summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTORS10
-rw-r--r--FORMATS27
-rw-r--r--HISTORY39
-rw-r--r--INSTALL5
-rw-r--r--MANUAL16
-rw-r--r--Makefile4
-rw-r--r--channels.conf2
-rw-r--r--config.c158
-rw-r--r--config.h35
-rw-r--r--dvbapi.c17
-rw-r--r--dvbapi.h3
-rw-r--r--dvbosd.h3
-rw-r--r--eit.c85
-rw-r--r--gmon.outbin0 -> 101224 bytes
-rw-r--r--i18n.c11
-rw-r--r--menu.c13
-rw-r--r--recording.c31
-rw-r--r--recording.h4
-rw-r--r--remux.c16
-rw-r--r--svdrp.c16
-rw-r--r--svdrphosts.conf13
-rw-r--r--tools.c23
-rw-r--r--tools.h9
-rw-r--r--vdr.c3
24 files changed, 427 insertions, 116 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index 1d06173..e0b9ee1 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -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
diff --git a/FORMATS b/FORMATS
index 2a99e6e..d7d4293 100644
--- a/FORMATS
+++ b/FORMATS
@@ -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
diff --git a/HISTORY b/HISTORY
index a2c2e41..bf8ce2c 100644
--- a/HISTORY
+++ b/HISTORY
@@ -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).
diff --git a/INSTALL b/INSTALL
index d165096..cf69489 100644
--- a/INSTALL
+++ b/INSTALL
@@ -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.
diff --git a/MANUAL b/MANUAL
index 99d91be..d0ce7a2 100644
--- a/MANUAL
+++ b/MANUAL
@@ -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)
diff --git a/Makefile b/Makefile
index 38597e8..f74179d 100644
--- a/Makefile
+++ b/Makefile
@@ -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
diff --git a/channels.conf b/channels.conf
index a2bd32f..87796ae 100644
--- a/channels.conf
+++ b/channels.conf
@@ -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
diff --git a/config.c b/config.c
index f930351..974aed0 100644
--- a/config.c
+++ b/config.c
@@ -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);
diff --git a/config.h b/config.h
index 42f7337..325f4ef 100644
--- a/config.h
+++ b/config.h
@@ -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;
diff --git a/dvbapi.c b/dvbapi.c
index 048639c..314d91f 100644
--- a/dvbapi.c
+++ b/dvbapi.c
@@ -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;
}
diff --git a/dvbapi.h b/dvbapi.h
index 7337571..fbc1e9d 100644
--- a/dvbapi.h
+++ b/dvbapi.h
@@ -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
diff --git a/dvbosd.h b/dvbosd.h
index ceac507..0e90414 100644
--- a/dvbosd.h
+++ b/dvbosd.h
@@ -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>
diff --git a/eit.c b/eit.c
index ed757d2..2860fc4 100644
--- a/eit.c
+++ b/eit.c
@@ -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)
{
diff --git a/gmon.out b/gmon.out
new file mode 100644
index 0000000..ea79bc5
--- /dev/null
+++ b/gmon.out
Binary files differ
diff --git a/i18n.c b/i18n.c
index 7977fcd..3d9089a 100644
--- a/i18n.c
+++ b/i18n.c
@@ -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",
diff --git a/menu.c b/menu.c
index 1cd5491..40ac185 100644
--- a/menu.c
+++ b/menu.c
@@ -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;
diff --git a/recording.c b/recording.c
index acdf264..7a55e1a 100644
--- a/recording.c
+++ b/recording.c
@@ -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();
diff --git a/recording.h b/recording.h
index 3aaa7e9..38626f8 100644
--- a/recording.h
+++ b/recording.h
@@ -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);
diff --git a/remux.c b/remux.c
index f89b897..99a6440 100644
--- a/remux.c
+++ b/remux.c
@@ -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
diff --git a/svdrp.c b/svdrp.c
index 67de63c..4cdf2fb 100644
--- a/svdrp.c
+++ b/svdrp.c
@@ -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;
}
diff --git a/svdrphosts.conf b/svdrphosts.conf
new file mode 100644
index 0000000..dec9c42
--- /dev/null
+++ b/svdrphosts.conf
@@ -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!)
diff --git a/tools.c b/tools.c
index dc579e5..441c5ce 100644
--- a/tools.c
+++ b/tools.c
@@ -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;
diff --git a/tools.h b/tools.h
index f939018..9663a8e 100644
--- a/tools.h
+++ b/tools.h
@@ -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);
diff --git a/vdr.c b/vdr.c
index 5351e40..670246a 100644
--- a/vdr.c
+++ b/vdr.c
@@ -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)