📄 arj_proc.c
字号:
} } return(match);}/* Returns the exact amount of data that could be safely written to the destination volume */unsigned int get_volfree(unsigned int increment){ unsigned long pvol; unsigned int arjsec_overhead; long remain; if(increment==0||volume_flag_set) { volume_flag_set=1; return(0); } pvol=0L; if(arjprot_tail) pvol=calc_protdata_size(volume_limit, prot_blocks); else if(protfile_option) pvol=calc_protdata_size(volume_limit, protfile_option); arjsec_overhead=sign_with_arjsec?ARJSEC_SIG_MAXLEN+1:0; remain=volume_limit-ftell(aostream)-pvol-(long)arjsec_overhead- (long)out_bytes-(long)cpos-(long)ext_voldata- MULTIVOLUME_RESERVE-t_volume_offset; return((unsigned int)min(remain, (unsigned long)increment));}/* Performs various checks when multivolume data is packed to predict an overrun. Returns number of bytes that could be successfully written. */unsigned int check_multivolume(unsigned int increment){ unsigned long pvol; unsigned int arjsec_overhead; long remain; unsigned int inc, rc; if(!file_packing) return(increment); if(increment==0||volume_flag_set) { volume_flag_set=1; return(0); } pvol=0L; if(protfile_option) pvol=calc_protdata_size(volume_limit, protfile_option); arjsec_overhead=sign_with_arjsec?ARJSEC_SIG_MAXLEN+1:0; /* Split this expression to work around High C bugs -- ASR 14/08/2001 */ remain=volume_limit-ftell(aostream)-pvol-(long)arjsec_overhead; stop_optimizer(); remain-=(long)out_bytes+(long)cpos+(long)ext_voldata; stop_optimizer(); remain-=(long)MULTIVOLUME_RESERVE+(long)t_volume_offset; /* Now decrement the buffer size until we fit the remainder */ while((long)bufsiz*2L>remain&&bufsiz>MIN_CRITICAL_BUFSIZ) bufsiz>>=1; if(bufsiz<MIN_CRITICAL_BUFSIZ) bufsiz=MIN_CRITICAL_BUFSIZ; if((long)increment+1000L<remain&&(long)increment*2L<remain) return(increment); inc=0; if((long)increment<remain) inc=increment; else if(remain>0) inc=remain; if(inc<=0) { volume_flag_set=1; return(0); } if((long)increment*2L>remain) { if(inc>1000) rc=(inc-inc%500)>>1; else if(inc>2000) rc=inc-1000; else rc=(inc>512)?inc>>1:inc; } /* Mistrust the return value. That would help to get around certain compiler optimization bugs (as with OpenWatcom v 1.1RC) - at least the wrong value won't be passed to fread() causing buffer overrun. */ return(min(rc, increment));}/* Compares the extension from pad with the file's extension. Returns 1 if there was a match. */static int compare_exts(char *name, char *pad){ int k; /* si = name, di = pad */ if(strlen(pad)==1&&strchr(name, '.')==NULL) return(1); k=strlen(name)-strlen(pad); if(k<0) return(0); else return(strcmp_os(name+k, pad)==0);}/* "Stores" a file by simply copying it */void store(){ int fetch_size; unsigned int mem_size; char *fetch; int to_read; fetch=(char *)malloc_msg(PROC_BLOCK_SIZE); mem_stats(); origsize=0L; cpos=0; ext_voldata=0; display_indicator(0L); crc32term=CRC_MASK; to_read=PROC_BLOCK_SIZE; if(multivolume_option&&file_packing) to_read=check_multivolume(to_read); if(file_packing) { while((fetch_size=fread_crc(fetch, to_read, encstream))>0) { if(garble_enabled) garble_encode_stub(fetch, fetch_size); if(!no_file_activity) { file_write(fetch, 1, fetch_size, aostream); } display_indicator(origsize); if(multivolume_option) to_read=check_multivolume(to_read); } } else { while(encmem_remain!=0) { mem_size=min((unsigned int)PROC_BLOCK_SIZE, encmem_remain); far_memmove((char FAR *)fetch, encblock_ptr, mem_size); crc32_for_block(fetch, mem_size); if(garble_enabled) garble_encode_stub(fetch, mem_size); far_memmove(packblock_ptr, (char FAR *)fetch, mem_size); encblock_ptr+=mem_size; packblock_ptr+=mem_size; origsize+=mem_size; encmem_remain-=mem_size; /* Changed this order. This is an ASR fix for High C beta -- 05/04/2001 */ } } free(fetch); compsize=origsize;}/* Performs a "hollow" file processing (just calculates the CRC) */void hollow_encode(){ int fetch_size; char *fetch; fetch=(char *)malloc_msg(PROC_BLOCK_SIZE); mem_stats(); origsize=0L; out_bytes=0; cpos=0; ext_voldata=0; display_indicator(0L); crc32term=CRC_MASK; fetch_size=PROC_BLOCK_SIZE; while(fread_crc(fetch, fetch_size, encstream)!=0) display_indicator(origsize); free(fetch); compsize=0L;}#endif#if SFX_LEVEL>=ARJ||defined(REARJ)/* Retrieves a pair of decimal digits from the given pointer */static int get_dec_pair(char *str){ if(str[0]=='\0') return(0); if(str[1]=='\0') return((int)str[0]-'0'); return((int)(str[0]-'0')*10+(int)(str[1]-'0'));}/* Converts the given time string ("yyyymmddhhmmss") to the internal timestamp format */void convert_strtime(struct timestamp *dest, char *str){ char tmp_strtime[30]; int y, m, d, hh, mm, ss; /* Timestamp components */ strncpy(tmp_strtime, str, 14); tmp_strtime[14]='\0'; strcat(tmp_strtime, strtime_filler); y=get_dec_pair(tmp_strtime); if(y>=19&&y<80) { y=y*100+get_dec_pair(tmp_strtime+2); m=get_dec_pair(tmp_strtime+4); d=get_dec_pair(tmp_strtime+6); hh=get_dec_pair(tmp_strtime+8); mm=get_dec_pair(tmp_strtime+10); ss=get_dec_pair(tmp_strtime+12); } else { m=get_dec_pair(tmp_strtime+2); d=get_dec_pair(tmp_strtime+4); hh=get_dec_pair(tmp_strtime+6); mm=get_dec_pair(tmp_strtime+8); ss=get_dec_pair(tmp_strtime+10); y+=(y>=80)?1900:2000; } if(m<1||m>12||d<1||d>31||hh>23||mm>59||ss>59) error(M_INVALID_DATE_STRING, str); make_timestamp(dest, y, m, d, hh, mm, ss);}#endif#if SFX_LEVEL>=ARJSFXV||defined(REARJ)/* Checks integrity of the executable file */int check_integrity(char *name){ #if SFX_LEVEL>=ARJ char *buf; int f_len=PROC_BLOCK_SIZE; #else char buf[CACHE_SIZE]; int f_len=CACHE_SIZE; #endif FILE *stream; int p_len; int fetch, i; int c; char *bptr; unsigned long wr_pos; unsigned long fsize, cur_pos; char pattern[20]; unsigned long st_crc, st_fsize; /* Stored parameters */ #if SFX_LEVEL>=ARJ buf=(char *)malloc_msg(f_len); #endif stream=file_open(name, m_rb); if(stream==NULL) { msg_cprintf(H_ERR, M_CANTOPEN, name); #if SFX_LEVEL>=ARJ nputlf(); return(0); #else return(1); #endif } strcpy(pattern, (char *)integrity_pattern); pattern[0]--; p_len=strlen(pattern); fseek(stream, 0L, SEEK_END); fsize=ftell(stream); fseek(stream, 0L, SEEK_SET); crc32term=CRC_MASK; cur_pos=0L; while(1) { fseek(stream, cur_pos, SEEK_SET); fetch=fread(buf, 1, f_len, stream); if(fetch==0) #if SFX_LEVEL>=ARJSFXV error(M_CANTREAD); #else pause_error(M_NO_INTEGRITY_PATTERN); #endif fetch-=p_len; bptr=buf; for(i=0; i<fetch; i++) { if(!memcmp(bptr, pattern, p_len)) break; bptr++; } if(i<fetch) break; cur_pos+=f_len/2; /* Dirty hack */ } wr_pos=(long)i+cur_pos+p_len; fseek(stream, wr_pos, SEEK_SET); if(fread(&st_crc, 1, 4, stream)!=4) #if SFX_LEVEL>=ARJSFXV error(M_CANTREAD); #else pause_error(M_NO_INTEGRITY_PATTERN); #endif if(fread(&st_fsize, 1, 4, stream)!=4) #if SFX_LEVEL>=ARJSFXV error(M_CANTREAD); #else pause_error(M_NO_INTEGRITY_PATTERN); #endif #ifdef WORDS_BIGENDIAN /* Another dirty hack */ st_crc = mget_dword((char*) &st_crc); st_fsize = mget_dword((char*) &st_fsize); #endif crc32term=CRC_MASK; fseek(stream, 0L, SEEK_SET); for(cur_pos=0L; cur_pos<wr_pos; cur_pos++) { if((c=fgetc(stream))==-1) #if SFX_LEVEL>=ARJSFXV error(M_CANTREAD); #else pause_error(M_NO_INTEGRITY_PATTERN); #endif crc32term=crc32_for_char(crc32term, (unsigned char)c); } cur_pos+=8L; fseek(stream, cur_pos, SEEK_SET); while(cur_pos<fsize) { if((c=fgetc(stream))==-1) #if SFX_LEVEL>=ARJSFXV error(M_CANTREAD); #else pause_error(M_NO_INTEGRITY_PATTERN); #endif crc32term=crc32_for_char(crc32term, (unsigned char)c); cur_pos++; } fsize+=2L; #if SFX_LEVEL>=ARJ free(buf); #endif fclose(stream); #if SFX_LEVEL>=ARJSFXV return(crc32term==st_crc&&fsize==st_fsize); #else if(crc32term==st_crc&&fsize==st_fsize) msg_cprintf(0, M_INTEGRITY_OK); else pause_error(M_INTEGRITY_VIOLATED); return(0); #endif}#endif/* Converts a filename to the format used in current OS (simply substitutes the UNIX separators with DOS ones) */void name_to_hdr(char *name){ int i; for(i=0; name[i]!='\0'; i++) { if(name[i]==PATHSEP_UNIX) name[i]=PATHSEP_DEFAULT; }}#if SFX_LEVEL>=ARJSFXV/* Formats the given filename to look properly in the "Adding..." and other messages. */char *format_filename(char *name){ int f_pos, tf_pos; char *result; int ctr; /* Path delimiter counter */ int len; static char name_holder[FNAME_FLEN+1]; int i; if(show_filenames_only) f_pos=split_name(name, NULL, NULL); else f_pos=0; tf_pos=f_pos; ctr=1; while(name[tf_pos]!='\0') { if(tf_pos>0&&name[tf_pos]==PATHSEP_DEFAULT) ctr++; tf_pos++; } len=ctr*CCHMAXPATH+ctr; if(len>FNAME_FLEN-1) len=FNAME_FLEN-1; result=&name[f_pos]; if(strlen(result)<len) { strcpy(name_holder, result); for(i=strlen(name_holder); i<len; i++) strcat(name_holder, " "); result=name_holder; } return(result);}#endif#if SFX_LEVEL>=ARJ/* Parses the given argument to a file attribute bitmap */static void parse_attrs(char *str){ char *sptr, *attrptr; char *g_attr; char c; int attrno; file_attr_mask=TAG_FILES; if(*str=='\0') file_attr_mask=TAG_RDONLY|TAG_SYSTEM|TAG_HIDDEN|TAG_DIREC|TAG_LABEL| TAG_CHAPTER|TAG_NORMAL|TAG_WINLFN; else { sptr=str; attrptr=allowed_attrs; while((c=*sptr++)!='\0') { c=toupper(c); if((g_attr=strchr(attrptr, c))==NULL) error(M_INVALID_SWITCH, str); attrno=g_attr-attrptr-1; if(attrno>=0) file_attr_mask|=1<<attrno; else if(attrno==-1) file_attr_mask=TAG_RDONLY|TAG_SYSTEM|TAG_HIDDEN|TAG_DIREC|TAG_NORMAL; } if((file_attr_mask|(TAG_ARCH|TAG_NOT_ARCH))==(TAG_ARCH|TAG_NOT_ARCH)) file_attr_mask|=TAG_RDONLY|TAG_SYSTEM|TAG_HIDDEN|TAG_DIREC|TAG_NORMAL; }}/* Returns real size in bytes for diskette size shortcuts (i.e., 360, 720, and so on...) */static unsigned long select_preset_size(unsigned long rsize){ if(rsize==360) return(362000L); else if(rsize==720) return(730000L); else if(rsize==1200) return(1213000L); else if(rsize==1440) return(1457000L); return(rsize);}#endif#if SFX_LEVEL>=ARJSFXV/* Returns 1 if the switch has a "tail" of extra dataa */static int get_switch_state(char *sw){ if(sw[0]=='\0') return(0); if((sw[0]=='+'||sw[0]=='-')&&sw[1]=='\0') return(0); return(1);}/* Parses query list given by -jy for ARJ and -y for ARJSFX */static void parse_yes_queries(char *sw){ char *swptr; unsigned int c; int **index; FMSG *table; FMSG *entry; int num; swptr=sw; while((c=(unsigned int)*(swptr++))!='\0') { c=toupper(c); index=jysw_index; table=M_JYSW_TABLE; if((entry=msg_strchr(table, (char)c))==NULL) error(M_INVALID_SWITCH, sw); num=entry-table; if(*swptr=='+') { *index[num]=1; swptr++; } else if(*swptr=='-') { *index[num]=0; swptr++; } *index[num]=!*index[num]; }}#endif#if SFX_LEVEL>=ARJ&&TARGET==UNIX/* Disables/enables archiving for a particular block device */static void add_blkdev_spec(char *swptr){ int is_excl=0; char *fnm; if(swptr[0]=='-') { is_excl=1; swptr++; } else if(swptr[0]=='+') swptr++; fnm=(swptr[0]=='\0')?".":swptr; set_dev_mode(is_excl); if(add_dev(fnm)) msg_cprintf(H_ALERT, M_BAD_DEV_SPEC, fnm);}#endif#if SFX_LEVEL>=ARJSFXJR/* Sets internal variables depending on the switch given */void analyze_arg(char *sw){ char *swptr; unsigned int c; FMSG *entry; int num; /* Switch number within the table */ #if SFX_LEVEL>=ARJSFXV int done; FMSG *table; FMSG *params; int **index; char lim; int sw_tail; #endif #if SFX_LEVEL>=ARJ int type; char vol_sw; /* -v... subswitch storage */ int p_len; char *p_ptr; unsigned long cnv_num; #endif swptr=sw; if(swptr[0]==swptr[1]&&swptr[2]=='\0') skip_switch_processing=1; else { swptr++; #if SFX_LEVEL>=ARJ
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -