/* 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 . */ #include #include #include #include #include #include #include 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; }