VError OpenHelper::Open(const PathBuffer& inPath, FileDescSystemRef* outFd) { if(GetFileAccess()==FA_MAX) return OpenMax(inPath.GetPath(), outFd); bool failToGetLock=false; //(we don't care) VError verr=OpenStd(inPath.GetPath(), outFd, &failToGetLock); return verr; }
VError XLinuxFile::CreateAlias(const VFilePath &inTargetPath, const VFilePath *unused) const { PathBuffer targetPath; targetPath.Init(inTargetPath); LinkHelper lnkHlp; VError verr=lnkHlp.Link(fPath, targetPath); return verr; }
int FSSmb::Rename( FSPath& oldpath, FSPath& newpath, int* err, FSCInfo* info ) { FREPARE_SMB_OPER( lock, info, &_param ); int n = smbc_rename( pathBuffer1.SetPath( oldpath ), pathBuffer2.SetPath( newpath ) ); SetError( err, errno ); return n < 0 ? -1 : n; }
VFilePath VProcess::GetExecutableFilePath() const { VFilePath filePath; #if VERSIONMAC CFURLRef exeURL = ::CFBundleCopyExecutableURL( ::CFBundleGetMainBundle()); if (testAssert( exeURL != NULL )) { CFStringRef cfPath = ::CFURLCopyFileSystemPath( exeURL, kCFURLHFSPathStyle); if (testAssert( cfPath != NULL )) { VString thepath; thepath.MAC_FromCFString( cfPath); thepath.Compose(); filePath.FromFullPath( thepath, FPS_SYSTEM); ::CFRelease( cfPath); } ::CFRelease(exeURL ); } #elif VERSIONWIN // Get a path to the exe. UniChar path[4096]; DWORD pathLength=0; path[sizeof(path)/sizeof(UniChar)-2]=0; pathLength = ::GetModuleFileNameW(NULL, path, sizeof(path)); if (testAssert(pathLength != 0 && !path[sizeof(path)/sizeof(UniChar)-2])) { VString thepath( path); filePath.FromFullPath( thepath, FPS_SYSTEM); } #elif VERSION_LINUX PathBuffer path; VError verr=path.InitWithExe(); xbox_assert(verr==VE_OK); path.ToPath(&filePath); xbox_assert(verr==VE_OK); #endif return filePath; }
bool XLinuxLibrary::Load(const VFilePath &inFilePath) { VFile* soFile=RetainExecutableFile(inFilePath); VFilePath soPath=soFile->GetPath(); soFile->Release(); PathBuffer tmpBuf; tmpBuf.Init(soPath); if(fLib.Open(tmpBuf)!=VE_OK) return false; return true; }
VError XLinuxFile::Rename(const VFilePath& inDstPath, VFile** outFile) const { if(outFile!=NULL) *outFile=NULL; PathBuffer dstPath; dstPath.Init(inDstPath); RenameHelper rnmHlp; VError verr=rnmHlp.Rename(fPath, dstPath); if(verr==VE_OK && outFile!=NULL) *outFile=new VFile(inDstPath); return verr; }
ReaddirHelper::ReaddirHelper(const PathBuffer& inFolderPath, FileIteratorOptions inOptions) : fOpts(inOptions), fDir(NULL), fPath(inFolderPath) { memset(&fEntry, 0, sizeof(fEntry)); //If it fails for any reason (inFolderPath is a file for ex.), opendir returns NULL. fDir=opendir(inFolderPath.GetPath()); }
int FSSmb::RmDir( FSPath& path, int* err, FSCInfo* info ) { FREPARE_SMB_OPER( lock, info, &_param ); int n = smbc_rmdir( pathBuffer1.SetPath( path ) ); SetError( err, errno ); return n < 0 ? -1 : n; }
int FSSmb::OpenRead( FSPath& path, int flags, int* err, FSCInfo* info ) { FREPARE_SMB_OPER( lock, info, &_param ); int n = smbc_open( pathBuffer1.SetPath( path ), O_RDONLY | OPENFLAG_LARGEFILE, 0 ); SetError( err, errno ); return n < 0 ? -1 : n; }
VError MkdirHelper::MakeDir(const PathBuffer& inPath) const { mode_t modeFlags=PERM_755; int res=mkdir(inPath.GetPath(), modeFlags); return (res==0) ? VE_OK : MAKE_NATIVE_VERROR(errno); }
VError XLinuxFile::Copy(const VFilePath& inDestination, VFile** outFile, FileCopyOptions inOptions ) const { VFilePath tmpPath(inDestination); if(tmpPath.IsFolder()) { VStr255 name; //jmo - todo : NAME_MAX ? fOwner->GetName(name); tmpPath.SetFileName(name); } PathBuffer dstPath; dstPath.Init(tmpPath); CopyHelper cpHlp; return cpHlp.Copy(fPath, dstPath); }
XLinuxFileIterator::XLinuxFileIterator(const VFolder *inFolder, FileIteratorOptions inOptions) : fOpts(0) , fIt(NULL) , fFileSystem( inFolder->GetFileSystem()) { //Because Next() returns a VFile ptr, we want files and no folders. fOpts=inOptions; fOpts|=FI_WANT_FILES; fOpts&=~FI_WANT_FOLDERS; VFilePath tmpPath; inFolder->GetPath(tmpPath); PathBuffer path; path.Init(tmpPath); fIt=new FsIterator(path, inOptions); }
int FSSmb::OpenCreate( FSPath& path, bool overwrite, int mode, int flags, int* err, FSCInfo* info ) { FREPARE_SMB_OPER( lock, info, &_param ); int n = smbc_open( pathBuffer1.SetPath( path ), O_CREAT | O_WRONLY | O_TRUNC | OPENFLAG_LARGEFILE | ( overwrite ? 0 : O_EXCL ) , mode ); SetError( err, errno ); return n < 0 ? -1 : n; }
VError XLinuxFile::Move(const VFilePath& inDestinationPath, VFileSystem *inDestinationFileSystem, VFile** outFile, FileCopyOptions /*inOptions*/) const { VFilePath dstPath(inDestinationPath); if (dstPath.IsFolder()) { VStr255 name; //jmo - todo : NAME_MAX ? fOwner->GetName(name); dstPath.SetFileName(name); } PathBuffer pathBuffer; pathBuffer.Init(dstPath); //First we try to rename the file... VError verr; { RenameHelper rnmHlp; verr=rnmHlp.Rename(fPath, pathBuffer); } //If Rename() fails because src and dst are not on the same fs, we try a Copy() if(verr!=VE_OK && IS_NATIVE_VERROR(verr) && NATIVE_ERRCODE_FROM_VERROR(verr)==EXDEV) { CopyHelper cpHlp; verr = cpHlp.Copy(fPath, pathBuffer); // it's a move not a copy, so one must delete the source after a sucessful copy if (verr == VE_OK) { int res=unlink(fPath.GetPath()); verr = (res==0) ? VE_OK : MAKE_NATIVE_VERROR(errno); } } if (outFile != NULL) { *outFile = (verr == VE_OK) ? new VFile( dstPath, inDestinationFileSystem) : NULL; } return verr; }
VError XLinuxFile::Rename(const VString& inName, VFile** outFile) const { //jmo - todo : we should check that inName < NAME_MAX or use PathBuffer VFilePath newPath(fOwner->GetPath()); newPath.SetFileName(inName); PathBuffer dstPath; dstPath.Init(newPath); RenameHelper rnmHlp; VError verr=rnmHlp.Rename(fPath, dstPath); if (outFile != NULL) { *outFile = (verr == VE_OK) ? new VFile( newPath, fOwner->GetFileSystem()) : NULL; } return verr; }
//static bool OpenHelper::ProcessCanWrite(const PathBuffer& inPath) { int fd=open(const_cast<char*>(inPath.GetPath()), O_WRONLY); if(fd>0) { close(fd); return true; } return false; }
int FSSmb::SetFileTime ( FSPath& path, FSTime aTime, FSTime mTime, int* err, FSCInfo* info ) { FREPARE_SMB_OPER( lock, info, &_param ); struct timeval tv[2]; tv[0].tv_sec = aTime; tv[0].tv_usec = 0; tv[1].tv_sec = mTime; tv[1].tv_usec = 0; int n = smbc_utimes( pathBuffer1.SetPath( path ), tv ); SetError( err, errno ); return n < 0 ? -1 : n; }
VError PathBuffer::Init(const VString& inPath, Mode inMode) { PathBuffer tmpBuf; char* buf=NULL; //If we want the real path of the file, we perform the UTF8 conversion in a tmp buffer and then the realpath transform in 'this' if(inMode==withRealPath) buf=tmpBuf.fPath; else buf=fPath; VSize n=inPath.ToBlock(buf, sizeof(fPath), VTC_UTF_8, false /*without trailing 0*/, false /*no lenght prefix*/); if(n==sizeof(fPath)) return VE_INVALID_PARAMETER; //UTF8 path is more than PATH_MAX bytes long ; we do not support that. buf[n]=0; if(inMode==withRealPath) return tmpBuf.RealPath(this); return VE_OK; }
VError StatHelper::Stat(const PathBuffer& inPath) { int res=(fFlags&followLinks) ? stat(inPath.GetPath(), &fStat) : lstat(inPath.GetPath(), &fStat); if(res==ENOENT || res==ENOTDIR) fDoesNotExist=true; //We are sure that the file doesn't exists if(res!=0) return MAKE_NATIVE_VERROR(errno); fDoesExist=true; //We are sure that the file exists if(fFlags&withFileSystemStats) { //I put stats on file systems here because they are obtained through a file of the fs. res=statfs(inPath.GetPath(), &fFsStat); if(res!=0) return MAKE_NATIVE_VERROR(errno); } return VE_OK; }
VError XLinuxFile::Copy(const VFilePath& inDestination, VFileSystem *inDestinationFileSystem, VFile** outFile, FileCopyOptions /*inOptions*/) const { VFilePath dstPath(inDestination); if(dstPath.IsFolder()) { VStr255 name; //jmo - todo : NAME_MAX ? fOwner->GetName(name); dstPath.SetFileName(name); } PathBuffer pathBuffer; pathBuffer.Init(dstPath); CopyHelper cpHlp; VError err = cpHlp.Copy(fPath, pathBuffer); if (outFile != NULL) { *outFile = (err == VE_OK) ? new VFile( dstPath, inDestinationFileSystem) : NULL; } return err; }
VError TouchHelper::Touch(const PathBuffer& inPath, VTime inAccessTime, VTime inModificationTime) const { struct utimbuf buf; memset(&buf, 0, sizeof(buf)); buf.actime=XBoxToUnixTime(inAccessTime); buf.modtime=XBoxToUnixTime(inModificationTime); int res=utime(inPath.GetPath(), &buf); if(res<0) return MAKE_NATIVE_VERROR(errno); return VE_OK; }
VError DynLoadHelper::Open(const PathBuffer& inLibPath) { fHandle=dlopen(inLibPath.GetPath(), fRelocationMode|fScopeMode); if(fHandle==NULL) { char* msg=dlerror(); if(msg!=NULL) DebugMsg("dlopen error %s\n", msg); return VE_INVALID_PARAMETER; } return VE_OK; }
static int InternalStat( FSPath& path, FSStat* fsStat, FSCInfo* info ) { struct stat st; if ( SMB_STAT( pathBuffer1.SetPath( path ), &st ) ) { return -1; } fsStat->mode = ( st.st_mode & ~( S_IXUSR | S_IXGRP | S_IXOTH ) ); fsStat->size = st.st_size; fsStat->mtime = st.st_mtime; fsStat->gid = st.st_gid; fsStat->uid = st.st_uid; fsStat->dev = st.st_dev; fsStat->ino = st.st_ino; return 0; }
VError CreateHelper::Create(const PathBuffer& inPath) const { //I'm pretty sure it doesn't behave in the same way than the windows platform. //(the share and overwrite behavior might be different) int openFlags=0; if(fCreateOpts & FCR_Overwrite) openFlags|=O_RDONLY|O_CREAT; //CREATE_ALWAYS ? else openFlags|=O_RDONLY|O_CREAT|O_EXCL; //CREATE_NEW mode_t modeFlags=PERM_644; int fd=open(const_cast<char*>(inPath.GetPath()), openFlags, modeFlags); if(fd<0) return MAKE_NATIVE_VERROR(errno); close(fd); return VE_OK; }
VError RenameHelper::Rename(const PathBuffer& inSrc, const PathBuffer& inDst) const { int res=rename(inSrc.GetPath(), inDst.GetPath()); return (res==0) ? VE_OK : MAKE_NATIVE_VERROR(errno); }
VError LinkHelper::Link(const PathBuffer& inLinkPath, const PathBuffer &inTargetPath) const { int res=symlink(inTargetPath.GetPath(), inLinkPath.GetPath()); return (res==0) ? VE_OK : MAKE_NATIVE_VERROR(errno); }
bool StatHelper::Access(const PathBuffer& inPath) { int res=access(inPath.GetPath(), F_OK); return (res==0) ? true : false ; };
VError RemoveHelper::Remove(const PathBuffer& inPath) { int res=unlink(inPath.GetPath()); return (res==0) ? VE_OK : MAKE_NATIVE_VERROR(errno); }
int FSSmb::ReadDir( FSList* list, FSPath& _path, int* err, FSCInfo* info ) { FREPARE_SMB_OPER( lock, info, &_param ); if ( info && info->Stopped() ) { return -2; } list->Clear(); FSPath path( _path ); int d = smbc_opendir( pathBuffer1.SetPath( path ) ); if ( d < 0 ) { SetError( err, errno ); return -1; } try { struct smbc_dirent* pEnt; int n = path.Count(); while ( true ) { if ( info && info->Stopped() ) { smbc_closedir( d ); return -2; } pEnt = smbc_readdir( d ); if ( !pEnt ) { //??? break; } //skip . and .. if ( pEnt->name[0] == '.' && ( !pEnt->name[1] || ( pEnt->name[1] == '.' && !pEnt->name[2] ) ) ) { continue; } if ( //ignore it pEnt->smbc_type == SMBC_PRINTER_SHARE || pEnt->smbc_type == SMBC_IPC_SHARE ) { continue; } clPtr<FSNode> pNode = new FSNode(); path.SetItem( n, CS_UTF8, pEnt->name ); switch ( pEnt->smbc_type ) { case SMBC_WORKGROUP: pNode->extType = FSNode::WORKGROUP; pNode->st.mode = S_IFDIR; break; case SMBC_SERVER: pNode->extType = FSNode::SERVER; pNode->st.mode = S_IFDIR; break; case SMBC_FILE_SHARE: pNode->extType = FSNode::FILESHARE; pNode->st.mode = S_IFDIR; break; case SMBC_PRINTER_SHARE: case SMBC_COMMS_SHARE: case SMBC_IPC_SHARE: case SMBC_DIR: pNode->st.mode = S_IFDIR; break; default: InternalStat( path, &pNode->st, info ); } pNode->name.Set( sys_charset_id, pEnt->name ); list->Append( pNode ); }; smbc_closedir( d ); return 0; err: SetError( err, errno ); smbc_closedir( d ); return -1; } catch ( ... ) { smbc_closedir( d ); throw; } }
VError RmdirHelper::RemoveDir(const PathBuffer& inPath) const { int res=rmdir(inPath.GetPath()); return (res==0) ? VE_OK : MAKE_NATIVE_VERROR(errno); }