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&&current_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&&current_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&&timestamp_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&&reg_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&&current_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