MythTV  master
main_helpers.cpp
Go to the documentation of this file.
1 #include "mythconfig.h"
2 #if CONFIG_DARWIN
3  #include <sys/aio.h> // O_SYNC
4 #endif
5 #if CONFIG_SYSTEMD_NOTIFY
6  #include <systemd/sd-daemon.h>
7  #define be_sd_notify(x) \
8  (void)sd_notify(0, x);
9 #else
10  #define be_sd_notify(x)
11 #endif
12 
13 // C++ headers
14 #include <cerrno>
15 #include <csignal>
16 #include <cstdlib>
17 #include <fcntl.h>
18 #include <sys/stat.h>
19 #include <sys/time.h> // for setpriority
20 #include <sys/types.h>
21 #include <unistd.h>
22 
23 #include <QCoreApplication>
24 #include <QFileInfo>
25 #include <QRegExp>
26 #include <QFile>
27 #include <QDir>
28 #include <QMap>
29 
30 #include "tv_rec.h"
31 #include "scheduledrecording.h"
32 #include "autoexpire.h"
33 #include "scheduler.h"
34 #include "mainserver.h"
35 #include "encoderlink.h"
36 #include "remoteutil.h"
37 #include "backendhousekeeper.h"
38 
39 #include "mythcontext.h"
40 #include "mythversion.h"
41 #include "mythdb.h"
42 #include "dbutil.h"
43 #include "exitcodes.h"
44 #include "compat.h"
45 #include "storagegroup.h"
46 #include "programinfo.h"
47 #include "dbcheck.h"
48 #include "jobqueue.h"
49 #include "previewgenerator.h"
50 #include "commandlineparser.h"
51 #include "mythsystemevent.h"
52 #include "main_helpers.h"
53 #include "backendcontext.h"
54 #include "mythtranslation.h"
55 #include "mythtimezone.h"
56 #include "signalhandling.h"
57 #include "hardwareprofile.h"
58 
59 #include "mediaserver.h"
60 #include "httpstatus.h"
61 #include "mythlogging.h"
62 
63 #define LOC QString("MythBackend: ")
64 #define LOC_WARN QString("MythBackend, Warning: ")
65 #define LOC_ERR QString("MythBackend, Error: ")
66 
67 static MainServer *mainServer = nullptr;
68 
69 bool setupTVs(bool ismaster, bool &error)
70 {
71  error = false;
72  QString localhostname = gCoreContext->GetHostName();
73 
75 
76  if (ismaster)
77  {
78  // Hack to make sure recorded.basename gets set if the user
79  // downgrades to a prior version and creates new entries
80  // without it.
81  if (!query.exec("UPDATE recorded SET basename = CONCAT(chanid, '_', "
82  "DATE_FORMAT(starttime, '%Y%m%d%H%i00'), '_', "
83  "DATE_FORMAT(endtime, '%Y%m%d%H%i00'), '.nuv') "
84  "WHERE basename = '';"))
85  MythDB::DBError("Updating record basename", query);
86 
87  // Hack to make sure record.station gets set if the user
88  // downgrades to a prior version and creates new entries
89  // without it.
90  if (!query.exec("UPDATE channel SET callsign=chanid "
91  "WHERE callsign IS NULL OR callsign='';"))
92  MythDB::DBError("Updating channel callsign", query);
93 
94  if (query.exec("SELECT MIN(chanid) FROM channel;"))
95  {
96  query.first();
97  int min_chanid = query.value(0).toInt();
98  if (!query.exec(QString("UPDATE record SET chanid = %1 "
99  "WHERE chanid IS NULL;").arg(min_chanid)))
100  MythDB::DBError("Updating record chanid", query);
101  }
102  else
103  MythDB::DBError("Querying minimum chanid", query);
104 
105  MSqlQuery records_without_station(MSqlQuery::InitCon());
106  records_without_station.prepare("SELECT record.chanid,"
107  " channel.callsign FROM record LEFT JOIN channel"
108  " ON record.chanid = channel.chanid WHERE record.station='';");
109  if (records_without_station.exec() && records_without_station.next())
110  {
111  MSqlQuery update_record(MSqlQuery::InitCon());
112  update_record.prepare("UPDATE record SET station = :CALLSIGN"
113  " WHERE chanid = :CHANID;");
114  do
115  {
116  update_record.bindValue(":CALLSIGN",
117  records_without_station.value(1));
118  update_record.bindValue(":CHANID",
119  records_without_station.value(0));
120  if (!update_record.exec())
121  {
122  MythDB::DBError("Updating record station", update_record);
123  }
124  } while (records_without_station.next());
125  }
126  }
127 
128  if (!query.exec(
129  "SELECT cardid, hostname "
130  "FROM capturecard "
131  "ORDER BY cardid"))
132  {
133  MythDB::DBError("Querying Recorders", query);
134  return false;
135  }
136 
137  vector<uint> cardids;
138  vector<QString> hosts;
139  while (query.next())
140  {
141  uint cardid = query.value(0).toUInt();
142  QString host = query.value(1).toString();
143  QString cidmsg = QString("Card %1").arg(cardid);
144 
145  if (host.isEmpty())
146  {
147  LOG(VB_GENERAL, LOG_ERR, cidmsg +
148  " does not have a hostname defined.\n"
149  "Please run setup and confirm all of the capture cards.\n");
150  continue;
151  }
152 
153  cardids.push_back(cardid);
154  hosts.push_back(host);
155  }
156 
157  QWriteLocker tvlocker(&TVRec::inputsLock);
158 
159  for (uint i = 0; i < cardids.size(); i++)
160  {
161  if (hosts[i] == localhostname)
162  new TVRec(cardids[i]);
163  }
164 
165  for (uint i = 0; i < cardids.size(); i++)
166  {
167  uint cardid = cardids[i];
168  QString host = hosts[i];
169  QString cidmsg = QString("Card %1").arg(cardid);
170 
171  if (!ismaster)
172  {
173  if (host == localhostname)
174  {
175  TVRec *tv = TVRec::GetTVRec(cardid);
176  if (tv && tv->Init())
177  {
178  EncoderLink *enc = new EncoderLink(cardid, tv);
179  tvList[cardid] = enc;
180  }
181  else
182  {
183  LOG(VB_GENERAL, LOG_ERR, "Problem with capture cards. " +
184  cidmsg + " failed init");
185  delete tv;
186  // The master assumes card comes up so we need to
187  // set error and exit if a non-master card fails.
188  error = true;
189  }
190  }
191  }
192  else
193  {
194  if (host == localhostname)
195  {
196  TVRec *tv = TVRec::GetTVRec(cardid);
197  if (tv && tv->Init())
198  {
199  EncoderLink *enc = new EncoderLink(cardid, tv);
200  tvList[cardid] = enc;
201  }
202  else
203  {
204  LOG(VB_GENERAL, LOG_ERR, "Problem with capture cards. " +
205  cidmsg + " failed init");
206  delete tv;
207  }
208  }
209  else
210  {
211  EncoderLink *enc = new EncoderLink(cardid, nullptr, host);
212  tvList[cardid] = enc;
213  }
214  }
215  }
216 
217  if (tvList.empty())
218  {
219  LOG(VB_GENERAL, LOG_WARNING, LOC +
220  "No valid capture cards are defined in the database.");
221  }
222 
223  return true;
224 }
225 
226 void cleanup(void)
227 {
228  if (mainServer)
229  {
230  mainServer->Stop();
231  qApp->processEvents();
232  }
233 
234  if (gCoreContext)
236 
237  delete housekeeping;
238  housekeeping = nullptr;
239 
240  if (gCoreContext)
241  {
242  delete gCoreContext->GetScheduler();
243  gCoreContext->SetScheduler(nullptr);
244  }
245 
246  delete expirer;
247  expirer = nullptr;
248 
249  delete jobqueue;
250  jobqueue = nullptr;
251 
252  delete g_pUPnp;
253  g_pUPnp = nullptr;
254 
255  if (SSDP::Instance())
256  {
258  SSDP::Instance()->wait();
259  }
260 
261  if (TaskQueue::Instance())
262  {
265  }
266 
267  while (!TVRec::inputs.empty())
268  {
269  TVRec *rec = *TVRec::inputs.begin();
270  delete rec;
271  }
272 
273 
274  delete gContext;
275  gContext = nullptr;
276 
277  delete mainServer;
278  mainServer = nullptr;
279 
280  delete gBackendContext;
281  gBackendContext = nullptr;
282 
283  if (pidfile.size())
284  {
285  unlink(pidfile.toLatin1().constData());
286  pidfile.clear();
287  }
288 
290 }
291 
293 {
294  QString eventString;
295 
296  if (cmdline.toBool("event"))
297  eventString = cmdline.toString("event");
298  else if (cmdline.toBool("systemevent"))
299  eventString = "SYSTEM_EVENT " +
300  cmdline.toString("systemevent") +
301  QString(" SENDER %1").arg(gCoreContext->GetHostName());
302 
303  if (!eventString.isEmpty())
304  {
306  {
307  gCoreContext->SendMessage(eventString);
308  return GENERIC_EXIT_OK;
309  }
311  }
312 
313  if (cmdline.toBool("setverbose"))
314  {
316  {
317  QString message = "SET_VERBOSE ";
318  message += cmdline.toString("setverbose");
319 
320  gCoreContext->SendMessage(message);
321  LOG(VB_GENERAL, LOG_INFO,
322  QString("Sent '%1' message").arg(message));
323  return GENERIC_EXIT_OK;
324  }
325  else
326  {
327  LOG(VB_GENERAL, LOG_ERR,
328  "Unable to connect to backend, verbose mask unchanged ");
330  }
331  }
332 
333  if (cmdline.toBool("setloglevel"))
334  {
336  {
337  QString message = "SET_LOG_LEVEL ";
338  message += cmdline.toString("setloglevel");
339 
340  gCoreContext->SendMessage(message);
341  LOG(VB_GENERAL, LOG_INFO,
342  QString("Sent '%1' message").arg(message));
343  return GENERIC_EXIT_OK;
344  }
345  else
346  {
347  LOG(VB_GENERAL, LOG_ERR,
348  "Unable to connect to backend, log level unchanged ");
350  }
351  }
352 
353  if (cmdline.toBool("clearcache"))
354  {
356  {
357  gCoreContext->SendMessage("CLEAR_SETTINGS_CACHE");
358  LOG(VB_GENERAL, LOG_INFO, "Sent CLEAR_SETTINGS_CACHE message");
359  return GENERIC_EXIT_OK;
360  }
361  else
362  {
363  LOG(VB_GENERAL, LOG_ERR, "Unable to connect to backend, settings "
364  "cache will not be cleared.");
366  }
367  }
368 
369  if (cmdline.toBool("printsched") ||
370  cmdline.toBool("testsched"))
371  {
372  Scheduler *sched = new Scheduler(false, &tvList);
373  if (cmdline.toBool("printsched"))
374  {
376  {
377  LOG(VB_GENERAL, LOG_ERR, "Cannot connect to master");
378  delete sched;
380  }
381  cout << "Retrieving Schedule from Master backend.\n";
383  }
384  else
385  {
386  cout << "Calculating Schedule from database.\n" <<
387  "Inputs, Card IDs, and Conflict info may be invalid "
388  "if you have multiple tuners.\n";
391  }
392 
393  verboseMask |= VB_SCHEDULE;
394  LogLevel_t oldLogLevel = logLevel;
395  logLevel = LOG_DEBUG;
396  sched->PrintList(true);
397  logLevel = oldLogLevel;
398  delete sched;
399  return GENERIC_EXIT_OK;
400  }
401 
402  if (cmdline.toBool("resched"))
403  {
404  bool ok = false;
406  {
407  LOG(VB_GENERAL, LOG_INFO, "Connected to master for reschedule");
408  ScheduledRecording::RescheduleMatch(0, 0, 0, QDateTime(),
409  "MythBackendCommand");
410  ok = true;
411  }
412  else
413  LOG(VB_GENERAL, LOG_ERR, "Cannot connect to master for reschedule");
414 
416  }
417 
418  if (cmdline.toBool("scanvideos"))
419  {
420  bool ok = false;
422  {
423  gCoreContext->SendReceiveStringList(QStringList() << "SCAN_VIDEOS");
424  LOG(VB_GENERAL, LOG_INFO, "Requested video scan");
425  ok = true;
426  }
427  else
428  LOG(VB_GENERAL, LOG_ERR, "Cannot connect to master for video scan");
429 
431  }
432 
433  if (cmdline.toBool("printexpire"))
434  {
435  expirer = new AutoExpire();
436  expirer->PrintExpireList(cmdline.toString("printexpire"));
437  return GENERIC_EXIT_OK;
438  }
439 
440  // This should never actually be reached..
441  return GENERIC_EXIT_OK;
442 }
443 using namespace MythTZ;
444 
446 {
447  MythSocket *tempMonitorConnection = new MythSocket();
448  if (tempMonitorConnection->ConnectToHost(
451  {
452  if (!gCoreContext->CheckProtoVersion(tempMonitorConnection))
453  {
454  LOG(VB_GENERAL, LOG_ERR, "Master backend is incompatible with "
455  "this backend.\nCannot become a slave.");
456  tempMonitorConnection->DecrRef();
458  }
459 
460  QStringList tempMonitorDone("DONE");
461 
462  QStringList tempMonitorAnnounce(QString("ANN Monitor %1 0")
463  .arg(gCoreContext->GetHostName()));
464  tempMonitorConnection->SendReceiveStringList(tempMonitorAnnounce);
465  if (tempMonitorAnnounce.empty() ||
466  tempMonitorAnnounce[0] == "ERROR")
467  {
468  tempMonitorConnection->DecrRef();
469  tempMonitorConnection = nullptr;
470  if (tempMonitorAnnounce.empty())
471  {
472  LOG(VB_GENERAL, LOG_ERR, LOC +
473  "Failed to open event socket, timeout");
474  }
475  else
476  {
477  LOG(VB_GENERAL, LOG_ERR, LOC +
478  "Failed to open event socket" +
479  ((tempMonitorAnnounce.size() >= 2) ?
480  QString(", error was %1").arg(tempMonitorAnnounce[1]) :
481  QString(", remote error")));
482  }
483  }
484 
485  QStringList timeCheck;
486  if (tempMonitorConnection)
487  {
488  timeCheck.push_back("QUERY_TIME_ZONE");
489  tempMonitorConnection->SendReceiveStringList(timeCheck);
490  tempMonitorConnection->WriteStringList(tempMonitorDone);
491  }
492  if (timeCheck.size() < 3)
493  {
494  if (tempMonitorConnection)
495  tempMonitorConnection->DecrRef();
497  }
498 
499  QDateTime our_time = MythDate::current();
500  QDateTime master_time = MythDate::fromString(timeCheck[2]);
501  int timediff = abs(our_time.secsTo(master_time));
502 
503  if (timediff > 300)
504  {
505  LOG(VB_GENERAL, LOG_ERR,
506  QString("Current time on the master backend differs by "
507  "%1 seconds from time on this system. Exiting.")
508  .arg(timediff));
509  if (tempMonitorConnection)
510  tempMonitorConnection->DecrRef();
512  }
513 
514  if (timediff > 20)
515  {
516  LOG(VB_GENERAL, LOG_WARNING,
517  QString("Time difference between the master "
518  "backend and this system is %1 seconds.")
519  .arg(timediff));
520  }
521  }
522  if (tempMonitorConnection)
523  tempMonitorConnection->DecrRef();
524 
525  return GENERIC_EXIT_OK;
526 }
527 
528 
530 {
531  if (cmdline.toBool("nohousekeeper"))
532  {
533  LOG(VB_GENERAL, LOG_WARNING, LOC +
534  "****** The Housekeeper has been DISABLED with "
535  "the --nohousekeeper option ******");
536  }
537  if (cmdline.toBool("nosched"))
538  {
539  LOG(VB_GENERAL, LOG_WARNING, LOC +
540  "********** The Scheduler has been DISABLED with "
541  "the --nosched option **********");
542  }
543  if (cmdline.toBool("noautoexpire"))
544  {
545  LOG(VB_GENERAL, LOG_WARNING, LOC +
546  "********* Auto-Expire has been DISABLED with "
547  "the --noautoexpire option ********");
548  }
549  if (cmdline.toBool("nojobqueue"))
550  {
551  LOG(VB_GENERAL, LOG_WARNING, LOC +
552  "********* The JobQueue has been DISABLED with "
553  "the --nojobqueue option *********");
554  }
555 }
556 
558 {
560 
562  {
563  LOG(VB_GENERAL, LOG_ERR,
564  "MySQL time zone support is missing. "
565  "Please install it and try again. "
566  "See 'mysql_tzinfo_to_sql' for assistance.");
568  }
569 
570  bool ismaster = gCoreContext->IsMasterHost();
571 
572  if (!UpgradeTVDatabaseSchema(ismaster, ismaster, true))
573  {
574  LOG(VB_GENERAL, LOG_ERR,
575  QString("Couldn't upgrade database to new schema on %1 backend.")
576  .arg(ismaster ? "master" : "slave"));
578  }
579 
580  be_sd_notify("STATUS=Loading translation");
581  MythTranslation::load("mythfrontend");
582 
583  if (!ismaster)
584  {
585  be_sd_notify("STATUS=Connecting to master backend");
586  int ret = connect_to_master();
587  if (ret != GENERIC_EXIT_OK)
588  return ret;
589  }
590 
591  be_sd_notify("STATUS=Get backend server port");
592  int port = gCoreContext->GetBackendServerPort();
593  if (gCoreContext->GetBackendServerIP().isEmpty())
594  {
595  cerr << "No setting found for this machine's BackendServerIP.\n"
596  << "Please run setup on this machine and modify the first page\n"
597  << "of the general settings.\n";
599  }
600 
601  MythSystemEventHandler *sysEventHandler = new MythSystemEventHandler();
602 
603  if (ismaster)
604  {
605  LOG(VB_GENERAL, LOG_NOTICE, LOC + "Starting up as the master server.");
606  }
607  else
608  {
609  LOG(VB_GENERAL, LOG_NOTICE, LOC + "Running as a slave backend.");
610  }
611 
613 
614  bool fatal_error = false;
615  bool runsched = setupTVs(ismaster, fatal_error);
616  if (fatal_error)
617  {
618  delete sysEventHandler;
620  }
621 
622  Scheduler *sched = nullptr;
623  if (ismaster)
624  {
625  if (runsched)
626  {
627  be_sd_notify("STATUS=Creating scheduler");
628  sched = new Scheduler(true, &tvList);
629  int err = sched->GetError();
630  if (err)
631  return err;
632 
633  if (cmdline.toBool("nosched"))
635  }
636 
637  if (!cmdline.toBool("noautoexpire"))
638  {
639  expirer = new AutoExpire(&tvList);
640  if (sched)
642  }
644  }
645 
646  if (!cmdline.toBool("nohousekeeper"))
647  {
648  be_sd_notify("STATUS=Creating housekeeper");
649  housekeeping = new HouseKeeper();
650 
651  if (ismaster)
652  {
658 
659  // only run this task if MythMusic is installed and we have a new enough schema
660  if (gCoreContext->GetNumSetting("MusicDBSchemaVer", 0) >= 1024)
662  }
663 
665 #ifdef __linux__
666  #ifdef CONFIG_BINDINGS_PYTHON
668  #endif
669 #endif
670 
671  housekeeping->Start();
672  }
673 
674  if (!cmdline.toBool("nojobqueue"))
675  jobqueue = new JobQueue(ismaster);
676 
677  // ----------------------------------------------------------------------
678  //
679  // ----------------------------------------------------------------------
680 
681  if (g_pUPnp == nullptr)
682  {
683  be_sd_notify("STATUS=Creating UPnP media server");
684  g_pUPnp = new MediaServer();
685 
686  g_pUPnp->Init(ismaster, cmdline.toBool("noupnp"));
687  }
688 
689  // ----------------------------------------------------------------------
690  // Setup status server
691  // ----------------------------------------------------------------------
692 
693  HttpStatus *httpStatus = nullptr;
694  HttpServer *pHS = g_pUPnp->GetHttpServer();
695 
696  if (pHS)
697  {
698  LOG(VB_GENERAL, LOG_INFO, "Main::Registering HttpStatus Extension");
699  be_sd_notify("STATUS=Registering HttpStatus Extension");
700 
701  httpStatus = new HttpStatus( &tvList, sched, expirer, ismaster );
702  pHS->RegisterExtension( httpStatus );
703  }
704 
705  be_sd_notify("STATUS=Creating main server");
706  mainServer = new MainServer(
707  ismaster, port, &tvList, sched, expirer);
708 
709  int exitCode = mainServer->GetExitCode();
710  if (exitCode != GENERIC_EXIT_OK)
711  {
712  LOG(VB_GENERAL, LOG_CRIT,
713  "Backend exiting, MainServer initialization error.");
714  cleanup();
715  return exitCode;
716  }
717 
718  if (httpStatus && mainServer)
719  httpStatus->SetMainServer(mainServer);
720 
721  be_sd_notify("STATUS=Check all storage groups");
723 
724  be_sd_notify("STATUS=Sending \"master started\" message");
726  gCoreContext->SendSystemEvent("MASTER_STARTED");
727 
728  // Provide systemd ready notification (for type=notify units)
729  be_sd_notify("READY=1");
730 
733  exitCode = qApp->exec();
736 
738  {
739  gCoreContext->SendSystemEvent("MASTER_SHUTDOWN");
740  qApp->processEvents();
741  }
742 
743  LOG(VB_GENERAL, LOG_NOTICE, "MythBackend exiting");
744  be_sd_notify("STOPPING=1\nSTATUS=Exiting");
745 
746  delete sysEventHandler;
747 
748  return exitCode;
749 }
static void CheckProgramIDAuthorities(void)
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:794
MythScheduler * GetScheduler(void)
void FillRecordListFromMaster(void)
Definition: scheduler.cpp:576
void bindValue(const QString &placeholder, const QVariant &val)
Definition: mythdbcon.cpp:875
bool UpgradeTVDatabaseSchema(const bool upgradeAllowed, const bool upgradeIfNoUI, const bool informSystemd)
Called from outside dbcheck.cpp to update the schema.
static TaskQueue * Instance()
Definition: taskqueue.cpp:58
#define GENERIC_EXIT_OK
Exited with no error.
Definition: exitcodes.h:10
#define GENERIC_EXIT_CONNECT_ERROR
Can't connect to master backend.
Definition: exitcodes.h:20
void RegisterTask(HouseKeeperTask *task)
QString pidfile
static void error(const char *str,...)
Definition: vbi.c:41
QString GetBackendServerIP(void)
Returns the IP address of the locally defined backend IP.
#define LOC
int GetMasterServerPort(void)
Returns the Master Backend control port If no master server port has been defined in the database,...
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:125
A simple wrapper containing details about a UPnP Media Server.
Definition: mediaserver.h:31
bool wait(unsigned long time=ULONG_MAX)
Wait for the MThread to exit, with a maximum timeout.
Definition: mthread.cpp:312
MediaServer * g_pUPnp
HouseKeeper * housekeeping
bool ConnectToMasterServer(bool blockingClient=true, bool openEventSocket=true)
void RegisterExtension(HttpServerExtension *)
Definition: httpserver.cpp:325
static QMap< uint, TVRec * > inputs
Definition: tv_rec.h:433
void SetScheduler(MythScheduler *sched)
unsigned int uint
Definition: compat.h:140
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
uint64_t verboseMask
Definition: logging.cpp:107
void DisableScheduling(void)
Definition: scheduler.h:113
bool toBool(QString key) const
Returns stored QVariant as a boolean.
static QReadWriteLock inputsLock
Definition: tv_rec.h:432
MythContext * gContext
This global variable contains the MythContext instance for the application.
Definition: mythcontext.cpp:63
bool Init(void)
Performs instance initialization, returns true on success.
Definition: tv_rec.cpp:175
void SendMessage(const QString &message)
int GetBackendServerPort(void)
Returns the locally defined backend control port.
QString GetMasterServerIP(void)
Returns the Master Backend IP address If the address is an IPv6 address, the scope Id is removed.
int connect_to_master(void)
QVariant value(int i) const
Definition: mythdbcon.h:182
void Stop(void)
Definition: mainserver.cpp:368
bool SendReceiveStringList(QStringList &strlist, bool quickTimeout=false, bool block=true)
Send a message to the backend and wait for a response.
int run_backend(MythBackendCommandLineParser &cmdline)
#define GENERIC_EXIT_DB_NOTIMEZONE
Missing DB time zone support.
Definition: exitcodes.h:36
static void CheckAllStorageGroupDirs(void)
This is the coordinating class of the Recorder Subsystem.
Definition: tv_rec.h:150
void SetMainServer(MainServer *mainServer)
Definition: httpstatus.h:88
void SetExiting(bool exiting=true)
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:10
void PrintList(bool onlyFutureRecordings=false)
Definition: scheduler.h:103
#define GENERIC_EXIT_SOCKET_ERROR
Socket error.
Definition: exitcodes.h:18
virtual int DecrRef(void)
Decrements reference count and deletes on 0.
void RequestTerminate(void)
Definition: ssdp.cpp:149
Manages registered HouseKeeperTasks and queues tasks for operation.
Definition: housekeeper.h:148
static void load(const QString &module_name)
Load a QTranslator for the user's preferred language.
void cleanup(void)
void FillRecordListFromDB(uint recordid=0)
Definition: scheduler.cpp:486
void Init(bool bMaster, bool bDisableUPnp=false)
Definition: mediaserver.cpp:74
BackendContext * gBackendContext
static void Done(void)
#define GENERIC_EXIT_INVALID_TIME
Invalid time.
Definition: exitcodes.h:22
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.
Definition: mythdbcon.cpp:547
MythCommFlagCommandLineParser cmdline
static void RescheduleMatch(uint recordid, uint sourceid, uint mplexid, const QDateTime &maxstarttime, const QString &why)
bool IsMasterHost(void)
is this the same host as the master
void SetExpirer(AutoExpire *autoExpirer)
Definition: scheduler.h:62
int GetExitCode() const
Definition: mainserver.h:149
void RequestTerminate()
Definition: taskqueue.cpp:101
bool first(void)
Wrap QSqlQuery::first() so we can display the query results.
Definition: mythdbcon.cpp:804
int GetNumSetting(const QString &key, int defaultval=0)
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:819
HttpServer * GetHttpServer()
Definition: upnp.h:129
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
static SSDP * Instance()
Definition: ssdp.cpp:54
LogLevel_t logLevel
Definition: logging.cpp:95
bool ConnectToHost(const QString &hostname, quint16 port)
connect to host
Definition: mythsocket.cpp:393
Used to expire recordings to make space for new recordings.
Definition: autoexpire.h:61
AutoExpire * expirer
bool CheckProtoVersion(MythSocket *socket, uint timeout_ms=kMythSocketLongTimeout, bool error_dialog_desired=false)
void PrintExpireList(QString expHost="ALL")
Prints a summary of the files that can be deleted.
Definition: autoexpire.cpp:809
#define GENERIC_EXIT_SETUP_ERROR
Incorrectly setup system.
Definition: exitcodes.h:21
static TVRec * GetTVRec(uint inputid)
Definition: tv_rec.cpp:4851
Class for communcating between myth backends and frontends.
Definition: mythsocket.h:26
static MainServer * mainServer
Scheduler * sched
bool SendReceiveStringList(QStringList &list, uint min_reply_length=0, uint timeoutMS=kLongTimeout)
Definition: mythsocket.cpp:345
Handles incoming MythSystemEvent messages.
void print_warnings(const MythBackendCommandLineParser &cmdline)
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:615
bool WriteStringList(const QStringList &list)
Definition: mythsocket.cpp:320
#define GENERIC_EXIT_NO_MYTHCONTEXT
No MythContext available.
Definition: exitcodes.h:13
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:179
bool IsMasterBackend(void)
is this the actual MBE process
#define be_sd_notify(x)
JobQueue * jobqueue
QString GetHostName(void)
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.
Definition: mythdate.cpp:30
void SendSystemEvent(const QString &msg)
QMap< int, EncoderLink * > tvList
int handle_command(const MythBackendCommandLineParser &cmdline)
bool setupTVs(bool ismaster, bool &error)
static bool CheckTimeZoneSupport(void)
Check if MySQL has working timz zone support.
Definition: dbutil.cpp:879
#define GENERIC_EXIT_DB_OUTOFDATE
Database needs upgrade.
Definition: exitcodes.h:16
void Start(void)
int GetError(void) const
Definition: scheduler.h:122