7 #include <QCoreApplication> 29 QString value = (v.isNull()) ? QString(
"") : v;
34 query.
prepare(
"DELETE FROM settings WHERE value = :KEY;");
40 query.
prepare(
"INSERT INTO settings ( value, data ) " 41 "VALUES ( :VALUE, :DATA );");
50 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
51 QString(
"Error: Database not open while trying " 52 "to save setting: %1\n").arg(key));
58 QString value = defaultval;
63 query.
prepare(
"SELECT data FROM settings WHERE value = :KEY AND " 67 value = query.
value(0).toString();
71 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
72 QObject::tr(
"Error: Database not open while trying to " 73 "load setting: %1",
"mythshutdown").arg(key) +
"\n");
81 LOG(VB_GENERAL, LOG_INFO,
"Mythshutdown: --lock");
87 while (!query.
exec(
"LOCK TABLE settings WRITE;") && tries < 5)
89 LOG(VB_GENERAL, LOG_INFO,
"Waiting for lock on setting table");
96 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
97 QObject::tr(
"Error: Waited too long to obtain " 98 "lock on setting table",
"mythshutdown") +
"\n");
103 query.
prepare(
"SELECT * FROM settings " 104 "WHERE value = 'MythShutdownLock' AND hostname IS NULL;");
108 if (query.
size() < 1)
111 query.
prepare(
"INSERT INTO settings (value, data) " 112 "VALUES ('MythShutdownLock', '1');");
119 query.
prepare(
"UPDATE settings SET data = data + 1 " 120 "WHERE value = 'MythShutdownLock' " 121 "AND hostname IS NULL;");
127 if (!query.
exec(
"UNLOCK TABLES;"))
135 LOG(VB_GENERAL, LOG_INFO,
"Mythshutdown: --unlock");
141 while (!query.
exec(
"LOCK TABLE settings WRITE;") && tries < 5)
143 LOG(VB_GENERAL, LOG_INFO,
"Waiting for lock on setting table");
150 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
151 QObject::tr(
"Error: Waited too long to obtain " 152 "lock on setting table",
"mythshutdown") +
"\n");
157 query.
prepare(
"SELECT * FROM settings " 158 "WHERE value = 'MythShutdownLock' AND hostname IS NULL;");
162 if (query.
size() < 1)
165 query.
prepare(
"INSERT INTO settings (value, data) " 166 "VALUES ('MythShutdownLock', '0');");
173 query.
prepare(
"UPDATE settings SET data = GREATEST(0, data - 1) " 174 "WHERE value = 'MythShutdownLock' " 175 "AND hostname IS NULL;");
181 if (!query.
exec(
"UNLOCK TABLES;"))
205 QString command = QString(
"ps ch -C %1 -o pid > /dev/null").arg(program);
213 QDateTime dtDateTime = QDateTime(
215 tTime, Qt::LocalTime).toUTC();
224 LOG(VB_GENERAL, LOG_INFO,
225 "isRecording: Attempting to connect to master server...");
228 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
229 QObject::tr(
"Error: Could not connect to master server",
230 "mythshutdown") +
"\n");
240 LOG(VB_GENERAL, LOG_INFO,
"Mythshutdown: --status");
246 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
247 QObject::tr(
"Transcoding in progress...",
"mythshutdown") +
"\n");
253 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
254 QObject::tr(
"Commercial Detection in progress...",
255 "mythshutdown") +
"\n");
261 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
262 QObject::tr(
"Grabbing EPG data in progress...",
"mythshutdown") +
269 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
270 QObject::tr(
"Recording in progress...",
"mythshutdown") +
"\n");
276 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
277 QObject::tr(
"Shutdown is locked",
"mythshutdown") +
"\n");
283 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
284 QObject::tr(
"Has queued or pending jobs",
"mythshutdown") +
"\n");
295 if (dtPeriod1End < dtPeriod1Start)
297 if (dtCurrent > dtPeriod1End)
298 dtPeriod1End = dtPeriod1End.addDays(1);
300 dtPeriod1Start = dtPeriod1Start.addDays(-1);
303 if (dtPeriod2End < dtPeriod2Start)
305 if (dtCurrent > dtPeriod2End)
306 dtPeriod2End = dtPeriod2End.addDays(1);
308 dtPeriod2Start = dtPeriod2Start.addDays(-1);
312 if (dtPeriod1Start != dtPeriod1End)
314 if (dtCurrent >= dtPeriod1Start && dtCurrent <= dtPeriod1End)
316 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
317 QObject::tr(
"In a daily wakeup period (1).",
"mythshutdown") +
323 if (dtPeriod2Start != dtPeriod2End)
325 if (dtCurrent >= dtPeriod2Start && dtCurrent <= dtPeriod2End)
327 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
328 QObject::tr(
"In a daily wakeup period (2).",
"mythshutdown") +
336 if (dtPeriod1Start != dtPeriod1End)
338 int delta = dtCurrent.secsTo(dtPeriod1Start);
339 if (delta >= 0 && delta <= 15 * 60)
341 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
342 QObject::tr(
"About to start daily wakeup period (1)",
343 "mythshutdown") +
"\n");
348 if (dtPeriod2Start != dtPeriod2End)
350 int delta = dtCurrent.secsTo(dtPeriod2Start);
351 if (delta >= 0 && delta <= 15 * 60)
353 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
354 QObject::tr(
"About to start daily wakeup period (2)",
355 "mythshutdown") +
"\n");
362 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
363 QObject::tr(
"Setup is running...",
"mythshutdown") +
"\n");
367 LOG(VB_GENERAL, LOG_INFO,
368 QObject::tr(
"Mythshutdown: --status returned: %1",
369 "mythshutdown").arg(res) +
"\n");
379 LOG(VB_GENERAL, LOG_INFO,
"Mythshutdown: --check");
385 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
386 QObject::tr(
"Not OK to shutdown",
"mythshutdown") +
"\n");
391 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
392 QObject::tr(
"OK to shutdown",
"mythshutdown") +
"\n");
396 LOG(VB_GENERAL, LOG_INFO,
397 QString(
"Mythshutdown: --check returned: %1").arg(res));
404 LOG(VB_GENERAL, LOG_INFO,
"Mythshutdown: --setwakeup");
406 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
407 QObject::tr(
"Wakeup time given is: %1 (local time)",
"mythshutdown")
418 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
419 QObject::tr(
"Setting scheduled wakeup time: " 420 "Attempting to connect to master server...",
421 "mythshutdown") +
"\n");
424 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
425 QObject::tr(
"Setting scheduled wakeup time: " 426 "Could not connect to master server!",
427 "mythshutdown") +
"\n");
432 QDateTime nextRecordingStart;
436 if (!nextRecordingStart.isNull())
439 QDateTime restarttime = nextRecordingStart
440 .addSecs((-1) * m_preRollSeconds);
443 "StartupSecsBeforeRecording", 240);
446 restarttime = restarttime.addSecs((-1) * add);
457 LOG(VB_GENERAL, LOG_INFO,
"Mythshutdown: --shutdown");
465 QDateTime dtNextDailyWakeup = QDateTime();
468 if (dtPeriod2Start < dtPeriod1Start)
470 QDateTime temp = dtPeriod1Start;
471 dtPeriod1Start = dtPeriod2Start;
472 dtPeriod2Start = temp;
474 dtPeriod1End = dtPeriod2End;
479 if (dtPeriod1End < dtPeriod1Start)
481 if (dtCurrent > dtPeriod1End)
482 dtPeriod1End = dtPeriod1End.addDays(1);
484 dtPeriod1Start = dtPeriod1Start.addDays(-1);
487 if (dtPeriod2End < dtPeriod2Start)
489 if (dtCurrent > dtPeriod2End)
490 dtPeriod2End = dtPeriod2End.addDays(1);
492 dtPeriod2Start = dtPeriod2Start.addDays(-1);
496 if (dtPeriod1Start != dtPeriod1End)
498 if (dtCurrent < dtPeriod1Start)
500 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
501 QObject::tr(
"Daily wakeup today at %1",
"mythshutdown")
504 dtNextDailyWakeup = dtPeriod1Start;
509 if (!dtNextDailyWakeup.isValid() && dtPeriod2Start != dtPeriod2End)
511 if (dtCurrent < dtPeriod2Start)
513 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
514 QObject::tr(
"Daily wakeup today at %1",
"mythshutdown")
517 dtNextDailyWakeup = dtPeriod2Start;
524 if (!dtNextDailyWakeup.isValid())
526 if (dtPeriod1Start != dtPeriod1End)
527 dtNextDailyWakeup = dtPeriod1Start;
528 else if (dtPeriod2Start != dtPeriod2End)
529 dtNextDailyWakeup = dtPeriod2Start;
531 if (dtNextDailyWakeup.isValid())
533 dtNextDailyWakeup = dtNextDailyWakeup.addDays(1);
535 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
536 QObject::tr(
"Next daily wakeup is tomorrow at %1",
544 if (!dtNextDailyWakeup.isValid())
546 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
547 QObject::tr(
"Error: no daily wakeup times are set",
548 "mythshutdown") +
"\n");
552 QDateTime dtNextRecordingStart = QDateTime();
557 if (!dtNextRecordingStart.isValid())
559 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
560 QObject::tr(
"Error: no recording time is set",
"mythshutdown") +
565 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
566 QObject::tr(
"Recording scheduled at: %1",
"mythshutdown")
572 if (dtNextRecordingStart.isValid())
574 int delta = dtCurrent.secsTo(dtNextRecordingStart);
578 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
579 QObject::tr(
"Scheduled recording time has already passed. " 580 "Schedule deleted",
"mythshutdown") +
"\n");
582 dtNextRecordingStart = QDateTime();
587 QDateTime dtWakeupTime = QDateTime();
593 if (!dtNextRecordingStart.isValid() && !dtNextDailyWakeup.isValid())
595 dtWakeupTime = QDateTime();
596 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
597 QObject::tr(
"Error: no wake up time set and no scheduled program",
598 "mythshutdown") +
"\n");
603 if (dtNextRecordingStart.isValid() && !dtNextDailyWakeup.isValid())
605 dtWakeupTime = dtNextRecordingStart;
606 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
607 QObject::tr(
"Will wake up at next scheduled program",
608 "mythshutdown") +
"\n");
613 if (!dtNextRecordingStart.isValid() && dtNextDailyWakeup.isValid())
615 dtWakeupTime = dtNextDailyWakeup;
616 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
617 QObject::tr(
"Will wake up at next daily wakeup",
618 "mythshutdown") +
"\n");
624 if (dtNextRecordingStart.isValid() && dtNextDailyWakeup.isValid())
626 if (dtNextDailyWakeup < dtNextRecordingStart)
628 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
629 QObject::tr(
"Program is scheduled but will " 630 "wake up at next daily wakeup",
631 "mythshutdown") +
"\n");
632 dtWakeupTime = dtNextDailyWakeup;
636 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
637 QObject::tr(
"Daily wakeup is set but will wake up " 638 "at next scheduled program",
639 "mythshutdown") +
"\n");
640 dtWakeupTime = dtNextRecordingStart;
651 int shutdownmode = 0;
652 QString nvramRestartCmd =
655 if (dtWakeupTime.isValid())
662 QString nvramCommand =
664 "MythShutdownNvramCmd",
665 "/usr/bin/nvram-wakeup --settime $time");
668 "MythShutdownWakeupTimeFmt",
"time_t");
670 if (wakeup_timeformat ==
"time_t")
673 nvramCommand.replace(
674 #
if QT_VERSION < QT_VERSION_CHECK(5,8,0)
675 "$time", time_ts.setNum(dtWakeupTime.toTime_t())
677 "$time", time_ts.setNum(dtWakeupTime.toSecsSinceEpoch())
682 nvramCommand.replace(
683 "$time", dtWakeupTime.toLocalTime()
684 .toString(wakeup_timeformat));
686 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
687 QObject::tr(
"Sending command to set time in BIOS %1",
689 .arg(nvramCommand) +
"\n");
693 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
694 QObject::tr(
"Program %1 exited with code %2",
"mythshutdown")
695 .arg(nvramCommand).arg(shutdownmode) +
"\n");
697 if (shutdownmode == 2)
699 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
700 QObject::tr(
"Error: nvram-wakeup failed to " 701 "set time in BIOS",
"mythshutdown") +
"\n");
707 if (nvramRestartCmd.isEmpty())
714 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
715 QObject::tr(
"The next wakeup time is less than " 716 "15 mins away, not shutting down.",
717 "mythshutdown") +
"\n");
724 switch (shutdownmode)
728 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
729 QObject::tr(
"everything looks fine, shutting down ...",
730 "mythshutdown") +
"\n");
732 "MythShutdownPoweroff",
"/sbin/poweroff");
733 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
734 "..\n.\n" + QObject::tr(
"shutting down",
"mythshutdown") +
743 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
744 QObject::tr(
"Everything looks fine, but reboot is needed",
745 "mythshutdown") +
"\n");
746 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
747 QObject::tr(
"Sending command to bootloader",
"mythshutdown") +
749 LOG(VB_STDIO|VB_FLUSH, LOG_ERR, nvramRestartCmd);
753 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
754 "..\n.\n" + QObject::tr(
"rebooting",
"mythshutdown") +
764 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
765 QObject::tr(
"Error: Invalid shutdown mode, doing nothing.",
766 "mythshutdown") +
"\n");
776 LOG(VB_GENERAL, LOG_INFO,
"Mythshutdown: --startup");
779 QDateTime startupTime = QDateTime();
785 if (!startupTime.isValid())
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);
849 QList<int> signallist;
850 signallist << SIGINT << SIGTERM << SIGSEGV << SIGABRT << SIGBUS << SIGFPE
853 signallist << SIGRTMIN;
862 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
"Error: " 863 "Could not initialize MythContext. Exiting.\n");
891 QDateTime wakeuptime = (utc) ?
895 if (!wakeuptime.isValid())
897 LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
898 QObject::tr(
"Error: " 899 "--setwakeup invalid date format (%1)\n\t\t\t" 900 "must be yyyy-MM-ddThh:mm:ss",
"mythshutdown")
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
static bool isRecording()
Startup context for MythTV.
void bindValue(const QString &placeholder, const QVariant &val)
static bool HasRunningOrPendingJobs(int startingWithinMins=0)
int main(int argc, char **argv)
#define GENERIC_EXIT_OK
Exited with no error.
static int getStatus(bool bWantRecStatus)
static QString getGlobalSetting(const QString &key, const QString &defaultval)
#define MYTH_APPNAME_MYTHSHUTDOWN
QSqlQuery wrapper that fetches a DB connection from the connection pool.
void PrintHelp(void) const
Print command line option help.
bool GetNextRecordingList(QDateTime &nextRecordingStart, bool *hasConflicts, vector< ProgramInfo > *list)
bool ConnectToMasterServer(bool blockingClient=true, bool openEventSocket=true)
static void Init(QList< int > &signallist, QObject *parent=nullptr)
bool isConnected(void)
Only updated once during object creation.
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
bool toBool(QString key) const
Returns stored QVariant as a boolean.
MythContext * gContext
This global variable contains the MythContext instance for the application.
static int checkOKShutdown(bool bWantRecStatus)
unsigned sleep(unsigned int x)
void SendMessage(const QString &message)
static int lockShutdown()
QVariant value(int i) const
bool Init(const bool gui=true, const bool promptForBackend=false, const bool bypassAutoDiscovery=false, const bool ignoreDB=false)
static bool isRunning(const char *program)
Returns true if a program containing the specified string is running on this machine.
bool IsConnectedToMaster(void)
static void setGlobalSetting(const QString &key, const QString &v)
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
QString GetSetting(const QString &key, const QString &defaultval="")
bool isActive(void) const
QString toString(QString key) const
Returns stored QVariant as a QString, falling to default if not provided.
static MSqlQueryInfo InitCon(ConnectionReuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
MythCommFlagCommandLineParser cmdline
uint myth_system(const QString &command, uint flags, uint timeout)
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
static GlobalSpinBoxSetting * idleWaitForRecordingTime()
static void setWakeupTime(const QDateTime &wakeupTime)
int GetNumSetting(const QString &key, int defaultval=0)
static int setScheduledWakeupTime()
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
#define LOG(_MASK_, _LEVEL_, _STRING_)
virtual bool Parse(int argc, const char *const *argv)
Loop through argv and populate arguments with values.
#define MYTH_BINARY_VERSION
Update this whenever the plug-in ABI changes.
Default UTC, database format.
int toInt(QString key) const
Returns stored QVariant as an integer, falling to default if not provided.
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
int ConfigureLogging(QString mask="general", unsigned int progress=0)
Read in logging options and initialize the logging interface.
static QDateTime getDailyWakeupTime(QString sPeriod)
#define GENERIC_EXIT_NO_MYTHCONTEXT
No MythContext available.
static void SetHandler(int signal, SigHandlerFunc handler)
static void DBError(const QString &where, const MSqlQuery &query)
#define GENERIC_EXIT_INVALID_CMDLINE
Command line parse error.
static int unlockShutdown()
int RemoteGetRecordingStatus(const ProgramInfo *pginfo, int overrecsecs, int underrecsecs)
Get status of an individual programme (with pre-post roll?).
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.
void PrintVersion(void) const
Print application version information.