bool CPlexClient::Init(const TiXmlElement* DeviceNode) { m_url = ""; m_presence = XMLUtils::GetAttribute(DeviceNode, "presence") == "1"; if (!m_presence) return false; m_uuid = XMLUtils::GetAttribute(DeviceNode, "clientIdentifier"); m_owned = XMLUtils::GetAttribute(DeviceNode, "owned"); m_serverName = XMLUtils::GetAttribute(DeviceNode, "name"); m_accessToken = XMLUtils::GetAttribute(DeviceNode, "accessToken"); m_httpsRequired = XMLUtils::GetAttribute(DeviceNode, "httpsRequired"); m_platform = XMLUtils::GetAttribute(DeviceNode, "platform"); std::vector<PlexConnection> connections; const TiXmlElement* ConnectionNode = DeviceNode->FirstChildElement("Connection"); while (ConnectionNode) { PlexConnection connection; connection.port = XMLUtils::GetAttribute(ConnectionNode, "port"); connection.address = XMLUtils::GetAttribute(ConnectionNode, "address"); connection.protocol = XMLUtils::GetAttribute(ConnectionNode, "protocol"); connection.external = XMLUtils::GetAttribute(ConnectionNode, "local") == "0" ? 1 : 0; connections.push_back(connection); ConnectionNode = ConnectionNode->NextSiblingElement("Connection"); } CURL url; if (!connections.empty()) { // sort so that all external=0 are first. These are the local connections. std::sort(connections.begin(), connections.end(), [] (PlexConnection const& a, PlexConnection const& b) { return a.external < b.external; }); for (const auto &connection : connections) { url.SetHostName(connection.address); url.SetPort(atoi(connection.port.c_str())); url.SetProtocol(connection.protocol); url.SetProtocolOptions("&X-Plex-Token=" + m_accessToken); int timeout = connection.external ? 5 : 1; if (CPlexUtils::GetIdentity(url, timeout)) { CLog::Log(LOGDEBUG, "CPlexClient::Init " "serverName(%s), ipAddress(%s), protocol(%s)", m_serverName.c_str(), connection.address.c_str(), connection.protocol.c_str()); m_url = url.Get(); m_protocol = url.GetProtocol(); m_local = (connection.external == 0); break; } } } return !m_url.empty(); }
std::string CGUIDialogNetworkSetup::ConstructPath() const { CURL url; if (m_protocol == NET_PROTOCOL_SMB) url.SetProtocol("smb"); else if (m_protocol == NET_PROTOCOL_FTP) url.SetProtocol("ftp"); else if (m_protocol == NET_PROTOCOL_HTTP) url.SetProtocol("http"); else if (m_protocol == NET_PROTOCOL_HTTPS) url.SetProtocol("https"); else if (m_protocol == NET_PROTOCOL_DAV) url.SetProtocol("dav"); else if (m_protocol == NET_PROTOCOL_DAVS) url.SetProtocol("davs"); else if (m_protocol == NET_PROTOCOL_UPNP) url.SetProtocol("upnp"); else if (m_protocol == NET_PROTOCOL_RSS) url.SetProtocol("rss"); else if (m_protocol == NET_PROTOCOL_NFS) url.SetProtocol("nfs"); else if (m_protocol == NET_PROTOCOL_SFTP) url.SetProtocol("sftp"); if (!m_username.empty()) { url.SetUserName(m_username); if (!m_password.empty()) url.SetPassword(m_password); } if(!m_server.empty()) url.SetHostName(m_server); if (((m_protocol == NET_PROTOCOL_FTP) || (m_protocol == NET_PROTOCOL_HTTP) || (m_protocol == NET_PROTOCOL_HTTPS) || (m_protocol == NET_PROTOCOL_DAV) || (m_protocol == NET_PROTOCOL_DAVS) || (m_protocol == NET_PROTOCOL_RSS) || (m_protocol == NET_PROTOCOL_SFTP) || (m_protocol == NET_PROTOCOL_NFS)) && !m_port.empty() && atoi(m_port.c_str()) > 0) { url.SetPort(atoi(m_port.c_str())); } if (!m_path.empty()) url.SetFileName(m_path); return url.Get(); }
bool CPlexClient::Init(std::string data, std::string ip) { m_url = ""; int port = 32400; m_protocol = "http"; std::string s; std::istringstream f(data); while (std::getline(f, s)) { int pos = s.find(':'); if (pos > 0) { std::string substr = s.substr(0, pos); std::string name = StringUtils::Trim(substr); substr = s.substr(pos + 1); std::string val = StringUtils::Trim(substr); if (name == "Content-Type") m_contentType = val; else if (name == "Resource-Identifier") m_uuid = val; else if (name == "Name") m_serverName = val; else if (name == "Port") port = atoi(val.c_str()); } } CURL url; url.SetHostName(ip); url.SetPort(port); url.SetProtocol(m_protocol); if (CPlexUtils::GetIdentity(url, 2)) m_url = url.Get(); return !m_url.empty(); }
bool CZeroconfDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items) { assert(strPath.substr(0, 11) == "zeroconf://"); CStdString path = strPath.substr(11, strPath.length()); URIUtils::RemoveSlashAtEnd(path); if(path.empty()) { std::vector<CZeroconfBrowser::ZeroconfService> found_services = CZeroconfBrowser::GetInstance()->GetFoundServices(); for(std::vector<CZeroconfBrowser::ZeroconfService>::iterator it = found_services.begin(); it != found_services.end(); ++it) { //only use discovered services we can connect to through directory CStdString tmp; if(GetXBMCProtocol(it->GetType(), tmp)) { CFileItemPtr item(new CFileItem("", true)); CURL url; url.SetProtocol("zeroconf"); CStdString service_path = CZeroconfBrowser::ZeroconfService::toPath(*it); CURL::Encode(service_path); url.SetFileName(service_path); item->m_strPath = url.Get(); //now do the formatting CStdString protocol = GetHumanReadableProtocol(it->GetType()); item->SetLabel(it->GetName() + " (" + protocol + ")"); item->SetLabelPreformated(true); //just set the default folder icon item->FillInDefaultIcon(); items.Add(item); } } return true; } else { //decode the path first CStdString decoded = path; CURL::Decode(decoded); try { CZeroconfBrowser::ZeroconfService zeroconf_service = CZeroconfBrowser::ZeroconfService::fromPath(decoded); if(!CZeroconfBrowser::GetInstance()->ResolveService(zeroconf_service)) { CLog::Log(LOGINFO, "CZeroconfDirectory::GetDirectory service ( %s ) could not be resolved in time", zeroconf_service.GetName().c_str()); return false; } else { assert(!zeroconf_service.GetIP().empty()); CURL service; service.SetPort(zeroconf_service.GetPort()); service.SetHostName(zeroconf_service.GetIP()); //do protocol conversion (_smb._tcp -> smb) //ToDo: try automatic conversion -> remove leading '_' and '._tcp'? CStdString protocol; if(!GetXBMCProtocol(zeroconf_service.GetType(), protocol)) { CLog::Log(LOGERROR, "CZeroconfDirectory::GetDirectory Unknown service type (%s), skipping; ", zeroconf_service.GetType().c_str()); return false; } service.SetProtocol(protocol); return CDirectory::GetDirectory(service.Get(), items, "", true, true); } } catch (std::runtime_error& e) { CLog::Log(LOGERROR, "CZeroconfDirectory::GetDirectory failed getting directory: '%s'. Error: '%s'", decoded.c_str(), e.what()); return false; } } }
bool CNFSDirectory::ResolveSymlink( const CStdString &dirName, struct nfsdirent *dirent, CURL &resolvedUrl) { CSingleLock lock(gNfsConnection); int ret = 0; bool retVal = true; CStdString fullpath = dirName; char resolvedLink[MAX_PATH]; URIUtils::AddSlashAtEnd(fullpath); fullpath.append(dirent->name); resolvedUrl.Reset(); resolvedUrl.SetPort(2049); resolvedUrl.SetProtocol("nfs"); resolvedUrl.SetHostName(gNfsConnection.GetConnectedIp()); ret = gNfsConnection.GetImpl()->nfs_readlink(gNfsConnection.GetNfsContext(), fullpath.c_str(), resolvedLink, MAX_PATH); if(ret == 0) { struct stat tmpBuffer = {0}; fullpath = dirName; URIUtils::AddSlashAtEnd(fullpath); fullpath.append(resolvedLink); //special case - if link target is absolute it could be even another export //intervolume symlinks baby ... if(resolvedLink[0] == '/') { //use the special stat function for using an extra context //because we are inside of a dir traversation //and just can't change the global nfs context here //without destroying something... fullpath = resolvedLink; resolvedUrl.SetFileName(fullpath); ret = gNfsConnection.stat(resolvedUrl, &tmpBuffer); } else { ret = gNfsConnection.GetImpl()->nfs_stat(gNfsConnection.GetNfsContext(), fullpath.c_str(), &tmpBuffer); resolvedUrl.SetFileName(gNfsConnection.GetConnectedExport() + fullpath); } if (ret != 0) { CLog::Log(LOGERROR, "NFS: Failed to stat(%s) on link resolve %s\n", fullpath.c_str(), gNfsConnection.GetImpl()->nfs_get_error(gNfsConnection.GetNfsContext())); retVal = false;; } else { dirent->inode = tmpBuffer.st_ino; dirent->mode = tmpBuffer.st_mode; dirent->size = tmpBuffer.st_size; dirent->atime.tv_sec = tmpBuffer.st_atime; dirent->mtime.tv_sec = tmpBuffer.st_mtime; dirent->ctime.tv_sec = tmpBuffer.st_ctime; //map stat mode to nf3type if(S_ISBLK(tmpBuffer.st_mode)){ dirent->type = NF3BLK; } else if(S_ISCHR(tmpBuffer.st_mode)){ dirent->type = NF3CHR; } else if(S_ISDIR(tmpBuffer.st_mode)){ dirent->type = NF3DIR; } else if(S_ISFIFO(tmpBuffer.st_mode)){ dirent->type = NF3FIFO; } else if(S_ISREG(tmpBuffer.st_mode)){ dirent->type = NF3REG; } else if(S_ISLNK(tmpBuffer.st_mode)){ dirent->type = NF3LNK; } else if(S_ISSOCK(tmpBuffer.st_mode)){ dirent->type = NF3SOCK; } } } else { CLog::Log(LOGERROR, "Failed to readlink(%s) %s\n", fullpath.c_str(), gNfsConnection.GetImpl()->nfs_get_error(gNfsConnection.GetNfsContext())); retVal = false; } return retVal; }
CStdString CGUIDialogNetworkSetup::ConstructPath() const { CURL url; if (m_protocol == NET_PROTOCOL_SMB) url.SetProtocol("smb"); else if (m_protocol == NET_PROTOCOL_FTP) url.SetProtocol("ftp"); else if (m_protocol == NET_PROTOCOL_HTTP) url.SetProtocol("http"); else if (m_protocol == NET_PROTOCOL_HTTPS) url.SetProtocol("https"); else if (m_protocol == NET_PROTOCOL_DAV) url.SetProtocol("dav"); else if (m_protocol == NET_PROTOCOL_DAVS) url.SetProtocol("davs"); else if (m_protocol == NET_PROTOCOL_DAAP) url.SetProtocol("daap"); else if (m_protocol == NET_PROTOCOL_UPNP) url.SetProtocol("upnp"); else if (m_protocol == NET_PROTOCOL_TUXBOX) url.SetProtocol("tuxbox"); else if (m_protocol == NET_PROTOCOL_RSS) url.SetProtocol("rss"); else if (m_protocol == NET_PROTOCOL_HTSP) url.SetProtocol("htsp"); else if (m_protocol == NET_PROTOCOL_VTP) url.SetProtocol("vtp"); else if (m_protocol == NET_PROTOCOL_MYTH) url.SetProtocol("myth"); else if (m_protocol == NET_PROTOCOL_NFS) url.SetProtocol("nfs"); else if (m_protocol == NET_PROTOCOL_SFTP) url.SetProtocol("sftp"); else if (m_protocol == NET_PROTOCOL_AFP) url.SetProtocol("afp"); if (!m_username.IsEmpty()) { url.SetUserName(m_username); if (!m_password.IsEmpty()) url.SetPassword(m_password); } if(!m_server.IsEmpty()) url.SetHostName(m_server); if (((m_protocol == NET_PROTOCOL_FTP) || (m_protocol == NET_PROTOCOL_HTTP) || (m_protocol == NET_PROTOCOL_HTTPS) || (m_protocol == NET_PROTOCOL_DAV) || (m_protocol == NET_PROTOCOL_DAVS) || (m_protocol == NET_PROTOCOL_RSS) || (m_protocol == NET_PROTOCOL_DAAP && !m_server.IsEmpty()) || (m_protocol == NET_PROTOCOL_HTSP) || (m_protocol == NET_PROTOCOL_VTP) || (m_protocol == NET_PROTOCOL_MYTH) || (m_protocol == NET_PROTOCOL_TUXBOX) || (m_protocol == NET_PROTOCOL_SFTP) || (m_protocol == NET_PROTOCOL_NFS)) && !m_port.IsEmpty() && atoi(m_port.c_str()) > 0) { url.SetPort(atoi(m_port)); } if (!m_path.IsEmpty()) url.SetFileName(m_path); return url.Get(); }
bool CZeroconfDirectory::GetDirectory(const CURL& url, CFileItemList &items) { assert(url.IsProtocol("zeroconf")); std::string strPath = url.Get(); std::string path = strPath.substr(11, strPath.length()); URIUtils::RemoveSlashAtEnd(path); if(path.empty()) { std::vector<CZeroconfBrowser::ZeroconfService> found_services = CZeroconfBrowser::GetInstance()->GetFoundServices(); for(std::vector<CZeroconfBrowser::ZeroconfService>::iterator it = found_services.begin(); it != found_services.end(); ++it) { //only use discovered services we can connect to through directory std::string tmp; if(GetXBMCProtocol(it->GetType(), tmp)) { CFileItemPtr item(new CFileItem("", true)); CURL url; url.SetProtocol("zeroconf"); std::string service_path(CURL::Encode(CZeroconfBrowser::ZeroconfService::toPath(*it))); url.SetFileName(service_path); item->SetPath(url.Get()); //now do the formatting std::string protocol = GetHumanReadableProtocol(it->GetType()); item->SetLabel(it->GetName() + " (" + protocol + ")"); item->SetLabelPreformated(true); //just set the default folder icon item->FillInDefaultIcon(); items.Add(item); } } return true; } else { //decode the path first std::string decoded(CURL::Decode(path)); try { CZeroconfBrowser::ZeroconfService zeroconf_service = CZeroconfBrowser::ZeroconfService::fromPath(decoded); if(!CZeroconfBrowser::GetInstance()->ResolveService(zeroconf_service)) { CLog::Log(LOGINFO, "CZeroconfDirectory::GetDirectory service ( %s ) could not be resolved in time", zeroconf_service.GetName().c_str()); return false; } else { assert(!zeroconf_service.GetIP().empty()); CURL service; service.SetPort(zeroconf_service.GetPort()); service.SetHostName(zeroconf_service.GetIP()); //do protocol conversion (_smb._tcp -> smb) //ToDo: try automatic conversion -> remove leading '_' and '._tcp'? std::string protocol; if(!GetXBMCProtocol(zeroconf_service.GetType(), protocol)) { CLog::Log(LOGERROR, "CZeroconfDirectory::GetDirectory Unknown service type (%s), skipping; ", zeroconf_service.GetType().c_str()); return false; } service.SetProtocol(protocol); //first try to show the txt-record defined path if any if(GetDirectoryFromTxtRecords(zeroconf_service, service, items)) { return true; } else//no txt record path - so let the CDirectory handler show the folders { // CDirectory::GetDirectory returns false if authorization is required // The target vfs directory will call RequireAuthentication but that is // is not good enough as we can be running as a job and not under main thread, // so authentication dialog does not get called. Set it again here so // authentication dialog gets called and we will get called again with user/pass setup. bool status = CDirectory::GetDirectory(service, items, "", DIR_FLAG_ALLOW_PROMPT); if(!status) RequireAuthentication(service); return status; } } } catch (std::runtime_error& e) { CLog::Log(LOGERROR, "CZeroconfDirectory::GetDirectory failed getting directory: '%s'. Error: '%s'", decoded.c_str(), e.what()); return false; } } }