Exemple #1
0
bool CFileSMB::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,"FileSmb->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.

  CStdString strFileName;
  m_fd = OpenFile(url, strFileName);

  CLog::Log(LOGDEBUG,"CFileSMB::Open - opened %s, fd=%d",url.GetFileName().c_str(), m_fd);
  if (m_fd == -1)
  {
    // write error to logfile
#ifndef _LINUX
    int nt_error = smb.ConvertUnixToNT(errno);
    CLog::Log(LOGINFO, "FileSmb->Open: Unable to open file : '%s'\nunix_err:'%x' nt_err : '%x' error : '%s'", strFileName.c_str(), errno, nt_error, get_friendly_nt_error_msg(nt_error));
#else
    CLog::Log(LOGINFO, "FileSmb->Open: Unable to open file : '%s'\nunix_err:'%x' error : '%s'", strFileName.c_str(), errno, strerror(errno));
#endif
    return false;
  }

  CSingleLock lock(smb);
#ifndef _LINUX
  struct __stat64 tmpBuffer = {0};
#else
  struct stat tmpBuffer;
#endif
  if (smbc_stat(strFileName, &tmpBuffer) < 0)
  {
    smbc_close(m_fd);
    m_fd = -1;
    return false;
  }

  m_fileSize = tmpBuffer.st_size;

  int64_t ret = smbc_lseek(m_fd, 0, SEEK_SET);
  if ( ret < 0 )
  {
    smbc_close(m_fd);
    m_fd = -1;
    return false;
  }
  // We've successfully opened the file!
  return true;
}
Exemple #2
0
int CFileSMB::OpenFile(const CURL &url, CStdString& strAuth)
{
  int fd = -1;
  smb.Init();

  strAuth = GetAuthenticatedPath(url);
  CStdString strPath = strAuth;

  {
    CSingleLock lock(smb);
    fd = smbc_open(strPath.c_str(), O_RDONLY, 0);
  }

  // file open failed, try to open the directory to force authentication
#ifndef _LINUX
  if (fd < 0 && smb.ConvertUnixToNT(errno) == NT_STATUS_ACCESS_DENIED)
#else
  if (fd < 0 && errno == EACCES)
#endif
  {
    CURL urlshare(url);

    /* just replace the filename with the sharename */
    urlshare.SetFileName(url.GetShareName());

    CSMBDirectory smbDir;
    // TODO: Currently we always allow prompting on files.  This may need to
    // change in the future as background scanners are more prolific.
    smbDir.SetAllowPrompting(true);
    fd = smbDir.Open(urlshare);

    // directory open worked, try opening the file again
    if (fd >= 0)
    {
      CSingleLock lock(smb);
      // close current directory filehandle
      // dont need to purge since its the same server and share
      smbc_closedir(fd);

      // set up new filehandle (as CFileSMB::Open does)
      strPath = GetAuthenticatedPath(url);

      fd = smbc_open(strPath.c_str(), O_RDONLY, 0);
    }
  }

  if (fd >= 0)
    strAuth = strPath;

  return fd;
}
Exemple #3
0
bool CFileSMB::Rename(const CURL& url, const CURL& urlnew)
{
  smb.Init();
  CStdString strFile = GetAuthenticatedPath(url);
  CStdString strFileNew = GetAuthenticatedPath(urlnew);
  CSingleLock lock(smb);

  int result = smbc_rename(strFile.c_str(), strFileNew.c_str());

  if(result != 0)
#ifndef _LINUX
    CLog::Log(LOGERROR, "%s - Error( %s )", __FUNCTION__, get_friendly_nt_error_msg(smb.ConvertUnixToNT(errno)));
#else
    CLog::Log(LOGERROR, "%s - Error( %s )", __FUNCTION__, strerror(errno));
#endif

  return (result == 0);
}
Exemple #4
0
bool CSmbFile::Delete(const CURL& url)
{
  smb.Init();
  CStdString strFile = GetAuthenticatedPath(url);

  CSingleLock lock(smb);

  int result = smbc_unlink(strFile.c_str());

  if(result != 0)
#ifdef TARGET_WINDOWS
    CLog::Log(LOGERROR, "%s - Error( %s )", __FUNCTION__, get_friendly_nt_error_msg(smb.ConvertUnixToNT(errno)));
#else
    CLog::Log(LOGERROR, "%s - Error( %s )", __FUNCTION__, strerror(errno));
#endif

  return (result == 0);
}
Exemple #5
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
#ifdef TARGET_POSIX
  smb.SetActivityTime();
#endif
  int64_t pos = smbc_lseek(m_fd, iFilePosition, iWhence);

  if ( pos < 0 )
  {
#ifdef TARGET_WINDOWS
    CLog::Log(LOGERROR, "%s - Error( %s )", __FUNCTION__, get_friendly_nt_error_msg(smb.ConvertUnixToNT(errno)));
#else
    CLog::Log(LOGERROR, "%s - Error( %"PRId64", %d, %s )", __FUNCTION__, pos, errno, strerror(errno));
#endif
    return -1;
  }

  return (int64_t)pos;
}
Exemple #6
0
unsigned int CFileSMB::Read(void *lpBuf, int64_t uiBufSize)
{
  if (m_fd == -1) return 0;
  CSingleLock lock(smb); // Init not called since it has to be "inited" by now
#ifdef _LINUX
  smb.SetActivityTime();
#endif
  /* 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;

  int 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);
  }

  if ( bytesRead < 0 )
  {
#ifndef _LINUX
    CLog::Log(LOGERROR, "%s - Error( %s )", __FUNCTION__, get_friendly_nt_error_msg(smb.ConvertUnixToNT(errno)));
#else
    CLog::Log(LOGERROR, "%s - Error( %d, %d, %s )", __FUNCTION__, bytesRead, errno, strerror(errno));
#endif
    return 0;
  }

  return (unsigned int)bytesRead;
}