Go to the documentation of this file.
35 #include <sys/capability.h>
36 #include <sys/prctl.h>
38 #include <systemd/sd-daemon.h>
75 #define MINCHANNELWAIT 10 // seconds to wait between failed channel switchings
76 #define ACTIVITYTIMEOUT 60 // seconds before starting housekeeping
77 #define SHUTDOWNWAIT 300 // seconds to wait in user prompt before automatic shutdown
78 #define SHUTDOWNRETRY 360 // seconds before trying again to shut down
79 #define SHUTDOWNFORCEPROMPT 5 // seconds to wait in user prompt to allow forcing shutdown
80 #define SHUTDOWNCANCELPROMPT 5 // seconds to wait in user prompt to allow canceling shutdown
81 #define RESTARTCANCELPROMPT 5 // seconds to wait in user prompt before restarting on SIGHUP
82 #define MANUALSTART 600 // seconds the next timer must be in the future to assume manual start
83 #define CHANNELSAVEDELTA 600 // seconds before saving channels.conf after automatic modifications
84 #define DEVICEREADYTIMEOUT 30 // seconds to wait until all devices are ready
85 #define MENUTIMEOUT 120 // seconds of user inactivity after which an OSD display is closed
86 #define TIMERCHECKDELTA 10 // seconds between checks for timers that need to see their channel
87 #define TIMERDEVICETIMEOUT 8 // seconds before a device used for timer check may be reused
88 #define TIMERLOOKAHEADTIME 60 // seconds before a non-VPS timer starts and the channel is switched if possible
89 #define VPSLOOKAHEADTIME 24 // hours within which VPS timers will make sure their events are up to date
90 #define VPSUPTODATETIME 3600 // seconds before the event or schedule of a VPS timer needs to be refreshed
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 char *caps_text = cap_to_text(caps_all, NULL);
136 fprintf(stderr,
"vdr: cap_to_text failed: %s\n", strerror(errno));
139 if (cap_free(caps_all)) {
140 fprintf(stderr,
"vdr: cap_free failed: %s\n", strerror(errno));
144 if (strstr(caps_text,
"cap_sys_time"))
145 caps = cap_from_text(
"= cap_sys_nice,cap_sys_time,cap_net_raw=ep");
147 caps = cap_from_text(
"= cap_sys_nice,cap_net_raw=ep");
149 fprintf(stderr,
"vdr: cap_from_text failed: %s\n", strerror(errno));
152 if (cap_set_proc(caps) == -1) {
153 fprintf(stderr,
"vdr: cap_set_proc failed: %s\n", strerror(errno));
164 if (prctl(PR_SET_KEEPCAPS, On ? 1 : 0, 0, 0, 0) != 0) {
165 fprintf(stderr,
"vdr: prctl failed\n");
191 esyslog(
"PANIC: watchdog timer expired - exiting!");
193 sd_notify(0,
"STOPPING=1\nSTATUS=PANIC");
198 int main(
int argc,
char *argv[])
202 struct termios savedTm;
203 bool HasStdin = (tcgetpgrp(STDIN_FILENO) == getpid() || getppid() != (pid_t)1) && tcgetattr(STDIN_FILENO, &savedTm) == 0;
207 setlocale(LC_ALL,
"");
211 #define dd(a, b) (*a ? a : b)
212 #define DEFAULTSVDRPPORT 6419
213 #define DEFAULTWATCHDOG 0 // seconds
214 #define DEFAULTVIDEODIR VIDEODIR
215 #define DEFAULTCONFDIR dd(CONFDIR, VideoDirectory)
216 #define DEFAULTARGSDIR dd(ARGSDIR, "/etc/vdr/conf.d")
217 #define DEFAULTCACHEDIR dd(CACHEDIR, VideoDirectory)
218 #define DEFAULTRESDIR dd(RESDIR, ConfigDirectory)
219 #define DEFAULTPLUGINDIR PLUGINDIR
220 #define DEFAULTLOCDIR LOCDIR
221 #define DEFAULTEPGDATAFILENAME "epg.data"
223 bool StartedAsRoot =
false;
224 const char *VdrUser = NULL;
225 bool UserDump =
false;
227 const char *AudioCommand = NULL;
229 const char *ConfigDirectory = NULL;
230 const char *CacheDirectory = NULL;
231 const char *ResourceDirectory = NULL;
234 bool DisplayHelp =
false;
235 bool DisplayVersion =
false;
236 bool DaemonMode =
false;
237 int SysLogTarget = LOG_USER;
238 bool MuteAudio =
false;
240 const char *Terminal = NULL;
242 #ifndef DEPRECATED_VDR_CHARSET_OVERRIDE
243 #define DEPRECATED_VDR_CHARSET_OVERRIDE 0
245 #if DEPRECATED_VDR_CHARSET_OVERRIDE
251 const char *LircDevice = NULL;
252 #if !defined(REMOTE_KBD)
255 #if defined(REMOTE_LIRC)
256 LircDevice = LIRC_DEVICE;
258 #if defined(VDR_USER)
262 time_t SdWatchdog = 0;
263 int SdWatchdogTimeout = 0;
268 Args =
new cArgs(argv[0]);
278 static struct option long_options[] = {
279 {
"audio", required_argument, NULL,
'a' },
280 {
"cachedir", required_argument, NULL,
'c' | 0x100 },
281 {
"chartab", required_argument, NULL,
'c' | 0x200 },
282 {
"config", required_argument, NULL,
'c' },
283 {
"daemon", no_argument, NULL,
'd' },
284 {
"device", required_argument, NULL,
'D' },
285 {
"dirnames", required_argument, NULL,
'd' | 0x100 },
286 {
"edit", required_argument, NULL,
'e' | 0x100 },
287 {
"epgfile", required_argument, NULL,
'E' },
288 {
"filesize", required_argument, NULL,
'f' | 0x100 },
289 {
"genindex", required_argument, NULL,
'g' | 0x100 },
290 {
"grab", required_argument, NULL,
'g' },
291 {
"help", no_argument, NULL,
'h' },
292 {
"instance", required_argument, NULL,
'i' },
293 {
"lib", required_argument, NULL,
'L' },
294 {
"lirc", optional_argument, NULL,
'l' | 0x100 },
295 {
"localedir",required_argument, NULL,
'l' | 0x200 },
296 {
"log", required_argument, NULL,
'l' },
297 {
"mute", no_argument, NULL,
'm' },
298 {
"no-kbd", no_argument, NULL,
'n' | 0x100 },
299 {
"plugin", required_argument, NULL,
'P' },
300 {
"port", required_argument, NULL,
'p' },
301 {
"record", required_argument, NULL,
'r' },
302 {
"resdir", required_argument, NULL,
'r' | 0x100 },
303 {
"showargs", optional_argument, NULL,
's' | 0x200 },
304 {
"shutdown", required_argument, NULL,
's' },
305 {
"split", no_argument, NULL,
's' | 0x100 },
306 {
"terminal", required_argument, NULL,
't' },
307 {
"updindex", required_argument, NULL,
'u' | 0x200 },
308 {
"user", required_argument, NULL,
'u' },
309 {
"userdump", no_argument, NULL,
'u' | 0x100 },
310 {
"version", no_argument, NULL,
'V' },
311 {
"vfat", no_argument, NULL,
'v' | 0x100 },
312 {
"video", required_argument, NULL,
'v' },
313 {
"watchdog", required_argument, NULL,
'w' },
314 { NULL, no_argument, NULL, 0 }
318 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) {
320 case 'a': AudioCommand = optarg;
323 CacheDirectory = optarg;
328 case 'c': ConfigDirectory = optarg;
330 case 'd': DaemonMode =
true;
332 case 'D':
if (*optarg ==
'-') {
337 int n = atoi(optarg);
343 fprintf(stderr,
"vdr: invalid DVB device number: %s\n", optarg);
348 int n = strtol(s, &s, 10);
349 if (n <= 0 || n >= PATH_MAX) {
350 fprintf(stderr,
"vdr: invalid directory path length: %s\n", optarg);
357 fprintf(stderr,
"vdr: invalid delimiter: %s\n", optarg);
365 int n = strtol(s, &s, 10);
366 if (n <= 0 || n > NAME_MAX) {
367 fprintf(stderr,
"vdr: invalid directory name length: %s\n", optarg);
374 fprintf(stderr,
"vdr: invalid delimiter: %s\n", optarg);
381 int n = strtol(s, &s, 10);
382 if (n != 0 && n != 1) {
383 fprintf(stderr,
"vdr: invalid directory encoding: %s\n", optarg);
388 fprintf(stderr,
"vdr: unexpected data: %s\n", optarg);
395 case 'E': EpgDataFileName = (*optarg !=
'-' ? optarg : NULL);
408 case 'h': DisplayHelp =
true;
415 fprintf(stderr,
"vdr: invalid instance id: %s\n", optarg);
418 char *p = strchr(optarg,
'.');
422 int l = atoi(optarg);
423 if (0 <= l && l <= 3) {
429 if (0 <= l && l <= 7) {
430 int targets[] = { LOG_LOCAL0, LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4, LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7 };
431 SysLogTarget = targets[l];
439 fprintf(stderr,
"vdr: invalid log level: %s\n", optarg);
442 case 'L':
if (access(optarg, R_OK | X_OK) == 0)
445 fprintf(stderr,
"vdr: can't access plugin directory: %s\n", optarg);
450 LircDevice = optarg ? optarg : LIRC_DEVICE;
453 if (access(optarg, R_OK | X_OK) == 0)
454 LocaleDirectory = optarg;
456 fprintf(stderr,
"vdr: can't access locale directory: %s\n", optarg);
460 case 'm': MuteAudio =
true;
466 SVDRPport = atoi(optarg);
468 fprintf(stderr,
"vdr: invalid port number: %s\n", optarg);
472 case 'P': PluginManager.
AddPlugin(optarg);
477 ResourceDirectory = optarg;
488 fprintf(stderr,
"vdr: can't read arguments from directory: %s\n", ArgsDir);
493 for (
int i = 1; i < c; i++)
494 printf(
"%s\n", v[i]);
497 case 't': Terminal = optarg;
498 if (access(Terminal, R_OK | W_OK) < 0) {
499 fprintf(stderr,
"vdr: can't access terminal: %s\n", Terminal);
503 case 'u':
if (*optarg)
511 case 'V': DisplayVersion =
true;
518 case 'v': VideoDirectory = optarg;
519 while (optarg && *optarg && optarg[strlen(optarg) - 1] ==
'/')
520 optarg[strlen(optarg) - 1] = 0;
524 int t = atoi(optarg);
530 fprintf(stderr,
"vdr: invalid watchdog timeout: %s\n", optarg);
538 if (VdrUser && geteuid() == 0) {
539 StartedAsRoot =
true;
540 if (strcmp(VdrUser,
"root") && strcmp(VdrUser,
"0")) {
543 if (!
SetUser(VdrUser, UserDump))
554 if (DisplayHelp || DisplayVersion) {
559 printf(
"Usage: vdr [OPTIONS]\n\n"
560 " -a CMD, --audio=CMD send Dolby Digital audio to stdin of command CMD\n"
561 " --cachedir=DIR save cache files in DIR (default: %s)\n"
562 " --chartab=CHARACTER_TABLE\n"
563 " set the character table to use for strings in the\n"
564 " DVB data stream that don't begin with a character\n"
565 " table indicator, but don't use the standard default\n"
566 " character table (for instance ISO-8859-9)\n"
567 " -c DIR, --config=DIR read config files from DIR (default: %s)\n"
568 " -d, --daemon run in daemon mode\n"
569 " -D NUM, --device=NUM use only the given DVB device (NUM = 0, 1, 2...)\n"
570 " there may be several -D options (default: all DVB\n"
571 " devices will be used); if -D- is given, no DVB\n"
572 " devices will be used at all, independent of any\n"
573 " other -D options\n"
574 " --dirnames=PATH[,NAME[,ENC]]\n"
575 " set the maximum directory path length to PATH\n"
576 " (default: %d); if NAME is also given, it defines\n"
577 " the maximum directory name length (default: %d);\n"
578 " the optional ENC can be 0 or 1, and controls whether\n"
579 " special characters in directory names are encoded as\n"
580 " hex values (default: 0); if PATH or NAME are left\n"
581 " empty (as in \",,1\" to only set ENC), the defaults\n"
583 " --edit=REC cut recording REC and exit\n"
584 " -E FILE, --epgfile=FILE write the EPG data into the given FILE (default is\n"
585 " '%s' in the cache directory)\n"
586 " '-E-' disables this\n"
587 " if FILE is a directory, the default EPG file will be\n"
588 " created in that directory\n"
589 " --filesize=SIZE limit video files to SIZE bytes (default is %dM)\n"
590 " only useful in conjunction with --edit\n"
591 " --genindex=REC generate index for recording REC and exit\n"
592 " -g DIR, --grab=DIR write images from the SVDRP command GRAB into the\n"
593 " given DIR; DIR must be the full path name of an\n"
594 " existing directory, without any \"..\", double '/'\n"
595 " or symlinks (default: none, same as -g-)\n"
596 " -h, --help print this help and exit\n"
597 " -i ID, --instance=ID use ID as the id of this VDR instance (default: 0)\n"
598 " -l LEVEL, --log=LEVEL set log level (default: 3)\n"
599 " 0 = no logging, 1 = errors only,\n"
600 " 2 = errors and info, 3 = errors, info and debug\n"
601 " if logging should be done to LOG_LOCALn instead of\n"
602 " LOG_USER, add '.n' to LEVEL, as in 3.7 (n=0..7)\n"
603 " -L DIR, --lib=DIR search for plugins in DIR (default is %s)\n"
604 " --lirc[=PATH] use a LIRC remote control device, attached to PATH\n"
606 " --localedir=DIR search for locale files in DIR (default is\n"
608 " -m, --mute mute audio of the primary DVB device at startup\n"
609 " --no-kbd don't use the keyboard as an input device\n"
610 " -p PORT, --port=PORT use PORT for SVDRP (default: %d)\n"
611 " 0 turns off SVDRP\n"
612 " -P OPT, --plugin=OPT load a plugin defined by the given options\n"
613 " -r CMD, --record=CMD call CMD before and after a recording, and after\n"
614 " a recording has been edited or deleted\n"
615 " --resdir=DIR read resource files from DIR (default: %s)\n"
616 " -s CMD, --shutdown=CMD call CMD to shutdown the computer\n"
617 " --split split edited files at the editing marks (only\n"
618 " useful in conjunction with --edit)\n"
619 " --showargs[=DIR] print the arguments read from DIR and exit\n"
621 " -t TTY, --terminal=TTY controlling tty\n"
622 " -u USER, --user=USER run as user USER; only applicable if started as\n"
623 " root; USER can be a user name or a numerical id\n"
624 " --updindex=REC update index for recording REC and exit\n"
625 " --userdump allow coredumps if -u is given (debugging)\n"
626 " -v DIR, --video=DIR use DIR as video directory (default: %s)\n"
627 " -V, --version print version information and exit\n"
628 " --vfat for backwards compatibility (same as\n"
629 " --dirnames=250,40,1)\n"
630 " -w SEC, --watchdog=SEC activate the watchdog timer with a timeout of SEC\n"
631 " seconds (default: %d); '0' disables the watchdog\n"
653 printf(
"Plugins: vdr -P\"name [OPTIONS]\"\n\n");
654 for (
int i = 0; ; i++) {
659 if (DisplayHelp && help) {
674 openlog(
"vdr", LOG_CONS, SysLogTarget);
679 fprintf(stderr,
"vdr: can't access video directory %s\n", VideoDirectory);
686 if (daemon(1, 0) == -1) {
687 fprintf(stderr,
"vdr: %m\n");
694 stdin = freopen(Terminal,
"r", stdin);
695 stdout = freopen(Terminal,
"w", stdout);
696 stderr = freopen(Terminal,
"w", stderr);
698 tcgetattr(STDIN_FILENO, &savedTm);
702 if (StartedAsRoot && VdrUser)
703 isyslog(
"switched to user '%s'", VdrUser);
710 char *CodeSet = NULL;
711 if (setlocale(LC_CTYPE,
""))
712 CodeSet = nl_langinfo(CODESET);
714 char *LangEnv = getenv(
"LANG");
716 CodeSet = strchr(LangEnv,
'.');
723 isyslog(
"codeset is '%s' - %s", CodeSet, known ?
"known" :
"unknown");
726 #if DEPRECATED_VDR_CHARSET_OVERRIDE
727 if (DeprecatedVdrCharsetOverride)
728 isyslog(
"use of environment variable VDR_CHARSET_OVERRIDE (%s) is deprecated!", DeprecatedVdrCharsetOverride);
744 int LastTimerChannel = -1;
745 int PreviousChannel[2] = { 1, 1 };
746 int PreviousChannelIndex = 0;
747 time_t LastChannelChanged = time(NULL);
748 time_t LastInteract = 0;
749 int MaxLatencyTime = 0;
750 bool InhibitEpgScan =
false;
751 bool IsInfoMenu =
false;
752 cSkin *CurrentSkin = NULL;
753 int OldPrimaryDVB = 0;
762 if (!ConfigDirectory)
768 if (!ResourceDirectory)
790 const char *msg =
"no fonts available - OSD will not show any text!";
791 fprintf(stderr,
"vdr: %s\n", msg);
801 if (EpgDataFileName) {
802 const char *EpgDirectory = NULL;
804 EpgDirectory = EpgDataFileName;
807 else if (*EpgDataFileName !=
'/' && *EpgDataFileName !=
'.')
808 EpgDirectory = CacheDirectory;
813 EpgDataReader.
Start();
835 isyslog(
"trying device number %d instead", i + 1);
843 const char *msg =
"no primary device found - using first device!";
844 fprintf(stderr,
"vdr: %s\n", msg);
849 const char *msg =
"no primary device found - giving up!";
850 fprintf(stderr,
"vdr: %s\n", msg);
890 if (!DaemonMode && HasStdin && UseKbd)
936 if (signal(SIGHUP,
SignalHandler) == SIG_IGN) signal(SIGHUP, SIG_IGN);
937 if (signal(SIGINT,
SignalHandler) == SIG_IGN) signal(SIGINT, SIG_IGN);
938 if (signal(SIGTERM,
SignalHandler) == SIG_IGN) signal(SIGTERM, SIG_IGN);
939 if (signal(SIGPIPE,
SignalHandler) == SIG_IGN) signal(SIGPIPE, SIG_IGN);
940 if (WatchdogTimeout > 0)
941 if (signal(SIGALRM,
Watchdog) == SIG_IGN) signal(SIGALRM, SIG_IGN);
945 if (WatchdogTimeout > 0) {
946 dsyslog(
"setting watchdog timer to %d seconds", WatchdogTimeout);
947 alarm(WatchdogTimeout);
951 if (sd_watchdog_enabled(0, NULL) > 0) {
953 SdWatchdog = time(NULL);
954 sd_watchdog_enabled(0, &timeout);
955 SdWatchdogTimeout = (int)timeout/1000000;
956 dsyslog(
"SD_WATCHDOG enabled with timeout set to %d seconds", SdWatchdogTimeout);
961 sd_notify(0,
"READY=1\nSTATUS=Ready");
971 #define DELETE_MENU ((IsInfoMenu &= (Menu == NULL)), delete Menu, Menu = NULL)
974 #ifdef DEBUGRINGBUFFERS
975 cRingBufferLinear::PrintDebugRBL();
980 time_t Now = time(NULL);
984 static time_t lastTime = 0;
989 if (Channel && (Channel->
Vpid() || Channel->
Apid(0) || Channel->
Dpid(0))) {
992 else if (LastTimerChannel > 0) {
993 Channel = Channels->GetByNumber(LastTimerChannel);
999 LastTimerChannel = -1;
1007 static time_t lastOsdSizeUpdate = 0;
1008 if (Now != lastOsdSizeUpdate) {
1010 static int OsdState = 0;
1015 lastOsdSizeUpdate = Now;
1019 if (WatchdogTimeout > 0) {
1020 int LatencyTime = WatchdogTimeout - alarm(WatchdogTimeout);
1021 if (LatencyTime > MaxLatencyTime) {
1022 MaxLatencyTime = LatencyTime;
1023 dsyslog(
"max. latency time %d seconds", MaxLatencyTime);
1028 if (SdWatchdogTimeout && (Now - SdWatchdog) * 2 > SdWatchdogTimeout) {
1029 sd_notify(0,
"WATCHDOG=1");
1035 static bool ChannelsRenumber =
false;
1039 static time_t ChannelSaveTimeout = 0;
1041 static cStateKey ChannelsStateKey(
true);
1042 static int ChannelsModifiedByUser = 0;
1045 if (ChannelSaveTimeout != 1) {
1048 ChannelSaveTimeout = 1;
1049 else if (!ChannelSaveTimeout)
1053 ChannelSaveTimeout = 1;
1056 ChannelSaveTimeout = 1;
1057 if (Timers && Channels) {
1060 ChannelSaveTimeout = 0;
1063 for (
const cChannel *Channel = Channels->
First(); Channel; Channel = Channels->
Next(Channel)) {
1066 ChannelsRenumber =
true;
1072 isyslog(
"retuning due to modification of channel %d (%s)", Channel->Number(), Channel->Name());
1073 Channels->
SwitchTo(Channel->Number());
1083 ChannelsStateKey.
Remove();
1086 if (ChannelSaveTimeout == 1) {
1088 ChannelsStateKey.
Reset();
1089 TimersStateKey.
Reset();
1097 LastChannelChanged = Now;
1099 if (Now - LastChannelChanged >=
Setup.
ZapTimeout && LastChannel != PreviousChannel[PreviousChannelIndex])
1100 PreviousChannel[PreviousChannelIndex ^= 1] = LastChannel;
1109 SchedulesStateKey.
Reset();
1110 bool TimersModified =
false;
1114 TimersModified =
true;
1115 SchedulesStateKey.
Remove();
1117 TimersStateKey.
Remove(TimersModified);
1122 bool TimersModified =
false;
1124 TimersModified =
true;
1128 Timer->SetPending(
true);
1130 LastTimerChannel = Timer->Channel()->Number();
1131 TimersModified =
true;
1134 static time_t LastTimerCheck = 0;
1136 InhibitEpgScan =
false;
1137 for (
cTimer *Timer = Timers->
First(); Timer; Timer = Timers->
Next(Timer)) {
1138 if (Timer->Remote())
1140 bool InVpsMargin =
false;
1141 bool NeedsTransponder =
false;
1142 if (Timer->HasFlags(
tfActive) && !Timer->Recording()) {
1143 if (Timer->HasFlags(
tfVps)) {
1146 Timer->SetInVpsMargin(InVpsMargin);
1148 else if (Timer->Event()) {
1149 InVpsMargin = Timer->Event()->StartTime() <= Now && Now < Timer->Event()->EndTime();
1154 const cSchedule *Schedule = Schedules->GetSchedule(Timer->Channel());
1155 InVpsMargin = !Schedule;
1158 InhibitEpgScan |= InVpsMargin | NeedsTransponder;
1163 if (NeedsTransponder || InVpsMargin) {
1166 if (!Device && InVpsMargin)
1174 dsyslog(
"switching device %d to channel %d %s (%s)", Device->
DeviceNumber() + 1, Timer->Channel()->Number(), *Timer->Channel()->GetChannelID().ToString(), Timer->Channel()->Name());
1183 LastTimerCheck = Now;
1187 TimersModified =
true;
1190 if (MaxPriority >= 0)
1192 TimersStateKey.
Remove(TimersModified);
1195 if (ChannelsRenumber) {
1197 Channels->ReNumber();
1198 ChannelsRenumber =
false;
1226 bool WasOpen = Interact != NULL;
1227 bool WasMenu = Interact && Interact->
IsMenu();
1265 #define DirectMainFunction(function)\
1267 if (cControl::Control())\
1268 cControl::Control()->Hide();\
1269 Menu = new cMenuMain(function);\
1270 key = kNone; } // nobody else needs to see this key
1291 esyslog(
"ERROR: unknown plugin '%s'", PluginName);
1383 isyslog(
"Power button pressed");
1417 if (state ==
osEnd) {
1454 case osEnd:
if (Interact == Menu)
1472 if (PreviousChannel[PreviousChannelIndex ^ 1] == LastChannel || LastChannel != PreviousChannel[0] && LastChannel != PreviousChannel[1])
1473 PreviousChannelIndex ^= 1;
1475 Channels->SwitchTo(PreviousChannel[PreviousChannelIndex ^= 1]);
1498 case kOk: LastChannel = -1;
break;
1512 if (!InhibitEpgScan)
1525 if (NewPrimaryDVB != OldPrimaryDVB) {
1531 OldPrimaryDVB = NewPrimaryDVB;
1584 esyslog(
"emergency exit requested - shutting down");
1589 signal(SIGHUP, SIG_DFL);
1590 signal(SIGINT, SIG_DFL);
1591 signal(SIGTERM, SIG_DFL);
1592 signal(SIGPIPE, SIG_DFL);
1593 signal(SIGALRM, SIG_DFL);
1622 if (WatchdogTimeout > 0)
1623 dsyslog(
"max. latency time %d seconds", MaxLatencyTime);
1632 tcsetattr(STDIN_FILENO, TCSANOW, &savedTm);
1635 sd_notify(0,
"STOPPING=1\nSTATUS=Startup failed, exiting");
1637 sd_notify(0,
"STOPPING=1\nSTATUS=Exiting");
bool SwitchTo(int Number) const
static bool DropCaps(void)
bool EmergencyExitRequested(void)
Returns true if an emergency exit was requested.
static char * OverrideCharacterTable
static void Process(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...
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 bool SetUser(const char *User, bool UserDump)
static void DestroyPositioner(void)
Destroys a previously created positioner.
bool Load(const char *FileName, bool AllowComments=false, bool MustExist=false)
static bool WaitForAllDevicesReady(int Timeout=0)
Waits until all devices have become ready, or the given Timeout (seconds) has expired.
static int CurrentChannel(void)
Returns the number of the current channel on the primary device.
static void SetName(const char *Name)
void AssertFreeDiskSpace(int Priority, bool Force)
The special Priority value -1 means that we shall get rid of any deleted recordings faster than norma...
const cKeyMacro * Get(eKeys Key)
virtual bool HasProgramme(void) const
Returns true if the device is currently showing any programme to the user, either through replaying o...
void StopSVDRPHandler(void)
void DelAll(void)
Deletes/terminates all operations.
static bool PutMacro(eKeys Key)
static bool useDvbDevices
const cTimer * GetMatch(time_t t) const
static bool HasPlugins(void)
void Load(const char *FileName)
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...
static cPlugin * GetPlugin(int Index)
cRecordingsHandler RecordingsHandler
static const cSchedules * GetSchedulesRead(cStateKey &StateKey, int TimeoutMs=0)
Gets the list of schedules for read access.
#define LOCK_CHANNELS_READ
bool ConfirmRestart(bool Ask)
Check for background activity that blocks restart.
void Start(const char *Message, int Seconds)
Start the 5 minute shutdown warning countdown.
static bool Process(cTimers *Timers, time_t t)
#define TIMERLOOKAHEADTIME
void ReportEpgBugFixStats(bool Force)
bool WaitForAllCamSlotsReady(int Timeout=0)
Waits until all CAM slots have become ready, or the given Timeout (seconds) has expired.
static const cTimers * GetTimersRead(cStateKey &StateKey, int TimeoutMs=0)
Gets the list of timers for read access.
static const char * LastReplayed(void)
bool PresentSeenWithin(int Seconds) const
virtual bool IsTunedToTransponder(const cChannel *Channel) const
Returns true if this device is currently tuned to the given Channel's transponder.
#define LOCK_SCHEDULES_READ
static void SetThemesDirectory(const char *ThemesDirectory)
bool Load(const char *FileName)
bool Finished(bool &Error)
Returns true if all operations in the list have been finished.
virtual const char * Version(void)=0
bool CamResponsesLoad(const char *FileName, bool AllowComments, bool MustExist)
bool SetEvents(const cSchedules *Schedules)
void MainThreadHook(void)
static time_t LastActivity(void)
Absolute time when last key was delivered by Get().
#define SHUTDOWNFORCEPROMPT
virtual const char * Description(void)=0
static bool SetKeepCaps(bool On)
bool Put(uint64_t Code, bool Repeat=false, bool Release=false)
static void MsgChannelChange(const cChannel *Channel)
static void UpdateOsdSize(bool Force=false)
Inquires the actual size of the video display and adjusts the OSD and font sizes accordingly.
char ** GetArgv(void) const
bool ConfirmShutdown(bool Ask)
Check for background activity that blocks shutdown.
#define CHANNELMOD_TRANSP
static int CurrentVolume(void)
static cDevice * PrimaryDevice(void)
Returns the primary device.
bool Load(const char *FileName)
static void Cleanup(bool Force=false)
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.
static int IsOpen(void)
Returns true if there is currently a level 0 OSD open.
cShutdownHandler ShutdownHandler
static cDisplayVolume * Create(void)
static cPositioner * GetPositioner(void)
Returns a previously created positioner.
#define RESTARTCANCELPROMPT
void StopReplay(void)
Stops the current replay session (if any).
virtual eOSState ProcessKey(eKeys Key)
void SetOverrideCharacterTable(const char *CharacterTable)
#define MAXVIDEOFILESIZETS
static cDevice * GetDevice(int Index)
Gets the device with the given Index.
#define DEFAULTEPGDATAFILENAME
static tThreadId ThreadId(void)
static bool Load(const char *FileName)
static void Shutdown(void)
virtual void Hide(void)=0
static void SetCacheDirectory(const char *Dir)
#define TIMERDEVICETIMEOUT
bool IsPrimaryDevice(void) const
bool Retry(time_t AtTime=0)
Check whether its time to re-try the shutdown.
bool InitializePlugins(void)
void CheckManualStart(int ManualStart)
Check whether the next timer is in ManualStart time window.
static void SetMainThreadId(void)
bool ToggleMute(void)
Turns the volume off or on and returns the new mute state.
static void Shutdown(void)
Shuts down the OSD provider facility by deleting the current OSD provider.
virtual bool NeedsFastResponse(void)
void Shutdown(bool Log=false)
void AddPlugin(const char *Args)
static void Launch(cControl *Control)
static void Shutdown(void)
Closes down all devices.
void SetDirectory(const char *Directory)
void I18nInitialize(const char *LocaleDir)
Detects all available locales and loads the language names and codes.
static bool SetPrimaryDevice(int n)
Sets the primary device to 'n'.
char OSDSkin[MaxSkinName]
bool CutRecording(const char *FileName)
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.
void RemoveDeletedRecordings(void)
void SetSVDRPPorts(int TcpPort, int UdpPort)
#define SHUTDOWNCANCELPROMPT
bool Load(const char *FileName=NULL, bool AllowComments=false, bool MustExist=false)
bool GenerateIndex(const char *FileName, bool Update)
Generates the index of the existing recording with the given FileName.
void Remove(bool IncState=true)
Removes this key from the lock it was previously used with.
bool Update(void)
Update status display of the countdown.
void SetVolume(int Volume, bool Absolute=false)
Sets the volume to the given value, either absolutely or relative to the current volume.
void SetSVDRPGrabImageDir(const char *GrabImageDir)
void Exit(int ExitCode)
Set VDR exit code and initiate end of VDR main loop.
bool Confirm(const char *s, int Seconds=10, bool WaitForTimeout=false)
static bool Initialize(void)
Initializes the DVB devices.
void Purge(bool Force=false)
int main(int argc, char *argv[])
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.
const T * First(void) const
Returns the first element in this list, or NULL if the list is empty.
void SetUserInactive(void)
Set VDR manually into non-interactive mode from now on.
virtual void Clear(void)
Free up all registered skins.
bool LoadPlugins(bool Log=false)
cChannelCamRelations ChannelCamRelations
bool Load(const char *SkinName)
bool ReadDirectory(const char *Directory)
static bool OsdSizeChanged(int &State)
Checks if the OSD size has changed and a currently displayed OSD needs to be redrawn.
void SetOccupied(int Seconds)
Sets the occupied timeout for this device to the given number of Seconds, This can be used to tune a ...
void SetRetry(int Seconds)
Set shutdown retry so that VDR will not try to automatically shut down within Seconds.
static void SignalHandler(int signum)
void StartSVDRPHandler(void)
bool StateChanged(void)
Returns true if this key is used for obtaining a write lock, and the lock's state differs from that o...
void SetShutdownCommand(const char *ShutdownCommand)
Set the command string for shutdown command.
cCiResourceHandlers CiResourceHandlers
eKeys GetKey(bool Wait=true)
#define DEVICEREADYTIMEOUT
void ProcessQueuedMessages(void)
Processes the first queued message, if any.
static void SetEpgDataFileName(const char *FileName)
static int NumDevices(void)
Returns the total number of devices.
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().
static bool Load(const char *FileName, bool AllowComments=false, bool MustExist=false)
static bool BondDevices(const char *Bondings)
Bonds the devices as defined in the given Bondings string.
static cDisplayTracks * Create(void)
bool Done(void)
Check if countdown timer has run out without canceling.
void Cancel(void)
Cancel the 5 minute shutdown warning countdown.
bool IsUserInactive(time_t AtTime=0)
Check whether VDR is in interactive mode or non-interactive mode (waiting for shutdown).
char OSDTheme[MaxThemeName]
static cDevice * ActualDevice(void)
Returns the actual receiving device in case of Transfer Mode, or the primary device otherwise.
static void Process(eKeys Key)
static cString GetFontFileName(const char *FontName)
Returns the actual font file name for the given FontName.
static void Watchdog(int signum)
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...
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 SwitchChannel(const cChannel *Channel, bool LiveView)
Switches the device to the given Channel, initiating transfer mode if necessary.
cSourceParams SourceParams
bool Active(void)
Checks whether the thread is still alive.
static cTimers * GetTimersWrite(cStateKey &StateKey, int TimeoutMs=0)
Gets the list of timers for write access.
static void SetSystemCharacterTable(const char *CharacterTable)
static const cChannels * GetChannelsRead(cStateKey &StateKey, int TimeoutMs=0)
Gets the list of channels for read access.
bool SetSystemCharacterTable(const char *CharacterTable)
int DeviceNumber(void) const
Returns the number of this device (0 ... numDevices - 1).
static void SetCommand(const char *Command)
int GetExitCode(void)
Get the currently set exit code of VDR.
static void SetUseDevice(int n)
Sets the 'useDevice' flag of the given device.
cSkin * Current(void)
Returns a pointer to the current skin.
const T * Next(const T *Object) const
< Returns the element immediately before Object in this list, or NULL if Object is the first element ...
static void Destroy(void)
static void SetConfigDirectory(const char *Dir)
void bool Start(void)
Sets the description of this thread, which will be used when logging starting or stopping of the thre...
static void Process(eKeys Key)
bool DoExit(void)
Check if an exit code was set, and VDR should exit.
static cDisplaySubtitleTracks * Create(void)
#define MAXVIDEOFILESIZEDEFAULT
static bool PauseLiveVideo(void)
#define DirectMainFunction(function)
virtual bool HasDecoder(void) const
Tells whether this device has an MPEG decoder.
static bool Start(cTimers *Timers, cTimer *Timer, bool Pause=false)
virtual cOsdObject * MainMenuAction(void)
#define LOCK_CHANNELS_WRITE
virtual const char * CommandLineHelp(void)
cStateKey StateKeySVDRPRemoteTimersPoll
Controls whether a change to the local list of timers needs to result in sending a POLL to the remote...
#define CHANNELMOD_RETUNE
static tChannelID FromString(const char *s)
bool DoShutdown(bool Force)
Call the shutdown script with data of the next pending timer.
char FontOsd[MAXFONTNAME]
virtual cOsdObject * GetInfo(void)
Returns an OSD object that displays information about the currently played programme.
static cControl * Control(bool Hidden=false)
Returns the current replay control (if any) in case it is currently visible.
static cOsdObject * PluginOsdObject(void)
bool Load(const char *FileName, bool AllowComments=false, bool MustExist=false)
static void Shutdown(void)
static void ChannelDataModified(const cChannel *Channel)
static void SetResourceDirectory(const char *Dir)
int GetMaxPriority(void) const
Returns the maximum priority of all local timers that are currently recording.
cNestedItemList RecordingCommands
bool SetCurrent(const char *Name=NULL)
Sets the current skin to the one indicated by name.