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