aboutsummaryrefslogtreecommitdiff
path: root/coreutils/date.c
diff options
context:
space:
mode:
authoraldot <aldot@69ca8d6d-28ef-0310-b511-8ec308f3f277>2006-08-28 23:31:54 +0000
committeraldot <aldot@69ca8d6d-28ef-0310-b511-8ec308f3f277>2006-08-28 23:31:54 +0000
commitd52f45a484fc7fc049ab40db9adc6ead7ea9b122 (patch)
tree2a57564b8917a983365c765d4daa83032d9f0a17 /coreutils/date.c
parent2803d256e9decd450b955c2846bf945db72bb79e (diff)
downloadbusybox-w32-d52f45a484fc7fc049ab40db9adc6ead7ea9b122.tar.gz
busybox-w32-d52f45a484fc7fc049ab40db9adc6ead7ea9b122.tar.bz2
busybox-w32-d52f45a484fc7fc049ab40db9adc6ead7ea9b122.zip
- pull from busybox_scratch: r15829:15850
Various fixes, cleanups and shrinkage: saves 952 Bytes: text data bss dec hex filename 1087742 15853 790632 1894227 1ce753 ../busybox/busybox.old 1086790 15853 790632 1893275 1ce39b busybox via: # scripts/bloat-o-meter ../busybox/busybox_unstripped.old busybox_unstripped function old new delta ipcrm_main 756 822 +66 getval - 61 +61 maybe_set_utc - 40 +40 udhcpc_main 2896 2912 +16 md5_hash_block 428 437 +9 opt 8 16 +8 qgravechar 106 110 +4 make_bitmap 292 295 +3 inflate_unzip 2056 2059 +3 add_partition 1412 1414 +2 __parsespent 156 158 +2 qrealloc 41 42 +1 format - 1 +1 catv_main 313 314 +1 watch_main 293 292 -1 varunset 81 80 -1 part 1 - -1 check_if_skip 837 836 -1 start_stop_daemon_main 840 837 -3 create_lost_and_found 175 172 -3 supress_non_delimited_lines 4 - -4 static.l 4 - -4 static.c 5 1 -4 bsd_sum_file 237 233 -4 eval2 338 332 -6 arithmetic_common 166 158 -8 cmpfunc 22 5 -17 cksum_main 294 275 -19 cmp_main 465 439 -26 dd_main 1535 1508 -27 rmmod_main 376 333 -43 cut_file 727 644 -83 ipcs_main 3809 3721 -88 cut_main 722 614 -108 date_main 1443 1263 -180 remove_ids 222 - -222 ------------------------------------------------------------------------------ (add/remove: 3/4 grow/shrink: 11/18 up/down: 217/-853) Total: -636 bytes git-svn-id: svn://busybox.net/trunk/busybox@16009 69ca8d6d-28ef-0310-b511-8ec308f3f277
Diffstat (limited to 'coreutils/date.c')
-rw-r--r--coreutils/date.c260
1 files changed, 123 insertions, 137 deletions
diff --git a/coreutils/date.c b/coreutils/date.c
index f08392ec2..2a82e0413 100644
--- a/coreutils/date.c
+++ b/coreutils/date.c
@@ -5,14 +5,17 @@
5 * by Matthew Grant <grantma@anathoth.gen.nz> 5 * by Matthew Grant <grantma@anathoth.gen.nz>
6 * 6 *
7 * iso-format handling added by Robert Griebl <griebl@gmx.de> 7 * iso-format handling added by Robert Griebl <griebl@gmx.de>
8 * bugfixes and cleanup by Bernhard Fischer
8 * 9 *
9 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 10 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
10*/ 11*/
11 12
13#include "busybox.h"
14
12/* This 'date' command supports only 2 time setting formats, 15/* This 'date' command supports only 2 time setting formats,
13 all the GNU strftime stuff (its in libc, lets use it), 16 all the GNU strftime stuff (its in libc, lets use it),
14 setting time using UTC and displaying int, as well as 17 setting time using UTC and displaying it, as well as
15 an RFC 822 complient date output for shell scripting 18 an RFC 2822 compliant date output for shell scripting
16 mail commands */ 19 mail commands */
17 20
18/* Input parsing code is always bulky - used heavy duty libc stuff as 21/* Input parsing code is always bulky - used heavy duty libc stuff as
@@ -20,13 +23,6 @@
20 23
21/* Default input handling to save surprising some people */ 24/* Default input handling to save surprising some people */
22 25
23#include <stdlib.h>
24#include <errno.h>
25#include <unistd.h>
26#include <time.h>
27#include <stdio.h>
28#include <string.h>
29#include "busybox.h"
30 26
31#define DATE_OPT_RFC2822 0x01 27#define DATE_OPT_RFC2822 0x01
32#define DATE_OPT_SET 0x02 28#define DATE_OPT_SET 0x02
@@ -36,119 +32,45 @@
36#define DATE_OPT_TIMESPEC 0x20 32#define DATE_OPT_TIMESPEC 0x20
37#define DATE_OPT_HINT 0x40 33#define DATE_OPT_HINT 0x40
38 34
39 35static void maybe_set_utc(int opt)
40static struct tm *date_conv_time(struct tm *tm_time, const char *t_string)
41{
42 int nr;
43 char *cp;
44
45 nr = sscanf(t_string, "%2d%2d%2d%2d%d", &(tm_time->tm_mon),
46 &(tm_time->tm_mday), &(tm_time->tm_hour), &(tm_time->tm_min),
47 &(tm_time->tm_year));
48
49 if (nr < 4 || nr > 5) {
50 bb_error_msg_and_die(bb_msg_invalid_date, t_string);
51 }
52
53 cp = strchr(t_string, '.');
54 if (cp) {
55 nr = sscanf(cp + 1, "%2d", &(tm_time->tm_sec));
56 if (nr != 1) {
57 bb_error_msg_and_die(bb_msg_invalid_date, t_string);
58 }
59 }
60
61 /* correct for century - minor Y2K problem here? */
62 if (tm_time->tm_year >= 1900) {
63 tm_time->tm_year -= 1900;
64 }
65 /* adjust date */
66 tm_time->tm_mon -= 1;
67
68 return (tm_time);
69
70}
71
72
73/* The new stuff for LRP */
74
75static struct tm *date_conv_ftime(struct tm *tm_time, const char *t_string)
76{ 36{
77 struct tm t; 37 if ((opt & DATE_OPT_UTC) && putenv("TZ=UTC0") != 0)
78 38 bb_error_msg_and_die(bb_msg_memory_exhausted);
79 /* Parse input and assign appropriately to tm_time */
80
81 if (t = *tm_time, sscanf(t_string, "%d:%d:%d", &t.tm_hour, &t.tm_min,
82 &t.tm_sec) == 3) {
83 /* no adjustments needed */
84 } else if (t = *tm_time, sscanf(t_string, "%d:%d", &t.tm_hour,
85 &t.tm_min) == 2) {
86 /* no adjustments needed */
87 } else if (t = *tm_time, sscanf(t_string, "%d.%d-%d:%d:%d", &t.tm_mon,
88 &t.tm_mday, &t.tm_hour,
89 &t.tm_min, &t.tm_sec) == 5) {
90 /* Adjust dates from 1-12 to 0-11 */
91 t.tm_mon -= 1;
92 } else if (t = *tm_time, sscanf(t_string, "%d.%d-%d:%d", &t.tm_mon,
93 &t.tm_mday,
94 &t.tm_hour, &t.tm_min) == 4) {
95 /* Adjust dates from 1-12 to 0-11 */
96 t.tm_mon -= 1;
97 } else if (t = *tm_time, sscanf(t_string, "%d.%d.%d-%d:%d:%d", &t.tm_year,
98 &t.tm_mon, &t.tm_mday,
99 &t.tm_hour, &t.tm_min,
100 &t.tm_sec) == 6) {
101 t.tm_year -= 1900; /* Adjust years */
102 t.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */
103 } else if (t = *tm_time, sscanf(t_string, "%d.%d.%d-%d:%d", &t.tm_year,
104 &t.tm_mon, &t.tm_mday,
105 &t.tm_hour, &t.tm_min) == 5) {
106 t.tm_year -= 1900; /* Adjust years */
107 t.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */
108 } else {
109 bb_error_msg_and_die(bb_msg_invalid_date, t_string);
110 }
111 *tm_time = t;
112 return (tm_time);
113} 39}
114 40
115int date_main(int argc, char **argv) 41int date_main(int argc, char **argv)
116{ 42{
117 char *date_str = NULL;
118 char *date_fmt = NULL;
119 int set_time;
120 int utc;
121 time_t tm; 43 time_t tm;
122 unsigned long opt;
123 struct tm tm_time; 44 struct tm tm_time;
45 unsigned long opt;
46 int ifmt = -1;
47 char *date_str = NULL;
48 char *date_fmt = NULL;
124 char *filename = NULL; 49 char *filename = NULL;
125
126 int ifmt = 0;
127 char *isofmt_arg; 50 char *isofmt_arg;
128 char *hintfmt_arg; 51 char *hintfmt_arg;
129 52
130 bb_opt_complementally = "?:d--s:s--d"; 53 bb_opt_complementally = "?:d--s:s--d"
54 USE_FEATURE_DATE_ISOFMT(":R--I:I--R");
131 opt = bb_getopt_ulflags(argc, argv, "Rs:ud:r:" 55 opt = bb_getopt_ulflags(argc, argv, "Rs:ud:r:"
132 USE_FEATURE_DATE_ISOFMT("I::D:"), 56 USE_FEATURE_DATE_ISOFMT("I::D:"),
133 &date_str, &date_str, &filename 57 &date_str, &date_str, &filename
134 USE_FEATURE_DATE_ISOFMT(, &isofmt_arg, &hintfmt_arg)); 58 USE_FEATURE_DATE_ISOFMT(, &isofmt_arg, &hintfmt_arg));
135 set_time = opt & DATE_OPT_SET; 59 maybe_set_utc(opt);
136 utc = opt & DATE_OPT_UTC;
137 if (utc && putenv("TZ=UTC0") != 0) {
138 bb_error_msg_and_die(bb_msg_memory_exhausted);
139 }
140 60
141 if(ENABLE_FEATURE_DATE_ISOFMT && (opt & DATE_OPT_TIMESPEC)) { 61 if (ENABLE_FEATURE_DATE_ISOFMT && (opt & DATE_OPT_TIMESPEC)) {
142 if (!isofmt_arg) { 62 if (!isofmt_arg) {
143 ifmt = 1; 63 ifmt = 0; /* default is date */
144 } else { 64 } else {
145 char *isoformats[]={"date","hours","minutes","seconds"}; 65 const char * const isoformats[] =
146 for(ifmt = 4; ifmt;) 66 {"date", "hours", "minutes", "seconds"};
147 if(!strcmp(isofmt_arg,isoformats[--ifmt])) 67
68 for (ifmt = 0; ifmt < 4; ifmt++)
69 if (!strcmp(isofmt_arg, isoformats[ifmt])) {
148 break; 70 break;
149 } 71 }
150 if (!ifmt) { 72 if (ifmt == 4) /* parse error */
151 bb_show_usage(); 73 bb_show_usage();
152 } 74 }
153 } 75 }
154 76
@@ -156,18 +78,19 @@ int date_main(int argc, char **argv)
156 if ((date_fmt == NULL) && (optind < argc) && (argv[optind][0] == '+')) { 78 if ((date_fmt == NULL) && (optind < argc) && (argv[optind][0] == '+')) {
157 date_fmt = &argv[optind][1]; /* Skip over the '+' */ 79 date_fmt = &argv[optind][1]; /* Skip over the '+' */
158 } else if (date_str == NULL) { 80 } else if (date_str == NULL) {
159 set_time = 1; 81 opt |= DATE_OPT_SET;
160 date_str = argv[optind]; 82 date_str = argv[optind];
161 } 83 }
162 84
163 /* Now we have parsed all the information except the date format 85 /* Now we have parsed all the information except the date format
164 which depends on whether the clock is being set or read */ 86 which depends on whether the clock is being set or read */
165 87
166 if(filename) { 88 if (filename) {
167 struct stat statbuf; 89 struct stat statbuf;
168 xstat(filename,&statbuf); 90 xstat(filename, &statbuf);
169 tm=statbuf.st_mtime; 91 tm = statbuf.st_mtime;
170 } else time(&tm); 92 } else
93 time(&tm);
171 memcpy(&tm_time, localtime(&tm), sizeof(tm_time)); 94 memcpy(&tm_time, localtime(&tm), sizeof(tm_time));
172 /* Zero out fields - take her back to midnight! */ 95 /* Zero out fields - take her back to midnight! */
173 if (date_str != NULL) { 96 if (date_str != NULL) {
@@ -179,9 +102,64 @@ int date_main(int argc, char **argv)
179 if (ENABLE_FEATURE_DATE_ISOFMT && (opt & DATE_OPT_HINT)) { 102 if (ENABLE_FEATURE_DATE_ISOFMT && (opt & DATE_OPT_HINT)) {
180 strptime(date_str, hintfmt_arg, &tm_time); 103 strptime(date_str, hintfmt_arg, &tm_time);
181 } else if (strchr(date_str, ':') != NULL) { 104 } else if (strchr(date_str, ':') != NULL) {
182 date_conv_ftime(&tm_time, date_str); 105 /* Parse input and assign appropriately to tm_time */
106
107 if (sscanf(date_str, "%d:%d:%d", &tm_time.tm_hour, &tm_time.tm_min,
108 &tm_time.tm_sec) == 3) {
109 /* no adjustments needed */
110 } else if (sscanf(date_str, "%d:%d", &tm_time.tm_hour,
111 &tm_time.tm_min) == 2) {
112 /* no adjustments needed */
113 } else if (sscanf(date_str, "%d.%d-%d:%d:%d", &tm_time.tm_mon,
114 &tm_time.tm_mday, &tm_time.tm_hour,
115 &tm_time.tm_min, &tm_time.tm_sec) == 5) {
116 /* Adjust dates from 1-12 to 0-11 */
117 tm_time.tm_mon -= 1;
118 } else if (sscanf(date_str, "%d.%d-%d:%d", &tm_time.tm_mon,
119 &tm_time.tm_mday,
120 &tm_time.tm_hour, &tm_time.tm_min) == 4) {
121 /* Adjust dates from 1-12 to 0-11 */
122 tm_time.tm_mon -= 1;
123 } else if (sscanf(date_str, "%d.%d.%d-%d:%d:%d", &tm_time.tm_year,
124 &tm_time.tm_mon, &tm_time.tm_mday,
125 &tm_time.tm_hour, &tm_time.tm_min,
126 &tm_time.tm_sec) == 6) {
127 tm_time.tm_year -= 1900; /* Adjust years */
128 tm_time.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */
129 } else if (sscanf(date_str, "%d.%d.%d-%d:%d", &tm_time.tm_year,
130 &tm_time.tm_mon, &tm_time.tm_mday,
131 &tm_time.tm_hour, &tm_time.tm_min) == 5) {
132 tm_time.tm_year -= 1900; /* Adjust years */
133 tm_time.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */
134 } else {
135 bb_error_msg_and_die(bb_msg_invalid_date, date_str);
136 }
183 } else { 137 } else {
184 date_conv_time(&tm_time, date_str); 138 int nr;
139 char *cp;
140
141 nr = sscanf(date_str, "%2d%2d%2d%2d%d", &tm_time.tm_mon,
142 &tm_time.tm_mday, &tm_time.tm_hour, &tm_time.tm_min,
143 &tm_time.tm_year);
144
145 if (nr < 4 || nr > 5) {
146 bb_error_msg_and_die(bb_msg_invalid_date, date_str);
147 }
148
149 cp = strchr(date_str, '.');
150 if (cp) {
151 nr = sscanf(cp + 1, "%2d", &tm_time.tm_sec);
152 if (nr != 1) {
153 bb_error_msg_and_die(bb_msg_invalid_date, date_str);
154 }
155 }
156
157 /* correct for century - minor Y2K problem here? */
158 if (tm_time.tm_year >= 1900) {
159 tm_time.tm_year -= 1900;
160 }
161 /* adjust date */
162 tm_time.tm_mon -= 1;
185 } 163 }
186 164
187 /* Correct any day of week and day of year etc. fields */ 165 /* Correct any day of week and day of year etc. fields */
@@ -190,12 +168,10 @@ int date_main(int argc, char **argv)
190 if (tm < 0) { 168 if (tm < 0) {
191 bb_error_msg_and_die(bb_msg_invalid_date, date_str); 169 bb_error_msg_and_die(bb_msg_invalid_date, date_str);
192 } 170 }
193 if (utc && putenv("TZ=UTC0") != 0) { 171 maybe_set_utc(opt);
194 bb_error_msg_and_die(bb_msg_memory_exhausted);
195 }
196 172
197 /* if setting time, set it */ 173 /* if setting time, set it */
198 if (set_time && stime(&tm) < 0) { 174 if ((opt & DATE_OPT_SET) && stime(&tm) < 0) {
199 bb_perror_msg("cannot set date"); 175 bb_perror_msg("cannot set date");
200 } 176 }
201 } 177 }
@@ -203,33 +179,43 @@ int date_main(int argc, char **argv)
203 /* Display output */ 179 /* Display output */
204 180
205 /* Deal with format string */ 181 /* Deal with format string */
182
206 if (date_fmt == NULL) { 183 if (date_fmt == NULL) {
207 /* Start with the default case */ 184 int i;
208 185 date_fmt = xzalloc(32);
209 date_fmt = (opt & DATE_OPT_RFC2822 ? 186 if (ENABLE_FEATURE_DATE_ISOFMT && ifmt >= 0) {
210 (utc ? "%a, %d %b %Y %H:%M:%S GMT" : 187 strcpy(date_fmt, "%Y-%m-%d");
211 "%a, %d %b %Y %H:%M:%S %z") : 188 if (ifmt > 0) {
212 "%a %b %e %H:%M:%S %Z %Y"); 189 i = 8;
213 190 date_fmt[i++] = 'T';
214 if (ENABLE_FEATURE_DATE_ISOFMT) { 191 date_fmt[i++] = '%';
215 if (ifmt == 4) 192 date_fmt[i++] = 'H';
216 date_fmt = utc ? "%Y-%m-%dT%H:%M:%SZ" : "%Y-%m-%dT%H:%M:%S%z"; 193 if (ifmt > 1) {
217 else if (ifmt == 3) 194 date_fmt[i++] = ':';
218 date_fmt = utc ? "%Y-%m-%dT%H:%MZ" : "%Y-%m-%dT%H:%M%z"; 195 date_fmt[i++] = '%';
219 else if (ifmt == 2) 196 date_fmt[i++] = 'M';
220 date_fmt = utc ? "%Y-%m-%dT%HZ" : "%Y-%m-%dT%H%z"; 197 }
221 else if (ifmt == 1) 198 if (ifmt > 2) {
222 date_fmt = "%Y-%m-%d"; 199 date_fmt[i++] = ':';
223 } 200 date_fmt[i++] = '%';
201 date_fmt[i++] = 'S';
202 }
203format_utc:
204 date_fmt[i++] = '%';
205 date_fmt[i] = (opt & DATE_OPT_UTC) ? 'Z' : 'z';
206 }
207 } else if (opt & DATE_OPT_RFC2822) {
208 strcpy(date_fmt, "%a, %d %b %Y %H:%M:%S ");
209 i = 22;
210 goto format_utc;
211 } else /* default case */
212 date_fmt = "%a %b %e %H:%M:%S %Z %Y";
224 } 213 }
225
226 if (*date_fmt == '\0') {
227 214
215 if (*date_fmt == '\0') {
228 /* With no format string, just print a blank line */ 216 /* With no format string, just print a blank line */
229 217 *bb_common_bufsiz1 = 0;
230 *bb_common_bufsiz1=0;
231 } else { 218 } else {
232
233 /* Handle special conversions */ 219 /* Handle special conversions */
234 220
235 if (strncmp(date_fmt, "%f", 2) == 0) { 221 if (strncmp(date_fmt, "%f", 2) == 0) {