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 = cap_from_text(
"= cap_sys_nice,cap_sys_time,cap_net_raw=ep");
131 fprintf(stderr,
"vdr: cap_from_text failed: %s\n", strerror(errno));
134 if (cap_set_proc(caps) == -1) {
135 fprintf(stderr,
"vdr: cap_set_proc failed: %s\n", strerror(errno));
146 if (prctl(PR_SET_KEEPCAPS, On ? 1 : 0, 0, 0, 0) != 0) {
147 fprintf(stderr,
"vdr: prctl failed\n");
173 esyslog(
"PANIC: watchdog timer expired - exiting!");
175 sd_notify(0,
"STOPPING=1\nSTATUS=PANIC");
180 int main(
int argc,
char *argv[])
184 struct termios savedTm;
185 bool HasStdin = (tcgetpgrp(STDIN_FILENO) == getpid() || getppid() != (pid_t)1) && tcgetattr(STDIN_FILENO, &savedTm) == 0;
189 setlocale(LC_ALL,
"");
193 #define dd(a, b) (*a ? a : b) 194 #define DEFAULTSVDRPPORT 6419 195 #define DEFAULTWATCHDOG 0 // seconds 196 #define DEFAULTVIDEODIR VIDEODIR 197 #define DEFAULTCONFDIR dd(CONFDIR, VideoDirectory) 198 #define DEFAULTARGSDIR dd(ARGSDIR, "/etc/vdr/conf.d") 199 #define DEFAULTCACHEDIR dd(CACHEDIR, VideoDirectory) 200 #define DEFAULTRESDIR dd(RESDIR, ConfigDirectory) 201 #define DEFAULTPLUGINDIR PLUGINDIR 202 #define DEFAULTLOCDIR LOCDIR 203 #define DEFAULTEPGDATAFILENAME "epg.data" 205 bool StartedAsRoot =
false;
206 const char *VdrUser = NULL;
207 bool UserDump =
false;
209 const char *AudioCommand = NULL;
211 const char *ConfigDirectory = NULL;
212 const char *CacheDirectory = NULL;
213 const char *ResourceDirectory = NULL;
216 bool DisplayHelp =
false;
217 bool DisplayVersion =
false;
218 bool DaemonMode =
false;
219 int SysLogTarget = LOG_USER;
220 bool MuteAudio =
false;
222 const char *Terminal = NULL;
224 #ifndef DEPRECATED_VDR_CHARSET_OVERRIDE 225 #define DEPRECATED_VDR_CHARSET_OVERRIDE 0 227 #if DEPRECATED_VDR_CHARSET_OVERRIDE 233 const char *LircDevice = NULL;
234 #if !defined(REMOTE_KBD) 237 #if defined(REMOTE_LIRC) 238 LircDevice = LIRC_DEVICE;
240 #if defined(VDR_USER) 244 time_t SdWatchdog = 0;
245 int SdWatchdogTimeout = 0;
250 Args =
new cArgs(argv[0]);
260 static struct option long_options[] = {
261 {
"audio", required_argument, NULL,
'a' },
262 {
"cachedir", required_argument, NULL,
'c' | 0x100 },
263 {
"chartab", required_argument, NULL,
'c' | 0x200 },
264 {
"config", required_argument, NULL,
'c' },
265 {
"daemon", no_argument, NULL,
'd' },
266 {
"device", required_argument, NULL,
'D' },
267 {
"dirnames", required_argument, NULL,
'd' | 0x100 },
268 {
"edit", required_argument, NULL,
'e' | 0x100 },
269 {
"epgfile", required_argument, NULL,
'E' },
270 {
"filesize", required_argument, NULL,
'f' | 0x100 },
271 {
"genindex", required_argument, NULL,
'g' | 0x100 },
272 {
"grab", required_argument, NULL,
'g' },
273 {
"help", no_argument, NULL,
'h' },
274 {
"instance", required_argument, NULL,
'i' },
275 {
"lib", required_argument, NULL,
'L' },
276 {
"lirc", optional_argument, NULL,
'l' | 0x100 },
277 {
"localedir",required_argument, NULL,
'l' | 0x200 },
278 {
"log", required_argument, NULL,
'l' },
279 {
"mute", no_argument, NULL,
'm' },
280 {
"no-kbd", no_argument, NULL,
'n' | 0x100 },
281 {
"plugin", required_argument, NULL,
'P' },
282 {
"port", required_argument, NULL,
'p' },
283 {
"record", required_argument, NULL,
'r' },
284 {
"resdir", required_argument, NULL,
'r' | 0x100 },
285 {
"showargs", optional_argument, NULL,
's' | 0x200 },
286 {
"shutdown", required_argument, NULL,
's' },
287 {
"split", no_argument, NULL,
's' | 0x100 },
288 {
"terminal", required_argument, NULL,
't' },
289 {
"updindex", required_argument, NULL,
'u' | 0x200 },
290 {
"user", required_argument, NULL,
'u' },
291 {
"userdump", no_argument, NULL,
'u' | 0x100 },
292 {
"version", no_argument, NULL,
'V' },
293 {
"vfat", no_argument, NULL,
'v' | 0x100 },
294 {
"video", required_argument, NULL,
'v' },
295 {
"watchdog", required_argument, NULL,
'w' },
296 { NULL, no_argument, NULL, 0 }
300 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) {
302 case 'a': AudioCommand = optarg;
305 CacheDirectory = optarg;
310 case 'c': ConfigDirectory = optarg;
312 case 'd': DaemonMode =
true;
314 case 'D':
if (*optarg ==
'-') {
319 int n = atoi(optarg);
325 fprintf(stderr,
"vdr: invalid DVB device number: %s\n", optarg);
330 int n = strtol(s, &s, 10);
331 if (n <= 0 || n >= PATH_MAX) {
332 fprintf(stderr,
"vdr: invalid directory path length: %s\n", optarg);
339 fprintf(stderr,
"vdr: invalid delimiter: %s\n", optarg);
347 int n = strtol(s, &s, 10);
348 if (n <= 0 || n > NAME_MAX) {
349 fprintf(stderr,
"vdr: invalid directory name length: %s\n", optarg);
356 fprintf(stderr,
"vdr: invalid delimiter: %s\n", optarg);
363 int n = strtol(s, &s, 10);
364 if (n != 0 && n != 1) {
365 fprintf(stderr,
"vdr: invalid directory encoding: %s\n", optarg);
370 fprintf(stderr,
"vdr: unexpected data: %s\n", optarg);
377 case 'E': EpgDataFileName = (*optarg !=
'-' ? optarg : NULL);
390 case 'h': DisplayHelp =
true;
397 fprintf(stderr,
"vdr: invalid instance id: %s\n", optarg);
400 char *p = strchr(optarg,
'.');
404 int l = atoi(optarg);
405 if (0 <= l && l <= 3) {
411 if (0 <= l && l <= 7) {
412 int targets[] = { LOG_LOCAL0, LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4, LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7 };
413 SysLogTarget = targets[l];
421 fprintf(stderr,
"vdr: invalid log level: %s\n", optarg);
424 case 'L':
if (access(optarg, R_OK | X_OK) == 0)
427 fprintf(stderr,
"vdr: can't access plugin directory: %s\n", optarg);
432 LircDevice = optarg ? optarg : LIRC_DEVICE;
435 if (access(optarg, R_OK | X_OK) == 0)
436 LocaleDirectory = optarg;
438 fprintf(stderr,
"vdr: can't access locale directory: %s\n", optarg);
442 case 'm': MuteAudio =
true;
448 SVDRPport = atoi(optarg);
450 fprintf(stderr,
"vdr: invalid port number: %s\n", optarg);
454 case 'P': PluginManager.
AddPlugin(optarg);
459 ResourceDirectory = optarg;
470 fprintf(stderr,
"vdr: can't read arguments from directory: %s\n", ArgsDir);
475 for (
int i = 1; i < c; i++)
476 printf(
"%s\n", v[i]);
479 case 't': Terminal = optarg;
480 if (access(Terminal, R_OK | W_OK) < 0) {
481 fprintf(stderr,
"vdr: can't access terminal: %s\n", Terminal);
485 case 'u':
if (*optarg)
493 case 'V': DisplayVersion =
true;
500 case 'v': VideoDirectory = optarg;
501 while (optarg && *optarg && optarg[strlen(optarg) - 1] ==
'/')
502 optarg[strlen(optarg) - 1] = 0;
506 int t = atoi(optarg);
512 fprintf(stderr,
"vdr: invalid watchdog timeout: %s\n", optarg);
520 if (VdrUser && geteuid() == 0) {
521 StartedAsRoot =
true;
522 if (strcmp(VdrUser,
"root") && strcmp(VdrUser,
"0")) {
525 if (!
SetUser(VdrUser, UserDump))
536 if (DisplayHelp || DisplayVersion) {
541 printf(
"Usage: vdr [OPTIONS]\n\n" 542 " -a CMD, --audio=CMD send Dolby Digital audio to stdin of command CMD\n" 543 " --cachedir=DIR save cache files in DIR (default: %s)\n" 544 " --chartab=CHARACTER_TABLE\n" 545 " set the character table to use for strings in the\n" 546 " DVB data stream that don't begin with a character\n" 547 " table indicator, but don't use the standard default\n" 548 " character table (for instance ISO-8859-9)\n" 549 " -c DIR, --config=DIR read config files from DIR (default: %s)\n" 550 " -d, --daemon run in daemon mode\n" 551 " -D NUM, --device=NUM use only the given DVB device (NUM = 0, 1, 2...)\n" 552 " there may be several -D options (default: all DVB\n" 553 " devices will be used); if -D- is given, no DVB\n" 554 " devices will be used at all, independent of any\n" 555 " other -D options\n" 556 " --dirnames=PATH[,NAME[,ENC]]\n" 557 " set the maximum directory path length to PATH\n" 558 " (default: %d); if NAME is also given, it defines\n" 559 " the maximum directory name length (default: %d);\n" 560 " the optional ENC can be 0 or 1, and controls whether\n" 561 " special characters in directory names are encoded as\n" 562 " hex values (default: 0); if PATH or NAME are left\n" 563 " empty (as in \",,1\" to only set ENC), the defaults\n" 565 " --edit=REC cut recording REC and exit\n" 566 " -E FILE, --epgfile=FILE write the EPG data into the given FILE (default is\n" 567 " '%s' in the cache directory)\n" 568 " '-E-' disables this\n" 569 " if FILE is a directory, the default EPG file will be\n" 570 " created in that directory\n" 571 " --filesize=SIZE limit video files to SIZE bytes (default is %dM)\n" 572 " only useful in conjunction with --edit\n" 573 " --genindex=REC generate index for recording REC and exit\n" 574 " -g DIR, --grab=DIR write images from the SVDRP command GRAB into the\n" 575 " given DIR; DIR must be the full path name of an\n" 576 " existing directory, without any \"..\", double '/'\n" 577 " or symlinks (default: none, same as -g-)\n" 578 " -h, --help print this help and exit\n" 579 " -i ID, --instance=ID use ID as the id of this VDR instance (default: 0)\n" 580 " -l LEVEL, --log=LEVEL set log level (default: 3)\n" 581 " 0 = no logging, 1 = errors only,\n" 582 " 2 = errors and info, 3 = errors, info and debug\n" 583 " if logging should be done to LOG_LOCALn instead of\n" 584 " LOG_USER, add '.n' to LEVEL, as in 3.7 (n=0..7)\n" 585 " -L DIR, --lib=DIR search for plugins in DIR (default is %s)\n" 586 " --lirc[=PATH] use a LIRC remote control device, attached to PATH\n" 588 " --localedir=DIR search for locale files in DIR (default is\n" 590 " -m, --mute mute audio of the primary DVB device at startup\n" 591 " --no-kbd don't use the keyboard as an input device\n" 592 " -p PORT, --port=PORT use PORT for SVDRP (default: %d)\n" 593 " 0 turns off SVDRP\n" 594 " -P OPT, --plugin=OPT load a plugin defined by the given options\n" 595 " -r CMD, --record=CMD call CMD before and after a recording, and after\n" 596 " a recording has been edited or deleted\n" 597 " --resdir=DIR read resource files from DIR (default: %s)\n" 598 " -s CMD, --shutdown=CMD call CMD to shutdown the computer\n" 599 " --split split edited files at the editing marks (only\n" 600 " useful in conjunction with --edit)\n" 601 " --showargs[=DIR] print the arguments read from DIR and exit\n" 603 " -t TTY, --terminal=TTY controlling tty\n" 604 " -u USER, --user=USER run as user USER; only applicable if started as\n" 605 " root; USER can be a user name or a numerical id\n" 606 " --updindex=REC update index for recording REC and exit\n" 607 " --userdump allow coredumps if -u is given (debugging)\n" 608 " -v DIR, --video=DIR use DIR as video directory (default: %s)\n" 609 " -V, --version print version information and exit\n" 610 " --vfat for backwards compatibility (same as\n" 611 " --dirnames=250,40,1)\n" 612 " -w SEC, --watchdog=SEC activate the watchdog timer with a timeout of SEC\n" 613 " seconds (default: %d); '0' disables the watchdog\n" 635 printf(
"Plugins: vdr -P\"name [OPTIONS]\"\n\n");
636 for (
int i = 0; ; i++) {
641 if (DisplayHelp && help) {
656 openlog(
"vdr", LOG_CONS, SysLogTarget);
661 fprintf(stderr,
"vdr: can't access video directory %s\n", VideoDirectory);
668 if (daemon(1, 0) == -1) {
669 fprintf(stderr,
"vdr: %m\n");
676 stdin = freopen(Terminal,
"r", stdin);
677 stdout = freopen(Terminal,
"w", stdout);
678 stderr = freopen(Terminal,
"w", stderr);
680 tcgetattr(STDIN_FILENO, &savedTm);
684 if (StartedAsRoot && VdrUser)
685 isyslog(
"switched to user '%s'", VdrUser);
692 char *CodeSet = NULL;
693 if (setlocale(LC_CTYPE,
""))
694 CodeSet = nl_langinfo(CODESET);
696 char *LangEnv = getenv(
"LANG");
698 CodeSet = strchr(LangEnv,
'.');
705 isyslog(
"codeset is '%s' - %s", CodeSet, known ?
"known" :
"unknown");
708 #if DEPRECATED_VDR_CHARSET_OVERRIDE 709 if (DeprecatedVdrCharsetOverride)
710 isyslog(
"use of environment variable VDR_CHARSET_OVERRIDE (%s) is deprecated!", DeprecatedVdrCharsetOverride);
726 int LastTimerChannel = -1;
727 int PreviousChannel[2] = { 1, 1 };
728 int PreviousChannelIndex = 0;
729 time_t LastChannelChanged = time(NULL);
730 time_t LastInteract = 0;
731 int MaxLatencyTime = 0;
732 bool InhibitEpgScan =
false;
733 bool IsInfoMenu =
false;
734 cSkin *CurrentSkin = NULL;
735 int OldPrimaryDVB = 0;
744 if (!ConfigDirectory)
750 if (!ResourceDirectory)
772 const char *msg =
"no fonts available - OSD will not show any text!";
773 fprintf(stderr,
"vdr: %s\n", msg);
783 if (EpgDataFileName) {
784 const char *EpgDirectory = NULL;
786 EpgDirectory = EpgDataFileName;
789 else if (*EpgDataFileName !=
'/' && *EpgDataFileName !=
'.')
790 EpgDirectory = CacheDirectory;
795 EpgDataReader.
Start();
817 isyslog(
"trying device number %d instead", i + 1);
825 const char *msg =
"no primary device found - using first device!";
826 fprintf(stderr,
"vdr: %s\n", msg);
831 const char *msg =
"no primary device found - giving up!";
832 fprintf(stderr,
"vdr: %s\n", msg);
872 if (!DaemonMode && HasStdin && UseKbd)
918 if (signal(SIGHUP,
SignalHandler) == SIG_IGN) signal(SIGHUP, SIG_IGN);
919 if (signal(SIGINT,
SignalHandler) == SIG_IGN) signal(SIGINT, SIG_IGN);
920 if (signal(SIGTERM,
SignalHandler) == SIG_IGN) signal(SIGTERM, SIG_IGN);
921 if (signal(SIGPIPE,
SignalHandler) == SIG_IGN) signal(SIGPIPE, SIG_IGN);
922 if (WatchdogTimeout > 0)
923 if (signal(SIGALRM,
Watchdog) == SIG_IGN) signal(SIGALRM, SIG_IGN);
927 if (WatchdogTimeout > 0) {
928 dsyslog(
"setting watchdog timer to %d seconds", WatchdogTimeout);
929 alarm(WatchdogTimeout);
933 if (sd_watchdog_enabled(0, NULL) > 0) {
935 SdWatchdog = time(NULL);
936 sd_watchdog_enabled(0, &timeout);
937 SdWatchdogTimeout = (int)timeout/1000000;
938 dsyslog(
"SD_WATCHDOG enabled with timeout set to %d seconds", SdWatchdogTimeout);
943 sd_notify(0,
"READY=1\nSTATUS=Ready");
953 #define DELETE_MENU ((IsInfoMenu &= (Menu == NULL)), delete Menu, Menu = NULL) 956 #ifdef DEBUGRINGBUFFERS 957 cRingBufferLinear::PrintDebugRBL();
962 time_t Now = time(NULL);
966 static time_t lastTime = 0;
971 if (Channel && (Channel->
Vpid() || Channel->
Apid(0) || Channel->
Dpid(0))) {
974 else if (LastTimerChannel > 0) {
975 Channel = Channels->GetByNumber(LastTimerChannel);
981 LastTimerChannel = -1;
989 static time_t lastOsdSizeUpdate = 0;
990 if (Now != lastOsdSizeUpdate) {
992 static int OsdState = 0;
994 if (
cOsdMenu *OsdMenu = dynamic_cast<cOsdMenu *>(Menu))
997 lastOsdSizeUpdate = Now;
1001 if (WatchdogTimeout > 0) {
1002 int LatencyTime = WatchdogTimeout - alarm(WatchdogTimeout);
1003 if (LatencyTime > MaxLatencyTime) {
1004 MaxLatencyTime = LatencyTime;
1005 dsyslog(
"max. latency time %d seconds", MaxLatencyTime);
1010 if (SdWatchdogTimeout && (Now - SdWatchdog) * 2 > SdWatchdogTimeout) {
1011 sd_notify(0,
"WATCHDOG=1");
1017 static bool ChannelsRenumber =
false;
1021 static time_t ChannelSaveTimeout = 0;
1023 static cStateKey ChannelsStateKey(
true);
1024 static int ChannelsModifiedByUser = 0;
1027 if (ChannelSaveTimeout != 1) {
1030 ChannelSaveTimeout = 1;
1031 else if (!ChannelSaveTimeout)
1035 ChannelSaveTimeout = 1;
1038 ChannelSaveTimeout = 1;
1039 if (Timers && Channels) {
1042 ChannelSaveTimeout = 0;
1045 for (
const cChannel *Channel = Channels->
First(); Channel; Channel = Channels->
Next(Channel)) {
1048 ChannelsRenumber =
true;
1054 isyslog(
"retuning due to modification of channel %d (%s)", Channel->Number(), Channel->Name());
1055 Channels->
SwitchTo(Channel->Number());
1065 ChannelsStateKey.
Remove();
1068 if (ChannelSaveTimeout == 1) {
1070 ChannelsStateKey.
Reset();
1071 TimersStateKey.
Reset();
1079 LastChannelChanged = Now;
1081 if (Now - LastChannelChanged >=
Setup.
ZapTimeout && LastChannel != PreviousChannel[PreviousChannelIndex])
1082 PreviousChannel[PreviousChannelIndex ^= 1] = LastChannel;
1091 SchedulesStateKey.
Reset();
1092 bool TimersModified =
false;
1096 TimersModified =
true;
1097 SchedulesStateKey.
Remove();
1099 TimersStateKey.
Remove(TimersModified);
1104 bool TimersModified =
false;
1106 TimersModified =
true;
1110 Timer->SetPending(
true);
1112 LastTimerChannel = Timer->Channel()->Number();
1113 TimersModified =
true;
1116 static time_t LastTimerCheck = 0;
1118 InhibitEpgScan =
false;
1119 for (
cTimer *Timer = Timers->
First(); Timer; Timer = Timers->
Next(Timer)) {
1120 if (Timer->Remote())
1122 bool InVpsMargin =
false;
1123 bool NeedsTransponder =
false;
1124 if (Timer->HasFlags(
tfActive) && !Timer->Recording()) {
1125 if (Timer->HasFlags(
tfVps)) {
1128 Timer->SetInVpsMargin(InVpsMargin);
1130 else if (Timer->Event()) {
1131 InVpsMargin = Timer->Event()->StartTime() <= Now && Now < Timer->Event()->EndTime();
1136 const cSchedule *Schedule = Schedules->GetSchedule(Timer->Channel());
1137 InVpsMargin = !Schedule;
1140 InhibitEpgScan |= InVpsMargin | NeedsTransponder;
1145 if (NeedsTransponder || InVpsMargin) {
1148 if (!Device && InVpsMargin)
1156 dsyslog(
"switching device %d to channel %d %s (%s)", Device->
DeviceNumber() + 1, Timer->Channel()->Number(), *Timer->Channel()->GetChannelID().ToString(), Timer->Channel()->Name());
1165 LastTimerCheck = Now;
1169 TimersModified =
true;
1172 TimersStateKey.
Remove(TimersModified);
1175 if (ChannelsRenumber) {
1177 Channels->ReNumber();
1178 ChannelsRenumber =
false;
1207 bool WasOpen = Interact != NULL;
1208 bool WasMenu = Interact && Interact->
IsMenu();
1246 #define DirectMainFunction(function)\ 1248 if (cControl::Control())\ 1249 cControl::Control()->Hide();\ 1250 Menu = new cMenuMain(function);\ 1251 key = kNone; } // nobody else needs to see this key 1272 esyslog(
"ERROR: unknown plugin '%s'", PluginName);
1364 isyslog(
"Power button pressed");
1398 if (state ==
osEnd) {
1435 case osEnd:
if (Interact == Menu)
1453 if (PreviousChannel[PreviousChannelIndex ^ 1] == LastChannel || LastChannel != PreviousChannel[0] && LastChannel != PreviousChannel[1])
1454 PreviousChannelIndex ^= 1;
1456 Channels->SwitchTo(PreviousChannel[PreviousChannelIndex ^= 1]);
1479 case kOk: LastChannel = -1;
break;
1493 if (!InhibitEpgScan)
1506 if (NewPrimaryDVB != OldPrimaryDVB) {
1512 OldPrimaryDVB = NewPrimaryDVB;
1565 esyslog(
"emergency exit requested - shutting down");
1570 signal(SIGHUP, SIG_DFL);
1571 signal(SIGINT, SIG_DFL);
1572 signal(SIGTERM, SIG_DFL);
1573 signal(SIGPIPE, SIG_DFL);
1574 signal(SIGALRM, SIG_DFL);
1603 if (WatchdogTimeout > 0)
1604 dsyslog(
"max. latency time %d seconds", MaxLatencyTime);
1613 tcsetattr(STDIN_FILENO, TCSANOW, &savedTm);
1616 sd_notify(0,
"STOPPING=1\nSTATUS=Startup failed, exiting");
1618 sd_notify(0,
"STOPPING=1\nSTATUS=Exiting");
const cTimer * GetMatch(time_t t) const
static void Watchdog(int signum)
void Purge(bool Force=false)
void SetSVDRPPorts(int TcpPort, int UdpPort)
static const cChannels * GetChannelsRead(cStateKey &StateKey, int TimeoutMs=0)
Gets the list of channels for read access.
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 PresentSeenWithin(int Seconds) const
static void SetThemesDirectory(const char *ThemesDirectory)
static tChannelID FromString(const char *s)
bool ToggleMute(void)
Turns the volume off or on and returns the new mute state.
void CheckManualStart(int ManualStart)
Check whether the next timer is in ManualStart time window.
#define TIMERDEVICETIMEOUT
#define SHUTDOWNFORCEPROMPT
bool Confirm(const char *s, int Seconds=10, bool WaitForTimeout=false)
bool IsUserInactive(time_t AtTime=0)
Check whether VDR is in interactive mode or non-interactive mode (waiting for shutdown).
static const cSchedules * GetSchedulesRead(cStateKey &StateKey, int TimeoutMs=0)
Gets the list of schedules for read access.
static bool Initialize(void)
Initializes the DVB devices.
bool LoadPlugins(bool Log=false)
bool Load(const char *SkinName)
virtual cOsdObject * GetInfo(void)
Returns an OSD object that displays information about the currently played programme.
void Shutdown(bool Log=false)
static void Shutdown(void)
virtual const char * Version(void)=0
bool IsPrimaryDevice(void) const
virtual bool HasProgramme(void) const
Returns true if the device is currently showing any programme to the user, either through replaying o...
static bool DropCaps(void)
#define RESTARTCANCELPROMPT
cCiResourceHandlers CiResourceHandlers
#define CHANNELMOD_TRANSP
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 ReportEpgBugFixStats(bool Force)
virtual cOsdObject * MainMenuAction(void)
static cDisplayVolume * Create(void)
void ProcessQueuedMessages(void)
Processes the first queued message, if any.
void Remove(bool IncState=true)
Removes this key from the lock it was previously used with.
void SetUserInactive(void)
Set VDR manually into non-interactive mode from now on.
static cDevice * GetDevice(int Index)
Gets the device with the given Index.
static cControl * Control(bool Hidden=false)
Returns the current replay control (if any) in case it is currently visible.
bool Load(const char *FileName=NULL, bool AllowComments=false, bool MustExist=false)
static void Process(eKeys Key)
bool Update(void)
Update status display of the countdown.
bool EmergencyExitRequested(void)
Returns true if an emergency exit was requested.
static int NumDevices(void)
Returns the total number of devices.
bool DoShutdown(bool Force)
Call the shutdown script with data of the next pending timer.
void Exit(int ExitCode)
Set VDR exit code and initiate end of VDR main loop.
bool InitializePlugins(void)
static bool OsdSizeChanged(int &State)
Checks if the OSD size has changed and a currently displayed OSD needs to be redrawn.
#define LOCK_CHANNELS_WRITE
void MainThreadHook(void)
static bool SetKeepCaps(bool On)
char ** GetArgv(void) const
static void SetEpgDataFileName(const char *FileName)
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...
void SetSyncStateKey(cStateKey &StateKey)
When making changes to this list (while holding a write lock) that shall not affect some other code t...
static void SetCommand(const char *Command)
void StopSVDRPHandler(void)
cNestedItemList RecordingCommands
#define MAXVIDEOFILESIZEDEFAULT
static bool Load(const char *FileName)
static cTimers * GetTimersWrite(cStateKey &StateKey, int TimeoutMs=0)
Gets the list of timers for write access.
static bool Load(const char *FileName, bool AllowComments=false, bool MustExist=false)
static cPositioner * GetPositioner(void)
Returns a previously created positioner.
static int CurrentVolume(void)
#define TIMERLOOKAHEADTIME
virtual const char * Description(void)=0
virtual const char * CommandLineHelp(void)
static void Destroy(void)
void Start(const char *Message, int Seconds)
Start the 5 minute shutdown warning countdown.
static int CurrentChannel(void)
Returns the number of the current channel on the primary device.
static bool PutMacro(eKeys Key)
static bool BondDevices(const char *Bondings)
Bonds the devices as defined in the given Bondings string.
void SetVolume(int Volume, bool Absolute=false)
Sets the volume to the given value, either absolutely or relative to the current volume.
int GetExitCode(void)
Get the currently set exit code of VDR.
cStateKey StateKeySVDRPRemoteTimersPoll
Controls whether a change to the local list of timers needs to result in sending a POLL to the remote...
void StartSVDRPHandler(void)
static char * OverrideCharacterTable
virtual void Clear(void)
Free up all registered skins.
bool SwitchChannel(const cChannel *Channel, bool LiveView)
Switches the device to the given Channel, initiating transfer mode if necessary.
#define LOCK_CHANNELS_READ
char FontOsd[MAXFONTNAME]
void RemoveDeletedRecordings(void)
bool DoExit(void)
Check if an exit code was set, and VDR should exit.
void SetSVDRPGrabImageDir(const char *GrabImageDir)
int main(int argc, char *argv[])
static void SetName(const char *Name)
const cKeyMacro * Get(eKeys Key)
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 bool Start(void)
Sets the description of this thread, which will be used when logging starting or stopping of the thre...
static void UpdateOsdSize(bool Force=false)
Inquires the actual size of the video display and adjusts the OSD and font sizes accordingly.
cSourceParams SourceParams
bool Finished(bool &Error)
Returns true if all operations in the list have been finished.
static bool Process(cTimers *Timers, time_t t)
bool GenerateIndex(const char *FileName, bool Update)
Generates the index of the existing recording with the given FileName.
bool ConfirmShutdown(bool Ask)
Check for background activity that blocks shutdown.
bool Load(const char *FileName, bool AllowComments=false, bool MustExist=false)
void Load(const char *FileName)
bool Put(uint64_t Code, bool Repeat=false, bool Release=false)
bool ReadDirectory(const char *Directory)
static void Cleanup(bool Force=false)
cShutdownHandler ShutdownHandler
static int IsOpen(void)
Returns true if there is currently a level 0 OSD open.
static const char * GetPlugin(void)
Returns the name of the plugin that was set with a previous call to PutMacro() or CallPlugin().
static void SetSystemCharacterTable(const char *CharacterTable)
static bool WaitForAllDevicesReady(int Timeout=0)
Waits until all devices have become ready, or the given Timeout (seconds) has expired.
static tThreadId ThreadId(void)
static cDisplaySubtitleTracks * Create(void)
cRecordingsHandler RecordingsHandler
#define DEVICEREADYTIMEOUT
bool IsOpen(void)
Returns true if there is currently a skin display object active.
static void Launch(cControl *Control)
virtual bool HasDecoder(void) const
Tells whether this device has an MPEG decoder.
static const char * LastReplayed(void)
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...
const T * First(void) const
Returns the first element in this list, or NULL if the list is empty.
bool SetSystemCharacterTable(const char *CharacterTable)
bool CamResponsesLoad(const char *FileName, bool AllowComments, bool MustExist)
static bool useDvbDevices
static bool HasPlugins(void)
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...
virtual eOSState ProcessKey(eKeys Key)
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 void SetMainThreadId(void)
#define DEFAULTEPGDATAFILENAME
bool WaitForAllCamSlotsReady(int Timeout=0)
Waits until all CAM slots have become ready, or the given Timeout (seconds) has expired.
#define CHANNELMOD_RETUNE
static time_t LastActivity(void)
Absolute time when last key was delivered by Get().
static void Process(eKeys Key)
void DelAll(void)
Deletes/terminates all operations.
static void SetCacheDirectory(const char *Dir)
int DeviceNumber(void) const
Returns the number of this device (0 ... numDevices - 1).
static void Process(eKeys Key)
static cString GetFontFileName(const char *FontName)
Returns the actual font file name for the given FontName.
bool CutRecording(const char *FileName)
eKeys GetKey(bool Wait=true)
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 cDevice * PrimaryDevice(void)
Returns the primary device.
bool Load(const char *FileName)
bool Active(void)
Checks whether the thread is still alive.
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.
int GetMaxPriority(void) const
Returns the maximum priority of all local timers that are currently recording.
void AddPlugin(const char *Args)
static bool NeedsUpdate(void)
static bool SetPrimaryDevice(int n)
Sets the primary device to 'n'.
static cDisplayTracks * Create(void)
void StopReplay(void)
Stops the current replay session (if any).
cChannelCamRelations ChannelCamRelations
bool Transferring(void) const
Returns true if we are currently in Transfer Mode.
virtual bool NeedsFastResponse(void)
bool Retry(time_t AtTime=0)
Check whether its time to re-try the shutdown.
bool ConfirmRestart(bool Ask)
Check for background activity that blocks restart.
static bool SetUser(const char *User, bool UserDump)
void SetDirectory(const char *Directory)
void AssertFreeDiskSpace(int Priority, bool Force)
The special Priority value -1 means that we shall get rid of any deleted recordings faster than norma...
static void SignalHandler(int signum)
static cPlugin * GetPlugin(int Index)
static void Shutdown(void)
Closes down all devices.
static cDevice * ActualDevice(void)
Returns the actual receiving device in case of Transfer Mode, or the primary device otherwise.
virtual bool IsTunedToTransponder(const cChannel *Channel) const
Returns true if this device is currently tuned to the given Channel's transponder.
static cOsdObject * PluginOsdObject(void)
#define SHUTDOWNCANCELPROMPT
bool Load(const char *FileName)
static void MsgChannelChange(const cChannel *Channel)
bool SetEvents(const cSchedules *Schedules)
static bool Start(cTimers *Timers, cTimer *Timer, bool Pause=false)
bool SwitchTo(int Number) const
bool Load(const char *FileName, bool AllowComments=false, bool MustExist=false)
void SetRetry(int Seconds)
Set shutdown retry so that VDR will not try to automatically shut down within Seconds.
#define LOCK_SCHEDULES_READ
char OSDTheme[MaxThemeName]
void SetShutdownCommand(const char *ShutdownCommand)
Set the command string for shutdown command.
#define MAXVIDEOFILESIZETS
char OSDSkin[MaxSkinName]
static bool PauseLiveVideo(void)
cSkin * Current(void)
Returns a pointer to the current skin.
static const cTimers * GetTimersRead(cStateKey &StateKey, int TimeoutMs=0)
Gets the list of timers for read access.
static void SetResourceDirectory(const char *Dir)
bool SetCurrent(const char *Name=NULL)
Sets the current skin to the one indicated by name.
static void Shutdown(void)
static void ChannelDataModified(const cChannel *Channel)
#define DirectMainFunction(function)
bool Replaying(void) const
Returns true if we are currently replaying.
void SetOverrideCharacterTable(const char *CharacterTable)
static void SetUseDevice(int n)
Sets the 'useDevice' flag of the given device.
void I18nInitialize(const char *LocaleDir)
Detects all available locales and loads the language names and codes.
virtual bool ProvidesTransponder(const cChannel *Channel) const
Returns true if this device can provide the transponder of the given Channel (which implies that it c...
static void Shutdown(void)
Shuts down the OSD provider facility by deleting the current OSD provider.
static void DestroyPositioner(void)
Destroys a previously created positioner.
void Cancel(void)
Cancel the 5 minute shutdown warning countdown.
static void SetConfigDirectory(const char *Dir)
virtual void Hide(void)=0
bool Done(void)
Check if countdown timer has run out without canceling.
const T * Next(const T *Object) const
< Returns the element immediately before Object in this list, or NULL if Object is the first element ...