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