Version 0.99pre5

- Updated channel settings for 'N24' (thanks to Andreas Gebel).
- Fixed handling hierarchical recordings menu in case of directories starting
  with the same sequence of characters.
- Fixed handling timers on the 29th, 30th or 31st of a month in case the next
  month has less than 31 days.
- Added a description of the sort order of individual episodes in the
  recordings menu to the MANUAL.
- Removed the EPG bugfix for "Title / Subtitle" cleanup. Apparently Pro-7 has
  finally stopped this nasty habit.
- Added some EPG bugfix statistics (printed to the log file every time the EPG
  data is cleaned up and when VDR is terminated). Maybe somebody in charge of
  the EPG data at the listed channels will read this and take the necessary
  actions to fix these things...
- Changed the [dei]syslog macros in tools.h to use a variable number of args,
  thus making it safe to use them in nested 'if/else' statements.
- Fixed error handling in establishing an SVDRP connection (thanks to Davide
  Achilli) for pointing this out).
- The new configuration file 'svdrphosts.conf' is now used to define which
  hosts may access the SVDRP port (by default only 'localhost' has access).
  See FORMATS for details.
- The special keywords TITLE and EPISODE can now be used in timer file names
  (see MANUAL and FORMATS for details).
- The new setup parameter NameInstantRecord can be used to define how an
  instant recording will be named (see MANUAL for details).
- When looking for the EPG record of the timer that starts a recording, now
  that record is taken which covers the time calculated as
  'start + (Setup.MarginStart * 2) + 1)' in order to have a better chance of
  hitting the right record in case of an instant recording. Timers that start
  further in the future should always be programmed via the "Schedules" menu.
- The special VPIDs '0' and '1' are now used to enable recording radio channels.
  Actually '0' should be enough, but '1' must be used with encrypted channels
  (driver bug?). Note, though, that since VDR is mainly a *video recorder*, some
  features like, e. g.,  the progress display, may not work as expected with
  radio recordings. Thanks to Michael Paar.
- Fixed a problem with the ERR macro defined by ncurses.h (thanks to Artur
  Skawina).
This commit is contained in:
Klaus Schmidinger 2002-02-03 18:00:00 +01:00
parent 3db2d636b2
commit ef0a53af72
24 changed files with 427 additions and 116 deletions

View File

@ -137,6 +137,7 @@ Matjaz Thaler <matjaz.thaler@guest.arnes.si>
Artur Skawina <skawina@geocities.com>
for improving the font file generation in the Makefile
for pointing out a problem with the ERR macro defined by ncurses.h
Werner Fink <werner@suse.de>
for making I/O more robust by handling EINTR
@ -179,3 +180,12 @@ Lauri Pesonen <lauri.pesonen@firsthop.com>
Sergei Haller <Sergei.Haller@math.uni-giessen.de>
for fixing the LastActivity timestamp after a shutdown prompt
Andreas Gebel <andreas@xcapenet.de>
for his help in keeping 'channels.conf' up to date
Davide Achilli <davide@objsystem.it>
for pointing out a bug in error handling while establishing an SVDRP connection
Michael Paar <mpaar@uumail.de>
for enabling recording of radio channels

27
FORMATS
View File

@ -24,7 +24,7 @@ Video Disk Recorder File Formats
- Polarization (one of 'h', 'H', 'v', 'V') **
- Diseqc number **
- Symbol rate ***
- Video PID
- Video PID (set to '0' for radio channels, '1' for encrypted radio channels)
- Audio PID (either one number, or two, separated by a comma)
If this channel also carries Dolby Digital sound, the Dolby PIDs follow
the audio PIDs, separated by a semicolon, as in "...:101,102;103,104:..."
@ -72,6 +72,11 @@ Video Disk Recorder File Formats
any ':' characters, these have to be replaced with '|'. If the name shall
contain subdirectories, these have to be delimited by '~' (since the '/'
character may be part of a regular programme name).
The special keywords TITLE and EPISODE, if present, will be replaced
with the title and episode information from the EPG data at the time of
recording (if that data is available). If at the time of recording either
of these cannot be determined, TITLE will default to the channel name, and
EPISODE will default to a blank.
- Summary (any newline characters in the summary have to be replaced with '|';
the summary may contain ':' characters)
@ -111,6 +116,26 @@ Video Disk Recorder File Formats
1..9, the command can be selected directly by pressing the respective numerical
key on the remote control.
* svdrphosts.conf
This file contains the IP numbers of all hosts that are allowed to access the
SVDRP port.
Each line contains one IP number in the format
IP-Address[/Netmask]
where 'IP-Address' is the address of a host or a network in the usual dot
separated notation (as in 192.168.100.1). If the optional 'Netmask' is given
only the given number of bits of 'IP-Address' are taken into account. This
allows you to grant SVDRP access to all hosts of an entire network. 'Netmask'
can be any integer from 1 to 32. The special value of 0 is only accepted if
the 'IP-Address' is 0.0.0.0, because this will give access to any host (USE
THIS WITH CARE!).
Everything following (and including) a '#' character is considered to be
comment.
* marks.vdr
This file (if present in a recording directory) contains the editing marks

39
HISTORY
View File

@ -930,3 +930,42 @@ Video Disk Recorder Revision History
2002-01-30: Version 0.99pre4
- Fixed handling improperly formatted EIT data (thanks to Rolf Hakenes).
2002-02-03: Version 0.99pre5
- Updated channel settings for 'N24' (thanks to Andreas Gebel).
- Fixed handling hierarchical recordings menu in case of directories starting
with the same sequence of characters.
- Fixed handling timers on the 29th, 30th or 31st of a month in case the next
month has less than 31 days.
- Added a description of the sort order of individual episodes in the
recordings menu to the MANUAL.
- Removed the EPG bugfix for "Title / Subtitle" cleanup. Apparently Pro-7 has
finally stopped this nasty habit.
- Added some EPG bugfix statistics (printed to the log file every time the EPG
data is cleaned up and when VDR is terminated). Maybe somebody in charge of
the EPG data at the listed channels will read this and take the necessary
actions to fix these things...
- Changed the [dei]syslog macros in tools.h to use a variable number of args,
thus making it safe to use them in nested 'if/else' statements.
- Fixed error handling in establishing an SVDRP connection (thanks to Davide
Achilli) for pointing this out).
- The new configuration file 'svdrphosts.conf' is now used to define which
hosts may access the SVDRP port (by default only 'localhost' has access).
See FORMATS for details.
- The special keywords TITLE and EPISODE can now be used in timer file names
(see MANUAL and FORMATS for details).
- The new setup parameter NameInstantRecord can be used to define how an
instant recording will be named (see MANUAL for details).
- When looking for the EPG record of the timer that starts a recording, now
that record is taken which covers the time calculated as
'start + (Setup.MarginStart * 2) + 1)' in order to have a better chance of
hitting the right record in case of an instant recording. Timers that start
further in the future should always be programmed via the "Schedules" menu.
- The special VPIDs '0' and '1' are now used to enable recording radio channels.
Actually '0' should be enough, but '1' must be used with encrypted channels
(driver bug?). Note, though, that since VDR is mainly a *video recorder*, some
features like, e. g., the progress display, may not work as expected with
radio recordings. Thanks to Michael Paar.
- Fixed a problem with the ERR macro defined by ncurses.h (thanks to Artur
Skawina).

