now working with some basic commands
This commit is contained in:
parent
36888b42b5
commit
89736f5fab
188
descriptor.c
188
descriptor.c
|
@ -12,16 +12,19 @@
|
|||
struct descriptor *
|
||||
read_descriptor_header(struct epg *epg)
|
||||
{
|
||||
static struct descriptor d;
|
||||
struct descriptor *d;
|
||||
|
||||
d = (struct descriptor *)malloc(sizeof(struct descriptor));
|
||||
d->loaded = 0;
|
||||
|
||||
if (epg->binsize - epg->offset < 2)
|
||||
return NULL;
|
||||
|
||||
memcpy(&d, epg->bin + epg->offset, 2);
|
||||
memcpy(d, epg->bin + epg->offset, 2);
|
||||
|
||||
epg->offset += 2;
|
||||
|
||||
return &d;
|
||||
return d;
|
||||
}
|
||||
|
||||
static char *
|
||||
|
@ -44,25 +47,37 @@ string_to_end(struct epg *epg, struct descriptor *d, int sofar,
|
|||
return str;
|
||||
}
|
||||
|
||||
static char *
|
||||
read_lstring(struct epg *epg, unsigned int *len)
|
||||
{
|
||||
int l = epg->bin[epg->offset++];
|
||||
char *c;
|
||||
|
||||
c = malloc(l + 1);
|
||||
memcpy(c, epg->bin + epg->offset, l);
|
||||
c[l] = '\0';
|
||||
epg->offset += l;
|
||||
|
||||
if (len)
|
||||
*len = l;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void
|
||||
read_descriptor(struct epg *epg, struct descriptor *d)
|
||||
{
|
||||
d->loaded = 1;
|
||||
switch (d->tag)
|
||||
{
|
||||
case DS_SHORT_EVENT:
|
||||
memcpy(d->content.d77.lang, epg->bin + epg->offset, 3);
|
||||
epg->offset += 3;
|
||||
|
||||
d->content.d77.namelen = epg->bin[epg->offset++];
|
||||
d->content.d77.name = read_string_len(epg->bin + epg->offset,
|
||||
d->content.d77.namelen);
|
||||
epg->offset += d->content.d77.namelen;
|
||||
|
||||
d->content.d77.textlen = epg->bin[epg->offset++];
|
||||
d->content.d77.text = read_string_len(epg->bin + epg->offset,
|
||||
d->content.d77.textlen);
|
||||
epg->offset += d->content.d77.textlen;
|
||||
|
||||
d->content.d77.name =
|
||||
read_lstring(epg, &d->content.d77.namelen);
|
||||
d->content.d77.text =
|
||||
read_lstring(epg, &d->content.d77.textlen);
|
||||
break;
|
||||
|
||||
case DS_COMPONENT:
|
||||
|
@ -74,10 +89,8 @@ read_descriptor(struct epg *epg, struct descriptor *d)
|
|||
break;
|
||||
|
||||
case DS_USER_DEFINED:
|
||||
d->content.d137.textlen = epg->bin[epg->offset++];
|
||||
d->content.d137.text = read_string_len(epg->bin + epg->offset,
|
||||
d->content.d137.textlen);
|
||||
epg->offset += d->content.d137.textlen;
|
||||
d->content.d137.text =
|
||||
read_lstring(epg, &d->content.d137.textlen);
|
||||
|
||||
memcpy(d->content.d137.lang, epg->bin + epg->offset, 3);
|
||||
epg->offset += 3;
|
||||
|
@ -87,29 +100,44 @@ read_descriptor(struct epg *epg, struct descriptor *d)
|
|||
break;
|
||||
|
||||
case DS_CONTENT_IDENTIFIER:
|
||||
memcpy(&d->content.d118, epg->bin + epg->offset, 1);
|
||||
epg->offset++;
|
||||
d->content.d118.cridlen = d->content.d118.ref = 0;
|
||||
switch (d->content.d118.location)
|
||||
{
|
||||
unsigned int end = epg->offset + d->len;
|
||||
|
||||
d->content.d118.i = 0;
|
||||
|
||||
while (epg->offset < end)
|
||||
{
|
||||
case 0:
|
||||
d->content.d118.cridlen = epg->bin[epg->offset++];
|
||||
d->content.d118.crid = read_string_len(
|
||||
epg->bin + epg->offset, d->content.d118.cridlen);
|
||||
epg->offset += d->content.d118.cridlen;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
d->content.d118.ref =
|
||||
_swap16((uint16_t)epg->bin[epg->offset]);
|
||||
/* Not safe to use post increment in macro */
|
||||
struct crid *crid =
|
||||
&d->content.d118.crids[d->content.d118.i];
|
||||
|
||||
memcpy(crid, epg->bin + epg->offset, 1);
|
||||
epg->offset++;
|
||||
break;
|
||||
default:
|
||||
printf("Unknown CRID location - %d\n",
|
||||
d->content.d118.location);
|
||||
crid->cridlen = crid->ref = 0;
|
||||
switch (crid->location)
|
||||
{
|
||||
case 0:
|
||||
crid->crid = read_lstring(epg, &crid->cridlen);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
crid->ref =
|
||||
_swap16((uint16_t)epg->bin[epg->offset]);
|
||||
/* Not safe to use post increment in macro */
|
||||
epg->offset++;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("Unknown CRID location - %d\n",
|
||||
crid->location);
|
||||
}
|
||||
if (d->content.d118.i++ >= 3)
|
||||
{
|
||||
printf("Too many content IDs.\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
printf("Default descriptor: %d\n", d->tag);
|
||||
|
@ -132,33 +160,45 @@ skip_descriptor(struct epg *epg, struct descriptor *d)
|
|||
void
|
||||
free_descriptor(struct descriptor *d)
|
||||
{
|
||||
switch (d->tag)
|
||||
if (d->loaded)
|
||||
{
|
||||
case DS_SHORT_EVENT:
|
||||
if (d->content.d77.name)
|
||||
free(d->content.d77.name);
|
||||
if (d->content.d77.text)
|
||||
free(d->content.d77.text);
|
||||
break;
|
||||
case DS_COMPONENT:
|
||||
if (d->content.d80.text)
|
||||
free(d->content.d80.text);
|
||||
break;
|
||||
case DS_USER_DEFINED:
|
||||
if (d->content.d137.text)
|
||||
free(d->content.d137.text);
|
||||
if (d->content.d137.warning)
|
||||
free(d->content.d137.warning);
|
||||
break;
|
||||
case DS_CONTENT_IDENTIFIER:
|
||||
if (d->content.d118.crid)
|
||||
free(d->content.d118.crid);
|
||||
break;
|
||||
default:
|
||||
if (d->content.unknown.text)
|
||||
free(d->content.unknown.text);
|
||||
break;
|
||||
switch (d->tag)
|
||||
{
|
||||
case DS_SHORT_EVENT:
|
||||
if (d->content.d77.name)
|
||||
free(d->content.d77.name);
|
||||
if (d->content.d77.text)
|
||||
free(d->content.d77.text);
|
||||
break;
|
||||
case DS_COMPONENT:
|
||||
if (d->content.d80.text)
|
||||
free(d->content.d80.text);
|
||||
break;
|
||||
case DS_USER_DEFINED:
|
||||
if (d->content.d137.text)
|
||||
free(d->content.d137.text);
|
||||
if (d->content.d137.warning)
|
||||
free(d->content.d137.warning);
|
||||
break;
|
||||
case DS_CONTENT_IDENTIFIER:
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < d->content.d118.i; i++)
|
||||
{
|
||||
struct crid *crid = &d->content.d118.crids[i];
|
||||
if (crid->cridlen)
|
||||
free(crid->crid);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
if (d->content.unknown.text)
|
||||
free(d->content.unknown.text);
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(d);
|
||||
}
|
||||
|
||||
char *
|
||||
|
@ -187,7 +227,7 @@ dump_descriptor(struct descriptor *d, int content)
|
|||
descriptor_name(d));
|
||||
DUMPINT(d, len);
|
||||
|
||||
if (!content)
|
||||
if (!content || !d->loaded)
|
||||
return;
|
||||
|
||||
switch (d->tag)
|
||||
|
@ -195,10 +235,8 @@ dump_descriptor(struct descriptor *d, int content)
|
|||
case DS_SHORT_EVENT:
|
||||
DUMPNSTR(d, content.d77.lang, 3);
|
||||
DUMPINT(d, content.d77.namelen);
|
||||
//DUMPNSTR(d, content.d77.name, d->content.d77.namelen);
|
||||
DUMPHEX(d, content.d77.name, d->content.d77.namelen);
|
||||
DUMPINT(d, content.d77.textlen);
|
||||
//DUMPNSTR(d, content.d77.text, d->content.d77.textlen);
|
||||
DUMPHEX(d, content.d77.text, d->content.d77.textlen);
|
||||
break;
|
||||
|
||||
|
@ -220,13 +258,23 @@ dump_descriptor(struct descriptor *d, int content)
|
|||
break;
|
||||
|
||||
case DS_CONTENT_IDENTIFIER:
|
||||
DUMPINT(d, content.d118.location);
|
||||
DUMPINT(d, content.d118.type);
|
||||
DUMPINT(d, content.d118.cridlen);
|
||||
if (d->content.d118.cridlen)
|
||||
DUMPHEX(d, content.d118.crid, d->content.d118.cridlen);
|
||||
DUMPINT(d, content.d118.ref);
|
||||
{
|
||||
int i;
|
||||
|
||||
DUMPINT(d, content.d118.i);
|
||||
|
||||
for (i = 0; i < d->content.d118.i; i++)
|
||||
{
|
||||
struct crid *crid = &d->content.d118.crids[i];
|
||||
DUMPINT(crid, location);
|
||||
DUMPINT(crid, type);
|
||||
DUMPINT(crid, cridlen);
|
||||
if (crid->cridlen)
|
||||
DUMPHEX(crid, crid, crid->cridlen);
|
||||
DUMPINT(crid, ref);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
if (d->content.unknown.textlen)
|
||||
|
|
27
descriptor.h
27
descriptor.h
|
@ -7,14 +7,27 @@
|
|||
#define DS_FTA_CONTENT_MGMT 126
|
||||
#define DS_USER_DEFINED 137
|
||||
|
||||
#define PARSER_SHORT_EVENT 0
|
||||
#define PARSER_CONTENT_ID 1
|
||||
#define PARSER_USER_DEFINED 2
|
||||
|
||||
#pragma pack(1)
|
||||
struct crid {
|
||||
unsigned int location:2;
|
||||
unsigned int type:6;
|
||||
unsigned int cridlen;
|
||||
char *crid;
|
||||
unsigned int ref:16;
|
||||
};
|
||||
|
||||
struct descriptor {
|
||||
unsigned int tag:8;
|
||||
unsigned int len:8;
|
||||
union {
|
||||
struct {
|
||||
char lang[3];
|
||||
unsigned int namelen:8;
|
||||
unsigned int textlen:8;
|
||||
unsigned int namelen;
|
||||
unsigned int textlen;
|
||||
char *name;
|
||||
char *text;
|
||||
} d77; /* SHORT_EVENT */
|
||||
|
@ -28,18 +41,15 @@ struct descriptor {
|
|||
unsigned int textlen;
|
||||
} d80; /* COMPONENT */
|
||||
struct {
|
||||
unsigned int textlen:8;
|
||||
unsigned int textlen;
|
||||
char *text;
|
||||
char lang[3];
|
||||
char *warning;
|
||||
unsigned int warninglen;
|
||||
} d137; /* USER_DEFINED - content warnings? */
|
||||
struct {
|
||||
unsigned int location:2;
|
||||
unsigned int type:6;
|
||||
unsigned int cridlen:8;
|
||||
char *crid;
|
||||
unsigned int ref:16;
|
||||
struct crid crids[3];
|
||||
int i;
|
||||
} d118; /* CONTENT_IDENTIFIER */
|
||||
struct {
|
||||
char *text;
|
||||
|
@ -47,5 +57,6 @@ struct descriptor {
|
|||
} unknown; /* 74, 84, 95, 126, ... */
|
||||
|
||||
} content;
|
||||
int loaded;
|
||||
};
|
||||
|
||||
|
|
99
epg.c
99
epg.c
|
@ -71,6 +71,14 @@ read_data(struct epg *epg)
|
|||
d.start_date = _swap16(d.start_date);
|
||||
d.u1.comp = _swap16(d.u1.comp);
|
||||
|
||||
d.start_hour = bcd(d.start_hour);
|
||||
d.start_min = bcd(d.start_min);
|
||||
d.start_sec = bcd(d.start_sec);
|
||||
|
||||
d.dur_hour = bcd(d.dur_hour);
|
||||
d.dur_min = bcd(d.dur_min);
|
||||
d.dur_sec = bcd(d.dur_sec);
|
||||
|
||||
epg->offset += sizeof(d);
|
||||
|
||||
return &d;
|
||||
|
@ -84,12 +92,11 @@ dump_data(struct data *d)
|
|||
printf("Data:\n");
|
||||
DUMPINT(d, event_id);
|
||||
|
||||
tm = MJD_TO_UNIX(d->start_date);
|
||||
printf(" %30s: %#x (%s)\n", "start_date",
|
||||
d->start_date, ctime_nl(&tm));
|
||||
tm = mjd(d->start_date, d->start_hour, d->start_min, d->start_sec);
|
||||
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", "start_time",
|
||||
d->start_hour, d->start_min, d->start_sec);
|
||||
printf(" %30s: %d:%02d:%02d\n", "duration",
|
||||
d->dur_hour, d->dur_min, d->dur_sec);
|
||||
|
||||
|
@ -98,3 +105,85 @@ dump_data(struct data *d)
|
|||
DUMPINT(d, u1.u.descriptors_loop_length);
|
||||
}
|
||||
|
||||
void
|
||||
parse(char *epgpath,
|
||||
void (*callback)(struct epg *, struct section *, struct data *,
|
||||
struct descriptor **, void *), void *val)
|
||||
{
|
||||
struct descriptor *dslist[3];
|
||||
struct epg *epg;
|
||||
int i;
|
||||
|
||||
if (!(epg = open_file(epgpath)))
|
||||
return;
|
||||
|
||||
while (epg->offset < epg->binsize)
|
||||
{
|
||||
struct section *s;
|
||||
uint32_t send;
|
||||
|
||||
if (!(s = read_section(epg)))
|
||||
break;
|
||||
|
||||
send = epg->offset - 11 + s->u1.u.length - 4;
|
||||
|
||||
while (epg->offset < send)
|
||||
{
|
||||
struct data *d;
|
||||
uint32_t dend;
|
||||
|
||||
if (!(d = read_data(epg)))
|
||||
break;
|
||||
|
||||
dslist[0] = dslist[1] = dslist[2] = NULL;
|
||||
|
||||
dend = epg->offset + d->u1.u.descriptors_loop_length;
|
||||
while (epg->offset < dend)
|
||||
{
|
||||
struct descriptor *ds;
|
||||
|
||||
if (!(ds = read_descriptor_header(epg)))
|
||||
continue;
|
||||
|
||||
switch (ds->tag)
|
||||
{
|
||||
case DS_SHORT_EVENT:
|
||||
read_descriptor(epg, ds);
|
||||
dslist[PARSER_SHORT_EVENT] = ds;
|
||||
break;
|
||||
|
||||
case DS_CONTENT_IDENTIFIER:
|
||||
read_descriptor(epg, ds);
|
||||
dslist[PARSER_CONTENT_ID] = ds;
|
||||
break;
|
||||
|
||||
case DS_USER_DEFINED:
|
||||
read_descriptor(epg, ds);
|
||||
dslist[PARSER_USER_DEFINED] = ds;
|
||||
break;
|
||||
|
||||
default:
|
||||
skip_descriptor(epg, ds);
|
||||
free_descriptor(ds);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
callback(epg, s, d, dslist, val);
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
if (dslist[i])
|
||||
free_descriptor(dslist[i]);
|
||||
}
|
||||
|
||||
/* Skip CRC */
|
||||
epg->offset += 4;
|
||||
|
||||
/* Skip padding bytes... */
|
||||
while (epg->bin[epg->offset] == 'U')
|
||||
epg->offset++;
|
||||
}
|
||||
|
||||
close_file(epg);
|
||||
}
|
||||
|
||||
|
|
2
epg.h
2
epg.h
|
@ -1,6 +1,8 @@
|
|||
|
||||
#include <sys/param.h>
|
||||
|
||||
#define DEFAULT_EPG_FILE "/mnt/hd1/dvbepg/epg.dat"
|
||||
|
||||
struct epg {
|
||||
char fname[MAXPATHLEN + 1];
|
||||
int fd;
|
||||
|
|
13
lint.h
13
lint.h
|
@ -3,6 +3,8 @@
|
|||
#include "descriptor.h"
|
||||
#include "util.h"
|
||||
|
||||
#define SYSOPT_PARSABLE 0x1
|
||||
|
||||
extern int debug;
|
||||
extern const char *version;
|
||||
extern unsigned long sysopts;
|
||||
|
@ -12,7 +14,8 @@ inline uint32_t read_uint32(uint8_t *, int);
|
|||
void hexdump(uint8_t *, uint32_t, uint32_t);
|
||||
char *hexstr(uint8_t *, uint32_t);
|
||||
char *ctime_nl(time_t *);
|
||||
char *read_string_len(uint8_t *, uint32_t);
|
||||
time_t mjd(uint16_t, int, int, int);
|
||||
void safeprintf(char *, ...);
|
||||
|
||||
struct epg *open_file(char *);
|
||||
void close_file(struct epg *);
|
||||
|
@ -23,9 +26,17 @@ void dump_section(struct section *);
|
|||
struct data *read_data(struct epg *);
|
||||
void dump_data(struct data *);
|
||||
|
||||
void parse(char *,
|
||||
void (*)(struct epg *, struct section *, struct data *,
|
||||
struct descriptor **, void *), void *);
|
||||
|
||||
struct descriptor *read_descriptor_header(struct epg *);
|
||||
void read_descriptor(struct epg *, struct descriptor *);
|
||||
void skip_descriptor(struct epg *, struct descriptor *);
|
||||
void dump_descriptor(struct descriptor *, int);
|
||||
void free_descriptor(struct descriptor *);
|
||||
|
||||
#ifdef sun
|
||||
char *strcasestr (char *, char *);
|
||||
#endif
|
||||
|
||||
|
|
233
main.c
233
main.c
|
@ -25,69 +25,212 @@ syntax()
|
|||
{
|
||||
fprintf(stderr, "Humax EPG Tool v%s, by af123, 2011.\n\n", version);
|
||||
fprintf(stderr,
|
||||
"Syntax: epg ...\n");
|
||||
"Syntax: epg [options] <command>...\n");
|
||||
fprintf(stderr,
|
||||
" Options:\n"
|
||||
" -d[level] Set debug level.\n"
|
||||
" -f<file> Specify alternate EPG data file.\n"
|
||||
" -h Show help text.\n"
|
||||
" -p Parsable output.\n"
|
||||
);
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr,
|
||||
" Commands:\n"
|
||||
" dump Show a parsed summary of the EPG.\n"
|
||||
" search <text> Search programme names for text.\n"
|
||||
" searchall <text> "
|
||||
"Search programme names/descriptions for text.\n"
|
||||
);
|
||||
fprintf(stderr, "\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
dump(struct epg *epg __attribute__((unused)),
|
||||
struct section *s, struct data *d, struct descriptor **ds,
|
||||
void *var __attribute__((unused)))
|
||||
{
|
||||
time_t tm;
|
||||
|
||||
tm = mjd(d->start_date, d->start_hour, d->start_min, d->start_sec);
|
||||
|
||||
printf("----------------------------------------------------------\n");
|
||||
|
||||
if (sysopts & SYSOPT_PARSABLE)
|
||||
{
|
||||
printf("ServiceID:%d\n", s->service_id);
|
||||
printf("EventID:%d\n", d->event_id);
|
||||
printf("Start:%ld\n", tm);
|
||||
printf("Duration:%d\n",
|
||||
d->dur_hour * 3600 + d->dur_min * 60 + d->dur_sec);
|
||||
printf("Encrypted:%d\n", d->u1.u.free_CA_mode);
|
||||
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);
|
||||
}
|
||||
|
||||
if (ds[PARSER_CONTENT_ID])
|
||||
{
|
||||
struct descriptor *d118 = ds[PARSER_CONTENT_ID];
|
||||
int i;
|
||||
|
||||
printf("nCRIDs:%d\n", d118->content.d118.i);
|
||||
|
||||
for (i = 0; i < d118->content.d118.i; i++)
|
||||
{
|
||||
struct crid *crid =
|
||||
&d118->content.d118.crids[i];
|
||||
|
||||
printf("CRID:%d:%.*s\n", crid->type,
|
||||
crid->cridlen, crid->crid);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
printf("%30s: %d\n", "Service ID", s->service_id);
|
||||
printf("%30s: %d\n", "Event ID", d->event_id);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
struct section *h;
|
||||
struct epg *epg;
|
||||
int i = 0;
|
||||
char *epgpath = DEFAULT_EPG_FILE;
|
||||
char *cp;
|
||||
|
||||
if (!(epg = open_file("../epg.dat")))
|
||||
return 0;
|
||||
|
||||
while (epg->offset < epg->binsize)
|
||||
{
|
||||
uint32_t send;
|
||||
|
||||
if (!(h = read_section(epg)))
|
||||
break;
|
||||
//dump_section(h);
|
||||
|
||||
send = epg->offset - 11 + h->u1.u.length - 4;
|
||||
|
||||
while (epg->offset < send)
|
||||
argc--, argv++;
|
||||
while (argc > 0 && *argv[0] == '-')
|
||||
{
|
||||
for (cp = &argv[0][1]; *cp; cp++)
|
||||
{
|
||||
struct data *d;
|
||||
uint32_t dend;
|
||||
switch (*cp)
|
||||
{
|
||||
case 'd':
|
||||
if (*++cp == '\0')
|
||||
debug = 1;
|
||||
else
|
||||
debug = atoi(cp);
|
||||
goto nextopt;
|
||||
|
||||
if (!(d = read_data(epg)))
|
||||
case 'f':
|
||||
if (*++cp == '\0')
|
||||
{
|
||||
fprintf(stderr,
|
||||
"No argument supplied for -f\n");
|
||||
exit(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (isspace((int)*cp))
|
||||
cp++;
|
||||
epgpath = strdup(cp);
|
||||
}
|
||||
goto nextopt;
|
||||
|
||||
case 'h':
|
||||
return syntax();
|
||||
|
||||
case 'p':
|
||||
sysopts |= SYSOPT_PARSABLE;
|
||||
break;
|
||||
//dump_data(d);
|
||||
|
||||
dend = epg->offset + d->u1.u.descriptors_loop_length;
|
||||
while (epg->offset < dend)
|
||||
{
|
||||
struct descriptor *ds;
|
||||
|
||||
ds = read_descriptor_header(epg);
|
||||
read_descriptor(epg, ds);
|
||||
|
||||
/*
|
||||
if (ds->tag == DS_CONTENT_IDENTIFIER)
|
||||
dump_descriptor(ds, 1);
|
||||
*/
|
||||
|
||||
free_descriptor(ds);
|
||||
}
|
||||
}
|
||||
|
||||
/* Skip CRC */
|
||||
epg->offset += 4;
|
||||
|
||||
/* Skip padding bytes... */
|
||||
while (epg->bin[epg->offset] == 'U')
|
||||
epg->offset++;
|
||||
nextopt:
|
||||
argc--, argv++;
|
||||
}
|
||||
|
||||
close_file(epg);
|
||||
|
||||
if (argc < 1)
|
||||
return syntax();
|
||||
|
||||
if (!strcmp(argv[0], "dump"))
|
||||
parse(epgpath, dump, NULL);
|
||||
else if (!strcmp(argv[0], "search") && argc > 1)
|
||||
parse(epgpath, search, (void *)argv[1]);
|
||||
else if (!strcmp(argv[0], "searchall") && argc > 1)
|
||||
parse(epgpath, searchall, (void *)argv[1]);
|
||||
else
|
||||
syntax();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
42
test
42
test
|
@ -1,42 +0,0 @@
|
|||
{'CRC_32': 3423408323L,
|
||||
'current_next_indicator': 1,
|
||||
'datas': [{'descriptors': [{'descriptor_length': 2,
|
||||
'descriptor_tag': 84,
|
||||
'unknown': '\x00\x00'},
|
||||
{'ISO_639_language_code': 'eng',
|
||||
'component_tag': 1,
|
||||
'component_type': 1,
|
||||
'descriptor_length': 6,
|
||||
'descriptor_tag': 80,
|
||||
'reserved_future_use': 15,
|
||||
'stream_content': 2,
|
||||
'text': ''},
|
||||
{'ISO_639_language_code': 'eng',
|
||||
'descriptor_length': 38,
|
||||
'descriptor_tag': 77,
|
||||
'event_name': '\x1f\x01\x05g60\xe3/U\x86$~\xe8\x80',
|
||||
'event_name_length': 14,
|
||||
'text': '\x1f\x01\xa9\x89\x1f\xbaS/UO\xaf\xb6\x9dNj\xc8a\xeb\x9d',
|
||||
'text_length': 19}],
|
||||
'descriptors_loop_length': 52,
|
||||
'duration': datetime.timedelta(0, 21600),
|
||||
'event_id': 795,
|
||||
'free_CA_mode': 0,
|
||||
'running_status': 0,
|
||||
'start_time': datetime.datetime(2011, 6, 1, 0, 0)}],
|
||||
'last_section_number': 248,
|
||||
'last_table_id': 97,
|
||||
'original_network_id': 9018,
|
||||
'pre_header_1': '(Gq\x87\x00\x00\x00\x00\x02\x00\x00\x00\x00\x01',
|
||||
'pre_header_2': '\x00\x00\x00\x00',
|
||||
'reserved': 3,
|
||||
'reserved_future_use': 1,
|
||||
'section_length': 79,
|
||||
'section_number': 0,
|
||||
'section_syntax_indicator': 1,
|
||||
'segment_last_section_number': 0,
|
||||
'service_id': 26560,
|
||||
'table_id': 96,
|
||||
'total_length': 84,
|
||||
'transport_stream_id': 24576,
|
||||
'version_number': 6}
|
73
util.c
73
util.c
|
@ -12,6 +12,70 @@
|
|||
|
||||
#include "lint.h"
|
||||
|
||||
#ifdef sun
|
||||
char *
|
||||
strcasestr (char *h, char *n)
|
||||
{
|
||||
char *hp, *np = n, *match = 0;
|
||||
|
||||
if(!*np) {
|
||||
return np;
|
||||
}
|
||||
|
||||
for (hp = h; *hp; hp++) {
|
||||
if (toupper(*hp) == toupper(*np)) {
|
||||
if (!match) {
|
||||
match = hp;
|
||||
}
|
||||
if(!*++np) {
|
||||
return match;
|
||||
}
|
||||
} else {
|
||||
if (match) {
|
||||
match = 0;
|
||||
np = n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
safeprintf(char *fmt, ...)
|
||||
{
|
||||
char buf[0x400];
|
||||
char *p;
|
||||
va_list argp;
|
||||
int len;
|
||||
|
||||
va_start(argp, fmt);
|
||||
len = vsprintf(buf, fmt, argp);
|
||||
va_end(argp);
|
||||
|
||||
for (p = buf; p < buf + len; p++)
|
||||
if (!isprint(*p))
|
||||
*p = '.';
|
||||
|
||||
printf("%.*s\n", len, buf);
|
||||
}
|
||||
|
||||
time_t
|
||||
mjd(uint16_t day, int h, int m, int s)
|
||||
{
|
||||
time_t tm;
|
||||
struct tm *t;
|
||||
|
||||
tm = MJD_TO_UNIX(day);
|
||||
t = localtime(&tm);
|
||||
t->tm_hour = h;
|
||||
t->tm_min = m;
|
||||
t->tm_sec = s;
|
||||
|
||||
return mktime(t);
|
||||
}
|
||||
|
||||
char *
|
||||
ctime_nl(time_t *tm)
|
||||
{
|
||||
|
@ -23,15 +87,6 @@ ctime_nl(time_t *tm)
|
|||
return buf;
|
||||
}
|
||||
|
||||
inline char *
|
||||
read_string_len(uint8_t *src, uint32_t len)
|
||||
{
|
||||
char *s = malloc(len + 1);
|
||||
memcpy(s, src, len);
|
||||
s[len] = '\0';
|
||||
return s;
|
||||
}
|
||||
|
||||
inline uint32_t
|
||||
read_uint32(uint8_t *p, int le)
|
||||
{
|
||||
|
|
2
util.h
2
util.h
|
@ -4,6 +4,8 @@
|
|||
|
||||
#define _swap16(v) ((((v) >> 8) & 0xff) | (((v) & 0xff) << 8))
|
||||
|
||||
#define bcd(v) (((((v) >> 4) & 0xf) * 10) + ((v) & 0xf))
|
||||
|
||||
#define DUMPINT(ss,xx) printf(" %30s: %d\n", #xx, ss->xx)
|
||||
#define DUMPSTR(ss,xx) printf(" %30s: %s\n", #xx, ss->xx)
|
||||
#define DUMPNSTR(ss,xx,nn) printf(" %30s: %.*s\n", #xx, nn, ss->xx)
|
||||
|
|
Loading…
Reference in New Issue