00001
00002 #include <iostream>
00003 #include <cstdlib>
00004 using namespace std;
00005 #include <unistd.h>
00006
00007 #include <QCoreApplication>
00008 #include <QFile>
00009
00010 #include "exitcodes.h"
00011 #include "mythcontext.h"
00012 #include "mythdb.h"
00013 #include "mythsystem.h"
00014 #include "mythversion.h"
00015 #include "jobqueue.h"
00016 #include "tv.h"
00017 #include "remoteutil.h"
00018 #include "tvremoteutil.h"
00019 #include "compat.h"
00020 #include "mythlogging.h"
00021 #include "commandlineparser.h"
00022 #include "programinfo.h"
00023
00024 static void setGlobalSetting(const QString &key, const QString &value)
00025 {
00026 MSqlQuery query(MSqlQuery::InitCon());
00027 if (query.isConnected())
00028 {
00029 query.prepare("DELETE FROM settings WHERE value = :KEY;");
00030 query.bindValue(":KEY", key);
00031
00032 if (!query.exec() || !query.isActive())
00033 MythDB::DBError("Clear setting", query);
00034
00035 query.prepare("INSERT INTO settings ( value, data ) "
00036 "VALUES ( :VALUE, :DATA );");
00037 query.bindValue(":VALUE", key);
00038 query.bindValue(":DATA", value);
00039
00040 if (!query.exec() || !query.isActive())
00041 MythDB::DBError("Save new global setting", query);
00042 }
00043 else
00044 {
00045 LOG(VB_GENERAL, LOG_ERR,
00046 QString("Database not open while trying to save setting: %1")
00047 .arg(key));
00048 }
00049 }
00050
00051 static QString getGlobalSetting(const QString &key, const QString &defaultval)
00052 {
00053 QString value = defaultval;
00054
00055 MSqlQuery query(MSqlQuery::InitCon());
00056 if (query.isConnected())
00057 {
00058 query.prepare("SELECT data FROM settings WHERE value = :KEY AND "
00059 "hostname IS NULL;");
00060 query.bindValue(":KEY", key);
00061 if (query.exec() && query.next())
00062 value = query.value(0).toString();
00063 }
00064 else
00065 {
00066 LOG(VB_GENERAL, LOG_ERR,
00067 QString("Database not open while trying to load setting: %1")
00068 .arg(key));
00069 }
00070
00071 return value;
00072 }
00073
00074 static int lockShutdown()
00075 {
00076 LOG(VB_GENERAL, LOG_INFO, "Mythshutdown: --lock");
00077
00078 MSqlQuery query(MSqlQuery::InitCon());
00079
00080
00081 int tries = 0;
00082 while (!query.exec("LOCK TABLE settings WRITE;") && tries < 5)
00083 {
00084 LOG(VB_GENERAL, LOG_INFO, "Waiting for lock on setting table");
00085 sleep(1);
00086 tries++;
00087 }
00088
00089 if (tries >= 5)
00090 {
00091 LOG(VB_GENERAL, LOG_ERR,
00092 "Waited too long to obtain lock on setting table");
00093 return 1;
00094 }
00095
00096
00097 query.prepare("SELECT * FROM settings "
00098 "WHERE value = 'MythShutdownLock' AND hostname IS NULL;");
00099 if (!query.exec())
00100 MythDB::DBError("lockShutdown -- select", query);
00101
00102 if (query.size() < 1)
00103 {
00104
00105 query.prepare("INSERT INTO settings (value, data) "
00106 "VALUES ('MythShutdownLock', '1');");
00107 if (!query.exec())
00108 MythDB::DBError("lockShutdown -- insert", query);
00109 }
00110 else
00111 {
00112
00113 query.prepare("UPDATE settings SET data = data + 1 "
00114 "WHERE value = 'MythShutdownLock' "
00115 "AND hostname IS NULL;");
00116 if (!query.exec())
00117 MythDB::DBError("lockShutdown -- update", query);
00118 }
00119
00120
00121 if (!query.exec("UNLOCK TABLES;"))
00122 MythDB::DBError("lockShutdown -- unlock", query);
00123
00124 return 0;
00125 }
00126
00127 static int unlockShutdown()
00128 {
00129 LOG(VB_GENERAL, LOG_INFO, "Mythshutdown: --unlock");
00130
00131 MSqlQuery query(MSqlQuery::InitCon());
00132
00133
00134 int tries = 0;
00135 while (!query.exec("LOCK TABLE settings WRITE;") && tries < 5)
00136 {
00137 LOG(VB_GENERAL, LOG_INFO, "Waiting for lock on setting table");
00138 sleep(1);
00139 tries++;
00140 }
00141
00142 if (tries >= 5)
00143 {
00144 LOG(VB_GENERAL, LOG_ERR,
00145 "Waited too long to obtain lock on setting table");
00146 return 1;
00147 }
00148
00149
00150 query.prepare("SELECT * FROM settings "
00151 "WHERE value = 'MythShutdownLock' AND hostname IS NULL;");
00152 if (!query.exec())
00153 MythDB::DBError("unlockShutdown -- select", query);
00154
00155 if (query.size() < 1)
00156 {
00157
00158 query.prepare("INSERT INTO settings (value, data) "
00159 "VALUES ('MythShutdownLock', '0');");
00160 if (!query.exec())
00161 MythDB::DBError("unlockShutdown -- insert", query);
00162 }
00163 else
00164 {
00165
00166 query.prepare("UPDATE settings SET data = GREATEST(0, data - 1) "
00167 "WHERE value = 'MythShutdownLock' "
00168 "AND hostname IS NULL;");
00169 if (!query.exec())
00170 MythDB::DBError("unlockShutdown -- update", query);
00171 }
00172
00173
00174 if (!query.exec("UNLOCK TABLES;"))
00175 MythDB::DBError("unlockShutdown -- unlock", query);
00176
00177
00178 gCoreContext->SendMessage("RESET_IDLETIME");
00179
00180 return 0;
00181 }
00182
00196 static bool isRunning(const char *program)
00197 {
00198 QString command = QString("ps ch -C %1 -o pid > /dev/null").arg(program);
00199 return (myth_system(command) == GENERIC_EXIT_OK);
00200 }
00201
00202 static QDateTime getDailyWakeupTime(QString sPeriod)
00203 {
00204 QString sTime = getGlobalSetting(sPeriod, "00:00");
00205 QTime tTime = QTime::fromString(sTime, "hh:mm");
00206 QDateTime dtDateTime = QDateTime(QDate::currentDate(), tTime);
00207
00208 return dtDateTime;
00209 }
00210
00211 static bool isRecording()
00212 {
00213 if (!gCoreContext->IsConnectedToMaster())
00214 {
00215 LOG(VB_GENERAL, LOG_NOTICE,
00216 "isRecording: Attempting to connect to master server...");
00217 if (!gCoreContext->ConnectToMasterServer(false))
00218 {
00219 LOG(VB_GENERAL, LOG_ERR,
00220 "isRecording: Could not connect to master server!");
00221 return false;
00222 }
00223 }
00224
00225 return RemoteGetRecordingStatus(NULL, false);
00226 }
00227
00228 static int getStatus(bool bWantRecStatus)
00229 {
00230 LOG(VB_GENERAL, LOG_INFO, "Mythshutdown: --status");
00231
00232 int res = 0;
00233
00234 if (isRunning("mythtranscode"))
00235 {
00236 LOG(VB_GENERAL, LOG_NOTICE, "Transcoding in progress...");
00237 res |= 1;
00238 }
00239
00240 if (isRunning("mythcommflag"))
00241 {
00242 LOG(VB_GENERAL, LOG_NOTICE, "Commercial Detection in progress...");
00243 res |= 2;
00244 }
00245
00246 if (isRunning("mythfilldatabase"))
00247 {
00248 LOG(VB_GENERAL, LOG_NOTICE, "Grabbing EPG data in progress...");
00249 res |= 4;
00250 }
00251
00252 if (bWantRecStatus && isRecording())
00253 {
00254 LOG(VB_GENERAL, LOG_NOTICE, "Recording in progress...");
00255 res |= 8;
00256 }
00257
00258 if (getGlobalSetting("MythShutdownLock", "0") != "0")
00259 {
00260 LOG(VB_GENERAL, LOG_NOTICE, "Shutdown is locked");
00261 res |= 16;
00262 }
00263
00264 if (JobQueue::HasRunningOrPendingJobs(15))
00265 {
00266 LOG(VB_GENERAL, LOG_NOTICE, "Has queued or pending jobs");
00267 res |= 32;
00268 }
00269
00270 QDateTime dtPeriod1Start = getDailyWakeupTime("DailyWakeupStartPeriod1");
00271 QDateTime dtPeriod1End = getDailyWakeupTime("DailyWakeupEndPeriod1");
00272 QDateTime dtPeriod2Start = getDailyWakeupTime("DailyWakeupStartPeriod2");
00273 QDateTime dtPeriod2End = getDailyWakeupTime("DailyWakeupEndPeriod2");
00274 QDateTime dtCurrent = QDateTime::currentDateTime();
00275
00276
00277 if (dtPeriod1End < dtPeriod1Start)
00278 {
00279 if (dtCurrent > dtPeriod1End)
00280 dtPeriod1End = dtPeriod1End.addDays(1);
00281 else
00282 dtPeriod1Start = dtPeriod1Start.addDays(-1);
00283 }
00284
00285 if (dtPeriod2End < dtPeriod2Start)
00286 {
00287 if (dtCurrent > dtPeriod2End)
00288 dtPeriod2End = dtPeriod2End.addDays(1);
00289 else
00290 dtPeriod2Start = dtPeriod2Start.addDays(-1);
00291 }
00292
00293
00294 if (dtPeriod1Start != dtPeriod1End)
00295 {
00296 if (dtCurrent >= dtPeriod1Start && dtCurrent <= dtPeriod1End)
00297 {
00298 LOG(VB_GENERAL, LOG_NOTICE, "In a daily wakeup period (1).");
00299 res |= 64;
00300 }
00301 }
00302
00303 if (dtPeriod2Start != dtPeriod2End)
00304 {
00305 if (dtCurrent >= dtPeriod2Start && dtCurrent <= dtPeriod2End)
00306 {
00307 LOG(VB_GENERAL, LOG_NOTICE, "In a daily wakeup period (2).");
00308 res |= 64;
00309 }
00310 }
00311
00312
00313
00314 if (dtPeriod1Start != dtPeriod1End)
00315 {
00316 int delta = dtCurrent.secsTo(dtPeriod1Start);
00317 if (delta >= 0 && delta <= 15 * 60)
00318 {
00319 LOG(VB_GENERAL, LOG_NOTICE,
00320 "About to start daily wakeup period (1)");
00321 res |= 128;
00322 }
00323 }
00324
00325 if (dtPeriod2Start != dtPeriod2End)
00326 {
00327 int delta = dtCurrent.secsTo(dtPeriod2Start);
00328 if (delta >= 0 && delta <= 15 * 60)
00329 {
00330 LOG(VB_GENERAL, LOG_NOTICE,
00331 "About to start daily wakeup period (2)");
00332 res |= 128;
00333 }
00334 }
00335
00336 if (isRunning("mythtv-setup"))
00337 {
00338 LOG(VB_GENERAL, LOG_NOTICE, "Setup is running...");
00339 res = 255;
00340 }
00341
00342 LOG(VB_GENERAL, LOG_INFO,
00343 QString("Mythshutdown: --status returned: %1").arg(res));
00344
00345 return res;
00346 }
00347
00348 static int checkOKShutdown(bool bWantRecStatus)
00349 {
00350
00351
00352
00353 LOG(VB_GENERAL, LOG_INFO, "Mythshutdown: --check");
00354
00355 int res = getStatus(bWantRecStatus);
00356
00357 if (res > 0)
00358 {
00359 LOG(VB_GENERAL, LOG_NOTICE, "Not OK to shutdown");
00360 res = 1;
00361 }
00362 else
00363 {
00364 LOG(VB_GENERAL, LOG_NOTICE, "OK to shutdown");
00365 res = 0;
00366 }
00367
00368 LOG(VB_GENERAL, LOG_INFO,
00369 QString("Mythshutdown: --check returned: %1").arg(res));
00370
00371 return res;
00372 }
00373
00374 static int setWakeupTime(QString sWakeupTime)
00375 {
00376 LOG(VB_GENERAL, LOG_INFO, "Mythshutdown: --setwakeup");
00377
00378 LOG(VB_GENERAL, LOG_NOTICE,
00379 QString("Mythshutdown: wakeup time given is: %1").arg(sWakeupTime));
00380
00381
00382 QDateTime dtWakeupTime;
00383 dtWakeupTime = QDateTime::fromString(sWakeupTime, Qt::ISODate);
00384
00385 if (!dtWakeupTime.isValid())
00386 {
00387 LOG(VB_GENERAL, LOG_ERR,
00388 QString("Mythshutdown: --setwakeup invalid date "
00389 "format (%1)\n\t\t\t"
00390 "must be yyyy-MM-ddThh:mm:ss")
00391 .arg(sWakeupTime));
00392 return 1;
00393 }
00394
00395 setGlobalSetting("MythShutdownNextScheduled",
00396 dtWakeupTime.toString(Qt::ISODate));
00397
00398 return 0;
00399 }
00400
00401 static int setScheduledWakeupTime()
00402 {
00403 if (!gCoreContext->IsConnectedToMaster())
00404 {
00405 LOG(VB_GENERAL, LOG_NOTICE,
00406 "setScheduledWakeupTime: "
00407 "Attempting to connect to master server...");
00408 if (!gCoreContext->ConnectToMasterServer(false))
00409 {
00410 LOG(VB_GENERAL, LOG_NOTICE,
00411 "setScheduledWakeupTime: "
00412 "Could not connect to master server!");
00413 return 1;
00414 }
00415 }
00416
00417 QDateTime nextRecordingStart;
00418 GetNextRecordingList(nextRecordingStart);
00419
00420
00421 if (!nextRecordingStart.isNull())
00422 {
00423 int m_preRollSeconds = gCoreContext->GetNumSetting("RecordPreRoll");
00424 QDateTime restarttime = nextRecordingStart
00425 .addSecs((-1) * m_preRollSeconds);
00426
00427 int add = gCoreContext->GetNumSetting("StartupSecsBeforeRecording", 240);
00428 if (add)
00429 restarttime = restarttime.addSecs((-1) * add);
00430
00431 setWakeupTime(restarttime.toString(Qt::ISODate));
00432
00433 return 0;
00434 }
00435 return 1;
00436 }
00437
00438 static int shutdown()
00439 {
00440 LOG(VB_GENERAL, LOG_INFO, "Mythshutdown: --shutdown");
00441
00442
00443 QDateTime dtPeriod1Start = getDailyWakeupTime("DailyWakeupStartPeriod1");
00444 QDateTime dtPeriod1End = getDailyWakeupTime("DailyWakeupEndPeriod1");
00445 QDateTime dtPeriod2Start = getDailyWakeupTime("DailyWakeupStartPeriod2");
00446 QDateTime dtPeriod2End = getDailyWakeupTime("DailyWakeupEndPeriod2");
00447 QDateTime dtCurrent = QDateTime::currentDateTime();
00448 QDateTime dtNextDailyWakeup = QDateTime();
00449
00450
00451 if (dtPeriod2Start < dtPeriod1Start)
00452 {
00453 QDateTime temp = dtPeriod1Start;
00454 dtPeriod1Start = dtPeriod2Start;
00455 dtPeriod2Start = temp;
00456 temp = dtPeriod1End;
00457 dtPeriod1End = dtPeriod2End;
00458 dtPeriod2End = temp;
00459 }
00460
00461
00462 if (dtPeriod1End < dtPeriod1Start)
00463 {
00464 if (dtCurrent > dtPeriod1End)
00465 dtPeriod1End = dtPeriod1End.addDays(1);
00466 else
00467 dtPeriod1Start = dtPeriod1Start.addDays(-1);
00468 }
00469
00470 if (dtPeriod2End < dtPeriod2Start)
00471 {
00472 if (dtCurrent > dtPeriod2End)
00473 dtPeriod2End = dtPeriod2End.addDays(1);
00474 else
00475 dtPeriod2Start = dtPeriod2Start.addDays(-1);
00476 }
00477
00478
00479 if (dtPeriod1Start != dtPeriod1End)
00480 {
00481 if (dtCurrent < dtPeriod1Start)
00482 {
00483 LOG(VB_GENERAL, LOG_NOTICE,
00484 "daily wakeup today at " + dtPeriod1Start.toString("hh:mm:ss"));
00485 dtNextDailyWakeup = dtPeriod1Start;
00486 }
00487 }
00488
00489
00490 if (!dtNextDailyWakeup.isValid() && dtPeriod2Start != dtPeriod2End)
00491 {
00492 if (dtCurrent < dtPeriod2Start)
00493 {
00494 LOG(VB_GENERAL, LOG_NOTICE,
00495 "daily wakeup today at " + dtPeriod2Start.toString("hh:mm:ss"));
00496 dtNextDailyWakeup = dtPeriod2Start;
00497 }
00498 }
00499
00500
00501
00502
00503 if (!dtNextDailyWakeup.isValid())
00504 {
00505 if (dtPeriod1Start != dtPeriod1End)
00506 dtNextDailyWakeup = dtPeriod1Start;
00507 else if (dtPeriod2Start != dtPeriod2End)
00508 dtNextDailyWakeup = dtPeriod2Start;
00509
00510 if (dtNextDailyWakeup.isValid())
00511 {
00512 dtNextDailyWakeup = dtNextDailyWakeup.addDays(1);
00513
00514 LOG(VB_GENERAL, LOG_NOTICE, "next daily wakeup is tomorrow at " +
00515 dtNextDailyWakeup.toString("hh:mm:ss"));
00516 }
00517 }
00518
00519
00520 if (!dtNextDailyWakeup.isValid())
00521 LOG(VB_GENERAL, LOG_ERR, "no daily wakeup times are set");
00522
00523
00524 QDateTime dtNextRecordingStart = QDateTime();
00525 QString s = getGlobalSetting("MythShutdownNextScheduled", "");
00526 if (!s.isEmpty())
00527 dtNextRecordingStart = QDateTime::fromString(s, Qt::ISODate);
00528
00529 if (!dtNextRecordingStart.isValid())
00530 LOG(VB_GENERAL, LOG_ERR, "no recording time is set");
00531 else
00532 LOG(VB_GENERAL, LOG_NOTICE, "recording scheduled at: " +
00533 dtNextRecordingStart.toString(Qt::ISODate));
00534
00535
00536 if (dtNextRecordingStart.isValid())
00537 {
00538 int delta = dtCurrent.secsTo(dtNextRecordingStart);
00539
00540 if (delta < 0)
00541 {
00542 LOG(VB_GENERAL, LOG_NOTICE,
00543 "Scheduled recording time has already passed. "
00544 "Schedule deleted");
00545
00546 dtNextRecordingStart = QDateTime();
00547 setGlobalSetting("MythShutdownNextScheduled", "");
00548 }
00549 }
00550
00551 QDateTime dtWakeupTime = QDateTime();
00552
00553
00554
00555
00556
00557 if (!dtNextRecordingStart.isValid() && !dtNextDailyWakeup.isValid())
00558 {
00559 dtWakeupTime = QDateTime();
00560 LOG(VB_GENERAL, LOG_ERR,
00561 "no wake up time set and no scheduled program");
00562 }
00563
00564
00565
00566 if (dtNextRecordingStart.isValid() && !dtNextDailyWakeup.isValid())
00567 {
00568 dtWakeupTime = dtNextRecordingStart;
00569 LOG(VB_GENERAL, LOG_NOTICE, "will wake up at next scheduled program");
00570 }
00571
00572
00573
00574 if (!dtNextRecordingStart.isValid() && dtNextDailyWakeup.isValid())
00575 {
00576 dtWakeupTime = dtNextDailyWakeup;
00577 LOG(VB_GENERAL, LOG_NOTICE, "will wake up at next daily wakeup");
00578 }
00579
00580
00581
00582
00583 if (dtNextRecordingStart.isValid() && dtNextDailyWakeup.isValid())
00584 {
00585 if (dtNextDailyWakeup < dtNextRecordingStart)
00586 {
00587 LOG(VB_GENERAL, LOG_NOTICE,
00588 "program is scheduled but will wake up at next daily wakeup");
00589 dtWakeupTime = dtNextDailyWakeup;
00590 }
00591 else
00592 {
00593 LOG(VB_GENERAL, LOG_NOTICE, "daily wakeup is set but will wake up "
00594 "at next scheduled program");
00595 dtWakeupTime = dtNextRecordingStart;
00596 }
00597 }
00598
00599
00600 setGlobalSetting("MythShutdownWakeupTime",
00601 dtWakeupTime.toString(Qt::ISODate));
00602
00603
00604
00605
00606 int shutdownmode = 0;
00607 QString nvramRestartCmd =
00608 gCoreContext->GetSetting("MythShutdownNvramRestartCmd", "");
00609
00610 if (dtWakeupTime.isValid())
00611 {
00612
00613 if (dtCurrent.secsTo(dtWakeupTime) > 15 * 60)
00614 {
00615 QString nvramCommand =
00616 gCoreContext->GetSetting("MythShutdownNvramCmd",
00617 "/usr/bin/nvram-wakeup --settime $time");
00618
00619 QString wakeup_timeformat = gCoreContext->GetSetting(
00620 "MythShutdownWakeupTimeFmt", "time_t");
00621
00622 if (wakeup_timeformat == "time_t")
00623 {
00624 QString time_ts;
00625 nvramCommand.replace(
00626 "$time", time_ts.setNum(dtWakeupTime.toTime_t()));
00627 }
00628 else
00629 nvramCommand.replace(
00630 "$time", dtWakeupTime.toString(wakeup_timeformat));
00631
00632 LOG(VB_GENERAL, LOG_NOTICE, "sending command to set time in bios" +
00633 nvramCommand);
00634
00635 shutdownmode = myth_system(nvramCommand);
00636
00637 LOG(VB_GENERAL, LOG_NOTICE, (nvramCommand + " exited with code %2")
00638 .arg(shutdownmode));
00639
00640 if (shutdownmode == 2)
00641 {
00642 LOG(VB_GENERAL, LOG_ERR,
00643 "nvram-wakeup failed to set time in bios");
00644 return 1;
00645 }
00646
00647
00648
00649 if (nvramRestartCmd.isEmpty())
00650 shutdownmode = 0;
00651 else
00652 shutdownmode = 1;
00653 }
00654 else
00655 {
00656 LOG(VB_GENERAL, LOG_NOTICE, "The next wakeup time is less than "
00657 "15 mins away, not shutting down");
00658 return 0;
00659 }
00660 }
00661
00662 int res = 0;
00663
00664 switch (shutdownmode)
00665 {
00666 case 0:
00667 {
00668 LOG(VB_GENERAL, LOG_NOTICE,
00669 "everything looks fine, shutting down ...");
00670 QString poweroffCmd = gCoreContext->GetSetting(
00671 "MythShutdownPoweroff", "/sbin/poweroff");
00672 LOG(VB_GENERAL, LOG_NOTICE, "..");
00673 LOG(VB_GENERAL, LOG_NOTICE, ".");
00674 LOG(VB_GENERAL, LOG_NOTICE, "shutting down ...");
00675
00676 myth_system(poweroffCmd);
00677 res = 0;
00678 break;
00679 }
00680 case 1:
00681 {
00682 LOG(VB_GENERAL, LOG_NOTICE,
00683 "everything looks fine, but reboot is needed");
00684 LOG(VB_GENERAL, LOG_NOTICE, "sending command to bootloader ...");
00685 LOG(VB_GENERAL, LOG_NOTICE, nvramRestartCmd);
00686
00687 myth_system(nvramRestartCmd);
00688
00689 LOG(VB_GENERAL, LOG_NOTICE, "..");
00690 LOG(VB_GENERAL, LOG_NOTICE, ".");
00691 LOG(VB_GENERAL, LOG_NOTICE, "rebooting ...");
00692
00693 QString rebootCmd =
00694 gCoreContext->GetSetting("MythShutdownReboot", "/sbin/reboot");
00695 myth_system(rebootCmd);
00696 res = 0;
00697 break;
00698 }
00699 default:
00700 LOG(VB_GENERAL, LOG_ERR,
00701 "panic. invalid shutdown mode, do nothing");
00702 res = 1;
00703 break;
00704 }
00705
00706 return res;
00707 }
00708
00709 static int startup()
00710 {
00711 LOG(VB_GENERAL, LOG_INFO, "Mythshutdown: --startup");
00712
00713 int res = 0;
00714 QDateTime startupTime = QDateTime();
00715 QString s = getGlobalSetting("MythshutdownWakeupTime", "");
00716 if (!s.isEmpty())
00717 startupTime = QDateTime::fromString(s, Qt::ISODate);
00718
00719
00720 if (!startupTime.isValid())
00721 res = 1;
00722 else
00723 {
00724
00725
00726
00727 int delta = startupTime.secsTo(QDateTime::currentDateTime());
00728 if (delta < 0)
00729 delta = -delta;
00730
00731 if (delta < 15 * 60)
00732 res = 0;
00733 else
00734 res = 1;
00735 }
00736
00737 if (res)
00738 LOG(VB_GENERAL, LOG_INFO,
00739 QString("looks like we were started manually: %1").arg(res));
00740 else
00741 LOG(VB_GENERAL, LOG_INFO,
00742 QString("looks like we were started automatically: %1").arg(res));
00743
00744
00745 LOG(VB_GENERAL, LOG_INFO,
00746 QString("Mythshutdown: --startup returned: %1").arg(res));
00747
00748 return res;
00749 }
00750
00751 int main(int argc, char **argv)
00752 {
00753 MythShutdownCommandLineParser cmdline;
00754 if (!cmdline.Parse(argc, argv))
00755 {
00756 cmdline.PrintHelp();
00757 return GENERIC_EXIT_INVALID_CMDLINE;
00758 }
00759
00760 if (cmdline.toBool("showhelp"))
00761 {
00762 cmdline.PrintHelp();
00763 return GENERIC_EXIT_OK;
00764 }
00765
00766 if (cmdline.toBool("showversion"))
00767 {
00768 cmdline.PrintVersion();
00769 return GENERIC_EXIT_OK;
00770 }
00771
00772 QCoreApplication a(argc, argv);
00773 QCoreApplication::setApplicationName(MYTH_APPNAME_MYTHSHUTDOWN);
00774
00775 int retval;
00776 QString mask("none");
00777 if ((retval = cmdline.ConfigureLogging(mask)) != GENERIC_EXIT_OK)
00778 return retval;
00779
00780 gContext = new MythContext(MYTH_BINARY_VERSION);
00781 if (!gContext->Init(false))
00782 {
00783 LOG(VB_GENERAL, LOG_ERR,
00784 "mythshutdown: Could not initialize MythContext. Exiting.");
00785 return GENERIC_EXIT_NO_MYTHCONTEXT;
00786 }
00787
00788 int res = 0;
00789
00790 if (cmdline.toBool("lock"))
00791 res = lockShutdown();
00792 else if (cmdline.toBool("unlock"))
00793 res = unlockShutdown();
00794 else if (cmdline.toBool("check"))
00795 res = checkOKShutdown((bool)(cmdline.toInt("check") == 1));
00796 else if (cmdline.toBool("setschedwakeup"))
00797 res = setScheduledWakeupTime();
00798 else if (cmdline.toBool("startup"))
00799 res = startup();
00800 else if (cmdline.toBool("shutdown"))
00801 res = shutdown();
00802 else if (cmdline.toBool("status"))
00803 res = getStatus((bool)(cmdline.toInt("status") == 1));
00804 else if (cmdline.toBool("setwakeup"))
00805 res = setWakeupTime(cmdline.toString("setwakeup"));
00806 else if (cmdline.toBool("safeshutdown"))
00807 {
00808 res = checkOKShutdown(true);
00809 if (res == 0)
00810 {
00811
00812 res = setScheduledWakeupTime();
00813 res = shutdown();
00814 }
00815
00816 }
00817 else
00818 cmdline.PrintHelp();
00819
00820 delete gContext;
00821
00822 return res;
00823 }
00824