Made several functions threadsafe

This commit is contained in:
Klaus Schmidinger 2004-12-19 16:33:34 +01:00
parent 9a8ef2b6c2
commit 1d3495a0f0
18 changed files with 360 additions and 219 deletions

View File

@ -348,6 +348,8 @@ Rainer Zocholl <vdrcontrib@zocki.toppoint.de>
for suggesting that VDR should stop if one of the configuration files can't be for suggesting that VDR should stop if one of the configuration files can't be
read correctly at program startup read correctly at program startup
for reporting a possible race condition in generating the DVB device names for reporting a possible race condition in generating the DVB device names
for pointing out that non-threadsafe functions should be replaced with their
threadsafe versions
Oleg Assovski <assen@bitcom.msk.ru> Oleg Assovski <assen@bitcom.msk.ru>
for adding EPG scanning for another 4 days for adding EPG scanning for another 4 days

12
HISTORY
View File

@ -3209,3 +3209,15 @@ Video Disk Recorder Revision History
- Added 'channels.conf.terr' entries for Lübeck (thanks to Stefan Hußfeldt). - Added 'channels.conf.terr' entries for Lübeck (thanks to Stefan Hußfeldt).
- Fixed a race condition in starting a thread (thanks to Reinhard Nissl for - Fixed a race condition in starting a thread (thanks to Reinhard Nissl for
reporting this one). reporting this one).
- Replaced non-threadsafe library functions with their threadsafe versions (thanks
to Rainer Zocholl for pointing this out).
- Other non-threadsafe functions have been replaced by threadsafe classes that hide
the actual buffering. In particular these are:
readdir() -> cReadDir
readline() -> cReadLine
strescape() -> cStrEscape
AddDirectory() -> cAddDirectory
ctime() -> cCtime
itoa() -> cItoa
WeekDayName() -> cWeekDayName
DayDateTime() -> cDayDateTime

View File

@ -8,3 +8,7 @@ VDR Plugin 'skincurses' Revision History
2004-05-31: Version 0.0.2 2004-05-31: Version 0.0.2
- Fixed some default parameters. - Fixed some default parameters.
2004-12-26: Version 0.0.3
- Made several functions threadsafe.

View File

@ -32,3 +32,7 @@ VDR Plugin 'sky' Revision History
2004-12-12: Version 0.3.2 2004-12-12: Version 0.3.2
- Changed Apid access in cChannel. - Changed Apid access in cChannel.
2004-12-19: Version 0.3.3
- Made several functions threadsafe.

View File

