Compare commits

..

4 Commits

Author SHA1 Message Date
adrianf36 b55c134eed Handle empty warning descriptors 2022-08-28 16:53:21 +01:00
MofTot b3ea751561 Copy freesat to non-freesat database 2020-04-22 14:43:58 +01:00
HummyPkg 5e468f5857 Add licence 2019-03-29 12:53:35 +00:00
adrianf36 222797837c Changes for Foxsat platform 2019-03-29 12:39:35 +00:00
15 changed files with 771 additions and 1037 deletions

2
.gitignore vendored
View File

@ -1,2 +0,0 @@
*.o
epg

View File

@ -1,43 +1,36 @@
MAKE=gmake
DEFS=
DEFS=-DFOXSATPLATFORM -DFOXSATFILE
#DEFS= -DFOXSATFILE
SRCS= descriptor.c \
epg.c \
file.c \
huffman.c \
main.c \
util.c
util.c \
epgsql.c
HDRS= descriptor.h \
epg.h \
lint.h \
util.h \
xgetopt.h
epgsql.h
OBJS= $(SRCS:.c=.o)
CC=gcc
#CC=gcc
#CC=mipsel-linux-gcc
CFLAGS=-g
CC=mips-linux-gcc
CFLAGS=-g -pthread
INCS=
LIBS=
LIBS=-lsqlite3 -ldl
#CFLAGS=-g -O3 -fno-strict-aliasing
#WARN=-pedantic -Wall -Wnested-externs -Wpointer-arith -Werror -Wno-unused
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
install: epg
strip epg
cp epg /mod/bin/epg
epg: ${OBJS}
@echo "Linking..."
@-[ -f $@ ] && mv $@ $@~ || exit 0

View File

