9 #include <QCoreApplication>
20 #include "libmythbase/mythversion.h"
33 QString value = (v.isNull()) ? QString(
"") : v;
38 query.
prepare(
"DELETE FROM settings WHERE value = :KEY;");
44 query.
prepare(
"INSERT INTO settings ( value, data ) "
45 "VALUES ( :VALUE, :DATA );");
54 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
55 QString(
"Error: Database not open while trying "
56 "to save setting: %1\n").arg(key));
62 QString value = defaultval;
67 query.
prepare(
"SELECT data FROM settings WHERE value = :KEY AND "
71 value = query.
value(0).toString();
75 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
76 QObject::tr(
"Error: Database not open while trying to "
77 "load setting: %1",
"mythshutdown").arg(key) +
"\n");
85 LOG(VB_GENERAL, LOG_INFO,
"Mythshutdown: --lock");
91 while (!query.
exec(
"LOCK TABLE settings WRITE;") && tries < 5)
93 LOG(VB_GENERAL, LOG_INFO,
"Waiting for lock on setting table");
100 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
101 QObject::tr(
"Error: Waited too long to obtain "
102 "lock on setting table",
"mythshutdown") +
"\n");
107 query.
prepare(
"SELECT * FROM settings "
108 "WHERE value = 'MythShutdownLock' AND hostname IS NULL;");
112 if (query.
size() < 1)
115 query.
prepare(
"INSERT INTO settings (value, data) "
116 "VALUES ('MythShutdownLock', '1');");
123 query.
prepare(
"UPDATE settings SET data = data + 1 "
124 "WHERE value = 'MythShutdownLock' "
125 "AND hostname IS NULL;");
131 if (!query.
exec(
"UNLOCK TABLES;"))
139 LOG(VB_GENERAL, LOG_INFO,
"Mythshutdown: --unlock");
145 while (!query.
exec(
"LOCK TABLE settings WRITE;") && tries < 5)
147 LOG(VB_GENERAL, LOG_INFO,
"Waiting for lock on setting table");
154 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
155 QObject::tr(
"Error: Waited too long to obtain "
156 "lock on setting table",
"mythshutdown") +
"\n");
161 query.
prepare(
"SELECT * FROM settings "
162 "WHERE value = 'MythShutdownLock' AND hostname IS NULL;");
166 if (query.
size() < 1)
169 query.
prepare(
"INSERT INTO settings (value, data) "
170 "VALUES ('MythShutdownLock', '0');");
177 query.
prepare(
"UPDATE settings SET data = GREATEST(0, data - 1) "
178 "WHERE value = 'MythShutdownLock' "
179 "AND hostname IS NULL;");
185 if (!query.
exec(
"UNLOCK TABLES;"))
209 QString command = QString(
"ps ch -C %1 -o pid > /dev/null").arg(program);
217 QDateTime dtDateTime = QDateTime(
219 tTime, Qt::LocalTime).toUTC();
228 LOG(VB_GENERAL, LOG_INFO,
229 "isRecording: Attempting to connect to master server...");
232 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
233 QObject::tr(
"Error: Could not connect to master server",
234 "mythshutdown") +
"\n");
244 LOG(VB_GENERAL, LOG_INFO,
"Mythshutdown: --status");
250 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
251 QObject::tr(
"Transcoding in progress...",
"mythshutdown") +
"\n");
257 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
258 QObject::tr(
"Commercial Detection in progress...",
259 "mythshutdown") +
"\n");
265 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
266 QObject::tr(
"Grabbing EPG data in progress...",
"mythshutdown") +
273 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
274 QObject::tr(
"Recording in progress...",
"mythshutdown") +
"\n");
280 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
281 QObject::tr(
"Shutdown is locked",
"mythshutdown") +
"\n");
287 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
288 QObject::tr(
"Has queued or pending jobs",
"mythshutdown") +
"\n");
299 if (dtPeriod1End < dtPeriod1Start)
301 if (dtCurrent > dtPeriod1End)
302 dtPeriod1End = dtPeriod1End.addDays(1);
304 dtPeriod1Start = dtPeriod1Start.addDays(-1);
307 if (dtPeriod2End < dtPeriod2Start)
309 if (dtCurrent > dtPeriod2End)
310 dtPeriod2End = dtPeriod2End.addDays(1);
312 dtPeriod2Start = dtPeriod2Start.addDays(-1);
316 if (dtPeriod1Start != dtPeriod1End)
318 if (dtCurrent >= dtPeriod1Start && dtCurrent <= dtPeriod1End)
320 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
321 QObject::tr(
"In a daily wakeup period (1).",
"mythshutdown") +
327 if (dtPeriod2Start != dtPeriod2End)
329 if (dtCurrent >= dtPeriod2Start && dtCurrent <= dtPeriod2End)
331 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
332 QObject::tr(
"In a daily wakeup period (2).",
"mythshutdown") +
340 if (dtPeriod1Start != dtPeriod1End)
342 auto delta = std::chrono::seconds(dtCurrent.secsTo(dtPeriod1Start));
343 if (delta >= 0s && delta <= 15min)
345 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
346 QObject::tr(
"About to start daily wakeup period (1)",
347 "mythshutdown") +
"\n");
352 if (dtPeriod2Start != dtPeriod2End)
354 auto delta = std::chrono::seconds(dtCurrent.secsTo(dtPeriod2Start));
355 if (delta >= 0s && delta <= 15min)
357 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
358 QObject::tr(
"About to start daily wakeup period (2)",
359 "mythshutdown") +
"\n");
366 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
367 QObject::tr(
"Setup is running...",
"mythshutdown") +
"\n");
371 LOG(VB_GENERAL, LOG_INFO,
372 QObject::tr(
"Mythshutdown: --status returned: %1",
373 "mythshutdown").arg(res) +
"\n");
383 LOG(VB_GENERAL, LOG_INFO,
"Mythshutdown: --check");
389 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
390 QObject::tr(
"Not OK to shutdown",
"mythshutdown") +
"\n");
395 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
396 QObject::tr(
"OK to shutdown",
"mythshutdown") +
"\n");
400 LOG(VB_GENERAL, LOG_INFO,
401 QString(
"Mythshutdown: --check returned: %1").arg(res));
408 LOG(VB_GENERAL, LOG_INFO,
"Mythshutdown: --setwakeup");
410 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
411 QObject::tr(
"Wakeup time given is: %1 (local time)",
"mythshutdown")
422 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
423 QObject::tr(
"Setting scheduled wakeup time: "
424 "Attempting to connect to master server...",
425 "mythshutdown") +
"\n");
428 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
429 QObject::tr(
"Setting scheduled wakeup time: "
430 "Could not connect to master server!",
431 "mythshutdown") +
"\n");
436 QDateTime nextRecordingStart;
440 if (!nextRecordingStart.isNull())
443 QDateTime restarttime = nextRecordingStart
444 .addSecs((-1LL) * m_preRollSeconds);
447 "StartupSecsBeforeRecording", 240);
450 restarttime = restarttime.addSecs((-1LL) * add);
461 LOG(VB_GENERAL, LOG_INFO,
"Mythshutdown: --shutdown");
469 QDateTime dtNextDailyWakeup = QDateTime();
472 if (dtPeriod2Start < dtPeriod1Start)
474 QDateTime temp = dtPeriod1Start;
475 dtPeriod1Start = dtPeriod2Start;
476 dtPeriod2Start = temp;
478 dtPeriod1End = dtPeriod2End;
483 if (dtPeriod1End < dtPeriod1Start)
485 if (dtCurrent > dtPeriod1End)
486 dtPeriod1End = dtPeriod1End.addDays(1);
488 dtPeriod1Start = dtPeriod1Start.addDays(-1);
491 if (dtPeriod2End < dtPeriod2Start)
493 if (dtCurrent > dtPeriod2End)
494 dtPeriod2End = dtPeriod2End.addDays(1);
496 dtPeriod2Start = dtPeriod2Start.addDays(-1);
500 if (dtPeriod1Start != dtPeriod1End)
502 if (dtCurrent < dtPeriod1Start)
504 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
505 QObject::tr(
"Daily wakeup today at %1",
"mythshutdown")
508 dtNextDailyWakeup = dtPeriod1Start;
513 if (!dtNextDailyWakeup.isValid() && dtPeriod2Start != dtPeriod2End)
515 if (dtCurrent < dtPeriod2Start)
517 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
518 QObject::tr(
"Daily wakeup today at %1",
"mythshutdown")
521 dtNextDailyWakeup = dtPeriod2Start;
528 if (!dtNextDailyWakeup.isValid())
530 if (dtPeriod1Start != dtPeriod1End)
531 dtNextDailyWakeup = dtPeriod1Start;
532 else if (dtPeriod2Start != dtPeriod2End)
533 dtNextDailyWakeup = dtPeriod2Start;
535 if (dtNextDailyWakeup.isValid())
537 dtNextDailyWakeup = dtNextDailyWakeup.addDays(1);
539 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
540 QObject::tr(
"Next daily wakeup is tomorrow at %1",
548 if (!dtNextDailyWakeup.isValid())
550 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
551 QObject::tr(
"Error: no daily wakeup times are set",
552 "mythshutdown") +
"\n");
556 QDateTime dtNextRecordingStart = QDateTime();
561 if (!dtNextRecordingStart.isValid())
563 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
564 QObject::tr(
"Error: no recording time is set",
"mythshutdown") +
569 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
570 QObject::tr(
"Recording scheduled at: %1",
"mythshutdown")
576 if (dtNextRecordingStart.isValid())
578 int delta = dtCurrent.secsTo(dtNextRecordingStart);
582 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
583 QObject::tr(
"Scheduled recording time has already passed. "
584 "Schedule deleted",
"mythshutdown") +
"\n");
586 dtNextRecordingStart = QDateTime();
591 QDateTime dtWakeupTime = QDateTime();
597 if (!dtNextRecordingStart.isValid() && !dtNextDailyWakeup.isValid())
599 dtWakeupTime = QDateTime();
600 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
601 QObject::tr(
"Error: no wake up time set and no scheduled program",
602 "mythshutdown") +
"\n");
607 if (dtNextRecordingStart.isValid() && !dtNextDailyWakeup.isValid())
609 dtWakeupTime = dtNextRecordingStart;
610 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
611 QObject::tr(
"Will wake up at next scheduled program",
612 "mythshutdown") +
"\n");
617 if (!dtNextRecordingStart.isValid() && dtNextDailyWakeup.isValid())
619 dtWakeupTime = dtNextDailyWakeup;
620 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
621 QObject::tr(
"Will wake up at next daily wakeup",
622 "mythshutdown") +
"\n");
628 if (dtNextRecordingStart.isValid() && dtNextDailyWakeup.isValid())
630 if (dtNextDailyWakeup < dtNextRecordingStart)
632 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
633 QObject::tr(
"Program is scheduled but will "
634 "wake up at next daily wakeup",
635 "mythshutdown") +
"\n");
636 dtWakeupTime = dtNextDailyWakeup;
640 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
641 QObject::tr(
"Daily wakeup is set but will wake up "
642 "at next scheduled program",
643 "mythshutdown") +
"\n");
644 dtWakeupTime = dtNextRecordingStart;
655 int shutdownmode = 0;
656 QString nvramRestartCmd =
659 if (dtWakeupTime.isValid())
666 QString nvramCommand =
668 "MythShutdownNvramCmd",
669 "/usr/bin/nvram-wakeup --settime $time");
672 "MythShutdownWakeupTimeFmt",
"time_t");
674 if (wakeup_timeformat ==
"time_t")
677 nvramCommand.replace(
678 "$time", time_ts.setNum(dtWakeupTime.toSecsSinceEpoch())
683 nvramCommand.replace(
684 "$time", dtWakeupTime.toLocalTime()
685 .toString(wakeup_timeformat));
688 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
689 QObject::tr(
"Sending command to set time in BIOS %1",
691 .arg(nvramCommand) +
"\n");
695 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
696 QObject::tr(
"Program %1 exited with code %2",
"mythshutdown")
697 .arg(nvramCommand).arg(shutdownmode) +
"\n");
699 if (shutdownmode == 2)
701 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
702 QObject::tr(
"Error: nvram-wakeup failed to "
703 "set time in BIOS",
"mythshutdown") +
"\n");
709 if (nvramRestartCmd.isEmpty())
716 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
717 QObject::tr(
"The next wakeup time is less than "
718 "15 mins away, not shutting down.",
719 "mythshutdown") +
"\n");
726 switch (shutdownmode)
730 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
731 QObject::tr(
"everything looks fine, shutting down ...",
732 "mythshutdown") +
"\n");
734 "MythShutdownPoweroff",
"/sbin/poweroff");
735 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
736 "..\n.\n" + QObject::tr(
"shutting down",
"mythshutdown") +
745 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
746 QObject::tr(
"Everything looks fine, but reboot is needed",
747 "mythshutdown") +
"\n");
748 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
749 QObject::tr(
"Sending command to bootloader",
"mythshutdown") +
751 LOG(VB_STDIO|VB_FLUSH, LOG_ERR, nvramRestartCmd);
755 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
756 "..\n.\n" + QObject::tr(
"rebooting",
"mythshutdown") +
766 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
767 QObject::tr(
"Error: Invalid shutdown mode, doing nothing.",
768 "mythshutdown") +
"\n");
778 LOG(VB_GENERAL, LOG_INFO,
"Mythshutdown: --startup");
781 QDateTime startupTime = QDateTime();
787 if (!startupTime.isValid())
794 delta = std::chrono::abs(delta);
804 LOG(VB_GENERAL, LOG_INFO,
805 QString(
"looks like we were started manually: %1").arg(res));
809 LOG(VB_GENERAL, LOG_INFO,
810 QString(
"looks like we were started automatically: %1").arg(res));
814 LOG(VB_GENERAL, LOG_INFO,
815 QString(
"Mythshutdown: --startup returned: %1").arg(res));
820 int main(
int argc,
char **argv)
841 QCoreApplication a(argc, argv);
855 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
"Error: "
856 "Could not initialize MythContext. Exiting.\n");
884 QDateTime wakeuptime = (utc) ?
888 if (!wakeuptime.isValid())
890 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
891 QObject::tr(
"Error: "
892 "--setwakeup invalid date format (%1)\n\t\t\t"
893 "must be yyyy-MM-ddThh:mm:ss",
"mythshutdown")