1 /*
2 * $Id: arj_user.c,v 1.11 2004/06/18 16:19:37 andrew_belov Exp $
3 * ---------------------------------------------------------------------------
4 * High-level routines that perform ARJ command processing are located in this
5 * module. It may be partially inherited by ARJSFXV and ARJSFX.
6 *
7 */
8
9 #include "arj.h"
10
11 DEBUGHDR(__FILE__) /* Debug information block */
12
13 /* Operating system names used in short listings. For their numerical
14 equivalents see ARJ_USER.H. */
15
16 static char *host_os_names[]={"MS-DOS", "PRIMOS", "UNIX", "AMIGA", "MAC-OS",
17 "OS/2", "APPLE GS", "ATARI ST", "NEXT",
18 "VAX VMS", "WIN95", "WIN32", NULL};
19
20 /* Binary/Text/... - type signature */
21
22 #if SFX_LEVEL>=ARJSFXV
23 static char type_sig[]={'B', 'T', '?', 'D', 'V', 'C', 'U'};
24 #else
25 static char type_sig[]={'B', 'T', '?', 'D'};
26 #endif
27
28 /* Combined volume/extfile flags for UNIX-mode lists */
29
30 #if TARGET==UNIX&&SFX_LEVEL>=ARJSFXV
31 static char vfext_flags[]={' ', '>', '<', '*'};
32 #endif
33
34 /* List order */
35
36 #if SFX_LEVEL>=ARJSFXV
37 #if TARGET==UNIX
38 #define LFLAGS is_chapter?'*':' ', is_in_subdir?'+':' ', method, enc_type, vfext_flags[(is_volume?1:0)+(is_extfile?2:0)]
39 #else
40 #define LFLAGS is_chapter?'*':' ', type_sig[uf_type], is_in_subdir?'+':' ', method, enc_type, is_volume?'V':' ', is_extfile?'X':' '
41 #endif
42 #else
43 #if TARGET==UNIX
44 #define LFLAGS is_in_subdir?'+':' ', method, enc_type
45 #else
46 #define LFLAGS type_sig[uf_type], is_in_subdir?'+':' ', method, enc_type
47 #endif
48 #endif
49 #if TARGET!=UNIX
50 #define LMODESTR file_crc, mode_str
51 #else
52 #define LMODESTR mode_str
53 #endif
54
55 /* Y2K mess */
56
57 #if SFX_LEVEL>=ARJSFXV
58 static char century_sig[]={' ', ' ', '1'}; /* 20th/21st/22nd centuries */
59 #endif
60
61 /* Misc. */
62
63 static char volfmt_2digit[]="%s%02d";
64 static char volfmt_3digit[]="%s%03d";
65 static char volfmt_4digit[]="%s%4d";
66 static char stub_fmt[]="%s%03d%s";
67 static char bell[]="\a";
68
69 /* Local variables */
70
71 static FILE_COUNT total_processed; /* Number of already processed files */
72 static unsigned long FAR *order_list; /* List of files to order */
73 #if SFX_LEVEL>=ARJ
74 static FILE_COUNT cf_num; /* Current file # */
75 #endif
76 static FILE_COUNT order_fcap; /* Size of order array */
77 static FILE_COUNT order_fcount; /* # of files in order array */
78 static FILE_COUNT vol_file_num;
79 static unsigned long saved_timestamp;
80 #if SFX_LEVEL>=ARJ
81 static char *arjsec_signature;
82 #else
83 static char arjsec_signature[ARJSEC_SIG_MAXLEN];
84 #endif
85 static unsigned long first_file_offset; /* Offset of first file within arch. */
86
87 #if SFX_LEVEL>=ARJSFXV
88 static int total_os;
89 static int is_removable; /* 1 if the current archive is on a
90 removable media */
91 #endif
92
93 /* Since ARJSFX has totally static allocation, the cache buffers are statically
94 allocated, too */
95
96 #if SFX_LEVEL<=ARJSFX&&!defined(NO_CACHING)
97 static char cache_buf[VBUF_SFX];
98 #endif
99
100 /* Return 1 if the given system is similar to ARJ host OS */
101
test_host_os(int os)102 int test_host_os(int os)
103 {
104 int i;
105
106 for(i=0; friendly_systems[i]>=0; i++)
107 {
108 if(friendly_systems[i]==os)
109 return(1);
110 }
111 return(0);
112 }
113
114 #if SFX_LEVEL>=ARJ
115
116 /* Allocates RAM for and composes the protection filename */
117
form_prot_name()118 char *form_prot_name()
119 {
120 int name_len;
121 char *result; /* Address of newly-formed buffer */
122 char *tmp_ptr;
123
124 name_len=strlen(archive_name)+far_strlen(M_PROT_SUFFIX)+2;
125 strcpy(result=malloc_msg(name_len), archive_name);
126 name_len=split_name(result, NULL, NULL);
127 if((tmp_ptr=strchr(&result[name_len], '.'))==NULL)
128 msg_strcat(result, M_PROT_SUFFIX);
129 else if(tmp_ptr[1]=='\0')
130 msg_strcat(result, M_PROT_SUFFIX);
131 else
132 tmp_ptr[1]=M_PROT_SUFFIX[1]; /* Substitute first letter of extension
133 with the one from prot_name suffix */
134 return(result);
135 }
136
137 #endif
138
139 #if SFX_LEVEL>=ARJSFXV
140
141 /* Checks for the occurence of the destination file, returns 1 if the file can
142 be extracted, 0 if it already exists and must be skipped */
143
destfile_extr_validation()144 int destfile_extr_validation()
145 {
146 char tmp_name[FILENAME_MAX];
147
148 if(!new_files_only)
149 return(1);
150 strcpy(tmp_name, filename);
151 add_base_dir(tmp_name);
152 return(!file_exists(tmp_name));
153 }
154
155 #endif
156
157 #if SFX_LEVEL>=ARJ
158
159 /* Writes an index file entry */
160
write_index_entry(char * prefix)161 void write_index_entry(char *prefix)
162 {
163 int bytes_written;
164
165 if(create_index)
166 {
167 if(prefix[0]=='\0')
168 bytes_written=msg_fprintf(idxstream, M_IDXFMT_NP, filename);
169 else
170 bytes_written=msg_fprintf(idxstream, (strlen(prefix)>3)?M_IDXFMT_LONG:M_IDXFMT_SHORT, prefix, filename);
171 if(bytes_written==0)
172 error(M_DISK_FULL);
173 }
174 }
175
176 #endif
177
178 /* Outputs the listing header */
179
show_list_header()180 static void show_list_header()
181 {
182 #if SFX_LEVEL>=ARJ
183 if(std_list_cmd)
184 {
185 if(verbose_display==VERBOSE_STD)
186 return;
187 if(verbose_display==VERBOSE_ENH)
188 msg_cprintf(0, M_VLIST_P1);
189 else
190 {
191 msg_cprintf(0, M_VLIST_HDR);
192 msg_cprintf(0, M_VLIST_P1);
193 }
194 }
195 else
196 msg_cprintf(0, M_LIST_P1);
197 msg_cprintf(0, verbose_display?M_LIST_P2_CHAP:M_LIST_P2);
198 #else
199 if(std_list_cmd)
200 {
201 msg_cprintf(0, M_VLIST_HDR);
202 msg_cprintf(0, M_VLIST_P1);
203 }
204 else
205 msg_cprintf(0, M_LIST_P1);
206 msg_cprintf(0, M_LIST_P2);
207 #endif
208 msg_cprintf(0, M_LIST_SEPARATOR);
209 }
210
211 /* Picks the most favorable century character */
212
213 #if SFX_LEVEL>=ARJSFXV
pick_century(char * timetext)214 static char pick_century(char *timetext)
215 {
216 int n_centuries;
217
218 #if SFX_LEVEL>=ARJ
219 switch(skip_century)
220 {
221 case CENT_DEFAULT:
222 if(timetext[0]=='2'&&timetext[1]=='0')
223 n_centuries=1;
224 else if(timetext[0]=='2'&&timetext[1]=='1')
225 n_centuries=2;
226 else
227 n_centuries=0;
228 return(century_sig[n_centuries]);
229 case CENT_SKIP:
230 return(' ');
231 case CENT_SMART:
232 if(timetext[0]=='1'||(timetext[0]=='2'&&timetext[1]=='0'&&timetext[2]<'7'))
233 return(' ');
234 else
235 return(timetext[1]);
236 }
237 return(' ');
238 #elif SFX_LEVEL>=ARJSFXV
239 if(timetext[0]=='2'&&timetext[1]=='0')
240 n_centuries=1;
241 else if(timetext[0]=='2'&&timetext[1]=='1')
242 n_centuries=2;
243 else
244 n_centuries=0;
245 return(century_sig[n_centuries]);
246 #endif
247 }
248 #endif
249
250 /* List command itself */
251
252 #if SFX_LEVEL>=ARJSFXV
list_cmd(FILE_COUNT lnum,FILE_COUNT fnum)253 static int list_cmd(FILE_COUNT lnum, FILE_COUNT fnum)
254 #else
255 static void list_cmd()
256 #endif
257 {
258 int is_in_subdir;
259 #if SFX_LEVEL>=ARJSFXV
260 int is_volume, is_extfile;
261 int is_chapter; /* Chapter or backup */
262 char FAR *raw_ea;
263 unsigned int raw_ea_size;
264 struct ext_hdr FAR *p_eh;
265 #endif
266 #if SFX_LEVEL>=ARJ
267 char tmp_name[FILENAME_MAX];
268 #endif
269 int uf_type;
270 unsigned int ratio;
271 unsigned int entry;
272 char timetext[22];
273 char mode_str[16]; /* ASR fix for 2.77 */
274 char *tmp_ptr; /* Either from the host_os_names list or
275 nullstr */
276 char enc_type;
277
278 #if SFX_LEVEL>=ARJSFXV
279 if(!destfile_extr_validation())
280 return(0);
281 #endif
282 #if SFX_LEVEL>=ARJSFXV
283 if(lnum==0)
284 show_list_header();
285 #else
286 if(total_files==0)
287 show_list_header();
288 #endif
289 #if SFX_LEVEL>=ARJ
290 for(total_os=0; host_os_names[total_os]!=NULL; total_os++);
291 #endif
292 enc_type=(arj_flags&GARBLED_FLAG)?ext_hdr_flags+'0':' ';
293 #if SFX_LEVEL>=ARJSFXV
294 is_volume=(arj_flags&VOLUME_FLAG)?1:0;
295 is_extfile=(arj_flags&EXTFILE_FLAG)?1:0;
296 #endif
297 #if SFX_LEVEL>=ARJ
298 is_chapter=(total_chapters!=0&&((int)chapter_number<total_chapters||(int)ext_flags>total_chapters))?1:0;
299 #elif SFX_LEVEL==ARJSFXV
300 is_chapter=(arj_flags&BACKUP_FLAG)?1:0;
301 #endif
302 is_in_subdir=entry_pos>0;
303 ratio=calc_percentage(compsize, origsize);
304 total_uncompressed+=origsize;
305 total_compressed+=compsize;
306 #if SFX_LEVEL>=ARJSFXV
307 if(chk_free_space)
308 disk_space_used+=((origsize+(unsigned long)alloc_unit_size-1L)/(unsigned long)alloc_unit_size)*(unsigned long)alloc_unit_size;
309 #endif
310 timestamp_to_str(timetext, &ftime_stamp);
311 #if SFX_LEVEL>=ARJ
312 uf_type=(file_type==ARJT_BINARY||file_type==ARJT_TEXT||file_type==ARJT_DIR||file_type==ARJT_UXSPECIAL||file_type==ARJT_LABEL||file_type==ARJT_CHAPTER)?file_type:ARJT_COMMENT;
313 #elif SFX_LEVEL==ARJSFXV
314 uf_type=(file_type==ARJT_BINARY||file_type==ARJT_TEXT||file_type==ARJT_DIR||file_type==ARJT_UXSPECIAL||file_type==ARJT_LABEL)?file_type:ARJT_DIR;
315 #else
316 uf_type=(file_type==ARJT_BINARY||file_type==ARJT_TEXT||file_type==ARJT_DIR)?file_type:ARJT_DIR;
317 #endif
318 /* In ARJSFX, there are no non-host OSes */
319 #if SFX_LEVEL<=ARJSFX
320 mode_str[0]='\0';
321 #else
322 msg_strcpy(mode_str, M_EMPTY_ATTR);
323 #endif
324 if(test_host_os(host_os))
325 {
326 get_mode_str(mode_str, file_mode.native);
327 #if TARGET==UNIX
328 if(file_type==ARJT_BINARY||file_type==ARJT_TEXT)
329 mode_str[0]='-';
330 else
331 mode_str[0]=tolower(type_sig[uf_type]);
332 #endif
333 }
334 #if SFX_LEVEL>=ARJ
335 strcpy(tmp_name, filename);
336 if((uf_type==ARJT_BINARY||uf_type==ARJT_TEXT||uf_type==ARJT_DIR||file_type==ARJT_UXSPECIAL)&&(host_os==OS_WIN95||host_os==OS_WINNT))
337 {
338 total_longnames++;
339 if(volume_flag_set)
340 split_longnames++;
341 }
342 #endif
343 if(std_list_cmd)
344 {
345 #if SFX_LEVEL>=ARJSFXV
346 #if SFX_LEVEL>=ARJ
347 if(verbose_display!=VERBOSE_ENH)
348 {
349 if(verbose_display==VERBOSE_NONE)
350 {
351 #endif
352 msg_cprintf(H_HL, M_LIST_NUM_FMT, fnum);
353 #if SFX_LEVEL>=ARJ
354 }
355 #endif
356 #if SFX_LEVEL>=ARJ
357 entry=(exclude_paths==EP_PATH)?(unsigned int)entry_pos:0;
358 msg_cprintf(H_HL, M_FILENAME_FORM, tmp_name+entry);
359 #else
360 entry=0;
361 msg_cprintf(H_HL, M_FILENAME_FORM, filename);
362 #endif
363 #if SFX_LEVEL>=ARJ
364 if(verbose_display==VERBOSE_STD)
365 return(1);
366 #endif
367 if(comment[0]!='\0')
368 {
369 display_comment(comment);
370 #if SFX_LEVEL>=ARJ
371 msg_cprintf(0, (FMSG *)lf);
372 #endif
373 }
374 #if SFX_LEVEL>=ARJ
375 if(ext_flags!=0)
376 msg_cprintf(H_HL|H_NFMT, M_CHAPTER_LIST_FMT, (int)ext_flags, (int)chapter_number);
377 #endif
378 #if SFX_LEVEL>=ARJ
379 }
380 #endif
381 tmp_ptr=((int)host_os>=total_os)?nullstr:host_os_names[host_os];
382 msg_cprintf(H_HL|H_NFMT, M_REV_OS_FMT, (int)arj_nbr, tmp_ptr);
383 #else
384 msg_cprintf(H_HL, M_VERBOSE_NAME_FMT, filename);
385 if(comment[0]!='\0')
386 {
387 if(show_ansi_comments)
388 printf(strform, comment);
389 else
390 display_comment(comment);
391 }
392 msg_cprintf(H_HL|H_NFMT, M_REV_OS_FMT, (int)arj_nbr, host_os_names[host_os]);
393 #endif
394 }
395 else
396 #if SFX_LEVEL>=ARJ
397 msg_cprintf(0, (strlen(tmp_name+entry_pos)>12)?M_LONG_NAME_FMT:M_SHORT_NAME_FMT, tmp_name+entry_pos);
398 #elif SFX_LEVEL>=ARJSFXV
399 msg_cprintf(0, (strlen(filename+entry_pos)>12)?M_LONG_NAME_FMT:M_SHORT_NAME_FMT, filename+entry_pos);
400 #else
401 msg_cprintf(0, (strlen(list_adapted_name)>12)?M_LONG_NAME_FMT:M_SHORT_NAME_FMT, list_adapted_name);
402 #endif
403 #if SFX_LEVEL>=ARJ
404 if(verbose_display)
405 msg_cprintf(H_HL|H_NFMT, M_VERBOSE_LIST_LINE, origsize, compsize, ratio/1000, ratio%1000, pick_century(timetext), timetext+2, (int)ext_flags, (int)chapter_number, mode_str, LFLAGS);
406 else
407 #endif
408 #if SFX_LEVEL>=ARJSFXV
409 msg_cprintf(H_HL|H_NFMT, M_STD_LIST_LINE, origsize, compsize, ratio/1000, ratio%1000, pick_century(timetext), timetext+2, LMODESTR, LFLAGS);
410 #else
411 msg_cprintf(H_HL|H_NFMT, M_STD_LIST_LINE, origsize, compsize, ratio/1000, ratio%1000, timetext+2, LMODESTR, LFLAGS);
412 #endif
413 #if SFX_LEVEL>=ARJ
414 if(std_list_cmd&&verbose_display==VERBOSE_ENH)
415 {
416 if((tmp_ptr=strrchr(tmp_name, '.'))==NULL)
417 tmp_ptr=nullstr;
418 msg_cprintf(H_HL|H_NFMT, M_PATH_LIST_FMT, tmp_ptr, tmp_name+entry_pos, filename);
419 }
420 msg_cprintf(0, (FMSG *)lf);
421 if(std_list_cmd&&ts_valid(atime_stamp)&&verbose_display!=VERBOSE_ENH)
422 {
423 timestamp_to_str(timetext, &atime_stamp);
424 msg_cprintf(H_HL|H_NFMT, M_ATIME_FMT, pick_century(timetext), timetext+2);
425 timestamp_to_str(timetext, &ctime_stamp);
426 msg_cprintf(H_HL|H_NFMT, M_CTIME_FMT, pick_century(timetext), timetext+2);
427 }
428 /* Report the extended headers */
429 if(std_list_cmd&&valid_ext_hdr&&!(arj_flags&VOLUME_FLAG)&&verbose_display!=VERBOSE_ENH)
430 {
431 /* UNIX special files */
432 if((p_eh=eh_lookup(eh, UXSPECIAL_ID))!=NULL)
433 uxspecial_stats(p_eh->raw, UXSTATS_LONG);
434 /* Owner (character) */
435 if((p_eh=eh_lookup(eh, OWNER_ID))!=NULL)
436 owner_stats(p_eh->raw, 1);
437 /* Owner (UID/GID). The archiving won't allow simultaneous storage of both
438 numeric and character IDs */
439 if((p_eh=eh_lookup(eh, OWNER_ID_NUM))!=NULL)
440 owner_stats(p_eh->raw, 0);
441 /* EAs */
442 if((p_eh=eh_lookup(eh, EA_ID))!=NULL&&(!file_garbled||garble_enabled))
443 {
444 raw_ea=unpack_ea(p_eh);
445 raw_ea_size=get_eablk_size(raw_ea);
446 ratio=calc_percentage((unsigned long)p_eh->size, (unsigned long)raw_ea_size);
447 msg_cprintf(H_HL|H_NFMT, M_EA_LIST, raw_ea_size, p_eh->size, ratio/1000, ratio%1000, get_num_eas(raw_ea));
448 farfree(raw_ea);
449 }
450 }
451 write_index_entry(nullstr);
452 #else
453 #if SFX_LEVEL>=ARJSFXV
454 msg_cprintf(0, (FMSG *)lf);
455 #endif
456 #endif
457 #if SFX_LEVEL>=ARJSFXV
458 return(1);
459 #endif
460 }
461
462 /* A simplified set of filelist routines */
463
464 #if SFX_LEVEL<=ARJSFX
465
466 /* Looks for the given fully-qualified filename in the file argument array */
467
f_arg_lookup(char * name)468 static int f_arg_lookup(char *name)
469 {
470 int i;
471
472 for(i=0; i<sflist_args; i++)
473 if(!strcmp_os(name, sflist[i]))
474 return(i+1);
475 return(0);
476 }
477
478 /* Adds a new filename to the arg table if it's not present there */
479
add_f_arg(char * name)480 static void add_f_arg(char *name)
481 {
482 char *nptr;
483
484 if(f_arg_lookup(name)==0)
485 {
486 if((nptr=(char *)malloc(strlen(name)+1))==NULL)
487 error(M_OUT_OF_MEMORY);
488 strcpy(nptr, name);
489 sflist[sflist_args++]=nptr;
490 }
491 }
492
493 #endif
494
495 #if SFX_LEVEL>=ARJ
496
497 /* Checks if an archived file can be processed, returns 1 if yes. */
498
processing_validation()499 static int processing_validation()
500 {
501 int rc;
502 int entry;
503
504 if(filter_attrs)
505 {
506 rc=0;
507 if(file_attr_mask&TAG_WINLFN&&(host_os==OS_WIN95||host_os==OS_WINNT)&&
508 (file_type==ARJT_DIR||file_type==ARJT_UXSPECIAL||file_type==ARJT_BINARY||file_type==ARJT_TEXT))
509 rc=1;
510 if(file_attr_mask&TAG_LABEL&&file_type==ARJT_LABEL)
511 rc=1;
512 if(file_attr_mask&TAG_CHAPTER&&file_type==ARJT_CHAPTER)
513 rc=1;
514 if(file_attr_mask&TAG_DIREC&&file_type==ARJT_DIR)
515 rc=1;
516 if(file_attr_mask&TAG_UXSPECIAL&&file_type==ARJT_UXSPECIAL)
517 rc=1;
518 if(file_attr_mask&TAG_NORMAL&&(file_type==ARJT_BINARY||file_type==ARJT_TEXT))
519 {
520 if((file_mode.dos&FATTR_DIREC)!=FATTR_DIREC&&
521 (file_mode.dos&FATTR_RDONLY)!=FATTR_RDONLY&&
522 (file_mode.dos&FATTR_SYSTEM)!=FATTR_SYSTEM&&
523 (file_mode.dos&FATTR_HIDDEN)!=FATTR_HIDDEN&&
524 file_type!=ARJT_UXSPECIAL)
525 rc=1;
526 }
527 if(file_attr_mask&TAG_RDONLY&&file_mode.dos&FATTR_RDONLY)
528 rc=1;
529 if(file_attr_mask&TAG_HIDDEN&&file_mode.dos&FATTR_HIDDEN)
530 rc=1;
531 if(file_attr_mask&TAG_SYSTEM&&file_mode.dos&FATTR_SYSTEM)
532 rc=1;
533 if(file_attr_mask&TAG_ARCH&&(file_mode.dos&FATTR_ARCH)!=FATTR_ARCH)
534 return(0);
535 if(file_attr_mask&TAG_NOT_ARCH&&file_mode.dos&FATTR_ARCH)
536 return(0);
537 if(!rc)
538 return(0);
539 }
540 if(ts_valid(tested_ftime_newer)&&(filter_same_or_newer==TCHECK_FTIME||filter_same_or_newer==TCHECK_NDAYS))
541 {
542 if(ts_cmp(&ftime_stamp, &tested_ftime_newer)<0)
543 return(0);
544 }
545 if(ts_valid(tested_ftime_older)&&(filter_older==TCHECK_FTIME||filter_older==TCHECK_NDAYS))
546 {
547 if(ts_cmp(&ftime_stamp, &tested_ftime_older)>=0)
548 return(0);
549 }
550 /* ctime */
551 if(ts_valid(tested_ftime_newer)&&filter_same_or_newer==TCHECK_CTIME)
552 {
553 if(ts_cmp(&ctime_stamp, &tested_ftime_newer)<0)
554 return(0);
555 }
556 if(ts_valid(tested_ftime_older)&&filter_older==TCHECK_CTIME)
557 {
558 if(ts_cmp(&ctime_stamp, &tested_ftime_older)>=0)
559 return(0);
560 }
561 /* atime */
562 if(ts_valid(tested_ftime_newer)&&filter_same_or_newer==TCHECK_ATIME)
563 {
564 if(ts_cmp(&atime_stamp, &tested_ftime_newer)<0)
565 return(0);
566 }
567 if(ts_valid(tested_ftime_older)&&filter_older==TCHECK_ATIME)
568 {
569 if(ts_cmp(&atime_stamp, &tested_ftime_older)>=0)
570 return(0);
571 }
572 entry=(add_command&&exclude_paths==EP_BASEDIR)?strlen(target_dir):0;
573 return(!flist_find(&flist_exclusion, filename+entry));
574 }
575
576 /* Retrieves total statistics for the archive */
577
get_totals()578 static void get_totals()
579 {
580 FILE_COUNT cur_file;
581
582 if(add_command)
583 {
584 total_size=0L;
585 total_written=0L;
586 display_totals=1;
587 for(cur_file=0; cur_file<flist_main.files; cur_file++)
588 {
589 flist_retrieve(filename, &properties, &flist_main, cur_file);
590 if(match_attrib(&properties))
591 total_size+=properties.fsize;
592 }
593 }
594 }
595
596 /* Basic archive processing routine */
597
process_archive(int cmd,int no_in_arch)598 static void process_archive(int cmd, int no_in_arch)
599 {
600 FILE_COUNT pf_num;
601 FILE_COUNT cur_file;
602 int val_result;
603 int update_perm; /* Update permission */
604 int pack_rc;
605 int sp_action;
606
607 ts_store(&ftime_stamp, OS_SPECIAL, 0L);
608 force_volume_flag=0;
609 if(modify_command)
610 ext_hdr_capacity=LONG_MAX; /* ASR fix 15/05/2003 */
611 while(!no_in_arch&&read_header(0, aistream, archive_name))
612 {
613 if(!modify_command&&exit_after_count&&total_processed+comment_entries+total_files-split_files>=exit_count)
614 break;
615 pf_num=flist_lookup(++cf_num);
616 val_result=processing_validation();
617 switch(cmd)
618 {
619 case ARJ_CMD_ADD:
620 if(pf_num!=0&&file_type!=ARJT_LABEL)
621 {
622 flist_retrieve(filename, &properties, &flist_main, pf_num-1);
623 update_perm=1;
624 if(serialize_exts)
625 {
626 msg_sprintf(misc_buf, M_QUERY_UPDATE, filename);
627 update_perm=query_action(REPLY_YES, QUERY_UPDATE, (FMSG *)misc_buf);
628 }
629 if(update_perm)
630 {
631 if(!new_files_only)
632 {
633 pack_rc=pack_file_stub(0, 1);
634 if(pack_rc!=0)
635 {
636 if(volume_flag_set)
637 {
638 vol_file_num=pf_num;
639 break;
640 }
641 if(pack_rc!=1)
642 break;
643 cfa_store(pf_num-1, FLFLAG_PROCESSED);
644 break;
645 }
646 }
647 }
648 cfa_store(pf_num-1, FLFLAG_SKIPPED);
649 }
650 special_processing(CFA_NONE, aistream);
651 break;
652 case ARJ_CMD_COMMENT:
653 if(pf_num&&val_result&&(!use_comment||supply_comment_file)&&!(arj_flags&EXTFILE_FLAG))
654 {
655 update_perm=1;
656 if(query_for_each_file)
657 {
658 msg_sprintf(misc_buf, M_QUERY_COMMENT, filename);
659 update_perm=query_action(REPLY_YES, QUERY_ARCH_OP, (FMSG *)misc_buf);
660 }
661 if(update_perm)
662 {
663 if(supply_comment(comment_file, filename))
664 comment_entries++;
665 }
666 }
667 special_processing(CFA_NONE, aistream);
668 break;
669 case ARJ_CMD_DELETE:
670 if(pf_num&&val_result)
671 {
672 if(arcv_delete(cf_num))
673 break;
674 }
675 special_processing(CFA_NONE, aistream);
676 break;
677 case ARJ_CMD_FRESHEN:
678 case ARJ_CMD_UPDATE:
679 if(pf_num&&file_type!=ARJT_LABEL)
680 {
681 flist_retrieve(filename, &properties, &flist_main, pf_num-1);
682 pack_rc=pack_file_stub(1, 1);
683 if(pack_rc!=0)
684 {
685 if(vol_file_num==pf_num)
686 {
687 if(volume_flag_set)
688 break;
689 if(pack_rc==1)
690 cfa_store(vol_file_num-1, FLFLAG_PROCESSED);
691 vol_file_num=0;
692 break;
693 }
694 if(volume_flag_set)
695 vol_file_num=pf_num;
696 else if(pack_rc==1)
697 cfa_store(pf_num-1, FLFLAG_PROCESSED);
698 break;
699 }
700 special_processing(CFA_NONE, aistream);
701 cfa_store(pf_num-1, FLFLAG_SKIPPED);
702 break;
703 }
704 special_processing(CFA_NONE, aistream);
705 break;
706 case ARJ_CMD_GARBLE:
707 sp_action=CFA_NONE;
708 if(pf_num!=0&&val_result)
709 {
710 update_perm=1;
711 if(query_for_each_file)
712 {
713 msg_sprintf(misc_buf, M_QUERY_GARBLE, filename);
714 update_perm=query_action(REPLY_YES, QUERY_ARCH_OP, (FMSG *)misc_buf);
715 }
716 if(update_perm)
717 sp_action=CFA_GARBLE;
718 }
719 special_processing(sp_action, aistream);
720 break;
721 case ARJ_CMD_RENAME:
722 if(pf_num!=0&&val_result)
723 {
724 if(rename_file())
725 total_files++;
726 }
727 special_processing(CFA_NONE, aistream);
728 break;
729 case ARJ_CMD_ORDER:
730 if(arj_flags&VOLUME_FLAG||arj_flags&EXTFILE_FLAG)
731 error(M_CANT_ORDER_MV);
732 if(order_fcount>=order_fcap)
733 {
734 if(order_fcap==0)
735 order_fcap=flist_main.files;
736 order_fcap+=FILELIST_INCREMENT;
737 if((order_list=(unsigned long FAR *)farrealloc(order_list, order_fcap*sizeof(unsigned long)))==NULL)
738 error(M_OUT_OF_MEMORY);
739 }
740 if(pf_num!=0)
741 {
742 arch_hdr_index[pf_num-1]=cur_header_pos;
743 cfa_store(pf_num-1, FLFLAG_PROCESSED);
744 order_list[order_fcount++]=0L;
745 }
746 else
747 order_list[order_fcount++]=cur_header_pos;
748 total_files++;
749 skip_compdata();
750 break;
751 case ARJ_CMD_REMPATH:
752 sp_action=CFA_NONE;
753 if(pf_num!=0&&val_result)
754 {
755 update_perm=1;
756 if(query_for_each_file)
757 {
758 msg_sprintf(misc_buf, M_QUERY_GARBLE, filename);
759 update_perm=query_action(REPLY_YES, QUERY_ARCH_OP, (FMSG *)misc_buf);
760 }
761 if(update_perm)
762 sp_action=CFA_REMPATH;
763 }
764 special_processing(sp_action, aistream);
765 break;
766 case ARJ_CMD_JOIN:
767 case ARJ_CMD_SECURE:
768 special_processing(CFA_NONE, aistream);
769 total_files++;
770 break;
771 case ARJ_CMD_COPY:
772 sp_action=CFA_NONE;
773 if(pf_num!=0&&val_result)
774 {
775 if(chapter_mode==CHAP_USE)
776 sp_action=CFA_MARK_EXT;
777 else if(chapter_mode==CHAP_REMOVE)
778 sp_action=CFA_UNMARK_EXT;
779 else if(garble_enabled)
780 sp_action=CFA_UNGARBLE;
781 }
782 special_processing(sp_action, aistream);
783 break;
784 case ARJ_CMD_EXTR_NP:
785 case ARJ_CMD_PRINT:
786 if(pf_num!=0&&val_result)
787 {
788 update_perm=1;
789 if(query_for_each_file)
790 {
791 if(!first_vol_passed||!continued_prevvolume)
792 {
793 msg_sprintf(misc_buf, M_QUERY_EXTRACT, filename);
794 update_perm=query_action(REPLY_YES, QUERY_ARCH_OP, (FMSG *)misc_buf);
795 }
796 else
797 {
798 if(ofstream==NULL)
799 update_perm=0;
800 }
801 }
802 if(update_perm)
803 {
804 if(unpack_file_proc(cmd==ARJ_CMD_PRINT, cf_num))
805 {
806 total_files++;
807 if(volume_flag_set)
808 split_files++;
809 }
810 tmp_tmp_filename[0]='\0';
811 }
812 else
813 skip_compdata();
814 }
815 else
816 skip_compdata();
817 break;
818 case ARJ_CMD_LIST:
819 if(pf_num!=0&&val_result)
820 {
821 if(list_cmd(total_files, cf_num))
822 total_files++;
823 }
824 skip_compdata();
825 break;
826 case ARJ_CMD_TEST:
827 if(pf_num!=0&&val_result)
828 {
829 if(test_archive_crc==TC_CRC_AND_CONTENTS)
830 add_base_dir(filename);
831 if(unpack_validation(cmd))
832 total_files++;
833 }
834 else
835 skip_compdata();
836 break;
837 case ARJ_CMD_WHERE:
838 if(pf_num!=0&&val_result)
839 {
840 if(unpack_validation(cmd))
841 total_files++;
842 }
843 else
844 skip_compdata();
845 break;
846 }
847 }
848 if((cmd==ARJ_CMD_ADD||cmd==ARJ_CMD_UPDATE)&&multivolume_option&&continued_nextvolume&&!no_inarch)
849 volume_flag_set=1;
850 if(multivolume_option&&add_command)
851 continued_nextvolume=1;
852 ext_voldata=0;
853 /* ASR fix for v 2.76.04 - prevent phantom EAs at archive joints */
854 if(!continued_nextvolume)
855 {
856 if(eh!=NULL)
857 {
858 eh_release(eh);
859 eh=NULL;
860 }
861 }
862 if(cmd==ARJ_CMD_ADD||cmd==ARJ_CMD_UPDATE)
863 {
864 if(cf_num!=0)
865 {
866 resume_position=0L;
867 continued_prevvolume=0;
868 }
869 if(multivolume_option&&check_multivolume(MULTIVOLUME_INCREMENT)<MULTIVOLUME_INCREMENT)
870 volume_flag_set=1;
871 if(!volume_flag_set&&vol_file_num!=0)
872 {
873 flist_retrieve(filename, &properties, &flist_main, vol_file_num-1);
874 if(pack_file_stub(0, 0)&&!volume_flag_set)
875 {
876 cfa_store(vol_file_num-1, FLFLAG_PROCESSED);
877 vol_file_num=0;
878 }
879 }
880 for(cur_file=0; !volume_flag_set&&cur_file<flist_main.files; cur_file++)
881 {
882 if(cfa_get(cur_file)==FLFLAG_TO_PROCESS)
883 {
884 flist_retrieve(filename, &properties, &flist_main, cur_file);
885 if(pack_file_stub(0, 0))
886 {
887 if(volume_flag_set)
888 vol_file_num=cur_file+1;
889 else
890 cfa_store(cur_file, FLFLAG_PROCESSED);
891 }
892 else
893 cfa_store(cur_file, FLFLAG_SKIPPED);
894 if(multivolume_option&&check_multivolume(MULTIVOLUME_INCREMENT)<MULTIVOLUME_INCREMENT&&(cur_file+1)<flist_main.files)
895 volume_flag_set=1;
896 }
897 }
898 if(multivolume_option&&check_multivolume(MULTIVOLUME_INCREMENT)<MULTIVOLUME_INCREMENT&&cur_file<flist_main.files)
899 volume_flag_set=1;
900 #ifdef HAVE_VOL_LABELS
901 if(handle_labels&&!volume_flag_set)
902 store_label();
903 #endif
904 if(multivolume_option&&check_multivolume(MULTIVOLUME_INCREMENT)<MULTIVOLUME_INCREMENT&&cur_file<flist_main.files)
905 volume_flag_set=1;
906 if(total_chapters!=0&&!volume_flag_set&¤t_chapter<=CHAPTERS_MAX&&total_chapters>recent_chapter)
907 create_chapter_mark();
908 }
909 else if(cmd==ARJ_CMD_JOIN)
910 total_files+=copy_archive();
911 else if(cmd==ARJ_CMD_ORDER)
912 {
913 pf_num=0;
914 for(cur_file=0; cur_file<flist_main.files; cur_file++)
915 {
916 /* has been previously selected? Otherwise its "default" value is FLFLAG_TO_PROCESS :-o */
917 if(cfa_get(cur_file)==FLFLAG_PROCESSED)
918 {
919 fseek(aistream, arch_hdr_index[cur_file], SEEK_SET);
920 read_header(0, aistream, archive_name);
921 special_processing(CFA_NONE, aistream);
922 pf_num++;
923 }
924 }
925 for(cur_file=0; cur_file<order_fcount; cur_file++)
926 {
927 if(order_list[cur_file]>0L)
928 {
929 fseek(aistream, order_list[cur_file], SEEK_SET);
930 read_header(0, aistream, archive_name);
931 special_processing(CFA_NONE, aistream);
932 pf_num++;
933 }
934 }
935 if(total_files!=pf_num)
936 error(M_ORDER_CNT_MISMATCH);
937 msg_cprintf(0, M_FILES_REORDERED);
938 }
939 if(cmd==ARJ_CMD_COPY&&total_chapters!=0&&!volume_flag_set&&total_files!=0&&total_chapters>recent_chapter)
940 create_chapter_mark();
941 }
942
943 /* Some post-processing actions */
944
finish_processing(int cmd)945 static void finish_processing(int cmd)
946 {
947 int skip_query;
948 unsigned long cur_pos, eof_pos;
949 int entry;
950 char *ext_ptr;
951 char *bak_name;
952 FILE_COUNT cur_file;
953 int vol_code;
954 char *msg_ptr;
955 int ratio;
956 unsigned long free_space;
957 int protected=0;
958 int is_prot;
959
960 if(modify_command)
961 {
962 if(cmd==ARJ_CMD_DELETE&&total_files!=0&&file_args==1&&!strcmp_os(f_arg_array[0], all_wildcard))
963 {
964 skip_query=yes_on_all_queries||query_delete;
965 if(!skip_query)
966 {
967 msg_sprintf(misc_buf, M_QUERY_DELETE_N_FILES, total_files);
968 if(!query_action(REPLY_YES, QUERY_DELETE_N_FILES, (FMSG *)misc_buf))
969 {
970 errors++;
971 tmp_archive_cleanup();
972 longjmp(main_proc, 1);
973 }
974 }
975 }
976 if(cmd==ARJ_CMD_DELETE&&total_chapters!=0&¤t_chapter!=RESERVED_CHAPTER&&total_chapters>max_chapter)
977 final_header(FP_CHAPTER);
978 if(cmd==ARJ_CMD_DELETE&&!first_vol_passed&&!continued_nextvolume&&ftell(aostream)==first_file_offset)
979 {
980 msg_cprintf(H_HL|H_NFMT, M_DELETING_EMPTY_ARCH, archive_name);
981 file_close(aistream);
982 aistream=NULL;
983 if(!no_file_activity)
984 {
985 if(file_unlink(archive_name))
986 error(M_CANT_DELETE, archive_name);
987 tmp_archive_cleanup();
988 }
989 }
990 /* ASR fix: the original didn't check for ARJ_CMD_COMMENT */
991 else if(total_files!=0||(cmd==ARJ_CMD_COMMENT&&comment_entries!=0)||create_sfx!=0)
992 {
993 fput_word(HEADER_ID, aostream);
994 fput_word(0, aostream);
995 last_hdr_offset=0L;
996 if(!no_file_activity)
997 {
998 eof_pos=ftell(aostream);
999 if(continued_nextvolume&&add_command&&!volume_flag_set&&!force_volume_flag)
1000 {
1001 final_header(FP_VOLUME);
1002 continued_nextvolume=0;
1003 }
1004 if(!encryption_applied&&encryption_id!=ENCID_NONE)
1005 final_header(FP_GARBLE);
1006 if(sign_with_arjsec)
1007 {
1008 msg_cprintf(0, M_WORKING);
1009 cur_pos=ftell(aostream);
1010 secured_size=cur_pos-main_hdr_offset;
1011 arjsec_offset=(unsigned long)is_registered*cur_pos;
1012 final_header(FP_SECURITY);
1013 if(create_envelope(aostream, arjsec_offset, ARJSEC_ITER))
1014 {
1015 arj_delay(5);
1016 error(M_NO_ARJSEC_KEY);
1017 }
1018 }
1019 if(test_archive_crc)
1020 {
1021 archive_cleanup();
1022 cmd_verb=cmd;
1023 }
1024 protected=0;
1025 if(arjprot_tail)
1026 {
1027 if(prot_blocks==0)
1028 prot_blocks=arjprot_tail;
1029 fseek(aostream, 0L, SEEK_END);
1030 arjsec_offset=ftell(aostream);
1031 if(!sign_with_arjsec)
1032 final_header(FP_PROT);
1033 protected=1;
1034 create_protfile(aostream, prot_blocks, 0);
1035 }
1036 if(multivolume_option)
1037 {
1038 fseek(aostream, 0L, SEEK_END);
1039 if(debug_enabled&&strchr(debug_opt, 'a')!=NULL&&create_index)
1040 {
1041 if(msg_fprintf(idxstream, M_ARCH_SIZE, ftell(aostream), archive_name)<0)
1042 error(M_DISK_FULL);
1043 }
1044 if(ftell(aostream)>volume_limit&&create_index)
1045 {
1046 if(msg_fprintf(idxstream, M_VOLUME_BUG, archive_name)<0)
1047 error(M_DISK_FULL);
1048 }
1049 }
1050 if(ferror(aostream)||fclose(aostream)==EOF)
1051 error(M_DISK_FULL);
1052 aostream=NULL;
1053 if(test_archive_crc&&protected)
1054 {
1055 protected=1;
1056 if(debug_enabled&&strchr(debug_opt, 'a')!=NULL)
1057 protected=2;
1058 msg_strcpy(tmp_tmp_filename, M_ARJFIXED_NAME);
1059 if(recover_file(tmp_archive_name, nullstr, tmp_tmp_filename, protected, eof_pos))
1060 {
1061 msg_cprintf(H_HL, M_CANT_FIND_DAMAGE, archive_name);
1062 printf("\n");
1063 }
1064 else
1065 {
1066 if(create_index)
1067 {
1068 if(msg_fprintf(idxstream, M_AUTOPROT_DAMAGE, archive_name)<0)
1069 error(M_DISK_FULL);
1070 }
1071 }
1072 tmp_tmp_filename[0]='\0';
1073 }
1074 }
1075 aostream=NULL;
1076 if(create_sfx&&!first_vol_passed)
1077 {
1078 entry=split_name(archive_name, NULL, NULL);
1079 if((ext_ptr=strchr(archive_name+entry, '.'))==NULL)
1080 msg_strcat(archive_name, M_EXE_EXT);
1081 #ifndef NULL_EXE_EXTENSION
1082 else
1083 msg_strcpy(ext_ptr, M_EXE_EXT);
1084 #endif
1085 }
1086 if(aistream!=NULL)
1087 {
1088 file_close(aistream);
1089 aistream=NULL;
1090 if(!no_file_activity)
1091 {
1092 if(keep_bak&&file_exists(archive_name))
1093 {
1094 bak_name=(char *)malloc_msg(far_strlen(M_BAK_EXT)+strlen(archive_name)+1);
1095 strcpy(bak_name, archive_name);
1096 entry=split_name(bak_name, NULL, NULL);
1097 if((ext_ptr=strchr(bak_name+entry, '.'))==NULL)
1098 msg_strcat(bak_name, M_BAK_EXT);
1099 else
1100 msg_strcpy(ext_ptr, M_BAK_EXT);
1101 file_unlink(bak_name);
1102 rename_with_check(archive_name, bak_name);
1103 free(bak_name);
1104 }
1105 else
1106 {
1107 if(create_sfx)
1108 {
1109 if(file_exists(archive_name))
1110 if(file_unlink(archive_name))
1111 error(M_CANT_DELETE, archive_name);
1112 }
1113 else
1114 {
1115 if(file_unlink(archive_name))
1116 error(M_CANT_DELETE, archive_name);
1117 }
1118 }
1119 }
1120 }
1121 if(!no_file_activity)
1122 {
1123 if(assign_work_directory)
1124 {
1125 msg_cprintf(H_HL|H_NFMT, M_COPYING_TEMP, tmp_archive_name, archive_name);
1126 tmp_archive_used=1;
1127 if(file_copy(archive_name, tmp_archive_name, test_archive_crc))
1128 error(M_CANT_COPY_TEMP, tmp_archive_name, archive_name);
1129 tmp_archive_used=0;
1130 if(file_unlink(tmp_archive_name))
1131 error(M_CANT_DELETE, archive_name);
1132 }
1133 else
1134 rename_with_check(tmp_archive_name, archive_name);
1135 if(create_sfx&&!first_vol_passed)
1136 msg_cprintf(0, M_SFX_CREATED);
1137 }
1138 tmp_archive_name[0]='\0';
1139 }
1140 else
1141 {
1142 fput_word(HEADER_ID, aostream);
1143 fput_word(0, aostream);
1144 last_hdr_offset=0L;
1145 if(!no_file_activity&&delete_processed&&add_command&&test_archive_crc)
1146 {
1147 for(cur_file=0; cur_file<flist_main.files; cur_file++)
1148 if(cfa_get(cur_file)==FLFLAG_PROCESSED)
1149 break;
1150 if(cur_file<flist_main.files)
1151 {
1152 archive_cleanup();
1153 cmd_verb=cmd;
1154 }
1155 }
1156 file_close(aistream);
1157 aistream=NULL;
1158 tmp_archive_cleanup();
1159 if(continued_nextvolume&&!volume_flag_set&&no_inarch)
1160 continued_nextvolume=0;
1161 }
1162 }
1163 if(create_index&&(cmd==ARJ_CMD_ADD||cmd==ARJ_CMD_UPDATE))
1164 {
1165 filename[0]='\0';
1166 vol_code=2;
1167 if(continued_nextvolume&&volume_flag_set)
1168 {
1169 vol_code=continued_prevvolume;
1170 far_strcpy((char FAR *)filename, tmp_filename);
1171 }
1172 if(msg_fprintf(idxstream, M_NEXT_VOLUME_STATS, volume_number, vol_code, resume_position, filename)<0)
1173 error(M_DISK_FULL);
1174 }
1175 if(cmd==ARJ_CMD_ADD||cmd==ARJ_CMD_FRESHEN||cmd==ARJ_CMD_UPDATE||cmd==ARJ_CMD_JOIN)
1176 {
1177 if(filter_fa_arch==FAA_BACKUP_CLEAR||filter_fa_arch==FAA_CLEAR)
1178 group_clear_arch(&flist_main);
1179 if(delete_processed)
1180 delete_processed_files(&flist_main);
1181 }
1182 total_processed+=total_files+comment_entries;
1183 av_compressed+=total_compressed;
1184 av_uncompressed+=total_uncompressed;
1185 av_total_files+=total_files;
1186 av_total_longnames+=total_longnames;
1187 if(quiet_mode==ARJ_QUIET2)
1188 new_stdout=stdout;
1189 /* Now produce statistics for each command individually */
1190 if(cmd==ARJ_CMD_LIST)
1191 {
1192 if(!std_list_cmd||verbose_display!=VERBOSE_ENH)
1193 {
1194 if(total_files==0||(std_list_cmd&&verbose_display==VERBOSE_STD))
1195 {
1196 if(total_longnames==0)
1197 msg_cprintf(H_HL|H_NFMT, M_N_FILES, total_files);
1198 else
1199 msg_cprintf(H_HL|H_NFMT, M_N_FILES_LFN, total_files, total_longnames);
1200 if(total_chapters!=0)
1201 {
1202 msg_cprintf(0, M_CHAPTERS_ON);
1203 msg_cprintf(0, (FMSG *)lf);
1204 }
1205 }
1206 else
1207 {
1208 msg_cprintf(0, M_BRIEF_LIST_SEPARATOR);
1209 if(total_chapters!=0)
1210 {
1211 msg_strcpy(strcpy_buf, M_CHAPTERS_ON);
1212 msg_ptr=strcpy_buf;
1213 }
1214 else
1215 msg_ptr=nullstr;
1216 ratio=calc_percentage(total_compressed, total_uncompressed);
1217 if(total_longnames==0)
1218 msg_cprintf(H_HL|H_NFMT, M_TOTAL_STATS, total_files, total_uncompressed, total_compressed, ratio/1000, ratio%1000, msg_ptr);
1219 else
1220 msg_cprintf(H_HL|H_NFMT, M_TOTAL_STATS_LFN, total_files, total_uncompressed, total_compressed, ratio/1000, ratio%1000, msg_ptr, total_longnames);
1221 if(av_total_files>total_files)
1222 {
1223 ratio=calc_percentage(av_compressed, av_uncompressed);
1224 if(total_longnames==0)
1225 msg_cprintf(H_HL|H_NFMT, M_TOTAL_STATS, av_total_files, av_uncompressed, av_compressed, ratio/1000, ratio%1000, nullstr);
1226 else
1227 msg_cprintf(H_HL|H_NFMT, M_TOTAL_STATS_LFN, av_total_files, av_uncompressed, av_compressed, ratio/1000, ratio%1000, nullstr, av_total_longnames);
1228 }
1229 }
1230 }
1231 if(chk_free_space)
1232 {
1233 free_space=file_getfree(target_dir);
1234 if(disk_space_used+minfree>free_space)
1235 {
1236 msg_cprintf(H_ALERT, M_NOT_ENOUGH_SPACE_X, disk_space_used+minfree-free_space);
1237 errors++;
1238 }
1239 }
1240 }
1241 else if(cmd==ARJ_CMD_PRINT)
1242 {
1243 if(!help_issued)
1244 msg_cprintf(H_HL|H_NFMT, M_N_FILES, total_files);
1245 }
1246 else if(cmd==ARJ_CMD_COMMENT)
1247 msg_cprintf(H_HL|H_NFMT, M_N_COMMENTS, comment_entries);
1248 else if(cmd==ARJ_CMD_ADD||cmd==ARJ_CMD_FRESHEN||cmd==ARJ_CMD_UPDATE)
1249 {
1250 if(total_files==0)
1251 {
1252 if(total_longnames==0)
1253 msg_cprintf(H_HL|H_NFMT, M_N_FILES, total_files);
1254 else
1255 msg_cprintf(H_HL|H_NFMT, M_N_FILES_LFN, total_files, total_longnames);
1256 }
1257 else
1258 {
1259 if(verbose_display==VERBOSE_STD)
1260 {
1261 msg_cprintf(0, M_FINAL_FOOTER);
1262 ratio=calc_percentage(total_compressed, total_uncompressed);
1263 msg_cprintf(H_HL|H_NFMT, M_VERBOSE_FOOTER, total_files, total_uncompressed, total_compressed, ratio/10, ratio%10);
1264 if(total_files<av_total_files)
1265 {
1266 ratio=calc_percentage(av_compressed, av_uncompressed);
1267 msg_cprintf(H_HL|H_NFMT, M_VERBOSE_FOOTER, av_total_files, av_uncompressed, av_compressed, ratio/10, ratio%10);
1268 }
1269 }
1270 else
1271 {
1272 if(total_longnames==0)
1273 msg_cprintf(H_HL|H_NFMT, M_N_FILES, total_files);
1274 else
1275 msg_cprintf(H_HL|H_NFMT, M_N_FILES_LFN, total_files, total_longnames);
1276 }
1277 }
1278 if(comment_entries!=0)
1279 msg_cprintf(H_HL|H_NFMT, M_N_COMMENTS, comment_entries);
1280 }
1281 else if(cmd==ARJ_CMD_TEST&&total_files!=0&&errors==0&&(protfile_option||arjprot_tail||security_state==ARJSEC_SIGNED))
1282 {
1283 eof_pos=ftell(aistream);
1284 fseek(aistream, 0L, SEEK_END);
1285 arjsec_offset=ftell(aistream);
1286 is_prot=(security_state==ARJSEC_SIGNED&&chk_prot_sig(aistream, eof_pos))?1:0;
1287 file_close(aistream);
1288 aistream=NULL;
1289 if(arjprot_tail||is_prot)
1290 {
1291 protected=1;
1292 if(debug_enabled&&strchr(debug_opt, 'a')!=NULL)
1293 protected=2;
1294 if(recover_file(archive_name, nullstr, nullstr, protected, eof_pos))
1295 {
1296 msg_cprintf(H_HL, M_CANT_FIND_DAMAGE, archive_name);
1297 printf("\n");
1298 }
1299 else
1300 {
1301 if(create_index)
1302 {
1303 if(msg_fprintf(idxstream, M_AUTOPROT_DAMAGE, archive_name)<0)
1304 error(M_DISK_FULL);
1305 }
1306 }
1307 }
1308 if(protfile_option&&protected)
1309 {
1310 arjprot_tail=protfile_option;
1311 if(prot_blocks==0)
1312 prot_blocks=protfile_option;
1313 if((aostream=file_open(archive_name, m_rbp))==NULL)
1314 error(M_CANTOPEN, archive_name);
1315 if(security_state==ARJSEC_NONE)
1316 final_header(FP_PROT);
1317 create_protfile(aostream, prot_blocks, 0);
1318 file_close(aostream);
1319 aostream=NULL;
1320 }
1321 }
1322 else
1323 {
1324 if(cmd==ARJ_CMD_COPY&&chapter_mode)
1325 {
1326 if(chapter_mode==CHAP_USE)
1327 msg_cprintf(0, M_CHAPTERS_ON);
1328 else if(chapter_mode==CHAP_REMOVE)
1329 msg_cprintf(0, M_CHAPTERS_OFF);
1330 msg_cprintf(0, strform, "\n");
1331 }
1332 if(cmd==ARJ_CMD_COPY&&protfile_option&&!arjprot_tail)
1333 msg_cprintf(0, M_ARJPROT_DISABLED);
1334 msg_cprintf(H_HL|H_NFMT, M_N_FILES, total_files);
1335 if(comment_entries>0)
1336 msg_cprintf(H_HL|H_NFMT, M_N_COMMENTS, comment_entries);
1337 }
1338 if(security_state==ARJSEC_SIGNED&&arjsec_opt!=ARJSECP_SKIP)
1339 {
1340 msg_cprintf(H_HL|H_NFMT, M_VALID_ARJSEC, arjsec_signature);
1341 msg_strcpy(strcpy_buf, M_SDN_1);
1342 if(strstr(arjsec_signature, strcpy_buf)!=NULL)
1343 {
1344 msg_cprintf(0, M_SDN_ADD_DESC);
1345 msg_cprintf(0, M_SDN_SECURITY_TEST);
1346 }
1347 msg_strcpy(strcpy_buf, M_SDN_2);
1348 if(strstr(arjsec_signature, strcpy_buf)!=NULL)
1349 {
1350 msg_cprintf(0, M_SDN_DIST_DESC);
1351 msg_cprintf(0, M_SDN_SECURITY_TEST);
1352 }
1353 }
1354 file_close(aistream);
1355 aistream=NULL;
1356 if(arjprot_tail)
1357 msg_cprintf(0, M_ARJPROT_ENABLED, prot_blocks);
1358 if(arjsec_signature!=NULL)
1359 {
1360 free(arjsec_signature);
1361 arjsec_signature=NULL;
1362 }
1363 if(((modify_command&×tamp_override==ATO_SAVE_ARCHIVE)||
1364 timestamp_override==ATO_NEWEST)&&ts_valid(ftime_max))
1365 file_setftime(archive_name, ts_native(&ftime_max, OS));
1366 else if((timestamp_override==ATO_SAVE_ORIGINAL||timestamp_override==ATO_SAVE_BOTH)&&saved_timestamp!=0L)
1367 file_setftime(archive_name, saved_timestamp);
1368 if(modify_command&&file_is_removable(archive_name))
1369 reset_drive(archive_name);
1370 if(!modify_command&&total_processed==0&&!continued_nextvolume)
1371 {
1372 if(errorlevel==ARJ_ERL_SUCCESS)
1373 errorlevel=ARJ_ERL_WARNING;
1374 errors++;
1375 }
1376 total_processed-=split_files;
1377 av_total_files-=split_files;
1378 av_total_longnames-=split_longnames;
1379 }
1380
1381 #endif
1382
1383 /* Changes SFX executable name (for -ve) */
1384
1385 #if SFX_LEVEL>=ARJSFXV
iterate_sfxname()1386 static char *iterate_sfxname()
1387 {
1388 char *rc, *p;
1389 int l;
1390 char *tmp_str;
1391
1392 for(l=strlen(archive_name); l>0; l--)
1393 {
1394 if(archive_name[l]=='.')
1395 break;
1396 }
1397 if(l<4)
1398 {
1399 p=(l>0)?(archive_name+l):nullstr;
1400 l=0;
1401 rc=archive_name;
1402 }
1403 else
1404 {
1405 p=archive_name+l;
1406 l-=3;
1407 rc=archive_name+l;
1408 }
1409 if(volume_number>0)
1410 {
1411 tmp_str=malloc_str(archive_name);
1412 tmp_str[l]='\0';
1413 sprintf(archive_name, stub_fmt, tmp_str, volume_number, p);
1414 free(tmp_str);
1415 }
1416 return(rc);
1417 }
1418 #endif
1419
1420 /* Mangles the filename so it can be transformed to an aesthetic SFX name.
1421 ASR fix 26/08/2001 for UNIX. */
1422
1423 #if SFX_LEVEL>=ARJSFXV
fix_sfx_name()1424 static void fix_sfx_name()
1425 {
1426 #ifdef NULL_EXE_EXTENSION
1427 char *digit_pos;
1428 static char exe_append[]=".exe";
1429
1430 if(!first_vol_passed)
1431 return;
1432 digit_pos=strrchr(archive_name, PATHSEP_DEFAULT);
1433 if(digit_pos==NULL)
1434 digit_pos=archive_name;
1435 digit_pos=strchr(digit_pos, '.');
1436 if(digit_pos==NULL) /* "test" -> "test.exe" */
1437 strcat(archive_name, exe_append);
1438 else if(strlen(digit_pos)<3) /* ".xx" -> ".01" */
1439 strcpy(digit_pos, exe_append);
1440 #endif
1441 }
1442 #endif
1443
1444 /* Extended archive processing routine. A non-zero return value indicates
1445 that processing of further volumes must be omitted. */
1446
1447 #if SFX_LEVEL>=ARJ
process_archive_proc(int cmd)1448 static int process_archive_proc(int cmd)
1449 {
1450 struct timestamp tmp_time;
1451 static unsigned int t_buf, v_buf;
1452 char *tmp_ptr;
1453 int vol_num_digits;
1454 int encryption_version;
1455 char *vol_name_fmt;
1456 int filename_length;
1457 unsigned long avail_space;
1458 char timetext[22];
1459 char *sfx_name;
1460 int entry;
1461 int query_result;
1462 int no_input;
1463 FILE *cmtstream;
1464 int cmt_len;
1465 char *digit_pos;
1466 unsigned long arch_size;
1467 unsigned int desc_word, reg_id; /* SFX */
1468
1469 order_fcount=0;
1470 order_fcap=0;
1471 order_list=NULL;
1472 arjsec_signature=NULL;
1473 volume_flag_set=0;
1474 main_hdr_offset=last_hdr_offset=0L;
1475 tmp_archive_used=0;
1476 cf_num=0;
1477 total_files=total_longnames=0;
1478 comment_entries=0;
1479 security_state=ARJSEC_NONE;
1480 disk_space_used=0L;
1481 total_uncompressed=0L;
1482 total_compressed=0L;
1483 archive_size=0L;
1484 ts_store(&ftime_max, OS_SPECIAL, 0L);
1485 saved_timestamp=0L;
1486 ext_hdr_flags=0;
1487 encryption_applied=0;
1488 split_files=0;
1489 split_longnames=0;
1490 cmd_verb=cmd;
1491 if(!setjmp(main_proc))
1492 {
1493 set_file_apis(use_ansi_cp);
1494 v_buf=add_command?VBUF_ADD:VBUF_EXTRACT;
1495 t_buf=TBUF_ARJ;
1496 if(coreleft()<TBUF_MINFREE)
1497 t_buf>>=1;
1498 if(coreleft()<VBUF_MINFREE)
1499 v_buf>>=1;
1500 if((tmp_ptr=strchr(debug_opt, 'b'))!=NULL)
1501 {
1502 tmp_ptr++;
1503 v_buf=(int)strtol(tmp_ptr, &tmp_ptr, 10);
1504 }
1505 if((tmp_ptr=strchr(debug_opt, 'p'))!=NULL)
1506 {
1507 tmp_ptr++;
1508 t_buf=(int)strtol(tmp_ptr, &tmp_ptr, 10);
1509 }
1510 if((tmp_ptr=strchr(debug_opt, 'v'))!=NULL)
1511 msg_cprintf(H_HL|H_NFMT, M_BRIEF_MEMSTATS, coreleft(), t_buf, v_buf);
1512 if(chk_free_space)
1513 alloc_unit_size=get_bytes_per_cluster(target_dir);
1514 ts_store(&ftime_stamp, OS_SPECIAL, 0L);
1515 first_hdr_size=FIRST_HDR_SIZE;
1516 if(multivolume_option)
1517 {
1518 if(use_sfxstub)
1519 digit_pos=iterate_sfxname();
1520 else
1521 {
1522 vol_num_digits=2;
1523 tmp_ptr=volfmt_2digit;
1524 fix_sfx_name();
1525 filename_length=strlen(archive_name)-vol_num_digits;
1526 if(volume_number>99||isdigit(archive_name[filename_length-1]))
1527 {
1528 vol_num_digits=3;
1529 tmp_ptr=volfmt_3digit;
1530 filename_length--;
1531 if(volume_number>999&&lfn_supported)
1532 {
1533 if(volume_number>1000)
1534 filename_length--;
1535 tmp_ptr=volfmt_4digit;
1536 }
1537 else if(volume_number>999)
1538 volume_number=1;
1539 }
1540 if(volume_number>0)
1541 {
1542 vol_name_fmt=malloc_str(archive_name);
1543 vol_name_fmt[filename_length]='\0';
1544 sprintf(archive_name, tmp_ptr, vol_name_fmt, volume_number);
1545 free(vol_name_fmt);
1546 }
1547 digit_pos=archive_name+filename_length;
1548 }
1549 continued_nextvolume=1;
1550 if(modify_command)
1551 {
1552 do
1553 {
1554 avail_space=file_getfree(archive_name);
1555 arch_size=0L;
1556 if(assign_work_directory&&file_exists(archive_name))
1557 {
1558 arch_size=file_getfsize(archive_name);
1559 if(file_getfree(work_directory)<(avail_space+arch_size)*2)
1560 arch_size=0L;
1561 avail_space+=arch_size;
1562 }
1563 if(multivolume_option==MV_AVAIL)
1564 volume_limit=avail_space;
1565 if(debug_enabled&&strchr(debug_opt, 'v')!=NULL)
1566 msg_cprintf(H_HL|H_NFMT, M_AVAIL_SPACE, avail_space);
1567 if(avail_space<MIN_VOLUME_SIZE)
1568 {
1569 msg_cprintf(H_HL|H_NFMT, M_FILENAME_FORM, archive_name);
1570 if(!yes_on_all_queries&&!skip_space_query)
1571 {
1572 msg_cprintf(H_ALERT, M_NOT_ENOUGH_SPACE_V);
1573 return(0);
1574 }
1575 else
1576 error(M_NOT_ENOUGH_SPACE_V);
1577 }
1578 if(volume_limit>avail_space)
1579 {
1580 if(!yes_on_all_queries&&!skip_space_query)
1581 {
1582 msg_cprintf(H_HL|H_NFMT, M_FILENAME_FORM, archive_name);
1583 msg_sprintf(misc_buf, M_LOW_SPACE_WARNING, avail_space);
1584 if(!query_action(REPLY_YES, QUERY_LOW_SPACE, (FMSG *)misc_buf))
1585 return(0);
1586 }
1587 }
1588 } while((arch_size+avail_space)!=file_getfree(archive_name));
1589 }
1590 }
1591 ctrlc_not_busy=0;
1592 aistream=NULL;
1593 if(file_exists(archive_name))
1594 {
1595 if(modify_command)
1596 {
1597 saved_timestamp=file_getftime(archive_name);
1598 aistream=file_open_noarch(archive_name, m_rbp);
1599 }
1600 else
1601 aistream=file_open(archive_name, m_rb);
1602 fseek(aistream, arcv_ext_pos, SEEK_SET);
1603 arcv_ext_pos=0L;
1604 }
1605 ctrlc_not_busy=1;
1606 if(aistream==NULL&&msg_strchr(M_UPDATE_COMMANDS, (char)cmd)==NULL)
1607 {
1608 if(multivolume_option&&!yes_on_all_queries&&!skip_next_vol_query)
1609 {
1610 error_report();
1611 msg_cprintf(H_ERR, M_CANTOPEN, archive_name);
1612 nputlf();
1613 return(0);
1614 }
1615 else
1616 error(M_CANTOPEN, archive_name);
1617 }
1618 if(create_index)
1619 {
1620 cur_time_stamp(&tmp_time);
1621 timestamp_to_str(timetext, &tmp_time);
1622 if(msg_fprintf(idxstream, M_IDX_VOLUME_HEADER, timetext, resume_position, archive_name)<0)
1623 error(M_DISK_FULL);
1624 }
1625 no_inarch=1;
1626 if(aistream!=NULL)
1627 {
1628 #ifndef NO_CACHING
1629 setvbuf(aistream, NULL, _IOFBF, v_buf);
1630 #endif
1631 no_inarch=0;
1632 }
1633 if(!modify_command)
1634 msg_cprintf(H_HL|H_NFMT, M_PROCESSING_ARCHIVE, archive_name);
1635 else
1636 {
1637 if(!tmp_archive_name)
1638 {
1639 tmp_archive_used=-1;
1640 tmp_archive_name=(char *)malloc_msg(FILENAME_MAX);
1641 tmp_archive_name[0]='\0';
1642 tmp_archive_used=0;
1643 }
1644 if(create_sfx)
1645 {
1646 if(!first_vol_passed)
1647 {
1648 sfx_name=malloc_msg(filename_length=strlen(archive_name)+far_strlen(M_EXE_EXT)+1);
1649 strcpy(sfx_name, archive_name);
1650 entry=split_name(sfx_name, NULL, NULL);
1651 if((tmp_ptr=strchr(sfx_name+entry, '.'))==NULL)
1652 msg_strcat(sfx_name, M_EXE_EXT);
1653 #ifndef NULL_EXE_EXTENSION
1654 else
1655 msg_strcpy(tmp_ptr, M_EXE_EXT);
1656 #endif
1657 if(file_exists(sfx_name))
1658 {
1659 query_result=yes_on_all_queries||overwrite_existing;
1660 if(!query_result)
1661 {
1662 msg_cprintf(H_HL|H_NFMT, M_EXISTS, sfx_name);
1663 msg_sprintf(misc_buf, M_QUERY_UPDATE, sfx_name);
1664 query_result=query_action(REPLY_YES, QUERY_OVERWRITE, (FMSG *)misc_buf);
1665 }
1666 if(!query_result||(stricmp(archive_name, sfx_name)&&file_unlink(sfx_name)))
1667 error(M_CANT_DELETE, sfx_name);
1668 }
1669 msg_cprintf(H_HL|H_NFMT, M_CREATING_SFX, sfx_name);
1670 free(sfx_name);
1671 }
1672 }
1673 else
1674 msg_cprintf(H_HL|H_NFMT, (aistream==NULL)?M_CREATING_ARCHIVE:M_UPDATING_ARCHIVE, archive_name);
1675 if(!no_file_activity)
1676 {
1677 if(aistream==NULL)
1678 {
1679 aostream=file_open_noarch(archive_name, m_wb);
1680 file_close(aostream);
1681 aostream=NULL;
1682 file_unlink(archive_name);
1683 }
1684 tmp_archive_used=-1;
1685 if(assign_work_directory)
1686 {
1687 strcpy(tmp_archive_name, work_directory);
1688 add_pathsep(tmp_archive_name);
1689 }
1690 else
1691 split_name(archive_name, tmp_archive_name, NULL);
1692 strcat(tmp_archive_name, arjtemp_spec);
1693 find_tmp_filename(tmp_archive_name);
1694 aostream=file_open_noarch(tmp_archive_name, m_wbp);
1695 tmp_archive_used=0;
1696 #ifndef NO_CACHING
1697 setvbuf(aostream, NULL, _IOFBF, t_buf);
1698 #endif
1699 avail_space=file_getfree(tmp_archive_name);
1700 if(volume_limit>avail_space)
1701 {
1702 if(!yes_on_all_queries&&!skip_space_query)
1703 {
1704 msg_cprintf(H_HL|H_NFMT, M_FILENAME_FORM, tmp_archive_name);
1705 msg_sprintf(misc_buf, M_LOW_SPACE_WARNING, avail_space);
1706 if(!query_action(REPLY_YES, QUERY_LOW_SPACE, (FMSG *)misc_buf))
1707 {
1708 tmp_archive_cleanup();
1709 return(0);
1710 }
1711 }
1712 }
1713 if(create_sfx==SFXCRT_SFX&&multivolume_option)
1714 {
1715 if(!first_vol_passed)
1716 fetch_sfxv();
1717 else
1718 if(use_sfxstub)
1719 fetch_sfxstub();
1720 }
1721 else if(create_sfx==SFXCRT_SFX)
1722 fetch_sfx();
1723 else if(create_sfx==SFXCRT_SFXJR)
1724 fetch_sfxjr();
1725 /* Adjust the privileges on UNIX platforms */
1726 #if TARGET==UNIX
1727 if(create_sfx)
1728 {
1729 if(create_sfx==SFXCRT_SFX&&multivolume_option&&first_vol_passed&&!use_sfxstub)
1730 make_nonexecutable(aostream);
1731 else
1732 make_executable(aostream);
1733 }
1734 else
1735 make_nonexecutable(aostream);
1736 #endif
1737 }
1738 }
1739 no_input=0;
1740 if(aistream==NULL)
1741 {
1742 no_input=1;
1743 fill_archive_header();
1744 if(win32_platform&&use_ansi_cp)
1745 msg_cprintf(0, M_ANSI_CP_ARCHIVE);
1746 }
1747 else
1748 {
1749 if((main_hdr_offset=find_header(0, aistream))<0L)
1750 {
1751 msg_cprintf(H_ALERT, M_NOT_ARJ_ARCHIVE, archive_name);
1752 msg_cprintf(0, (FMSG *)lf);
1753 file_close(aistream);
1754 aistream=NULL;
1755 if(errorlevel==ARJ_ERL_SUCCESS)
1756 errorlevel=ARJ_ERL_NOT_ARJ_ARCHIVE;
1757 errors++;
1758 tmp_archive_cleanup();
1759 return(ARJ_ERL_NOT_ARJ_ARCHIVE);
1760 }
1761 if(main_hdr_offset==0L&&modify_command&&create_sfx)
1762 copy_bytes(main_hdr_offset);
1763 if(main_hdr_offset>EXESIZE_MINSFX)
1764 {
1765 fseek(aistream, main_hdr_offset, SEEK_SET);
1766 fseek(aistream, -8L, SEEK_CUR);
1767 desc_word=fget_word(aistream);
1768 reg_id=fget_word(aistream);
1769 sfx_desc_word=desc_word;
1770 /* Perform a simple integrity check */
1771 if(reg_id!=REG_ID&®_id!=UNREG_ID)
1772 sfx_desc_word=SFXDESC_NONSFX;
1773 if(sfx_desc_word<SFXDESC_MIN||sfx_desc_word>SFXDESC_MAX)
1774 sfx_desc_word=SFXDESC_NONSFX;
1775 }
1776 fseek(aistream, main_hdr_offset, SEEK_SET);
1777 if(!read_header(1, aistream, archive_name))
1778 error(M_INVALID_COMMENT_HDR);
1779 if(use_sfxstub)
1780 digit_pos=iterate_sfxname();
1781 if(modify_command&&continued_nextvolume&&!multivolume_option)
1782 {
1783 msg_cprintf(0, M_MV_UPDATE_REQ_SW);
1784 file_close(aistream);
1785 aistream=NULL;
1786 errors++;
1787 tmp_archive_cleanup();
1788 return(0);
1789 }
1790 if(modify_command&&(cmd==ARJ_CMD_GARBLE||garble_enabled))
1791 {
1792 if(arj_nbr>=ARJ_NEWCRYPT_VERSION&&ext_hdr_flags==0&&!encryption_applied)
1793 {
1794 ext_hdr_flags=ENCRYPT_STD;
1795 if(gost_cipher==GOST256)
1796 ext_hdr_flags=ENCRYPT_UNK;
1797 else if(gost_cipher==GOST40)
1798 ext_hdr_flags=ENCRYPT_GOST40;
1799 }
1800 else
1801 {
1802 if((gost_cipher!=GOST256||(ext_hdr_flags!=ENCRYPT_GOST256&&ext_hdr_flags!=ENCRYPT_GOST256L))&&
1803 (gost_cipher!=GOST40||ext_hdr_flags!=ENCRYPT_GOST40)&&
1804 gost_cipher!=GOST_NONE)
1805 error(M_WRONG_ENC_VERSION, 0);
1806 }
1807 }
1808 if(!win32_platform&&create_sfx&&!multivolume_option&&ext_hdr_flags>=ENCRYPT_STD)
1809 error(M_BAD_SYNTAX);
1810 if(cmd!=ARJ_CMD_COPY&&chapter_mode&&total_chapters==0)
1811 error(M_NOT_A_CHAPTER_ARCH);
1812 if(cmd==ARJ_CMD_DELETE&&delete_processed==DP_EXTRACT&&total_chapters!=0)
1813 error(M_BAD_SYNTAX);
1814 if(cmd==ARJ_CMD_DELETE&¤t_chapter==RESERVED_CHAPTER&&total_chapters==0)
1815 error(M_NOT_A_CHAPTER_ARCH);
1816 if(arjsec_opt==ARJSECP_SET_ERROR&&arj_flags&SECURED_FLAG)
1817 error(M_SKIPPING_SEC);
1818 if(protfile_option&&(multivolume_option||continued_nextvolume)&&
1819 !arjprot_tail&&is_removable)
1820 error(M_ARJPROT_REJECTED);
1821 timestamp_to_str(timetext, &ftime_stamp);
1822 msg_cprintf(H_HL|H_NFMT, M_ARCHIVE_CREATED, timetext);
1823 if(arj_nbr>=ARJ_M_VERSION)
1824 {
1825 ts_store(&tmp_time, host_os, compsize);
1826 timestamp_to_str(timetext, &tmp_time);
1827 msg_cprintf(H_HL|H_NFMT, M_MODIFIED, timetext);
1828 if(total_chapters!=0)
1829 msg_cprintf(H_HL, M_CHAPTER_NUMBER, total_chapters);
1830 }
1831 msg_cprintf(0, (FMSG *)lf);
1832 if((!modify_command||!use_comment)&&(cmd!=ARJ_CMD_COMMENT||supply_comment_file))
1833 {
1834 if((cmd!=ARJ_CMD_LIST||!std_list_cmd||verbose_display!=VERBOSE_ENH)&&comment_display!=CMTD_NONE)
1835 display_comment(comment);
1836 }
1837 set_file_apis(ansi_codepage);
1838 if(ansi_codepage)
1839 {
1840 msg_cprintf(0, M_ANSI_CP_ARCHIVE);
1841 #if TARGET!=WIN32
1842 if(cmd==ARJ_CMD_EXTR_NP&&!use_ansi_cp)
1843 error(M_REQUIRES_ARJ32);
1844 #endif
1845 }
1846 if(cmd==ARJ_CMD_LIST&&debug_enabled&&strchr(debug_opt, 'l')!=NULL)
1847 msg_cprintf(H_HL|H_NFMT, M_ENCRYPT_VALUE, ext_hdr_flags);
1848 }
1849 if(multivolume_option)
1850 volume_number=strtol(digit_pos, &digit_pos, 10)+1;
1851 if(modify_command)
1852 {
1853 main_hdr_offset=ftell(aostream);
1854 if(security_state)
1855 {
1856 msg_cprintf(0, M_CANT_UPDATE_SEC);
1857 msg_cprintf(0, (FMSG *)lf);
1858 file_close(aistream);
1859 aistream=NULL;
1860 errors++;
1861 errorlevel=ARJ_ERL_ARJSEC_ERROR;
1862 tmp_archive_cleanup();
1863 return(0);
1864 }
1865 if(timestamp_override!=ATO_SAVE_BOTH)
1866 {
1867 cur_time_stamp(&tmp_time);
1868 compsize=ts_native(&tmp_time, host_os);
1869 }
1870 if(ts_valid(secondary_ftime))
1871 compsize=ts_native(&secondary_ftime, host_os); /* Archive modification time */
1872 if(garble_enabled)
1873 {
1874 encryption_version=garble_init(0);
1875 if(ext_hdr_flags==ENCRYPT_UNK)
1876 ext_hdr_flags=encryption_version;
1877 if(ext_hdr_flags!=0&&encryption_version!=ext_hdr_flags)
1878 error(M_WRONG_ENC_VERSION, ext_hdr_flags);
1879 }
1880 ext_flags=ext_hdr_flags;
1881 if(protfile_option)
1882 {
1883 arjprot_tail=protfile_option;
1884 if(prot_blocks==0)
1885 prot_blocks=arjprot_tail%256; /* v 2.75+ - %'ing is pointless! */
1886 }
1887 if(sfx_desc_word!=SFXDESC_NONSFX)
1888 {
1889 if(chapter_mode)
1890 error(M_CHAPTER_SFX_CREATION);
1891 if(custom_method==5||method_specifier==4)
1892 error(M_INVALID_METHOD_SFX);
1893 if(sfx_desc_word<=SFXDESC_SFX&&multivolume_option)
1894 error(M_BAD_SYNTAX);
1895 /* Skip check for EAs - an existing archive may contain them but
1896 they are harmless! */
1897 if(sfx_desc_word==SFXDESC_SFXJR&&(type_override||lfn_supported!=LFN_NOT_SUPPORTED))
1898 error(M_TEXTMODE_LFN_SFXJR);
1899 if(sfx_desc_word==SFXDESC_SFXJR&&garble_enabled)
1900 error(M_NO_GARBLE_IN_SFXJR);
1901 if(sfx_desc_word==SFXDESC_SFX&&ext_hdr_flags>ENCRYPT_STD)
1902 error(M_WRONG_ENC_VERSION, ext_hdr_flags);
1903 }
1904 if(cmd==ARJ_CMD_COPY)
1905 {
1906 if(chapter_mode==CHAP_USE&&total_chapters!=0&&!multivolume_option)
1907 error(M_ALREADY_CHAPTER_ARCH);
1908 if(chapter_mode==CHAP_REMOVE&&total_chapters==0)
1909 error(M_NOT_A_CHAPTER_ARCH);
1910 if(chapter_mode==CHAP_USE&&total_chapters==0)
1911 {
1912 chapter_number=1;
1913 total_chapters=1;
1914 current_chapter=HIGHEST_CHAPTER;
1915 comment_entries++;
1916 }
1917 else if(chapter_mode==CHAP_REMOVE&&total_chapters!=0)
1918 {
1919 chapter_number=0;
1920 total_chapters=0;
1921 current_chapter=HIGHEST_CHAPTER;
1922 comment_entries++;
1923 }
1924 if(garble_enabled)
1925 {
1926 ext_flags=0;
1927 arj_flags&=~GARBLED_FLAG;
1928 if(!test_archive_crc)
1929 test_archive_crc=TC_ARCHIVE;
1930 }
1931 if(use_ansi_cp==ANSICP_SKIP)
1932 {
1933 if(arj_nbr==ARJ_ANSI_VERSION||arj_flags&ANSICP_FLAG)
1934 {
1935 msg_cprintf(H_ALERT, M_NOT_OEM_CP_ARCHIVE);
1936 file_close(aistream);
1937 aistream=NULL;
1938 errors++;
1939 errorlevel=ARJ_ERL_WARNING;
1940 tmp_archive_cleanup();
1941 return(0);
1942 }
1943 arj_flags|=ANSICP_FLAG;
1944 comment_entries++;
1945 }
1946 if(protfile_option)
1947 {
1948 arjprot_tail=0;
1949 prot_blocks=0;
1950 arj_flags&=~PROT_FLAG;
1951 comment_entries++;
1952 }
1953 }
1954 if(add_command&&multivolume_option)
1955 arj_flags|=VOLUME_FLAG;
1956 if(arj_flags&DUAL_NAME_FLAG)
1957 dual_name=1;
1958 if(add_command&&!dual_name&&(lfn_mode==LFN_DUAL||lfn_mode==LFN_DUAL_EXT))
1959 error(M_CANT_CNV_TO_DUAL_N);
1960 if(arj_flags&ANSICP_FLAG)
1961 ansi_codepage=1;
1962 if(add_command&&!ansi_codepage&&use_ansi_cp==ANSICP_CONVERT)
1963 error(M_ARCHIVE_CP_MISMATCH);
1964 if(!win32_platform&&ansi_codepage)
1965 error(M_ARCHIVE_CP_MISMATCH);
1966 create_header(1);
1967 if((cmd==ARJ_CMD_COMMENT&&!supply_comment_file)||use_comment)
1968 {
1969 if(supply_comment(archive_cmt_name, archive_name))
1970 comment_entries++;
1971 }
1972 write_header();
1973 first_file_offset=ftell(aostream);
1974 }
1975 else
1976 {
1977 first_file_offset=ftell(aistream);
1978 if(security_state&&arjsec_opt!=ARJSECP_SKIP)
1979 {
1980 if(method>ARJSEC_VERSION)
1981 {
1982 msg_cprintf(H_HL|H_NFMT, M_CANT_HANDLE_ARJSEC_V, method);
1983 msg_cprintf(0, (FMSG *)misc_buf);
1984 }
1985 else
1986 {
1987 msg_cprintf(0, M_VERIFYING_ARJSEC);
1988 if(arjsec_signature==NULL)
1989 arjsec_signature=(char *)malloc_msg(ARJSEC_SIG_MAXLEN+1);
1990 if(get_arjsec_signature(aistream, arjsec_offset, arjsec_signature, ARJSEC_ITER))
1991 {
1992 arj_delay(5);
1993 msg_cprintf(0, M_DAMAGED_SEC_ARCHIVE);
1994 fclose(aistream);
1995 aistream=NULL;
1996 errors++;
1997 return(0);
1998 }
1999 msg_cprintf(0, M_VALID_ENVELOPE);
2000 fseek(aistream, first_file_offset, SEEK_SET);
2001 security_state=ARJSEC_SIGNED;
2002 }
2003 }
2004 if(garble_enabled)
2005 {
2006 encryption_version=garble_init(0);
2007 if((encryption_version!=ENCRYPT_GOST256&&encryption_version!=ENCRYPT_GOST256L)||
2008 (ext_hdr_flags!=ENCRYPT_GOST256&&ext_hdr_flags!=ENCRYPT_GOST256L))
2009 {
2010 if(ext_hdr_flags!=0&&encryption_version!=ext_hdr_flags)
2011 error(M_WRONG_ENC_VERSION, encryption_version);
2012 }
2013 }
2014 if(test_archive_crc==TC_ARCHIVE)
2015 {
2016 cmd_verb=ARJ_CMD_TEST;
2017 while(read_header(0, aistream, archive_name))
2018 unpack_validation(ARJ_CMD_TEST);
2019 cmd_verb=cmd;
2020 if(errors!=0)
2021 error(M_FOUND_N_ERRORS, errors);
2022 fseek(aistream, first_file_offset, SEEK_SET);
2023 }
2024 if(cmd==ARJ_CMD_EXTR_NP&&use_comment&&archive_cmt_name[0]!='\0')
2025 {
2026 msg_cprintf(H_HL|H_NFMT, M_EXTRACTING_CMT_TO_F, archive_cmt_name);
2027 cmtstream=file_create(archive_cmt_name, m_w);
2028 if(hdr_comment[0]=='\0')
2029 {
2030 msg_strcpy(strcpy_buf, M_EMPTY_COMMENT);
2031 if(fputs(strcpy_buf, cmtstream)==EOF)
2032 error(M_DISK_FULL);
2033 }
2034 else
2035 {
2036 cmt_len=strlen(hdr_comment);
2037 if(fwrite(hdr_comment, 1, cmt_len, cmtstream)!=cmt_len)
2038 error(M_DISK_FULL);
2039 }
2040 comment_entries++;
2041 fclose(cmtstream);
2042 }
2043 }
2044 if((tmp_ptr=strchr(debug_opt, 'v'))!=NULL)
2045 msg_cprintf(H_HL|H_NFMT, M_BRIEF_MEMSTATS, coreleft(), t_buf, v_buf);
2046 /* The main part of the whole routine */
2047 process_archive(cmd, no_input);
2048 finish_processing(cmd);
2049 }
2050 if(order_list!=NULL)
2051 {
2052 farfree(order_list);
2053 order_list=NULL;
2054 }
2055 file_close(aistream);
2056 aistream=NULL;
2057 return(0);
2058 }
2059
2060 #elif SFX_LEVEL<=ARJSFXV /* Simplified routine for ARJSFXV */
2061
2062 #if SFX_LEVEL>=ARJSFXV
2063 static
2064 #endif
process_archive()2065 void process_archive()
2066 {
2067 char timetext[22];
2068 int query_result;
2069 FILE_COUNT pf_num;
2070 unsigned int ratio;
2071 int lt;
2072 #if SFX_LEVEL>=ARJSFXV
2073 struct timestamp tmp_time;
2074 static unsigned int t_buf, v_buf;
2075 char *tmp_ptr, *msg_ptr;
2076 char *digit_pos;
2077 int vol_num_digits;
2078 char *vol_name_fmt;
2079 int filename_length;
2080 char FAR *cmt_ptr;
2081 int no_in_arch;
2082 int enc_version;
2083 unsigned long free_space;
2084 unsigned int cf_num;
2085 #else
2086 char *cmt_ptr;
2087 int i;
2088 char tmp_name[FILENAME_MAX];
2089 #endif
2090
2091 #if SFX_LEVEL>=ARJSFXV
2092 cf_num=0;
2093 volume_flag_set=0;
2094 main_hdr_offset=last_hdr_offset=0L;
2095 total_files=0;
2096 comment_entries=0;
2097 security_state=ARJSEC_NONE;
2098 dual_name=0;
2099 ansi_codepage=0;
2100 disk_space_used=0L;
2101 total_uncompressed=0L;
2102 total_compressed=0L;
2103 archive_size=0L;
2104 ts_store(&ftime_max, OS, 0L);
2105 ts_store(&ftime_stamp, OS_SPECIAL, 0L);
2106 valid_ext_hdr=0;
2107 if(eh!=NULL)
2108 eh_release(eh);
2109 eh=NULL;
2110 first_hdr_size=STD_HDR_SIZE;
2111 for(total_os=0; host_os_names[total_os]!=NULL; total_os++);
2112 v_buf=VBUF_SFX;
2113 if((tmp_ptr=strchr(debug_opt, 'b'))!=NULL)
2114 {
2115 tmp_ptr++;
2116 v_buf=(int)strtol(tmp_ptr, &tmp_ptr, 10);
2117 }
2118 t_buf=TBUF_ARJ;
2119 if((tmp_ptr=strchr(debug_opt, 'p'))!=NULL)
2120 {
2121 tmp_ptr++;
2122 t_buf=(int)strtol(tmp_ptr, &tmp_ptr, 10);
2123 }
2124 if(multivolume_option)
2125 {
2126 if(use_sfxstub)
2127 digit_pos=iterate_sfxname();
2128 else
2129 {
2130 vol_num_digits=2;
2131 tmp_ptr=volfmt_2digit;
2132 if(volume_number>99)
2133 {
2134 vol_num_digits++;
2135 tmp_ptr=volfmt_3digit;
2136 }
2137 if(volume_number>1000) /* ASR fix 20/10/2000 */
2138 {
2139 vol_num_digits++;
2140 tmp_ptr=volfmt_4digit;
2141 }
2142 fix_sfx_name();
2143 filename_length=strlen(archive_name)-vol_num_digits;
2144 if(volume_number>0)
2145 {
2146 vol_name_fmt=malloc_str(archive_name);
2147 vol_name_fmt[filename_length]='\0';
2148 sprintf(archive_name, tmp_ptr, vol_name_fmt, volume_number);
2149 free(vol_name_fmt);
2150 }
2151 digit_pos=archive_name+filename_length;
2152 }
2153 continued_nextvolume=1;
2154 }
2155 ctrlc_not_busy=0;
2156 aistream=file_open(archive_name, m_rb);
2157 ctrlc_not_busy=1;
2158 if(aistream==NULL)
2159 {
2160 if(multivolume_option&&!yes_on_all_queries&&!skip_next_vol_query)
2161 {
2162 show_sfx_logo();
2163 msg_cprintf(H_ERR, M_CANTOPEN, archive_name);
2164 msg_cprintf(0, (FMSG *)lf);
2165 return;
2166 }
2167 else
2168 error(M_CANTOPEN, archive_name);
2169 }
2170 #endif
2171 /* ARJSFX initialization... quite short */
2172 #if SFX_LEVEL<=ARJSFX
2173 /* Set up ARJ$DISP screen if needed */
2174 if(arjdisp_enabled)
2175 {
2176 cmd_verb=ARJDISP_CMD_START;
2177 filename[0]='+';
2178 filename[1]='\0';
2179 uncompsize=compsize=0L;
2180 display_indicator(0L);
2181 }
2182 if((aistream=file_open(archive_name, m_rb))==NULL)
2183 error(M_CANTOPEN, archive_name);
2184 #endif
2185 /* Initialize caching */
2186 #ifndef NO_CACHING
2187 #if SFX_LEVEL>=ARJSFXV
2188 if(aistream!=NULL)
2189 setvbuf(aistream, NULL, _IOFBF, v_buf);
2190 #else
2191 setvbuf(aistream, cache_buf, _IOFBF, VBUF_SFX);
2192 #endif
2193 #endif
2194 /* Skip EXE header */
2195 #if SFX_LEVEL>=ARJSFXV
2196 if(!first_vol_passed)
2197 sfx_seek();
2198 else
2199 main_hdr_offset=find_header(0, aistream);
2200 #else
2201 sfx_seek();
2202 #endif
2203 /* Header verification */
2204 #if SFX_LEVEL>=ARJSFXV
2205 if(main_hdr_offset<0L)
2206 {
2207 msg_cprintf(H_ALERT, M_NOT_ARJ_ARCHIVE, archive_name);
2208 msg_cprintf(0, (FMSG *)lf);
2209 file_close(aistream);
2210 aistream=NULL;
2211 if(errorlevel==ARJ_ERL_SUCCESS)
2212 errorlevel=ARJ_ERL_NOT_ARJ_ARCHIVE;
2213 errors++;
2214 return;
2215 }
2216 fseek(aistream, main_hdr_offset, SEEK_SET);
2217 #endif
2218 /* Read the main archive header */
2219 #if SFX_LEVEL>=ARJSFXV
2220 if(!read_header(1, aistream, archive_name))
2221 error(M_INVALID_COMMENT_HDR);
2222 #else
2223 if(!read_header(1))
2224 error(M_BAD_HEADER);
2225 #endif
2226 /* ARJSFXV: increment SFXNAME */
2227 #if SFX_LEVEL>=ARJSFXV
2228 if(use_sfxstub)
2229 digit_pos=iterate_sfxname();
2230 if(multivolume_option)
2231 volume_number=strtol(digit_pos, &digit_pos, 10)+1;
2232 #endif
2233 /* Analyze preset options */
2234 cmt_ptr=comment;
2235 #if SFX_LEVEL>=ARJSFXV
2236 if(!first_vol_passed)
2237 {
2238 if(!skip_preset_options)
2239 cmt_ptr=preprocess_comment(cmt_ptr);
2240 sfx_setup();
2241 show_sfx_logo();
2242 msg_cprintf(H_HL|H_NFMT, M_PROCESSING_ARCHIVE, archive_name);
2243 timestamp_to_str(timetext, &ftime_stamp);
2244 msg_cprintf(H_HL|H_NFMT, M_ARCHIVE_CREATED, timetext);
2245 if(arj_nbr>=ARJ_M_VERSION)
2246 {
2247 ts_store(&tmp_time, host_os, compsize);
2248 timestamp_to_str(timetext, &tmp_time);
2249 msg_cprintf(H_HL|H_NFMT, M_MODIFIED, timetext);
2250 }
2251 msg_cprintf(0, (FMSG *)lf);
2252 if(ansi_codepage)
2253 msg_cprintf(0, M_ANSI_CP_ARCHIVE);
2254 if(chk_free_space)
2255 alloc_unit_size=get_bytes_per_cluster(target_dir);
2256 if(process_lfn_archive==1)
2257 lfn_supported=LFN_NOT_SUPPORTED;
2258 display_comment(cmt_ptr);
2259 if(!first_vol_passed&&cmd_verb==ARJ_CMD_EXTRACT&&!yes_on_all_queries&&!skip_extract_query)
2260 if(!query_action(REPLY_YES, QUERY_CRITICAL, M_CONTINUE_EXTRACTION))
2261 exit(ARJ_ERL_WARNING);
2262 }
2263 #endif
2264 /* */ /* Nag screen removed */ /* */
2265 #if SFX_LEVEL>=ARJSFXV
2266 if(!first_vol_passed)
2267 {
2268 if((garble_enabled&&!strcmp(garble_password, "?"))||
2269 (file_garbled&&!garble_enabled&&(cmd_verb==ARJ_CMD_EXTRACT||cmd_verb==ARJ_CMD_TEST)))
2270 {
2271 garble_enabled=1;
2272 tmp_ptr=(char *)malloc_msg(INPUT_LENGTH+1);
2273 msg_cprintf(0, M_ENTER_PWD);
2274 read_line_noecho(tmp_ptr, INPUT_LENGTH);
2275 garble_password=malloc_str(tmp_ptr);
2276 free(tmp_ptr);
2277 }
2278 if(chk_free_space)
2279 alloc_unit_size=get_bytes_per_cluster(target_dir);
2280 if(process_lfn_archive==1)
2281 lfn_supported=LFN_NOT_SUPPORTED;
2282 #if SFX_LEVEL>=ARJ
2283 if(garble_enabled)
2284 {
2285 enc_version=garble_init(0);
2286 if(ext_hdr_flags!=0&&enc_version!=ext_hdr_flags)
2287 error(M_WRONG_ENC_VERSION, ext_hdr_flags);
2288 }
2289 #endif
2290 }
2291 #else
2292 if(!skip_preset_options)
2293 cmt_ptr=preprocess_comment(cmt_ptr);
2294 if(quiet_mode&&!yes_on_all_queries)
2295 quiet_mode=0;
2296 if(quiet_mode)
2297 freopen(dev_null, m_w, stdout);
2298 if(!process_lfn_archive)
2299 lfn_supported=LFN_NOT_SUPPORTED;
2300 msg_cprintf(H_HL|H_NFMT, M_ARJSFX_BANNER, exe_name);
2301 msg_cprintf(H_HL|H_NFMT, M_PROCESSING_ARCHIVE, archive_name);
2302 logo_shown=1;
2303 timestamp_to_str(timetext, &ftime_stamp);
2304 msg_cprintf(H_HL|H_NFMT, M_ARCHIVE_CREATED, timetext);
2305 if(show_ansi_comments)
2306 fputs(cmt_ptr, stdout);
2307 else
2308 display_comment(cmt_ptr);
2309 /* The sfx_setup() occurs here */
2310 if(list_sfx_cmd)
2311 cmd_verb=ARJ_CMD_LIST;
2312 else if(verbose_list)
2313 {
2314 cmd_verb=ARJ_CMD_LIST;
2315 std_list_cmd=1;
2316 }
2317 else if(test_sfx_cmd)
2318 cmd_verb=ARJ_CMD_TEST;
2319 else
2320 {
2321 cmd_verb=ARJ_CMD_EXTR_NP;
2322 test_mode=1;
2323 }
2324 if(garble_enabled&&garble_password[0]=='\0')
2325 error(M_NO_PWD_OPTION);
2326 if(file_args==0)
2327 f_arg_array[file_args++]=all_wildcard;
2328 case_path(target_dir);
2329 for(i=0; i<file_args; i++)
2330 {
2331 strcpy(tmp_name, f_arg_array[i]);
2332 case_path(tmp_name);
2333 add_f_arg(tmp_name);
2334 }
2335 if(cmd_verb==ARJ_CMD_EXTR_NP&&!yes_on_all_queries&&!skip_extract_query)
2336 {
2337 msg_cprintf(0, M_CONTINUE_EXTRACTION);
2338 if(!query_action())
2339 exit(ARJSFX_ERL_ERROR);
2340 }
2341 #endif
2342 #if SFX_LEVEL>=ARJSFXV
2343 if(!first_vol_passed&&prompt_for_directory)
2344 #else
2345 if(prompt_for_directory)
2346 #endif
2347 {
2348 query_result=0;
2349 if(target_dir[0]!='\0')
2350 {
2351 #if SFX_LEVEL>=ARJSFXV
2352 msg_sprintf(misc_buf, M_QUERY_DEST_DIR, target_dir);
2353 query_result=query_action(REPLY_YES, QUERY_CRITICAL, (FMSG *)misc_buf);
2354 #else
2355 msg_cprintf(H_HL|H_NFMT, M_QUERY_DEST_DIR, target_dir);
2356 query_result=query_action();
2357 #endif
2358 }
2359 if(!query_result)
2360 {
2361 msg_cprintf(0, M_ENTER_INSTALL_DIR);
2362 read_line(target_dir, FILENAME_MAX-2);
2363 alltrim(target_dir);
2364 if(target_dir[0]!='\0')
2365 {
2366 if(target_dir[lt=strlen(target_dir)-1]!=PATHSEP_DEFAULT)
2367 {
2368 target_dir[lt+1]=PATHSEP_DEFAULT;
2369 target_dir[lt+2]='\0';
2370 }
2371 case_path(target_dir);
2372 }
2373 }
2374 }
2375 if(security_state&&!skip_integrity_test)
2376 {
2377 if(get_arjsec_signature(aistream, arjsec_offset, arjsec_signature, ARJSEC_ITER))
2378 {
2379 arj_delay(5);
2380 error(M_DAMAGED_SEC_ARCHIVE);
2381 }
2382 licensed_sfx=1;
2383 }
2384 if(test_sfx_cmd&&cmd_verb==ARJ_CMD_EXTRACT)
2385 {
2386 last_hdr_offset=ftell(aistream);
2387 #if SFX_LEVEL>=ARJSFXV
2388 while(read_header(0, aistream, archive_name))
2389 #else
2390 while(read_header(0))
2391 #endif
2392 unpack_validation();
2393 if(errors!=0)
2394 error(M_FOUND_N_ERRORS, errors);
2395 fseek(aistream, last_hdr_offset, SEEK_SET);
2396 }
2397 #if SFX_LEVEL>=ARJSFXV
2398 ts_store(&ftime_stamp, OS, 0L);
2399 if(first_volume_number!=0)
2400 {
2401 volume_number=first_volume_number;
2402 first_volume_number=0;
2403 first_vol_passed=1;
2404 no_in_arch=1;
2405 }
2406 else
2407 no_in_arch=0;
2408 #endif
2409 #if SFX_LEVEL>=ARJSFXV
2410 while(!no_in_arch&&read_header(0, aistream, archive_name))
2411 #else
2412 while(read_header(0))
2413 #endif
2414 {
2415 pf_num=flist_lookup();
2416 #if SFX_LEVEL>=ARJSFXV
2417 cf_num++;
2418 #endif
2419 switch(cmd_verb)
2420 {
2421 case ARJ_CMD_EXTR_NP:
2422 case ARJ_CMD_EXTRACT:
2423 if(pf_num!=0)
2424 {
2425 if(unpack_file_proc())
2426 total_files++;
2427 tmp_tmp_filename[0]='\0';
2428 }
2429 else
2430 skip_compdata();
2431 break;
2432 case ARJ_CMD_LIST:
2433 if(pf_num!=0)
2434 {
2435 #if SFX_LEVEL>=ARJSFXV
2436 if(list_cmd(total_files, cf_num))
2437 total_files++;
2438 #else
2439 list_cmd();
2440 total_files++;
2441 #endif
2442 }
2443 skip_compdata();
2444 break;
2445 case ARJ_CMD_TEST:
2446 if(pf_num!=0)
2447 {
2448 if(unpack_validation())
2449 total_files++;
2450 #if SFX_LEVEL>ARJSFXV /* Avoid to skip data twice! Is this "minimal" fix safe????? */
2451 else
2452 skip_compdata();
2453 #endif
2454 }
2455 else
2456 skip_compdata();
2457 break;
2458 }
2459 }
2460 #if SFX_LEVEL>=ARJSFXV
2461 total_processed+=total_files+comment_entries;
2462 av_compressed+=total_compressed;
2463 av_uncompressed+=total_uncompressed;
2464 av_total_files+=total_files;
2465 #endif
2466 #if SFX_LEVEL>=ARJSFXV
2467 if(cmd_verb==ARJ_CMD_LIST)
2468 #else
2469 if(cmd_verb==ARJ_CMD_LIST&&total_files>0)
2470 #endif
2471 {
2472 msg_cprintf(0, M_BRIEF_LIST_SEPARATOR);
2473 #if SFX_LEVEL>=ARJSFXV
2474 msg_ptr=nullstr;
2475 #endif
2476 ratio=calc_percentage(total_compressed, total_uncompressed);
2477 #if SFX_LEVEL>=ARJSFXV
2478 msg_cprintf(H_HL|H_NFMT, M_TOTAL_STATS, total_files, total_uncompressed, total_compressed, ratio/1000, ratio%1000, msg_ptr, nullstr);
2479 if(av_total_files>total_files)
2480 msg_cprintf(H_HL|H_NFMT, M_TOTAL_STATS, av_total_files, av_uncompressed, av_compressed, ratio/1000, ratio%1000, nullstr, nullstr);
2481 #else
2482 msg_cprintf(H_HL|H_NFMT, M_TOTAL_STATS, total_files, total_uncompressed, total_compressed, ratio/1000, ratio%1000);
2483 #endif
2484 #if SFX_LEVEL>=ARJSFXV
2485 if(chk_free_space)
2486 {
2487 free_space=file_getfree(target_dir);
2488 if(disk_space_used+minfree>free_space)
2489 {
2490 msg_cprintf(H_ALERT, M_NOT_ENOUGH_SPACE_X, disk_space_used+minfree-free_space);
2491 errors++;
2492 }
2493 }
2494 #endif
2495 }
2496 else
2497 {
2498 #if SFX_LEVEL>=ARJSFXV
2499 msg_cprintf(H_HL|H_NFMT, M_N_FILES, total_files);
2500 if(comment_entries!=0)
2501 msg_cprintf(H_HL|H_NFMT, M_N_COMMENTS, comment_entries);
2502 #else
2503 msg_cprintf(H_HL|H_NFMT, M_N_FILES, total_files);
2504 #endif
2505 }
2506 #if SFX_LEVEL>=ARJSFXV
2507 file_close(aistream);
2508 #else
2509 fclose(aistream);
2510 #endif
2511 #if SFX_LEVEL>=ARJSFXV
2512 aistream=NULL;
2513 if(total_processed==0&&!continued_nextvolume)
2514 {
2515 if(errorlevel==ARJ_ERL_SUCCESS)
2516 errorlevel=ARJ_ERL_WARNING;
2517 errors++;
2518 }
2519 #endif
2520 if(valid_envelope)
2521 msg_cprintf(H_HL|H_NFMT, M_VALID_ARJSEC, arjsec_signature);
2522 #if SFX_LEVEL<=ARJSFX
2523 /* ARJDISP cleanup */
2524 if(arjdisp_enabled)
2525 {
2526 cmd_verb=ARJDISP_CMD_END;
2527 display_indicator(0L);
2528 }
2529 #endif
2530 }
2531
2532 #endif
2533
2534 #if SFX_LEVEL>=ARJSFXV
2535
2536 /* Performs all archive processing actions including setup and so on... */
2537
2538 #if SFX_LEVEL>=ARJ
perform_cmd(int cmd)2539 void perform_cmd(int cmd)
2540 #else
2541 void perform_cmd()
2542 #endif
2543 {
2544 char *tmp_ptr;
2545 char *syscmd;
2546 int vol_num;
2547 unsigned long arch_time;
2548 char reply;
2549 #if SFX_LEVEL>=ARJ
2550 int tries;
2551 int proc_rc;
2552 #endif
2553
2554 #if SFX_LEVEL>=ARJ
2555 /* Set up ARJ$DISP screen if needed */
2556 if(arjdisp_enabled)
2557 {
2558 cmd_verb=ARJDISP_CMD_START;
2559 filename[0]='+';
2560 filename[1]='\0';
2561 uncompsize=compsize=0L;
2562 display_indicator(0L);
2563 }
2564 #endif
2565 ofstream=NULL;
2566 volume_flag_set=0;
2567 first_vol_passed=0;
2568 continued_nextvolume=0;
2569 total_processed=0;
2570 volume_number=0;
2571 resume_position=0L;
2572 is_removable=0;
2573 #if SFX_LEVEL>=ARJ
2574 if(eh!=NULL)
2575 {
2576 eh_release(eh);
2577 eh=NULL;
2578 }
2579 comment=NULL;
2580 tmp_filename=NULL;
2581 encstream=NULL;
2582 vol_file_num=0;
2583 split_files=0;
2584 dual_name=0;
2585 ansi_codepage=0;
2586 arjprot_tail=0;
2587 ext_hdr_flags=0;
2588 sfx_desc_word=0;
2589 total_chapters=0;
2590 recent_chapter=0;
2591 max_chapter=0;
2592 prot_blocks=0;
2593 #endif
2594 #if SFX_LEVEL>=ARJ
2595 modify_command=msg_strchr(M_MODIFY_COMMANDS, (char)cmd)!=NULL;
2596 add_command=msg_strchr(M_ADD_COMMANDS, (char)cmd)!=NULL;
2597 order_command=cmd==ARJ_CMD_ORDER;
2598 get_totals();
2599 if((tmp_ptr=strchr(debug_opt, 'o'))!=NULL)
2600 convert_strtime(&secondary_ftime, ++tmp_ptr);
2601 else
2602 ts_store(&secondary_ftime, OS_SPECIAL, 0L);
2603 if(resume_volume_num!=0)
2604 {
2605 volume_number=resume_volume_num;
2606 resume_volume_num=0;
2607 first_vol_passed=1;
2608 }
2609 if(start_at_ext_pos)
2610 {
2611 resume_position=ext_pos;
2612 continued_prevvolume=1;
2613 mvfile_type=-1;
2614 }
2615 t_volume_offset=mv_reserve_space;
2616 #endif
2617 comment=farmalloc_msg(COMMENT_MAX);
2618 comment[0]='\0';
2619 tmp_filename=farmalloc_msg(FILENAME_MAX);
2620 tmp_filename[0]='\0';
2621 is_removable=file_is_removable(archive_name);
2622 #if SFX_LEVEL>=ARJ
2623 if(mv_cmd_state!=MVC_NONE)
2624 {
2625 if(mv_cmd[0]!='\0')
2626 {
2627 if(mv_cmd_state==MVC_DELETION)
2628 delete_files(mv_cmd);
2629 else if(mv_cmd_state==MVC_RUN_CMD)
2630 {
2631 msg_cprintf(H_PROMPT, M_COMMAND);
2632 msg_cprintf(H_HL|H_NFMT, M_FILENAME_FORM, mv_cmd);
2633 #if TARGET==UNIX
2634 nputlf();
2635 #endif
2636 exec_cmd(mv_cmd);
2637 }
2638 }
2639 else
2640 {
2641 syscmd=(char *)malloc_msg(CMDLINE_LENGTH+1);
2642 while(1)
2643 {
2644 msg_cprintf(0, M_ENTER_CMD_EXIT);
2645 msg_cprintf(H_PROMPT, M_COMMAND);
2646 read_line(syscmd, CMDLINE_LENGTH);
2647 alltrim(syscmd);
2648 msg_strcpy(strcpy_buf, M_EXIT_CMD);
2649 if(!stricmp(strcpy_buf, syscmd))
2650 break;
2651 if(syscmd[0]!='\0')
2652 exec_cmd(syscmd);
2653 }
2654 free(syscmd);
2655 }
2656 }
2657 #endif
2658 /* The archive processing itself occurs now */
2659 #if SFX_LEVEL>=ARJ
2660 proc_rc=process_archive_proc(cmd);
2661 #else
2662 process_archive();
2663 #endif
2664 #if SFX_LEVEL>=ARJ
2665 if(multivolume_option&&!proc_rc)
2666 #else
2667 if(multivolume_option)
2668 #endif
2669 {
2670 is_removable=file_is_removable(archive_name);
2671 #if SFX_LEVEL>=ARJ
2672 t_volume_offset=0L;
2673 tries=0;
2674 #endif
2675 first_vol_passed=1;
2676 #if SFX_LEVEL>=ARJ
2677 vol_num=volume_number;
2678 #endif
2679 while(continued_nextvolume)
2680 {
2681 #if SFX_LEVEL>=ARJ
2682 arch_time=file_getftime(archive_name);
2683 do
2684 {
2685 if(vol_num!=volume_number)
2686 {
2687 tries=0;
2688 vol_num=volume_number;
2689 }
2690 if(++tries>MAX_VOLUME_TRIES)
2691 {
2692 if(errorlevel==ARJ_ERL_SUCCESS)
2693 errorlevel=ARJ_ERL_FATAL_ERROR;
2694 errors++;
2695 goto all_volumes_done;
2696 }
2697 if(beep_between_volumes)
2698 msg_cprintf(0, (FMSG *)bell);
2699 if((!is_removable||skip_next_vol_query)&&(yes_on_all_queries||skip_next_vol_query))
2700 break;
2701 reply=M_YES[0];
2702 if(is_removable)
2703 msg_sprintf(misc_buf, M_INSERT_DISKETTE, volume_number, reply);
2704 else
2705 msg_sprintf(misc_buf, M_QUERY_NEXT_VOLUME, volume_number);
2706 if(!query_action(REPLY_YES, QUERY_NEXT_VOLUME, (FMSG *)misc_buf))
2707 {
2708 if(errorlevel==ARJ_ERL_SUCCESS)
2709 errorlevel=ARJ_ERL_WARNING;
2710 errors++;
2711 goto all_volumes_done;
2712 }
2713 if(inhibit_change_test||tries>MAX_VOLUME_FT_CHECKS||!is_removable)
2714 break;
2715 if(!file_exists(archive_name))
2716 break;
2717 } while(file_getftime(archive_name)==arch_time);
2718 if(mv_cmd_state!=MVC_NONE)
2719 {
2720 if(mv_cmd[0]!='\0')
2721 {
2722 if(mv_cmd_state==MVC_DELETION)
2723 delete_files(mv_cmd);
2724 else if(mv_cmd_state==MVC_RUN_CMD)
2725 {
2726 msg_cprintf(H_PROMPT, M_COMMAND);
2727 printf(strform, mv_cmd);
2728 exec_cmd(mv_cmd);
2729 }
2730 }
2731 else
2732 {
2733 syscmd=(char *)malloc_msg(CMDLINE_LENGTH+1);
2734 while(1)
2735 {
2736 msg_cprintf(0, M_ENTER_CMD_EXIT);
2737 msg_cprintf(H_PROMPT, M_COMMAND);
2738 read_line(syscmd, CMDLINE_LENGTH);
2739 alltrim(syscmd);
2740 msg_strcpy(strcpy_buf, M_EXIT_CMD);
2741 if(!stricmp(strcpy_buf, syscmd))
2742 break;
2743 if(syscmd[0]!='\0')
2744 exec_cmd(syscmd);
2745 }
2746 free(syscmd);
2747 }
2748 }
2749 if(pause_between_volumes)
2750 arj_delay(change_vol_delay);
2751 #else
2752 if(!yes_on_all_queries&&!skip_next_vol_query)
2753 msg_cprintf(0, (FMSG *)bell);
2754 if((is_removable&&!skip_next_vol_query)||(!yes_on_all_queries&&!skip_next_vol_query))
2755 {
2756 reply=M_YES[0];
2757 if(is_removable)
2758 msg_sprintf(misc_buf, M_INSERT_DISKETTE, volume_number, reply);
2759 else
2760 msg_sprintf(misc_buf, M_QUERY_NEXT_VOLUME, volume_number);
2761 if(!query_action(REPLY_YES, QUERY_CRITICAL, (FMSG *)misc_buf))
2762 {
2763 if(errorlevel==ARJ_ERL_SUCCESS)
2764 errorlevel=ARJ_ERL_WARNING;
2765 errors++;
2766 break;
2767 }
2768 }
2769 #endif
2770 /* Process next volume... */
2771 #if SFX_LEVEL>=ARJ
2772 process_archive_proc(cmd);
2773 #else
2774 process_archive();
2775 #endif
2776 }
2777 all_volumes_done:
2778 #if SFX_LEVEL>=ARJ
2779 if(beep_between_volumes)
2780 msg_cprintf(0, (FMSG *)bell);
2781 #else
2782 if(volume_number>1)
2783 msg_cprintf(0, (FMSG *)bell);
2784 #endif
2785 }
2786 if(ofstream!=NULL)
2787 {
2788 file_close(ofstream);
2789 ofstream=NULL;
2790 far_strcpy((char FAR *)filename, tmp_filename);
2791 file_setftime(filename, ts_native(&volume_ftime, OS));
2792 }
2793 #if SFX_LEVEL>=ARJ
2794 if(tmp_filename!=NULL)
2795 farfree(tmp_filename);
2796 if(comment!=NULL)
2797 farfree(comment);
2798 #else
2799 farfree(tmp_filename);
2800 farfree(comment);
2801 #endif
2802 #if SFX_LEVEL>=ARJ
2803 /* ARJDISP cleanup */
2804 if(arjdisp_enabled)
2805 {
2806 cmd_verb=ARJDISP_CMD_END;
2807 display_indicator(0L);
2808 }
2809 #endif
2810 }
2811
2812 #endif
2813