xref: /illumos-gate/usr/src/cmd/valtools/ckstr.c (revision a28480febf31f0e61debac062a55216a98a05a92)
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 <stdlib.h>
37 #include <locale.h>
38 #include <libintl.h>
39 #include <limits.h>
40 #include "usage.h"
41 #include "libadm.h"
42 
43 #define	BADPID	(-2)
44 #define	MAXREGEXP	128
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, length;
50 
51 static const char	vusage[] = "rl";
52 static const char	husage[] = "rlWh";
53 static const char	eusage[] = "rlWe";
54 
55 #define	USAGE	"[-l length] [[-r regexp] [...]]"
56 
57 static void
58 usage(void)
59 {
60 	switch (*prog) {
61 	default:
62 		(void) fprintf(stderr,
63 			gettext("usage: %s [options] %s\n"),
64 			prog, USAGE);
65 		(void) fprintf(stderr, gettext(OPTMESG));
66 		(void) fprintf(stderr, gettext(STDOPTS));
67 		break;
68 
69 	case 'v':
70 		(void) fprintf(stderr,
71 			gettext("usage: %s %s input\n"), prog, USAGE);
72 		break;
73 
74 	case 'h':
75 		(void) fprintf(stderr,
76 			gettext("usage: %s [options] %s\n"),
77 			prog, USAGE);
78 		(void) fprintf(stderr, gettext(OPTMESG));
79 		(void) fprintf(stderr,
80 			gettext("\t-W width\n\t-h help\n"));
81 		break;
82 
83 	case 'e':
84 		(void) fprintf(stderr,
85 			gettext("usage: %s [options] %s\n"),
86 			prog, USAGE);
87 		(void) fprintf(stderr, gettext(OPTMESG));
88 		(void) fprintf(stderr,
89 			gettext("\t-W width\n\t-e error\n"));
90 		break;
91 	}
92 	exit(1);
93 }
94 
95 /*
96  * Given argv[0], return a pointer to the basename of the program.
97  */
98 static char *
99 prog_name(char *arg0)
100 {
101 	char *str;
102 
103 	/* first strip trailing '/' characters (exec() allows these!) */
104 	str = arg0 + strlen(arg0);
105 	while (str > arg0 && *--str == '/')
106 		*str = '\0';
107 	if ((str = strrchr(arg0, '/')) != NULL)
108 		return (str + 1);
109 	return (arg0);
110 }
111 
112 int
113 main(int argc, char **argv)
114 {
115 	int c, n;
116 	char	*strval;
117 	char	**regexp;
118 	size_t	len;
119 	size_t	maxregexp = MAXREGEXP;
120 	size_t	nregexp = 0;
121 
122 	(void) setlocale(LC_ALL, "");
123 
124 #if	!defined(TEXT_DOMAIN)
125 #define	TEXT_DOMAIN	"SYS_TEST"
126 #endif
127 	(void) textdomain(TEXT_DOMAIN);
128 
129 	prog = prog_name(argv[0]);
130 
131 	regexp = (char **)calloc(maxregexp, sizeof (char *));
132 	if (!regexp) {
133 		(void) fprintf(stderr,
134 			gettext("Not enough memory\n"));
135 		exit(1);
136 	}
137 	while ((c = getopt(argc, argv, "r:l:d:p:e:h:k:s:QW:?")) != EOF) {
138 		/* check for invalid option */
139 		if ((*prog == 'v') && !strchr(vusage, c))
140 			usage();
141 		if ((*prog == 'e') && !strchr(eusage, c))
142 			usage();
143 		if ((*prog == 'h') && !strchr(husage, c))
144 			usage();
145 
146 		switch (c) {
147 		case 'Q':
148 			ckquit = 0;
149 			break;
150 
151 		case 'W':
152 			ckwidth = atoi(optarg);
153 			if (ckwidth < 0) {
154 				(void) fprintf(stderr,
155 		gettext("%s: ERROR: negative display width specified\n"),
156 					prog);
157 				exit(1);
158 			}
159 			break;
160 
161 		case 'r':
162 			regexp[nregexp++] = optarg;
163 			if (nregexp == maxregexp) {
164 				maxregexp += MAXREGEXP;
165 				regexp = (char **)realloc(regexp,
166 					maxregexp * sizeof (char *));
167 				if (!regexp) {
168 					(void) fprintf(stderr,
169 						gettext("Not enough memory\n"));
170 					exit(1);
171 				}
172 				(void) memset(regexp + nregexp, 0,
173 					(maxregexp - nregexp) *
174 					sizeof (char *));
175 			}
176 			break;
177 
178 		case 'l':
179 			length = atoi(optarg);
180 			if ((length <= 0) || (length > 128)) {
181 				(void) fprintf(stderr,
182 		gettext("%s: ERROR: length must be between 1 and 128\n"),
183 					prog);
184 				exit(1);
185 			}
186 			break;
187 
188 		case 'd':
189 			deflt = optarg;
190 			break;
191 
192 		case 'p':
193 			prompt = optarg;
194 			break;
195 
196 		case 'e':
197 			error = optarg;
198 			break;
199 
200 		case 'h':
201 			help = optarg;
202 			break;
203 
204 		case 'k':
205 			kpid = atoi(optarg);
206 			break;
207 
208 		case 's':
209 			signo = atoi(optarg);
210 			break;
211 
212 		default:
213 			usage();
214 		}
215 	}
216 
217 	if (signo) {
218 		if (kpid == BADPID)
219 			usage();
220 	} else
221 		signo = SIGTERM;
222 
223 	if (*prog == 'v') {
224 		if (argc != (optind+1))
225 			usage();
226 		if (ckstr_val(regexp, length, argv[optind]))
227 			exit(1);
228 		exit(0);
229 	}
230 
231 	if (*prog == 'e') {
232 		if (argc > (optind+1))
233 			usage(); /* too many args */
234 		ckindent = 0;
235 		ckstr_err(regexp, length, error, argv[optind]);
236 		exit(0);
237 	}
238 
239 	if (optind != argc)
240 		usage();
241 
242 	if (*prog == 'h') {
243 		ckindent = 0;
244 		ckstr_hlp(regexp, length, help);
245 		exit(0);
246 	}
247 
248 	regexp[nregexp] = NULL;
249 
250 	if (deflt) {
251 		len = strlen(deflt) + 1;
252 		if (len < MAX_INPUT)
253 			len = MAX_INPUT;
254 	} else {
255 		len = MAX_INPUT;
256 	}
257 	strval = (char *)malloc(len);
258 	if (!strval) {
259 		(void) fprintf(stderr,
260 			gettext("Not enough memory\n"));
261 		exit(1);
262 	}
263 	n = ckstr(strval, regexp, length, deflt, error, help, prompt);
264 	if (n == 3) {
265 		if (kpid > -2)
266 			(void) kill(kpid, signo);
267 		(void) puts("q");
268 	} else if (n == 0)
269 		(void) fputs(strval, stdout);
270 	return (n);
271 }
272