aboutsummaryrefslogtreecommitdiffstats
path: root/util/alevt/alevt-date.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--util/alevt/alevt-date.c225
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);
+}