int setup_basics(const MythBackendCommandLineParser &cmdline) { ofstream pidfs; if (!openPidfile(pidfs, cmdline.toString("pidfile"))) return GENERIC_EXIT_PERMISSIONS_ERROR; if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) VERBOSE(VB_IMPORTANT, LOC_WARN + "Unable to ignore SIGPIPE"); if (cmdline.toBool("daemon") && (daemon(0, 1) < 0)) { VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to daemonize" + ENO); return GENERIC_EXIT_DAEMONIZING_ERROR; } QString username = cmdline.toString("username"); if (!username.isEmpty() && !setUser(username)) return GENERIC_EXIT_PERMISSIONS_ERROR; if (pidfs) { pidfs << getpid() << endl; pidfs.close(); } return GENERIC_EXIT_OK; }
int main(int argc, char **argv) { MythBackendCommandLineParser cmdline; if (!cmdline.Parse(argc, argv)) { cmdline.PrintHelp(); return GENERIC_EXIT_INVALID_CMDLINE; } if (cmdline.toBool("showhelp")) { cmdline.PrintHelp(); return GENERIC_EXIT_OK; } if (cmdline.toBool("showversion")) { cmdline.PrintVersion(); return GENERIC_EXIT_OK; } #ifndef _WIN32 for (int i = UNUSED_FILENO; i < sysconf(_SC_OPEN_MAX) - 1; ++i) close(i); QCoreApplication a(argc, argv); #else // MINGW application needs a window to receive messages // such as socket notifications :[ QApplication a(argc, argv); #endif QCoreApplication::setApplicationName(MYTH_APPNAME_MYTHBACKEND); pidfile = cmdline.toString("pidfile"); int retval = cmdline.Daemonize(); if (retval != GENERIC_EXIT_OK) return retval; bool daemonize = cmdline.toBool("daemon"); QString mask("general"); if ((retval = cmdline.ConfigureLogging(mask, daemonize)) != GENERIC_EXIT_OK) return retval; if (daemonize) // Don't listen to console input if daemonized close(0); CleanupGuard callCleanup(cleanup); #ifndef _WIN32 QList<int> signallist; signallist << SIGINT << SIGTERM << SIGSEGV << SIGABRT; SignalHandler handler(signallist); signal(SIGHUP, SIG_IGN); #endif gContext = new MythContext(MYTH_BINARY_VERSION); if (!gContext->Init(false)) { LOG(VB_GENERAL, LOG_CRIT, "Failed to init MythContext."); return GENERIC_EXIT_NO_MYTHCONTEXT; } setHttpProxy(); cmdline.ApplySettingsOverride(); if (cmdline.toBool("event") || cmdline.toBool("systemevent") || cmdline.toBool("setverbose") || cmdline.toBool("printsched") || cmdline.toBool("testsched") || cmdline.toBool("resched") || cmdline.toBool("scanvideos") || cmdline.toBool("clearcache") || cmdline.toBool("printexpire") || cmdline.toBool("setloglevel")) { gCoreContext->SetBackend(false); return handle_command(cmdline); } gCoreContext->SetBackend(true); retval = run_backend(cmdline); return retval; }
int handle_command(const MythBackendCommandLineParser &cmdline) { QString eventString; if (cmdline.toBool("event")) eventString = cmdline.toString("event"); else if (cmdline.toBool("systemevent")) eventString = "SYSTEM_EVENT " + cmdline.toString("systemevent") + QString(" SENDER %1").arg(gCoreContext->GetHostName()); if (!eventString.isEmpty()) { if (gCoreContext->ConnectToMasterServer()) { gCoreContext->SendMessage(eventString); return GENERIC_EXIT_OK; } return GENERIC_EXIT_NO_MYTHCONTEXT; } if (cmdline.toBool("setverbose")) { if (gCoreContext->ConnectToMasterServer()) { QString message = "SET_VERBOSE "; message += cmdline.toString("setverbose"); gCoreContext->SendMessage(message); LOG(VB_GENERAL, LOG_INFO, QString("Sent '%1' message").arg(message)); return GENERIC_EXIT_OK; } else { LOG(VB_GENERAL, LOG_ERR, "Unable to connect to backend, verbose mask unchanged "); return GENERIC_EXIT_CONNECT_ERROR; } } if (cmdline.toBool("setloglevel")) { if (gCoreContext->ConnectToMasterServer()) { QString message = "SET_LOG_LEVEL "; message += cmdline.toString("setloglevel"); gCoreContext->SendMessage(message); LOG(VB_GENERAL, LOG_INFO, QString("Sent '%1' message").arg(message)); return GENERIC_EXIT_OK; } else { LOG(VB_GENERAL, LOG_ERR, "Unable to connect to backend, log level unchanged "); return GENERIC_EXIT_CONNECT_ERROR; } } if (cmdline.toBool("clearcache")) { if (gCoreContext->ConnectToMasterServer()) { gCoreContext->SendMessage("CLEAR_SETTINGS_CACHE"); LOG(VB_GENERAL, LOG_INFO, "Sent CLEAR_SETTINGS_CACHE message"); return GENERIC_EXIT_OK; } else { LOG(VB_GENERAL, LOG_ERR, "Unable to connect to backend, settings " "cache will not be cleared."); return GENERIC_EXIT_CONNECT_ERROR; } } if (cmdline.toBool("printsched") || cmdline.toBool("testsched")) { Scheduler *sched = new Scheduler(false, &tvList); if (cmdline.toBool("printsched")) { if (!gCoreContext->ConnectToMasterServer()) { LOG(VB_GENERAL, LOG_ERR, "Cannot connect to master"); delete sched; return GENERIC_EXIT_CONNECT_ERROR; } cout << "Retrieving Schedule from Master backend.\n"; sched->FillRecordListFromMaster(); } else { cout << "Calculating Schedule from database.\n" << "Inputs, Card IDs, and Conflict info may be invalid " "if you have multiple tuners.\n"; ProgramInfo::CheckProgramIDAuthorities(); sched->FillRecordListFromDB(); } verboseMask |= VB_SCHEDULE; LogLevel_t oldLogLevel = logLevel; logLevel = LOG_DEBUG; sched->PrintList(true); logLevel = oldLogLevel; delete sched; return GENERIC_EXIT_OK; } if (cmdline.toBool("resched")) { bool ok = false; if (gCoreContext->ConnectToMasterServer()) { LOG(VB_GENERAL, LOG_INFO, "Connected to master for reschedule"); ScheduledRecording::RescheduleMatch(0, 0, 0, QDateTime(), "MythBackendCommand"); ok = true; } else LOG(VB_GENERAL, LOG_ERR, "Cannot connect to master for reschedule"); return (ok) ? GENERIC_EXIT_OK : GENERIC_EXIT_CONNECT_ERROR; } if (cmdline.toBool("scanvideos")) { bool ok = false; if (gCoreContext->ConnectToMasterServer()) { gCoreContext->SendReceiveStringList(QStringList() << "SCAN_VIDEOS"); LOG(VB_GENERAL, LOG_INFO, "Requested video scan"); ok = true; } else LOG(VB_GENERAL, LOG_ERR, "Cannot connect to master for video scan"); return (ok) ? GENERIC_EXIT_OK : GENERIC_EXIT_CONNECT_ERROR; } if (cmdline.toBool("printexpire")) { expirer = new AutoExpire(); expirer->PrintExpireList(cmdline.toString("printexpire")); return GENERIC_EXIT_OK; } // This should never actually be reached.. return GENERIC_EXIT_OK; }
int handle_command(const MythBackendCommandLineParser &cmdline) { QString eventString; if (cmdline.toBool("event")) eventString = cmdline.toString("event"); else if (cmdline.toBool("systemevent")) eventString = "SYSTEM_EVENT " + cmdline.toString("systemevent") + QString(" SENDER %1").arg(gCoreContext->GetHostName()); if (!eventString.isEmpty()) { if (gCoreContext->ConnectToMasterServer()) { RemoteSendMessage(eventString); return GENERIC_EXIT_OK; } return GENERIC_EXIT_NO_MYTHCONTEXT; } if (cmdline.toBool("setverbose")) { if (gCoreContext->ConnectToMasterServer()) { QString message = "SET_VERBOSE "; message += cmdline.toString("setverbose"); RemoteSendMessage(message); VERBOSE(VB_IMPORTANT, QString("Sent '%1' message").arg(message)); return GENERIC_EXIT_OK; } else { VERBOSE(VB_IMPORTANT, "Unable to connect to backend, verbose level unchanged "); return GENERIC_EXIT_CONNECT_ERROR; } } if (cmdline.toBool("clearcache")) { if (gCoreContext->ConnectToMasterServer()) { RemoteSendMessage("CLEAR_SETTINGS_CACHE"); VERBOSE(VB_IMPORTANT, "Sent CLEAR_SETTINGS_CACHE message"); return GENERIC_EXIT_OK; } else { VERBOSE(VB_IMPORTANT, "Unable to connect to backend, settings " "cache will not be cleared."); return GENERIC_EXIT_CONNECT_ERROR; } } if (cmdline.toBool("printsched") || cmdline.toBool("testsched")) { sched = new Scheduler(false, &tvList); if (!cmdline.toBool("testsched") && gCoreContext->ConnectToMasterServer()) { cout << "Retrieving Schedule from Master backend.\n"; sched->FillRecordListFromMaster(); } else { cout << "Calculating Schedule from database.\n" << "Inputs, Card IDs, and Conflict info may be invalid " "if you have multiple tuners.\n"; sched->FillRecordListFromDB(); } print_verbose_messages |= VB_SCHEDULE; sched->PrintList(true); return GENERIC_EXIT_OK; } if (cmdline.toBool("resched")) { bool ok = false; if (gCoreContext->ConnectToMasterServer()) { VERBOSE(VB_IMPORTANT, "Connected to master for reschedule"); ScheduledRecording::signalChange(-1); ok = true; } else VERBOSE(VB_IMPORTANT, "Cannot connect to master for reschedule"); return (ok) ? GENERIC_EXIT_OK : GENERIC_EXIT_CONNECT_ERROR; } if (cmdline.toBool("scanvideos")) { bool ok = false; if (gCoreContext->ConnectToMasterServer()) { gCoreContext->SendReceiveStringList(QStringList() << "SCAN_VIDEOS"); VERBOSE(VB_IMPORTANT, "Requested video scan"); ok = true; } else VERBOSE(VB_IMPORTANT, "Cannot connect to master for video scan"); return (ok) ? GENERIC_EXIT_OK : GENERIC_EXIT_CONNECT_ERROR; } if (!cmdline.toBool("printexpire")) { expirer = new AutoExpire(); expirer->PrintExpireList(cmdline.toString("printexpire")); return GENERIC_EXIT_OK; } // This should never actually be reached.. return GENERIC_EXIT_OK; }