epgrec一式改修
予てより/var/log/messagesに時々現れていた
epgdump[5897]: segfault at 7fff3b687000 ip 0000000000403c55 sp 00007fff3b680cb0 error 4 in epgdump[400000+9000]
の頻度が高くなってきた気がした。
結果的には2時間間隔で実行する番組表の取得に失敗しているわけだが、何回かに1回でもきちんと取得できていれば大筋で問題無い仕組みなのでスルーしていたのだが、epgrec プロジェクト - SourceForge.JPでは特にアップデートされた形跡は無いものの、いろいろと有志が改修を試みているようなので、ひとつまじめに取り組んでみた。
yano@GT110b:~/software/tv$ diff -bc epgdumpr2_20111001/ epgdumpr2/
diff -bc epgdumpr2_20111001/Makefile epgdumpr2/Makefile
*** epgdumpr2_20111001/Makefile 2009-03-15 21:33:35.000000000 +0900
--- epgdumpr2/Makefile 2013-05-17 12:00:24.366854210 +0900
***************
*** 1,10 ****
TARGETS = epgdump
OBJ_TARGETS = epgdump.o aribstr.o eit.o ts.o util.o sdt.o
HEDDERDEPEND = eit.h sdt.h aribstr.h ts.h util.h
LANG=C
CC = gcc
! CFLAGS = -std=c99 -O2 -Wall -g
#LDFLAGS = -pthread
LIBS =
--- 1,12 ----
+ PREFIX = /usr/local
TARGETS = epgdump
OBJ_TARGETS = epgdump.o aribstr.o eit.o ts.o util.o sdt.o
HEDDERDEPEND = eit.h sdt.h aribstr.h ts.h util.h
LANG=C
CC = gcc
! #CFLAGS = -std=c99 -O2 -Wall -g
! CFLAGS = -std=c99 -O2 -Wall -g -Werror -Wno-return-type
#LDFLAGS = -pthread
LIBS =
***************
*** 21,23 ****
--- 23,28 ----
clean:
rm -f core ${TARGETS} *.o
+
+ install:
+ install -m 755 ${TARGETS} ${PREFIX}/bin
diff -bc epgdumpr2_20111001/aribstr.c epgdumpr2/aribstr.c
*** epgdumpr2_20111001/aribstr.c 2009-11-18 12:35:20.000000000 +0900
--- epgdumpr2/aribstr.c 2013-05-17 11:27:45.868259545 +0900
***************
*** 318,324 ****
fptr = code;
tptr = xcode;
! iconv(cd, &fptr, &inbyte, &tptr, &outbyte);
iconv_close(cd);
--- 318,324 ----
fptr = code;
tptr = xcode;
! iconv(cd, (char **)&fptr, &inbyte, &tptr, &outbyte);
iconv_close(cd);
***************
*** 622,644 ****
void LockingShiftGL(const BYTE byIndexG)
{
// LSx
! m_pLockingGL = &m_CodeG[byIndexG];
}
void LockingShiftGR(const BYTE byIndexG)
{
// LSxR
! m_pLockingGR = &m_CodeG[byIndexG];
}
void SingleShiftGL(const BYTE byIndexG)
{
// SSx
! m_pSingleGL = &m_CodeG[byIndexG];
}
! const bool DesignationGSET(const BYTE byIndexG, const BYTE byCode)
{
// Gのグラフィックセットを割り当てる
switch(byCode){
case 0x42U : m_CodeG[byIndexG] = CODE_KANJI; return true; // Kanji
--- 622,646 ----
void LockingShiftGL(const BYTE byIndexG)
{
// LSx
! m_pLockingGL = &m_CodeG[(int)byIndexG];
}
void LockingShiftGR(const BYTE byIndexG)
{
// LSxR
! m_pLockingGR = &m_CodeG[(int)byIndexG];
}
void SingleShiftGL(const BYTE byIndexG)
{
// SSx
! m_pSingleGL = &m_CodeG[(int)byIndexG];
}
! const bool DesignationGSET(const BYTE byIndexG_arg, const BYTE byCode)
{
+ int byIndexG = (int)byIndexG_arg;
+
// Gのグラフィックセットを割り当てる
switch(byCode){
case 0x42U : m_CodeG[byIndexG] = CODE_KANJI; return true; // Kanji
***************
*** 660,667 ****
}
}
! const bool DesignationDRCS(const BYTE byIndexG, const BYTE byCode)
{
// DRCSのグラフィックセットを割り当てる
switch(byCode){
case 0x40U : m_CodeG[byIndexG] = CODE_UNKNOWN; return true; // DRCS-0
--- 662,671 ----
}
}
! const bool DesignationDRCS(const BYTE byIndexG_arg, const BYTE byCode)
{
+ int byIndexG = (int)byIndexG_arg;
+
// DRCSのグラフィックセットを割り当てる
switch(byCode){
case 0x40U : m_CodeG[byIndexG] = CODE_UNKNOWN; return true; // DRCS-0
diff -bc epgdumpr2_20111001/eit.h epgdumpr2/eit.h
*** epgdumpr2_20111001/eit.h 2009-11-18 12:23:01.000000000 +0900
--- epgdumpr2/eit.h 2013-05-17 11:27:45.868259545 +0900
***************
*** 28,34 ****
typedef struct _EITbody {
int event_id;
char start_time[5];
! char duration[3];
int running_status;
int free_CA_mode;
int descriptors_loop_length;
--- 28,34 ----
typedef struct _EITbody {
int event_id;
char start_time[5];
! unsigned char duration[3];
int running_status;
int free_CA_mode;
int descriptors_loop_length;
diff -bc epgdumpr2_20111001/ts.c epgdumpr2/ts.c
*** epgdumpr2_20111001/ts.c 2010-02-27 16:45:15.000000000 +0900
--- epgdumpr2/ts.c 2013-05-21 13:30:28.732126582 +0900
***************
*** 40,52 ****
/* 戻すべき残りがあるか? */
if(ridx >= 0 && secs[ridx].cont) {
/* バッファチェック */
if((secs[ridx].cur.payload[secs[ridx].curlen] & 0xFF) == 0xFF) {
secs[ridx].cont = 0;
secs[ridx].seclen = 0;
secs[ridx].setlen = 0;
secs[ridx].curlen = 0;
! } else {
len = secs[ridx].cur.payloadlen - secs[ridx].curlen;
/* 全部設定済みチェック */
if(len == 0) {
--- 40,56 ----
/* 戻すべき残りがあるか? */
if(ridx >= 0 && secs[ridx].cont) {
+ /*
+ printf("secs[%d].cur.cont=%d, secs[%d].cur.payloadlen=%d, secs[%d].curlen=%d, secs[%d].seclen=%d, len=%d\n",
+ ridx, secs[ridx].cur.cont, ridx, secs[ridx].cur.payloadlen, ridx, secs[ridx].curlen, ridx, secs[ridx].seclen, len);
+ */
/* バッファチェック */
if((secs[ridx].cur.payload[secs[ridx].curlen] & 0xFF) == 0xFF) {
secs[ridx].cont = 0;
secs[ridx].seclen = 0;
secs[ridx].setlen = 0;
secs[ridx].curlen = 0;
! } else if ( secs[ridx].curlen <= secs[ridx].cur.payloadlen ){
len = secs[ridx].cur.payloadlen - secs[ridx].curlen;
/* 全部設定済みチェック */
if(len == 0) {
***************
*** 68,73 ****
--- 72,82 ----
boff = 12;
secs[ridx].seclen = getBit(&secs[ridx].cur.payload[secs[ridx].curlen], &boff, 12) + 3; // ヘッダ
+ if(secs[ridx].seclen > MAXSECLEN){
+ // セクションが MAXSECLEN より大きい時はこのセクションをスキップ
+ secs[ridx].cont = 0;
+ goto retry;
+ }
/*
if(secs[ridx].seclen == 2334) {
***************
*** 96,101 ****
--- 105,116 ----
goto retry; /* もう一回 */
}
}
+ } else {
+ /*
+ printf("secs[%d].cont=%d, secs[%d].cur.payloadlen=%d, secs[%d].curlen=%d, secs[%d].seclen=%d\n",
+ ridx, secs[ridx].cont, ridx, secs[ridx].cur.payloadlen, ridx, secs[ridx].curlen, ridx, secs[ridx].seclen);
+ */
+ secs[ridx].cont = 0;
}
}
***************
*** 203,209 ****
}
memset(pk.payload, 0xFF, sizeof(pk.payload));
! if(pk.payloadlen <= 0){
continue;
}
memcpy(pk.payload, payptr, pk.payloadlen);
--- 218,224 ----
}
memset(pk.payload, 0xFF, sizeof(pk.payload));
! if( !(0 < pk.payloadlen && pk.payloadlen <= sizeof(pk.payload)) ){
continue;
}
memcpy(pk.payload, payptr, pk.payloadlen);
***************
*** 227,232 ****
--- 242,252 ----
/* 最初 セクション長を調べる */
boff = 12;
secs[i].seclen = getBit(secs[i].cur.payload, &boff, 12) + 3; // ヘッダ;
+ if(secs[i].seclen > MAXSECLEN){
+ /* セクション長が MAXSECLEN より長いときはこのセクションをスキップ */
+ secs[i].cont = 0;
+ goto retry;
+ }
/*
if(secs[i].seclen == 2334) {
printf("aa");
***************
*** 274,280 ****
}
}
! //return NULL;
}
/* BonTest/TsStream.cppからのパクリ */
--- 294,300 ----
}
}
! return NULL;
}
/* BonTest/TsStream.cppからのパクリ */
***************
*** 311,316 ****
--- 331,342 ----
int checkcrc(SECcache *secs) {
+ /* regard a section with more than MAXSECLEN data as an error. */
+ if(secs->seclen > MAXSECLEN) {
+ fprintf(stderr, "SECcache overrun secs->seclen=%d\n", secs->seclen);
+ return 0;
+ }
+
/* セクションの終りに置かれる4バイトのCRC32は、
CRC計算の結果0になるように設定される。
値が発生した場合は、エラーなので対象外にする */
***************
*** 320,323 ****
}
return 1;
}
-
--- 346,348 ----
diff -bc epgdumpr2_20111001/util.h epgdumpr2/util.h
*** epgdumpr2_20111001/util.h 2009-03-08 16:53:42.000000000 +0900
--- epgdumpr2/util.h 2013-05-17 11:46:37.356293005 +0900
***************
*** 1,12 ****
--- 1,15 ----
#ifndef UTIL_H
#define UTILH 1
+ // try for segfault at 7fff77650000 ip 0000000000403c55 sp 00007fff7764ae30 error 4 in epgdump[400000+9000]
+ // #define MAXSECLEN (4096*4)
#define MAXSECLEN 4096
#ifdef __cplusplus
extern "C"{
#endif /* __cplusplus */
+ int strrep(char *buf, char *mae, char *ato);
int getBit(unsigned char *byte, int *pbit, int gbit);
void getStr(char *tostr, unsigned char *byte, int *pbit, int len);
int parseOTHERdesc(unsigned char *data);
しかし、この改修を行っても日テレNEWS24の番組表が空っぽのままだったので更に調べてみたところ、日テレNEWS24のチャンネルがCS24:350からCS8:349に移っていた。ついでにディズニージュニアがCS8:339でスタートしたのも思い出したので、そのへんも追加。差分は「BS新チャンネル対応公式版」のepgdumpr2_20111001.tar.gzに対する差分なので、2011年11月版のCSチャンネル対応も含む。








