📄 arj_proc.c
字号:
/* * $Id: arj_proc.c,v 1.11 2003/09/14 22:14:48 andrew_belov Exp $ * --------------------------------------------------------------------------- * This file contains many of the functions that are called by various ARJ * modules. Everything is OS-independent, all OS-dependent procedures must be * moved to ENVIRON.C. * */#include "arj.h"DEBUGHDR(__FILE__) /* Debug information block *//* Other defines */#define FNAME_FLEN 27 /* Length of formatted filename *//* String table (may need some localization in the future...) */#if SFX_LEVEL>=ARJ||defined(REARJ)static char strtime_filler[]="00000000000000";#endif#if SFX_LEVEL>=ARJstatic char time_tail_pattern[]="%04d%02d%02d%03d%02d%02d%02d";static char date_digit_format[]="%04d%02d%02d";static char allowed_attrs[]=TAG_LIST;static char vol_st_id[]=" - "; /* A substring of M_NEXT_VOL_STATS */#endif#if SFX_LEVEL>=ARJSFXVstatic char nonexistent_name[]="...";#endif#if SFX_LEVEL>=ARJSFXV||defined(REARJ)/* The first byte in integrity_pattern[] is changed to avoid confusion with the pattern to search */static unsigned char integrity_pattern[]={0xB1, 0x03, 0xB0, 0x02, 0xB0, 0x03, 0xB0, 0x04, 0xB0, 0x05, 0};#endif#if SFX_LEVEL>=ARJstatic int hswitch; /* Indicates that we have a "-h..." */static int jswitch; /* Indicates that we have a "-j..." */static int os2switch; /* ARJ/2 switches (-h2, -2) */static int noswitch;#endif#if SFX_LEVEL>=ARJstaticint *sw_index[]={&jswitch, &hswitch, &allow_any_attrs, &filter_fa_arch, &skip_ts_check, &delete_processed, &exclude_paths, &freshen_criteria, &garble_enabled, &indicator_style, &keep_bak, &create_list_file, &custom_method, &new_files_only, &filter_same_or_newer, &fnm_matching, &query_for_each_file, &recurse_subdirs, ×tamp_override, &type_override, &update_criteria, &multivolume_option, &assign_work_directory, &exclude_files, &yes_on_all_queries, &use_comment, &help_issued, &listchars_allowed, &handle_labels, &disable_arj_sw, &select_by_number, &install_errhdl, &quiet_mode, &rsp_per_line, &noswitch, NULL};staticint *jsw_index[]={&jswitch, &comment_display, &chapter_mode, &exit_after_count, &chk_free_space, &create_sfx, &validate_style, &select_backup_files, &jh_enabled, &create_index, &keep_tmp_archive, &show_filenames_only, &max_compression, &restart_at_filename, &serialize_exts, &prompt_for_more, &set_string_parameter, &ignore_crc_errors, &store_by_suffix, &test_archive_crc, &translate_unix_paths, &verbose_display, &extract_to_file, &start_at_ext_pos, &assume_yes, &supply_comment_file, &hollow_mode, &skip_time_attrs, NULL};staticint *hsw_index[]={&hswitch, &clear_archive_bit, &filter_attrs, &run_cmd_at_start, &debug_enabled, &arjsec_opt, &lfn_mode, &gost_cipher, &detailed_index, &protfile_option, &listfile_err_opt, &filelist_storage, &nonexist_filespec, &extm_mode, &arjdisp_enabled, &ignore_open_errors, &ignore_archive_errors, &disable_sharing, &set_target_directory, &allow_mv_update, &chk_arj_version, &search_mode, &override_archive_exts, &use_ansi_cp, &sign_with_arjsec, &append_curtime, &marksym_expansion, &force_lfn, &noswitch, NULL};staticint *os2sw_index[]={&os2switch, &arcmail_sw, &noswitch, &crit_eas, &dos_host, &include_eas, &disable_comment_series, &suppress_hardlinks, &skip_century, &fix_longnames, &do_chown, &priority.class, &recursion_order, &symlink_accuracy, &noswitch, &exclude_eas, NULL};staticint *jysw_index[]={&skip_append_query, &prompt_for_mkdir, &query_delete, &skip_space_query, &skip_rename_prompt, &overwrite_existing, &kbd_cleanup_on_input, &skip_scanned_query, &skip_next_vol_query, &accept_shortcut_keys, NULL};#elif SFX_LEVEL==ARJSFXVstaticint *sw_index[]={&skip_integrity_test, &prompt_for_directory, &skip_ts_check, &chk_free_space, &extract_expath, &freshen_criteria, &garble_enabled, &help_issued, &indicator_style, &process_lfn_archive, &skip_preset_options, &list_sfx_cmd, &overwrite_ro, &new_files_only, &gost_cipher, &fnm_matching, &ignore_crc_errors, &disable_sharing, &test_sfx_cmd, &update_criteria, &verbose_list, &extract_to_file, &extract_cmd, &yes_on_all_queries, &assume_yes, &help_issued, &skip_volumes, &debug_enabled, &quiet_mode, &handle_labels, &arjdisp_enabled, &execute_extr_cmd, NULL};staticint *jysw_index[]={&skip_append_query, &prompt_for_mkdir, &skip_space_query, &skip_extract_query, &skip_rename_prompt, &overwrite_existing, &kbd_cleanup_on_input, &skip_next_vol_query, NULL};#elif SFX_LEVEL==ARJSFXstaticint *sw_index[]={&extract_expath, &list_sfx_cmd, &test_sfx_cmd, &verbose_list, &extract_cmd, &show_ansi_comments, &prompt_for_directory, &skip_ts_check, &arjdisp_enabled, &freshen_criteria, &garble_enabled, &indicator_style, &process_lfn_archive, &verbose_display, &make_directories, &new_files_only, &overwrite_existing, &fnm_matching, &skip_integrity_test, &update_criteria, &skip_extract_query, &yes_on_all_queries, &quiet_mode, &help_issued, &help_issued, &execute_extr_cmd};#endif/* Local functions */#if SFX_LEVEL>=ARJ static int compare_exts(char *name, char *pad);#endif#if SFX_LEVEL>=ARJ/* Encodes a block of data */void garble_encode_stub(char *data, int len){ garble_encode(data, len);}/* Decodes a block of data */void garble_decode_stub(char *data, int len){ garble_decode(data, len);}#endif#if SFX_LEVEL>=ARJ/* Returns day of year */static int day_of_year(struct tm *tms){ int m, y, rc; rc=0; for(m=tms->tm_mon; m>0; m--) { switch(m) { case 1: rc+=31; break; case 2: rc+=28; y=tms->tm_year+1900; if((y%4==0)&&(y%100!=0||y%400==0)) rc++; break; case 3: rc+=31; break; case 4: rc+=30; break; case 5: rc+=31; break; case 6: rc+=30; break; case 7: rc+=31; break; case 8: rc+=31; break; case 9: rc+=30; break; case 10: rc+=31; break; case 11: rc+=30; break; } } return(rc+tms->tm_mday);}/* Appends current date/time to the archive filename in accordance with the "-h#" option */void append_curtime_proc(){ time_t curtime; struct tm *tms; char time_pad[19]; char ext[32]; char *ext_pos; char *aptr, *tptr; char *dptr=time_pad; /* ASR fix for High C -- 29/03/2001 */ int l, lim; int doy; /* Day of year */ curtime=time(NULL); tms=localtime(&curtime); doy=day_of_year(tms); sprintf(time_pad, time_tail_pattern, tms->tm_year+1900, tms->tm_mon+1, tms->tm_mday, doy, tms->tm_hour, tms->tm_min, tms->tm_sec); if((ext_pos=strchr(archive_name+split_name(archive_name, NULL, NULL), '.'))!=NULL) { strncpy(ext, ext_pos, sizeof(ext)); *ext_pos='\0'; } else ext[0]='\0'; if(time_str[0]=='\0') { if(append_curtime==ATS_DUAL) strcat(archive_name, time_pad+7); else if(append_curtime==ATS_TIME) strcat(archive_name, time_pad+8); else if(append_curtime==ATS_DATE) { time_pad[8]='\0'; strcat(archive_name, time_pad+2); } } else /* Custom format */ { l=strlen(time_str); aptr=archive_name+strlen(archive_name)+l; *aptr='\0'; lim=0; for(tptr=time_str+l-1; (unsigned int)tptr>=(unsigned int)time_str; tptr--) { if(*tptr==*(tptr+1)) *(--aptr)=(lim>0)?dptr[--lim]:*tptr; else { switch(*tptr) { case 'Y': dptr=time_pad; lim=4; *(--aptr)=dptr[--lim]; break; case 'M': dptr=time_pad+4; lim=2; *(--aptr)=dptr[--lim]; break; case 'D': dptr=time_pad+6; lim=2; *(--aptr)=dptr[--lim]; break; case 'N': dptr=time_pad+8; lim=3; *(--aptr)=dptr[--lim]; break; case 'h': dptr=time_pad+11; lim=2; *(--aptr)=dptr[--lim]; break; case 'm': dptr=time_pad+13; lim=2; *(--aptr)=dptr[--lim]; break; case 's': dptr=time_pad+15; lim=2; *(--aptr)=dptr[--lim]; break; default: *(--aptr)=*tptr; } } } } strcat(archive_name, ext);}/* Adds an ending backslash to the given pathname if it doesn't contain one */void add_pathsep(char *path){ int len; if((len=strlen(path))==0) /* Maybe current path? */ return; if(strchr(path_separators, path[len-1])==NULL) { path[len]=PATHSEP_DEFAULT; path[len+1]='\0'; }}/* Converts the timestamps given by the user to the internal storage format */void convert_time_limits(){ char *cptr; time_t tmp_ts; time_t ts; struct tm *tms; struct timestamp arj_ts; /* ARJ-format timestamp storage */ if(filter_same_or_newer==TCHECK_NDAYS) { tmp_ts=strtoul(timestr_newer, &cptr, 10)*(-86400L); ts=sum_time(tmp_ts, time(NULL)); tms=localtime(&ts); if(tms==NULL) /* ASR fix 21/02/2001 -- IBM LIBC */ error(M_INVALID_DATE); sprintf(misc_buf, date_digit_format, tms->tm_year+1900, tms->tm_mon+1, tms->tm_mday); timestr_newer=malloc_str(misc_buf); /* MEMORY LEAK! (Never freed) */ } if(filter_older==TCHECK_NDAYS) { tmp_ts=strtoul(timestr_older, &cptr, 10)*(-86400L); ts=sum_time(tmp_ts, time(NULL)); tms=localtime(&ts); if(tms==NULL) /* ASR fix 21/02/2001 -- IBM LIBC */ error(M_INVALID_DATE); sprintf(misc_buf, date_digit_format, tms->tm_year+1900, tms->tm_mon+1, tms->tm_mday); timestr_older=malloc_str(misc_buf); /* MEMORY LEAK! (Never freed) */ } if(timestr_older[0]!='\0') convert_strtime(&tested_ftime_older, timestr_older); if(timestr_newer[0]!='\0') convert_strtime(&tested_ftime_newer, timestr_newer); if(timestr_older[0]=='\0'&×tr_newer[0]=='\0') { ts=time(NULL); tms=localtime(&ts); make_timestamp(&arj_ts, tms->tm_year, tms->tm_mon+1, tms->tm_mday, 0, 0, 0); if(timestr_newer[0]=='\0') tested_ftime_newer=arj_ts; if(timestr_older[0]=='\0') tested_ftime_older=arj_ts; }}/* Analyzes ARJ_SW settings */void parse_arj_sw(int cmd, char *arj_sw, char *dest){ int use_file; /* 1 if ARJ_SW represents a file */ char *buf; char *dptr, *varname; char *sptr; FILE *stream; char *sw, *sw_p; use_file=0; while(arj_sw[0]==' ') arj_sw++; if(strchr(switch_chars, arj_sw[0])==NULL) { buf=dest; dptr=dest+FILENAME_MAX+1; sptr=dest+FILENAME_MAX*2+2; sptr[0]='\0'; dptr[0]='\0'; stream=file_open_noarch(arj_sw, m_r); while(fgets(buf, FILENAME_MAX, stream)!=NULL) { strip_lf(buf); if(buf[0]=='#') continue; else if(!use_file&&buf[0]=='+'&&buf[1]==' ') { strcpy(sptr, buf+1); use_file=1; } else if(!use_file&&buf[0]=='-'&&buf[1]==' ') { strcat(dptr, buf+2); strcat(dptr, " "); use_file=1; } else if((cmd==ARJ_CMD_ADDC&&!strnicmp(buf, "AC ", 3))|| (cmd==ARJ_CMD_CNVC&&!strnicmp(buf, "CC ", 3))|| (cmd==ARJ_CMD_DELC&&!strnicmp(buf, "DC ", 3))) { strcpy(dptr, buf+3); use_file=1; break; } else { if(toupper((int)buf[0])==cmd&&buf[1]==' ') { strcpy(dptr, buf+2); use_file=1; break; } } } fclose(stream); strcat(dptr, sptr); sw=malloc_str(dptr); } else sw=malloc_str(arj_sw); varname=use_file?arj_sw:arj_env_name; sw_p=malloc_str(sw); /* Tokenize switch */ for(dptr=sw; *dptr!='\0'; dptr++) if(*dptr==' ') *dptr='\0'; sptr=dptr; dptr=sw; while((unsigned int)dptr<(unsigned int)sptr) { while(*dptr=='\0') dptr++; if((unsigned int)dptr<(unsigned int)sptr) { if(is_switch(dptr)) analyze_arg(dptr); while(*dptr!='\0'&&(unsigned int)dptr<(unsigned int)sptr) dptr++; } } if(!translate_unix_paths) switch_char=0; msg_cprintf(H_HL|H_NFMT, M_USING_ENV_VAR, varname, sw_p); free(sw_p);}/* Copies a part of archive */void copy_bytes(unsigned long nbytes){ char *buf; unsigned int fetch_size; buf=malloc_msg(PROC_BLOCK_SIZE); fseek(aistream, 0L, SEEK_SET); while(nbytes>0L) { fetch_size=(unsigned int)min(PROC_BLOCK_SIZE, nbytes); if(fread(buf, 1, fetch_size, aistream)!=fetch_size) error(M_CANTREAD); if(fwrite(buf, 1, fetch_size, aostream)!=fetch_size) error(M_DISK_FULL); nbytes-=(unsigned long)fetch_size; } free(buf);}/* Returns 1 if the given filename did not contain any UNIX-style ('/') path separators, and all native path separators have been converted to UNIX-style ones ('/'). 0 is returned if the filename initially contained a UNIX-style separator. When it returns 1, the PATHSYM_FLAG in arj_flags is set by parent procedure. */int translate_path(char *name){ int i; if(strchr(name, PATHSEP_UNIX)!=NULL) return(0); for(i=0; name[i]!=0; i++) if(name[i]==PATHSEP_DEFAULT) name[i]=PATHSEP_UNIX; return(1);}/* Restarts archive processing from the specified file */void restart_proc(char *dest){ char *r_name, *c_name; char *dptr; char vol_stats[40]; char *vs_ptr; int i; int vs_match; int vn=0, vc=0; /* ASR fix for High C -- 29/03/2001 */ unsigned long vs=0; /* ASR fix for High C -- 29/03/2001 */ FILE_COUNT cur_file; int nd; dptr=dest; r_name=malloc_msg(FILENAME_MAX); c_name=malloc_msg(FILENAME_MAX); strcpy(r_name, filename_to_restart); msg_strcpy(vol_stats, M_NEXT_VOLUME_STATS); vs_ptr=vol_stats; i=0; while(*vs_ptr!='\0') { if(!strncmp(vs_ptr, vol_st_id, sizeof(vol_st_id)-1)) break; i++; vs_ptr++; } i+=sizeof(vol_st_id)-1; if(filename_to_restart[0]=='\0'&&index_name[0]!='\0') { vs_match=0; r_name[0]='\0'; idxstream=file_open_noarch(index_name, m_r); while(fgets(dptr, FILENAME_MAX, idxstream)!=NULL) { strip_lf(dptr); if(!memcmp(dptr, vol_stats, i)) { vs_match=1; vn=atoi(dptr+i); vc=atoi(dptr+i+4); vs=atoi(dptr+i+6); strcpy(r_name, dptr+i+17); } } fclose(idxstream); if(vs_match==0) error(M_RESTART_INFO_NF); else { resume_volume_num=vn; if(vc==1) { start_at_ext_pos=1; ext_pos=vs; } else if(vc==2) error(M_NOTHING_TO_DO); } } for(cur_file=0L; cur_file<flist_main.files; cur_file++) { flist_retrieve(c_name, NULL, &flist_main, cur_file); if(!strcmp_os(c_name, r_name)) break; cfa_store(cur_file, FLFLAG_DELETED); } if(cur_file>=flist_main.files) error(M_CANT_FIND_RST_FILE, r_name); free(c_name); free(r_name); if(create_sfx) { nd=split_name(archive_name, NULL, NULL); vs_ptr=strchr(archive_name+nd, '.'); if(vs_ptr==NULL) msg_strcat(archive_name, M_EXE_EXT); else msg_strcpy(vs_ptr, M_EXE_EXT); }}/* Looks for an extension of the given filename in the extension list */int search_for_extension(char *name, char *ext_list){ int match; char *endptr; char ext_pad[EXTENSION_MAX+1]; char *t_ptr; int i; match=0; endptr=&ext_list[strlen(ext_list)]; t_ptr=ext_list; while(t_ptr!=endptr) { if(*t_ptr=='.') t_ptr++; ext_pad[0]='.'; for(i=0; i<EXTENSION_MAX&&t_ptr[i]!='\0'&&t_ptr[i]!='.'; i++) ext_pad[i+1]=t_ptr[i]; ext_pad[i+1]='\0'; if(compare_exts(name, ext_pad)) { match=1; break; } else { while(*t_ptr!='\0'&&*t_ptr!='.') t_ptr++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -