8847 libadm: variable 'daynum' set but not used
[unleashed.git] / usr / src / lib / libadm / common / ckdate.c
blob9ae38509e1e3c9ee1582e3659f034a808c784512
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
21 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
22 /* All Rights Reserved */
26 * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
29 /*LINTLIBRARY*/
31 #include <stdio.h>
32 #include <string.h>
33 #include <ctype.h>
34 #include <sys/types.h>
35 #include <stdlib.h>
36 #include <limits.h>
37 #include "libadm.h"
39 static int fmtcheck(char *);
41 #define MSGSIZ 64
42 #define PROMPT "Enter the date"
43 #define MESG "Please enter a date"
44 #define DEFAULT "%m/%d/%y"
46 static char *p_ndigit(char *, int *, int);
47 static char *p_date(char *, int, int, int);
48 static char *p_eday(char *, int, int);
49 static char *p_dlm(char *, char);
51 #define MLIM 10
52 #define STDIG 2
53 #define LD2 10
54 #define LD 01
55 #define UD 31
56 #define LM 01
57 #define UM 12
59 * All digits are valid for a YY year format
60 * 70-99 refer to the 20th Century
61 * 00-69 refer to the 21st Century
63 #define LY 00
64 #define UY 99
65 #define LCY 1970
66 #define UCY 9999
67 #define CCYY 4
68 #define DELIM1 '/'
69 #define DELIM2 '-'
70 #define BLANK ' '
71 #define TAB ' '
73 static void
74 setmsg(char *msg, char *fmt, size_t sz)
76 if ((fmt == NULL) || strcmp(fmt, "%D") == 0)
77 fmt = "%m/%d/%y";
78 (void) snprintf(msg, sz, "%s. Format is <%s>.", MESG, fmt);
81 static char *
82 p_ndigit(char *string, int *value, int n)
84 char *ptr;
85 int accum = 0;
87 if (!string)
88 return (NULL);
89 for (ptr = string; *ptr && n > 0; n--, ptr++) {
90 if (! isdigit((unsigned char)*ptr))
91 return (NULL);
92 accum = (10 * accum) + (*ptr - '0');
94 if (n)
95 return (NULL);
96 *value = accum;
97 return (ptr);
100 static char *
101 p_date(char *string, int llim, int ulim, int ndig)
103 char *ptr;
104 int begin = -1;
106 if (!(ptr = p_ndigit(string, &begin, ndig)))
107 return (NULL);
108 if (begin >= llim && begin <= ulim)
109 return (ptr);
110 else
111 return (NULL);
114 static char *
115 p_eday(char *string, int llim, int ulim)
117 char *ptr, *copy;
118 int begin = -1;
119 int iday = 0;
120 int idaymax = 2;
122 if (*string == BLANK) {
123 string++;
124 idaymax--;
126 copy = string;
127 while (isdigit((unsigned char)*copy) && (iday < idaymax)) {
128 copy++;
129 iday++;
131 if (iday == 1) {
132 llim = 1;
133 ulim = 9;
134 } else if (iday == 2) {
135 llim = 10;
136 ulim = 31;
138 if (iday == 0)
139 return (NULL);
141 if (!(ptr = p_ndigit(string, &begin, iday)))
142 return (NULL);
144 if (begin >= llim && begin <= ulim)
145 return (ptr);
146 else
147 return (NULL);
150 /* p_month will parse the string for the month - abbr. form i.e. JAN - DEC */
152 static char *
153 p_month(char *string, char mnabr)
155 static char *fmonth[] = {
156 "JANUARY", "FEBRUARY", "MARCH", "APRIL",
157 "MAY", "JUNE", "JULY", "AUGUST",
158 "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER"
160 static char *amonth[] = {
161 "JAN", "FEB", "MAR", "APR", "MAY", "JUN",
162 "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"
164 int ichng, icnt;
165 char *mnth[12];
166 char *copy;
167 char mletter[MLIM];
168 int mlen;
169 int imnth = 0;
170 int legit = 0;
171 int n = 0;
173 if (mnabr == 'a') {
174 mlen = 3;
175 for (icnt = 0; icnt < 12; icnt++)
176 mnth[icnt] = amonth[icnt];
177 } else {
178 mlen = 9;
179 for (icnt = 0; icnt < 12; icnt++)
180 mnth[icnt] = fmonth[icnt];
183 copy = string;
185 while (((islower((unsigned char)*copy)) ||
186 (isupper((unsigned char)*copy))) && (imnth < mlen)) {
187 mletter[imnth] = toupper((unsigned char)*copy++);
188 imnth++;
190 mletter[imnth] = '\0';
191 while (!(legit) && (n < 12)) {
192 if (strncmp(mletter, mnth[n],
193 (imnth = (int)strlen(mnth[n]))) == 0)
194 legit = 1; /* found legitimate string */
195 n++;
197 if (legit) {
198 for (ichng = 0; ichng < imnth; ichng++) {
199 *string = toupper((unsigned char)*string);
200 string++;
203 return (string);
205 * I know this causes side effects, but it's less
206 * code than adding in a copy for string and using that
208 } else
209 return (NULL);
212 static char *
213 p_dlm(char *string, char dchoice)
215 char dlm;
218 if (! string)
219 return (NULL);
220 (void) sscanf(string, "%1c", &dlm);
221 if (dchoice == '/')
222 return (((dlm == DELIM1) || (dlm == DELIM2)) ? string+1 : NULL);
223 else
224 return ((dlm == dchoice) ? string + 1 : NULL);
228 ckdate_err(char *fmt, char *error)
230 char defmesg[MSGSIZ];
232 if ((fmt != NULL) && (fmtcheck(fmt) == 1))
233 return (4);
234 setmsg(defmesg, fmt, MSGSIZ);
235 puterror(stdout, defmesg, error);
236 return (0);
240 ckdate_hlp(char *fmt, char *help)
242 char defmesg[MSGSIZ];
244 if ((fmt != NULL) && (fmtcheck(fmt) == 1))
245 return (4);
246 setmsg(defmesg, fmt, MSGSIZ);
247 puthelp(stdout, defmesg, help);
248 return (0);
252 * A little state machine that checks out the format to
253 * make sure it is acceptable.
254 * return value 1: NG
255 * return value 0: OK
257 static int
258 fmtcheck(char *fmt)
260 int percent = 0;
262 while (*fmt) {
263 switch (*fmt++) {
264 case '%': /* previous state must be start or letter */
265 if (percent == 0)
266 percent = 1;
267 else
268 return (1);
269 break;
270 case 'd': /* previous state must be "%" */
271 case 'e':
272 case 'm':
273 case 'y':
274 case 'Y':
275 case 'D':
276 case 'h':
277 case 'b':
278 case 'B':
279 if (percent == 1)
280 percent = 0;
281 else
282 return (1);
283 break;
284 case TAB: /* previous state must be start or letter */
285 case BLANK:
286 case DELIM1:
287 case DELIM2:
288 if (percent == 1)
289 return (1);
290 break;
291 default:
292 return (1);
295 return (percent);
299 ckdate_val(char *fmt, char *input)
301 char ltrl, dfl;
302 int valid = 1; /* time of day string is valid for format */
304 if ((fmt != NULL) && (fmtcheck(fmt) == 1))
305 return (4);
307 if (fmt == NULL)
308 fmt = DEFAULT;
309 ltrl = '\0';
310 while (*fmt && valid) {
311 if ((*fmt) == '%') {
312 fmt++;
313 switch (*fmt) {
314 case 'd':
315 input = p_date(input, LD, UD, STDIG);
316 if (!input)
317 valid = 0;
318 break;
320 case 'e':
321 input = p_eday(input, LD2, UD);
322 if (!input)
323 valid = 0;
324 break;
326 case 'm':
327 input = p_date(input, LM, UM, STDIG);
328 if (!input)
329 valid = 0;
330 break;
332 case 'y':
333 input = p_date(input, LY, UY, STDIG);
334 if (!input)
335 valid = 0;
336 break;
338 case 'Y':
339 input = p_date(input, LCY, UCY, CCYY);
340 if (!input)
341 valid = 0;
342 break;
344 case 'D':
345 input = p_date(input, LM, UM, STDIG);
346 if (!input) {
347 valid = 0;
348 break;
350 input = p_dlm(input, DELIM1);
351 if (!input) {
352 valid = 0;
353 break;
355 input = p_date(input, LD, UD, STDIG);
356 if (!input) {
357 valid = 0;
358 break;
360 input = p_dlm(input, DELIM1);
361 if (!input) {
362 valid = 0;
363 break;
365 input = p_date(input, LY, UY, STDIG);
366 if (!input)
367 valid = 0;
368 break;
370 case 'h':
371 case 'b':
372 input = p_month(input, 'a');
373 if (!input)
374 valid = 0;
375 break;
377 case 'B':
378 input = p_month(input, 'f');
379 if (!input)
380 valid = 0;
381 break;
383 default:
384 (void) sscanf(input, "%1c", &ltrl);
385 input++;
387 } else {
388 dfl = '\0';
389 (void) sscanf(input, "%1c", &dfl);
390 input++;
392 fmt++;
393 } /* end of while fmt and valid */
395 if ((*fmt == NULL) && ((input != NULL) && *input != 0)) {
396 if (*input != NULL)
397 valid = 0;
399 return ((valid == 0));
403 ckdate(char *date, char *fmt, char *defstr, char *error, char *help,
404 char *prompt)
406 char defmesg[MSGSIZ];
407 char input[MAX_INPUT];
408 char *ept, end[128];
410 ept = end;
411 *ept = '\0';
413 if ((fmt != NULL) && (fmtcheck(fmt) == 1))
414 return (4);
416 setmsg(defmesg, fmt, MSGSIZ);
417 (void) sprintf(ept, "[?,q]");
419 if (!prompt)
420 prompt = PROMPT;
422 start:
423 putprmpt(stderr, prompt, NULL, defstr);
424 if (getinput(input))
425 return (1);
427 if (!strlen(input)) {
428 if (defstr) {
429 (void) strcpy(date, defstr);
430 return (0);
432 puterror(stderr, defmesg, error);
433 goto start;
434 } else if (strcmp(input, "?") == 0) {
435 puthelp(stderr, defmesg, help);
436 goto start;
437 } else if (ckquit && strcmp(input, "q") == 0) {
438 return (3);
439 } else if (ckdate_val(fmt, input)) {
440 puterror(stderr, defmesg, error);
441 goto start;
443 (void) strcpy(date, input);
444 return (0);