clPtr<FS> clArchPlugin::OpenFS( clPtr<FS> Fs, FSPath& Path ) const
{
	FSString Uri = Fs->Uri( Path );

	struct archive* Arch = ArchOpen( Uri.GetUtf8() );

	if ( Arch == nullptr )
	{
		return nullptr;
	}

	FSArchNode RootDir;
	RootDir.fsStat.mode = S_IFDIR;

	FSPath NodePath;
	struct archive_entry* entry = archive_entry_new2( Arch );

	int Res;

	while ( ( Res = archive_read_next_header2( Arch, entry ) ) == ARCHIVE_OK )
	{
		NodePath.Set( CS_UTF8, archive_entry_pathname( entry ) );

		FSString* ItemName = NodePath.GetItem( NodePath.Count() - 1 );

		if ( NodePath.Count() == 1 && ( ItemName->IsDot() || ItemName->IsEmpty() ) )
		{
			// skip root dir
			continue;
		}

		const mode_t Mode = archive_entry_mode( entry );
		const int64_t Size = archive_entry_size( entry );
		RootDir.entryOffset += Size;

		FSStat ItemStat;
		ItemStat.mode = S_ISREG( Mode ) ? Mode : S_IFDIR;
		ItemStat.size = Size;
		ItemStat.m_CreationTime = archive_entry_ctime( entry );
		ItemStat.m_LastAccessTime = archive_entry_atime( entry );
		ItemStat.m_LastWriteTime = archive_entry_mtime( entry );
		ItemStat.m_ChangeTime = ItemStat.m_LastWriteTime;

		FSArchNode* Dir = ArchGetParentDir( &RootDir, NodePath, ItemStat );
		FSArchNode* Item = Dir->Add( FSArchNode( ItemName->GetUtf8(), ItemStat ) );
		if (Item) {
			Item->entryOffset = archive_read_header_position( Arch );
		}
	}

	if ( Res != ARCHIVE_EOF )
	{
		dbg_printf( "Couldn't read archive entry: %s\n", archive_error_string( Arch ) );
	}

	archive_entry_free( entry );
	ArchClose( Arch );

	return new FSArch( RootDir, Uri );
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
int FSTmp::MkDir(FSPath& path, int mode, int* err, FSCInfo* info)
{
	FSPath parentPath;
	parentPath.Copy(path, path.Count() - 1);
	FSTmpNode* parent = rootDir.findByFsPath(&parentPath);
	if (!parent)
		return SetError(err, FSTMP_ERROR_FILE_NOT_FOUND);
	FSTmpNode* parentDir = parent;
	FSTmpNode fsTmpNode(path.GetItem(path.Count() - 1)->GetUnicode(), parentDir);
	parentDir->Add(&fsTmpNode);
	return SetError(err, 0);
}
Esempio n. 5
0
static void stripPathFromLastItem(FSPath& path)
{
	FSString* lastItem = path.GetItem(path.Count() - 1);
	if (lastItem)
	{
		const unicode_t* lastU = lastItem->GetUnicode();
		const unicode_t* lastDelim = unicode_strrchr(lastU, DIR_SPLITTER);
		if (lastDelim != 0)
		{
			path.SetItemStr(path.Count() - 1,FSString(lastDelim + 1));
		}
	}
}
Esempio n. 6
0
int FSSys::Stat( FSPath& path, FSStat* fsStat, int* err, FSCInfo* info )
{
	if ( _drive >= 0 && path.Count() == 1 || _drive == -1 && path.Count() == 3 )
	{
		//pseudo stat
		fsStat->size = 0;
		fsStat->dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
		fsStat->mode = S_IFDIR;
		fsStat->mtime = 0;
		fsStat->mode |= 0664;
		return 0;
	}

	WIN32_FIND_DATAW ent;
	HANDLE handle = FindFirstFileW( SysPathStr( _drive, path.GetUnicode() ).data(), &ent );

	if ( handle == INVALID_HANDLE_VALUE )
	{
		SetError( err, GetLastError() );
		return -1;
	}

	try
	{
		fsStat->size = ( seek_t( ent.nFileSizeHigh ) << 32 ) + ent.nFileSizeLow;
		fsStat->dwFileAttributes = ent.dwFileAttributes;
		fsStat->mtime = ent.ftLastWriteTime;

		if ( ent.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
		{
			fsStat->mode = S_IFDIR;
		}
		else
		{
			fsStat->mode = S_IFREG;
		}

		fsStat->mode |= 0664;
		FindClose( handle );
		return 0;
	}
	catch ( ... )
	{
		FindClose( handle );
		throw;
	}

	//...
	SetError( err, 50 );
	return -1;
}
Esempio n. 7
0
void FSPath::Copy(const FSPath& a, int elementCount)
{
	cacheCs = -2;
	data.clear();
	if (elementCount<0 || elementCount>a.Count())
		elementCount = a.Count();

	for (int i = 0; i < elementCount; i++)
	{
		FSString s;
		s.Copy(a.data.const_item(i));
		data.append(s);
	}

}
Esempio n. 8
0
bool DeleteListRecursively( FS* fs, FSPath path, FSList& list )
{
	const int cnt = path.Count();
	int ret_err;

	for ( FSNode* node = list.First(); node; node = node->next )
	{
		if ( node->extType )
		{
			continue;
		}

		path.SetItemStr( cnt, node->Name() );

		if ( node->IsDir() && !node->st.IsLnk() )
		{
			if ( !DeleteDirRecursively( fs, path ) )
			{
				return false;
			}
		}
		else if ( fs->Delete( path, &ret_err, nullptr ) != 0 )
		{
			return false;
		}
	}

	return true;
}
Esempio n. 9
0
int FSTmp::Delete(FSPath& path, int* err, FSCInfo* info)
{
	FSString* dName = path.GetItem(path.Count() - 1);
	FSTmpNode* n = rootDir.findByName(dName);
	if (n == 0)
	{
		return FS::SetError(err, FSTMP_ERROR_FILE_NOT_FOUND);;
	}
	else
	{
		/*
		if (n->nodeType == FSTmpNode::NODE_FILE)
		{ // remove file at base FS
			int ret = baseFS->Delete(n->baseFSPath, err, info);
			if (ret != 0)
				return ret;
		}
		*/
		// remove from tmpfs list
		for (auto it = n->parentDir->content.begin(); it != n->parentDir->content.end(); ++it)
		{ 
			if ((*it).name.Cmp(*dName) == 0)
			{
				n->parentDir->content.erase(it);
				return FS::SetError(err, 0);
			}
		}
		return FS::SetError(err, FSTMP_ERROR_FILE_NOT_FOUND);;
	}
}
Esempio n. 10
0
void OperCFThread::CreateDirectory( FS* fs, FSPath& srcPath, FSPath& destPath, bool processMultipleFolders )
{
	if ( processMultipleFolders )
	{
		const int DirIndex = srcPath.GetFirstUnmatchedItem( destPath );
		FSPath Path;

		for ( int i = 0; i < destPath.Count(); i++ )
		{
			// get next dir
			Path.PushStr( *destPath.GetItem( i ) );
			
			int ret_err;

			// try to create dir
			if ( i >= DirIndex && fs->MkDir( Path, 0777, &ret_err, Info() ) )
			{
				// skip "already exists" error
				if ( !fs->IsEEXIST( ret_err ) )
				{
					throw_msg( "%s", fs->StrError( ret_err ).GetUtf8() );
				}
			}
		}
	}
	else
	{
		int ret_err;

		if ( fs->MkDir( destPath, 0777, &ret_err, Info() ) )
		{
			throw_msg( "%s", fs->StrError( ret_err ).GetUtf8() );
		}
	}
}
Esempio n. 11
0
bool ParzeLink( FSPath& path, FSString& link )
{
	FSPath t( link );

	if ( !path.IsAbsolute() && !t.IsAbsolute() ) { return false; } //не абсолютный путь

	int first = 0;

	if ( t.IsAbsolute() )
	{
		path.Clear();
		path.PushStr( FSString( "" ) );
		first = 1;
	}

	for ( int i = first; i < t.Count(); i++ )
	{
		FSString p = *( t.GetItem( i ) );

		if ( p.IsDot() ) { continue; }

		if ( p.Is2Dot() )
		{
			if ( path.Count() > 1 ) { path.Pop(); }
		}
		else
		{
			path.PushStr( p );
		}
	}

	return true;
}
Esempio n. 12
0
bool OperCFThread::DeleteList( FS* fs, FSPath& _path, FSList& list )
{
	if ( Info()->Stopped() ) { return false; }

	FSPath path = _path;
	int cnt = path.Count();

	for ( FSNode* node = list.First(); node; node = node->next )
	{
		if ( node->extType ) { continue; }

		path.SetItemStr( cnt, node->Name() );

		if ( node->IsDir() && !node->st.IsLnk() )
		{
			if ( !DeleteDir( fs, path ) ) { return false; }

			if ( !RmDir( fs, path ) ) { return false; }

			continue;
		}

		if ( !DeleteFile( fs, path ) ) { return false; }
	}

	return true;
}
Esempio n. 13
0
bool OperCFThread::CopyDir(FS *srcFs, FSPath &__srcPath, FSNode *srcNode, FS *destFs, FSPath &__destPath, bool move)
{
	if (Info()->Stopped()) return false;

	FSList list;
	
	int ret_error;
	
	while (true) {
		int ret = srcFs->ReadDir(&list, __srcPath, &ret_error, Info());
		if (ret == -2) return false;
		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 true;
		case CMD_RETRY: continue;
		default: return false;
		}
	}
	
	while (destFs->MkDir(__destPath, MkDirMode, &ret_error, Info()) && !destFs->IsEEXIST(ret_error)) {
		switch (RedMessage( _LT("Can't create the directory:\n"), destFs->Uri(__destPath).GetUtf8(), bRetrySkipCancel, destFs->StrError(ret_error).GetUtf8())) {
		case CMD_CANCEL: return false;
		case CMD_SKIP: return true;
		}
	}
		
	
	FSPath srcPath = __srcPath; int srcPos = srcPath.Count();
	FSPath destPath = __destPath; int destPos = destPath.Count();
	
		
	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, move)) return false; 
	}

	destFs->SetFileTime(destPath, srcNode->st.mtime, srcNode->st.mtime, 0, Info());

	return !move || RmDir(srcFs, __srcPath);
}
Esempio n. 14
0
void FSPath::Copy( const FSPath& a )
{
	cacheCs = -2;
	data.clear();

	for ( int i = 0 ; i < a.Count(); i++ )
	{
		FSString s;
		s.Copy( a.data.const_item( i ) );
		data.append( s );
	}
}
Esempio n. 15
0
int FSTmp::Rename(FSPath&  oldpath, FSPath& newpath, int* err, FSCInfo* info)
{
	FSTmpNode* n = rootDir.findByName(oldpath.GetItem(oldpath.Count() - 1));
	if (n == 0)
	{
		return FS::SetError(err, FSTMP_ERROR_FILE_NOT_FOUND);
	}
	else
	{
		if (n->nodeType == FSTmpNode::NODE_FILE)
		{
			int ret = baseFS->Rename(n->baseFSPath, newpath, err, info);
			if (ret != 0)
				return ret;
			n->name = newpath.GetUnicode();
			return SetError(err, 0);
		}
		else
		{// XXX ??? add case when new and old path are in different dirs
			((FSTmpNode*)(n))->name = *newpath.GetItem(newpath.Count() - 1);
			return SetError(err, 0);
		}
	}
}
Esempio n. 16
0
int FSTmp::RmDir(FSPath& path, int* err, FSCInfo* info)
{
	FSTmpNode* n = rootDir.findByFsPath(&path);
	FSString* dirName = path.GetItem(path.Count() - 1);

	for (auto it = n->parentDir->content.begin(); it != n->parentDir->content.end(); ++it)
	{
		if ((*it).name.Cmp(*dirName) == 0)
		{
			n->parentDir->content.erase(it);
			return FS::SetError(err, 0);
		}
	}
	return FS::SetError(err, FSTMP_ERROR_FILE_NOT_FOUND);
}
Esempio n. 17
0
void OperDirCalcThread::Calc()
{
	MutexLock lock( Node().GetMutex() );

	if ( !Node().Data() ) { return; }

	OperDirCalcData* CalcData = ( OperDirCalcData* )Node().Data();

	clPtr<FS> fs = CalcData->dirFs;
	FSPath path =  CalcData->_path;
	clPtr<FSList> list = CalcData->dirList;

	lock.Unlock(); //!!!


	//dbg_printf("OperDirCalcThread::Calc list data:");
	//path.dbg_printf("FSPath:");
	//for (FSNode* node = list->First(); node; node = node->next)
	//	dbg_printf("%s\n", node->name.GetUtf8());
	if (list->Count() == 0)
	{ // then calculate current dir size
		CalcDir(fs.Ptr(), path);
	}
	else
	{ // list is not empty: calculate size of objects in the list
		int cnt = path.Count();

		for (FSNode* node = list->First(); node; node = node->next)
		{
			path.SetItemStr(cnt, node->Name()); //-V595

			bool IsDir = node->IsDir() && !node->st.IsLnk();

			if ( IsDir )
			{
				int64_t Size = CalcDir( fs.Ptr(), path);

				if ( Size >= 0 && node && node->originNode ) { node->originNode->st.size = Size; }
				CalcData->folderCount++;
			}
			else
			{
				CalcData->fileCount++;
				CalcData->sumSize += node->st.size;
			}
		}
	}
}
Esempio n. 18
0
int FSTmp::SetFileTime(FSPath& path, FSTime cTime, FSTime aTime, FSTime mTime, int* err, FSCInfo* info)
{
	FSTmpNode* fsTemp = rootDir.findByName(path.GetItem(path.Count() - 1));
	if (fsTemp == 0)
	{
		return FS::SetError(err, FSTMP_ERROR_FILE_NOT_FOUND);
	}
	else
	{
		fsTemp->fsStat.m_CreationTime = cTime;
		fsTemp->fsStat.m_LastAccessTime = aTime;
		fsTemp->fsStat.m_LastWriteTime = mTime;
		fsTemp->fsStat.m_ChangeTime = mTime;

		if (fsTemp->nodeType == FSTmpNode::NODE_FILE)
			return baseFS->SetFileTime(fsTemp->baseFSPath, cTime, aTime, mTime, err, info);
		else
			return FS::SetError(err, 0);
			
	}
}
Esempio n. 19
0
int FSTmp::ReadDir(FSList* list, FSPath& path, int* err, FSCInfo* info)
{
	list->Clear();

	// Adding the ".." node to root dir even if it is disabled in config 
	// to address CR #436: "Temporary panel should have .. item to go back to last directory"
	if (!g_WcmConfig.panelShowDotsInRoot)
	{
		if (path.Count() == 1) // i.e. on root level
		{
			clPtr<FSNode> pNode = new FSNode();
			pNode->name = std::string("..");
			pNode->st.mode = S_IFDIR;
			list->Append(pNode);
		}
	}

	FSTmpNode* n = rootDir.findByFsPath(&path);
	if (!n || n->nodeType != FSTmpNode::NODE_DIR)
	{
		return FS::SetError(err, FSTMP_ERROR_FILE_NOT_FOUND);
	}

	for (FSTmpNode& tn : n->content)
	{
		clPtr<FSNode> pNode = new FSNode();

		pNode->name=(std::string("") + tn.name.GetUtf8()).c_str();
		if (tn.nodeType == FSTmpNode::NODE_DIR)
			pNode->st = tn.fsStat;
		else
		{
			if (baseFS->Stat(tn.baseFSPath, & pNode->st, 0, 0) != 0)
				pNode->st = tn.fsStat;
		}
		list->Append(pNode);
	}
	return 0;
}
Esempio n. 20
0
int FSWin32Net::ReadDir ( FSList* list, FSPath& path, int* err, FSCInfo* info )
{
	list->Clear();

	if ( path.Count() > 1 )
	{
		if ( err ) { *err = ERRNOSUPPORT; }

		return -1;
	}


	WNetEnumerator en;

	if ( !en.Open( _res.Get() ) )
	{
		SetError( err, GetLastError() );
		return -1;
	}

	try
	{
		while ( true )
		{
			if ( info && info->Stopped() )
			{
				return -2;
			}

			DWORD dwErr = 0;
			NETRESOURCEW* p = en.Next( &dwErr );

			if ( !p )
			{
				if ( !dwErr ) { break; }

				SetError( err, dwErr );
				return -1;
			}

			if ( !p->lpRemoteName ) { continue; }

			wchar_t* pName = p->lpRemoteName;

			if ( p->dwDisplayType == RESOURCEDISPLAYTYPE_SHARE || p->dwDisplayType == RESOURCEDISPLAYTYPE_SERVER )
			{
				//выкинуть из названия шары имя сервера, а из названия сервера - косые символы
				wchar_t* last = 0;

				for ( wchar_t* s = pName; *s; s++ )
					if ( *s == '\\' ) { last = s; }

				if ( last && last[1] ) { pName = last + 1; }
			}

			clPtr<FSNode> pNode = new FSNode();

			pNode->name.Set( CS_UNICODE, Utf16ToUnicode( pName ).data() );
			pNode->st.mode = S_IFDIR;
			pNode->st.mode |= 0664;

			pNode->_w32NetRes = W32NetRes( p );

			switch ( p->dwDisplayType )
			{
					//case RESOURCEDISPLAYTYPE_GENERIC: return "GENERIC";
				case RESOURCEDISPLAYTYPE_DOMAIN:
				case RESOURCEDISPLAYTYPE_GROUP:
				case RESOURCEDISPLAYTYPE_NETWORK:
					pNode->extType = FSNode::WORKGROUP;
					break;

				case RESOURCEDISPLAYTYPE_SERVER:
					pNode->extType = FSNode::SERVER;
					break;

				case RESOURCEDISPLAYTYPE_DIRECTORY:
				case RESOURCEDISPLAYTYPE_SHARE:
					pNode->extType = FSNode::FILESHARE;
					break;
			};

			list->Append( pNode );
		};

		return 0;
	}
	catch ( ... )
	{
		throw;
	}

	SetError( err, 100 );
	return -1;
}
Esempio n. 21
0
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;
	}
}
Esempio n. 22
0
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;
}
Esempio n. 23
0
clPtr<FS> ParzeURI( const unicode_t* uri, FSPath& path, clPtr<FS>* checkFS, int count )
{

#ifdef LIBSMBCLIENT_EXIST

	if ( uri[0] == 's' && uri[1] == 'm' && uri[2] == 'b' && uri[3] == ':' && uri[4] == '/' && uri[5] == '/' )
	{
		return ParzeSmbURI( uri + 6, path, checkFS, count );
	}

#endif

	if ( uri[0] == 'f' && uri[1] == 't' && uri[2] == 'p' && uri[3] == ':' && uri[4] == '/' && uri[5] == '/' )
	{
		return ParzeFtpURI( uri + 6, path, checkFS, count );
	}

#if defined(LIBSSH_EXIST) || defined(LIBSSH2_EXIST)

	if ( uri[0] == 's' && uri[1] == 'f' && uri[2] == 't' && uri[3] == 'p' && uri[4] == ':' && uri[5] == '/' && uri[6] == '/' )
	{
		return ParzeSftpURI( uri + 7, path, checkFS, count );
	}

#endif

	if ( uri[0] == 'f' && uri[1] == 'i' && uri[2] == 'l' && uri[3] == 'e' && uri[4] == ':' && uri[5] == '/' && uri[6] == '/' )
	{
		uri += 6;   //оставляем 1 символ '/'
	}


#ifdef _WIN32
	int c = uri[0];

	if ( c == '\\' || c == '/' )
	{
		if ( uri[1] == '/' || uri[1] == '\\' )
		{
			FSString link = uri + 1;

			if ( !ParzeLink( path, link ) ) { return clPtr<FS>(); }

			if ( path.Count() == 1 )
			{
				clPtr<FS> netFs = new FSWin32Net( 0 );
				path.Set( CS_UTF8, "/" );
				return netFs;
			}

			if ( path.Count() == 2 )
			{
				static unicode_t aa[] = {'\\', '\\', 0};
				std::vector<wchar_t> name = UnicodeToUtf16( carray_cat<unicode_t>( aa, path.GetItem( 1 )->GetUnicode() ).data() );

				NETRESOURCEW r;
				r.dwScope = RESOURCE_GLOBALNET;
				r.dwType = RESOURCETYPE_ANY;
				r.dwDisplayType = RESOURCEDISPLAYTYPE_GENERIC;
				r.dwUsage = RESOURCEUSAGE_CONTAINER;
				r.lpLocalName = 0;
				r.lpRemoteName = name.data();
				r.lpComment = 0;
				r.lpProvider = 0;

				clPtr<FS> netFs = new FSWin32Net( &r );
				path.Set( CS_UTF8, "/" );
				return netFs;
			}

			return new FSSys( -1 );
		}

		FSString link = uri;

		if ( !ParzeLink( path, link ) ) { return clPtr<FS>(); }

		return ( count > 0 && !checkFS[0].IsNull() ) ? checkFS[0] : clPtr<FS>();
	}

	if ( c >= 'A' && c <= 'Z' ) { c = c - 'A' + 'a'; }

	if ( c < 'a' || c > 'z' || uri[1] != ':' || ( uri[2] != '/' && uri[2] != '\\' ) )
	{
		FSString link = uri;

		if ( !ParzeLink( path, link ) ) { return clPtr<FS>(); }

		return ( count > 0 && !checkFS[0].IsNull() ) ? checkFS[0] : clPtr<FS>();
	}

	FSString link = uri + 2;

	if ( !ParzeLink( path, link ) ) { return clPtr<FS>(); }

	return new FSSys( c - 'a' );
#else
	FSString link = uri;

	if ( !ParzeLink( path, link ) ) { return clPtr<FS>(); }

	if ( uri[0] != '/' )
	{
		return ( count > 0 && !checkFS[0].IsNull() ) ? checkFS[0] : clPtr<FS>();
	}

	return new FSSys(); //systemclPtr<FS>;
#endif
}
Esempio n. 24
0
int64_t OperDirCalcThread::CalcDir( FS* fs, FSPath path )
{
	if ( Info()->Stopped() ) { return -1; }

	{
		//lock
		MutexLock lock( Node().GetMutex() );

		if ( !Node().Data() ) { return -1; }

		OperDirCalcData* data = ( OperDirCalcData* )Node().Data();
		MutexLock l1( &data->resMutex );
		data->currentPath = path;
	}

	Node().SendSignal( 10 );

	FSList list;
	int err;

	if ( fs->ReadDir( &list, path, &err, Info() ) )
	{
		MutexLock lock( Node().GetMutex() );

		if ( !Node().Data() ) { return -1; }

		MutexLock l1( &( ( OperDirCalcData* )Node().Data() )->resMutex );
		( ( OperDirCalcData* )Node().Data() )->badDirs++;
		return -1;
	};

	int count = list.Count();

	std::vector<FSNode*> p = list.GetArray();

	//list.SortByName(p.ptr(), count, true, false);

	int lastPathPos = path.Count();

	FSPath filePath = path;

	int64_t fileCount = 0;

	int64_t folderCount = 0;

	int64_t sumSize = 0;

	int i;

	for ( i = 0; i < count; i++ )
	{
		if ( p[i]->IsDir() )
		{
			folderCount++;
			continue;
		};

		fileCount++;

		if ( p[i]->IsReg() && !p[i]->IsLnk() )
		{
			sumSize += p[i]->Size();
		}
	}

	{
		//lock
		MutexLock lock( Node().GetMutex() );

		if ( !Node().Data() ) { return -1; }

		OperDirCalcData* data = ( OperDirCalcData* )Node().Data();
		MutexLock l1( &data->resMutex );

		data->fileCount += fileCount;
		data->folderCount += folderCount;
		data->sumSize += sumSize;
	}

	Node().SendSignal( 20 );

	for ( i = 0; i < count; i++ )
	{
		if ( p[i]->IsDir() && !p[i]->extType && p[i]->st.link.IsEmpty() )
		{
			if ( Info()->Stopped() )
			{
				return -1;
			}

			path.SetItemStr( lastPathPos, p[i]->Name() );
			sumSize += CalcDir( fs, path );
		}
	}

	return sumSize;
}