Compare commits
4 Commits
Author | SHA1 | Date |
---|---|---|
adrianf36 | b55c134eed | |
MofTot | b3ea751561 | |
HummyPkg | 5e468f5857 | |
adrianf36 | 222797837c |
|
@ -1,2 +0,0 @@
|
||||||
*.o
|
|
||||||
epg
|
|
25
Makefile
25
Makefile
|
@ -1,43 +1,36 @@
|
||||||
|
|
||||||
MAKE=gmake
|
MAKE=gmake
|
||||||
|
|
||||||
DEFS=
|
DEFS=-DFOXSATPLATFORM -DFOXSATFILE
|
||||||
|
#DEFS= -DFOXSATFILE
|
||||||
|
|
||||||
SRCS= descriptor.c \
|
SRCS= descriptor.c \
|
||||||
epg.c \
|
epg.c \
|
||||||
file.c \
|
file.c \
|
||||||
huffman.c \
|
huffman.c \
|
||||||
main.c \
|
main.c \
|
||||||
util.c
|
util.c \
|
||||||
|
epgsql.c
|
||||||
|
|
||||||
HDRS= descriptor.h \
|
HDRS= descriptor.h \
|
||||||
epg.h \
|
epg.h \
|
||||||
lint.h \
|
lint.h \
|
||||||
util.h \
|
util.h \
|
||||||
xgetopt.h
|
epgsql.h
|
||||||
|
|
||||||
OBJS= $(SRCS:.c=.o)
|
OBJS= $(SRCS:.c=.o)
|
||||||
CC=gcc
|
#CC=gcc
|
||||||
#CC=mipsel-linux-gcc
|
#CC=mipsel-linux-gcc
|
||||||
CFLAGS=-g
|
CC=mips-linux-gcc
|
||||||
|
CFLAGS=-g -pthread
|
||||||
INCS=
|
INCS=
|
||||||
LIBS=
|
LIBS=-lsqlite3 -ldl
|
||||||
#CFLAGS=-g -O3 -fno-strict-aliasing
|
#CFLAGS=-g -O3 -fno-strict-aliasing
|
||||||
#WARN=-pedantic -Wall -Wnested-externs -Wpointer-arith -Werror -Wno-unused
|
#WARN=-pedantic -Wall -Wnested-externs -Wpointer-arith -Werror -Wno-unused
|
||||||
WARN=-pedantic -Wall -W -Wnested-externs -Wpointer-arith -Wno-long-long
|
WARN=-pedantic -Wall -W -Wnested-externs -Wpointer-arith -Wno-long-long
|
||||||
|
|
||||||
PLATFORM=$(shell uname -s | cut -d- -f1)
|
|
||||||
ifeq ($(PLATFORM),Linux)
|
|
||||||
DEFS=-DHAVE_SQLITE3
|
|
||||||
LIBS=-lsqlite3 -lxconv
|
|
||||||
endif
|
|
||||||
|
|
||||||
all: tags epg
|
all: tags epg
|
||||||
|
|
||||||
install: epg
|
|
||||||
strip epg
|
|
||||||
cp epg /mod/bin/epg
|
|
||||||
|
|
||||||
epg: ${OBJS}
|
epg: ${OBJS}
|
||||||
@echo "Linking..."
|
@echo "Linking..."
|
||||||
@-[ -f $@ ] && mv $@ $@~ || exit 0
|
@-[ -f $@ ] && mv $@ $@~ || exit 0
|
||||||
|
|
89
descriptor.c
89
descriptor.c
|
@ -19,7 +19,7 @@ read_descriptor_header(struct epg *epg)
|
||||||
{
|
{
|
||||||
struct descriptor *d;
|
struct descriptor *d;
|
||||||
|
|
||||||
d = (struct descriptor *)calloc(sizeof(struct descriptor), 1);
|
d = (struct descriptor *)malloc(sizeof(struct descriptor));
|
||||||
d->loaded = 0;
|
d->loaded = 0;
|
||||||
|
|
||||||
if (epg->binsize - epg->offset < 2)
|
if (epg->binsize - epg->offset < 2)
|
||||||
|
@ -55,16 +55,9 @@ string_to_end(struct epg *epg, struct descriptor *d, int sofar,
|
||||||
static char *
|
static char *
|
||||||
read_lstring(struct epg *epg, unsigned int *len)
|
read_lstring(struct epg *epg, unsigned int *len)
|
||||||
{
|
{
|
||||||
unsigned int l = epg->bin[epg->offset++];
|
int l = epg->bin[epg->offset++];
|
||||||
char *c;
|
char *c;
|
||||||
|
|
||||||
/* Check that there is enough file left. */
|
|
||||||
if (epg->binsize - epg->offset < l)
|
|
||||||
l = epg->binsize - epg->offset;
|
|
||||||
|
|
||||||
if (l < 1)
|
|
||||||
return strdup("Short file");
|
|
||||||
|
|
||||||
c = malloc(l + 1);
|
c = malloc(l + 1);
|
||||||
memcpy(c, epg->bin + epg->offset, l);
|
memcpy(c, epg->bin + epg->offset, l);
|
||||||
c[l] = '\0';
|
c[l] = '\0';
|
||||||
|
@ -93,31 +86,6 @@ read_descriptor(struct epg *epg, struct descriptor *d)
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DS_EXTENDED_EVENT:
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
epg->offset++; /* Skip descriptor number and last descriptor */
|
|
||||||
memcpy(d->content.d78.lang, epg->bin + epg->offset, 3);
|
|
||||||
epg->offset += 3;
|
|
||||||
|
|
||||||
d->content.d78.items = epg->bin[epg->offset++];
|
|
||||||
if (debug > 1 && d->content.d78.items > 0)
|
|
||||||
printf("Extended event items: %d\n",
|
|
||||||
d->content.d78.items);
|
|
||||||
/* Skip items. */
|
|
||||||
for (i = 0; i < d->content.d78.items; i++)
|
|
||||||
{
|
|
||||||
int l = epg->bin[epg->offset++];
|
|
||||||
epg->offset += l;
|
|
||||||
}
|
|
||||||
|
|
||||||
d->content.d78.text =
|
|
||||||
read_lstring(epg, &d->content.d78.textlen);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case DS_COMPONENT:
|
case DS_COMPONENT:
|
||||||
memcpy(&d->content.d80, epg->bin + epg->offset, 6);
|
memcpy(&d->content.d80, epg->bin + epg->offset, 6);
|
||||||
epg->offset += 6;
|
epg->offset += 6;
|
||||||
|
@ -127,37 +95,15 @@ read_descriptor(struct epg *epg, struct descriptor *d)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DS_USER_DEFINED:
|
case DS_USER_DEFINED:
|
||||||
{
|
d->content.d137.text =
|
||||||
int sofar = 0;
|
read_lstring(epg, &d->content.d137.textlen);
|
||||||
|
|
||||||
/* reserved:6 guidance_type:2 */
|
|
||||||
d->content.d137.guidance_type = epg->bin[epg->offset++] & 0x3;
|
|
||||||
sofar++;
|
|
||||||
switch (d->content.d137.guidance_type)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
/* guidance_type 0 means unsuitable for broadcast
|
|
||||||
* prior to the watershed so set mode to 1. */
|
|
||||||
d->content.d137.guidance_mode = 1;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
/* reserved:7 guidance_mode:1 */
|
|
||||||
d->content.d137.guidance_mode =
|
|
||||||
epg->bin[epg->offset++] & 0x1;
|
|
||||||
sofar++;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* Unknown guidance type.. */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(d->content.d137.lang, epg->bin + epg->offset, 3);
|
memcpy(d->content.d137.lang, epg->bin + epg->offset, 3);
|
||||||
epg->offset += 3;
|
epg->offset += 3;
|
||||||
sofar += 3;
|
d->content.d137.warning = string_to_end(epg, d,
|
||||||
d->content.d137.warning = string_to_end(epg, d, sofar,
|
4 + d->content.d137.textlen,
|
||||||
&d->content.d137.warninglen);
|
&d->content.d137.warninglen);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case DS_LINKAGE:
|
case DS_LINKAGE:
|
||||||
memcpy(&d->content.d74, epg->bin + epg->offset,
|
memcpy(&d->content.d74, epg->bin + epg->offset,
|
||||||
|
@ -270,17 +216,14 @@ free_descriptor(struct descriptor *d)
|
||||||
free(d->content.d77.text);
|
free(d->content.d77.text);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DS_EXTENDED_EVENT:
|
|
||||||
if (d->content.d78.text)
|
|
||||||
free(d->content.d78.text);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DS_COMPONENT:
|
case DS_COMPONENT:
|
||||||
if (d->content.d80.text)
|
if (d->content.d80.text)
|
||||||
free(d->content.d80.text);
|
free(d->content.d80.text);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DS_USER_DEFINED:
|
case DS_USER_DEFINED:
|
||||||
|
if (d->content.d137.text)
|
||||||
|
free(d->content.d137.text);
|
||||||
if (d->content.d137.warning)
|
if (d->content.d137.warning)
|
||||||
free(d->content.d137.warning);
|
free(d->content.d137.warning);
|
||||||
break;
|
break;
|
||||||
|
@ -325,6 +268,7 @@ descriptor_name(struct descriptor *d)
|
||||||
case DS_CONTENT_IDENTIFIER: return "content id";
|
case DS_CONTENT_IDENTIFIER: return "content id";
|
||||||
case DS_FTA_CONTENT_MGMT: return "content mgmt";
|
case DS_FTA_CONTENT_MGMT: return "content mgmt";
|
||||||
case DS_USER_DEFINED: return "user defined";
|
case DS_USER_DEFINED: return "user defined";
|
||||||
|
default: return "Unknown";
|
||||||
}
|
}
|
||||||
return "Unknown";
|
return "Unknown";
|
||||||
}
|
}
|
||||||
|
@ -356,8 +300,10 @@ content_type(struct descriptor *d)
|
||||||
return "Leisure";
|
return "Leisure";
|
||||||
case 0xf:
|
case 0xf:
|
||||||
return "Drama";
|
return "Drama";
|
||||||
|
default:
|
||||||
|
return "Undefined";
|
||||||
}
|
}
|
||||||
return "Undefined";
|
return "Unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -381,13 +327,6 @@ dump_descriptor(struct descriptor *d, int content)
|
||||||
DUMPHEX(d, content.d77.text, d->content.d77.textlen);
|
DUMPHEX(d, content.d77.text, d->content.d77.textlen);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DS_EXTENDED_EVENT:
|
|
||||||
DUMPNSTR(d, content.d78.lang, 3);
|
|
||||||
DUMPINT(d, content.d78.items);
|
|
||||||
DUMPINT(d, content.d78.textlen);
|
|
||||||
DUMPHEX(d, content.d78.text, d->content.d78.textlen);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DS_COMPONENT:
|
case DS_COMPONENT:
|
||||||
DUMPINT(d, content.d80.stream_content);
|
DUMPINT(d, content.d80.stream_content);
|
||||||
DUMPINT(d, content.d80.reserved);
|
DUMPINT(d, content.d80.reserved);
|
||||||
|
@ -399,9 +338,9 @@ dump_descriptor(struct descriptor *d, int content)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DS_USER_DEFINED:
|
case DS_USER_DEFINED:
|
||||||
DUMPINT(d, content.d137.guidance_type);
|
DUMPINT(d, content.d137.textlen);
|
||||||
DUMPINT(d, content.d137.guidance_mode);
|
|
||||||
DUMPNSTR(d, content.d137.lang, 3);
|
DUMPNSTR(d, content.d137.lang, 3);
|
||||||
|
DUMPHEX(d, content.d137.text, d->content.d137.textlen);
|
||||||
DUMPHEX(d, content.d137.warning, d->content.d137.warninglen);
|
DUMPHEX(d, content.d137.warning, d->content.d137.warninglen);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
65
descriptor.h
65
descriptor.h
|
@ -3,15 +3,18 @@
|
||||||
* by af123, 2011
|
* by af123, 2011
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define DS_LINKAGE 74 /* 0x4a */
|
#define DS_LINKAGE 74
|
||||||
#define DS_SHORT_EVENT 77 /* 0x4d */
|
#define DS_SHORT_EVENT 77
|
||||||
#define DS_EXTENDED_EVENT 78 /* 0x4e */
|
#define DS_COMPONENT 80
|
||||||
#define DS_COMPONENT 80 /* 0x50 */
|
#define DS_CONTENT 84
|
||||||
#define DS_CONTENT 84 /* 0x54 */
|
#define DS_PRIVATE_DATA_SPECIFIER 95
|
||||||
#define DS_PRIVATE_DATA_SPECIFIER 95 /* 0x5f */
|
#define DS_CONTENT_IDENTIFIER 118
|
||||||
#define DS_CONTENT_IDENTIFIER 118 /* 0x76 */
|
#define DS_FTA_CONTENT_MGMT 126
|
||||||
#define DS_FTA_CONTENT_MGMT 126 /* 0x7e */
|
#ifdef FOXSATPLATFORM
|
||||||
#define DS_USER_DEFINED 137 /* 0x89 */
|
#define DS_USER_DEFINED 218
|
||||||
|
#else
|
||||||
|
#define DS_USER_DEFINED 137
|
||||||
|
#endif
|
||||||
|
|
||||||
#define PARSER_SHORT_EVENT 0
|
#define PARSER_SHORT_EVENT 0
|
||||||
#define PARSER_USER_DEFINED 1
|
#define PARSER_USER_DEFINED 1
|
||||||
|
@ -19,9 +22,7 @@
|
||||||
#define PARSER_CRID_EVENT 3
|
#define PARSER_CRID_EVENT 3
|
||||||
#define PARSER_CRID_SERIES 4
|
#define PARSER_CRID_SERIES 4
|
||||||
#define PARSER_CRID_REC 5
|
#define PARSER_CRID_REC 5
|
||||||
#define PARSER_EXTENDED_EVENT 6
|
#define PARSER_MAX 6
|
||||||
#define PARSER_FTA_CONTENT_MGMT 7
|
|
||||||
#define PARSER_MAX 8
|
|
||||||
|
|
||||||
#define CRIDT_EVENT '1'
|
#define CRIDT_EVENT '1'
|
||||||
#define CRIDT_SERIES '2'
|
#define CRIDT_SERIES '2'
|
||||||
|
@ -29,8 +30,13 @@
|
||||||
|
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
struct crid {
|
struct crid {
|
||||||
|
#ifdef FOXSATPLATFORM
|
||||||
|
unsigned int type:6;
|
||||||
|
unsigned int location:2;
|
||||||
|
#else
|
||||||
unsigned int location:2;
|
unsigned int location:2;
|
||||||
unsigned int type:6;
|
unsigned int type:6;
|
||||||
|
#endif
|
||||||
unsigned int cridlen;
|
unsigned int cridlen;
|
||||||
char *crid;
|
char *crid;
|
||||||
unsigned int ref:16;
|
unsigned int ref:16;
|
||||||
|
@ -48,14 +54,13 @@ struct descriptor {
|
||||||
char *text;
|
char *text;
|
||||||
} d77; /* SHORT_EVENT */
|
} d77; /* SHORT_EVENT */
|
||||||
struct {
|
struct {
|
||||||
char lang[3];
|
#ifdef FOXSATPLATFORM
|
||||||
unsigned int items;
|
unsigned int reserved:4;
|
||||||
unsigned int textlen;
|
unsigned int stream_content:4;
|
||||||
char *text;
|
#else
|
||||||
} d78; /* EXTENDED_EVENT */
|
|
||||||
struct {
|
|
||||||
unsigned int stream_content:4;
|
unsigned int stream_content:4;
|
||||||
unsigned int reserved:4;
|
unsigned int reserved:4;
|
||||||
|
#endif
|
||||||
unsigned int type:8;
|
unsigned int type:8;
|
||||||
unsigned int tag:8;
|
unsigned int tag:8;
|
||||||
char lang[3];
|
char lang[3];
|
||||||
|
@ -63,17 +68,22 @@ struct descriptor {
|
||||||
unsigned int textlen;
|
unsigned int textlen;
|
||||||
} d80; /* COMPONENT */
|
} d80; /* COMPONENT */
|
||||||
struct {
|
struct {
|
||||||
|
#ifdef FOXSATPLATFORM
|
||||||
|
unsigned int level1:4;
|
||||||
|
unsigned int level2:4;
|
||||||
|
#else
|
||||||
unsigned int level2:4;
|
unsigned int level2:4;
|
||||||
unsigned int level1:4;
|
unsigned int level1:4;
|
||||||
|
#endif
|
||||||
unsigned int user:8;
|
unsigned int user:8;
|
||||||
} d84; /* CONTENT */
|
} d84; /* CONTENT */
|
||||||
struct {
|
struct {
|
||||||
unsigned int guidance_type;
|
unsigned int textlen;
|
||||||
unsigned int guidance_mode;
|
char *text;
|
||||||
char lang[3];
|
char lang[3];
|
||||||
char *warning;
|
char *warning;
|
||||||
unsigned int warninglen;
|
unsigned int warninglen;
|
||||||
} d137; /* USER_DEFINED - content warnings */
|
} d137; /* USER_DEFINED - content warnings? */
|
||||||
struct {
|
struct {
|
||||||
unsigned int no_revocation:1;
|
unsigned int no_revocation:1;
|
||||||
unsigned int control_remote_access:2;
|
unsigned int control_remote_access:2;
|
||||||
|
@ -87,16 +97,29 @@ struct descriptor {
|
||||||
unsigned int linkage_type:8;
|
unsigned int linkage_type:8;
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
|
#ifdef FOXSATPLATFORM
|
||||||
|
unsigned int handover_type:4;
|
||||||
|
unsigned int reserved:3;
|
||||||
|
unsigned int origin_type:1;
|
||||||
|
unsigned int id:16;
|
||||||
|
#else
|
||||||
unsigned int origin_type:1;
|
unsigned int origin_type:1;
|
||||||
unsigned int reserved:3;
|
unsigned int reserved:3;
|
||||||
unsigned int handover_type:4;
|
unsigned int handover_type:4;
|
||||||
unsigned int id:16;
|
unsigned int id:16;
|
||||||
|
#endif
|
||||||
} l8;
|
} l8;
|
||||||
struct {
|
struct {
|
||||||
unsigned int event_id:16;
|
unsigned int event_id:16;
|
||||||
|
#ifdef FOXSATPLATFORM
|
||||||
|
unsigned int listed:1;
|
||||||
|
unsigned int simulcast:1;
|
||||||
|
unsigned int reserved:6;
|
||||||
|
#else
|
||||||
unsigned int reserved:6;
|
unsigned int reserved:6;
|
||||||
unsigned int simulcast:1;
|
unsigned int simulcast:1;
|
||||||
unsigned int listed:1;
|
unsigned int listed:1;
|
||||||
|
#endif
|
||||||
} ld;
|
} ld;
|
||||||
} l;
|
} l;
|
||||||
} d74; /* DS_LINKAGE */
|
} d74; /* DS_LINKAGE */
|
||||||
|
|
149
epg.c
149
epg.c
|
@ -23,7 +23,7 @@ read_section(struct epg *epg)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
memcpy(&h, epg->bin + epg->offset, sizeof(h));
|
memcpy(&h, epg->bin + epg->offset, sizeof(h));
|
||||||
if (memcmp(h.magic, SECTION_MAGIC, sizeof(h.magic) - 1))
|
if (memcmp(h.magic, SECTION_MAGIC, sizeof(h.magic)))
|
||||||
{
|
{
|
||||||
printf("Section header magic mismatch.\n");
|
printf("Section header magic mismatch.\n");
|
||||||
hexdump(epg->bin + epg->offset, 64, 0);
|
hexdump(epg->bin + epg->offset, 64, 0);
|
||||||
|
@ -111,28 +111,6 @@ dump_data(struct data *d)
|
||||||
DUMPINT(d, u1.u.descriptors_loop_length);
|
DUMPINT(d, u1.u.descriptors_loop_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
|
||||||
check_filter_timerange(struct epgfilter *f, enum epgfiltertype type,
|
|
||||||
unsigned long idl, unsigned long idh)
|
|
||||||
{
|
|
||||||
if (!f)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
for (; f; f = f->next)
|
|
||||||
{
|
|
||||||
if (f->type != type)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!(
|
|
||||||
(idl > f->num && idl < f->num2) ||
|
|
||||||
(idh > f->num && idh < f->num2) ||
|
|
||||||
(idl < f->num && idh > f->num))
|
|
||||||
)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
check_filter_range(struct epgfilter *f, enum epgfiltertype type,
|
check_filter_range(struct epgfilter *f, enum epgfiltertype type,
|
||||||
unsigned long idl, unsigned long idh)
|
unsigned long idl, unsigned long idh)
|
||||||
|
@ -142,14 +120,7 @@ check_filter_range(struct epgfilter *f, enum epgfiltertype type,
|
||||||
|
|
||||||
for (; f; f = f->next)
|
for (; f; f = f->next)
|
||||||
{
|
{
|
||||||
if (f->type != type)
|
if (f->type == type && (f->num < idl || f->num > idh))
|
||||||
continue;
|
|
||||||
if (f->match == FT_RANGE)
|
|
||||||
{
|
|
||||||
if (idl < f->num || idl > f->num2)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else if (f->num < idl || f->num > idh)
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -178,7 +149,7 @@ check_filter(struct epgfilter *f, enum epgfiltertype type,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
void
|
||||||
parse(char *epgpath,
|
parse(char *epgpath,
|
||||||
void (*callback)(struct epg *, struct section *, struct data *,
|
void (*callback)(struct epg *, struct section *, struct data *,
|
||||||
struct descriptor **, void *), void *val, struct epgfilter *filter)
|
struct descriptor **, void *), void *val, struct epgfilter *filter)
|
||||||
|
@ -188,7 +159,7 @@ parse(char *epgpath,
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!(epg = open_file(epgpath)))
|
if (!(epg = open_file(epgpath)))
|
||||||
return 0;
|
return;
|
||||||
|
|
||||||
while (epg->offset < epg->binsize)
|
while (epg->offset < epg->binsize)
|
||||||
{
|
{
|
||||||
|
@ -206,8 +177,11 @@ parse(char *epgpath,
|
||||||
/* Skip this service. */
|
/* Skip this service. */
|
||||||
epg->offset += s->total_length - 14;
|
epg->offset += s->total_length - 14;
|
||||||
/* Skip padding bytes... */
|
/* Skip padding bytes... */
|
||||||
while (epg->offset < epg->binsize &&
|
#ifdef FOXSATFILE
|
||||||
epg->bin[epg->offset] == 'U')
|
while ((epg->offset % 4) != 0)
|
||||||
|
#else
|
||||||
|
while (epg->bin[epg->offset] == 'U')
|
||||||
|
#endif
|
||||||
epg->offset++;
|
epg->offset++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -233,10 +207,10 @@ parse(char *epgpath,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((filterflags &
|
if ((filterflags & FILTER_TIMESTAMP))
|
||||||
(FILTER_TIMESTAMP | FILTER_TIMERANGE)))
|
|
||||||
{
|
{
|
||||||
time_t tm, dur;
|
time_t tm;
|
||||||
|
int dur;
|
||||||
|
|
||||||
tm = mjd(d->start_date, d->start_hour,
|
tm = mjd(d->start_date, d->start_hour,
|
||||||
d->start_min, d->start_sec);
|
d->start_min, d->start_sec);
|
||||||
|
@ -244,29 +218,12 @@ parse(char *epgpath,
|
||||||
dur = d->dur_hour * 3600 + d->dur_min * 60 +
|
dur = d->dur_hour * 3600 + d->dur_min * 60 +
|
||||||
d->dur_sec;
|
d->dur_sec;
|
||||||
|
|
||||||
if ((filterflags & FILTER_TIMESTAMP))
|
if (!check_filter_range(filter,
|
||||||
|
FILTER_TIMESTAMP, tm, tm + dur))
|
||||||
{
|
{
|
||||||
if (!check_filter_range(filter,
|
/* Skip this event. */
|
||||||
FILTER_TIMESTAMP,
|
epg->offset = dend;
|
||||||
(unsigned long) tm,
|
continue;
|
||||||
(unsigned long) (tm + dur)))
|
|
||||||
{
|
|
||||||
/* Skip this event. */
|
|
||||||
epg->offset = dend;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((filterflags & FILTER_TIMERANGE))
|
|
||||||
{
|
|
||||||
if (!check_filter_timerange(filter,
|
|
||||||
FILTER_TIMERANGE,
|
|
||||||
(unsigned long) tm,
|
|
||||||
(unsigned long) (tm + dur)))
|
|
||||||
{
|
|
||||||
/* Skip this event. */
|
|
||||||
epg->offset = dend;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,14 +248,6 @@ parse(char *epgpath,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (debug)
|
|
||||||
printf("Checking descriptor: "
|
|
||||||
"%d/%#x (%d)\n",
|
|
||||||
dstag, dstag, dslen);
|
|
||||||
if (debug > 3)
|
|
||||||
hexdump(epg->bin + epg->offset,
|
|
||||||
dslen + 2, 0);
|
|
||||||
|
|
||||||
switch (dstag)
|
switch (dstag)
|
||||||
{
|
{
|
||||||
case DS_SHORT_EVENT:
|
case DS_SHORT_EVENT:
|
||||||
|
@ -308,13 +257,6 @@ parse(char *epgpath,
|
||||||
dslist[PARSER_SHORT_EVENT] = ds;
|
dslist[PARSER_SHORT_EVENT] = ds;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DS_EXTENDED_EVENT:
|
|
||||||
if (!(ds = read_descriptor_header(epg)))
|
|
||||||
break;
|
|
||||||
read_descriptor(epg, ds);
|
|
||||||
dslist[PARSER_EXTENDED_EVENT] = ds;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DS_CONTENT_IDENTIFIER:
|
case DS_CONTENT_IDENTIFIER:
|
||||||
if (!(ds = read_descriptor_header(epg)))
|
if (!(ds = read_descriptor_header(epg)))
|
||||||
break;
|
break;
|
||||||
|
@ -347,14 +289,12 @@ parse(char *epgpath,
|
||||||
dslist[PARSER_CONTENT] = ds;
|
dslist[PARSER_CONTENT] = ds;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DS_FTA_CONTENT_MGMT:
|
|
||||||
if (!(ds = read_descriptor_header(epg)))
|
|
||||||
break;
|
|
||||||
read_descriptor(epg, ds);
|
|
||||||
dslist[PARSER_FTA_CONTENT_MGMT] = ds;
|
|
||||||
break;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
case DS_FTA_CONTENT_MGMT:
|
||||||
|
read_descriptor(epg, ds);
|
||||||
|
dump_descriptor(ds, 1);
|
||||||
|
free_descriptor(ds);
|
||||||
|
break;
|
||||||
|
|
||||||
case DS_LINKAGE:
|
case DS_LINKAGE:
|
||||||
read_descriptor(epg, ds);
|
read_descriptor(epg, ds);
|
||||||
|
@ -364,39 +304,11 @@ parse(char *epgpath,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (debug > 2)
|
|
||||||
printf("! Unhandled.\n");
|
|
||||||
epg->offset += dslen + 2;
|
epg->offset += dslen + 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Move synopsis from extended event descriptor into
|
|
||||||
* short description if appropriate. */
|
|
||||||
if (dslist[PARSER_SHORT_EVENT] &&
|
|
||||||
dslist[PARSER_EXTENDED_EVENT] &&
|
|
||||||
dslist[PARSER_EXTENDED_EVENT]->content.d78.textlen
|
|
||||||
> 0 &&
|
|
||||||
dslist[PARSER_SHORT_EVENT]->content.d77.textlen
|
|
||||||
== 2 &&
|
|
||||||
dslist[PARSER_SHORT_EVENT]->content.d77.text[1]
|
|
||||||
== '\0')
|
|
||||||
{
|
|
||||||
if (debug > 3)
|
|
||||||
printf("Moving event text from "
|
|
||||||
"extended to short event.\n");
|
|
||||||
free(dslist[PARSER_SHORT_EVENT]
|
|
||||||
->content.d77.text);
|
|
||||||
dslist[PARSER_SHORT_EVENT]->content.d77.text
|
|
||||||
= dslist[PARSER_EXTENDED_EVENT]->
|
|
||||||
content.d78.text;
|
|
||||||
dslist[PARSER_SHORT_EVENT]->content.d77.textlen
|
|
||||||
= dslist[PARSER_EXTENDED_EVENT]->
|
|
||||||
content.d78.textlen;
|
|
||||||
dslist[PARSER_EXTENDED_EVENT]->content.d78.text
|
|
||||||
= (char *)NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
(
|
(
|
||||||
!(filterflags & FILTER_CRID) ||
|
!(filterflags & FILTER_CRID) ||
|
||||||
|
@ -416,13 +328,6 @@ parse(char *epgpath,
|
||||||
check_filter(filter, FILTER_CONTENT,
|
check_filter(filter, FILTER_CONTENT,
|
||||||
dslist[PARSER_CONTENT]->content.d84.level1,
|
dslist[PARSER_CONTENT]->content.d84.level1,
|
||||||
NULL))
|
NULL))
|
||||||
) && (
|
|
||||||
!(filterflags & FILTER_GUIDETYPE) ||
|
|
||||||
(dslist[PARSER_USER_DEFINED] &&
|
|
||||||
check_filter(filter, FILTER_GUIDETYPE,
|
|
||||||
dslist[PARSER_USER_DEFINED]->
|
|
||||||
content.d137.guidance_type,
|
|
||||||
NULL))
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
callback(epg, s, d, dslist, val);
|
callback(epg, s, d, dslist, val);
|
||||||
|
@ -431,19 +336,19 @@ parse(char *epgpath,
|
||||||
if (dslist[i])
|
if (dslist[i])
|
||||||
free_descriptor(dslist[i]);
|
free_descriptor(dslist[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Skip CRC */
|
/* Skip CRC */
|
||||||
epg->offset += 4;
|
epg->offset += 4;
|
||||||
|
|
||||||
/* Skip padding bytes... */
|
/* Skip padding bytes... */
|
||||||
while (epg->offset < epg->binsize &&
|
#ifdef FOXSATFILE
|
||||||
epg->bin[epg->offset] == 'U')
|
while ((epg->offset % 4) != 0)
|
||||||
|
#else
|
||||||
|
while (epg->bin[epg->offset] == 'U')
|
||||||
|
#endif
|
||||||
epg->offset++;
|
epg->offset++;
|
||||||
}
|
}
|
||||||
|
|
||||||
close_file(epg);
|
close_file(epg);
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
42
epg.h
42
epg.h
|
@ -5,7 +5,11 @@
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
|
||||||
#define DEFAULT_EPG_FILE "/mnt/hd1/dvbepg/epg.dat"
|
#ifdef FOXSATFILE
|
||||||
|
#define DEFAULT_EPG_FILE "/mnt/hd2/fsatepg/epg.dat"
|
||||||
|
#else
|
||||||
|
#define DEFAULT_EPG_FILE "/mnt/hd1/dvbepg/epg.dat"
|
||||||
|
#endif
|
||||||
|
|
||||||
struct epg {
|
struct epg {
|
||||||
char fname[MAXPATHLEN + 1];
|
char fname[MAXPATHLEN + 1];
|
||||||
|
@ -15,26 +19,50 @@ struct epg {
|
||||||
uint32_t binsize;
|
uint32_t binsize;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SECTION_MAGIC "(Gq\x87\x00\x00\x00\x00\x02\x00\x00\x00\x00\x01"
|
#ifdef FOXSATFILE
|
||||||
|
#define SECTION_MAGIC "\x19\x77\x09\x29\xff\xff"
|
||||||
|
#else
|
||||||
|
#define SECTION_MAGIC "(Gq\x87\x00\x00\x00\x00\x02\x00\x00\x00\x00\x01"
|
||||||
|
#endif
|
||||||
|
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
|
|
||||||
|
|
||||||
struct section {
|
struct section {
|
||||||
|
#ifdef FOXSATFILE
|
||||||
|
char magic[6];
|
||||||
|
#else
|
||||||
char magic[14];
|
char magic[14];
|
||||||
|
#endif
|
||||||
unsigned int total_length:16;
|
unsigned int total_length:16;
|
||||||
|
#ifndef FOXSATFILE
|
||||||
unsigned int magic2:32;
|
unsigned int magic2:32;
|
||||||
|
#endif
|
||||||
unsigned int table_id:8;
|
unsigned int table_id:8;
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
|
#ifdef FOXSATPLATFORM
|
||||||
|
unsigned int syntax_indicator:1;
|
||||||
|
unsigned int reserved:3;
|
||||||
|
unsigned int length:12;
|
||||||
|
#else
|
||||||
unsigned int length:12;
|
unsigned int length:12;
|
||||||
unsigned int reserved:3;
|
unsigned int reserved:3;
|
||||||
unsigned int syntax_indicator:1;
|
unsigned int syntax_indicator:1;
|
||||||
|
#endif
|
||||||
} u;
|
} u;
|
||||||
unsigned int comp:16;
|
unsigned int comp:16;
|
||||||
} u1;
|
} u1;
|
||||||
unsigned int service_id:16;
|
unsigned int service_id:16;
|
||||||
|
#ifdef FOXSATPLATFORM
|
||||||
|
unsigned int reserved2:2;
|
||||||
|
unsigned int version_number:5;
|
||||||
|
unsigned int current_next_indicator:1;
|
||||||
|
#else
|
||||||
unsigned int current_next_indicator:1;
|
unsigned int current_next_indicator:1;
|
||||||
unsigned int version_number:5;
|
unsigned int version_number:5;
|
||||||
unsigned int reserved2:2;
|
unsigned int reserved2:2;
|
||||||
|
#endif
|
||||||
unsigned int section_number:8;
|
unsigned int section_number:8;
|
||||||
unsigned int last_section_number:8;
|
unsigned int last_section_number:8;
|
||||||
unsigned int transport_stream_id:16;
|
unsigned int transport_stream_id:16;
|
||||||
|
@ -55,9 +83,15 @@ struct data {
|
||||||
unsigned int dur_sec:8;
|
unsigned int dur_sec:8;
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
|
#ifdef FOXSATPLATFORM
|
||||||
|
unsigned int running_status:3;
|
||||||
|
unsigned int free_CA_mode:1;
|
||||||
|
unsigned int descriptors_loop_length:12;
|
||||||
|
#else
|
||||||
unsigned int descriptors_loop_length:12;
|
unsigned int descriptors_loop_length:12;
|
||||||
unsigned int free_CA_mode:1;
|
unsigned int free_CA_mode:1;
|
||||||
unsigned int running_status:3;
|
unsigned int running_status:3;
|
||||||
|
#endif
|
||||||
} u;
|
} u;
|
||||||
unsigned int comp:16;
|
unsigned int comp:16;
|
||||||
} u1;
|
} u1;
|
||||||
|
@ -70,9 +104,7 @@ enum epgfiltertype {
|
||||||
FILTER_TIMESTAMP = 0x8,
|
FILTER_TIMESTAMP = 0x8,
|
||||||
FILTER_CRID = 0x10,
|
FILTER_CRID = 0x10,
|
||||||
FILTER_SCRID = 0x20,
|
FILTER_SCRID = 0x20,
|
||||||
FILTER_CONTENT = 0x40,
|
FILTER_CONTENT = 0x40
|
||||||
FILTER_TIMERANGE = 0x80,
|
|
||||||
FILTER_GUIDETYPE = 0x100
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum matchtype { FT_EQUAL, FT_RANGE, FT_GREATER, FT_LESS };
|
enum matchtype { FT_EQUAL, FT_RANGE, FT_GREATER, FT_LESS };
|
||||||
|
|
|
@ -0,0 +1,193 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "epgsql.h"
|
||||||
|
#include <sqlite3.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
static int callback(void *NotUsed, int argc, char **argv, char **azColName){
|
||||||
|
int i;
|
||||||
|
for(i=0; i<argc; i++){
|
||||||
|
printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int OpenCreateDB(char * DBFile, sqlite3 **db){
|
||||||
|
/* Open the Database file -> Create it if it doesn't exist
|
||||||
|
Return the Success/Failure status of the Open command
|
||||||
|
and the pointer to the opened DB */
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = sqlite3_open_v2(DBFile, &*db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);
|
||||||
|
|
||||||
|
if( rc != SQLITE_OK){
|
||||||
|
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(*db));
|
||||||
|
sqlite3_close(*db);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CloseDB(sqlite3 *db) {
|
||||||
|
/* Close the database and return the result */
|
||||||
|
return sqlite3_close(db);
|
||||||
|
}
|
||||||
|
|
||||||
|
int InitDB(char * InitScript, sqlite3 *db) {
|
||||||
|
/* Use the database initialisation script to initialise the DB
|
||||||
|
Script should create tables if they don't already exist
|
||||||
|
And delete any data that will be replaced */
|
||||||
|
int fp;
|
||||||
|
char *zErrMsg = 0;
|
||||||
|
int rc;
|
||||||
|
char * SQLStatement;
|
||||||
|
uint32_t SQLStatementSize;
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
/* Get the size of the init file */
|
||||||
|
if (stat(InitScript, &st) == -1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error getting size of DB Creation/Initialisation File : %s\n", InitScript);
|
||||||
|
sqlite3_close(db);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
SQLStatementSize = st.st_size;
|
||||||
|
|
||||||
|
if ((fp = open(InitScript, O_RDONLY, 0)) == -1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Failed to open DB Creation/Initialisation File : %s\n", InitScript);
|
||||||
|
sqlite3_close(db);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLStatement = (char *)mmap(NULL, SQLStatementSize, PROT_READ, MAP_SHARED, fp, 0);
|
||||||
|
if (SQLStatement == MAP_FAILED)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Failed to MMAP the DB Creation File : %s\n", InitScript);
|
||||||
|
fprintf(stderr, "SQLStatement : %s, Map_failed : %i\n", SQLStatement, MAP_FAILED);
|
||||||
|
|
||||||
|
close(fp);
|
||||||
|
sqlite3_close(db);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = sqlite3_exec(db, SQLStatement, 0, 0, &zErrMsg);
|
||||||
|
|
||||||
|
munmap((void *)SQLStatement, SQLStatementSize);
|
||||||
|
if (fp > 0)
|
||||||
|
close(fp);
|
||||||
|
|
||||||
|
if( rc!=SQLITE_OK ){
|
||||||
|
fprintf(stderr, "SQL error executing DB Init script : %s\n", zErrMsg);
|
||||||
|
fprintf(stderr, "RC = %i\n", rc);
|
||||||
|
sqlite3_free(zErrMsg);
|
||||||
|
sqlite3_close(db);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ExecSQLStatement(char *SQL, sqlite3 *db)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
char *zErrMsg = 0;
|
||||||
|
|
||||||
|
rc = sqlite3_exec(db, SQL, 0, 0, &zErrMsg);
|
||||||
|
|
||||||
|
if( rc!=SQLITE_OK ){
|
||||||
|
fprintf(stderr, "SQL error executing script : %s\n", zErrMsg);
|
||||||
|
fprintf(stderr, "RC : %i\n", rc);
|
||||||
|
fprintf(stderr, "SQL : %s\n", SQL);
|
||||||
|
sqlite3_free(zErrMsg);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ExecSQLStatementRowCount(char *SQL, sqlite3 *db)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
char *zErrMsg = 0;
|
||||||
|
|
||||||
|
rc = sqlite3_exec(db, SQL, 0, 0, &zErrMsg);
|
||||||
|
|
||||||
|
if( rc!=SQLITE_OK ){
|
||||||
|
fprintf(stderr, "SQL error executing script : %s\n", zErrMsg);
|
||||||
|
fprintf(stderr, "RC : %i\n", rc);
|
||||||
|
fprintf(stderr, "SQL : %s\n", SQL);
|
||||||
|
sqlite3_free(zErrMsg);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return sqlite3_changes(db);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*int GetFileTimestamp(sqlite3 *db, char *res)*/
|
||||||
|
void GetFileTimestamp(unsigned int * TS)
|
||||||
|
{
|
||||||
|
sqlite3_stmt *pStmt;
|
||||||
|
char sql[256]={0};
|
||||||
|
int rc;
|
||||||
|
int i;
|
||||||
|
sqlite3 *db1;
|
||||||
|
int KeepGoing=1;
|
||||||
|
|
||||||
|
*TS = 0;
|
||||||
|
|
||||||
|
rc = sqlite3_open_v2("/opt/epg/epg.db", &db1, SQLITE_OPEN_READWRITE, 0);
|
||||||
|
if( rc ){
|
||||||
|
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db1));
|
||||||
|
sqlite3_close(db1);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sprintf(sql, "select lastfileprocessed from epgtimestamp limit 1;");
|
||||||
|
|
||||||
|
if (sqlite3_prepare_v2(db1, sql, strlen(sql), &pStmt, NULL) != SQLITE_OK) {
|
||||||
|
fprintf(stderr, "Error Preparing Statement : %s\n", sqlite3_errmsg(db1));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (KeepGoing==1) {
|
||||||
|
rc = sqlite3_step(pStmt);
|
||||||
|
|
||||||
|
switch (rc) {
|
||||||
|
case SQLITE_ROW:
|
||||||
|
/* know it will be one column and one row (due to the query) so
|
||||||
|
stuff the result into the result string */
|
||||||
|
for (i=0; i<(sqlite3_column_count(pStmt)); i++)
|
||||||
|
*TS = strtoul((char*)sqlite3_column_text(pStmt, i), NULL, 10);
|
||||||
|
break;
|
||||||
|
case SQLITE_DONE:
|
||||||
|
KeepGoing=0;
|
||||||
|
break;
|
||||||
|
case SQLITE_ERROR:
|
||||||
|
fprintf(stderr, "Error Executing Statement : %s\n", sqlite3_errmsg(db1));
|
||||||
|
KeepGoing=0;
|
||||||
|
break;
|
||||||
|
case SQLITE_BUSY:
|
||||||
|
case SQLITE_LOCKED:
|
||||||
|
fprintf(stderr, "In waiting loop ... %i\n", rc);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "Error Condition ... %i\n", rc);
|
||||||
|
fprintf(stderr, "Error Executing Statement : %s\n", sqlite3_errmsg(db1));
|
||||||
|
KeepGoing=0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_finalize(pStmt);
|
||||||
|
sqlite3_close(db1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
#include <sqlite3.h>
|
||||||
|
|
||||||
|
static int callback(void *NotUsed, int argc, char **argv, char **azColName);
|
||||||
|
int OpenCreateDB(char * DBFile, sqlite3 **db);
|
||||||
|
int CloseDB(sqlite3 *db);
|
||||||
|
int InitDB(char * InitScript, sqlite3 *db);
|
||||||
|
int ExecSQLStatement(char *SQL, sqlite3 *db);
|
||||||
|
int ExecSQLStatementRowCount(char *SQL, sqlite3 *db);
|
||||||
|
void GetFileTimestamp(unsigned int *);
|
||||||
|
|
||||||
|
|
33
file.c
33
file.c
|
@ -23,27 +23,7 @@ struct epg *
|
||||||
open_file(char *filename)
|
open_file(char *filename)
|
||||||
{
|
{
|
||||||
struct epg *epg;
|
struct epg *epg;
|
||||||
struct stat st, st2;
|
struct stat st;
|
||||||
|
|
||||||
if (debug)
|
|
||||||
printf("Opening file '%s'\n", filename);
|
|
||||||
|
|
||||||
if (stat(filename, &st) == -1)
|
|
||||||
{
|
|
||||||
perror(filename);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
sleep(1);
|
|
||||||
if (stat(filename, &st2) == -1)
|
|
||||||
{
|
|
||||||
perror(filename);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (st.st_size != st2.st_size)
|
|
||||||
{
|
|
||||||
printf("EPG data file is updating, try later.\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(epg = malloc(sizeof(struct epg))))
|
if (!(epg = malloc(sizeof(struct epg))))
|
||||||
{
|
{
|
||||||
|
@ -51,7 +31,18 @@ open_file(char *filename)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
printf("Opening file '%s'\n", filename);
|
||||||
|
|
||||||
strcpy(epg->fname, filename);
|
strcpy(epg->fname, filename);
|
||||||
|
|
||||||
|
if (stat(epg->fname, &st) == -1)
|
||||||
|
{
|
||||||
|
perror(epg->fname);
|
||||||
|
free(epg);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
epg->binsize = st.st_size;
|
epg->binsize = st.st_size;
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
|
|
18
huffman.c
18
huffman.c
|
@ -1,14 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Humax EPG Tool
|
* Humax EPG Tool
|
||||||
* by af123, 2011 - 2018
|
* by af123, 2011
|
||||||
*
|
|
||||||
* These tables and the decompression code are derived from MythTV
|
|
||||||
* https://github.com/MythTV/mythtv/tree/master/mythtv/libs/libmythtv/mpeg/
|
|
||||||
* freesat_tables.cpp and freesat_huffman.cpp
|
|
||||||
*
|
|
||||||
* MythTV is released as free open source software under version 2 or later
|
|
||||||
* of the GPL (GNU General Public License) a copy of which can be viewed at
|
|
||||||
* https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -22,6 +14,12 @@
|
||||||
|
|
||||||
#include "lint.h"
|
#include "lint.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These tables and the decompression code are taken/derived from MythTV
|
||||||
|
* https://github.com/MythTV/mythtv/tree/master/mythtv/libs/libmythtv/mpeg
|
||||||
|
* freesat_tables.h and freesat_huffman.cpp
|
||||||
|
*/
|
||||||
|
|
||||||
struct fsattab {
|
struct fsattab {
|
||||||
unsigned int value;
|
unsigned int value;
|
||||||
short bits;
|
short bits;
|
||||||
|
@ -5746,7 +5744,7 @@ static unsigned fsat_index_2[] = {
|
||||||
#define ESCAPE '\1'
|
#define ESCAPE '\1'
|
||||||
|
|
||||||
unsigned char *
|
unsigned char *
|
||||||
freeview_huffman_to_string(const unsigned char *src, unsigned int size,
|
freeview_huffman_to_string(const unsigned char *src, uint size,
|
||||||
unsigned int *len)
|
unsigned int *len)
|
||||||
{
|
{
|
||||||
struct fsattab *fsat_table;
|
struct fsattab *fsat_table;
|
||||||
|
|
7
lint.h
7
lint.h
|
@ -20,10 +20,9 @@ inline uint32_t read_uint32(uint8_t *, int);
|
||||||
void hexdump(uint8_t *, uint32_t, uint32_t);
|
void hexdump(uint8_t *, uint32_t, uint32_t);
|
||||||
char *hexstr(uint8_t *, uint32_t);
|
char *hexstr(uint8_t *, uint32_t);
|
||||||
char *ctime_nl(time_t *);
|
char *ctime_nl(time_t *);
|
||||||
time_t mjd(unsigned int, unsigned int, unsigned int, unsigned int);
|
time_t mjd(uint16_t, int, int, int);
|
||||||
void safeprintf(char *, ...);
|
void safeprintf(char *, ...);
|
||||||
void uncompress_epg(char **, unsigned int *);
|
void uncompress_epg(char **, unsigned int *);
|
||||||
void iso6937_convert(char **, unsigned int *);
|
|
||||||
|
|
||||||
struct epg *open_file(char *);
|
struct epg *open_file(char *);
|
||||||
void close_file(struct epg *);
|
void close_file(struct epg *);
|
||||||
|
@ -36,7 +35,7 @@ void dump_section(struct section *);
|
||||||
struct data *read_data(struct epg *);
|
struct data *read_data(struct epg *);
|
||||||
void dump_data(struct data *);
|
void dump_data(struct data *);
|
||||||
|
|
||||||
int parse(char *,
|
void parse(char *,
|
||||||
void (*)(struct epg *, struct section *, struct data *,
|
void (*)(struct epg *, struct section *, struct data *,
|
||||||
struct descriptor **, void *), void *, struct epgfilter *);
|
struct descriptor **, void *), void *, struct epgfilter *);
|
||||||
|
|
||||||
|
@ -47,7 +46,7 @@ void dump_descriptor(struct descriptor *, int);
|
||||||
void free_descriptor(struct descriptor *);
|
void free_descriptor(struct descriptor *);
|
||||||
const char *content_type(struct descriptor *);
|
const char *content_type(struct descriptor *);
|
||||||
|
|
||||||
unsigned char *freeview_huffman_to_string(const unsigned char *, unsigned int,
|
unsigned char *freeview_huffman_to_string(const unsigned char *, uint,
|
||||||
unsigned int *);
|
unsigned int *);
|
||||||
|
|
||||||
int is_bst(time_t);
|
int is_bst(time_t);
|
||||||
|
|
31
util.c
31
util.c
|
@ -13,42 +13,25 @@
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <xconv.h>
|
|
||||||
|
|
||||||
#include "lint.h"
|
#include "lint.h"
|
||||||
|
|
||||||
void
|
void
|
||||||
uncompress_epg(char **epg, unsigned int *epglen)
|
uncompress_epg(char **epg, unsigned int *epglen)
|
||||||
{
|
{
|
||||||
char *newepg;
|
char *new;
|
||||||
unsigned int newlen;
|
unsigned int newlen;
|
||||||
|
|
||||||
if ((newepg = (char *)
|
if ((new = (char *)
|
||||||
freeview_huffman_to_string((unsigned char *)(*epg),
|
freeview_huffman_to_string((unsigned char *)(*epg),
|
||||||
*epglen, &newlen)))
|
*epglen, &newlen)))
|
||||||
{
|
{
|
||||||
free(*epg);
|
free(*epg);
|
||||||
*epg = newepg;
|
*epg = new;
|
||||||
*epglen = newlen;
|
*epglen = newlen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
iso6937_convert(char **str, unsigned int *len)
|
|
||||||
{
|
|
||||||
char dst[0x200];
|
|
||||||
int newlen;
|
|
||||||
|
|
||||||
newlen = xconv(*str, dst, sizeof(dst));
|
|
||||||
|
|
||||||
if (newlen)
|
|
||||||
{
|
|
||||||
free(*str);
|
|
||||||
*str = strdup(dst);
|
|
||||||
*len = newlen;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef sun
|
#ifdef sun
|
||||||
char *
|
char *
|
||||||
strcasestr (char *h, char *n)
|
strcasestr (char *h, char *n)
|
||||||
|
@ -99,16 +82,16 @@ safeprintf(char *fmt, ...)
|
||||||
}
|
}
|
||||||
|
|
||||||
time_t
|
time_t
|
||||||
mjd(unsigned int day, unsigned int h, unsigned int m, unsigned int s)
|
mjd(uint16_t day, int h, int m, int s)
|
||||||
{
|
{
|
||||||
time_t tm;
|
time_t tm;
|
||||||
struct tm *t;
|
struct tm *t;
|
||||||
|
|
||||||
tm = MJD_TO_UNIX(day);
|
tm = MJD_TO_UNIX(day);
|
||||||
t = gmtime(&tm);
|
t = gmtime(&tm);
|
||||||
t->tm_hour = (int) h;
|
t->tm_hour = h;
|
||||||
t->tm_min = (int) m;
|
t->tm_min = m;
|
||||||
t->tm_sec = (int) s;
|
t->tm_sec = s;
|
||||||
|
|
||||||
return mktime(t);
|
return mktime(t);
|
||||||
}
|
}
|
||||||
|
|
6
util.h
6
util.h
|
@ -6,7 +6,11 @@
|
||||||
/* Works for modern dates, 1970 - 2038 */
|
/* Works for modern dates, 1970 - 2038 */
|
||||||
#define MJD_TO_UNIX(xx) (((xx) - 40587) * 86400)
|
#define MJD_TO_UNIX(xx) (((xx) - 40587) * 86400)
|
||||||
|
|
||||||
#define _swap16(v) ((((v) >> 8) & 0xff) | (((v) & 0xff) << 8))
|
#ifdef FOXSATPLATFORM
|
||||||
|
#define _swap16(v) (v)
|
||||||
|
#else
|
||||||
|
#define _swap16(v) ((((v) >> 8) & 0xff) | (((v) & 0xff) << 8))
|
||||||
|
#endif
|
||||||
|
|
||||||
#define bcd(v) (((((v) >> 4) & 0xf) * 10) + ((v) & 0xf))
|
#define bcd(v) (((((v) >> 4) & 0xf) * 10) + ((v) & 0xf))
|
||||||
|
|
||||||
|
|
40
xgetopt.h
40
xgetopt.h
|
@ -1,40 +0,0 @@
|
||||||
|
|
||||||
#define GETOPTOPT \
|
|
||||||
do { \
|
|
||||||
if (*++cp == '\0' && argc > 1) \
|
|
||||||
{ \
|
|
||||||
argc--, argv++; \
|
|
||||||
cp = argv[0]; \
|
|
||||||
} \
|
|
||||||
while (*cp != '\0' && isspace((int)*cp)) \
|
|
||||||
cp++; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define GETOPTINTOPT \
|
|
||||||
do { \
|
|
||||||
if (*++cp == '\0' && argc > 1 && atoi(argv[1]) > 0) \
|
|
||||||
{ \
|
|
||||||
argc--, argv++; \
|
|
||||||
cp = argv[0]; \
|
|
||||||
} \
|
|
||||||
while (*cp != '\0' && isspace((int)*cp)) \
|
|
||||||
cp++; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#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)
|
|
||||||
|
|
Loading…
Reference in New Issue