📄 arj_user.c
字号:
/* * $Id: arj_user.c,v 1.9 2003/06/27 18:58:35 andrew_belov Exp $ * --------------------------------------------------------------------------- * High-level routines that perform ARJ command processing are located in this * module. It may be partially inherited by ARJSFXV and ARJSFX. * */#include "arj.h"DEBUGHDR(__FILE__) /* Debug information block *//* Operating system names used in short listings. For their numerical equivalents see ARJ_USER.H. */static char *host_os_names[]={"MS-DOS", "PRIMOS", "UNIX", "AMIGA", "MAC-OS", "OS/2", "APPLE GS", "ATARI ST", "NEXT", "VAX VMS", "WIN95", "WIN32", NULL};/* Binary/Text/... - type signature */#if SFX_LEVEL>=ARJSFXVstatic char type_sig[]={'B', 'T', '?', 'D', 'V', 'C', 'U'};#elsestatic char type_sig[]={'B', 'T', '?', 'D'};#endif/* Combined volume/extfile flags for UNIX-mode lists */#if TARGET==UNIX&&SFX_LEVEL>=ARJSFXVstatic char vfext_flags[]={' ', '>', '<', '*'};#endif/* List order */#if SFX_LEVEL>=ARJSFXV #if TARGET==UNIX #define LFLAGS is_chapter?'*':' ', is_in_subdir?'+':' ', method, enc_type, vfext_flags[(is_volume?1:0)+(is_extfile?2:0)] #else #define LFLAGS is_chapter?'*':' ', type_sig[uf_type], is_in_subdir?'+':' ', method, enc_type, is_volume?'V':' ', is_extfile?'X':' ' #endif#else #if TARGET==UNIX #define LFLAGS is_in_subdir?'+':' ', method, enc_type #else #define LFLAGS type_sig[uf_type], is_in_subdir?'+':' ', method, enc_type #endif#endif#if TARGET!=UNIX #define LMODESTR file_crc, mode_str#else #define LMODESTR mode_str#endif/* Y2K mess */#if SFX_LEVEL>=ARJSFXVstatic char century_sig[]={' ', ' ', '1'}; /* 20th/21st/22nd centuries */#endif/* Misc. */static char volfmt_2digit[]="%s%02d";static char volfmt_3digit[]="%s%03d";static char volfmt_4digit[]="%s%4d";static char stub_fmt[]="%s%03d%s";static char bell[]="\a";/* Local variables */static FILE_COUNT total_processed; /* Number of already processed files */static unsigned long FAR *order_list; /* List of files to order */#if SFX_LEVEL>=ARJstatic FILE_COUNT cf_num; /* Current file # */#endifstatic FILE_COUNT order_fcap; /* Size of order array */static FILE_COUNT order_fcount; /* # of files in order array */static FILE_COUNT vol_file_num;static unsigned long saved_timestamp;#if SFX_LEVEL>=ARJstatic char *arjsec_signature;#elsestatic char arjsec_signature[ARJSEC_SIG_MAXLEN];#endifstatic unsigned long first_file_offset; /* Offset of first file within arch. */#if SFX_LEVEL>=ARJSFXVstatic int total_os;static int is_removable; /* 1 if the current archive is on a removable media */#endif/* Since ARJSFX has totally static allocation, the cache buffers are statically allocated, too */#if SFX_LEVEL<=ARJSFX&&!defined(NO_CACHING)static char cache_buf[VBUF_SFX];#endif/* Return 1 if the given system is similar to ARJ host OS */int test_host_os(int os){ int i; for(i=0; friendly_systems[i]>=0; i++) { if(friendly_systems[i]==os) return(1); } return(0);}#if SFX_LEVEL>=ARJ/* Allocates RAM for and composes the protection filename */char *form_prot_name(){ int name_len; char *result; /* Address of newly-formed buffer */ char *tmp_ptr; name_len=strlen(archive_name)+far_strlen(M_PROT_SUFFIX)+2; strcpy(result=malloc_msg(name_len), archive_name); name_len=split_name(result, NULL, NULL); if((tmp_ptr=strchr(&result[name_len], '.'))==NULL) msg_strcat(result, M_PROT_SUFFIX); else if(tmp_ptr[1]=='\0') msg_strcat(result, M_PROT_SUFFIX); else tmp_ptr[1]=M_PROT_SUFFIX[1]; /* Substitute first letter of extension with the one from prot_name suffix */ return(result);}#endif#if SFX_LEVEL>=ARJSFXV/* Checks for the occurence of the destination file, returns 1 if the file can be extracted, 0 if it already exists and must be skipped */int destfile_extr_validation(){ char tmp_name[FILENAME_MAX]; if(!new_files_only) return(1); strcpy(tmp_name, filename); add_base_dir(tmp_name); return(!file_exists(tmp_name));}#endif#if SFX_LEVEL>=ARJ/* Writes an index file entry */void write_index_entry(char *prefix){ int bytes_written; if(create_index) { if(prefix[0]=='\0') bytes_written=msg_fprintf(idxstream, M_IDXFMT_NP, filename); else bytes_written=msg_fprintf(idxstream, (strlen(prefix)>3)?M_IDXFMT_LONG:M_IDXFMT_SHORT, prefix, filename); if(bytes_written==0) error(M_DISK_FULL); }}#endif/* Outputs the listing header */static void show_list_header(){ #if SFX_LEVEL>=ARJ if(std_list_cmd) { if(verbose_display==VERBOSE_STD) return; if(verbose_display==VERBOSE_ENH) msg_cprintf(0, M_VLIST_P1); else { msg_cprintf(0, M_VLIST_HDR); msg_cprintf(0, M_VLIST_P1); } } else msg_cprintf(0, M_LIST_P1); msg_cprintf(0, verbose_display?M_LIST_P2_CHAP:M_LIST_P2); #else if(std_list_cmd) { msg_cprintf(0, M_VLIST_HDR); msg_cprintf(0, M_VLIST_P1); } else msg_cprintf(0, M_LIST_P1); msg_cprintf(0, M_LIST_P2); #endif msg_cprintf(0, M_LIST_SEPARATOR);}/* Picks the most favorable century character */#if SFX_LEVEL>=ARJSFXVstatic char pick_century(char *timetext){ int n_centuries; #if SFX_LEVEL>=ARJ switch(skip_century) { case CENT_DEFAULT: if(timetext[0]=='2'&&timetext[1]=='0') n_centuries=1; else if(timetext[0]=='2'&&timetext[1]=='1') n_centuries=2; else n_centuries=0; return(century_sig[n_centuries]); case CENT_SKIP: return(' '); case CENT_SMART: if(timetext[0]=='1'||timetext[0]=='2'&&timetext[1]=='0'&&timetext[2]<'7') return(' '); else return(timetext[1]); } return(' '); #elif SFX_LEVEL>=ARJSFXV if(timetext[0]=='2'&&timetext[1]=='0') n_centuries=1; else if(timetext[0]=='2'&&timetext[1]=='1') n_centuries=2; else n_centuries=0; return(century_sig[n_centuries]); #endif}#endif/* List command itself */#if SFX_LEVEL>=ARJSFXVstatic int list_cmd(FILE_COUNT lnum, FILE_COUNT fnum)#elsestatic void list_cmd()#endif{ int is_in_subdir; #if SFX_LEVEL>=ARJSFXV int is_volume, is_extfile; int is_chapter; /* Chapter or backup */ char FAR *raw_ea; unsigned int raw_ea_size; struct ext_hdr FAR *p_eh; #endif #if SFX_LEVEL>=ARJ char tmp_name[FILENAME_MAX]; #endif int uf_type; unsigned int ratio; unsigned int entry; char timetext[22]; char mode_str[16]; /* ASR fix for 2.77 */ char *tmp_ptr; /* Either from the host_os_names list or nullstr */ char enc_type; #if SFX_LEVEL>=ARJSFXV if(!destfile_extr_validation()) return(0); #endif #if SFX_LEVEL>=ARJSFXV if(lnum==0) show_list_header(); #else if(total_files==0) show_list_header(); #endif #if SFX_LEVEL>=ARJ for(total_os=0; host_os_names[total_os]!=NULL; total_os++); #endif enc_type=(arj_flags&GARBLED_FLAG)?ext_hdr_flags+'0':' '; #if SFX_LEVEL>=ARJSFXV is_volume=(arj_flags&VOLUME_FLAG)?1:0; is_extfile=(arj_flags&EXTFILE_FLAG)?1:0; #endif #if SFX_LEVEL>=ARJ is_chapter=(total_chapters!=0&&((int)chapter_number<total_chapters||(int)ext_flags>total_chapters))?1:0; #elif SFX_LEVEL==ARJSFXV is_chapter=(arj_flags&BACKUP_FLAG)?1:0; #endif is_in_subdir=entry_pos>0; ratio=calc_percentage(compsize, origsize); total_uncompressed+=origsize; total_compressed+=compsize; #if SFX_LEVEL>=ARJSFXV if(chk_free_space) disk_space_used+=((origsize+(unsigned long)alloc_unit_size-1L)/(unsigned long)alloc_unit_size)*(unsigned long)alloc_unit_size; #endif timestamp_to_str(timetext, &ftime_stamp); #if SFX_LEVEL>=ARJ uf_type=(file_type==ARJT_BINARY||file_type==ARJT_TEXT||file_type==ARJT_DIR||file_type==ARJT_UXSPECIAL||file_type==ARJT_LABEL||file_type==ARJT_CHAPTER)?file_type:ARJT_COMMENT; #elif SFX_LEVEL==ARJSFXV uf_type=(file_type==ARJT_BINARY||file_type==ARJT_TEXT||file_type==ARJT_DIR||file_type==ARJT_UXSPECIAL||file_type==ARJT_LABEL)?file_type:ARJT_DIR; #else uf_type=(file_type==ARJT_BINARY||file_type==ARJT_TEXT||file_type==ARJT_DIR)?file_type:ARJT_DIR; #endif /* In ARJSFX, there are no non-host OSes */ #if SFX_LEVEL<=ARJSFX mode_str[0]='\0'; #else msg_strcpy(mode_str, M_EMPTY_ATTR); #endif if(test_host_os(host_os)) { get_mode_str(mode_str, file_mode.native); #if TARGET==UNIX if(file_type==ARJT_BINARY||file_type==ARJT_TEXT) mode_str[0]='-'; else mode_str[0]=tolower(type_sig[uf_type]); #endif } #if SFX_LEVEL>=ARJ strcpy(tmp_name, filename); if((uf_type==ARJT_BINARY||uf_type==ARJT_TEXT||uf_type==ARJT_DIR||file_type==ARJT_UXSPECIAL)&&(host_os==OS_WIN95||host_os==OS_WINNT)) { total_longnames++; if(volume_flag_set) split_longnames++; } #endif if(std_list_cmd) { #if SFX_LEVEL>=ARJSFXV #if SFX_LEVEL>=ARJ if(verbose_display!=VERBOSE_ENH) { if(verbose_display==VERBOSE_NONE) { #endif msg_cprintf(H_HL, M_LIST_NUM_FMT, fnum); #if SFX_LEVEL>=ARJ } #endif #if SFX_LEVEL>=ARJ entry=(exclude_paths==EP_PATH)?(unsigned int)entry_pos:0; msg_cprintf(H_HL, M_FILENAME_FORM, tmp_name+entry); #else entry=0; msg_cprintf(H_HL, M_FILENAME_FORM, filename); #endif #if SFX_LEVEL>=ARJ if(verbose_display==VERBOSE_STD) return(1); #endif if(comment[0]!='\0') { display_comment(comment); #if SFX_LEVEL>=ARJ msg_cprintf(0, (FMSG *)lf); #endif } #if SFX_LEVEL>=ARJ if(ext_flags!=0) msg_cprintf(H_HL|H_NFMT, M_CHAPTER_LIST_FMT, (int)ext_flags, (int)chapter_number); #endif #if SFX_LEVEL>=ARJ } #endif tmp_ptr=((int)host_os>=total_os)?nullstr:host_os_names[host_os]; msg_cprintf(H_HL|H_NFMT, M_REV_OS_FMT, (int)arj_nbr, tmp_ptr); #else msg_cprintf(H_HL, M_VERBOSE_NAME_FMT, filename); if(comment[0]!='\0') { if(show_ansi_comments) printf(strform, comment); else display_comment(comment); } msg_cprintf(H_HL|H_NFMT, M_REV_OS_FMT, (int)arj_nbr, host_os_names[host_os]); #endif } else #if SFX_LEVEL>=ARJ msg_cprintf(0, (strlen(tmp_name+entry_pos)>12)?M_LONG_NAME_FMT:M_SHORT_NAME_FMT, tmp_name+entry_pos); #elif SFX_LEVEL>=ARJSFXV msg_cprintf(0, (strlen(filename+entry_pos)>12)?M_LONG_NAME_FMT:M_SHORT_NAME_FMT, filename+entry_pos); #else msg_cprintf(0, (strlen(list_adapted_name)>12)?M_LONG_NAME_FMT:M_SHORT_NAME_FMT, list_adapted_name); #endif#if SFX_LEVEL>=ARJ if(verbose_display) msg_cprintf(H_HL|H_NFMT, M_VERBOSE_LIST_LINE, origsize, compsize, ratio/1000, ratio%1000, pick_century(timetext), timetext+2, (int)ext_flags, (int)chapter_number, mode_str, LFLAGS); else#endif #if SFX_LEVEL>=ARJSFXV msg_cprintf(H_HL|H_NFMT, M_STD_LIST_LINE, origsize, compsize, ratio/1000, ratio%1000, pick_century(timetext), timetext+2, LMODESTR, LFLAGS); #else msg_cprintf(H_HL|H_NFMT, M_STD_LIST_LINE, origsize, compsize, ratio/1000, ratio%1000, timetext+2, LMODESTR, LFLAGS); #endif #if SFX_LEVEL>=ARJ if(std_list_cmd&&verbose_display==VERBOSE_ENH) { if((tmp_ptr=strrchr(tmp_name, '.'))==NULL) tmp_ptr=nullstr; msg_cprintf(H_HL|H_NFMT, M_PATH_LIST_FMT, tmp_ptr, tmp_name+entry_pos, filename); } msg_cprintf(0, (FMSG *)lf); if(std_list_cmd&&ts_valid(atime_stamp)&&verbose_display!=VERBOSE_ENH) { timestamp_to_str(timetext, &atime_stamp); msg_cprintf(H_HL|H_NFMT, M_ATIME_FMT, pick_century(timetext), timetext+2); timestamp_to_str(timetext, &ctime_stamp); msg_cprintf(H_HL|H_NFMT, M_CTIME_FMT, pick_century(timetext), timetext+2); } /* Report the extended headers */ if(std_list_cmd&&valid_ext_hdr&&!(arj_flags&VOLUME_FLAG)&&verbose_display!=VERBOSE_ENH) { /* UNIX special files */ if((p_eh=eh_lookup(eh, UXSPECIAL_ID))!=NULL) uxspecial_stats(p_eh->raw, UXSTATS_LONG); /* Owner (character) */ if((p_eh=eh_lookup(eh, OWNER_ID))!=NULL) owner_stats(p_eh->raw, 1); /* Owner (UID/GID). The archiving won't allow simultaneous storage of both numeric and character IDs */ if((p_eh=eh_lookup(eh, OWNER_ID_NUM))!=NULL) owner_stats(p_eh->raw, 0); /* EAs */ if((p_eh=eh_lookup(eh, EA_ID))!=NULL&&(!file_garbled||garble_enabled)) { raw_ea=unpack_ea(p_eh); raw_ea_size=get_eablk_size(raw_ea); ratio=calc_percentage((unsigned long)p_eh->size, (unsigned long)raw_ea_size); msg_cprintf(H_HL|H_NFMT, M_EA_LIST, raw_ea_size, p_eh->size, ratio/1000, ratio%1000, get_num_eas(raw_ea)); farfree(raw_ea); } } write_index_entry(nullstr); #else #if SFX_LEVEL>=ARJSFXV msg_cprintf(0, (FMSG *)lf); #endif #endif #if SFX_LEVEL>=ARJSFXV return(1); #endif}/* A simplified set of filelist routines */#if SFX_LEVEL<=ARJSFX/* Looks for the given fully-qualified filename in the file argument array */static int f_arg_lookup(char *name){ int i; for(i=0; i<sflist_args; i++) if(!strcmp_os(name, sflist[i])) return(i+1); return(0);}/* Adds a new filename to the arg table if it's not present there */static void add_f_arg(char *name){ char *nptr; if(f_arg_lookup(name)==0) { if((nptr=(char *)malloc(strlen(name)+1))==NULL) error(M_OUT_OF_MEMORY);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -