예제 #1
0
bool TranslationManager::openTranslationsFile(const FSNode &node, File &inFile, int depth) {
	if (!node.exists() || !node.isReadable() || !node.isDirectory())
		return false;

	// Check if we can find the file in this directory
	// Since File::open(FSNode) makes all the needed tests, it is not really
	// necessary to make them here. But it avoid printing warnings.
	FSNode fileNode = node.getChild("translations.dat");
	if (fileNode.exists() && fileNode.isReadable() && !fileNode.isDirectory()) {
		if (inFile.open(fileNode)) {
			if (checkHeader(inFile))
				return true;
			inFile.close();
		}
	}

	// Check if we exceeded the given recursion depth
	if (depth - 1 == -1)
		return false;

	// Otherwise look for it in sub-directories
	FSList fileList;
	if (!node.getChildren(fileList, FSNode::kListDirectoriesOnly))
		return false;

	for (FSList::iterator i = fileList.begin(); i != fileList.end(); ++i) {
		if (openTranslationsFile(*i, inFile, depth == -1 ? - 1 : depth - 1))
			return true;
	}

	// Not found in this directory or its sub-directories
	return false;
}
예제 #2
0
파일: archive.cpp 프로젝트: jvprat/residual
void SearchSet::addSubDirectoriesMatching(const FSNode &directory, String origPattern, bool ignoreCase, int priority) {
	FSList subDirs;
	if (!directory.getChildren(subDirs))
		return;

	String nextPattern, pattern;
	String::const_iterator sep = Common::find(origPattern.begin(), origPattern.end(), '/');
	if (sep != origPattern.end()) {
		pattern = String(origPattern.begin(), sep);

		++sep;
		if (sep != origPattern.end())
			nextPattern = String(sep, origPattern.end());
	}
	else {
		pattern = origPattern;
	}

	// TODO: The code we have for displaying all matches, which vary only in case, might
	// be a bit overhead, but as long as we want to display all useful information to the
	// user we will need to keep track of all directory names added so far. We might
	// want to reconsider this though.
	typedef HashMap<String, bool, IgnoreCase_Hash, IgnoreCase_EqualTo> MatchList;
	MatchList multipleMatches;
	MatchList::iterator matchIter;

	for (FSList::const_iterator i = subDirs.begin(); i != subDirs.end(); ++i) {
		String name = i->getName();

		if (Common::matchString(name.c_str(), pattern.c_str(), ignoreCase)) {
			matchIter = multipleMatches.find(name);
			if (matchIter == multipleMatches.end()) {
				multipleMatches[name] = true;
			} else {
				if (matchIter->_value) {
					warning("Clash in case for match of pattern \"%s\" found in directory \"%s\": \"%s\"", pattern.c_str(), directory.getPath().c_str(), matchIter->_key.c_str());
					matchIter->_value = false;
				}

				warning("Clash in case for match of pattern \"%s\" found in directory \"%s\": \"%s\"", pattern.c_str(), directory.getPath().c_str(), name.c_str());
			}

			if (nextPattern.empty())
				addDirectory(name, *i, priority);
			else
				addSubDirectoriesMatching(*i, nextPattern, ignoreCase, priority);
		}
	}
}
예제 #3
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;
}
예제 #4
0
파일: fs.cpp 프로젝트: RobLoach/scummvm
bool FSNode::getChildren(FSList &fslist, ListMode mode, bool hidden) const {
    if (!_realNode || !_realNode->isDirectory())
        return false;

    AbstractFSList tmp;

    if (!_realNode->getChildren(tmp, mode, hidden))
        return false;

    fslist.clear();
    for (AbstractFSList::iterator i = tmp.begin(); i != tmp.end(); ++i) {
        fslist.push_back(FSNode(*i));
    }

    return true;
}
예제 #5
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;
}
예제 #6
0
bool FilesystemNode::listDir(FSList &fslist, ListMode mode) const {
	if (!_realNode || !_realNode->isDirectory())
		return false;

	AbstractFSList tmp;
	
	if (!_realNode->listDir(tmp, mode))
		return false;
	
	fslist.clear();
	for (AbstractFSList::iterator i = tmp.begin(); i != tmp.end(); ++i) {
		fslist.push_back(FilesystemNode(*i));
	}
	
	return true;
}
예제 #7
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);
}
예제 #8
0
void Sword1CheckDirectory(const FSList &fslist, bool *filesFound) {
	for (FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
		if (!file->isDirectory()) {
			const char *fileName = file->displayName().c_str();
			for (int cnt = 0; cnt < NUM_FILES_TO_CHECK; cnt++)
				if (scumm_stricmp(fileName, g_filesToCheck[cnt]) == 0)
					filesFound[cnt] = true;
		} else {
			for (int cnt = 0; cnt < ARRAYSIZE(g_dirNames); cnt++)
				if (scumm_stricmp(file->displayName().c_str(), g_dirNames[cnt]) == 0) {
					FSList fslist2;
					if (file->listDir(fslist2, FilesystemNode::kListFilesOnly))
						Sword1CheckDirectory(fslist2, filesFound);
				}
		}
	}
}
예제 #9
0
DetectedGameList Engine_GOB_detectGames(const FSList &fslist) {
	DetectedGameList detectedGames;
	const GameSettings *g;
	FSList::const_iterator file;

	// Iterate over all files in the given directory
	for (file = fslist.begin(); file != fslist.end(); file++) {
		if (file->isDirectory())
			continue;

		// All the supported games have an intro.stk file.
		if (scumm_stricmp(file->displayName().c_str(), "intro.stk") == 0)
			break;
	}

	if (file == fslist.end())
		return detectedGames;

	uint8 md5sum[16];
	char md5str[32 + 1];

	if (Common::md5_file(file->path().c_str(), md5sum, kMD5FileSizeLimit)) {
		for (int i = 0; i < 16; i++) {
			sprintf(md5str + i * 2, "%02x", (int)md5sum[i]);
		}
		for (g = gob_games; g->gameid; g++) {
			if (strcmp(g->md5sum, (char *)md5str) == 0) {
				detectedGames.push_back(DetectedGame(g->gameid, g->description));
			}
		}
		if (detectedGames.empty()) {
			printf("Unknown MD5 (%s)! Please report the details (language, platform, etc.) of this game to the ScummVM team\n", md5str);

			const PlainGameDescriptor *g1 = gob_list;
			while (g1->gameid) {
				detectedGames.push_back(*g1);
				g1++;
			}
		}
	}
	return detectedGames;
}
예제 #10
0
void File::addDefaultDirectoryRecursive(const FilesystemNode &dir, int level, const String &prefix) {
	if (level <= 0)
		return;

	FSList fslist;
	if (!dir.listDir(fslist, FilesystemNode::kListAll)) {
		// Failed listing the contents of this node, so it is either not a 
		// directory, or just doesn't exist at all.
		return;
	}

	if (!_defaultDirectories)
		_defaultDirectories = new StringIntMap;

	// Do not add directories multiple times, unless this time they are added
	// with a bigger depth.
	const String &directory(dir.path());
	if (_defaultDirectories->contains(directory) && (*_defaultDirectories)[directory] >= level)
		return;
	(*_defaultDirectories)[directory] = level;

	if (!_filesMap)
		_filesMap = new FilesMap;

	for (FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
		if (file->isDirectory()) {
			addDefaultDirectoryRecursive(file->path(), level - 1, prefix + file->displayName() + "/");
		} else {
			String lfn(prefix);
			lfn += file->displayName();
			lfn.toLowercase();
			if (!_filesMap->contains(lfn)) {
				(*_filesMap)[lfn] = file->path();
			}
		}
	}
}
예제 #11
0
파일: fs.cpp 프로젝트: RobLoach/scummvm
void FSDirectory::cacheDirectoryRecursive(FSNode node, int depth, const String& prefix) const {
    if (depth <= 0)
        return;

    FSList list;
    node.getChildren(list, FSNode::kListAll, true);

    FSList::iterator it = list.begin();
    for ( ; it != list.end(); ++it) {
        String name = prefix + it->getName();

        // don't touch name as it might be used for warning messages
        String lowercaseName = name;
        lowercaseName.toLowercase();

        // since the hashmap is case insensitive, we need to check for clashes when caching
        if (it->isDirectory()) {
            if (!_flat && _subDirCache.contains(lowercaseName)) {
                warning("FSDirectory::cacheDirectory: name clash when building cache, ignoring sub-directory '%s'", name.c_str());
            } else {
                if (_subDirCache.contains(lowercaseName)) {
                    warning("FSDirectory::cacheDirectory: name clash when building subDirCache with subdirectory '%s'", name.c_str());
                }
                cacheDirectoryRecursive(*it, depth - 1, _flat ? prefix : lowercaseName + "/");
                _subDirCache[lowercaseName] = *it;
            }
        } else {
            if (_fileCache.contains(lowercaseName)) {
                warning("FSDirectory::cacheDirectory: name clash when building cache, ignoring file '%s'", name.c_str());
            } else {
                _fileCache[lowercaseName] = *it;
            }
        }
    }

}
예제 #12
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;
}
예제 #13
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;
}