diff options
author | jmarshallnz <jcmarsha@gmail.com> | 2013-01-25 15:55:46 -0800 |
---|---|---|
committer | jmarshallnz <jcmarsha@gmail.com> | 2013-01-25 15:55:46 -0800 |
commit | c950be79577655dad75e89e9939517516756a745 (patch) | |
tree | e45209c511e553901964af97260e4ae27331c482 | |
parent | b62e13b7976581467f1cae55721a1e1dc2394032 (diff) | |
parent | 6e28059b93220b1188461bfc99709cf7d27ae11c (diff) |
Merge pull request #2058 from norbini/ticket_13784_videoscanner_skips_sftp
[Fix] Videoscanner should not skip sftp/ssh sources
-rw-r--r-- | xbmc/filesystem/SFTPDirectory.cpp | 15 | ||||
-rw-r--r-- | xbmc/filesystem/SFTPDirectory.h | 1 | ||||
-rw-r--r-- | xbmc/filesystem/SFTPFile.cpp | 55 | ||||
-rw-r--r-- | xbmc/filesystem/SFTPFile.h | 4 |
4 files changed, 63 insertions, 12 deletions
diff --git a/xbmc/filesystem/SFTPDirectory.cpp b/xbmc/filesystem/SFTPDirectory.cpp index ed04eb236d..a7d7c93769 100644 --- a/xbmc/filesystem/SFTPDirectory.cpp +++ b/xbmc/filesystem/SFTPDirectory.cpp @@ -20,6 +20,7 @@ #include "SFTPDirectory.h" #ifdef HAS_FILESYSTEM_SFTP +#include "utils/log.h" #include "URL.h" using namespace XFILE; @@ -39,4 +40,18 @@ bool CSFTPDirectory::GetDirectory(const CStdString& strPath, CFileItemList &item CSFTPSessionPtr session = CSFTPSessionManager::CreateSession(url); return session->GetDirectory(url.GetWithoutFilename().c_str(), url.GetFileName().c_str(), items); } + +bool CSFTPDirectory::Exists(const char* strPath) +{ + CURL url(strPath); + + CSFTPSessionPtr session = CSFTPSessionManager::CreateSession(url); + if (session) + return session->DirectoryExists(url.GetFileName().c_str()); + else + { + CLog::Log(LOGERROR, "SFTPDirectory: Failed to create session to check exists"); + return false; + } +} #endif diff --git a/xbmc/filesystem/SFTPDirectory.h b/xbmc/filesystem/SFTPDirectory.h index 82ef542a71..bc94a83708 100644 --- a/xbmc/filesystem/SFTPDirectory.h +++ b/xbmc/filesystem/SFTPDirectory.h @@ -35,6 +35,7 @@ namespace XFILE CSFTPDirectory(void); virtual ~CSFTPDirectory(void); virtual bool GetDirectory(const CStdString& strPath, CFileItemList &items); + virtual bool Exists(const char* strPath); }; } #endif diff --git a/xbmc/filesystem/SFTPFile.cpp b/xbmc/filesystem/SFTPFile.cpp index d176969835..34b797fd36 100644 --- a/xbmc/filesystem/SFTPFile.cpp +++ b/xbmc/filesystem/SFTPFile.cpp @@ -35,6 +35,11 @@ #pragma comment(lib, "ssh.lib") #endif +#ifdef TARGET_WINDOWS +#define S_ISDIR(m) ((m & _S_IFDIR) != 0) +#define S_ISREG(m) ((m & _S_IFREG) != 0) +#endif + #ifdef _MSC_VER #define O_RDONLY _O_RDONLY #endif @@ -187,19 +192,20 @@ bool CSFTPSession::GetDirectory(const CStdString &base, const CStdString &folder return false; } -bool CSFTPSession::Exists(const char *path) +bool CSFTPSession::DirectoryExists(const char *path) { bool exists = false; - CSingleLock lock(m_critSect); - if(m_connected) - { - sftp_attributes attributes = sftp_stat(m_sftp_session, CorrectPath(path).c_str()); - exists = attributes != NULL; + uint32_t permissions = 0; + exists = GetItemPermissions(path, permissions); + return exists && S_ISDIR(permissions); +} - if (attributes) - sftp_attributes_free(attributes); - } - return exists; +bool CSFTPSession::FileExists(const char *path) +{ + bool exists = false; + uint32_t permissions = 0; + exists = GetItemPermissions(path, permissions); + return exists && S_ISREG(permissions); } int CSFTPSession::Stat(const char *path, struct __stat64* buffer) @@ -422,6 +428,33 @@ void CSFTPSession::Disconnect() m_session = NULL; } +/*! + \brief Gets POSIX compatible permissions information about the specified file or directory. + \param path Remote SSH path to the file or directory. + \param permissions POSIX compatible permissions information for the file or directory (if it exists). i.e. can use macros S_ISDIR() etc. + \return Returns \e true, if it was possible to get permissions for the file or directory, \e false otherwise. + */ +bool CSFTPSession::GetItemPermissions(const char *path, uint32_t &permissions) +{ + bool gotPermissions = false; + CSingleLock lock(m_critSect); + if(m_connected) + { + sftp_attributes attributes = sftp_stat(m_sftp_session, CorrectPath(path).c_str()); + if (attributes) + { + if (attributes->flags & SSH_FILEXFER_ATTR_PERMISSIONS) + { + permissions = attributes->permissions; + gotPermissions = true; + } + + sftp_attributes_free(attributes); + } + } + return gotPermissions; +} + CCriticalSection CSFTPSessionManager::m_critSect; map<CStdString, CSFTPSessionPtr> CSFTPSessionManager::sessions; @@ -554,7 +587,7 @@ bool CSFTPFile::Exists(const CURL& url) { CSFTPSessionPtr session = CSFTPSessionManager::CreateSession(url); if (session) - return session->Exists(url.GetFileName().c_str()); + return session->FileExists(url.GetFileName().c_str()); else { CLog::Log(LOGERROR, "SFTPFile: Failed to create session to check exists"); diff --git a/xbmc/filesystem/SFTPFile.h b/xbmc/filesystem/SFTPFile.h index 7d3574cc8d..1ac83c8d32 100644 --- a/xbmc/filesystem/SFTPFile.h +++ b/xbmc/filesystem/SFTPFile.h @@ -58,7 +58,8 @@ public: sftp_file CreateFileHande(const CStdString &file); void CloseFileHandle(sftp_file handle); bool GetDirectory(const CStdString &base, const CStdString &folder, CFileItemList &items); - bool Exists(const char *path); + bool DirectoryExists(const char *path); + bool FileExists(const char *path); int Stat(const char *path, struct __stat64* buffer); int Seek(sftp_file handle, uint64_t position); int Read(sftp_file handle, void *buffer, size_t length); @@ -68,6 +69,7 @@ private: bool VerifyKnownHost(ssh_session session); bool Connect(const CStdString &host, unsigned int port, const CStdString &username, const CStdString &password); void Disconnect(); + bool GetItemPermissions(const char *path, uint32_t &permissions); CCriticalSection m_critSect; bool m_connected; |