diff options
Diffstat (limited to 'tests/readtime.c')
-rw-r--r-- | tests/readtime.c | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/tests/readtime.c b/tests/readtime.c new file mode 100644 index 0000000..f7cc36a --- /dev/null +++ b/tests/readtime.c @@ -0,0 +1,161 @@ +/* This file is part of GNU Pies testsuite. + Copyright (C) 2019 Sergey Poznyakoff + + GNU Pies is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GNU Pies is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Pies. If not, see <http://www.gnu.org/licenses/>. */ + +#include <config.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <time.h> +#include <locale.h> +#include <libpies.h> + +char *progname; +int precision = 2; + +void +usage (FILE *fp, int status) +{ + fprintf (fp, "usage: %s [-v] [-p PREC] URL\n", progname); + fprintf (fp, "Reads time stamp from URL as per RFC868.\n"); + fprintf (fp, "Exits with status 0 if it is within PREC seconds from the current time.\n"); + fprintf (fp, "Default PREC is %d seconds.\n", precision); + exit (status); +} + +enum { SEVENTY_YEARS = (unsigned long)25567 * 24 * 60 * 60 }; + +int +main (int argc, char **argv) +{ + int c, fd; + struct pies_url *url; + time_t now; + int human_time = 0; + union + { + char s[80]; + uint32_t u; + } buf; + uint32_t t, d; + ssize_t n; + int verbose = 0; + + progname = argv[0]; + setlocale (LC_ALL, "C"); + + while ((c = getopt (argc, argv, "Hhvp:")) != EOF) + { + switch (c) + { + case 'H': + human_time = 1; + break; + + case 'h': + usage (stdout, 0); + break; + + case 'p': + precision = atoi (optarg); + if (precision <= 0) + { + fprintf (stderr, "%s: bad precision\n", progname); + exit (1); + } + break; + + case 'v': + verbose++; + break; + + default: + exit (64); + } + } + + argc -= optind; + argv += optind; + + if (argc != 1) + usage (stderr, 64); + + if (pies_url_create (&url, argv[0])) + { + perror (argv[0]); + return 64; + } + + fd = url_connect (url, NULL); + time (&now); + n = read (fd, &buf, sizeof (buf)); + if (n == -1) + { + perror ("read"); + exit (1); + } + + if (human_time) + { + struct tm daytime; + char *p; + + if (buf.s[n-1] == '\n') + { + buf.s[--n] = 0; + if (buf.s[n-1] == '\r') + buf.s[--n] = 0; + } + if (verbose > 1) + printf ("got %*.*s\n", (int)n, (int)n, buf.s); + p = strptime (buf.s, "%a %b %d %H:%M:%S %Y", &daytime); + if (!p) + { + fprintf (stderr, "%s: unable to parse time '%s'\n", progname, buf.s); + exit (1); + } + if (*p) + { + fprintf (stderr, "%s: trailing garbage: '%s'\n", progname, p); + } + t = mktime (&daytime); + } + else + { + if (n < sizeof (buf.u)) + { + fprintf (stderr, "%s: read %d bytes\n", progname, (int)n); + exit (1); + } + t = ntohl (buf.u); + if (verbose > 1) + printf ("got %lu\n", (unsigned long) t); + t -= SEVENTY_YEARS; + } + + if (t > now) + d = t - now; + else + d = now - t; + + if (d > precision) + { + fprintf (stderr, "%s: time diff %lu\n", progname, (unsigned long) d); + exit (1); + } + else if (verbose) + printf ("OK\n"); + return 0; +} |