diff options
author | Karlson2k <k2k@narod.ru> | 2014-11-17 22:55:33 +0400 |
---|---|---|
committer | Karlson2k <k2k@narod.ru> | 2014-11-17 22:55:33 +0400 |
commit | d8a405884716f45785b33b198c69030e20da06a4 (patch) | |
tree | aa81ccbdc15017bf93ed890e2f76aac9c82235a0 | |
parent | c75d23c714dcdbd02907bb29bbd80730883ee73b (diff) | |
parent | aeebd22d2e88fd14f1b0624d0bdbc6f791a75892 (diff) |
Merge pull request #5740 from elupus/samba_fixes
Samba fixes and cleanup for helix
-rw-r--r-- | xbmc/Application.cpp | 4 | ||||
-rw-r--r-- | xbmc/URL.cpp | 16 | ||||
-rw-r--r-- | xbmc/Util.cpp | 16 | ||||
-rw-r--r-- | xbmc/Util.h | 1 | ||||
-rw-r--r-- | xbmc/filesystem/SMBDirectory.cpp | 14 | ||||
-rw-r--r-- | xbmc/filesystem/SMBFile.cpp | 122 | ||||
-rw-r--r-- | xbmc/filesystem/SMBFile.h | 4 |
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; |