std::string CFavouritesService::GetFavouritesUrl(const CFileItem& item, int contextWindow) const { CURL url; url.SetProtocol("favourites"); url.SetHostName(CURL::Encode(GetExecutePath(item, contextWindow))); return url.Get(); }
bool CAFPDirectory::ResolveSymlink( const CStdString &dirName, const CStdString &fileName, struct stat *stat, CURL &resolvedUrl) { CSingleLock lock(gAfpConnection); int ret = 0; bool retVal = true; char resolvedLink[MAX_PATH]; CStdString fullpath = dirName; URIUtils::AddSlashAtEnd(fullpath); fullpath += fileName; CPasswordManager::GetInstance().AuthenticateURL(resolvedUrl); resolvedUrl.SetProtocol("afp"); resolvedUrl.SetHostName(gAfpConnection.GetConnectedIp()); ret = gAfpConnection.GetImpl()->afp_wrap_readlink(gAfpConnection.GetVolume(), fullpath.c_str(), resolvedLink, MAX_PATH); if(ret == 0) { fullpath = dirName; URIUtils::AddSlashAtEnd(fullpath); fullpath.append(resolvedLink); 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; fullpath = fullpath.Right(fullpath.length()-1); resolvedUrl.SetFileName(fullpath); ret = gAfpConnection.stat(resolvedUrl, stat); if(ret < 0) { URIUtils::AddSlashAtEnd(fullpath); resolvedUrl.SetFileName(fullpath); ret = gAfpConnection.stat(resolvedUrl, stat); } } else { ret = gAfpConnection.GetImpl()->afp_wrap_getattr(gAfpConnection.GetVolume(), fullpath.c_str(), stat); resolvedUrl.SetFileName(gAfpConnection.GetUrl()->volumename + fullpath); } if (ret != 0) { CLog::Log(LOGERROR, "AFP: Failed to stat(%s) on link resolve %s\n", fullpath.c_str(), strerror(errno)); retVal = false;; } } else { CLog::Log(LOGERROR, "Failed to readlink(%s) %s\n", fullpath.c_str(), strerror(errno)); retVal = false; } return retVal; }
/*! \brief Set a skin file setting. * \param params The parameters. * \details params[0] = Name of skin setting. * params[1] = File mask or add-on type (optional). * params[2] = Extra URL to allow selection from or * content type if mask is an addon-on type (optional). */ static int SetFile(const std::vector<std::string>& params) { int string = CSkinSettings::GetInstance().TranslateString(params[0]); std::string value = CSkinSettings::GetInstance().GetString(string); VECSOURCES localShares; g_mediaManager.GetLocalDrives(localShares); // Note. can only browse one addon type from here // if browsing for addons, required param[1] is addontype string, with optional param[2] // as contenttype string see IAddon.h & ADDON::TranslateXX std::string strMask = (params.size() > 1) ? params[1] : ""; StringUtils::ToLower(strMask); ADDON::TYPE type; if ((type = TranslateType(strMask)) != ADDON_UNKNOWN) { CURL url; url.SetProtocol("addons"); url.SetHostName("enabled"); url.SetFileName(strMask+"/"); localShares.clear(); std::string content = (params.size() > 2) ? params[2] : ""; StringUtils::ToLower(content); url.SetPassword(content); std::string strMask; if (type == ADDON_SCRIPT) strMask = ".py"; std::string replace; if (CGUIDialogFileBrowser::ShowAndGetFile(url.Get(), strMask, TranslateType(type, true), replace, true, true, true)) { if (StringUtils::StartsWithNoCase(replace, "addons://")) CSkinSettings::GetInstance().SetString(string, URIUtils::GetFileName(replace)); else CSkinSettings::GetInstance().SetString(string, replace); } } else { // show all network drives g_mediaManager.GetNetworkLocations(localShares); if (params.size() > 2) { value = params[2]; URIUtils::AddSlashAtEnd(value); bool bIsSource; if (CUtil::GetMatchingSource(value,localShares,bIsSource) < 0) // path is outside shares - add it as a separate one { CMediaSource share; share.strName = g_localizeStrings.Get(13278); share.strPath = value; localShares.push_back(share); } } if (CGUIDialogFileBrowser::ShowAndGetFile(localShares, strMask, g_localizeStrings.Get(1033), value)) CSkinSettings::GetInstance().SetString(string, value); } return 0; }
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(); }
bool CWinLibraryDirectory::GetStoragePath(std::string library, std::string & path) { CURL url; url.SetProtocol("win-lib"); url.SetHostName(library); if (!IsValid(url)) return false; path = url.Get(); return true; }
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(); }
CStdString CTextureCache::GetWrappedImageURL(const CStdString &image, const CStdString &type, const CStdString &options) { if (StringUtils::StartsWith(image, "image://")) return image; // already wrapped CURL url; url.SetProtocol("image"); url.SetUserName(type); url.SetHostName(image); if (!options.IsEmpty()) { url.SetFileName("transform"); url.SetOptions("?" + options); } return url.Get(); }
static bool LoadFromFile(const std::string& strPath, CFileItemList& items) { CXBMCTinyXML doc; if (!doc.LoadFile(strPath)) { CLog::Log(LOGERROR, "Unable to load %s (row %i column %i)", strPath.c_str(), doc.Row(), doc.Column()); return false; } TiXmlElement *root = doc.RootElement(); if (!root || strcmp(root->Value(), "favourites")) { CLog::Log(LOGERROR, "Favourites.xml doesn't contain the <favourites> root element"); return false; } TiXmlElement *favourite = root->FirstChildElement("favourite"); while (favourite) { // format: // <favourite name="Cool Video" thumb="foo.jpg">PlayMedia(c:\videos\cool_video.avi)</favourite> // <favourite name="My Album" thumb="bar.tbn">ActivateWindow(MyMusic,c:\music\my album)</favourite> // <favourite name="Apple Movie Trailers" thumb="path_to_thumb.png">RunScript(special://xbmc/scripts/apple movie trailers/default.py)</favourite> const char *name = favourite->Attribute("name"); const char *thumb = favourite->Attribute("thumb"); if (name && favourite->FirstChild()) { CURL url; url.SetProtocol("favourites"); url.SetHostName(CURL::Encode(favourite->FirstChild()->Value())); const std::string favURL(url.Get()); if (!items.Contains(favURL)) { const CFileItemPtr item(std::make_shared<CFileItem>(name)); item->SetPath(favURL); if (thumb) item->SetArt("thumb", thumb); items.Add(item); } } favourite = favourite->NextSiblingElement("favourite"); } return true; }
CURL URIUtils::CreateArchivePath(const std::string& type, const CURL& archiveUrl, const std::string& pathInArchive, const std::string& password) { CURL url; url.SetProtocol(type); if (!password.empty()) url.SetUserName(password); url.SetHostName(archiveUrl.Get()); /* NOTE: on posix systems, the replacement of \ with / is incorrect. Ideally this would not be done. We need to check that the ZipManager and RarManager code (and elsewhere) doesn't pass in non-posix paths. */ std::string strBuffer(pathInArchive); StringUtils::Replace(strBuffer, '\\', '/'); StringUtils::TrimLeft(strBuffer, "/"); url.SetFileName(strBuffer); return url; }
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; } } }