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