/* * $Id: rearj.c,v 1.11 2005/06/21 19:53:14 andrew_belov Exp $ * --------------------------------------------------------------------------- * This is the main file of the REARJ utility. * */ #include #include #include #include "arj.h" #if COMPILER==BCC #include #elif COMPILER==MSC #include #endif #if TARGET==UNIX #include #endif DEBUGHDR(__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; i0)?-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]; #endif if(truename(full_name, name)) { msg_cprintf(H_HL|H_NFMT, M_SKIP_CANT_FIND, name); return(REARJ_ERL_WARNING); } entry=split_name(full_name, NULL, filespec); #if TARGET==UNIX fspec_len=strlen(filespec); #endif dot_pos=strrchr(filespec, '.'); if(dot_pos==NULL) { #if TARGET!=UNIX extension[0]='\0'; #endif strcpy(target_name, full_name); strcat(target_name, dot); strcat(target_name, archivers[target_type].suffix); strcpy(bak_name, full_name); } else { #if TARGET!=UNIX *dot_pos++='\0'; strcpy(extension, dot_pos); #endif strncpy(target_name, full_name, entry); target_name[entry]='\0'; strcpy(bak_name, target_name); #if TARGET!=UNIX strcat(target_name, filespec); strcat(target_name, dot); strcat(target_name, archivers[target_type].suffix); #endif strcat(bak_name, filespec); } strcat(bak_name, dot); strcat(bak_name, backup_extension); strcpy(cnv_name, work_dir); strcat(cnv_name, pathsep_str); strcat(cnv_name, filespec); strcat(cnv_name, dot); strcat(cnv_name, archivers[target_type].suffix); repack=!strcmp_os(target_name, full_name); tmp_name=cnv_diskette_archives?cnv_name:target_name; src_type=-1; for(i=0; ipattern_len&& filespec[fspec_len-pattern_len-1]=='.'&& !strcmp_os(filespec+fspec_len-pattern_len, archivers[i].suffix)) { match=1; strcat(target_name, filespec); target_name[strlen(target_name)-pattern_len]='\0'; strcat(target_name, archivers[target_type].suffix); } } if(match) src_type=i; #else if(!strcmp_os(extension, archivers[i].suffix)) src_type=i; #endif } if(src_type==-1) src_type=default_suffix; if(src_type==-1) { msg_cprintf(H_HL|H_NFMT, M_SKIP_UNKNOWN_TYPE, full_name); return(REARJ_ERL_UNCONFIGURED); } old_fsize=file_getfsize(full_name); if((!overwrite_existing&&!repack&&file_exists(target_name))|| (cnv_diskette_archives&&!overwrite_existing&&file_exists(cnv_name))) { msg_cprintf(H_HL|H_NFMT, M_SKIP_TGT_EXISTS, full_name); return(REARJ_ERL_TGT_EXISTS); } if(!update_with_backups&&repack) { msg_cprintf(H_HL|H_NFMT, M_SKIP_REPACK, full_name); return(REARJ_ERL_UPD_SKIPPED); } msg_cprintf(H_HL|H_NFMT, M_CONVERTING_ARCHIVE, full_name, archivers[src_type].suffix, archivers[target_type].suffix); if(conversion_query) { msg_cprintf(0, M_QUERY_CONVERT); if(!query_action()) { msg_cprintf(H_HL|H_NFMT, M_SKIPPING, full_name); return(REARJ_ERL_UPD_SKIPPED); } } if(overwrite_existing&&!repack&&file_exists(target_name)&&!no_file_activity) if(file_unlink(target_name)) error(M_CANT_UNLINK, target_name); if(cnv_diskette_archives&&overwrite_existing&&file_exists(cnv_name)&&!no_file_activity) if(file_unlink(cnv_name)) error(M_CANT_UNLINK, cnv_name); ts_store(&old_ftime, OS, file_getftime(full_name)); unlink_all(tmp_dir); if(file_chdir(tmp_dir)) error(M_CANT_CHDIR, tmp_dir); if(run_preunpack_cmd) { sprintf(cmd_buffer, "%s %s", preunpack_cmd_text, full_name); msg_cprintf(H_HL|H_NFMT, M_EXECUTING_PRE, cmd_buffer); exec_cmd(cmd_buffer); } sprintf(cmd_buffer, archivers[src_type].unpack_cmd, full_name); msg_cprintf(H_HL|H_NFMT, M_EXECUTING, cmd_buffer); exec_rc=exec_exe(cmd_buffer); if(exec_rc!=0) { if(exec_rc==-1) msg_cprintf(H_HL|H_NFMT, M_SKIP_EXE_MISSING, full_name); else msg_cprintf(H_HL|H_NFMT, M_SKIP_UNPACK_ERR, full_name, exec_rc); return(REARJ_ERL_UNPACK); } if(!archivers[target_type].subdirs_supported&&check_for_dirs()) { msg_cprintf(H_HL|H_NFMT, M_SKIP_UNSUPP_DIR, full_name); return(REARJ_ERL_DIRECTORIES); } if(!check_for_entries()) { msg_cprintf(H_HL|H_NFMT, M_SKIP_NO_FILES, full_name); return(REARJ_ERL_UNPACK); } if(run_precount_cmd) { sprintf(cmd_buffer, "%s %s", precount_cmd_text, full_name); msg_cprintf(H_HL|H_NFMT, M_EXECUTING_CNT, cmd_buffer); exec_cmd(cmd_buffer); } if(!skip_size_check) old_count=count_files(); if(run_extract_cmd) { msg_cprintf(H_HL|H_NFMT, M_EXECUTING_EXTR, extract_cmd_text); exec_rc=exec_exe(extract_cmd_text); if(exec_rc!=0) { if(exec_rc==-1) msg_cprintf(H_HL|H_NFMT, M_SKIP_V_EXE_MISSING, full_name); else msg_cprintf(H_HL|H_NFMT, M_SKIP_V_ERR, full_name, exec_rc); return(REARJ_ERL_VIRUS); } } if(convert_nested_archives) { nst_suf_wildcard=(acc_nested_suffixes!=NULL)?acc_nested_suffixes:archivers[src_type].suffix; /* ASR FIX 30/12/1999: only 6 additional (%s) params in original REARJ v 2.42 */ sprintf(cmd_buffer, "%s *.%s " REARJ_SWITCHAR "t%s " REARJ_SWITCHAR "d " REARJ_SWITCHAR "r " REARJ_SWITCHAR "a%s " REARJ_SWITCHAR "e%s%s%s%s%s%s%s", exe_name, nst_suf_wildcard, archivers[target_type].suffix, nst_suf_wildcard, skip_size_check?" " REARJ_SWITCHAR "s":nullstr, no_file_activity?" " REARJ_SWITCHAR "z":nullstr, update_with_backups?" " REARJ_SWITCHAR "u":nullstr, overwrite_existing?" " REARJ_SWITCHAR "o":nullstr, run_extract_cmd?" " REARJ_SWITCHAR "v":nullstr, skip_rearj_sw?" " REARJ_SWITCHAR "+":nullstr, skip_packing?" " REARJ_SWITCHAR "g":nullstr); msg_cprintf(H_HL|H_NFMT, M_EXECUTING, cmd_buffer); exec_rc=exec_exe(cmd_buffer); if(exec_rc!=0) { if(exec_rc==-1) msg_cprintf(H_HL|H_NFMT, M_SKIP_REARJ_MISSING, full_name); else msg_cprintf(H_HL|H_NFMT, M_SKIP_REARJ_FAILED, full_name, exec_rc); return(REARJ_ERL_INTERNAL); } } if(skip_packing) { if(logging_enabled) { arj_gettime(&log_ts); if(fprintf(logstream, M_LOGENTRY_CONV, timeseq, archivers[target_type].suffix, old_fsize, 0L, 0L, full_name)<=0) error(M_CANT_WRITE_LOG); } return(0); } if(!skip_size_check) old_size=count_total_size(); if(!archivers[target_type].hidden_supported) reset_attrs(); if(update_with_backups&&repack) { if(file_exists(bak_name)&&!no_file_activity) if(file_unlink(bak_name)) error(M_CANT_UNLINK, bak_name); if(!no_file_activity) if(rename_with_check(full_name, bak_name)) { msg_cprintf(H_HL|H_NFMT, M_SKIP_CANT_RENAME, full_name, bak_name); return(REARJ_ERL_RENAME); } if(!no_file_activity) msg_cprintf(H_HL|H_NFMT, M_BACKED_UP, full_name, bak_name); } sprintf(cmd_buffer, archivers[target_type].pack_cmd, tmp_name); msg_cprintf(H_HL|H_NFMT, M_EXECUTING, cmd_buffer); exec_rc=exec_exe(cmd_buffer); if(exec_rc!=0) { if(update_with_backups&&repack) { if(file_exists(full_name)&&!no_file_activity) if(file_unlink(full_name)) error(M_CANT_UNLINK, full_name); if(!no_file_activity) if(rename_with_check(bak_name, full_name)) error(M_CANTRENAME, bak_name, full_name); } if(exec_rc==-1) msg_cprintf(H_HL|H_NFMT, M_SKIP_P_EXE_MISSING, full_name); else { /* ASR fix for 2.42.05 -- unlink empty .tar.gz archives */ if(archivers[target_type].manual_deletion) unlink(tmp_name); msg_cprintf(H_HL|H_NFMT, M_SKIP_PACK_ERR, full_name, exec_rc); } return(REARJ_ERL_PACK); } if(file_chdir(work_dir)) error(M_CANT_CHDIR, work_dir); if(!file_exists(tmp_name)) { if(update_with_backups&&repack) { if(file_exists(full_name)&&!no_file_activity) if(file_unlink(full_name)) error(M_CANT_UNLINK, full_name); if(!no_file_activity) if(rename_with_check(bak_name, full_name)) error(M_CANTRENAME, bak_name, full_name); } msg_cprintf(H_HL|H_NFMT, M_SKIP_NOT_PACKED, full_name); return(REARJ_ERL_PACK); } new_fsize=file_getfsize(tmp_name); if(skip_larger_output&&old_fsizeMAX_SUFFIX) error(M_INVALID_SUFFIX, tmp_line); if((archivers[i].suffix=strdup(tmp_line))==NULL) error(M_OUT_OF_MEMORY); /* Pack command */ if(fgets(tmp_line, sizeof(tmp_line), stream)==NULL) error(M_MISSING_PACK_CMD, archivers[i].suffix); tokenize_lf(tmp_line); alltrim(tmp_line); if(strlen(tmp_line)==0) error(M_INVALID_PACK_CMD, tmp_line); if(strstr(tmp_line, strform)==NULL&&strstr(tmp_line, u_strform)==NULL) error(M_NO_PACK_STRFORM, tmp_line); if((archivers[i].pack_cmd=strdup(tmp_line))==NULL) error(M_OUT_OF_MEMORY); /* Unpack command */ if(fgets(tmp_line, sizeof(tmp_line), stream)==NULL) error(M_MISSING_UNPACK_CMD, archivers[i].suffix); tokenize_lf(tmp_line); alltrim(tmp_line); if(strlen(tmp_line)==0) error(M_INVALID_UNPACK_CMD, tmp_line); if(strstr(tmp_line, strform)==NULL&&strstr(tmp_line, u_strform)==NULL) error(M_NO_UNPACK_STRFORM, tmp_line); if((archivers[i].unpack_cmd=strdup(tmp_line))==NULL) error(M_OUT_OF_MEMORY); /* Option record */ if(fgets(tmp_line, sizeof(tmp_line), stream)==NULL) error(M_MISSING_OPTIONS, archivers[i].suffix); tokenize_lf(tmp_line); alltrim(tmp_line); if(strpbrk(tmp_line, "Aa")!=NULL) archivers[i].hidden_supported=1; if(strpbrk(tmp_line, "Dd")!=NULL) archivers[i].subdirs_supported=1; /* ASR fix for v 2.42.05 (.tar.gz): */ if(strpbrk(tmp_line, "Tt")!=NULL) archivers[i].manual_deletion=1; } no_more_exts: total_suffixes=i; } fclose(stream); } /* atexit routine */ static void final_cleanup(void) { if(!cleanup_initiated) { cleanup_initiated=1; if(tmpdir_malloced) release_dir(tmp_dir); /* ASR fix 14/11/2000 */ if(work_dir[0]!='\0') file_chdir(work_dir); if(tmp_dir!=NULL) { if(clear_tmp_dir) unlink_all(tmp_dir); if(!work_directory_assigned) file_rmdir(tmp_dir); if(tmpdir_malloced) { free(tmp_dir); /* malloc'ed */ tmpdir_malloced=0; } } } #ifdef COLOR_OUTPUT scrn_reset(); #endif } /* Ctrl+C handler */ static void ctrlc_handler(SIGHDLPARAMS) { /* Check if we are able to honor the request. If we aren't, raise the signal again and make a speedy getaway. */ if(ctrlc_busy) raise(SIGINT); else { ctrlc_initiated=1; signal(SIGINT, NULL); /* Restore default Ctrl+C handler */ msg_cprintf(H_SIG, M_BREAK_SIGNALED); exit(REARJ_ERL_WARNING); } } /* Main routine */ int main(int argc, char **argv) { int cnv_rc, exit_code; static char rearj_exe[CCHMAXPATH]; int switchar; int arg; char *aptr=NULL; unsigned int i; FILE_COUNT cur_file; char tmp_name[CCHMAXPATH], src_name[CCHMAXPATH]; char *fullpath; long total_gain; char *env_ptr, *env_dup, *env_tail; struct timestamp timestamp; time_t start_time, end_time; unsigned long time_diff; #ifdef COLOR_OUTPUT no_colors=redirected=!is_tty(stdout); #endif msg_cprintf(0, M_REARJ_BANNER); #ifdef USE_TZSET tzset(); #endif build_crc32_table(); ctrlc_busy=0; lfn_supported=LFN_NOT_SUPPORTED; convert_nested_archives=0; run_precount_cmd=0; run_preunpack_cmd=0; recurse_subdirs=0; help_issued=0; no_file_activity=0; delete_original_archives=0; skip_larger_output=0; cnv_diskette_archives=0; run_extract_cmd=0; skip_rearj_sw=0; logging_enabled=0; internal_archives_only=0; pick_older=0; pick_newer=0; conversion_query=0; chk_integrity=0; overwrite_existing=0; skip_lfn=0; skip_packing=0; skip_timestamping=0; skip_size_check=0; work_directory_assigned=0; testing_mode=0; update_with_backups=0; clear_tmp_dir=0; skip_count=0; target_type=0; total_old_fsize=total_new_fsize=0L; total_files=0; ts_store(&ts_older, OS_SPECIAL, 0L); ts_newer=ts_older; ctrlc_initiated=0; is_registered=0; exit_code=REARJ_ERL_SUCCESS; log_name=rearj_log; default_suffix=-1; backup_extension=backup_ext; #ifndef SKIP_GET_EXE_NAME get_exe_name(rearj_exe); #else get_exe_name(rearj_exe, argv[0]); #endif exe_name=rearj_exe; target_suffix=NULL; suffix_override=NULL; extract_cmd_text=NULL; precount_cmd_text=NULL; preunpack_cmd_text=NULL; tmp_dir=NULL; testing_marker=NULL; acc_nested_suffixes=NULL; work_dir[0]='\0'; timestr_older=timestr_newer=nullstr; flist_init(&flist_exclusion, EXCL_FLIST_SIZE, 0, 0); atexit(final_cleanup); parse_reg_key(); detect_lfns(); is_registered=reg_validation(regdata+REG_KEY1_SHIFT, regdata+REG_KEY2_SHIFT, regdata+REG_NAME_SHIFT, regdata+REG_HDR_SHIFT); if(!is_registered&&!msg_strcmp((FMSG *)regdata+REG_KEY2_SHIFT, M_REG_TYPE)) msg_cprintf(0, M_REGISTERED_TO, regdata+REG_NAME_SHIFT); limit=20; total_suffixes=0; if(signal(SIGINT, ctrlc_handler)==SIG_ERR) error(M_SIGNAL_FAILED); limit=0; if(regdata[REG_NAME_SHIFT]=='\0') is_registered=1; if(!reg_validation(single_spc, single_spc, single_spc, regdata+REG_HDR_SHIFT)) is_registered=2; n_args=0; switchar=get_sw_char(); for(arg=1; arg=MAX_ARGS) error(M_ARGTABLE_OVERFLOW); arg_ptr[n_args++]=aptr; } } if(skip_lfn) lfn_supported=LFN_NOT_SUPPORTED; if(chk_integrity) exit(check_integrity(rearj_exe)); if(help_issued||n_args==0) { msg_cprintf(0, strform, M_REARJ_COMMANDS); msg_cprintf(0, strform, M_REARJ_RCODES); exit(REARJ_ERL_SUCCESS); } if(delete_original_archives&&testing_mode) error(M_YD_CMD_CONFLICT); if(testing_mode&&testing_marker!=NULL&&!logging_enabled) error(M_LY_CMD); parse_rearj_cfg(); if(run_extract_cmd&&extract_cmd_text==NULL) error(M_NO_V_CMD, cfg_name); if(suffix_override!=NULL) { default_suffix=-1; for(i=0; i1, 1); for(i=limit; i0) msg_cprintf(0, M_CWD_MUST_BE_EMPTY); if(tmp_dir==NULL) { /* BUGBUG: this comes from a NetBSD patch. Originally a check for NO_MKDTEMP was suggested, but where are we expected to define it under DOS? -- ASR fix 25/01/2004 */ #ifdef HAVE_MKDTEMP tmp_dir=mkdtemp("/tmp/arj.XXXXXX"); /* BUGBUG: hardcoded location? */ #else tmp_dir=tmpnam(NULL); if(file_mkdir(tmp_dir)) error(M_CANT_MKDIR, tmp_dir); #endif } else { if(file_chdir(tmp_dir)) error(M_CANT_CHDIR, tmp_dir); if(count_files()>0) error(M_WORK_DIR_NOT_EMPTY, tmp_dir); if(file_chdir(work_dir)) error(M_CANT_CHDIR, work_dir); } if((fullpath=(char *)malloc(CCHMAXPATH))==NULL) error(M_OUT_OF_MEMORY); if(truename(fullpath, tmp_dir)) error(M_CANT_GET_FULL_PATH); tmp_dir=fullpath; clear_tmp_dir=1; tmpdir_malloced=1; /* Introduced by ASR */ for(cur_file=0; cur_file=0)&& (!pick_older||!ts_valid(ts_older)||ts_cmp(×tamp, &ts_older)<0)) { cnv_rc=convert_archive(src_name); if(cnv_rc!=REARJ_ERL_SUCCESS) { skip_count++; log_as_skipped(src_name, cnv_rc); if(exit_code==REARJ_ERL_SUCCESS&&(!internal_archives_only||cnv_rc!=REARJ_ERL_UNCONFIGURED)) exit_code=cnv_rc; } release_dir(tmp_dir); /* ASR fix 14/11/2000 */ if(file_chdir(work_dir)) error(M_CANT_CHDIR, work_dir); unlink_all(tmp_dir); if(file_rmdir(tmp_dir)) msg_cprintf(H_ERR, M_CANT_RMDIR, tmp_dir); if(file_mkdir(tmp_dir)) error(M_CANT_MKDIR, tmp_dir); } } if(!work_directory_assigned) { if(file_rmdir(tmp_dir)) msg_cprintf(H_ERR, M_CANT_RMDIR, tmp_dir); } if(tmpdir_malloced) { free(tmp_dir); tmpdir_malloced=0; } tmp_dir=NULL; time(&end_time); time_diff=sub_time(end_time, start_time); total_gain=(long)(total_old_fsize-total_new_fsize); msg_cprintf(H_HL|H_NFMT, M_TOTAL_SECONDS, time_diff); msg_cprintf(H_HL|H_NFMT, M_TOTAL_CONVERTED, total_files); msg_cprintf(H_HL|H_NFMT, M_TOTAL_SKIPPED, skip_count); msg_cprintf(H_HL|H_NFMT, M_OLD_SIZE, total_old_fsize); msg_cprintf(H_HL|H_NFMT, M_NEW_SIZE, total_new_fsize); msg_cprintf(H_HL|H_NFMT, M_SAVINGS_SIZE, total_gain); if(logging_enabled) { arj_gettime(&log_ts); if(fprintf(logstream, M_LOGENTRY_FOOTER, timeseq, archivers[target_type].suffix, total_old_fsize, total_new_fsize, total_gain, time_diff)<=0) error(M_CANT_WRITE_LOG); fclose(logstream); } flist_cleanup_proc(&flist_main); flist_cleanup_proc(&flist_exclusion); return((skip_count>0)?exit_code:REARJ_ERL_SUCCESS); }