MythTV  master
mythcorecontext.cpp
Go to the documentation of this file.
1 // Qt
2 #include <QCoreApplication>
3 #include <QUrl>
4 #include <QDir>
5 #include <QFileInfo>
6 #include <QDebug>
7 #include <QMutex>
8 #include <QRunnable>
9 #include <QWaitCondition>
10 #include <QNetworkInterface>
11 #include <QAbstractSocket>
12 #include <QHostAddress>
13 #include <QHostInfo>
14 #include <QNetworkInterface>
15 #include <QNetworkAddressEntry>
16 #include <QLocale>
17 #include <QPair>
18 #include <QDateTime>
19 #include <QRunnable>
20 
21 // Std
22 #include <algorithm>
23 #include <cmath>
24 #include <cstdarg>
25 #include <queue>
26 #include <unistd.h> // for usleep()
27 using namespace std;
28 
29 #ifdef _WIN32
30 #include <winsock2.h>
31 #else
32 #include <clocale>
33 #include <utility>
34 #endif
35 
36 // MythTV
37 #include "compat.h"
38 #include "mythconfig.h" // for CONFIG_DARWIN
39 #include "mythdownloadmanager.h"
40 #include "mythcorecontext.h"
41 #include "mythsocket.h"
42 #include "mythsystemlegacy.h"
43 #include "mthreadpool.h"
44 #include "exitcodes.h"
45 #include "mythlogging.h"
46 #include "mythversion.h"
47 #include "logging.h"
48 #include "mthread.h"
49 #include "serverpool.h"
50 #include "mythdate.h"
51 #include "mythplugin.h"
52 #include "mythmiscutil.h"
53 #include "mythpower.h"
54 
55 #define LOC QString("MythCoreContext::%1(): ").arg(__func__)
56 
58 
59 class MythCoreContextPrivate : public QObject
60 {
61  public:
62  MythCoreContextPrivate(MythCoreContext *lparent, QString binversion,
63  QObject *guicontext);
64  ~MythCoreContextPrivate() override;
65 
66  bool WaitForWOL(int timeout_in_ms = INT_MAX);
67 
68  public:
70  QObject *m_guiContext;
71  QObject *m_guiObject;
73 
74  QMutex m_localHostLock;
75  QString m_localHostname;
77  QString m_masterHostname;
78  QMutex m_scopesLock;
79  QMap<QString, QString> m_scopes;
80 
81  QMutex m_sockLock;
84 
89 
90  bool m_backend;
91  bool m_frontend;
92 
93  MythDB *m_database;
94 
95  QThread *m_uiThread;
96 
98  QString m_language;
99 
101 
103 
104  QMap<QObject *, QByteArray> m_playbackClients;
108 
110 
112 
114 
115  QMap<QString, QPair<int64_t, uint64_t> > m_fileswritten;
116  QMutex m_fileslock;
117 
119 
120  QList<QHostAddress> m_approvedIps;
121  QList<QHostAddress> m_deniedIps;
122 
124 };
125 
127  QString binversion,
128  QObject *guicontext)
129  : m_parent(lparent),
130  m_guiContext(guicontext),
131  m_guiObject(nullptr),
132  m_appBinaryVersion(std::move(binversion)),
133  m_sockLock(QMutex::NonRecursive),
134  m_serverSock(nullptr),
135  m_eventSock(nullptr),
136  m_wolInProgress(false),
137  m_isWOLAllowed(true),
138  m_backend(false),
139  m_frontend(false),
140  m_database(GetMythDB()),
141  m_uiThread(QThread::currentThread()),
142  m_locale(nullptr),
143  m_scheduler(nullptr),
144  m_blockingClient(true),
145  m_inwanting(false),
146  m_intvwanting(false),
147  m_announcedProtocol(false),
148  m_pluginmanager(nullptr),
149  m_isexiting(false),
150  m_sessionManager(nullptr),
151  m_power(nullptr)
152 {
153  MThread::ThreadSetup("CoreContext");
154 #if QT_VERSION < QT_VERSION_CHECK(5,10,0)
155  srandom(MythDate::current().toSecsSinceEpoch() ^ QTime::currentTime().msec());
156 #endif
157 }
158 
159 static void delete_sock(QMutexLocker &locker, MythSocket **s)
160 {
161  if (*s)
162  {
163  MythSocket *tmp = *s;
164  *s = nullptr;
165  locker.unlock();
166  tmp->DecrRef();
167  locker.relock();
168  }
169 }
170 
172 {
173  if (m_power)
174  MythPower::AcquireRelease(this, false);
175 
177 
178  {
179  QMutexLocker locker(&m_sockLock);
180  delete_sock(locker, &m_serverSock);
181  delete_sock(locker, &m_eventSock);
182  }
183 
184  delete m_locale;
185 
186  delete m_sessionManager;
187 
189 
191 
193 
194  // This has already been run in the MythContext dtor. Do we need it here
195  // too?
196 #if 0
197  logStop(); // need to shutdown db logger before we kill db
198 #endif
199 
201 
202  GetMythDB()->GetDBManager()->CloseDatabases();
203 
204  if (m_database) {
205  DestroyMythDB();
206  m_database = nullptr;
207  }
208 
210 }
211 
215 bool MythCoreContextPrivate::WaitForWOL(int timeout_in_ms)
216 {
217  int timeout_remaining = timeout_in_ms;
218  while (m_wolInProgress && (timeout_remaining > 0))
219  {
220  LOG(VB_GENERAL, LOG_INFO, LOC + "Wake-On-LAN in progress, waiting...");
221 
222  int max_wait = min(1000, timeout_remaining);
224  &m_wolInProgressLock, max_wait);
225  timeout_remaining -= max_wait;
226  }
227 
228  return !m_wolInProgress;
229 }
230 
231 MythCoreContext::MythCoreContext(const QString &binversion,
232  QObject *guiContext)
233 {
234  d = new MythCoreContextPrivate(this, binversion, guiContext);
235 }
236 
238 {
239  if (!d)
240  {
241  LOG(VB_GENERAL, LOG_EMERG, LOC + "Out-of-memory");
242  return false;
243  }
244 
246  {
247  LOG(VB_GENERAL, LOG_CRIT,
248  QString("Application binary version (%1) does not "
249  "match libraries (%2)")
251 
252  QString warning = tr("This application is not compatible with the "
253  "installed MythTV libraries. Please recompile "
254  "after a make distclean");
255  LOG(VB_GENERAL, LOG_WARNING, warning);
256 
257  return false;
258  }
259 
260 #ifndef _WIN32
261  QString lang_variables("");
262  QString lc_value = setlocale(LC_CTYPE, nullptr);
263  if (lc_value.isEmpty())
264  {
265  // try fallback to environment variables for non-glibc systems
266  // LC_ALL, then LC_CTYPE
267  lc_value = getenv("LC_ALL");
268  if (lc_value.isEmpty())
269  lc_value = getenv("LC_CTYPE");
270  }
271  if (!lc_value.contains("UTF-8", Qt::CaseInsensitive))
272  lang_variables.append("LC_ALL or LC_CTYPE");
273  lc_value = getenv("LANG");
274  if (!lc_value.contains("UTF-8", Qt::CaseInsensitive))
275  {
276  if (!lang_variables.isEmpty())
277  lang_variables.append(", and ");
278  lang_variables.append("LANG");
279  }
280  LOG(VB_GENERAL, LOG_INFO, QString("Assumed character encoding: %1")
281  .arg(lc_value));
282  if (!lang_variables.isEmpty())
283  {
284  LOG(VB_GENERAL, LOG_WARNING, QString("This application expects to "
285  "be running a locale that specifies a UTF-8 codeset, and many "
286  "features may behave improperly with your current language "
287  "settings. Please set the %1 variable(s) in the environment "
288  "in which this program is executed to include a UTF-8 codeset "
289  "(such as 'en_US.UTF-8').").arg(lang_variables));
290  }
291 #endif
292 
293  return true;
294 }
295 
297 {
298  delete d;
299  d = nullptr;
300 }
301 
303  const QString &announcement,
304  uint timeout_in_ms,
305  bool &proto_mismatch)
306 {
307  proto_mismatch = false;
308 
309 #ifndef IGNORE_PROTO_VER_MISMATCH
310  if (!CheckProtoVersion(serverSock, timeout_in_ms, true))
311  {
312  proto_mismatch = true;
313  return false;
314  }
315 #else
316  Q_UNUSED(timeout_in_ms);
317 #endif
318 
319  QStringList strlist(announcement);
320 
321  if (!serverSock->WriteStringList(strlist))
322  {
323  LOG(VB_GENERAL, LOG_ERR, LOC + "Connecting server socket to "
324  "master backend, socket write failed");
325  return false;
326  }
327 
328  if (!serverSock->ReadStringList(strlist, MythSocket::kShortTimeout) ||
329  strlist.empty() || (strlist[0] == "ERROR"))
330  {
331  if (!strlist.empty())
332  {
333  LOG(VB_GENERAL, LOG_ERR, LOC + "Problem connecting "
334  "server socket to master backend");
335  }
336  else
337  {
338  LOG(VB_GENERAL, LOG_ERR, LOC + "Timeout connecting "
339  "server socket to master backend");
340  }
341  return false;
342  }
343 
344  return true;
345 }
346 
347 // Connects to master server safely (i.e. by taking m_sockLock)
349  bool openEventSocket)
350 {
351  QMutexLocker locker(&d->m_sockLock);
352  bool success = ConnectToMasterServer(blockingClient, openEventSocket);
353 
354  return success;
355 }
356 
357 // Assumes that either m_sockLock is held, or the app is still single
358 // threaded (i.e. during startup).
359 bool MythCoreContext::ConnectToMasterServer(bool blockingClient,
360  bool openEventSocket)
361 {
362  if (IsMasterBackend())
363  {
364  // Should never get here unless there is a bug in the code somewhere.
365  // If this happens, it can cause endless event loops.
366  LOG(VB_GENERAL, LOG_ERR, LOC + "ERROR: Master backend tried to connect back "
367  "to itself!");
368  return false;
369  }
370  if (IsExiting())
371  return false;
372 
373  QString server = GetMasterServerIP();
374  if (server.isEmpty())
375  return false;
376 
377  int port = GetMasterServerPort();
378  bool proto_mismatch = false;
379 
380  if (d->m_serverSock && !d->m_serverSock->IsConnected())
381  {
382  d->m_serverSock->DecrRef();
383  d->m_serverSock = nullptr;
384  }
385 
386  if (!d->m_serverSock)
387  {
388  QString type = IsFrontend() ? "Frontend" : (blockingClient ? "Playback" : "Monitor");
389  QString ann = QString("ANN %1 %2 %3")
390  .arg(type)
391  .arg(d->m_localHostname).arg(static_cast<int>(false));
393  server, port, ann, &proto_mismatch);
394  }
395 
396  if (!d->m_serverSock)
397  return false;
398 
399  d->m_blockingClient = blockingClient;
400 
401  if (!openEventSocket)
402  return true;
403 
404 
405  if (!IsBackend())
406  {
407  if (d->m_eventSock && !d->m_eventSock->IsConnected())
408  {
409  d->m_eventSock->DecrRef();
410  d->m_eventSock = nullptr;
411  }
412  if (!d->m_eventSock)
413  d->m_eventSock = ConnectEventSocket(server, port);
414 
415  if (!d->m_eventSock)
416  {
417  d->m_serverSock->DecrRef();
418  d->m_serverSock = nullptr;
419 
420  QCoreApplication::postEvent(
421  d->m_guiContext, new MythEvent("CONNECTION_FAILURE"));
422 
423  return false;
424  }
425  }
426 
427  return true;
428 }
429 
431  const QString &hostname, int port, const QString &announce,
432  bool *p_proto_mismatch, int maxConnTry, int setup_timeout)
433 {
434  MythSocket *serverSock = nullptr;
435 
436  {
437  QMutexLocker locker(&d->m_wolInProgressLock);
438  d->WaitForWOL();
439  }
440 
441  QString WOLcmd;
442  if (IsWOLAllowed())
443  WOLcmd = GetSetting("WOLbackendCommand", "");
444 
445  if (maxConnTry < 1)
446  maxConnTry = max(GetNumSetting("BackendConnectRetry", 1), 1);
447 
448  int WOLsleepTime = 0;
449  int WOLmaxConnTry = 0;
450  if (!WOLcmd.isEmpty())
451  {
452  WOLsleepTime = GetNumSetting("WOLbackendReconnectWaitTime", 0);
453  WOLmaxConnTry = max(GetNumSetting("WOLbackendConnectRetry", 1), 1);
454  maxConnTry = max(maxConnTry, WOLmaxConnTry);
455  }
456 
457  bool we_attempted_wol = false;
458 
459  if (setup_timeout <= 0)
460  setup_timeout = MythSocket::kShortTimeout;
461 
462  bool proto_mismatch = false;
463  for (int cnt = 1; cnt <= maxConnTry; cnt++)
464  {
465  LOG(VB_GENERAL, LOG_INFO, LOC +
466  QString("Connecting to backend server: %1:%2 (try %3 of %4)")
467  .arg(hostname).arg(port).arg(cnt).arg(maxConnTry));
468 
469  serverSock = new MythSocket();
470 
471  int sleepms = 0;
472  if (serverSock->ConnectToHost(hostname, port))
473  {
474  if (SetupCommandSocket(
475  serverSock, announce, setup_timeout, proto_mismatch))
476  {
477  break;
478  }
479 
480  if (proto_mismatch)
481  {
482  if (p_proto_mismatch)
483  *p_proto_mismatch = true;
484 
485  serverSock->DecrRef();
486  serverSock = nullptr;
487  break;
488  }
489 
490  setup_timeout = (int)(setup_timeout * 1.5F);
491  }
492  else if (!WOLcmd.isEmpty() && (cnt < maxConnTry))
493  {
494  if (!we_attempted_wol)
495  {
496  QMutexLocker locker(&d->m_wolInProgressLock);
497  if (d->m_wolInProgress)
498  {
499  d->WaitForWOL();
500  continue;
501  }
502 
503  d->m_wolInProgress = we_attempted_wol = true;
504  }
505 
508  sleepms = WOLsleepTime * 1000;
509  }
510 
511  serverSock->DecrRef();
512  serverSock = nullptr;
513 
514  if (cnt == 1)
515  {
516  QCoreApplication::postEvent(
517  d->m_guiContext, new MythEvent("CONNECTION_FAILURE"));
518  }
519 
520  if (sleepms)
521  usleep(sleepms * 1000);
522  }
523 
524  if (we_attempted_wol)
525  {
526  QMutexLocker locker(&d->m_wolInProgressLock);
527  d->m_wolInProgress = false;
528  d->m_wolInProgressWaitCondition.wakeAll();
529  }
530 
531  if (!serverSock && !proto_mismatch)
532  {
533  LOG(VB_GENERAL, LOG_ERR,
534  "Connection to master server timed out.\n\t\t\t"
535  "Either the server is down or the master server settings"
536  "\n\t\t\t"
537  "in mythtv-settings does not contain the proper IP address\n");
538  }
539  else
540  {
541  QCoreApplication::postEvent(
542  d->m_guiContext, new MythEvent("CONNECTION_RESTABLISHED"));
543  }
544 
545  return serverSock;
546 }
547 
549  int port)
550 {
551  auto *eventSock = new MythSocket(-1, this);
552 
553  // Assume that since we _just_ connected the command socket,
554  // this one won't need multiple retries to work...
555  if (!eventSock->ConnectToHost(hostname, port))
556  {
557  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to connect event "
558  "socket to master backend");
559  eventSock->DecrRef();
560  return nullptr;
561  }
562 
563  QString str = QString("ANN Monitor %1 %2")
564  .arg(d->m_localHostname).arg(static_cast<int>(true));
565  QStringList strlist(str);
566  eventSock->WriteStringList(strlist);
567  bool ok = true;
568  if (!eventSock->ReadStringList(strlist) || strlist.empty() ||
569  (strlist[0] == "ERROR"))
570  {
571  if (!strlist.empty())
572  {
573  LOG(VB_GENERAL, LOG_ERR, LOC +
574  "Problem connecting event socket to master backend");
575  }
576  else
577  {
578  LOG(VB_GENERAL, LOG_ERR, LOC +
579  "Timeout connecting event socket to master backend");
580  }
581  ok = false;
582  }
583 
584  if (!ok)
585  {
586  eventSock->DecrRef();
587  eventSock = nullptr;
588  }
589 
590  return eventSock;
591 }
592 
594 {
595  QMutexLocker locker(&d->m_sockLock);
596  return d->m_serverSock;
597 }
598 
600 {
601  QStringList strlist;
602 
603  QMutexLocker locker(&d->m_sockLock);
604  if (d->m_serverSock == nullptr)
605  return;
606 
607  strlist << "BLOCK_SHUTDOWN";
609 
610  d->m_blockingClient = true;
611 }
612 
614 {
615  QStringList strlist;
616 
617  QMutexLocker locker(&d->m_sockLock);
618  if (d->m_serverSock == nullptr)
619  return;
620 
621  strlist << "ALLOW_SHUTDOWN";
623 
624  d->m_blockingClient = false;
625 }
626 
628 {
629  return d->m_blockingClient;
630 }
631 
633 {
634  d->m_isWOLAllowed = allow;
635 }
636 
638 {
639  return d->m_isWOLAllowed;
640 }
641 
643 {
644  d->m_backend = backend;
645 }
646 
648 {
649  return d->m_backend;
650 }
651 
653 {
654  d->m_frontend = frontend;
655 }
656 
658 {
659  return d->m_frontend;
660 }
661 
663 {
664  QString host = GetHostName();
665  return IsMasterHost(host);
666 }
667 
668 bool MythCoreContext::IsMasterHost(const QString &host)
669 {
670  // Temporary code here only to facilitate the upgrade
671  // from 1346 or earlier. The way of determining master host is
672  // changing, and the new way of determning master host
673  // will not work with earlier databases.
674  // This code can be removed when updating from prior to
675  // 1347 is no longer allowed.
676  // Note that we are deprecating some settings including
677  // MasterServerIP, and can remove them at a future time.
678  if (GetNumSetting("DBSchemaVer") < 1347)
679  {
680  // Temporary copy of code from old version of
681  // IsThisHost(Qstring&,QString&)
682  QString addr(resolveSettingAddress("MasterServerIP"));
683  if (addr.toLower() == host.toLower())
684  return true;
685  QHostAddress addrfix(addr);
686  addrfix.setScopeId(QString());
687  QString addrstr = addrfix.toString();
688  if (addrfix.isNull())
689  addrstr = resolveAddress(addr);
690  QString thisip = GetBackendServerIP4(host);
691  QString thisip6 = GetBackendServerIP6(host);
692  return !addrstr.isEmpty()
693  && ((addrstr == thisip) || (addrstr == thisip6));
694  }
695  return GetSetting("MasterServerName") == host;
696 }
697 
699 {
700  return (IsBackend() && IsMasterHost());
701 }
702 
704 {
705 #if CONFIG_DARWIN || (__FreeBSD__) || defined(__OpenBSD__)
706  const char *command = "ps -axc | grep -i mythbackend | grep -v grep > /dev/null";
707 #elif defined _WIN32
708  const char *command = "%systemroot%\\system32\\tasklist.exe "
709  " | %systemroot%\\system32\\find.exe /i \"mythbackend.exe\" ";
710 #else
711  const char *command = "ps ch -C mythbackend -o pid > /dev/null";
712 #endif
713  uint res = myth_system(command, kMSDontBlockInputDevs |
716  return (res == GENERIC_EXIT_OK);
717 }
718 
719 bool MythCoreContext::IsThisBackend(const QString &addr)
720 {
721  return IsBackend() && IsThisHost(addr);
722 }
723 
724 bool MythCoreContext::IsThisHost(const QString &addr)
725 {
726  return IsThisHost(addr, GetHostName());
727 }
728 
729 bool MythCoreContext::IsThisHost(const QString &addr, const QString &host)
730 {
731  if (addr.toLower() == host.toLower())
732  return true;
733 
734  QHostAddress addrfix(addr);
735  addrfix.setScopeId(QString());
736  QString addrstr = addrfix.toString();
737 
738  if (addrfix.isNull())
739  {
740  addrstr = resolveAddress(addr);
741  }
742 
743  QString thisip = GetBackendServerIP(host);
744 
745  return !addrstr.isEmpty() && ((addrstr == thisip));
746 }
747 
749 {
750  // find out if a backend runs on this host...
751  bool backendOnLocalhost = false;
752 
753  QStringList strlist("QUERY_IS_ACTIVE_BACKEND");
754  strlist << GetHostName();
755 
756  SendReceiveStringList(strlist);
757 
758  backendOnLocalhost = strlist[0] != "FALSE";
759 
760  return !backendOnLocalhost;
761 }
762 
763 QString MythCoreContext::GenMythURL(const QString& host, int port, QString path, const QString& storageGroup)
764 {
765  QUrl ret;
766 
767  QString m_host;
768 
769  QHostAddress addr(host);
770  if (!addr.isNull())
771  {
772  LOG(VB_GENERAL, LOG_CRIT, LOC + QString("(%1/%2): Given "
773  "IP address instead of hostname "
774  "(ID). This is invalid.").arg(host).arg(path));
775  }
776 
777  m_host = host;
778 
779  // Basically if it appears to be an IPv6 IP surround the IP with [] otherwise don't bother
780  if (!addr.isNull() && addr.protocol() == QAbstractSocket::IPv6Protocol)
781  m_host = "[" + addr.toString().toLower() + "]";
782 
783  ret.setScheme("myth");
784  if (!storageGroup.isEmpty())
785  ret.setUserName(storageGroup);
786  ret.setHost(m_host);
787  if (port > 0 && port != 6543)
788  ret.setPort(port);
789  if (!path.startsWith("/"))
790  path = QString("/") + path;
791  ret.setPath(path);
792 
793 #if 0
794  LOG(VB_GENERAL, LOG_DEBUG, LOC +
795  QString("GenMythURL returning %1").arg(ret.toString()));
796 #endif
797 
798  return ret.toString();
799 }
800 
801 QString MythCoreContext::GetMasterHostPrefix(const QString &storageGroup,
802  const QString &path)
803 {
804  return GenMythURL(GetMasterHostName(),
806  path,
807  storageGroup);
808 }
809 
811 {
812  QMutexLocker locker(&d->m_masterHostLock);
813 
814  if (d->m_masterHostname.isEmpty())
815  {
816 
817  if (IsMasterBackend())
819  else
820  {
821  QStringList strlist("QUERY_HOSTNAME");
822 
823  if (SendReceiveStringList(strlist))
824  d->m_masterHostname = strlist[0];
825  }
826  }
827 
828  return d->m_masterHostname;
829 }
830 
831 void MythCoreContext::ClearSettingsCache(const QString &myKey)
832 {
833  d->m_database->ClearSettingsCache(myKey);
834 }
835 
837 {
838  d->m_database->ActivateSettingsCache(activate);
839 }
840 
842 {
843  QMutexLocker locker(&d->m_localHostLock);
844  return d->m_localHostname;
845 }
846 
848 {
849  return GetSetting("RecordFilePrefix");
850 }
851 
853  int &width, int &height,
854  double &forced_aspect,
855  double &refresh_rate,
856  int index)
857 {
858  d->m_database->GetResolutionSetting(type, width, height, forced_aspect,
859  refresh_rate, index);
860 }
861 
862 void MythCoreContext::GetResolutionSetting(const QString &t, int &w,
863  int &h, int i)
864 {
865  d->m_database->GetResolutionSetting(t, w, h, i);
866 }
867 
869 {
870  return d->m_database->GetDBManager();
871 }
872 
880 {
881  return d->m_database->IsDatabaseIgnored();
882 }
883 
884 void MythCoreContext::SaveSetting(const QString &key, int newValue)
885 {
886  d->m_database->SaveSetting(key, newValue);
887 }
888 
889 void MythCoreContext::SaveSetting(const QString &key, const QString &newValue)
890 {
891  d->m_database->SaveSetting(key, newValue);
892 }
893 
894 bool MythCoreContext::SaveSettingOnHost(const QString &key,
895  const QString &newValue,
896  const QString &host)
897 {
898  return d->m_database->SaveSettingOnHost(key, newValue, host);
899 }
900 
901 QString MythCoreContext::GetSetting(const QString &key,
902  const QString &defaultval)
903 {
904  return d->m_database->GetSetting(key, defaultval);
905 }
906 
907 bool MythCoreContext::GetBoolSetting(const QString &key, bool defaultval)
908 {
909  int result = GetNumSetting(key, static_cast<int>(defaultval));
910  return result > 0;
911 }
912 
913 int MythCoreContext::GetNumSetting(const QString &key, int defaultval)
914 {
915  return d->m_database->GetNumSetting(key, defaultval);
916 }
917 
918 double MythCoreContext::GetFloatSetting(const QString &key, double defaultval)
919 {
920  return d->m_database->GetFloatSetting(key, defaultval);
921 }
922 
923 QString MythCoreContext::GetSettingOnHost(const QString &key,
924  const QString &host,
925  const QString &defaultval)
926 {
927  return d->m_database->GetSettingOnHost(key, host, defaultval);
928 }
929 
931  const QString &host,
932  bool defaultval)
933 {
934  int result = GetNumSettingOnHost(key, host, static_cast<int>(defaultval));
935  return result > 0;
936 }
937 
939  const QString &host,
940  int defaultval)
941 {
942  return d->m_database->GetNumSettingOnHost(key, host, defaultval);
943 }
944 
945 double MythCoreContext::GetFloatSettingOnHost(const QString &key,
946  const QString &host,
947  double defaultval)
948 {
949  return d->m_database->GetFloatSettingOnHost(key, host, defaultval);
950 }
951 
958 {
959  QString masterserver = gCoreContext->GetSetting("MasterServerName");
960  QString masterip = resolveSettingAddress("BackendServerAddr",masterserver);
961  // Even if empty, return it here if we were to assume that localhost
962  // should be used it just causes a lot of unnecessary error messages.
963  return masterip;
964 }
965 
972 {
973  QString masterserver = gCoreContext->GetSetting
974  ("MasterServerName");
976  ("BackendServerPort", masterserver, 6543);
977 }
978 
985 {
986  QString masterhost = GetMasterHostName();
987 
988  return GetBackendStatusPort(masterhost);
989 }
990 
996 {
998 }
999 
1009 QString MythCoreContext::GetBackendServerIP(const QString &host)
1010 {
1011  return resolveSettingAddress("BackendServerAddr",host);
1012 }
1013 
1019 {
1021 }
1022 
1028 QString MythCoreContext::GetBackendServerIP4(const QString &host)
1029 {
1030  return resolveSettingAddress("BackendServerIP", host, ResolveIPv4);
1031 }
1032 
1038 {
1040 }
1041 
1047 QString MythCoreContext::GetBackendServerIP6(const QString &host)
1048 {
1049  return resolveSettingAddress("BackendServerIP6", host, ResolveIPv6);
1050 }
1051 
1056 {
1058 }
1059 
1064 {
1065  return GetNumSettingOnHost("BackendServerPort", host, 6543);
1066 }
1067 
1072 {
1074 }
1075 
1080 {
1081  return GetNumSettingOnHost("BackendStatusPort", host, 6544);
1082 }
1083 
1088 bool MythCoreContext::GetScopeForAddress(QHostAddress &addr) const
1089 {
1090  QHostAddress addr1 = addr;
1091  addr1.setScopeId(QString());
1092  QString addrstr = addr1.toString();
1093  QMutexLocker lock(&d->m_scopesLock);
1094 
1095  if (!d->m_scopes.contains(addrstr))
1096  return false;
1097 
1098  addr.setScopeId(d->m_scopes[addrstr]);
1099  return true;
1100 }
1101 
1108 void MythCoreContext::SetScopeForAddress(const QHostAddress &addr)
1109 {
1110  QHostAddress addr1 = addr;
1111  addr1.setScopeId(QString());
1112  QMutexLocker lock(&d->m_scopesLock);
1113 
1114  d->m_scopes.insert(addr1.toString(), addr.scopeId());
1115 }
1116 
1122 void MythCoreContext::SetScopeForAddress(const QHostAddress &addr, int scope)
1123 {
1124  QHostAddress addr1 = addr;
1125  addr1.setScopeId(QString());
1126  QMutexLocker lock(&d->m_scopesLock);
1127 
1128  d->m_scopes.insert(addr1.toString(), QString::number(scope));
1129 }
1130 
1142 QString MythCoreContext::resolveSettingAddress(const QString &name,
1143  const QString &host,
1144  ResolveType type, bool keepscope)
1145 {
1146  QString value;
1147 
1148  if (host.isEmpty())
1149  {
1150  value = GetSetting(name);
1151  }
1152  else
1153  {
1154  value = GetSettingOnHost(name, host);
1155  }
1156 
1157  return resolveAddress(value, type, keepscope);
1158 }
1159 
1171 QString MythCoreContext::resolveAddress(const QString &host, ResolveType type,
1172  bool keepscope)
1173 {
1174  QHostAddress addr(host);
1175 
1176  if (!host.isEmpty() && addr.isNull())
1177  {
1178  // address is likely a hostname, attempts to resolve it
1179  QHostInfo info = QHostInfo::fromName(host);
1180  QList<QHostAddress> list = info.addresses();
1181 
1182  if (list.isEmpty())
1183  {
1184  LOG(VB_GENERAL, LOG_WARNING, LOC +
1185  QString("Can't resolve hostname:'%1', using localhost").arg(host));
1186  return type == ResolveIPv4 ? "127.0.0.1" : "::1";
1187  }
1188  QHostAddress v4;
1189  QHostAddress v6;
1190 
1191  // Return the first address fitting the type critera
1192  for (const auto& item : qAsConst(list))
1193  {
1194  addr = item;
1195  QAbstractSocket::NetworkLayerProtocol prot = addr.protocol();
1196 
1197  if (prot == QAbstractSocket::IPv4Protocol)
1198  {
1199  v4 = addr;
1200  if (type == 0)
1201  break;
1202  }
1203  else if (prot == QAbstractSocket::IPv6Protocol)
1204  {
1205  v6 = addr;
1206  if (type != 0)
1207  break;
1208  }
1209  }
1210  switch (type)
1211  {
1212  case ResolveIPv4:
1213  addr = v4.isNull() ? QHostAddress::LocalHost : v4;
1214  break;
1215  case ResolveIPv6:
1216  addr = v6.isNull() ? QHostAddress::LocalHostIPv6 : v6;
1217  break;
1218  default:
1219  addr = v6.isNull() ?
1220  (v4.isNull() ? QHostAddress::LocalHostIPv6 : v4) : v6;
1221  break;
1222  }
1223  }
1224  else if (host.isEmpty())
1225  {
1226  return QString();
1227  }
1228 
1229  if (!keepscope)
1230  {
1231  addr.setScopeId(QString());
1232  }
1233  return addr.toString();
1234 }
1235 
1247 bool MythCoreContext::CheckSubnet(const QAbstractSocket *socket)
1248 {
1249  QHostAddress peer = socket->peerAddress();
1250  return CheckSubnet(peer);
1251 }
1252 
1264 bool MythCoreContext::CheckSubnet(const QHostAddress &peer)
1265 {
1266  static const QHostAddress kLinkLocal("fe80::");
1267  if (GetBoolSetting("AllowConnFromAll",false))
1268  return true;
1269  if (d->m_approvedIps.contains(peer))
1270  return true;
1271  if (d->m_deniedIps.contains(peer))
1272  {
1273  LOG(VB_GENERAL, LOG_WARNING, LOC +
1274  QString("Repeat denied connection from ip address: %1")
1275  .arg(peer.toString()));
1276  return false;
1277  }
1278 
1279  // allow all link-local
1280  if (peer.isInSubnet(kLinkLocal,10))
1281  {
1282  d->m_approvedIps.append(peer);
1283  return true;
1284  }
1285 
1286  // loop through all available interfaces
1287  QList<QNetworkInterface> IFs = QNetworkInterface::allInterfaces();
1288  QList<QNetworkInterface>::const_iterator qni;
1289  for (qni = IFs.begin(); qni != IFs.end(); ++qni)
1290  {
1291  if ((qni->flags() & QNetworkInterface::IsRunning) == 0)
1292  continue;
1293 
1294  QList<QNetworkAddressEntry> IPs = qni->addressEntries();
1295  QList<QNetworkAddressEntry>::iterator qnai;
1296  for (qnai = IPs.begin(); qnai != IPs.end(); ++qnai)
1297  {
1298  int pfxlen = qnai->prefixLength();
1299  // Set this to test rejection without having an extra
1300  // network.
1301  if (GetBoolSetting("DebugSubnet"))
1302  pfxlen += 4;
1303  if (peer.isInSubnet(qnai->ip(),pfxlen))
1304  {
1305  d->m_approvedIps.append(peer);
1306  return true;
1307  }
1308  }
1309  }
1310  d->m_deniedIps.append(peer);
1311  LOG(VB_GENERAL, LOG_WARNING, LOC +
1312  QString("Denied connection from ip address: %1")
1313  .arg(peer.toString()));
1314  return false;
1315 }
1316 
1317 
1319  const QString &value)
1320 {
1321  d->m_database->OverrideSettingForSession(key, value);
1322 }
1323 
1325 {
1326  d->m_database->ClearOverrideSettingForSession(key);
1327 }
1328 
1330 {
1331  return is_current_thread(d->m_uiThread);
1332 }
1333 
1353  QStringList &strlist, bool quickTimeout, bool block)
1354 {
1355  QString msg;
1356  if (HasGUI() && IsUIThread())
1357  {
1358  msg = "SendReceiveStringList(";
1359  for (uint i=0; i<(uint)strlist.size() && i<2; i++)
1360  msg += (i?",":"") + strlist[i];
1361  msg += (strlist.size() > 2) ? "...)" : ")";
1362  LOG(VB_GENERAL, LOG_DEBUG, LOC + msg + " called from UI thread");
1363  }
1364 
1365  QString query_type = "UNKNOWN";
1366 
1367  if (!strlist.isEmpty())
1368  query_type = strlist[0];
1369 
1370  QMutexLocker locker(&d->m_sockLock);
1371  if (!d->m_serverSock)
1372  {
1373  bool blockingClient = d->m_blockingClient &&
1374  (GetNumSetting("idleTimeoutSecs",0) > 0);
1375  ConnectToMasterServer(blockingClient);
1376  }
1377 
1378  bool ok = false;
1379 
1380  if (d->m_serverSock)
1381  {
1382  QStringList sendstrlist = strlist;
1383  uint timeout = quickTimeout ?
1385  ok = d->m_serverSock->SendReceiveStringList(strlist, 0, timeout);
1386 
1387  if (!ok)
1388  {
1389  LOG(VB_GENERAL, LOG_NOTICE, LOC +
1390  QString("Connection to backend server lost"));
1391  d->m_serverSock->DecrRef();
1392  d->m_serverSock = nullptr;
1393 
1394  if (d->m_eventSock)
1395  {
1396  d->m_eventSock->DecrRef();
1397  d->m_eventSock = nullptr;
1398  }
1399 
1400  if (block)
1401  {
1403 
1404  if (d->m_serverSock)
1405  {
1407  strlist, 0, timeout);
1408  }
1409  }
1410  }
1411 
1412  // this should not happen
1413  while (ok && strlist[0] == "BACKEND_MESSAGE")
1414  {
1415  // oops, not for us
1416  LOG(VB_GENERAL, LOG_EMERG, LOC + "SRSL you shouldn't see this!!");
1417  QString message = strlist[1];
1418  strlist.pop_front(); strlist.pop_front();
1419 
1420  MythEvent me(message, strlist);
1421  dispatch(me);
1422 
1423  ok = d->m_serverSock->ReadStringList(strlist, timeout);
1424  }
1425 
1426  if (!ok)
1427  {
1428  if (d->m_serverSock)
1429  {
1430  d->m_serverSock->DecrRef();
1431  d->m_serverSock = nullptr;
1432  }
1433 
1434  LOG(VB_GENERAL, LOG_CRIT, LOC +
1435  QString("Reconnection to backend server failed"));
1436 
1437  QCoreApplication::postEvent(d->m_guiContext,
1438  new MythEvent("PERSISTENT_CONNECTION_FAILURE"));
1439  }
1440  }
1441 
1442  if (ok)
1443  {
1444  if (strlist.isEmpty())
1445  ok = false;
1446  else if (strlist[0] == "ERROR")
1447  {
1448  if (strlist.size() == 2)
1449  {
1450  LOG(VB_GENERAL, LOG_INFO, LOC +
1451  QString("Protocol query '%1' responded with the error '%2'")
1452  .arg(query_type).arg(strlist[1]));
1453  }
1454  else
1455  {
1456  LOG(VB_GENERAL, LOG_INFO, LOC +
1457  QString("Protocol query '%1' responded with an error, but "
1458  "no error message.") .arg(query_type));
1459  }
1460 
1461  ok = false;
1462  }
1463  else if (strlist[0] == "UNKNOWN_COMMAND")
1464  {
1465  LOG(VB_GENERAL, LOG_ERR, LOC +
1466  QString("Protocol query '%1' responded with the error 'UNKNOWN_COMMAND'")
1467  .arg(query_type));
1468 
1469  ok = false;
1470  }
1471  }
1472 
1473  return ok;
1474 }
1475 
1476 class SendAsyncMessage : public QRunnable
1477 {
1478  public:
1479  SendAsyncMessage(QString msg, QStringList extra) :
1480  m_message(std::move(msg)), m_extraData(std::move(extra))
1481  {
1482  }
1483 
1484  explicit SendAsyncMessage(QString msg) : m_message(std::move(msg)) { }
1485 
1486  void run(void) override // QRunnable
1487  {
1488  QStringList strlist("MESSAGE");
1489  strlist << m_message;
1490  strlist << m_extraData;
1492  }
1493 
1494  private:
1495  QString m_message;
1496  QStringList m_extraData;
1497 };
1498 
1499 void MythCoreContext::SendMessage(const QString &message)
1500 {
1501  if (IsBackend())
1502  {
1503  dispatch(MythEvent(message));
1504  }
1505  else
1506  {
1508  new SendAsyncMessage(message), "SendMessage");
1509  }
1510 }
1511 
1513 {
1514  if (IsBackend())
1515  {
1516  dispatch(event);
1517  }
1518  else
1519  {
1521  new SendAsyncMessage(event.Message(), event.ExtraDataList()),
1522  "SendEvent");
1523  }
1524 }
1525 
1526 void MythCoreContext::SendSystemEvent(const QString &msg)
1527 {
1528  if (QCoreApplication::applicationName() == MYTH_APPNAME_MYTHTV_SETUP)
1529  return;
1530 
1531  SendMessage(QString("SYSTEM_EVENT %1 SENDER %2")
1532  .arg(msg).arg(GetHostName()));
1533 }
1534 
1536  const QString &hostname,
1537  const QString &args)
1538 {
1539  SendSystemEvent(QString("%1 HOST %2 %3").arg(msg).arg(hostname).arg(args));
1540 }
1541 
1542 
1544 {
1545  do
1546  {
1547  QStringList strlist;
1548  if (!sock->ReadStringList(strlist))
1549  continue;
1550 
1551  if (strlist.size() < 2)
1552  continue;
1553 
1554  QString prefix = strlist[0];
1555  QString message = strlist[1];
1556 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
1557  QStringList tokens = message.split(" ", QString::SkipEmptyParts);
1558 #else
1559  QStringList tokens = message.split(" ", Qt::SkipEmptyParts);
1560 #endif
1561 
1562  if (prefix == "OK")
1563  {
1564  }
1565  else if (prefix != "BACKEND_MESSAGE")
1566  {
1567  LOG(VB_NETWORK, LOG_ERR, LOC +
1568  QString("Received a: %1 message from the backend "
1569  "but I don't know what to do with it.")
1570  .arg(prefix));
1571  }
1572  else if (message == "CLEAR_SETTINGS_CACHE")
1573  {
1574  // No need to dispatch this message to ourself, so handle it
1575  LOG(VB_NETWORK, LOG_INFO, LOC + "Received remote 'Clear Cache' request");
1577  }
1578  else if (message.startsWith("FILE_WRITTEN"))
1579  {
1580  QString file;
1581  uint64_t size = 0;
1582  int NUMTOKENS = 3; // Number of tokens expected
1583 
1584  if (tokens.size() == NUMTOKENS)
1585  {
1586  file = tokens[1];
1587  size = tokens[2].toULongLong();
1588  }
1589  else
1590  {
1591  LOG(VB_NETWORK, LOG_ERR, LOC +
1592  QString("FILE_WRITTEN event received "
1593  "with invalid number of arguments, "
1594  "%1 expected, %2 actual")
1595  .arg(NUMTOKENS-1)
1596  .arg(tokens.size()-1));
1597  return;
1598  }
1599  // No need to dispatch this message to ourself, so handle it
1600  LOG(VB_NETWORK, LOG_INFO, LOC +
1601  QString("Received remote 'FILE_WRITTEN %1' request").arg(file));
1602  RegisterFileForWrite(file, size);
1603  }
1604  else if (message.startsWith("FILE_CLOSED"))
1605  {
1606  QString file;
1607  int NUMTOKENS = 2; // Number of tokens expected
1608 
1609  if (tokens.size() == NUMTOKENS)
1610  {
1611  file = tokens[1];
1612  }
1613  else
1614  {
1615  LOG(VB_NETWORK, LOG_ERR, LOC +
1616  QString("FILE_CLOSED event received "
1617  "with invalid number of arguments, "
1618  "%1 expected, %2 actual")
1619  .arg(NUMTOKENS-1)
1620  .arg(tokens.size()-1));
1621  return;
1622  }
1623  // No need to dispatch this message to ourself, so handle it
1624  LOG(VB_NETWORK, LOG_INFO, LOC +
1625  QString("Received remote 'FILE_CLOSED %1' request").arg(file));
1627  }
1628  else
1629  {
1630  strlist.pop_front();
1631  strlist.pop_front();
1632  MythEvent me(message, strlist);
1633  dispatch(me);
1634  }
1635  }
1636  while (sock->IsDataAvailable());
1637 }
1638 
1640 {
1641  (void)sock;
1642 
1643  LOG(VB_GENERAL, LOG_NOTICE, LOC +
1644  "Event socket closed. No connection to the backend.");
1645 
1646  dispatch(MythEvent("BACKEND_SOCKETS_CLOSED"));
1647 }
1648 
1650  bool error_dialog_desired)
1651 {
1652  if (!socket)
1653  return false;
1654 
1655  QStringList strlist(QString("MYTH_PROTO_VERSION %1 %2")
1657  .arg(QString::fromUtf8(MYTH_PROTO_TOKEN)));
1658  socket->WriteStringList(strlist);
1659 
1660  if (!socket->ReadStringList(strlist, timeout_ms) || strlist.empty())
1661  {
1662  LOG(VB_GENERAL, LOG_CRIT, "Protocol version check failure.\n\t\t\t"
1663  "The response to MYTH_PROTO_VERSION was empty.\n\t\t\t"
1664  "This happens when the backend is too busy to respond,\n\t\t\t"
1665  "or has deadlocked due to bugs or hardware failure.");
1666 
1667  return false;
1668  }
1669  if (strlist[0] == "REJECT" && strlist.size() >= 2)
1670  {
1671  LOG(VB_GENERAL, LOG_CRIT, LOC + QString("Protocol version or token mismatch "
1672  "(frontend=%1/%2,backend=%3/\?\?)\n")
1674  .arg(QString::fromUtf8(MYTH_PROTO_TOKEN))
1675  .arg(strlist[1]));
1676 
1677  if (error_dialog_desired && d->m_guiContext)
1678  {
1679  QStringList list(strlist[1]);
1680  QCoreApplication::postEvent(
1681  d->m_guiContext, new MythEvent("VERSION_MISMATCH", list));
1682  }
1683 
1684  return false;
1685  }
1686  if (strlist[0] == "ACCEPT")
1687  {
1688  if (!d->m_announcedProtocol)
1689  {
1690  d->m_announcedProtocol = true;
1691  LOG(VB_GENERAL, LOG_INFO, LOC +
1692  QString("Using protocol version %1 %2")
1694  .arg(QString::fromUtf8(MYTH_PROTO_TOKEN)));
1695  }
1696 
1697  return true;
1698  }
1699 
1700  LOG(VB_GENERAL, LOG_ERR, LOC +
1701  QString("Unexpected response to MYTH_PROTO_VERSION: %1")
1702  .arg(strlist[0]));
1703  return false;
1704 }
1705 
1707 {
1708  LOG(VB_NETWORK, LOG_INFO, LOC + QString("MythEvent: %1").arg(event.Message()));
1709 
1710  MythObservable::dispatch(event);
1711 }
1712 
1714 {
1715  QMutexLocker locker(&d->m_localHostLock);
1717  d->m_database->SetLocalHostname(hostname);
1718 }
1719 
1721 {
1722  d->m_guiObject = gui;
1723 }
1724 
1725 bool MythCoreContext::HasGUI(void) const
1726 {
1727  return d->m_guiObject;
1728 }
1729 
1731 {
1732  return d->m_guiObject;
1733 }
1734 
1736 {
1737  return d->m_guiContext;
1738 }
1739 
1741 {
1742  return d->m_database;
1743 }
1744 
1746 {
1747  return d->m_locale;
1748 }
1749 
1755 {
1756  return GetLanguageAndVariant().left(2);
1757 }
1758 
1767 {
1768  if (d->m_language.isEmpty())
1769  d->m_language = GetSetting("Language", "en_US").toLower();
1770 
1771  return d->m_language;
1772 }
1773 
1775 {
1776  d->m_language.clear();
1777 }
1778 
1780 {
1781  QMutexLocker locker(&d->m_sockLock);
1782  LOG(VB_GENERAL, LOG_INFO, "Restarting Backend Connections");
1783  if (d->m_serverSock)
1785  if (d->m_eventSock)
1787  dispatch(MythEvent("BACKEND_SOCKETS_CLOSED"));
1788 }
1789 
1791 {
1792  if (Create && !d->m_power)
1793  {
1795  }
1796  else if (!Create && d->m_power)
1797  {
1798  MythPower::AcquireRelease(d, false);
1799  d->m_power = nullptr;
1800  }
1801 }
1802 
1804 {
1805  if (!d->m_locale)
1806  d->m_locale = new MythLocale();
1807 
1808  QString localeCode = d->m_locale->GetLocaleCode();
1809  LOG(VB_GENERAL, LOG_NOTICE, QString("Setting QT default locale to %1")
1810  .arg(localeCode));
1811  QLocale::setDefault(d->m_locale->ToQLocale());
1812 }
1813 
1815 {
1816  if (!d->m_locale)
1817  d->m_locale = new MythLocale();
1818  else
1819  d->m_locale->ReInit();
1820 
1821  QString localeCode = d->m_locale->GetLocaleCode();
1822  LOG(VB_GENERAL, LOG_NOTICE, QString("Setting QT default locale to %1")
1823  .arg(localeCode));
1824  QLocale::setDefault(d->m_locale->ToQLocale());
1825 }
1826 
1828 {
1829  if (!d->m_locale)
1830  InitLocale();
1831 
1832  return d->m_locale->ToQLocale();
1833 }
1834 
1836 {
1837  if (!d->m_locale)
1838  InitLocale();
1839 
1840  if (!d->m_locale->GetLocaleCode().isEmpty())
1841  {
1842  LOG(VB_GENERAL, LOG_INFO,
1843  QString("Current locale %1") .arg(d->m_locale->GetLocaleCode()));
1844 
1846  return;
1847  }
1848 
1849  LOG(VB_GENERAL, LOG_ERR, LOC +
1850  "No locale defined! We weren't able to set locale defaults.");
1851 }
1852 
1854 {
1855  d->m_scheduler = sched;
1856 }
1857 
1859 {
1860  return d->m_scheduler;
1861 }
1862 
1868 void MythCoreContext::WaitUntilSignals(const char *signal1, ...)
1869 {
1870  if (!signal1)
1871  return;
1872 
1873  QEventLoop eventLoop;
1874  va_list vl;
1875 
1876  LOG(VB_GENERAL, LOG_DEBUG, LOC +
1877  QString("Waiting for signal %1")
1878  .arg(signal1));
1879  connect(this, signal1, &eventLoop, SLOT(quit()));
1880 
1881  va_start(vl, signal1);
1882  const char *s = va_arg(vl, const char *);
1883  while (s)
1884  {
1885  LOG(VB_GENERAL, LOG_DEBUG, LOC +
1886  QString("Waiting for signal %1")
1887  .arg(s));
1888  connect(this, s, &eventLoop, SLOT(quit()));
1889  s = va_arg(vl, const char *);
1890  }
1891  va_end(vl);
1892 
1893  eventLoop.exec(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers);
1894 }
1895 
1902 void MythCoreContext::RegisterForPlayback(QObject *sender, const char *method)
1903 {
1904  if (!sender || !method)
1905  return;
1906 
1907  QMutexLocker lock(&d->m_playbackLock);
1908 
1909  if (!d->m_playbackClients.contains(sender))
1910  {
1911  d->m_playbackClients.insert(sender, QByteArray(method));
1912  connect(this, SIGNAL(TVPlaybackAboutToStart()),
1913  sender, method,
1914  Qt::BlockingQueuedConnection);
1915  }
1916 }
1917 
1924 {
1925  QMutexLocker lock(&d->m_playbackLock);
1926 
1927  if (d->m_playbackClients.contains(sender))
1928  {
1929  QByteArray ba = d->m_playbackClients.value(sender);
1930  const char *method = ba.constData();
1931  disconnect(this, SIGNAL(TVPlaybackAboutToStart()),
1932  sender, method);
1933  d->m_playbackClients.remove(sender);
1934  }
1935 }
1936 
1944 {
1945  QMutexLocker lock(&d->m_playbackLock);
1946  QByteArray ba;
1947  const char *method = nullptr;
1948  d->m_inwanting = true;
1949 
1950  // If any registered client are in the same thread, they will deadlock, so rebuild
1951  // connections for any clients in the same thread as non-blocking connection
1952  QThread *currentThread = QThread::currentThread();
1953 
1954  QMap<QObject *, QByteArray>::iterator it = d->m_playbackClients.begin();
1955  for (; it != d->m_playbackClients.end(); ++it)
1956  {
1957  if (it.key() == sender)
1958  continue; // will be done separately, no need to do it again
1959 
1960  QThread *thread = it.key()->thread();
1961 
1962  if (thread != currentThread)
1963  continue;
1964 
1965  disconnect(this, SIGNAL(TVPlaybackAboutToStart()), it.key(), it.value());
1966  connect(this, SIGNAL(TVPlaybackAboutToStart()), it.key(), it.value());
1967  }
1968 
1969  // disconnect sender so it won't receive the message
1970  if (d->m_playbackClients.contains(sender))
1971  {
1972  ba = d->m_playbackClients.value(sender);
1973  method = ba.constData();
1974  disconnect(this, SIGNAL(TVPlaybackAboutToStart()), sender, method);
1975  }
1976 
1977  // emit signal
1978  emit TVPlaybackAboutToStart();
1979 
1980  // reconnect sender
1981  if (method)
1982  {
1983  connect(this, SIGNAL(TVPlaybackAboutToStart()),
1984  sender, method,
1985  Qt::BlockingQueuedConnection);
1986  }
1987  // Restore blocking connections
1988  for (; it != d->m_playbackClients.end(); ++it)
1989  {
1990  if (it.key() == sender)
1991  continue; // already done above, no need to do it again
1992 
1993  QThread *thread = it.key()->thread();
1994 
1995  if (thread != currentThread)
1996  continue;
1997 
1998  disconnect(this, SIGNAL(TVPlaybackAboutToStart()), it.key(), it.value());
1999  connect(this, SIGNAL(TVPlaybackAboutToStart()),
2000  it.key(), it.value(), Qt::BlockingQueuedConnection);
2001  }
2002  d->m_inwanting = false;
2003 }
2004 
2011 {
2012  // when called, it will be while the m_playbackLock is held
2013  // following a call to WantingPlayback
2014  d->m_intvwanting = b;
2015 }
2016 
2023 {
2024  bool locked = d->m_playbackLock.tryLock();
2025  bool intvplayback = d->m_intvwanting;
2026 
2027  if (!locked && d->m_inwanting)
2028  return true; // we're in the middle of WantingPlayback
2029 
2030  if (!locked)
2031  return false;
2032 
2033  d->m_playbackLock.unlock();
2034 
2035  return intvplayback;
2036 }
2037 
2039 {
2040  if (!d->m_sessionManager)
2042 
2043  return d->m_sessionManager;
2044 }
2045 
2046 bool MythCoreContext::TestPluginVersion(const QString &name,
2047  const QString &libversion,
2048  const QString &pluginversion)
2049 {
2050  if (libversion == pluginversion)
2051  return true;
2052 
2053  LOG(VB_GENERAL, LOG_EMERG, LOC +
2054  QString("Plugin %1 (%2) binary version does not "
2055  "match libraries (%3)")
2056  .arg(name).arg(pluginversion).arg(libversion));
2057  return false;
2058 }
2059 
2061 {
2062  if (d->m_pluginmanager == pmanager)
2063  return;
2064 
2065  if (d->m_pluginmanager)
2066  {
2067  delete d->m_pluginmanager;
2068  d->m_pluginmanager = nullptr;
2069  }
2070 
2071  d->m_pluginmanager = pmanager;
2072 }
2073 
2075 {
2076  return d->m_pluginmanager;
2077 }
2078 
2080 {
2081  d->m_isexiting = exiting;
2082 }
2083 
2085 {
2086  return d->m_isexiting;
2087 }
2088 
2089 void MythCoreContext::RegisterFileForWrite(const QString& file, uint64_t size)
2090 {
2091  QMutexLocker lock(&d->m_fileslock);
2092 
2093  QPair<int64_t, uint64_t> pair(QDateTime::currentMSecsSinceEpoch(), size);
2094  d->m_fileswritten.insert(file, pair);
2095 
2096  if (IsBackend())
2097  {
2098  QString message = QString("FILE_WRITTEN %1 %2").arg(file).arg(size);
2099  MythEvent me(message);
2100  dispatch(me);
2101  }
2102 
2103  LOG(VB_FILE, LOG_DEBUG, LOC +
2104  QString("%1").arg(file));
2105 }
2106 
2108 {
2109  QMutexLocker lock(&d->m_fileslock);
2110 
2111  d->m_fileswritten.remove(file);
2112 
2113  if (IsBackend())
2114  {
2115  QString message = QString("FILE_CLOSED %1").arg(file);
2116  MythEvent me(message);
2117  dispatch(me);
2118  }
2119 
2120  LOG(VB_FILE, LOG_DEBUG, LOC +
2121  QString("%1").arg(file));
2122 }
2123 
2125 {
2126  QMutexLocker lock(&d->m_fileslock);
2127 
2128  return d->m_fileswritten.contains(file);
2129 }
2130 
2131 /* vim: set expandtab tabstop=4 shiftwidth=4: */
MythCoreContext::resolveSettingAddress
QString resolveSettingAddress(const QString &name, const QString &host=QString(), ResolveType type=ResolveAny, bool keepscope=false)
Retrieve IP setting "name" for "host".
Definition: mythcorecontext.cpp:1142
MythCoreContext::SetPluginManager
void SetPluginManager(MythPluginManager *pmanager)
Definition: mythcorecontext.cpp:2060
loggingDeregisterThread
void loggingDeregisterThread(void)
Deregister the current thread's name.
Definition: logging.cpp:789
MythCoreContext::SetWOLAllowed
void SetWOLAllowed(bool allow)
Definition: mythcorecontext.cpp:632
build_compdb.args
args
Definition: build_compdb.py:11
DestroyMythDB
void DestroyMythDB(void)
Definition: mythdb.cpp:51
MythLocale::ReInit
void ReInit()
Definition: mythlocale.cpp:53
MythCoreContext::SendMessage
void SendMessage(const QString &message)
Definition: mythcorecontext.cpp:1499
myth_system
uint myth_system(const QString &command, uint flags, uint timeout)
Definition: mythsystemlegacy.cpp:501
hardwareprofile.smolt.timeout
float timeout
Definition: smolt.py:103
MythCoreContext::GetMasterHostName
QString GetMasterHostName(void)
Definition: mythcorecontext.cpp:810
GENERIC_EXIT_OK
#define GENERIC_EXIT_OK
Exited with no error.
Definition: exitcodes.h:10
MythPower
Definition: mythpower.h:18
MythPluginManager
Definition: mythplugin.h:62
MythCoreContextPrivate::m_fileswritten
QMap< QString, QPair< int64_t, uint64_t > > m_fileswritten
Definition: mythcorecontext.cpp:115
ReferenceCounter::DecrRef
virtual int DecrRef(void)
Decrements reference count and deletes on 0.
Definition: referencecounter.cpp:125
MYTH_PROTO_TOKEN
#define MYTH_PROTO_TOKEN
Definition: mythversion.h:49
MythScheduler
This is an generic interface to a program scheduler.
Definition: mythscheduler.h:20
kMSDontBlockInputDevs
@ kMSDontBlockInputDevs
avoid blocking LIRC & Joystick Menu
Definition: mythsystem.h:34
MythCoreContext::GetScheduler
MythScheduler * GetScheduler(void)
Definition: mythcorecontext.cpp:1858
MythSocket::SendReceiveStringList
bool SendReceiveStringList(QStringList &list, uint min_reply_length=0, uint timeoutMS=kLongTimeout)
Definition: mythsocket.cpp:336
false
VERBOSE_PREAMBLE false
Definition: verbosedefs.h:85
MythCoreContext::SendReceiveStringList
bool SendReceiveStringList(QStringList &strlist, bool quickTimeout=false, bool block=true)
Send a message to the backend and wait for a response.
Definition: mythcorecontext.cpp:1352
MythCoreContext::IsBlockingClient
bool IsBlockingClient(void) const
is this client blocking shutdown
Definition: mythcorecontext.cpp:627
MythCoreContext::IsFrontendOnly
bool IsFrontendOnly(void)
is there a frontend, but no backend, running on this host
Definition: mythcorecontext.cpp:748
MythCoreContext::AllowShutdown
void AllowShutdown(void)
Definition: mythcorecontext.cpp:613
MythCoreContextPrivate::m_masterHostLock
QMutex m_masterHostLock
Locking for m_masterHostname.
Definition: mythcorecontext.cpp:76
MythCoreContext::ResetSockets
void ResetSockets(void)
Definition: mythcorecontext.cpp:1779
MythLocale
Definition: mythlocale.h:12
MythCoreContext::GetDBManager
MDBManager * GetDBManager(void)
Definition: mythcorecontext.cpp:868
MythCoreContext::UnregisterFileForWrite
void UnregisterFileForWrite(const QString &file)
Definition: mythcorecontext.cpp:2107
MythCoreContext::ConnectToMasterServer
bool ConnectToMasterServer(bool blockingClient=true, bool openEventSocket=true)
Definition: mythcorecontext.cpp:359
MythCoreContextPrivate::m_eventSock
MythSocket * m_eventSock
socket events arrive on
Definition: mythcorecontext.cpp:83
MythCoreContext::GetLocale
MythLocale * GetLocale(void) const
Definition: mythcorecontext.cpp:1745
MythCoreContextPrivate::m_playbackClients
QMap< QObject *, QByteArray > m_playbackClients
Definition: mythcorecontext.cpp:104
MythCoreContext::~MythCoreContext
~MythCoreContext() override
Definition: mythcorecontext.cpp:296
mythplugin.h
MythCoreContext::InitLocale
void InitLocale(void)
Definition: mythcorecontext.cpp:1803
ShutdownMythDownloadManager
void ShutdownMythDownloadManager(void)
Deletes the running MythDownloadManager at program exit.
Definition: mythdownloadmanager.cpp:149
MythCoreContext::SetScheduler
void SetScheduler(MythScheduler *sched)
Definition: mythcorecontext.cpp:1853
MythCoreContext::GetBackendStatusPort
int GetBackendStatusPort(void)
Returns the locally defined backend status port.
Definition: mythcorecontext.cpp:1071
MythCoreContext::OverrideSettingForSession
void OverrideSettingForSession(const QString &key, const QString &value)
Definition: mythcorecontext.cpp:1318
MDBManager
DB connection pool, used by MSqlQuery. Do not use directly.
Definition: mythdbcon.h:53
MythCoreContextPrivate::m_backend
bool m_backend
Definition: mythcorecontext.cpp:90
MythLocale::ToQLocale
QLocale ToQLocale() const
Definition: mythlocale.h:30
MythEvent
This class is used as a container for messages.
Definition: mythevent.h:16
MYTH_APPNAME_MYTHTV_SETUP
#define MYTH_APPNAME_MYTHTV_SETUP
Definition: mythcorecontext.h:19
MythCoreContextPrivate::m_appBinaryVersion
QString m_appBinaryVersion
Definition: mythcorecontext.cpp:72
srandom
static void srandom(unsigned int)
Definition: compat.h:148
MythCoreContext::RegisterFileForWrite
void RegisterFileForWrite(const QString &file, uint64_t size=0LL)
Definition: mythcorecontext.cpp:2089
MythCoreContext::IsDatabaseIgnored
bool IsDatabaseIgnored(void) const
/brief Returns true if database is being ignored.
Definition: mythcorecontext.cpp:879
arg
arg(title).arg(filename).arg(doDelete))
MythCoreContext::GetGUIObject
QObject * GetGUIObject(void)
Definition: mythcorecontext.cpp:1730
MythCoreContext::GetFilePrefix
QString GetFilePrefix(void)
Definition: mythcorecontext.cpp:847
MythCoreContext::IsUIThread
bool IsUIThread(void)
Definition: mythcorecontext.cpp:1329
MythCoreContext::connectionClosed
void connectionClosed(MythSocket *sock) override
Definition: mythcorecontext.cpp:1639
MythSocket::DisconnectFromHost
void DisconnectFromHost(void)
Definition: mythsocket.cpp:508
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
is_current_thread
bool is_current_thread(MThread *thread)
Use this to determine if you are in the named thread.
Definition: mthread.cpp:41
MythCoreContextPrivate::m_blockingClient
bool m_blockingClient
Definition: mythcorecontext.cpp:102
GetMythDB
MythDB * GetMythDB(void)
Definition: mythdb.cpp:46
MythCoreContext::TestPluginVersion
static bool TestPluginVersion(const QString &name, const QString &libversion, const QString &pluginversion)
Definition: mythcorecontext.cpp:2046
build_compdb.file
file
Definition: build_compdb.py:55
MythCoreContextPrivate::m_intvwanting
bool m_intvwanting
Definition: mythcorecontext.cpp:107
MythObservable::dispatch
void dispatch(const MythEvent &event)
Dispatch an event to all listeners.
Definition: mythobservable.cpp:73
MythCoreContext::GetScopeForAddress
bool GetScopeForAddress(QHostAddress &addr) const
Return the cached scope Id for the given address.
Definition: mythcorecontext.cpp:1088
MythSocket::ConnectToHost
bool ConnectToHost(const QString &hostname, quint16 port)
connect to host
Definition: mythsocket.cpp:384
MythCoreContext::InitPower
void InitPower(bool Create=true)
Definition: mythcorecontext.cpp:1790
MythCoreContext::SafeConnectToMasterServer
bool SafeConnectToMasterServer(bool blockingClient=true, bool openEventSocket=true)
Definition: mythcorecontext.cpp:348
hardwareprofile.distros.mythtv_data.data_mythtv.prefix
string prefix
Definition: data_mythtv.py:40
MythDate::current
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:10
MythEvent::Message
const QString & Message() const
Definition: mythevent.h:65
MythSocket::IsConnected
bool IsConnected(void) const
Definition: mythsocket.cpp:561
MythCoreContextPrivate::m_wolInProgressWaitCondition
QWaitCondition m_wolInProgressWaitCondition
Definition: mythcorecontext.cpp:86
true
VERBOSE_PREAMBLE Most true
Definition: verbosedefs.h:91
MythCoreContextPrivate::m_database
MythDB * m_database
Definition: mythcorecontext.cpp:93
MythCoreContext::GetMasterServerStatusPort
int GetMasterServerStatusPort(void)
Returns the Master Backend status port If no master server status port has been defined in the databa...
Definition: mythcorecontext.cpp:984
tmp
static guint32 * tmp
Definition: goom_core.cpp:30
MythCoreContextPrivate::m_scopesLock
QMutex m_scopesLock
Locking for m_masterHostname.
Definition: mythcorecontext.cpp:78
mythversion.h
mythsystemlegacy.h
SendAsyncMessage::SendAsyncMessage
SendAsyncMessage(QString msg, QStringList extra)
Definition: mythcorecontext.cpp:1479
MythCoreContext::SendHostSystemEvent
void SendHostSystemEvent(const QString &msg, const QString &hostname, const QString &args)
Definition: mythcorecontext.cpp:1535
MythCoreContextPrivate::m_pluginmanager
MythPluginManager * m_pluginmanager
Definition: mythcorecontext.cpp:111
LOC
#define LOC
Definition: mythcorecontext.cpp:55
MythSocket
Class for communcating between myth backends and frontends.
Definition: mythsocket.h:26
MythCoreContext::ClearOverrideSettingForSession
void ClearOverrideSettingForSession(const QString &key)
Definition: mythcorecontext.cpp:1324
MythCoreContext::IsConnectedToMaster
bool IsConnectedToMaster(void)
Definition: mythcorecontext.cpp:593
MythCoreContext::MythCoreContext
MythCoreContext(const QString &binversion, QObject *guiContext)
Definition: mythcorecontext.cpp:231
quit
@ quit
Definition: lirc_client.h:30
MThreadPool::ShutdownAllPools
static void ShutdownAllPools(void)
Definition: mthreadpool.cpp:326
MythCoreContext::UnregisterForPlayback
void UnregisterForPlayback(QObject *sender)
Definition: mythcorecontext.cpp:1923
MythCoreContext::IsRegisteredFileForWrite
bool IsRegisteredFileForWrite(const QString &file)
Definition: mythcorecontext.cpp:2124
MythWakeup
bool MythWakeup(const QString &wakeUpCommand, uint flags, uint timeout)
Definition: mythmiscutil.cpp:675
MythCoreContext::IsMasterBackend
bool IsMasterBackend(void)
is this the actual MBE process
Definition: mythcorecontext.cpp:698
MythCoreContextPrivate::m_playbackLock
QMutex m_playbackLock
Definition: mythcorecontext.cpp:105
mythdate.h
MythCoreContextPrivate::m_localHostname
QString m_localHostname
hostname from config.xml or gethostname()
Definition: mythcorecontext.cpp:75
MythCoreContextPrivate::m_isWOLAllowed
bool m_isWOLAllowed
Definition: mythcorecontext.cpp:88
mythlogging.h
MythCoreContext::Init
bool Init(void)
Definition: mythcorecontext.cpp:237
MythCoreContext::GenMythURL
static QString GenMythURL(const QString &host=QString(), int port=0, QString path=QString(), const QString &storageGroup=QString())
Definition: mythcorecontext.cpp:763
MythCoreContext::GetGUIContext
QObject * GetGUIContext(void)
Definition: mythcorecontext.cpp:1735
MythCoreContext::GetQLocale
QLocale GetQLocale(void)
Definition: mythcorecontext.cpp:1827
MythCoreContext::BackendIsRunning
static bool BackendIsRunning(void)
a backend process is running on this host
Definition: mythcorecontext.cpp:703
MythSocket::WriteStringList
bool WriteStringList(const QStringList &list)
Definition: mythsocket.cpp:311
MythCoreContext::SetAsFrontend
void SetAsFrontend(bool frontend)
Definition: mythcorecontext.cpp:652
MThreadPool::StopAllPools
static void StopAllPools(void)
Definition: mthreadpool.cpp:315
MythSocket::kShortTimeout
static const uint kShortTimeout
Definition: mythsocket.h:71
MythCoreContext::GetBackendServerPort
int GetBackendServerPort(void)
Returns the locally defined backend control port.
Definition: mythcorecontext.cpp:1055
MythCoreContext::SendSystemEvent
void SendSystemEvent(const QString &msg)
Definition: mythcorecontext.cpp:1526
MythCoreContextPrivate::m_isexiting
bool m_isexiting
Definition: mythcorecontext.cpp:113
MythCoreContext::SendEvent
void SendEvent(const MythEvent &event)
Definition: mythcorecontext.cpp:1512
MythCoreContext::GetMasterServerIP
QString GetMasterServerIP(void)
Returns the Master Backend IP address If the address is an IPv6 address, the scope Id is removed.
Definition: mythcorecontext.cpp:957
MythCoreContextPrivate::m_parent
MythCoreContext * m_parent
Definition: mythcorecontext.cpp:69
hardwareprofile.i18n.t
t
Definition: i18n.py:36
MythCoreContextPrivate::m_frontend
bool m_frontend
Definition: mythcorecontext.cpp:91
compat.h
MythCoreContext::GetBackendServerIP
QString GetBackendServerIP(void)
Returns the IP address of the locally defined backend IP.
Definition: mythcorecontext.cpp:995
MythCoreContextPrivate::WaitForWOL
bool WaitForWOL(int timeout_in_ms=INT_MAX)
If another thread has already started WOL process, wait on them...
Definition: mythcorecontext.cpp:215
MythCoreContext::WaitUntilSignals
void WaitUntilSignals(const char *signal1,...)
Definition: mythcorecontext.cpp:1868
MythCoreContextPrivate::m_sessionManager
MythSessionManager * m_sessionManager
Definition: mythcorecontext.cpp:118
MythCoreContext::IsFrontend
bool IsFrontend(void) const
is this process a frontend process
Definition: mythcorecontext.cpp:657
MythCoreContext::SetupCommandSocket
bool SetupCommandSocket(MythSocket *serverSock, const QString &announcement, uint timeout_in_ms, bool &proto_mismatch)
Definition: mythcorecontext.cpp:302
MythCoreContextPrivate::m_guiObject
QObject * m_guiObject
Definition: mythcorecontext.cpp:71
MythCoreContext::GetDB
MythDB * GetDB(void)
Definition: mythcorecontext.cpp:1740
MythCoreContext::readyRead
void readyRead(MythSocket *sock) override
Definition: mythcorecontext.cpp:1543
MythCoreContext::GetNumSettingOnHost
int GetNumSettingOnHost(const QString &key, const QString &host, int defaultval=0)
Definition: mythcorecontext.cpp:938
MythCoreContextPrivate::m_approvedIps
QList< QHostAddress > m_approvedIps
Definition: mythcorecontext.cpp:120
MythCoreContextPrivate::m_wolInProgressLock
QMutex m_wolInProgressLock
Definition: mythcorecontext.cpp:85
MythCoreContext::GetResolutionSetting
void GetResolutionSetting(const QString &type, int &width, int &height, double &forced_aspect, double &refresh_rate, int index=-1)
Definition: mythcorecontext.cpp:852
MythCoreContext::RegisterForPlayback
void RegisterForPlayback(QObject *sender, const char *method)
Definition: mythcorecontext.cpp:1902
MythCoreContext::GetBackendServerIP4
QString GetBackendServerIP4(void)
Returns the IPv4 address defined for the current host see GetBackendServerIP4(host)
Definition: mythcorecontext.cpp:1018
SendAsyncMessage::m_message
QString m_message
Definition: mythcorecontext.cpp:1495
MythCoreContext::TVPlaybackAboutToStart
void TVPlaybackAboutToStart(void)
SendAsyncMessage
Definition: mythcorecontext.cpp:1476
uint
unsigned int uint
Definition: compat.h:140
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:57
SendAsyncMessage::m_extraData
QStringList m_extraData
Definition: mythcorecontext.cpp:1496
MythCoreContextPrivate::~MythCoreContextPrivate
~MythCoreContextPrivate() override
Definition: mythcorecontext.cpp:171
MythCoreContext::ConnectEventSocket
MythSocket * ConnectEventSocket(const QString &hostname, int port)
Definition: mythcorecontext.cpp:548
MythCoreContext::GetLanguage
QString GetLanguage(void)
Returns two character ISO-639 language descriptor for UI language.
Definition: mythcorecontext.cpp:1754
MythCoreContext::GetNumSetting
int GetNumSetting(const QString &key, int defaultval=0)
Definition: mythcorecontext.cpp:913
logStop
void logStop(void)
Entry point for stopping logging for an application.
Definition: logging.cpp:755
MythLocale::SaveLocaleDefaults
void SaveLocaleDefaults(bool overwrite=false)
Definition: mythlocale.cpp:172
MythCoreContext::ResolveIPv6
@ ResolveIPv6
Definition: mythcorecontext.h:191
MythCoreContext::resolveAddress
static QString resolveAddress(const QString &host, ResolveType type=ResolveAny, bool keepscope=false)
if host is an IP address, it will be returned or resolved otherwise.
Definition: mythcorecontext.cpp:1171
MythCoreContext::SetLocalHostname
void SetLocalHostname(const QString &hostname)
Definition: mythcorecontext.cpp:1713
MythCoreContextPrivate::m_locale
MythLocale * m_locale
Definition: mythcorecontext.cpp:97
SendAsyncMessage::run
void run(void) override
Definition: mythcorecontext.cpp:1486
MythCoreContext::GetBoolSetting
bool GetBoolSetting(const QString &key, bool defaultval=false)
Definition: mythcorecontext.cpp:907
mthreadpool.h
MythEvent::ExtraDataList
const QStringList & ExtraDataList() const
Definition: mythevent.h:67
MYTH_BINARY_VERSION
#define MYTH_BINARY_VERSION
Update this whenever the plug-in ABI changes.
Definition: mythversion.h:16
MythCoreContext::GetMasterServerPort
static int GetMasterServerPort(void)
Returns the Master Backend control port If no master server port has been defined in the database,...
Definition: mythcorecontext.cpp:971
sched
Scheduler * sched
MYTH_PROTO_VERSION
#define MYTH_PROTO_VERSION
Increment this whenever the MythTV network protocol changes.
Definition: mythversion.h:48
MythCoreContext::InWantingPlayback
bool InWantingPlayback(void)
Returns true if a client has requested playback.
Definition: mythcorecontext.cpp:2022
MythCoreContext::CheckProtoVersion
bool CheckProtoVersion(MythSocket *socket, uint timeout_ms=kMythSocketLongTimeout, bool error_dialog_desired=false)
Definition: mythcorecontext.cpp:1649
MythPower::AcquireRelease
static MythPower * AcquireRelease(void *Reference, bool Acquire, uint MinimumDelay=0)
Definition: mythpower.cpp:70
MythCoreContext::ResolveIPv4
@ ResolveIPv4
Definition: mythcorecontext.h:191
MythCoreContext
This class contains the runtime context for MythTV.
Definition: mythcorecontext.h:52
mythmiscutil.h
MythCoreContext::ConnectCommandSocket
MythSocket * ConnectCommandSocket(const QString &hostname, int port, const QString &announcement, bool *proto_mismatch=nullptr, int maxConnTry=-1, int setup_timeout=-1)
Definition: mythcorecontext.cpp:430
mythcorecontext.h
MythCoreContextPrivate::m_announcedProtocol
bool m_announcedProtocol
Definition: mythcorecontext.cpp:109
MythCoreContext::IsBackend
bool IsBackend(void) const
is this process a backend process
Definition: mythcorecontext.cpp:647
kLinkLocal
static QPair< QHostAddress, int > kLinkLocal
Definition: serverpool.cpp:24
MythCoreContextPrivate::m_masterHostname
QString m_masterHostname
master backend hostname
Definition: mythcorecontext.cpp:77
MythCoreContext::ResetLanguage
void ResetLanguage(void)
Definition: mythcorecontext.cpp:1774
MythCoreContext::GetSettingOnHost
QString GetSettingOnHost(const QString &key, const QString &host, const QString &defaultval="")
Definition: mythcorecontext.cpp:923
MythCoreContextPrivate::m_scopes
QMap< QString, QString > m_scopes
Scope Id cache for Link-Local addresses.
Definition: mythcorecontext.cpp:79
kMSProcessEvents
@ kMSProcessEvents
process events while waiting
Definition: mythsystem.h:37
MythCoreContext::GetLanguageAndVariant
QString GetLanguageAndVariant(void)
Returns the user-set language and variant.
Definition: mythcorecontext.cpp:1766
MythCoreContextPrivate::m_serverSock
MythSocket * m_serverSock
socket for sending MythProto requests
Definition: mythcorecontext.cpp:82
serverpool.h
MythCoreContextPrivate::m_wolInProgress
bool m_wolInProgress
Definition: mythcorecontext.cpp:87
MythSocket::IsDataAvailable
bool IsDataAvailable(void)
Definition: mythsocket.cpp:567
MythCoreContextPrivate::m_inwanting
bool m_inwanting
Definition: mythcorecontext.cpp:106
logging.h
MythSocket::kLongTimeout
static const uint kLongTimeout
Definition: mythsocket.h:72
mthread.h
delete_sock
static void delete_sock(QMutexLocker &locker, MythSocket **s)
Definition: mythcorecontext.cpp:159
MythCoreContext::TVInWantingPlayback
void TVInWantingPlayback(bool b)
Let the TV class tell us if we was interrupted following a call to WantingPlayback().
Definition: mythcorecontext.cpp:2010
MythCoreContext::d
MythCoreContextPrivate * d
Definition: mythcorecontext.h:268
MythCoreContextPrivate::m_uiThread
QThread * m_uiThread
Definition: mythcorecontext.cpp:95
SendAsyncMessage::SendAsyncMessage
SendAsyncMessage(QString msg)
Definition: mythcorecontext.cpp:1484
MythCoreContext::ActivateSettingsCache
void ActivateSettingsCache(bool activate=true)
Definition: mythcorecontext.cpp:836
MThread::Cleanup
static void Cleanup(void)
This will print out all the running threads, call exit(1) on each and then wait up to 5 seconds total...
Definition: mthread.cpp:145
MythCoreContext::ResolveType
ResolveType
Definition: mythcorecontext.h:191
MythCoreContextPrivate::m_sockLock
QMutex m_sockLock
protects both m_serverSock and m_eventSock
Definition: mythcorecontext.cpp:81
MythLocale::GetLocaleCode
QString GetLocaleCode() const
Name of language in that language.
Definition: mythlocale.h:28
MythCoreContext::WantingPlayback
void WantingPlayback(QObject *sender)
All the objects that have registered using MythCoreContext::RegisterForPlayback but sender will be ca...
Definition: mythcorecontext.cpp:1943
ShutdownMythSystemLegacy
void MBASE_PUBLIC ShutdownMythSystemLegacy(void)
Definition: mythsystemunix.cpp:66
MythCoreContext::GetHostName
QString GetHostName(void)
Definition: mythcorecontext.cpp:841
MythCoreContextPrivate::m_scheduler
MythScheduler * m_scheduler
Definition: mythcorecontext.cpp:100
MythCoreContext::ReInitLocale
void ReInitLocale(void)
Definition: mythcorecontext.cpp:1814
MThread::ThreadSetup
static void ThreadSetup(const QString &name)
This is to be called on startup in those few threads that haven't been ported to MThread.
Definition: mthread.cpp:227
MythCoreContextPrivate::m_deniedIps
QList< QHostAddress > m_deniedIps
Definition: mythcorecontext.cpp:121
MythCoreContext::IsExiting
bool IsExiting(void)
Definition: mythcorecontext.cpp:2084
MythCoreContext::GetBoolSettingOnHost
bool GetBoolSettingOnHost(const QString &key, const QString &host, bool defaultval=false)
Definition: mythcorecontext.cpp:930
MythCoreContext::ClearSettingsCache
void ClearSettingsCache(const QString &myKey=QString(""))
Definition: mythcorecontext.cpp:831
MythCoreContext::IsThisHost
bool IsThisHost(const QString &addr)
is this address mapped to this host
Definition: mythcorecontext.cpp:724
MythCoreContext::HasGUI
bool HasGUI(void) const
Definition: mythcorecontext.cpp:1725
MythCoreContext::IsMasterHost
bool IsMasterHost(void)
is this the same host as the master
Definition: mythcorecontext.cpp:662
MythCoreContextPrivate::m_localHostLock
QMutex m_localHostLock
Locking for m_localHostname.
Definition: mythcorecontext.cpp:74
musicbrainzngs.caa.hostname
string hostname
Definition: caa.py:17
mythpower.h
MythCoreContext::BlockShutdown
void BlockShutdown(void)
Definition: mythcorecontext.cpp:599
MythCoreContext::IsWOLAllowed
bool IsWOLAllowed() const
Definition: mythcorecontext.cpp:637
MythCoreContext::GetFloatSetting
double GetFloatSetting(const QString &key, double defaultval=0.0)
Definition: mythcorecontext.cpp:918
kMSDontDisableDrawing
@ kMSDontDisableDrawing
avoid disabling UI drawing
Definition: mythsystem.h:35
MythCoreContextPrivate::m_fileslock
QMutex m_fileslock
Definition: mythcorecontext.cpp:116
MythCoreContext::SaveSetting
void SaveSetting(const QString &key, int newValue)
Definition: mythcorecontext.cpp:884
MythCoreContext::GetMasterHostPrefix
QString GetMasterHostPrefix(const QString &storageGroup=QString(), const QString &path=QString())
Definition: mythcorecontext.cpp:801
MythCoreContext::GetSessionManager
MythSessionManager * GetSessionManager(void)
Definition: mythcorecontext.cpp:2038
exitcodes.h
mythdownloadmanager.h
MythSocket::ReadStringList
bool ReadStringList(QStringList &list, uint timeoutMS=kShortTimeout)
Definition: mythsocket.cpp:323
MythCoreContext::GetBackendServerIP6
QString GetBackendServerIP6(void)
Returns the IPv6 address defined for the current host see GetBackendServerIP6(host)
Definition: mythcorecontext.cpp:1037
MThreadPool::globalInstance
static MThreadPool * globalInstance(void)
Definition: mthreadpool.cpp:307
MythCoreContext::GetPluginManager
MythPluginManager * GetPluginManager(void)
Definition: mythcorecontext.cpp:2074
MythCoreContext::SetScopeForAddress
void SetScopeForAddress(const QHostAddress &addr)
Record the scope Id of the given IP address.
Definition: mythcorecontext.cpp:1108
MythCoreContext::CheckSubnet
bool CheckSubnet(const QAbstractSocket *socket)
Check if a socket is connected to an approved peer.
Definition: mythcorecontext.cpp:1247
mythsocket.h
MythCoreContextPrivate::m_guiContext
QObject * m_guiContext
Definition: mythcorecontext.cpp:70
MythCoreContextPrivate
Definition: mythcorecontext.cpp:59
MythCoreContext::SaveLocaleDefaults
void SaveLocaleDefaults(void)
Definition: mythcorecontext.cpp:1835
MythCoreContext::dispatch
void dispatch(const MythEvent &event)
Definition: mythcorecontext.cpp:1706
MythCoreContextPrivate::m_language
QString m_language
Definition: mythcorecontext.cpp:98
MythCoreContext::SaveSettingOnHost
bool SaveSettingOnHost(const QString &key, const QString &newValue, const QString &host)
Definition: mythcorecontext.cpp:894
MythCoreContext::SetAsBackend
void SetAsBackend(bool backend)
Definition: mythcorecontext.cpp:642
MythCoreContext::IsThisBackend
bool IsThisBackend(const QString &addr)
is this address mapped to this backend host
Definition: mythcorecontext.cpp:719
MythCoreContext::GetFloatSettingOnHost
double GetFloatSettingOnHost(const QString &key, const QString &host, double defaultval=0.0)
Definition: mythcorecontext.cpp:945
MThreadPool::start
void start(QRunnable *runnable, const QString &debugName, int priority=0)
Definition: mthreadpool.cpp:342
MythCoreContext::SetExiting
void SetExiting(bool exiting=true)
Definition: mythcorecontext.cpp:2079
MythCoreContext::SetGUIObject
void SetGUIObject(QObject *gui)
Definition: mythcorecontext.cpp:1720
MythCoreContextPrivate::m_power
MythPower * m_power
Definition: mythcorecontext.cpp:123
MythCoreContextPrivate::MythCoreContextPrivate
MythCoreContextPrivate(MythCoreContext *lparent, QString binversion, QObject *guicontext)
Definition: mythcorecontext.cpp:126
MythCoreContext::GetSetting
QString GetSetting(const QString &key, const QString &defaultval="")
Definition: mythcorecontext.cpp:901
MythSessionManager
Definition: mythsession.h:98