xref: /illumos-gate/usr/src/cmd/valtools/cktime.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 
42 static char	*prog;
43 static char	*deflt = NULL, *prompt = NULL, *error = NULL, *help = NULL;
44 static int	kpid = BADPID;
45 static int	signo;
46 static char	*fmt;
47 
48 static const char	vusage[] = "f";
49 static const char	husage[] = "fWh";
50 static const char	eusage[] = "fWe";
51 
52 #define	MYFMT \
53 	"%s:ERROR:invalid format\n" \
54 	"valid format descriptors are:\n" \
55 	"\t%%H  #hour (00-23)\n" \
56 	"\t%%I  #hour (00-12)\n" \
57 	"\t%%M  #minute (00-59)\n" \
58 	"\t%%p  #AM, PM, am or pm\n" \
59 	"\t%%r  #time as %%I:%%M:%%S %%p\n" \
60 	"\t%%R  #time as %%H:%%M (default)\n" \
61 	"\t%%S  #seconds (00-59)\n" \
62 	"\t%%T  #time as %%H:%%M:%%S\n"
63 
64 static void
65 usage(void)
66 {
67 	switch (*prog) {
68 	default:
69 		(void) fprintf(stderr,
70 			gettext("usage: %s [options] [-f format]\n"),
71 			prog);
72 		(void) fprintf(stderr, gettext(OPTMESG));
73 		(void) fprintf(stderr, gettext(STDOPTS));
74 		break;
75 
76 	case 'v':
77 		(void) fprintf(stderr,
78 			gettext("usage: %s [-f format] input\n"), prog);
79 		break;
80 
81 	case 'h':
82 		(void) fprintf(stderr,
83 			gettext("usage: %s [options] [-f format]\n"),
84 			prog);
85 		(void) fprintf(stderr, gettext(OPTMESG));
86 		(void) fprintf(stderr,
87 			gettext("\t-W width\n\t-h help\n"));
88 		break;
89 
90 	case 'e':
91 		(void) fprintf(stderr,
92 			gettext("usage: %s [options] [-f format]\n"),
93 			prog);
94 		(void) fprintf(stderr, gettext(OPTMESG));
95 		(void) fprintf(stderr,
96 			gettext("\t-W width\n\t-e error\n"));
97 		break;
98 	}
99 	exit(1);
100 }
101 
102 /*
103  * Given argv[0], return a pointer to the basename of the program.
104  */
105 static char *
106 prog_name(char *arg0)
107 {
108 	char *str;
109 
110 	/* first strip trailing '/' characters (exec() allows these!) */
111 	str = arg0 + strlen(arg0);
112 	while (str > arg0 && *--str == '/')
113 		*str = '\0';
114 	if ((str = strrchr(arg0, '/')) != NULL)
115 		return (str + 1);
116 	return (arg0);
117 }
118 
119 int
120 main(int argc, char **argv)
121 {
122 	int c, n;
123 	char *tod;
124 	size_t	len;
125 
126 	(void) setlocale(LC_ALL, "");
127 
128 #if	!defined(TEXT_DOMAIN)
129 #define	TEXT_DOMAIN	"SYS_TEST"
130 #endif
131 	(void) textdomain(TEXT_DOMAIN);
132 
133 	prog = prog_name(argv[0]);
134 
135 	while ((c = getopt(argc, argv, "f:d:p:e:h:k:s:QW:?")) != EOF) {
136 		/* check for invalid option */
137 		if ((*prog == 'v') && !strchr(vusage, c))
138 			usage();
139 		if ((*prog == 'e') && !strchr(eusage, c))
140 			usage();
141 		if ((*prog == 'h') && !strchr(husage, c))
142 			usage();
143 
144 		switch (c) {
145 		case 'Q':
146 			ckquit = 0;
147 			break;
148 
149 		case 'W':
150 			ckwidth = atoi(optarg);
151 			if (ckwidth < 0) {
152 				(void) fprintf(stderr,
153 		gettext("%s: ERROR: negative display width specified\n"),
154 					prog);
155 				exit(1);
156 			}
157 			break;
158 
159 		case 'f':
160 			fmt = optarg;
161 			break;
162 
163 		case 'd':
164 			deflt = optarg;
165 			break;
166 
167 		case 'p':
168 			prompt = optarg;
169 			break;
170 
171 		case 'e':
172 			error = optarg;
173 			break;
174 
175 		case 'h':
176 			help = optarg;
177 			break;
178 
179 		case 'k':
180 			kpid = atoi(optarg);
181 			break;
182 
183 		case 's':
184 			signo = atoi(optarg);
185 			break;
186 
187 		default:
188 			usage();
189 		}
190 	}
191 
192 	if (signo) {
193 		if (kpid == BADPID)
194 			usage();
195 	} else
196 		signo = SIGTERM;
197 
198 	if (*prog == 'v') {
199 		if (argc != (optind+1))
200 			usage();
201 		n = cktime_val(fmt, argv[optind]);
202 		/*
203 		 * TRANSLATION_NOTE
204 		 * In the below, "AM", "PM", "am", and "pm" are
205 		 * keywords.  So, do not translate them.
206 		 */
207 		if (n == 4)
208 			(void) fprintf(stderr, gettext(MYFMT), prog);
209 		exit(n);
210 	}
211 
212 	if (optind != argc)
213 		usage();
214 
215 	if (*prog == 'e') {
216 		ckindent = 0;
217 		if (cktime_err(fmt, error)) {
218 			(void) fprintf(stderr, gettext(MYFMT), prog);
219 			exit(4);
220 		} else
221 			exit(0);
222 	} else if (*prog == 'h') {
223 		ckindent = 0;
224 		if (cktime_hlp(fmt, help)) {
225 			(void) fprintf(stderr, gettext(MYFMT), prog);
226 			exit(4);
227 		} else
228 			exit(0);
229 	}
230 
231 	if (deflt) {
232 		len = strlen(deflt) + 1;
233 		if (len < MAX_INPUT)
234 			len = MAX_INPUT;
235 	} else {
236 		len = MAX_INPUT;
237 	}
238 	tod = (char *)malloc(len);
239 	if (!tod) {
240 		(void) fprintf(stderr,
241 			gettext("Not enough memory\n"));
242 		exit(1);
243 	}
244 	n = cktime(tod, fmt, deflt, error, help, prompt);
245 	if (n == 3) {
246 		if (kpid > -2)
247 			(void) kill(kpid, signo);
248 		(void) puts("q");
249 	} else if (n == 0)
250 		(void) fputs(tod, stdout);
251 	if (n == 4)
252 		(void) fprintf(stderr, gettext(MYFMT), prog);
253 	return (n);
254 }
255