xref: /illumos-gate/usr/src/cmd/valtools/ckpath.c (revision ce8560eeb961d528e27685fcdd2ffb03e9478dbf)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
28 /*	  All Rights Reserved  	*/
29 
30 
31 #pragma ident	"%Z%%M%	%I%	%E% SMI"
32 
33 #include <stdio.h>
34 #include <string.h>
35 #include <signal.h>
36 #include <valtools.h>
37 #include <stdlib.h>
38 #include <locale.h>
39 #include <libintl.h>
40 #include <limits.h>
41 #include "usage.h"
42 #include "libadm.h"
43 
44 #define	BADPID	(-2)
45 
46 static char	*prog;
47 static char	*deflt = NULL, *prompt = NULL, *error = NULL, *help = NULL;
48 static int	kpid = BADPID;
49 static int	signo, pflags;
50 
51 static const char	vusage[] = "abcfglrtwxyzno";
52 static const char	eusage[] = "abcfglrtwxyznoWe";
53 static const char	husage[] = "abcfglrtwxyznoWh";
54 
55 #define	USAGE "[-[a|l][b|c|f|y][n|[o|z]]rtwx]"
56 #define	MYOPTS	\
57 	"\t-a  #absolute path\n" \
58 	"\t-b  #block special device\n" \
59 	"\t-c  #character special device\n" \
60 	"\t-f  #ordinary file\n" \
61 	"\t-l  #relative path\n" \
62 	"\t-n  #must not exist (new)\n" \
63 	"\t-o  #must exist (old)\n" \
64 	"\t-r  #read permission\n" \
65 	"\t-t  #permission to create (touch)\n" \
66 	"\t-w  #write permission\n" \
67 	"\t-x  #execute permisiion\n" \
68 	"\t-y  #directory\n" \
69 	"\t-z  #non-zero length\n"
70 
71 static void
72 usage(void)
73 {
74 	switch (*prog) {
75 	default:
76 		(void) fprintf(stderr,
77 			gettext("usage: %s [options] %s\n"),
78 			prog, USAGE);
79 		(void) fprintf(stderr, gettext(MYOPTS));
80 		(void) fprintf(stderr, gettext(OPTMESG));
81 		(void) fprintf(stderr, gettext(STDOPTS));
82 		break;
83 
84 	case 'v':
85 		(void) fprintf(stderr,
86 			gettext("usage: %s %s input\n"),
87 			prog, USAGE);
88 		(void) fprintf(stderr, gettext(OPTMESG));
89 		(void) fprintf(stderr, gettext(MYOPTS));
90 		break;
91 
92 	case 'h':
93 		(void) fprintf(stderr,
94 			gettext("usage: %s [options] %s\n"),
95 			prog, USAGE);
96 		(void) fprintf(stderr, gettext(MYOPTS));
97 		(void) fprintf(stderr, gettext(OPTMESG));
98 		(void) fprintf(stderr,
99 			gettext("\t-W width\n\t-h help\n"));
100 		break;
101 
102 	case 'e':
103 		(void) fprintf(stderr,
104 			gettext("usage: %s [options] %s [input]\n"),
105 			prog, USAGE);
106 		(void) fprintf(stderr, gettext(MYOPTS));
107 		(void) fprintf(stderr, gettext(OPTMESG));
108 		(void) fprintf(stderr,
109 			gettext("\t-W width\n\t-e error\n"));
110 		break;
111 	}
112 	exit(1);
113 }
114 
115 /*
116  * Given argv[0], return a pointer to the basename of the program.
117  */
118 static char *
119 prog_name(char *arg0)
120 {
121 	char *str;
122 
123 	/* first strip trailing '/' characters (exec() allows these!) */
124 	str = arg0 + strlen(arg0);
125 	while (str > arg0 && *--str == '/')
126 		*str = '\0';
127 	if ((str = strrchr(arg0, '/')) != NULL)
128 		return (str + 1);
129 	return (arg0);
130 }
131 
132 int
133 main(int argc, char **argv)
134 {
135 	int c, n;
136 	char *pathval;
137 	size_t	len;
138 
139 	(void) setlocale(LC_ALL, "");
140 
141 #if	!defined(TEXT_DOMAIN)
142 #define	TEXT_DOMAIN	"SYS_TEST"
143 #endif
144 	(void) textdomain(TEXT_DOMAIN);
145 
146 	prog = prog_name(argv[0]);
147 
148 	while ((c = getopt(argc, argv, "abcfglrtwxyznod:p:e:h:k:s:QW:?"))
149 		!= EOF) {
150 		/* check for invalid option */
151 		if ((*prog == 'v') && !strchr(vusage, c))
152 			usage();
153 		if ((*prog == 'e') && !strchr(eusage, c))
154 			usage();
155 		if ((*prog == 'h') && !strchr(husage, c))
156 			usage();
157 
158 		switch (c) {
159 		case 'Q':
160 			ckquit = 0;
161 			break;
162 
163 		case 'W':
164 			ckwidth = atoi(optarg);
165 			if (ckwidth < 0) {
166 				(void) fprintf(stderr,
167 		gettext("%s: ERROR: negative display width specified\n"),
168 					prog);
169 				exit(1);
170 			}
171 			break;
172 
173 		case 'a':
174 			pflags |= P_ABSOLUTE;
175 			break;
176 
177 		case 'b':
178 			pflags |= P_BLK;
179 			break;
180 
181 		case 'c':
182 			pflags |= P_CHR;
183 			break;
184 
185 		case 'f':
186 		case 'g': /* outdated */
187 			pflags |= P_REG;
188 			break;
189 
190 		case 'l':
191 			pflags |= P_RELATIVE;
192 			break;
193 
194 		case 'n':
195 			pflags |= P_NEXIST;
196 			break;
197 
198 		case 'o':
199 			pflags |= P_EXIST;
200 			break;
201 
202 		case 't':
203 			pflags |= P_CREAT;
204 			break;
205 
206 		case 'r':
207 			pflags |= P_READ;
208 			break;
209 
210 		case 'w':
211 			pflags |= P_WRITE;
212 			break;
213 
214 		case 'x':
215 			pflags |= P_EXEC;
216 			break;
217 
218 		case 'y':
219 			pflags |= P_DIR;
220 			break;
221 
222 		case 'z':
223 			pflags |= P_NONZERO;
224 			break;
225 
226 		case 'd':
227 			deflt = optarg;
228 			break;
229 
230 		case 'p':
231 			prompt = optarg;
232 			break;
233 
234 		case 'e':
235 			error = optarg;
236 			break;
237 
238 		case 'h':
239 			help = optarg;
240 			break;
241 
242 		case 'k':
243 			kpid = atoi(optarg);
244 			break;
245 
246 		case 's':
247 			signo = atoi(optarg);
248 			break;
249 
250 		default:
251 			usage();
252 		}
253 	}
254 
255 	if (signo) {
256 		if (kpid == BADPID)
257 			usage();
258 	} else
259 		signo = SIGTERM;
260 
261 	if (ckpath_stx(pflags)) {
262 		(void) fprintf(stderr,
263 			gettext("%s: ERROR: mutually exclusive options used\n"),
264 			prog);
265 		exit(4);
266 	}
267 
268 	if (*prog == 'v') {
269 		if (argc != (optind+1))
270 			usage(); /* too many paths listed */
271 		exit(ckpath_val(argv[optind], pflags));
272 	} else if (*prog == 'e') {
273 		if (argc > (optind+1))
274 			usage();
275 		ckindent = 0;
276 		ckpath_err(pflags, error, argv[optind]);
277 		exit(0);
278 	}
279 
280 	if (optind != argc)
281 		usage();
282 
283 	if (*prog == 'h') {
284 		ckindent = 0;
285 		ckpath_hlp(pflags, help);
286 		exit(0);
287 	}
288 
289 	if (deflt) {
290 		len = strlen(deflt) + 1;
291 		if (len < MAX_INPUT)
292 			len = MAX_INPUT;
293 	} else {
294 		len = MAX_INPUT;
295 	}
296 	pathval = (char *)malloc(len);
297 	if (!pathval) {
298 		(void) fprintf(stderr,
299 			gettext("Not enough memory\n"));
300 		exit(1);
301 	}
302 	n = ckpath(pathval, pflags, deflt, error, help, prompt);
303 	if (n == 3) {
304 		if (kpid > -2)
305 			(void) kill(kpid, signo);
306 		(void) puts("q");
307 	} else if (n == 0)
308 		(void) fputs(pathval, stdout);
309 	return (n);
310 }
311