View File

@ -81,6 +81,11 @@ WARNING: DUE TO THE OPEN SVDRP PORT THIS PROGRAM MAY CONSTITUTE A
A CONTROLLED ENVIRONMENT, YOU MAY WANT TO DISABLE SVDRP
BY USING '--port=0'!
The file 'svdrphosts.conf' can be used to define which hosts are allowed
to access the SVDRP port. By default only localhost (127.0.0.1) is granted
access. If you want to give other hosts access to your SVDRP port you need to
add their IP numbers to 'svdrphosts.conf'.
If the program shall run as a daemon, use the --daemon option. This
will completely detach it from the terminal and will continue as a
background process.

16
MANUAL
View File

@ -166,6 +166,14 @@ Video Disk Recorder User's Manual
that directory (and any possible subdirectory thereof) as well as the total
number of new recordings (as opposed to a recording's entry, which displays
the date and time of the recording).
If the setup parameter UseSubtitle was turned on when a recording took place,
VDR adds the "subtitle" (which is usually the name of the episode in case of
a series) to the recording's name. The "Recordings" menu then displays all
recordings of a periodic timer in chronological order, since these are
usually the individual episodes of a series, which you may want to view in
the order in which they were broadcast.
Playback can be stopped via the "Main" menu by selecting "Stop replaying",
or by pressing the "Blue" button outside the menu.
A previously stopped playback session can be resumed by pressing the "Blue"
@ -377,6 +385,14 @@ Video Disk Recorder User's Manual
0 = instant recordings will not be marked
1 = instant recordings will be marked.
NameInstantRecord = TITLE-EPISODE
Defines how to name an instant recording. If the keywords
TITLE and/or EPISODE are present, they will be replaced
with the title and episode information from the EPG data
at the time of recording (if that data is available).
If this parameter is empty, the channel name will be used
by default.
LnbSLOF = 11700 The switching frequency (in MHz) between low and high LOF
LnbFrequLo = 9750 The LNB's low and high local oscillator frequencies (in MHz)
LnbFrequHi = 10600 (these have no meaning for DVB-C receivers)

View File

@ -4,7 +4,7 @@
# See the main source file 'vdr.c' for copyright information and
# how to reach the author.
#
# $Id: Makefile 1.29 2002/01/13 16:57:27 kls Exp $
# $Id: Makefile 1.30 2002/02/01 14:40:09 kls Exp $
.DELETE_ON_ERROR:
@ -105,7 +105,7 @@ $(DTVLIB) $(DTVDIR)/libdtv.h:
clean:
make -C $(AC3DIR) clean
make -C $(DTVDIR) clean
-rm -f $(OBJS) $(DEPFILE) vdr genfontfile genfontfile.o core *~
-rm -f $(OBJS) $(DEPFILE) vdr genfontfile genfontfile.o core* *~
fontclean:
-rm -f fontfix.c fontosd.c
CLEAN: clean fontclean

View File

@ -96,7 +96,7 @@ Cinedom 5A:11758:h:0:27500:1279:1280:0:3:194
Cinedom 5B:11720:h:0:27500:1791:1792:0:3:177
Cinedom 5C:12070:h:0:27500:1023:1024:0:3:186
:Beta Digital
N24:11914:H:0:27500:255:256:8191:3:52
N24:12480:v:0:27500:2047:2048:0:0:47
CNBC:11954:h:0:27500:510:520:0:0:28010
Liberty TV.com:12610:V:0:22000:941:943,942:0:0:12199
:PW Erotic

