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