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