/*
================
Sys_ListFiles
================
*/
int Sys_ListFiles( const char *directory, const char *extension, idStrList &list ) {
	struct dirent *d;
	DIR *fdir;
	bool dironly = false;
	char search[MAX_OSPATH];
	struct stat st;
	bool debug;

	list.Clear();

	debug = cvarSystem->GetCVarBool( "fs_debug" );

	if (!extension)
		extension = "";

	// passing a slash as extension will find directories
	if (extension[0] == '/' && extension[1] == 0) {
		extension = "";
		dironly = true;
	}

	// search
	// NOTE: case sensitivity of directory path can screw us up here
	if ((fdir = opendir(directory)) == NULL) {
		if (debug) {
			common->Printf("Sys_ListFiles: opendir %s failed\n", directory);
		}
		return -1;
	}

	while ((d = readdir(fdir)) != NULL) {
		idStr::snPrintf(search, sizeof(search), "%s/%s", directory, d->d_name);
		if (stat(search, &st) == -1)
			continue;
		if (!dironly) {
			idStr look(search);
			idStr ext;
			look.ExtractFileExtension(ext);
			if (extension[0] != '\0' && ext.Icmp(&extension[1]) != 0) {
				continue;
			}
		}
		if ((dironly && !(st.st_mode & S_IFDIR)) ||
			(!dironly && (st.st_mode & S_IFDIR)))
			continue;

		list.Append(d->d_name);
	}

	closedir(fdir);

	if ( debug ) {
		common->Printf( "Sys_ListFiles: %d entries in %s\n", list.Num(), directory );
	}

	return list.Num();
}
Пример #2
0
/*
===============
idSessionLocal::GetSaveGameList
===============
*/
void idSessionLocal::GetSaveGameList( idStrList &fileList, idList<fileTIME_T> &fileTimes ) {
	int i;
	idFileList *files;

	// NOTE: no fs_game_base for savegames
	idStr game = cvarSystem->GetCVarString( "fs_game" );
	if( game.Length() ) {
		files = fileSystem->ListFiles( "savegames", ".save", false, false, game );
	} else {
		files = fileSystem->ListFiles( "savegames", ".save" );
	}
	
	fileList = files->GetList();
	fileSystem->FreeFileList( files );

	for ( i = 0; i < fileList.Num(); i++ ) {
		ID_TIME_T timeStamp;

		fileSystem->ReadFile( "savegames/" + fileList[i], NULL, &timeStamp );
		fileList[i].StripLeading( '/' );
		fileList[i].StripFileExtension();

		fileTIME_T ft;
		ft.index = i;
		ft.timeStamp = timeStamp;
		fileTimes.Append( ft );
	}

	fileTimes.Sort( idListSaveGameCompare );
}
/*
============
idAASBuild::CheckForEntities
============
*/
bool idAASBuild::CheckForEntities( const idMapFile *mapFile, idStrList &entityClassNames ) const {
	int		i;
	idStr	classname;
	com_editors |= EDITOR_AAS;
	for( i = 0; i < mapFile->GetNumEntities(); i++ ) {
		if( !mapFile->GetEntity( i )->epairs.GetString( "classname", "", classname ) ) {
			continue;
		}
		if( aasSettings->ValidEntity( classname ) ) {
			entityClassNames.AddUnique( classname );
		}
	}
	com_editors &= ~EDITOR_AAS;
	return ( entityClassNames.Num() != 0 );
}
Пример #4
0
/*
========================
idResourceContainer::WriteManifestFile
========================
*/
void idResourceContainer::WriteManifestFile( const char* name, const idStrList& list )
{
	idStr filename( name );
	filename.SetFileExtension( "manifest" );
	filename.Insert( "maps/", 0 );
	idFile* outFile = fileSystem->OpenFileWrite( filename );
	if( outFile != NULL )
	{
		int num = list.Num();
		outFile->WriteBig( num );
		for( int i = 0; i < num; i++ )
		{
			outFile->WriteString( list[ i ] );
		}
		delete outFile;
	}
}
Пример #5
0
/*
========================
idResourceContainer::ReadManifestFile
========================
*/
int idResourceContainer::ReadManifestFile( const char* name, idStrList& list )
{
	idFile* inFile = fileSystem->OpenFileRead( name );
	if( inFile != NULL )
	{
		list.SetGranularity( 16384 );
		idStr str;
		int num;
		list.Clear();
		inFile->ReadBig( num );
		for( int i = 0; i < num; i++ )
		{
			inFile->ReadString( str );
			list.Append( str );
		}
		delete inFile;
	}
	return list.Num();
}
Пример #6
0
/*
==============
Sys_ListFiles
==============
*/
int Sys_ListFiles(const char *directory, const char *extension, idStrList &list)
{
	idStr		search;
	struct _finddata_t findinfo;
	int			findhandle;
	int			flag;

	if (!extension) {
		extension = "";
	}

	// passing a slash as extension will find directories
	if (extension[0] == '/' && extension[1] == 0) {
		extension = "";
		flag = 0;
	} else {
		flag = _A_SUBDIR;
	}

	sprintf(search, "%s\\*%s", directory, extension);

	// search
	list.Clear();

	findhandle = _findfirst(search, &findinfo);

	if (findhandle == -1) {
		return -1;
	}

	do {
		if (flag ^(findinfo.attrib & _A_SUBDIR)) {
			list.Append(findinfo.name);
		}
	} while (_findnext(findhandle, &findinfo) != -1);

	_findclose(findhandle);

	return list.Num();
}
Пример #7
0
void CDialogTextures::addStrList( const char *root, const idStrList &list, int id ) {
    idStr		out, path;

    HTREEITEM base = m_treeTextures.GetRootItem();
    while (base) {
        out = m_treeTextures.GetItemText(base);
        if (stricmp(root, out) == 0) {
            break;
        }
        base = m_treeTextures.GetNextSiblingItem(base);
    }

    if (base == NULL) {
        base = m_treeTextures.InsertItem(root);
    }

    HTREEITEM	item = base;
    HTREEITEM	add;

    int		count = list.Num();

    idStr	last, qt;
    for (int i = 0; i < count; i++) {
        idStr name = list[i];

        // now break the name down convert to slashes
        name.BackSlashesToSlashes();
        name.Strip(' ');

        int index;
        int len = last.Length();
        if (len == 0) {
            index = name.Last('/');
            if (index >= 0) {
                name.Left(index, last);
            }
        }
        else if (idStr::Icmpn(last, name, len) == 0 && name.Last('/') <= len) {
            name.Right(name.Length() - len - 1, out);
            add = m_treeTextures.InsertItem(out, item);
            qt = root;
            qt += "/";
            qt += name;
            quickTree.Set(qt, add);
            m_treeTextures.SetItemData(add, id);
            m_treeTextures.SetItemImage(add, 2, 2);
            continue;
        }
        else {
            last.Empty();
        }

        index = 0;
        item = base;
        path = "";
        while (index >= 0) {
            index = name.Find('/');
            if (index >= 0) {
                HTREEITEM newItem = NULL;
                HTREEITEM *check = NULL;
                name.Left( index, out );
                path += out;
                qt = root;
                qt += "/";
                qt += path;
                if (quickTree.Get(qt, &check)) {
                    newItem = *check;
                }
                //HTREEITEM	newItem = FindTreeItem(&m_treeTextures, item, name.Left(index, out), item);
                if (newItem == NULL) {
                    newItem = m_treeTextures.InsertItem(out, item);
                    qt = root;
                    qt += "/";
                    qt += path;
                    quickTree.Set(qt, newItem);
                    m_treeTextures.SetItemImage(newItem, 0, 1);
                }

                assert(newItem);
                item = newItem;
                name.Right( name.Length() - index - 1, out );
                name = out;
                path += "/";
            }
            else {
                add = m_treeTextures.InsertItem(name, item);
                qt = root;
                qt += "/";
                qt += path;
                qt += name;
                quickTree.Set(qt, add);
                m_treeTextures.SetItemData(add, id);
                m_treeTextures.SetItemImage(add, 2, 2);
                path = "";
            }
        }
    }

}
Пример #8
0
/*
================
Sys_ListFiles
================
*/
int Sys_ListFiles( const char* directory, const char* extension, idStrList& list )
{
	struct dirent* d;
	DIR* fdir;
	bool dironly = false;
	char search[MAX_OSPATH];
	struct stat st;
	bool debug;
	
	list.Clear();
	
	debug = cvarSystem->GetCVarBool( "fs_debug" );
	// DG: we use fnmatch for shell-style pattern matching
	// so the pattern should at least contain "*" to match everything,
	// the extension will be added behind that (if !dironly)
	idStr pattern( "*" );
	
	// passing a slash as extension will find directories
	if( extension[0] == '/' && extension[1] == 0 )
	{
		dironly = true;
	}
	else
	{
		// so we have *<extension>, the same as in the windows code basically
		pattern += extension;
	}
	// DG end
	
	// NOTE: case sensitivity of directory path can screw us up here
	if( ( fdir = opendir( directory ) ) == NULL )
	{
		if( debug )
		{
			common->Printf( "Sys_ListFiles: opendir %s failed\n", directory );
		}
		return -1;
	}
	
	// DG: use readdir_r instead of readdir for thread safety
	// the following lines are from the readdir_r manpage.. fscking ugly.
	int nameMax = pathconf( directory, _PC_NAME_MAX );
	if( nameMax == -1 )
		nameMax = 255;
	int direntLen = offsetof( struct dirent, d_name ) + nameMax + 1;
	
	struct dirent* entry = ( struct dirent* )Mem_Alloc( direntLen, TAG_CRAP );
	
	if( entry == NULL )
	{
		common->Warning( "Sys_ListFiles: Mem_Alloc for entry failed!" );
		closedir( fdir );
		return 0;
	}
	
	while( readdir_r( fdir, entry, &d ) == 0 && d != NULL )
	{
		// DG end
		idStr::snPrintf( search, sizeof( search ), "%s/%s", directory, d->d_name );
		if( stat( search, &st ) == -1 )
			continue;
		if( !dironly )
		{
			// DG: the original code didn't work because d3 bfg abuses the extension
			// to match whole filenames and patterns in the savegame-code, not just file extensions...
			// so just use fnmatch() which supports matching shell wildcard patterns ("*.foo" etc)
			// if we should ever need case insensitivity, use FNM_CASEFOLD as third flag
			if( fnmatch( pattern.c_str(), d->d_name, 0 ) != 0 )
				continue;
			// DG end
		}
		if( ( dironly && !( st.st_mode & S_IFDIR ) ) ||
				( !dironly && ( st.st_mode & S_IFDIR ) ) )
			continue;
			
		list.Append( d->d_name );
	}
	
	closedir( fdir );
	Mem_Free( entry );
	
	if( debug )
	{
		common->Printf( "Sys_ListFiles: %d entries in %s\n", list.Num(), directory );
	}
	
	return list.Num();
}
Пример #9
0
HTREEITEM CDialogSound::AddStrList(const char *root, const idStrList &list, int id) {
	idStr		out;

	HTREEITEM	base = treeSounds.InsertItem(root);
	HTREEITEM	item = base;
	HTREEITEM	add;

	int count = list.Num();

	idStr	last, path, path2;
	for (int i = 0; i < count; i++) {
		idStr name = list[i];

		// now break the name down convert to slashes
		name.BackSlashesToSlashes();
		name.Strip(' ');

		int index;
		int len = last.Length();
		if (len == 0) {
			index = name.Last('/');
			if (index >= 0) {
				name.Left(index, last);
			}
		}
		else if (idStr::Icmpn(last, name, len) == 0 && name.Last('/') <= len) {
			name.Right(name.Length() - len - 1, out);
			add = treeSounds.InsertItem(out, item);
			quickTree.Set(name, add);
			treeSounds.SetItemData(add, id);
			treeSounds.SetItemImage(add, 2, 2);
			continue;
		}
		else {
			last.Empty();
		}

		index = 0;
		item = base;
		path = "";
		path2 = "";
		while (index >= 0) {
			index = name.Find('/');
			if (index >= 0) {
				HTREEITEM newItem = NULL;
				HTREEITEM *check = NULL;
				name.Left( index, out );
				path += out;
				if (quickTree.Get(path, &check)) {
					newItem = *check;
				}

				//HTREEITEM newItem = FindTreeItem(&treeSounds, item, name.Left(index, out), item);
				if (newItem == NULL) {
					newItem = treeSounds.InsertItem(out, item);
					quickTree.Set(path, newItem);
					treeSounds.SetItemData(newItem, WAVEDIR);
					treeSounds.SetItemImage(newItem, 0, 1);
				}

				assert(newItem);
				item = newItem;
				name.Right( name.Length() - index - 1, out );
				name = out;
				path += "/";
			}
			else {
				add = treeSounds.InsertItem(name, item);
				treeSounds.SetItemData(add, id);
				treeSounds.SetItemImage(add, 2, 2);
				path = "";
			}
		}
	}
	return base;
}
Пример #10
0
/*
========================
idResourceContainer::Open
========================
*/
void idResourceContainer::WriteResourceFile( const char* manifestName, const idStrList& manifest, const bool& _writeManifest )
{

	if( manifest.Num() == 0 )
	{
		return;
	}
	
	idLib::Printf( "Writing resource file %s\n", manifestName );
	
	// build multiple output files at 1GB each
	idList < idStrList > outPutFiles;
	
	idFileManifest outManifest;
	int64 size = 0;
	idStrList flist;
	flist.SetGranularity( 16384 );
	for( int i = 0; i < manifest.Num(); i++ )
	{
		flist.Append( manifest[ i ] );
		size += fileSystem->GetFileLength( manifest[ i ] );
		if( size > 1024 * 1024 * 1024 )
		{
			outPutFiles.Append( flist );
			size = 0;
			flist.Clear();
		}
		outManifest.AddFile( manifest[ i ] );
	}
	
	outPutFiles.Append( flist );
	
	if( _writeManifest )
	{
		idStr temp = manifestName;
		temp.Replace( "maps/", "manifests/" );
		temp.StripFileExtension();
		temp.SetFileExtension( "manifest" );
		outManifest.WriteManifestFile( temp );
	}
	
	for( int idx = 0; idx < outPutFiles.Num(); idx++ )
	{
	
		idStrList& fileList = outPutFiles[ idx ];
		if( fileList.Num() == 0 )
		{
			continue;
		}
		
		idStr fileName = manifestName;
		if( idx > 0 )
		{
			fileName = va( "%s_%02d", manifestName, idx );
		}
		fileName.SetFileExtension( "resources" );
		
		idFile* resFile = fileSystem->OpenFileWrite( fileName );
		
		if( resFile == NULL )
		{
			idLib::Warning( "Cannot open %s for writing.\n", fileName.c_str() );
			return;
		}
		
		idLib::Printf( "Writing resource file %s\n", fileName.c_str() );
		
		int	tableOffset = 0;
		int	tableLength = 0;
		int	tableNewLength = 0;
		uint32	resourceFileMagic = RESOURCE_FILE_MAGIC;
		
		resFile->WriteBig( resourceFileMagic );
		resFile->WriteBig( tableOffset );
		resFile->WriteBig( tableLength );
		
		idList< idResourceCacheEntry > entries;
		
		entries.Resize( fileList.Num() );
		
		for( int i = 0; i < fileList.Num(); i++ )
		{
			idResourceCacheEntry ent;
			
			ent.filename = fileList[ i ];
			ent.length = 0;
			ent.offset = 0;
			
			idFile* file = fileSystem->OpenFileReadMemory( ent.filename, false );
			idFile_Memory* fm = dynamic_cast< idFile_Memory* >( file );
			if( fm == NULL )
			{
				continue;
			}
			// if the entry is uncompressed, align the file pointer to a 16 byte boundary
			// so it will be usable if memory mapped
			ent.length = fm->Length();
			
			// always get the offset, even if the file will have zero length
			ent.offset = resFile->Tell();
			
			entries.Append( ent );
			
			if( ent.length == 0 )
			{
				ent.filename = "";
				delete fm;
				continue;
			}
			
			resFile->Write( fm->GetDataPtr(), ent.length );
			
			delete fm;
			
			// pacifier every ten megs
			if( ( ent.offset + ent.length ) / 10000000 != ent.offset / 10000000 )
			{
				idLib::Printf( "." );
			}
		}
		
		idLib::Printf( "\n" );
		
		// write the table out now that we have all the files
		tableOffset = resFile->Tell();
		
		// count how many we are going to write for this platform
		int	numFileResources = entries.Num();
		
		resFile->WriteBig( numFileResources );
		
		// write the individual resource entries
		for( int i = 0; i < entries.Num(); i++ )
		{
			entries[ i ].Write( resFile );
			if( i + 1 == numFileResources )
			{
				// we just wrote out the last new entry
				tableNewLength = resFile->Tell() - tableOffset;
			}
		}
		
		// go back and write the header offsets again, now that we have file offsets and lengths
		tableLength = resFile->Tell() - tableOffset;
		resFile->Seek( 0, FS_SEEK_SET );
		resFile->WriteBig( resourceFileMagic );
		resFile->WriteBig( tableOffset );
		resFile->WriteBig( tableLength );
		delete resFile;
	}
}