// - 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; }
/* ================ 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)); }
/* ================== 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; }
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; }