|
MythTV
0.26-pre
|
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 // lock setting table 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 // does the setting already exist? 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 // add the lock setting 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 // update the lock setting 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 // unlock settings table 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 // lock setting table 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 // does the setting exist? 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 // add the lock setting 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 // update lock setting 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 // unlock table 00174 if (!query.exec("UNLOCK TABLES;")) 00175 MythDB::DBError("unlockShutdown -- unlock", query); 00176 00177 // tell the master BE to reset its idle time 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 // Check for time periods that cross midnight 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 // Check for one of the daily wakeup periods 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 // Are we about to start a daily wakeup period 00313 // allow for a 15 minute window 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 // mythbackend wants 0=ok to shutdown, 00351 // 1=reset idle count, 2=wait for frontend 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 // check time given is valid 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 // set the wakeup time for the next scheduled recording 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 // get next daily wakeup times if any are set 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 // Make sure Period1 is before Period2 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 // Check for time periods that cross midnight 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 // have we passed the first wakeup time today 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 // have we passed the second wakeup time today 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 // if we have at least one valid daily wakeup time 00501 // and dtNextDailyWakeup is still not valid 00502 // then next daily wakeup is tomorrow 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 // if dtNextDailyWakeup is still not valid then no daily wakeups are set 00520 if (!dtNextDailyWakeup.isValid()) 00521 LOG(VB_GENERAL, LOG_ERR, "no daily wakeup times are set"); 00522 00523 // get next scheduled wake up for a recording if any 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 // check if scheduled recording time has already passed 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 // simple case 00554 // no daily wakeup set 00555 // no scheduled program set 00556 // just shut down 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 // no daily wakeup set 00565 // scheduled program is set 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 // daily wakeup is set 00573 // no scheduled program is set 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 // daily wakeup is set 00581 // scheduled program is set 00582 // wake up at which ever is the earliest 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 // save the next wakuptime in the db 00600 setGlobalSetting("MythShutdownWakeupTime", 00601 dtWakeupTime.toString(Qt::ISODate)); 00602 00603 // stop here to debug 00604 //return 0; 00605 00606 int shutdownmode = 0; // default to poweroff no reboot 00607 QString nvramRestartCmd = 00608 gCoreContext->GetSetting("MythShutdownNvramRestartCmd", ""); 00609 00610 if (dtWakeupTime.isValid()) 00611 { 00612 // dont't shutdown if we are within 15 mins of the next wakeup time 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 // we don't trust the return code from nvram-wakeup so only reboot 00648 // if the user has set a restart command 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 // if we don't have a valid startup time assume we were started manually 00720 if (!startupTime.isValid()) 00721 res = 1; 00722 else 00723 { 00724 // if we started within 15mins of the saved wakeup time assume we started 00725 // automatically to record or for a daily wakeup/shutdown period 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 // Nothing to stop a shutdown (eg. recording in progress). 00812 res = setScheduledWakeupTime(); 00813 res = shutdown(); 00814 } 00815 00816 } 00817 else 00818 cmdline.PrintHelp(); 00819 00820 delete gContext; 00821 00822 return res; 00823 } 00824
1.7.6.1