static bool RemoteSendReceiveStringList(const QString &host, QStringList &strlist) { bool ok = false; if (gCoreContext->IsMasterBackend()) { // since the master backend cannot connect back around to // itself, and the libraries do not have access to the list // of connected slave backends to query an existing connection // start up a new temporary connection directly to the slave // backend to query the file list QString ann = QString("ANN Playback %1 0") .arg(gCoreContext->GetHostName()); QString addr = gCoreContext->GetBackendServerIP(host); int port = gCoreContext->GetBackendServerPort(host); bool mismatch = false; MythSocket *sock = gCoreContext->ConnectCommandSocket( addr, port, ann, &mismatch); if (sock) { ok = sock->SendReceiveStringList(strlist); sock->DecrRef(); } else strlist.clear(); } else ok = gCoreContext->SendReceiveStringList(strlist); return ok; }
bool RemoteGetFileList(QString host, QString path, QStringList* list, QString sgroup, bool fileNamesOnly) { // Make sure the list is empty when we get started list->clear(); if (sgroup.isEmpty()) sgroup = "Videos"; *list << "QUERY_SG_GETFILELIST"; *list << host; *list << StorageGroup::GetGroupToUse(host, sgroup); *list << path; *list << QString::number(fileNamesOnly); bool ok = false; if (gCoreContext->IsMasterBackend()) { // since the master backend cannot connect back around to // itself, and the libraries do not have access to the list // of connected slave backends to query an existing connection // start up a new temporary connection directly to the slave // backend to query the file list QString ann = QString("ANN Playback %1 0") .arg(gCoreContext->GetHostName()); QString addr = gCoreContext->GetBackendServerIP(host); int port = gCoreContext->GetBackendServerPort(host); bool mismatch = false; MythSocket *sock = gCoreContext->ConnectCommandSocket( addr, port, ann, &mismatch); if (sock) { ok = sock->SendReceiveStringList(*list); sock->DecrRef(); } else list->clear(); } else ok = gCoreContext->SendReceiveStringList(*list); // Should the SLAVE UNREACH test be here ? return ok; }
MythSocket *RemoteFile::openSocket(bool control) { QUrl qurl(path); QString dir; QString host = qurl.host(); int port = qurl.port(); dir = qurl.path(); if (qurl.hasQuery()) #if QT_VERSION >= QT_VERSION_CHECK(5,0,0) dir += "?" + QUrl::fromPercentEncoding( qurl.query(QUrl::FullyEncoded).toLocal8Bit()); #else dir += "?" + QUrl::fromPercentEncoding(qurl.encodedQuery()); #endif if (qurl.hasFragment()) dir += "#" + qurl.fragment(); QString sgroup = qurl.userName(); MythSocket *lsock = new MythSocket(); QString stype = (control) ? "control socket" : "file data socket"; QString loc = QString("RemoteFile::openSocket(%1): ").arg(stype); if (port <= 0) { port = GetMythDB()->GetSettingOnHost("BackendServerPort", host).toInt(); // if we still have no port use the default if (port <= 0) port = 6543; } if (!lsock->ConnectToHost(host, port)) { LOG(VB_GENERAL, LOG_ERR, loc + QString("Could not connect to server %1:%2") .arg(host).arg(port)); lsock->DecrRef(); return NULL; } QString hostname = GetMythDB()->GetHostName(); QStringList strlist; #ifndef IGNORE_PROTO_VER_MISMATCH if (!gCoreContext->CheckProtoVersion(lsock)) { LOG(VB_GENERAL, LOG_ERR, loc + QString("Failed validation to server %1:%2").arg(host).arg(port)); lsock->DecrRef(); return NULL; } #endif if (control) { strlist.append(QString("ANN Playback %1 %2").arg(hostname).arg(false)); if (!lsock->SendReceiveStringList(strlist)) { LOG(VB_GENERAL, LOG_ERR, loc + QString("Could not read string list from server %1:%2") .arg(host).arg(port)); lsock->DecrRef(); return NULL; } } else { strlist.push_back(QString("ANN FileTransfer %1 %2 %3 %4") .arg(hostname).arg(writemode) .arg(usereadahead).arg(timeout_ms)); strlist << QString("%1").arg(dir); strlist << sgroup; QStringList::const_iterator it = possibleauxfiles.begin(); for (; it != possibleauxfiles.end(); ++it) strlist << *it; if (!lsock->SendReceiveStringList(strlist)) { LOG(VB_GENERAL, LOG_ERR, loc + QString("Did not get proper response from %1:%2") .arg(host).arg(port)); strlist.clear(); strlist.push_back("ERROR"); strlist.push_back("invalid response"); } if (strlist.size() >= 3) { it = strlist.begin(); ++it; recordernum = (*it).toInt(); ++it; filesize = (*(it)).toLongLong(); ++it; for (; it != strlist.end(); ++it) auxfiles << *it; } else if (0 < strlist.size() && strlist.size() < 3 && strlist[0] != "ERROR") { LOG(VB_GENERAL, LOG_ERR, loc + QString("Did not get proper response from %1:%2") .arg(host).arg(port)); strlist.clear(); strlist.push_back("ERROR"); strlist.push_back("invalid response"); } } if (strlist.empty() || strlist[0] == "ERROR") { lsock->DecrRef(); lsock = NULL; if (strlist.empty()) { LOG(VB_GENERAL, LOG_ERR, loc + "Failed to open socket, timeout"); } else { LOG(VB_GENERAL, LOG_ERR, loc + "Failed to open socket" + ((strlist.size() >= 2) ? QString(", error was %1").arg(strlist[1]) : QString(", remote error"))); } } return lsock; }
int connect_to_master(void) { MythSocket *tempMonitorConnection = new MythSocket(); if (tempMonitorConnection->ConnectToHost( gCoreContext->GetMasterServerIP(), gCoreContext->GetMasterServerPort())) { if (!gCoreContext->CheckProtoVersion(tempMonitorConnection)) { LOG(VB_GENERAL, LOG_ERR, "Master backend is incompatible with " "this backend.\nCannot become a slave."); tempMonitorConnection->DecrRef(); return GENERIC_EXIT_CONNECT_ERROR; } QStringList tempMonitorDone("DONE"); QStringList tempMonitorAnnounce(QString("ANN Monitor %1 0") .arg(gCoreContext->GetHostName())); tempMonitorConnection->SendReceiveStringList(tempMonitorAnnounce); if (tempMonitorAnnounce.empty() || tempMonitorAnnounce[0] == "ERROR") { tempMonitorConnection->DecrRef(); tempMonitorConnection = NULL; if (tempMonitorAnnounce.empty()) { LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to open event socket, timeout"); } else { LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to open event socket" + ((tempMonitorAnnounce.size() >= 2) ? QString(", error was %1").arg(tempMonitorAnnounce[1]) : QString(", remote error"))); } } QStringList timeCheck; if (tempMonitorConnection) { timeCheck.push_back("QUERY_TIME_ZONE"); tempMonitorConnection->SendReceiveStringList(timeCheck); tempMonitorConnection->WriteStringList(tempMonitorDone); } if (timeCheck.size() < 3) { if (tempMonitorConnection) tempMonitorConnection->DecrRef(); return GENERIC_EXIT_SOCKET_ERROR; } QDateTime our_time = MythDate::current(); QDateTime master_time = MythDate::fromString(timeCheck[2]); int timediff = abs(our_time.secsTo(master_time)); if (timediff > 300) { LOG(VB_GENERAL, LOG_ERR, QString("Current time on the master backend differs by " "%1 seconds from time on this system. Exiting.") .arg(timediff)); if (tempMonitorConnection) tempMonitorConnection->DecrRef(); return GENERIC_EXIT_INVALID_TIME; } if (timediff > 20) { LOG(VB_GENERAL, LOG_WARNING, QString("Time difference between the master " "backend and this system is %1 seconds.") .arg(timediff)); } } if (tempMonitorConnection) tempMonitorConnection->DecrRef(); return GENERIC_EXIT_OK; }