⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 filelist.c

📁 arj source code
💻 C
📖 第 1 页 / 共 2 页
字号:
   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 + -