MythTV  master
mythcorecontext.cpp
Go to the documentation of this file.
1 #include "mythcorecontext.h"
2 
3 // Qt
4 #include <QtGlobal>
5 #include <QCoreApplication>
6 #include <QUrl>
7 #include <QDir>
8 #include <QFileInfo>
9 #include <QDebug>
10 #include <QMutex>
11 #include <QRunnable>
12 #include <QWaitCondition>
13 #include <QAbstractSocket>
14 #include <QHostAddress>
15 #include <QHostInfo>
16 #include <QNetworkInterface>
17 #include <QNetworkAddressEntry>
18 #include <QLocale>
19 #include <QPair>
20 #include <QRegularExpression>
21 #include <QDateTime>
22 
23 // Std
24 #include <algorithm>
25 #include <cmath>
26 #include <cstdarg>
27 #include <queue>
28 #include <unistd.h> // for usleep()
29 
30 #ifdef _WIN32
31 #include <winsock2.h>
32 #else
33 #include <clocale>
34 #include <utility>
35 #endif
36 
37 // MythTV
38 #include "compat.h"
39 #include "mythappname.h"
40 #include "mythdownloadmanager.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(std::chrono::milliseconds timeout = std::chrono::milliseconds::max());
67 
68  public:
69  MythCoreContext *m_parent { nullptr };
70  QObject *m_guiContext { nullptr };
71  QObject *m_guiObject { nullptr };
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;
82  MythSocket *m_serverSock { nullptr };
83  MythSocket *m_eventSock { nullptr };
84 
87  bool m_wolInProgress { false };
88  bool m_isWOLAllowed { true };
89 
90  bool m_backend { false };
91  bool m_frontend { false };
92 
93  MythDB *m_database { nullptr };
94 
95  QThread *m_uiThread { nullptr };
96 
97  MythLocale *m_locale { nullptr };
98  QString m_language;
99  QString m_audioLanguage;
100 
102 
103  bool m_blockingClient { true };
104 
105  QMap<QObject *, MythCoreContext::PlaybackStartCb> m_playbackClients;
107  bool m_inwanting { false };
108  bool m_intvwanting { false };
109 
110  bool m_announcedProtocol { false };
111 
113 
114  bool m_isexiting { false };
115 
116  QMap<QString, QPair<int64_t, uint64_t> > m_fileswritten;
117  QMutex m_fileslock;
118 
120 
121  QList<QHostAddress> m_approvedIps;
122  QList<QHostAddress> m_deniedIps;
123 
124  MythPower *m_power { nullptr };
125 };
126 
128  QString binversion,
129  QObject *guicontext)
130  : m_parent(lparent),
131  m_guiContext(guicontext),
132  m_appBinaryVersion(std::move(binversion)),
133  m_database(GetMythDB()),
134  m_uiThread(QThread::currentThread())
135 {
136  MThread::ThreadSetup("CoreContext");
137 }
138 
139 static void delete_sock(
140 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
141  QMutexLocker &locker,
142 #else
143  QMutexLocker<QMutex> &locker,
144 #endif
145  MythSocket **s)
146 {
147  if (*s)
148  {
149  MythSocket *tmp = *s;
150  *s = nullptr;
151  locker.unlock();
152  tmp->DecrRef();
153  locker.relock();
154  }
155 }
156 
158 {
159  if (m_power)
160  MythPower::AcquireRelease(this, false);
161 
163 
164  {
165  QMutexLocker locker(&m_sockLock);
166  delete_sock(locker, &m_serverSock);
167  delete_sock(locker, &m_eventSock);
168  }
169 
170  delete m_locale;
171 
172  delete m_sessionManager;
173 
175 
177 
179 
180  // This has already been run in the MythContext dtor. Do we need it here
181  // too?
182 #if 0
183  logStop(); // need to shutdown db logger before we kill db
184 #endif
185 
187 
188  GetMythDB()->GetDBManager()->CloseDatabases();
189 
190  if (m_database) {
191  DestroyMythDB();
192  m_database = nullptr;
193  }
194 
196 }
197 
201 bool MythCoreContextPrivate::WaitForWOL(std::chrono::milliseconds timeout)
202 {
203  std::chrono::milliseconds timeout_remaining = timeout;
204  while (m_wolInProgress && (timeout_remaining > 0ms))
205  {
206  LOG(VB_GENERAL, LOG_INFO, LOC + "Wake-On-LAN in progress, waiting...");
207 
208  std::chrono::milliseconds max_wait = std::min(1000ms, timeout_remaining);
209  m_wolInProgressWaitCondition.wait(&m_wolInProgressLock, max_wait.count());
210  timeout_remaining -= max_wait;
211  }
212 
213  return !m_wolInProgress;
214 }
215 
216 MythCoreContext::MythCoreContext(const QString &binversion,
217  QObject *guiContext)
218 {
219  d = new MythCoreContextPrivate(this, binversion, guiContext);
220 }
221 
223 {
224  if (!d)
225  {
226  LOG(VB_GENERAL, LOG_EMERG, LOC + "Out-of-memory");
227  return false;
228  }
229 
230  if (d->m_appBinaryVersion != MYTH_BINARY_VERSION)
231  {
232  LOG(VB_GENERAL, LOG_CRIT,
233  QString("Application binary version (%1) does not "
234  "match libraries (%2)")
235  .arg(d->m_appBinaryVersion, MYTH_BINARY_VERSION));
236 
237  QString warning = tr("This application is not compatible with the "
238  "installed MythTV libraries. Please recompile "
239  "after a make distclean");
240  LOG(VB_GENERAL, LOG_WARNING, warning);
241 
242  return false;
243  }
244 
245 #ifndef _WIN32
246  static const QRegularExpression utf8
247  { "utf-?8", QRegularExpression::CaseInsensitiveOption };
248  QString lang_variables("");
249  QString lc_value = setlocale(LC_CTYPE, nullptr);
250  if (lc_value.isEmpty())
251  {
252  // try fallback to environment variables for non-glibc systems
253  // LC_ALL, then LC_CTYPE
254  lc_value = qEnvironmentVariable("LC_ALL");
255  if (lc_value.isEmpty())
256  lc_value = qEnvironmentVariable("LC_CTYPE");
257  }
258  if (!lc_value.contains(utf8))
259  lang_variables.append("LC_ALL or LC_CTYPE");
260  lc_value = qEnvironmentVariable("LANG");
261  if (!lc_value.contains(utf8))
262  {
263  if (!lang_variables.isEmpty())
264  lang_variables.append(", and ");
265  lang_variables.append("LANG");
266  }
267  LOG(VB_GENERAL, LOG_INFO, QString("Assumed character encoding: %1")
268  .arg(lc_value));
269  if (!lang_variables.isEmpty())
270  {
271  LOG(VB_GENERAL, LOG_WARNING, QString("This application expects to "
272  "be running a locale that specifies a UTF-8 codeset, and many "
273  "features may behave improperly with your current language "
274  "settings. Please set the %1 variable(s) in the environment "
275  "in which this program is executed to include a UTF-8 codeset "
276  "(such as 'en_US.UTF-8').").arg(lang_variables));
277  }
278 #endif
279 
280  return true;
281 }
282 
284 {
285  delete d;
286  d = nullptr;
287 }
288 
289 void MythCoreContext::setTestIntSettings(QMap<QString,int> &overrides)
290 {
291  m_testOverrideInts = std::move(overrides);
292 }
293 
294 void MythCoreContext::setTestFloatSettings(QMap<QString,double> &overrides)
295 {
296  m_testOverrideFloats = std::move(overrides);
297 }
298 
299 void MythCoreContext::setTestStringSettings(QMap<QString,QString> &overrides)
300 {
301  m_testOverrideStrings = std::move(overrides);
302 }
303 
305  const QString &announcement,
306  [[maybe_unused]] std::chrono::milliseconds timeout,
307  bool &proto_mismatch)
308 {
309  proto_mismatch = false;
310 
311 #ifndef IGNORE_PROTO_VER_MISMATCH
312  if (!CheckProtoVersion(serverSock, timeout, true))
313  {
314  proto_mismatch = true;
315  return false;
316  }
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 { "Monitor" };
389  if (IsFrontend())
390  type = "Frontend";
391  else if (blockingClient)
392  type = "Playback";
393  QString ann = QString("ANN %1 %2 %3")
394  .arg(type, d->m_localHostname, QString::number(static_cast<int>(false)));
396  server, port, ann, &proto_mismatch);
397  }
398 
399  if (!d->m_serverSock)
400  return false;
401 
402  d->m_blockingClient = blockingClient;
403 
404  if (!openEventSocket)
405  return true;
406 
407 
408  if (!IsBackend())
409  {
410  if (d->m_eventSock && !d->m_eventSock->IsConnected())
411  {
412  d->m_eventSock->DecrRef();
413  d->m_eventSock = nullptr;
414  }
415  if (!d->m_eventSock)
416  d->m_eventSock = ConnectEventSocket(server, port);
417 
418  if (!d->m_eventSock)
419  {
420  d->m_serverSock->DecrRef();
421  d->m_serverSock = nullptr;
422 
423  QCoreApplication::postEvent(
424  d->m_guiContext, new MythEvent("CONNECTION_FAILURE"));
425 
426  return false;
427  }
428  }
429 
430  return true;
431 }
432 
434  const QString &hostname, int port, const QString &announce,
435  bool *p_proto_mismatch, int maxConnTry, std::chrono::milliseconds setup_timeout)
436 {
437  MythSocket *serverSock = nullptr;
438 
439  {
440  QMutexLocker locker(&d->m_wolInProgressLock);
441  d->WaitForWOL();
442  }
443 
444  QString WOLcmd;
445  if (IsWOLAllowed())
446  WOLcmd = GetSetting("WOLbackendCommand", "");
447 
448  if (maxConnTry < 1)
449  maxConnTry = std::max(GetNumSetting("BackendConnectRetry", 1), 1);
450 
451  std::chrono::seconds WOLsleepTime = 0s;
452  int WOLmaxConnTry = 0;
453  if (!WOLcmd.isEmpty())
454  {
455  WOLsleepTime = GetDurSetting<std::chrono::seconds>("WOLbackendReconnectWaitTime", 0s);
456  WOLmaxConnTry = std::max(GetNumSetting("WOLbackendConnectRetry", 1), 1);
457  maxConnTry = std::max(maxConnTry, WOLmaxConnTry);
458  }
459 
460  bool we_attempted_wol = false;
461 
462  if (setup_timeout <= 0ms)
463  setup_timeout = MythSocket::kShortTimeout;
464 
465  bool proto_mismatch = false;
466  for (int cnt = 1; cnt <= maxConnTry; cnt++)
467  {
468  LOG(VB_GENERAL, LOG_INFO, LOC +
469  QString("Connecting to backend server: %1:%2 (try %3 of %4)")
470  .arg(hostname).arg(port).arg(cnt).arg(maxConnTry));
471 
472  serverSock = new MythSocket();
473 
474  std::chrono::microseconds sleepus = 0us;
475  if (serverSock->ConnectToHost(hostname, port))
476  {
477  if (SetupCommandSocket(
478  serverSock, announce, setup_timeout, proto_mismatch))
479  {
480  break;
481  }
482 
483  if (proto_mismatch)
484  {
485  if (p_proto_mismatch)
486  *p_proto_mismatch = true;
487 
488  serverSock->DecrRef();
489  serverSock = nullptr;
490  break;
491  }
492 
493  setup_timeout += setup_timeout / 2;
494  }
495  else if (!WOLcmd.isEmpty() && (cnt < maxConnTry))
496  {
497  if (!we_attempted_wol)
498  {
499  QMutexLocker locker(&d->m_wolInProgressLock);
500  if (d->m_wolInProgress)
501  {
502  d->WaitForWOL();
503  continue;
504  }
505 
506  d->m_wolInProgress = we_attempted_wol = true;
507  }
508 
511  sleepus = WOLsleepTime;
512  }
513 
514  serverSock->DecrRef();
515  serverSock = nullptr;
516 
517  if (cnt == 1)
518  {
519  QCoreApplication::postEvent(
520  d->m_guiContext, new MythEvent("CONNECTION_FAILURE"));
521  }
522 
523  if (sleepus != 0us)
524  usleep(sleepus.count());
525  }
526 
527  if (we_attempted_wol)
528  {
529  QMutexLocker locker(&d->m_wolInProgressLock);
530  d->m_wolInProgress = false;
531  d->m_wolInProgressWaitCondition.wakeAll();
532  }
533 
534  if (!serverSock && !proto_mismatch)
535  {
536  LOG(VB_GENERAL, LOG_ERR,
537  "Connection to master server timed out.\n\t\t\t"
538  "Either the server is down or the master server settings"
539  "\n\t\t\t"
540  "in mythtv-settings does not contain the proper IP address\n");
541  }
542  else
543  {
544  QCoreApplication::postEvent(
545  d->m_guiContext, new MythEvent("CONNECTION_RESTABLISHED"));
546  }
547 
548  return serverSock;
549 }
550 
552  int port)
553 {
554  auto *eventSock = new MythSocket(-1, this);
555 
556  // Assume that since we _just_ connected the command socket,
557  // this one won't need multiple retries to work...
558  if (!eventSock->ConnectToHost(hostname, port))
559  {
560  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to connect event "
561  "socket to master backend");
562  eventSock->DecrRef();
563  return nullptr;
564  }
565 
566  QString str = QString("ANN Monitor %1 %2")
567  .arg(d->m_localHostname).arg(static_cast<int>(true));
568  QStringList strlist(str);
569  eventSock->WriteStringList(strlist);
570  bool ok = true;
571  if (!eventSock->ReadStringList(strlist) || strlist.empty() ||
572  (strlist[0] == "ERROR"))
573  {
574  if (!strlist.empty())
575  {
576  LOG(VB_GENERAL, LOG_ERR, LOC +
577  "Problem connecting event socket to master backend");
578  }
579  else
580  {
581  LOG(VB_GENERAL, LOG_ERR, LOC +
582  "Timeout connecting event socket to master backend");
583  }
584  ok = false;
585  }
586 
587  if (!ok)
588  {
589  eventSock->DecrRef();
590  eventSock = nullptr;
591  }
592 
593  return eventSock;
594 }
595 
597 {
598  QMutexLocker locker(&d->m_sockLock);
599  return d->m_serverSock;
600 }
601 
603 {
604  QStringList strlist;
605 
606  QMutexLocker locker(&d->m_sockLock);
607  if (d->m_serverSock == nullptr)
608  return;
609 
610  strlist << "BLOCK_SHUTDOWN";
612 
613  d->m_blockingClient = true;
614 }
615 
617 {
618  QStringList strlist;
619 
620  QMutexLocker locker(&d->m_sockLock);
621  if (d->m_serverSock == nullptr)
622  return;
623 
624  strlist << "ALLOW_SHUTDOWN";
626 
627  d->m_blockingClient = false;
628 }
629 
631 {
632  return d->m_blockingClient;
633 }
634 
636 {
637  d->m_isWOLAllowed = allow;
638 }
639 
641 {
642  return d->m_isWOLAllowed;
643 }
644 
646 {
647  d->m_backend = backend;
648 }
649 
651 {
652  return d->m_backend;
653 }
654 
656 {
657  d->m_frontend = frontend;
658 }
659 
661 {
662  return d->m_frontend;
663 }
664 
666 {
667  QString host = GetHostName();
668  return IsMasterHost(host);
669 }
670 
671 bool MythCoreContext::IsMasterHost(const QString &host)
672 {
673  // Temporary code here only to facilitate the upgrade
674  // from 1346 or earlier. The way of determining master host is
675  // changing, and the new way of determning master host
676  // will not work with earlier databases.
677  // This code can be removed when updating from prior to
678  // 1347 is no longer allowed.
679  // Note that we are deprecating some settings including
680  // MasterServerIP, and can remove them at a future time.
681  if (GetNumSetting("DBSchemaVer") < 1347)
682  {
683  // Temporary copy of code from old version of
684  // IsThisHost(Qstring&,QString&)
685  QString addr(resolveSettingAddress("MasterServerIP"));
686  if (addr.toLower() == host.toLower())
687  return true;
688  QHostAddress addrfix(addr);
689  addrfix.setScopeId(QString());
690  QString addrstr = addrfix.toString();
691  if (addrfix.isNull())
692  addrstr = resolveAddress(addr);
693  QString thisip = GetBackendServerIP4(host);
694  QString thisip6 = GetBackendServerIP6(host);
695  return !addrstr.isEmpty()
696  && ((addrstr == thisip) || (addrstr == thisip6));
697  }
698  return GetSetting("MasterServerName") == host;
699 }
700 
702 {
703  return (IsBackend() && IsMasterHost());
704 }
705 
707 {
708 #if defined(Q_OS_DARWIN) || defined(__FreeBSD__) || defined(__OpenBSD__)
709  const char *command = "ps -axc | grep -i mythbackend | grep -v grep > /dev/null";
710 #elif defined _WIN32
711  const char *command = "%systemroot%\\system32\\tasklist.exe "
712  " | %systemroot%\\system32\\find.exe /i \"mythbackend.exe\" ";
713 #else
714  const char *command = "ps ch -C mythbackend -o pid > /dev/null";
715 #endif
716  uint res = myth_system(command, kMSDontBlockInputDevs |
719  return (res == GENERIC_EXIT_OK);
720 }
721 
722 bool MythCoreContext::IsThisBackend(const QString &addr)
723 {
724  return IsBackend() && IsThisHost(addr);
725 }
726 
727 bool MythCoreContext::IsThisHost(const QString &addr)
728 {
729  return IsThisHost(addr, GetHostName());
730 }
731 
732 bool MythCoreContext::IsThisHost(const QString &addr, const QString &host)
733 {
734  if (addr.toLower() == host.toLower())
735  return true;
736 
737  QHostAddress addrfix(addr);
738  addrfix.setScopeId(QString());
739  QString addrstr = addrfix.toString();
740 
741  if (addrfix.isNull())
742  {
743  addrstr = resolveAddress(addr);
744  }
745 
746  QString thisip = GetBackendServerIP(host);
747 
748  return !addrstr.isEmpty() && ((addrstr == thisip));
749 }
750 
752 {
753  // find out if a backend runs on this host...
754  bool backendOnLocalhost = false;
755 
756  QStringList strlist("QUERY_IS_ACTIVE_BACKEND");
757  strlist << GetHostName();
758 
759  SendReceiveStringList(strlist);
760 
761  backendOnLocalhost = strlist[0] != "FALSE";
762 
763  return !backendOnLocalhost;
764 }
765 
766 QString MythCoreContext::GenMythURL(const QString& host, int port, QString path, const QString& storageGroup)
767 {
768  QUrl ret;
769 
770  QString m_host;
771 
772  QHostAddress addr(host);
773  if (!addr.isNull())
774  {
775  LOG(VB_GENERAL, LOG_CRIT, LOC + QString("(%1/%2): Given "
776  "IP address instead of hostname "
777  "(ID). This is invalid.").arg(host, path));
778  }
779 
780  m_host = host;
781 
782  // Basically if it appears to be an IPv6 IP surround the IP with [] otherwise don't bother
783  if (!addr.isNull() && addr.protocol() == QAbstractSocket::IPv6Protocol)
784  m_host = "[" + addr.toString().toLower() + "]";
785 
786  ret.setScheme("myth");
787  if (!storageGroup.isEmpty())
788  ret.setUserName(storageGroup);
789  ret.setHost(m_host);
790  if (port > 0 && port != 6543)
791  ret.setPort(port);
792  if (!path.startsWith("/"))
793  path = QString("/") + path;
794  ret.setPath(path);
795 
796 #if 0
797  LOG(VB_GENERAL, LOG_DEBUG, LOC +
798  QString("GenMythURL returning %1").arg(ret.toString()));
799 #endif
800 
801  return ret.toString();
802 }
803 
804 QString MythCoreContext::GetMasterHostPrefix(const QString &storageGroup,
805  const QString &path)
806 {
807  return GenMythURL(GetMasterHostName(),
809  path,
810  storageGroup);
811 }
812 
814 {
815  QMutexLocker locker(&d->m_masterHostLock);
816 
817  if (d->m_masterHostname.isEmpty())
818  {
819 
820  if (IsMasterBackend())
822  else
823  {
824  QStringList strlist("QUERY_HOSTNAME");
825 
826  if (SendReceiveStringList(strlist))
827  d->m_masterHostname = strlist[0];
828  }
829  }
830 
831  return d->m_masterHostname;
832 }
833 
834 void MythCoreContext::ClearSettingsCache(const QString &myKey)
835 {
836  d->m_database->ClearSettingsCache(myKey);
837 }
838 
840 {
841  d->m_database->ActivateSettingsCache(activate);
842 }
843 
845 {
846  QMutexLocker locker(&d->m_localHostLock);
847  return d->m_localHostname;
848 }
849 
851 {
852  return GetSetting("RecordFilePrefix");
853 }
854 
856  int &width, int &height,
857  double &forced_aspect,
858  double &refresh_rate,
859  int index)
860 {
861  d->m_database->GetResolutionSetting(type, width, height, forced_aspect,
862  refresh_rate, index);
863 }
864 
865 void MythCoreContext::GetResolutionSetting(const QString &t, int &w,
866  int &h, int i)
867 {
868  d->m_database->GetResolutionSetting(t, w, h, i);
869 }
870 
872 {
873  return d->m_database->GetDBManager();
874 }
875 
883 {
884  return d->m_database->IsDatabaseIgnored();
885 }
886 
887 void MythCoreContext::SaveSetting(const QString &key, int newValue)
888 {
889  d->m_database->SaveSetting(key, newValue);
890 }
891 
892 void MythCoreContext::SaveSetting(const QString &key, const QString &newValue)
893 {
894  d->m_database->SaveSetting(key, newValue);
895 }
896 
897 bool MythCoreContext::SaveSettingOnHost(const QString &key,
898  const QString &newValue,
899  const QString &host)
900 {
901  return d->m_database->SaveSettingOnHost(key, newValue, host);
902 }
903 
904 QString MythCoreContext::GetSetting(const QString &key,
905  const QString &defaultval)
906 {
907  if (!m_testOverrideStrings.empty())
908  return m_testOverrideStrings[key];
909  return d->m_database->GetSetting(key, defaultval);
910 }
911 
912 bool MythCoreContext::GetBoolSetting(const QString &key, bool defaultval)
913 {
914  int result = GetNumSetting(key, static_cast<int>(defaultval));
915  return result > 0;
916 }
917 
918 int MythCoreContext::GetNumSetting(const QString &key, int defaultval)
919 {
920  if (!m_testOverrideInts.empty())
921  return m_testOverrideInts[key];
922  return d->m_database->GetNumSetting(key, defaultval);
923 }
924 
925 double MythCoreContext::GetFloatSetting(const QString &key, double defaultval)
926 {
927  if (!m_testOverrideFloats.empty())
928  return m_testOverrideFloats[key];
929  return d->m_database->GetFloatSetting(key, defaultval);
930 }
931 
932 QString MythCoreContext::GetSettingOnHost(const QString &key,
933  const QString &host,
934  const QString &defaultval)
935 {
936  if (!m_testOverrideStrings.empty())
937  return m_testOverrideStrings[key];
938  return d->m_database->GetSettingOnHost(key, host, defaultval);
939 }
940 
942  const QString &host,
943  bool defaultval)
944 {
945  int result = GetNumSettingOnHost(key, host, static_cast<int>(defaultval));
946  return result > 0;
947 }
948 
950  const QString &host,
951  int defaultval)
952 {
953  if (!m_testOverrideInts.empty())
954  return m_testOverrideInts[key];
955  return d->m_database->GetNumSettingOnHost(key, host, defaultval);
956 }
957 
958 double MythCoreContext::GetFloatSettingOnHost(const QString &key,
959  const QString &host,
960  double defaultval)
961 {
962  if (!m_testOverrideFloats.empty())
963  return m_testOverrideFloats[key];
964  return d->m_database->GetFloatSettingOnHost(key, host, defaultval);
965 }
966 
973 {
974  QString masterserver = gCoreContext->GetSetting("MasterServerName");
975  QString masterip = resolveSettingAddress("BackendServerAddr",masterserver);
976  // Even if empty, return it here if we were to assume that localhost
977  // should be used it just causes a lot of unnecessary error messages.
978  return masterip;
979 }
980 
987 {
988  QString masterserver = gCoreContext->GetSetting
989  ("MasterServerName");
991  ("BackendServerPort", masterserver, 6543);
992 }
993 
1000 {
1001  QString masterhost = GetMasterHostName();
1002 
1003  return GetBackendStatusPort(masterhost);
1004 }
1005 
1011 {
1013 }
1014 
1024 QString MythCoreContext::GetBackendServerIP(const QString &host)
1025 {
1026  return resolveSettingAddress("BackendServerAddr",host);
1027 }
1028 
1034 {
1036 }
1037 
1043 QString MythCoreContext::GetBackendServerIP4(const QString &host)
1044 {
1045  return resolveSettingAddress("BackendServerIP", host, ResolveIPv4);
1046 }
1047 
1053 {
1055 }
1056 
1062 QString MythCoreContext::GetBackendServerIP6(const QString &host)
1063 {
1064  return resolveSettingAddress("BackendServerIP6", host, ResolveIPv6);
1065 }
1066 
1071 {
1073 }
1074 
1075 QHash<QString,int> MythCoreContext::s_serverPortCache;
1076 
1078 {
1079  s_serverPortCache.clear();
1080 }
1081 
1086 {
1087  int port = s_serverPortCache.value(host, -1);
1088  if (port != -1)
1089  return port;
1090  port = GetNumSettingOnHost("BackendServerPort", host, 6543);
1091  s_serverPortCache[host] = port;
1092  return port;
1093 }
1094 
1099 {
1101 }
1102 
1107 {
1108  return GetNumSettingOnHost("BackendStatusPort", host, 6544);
1109 }
1110 
1115 bool MythCoreContext::GetScopeForAddress(QHostAddress &addr) const
1116 {
1117  QHostAddress addr1 = addr;
1118  addr1.setScopeId(QString());
1119  QString addrstr = addr1.toString();
1120  QMutexLocker lock(&d->m_scopesLock);
1121 
1122  if (!d->m_scopes.contains(addrstr))
1123  return false;
1124 
1125  addr.setScopeId(d->m_scopes[addrstr]);
1126  return true;
1127 }
1128 
1135 void MythCoreContext::SetScopeForAddress(const QHostAddress &addr)
1136 {
1137  QHostAddress addr1 = addr;
1138  addr1.setScopeId(QString());
1139  QMutexLocker lock(&d->m_scopesLock);
1140 
1141  d->m_scopes.insert(addr1.toString(), addr.scopeId());
1142 }
1143 
1149 void MythCoreContext::SetScopeForAddress(const QHostAddress &addr, int scope)
1150 {
1151  QHostAddress addr1 = addr;
1152  addr1.setScopeId(QString());
1153  QMutexLocker lock(&d->m_scopesLock);
1154 
1155  d->m_scopes.insert(addr1.toString(), QString::number(scope));
1156 }
1157 
1169 QString MythCoreContext::resolveSettingAddress(const QString &name,
1170  const QString &host,
1171  ResolveType type, bool keepscope)
1172 {
1173  QString value;
1174 
1175  if (host.isEmpty())
1176  {
1177  value = GetSetting(name);
1178  }
1179  else
1180  {
1181  value = GetSettingOnHost(name, host);
1182  }
1183 
1184  return resolveAddress(value, type, keepscope);
1185 }
1186 
1198 QString MythCoreContext::resolveAddress(const QString &host, ResolveType type,
1199  bool keepscope)
1200 {
1201  QHostAddress addr(host);
1202 
1203  if (!host.isEmpty() && addr.isNull())
1204  {
1205  // address is likely a hostname, attempts to resolve it
1206  QHostInfo info = QHostInfo::fromName(host);
1207  QList<QHostAddress> list = info.addresses();
1208 
1209  if (list.isEmpty())
1210  {
1211  LOG(VB_GENERAL, LOG_WARNING, LOC +
1212  QString("Can't resolve hostname:'%1', using localhost").arg(host));
1213  return type == ResolveIPv4 ? "127.0.0.1" : "::1";
1214  }
1215  QHostAddress v4;
1216  QHostAddress v6;
1217 
1218  // Return the first address fitting the type critera
1219  for (const auto& item : std::as_const(list))
1220  {
1221  addr = item;
1222  QAbstractSocket::NetworkLayerProtocol prot = addr.protocol();
1223 
1224  if (prot == QAbstractSocket::IPv4Protocol)
1225  {
1226  v4 = addr;
1227  if (type == 0)
1228  break;
1229  }
1230  else if (prot == QAbstractSocket::IPv6Protocol)
1231  {
1232  v6 = addr;
1233  if (type != 0)
1234  break;
1235  }
1236  }
1237  switch (type)
1238  {
1239  case ResolveIPv4:
1240  addr = v4.isNull() ? QHostAddress::LocalHost : v4;
1241  break;
1242  case ResolveIPv6:
1243  addr = v6.isNull() ? QHostAddress::LocalHostIPv6 : v6;
1244  break;
1245  default:
1246  if (!v6.isNull())
1247  addr = v6;
1248  else if (!v4.isNull())
1249  addr = v4;
1250  else
1251  addr = QHostAddress::LocalHostIPv6;
1252  break;
1253  }
1254  }
1255  else if (host.isEmpty())
1256  {
1257  return {};
1258  }
1259 
1260  if (!keepscope)
1261  {
1262  addr.setScopeId(QString());
1263  }
1264  return addr.toString();
1265 }
1266 
1278 bool MythCoreContext::CheckSubnet(const QAbstractSocket *socket)
1279 {
1280  QHostAddress peer = socket->peerAddress();
1281  return CheckSubnet(peer);
1282 }
1283 
1295 bool MythCoreContext::CheckSubnet(const QHostAddress &peer)
1296 {
1297  static const QHostAddress kLinkLocal("fe80::");
1298  if (GetBoolSetting("AllowConnFromAll",false))
1299  return true;
1300  if (d->m_approvedIps.contains(peer))
1301  return true;
1302  if (d->m_deniedIps.contains(peer))
1303  {
1304  LOG(VB_GENERAL, LOG_WARNING, LOC +
1305  QString("Repeat denied connection from ip address: %1")
1306  .arg(peer.toString()));
1307  return false;
1308  }
1309 
1310  // allow all link-local
1311  if (peer.isInSubnet(kLinkLocal,10))
1312  {
1313  d->m_approvedIps.append(peer);
1314  return true;
1315  }
1316 
1317  // loop through all available interfaces
1318  QList<QNetworkInterface> IFs = QNetworkInterface::allInterfaces();
1319  for (const auto & qni : std::as_const(IFs))
1320  {
1321  if ((qni.flags() & QNetworkInterface::IsRunning) == 0)
1322  continue;
1323 
1324  QList<QNetworkAddressEntry> IPs = qni.addressEntries();
1325  for (const auto & qnai : std::as_const(IPs))
1326  {
1327  int pfxlen = qnai.prefixLength();
1328  // Set this to test rejection without having an extra
1329  // network.
1330  if (GetBoolSetting("DebugSubnet"))
1331  pfxlen += 4;
1332  if (peer.isInSubnet(qnai.ip(),pfxlen))
1333  {
1334  d->m_approvedIps.append(peer);
1335  return true;
1336  }
1337  }
1338  }
1339  d->m_deniedIps.append(peer);
1340  LOG(VB_GENERAL, LOG_WARNING, LOC +
1341  QString("Denied connection from ip address: %1")
1342  .arg(peer.toString()));
1343  return false;
1344 }
1345 
1346 
1348  const QString &value)
1349 {
1350  d->m_database->OverrideSettingForSession(key, value);
1351 }
1352 
1354 {
1355  d->m_database->ClearOverrideSettingForSession(key);
1356 }
1357 
1359 {
1360  return is_current_thread(d->m_uiThread);
1361 }
1362 
1382  QStringList &strlist, bool quickTimeout, bool block)
1383 {
1384  QString msg;
1385  if (HasGUI() && IsUIThread())
1386  {
1387  msg = "SendReceiveStringList(";
1388  for (uint i=0; i<(uint)strlist.size() && i<2; i++)
1389  msg += (i?",":"") + strlist[i];
1390  msg += (strlist.size() > 2) ? "...)" : ")";
1391  LOG(VB_GENERAL, LOG_DEBUG, LOC + msg + " called from UI thread");
1392  }
1393 
1394  QString query_type = "UNKNOWN";
1395 
1396  if (!strlist.isEmpty())
1397  query_type = strlist[0];
1398 
1399  QMutexLocker locker(&d->m_sockLock);
1400  if (!d->m_serverSock)
1401  {
1402  bool blockingClient = d->m_blockingClient &&
1403  (GetNumSetting("idleTimeoutSecs",0) > 0);
1404  ConnectToMasterServer(blockingClient);
1405  }
1406 
1407  bool ok = false;
1408 
1409  if (d->m_serverSock)
1410  {
1411  std::chrono::milliseconds timeout = quickTimeout ?
1413  ok = d->m_serverSock->SendReceiveStringList(strlist, 0, timeout);
1414 
1415  if (!ok)
1416  {
1417  LOG(VB_GENERAL, LOG_NOTICE, LOC +
1418  QString("Connection to backend server lost"));
1419  d->m_serverSock->DecrRef();
1420  d->m_serverSock = nullptr;
1421 
1422  if (d->m_eventSock)
1423  {
1424  d->m_eventSock->DecrRef();
1425  d->m_eventSock = nullptr;
1426  }
1427 
1428  if (block)
1429  {
1431 
1432  if (d->m_serverSock)
1433  {
1435  strlist, 0, timeout);
1436  }
1437  }
1438  }
1439 
1440  // this should not happen
1441  while (ok && strlist[0] == "BACKEND_MESSAGE")
1442  {
1443  // oops, not for us
1444  LOG(VB_GENERAL, LOG_EMERG, LOC + "SRSL you shouldn't see this!!");
1445  QString message = strlist[1];
1446  strlist.pop_front(); strlist.pop_front();
1447 
1448  MythEvent me(message, strlist);
1449  dispatch(me);
1450 
1451  ok = d->m_serverSock->ReadStringList(strlist, timeout);
1452  }
1453 
1454  if (!ok)
1455  {
1456  if (d->m_serverSock)
1457  {
1458  d->m_serverSock->DecrRef();
1459  d->m_serverSock = nullptr;
1460  }
1461 
1462  LOG(VB_GENERAL, LOG_CRIT, LOC +
1463  QString("Reconnection to backend server failed"));
1464 
1465  QCoreApplication::postEvent(d->m_guiContext,
1466  new MythEvent("PERSISTENT_CONNECTION_FAILURE"));
1467  }
1468  }
1469 
1470  if (ok)
1471  {
1472  if (strlist.isEmpty())
1473  ok = false;
1474  else if (strlist[0] == "ERROR")
1475  {
1476  if (strlist.size() == 2)
1477  {
1478  LOG(VB_GENERAL, LOG_INFO, LOC +
1479  QString("Protocol query '%1' responded with the error '%2'")
1480  .arg(query_type, strlist[1]));
1481  }
1482  else
1483  {
1484  LOG(VB_GENERAL, LOG_INFO, LOC +
1485  QString("Protocol query '%1' responded with an error, but "
1486  "no error message.") .arg(query_type));
1487  }
1488 
1489  ok = false;
1490  }
1491  else if (strlist[0] == "UNKNOWN_COMMAND")
1492  {
1493  LOG(VB_GENERAL, LOG_ERR, LOC +
1494  QString("Protocol query '%1' responded with the error 'UNKNOWN_COMMAND'")
1495  .arg(query_type));
1496 
1497  ok = false;
1498  }
1499  }
1500 
1501  return ok;
1502 }
1503 
1504 class SendAsyncMessage : public QRunnable
1505 {
1506  public:
1507  SendAsyncMessage(QString msg, QStringList extra) :
1508  m_message(std::move(msg)), m_extraData(std::move(extra))
1509  {
1510  }
1511 
1512  explicit SendAsyncMessage(QString msg) : m_message(std::move(msg)) { }
1513 
1514  void run(void) override // QRunnable
1515  {
1516  QStringList strlist("MESSAGE");
1517  strlist << m_message;
1518  strlist << m_extraData;
1520  }
1521 
1522  private:
1523  QString m_message;
1524  QStringList m_extraData;
1525 };
1526 
1527 void MythCoreContext::SendMessage(const QString &message)
1528 {
1529  if (IsBackend())
1530  {
1531  dispatch(MythEvent(message));
1532  }
1533  else
1534  {
1536  new SendAsyncMessage(message), "SendMessage");
1537  }
1538 }
1539 
1541 {
1542  if (IsBackend())
1543  {
1544  dispatch(event);
1545  }
1546  else
1547  {
1549  new SendAsyncMessage(event.Message(), event.ExtraDataList()),
1550  "SendEvent");
1551  }
1552 }
1553 
1554 void MythCoreContext::SendSystemEvent(const QString &msg)
1555 {
1556  if (QCoreApplication::applicationName() == MYTH_APPNAME_MYTHTV_SETUP)
1557  return;
1558 
1559  SendMessage(QString("SYSTEM_EVENT %1 SENDER %2")
1560  .arg(msg, GetHostName()));
1561 }
1562 
1564  const QString &hostname,
1565  const QString &args)
1566 {
1567  SendSystemEvent(QString("%1 HOST %2 %3").arg(msg, hostname, args));
1568 }
1569 
1570 
1572 {
1573  do
1574  {
1575  QStringList strlist;
1576  if (!sock->ReadStringList(strlist))
1577  continue;
1578 
1579  if (strlist.size() < 2)
1580  continue;
1581 
1582  QString prefix = strlist[0];
1583  QString message = strlist[1];
1584  QStringList tokens = message.split(" ", Qt::SkipEmptyParts);
1585 
1586  if (prefix == "OK")
1587  {
1588  }
1589  else if (prefix != "BACKEND_MESSAGE")
1590  {
1591  LOG(VB_NETWORK, LOG_ERR, LOC +
1592  QString("Received a: %1 message from the backend "
1593  "but I don't know what to do with it.")
1594  .arg(prefix));
1595  }
1596  else if (message == "CLEAR_SETTINGS_CACHE")
1597  {
1598  // No need to dispatch this message to ourself, so handle it
1599  LOG(VB_NETWORK, LOG_INFO, LOC + "Received remote 'Clear Cache' request");
1601  }
1602  else if (message.startsWith("FILE_WRITTEN"))
1603  {
1604  QString file;
1605  uint64_t size = 0;
1606  int NUMTOKENS = 3; // Number of tokens expected
1607 
1608  if (tokens.size() == NUMTOKENS)
1609  {
1610  file = tokens[1];
1611  size = tokens[2].toULongLong();
1612  }
1613  else
1614  {
1615  LOG(VB_NETWORK, LOG_ERR, LOC +
1616  QString("FILE_WRITTEN 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_WRITTEN %1' request").arg(file));
1626  RegisterFileForWrite(file, size);
1627  }
1628  else if (message.startsWith("FILE_CLOSED"))
1629  {
1630  QString file;
1631  int NUMTOKENS = 2; // Number of tokens expected
1632 
1633  if (tokens.size() == NUMTOKENS)
1634  {
1635  file = tokens[1];
1636  }
1637  else
1638  {
1639  LOG(VB_NETWORK, LOG_ERR, LOC +
1640  QString("FILE_CLOSED event received "
1641  "with invalid number of arguments, "
1642  "%1 expected, %2 actual")
1643  .arg(NUMTOKENS-1)
1644  .arg(tokens.size()-1));
1645  return;
1646  }
1647  // No need to dispatch this message to ourself, so handle it
1648  LOG(VB_NETWORK, LOG_INFO, LOC +
1649  QString("Received remote 'FILE_CLOSED %1' request").arg(file));
1651  }
1652  else
1653  {
1654  strlist.pop_front();
1655  strlist.pop_front();
1656  MythEvent me(message, strlist);
1657  dispatch(me);
1658  }
1659  }
1660  while (sock->IsDataAvailable());
1661 }
1662 
1663 void MythCoreContext::connectionClosed([[maybe_unused]] MythSocket *sock)
1664 {
1665  LOG(VB_GENERAL, LOG_NOTICE, LOC +
1666  "Event socket closed. No connection to the backend.");
1667 
1668  dispatch(MythEvent("BACKEND_SOCKETS_CLOSED"));
1669 }
1670 
1672  std::chrono::milliseconds timeout,
1673  bool error_dialog_desired)
1674 {
1675  if (!socket)
1676  return false;
1677 
1678  QStringList strlist(QString("MYTH_PROTO_VERSION %1 %2")
1679  .arg(MYTH_PROTO_VERSION,
1680  QString::fromUtf8(MYTH_PROTO_TOKEN)));
1681  socket->WriteStringList(strlist);
1682 
1683  if (!socket->ReadStringList(strlist, timeout) || strlist.empty())
1684  {
1685  LOG(VB_GENERAL, LOG_CRIT, "Protocol version check failure.\n\t\t\t"
1686  "The response to MYTH_PROTO_VERSION was empty.\n\t\t\t"
1687  "This happens when the backend is too busy to respond,\n\t\t\t"
1688  "or has deadlocked due to bugs or hardware failure.");
1689 
1690  return false;
1691  }
1692  if (strlist[0] == "REJECT" && strlist.size() >= 2)
1693  {
1694  LOG(VB_GENERAL, LOG_CRIT, LOC + QString("Protocol version or token mismatch "
1695  "(frontend=%1/%2,backend=%3/\?\?)\n")
1696  .arg(MYTH_PROTO_VERSION,
1697  QString::fromUtf8(MYTH_PROTO_TOKEN),
1698  strlist[1]));
1699 
1700  if (error_dialog_desired && d->m_guiContext)
1701  {
1702  QStringList list(strlist[1]);
1703  QCoreApplication::postEvent(
1704  d->m_guiContext, new MythEvent("VERSION_MISMATCH", list));
1705  }
1706 
1707  return false;
1708  }
1709  if (strlist[0] == "ACCEPT")
1710  {
1711  if (!d->m_announcedProtocol)
1712  {
1713  d->m_announcedProtocol = true;
1714  LOG(VB_GENERAL, LOG_INFO, LOC +
1715  QString("Using protocol version %1 %2")
1716  .arg(MYTH_PROTO_VERSION,
1717  QString::fromUtf8(MYTH_PROTO_TOKEN)));
1718  }
1719 
1720  return true;
1721  }
1722 
1723  LOG(VB_GENERAL, LOG_ERR, LOC +
1724  QString("Unexpected response to MYTH_PROTO_VERSION: %1")
1725  .arg(strlist[0]));
1726  return false;
1727 }
1728 
1730 {
1731  LOG(VB_NETWORK, LOG_INFO, LOC + QString("MythEvent: %1").arg(event.Message()));
1732 
1733  MythObservable::dispatch(event);
1734 }
1735 
1737 {
1738  QMutexLocker locker(&d->m_localHostLock);
1740  d->m_database->SetLocalHostname(hostname);
1741 }
1742 
1744 {
1745  d->m_guiObject = gui;
1746 }
1747 
1748 bool MythCoreContext::HasGUI(void) const
1749 {
1750  return d->m_guiObject;
1751 }
1752 
1754 {
1755  return d->m_guiObject;
1756 }
1757 
1759 {
1760  return d->m_guiContext;
1761 }
1762 
1764 {
1765  return d->m_database;
1766 }
1767 
1769 {
1770  return d->m_locale;
1771 }
1772 
1778 {
1779  return GetLanguageAndVariant().left(2);
1780 }
1781 
1790 {
1791  if (d->m_language.isEmpty())
1792  d->m_language = GetSetting("Language", "en_US").toLower();
1793 
1794  return d->m_language;
1795 }
1796 
1798 {
1799  d->m_language.clear();
1800 }
1801 
1807 {
1808  return GetAudioLanguageAndVariant().left(2);
1809 }
1810 
1819 {
1820  if (d->m_audioLanguage.isEmpty())
1821  {
1822  auto menuLanguage = GetLanguageAndVariant();
1823  d->m_audioLanguage = GetSetting("AudioLanguage", menuLanguage).toLower();
1824 
1825  LOG(VB_AUDIO, LOG_DEBUG, LOC + QString("audio language:%1 menu language:%2")
1826  .arg(d->m_audioLanguage, menuLanguage));
1827  }
1828  return d->m_audioLanguage;
1829 }
1830 
1832 {
1833  d->m_audioLanguage.clear();
1834 }
1835 
1837 {
1838  QMutexLocker locker(&d->m_sockLock);
1839  LOG(VB_GENERAL, LOG_INFO, "Restarting Backend Connections");
1840  if (d->m_serverSock)
1842  if (d->m_eventSock)
1844  dispatch(MythEvent("BACKEND_SOCKETS_CLOSED"));
1845 }
1846 
1848 {
1849  if (Create && !d->m_power)
1850  {
1852  }
1853  else if (!Create && d->m_power)
1854  {
1855  MythPower::AcquireRelease(d, false);
1856  d->m_power = nullptr;
1857  }
1858 }
1859 
1861 {
1862  if (!d->m_locale)
1863  d->m_locale = new MythLocale();
1864 
1865  QString localeCode = d->m_locale->GetLocaleCode();
1866  LOG(VB_GENERAL, LOG_NOTICE, QString("Setting QT default locale to %1")
1867  .arg(localeCode));
1868  QLocale::setDefault(d->m_locale->ToQLocale());
1869 }
1870 
1872 {
1873  if (!d->m_locale)
1874  d->m_locale = new MythLocale();
1875  else
1876  d->m_locale->ReInit();
1877 
1878  QString localeCode = d->m_locale->GetLocaleCode();
1879  LOG(VB_GENERAL, LOG_NOTICE, QString("Setting QT default locale to %1")
1880  .arg(localeCode));
1881  QLocale::setDefault(d->m_locale->ToQLocale());
1882 }
1883 
1885 {
1886  if (!d->m_locale)
1887  InitLocale();
1888 
1889  return d->m_locale->ToQLocale();
1890 }
1891 
1893 {
1894  if (!d->m_locale)
1895  InitLocale();
1896 
1897  if (!d->m_locale->GetLocaleCode().isEmpty())
1898  {
1899  LOG(VB_GENERAL, LOG_INFO,
1900  QString("Current locale %1") .arg(d->m_locale->GetLocaleCode()));
1901 
1903  return;
1904  }
1905 
1906  LOG(VB_GENERAL, LOG_ERR, LOC +
1907  "No locale defined! We weren't able to set locale defaults.");
1908 }
1909 
1911 {
1912  d->m_scheduler = sched;
1913 }
1914 
1916 {
1917  return d->m_scheduler;
1918 }
1919 
1924 void MythCoreContext::WaitUntilSignals(std::vector<CoreWaitInfo> & sigs) const
1925 {
1926  if (sigs.empty())
1927  return;
1928 
1929  QEventLoop eventLoop;
1930  for (const auto& s : sigs)
1931  {
1932  LOG(VB_GENERAL, LOG_DEBUG, LOC +
1933  QString("Waiting for signal %1")
1934  .arg(s.name));
1935  connect(this, s.fn, &eventLoop, &QEventLoop::quit);// clazy:exclude=connect-non-signal
1936  }
1937 
1938  eventLoop.exec(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers);
1939 }
1940 
1948 {
1949  if (!sender || !method)
1950  return;
1951 
1952  QMutexLocker lock(&d->m_playbackLock);
1953 
1954  if (!d->m_playbackClients.contains(sender))
1955  {
1956  d->m_playbackClients.insert(sender, method);
1958  sender, method,
1959  Qt::BlockingQueuedConnection);
1960  }
1961 }
1962 
1969 {
1970  QMutexLocker lock(&d->m_playbackLock);
1971 
1972  if (d->m_playbackClients.contains(sender))
1973  {
1974  PlaybackStartCb method = d->m_playbackClients.value(sender);
1975  disconnect(this, &MythCoreContext::TVPlaybackAboutToStart,
1976  sender, method);
1977  d->m_playbackClients.remove(sender);
1978  }
1979 }
1980 
1988 {
1989  QMutexLocker lock(&d->m_playbackLock);
1990  PlaybackStartCb method { nullptr };
1991  d->m_inwanting = true;
1992 
1993  // If any registered client are in the same thread, they will deadlock, so rebuild
1994  // connections for any clients in the same thread as non-blocking connection
1995  QThread *currentThread = QThread::currentThread();
1996 
1997  QMap<QObject *, PlaybackStartCb>::iterator it = d->m_playbackClients.begin();
1998  for (; it != d->m_playbackClients.end(); ++it)
1999  {
2000  if (it.key() == sender)
2001  continue; // will be done separately, no need to do it again
2002 
2003  QThread *thread = it.key()->thread();
2004 
2005  if (thread != currentThread)
2006  continue;
2007 
2008  disconnect(this, &MythCoreContext::TVPlaybackAboutToStart, it.key(), it.value());
2009  connect(this, &MythCoreContext::TVPlaybackAboutToStart, it.key(), it.value());
2010  }
2011 
2012  // disconnect sender so it won't receive the message
2013  if (d->m_playbackClients.contains(sender))
2014  {
2015  method = d->m_playbackClients.value(sender);
2016  disconnect(this, &MythCoreContext::TVPlaybackAboutToStart, sender, method);
2017  }
2018 
2019  // emit signal
2020  emit TVPlaybackAboutToStart();
2021 
2022  // reconnect sender
2023  if (method)
2024  {
2026  sender, method,
2027  Qt::BlockingQueuedConnection);
2028  }
2029  // Restore blocking connections
2030  for (; it != d->m_playbackClients.end(); ++it)
2031  {
2032  if (it.key() == sender)
2033  continue; // already done above, no need to do it again
2034 
2035  QThread *thread = it.key()->thread();
2036 
2037  if (thread != currentThread)
2038  continue;
2039 
2040  disconnect(this, &MythCoreContext::TVPlaybackAboutToStart,
2041  it.key(), it.value());
2043  it.key(), it.value(), Qt::BlockingQueuedConnection);
2044  }
2045  d->m_inwanting = false;
2046 }
2047 
2054 {
2055  // when called, it will be while the m_playbackLock is held
2056  // following a call to WantingPlayback
2057  d->m_intvwanting = b;
2058 }
2059 
2066 {
2067  bool locked = d->m_playbackLock.tryLock();
2068  bool intvplayback = d->m_intvwanting;
2069 
2070  if (!locked && d->m_inwanting)
2071  return true; // we're in the middle of WantingPlayback
2072 
2073  if (!locked)
2074  return false;
2075 
2076  d->m_playbackLock.unlock();
2077 
2078  return intvplayback;
2079 }
2080 
2082 {
2083  if (!d->m_sessionManager)
2085 
2086  return d->m_sessionManager;
2087 }
2088 
2089 bool MythCoreContext::TestPluginVersion(const QString &name,
2090  const QString &libversion,
2091  const QString &pluginversion)
2092 {
2093  if (libversion == pluginversion)
2094  return true;
2095 
2096  LOG(VB_GENERAL, LOG_EMERG, LOC +
2097  QString("Plugin %1 (%2) binary version does not "
2098  "match libraries (%3)")
2099  .arg(name, pluginversion, libversion));
2100  return false;
2101 }
2102 
2104 {
2105  if (d->m_pluginmanager == pmanager)
2106  return;
2107 
2108  if (d->m_pluginmanager)
2109  {
2110  delete d->m_pluginmanager;
2111  d->m_pluginmanager = nullptr;
2112  }
2113 
2114  d->m_pluginmanager = pmanager;
2115 }
2116 
2118 {
2119  return d->m_pluginmanager;
2120 }
2121 
2123 {
2124  d->m_isexiting = exiting;
2125 }
2126 
2128 {
2129  return d->m_isexiting;
2130 }
2131 
2132 void MythCoreContext::RegisterFileForWrite(const QString& file, uint64_t size)
2133 {
2134  QMutexLocker lock(&d->m_fileslock);
2135 
2136  QPair<int64_t, uint64_t> pair(QDateTime::currentMSecsSinceEpoch(), size);
2137  d->m_fileswritten.insert(file, pair);
2138 
2139  if (IsBackend())
2140  {
2141  QString message = QString("FILE_WRITTEN %1 %2").arg(file).arg(size);
2142  MythEvent me(message);
2143  dispatch(me);
2144  }
2145 
2146  LOG(VB_FILE, LOG_DEBUG, LOC +
2147  QString("%1").arg(file));
2148 }
2149 
2151 {
2152  QMutexLocker lock(&d->m_fileslock);
2153 
2154  d->m_fileswritten.remove(file);
2155 
2156  if (IsBackend())
2157  {
2158  QString message = QString("FILE_CLOSED %1").arg(file);
2159  MythEvent me(message);
2160  dispatch(me);
2161  }
2162 
2163  LOG(VB_FILE, LOG_DEBUG, LOC +
2164  QString("%1").arg(file));
2165 }
2166 
2168 {
2169  QMutexLocker lock(&d->m_fileslock);
2170 
2171  return d->m_fileswritten.contains(file);
2172 }
2173 
2174 /* 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:1169
MythCoreContext::SetPluginManager
void SetPluginManager(MythPluginManager *pmanager)
Definition: mythcorecontext.cpp:2103
loggingDeregisterThread
void loggingDeregisterThread(void)
Deregister the current thread's name.
Definition: logging.cpp:719
MythCoreContext::SetWOLAllowed
void SetWOLAllowed(bool allow)
Definition: mythcorecontext.cpp:635
build_compdb.args
args
Definition: build_compdb.py:11
DestroyMythDB
void DestroyMythDB(void)
Definition: mythdb.cpp:56
MythLocale::ReInit
void ReInit()
Definition: mythlocale.cpp:54
MythCoreContextPrivate::WaitForWOL
bool WaitForWOL(std::chrono::milliseconds timeout=std::chrono::milliseconds::max())
If another thread has already started WOL process, wait on them...
Definition: mythcorecontext.cpp:201
MythCoreContext::SendMessage
void SendMessage(const QString &message)
Definition: mythcorecontext.cpp:1527
hardwareprofile.smolt.timeout
float timeout
Definition: smolt.py:101
MythCoreContext::GetMasterHostName
QString GetMasterHostName(void)
Definition: mythcorecontext.cpp:813
MythPower
Definition: mythpower.h:19
MythPluginManager
Definition: mythplugin.h:62
MythCoreContextPrivate::m_fileswritten
QMap< QString, QPair< int64_t, uint64_t > > m_fileswritten
Definition: mythcorecontext.cpp:116
ReferenceCounter::DecrRef
virtual int DecrRef(void)
Decrements reference count and deletes on 0.
Definition: referencecounter.cpp:124
MythScheduler
This is an generic interface to a program scheduler.
Definition: mythscheduler.h:17
kMSDontBlockInputDevs
@ kMSDontBlockInputDevs
avoid blocking LIRC & Joystick Menu
Definition: mythsystem.h:36
MythCoreContext::GetScheduler
MythScheduler * GetScheduler(void)
Definition: mythcorecontext.cpp:1915
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:1381
MythCoreContext::IsBlockingClient
bool IsBlockingClient(void) const
is this client blocking shutdown
Definition: mythcorecontext.cpp:630
MythCoreContext::IsFrontendOnly
bool IsFrontendOnly(void)
is there a frontend, but no backend, running on this host
Definition: mythcorecontext.cpp:751
MythCoreContext::AllowShutdown
void AllowShutdown(void)
Definition: mythcorecontext.cpp:616
MythCoreContextPrivate::m_masterHostLock
QMutex m_masterHostLock
Locking for m_masterHostname.
Definition: mythcorecontext.cpp:76
MythCoreContext::ResetSockets
void ResetSockets(void)
Definition: mythcorecontext.cpp:1836
MythLocale
Definition: mythlocale.h:12
MythCoreContext::GetDBManager
MDBManager * GetDBManager(void)
Definition: mythcorecontext.cpp:871
MythCoreContext::UnregisterFileForWrite
void UnregisterFileForWrite(const QString &file)
Definition: mythcorecontext.cpp:2150
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:1768
MythCoreContext::~MythCoreContext
~MythCoreContext() override
Definition: mythcorecontext.cpp:283
mythplugin.h
MythCoreContext::InitLocale
void InitLocale(void)
Definition: mythcorecontext.cpp:1860
ShutdownMythDownloadManager
void ShutdownMythDownloadManager(void)
Deletes the running MythDownloadManager at program exit.
Definition: mythdownloadmanager.cpp:134
MythCoreContext::GetAudioLanguage
QString GetAudioLanguage(void)
Returns two character ISO-639 language descriptor for audio language.
Definition: mythcorecontext.cpp:1806
MythCoreContext::SetScheduler
void SetScheduler(MythScheduler *sched)
Definition: mythcorecontext.cpp:1910
MythCoreContext::GetBackendStatusPort
int GetBackendStatusPort(void)
Returns the locally defined backend status port.
Definition: mythcorecontext.cpp:1098
MythCoreContext::OverrideSettingForSession
void OverrideSettingForSession(const QString &key, const QString &value)
Definition: mythcorecontext.cpp:1347
MDBManager
DB connection pool, used by MSqlQuery. Do not use directly.
Definition: mythdbcon.h:54
MythCoreContextPrivate::m_backend
bool m_backend
Definition: mythcorecontext.cpp:90
MythLocale::ToQLocale
QLocale ToQLocale() const
Definition: mythlocale.h:29
MythCoreContext::s_serverPortCache
static QHash< QString, int > s_serverPortCache
Definition: mythcorecontext.h:185
MythEvent
This class is used as a container for messages.
Definition: mythevent.h:16
MythCoreContextPrivate::m_appBinaryVersion
QString m_appBinaryVersion
Definition: mythcorecontext.cpp:72
sched
Scheduler * sched
MythCoreContext::RegisterFileForWrite
void RegisterFileForWrite(const QString &file, uint64_t size=0LL)
Definition: mythcorecontext.cpp:2132
MythCoreContext::IsDatabaseIgnored
bool IsDatabaseIgnored(void) const
/brief Returns true if database is being ignored.
Definition: mythcorecontext.cpp:882
MythCoreContext::GetGUIObject
QObject * GetGUIObject(void)
Definition: mythcorecontext.cpp:1753
MythCoreContext::GetFilePrefix
QString GetFilePrefix(void)
Definition: mythcorecontext.cpp:850
MythCoreContext::IsUIThread
bool IsUIThread(void)
Definition: mythcorecontext.cpp:1358
MythCoreContext::connectionClosed
void connectionClosed(MythSocket *sock) override
Definition: mythcorecontext.cpp:1663
MythSocket::DisconnectFromHost
void DisconnectFromHost(void)
Definition: mythsocket.cpp:498
MythCoreContext::CheckProtoVersion
bool CheckProtoVersion(MythSocket *socket, std::chrono::milliseconds timeout=kMythSocketLongTimeout, bool error_dialog_desired=false)
Definition: mythcorecontext.cpp:1671
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
is_current_thread
bool is_current_thread(MThread *thread)
Use this to determine if you are in the named thread.
Definition: mthread.cpp:40
MythCoreContextPrivate::m_blockingClient
bool m_blockingClient
Definition: mythcorecontext.cpp:103
GetMythDB
MythDB * GetMythDB(void)
Definition: mythdb.cpp:51
MythCoreContext::TestPluginVersion
static bool TestPluginVersion(const QString &name, const QString &libversion, const QString &pluginversion)
Definition: mythcorecontext.cpp:2089
build_compdb.file
file
Definition: build_compdb.py:55
MythCoreContextPrivate::m_intvwanting
bool m_intvwanting
Definition: mythcorecontext.cpp:108
MythObservable::dispatch
void dispatch(const MythEvent &event)
Dispatch an event to all listeners.
Definition: mythobservable.cpp:73
myth_system
uint myth_system(const QString &command, uint flags, std::chrono::seconds timeout)
Definition: mythsystemlegacy.cpp:506
MythCoreContext::GetScopeForAddress
bool GetScopeForAddress(QHostAddress &addr) const
Return the cached scope Id for the given address.
Definition: mythcorecontext.cpp:1115
MythSocket::ConnectToHost
bool ConnectToHost(const QString &hostname, quint16 port)
connect to host
Definition: mythsocket.cpp:374
MythCoreContext::setTestStringSettings
void setTestStringSettings(QMap< QString, QString > &overrides)
Definition: mythcorecontext.cpp:299
MythCoreContext::InitPower
void InitPower(bool Create=true)
Definition: mythcorecontext.cpp:1847
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:37
MythCoreContext::ResetAudioLanguage
void ResetAudioLanguage(void)
Definition: mythcorecontext.cpp:1831
MythEvent::Message
const QString & Message() const
Definition: mythevent.h:65
MythSocket::IsConnected
bool IsConnected(void) const
Definition: mythsocket.cpp:551
MythCoreContextPrivate::m_wolInProgressWaitCondition
QWaitCondition m_wolInProgressWaitCondition
Definition: mythcorecontext.cpp:86
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:999
tmp
static guint32 * tmp
Definition: goom_core.cpp:26
MythCoreContextPrivate::m_scopesLock
QMutex m_scopesLock
Locking for m_masterHostname.
Definition: mythcorecontext.cpp:78
mythsystemlegacy.h
SendAsyncMessage::SendAsyncMessage
SendAsyncMessage(QString msg, QStringList extra)
Definition: mythcorecontext.cpp:1507
MythCoreContext::SendHostSystemEvent
void SendHostSystemEvent(const QString &msg, const QString &hostname, const QString &args)
Definition: mythcorecontext.cpp:1563
MythCoreContextPrivate::m_pluginmanager
MythPluginManager * m_pluginmanager
Definition: mythcorecontext.cpp:112
LOC
#define LOC
Definition: mythcorecontext.cpp:55
MythSocket
Class for communcating between myth backends and frontends.
Definition: mythsocket.h:25
MythCoreContext::ClearOverrideSettingForSession
void ClearOverrideSettingForSession(const QString &key)
Definition: mythcorecontext.cpp:1353
MythCoreContext::IsConnectedToMaster
bool IsConnectedToMaster(void)
Definition: mythcorecontext.cpp:596
MythCoreContext::MythCoreContext
MythCoreContext(const QString &binversion, QObject *guiContext)
Definition: mythcorecontext.cpp:216
quit
@ quit
Definition: lirc_client.h:30
MythCoreContext::GetAudioLanguageAndVariant
QString GetAudioLanguageAndVariant(void)
Returns the user-set audio language and variant.
Definition: mythcorecontext.cpp:1818
MThreadPool::ShutdownAllPools
static void ShutdownAllPools(void)
Definition: mthreadpool.cpp:326
MythCoreContext::UnregisterForPlayback
void UnregisterForPlayback(QObject *sender)
Definition: mythcorecontext.cpp:1968
MythCoreContext::IsRegisteredFileForWrite
bool IsRegisteredFileForWrite(const QString &file)
Definition: mythcorecontext.cpp:2167
MythCoreContext::IsMasterBackend
bool IsMasterBackend(void)
is this the actual MBE process
Definition: mythcorecontext.cpp:701
MythCoreContextPrivate::m_playbackLock
QMutex m_playbackLock
Definition: mythcorecontext.cpp:106
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:222
MythCoreContext::GenMythURL
static QString GenMythURL(const QString &host=QString(), int port=0, QString path=QString(), const QString &storageGroup=QString())
Definition: mythcorecontext.cpp:766
MythCoreContext::GetGUIContext
QObject * GetGUIContext(void)
Definition: mythcorecontext.cpp:1758
MythCoreContext::GetQLocale
QLocale GetQLocale(void)
Definition: mythcorecontext.cpp:1884
MythCoreContext::BackendIsRunning
static bool BackendIsRunning(void)
a backend process is running on this host
Definition: mythcorecontext.cpp:706
MythSocket::WriteStringList
bool WriteStringList(const QStringList &list)
Definition: mythsocket.cpp:301
MythCoreContext::SetAsFrontend
void SetAsFrontend(bool frontend)
Definition: mythcorecontext.cpp:655
MThreadPool::StopAllPools
static void StopAllPools(void)
Definition: mthreadpool.cpp:315
MythCoreContext::GetBackendServerPort
int GetBackendServerPort(void)
Returns the locally defined backend control port.
Definition: mythcorecontext.cpp:1070
MythCoreContext::SendSystemEvent
void SendSystemEvent(const QString &msg)
Definition: mythcorecontext.cpp:1554
MythCoreContextPrivate::m_isexiting
bool m_isexiting
Definition: mythcorecontext.cpp:114
MythCoreContext::SendEvent
void SendEvent(const MythEvent &event)
Definition: mythcorecontext.cpp:1540
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:972
MythCoreContext::WaitUntilSignals
void WaitUntilSignals(std::vector< CoreWaitInfo > &sigs) const
Wait until any of the provided signals have been received.
Definition: mythcorecontext.cpp:1924
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
GENERIC_EXIT_OK
@ GENERIC_EXIT_OK
Exited with no error.
Definition: exitcodes.h:13
compat.h
MythPower::AcquireRelease
static MythPower * AcquireRelease(void *Reference, bool Acquire, std::chrono::seconds MinimumDelay=0s)
Definition: mythpower.cpp:72
MythCoreContext::GetBackendServerIP
QString GetBackendServerIP(void)
Returns the IP address of the locally defined backend IP.
Definition: mythcorecontext.cpp:1010
MythCoreContextPrivate::m_sessionManager
MythSessionManager * m_sessionManager
Definition: mythcorecontext.cpp:119
MythCoreContext::IsFrontend
bool IsFrontend(void) const
is this process a frontend process
Definition: mythcorecontext.cpp:660
MythCoreContextPrivate::m_guiObject
QObject * m_guiObject
Definition: mythcorecontext.cpp:71
MythCoreContext::GetDB
MythDB * GetDB(void)
Definition: mythcorecontext.cpp:1763
MythCoreContext::readyRead
void readyRead(MythSocket *sock) override
Definition: mythcorecontext.cpp:1571
MythWakeup
bool MythWakeup(const QString &wakeUpCommand, uint flags, std::chrono::seconds timeout)
Definition: mythmiscutil.cpp:630
MythCoreContext::GetNumSettingOnHost
int GetNumSettingOnHost(const QString &key, const QString &host, int defaultval=0)
Definition: mythcorecontext.cpp:949
MythCoreContextPrivate::m_approvedIps
QList< QHostAddress > m_approvedIps
Definition: mythcorecontext.cpp:121
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:855
MythCoreContext::RegisterForPlayback
void RegisterForPlayback(QObject *sender, PlaybackStartCb method)
Definition: mythcorecontext.cpp:1947
MythCoreContext::GetBackendServerIP4
QString GetBackendServerIP4(void)
Returns the IPv4 address defined for the current host see GetBackendServerIP4(host)
Definition: mythcorecontext.cpp:1033
MythCoreContext::ResolveIPv6
@ ResolveIPv6
Definition: mythcorecontext.h:190
MythCoreContext::m_testOverrideStrings
QMap< QString, QString > m_testOverrideStrings
Definition: mythcorecontext.h:303
SendAsyncMessage::m_message
QString m_message
Definition: mythcorecontext.cpp:1523
MythCoreContext::TVPlaybackAboutToStart
void TVPlaybackAboutToStart(void)
MythSocket::kShortTimeout
static constexpr std::chrono::milliseconds kShortTimeout
Definition: mythsocket.h:70
SendAsyncMessage
Definition: mythcorecontext.cpp:1504
MythCoreContext::ConnectCommandSocket
MythSocket * ConnectCommandSocket(const QString &hostname, int port, const QString &announcement, bool *proto_mismatch=nullptr, int maxConnTry=-1, std::chrono::milliseconds setup_timeout=-1ms)
Definition: mythcorecontext.cpp:433
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:1524
MythCoreContextPrivate::~MythCoreContextPrivate
~MythCoreContextPrivate() override
Definition: mythcorecontext.cpp:157
MythCoreContext::ConnectEventSocket
MythSocket * ConnectEventSocket(const QString &hostname, int port)
Definition: mythcorecontext.cpp:551
MythCoreContext::GetLanguage
QString GetLanguage(void)
Returns two character ISO-639 language descriptor for UI language.
Definition: mythcorecontext.cpp:1777
MythCoreContext::GetNumSetting
int GetNumSetting(const QString &key, int defaultval=0)
Definition: mythcorecontext.cpp:918
logStop
void logStop(void)
Entry point for stopping logging for an application.
Definition: logging.cpp:685
mythappname.h
MythLocale::SaveLocaleDefaults
void SaveLocaleDefaults(bool overwrite=false)
Definition: mythlocale.cpp:173
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:1198
MythCoreContextPrivate::m_audioLanguage
QString m_audioLanguage
Definition: mythcorecontext.cpp:99
MythCoreContext::SetLocalHostname
void SetLocalHostname(const QString &hostname)
Definition: mythcorecontext.cpp:1736
MythCoreContextPrivate::m_locale
MythLocale * m_locale
Definition: mythcorecontext.cpp:97
SendAsyncMessage::run
void run(void) override
Definition: mythcorecontext.cpp:1514
MythCoreContext::GetBoolSetting
bool GetBoolSetting(const QString &key, bool defaultval=false)
Definition: mythcorecontext.cpp:912
MYTH_APPNAME_MYTHTV_SETUP
static constexpr const char * MYTH_APPNAME_MYTHTV_SETUP
Definition: mythappname.h:7
mthreadpool.h
MythEvent::ExtraDataList
const QStringList & ExtraDataList() const
Definition: mythevent.h:67
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:986
MythCoreContextPrivate::m_playbackClients
QMap< QObject *, MythCoreContext::PlaybackStartCb > m_playbackClients
Definition: mythcorecontext.cpp:105
MythCoreContext::InWantingPlayback
bool InWantingPlayback(void)
Returns true if a client has requested playback.
Definition: mythcorecontext.cpp:2065
MythCoreContext
This class contains the runtime context for MythTV.
Definition: mythcorecontext.h:41
mythmiscutil.h
MythCoreContext::setTestIntSettings
void setTestIntSettings(QMap< QString, int > &overrides)
Definition: mythcorecontext.cpp:289
mythcorecontext.h
MythCoreContext::m_testOverrideFloats
QMap< QString, double > m_testOverrideFloats
Definition: mythcorecontext.h:302
MythCoreContextPrivate::m_announcedProtocol
bool m_announcedProtocol
Definition: mythcorecontext.cpp:110
MythCoreContext::IsBackend
bool IsBackend(void) const
is this process a backend process
Definition: mythcorecontext.cpp:650
kLinkLocal
static QPair< QHostAddress, int > kLinkLocal
Definition: serverpool.cpp:27
MythCoreContextPrivate::m_masterHostname
QString m_masterHostname
master backend hostname
Definition: mythcorecontext.cpp:77
MythCoreContext::ResetLanguage
void ResetLanguage(void)
Definition: mythcorecontext.cpp:1797
MythCoreContext::GetSettingOnHost
QString GetSettingOnHost(const QString &key, const QString &host, const QString &defaultval="")
Definition: mythcorecontext.cpp:932
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:39
MythCoreContext::GetLanguageAndVariant
QString GetLanguageAndVariant(void)
Returns the user-set language and variant.
Definition: mythcorecontext.cpp:1789
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:557
MythCoreContextPrivate::m_inwanting
bool m_inwanting
Definition: mythcorecontext.cpp:107
MythCoreContext::ClearBackendServerPortCache
static void ClearBackendServerPortCache()
Definition: mythcorecontext.cpp:1077
logging.h
mthread.h
MythCoreContext::ResolveIPv4
@ ResolveIPv4
Definition: mythcorecontext.h:190
MythCoreContext::TVInWantingPlayback
void TVInWantingPlayback(bool b)
Let the TV class tell us if we was interrupted following a call to WantingPlayback().
Definition: mythcorecontext.cpp:2053
MythCoreContext::d
MythCoreContextPrivate * d
Definition: mythcorecontext.h:294
MythCoreContextPrivate::m_uiThread
QThread * m_uiThread
Definition: mythcorecontext.cpp:95
SendAsyncMessage::SendAsyncMessage
SendAsyncMessage(QString msg)
Definition: mythcorecontext.cpp:1512
MythCoreContext::ActivateSettingsCache
void ActivateSettingsCache(bool activate=true)
Definition: mythcorecontext.cpp:839
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:142
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:27
MythCoreContext::WantingPlayback
void WantingPlayback(QObject *sender)
All the objects that have registered using MythCoreContext::RegisterForPlayback but sender will be ca...
Definition: mythcorecontext.cpp:1987
ShutdownMythSystemLegacy
void MBASE_PUBLIC ShutdownMythSystemLegacy(void)
Definition: mythsystemunix.cpp:74
MythCoreContext::GetHostName
QString GetHostName(void)
Definition: mythcorecontext.cpp:844
MythCoreContextPrivate::m_scheduler
MythScheduler * m_scheduler
Definition: mythcorecontext.cpp:101
MythCoreContext::ReInitLocale
void ReInitLocale(void)
Definition: mythcorecontext.cpp:1871
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:221
MythCoreContextPrivate::m_deniedIps
QList< QHostAddress > m_deniedIps
Definition: mythcorecontext.cpp:122
MythCoreContext::IsExiting
bool IsExiting(void)
Definition: mythcorecontext.cpp:2127
azlyrics.info
dictionary info
Definition: azlyrics.py:7
MythCoreContext::GetBoolSettingOnHost
bool GetBoolSettingOnHost(const QString &key, const QString &host, bool defaultval=false)
Definition: mythcorecontext.cpp:941
MythCoreContext::ClearSettingsCache
void ClearSettingsCache(const QString &myKey=QString(""))
Definition: mythcorecontext.cpp:834
MythCoreContext::IsThisHost
bool IsThisHost(const QString &addr)
is this address mapped to this host
Definition: mythcorecontext.cpp:727
MythCoreContext::HasGUI
bool HasGUI(void) const
Definition: mythcorecontext.cpp:1748
MythCoreContext::IsMasterHost
bool IsMasterHost(void)
is this the same host as the master
Definition: mythcorecontext.cpp:665
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:602
MythCoreContext::IsWOLAllowed
bool IsWOLAllowed() const
Definition: mythcorecontext.cpp:640
MythCoreContext::GetFloatSetting
double GetFloatSetting(const QString &key, double defaultval=0.0)
Definition: mythcorecontext.cpp:925
kMSDontDisableDrawing
@ kMSDontDisableDrawing
avoid disabling UI drawing
Definition: mythsystem.h:37
MythCoreContextPrivate::m_fileslock
QMutex m_fileslock
Definition: mythcorecontext.cpp:117
MythCoreContext::SaveSetting
void SaveSetting(const QString &key, int newValue)
Definition: mythcorecontext.cpp:887
MythCoreContext::GetMasterHostPrefix
QString GetMasterHostPrefix(const QString &storageGroup=QString(), const QString &path=QString())
Definition: mythcorecontext.cpp:804
MythCoreContext::GetSessionManager
MythSessionManager * GetSessionManager(void)
Definition: mythcorecontext.cpp:2081
exitcodes.h
mythdownloadmanager.h
MythCoreContext::GetBackendServerIP6
QString GetBackendServerIP6(void)
Returns the IPv6 address defined for the current host see GetBackendServerIP6(host)
Definition: mythcorecontext.cpp:1052
delete_sock
static void delete_sock(QMutexLocker< QMutex > &locker, MythSocket **s)
Definition: mythcorecontext.cpp:139
MThreadPool::globalInstance
static MThreadPool * globalInstance(void)
Definition: mthreadpool.cpp:307
MythCoreContext::GetPluginManager
MythPluginManager * GetPluginManager(void)
Definition: mythcorecontext.cpp:2117
MythCoreContext::SetScopeForAddress
void SetScopeForAddress(const QHostAddress &addr)
Record the scope Id of the given IP address.
Definition: mythcorecontext.cpp:1135
MythSocket::kLongTimeout
static constexpr std::chrono::milliseconds kLongTimeout
Definition: mythsocket.h:71
MythCoreContext::SetupCommandSocket
bool SetupCommandSocket(MythSocket *serverSock, const QString &announcement, std::chrono::milliseconds timeout, bool &proto_mismatch)
Definition: mythcorecontext.cpp:304
MythCoreContext::CheckSubnet
bool CheckSubnet(const QAbstractSocket *socket)
Check if a socket is connected to an approved peer.
Definition: mythcorecontext.cpp:1278
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:1892
MythCoreContext::dispatch
void dispatch(const MythEvent &event)
Definition: mythcorecontext.cpp:1729
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:897
MythSocket::ReadStringList
bool ReadStringList(QStringList &list, std::chrono::milliseconds timeoutMS=kShortTimeout)
Definition: mythsocket.cpp:313
MythCoreContext::SetAsBackend
void SetAsBackend(bool backend)
Definition: mythcorecontext.cpp:645
MythCoreContext::m_testOverrideInts
QMap< QString, int > m_testOverrideInts
Definition: mythcorecontext.h:301
MythCoreContext::PlaybackStartCb
void(QObject::*)(void) PlaybackStartCb
Definition: mythcorecontext.h:222
MythCoreContext::IsThisBackend
bool IsThisBackend(const QString &addr)
is this address mapped to this backend host
Definition: mythcorecontext.cpp:722
MythCoreContext::setTestFloatSettings
void setTestFloatSettings(QMap< QString, double > &overrides)
Definition: mythcorecontext.cpp:294
MythCoreContext::GetFloatSettingOnHost
double GetFloatSettingOnHost(const QString &key, const QString &host, double defaultval=0.0)
Definition: mythcorecontext.cpp:958
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:2122
MythCoreContext::ResolveType
ResolveType
Definition: mythcorecontext.h:190
MythCoreContext::SetGUIObject
void SetGUIObject(QObject *gui)
Definition: mythcorecontext.cpp:1743
MythSocket::SendReceiveStringList
bool SendReceiveStringList(QStringList &list, uint min_reply_length=0, std::chrono::milliseconds timeoutMS=kLongTimeout)
Definition: mythsocket.cpp:326
MythCoreContextPrivate::m_power
MythPower * m_power
Definition: mythcorecontext.cpp:124
MythCoreContextPrivate::MythCoreContextPrivate
MythCoreContextPrivate(MythCoreContext *lparent, QString binversion, QObject *guicontext)
Definition: mythcorecontext.cpp:127
uint
unsigned int uint
Definition: freesurround.h:24
MythCoreContext::GetSetting
QString GetSetting(const QString &key, const QString &defaultval="")
Definition: mythcorecontext.cpp:904
MythSessionManager
Definition: mythsession.h:104