Exemple #1
0
// - name should be allocated on the heap
R_API char *r_bin_filter_name(RBinFile *bf, Sdb *db, ut64 vaddr, char *name) {
	r_return_val_if_fail (db && name, NULL);

	char *resname = name;
	const char *uname = sdb_fmt ("%" PFMT64x ".%s", vaddr, resname);
	ut32 vhash = sdb_hash (uname); // vaddr hash - unique
	ut32 hash = sdb_hash (resname); // name hash - if dupped and not in unique hash must insert
	int count = sdb_num_inc (db, sdb_fmt ("%x", hash), 1, 0);

	if (sdb_exists (db, sdb_fmt ("%x", vhash))) {
		// TODO: symbol is dupped, so symbol can be removed!
		return resname;
	}
	sdb_num_set (db, sdb_fmt ("%x", vhash), 1, 0);
	if (vaddr) {
		char *p = hashify (resname, vaddr);
		if (p) {
			resname = p;
		}
	}
	if (count > 1) {
		char *p = r_str_appendf (resname, "_%d", count - 1);
		if (p) {
			resname = p;
		}

		// two symbols at different addresses and same name wtf
		//	eprintf ("Symbol '%s' dupped!\n", sym->name);
	}
	return resname;
}
Exemple #2
0
/*
================
Mod_Free
================
*/
void Mod_Free (model_t *mod)
{
	model_t		*hashstart;
	model_t		**prev;
	unsigned	hash;

	hash = hashify (mod->name) % MODEL_HASH_SIZE;
	
	prev = &models_hash[hash];
	for (;;)
	{
		hashstart = *prev;
		if (!hashstart)
			break;
		if (hashstart == mod)
		{
			*prev = hashstart->hash_next;
			break;
		}
		prev = &hashstart->hash_next;
	}

	Hunk_Free (mod->extradata);
	memset (mod, 0, sizeof(*mod));
}
Exemple #3
0
/*
==================
Mod_ForName

Loads in a model for the given name
==================
*/
model_t *Mod_ForName (const char *name_, qboolean crash)
{
	model_t		*mod;
	model_t		*modelhash;
	mscache_t	*model_size;
	byte		*buf;
	int			i;
	unsigned	hash;

	size_t len = strlen(name_);
	char *name = (char *) alloca(len + 1);
	strcpy(name, name_);

	if (!name || !name[0])
		VID_Error (ERR_DROP, "Mod_ForName: NULL name");
		
	//
	// inline models are grabbed only from worldmodel
	//
	if (name[0] == '*')
	{
		i = atoi(name+1);
		if (i < 1 || !r_worldmodel || i >= r_worldmodel->numsubmodels)
			VID_Error (ERR_DROP, "bad inline model number %d", i);
		return &mod_inline[i];
	}

	fast_strlwr (name);

	hash = hashify (name) % MODEL_HASH_SIZE;

	for (modelhash = models_hash[hash]; modelhash; modelhash = modelhash->hash_next)
	{
		if (!strcmp (modelhash->name, name))
		{
			return modelhash;
		}
	}

	for (model_size = model_size_cache[hash]; model_size; model_size = model_size->hash_next)
	{
		if (!strcmp (model_size->name, name))
			break;
	}

	//
	// search the currently loaded models
	//
	/*for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++)
	{
		if (!mod->name[0] || mod->hash != hash)
			continue;
		if (!strcmp (mod->name, name) )
			return mod;
	}*/
	
	//
	// find a free model slot spot
	//
	for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++)
	{
		if (!mod->name[0])
			break;	// free spot
	}

	if (i == mod_numknown)
	{
		if (mod_numknown == MAX_MOD_KNOWN)
			VID_Error (ERR_DROP, "mod_numknown == MAX_MOD_KNOWN");
		mod_numknown++;
	}

	strncpy (mod->name, name, sizeof(mod->name)-1);

	//
	// load the file
	//
	modfilelen = FS_LoadFile (name, (void **)&buf);
	if (!buf)
	{
		if (crash)
			VID_Error (ERR_DROP, "Mod_NumForName: %s not found", mod->name);
		mod->name[0] = 0;
		return NULL;
	}
	
	loadmodel = mod;

	//
	// fill it in
	//


	// call the apropriate loader
	
	switch (LittleLong(*(unsigned *)buf))
	{
		case IDALIASHEADER:
			if (model_size)
				loadmodel->extradata = Hunk_Begin (model_size->size, model_size->size);
			else
				loadmodel->extradata = Hunk_Begin (0x200000, 0);
			Mod_LoadAliasModel (mod, buf);
			break;
			
		case IDSPRITEHEADER:
			if (model_size)
				loadmodel->extradata = Hunk_Begin (model_size->size, model_size->size);
			else
				loadmodel->extradata = Hunk_Begin (0x4000, 0);
			Mod_LoadSpriteModel (mod, buf);
			break;
		
		case IDBSPHEADER:
			if (model_size)
				loadmodel->extradata = Hunk_Begin (model_size->size, model_size->size);
			else
				loadmodel->extradata = Hunk_Begin (0x1000000, 0);
			Mod_LoadBrushModel (mod, buf);
			break;

		default:
			VID_Error (ERR_DROP,"Mod_NumForName: unknown 0x%.8x fileid for %s", LittleLong(*(unsigned *)buf), mod->name);
			break;
	}

	if (model_size)
	{
		loadmodel->extradatasize = model_size->size;
	}
	else
	{
		loadmodel->extradatasize = Hunk_End ();

		model_size = (mscache_t	*) malloc (sizeof(*model_size));
		if (!model_size)
			VID_Error (ERR_FATAL, "Mod_ForName: out of memory");
		strcpy (model_size->name, mod->name);
		model_size->size = loadmodel->extradatasize;
		model_size->hash_next = model_size_cache[hash];

		model_size_cache[hash] = model_size;
	}

	mod->hash_next = models_hash[hash];
	models_hash[hash] = mod;

	FS_FreeFile (buf);

	return mod;
}
Exemple #4
0
int EXPORT FS_FOpenFile (const char *filename, FILE **file, handlestyle_t openHandle, qboolean *closeHandle)
{
	fscache_t		*cache;
	searchpath_t	*search;
	pack_t			*pak;
	filelink_t		*link;
	char			netpath[MAX_OSPATH];
	char			lowered[MAX_QPATH];

	// check for links firstal
	if (!fs_noextern->intvalue)
	{
		for (link = fs_links ; link ; link=link->next)
		{
			if (!strncmp (filename, link->from, link->fromlength))
			{
				Com_sprintf (netpath, sizeof(netpath), "%s%s",link->to, filename+link->fromlength);
				if (openHandle != HANDLE_NONE)
				{
					*file = fopen (netpath, "rb");
					if (*file)
					{	
						Com_DPrintf ("link file: %s\n",netpath);
						*closeHandle = true;
						return FS_filelength (*file);
					}
					return -1;
				}
				else
				{
					return Sys_FileLength (netpath);
				}
			}
		}
	}

#ifdef BTREE_SEARCH
	cache = rbfind (filename, rb);
	if (cache)
	{
		cache = *(fscache_t **)cache;
		if (cache->filepath[0] == 0)
		{
			*file = NULL;
			return -1;
		}
#ifdef _DEBUG
		Com_DPrintf ("File '%s' found in cache: %s\n", filename, cache->filepath);
#endif
		if (openHandle != HANDLE_NONE)
		{
			if (cache->pak)
			{
				if (openHandle == HANDLE_DUPE)
				{
					*file = fopen (cache->pak->filename, "rb");
					if (!*file)
					{
						Com_Printf ("WARNING: Cached pak '%s' failed to open! Did you delete it?\n", LOG_WARNING|LOG_GENERAL, cache->pak->filename);
						rbdelete (filename, rb);
						return -1;
					}
					*closeHandle = true;
				}
				else
				{
					*file = cache->pak->h.handle;
					*closeHandle = false;
				}
			}
			else
			{
				*file = fopen (cache->filepath, "rb");
				if (!*file)
				{
					Com_Printf ("WARNING: Cached file '%s' failed to open! Did you delete it?\n", LOG_WARNING|LOG_GENERAL, cache->filepath);
					rbdelete (filename, rb);
					return -1;
				}
					//Com_Error (ERR_FATAL, "Couldn't open %s (cached)", cache->filepath);	

				*closeHandle = true;
			}
			if (cache->fileseek && fseek (*file, cache->fileseek, SEEK_SET))
				Com_Error (ERR_FATAL, "Couldn't seek to offset %u in %s (cached)", cache->fileseek, cache->filepath);
		}
		return cache->filelen;
	}

#elif HASH_CACHE
	hash = hashify (filename);

	cache = &fscache;

	while (cache->next)
	{ 
		cache = cache->next;
		if (cache->hash == hash && !Q_stricmp (cache->filename, filename))
		{
			Com_Printf (" (cached) ", LOG_GENERAL);
			if (cache->filepath[0] == 0)
			{
				*file = NULL;
				return -1;
			}
			*file = fopen (cache->filepath, "rb");
			if (!*file)
				Com_Error (ERR_FATAL, "Couldn't open %s", cache->filepath);	
			fseek (*file, cache->fileseek, SEEK_SET);
			return cache->filelen;
		}
	}
#elif MAGIC_BTREE
	{
		magic_t *magic;

		hash = hashify (filename);

		magic = rbfind ((void *)hash, rb);
		if (magic)
		{
			magic = *(magic_t **)magic;

			do
			{
				cache = magic->entry;
				if (!Q_stricmp (cache->filename, filename))
				{
					if (cache->filepath[0] == 0)
					{
						*file = NULL;
						return -1;
					}
					*file = fopen (cache->filepath, "rb");
					if (!*file)
						Com_Error (ERR_FATAL, "Couldn't open %s", cache->filepath);	
					fseek (*file, cache->fileseek, SEEK_SET);
					return cache->filelen;
				}

				magic = magic->next;
			} while (magic);
		}
	}
#endif

#ifdef _DEBUG
	Com_DPrintf ("File '%s' not found in cache, searching fs_searchpaths\n", filename);
#endif

	Q_strncpy (lowered, filename, sizeof(lowered)-1);
	fast_strlwr (lowered);

	for (search = fs_searchpaths ; search ; search = search->next)
	{
		// is the element a pak file?
		if (search->pack)
		{
//			char		*lower;
			packfile_t	*entry;

			//r1: optimized btree search
			pak = search->pack;

			if (pak->type == PAK_QUAKE)
			{
				entry = rbfind (lowered, pak->rb);

				if (entry)
				{
					entry = *(packfile_t **)entry;

	#ifdef _DEBUG
					Com_DPrintf ("File '%s' found in %s, (%s)\n", filename, pak->filename, entry->name);
	#endif
					if (openHandle != HANDLE_NONE)
					{
						//*file = fopen (pak->filename, "rb");
						if (openHandle == HANDLE_DUPE)
						{
							*file = fopen (pak->filename, "rb");
							*closeHandle = true;	
						}
						else
						{
							*file = pak->h.handle;
							*closeHandle = false;
						}
						//if (!*file)
						//	Com_Error (ERR_FATAL, "Couldn't reopen pak file %s", pak->filename);	

						if (fseek (*file, entry->filepos, SEEK_SET))
							Com_Error (ERR_FATAL, "Couldn't seek to offset %u for %s in %s", entry->filepos, entry->name, pak->filename);
					}

					if (fs_cache->intvalue & 1)
					{
	#if BTREE_SEARCH
						FS_AddToCache (pak->filename, entry->filelen, entry->filepos, filename, pak);
	#elif HASH_CACHE
						FS_AddToCache (hash, pak->filename, entry->filelen, entry->filepos, cache, filename);
	#elif MAGIC_BTREE
						FS_AddToCache (pak->filename, entry->filelen, entry->filepos, filename, hash);
	#endif
					}

					return entry->filelen;
				}
			}
		}
		else if (!fs_noextern->intvalue)
		{
			struct stat	statInfo;
			int filelen;
			// check a file in the directory tree
			
			Com_sprintf (netpath, sizeof(netpath), "%s/%s",search->filename, filename);

			if (openHandle == HANDLE_NONE)
			{
				filelen = Sys_FileLength (netpath);
				if (filelen == -1)
					continue;
				
				if (fs_cache->intvalue & 4)
					FS_AddToCache (netpath, filelen, 0, filename, NULL);

				return filelen;
			}

			//fix for moronic implementations that allow fopen (FILE OPEN) to open a directory
			//(this means you linux and krew)
			if (stat (netpath, &statInfo))
				continue;

			if (statInfo.st_mode & S_IFDIR)
			{
				Com_Printf ("WARNING: Tried to open a directory as a file: %s\n", LOG_WARNING, netpath);
				continue;
			}

			*file = fopen (netpath, "rb");

			if (!*file)
				continue;

			*closeHandle = true;
			
			Com_DPrintf ("FindFile: %s\n",netpath);

			filelen = FS_filelength (*file);
			if (fs_cache->intvalue & 4)
			{
#if BTREE_SEARCH
				FS_AddToCache (netpath, filelen, 0, filename, NULL);
#elif HASH_CACHE
				FS_AddToCache (hash, netpath, filelen, 0, cache, filename);
#elif MAGIC_BTREE
				FS_AddToCache (netpath, filelen, 0, filename, hash);
#endif
			}
			return filelen;
		}
		
	}
	
	Com_DPrintf ("FindFile: can't find %s\n", filename);

	if (fs_cache->intvalue & 2)
	{
#if BTREE_SEARCH
		FS_AddToCache (NULL, 0, 0, filename, NULL);
#elif HASH_CACHE
		FS_AddToCache (hash, NULL, 0, 0, cache, filename);
#elif MAGIC_BTREE
		FS_AddToCache (NULL, 0, 0, filename, hash);
#endif
	}
	
	*file = NULL;
	return -1;
}