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
usage(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 *
prog_name(char * arg0)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
main(int argc,char ** argv)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