| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- #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);
- }
|