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