bool OperCFThread::Copy(FS *srcFs, FSPath &__srcPath, FSList *list, FS *destFs, FSPath &__destPath, cstrhash<bool,unicode_t> &resList) { if (list->Count()<=0) return true; FSPath srcPath = __srcPath; int srcPos = srcPath.Count(); FSPath destPath = __destPath; int destPos = destPath.Count(); FSStat st; int ret_error; int res = destFs->Stat(__destPath, &st, &ret_error, Info()); if (res == -2) return false; if (res && !destFs->IsENOENT(ret_error)) { RedMessage( _LT("Can't copy to:\n"), destFs->Uri(destPath).GetUtf8(), bOk, destFs->StrError(ret_error).GetUtf8()); return false; } bool exist = (res == 0); if (list->Count()>1) { //если файлов >1 то копировать можно только в каталог if (!exist) { RedMessage( _LT("Can't copy files, destination is not found:\n"), destFs->Uri(__destPath).GetUtf8(), bOk); return false; } if (!st.IsDir()) { RedMessage( _LT("Destination is not directory:\n"), destFs->Uri(__destPath).GetUtf8(), bOk); return false; } for (FSNode *node = list->First(); node; node = node->next) { if (Info()->Stopped()) return false; srcPath.SetItemStr(srcPos, node->Name()); destPath.SetItemStr(destPos, node->Name()); if (!CopyNode(srcFs, srcPath, node, destFs, destPath, false)) return false; resList[node->Name().GetUnicode()] = true; } } else { // 1 element if (exist && st.IsDir()) destPath.SetItemStr(destPos, list->First()->Name()); srcPath.SetItemStr(srcPos, list->First()->Name()); if (!CopyNode(srcFs, srcPath, list->First(), destFs, destPath, false)) return false; resList[list->First()->Name().GetUnicode()] = true; }; return true; }
bool OperCFThread::Move(FS *srcFs, FSPath &__srcPath, FSList *list, FS *destFs, FSPath &__destPath) { if (list->Count()<=0) return true; FSPath srcPath = __srcPath; int srcPos = srcPath.Count(); FSPath destPath = __destPath; int destPos = destPath.Count(); FSStat st; int ret_error; int r = destFs->Stat(__destPath, &st, &ret_error, Info()); if (r == -2) return false; if (list->Count()>1) { //если файлов >1 то копировать можно только в каталог if (r) { RedMessage( _LT("Can't move files, bad destination directory:\n"), destFs->Uri(__destPath).GetUtf8(), bOk, destFs->StrError(ret_error).GetUtf8()); return false; } if (!st.IsDir()) { RedMessage( _LT("Destination is not directory:\n"), destFs->Uri(__destPath).GetUtf8(), bOk); return false; } for (FSNode *node = list->First(); node; node = node->next) { srcPath.SetItemStr(srcPos, node->Name()); destPath.SetItemStr(destPos, node->Name()); //printf("MOVE '%s'\n", srcPath.GetUtf8()); if (!MoveNode(srcFs, srcPath, node, destFs, destPath)) return false; } } else { // 1 element if (r && !destFs->IsENOENT(ret_error)) { RedMessage( _LT("Can't move to:\n"), destFs->Uri(destPath).GetUtf8(), bOk, destFs->StrError(ret_error).GetUtf8()); return false; } if (!r && st.IsDir()) destPath.SetItemStr(destPos, list->First()->Name()); FSNode *node = list->First(); srcPath.SetItemStr(srcPos, list->First()->Name()); if (!MoveNode(srcFs, srcPath, list->First(), destFs, destPath)) return false; } return true; }
bool FSTmp::AddNode(FSPath& srcPath, FSPath& destDir) { FSTmpNode* dn = rootDir.findByFsPath(&destDir); if (!dn || dn->nodeType != FSTmpNode::NODE_DIR) { return false; } FSStat st; if (baseFS->Stat(srcPath, &st, 0, 0)!=0) return false; if (!st.IsReg()) return false; FSTmpNode fsTmpNode(&srcPath, &st, dn); return dn->Add(&fsTmpNode); }
void InitConfigPath() { #ifdef _WIN32 #else const sys_char_t *home = (sys_char_t*) getenv("HOME"); if (home) { FSPath path(sys_charset_id, home); path.Push(CS_UTF8, ".wcm"); FSSys fs; FSStat st; int err; if (fs.Stat(path, &st, &err, 0)) { if (fs.IsENOENT(err)) //директорий не существует { if (fs.MkDir(path, 0700, &err, 0)) { fprintf(stderr, "can`t create config directory %s (%s)", path.GetUtf8(), fs.StrError(err).GetUtf8()); return; } } else { fprintf(stderr, "can`t create config directory statuc %s (%s)", path.GetUtf8(), fs.StrError(err).GetUtf8()); return; } } else if (!st.IsDir()) { fprintf(stderr, "err: '%s' is not directory", path.GetUtf8()); return; } configDirPath = path; } else { fprintf(stderr, "err: HOME env value not found"); } #endif }
void OperRDThread::Run() { int n = 8; int ret_err; while (true) { if (!(fs->Flags() & FS::HAVE_SYMLINK)) break; FSStat st; if (fs->Stat(path, &st, &ret_err, Info())) throw_msg("%s", fs->StrError(ret_err).GetUtf8()); if (!st.IsLnk()) break; n--; if (n<0) throw_msg("too more symbolic links '%s'", path.GetUtf8()); path.Pop(); if (!ParzeLink(path, st.link)) throw_msg("invalid symbolic link '%s'", path.GetUtf8()); } cptr<FSList> list = new FSList; int ret = fs->ReadDir(list.ptr(), path, &ret_err, Info()); if (ret) throw_msg("%s", fs->StrError(ret_err).GetUtf8()); MutexLock lock(Node().GetMutex()); //!!! if (Node().NBStopped()) return; OperRDData *data = ((OperRDData*)Node().Data()); data->list = list; data->path = path; data->executed = true; }
void OperRDThread::Run() { if ( !fs.Ptr() ) { return; } int n = 8; int ret_err; int havePostponedStatError = 0; FSString postponedStrError; while ( true ) { if ( !( fs->Flags() & FS::HAVE_SYMLINK ) ) { break; } FSStat st; // if path is inaccessible, try .. path. Throw the exception later // This makes panel at least having some valid folder while ( fs->Stat( path, &st, &ret_err, Info() ) ) { havePostponedStatError = 1; postponedStrError = fs->StrError( ret_err ); if ( !path.IsAbsolute() || path.Count() <= 1 || !path.Pop() ) { throw_msg( "%s", postponedStrError.GetUtf8() ); } } // yell immediately if the path is inaccessible (orig behavior) //if (fs->Stat(path, &st, &ret_err, Info())) // throw_msg("%s", fs->StrError(ret_err).GetUtf8()); if ( !st.IsLnk() ) { break; } n--; if ( n < 0 ) { throw_msg( "too many symbolic links '%s'", path.GetUtf8() ); } path.Pop(); if ( !ParzeLink( path, st.link ) ) { throw_msg( "invalid symbolic link '%s'", path.GetUtf8() ); } } clPtr<FSList> list = new FSList; int havePostponedReadError = 0; // if directory is not readable, try .. path. Throw the exception later // "Stat" call above does not catch this: it checks only folder existence, but not accessibilly while ( fs->ReadDir( list.ptr(), path, &ret_err, Info() ) ) { havePostponedReadError = 1; postponedStrError = fs->StrError( ret_err ); if ( !path.IsAbsolute() || path.Count() <= 1 || !path.Pop() ) { throw_msg( "%s", postponedStrError.GetUtf8() ); } } // yell immediately if the dir is unreadable (orig behavior) //int ret = fs->ReadDir(list.ptr(), path, &ret_err, Info()); //if (ret) // throw_msg("%s", fs->StrError(ret_err).GetUtf8()); FSStatVfs vst; fs->StatVfs( path, &vst, &ret_err, Info() ); MutexLock lock( Node().GetMutex() ); //!!! if ( Node().NBStopped() ) { return; } OperRDData* data = ( ( OperRDData* )Node().Data() ); data->list = list; data->path = path; data->executed = true; data->vst = vst; if ( havePostponedReadError || havePostponedStatError ) { data->nonFatalErrorString = postponedStrError; } }
int OperCFThread::MoveDir( FS* srcFs, FSPath& __srcPath, FSNode* srcNode, FS* destFs, FSPath& __destPath ) { if ( Info()->Stopped() ) { return -1; } if ( srcFs != destFs ) { return 1; } FSPath srcPath = __srcPath; int srcPos = srcPath.Count(); FSPath destPath = __destPath; int destPos = destPath.Count(); if ( IsSameFile( srcFs, srcPath, &( srcNode->st ), destFs, destPath ) ) { RedMessage( _LT( "Can't move directory to itself:\n" ), srcFs->Uri( __srcPath ).GetUtf8() ); return -1; } FSStat st; int ret_error; if ( !destFs->Stat( destPath, &st, &ret_error, Info() ) ) { if ( !st.IsDir() ) { switch ( RedMessage( _LT( "Can't copy directory\n" ), srcFs->Uri( srcPath ).GetUtf8(), _LT( "to file" ), "\n", _LT( "Delete the file?" ), destFs->Uri( destPath ).GetUtf8(), bOkSkipCancel ) ) { case CMD_CANCEL: return -1; case CMD_SKIP: return 0; } if ( !Unlink( destFs, destPath ) ) { return -1; } } else { FSList list; while ( true ) { int ret = srcFs->ReadDir( &list, srcPath, &ret_error, Info() ); if ( ret == -2 ) { return -1; } if ( !ret ) { break; } switch ( RedMessage( _LT( "Can`t open directory:\n" ), srcFs->Uri( __srcPath ).GetUtf8(), bRetrySkipCancel, srcFs->StrError( ret_error ).GetUtf8() ) ) { case CMD_SKIP: return 0; case CMD_RETRY: continue; default: return -1; } } for ( FSNode* node = list.First(); node; node = node->next ) { if ( Info()->Stopped() ) { return -1; } srcPath.SetItemStr( srcPos, node->Name() ); destPath.SetItemStr( destPos, node->Name() ); if ( !MoveFile( srcFs, srcPath, node, destFs, destPath ) ) { return -1; } } destFs->SetFileTime( destPath, srcNode->st.m_CreationTime, srcNode->st.m_LastWriteTime, srcNode->st.m_LastWriteTime, 0, Info() ); return RmDir( srcFs, srcPath ) ? 0 : -1; } } if ( srcFs->Rename( srcPath, destPath, &ret_error, Info() ) ) { if ( srcFs->IsEXDEV( ret_error ) ) { return 1; } return RedMessage( _LT( "Can't rename the directory:\n" ), srcFs->Uri( srcPath ).GetUtf8(), "\nto\n", destFs->Uri( destPath ).GetUtf8(), bSkipCancel, srcFs->StrError( ret_error ).GetUtf8() ) == CMD_SKIP ? 0 : -1; } return 0; }
bool IsDir() const { return fsStat.IsDir(); }