9 #include <QCoreApplication>
21 #include "libmythbase/mythversion.h"
34 QString value = (v.isNull()) ? QString(
"") : v;
39 query.
prepare(
"DELETE FROM settings WHERE value = :KEY;");
45 query.
prepare(
"INSERT INTO settings ( value, data ) "
46 "VALUES ( :VALUE, :DATA );");
55 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
56 QString(
"Error: Database not open while trying "
57 "to save setting: %1\n").arg(key));
63 QString value = defaultval;
68 query.
prepare(
"SELECT data FROM settings WHERE value = :KEY AND "
72 value = query.
value(0).toString();
76 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
77 QObject::tr(
"Error: Database not open while trying to "
78 "load setting: %1",
"mythshutdown").arg(key) +
"\n");
86 LOG(VB_GENERAL, LOG_INFO,
"Mythshutdown: --lock");
92 while (!query.
exec(
"LOCK TABLE settings WRITE;") && tries < 5)
94 LOG(VB_GENERAL, LOG_INFO,
"Waiting for lock on setting table");
101 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
102 QObject::tr(
"Error: Waited too long to obtain "
103 "lock on setting table",
"mythshutdown") +
"\n");
108 query.
prepare(
"SELECT * FROM settings "
109 "WHERE value = 'MythShutdownLock' AND hostname IS NULL;");
113 if (query.
size() < 1)
116 query.
prepare(
"INSERT INTO settings (value, data) "
117 "VALUES ('MythShutdownLock', '1');");
124 query.
prepare(
"UPDATE settings SET data = data + 1 "
125 "WHERE value = 'MythShutdownLock' "
126 "AND hostname IS NULL;");
132 if (!query.
exec(
"UNLOCK TABLES;"))
140 LOG(VB_GENERAL, LOG_INFO,
"Mythshutdown: --unlock");
146 while (!query.
exec(
"LOCK TABLE settings WRITE;") && tries < 5)
148 LOG(VB_GENERAL, LOG_INFO,
"Waiting for lock on setting table");
155 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
156 QObject::tr(
"Error: Waited too long to obtain "
157 "lock on setting table",
"mythshutdown") +
"\n");
162 query.
prepare(
"SELECT * FROM settings "
163 "WHERE value = 'MythShutdownLock' AND hostname IS NULL;");
167 if (query.
size() < 1)
170 query.
prepare(
"INSERT INTO settings (value, data) "
171 "VALUES ('MythShutdownLock', '0');");
178 query.
prepare(
"UPDATE settings SET data = GREATEST(0, data - 1) "
179 "WHERE value = 'MythShutdownLock' "
180 "AND hostname IS NULL;");
186 if (!query.
exec(
"UNLOCK TABLES;"))
210 QString command = QString(
"ps ch -C %1 -o pid > /dev/null").arg(program);
218 #if QT_VERSION < QT_VERSION_CHECK(6,5,0)
220 tTime, Qt::LocalTime).toUTC();
223 tTime, QTimeZone(QTimeZone::LocalTime)).toUTC();
231 LOG(VB_GENERAL, LOG_INFO,
232 "isRecording: Attempting to connect to master server...");
235 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
236 QObject::tr(
"Error: Could not connect to master server",
237 "mythshutdown") +
"\n");
247 LOG(VB_GENERAL, LOG_INFO,
"Mythshutdown: --status");
253 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
254 QObject::tr(
"Transcoding in progress...",
"mythshutdown") +
"\n");
260 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
261 QObject::tr(
"Commercial Detection in progress...",
262 "mythshutdown") +
"\n");
268 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
269 QObject::tr(
"Grabbing EPG data in progress...",
"mythshutdown") +
276 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
277 QObject::tr(
"Recording in progress...",
"mythshutdown") +
"\n");
283 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
284 QObject::tr(
"Shutdown is locked",
"mythshutdown") +
"\n");
290 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
291 QObject::tr(
"Has queued or pending jobs",
"mythshutdown") +
"\n");
302 if (dtPeriod1End < dtPeriod1Start)
304 if (dtCurrent > dtPeriod1End)
305 dtPeriod1End = dtPeriod1End.addDays(1);
307 dtPeriod1Start = dtPeriod1Start.addDays(-1);
310 if (dtPeriod2End < dtPeriod2Start)
312 if (dtCurrent > dtPeriod2End)
313 dtPeriod2End = dtPeriod2End.addDays(1);
315 dtPeriod2Start = dtPeriod2Start.addDays(-1);
319 if (dtPeriod1Start != dtPeriod1End)
321 if (dtCurrent >= dtPeriod1Start && dtCurrent <= dtPeriod1End)
323 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
324 QObject::tr(
"In a daily wakeup period (1).",
"mythshutdown") +
330 if (dtPeriod2Start != dtPeriod2End)
332 if (dtCurrent >= dtPeriod2Start && dtCurrent <= dtPeriod2End)
334 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
335 QObject::tr(
"In a daily wakeup period (2).",
"mythshutdown") +
343 if (dtPeriod1Start != dtPeriod1End)
345 auto delta = std::chrono::seconds(dtCurrent.secsTo(dtPeriod1Start));
346 if (delta >= 0s && delta <= 15min)
348 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
349 QObject::tr(
"About to start daily wakeup period (1)",
350 "mythshutdown") +
"\n");
355 if (dtPeriod2Start != dtPeriod2End)
357 auto delta = std::chrono::seconds(dtCurrent.secsTo(dtPeriod2Start));
358 if (delta >= 0s && delta <= 15min)
360 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
361 QObject::tr(
"About to start daily wakeup period (2)",
362 "mythshutdown") +
"\n");
369 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
370 QObject::tr(
"Setup is running...",
"mythshutdown") +
"\n");
374 LOG(VB_GENERAL, LOG_INFO,
375 QObject::tr(
"Mythshutdown: --status returned: %1",
376 "mythshutdown").arg(res) +
"\n");
386 LOG(VB_GENERAL, LOG_INFO,
"Mythshutdown: --check");
392 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
393 QObject::tr(
"Not OK to shutdown",
"mythshutdown") +
"\n");
398 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
399 QObject::tr(
"OK to shutdown",
"mythshutdown") +
"\n");
403 LOG(VB_GENERAL, LOG_INFO,
404 QString(
"Mythshutdown: --check returned: %1").arg(res));
411 LOG(VB_GENERAL, LOG_INFO,
"Mythshutdown: --setwakeup");
413 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
414 QObject::tr(
"Wakeup time given is: %1 (local time)",
"mythshutdown")
425 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
426 QObject::tr(
"Setting scheduled wakeup time: "
427 "Attempting to connect to master server...",
428 "mythshutdown") +
"\n");
431 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
432 QObject::tr(
"Setting scheduled wakeup time: "
433 "Could not connect to master server!",
434 "mythshutdown") +
"\n");
439 QDateTime nextRecordingStart;
443 if (!nextRecordingStart.isNull())
446 QDateTime restarttime = nextRecordingStart
447 .addSecs((-1LL) * m_preRollSeconds);
450 "StartupSecsBeforeRecording", 240);
453 restarttime = restarttime.addSecs((-1LL) * add);
464 LOG(VB_GENERAL, LOG_INFO,
"Mythshutdown: --shutdown");
472 QDateTime dtNextDailyWakeup = QDateTime();
475 if (dtPeriod2Start < dtPeriod1Start)
477 QDateTime temp = dtPeriod1Start;
478 dtPeriod1Start = dtPeriod2Start;
479 dtPeriod2Start = temp;
481 dtPeriod1End = dtPeriod2End;
486 if (dtPeriod1End < dtPeriod1Start)
488 if (dtCurrent > dtPeriod1End)
489 dtPeriod1End = dtPeriod1End.addDays(1);
491 dtPeriod1Start = dtPeriod1Start.addDays(-1);
494 if (dtPeriod2End < dtPeriod2Start)
496 if (dtCurrent > dtPeriod2End)
497 dtPeriod2End = dtPeriod2End.addDays(1);
499 dtPeriod2Start = dtPeriod2Start.addDays(-1);
503 if (dtPeriod1Start != dtPeriod1End)
505 if (dtCurrent < dtPeriod1Start)
507 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
508 QObject::tr(
"Daily wakeup today at %1",
"mythshutdown")
511 dtNextDailyWakeup = dtPeriod1Start;
516 if (!dtNextDailyWakeup.isValid() && dtPeriod2Start != dtPeriod2End)
518 if (dtCurrent < dtPeriod2Start)
520 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
521 QObject::tr(
"Daily wakeup today at %1",
"mythshutdown")
524 dtNextDailyWakeup = dtPeriod2Start;
531 if (!dtNextDailyWakeup.isValid())
533 if (dtPeriod1Start != dtPeriod1End)
534 dtNextDailyWakeup = dtPeriod1Start;
535 else if (dtPeriod2Start != dtPeriod2End)
536 dtNextDailyWakeup = dtPeriod2Start;
538 if (dtNextDailyWakeup.isValid())
540 dtNextDailyWakeup = dtNextDailyWakeup.addDays(1);
542 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
543 QObject::tr(
"Next daily wakeup is tomorrow at %1",
551 if (!dtNextDailyWakeup.isValid())
553 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
554 QObject::tr(
"Error: no daily wakeup times are set",
555 "mythshutdown") +
"\n");
559 QDateTime dtNextRecordingStart = QDateTime();
564 if (!dtNextRecordingStart.isValid())
566 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
567 QObject::tr(
"Error: no recording time is set",
"mythshutdown") +
572 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
573 QObject::tr(
"Recording scheduled at: %1",
"mythshutdown")
579 if (dtNextRecordingStart.isValid())
581 int delta = dtCurrent.secsTo(dtNextRecordingStart);
585 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
586 QObject::tr(
"Scheduled recording time has already passed. "
587 "Schedule deleted",
"mythshutdown") +
"\n");
589 dtNextRecordingStart = QDateTime();
594 QDateTime dtWakeupTime = QDateTime();
600 if (!dtNextRecordingStart.isValid() && !dtNextDailyWakeup.isValid())
602 dtWakeupTime = QDateTime();
603 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
604 QObject::tr(
"Error: no wake up time set and no scheduled program",
605 "mythshutdown") +
"\n");
610 if (dtNextRecordingStart.isValid() && !dtNextDailyWakeup.isValid())
612 dtWakeupTime = dtNextRecordingStart;
613 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
614 QObject::tr(
"Will wake up at next scheduled program",
615 "mythshutdown") +
"\n");
620 if (!dtNextRecordingStart.isValid() && dtNextDailyWakeup.isValid())
622 dtWakeupTime = dtNextDailyWakeup;
623 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
624 QObject::tr(
"Will wake up at next daily wakeup",
625 "mythshutdown") +
"\n");
631 if (dtNextRecordingStart.isValid() && dtNextDailyWakeup.isValid())
633 if (dtNextDailyWakeup < dtNextRecordingStart)
635 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
636 QObject::tr(
"Program is scheduled but will "
637 "wake up at next daily wakeup",
638 "mythshutdown") +
"\n");
639 dtWakeupTime = dtNextDailyWakeup;
643 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
644 QObject::tr(
"Daily wakeup is set but will wake up "
645 "at next scheduled program",
646 "mythshutdown") +
"\n");
647 dtWakeupTime = dtNextRecordingStart;
658 int shutdownmode = 0;
659 QString nvramRestartCmd =
662 if (dtWakeupTime.isValid())
669 QString nvramCommand =
671 "MythShutdownNvramCmd",
672 "/usr/bin/nvram-wakeup --settime $time");
675 "MythShutdownWakeupTimeFmt",
"time_t");
677 if (wakeup_timeformat ==
"time_t")
680 nvramCommand.replace(
681 "$time", time_ts.setNum(dtWakeupTime.toSecsSinceEpoch())
686 nvramCommand.replace(
687 "$time", dtWakeupTime.toLocalTime()
688 .toString(wakeup_timeformat));
691 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
692 QObject::tr(
"Sending command to set time in BIOS %1",
694 .arg(nvramCommand) +
"\n");
698 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
699 QObject::tr(
"Program %1 exited with code %2",
"mythshutdown")
700 .arg(nvramCommand).arg(shutdownmode) +
"\n");
702 if (shutdownmode == 2)
704 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
705 QObject::tr(
"Error: nvram-wakeup failed to "
706 "set time in BIOS",
"mythshutdown") +
"\n");
712 if (nvramRestartCmd.isEmpty())
719 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
720 QObject::tr(
"The next wakeup time is less than "
721 "15 mins away, not shutting down.",
722 "mythshutdown") +
"\n");
729 switch (shutdownmode)
733 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
734 QObject::tr(
"everything looks fine, shutting down ...",
735 "mythshutdown") +
"\n");
737 "MythShutdownPoweroff",
"/sbin/poweroff");
738 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
739 "..\n.\n" + QObject::tr(
"shutting down",
"mythshutdown") +
748 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
749 QObject::tr(
"Everything looks fine, but reboot is needed",
750 "mythshutdown") +
"\n");
751 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
752 QObject::tr(
"Sending command to bootloader",
"mythshutdown") +
754 LOG(VB_STDIO|VB_FLUSH, LOG_ERR, nvramRestartCmd);
758 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
759 "..\n.\n" + QObject::tr(
"rebooting",
"mythshutdown") +
769 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
770 QObject::tr(
"Error: Invalid shutdown mode, doing nothing.",
771 "mythshutdown") +
"\n");
781 LOG(VB_GENERAL, LOG_INFO,
"Mythshutdown: --startup");
784 QDateTime startupTime = QDateTime();
790 if (!startupTime.isValid())
797 delta = std::chrono::abs(delta);
807 LOG(VB_GENERAL, LOG_INFO,
808 QString(
"looks like we were started manually: %1").arg(res));
812 LOG(VB_GENERAL, LOG_INFO,
813 QString(
"looks like we were started automatically: %1").arg(res));
817 LOG(VB_GENERAL, LOG_INFO,
818 QString(
"Mythshutdown: --startup returned: %1").arg(res));
823 int main(
int argc,
char **argv)
844 QCoreApplication a(argc, argv);
858 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
"Error: "
859 "Could not initialize MythContext. Exiting.\n");
887 QDateTime wakeuptime = (utc) ?
891 if (!wakeuptime.isValid())
893 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
894 QObject::tr(
"Error: "
895 "--setwakeup invalid date format (%1)\n\t\t\t"
896 "must be yyyy-MM-ddThh:mm:ss",
"mythshutdown")