📄 rearj.c
字号:
/* * $Id: rearj.c,v 1.8 2004/01/25 10:39:31 andrew_belov Exp $ * --------------------------------------------------------------------------- * This is the main file of the REARJ utility. * */#include <stdio.h>#include <signal.h>#include <time.h>#include "arj.h"#if COMPILER==BCC#include <dir.h>#elif COMPILER==MSC#include <direct.h>#endifDEBUGHDR(__FILE__) /* Debug information block *//* Limits for "*.*"-alike processing */#ifdef TILED #define LARGE_FLIST_SIZE 20000 #define EXCL_FLIST_SIZE 10000#else #define LARGE_FLIST_SIZE FILELIST_CAPACITY #define EXCL_FLIST_SIZE FILELIST_CAPACITY#endif#define MAX_SUFFIXES 25 /* Number of supported suffixes */#if TARGET!=UNIX#define MAX_SUFFIX 3 /* Consider increasing... */#else#define MAX_SUFFIX 32#endif#define MAX_ARGS 100 /* Maximum # of command-line args */#if TARGET==UNIX #define REARJ_SWITCHAR "-"#else #define REARJ_SWITCHAR "/"#endif/* Time output sequence */#define timeseq (int)log_ts.ti_hour, (int)log_ts.ti_min, (int)log_ts.ti_sec/* Configuration entry structure */struct archiver_entry{ char *suffix; char *pack_cmd; char *unpack_cmd; int hidden_supported; /* Consider making them chars */ int subdirs_supported; /* The following is an ASR fix for REARJ v 2.42.05 (.tar.gz) */ int manual_deletion; /* Can't delete errorneous archives */};/* Local variables */static int logging_enabled; /* 1 if actions are to be logged */static struct time log_ts; /* Current time (for logging) */static int total_suffixes; /* Number of suffixes in REARJ.CFG */static struct archiver_entry archivers[MAX_SUFFIXES];static int target_type; /* Target archive type */static FILE *logstream; /* Log file */static int ctrlc_busy; /* 1 if Ctrl+C can't be processed */static int cnv_diskette_archives; /* Convert diskette archives (-f) */static int internal_archives_only; /* Process only internal archive files (-e) */static int update_with_backups; /* Allow updates of archives with backup (-u) */static int conversion_query; /* Query for conversion (-q) */static int skip_size_check; /* Do not check total size and count */static int run_preunpack_cmd; /* Run a cmd. before unpacking */static int run_precount_cmd; /* 1 if a command must be run before counting files */static int run_extract_cmd; /* Run a command when all files have been extracted */static int testing_mode; /* /Y testing mode */static char *backup_extension; /* "BAK" (without a preceding dot) */static char dot[]="."; /* Widely-used symbol */static char work_dir[CCHMAXPATH]; /* Working directory */static char name_fetch[CCHMAXPATH]; /* For parsing list files */static int default_suffix; /* For non-standard extensions */static char *tmp_dir;static char *preunpack_cmd_text;static char *precount_cmd_text;static char *extract_cmd_text;static struct timestamp ts_newer;static struct timestamp ts_older;static int limit;static int cleanup_initiated;static int ctrlc_initiated;static int skip_packing;static int skip_rearj_sw;static int skip_larger_output;static int skip_timestamping;static int pick_older; /* Pick older archives (/m) */static int pick_newer; /* Pick newer archives (/n) */static int exclusion_assigned; /* Never used but implemented (/x) */static int convert_nested_archives;static char *acc_nested_suffixes; /* Filter for nested archives */static int delete_original_archives;static unsigned long total_old_fsize, total_new_fsize;static int skip_lfn;static int chk_integrity;static char *suffix_override;static char *log_name;static char *target_suffix;static char *testing_marker; /* Text to write (/Y****) */static char *timestr_older;static char *timestr_newer;static FILE *liststream;static struct date x_date;static int work_directory_assigned;static int skip_count;static int clear_tmp_dir; /* 1 if files in tmp. dir must be removed upon shutdown */static char *arg_ptr[MAX_ARGS]; /* Argument table */static char u_strform[]="%S";static char single_spc[]=" ";static int n_args;static int tmpdir_malloced;static char rearj_sw[]="REARJ_SW";/* Filenames/extensions */static char backup_ext[]="bak";static char cfg_name[]="rearj.cfg";static char rearj_log[]="rearj.log";/* Pauses the execution and displays an error */void pause_error(FMSG *msg){ arj_delay(5); msg_cprintf(H_ERR, msg); exit(REARJ_ERL_WARNING);}/* Resets the attributes of all files in the current directory */static void reset_attrs(){ char tmp_name[CCHMAXPATH]; struct flist_root tmp_flist; FILE_COUNT i; strcpy(tmp_name, all_wildcard); flist_init(&tmp_flist, LARGE_FLIST_SIZE, 0, 0); wild_list(&tmp_flist, tmp_name, FETCH_DIRS, 1, 1, NULL); for(i=0; i<tmp_flist.files; i++) { retrieve_entry(tmp_name, &tmp_flist, i); flush_kbd(); if(file_chmod(tmp_name, 1, 0)==-1) error(M_CANT_CLEAR_ATTRS, tmp_name); } flist_cleanup_proc(&tmp_flist);}/* Returns total size of the files located in the current directory */static unsigned long count_total_size(){ char tmp_name[CCHMAXPATH]; struct flist_root tmp_flist; FILE_COUNT i; unsigned long rc; rc=0L; strcpy(tmp_name, all_wildcard); flist_init(&tmp_flist, LARGE_FLIST_SIZE, 0, 0); wild_list(&tmp_flist, tmp_name, FETCH_DIRS, 1, 1, NULL); for(i=0; i<tmp_flist.files; i++) { retrieve_entry(tmp_name, &tmp_flist, i); flush_kbd(); rc+=(unsigned long)file_getfsize(tmp_name); } flist_cleanup_proc(&tmp_flist); return(rc);}/* Copies one file to another with mandatory comparision */static int file_copy_v(char *src, char *dest){ FILE *istream, *ostream; char buf[CACHE_SIZE], dbuf[CACHE_SIZE]; int bytes_read; istream=file_open(src, m_rb); if(istream==NULL) return(-1); ostream=file_open(dest, m_wb); if(ostream==NULL) { fclose(istream); return(-1); } flush_kbd(); do { flush_kbd(); if((bytes_read=fread(buf, 1, sizeof(buf), istream))==0) break; } while(fwrite(buf, 1, bytes_read, ostream)==bytes_read); if(fclose(istream)) { fclose(ostream); return(-1); } if(fclose(ostream)) return(-1); istream=file_open(src, m_rb); if(istream==NULL) return(-1); ostream=file_open(dest, m_rb); if(ostream==NULL) { fclose(istream); return(-1); } flush_kbd(); while(1) { if((bytes_read=fread(buf, 1, CACHE_SIZE, istream))==0) break; if(fread(dbuf, 1, CACHE_SIZE, ostream)!=bytes_read) break; if(memcmp(buf, dbuf, bytes_read)) break; flush_kbd(); } fclose(ostream); fclose(istream); return((bytes_read>0)?-1:0);}/* Returns total number of the files located in the current directory */static FILE_COUNT count_files(){ char tmp_name[CCHMAXPATH]; struct flist_root tmp_flist; FILE_COUNT rc; strcpy(tmp_name, all_wildcard); flist_init(&tmp_flist, LARGE_FLIST_SIZE, 0, 0); wild_list(&tmp_flist, tmp_name, FETCH_DIRS, 1, 1, NULL); rc=tmp_flist.files; flist_cleanup_proc(&tmp_flist); return(rc);}/* Recursively removes files and subdirectories */static void recursive_unlink(char *name){ struct new_ffblk new_ffblk; char tmp_name[CCHMAXPATH]; char subdir_wildcard[20]; int attr_mask; int result; attr_mask=STD_FI_ATTRS; result=lfn_findfirst(name, &new_ffblk, attr_mask); while(result==0) { if(new_ffblk.ff_attrib&STD_DIR_ATTR) { if(strcmp(new_ffblk.ff_name, cur_dir_spec)&&strcmp(new_ffblk.ff_name, up_dir_spec)) { split_name(name, tmp_name, subdir_wildcard); if(strlen(new_ffblk.ff_name)+strlen(tmp_name)+strlen(subdir_wildcard)+2>=CCHMAXPATH) error(M_MAXDIR_EXCEEDED, tmp_name); strcat(tmp_name, new_ffblk.ff_name); strcat(tmp_name, pathsep_str); strcat(tmp_name, subdir_wildcard); case_path(tmp_name); recursive_unlink(tmp_name); /* Remove the directory itself */ split_name(name, tmp_name, NULL); strcat(tmp_name, new_ffblk.ff_name); flush_kbd(); file_chmod(tmp_name, 1, 0); if(file_rmdir(tmp_name)) error(M_CANT_RMDIR, tmp_name); } } else { split_name(name, tmp_name, NULL); strcat(tmp_name, new_ffblk.ff_name); case_path(tmp_name); flush_kbd(); file_chmod(tmp_name, 1, 0); if(file_unlink(tmp_name)) error(M_CANT_UNLINK, tmp_name); } result=lfn_findnext(&new_ffblk); } lfn_findclose(&new_ffblk);}/* Releases the working directory -- ASR fix 14/11/2000 */static void release_dir(char *dir){ char tmp_name[4]; #ifdef HAVE_DRIVES if(dir[0]!='\0'&&dir[1]==':') { memcpy(tmp_name, dir, 2); strcpy(tmp_name+2, pathsep_str); } else strcpy(tmp_name, pathsep_str); #else strcpy(tmp_name, pathsep_str); #endif file_chdir(tmp_name);}/* Removes all files on the specified drive/path */static void unlink_all(char *path){ char tmp_path[CCHMAXPATH]; char c; strcpy(tmp_path, path); case_path(tmp_path); c=tmp_path[strlen(tmp_path)-1]; #ifdef HAVE_DRIVES strcat(tmp_path, (c==PATHSEP_DEFAULT||c==':')?all_wildcard:root_wildcard); #else strcat(tmp_path, (c==PATHSEP_DEFAULT)?all_wildcard:root_wildcard); #endif if(no_file_activity) msg_cprintf(H_HL|H_NFMT, M_DELETING, tmp_path); recursive_unlink(tmp_path);}/* Writes a "SKIPPED" log entry */static void log_as_skipped(char *name, int reason){ if(logging_enabled) { arj_gettime(&log_ts); if(fprintf(logstream, M_LOGENTRY_SKIP, timeseq, archivers[target_type].suffix, reason, name)<=0) error(M_CANT_WRITE_LOG); }}/* Checks if any subdirectories are present in the current directory */static int check_for_dirs(){ char tmp_name[CCHMAXPATH]; struct new_ffblk new_ffblk; int attr_mask; int result; strcpy(tmp_name, all_wildcard); attr_mask=STD_FI_ATTRS; result=lfn_findfirst(tmp_name, &new_ffblk, attr_mask); while(result==0) { if(new_ffblk.ff_attrib&STD_DIR_ATTR&&strcmp(new_ffblk.ff_name, cur_dir_spec)&&strcmp(new_ffblk.ff_name, up_dir_spec)) { lfn_findclose(&new_ffblk); return(1); } result=lfn_findnext(&new_ffblk); } lfn_findclose(&new_ffblk); return(0);}/* Checks if any files and/or subdirectories are present in the current directory */static int check_for_entries(){ char tmp_name[CCHMAXPATH]; struct new_ffblk new_ffblk; int attr_mask; int result; strcpy(tmp_name, all_wildcard); attr_mask=STD_FI_ATTRS; result=lfn_findfirst(tmp_name, &new_ffblk, attr_mask); while(result==0) { if(!(new_ffblk.ff_attrib&STD_DIR_ATTR)) { lfn_findclose(&new_ffblk); return(1); } else if(strcmp(new_ffblk.ff_name, cur_dir_spec)&&strcmp(new_ffblk.ff_name, up_dir_spec)) { lfn_findclose(&new_ffblk); return(1); } result=lfn_findnext(&new_ffblk); } lfn_findclose(&new_ffblk); return(0);}/* Returns a fully-qualified filename */static int truename(char *dest, char *name){ char tmp_name[CCHMAXPATH], cur_dir[CCHMAXPATH]; int tmp_entry;#ifdef HAVE_DRIVES int dsk;#endif tmp_entry=split_name(name, dest, tmp_name); /* Verify if it's a root directory path or file path */ if(#ifdef HAVE_DRIVES (dest[1]!=':'||dest[2]!='\0')&& (dest[1]!=':'||dest[2]!=PATHSEP_DEFAULT||dest[3]!='\0')&&#endif (dest[0]!=PATHSEP_DEFAULT||dest[1]!='\0')&& (tmp_entry>0)) dest[tmp_entry-1]='\0';#ifdef HAVE_DRIVES dsk=getdisk(); if(dest[1]==':') setdisk(toupper(dest[0])-'A');#endif if(file_getcwd(cur_dir)==NULL) { msg_cprintf(0, M_GETCWD_FAILED); return(1); } if(#ifdef HAVE_DRIVES (dest[1]!=':'||dest[2]!='\0')&&#endif dest[0]!='\0') { if(file_chdir(dest)) { msg_cprintf(H_HL|H_NFMT, M_PATH_NOT_FOUND, dest);termination: if(file_chdir(cur_dir)) error(M_CANT_CHDIR, cur_dir);#ifdef HAVE_DRIVES setdisk(dsk);#endif return(1); } } if(file_getcwd(dest)==NULL) { msg_cprintf(0, M_GETCWD_FAILED); goto termination; } if(tmp_name[0]!='\0'&&dest[strlen(dest)-1]!=PATHSEP_DEFAULT) strcat(dest, pathsep_str); strcat(dest, tmp_name); if(file_chdir(cur_dir)) error(M_CANT_CHDIR, cur_dir);#ifdef HAVE_DRIVES setdisk(dsk);#endif return(0);}/* Runs an external command */static int exec_cmd(char *cmd){ int rc; if(no_file_activity) return(1); flush_kbd(); ctrlc_busy=1; rc=system_cmd(cmd); ctrlc_busy=0; flush_kbd(); return(rc);}/* Runs an external executable */static int exec_exe(char *cmd){ int rc; if(no_file_activity) return(1); flush_kbd(); ctrlc_busy=1; rc=exec_pgm(cmd); ctrlc_busy=0; flush_kbd(); return(rc);}/* Archive conversion procedure */static int convert_archive(char *name){ long old_fsize, new_fsize; int exec_rc=0; char full_name[CCHMAXPATH], target_name[CCHMAXPATH]; char bak_name[CCHMAXPATH]; char cnv_name[CCHMAXPATH]; /* Converted file in the work dir. */ char filespec[40]; int entry; char *dot_pos; int repack; char *tmp_name; int i; int src_type; struct timestamp old_ftime; char cmd_buffer[400]; FILE_COUNT old_count=0, new_count; char *nst_suf_wildcard; unsigned long old_size=0, new_size; long gain; #if TARGET==UNIX int match, fspec_len, pattern_len; #else char extension[64];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -