summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorTed Unangst <tedu@cvs.openbsd.org>2019-01-21 21:35:59 +0000
committerTed Unangst <tedu@cvs.openbsd.org>2019-01-21 21:35:59 +0000
commit94c9630d492c7ccefe64eb134c567b681c5df8ef (patch)
tree7b17996101677f0d7ecb4431bb8b86a53853aa70 /lib
parent491a489b5452a566dc12d9951f40fcffda39db22 (diff)
strftime can print epoch seconds with %s, so allow strptime to parse it.
ok cheloha
Diffstat (limited to 'lib')
-rw-r--r--lib/libc/time/strptime.38
-rw-r--r--lib/libc/time/strptime.c38
2 files changed, 42 insertions, 4 deletions
diff --git a/lib/libc/time/strptime.3 b/lib/libc/time/strptime.3
index 6b66d06aa0c..8872a8e7aaf 100644
--- a/lib/libc/time/strptime.3
+++ b/lib/libc/time/strptime.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: strptime.3,v 1.25 2016/02/08 20:05:43 tedu Exp $
+.\" $OpenBSD: strptime.3,v 1.26 2019/01/21 21:35:58 tedu Exp $
.\"
.\" Copyright (c) 1997, 1998, 2005, 2008 The NetBSD Foundation, Inc.
.\" All rights reserved.
@@ -26,7 +26,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd $Mdocdate: February 8 2016 $
+.Dd $Mdocdate: January 21 2019 $
.Dt STRPTIME 3
.Os
.Sh NAME
@@ -145,6 +145,9 @@ the time as %H:%M.
.It Cm \&%S
the seconds [0,60];
leading zeros are permitted but not required.
+.It Cm \&%s
+the number of seconds since the Epoch, UTC (see
+.Xr mktime 3 ) .
.It Cm \&%t
any whitespace.
.It Cm \&%T
@@ -301,6 +304,7 @@ function conforms to
The
.Ql \&%G ,
.Ql \&%g ,
+.Ql \&%s ,
.Ql \&%u ,
.Ql \&%V ,
.Ql \&%Y ,
diff --git a/lib/libc/time/strptime.c b/lib/libc/time/strptime.c
index 2932575860d..a1cbbdbb8e3 100644
--- a/lib/libc/time/strptime.c
+++ b/lib/libc/time/strptime.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: strptime.c,v 1.22 2016/05/23 00:05:15 guenther Exp $ */
+/* $OpenBSD: strptime.c,v 1.23 2019/01/21 21:35:58 tedu Exp $ */
/* $NetBSD: strptime.c,v 1.12 1998/01/20 21:39:40 mycroft Exp $ */
/*-
* Copyright (c) 1997, 1998, 2005, 2008 The NetBSD Foundation, Inc.
@@ -30,6 +30,7 @@
#include <ctype.h>
#include <locale.h>
+#include <stdint.h>
#include <string.h>
#include <time.h>
@@ -71,6 +72,7 @@ static const int mon_lengths[2][MONSPERYEAR] = {
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
};
+static int _conv_num64(const unsigned char **, int64_t *, int64_t, int64_t);
static int _conv_num(const unsigned char **, int *, int, int);
static int leaps_thru_end_of(const int y);
static char *_strptime(const char *, const char *, struct tm *, int);
@@ -333,7 +335,16 @@ literal:
if (!(_conv_num(&bp, &tm->tm_sec, 0, 61)))
return (NULL);
break;
-
+ case 's': /* Seconds since epoch */
+ {
+ int64_t i64;
+ if (!(_conv_num64(&bp, &i64, 0, INT64_MAX)))
+ return (NULL);
+ if (!gmtime_r(&i64, tm))
+ return (NULL);
+ fields = 0xffff; /* everything */
+ }
+ break;
case 'U': /* The week of year, beginning on sunday. */
case 'W': /* The week of year, beginning on monday. */
_LEGAL_ALT(_ALT_O);
@@ -660,6 +671,29 @@ _conv_num(const unsigned char **buf, int *dest, int llim, int ulim)
return (1);
}
+static int
+_conv_num64(const unsigned char **buf, int64_t *dest, int64_t llim, int64_t ulim)
+{
+ int result = 0;
+ int64_t rulim = ulim;
+
+ if (**buf < '0' || **buf > '9')
+ return (0);
+
+ /* we use rulim to break out of the loop when we run out of digits */
+ do {
+ result *= 10;
+ result += *(*buf)++ - '0';
+ rulim /= 10;
+ } while ((result * 10 <= ulim) && rulim && **buf >= '0' && **buf <= '9');
+
+ if (result < llim || result > ulim)
+ return (0);
+
+ *dest = result;
+ return (1);
+}
+
static const u_char *
_find_string(const u_char *bp, int *tgt, const char * const *n1,
const char * const *n2, int c)