[SETUPLIB] Improve the bootloader 'validity' checks -- Addendum to f06734e5 (r74512).
[reactos.git] / base / shell / cmd / date.c
1 /*
2 * DATE.C - date internal command.
3 *
4 *
5 * History:
6 *
7 * 08 Jul 1998 (John P. Price)
8 * started.
9 *
10 * 20 Jul 1998 (John P. Price)
11 * corrected number of days for December from 30 to 31.
12 * (Thanx to Steffen Kaiser for bug report)
13 *
14 * 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
15 * added config.h include
16 *
17 * 29-Jul-1998 (Rob Lake)
18 * fixed stand-alone mode.
19 * Added Pacific C compatible dos_getdate functions
20 *
21 * 09-Jan-1999 (Eric Kohl)
22 * Added locale support
23 *
24 * 23-Jan-1999 (Eric Kohl)
25 * Unicode and redirection safe!
26 *
27 * 04-Feb-1999 (Eric Kohl)
28 * Fixed date input bug.
29 *
30 * 03-Apr-2005 (Magnus Olsen <magnus@greatlord.com>)
31 * Remove all hardcoded strings in En.rc
32 */
33
34 #include "precomp.h"
35
36 #ifdef INCLUDE_CMD_DATE
37
38
39 static WORD awMonths[2][13] =
40 {
41 {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
42 {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
43 };
44
45
46 static VOID
47 PrintDateString (VOID)
48 {
49 switch (nDateFormat)
50 {
51 case 0: /* mmddyy */
52 default:
53 ConOutResPrintf(STRING_DATE_HELP1, cDateSeparator, cDateSeparator);
54 break;
55
56 case 1: /* ddmmyy */
57 ConOutResPrintf(STRING_DATE_HELP2, cDateSeparator, cDateSeparator);
58 break;
59
60 case 2: /* yymmdd */
61 ConOutResPrintf(STRING_DATE_HELP3, cDateSeparator, cDateSeparator);
62 break;
63 }
64 }
65
66 static BOOL
67 ReadNumber (LPTSTR *s, LPWORD lpwValue)
68 {
69 if (_istdigit (**s))
70 {
71 while (_istdigit (**s))
72 {
73 *lpwValue = *lpwValue * 10 + **s - _T('0');
74 (*s)++;
75 }
76 return TRUE;
77 }
78 return FALSE;
79 }
80
81 static BOOL
82 ReadSeparator (LPTSTR *s)
83 {
84 if (**s == _T('/') || **s == _T('-') || **s == cDateSeparator)
85 {
86 (*s)++;
87 return TRUE;
88 }
89 return FALSE;
90 }
91
92 static BOOL
93 ParseDate (LPTSTR s)
94 {
95 SYSTEMTIME d;
96 unsigned char leap;
97 LPTSTR p = s;
98
99 if (!*s)
100 return TRUE;
101
102 GetLocalTime (&d);
103
104 d.wYear = 0;
105 d.wDay = 0;
106 d.wMonth = 0;
107
108 switch (nDateFormat)
109 {
110 case 0: /* mmddyy */
111 default:
112 if (!ReadNumber (&p, &d.wMonth))
113 return FALSE;
114 if (!ReadSeparator (&p))
115 return FALSE;
116 if (!ReadNumber (&p, &d.wDay))
117 return FALSE;
118 if (!ReadSeparator (&p))
119 return FALSE;
120 if (!ReadNumber (&p, &d.wYear))
121 return FALSE;
122 break;
123
124 case 1: /* ddmmyy */
125 if (!ReadNumber (&p, &d.wDay))
126 return FALSE;
127 if (!ReadSeparator (&p))
128 return FALSE;
129 if (!ReadNumber (&p, &d.wMonth))
130 return FALSE;
131 if (!ReadSeparator (&p))
132 return FALSE;
133 if (!ReadNumber (&p, &d.wYear))
134 return FALSE;
135 break;
136
137 case 2: /* yymmdd */
138 if (!ReadNumber (&p, &d.wYear))
139 return FALSE;
140 if (!ReadSeparator (&p))
141 return FALSE;
142 if (!ReadNumber (&p, &d.wMonth))
143 return FALSE;
144 if (!ReadSeparator (&p))
145 return FALSE;
146 if (!ReadNumber (&p, &d.wDay))
147 return FALSE;
148 break;
149 }
150
151 /* if only entered two digits: */
152 /* assume 2000's if value less than 80 */
153 /* assume 1900's if value greater or equal 80 */
154 if (d.wYear <= 99)
155 {
156 if (d.wYear >= 80)
157 d.wYear = 1900 + d.wYear;
158 else
159 d.wYear = 2000 + d.wYear;
160 }
161
162 leap = (!(d.wYear % 4) && (d.wYear % 100)) || !(d.wYear % 400);
163
164 if ((d.wMonth >= 1 && d.wMonth <= 12) &&
165 (d.wDay >= 1 && d.wDay <= awMonths[leap][d.wMonth]) &&
166 (d.wYear >= 1980 && d.wYear <= 2099))
167 {
168 SetLocalTime (&d);
169 return TRUE;
170 }
171
172 return FALSE;
173 }
174
175
176 INT cmd_date (LPTSTR param)
177 {
178 LPTSTR *arg;
179 INT argc;
180 INT i;
181 BOOL bPrompt = TRUE;
182 INT nDateString = -1;
183
184 if (!_tcsncmp (param, _T("/?"), 2))
185 {
186 ConOutResPaging(TRUE,STRING_DATE_HELP4);
187 return 0;
188 }
189
190 nErrorLevel = 0;
191
192 /* build parameter array */
193 arg = split (param, &argc, FALSE, FALSE);
194
195 /* check for options */
196 for (i = 0; i < argc; i++)
197 {
198 if (_tcsicmp (arg[i], _T("/t")) == 0)
199 bPrompt = FALSE;
200 if ((*arg[i] != _T('/')) && (nDateString == -1))
201 nDateString = i;
202 }
203
204 if (nDateString == -1)
205 ConOutPrintf(_T("%s"), GetDateString());
206
207 if (!bPrompt)
208 {
209 freep (arg);
210 return 0;
211 }
212
213 if (nDateString == -1)
214 {
215 while (TRUE) /* forever loop */
216 {
217 TCHAR s[40];
218
219 PrintDateString ();
220 ConInString (s, 40);
221 TRACE ("\'%s\'\n", debugstr_aw(s));
222 while (*s && s[_tcslen (s) - 1] < _T(' '))
223 s[_tcslen (s) - 1] = _T('\0');
224 if (ParseDate (s))
225 {
226 freep (arg);
227 return 0;
228 }
229 ConErrResPuts(STRING_DATE_ERROR);
230 }
231 }
232 else
233 {
234 if (!ParseDate (arg[nDateString]))
235 {
236 while (TRUE) /* forever loop */
237 {
238 TCHAR s[40];
239 ConErrResPuts(STRING_DATE_ERROR);
240
241 PrintDateString ();
242 ConInString (s, 40);
243
244 while (*s && s[_tcslen (s) - 1] < _T(' '))
245 s[_tcslen (s) - 1] = _T('\0');
246 if (ParseDate (s))
247 {
248 freep (arg);
249 return 0;
250 }
251 }
252 }
253 }
254
255 freep (arg);
256 return 0;
257 }
258 #endif /* INCLUDE_CMD_DATE */
259
260 /* EOF */