aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjmarshallnz <jcmarsha@gmail.com>2013-01-25 15:55:46 -0800
committerjmarshallnz <jcmarsha@gmail.com>2013-01-25 15:55:46 -0800
commitc950be79577655dad75e89e9939517516756a745 (patch)
treee45209c511e553901964af97260e4ae27331c482
parentb62e13b7976581467f1cae55721a1e1dc2394032 (diff)
parent6e28059b93220b1188461bfc99709cf7d27ae11c (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.cpp15
-rw-r--r--xbmc/filesystem/SFTPDirectory.h1
-rw-r--r--xbmc/filesystem/SFTPFile.cpp55
-rw-r--r--xbmc/filesystem/SFTPFile.h4
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;