📄 filelist.c
字号:
farfree(root->table->hcrc); if(root->table->sec_cache!=NULL&&root->table->sec_cache!=root->table->cache) farfree(root->table->sec_cache); if(root->table->cache!=NULL) farfree(root->table->cache); free(root->table); if(root->fsptr!=NULL) free(root->fsptr); } root->storage=BST_NONE;}#elif defined(REARJ) /* REARJ-only version of cleanup proc. */void flist_cleanup_proc(struct flist_root *root){ FILE_COUNT i; if(root->files>0) { for(i=0; i<root->files; i++) farfree(root->names[i]); for(i=0; i<root->d_files; i++) farfree(root->d_names[i]); farfree(root->names); farfree(root->instances); if(root->d_names!=NULL) farfree(root->d_names); if(root->checksums!=NULL) farfree(root->checksums); root->files=0; }}#endif/* Retrieves a filename with given entry code from the list. Two implemenations follow... */#ifndef SIMPLE_FLISTvoid retrieve_entry(char *dest, struct file_properties *properties, struct flist_root *root, FILE_COUNT entry){ struct idblock FAR *idblock_ptr; /* Temporary cache pointer */ struct disk_file_info FAR *dptr; int idx; /* Temporary idblock index */ int curblock; idblock_ptr=root->table->cache; /* If there are unfreed locations, do neccessary cleanup */ if(!root->table->not_allocated) cache_cleanup(root); if(root->table->hiblock<=0) { curblock=0; idblock_ptr=root->table->sec_cache; } else { for(curblock=0; curblock<=root->table->hiblock; curblock++) { if(root->table->enumerators[curblock]>entry) break; } if(curblock>0) curblock--; get_heap_block(curblock, root); } idx=idblock_ptr->sub_offset[entry-root->table->enumerators[curblock]]; dptr=(struct disk_file_info FAR *)&idblock_ptr->filler[idx]; /* Allow NULL destinations for hardlink search -- ASR fix 24/08/2001 */ if(dest!=NULL) far_strcpy((char FAR *)dest, (char FAR *)dptr->name); if(properties!=NULL) far_memmove((char FAR *)properties, (char FAR *)&dptr->file_properties, sizeof(struct file_properties));}#else/* Retrieves a filelist entry */void retrieve_entry(char *dest, struct flist_root *root, FILE_COUNT num){ #ifdef REARJ FILE_COUNT instance; #endif #ifdef REARJ instance=root->instances[num]; far_strcpy((char FAR *)dest, root->d_names[instance-1]); far_strcat((char FAR *)dest, root->names[num]); #else far_strcpy((char FAR *)dest, root->names[num]); #endif}#endif/* Adds an entry to the hash. Returns -1 if there was an error. There are two implementations of it. */#ifndef SIMPLE_FLISTint add_entry(struct flist_root *root, char *name, FILE_COUNT *count, struct file_properties *properties){ struct idblock FAR *idblock_ptr; struct disk_file_info FAR *dptr; #ifdef TILED void FAR *tmp_ptr; /* Used for heap allocation test */ #endif unsigned long tmp_crc; long tmp_offset; /* Offset to fileinfo in blocks */ int new_blocks; /* New qty of XList blocks */ int old_blocks; /* Old qty of XList blocks */ int curblock; /* Cleanup loop variable */ int index; /* Index in ID block */ FILE_COUNT tmp_files; int tmp_hiblock; int extend_len; /* Number of bytes to reserve */ if(root->files>=root->maxfiles) { #if SFX_LEVEL>=ARJSFXV msg_cprintf(0, M_NAMES_LIMIT, root->maxfiles, name); #else msg_cprintf(0, M_NAMES_LIMIT, root->maxfiles, name); #endif return(-1); } if((idblock_ptr=root->table->sec_cache)==NULL) { if(root->type!=FL_STANDARD) root->table->sec_cache=farmalloc_msg(FLIST_BLOCK_SIZE); else root->table->sec_cache=root->table->cache; idblock_ptr=root->table->sec_cache; idblock_ptr->total_entries=0; idblock_ptr->size=0; } /* ASR fix -- debug enhancement 03/10/2001 */ if(debug_enabled&&strchr(debug_opt, '.')!=NULL) msg_cprintf(0, M_TOKEN, name); /* Missing in version 2.72 *//* if(properties!=NULL&&root==&flist_main) { if(!match_attrib(properties)) { if(count!=NULL) (*count)++; return(0); } } */ if(root->type!=FL_STANDARD&&root->no_dupl) { if(find_match(root, name)) { if(count!=NULL) (*count)++; return(0); } } tmp_hiblock=root->table->hiblock; extend_len=strlen(name)+sizeof(struct file_properties); tmp_files=root->files; tmp_offset=(long)idblock_ptr->size; /* Check against limits */ if(idblock_ptr->total_entries+1>ENTRIES_PER_BLOCK||(tmp_offset+(long)extend_len+1>(long)(FLIST_BLOCK_SIZE-sizeof(struct idblock)-2))) { save_heap_block(root, (char FAR *)root->table->sec_cache); /* WARNING: compiler-dependent... */ #ifdef TILED if((tmp_ptr=farmalloc(FAR_PROBE))==NULL) { msg_cprintf(0, M_HASH_MEM_LACK, name); return(-1); } farfree(tmp_ptr); #endif /* If the far heap has overgrown its limits, relocate it to XMS ASAP */ if(root->storage==BST_FAR&&filelist_storage!=BST_NONE) { if(root->files>max_filenames||farcoreleft()<FAR_HEAP_LOWBOUND) relocate_heap(root); } root->table->block_to_flush++; tmp_hiblock++; /* Reallocate the block if it's needed */ if(tmp_hiblock+1>=root->table->xlist_blocks) { old_blocks=root->table->xlist_blocks; root->table->xlist_blocks=new_blocks=old_blocks+FLIST_BLOCK_INCREMENT; root->table->enumerators=farrealloc_msg(root->table->enumerators, (unsigned long)new_blocks*sizeof(unsigned long)); if(root->storage==BST_FAR) { root->table->far_ptrs=farrealloc_msg(root->table->far_ptrs, (unsigned long)new_blocks*sizeof(char FAR *)); /* Reset the newly created pointers to NULL */ for(curblock=old_blocks; curblock<new_blocks; curblock++) root->table->far_ptrs[curblock]=NULL; } } /* New block starts, with no file entries yet */ idblock_ptr->total_entries=0; idblock_ptr->size=0; tmp_offset=0L; root->table->hiblock=tmp_hiblock; root->table->enumerators[tmp_hiblock]=tmp_files; root->table->enumerators[tmp_hiblock+1]=FLS_END; } root->table->not_flushed=1; dptr=(struct disk_file_info FAR *)&idblock_ptr->filler[tmp_offset]; far_strcpy(dptr->name, (char FAR *)name); if(properties!=NULL) far_memmove((char FAR *)&dptr->file_properties, (char FAR *)properties, sizeof(struct file_properties)); index=tmp_files-root->table->enumerators[tmp_hiblock]; idblock_ptr->sub_offset[index]=(int)tmp_offset; idblock_ptr->size=tmp_offset+extend_len+1; idblock_ptr->total_entries++; root->files++; if(root->type!=FL_STANDARD) { crc32term=CRC_MASK; crc32_for_block(name, strlen(name)); tmp_crc=crc32term; update_hcrc(root, tmp_crc); idblock_ptr->crc[index]=(char)tmp_crc; } if(count!=NULL) (*count)++; return(0);}#else#ifdef REARJint add_entry(struct flist_root *root, char *name, FILE_COUNT *count)#elseint add_entry(struct flist_root *root, struct flist_root *search_flist, char *name, FILE_COUNT *count)#endif{ long diff; char FAR * FAR *names_ptr; int nl; char FAR *nptr; unsigned int nblocks; char FAR *checksums_ptr; FILE_COUNT nfiles; #ifdef REARJ char tmp_name[CCHMAXPATH]; char pathname[CCHMAXPATH]; int tmp_entry; FILE_COUNT dir_num; FILE_COUNT FAR *instances_ptr; #endif if(root->files>=root->maxfiles) { #if SFX_LEVEL>=ARJSFXV msg_cprintf(0, M_NAMES_LIMIT, root->maxfiles, name); #else msg_cprintf(0, M_NAMES_LIMIT, root->maxfiles, name); #endif return(-1); } #ifdef REARJ if(root->check_excl&&is_excluded(name)) return(0); tmp_entry=split_name(name, NULL, tmp_name); if(tmp_entry>0) strncpy(pathname, name, tmp_entry); pathname[tmp_entry]='\0'; dir_num=find_d_match(root, pathname); if(root->no_dupl&&dir_num!=0&&find_match(root, tmp_name, dir_num)) return(0); #else if(root->no_dupl&&find_match(root, name)) { if(count!=NULL) (*count)++; return(0); } #endif /* Separate directory storage is available in (and required by) REARJ only */ #ifdef REARJ if(dir_num==0) { if(root->d_files>=root->d_boundary) { diff=(long)root->maxfiles-root->d_files; diff=max(diff, 64L); diff+=(long)root->d_files; if((names_ptr=(char FAR * FAR *)farrealloc(root->d_names, diff*sizeof(char FAR *)))==NULL) { #if SFX_LEVEL>=ARJSFXV msg_cprintf(0, M_HASH_MEM_LACK, name); #else msg_cprintf(0, M_HASH_MEM_LACK, name); #endif return(-1); } root->d_names=names_ptr; root->d_boundary=(FILE_COUNT)diff; } nl=strlen(pathname); if((nptr=(char FAR *)farmalloc(nl+1))==NULL) { #if SFX_LEVEL>=ARJSFXV msg_cprintf(0, M_HASH_MEM_LACK, name); #else msg_cprintf(0, M_HASH_MEM_LACK, name); #endif return(-1); } root->d_names[root->d_files]=nptr; far_strcpy(nptr, (char FAR *)pathname); dir_num=++root->d_files; } #endif if(root->files>=root->boundary) { nblocks=root->maxfiles/FILES_PER_BLOCK; if(nblocks>BLOCKS_LIMIT) nblocks=BLOCKS_LIMIT; diff=(long)root->maxfiles-root->files; if((long)nblocks<diff) diff=(long)nblocks; diff+=(long)root->files; if((names_ptr=(char FAR * FAR *)farrealloc(root->names, diff*sizeof(char FAR *)))==NULL) { #if SFX_LEVEL>=ARJSFXV msg_cprintf(0, M_HASH_MEM_LACK, name); #else msg_cprintf(0, M_HASH_MEM_LACK, name); #endif return(-1); } checksums_ptr=NULL; if(root->no_dupl) { if((checksums_ptr=(char FAR *)farrealloc(root->checksums, diff*sizeof(FILE_COUNT)))==NULL) { #if SFX_LEVEL>=ARJSFXV msg_cprintf(0, M_HASH_MEM_LACK, name); #else msg_cprintf(0, M_HASH_MEM_LACK, name); #endif return(-1); } } #ifdef REARJ if((instances_ptr=(FILE_COUNT FAR *)farrealloc(root->instances, diff*sizeof(FILE_COUNT)))==NULL) { #if SFX_LEVEL>=ARJSFXV msg_cprintf(0, M_HASH_MEM_LACK, name); #else msg_cprintf(0, M_HASH_MEM_LACK, name); #endif return(-1); } #endif root->names=names_ptr; root->checksums=checksums_ptr; #ifdef REARJ root->instances=instances_ptr; #endif root->boundary=(FILE_COUNT)diff; } #ifdef REARJ nl=strlen(tmp_name); #else nl=strlen(name); #endif if((nptr=(char FAR *)farmalloc(nl+1))==NULL) { #if SFX_LEVEL>=ARJSFXV msg_cprintf(0, M_HASH_MEM_LACK, name); #else msg_cprintf(0, M_HASH_MEM_LACK, name); #endif return(-1); } nfiles=root->files; root->names[nfiles]=nptr; #ifdef REARJ far_strcpy(nptr, (char FAR *)tmp_name); #else far_strcpy(nptr, (char FAR *)name); #endif #ifdef REARJ root->instances[nfiles]=dir_num; if(root->no_dupl) root->checksums[nfiles]=checksum(tmp_name); #else if(root->no_dupl) root->checksums[nfiles]=checksum(name); #endif root->files++; if(count!=NULL) (*count)++; return(0);}#endif/* Initializes the filelist storage */#if SFX_LEVEL>=ARJvoid flist_init_proc(struct flist_root *root, FILE_COUNT maxfiles, char type)#elif defined(REARJ)void flist_init(struct flist_root *root, FILE_COUNT maxfiles, int no_dupl, int check_excl)#elsevoid flist_init(struct flist_root *root, FILE_COUNT maxfiles, char no_dupl)#endif{ #ifndef SIMPLE_FLIST int curblock, cur_entry; char *cptr; root->storage=BST_NONE; root->maxfiles=maxfiles; root->type=type; root->files=0L; root->no_dupl=0; root->fsptr=NULL; root->table=NULL; if(maxfiles==0L) return; if(root==&flist_main) hash_matches=crc_matches=0; if(debug_enabled&&strchr(debug_opt, 'v')!=NULL) msg_cprintf(0, M_SEARCH_FLAG, type); root->table=malloc_msg(sizeof(struct flist_table)); #if TARGET==DOS if(detect_xms()&&filelist_storage==BST_XMS) { root->storage=BST_XMS; get_xms_entry(); if(!xms_malloc(XMS_BLOCK_PREALLOC*FLIST_BLOCK_SIZE, root)) error(M_LISTING_XMS_ERROR, M_XMS_INIT); root->table->xms_mem_blocks=XMS_BLOCK_PREALLOC; } else #endif if(filelist_storage!=BST_NONE&&max_filenames<50) { root->storage=BST_DISK; root->table->sf_stream=NULL; } else { root->storage=BST_FAR; root->table->far_ptrs=farmalloc_msg((unsigned long)FLIST_BLOCK_INCREMENT*sizeof(void FAR *)); for(curblock=0; curblock<FLIST_BLOCK_INCREMENT; curblock++) root->table->far_ptrs[curblock]=NULL; } root->table->cache=farmalloc_msg(FLIST_BLOCK_SIZE); root->table->sec_cache=NULL; root->table->block=-1; root->table->block_to_flush=0; root->table->low_block=0; root->table->not_flushed=0; root->table->not_allocated=0; root->table->xlist_blocks=FLIST_BLOCK_INCREMENT; root->table->enumerators=farmalloc_msg((unsigned long)FLIST_BLOCK_INCREMENT*sizeof(FILE_COUNT)); root->table->enumerators[0]=0; root->table->enumerators[1]=FLS_END; root->table->hiblock=0; root->table->hcrc=NULL; flist_capacity=FILELIST_CAPACITY; if(debug_enabled&&(cptr=strchr(debug_opt, 'z'))!=NULL) flist_capacity=(FILE_COUNT)strtol(cptr, &cptr, 10); if(root->type!=FL_STANDARD) { root->table->hcrc=farmalloc_msg((FILE_COUNT)flist_capacity); for(cur_entry=0; cur_entry<flist_capacity; cur_entry++) root->table->hcrc[cur_entry]=0; } #else root->maxfiles=maxfiles; root->no_dupl=(int)no_dupl; root->files=0; root->boundary=0; root->checksums=NULL; root->names=NULL; #ifdef REARJ root->check_excl=check_excl; root->d_files=0; root->d_boundary=0; root->d_names=NULL; root->instances=NULL; #endif #endif}#if SFX_LEVEL>=ARJ&&TARGET==UNIX/* [Hard]link search routine. Either returns a pointer to an existing entry in l_search structure, or creates a new entry. May operate with symlinks too (e.g. elimination of circular links) */FILE_COUNT link_search(struct l_entries *entries, struct l_search *l_search, struct file_properties *properties, FILE_COUNT ref){ FILE_COUNT i; for(i=0; i<entries->total; i++) { /* The refcount values are not compared, since these may vary */ if(!far_memcmp(&l_search->dev, (void FAR *)&entries->list[i].dev, sizeof(dev_t))&& l_search->inode==entries->list[i].inode) { if(properties!=NULL) { properties->islink=1; properties->l_search.ref=entries->list[i].ref; properties->type=ARJT_UXSPECIAL; properties->fsize=0L; } return(i); } } if(entries->total>=entries->alloc) { entries->alloc+=L_ENTRIES_INCREMENT; entries->list=(struct l_search FAR *)farrealloc_msg(entries->list, entries->alloc*sizeof(struct l_search)); } entries->list[i]=*l_search; entries->list[i].ref=ref; entries->total++; return(FLS_NONE);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -