MythTV  0.28pre
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Groups Pages
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 (gCoreContext)
223  {
225  }
226 
227  if (mainServer)
228  mainServer->Stop();
229 
230  delete housekeeping;
231  housekeeping = NULL;
232 
233  if (gCoreContext)
234  {
235  delete gCoreContext->GetScheduler();
236  gCoreContext->SetScheduler(NULL);
237  }
238 
239  delete expirer;
240  expirer = NULL;
241 
242  delete jobqueue;
243  jobqueue = NULL;
244 
245  delete g_pUPnp;
246  g_pUPnp = NULL;
247 
248  if (SSDP::Instance())
249  {
251  SSDP::Instance()->wait();
252  }
253 
254  if (TaskQueue::Instance())
255  {
258  }
259 
260  while (!TVRec::cards.empty())
261  {
262  TVRec *rec = *TVRec::cards.begin();
263  delete rec;
264  }
265 
266  delete gContext;
267  gContext = NULL;
268 
269  delete mainServer;
270  mainServer = NULL;
271 
272  if (pidfile.size())
273  {
274  unlink(pidfile.toLatin1().constData());
275  pidfile.clear();
276  }
277 
279 }
280 
282 {
283  QString eventString;
284 
285  if (cmdline.toBool("event"))
286  eventString = cmdline.toString("event");
287  else if (cmdline.toBool("systemevent"))
288  eventString = "SYSTEM_EVENT " +
289  cmdline.toString("systemevent") +
290  QString(" SENDER %1").arg(gCoreContext->GetHostName());
291 
292  if (!eventString.isEmpty())
293  {
295  {
296  gCoreContext->SendMessage(eventString);
297  return GENERIC_EXIT_OK;
298  }
299  return GENERIC_EXIT_NO_MYTHCONTEXT;
300  }
301 
302  if (cmdline.toBool("setverbose"))
303  {
305  {
306  QString message = "SET_VERBOSE ";
307  message += cmdline.toString("setverbose");
308 
309  gCoreContext->SendMessage(message);
310  LOG(VB_GENERAL, LOG_INFO,
311  QString("Sent '%1' message").arg(message));
312  return GENERIC_EXIT_OK;
313  }
314  else
315  {
316  LOG(VB_GENERAL, LOG_ERR,
317  "Unable to connect to backend, verbose mask unchanged ");
318  return GENERIC_EXIT_CONNECT_ERROR;
319  }
320  }
321 
322  if (cmdline.toBool("setloglevel"))
323  {
325  {
326  QString message = "SET_LOG_LEVEL ";
327  message += cmdline.toString("setloglevel");
328 
329  gCoreContext->SendMessage(message);
330  LOG(VB_GENERAL, LOG_INFO,
331  QString("Sent '%1' message").arg(message));
332  return GENERIC_EXIT_OK;
333  }
334  else
335  {
336  LOG(VB_GENERAL, LOG_ERR,
337  "Unable to connect to backend, log level unchanged ");
338  return GENERIC_EXIT_CONNECT_ERROR;
339  }
340  }
341 
342  if (cmdline.toBool("clearcache"))
343  {
345  {
346  gCoreContext->SendMessage("CLEAR_SETTINGS_CACHE");
347  LOG(VB_GENERAL, LOG_INFO, "Sent CLEAR_SETTINGS_CACHE message");
348  return GENERIC_EXIT_OK;
349  }
350  else
351  {
352  LOG(VB_GENERAL, LOG_ERR, "Unable to connect to backend, settings "
353  "cache will not be cleared.");
354  return GENERIC_EXIT_CONNECT_ERROR;
355  }
356  }
357 
358  if (cmdline.toBool("printsched") ||
359  cmdline.toBool("testsched"))
360  {
361  Scheduler *sched = new Scheduler(false, &tvList);
362  if (cmdline.toBool("printsched"))
363  {
365  {
366  LOG(VB_GENERAL, LOG_ERR, "Cannot connect to master");
367  delete sched;
368  return GENERIC_EXIT_CONNECT_ERROR;
369  }
370  cout << "Retrieving Schedule from Master backend.\n";
371  sched->FillRecordListFromMaster();
372  }
373  else
374  {
375  cout << "Calculating Schedule from database.\n" <<
376  "Inputs, Card IDs, and Conflict info may be invalid "
377  "if you have multiple tuners.\n";
379  sched->FillRecordListFromDB();
380  }
381 
382  verboseMask |= VB_SCHEDULE;
383  LogLevel_t oldLogLevel = logLevel;
384  logLevel = LOG_DEBUG;
385  sched->PrintList(true);
386  logLevel = oldLogLevel;
387  delete sched;
388  return GENERIC_EXIT_OK;
389  }
390 
391  if (cmdline.toBool("resched"))
392  {
393  bool ok = false;
395  {
396  LOG(VB_GENERAL, LOG_INFO, "Connected to master for reschedule");
397  ScheduledRecording::RescheduleMatch(0, 0, 0, QDateTime(),
398  "MythBackendCommand");
399  ok = true;
400  }
401  else
402  LOG(VB_GENERAL, LOG_ERR, "Cannot connect to master for reschedule");
403 
404  return (ok) ? GENERIC_EXIT_OK : GENERIC_EXIT_CONNECT_ERROR;
405  }
406 
407  if (cmdline.toBool("scanvideos"))
408  {
409  bool ok = false;
411  {
412  gCoreContext->SendReceiveStringList(QStringList() << "SCAN_VIDEOS");
413  LOG(VB_GENERAL, LOG_INFO, "Requested video scan");
414  ok = true;
415  }
416  else
417  LOG(VB_GENERAL, LOG_ERR, "Cannot connect to master for video scan");
418 
419  return (ok) ? GENERIC_EXIT_OK : GENERIC_EXIT_CONNECT_ERROR;
420  }
421 
422  if (cmdline.toBool("printexpire"))
423  {
424  expirer = new AutoExpire();
425  expirer->PrintExpireList(cmdline.toString("printexpire"));
426  return GENERIC_EXIT_OK;
427  }
428 
429  // This should never actually be reached..
430  return GENERIC_EXIT_OK;
431 }
432 using namespace MythTZ;
433 
435 {
436  MythSocket *tempMonitorConnection = new MythSocket();
437  if (tempMonitorConnection->ConnectToHost(
438  gCoreContext->GetSetting("MasterServerIP", "127.0.0.1"),
439  gCoreContext->GetNumSetting("MasterServerPort", 6543)))
440  {
441  if (!gCoreContext->CheckProtoVersion(tempMonitorConnection))
442  {
443  LOG(VB_GENERAL, LOG_ERR, "Master backend is incompatible with "
444  "this backend.\nCannot become a slave.");
445  tempMonitorConnection->DecrRef();
446  return GENERIC_EXIT_CONNECT_ERROR;
447  }
448 
449  QStringList tempMonitorDone("DONE");
450 
451  QStringList tempMonitorAnnounce("ANN Monitor tzcheck 0");
452  tempMonitorConnection->SendReceiveStringList(tempMonitorAnnounce);
453  if (tempMonitorAnnounce.empty() ||
454  tempMonitorAnnounce[0] == "ERROR")
455  {
456  tempMonitorConnection->DecrRef();
457  tempMonitorConnection = NULL;
458  if (tempMonitorAnnounce.empty())
459  {
460  LOG(VB_GENERAL, LOG_ERR, LOC +
461  "Failed to open event socket, timeout");
462  }
463  else
464  {
465  LOG(VB_GENERAL, LOG_ERR, LOC +
466  "Failed to open event socket" +
467  ((tempMonitorAnnounce.size() >= 2) ?
468  QString(", error was %1").arg(tempMonitorAnnounce[1]) :
469  QString(", remote error")));
470  }
471  }
472 
473  QStringList timeCheck;
474  if (tempMonitorConnection)
475  {
476  timeCheck.push_back("QUERY_TIME_ZONE");
477  tempMonitorConnection->SendReceiveStringList(timeCheck);
478  tempMonitorConnection->WriteStringList(tempMonitorDone);
479  }
480  if (timeCheck.size() < 3)
481  {
482  if (tempMonitorConnection)
483  tempMonitorConnection->DecrRef();
484  return GENERIC_EXIT_SOCKET_ERROR;
485  }
486 
487  QDateTime our_time = MythDate::current();
488  QDateTime master_time = MythDate::fromString(timeCheck[2]);
489  int timediff = abs(our_time.secsTo(master_time));
490 
491  if (timediff > 300)
492  {
493  LOG(VB_GENERAL, LOG_ERR,
494  QString("Current time on the master backend differs by "
495  "%1 seconds from time on this system. Exiting.")
496  .arg(timediff));
497  if (tempMonitorConnection)
498  tempMonitorConnection->DecrRef();
499  return GENERIC_EXIT_INVALID_TIME;
500  }
501 
502  if (timediff > 20)
503  {
504  LOG(VB_GENERAL, LOG_WARNING,
505  QString("Time difference between the master "
506  "backend and this system is %1 seconds.")
507  .arg(timediff));
508  }
509  }
510  if (tempMonitorConnection)
511  tempMonitorConnection->DecrRef();
512 
513  return GENERIC_EXIT_OK;
514 }
515 
516 
518 {
519  if (cmdline.toBool("nohousekeeper"))
520  {
521  LOG(VB_GENERAL, LOG_WARNING, LOC +
522  "****** The Housekeeper has been DISABLED with "
523  "the --nohousekeeper option ******");
524  }
525  if (cmdline.toBool("nosched"))
526  {
527  LOG(VB_GENERAL, LOG_WARNING, LOC +
528  "********** The Scheduler has been DISABLED with "
529  "the --nosched option **********");
530  }
531  if (cmdline.toBool("noautoexpire"))
532  {
533  LOG(VB_GENERAL, LOG_WARNING, LOC +
534  "********* Auto-Expire has been DISABLED with "
535  "the --noautoexpire option ********");
536  }
537  if (cmdline.toBool("nojobqueue"))
538  {
539  LOG(VB_GENERAL, LOG_WARNING, LOC +
540  "********* The JobQueue has been DISABLED with "
541  "the --nojobqueue option *********");
542  }
543 }
544 
546 {
548  {
549  LOG(VB_GENERAL, LOG_ERR,
550  "MySQL time zone support is missing. "
551  "Please install it and try again. "
552  "See 'mysql_tzinfo_to_sql' for assistance.");
553  return GENERIC_EXIT_DB_NOTIMEZONE;
554  }
555 
556  bool ismaster = gCoreContext->IsMasterHost();
557 
558  if (!UpgradeTVDatabaseSchema(ismaster, ismaster))
559  {
560  LOG(VB_GENERAL, LOG_ERR, "Couldn't upgrade database to new schema");
561  return GENERIC_EXIT_DB_OUTOFDATE;
562  }
563 
564  MythTranslation::load("mythfrontend");
565 
566  if (!ismaster)
567  {
568  int ret = connect_to_master();
569  if (ret != GENERIC_EXIT_OK)
570  return ret;
571  }
572 
573  int port = gCoreContext->GetNumSetting("BackendServerPort", 6543);
574  if (gCoreContext->GetSetting("BackendServerIP").isEmpty() &&
575  gCoreContext->GetSetting("BackendServerIP6").isEmpty())
576  {
577  cerr << "No setting found for this machine's BackendServerIP.\n"
578  << "Please run setup on this machine and modify the first page\n"
579  << "of the general settings.\n";
580  return GENERIC_EXIT_SETUP_ERROR;
581  }
582 
583  MythSystemEventHandler *sysEventHandler = new MythSystemEventHandler();
584 
585  if (ismaster)
586  {
587  LOG(VB_GENERAL, LOG_NOTICE, LOC + "Starting up as the master server.");
588  }
589  else
590  {
591  LOG(VB_GENERAL, LOG_NOTICE, LOC + "Running as a slave backend.");
592  }
593 
594  print_warnings(cmdline);
595 
596  bool fatal_error = false;
597  bool runsched = setupTVs(ismaster, fatal_error);
598  if (fatal_error)
599  {
600  delete sysEventHandler;
601  return GENERIC_EXIT_SETUP_ERROR;
602  }
603 
604  Scheduler *sched = NULL;
605  if (ismaster)
606  {
607  if (runsched)
608  {
609  sched = new Scheduler(true, &tvList);
610  int err = sched->GetError();
611  if (err)
612  return err;
613 
614  if (cmdline.toBool("nosched"))
615  sched->DisableScheduling();
616  }
617 
618  if (!cmdline.toBool("noautoexpire"))
619  {
620  expirer = new AutoExpire(&tvList);
621  if (sched)
622  sched->SetExpirer(expirer);
623  }
624  gCoreContext->SetScheduler(sched);
625  }
626 
627  if (!cmdline.toBool("nohousekeeper"))
628  {
629  housekeeping = new HouseKeeper();
630 
631  if (ismaster)
632  {
638  }
639 
641 #ifdef __linux__
642  #ifdef CONFIG_BINDINGS_PYTHON
644  #endif
645 #endif
646 
647  housekeeping->Start();
648  }
649 
650  if (!cmdline.toBool("nojobqueue"))
651  jobqueue = new JobQueue(ismaster);
652 
653  // ----------------------------------------------------------------------
654  //
655  // ----------------------------------------------------------------------
656 
657  if (g_pUPnp == NULL)
658  {
659  g_pUPnp = new MediaServer();
660 
661  g_pUPnp->Init(ismaster, cmdline.toBool("noupnp"));
662  }
663 
664  // ----------------------------------------------------------------------
665  // Setup status server
666  // ----------------------------------------------------------------------
667 
668  HttpStatus *httpStatus = NULL;
669  HttpServer *pHS = g_pUPnp->GetHttpServer();
670 
671  if (pHS)
672  {
673  LOG(VB_GENERAL, LOG_INFO, "Main::Registering HttpStatus Extension");
674 
675  httpStatus = new HttpStatus( &tvList, sched, expirer, ismaster );
676  pHS->RegisterExtension( httpStatus );
677  }
678 
679  mainServer = new MainServer(
680  ismaster, port, &tvList, sched, expirer);
681 
682  int exitCode = mainServer->GetExitCode();
683  if (exitCode != GENERIC_EXIT_OK)
684  {
685  LOG(VB_GENERAL, LOG_CRIT,
686  "Backend exiting, MainServer initialization error.");
687  cleanup();
688  return exitCode;
689  }
690 
691  if (httpStatus && mainServer)
692  httpStatus->SetMainServer(mainServer);
693 
695 
697  gCoreContext->SendSystemEvent("MASTER_STARTED");
698 
701  exitCode = qApp->exec();
704 
706  {
707  gCoreContext->SendSystemEvent("MASTER_SHUTDOWN");
708  qApp->processEvents();
709  }
710 
711  LOG(VB_GENERAL, LOG_NOTICE, "MythBackend exiting");
712 
713  delete sysEventHandler;
714 
715  return exitCode;
716 }
static void CheckProgramIDAuthorities(void)
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:765
MythScheduler * GetScheduler(void)
void FillRecordListFromMaster(void)
Definition: scheduler.cpp:548
void bindValue(const QString &placeholder, const QVariant &val)
Definition: mythdbcon.cpp:857
static TaskQueue * Instance()
Definition: taskqueue.cpp:66
void RegisterTask(HouseKeeperTask *task)
QString pidfile
QVariant value(int i) const
Definition: mythdbcon.h:182
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:147
void SetScheduler(MythScheduler *sched)
unsigned int uint
Definition: compat.h:135
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
uint64_t verboseMask
Definition: logging.cpp:118
void DisableScheduling(void)
Definition: scheduler.h:90
MythContext * gContext
This global variable contains the MythContext instance for the application.
Definition: mythcontext.cpp:52
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 connect_to_master(void)
void Stop(void)
Definition: mainserver.cpp:348
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:140
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
QString GetSetting(const QString &key, const QString &defaultval="")
void PrintList(bool onlyFutureRecordings=false)
Definition: scheduler.h:80
virtual int DecrRef(void)
Decrements reference count and deletes on 0.
void RequestTerminate(void)
Definition: ssdp.cpp:142
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)
then echo error
Definition: unittests.sh:42
void FillRecordListFromDB(uint recordid=0)
Definition: scheduler.cpp:460
void Init(bool bMaster, bool bDisableUPnp=false)
Definition: mediaserver.cpp:70
static void Done(void)
static MSqlQueryInfo InitCon(ConnectionReuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:529
int GetError(void) const
Definition: scheduler.h:99
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:775
static QMap< uint, TVRec * > cards
Definition: tv_rec.h:408
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:790
HttpServer * GetHttpServer()
Definition: upnp.h:125
static SSDP * Instance()
Definition: ssdp.cpp:47
LogLevel_t logLevel
Definition: logging.cpp:106
bool ConnectToHost(const QString &hostname, quint16 port)
connect to host
Definition: mythsocket.cpp:378
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:128
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:330
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:597
bool WriteStringList(const QStringList &list)
Definition: mythsocket.cpp:305
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:4694
void Start(void)