1 /*
2 * $Id: arj.c,v 1.13 2005/06/21 19:53:13 andrew_belov Exp $
3 * ---------------------------------------------------------------------------
4 * This is the main file of the ARJ project. The routines in this file have
5 * a wide variety of purposes, however, all archive-related procedures are NOT
6 * put into ARJ.C.
7 *
8 */
9
10 #include <stdio.h>
11 #include <signal.h>
12
13 #include "arj.h"
14
15 DEBUGHDR(__FILE__) /* Debug information block */
16
17 /* Expiry date/time */
18
19 #define EXPIRABLE 0 /* 1 -> allow expiry as such */
20
21 #define EXPIRY_YR 1980
22 #define EXPIRY_MO 1
23 #define EXPIRY_DY 1
24 #define EXPIRY_H 0
25 #define EXPIRY_M 0
26 #define EXPIRY_S 0
27
28 /* Local variables */
29
30 static char fixed_arjtemp[]="ARJTEMP.$$$";
31 static char arjtemp_wildcard[]="ARJTEMP.$??";
32 static char wildcard_pattern[]="?*[]^";
33 static int tmp_archive_exists;
34 static int tmp_archive_removed;
35 static unsigned long ticks;
36 static unsigned int limit;
37 static char brief_help[]="arjs.txt";
38 static char full_help[]="arjl.txt";
39 static char sort_filename[]="arjsort.$$$";
40 static char *arj_env_str=NULL;
41 static char single_spc[]=" ";
42
43 /* Forward references */
44
45 static void finish_archive_name(char *name);
46 static void final_cleanup(void);
47
48 /* Checks if all the files given to ARJ were successfully processed. */
49
file_arg_cleanup(struct flist_root * flist)50 static void file_arg_cleanup(struct flist_root *flist)
51 {
52 int cur_arg;
53 FILE_COUNT cur_file;
54 char *tmp_name;
55
56 for(cur_arg=0; cur_arg<file_args; cur_arg++)
57 {
58 if(order[cur_arg]==0&&strcmp_os(f_arg_array[cur_arg], nonexist_name))
59 {
60 msg_cprintf(H_ERR, M_CANT_FIND, f_arg_array[cur_arg]);
61 if(errorlevel==ARJ_ERL_SUCCESS)
62 errorlevel=ARJ_ERL_WARNING;
63 errors++;
64 }
65 }
66 if(flist->files>0)
67 {
68 tmp_name=malloc_msg(FILENAME_MAX);
69 for(cur_file=0; cur_file<flist->files; cur_file++)
70 {
71 flist_retrieve(tmp_name, NULL, flist, cur_file);
72 msg_cprintf(H_ERR, M_CANT_FIND, tmp_name);
73 if(listfile_err_opt)
74 {
75 if(errorlevel==ARJ_ERL_SUCCESS)
76 errorlevel=ARJ_ERL_WARNING;
77 errors++;
78 }
79 }
80 free(tmp_name);
81 }
82 }
83
84 /* Depending on the command given, issues some special setup */
85
cmd_setup(int * cmd,int * is_add_cmd)86 static void cmd_setup(int *cmd, int *is_add_cmd)
87 {
88 int cnv_cmd;
89 int add_cmd;
90 char *tmp_swptr;
91 char *vptr;
92 unsigned long vol_size;
93
94 cnv_cmd=*cmd;
95 switch(*cmd)
96 {
97 case ARJ_CMD_MOVE:
98 cnv_cmd=ARJ_CMD_ADD;
99 delete_processed=DP_ADD;
100 case ARJ_CMD_ADD:
101 if(freshen_criteria)
102 cnv_cmd=ARJ_CMD_FRESHEN;
103 if(update_criteria)
104 cnv_cmd=ARJ_CMD_UPDATE;
105 break;
106 case ARJ_CMD_REM_BAK:
107 current_chapter=RESERVED_CHAPTER;
108 break;
109 case ARJ_CMD_FRESHEN:
110 if(freshen_criteria==FC_NONE)
111 freshen_criteria=FC_EXISTING;
112 break;
113 case ARJ_CMD_UPDATE:
114 if(update_criteria==FC_NONE)
115 update_criteria=FC_EXISTING;
116 break;
117 case ARJ_CMD_SECURE:
118 sign_with_arjsec=1;
119 break;
120 case ARJ_CMD_ADDC:
121 cnv_cmd=ARJ_CMD_UPDATE;
122 update_criteria=UC_NEW_OR_DIFFERENT;
123 chapter_mode=CHAP_USE;
124 break;
125 case ARJ_CMD_CNVC:
126 cnv_cmd=ARJ_CMD_COPY;
127 chapter_mode=CHAP_USE;
128 break;
129 case ARJ_CMD_DELC:
130 cnv_cmd=ARJ_CMD_DELETE;
131 chapter_mode=CHAP_USE;
132 break;
133 case ARJ_CMD_EXEC:
134 cnv_cmd=ARJ_CMD_EXTR_NP;
135 execute_cmd=1;
136 if(extraction_filename[0]=='\0')
137 {
138 extraction_filename=fixed_arjtemp;
139 extract_to_file=1;
140 }
141 break;
142 case ARJ_CMD_SAMPLE:
143 cnv_cmd=ARJ_CMD_PRINT;
144 print_with_more=1;
145 break;
146 case ARJ_CMD_PRINT:
147 if(!prompt_for_more)
148 break;
149 print_with_more=1;
150 break;
151 case ARJ_CMD_V_LIST:
152 cnv_cmd=ARJ_CMD_LIST;
153 std_list_cmd=1;
154 break;
155 case ARJ_CMD_EXTRACT:
156 cnv_cmd=ARJ_CMD_EXTR_NP;
157 subdir_extraction=1;
158 break;
159 }
160 if(cnv_cmd==ARJ_CMD_EXTR_NP&&delete_processed&&!execute_cmd)
161 {
162 cnv_cmd=ARJ_CMD_DELETE;
163 delete_processed=DP_EXTRACT;
164 }
165 add_cmd=msg_strchr(M_ADD_COMMANDS, (char)cnv_cmd)!=NULL;
166 if(file_args<0)
167 {
168 if(!append_curtime)
169 error(M_NO_FILE_GIVEN);
170 else
171 {
172 archive_name[0]='\0';
173 file_args++;
174 finish_archive_name(archive_name);
175 }
176 }
177 if(cnv_cmd==ARJ_CMD_DELETE&&file_args==0&&delete_processed!=DP_EXTRACT)
178 error(M_NO_DELETE_ARG);
179 if(cnv_cmd!=ARJ_CMD_COMMENT&&msg_strchr(M_MODIFY_COMMANDS, (char)cnv_cmd)!=NULL&¤t_chapter!=0&¤t_chapter<=CHAPTERS_MAX)
180 error(M_BAD_SYNTAX);
181 if(add_cmd&&multivolume_option)
182 {
183 if(volume_limit<MIN_VOLUME_SIZE)
184 error(M_INVALID_VOL_SIZE);
185 /* ASR fix. This was dropped in original ARJ but stays here, with a fix to
186 treat -va adequately. */
187 if(protfile_option)
188 {
189 vol_size=(unsigned long)calc_protdata_size(volume_limit, protfile_option)+MIN_VOLUME_SIZE;
190 if(volume_limit<vol_size&&multivolume_option!=MV_AVAIL)
191 error(M_PROTFILE_EXCEEDS, vol_size);
192 }
193 }
194 if(add_command&&strpbrk(archive_name, wildcard_pattern)!=NULL)
195 error(M_CANTOPEN, archive_name);
196 if(cnv_cmd==ARJ_CMD_COPY&&file_args>0)
197 error(M_BAD_SYNTAX);
198 if(win32_platform&&lfn_mode==LFN_DUAL)
199 error(M_BAD_SYNTAX);
200 if(chapter_mode==CHAP_REMOVE&&cnv_cmd!=ARJ_CMD_COPY)
201 error(M_BAD_SYNTAX);
202 if(test_archive_crc>=TC_CRC_AND_CONTENTS&&exclude_paths)
203 error(M_JT_UNUSABLE, "-e/-e1");
204 if(test_archive_crc>=TC_CRC_AND_CONTENTS&&fix_longnames)
205 error(M_JT_UNUSABLE, "-2l");
206 if(arcmail_sw&&serialize_exts)
207 error(M_JO_UNUSABLE, "-2a");
208 #if TARGET==DOS
209 if(priority.class!=0)
210 error(M_OS_DEPENDENT, "-2p");
211 #endif
212 if(ea_supported&&restart_at_filename)
213 error(M_CANT_RESTART_W_EAS);
214 if(assign_work_directory&&work_directory[0]=='\0')
215 error(M_MISSING_FILENAME_ARG, "-w");
216 if(extract_to_file&&extraction_filename[0]=='\0')
217 error(M_MISSING_FILENAME_ARG, "-jw");
218 if(create_list_file&&list_file[0]=='\0')
219 error(M_MISSING_FILENAME_ARG, "-l");
220 if(create_index&&index_name[0]=='\0')
221 error(M_MISSING_FILENAME_ARG, "-ji");
222 if(restart_at_filename&&filename_to_restart[0]=='\0'&&index_name[0]=='\0')
223 error(M_MISSING_FILENAME_ARG, "-jn");
224 if((cnv_cmd==ARJ_CMD_EXTR_NP||cnv_cmd==ARJ_CMD_EXTRACT)&&use_comment&&archive_cmt_name[0]=='\0')
225 error(M_MISSING_FILENAME_ARG, "-z");
226 if(chk_arj_version)
227 {
228 tmp_swptr=swptr_hv;
229 if(tmp_swptr[0]=='\0'||tmp_swptr[0]=='R'||tmp_swptr[0]=='r')
230 {
231 if(!is_registered)
232 exit(ARJ_ERL_WARNING);
233 else if(tmp_swptr[0]!='\0')
234 tmp_swptr++;
235 }
236 if(tmp_swptr[0]!='\0')
237 {
238 msg_strcpy(strcpy_buf, M_VERSION);
239 vptr=strcpy_buf;
240 if(vptr[0]<tmp_swptr[0])
241 exit(ARJ_ERL_WARNING);
242 if(vptr[0]==tmp_swptr[0])
243 {
244 vptr+=2;
245 tmp_swptr+=2; /* Skip over "." */
246 if(vptr[0]<tmp_swptr[0])
247 exit(ARJ_ERL_WARNING);
248 if(vptr[0]==tmp_swptr[0])
249 {
250 vptr++;
251 tmp_swptr++;
252 if(vptr[0]<tmp_swptr[0])
253 exit(ARJ_ERL_WARNING);
254 if(vptr[0]==tmp_swptr[0])
255 {
256 vptr++;
257 tmp_swptr++;
258 if(vptr[0]<tmp_swptr[0])
259 exit(ARJ_ERL_WARNING);
260 }
261 }
262 }
263 }
264 }
265 if(file_args==0)
266 f_arg_array[file_args++]=all_wildcard;
267 method_specifier=(custom_method==0)?1:custom_method-1;
268 if(create_sfx)
269 {
270 if(method_specifier==4)
271 error(M_INVALID_METHOD_SFX);
272 if(chapter_mode)
273 error(M_CHAPTER_SFX_CREATION);
274 if(create_sfx==SFXCRT_SFXJR&&type_override&&primary_file_type==ARJT_TEXT)
275 error(M_TEXTMODE_LFN_SFXJR);
276 #if TARGET==DOS
277 if(create_sfx==SFXCRT_SFXJR&&lfn_supported!=LFN_NOT_SUPPORTED)
278 error(M_TEXTMODE_LFN_SFXJR);
279 #endif
280 #if defined(HAVE_EAS)
281 if(create_sfx==SFXCRT_SFXJR&&ea_supported)
282 error(M_TEXTMODE_LFN_SFXJR);
283 #endif
284 #if TARGET==UNIX
285 if(create_sfx==SFXCRT_SFXJR&&dos_host)
286 error(M_DOS_MODE_SFXJR);
287 #endif
288 if(create_sfx==SFXCRT_SFXJR&&garble_enabled)
289 error(M_NO_GARBLE_IN_SFXJR);
290 if(msg_strchr(M_MODIFY_COMMANDS, (char)cnv_cmd)==NULL)
291 error(M_INVALID_SFX_SW_USE);
292 if(create_sfx==SFXCRT_SFXJR&&multivolume_option)
293 error(M_MULTIVOLUME_SFXJR);
294 }
295 if(debug_enabled&&strchr(debug_opt, 'n')!=NULL)
296 no_file_activity=1;
297 if(ignore_crc_errors)
298 keep_tmp_file=1;
299 if(exit_after_count&&exit_count==0)
300 exit_count=file_args;
301 if(handle_labels&&label_drive=='\0'&&target_dir[0]!='\0'&&target_dir[1]==':')
302 label_drive=target_dir[0];
303 if(filelist_storage==BST_NONE&&!win32_platform)
304 {
305 filelist_storage=BST_DISK;
306 max_filenames=3000;
307 }
308 *cmd=cnv_cmd;
309 *is_add_cmd=add_cmd;
310 }
311
312 /* Gets the command for execution */
313
get_exec_cmd()314 static void get_exec_cmd()
315 {
316 if(set_string_parameter&&string_parameter[0]!='\0')
317 cmd_to_exec=string_parameter;
318 else
319 {
320 while(header[0]=='\0')
321 {
322 msg_cprintf(0, M_ENTER_CMD);
323 read_line(header, HEADERSIZE_MAX);
324 }
325 cmd_to_exec=malloc_str(header);
326 }
327 }
328
329 /* Picks an extension from the -hx extension list */
330
fetch_extension(int offset,char * dest)331 static int fetch_extension(int offset, char *dest)
332 {
333 int c_offset;
334
335 if(strlen(archive_ext_list)<offset)
336 return(0);
337 while(archive_ext_list[offset]!='\0'&&archive_ext_list[offset]!='.') offset++;
338 if(archive_ext_list[offset]=='\0')
339 return(0);
340 c_offset=offset;
341 do
342 offset++;
343 while(c_offset+6>offset&&archive_ext_list[offset]!='\0'&&archive_ext_list[offset]!='.');
344 while(c_offset<offset)
345 *(dest++)=archive_ext_list[c_offset++];
346 *dest='\0';
347 return(offset);
348 }
349
350 /* Adds ARJ extension to the archive name */
351
finish_archive_name(char * name)352 static void finish_archive_name(char *name)
353 {
354 int n_len;
355 char last_char;
356 int offset;
357 char ext_pad[EXTENSION_MAX+2]; /* +2 means space for '.' and '\0' */
358 int entry;
359
360 if(name[0]=='\0')
361 msg_strcpy(name, M_EXT_ARJ);
362 n_len=strlen(name);
363 entry=split_name(name, NULL, NULL);
364 last_char=name[n_len-1];
365 if(last_char=='.')
366 name[n_len-1]='\0';
367 else if(strchr(name+entry, '.')==NULL)
368 {
369 /* create_sfx is an ASR fix for 2.77 (empty extension on UNIX) */
370 if(!override_archive_exts)
371 {
372 #ifdef NULL_EXE_EXTENSION
373 if(!create_sfx)
374 msg_strcpy(name+n_len, M_EXT_ARJ);
375 else
376 name[n_len]='\0';
377 #else
378 msg_strcpy(name+n_len, M_EXT_ARJ);
379 #endif
380 if(lfn_supported==LFN_NOT_SUPPORTED)
381 strupper(name+n_len);
382 }
383 else
384 {
385 offset=0;
386 while((offset=fetch_extension(offset, ext_pad))!=0)
387 {
388 strcpy(name+n_len, ext_pad);
389 if(file_exists(name))
390 break;
391 }
392 if(offset==0)
393 {
394 fetch_extension(0, ext_pad);
395 strcpy(name+n_len, ext_pad);
396 }
397 }
398 }
399 }
400
401 /* Converts a filename entered from command-line to standard form */
402
cnv_cmdline_fnm(char * name)403 static void cnv_cmdline_fnm(char *name)
404 {
405 strip_lf(name);
406 alltrim(name);
407 if(translate_unix_paths)
408 unix_path_to_dos(name);
409 }
410
411 /* Creates an exclusion list */
412
create_excl_list(char * names)413 void create_excl_list(char *names)
414 {
415 char tmp_name[FILENAME_MAX];
416 FILE *stream;
417
418 if(listchars_allowed&&names[0]==listchar)
419 {
420 if(*++names=='\0')
421 error(M_MISSING_FILENAME_ARG, "-x");
422 unix_path_to_dos(names);
423 stream=file_open_noarch(names, m_r);
424 while(fgets(tmp_name, sizeof(tmp_name), stream)!=NULL)
425 {
426 cnv_cmdline_fnm(tmp_name);
427 if(tmp_name[0]!='\0')
428 flist_add_files(&flist_exclusion, NULL, tmp_name, 0, 0, 0, NULL);
429 }
430 fclose(stream);
431 }
432 else
433 flist_add_files(&flist_exclusion, NULL, names, 0, 0, 0, NULL);
434 }
435
436 /* Parses the command line, taking filename argument. Returns the command
437 code. */
438
parse_cmdline(char * token,int cmd)439 static int parse_cmdline(char *token, int cmd)
440 {
441 int name_len;
442 char *endptr;
443 char end_sym;
444
445 if(debug_enabled&&strchr(debug_opt, 'v')!=NULL)
446 msg_cprintf(H_HL|H_NFMT, M_TOKEN, token);
447 if(is_switch(token))
448 analyze_arg(token);
449 else
450 {
451 if(cmd==0)
452 {
453 cmd=toupper(token[0]);
454 /* Use fake 1-byte commands for 2-byte commands */
455 if(!stricmp(token, cmd_ac))
456 return(cmd=ARJ_CMD_ADDC);
457 if(!stricmp(token, cmd_cc))
458 return(cmd=ARJ_CMD_CNVC);
459 if(!stricmp(token, cmd_dc))
460 return(cmd=ARJ_CMD_DELC);
461 if(msg_strchr(M_CMD_TABLE, (char)cmd)==NULL||strlen(token)!=1)
462 {
463 msg_cprintf(H_HL|H_NFMT, M_INVALID_COMMAND, token);
464 exit(ARJ_ERL_USER_ERROR);
465 }
466 }
467 else
468 {
469 if(file_args<0)
470 {
471 far_strcpyn((char FAR *)archive_name, (char FAR *)token, FILENAME_MAX);
472 unix_path_to_dos(archive_name);
473 alltrim(archive_name);
474 if(archive_name[0]=='\0')
475 {
476 if(!append_curtime)
477 error(M_NO_FILE_GIVEN);
478 finish_archive_name(archive_name);
479 }
480 file_args++;
481 }
482 else
483 {
484 unix_path_to_dos(token);
485 name_len=strlen(token);
486 endptr=&token[name_len-1];
487 end_sym=*endptr;
488 while(*endptr==' ')
489 endptr--;
490 if(file_args<0||strcmp_os(token, nonexist_name))
491 {
492 if(file_args==0&&!set_target_directory&&target_dir[0]=='\0'&&
493 strchr(path_separators, *endptr)!=NULL)
494 {
495 target_dir=token;
496 if(end_sym!=' ')
497 return(cmd);
498 }
499 if(file_args==0&&!set_target_directory&&target_dir[0]=='\0'&&
500 msg_strchr(M_DIR_COMMANDS, (char)cmd)!=NULL&&strpbrk(token, wildcard_pattern)==NULL&&
501 is_directory(token))
502 {
503 target_dir=malloc_msg(name_len+2);
504 strcpy(target_dir, token);
505 target_dir[name_len]=PATHSEP_DEFAULT;
506 target_dir[name_len+1]='\0';
507 }
508 else
509 {
510 if(file_args>=params_max)
511 error(M_ARGTABLE_OVERFLOW);
512 f_arg_array[file_args++]=token;
513 }
514 }
515 else
516 f_arg_array[file_args++]=token;
517 }
518 }
519 }
520 return(cmd);
521 }
522
523 /* Ctrl+C handler */
524
ctrlc_handler(SIGHDLPARAMS)525 static void ctrlc_handler(SIGHDLPARAMS)
526 {
527 ctrlc_processing=1;
528 /* Check if we are able to honor the request. If we aren't, raise the
529 signal again and make a speedy getaway. */
530 if(!ctrlc_not_busy)
531 raise(SIGINT);
532 else
533 {
534 error_occured=1; /* ARJ needs termination */
535 signal(SIGINT, NULL); /* Restore default Ctrl+C handler */
536 msg_cprintf(H_SIG, M_BREAK_SIGNALED);
537 exit(ARJ_ERL_BREAK);
538 }
539 }
540
541 /* Termination handler */
542
543 #ifndef NO_TERM_HDL
term_handler(SIGHDLPARAMS)544 static void term_handler(SIGHDLPARAMS)
545 {
546 error_occured=1; /* ARJ needs termination */
547 signal(SIGTERM, NULL);
548 msg_cprintf(H_SIG, M_SIGTERM);
549 exit(ARJ_ERL_BREAK);
550 }
551 #endif
552
553 /* Executes an OS command with checking for break */
554
exec_cmd(char * cmd)555 void exec_cmd(char *cmd)
556 {
557 flush_kbd();
558 ctrlc_not_busy=0; /* Say that we are busy */
559 system_cmd(cmd);
560 ctrlc_not_busy=1;
561 if(ctrlc_processing) /* If processing was delayed... */
562 #if COMPILER==BCC
563 ctrlc_handler();
564 #else
565 ctrlc_handler(0);
566 #endif
567 }
568
569 /* atexit routine - closes all files and frees memory */
570
final_cleanup(void)571 static void final_cleanup(void)
572 {
573 short pad;
574 static int double_shutdown=0;
575
576 file_close(idxstream);
577 file_close(aistream);
578 file_close(atstream);
579 idxstream=NULL;
580 aistream=NULL;
581 atstream=NULL;
582 if(aostream!=NULL)
583 {
584 if(last_hdr_offset>0L)
585 {
586 fseek(aostream, last_hdr_offset+2L, SEEK_SET);
587 pad=0;
588 fwrite(&pad, 1, 2, aostream);
589 }
590 file_close(aostream);
591 aostream=NULL;
592 }
593 #if TARGET!=UNIX||defined(HAVE_FCLOSEALL)
594 fcloseall();
595 #endif
596 if(tmp_archive_name!=NULL)
597 {
598 if(tmp_archive_removed)
599 {
600 rename_with_check(tmp_archive_name, archive_name);
601 tmp_archive_name[0]='\0';
602 }
603 if(!keep_tmp_archive&&tmp_archive_name[0]!='\0'&&(!tmp_archive_used||!tmp_archive_exists))
604 file_unlink(tmp_archive_name);
605 if(tmp_archive_used==1)
606 file_unlink(archive_name);
607 free(tmp_archive_name);
608 tmp_archive_name=NULL;
609 }
610 if(tmp_tmp_filename!=NULL)
611 {
612 if(!keep_tmp_file&&tmp_tmp_filename[0]!='\0')
613 file_unlink(tmp_tmp_filename);
614 free(tmp_tmp_filename);
615 tmp_tmp_filename=NULL;
616 }
617 if(debug_enabled&&strchr(debug_opt, 'v')!=NULL)
618 {
619 msg_cprintf(0, M_EXITING_PROGRAM);
620 if(double_shutdown)
621 msg_cprintf(0, M_HERE_TWICE);
622 if(verify_heap())
623 msg_cprintf(H_ERR, M_BAD_HEAP);
624 }
625 if(double_shutdown)
626 return;
627 double_shutdown=1;
628 flist_cleanup(&flist_main);
629 flist_cleanup(&flist_order);
630 flist_cleanup(&flist_exclusion);
631 flist_cleanup(&flist_archive);
632 #if defined(HAVE_EAS)
633 flist_cleanup(&flist_ea);
634 flist_cleanup(&flist_xea);
635 #endif
636 #if TARGET==UNIX
637 if(l_entries.list!=NULL)
638 farfree(l_entries.list);
639 #endif
640 if(quiet_mode)
641 freopen(dev_con, m_w, stdout);
642 if(ferror(stdout))
643 msg_fprintf(stderr, M_DISK_FULL);
644 if(debug_enabled&&strchr(debug_opt, 't')!=NULL)
645 {
646 ticks=get_ticks()-ticks;
647 msg_cprintf(H_HL|H_NFMT, M_FINAL_TIMING, ticks);
648 }
649 if(!store_by_suffix)
650 free(archive_suffixes);
651 cfa_shutdown();
652 if(arj_env_str!=NULL)
653 free_env_str(arj_env_str);
654 if(eh!=NULL)
655 {
656 eh_release(eh);
657 eh=NULL;
658 }
659 if(ntext!=NULL) /* ASR fix for 2.76.05 */
660 free(ntext);
661 free_fmsg(arj_env_name);
662 free(header);
663 free(archive_name);
664 free(misc_buf);
665 free(strcpy_buf);
666 free(exe_name);
667 farfree(order);
668 free(f_arg_array);
669 #ifdef COLOR_OUTPUT
670 scrn_reset();
671 #endif
672 }
673
674 /* Waits and then prints an error message */
675
wait_error(FMSG * errmsg)676 static void wait_error(FMSG *errmsg)
677 {
678 arj_delay(5);
679 error(errmsg);
680 }
681
682 /* Checks if the ARJ beta has expired */
683
arj_exec_validation()684 static void arj_exec_validation()
685 {
686 #if !defined(COMMERCIAL)&&EXPIRABLE==1
687 struct timestamp cur_time, expiry_time;
688 #endif
689
690 limit=0;
691 #if !defined(COMMERCIAL)&&EXPIRABLE==1
692 /* See top of this module for definitions */
693 cur_time_stamp(&cur_time);
694 make_timestamp(&expiry_time, EXPIRY_YR, EXPIRY_MO, EXPIRY_DY, EXPIRY_H, EXPIRY_M, EXPIRY_S);
695 if(ts_cmp(&cur_time, &expiry_time)>=0)
696 limit=100;
697 #endif
698 /* The EXE validation must occur here. Skipped for speed-up */
699 }
700
701 /* This is not an optimization -- ASR fix for High C -- 05/04/2001 */
702
703 #if COMPILER==HIGHC&&!defined(DEBUG)
704 #pragma on(Optimize_for_space)
705 #endif
706
707 /* Main routine */
708
main(int argc,char * argv[])709 int main(int argc, char *argv[])
710 {
711 int cmd;
712 int is_add_cmd;
713 unsigned long start_time, proc_time;
714 FILE_COUNT i;
715 int j;
716 int cur_arg;
717 FILE *stream;
718 char *tmp_ptr, *tptr, *endptr;
719 int got_str=0;
720 char *name;
721 int flist_type;
722 FILE_COUNT numfiles;
723 int expand_wildcards;
724 int entry;
725 int sort_f;
726 FILE_COUNT count;
727 FILE_COUNT cur_file;
728 int ansi_cpf;
729 FILE *tmp_stdout;
730 FILE_COUNT default_capacity=EXT_FILELIST_CAPACITY;
731
732 #if TARGET==WIN32
733 win32_platform=1;
734 #else
735 win32_platform=0;
736 #endif
737 #ifdef COLOR_OUTPUT
738 no_colors=redirected=!is_tty(stdout);
739 #endif
740 errorlevel=0;
741 ignore_errors=0;
742 ansi_cpf=0;
743 in_key=1;
744 params_max=argc+PARAMS_MAX;
745 order=NULL;
746 f_arg_array=NULL;
747 #ifdef USE_TZSET
748 tzset();
749 #endif
750 ticks=get_ticks();
751 detect_lfns();
752 detect_eas();
753 ticks=get_ticks();
754 cmd=preprocess_cmdline(argc, argv);
755 set_file_apis(use_ansi_cp); /* ARJ32 only (from v 2.72) */
756 #ifndef NO_FATAL_ERROR_HDL
757 install_smart_handler();
758 #endif
759 /* Perform STDOUT setup -- ASR fix for IBM C Set++, VisualAge C++ and
760 GLIBC builds */
761 #ifdef STDOUT_SETBUF_FIX
762 setbuf(stdout, NULL);
763 setbuf(stderr, NULL);
764 #endif
765 new_stderr=NULL;
766 if(quiet_mode)
767 new_stderr=fopen(dev_null, m_w);
768 if(quiet_mode==ARJ_QUIET||quiet_mode==ARJ_SILENT)
769 new_stdout=new_stderr;
770 /* Test for low-memory DOS situtations */
771 #if TARGET==DOS
772 free(malloc_msg(10000));
773 farfree(farmalloc_msg(9000));
774 #endif
775 /* Locate the executables. On UNIX systems, before assuming /usr/bin/arj, we
776 try to guess if ARGV contains a somewhat qualified filename. This is a
777 special hack for PACKAGER. */
778 exe_name=(char *)malloc_msg(CCHMAXPATH);
779 #ifndef SKIP_GET_EXE_NAME
780 get_exe_name(exe_name);
781 #else
782 get_exe_name(exe_name, argv[0]);
783 #endif
784 case_path(arj_env_name);
785 init_crc();
786 start_time=get_ticks();
787 ctrlc_processing=0;
788 tmp_archive_removed=0;
789 tmp_archive_exists=0;
790 is_registered=1;
791 #ifdef COMMERCIAL
792 is_commercial=1;
793 #else
794 is_commercial=0;
795 #endif
796 archive_suffixes=NULL;
797 header=(char *)malloc_msg(HEADERSIZE_MAX);
798 archive_name=(char *)malloc_msg(FILENAME_MAX);
799 archive_name[0]='\0'; /* ASR fix for ARJ -i in ARJ 2.73 */
800 misc_buf=(char *)malloc_msg(FILENAME_MAX+INPUT_LENGTH);
801 tmp_tmp_filename=(char *)malloc_msg(FILENAME_MAX);
802 strcpy_buf=(char *)malloc_msg(200);
803 order=(FILE_COUNT FAR *)farmalloc_msg(params_max*sizeof(FILE_COUNT));
804 f_arg_array=(char **)malloc_msg(params_max*sizeof(char *));
805 limit=20;
806 parse_reg_key();
807 arj_exec_validation();
808 set_file_apis(use_ansi_cp);
809 init();
810 flist_init(&flist_main, 0, FL_STANDARD);
811 flist_init(&flist_exclusion, 0, FL_STANDARD);
812 flist_init(&flist_order, 0, FL_STANDARD);
813 flist_init(&flist_archive, 0, FL_STANDARD);
814 #if defined(HAVE_EAS)
815 flist_init(&flist_ea, 0, FL_STANDARD);
816 flist_init(&flist_xea, 0, FL_STANDARD);
817 #endif
818 if(signal(SIGINT, ctrlc_handler)==SIG_ERR)
819 error(M_SIGNAL_FAILED);
820 #ifndef NO_TERM_HDL
821 if(signal(SIGTERM, term_handler)==SIG_ERR)
822 error(M_SIGNAL_FAILED);
823 #endif
824 #ifdef HAVE_BREAK_HANDLER
825 if(signal(SIGBREAK, term_handler)==SIG_ERR)
826 error(M_SIGNAL_FAILED);
827 #endif
828 atexit(final_cleanup);
829 for(i=0; i<10; i++)
830 is_registered=reg_validation(regdata+REG_KEY1_SHIFT, regdata+REG_KEY2_SHIFT, regdata+REG_NAME_SHIFT, regdata+REG_HDR_SHIFT);
831 check_fmsg(CHKMSG_SKIP);
832 if((tmp_stdout=new_stdout)==new_stderr&&!is_registered)
833 new_stdout=stderr;
834 msg_strcpy(strcpy_buf, M_VERSION);
835 msg_cprintf(0, M_ARJ_BANNER, M_ARJ_BINDING, strcpy_buf);
836 if(!is_registered&&!msg_strcmp((FMSG *)(regdata+REG_KEY2_SHIFT), M_REG_TYPE))
837 msg_cprintf(0, M_REGISTERED_TO, regdata+REG_NAME_SHIFT);
838 else
839 msg_cprintf(0, (FMSG *)lf);
840 new_stdout=tmp_stdout;
841 proc_time=get_ticks();
842 flist_init(&flist_exclusion, FCLIM_EXCLUSION, FL_STANDARD);
843 #if defined(HAVE_EAS)
844 flist_init(&flist_ea, FCLIM_EA, FL_STANDARD);
845 flist_init(&flist_xea, FCLIM_EA, FL_STANDARD);
846 #endif
847 switch_char='\0';
848 if(!disable_arj_sw)
849 {
850 if((arj_env_str=malloc_env_str(arj_env_name))!=NULL)
851 parse_arj_sw(cmd, arj_env_str, header);
852 else
853 {
854 #ifndef SKIP_GET_EXE_NAME
855 split_name(exe_name, archive_name, NULL);
856 msg_strcat(archive_name, M_ARJ_CFG);
857 if(file_exists(archive_name))
858 parse_arj_sw(cmd, archive_name, header);
859 #else
860 msg_strcpy(misc_buf, M_ARJ_CFG);
861 sprintf(archive_name, "%s/.%s", getenv("HOME"), misc_buf);
862 if(!file_exists(archive_name))
863 sprintf(archive_name, "/usr/local/etc/%s", misc_buf);
864 if(file_exists(archive_name))
865 parse_arj_sw(cmd, archive_name, header);
866 #endif
867 archive_name[0]='\0'; /* ASR fix */
868 }
869 }
870 if(install_errhdl)
871 ignore_errors=1;
872 if(force_lfn)
873 lfn_supported=LFN_SUPPORTED;
874 if(use_ansi_cp==ANSICP_CONVERT)
875 ansi_cpf=1;
876 set_file_apis(use_ansi_cp);
877 #ifndef NO_FATAL_ERROR_HDL
878 if(win32_platform)
879 install_smart_handler();
880 #endif
881 if(lfn_mode==LFN_NONE||lfn_mode==LFN_IGNORE)
882 lfn_supported=LFN_NOT_SUPPORTED;
883 if(lfn_supported!=LFN_NOT_SUPPORTED&&lfn_mode==LFN_DUAL)
884 lfn_supported=LFN_COMP;
885 is_registered=!is_registered;
886 if(!is_registered&®data[REG_NAME_SHIFT]!='\0')
887 wait_error(M_CRC_ERROR);
888 cmd=0;
889 if(rsp_name[0]=='\0')
890 {
891 for(cur_arg=1; cur_arg<argc; cur_arg++)
892 cmd=parse_cmdline(argv[cur_arg], cmd);
893 }
894 else
895 {
896 stream=file_open_noarch(rsp_name, m_r);
897 while(fgets(header, FILENAME_MAX, stream)!=NULL)
898 {
899 tmp_ptr=malloc_str(header);
900 got_str=1;
901 for(tptr=tmp_ptr; *tptr!='\0'; tptr++)
902 {
903 if(rsp_per_line)
904 {
905 if(*tptr==LF)
906 *tptr='\0';
907 }
908 else if(*tptr==LF||*tptr==' ')
909 *tptr='\0';
910 }
911 endptr=tptr;
912 tptr=tmp_ptr;
913 while((endptr-tptr)>0)
914 {
915 /* ASR fix: check for overrun -- 25/08/2001 */
916 while(*tptr=='\0'&&((endptr-tptr)>0))
917 tptr++;
918 if((endptr-tptr)>0)
919 {
920 cmd=parse_cmdline(tptr, cmd);
921 while(*tptr!='\0'&&((endptr-tptr)>0))
922 tptr++;
923 }
924 }
925 }
926 fclose(stream);
927 if(!got_str)
928 error(M_CANTREAD);
929 }
930 if(install_errhdl)
931 ignore_errors=1;
932 if(force_lfn)
933 lfn_supported=LFN_SUPPORTED;
934 set_file_apis(use_ansi_cp);
935 #ifndef NO_FATAL_ERROR_HDL
936 if(win32_platform)
937 install_smart_handler();
938 #endif
939 if(file_args>=0)
940 {
941 case_path(archive_name);
942 finish_archive_name(archive_name);
943 }
944 for(j=0; j<file_args; j++)
945 {
946 tptr=f_arg_array[j];
947 if(strcmp_os(tptr, nonexist_name))
948 {
949 if(is_directory(tptr))
950 tptr=malloc_subdir_wc(tptr);
951 f_arg_array[j]=tptr;
952 }
953 }
954 if(lfn_mode==LFN_NONE||lfn_mode==LFN_IGNORE)
955 lfn_supported=LFN_NOT_SUPPORTED;
956 if(lfn_supported!=LFN_NOT_SUPPORTED&&lfn_mode==LFN_DUAL)
957 lfn_supported=LFN_COMP;
958 if(limit!=0)
959 wait_error(M_CRC_ERROR);
960 if(cmd==ARJ_CMD_CHK_INT)
961 {
962 if(archive_name[0]=='\0')
963 {
964 far_strcpyn((char FAR *)archive_name, (char FAR *)exe_name, FILENAME_MAX);
965 if(!ansi_cpf)
966 fix_ansi_name(archive_name);
967 }
968 set_file_apis(use_ansi_cp);
969 if(check_integrity(archive_name))
970 msg_cprintf(0, M_OK);
971 else
972 {
973 arj_delay(BAD_CRC_DELAY);
974 error(M_CRC_ERROR);
975 }
976 exit(ARJ_ERL_SUCCESS);
977 }
978 if(cmd==ARJ_CMD_RECOVER)
979 {
980 if(archive_name[0]=='\0')
981 far_strcpyn((char FAR *)archive_name, (char FAR *)exe_name, FILENAME_MAX);
982 set_file_apis(use_ansi_cp);
983 name=(char *)malloc_msg(FILENAME_MAX);
984 msg_strcpy(name, M_ARJFIXED_NAME);
985 stream=file_create(name, m_wb);
986 if(stream!=NULL)
987 fclose(stream);
988 free(name);
989 msg_strcpy(tmp_tmp_filename, M_ARJFIXED_NAME);
990 name=form_prot_name();
991 if(!protfile_option)
992 name[0]='\0';
993 if(recover_file(archive_name, name, tmp_tmp_filename, 0, 0L))
994 {
995 tmp_tmp_filename[0]='\0';
996 error(M_CANT_FIND_DAMAGE, archive_name);
997 }
998 msg_cprintf(H_HL|H_NFMT, M_REPAIRED_FILE, tmp_tmp_filename);
999 tmp_tmp_filename[0]='\0';
1000 free(name);
1001 exit(ARJ_ERL_SUCCESS);
1002 }
1003 if(argc<2||help_issued||limit!=0)
1004 {
1005 check_fmsg(CHKMSG_NOSKIP);
1006 help_issued=1;
1007 #if TARGET==UNIX
1008 allow_any_attrs=FETCH_FILES;
1009 #endif
1010 set_file_apis(use_ansi_cp);
1011 strcpy(archive_name, exe_name);
1012 if(is_tty(stdout))
1013 prompt_for_more=!prompt_for_more;
1014 else
1015 prompt_for_more=0;
1016 indicator_style=IND_NONE;
1017 cmd=ARJ_CMD_PRINT;
1018 file_args=1;
1019 f_arg_array[0]=(argc<2)?brief_help:full_help;
1020 }
1021 #if TARGET==DOS
1022 if(lfn_supported!=LFN_NOT_SUPPORTED)
1023 msg_cprintf(H_HL, M_LFN_ENABLED);
1024 #endif
1025 #if defined(HAVE_EAS)
1026 if(ea_supported)
1027 msg_cprintf(H_HL, M_EA_ENABLED);
1028 #endif
1029 case_path(archive_suffixes);
1030 case_path(swptr_t);
1031 case_path(archive_ext_list);
1032 case_path(target_dir);
1033 case_path(index_name);
1034 case_path(arjsec_env_name);
1035 case_path(list_file);
1036 case_path(swptr_hm);
1037 case_path(nonexist_name);
1038 case_path(arjcrypt_name);
1039 case_path(arjdisp_ptr);
1040 case_path(filename_to_restart);
1041 case_path(work_directory);
1042 case_path(extraction_filename);
1043 case_path(archive_cmt_name);
1044 case_path(comment_file);
1045 unix_path_to_dos(target_dir);
1046 unix_path_to_dos(index_name);
1047 unix_path_to_dos(arjsec_env_name);
1048 unix_path_to_dos(list_file);
1049 unix_path_to_dos(swptr_hm);
1050 unix_path_to_dos(nonexist_name);
1051 unix_path_to_dos(arjcrypt_name);
1052 unix_path_to_dos(arjdisp_ptr);
1053 unix_path_to_dos(filename_to_restart);
1054 unix_path_to_dos(work_directory);
1055 unix_path_to_dos(extraction_filename);
1056 unix_path_to_dos(archive_cmt_name);
1057 unix_path_to_dos(comment_file);
1058 cmd_setup(&cmd, &is_add_cmd);
1059 /* ASR fix: in the open-source release, there is no longer any distinction
1060 between commercial and shareware versions. Therefore, the code which
1061 checks for M_EXT_LIC has been removed. */
1062 #if TARGET!=DOS
1063 if(priority.class>0)
1064 set_priority(&priority);
1065 #endif
1066 if(run_cmd_at_start&&start_cmd[0]!='\0')
1067 exec_cmd(start_cmd);
1068 if(!exclude_files)
1069 {
1070 flist_cleanup(&flist_exclusion);
1071 flist_init(&flist_exclusion, FCLIM_EXCLUSION, FL_STANDARD);
1072 }
1073 flist_add_files(&flist_exclusion, NULL, arjtemp_wildcard, 0, 0, 0, NULL);
1074 if(filter_same_or_newer||filter_older)
1075 convert_time_limits();
1076 if(cmd==ARJ_CMD_WHERE||extm_mode)
1077 search_setup();
1078 else if(execute_cmd)
1079 get_exec_cmd();
1080 if(garble_enabled)
1081 {
1082 if(!strcmp(garble_password, "?"))
1083 {
1084 tptr=(char *)malloc_msg(INPUT_LENGTH+1);
1085 msg_cprintf(0, M_ENTER_PWD);
1086 read_line_noecho(tptr, INPUT_LENGTH);
1087 garble_password=malloc_str(tptr);
1088 if(is_add_cmd||cmd=='G')
1089 {
1090 msg_cprintf(0, M_VERIFY_PWD);
1091 read_line_noecho(tptr, INPUT_LENGTH);
1092 if(strcmp(tptr, garble_password))
1093 error(M_PWD_MISMATCH);
1094 }
1095 free(tptr);
1096 }
1097 }
1098 if(garble_password[0]=='\0'&&(cmd==ARJ_CMD_GARBLE||garble_enabled))
1099 error(M_NO_PWD_OPTION);
1100 limit=20;
1101 if(append_curtime)
1102 append_curtime_proc();
1103 if(is_add_cmd&&file_exists(archive_name))
1104 {
1105 tmp_archive_exists=1;
1106 if(tmp_archive_name==NULL)
1107 {
1108 tmp_archive_used=-1;
1109 tmp_archive_name=malloc_msg(FILENAME_MAX);
1110 tmp_archive_name[0]='\0';
1111 tmp_archive_used=0;
1112 }
1113 split_name(archive_name, tmp_archive_name, NULL);
1114 strcat(tmp_archive_name, arjtemp_spec);
1115 find_tmp_filename(tmp_archive_name);
1116 if(!stricmp(archive_name, tmp_archive_name))
1117 error(M_CANTRENAME, archive_name, tmp_archive_name);
1118 file_unlink(tmp_archive_name);
1119 tmp_archive_removed=1;
1120 rename_with_check(archive_name, tmp_archive_name);
1121 }
1122 set_file_apis(1);
1123 arj_exec_validation();
1124 set_file_apis(use_ansi_cp);
1125 #if TARGET!=UNIX
1126 if(cmd!=ARJ_CMD_ORDER)
1127 flist_type=find_dupl_drivespecs(f_arg_array, file_args)?FL_HASH:FL_STANDARD;
1128 else
1129 flist_type=FL_STANDARD;
1130 #else
1131 flist_type=FL_STANDARD;
1132 #endif
1133 numfiles=default_capacity;
1134 if((tptr=strchr(debug_opt, 'i'))!=NULL)
1135 {
1136 tptr++;
1137 numfiles=(FILE_COUNT)strtol(tptr, &tptr, 10);
1138 }
1139 if(strchr(debug_opt, 'q')!=NULL)
1140 flist_type=FL_STANDARD;
1141 flist_init(&flist_main, numfiles, (char)flist_type);
1142 flist_init(&flist_order, FILELIST_CAPACITY, (char)FL_STANDARD);
1143 if(is_add_cmd)
1144 {
1145 arch_wildcard_allowed=1;
1146 expand_wildcards=1;
1147 }
1148 else
1149 expand_wildcards=0;
1150 name=malloc_msg(FILENAME_MAX);
1151 for(j=limit; j<file_args; j++)
1152 {
1153 tptr=f_arg_array[j];
1154 if(listchars_allowed&&tptr[0]==listchar)
1155 {
1156 if(*++tptr=='\0')
1157 error(M_MISSING_FILENAME_ARG, f_arg_array[j]);
1158 sort_f=0;
1159 entry=split_name(tptr, NULL, NULL);
1160 if(cmd==ARJ_CMD_ORDER&&!stricmp(tptr+entry, sort_filename))
1161 sort_f=1;
1162 stream=file_open_noarch(tptr, m_r);
1163 tmp_ptr=header;
1164 order[j]=1;
1165 while(fgets(tmp_ptr, FILENAME_MAX, stream)!=NULL)
1166 {
1167 if(sort_f)
1168 {
1169 if(strlen(tmp_ptr)<=121)
1170 tmp_ptr[0]='\0';
1171 else if(tmp_ptr[120]==' ')
1172 safe_strcpy(tmp_ptr, tmp_ptr+121);
1173 }
1174 if(cmd==ARJ_CMD_ORDER&&strpbrk(tmp_ptr, wildcard_pattern)!=NULL)
1175 error(M_ORDER_WILDCARD);
1176 cnv_cmdline_fnm(tmp_ptr);
1177 if(tmp_ptr[0]!='\0')
1178 {
1179 name[0]='\0';
1180 if(is_add_cmd)
1181 strcat(name, target_dir);
1182 strcat(name, tmp_ptr);
1183 count=0;
1184 if(flist_add_files(&flist_main, &flist_exclusion, name, expand_wildcards, recurse_subdirs, allow_any_attrs, &count))
1185 {
1186 j=file_args;
1187 break;
1188 }
1189 if(listfile_err_opt&&count!=0)
1190 {
1191 if(flist_add(&flist_order, NULL, name, NULL, NULL))
1192 {
1193 j=file_args;
1194 break;
1195 }
1196 }
1197 }
1198 }
1199 fclose(stream);
1200 }
1201 else
1202 {
1203 if(cmd==ARJ_CMD_ORDER&&strpbrk(f_arg_array[j], wildcard_pattern))
1204 error(M_ORDER_WILDCARD);
1205 name[0]='\0';
1206 if(is_add_cmd)
1207 strcat(name, target_dir);
1208 strcat(name, f_arg_array[j]);
1209 count=0;
1210 if(flist_add_files(&flist_main, &flist_exclusion, name, expand_wildcards, recurse_subdirs, allow_any_attrs, &count))
1211 {
1212 if(strchr(debug_opt, 'i')!=NULL)
1213 order[j]=count;
1214 break;
1215 }
1216 order[j]=count;
1217 }
1218 }
1219 if(tmp_archive_removed)
1220 {
1221 rename_with_check(tmp_archive_name, archive_name);
1222 tmp_archive_name[0]='\0';
1223 tmp_archive_removed=0;
1224 }
1225 if(create_list_file)
1226 {
1227 stream=file_create(list_file, m_w);
1228 for(cur_file=0; cur_file<flist_main.files; cur_file++)
1229 {
1230 flist_retrieve(name, NULL, &flist_main, cur_file);
1231 strcat(name, lf);
1232 if(fputs(name, stream)==EOF)
1233 error(M_DISK_FULL);
1234 }
1235 fclose(stream);
1236 }
1237 cfa_init(flist_main.files+1);
1238 if(restart_at_filename)
1239 restart_proc(tmp_ptr=header);
1240 free(name);
1241 if(create_index)
1242 {
1243 idxstream=file_open(index_name, m_a);
1244 if(msg_fprintf(idxstream, M_INDEX_HDR)<0)
1245 error(M_DISK_FULL);
1246 }
1247 if(cmd==ARJ_CMD_ORDER)
1248 {
1249 fnm_matching=FMM_FULL_PATH;
1250 arch_hdr_index=farmalloc_msg(((unsigned long)flist_main.files+1L)*sizeof(unsigned long));
1251 for(cur_file=0; cur_file<flist_main.files; cur_file++)
1252 arch_hdr_index[cur_file]=0L;
1253 }
1254 if(!reg_validation(single_spc, single_spc, single_spc, regdata+REG_HDR_SHIFT))
1255 limit=20;
1256 flist_init(&flist_archive, FCLIM_ARCHIVE, FL_STANDARD);
1257 flist_add_files(&flist_archive, NULL, archive_name, !is_add_cmd, is_add_cmd?0:recurse_subdirs, allow_any_attrs, NULL);
1258 if(flist_archive.files==0)
1259 {
1260 msg_cprintf(H_ERR, M_CANT_FIND, archive_name);
1261 errorlevel=ARJ_ERL_CANTOPEN;
1262 errors++;
1263 }
1264 if(debug_enabled&&strchr(debug_opt, 't')!=NULL)
1265 msg_cprintf(H_HL|H_NFMT, M_N_TICKS, get_ticks()-ticks);
1266 check_fmsg(CHKMSG_SKIP);
1267 if(quiet_mode==ARJ_QUIET2)
1268 new_stdout=new_stderr;
1269 /* The main processing loop */
1270 for(cur_file=limit; cur_file<flist_archive.files; cur_file++)
1271 {
1272 if(quiet_mode==ARJ_QUIET2)
1273 new_stdout=new_stderr;
1274 flist_retrieve(archive_name, NULL, &flist_archive, cur_file);
1275 perform_cmd(cmd);
1276 if(cur_file+1<flist_archive.files)
1277 nputlf();
1278 }
1279 file_arg_cleanup(&flist_order);
1280 errno=0;
1281 if(errors>0)
1282 error(M_FOUND_N_ERRORS, errors);
1283 return(errorlevel);
1284 }
1285