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