Пример #1
0
bool CSMBFile::OpenForWrite(const CURL& url, bool bOverWrite)
{
  m_fileSize = 0;

  Close();
  // 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;

  std::string strFileName = GetAuthenticatedPath(url);

  CSingleLock lock(smb);

  if (bOverWrite)
  {
    CLog::Log(LOGWARNING, "SMBFile::OpenForWrite() called with overwriting enabled! - %s", strFileName.c_str());
    m_fd = smb.GetImpl()->smbc_creat(strFileName.c_str(), 0);
  }
  else
  {
    m_fd = smb.GetImpl()->smbc_open(strFileName.c_str(), O_RDWR, 0);
  }

  if (m_fd == -1)
  {
    // write error to logfile
    CLog::Log(LOGERROR, "SMBFile->Open: Unable to open file : '%s'\nunix_err:'%x' error : '%s'", strFileName.c_str(), errno, strerror(errno));
    return false;
  }

  // We've successfully opened the file!
  return true;
}
Пример #2
0
bool CSMBFile::Open(const CURL& url)
{
  Close();

  // 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()))
  {
      CLog::Log(LOGNOTICE,"SMBFile->Open: Bad URL : '%s'",url.GetFileName().c_str());
      return false;
  }
  m_url = url;

  // opening a file to another computer share will create a new session
  // when opening smb://server xbms will try to find folder.jpg in all shares
  // listed, which will create lot's of open sessions.

  std::string strFileName;
  m_fd = OpenFile(url, strFileName);

  CLog::Log(LOGDEBUG,"CSMBFile::Open - opened %s, fd=%d",url.GetFileName().c_str(), m_fd);
  if (m_fd == -1)
  {
    // write error to logfile
    CLog::Log(LOGINFO, "SMBFile->Open: Unable to open file : '%s'\nunix_err:'%x' error : '%s'", CURL::GetRedacted(strFileName).c_str(), errno, strerror(errno));
    return false;
  }

  CSingleLock lock(smb);

  struct stat tmpBuffer;
  if (smb.GetImpl()->smbc_stat(strFileName.c_str(), &tmpBuffer) < 0)
  {
    smb.GetImpl()->smbc_close(m_fd);
    m_fd = -1;
    return false;
  }

  m_fileSize = tmpBuffer.st_size;

  int64_t ret = smb.GetImpl()->smbc_lseek(m_fd, 0, SEEK_SET);
  if (ret < 0)
  {
    smb.GetImpl()->smbc_close(m_fd);
    m_fd = -1;
    return false;
  }
  // We've successfully opened the file!
  return true;
}
Пример #3
0
int64_t CSMBFile::GetPosition()
{
  if (m_fd == -1)
    return -1;
  CSingleLock lock(smb);
  return smb.GetImpl()->smbc_lseek(m_fd, 0, SEEK_CUR);
}
Пример #4
0
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.
  CSingleLock lock(smb);

  return smb.GetImpl()->smbc_write(m_fd, (void*)lpBuf, uiBufSize);
}
Пример #5
0
void CSMBFile::Close()
{
  if (m_fd != -1)
  {
    CLog::Log(LOGDEBUG,"CSMBFile::Close closing fd %d", m_fd);
    CSingleLock lock(smb);
    smb.GetImpl()->smbc_close(m_fd);
    m_fd = -1;
  }
}
Пример #6
0
ssize_t CSMBFile::Read(void *lpBuf, size_t uiBufSize)
{
  if (uiBufSize > SSIZE_MAX)
    uiBufSize = SSIZE_MAX;

  if (m_fd == -1)
    return -1;

  // Some external libs (libass) use test read with zero size and 
  // null buffer pointer to check whether file is readable, but 
  // libsmbclient always return "-1" if called with null buffer 
  // regardless of buffer size.
  // To overcome this, force return "0" in that case.
  if (uiBufSize == 0 && lpBuf == NULL)
    return 0;

  CSingleLock lock(smb); // Init not called since it has to be "inited" by now

  smb.SetActivityTime();
  /* work around stupid bug in samba */
  /* some samba servers has a bug in it where the */
  /* 17th bit will be ignored in a request of data */
  /* this can lead to a very small return of data */
  /* 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 */
  if (uiBufSize >= 64*1024-2)
    uiBufSize = 64*1024-2;

  ssize_t bytesRead = smb.GetImpl()->smbc_read(m_fd, lpBuf, (int)uiBufSize);
  if (bytesRead < 0 && errno == EINVAL)
  {
    CLog::Log(LOGERROR, "%s - Error( %" PRIdS ", %d, %s ) - Retrying", __FUNCTION__, bytesRead, errno, strerror(errno));
    bytesRead = smb.GetImpl()->smbc_read(m_fd, lpBuf, (int)uiBufSize);
  }

  if (bytesRead < 0)
    CLog::Log(LOGERROR, "%s - Error( %" PRIdS ", %d, %s )", __FUNCTION__, bytesRead, errno, strerror(errno));

  return bytesRead;
}
Пример #7
0
int CSMBFile::Stat(const CURL& url, struct __stat64* buffer)
{
  smb.Init();
  std::string strFileName = GetAuthenticatedPath(url);

  CSingleLock lock(smb);

  struct stat tmpBuffer = {0};
  int iResult = smb.GetImpl()->smbc_stat(strFileName.c_str(), &tmpBuffer);
  CUtil::StatToStat64(buffer, &tmpBuffer);
  return iResult;
}
Пример #8
0
int CSMBFile::Stat(struct __stat64* buffer)
{
  if (m_fd == -1)
    return -1;

  CSingleLock lock(smb);

  struct stat tmpBuffer = {0};
  int iResult = smb.GetImpl()->smbc_fstat(m_fd, &tmpBuffer);
  CUtil::StatToStat64(buffer, &tmpBuffer);
  return iResult;
}
Пример #9
0
bool CSMBFile::Delete(const CURL& url)
{
  smb.Init();
  std::string strFile = GetAuthenticatedPath(url);

  CSingleLock lock(smb);

  int result = smb.GetImpl()->smbc_unlink(strFile.c_str());
  if (result != 0)
    CLog::Log(LOGERROR, "%s - Error( %s )", __FUNCTION__, strerror(errno));

  return (result == 0);
}
Пример #10
0
int64_t CSMBFile::Seek(int64_t iFilePosition, int iWhence)
{
  if (m_fd == -1)
    return -1;

  CSingleLock lock(smb); // Init not called since it has to be "inited" by now

  smb.SetActivityTime();
  int64_t pos = smb.GetImpl()->smbc_lseek(m_fd, iFilePosition, iWhence);
  if (pos < 0)
  {
    CLog::Log(LOGERROR, "%s - Error( %" PRId64", %d, %s )", __FUNCTION__, pos, errno, strerror(errno));
    return -1;
  }

  return (int64_t)pos;
}
Пример #11
0
bool CSMBFile::Exists(const CURL& url)
{
  // 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;

  smb.Init();
  std::string strFileName = GetAuthenticatedPath(url);

  CSingleLock lock(smb);

  struct stat info = {0};
  int iResult = smb.GetImpl()->smbc_stat(strFileName.c_str(), &info);
  if (iResult < 0)
    return false;
  return true;
}
Пример #12
0
int CSMBFile::OpenFile(const CURL &url, std::string& strAuth)
{
  smb.Init();

  strAuth = GetAuthenticatedPath(url);
  std::string strPath = strAuth;

  int fd = -1;
  {
    CSingleLock lock(smb);
    fd = smb.GetImpl()->smbc_open(strPath.c_str(), O_RDONLY, 0);
  }
  if (fd >= 0)
    strAuth = strPath;

  return fd;
}