epg/main.c

348 lines
8.1 KiB
C
Raw Normal View History

2011-06-01 23:34:35 +00:00
/*
* Humax EPG Tool
* by af123, 2011
*/
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <time.h>
#include "lint.h"
int debug = 0;
const char *version = "0.0.1";
unsigned long sysopts = 0;
int
syntax()
{
fprintf(stderr, "Humax EPG Tool v%s, by af123, 2011.\n\n", version);
fprintf(stderr,
2011-06-03 10:27:40 +00:00
"Syntax: epg [options] [filters] <command>...\n\n");
2011-06-02 23:51:14 +00:00
fprintf(stderr,
" Options:\n"
2011-06-03 00:13:37 +00:00
" -b Brief output.\n"
" -d[level] Set debug level.\n"
" -f<file> Specify alternate EPG data file.\n"
" -h Show help text.\n"
2011-06-02 23:51:14 +00:00
" -p Parsable output.\n"
2011-06-03 10:27:40 +00:00
"\n"
);
fprintf(stderr,
" Filters: (can be specified multiple times, all must be true)\n"
" -D<descriptor type> Show only selected descriptor type.\n"
" -E<event id> Show only selected event.\n"
" -S<service id> Show only selected service.\n"
2011-06-04 21:45:40 +00:00
" -@<unix timestamp> Show only programmes at time.\n"
2011-06-03 10:27:40 +00:00
"\n"
2011-06-02 23:51:14 +00:00
);
2011-06-01 23:34:35 +00:00
fprintf(stderr,
" Commands:\n"
2011-06-02 23:51:14 +00:00
" dump Show a parsed summary of the EPG.\n"
2011-06-03 00:13:37 +00:00
" now Show what is currently on.\n"
2011-06-02 23:51:14 +00:00
" search <text> Search programme names for text.\n"
" searchall <text> "
"Search programme names/descriptions for text.\n"
2011-06-01 23:34:35 +00:00
);
fprintf(stderr, "\n");
return 0;
}
2011-06-03 21:36:58 +00:00
void
dumpraw(struct epg *epg __attribute__((unused)),
struct section *s, struct data *d, struct descriptor **ds,
void *var __attribute__((unused)))
{
dump_section(s);
dump_data(d);
if (ds[PARSER_SHORT_EVENT])
dump_descriptor(ds[PARSER_SHORT_EVENT], 1);
if (ds[PARSER_USER_DEFINED])
dump_descriptor(ds[PARSER_USER_DEFINED], 1);
if (ds[PARSER_CONTENT_ID])
dump_descriptor(ds[PARSER_CONTENT_ID], 1);
}
2011-06-02 23:51:14 +00:00
void
dump(struct epg *epg __attribute__((unused)),
struct section *s, struct data *d, struct descriptor **ds,
void *var __attribute__((unused)))
2011-06-01 23:34:35 +00:00
{
2011-06-02 23:51:14 +00:00
time_t tm;
tm = mjd(d->start_date, d->start_hour, d->start_min, d->start_sec);
2011-06-01 23:34:35 +00:00
2011-06-02 23:51:14 +00:00
if (sysopts & SYSOPT_PARSABLE)
2011-06-02 01:32:55 +00:00
{
2011-06-03 21:36:58 +00:00
/* service_id, event_id, start, duration, encrypted, name, text
* warning, num_crids, crid_type, crid, ...
*/
printf("%d\t%d\t%ld\t%d\t%d\t",
s->service_id, d->event_id, tm,
d->dur_hour * 3600 + d->dur_min * 60 + d->dur_sec,
d->u1.u.free_CA_mode);
2011-06-02 23:51:14 +00:00
if (ds[PARSER_SHORT_EVENT])
{
struct descriptor *d77 = ds[PARSER_SHORT_EVENT];
2011-06-01 23:34:35 +00:00
2011-06-03 21:36:58 +00:00
safeprintf("%.*s\t",
2011-06-02 23:51:14 +00:00
d77->content.d77.namelen, d77->content.d77.name);
2011-06-03 21:36:58 +00:00
safeprintf("%.*s\t",
2011-06-02 23:51:14 +00:00
d77->content.d77.textlen, d77->content.d77.text);
}
2011-06-03 21:36:58 +00:00
else
printf("\t\t");
2011-06-02 23:51:14 +00:00
if (ds[PARSER_USER_DEFINED])
{
struct descriptor *d137 = ds[PARSER_USER_DEFINED];
2011-06-01 23:34:35 +00:00
2011-06-03 21:36:58 +00:00
safeprintf("%.*s\t", d137->content.d137.warninglen,
2011-06-02 23:51:14 +00:00
d137->content.d137.warning);
}
2011-06-03 21:36:58 +00:00
else
printf("\t");
2011-06-02 01:32:55 +00:00
2011-06-02 23:51:14 +00:00
if (ds[PARSER_CONTENT_ID])
2011-06-02 01:32:55 +00:00
{
2011-06-02 23:51:14 +00:00
struct descriptor *d118 = ds[PARSER_CONTENT_ID];
int i;
2011-06-02 01:32:55 +00:00
2011-06-03 21:36:58 +00:00
printf("%d\t", d118->content.d118.i);
2011-06-02 01:32:55 +00:00
2011-06-02 23:51:14 +00:00
for (i = 0; i < d118->content.d118.i; i++)
2011-06-02 01:32:55 +00:00
{
2011-06-02 23:51:14 +00:00
struct crid *crid =
&d118->content.d118.crids[i];
2011-06-02 11:14:43 +00:00
2011-06-03 21:36:58 +00:00
printf("%d\t%.*s\t", crid->type,
2011-06-02 23:51:14 +00:00
crid->cridlen, crid->crid);
}
}
2011-06-03 21:36:58 +00:00
printf("\n");
2011-06-02 23:51:14 +00:00
return;
}
2011-06-02 15:21:56 +00:00
2011-06-03 23:53:59 +00:00
printf("----------------------------------------------------------\n");
if (sysopts & SYSOPT_BRIEF)
{
safeprintf("%d/%d: %s+%d\n",
s->service_id, d->event_id, ctime_nl(&tm),
d->dur_hour * 3600 + d->dur_min * 60 + d->dur_sec);
if (ds[PARSER_SHORT_EVENT])
{
struct descriptor *d77 = ds[PARSER_SHORT_EVENT];
safeprintf("Name:%.*s\n",
d77->content.d77.namelen, d77->content.d77.name);
safeprintf("Text:%.*s\n",
d77->content.d77.textlen, d77->content.d77.text);
}
if (ds[PARSER_USER_DEFINED])
{
struct descriptor *d137 = ds[PARSER_USER_DEFINED];
safeprintf("Warning:%.*s\n",
d137->content.d137.warninglen,
d137->content.d137.warning);
}
return;
}
2011-06-02 23:51:14 +00:00
printf("%30s: %d\n", "Service ID", s->service_id);
printf("%30s: %d\n", "Event ID", d->event_id);
2011-06-02 15:21:56 +00:00
2011-06-02 23:51:14 +00:00
printf("%30s: %#x %d:%02d:%02d (%s)\n", "start_date",
d->start_date, d->start_hour, d->start_min, d->start_sec,
ctime_nl(&tm));
printf("%30s: %d:%02d:%02d\n", "duration",
d->dur_hour, d->dur_min, d->dur_sec);
printf("%30s: %d\n", "encrypted", d->u1.u.free_CA_mode);
if (ds[PARSER_SHORT_EVENT])
{
struct descriptor *d77 = ds[PARSER_SHORT_EVENT];
safeprintf("%30s: %.*s\n", "Name",
d77->content.d77.namelen, d77->content.d77.name);
safeprintf("%30s: %.*s\n", "Text",
d77->content.d77.textlen, d77->content.d77.text);
}
if (ds[PARSER_USER_DEFINED])
{
struct descriptor *d137 = ds[PARSER_USER_DEFINED];
safeprintf("%30s: %.*s\n", "Warning",
d137->content.d137.warninglen, d137->content.d137.warning);
}
if (ds[PARSER_CONTENT_ID])
{
struct descriptor *d118 = ds[PARSER_CONTENT_ID];
int i;
printf("%30s: %d\n", "CRIDs", d118->content.d118.i);
for (i = 0; i < d118->content.d118.i; i++)
{
struct crid *crid = &d118->content.d118.crids[i];
printf("%30s: %d\n", "CRID Type", crid->type);
printf("%30s: %.*s\n", "CRID",
crid->cridlen, crid->crid);
2011-06-02 01:32:55 +00:00
}
2011-06-02 23:51:14 +00:00
}
}
void
search(struct epg *epg __attribute__((unused)),
struct section *s, struct data *d, struct descriptor **ds,
void *var)
{
if (ds[PARSER_SHORT_EVENT] &&
strcasestr(ds[PARSER_SHORT_EVENT]->content.d77.name, (char *)var))
dump(epg, s, d, ds, NULL);
}
2011-06-02 01:32:55 +00:00
2011-06-02 23:51:14 +00:00
void
searchall(struct epg *epg __attribute__((unused)),
struct section *s, struct data *d, struct descriptor **ds,
void *var)
{
if (ds[PARSER_SHORT_EVENT] && (
strcasestr(ds[PARSER_SHORT_EVENT]->content.d77.name, (char *)var)
||
strcasestr(ds[PARSER_SHORT_EVENT]->content.d77.text, (char *)var)
))
dump(epg, s, d, ds, NULL);
}
2011-06-03 10:27:40 +00:00
#define GETOPT \
do { \
if (*++cp == '\0' && argc < 2) \
{ \
fprintf(stderr, \
"No argument supplied for -%c\n", opt); \
exit(1); \
} \
else if (*cp == '\0') \
{ \
argc--, argv++; \
cp = argv[0]; \
} \
while (isspace((int)*cp)) \
cp++; \
} while (0)
2011-06-02 23:51:14 +00:00
int
main(int argc, char **argv)
{
char *epgpath = DEFAULT_EPG_FILE;
2011-06-03 10:27:40 +00:00
struct epgfilter *filter = NULL;
2011-06-02 23:51:14 +00:00
char *cp;
2011-06-02 01:32:55 +00:00
2011-06-02 23:51:14 +00:00
argc--, argv++;
while (argc > 0 && *argv[0] == '-')
{
for (cp = &argv[0][1]; *cp; cp++)
{
2011-06-03 10:27:40 +00:00
char opt;
switch (opt = *cp)
2011-06-02 23:51:14 +00:00
{
2011-06-03 00:13:37 +00:00
case 'b':
sysopts |= SYSOPT_BRIEF;
break;
2011-06-02 23:51:14 +00:00
case 'd':
if (*++cp == '\0')
debug = 1;
else
debug = atoi(cp);
goto nextopt;
case 'f':
2011-06-03 10:27:40 +00:00
GETOPT;
epgpath = strdup(cp);
2011-06-02 23:51:14 +00:00
goto nextopt;
case 'h':
return syntax();
case 'p':
sysopts |= SYSOPT_PARSABLE;
break;
2011-06-03 10:27:40 +00:00
/* Filters */
2011-06-04 21:45:40 +00:00
case '@':
GETOPT;
add_epgfilter(&filter, FILTER_TIMESTAMP,
atoi(cp), 0, NULL, FT_EQUAL);
/* Global flag to indicate that the
* timestamp check is required - has overhead
* so don't want to do it in all cases. */
sysopts |= SYSOPT_TIMESTAMP;
goto nextopt;
2011-06-03 10:27:40 +00:00
case 'D':
GETOPT;
add_epgfilter(&filter, FILTER_DESCRIPTOR,
2011-06-04 21:45:40 +00:00
atoi(cp), 0, NULL, FT_EQUAL);
2011-06-03 10:27:40 +00:00
goto nextopt;
case 'E':
GETOPT;
add_epgfilter(&filter, FILTER_EVENT,
2011-06-04 21:45:40 +00:00
atoi(cp), 0, NULL, FT_EQUAL);
2011-06-03 10:27:40 +00:00
goto nextopt;
case 'S':
GETOPT;
add_epgfilter(&filter, FILTER_SERVICE,
2011-06-04 21:45:40 +00:00
atoi(cp), 0, NULL, FT_EQUAL);
2011-06-03 10:27:40 +00:00
goto nextopt;
2011-06-02 23:51:14 +00:00
}
}
nextopt:
argc--, argv++;
2011-06-02 01:32:55 +00:00
}
2011-06-02 23:51:14 +00:00
if (argc < 1)
return syntax();
if (!strcmp(argv[0], "dump"))
2011-06-03 10:27:40 +00:00
parse(epgpath, dump, NULL, filter);
2011-06-03 21:36:58 +00:00
else if (!strcmp(argv[0], "dumpraw"))
parse(epgpath, dumpraw, NULL, filter);
2011-06-03 10:27:40 +00:00
else if (!strcmp(argv[0], "now"))
2011-06-05 19:36:34 +00:00
{
time_t tm;
time(&tm);
add_epgfilter(&filter, FILTER_TIMESTAMP, tm, 0, NULL, FT_EQUAL);
parse(epgpath, dump, NULL, filter);
}
2011-06-02 23:51:14 +00:00
else if (!strcmp(argv[0], "search") && argc > 1)
2011-06-03 10:27:40 +00:00
parse(epgpath, search, (void *)argv[1], filter);
2011-06-02 23:51:14 +00:00
else if (!strcmp(argv[0], "searchall") && argc > 1)
2011-06-03 10:27:40 +00:00
parse(epgpath, searchall, (void *)argv[1], filter);
2011-06-02 23:51:14 +00:00
else
syntax();
2011-06-01 23:34:35 +00:00
return 0;
}