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