diff options
author | aldot <aldot@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2006-08-28 23:31:54 +0000 |
---|---|---|
committer | aldot <aldot@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2006-08-28 23:31:54 +0000 |
commit | d52f45a484fc7fc049ab40db9adc6ead7ea9b122 (patch) | |
tree | 2a57564b8917a983365c765d4daa83032d9f0a17 /coreutils/date.c | |
parent | 2803d256e9decd450b955c2846bf945db72bb79e (diff) | |
download | busybox-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.c | 260 |
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 | 35 | static void maybe_set_utc(int opt) | |
40 | static 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 | |||
75 | static 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 | ||
115 | int date_main(int argc, char **argv) | 41 | int 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 | } | ||
203 | format_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) { |