@ -3,7 +3,7 @@
* *
* See the README file for copyright information and how to reach the author. * See the README file for copyright information and how to reach the author.
* *
* $Id: sky.c 1.8 2004/12/12 14:27:33 kls Exp $ * $Id: sky.c 1.9 2004/12/19 15:33:47 kls Exp $
*/ */
#include <sys/socket.h> #include <sys/socket.h>
@ -14,7 +14,7 @@
#include <vdr/plugin.h> #include <vdr/plugin.h>
#include <vdr/sources.h> #include <vdr/sources.h>
static const char *VERSION = "0.3.2"; static const char *VERSION = "0.3.3";
static const char *DESCRIPTION = "Sky Digibox interface"; static const char *DESCRIPTION = "Sky Digibox interface";
// --- cDigiboxDevice -------------------------------------------------------- // --- cDigiboxDevice --------------------------------------------------------
@ -273,7 +273,7 @@ bool cPluginSky::Initialize(void)
// Initialize any background activities the plugin shall perform. // Initialize any background activities the plugin shall perform.
const char *ConfigDir = ConfigDirectory(Name()); const char *ConfigDir = ConfigDirectory(Name());
if (ConfigDir) { if (ConfigDir) {
if (SkyChannels.Load(AddDirectory(ConfigDir, "channels.conf.sky"), true)) { if (SkyChannels.Load(*cAddDirectory(ConfigDir, "channels.conf.sky"), true)) {
new cDigiboxDevice; new cDigiboxDevice;
return true; return true;
} }

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: channels.c 1.31 2004/11/02 18:07:05 kls Exp $ * $Id: channels.c 1.32 2004/12/19 11:24:51 kls Exp $
*/ */
#include "channels.h" #include "channels.h"
@ -705,7 +705,8 @@ bool cChannel::Parse(const char *s, bool AllowNonUniqueID)
p = apidbuf; p = apidbuf;
char *q; char *q;
int NumApids = 0; int NumApids = 0;
while ((q = strtok(p, ",")) != NULL) { char *strtok_next;
while ((q = strtok_r(p, ",", &strtok_next)) != NULL) {
if (NumApids < MAXAPIDS) { if (NumApids < MAXAPIDS) {
char *l = strchr(q, '='); char *l = strchr(q, '=');
if (l) { if (l) {
@ -725,7 +726,8 @@ bool cChannel::Parse(const char *s, bool AllowNonUniqueID)
char *p = dpidbuf; char *p = dpidbuf;
char *q; char *q;
int NumDpids = 0; int NumDpids = 0;
while ((q = strtok(p, ",")) != NULL) { char *strtok_next;
while ((q = strtok_r(p, ",", &strtok_next)) != NULL) {
if (NumDpids < MAXAPIDS) { if (NumDpids < MAXAPIDS) {
char *l = strchr(q, '='); char *l = strchr(q, '=');
if (l) { if (l) {
@ -747,7 +749,8 @@ bool cChannel::Parse(const char *s, bool AllowNonUniqueID)
char *p = caidbuf; char *p = caidbuf;
char *q; char *q;
int NumCaIds = 0; int NumCaIds = 0;
while ((q = strtok(p, ",")) != NULL) { char *strtok_next;
while ((q = strtok_r(p, ",", &strtok_next)) != NULL) {
if (NumCaIds < MAXCAIDS) { if (NumCaIds < MAXCAIDS) {
caids[NumCaIds++] = strtol(q, NULL, 16) & 0xFFFF; caids[NumCaIds++] = strtol(q, NULL, 16) & 0xFFFF;
if (NumCaIds == 1 && caids[0] <= 0x00FF) if (NumCaIds == 1 && caids[0] <= 0x00FF)

5
keys.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: keys.c 1.5 2003/09/14 10:07:47 kls Exp $ * $Id: keys.c 1.6 2004/12/19 11:25:47 kls Exp $
*/ */
#include "keys.h" #include "keys.h"
@ -195,7 +195,8 @@ bool cKeyMacro::Parse(char *s)
{ {
int n = 0; int n = 0;
char *p; char *p;
while ((p = strtok(s, " \t")) != NULL) { char *strtok_next;
while ((p = strtok_r(s, " \t", &strtok_next)) != NULL) {
if (n < MAXKEYSINMACRO) { if (n < MAXKEYSINMACRO) {
if (*p == '@') { if (*p == '@') {
if (plugin) { if (plugin) {

5
osd.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: osd.c 1.58 2004/10/16 10:31:34 kls Exp $ * $Id: osd.c 1.59 2004/12/19 12:27:38 kls Exp $
*/ */
#include "osd.h" #include "osd.h"
@ -197,7 +197,8 @@ bool cBitmap::LoadXpm(const char *FileName)
int lines = 0; int lines = 0;
int index = 0; int index = 0;
char *s; char *s;
while ((s = readline(f)) != NULL) { cReadLine ReadLine;
while ((s = ReadLine.Read(f)) != NULL) {
s = skipspace(s); s = skipspace(s);
if (!isXpm) { if (!isXpm) {
if (strcmp(s, "/* XPM */") != 0) { if (strcmp(s, "/* XPM */") != 0) {

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: plugin.c 1.11 2004/05/22 11:25:22 kls Exp $ * $Id: plugin.c 1.12 2004/12/19 12:05:28 kls Exp $
*/ */
#include "plugin.h" #include "plugin.h"
@ -256,26 +256,23 @@ void cPluginManager::SetDirectory(const char *Directory)
void cPluginManager::AddPlugin(const char *Args) void cPluginManager::AddPlugin(const char *Args)
{ {
if (strcmp(Args, "*") == 0) { if (strcmp(Args, "*") == 0) {
DIR *d = opendir(directory); cReadDir d(directory);
if (d) { struct dirent *e;
struct dirent *e; while ((e = d.Next()) != NULL) {
while ((e = readdir(d)) != NULL) { if (strstr(e->d_name, LIBVDR_PREFIX) == e->d_name) {
if (strstr(e->d_name, LIBVDR_PREFIX) == e->d_name) { char *p = strstr(e->d_name, SO_INDICATOR);
char *p = strstr(e->d_name, SO_INDICATOR); if (p) {
if (p) { *p = 0;
*p = 0; p += strlen(SO_INDICATOR);
p += strlen(SO_INDICATOR); if (strcmp(p, VDRVERSION) == 0) {
if (strcmp(p, VDRVERSION) == 0) { char *name = e->d_name + strlen(LIBVDR_PREFIX);
char *name = e->d_name + strlen(LIBVDR_PREFIX); if (strcmp(name, "*") != 0) { // let's not get into a loop!
if (strcmp(name, "*") != 0) { // let's not get into a loop! AddPlugin(e->d_name + strlen(LIBVDR_PREFIX));
AddPlugin(e->d_name + strlen(LIBVDR_PREFIX));
}
} }
} }
} }
} }
closedir(d); }
}
return; return;
} }
char *s = strdup(skipspace(Args)); char *s = strdup(skipspace(Args));

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: recording.c 1.92 2004/11/01 14:04:47 kls Exp $ * $Id: recording.c 1.93 2004/12/19 15:44:42 kls Exp $
*/ */
#include "recording.h" #include "recording.h"
@ -157,7 +157,7 @@ cResumeFile::cResumeFile(const char *FileName)
fileName = MALLOC(char, strlen(FileName) + strlen(RESUMEFILESUFFIX) + 1); fileName = MALLOC(char, strlen(FileName) + strlen(RESUMEFILESUFFIX) + 1);
if (fileName) { if (fileName) {
strcpy(fileName, FileName); strcpy(fileName, FileName);
sprintf(fileName + strlen(fileName), RESUMEFILESUFFIX, Setup.ResumeID ? "." : "", Setup.ResumeID ? itoa(Setup.ResumeID) : ""); sprintf(fileName + strlen(fileName), RESUMEFILESUFFIX, Setup.ResumeID ? "." : "", Setup.ResumeID ? *cItoa(Setup.ResumeID) : "");
} }
else else
esyslog("ERROR: can't allocate memory for resume file name"); esyslog("ERROR: can't allocate memory for resume file name");
@ -628,47 +628,44 @@ cRecordings::cRecordings(bool Deleted)
void cRecordings::ScanVideoDir(const char *DirName) void cRecordings::ScanVideoDir(const char *DirName)
{ {
DIR *d = opendir(DirName); cReadDir d(DirName);
if (d) { struct dirent *e;
struct dirent *e; while ((e = d.Next()) != NULL) {
while ((e = readdir(d)) != NULL) { if (strcmp(e->d_name, ".") && strcmp(e->d_name, "..")) {
if (strcmp(e->d_name, ".") && strcmp(e->d_name, "..")) { char *buffer;
char *buffer; asprintf(&buffer, "%s/%s", DirName, e->d_name);
asprintf(&buffer, "%s/%s", DirName, e->d_name); struct stat st;
struct stat st; if (stat(buffer, &st) == 0) {
if (stat(buffer, &st) == 0) { if (S_ISLNK(st.st_mode)) {
if (S_ISLNK(st.st_mode)) { free(buffer);
buffer = ReadLink(buffer);
if (!buffer)
continue;
if (stat(buffer, &st) != 0) {
free(buffer); free(buffer);
buffer = ReadLink(buffer); continue;
if (!buffer)
continue;
if (stat(buffer, &st) != 0) {
free(buffer);
continue;
}
}
if (S_ISDIR(st.st_mode)) {
if (endswith(buffer, deleted ? DELEXT : RECEXT)) {
cRecording *r = new cRecording(buffer);
if (r->Name())
Add(r);
else
delete r;
}
else
ScanVideoDir(buffer);
} }
} }
free(buffer); if (S_ISDIR(st.st_mode)) {
if (endswith(buffer, deleted ? DELEXT : RECEXT)) {
cRecording *r = new cRecording(buffer);
if (r->Name())
Add(r);
else
delete r;
}
else
ScanVideoDir(buffer);
}
} }
free(buffer);
} }
closedir(d); }
}
} }
bool cRecordings::NeedsUpdate(void) bool cRecordings::NeedsUpdate(void)
{ {
return lastUpdate <= LastModifiedTime(AddDirectory(VideoDirectory, ".update")); return lastUpdate <= LastModifiedTime(*cAddDirectory(VideoDirectory, ".update"));
} }
bool cRecordings::Load(void) bool cRecordings::Load(void)
@ -750,8 +747,7 @@ bool cMark::Save(FILE *f)
bool cMarks::Load(const char *RecordingFileName) bool cMarks::Load(const char *RecordingFileName)
{ {
const char *MarksFile = AddDirectory(RecordingFileName, MARKSFILESUFFIX); if (cConfig<cMark>::Load(*cAddDirectory(RecordingFileName, MARKSFILESUFFIX))) {
if (cConfig<cMark>::Load(MarksFile)) {
Sort(); Sort();
return true; return true;
} }
@ -815,7 +811,7 @@ void cRecordingUserCommand::InvokeCommand(const char *State, const char *Recordi
{ {
if (command) { if (command) {
char *cmd; char *cmd;
asprintf(&cmd, "%s %s \"%s\"", command, State, strescape(RecordingFileName, "\"$")); asprintf(&cmd, "%s %s \"%s\"", command, State, *cStrEscape(RecordingFileName, "\"$"));
isyslog("executing '%s'", cmd); isyslog("executing '%s'", cmd);
SystemExec(cmd); SystemExec(cmd);
free(cmd); free(cmd);

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: skinclassic.c 1.7 2004/05/31 14:09:00 kls Exp $ * $Id: skinclassic.c 1.8 2004/12/19 15:46:09 kls Exp $
*/ */
#include "skinclassic.h" #include "skinclassic.h"
@ -141,8 +141,8 @@ void cSkinClassicDisplayChannel::SetMessage(eMessageType Type, const char *Text)
void cSkinClassicDisplayChannel::Flush(void) void cSkinClassicDisplayChannel::Flush(void)
{ {
if (!message) { if (!message) {
const char *date = DayDateTime(); cDayDateTime date;
osd->DrawText(osd->Width() - cFont::GetFont(fontSml)->Width(date) - 2, 0, date, Theme.Color(clrChannelDate), Theme.Color(clrBackground), cFont::GetFont(fontSml)); osd->DrawText(osd->Width() - cFont::GetFont(fontSml)->Width(*date) - 2, 0, *date, Theme.Color(clrChannelDate), Theme.Color(clrBackground), cFont::GetFont(fontSml));
} }
osd->Flush(); osd->Flush();
} }
@ -338,9 +338,9 @@ void cSkinClassicDisplayMenu::SetText(const char *Text, bool FixedFont)
void cSkinClassicDisplayMenu::Flush(void) void cSkinClassicDisplayMenu::Flush(void)
{ {
const char *date = DayDateTime(); cDayDateTime date;
const cFont *font = cFont::GetFont(fontOsd); const cFont *font = cFont::GetFont(fontOsd);
osd->DrawText(x1 - font->Width(date) - 2, y0, date, Theme.Color(clrMenuDate), Theme.Color(clrMenuTitleBg), font); osd->DrawText(x1 - font->Width(*date) - 2, y0, *date, Theme.Color(clrMenuDate), Theme.Color(clrMenuTitleBg), font);
osd->Flush(); osd->Flush();
} }

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: skinsttng.c 1.7 2004/12/05 13:19:59 kls Exp $ * $Id: skinsttng.c 1.8 2004/12/19 15:48:55 kls Exp $
*/ */
// Star Trek: The Next Generation® is a registered trademark of Paramount Pictures // Star Trek: The Next Generation® is a registered trademark of Paramount Pictures
@ -289,9 +289,9 @@ void cSkinSTTNGDisplayChannel::Flush(void)
{ {
if (withInfo) { if (withInfo) {
if (!message) { if (!message) {
const char *date = DayDateTime(); cDayDateTime date;
const cFont *font = cFont::GetFont(fontSml); const cFont *font = cFont::GetFont(fontSml);
osd->DrawText(x4 - font->Width(date) - 2, y7 - font->Height(date), date, Theme.Color(clrChannelDate), frameColor, font); osd->DrawText(x4 - font->Width(*date) - 2, y7 - font->Height(*date), *date, Theme.Color(clrChannelDate), frameColor, font);
} }
int seen = 0; int seen = 0;
@ -456,11 +456,11 @@ void cSkinSTTNGDisplayMenu::SetTitle(const char *Title)
void cSkinSTTNGDisplayMenu::SetButtons(const char *Red, const char *Green, const char *Yellow, const char *Blue) void cSkinSTTNGDisplayMenu::SetButtons(const char *Red, const char *Green, const char *Yellow, const char *Blue)
{ {
const char *date = DayDateTime(); cDayDateTime date;
const cFont *font = cFont::GetFont(fontSml); const cFont *font = cFont::GetFont(fontSml);
int d = 10; int d = 10;
int d2 = d / 2; int d2 = d / 2;
int t4 = x4 - font->Width(date) - 2; int t4 = x4 - font->Width(*date) - 2;
int w = t4 - x3; int w = t4 - x3;
int t0 = x3 + d2; int t0 = x3 + d2;
int t1 = x3 + w / 4; int t1 = x3 + w / 4;
@ -583,9 +583,9 @@ void cSkinSTTNGDisplayMenu::SetText(const char *Text, bool FixedFont)
void cSkinSTTNGDisplayMenu::Flush(void) void cSkinSTTNGDisplayMenu::Flush(void)
{ {
if (!message) { if (!message) {
const char *date = DayDateTime(); cDayDateTime date;
const cFont *font = cFont::GetFont(fontSml); const cFont *font = cFont::GetFont(fontSml);
osd->DrawText(x4 - font->Width(date) - 2, y7 - font->Height(date), date, Theme.Color(clrMenuDate), frameColor, font); osd->DrawText(x4 - font->Width(*date) - 2, y7 - font->Height(*date), *date, Theme.Color(clrMenuDate), frameColor, font);
} }
osd->Flush(); osd->Flush();
} }

31
svdrp.c
View File

@ -10,7 +10,7 @@
* and interact with the Video Disk Recorder - or write a full featured * and interact with the Video Disk Recorder - or write a full featured
* graphical interface that sits on top of an SVDRP connection. * graphical interface that sits on top of an SVDRP connection.
* *
* $Id: svdrp.c 1.65 2004/10/31 10:09:53 kls Exp $ * $Id: svdrp.c 1.66 2004/12/19 13:52:34 kls Exp $
*/ */
#include "svdrp.h" #include "svdrp.h"
@ -555,8 +555,9 @@ void cSVDRP::CmdGRAB(const char *Option)
char buf[strlen(Option) + 1]; char buf[strlen(Option) + 1];
char *p = strcpy(buf, Option); char *p = strcpy(buf, Option);
const char *delim = " \t"; const char *delim = " \t";
FileName = strtok(p, delim); char *strtok_next;
if ((p = strtok(NULL, delim)) != NULL) { FileName = strtok_r(p, delim, &strtok_next);
if ((p = strtok_r(NULL, delim, &strtok_next)) != NULL) {
if (strcasecmp(p, "JPEG") == 0) if (strcasecmp(p, "JPEG") == 0)
Jpeg = true; Jpeg = true;
else if (strcasecmp(p, "PNM") == 0) else if (strcasecmp(p, "PNM") == 0)
@ -566,7 +567,7 @@ void cSVDRP::CmdGRAB(const char *Option)
return; return;
} }
} }
if ((p = strtok(NULL, delim)) != NULL) { if ((p = strtok_r(NULL, delim, &strtok_next)) != NULL) {
if (isnumber(p)) if (isnumber(p))
Quality = atoi(p); Quality = atoi(p);
else { else {
@ -574,14 +575,14 @@ void cSVDRP::CmdGRAB(const char *Option)
return; return;
} }
} }
if ((p = strtok(NULL, delim)) != NULL) { if ((p = strtok_r(NULL, delim, &strtok_next)) != NULL) {
if (isnumber(p)) if (isnumber(p))
SizeX = atoi(p); SizeX = atoi(p);
else { else {
Reply(501, "Illegal sizex \"%s\"", p); Reply(501, "Illegal sizex \"%s\"", p);
return; return;
} }
if ((p = strtok(NULL, delim)) != NULL) { if ((p = strtok_r(NULL, delim, &strtok_next)) != NULL) {
if (isnumber(p)) if (isnumber(p))
SizeY = atoi(p); SizeY = atoi(p);
else { else {
@ -594,7 +595,7 @@ void cSVDRP::CmdGRAB(const char *Option)
return; return;
} }
} }
if ((p = strtok(NULL, delim)) != NULL) { if ((p = strtok_r(NULL, delim, &strtok_next)) != NULL) {
Reply(501, "Unexpected parameter \"%s\"", p); Reply(501, "Unexpected parameter \"%s\"", p);
return; return;
} }
@ -727,7 +728,8 @@ void cSVDRP::CmdLSTE(const char *Option)
char buf[strlen(Option) + 1]; char buf[strlen(Option) + 1];
strcpy(buf, Option); strcpy(buf, Option);
const char *delim = " \t"; const char *delim = " \t";
char *p = strtok(buf, delim); char *strtok_next;
char *p = strtok_r(buf, delim, &strtok_next);
while (p && DumpMode == dmAll) { while (p && DumpMode == dmAll) {
if (strcasecmp(p, "NOW") == 0) if (strcasecmp(p, "NOW") == 0)
DumpMode = dmPresent; DumpMode = dmPresent;
@ -735,7 +737,7 @@ void cSVDRP::CmdLSTE(const char *Option)
DumpMode = dmFollowing; DumpMode = dmFollowing;
else if (strcasecmp(p, "AT") == 0) { else if (strcasecmp(p, "AT") == 0) {
DumpMode = dmAtTime; DumpMode = dmAtTime;
if ((p = strtok(NULL, delim)) != NULL) { if ((p = strtok_r(NULL, delim, &strtok_next)) != NULL) {
if (isnumber(p)) if (isnumber(p))
AtTime = strtol(p, NULL, 10); AtTime = strtol(p, NULL, 10);
else { else {
@ -770,7 +772,7 @@ void cSVDRP::CmdLSTE(const char *Option)
Reply(501, "Unknown option: \"%s\"", p); Reply(501, "Unknown option: \"%s\"", p);
return; return;
} }
p = strtok(NULL, delim); p = strtok_r(NULL, delim, &strtok_next);
} }
} }
FILE *f = fdopen(file, "w"); FILE *f = fdopen(file, "w");
@ -995,11 +997,8 @@ void cSVDRP::CmdNEXT(const char *Option)
if (t) { if (t) {
time_t Start = t->StartTime(); time_t Start = t->StartTime();
int Number = t->Index() + 1; int Number = t->Index() + 1;
if (!*Option) { if (!*Option)
char *s = ctime(&Start); Reply(250, "%d %s", Number, *cCtime(Start));
s[strlen(s) - 1] = 0; // strip trailing newline
Reply(250, "%d %s", Number, s);
}
else if (strcasecmp(Option, "ABS") == 0) else if (strcasecmp(Option, "ABS") == 0)
Reply(250, "%d %ld", Number, Start); Reply(250, "%d %ld", Number, Start);
else if (strcasecmp(Option, "REL") == 0) else if (strcasecmp(Option, "REL") == 0)
@ -1152,7 +1151,7 @@ bool cSVDRP::Process(void)
char buffer[BUFSIZ]; char buffer[BUFSIZ];
gethostname(buffer, sizeof(buffer)); gethostname(buffer, sizeof(buffer));
time_t now = time(NULL); time_t now = time(NULL);
Reply(220, "%s SVDRP VideoDiskRecorder %s; %s", buffer, VDRVERSION, ctime(&now)); Reply(220, "%s SVDRP VideoDiskRecorder %s; %s", buffer, VDRVERSION, *cCtime(now));
} }
if (NewConnection) if (NewConnection)
lastActivity = time(NULL); lastActivity = time(NULL);

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: themes.c 1.3 2004/06/18 15:05:07 kls Exp $ * $Id: themes.c 1.4 2004/12/19 15:49:49 kls Exp $
*/ */
#include "themes.h" #include "themes.h"
@ -96,7 +96,8 @@ bool cTheme::Load(const char *FileName, bool OnlyDescriptions)
result = true; result = true;
char *s; char *s;
const char *error = NULL; const char *error = NULL;
while ((s = readline(f)) != NULL) { cReadLine ReadLine;
while ((s = ReadLine.Read(f)) != NULL) {
line++; line++;
char *p = strchr(s, '#'); char *p = strchr(s, '#');
if (p) if (p)
@ -242,29 +243,26 @@ bool cThemes::Load(const char *SkinName)
{ {
Clear(); Clear();
if (themesDirectory) { if (themesDirectory) {
DIR *d = opendir(themesDirectory); cReadDir d(themesDirectory);
if (d) { struct dirent *e;
struct dirent *e; while ((e = d.Next()) != NULL) {
while ((e = readdir(d)) != NULL) { if (strcmp(e->d_name, ".") && strcmp(e->d_name, "..")) {
if (strcmp(e->d_name, ".") && strcmp(e->d_name, "..")) { if (strstr(e->d_name, SkinName) == e->d_name && e->d_name[strlen(SkinName)] == '-') {
if (strstr(e->d_name, SkinName) == e->d_name && e->d_name[strlen(SkinName)] == '-') { cAddDirectory FileName(themesDirectory, e->d_name);
const char *FileName = AddDirectory(themesDirectory, e->d_name); cTheme Theme;
cTheme Theme; if (Theme.Load(*FileName, true)) {
if (Theme.Load(FileName, true)) { names = (char **)realloc(names, (numThemes + 1) * sizeof(char *));
names = (char **)realloc(names, (numThemes + 1) * sizeof(char *)); names[numThemes] = strdup(Theme.Name());
names[numThemes] = strdup(Theme.Name()); fileNames = (char **)realloc(fileNames, (numThemes + 1) * sizeof(char *));
fileNames = (char **)realloc(fileNames, (numThemes + 1) * sizeof(char *)); fileNames[numThemes] = strdup(*FileName);
fileNames[numThemes] = strdup(FileName); descriptions = (char **)realloc(descriptions, (numThemes + 1) * sizeof(char *));
descriptions = (char **)realloc(descriptions, (numThemes + 1) * sizeof(char *)); descriptions[numThemes] = strdup(Theme.Description());
descriptions[numThemes] = strdup(Theme.Description()); numThemes++;
numThemes++;
}
} }
} }
} }
closedir(d); }
return numThemes > 0; return numThemes > 0;
}
} }
return false; return false;
} }

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: timers.c 1.19 2004/11/22 16:49:15 kls Exp $ * $Id: timers.c 1.20 2004/12/19 14:11:29 kls Exp $
*/ */
#include "timers.h" #include "timers.h"
@ -111,7 +111,7 @@ const char *cTimer::ToText(bool UseChannelID)
free(buffer); free(buffer);
strreplace(file, ':', '|'); strreplace(file, ':', '|');
strreplace(summary, '\n', '|'); strreplace(summary, '\n', '|');
asprintf(&buffer, "%d:%s:%s:%04d:%04d:%d:%d:%s:%s\n", flags, UseChannelID ? Channel()->GetChannelID().ToString() : itoa(Channel()->Number()), PrintDay(day, firstday), start, stop, priority, lifetime, file, summary ? summary : ""); asprintf(&buffer, "%d:%s:%s:%04d:%04d:%d:%d:%s:%s\n", flags, UseChannelID ? Channel()->GetChannelID().ToString() : *cItoa(Channel()->Number()), PrintDay(day, firstday), start, stop, priority, lifetime, file, summary ? summary : "");
strreplace(summary, '|', '\n'); strreplace(summary, '|', '\n');
strreplace(file, '|', ':'); strreplace(file, '|', ':');
return buffer; return buffer;

200
tools.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: tools.c 1.82 2004/11/21 14:36:34 kls Exp $ * $Id: tools.c 1.83 2004/12/19 16:08:50 kls Exp $
*/ */
#include "tools.h" #include "tools.h"
@ -65,18 +65,6 @@ void writechar(int filedes, char c)
safe_write(filedes, &c, sizeof(c)); safe_write(filedes, &c, sizeof(c));
} }
char *readline(FILE *f)
{
static char buffer[MAXPARSEBUFFER];
if (fgets(buffer, sizeof(buffer), f) > 0) {
int l = strlen(buffer) - 1;
if (l >= 0 && buffer[l] == '\n')
buffer[l] = 0;
return buffer;
}
return NULL;
}
char *strcpyrealloc(char *dest, const char *src) char *strcpyrealloc(char *dest, const char *src)
{ {
if (src) { if (src) {
@ -167,29 +155,6 @@ char *compactspace(char *s)
return s; return s;
} }
const char *strescape(const char *s, const char *chars)
{
static char *buffer = NULL;
const char *p = s;
char *t = NULL;
while (*p) {
if (strchr(chars, *p)) {
if (!t) {
buffer = (char *)realloc(buffer, 2 * strlen(s) + 1);
t = buffer + (p - s);
s = strcpy(buffer, s);
}
*t++ = '\\';
}
if (t)
*t++ = *p;
p++;
}
if (t)
*t = 0;
return s;
}
bool startswith(const char *s, const char *p) bool startswith(const char *s, const char *p)
{ {
while (*p) { while (*p) {
@ -253,21 +218,6 @@ bool isnumber(const char *s)
return true; return true;
} }
const char *itoa(int n)
{
static char buf[16];
snprintf(buf, sizeof(buf), "%d", n);
return buf;
}
const char *AddDirectory(const char *DirName, const char *FileName)
{
static char *buf = NULL;
free(buf);
asprintf(&buf, "%s/%s", DirName && *DirName ? DirName : ".", FileName);
return buf;
}
int FreeDiskSpaceMB(const char *Directory, int *UsedMB) int FreeDiskSpaceMB(const char *Directory, int *UsedMB)
{ {
if (UsedMB) if (UsedMB)
@ -336,10 +286,10 @@ bool RemoveFileOrDir(const char *FileName, bool FollowSymlinks)
struct stat st; struct stat st;
if (stat(FileName, &st) == 0) { if (stat(FileName, &st) == 0) {
if (S_ISDIR(st.st_mode)) { if (S_ISDIR(st.st_mode)) {
DIR *d = opendir(FileName); cReadDir d(FileName);
if (d) { if (d.Ok()) {
struct dirent *e; struct dirent *e;
while ((e = readdir(d)) != NULL) { while ((e = d.Next()) != NULL) {
if (strcmp(e->d_name, ".") && strcmp(e->d_name, "..")) { if (strcmp(e->d_name, ".") && strcmp(e->d_name, "..")) {
char *buffer; char *buffer;
asprintf(&buffer, "%s/%s", FileName, e->d_name); asprintf(&buffer, "%s/%s", FileName, e->d_name);
@ -367,7 +317,6 @@ bool RemoveFileOrDir(const char *FileName, bool FollowSymlinks)
free(buffer); free(buffer);
} }
} }
closedir(d);
} }
else { else {
LOG_ERROR_STR(FileName); LOG_ERROR_STR(FileName);
@ -389,11 +338,11 @@ bool RemoveFileOrDir(const char *FileName, bool FollowSymlinks)
bool RemoveEmptyDirectories(const char *DirName, bool RemoveThis) bool RemoveEmptyDirectories(const char *DirName, bool RemoveThis)
{ {
DIR *d = opendir(DirName); cReadDir d(DirName);
if (d) { if (d.Ok()) {
bool empty = true; bool empty = true;
struct dirent *e; struct dirent *e;
while ((e = readdir(d)) != NULL) { while ((e = d.Next()) != NULL) {
if (strcmp(e->d_name, ".") && strcmp(e->d_name, "..") && strcmp(e->d_name, "lost+found")) { if (strcmp(e->d_name, ".") && strcmp(e->d_name, "..") && strcmp(e->d_name, "lost+found")) {
char *buffer; char *buffer;
asprintf(&buffer, "%s/%s", DirName, e->d_name); asprintf(&buffer, "%s/%s", DirName, e->d_name);
@ -414,7 +363,6 @@ bool RemoveEmptyDirectories(const char *DirName, bool RemoveThis)
free(buffer); free(buffer);
} }
} }
closedir(d);
if (RemoveThis && empty) { if (RemoveThis && empty) {
dsyslog("removing %s", DirName); dsyslog("removing %s", DirName);
if (remove(DirName) < 0) { if (remove(DirName) < 0) {
@ -451,7 +399,7 @@ char *ReadLink(const char *FileName)
bool SpinUpDisk(const char *FileName) bool SpinUpDisk(const char *FileName)
{ {
static char *buf = NULL; char *buf = NULL;
for (int n = 0; n < 10; n++) { for (int n = 0; n < 10; n++) {
free(buf); free(buf);
if (DirectoryOk(FileName)) if (DirectoryOk(FileName))
@ -471,12 +419,14 @@ bool SpinUpDisk(const char *FileName)
double seconds = (((long long)tp2.tv_sec * 1000000 + tp2.tv_usec) - ((long long)tp1.tv_sec * 1000000 + tp1.tv_usec)) / 1000000.0; double seconds = (((long long)tp2.tv_sec * 1000000 + tp2.tv_usec) - ((long long)tp1.tv_sec * 1000000 + tp1.tv_usec)) / 1000000.0;
if (seconds > 0.5) if (seconds > 0.5)
dsyslog("SpinUpDisk took %.2f seconds\n", seconds); dsyslog("SpinUpDisk took %.2f seconds\n", seconds);
free(buf);
return true; return true;
} }
else else
LOG_ERROR_STR(buf); LOG_ERROR_STR(buf);
} }
} }
free(buf);
esyslog("ERROR: SpinUpDisk failed"); esyslog("ERROR: SpinUpDisk failed");
return false; return false;
} }
@ -489,35 +439,119 @@ time_t LastModifiedTime(const char *FileName)
return 0; return 0;
} }
const char *WeekDayName(int WeekDay) // --- cBufferedStringFunction -----------------------------------------------
cBufferedStringFunction::cBufferedStringFunction(void)
{
buffer = NULL;
result = ""; // makes sure dereferencing it doesn't hurt
}
cBufferedStringFunction::~cBufferedStringFunction()
{
free(buffer);
}
// --- cAddDirectory ---------------------------------------------------------
cAddDirectory::cAddDirectory(const char *DirName, const char *FileName)
{
asprintf(&buffer, "%s/%s", DirName && *DirName ? DirName : ".", FileName);
result = buffer;
}
// --- cStrEscape ------------------------------------------------------------
cStrEscape::cStrEscape(const char *s, const char *chars)
{
buffer = NULL;
const char *p = s;
char *t = NULL;
while (*p) {
if (strchr(chars, *p)) {
if (!t) {
buffer = (char *)realloc(buffer, 2 * strlen(s) + 1);
t = buffer + (p - s);
s = strcpy(buffer, s);
}
*t++ = '\\';
}
if (t)
*t++ = *p;
p++;
}
if (t)
*t = 0;
result = s;
}
// --- cCtime ----------------------------------------------------------------
cCtime::cCtime(time_t Time)
{
if (ctime_r(&Time, buffer)) {
buffer[strlen(buffer) - 1] = 0; // strip trailing newline
result = buffer;
}
}
// --- cItoa -----------------------------------------------------------------
cItoa::cItoa(int n)
{
snprintf(buffer, sizeof(buffer), "%d", n);
result = buffer;
}
// --- cWeekDayName ----------------------------------------------------------
cWeekDayName::cWeekDayName(int WeekDay)
{
WeekDayName(WeekDay);
}
cWeekDayName::cWeekDayName(time_t t)
{
struct tm tm_r;
WeekDayName(localtime_r(&t, &tm_r)->tm_wday);
}
void cWeekDayName::WeekDayName(int WeekDay)
{ {
static char buffer[4];
WeekDay = WeekDay == 0 ? 6 : WeekDay - 1; // we start with monday==0! WeekDay = WeekDay == 0 ? 6 : WeekDay - 1; // we start with monday==0!
if (0 <= WeekDay && WeekDay <= 6) { if (0 <= WeekDay && WeekDay <= 6) {
const char *day = tr("MonTueWedThuFriSatSun"); const char *day = tr("MonTueWedThuFriSatSun");
day += WeekDay * 3; day += WeekDay * 3;
strncpy(buffer, day, 3); strn0cpy(buffer, day, sizeof(buffer));
return buffer; result = buffer;
} }
else else
return "???"; result = "???";
} }
const char *WeekDayName(time_t t) // --- cDayDateTime ----------------------------------------------------------
{
struct tm tm_r;
return WeekDayName(localtime_r(&t, &tm_r)->tm_wday);
}
const char *DayDateTime(time_t t) cDayDateTime::cDayDateTime(time_t t)
{ {
static char buffer[32];
if (t == 0) if (t == 0)
time(&t); time(&t);
struct tm tm_r; struct tm tm_r;
tm *tm = localtime_r(&t, &tm_r); tm *tm = localtime_r(&t, &tm_r);
snprintf(buffer, sizeof(buffer), "%s %2d.%02d %02d:%02d", WeekDayName(tm->tm_wday), tm->tm_mday, tm->tm_mon + 1, tm->tm_hour, tm->tm_min); snprintf(buffer, sizeof(buffer), "%s %2d.%02d %02d:%02d", *cWeekDayName(tm->tm_wday), tm->tm_mday, tm->tm_mon + 1, tm->tm_hour, tm->tm_min);
return buffer; result = buffer;
}
// --- cReadLine -------------------------------------------------------------
char *cReadLine::Read(FILE *f)
{
if (fgets(buffer, sizeof(buffer), f) > 0) {
int l = strlen(buffer) - 1;
if (l >= 0 && buffer[l] == '\n')
buffer[l] = 0;
return buffer;
}
return NULL;
} }
// --- cPoller --------------------------------------------------------------- // --- cPoller ---------------------------------------------------------------
@ -557,6 +591,24 @@ bool cPoller::Poll(int TimeoutMs)
return false; return false;
} }
// --- cReadDir --------------------------------------------------------------
cReadDir::cReadDir(const char *Directory)
{
directory = opendir(Directory);
}
cReadDir::~cReadDir()
{
if (directory)
closedir(directory);
}
struct dirent *cReadDir::Next(void)
{
return directory && readdir_r(directory, &u.d, &result) == 0 ? result : NULL;
}
// --- cFile ----------------------------------------------------------------- // --- cFile -----------------------------------------------------------------
bool cFile::files[FD_SETSIZE] = { false }; bool cFile::files[FD_SETSIZE] = { false };

85
tools.h
View File

@ -4,14 +4,16 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: tools.h 1.58 2004/10/31 16:16:37 kls Exp $ * $Id: tools.h 1.59 2004/12/19 14:49:48 kls Exp $
*/ */
#ifndef __TOOLS_H #ifndef __TOOLS_H
#define __TOOLS_H #define __TOOLS_H
#include <dirent.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <objalloc.h>
#include <poll.h> #include <poll.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -58,7 +60,6 @@ int BCD2INT(int x);
ssize_t safe_read(int filedes, void *buffer, size_t size); ssize_t safe_read(int filedes, void *buffer, size_t size);
ssize_t safe_write(int filedes, const void *buffer, size_t size); ssize_t safe_write(int filedes, const void *buffer, size_t size);
void writechar(int filedes, char c); void writechar(int filedes, char c);
char *readline(FILE *f);
char *strcpyrealloc(char *dest, const char *src); char *strcpyrealloc(char *dest, const char *src);
char *strn0cpy(char *dest, const char *src, size_t n); char *strn0cpy(char *dest, const char *src, size_t n);
char *strreplace(char *s, char c1, char c2); char *strreplace(char *s, char c1, char c2);
@ -66,7 +67,6 @@ char *strreplace(char *s, const char *s1, const char *s2); ///< re-allocates 's'
char *skipspace(const char *s); char *skipspace(const char *s);
char *stripspace(char *s); char *stripspace(char *s);
char *compactspace(char *s); char *compactspace(char *s);
const char *strescape(const char *s, const char *chars); ///< \warning returns a statically allocated string!
bool startswith(const char *s, const char *p); bool startswith(const char *s, const char *p);
bool endswith(const char *s, const char *p); bool endswith(const char *s, const char *p);
bool isempty(const char *s); bool isempty(const char *s);
@ -74,8 +74,6 @@ int numdigits(int n);
int time_ms(void); int time_ms(void);
void delay_ms(int ms); void delay_ms(int ms);
bool isnumber(const char *s); bool isnumber(const char *s);
const char *itoa(int n); ///< \warning returns a statically allocated string!
const char *AddDirectory(const char *DirName, const char *FileName); ///< \warning returns a statically allocated string!
int FreeDiskSpaceMB(const char *Directory, int *UsedMB = NULL); int FreeDiskSpaceMB(const char *Directory, int *UsedMB = NULL);
bool DirectoryOk(const char *DirName, bool LogErrors = false); bool DirectoryOk(const char *DirName, bool LogErrors = false);
bool MakeDirs(const char *FileName, bool IsDirectory = false); bool MakeDirs(const char *FileName, bool IsDirectory = false);
@ -84,9 +82,65 @@ bool RemoveEmptyDirectories(const char *DirName, bool RemoveThis = false);
char *ReadLink(const char *FileName); char *ReadLink(const char *FileName);
bool SpinUpDisk(const char *FileName); bool SpinUpDisk(const char *FileName);
time_t LastModifiedTime(const char *FileName); time_t LastModifiedTime(const char *FileName);
const char *WeekDayName(int WeekDay); ///< \warning returns a statically allocated string!
const char *WeekDayName(time_t t); ///< \warning returns a statically allocated string! class cBufferedStringFunction {
const char *DayDateTime(time_t t = 0); ///< \warning returns a statically allocated string! protected:
char *buffer;
const char *result;
public:
cBufferedStringFunction(void);
virtual ~cBufferedStringFunction();
const char * operator * () { return result; }
};
template<int size> class cBufferedStringFunctionFix : public cBufferedStringFunction {
protected:
char buffer[size];
const char *result;
public:
cBufferedStringFunctionFix(void) { result = ""; } // makes sure dereferencing it doesn't hurt
const char * operator * () { return result; }
};
class cAddDirectory : public cBufferedStringFunction {
public:
cAddDirectory(const char *DirName, const char *FileName);
};
class cStrEscape : public cBufferedStringFunction {
public:
cStrEscape(const char *s, const char *chars);
};
class cCtime : public cBufferedStringFunctionFix<32> {
public:
cCtime(time_t Time);
};
class cItoa : public cBufferedStringFunctionFix<16> {
public:
cItoa(int n);
};
class cWeekDayName : public cBufferedStringFunctionFix<4> {
private:
void WeekDayName(int WeekDay);
public:
cWeekDayName(int WeekDay);
cWeekDayName(time_t t);
};
class cDayDateTime : public cBufferedStringFunctionFix<32> {
public:
cDayDateTime(time_t t = 0);
};
class cReadLine {
private:
char buffer[MAXPARSEBUFFER];
public:
char *Read(FILE *f);
};
class cPoller { class cPoller {
private: private:
@ -99,6 +153,21 @@ public:
bool Poll(int TimeoutMs = 0); bool Poll(int TimeoutMs = 0);
}; };
class cReadDir {
private:
DIR *directory;
struct dirent *result;
union { // according to "The GNU C Library Reference Manual"
struct dirent d;
char b[offsetof(struct dirent, d_name) + NAME_MAX + 1];
} u;
public:
cReadDir(const char *Directory);
~cReadDir();
bool Ok(void) { return directory != NULL; }
struct dirent *Next(void);
};
class cFile { class cFile {
private: private:
static bool files[]; static bool files[];

43
vdr.c
View File

@ -22,7 +22,7 @@
* *
* The project's page is at http://www.cadsoft.de/vdr * The project's page is at http://www.cadsoft.de/vdr
* *
* $Id: vdr.c 1.194 2004/12/05 13:20:29 kls Exp $ * $Id: vdr.c 1.195 2004/12/19 15:28:34 kls Exp $
*/ */
#include <getopt.h> #include <getopt.h>
@ -384,19 +384,19 @@ int main(int argc, char *argv[])
ConfigDirectory = VideoDirectory; ConfigDirectory = VideoDirectory;
cPlugin::SetConfigDirectory(ConfigDirectory); cPlugin::SetConfigDirectory(ConfigDirectory);
cThemes::SetThemesDirectory(AddDirectory(ConfigDirectory, "themes")); cThemes::SetThemesDirectory(*cAddDirectory(ConfigDirectory, "themes"));
Setup.Load(AddDirectory(ConfigDirectory, "setup.conf")); Setup.Load(*cAddDirectory(ConfigDirectory, "setup.conf"));
if (!(Sources.Load(AddDirectory(ConfigDirectory, "sources.conf"), true, true) && if (!(Sources.Load(*cAddDirectory(ConfigDirectory, "sources.conf"), true, true) &&
Diseqcs.Load(AddDirectory(ConfigDirectory, "diseqc.conf"), true, Setup.DiSEqC) && Diseqcs.Load(*cAddDirectory(ConfigDirectory, "diseqc.conf"), true, Setup.DiSEqC) &&
Channels.Load(AddDirectory(ConfigDirectory, "channels.conf"), false, true) && Channels.Load(*cAddDirectory(ConfigDirectory, "channels.conf"), false, true) &&
Timers.Load(AddDirectory(ConfigDirectory, "timers.conf")) && Timers.Load(*cAddDirectory(ConfigDirectory, "timers.conf")) &&
Commands.Load(AddDirectory(ConfigDirectory, "commands.conf"), true) && Commands.Load(*cAddDirectory(ConfigDirectory, "commands.conf"), true) &&
RecordingCommands.Load(AddDirectory(ConfigDirectory, "reccmds.conf"), true) && RecordingCommands.Load(*cAddDirectory(ConfigDirectory, "reccmds.conf"), true) &&
SVDRPhosts.Load(AddDirectory(ConfigDirectory, "svdrphosts.conf"), true) && SVDRPhosts.Load(*cAddDirectory(ConfigDirectory, "svdrphosts.conf"), true) &&
CaDefinitions.Load(AddDirectory(ConfigDirectory, "ca.conf"), true) && CaDefinitions.Load(*cAddDirectory(ConfigDirectory, "ca.conf"), true) &&
Keys.Load(AddDirectory(ConfigDirectory, "remote.conf")) && Keys.Load(*cAddDirectory(ConfigDirectory, "remote.conf")) &&
KeyMacros.Load(AddDirectory(ConfigDirectory, "keymacros.conf"), true) KeyMacros.Load(*cAddDirectory(ConfigDirectory, "keymacros.conf"), true)
)) ))
EXIT(2); EXIT(2);
@ -405,13 +405,16 @@ int main(int argc, char *argv[])
// EPG data: // EPG data:
if (EpgDataFileName) { if (EpgDataFileName) {
if (DirectoryOk(EpgDataFileName)) const char *EpgDirectory = NULL;
EpgDataFileName = AddDirectory(EpgDataFileName, DEFAULTEPGDATAFILENAME); if (DirectoryOk(EpgDataFileName)) {
EpgDirectory = EpgDataFileName;
EpgDataFileName = DEFAULTEPGDATAFILENAME;
}
else if (*EpgDataFileName != '/' && *EpgDataFileName != '.') else if (*EpgDataFileName != '/' && *EpgDataFileName != '.')
EpgDataFileName = AddDirectory(VideoDirectory, EpgDataFileName); EpgDirectory = VideoDirectory;
cSchedules::SetEpgDataFileName(*cAddDirectory(EpgDirectory, EpgDataFileName));
cSchedules::Read();
} }
cSchedules::SetEpgDataFileName(EpgDataFileName);
cSchedules::Read();
// DVB interfaces: // DVB interfaces:
@ -867,7 +870,7 @@ int main(int argc, char *argv[])
if (!Next || Delta > Setup.MinEventTimeout * 60 || ForceShutdown) { if (!Next || Delta > Setup.MinEventTimeout * 60 || ForceShutdown) {
ForceShutdown = false; ForceShutdown = false;
if (timer) if (timer)
dsyslog("next timer event at %s", ctime(&Next)); dsyslog("next timer event at %s", *cCtime(Next));
if (WatchdogTimeout > 0) if (WatchdogTimeout > 0)
signal(SIGALRM, SIG_IGN); signal(SIGALRM, SIG_IGN);
if (Interface->Confirm(tr("Press any key to cancel shutdown"), UserShutdown ? 5 : SHUTDOWNWAIT, true)) { if (Interface->Confirm(tr("Press any key to cancel shutdown"), UserShutdown ? 5 : SHUTDOWNWAIT, true)) {
@ -875,7 +878,7 @@ int main(int argc, char *argv[])
const char *File = timer ? timer->File() : ""; const char *File = timer ? timer->File() : "";
Delta = Next - time(NULL); // compensates for Confirm() timeout Delta = Next - time(NULL); // compensates for Confirm() timeout
char *cmd; char *cmd;
asprintf(&cmd, "%s %ld %ld %d \"%s\" %d", Shutdown, Next, Delta, Channel, strescape(File, "\"$"), UserShutdown); asprintf(&cmd, "%s %ld %ld %d \"%s\" %d", Shutdown, Next, Delta, Channel, *cStrEscape(File, "\"$"), UserShutdown);
isyslog("executing '%s'", cmd); isyslog("executing '%s'", cmd);
SystemExec(cmd); SystemExec(cmd);
free(cmd); free(cmd);