aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarlson2k <k2k@narod.ru>2014-11-17 22:55:33 +0400
committerKarlson2k <k2k@narod.ru>2014-11-17 22:55:33 +0400
commitd8a405884716f45785b33b198c69030e20da06a4 (patch)
treeaa81ccbdc15017bf93ed890e2f76aac9c82235a0
parentc75d23c714dcdbd02907bb29bbd80730883ee73b (diff)
parentaeebd22d2e88fd14f1b0624d0bdbc6f791a75892 (diff)
Merge pull request #5740 from elupus/samba_fixes
Samba fixes and cleanup for helix
-rw-r--r--xbmc/Application.cpp4
-rw-r--r--xbmc/URL.cpp16
-rw-r--r--xbmc/Util.cpp16
-rw-r--r--xbmc/Util.h1
-rw-r--r--xbmc/filesystem/SMBDirectory.cpp14
-rw-r--r--xbmc/filesystem/SMBFile.cpp122
-rw-r--r--xbmc/filesystem/SMBFile.h4
7 files changed, 56 insertions, 121 deletions
diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp
index 415e4c267d..ec53704ca7 100644
--- a/xbmc/Application.cpp
+++ b/xbmc/Application.cpp
@@ -3555,6 +3555,10 @@ void CApplication::Stop(int exitCode)
CSFTPSessionManager::DisconnectAllSessions();
#endif
+#if defined(TARGET_POSIX) && defined(HAS_FILESYSTEM_SMB)
+ smb.Deinit();
+#endif
+
CLog::Log(LOGNOTICE, "unload skin");
UnloadSkin();
diff --git a/xbmc/URL.cpp b/xbmc/URL.cpp
index 74542764fc..ed4549dd4c 100644
--- a/xbmc/URL.cpp
+++ b/xbmc/URL.cpp
@@ -286,15 +286,7 @@ void CURL::Parse(const std::string& strURL1)
}
iPos = iSlash + 1;
if (iEnd > iPos)
- {
m_strFileName = strURL.substr(iPos, iEnd - iPos);
-
- iSlash = m_strFileName.find("/");
- if(iSlash == std::string::npos)
- m_strShareName = m_strFileName;
- else
- m_strShareName = m_strFileName.substr(0, iSlash);
- }
}
// iso9960 doesnt have an hostname;-)
@@ -321,7 +313,7 @@ void CURL::Parse(const std::string& strURL1)
StringUtils::Replace(m_strFileName, '\\', '/');
- /* update extension */
+ /* update extension + sharename */
SetFileName(m_strFileName);
/* decode urlencoding on this stuff */
@@ -346,6 +338,12 @@ void CURL::SetFileName(const std::string& strFileName)
else
m_strFileType = "";
+ slash = m_strFileName.find_first_of(GetDirectorySeparator());
+ if(slash == std::string::npos)
+ m_strShareName = m_strFileName;
+ else
+ m_strShareName = m_strFileName.substr(0, slash);
+
StringUtils::Trim(m_strFileType);
StringUtils::ToLower(m_strFileType);
}
diff --git a/xbmc/Util.cpp b/xbmc/Util.cpp
index ec8d3a853d..1760beb010 100644
--- a/xbmc/Util.cpp
+++ b/xbmc/Util.cpp
@@ -809,6 +809,22 @@ void CUtil::StatI64ToStat64(struct __stat64 *result, struct _stati64 *stat)
#endif
}
+void CUtil::StatToStat64(struct __stat64 *result, const struct stat *stat)
+{
+ memset(result, 0, sizeof(*result));
+ result->st_dev = stat->st_dev;
+ result->st_ino = stat->st_ino;
+ result->st_mode = stat->st_mode;
+ result->st_nlink = stat->st_nlink;
+ result->st_uid = stat->st_uid;
+ result->st_gid = stat->st_gid;
+ result->st_rdev = stat->st_rdev;
+ result->st_size = stat->st_size;
+ result->st_atime = stat->st_atime;
+ result->st_mtime = stat->st_mtime;
+ result->st_ctime = stat->st_ctime;
+}
+
void CUtil::Stat64ToStat(struct stat *result, struct __stat64 *stat)
{
result->st_dev = stat->st_dev;
diff --git a/xbmc/Util.h b/xbmc/Util.h
index 804bfb80cf..76af6da8d3 100644
--- a/xbmc/Util.h
+++ b/xbmc/Util.h
@@ -106,6 +106,7 @@ public:
static CStdString GetNextFilename(const CStdString &fn_template, int max);
static CStdString GetNextPathname(const CStdString &path_template, int max);
static void StatToStatI64(struct _stati64 *result, struct stat *stat);
+ static void StatToStat64(struct __stat64 *result, const struct stat *stat);
static void Stat64ToStatI64(struct _stati64 *result, struct __stat64 *stat);
static void StatI64ToStat64(struct __stat64 *result, struct _stati64 *stat);
static void Stat64ToStat(struct stat *result, struct __stat64 *stat);
diff --git a/xbmc/filesystem/SMBDirectory.cpp b/xbmc/filesystem/SMBDirectory.cpp
index 0815208e07..1fa00e6bff 100644
--- a/xbmc/filesystem/SMBDirectory.cpp
+++ b/xbmc/filesystem/SMBDirectory.cpp
@@ -172,9 +172,7 @@ bool CSMBDirectory::GetDirectory(const CURL& url, CFileItemList &items)
}
FILETIME fileTime, localTime;
- LONGLONG ll = Int32x32To64(lTimeDate & 0xffffffff, 10000000) + 116444736000000000ll;
- fileTime.dwLowDateTime = (DWORD) (ll & 0xffffffff);
- fileTime.dwHighDateTime = (DWORD)(ll >> 32);
+ TimeTToFileTime(lTimeDate, &fileTime);
FileTimeToLocalFileTime(&fileTime, &localTime);
if (bIsDir)
@@ -255,7 +253,7 @@ int CSMBDirectory::OpenDir(const CURL& url, std::string& strAuth)
fd = smbc_opendir(s.c_str());
}
- while (fd < 0) /* only to avoid goto in following code */
+ if (fd < 0) /* only to avoid goto in following code */
{
std::string cError;
@@ -263,21 +261,15 @@ int CSMBDirectory::OpenDir(const CURL& url, std::string& strAuth)
{
if (m_flags & DIR_FLAG_ALLOW_PROMPT)
RequireAuthentication(urlIn);
- break;
}
-
- if (errno == ENODEV || errno == ENOENT)
+ else if (errno == ENODEV || errno == ENOENT)
cError = StringUtils::Format(g_localizeStrings.Get(770).c_str(),errno);
else
cError = strerror(errno);
if (m_flags & DIR_FLAG_ALLOW_PROMPT)
SetErrorDialog(257, cError.c_str());
- break;
- }
- if (fd < 0)
- {
// write error to logfile
CLog::Log(LOGERROR, "SMBDirectory->GetDirectory: Unable to open directory : '%s'\nunix_err:'%x' error : '%s'", CURL::GetRedacted(strAuth).c_str(), errno, strerror(errno));
}
diff --git a/xbmc/filesystem/SMBFile.cpp b/xbmc/filesystem/SMBFile.cpp
index e4398e9b7b..8f4cc8522a 100644
--- a/xbmc/filesystem/SMBFile.cpp
+++ b/xbmc/filesystem/SMBFile.cpp
@@ -74,16 +74,8 @@ void CSMB::Deinit()
/* samba goes loco if deinited while it has some files opened */
if (m_context)
{
- try
- {
- smbc_set_context(NULL);
- smbc_free_context(m_context, 1);
- }
- XBMCCOMMONS_HANDLE_UNCHECKED
- catch(...)
- {
- CLog::Log(LOGERROR,"exception on CSMB::Deinit. errno: %d", errno);
- }
+ smbc_set_context(NULL);
+ smbc_free_context(m_context, 1);
m_context = NULL;
}
}
@@ -133,9 +125,6 @@ void CSMB::Init()
if (g_advancedSettings.m_sambadoscodepage.length() > 0)
fprintf(f, "\tdos charset = %s\n", g_advancedSettings.m_sambadoscodepage.c_str());
- // if no workgroup string is specified, samba will use the default value 'WORKGROUP'
- if ( CSettings::Get().GetString("smb.workgroup").length() > 0 )
- fprintf(f, "\tworkgroup = %s\n", CSettings::Get().GetString("smb.workgroup").c_str());
fclose(f);
}
}
@@ -154,6 +143,8 @@ void CSMB::Init()
smbc_setOptionOneSharePerServer(m_context, false);
smbc_setOptionBrowseMaxLmbCount(m_context, 0);
smbc_setTimeout(m_context, g_advancedSettings.m_sambaclienttimeout * 1000);
+ if (CSettings::Get().GetString("smb.workgroup").length() > 0)
+ smbc_setWorkgroup(m_context, strdup(CSettings::Get().GetString("smb.workgroup").c_str()));
smbc_setUser(m_context, strdup("guest"));
#else
m_context->debug = (g_advancedSettings.CanLogComponent(LOGSAMBA) ? 10 : 0);
@@ -163,6 +154,8 @@ void CSMB::Init()
m_context->options.one_share_per_server = false;
m_context->options.browse_max_lmb_count = 0;
m_context->timeout = g_advancedSettings.m_sambaclienttimeout * 1000;
+ if (CSettings::Get().GetString("smb.workgroup").length() > 0)
+ m_context->workgroup = strdup(CSettings::Get().GetString("smb.workgroup").c_str());
m_context->user = strdup("guest");
#endif
@@ -181,29 +174,6 @@ void CSMB::Init()
m_IdleTimeout = 180;
}
-void CSMB::Purge()
-{
-}
-
-/*
- * For each new connection samba creates a new session
- * But this is not what we want, we just want to have one session at the time
- * This means that we have to call smbc_purge() if samba created a new session
- * Samba will create a new session when:
- * - connecting to another server
- * - connecting to another share on the same server (share, not a different folder!)
- *
- * We try to avoid lot's of purge commands because it slow samba down.
- */
-void CSMB::PurgeEx(const CURL& url)
-{
- CSingleLock lock(*this);
- std::string strShare = url.GetFileName().substr(0, url.GetFileName().find('/'));
-
- m_strLastShare = strShare;
- m_strLastHost = url.GetHostName();
-}
-
std::string CSMB::URLEncode(const CURL &url)
{
/* due to smb wanting encoded urls we have to build it manually */
@@ -221,8 +191,11 @@ std::string CSMB::URLEncode(const CURL &url)
if(url.GetUserName().length() > 0 /* || url.GetPassWord().length() > 0 */)
{
flat += URLEncode(url.GetUserName());
- flat += ":";
- flat += URLEncode(url.GetPassWord());
+ if(url.GetPassWord().length() > 0)
+ {
+ flat += ":";
+ flat += URLEncode(url.GetPassWord());
+ }
flat += "@";
}
flat += URLEncode(url.GetHostName());
@@ -312,7 +285,6 @@ int64_t CSMBFile::GetPosition()
{
if (m_fd == -1)
return -1;
- smb.Init();
CSingleLock lock(smb);
return smbc_lseek(m_fd, 0, SEEK_CUR);
}
@@ -446,20 +418,7 @@ int CSMBFile::Stat(struct __stat64* buffer)
CSingleLock lock(smb);
int iResult = smbc_fstat(m_fd, &tmpBuffer);
-
- memset(buffer, 0, sizeof(struct __stat64));
- buffer->st_dev = tmpBuffer.st_dev;
- buffer->st_ino = tmpBuffer.st_ino;
- buffer->st_mode = tmpBuffer.st_mode;
- buffer->st_nlink = tmpBuffer.st_nlink;
- buffer->st_uid = tmpBuffer.st_uid;
- buffer->st_gid = tmpBuffer.st_gid;
- buffer->st_rdev = tmpBuffer.st_rdev;
- buffer->st_size = tmpBuffer.st_size;
- buffer->st_atime = tmpBuffer.st_atime;
- buffer->st_mtime = tmpBuffer.st_mtime;
- buffer->st_ctime = tmpBuffer.st_ctime;
-
+ CUtil::StatToStat64(buffer, &tmpBuffer);
return iResult;
}
@@ -471,20 +430,7 @@ int CSMBFile::Stat(const CURL& url, struct __stat64* buffer)
struct stat tmpBuffer = {0};
int iResult = smbc_stat(strFileName.c_str(), &tmpBuffer);
-
- memset(buffer, 0, sizeof(struct __stat64));
- buffer->st_dev = tmpBuffer.st_dev;
- buffer->st_ino = tmpBuffer.st_ino;
- buffer->st_mode = tmpBuffer.st_mode;
- buffer->st_nlink = tmpBuffer.st_nlink;
- buffer->st_uid = tmpBuffer.st_uid;
- buffer->st_gid = tmpBuffer.st_gid;
- buffer->st_rdev = tmpBuffer.st_rdev;
- buffer->st_size = tmpBuffer.st_size;
- buffer->st_atime = tmpBuffer.st_atime;
- buffer->st_mtime = tmpBuffer.st_mtime;
- buffer->st_ctime = tmpBuffer.st_ctime;
-
+ CUtil::StatToStat64(buffer, &tmpBuffer);
return iResult;
}
@@ -532,37 +478,21 @@ ssize_t CSMBFile::Read(void *lpBuf, size_t uiBufSize)
/* also worse, a request of exactly 64k will return */
/* as if eof, client has a workaround for windows */
/* thou it seems other servers are affected too */
- // FIXME: does this workaround still required?
- ssize_t totalRead = 0;
- uint8_t* buf = (uint8_t*)lpBuf;
- do
- {
- const ssize_t readSize = (uiBufSize >= 64 * 1024 - 2) ? 64 * 1024 - 2 : uiBufSize;
- ssize_t r = smbc_read(m_fd, buf + totalRead, readSize);
- if (r < 0)
- {
- if (errno == EINVAL)
- {
- CLog::LogF(LOGWARNING, "Error %d: \"%s\" - Retrying", errno, strerror(errno));
- r = smbc_read(m_fd, buf + totalRead, readSize);
- }
- if (r < 0)
- {
- CLog::LogF(LOGERROR, "Error %d: \"%s\"", errno, strerror(errno));
- if (totalRead == 0)
- return -1;
+ if( uiBufSize >= 64*1024-2 )
+ uiBufSize = 64*1024-2;
- break;
- }
- }
+ ssize_t bytesRead = smbc_read(m_fd, lpBuf, (int)uiBufSize);
+
+ if ( bytesRead < 0 && errno == EINVAL )
+ {
+ CLog::Log(LOGERROR, "%s - Error( %d, %d, %s ) - Retrying", __FUNCTION__, bytesRead, errno, strerror(errno));
+ bytesRead = smbc_read(m_fd, lpBuf, (int)uiBufSize);
+ }
- totalRead += r;
- uiBufSize -= r;
- if (r != readSize)
- break;
- } while (uiBufSize > 0);
+ if ( bytesRead < 0 )
+ CLog::Log(LOGERROR, "%s - Error( %d, %d, %s )", __FUNCTION__, bytesRead, errno, strerror(errno));
- return totalRead;
+ return bytesRead;
}
int64_t CSMBFile::Seek(int64_t iFilePosition, int iWhence)
@@ -598,7 +528,6 @@ ssize_t CSMBFile::Write(const void* lpBuf, size_t uiBufSize)
if (m_fd == -1) return -1;
// lpBuf can be safely casted to void* since xbmc_write will only read from it.
- smb.Init();
CSingleLock lock(smb);
return smbc_write(m_fd, (void*)lpBuf, uiBufSize);
@@ -639,7 +568,6 @@ bool CSMBFile::OpenForWrite(const CURL& url, bool bOverWrite)
m_fileSize = 0;
Close();
- smb.Init();
// we can't open files like smb://file.f or smb://server/file.f
// if a file matches the if below return false, it can't exist on a samba share.
if (!IsValidFile(url.GetFileName())) return false;
diff --git a/xbmc/filesystem/SMBFile.h b/xbmc/filesystem/SMBFile.h
index 0f6de4256d..a04b387e9e 100644
--- a/xbmc/filesystem/SMBFile.h
+++ b/xbmc/filesystem/SMBFile.h
@@ -47,8 +47,6 @@ public:
~CSMB();
void Init();
void Deinit();
- void Purge();
- void PurgeEx(const CURL& url);
void CheckIfIdle();
void SetActivityTime();
void AddActiveConnection();
@@ -59,8 +57,6 @@ public:
DWORD ConvertUnixToNT(int error);
private:
SMBCCTX *m_context;
- std::string m_strLastHost;
- std::string m_strLastShare;
#ifdef TARGET_POSIX
int m_OpenConnections;
unsigned int m_IdleTimeout;