@ -19,7 +19,7 @@ read_descriptor_header(struct epg *epg)
{
struct descriptor *d;
d = (struct descriptor *)calloc(sizeof(struct descriptor), 1);
d = (struct descriptor *)malloc(sizeof(struct descriptor));
d->loaded = 0;
if (epg->binsize - epg->offset < 2)
@ -55,16 +55,9 @@ string_to_end(struct epg *epg, struct descriptor *d, int sofar,
static char *
read_lstring(struct epg *epg, unsigned int *len)
{
unsigned int l = epg->bin[epg->offset++];
int l = epg->bin[epg->offset++];
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);
memcpy(c, epg->bin + epg->offset, l);
c[l] = '\0';
@ -93,31 +86,6 @@ read_descriptor(struct epg *epg, struct descriptor *d)
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:
memcpy(&d->content.d80, epg->bin + epg->offset, 6);
epg->offset += 6;
@ -127,37 +95,15 @@ read_descriptor(struct epg *epg, struct descriptor *d)
break;
case DS_USER_DEFINED:
{
int sofar = 0;
/* 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;
}
d->content.d137.text =
read_lstring(epg, &d->content.d137.textlen);
memcpy(d->content.d137.lang, epg->bin + epg->offset, 3);
epg->offset += 3;
sofar += 3;
d->content.d137.warning = string_to_end(epg, d, sofar,
d->content.d137.warning = string_to_end(epg, d,
4 + d->content.d137.textlen,
&d->content.d137.warninglen);
break;
}
case DS_LINKAGE:
memcpy(&d->content.d74, epg->bin + epg->offset,
@ -270,17 +216,14 @@ free_descriptor(struct descriptor *d)
free(d->content.d77.text);
break;
case DS_EXTENDED_EVENT:
if (d->content.d78.text)
free(d->content.d78.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;
@ -325,6 +268,7 @@ descriptor_name(struct descriptor *d)
case DS_CONTENT_IDENTIFIER: return "content id";
case DS_FTA_CONTENT_MGMT: return "content mgmt";
case DS_USER_DEFINED: return "user defined";
default: return "Unknown";
}
return "Unknown";
}
@ -356,8 +300,10 @@ content_type(struct descriptor *d)
return "Leisure";
case 0xf:
return "Drama";
default:
return "Undefined";
}
return "Undefined";
return "Unknown";
}
void
@ -381,13 +327,6 @@ dump_descriptor(struct descriptor *d, int content)
DUMPHEX(d, content.d77.text, d->content.d77.textlen);
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:
DUMPINT(d, content.d80.stream_content);
DUMPINT(d, content.d80.reserved);
@ -399,9 +338,9 @@ dump_descriptor(struct descriptor *d, int content)
break;
case DS_USER_DEFINED:
DUMPINT(d, content.d137.guidance_type);
DUMPINT(d, content.d137.guidance_mode);
DUMPINT(d, content.d137.textlen);
DUMPNSTR(d, content.d137.lang, 3);
DUMPHEX(d, content.d137.text, d->content.d137.textlen);
DUMPHEX(d, content.d137.warning, d->content.d137.warninglen);
break;

View File

@ -3,15 +3,18 @@
* by af123, 2011
*/
#define DS_LINKAGE 74 /* 0x4a */
#define DS_SHORT_EVENT 77 /* 0x4d */
#define DS_EXTENDED_EVENT 78 /* 0x4e */
#define DS_COMPONENT 80 /* 0x50 */
#define DS_CONTENT 84 /* 0x54 */
#define DS_PRIVATE_DATA_SPECIFIER 95 /* 0x5f */
#define DS_CONTENT_IDENTIFIER 118 /* 0x76 */
#define DS_FTA_CONTENT_MGMT 126 /* 0x7e */
#define DS_USER_DEFINED 137 /* 0x89 */
#define DS_LINKAGE 74
#define DS_SHORT_EVENT 77
#define DS_COMPONENT 80
#define DS_CONTENT 84
#define DS_PRIVATE_DATA_SPECIFIER 95
#define DS_CONTENT_IDENTIFIER 118
#define DS_FTA_CONTENT_MGMT 126
#ifdef FOXSATPLATFORM
#define DS_USER_DEFINED 218
#else
#define DS_USER_DEFINED 137
#endif
#define PARSER_SHORT_EVENT 0
#define PARSER_USER_DEFINED 1
@ -19,9 +22,7 @@
#define PARSER_CRID_EVENT 3
#define PARSER_CRID_SERIES 4
#define PARSER_CRID_REC 5
#define PARSER_EXTENDED_EVENT 6
#define PARSER_FTA_CONTENT_MGMT 7
#define PARSER_MAX 8
#define PARSER_MAX 6
#define CRIDT_EVENT '1'
#define CRIDT_SERIES '2'
@ -29,8 +30,13 @@
#pragma pack(1)
struct crid {
#ifdef FOXSATPLATFORM
unsigned int type:6;
unsigned int location:2;
#else
unsigned int location:2;
unsigned int type:6;
#endif
unsigned int cridlen;
char *crid;
unsigned int ref:16;
@ -48,14 +54,13 @@ struct descriptor {
char *text;
} d77; /* SHORT_EVENT */
struct {
char lang[3];
unsigned int items;
unsigned int textlen;
char *text;
} d78; /* EXTENDED_EVENT */
struct {
#ifdef FOXSATPLATFORM
unsigned int reserved:4;
unsigned int stream_content:4;
#else
unsigned int stream_content:4;
unsigned int reserved:4;
#endif
unsigned int type:8;
unsigned int tag:8;
char lang[3];
@ -63,17 +68,22 @@ struct descriptor {
unsigned int textlen;
} d80; /* COMPONENT */
struct {
#ifdef FOXSATPLATFORM
unsigned int level1:4;
unsigned int level2:4;
#else
unsigned int level2:4;
unsigned int level1:4;
#endif
unsigned int user:8;
} d84; /* CONTENT */
struct {
unsigned int guidance_type;
unsigned int guidance_mode;
unsigned int textlen;
char *text;
char lang[3];
char *warning;
unsigned int warninglen;
} d137; /* USER_DEFINED - content warnings */
} d137; /* USER_DEFINED - content warnings? */
struct {
unsigned int no_revocation:1;
unsigned int control_remote_access:2;
@ -87,16 +97,29 @@ struct descriptor {
unsigned int linkage_type:8;
union {
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 reserved:3;
unsigned int handover_type:4;
unsigned int id:16;
#endif
} l8;
struct {
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 simulcast:1;
unsigned int listed:1;
#endif
} ld;
} l;
} d74; /* DS_LINKAGE */

149
epg.c
View File

@ -23,7 +23,7 @@ read_section(struct epg *epg)
return NULL;
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");
hexdump(epg->bin + epg->offset, 64, 0);
@ -111,28 +111,6 @@ dump_data(struct data *d)
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
check_filter_range(struct epgfilter *f, enum epgfiltertype type,
unsigned long idl, unsigned long idh)
@ -142,14 +120,7 @@ check_filter_range(struct epgfilter *f, enum epgfiltertype type,
for (; f; f = f->next)
{
if (f->type != type)
continue;
if (f->match == FT_RANGE)
{
if (idl < f->num || idl > f->num2)
return 0;
}
else if (f->num < idl || f->num > idh)
if (f->type == type && (f->num < idl || f->num > idh))
return 0;
}
return 1;
@ -178,7 +149,7 @@ check_filter(struct epgfilter *f, enum epgfiltertype type,
return 1;
}
int
void
parse(char *epgpath,
void (*callback)(struct epg *, struct section *, struct data *,
struct descriptor **, void *), void *val, struct epgfilter *filter)
@ -188,7 +159,7 @@ parse(char *epgpath,
int i;
if (!(epg = open_file(epgpath)))
return 0;
return;
while (epg->offset < epg->binsize)
{
@ -206,8 +177,11 @@ parse(char *epgpath,
/* Skip this service. */
epg->offset += s->total_length - 14;
/* Skip padding bytes... */
while (epg->offset < epg->binsize &&
epg->bin[epg->offset] == 'U')
#ifdef FOXSATFILE
while ((epg->offset % 4) != 0)
#else
while (epg->bin[epg->offset] == 'U')
#endif
epg->offset++;
continue;
}
@ -233,10 +207,10 @@ parse(char *epgpath,
continue;
}
if ((filterflags &
(FILTER_TIMESTAMP | FILTER_TIMERANGE)))
if ((filterflags & FILTER_TIMESTAMP))
{
time_t tm, dur;
time_t tm;
int dur;
tm = mjd(d->start_date, d->start_hour,
d->start_min, d->start_sec);
@ -244,29 +218,12 @@ parse(char *epgpath,
dur = d->dur_hour * 3600 + d->dur_min * 60 +
d->dur_sec;
if ((filterflags & FILTER_TIMESTAMP))
if (!check_filter_range(filter,
FILTER_TIMESTAMP, tm, tm + dur))
{
if (!check_filter_range(filter,
FILTER_TIMESTAMP,
(unsigned long) tm,
(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;
}
/* Skip this event. */
epg->offset = dend;
continue;
}
}
@ -291,14 +248,6 @@ parse(char *epgpath,
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)
{
case DS_SHORT_EVENT:
@ -308,13 +257,6 @@ parse(char *epgpath,
dslist[PARSER_SHORT_EVENT] = ds;
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:
if (!(ds = read_descriptor_header(epg)))
break;
@ -347,14 +289,12 @@ parse(char *epgpath,
dslist[PARSER_CONTENT] = ds;
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:
read_descriptor(epg, ds);
@ -364,39 +304,11 @@ parse(char *epgpath,
*/
default:
if (debug > 2)
printf("! Unhandled.\n");
epg->offset += dslen + 2;
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 (
(
!(filterflags & FILTER_CRID) ||
@ -416,13 +328,6 @@ parse(char *epgpath,
check_filter(filter, FILTER_CONTENT,
dslist[PARSER_CONTENT]->content.d84.level1,
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);
@ -431,19 +336,19 @@ parse(char *epgpath,
if (dslist[i])
free_descriptor(dslist[i]);
}
/* Skip CRC */
epg->offset += 4;
/* Skip padding bytes... */
while (epg->offset < epg->binsize &&
epg->bin[epg->offset] == 'U')
#ifdef FOXSATFILE
while ((epg->offset % 4) != 0)
#else
while (epg->bin[epg->offset] == 'U')
#endif
epg->offset++;
}
close_file(epg);
return 1;
}
void

42
epg.h
View File

@ -5,7 +5,11 @@
#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 {
char fname[MAXPATHLEN + 1];
@ -15,26 +19,50 @@ struct epg {
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)
struct section {
#ifdef FOXSATFILE
char magic[6];
#else
char magic[14];
#endif
unsigned int total_length:16;
#ifndef FOXSATFILE
unsigned int magic2:32;
#endif
unsigned int table_id:8;
union {
struct {
#ifdef FOXSATPLATFORM
unsigned int syntax_indicator:1;
unsigned int reserved:3;
unsigned int length:12;
#else
unsigned int length:12;
unsigned int reserved:3;
unsigned int syntax_indicator:1;
#endif
} u;
unsigned int comp:16;
} u1;
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 version_number:5;
unsigned int reserved2:2;
#endif
unsigned int section_number:8;
unsigned int last_section_number:8;
unsigned int transport_stream_id:16;
@ -55,9 +83,15 @@ struct data {
unsigned int dur_sec:8;
union {
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 free_CA_mode:1;
unsigned int running_status:3;
#endif
} u;
unsigned int comp:16;
} u1;
@ -70,9 +104,7 @@ enum epgfiltertype {
FILTER_TIMESTAMP = 0x8,
FILTER_CRID = 0x10,
FILTER_SCRID = 0x20,
FILTER_CONTENT = 0x40,
FILTER_TIMERANGE = 0x80,
FILTER_GUIDETYPE = 0x100
FILTER_CONTENT = 0x40
};
enum matchtype { FT_EQUAL, FT_RANGE, FT_GREATER, FT_LESS };

193
epgsql.c Normal file
View File

@ -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);
}

11
epgsql.h Normal file
View File

@ -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
View File

@ -23,27 +23,7 @@ struct epg *
open_file(char *filename)
{
struct epg *epg;
struct stat st, st2;
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;
}
struct stat st;
if (!(epg = malloc(sizeof(struct epg))))
{
@ -51,7 +31,18 @@ open_file(char *filename)
return NULL;
}
if (debug)
printf("Opening file '%s'\n", filename);
strcpy(epg->fname, filename);
if (stat(epg->fname, &st) == -1)
{
perror(epg->fname);
free(epg);
return NULL;
}
epg->binsize = st.st_size;
if (debug)

View File

@ -1,14 +1,6 @@
/*
* Humax EPG Tool
* by af123, 2011 - 2018
*
* 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
* by af123, 2011
*/
#include <stdio.h>
@ -22,6 +14,12 @@
#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 {
unsigned int value;
short bits;
@ -5746,7 +5744,7 @@ static unsigned fsat_index_2[] = {
#define ESCAPE '\1'
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)
{
struct fsattab *fsat_table;

7
lint.h
View File

@ -20,10 +20,9 @@ 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 *);
time_t mjd(unsigned int, unsigned int, unsigned int, unsigned int);
time_t mjd(uint16_t, int, int, int);
void safeprintf(char *, ...);
void uncompress_epg(char **, unsigned int *);
void iso6937_convert(char **, unsigned int *);
struct epg *open_file(char *);
void close_file(struct epg *);
@ -36,7 +35,7 @@ void dump_section(struct section *);
struct data *read_data(struct epg *);
void dump_data(struct data *);
int parse(char *,
void parse(char *,
void (*)(struct epg *, struct section *, struct data *,
struct descriptor **, void *), void *, struct epgfilter *);
@ -47,7 +46,7 @@ void dump_descriptor(struct descriptor *, int);
void free_descriptor(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 *);
int is_bst(time_t);

1097
main.c

File diff suppressed because it is too large Load Diff

31
util.c
View File

@ -13,42 +13,25 @@
#include <time.h>
#include <strings.h>
#include <stdarg.h>
#include <xconv.h>
#include "lint.h"
void
uncompress_epg(char **epg, unsigned int *epglen)
{
char *newepg;
char *new;
unsigned int newlen;
if ((newepg = (char *)
if ((new = (char *)
freeview_huffman_to_string((unsigned char *)(*epg),
*epglen, &newlen)))
{
free(*epg);
*epg = newepg;
*epg = new;
*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
char *
strcasestr (char *h, char *n)
@ -99,16 +82,16 @@ safeprintf(char *fmt, ...)
}
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;
struct tm *t;
tm = MJD_TO_UNIX(day);
t = gmtime(&tm);
t->tm_hour = (int) h;
t->tm_min = (int) m;
t->tm_sec = (int) s;
t->tm_hour = h;
t->tm_min = m;
t->tm_sec = s;
return mktime(t);
}

6
util.h
View File

@ -6,7 +6,11 @@
/* Works for modern dates, 1970 - 2038 */
#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))

View File

@ -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)