From c51a5856bdc382b7c0ced4a7917f2779a685287d Mon Sep 17 00:00:00 2001 From: Adam Sutton Date: Wed, 6 Jun 2012 17:08:15 +0100 Subject: [PATCH] Fixed some bugs in cron code and re-enabled basic grabber code (still not fully functional). --- src/cron.c | 16 ++++++++--- src/cron.h | 1 + src/epggrab.c | 72 +++++++++++++++++++++++++++++++++++++++-------- src/epggrab/eit.c | 12 ++------ 4 files changed, 75 insertions(+), 26 deletions(-) diff --git a/src/cron.c b/src/cron.c index 802cb540..74e4ee9f 100644 --- a/src/cron.c +++ b/src/cron.c @@ -19,12 +19,12 @@ static int _cron_parse_field { int i = 0, j = 0, sn = -1, en = -1, mn = -1; *field = 0; - while ( str[i] != '\0' ) { + while ( 1 ) { if ( str[i] == '*' ) { sn = 0; en = 64; j = -1; - } else if ( str[i] == ',' || str[i] == ' ' ) { + } else if ( str[i] == ',' || str[i] == ' ' || str[i] == '\0' ) { if (j >= 0) sscanf(str+j, "%d", en == -1 ? (sn == -1 ? &sn : &en) : &mn); if (en == -1) en = sn; @@ -34,6 +34,7 @@ static int _cron_parse_field *field |= (0x1LL << (sn - offset)); sn++; } + if ( str[i] == '\0' ) break; j = i+1; sn = en = mn = -1; if (str[i] == ' ') break; @@ -145,13 +146,20 @@ int cron_is_time ( cron_t *cron ) return ret; } +// TODO: use this as part of cron_next/cron_is_time +void cron_run ( cron_t *cron ) +{ +} + // TODO: do proper search for next time time_t cron_next ( cron_t *cron ) { time_t now; time(&now); - now += 60; - return (now / 60) * 60; // round to start of minute + now += 62; // TODO: hack because timer goes off just before second tick + now /= 60; + now *= 60; + return now; } diff --git a/src/cron.h b/src/cron.h index 6c42b11d..b42904c9 100644 --- a/src/cron.h +++ b/src/cron.h @@ -19,6 +19,7 @@ const char *cron_get_string ( cron_t *cron ); int cron_set_string ( cron_t *cron, const char *str ); int cron_is_time ( cron_t *cron ); time_t cron_next ( cron_t *cron ); +void cron_run ( cron_t *cron ); void cron_serialize ( cron_t *cron, htsmsg_t *msg ); cron_t *cron_deserialize ( htsmsg_t *msg ); diff --git a/src/epggrab.c b/src/epggrab.c index e21eba12..59d81673 100644 --- a/src/epggrab.c +++ b/src/epggrab.c @@ -2,6 +2,7 @@ #include #include #include +#include #include "htsmsg.h" #include "settings.h" #include "tvheadend.h" @@ -12,6 +13,8 @@ #include "epggrab/xmltv.h" #include "epggrab/pyepg.h" #include "channels.h" +#include "spawn.h" +#include "htsmsg_xml.h" /* Thread protection */ int epggrab_confver; @@ -156,9 +159,50 @@ void epggrab_module_enable_socket ( epggrab_module_t *mod, uint8_t e ) htsmsg_t *epggrab_module_grab ( epggrab_module_t *mod, const char *cmd, const char *opts ) -{ - // TODO: implement this - return NULL; +{ + int i, outlen; + char *outbuf; + char errbuf[100]; + const char **argv = NULL; + wordexp_t we; + htsmsg_t *ret; + + /* Determine command */ + if ( !cmd || cmd[0] == '\0' ) + cmd = mod->path; + if ( !cmd ) { + tvhlog(LOG_ERR, "epggrab", "invalid configuraton no command specified"); + return NULL; + } + printf("cmd = %s, opts = %s\n", cmd, opts); + + /* Parse opts */ + if (opts) { + wordexp(opts, &we, 0); + argv = calloc(we.we_wordc+2, sizeof(char*)); + argv[0] = cmd; + for ( i = 0; i < we.we_wordc; i++ ) { + argv[i + 1] = we.we_wordv[i]; + } + } + + /* Debug */ + tvhlog(LOG_DEBUG, "pyepg", "grab %s %s", cmd, opts ?: ""); + + /* Grab */ + outlen = spawn_and_store_stdout(cmd, (char*const*)argv, &outbuf); + free(argv); + wordfree(&we); + if ( outlen < 1 ) { + tvhlog(LOG_ERR, "pyepg", "no output detected"); + return NULL; + } + + /* Extract */ + ret = htsmsg_xml_deserialize(outbuf, errbuf, sizeof(errbuf)); + if (!ret) + tvhlog(LOG_ERR, "pyepg", "htsmsg_xml_deserialize error %s", errbuf); + return ret; } /* ************************************************************************** @@ -361,7 +405,6 @@ htsmsg_t *epggrab_get_schedule ( void ) static void _epggrab_module_run ( epggrab_module_t *mod, const char *icmd, const char *iopts ) { -#if 0 int save = 0; time_t tm1, tm2; htsmsg_t *data; @@ -372,8 +415,8 @@ static void _epggrab_module_run if ( !mod || !mod->grab || !mod->parse ) return; /* Dup before unlock */ - if ( !icmd ) cmd = strdup(icmd); - if ( !iopts ) opts = strdup(iopts); + if ( icmd ) cmd = strdup(icmd); + if ( iopts ) opts = strdup(iopts); pthread_mutex_unlock(&epggrab_mutex); /* Grab */ @@ -419,9 +462,8 @@ static void _epggrab_module_run /* Free a re-lock */ if (cmd) free(cmd); - if (opts) free(cmd); + if (opts) free(opts); pthread_mutex_lock(&epggrab_mutex); -#endif } /* @@ -444,19 +486,25 @@ static time_t _epggrab_thread_simple ( void ) */ static time_t _epggrab_thread_advanced ( void ) { - time_t ret; + time_t ret, now; epggrab_sched_t *s; /* Determine which to run */ - time(&ret); + time(&now); + ret = now + 3600; // default TAILQ_FOREACH(s, &epggrab_schedule, link) { if ( cron_is_time(s->cron) ) { + cron_run(s->cron); _epggrab_module_run(s->mod, s->cmd, s->opts); - break; // TODO: can only run once else config may have changed + return now + 10; + // TODO: don't try to interate the list, it'll break due to locking + // module (i.e. _epggrab_module_run() unlocks) + } else { + ret = MIN(ret, cron_next(s->cron)); } } - return ret + 60; + return ret;//now + 30; } /* diff --git a/src/epggrab/eit.c b/src/epggrab/eit.c index faf811ea..106699d3 100644 --- a/src/epggrab/eit.c +++ b/src/epggrab/eit.c @@ -49,9 +49,7 @@ void eit_callback ( channel_t *ch, int id, time_t start, time_t stop, if (!ch || !ch->ch_name || !ch->ch_name[0]) return; /* Disabled? */ -#if TODO_REENABLE_THIS - if (epggrab_eit_disabled) return; -#endif + if (!epggrab_eitenabled) return; /* Find broadcast */ ebc = epg_broadcast_find_by_time(ch, start, stop, 1, &save); @@ -89,18 +87,12 @@ void eit_callback ( channel_t *ch, int id, time_t start, time_t stop, * ***********************************************************************/ static epggrab_module_t _eit_mod; -static uint8_t _eit_enabled; - -static void _eit_enable ( epggrab_module_t *mod, uint8_t e ) -{ - _eit_enabled = e; -} void eit_init ( epggrab_module_list_t *list ) { _eit_mod.id = strdup("eit"); _eit_mod.name = strdup("EIT: On-Air Grabber"); *((uint8_t*)&_eit_mod.flags) = EPGGRAB_MODULE_ASYNC; - _eit_mod.enable = _eit_enable; LIST_INSERT_HEAD(list, &_eit_mod, link); + // Note: this is mostly ignored anyway as EIT is treated as a special case! }