mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Made several functions threadsafe
This commit is contained in:
parent
9a8ef2b6c2
commit
1d3495a0f0
@ -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
12
HISTORY
@ -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
|
||||||
|
@ -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.
|
||||||
|
@ -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.
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
11
channels.c
11
channels.c
@ -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
5
keys.c
@ -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
5
osd.c
@ -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) {
|
||||||
|
31
plugin.c
31
plugin.c
@ -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));
|
||||||
|
70
recording.c
70
recording.c
@ -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);
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
14
skinsttng.c
14
skinsttng.c
@ -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
31
svdrp.c
@ -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);
|
||||||
|
42
themes.c
42
themes.c
@ -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;
|
||||||
}
|
}
|
||||||
|
4
timers.c
4
timers.c
@ -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
200
tools.c
@ -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
85
tools.h
@ -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
43
vdr.c
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user