config

OpenBSD system configuration
git clone git://jacobedwards.org/config
Log | Files | Refs | README

timedec.c (2208B)


      1 /*
      2  * Copyright 2023 Jacob R. Edwards <jacob@jacobedwards.org>
      3  *
      4  * Permission to use, copy, modify, and distribute this software for any
      5  * purpose with or without fee is hereby granted, provided that the above
      6  * copyright notice and this permission notice appear in all copies.
      7  *
      8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     15  */
     16 
     17 #include <stdio.h>
     18 #include <stdlib.h>
     19 #include <string.h>
     20 #include <time.h>
     21 
     22 char *
     23 die(char *msg)
     24 {
     25 	perror(msg);
     26 	exit(1);
     27 }
     28 
     29 char *
     30 xstrptime(char *buf, char *fmt, struct tm *tm)
     31 {
     32 	char *ep;
     33 	struct tm ref;
     34 
     35 	memcpy(&ref, tm, sizeof(ref));
     36 	if ((ep = strptime(buf, fmt, tm)))
     37 		return ep;
     38 	memcpy(tm, &ref, sizeof(ref));
     39 	return NULL;
     40 }
     41 
     42 char *
     43 strptimes(char *buf, char **fmts, struct tm *tm)
     44 {
     45 	char *ep;
     46 
     47 	for (; *fmts; ++fmts)
     48 		if ((ep = xstrptime(buf, *fmts, tm)))
     49 			return ep;
     50 	return NULL;
     51 }
     52 
     53 time_t
     54 decodedatetime(char *s)
     55 {
     56 	char *ep;
     57 	struct tm *tm;
     58 	time_t t;
     59 
     60 	t = time(NULL);
     61 	tm = localtime(&t);
     62 	tm->tm_hour = 0;
     63 	tm->tm_min = 0;
     64 	tm->tm_sec = 0;
     65 
     66 	ep = xstrptime(s, "%F", tm);
     67 	if (ep) {
     68 		if (ep[0] == '\0')
     69 			return mktime(tm);
     70 		else if (ep[0] != ' ')
     71 			return 0;
     72 		s = ep + 1;
     73 	}
     74 
     75 	ep = strptimes(s, (char *[]){ "%T", "%R", NULL }, tm);
     76 	if (!ep || (ep && ep[0]))
     77 		return 0;
     78 	return mktime(tm);
     79 }
     80 
     81 /*
     82  * This program takes a time given in the strftime(3) format '%F'
     83  * or '[%F ]%H:%M[:%S]' and outputs the time elapsed since Jan 1,
     84  * 1970 00:00 in seconds.
     85  *
     86  * It is meant as to be a standard interface to specifying time.
     87  */
     88 int
     89 main(int argc, char *argv[])
     90 {
     91 	char *ts;
     92 	time_t t;
     93 
     94 	if (!argv[1])
     95 		die("usage: timedec time");
     96 	t = decodedatetime(argv[1]);
     97 	if (t == 0)
     98 		die("invalid time (must be of the form '%F' or '[%F ]%H:%M[:%S]')");
     99 	return printf("%d\n", t) < 0;
    100 }