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