diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 304be837..97918215 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -2895,6 +2895,7 @@ Lars Hanisch the caller to have it display only a certain subset of the recordings for adding handling UTF-8 'umlaut' characters to cKbdRemote for fixing learning keyboard remote control codes + for making VDR read command line options from *.conf files in /etc/vdr/conf.d Alex Lasnier for adding tuning support for ATSC devices diff --git a/HISTORY b/HISTORY index 3770aebe..2ace5f49 100644 --- a/HISTORY +++ b/HISTORY @@ -8307,7 +8307,7 @@ Video Disk Recorder Revision History - The APIVERSION has been increased to 2.0.6 due to the changes to pat.h, sdt.h and the functional modification to cFont::CreateFont(). -2014-04-13: Version 2.1.7 +2014-04-14: Version 2.1.7 - No longer logging an error message in DirSizeMB() if the given directory doesn't exist. This avoids lots of log entries in case several VDRs use the same video @@ -8317,3 +8317,5 @@ Video Disk Recorder Revision History - A cCamSlot that has WantsTsData set to true in its constructor now also gets the CAT and EMM PIDs data. - Fixed a possible division by zero in frame rate detection. +- VDR now reads command line options from *.conf files in /etc/vdr/conf.d (thanks + to Lars Hanisch). See vdr.1 and vdr.5 for details. diff --git a/Make.config.template b/Make.config.template index 2bc0a8f1..dbb54140 100644 --- a/Make.config.template +++ b/Make.config.template @@ -6,7 +6,7 @@ # See the main source file 'vdr.c' for copyright information and # how to reach the author. # -# $Id: Make.config.template 2.19 2013/02/18 10:55:39 kls Exp $ +# $Id: Make.config.template 3.1 2014/04/14 11:43:53 kls Exp $ ### The C compiler and options: @@ -38,6 +38,7 @@ endif #VIDEODIR = /srv/vdr/video #CONFDIR = /var/lib/vdr +#ARGSDIR = /etc/vdr/conf.d #CACHEDIR = /var/cache/vdr # Overrides for preset/legacy configurations: diff --git a/Makefile b/Makefile index 0d3a8fc3..0fc382e7 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 3.2 2014/03/16 12:47:35 kls Exp $ +# $Id: Makefile 3.3 2014/04/14 12:08:24 kls Exp $ .DELETE_ON_ERROR: @@ -31,6 +31,7 @@ PLUGINDIR ?= $(CWD)/PLUGINS DESTDIR ?= VIDEODIR ?= /srv/vdr/video CONFDIR ?= /var/lib/vdr +ARGSDIR ?= /etc/vdr/conf.d CACHEDIR ?= /var/cache/vdr PREFIX ?= /usr/local @@ -66,7 +67,7 @@ endif SILIB = $(LSIDIR)/libsi.a -OBJS = audio.o channels.o ci.o config.o cutter.o device.o diseqc.o dvbdevice.o dvbci.o\ +OBJS = args.o audio.o channels.o ci.o config.o cutter.o device.o diseqc.o dvbdevice.o dvbci.o\ dvbplayer.o dvbspu.o dvbsubtitle.o eit.o eitscan.o epg.o filter.o font.o i18n.o interface.o keys.o\ lirc.o menu.o menuitems.o nit.o osdbase.o osd.o pat.o player.o plugin.o positioner.o\ receiver.o recorder.o recording.o remote.o remux.o ringbuffer.o sdt.o sections.o shutdown.o\ @@ -104,6 +105,7 @@ LIRC_DEVICE ?= /var/run/lirc/lircd DEFINES += -DLIRC_DEVICE=\"$(LIRC_DEVICE)\" DEFINES += -DVIDEODIR=\"$(VIDEODIR)\" DEFINES += -DCONFDIR=\"$(CONFDIR)\" +DEFINES += -DARGSDIR=\"$(ARGSDIR)\" DEFINES += -DCACHEDIR=\"$(CACHEDIR)\" DEFINES += -DRESDIR=\"$(RESDIR)\" DEFINES += -DPLUGINDIR=\"$(LIBDIR)\" @@ -146,8 +148,9 @@ $(SILIB): vdr.pc: @echo "bindir=$(BINDIR)" > $@ @echo "mandir=$(MANDIR)" >> $@ - @echo "configdir=$(CONFDIR)" >> $@ @echo "videodir=$(VIDEODIR)" >> $@ + @echo "configdir=$(CONFDIR)" >> $@ + @echo "argsdir=$(ARGSDIR)" >> $@ @echo "cachedir=$(CACHEDIR)" >> $@ @echo "resdir=$(RESDIR)" >> $@ @echo "libdir=$(LIBDIR)" >> $@ @@ -265,6 +268,7 @@ install-bin: vdr install-dirs: @mkdir -p $(DESTDIR)$(VIDEODIR) @mkdir -p $(DESTDIR)$(CONFDIR) + @mkdir -p $(DESTDIR)$(ARGSDIR) @mkdir -p $(DESTDIR)$(CACHEDIR) @mkdir -p $(DESTDIR)$(RESDIR) diff --git a/args.c b/args.c new file mode 100644 index 00000000..6a316055 --- /dev/null +++ b/args.c @@ -0,0 +1,129 @@ +/* + * args.c: Read arguments from files + * + * See the main source file 'vdr.c' for copyright information and + * how to reach the author. + * + * Original version written by Lars Hanisch . + * + * $Id: args.c 1.1 2014/04/14 12:02:38 kls Exp $ + */ + +#include "args.h" +#include + +cArgs::cArgs(const char *Argv0) +{ + argv0 = Argv0; + argc = 0; + argv = NULL; +} + +cArgs::~cArgs(void) +{ + if (argv != NULL) + delete [] argv; +} + +bool cArgs::AddArg(const char *s) +{ + if (inVdrSection) + args.Append(strdup(s)); + else if (*lastArg == NULL) + return false; + else + lastArg = cString::sprintf("%s %s", *lastArg, s); + return true; +} + +bool cArgs::ReadDirectory(const char *Directory) +{ + if (argv != NULL) + delete [] argv; + argc = 0; + argv = NULL; + args.Clear(); + lastArg = NULL; + inVdrSection = false; + cFileNameList files(Directory, false); + if (files.Size() == 0) + return false; + for (int i = 0; i < files.Size(); i++) { + const char *fileName = files.At(i); + if (startswith(fileName, ".") || !endswith(fileName, ".conf")) + continue; + cString fullFileName = AddDirectory(Directory, fileName); + struct stat fs; + if ((access(*fullFileName, F_OK) != 0) || (stat(*fullFileName, &fs) != 0) || S_ISDIR(fs.st_mode)) + continue; + bool ok = true; + int line = 0; + FILE *f = fopen(*fullFileName, "r"); + if (f) { + char *s; + cReadLine ReadLine; + while ((s = ReadLine.Read(f)) != NULL) { + line++; + s = stripspace(skipspace(s)); + if (!isempty(s) && (s[0] != '#')) { + if (startswith(s, "[") && endswith(s, "]")) { + s[strlen(s) - 1] = 0; + s++; + if (*lastArg) { + args.Append(strdup(*lastArg)); + lastArg = NULL; + } + if (strcmp(s, "vdr") == 0) + inVdrSection = true; + else { + inVdrSection = false; + lastArg = cString::sprintf("--plugin=%s", s); + } + } + else { + if ((strlen(s) > 2) && (s[0] == '-') && (s[1] != '-')) { // short option, split at first space + char *p = strchr(s, ' '); + if (p == NULL) { + ok = AddArg(s); + if (!ok) + break; + } + else { + *p = 0; + p++; + ok = AddArg(s); + if (!ok) + break; + ok = AddArg(p); + if (!ok) + break; + } + } + else { + ok = AddArg(s); + if (!ok) + break; + } + } + } + } + fclose(f); + } + if (!ok) { + esyslog("ERROR: args file %s, line %d", *fullFileName, line); + return false; + } + } + if (*lastArg) { + args.Append(strdup(*lastArg)); + lastArg = NULL; + } + argv = new char*[args.Size() + 1]; + argv[0] = strdup(*argv0); + argc = 1; + for (int i = 0; i < args.Size(); i++) { + argv[argc] = args.At(i); + argc++; + } + return true; +} diff --git a/args.h b/args.h new file mode 100644 index 00000000..2e91afb4 --- /dev/null +++ b/args.h @@ -0,0 +1,34 @@ +/* + * args.h: Read arguments from files + * + * See the main source file 'vdr.c' for copyright information and + * how to reach the author. + * + * Original version written by Lars Hanisch . + * + * $Id: args.h 1.1 2014/04/14 11:54:21 kls Exp $ + */ + +#ifndef __ARGS_H +#define __ARGS_H + +#include "tools.h" + +class cArgs { +private: + cString argv0; + cStringList args; + cString lastArg; + bool inVdrSection; + int argc; + char **argv; + bool AddArg(const char *s); +public: + cArgs(const char *Argv0); + ~cArgs(void); + bool ReadDirectory(const char *Directory); + int GetArgc(void) const { return argc; }; + char **GetArgv(void) const { return argv; }; + }; + +#endif //__ARGS_H diff --git a/vdr.1 b/vdr.1 index 36765dbd..c5bd281c 100644 --- a/vdr.1 +++ b/vdr.1 @@ -8,7 +8,7 @@ .\" License as specified in the file COPYING that comes with the .\" vdr distribution. .\" -.\" $Id: vdr.1 3.1 2013/12/25 11:01:36 kls Exp $ +.\" $Id: vdr.1 3.2 2014/04/14 12:52:45 kls Exp $ .\" .TH vdr 1 "31 Mar 2013" "2.0" "Video Disk Recorder" .SH NAME @@ -178,6 +178,10 @@ more information. Read resource files from \fIdir\fR (default is to read them from the config directory). .TP +.BI \-\-showargs[= dir ] +Read command line arguments from \fIdir\fR (default is \fI/etc/vdr/conf.d\fR), +display them to the console and exit. +.TP .BI \-s\ cmd ,\ \-\-shutdown= cmd Call \fIcmd\fR to shutdown the computer. See the file \fIINSTALL\fR for more information. @@ -213,6 +217,10 @@ Print version information and exit. .BI \-w\ sec ,\ \-\-watchdog= sec Activate the watchdog timer with a timeout of \fIsec\fR seconds. A value of \fB0\fR (default) disables the watchdog. +.P +If started without any options, vdr tries to read command line options +from files named '*.conf' in the directory /etc/vdr/conf.d. Files are +read in alphabetical order. See vdr(5) for details. .SH SIGNALS .TP .B SIGINT, SIGTERM diff --git a/vdr.5 b/vdr.5 index 645ce38b..44e56c49 100644 --- a/vdr.5 +++ b/vdr.5 @@ -8,7 +8,7 @@ .\" License as specified in the file COPYING that comes with the .\" vdr distribution. .\" -.\" $Id: vdr.5 3.2 2014/03/16 10:38:31 kls Exp $ +.\" $Id: vdr.5 3.3 2014/04/14 13:11:49 kls Exp $ .\" .TH vdr 5 "31 Mar 2013" "2.0" "Video Disk Recorder Files" .SH NAME @@ -899,6 +899,33 @@ Note that the \fBevent id\fR that comes from the DVB data stream is actually just 16 bit wide. The internal representation in VDR allows for 32 bit to be used, so that external tools can generate EPG data that is guaranteed not to collide with the ids of existing data. +.SS COMMANDLINE OPTIONS +If started without any options, vdr tries to read any files in the directory +/etc/vdr/conf.d with names that do not begin with a '.' and that end with '.conf'. +These files are read in alphabetical order. The format of these files is + +# comment +.br +[name] +.br +-a +.br +-b 123 +.br +--long +.br +--longarg=123 +.br + +Any lines that begin with '#' as the first non-whitespace character are considered +comments and are ignored. +A command line option file consists of one or more sections, indicated by '[name]', +where 'name' is either the fixed word 'vdr' (if this section contains options for +the main VDR program) or the name of the plugin this section applies to. +Each option must be written on a separate line, including the leading '-' (for +a short option) or '--' (for a long option). If the option has additional arguments, +they have to be written on the same line as the option itself, separated from the +option with a blank (short option) or equal sign (long option). .SH SEE ALSO .BR vdr (1) .SH AUTHOR diff --git a/vdr.c b/vdr.c index 835d33df..187332e0 100644 --- a/vdr.c +++ b/vdr.c @@ -22,7 +22,7 @@ * * The project's page is at http://www.tvdr.de * - * $Id: vdr.c 3.11 2014/03/16 12:49:13 kls Exp $ + * $Id: vdr.c 3.12 2014/04/14 12:17:17 kls Exp $ */ #include @@ -39,6 +39,7 @@ #endif #include #include +#include "args.h" #include "audio.h" #include "channels.h" #include "config.h" @@ -190,6 +191,7 @@ int main(int argc, char *argv[]) #define DEFAULTWATCHDOG 0 // seconds #define DEFAULTVIDEODIR VIDEODIR #define DEFAULTCONFDIR dd(CONFDIR, VideoDirectory) +#define DEFAULTARGSDIR dd(ARGSDIR, "/etc/vdr/conf.d") #define DEFAULTCACHEDIR dd(CACHEDIR, VideoDirectory) #define DEFAULTRESDIR dd(RESDIR, ConfigDirectory) #define DEFAULTPLUGINDIR PLUGINDIR @@ -227,6 +229,15 @@ int main(int argc, char *argv[]) VdrUser = VDR_USER; #endif + cArgs *Args = NULL; + if (argc == 1) { + Args = new cArgs(argv[0]); + if (Args->ReadDirectory(DEFAULTARGSDIR)) { + argc = Args->GetArgc(); + argv = Args->GetArgv(); + } + } + cVideoDirectory::SetName(VideoDirectory); cPluginManager PluginManager(DEFAULTPLUGINDIR); @@ -254,6 +265,7 @@ int main(int argc, char *argv[]) { "port", required_argument, NULL, 'p' }, { "record", required_argument, NULL, 'r' }, { "resdir", required_argument, NULL, 'r' | 0x100 }, + { "showargs", optional_argument, NULL, 's' | 0x200 }, { "shutdown", required_argument, NULL, 's' }, { "split", no_argument, NULL, 's' | 0x100 }, { "terminal", required_argument, NULL, 't' }, @@ -426,6 +438,19 @@ int main(int argc, char *argv[]) case 's' | 0x100: Setup.SplitEditedFiles = 1; break; + case 's' | 0x200: { + const char *ArgsDir = optarg ? optarg : DEFAULTARGSDIR; + cArgs Args(argv[0]); + if (!Args.ReadDirectory(ArgsDir)) { + fprintf(stderr, "vdr: can't read arguments from directory: %s\n", ArgsDir); + return 2; + } + int c = Args.GetArgc(); + char **v = Args.GetArgv(); + for (int i = 1; i < c; i++) + printf("%s\n", v[i]); + return 0; + } case 't': Terminal = optarg; if (access(Terminal, R_OK | W_OK) < 0) { fprintf(stderr, "vdr: can't access terminal: %s\n", Terminal); @@ -539,6 +564,8 @@ int main(int argc, char *argv[]) " -s CMD, --shutdown=CMD call CMD to shutdown the computer\n" " --split split edited files at the editing marks (only\n" " useful in conjunction with --edit)\n" + " --showargs[=DIR] print the arguments read from DIR and exit\n" + " (default: %s)\n" " -t TTY, --terminal=TTY controlling tty\n" " -u USER, --user=USER run as user USER; only applicable if started as\n" " root\n" @@ -561,6 +588,7 @@ int main(int argc, char *argv[]) DEFAULTLOCDIR, DEFAULTSVDRPPORT, DEFAULTRESDIR, + DEFAULTARGSDIR, DEFAULTVIDEODIR, DEFAULTWATCHDOG );