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
usage(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 *
prog_name(char * arg0)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
main(int argc,char ** argv)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