dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / lib / libadm / common / cktime.c
blob27bdffe9ed55df3a5c95ba7aded302a717e2c2a7
1 /*
2 * CDDL HEADER START
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.
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.
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]
20 * CDDL HEADER END
22 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
23 /* All Rights Reserved */
27 * Copyright (c) 1997,1998 by Sun Microsystems, Inc.
28 * All rights reserved.
31 * Copyright 2010 Nexenta Systems, Inc. All rights reserved.
34 /*LINTLIBRARY*/
36 #include <stdio.h>
37 #include <string.h>
38 #include <ctype.h>
39 #include <limits.h>
40 #include <sys/types.h>
41 #include <stdlib.h>
42 #include "libadm.h"
44 static int fmtcheck(char *);
46 #define PROMPT "Enter the time of day"
47 #define ERRMSG "Please enter the time of day. Format is"
48 #define DEFAULT "%H:%M"
50 #define TLEN 3
51 #define LH 00
52 #define UH 23
53 #define USH 12
54 #define LM 00
55 #define UM 59
56 #define LS 00
57 #define US 59
58 #define DELIM1 ':'
59 #define BLANK ' '
60 #define TAB ' '
62 static void
63 setmsg(char *msg, char *fmt, size_t sz)
65 if (fmt == NULL)
66 fmt = DEFAULT;
67 (void) snprintf(msg, sz, "%s <%s>.", ERRMSG, fmt);
70 static char *
71 p_ndig(char *string, int *value)
73 char *ptr;
74 int accum = 0;
75 int n = 2;
77 if (!string)
78 return (0);
79 for (ptr = string; *ptr && n > 0; n--, ptr++) {
80 if (! isdigit((unsigned char)*ptr))
81 return (NULL);
82 accum = (10 * accum) + (*ptr - '0');
84 if (n)
85 return (NULL);
86 *value = accum;
87 return (ptr);
90 static char *
91 p_time(char *string, int llim, int ulim)
93 char *ptr;
94 int begin = -1;
95 if (!(ptr = p_ndig(string, &begin)))
96 return (NULL);
97 if (begin >= llim && begin <= ulim)
98 return (ptr);
99 else return (NULL);
102 /* p_meridian will parse the string for the meridian - AM/PM or am/pm */
104 static char *
105 p_meridian(char *string)
107 static char *middle[] = { "AM", "PM", "am", "pm" };
108 int legit, n;
109 char mid[TLEN];
111 legit = 0;
112 n = 0;
113 mid[2] = '\0';
114 (void) sscanf(string, "%2s", mid);
115 while (!(legit) && (n < 4)) {
116 if ((strncmp(mid, middle[n], 2)) == 0)
117 legit = 1; /* found legitimate string */
118 n++;
120 if (legit)
121 return (string+2);
122 return (NULL);
125 static char *
126 p_delim(char *string, char dchoice)
128 char dlm;
130 if (! string)
131 return (NULL);
132 (void) sscanf(string, "%1c", &dlm);
133 return ((dlm == dchoice) ? string + 1 : NULL);
137 cktime_val(char *fmt, char *input)
139 char ltrl, dfl;
140 int valid = 1; /* time of day string is valid for format */
142 if ((fmt != NULL) && (fmtcheck(fmt) == 1))
143 return (4);
145 if (fmt == NULL)
146 fmt = DEFAULT;
147 ltrl = '\0';
148 while (*fmt && valid) {
149 if ((*fmt) == '%') {
150 switch (*++fmt) {
151 case 'H':
152 input = p_time(input, LH, UH);
153 if (!input)
154 valid = 0;
155 break;
157 case 'M':
158 input = p_time(input, LM, UM);
159 if (!input)
160 valid = 0;
161 break;
163 case 'S':
164 input = p_time(input, LS, US);
165 if (!input)
166 valid = 0;
167 break;
169 case 'T':
170 input = p_time(input, LH, UH);
171 if (!input) {
172 valid = 0;
173 break;
176 input = p_delim(input, DELIM1);
177 if (!input) {
178 valid = 0;
179 break;
181 input = p_time(input, LM, UM);
182 if (!input) {
183 valid = 0;
184 break;
186 input = p_delim(input, DELIM1);
187 if (!input) {
188 valid = 0;
189 break;
191 input = p_time(input, LS, US);
192 if (!input)
193 valid = 0;
194 break;
196 case 'R':
197 input = p_time(input, LH, UH);
198 if (!input) {
199 valid = 0;
200 break;
202 input = p_delim(input, DELIM1);
203 if (!input) {
204 valid = 0;
205 break;
207 input = p_time(input, LM, UM);
208 if (!input) {
209 valid = 0;
210 break;
212 break;
214 case 'r':
215 input = p_time(input, LH, USH);
216 if (!input) {
217 valid = 0;
218 break;
220 input = p_delim(input, DELIM1);
221 if (!input) {
222 valid = 0;
223 break;
225 input = p_time(input, LM, UM);
226 if (!input) {
227 valid = 0;
228 break;
230 input = p_delim(input, DELIM1);
231 if (!input) {
232 valid = 0;
233 break;
235 input = p_time(input, LS, US);
236 if (!input) {
237 valid = 0;
238 break;
240 input = p_delim(input, BLANK);
241 if (!input) {
242 valid = 0;
243 break;
245 input = p_meridian(input);
246 if (!input)
247 valid = 0;
248 break;
250 case 'I':
251 input = p_time(input, LH, USH);
252 if (!input)
253 valid = 0;
254 break;
256 case 'p':
257 input = p_meridian(input);
258 if (!input)
259 valid = 0;
260 break;
262 default:
263 (void) sscanf(input++, "%1c", &ltrl);
265 } else {
266 dfl = '\0';
267 (void) sscanf(input, "%1c", &dfl);
268 input++;
270 fmt++;
273 if (!(*fmt) && (input) && (*input))
274 valid = 0;
276 return ((valid == 0));
280 cktime_err(char *fmt, char *error)
282 char defmesg[128];
284 if ((fmt != NULL) && (fmtcheck(fmt) == 1))
285 return (4);
286 setmsg(defmesg, fmt, sizeof (defmesg));
287 puterror(stdout, defmesg, error);
288 return (0);
292 cktime_hlp(char *fmt, char *help)
294 char defmesg[128];
296 if ((fmt != NULL) && (fmtcheck(fmt) == 1))
297 return (4);
298 setmsg(defmesg, fmt, sizeof (defmesg));
299 puthelp(stdout, defmesg, help);
300 return (0);
304 * A little state machine that checks out the format to
305 * make sure it is acceptable.
306 * return value 1: NG
307 * return value 0: OK
310 fmtcheck(char *fmt)
312 int percent = 0;
314 while (*fmt) {
315 switch (*fmt++) {
316 case '%': /* previous state must be start or letter */
317 if (percent == 0)
318 percent = 1;
319 else
320 return (1);
321 break;
322 case 'H': /* previous state must be "%" */
323 case 'M':
324 case 'S':
325 case 'T':
326 case 'R':
327 case 'r':
328 case 'I':
329 case 'p':
330 if (percent == 1)
331 percent = 0;
332 else
333 return (1);
334 break;
335 case TAB: /* previous state must be start or letter */
336 case BLANK:
337 case DELIM1:
338 if (percent == 1)
339 return (1);
340 break;
341 default:
342 return (1);
345 return (percent);
349 cktime(char *tod, char *fmt, char *defstr, char *error, char *help,
350 char *prompt)
352 char input[MAX_INPUT],
353 defmesg[128];
355 if ((fmt != NULL) && (fmtcheck(fmt) == 1))
356 return (4);
358 if (fmt == NULL)
359 fmt = DEFAULT;
360 setmsg(defmesg, fmt, sizeof (defmesg));
361 if (!prompt)
362 prompt = "Enter a time of day";
364 start:
365 putprmpt(stderr, prompt, NULL, defstr);
366 if (getinput(input))
367 return (1);
369 if (!strlen(input)) {
370 if (defstr) {
371 (void) strcpy(tod, defstr);
372 return (0);
374 puterror(stderr, defmesg, error);
375 goto start;
377 if (strcmp(input, "?") == 0) {
378 puthelp(stderr, defmesg, help);
379 goto start;
381 if (ckquit && (strcmp(input, "q") == 0))
382 return (3);
384 if (cktime_val(fmt, input)) {
385 puterror(stderr, defmesg, error);
386 goto start;
388 (void) strcpy(tod, input);
389 return (0);