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