Changeset 1770 in MondoRescue for branches/stable/mindi-busybox/coreutils/date.c
- Timestamp:
- Nov 6, 2007, 11:01:53 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/stable/mindi-busybox/coreutils/date.c
r821 r1770 6 6 * 7 7 * iso-format handling added by Robert Griebl <griebl@gmx.de> 8 * bugfixes and cleanup by Bernhard Fischer 8 9 * 9 10 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 10 11 */ 11 12 12 #include <stdlib.h> 13 #include <errno.h> 14 #include <unistd.h> 15 #include <time.h> 16 #include <stdio.h> 17 #include <string.h> 18 #include "busybox.h" 13 #include "libbb.h" 19 14 20 15 /* This 'date' command supports only 2 time setting formats, 21 16 all the GNU strftime stuff (its in libc, lets use it), 22 setting time using UTC and displaying i nt, as well as23 an RFC 822 complient date output for shell scripting17 setting time using UTC and displaying it, as well as 18 an RFC 2822 compliant date output for shell scripting 24 19 mail commands */ 25 20 … … 29 24 /* Default input handling to save surprising some people */ 30 25 31 static struct tm *date_conv_time(struct tm *tm_time, const char *t_string)32 {33 int nr;34 char *cp;35 36 nr = sscanf(t_string, "%2d%2d%2d%2d%d", &(tm_time->tm_mon),37 &(tm_time->tm_mday), &(tm_time->tm_hour), &(tm_time->tm_min),38 &(tm_time->tm_year));39 40 if (nr < 4 || nr > 5) {41 bb_error_msg_and_die(bb_msg_invalid_date, t_string);42 }43 44 cp = strchr(t_string, '.');45 if (cp) {46 nr = sscanf(cp + 1, "%2d", &(tm_time->tm_sec));47 if (nr != 1) {48 bb_error_msg_and_die(bb_msg_invalid_date, t_string);49 }50 }51 52 /* correct for century - minor Y2K problem here? */53 if (tm_time->tm_year >= 1900) {54 tm_time->tm_year -= 1900;55 }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 66 static struct tm *date_conv_ftime(struct tm *tm_time, const char *t_string)67 {68 struct tm t;69 70 /* Parse input and assign appropriately to tm_time */71 72 if (t = *tm_time, sscanf(t_string, "%d:%d:%d", &t.tm_hour, &t.tm_min,73 &t.tm_sec) == 3) {74 /* no adjustments needed */75 } else if (t = *tm_time, sscanf(t_string, "%d:%d", &t.tm_hour,76 &t.tm_min) == 2) {77 /* no adjustments needed */78 } else if (t = *tm_time, sscanf(t_string, "%d.%d-%d:%d:%d", &t.tm_mon,79 &t.tm_mday, &t.tm_hour,80 &t.tm_min, &t.tm_sec) == 5) {81 /* Adjust dates from 1-12 to 0-11 */82 t.tm_mon -= 1;83 } else if (t = *tm_time, sscanf(t_string, "%d.%d-%d:%d", &t.tm_mon,84 &t.tm_mday,85 &t.tm_hour, &t.tm_min) == 4) {86 /* Adjust dates from 1-12 to 0-11 */87 t.tm_mon -= 1;88 } else if (t = *tm_time, sscanf(t_string, "%d.%d.%d-%d:%d:%d", &t.tm_year,89 &t.tm_mon, &t.tm_mday,90 &t.tm_hour, &t.tm_min,91 &t.tm_sec) == 6) {92 t.tm_year -= 1900; /* Adjust years */93 t.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */94 } else if (t = *tm_time, sscanf(t_string, "%d.%d.%d-%d:%d", &t.tm_year,95 &t.tm_mon, &t.tm_mday,96 &t.tm_hour, &t.tm_min) == 5) {97 t.tm_year -= 1900; /* Adjust years */98 t.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */99 } else {100 bb_error_msg_and_die(bb_msg_invalid_date, t_string);101 }102 *tm_time = t;103 return (tm_time);104 }105 26 106 27 #define DATE_OPT_RFC2822 0x01 … … 112 33 #define DATE_OPT_HINT 0x40 113 34 35 static void maybe_set_utc(int opt) 36 { 37 if (opt & DATE_OPT_UTC) 38 putenv((char*)"TZ=UTC0"); 39 } 40 41 int date_main(int argc, char **argv); 114 42 int date_main(int argc, char **argv) 115 43 { 44 time_t tm; 45 struct tm tm_time; 46 unsigned opt; 47 int ifmt = -1; 116 48 char *date_str = NULL; 117 49 char *date_fmt = NULL; 118 int set_time;119 int utc;120 time_t tm;121 unsigned long opt;122 struct tm tm_time;123 50 char *filename = NULL; 124 125 int ifmt = 0;126 51 char *isofmt_arg; 127 52 char *hintfmt_arg; 128 53 129 bb_opt_complementally = "?:d--s:s--d"; 130 opt = bb_getopt_ulflags(argc, argv, "Rs:ud:r:" 131 USE_FEATURE_DATE_ISOFMT("I::D:"), 132 &date_str, &date_str, &filename 133 USE_FEATURE_DATE_ISOFMT(, &isofmt_arg, &hintfmt_arg)); 134 set_time = opt & DATE_OPT_SET; 135 utc = opt & DATE_OPT_UTC; 136 if (utc && putenv("TZ=UTC0") != 0) { 137 bb_error_msg_and_die(bb_msg_memory_exhausted); 138 } 139 140 if(ENABLE_FEATURE_DATE_ISOFMT && (opt & DATE_OPT_TIMESPEC)) { 54 opt_complementary = "d--s:s--d" 55 USE_FEATURE_DATE_ISOFMT(":R--I:I--R"); 56 opt = getopt32(argv, "Rs:ud:r:" 57 USE_FEATURE_DATE_ISOFMT("I::D:"), 58 &date_str, &date_str, &filename 59 USE_FEATURE_DATE_ISOFMT(, &isofmt_arg, &hintfmt_arg)); 60 maybe_set_utc(opt); 61 62 if (ENABLE_FEATURE_DATE_ISOFMT && (opt & DATE_OPT_TIMESPEC)) { 141 63 if (!isofmt_arg) { 142 ifmt = 1;64 ifmt = 0; /* default is date */ 143 65 } else { 144 char *isoformats[]={"date","hours","minutes","seconds"}; 145 for(ifmt = 4; ifmt;) 146 if(!strcmp(isofmt_arg,isoformats[--ifmt])) 147 break; 148 } 149 if (!ifmt) { 66 static const char *const isoformats[] = { 67 "date", "hours", "minutes", "seconds" 68 }; 69 70 for (ifmt = 0; ifmt < 4; ifmt++) 71 if (!strcmp(isofmt_arg, isoformats[ifmt])) 72 goto found; 73 /* parse error */ 150 74 bb_show_usage(); 75 found: ; 151 76 } 152 77 } … … 156 81 date_fmt = &argv[optind][1]; /* Skip over the '+' */ 157 82 } else if (date_str == NULL) { 158 set_time = 1;83 opt |= DATE_OPT_SET; 159 84 date_str = argv[optind]; 160 85 } … … 163 88 which depends on whether the clock is being set or read */ 164 89 165 if (filename) {90 if (filename) { 166 91 struct stat statbuf; 167 xstat(filename,&statbuf); 168 tm=statbuf.st_mtime; 169 } else time(&tm); 92 xstat(filename, &statbuf); 93 tm = statbuf.st_mtime; 94 } else 95 time(&tm); 170 96 memcpy(&tm_time, localtime(&tm), sizeof(tm_time)); 171 97 /* Zero out fields - take her back to midnight! */ … … 179 105 strptime(date_str, hintfmt_arg, &tm_time); 180 106 } else if (strchr(date_str, ':') != NULL) { 181 date_conv_ftime(&tm_time, date_str); 107 /* Parse input and assign appropriately to tm_time */ 108 109 if (sscanf(date_str, "%d:%d:%d", &tm_time.tm_hour, &tm_time.tm_min, 110 &tm_time.tm_sec) == 3) { 111 /* no adjustments needed */ 112 } else if (sscanf(date_str, "%d:%d", &tm_time.tm_hour, 113 &tm_time.tm_min) == 2) { 114 /* no adjustments needed */ 115 } else if (sscanf(date_str, "%d.%d-%d:%d:%d", &tm_time.tm_mon, 116 &tm_time.tm_mday, &tm_time.tm_hour, 117 &tm_time.tm_min, &tm_time.tm_sec) == 5) { 118 /* Adjust dates from 1-12 to 0-11 */ 119 tm_time.tm_mon -= 1; 120 } else if (sscanf(date_str, "%d.%d-%d:%d", &tm_time.tm_mon, 121 &tm_time.tm_mday, 122 &tm_time.tm_hour, &tm_time.tm_min) == 4) { 123 /* Adjust dates from 1-12 to 0-11 */ 124 tm_time.tm_mon -= 1; 125 } else if (sscanf(date_str, "%d.%d.%d-%d:%d:%d", &tm_time.tm_year, 126 &tm_time.tm_mon, &tm_time.tm_mday, 127 &tm_time.tm_hour, &tm_time.tm_min, 128 &tm_time.tm_sec) == 6) { 129 tm_time.tm_year -= 1900; /* Adjust years */ 130 tm_time.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */ 131 } else if (sscanf(date_str, "%d.%d.%d-%d:%d", &tm_time.tm_year, 132 &tm_time.tm_mon, &tm_time.tm_mday, 133 &tm_time.tm_hour, &tm_time.tm_min) == 5) { 134 tm_time.tm_year -= 1900; /* Adjust years */ 135 tm_time.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */ 136 } else { 137 bb_error_msg_and_die(bb_msg_invalid_date, date_str); 138 } 182 139 } else { 183 date_conv_time(&tm_time, date_str); 140 int nr; 141 char *cp; 142 143 nr = sscanf(date_str, "%2d%2d%2d%2d%d", &tm_time.tm_mon, 144 &tm_time.tm_mday, &tm_time.tm_hour, &tm_time.tm_min, 145 &tm_time.tm_year); 146 147 if (nr < 4 || nr > 5) { 148 bb_error_msg_and_die(bb_msg_invalid_date, date_str); 149 } 150 151 cp = strchr(date_str, '.'); 152 if (cp) { 153 nr = sscanf(cp + 1, "%2d", &tm_time.tm_sec); 154 if (nr != 1) { 155 bb_error_msg_and_die(bb_msg_invalid_date, date_str); 156 } 157 } 158 159 /* correct for century - minor Y2K problem here? */ 160 if (tm_time.tm_year >= 1900) { 161 tm_time.tm_year -= 1900; 162 } 163 /* adjust date */ 164 tm_time.tm_mon -= 1; 184 165 } 185 166 … … 190 171 bb_error_msg_and_die(bb_msg_invalid_date, date_str); 191 172 } 192 if (utc && putenv("TZ=UTC0") != 0) { 193 bb_error_msg_and_die(bb_msg_memory_exhausted); 194 } 173 maybe_set_utc(opt); 195 174 196 175 /* if setting time, set it */ 197 if ( set_time&& stime(&tm) < 0) {176 if ((opt & DATE_OPT_SET) && stime(&tm) < 0) { 198 177 bb_perror_msg("cannot set date"); 199 178 } … … 203 182 204 183 /* Deal with format string */ 184 205 185 if (date_fmt == NULL) { 206 /* Start with the default case */ 207 208 date_fmt = (opt & DATE_OPT_RFC2822 ? 209 (utc ? "%a, %d %b %Y %H:%M:%S GMT" : 210 "%a, %d %b %Y %H:%M:%S %z") : 211 "%a %b %e %H:%M:%S %Z %Y"); 212 213 if (ENABLE_FEATURE_DATE_ISOFMT) { 214 if (ifmt == 4) 215 date_fmt = utc ? "%Y-%m-%dT%H:%M:%SZ" : "%Y-%m-%dT%H:%M:%S%z"; 216 else if (ifmt == 3) 217 date_fmt = utc ? "%Y-%m-%dT%H:%MZ" : "%Y-%m-%dT%H:%M%z"; 218 else if (ifmt == 2) 219 date_fmt = utc ? "%Y-%m-%dT%HZ" : "%Y-%m-%dT%H%z"; 220 else if (ifmt == 1) 221 date_fmt = "%Y-%m-%d"; 222 } 223 } 224 186 int i; 187 date_fmt = xzalloc(32); 188 if (ENABLE_FEATURE_DATE_ISOFMT && ifmt >= 0) { 189 strcpy(date_fmt, "%Y-%m-%d"); 190 if (ifmt > 0) { 191 i = 8; 192 date_fmt[i++] = 'T'; 193 date_fmt[i++] = '%'; 194 date_fmt[i++] = 'H'; 195 if (ifmt > 1) { 196 date_fmt[i++] = ':'; 197 date_fmt[i++] = '%'; 198 date_fmt[i++] = 'M'; 199 } 200 if (ifmt > 2) { 201 date_fmt[i++] = ':'; 202 date_fmt[i++] = '%'; 203 date_fmt[i++] = 'S'; 204 } 205 format_utc: 206 date_fmt[i++] = '%'; 207 date_fmt[i] = (opt & DATE_OPT_UTC) ? 'Z' : 'z'; 208 } 209 } else if (opt & DATE_OPT_RFC2822) { 210 /* Undo busybox.c for date -R */ 211 if (ENABLE_LOCALE_SUPPORT) 212 setlocale(LC_TIME, "C"); 213 strcpy(date_fmt, "%a, %d %b %Y %H:%M:%S "); 214 i = 22; 215 goto format_utc; 216 } else /* default case */ 217 date_fmt = (char*)"%a %b %e %H:%M:%S %Z %Y"; 218 } 219 220 #define date_buf bb_common_bufsiz1 225 221 if (*date_fmt == '\0') { 226 227 222 /* With no format string, just print a blank line */ 228 229 *bb_common_bufsiz1=0; 223 date_buf[0] = '\0'; 230 224 } else { 231 232 225 /* Handle special conversions */ 233 226 234 227 if (strncmp(date_fmt, "%f", 2) == 0) { 235 date_fmt = "%Y.%m.%d-%H:%M:%S";228 date_fmt = (char*)"%Y.%m.%d-%H:%M:%S"; 236 229 } 237 230 238 231 /* Generate output string */ 239 strftime( bb_common_bufsiz1, 200, date_fmt, &tm_time);240 } 241 puts( bb_common_bufsiz1);232 strftime(date_buf, sizeof(date_buf), date_fmt, &tm_time); 233 } 234 puts(date_buf); 242 235 243 236 return EXIT_SUCCESS;
Note:
See TracChangeset
for help on using the changeset viewer.