158
config.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: config.c 1.77 2002/01/19 16:06:42 kls Exp $
* $Id: config.c 1.82 2002/02/03 15:25:44 kls Exp $
*/
#include "config.h"
@ -296,9 +296,8 @@ bool cChannel::Switch(cDvbApi *DvbApi, bool Log)
if (!DvbApi)
DvbApi = cDvbApi::PrimaryDvbApi;
if (!DvbApi->Recording() && !groupSep) {
if (Log) {
if (Log)
isyslog(LOG_INFO, "switching to channel %d", number);
}
for (int i = 3; i--;) {
switch (DvbApi->SetChannel(number, frequency, polarization, diseqc, srate, vpid, apid1, apid2, dpid1, dpid2, tpid, ca, pnr)) {
case scrOk: return true;
@ -341,7 +340,7 @@ cTimer::cTimer(bool Instant)
*file = 0;
summary = NULL;
if (Instant && ch)
snprintf(file, sizeof(file), "%s%s", Setup.MarkInstantRecord ? "@" : "", ch->name);
snprintf(file, sizeof(file), "%s%s", Setup.MarkInstantRecord ? "@" : "", *Setup.NameInstantRecord ? Setup.NameInstantRecord : ch->name);
}
cTimer::cTimer(const cEventInfo *EventInfo)
@ -540,6 +539,13 @@ time_t cTimer::SetTime(time_t t, int SecondsFromMidnight)
return mktime(&tm);
}
char *cTimer::SetFile(const char *File)
{
if (!isempty(File))
strn0cpy(file, File, sizeof(file));
return file;
}
bool cTimer::Matches(time_t t)
{
startTime = stopTime = 0;
@ -551,7 +557,7 @@ bool cTimer::Matches(time_t t)
if (length < 0)
length += SECSINDAY;
int DaysToCheck = IsSingleEvent() ? 31 : 7;
int DaysToCheck = IsSingleEvent() ? 61 : 7; // 61 to handle months with 31/30/31
for (int i = -1; i <= DaysToCheck; i++) {
time_t t0 = IncDay(t, i);
if (DayMatches(t0)) {
@ -647,6 +653,40 @@ const char *cCommand::Execute(void)
return result;
}
// -- cSVDRPhost -------------------------------------------------------------
cSVDRPhost::cSVDRPhost(void)
{
addr.s_addr = 0;
mask = 0;
}
bool cSVDRPhost::Parse(const char *s)
{
mask = 0xFFFFFFFF;
const char *p = strchr(s, '/');
if (p) {
char *error = NULL;
int m = strtoul(p + 1, &error, 10);
if (error && !isspace(*error) || m > 32)
return false;
*(char *)p = 0; // yes, we know it's 'const' - will be restored!
if (m == 0)
mask = 0;
else
mask >>= (32 - m);
}
int result = inet_aton(s, &addr);
if (p)
*(char *)p = '/'; // there it is again
return result != 0 && (mask != 0 || addr.s_addr == 0);
}
bool cSVDRPhost::Accepts(in_addr_t Address)
{
return (Address & mask) == addr.s_addr;
}
// -- cKeys ------------------------------------------------------------------
cKeys Keys;
@ -659,9 +699,9 @@ cCommands Commands;
cChannels Channels;
bool cChannels::Load(const char *FileName)
bool cChannels::Load(const char *FileName, bool AllowComments)
{
if (cConfig<cChannel>::Load(FileName)) {
if (cConfig<cChannel>::Load(FileName, AllowComments)) {
ReNumber();
return true;
}
@ -779,6 +819,21 @@ cTimer *cTimers::GetNextActiveTimer(void)
return t0;
}
// -- cSVDRPhosts ------------------------------------------------------------
cSVDRPhosts SVDRPhosts;
bool cSVDRPhosts::Acceptable(in_addr_t Address)
{
cSVDRPhost *h = First();
while (h) {
if (h->Accepts(Address))
return true;
h = (cSVDRPhost *)h->Next();
}
return false;
}
// -- cSetup -----------------------------------------------------------------
cSetup Setup;
@ -792,6 +847,7 @@ cSetup::cSetup(void)
ShowInfoOnChSwitch = 1;
MenuScrollPage = 1;
MarkInstantRecord = 1;
strcpy(NameInstantRecord, "TITLE-EPISODE");
LnbSLOF = 11700;
LnbFrequLo = 9750;
LnbFrequHi = 10600;
@ -825,47 +881,51 @@ cSetup::cSetup(void)
bool cSetup::Parse(char *s)
{
const char *Delimiters = " \t\n=";
char *Name = strtok(s, Delimiters);
char *Value = strtok(NULL, Delimiters);
if (Name && Value) {
if (!strcasecmp(Name, "OSDLanguage")) OSDLanguage = atoi(Value);
else if (!strcasecmp(Name, "PrimaryDVB")) PrimaryDVB = atoi(Value);
else if (!strcasecmp(Name, "ShowInfoOnChSwitch")) ShowInfoOnChSwitch = atoi(Value);
else if (!strcasecmp(Name, "MenuScrollPage")) MenuScrollPage = atoi(Value);
else if (!strcasecmp(Name, "MarkInstantRecord")) MarkInstantRecord = atoi(Value);
else if (!strcasecmp(Name, "LnbSLOF")) LnbSLOF = atoi(Value);
else if (!strcasecmp(Name, "LnbFrequLo")) LnbFrequLo = atoi(Value);
else if (!strcasecmp(Name, "LnbFrequHi")) LnbFrequHi = atoi(Value);
else if (!strcasecmp(Name, "DiSEqC")) DiSEqC = atoi(Value);
else if (!strcasecmp(Name, "SetSystemTime")) SetSystemTime = atoi(Value);
else if (!strcasecmp(Name, "MarginStart")) MarginStart = atoi(Value);
else if (!strcasecmp(Name, "MarginStop")) MarginStop = atoi(Value);
else if (!strcasecmp(Name, "EPGScanTimeout")) EPGScanTimeout = atoi(Value);
else if (!strcasecmp(Name, "EPGBugfixLevel")) EPGBugfixLevel = atoi(Value);
else if (!strcasecmp(Name, "SVDRPTimeout")) SVDRPTimeout = atoi(Value);
else if (!strcasecmp(Name, "SortTimers")) SortTimers = atoi(Value);
else if (!strcasecmp(Name, "PrimaryLimit")) PrimaryLimit = atoi(Value);
else if (!strcasecmp(Name, "DefaultPriority")) DefaultPriority = atoi(Value);
else if (!strcasecmp(Name, "DefaultLifetime")) DefaultLifetime = atoi(Value);
else if (!strcasecmp(Name, "UseSubtitle")) UseSubtitle = atoi(Value);
else if (!strcasecmp(Name, "RecordingDirs")) RecordingDirs = atoi(Value);
else if (!strcasecmp(Name, "VideoFormat")) VideoFormat = atoi(Value);
else if (!strcasecmp(Name, "ChannelInfoPos")) ChannelInfoPos = atoi(Value);
else if (!strcasecmp(Name, "OSDwidth")) OSDwidth = atoi(Value);
else if (!strcasecmp(Name, "OSDheight")) OSDheight = atoi(Value);
else if (!strcasecmp(Name, "OSDMessageTime")) OSDMessageTime = atoi(Value);
else if (!strcasecmp(Name, "MaxVideoFileSize")) MaxVideoFileSize = atoi(Value);
else if (!strcasecmp(Name, "SplitEditedFiles")) SplitEditedFiles = atoi(Value);
else if (!strcasecmp(Name, "MinEventTimeout")) MinEventTimeout = atoi(Value);
else if (!strcasecmp(Name, "MinUserInactivity")) MinUserInactivity = atoi(Value);
else if (!strcasecmp(Name, "MultiSpeedMode")) MultiSpeedMode = atoi(Value);
else if (!strcasecmp(Name, "ShowReplayMode")) ShowReplayMode = atoi(Value);
else if (!strcasecmp(Name, "CurrentChannel")) CurrentChannel = atoi(Value);
else if (!strcasecmp(Name, "CurrentVolume")) CurrentVolume = atoi(Value);
else
return false;
return true;
char *p = strchr(s, '=');
if (p) {
*p = 0;
char *Name = compactspace(s);
char *Value = compactspace(p + 1);
if (*Name && *Value) {
if (!strcasecmp(Name, "OSDLanguage")) OSDLanguage = atoi(Value);
else if (!strcasecmp(Name, "PrimaryDVB")) PrimaryDVB = atoi(Value);
else if (!strcasecmp(Name, "ShowInfoOnChSwitch")) ShowInfoOnChSwitch = atoi(Value);
else if (!strcasecmp(Name, "MenuScrollPage")) MenuScrollPage = atoi(Value);
else if (!strcasecmp(Name, "MarkInstantRecord")) MarkInstantRecord = atoi(Value);
else if (!strcasecmp(Name, "NameInstantRecord")) strn0cpy(NameInstantRecord, Value, MaxFileName);
else if (!strcasecmp(Name, "LnbSLOF")) LnbSLOF = atoi(Value);
else if (!strcasecmp(Name, "LnbFrequLo")) LnbFrequLo = atoi(Value);
else if (!strcasecmp(Name, "LnbFrequHi")) LnbFrequHi = atoi(Value);
else if (!strcasecmp(Name, "DiSEqC")) DiSEqC = atoi(Value);
else if (!strcasecmp(Name, "SetSystemTime")) SetSystemTime = atoi(Value);
else if (!strcasecmp(Name, "MarginStart")) MarginStart = atoi(Value);
else if (!strcasecmp(Name, "MarginStop")) MarginStop = atoi(Value);
else if (!strcasecmp(Name, "EPGScanTimeout")) EPGScanTimeout = atoi(Value);
else if (!strcasecmp(Name, "EPGBugfixLevel")) EPGBugfixLevel = atoi(Value);
else if (!strcasecmp(Name, "SVDRPTimeout")) SVDRPTimeout = atoi(Value);
else if (!strcasecmp(Name, "SortTimers")) SortTimers = atoi(Value);
else if (!strcasecmp(Name, "PrimaryLimit")) PrimaryLimit = atoi(Value);
else if (!strcasecmp(Name, "DefaultPriority")) DefaultPriority = atoi(Value);
else if (!strcasecmp(Name, "DefaultLifetime")) DefaultLifetime = atoi(Value);
else if (!strcasecmp(Name, "UseSubtitle")) UseSubtitle = atoi(Value);
else if (!strcasecmp(Name, "RecordingDirs")) RecordingDirs = atoi(Value);
else if (!strcasecmp(Name, "VideoFormat")) VideoFormat = atoi(Value);
else if (!strcasecmp(Name, "ChannelInfoPos")) ChannelInfoPos = atoi(Value);
else if (!strcasecmp(Name, "OSDwidth")) OSDwidth = atoi(Value);
else if (!strcasecmp(Name, "OSDheight")) OSDheight = atoi(Value);
else if (!strcasecmp(Name, "OSDMessageTime")) OSDMessageTime = atoi(Value);
else if (!strcasecmp(Name, "MaxVideoFileSize")) MaxVideoFileSize = atoi(Value);
else if (!strcasecmp(Name, "SplitEditedFiles")) SplitEditedFiles = atoi(Value);
else if (!strcasecmp(Name, "MinEventTimeout")) MinEventTimeout = atoi(Value);
else if (!strcasecmp(Name, "MinUserInactivity")) MinUserInactivity = atoi(Value);
else if (!strcasecmp(Name, "MultiSpeedMode")) MultiSpeedMode = atoi(Value);
else if (!strcasecmp(Name, "ShowReplayMode")) ShowReplayMode = atoi(Value);
else if (!strcasecmp(Name, "CurrentChannel")) CurrentChannel = atoi(Value);
else if (!strcasecmp(Name, "CurrentVolume")) CurrentVolume = atoi(Value);
else
return false;
return true;
}
}
return false;
}
@ -882,6 +942,7 @@ bool cSetup::Load(const char *FileName)
bool result = true;
while (fgets(buffer, sizeof(buffer), f) > 0) {
line++;
stripspace(buffer);
if (!isempty(buffer)) {
if (*buffer != '#' && !Parse(buffer)) {
esyslog(LOG_ERR, "error in %s, line %d\n", fileName, line);
@ -911,6 +972,7 @@ bool cSetup::Save(const char *FileName)
fprintf(f, "ShowInfoOnChSwitch = %d\n", ShowInfoOnChSwitch);
fprintf(f, "MenuScrollPage = %d\n", MenuScrollPage);
fprintf(f, "MarkInstantRecord = %d\n", MarkInstantRecord);
fprintf(f, "NameInstantRecord = %s\n", NameInstantRecord);
fprintf(f, "LnbSLOF = %d\n", LnbSLOF);
fprintf(f, "LnbFrequLo = %d\n", LnbFrequLo);
fprintf(f, "LnbFrequHi = %d\n", LnbFrequHi);

View File

@ -4,12 +4,13 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: config.h 1.90 2002/01/30 18:30:03 kls Exp $
* $Id: config.h 1.93 2002/02/03 15:16:21 kls Exp $
*/
#ifndef __CONFIG_H
#define __CONFIG_H
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
@ -18,7 +19,7 @@
#include "eit.h"
#include "tools.h"
#define VDRVERSION "0.99pre4"
#define VDRVERSION "0.99pre5"
#define MAXPRIORITY 99
#define MAXLIFETIME 99
@ -65,6 +66,8 @@ enum eKeys { // "Up" and "Down" must be the first two keys!
#define ISRAWKEY(k) ((k) != kNone && ((k) & k_Flags) == 0)
#define NORMALKEY(k) (eKeys((k) & ~k_Repeat))
#define MaxFileName 256
struct tKey {
eKeys type;
char *name;
@ -122,7 +125,6 @@ private:
static char *buffer;
static const char *ToText(cTimer *Timer);
public:
enum { MaxFileName = 256 };
bool recording, pending;
int active;
int channel;
@ -148,6 +150,7 @@ public:
bool DayMatches(time_t t);
time_t IncDay(time_t t, int Days);
time_t SetTime(time_t t, int SecondsFromMidnight);
char *SetFile(const char *File);
bool Matches(time_t t = 0);
time_t StartTime(void);
time_t StopTime(void);
@ -171,6 +174,16 @@ public:
const char *Execute(void);
};
class cSVDRPhost : public cListObject {
private:
struct in_addr addr;
in_addr_t mask;
public:
cSVDRPhost(void);
bool Parse(const char *s);
bool Accepts(in_addr_t Address);
};
template<class T> class cConfig : public cList<T> {
private:
char *fileName;
@ -182,7 +195,7 @@ private:
public:
cConfig(void) { fileName = NULL; }
virtual ~cConfig() { delete fileName; }
virtual bool Load(const char *FileName)
virtual bool Load(const char *FileName, bool AllowComments = false)
{
Clear();
fileName = strdup(FileName);
@ -196,6 +209,11 @@ public:
result = true;
while (fgets(buffer, sizeof(buffer), f) > 0) {
line++;
if (AllowComments) {
char *p = strchr(buffer, '#');
if (p)
*p = 0;
}
if (!isempty(buffer)) {
T *l = new T;
if (l->Parse(buffer))
@ -242,7 +260,7 @@ protected:
int maxNumber;
public:
cChannels(void) { maxNumber = 0; }
virtual bool Load(const char *FileName);
virtual bool Load(const char *FileName, bool AllowComments = false);
int GetNextGroup(int Idx); // Get next channel group
int GetPrevGroup(int Idx); // Get previous channel group
int GetNextNormal(int Idx); // Get next normal channel (not group)
@ -263,10 +281,16 @@ public:
class cCommands : public cConfig<cCommand> {};
class cSVDRPhosts : public cConfig<cSVDRPhost> {
public:
bool Acceptable(in_addr_t Address);
};
extern cChannels Channels;
extern cTimers Timers;
extern cKeys Keys;
extern cCommands Commands;
extern cSVDRPhosts SVDRPhosts;
class cSetup {
private:
@ -279,6 +303,7 @@ public:
int ShowInfoOnChSwitch;
int MenuScrollPage;
int MarkInstantRecord;
char NameInstantRecord[MaxFileName];
int LnbSLOF;
int LnbFrequLo;
int LnbFrequHi;

View File

@ -7,7 +7,7 @@
* DVD support initially written by Andreas Schultz <aschultz@warp10.net>
* based on dvdplayer-0.5 by Matjaz Thaler <matjaz.thaler@guest.arnes.si>
*
* $Id: dvbapi.c 1.146 2002/01/26 15:39:48 kls Exp $
* $Id: dvbapi.c 1.147 2002/02/02 13:04:00 kls Exp $
*/
//#define DVDDEBUG 1
@ -548,9 +548,8 @@ void cRecordBuffer::Input(void)
}
else if (r < 0) {
if (FATALERRNO) {
if (errno == EBUFFEROVERFLOW) { // this error code is not defined in the library
if (errno == EBUFFEROVERFLOW) // this error code is not defined in the library
esyslog(LOG_ERR, "ERROR (%s,%d): DVB driver buffer overflow", __FILE__, __LINE__);
}
else {
LOG_ERROR;
break;
@ -1064,9 +1063,8 @@ cReplayBuffer::cReplayBuffer(cDvbApi *DvbApi, int VideoDev, int AudioDev, const
return;
// Create the index file:
index = new cIndexFile(FileName, false);
if (!index) {
if (!index)
esyslog(LOG_ERR, "ERROR: can't allocate index");
}
else if (!index->Ok()) {
delete index;
index = NULL;
@ -2251,9 +2249,8 @@ void cTransferBuffer::Input(void)
}
else if (r < 0) {
if (FATALERRNO) {
if (errno == EBUFFEROVERFLOW) { // this error code is not defined in the library
if (errno == EBUFFEROVERFLOW) // this error code is not defined in the library
esyslog(LOG_ERR, "ERROR (%s,%d): DVB driver buffer overflow", __FILE__, __LINE__);
}
else {
LOG_ERROR;
break;
@ -2719,12 +2716,10 @@ bool cDvbApi::Init(void)
}
}
PrimaryDvbApi = dvbApi[0];
if (NumDvbApis > 0) {
if (NumDvbApis > 0)
isyslog(LOG_INFO, "found %d video device%s", NumDvbApis, NumDvbApis > 1 ? "s" : "");
} // need braces because of isyslog-macro
else {
else
esyslog(LOG_ERR, "ERROR: no video device found, giving up!");
}
return NumDvbApis > 0;
}

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: dvbapi.h 1.60 2002/01/26 13:01:16 kls Exp $
* $Id: dvbapi.h 1.61 2002/02/03 16:43:38 kls Exp $
*/
#ifndef __DVBAPI_H
@ -12,6 +12,7 @@
#if defined(DEBUG_OSD) || defined(REMOTE_KBD)
#include <ncurses.h>
#undef ERR //XXX ncurses defines this - but this clashes with newer system header files
#endif
#include <stdlib.h> // FIXME: this is apparently necessary for the ost/... header files
// FIXME: shouldn't every header file include ALL the other header

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: dvbosd.h 1.9 2001/12/09 15:11:05 kls Exp $
* $Id: dvbosd.h 1.10 2002/02/03 16:43:50 kls Exp $
*/
#ifndef __DVBOSD_H
@ -12,6 +12,7 @@
#if defined(DEBUG_OSD) || defined(REMOTE_KBD)
#include <ncurses.h>
#undef ERR //XXX ncurses defines this - but this clashes with newer system header files
#endif
#include <ost/osd.h>
#include <stdio.h>

85
eit.c
View File

@ -16,7 +16,7 @@
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* $Id: eit.c 1.31 2002/01/13 16:14:31 kls Exp $
* $Id: eit.c 1.33 2002/02/02 12:12:26 kls Exp $
***************************************************************************/
#include "eit.h"
@ -352,6 +352,64 @@ void cEventInfo::Dump(FILE *f, const char *Prefix) const
}
}
#define MAXEPGBUGFIXSTATS 6
#define MAXEPGBUGFIXCHANS 50
struct tEpgBugFixStats {
int hits;
int n;
unsigned short serviceIDs[MAXEPGBUGFIXCHANS];
tEpgBugFixStats(void) { hits = n = 0; }
};
tEpgBugFixStats EpgBugFixStats[MAXEPGBUGFIXSTATS];
static void EpgBugFixStat(int Number, unsigned int ServiceID)
{
if (0 <= Number && Number < MAXEPGBUGFIXSTATS) {
tEpgBugFixStats *p = &EpgBugFixStats[Number];
p->hits++;
int i = 0;
for (; i < p->n; i++) {
if (p->serviceIDs[i] == ServiceID)
break;
}
if (i == p->n && p->n < MAXEPGBUGFIXCHANS)
p->serviceIDs[p->n++] = ServiceID;
}
}
static void ReportEpgBugFixStats(bool Reset = false)
{
if (Setup.EPGBugfixLevel > 0) {
dsyslog(LOG_INFO, "=====================");
dsyslog(LOG_INFO, "EPG bugfix statistics");
dsyslog(LOG_INFO, "=====================");
dsyslog(LOG_INFO, "IF SOMEBODY WHO IS IN CHARGE OF THE EPG DATA FOR ONE OF THE LISTED");
dsyslog(LOG_INFO, "CHANNELS READS THIS: PLEASE TAKE A LOOK AT THE FUNCTION cEventInfo::FixEpgBugs()");
dsyslog(LOG_INFO, "IN VDR/eit.c TO LEARN WHAT'S WRONG WITH YOUR DATA, AND FIX IT!");
dsyslog(LOG_INFO, "=====================");
dsyslog(LOG_INFO, "Fix\tHits\tChannels");
char buffer[1024];
for (int i = 0; i < MAXEPGBUGFIXSTATS; i++) {
const char *delim = "\t";
tEpgBugFixStats *p = &EpgBugFixStats[i];
char *q = buffer;
q += snprintf(q, sizeof(buffer) - (q - buffer), "%d\t%d", i, p->hits);
for (int c = 0; c < p->n; c++) {
cChannel *channel = Channels.GetByServiceID(p->serviceIDs[c]);
if (channel) {
q += snprintf(q, sizeof(buffer) - (q - buffer), "%s%s", delim, channel->name);
delim = ", ";
}
}
dsyslog(LOG_INFO, "%s", buffer);
if (Reset)
p->hits = p->n = 0;
}
dsyslog(LOG_INFO, "=====================");
}
}
void cEventInfo::FixEpgBugs(void)
{
// VDR can't usefully handle newline characters in the EPG data, so let's
@ -367,20 +425,6 @@ void cEventInfo::FixEpgBugs(void)
// EPG data. Let's fix their bugs as good as we can:
if (pTitle) {
// Pro7 preceeds the Subtitle with the Title:
//
// Title
// Title / Subtitle
//
if (pSubtitle && strstr(pSubtitle, pTitle) == pSubtitle) {
char *p = pSubtitle + strlen(pTitle);
const char *delim = " / ";
if (strstr(p, delim) == p) {
p += strlen(delim);
memmove(pSubtitle, p, strlen(p) + 1);
}
}
// VOX and VIVA put the Subtitle in quotes and use either the Subtitle
// or the Extended Description field, depending on how long the string is:
//
@ -400,6 +444,7 @@ void cEventInfo::FixEpgBugs(void)
delete pExtendedDescription;
pSubtitle = s;
pExtendedDescription = d;
EpgBugFixStat(0, GetServiceID());
}
}
}
@ -416,6 +461,7 @@ void cEventInfo::FixEpgBugs(void)
memmove(pSubtitle, pSubtitle + 1, strlen(pSubtitle));
pExtendedDescription = pSubtitle;
pSubtitle = NULL;
EpgBugFixStat(1, GetServiceID());
}
}
@ -427,6 +473,7 @@ void cEventInfo::FixEpgBugs(void)
if (pSubtitle && strcmp(pTitle, pSubtitle) == 0) {
delete pSubtitle;
pSubtitle = NULL;
EpgBugFixStat(2, GetServiceID());
}
// ZDF.info puts the Subtitle between double quotes, which is nothing
@ -442,6 +489,7 @@ void cEventInfo::FixEpgBugs(void)
char *p = strrchr(pSubtitle, '"');
if (p)
*p = 0;
EpgBugFixStat(3, GetServiceID());
}
}
@ -460,8 +508,10 @@ void cEventInfo::FixEpgBugs(void)
char *p = pExtendedDescription + 1;
while (*p) {
if (*p == '-' && *(p + 1) == ' ' && *(p + 2) && islower(*(p - 1)) && islower(*(p + 2))) {
if (!startswith(p + 2, "und ")) // special case in German, as in "Lach- und Sachgeschichten"
if (!startswith(p + 2, "und ")) { // special case in German, as in "Lach- und Sachgeschichten"
memmove(p, p + 2, strlen(p + 2) + 1);
EpgBugFixStat(4, GetServiceID());
}
}
p++;
}
@ -845,6 +895,8 @@ cSIProcessor::cSIProcessor(const char *FileName)
cSIProcessor::~cSIProcessor()
{
if (masterSIProcessor)
ReportEpgBugFixStats();
active = false;
Cancel(3);
ShutDownFilters();
@ -913,6 +965,7 @@ void cSIProcessor::Action()
schedules->Cleanup();
schedulesMutex.Unlock();
lastCleanup = now;
ReportEpgBugFixStats(true);
}
if (epgDataFileName && now - lastDump > 600)
{

BIN
gmon.out Normal file

Binary file not shown.

11
i18n.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: i18n.c 1.50 2002/01/27 15:52:32 kls Exp $
* $Id: i18n.c 1.51 2002/02/03 14:34:33 kls Exp $
*
* Slovenian translations provided by Miha Setina <mihasetina@softhome.net>
* Italian translations provided by Alberto Carraro <bertocar@tin.it>
@ -776,6 +776,15 @@ const tPhrase Phrases[] = {
"Enregistrement immédiat",
"Markere direkteopptak",
},
{ "NameInstantRecord",
"Direktaufz. benennen",
"", // TODO
"", // TODO
"", // TODO
"", // TODO
"", // TODO
"", // TODO
},
{ "LnbSLOF",
"LnbSLOF",
"LnbSLOF",

13
menu.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: menu.c 1.146 2002/01/27 15:50:50 kls Exp $
* $Id: menu.c 1.148 2002/02/03 15:42:38 kls Exp $
*/
#include "menu.h"
@ -1553,7 +1553,7 @@ cMenuRecordings::cMenuRecordings(const char *Base, int Level, bool OpenSubMenus)
cMenuRecordingItem *LastItem = NULL;
char *LastItemText = NULL;
for (cRecording *recording = Recordings.First(); recording; recording = Recordings.Next(recording)) {
if (!Base || strstr(recording->Name(), Base) == recording->Name()) {
if (!Base || (strstr(recording->Name(), Base) == recording->Name() && recording->Name()[strlen(Base)] == '~')) {
cMenuRecordingItem *Item = new cMenuRecordingItem(recording, level);
if (*Item->Text() && (!LastItem || strcmp(Item->Text(), LastItemText) != 0)) {
Add(Item);
@ -1829,6 +1829,7 @@ void cMenuSetup::Set(void)
Add(new cMenuEditBoolItem(tr("ShowInfoOnChSwitch"), &data.ShowInfoOnChSwitch));
Add(new cMenuEditBoolItem(tr("MenuScrollPage"), &data.MenuScrollPage));
Add(new cMenuEditBoolItem(tr("MarkInstantRecord"), &data.MarkInstantRecord));
Add(new cMenuEditStrItem( tr("NameInstantRecord"), data.NameInstantRecord, sizeof(data.NameInstantRecord), FileNameChars));
Add(new cMenuEditIntItem( tr("LnbSLOF"), &data.LnbSLOF));
Add(new cMenuEditIntItem( tr("LnbFrequLo"), &data.LnbFrequLo));
Add(new cMenuEditIntItem( tr("LnbFrequHi"), &data.LnbFrequHi));
@ -2309,14 +2310,16 @@ cRecordControl::cRecordControl(cDvbApi *DvbApi, cTimer *Timer)
timer->SetPending(true);
timer->SetRecording(true);
if (Channels.SwitchTo(timer->channel, dvbApi)) {
const char *Title = NULL;
const char *Subtitle = NULL;
const char *Summary = NULL;
if (GetEventInfo()) {
dsyslog(LOG_INFO, "Title: '%s' Subtitle: '%s'", eventInfo->GetTitle(), eventInfo->GetSubtitle());
Title = eventInfo->GetTitle();
Subtitle = eventInfo->GetSubtitle();
Summary = eventInfo->GetExtendedDescription();
dsyslog(LOG_INFO, "Title: '%s' Subtitle: '%s'", Title, Subtitle);
}
cRecording Recording(timer, Subtitle, Summary);
cRecording Recording(timer, Title, Subtitle, Summary);
fileName = strdup(Recording.FileName());
cRecordingUserCommand::InvokeCommand(RUC_BEFORERECORDING, fileName);
if (dvbApi->StartRecord(fileName, Channels.GetByNumber(timer->channel)->ca, timer->priority))
@ -2337,7 +2340,7 @@ cRecordControl::~cRecordControl()
bool cRecordControl::GetEventInfo(void)
{
cChannel *channel = Channels.GetByNumber(timer->channel);
time_t Time = timer->StartTime() + (timer->StopTime() - timer->StartTime()) / 2;
time_t Time = timer->StartTime() + ((Setup.MarginStart * 2) + 1) * 60;
for (int seconds = 0; seconds <= MAXWAIT4EPGINFO; seconds++) {
{
cThreadLock ThreadLock;

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: recording.c 1.48 2002/01/27 15:14:45 kls Exp $
* $Id: recording.c 1.49 2002/02/03 15:46:42 kls Exp $
*/
#include "recording.h"
@ -41,6 +41,9 @@
#define DISKCHECKDELTA 100 // seconds between checks for free disk space
#define REMOVELATENCY 10 // seconds to wait until next check after removing a file
#define TIMERMACRO_TITLE "TITLE"
#define TIMERMACRO_EPISODE "EPISODE"
void RemoveDeletedRecordings(void)
{
static time_t LastRemoveCheck = 0;
@ -214,19 +217,33 @@ char *ExchangeChars(char *s, bool ToFileSystem)
return s;
}
cRecording::cRecording(cTimer *Timer, const char *Subtitle, const char *Summary)
cRecording::cRecording(cTimer *Timer, const char *Title, const char *Subtitle, const char *Summary)
{
resume = RESUME_NOT_INITIALIZED;
titleBuffer = NULL;
sortBuffer = NULL;
fileName = NULL;
if (Timer->IsSingleEvent() || !Setup.UseSubtitle)
name = NULL;
// set up the actual name:
if (isempty(Title))
Title = Channels.GetChannelNameByNumber(Timer->channel);
if (isempty(Subtitle))
Subtitle = " ";
char *macroTITLE = strstr(Timer->file, TIMERMACRO_TITLE);
char *macroEPISODE = strstr(Timer->file, TIMERMACRO_EPISODE);
if (macroTITLE || macroEPISODE) {
name = strdup(Timer->file);
else {
if (isempty(Subtitle))
Subtitle = " ";
asprintf(&name, "%s~%s", Timer->file, Subtitle);
name = strreplace(name, TIMERMACRO_TITLE, Title);
name = strreplace(name, TIMERMACRO_EPISODE, Subtitle);
if (Timer->IsSingleEvent()) {
Timer->SetFile(name); // this was an instant recording, so let's set the actual data
Timers.Save();
}
}
else if (Timer->IsSingleEvent() || !Setup.UseSubtitle)
name = strdup(Timer->file);
else
asprintf(&name, "%s~%s", Timer->file, Subtitle);
// substitute characters that would cause problems in file names:
strreplace(name, '\n', ' ');
start = Timer->StartTime();

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: recording.h 1.21 2002/01/26 15:18:16 kls Exp $
* $Id: recording.h 1.22 2002/02/03 11:59:49 kls Exp $
*/
#ifndef __RECORDING_H
@ -43,7 +43,7 @@ public:
time_t start;
int priority;
int lifetime;
cRecording(cTimer *Timer, const char *Subtitle, const char *Summary);
cRecording(cTimer *Timer, const char *Title, const char *Subtitle, const char *Summary);
cRecording(const char *FileName);
~cRecording();
virtual bool operator< (const cListObject &ListObject);

16
remux.c
View File

@ -8,7 +8,7 @@
* the Linux DVB driver's 'tuxplayer' example and were rewritten to suit
* VDR's needs.
*
* $Id: remux.c 1.6 2001/08/19 11:52:05 kls Exp $
* $Id: remux.c 1.8 2002/02/03 16:20:37 kls Exp $
*/
/* The calling interface of the 'cRemux::Process()' function is defined
@ -555,6 +555,17 @@ XXX*/
return Result ? resultBuffer : NULL;
XXX*/
// Special VPID case to enable recording radio channels:
if (vPid == 0 || vPid == 1 || vPid == 0x1FFF) {
// XXX actually '0' should be enough, but '1' must be used with encrypted channels (driver bug?)
// XXX also allowing 0x1FFF to not break Michael Paar's original patch,
// XXX but it would probably be best to only use '0'
*PictureType = I_FRAME;
Result = resultDelivered = resultCount;
return Result ? resultBuffer : NULL;
}
// Check if we're getting anywhere here:
if (!synced && skipped >= 0) {
@ -583,9 +594,8 @@ XXX*/
if (l < 0)
return NULL; // no useful data found, wait for more
if (pt != NO_PICTURE) {
if (pt < I_FRAME || B_FRAME < pt) {
if (pt < I_FRAME || B_FRAME < pt)
esyslog(LOG_ERR, "ERROR: unknown picture type '%d'", pt);
}
else if (!synced) {
if (pt == I_FRAME) {
resultDelivered = i; // will drop everything before this position

16
svdrp.c
View File

@ -10,7 +10,7 @@
* and interact with the Video Disk Recorder - or write a full featured
* graphical interface that sits on top of an SVDRP connection.
*
* $Id: svdrp.c 1.28 2002/01/13 16:07:42 kls Exp $
* $Id: svdrp.c 1.30 2002/02/02 15:39:46 kls Exp $
*/
#include "svdrp.h"
@ -101,9 +101,17 @@ int cSocket::Accept(void)
struct sockaddr_in clientname;
uint size = sizeof(clientname);
int newsock = accept(sock, (struct sockaddr *)&clientname, &size);
if (newsock > 0)
isyslog(LOG_INFO, "connect from %s, port %hd", inet_ntoa(clientname.sin_addr), ntohs(clientname.sin_port));
else if (errno != EINTR)
if (newsock > 0) {
bool accepted = SVDRPhosts.Acceptable(clientname.sin_addr.s_addr);
if (!accepted) {
const char *s = "Access denied!\n";
write(newsock, s, strlen(s));
close(newsock);
newsock = -1;
}
isyslog(LOG_INFO, "connect from %s, port %hd - %s", inet_ntoa(clientname.sin_addr), ntohs(clientname.sin_port), accepted ? "accepted" : "DENIED");
}
else if (errno != EINTR && errno != EAGAIN)
LOG_ERROR;
return newsock;
}

13
svdrphosts.conf Normal file
View File

@ -0,0 +1,13 @@
#
# svdrphosts This file describes a number of host addresses that
# are allowed to connect to the SVDRP port of the Video
# Disk Recorder (VDR) running on this system.
# Syntax:
#
# IP-Address[/Netmask]
#
127.0.0.1 # always accept localhost
#192.168.100.0/24 # any host on the local net
#204.152.189.113 # a specific host
#0.0.0.0/0 # any host on any net (USE THIS WITH CARE!)

23
tools.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: tools.c 1.53 2002/01/27 12:36:23 kls Exp $
* $Id: tools.c 1.56 2002/02/03 16:44:08 kls Exp $
*/
#include "tools.h"
@ -13,6 +13,7 @@
#include <errno.h>
#if defined(DEBUG_OSD)
#include <ncurses.h>
#undef ERR //XXX ncurses defines this - but this clashes with newer system header files
#endif
#include <stdlib.h>
#include <sys/time.h>
@ -100,6 +101,23 @@ char *strreplace(char *s, char c1, char c2)
return s;
}
char *strreplace(char *s, const char *s1, const char *s2)
{
char *p = strstr(s, s1);
if (p) {
int of = p - s;
int l = strlen(s);
int l1 = strlen(s1);
int l2 = strlen(s2);
if (l2 > l1)
s = (char *)realloc(s, strlen(s) + l2 - l1 + 1);
if (l2 != l1)
memmove(s + of + l2, s + of + l1, l - of - l1 + 1);
strncpy(s + of, s2, l2);
}
return s;
}
char *skipspace(const char *s)
{
while (*s && isspace(*s))
@ -404,9 +422,8 @@ char *ReadLink(const char *FileName)
if (n < 0) {
if (errno == ENOENT || errno == EINVAL) // file doesn't exist or is not a symlink
TargetName = FileName;
else { // some other error occurred
else // some other error occurred
LOG_ERROR_STR(FileName);
}
}
else if (n < int(sizeof(RealName))) { // got it!
RealName[n] = 0;

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: tools.h 1.39 2002/01/26 15:38:10 kls Exp $
* $Id: tools.h 1.41 2002/02/03 12:36:25 kls Exp $
*/
#ifndef __TOOLS_H
@ -20,9 +20,9 @@
extern int SysLogLevel;
#define esyslog if (SysLogLevel > 0) syslog
#define isyslog if (SysLogLevel > 1) syslog
#define dsyslog if (SysLogLevel > 2) syslog
#define esyslog(a...) void( (SysLogLevel > 0) ? syslog(a) : void() )
#define isyslog(a...) void( (SysLogLevel > 1) ? syslog(a) : void() )
#define dsyslog(a...) void( (SysLogLevel > 2) ? syslog(a) : void() )
#define LOG_ERROR esyslog(LOG_ERR, "ERROR (%s,%d): %m", __FILE__, __LINE__)
#define LOG_ERROR_STR(s) esyslog(LOG_ERR, "ERROR: %s: %m", s)
@ -47,6 +47,7 @@ char *readline(FILE *f);
char *strcpyrealloc(char *dest, const char *src);
char *strn0cpy(char *dest, const char *src, size_t n);
char *strreplace(char *s, char c1, char c2);
char *strreplace(char *s, const char *s1, const char *s2); // re-allocates 's' and deletes the original string if necessary!
char *skipspace(const char *s);
char *stripspace(char *s);
char *compactspace(char *s);

3
vdr.c
View File

@ -22,7 +22,7 @@
*
* The project's page is at http://www.cadsoft.de/people/kls/vdr
*
* $Id: vdr.c 1.93 2002/01/26 14:07:01 kls Exp $
* $Id: vdr.c 1.94 2002/02/02 15:50:43 kls Exp $
*/
#include <getopt.h>
@ -272,6 +272,7 @@ int main(int argc, char *argv[])
Channels.Load(AddDirectory(ConfigDirectory, "channels.conf"));
Timers.Load(AddDirectory(ConfigDirectory, "timers.conf"));
Commands.Load(AddDirectory(ConfigDirectory, "commands.conf"));
SVDRPhosts.Load(AddDirectory(ConfigDirectory, "svdrphosts.conf"), true);
#if defined(REMOTE_LIRC)
Keys.SetDummyValues();
#elif !defined(REMOTE_NONE)