summaryrefslogtreecommitdiff
path: root/date.c
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>1999-10-05 16:24:54 +0000
committerEric Andersen <andersen@codepoet.org>1999-10-05 16:24:54 +0000
commitcc8ed39b240180b58810784f844e253263594ac3 (patch)
tree15feebbb4be9a9168209609f48f0b100f9364420 /date.c
downloadbusybox-w32-0_29alpha2.tar.gz
busybox-w32-0_29alpha2.tar.bz2
busybox-w32-0_29alpha2.zip
Initial revision0_29alpha2
Diffstat (limited to 'date.c')
-rw-r--r--date.c305
1 files changed, 305 insertions, 0 deletions
diff --git a/date.c b/date.c
new file mode 100644
index 000000000..a52a9a4a8
--- /dev/null
+++ b/date.c
@@ -0,0 +1,305 @@
1#include "internal.h"
2#include <stdlib.h>
3#include <errno.h>
4#include <sys/time.h>
5#include <unistd.h>
6#include <time.h>
7#include <stdio.h>
8#include <getopt.h>
9
10
11/* This 'date' command supports only 2 time setting formats,
12 all the GNU strftime stuff (its in libc, lets use it),
13 setting time using UTC and displaying int, as well as
14 an RFC 822 complient date output for shell scripting
15 mail commands */
16
17const char date_usage[] = "date [-uR] [+FORMAT|+%f] [ [-s|-d] MMDDhhmm[[CC]YY]\n | [[[[CCYY.]MM.DD-]hh:mm[:ss]]]] ]";
18
19static struct option const long_options[] =
20{
21 {"date", required_argument, NULL, 'd'},
22 /* {"rfc-822", no_argument, NULL, 'R'},
23 {"set", required_argument, NULL, 's'},
24 {"uct", no_argument, NULL, 'u'},
25 {"utc", no_argument, NULL, 'u'},
26 {"universal", no_argument, NULL, 'u'}, */
27 {NULL, 0, NULL, 0}
28};
29
30
31
32/* Input parsing code is always bulky - used heavy duty libc stuff as
33 much as possible, missed out a lot of bounds checking */
34
35/* Default input handling to save suprising some people */
36
37struct tm *
38date_conv_time(struct tm *tm_time, const char *t_string) {
39 int nr;
40
41 nr = sscanf(t_string, "%2d%2d%2d%2d%d",
42 &(tm_time->tm_mon),
43 &(tm_time->tm_mday),
44 &(tm_time->tm_hour),
45 &(tm_time->tm_min),
46 &(tm_time->tm_year));
47
48 if(nr < 4 || nr > 5) {
49 fprintf(stderr, "date: invalid date `%s'\n", t_string);
50 exit(1);
51 }
52
53 /* correct for century - minor Y2K problem here? */
54 if(tm_time->tm_year >= 1900)
55 tm_time->tm_year -= 1900;
56 /* adjust date */
57 tm_time->tm_mon -= 1;
58
59 return(tm_time);
60
61}
62
63
64/* The new stuff for LRP */
65
66struct tm *
67date_conv_ftime(struct tm *tm_time, const char *t_string) {
68 struct tm itm_time, jtm_time, ktm_time, \
69 ltm_time, mtm_time, ntm_time;
70
71 itm_time = *tm_time;
72 jtm_time = *tm_time;
73 ktm_time = *tm_time;
74 ltm_time = *tm_time;
75 mtm_time = *tm_time;
76 ntm_time = *tm_time;
77
78 /* Parse input and assign appropriately to tm_time */
79
80 if(sscanf(t_string, "%d:%d:%d",
81 &itm_time.tm_hour,
82 &itm_time.tm_min,
83 &itm_time.tm_sec) == 3 ) {
84
85 *tm_time = itm_time;
86 return(tm_time);
87
88 } else if (sscanf(t_string, "%d:%d",
89 &jtm_time.tm_hour,
90 &jtm_time.tm_min) == 2) {
91
92 *tm_time = jtm_time;
93 return(tm_time);
94
95 } else if (sscanf(t_string, "%d.%d-%d:%d:%d",
96 &ktm_time.tm_mon,
97 &ktm_time.tm_mday,
98 &ktm_time.tm_hour,
99 &ktm_time.tm_min,
100 &ktm_time.tm_sec) == 5) {
101
102 ktm_time.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */
103 *tm_time = ktm_time;
104 return(tm_time);
105
106 } else if (sscanf(t_string, "%d.%d-%d:%d",
107 &ltm_time.tm_mon,
108 &ltm_time.tm_mday,
109 &ltm_time.tm_hour,
110 &ltm_time.tm_min) == 4) {
111
112 ltm_time.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */
113 *tm_time = ltm_time;
114 return(tm_time);
115
116 } else if (sscanf(t_string, "%d.%d.%d-%d:%d:%d",
117 &mtm_time.tm_year,
118 &mtm_time.tm_mon,
119 &mtm_time.tm_mday,
120 &mtm_time.tm_hour,
121 &mtm_time.tm_min,
122 &mtm_time.tm_sec) == 6) {
123
124 mtm_time.tm_year -= 1900; /* Adjust years */
125 mtm_time.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */
126 *tm_time = mtm_time;
127 return(tm_time);
128
129 } else if (sscanf(t_string, "%d.%d.%d-%d:%d",
130 &ntm_time.tm_year,
131 &ntm_time.tm_mon,
132 &ntm_time.tm_mday,
133 &ntm_time.tm_hour,
134 &ntm_time.tm_min) == 5) {
135 ntm_time.tm_year -= 1900; /* Adjust years */
136 ntm_time.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */
137 *tm_time = ntm_time;
138 return(tm_time);
139
140 }
141
142 fprintf(stderr, "date: invalid date `%s'\n", t_string);
143
144 exit(1);
145
146}
147
148
149void
150date_err(void) {
151 fprintf(stderr, "date: only one date argument can be given at a time.\n");
152 exit(1);
153}
154
155int
156date_main(struct FileInfo * i, int argc, char * * argv)
157{
158 char *date_str = NULL;
159 char *date_fmt = NULL;
160 char *t_buff;
161 int set_time = 0;
162 int rfc822 = 0;
163 int utc = 0;
164 int use_arg = 0;
165 int n_args;
166 time_t tm;
167 struct tm tm_time;
168 char optc;
169
170 /* Interpret command line args */
171
172
173 while ((optc = getopt_long (argc, argv, "d:Rs:u", long_options, NULL))
174 != EOF) {
175 switch (optc) {
176 case 0:
177 break;
178
179 case 'R':
180 rfc822 = 1;
181 break;
182
183 case 's':
184 set_time = 1;
185 if(date_str != NULL) date_err();
186 date_str = optarg;
187 break;
188
189 case 'u':
190 utc = 1;
191 if (putenv ("TZ=UTC0") != 0) {
192 fprintf(stderr,"date: memory exhausted\n");
193 return(1);
194 }
195#if LOCALTIME_CACHE
196 tzset ();
197#endif break;
198
199 case 'd':
200 use_arg = 1;
201 if(date_str != NULL) date_err();
202 date_str = optarg;
203 break;
204
205 default:
206 usage(date_usage);
207 break;
208 }
209 }
210
211
212 n_args = argc - optind;
213
214 while (n_args--){
215 switch(argv[optind][0]) {
216 case '+':
217 /* Date format strings */
218 if(date_fmt != NULL) {
219 fprintf(stderr, "date: only one date format can be given.\n");
220 return(1);
221 }
222 date_fmt = &argv[optind][1];
223 break;
224
225 case '\0':
226 break;
227
228 default:
229 /* Anything left over must be a date string to set the time */
230 set_time = 1;
231 if(date_str != NULL) date_err();
232 date_str = argv[optind];
233 break;
234 }
235 optind++;
236 }
237
238
239 /* Now we have parsed all the information except the date format
240 which depends on whether the clock is being set or read */
241
242 time(&tm);
243 memcpy(&tm_time, localtime(&tm), sizeof(tm_time));
244 /* Zero out fields - take her back to midnight!*/
245 if(date_str != NULL) {
246 tm_time.tm_sec = 0;
247 tm_time.tm_min = 0;
248 tm_time.tm_hour = 0;
249 }
250
251 /* Process any date input to UNIX time since 1 Jan 1970 */
252 if(date_str != NULL) {
253
254 if(strchr(date_str, ':') != NULL) {
255 date_conv_ftime(&tm_time, date_str);
256 } else {
257 date_conv_time(&tm_time, date_str);
258 }
259
260 /* Correct any day of week and day of year etc fields */
261 tm = mktime(&tm_time);
262 if (tm < 0 ) {
263 fprintf(stderr, "date: invalid date `%s'\n", date_str);
264 exit(1);
265 }
266
267 /* if setting time, set it */
268 if(set_time) {
269 if( stime(&tm) < 0) {
270 fprintf(stderr, "date: can't set date.\n");
271 exit(1);
272 }
273 }
274 }
275
276 /* Display output */
277
278 /* Deal with format string */
279 if(date_fmt == NULL) {
280 date_fmt = (rfc822
281 ? (utc
282 ? "%a, %_d %b %Y %H:%M:%S GMT"
283 : "%a, %_d %b %Y %H:%M:%S %z")
284 : "%a %b %e %H:%M:%S %Z %Y");
285
286 } else if ( *date_fmt == '\0' ) {
287 /* Imitate what GNU 'date' does with NO format string! */
288 printf ("\n");
289 return(0);
290 }
291
292 /* Handle special conversions */
293
294 if( strncmp( date_fmt, "%f", 2) == 0 ) {
295 date_fmt = "%Y.%m.%d-%H:%M:%S";
296 }
297
298 /* Print OUTPUT (after ALL that!) */
299 t_buff = malloc(201);
300 strftime(t_buff, 200, date_fmt, &tm_time);
301 printf("%s\n", t_buff);
302
303 return(0);
304
305}