diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2009-07-18 04:49:20 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2009-07-18 04:49:20 +0200 |
commit | 38dd8aa657d80232d8bbce4ed359af2022f605c7 (patch) | |
tree | df326bb4ee6a083cc5b435a7b12d8ecb1331df8c /libbb | |
parent | 7aca89a7a32a1e560c447952c28a8b1e7fb775fc (diff) | |
download | busybox-w32-38dd8aa657d80232d8bbce4ed359af2022f605c7.tar.gz busybox-w32-38dd8aa657d80232d8bbce4ed359af2022f605c7.tar.bz2 busybox-w32-38dd8aa657d80232d8bbce4ed359af2022f605c7.zip |
touch: implement -t TIME (needed for testsuite)
This changes date -d TIME format a bit, makes it more compatible
function old new delta
parse_datestr 391 618 +227
touch_main 360 361 +1
packed_usage 26624 26615 -9
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'libbb')
-rw-r--r-- | libbb/time.c | 97 |
1 files changed, 82 insertions, 15 deletions
diff --git a/libbb/time.c b/libbb/time.c index 1cf2a050e..0816022b9 100644 --- a/libbb/time.c +++ b/libbb/time.c | |||
@@ -16,50 +16,117 @@ void FAST_FUNC parse_datestr(const char *date_str, struct tm *tm_time) | |||
16 | if (last_colon != NULL) { | 16 | if (last_colon != NULL) { |
17 | /* Parse input and assign appropriately to tm_time */ | 17 | /* Parse input and assign appropriately to tm_time */ |
18 | 18 | ||
19 | /* HH:MM */ | ||
19 | if (sscanf(date_str, "%u:%u%c", | 20 | if (sscanf(date_str, "%u:%u%c", |
20 | &tm_time->tm_hour, | 21 | &tm_time->tm_hour, |
21 | &tm_time->tm_min, | 22 | &tm_time->tm_min, |
22 | &end) >= 2) { | 23 | &end) >= 2) { |
23 | /* no adjustments needed */ | 24 | /* no adjustments needed */ |
24 | } else if (sscanf(date_str, "%u.%u-%u:%u%c", | 25 | } else |
26 | /* mm.dd-HH:MM */ | ||
27 | if (sscanf(date_str, "%u.%u-%u:%u%c", | ||
25 | &tm_time->tm_mon, &tm_time->tm_mday, | 28 | &tm_time->tm_mon, &tm_time->tm_mday, |
26 | &tm_time->tm_hour, &tm_time->tm_min, | 29 | &tm_time->tm_hour, &tm_time->tm_min, |
27 | &end) >= 4) { | 30 | &end) >= 4) { |
28 | /* Adjust dates from 1-12 to 0-11 */ | 31 | /* Adjust month from 1-12 to 0-11 */ |
29 | tm_time->tm_mon -= 1; | 32 | tm_time->tm_mon -= 1; |
30 | } else if (sscanf(date_str, "%u.%u.%u-%u:%u%c", &tm_time->tm_year, | 33 | } else |
34 | /* yyyy.mm.dd-HH:MM */ | ||
35 | if (sscanf(date_str, "%u.%u.%u-%u:%u%c", &tm_time->tm_year, | ||
31 | &tm_time->tm_mon, &tm_time->tm_mday, | 36 | &tm_time->tm_mon, &tm_time->tm_mday, |
32 | &tm_time->tm_hour, &tm_time->tm_min, | 37 | &tm_time->tm_hour, &tm_time->tm_min, |
33 | &end) >= 5) { | 38 | &end) >= 5) { |
34 | tm_time->tm_year -= 1900; /* Adjust years */ | 39 | tm_time->tm_year -= 1900; /* Adjust years */ |
35 | tm_time->tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */ | 40 | tm_time->tm_mon -= 1; /* Adjust month from 1-12 to 0-11 */ |
36 | } else if (sscanf(date_str, "%u-%u-%u %u:%u%c", &tm_time->tm_year, | 41 | } else |
42 | /* yyyy-mm-dd HH:MM */ | ||
43 | if (sscanf(date_str, "%u-%u-%u %u:%u%c", &tm_time->tm_year, | ||
37 | &tm_time->tm_mon, &tm_time->tm_mday, | 44 | &tm_time->tm_mon, &tm_time->tm_mday, |
38 | &tm_time->tm_hour, &tm_time->tm_min, | 45 | &tm_time->tm_hour, &tm_time->tm_min, |
39 | &end) >= 5) { | 46 | &end) >= 5) { |
40 | tm_time->tm_year -= 1900; /* Adjust years */ | 47 | tm_time->tm_year -= 1900; /* Adjust years */ |
41 | tm_time->tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */ | 48 | tm_time->tm_mon -= 1; /* Adjust month from 1-12 to 0-11 */ |
42 | //TODO: coreutils 6.9 also accepts "YYYY-MM-DD HH" (no minutes) | 49 | //TODO: coreutils 6.9 also accepts "yyyy-mm-dd HH" (no minutes) |
43 | } else { | 50 | } else { |
44 | bb_error_msg_and_die(bb_msg_invalid_date, date_str); | 51 | bb_error_msg_and_die(bb_msg_invalid_date, date_str); |
45 | } | 52 | } |
46 | if (end == ':') { | 53 | if (end == ':') { |
54 | /* xxx:SS */ | ||
47 | if (sscanf(last_colon + 1, "%u%c", &tm_time->tm_sec, &end) == 1) | 55 | if (sscanf(last_colon + 1, "%u%c", &tm_time->tm_sec, &end) == 1) |
48 | end = '\0'; | 56 | end = '\0'; |
49 | /* else end != NUL and we error out */ | 57 | /* else end != NUL and we error out */ |
50 | } | 58 | } |
51 | } else { | 59 | } else { |
52 | if (sscanf(date_str, "%2u%2u%2u%2u%u%c", &tm_time->tm_mon, | 60 | /* Googled the following on an old date manpage: |
53 | &tm_time->tm_mday, &tm_time->tm_hour, &tm_time->tm_min, | 61 | * |
54 | &tm_time->tm_year, &end) < 4) | 62 | * The canonical representation for setting the date/time is: |
63 | * cc Century (either 19 or 20) | ||
64 | * yy Year in abbreviated form (e.g. 89, 06) | ||
65 | * mm Numeric month, a number from 1 to 12 | ||
66 | * dd Day, a number from 1 to 31 | ||
67 | * HH Hour, a number from 0 to 23 | ||
68 | * MM Minutes, a number from 0 to 59 | ||
69 | * ss Seconds, a number from 0 to 61 (with leap seconds) | ||
70 | * Everything but the minutes is optional | ||
71 | * | ||
72 | * This coincides with the format of "touch -t TIME" | ||
73 | */ | ||
74 | int len = strchrnul(date_str, '.') - date_str; | ||
75 | |||
76 | /* MM[.SS] */ | ||
77 | if (len == 2 && sscanf(date_str, "%2u%2u%2u%2u%2u%c" + 12, | ||
78 | &tm_time->tm_min, | ||
79 | &end) >= 1) { | ||
80 | } else | ||
81 | /* HHMM[.SS] */ | ||
82 | if (len == 4 && sscanf(date_str, "%2u%2u%2u%2u%2u%c" + 9, | ||
83 | &tm_time->tm_hour, | ||
84 | &tm_time->tm_min, | ||
85 | &end) >= 2) { | ||
86 | } else | ||
87 | /* ddHHMM[.SS] */ | ||
88 | if (len == 6 && sscanf(date_str, "%2u%2u%2u%2u%2u%c" + 6, | ||
89 | &tm_time->tm_mday, | ||
90 | &tm_time->tm_hour, | ||
91 | &tm_time->tm_min, | ||
92 | &end) >= 3) { | ||
93 | } else | ||
94 | /* mmddHHMM[.SS] */ | ||
95 | if (len == 8 && sscanf(date_str, "%2u%2u%2u%2u%2u%c" + 3, | ||
96 | &tm_time->tm_mon, | ||
97 | &tm_time->tm_mday, | ||
98 | &tm_time->tm_hour, | ||
99 | &tm_time->tm_min, | ||
100 | &end) >= 4) { | ||
101 | /* Adjust month from 1-12 to 0-11 */ | ||
102 | tm_time->tm_mon -= 1; | ||
103 | } else | ||
104 | /* yymmddHHMM[.SS] */ | ||
105 | if (len == 10 && sscanf(date_str, "%2u%2u%2u%2u%2u%c", | ||
106 | &tm_time->tm_year, | ||
107 | &tm_time->tm_mon, | ||
108 | &tm_time->tm_mday, | ||
109 | &tm_time->tm_hour, | ||
110 | &tm_time->tm_min, | ||
111 | &end) >= 5) { | ||
112 | /* Adjust month from 1-12 to 0-11 */ | ||
113 | tm_time->tm_mon -= 1; | ||
114 | } else | ||
115 | /* yyyymmddHHMM[.SS] */ | ||
116 | if (len == 12 && sscanf(date_str, "%4u%2u%2u%2u%2u%c", | ||
117 | &tm_time->tm_year, | ||
118 | &tm_time->tm_mon, | ||
119 | &tm_time->tm_mday, | ||
120 | &tm_time->tm_hour, | ||
121 | &tm_time->tm_min, | ||
122 | &end) >= 5) { | ||
123 | tm_time->tm_year -= 1900; /* Adjust years */ | ||
124 | tm_time->tm_mon -= 1; /* Adjust month from 1-12 to 0-11 */ | ||
125 | } else { | ||
55 | bb_error_msg_and_die(bb_msg_invalid_date, date_str); | 126 | bb_error_msg_and_die(bb_msg_invalid_date, date_str); |
56 | /* correct for century - minor Y2K problem here? */ | ||
57 | if (tm_time->tm_year >= 1900) { | ||
58 | tm_time->tm_year -= 1900; | ||
59 | } | 127 | } |
60 | /* adjust date */ | ||
61 | tm_time->tm_mon -= 1; | ||
62 | if (end == '.') { | 128 | if (end == '.') { |
129 | /* xxx.SS */ | ||
63 | if (sscanf(strchr(date_str, '.') + 1, "%u%c", | 130 | if (sscanf(strchr(date_str, '.') + 1, "%u%c", |
64 | &tm_time->tm_sec, &end) == 1) | 131 | &tm_time->tm_sec, &end) == 1) |
65 | end = '\0'; | 132 | end = '\0'; |