Compare commits

...

3 Commits

  1. 19
      LICENCE
  2. 16
      Makefile
  3. 2
      descriptor.c
  4. 32
      descriptor.h
  5. 9
      epg.c
  6. 38
      epg.h
  7. 193
      epgsql.c
  8. 11
      epgsql.h
  9. 16
      huffman.c
  10. 351
      main.c
  11. 6
      util.h

19
LICENCE

@ -0,0 +1,19 @@
Copyright 2019 af123
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

16
Makefile

@ -1,26 +1,30 @@
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
util.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

2
descriptor.c

@ -298,6 +298,8 @@ content_type(struct descriptor *d)
return "Education/Science/Factual";
case 0xa:
return "Leisure";
case 0xf:
return "Drama";
default:
return "Undefined";
}

32
descriptor.h

@ -10,7 +10,11 @@
#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
@ -26,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;
@ -45,8 +54,13 @@ struct descriptor {
char *text;
} d77; /* SHORT_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];
@ -54,8 +68,13 @@ 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 {
@ -78,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 */

9
epg.c

@ -177,7 +177,11 @@ parse(char *epgpath,
/* Skip this service. */
epg->offset += s->total_length - 14;
/* Skip padding bytes... */
#ifdef FOXSATFILE
while ((epg->offset % 4) != 0)
#else
while (epg->bin[epg->offset] == 'U')
#endif
epg->offset++;
continue;
}
@ -332,12 +336,15 @@ parse(char *epgpath,
if (dslist[i])
free_descriptor(dslist[i]);
}
/* Skip CRC */
epg->offset += 4;
/* Skip padding bytes... */
#ifdef FOXSATFILE
while ((epg->offset % 4) != 0)
#else
while (epg->bin[epg->offset] == 'U')
#endif
epg->offset++;
}

38
epg.h

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

193
epgsql.c

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

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

16
huffman.c

@ -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.h 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;

351
main.c

