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