int CCurlFile::Stat(const CURL& url, struct __stat64* buffer) { // if file is already running, get info from it if( m_opened ) { CLog::Log(LOGWARNING, "%s - Stat called on open file %s", __FUNCTION__, url.Get().c_str()); if (buffer) { memset(buffer, 0, sizeof(struct __stat64)); buffer->st_size = GetLength(); buffer->st_mode = _S_IFREG; } return 0; } CURL url2(url); ParseAndCorrectUrl(url2); ASSERT(m_state->m_easyHandle == NULL); g_curlInterface.easy_aquire(url2.GetProtocol(), url2.GetHostName(), &m_state->m_easyHandle, NULL); SetCommonOptions(m_state); SetRequestHeaders(m_state); g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_TIMEOUT, 5); g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_NOBODY, 1); g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_WRITEDATA, NULL); /* will cause write failure*/ g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_FILETIME , 1); if(url2.GetProtocol() == "ftp") { // nocwd is less standard, will return empty list for non-existed remote dir on some ftp server, avoid it. if (url2.GetFileName().Right(1).Equals("/")) g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_FTP_FILEMETHOD, CURLFTPMETHOD_SINGLECWD); else g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_FTP_FILEMETHOD, CURLFTPMETHOD_NOCWD); } CURLcode result = g_curlInterface.easy_perform(m_state->m_easyHandle); if(result == CURLE_HTTP_RETURNED_ERROR) { long code; if(g_curlInterface.easy_getinfo(m_state->m_easyHandle, CURLINFO_RESPONSE_CODE, &code) == CURLE_OK && code == 404 ) return -1; } if(result == CURLE_GOT_NOTHING || result == CURLE_HTTP_RETURNED_ERROR || result == CURLE_RECV_ERROR /* some silly shoutcast servers */ ) { /* some http servers and shoutcast servers don't give us any data on a head request */ /* request normal and just fail out, it's their loss */ /* somehow curl doesn't reset CURLOPT_NOBODY properly so reset everything */ SetCommonOptions(m_state); SetRequestHeaders(m_state); g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_TIMEOUT, 5); g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_RANGE, "0-0"); g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_WRITEDATA, NULL); /* will cause write failure*/ g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_FILETIME , 1); result = g_curlInterface.easy_perform(m_state->m_easyHandle); } if( result == CURLE_HTTP_RANGE_ERROR ) { /* crap can't use the range option, disable it and try again */ g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_RANGE, NULL); result = g_curlInterface.easy_perform(m_state->m_easyHandle); } if( result != CURLE_WRITE_ERROR && result != CURLE_OK ) { g_curlInterface.easy_release(&m_state->m_easyHandle, NULL); errno = ENOENT; return -1; } double length; if (CURLE_OK != g_curlInterface.easy_getinfo(m_state->m_easyHandle, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &length) || length < 0.0) { if (url.GetProtocol() == "ftp") { g_curlInterface.easy_release(&m_state->m_easyHandle, NULL); errno = ENOENT; return -1; } else length = 0.0; } SetCorrectHeaders(m_state); if(buffer) { char *content; if (CURLE_OK != g_curlInterface.easy_getinfo(m_state->m_easyHandle, CURLINFO_CONTENT_TYPE, &content)) { g_curlInterface.easy_release(&m_state->m_easyHandle, NULL); errno = ENOENT; return -1; } else { memset(buffer, 0, sizeof(struct __stat64)); buffer->st_size = (int64_t)length; if(content && strstr(content, "text/html")) //consider html files directories buffer->st_mode = _S_IFDIR; else buffer->st_mode = _S_IFREG; } long filetime; if (CURLE_OK != g_curlInterface.easy_getinfo(m_state->m_easyHandle, CURLINFO_FILETIME, &filetime)) { CLog::Log(LOGWARNING, "%s - Cannot get curl filetime for %s", __FUNCTION__, url.Get().c_str()); } else { if (filetime != -1) buffer->st_mtime = filetime; } } g_curlInterface.easy_release(&m_state->m_easyHandle, NULL); return 0; }
CGUIViewState* CGUIViewState::GetViewState(int windowId, const CFileItemList& items) { // don't expect derived classes to clear the sources m_sources.clear(); if (windowId == 0) return GetViewState(g_windowManager.GetActiveWindow(),items); const CURL url=items.GetAsUrl(); if (items.IsAddonsPath()) return new CGUIViewStateAddonBrowser(items); if (items.HasSortDetails()) return new CGUIViewStateFromItems(items); if (url.GetProtocol()=="musicdb") return new CGUIViewStateMusicDatabase(items); if (url.GetProtocol()=="musicsearch") return new CGUIViewStateMusicSearch(items); if (items.IsSmartPlayList() || url.GetProtocol() == "upnp" || items.IsLibraryFolder()) { if (items.GetContent() == "songs" || items.GetContent() == "albums" || items.GetContent() == "mixed") return new CGUIViewStateMusicSmartPlaylist(items); else if (items.GetContent() == "musicvideos") return new CGUIViewStateVideoMusicVideos(items); else if (items.GetContent() == "tvshows") return new CGUIViewStateVideoTVShows(items); else if (items.GetContent() == "episodes") return new CGUIViewStateVideoEpisodes(items); else if (items.GetContent() == "movies") return new CGUIViewStateVideoMovies(items); } if (url.GetProtocol() == "library") return new CGUIViewStateLibrary(items); if (items.IsPlayList()) return new CGUIViewStateMusicPlaylist(items); if (items.GetPath() == "special://musicplaylists/") return new CGUIViewStateWindowMusicSongs(items); if (url.GetProtocol() == "androidapp") return new CGUIViewStateWindowPrograms(items); if (windowId==WINDOW_MUSIC_NAV) return new CGUIViewStateWindowMusicNav(items); if (windowId==WINDOW_MUSIC_FILES) return new CGUIViewStateWindowMusicSongs(items); if (windowId==WINDOW_MUSIC_PLAYLIST) return new CGUIViewStateWindowMusicPlaylist(items); if (windowId==WINDOW_MUSIC_PLAYLIST_EDITOR) return new CGUIViewStateWindowMusicSongs(items); if (windowId==WINDOW_VIDEO_FILES) return new CGUIViewStateWindowVideoFiles(items); if (windowId==WINDOW_VIDEO_NAV) return new CGUIViewStateWindowVideoNav(items); if (windowId==WINDOW_VIDEO_PLAYLIST) return new CGUIViewStateWindowVideoPlaylist(items); if (windowId==WINDOW_PVR) return new CGUIViewStatePVR(items); if (windowId==WINDOW_PICTURES) return new CGUIViewStateWindowPictures(items); if (windowId==WINDOW_PROGRAMS) return new CGUIViewStateWindowPrograms(items); if (windowId==WINDOW_ADDON_BROWSER) return new CGUIViewStateAddonBrowser(items); // Use as fallback/default return new CGUIViewStateGeneral(items); }
bool CPVRDirectory::Exists(const CURL& url) { return (url.GetProtocol() == "pvr" && url.GetHostName() == "recordings"); }