- char *date_str = NULL;
- char *date_fmt = NULL;
- char *t_buff;
- int set_time = 0;
- int rfc822 = 0;
- int utc = 0;
- int use_arg = 0;
- int n_args;
- time_t tm;
- struct tm tm_time;
- char optc;
-
- /* Interpret command line args */
-
-
- while ((optc = getopt_long (argc, argv, "d:Rs:u", long_options, NULL))
- != EOF) {
- switch (optc) {
- case 0:
- break;
-
- case 'R':
- rfc822 = 1;
- break;
-
- case 's':
- set_time = 1;
- if(date_str != NULL) date_err();
- date_str = optarg;
- break;
-
- case 'u':
- utc = 1;
- if (putenv ("TZ=UTC0") != 0) {
- fprintf(stderr,"date: memory exhausted\n");
- return(1);
- }
-#if LOCALTIME_CACHE
- tzset ();
-#endif break;
-
- case 'd':
- use_arg = 1;
- if(date_str != NULL) date_err();
- date_str = optarg;
- break;
-
- default:
- usage(date_usage);
- break;
- }
- }
-
-
- n_args = argc - optind;
-
- while (n_args--){
- switch(argv[optind][0]) {
- case '+':
- /* Date format strings */
- if(date_fmt != NULL) {
- fprintf(stderr, "date: only one date format can be given.\n");
- return(1);
- }
- date_fmt = &argv[optind][1];
- break;
-
- case '\0':
- break;
-
- default:
- /* Anything left over must be a date string to set the time */
- set_time = 1;
- if(date_str != NULL) date_err();
- date_str = argv[optind];
- break;
- }
- optind++;
- }
-
-
- /* Now we have parsed all the information except the date format
- which depends on whether the clock is being set or read */
-
- time(&tm);
- memcpy(&tm_time, localtime(&tm), sizeof(tm_time));
- /* Zero out fields - take her back to midnight!*/
- if(date_str != NULL) {
- tm_time.tm_sec = 0;
- tm_time.tm_min = 0;
- tm_time.tm_hour = 0;
- }
-
- /* Process any date input to UNIX time since 1 Jan 1970 */
- if(date_str != NULL) {
-
- if(strchr(date_str, ':') != NULL) {
- date_conv_ftime(&tm_time, date_str);
- } else {
- date_conv_time(&tm_time, date_str);
- }
-
- /* Correct any day of week and day of year etc fields */
- tm = mktime(&tm_time);
- if (tm < 0 ) {
- fprintf(stderr, "date: invalid date `%s'\n", date_str);
- exit(1);
- }
-
- /* if setting time, set it */
- if(set_time) {
- if( stime(&tm) < 0) {
- fprintf(stderr, "date: can't set date.\n");
- exit(1);
- }
- }
- }
-
- /* Display output */
-
- /* Deal with format string */
- if(date_fmt == NULL) {
- date_fmt = (rfc822
- ? (utc
- ? "%a, %_d %b %Y %H:%M:%S GMT"
- : "%a, %_d %b %Y %H:%M:%S %z")
- : "%a %b %e %H:%M:%S %Z %Y");
-
- } else if ( *date_fmt == '\0' ) {
- /* Imitate what GNU 'date' does with NO format string! */
- printf ("\n");
- return(0);
- }
-
- /* Handle special conversions */
-
- if( strncmp( date_fmt, "%f", 2) == 0 ) {
- date_fmt = "%Y.%m.%d-%H:%M:%S";
- }
-
- /* Print OUTPUT (after ALL that!) */
- t_buff = malloc(201);
- strftime(t_buff, 200, date_fmt, &tm_time);
- printf("%s\n", t_buff);
-
- return(0);
-
+ char *date_str = NULL;
+ char *date_fmt = NULL;
+ int set_time;
+ int utc;
+ int use_arg = 0;
+ time_t tm;
+ unsigned long opt;
+ struct tm tm_time;
+ char *filename = NULL;
+
+#ifdef CONFIG_FEATURE_DATE_ISOFMT
+ int ifmt = 0;
+ char *isofmt_arg;
+
+# define GETOPT_ISOFMT "I::"
+#else
+# define GETOPT_ISOFMT
+#endif
+ bb_opt_complementaly = "d~ds:s~ds";
+ opt = bb_getopt_ulflags(argc, argv, "Rs:ud:r:" GETOPT_ISOFMT,
+ &date_str, &date_str, &filename
+#ifdef CONFIG_FEATURE_DATE_ISOFMT
+ , &isofmt_arg
+#endif
+ );
+ set_time = opt & DATE_OPT_SET;
+ utc = opt & DATE_OPT_UTC;
+ if ((utc) && (putenv("TZ=UTC0") != 0)) {
+ bb_error_msg_and_die(bb_msg_memory_exhausted);
+ }
+ use_arg = opt & DATE_OPT_DATE;
+ if(opt & BB_GETOPT_ERROR)
+ bb_show_usage();
+#ifdef CONFIG_FEATURE_DATE_ISOFMT
+ if(opt & DATE_OPT_TIMESPEC) {
+ if (!isofmt_arg) {
+ ifmt = 1;
+ } else {
+ int ifmt_len = bb_strlen(isofmt_arg);
+
+ if ((ifmt_len <= 4)
+ && (strncmp(isofmt_arg, "date", ifmt_len) == 0)) {
+ ifmt = 1;
+ } else if ((ifmt_len <= 5)
+ && (strncmp(isofmt_arg, "hours", ifmt_len) == 0)) {
+ ifmt = 2;
+ } else if ((ifmt_len <= 7)
+ && (strncmp(isofmt_arg, "minutes", ifmt_len) == 0)) {
+ ifmt = 3;
+ } else if ((ifmt_len <= 7)
+ && (strncmp(isofmt_arg, "seconds", ifmt_len) == 0)) {
+ ifmt = 4;
+ }
+ }
+ if (!ifmt) {
+ bb_show_usage();
+ }
+ }
+#endif
+
+ if ((date_fmt == NULL) && (optind < argc) && (argv[optind][0] == '+')) {
+ date_fmt = &argv[optind][1]; /* Skip over the '+' */
+ } else if (date_str == NULL) {
+ set_time = 1;
+ date_str = argv[optind];
+ }
+
+ /* Now we have parsed all the information except the date format
+ which depends on whether the clock is being set or read */
+
+ if(filename) {
+ struct stat statbuf;
+ if(stat(filename,&statbuf))
+ bb_perror_msg_and_die("File '%s' not found.\n",filename);
+ tm=statbuf.st_mtime;
+ } else time(&tm);
+ memcpy(&tm_time, localtime(&tm), sizeof(tm_time));
+ /* Zero out fields - take her back to midnight! */
+ if (date_str != NULL) {
+ tm_time.tm_sec = 0;
+ tm_time.tm_min = 0;
+ tm_time.tm_hour = 0;
+
+ /* Process any date input to UNIX time since 1 Jan 1970 */
+ if (strchr(date_str, ':') != NULL) {
+ date_conv_ftime(&tm_time, date_str);
+ } else {
+ date_conv_time(&tm_time, date_str);
+ }
+
+ /* Correct any day of week and day of year etc. fields */
+ tm_time.tm_isdst = -1; /* Be sure to recheck dst. */
+ tm = mktime(&tm_time);
+ if (tm < 0) {
+ bb_error_msg_and_die(bb_msg_invalid_date, date_str);
+ }
+ if (utc && (putenv("TZ=UTC0") != 0)) {
+ bb_error_msg_and_die(bb_msg_memory_exhausted);
+ }
+
+ /* if setting time, set it */
+ if (set_time && (stime(&tm) < 0)) {
+ bb_perror_msg("cannot set date");
+ }
+ }
+
+ /* Display output */
+
+ /* Deal with format string */
+ if (date_fmt == NULL) {
+#ifdef CONFIG_FEATURE_DATE_ISOFMT
+ switch (ifmt) {
+ case 4:
+ date_fmt = utc ? "%Y-%m-%dT%H:%M:%SZ" : "%Y-%m-%dT%H:%M:%S%z";
+ break;
+ case 3:
+ date_fmt = utc ? "%Y-%m-%dT%H:%MZ" : "%Y-%m-%dT%H:%M%z";
+ break;
+ case 2:
+ date_fmt = utc ? "%Y-%m-%dT%HZ" : "%Y-%m-%dT%H%z";
+ break;
+ case 1:
+ date_fmt = "%Y-%m-%d";
+ break;
+ case 0:
+ default:
+#endif
+ date_fmt = (opt & DATE_OPT_RFC2822 ?
+ (utc ? "%a, %d %b %Y %H:%M:%S GMT" :
+ "%a, %d %b %Y %H:%M:%S %z") :
+ "%a %b %e %H:%M:%S %Z %Y");
+
+#ifdef CONFIG_FEATURE_DATE_ISOFMT
+ break;
+ }
+#endif
+ } else if (*date_fmt == '\0') {
+ /* Imitate what GNU 'date' does with NO format string! */
+ printf("\n");
+ return EXIT_SUCCESS;
+ }
+
+ /* Handle special conversions */
+
+ if (strncmp(date_fmt, "%f", 2) == 0) {
+ date_fmt = "%Y.%m.%d-%H:%M:%S";
+ }
+
+ {
+ /* Print OUTPUT (after ALL that!) */
+ RESERVE_CONFIG_BUFFER(t_buff, 201);
+ strftime(t_buff, 200, date_fmt, &tm_time);
+ puts(t_buff);
+ RELEASE_CONFIG_BUFFER(t_buff);
+ }
+
+ return EXIT_SUCCESS;