pair<CStdString,CStdString> CPartyModeManager::GetWhereClauseWithHistory() const { CStdString historyWhereMusic; CStdString historyWhereVideo; // now add this on to the normal where clause if (m_history.size()) { if (m_strCurrentFilterMusic.IsEmpty()) historyWhereMusic = "songview.idSong not in ("; else historyWhereMusic = m_strCurrentFilterMusic + " and songview.idSong not in ("; if (m_strCurrentFilterVideo.IsEmpty()) historyWhereVideo = "idMVideo not in ("; else historyWhereVideo = m_strCurrentFilterVideo + " and idMVideo not in ("; for (unsigned int i = 0; i < m_history.size(); i++) { CStdString number; number.Format("%i,", m_history[i].second); if (m_history[i].first == 1) historyWhereMusic += number; if (m_history[i].first == 2) historyWhereVideo += number; } historyWhereMusic.TrimRight(","); historyWhereMusic += ")"; historyWhereVideo.TrimRight(","); historyWhereVideo += ")"; } return make_pair(historyWhereMusic,historyWhereVideo); }
/*! \brief Is the share \e strPath in the virtual directory. \param strPath Share to test \return Returns \e true, if share is in the virtual directory. \note The parameter \e strPath can not be a share with directory. Eg. "iso9660://dir" will return \e false. It must be "iso9660://". */ bool CVirtualDirectory::IsSource(const CStdString& strPath, VECSOURCES *sources, CStdString *name) const { CStdString strPathCpy = strPath; strPathCpy.TrimRight("/"); strPathCpy.TrimRight("\\"); // just to make sure there's no mixed slashing in share/default defines // ie. f:/video and f:\video was not be recognised as the same directory, // resulting in navigation to a lower directory then the share. if(URIUtils::IsDOSPath(strPathCpy)) strPathCpy.Replace("/", "\\"); VECSOURCES shares; if (sources) shares = *sources; else GetSources(shares); for (int i = 0; i < (int)shares.size(); ++i) { const CMediaSource& share = shares.at(i); CStdString strShare = share.strPath; strShare.TrimRight("/"); strShare.TrimRight("\\"); if(URIUtils::IsDOSPath(strShare)) strShare.Replace("/", "\\"); if (strShare == strPathCpy) { if (name) *name = share.strName; return true; } } return false; }
void CXRandR::LoadCustomModeLinesToAllOutputs(void) { /* 歌方: 1、 卦指: 1、 傍苧: 1、 */ Query(); TiXmlDocument xmlDoc; if (!xmlDoc.LoadFile("special://xbmc/userdata/ModeLines.xml")) { return; } TiXmlElement *pRootElement = xmlDoc.RootElement(); if (strcasecmp(pRootElement->Value(), "modelines") != 0) { // TODO ERROR return; } char cmd[255]; CStdString name; CStdString strModeLine; for (TiXmlElement* modeline = pRootElement->FirstChildElement("modeline"); modeline; modeline = modeline->NextSiblingElement("modeline")) { name = modeline->Attribute("label"); name.TrimLeft(" \n\t\r"); name.TrimRight(" \n\t\r"); strModeLine = modeline->FirstChild()->Value(); strModeLine.TrimLeft(" \n\t\r"); strModeLine.TrimRight(" \n\t\r"); if (getenv("XBMC_BIN_HOME")) { snprintf(cmd, sizeof(cmd), "%s/xbmc-xrandr --newmode \"%s\" %s > /dev/null 2>&1", getenv("XBMC_BIN_HOME"), name.c_str(), strModeLine.c_str()); if (system(cmd) != 0) CLog::Log(LOGERROR, "Unable to create modeline \"%s\"", name.c_str()); } for (unsigned int i = 0; i < m_outputs.size(); i++) { if (getenv("XBMC_BIN_HOME")) { snprintf(cmd, sizeof(cmd), "%s/xbmc-xrandr --addmode %s \"%s\" > /dev/null 2>&1", getenv("XBMC_BIN_HOME"),m_outputs[i].name.c_str(), name.c_str()); if (system(cmd) != 0) CLog::Log(LOGERROR, "Unable to add modeline \"%s\"", name.c_str()); } } } }
void PathHelper::RemoveFromPath(CStdString sPath) { CStdString sFullPath = GetProcessPath(); sFullPath.ToLower(); sPath.ToLower(); if ( sPath.Right(1) == _T("\\") ) { sPath = sPath.Left(sPath.length() - 1); } int nStart = (x64_int_cast)sFullPath.find(sPath); while (nStart >= 0) // there may be multiple copies { int nEnd = nStart + (x64_int_cast)sPath.length() + 1; sFullPath = sFullPath.Left(nStart) + sFullPath.Right(sFullPath.length() - nEnd ); sFullPath.TrimRight(); sFullPath.TrimLeft(); if (sFullPath.Left(1) == _T(";")) sFullPath = sFullPath.Mid(1); sFullPath.Replace(_T(";;"),_T(";")); nStart = (x64_int_cast)sFullPath.find(sPath); } SetProcessPath(sFullPath); }
void CDVDPlayerSubtitle::GetCurrentSubtitle(CStdString& strSubtitle, double pts) { strSubtitle = ""; Process(pts); // TODO: move to separate thread? CSingleLock lock(*m_pOverlayContainer); VecOverlays* pOverlays = m_pOverlayContainer->GetOverlays(); if (pOverlays) { for(vector<CDVDOverlay*>::iterator it = pOverlays->begin();it != pOverlays->end();it++) { CDVDOverlay* pOverlay = *it; if (pOverlay->IsOverlayType(DVDOVERLAY_TYPE_TEXT) && (pOverlay->iPTSStartTime <= pts) && (pOverlay->iPTSStopTime >= pts || pOverlay->iPTSStopTime == 0LL)) { CDVDOverlayText::CElement* e = ((CDVDOverlayText*)pOverlay)->m_pHead; while (e) { if (e->IsElementType(CDVDOverlayText::ELEMENT_TYPE_TEXT)) { CDVDOverlayText::CElementText* t = (CDVDOverlayText::CElementText*)e; strSubtitle += t->m_text; strSubtitle += "\n"; } e = e->pNext; } } } } strSubtitle.TrimRight('\n'); }
bool ParseIPFilter(CStdString in, std::list<CStdString>* output /*=0*/) { bool valid = true; in.Replace(_T("\n"), _T(" ")); in.Replace(_T("\r"), _T(" ")); in.Replace(_T("\t"), _T(" ")); while (in.Replace(_T(" "), _T(" "))); in.TrimLeft(_T(" ")); in.TrimRight(_T(" ")); in += _T(" "); int pos; while ((pos = in.Find(_T(" "))) != -1) { CStdString ip = in.Left(pos); if (ip == _T("")) break; in = in.Mid(pos + 1); if (ip == _T("*") || IsValidAddressFilter(ip)) { if (output) output->push_back(ip); } else valid = false; } return valid; }
void CWeatherJob::LocalizeOverview(CStdString &str) { CStdStringArray words; StringUtils::SplitString(str, " ", words); str.clear(); for (unsigned int i = 0; i < words.size(); i++) { LocalizeOverviewToken(words[i]); str += words[i] + " "; } str.TrimRight(" "); }
CStdString CTextureCacheJob::DecodeImageURL(const CStdString &url, unsigned int &width, unsigned int &height, std::string &additional_info) { // unwrap the URL as required CStdString image(url); additional_info.clear(); width = height = 0; if (url.compare(0, 8, "image://") == 0) { // format is image://[type@]<url_encoded_path>?options CURL thumbURL(url); if (!thumbURL.GetUserName().IsEmpty()) { if (thumbURL.GetUserName() == "music") additional_info = "music"; else return ""; // we don't re-cache special images (eg picturefolder/video embedded thumbs) } image = thumbURL.GetHostName(); CURL::Decode(image); CStdString optionString = thumbURL.GetOptions().Mid(1); optionString.TrimRight('/'); // in case XBMC adds a slash std::vector<CStdString> options; StringUtils::SplitString(optionString, "&", options); for (std::vector<CStdString>::iterator i = options.begin(); i != options.end(); i++) { CStdString option, value; int pos = i->Find('='); if (pos != -1) { option = i->Left(pos); value = i->Mid(pos + 1); } else { option = *i; value = ""; } if (option == "size" && value == "thumb") { width = height = g_advancedSettings.GetThumbSize(); } else if (option == "flipped") { additional_info = "flipped"; } } } return image; }
const CStdString CVideoInfoTag::GetCast(bool bIncludeRole /*= false*/) const { CStdString strLabel; for (iCast it = m_cast.begin(); it != m_cast.end(); ++it) { CStdString character; if (it->strRole.IsEmpty() || !bIncludeRole) character.Format("%s\n", it->strName.c_str()); else character.Format("%s %s %s\n", it->strName.c_str(), g_localizeStrings.Get(20347).c_str(), it->strRole.c_str()); strLabel += character; } return strLabel.TrimRight("\n"); }
bool DocProvHelper::ForceDirectory(CStdString lpDirectory) const { ASSERT(lpDirectory); CStdString szDirectory = lpDirectory; /* TXTEX_IGNORE */ szDirectory.TrimRight(_T("\\")); /* TXTEX_IGNORE */ szDirectory.TrimRight(_T("/")); if( (GetFilePath(szDirectory) == szDirectory) || CGeneral::FileExists(szDirectory) ) return true; if (PathIsUNCFolderShare(szDirectory)) return true; // if it_T('s a share assume it exists - it')ll fail at the next level up if not if(!ForceDirectory(GetFilePath(szDirectory))) return false; if (!CreateDirectory(szDirectory, NULL)) return false; return true; }
void CMemoryUnitManager::GetMemoryUnitSources(VECSOURCES &shares) { for (unsigned int i = 0; i < m_memUnits.size(); i++) { CMediaSource share; CStdString volumeName = m_memUnits[i]->GetVolumeName(); volumeName.TrimRight(' '); // Memory Unit # (volumeName) (fs) if (volumeName.IsEmpty()) share.strName.Format("%s %i (%s)", g_localizeStrings.Get(20136).c_str(), i + 1, m_memUnits[i]->GetFileSystem()); else share.strName.Format("%s %i (%s) (%s)", g_localizeStrings.Get(20136).c_str(), i + 1, volumeName.c_str(), m_memUnits[i]->GetFileSystem()); share.strPath.Format("mem%i://", i); shares.push_back(share); } }
CStdString CMediaManager::GetDiskLabel(const CStdString& devicePath) { #ifdef TARGET_WINDOWS if(!m_bhasoptical) return ""; CStdString strDevice = TranslateDevicePath(devicePath); WCHAR cVolumenName[128]; WCHAR cFSName[128]; URIUtils::AddSlashAtEnd(strDevice); if(GetVolumeInformationW(CStdStringW(strDevice).c_str(), cVolumenName, 127, NULL, NULL, NULL, cFSName, 127)==0) return ""; g_charsetConverter.wToUTF8(cVolumenName, strDevice); return strDevice.TrimRight(" "); #else return MEDIA_DETECT::CDetectDVDMedia::GetDVDLabel(); #endif }
bool CGUIDialogPluginSettings::TranslateSingleString(const CStdString &strCondition, vector<CStdString> &condVec) { CStdString strTest = strCondition; strTest.ToLower(); strTest.TrimLeft(" "); strTest.TrimRight(" "); int pos1 = strTest.Find("("); int pos2 = strTest.Find(","); int pos3 = strTest.Find(")"); if (pos1 >= 0 && pos2 > pos1 && pos3 > pos2) { condVec.push_back(strTest.Left(pos1)); condVec.push_back(strTest.Mid(pos1 + 1, pos2 - pos1 - 1)); condVec.push_back(strTest.Mid(pos2 + 1, pos3 - pos2 - 1)); return true; } return false; }
/*---------------------------------------------------------------------- | CUPnPDirectory::GetDirectory +---------------------------------------------------------------------*/ bool CUPnPDirectory::GetResource(const CURL& path, CFileItem &item) { if(path.GetProtocol() != "upnp") return false; CUPnP* upnp = CUPnP::GetInstance(); if(!upnp) return false; CStdString uuid = path.GetHostName(); CStdString object = path.GetFileName(); object.TrimRight("/"); CURL::Decode(object); PLT_DeviceDataReference device; if(!FindDeviceWait(upnp, uuid.c_str(), device)) { CLog::Log(LOGERROR, "CUPnPDirectory::GetResource - unable to find uuid %s", uuid.c_str()); return false; } PLT_MediaObjectListReference list; if (NPT_FAILED(upnp->m_MediaBrowser->BrowseSync(device, object.c_str(), list, true))) { CLog::Log(LOGERROR, "CUPnPDirectory::GetResource - unable to find object %s", object.c_str()); return false; } if (list.IsNull() || !list->GetItemCount()) { CLog::Log(LOGERROR, "CUPnPDirectory::GetResource - no items returned for object %s", object.c_str()); return false; } PLT_MediaObjectList::Iterator entry = list->GetFirstItem(); if (entry == 0) return false; return UPNP::GetResource(*entry, item); }
void CCurlFile::ParseAndCorrectUrl(CURL &url2) { CStdString strProtocol = url2.GetTranslatedProtocol(); url2.SetProtocol(strProtocol); if( strProtocol.Equals("ftp") || strProtocol.Equals("ftps") ) { /* this is uggly, depending on from where */ /* we get the link it may or may not be */ /* url encoded. if handed from ftpdirectory */ /* it won't be so let's handle that case */ CStdString partial, filename(url2.GetFileName()); CStdStringArray array; /* our current client doesn't support utf8 */ g_charsetConverter.utf8ToStringCharset(filename); /* TODO: create a tokenizer that doesn't skip empty's */ CUtil::Tokenize(filename, array, "/"); filename.Empty(); for(CStdStringArray::iterator it = array.begin(); it != array.end(); it++) { if(it != array.begin()) filename += "/"; partial = *it; CURL::Encode(partial); filename += partial; } /* make sure we keep slashes */ if(url2.GetFileName().Right(1) == "/") filename += "/"; url2.SetFileName(filename); CStdString options = url2.GetOptions().Mid(1); options.TrimRight('/'); // hack for trailing slashes being added from source m_ftpauth = ""; m_ftpport = ""; m_ftppasvip = false; /* parse options given */ CUtil::Tokenize(options, array, "&"); for(CStdStringArray::iterator it = array.begin(); it != array.end(); it++) { CStdString name, value; int pos = it->Find('='); if(pos >= 0) { name = it->Left(pos); value = it->Mid(pos+1, it->size()); } else { name = (*it); value = ""; } if(name.Equals("auth")) { m_ftpauth = value; if(m_ftpauth.IsEmpty()) m_ftpauth = "any"; } else if(name.Equals("active")) { m_ftpport = value; if(value.IsEmpty()) m_ftpport = "-"; } else if(name.Equals("pasvip")) { if(value == "0") m_ftppasvip = false; else m_ftppasvip = true; } } /* ftp has no options */ url2.SetOptions(""); } else if( strProtocol.Equals("http") || strProtocol.Equals("https")) { if (g_guiSettings.GetBool("network.usehttpproxy") && !g_guiSettings.GetString("network.httpproxyserver").empty() && !g_guiSettings.GetString("network.httpproxyport").empty() && m_proxy.IsEmpty()) { m_proxy = g_guiSettings.GetString("network.httpproxyserver"); m_proxy += ":" + g_guiSettings.GetString("network.httpproxyport"); if (g_guiSettings.GetString("network.httpproxyusername").length() > 0 && m_proxyuserpass.IsEmpty()) { m_proxyuserpass = g_guiSettings.GetString("network.httpproxyusername"); m_proxyuserpass += ":" + g_guiSettings.GetString("network.httpproxypassword"); } m_proxytype = (ProxyType)g_guiSettings.GetInt("network.httpproxytype"); CLog::Log(LOGDEBUG, "Using proxy %s, type %d", m_proxy.c_str(), proxyType2CUrlProxyType[m_proxytype]); } // get username and password m_username = url2.GetUserName(); m_password = url2.GetPassWord(); // handle any protocol options CStdString options = url2.GetProtocolOptions(); options.TrimRight('/'); // hack for trailing slashes being added from source if (options.length() > 0) { // clear protocol options url2.SetProtocolOptions(""); // set xbmc headers CStdStringArray array; CUtil::Tokenize(options, array, "&"); for(CStdStringArray::iterator it = array.begin(); it != array.end(); it++) { // parse name, value CStdString name, value; int pos = it->Find('='); if(pos >= 0) { name = it->Left(pos); value = it->Mid(pos+1, it->size()); } else { name = (*it); value = ""; } // url decode value CURL::Decode(value); if(name.Equals("auth")) { m_httpauth = value; if(m_httpauth.IsEmpty()) m_httpauth = "any"; } else if (name.Equals("Referer")) SetReferer(value); else if (name.Equals("User-Agent")) SetUserAgent(value); else if (name.Equals("Cookie")) SetCookie(value); else if (name.Equals("Encoding")) SetContentEncoding(value); else if (name.Equals("noshout") && value.Equals("true")) m_skipshout = true; else SetRequestHeader(name, value); } } } if (m_username.length() > 0 && m_password.length() > 0) m_url = url2.GetWithoutUserDetails(); else m_url = url2.Get(); }
// Generates the drive url, (like iso9660://) // from the CCdInfo class void CDetectDVDMedia::DetectMediaType() { bool bCDDA(false); CLog::Log(LOGINFO, "Detecting DVD-ROM media filesystem..."); CStdString strNewUrl; CCdIoSupport cdio; // Delete old CD-Information if ( m_pCdInfo != NULL ) { delete m_pCdInfo; m_pCdInfo = NULL; } // Detect new CD-Information m_pCdInfo = cdio.GetCdInfo(); if (m_pCdInfo == NULL) { CLog::Log(LOGERROR, "Detection of DVD-ROM media failed."); return ; } CLog::Log(LOGINFO, "Tracks overall:%i; Audio tracks:%i; Data tracks:%i", m_pCdInfo->GetTrackCount(), m_pCdInfo->GetAudioTrackCount(), m_pCdInfo->GetDataTrackCount() ); // Detect ISO9660(mode1/mode2), CDDA filesystem or UDF if (m_pCdInfo->IsISOHFS(1) || m_pCdInfo->IsIso9660(1) || m_pCdInfo->IsIso9660Interactive(1)) { strNewUrl = "iso9660://"; m_isoReader.Scan(); } else { if (m_pCdInfo->IsUDF(1) || m_pCdInfo->IsUDFX(1)) strNewUrl = "D:\\"; else if (m_pCdInfo->IsAudio(1)) { strNewUrl = "cdda://local/"; bCDDA = true; } else strNewUrl = "D:\\"; } if (m_pCdInfo->IsISOUDF(1)) { if (!g_advancedSettings.m_detectAsUdf) { strNewUrl = "iso9660://"; m_isoReader.Scan(); } else { strNewUrl = "D:\\"; } } CLog::Log(LOGINFO, "Using protocol %s", strNewUrl.c_str()); if (m_pCdInfo->IsValidFs()) { if (!m_pCdInfo->IsAudio(1)) CLog::Log(LOGINFO, "Disc label: %s", m_pCdInfo->GetDiscLabel().c_str()); } else { CLog::Log(LOGWARNING, "Filesystem is not supported"); } CStdString strLabel = ""; if (bCDDA) { strLabel = "Audio-CD"; } else { strLabel = m_pCdInfo->GetDiscLabel(); strLabel.TrimRight(" "); } SetNewDVDShareUrl( strNewUrl , bCDDA, strLabel); }
CStdString CPlayListM3U::GetBestBandwidthStream(const CStdString &strFileName, size_t bandwidth) { // we may be passed a playlist that does not contain playlists of different // bitrates (eg: this playlist is really the HLS video). So, default the // return to the filename so it can be played char szLine[4096]; CStdString strLine; CStdString strPlaylist = strFileName; size_t maxBandwidth = 0; // if we cannot get the last / we wont be able to determine the sub-playlists size_t baseEnd = strPlaylist.rfind('/'); if (baseEnd == std::string::npos) return strPlaylist; // store the base path (the path without the filename) CStdString basePath = strPlaylist.substr(0, baseEnd + 1); // open the file, and if it fails, return CFile file; if (!file.Open(strFileName) ) { file.Close(); return strPlaylist; } // convert bandwidth specified in kbps to bps used by the m3u8 bandwidth *= 1000; while (file.ReadString(szLine, 1024)) { // read and trim a line strLine = szLine; strLine.TrimRight(" \t\r\n"); strLine.TrimLeft(" \t"); // skip the first line if (strLine == M3U_START_MARKER) continue; else if (strLine.Left(strlen(M3U_STREAM_MARKER)) == M3U_STREAM_MARKER) { // parse the line so we can pull out the bandwidth std::map< CStdString, CStdString > params = ParseStreamLine(strLine); std::map< CStdString, CStdString >::iterator it = params.find(M3U_BANDWIDTH_MARKER); if (it != params.end()) { size_t streamBandwidth = atoi(it->second.c_str()); if ((maxBandwidth < streamBandwidth) && (streamBandwidth <= bandwidth)) { // read the next line if (!file.ReadString(szLine, 1024)) continue; strLine = szLine; strLine.TrimRight(" \t\r\n"); strLine.TrimLeft(" \t"); // this line was empty if (strLine.empty()) continue; // store the max bandwidth maxBandwidth = streamBandwidth; // if the path is absolute just use it if (CURL::IsFullPath(strLine)) strPlaylist = strLine; else strPlaylist = basePath + strLine; } } } } CLog::Log(LOGINFO, "Auto-selecting %s based on configured bandwidth.", strPlaylist.c_str()); return strPlaylist; }
bool CPlayListM3U::Load(const CStdString& strFileName) { char szLine[4096]; CStdString strLine; CStdString strInfo = ""; long lDuration = 0; Clear(); m_strPlayListName = URIUtils::GetFileName(strFileName); URIUtils::GetParentPath(strFileName, m_strBasePath); CFile file; if (!file.Open(strFileName) ) { file.Close(); return false; } while (file.ReadString(szLine, 1024)) { strLine = szLine; strLine.TrimRight(" \t\r\n"); strLine.TrimLeft(" \t"); if (strLine.Left( (int)strlen(M3U_INFO_MARKER) ) == M3U_INFO_MARKER) { // start of info int iColon = (int)strLine.find(":"); int iComma = (int)strLine.find(","); if (iColon >= 0 && iComma >= 0 && iComma > iColon) { // Read the info and duration iColon++; CStdString strLength = strLine.Mid(iColon, iComma - iColon); lDuration = atoi(strLength.c_str()); iComma++; strInfo = strLine.Right((int)strLine.size() - iComma); g_charsetConverter.unknownToUTF8(strInfo); } } else if (strLine != M3U_START_MARKER && strLine.Left(strlen(M3U_ARTIST_MARKER)) != M3U_ARTIST_MARKER && strLine.Left(strlen(M3U_ALBUM_MARKER)) != M3U_ALBUM_MARKER ) { CStdString strFileName = strLine; if (strFileName.size() > 0 && strFileName[0] == '#') continue; // assume a comment or something else we don't support // Skip self - do not load playlist recursively if (URIUtils::GetFileName(strFileName).Equals(m_strPlayListName)) continue; if (strFileName.length() > 0) { g_charsetConverter.unknownToUTF8(strFileName); // If no info was read from from the extended tag information, use the file name if (strInfo.length() == 0) { strInfo = URIUtils::GetFileName(strFileName); } // should substitition occur befor or after charset conversion?? strFileName = URIUtils::SubstitutePath(strFileName); // Get the full path file name and add it to the the play list CUtil::GetQualifiedFilename(m_strBasePath, strFileName); CFileItemPtr newItem(new CFileItem(strInfo)); newItem->SetPath(strFileName); if (lDuration && newItem->IsAudio()) newItem->GetMusicInfoTag()->SetDuration(lDuration); Add(newItem); // Reset the values just in case there part of the file have the extended marker // and part don't strInfo = ""; lDuration = 0; } } } file.Close(); return true; }
bool CPlayListPLS::Load(const CStdString &strFile) { //read it from the file CStdString strFileName(strFile); m_strPlayListName = URIUtils::GetFileName(strFileName); Clear(); bool bShoutCast = false; if( strFileName.Left(8).Equals("shout://") ) { strFileName.Delete(0, 8); strFileName.Insert(0, "http://"); m_strBasePath = ""; bShoutCast = true; } else URIUtils::GetParentPath(strFileName, m_strBasePath); CFile file; if (!file.Open(strFileName) ) { file.Close(); return false; } if (file.GetLength() > 1024*1024) { CLog::Log(LOGWARNING, "%s - File is larger than 1 MB, most likely not a playlist",__FUNCTION__); return false; } char szLine[4096]; CStdString strLine; // run through looking for the [playlist] marker. // if we find another http stream, then load it. while (1) { if ( !file.ReadString(szLine, sizeof(szLine) ) ) { file.Close(); return size() > 0; } strLine = szLine; strLine.TrimLeft(" \t"); strLine.TrimRight(" \n\r"); if(strLine.Equals(START_PLAYLIST_MARKER)) break; // if there is something else before playlist marker, this isn't a pls file if(!strLine.IsEmpty()) return false; } bool bFailed = false; while (file.ReadString(szLine, sizeof(szLine) ) ) { strLine = szLine; StringUtils::RemoveCRLF(strLine); int iPosEqual = strLine.Find("="); if (iPosEqual > 0) { CStdString strLeft = strLine.Left(iPosEqual); iPosEqual++; CStdString strValue = strLine.Right(strLine.size() - iPosEqual); strLeft.ToLower(); while (strLeft[0] == ' ' || strLeft[0] == '\t') strLeft.erase(0,1); if (strLeft == "numberofentries") { m_vecItems.reserve(atoi(strValue.c_str())); } else if (strLeft.Left(4) == "file") { vector <int>::size_type idx = atoi(strLeft.c_str() + 4); if (!Resize(idx)) { bFailed = true; break; } // Skip self - do not load playlist recursively if (URIUtils::GetFileName(strValue).Equals(URIUtils::GetFileName(strFileName))) continue; if (m_vecItems[idx - 1]->GetLabel().empty()) m_vecItems[idx - 1]->SetLabel(URIUtils::GetFileName(strValue)); CFileItem item(strValue, false); if (bShoutCast && !item.IsAudio()) strValue.Replace("http:", "shout:"); strValue = URIUtils::SubstitutePath(strValue); CUtil::GetQualifiedFilename(m_strBasePath, strValue); g_charsetConverter.unknownToUTF8(strValue); m_vecItems[idx - 1]->SetPath(strValue); } else if (strLeft.Left(5) == "title") { vector <int>::size_type idx = atoi(strLeft.c_str() + 5); if (!Resize(idx)) { bFailed = true; break; } g_charsetConverter.unknownToUTF8(strValue); m_vecItems[idx - 1]->SetLabel(strValue); } else if (strLeft.Left(6) == "length") { vector <int>::size_type idx = atoi(strLeft.c_str() + 6); if (!Resize(idx)) { bFailed = true; break; } m_vecItems[idx - 1]->GetMusicInfoTag()->SetDuration(atol(strValue.c_str())); } else if (strLeft == "playlistname") { m_strPlayListName = strValue; g_charsetConverter.unknownToUTF8(m_strPlayListName); } } } file.Close(); if (bFailed) { CLog::Log(LOGERROR, "File %s is not a valid PLS playlist. Location of first file,title or length is not permitted (eg. File0 should be File1)", URIUtils::GetFileName(strFileName).c_str()); return false; } // check for missing entries ivecItems p = m_vecItems.begin(); while ( p != m_vecItems.end()) { if ((*p)->GetPath().empty()) { p = m_vecItems.erase(p); } else { ++p; } } return true; }
bool PVRIptvData::LoadPlayList(void) { if (m_strM3uUrl.IsEmpty()) { XBMC->Log(LOG_NOTICE, "Playlist file path is not configured. Channels not loaded."); return false; } CStdString strPlaylistContent; if (!GetCachedFileContents(M3U_FILE_NAME, m_strM3uUrl, strPlaylistContent)) { XBMC->Log(LOG_ERROR, "Unable to load playlist file '%s': file is missing or empty.", m_strM3uUrl.c_str()); return false; } std::stringstream stream(strPlaylistContent); /* load channels */ bool bFirst = true; int iUniqueChannelId = 0; int iUniqueGroupId = 0; int iCurrentGroupId = 0; int iChannelNum = 0; int iEPGTimeShift = 0; PVRIptvChannel tmpChannel; tmpChannel.strTvgId = ""; tmpChannel.strChannelName = ""; tmpChannel.strTvgName = ""; tmpChannel.strTvgLogo = ""; tmpChannel.iTvgShift = 0; char szLine[1024]; while(stream.getline(szLine, 1024)) { CStdString strLine = ""; strLine.append(szLine); strLine.TrimRight(" \t\r\n"); strLine.TrimLeft(" \t"); if (strLine.IsEmpty()) { continue; } if (bFirst) { bFirst = false; if (strLine.Left(3) == "\xEF\xBB\xBF") { strLine.Delete(0, 3); } if (strLine.Left((int)strlen(M3U_START_MARKER)) == M3U_START_MARKER) { double fTvgShift = atof(ReadMarkerValue(strLine, TVG_INFO_SHIFT_MARKER)); iEPGTimeShift = (int) (fTvgShift * 3600.0); continue; } else { break; } } if (strLine.Left((int)strlen(M3U_INFO_MARKER)) == M3U_INFO_MARKER) { bool bRadio = false; double fTvgShift = 0; CStdString strChnlName = ""; CStdString strTvgId = ""; CStdString strTvgName = ""; CStdString strTvgLogo = ""; CStdString strGroupName = ""; CStdString strRadio = ""; // parse line int iColon = (int)strLine.Find(':'); int iComma = (int)strLine.ReverseFind(','); if (iColon >= 0 && iComma >= 0 && iComma > iColon) { // parse name iComma++; strChnlName = strLine.Right((int)strLine.size() - iComma).Trim(); tmpChannel.strChannelName = XBMC->UnknownToUTF8(strChnlName); // parse info CStdString strInfoLine = strLine.Mid(++iColon, --iComma - iColon); strTvgId = ReadMarkerValue(strInfoLine, TVG_INFO_ID_MARKER); strTvgName = ReadMarkerValue(strInfoLine, TVG_INFO_NAME_MARKER); strTvgLogo = ReadMarkerValue(strInfoLine, TVG_INFO_LOGO_MARKER); strGroupName = ReadMarkerValue(strInfoLine, GROUP_NAME_MARKER); strRadio = ReadMarkerValue(strInfoLine, RADIO_MARKER); fTvgShift = atof(ReadMarkerValue(strInfoLine, TVG_INFO_SHIFT_MARKER)); if (strTvgId.IsEmpty()) { char buff[255]; sprintf(buff, "%d", atoi(strInfoLine)); strTvgId.append(buff); } if (strTvgLogo.IsEmpty()) { strTvgLogo = strChnlName; } bRadio = !strRadio.CompareNoCase("true"); tmpChannel.strTvgId = strTvgId; tmpChannel.strTvgName = XBMC->UnknownToUTF8(strTvgName); tmpChannel.strTvgLogo = XBMC->UnknownToUTF8(strTvgLogo); tmpChannel.iTvgShift = (int)(fTvgShift * 3600.0); tmpChannel.bRadio = bRadio; if (tmpChannel.iTvgShift == 0 && iEPGTimeShift != 0) { tmpChannel.iTvgShift = iEPGTimeShift; } if (!strGroupName.IsEmpty()) { strGroupName = XBMC->UnknownToUTF8(strGroupName); PVRIptvChannelGroup * pGroup; if ((pGroup = FindGroup(strGroupName)) == NULL) { PVRIptvChannelGroup group; group.strGroupName = strGroupName; group.iGroupId = ++iUniqueGroupId; group.bRadio = bRadio; m_groups.push_back(group); iCurrentGroupId = iUniqueGroupId; } else { iCurrentGroupId = pGroup->iGroupId; } } } } else if (strLine[0] != '#') { PVRIptvChannel channel; channel.iUniqueId = ++iUniqueChannelId; channel.iChannelNumber = ++iChannelNum; channel.strTvgId = tmpChannel.strTvgId; channel.strChannelName = tmpChannel.strChannelName; channel.strTvgName = tmpChannel.strTvgName; channel.strTvgLogo = tmpChannel.strTvgLogo; channel.iTvgShift = tmpChannel.iTvgShift; channel.bRadio = tmpChannel.bRadio; channel.strStreamURL = strLine; channel.iEncryptionSystem = 0; if (iCurrentGroupId > 0) { channel.bRadio = m_groups.at(iCurrentGroupId - 1).bRadio; m_groups.at(iCurrentGroupId - 1).members.push_back(channel.iChannelNumber); } m_channels.push_back(channel); tmpChannel.strTvgId = ""; tmpChannel.strChannelName = ""; tmpChannel.strTvgName = ""; tmpChannel.strTvgLogo = ""; tmpChannel.iTvgShift = 0; tmpChannel.bRadio = false; } } stream.clear(); if (m_channels.size() == 0) { XBMC->Log(LOG_ERROR, "Unable to load channels from file '%s': file is corrupted.", m_strM3uUrl.c_str()); return false; } ApplyChannelsLogos(); XBMC->Log(LOG_NOTICE, "Loaded %d channels.", m_channels.size()); return true; }
void CFileItemHandler::HandleFileItem(const char *ID, bool allowFile, const char *resultname, CFileItemPtr item, const CVariant ¶meterObject, const CVariant &validFields, CVariant &result, bool append /* = true */) { CVariant object; bool hasFileField = false; bool hasThumbnailField = false; if (item.get()) { for (unsigned int i = 0; i < validFields.size(); i++) { CStdString field = validFields[i].asString(); if (field == "file") hasFileField = true; if (field == "thumbnail") hasThumbnailField = true; } if (allowFile && hasFileField) { if (item->HasVideoInfoTag() && !item->GetVideoInfoTag()->GetPath().IsEmpty()) object["file"] = item->GetVideoInfoTag()->GetPath().c_str(); if (item->HasMusicInfoTag() && !item->GetMusicInfoTag()->GetURL().IsEmpty()) object["file"] = item->GetMusicInfoTag()->GetURL().c_str(); if (!object.isMember("file")) object["file"] = item->GetPath().c_str(); } if (ID) { if (stricmp(ID, "genreid") == 0) { CStdString genre = item->GetPath(); genre.TrimRight('/'); object[ID] = atoi(genre.c_str()); } else if (item->HasMusicInfoTag() && item->GetMusicInfoTag()->GetDatabaseId() > 0) object[ID] = (int)item->GetMusicInfoTag()->GetDatabaseId(); else if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_iDbId > 0) object[ID] = item->GetVideoInfoTag()->m_iDbId; if (stricmp(ID, "id") == 0) { if (item->HasMusicInfoTag()) object["type"] = "song"; else if (item->HasVideoInfoTag()) { switch (item->GetVideoContentType()) { case VIDEODB_CONTENT_EPISODES: object["type"] = "episode"; break; case VIDEODB_CONTENT_MUSICVIDEOS: object["type"] = "musicvideo"; break; case VIDEODB_CONTENT_MOVIES: object["type"] = "movie"; break; } } else if (item->HasPictureInfoTag()) object["type"] = "picture"; if (!object.isMember("type")) object["type"] = "unknown"; } } if (hasThumbnailField) { if (item->HasThumbnail()) object["thumbnail"] = item->GetThumbnailImage().c_str(); else if (item->HasVideoInfoTag()) { CStdString strPath, strFileName; URIUtils::Split(item->GetCachedVideoThumb(), strPath, strFileName); CStdString cachedThumb = strPath + "auto-" + strFileName; if (CFile::Exists(cachedThumb)) object["thumbnail"] = cachedThumb; } if (!object.isMember("thumbnail")) object["thumbnail"] = ""; } if (item->HasVideoInfoTag()) FillDetails(item->GetVideoInfoTag(), item, validFields, object); if (item->HasMusicInfoTag()) FillDetails(item->GetMusicInfoTag(), item, validFields, object); if (item->HasPictureInfoTag()) FillDetails(item->GetPictureInfoTag(), item, validFields, object); object["label"] = item->GetLabel().c_str(); } else object = CVariant(CVariant::VariantTypeNull); if (resultname) { if (append) result[resultname].append(object); else result[resultname] = object; } }
void CScraperParser::RemoveWhiteSpace(CStdString &string) { string.TrimLeft(" \t\r\n"); string.TrimRight(" \t\r\n"); }
/*---------------------------------------------------------------------- | CUPnPDirectory::GetDirectory +---------------------------------------------------------------------*/ bool CUPnPDirectory::GetResource(const CURL& path, CFileItem &item) { if(path.GetProtocol() != "upnp") return false; CUPnP* upnp = CUPnP::GetInstance(); if(!upnp) return false; CStdString uuid = path.GetHostName(); CStdString object = path.GetFileName(); object.TrimRight("/"); CURL::Decode(object); PLT_DeviceDataReference device; if(!FindDeviceWait(upnp, uuid.c_str(), device)) return false; PLT_MediaObjectListReference list; if (NPT_FAILED(upnp->m_MediaBrowser->BrowseSync(device, object.c_str(), list, true))) return false; PLT_MediaObjectList::Iterator entry = list->GetFirstItem(); if (entry == 0) return false; PLT_MediaItemResource resource; // look for a resource with "xbmc-get" protocol // if we can't find one, keep the first resource if(NPT_FAILED(NPT_ContainerFind((*entry)->m_Resources, CProtocolFinder("xbmc-get"), resource))) { if((*entry)->m_Resources.GetItemCount()) resource = (*entry)->m_Resources[0]; else return false; } // store original path so we remember it item.SetProperty("original_listitem_url", item.GetPath()); item.SetProperty("original_listitem_mime", item.GetMimeType(false)); // if it's an item, path is the first url to the item // we hope the server made the first one reachable for us // (it could be a format we dont know how to play however) item.SetPath((const char*) resource.m_Uri); // look for content type in protocol info if (resource.m_ProtocolInfo.IsValid()) { CLog::Log(LOGDEBUG, "CUPnPDirectory::GetResource - resource protocol info '%s'", (const char*)(resource.m_ProtocolInfo.ToString())); if (resource.m_ProtocolInfo.GetContentType().Compare("application/octet-stream") != 0) { item.SetMimeType((const char*)resource.m_ProtocolInfo.GetContentType()); } } else { CLog::Log(LOGERROR, "CUPnPDirectory::GetResource - invalid protocol info '%s'", (const char*)(resource.m_ProtocolInfo.ToString())); } // look for subtitles unsigned subs = 0; for(unsigned r = 0; r < (*entry)->m_Resources.GetItemCount(); r++) { PLT_MediaItemResource& res = (*entry)->m_Resources[r]; PLT_ProtocolInfo& info = res.m_ProtocolInfo; static const char* allowed[] = { "text/srt" , "text/ssa" , "text/sub" , "text/idx" }; for(unsigned type = 0; type < sizeof(allowed)/sizeof(allowed[0]); type++) { if(info.Match(PLT_ProtocolInfo("*", "*", allowed[type], "*"))) { CStdString prop; prop.Format("upnp:subtitle:%d", ++subs); item.SetProperty(prop, (const char*)res.m_Uri); break; } } } return true; }
//********************************************************************************************* bool CRTVDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items) { CURL url(strPath); CStdString strRoot = strPath; URIUtils::AddSlashAtEnd(strRoot); // Host name is "*" so we try to discover all ReplayTVs. This requires some trickery but works. if (url.GetHostName() == "*") { // Check to see whether the URL's path is blank or "Video" if (url.GetFileName() == "" || url.GetFileName() == "Video") { int iOldSize=items.Size(); struct RTV * rtv = NULL; int numRTV; // Request that all ReplayTVs on the LAN identify themselves. Each ReplayTV // is given 3000ms to respond to the request. rtv_discovery returns an array // of structs containing the IP and friendly name of all ReplayTVs found on the LAN. // For some reason, DVArchive doesn't respond to this request (probably only responds // to requests from an IP address of a real ReplayTV). numRTV = rtv_discovery(&rtv, 3000); // Run through the array and add the ReplayTVs found as folders in XBMC. // We must add the IP of each ReplayTV as if it is a file name at the end of a the // auto-discover URL--e.g. rtv://*/192.168.1.100--because XBMC does not permit // dyamically added shares and will not play from them. This little trickery is // the best workaround I could come up with. for (int i = 0; i < numRTV; i++) { CFileItemPtr pItem(new CFileItem(rtv[i].friendlyName)); // This will keep the /Video or / and allow one to set up an auto ReplayTV // share of either type--simple file listing or ReplayGuide listing. pItem->SetPath(strRoot + rtv[i].hostname); pItem->m_bIsFolder = true; pItem->SetLabelPreformated(true); items.Add(pItem); } free(rtv); return (items.Size()>iOldSize); // Else the URL's path should be an IP address of the ReplayTV } else { CStdString strURL, strRTV; int pos; // Isolate the IP from the URL and replace the "*" with the real IP // of the ReplayTV. E.g., rtv://*/Video/192.168.1.100/ becomes // rtv://192.168.1.100/Video/ . This trickery makes things work. strURL = strRoot.TrimRight('/'); pos = strURL.ReverseFind('/'); strRTV = strURL.Left(pos + 1); strRTV.Replace("*", strURL.Mid(pos + 1)); CURL tmpURL(strRTV); // Force the newly constructed share into the right variables to // be further processed by the remainder of GetDirectory. url = tmpURL; strRoot = strRTV; } } // Allow for ReplayTVs on ports other than 80 CStdString strHostAndPort; strHostAndPort = url.GetHostName(); if (url.HasPort()) { char buffer[10]; strHostAndPort += ':'; strHostAndPort += itoa(url.GetPort(), buffer, 10); } // No path given, list shows from ReplayGuide if (url.GetFileName() == "") { unsigned char * data = NULL; // Get the RTV guide data in XML format rtv_get_guide_xml(&data, strHostAndPort.c_str()); // Begin parsing the XML data TiXmlDocument xmlDoc; xmlDoc.Parse( (const char *) data ); if ( xmlDoc.Error() ) { free(data); return false; } TiXmlElement* pRootElement = xmlDoc.RootElement(); if (!pRootElement) { free(data); return false; } const TiXmlNode *pChild = pRootElement->FirstChild(); while (pChild > 0) { CStdString strTagName = pChild->Value(); if ( !strcmpi(strTagName.c_str(), "ITEM") ) { const TiXmlNode *nameNode = pChild->FirstChild("DISPLAYNAME"); // const TiXmlNode *qualityNode = pChild->FirstChild("QUALITY"); const TiXmlNode *recordedNode = pChild->FirstChild("RECORDED"); const TiXmlNode *pathNode = pChild->FirstChild("PATH"); // const TiXmlNode *durationNode = pChild->FirstChild("DURATION"); const TiXmlNode *sizeNode = pChild->FirstChild("SIZE"); const TiXmlNode *atrbNode = pChild->FirstChild("ATTRIB"); SYSTEMTIME dtDateTime; DWORD dwFileSize = 0; memset(&dtDateTime, 0, sizeof(dtDateTime)); // DISPLAYNAME const char* szName = NULL; if (nameNode) { szName = nameNode->FirstChild()->Value() ; } else { // Something went wrong, the recording has no name free(data); return false; } // QUALITY // const char* szQuality = NULL; // if (qualityNode) // { // szQuality = qualityNode->FirstChild()->Value() ; // } // RECORDED if (recordedNode) { CStdString strRecorded = recordedNode->FirstChild()->Value(); int iYear, iMonth, iDay; iYear = atoi(strRecorded.Left(4).c_str()); iMonth = atoi(strRecorded.Mid(5, 2).c_str()); iDay = atoi(strRecorded.Mid(8, 2).c_str()); dtDateTime.wYear = iYear; dtDateTime.wMonth = iMonth; dtDateTime.wDay = iDay; int iHour, iMin, iSec; iHour = atoi(strRecorded.Mid(11, 2).c_str()); iMin = atoi(strRecorded.Mid(14, 2).c_str()); iSec = atoi(strRecorded.Mid(17, 2).c_str()); dtDateTime.wHour = iHour; dtDateTime.wMinute = iMin; dtDateTime.wSecond = iSec; } // PATH const char* szPath = NULL; if (pathNode) { szPath = pathNode->FirstChild()->Value() ; } else { // Something went wrong, the recording has no filename free(data); return false; } // DURATION // const char* szDuration = NULL; // if (durationNode) // { // szDuration = durationNode->FirstChild()->Value() ; // } // SIZE // NOTE: Size here is actually just duration in minutes because // filesize is not reported by the stripped down GuideParser I use if (sizeNode) { dwFileSize = atol( sizeNode->FirstChild()->Value() ); } // ATTRIB // NOTE: Not currently reported in the XML guide data, nor is it particularly // needed unless someone wants to add the ability to sub-divide the recordings // into categories, as on a real RTV. int attrib = 0; if (atrbNode) { attrib = atoi( atrbNode->FirstChild()->Value() ); } bool bIsFolder(false); if (attrib & FILE_ATTRIBUTE_DIRECTORY) bIsFolder = true; CFileItemPtr pItem(new CFileItem(szName)); pItem->m_dateTime=dtDateTime; pItem->SetPath(strRoot + szPath); // Hack to show duration of show in minutes as KB in XMBC because // it doesn't currently permit showing duration in minutes. // E.g., a 30 minute show will show as 29.3 KB in XBMC. pItem->m_dwSize = dwFileSize * 1000; pItem->m_bIsFolder = bIsFolder; pItem->SetLabelPreformated(true); items.Add(pItem); } pChild = pChild->NextSibling(); } free(data); // Path given (usually Video), list filenames only } else { unsigned char * data; char * p, * q; unsigned long status; // Return a listing of all files in the given path status = rtv_list_files(&data, strHostAndPort.c_str(), url.GetFileName().c_str()); if (status == 0) { return false; } // Loop through the file list using pointers p and q, where p will point to the current // filename and q will point to the next filename p = (char *) data; while (p) { // Look for the end of the current line of the file listing q = strchr(p, '\n'); // If found, replace the newline character with the NULL terminator if (q) { *q = '\0'; // Increment q so that it points to the next filename q++; // *p should be the current null-terminated filename in the list if (*p) { // Only display MPEG files in XBMC (but not circular.mpg, as that is the RTV // video buffer and XBMC may cause problems if it tries to play it) if (strstr(p, ".mpg") && !strstr(p, "circular")) { CFileItemPtr pItem(new CFileItem(p)); pItem->SetPath(strRoot + p); pItem->m_bIsFolder = false; // The list returned by the RTV doesn't include file sizes, unfortunately //pItem->m_dwSize = atol(szSize); pItem->SetLabelPreformated(true); items.Add(pItem); } } } // Point p to the next filename in the list and loop p = q; } free(data); } return true; }
void COptions::SetOption(int nOptionID, LPCTSTR value, bool save /*=true*/) { CStdString str = value; Init(); switch (nOptionID) { case OPTION_SERVERPORT: case OPTION_TLSPORTS: { std::set<int> portSet; str.TrimLeft(_T(" ,")); int pos = str.FindOneOf(_T(" ,")); while (pos != -1) { int port = _ttoi(str.Left(pos)); if (port >= 1 && port <= 65535) portSet.insert(port); str = str.Mid(pos + 1); str.TrimLeft(_T(" ,")); pos = str.FindOneOf(_T(" ,")); } if (str != _T("")) { int port = _ttoi(str); if (port >= 1 && port <= 65535) portSet.insert(port); } str = _T(""); for (std::set<int>::const_iterator iter = portSet.begin(); iter != portSet.end(); iter++) { CStdString tmp; tmp.Format(_T("%d "), *iter); str += tmp; } str.TrimRight(' '); } break; case OPTION_WELCOMEMESSAGE: { std::vector<CStdString> msgLines; int oldpos = 0; str.Replace(_T("\r\n"), _T("\n")); int pos = str.Find(_T("\n")); CStdString line; while (pos != -1) { if (pos) { line = str.Mid(oldpos, pos - oldpos); line = line.Left(CONST_WELCOMEMESSAGE_LINESIZE); line.TrimRight(_T(" ")); if (msgLines.size() || line != _T("")) msgLines.push_back(line); } oldpos = pos + 1; pos = str.Find(_T("\n"), oldpos); } line = str.Mid(oldpos); if (line != _T("")) { line = line.Left(CONST_WELCOMEMESSAGE_LINESIZE); msgLines.push_back(line); } str = _T(""); for (unsigned int i = 0; i < msgLines.size(); i++) str += msgLines[i] + _T("\r\n"); str.TrimRight(_T("\r\n")); if (str == _T("")) { str = _T("%v"); str += _T("\r\nwritten by Tim Kosse ([email protected])"); str += _T("\r\nPlease visit https://filezilla-project.org/"); } } break; case OPTION_ADMINIPBINDINGS: { CStdString sub; std::list<CStdString> ipBindList; for (unsigned int i = 0; i<_tcslen(value); i++) { TCHAR cur = value[i]; if ((cur < '0' || cur > '9') && cur != '.' && cur != ':') { if (sub == _T("") && cur == '*') { ipBindList.clear(); ipBindList.push_back(_T("*")); break; } if (sub != _T("")) { if (IsIpAddress(sub)) ipBindList.push_back(sub); sub = _T(""); } } else sub += cur; } if (sub != _T("")) { if (IsIpAddress(sub)) ipBindList.push_back(sub); } str = _T(""); for (std::list<CStdString>::iterator iter = ipBindList.begin(); iter!=ipBindList.end(); iter++) if (!IsLocalhost(*iter)) str += *iter + _T(" "); str.TrimRight(_T(" ")); } break; case OPTION_ADMINPASS: if (str != _T("") && str.GetLength() < 6) return; break; case OPTION_MODEZ_DISALLOWED_IPS: case OPTION_IPFILTER_ALLOWED: case OPTION_IPFILTER_DISALLOWED: case OPTION_ADMINIPADDRESSES: { str.Replace('\r', ' '); str.Replace('\n', ' '); str.Replace('\r', ' '); while (str.Replace(_T(" "), _T(" "))); str += _T(" "); CStdString ips; int pos = str.Find(' '); while (pos != -1) { CStdString sub = str.Left(pos); str = str.Mid(pos + 1); str.TrimLeft(' '); if (sub == _T("*")) ips += _T(" ") + sub; else { if (IsValidAddressFilter(sub)) ips += " " + sub; pos = str.Find(' '); } } ips.TrimLeft(' '); str = ips; } break; case OPTION_IPBINDINGS: { std::list<CStdString> ipBindList; str += _T(" "); while (!str.empty()) { int pos = str.Find(' '); if (pos < 0) { break; } CStdString sub = str.Left(pos); str = str.Mid(pos + 1); if (sub == _T("*")) { ipBindList.clear(); ipBindList.push_back(_T("*")); break; } else if (IsIpAddress(sub, true)) { ipBindList.push_back(sub); } } if (ipBindList.empty()) ipBindList.push_back(_T("*")); str.clear(); for (auto const& ip : ipBindList) { str += ip + _T(" "); } str.TrimRight(_T(" ")); } break; case OPTION_CUSTOMPASVIPSERVER: if (str.Find(_T("filezilla.sourceforge.net")) != -1) str = _T("http://ip.filezilla-project.org/ip.php"); break; } { simple_lock lock(m_mutex); m_sOptionsCache[nOptionID-1].bCached = TRUE; m_sOptionsCache[nOptionID-1].nType = 0; m_sOptionsCache[nOptionID-1].str = str; m_OptionsCache[nOptionID-1]=m_sOptionsCache[nOptionID-1]; } if (!save) return; USES_CONVERSION; CStdString xmlFileName = GetExecutableDirectory() + _T("FileZilla Server.xml"); char* bufferA = T2A(xmlFileName); if (!bufferA) return; TiXmlDocument document; if (!document.LoadFile(bufferA)) return; TiXmlElement* pRoot = document.FirstChildElement("FileZillaServer"); if (!pRoot) return; TiXmlElement* pSettings = pRoot->FirstChildElement("Settings"); if (!pSettings) pSettings = pRoot->LinkEndChild(new TiXmlElement("Settings"))->ToElement(); TiXmlElement* pItem; for (pItem = pSettings->FirstChildElement("Item"); pItem; pItem = pItem->NextSiblingElement("Item")) { const char* pName = pItem->Attribute("name"); if (!pName) continue; CStdString name(pName); if (name != m_Options[nOptionID-1].name) continue; break; } if (!pItem) pItem = pSettings->LinkEndChild(new TiXmlElement("Item"))->ToElement(); pItem->Clear(); pItem->SetAttribute("name", ConvToNetwork(m_Options[nOptionID - 1].name).c_str()); pItem->SetAttribute("type", "string"); pItem->LinkEndChild(new TiXmlText(ConvToNetwork(value).c_str())); document.SaveFile(bufferA); }