1 /*
2 * $Id: rearj.c,v 1.11 2005/06/21 19:53:14 andrew_belov Exp $
3 * ---------------------------------------------------------------------------
4 * This is the main file of the REARJ utility.
5 *
6 */
7
8 #include <stdio.h>
9 #include <signal.h>
10 #include <time.h>
11
12 #include "arj.h"
13
14 #if COMPILER==BCC
15 #include <dir.h>
16 #elif COMPILER==MSC
17 #include <direct.h>
18 #endif
19
20 #if TARGET==UNIX
21 #include <unistd.h>
22 #endif
23
24 DEBUGHDR(__FILE__) /* Debug information block */
25
26 /* Limits for "*.*"-alike processing */
27 #ifdef TILED
28 #define LARGE_FLIST_SIZE 20000
29 #define EXCL_FLIST_SIZE 10000
30 #else
31 #define LARGE_FLIST_SIZE FILELIST_CAPACITY
32 #define EXCL_FLIST_SIZE FILELIST_CAPACITY
33 #endif
34
35 #define MAX_SUFFIXES 25 /* Number of supported suffixes */
36 #if TARGET!=UNIX
37 #define MAX_SUFFIX 3 /* Consider increasing... */
38 #else
39 #define MAX_SUFFIX 32
40 #endif
41 #define MAX_ARGS 100 /* Maximum # of command-line args */
42
43 #if TARGET==UNIX
44 #define REARJ_SWITCHAR "-"
45 #else
46 #define REARJ_SWITCHAR "/"
47 #endif
48
49 /* Time output sequence */
50
51 #define timeseq (int)log_ts.ti_hour, (int)log_ts.ti_min, (int)log_ts.ti_sec
52
53 /* Configuration entry structure */
54
55 struct archiver_entry
56 {
57 char *suffix;
58 char *pack_cmd;
59 char *unpack_cmd;
60 int hidden_supported; /* Consider making them chars */
61 int subdirs_supported;
62 /* The following is an ASR fix for REARJ v 2.42.05 (.tar.gz) */
63 int manual_deletion; /* Can't delete errorneous archives */
64 };
65
66 /* Local variables */
67
68 static int logging_enabled; /* 1 if actions are to be logged */
69 static struct time log_ts; /* Current time (for logging) */
70 static int total_suffixes; /* Number of suffixes in REARJ.CFG */
71 static struct archiver_entry archivers[MAX_SUFFIXES];
72 static int target_type; /* Target archive type */
73 static FILE *logstream; /* Log file */
74 static int ctrlc_busy; /* 1 if Ctrl+C can't be processed */
75 static int cnv_diskette_archives; /* Convert diskette archives (-f) */
76 static int internal_archives_only; /* Process only internal archive
77 files (-e) */
78 static int update_with_backups; /* Allow updates of archives with
79 backup (-u) */
80 static int conversion_query; /* Query for conversion (-q) */
81 static int skip_size_check; /* Do not check total size and count */
82 static int run_preunpack_cmd; /* Run a cmd. before unpacking */
83 static int run_precount_cmd; /* 1 if a command must be run before
84 counting files */
85 static int run_extract_cmd; /* Run a command when all files have
86 been extracted */
87 static int testing_mode; /* /Y testing mode */
88 static char *backup_extension; /* "BAK" (without a preceding dot) */
89 static char dot[]="."; /* Widely-used symbol */
90 static char work_dir[CCHMAXPATH]; /* Working directory */
91 static char name_fetch[CCHMAXPATH]; /* For parsing list files */
92 static int default_suffix; /* For non-standard extensions */
93 static char *tmp_dir;
94 static char *preunpack_cmd_text;
95 static char *precount_cmd_text;
96 static char *extract_cmd_text;
97 static struct timestamp ts_newer;
98 static struct timestamp ts_older;
99 static int limit;
100 static int cleanup_initiated;
101 static int ctrlc_initiated;
102 static int skip_packing;
103 static int skip_rearj_sw;
104 static int skip_larger_output;
105 static int skip_timestamping;
106 static int pick_older; /* Pick older archives (/m) */
107 static int pick_newer; /* Pick newer archives (/n) */
108 static int exclusion_assigned; /* Never used but implemented (/x) */
109 static int convert_nested_archives;
110 static char *acc_nested_suffixes; /* Filter for nested archives */
111 static int delete_original_archives;
112 static unsigned long total_old_fsize, total_new_fsize;
113 static int skip_lfn;
114 static int chk_integrity;
115 static char *suffix_override;
116 static char *log_name;
117 static char *target_suffix;
118 static char *testing_marker; /* Text to write (/Y****) */
119 static char *timestr_older;
120 static char *timestr_newer;
121 static FILE *liststream;
122 static struct date x_date;
123 static int work_directory_assigned;
124 static int skip_count;
125 static int clear_tmp_dir; /* 1 if files in tmp. dir must be
126 removed upon shutdown */
127 static char *arg_ptr[MAX_ARGS]; /* Argument table */
128 static char u_strform[]="%S";
129 static char single_spc[]=" ";
130 static int n_args;
131 static int tmpdir_malloced;
132 static char rearj_sw[]="REARJ_SW";
133
134 /* Filenames/extensions */
135
136 static char backup_ext[]="bak";
137 static char cfg_name[]="rearj.cfg";
138 static char rearj_log[]="rearj.log";
139
140 /* Pauses the execution and displays an error */
141
pause_error(FMSG * msg)142 void pause_error(FMSG *msg)
143 {
144 arj_delay(5);
145 msg_cprintf(H_ERR, msg);
146 exit(REARJ_ERL_WARNING);
147 }
148
149 /* Resets the attributes of all files in the current directory */
150
reset_attrs()151 static void reset_attrs()
152 {
153 char tmp_name[CCHMAXPATH];
154 struct flist_root tmp_flist;
155 FILE_COUNT i;
156
157 strcpy(tmp_name, all_wildcard);
158 flist_init(&tmp_flist, LARGE_FLIST_SIZE, 0, 0);
159 wild_list(&tmp_flist, tmp_name, FETCH_DIRS, 1, 1, NULL);
160 for(i=0; i<tmp_flist.files; i++)
161 {
162 retrieve_entry(tmp_name, &tmp_flist, i);
163 flush_kbd();
164 if(file_chmod(tmp_name, 1, 0)==-1)
165 error(M_CANT_CLEAR_ATTRS, tmp_name);
166 }
167 flist_cleanup_proc(&tmp_flist);
168 }
169
170 /* Returns total size of the files located in the current directory */
171
count_total_size()172 static unsigned long count_total_size()
173 {
174 char tmp_name[CCHMAXPATH];
175 struct flist_root tmp_flist;
176 FILE_COUNT i;
177 unsigned long rc;
178
179 rc=0L;
180 strcpy(tmp_name, all_wildcard);
181 flist_init(&tmp_flist, LARGE_FLIST_SIZE, 0, 0);
182 wild_list(&tmp_flist, tmp_name, FETCH_DIRS, 1, 1, NULL);
183 for(i=0; i<tmp_flist.files; i++)
184 {
185 retrieve_entry(tmp_name, &tmp_flist, i);
186 flush_kbd();
187 rc+=(unsigned long)file_getfsize(tmp_name);
188 }
189 flist_cleanup_proc(&tmp_flist);
190 return(rc);
191 }
192
193 /* Copies one file to another with mandatory comparison */
194
file_copy_v(char * src,char * dest)195 static int file_copy_v(char *src, char *dest)
196 {
197 FILE *istream, *ostream;
198 char buf[CACHE_SIZE], dbuf[CACHE_SIZE];
199 int bytes_read;
200
201 istream=file_open(src, m_rb);
202 if(istream==NULL)
203 return(-1);
204 ostream=file_open(dest, m_wb);
205 if(ostream==NULL)
206 {
207 fclose(istream);
208 return(-1);
209 }
210 flush_kbd();
211 do
212 {
213 flush_kbd();
214 if((bytes_read=fread(buf, 1, sizeof(buf), istream))==0)
215 break;
216 } while(fwrite(buf, 1, bytes_read, ostream)==bytes_read);
217 if(fclose(istream))
218 {
219 fclose(ostream);
220 return(-1);
221 }
222 if(fclose(ostream))
223 return(-1);
224 istream=file_open(src, m_rb);
225 if(istream==NULL)
226 return(-1);
227 ostream=file_open(dest, m_rb);
228 if(ostream==NULL)
229 {
230 fclose(istream);
231 return(-1);
232 }
233 flush_kbd();
234 while(1)
235 {
236 if((bytes_read=fread(buf, 1, CACHE_SIZE, istream))==0)
237 break;
238 if(fread(dbuf, 1, CACHE_SIZE, ostream)!=bytes_read)
239 break;
240 if(memcmp(buf, dbuf, bytes_read))
241 break;
242 flush_kbd();
243 }
244 fclose(ostream);
245 fclose(istream);
246 return((bytes_read>0)?-1:0);
247 }
248
249 /* Returns total number of the files located in the current directory */
250
count_files()251 static FILE_COUNT count_files()
252 {
253 char tmp_name[CCHMAXPATH];
254 struct flist_root tmp_flist;
255 FILE_COUNT rc;
256
257 strcpy(tmp_name, all_wildcard);
258 flist_init(&tmp_flist, LARGE_FLIST_SIZE, 0, 0);
259 wild_list(&tmp_flist, tmp_name, FETCH_DIRS, 1, 1, NULL);
260 rc=tmp_flist.files;
261 flist_cleanup_proc(&tmp_flist);
262 return(rc);
263 }
264
265 /* Recursively removes files and subdirectories */
266
recursive_unlink(char * name)267 static void recursive_unlink(char *name)
268 {
269 struct new_ffblk new_ffblk;
270 char tmp_name[CCHMAXPATH];
271 char subdir_wildcard[20];
272 int attr_mask;
273 int result;
274
275 attr_mask=STD_FI_ATTRS;
276 result=lfn_findfirst(name, &new_ffblk, attr_mask);
277 while(result==0)
278 {
279 if(new_ffblk.ff_attrib&STD_DIR_ATTR)
280 {
281 if(strcmp(new_ffblk.ff_name, cur_dir_spec)&&strcmp(new_ffblk.ff_name, up_dir_spec))
282 {
283 split_name(name, tmp_name, subdir_wildcard);
284 if(strlen(new_ffblk.ff_name)+strlen(tmp_name)+strlen(subdir_wildcard)+2>=CCHMAXPATH)
285 error(M_MAXDIR_EXCEEDED, tmp_name);
286 strcat(tmp_name, new_ffblk.ff_name);
287 strcat(tmp_name, pathsep_str);
288 strcat(tmp_name, subdir_wildcard);
289 case_path(tmp_name);
290 recursive_unlink(tmp_name);
291 /* Remove the directory itself */
292 split_name(name, tmp_name, NULL);
293 strcat(tmp_name, new_ffblk.ff_name);
294 flush_kbd();
295 file_chmod(tmp_name, 1, 0);
296 if(file_rmdir(tmp_name))
297 error(M_CANT_RMDIR, tmp_name);
298 }
299 }
300 else
301 {
302 split_name(name, tmp_name, NULL);
303 strcat(tmp_name, new_ffblk.ff_name);
304 case_path(tmp_name);
305 flush_kbd();
306 file_chmod(tmp_name, 1, 0);
307 if(file_unlink(tmp_name))
308 error(M_CANT_UNLINK, tmp_name);
309 }
310 result=lfn_findnext(&new_ffblk);
311 }
312 lfn_findclose(&new_ffblk);
313 }
314
315 /* Releases the working directory -- ASR fix 14/11/2000 */
316
release_dir(char * dir)317 static void release_dir(char *dir)
318 {
319 char tmp_name[4];
320
321 #ifdef HAVE_DRIVES
322 if(dir[0]!='\0'&&dir[1]==':')
323 {
324 memcpy(tmp_name, dir, 2);
325 strcpy(tmp_name+2, pathsep_str);
326 }
327 else
328 strcpy(tmp_name, pathsep_str);
329 #else
330 strcpy(tmp_name, pathsep_str);
331 #endif
332 file_chdir(tmp_name);
333 }
334
335 /* Removes all files on the specified drive/path */
336
unlink_all(char * path)337 static void unlink_all(char *path)
338 {
339 char tmp_path[CCHMAXPATH];
340 char c;
341
342 strcpy(tmp_path, path);
343 case_path(tmp_path);
344 c=tmp_path[strlen(tmp_path)-1];
345 #ifdef HAVE_DRIVES
346 strcat(tmp_path, (c==PATHSEP_DEFAULT||c==':')?all_wildcard:root_wildcard);
347 #else
348 strcat(tmp_path, (c==PATHSEP_DEFAULT)?all_wildcard:root_wildcard);
349 #endif
350 if(no_file_activity)
351 msg_cprintf(H_HL|H_NFMT, M_DELETING, tmp_path);
352 recursive_unlink(tmp_path);
353 }
354
355 /* Writes a "SKIPPED" log entry */
356
log_as_skipped(char * name,int reason)357 static void log_as_skipped(char *name, int reason)
358 {
359 if(logging_enabled)
360 {
361 arj_gettime(&log_ts);
362 if(fprintf(logstream, M_LOGENTRY_SKIP, timeseq, archivers[target_type].suffix, reason, name)<=0)
363 error(M_CANT_WRITE_LOG);
364 }
365 }
366
367 /* Checks if any subdirectories are present in the current directory */
368
check_for_dirs()369 static int check_for_dirs()
370 {
371 char tmp_name[CCHMAXPATH];
372 struct new_ffblk new_ffblk;
373 int attr_mask;
374 int result;
375
376 strcpy(tmp_name, all_wildcard);
377 attr_mask=STD_FI_ATTRS;
378 result=lfn_findfirst(tmp_name, &new_ffblk, attr_mask);
379 while(result==0)
380 {
381 if(new_ffblk.ff_attrib&STD_DIR_ATTR&&strcmp(new_ffblk.ff_name, cur_dir_spec)&&strcmp(new_ffblk.ff_name, up_dir_spec))
382 {
383 lfn_findclose(&new_ffblk);
384 return(1);
385 }
386 result=lfn_findnext(&new_ffblk);
387 }
388 lfn_findclose(&new_ffblk);
389 return(0);
390 }
391
392 /* Checks if any files and/or subdirectories are present in the current
393 directory */
394
check_for_entries()395 static int check_for_entries()
396 {
397 char tmp_name[CCHMAXPATH];
398 struct new_ffblk new_ffblk;
399 int attr_mask;
400 int result;
401
402 strcpy(tmp_name, all_wildcard);
403 attr_mask=STD_FI_ATTRS;
404 result=lfn_findfirst(tmp_name, &new_ffblk, attr_mask);
405 while(result==0)
406 {
407 if(!(new_ffblk.ff_attrib&STD_DIR_ATTR))
408 {
409 lfn_findclose(&new_ffblk);
410 return(1);
411 }
412 else if(strcmp(new_ffblk.ff_name, cur_dir_spec)&&strcmp(new_ffblk.ff_name, up_dir_spec))
413 {
414 lfn_findclose(&new_ffblk);
415 return(1);
416 }
417 result=lfn_findnext(&new_ffblk);
418 }
419 lfn_findclose(&new_ffblk);
420 return(0);
421 }
422
423 /* Returns a fully-qualified filename */
424
truename(char * dest,char * name)425 static int truename(char *dest, char *name)
426 {
427 char tmp_name[CCHMAXPATH], cur_dir[CCHMAXPATH];
428 int tmp_entry;
429 #ifdef HAVE_DRIVES
430 int dsk;
431 #endif
432
433 tmp_entry=split_name(name, dest, tmp_name);
434 /* Verify if it's a root directory path or file path */
435 if(
436 #ifdef HAVE_DRIVES
437 (dest[1]!=':'||dest[2]!='\0')&&
438 (dest[1]!=':'||dest[2]!=PATHSEP_DEFAULT||dest[3]!='\0')&&
439 #endif
440 (dest[0]!=PATHSEP_DEFAULT||dest[1]!='\0')&&
441 (tmp_entry>0))
442 dest[tmp_entry-1]='\0';
443 #ifdef HAVE_DRIVES
444 dsk=getdisk();
445 if(dest[1]==':')
446 setdisk(toupper(dest[0])-'A');
447 #endif
448 if(file_getcwd(cur_dir)==NULL)
449 {
450 msg_cprintf(0, M_GETCWD_FAILED);
451 return(1);
452 }
453 if(
454 #ifdef HAVE_DRIVES
455 (dest[1]!=':'||dest[2]!='\0')&&
456 #endif
457 dest[0]!='\0')
458 {
459 if(file_chdir(dest))
460 {
461 msg_cprintf(H_HL|H_NFMT, M_PATH_NOT_FOUND, dest);
462 termination:
463 if(file_chdir(cur_dir))
464 error(M_CANT_CHDIR, cur_dir);
465 #ifdef HAVE_DRIVES
466 setdisk(dsk);
467 #endif
468 return(1);
469 }
470 }
471 if(file_getcwd(dest)==NULL)
472 {
473 msg_cprintf(0, M_GETCWD_FAILED);
474 goto termination;
475 }
476 if(tmp_name[0]!='\0'&&dest[strlen(dest)-1]!=PATHSEP_DEFAULT)
477 strcat(dest, pathsep_str);
478 strcat(dest, tmp_name);
479 if(file_chdir(cur_dir))
480 error(M_CANT_CHDIR, cur_dir);
481 #ifdef HAVE_DRIVES
482 setdisk(dsk);
483 #endif
484 return(0);
485 }
486
487 /* Runs an external command */
488
exec_cmd(char * cmd)489 static int exec_cmd(char *cmd)
490 {
491 int rc;
492
493 if(no_file_activity)
494 return(1);
495 flush_kbd();
496 ctrlc_busy=1;
497 rc=system_cmd(cmd);
498 ctrlc_busy=0;
499 flush_kbd();
500 return(rc);
501 }
502
503 /* Runs an external executable */
504
exec_exe(char * cmd)505 static int exec_exe(char *cmd)
506 {
507 int rc;
508
509 if(no_file_activity)
510 return(1);
511 flush_kbd();
512 ctrlc_busy=1;
513 rc=exec_pgm(cmd);
514 ctrlc_busy=0;
515 flush_kbd();
516 return(rc);
517 }
518
519 /* Archive conversion procedure */
520
convert_archive(char * name)521 static int convert_archive(char *name)
522 {
523 long old_fsize, new_fsize;
524 int exec_rc=0;
525 char full_name[CCHMAXPATH], target_name[CCHMAXPATH];
526 char bak_name[CCHMAXPATH];
527 char cnv_name[CCHMAXPATH]; /* Converted file in the work dir. */
528 char filespec[40];
529 int entry;
530 char *dot_pos;
531 int repack;
532 char *tmp_name;
533 int i;
534 int src_type;
535 struct timestamp old_ftime;
536 char cmd_buffer[400];
537 FILE_COUNT old_count=0, new_count;
538 char *nst_suf_wildcard;
539 unsigned long old_size=0, new_size;
540 long gain;
541 #if TARGET==UNIX
542 int match, fspec_len, pattern_len;
543 #else
544 char extension[64];
545 #endif
546
547 if(truename(full_name, name))
548 {
549 msg_cprintf(H_HL|H_NFMT, M_SKIP_CANT_FIND, name);
550 return(REARJ_ERL_WARNING);
551 }
552 entry=split_name(full_name, NULL, filespec);
553 #if TARGET==UNIX
554 fspec_len=strlen(filespec);
555 #endif
556 dot_pos=strrchr(filespec, '.');
557 if(dot_pos==NULL)
558 {
559 #if TARGET!=UNIX
560 extension[0]='\0';
561 #endif
562 strcpy(target_name, full_name);
563 strcat(target_name, dot);
564 strcat(target_name, archivers[target_type].suffix);
565 strcpy(bak_name, full_name);
566 }
567 else
568 {
569 #if TARGET!=UNIX
570 *dot_pos++='\0';
571 strcpy(extension, dot_pos);
572 #endif
573 strncpy(target_name, full_name, entry);
574 target_name[entry]='\0';
575 strcpy(bak_name, target_name);
576 #if TARGET!=UNIX
577 strcat(target_name, filespec);
578 strcat(target_name, dot);
579 strcat(target_name, archivers[target_type].suffix);
580 #endif
581 strcat(bak_name, filespec);
582 }
583 strcat(bak_name, dot);
584 strcat(bak_name, backup_extension);
585 strcpy(cnv_name, work_dir);
586 strcat(cnv_name, pathsep_str);
587 strcat(cnv_name, filespec);
588 strcat(cnv_name, dot);
589 strcat(cnv_name, archivers[target_type].suffix);
590 repack=!strcmp_os(target_name, full_name);
591 tmp_name=cnv_diskette_archives?cnv_name:target_name;
592 src_type=-1;
593 for(i=0; i<total_suffixes; i++)
594 {
595 #if TARGET==UNIX
596 match=0;
597 if(dot_pos==NULL)
598 {
599 if(archivers[i].suffix[0]=='\0')
600 match=1;
601 }
602 else
603 {
604 pattern_len=strlen(archivers[i].suffix);
605 if(fspec_len>pattern_len&&
606 filespec[fspec_len-pattern_len-1]=='.'&&
607 !strcmp_os(filespec+fspec_len-pattern_len, archivers[i].suffix))
608 {
609 match=1;
610 strcat(target_name, filespec);
611 target_name[strlen(target_name)-pattern_len]='\0';
612 strcat(target_name, archivers[target_type].suffix);
613 }
614 }
615 if(match)
616 src_type=i;
617 #else
618 if(!strcmp_os(extension, archivers[i].suffix))
619 src_type=i;
620 #endif
621 }
622 if(src_type==-1)
623 src_type=default_suffix;
624 if(src_type==-1)
625 {
626 msg_cprintf(H_HL|H_NFMT, M_SKIP_UNKNOWN_TYPE, full_name);
627 return(REARJ_ERL_UNCONFIGURED);
628 }
629 old_fsize=file_getfsize(full_name);
630 if((!overwrite_existing&&!repack&&file_exists(target_name))||
631 (cnv_diskette_archives&&!overwrite_existing&&file_exists(cnv_name)))
632 {
633 msg_cprintf(H_HL|H_NFMT, M_SKIP_TGT_EXISTS, full_name);
634 return(REARJ_ERL_TGT_EXISTS);
635 }
636 if(!update_with_backups&&repack)
637 {
638 msg_cprintf(H_HL|H_NFMT, M_SKIP_REPACK, full_name);
639 return(REARJ_ERL_UPD_SKIPPED);
640 }
641 msg_cprintf(H_HL|H_NFMT, M_CONVERTING_ARCHIVE, full_name, archivers[src_type].suffix, archivers[target_type].suffix);
642 if(conversion_query)
643 {
644 msg_cprintf(0, M_QUERY_CONVERT);
645 if(!query_action())
646 {
647 msg_cprintf(H_HL|H_NFMT, M_SKIPPING, full_name);
648 return(REARJ_ERL_UPD_SKIPPED);
649 }
650 }
651 if(overwrite_existing&&!repack&&file_exists(target_name)&&!no_file_activity)
652 if(file_unlink(target_name))
653 error(M_CANT_UNLINK, target_name);
654 if(cnv_diskette_archives&&overwrite_existing&&file_exists(cnv_name)&&!no_file_activity)
655 if(file_unlink(cnv_name))
656 error(M_CANT_UNLINK, cnv_name);
657 ts_store(&old_ftime, OS, file_getftime(full_name));
658 unlink_all(tmp_dir);
659 if(file_chdir(tmp_dir))
660 error(M_CANT_CHDIR, tmp_dir);
661 if(run_preunpack_cmd)
662 {
663 sprintf(cmd_buffer, "%s %s", preunpack_cmd_text, full_name);
664 msg_cprintf(H_HL|H_NFMT, M_EXECUTING_PRE, cmd_buffer);
665 exec_cmd(cmd_buffer);
666 }
667 sprintf(cmd_buffer, archivers[src_type].unpack_cmd, full_name);
668 msg_cprintf(H_HL|H_NFMT, M_EXECUTING, cmd_buffer);
669 exec_rc=exec_exe(cmd_buffer);
670 if(exec_rc!=0)
671 {
672 if(exec_rc==-1)
673 msg_cprintf(H_HL|H_NFMT, M_SKIP_EXE_MISSING, full_name);
674 else
675 msg_cprintf(H_HL|H_NFMT, M_SKIP_UNPACK_ERR, full_name, exec_rc);
676 return(REARJ_ERL_UNPACK);
677 }
678 if(!archivers[target_type].subdirs_supported&&check_for_dirs())
679 {
680 msg_cprintf(H_HL|H_NFMT, M_SKIP_UNSUPP_DIR, full_name);
681 return(REARJ_ERL_DIRECTORIES);
682 }
683 if(!check_for_entries())
684 {
685 msg_cprintf(H_HL|H_NFMT, M_SKIP_NO_FILES, full_name);
686 return(REARJ_ERL_UNPACK);
687 }
688 if(run_precount_cmd)
689 {
690 sprintf(cmd_buffer, "%s %s", precount_cmd_text, full_name);
691 msg_cprintf(H_HL|H_NFMT, M_EXECUTING_CNT, cmd_buffer);
692 exec_cmd(cmd_buffer);
693 }
694 if(!skip_size_check)
695 old_count=count_files();
696 if(run_extract_cmd)
697 {
698 msg_cprintf(H_HL|H_NFMT, M_EXECUTING_EXTR, extract_cmd_text);
699 exec_rc=exec_exe(extract_cmd_text);
700 if(exec_rc!=0)
701 {
702 if(exec_rc==-1)
703 msg_cprintf(H_HL|H_NFMT, M_SKIP_V_EXE_MISSING, full_name);
704 else
705 msg_cprintf(H_HL|H_NFMT, M_SKIP_V_ERR, full_name, exec_rc);
706 return(REARJ_ERL_VIRUS);
707 }
708 }
709 if(convert_nested_archives)
710 {
711 nst_suf_wildcard=(acc_nested_suffixes!=NULL)?acc_nested_suffixes:archivers[src_type].suffix;
712 /* ASR FIX 30/12/1999: only 6 additional (%s) params in original REARJ v 2.42 */
713 sprintf(cmd_buffer,
714 "%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",
715 exe_name,
716 nst_suf_wildcard,
717 archivers[target_type].suffix,
718 nst_suf_wildcard,
719 skip_size_check?" " REARJ_SWITCHAR "s":nullstr,
720 no_file_activity?" " REARJ_SWITCHAR "z":nullstr,
721 update_with_backups?" " REARJ_SWITCHAR "u":nullstr,
722 overwrite_existing?" " REARJ_SWITCHAR "o":nullstr,
723 run_extract_cmd?" " REARJ_SWITCHAR "v":nullstr,
724 skip_rearj_sw?" " REARJ_SWITCHAR "+":nullstr,
725 skip_packing?" " REARJ_SWITCHAR "g":nullstr);
726 msg_cprintf(H_HL|H_NFMT, M_EXECUTING, cmd_buffer);
727 exec_rc=exec_exe(cmd_buffer);
728 if(exec_rc!=0)
729 {
730 if(exec_rc==-1)
731 msg_cprintf(H_HL|H_NFMT, M_SKIP_REARJ_MISSING, full_name);
732 else
733 msg_cprintf(H_HL|H_NFMT, M_SKIP_REARJ_FAILED, full_name, exec_rc);
734 return(REARJ_ERL_INTERNAL);
735 }
736 }
737 if(skip_packing)
738 {
739 if(logging_enabled)
740 {
741 arj_gettime(&log_ts);
742 if(fprintf(logstream, M_LOGENTRY_CONV, timeseq, archivers[target_type].suffix, old_fsize, 0L, 0L, full_name)<=0)
743 error(M_CANT_WRITE_LOG);
744 }
745 return(0);
746 }
747 if(!skip_size_check)
748 old_size=count_total_size();
749 if(!archivers[target_type].hidden_supported)
750 reset_attrs();
751 if(update_with_backups&&repack)
752 {
753 if(file_exists(bak_name)&&!no_file_activity)
754 if(file_unlink(bak_name))
755 error(M_CANT_UNLINK, bak_name);
756 if(!no_file_activity)
757 if(rename_with_check(full_name, bak_name))
758 {
759 msg_cprintf(H_HL|H_NFMT, M_SKIP_CANT_RENAME, full_name, bak_name);
760 return(REARJ_ERL_RENAME);
761 }
762 if(!no_file_activity)
763 msg_cprintf(H_HL|H_NFMT, M_BACKED_UP, full_name, bak_name);
764 }
765 sprintf(cmd_buffer, archivers[target_type].pack_cmd, tmp_name);
766 msg_cprintf(H_HL|H_NFMT, M_EXECUTING, cmd_buffer);
767 exec_rc=exec_exe(cmd_buffer);
768 if(exec_rc!=0)
769 {
770 if(update_with_backups&&repack)
771 {
772 if(file_exists(full_name)&&!no_file_activity)
773 if(file_unlink(full_name))
774 error(M_CANT_UNLINK, full_name);
775 if(!no_file_activity)
776 if(rename_with_check(bak_name, full_name))
777 error(M_CANTRENAME, bak_name, full_name);
778 }
779 if(exec_rc==-1)
780 msg_cprintf(H_HL|H_NFMT, M_SKIP_P_EXE_MISSING, full_name);
781 else
782 {
783 /* ASR fix for 2.42.05 -- unlink empty .tar.gz archives */
784 if(archivers[target_type].manual_deletion)
785 unlink(tmp_name);
786 msg_cprintf(H_HL|H_NFMT, M_SKIP_PACK_ERR, full_name, exec_rc);
787 }
788 return(REARJ_ERL_PACK);
789 }
790 if(file_chdir(work_dir))
791 error(M_CANT_CHDIR, work_dir);
792 if(!file_exists(tmp_name))
793 {
794 if(update_with_backups&&repack)
795 {
796 if(file_exists(full_name)&&!no_file_activity)
797 if(file_unlink(full_name))
798 error(M_CANT_UNLINK, full_name);
799 if(!no_file_activity)
800 if(rename_with_check(bak_name, full_name))
801 error(M_CANTRENAME, bak_name, full_name);
802 }
803 msg_cprintf(H_HL|H_NFMT, M_SKIP_NOT_PACKED, full_name);
804 return(REARJ_ERL_PACK);
805 }
806 new_fsize=file_getfsize(tmp_name);
807 if(skip_larger_output&&old_fsize<new_fsize)
808 {
809 msg_cprintf(H_HL|H_NFMT, M_SKIP_LARGER, full_name);
810 if(!no_file_activity)
811 if(file_unlink(tmp_name))
812 error(M_CANT_UNLINK, tmp_name);
813 if(update_with_backups||!repack||no_file_activity)
814 return(REARJ_ERL_OVERGROW);
815 else
816 {
817 if(rename_with_check(bak_name, full_name))
818 return(REARJ_ERL_OVERGROW);
819 else
820 error(M_CANTRENAME, bak_name, full_name);
821 }
822 }
823 if(!skip_size_check)
824 {
825 msg_cprintf(H_HL|H_NFMT, M_VERIFYING_SIZE, old_count, old_size);
826 unlink_all(tmp_dir);
827 if(file_chdir(tmp_dir))
828 error(M_CANT_CHDIR, tmp_dir);
829 sprintf(cmd_buffer, archivers[target_type].unpack_cmd, tmp_name);
830 msg_cprintf(H_HL|H_NFMT, M_EXECUTING, cmd_buffer);
831 exec_exe(cmd_buffer);
832 new_count=count_files();
833 new_size=count_total_size();
834 msg_cprintf(H_HL|H_NFMT, M_FOUND_SIZE, new_count, new_size);
835 if(old_count!=new_count)
836 {
837 msg_cprintf(H_HL|H_NFMT, M_SKIP_COUNT_MISMATCH, full_name);
838 if(!no_file_activity)
839 if(file_unlink(tmp_name))
840 error(M_CANT_UNLINK, tmp_name);
841 if(update_with_backups&&repack&&!no_file_activity)
842 if(rename_with_check(bak_name, full_name))
843 error(M_CANTRENAME, bak_name, full_name);
844 return(REARJ_ERL_COUNT);
845 }
846 if(old_size!=new_size)
847 {
848 msg_cprintf(H_HL|H_NFMT, M_SKIP_SIZE_MISMATCH, full_name);
849 if(!no_file_activity)
850 if(file_unlink(tmp_name))
851 error(M_CANT_UNLINK, tmp_name);
852 if(update_with_backups&&repack&&!no_file_activity)
853 if(rename_with_check(bak_name, full_name))
854 error(M_CANTRENAME, bak_name, full_name);
855 return(REARJ_ERL_SIZE);
856 }
857 msg_cprintf(H_HL, M_SIZE_VERIFIED);
858 if(file_chdir(work_dir))
859 error(M_CANT_CHDIR, work_dir);
860 }
861 if(cnv_diskette_archives)
862 {
863 if(file_getfree(full_name)+old_fsize<new_fsize)
864 {
865 msg_cprintf(H_HL|H_NFMT, M_SKIP_DISK_FULL, full_name);
866 if(!no_file_activity)
867 if(file_unlink(tmp_name))
868 error(M_CANT_UNLINK, tmp_name);
869 if(update_with_backups&&repack&&!no_file_activity)
870 if(rename_with_check(bak_name, full_name))
871 error(M_CANTRENAME, bak_name, full_name);
872 return(REARJ_ERL_DISK_FULL);
873 }
874 }
875 if(delete_original_archives)
876 {
877 if(!repack)
878 {
879 msg_cprintf(H_HL|H_NFMT, M_DELETING_2, full_name);
880 if(!no_file_activity)
881 if(file_unlink(full_name))
882 error(M_CANT_UNLINK, full_name);
883 }
884 else if(cnv_diskette_archives&&update_with_backups)
885 {
886 msg_cprintf(H_HL|H_NFMT, M_DELETING_2, bak_name);
887 if(!no_file_activity)
888 if(file_unlink(bak_name))
889 error(M_CANT_UNLINK, bak_name);
890 }
891 }
892 if(cnv_diskette_archives)
893 {
894 if(!no_file_activity)
895 {
896 if(file_copy_v(cnv_name, target_name))
897 error(M_CANT_COPY, cnv_name, target_name);
898 }
899 if(!no_file_activity)
900 if(file_unlink(cnv_name))
901 error(M_CANT_UNLINK, cnv_name);
902 }
903 if(delete_original_archives&&!cnv_diskette_archives&&update_with_backups&&repack)
904 {
905 msg_cprintf(H_HL|H_NFMT, M_DELETING_2, bak_name);
906 if(!no_file_activity)
907 if(file_unlink(bak_name))
908 error(M_CANT_UNLINK, bak_name);
909 }
910 if(!skip_timestamping)
911 file_setftime(target_name, ts_native(&old_ftime, OS));
912 if(testing_mode&&!delete_original_archives)
913 {
914 if(update_with_backups&&repack)
915 {
916 if(file_exists(full_name))
917 if(file_unlink(full_name))
918 error(M_CANT_UNLINK, full_name);
919 msg_cprintf(H_HL|H_NFMT, M_RENAMING, bak_name, full_name);
920 if(!no_file_activity)
921 {
922 if(rename_with_check(bak_name, full_name))
923 error(M_CANTRENAME, bak_name, full_name);
924 }
925 }
926 else if(!repack)
927 {
928 msg_cprintf(H_HL|H_NFMT, M_DELETING_2, target_name);
929 if(!no_file_activity)
930 if(file_unlink(target_name))
931 error(M_CANT_UNLINK, target_name);
932 }
933 }
934 gain=(long)(old_fsize-new_fsize);
935 msg_cprintf(H_HL|H_NFMT, M_OLD_SIZE, old_fsize);
936 msg_cprintf(H_HL|H_NFMT, M_NEW_SIZE, new_fsize);
937 msg_cprintf(H_HL|H_NFMT, M_SAVINGS_SIZE, gain);
938 printf("\n");
939 total_old_fsize+=old_fsize;
940 total_new_fsize+=new_fsize;
941 total_files++;
942 if(logging_enabled)
943 {
944 arj_gettime(&log_ts);
945 if(fprintf(logstream, M_LOGENTRY_CONV, timeseq, archivers[target_type].suffix, old_fsize, new_fsize, gain, full_name)<=0)
946 error(M_CANT_WRITE_LOG);
947 }
948 return(0);
949 }
950
951 /* Adds a new file to the exclusion filelist */
952
submit_exclusion(char * name)953 static void submit_exclusion(char *name)
954 {
955 char tmp_name[CCHMAXPATH];
956 FILE *stream;
957
958 if(name[0]=='!')
959 {
960 name++;
961 if(name[0]=='\0')
962 error(M_LISTFILE_MISSING);
963 if((stream=file_open(name, m_r))==NULL)
964 error(M_CANTOPEN, stream);
965 while(fgets(tmp_name, sizeof(tmp_name), stream)!=NULL)
966 {
967 tokenize_lf(tmp_name);
968 alltrim(tmp_name);
969 if(tmp_name[0]!='\0')
970 {
971 if(wild_list(&flist_exclusion, tmp_name, 0, 0, 0, NULL))
972 break;
973 }
974 }
975 fclose(stream);
976 }
977 else
978 wild_list(&flist_exclusion, name, 0, 0, 0, NULL);
979 }
980
981 /* Sets up REARJ */
982
analyze_rearj_sw(char * arg)983 static void analyze_rearj_sw(char *arg)
984 {
985 char sw;
986 char *swptr;
987
988 swptr=arg+1;
989 sw=toupper(*swptr);
990 swptr++;
991 if(sw=='D'&&*swptr=='\0')
992 delete_original_archives=1;
993 else if(sw=='E'&&*swptr=='\0')
994 internal_archives_only=1;
995 else if(sw=='F'&&*swptr=='\0')
996 cnv_diskette_archives=1;
997 else if(sw=='H'&&*swptr=='\0')
998 help_issued=1;
999 else if(sw=='O'&&*swptr=='\0')
1000 overwrite_existing=1;
1001 else if(sw=='P'&&*swptr=='\0')
1002 skip_lfn=1;
1003 else if(sw=='Q'&&*swptr=='\0')
1004 conversion_query=1;
1005 else if(sw=='R'&&*swptr=='\0')
1006 recurse_subdirs=1;
1007 else if(sw=='S'&&*swptr=='\0')
1008 skip_size_check=1;
1009 else if(sw=='V'&&*swptr=='\0')
1010 run_extract_cmd=1;
1011 else if(sw=='Z'&&*swptr=='\0')
1012 no_file_activity=1;
1013 else if(sw=='A')
1014 {
1015 if(*swptr!='\0')
1016 {
1017 case_path(swptr);
1018 acc_nested_suffixes=swptr;
1019 }
1020 convert_nested_archives=1;
1021 }
1022 else if(sw=='B'&&*swptr!='\0')
1023 {
1024 run_preunpack_cmd=1;
1025 preunpack_cmd_text=swptr;
1026 }
1027 else if(sw=='C'&&*swptr!='\0')
1028 {
1029 run_precount_cmd=1;
1030 precount_cmd_text=swptr;
1031 }
1032 else if(sw=='I')
1033 {
1034 if(*swptr!='\0')
1035 {
1036 case_path(swptr);
1037 exe_name=swptr;
1038 }
1039 chk_integrity=1;
1040 }
1041 else if(sw=='F'&&*swptr!='\0')
1042 {
1043 default_suffix=-1;
1044 case_path(swptr);
1045 suffix_override=swptr;
1046 }
1047 else if(sw=='L')
1048 {
1049 if(*swptr!='\0')
1050 {
1051 case_path(swptr);
1052 log_name=swptr;
1053 }
1054 logging_enabled=1;
1055 }
1056 else if(sw=='T'&&*swptr!='\0')
1057 {
1058 target_type=-1;
1059 case_path(swptr);
1060 target_suffix=swptr;
1061 }
1062 else if(sw=='U')
1063 {
1064 if(*swptr!='\0')
1065 {
1066 case_path(swptr);
1067 backup_extension=swptr;
1068 }
1069 update_with_backups=1;
1070 }
1071 else if(sw=='W'&&*swptr!='\0')
1072 {
1073 case_path(swptr);
1074 tmp_dir=swptr;
1075 work_directory_assigned=1;
1076 }
1077 else if(sw=='X'&&*swptr!='\0')
1078 submit_exclusion(swptr);
1079 else if(sw=='G'&&*swptr=='\0')
1080 skip_packing=1;
1081 else if(sw=='J'&&*swptr=='\0')
1082 skip_larger_output=1;
1083 else if(sw=='K'&&*swptr=='\0')
1084 skip_timestamping=1;
1085 else if(sw=='+'&&*swptr=='\0')
1086 skip_rearj_sw=1;
1087 else if(sw=='M')
1088 {
1089 pick_older=1;
1090 timestr_older=swptr;
1091 }
1092 else if(sw=='N')
1093 {
1094 pick_newer=1;
1095 timestr_newer=swptr;
1096 }
1097 else if(sw=='Y')
1098 {
1099 testing_mode=1;
1100 testing_marker=swptr;
1101 }
1102 else
1103 error(M_INVALID_SWITCH, arg);
1104 }
1105
1106 /* Parses REARJ.CFG */
1107
parse_rearj_cfg()1108 static void parse_rearj_cfg()
1109 {
1110 #if COMPILER==BCC
1111 char *cfg_path;
1112 #else
1113 char cfg_path[CCHMAXPATH];
1114 #endif
1115 char tmp_line[200];
1116 FILE *stream;
1117 int i, fakesuffix;
1118
1119 #if TARGET!=UNIX
1120 #if COMPILER==BCC
1121 if((cfg_path=searchpath(cfg_name))==NULL)
1122 error(M_CANT_FIND_CONFIG, cfg_name);
1123 #else
1124 _searchenv(cfg_name, "PATH", cfg_path);
1125 if(cfg_path[0]=='\0')
1126 error(M_CANT_FIND_CONFIG, cfg_name);
1127 #endif
1128 #else
1129 /* Attempt search in home directory first, then in /usr/local/etc. */
1130 sprintf(cfg_path, "%s/.%s", getenv("HOME"), cfg_name);
1131 if((stream=file_open(cfg_path, m_r))!=NULL)
1132 fclose(stream);
1133 else
1134 sprintf(cfg_path, "/usr/local/etc/%s", cfg_name);
1135 #endif
1136 if((stream=file_open(cfg_path, m_r))==NULL)
1137 error(M_CANTOPEN, cfg_path);
1138 msg_cprintf(H_HL|H_NFMT, M_USING_CONFIG, cfg_path);
1139 if(fgets(tmp_line, sizeof(tmp_line), stream)==NULL)
1140 total_suffixes=0;
1141 else
1142 {
1143 rewind(stream);
1144 for(i=0; i<MAX_SUFFIXES; i++)
1145 {
1146 /* ASR fix for 2.43, 24/01/2003 - the option strings may be placed before
1147 ANY extension command. */
1148 do
1149 {
1150 /* Extension */
1151 do
1152 {
1153 if(fgets(tmp_line, sizeof(tmp_line), stream)==NULL)
1154 goto no_more_exts;
1155 archivers[i].hidden_supported=0;
1156 archivers[i].subdirs_supported=0;
1157 archivers[i].manual_deletion=0; /* ASR fix */
1158 tokenize_lf(tmp_line);
1159 alltrim(tmp_line);
1160 } while (tmp_line[0]=='\0');
1161 fakesuffix=1;
1162 #ifdef COLOR_OUTPUT
1163 if(!strnicmp(tmp_line, "COLORS ", 7))
1164 {
1165 if(parse_colors(tmp_line+7))
1166 error(M_INVALID_PARAM_STR, tmp_line);
1167 }
1168 else
1169 #endif
1170 if(!strnicmp(tmp_line, "VIRUS ", 6))
1171 {
1172 if((extr_cmd_text=strdup(tmp_line+6))==NULL)
1173 error(M_OUT_OF_MEMORY);
1174 if(strchr(extr_cmd_text, PATHSEP_DEFAULT)==NULL)
1175 {
1176 msg_cprintf(0, M_NO_ANTIVIRUS_PATH);
1177 msg_cprintf(0, M_IGNORED_FOR_COMP);
1178 arj_delay(4);
1179 }
1180 }
1181 else
1182 fakesuffix=0;
1183 } while(fakesuffix);
1184 if(strlen(tmp_line)>MAX_SUFFIX)
1185 error(M_INVALID_SUFFIX, tmp_line);
1186 if((archivers[i].suffix=strdup(tmp_line))==NULL)
1187 error(M_OUT_OF_MEMORY);
1188 /* Pack command */
1189 if(fgets(tmp_line, sizeof(tmp_line), stream)==NULL)
1190 error(M_MISSING_PACK_CMD, archivers[i].suffix);
1191 tokenize_lf(tmp_line);
1192 alltrim(tmp_line);
1193 if(strlen(tmp_line)==0)
1194 error(M_INVALID_PACK_CMD, tmp_line);
1195 if(strstr(tmp_line, strform)==NULL&&strstr(tmp_line, u_strform)==NULL)
1196 error(M_NO_PACK_STRFORM, tmp_line);
1197 if((archivers[i].pack_cmd=strdup(tmp_line))==NULL)
1198 error(M_OUT_OF_MEMORY);
1199 /* Unpack command */
1200 if(fgets(tmp_line, sizeof(tmp_line), stream)==NULL)
1201 error(M_MISSING_UNPACK_CMD, archivers[i].suffix);
1202 tokenize_lf(tmp_line);
1203 alltrim(tmp_line);
1204 if(strlen(tmp_line)==0)
1205 error(M_INVALID_UNPACK_CMD, tmp_line);
1206 if(strstr(tmp_line, strform)==NULL&&strstr(tmp_line, u_strform)==NULL)
1207 error(M_NO_UNPACK_STRFORM, tmp_line);
1208 if((archivers[i].unpack_cmd=strdup(tmp_line))==NULL)
1209 error(M_OUT_OF_MEMORY);
1210 /* Option record */
1211 if(fgets(tmp_line, sizeof(tmp_line), stream)==NULL)
1212 error(M_MISSING_OPTIONS, archivers[i].suffix);
1213 tokenize_lf(tmp_line);
1214 alltrim(tmp_line);
1215 if(strpbrk(tmp_line, "Aa")!=NULL)
1216 archivers[i].hidden_supported=1;
1217 if(strpbrk(tmp_line, "Dd")!=NULL)
1218 archivers[i].subdirs_supported=1;
1219 /* ASR fix for v 2.42.05 (.tar.gz): */
1220 if(strpbrk(tmp_line, "Tt")!=NULL)
1221 archivers[i].manual_deletion=1;
1222 }
1223 no_more_exts:
1224 total_suffixes=i;
1225 }
1226 fclose(stream);
1227 }
1228
1229 /* atexit routine */
1230
final_cleanup(void)1231 static void final_cleanup(void)
1232 {
1233 if(!cleanup_initiated)
1234 {
1235 cleanup_initiated=1;
1236 if(tmpdir_malloced)
1237 release_dir(tmp_dir); /* ASR fix 14/11/2000 */
1238 if(work_dir[0]!='\0')
1239 file_chdir(work_dir);
1240 if(tmp_dir!=NULL)
1241 {
1242 if(clear_tmp_dir)
1243 unlink_all(tmp_dir);
1244 if(!work_directory_assigned)
1245 file_rmdir(tmp_dir);
1246 if(tmpdir_malloced)
1247 {
1248 free(tmp_dir); /* malloc'ed */
1249 tmpdir_malloced=0;
1250 }
1251 }
1252 }
1253 #ifdef COLOR_OUTPUT
1254 scrn_reset();
1255 #endif
1256 }
1257
1258 /* Ctrl+C handler */
1259
ctrlc_handler(SIGHDLPARAMS)1260 static void ctrlc_handler(SIGHDLPARAMS)
1261 {
1262 /* Check if we are able to honor the request. If we aren't, raise the
1263 signal again and make a speedy getaway. */
1264 if(ctrlc_busy)
1265 raise(SIGINT);
1266 else
1267 {
1268 ctrlc_initiated=1;
1269 signal(SIGINT, NULL); /* Restore default Ctrl+C handler */
1270 msg_cprintf(H_SIG, M_BREAK_SIGNALED);
1271 exit(REARJ_ERL_WARNING);
1272 }
1273 }
1274
1275 /* Main routine */
1276
main(int argc,char ** argv)1277 int main(int argc, char **argv)
1278 {
1279 int cnv_rc, exit_code;
1280 static char rearj_exe[CCHMAXPATH];
1281 int switchar;
1282 int arg;
1283 char *aptr=NULL;
1284 unsigned int i;
1285 FILE_COUNT cur_file;
1286 char tmp_name[CCHMAXPATH], src_name[CCHMAXPATH];
1287 char *fullpath;
1288 long total_gain;
1289 char *env_ptr, *env_dup, *env_tail;
1290 struct timestamp timestamp;
1291 time_t start_time, end_time;
1292 unsigned long time_diff;
1293
1294 #ifdef COLOR_OUTPUT
1295 no_colors=redirected=!is_tty(stdout);
1296 #endif
1297 msg_cprintf(0, M_REARJ_BANNER);
1298 #ifdef USE_TZSET
1299 tzset();
1300 #endif
1301 build_crc32_table();
1302 ctrlc_busy=0;
1303 lfn_supported=LFN_NOT_SUPPORTED;
1304 convert_nested_archives=0;
1305 run_precount_cmd=0;
1306 run_preunpack_cmd=0;
1307 recurse_subdirs=0;
1308 help_issued=0;
1309 no_file_activity=0;
1310 delete_original_archives=0;
1311 skip_larger_output=0;
1312 cnv_diskette_archives=0;
1313 run_extract_cmd=0;
1314 skip_rearj_sw=0;
1315 logging_enabled=0;
1316 internal_archives_only=0;
1317 pick_older=0;
1318 pick_newer=0;
1319 conversion_query=0;
1320 chk_integrity=0;
1321 overwrite_existing=0;
1322 skip_lfn=0;
1323 skip_packing=0;
1324 skip_timestamping=0;
1325 skip_size_check=0;
1326 work_directory_assigned=0;
1327 testing_mode=0;
1328 update_with_backups=0;
1329 clear_tmp_dir=0;
1330 skip_count=0;
1331 target_type=0;
1332 total_old_fsize=total_new_fsize=0L;
1333 total_files=0;
1334 ts_store(&ts_older, OS_SPECIAL, 0L);
1335 ts_newer=ts_older;
1336 ctrlc_initiated=0;
1337 is_registered=0;
1338 exit_code=REARJ_ERL_SUCCESS;
1339 log_name=rearj_log;
1340 default_suffix=-1;
1341 backup_extension=backup_ext;
1342 #ifndef SKIP_GET_EXE_NAME
1343 get_exe_name(rearj_exe);
1344 #else
1345 get_exe_name(rearj_exe, argv[0]);
1346 #endif
1347 exe_name=rearj_exe;
1348 target_suffix=NULL;
1349 suffix_override=NULL;
1350 extract_cmd_text=NULL;
1351 precount_cmd_text=NULL;
1352 preunpack_cmd_text=NULL;
1353 tmp_dir=NULL;
1354 testing_marker=NULL;
1355 acc_nested_suffixes=NULL;
1356 work_dir[0]='\0';
1357 timestr_older=timestr_newer=nullstr;
1358 flist_init(&flist_exclusion, EXCL_FLIST_SIZE, 0, 0);
1359 atexit(final_cleanup);
1360 parse_reg_key();
1361 detect_lfns();
1362 is_registered=reg_validation(regdata+REG_KEY1_SHIFT, regdata+REG_KEY2_SHIFT, regdata+REG_NAME_SHIFT, regdata+REG_HDR_SHIFT);
1363 if(!is_registered&&!msg_strcmp((FMSG *)regdata+REG_KEY2_SHIFT, M_REG_TYPE))
1364 msg_cprintf(0, M_REGISTERED_TO, regdata+REG_NAME_SHIFT);
1365 limit=20;
1366 total_suffixes=0;
1367 if(signal(SIGINT, ctrlc_handler)==SIG_ERR)
1368 error(M_SIGNAL_FAILED);
1369 limit=0;
1370 if(regdata[REG_NAME_SHIFT]=='\0')
1371 is_registered=1;
1372 if(!reg_validation(single_spc, single_spc, single_spc, regdata+REG_HDR_SHIFT))
1373 is_registered=2;
1374 n_args=0;
1375 switchar=get_sw_char();
1376 for(arg=1; arg<argc; arg++)
1377 {
1378 aptr=argv[arg];
1379 if(aptr[0]==switchar&&aptr[1]=='+'&&aptr[2]=='\0')
1380 skip_rearj_sw=0;
1381 }
1382 if((env_ptr=getenv(rearj_sw))!=NULL)
1383 {
1384 env_dup=strdup(env_ptr);
1385 msg_cprintf(H_HL|H_NFMT, M_USING_REARJ_SW, env_dup);
1386 for(env_ptr=env_dup; *env_ptr!='\0'; env_ptr++)
1387 if(*env_ptr==' ')
1388 *env_ptr='\0'; /* Tokenize by spaces */
1389 env_tail=env_ptr;
1390 env_ptr=env_dup;
1391 while(env_ptr<env_tail)
1392 {
1393 while(*env_ptr=='\0')
1394 env_ptr++;
1395 if(env_ptr<env_tail)
1396 {
1397 if(switchar=='-')
1398 name_to_hdr(env_ptr);
1399 if(*env_ptr==switchar)
1400 analyze_rearj_sw(aptr);
1401 while(*env_ptr!='\0'&&env_ptr<env_tail)
1402 env_ptr++;
1403 }
1404 }
1405 }
1406 for(arg=1; arg<argc; arg++)
1407 {
1408 aptr=argv[arg];
1409 if(switchar=='-')
1410 name_to_hdr(aptr);
1411 if(aptr[0]==switchar)
1412 analyze_rearj_sw(aptr);
1413 else
1414 {
1415 if(n_args>=MAX_ARGS)
1416 error(M_ARGTABLE_OVERFLOW);
1417 arg_ptr[n_args++]=aptr;
1418 }
1419 }
1420 if(skip_lfn)
1421 lfn_supported=LFN_NOT_SUPPORTED;
1422 if(chk_integrity)
1423 exit(check_integrity(rearj_exe));
1424 if(help_issued||n_args==0)
1425 {
1426 msg_cprintf(0, strform, M_REARJ_COMMANDS);
1427 msg_cprintf(0, strform, M_REARJ_RCODES);
1428 exit(REARJ_ERL_SUCCESS);
1429 }
1430 if(delete_original_archives&&testing_mode)
1431 error(M_YD_CMD_CONFLICT);
1432 if(testing_mode&&testing_marker!=NULL&&!logging_enabled)
1433 error(M_LY_CMD);
1434 parse_rearj_cfg();
1435 if(run_extract_cmd&&extract_cmd_text==NULL)
1436 error(M_NO_V_CMD, cfg_name);
1437 if(suffix_override!=NULL)
1438 {
1439 default_suffix=-1;
1440 for(i=0; i<total_suffixes; i++)
1441 {
1442 if(!strcmp_os(suffix_override, archivers[i].suffix))
1443 default_suffix=i;
1444 }
1445 if(default_suffix<0)
1446 error(M_INVALID_F_SUFFIX, suffix_override);
1447 }
1448 if(target_suffix!=NULL)
1449 {
1450 target_type=-1;
1451 for(i=limit; i<total_suffixes; i++)
1452 {
1453 if(!strcmp_os(target_suffix, archivers[i].suffix))
1454 target_type=i;
1455 }
1456 if(target_type<0)
1457 error(M_INVALID_T_SUFFIX, target_suffix);
1458 }
1459 if(pick_older||pick_newer)
1460 {
1461 if(timestr_older[0]!='\0')
1462 convert_strtime(&ts_older, timestr_older);
1463 if(timestr_newer[0]!='\0')
1464 convert_strtime(&ts_newer, timestr_newer);
1465 if(timestr_older[0]=='\0'||timestr_newer[0]=='\0')
1466 {
1467 arj_getdate(&x_date);
1468 make_timestamp(×tamp, x_date.da_year, x_date.da_mon, x_date.da_day,
1469 0, 0, 0);
1470 if(timestr_newer[0]=='\0')
1471 ts_newer=timestamp;
1472 if(timestr_older[0]=='\0')
1473 ts_older=timestamp;
1474 }
1475 }
1476 if(file_getcwd(work_dir)==NULL)
1477 error(M_GETCWD_FAILED);
1478 if(no_file_activity)
1479 msg_cprintf(0, M_SIMULATION_MODE);
1480 flist_init(&flist_main, LARGE_FLIST_SIZE, n_args>1, 1);
1481 for(i=limit; i<n_args; i++)
1482 {
1483 flush_kbd();
1484 if(arg_ptr[i][0]=='!')
1485 {
1486 if(arg_ptr[i][1]=='\0')
1487 error(M_NO_LISTFILE);
1488 if((liststream=file_open(arg_ptr[i]+1, m_r))==NULL)
1489 error(M_CANTOPEN, arg_ptr[i]+1);
1490 while(fgets(name_fetch, CCHMAXPATH, liststream)!=NULL)
1491 {
1492 tokenize_lf(name_fetch);
1493 alltrim(name_fetch);
1494 if(name_fetch[0]!='\0')
1495 {
1496 strcpy(tmp_name, name_fetch);
1497 if(wild_list(&flist_main, tmp_name, 0, 1, recurse_subdirs, NULL))
1498 break;
1499 }
1500 }
1501 fclose(liststream);
1502 }
1503 else
1504 {
1505 strcpy(tmp_name, arg_ptr[i]);
1506 if(wild_list(&flist_main, tmp_name, 0, 1, recurse_subdirs, NULL))
1507 break;
1508 }
1509 }
1510 if(flist_main.files==0)
1511 {
1512 msg_cprintf(0, internal_archives_only?M_NO_FILES_INT:M_NO_FILES);
1513 exit(internal_archives_only?REARJ_ERL_SUCCESS:REARJ_ERL_WARNING);
1514 }
1515 time(&start_time);
1516 if(logging_enabled)
1517 {
1518 if((logstream=file_open(log_name, m_a))==NULL)
1519 error(M_CANTOPEN, log_name);
1520 arj_gettime(&log_ts);
1521 if(testing_marker!=NULL)
1522 if(fprintf(logstream, M_LOGENTRY_MARKER, timeseq, archivers[target_type].suffix, testing_marker)<=0)
1523 error(M_CANT_WRITE_LOG);
1524 if(fprintf(logstream, M_LOGENTRY_HEADER, timeseq, archivers[target_type].suffix)<=0)
1525 error(M_CANT_WRITE_LOG);
1526 }
1527 if(cnv_diskette_archives&&count_files()>0)
1528 msg_cprintf(0, M_CWD_MUST_BE_EMPTY);
1529 if(tmp_dir==NULL)
1530 {
1531 /* BUGBUG: this comes from a NetBSD patch. Originally a check for NO_MKDTEMP
1532 was suggested, but where are we expected to define it under DOS? --
1533 ASR fix 25/01/2004 */
1534 #ifdef HAVE_MKDTEMP
1535 tmp_dir=mkdtemp("/tmp/arj.XXXXXX"); /* BUGBUG: hardcoded location? */
1536 #else
1537 tmp_dir=tmpnam(NULL);
1538 if(file_mkdir(tmp_dir))
1539 error(M_CANT_MKDIR, tmp_dir);
1540 #endif
1541 }
1542 else
1543 {
1544 if(file_chdir(tmp_dir))
1545 error(M_CANT_CHDIR, tmp_dir);
1546 if(count_files()>0)
1547 error(M_WORK_DIR_NOT_EMPTY, tmp_dir);
1548 if(file_chdir(work_dir))
1549 error(M_CANT_CHDIR, work_dir);
1550 }
1551 if((fullpath=(char *)malloc(CCHMAXPATH))==NULL)
1552 error(M_OUT_OF_MEMORY);
1553 if(truename(fullpath, tmp_dir))
1554 error(M_CANT_GET_FULL_PATH);
1555 tmp_dir=fullpath;
1556 clear_tmp_dir=1;
1557 tmpdir_malloced=1; /* Introduced by ASR */
1558 for(cur_file=0; cur_file<flist_main.files; cur_file++)
1559 {
1560 flush_kbd();
1561 if(fetch_keystrokes())
1562 {
1563 msg_cprintf(H_PROMPT, M_OK_TO_QUIT);
1564 if(query_action())
1565 {
1566 msg_cprintf(H_OPER, M_QUITTING);
1567 exit(REARJ_ERL_WARNING);
1568 }
1569 }
1570 retrieve_entry(src_name, &flist_main, cur_file);
1571 ts_store(×tamp, OS, file_getftime(src_name));
1572 if((!pick_newer||!ts_valid(ts_newer)||ts_cmp(×tamp, &ts_newer)>=0)&&
1573 (!pick_older||!ts_valid(ts_older)||ts_cmp(×tamp, &ts_older)<0))
1574 {
1575 cnv_rc=convert_archive(src_name);
1576 if(cnv_rc!=REARJ_ERL_SUCCESS)
1577 {
1578 skip_count++;
1579 log_as_skipped(src_name, cnv_rc);
1580 if(exit_code==REARJ_ERL_SUCCESS&&(!internal_archives_only||cnv_rc!=REARJ_ERL_UNCONFIGURED))
1581 exit_code=cnv_rc;
1582 }
1583 release_dir(tmp_dir); /* ASR fix 14/11/2000 */
1584 if(file_chdir(work_dir))
1585 error(M_CANT_CHDIR, work_dir);
1586 unlink_all(tmp_dir);
1587 if(file_rmdir(tmp_dir))
1588 msg_cprintf(H_ERR, M_CANT_RMDIR, tmp_dir);
1589 if(file_mkdir(tmp_dir))
1590 error(M_CANT_MKDIR, tmp_dir);
1591 }
1592 }
1593 if(!work_directory_assigned)
1594 {
1595 if(file_rmdir(tmp_dir))
1596 msg_cprintf(H_ERR, M_CANT_RMDIR, tmp_dir);
1597 }
1598 if(tmpdir_malloced)
1599 {
1600 free(tmp_dir);
1601 tmpdir_malloced=0;
1602 }
1603 tmp_dir=NULL;
1604 time(&end_time);
1605 time_diff=sub_time(end_time, start_time);
1606 total_gain=(long)(total_old_fsize-total_new_fsize);
1607 msg_cprintf(H_HL|H_NFMT, M_TOTAL_SECONDS, time_diff);
1608 msg_cprintf(H_HL|H_NFMT, M_TOTAL_CONVERTED, total_files);
1609 msg_cprintf(H_HL|H_NFMT, M_TOTAL_SKIPPED, skip_count);
1610 msg_cprintf(H_HL|H_NFMT, M_OLD_SIZE, total_old_fsize);
1611 msg_cprintf(H_HL|H_NFMT, M_NEW_SIZE, total_new_fsize);
1612 msg_cprintf(H_HL|H_NFMT, M_SAVINGS_SIZE, total_gain);
1613 if(logging_enabled)
1614 {
1615 arj_gettime(&log_ts);
1616 if(fprintf(logstream, M_LOGENTRY_FOOTER, timeseq, archivers[target_type].suffix, total_old_fsize, total_new_fsize, total_gain, time_diff)<=0)
1617 error(M_CANT_WRITE_LOG);
1618 fclose(logstream);
1619 }
1620 flist_cleanup_proc(&flist_main);
1621 flist_cleanup_proc(&flist_exclusion);
1622 return((skip_count>0)?exit_code:REARJ_ERL_SUCCESS);
1623 }
1624