xref: /illumos-gate/usr/src/cmd/valtools/ckpath.c (revision 012e6ce759c490003aed29439cc47d3d73a99ad3)
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 #include <stdio.h>
31 #include <string.h>
32 #include <signal.h>
33 #include <valtools.h>
34 #include <stdlib.h>
35 #include <locale.h>
36 #include <libintl.h>
37 #include <limits.h>
38 #include "usage.h"
39 #include "libadm.h"
40 
41 #define	BADPID	(-2)
42 
43 static char	*prog;
44 static char	*deflt = NULL, *prompt = NULL, *error = NULL, *help = NULL;
45 static int	kpid = BADPID;
46 static int	signo, pflags;
47 
48 static const char	vusage[] = "abcfglrtwxyzno";
49 static const char	eusage[] = "abcfglrtwxyznoWe";
50 static const char	husage[] = "abcfglrtwxyznoWh";
51 
52 #define	USAGE "[-[a|l][b|c|f|y][n|[o|z]]rtwx]"
53 #define	MYOPTS	\
54 	"\t-a  #absolute path\n" \
55 	"\t-b  #block special device\n" \
56 	"\t-c  #character special device\n" \
57 	"\t-f  #ordinary file\n" \
58 	"\t-l  #relative path\n" \
59 	"\t-n  #must not exist (new)\n" \
60 	"\t-o  #must exist (old)\n" \
61 	"\t-r  #read permission\n" \
62 	"\t-t  #permission to create (touch)\n" \
63 	"\t-w  #write permission\n" \
64 	"\t-x  #execute permisiion\n" \
65 	"\t-y  #directory\n" \
66 	"\t-z  #non-zero length\n"
67 
68 static void
69 usage(void)
70 {
71 	switch (*prog) {
72 	default:
73 		(void) fprintf(stderr,
74 			gettext("usage: %s [options] %s\n"),
75 			prog, USAGE);
76 		(void) fprintf(stderr, gettext(MYOPTS));
77 		(void) fprintf(stderr, gettext(OPTMESG));
78 		(void) fprintf(stderr, gettext(STDOPTS));
79 		break;
80 
81 	case 'v':
82 		(void) fprintf(stderr,
83 			gettext("usage: %s %s input\n"),
84 			prog, USAGE);
85 		(void) fprintf(stderr, gettext(OPTMESG));
86 		(void) fprintf(stderr, gettext(MYOPTS));
87 		break;
88 
89 	case 'h':
90 		(void) fprintf(stderr,
91 			gettext("usage: %s [options] %s\n"),
92 			prog, USAGE);
93 		(void) fprintf(stderr, gettext(MYOPTS));
94 		(void) fprintf(stderr, gettext(OPTMESG));
95 		(void) fprintf(stderr,
96 			gettext("\t-W width\n\t-h help\n"));
97 		break;
98 
99 	case 'e':
100 		(void) fprintf(stderr,
101 			gettext("usage: %s [options] %s [input]\n"),
102 			prog, USAGE);
103 		(void) fprintf(stderr, gettext(MYOPTS));
104 		(void) fprintf(stderr, gettext(OPTMESG));
105 		(void) fprintf(stderr,
106 			gettext("\t-W width\n\t-e error\n"));
107 		break;
108 	}
109 	exit(1);
110 }
111 
112 /*
113  * Given argv[0], return a pointer to the basename of the program.
114  */
115 static char *
116 prog_name(char *arg0)
117 {
118 	char *str;
119 
120 	/* first strip trailing '/' characters (exec() allows these!) */
121 	str = arg0 + strlen(arg0);
122 	while (str > arg0 && *--str == '/')
123 		*str = '\0';
124 	if ((str = strrchr(arg0, '/')) != NULL)
125 		return (str + 1);
126 	return (arg0);
127 }
128 
129 int
130 main(int argc, char **argv)
131 {
132 	int c, n;
133 	char *pathval;
134 	size_t	len;
135 
136 	(void) setlocale(LC_ALL, "");
137 
138 #if	!defined(TEXT_DOMAIN)
139 #define	TEXT_DOMAIN	"SYS_TEST"
140 #endif
141 	(void) textdomain(TEXT_DOMAIN);
142 
143 	prog = prog_name(argv[0]);
144 
145 	while ((c = getopt(argc, argv, "abcfglrtwxyznod:p:e:h:k:s:QW:?"))
146 		!= EOF) {
147 		/* check for invalid option */
148 		if ((*prog == 'v') && !strchr(vusage, c))
149 			usage();
150 		if ((*prog == 'e') && !strchr(eusage, c))
151 			usage();
152 		if ((*prog == 'h') && !strchr(husage, c))
153 			usage();
154 
155 		switch (c) {
156 		case 'Q':
157 			ckquit = 0;
158 			break;
159 
160 		case 'W':
161 			ckwidth = atoi(optarg);
162 			if (ckwidth < 0) {
163 				(void) fprintf(stderr,
164 		gettext("%s: ERROR: negative display width specified\n"),
165 					prog);
166 				exit(1);
167 			}
168 			break;
169 
170 		case 'a':
171 			pflags |= P_ABSOLUTE;
172 			break;
173 
174 		case 'b':
175 			pflags |= P_BLK;
176 			break;
177 
178 		case 'c':
179 			pflags |= P_CHR;
180 			break;
181 
182 		case 'f':
183 		case 'g': /* outdated */
184 			pflags |= P_REG;
185 			break;
186 
187 		case 'l':
188 			pflags |= P_RELATIVE;
189 			break;
190 
191 		case 'n':
192 			pflags |= P_NEXIST;
193 			break;
194 
195 		case 'o':
196 			pflags |= P_EXIST;
197 			break;
198 
199 		case 't':
200 			pflags |= P_CREAT;
201 			break;
202 
203 		case 'r':
204 			pflags |= P_READ;
205 			break;
206 
207 		case 'w':
208 			pflags |= P_WRITE;
209 			break;
210 
211 		case 'x':
212 			pflags |= P_EXEC;
213 			break;
214 
215 		case 'y':
216 			pflags |= P_DIR;
217 			break;
218 
219 		case 'z':
220 			pflags |= P_NONZERO;
221 			break;
222 
223 		case 'd':
224 			deflt = optarg;
225 			break;
226 
227 		case 'p':
228 			prompt = optarg;
229 			break;
230 
231 		case 'e':
232 			error = optarg;
233 			break;
234 
235 		case 'h':
236 			help = optarg;
237 			break;
238 
239 		case 'k':
240 			kpid = atoi(optarg);
241 			break;
242 
243 		case 's':
244 			signo = atoi(optarg);
245 			break;
246 
247 		default:
248 			usage();
249 		}
250 	}
251 
252 	if (signo) {
253 		if (kpid == BADPID)
254 			usage();
255 	} else
256 		signo = SIGTERM;
257 
258 	if (ckpath_stx(pflags)) {
259 		(void) fprintf(stderr,
260 			gettext("%s: ERROR: mutually exclusive options used\n"),
261 			prog);
262 		exit(4);
263 	}
264 
265 	if (*prog == 'v') {
266 		if (argc != (optind+1))
267 			usage(); /* too many paths listed */
268 		exit(ckpath_val(argv[optind], pflags));
269 	} else if (*prog == 'e') {
270 		if (argc > (optind+1))
271 			usage();
272 		ckindent = 0;
273 		ckpath_err(pflags, error, argv[optind]);
274 		exit(0);
275 	}
276 
277 	if (optind != argc)
278 		usage();
279 
280 	if (*prog == 'h') {
281 		ckindent = 0;
282 		ckpath_hlp(pflags, help);
283 		exit(0);
284 	}
285 
286 	if (deflt) {
287 		len = strlen(deflt) + 1;
288 		if (len < MAX_INPUT)
289 			len = MAX_INPUT;
290 	} else {
291 		len = MAX_INPUT;
292 	}
293 	pathval = (char *)malloc(len);
294 	if (!pathval) {
295 		(void) fprintf(stderr,
296 			gettext("Not enough memory\n"));
297 		exit(1);
298 	}
299 	n = ckpath(pathval, pflags, deflt, error, help, prompt);
300 	if (n == 3) {
301 		if (kpid > -2)
302 			(void) kill(kpid, signo);
303 		(void) puts("q");
304 	} else if (n == 0)
305 		(void) fputs(pathval, stdout);
306 	return (n);
307 }
308