diff options
author | Mark Purcell <msp@debian.org> | 2010-02-25 21:13:46 +1100 |
---|---|---|
committer | etobi <git@e-tobi.net> | 2013-09-03 09:48:46 +0200 |
commit | 665818f1969f893f05edf5b70eb1804c89b2829e (patch) | |
tree | 34ba68cee03c52d769a5a51b456b7e9d63cd091a /util/alevt/alevt-date.c | |
parent | 109c7947d6a11a2a54eff1b19615ed80ea2f0602 (diff) | |
parent | 9fe4d4ea9c054e539ab679ed2e9c076c35beb69d (diff) | |
download | linux-dvb-apps-665818f1969f893f05edf5b70eb1804c89b2829e.tar.gz |
Imported Debian patch 1.1.1+rev1355-1debian/1.1.1+rev1355-1
Diffstat (limited to 'util/alevt/alevt-date.c')
-rw-r--r-- | util/alevt/alevt-date.c | 225 |
1 files changed, 225 insertions, 0 deletions
diff --git a/util/alevt/alevt-date.c b/util/alevt/alevt-date.c new file mode 100644 index 0000000..5496937 --- /dev/null +++ b/util/alevt/alevt-date.c @@ -0,0 +1,225 @@ +#include <stdio.h> +#include <string.h> +#include <sys/time.h> +#include <time.h> +#include <stdlib.h> +#include <unistd.h> +#include <signal.h> +#include "os.h" +#include "vt.h" +#include "fdset.h" +#include "vbi.h" +#include "lang.h" +#include "misc.h" + +char *fmt = "%a %b %d %H:%M:%S %Z %Y"; +int max_diff = 2*60*60; // default: 2 hours +int set_time = 0; +char *outfile = ""; +static char *channel; +u_int16_t sid; + + +static void chk_time(int t) +{ + struct tm *tm; + time_t sys_t; + int dt; + char buf[256]; + + if (t < 0 || t > 235959 || t%100 > 59 || t/100%100 > 59) + return; + + sys_t = time(0); + tm = localtime(&sys_t); + + // Now convert to UTC seconds + t = t/100/100 * 60*60 + t/100%100 * 60 + t%100; +#ifdef BSD + t -= tm->tm_gmtoff; // dst already included... +#else + t += timezone; + if (tm->tm_isdst) + t -= 60*60; +#endif + + dt = t - sys_t % (24*60*60); + if (dt <= -12*60*60) + dt += 24*60*60; + + if (dt <= -max_diff || dt >= max_diff) + fatal("time diff too big (%2d:%02d:%02d)", dt/60/60, abs(dt)/60%60, abs(dt)%60); + + sys_t += dt; + + if (set_time) + { + struct timeval tv[1]; + + tv->tv_sec = sys_t; + tv->tv_usec = 500000; + if (settimeofday(tv, 0) == -1) + ioerror("settimeofday"); + } + if (*fmt) + { + tm = localtime(&sys_t); + if (strftime(buf, sizeof(buf), fmt, tm)) + puts(buf); + } + exit(0); +} + + +static void event(void *_, struct vt_event *ev) +{ + switch (ev->type) + { + /* vbi may generate EV_PAGE, EV_HEADER, EV_XPACKET */ + /* for event arguments see vt.h */ + + case EV_HEADER: // a new title line (for running headers) + { + static int last_t = -1; + u8 *s = ev->p1; + int i, t = 1; + + if (ev->i2 & PG_OUTOFSEQ) + break; + + for (i = 32; i < 40; ++i) + if (s[i] >= '0' && s[i] <= '9') + t = t * 10+ s[i] - '0'; + if (t >= 1000000 && t <= 1235959) + if (t == last_t || t - last_t == 1) + chk_time(t - 1000000); + last_t = t; + break; + } + } +} + + +static void usage(FILE *fp, int exit_val) +{ + fprintf(fp, "usage: %s [options]\n", prgname); + fprintf(fp, + "\n" + " Valid options:\t\tDefault:\n" + " -d -delta <max_secs>\t7200 (2 hours)\n" + " -f -format <fmtstr>\t\t%%c\n" + " -h -help\n" + " -s -set\t\t\toff\n" + " -to -timeout <seconds>\t(none)\n" + " -v -vbi <vbidev>\t\t/dev/vbi\n" + " \t\t/dev/vbi0\n" + " \t\t/dev/video0\n" + " \t\t/dev/dvb/adapter0/demux0\n" + ); + exit(exit_val); +} + + +static int option(int argc, char **argv, int *ind, char **arg) +{ + static struct { char *nam, *altnam; int arg; } opts[] = { + { "-delta", "-d", 1 }, + { "-format", "-f", 1 }, + { "-help", "-h", 0 }, + { "-set", "-s", 0 }, + { "-timeout", "-to", 1 }, + { "-vbi", "-v", 1 }, + }; + int i; + + if (*ind >= argc) + return 0; + + *arg = argv[(*ind)++]; + for (i = 0; i < NELEM(opts); ++i) + if (streq(*arg, opts[i].nam) || streq(*arg, opts[i].altnam)) + { + if (opts[i].arg) + if (*ind < argc) + *arg = argv[(*ind)++]; + else + fatal("option %s requires an argument", *arg); + return i+1; + } + + if (**arg == '-') + { + fatal("%s: invalid option", *arg); + usage(stderr, 1); + } + + return -1; +} + + +int main(int argc, char **argv) +{ + char *vbi_name = NULL; + int timeout = 0; + struct vbi *vbi; + int opt, ind; + char *arg; + int ttpid = -1; + + setprgname(argv[0]); + ind = 1; + while (opt = option(argc, argv, &ind, &arg)) + switch (opt) + { + case 1: // -delta + max_diff = atoi(arg); + if (max_diff < 1) + fatal("-delta: illegal value '%s'", arg); + if (max_diff > 12*60*60) + { + max_diff = 12*60*60; + error("-delta: %d too big. Assuming %d", arg, max_diff); + } + break; + case 2: // -format + fmt = arg; + break; + case 3: // help + usage(stdout, 0); + break; + case 4: // -set + set_time = 1; + break; + case 5: // -timeout + timeout = atoi(arg); + if (timeout < 1 || timeout > 60*60) + fatal("-timeout: illegal value '%s'", arg); + break; + case 6: // -vbi + vbi_name = arg; + break; + case -1: + usage(stderr, 1); + break; + } + + fdset_init(fds); + + if (timeout) + { + signal(SIGALRM, SIG_DFL); // kill me + alarm(timeout); + } + vbi = vbi_open(vbi_name, 0, channel, outfile, sid, ttpid); // open device + if (not vbi) + fatal_ioerror(vbi_name); + vbi_add_handler(vbi, event, 0); // register event handler + + for (;;) + fdset_select(fds, -1); // call scheduler + + /* never reached */ + vbi_del_handler(vbi, event, 0); + vbi_close(vbi); + exit(0); +} |