@ -15,16 +15,22 @@
#include <sys/stat.h>
#include <time.h>
#include "lint.h"
#include <sqlite3.h>
#include "epgsql.h"
#include "sys/stat.h"
#include <stdlib.h>
int debug = 0;
const char *version = "1.0.2";
const char *version = "1.8";
unsigned long sysopts = 0;
unsigned long filterflags = 0;
int
syntax()
{
fprintf(stderr, "Humax EPG Tool v%s, by af123, 2011.\n\n", version);
fprintf(stderr, "Humax Foxsat EPG Tool v%s, by adrianf36, 2011-2016, MofTot 2018-20.\n", version);
fprintf(stderr, "based on the Humax (T2) EPG Tool from af123 v1.0.2, 2011.\n\n");
fprintf(stderr,
"Syntax: epg [options] [filters] <command>...\n\n");
fprintf(stderr,
@ -51,6 +57,11 @@ syntax()
" Commands:\n"
" dump Show a parsed summary of the EPG.\n"
" dumpraw Show raw data from the EPG.\n"
" dumpsql Process the EPG file into a Sqlite Database\n"
" dumpsqlcont As 'dumpsql' but run continuously\n"
" Check for updated data every hour and process if necessary\n"
);
fprintf(stderr,
" now Show what is currently on.\n"
" parse Parse the EPG, no output.\n"
" search <text> Search programme names for text.\n"
@ -62,7 +73,85 @@ syntax()
}
#define DECOMPRESS(str, len) \
if (*(str) == 0x1f) uncompress_epg(&(str), &(len))
if (str && *(str) == 0x1f) uncompress_epg(&(str), &(len))
unsigned int NeedToProcess (char * epgFile)
{
struct stat epgstat;
unsigned int FileTS;
unsigned int DBTS;
FILE * fp;
/* Get the timestamp of the epg file to be processed */
if ((fp = fopen(epgFile, "r"))) {
if (!stat(epgFile, &epgstat))
{
FileTS = (unsigned int) (epgstat.st_mtime);
} else {
fprintf(stderr, "Error getting epg file modified date\n");
return 0;
}
} else {
fprintf(stderr, "Input file (%s) does not exist!\n", epgFile);
return 0;
}
/* Get the timestamp of the last file processed from the DB */
GetFileTimestamp(&DBTS);
/*
printf("File Timestamp : %i\n", FileTS);
printf("DB Timestamp : %i\n", DBTS);
*/
if (FileTS==DBTS)
return 0;
else
return FileTS;
}
void SwapEPGFiles()
{
/*
Having built the new EPG file as epgnew.db delete the old one
and replace it with the new one. Handle the case where the old
one can't be deleted because it's being accessed
First thing make sure that the size of the new file looks sensible.
Expect this to be > 10MB ..... usually it's about 12MB
*/
struct stat epgstat;
off_t fsize;
FILE * fp;
if ((fp = fopen("/opt/epg/epgnew.db", "r"))) {
if (!stat("/opt/epg/epgnew.db", &epgstat))
{
fsize = epgstat.st_size;
if (fsize > (10 * 1024 * 1024)) {
while (remove("/opt/epg/epg.db") == -1)
{
sleep(5);
}
while (rename("/opt/epg/epgnew.db", "/opt/epg/epg.db") != 0)
{
sleep(5);
}
} else {
/* epgnew.db is smaller than we expected and is probably incomplete.
Delete it and output a warning.
*/
fprintf(stderr, "Error. epgnew.db file size too small. Probably corrupt.\n");
remove("/opt/epg/epgnew.db");
}
} else {
fprintf(stderr, "Error getting epgnew.db file size\n");
}
} else {
fprintf(stderr, "Can't open epgnew.db\n");
}
}
void
pass(struct epg *epg __attribute__((unused)),
@ -99,6 +188,209 @@ dumpraw(struct epg *epg __attribute__((unused)),
/* Strings should all be safe now the huffman module is in place... */
#define safeprintf printf
void EscapeChars(char ** InString, unsigned int *Len)
{
/* Escape String for inserting into SQLite */
/* Replace single quote ' with two single quotes '' */
char * new;
unsigned int i,j;
int charcount=0;
char * originalstring;
originalstring=*InString;
if (strchr(*InString, '\'')!=NULL) {
/* at least one ' character - process string */
/* count them so we know how much space to allocate */
for (i=0; i<*Len; i++) {
if (originalstring[i]==0x27) {
charcount++;
}
}
new = (char *) malloc(sizeof(char) * (*Len + charcount + 1));
j=0;
for (i=0; i<*Len; i++) {
new[j++]=originalstring[i];
if (originalstring[i]==0x27)
new[j++]=0x27;
}
new[j]='\0';
free(*InString);
*InString = new;
*Len = strlen(new);
}
}
void
dumpsql(struct epg *epg __attribute__((unused)),
struct section *s, struct data *d, struct descriptor **ds,
void *var)
{
time_t tm;
char SQLStatement[5000];
sqlite3 * db = (sqlite3 *)var;
int rc;
tm = mjd(d->start_date, d->start_hour, d->start_min, d->start_sec);
if (ds[PARSER_SHORT_EVENT])
{
struct descriptor *d77 = ds[PARSER_SHORT_EVENT];
DECOMPRESS(d77->content.d77.name, d77->content.d77.namelen);
DECOMPRESS(d77->content.d77.text, d77->content.d77.textlen);
EscapeChars(&d77->content.d77.name, &d77->content.d77.namelen);
EscapeChars(&d77->content.d77.text, &d77->content.d77.textlen);
}
if (ds[PARSER_USER_DEFINED])
{
struct descriptor *d = ds[PARSER_USER_DEFINED];
DECOMPRESS(d->content.d137.warning, d->content.d137.warninglen);
EscapeChars(&d->content.d137.warning, &d->content.d137.warninglen);
}
/* service_id, event_id, start, duration, encrypted, name, text
* warning, content code, content type,
* event CRID, series CRID, rec CRID
*/
sprintf(SQLStatement,"insert into epg (serviceid, eventid, starttime, duration, encrypted, name,"\
"descr, warning, contentcode, contenttype, ECRID, SCRID, RCRID) values (");
sprintf(SQLStatement, "%s%d,%d,%ld,%d,%d,", SQLStatement,
s->service_id, d->event_id, tm,
d->dur_hour * 3600 + d->dur_min * 60 + d->dur_sec,
d->u1.u.free_CA_mode);
if (ds[PARSER_SHORT_EVENT])
{
struct descriptor *d77 = ds[PARSER_SHORT_EVENT];
sprintf(SQLStatement,"%s'%.*s',", SQLStatement, d77->content.d77.namelen, d77->content.d77.name);
sprintf(SQLStatement,"%s'%.*s',", SQLStatement, d77->content.d77.textlen, d77->content.d77.text);
}
else
sprintf(SQLStatement,"%s'','',",SQLStatement);
if (ds[PARSER_USER_DEFINED])
{
struct descriptor *d137 = ds[PARSER_USER_DEFINED];
EscapeChars(&d137->content.d137.warning, &d137->content.d137.warninglen);
sprintf(SQLStatement,"%s'%.*s',", SQLStatement, d137->content.d137.warninglen, d137->content.d137.warning);
}
else
sprintf(SQLStatement,"%s'',",SQLStatement);
if (ds[PARSER_CONTENT])
{
sprintf(SQLStatement,"%s%d,", SQLStatement, ds[PARSER_CONTENT]->content.d84.level1);
sprintf(SQLStatement,"%s'%s',", SQLStatement, content_type(ds[PARSER_CONTENT]));
}
else
sprintf(SQLStatement,"%s0,'',",SQLStatement);
if (ds[PARSER_CRID_EVENT])
{
struct descriptor *d = ds[PARSER_CRID_EVENT];
EscapeChars(&d->content.d118.crids[0].crid, &d->content.d118.crids[0].cridlen);
sprintf(SQLStatement,"%s'%.*s',", SQLStatement, d->content.d118.crids[0].cridlen,
d->content.d118.crids[0].crid);
}
else
sprintf(SQLStatement,"%s'',",SQLStatement);
if (ds[PARSER_CRID_SERIES])
{
struct descriptor *d = ds[PARSER_CRID_SERIES];
EscapeChars(&d->content.d118.crids[0].crid, &d->content.d118.crids[0].cridlen);
sprintf(SQLStatement,"%s'%.*s',", SQLStatement, d->content.d118.crids[0].cridlen,
d->content.d118.crids[0].crid);
}
else
sprintf(SQLStatement,"%s'',",SQLStatement);
if (ds[PARSER_CRID_REC])
{
struct descriptor *d = ds[PARSER_CRID_REC];
EscapeChars(&d->content.d118.crids[0].crid, &d->content.d118.crids[0].cridlen);
sprintf(SQLStatement,"%s'%.*s'", SQLStatement, d->content.d118.crids[0].cridlen,
d->content.d118.crids[0].crid);
}
else
sprintf(SQLStatement,"%s''",SQLStatement);
sprintf(SQLStatement,"%s)",SQLStatement);
rc = ExecSQLStatement(SQLStatement, db);
return;
}
void dosqldump(char * epgpath,struct epgfilter *filter, int Continuous)
{
sqlite3 * db;
int rc;
unsigned int FileTS;
char SQL [500] = {0};
if (Continuous==1) {
while (1) {
FileTS = NeedToProcess(epgpath);
if (FileTS !=0) {
/* Delete any old epgnew SQLite files before trying to open a new one */
/* Don't worry about error handling - just need to make sure they're gone! */
remove("/opt/epg/epgnew.db");
remove("/opt/epg/epgnew.db-journal");
rc = OpenCreateDB("/opt/epg/epgnew.db", &db);
rc = ExecSQLStatement("pragma journal_mode = off;", db);
rc = ExecSQLStatement("pragma synchronous = off;", db);
InitDB("/opt/epg/epgDBinit.sql", db);
rc = ExecSQLStatement("BEGIN;", db);
parse(epgpath, dumpsql, (void *)db, filter);
rc = ExecSQLStatement("COMMIT;", db);
copy_freesat_to_non_freesat(db);
sprintf(SQL, "replace into epgtimestamp (lastfileprocessed) values (%i);", FileTS);
rc = ExecSQLStatement("Delete from epgtimestamp;", db);
rc = ExecSQLStatement(SQL, db);
if (db != NULL) CloseDB(db);
SwapEPGFiles();
}
sleep(3600);
}
} else {
FileTS = NeedToProcess(epgpath);
if (FileTS != 0) {
/* Delete any old epgnew SQLite files before trying to open a new one */
/* Don't worry about error handling - just need to make sure they're gone! */
remove("/opt/epg/epgnew.db");
remove("/opt/epg/epgnew.db-journal");
rc = OpenCreateDB("/opt/epg/epgnew.db", &db);
InitDB("/opt/epg/epgDBinit.sql", db);
rc = ExecSQLStatement("BEGIN;", db);
parse(epgpath, dumpsql, (void *)db, filter);
rc = ExecSQLStatement("COMMIT;", db);
copy_freesat_to_non_freesat(db);
sprintf(SQL, "replace into epgtimestamp (lastfileprocessed) values (%i);", FileTS);
rc = ExecSQLStatement("Delete from epgtimestamp;", db);
rc = ExecSQLStatement(SQL, db);
if (db != NULL) CloseDB(db);
SwapEPGFiles();
}
}
}
void
dump(struct epg *epg __attribute__((unused)),
struct section *s, struct data *d, struct descriptor **ds,
@ -127,7 +419,7 @@ dump(struct epg *epg __attribute__((unused)),
* event CRID, series CRID, rec CRID
*/
printf("%d\t%d\t%ld\t%d\t%d\t",
s->service_id, d->event_id, tm,
s->service_id, d->event_id, tm,
d->dur_hour * 3600 + d->dur_min * 60 + d->dur_sec,
d->u1.u.free_CA_mode);
if (ds[PARSER_SHORT_EVENT])
@ -196,7 +488,7 @@ dump(struct epg *epg __attribute__((unused)),
if (sysopts & SYSOPT_BRIEF)
{
safeprintf("%d/%d: %s+%d\n",
s->service_id, d->event_id, ctime_nl(&tm),
s->service_id, d->event_id, ctime_nl(&tm),
d->dur_hour * 3600 + d->dur_min * 60 + d->dur_sec);
if (ds[PARSER_SHORT_EVENT])
{
@ -280,6 +572,47 @@ dump(struct epg *epg __attribute__((unused)),
}
}
int
copy_freesat_to_non_freesat(sqlite3 * db)
{
int rc;
ExecSQLStatement(
"attach database '/opt/webif/plugin/epg/epgsettings.db' as epgsettings",
db
);
ExecSQLStatement("BEGIN;", db);
rc = ExecSQLStatementRowCount(
"insert into epg "
"select epgmappings.nonfreesatserviceid, "
"eventid, "
"starttime, "
"duration, "
"encrypted, "
"name, "
"descr, "
"warning, "
"contentcode, "
"contenttype, "
"ECRID, "
"SCRID, "
"RCRID "
"from epgsettings.epgmappings join epg on epg.serviceid = epgsettings.epgmappings.freesatserviceid "
"except "
"select epg.* "
"from epgsettings.epgmappings join epg on epg.serviceid = epgsettings.epgmappings.freesatserviceid",
db
);
ExecSQLStatement("COMMIT;", db);
printf("%d EPG event(s) copied from Freesat to non-Freesat\n", rc);
return rc;
}
void
search(struct epg *epg __attribute__((unused)),
struct section *s, struct data *d, struct descriptor **ds,
@ -453,6 +786,8 @@ nextopt:
parse(epgpath, pass, NULL, filter);
else if (!strcmp(argv[0], "dumpraw"))
parse(epgpath, dumpraw, NULL, filter);
else if (!strcmp(argv[0], "dumpsql"))
dosqldump(epgpath, filter, 0);
else if (!strcmp(argv[0], "now"))
{
time_t tm;
@ -465,9 +800,13 @@ nextopt:
parse(epgpath, search, (void *)argv[1], filter);
else if (!strcmp(argv[0], "searchall") && argc > 1)
parse(epgpath, searchall, (void *)argv[1], filter);
else if (!strcmp(argv[0], "dumpsqlcont"))
{
dosqldump(epgpath, filter, 1);
}
else
syntax();
return 0;
}

6
util.h

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

Loading…
Cancel
Save