lineedit: do not hang on error, but return error indicator.
[oweals/busybox.git] / libbb / time.c
index 45ae6f3a7e9ddbc58a65227954900bc9a0b0e9a9..2a74d34c2c435299f59f845e72ca29f098c125d8 100644 (file)
@@ -4,7 +4,7 @@
  *
  * Copyright (C) 2007 Denys Vlasenko
  *
- * Licensed under GPL version 2, see file LICENSE in this tarball for details.
+ * Licensed under GPLv2, see file LICENSE in this source tree.
  */
 #include "libbb.h"
 
@@ -15,6 +15,9 @@ void FAST_FUNC parse_datestr(const char *date_str, struct tm *ptm)
 
        if (last_colon != NULL) {
                /* Parse input and assign appropriately to ptm */
+#if ENABLE_DESKTOP
+               const char *endp;
+#endif
 
                /* HH:MM */
                if (sscanf(date_str, "%u:%u%c",
@@ -46,8 +49,17 @@ void FAST_FUNC parse_datestr(const char *date_str, struct tm *ptm)
                                        &end) >= 5) {
                        ptm->tm_year -= 1900; /* Adjust years */
                        ptm->tm_mon -= 1; /* Adjust month from 1-12 to 0-11 */
+               } else
+#if ENABLE_DESKTOP  /* strptime is BIG: ~1k in uclibc, ~10k in glibc */
+               /* month_name d HH:MM:SS YYYY. Supported by GNU date */
+               if ((endp = strptime(date_str, "%b %d %T %Y", ptm)) != NULL
+                && *endp == '\0'
+               ) {
+                       return; /* don't fall through to end == ":" check */
+               } else
+#endif
 //TODO: coreutils 6.9 also accepts "yyyy-mm-dd HH" (no minutes)
-               } else {
+               {
                        bb_error_msg_and_die(bb_msg_invalid_date, date_str);
                }
                if (end == ':') {
@@ -56,6 +68,16 @@ void FAST_FUNC parse_datestr(const char *date_str, struct tm *ptm)
                                end = '\0';
                        /* else end != NUL and we error out */
                }
+       } else if (date_str[0] == '@') {
+               time_t t = bb_strtol(date_str + 1, NULL, 10);
+               if (!errno) {
+                       struct tm *lt = localtime(&t);
+                       if (lt) {
+                               *ptm = *lt;
+                               return;
+                       }
+               }
+               end = '1';
        } else {
                /* Googled the following on an old date manpage:
                 *