MythTV  master
remoteutil.cpp
Go to the documentation of this file.
1 #include <unistd.h>
2 
3 #include <QFileInfo>
4 #include <QFile>
5 #include <QDir>
6 #include <QList>
7 
8 #include "libmythbase/compat.h"
10 #include "libmythbase/mythevent.h"
11 #include "libmythbase/mythsocket.h"
13 
14 #include "programinfo.h"
15 #include "remoteutil.h"
16 
17 std::vector<ProgramInfo *> *RemoteGetRecordedList(int sort)
18 {
19  QString str = "QUERY_RECORDINGS ";
20  if (sort < 0)
21  str += "Descending";
22  else if (sort > 0)
23  str += "Ascending";
24  else
25  str += "Unsorted";
26 
27  QStringList strlist(str);
28 
29  auto *info = new std::vector<ProgramInfo *>;
30 
31  if (!RemoteGetRecordingList(*info, strlist))
32  {
33  delete info;
34  return nullptr;
35  }
36 
37  return info;
38 }
39 
41 {
42  QStringList strlist(QString("QUERY_LOAD"));
43 
44  if (gCoreContext->SendReceiveStringList(strlist) && strlist.size() >= 3)
45  {
46  load[0] = strlist[0].toDouble();
47  load[1] = strlist[1].toDouble();
48  load[2] = strlist[2].toDouble();
49  return true;
50  }
51 
52  return false;
53 }
54 
55 bool RemoteGetUptime(std::chrono::seconds &uptime)
56 {
57  QStringList strlist(QString("QUERY_UPTIME"));
58 
59  if (!gCoreContext->SendReceiveStringList(strlist) || strlist.isEmpty())
60  return false;
61 
62  if (strlist[0].isEmpty() || !strlist[0].at(0).isNumber())
63  return false;
64 
65  if (sizeof(time_t) == sizeof(int))
66  uptime = std::chrono::seconds(strlist[0].toUInt());
67  else if (sizeof(time_t) == sizeof(long))
68  uptime = std::chrono::seconds(strlist[0].toULong());
69  else if (sizeof(time_t) == sizeof(long long))
70  uptime = std::chrono::seconds(strlist[0].toULongLong());
71 
72  return true;
73 }
74 
75 bool RemoteGetMemStats(int &totalMB, int &freeMB, int &totalVM, int &freeVM)
76 {
77  QStringList strlist(QString("QUERY_MEMSTATS"));
78 
79  if (gCoreContext->SendReceiveStringList(strlist) && strlist.size() >= 4)
80  {
81  totalMB = strlist[0].toInt();
82  freeMB = strlist[1].toInt();
83  totalVM = strlist[2].toInt();
84  freeVM = strlist[3].toInt();
85  return true;
86  }
87 
88  return false;
89 }
90 
91 bool RemoteCheckFile(ProgramInfo *pginfo, bool checkSlaves)
92 {
93  QStringList strlist("QUERY_CHECKFILE");
94  strlist << QString::number((int)checkSlaves);
95  pginfo->ToStringList(strlist);
96 
97  if (!gCoreContext->SendReceiveStringList(strlist) ||
98  (strlist.size() < 2) || !strlist[0].toInt())
99  return false;
100 
101  // Only modify the pathname if the recording file is available locally on
102  // this host
103  QString localpath = strlist[1];
104  QFile checkFile(localpath);
105  if (checkFile.exists())
106  pginfo->SetPathname(localpath);
107 
108  return true;
109 }
110 
111 bool RemoteDeleteRecording(uint recordingID, bool forceMetadataDelete,
112  bool forgetHistory)
113 {
114  // FIXME: Remove when DELETE_RECORDING has been updated to use recording id
115  ProgramInfo recInfo(recordingID);
116  bool result = true;
117  QString cmd =
118  QString("DELETE_RECORDING %1 %2 %3 %4")
119  .arg(QString::number(recInfo.GetChanID()),
120  recInfo.GetRecordingStartTime().toString(Qt::ISODate),
121  forceMetadataDelete ? "FORCE" : "NO_FORCE",
122  forgetHistory ? "FORGET" : "NO_FORGET");
123  QStringList strlist(cmd);
124 
125  if ((!gCoreContext->SendReceiveStringList(strlist) || strlist.isEmpty()) ||
126  (strlist[0].toInt() == -2))
127  result = false;
128 
129  if (!result)
130  {
131  LOG(VB_GENERAL, LOG_ALERT,
132  QString("Failed to delete recording %1:%2")
133  .arg(recInfo.GetChanID())
134  .arg(recInfo.GetRecordingStartTime().toString(Qt::ISODate)));
135  }
136 
137  return result;
138 }
139 
140 bool RemoteUndeleteRecording(uint recordingID)
141 {
142  // FIXME: Remove when UNDELETE_RECORDING has been updated to use recording id
143  ProgramInfo recInfo(recordingID);
144  bool result = false;
145 
146 #if 0
147  if (!gCoreContext->GetNumSetting("AutoExpireInsteadOfDelete", 0))
148  return result;
149 #endif
150 
151  QStringList strlist(QString("UNDELETE_RECORDING"));
152  strlist.push_back(QString::number(recInfo.GetChanID()));
153  strlist.push_back(recInfo.GetRecordingStartTime().toString(Qt::ISODate));
154 
156 
157  if (!strlist.isEmpty() && strlist[0].toInt() == 0)
158  result = true;
159 
160  return result;
161 }
162 
163 void RemoteGetAllScheduledRecordings(std::vector<ProgramInfo *> &scheduledlist)
164 {
165  QStringList strList(QString("QUERY_GETALLSCHEDULED"));
166  RemoteGetRecordingList(scheduledlist, strList);
167 }
168 
169 void RemoteGetAllExpiringRecordings(std::vector<ProgramInfo *> &expiringlist)
170 {
171  QStringList strList(QString("QUERY_GETEXPIRING"));
172  RemoteGetRecordingList(expiringlist, strList);
173 }
174 
176  std::vector<ProgramInfo *> &reclist, QStringList &strList)
177 {
178  if (!gCoreContext->SendReceiveStringList(strList) || strList.isEmpty())
179  return 0;
180 
181  int numrecordings = strList[0].toInt();
182  if (numrecordings <= 0)
183  return 0;
184 
185  if (numrecordings * NUMPROGRAMLINES + 1 > strList.size())
186  {
187  LOG(VB_GENERAL, LOG_ERR,
188  "RemoteGetRecordingList() list size appears to be incorrect.");
189  return 0;
190  }
191 
192  uint reclist_initial_size = (uint) reclist.size();
193  QStringList::const_iterator it = strList.cbegin() + 1;
194  for (int i = 0; i < numrecordings; i++)
195  {
196  auto *pginfo = new ProgramInfo(it, strList.cend());
197  reclist.push_back(pginfo);
198  }
199 
200  return ((uint) reclist.size()) - reclist_initial_size;
201 }
202 
203 std::vector<ProgramInfo *> *RemoteGetConflictList(const ProgramInfo *pginfo)
204 {
205  QString cmd = QString("QUERY_GETCONFLICTING");
206  QStringList strlist( cmd );
207  pginfo->ToStringList(strlist);
208 
209  auto *retlist = new std::vector<ProgramInfo *>;
210 
211  RemoteGetRecordingList(*retlist, strlist);
212  return retlist;
213 }
214 
216 {
217  QStringList strlist( "QUERY_PIXMAP_LASTMODIFIED" );
218  pginfo->ToStringList(strlist);
219 
220  if (!gCoreContext->SendReceiveStringList(strlist))
221  return {};
222 
223  if (!strlist.isEmpty() && !strlist[0].isEmpty() && (strlist[0] != "BAD"))
224  {
225  qint64 timet = strlist[0].toLongLong();
226  return MythDate::fromSecsSinceEpoch(timet);
227  }
228 
229  return {};
230 }
231 
235  const ProgramInfo &pginfo, const QString &cachefile)
236 {
237  QString loc("RemoteGetPreviewIfModified: ");
238  QDateTime cacheLastModified;
239  QFileInfo cachefileinfo(cachefile);
240  if (cachefileinfo.exists())
241  cacheLastModified = cachefileinfo.lastModified();
242 
243  QStringList strlist("QUERY_PIXMAP_GET_IF_MODIFIED");
244  strlist << ((cacheLastModified.isValid()) ? // unix secs, UTC
245  QString::number(cacheLastModified.toSecsSinceEpoch()) :
246  QString("-1"));
247  strlist << QString::number(200 * 1024); // max size of preview file
248  pginfo.ToStringList(strlist);
249 
250  if (!gCoreContext->SendReceiveStringList(strlist) ||
251  strlist.isEmpty() || strlist[0] == "ERROR")
252  {
253  LOG(VB_GENERAL, LOG_ERR, loc + "Remote error" +
254  ((strlist.size() >= 2) ? (":\n\t\t\t" + strlist[1]) : ""));
255 
256  return {};
257  }
258 
259  if (strlist[0] == "WARNING")
260  {
261  LOG(VB_NETWORK, LOG_WARNING, loc + "Remote warning" +
262  ((strlist.size() >= 2) ? (":\n\t\t\t" + strlist[1]) : ""));
263 
264  return {};
265  }
266 
267  QDateTime retdatetime;
268  qlonglong timet = strlist[0].toLongLong();
269  if (timet >= 0)
270  {
271  retdatetime = MythDate::fromSecsSinceEpoch(timet);
272  }
273 
274  if (strlist.size() < 4)
275  {
276  return retdatetime;
277  }
278 
279  size_t length = strlist[1].toULongLong();
280  quint16 checksum16 = strlist[2].toUInt();
281  QByteArray data = QByteArray::fromBase64(strlist[3].toLatin1());
282  if ((size_t) data.size() < length)
283  { // (note data.size() may be up to 3 bytes longer after decoding
284  LOG(VB_GENERAL, LOG_ERR, loc +
285  QString("Preview size check failed %1 < %2")
286  .arg(data.size()).arg(length));
287  return {};
288  }
289  data.resize(length);
290 
291 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
292  quint16 calculated = qChecksum(data.constData(), data.size());
293 #else
294  quint16 calculated = qChecksum(data);
295 #endif
296  if (checksum16 != calculated)
297  {
298  LOG(VB_GENERAL, LOG_ERR, loc + "Preview checksum failed");
299  return {};
300  }
301 
302  QString pdir(cachefile.section("/", 0, -2));
303  QDir cfd(pdir);
304  if (!cfd.exists() && !cfd.mkdir(pdir))
305  {
306  LOG(VB_GENERAL, LOG_ERR, loc +
307  QString("Unable to create remote cache directory '%1'")
308  .arg(pdir));
309 
310  return {};
311  }
312 
313  QFile file(cachefile);
314  if (!file.open(QIODevice::WriteOnly|QIODevice::Truncate))
315  {
316  LOG(VB_GENERAL, LOG_ERR, loc +
317  QString("Unable to open cached preview file for writing '%1'")
318  .arg(cachefile));
319 
320  return {};
321  }
322 
323  off_t offset = 0;
324  size_t remaining = length;
325  uint failure_cnt = 0;
326  while ((remaining > 0) && (failure_cnt < 5))
327  {
328  ssize_t written = file.write(data.data() + offset, remaining);
329  if (written < 0)
330  {
331  failure_cnt++;
332  usleep(50000);
333  continue;
334  }
335 
336  failure_cnt = 0;
337  offset += written;
338  remaining -= written;
339  }
340 
341  if (remaining)
342  {
343  LOG(VB_GENERAL, LOG_ERR, loc +
344  QString("Failed to write cached preview file '%1'")
345  .arg(cachefile));
346 
347  file.resize(0); // in case unlink fails..
348  file.remove(); // closes fd
349  return {};
350  }
351 
352  file.close();
353 
354  return retdatetime;
355 }
356 
357 bool RemoteFillProgramInfo(ProgramInfo &pginfo, const QString &playbackhost)
358 {
359  QStringList strlist( "FILL_PROGRAM_INFO" );
360  strlist << playbackhost;
361  pginfo.ToStringList(strlist);
362 
363  if (gCoreContext->SendReceiveStringList(strlist))
364  {
365  ProgramInfo tmp(strlist);
366  if (tmp.HasPathname() || tmp.GetChanID())
367  {
368  pginfo = tmp;
369  return true;
370  }
371  }
372 
373  return false;
374 }
375 
376 QStringList RemoteRecordings(void)
377 {
378  QStringList strlist("QUERY_ISRECORDING");
379 
380  if (!gCoreContext->SendReceiveStringList(strlist, false, false))
381  {
382  QStringList empty;
383  empty << "0" << "0";
384  return empty;
385  }
386 
387  return strlist;
388 }
389 
391 {
392  int mask = 0;
393 
394  QString cmd = "QUERY_ISRECORDING";
395 
396  QStringList strlist( cmd );
397 
398  if (!gCoreContext->SendReceiveStringList(strlist) || strlist.isEmpty())
399  return mask;
400 
401  int recCount = strlist[0].toInt();
402 
403  for (int i = 0, j = 0; j < recCount; i++)
404  {
405  cmd = QString("QUERY_RECORDER %1").arg(i + 1);
406 
407  strlist = QStringList( cmd );
408  strlist << "IS_RECORDING";
409 
410  if (gCoreContext->SendReceiveStringList(strlist) && !strlist.isEmpty())
411  {
412  if (strlist[0].toInt())
413  {
414  mask |= 1<<i;
415  j++; // count active recorder
416  }
417  }
418  else
419  {
420  break;
421  }
422  }
423 
424  return mask;
425 }
426 
427 bool RemoteGetFileList(const QString& host, const QString& path, QStringList* list,
428  QString sgroup, bool fileNamesOnly)
429 {
430 
431  // Make sure the list is empty when we get started
432  list->clear();
433 
434  if (sgroup.isEmpty())
435  sgroup = "Videos";
436 
437  *list << "QUERY_SG_GETFILELIST";
438  *list << host;
439  *list << StorageGroup::GetGroupToUse(host, sgroup);
440  *list << path;
441  *list << QString::number(static_cast<int>(fileNamesOnly));
442 
443  bool ok = false;
444 
446  {
447  // since the master backend cannot connect back around to
448  // itself, and the libraries do not have access to the list
449  // of connected slave backends to query an existing connection
450  // start up a new temporary connection directly to the slave
451  // backend to query the file list
452  QString ann = QString("ANN Playback %1 0")
453  .arg(gCoreContext->GetHostName());
454  QString addr = gCoreContext->GetBackendServerIP(host);
455  int port = gCoreContext->GetBackendServerPort(host);
456  bool mismatch = false;
457 
459  addr, port, ann, &mismatch);
460  if (sock)
461  {
462  ok = sock->SendReceiveStringList(*list);
463  sock->DecrRef();
464  }
465  else
466  list->clear();
467  }
468  else
469  ok = gCoreContext->SendReceiveStringList(*list);
470 
471 // Should the SLAVE UNREACH test be here ?
472  return ok;
473 }
474 
481 {
482  QStringList strlist( QString("CHECK_RECORDING") );
483  pginfo->ToStringList(strlist);
484 
485  if (gCoreContext->SendReceiveStringList(strlist) && !strlist.isEmpty())
486  return strlist[0].toInt();
487 
488  return 0;
489 }
490 
500  const ProgramInfo *pginfo, int overrecsecs, int underrecsecs)
501 {
502  QDateTime curtime = MythDate::current();
503 
504  int retval = 0;
505 
506  if (pginfo)
507  {
508  if (curtime >= pginfo->GetScheduledStartTime().addSecs(-underrecsecs) &&
509  curtime < pginfo->GetScheduledEndTime().addSecs(overrecsecs))
510  {
511  if (curtime >= pginfo->GetScheduledStartTime() &&
512  curtime < pginfo->GetScheduledEndTime())
513  retval = 1;
514  else if (curtime < pginfo->GetScheduledStartTime() &&
515  RemoteCheckForRecording(pginfo) > 0)
516  retval = 2;
517  else if (curtime > pginfo->GetScheduledEndTime() &&
518  RemoteCheckForRecording(pginfo) > 0)
519  retval = 3;
520  }
521  }
522 
523  return retval;
524 }
525 
529 std::vector<ProgramInfo *> *RemoteGetCurrentlyRecordingList(void)
530 {
531  QString str = "QUERY_RECORDINGS ";
532  str += "Recording";
533  QStringList strlist( str );
534 
535  auto *reclist = new std::vector<ProgramInfo *>;
536  auto *info = new std::vector<ProgramInfo *>;
537  if (!RemoteGetRecordingList(*info, strlist))
538  {
539  delete info;
540  return reclist;
541  }
542 
543  // make sure whatever RemoteGetRecordingList() returned
544  // only has RecStatus::Recording shows
545  for (auto & p : *info)
546  {
547  if (p->GetRecordingStatus() == RecStatus::Recording ||
548  p->GetRecordingStatus() == RecStatus::Tuning ||
549  p->GetRecordingStatus() == RecStatus::Failing ||
550  (p->GetRecordingStatus() == RecStatus::Recorded &&
551  p->GetRecordingGroup() == "LiveTV"))
552  {
553  reclist->push_back(new ProgramInfo(*p));
554  }
555  }
556 
557  while (!info->empty())
558  {
559  delete info->back();
560  info->pop_back();
561  }
562  delete info;
563 
564  return reclist;
565 }
566 
570 bool RemoteGetActiveBackends(QStringList *list)
571 {
572  list->clear();
573  *list << "QUERY_ACTIVE_BACKENDS";
574 
575  if (!gCoreContext->SendReceiveStringList(*list))
576  return false;
577 
578  list->removeFirst();
579  return true;
580 }
581 
582 /* vim: set expandtab tabstop=4 shiftwidth=4: */
mythevent.h
ReferenceCounter::DecrRef
virtual int DecrRef(void)
Decrements reference count and deletes on 0.
Definition: referencecounter.cpp:125
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
RecStatus::Tuning
@ Tuning
Definition: recordingstatus.h:22
RemoteGetPreviewLastModified
QDateTime RemoteGetPreviewLastModified(const ProgramInfo *pginfo)
Definition: remoteutil.cpp:215
RemoteGetRecordingList
uint RemoteGetRecordingList(std::vector< ProgramInfo * > &reclist, QStringList &strList)
Definition: remoteutil.cpp:175
RemoteGetRecordingMask
int RemoteGetRecordingMask(void)
Definition: remoteutil.cpp:390
RemoteUndeleteRecording
bool RemoteUndeleteRecording(uint recordingID)
Definition: remoteutil.cpp:140
RecStatus::Recorded
@ Recorded
Definition: recordingstatus.h:29
ProgramInfo::GetScheduledEndTime
QDateTime GetScheduledEndTime(void) const
The scheduled end time of the program.
Definition: programinfo.h:397
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
RemoteCheckFile
bool RemoteCheckFile(ProgramInfo *pginfo, bool checkSlaves)
Definition: remoteutil.cpp:91
NUMPROGRAMLINES
static constexpr int8_t NUMPROGRAMLINES
Definition: programinfo.h:28
build_compdb.file
file
Definition: build_compdb.py:55
remoteutil.h
MythDate::current
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:14
ProgramInfo::GetRecordingStartTime
QDateTime GetRecordingStartTime(void) const
Approximate time the recording started.
Definition: programinfo.h:404
tmp
static guint32 * tmp
Definition: goom_core.cpp:26
RemoteGetLoad
bool RemoteGetLoad(system_load_array &load)
Definition: remoteutil.cpp:40
system_load_array
std::array< double, 3 > system_load_array
Definition: remoteutil.h:18
MythSocket
Class for communcating between myth backends and frontends.
Definition: mythsocket.h:25
MythCoreContext::IsMasterBackend
bool IsMasterBackend(void)
is this the actual MBE process
Definition: mythcorecontext.cpp:695
ProgramInfo::SetPathname
void SetPathname(const QString &pn)
Definition: programinfo.cpp:2438
MythDate::fromSecsSinceEpoch
MBASE_PUBLIC QDateTime fromSecsSinceEpoch(int64_t seconds)
This function takes the number of seconds since the start of the epoch and returns a QDateTime with t...
Definition: mythdate.cpp:72
programinfo.h
ProgramInfo::GetScheduledStartTime
QDateTime GetScheduledStartTime(void) const
The scheduled start time of program.
Definition: programinfo.h:390
RemoteRecordings
QStringList RemoteRecordings(void)
Definition: remoteutil.cpp:376
MythCoreContext::GetBackendServerPort
int GetBackendServerPort(void)
Returns the locally defined backend control port.
Definition: mythcorecontext.cpp:1064
hardwareprofile.config.p
p
Definition: config.py:33
RemoteGetRecordingStatus
int RemoteGetRecordingStatus(const ProgramInfo *pginfo, int overrecsecs, int underrecsecs)
Get status of an individual programme (with pre-post roll?).
Definition: remoteutil.cpp:499
compat.h
MythCoreContext::GetBackendServerIP
QString GetBackendServerIP(void)
Returns the IP address of the locally defined backend IP.
Definition: mythcorecontext.cpp:1004
RecStatus::Failing
@ Failing
Definition: recordingstatus.h:18
RemoteCheckForRecording
int RemoteCheckForRecording(const ProgramInfo *pginfo)
Get recorder for a programme.
Definition: remoteutil.cpp:480
storagegroup.h
StorageGroup::GetGroupToUse
static QString GetGroupToUse(const QString &host, const QString &sgroup)
Definition: storagegroup.cpp:866
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
RemoteGetAllExpiringRecordings
void RemoteGetAllExpiringRecordings(std::vector< ProgramInfo * > &expiringlist)
Definition: remoteutil.cpp:169
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
RemoteGetCurrentlyRecordingList
std::vector< ProgramInfo * > * RemoteGetCurrentlyRecordingList(void)
return list of currently recording shows
Definition: remoteutil.cpp:529
MythCoreContext::GetNumSetting
int GetNumSetting(const QString &key, int defaultval=0)
Definition: mythcorecontext.cpp:912
RemoteGetMemStats
bool RemoteGetMemStats(int &totalMB, int &freeMB, int &totalVM, int &freeVM)
Definition: remoteutil.cpp:75
off_t
#define off_t
Definition: mythiowrapper.cpp:241
ProgramInfo::GetChanID
uint GetChanID(void) const
This is the unique key used in the database to locate tuning information.
Definition: programinfo.h:372
RemoteGetUptime
bool RemoteGetUptime(std::chrono::seconds &uptime)
Definition: remoteutil.cpp:55
ProgramInfo
Holds information on recordings and videos.
Definition: programinfo.h:67
RecStatus::Recording
@ Recording
Definition: recordingstatus.h:30
ProgramInfo::ToStringList
void ToStringList(QStringList &list) const
Serializes ProgramInfo into a QStringList which can be passed over a socket.
Definition: programinfo.cpp:1267
mythcorecontext.h
RemoteFillProgramInfo
bool RemoteFillProgramInfo(ProgramInfo &pginfo, const QString &playbackhost)
Definition: remoteutil.cpp:357
RemoteGetAllScheduledRecordings
void RemoteGetAllScheduledRecordings(std::vector< ProgramInfo * > &scheduledlist)
Definition: remoteutil.cpp:163
MythDate::ISODate
@ ISODate
Default UTC.
Definition: mythdate.h:17
RemoteGetConflictList
std::vector< ProgramInfo * > * RemoteGetConflictList(const ProgramInfo *pginfo)
Definition: remoteutil.cpp:203
MythCoreContext::GetHostName
QString GetHostName(void)
Definition: mythcorecontext.cpp:838
RemoteGetRecordedList
std::vector< ProgramInfo * > * RemoteGetRecordedList(int sort)
Definition: remoteutil.cpp:17
RemoteGetPreviewIfModified
QDateTime RemoteGetPreviewIfModified(const ProgramInfo &pginfo, const QString &cachefile)
Download preview & get timestamp if newer than cachefile's last modified time, otherwise just get the...
Definition: remoteutil.cpp:234
RemoteDeleteRecording
bool RemoteDeleteRecording(uint recordingID, bool forceMetadataDelete, bool forgetHistory)
Definition: remoteutil.cpp:111
mythsocket.h
RemoteGetActiveBackends
bool RemoteGetActiveBackends(QStringList *list)
return list of backends currently connected to the master
Definition: remoteutil.cpp:570
MythSocket::SendReceiveStringList
bool SendReceiveStringList(QStringList &list, uint min_reply_length=0, std::chrono::milliseconds timeoutMS=kLongTimeout)
Definition: mythsocket.cpp:332
RemoteGetFileList
bool RemoteGetFileList(const QString &host, const QString &path, QStringList *list, QString sgroup, bool fileNamesOnly)
Definition: remoteutil.cpp:427