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 <QDateTime>
19 
20 // Std
21 #include <algorithm>
22 #include <cmath>
23 #include <cstdarg>
24 #include <queue>
25 #include <unistd.h> // for usleep()
26 
27 #ifdef _WIN32
28 #include <winsock2.h>
29 #else
30 #include <clocale>
31 #include <utility>
32 #endif
33 
34 // MythTV
35 #include "compat.h"
36 #include "mythdownloadmanager.h"
37 #include "mythcorecontext.h"
38 #include "mythsocket.h"
39 #include "mythsystemlegacy.h"
40 #include "mthreadpool.h"
41 #include "exitcodes.h"
42 #include "mythlogging.h"
43 #include "mythversion.h"
44 #include "logging.h"
45 #include "mthread.h"
46 #include "serverpool.h"
47 #include "mythdate.h"
48 #include "mythplugin.h"
49 #include "mythmiscutil.h"
50 #include "mythpower.h"
51 #include "configuration.h"
52 
53 #define LOC QString("MythCoreContext::%1(): ").arg(__func__)
54 
57 
58 class MythCoreContextPrivate : public QObject
59 {
60  public:
61  MythCoreContextPrivate(MythCoreContext *lparent, QString binversion,
62  QObject *guicontext);
63  ~MythCoreContextPrivate() override;
64 
65  bool WaitForWOL(std::chrono::milliseconds timeout = std::chrono::milliseconds::max());
66 
67  public:
68  MythCoreContext *m_parent { nullptr };
69  QObject *m_guiContext { nullptr };
70  QObject *m_guiObject { nullptr };
72 
73  QMutex m_localHostLock;
74  QString m_localHostname;
76  QString m_masterHostname;
77  QMutex m_scopesLock;
78  QMap<QString, QString> m_scopes;
79 
80  QMutex m_sockLock;
81  MythSocket *m_serverSock { nullptr };
82  MythSocket *m_eventSock { nullptr };
83 
86  bool m_wolInProgress { false };
87  bool m_isWOLAllowed { true };
88 
89  bool m_backend { false };
90  bool m_frontend { false };
91 
92  MythDB *m_database { nullptr };
93 
94  QThread *m_uiThread { nullptr };
95 
96  MythLocale *m_locale { nullptr };
97  QString m_language;
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 
229  {
230  LOG(VB_GENERAL, LOG_CRIT,
231  QString("Application binary version (%1) does not "
232  "match libraries (%2)")
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  QString lang_variables("");
245  QString lc_value = setlocale(LC_CTYPE, nullptr);
246  if (lc_value.isEmpty())
247  {
248  // try fallback to environment variables for non-glibc systems
249  // LC_ALL, then LC_CTYPE
250  lc_value = qEnvironmentVariable("LC_ALL");
251  if (lc_value.isEmpty())
252  lc_value = qEnvironmentVariable("LC_CTYPE");
253  }
254  if (!lc_value.contains("UTF-8", Qt::CaseInsensitive))
255  lang_variables.append("LC_ALL or LC_CTYPE");
256  lc_value = qEnvironmentVariable("LANG");
257  if (!lc_value.contains("UTF-8", Qt::CaseInsensitive))
258  {
259  if (!lang_variables.isEmpty())
260  lang_variables.append(", and ");
261  lang_variables.append("LANG");
262  }
263  LOG(VB_GENERAL, LOG_INFO, QString("Assumed character encoding: %1")
264  .arg(lc_value));
265  if (!lang_variables.isEmpty())
266  {
267  LOG(VB_GENERAL, LOG_WARNING, QString("This application expects to "
268  "be running a locale that specifies a UTF-8 codeset, and many "
269  "features may behave improperly with your current language "
270  "settings. Please set the %1 variable(s) in the environment "
271  "in which this program is executed to include a UTF-8 codeset "
272  "(such as 'en_US.UTF-8').").arg(lang_variables));
273  }
274 #endif
275 
276  return true;
277 }
278 
280 {
281  delete d;
282  d = nullptr;
283 }
284 
285 void MythCoreContext::setTestIntSettings(QMap<QString,int> &overrides)
286 {
287  m_testOverrideInts = std::move(overrides);
288 }
289 
290 void MythCoreContext::setTestFloatSettings(QMap<QString,double> &overrides)
291 {
292  m_testOverrideFloats = std::move(overrides);
293 }
294 
295 void MythCoreContext::setTestStringSettings(QMap<QString,QString> &overrides)
296 {
297  m_testOverrideStrings = std::move(overrides);
298 }
299 
301  const QString &announcement,
302  std::chrono::milliseconds timeout,
303  bool &proto_mismatch)
304 {
305  proto_mismatch = false;
306 
307 #ifndef IGNORE_PROTO_VER_MISMATCH
308  if (!CheckProtoVersion(serverSock, timeout, true))
309  {
310  proto_mismatch = true;
311  return false;
312  }
313 #else
314  Q_UNUSED(timeout);
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 = IsFrontend() ? "Frontend" : (blockingClient ? "Playback" : "Monitor");
387  QString ann = QString("ANN %1 %2 %3")
388  .arg(type, d->m_localHostname, QString::number(static_cast<int>(false)));
390  server, port, ann, &proto_mismatch);
391  }
392 
393  if (!d->m_serverSock)
394  return false;
395 
396  d->m_blockingClient = blockingClient;
397 
398  if (!openEventSocket)
399  return true;
400 
401 
402  if (!IsBackend())
403  {
404  if (d->m_eventSock && !d->m_eventSock->IsConnected())
405  {
406  d->m_eventSock->DecrRef();
407  d->m_eventSock = nullptr;
408  }
409  if (!d->m_eventSock)
410  d->m_eventSock = ConnectEventSocket(server, port);
411 
412  if (!d->m_eventSock)
413  {
414  d->m_serverSock->DecrRef();
415  d->m_serverSock = nullptr;
416 
417  QCoreApplication::postEvent(
418  d->m_guiContext, new MythEvent("CONNECTION_FAILURE"));
419 
420  return false;
421  }
422  }
423 
424  return true;
425 }
426 
428  const QString &hostname, int port, const QString &announce,
429  bool *p_proto_mismatch, int maxConnTry, std::chrono::milliseconds setup_timeout)
430 {
431  MythSocket *serverSock = nullptr;
432 
433  {
434  QMutexLocker locker(&d->m_wolInProgressLock);
435  d->WaitForWOL();
436  }
437 
438  QString WOLcmd;
439  if (IsWOLAllowed())
440  WOLcmd = GetSetting("WOLbackendCommand", "");
441 
442  if (maxConnTry < 1)
443  maxConnTry = std::max(GetNumSetting("BackendConnectRetry", 1), 1);
444 
445  std::chrono::seconds WOLsleepTime = 0s;
446  int WOLmaxConnTry = 0;
447  if (!WOLcmd.isEmpty())
448  {
449  WOLsleepTime = GetDurSetting<std::chrono::seconds>("WOLbackendReconnectWaitTime", 0s);
450  WOLmaxConnTry = std::max(GetNumSetting("WOLbackendConnectRetry", 1), 1);
451  maxConnTry = std::max(maxConnTry, WOLmaxConnTry);
452  }
453 
454  bool we_attempted_wol = false;
455 
456  if (setup_timeout <= 0ms)
457  setup_timeout = MythSocket::kShortTimeout;
458 
459  bool proto_mismatch = false;
460  for (int cnt = 1; cnt <= maxConnTry; cnt++)
461  {
462  LOG(VB_GENERAL, LOG_INFO, LOC +
463  QString("Connecting to backend server: %1:%2 (try %3 of %4)")
464  .arg(hostname).arg(port).arg(cnt).arg(maxConnTry));
465 
466  serverSock = new MythSocket();
467 
468  std::chrono::microseconds sleepus = 0us;
469  if (serverSock->ConnectToHost(hostname, port))
470  {
471  if (SetupCommandSocket(
472  serverSock, announce, setup_timeout, proto_mismatch))
473  {
474  break;
475  }
476 
477  if (proto_mismatch)
478  {
479  if (p_proto_mismatch)
480  *p_proto_mismatch = true;
481 
482  serverSock->DecrRef();
483  serverSock = nullptr;
484  break;
485  }
486 
487  setup_timeout += setup_timeout / 2;
488  }
489  else if (!WOLcmd.isEmpty() && (cnt < maxConnTry))
490  {
491  if (!we_attempted_wol)
492  {
493  QMutexLocker locker(&d->m_wolInProgressLock);
494  if (d->m_wolInProgress)
495  {
496  d->WaitForWOL();
497  continue;
498  }
499 
500  d->m_wolInProgress = we_attempted_wol = true;
501  }
502 
505  sleepus = WOLsleepTime;
506  }
507 
508  serverSock->DecrRef();
509  serverSock = nullptr;
510 
511  if (cnt == 1)
512  {
513  QCoreApplication::postEvent(
514  d->m_guiContext, new MythEvent("CONNECTION_FAILURE"));
515  }
516 
517  if (sleepus != 0us)
518  usleep(sleepus.count());
519  }
520 
521  if (we_attempted_wol)
522  {
523  QMutexLocker locker(&d->m_wolInProgressLock);
524  d->m_wolInProgress = false;
525  d->m_wolInProgressWaitCondition.wakeAll();
526  }
527 
528  if (!serverSock && !proto_mismatch)
529  {
530  LOG(VB_GENERAL, LOG_ERR,
531  "Connection to master server timed out.\n\t\t\t"
532  "Either the server is down or the master server settings"
533  "\n\t\t\t"
534  "in mythtv-settings does not contain the proper IP address\n");
535  }
536  else
537  {
538  QCoreApplication::postEvent(
539  d->m_guiContext, new MythEvent("CONNECTION_RESTABLISHED"));
540  }
541 
542  return serverSock;
543 }
544 
546  int port)
547 {
548  auto *eventSock = new MythSocket(-1, this);
549 
550  // Assume that since we _just_ connected the command socket,
551  // this one won't need multiple retries to work...
552  if (!eventSock->ConnectToHost(hostname, port))
553  {
554  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to connect event "
555  "socket to master backend");
556  eventSock->DecrRef();
557  return nullptr;
558  }
559 
560  QString str = QString("ANN Monitor %1 %2")
561  .arg(d->m_localHostname).arg(static_cast<int>(true));
562  QStringList strlist(str);
563  eventSock->WriteStringList(strlist);
564  bool ok = true;
565  if (!eventSock->ReadStringList(strlist) || strlist.empty() ||
566  (strlist[0] == "ERROR"))
567  {
568  if (!strlist.empty())
569  {
570  LOG(VB_GENERAL, LOG_ERR, LOC +
571  "Problem connecting event socket to master backend");
572  }
573  else
574  {
575  LOG(VB_GENERAL, LOG_ERR, LOC +
576  "Timeout connecting event socket to master backend");
577  }
578  ok = false;
579  }
580 
581  if (!ok)
582  {
583  eventSock->DecrRef();
584  eventSock = nullptr;
585  }
586 
587  return eventSock;
588 }
589 
591 {
592  QMutexLocker locker(&d->m_sockLock);
593  return d->m_serverSock;
594 }
595 
597 {
598  QStringList strlist;
599 
600  QMutexLocker locker(&d->m_sockLock);
601  if (d->m_serverSock == nullptr)
602  return;
603 
604  strlist << "BLOCK_SHUTDOWN";
606 
607  d->m_blockingClient = true;
608 }
609 
611 {
612  QStringList strlist;
613 
614  QMutexLocker locker(&d->m_sockLock);
615  if (d->m_serverSock == nullptr)
616  return;
617 
618  strlist << "ALLOW_SHUTDOWN";
620 
621  d->m_blockingClient = false;
622 }
623 
625 {
626  return d->m_blockingClient;
627 }
628 
630 {
631  d->m_isWOLAllowed = allow;
632 }
633 
635 {
636  return d->m_isWOLAllowed;
637 }
638 
640 {
641  d->m_backend = backend;
642 }
643 
645 {
646  return d->m_backend;
647 }
648 
650 {
651  d->m_frontend = frontend;
652 }
653 
655 {
656  return d->m_frontend;
657 }
658 
660 {
661  QString host = GetHostName();
662  return IsMasterHost(host);
663 }
664 
665 bool MythCoreContext::IsMasterHost(const QString &host)
666 {
667  // Temporary code here only to facilitate the upgrade
668  // from 1346 or earlier. The way of determining master host is
669  // changing, and the new way of determning master host
670  // will not work with earlier databases.
671  // This code can be removed when updating from prior to
672  // 1347 is no longer allowed.
673  // Note that we are deprecating some settings including
674  // MasterServerIP, and can remove them at a future time.
675  if (GetNumSetting("DBSchemaVer") < 1347)
676  {
677  // Temporary copy of code from old version of
678  // IsThisHost(Qstring&,QString&)
679  QString addr(resolveSettingAddress("MasterServerIP"));
680  if (addr.toLower() == host.toLower())
681  return true;
682  QHostAddress addrfix(addr);
683  addrfix.setScopeId(QString());
684  QString addrstr = addrfix.toString();
685  if (addrfix.isNull())
686  addrstr = resolveAddress(addr);
687  QString thisip = GetBackendServerIP4(host);
688  QString thisip6 = GetBackendServerIP6(host);
689  return !addrstr.isEmpty()
690  && ((addrstr == thisip) || (addrstr == thisip6));
691  }
692  return GetSetting("MasterServerName") == host;
693 }
694 
696 {
697  return (IsBackend() && IsMasterHost());
698 }
699 
701 {
702 #if defined(Q_OS_DARWIN) || defined(__FreeBSD__) || defined(__OpenBSD__)
703  const char *command = "ps -axc | grep -i mythbackend | grep -v grep > /dev/null";
704 #elif defined _WIN32
705  const char *command = "%systemroot%\\system32\\tasklist.exe "
706  " | %systemroot%\\system32\\find.exe /i \"mythbackend.exe\" ";
707 #else
708  const char *command = "ps ch -C mythbackend -o pid > /dev/null";
709 #endif
710  uint res = myth_system(command, kMSDontBlockInputDevs |
713  return (res == GENERIC_EXIT_OK);
714 }
715 
716 bool MythCoreContext::IsThisBackend(const QString &addr)
717 {
718  return IsBackend() && IsThisHost(addr);
719 }
720 
721 bool MythCoreContext::IsThisHost(const QString &addr)
722 {
723  return IsThisHost(addr, GetHostName());
724 }
725 
726 bool MythCoreContext::IsThisHost(const QString &addr, const QString &host)
727 {
728  if (addr.toLower() == host.toLower())
729  return true;
730 
731  QHostAddress addrfix(addr);
732  addrfix.setScopeId(QString());
733  QString addrstr = addrfix.toString();
734 
735  if (addrfix.isNull())
736  {
737  addrstr = resolveAddress(addr);
738  }
739 
740  QString thisip = GetBackendServerIP(host);
741 
742  return !addrstr.isEmpty() && ((addrstr == thisip));
743 }
744 
746 {
747  // find out if a backend runs on this host...
748  bool backendOnLocalhost = false;
749 
750  QStringList strlist("QUERY_IS_ACTIVE_BACKEND");
751  strlist << GetHostName();
752 
753  SendReceiveStringList(strlist);
754 
755  backendOnLocalhost = strlist[0] != "FALSE";
756 
757  return !backendOnLocalhost;
758 }
759 
760 QString MythCoreContext::GenMythURL(const QString& host, int port, QString path, const QString& storageGroup)
761 {
762  QUrl ret;
763 
764  QString m_host;
765 
766  QHostAddress addr(host);
767  if (!addr.isNull())
768  {
769  LOG(VB_GENERAL, LOG_CRIT, LOC + QString("(%1/%2): Given "
770  "IP address instead of hostname "
771  "(ID). This is invalid.").arg(host, path));
772  }
773 
774  m_host = host;
775 
776  // Basically if it appears to be an IPv6 IP surround the IP with [] otherwise don't bother
777  if (!addr.isNull() && addr.protocol() == QAbstractSocket::IPv6Protocol)
778  m_host = "[" + addr.toString().toLower() + "]";
779 
780  ret.setScheme("myth");
781  if (!storageGroup.isEmpty())
782  ret.setUserName(storageGroup);
783  ret.setHost(m_host);
784  if (port > 0 && port != 6543)
785  ret.setPort(port);
786  if (!path.startsWith("/"))
787  path = QString("/") + path;
788  ret.setPath(path);
789 
790 #if 0
791  LOG(VB_GENERAL, LOG_DEBUG, LOC +
792  QString("GenMythURL returning %1").arg(ret.toString()));
793 #endif
794 
795  return ret.toString();
796 }
797 
798 QString MythCoreContext::GetMasterHostPrefix(const QString &storageGroup,
799  const QString &path)
800 {
801  return GenMythURL(GetMasterHostName(),
803  path,
804  storageGroup);
805 }
806 
808 {
809  QMutexLocker locker(&d->m_masterHostLock);
810 
811  if (d->m_masterHostname.isEmpty())
812  {
813 
814  if (IsMasterBackend())
816  else
817  {
818  QStringList strlist("QUERY_HOSTNAME");
819 
820  if (SendReceiveStringList(strlist))
821  d->m_masterHostname = strlist[0];
822  }
823  }
824 
825  return d->m_masterHostname;
826 }
827 
828 void MythCoreContext::ClearSettingsCache(const QString &myKey)
829 {
830  d->m_database->ClearSettingsCache(myKey);
831 }
832 
834 {
835  d->m_database->ActivateSettingsCache(activate);
836 }
837 
839 {
840  QMutexLocker locker(&d->m_localHostLock);
841  return d->m_localHostname;
842 }
843 
845 {
846  return GetSetting("RecordFilePrefix");
847 }
848 
850  int &width, int &height,
851  double &forced_aspect,
852  double &refresh_rate,
853  int index)
854 {
855  d->m_database->GetResolutionSetting(type, width, height, forced_aspect,
856  refresh_rate, index);
857 }
858 
859 void MythCoreContext::GetResolutionSetting(const QString &t, int &w,
860  int &h, int i)
861 {
862  d->m_database->GetResolutionSetting(t, w, h, i);
863 }
864 
866 {
867  return d->m_database->GetDBManager();
868 }
869 
877 {
878  return d->m_database->IsDatabaseIgnored();
879 }
880 
881 void MythCoreContext::SaveSetting(const QString &key, int newValue)
882 {
883  d->m_database->SaveSetting(key, newValue);
884 }
885 
886 void MythCoreContext::SaveSetting(const QString &key, const QString &newValue)
887 {
888  d->m_database->SaveSetting(key, newValue);
889 }
890 
891 bool MythCoreContext::SaveSettingOnHost(const QString &key,
892  const QString &newValue,
893  const QString &host)
894 {
895  return d->m_database->SaveSettingOnHost(key, newValue, host);
896 }
897 
898 QString MythCoreContext::GetSetting(const QString &key,
899  const QString &defaultval)
900 {
901  if (!m_testOverrideStrings.empty())
902  return m_testOverrideStrings[key];
903  return d->m_database->GetSetting(key, defaultval);
904 }
905 
906 bool MythCoreContext::GetBoolSetting(const QString &key, bool defaultval)
907 {
908  int result = GetNumSetting(key, static_cast<int>(defaultval));
909  return result > 0;
910 }
911 
912 int MythCoreContext::GetNumSetting(const QString &key, int defaultval)
913 {
914  if (!m_testOverrideInts.empty())
915  return m_testOverrideInts[key];
916  return d->m_database->GetNumSetting(key, defaultval);
917 }
918 
919 double MythCoreContext::GetFloatSetting(const QString &key, double defaultval)
920 {
921  if (!m_testOverrideFloats.empty())
922  return m_testOverrideFloats[key];
923  return d->m_database->GetFloatSetting(key, defaultval);
924 }
925 
926 QString MythCoreContext::GetSettingOnHost(const QString &key,
927  const QString &host,
928  const QString &defaultval)
929 {
930  if (!m_testOverrideStrings.empty())
931  return m_testOverrideStrings[key];
932  return d->m_database->GetSettingOnHost(key, host, defaultval);
933 }
934 
936  const QString &host,
937  bool defaultval)
938 {
939  int result = GetNumSettingOnHost(key, host, static_cast<int>(defaultval));
940  return result > 0;
941 }
942 
944  const QString &host,
945  int defaultval)
946 {
947  if (!m_testOverrideInts.empty())
948  return m_testOverrideInts[key];
949  return d->m_database->GetNumSettingOnHost(key, host, defaultval);
950 }
951 
952 double MythCoreContext::GetFloatSettingOnHost(const QString &key,
953  const QString &host,
954  double defaultval)
955 {
956  if (!m_testOverrideFloats.empty())
957  return m_testOverrideFloats[key];
958  return d->m_database->GetFloatSettingOnHost(key, host, defaultval);
959 }
960 
967 {
968  QString masterserver = gCoreContext->GetSetting("MasterServerName");
969  QString masterip = resolveSettingAddress("BackendServerAddr",masterserver);
970  // Even if empty, return it here if we were to assume that localhost
971  // should be used it just causes a lot of unnecessary error messages.
972  return masterip;
973 }
974 
981 {
982  QString masterserver = gCoreContext->GetSetting
983  ("MasterServerName");
985  ("BackendServerPort", masterserver, 6543);
986 }
987 
994 {
995  QString masterhost = GetMasterHostName();
996 
997  return GetBackendStatusPort(masterhost);
998 }
999 
1005 {
1007 }
1008 
1018 QString MythCoreContext::GetBackendServerIP(const QString &host)
1019 {
1020  return resolveSettingAddress("BackendServerAddr",host);
1021 }
1022 
1028 {
1030 }
1031 
1037 QString MythCoreContext::GetBackendServerIP4(const QString &host)
1038 {
1039  return resolveSettingAddress("BackendServerIP", host, ResolveIPv4);
1040 }
1041 
1047 {
1049 }
1050 
1056 QString MythCoreContext::GetBackendServerIP6(const QString &host)
1057 {
1058  return resolveSettingAddress("BackendServerIP6", host, ResolveIPv6);
1059 }
1060 
1065 {
1067 }
1068 
1069 QHash<QString,int> MythCoreContext::s_serverPortCache;
1070 
1072 {
1073  s_serverPortCache.clear();
1074 }
1075 
1080 {
1081  int port = s_serverPortCache.value(host, -1);
1082  if (port != -1)
1083  return port;
1084  port = GetNumSettingOnHost("BackendServerPort", host, 6543);
1085  s_serverPortCache[host] = port;
1086  return port;
1087 }
1088 
1093 {
1095 }
1096 
1101 {
1102  return GetNumSettingOnHost("BackendStatusPort", host, 6544);
1103 }
1104 
1109 bool MythCoreContext::GetScopeForAddress(QHostAddress &addr) const
1110 {
1111  QHostAddress addr1 = addr;
1112  addr1.setScopeId(QString());
1113  QString addrstr = addr1.toString();
1114  QMutexLocker lock(&d->m_scopesLock);
1115 
1116  if (!d->m_scopes.contains(addrstr))
1117  return false;
1118 
1119  addr.setScopeId(d->m_scopes[addrstr]);
1120  return true;
1121 }
1122 
1129 void MythCoreContext::SetScopeForAddress(const QHostAddress &addr)
1130 {
1131  QHostAddress addr1 = addr;
1132  addr1.setScopeId(QString());
1133  QMutexLocker lock(&d->m_scopesLock);
1134 
1135  d->m_scopes.insert(addr1.toString(), addr.scopeId());
1136 }
1137 
1143 void MythCoreContext::SetScopeForAddress(const QHostAddress &addr, int scope)
1144 {
1145  QHostAddress addr1 = addr;
1146  addr1.setScopeId(QString());
1147  QMutexLocker lock(&d->m_scopesLock);
1148 
1149  d->m_scopes.insert(addr1.toString(), QString::number(scope));
1150 }
1151 
1163 QString MythCoreContext::resolveSettingAddress(const QString &name,
1164  const QString &host,
1165  ResolveType type, bool keepscope)
1166 {
1167  QString value;
1168 
1169  if (host.isEmpty())
1170  {
1171  value = GetSetting(name);
1172  }
1173  else
1174  {
1175  value = GetSettingOnHost(name, host);
1176  }
1177 
1178  return resolveAddress(value, type, keepscope);
1179 }
1180 
1192 QString MythCoreContext::resolveAddress(const QString &host, ResolveType type,
1193  bool keepscope)
1194 {
1195  QHostAddress addr(host);
1196 
1197  if (!host.isEmpty() && addr.isNull())
1198  {
1199  // address is likely a hostname, attempts to resolve it
1200  QHostInfo info = QHostInfo::fromName(host);
1201  QList<QHostAddress> list = info.addresses();
1202 
1203  if (list.isEmpty())
1204  {
1205  LOG(VB_GENERAL, LOG_WARNING, LOC +
1206  QString("Can't resolve hostname:'%1', using localhost").arg(host));
1207  return type == ResolveIPv4 ? "127.0.0.1" : "::1";
1208  }
1209  QHostAddress v4;
1210  QHostAddress v6;
1211 
1212  // Return the first address fitting the type critera
1213  for (const auto& item : qAsConst(list))
1214  {
1215  addr = item;
1216  QAbstractSocket::NetworkLayerProtocol prot = addr.protocol();
1217 
1218  if (prot == QAbstractSocket::IPv4Protocol)
1219  {
1220  v4 = addr;
1221  if (type == 0)
1222  break;
1223  }
1224  else if (prot == QAbstractSocket::IPv6Protocol)
1225  {
1226  v6 = addr;
1227  if (type != 0)
1228  break;
1229  }
1230  }
1231  switch (type)
1232  {
1233  case ResolveIPv4:
1234  addr = v4.isNull() ? QHostAddress::LocalHost : v4;
1235  break;
1236  case ResolveIPv6:
1237  addr = v6.isNull() ? QHostAddress::LocalHostIPv6 : v6;
1238  break;
1239  default:
1240  addr = v6.isNull() ?
1241  (v4.isNull() ? QHostAddress::LocalHostIPv6 : v4) : v6;
1242  break;
1243  }
1244  }
1245  else if (host.isEmpty())
1246  {
1247  return {};
1248  }
1249 
1250  if (!keepscope)
1251  {
1252  addr.setScopeId(QString());
1253  }
1254  return addr.toString();
1255 }
1256 
1268 bool MythCoreContext::CheckSubnet(const QAbstractSocket *socket)
1269 {
1270  QHostAddress peer = socket->peerAddress();
1271  return CheckSubnet(peer);
1272 }
1273 
1285 bool MythCoreContext::CheckSubnet(const QHostAddress &peer)
1286 {
1287  static const QHostAddress kLinkLocal("fe80::");
1288  if (GetBoolSetting("AllowConnFromAll",false))
1289  return true;
1290  if (d->m_approvedIps.contains(peer))
1291  return true;
1292  if (d->m_deniedIps.contains(peer))
1293  {
1294  LOG(VB_GENERAL, LOG_WARNING, LOC +
1295  QString("Repeat denied connection from ip address: %1")
1296  .arg(peer.toString()));
1297  return false;
1298  }
1299 
1300  // allow all link-local
1301  if (peer.isInSubnet(kLinkLocal,10))
1302  {
1303  d->m_approvedIps.append(peer);
1304  return true;
1305  }
1306 
1307  // loop through all available interfaces
1308  QList<QNetworkInterface> IFs = QNetworkInterface::allInterfaces();
1309  for (const auto & qni : qAsConst(IFs))
1310  {
1311  if ((qni.flags() & QNetworkInterface::IsRunning) == 0)
1312  continue;
1313 
1314  QList<QNetworkAddressEntry> IPs = qni.addressEntries();
1315  for (const auto & qnai : qAsConst(IPs))
1316  {
1317  int pfxlen = qnai.prefixLength();
1318  // Set this to test rejection without having an extra
1319  // network.
1320  if (GetBoolSetting("DebugSubnet"))
1321  pfxlen += 4;
1322  if (peer.isInSubnet(qnai.ip(),pfxlen))
1323  {
1324  d->m_approvedIps.append(peer);
1325  return true;
1326  }
1327  }
1328  }
1329  d->m_deniedIps.append(peer);
1330  LOG(VB_GENERAL, LOG_WARNING, LOC +
1331  QString("Denied connection from ip address: %1")
1332  .arg(peer.toString()));
1333  return false;
1334 }
1335 
1336 
1338  const QString &value)
1339 {
1340  d->m_database->OverrideSettingForSession(key, value);
1341 }
1342 
1344 {
1345  d->m_database->ClearOverrideSettingForSession(key);
1346 }
1347 
1349 {
1350  return is_current_thread(d->m_uiThread);
1351 }
1352 
1372  QStringList &strlist, bool quickTimeout, bool block)
1373 {
1374  QString msg;
1375  if (HasGUI() && IsUIThread())
1376  {
1377  msg = "SendReceiveStringList(";
1378  for (uint i=0; i<(uint)strlist.size() && i<2; i++)
1379  msg += (i?",":"") + strlist[i];
1380  msg += (strlist.size() > 2) ? "...)" : ")";
1381  LOG(VB_GENERAL, LOG_DEBUG, LOC + msg + " called from UI thread");
1382  }
1383 
1384  QString query_type = "UNKNOWN";
1385 
1386  if (!strlist.isEmpty())
1387  query_type = strlist[0];
1388 
1389  QMutexLocker locker(&d->m_sockLock);
1390  if (!d->m_serverSock)
1391  {
1392  bool blockingClient = d->m_blockingClient &&
1393  (GetNumSetting("idleTimeoutSecs",0) > 0);
1394  ConnectToMasterServer(blockingClient);
1395  }
1396 
1397  bool ok = false;
1398 
1399  if (d->m_serverSock)
1400  {
1401  std::chrono::milliseconds timeout = quickTimeout ?
1403  ok = d->m_serverSock->SendReceiveStringList(strlist, 0, timeout);
1404 
1405  if (!ok)
1406  {
1407  LOG(VB_GENERAL, LOG_NOTICE, LOC +
1408  QString("Connection to backend server lost"));
1409  d->m_serverSock->DecrRef();
1410  d->m_serverSock = nullptr;
1411 
1412  if (d->m_eventSock)
1413  {
1414  d->m_eventSock->DecrRef();
1415  d->m_eventSock = nullptr;
1416  }
1417 
1418  if (block)
1419  {
1421 
1422  if (d->m_serverSock)
1423  {
1425  strlist, 0, timeout);
1426  }
1427  }
1428  }
1429 
1430  // this should not happen
1431  while (ok && strlist[0] == "BACKEND_MESSAGE")
1432  {
1433  // oops, not for us
1434  LOG(VB_GENERAL, LOG_EMERG, LOC + "SRSL you shouldn't see this!!");
1435  QString message = strlist[1];
1436  strlist.pop_front(); strlist.pop_front();
1437 
1438  MythEvent me(message, strlist);
1439  dispatch(me);
1440 
1441  ok = d->m_serverSock->ReadStringList(strlist, timeout);
1442  }
1443 
1444  if (!ok)
1445  {
1446  if (d->m_serverSock)
1447  {
1448  d->m_serverSock->DecrRef();
1449  d->m_serverSock = nullptr;
1450  }
1451 
1452  LOG(VB_GENERAL, LOG_CRIT, LOC +
1453  QString("Reconnection to backend server failed"));
1454 
1455  QCoreApplication::postEvent(d->m_guiContext,
1456  new MythEvent("PERSISTENT_CONNECTION_FAILURE"));
1457  }
1458  }
1459 
1460  if (ok)
1461  {
1462  if (strlist.isEmpty())
1463  ok = false;
1464  else if (strlist[0] == "ERROR")
1465  {
1466  if (strlist.size() == 2)
1467  {
1468  LOG(VB_GENERAL, LOG_INFO, LOC +
1469  QString("Protocol query '%1' responded with the error '%2'")
1470  .arg(query_type, strlist[1]));
1471  }
1472  else
1473  {
1474  LOG(VB_GENERAL, LOG_INFO, LOC +
1475  QString("Protocol query '%1' responded with an error, but "
1476  "no error message.") .arg(query_type));
1477  }
1478 
1479  ok = false;
1480  }
1481  else if (strlist[0] == "UNKNOWN_COMMAND")
1482  {
1483  LOG(VB_GENERAL, LOG_ERR, LOC +
1484  QString("Protocol query '%1' responded with the error 'UNKNOWN_COMMAND'")
1485  .arg(query_type));
1486 
1487  ok = false;
1488  }
1489  }
1490 
1491  return ok;
1492 }
1493 
1494 class SendAsyncMessage : public QRunnable
1495 {
1496  public:
1497  SendAsyncMessage(QString msg, QStringList extra) :
1498  m_message(std::move(msg)), m_extraData(std::move(extra))
1499  {
1500  }
1501 
1502  explicit SendAsyncMessage(QString msg) : m_message(std::move(msg)) { }
1503 
1504  void run(void) override // QRunnable
1505  {
1506  QStringList strlist("MESSAGE");
1507  strlist << m_message;
1508  strlist << m_extraData;
1510  }
1511 
1512  private:
1513  QString m_message;
1514  QStringList m_extraData;
1515 };
1516 
1517 void MythCoreContext::SendMessage(const QString &message)
1518 {
1519  if (IsBackend())
1520  {
1521  dispatch(MythEvent(message));
1522  }
1523  else
1524  {
1526  new SendAsyncMessage(message), "SendMessage");
1527  }
1528 }
1529 
1531 {
1532  if (IsBackend())
1533  {
1534  dispatch(event);
1535  }
1536  else
1537  {
1539  new SendAsyncMessage(event.Message(), event.ExtraDataList()),
1540  "SendEvent");
1541  }
1542 }
1543 
1544 void MythCoreContext::SendSystemEvent(const QString &msg)
1545 {
1546  if (QCoreApplication::applicationName() == MYTH_APPNAME_MYTHTV_SETUP)
1547  return;
1548 
1549  SendMessage(QString("SYSTEM_EVENT %1 SENDER %2")
1550  .arg(msg, GetHostName()));
1551 }
1552 
1554  const QString &hostname,
1555  const QString &args)
1556 {
1557  SendSystemEvent(QString("%1 HOST %2 %3").arg(msg, hostname, args));
1558 }
1559 
1560 
1562 {
1563  do
1564  {
1565  QStringList strlist;
1566  if (!sock->ReadStringList(strlist))
1567  continue;
1568 
1569  if (strlist.size() < 2)
1570  continue;
1571 
1572  QString prefix = strlist[0];
1573  QString message = strlist[1];
1574 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
1575  QStringList tokens = message.split(" ", QString::SkipEmptyParts);
1576 #else
1577  QStringList tokens = message.split(" ", Qt::SkipEmptyParts);
1578 #endif
1579 
1580  if (prefix == "OK")
1581  {
1582  }
1583  else if (prefix != "BACKEND_MESSAGE")
1584  {
1585  LOG(VB_NETWORK, LOG_ERR, LOC +
1586  QString("Received a: %1 message from the backend "
1587  "but I don't know what to do with it.")
1588  .arg(prefix));
1589  }
1590  else if (message == "CLEAR_SETTINGS_CACHE")
1591  {
1592  // No need to dispatch this message to ourself, so handle it
1593  LOG(VB_NETWORK, LOG_INFO, LOC + "Received remote 'Clear Cache' request");
1595  }
1596  else if (message.startsWith("FILE_WRITTEN"))
1597  {
1598  QString file;
1599  uint64_t size = 0;
1600  int NUMTOKENS = 3; // Number of tokens expected
1601 
1602  if (tokens.size() == NUMTOKENS)
1603  {
1604  file = tokens[1];
1605  size = tokens[2].toULongLong();
1606  }
1607  else
1608  {
1609  LOG(VB_NETWORK, LOG_ERR, LOC +
1610  QString("FILE_WRITTEN event received "
1611  "with invalid number of arguments, "
1612  "%1 expected, %2 actual")
1613  .arg(NUMTOKENS-1)
1614  .arg(tokens.size()-1));
1615  return;
1616  }
1617  // No need to dispatch this message to ourself, so handle it
1618  LOG(VB_NETWORK, LOG_INFO, LOC +
1619  QString("Received remote 'FILE_WRITTEN %1' request").arg(file));
1620  RegisterFileForWrite(file, size);
1621  }
1622  else if (message.startsWith("FILE_CLOSED"))
1623  {
1624  QString file;
1625  int NUMTOKENS = 2; // Number of tokens expected
1626 
1627  if (tokens.size() == NUMTOKENS)
1628  {
1629  file = tokens[1];
1630  }
1631  else
1632  {
1633  LOG(VB_NETWORK, LOG_ERR, LOC +
1634  QString("FILE_CLOSED event received "
1635  "with invalid number of arguments, "
1636  "%1 expected, %2 actual")
1637  .arg(NUMTOKENS-1)
1638  .arg(tokens.size()-1));
1639  return;
1640  }
1641  // No need to dispatch this message to ourself, so handle it
1642  LOG(VB_NETWORK, LOG_INFO, LOC +
1643  QString("Received remote 'FILE_CLOSED %1' request").arg(file));
1645  }
1646  else
1647  {
1648  strlist.pop_front();
1649  strlist.pop_front();
1650  MythEvent me(message, strlist);
1651  dispatch(me);
1652  }
1653  }
1654  while (sock->IsDataAvailable());
1655 }
1656 
1658 {
1659  (void)sock;
1660 
1661  LOG(VB_GENERAL, LOG_NOTICE, LOC +
1662  "Event socket closed. No connection to the backend.");
1663 
1664  dispatch(MythEvent("BACKEND_SOCKETS_CLOSED"));
1665 }
1666 
1668  std::chrono::milliseconds timeout,
1669  bool error_dialog_desired)
1670 {
1671  if (!socket)
1672  return false;
1673 
1674  QStringList strlist(QString("MYTH_PROTO_VERSION %1 %2")
1675  .arg(MYTH_PROTO_VERSION,
1676  QString::fromUtf8(MYTH_PROTO_TOKEN)));
1677  socket->WriteStringList(strlist);
1678 
1679  if (!socket->ReadStringList(strlist, timeout) || strlist.empty())
1680  {
1681  LOG(VB_GENERAL, LOG_CRIT, "Protocol version check failure.\n\t\t\t"
1682  "The response to MYTH_PROTO_VERSION was empty.\n\t\t\t"
1683  "This happens when the backend is too busy to respond,\n\t\t\t"
1684  "or has deadlocked due to bugs or hardware failure.");
1685 
1686  return false;
1687  }
1688  if (strlist[0] == "REJECT" && strlist.size() >= 2)
1689  {
1690  LOG(VB_GENERAL, LOG_CRIT, LOC + QString("Protocol version or token mismatch "
1691  "(frontend=%1/%2,backend=%3/\?\?)\n")
1692  .arg(MYTH_PROTO_VERSION,
1693  QString::fromUtf8(MYTH_PROTO_TOKEN),
1694  strlist[1]));
1695 
1696  if (error_dialog_desired && d->m_guiContext)
1697  {
1698  QStringList list(strlist[1]);
1699  QCoreApplication::postEvent(
1700  d->m_guiContext, new MythEvent("VERSION_MISMATCH", list));
1701  }
1702 
1703  return false;
1704  }
1705  if (strlist[0] == "ACCEPT")
1706  {
1707  if (!d->m_announcedProtocol)
1708  {
1709  d->m_announcedProtocol = true;
1710  LOG(VB_GENERAL, LOG_INFO, LOC +
1711  QString("Using protocol version %1 %2")
1712  .arg(MYTH_PROTO_VERSION,
1713  QString::fromUtf8(MYTH_PROTO_TOKEN)));
1714  }
1715 
1716  return true;
1717  }
1718 
1719  LOG(VB_GENERAL, LOG_ERR, LOC +
1720  QString("Unexpected response to MYTH_PROTO_VERSION: %1")
1721  .arg(strlist[0]));
1722  return false;
1723 }
1724 
1726 {
1727  LOG(VB_NETWORK, LOG_INFO, LOC + QString("MythEvent: %1").arg(event.Message()));
1728 
1729  MythObservable::dispatch(event);
1730 }
1731 
1733 {
1734  QMutexLocker locker(&d->m_localHostLock);
1736  d->m_database->SetLocalHostname(hostname);
1737 }
1738 
1740 {
1741  d->m_guiObject = gui;
1742 }
1743 
1744 bool MythCoreContext::HasGUI(void) const
1745 {
1746  return d->m_guiObject;
1747 }
1748 
1750 {
1751  return d->m_guiObject;
1752 }
1753 
1755 {
1756  return d->m_guiContext;
1757 }
1758 
1760 {
1761  return d->m_database;
1762 }
1763 
1765 {
1766  return d->m_locale;
1767 }
1768 
1774 {
1775  return GetLanguageAndVariant().left(2);
1776 }
1777 
1786 {
1787  if (d->m_language.isEmpty())
1788  d->m_language = GetSetting("Language", "en_US").toLower();
1789 
1790  return d->m_language;
1791 }
1792 
1794 {
1795  d->m_language.clear();
1796 }
1797 
1799 {
1800  QMutexLocker locker(&d->m_sockLock);
1801  LOG(VB_GENERAL, LOG_INFO, "Restarting Backend Connections");
1802  if (d->m_serverSock)
1804  if (d->m_eventSock)
1806  dispatch(MythEvent("BACKEND_SOCKETS_CLOSED"));
1807 }
1808 
1810 {
1811  delete g_pConfig;
1812  g_pConfig = pConfig;
1813 }
1814 
1816 {
1817  // If someone is asking for a config and it's nullptr, create a
1818  // new XmlConfiguration since we don't have database info yet.
1819 
1820  if (g_pConfig == nullptr)
1821  g_pConfig = new XmlConfiguration( "config.xml" );
1822 
1823  return g_pConfig;
1824 }
1825 
1827 {
1828  if (Create && !d->m_power)
1829  {
1831  }
1832  else if (!Create && d->m_power)
1833  {
1834  MythPower::AcquireRelease(d, false);
1835  d->m_power = nullptr;
1836  }
1837 }
1838 
1840 {
1841  if (!d->m_locale)
1842  d->m_locale = new MythLocale();
1843 
1844  QString localeCode = d->m_locale->GetLocaleCode();
1845  LOG(VB_GENERAL, LOG_NOTICE, QString("Setting QT default locale to %1")
1846  .arg(localeCode));
1847  QLocale::setDefault(d->m_locale->ToQLocale());
1848 }
1849 
1851 {
1852  if (!d->m_locale)
1853  d->m_locale = new MythLocale();
1854  else
1855  d->m_locale->ReInit();
1856 
1857  QString localeCode = d->m_locale->GetLocaleCode();
1858  LOG(VB_GENERAL, LOG_NOTICE, QString("Setting QT default locale to %1")
1859  .arg(localeCode));
1860  QLocale::setDefault(d->m_locale->ToQLocale());
1861 }
1862 
1864 {
1865  if (!d->m_locale)
1866  InitLocale();
1867 
1868  return d->m_locale->ToQLocale();
1869 }
1870 
1872 {
1873  if (!d->m_locale)
1874  InitLocale();
1875 
1876  if (!d->m_locale->GetLocaleCode().isEmpty())
1877  {
1878  LOG(VB_GENERAL, LOG_INFO,
1879  QString("Current locale %1") .arg(d->m_locale->GetLocaleCode()));
1880 
1882  return;
1883  }
1884 
1885  LOG(VB_GENERAL, LOG_ERR, LOC +
1886  "No locale defined! We weren't able to set locale defaults.");
1887 }
1888 
1890 {
1891  d->m_scheduler = sched;
1892 }
1893 
1895 {
1896  return d->m_scheduler;
1897 }
1898 
1903 void MythCoreContext::WaitUntilSignals(std::vector<CoreWaitInfo> & sigs) const
1904 {
1905  if (sigs.empty())
1906  return;
1907 
1908  QEventLoop eventLoop;
1909  for (auto s : sigs)
1910  {
1911  LOG(VB_GENERAL, LOG_DEBUG, LOC +
1912  QString("Waiting for signal %1")
1913  .arg(s.name));
1914  connect(this, s.fn, &eventLoop, &QEventLoop::quit);
1915  }
1916 
1917  eventLoop.exec(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers);
1918 }
1919 
1927 {
1928  if (!sender || !method)
1929  return;
1930 
1931  QMutexLocker lock(&d->m_playbackLock);
1932 
1933  if (!d->m_playbackClients.contains(sender))
1934  {
1935  d->m_playbackClients.insert(sender, method);
1937  sender, method,
1938  Qt::BlockingQueuedConnection);
1939  }
1940 }
1941 
1948 {
1949  QMutexLocker lock(&d->m_playbackLock);
1950 
1951  if (d->m_playbackClients.contains(sender))
1952  {
1953  PlaybackStartCb method = d->m_playbackClients.value(sender);
1954  disconnect(this, &MythCoreContext::TVPlaybackAboutToStart,
1955  sender, method);
1956  d->m_playbackClients.remove(sender);
1957  }
1958 }
1959 
1967 {
1968  QMutexLocker lock(&d->m_playbackLock);
1969  PlaybackStartCb method { nullptr };
1970  d->m_inwanting = true;
1971 
1972  // If any registered client are in the same thread, they will deadlock, so rebuild
1973  // connections for any clients in the same thread as non-blocking connection
1974  QThread *currentThread = QThread::currentThread();
1975 
1976  QMap<QObject *, PlaybackStartCb>::iterator it = d->m_playbackClients.begin();
1977  for (; it != d->m_playbackClients.end(); ++it)
1978  {
1979  if (it.key() == sender)
1980  continue; // will be done separately, no need to do it again
1981 
1982  QThread *thread = it.key()->thread();
1983 
1984  if (thread != currentThread)
1985  continue;
1986 
1987  disconnect(this, &MythCoreContext::TVPlaybackAboutToStart, it.key(), it.value());
1988  connect(this, &MythCoreContext::TVPlaybackAboutToStart, it.key(), it.value());
1989  }
1990 
1991  // disconnect sender so it won't receive the message
1992  if (d->m_playbackClients.contains(sender))
1993  {
1994  method = d->m_playbackClients.value(sender);
1995  disconnect(this, &MythCoreContext::TVPlaybackAboutToStart, sender, method);
1996  }
1997 
1998  // emit signal
1999  emit TVPlaybackAboutToStart();
2000 
2001  // reconnect sender
2002  if (method)
2003  {
2005  sender, method,
2006  Qt::BlockingQueuedConnection);
2007  }
2008  // Restore blocking connections
2009  for (; it != d->m_playbackClients.end(); ++it)
2010  {
2011  if (it.key() == sender)
2012  continue; // already done above, no need to do it again
2013 
2014  QThread *thread = it.key()->thread();
2015 
2016  if (thread != currentThread)
2017  continue;
2018 
2019  disconnect(this, &MythCoreContext::TVPlaybackAboutToStart,
2020  it.key(), it.value());
2022  it.key(), it.value(), Qt::BlockingQueuedConnection);
2023  }
2024  d->m_inwanting = false;
2025 }
2026 
2033 {
2034  // when called, it will be while the m_playbackLock is held
2035  // following a call to WantingPlayback
2036  d->m_intvwanting = b;
2037 }
2038 
2045 {
2046  bool locked = d->m_playbackLock.tryLock();
2047  bool intvplayback = d->m_intvwanting;
2048 
2049  if (!locked && d->m_inwanting)
2050  return true; // we're in the middle of WantingPlayback
2051 
2052  if (!locked)
2053  return false;
2054 
2055  d->m_playbackLock.unlock();
2056 
2057  return intvplayback;
2058 }
2059 
2061 {
2062  if (!d->m_sessionManager)
2064 
2065  return d->m_sessionManager;
2066 }
2067 
2068 bool MythCoreContext::TestPluginVersion(const QString &name,
2069  const QString &libversion,
2070  const QString &pluginversion)
2071 {
2072  if (libversion == pluginversion)
2073  return true;
2074 
2075  LOG(VB_GENERAL, LOG_EMERG, LOC +
2076  QString("Plugin %1 (%2) binary version does not "
2077  "match libraries (%3)")
2078  .arg(name, pluginversion, libversion));
2079  return false;
2080 }
2081 
2083 {
2084  if (d->m_pluginmanager == pmanager)
2085  return;
2086 
2087  if (d->m_pluginmanager)
2088  {
2089  delete d->m_pluginmanager;
2090  d->m_pluginmanager = nullptr;
2091  }
2092 
2093  d->m_pluginmanager = pmanager;
2094 }
2095 
2097 {
2098  return d->m_pluginmanager;
2099 }
2100 
2102 {
2103  d->m_isexiting = exiting;
2104 }
2105 
2107 {
2108  return d->m_isexiting;
2109 }
2110 
2111 void MythCoreContext::RegisterFileForWrite(const QString& file, uint64_t size)
2112 {
2113  QMutexLocker lock(&d->m_fileslock);
2114 
2115  QPair<int64_t, uint64_t> pair(QDateTime::currentMSecsSinceEpoch(), size);
2116  d->m_fileswritten.insert(file, pair);
2117 
2118  if (IsBackend())
2119  {
2120  QString message = QString("FILE_WRITTEN %1 %2").arg(file).arg(size);
2121  MythEvent me(message);
2122  dispatch(me);
2123  }
2124 
2125  LOG(VB_FILE, LOG_DEBUG, LOC +
2126  QString("%1").arg(file));
2127 }
2128 
2130 {
2131  QMutexLocker lock(&d->m_fileslock);
2132 
2133  d->m_fileswritten.remove(file);
2134 
2135  if (IsBackend())
2136  {
2137  QString message = QString("FILE_CLOSED %1").arg(file);
2138  MythEvent me(message);
2139  dispatch(me);
2140  }
2141 
2142  LOG(VB_FILE, LOG_DEBUG, LOC +
2143  QString("%1").arg(file));
2144 }
2145 
2147 {
2148  QMutexLocker lock(&d->m_fileslock);
2149 
2150  return d->m_fileswritten.contains(file);
2151 }
2152 
2153 /* 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:1163
MythCoreContext::SetPluginManager
void SetPluginManager(MythPluginManager *pmanager)
Definition: mythcorecontext.cpp:2082
loggingDeregisterThread
void loggingDeregisterThread(void)
Deregister the current thread's name.
Definition: logging.cpp:751
MythCoreContext::SetWOLAllowed
void SetWOLAllowed(bool allow)
Definition: mythcorecontext.cpp:629
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:199
MythCoreContext::SendMessage
void SendMessage(const QString &message)
Definition: mythcorecontext.cpp:1517
hardwareprofile.smolt.timeout
float timeout
Definition: smolt.py:103
MythCoreContext::GetMasterHostName
QString GetMasterHostName(void)
Definition: mythcorecontext.cpp:807
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: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:1894
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:1371
MythCoreContext::IsBlockingClient
bool IsBlockingClient(void) const
is this client blocking shutdown
Definition: mythcorecontext.cpp:624
MythCoreContext::IsFrontendOnly
bool IsFrontendOnly(void)
is there a frontend, but no backend, running on this host
Definition: mythcorecontext.cpp:745
MythCoreContext::AllowShutdown
void AllowShutdown(void)
Definition: mythcorecontext.cpp:610
MythCoreContextPrivate::m_masterHostLock
QMutex m_masterHostLock
Locking for m_masterHostname.
Definition: mythcorecontext.cpp:75
MythCoreContext::ResetSockets
void ResetSockets(void)
Definition: mythcorecontext.cpp:1798
MythLocale
Definition: mythlocale.h:12
MythCoreContext::GetDBManager
MDBManager * GetDBManager(void)
Definition: mythcorecontext.cpp:865
MythCoreContext::UnregisterFileForWrite
void UnregisterFileForWrite(const QString &file)
Definition: mythcorecontext.cpp:2129
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:82
MythCoreContext::GetLocale
MythLocale * GetLocale(void) const
Definition: mythcorecontext.cpp:1764
MythCoreContext::~MythCoreContext
~MythCoreContext() override
Definition: mythcorecontext.cpp:279
mythplugin.h
MythCoreContext::InitLocale
void InitLocale(void)
Definition: mythcorecontext.cpp:1839
ShutdownMythDownloadManager
void ShutdownMythDownloadManager(void)
Deletes the running MythDownloadManager at program exit.
Definition: mythdownloadmanager.cpp:133
MythCoreContext::SetScheduler
void SetScheduler(MythScheduler *sched)
Definition: mythcorecontext.cpp:1889
MythCoreContext::GetBackendStatusPort
int GetBackendStatusPort(void)
Returns the locally defined backend status port.
Definition: mythcorecontext.cpp:1092
MythCoreContext::OverrideSettingForSession
void OverrideSettingForSession(const QString &key, const QString &value)
Definition: mythcorecontext.cpp:1337
MDBManager
DB connection pool, used by MSqlQuery. Do not use directly.
Definition: mythdbcon.h:55
MythCoreContextPrivate::m_backend
bool m_backend
Definition: mythcorecontext.cpp:89
MythLocale::ToQLocale
QLocale ToQLocale() const
Definition: mythlocale.h:29
MythCoreContext::s_serverPortCache
static QHash< QString, int > s_serverPortCache
Definition: mythcorecontext.h:211
MythEvent
This class is used as a container for messages.
Definition: mythevent.h:16
MythCoreContextPrivate::m_appBinaryVersion
QString m_appBinaryVersion
Definition: mythcorecontext.cpp:71
sched
Scheduler * sched
MythCoreContext::RegisterFileForWrite
void RegisterFileForWrite(const QString &file, uint64_t size=0LL)
Definition: mythcorecontext.cpp:2111
MythCoreContext::IsDatabaseIgnored
bool IsDatabaseIgnored(void) const
/brief Returns true if database is being ignored.
Definition: mythcorecontext.cpp:876
MythCoreContext::GetGUIObject
QObject * GetGUIObject(void)
Definition: mythcorecontext.cpp:1749
MythCoreContext::GetFilePrefix
QString GetFilePrefix(void)
Definition: mythcorecontext.cpp:844
MythCoreContext::IsUIThread
bool IsUIThread(void)
Definition: mythcorecontext.cpp:1348
MythCoreContext::connectionClosed
void connectionClosed(MythSocket *sock) override
Definition: mythcorecontext.cpp:1657
MythSocket::DisconnectFromHost
void DisconnectFromHost(void)
Definition: mythsocket.cpp:504
MythCoreContext::CheckProtoVersion
bool CheckProtoVersion(MythSocket *socket, std::chrono::milliseconds timeout=kMythSocketLongTimeout, bool error_dialog_desired=false)
Definition: mythcorecontext.cpp:1667
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:2068
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
GENERIC_EXIT_OK
@ GENERIC_EXIT_OK
Exited with no error.
Definition: exitcodes.h:11
MythCoreContext::GetScopeForAddress
bool GetScopeForAddress(QHostAddress &addr) const
Return the cached scope Id for the given address.
Definition: mythcorecontext.cpp:1109
MythSocket::ConnectToHost
bool ConnectToHost(const QString &hostname, quint16 port)
connect to host
Definition: mythsocket.cpp:380
MythCoreContext::setTestStringSettings
void setTestStringSettings(QMap< QString, QString > &overrides)
Definition: mythcorecontext.cpp:295
MythCoreContext::InitPower
void InitPower(bool Create=true)
Definition: mythcorecontext.cpp:1826
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
MythEvent::Message
const QString & Message() const
Definition: mythevent.h:65
MythSocket::IsConnected
bool IsConnected(void) const
Definition: mythsocket.cpp:557
MythCoreContextPrivate::m_wolInProgressWaitCondition
QWaitCondition m_wolInProgressWaitCondition
Definition: mythcorecontext.cpp:85
MythCoreContextPrivate::m_database
MythDB * m_database
Definition: mythcorecontext.cpp:92
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:993
XmlConfiguration
Definition: configuration.h:60
tmp
static guint32 * tmp
Definition: goom_core.cpp:26
MythCoreContextPrivate::m_scopesLock
QMutex m_scopesLock
Locking for m_masterHostname.
Definition: mythcorecontext.cpp:77
mythversion.h
mythsystemlegacy.h
SendAsyncMessage::SendAsyncMessage
SendAsyncMessage(QString msg, QStringList extra)
Definition: mythcorecontext.cpp:1497
MYTH_APPNAME_MYTHTV_SETUP
static constexpr const char * MYTH_APPNAME_MYTHTV_SETUP
Definition: mythcorecontext.h:25
MythCoreContext::SendHostSystemEvent
void SendHostSystemEvent(const QString &msg, const QString &hostname, const QString &args)
Definition: mythcorecontext.cpp:1553
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:1343
MythCoreContext::IsConnectedToMaster
bool IsConnectedToMaster(void)
Definition: mythcorecontext.cpp:590
MythCoreContext::MythCoreContext
MythCoreContext(const QString &binversion, QObject *guiContext)
Definition: mythcorecontext.cpp:214
quit
@ quit
Definition: lirc_client.h:30
MYTH_PROTO_VERSION
static constexpr const char * MYTH_PROTO_VERSION
Increment this whenever the MythTV network protocol changes.
Definition: mythversion.h:47
MThreadPool::ShutdownAllPools
static void ShutdownAllPools(void)
Definition: mthreadpool.cpp:336
MythCoreContext::UnregisterForPlayback
void UnregisterForPlayback(QObject *sender)
Definition: mythcorecontext.cpp:1947
MythCoreContext::IsRegisteredFileForWrite
bool IsRegisteredFileForWrite(const QString &file)
Definition: mythcorecontext.cpp:2146
MythCoreContext::IsMasterBackend
bool IsMasterBackend(void)
is this the actual MBE process
Definition: mythcorecontext.cpp:695
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:74
MythCoreContextPrivate::m_isWOLAllowed
bool m_isWOLAllowed
Definition: mythcorecontext.cpp:87
MythCoreContext::SetConfiguration
static void SetConfiguration(Configuration *pConfig)
Definition: mythcorecontext.cpp:1809
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:760
MythCoreContext::GetGUIContext
QObject * GetGUIContext(void)
Definition: mythcorecontext.cpp:1754
MythCoreContext::GetQLocale
QLocale GetQLocale(void)
Definition: mythcorecontext.cpp:1863
MythCoreContext::BackendIsRunning
static bool BackendIsRunning(void)
a backend process is running on this host
Definition: mythcorecontext.cpp:700
MythSocket::WriteStringList
bool WriteStringList(const QStringList &list)
Definition: mythsocket.cpp:307
MythCoreContext::SetAsFrontend
void SetAsFrontend(bool frontend)
Definition: mythcorecontext.cpp:649
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:1064
MythCoreContext::SendSystemEvent
void SendSystemEvent(const QString &msg)
Definition: mythcorecontext.cpp:1544
MythCoreContextPrivate::m_isexiting
bool m_isexiting
Definition: mythcorecontext.cpp:112
MythCoreContext::SendEvent
void SendEvent(const MythEvent &event)
Definition: mythcorecontext.cpp:1530
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:966
MythCoreContext::WaitUntilSignals
void WaitUntilSignals(std::vector< CoreWaitInfo > &sigs) const
Wait until any of the provided signals have been received.
Definition: mythcorecontext.cpp:1903
MythCoreContextPrivate::m_parent
MythCoreContext * m_parent
Definition: mythcorecontext.cpp:68
hardwareprofile.i18n.t
t
Definition: i18n.py:36
MythCoreContextPrivate::m_frontend
bool m_frontend
Definition: mythcorecontext.cpp:90
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:1004
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:654
MythCoreContextPrivate::m_guiObject
QObject * m_guiObject
Definition: mythcorecontext.cpp:70
MythCoreContext::GetDB
MythDB * GetDB(void)
Definition: mythcorecontext.cpp:1759
MythCoreContext::readyRead
void readyRead(MythSocket *sock) override
Definition: mythcorecontext.cpp:1561
MythWakeup
bool MythWakeup(const QString &wakeUpCommand, uint flags, std::chrono::seconds timeout)
Definition: mythmiscutil.cpp:631
MythCoreContext::GetNumSettingOnHost
int GetNumSettingOnHost(const QString &key, const QString &host, int defaultval=0)
Definition: mythcorecontext.cpp:943
MythCoreContextPrivate::m_approvedIps
QList< QHostAddress > m_approvedIps
Definition: mythcorecontext.cpp:119
MythCoreContextPrivate::m_wolInProgressLock
QMutex m_wolInProgressLock
Definition: mythcorecontext.cpp:84
MythCoreContext::GetResolutionSetting
void GetResolutionSetting(const QString &type, int &width, int &height, double &forced_aspect, double &refresh_rate, int index=-1)
Definition: mythcorecontext.cpp:849
MythCoreContext::RegisterForPlayback
void RegisterForPlayback(QObject *sender, PlaybackStartCb method)
Definition: mythcorecontext.cpp:1926
MythCoreContext::GetBackendServerIP4
QString GetBackendServerIP4(void)
Returns the IPv4 address defined for the current host see GetBackendServerIP4(host)
Definition: mythcorecontext.cpp:1027
MythCoreContext::m_testOverrideStrings
QMap< QString, QString > m_testOverrideStrings
Definition: mythcorecontext.h:330
SendAsyncMessage::m_message
QString m_message
Definition: mythcorecontext.cpp:1513
MythCoreContext::TVPlaybackAboutToStart
void TVPlaybackAboutToStart(void)
MythSocket::kShortTimeout
static constexpr std::chrono::milliseconds kShortTimeout
Definition: mythsocket.h:70
SendAsyncMessage
Definition: mythcorecontext.cpp:1494
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:427
MYTH_BINARY_VERSION
static constexpr const char * MYTH_BINARY_VERSION
Update this whenever the plug-in ABI changes.
Definition: mythversion.h:15
uint
unsigned int uint
Definition: compat.h:79
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:1514
MythCoreContextPrivate::~MythCoreContextPrivate
~MythCoreContextPrivate() override
Definition: mythcorecontext.cpp:155
MythCoreContext::ConnectEventSocket
MythSocket * ConnectEventSocket(const QString &hostname, int port)
Definition: mythcorecontext.cpp:545
MythCoreContext::GetLanguage
QString GetLanguage(void)
Returns two character ISO-639 language descriptor for UI language.
Definition: mythcorecontext.cpp:1773
MythCoreContext::GetNumSetting
int GetNumSetting(const QString &key, int defaultval=0)
Definition: mythcorecontext.cpp:912
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:216
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:1192
MythCoreContext::SetLocalHostname
void SetLocalHostname(const QString &hostname)
Definition: mythcorecontext.cpp:1732
MythCoreContextPrivate::m_locale
MythLocale * m_locale
Definition: mythcorecontext.cpp:96
SendAsyncMessage::run
void run(void) override
Definition: mythcorecontext.cpp:1504
MythCoreContext::GetBoolSetting
bool GetBoolSetting(const QString &key, bool defaultval=false)
Definition: mythcorecontext.cpp:906
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:980
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:2044
MythCoreContext::ResolveIPv4
@ ResolveIPv4
Definition: mythcorecontext.h:216
MythCoreContext
This class contains the runtime context for MythTV.
Definition: mythcorecontext.h:65
mythmiscutil.h
MythCoreContext::setTestIntSettings
void setTestIntSettings(QMap< QString, int > &overrides)
Definition: mythcorecontext.cpp:285
mythcorecontext.h
MythCoreContext::m_testOverrideFloats
QMap< QString, double > m_testOverrideFloats
Definition: mythcorecontext.h:329
Configuration
Definition: configuration.h:21
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:644
kLinkLocal
static QPair< QHostAddress, int > kLinkLocal
Definition: serverpool.cpp:27
MythCoreContextPrivate::m_masterHostname
QString m_masterHostname
master backend hostname
Definition: mythcorecontext.cpp:76
MythCoreContext::ResetLanguage
void ResetLanguage(void)
Definition: mythcorecontext.cpp:1793
MythCoreContext::GetSettingOnHost
QString GetSettingOnHost(const QString &key, const QString &host, const QString &defaultval="")
Definition: mythcorecontext.cpp:926
MythCoreContextPrivate::m_scopes
QMap< QString, QString > m_scopes
Scope Id cache for Link-Local addresses.
Definition: mythcorecontext.cpp:78
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:1785
std
Definition: mythchrono.h:23
MythCoreContextPrivate::m_serverSock
MythSocket * m_serverSock
socket for sending MythProto requests
Definition: mythcorecontext.cpp:81
serverpool.h
MythCoreContextPrivate::m_wolInProgress
bool m_wolInProgress
Definition: mythcorecontext.cpp:86
MythSocket::IsDataAvailable
bool IsDataAvailable(void)
Definition: mythsocket.cpp:563
MythCoreContextPrivate::m_inwanting
bool m_inwanting
Definition: mythcorecontext.cpp:105
MythCoreContext::ClearBackendServerPortCache
static void ClearBackendServerPortCache()
Definition: mythcorecontext.cpp:1071
logging.h
configuration.h
MYTH_PROTO_TOKEN
static constexpr const char * MYTH_PROTO_TOKEN
Definition: mythversion.h:48
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:2032
MythCoreContext::d
MythCoreContextPrivate * d
Definition: mythcorecontext.h:321
MythCoreContextPrivate::m_uiThread
QThread * m_uiThread
Definition: mythcorecontext.cpp:94
SendAsyncMessage::SendAsyncMessage
SendAsyncMessage(QString msg)
Definition: mythcorecontext.cpp:1502
MythCoreContext::ActivateSettingsCache
void ActivateSettingsCache(bool activate=true)
Definition: mythcorecontext.cpp:833
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:216
MythCoreContextPrivate::m_sockLock
QMutex m_sockLock
protects both m_serverSock and m_eventSock
Definition: mythcorecontext.cpp:80
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:1966
ShutdownMythSystemLegacy
void MBASE_PUBLIC ShutdownMythSystemLegacy(void)
Definition: mythsystemunix.cpp:75
MythCoreContext::GetHostName
QString GetHostName(void)
Definition: mythcorecontext.cpp:838
MythCoreContextPrivate::m_scheduler
MythScheduler * m_scheduler
Definition: mythcorecontext.cpp:99
MythCoreContext::ReInitLocale
void ReInitLocale(void)
Definition: mythcorecontext.cpp:1850
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:2106
MythCoreContext::GetBoolSettingOnHost
bool GetBoolSettingOnHost(const QString &key, const QString &host, bool defaultval=false)
Definition: mythcorecontext.cpp:935
MythCoreContext::ClearSettingsCache
void ClearSettingsCache(const QString &myKey=QString(""))
Definition: mythcorecontext.cpp:828
MythCoreContext::g_pConfig
static Configuration * g_pConfig
Definition: mythcorecontext.h:247
MythCoreContext::IsThisHost
bool IsThisHost(const QString &addr)
is this address mapped to this host
Definition: mythcorecontext.cpp:721
MythCoreContext::HasGUI
bool HasGUI(void) const
Definition: mythcorecontext.cpp:1744
MythCoreContext::IsMasterHost
bool IsMasterHost(void)
is this the same host as the master
Definition: mythcorecontext.cpp:659
MythCoreContextPrivate::m_localHostLock
QMutex m_localHostLock
Locking for m_localHostname.
Definition: mythcorecontext.cpp:73
musicbrainzngs.caa.hostname
string hostname
Definition: caa.py:17
mythpower.h
MythCoreContext::BlockShutdown
void BlockShutdown(void)
Definition: mythcorecontext.cpp:596
MythCoreContext::IsWOLAllowed
bool IsWOLAllowed() const
Definition: mythcorecontext.cpp:634
MythCoreContext::GetFloatSetting
double GetFloatSetting(const QString &key, double defaultval=0.0)
Definition: mythcorecontext.cpp:919
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:881
MythCoreContext::GetMasterHostPrefix
QString GetMasterHostPrefix(const QString &storageGroup=QString(), const QString &path=QString())
Definition: mythcorecontext.cpp:798
MythCoreContext::GetSessionManager
MythSessionManager * GetSessionManager(void)
Definition: mythcorecontext.cpp:2060
exitcodes.h
mythdownloadmanager.h
MythCoreContext::GetBackendServerIP6
QString GetBackendServerIP6(void)
Returns the IPv6 address defined for the current host see GetBackendServerIP6(host)
Definition: mythcorecontext.cpp:1046
delete_sock
static void delete_sock(QMutexLocker< QMutex > &locker, MythSocket **s)
Definition: mythcorecontext.cpp:137
MThreadPool::globalInstance
static MThreadPool * globalInstance(void)
Definition: mthreadpool.cpp:317
MythCoreContext::GetPluginManager
MythPluginManager * GetPluginManager(void)
Definition: mythcorecontext.cpp:2096
MythCoreContext::SetScopeForAddress
void SetScopeForAddress(const QHostAddress &addr)
Record the scope Id of the given IP address.
Definition: mythcorecontext.cpp:1129
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:300
MythCoreContext::CheckSubnet
bool CheckSubnet(const QAbstractSocket *socket)
Check if a socket is connected to an approved peer.
Definition: mythcorecontext.cpp:1268
mythsocket.h
MythCoreContextPrivate::m_guiContext
QObject * m_guiContext
Definition: mythcorecontext.cpp:69
MythCoreContextPrivate
Definition: mythcorecontext.cpp:58
MythCoreContext::SaveLocaleDefaults
void SaveLocaleDefaults(void)
Definition: mythcorecontext.cpp:1871
MythCoreContext::dispatch
void dispatch(const MythEvent &event)
Definition: mythcorecontext.cpp:1725
MythCoreContextPrivate::m_language
QString m_language
Definition: mythcorecontext.cpp:97
MythCoreContext::SaveSettingOnHost
bool SaveSettingOnHost(const QString &key, const QString &newValue, const QString &host)
Definition: mythcorecontext.cpp:891
MythSocket::ReadStringList
bool ReadStringList(QStringList &list, std::chrono::milliseconds timeoutMS=kShortTimeout)
Definition: mythsocket.cpp:319
MythCoreContext::SetAsBackend
void SetAsBackend(bool backend)
Definition: mythcorecontext.cpp:639
MythCoreContext::m_testOverrideInts
QMap< QString, int > m_testOverrideInts
Definition: mythcorecontext.h:328
MythCoreContext::PlaybackStartCb
void(QObject::*)(void) PlaybackStartCb
Definition: mythcorecontext.h:249
MythCoreContext::IsThisBackend
bool IsThisBackend(const QString &addr)
is this address mapped to this backend host
Definition: mythcorecontext.cpp:716
MythCoreContext::setTestFloatSettings
void setTestFloatSettings(QMap< QString, double > &overrides)
Definition: mythcorecontext.cpp:290
MythCoreContext::GetFloatSettingOnHost
double GetFloatSettingOnHost(const QString &key, const QString &host, double defaultval=0.0)
Definition: mythcorecontext.cpp:952
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:2101
MythCoreContext::SetGUIObject
void SetGUIObject(QObject *gui)
Definition: mythcorecontext.cpp:1739
MythSocket::SendReceiveStringList
bool SendReceiveStringList(QStringList &list, uint min_reply_length=0, std::chrono::milliseconds timeoutMS=kLongTimeout)
Definition: mythsocket.cpp:332
MythCoreContextPrivate::m_power
MythPower * m_power
Definition: mythcorecontext.cpp:122
MythCoreContextPrivate::MythCoreContextPrivate
MythCoreContextPrivate(MythCoreContext *lparent, QString binversion, QObject *guicontext)
Definition: mythcorecontext.cpp:125
MythCoreContext::GetSetting
QString GetSetting(const QString &key, const QString &defaultval="")
Definition: mythcorecontext.cpp:898
MythSessionManager
Definition: mythsession.h:102
MythCoreContext::GetConfiguration
static Configuration * GetConfiguration()
Definition: mythcorecontext.cpp:1815