35 #include <sys/capability.h>
36 #include <sys/prctl.h>
38 #include <systemd/sd-daemon.h>
75 #define MINCHANNELWAIT 10
76 #define ACTIVITYTIMEOUT 60
77 #define SHUTDOWNWAIT 300
78 #define SHUTDOWNRETRY 360
79 #define SHUTDOWNFORCEPROMPT 5
80 #define SHUTDOWNCANCELPROMPT 5
81 #define RESTARTCANCELPROMPT 5
82 #define MANUALSTART 600
83 #define CHANNELSAVEDELTA 600
84 #define DEVICEREADYTIMEOUT 30
85 #define MENUTIMEOUT 120
86 #define TIMERCHECKDELTA 10
87 #define TIMERDEVICETIMEOUT 8
88 #define TIMERLOOKAHEADTIME 60
89 #define VPSLOOKAHEADTIME 24
90 #define VPSUPTODATETIME 3600
92 #define EXIT(v) { ShutdownHandler.Exit(v); goto Exit; }
96 static bool SetUser(
const char *User,
bool UserDump)
99 struct passwd *user =
isnumber(User) ? getpwuid(atoi(User)) : getpwnam(User);
101 fprintf(stderr,
"vdr: unknown user: '%s'\n", User);
104 if (setgid(user->pw_gid) < 0) {
105 fprintf(stderr,
"vdr: cannot set group id %u: %s\n", (
unsigned int)user->pw_gid, strerror(errno));
108 if (initgroups(user->pw_name, user->pw_gid) < 0) {
109 fprintf(stderr,
"vdr: cannot set supplemental group ids for user %s: %s\n", user->pw_name, strerror(errno));
112 if (setuid(user->pw_uid) < 0) {
113 fprintf(stderr,
"vdr: cannot set user id %u: %s\n", (
unsigned int)user->pw_uid, strerror(errno));
116 if (UserDump && prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) < 0)
117 fprintf(stderr,
"vdr: warning - cannot set dumpable: %s\n", strerror(errno));
118 setenv(
"HOME", user->pw_dir, 1);
119 setenv(
"USER", user->pw_name, 1);
120 setenv(
"LOGNAME", user->pw_name, 1);
121 setenv(
"SHELL", user->pw_shell, 1);
129 cap_t caps_all = cap_get_proc();
131 fprintf(stderr,
"vdr: cap_get_proc failed: %s\n", strerror(errno));
134 cap_flag_value_t cap_flag_value;
135 if (cap_get_flag(caps_all, CAP_SYS_TIME, CAP_PERMITTED , &cap_flag_value)) {
136 fprintf(stderr,
"vdr: cap_get_flag failed: %s\n", strerror(errno));
140 if (cap_flag_value == CAP_SET)
141 caps = cap_from_text(
"= cap_sys_nice,cap_sys_time,cap_net_raw=ep");
143 fprintf(stdout,
"vdr: OS does not support cap_sys_time\n");
144 caps = cap_from_text(
"= cap_sys_nice,cap_net_raw=ep");
147 fprintf(stderr,
"vdr: cap_from_text failed: %s\n", strerror(errno));
150 if (cap_set_proc(caps) == -1) {
151 fprintf(stderr,
"vdr: cap_set_proc failed: %s\n", strerror(errno));
162 if (prctl(PR_SET_KEEPCAPS, On ? 1 : 0, 0, 0, 0) != 0) {
163 fprintf(stderr,
"vdr: prctl failed\n");
189 esyslog(
"PANIC: watchdog timer expired - exiting!");
191 sd_notify(0,
"STOPPING=1\nSTATUS=PANIC");
196 int main(
int argc,
char *argv[])
200 struct termios savedTm;
201 bool HasStdin = (tcgetpgrp(STDIN_FILENO) == getpid() || getppid() != (pid_t)1) && tcgetattr(STDIN_FILENO, &savedTm) == 0;
205 setlocale(LC_ALL,
"");
209 #define dd(a, b) (*a ? a : b)
210 #define DEFAULTSVDRPPORT 6419
211 #define DEFAULTWATCHDOG 0
212 #define DEFAULTVIDEODIR VIDEODIR
213 #define DEFAULTCONFDIR dd(CONFDIR, VideoDirectory)
214 #define DEFAULTARGSDIR dd(ARGSDIR, "/etc/vdr/conf.d")
215 #define DEFAULTCACHEDIR dd(CACHEDIR, VideoDirectory)
216 #define DEFAULTRESDIR dd(RESDIR, ConfigDirectory)
217 #define DEFAULTPLUGINDIR PLUGINDIR
218 #define DEFAULTLOCDIR LOCDIR
219 #define DEFAULTEPGDATAFILENAME "epg.data"
221 bool StartedAsRoot =
false;
222 const char *VdrUser = NULL;
223 bool UserDump =
false;
225 const char *AudioCommand = NULL;
227 const char *ConfigDirectory = NULL;
228 const char *CacheDirectory = NULL;
229 const char *ResourceDirectory = NULL;
232 bool DisplayHelp =
false;
233 bool DisplayVersion =
false;
234 bool DaemonMode =
false;
235 int SysLogTarget = LOG_USER;
236 bool MuteAudio =
false;
238 const char *Terminal = NULL;
240 #ifndef DEPRECATED_VDR_CHARSET_OVERRIDE
241 #define DEPRECATED_VDR_CHARSET_OVERRIDE 0
243 #if DEPRECATED_VDR_CHARSET_OVERRIDE
249 const char *LircDevice = NULL;
250 #if !defined(REMOTE_KBD)
253 #if defined(REMOTE_LIRC)
254 LircDevice = LIRC_DEVICE;
256 #if defined(VDR_USER)
260 time_t SdWatchdog = 0;
261 int SdWatchdogTimeout = 0;
266 Args =
new cArgs(argv[0]);
276 static struct option long_options[] = {
277 {
"audio", required_argument, NULL,
'a' },
278 {
"cachedir", required_argument, NULL,
'c' | 0x100 },
279 {
"chartab", required_argument, NULL,
'c' | 0x200 },
280 {
"config", required_argument, NULL,
'c' },
281 {
"daemon", no_argument, NULL,
'd' },
282 {
"device", required_argument, NULL,
'D' },
283 {
"dirnames", required_argument, NULL,
'd' | 0x100 },
284 {
"edit", required_argument, NULL,
'e' | 0x100 },
285 {
"epgfile", required_argument, NULL,
'E' },
286 {
"filesize", required_argument, NULL,
'f' | 0x100 },
287 {
"genindex", required_argument, NULL,
'g' | 0x100 },
288 {
"grab", required_argument, NULL,
'g' },
289 {
"help", no_argument, NULL,
'h' },
290 {
"instance", required_argument, NULL,
'i' },
291 {
"lib", required_argument, NULL,
'L' },
292 {
"lirc", optional_argument, NULL,
'l' | 0x100 },
293 {
"localedir",required_argument, NULL,
'l' | 0x200 },
294 {
"log", required_argument, NULL,
'l' },
295 {
"mute", no_argument, NULL,
'm' },
296 {
"no-kbd", no_argument, NULL,
'n' | 0x100 },
297 {
"plugin", required_argument, NULL,
'P' },
298 {
"port", required_argument, NULL,
'p' },
299 {
"record", required_argument, NULL,
'r' },
300 {
"resdir", required_argument, NULL,
'r' | 0x100 },
301 {
"showargs", optional_argument, NULL,
's' | 0x200 },
302 {
"shutdown", required_argument, NULL,
's' },
303 {
"split", no_argument, NULL,
's' | 0x100 },
304 {
"terminal", required_argument, NULL,
't' },
305 {
"updindex", required_argument, NULL,
'u' | 0x200 },
306 {
"user", required_argument, NULL,
'u' },
307 {
"userdump", no_argument, NULL,
'u' | 0x100 },
308 {
"version", no_argument, NULL,
'V' },
309 {
"vfat", no_argument, NULL,
'v' | 0x100 },
310 {
"video", required_argument, NULL,
'v' },
311 {
"watchdog", required_argument, NULL,
'w' },
312 { NULL, no_argument, NULL, 0 }
316 while ((c = getopt_long(argc, argv,
"a:c:dD:e:E:g:hi:l:L:mp:P:r:s:t:u:v:Vw:", long_options, NULL)) != -1) {
318 case 'a': AudioCommand = optarg;
321 CacheDirectory = optarg;
326 case 'c': ConfigDirectory = optarg;
328 case 'd': DaemonMode =
true;
330 case 'D':
if (*optarg ==
'-') {
335 int n = atoi(optarg);
341 fprintf(stderr,
"vdr: invalid DVB device number: %s\n", optarg);
346 int n = strtol(s, &s, 10);
347 if (n <= 0 || n >= PATH_MAX) {
348 fprintf(stderr,
"vdr: invalid directory path length: %s\n", optarg);
355 fprintf(stderr,
"vdr: invalid delimiter: %s\n", optarg);
363 int n = strtol(s, &s, 10);
364 if (n <= 0 || n > NAME_MAX) {
365 fprintf(stderr,
"vdr: invalid directory name length: %s\n", optarg);
372 fprintf(stderr,
"vdr: invalid delimiter: %s\n", optarg);
379 int n = strtol(s, &s, 10);
380 if (n != 0 && n != 1) {
381 fprintf(stderr,
"vdr: invalid directory encoding: %s\n", optarg);
386 fprintf(stderr,
"vdr: unexpected data: %s\n", optarg);
393 case 'E': EpgDataFileName = (*optarg !=
'-' ? optarg : NULL);
406 case 'h': DisplayHelp =
true;
413 fprintf(stderr,
"vdr: invalid instance id: %s\n", optarg);
416 char *p = strchr(optarg,
'.');
420 int l = atoi(optarg);
421 if (0 <= l && l <= 3) {
428 if (0 <= l && l <= 7) {
429 int targets[] = { LOG_LOCAL0, LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4, LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7 };
430 SysLogTarget = targets[l];
438 fprintf(stderr,
"vdr: invalid log level: %s\n", optarg);
441 case 'L':
if (access(optarg, R_OK | X_OK) == 0)
444 fprintf(stderr,
"vdr: can't access plugin directory: %s\n", optarg);
449 LircDevice = optarg ? optarg : LIRC_DEVICE;
452 if (access(optarg, R_OK | X_OK) == 0)
453 LocaleDirectory = optarg;
455 fprintf(stderr,
"vdr: can't access locale directory: %s\n", optarg);
459 case 'm': MuteAudio =
true;
465 SVDRPport = atoi(optarg);
467 fprintf(stderr,
"vdr: invalid port number: %s\n", optarg);
471 case 'P': PluginManager.
AddPlugin(optarg);
476 ResourceDirectory = optarg;
487 fprintf(stderr,
"vdr: can't read arguments from directory: %s\n", ArgsDir);
492 for (
int i = 1; i < c; i++)
493 printf(
"%s\n", v[i]);
496 case 't': Terminal = optarg;
497 if (access(Terminal, R_OK | W_OK) < 0) {
498 fprintf(stderr,
"vdr: can't access terminal: %s\n", Terminal);
502 case 'u':
if (*optarg)
510 case 'V': DisplayVersion =
true;
517 case 'v': VideoDirectory = optarg;
518 while (optarg && *optarg && optarg[strlen(optarg) - 1] ==
'/')
519 optarg[strlen(optarg) - 1] = 0;
523 int t = atoi(optarg);
529 fprintf(stderr,
"vdr: invalid watchdog timeout: %s\n", optarg);
537 if (VdrUser && geteuid() == 0) {
538 StartedAsRoot =
true;
539 if (strcmp(VdrUser,
"root") && strcmp(VdrUser,
"0")) {
542 if (!
SetUser(VdrUser, UserDump))
553 if (DisplayHelp || DisplayVersion) {
558 printf(
"Usage: vdr [OPTIONS]\n\n"
559 " -a CMD, --audio=CMD send Dolby Digital audio to stdin of command CMD\n"
560 " --cachedir=DIR save cache files in DIR (default: %s)\n"
561 " --chartab=CHARACTER_TABLE\n"
562 " set the character table to use for strings in the\n"
563 " DVB data stream that don't begin with a character\n"
564 " table indicator, but don't use the standard default\n"
565 " character table (for instance ISO-8859-9)\n"
566 " -c DIR, --config=DIR read config files from DIR (default: %s)\n"
567 " -d, --daemon run in daemon mode\n"
568 " -D NUM, --device=NUM use only the given DVB device (NUM = 0, 1, 2...)\n"
569 " there may be several -D options (default: all DVB\n"
570 " devices will be used); if -D- is given, no DVB\n"
571 " devices will be used at all, independent of any\n"
572 " other -D options\n"
573 " --dirnames=PATH[,NAME[,ENC]]\n"
574 " set the maximum directory path length to PATH\n"
575 " (default: %d); if NAME is also given, it defines\n"
576 " the maximum directory name length (default: %d);\n"
577 " the optional ENC can be 0 or 1, and controls whether\n"
578 " special characters in directory names are encoded as\n"
579 " hex values (default: 0); if PATH or NAME are left\n"
580 " empty (as in \",,1\" to only set ENC), the defaults\n"
582 " --edit=REC cut recording REC and exit\n"
583 " -E FILE, --epgfile=FILE write the EPG data into the given FILE (default is\n"
584 " '%s' in the cache directory)\n"
585 " '-E-' disables this\n"
586 " if FILE is a directory, the default EPG file will be\n"
587 " created in that directory\n"
588 " --filesize=SIZE limit video files to SIZE bytes (default is %dM)\n"
589 " only useful in conjunction with --edit\n"
590 " --genindex=REC generate index for recording REC and exit\n"
591 " -g DIR, --grab=DIR write images from the SVDRP command GRAB into the\n"
592 " given DIR; DIR must be the full path name of an\n"
593 " existing directory, without any \"..\", double '/'\n"
594 " or symlinks (default: none, same as -g-)\n"
595 " -h, --help print this help and exit\n"
596 " -i ID, --instance=ID use ID as the id of this VDR instance (default: 0)\n"
597 " -l LEVEL, --log=LEVEL set log level (default: 3)\n"
598 " 0 = no logging, 1 = errors only,\n"
599 " 2 = errors and info, 3 = errors, info and debug\n"
600 " if logging should be done to LOG_LOCALn instead of\n"
601 " LOG_USER, add '.n' to LEVEL, as in 3.7 (n=0..7)\n"
602 " -L DIR, --lib=DIR search for plugins in DIR (default is %s)\n"
603 " --lirc[=PATH] use a LIRC remote control device, attached to PATH\n"
605 " --localedir=DIR search for locale files in DIR (default is\n"
607 " -m, --mute mute audio of the primary DVB device at startup\n"
608 " --no-kbd don't use the keyboard as an input device\n"
609 " -p PORT, --port=PORT use PORT for SVDRP (default: %d)\n"
610 " 0 turns off SVDRP\n"
611 " -P OPT, --plugin=OPT load a plugin defined by the given options\n"
612 " -r CMD, --record=CMD call CMD before and after a recording, and after\n"
613 " a recording has been edited or deleted\n"
614 " --resdir=DIR read resource files from DIR (default: %s)\n"
615 " -s CMD, --shutdown=CMD call CMD to shutdown the computer\n"
616 " --split split edited files at the editing marks (only\n"
617 " useful in conjunction with --edit)\n"
618 " --showargs[=DIR] print the arguments read from DIR and exit\n"
620 " -t TTY, --terminal=TTY controlling tty\n"
621 " -u USER, --user=USER run as user USER; only applicable if started as\n"
622 " root; USER can be a user name or a numerical id\n"
623 " --updindex=REC update index for recording REC and exit\n"
624 " --userdump allow coredumps if -u is given (debugging)\n"
625 " -v DIR, --video=DIR use DIR as video directory (default: %s)\n"
626 " -V, --version print version information and exit\n"
627 " --vfat for backwards compatibility (same as\n"
628 " --dirnames=250,40,1)\n"
629 " -w SEC, --watchdog=SEC activate the watchdog timer with a timeout of SEC\n"
630 " seconds (default: %d); '0' disables the watchdog\n"
652 printf(
"Plugins: vdr -P\"name [OPTIONS]\"\n\n");
653 for (
int i = 0; ; i++) {
658 if (DisplayHelp && help) {
673 openlog(
"vdr", LOG_CONS, SysLogTarget);
678 fprintf(stderr,
"vdr: can't access video directory %s\n", VideoDirectory);
685 if (daemon(1, 0) == -1) {
686 fprintf(stderr,
"vdr: %m\n");
693 stdin = freopen(Terminal,
"r", stdin);
694 stdout = freopen(Terminal,
"w", stdout);
695 stderr = freopen(Terminal,
"w", stderr);
697 tcgetattr(STDIN_FILENO, &savedTm);
701 if (StartedAsRoot && VdrUser)
702 isyslog(
"switched to user '%s'", VdrUser);
709 char *CodeSet = NULL;
710 if (setlocale(LC_CTYPE,
""))
711 CodeSet = nl_langinfo(CODESET);
713 char *LangEnv = getenv(
"LANG");
715 CodeSet = strchr(LangEnv,
'.');
722 isyslog(
"codeset is '%s' - %s", CodeSet, known ?
"known" :
"unknown");
725 #if DEPRECATED_VDR_CHARSET_OVERRIDE
726 if (DeprecatedVdrCharsetOverride)
727 isyslog(
"use of environment variable VDR_CHARSET_OVERRIDE (%s) is deprecated!", DeprecatedVdrCharsetOverride);
743 int LastTimerChannel = -1;
744 int PreviousChannel[2] = { 1, 1 };
745 int PreviousChannelIndex = 0;
746 time_t LastChannelChanged = time(NULL);
747 time_t LastInteract = 0;
748 int MaxLatencyTime = 0;
749 bool InhibitEpgScan =
false;
750 bool IsInfoMenu =
false;
751 cSkin *CurrentSkin = NULL;
752 int OldPrimaryDVB = 0;
761 if (!ConfigDirectory)
767 if (!ResourceDirectory)
789 const char *msg =
"no fonts available - OSD will not show any text!";
790 fprintf(stderr,
"vdr: %s\n", msg);
800 if (EpgDataFileName) {
801 const char *EpgDirectory = NULL;
803 EpgDirectory = EpgDataFileName;
806 else if (*EpgDataFileName !=
'/' && *EpgDataFileName !=
'.')
807 EpgDirectory = CacheDirectory;
812 EpgDataReader.
Start();
834 isyslog(
"trying device number %d instead", i + 1);
842 const char *msg =
"no primary device found - using first device!";
843 fprintf(stderr,
"vdr: %s\n", msg);
848 const char *msg =
"no primary device found - giving up!";
849 fprintf(stderr,
"vdr: %s\n", msg);
889 if (!DaemonMode && HasStdin && UseKbd)
935 if (signal(SIGHUP,
SignalHandler) == SIG_IGN) signal(SIGHUP, SIG_IGN);
936 if (signal(SIGINT,
SignalHandler) == SIG_IGN) signal(SIGINT, SIG_IGN);
937 if (signal(SIGTERM,
SignalHandler) == SIG_IGN) signal(SIGTERM, SIG_IGN);
938 if (signal(SIGPIPE,
SignalHandler) == SIG_IGN) signal(SIGPIPE, SIG_IGN);
939 if (WatchdogTimeout > 0)
940 if (signal(SIGALRM,
Watchdog) == SIG_IGN) signal(SIGALRM, SIG_IGN);
944 if (WatchdogTimeout > 0) {
945 dsyslog(
"setting watchdog timer to %d seconds", WatchdogTimeout);
946 alarm(WatchdogTimeout);
950 if (sd_watchdog_enabled(0, NULL) > 0) {
952 SdWatchdog = time(NULL);
953 sd_watchdog_enabled(0, &timeout);
954 SdWatchdogTimeout = (int)timeout/1000000;
955 dsyslog(
"SD_WATCHDOG enabled with timeout set to %d seconds", SdWatchdogTimeout);
960 sd_notify(0,
"READY=1\nSTATUS=Ready");
970 #define DELETE_MENU ((IsInfoMenu &= (Menu == NULL)), delete Menu, Menu = NULL)
973 #ifdef DEBUGRINGBUFFERS
974 cRingBufferLinear::PrintDebugRBL();
979 time_t Now = time(NULL);
983 static time_t lastTime = 0;
988 if (Channel && (Channel->
Vpid() || Channel->
Apid(0) || Channel->
Dpid(0))) {
991 else if (LastTimerChannel > 0) {
992 Channel = Channels->GetByNumber(LastTimerChannel);
998 LastTimerChannel = -1;
1006 static time_t lastOsdSizeUpdate = 0;
1007 if (Now != lastOsdSizeUpdate) {
1009 static int OsdState = 0;
1014 lastOsdSizeUpdate = Now;
1018 if (WatchdogTimeout > 0) {
1019 int LatencyTime = WatchdogTimeout - alarm(WatchdogTimeout);
1020 if (LatencyTime > MaxLatencyTime) {
1021 MaxLatencyTime = LatencyTime;
1022 dsyslog(
"max. latency time %d seconds", MaxLatencyTime);
1027 if (SdWatchdogTimeout && (Now - SdWatchdog) * 2 > SdWatchdogTimeout) {
1028 sd_notify(0,
"WATCHDOG=1");
1034 static bool ChannelsRenumber =
false;
1038 static time_t ChannelSaveTimeout = 0;
1040 static cStateKey ChannelsStateKey(
true);
1041 static int ChannelsModifiedByUser = 0;
1044 if (ChannelSaveTimeout != 1) {
1047 ChannelSaveTimeout = 1;
1048 else if (!ChannelSaveTimeout)
1052 ChannelSaveTimeout = 1;
1055 ChannelSaveTimeout = 1;
1056 if (Timers && Channels) {
1059 ChannelSaveTimeout = 0;
1062 for (
const cChannel *Channel = Channels->
First(); Channel; Channel = Channels->
Next(Channel)) {
1065 ChannelsRenumber =
true;
1071 isyslog(
"retuning due to modification of channel %d (%s)", Channel->Number(), Channel->Name());
1072 Channels->
SwitchTo(Channel->Number());
1082 ChannelsStateKey.
Remove();
1085 if (ChannelSaveTimeout == 1) {
1087 ChannelsStateKey.
Reset();
1088 TimersStateKey.
Reset();
1096 LastChannelChanged = Now;
1098 if (Now - LastChannelChanged >=
Setup.
ZapTimeout && LastChannel != PreviousChannel[PreviousChannelIndex])
1099 PreviousChannel[PreviousChannelIndex ^= 1] = LastChannel;
1108 SchedulesStateKey.
Reset();
1109 bool TimersModified =
false;
1113 TimersModified =
true;
1114 SchedulesStateKey.
Remove();
1116 TimersStateKey.
Remove(TimersModified);
1121 bool TimersModified =
false;
1123 TimersModified =
true;
1127 Timer->SetPending(
true);
1129 LastTimerChannel = Timer->Channel()->Number();
1130 TimersModified =
true;
1133 static time_t LastTimerCheck = 0;
1135 InhibitEpgScan =
false;
1136 for (
cTimer *Timer = Timers->
First(); Timer; Timer = Timers->
Next(Timer)) {
1137 if (Timer->Remote())
1139 bool InVpsMargin =
false;
1140 bool NeedsTransponder =
false;
1141 if (Timer->HasFlags(
tfActive) && !Timer->Recording()) {
1142 if (Timer->HasFlags(
tfVps)) {
1145 Timer->SetInVpsMargin(InVpsMargin);
1147 else if (Timer->Event()) {
1148 InVpsMargin = Timer->Event()->StartTime() <= Now && Now < Timer->Event()->EndTime();
1153 const cSchedule *Schedule = Schedules->GetSchedule(Timer->Channel());
1154 InVpsMargin = !Schedule;
1157 InhibitEpgScan |= InVpsMargin | NeedsTransponder;
1162 if (NeedsTransponder || InVpsMargin) {
1165 if (!Device && InVpsMargin)
1173 dsyslog(
"switching device %d to channel %d %s (%s)", Device->
DeviceNumber() + 1, Timer->Channel()->Number(), *Timer->Channel()->GetChannelID().ToString(), Timer->Channel()->Name());
1182 LastTimerCheck = Now;
1186 TimersModified =
true;
1189 if (MaxPriority >= 0)
1191 TimersStateKey.
Remove(TimersModified);
1194 if (ChannelsRenumber) {
1196 Channels->ReNumber();
1197 ChannelsRenumber =
false;
1211 if (!NeedsFastResponse) {
1236 bool WasOpen = Interact != NULL;
1237 bool WasMenu = Interact && Interact->
IsMenu();
1275 #define DirectMainFunction(function)\
1279 Menu = new cMenuMain(function);\
1301 esyslog(
"ERROR: unknown plugin '%s'", PluginName);
1393 isyslog(
"Power button pressed");
1420 Interact = Menu ? Menu : Control;
1424 if (state ==
osUnknown && Interact != Control) {
1427 if (state ==
osEnd) {
1468 case osEnd:
if (Interact == Menu)
1488 if (PreviousChannel[PreviousChannelIndex ^ 1] == LastChannel || LastChannel != PreviousChannel[0] && LastChannel != PreviousChannel[1])
1489 PreviousChannelIndex ^= 1;
1491 Channels->SwitchTo(PreviousChannel[PreviousChannelIndex ^= 1]);
1514 case kOk: LastChannel = -1;
break;
1529 if (!InhibitEpgScan)
1542 if (NewPrimaryDVB != OldPrimaryDVB) {
1549 OldPrimaryDVB = NewPrimaryDVB;
1602 esyslog(
"emergency exit requested - shutting down");
1607 signal(SIGHUP, SIG_DFL);
1608 signal(SIGINT, SIG_DFL);
1609 signal(SIGTERM, SIG_DFL);
1610 signal(SIGPIPE, SIG_DFL);
1611 signal(SIGALRM, SIG_DFL);
1640 if (WatchdogTimeout > 0)
1641 dsyslog(
"max. latency time %d seconds", MaxLatencyTime);
1650 tcsetattr(STDIN_FILENO, TCSANOW, &savedTm);
1653 sd_notify(0,
"STOPPING=1\nSTATUS=Startup failed, exiting");
1655 sd_notify(0,
"STOPPING=1\nSTATUS=Exiting");
#define CHANNELMOD_RETUNE
#define CHANNELMOD_TRANSP
#define LOCK_CHANNELS_READ
#define LOCK_CHANNELS_WRITE
cChannelCamRelations ChannelCamRelations
cCiResourceHandlers CiResourceHandlers
bool CamResponsesLoad(const char *FileName, bool AllowComments, bool MustExist)
char ** GetArgv(void) const
bool ReadDirectory(const char *Directory)
bool WaitForAllCamSlotsReady(int Timeout=0)
Waits until all CAM slots have become ready, or the given Timeout (seconds) has expired.
void Load(const char *FileName)
bool ModifiedByUser(int &State) const
Returns true if the channels have been modified by the user since the last call to this function with...
static const cChannels * GetChannelsRead(cStateKey &StateKey, int TimeoutMs=0)
Gets the list of channels for read access.
bool SwitchTo(int Number) const
static bool Load(const char *FileName, bool AllowComments=false, bool MustExist=false)
static void SetSystemCharacterTable(const char *CharacterTable)
bool Load(const char *FileName=NULL, bool AllowComments=false, bool MustExist=false)
static void Shutdown(void)
virtual cOsdObject * GetInfo(void)
Returns an OSD object that displays information about the currently played programme.
static cControl * Control(bool Hidden=false)
Old version of this function, for backwards compatibility with plugins.
static void Launch(cControl *Control)
virtual void Hide(void)=0
bool Update(void)
Update status display of the countdown.
void Start(const char *Message, int Seconds)
Start the 5 minute shutdown warning countdown.
void Cancel(void)
Cancel the 5 minute shutdown warning countdown.
bool Done(void)
Check if countdown timer has run out without canceling.
bool IsPrimaryDevice(void) const
static bool WaitForAllDevicesReady(int Timeout=0)
Waits until all devices have become ready, or the given Timeout (seconds) has expired.
static cDevice * ActualDevice(void)
Returns the actual receiving device in case of Transfer Mode, or the primary device otherwise.
static void SetUseDevice(int n)
Sets the 'useDevice' flag of the given device.
static cDevice * GetDevice(int Index)
Gets the device with the given Index.
static void Shutdown(void)
Closes down all devices.
void SetOccupied(int Seconds)
Sets the occupied timeout for this device to the given number of Seconds, This can be used to tune a ...
bool SwitchChannel(const cChannel *Channel, bool LiveView)
Switches the device to the given Channel, initiating transfer mode if necessary.
int DeviceNumber(void) const
Returns the number of this device (0 ... numDevices - 1).
static int CurrentChannel(void)
Returns the number of the current channel on the primary device.
static bool SetPrimaryDevice(int n)
Sets the primary device to 'n'.
void StopReplay(void)
Stops the current replay session (if any).
void SetVolume(int Volume, bool Absolute=false)
Sets the volume to the given value, either absolutely or relative to the current volume.
static int NumDevices(void)
Returns the total number of devices.
virtual bool HasDecoder(void) const
Tells whether this device has an MPEG decoder.
virtual bool HasProgramme(void) const
Returns true if the device is currently showing any programme to the user, either through replaying o...
static int CurrentVolume(void)
virtual bool IsTunedToTransponder(const cChannel *Channel) const
Returns true if this device is currently tuned to the given Channel's transponder.
static cDevice * PrimaryDevice(void)
Returns the primary device.
static cDevice * GetDeviceForTransponder(const cChannel *Channel, int Priority)
Returns a device that is not currently "occupied" and can be tuned to the transponder of the given Ch...
bool ToggleMute(void)
Turns the volume off or on and returns the new mute state.
bool Load(const char *FileName, bool AllowComments=false, bool MustExist=false)
static void Process(eKeys Key)
static cDisplaySubtitleTracks * Create(void)
static cDisplayTracks * Create(void)
static void Process(eKeys Key)
static cDisplayVolume * Create(void)
static void Process(eKeys Key)
static bool BondDevices(const char *Bondings)
Bonds the devices as defined in the given Bondings string.
static bool useDvbDevices
static bool Initialize(void)
Initializes the DVB devices.
static cString GetFontFileName(const char *FontName)
Returns the actual font file name for the given FontName.
bool Confirm(const char *s, int Seconds=10, bool WaitForTimeout=false)
eKeys GetKey(bool Wait=true)
const cKeyMacro * Get(eKeys Key)
void SetSyncStateKey(cStateKey &StateKey)
When making changes to this list (while holding a write lock) that shall not affect some other code t...
void Purge(bool Force=false)
const T * Next(const T *Object) const
< Returns the element immediately before Object in this list, or NULL if Object is the first element ...
const T * First(void) const
Returns the first element in this list, or NULL if the list is empty.
static cOsdObject * PluginOsdObject(void)
bool Load(const char *FileName)
virtual bool NeedsFastResponse(void)
virtual eOSState ProcessKey(eKeys Key)
static bool OsdSizeChanged(int &State)
Checks if the OSD size has changed and a currently displayed OSD needs to be redrawn.
static void Shutdown(void)
Shuts down the OSD provider facility by deleting the current OSD provider.
static void UpdateOsdSize(bool Force=false)
Inquires the actual size of the video display and adjusts the OSD and font sizes accordingly.
static int IsOpen(void)
Returns true if there is currently a level 0 OSD open.
void MainThreadHook(void)
void SetDirectory(const char *Directory)
bool InitializePlugins(void)
void AddPlugin(const char *Args)
static bool HasPlugins(void)
bool LoadPlugins(bool Log=false)
void Shutdown(bool Log=false)
static cPlugin * GetPlugin(int Index)
virtual const char * CommandLineHelp(void)
virtual const char * Description(void)=0
static void SetCacheDirectory(const char *Dir)
virtual const char * Version(void)=0
virtual cOsdObject * MainMenuAction(void)
static void SetConfigDirectory(const char *Dir)
static void SetResourceDirectory(const char *Dir)
static cPositioner * GetPositioner(void)
Returns a previously created positioner.
static void DestroyPositioner(void)
Destroys a previously created positioner.
static void ChannelDataModified(const cChannel *Channel)
static bool Process(cTimers *Timers, time_t t)
static bool PauseLiveVideo(void)
static void Shutdown(void)
static bool Start(cTimers *Timers, cTimer *Timer, bool Pause=false)
static void SetCommand(const char *Command)
void DelAll(void)
Deletes/terminates all operations.
bool Finished(bool &Error)
Returns true if all operations in the list have been finished.
static void Update(bool Wait=false)
Triggers an update of the list of recordings, which will run as a separate thread if Wait is false.
static bool NeedsUpdate(void)
static const char * GetPlugin(void)
Returns the name of the plugin that was set with a previous call to PutMacro() or CallPlugin().
bool Put(uint64_t Code, bool Repeat=false, bool Release=false)
static bool PutMacro(eKeys Key)
static time_t LastActivity(void)
Absolute time when last key was delivered by Get().
static const char * LastReplayed(void)
bool PresentSeenWithin(int Seconds) const
static const cSchedules * GetSchedulesRead(cStateKey &StateKey, int TimeoutMs=0)
Gets the list of schedules for read access.
static void SetEpgDataFileName(const char *FileName)
static void Cleanup(bool Force=false)
bool Load(const char *FileName, bool AllowComments=false, bool MustExist=false)
char OSDTheme[MaxThemeName]
char OSDSkin[MaxSkinName]
bool Load(const char *FileName)
char FontOsd[MAXFONTNAME]
void CheckManualStart(int ManualStart)
Check whether the next timer is in ManualStart time window.
void SetShutdownCommand(const char *ShutdownCommand)
Set the command string for shutdown command.
bool ConfirmShutdown(bool Ask)
Check for background activity that blocks shutdown.
bool EmergencyExitRequested(void)
Returns true if an emergency exit was requested.
void SetRetry(int Seconds)
Set shutdown retry so that VDR will not try to automatically shut down within Seconds.
bool Retry(time_t AtTime=0)
Check whether its time to re-try the shutdown.
bool IsUserInactive(time_t AtTime=0)
Check whether VDR is in interactive mode or non-interactive mode (waiting for shutdown).
bool DoShutdown(bool Force)
Call the shutdown script with data of the next pending timer.
bool ConfirmRestart(bool Ask)
Check for background activity that blocks restart.
void Exit(int ExitCode)
Set VDR exit code and initiate end of VDR main loop.
void SetUserInactiveTimeout(int Seconds=-1, bool Force=false)
Set the time in the future when VDR will switch into non-interactive mode or power down.
bool DoExit(void)
Check if an exit code was set, and VDR should exit.
void SetUserInactive(void)
Set VDR manually into non-interactive mode from now on.
int GetExitCode(void)
Get the currently set exit code of VDR.
bool SetCurrent(const char *Name=NULL)
Sets the current skin to the one indicated by name.
eKeys Message(eMessageType Type, const char *s, int Seconds=0)
Displays the given message, either through a currently visible display object that is capable of doin...
cSkin * Current(void)
Returns a pointer to the current skin.
virtual void Clear(void)
Free up all registered skins.
void ProcessQueuedMessages(void)
Processes the first queued message, if any.
int QueueMessage(eMessageType Type, const char *s, int Seconds=0, int Timeout=0)
Like Message(), but this function may be called from a background thread.
void Remove(bool IncState=true)
Removes this key from the lock it was previously used with.
void Reset(void)
Resets the state of this key, so that the next call to a lock's Lock() function with this key will re...
bool StateChanged(void)
Returns true if this key is used for obtaining a write lock, and the lock's state differs from that o...
static void MsgChannelChange(const cChannel *Channel)
static void SetThemesDirectory(const char *ThemesDirectory)
bool Load(const char *SkinName)
static void SetMainThreadId(void)
void bool Start(void)
Sets the description of this thread, which will be used when logging starting or stopping of the thre...
bool Active(void)
Checks whether the thread is still alive.
static tThreadId ThreadId(void)
static bool Load(const char *FileName)
int GetMaxPriority(void) const
Returns the maximum priority of all local timers that are currently recording.
static cTimers * GetTimersWrite(cStateKey &StateKey, int TimeoutMs=0)
Gets the list of timers for write access.
static const cTimers * GetTimersRead(cStateKey &StateKey, int TimeoutMs=0)
Gets the list of timers for read access.
const cTimer * GetMatch(time_t t) const
bool SetEvents(const cSchedules *Schedules)
static void Destroy(void)
static void SetName(const char *Name)
cNestedItemList RecordingCommands
bool CutRecording(const char *FileName)
void ReportEpgBugFixStats(bool Force)
#define LOCK_SCHEDULES_READ
void I18nInitialize(const char *LocaleDir)
Detects all available locales and loads the language names and codes.
bool SetSystemCharacterTable(const char *CharacterTable)
static char * OverrideCharacterTable
bool SetOverrideCharacterTable(const char *CharacterTable)
bool GenerateIndex(const char *FileName, bool Update)
Generates the index of the existing recording with the given FileName.
void AssertFreeDiskSpace(int Priority, bool Force)
The special Priority value -1 means that we shall get rid of any deleted recordings faster than norma...
cRecordingsHandler RecordingsHandler
void RemoveDeletedRecordings(void)
#define MAXVIDEOFILESIZEDEFAULT
#define MAXVIDEOFILESIZETS
cShutdownHandler ShutdownHandler
cSourceParams SourceParams
static tChannelID FromString(const char *s)
void StopSVDRPHandler(void)
void SetSVDRPGrabImageDir(const char *GrabImageDir)
void StartSVDRPHandler(void)
void SetSVDRPPorts(int TcpPort, int UdpPort)
cStateKey StateKeySVDRPRemoteTimersPoll
Controls whether a change to the local list of timers needs to result in sending a POLL to the remote...
static bool SetUser(const char *User, bool UserDump)
#define SHUTDOWNFORCEPROMPT
int main(int argc, char *argv[])
#define TIMERLOOKAHEADTIME
#define SHUTDOWNCANCELPROMPT
#define DEFAULTEPGDATAFILENAME
static void SignalHandler(int signum)
static bool SetKeepCaps(bool On)
#define DirectMainFunction(function)
#define TIMERDEVICETIMEOUT
static bool DropCaps(void)
static void Watchdog(int signum)
#define RESTARTCANCELPROMPT
#define DEVICEREADYTIMEOUT