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