📄 arj_proc.c
字号:
else if(!stricmp(arg, cmd_dc)) cmd=ARJ_CMD_DELC; else cmd=toupper(arg[0]); } } } if(cmd==ARJ_CMD_PRINT||cmd==ARJ_CMD_SAMPLE) new_stdout=stderr; if(install_errhdl) ignore_errors=1; return(cmd);}#endif#if SFX_LEVEL>=ARJSFX||defined(REARJ)/* Splits the given name to pathname and filename. On return, pathname contains ASCIIZ path specification including path terminator, filename contains ASCIIZ filename (with no preceding path terminators), and the return value is the offset of filename within the given name. */#if SFX_LEVEL>=ARJSFXV||defined(REARJ)int split_name(char *name, char *pathname, char *filename)#elseint split_name(char *name)#endif{ char *f_sep, *last_sep; int i, sep_offset; last_sep=NULL; for(i=0; path_separators[i]!='\0'; i++) { if((f_sep=strrchr(name, path_separators[i]))!=NULL) { if(last_sep==NULL||f_sep>last_sep) last_sep=f_sep; } } sep_offset=(last_sep==NULL)?0:last_sep-name+1; #if SFX_LEVEL>=ARJSFXV||defined(REARJ) if(pathname!=NULL) strcpyn(pathname, name, sep_offset+1); if(filename!=NULL) strcpy(filename, name+sep_offset); #endif return(sep_offset);}#endif#if SFX_LEVEL>=ARJSFXV/* Returns the error code for error message given */int subclass_errors(FMSG *errmsg){ if(errmsg==M_OUT_OF_MEMORY||errmsg==M_OUT_OF_NEAR_MEMORY) return(ARJ_ERL_NO_MEMORY); if(errmsg==M_HEADER_CRC_ERROR||errmsg==M_CRC_ERROR) return(ARJ_ERL_CRC_ERROR); #if SFX_LEVEL>=ARJ if(errmsg==M_DAMAGED_SEC_ARCHIVE||errmsg==M_CANT_UPDATE_SEC||errmsg==M_SKIPPING_SEC) return(ARJ_ERL_ARJSEC_ERROR); #endif if(errmsg==M_DISK_FULL) return(ARJ_ERL_DISK_FULL); if(errmsg==M_CANTOPEN) return(ARJ_ERL_CANTOPEN); if(errmsg==M_NOT_ARJ_ARCHIVE) return(ARJ_ERL_NOT_ARJ_ARCHIVE); #if SFX_LEVEL>=ARJ #if TARGET==DOS if(errmsg==M_LISTING_XMS_ERROR) return(ARJ_ERL_XMS_ERROR); #endif if(errmsg==M_TOO_MANY_CHAPTERS) return(ARJ_ERL_TOO_MANY_CHAPTERS); #endif if(errmsg==M_INVALID_SWITCH||errmsg==M_ARGTABLE_OVERFLOW||errmsg==M_NO_FILE_GIVEN|| #if SFX_LEVEL>=ARJ errmsg==M_NO_DELETE_ARG||errmsg==M_INVALID_VOL_SIZE|| errmsg==M_NO_STR_ENTERED||errmsg==M_JT_UNUSABLE|| #endif errmsg==M_NO_PWD_OPTION|| errmsg==M_MISSING_FILENAME_ARG||errmsg==M_INVALID_DATE_STRING||errmsg==M_BAD_SYNTAX) return(ARJ_ERL_USER_ERROR); return(ARJ_ERL_FATAL_ERROR);}#endif#if SFX_LEVEL>=ARJ/* Retrieves search data from string parameter given by -jq */static int get_str_from_jq(){ char *sptr, *tsptr; char *endptr; int patterns; char pt; sptr=string_parameter; if(sptr[0]!='+'&&sptr[0]!='-') error(M_INVALID_PARAM_STR, sptr); ignore_pcase=sptr[0]=='+'; fdisp_lines=(int)strtoul(sptr, &sptr, 10); patterns=0; if(*sptr!='\0') { pt=*sptr; sptr++; /* Tokenize string_parameter */ for(tsptr=sptr; *tsptr!='\0'; tsptr++) if(*tsptr==pt) *tsptr='\0'; endptr=tsptr; tsptr=sptr; while((unsigned int)tsptr<(unsigned int)endptr&&patterns<SEARCH_STR_MAX) { while(*tsptr=='\0') tsptr++; if((unsigned int)tsptr<(unsigned int)endptr) { search_str[patterns++]=tsptr; while(*tsptr!='\0'&&(unsigned int)tsptr<(unsigned int)endptr) tsptr++; } } } return(patterns);}#endif#if SFX_LEVEL>=ARJSFXV/* Performs an optimized seek operation */void file_seek(FILE *stream, long offset, int whence){ char *buffer; if(whence==SEEK_CUR&&offset>=0L&&offset<=(long)CACHE_SIZE) { buffer=malloc_msg(CACHE_SIZE); if(offset>0L) fread(buffer, 1, (int)offset, stream); free(buffer); } else fseek(stream, offset, whence);}#endif#if SFX_LEVEL>=ARJ/* Performs a search operation set-up */void search_setup(){ char entry[INPUT_LENGTH]; int patterns; if(set_string_parameter&&string_parameter[0]!='\0') patterns=get_str_from_jq(); else { ignore_pcase=query_action(REPLY_NO, QUERY_CRITICAL, M_QUERY_CASE_IGNORE); msg_cprintf(0, M_ENTER_NUM_MATCHES); read_line(entry, sizeof(entry)); fdisp_lines=strtoul(entry, NULL, 0); /* Can accept hex values */ msg_cprintf(0, M_ENTER_SEARCH_STR, SEARCH_STR_MAX); for(patterns=0; patterns<SEARCH_STR_MAX; patterns++) { msg_cprintf(0, (FMSG *)le_prompt, patterns+1); if(read_line(entry, sizeof(entry))<=0) break; search_str[patterns]=malloc_str(entry); } } if(patterns==0) error(M_NO_STR_ENTERED); while(patterns-->0) { if(ignore_pcase) strupper(search_str[patterns]); } if(fdisp_lines!=0) indicator_style=IND_NONE; reserve_size=0; search_reserve=malloc_msg(sizeof(entry)*2);}#endif#if (SFX_LEVEL>=ARJSFX)||defined(ARJDISP)/* Based on the unsigned long values given, calculates their proportion (per mille, so 42.3% is returned as 423). */int calc_percentage(unsigned long partial, unsigned long total){ int dec; for(dec=0; dec<3; dec++) { if(partial<=0x19999999) partial*=10L; else total/=10L; } if(partial+total/2<=partial) { partial/=2; total/=2; } if(total==0) return(0); else return((partial+total/2)/total);}#endif#if SFX_LEVEL>=ARJSFXV/* Performs a "smart" seeking, depending on file type (special handling is performed for text files) */void smart_seek(unsigned long position, FILE *stream){ char *tmp_buf; int fetch_size; fseek(stream, 0L, SEEK_SET); if(position>0L) { if(file_type==ARJT_BINARY) fseek(stream, position, SEEK_SET); else { tmp_buf=(char *)malloc_msg(PROC_BLOCK_SIZE); while(position>0L) { fetch_size=(int)min(position, (unsigned long)PROC_BLOCK_SIZE); if(fread(tmp_buf, 1, fetch_size, stream)!=fetch_size) error(M_SEEK_FAILED); position-=(unsigned long)fetch_size; } fseek(stream, 0L, SEEK_CUR); free(tmp_buf); } }}#endif#if SFX_LEVEL>=ARJSFX||defined(REARJ)||defined(REGISTER)/* This procedure trims the extra spaces and tabs at the left and right of line given */void alltrim(char *cmd){ int fchars; char *lpos; lpos=cmd; for(fchars=strlen(cmd)-1; fchars>=0; fchars--) { if(cmd[fchars]!='\x09'&&cmd[fchars]!=' ') break; } if(fchars>=0) { while(lpos[0]=='\x09'||lpos[0]==' ') { lpos++; fchars--; } while(fchars>=0) { (cmd++)[0]=(lpos++)[0]; fchars--; } } cmd[0]='\0';}#endif#if SFX_LEVEL>=ARJSFX/* Extracts a stored file */void unstore(int action){ char *fetch; #if SFX_LEVEL>=ARJSFXV unsigned int fetch_size; unsigned long cur_pos; #endif unsigned long bytes_written; int count; #if SFX_LEVEL>=ARJSFXV fetch=NULL; for(fetch_size=PROC_BLOCK_SIZE; fetch_size>=512; fetch_size-=512) { if((fetch=(char *)malloc(fetch_size))!=NULL) break; } if(fetch==NULL) error(M_OUT_OF_MEMORY); mem_stats(); #else fetch=dec_text; #endif display_indicator(bytes_written=0L); #if SFX_LEVEL>=ARJSFXV if(file_packing) { cur_pos=ftell(aistream); count=min(fetch_size-(cur_pos%fetch_size), compsize); } else count=min(fetch_size, compsize); #else count=min(DICSIZ, compsize); #endif while(compsize>0L) { if(file_packing) { if(fread(fetch, 1, count, aistream)!=count) error(M_CANTREAD); } else { far_memmove((char FAR *)fetch, packblock_ptr, count); packblock_ptr+=count; packmem_remain-=count; } if(file_garbled) #if SFX_LEVEL>=ARJ garble_decode_stub(fetch, count); #else garble_decode(fetch, count); #endif bytes_written+=(unsigned long)count; display_indicator(bytes_written); compsize-=(unsigned long)count; if(extraction_stub(fetch, count, action)) break; #if SFX_LEVEL>=ARJSFXV count=min(fetch_size, compsize); #else count=min(DICSIZ, compsize); #endif } #if SFX_LEVEL>=ARJSFXV free(fetch); #endif}#endif#if SFX_LEVEL>=ARJ/* Performs a "hollow" file decoding (compares the CRC if requested to do so, otherwise quits). */void hollow_decode(int action){ char *fetch; unsigned long bytes_written; unsigned long cur_pos; int count; if(action==BOP_COMPARE) { fetch=(char *)malloc_msg(PROC_BLOCK_SIZE); mem_stats(); display_indicator(bytes_written=0L); cur_pos=origsize; count=min(cur_pos, (unsigned long)PROC_BLOCK_SIZE); while(cur_pos>0L) { if(fread(fetch, 1, count, tstream)!=count) { identical_filedata=0; break; } crc32_for_block(fetch, count); bytes_written+=(unsigned long)count; display_indicator(bytes_written); cur_pos-=(unsigned long)count; count=min(PROC_BLOCK_SIZE, cur_pos); } free(fetch); }}#endif#if SFX_LEVEL>=ARJ/* Packs a memory block. The destination area must be large enough to hold an unpacked copy. */void pack_mem(struct mempack *mempack){ unsigned long s_compsize, s_origsize; int s_method, s_packing; int s_type; unsigned long c_t; s_compsize=compsize; s_origsize=origsize; s_method=method; s_packing=file_packing; s_type=file_type; origsize=mempack->origsize; compsize=0L; method=mempack->method; encblock_ptr=mempack->orig; packblock_ptr=mempack->comp+MEMPACK_OVERHEAD; encmem_remain=mempack->origsize; packmem_remain=0; unpackable=0; file_packing=0; file_type=ARJT_BINARY; if(garble_enabled) garble_init(password_modifier); crc32term=CRC_MASK; if(method==1||method==2||method==3) encode_stub(method); else if(method==4) encode_f_stub(); if(unpackable) /* Fall back to method #0 */ { encblock_ptr=mempack->orig; packblock_ptr=mempack->comp+MEMPACK_OVERHEAD; encmem_remain=mempack->origsize; method=0; if(garble_enabled) garble_init(password_modifier); crc32term=CRC_MASK; } if(method==0) store(); c_t=crc32term^CRC_MASK; mempack->comp[0]=c_t&0x000000FF; mempack->comp[1]=(c_t&0x0000FF00)>>8; mempack->comp[2]=(c_t&0x00FF0000)>>16; mempack->comp[3]=(c_t&0xFF000000)>>24; mempack->compsize=compsize+MEMPACK_OVERHEAD; mempack->method=method; file_type=s_type; file_packing=s_packing; compsize=s_compsize; origsize=s_origsize; method=s_method;}#endif#if SFX_LEVEL>=ARJSFXV/* Unpacks a memory block. The destination area must be large enough to hold an unpacked copy. */void unpack_mem(struct mempack *mempack){ unsigned long s_compsize, s_origsize; int s_method, s_packing, s_type; unsigned long c_t; s_type=file_type; s_compsize=compsize; s_origsize=origsize; s_method=method; s_packing=file_packing; file_type=ARJT_BINARY; origsize=mempack->origsize; encmem_limit=mempack->origsize; compsize=mempack->compsize-MEMPACK_OVERHEAD; method=mempack->method; encblock_ptr=mempack->orig; packblock_ptr=mempack->comp+MEMPACK_OVERHEAD; encmem_remain=0; file_packing=0; packmem_remain=mempack->compsize-MEMPACK_OVERHEAD; /* v 2.76.04+ - to allow for ARJCRYPT modules within SFXV, we reinitialize the encryption only for garbled files (was for garble_enabled until now) */ if(file_garbled) garble_init(password_modifier); crc32term=CRC_MASK; if(method==1||method==2||method==3) decode(BOP_NONE); #if SFX_LEVEL>=ARJ else if(method==4) decode_f(BOP_NONE); #endif else if(method==0) unstore(BOP_NONE); c_t=(unsigned long)((unsigned char)mempack->comp[0])+ ((unsigned long)((unsigned char)mempack->comp[1])<<8)+ ((unsigned long)((unsigned char)mempack->comp[2])<<16)+ ((unsigned long)((unsigned char)mempack->comp[3])<<24); if(c_t!=(crc32term^CRC_MASK)) error(M_CRC_ERROR); file_type=s_type; file_packing=s_packing; compsize=s_compsize; origsize=s_origsize; method=s_method;}#endif/* Strips ending LF character from the given string */#if SFX_LEVEL>=ARJSFX||defined(REGISTER)||defined(REARJ)void strip_lf(char *str){ int i; if((i=strlen(str))>0) { if(str[i-1]==LF) str[i-1]='\0'; }}#endif/* Trims leftmost spaces */#if SFX_LEVEL>=ARJ||defined(REGISTER)||defined(REARJ)char *ltrim(char *str){ char *rc; for(rc=str; *rc==' '; rc++); return(rc);}#endif#if defined(WORDS_BIGENDIAN)&&!defined(ARJDISP)&&!defined(REGISTER)/* Model-independent routine to get 2 bytes from far RAM */unsigned int mget_word(char FAR *p){ unsigned int b0, b1; b0=mget_byte(p); b1=mget_byte(p+1); return (b1<<8)|b0;}/* Model-independent routine to get 4 bytes from far RAM */unsigned long mget_dword(char FAR *p){ unsigned long w0, w1; w0=mget_word(p); w1=mget_word(p+2); return (w1<<16)|w0;}/* Model-independent routine to store 2 bytes
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -