Example #1
0
bool CFileNFS::OpenForWrite(const CURL& url, bool bOverWrite)
{ 
  int ret = 0;
  // we can't open files like nfs://file.f or nfs://server/file.f
  // if a file matches the if below return false, it can't exist on a nfs share.
  if (!IsValidFile(url.GetFileName())) return false;
  
  Close();
  CSingleLock lock(gNfsConnection);
  CStdString filename = "";
  
  if(!gNfsConnection.Connect(url,filename))
    return false;
  
  m_pNfsContext = gNfsConnection.GetNfsContext();
  
  if (bOverWrite)
  {
    CLog::Log(LOGWARNING, "FileNFS::OpenForWrite() called with overwriting enabled! - %s", filename.c_str());
    //create file with proper permissions
    ret = gNfsConnection.GetImpl()->nfs_creat(m_pNfsContext, filename.c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH, &m_pFileHandle);    
    //if file was created the file handle isn't valid ... so close it and open later
    if(ret == 0)
    {
      gNfsConnection.GetImpl()->nfs_close(m_pNfsContext,m_pFileHandle);
    }
  }

  ret = gNfsConnection.GetImpl()->nfs_open(m_pNfsContext, filename.c_str(), O_RDWR, &m_pFileHandle);
  
  if (ret || m_pFileHandle == NULL)
  {
    // write error to logfile
    CLog::Log(LOGERROR, "CFileNFS::Open: Unable to open file : '%s' error : '%s'", filename.c_str(), gNfsConnection.GetImpl()->nfs_get_error(gNfsConnection.GetNfsContext()));
    return false;
  }
  m_url=url;
  
  struct __stat64 tmpBuffer = {0};

  //only stat if file was not created
  if(!bOverWrite) 
  {
    if(Stat(&tmpBuffer))
    {
      m_url.Reset();
      Close();
      return false;
    }
    m_fileSize = tmpBuffer.st_size;//cache filesize of this file    
  }
  else//file was created - filesize is zero
  {
    m_fileSize = 0;    
  }
  
  // We've successfully opened the file!
  return true;
}
Example #2
0
bool CNFSFile::Open(const CURL& url)
{
  int ret = 0;
  Close();
  // we can't open files like nfs://file.f or nfs://server/file.f
  // if a file matches the if below return false, it can't exist on a nfs share.
  if (!IsValidFile(url.GetFileName()))
  {
    CLog::Log(LOGNOTICE,"NFS: Bad URL : '%s'",url.GetFileName().c_str());
    return false;
  }
  
  CStdString filename = "";
   
  CSingleLock lock(gNfsConnection);
  
  if(!gNfsConnection.Connect(url, filename))
    return false;
  
  m_pNfsContext = gNfsConnection.GetNfsContext(); 
  m_exportPath = gNfsConnection.GetContextMapId();
  
  ret = gNfsConnection.GetImpl()->nfs_open(m_pNfsContext, filename.c_str(), O_RDONLY, &m_pFileHandle);
  
  if (ret != 0) 
  {
    CLog::Log(LOGINFO, "CNFSFile::Open: Unable to open file : '%s'  error : '%s'", url.GetFileName().c_str(), gNfsConnection.GetImpl()->nfs_get_error(m_pNfsContext));
    m_pNfsContext = NULL;
    m_exportPath.clear();
    return false;
  } 
  
  CLog::Log(LOGDEBUG,"CNFSFile::Open - opened %s",url.GetFileName().c_str());
  m_url=url;
  
  struct __stat64 tmpBuffer;

  if( Stat(&tmpBuffer) )
  {
    m_url.Reset();
    Close();
    return false;
  }
  
  m_fileSize = tmpBuffer.st_size;//cache the size of this file
  // We've successfully opened the file!
  return true;
}
Example #3
0
CNFSFile::CNFSFile()
: m_fileSize(0)
, m_pFileHandle(NULL)
, m_pNfsContext(NULL)
{
  gNfsConnection.AddActiveConnection();
}
Example #4
0
unsigned int CFileNFS::Read(void *lpBuf, int64_t uiBufSize)
{
  int numberOfBytesRead = 0;
  CSingleLock lock(gNfsConnection);
  
  if (m_pFileHandle == NULL || gNfsConnection.GetNfsContext()==NULL ) return 0;

  numberOfBytesRead = gNfsConnection.GetImpl()->nfs_read(gNfsConnection.GetNfsContext(), m_pFileHandle, uiBufSize, (char *)lpBuf);
  //something went wrong ...
  if (numberOfBytesRead < 0) 
  {
    CLog::Log(LOGERROR, "%s - Error( %d, %s )", __FUNCTION__, numberOfBytesRead, gNfsConnection.GetImpl()->nfs_get_error(gNfsConnection.GetNfsContext()));
    return 0;
  }
  return (unsigned int)numberOfBytesRead;
}
Example #5
0
int64_t CNFSFile::GetPosition()
{
  int ret = 0;
  uint64_t offset = 0;
  CSingleLock lock(gNfsConnection);
  
  if (gNfsConnection.GetNfsContext() == NULL || m_pFileHandle == NULL) return 0;
  
  ret = (int)gNfsConnection.GetImpl()->nfs_lseek(gNfsConnection.GetNfsContext(), m_pFileHandle, 0, SEEK_CUR, &offset);
  
  if (ret < 0) 
  {
    CLog::Log(LOGERROR, "NFS: Failed to lseek(%s)",gNfsConnection.GetImpl()->nfs_get_error(gNfsConnection.GetNfsContext()));
  }
  return offset;
}
Example #6
0
int64_t CFileNFS::Seek(int64_t iFilePosition, int iWhence)
{
  int ret = 0;
  off_t offset = 0;

  CSingleLock lock(gNfsConnection);  
  if (m_pFileHandle == NULL || gNfsConnection.GetNfsContext()==NULL) return -1;
  
 
  ret = (int)gNfsConnection.GetImpl()->nfs_lseek(gNfsConnection.GetNfsContext(), m_pFileHandle, iFilePosition, iWhence, &offset);
  if (ret < 0) 
  {
    CLog::Log(LOGERROR, "%s - Error( seekpos: %"PRId64", whence: %i, fsize: %"PRId64", %s)", __FUNCTION__, iFilePosition, iWhence, m_fileSize, gNfsConnection.GetImpl()->nfs_get_error(gNfsConnection.GetNfsContext()));
    return -1;
  }
  return (int64_t)offset;
}
Example #7
0
bool CNFSFile::Delete(const CURL& url)
{
  int ret = 0;
  CSingleLock lock(gNfsConnection);
  CStdString filename = "";
  
  if(!gNfsConnection.Connect(url, filename))
    return false;
  
  
  ret = gNfsConnection.GetImpl()->nfs_unlink(gNfsConnection.GetNfsContext(), filename.c_str());
  
  if(ret != 0)
  {
    CLog::Log(LOGERROR, "%s - Error( %s )", __FUNCTION__, gNfsConnection.GetImpl()->nfs_get_error(gNfsConnection.GetNfsContext()));
  }
  return (ret == 0);
}
Example #8
0
void CFileNFS::Close()
{
  CSingleLock lock(gNfsConnection);
  
  if (m_pFileHandle != NULL && gNfsConnection.GetNfsContext()!=NULL)
  {
    int ret = 0;
    CLog::Log(LOGDEBUG,"CFileNFS::Close closing file %s", m_url.GetFileName().c_str());
    ret = gNfsConnection.GetImpl()->nfs_close(gNfsConnection.GetNfsContext(), m_pFileHandle);
    
	  if (ret < 0) 
    {
      CLog::Log(LOGERROR, "Failed to close(%s) - %s\n", m_url.GetFileName().c_str(), gNfsConnection.GetImpl()->nfs_get_error(gNfsConnection.GetNfsContext()));
    }
    m_pFileHandle=NULL;
    m_fileSize = 0;
  }
}
Example #9
0
int CNFSFile::Stat(const CURL& url, struct __stat64* buffer)
{
  int ret = 0;
  CSingleLock lock(gNfsConnection);
  CStdString filename = "";
  
  if(!gNfsConnection.Connect(url,filename))
    return -1;
   

  NFSSTAT tmpBuffer = {0};

  ret = gNfsConnection.GetImpl()->nfs_stat(gNfsConnection.GetNfsContext(), filename.c_str(), &tmpBuffer);
  
  //if buffer == NULL we where called from Exists - in that case don't spam the log with errors
  if (ret != 0 && buffer != NULL) 
  {
    CLog::Log(LOGERROR, "NFS: Failed to stat(%s) %s\n", url.GetFileName().c_str(), gNfsConnection.GetImpl()->nfs_get_error(gNfsConnection.GetNfsContext()));
    ret = -1;
  }
  else
  {  
    if(buffer)
    {
#if defined(TARGET_WINDOWS)// TODO get rid of this define after gotham
      memcpy(buffer, &tmpBuffer, sizeof(struct __stat64));
#else
      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;
#endif
    }
  }
  return ret;
}
Example #10
0
//this was a bitch!
//for nfs write to work we have to write chunked
//otherwise this could crash on big files
ssize_t CNFSFile::Write(const void* lpBuf, size_t uiBufSize)
{
  size_t numberOfBytesWritten = 0;
  int writtenBytes = 0;
  size_t leftBytes = uiBufSize;
  //clamp max write chunksize to 32kb - fixme - this might be superfluious with future libnfs versions
  size_t chunkSize = gNfsConnection.GetMaxWriteChunkSize() > 32768 ? 32768 : (size_t)gNfsConnection.GetMaxWriteChunkSize();
  
  CSingleLock lock(gNfsConnection);
  
  if (m_pFileHandle == NULL || m_pNfsContext == NULL) return -1;
  
  //write as long as some bytes are left to be written
  while( leftBytes )
  {
    //the last chunk could be smalle than chunksize
    if(leftBytes < chunkSize)
    {
      chunkSize = leftBytes;//write last chunk with correct size
    }
    //write chunk
    writtenBytes = gNfsConnection.GetImpl()->nfs_write(m_pNfsContext,
                                  m_pFileHandle, 
                                  chunkSize, 
                                  (char *)lpBuf + numberOfBytesWritten);
    //decrease left bytes
    leftBytes-= writtenBytes;
    //increase overall written bytes
    numberOfBytesWritten += writtenBytes;
        
    //danger - something went wrong
    if (writtenBytes < 0) 
    {
      CLog::Log(LOGERROR, "Failed to pwrite(%s) %s\n", m_url.GetFileName().c_str(), gNfsConnection.GetImpl()->nfs_get_error(m_pNfsContext));
      if (numberOfBytesWritten == 0)
        return -1;

      break;
    }     
  }
  //return total number of written bytes
  return numberOfBytesWritten;
}
Example #11
0
bool CNFSFile::Rename(const CURL& url, const CURL& urlnew)
{
  int ret = 0;
  CSingleLock lock(gNfsConnection);
  CStdString strFile = "";
  
  if(!gNfsConnection.Connect(url,strFile))
    return false;
  
  CStdString strFileNew;
  CStdString strDummy;
  gNfsConnection.splitUrlIntoExportAndPath(urlnew, strDummy, strFileNew);
  
  ret = gNfsConnection.GetImpl()->nfs_rename(gNfsConnection.GetNfsContext() , strFile.c_str(), strFileNew.c_str());
  
  if(ret != 0)
  {
    CLog::Log(LOGERROR, "%s - Error( %s )", __FUNCTION__, gNfsConnection.GetImpl()->nfs_get_error(gNfsConnection.GetNfsContext()));
  } 
  return (ret == 0);
}
Example #12
0
void CNFSFile::Close()
{
  CSingleLock lock(gNfsConnection);
  
  if (m_pFileHandle != NULL && m_pNfsContext != NULL)
  {
    int ret = 0;
    CLog::Log(LOGDEBUG,"CNFSFile::Close closing file %s", m_url.GetFileName().c_str());
    ret = gNfsConnection.GetImpl()->nfs_close(m_pNfsContext, m_pFileHandle);
    gNfsConnection.removeFromKeepAliveList(m_pFileHandle);
        
	  if (ret < 0) 
    {
      CLog::Log(LOGERROR, "Failed to close(%s) - %s\n", m_url.GetFileName().c_str(), gNfsConnection.GetImpl()->nfs_get_error(m_pNfsContext));
    }
    m_pFileHandle = NULL;
    m_pNfsContext = NULL;    
    m_fileSize = 0;
    m_exportPath.clear();
  }
}
Example #13
0
unsigned int CNFSFile::Read(void *lpBuf, int64_t uiBufSize)
{
  int numberOfBytesRead = 0;
  CSingleLock lock(gNfsConnection);
  
  if (m_pFileHandle == NULL || m_pNfsContext == NULL ) return 0;

  numberOfBytesRead = gNfsConnection.GetImpl()->nfs_read(m_pNfsContext, m_pFileHandle, uiBufSize, (char *)lpBuf);  

  lock.Leave();//no need to keep the connection lock after that
  
  gNfsConnection.resetKeepAlive(m_exportPath, m_pFileHandle);//triggers keep alive timer reset for this filehandle
  
  //something went wrong ...
  if (numberOfBytesRead < 0) 
  {
    CLog::Log(LOGERROR, "%s - Error( %d, %s )", __FUNCTION__, numberOfBytesRead, gNfsConnection.GetImpl()->nfs_get_error(m_pNfsContext));
    return 0;
  }
  return (unsigned int)numberOfBytesRead;
}
Example #14
0
//this was a bitch!
//for nfs write to work we have to write chunked
//otherwise this could crash on big files
int CFileNFS::Write(const void* lpBuf, int64_t uiBufSize)
{
  int numberOfBytesWritten = 0;
  int writtenBytes = 0;
  int leftBytes = uiBufSize;
  int chunkSize = gNfsConnection.GetMaxWriteChunkSize();
  
  CSingleLock lock(gNfsConnection);
  
  if (m_pFileHandle == NULL || gNfsConnection.GetNfsContext() == NULL) return -1;
  
  //write as long as some bytes are left to be written
  while( leftBytes )
  {
    //the last chunk could be smalle than chunksize
    if(leftBytes < chunkSize)
    {
      chunkSize = leftBytes;//write last chunk with correct size
    }
    //write chunk
    writtenBytes = gNfsConnection.GetImpl()->nfs_write(gNfsConnection.GetNfsContext(), 
                                  m_pFileHandle, 
                                  (size_t)chunkSize, 
                                  (char *)lpBuf + numberOfBytesWritten);
    //decrease left bytes
    leftBytes-= writtenBytes;
    //increase overall written bytes
    numberOfBytesWritten += writtenBytes;
        
    //danger - something went wrong
    if (writtenBytes < 0) 
    {
      CLog::Log(LOGERROR, "Failed to pwrite(%s) %s\n", m_url.GetFileName().c_str(), gNfsConnection.GetImpl()->nfs_get_error(gNfsConnection.GetNfsContext()));        
      break;
    }     
  }
  //return total number of written bytes
  return numberOfBytesWritten;
}
Example #15
0
int CNFSFile::Truncate(int64_t iSize)
{
  int ret = 0;
  
  CSingleLock lock(gNfsConnection);  
  if (m_pFileHandle == NULL || m_pNfsContext == NULL) return -1;
  
  
  ret = (int)gNfsConnection.GetImpl()->nfs_ftruncate(m_pNfsContext, m_pFileHandle, iSize);
  if (ret < 0) 
  {
    CLog::Log(LOGERROR, "%s - Error( ftruncate: %"PRId64", fsize: %"PRId64", %s)", __FUNCTION__, iSize, m_fileSize, gNfsConnection.GetImpl()->nfs_get_error(m_pNfsContext));
    return -1;
  }
  return ret;
}
Example #16
0
CNFSFile::~CNFSFile()
{
  Close();
  gNfsConnection.AddIdleConnection();
}
Example #17
0
CFileNFS::~CFileNFS()
{
  Close();
  gNfsConnection.AddIdleConnection();
}
Example #18
0
CFileNFS::CFileNFS()
: m_fileSize(0)
, m_pFileHandle(NULL)
{
  gNfsConnection.AddActiveConnection();
}