aboutsummaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2009-07-18 04:49:20 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2009-07-18 04:49:20 +0200
commit38dd8aa657d80232d8bbce4ed359af2022f605c7 (patch)
treedf326bb4ee6a083cc5b435a7b12d8ecb1331df8c /libbb
parent7aca89a7a32a1e560c447952c28a8b1e7fb775fc (diff)
downloadbusybox-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.c97
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';