2
* $Id: arj_proc.c,v 1.15 2004/06/18 16:19:37 andrew_belov Exp $
3
* ---------------------------------------------------------------------------
4
* This file contains many of the functions that are called by various ARJ
5
* modules. Everything is OS-independent, all OS-dependent procedures must be
12
DEBUGHDR(__FILE__) /* Debug information block */
16
#define FNAME_FLEN 27 /* Length of formatted filename */
18
/* String table (may need some localization in the future...) */
20
#if SFX_LEVEL>=ARJ||defined(REARJ)
21
static char strtime_filler[]="00000000000000";
24
static char time_tail_pattern[]="%04d%02d%02d%03d%02d%02d%02d";
25
static char date_digit_format[]="%04d%02d%02d";
26
static char allowed_attrs[]=TAG_LIST;
27
static char vol_st_id[]=" - "; /* A substring of M_NEXT_VOL_STATS */
29
#if SFX_LEVEL>=ARJSFXV
30
static char nonexistent_name[]="...";
33
#if SFX_LEVEL>=ARJSFXV||defined(REARJ)
35
/* The first byte in integrity_pattern[] is changed to avoid confusion with the
38
static unsigned char integrity_pattern[]={0xB1, 0x03, 0xB0, 0x02, 0xB0, 0x03, 0xB0,
44
static int hswitch; /* Indicates that we have a "-h..." */
45
static int jswitch; /* Indicates that we have a "-j..." */
46
static int os2switch; /* ARJ/2 switches (-h2, -2) */
52
int *sw_index[]={&jswitch, &hswitch, &allow_any_attrs, &filter_fa_arch,
53
&skip_ts_check, &delete_processed, &exclude_paths,
54
&freshen_criteria, &garble_enabled, &indicator_style,
55
&keep_bak, &create_list_file, &custom_method, &new_files_only,
56
&filter_same_or_newer, &fnm_matching, &query_for_each_file,
57
&recurse_subdirs, ×tamp_override, &type_override,
58
&update_criteria, &multivolume_option, &assign_work_directory,
59
&exclude_files, &yes_on_all_queries, &use_comment,
60
&help_issued, &listchars_allowed, &handle_labels, &disable_arj_sw,
61
&select_by_number, &install_errhdl, &quiet_mode,
62
&rsp_per_line, &noswitch, &lowercase_names, NULL};
64
int *jsw_index[]={&jswitch, &comment_display, &chapter_mode, &exit_after_count,
65
&chk_free_space, &create_sfx, &validate_style, &select_backup_files,
66
&jh_enabled, &create_index, &keep_tmp_archive, &show_filenames_only,
67
&max_compression, &restart_at_filename, &serialize_exts,
68
&prompt_for_more, &set_string_parameter, &ignore_crc_errors,
69
&store_by_suffix, &test_archive_crc, &translate_unix_paths,
70
&verbose_display, &extract_to_file, &start_at_ext_pos,
71
&assume_yes, &supply_comment_file, &hollow_mode, &skip_time_attrs,
74
int *hsw_index[]={&hswitch, &clear_archive_bit, &filter_attrs, &run_cmd_at_start,
75
&debug_enabled, &arjsec_opt, &lfn_mode, &gost_cipher,
76
&detailed_index, &protfile_option, &listfile_err_opt,
77
&filelist_storage, &nonexist_filespec, &extm_mode,
78
&arjdisp_enabled, &ignore_open_errors, &ignore_archive_errors,
79
&disable_sharing, &set_target_directory, &allow_mv_update,
80
&chk_arj_version, &search_mode, &override_archive_exts,
81
&use_ansi_cp, &sign_with_arjsec, &append_curtime,
82
&marksym_expansion, &force_lfn, &noswitch, NULL};
84
int *os2sw_index[]={&os2switch, &arcmail_sw, &noswitch, &crit_eas, &dos_host,
85
&include_eas, &disable_comment_series, &suppress_hardlinks,
86
&start_with_seek, &skip_century, &fix_longnames, &do_chown,
87
&priority.class, &recursion_order, &symlink_accuracy, &noswitch,
91
int *jysw_index[]={&skip_append_query, &prompt_for_mkdir, &query_delete,
92
&skip_space_query, &skip_rename_prompt, &overwrite_existing,
93
&kbd_cleanup_on_input, &skip_scanned_query,
94
&skip_next_vol_query, &accept_shortcut_keys, NULL};
95
#elif SFX_LEVEL==ARJSFXV
97
int *sw_index[]={&skip_integrity_test, &prompt_for_directory, &skip_ts_check,
98
&chk_free_space, &extract_expath, &freshen_criteria,
99
&garble_enabled, &help_issued, &indicator_style,
100
&process_lfn_archive, &skip_preset_options, &list_sfx_cmd,
101
&overwrite_ro, &new_files_only, &gost_cipher, &fnm_matching,
102
&ignore_crc_errors, &disable_sharing, &test_sfx_cmd,
103
&update_criteria, &verbose_list, &extract_to_file,
104
&extract_cmd, &yes_on_all_queries, &assume_yes, &help_issued,
105
&skip_volumes, &debug_enabled, &quiet_mode, &handle_labels,
106
&arjdisp_enabled, &execute_extr_cmd, &lowercase_names, NULL};
108
int *jysw_index[]={&skip_append_query, &prompt_for_mkdir, &skip_space_query,
109
&skip_extract_query, &skip_rename_prompt, &overwrite_existing,
110
&kbd_cleanup_on_input, &skip_next_vol_query, NULL};
111
#elif SFX_LEVEL==ARJSFX
113
int *sw_index[]={&extract_expath, &list_sfx_cmd, &test_sfx_cmd, &verbose_list,
114
&extract_cmd, &show_ansi_comments, &prompt_for_directory,
115
&skip_ts_check, &arjdisp_enabled, &freshen_criteria,
116
&garble_enabled, &indicator_style, &process_lfn_archive,
117
&verbose_display, &make_directories, &new_files_only,
118
&overwrite_existing, &fnm_matching, &skip_integrity_test,
119
&update_criteria, &skip_extract_query, &yes_on_all_queries,
120
&quiet_mode, &help_issued, &help_issued, &execute_extr_cmd};
123
/* Local functions */
126
static int compare_exts(char *name, char *pad);
131
/* Encodes a block of data */
133
void garble_encode_stub(char *data, int len)
135
garble_encode(data, len);
138
/* Decodes a block of data */
140
void garble_decode_stub(char *data, int len)
142
garble_decode(data, len);
149
/* Returns day of year */
151
static int day_of_year(struct tm *tms)
156
for(m=tms->tm_mon; m>0; m--)
160
case 1: rc+=31; break;
164
if((y%4==0)&&(y%100!=0||y%400==0))
167
case 3: rc+=31; break;
168
case 4: rc+=30; break;
169
case 5: rc+=31; break;
170
case 6: rc+=30; break;
171
case 7: rc+=31; break;
172
case 8: rc+=31; break;
173
case 9: rc+=30; break;
174
case 10: rc+=31; break;
175
case 11: rc+=30; break;
178
return(rc+tms->tm_mday);
181
/* Appends current date/time to the archive filename in accordance with the
184
void append_curtime_proc()
192
char *dptr=time_pad; /* ASR fix for High C -- 29/03/2001 */
194
int doy; /* Day of year */
197
tms=localtime(&curtime);
198
doy=day_of_year(tms);
199
sprintf(time_pad, time_tail_pattern, tms->tm_year+1900, tms->tm_mon+1,
200
tms->tm_mday, doy, tms->tm_hour, tms->tm_min, tms->tm_sec);
201
if((ext_pos=strchr(archive_name+split_name(archive_name, NULL, NULL), '.'))!=NULL)
203
strncpy(ext, ext_pos, sizeof(ext));
208
if(time_str[0]=='\0')
210
if(append_curtime==ATS_DUAL)
211
strcat(archive_name, time_pad+7);
212
else if(append_curtime==ATS_TIME)
213
strcat(archive_name, time_pad+8);
214
else if(append_curtime==ATS_DATE)
217
strcat(archive_name, time_pad+2);
220
else /* Custom format */
223
aptr=archive_name+strlen(archive_name)+l;
226
for(tptr=time_str+l-1; (tptr-time_str)>=0; tptr--)
229
*(--aptr)=(lim>0)?dptr[--lim]:*tptr;
237
*(--aptr)=dptr[--lim];
242
*(--aptr)=dptr[--lim];
247
*(--aptr)=dptr[--lim];
252
*(--aptr)=dptr[--lim];
257
*(--aptr)=dptr[--lim];
262
*(--aptr)=dptr[--lim];
267
*(--aptr)=dptr[--lim];
275
strcat(archive_name, ext);
278
/* Adds an ending backslash to the given pathname if it doesn't contain one */
280
void add_pathsep(char *path)
284
if((len=strlen(path))==0) /* Maybe current path? */
286
if(strchr(path_separators, path[len-1])==NULL)
288
path[len]=PATHSEP_DEFAULT;
293
/* Converts the timestamps given by the user to the internal storage format */
295
void convert_time_limits()
301
struct timestamp arj_ts; /* ARJ-format timestamp storage */
303
if(filter_same_or_newer==TCHECK_NDAYS)
305
tmp_ts=strtoul(timestr_newer, &cptr, 10)*(-86400L);
306
ts=sum_time(tmp_ts, time(NULL));
308
if(tms==NULL) /* ASR fix 21/02/2001 -- IBM LIBC */
309
error(M_INVALID_DATE);
310
sprintf(misc_buf, date_digit_format, tms->tm_year+1900, tms->tm_mon+1, tms->tm_mday);
311
timestr_newer=malloc_str(misc_buf); /* MEMORY LEAK! (Never freed) */
313
if(filter_older==TCHECK_NDAYS)
315
tmp_ts=strtoul(timestr_older, &cptr, 10)*(-86400L);
316
ts=sum_time(tmp_ts, time(NULL));
318
if(tms==NULL) /* ASR fix 21/02/2001 -- IBM LIBC */
319
error(M_INVALID_DATE);
320
sprintf(misc_buf, date_digit_format, tms->tm_year+1900, tms->tm_mon+1, tms->tm_mday);
321
timestr_older=malloc_str(misc_buf); /* MEMORY LEAK! (Never freed) */
323
if(timestr_older[0]!='\0')
324
convert_strtime(&tested_ftime_older, timestr_older);
325
if(timestr_newer[0]!='\0')
326
convert_strtime(&tested_ftime_newer, timestr_newer);
327
if(timestr_older[0]=='\0'&×tr_newer[0]=='\0')
331
make_timestamp(&arj_ts, tms->tm_year, tms->tm_mon+1, tms->tm_mday, 0, 0, 0);
332
if(timestr_newer[0]=='\0')
333
tested_ftime_newer=arj_ts;
334
if(timestr_older[0]=='\0')
335
tested_ftime_older=arj_ts;
339
/* Analyzes ARJ_SW settings */
341
void parse_arj_sw(int cmd, char *arj_sw, char *dest)
343
int use_file; /* 1 if ARJ_SW represents a file */
345
char *dptr, *varname;
351
while(arj_sw[0]==' ')
353
if(strchr(switch_chars, arj_sw[0])==NULL)
356
dptr=dest+FILENAME_MAX+1;
357
sptr=dest+FILENAME_MAX*2+2;
360
stream=file_open_noarch(arj_sw, m_r);
361
while(fgets(buf, FILENAME_MAX, stream)!=NULL)
366
else if(!use_file&&buf[0]=='+'&&buf[1]==' ')
371
else if(!use_file&&buf[0]=='-'&&buf[1]==' ')
377
else if((cmd==ARJ_CMD_ADDC&&!strnicmp(buf, "AC ", 3))||
378
(cmd==ARJ_CMD_CNVC&&!strnicmp(buf, "CC ", 3))||
379
(cmd==ARJ_CMD_DELC&&!strnicmp(buf, "DC ", 3)))
387
if(toupper((int)buf[0])==cmd&&buf[1]==' ')
400
sw=malloc_str(arj_sw);
401
varname=use_file?arj_sw:arj_env_name;
403
/* Tokenize switch */
404
for(dptr=sw; *dptr!='\0'; dptr++)
417
while(*dptr!='\0'&&(dptr-sptr)<0)
421
if(!translate_unix_paths)
423
msg_cprintf(H_HL|H_NFMT, M_USING_ENV_VAR, varname, sw_p);
427
/* Copies a part of archive */
429
void copy_bytes(unsigned long nbytes)
432
unsigned int fetch_size;
434
buf=malloc_msg(PROC_BLOCK_SIZE);
435
fseek(aistream, 0L, SEEK_SET);
438
fetch_size=(unsigned int)min(PROC_BLOCK_SIZE, nbytes);
439
if(fread(buf, 1, fetch_size, aistream)!=fetch_size)
441
if(fwrite(buf, 1, fetch_size, aostream)!=fetch_size)
443
nbytes-=(unsigned long)fetch_size;
448
/* Returns 1 if the given filename did not contain any UNIX-style ('/') path
449
separators, and all native path separators have been converted to UNIX-style
450
ones ('/'). 0 is returned if the filename initially contained a UNIX-style
451
separator. When it returns 1, the PATHSYM_FLAG in arj_flags is set by parent
454
int translate_path(char *name)
458
if(strchr(name, PATHSEP_UNIX)!=NULL)
460
for(i=0; name[i]!=0; i++)
461
if(name[i]==PATHSEP_DEFAULT)
462
name[i]=PATHSEP_UNIX;
466
/* Restarts archive processing from the specified file */
468
void restart_proc(char *dest)
470
char *r_name, *c_name;
476
int vn=0, vc=0; /* ASR fix for High C -- 29/03/2001 */
477
unsigned long vs=0; /* ASR fix for High C -- 29/03/2001 */
482
r_name=malloc_msg(FILENAME_MAX);
483
c_name=malloc_msg(FILENAME_MAX);
484
strcpy(r_name, filename_to_restart);
485
msg_strcpy(vol_stats, M_NEXT_VOLUME_STATS);
490
if(!strncmp(vs_ptr, vol_st_id, sizeof(vol_st_id)-1))
495
i+=sizeof(vol_st_id)-1;
496
if(filename_to_restart[0]=='\0'&&index_name[0]!='\0')
500
idxstream=file_open_noarch(index_name, m_r);
501
while(fgets(dptr, FILENAME_MAX, idxstream)!=NULL)
504
if(!memcmp(dptr, vol_stats, i))
510
strcpy(r_name, dptr+i+17);
515
error(M_RESTART_INFO_NF);
518
resume_volume_num=vn;
525
error(M_NOTHING_TO_DO);
528
for(cur_file=0L; cur_file<flist_main.files; cur_file++)
530
flist_retrieve(c_name, NULL, &flist_main, cur_file);
531
if(!strcmp_os(c_name, r_name))
533
cfa_store(cur_file, FLFLAG_DELETED);
535
if(cur_file>=flist_main.files)
536
error(M_CANT_FIND_RST_FILE, r_name);
541
nd=split_name(archive_name, NULL, NULL);
542
vs_ptr=strchr(archive_name+nd, '.');
544
msg_strcat(archive_name, M_EXE_EXT);
546
msg_strcpy(vs_ptr, M_EXE_EXT);
550
/* Looks for an extension of the given filename in the extension list */
552
int search_for_extension(char *name, char *ext_list)
556
char ext_pad[EXTENSION_MAX+1];
561
endptr=&ext_list[strlen(ext_list)];
568
for(i=0; i<EXTENSION_MAX&&t_ptr[i]!='\0'&&t_ptr[i]!='.'; i++)
569
ext_pad[i+1]=t_ptr[i];
571
if(compare_exts(name, ext_pad))
578
while(*t_ptr!='\0'&&*t_ptr!='.')
585
/* Returns the exact amount of data that could be safely written to the
586
destination volume */
588
unsigned long get_volfree(unsigned int increment)
591
unsigned int arjsec_overhead;
594
if(increment==0||volume_flag_set)
601
pvol=calc_protdata_size(volume_limit, prot_blocks);
602
else if(protfile_option)
603
pvol=calc_protdata_size(volume_limit, protfile_option);
604
arjsec_overhead=sign_with_arjsec?ARJSEC_SIG_MAXLEN+1:0;
605
remain=volume_limit-ftell(aostream)-pvol-(long)arjsec_overhead-
606
(long)out_bytes-(long)cpos-(long)ext_voldata-
607
MULTIVOLUME_RESERVE-t_volume_offset;
608
return((unsigned long)min(remain, (unsigned long)increment));
611
/* Performs various checks when multivolume data is packed to predict an
612
overrun. Returns number of bytes that could be successfully written. */
614
unsigned int check_multivolume(unsigned int increment)
617
unsigned int arjsec_overhead;
619
unsigned int inc, rc;
623
if(increment==0||volume_flag_set)
630
pvol=calc_protdata_size(volume_limit, protfile_option);
631
arjsec_overhead=sign_with_arjsec?ARJSEC_SIG_MAXLEN+1:0;
632
/* Split this expression to work around High C bugs -- ASR 14/08/2001 */
633
remain=volume_limit-ftell(aostream)-pvol-(long)arjsec_overhead;
635
remain-=(long)out_bytes+(long)cpos+(long)ext_voldata;
637
remain-=(long)MULTIVOLUME_RESERVE+(long)t_volume_offset;
638
/* Now decrement the buffer size until we fit the remainder */
639
while((long)bufsiz*2L>remain&&bufsiz>MIN_CRITICAL_BUFSIZ)
641
if(bufsiz<MIN_CRITICAL_BUFSIZ)
642
bufsiz=MIN_CRITICAL_BUFSIZ;
643
if((long)increment+1000L<remain&&(long)increment*2L<remain)
646
if((long)increment<remain)
655
if((long)increment*2L>remain)
662
rc=(inc>512)?inc>>1:inc;
664
/* Mistrust the return value. That would help to get around certain compiler
665
optimization bugs (as with OpenWatcom v 1.1RC) - at least the wrong value
666
won't be passed to fread() causing buffer overrun. */
667
return(min(rc, increment));
670
/* Compares the extension from pad with the file's extension. Returns 1 if
671
there was a match. */
673
static int compare_exts(char *name, char *pad)
677
/* si = name, di = pad */
678
if(strlen(pad)==1&&strchr(name, '.')==NULL)
680
k=strlen(name)-strlen(pad);
684
return(strcmp_os(name+k, pad)==0);
687
/* "Stores" a file by simply copying it */
692
unsigned int mem_size;
696
fetch=(char *)malloc_msg(PROC_BLOCK_SIZE);
701
display_indicator(0L);
703
to_read=PROC_BLOCK_SIZE;
704
if(multivolume_option&&file_packing)
705
to_read=check_multivolume(to_read);
708
while((fetch_size=fread_crc(fetch, to_read, encstream))>0)
711
garble_encode_stub(fetch, fetch_size);
712
if(!no_file_activity)
714
file_write(fetch, 1, fetch_size, aostream);
716
display_indicator(origsize);
717
if(multivolume_option)
718
to_read=check_multivolume(to_read);
723
while(encmem_remain!=0)
725
mem_size=min((unsigned int)PROC_BLOCK_SIZE, encmem_remain);
726
far_memmove((char FAR *)fetch, encblock_ptr, mem_size);
727
crc32_for_block(fetch, mem_size);
729
garble_encode_stub(fetch, mem_size);
730
far_memmove(packblock_ptr, (char FAR *)fetch, mem_size);
731
encblock_ptr+=mem_size;
732
packblock_ptr+=mem_size;
734
encmem_remain-=mem_size; /* Changed this order. This is an ASR
735
fix for High C beta -- 05/04/2001 */
742
/* Performs a "hollow" file processing (just calculates the CRC) */
749
fetch=(char *)malloc_msg(PROC_BLOCK_SIZE);
755
display_indicator(0L);
757
fetch_size=PROC_BLOCK_SIZE;
758
while(fread_crc(fetch, fetch_size, encstream)!=0)
759
display_indicator(origsize);
766
#if SFX_LEVEL>=ARJ||defined(REARJ)
768
/* Retrieves a pair of decimal digits from the given pointer */
770
static int get_dec_pair(char *str)
775
return((int)str[0]-'0');
776
return((int)(str[0]-'0')*10+(int)(str[1]-'0'));
779
/* Converts the given time string ("yyyymmddhhmmss") to the internal timestamp
782
void convert_strtime(struct timestamp *dest, char *str)
784
char tmp_strtime[30];
785
int y, m, d, hh, mm, ss; /* Timestamp components */
787
strncpy(tmp_strtime, str, 14);
788
tmp_strtime[14]='\0';
789
strcat(tmp_strtime, strtime_filler);
790
y=get_dec_pair(tmp_strtime);
793
y=y*100+get_dec_pair(tmp_strtime+2);
794
m=get_dec_pair(tmp_strtime+4);
795
d=get_dec_pair(tmp_strtime+6);
796
hh=get_dec_pair(tmp_strtime+8);
797
mm=get_dec_pair(tmp_strtime+10);
798
ss=get_dec_pair(tmp_strtime+12);
802
m=get_dec_pair(tmp_strtime+2);
803
d=get_dec_pair(tmp_strtime+4);
804
hh=get_dec_pair(tmp_strtime+6);
805
mm=get_dec_pair(tmp_strtime+8);
806
ss=get_dec_pair(tmp_strtime+10);
807
y+=(y>=80)?1900:2000;
809
if(m<1||m>12||d<1||d>31||hh>23||mm>59||ss>59)
810
error(M_INVALID_DATE_STRING, str);
811
make_timestamp(dest, y, m, d, hh, mm, ss);
816
#if SFX_LEVEL>=ARJSFXV||defined(REARJ)
818
/* Checks integrity of the executable file */
820
int check_integrity(char *name)
824
int f_len=PROC_BLOCK_SIZE;
826
char buf[CACHE_SIZE];
827
int f_len=CACHE_SIZE;
834
unsigned long wr_pos;
835
unsigned long fsize, cur_pos;
837
unsigned long st_crc, st_fsize; /* Stored parameters */
840
buf=(char *)malloc_msg(f_len);
842
stream=file_open(name, m_rb);
845
msg_cprintf(H_ERR, M_CANTOPEN, name);
853
strcpy(pattern, (char *)integrity_pattern);
855
p_len=strlen(pattern);
856
fseek(stream, 0L, SEEK_END);
858
fseek(stream, 0L, SEEK_SET);
863
fseek(stream, cur_pos, SEEK_SET);
864
fetch=fread(buf, 1, f_len, stream);
866
#if SFX_LEVEL>=ARJSFXV
869
pause_error(M_NO_INTEGRITY_PATTERN);
873
for(i=0; i<fetch; i++)
875
if(!memcmp(bptr, pattern, p_len))
881
cur_pos+=f_len/2; /* Dirty hack */
883
wr_pos=(long)i+cur_pos+p_len;
884
fseek(stream, wr_pos, SEEK_SET);
885
if(fread(&st_crc, 1, 4, stream)!=4)
886
#if SFX_LEVEL>=ARJSFXV
889
pause_error(M_NO_INTEGRITY_PATTERN);
891
if(fread(&st_fsize, 1, 4, stream)!=4)
892
#if SFX_LEVEL>=ARJSFXV
895
pause_error(M_NO_INTEGRITY_PATTERN);
897
#ifdef WORDS_BIGENDIAN /* Another dirty hack */
898
st_crc = mget_dword((char*) &st_crc);
899
st_fsize = mget_dword((char*) &st_fsize);
902
fseek(stream, 0L, SEEK_SET);
903
for(cur_pos=0L; cur_pos<wr_pos; cur_pos++)
905
if((c=fgetc(stream))==-1)
906
#if SFX_LEVEL>=ARJSFXV
909
pause_error(M_NO_INTEGRITY_PATTERN);
911
crc32term=crc32_for_char(crc32term, (unsigned char)c);
914
fseek(stream, cur_pos, SEEK_SET);
917
if((c=fgetc(stream))==-1)
918
#if SFX_LEVEL>=ARJSFXV
921
pause_error(M_NO_INTEGRITY_PATTERN);
923
crc32term=crc32_for_char(crc32term, (unsigned char)c);
931
#if SFX_LEVEL>=ARJSFXV
932
return(crc32term==st_crc&&fsize==st_fsize);
934
if(crc32term==st_crc&&fsize==st_fsize)
935
msg_cprintf(0, M_INTEGRITY_OK);
937
pause_error(M_INTEGRITY_VIOLATED);
944
/* Converts a filename to the format used in current OS (simply substitutes
945
the UNIX separators with DOS ones) */
947
void name_to_hdr(char *name)
951
for(i=0; name[i]!='\0'; i++)
953
if(name[i]==PATHSEP_UNIX)
954
name[i]=PATHSEP_DEFAULT;
958
#if SFX_LEVEL>=ARJSFXV
960
/* Formats the given filename to look properly in the "Adding..." and other
963
char *format_filename(char *name)
967
int ctr; /* Path delimiter counter */
969
static char name_holder[FNAME_FLEN+1];
972
if(show_filenames_only)
973
f_pos=split_name(name, NULL, NULL);
978
while(name[tf_pos]!='\0')
980
if(tf_pos>0&&name[tf_pos]==PATHSEP_DEFAULT)
984
len=ctr*CCHMAXPATH+ctr;
988
if(strlen(result)<len)
990
strcpy(name_holder, result);
991
for(i=strlen(name_holder); i<len; i++)
992
strcat(name_holder, " ");
1002
/* Parses the given argument to a file attribute bitmap */
1004
static void parse_attrs(char *str)
1006
char *sptr, *attrptr;
1011
file_attr_mask=TAG_FILES;
1013
file_attr_mask=TAG_RDONLY|TAG_SYSTEM|TAG_HIDDEN|TAG_DIREC|TAG_LABEL|
1014
TAG_CHAPTER|TAG_NORMAL|TAG_WINLFN;
1018
attrptr=allowed_attrs;
1019
while((c=*sptr++)!='\0')
1022
if((g_attr=strchr(attrptr, c))==NULL)
1023
error(M_INVALID_SWITCH, str);
1024
attrno=g_attr-attrptr-1;
1026
file_attr_mask|=1<<attrno;
1028
file_attr_mask=TAG_RDONLY|TAG_SYSTEM|TAG_HIDDEN|TAG_DIREC|TAG_NORMAL;
1030
if((file_attr_mask|(TAG_ARCH|TAG_NOT_ARCH))==(TAG_ARCH|TAG_NOT_ARCH))
1031
file_attr_mask|=TAG_RDONLY|TAG_SYSTEM|TAG_HIDDEN|TAG_DIREC|TAG_NORMAL;
1035
/* Returns real size in bytes for diskette size shortcuts (i.e., 360, 720, and
1038
static unsigned long select_preset_size(unsigned long rsize)
1044
else if(rsize==1200)
1046
else if(rsize==1440)
1053
#if SFX_LEVEL>=ARJSFXV
1055
/* Returns 1 if the switch has a "tail" of extra dataa */
1057
static int get_switch_state(char *sw)
1061
if((sw[0]=='+'||sw[0]=='-')&&sw[1]=='\0')
1066
/* Parses query list given by -jy for ARJ and -y for ARJSFX */
1068
static void parse_yes_queries(char *sw)
1078
while((c=(unsigned int)*(swptr++))!='\0')
1083
if((entry=msg_strchr(table, (char)c))==NULL)
1084
error(M_INVALID_SWITCH, sw);
1091
else if(*swptr=='-')
1096
*index[num]=!*index[num];
1102
#if SFX_LEVEL>=ARJ&&TARGET==UNIX
1104
/* Disables/enables archiving for a particular block device */
1106
static void add_blkdev_spec(char *swptr)
1116
else if(swptr[0]=='+')
1118
fnm=(swptr[0]=='\0')?".":swptr;
1119
set_dev_mode(is_excl);
1121
msg_cprintf(H_ALERT, M_BAD_DEV_SPEC, fnm);
1126
#if SFX_LEVEL>=ARKSFXV
1128
/* A user-friendly strtoul(). Can tell between hex and decimal notations */
1130
unsigned long stoul(char *p, char **rp)
1143
if(p[0]=='0'&&p[1]=='x')
1150
rc=strtoul(p, rp, radix);
1167
else if(c=='T'||c=='P'||c=='E') /* BUGBUG: Reserved */
1177
#if SFX_LEVEL>=ARJSFXJR
1179
/* Sets internal variables depending on the switch given */
1181
void analyze_arg(char *sw)
1186
int num; /* Switch number within the table */
1187
#if SFX_LEVEL>=ARJSFXV
1197
char vol_sw; /* -v... subswitch storage */
1200
unsigned long cnv_num;
1204
if(swptr[0]==swptr[1]&&swptr[2]=='\0')
1205
skip_switch_processing=1;
1210
hswitch=jswitch=os2switch=0;
1211
if(toupper(*swptr)=='H'&&*(swptr+1)=='2')
1219
#if SFX_LEVEL>=ARJSFXV
1222
while((c=(unsigned int)*(swptr++))!='\0')
1229
params=M_JSW_PARAMS;
1235
params=M_HSW_PARAMS;
1240
table=M_OS2SW_TABLE;
1241
params=M_OS2SW_PARAMS;
1250
#elif SFX_LEVEL>=ARJSFXV
1255
#if SFX_LEVEL>=ARJSFXV
1256
entry=msg_strchr(table, (char)c);
1258
entry=msg_strchr(M_SW_TABLE, (char)c);
1262
#if SFX_LEVEL>=ARJSFXV
1263
error(M_INVALID_SWITCH, sw);
1265
msg_cprintf(0, M_ARJSFX_BANNER, exe_name);
1266
msg_cprintf(0, M_INVALID_SWITCH, (char)c);
1267
check_fmsg(CHKMSG_NOSKIP);
1268
exit(ARJSFX_ERL_ERROR);
1271
#if SFX_LEVEL>=ARJSFXV
1274
num=entry-M_SW_TABLE;
1276
#if SFX_LEVEL>=ARJSFXV
1278
sw_tail=get_switch_state(swptr);
1280
/* ARJ parameters */
1282
if(!jswitch&&!hswitch&&!os2switch&&c=='G'&&sw_tail)
1286
garble_password=swptr;
1288
else if(!jswitch&&!hswitch&&!os2switch&&c=='E'&&sw_tail)
1291
left_trim=(unsigned int)stoul(swptr, &swptr);
1292
exclude_paths=(left_trim==0)?EP_PATH:EP_BASEDIR;
1294
else if(!jswitch&&!hswitch&&!os2switch&&c=='L'&&sw_tail)
1300
else if(!jswitch&&!hswitch&&!os2switch&&c=='O'&&sw_tail)
1303
if(toupper(*swptr)=='B')
1306
filter_older=TCHECK_NOTHING;
1309
filter_older=TCHECK_FTIME;
1310
timestr_older=swptr;
1313
else if(toupper(*swptr)=='D')
1317
filter_same_or_newer=TCHECK_NOTHING;
1318
else if(toupper(*swptr)=='B')
1320
filter_older=TCHECK_NDAYS;
1322
timestr_older=swptr;
1326
filter_same_or_newer=TCHECK_NDAYS;
1327
timestr_newer=swptr;
1330
else if(toupper(*swptr)=='C')
1333
if(toupper(*swptr)=='B')
1335
filter_older=TCHECK_CTIME;
1337
timestr_older=swptr;
1341
filter_same_or_newer=TCHECK_CTIME;
1342
timestr_newer=swptr;
1345
else if(toupper(*swptr)=='A')
1348
if(toupper(*swptr)=='B')
1350
filter_older=TCHECK_ATIME;
1352
timestr_older=swptr;
1356
filter_same_or_newer=TCHECK_ATIME;
1357
timestr_newer=swptr;
1362
filter_same_or_newer=TCHECK_FTIME;
1363
timestr_newer=swptr;
1366
else if(!jswitch&&!hswitch&&!os2switch&&c=='T'&&sw_tail)
1369
type_override=FT_BINARY;
1370
type=(int)(*swptr-'0');
1371
if(type!=ARJT_BINARY&&type!=ARJT_TEXT)
1372
error(M_INVALID_SWITCH, sw);
1374
/* ASR fix 25/01/2004: the "-t1gf" combination was the only way to
1375
enforce "text with graphics" which was not trivial. Now "-t1g"
1376
should do it as well. */
1378
type_override=FT_TEXT;
1379
while((c=toupper(*swptr))=='G'||c=='F')
1382
type_override=FT_TEXT_GRAPHICS;
1383
else if(c=='F'&&type_override<FT_TEXT_FORCED)
1384
type_override=FT_TEXT_FORCED;
1390
secondary_file_type=type;
1393
primary_file_type=type;
1395
else if(!jswitch&&!hswitch&&!os2switch&&c=='V'&&sw_tail)
1398
multivolume_option=MV_STD;
1401
vol_sw=(char)toupper(*swptr);
1405
beep_between_volumes=1;
1407
else if(vol_sw=='W')
1410
whole_files_in_mv=1;
1412
else if(vol_sw=='A')
1415
multivolume_option=MV_AVAIL;
1416
volume_limit=MIN_VOLUME_SIZE;
1418
else if(vol_sw=='E')
1423
else if(vol_sw=='I')
1426
inhibit_change_test=1;
1428
else if(vol_sw=='P')
1431
pause_between_volumes=1;
1432
if((change_vol_delay=(int)stoul(swptr, &swptr))==0)
1433
change_vol_delay=STD_CHANGE_VOL_DELAY;
1435
else if(vol_sw=='R')
1438
mv_reserve_space=stoul(swptr, &swptr);
1440
else if(vol_sw=='S'||vol_sw=='Z'||vol_sw=='D')
1443
mv_cmd_state=MVC_RUN_CMD;
1445
mv_cmd_state=MVC_RUN_CMD_NOECHO;
1446
else if(vol_sw=='D')
1448
mv_cmd_state=MVC_DELETION;
1450
error(M_INVALID_SWITCH, sw);
1459
else if(isdigit(vol_sw))
1461
volume_limit=stoul(swptr, &swptr);
1465
error(M_INVALID_SWITCH, sw);
1467
volume_limit=select_preset_size(volume_limit);
1468
mv_reserve_space=select_preset_size(mv_reserve_space);
1470
else if(!jswitch&&!hswitch&&!os2switch&&c=='W'&&sw_tail)
1473
assign_work_directory=1;
1474
work_directory=swptr;
1476
else if(!jswitch&&!hswitch&&!os2switch&&c=='X'&&sw_tail)
1480
flist_cleanup(&flist_exclusion);
1481
flist_init(&flist_exclusion, FCLIM_EXCLUSION, FL_STANDARD);
1485
create_excl_list(swptr);
1487
else if(!jswitch&&!hswitch&&!os2switch&&c=='Z'&&sw_tail)
1491
archive_cmt_name=swptr;
1493
else if(!jswitch&&!hswitch&&!os2switch&&c=='!'&&sw_tail)
1496
listchars_allowed=1;
1497
listchar=toupper(*swptr);
1499
else if(!jswitch&&!hswitch&&!os2switch&&c=='$'&&sw_tail)
1503
label_drive=toupper(*swptr);
1504
if(!isalpha(*swptr)||strlen(swptr)>2)
1505
error(M_INVALID_SWITCH, sw);
1506
if(swptr[1]!=':'&&swptr[1]!='\0')
1507
error(M_INVALID_SWITCH, sw);
1509
else if(!jswitch&&!hswitch&&!os2switch&&c=='+'&&sw_tail)
1511
else if(hswitch&&c=='B')
1517
else if(hswitch&&c=='C'&&sw_tail)
1523
else if(hswitch&&c=='D')
1526
error(M_INVALID_SWITCH, sw);
1531
else if(hswitch&&c=='G')
1534
gost_cipher=GOST256;
1535
if(*swptr=='!'&&swptr[1]=='\0')
1538
arjcrypt_name=swptr;
1540
else if(hswitch&&c=='M')
1543
filelist_storage=BST_DISK;
1544
max_filenames=(FILE_COUNT)stoul(swptr, &swptr);
1545
if(max_filenames==0)
1546
max_filenames=EXT_FILELIST_CAPACITY;
1547
if(*swptr=='!'&&swptr[1]!='\0')
1550
else if(*swptr=='!'&&swptr[1]=='\0')
1551
filelist_storage=BST_XMS;
1554
else if(hswitch&&c=='N')
1557
nonexist_filespec=1;
1558
nonexist_name=swptr;
1560
else if(hswitch&&c=='P')
1566
else if(hswitch&&c=='T')
1569
set_target_directory=1;
1570
p_len=strlen(swptr);
1571
p_ptr=&swptr[p_len-1];
1574
if(strchr(path_separators, *p_ptr)!=NULL)
1578
strcpy(target_dir=malloc_msg(p_len+2), swptr);
1579
target_dir[p_len]=PATHSEP_DEFAULT;
1580
target_dir[p_len+1]='\0';
1583
else if(hswitch&&c=='V')
1589
else if(hswitch&&c=='X')
1592
override_archive_exts=1;
1593
archive_ext_list=swptr;
1594
if(swptr[0]!='.'||swptr[1]=='\0')
1595
error(M_INVALID_SWITCH, sw);
1597
else if(hswitch&&c=='Z')
1601
arjsec_env_name=swptr;
1603
else if(hswitch&&c=='#'&&*swptr!='\0'&&!isdigit(*swptr))
1609
else if(jswitch&&c=='C'&&sw_tail)
1613
exit_count=(FILE_COUNT)stoul(swptr, &swptr);
1615
else if(jswitch&&c=='D'&&sw_tail)
1619
minfree=stoul(swptr, &swptr);
1621
else if(jswitch&&c=='B'&&sw_tail)
1624
chapter_mode=CHAP_USE;
1629
chapter_to_process=RESERVED_CHAPTER;
1633
cnv_num=stoul(swptr, &swptr);
1634
chapter_to_process=current_chapter=(int)cnv_num;
1638
chapter_to_process=RESERVED_CHAPTER;
1641
cnv_num=stoul(swptr, &swptr);
1642
chapter_to_process=(int)cnv_num;
1643
if(chapter_to_process>CHAPTERS_MAX)
1644
error(M_INVALID_SWITCH, sw);
1647
if(current_chapter==0&&chapter_to_process==0)
1648
chapter_mode=CHAP_REMOVE;
1651
else if(jswitch&&c=='H'&&sw_tail)
1655
cnv_num=stoul(swptr, &swptr);
1656
if(cnv_num<(unsigned long)MIN_BUFSIZ||cnv_num>(unsigned long)MAX_USER_BUFSIZ)
1657
error(M_INVALID_SWITCH, sw);
1658
#if MAX_BUFSIZ<MAX_USER_BUFSIZ
1659
if(cnv_num>(unsigned long)MAX_BUFSIZ)
1662
user_bufsiz=(unsigned int)cnv_num;
1664
else if(jswitch&&c=='I'&&sw_tail)
1670
else if(jswitch&&c=='N'&&sw_tail)
1673
restart_at_filename=1;
1674
filename_to_restart=swptr;
1676
else if(jswitch&&c=='Q'&&sw_tail)
1679
set_string_parameter=1;
1680
string_parameter=swptr;
1682
else if(jswitch&&c=='P'&&sw_tail)
1686
cnv_num=stoul(swptr, &swptr);
1688
lines_per_page=(int)cnv_num;
1690
else if(jswitch&&c=='S'&&sw_tail)
1694
free(archive_suffixes);
1695
archive_suffixes=swptr;
1697
else if(jswitch&&c=='W'&&sw_tail)
1701
extraction_filename=swptr;
1703
else if(jswitch&&c=='X'&&sw_tail)
1707
ext_pos=stoul(swptr, &swptr);
1709
else if(jswitch&&c=='Y'&&sw_tail)
1713
yes_query_list=swptr;
1714
parse_yes_queries(yes_query_list);
1716
else if(jswitch&&c=='Z'&&sw_tail)
1719
supply_comment_file=1;
1723
else if(os2switch&&c=='B')
1726
add_blkdev_spec(swptr);
1729
else if(os2switch&&c=='E')
1737
#if defined(HAVE_EAS)
1738
flist_add_files(&flist_ea, NULL, swptr, 0, 0, 0, NULL);
1742
else if(os2switch&&c=='I'&&sw_tail)
1746
arcv_ext_pos=stoul(swptr, &swptr);
1748
else if(os2switch&&c=='P')
1751
error(M_INVALID_SWITCH, sw);
1752
priority.class=stoul(swptr, &swptr);
1753
if(priority.class<1||priority.class>PRIORITY_CLASSES)
1754
error(M_INVALID_SWITCH, sw);
1755
#if TARGET==OS2||TARGET==WIN32
1756
if((p_ptr=strchr(swptr, ':'))==NULL)
1761
priority.delta=stoul(swptr, &swptr);
1763
if(priority.delta<-31||priority.delta>31)
1765
if(priority.delta<-2||priority.delta>2)
1767
#error No priority delta limits!
1769
error(M_INVALID_SWITCH, sw);
1776
else if(os2switch&&c=='T')
1778
done=!parse_colors(swptr);
1780
error(M_INVALID_SWITCH, sw);
1783
else if(os2switch&&c=='X')
1787
error(M_MISSING_FILENAME_ARG, "-2x");
1791
#if defined(HAVE_EAS)
1792
flist_add_files(&flist_xea, NULL, swptr, 0, 0, 0, NULL);
1796
else if(*swptr=='+')
1801
else if(*swptr=='-')
1806
else if(*swptr>='0'&&*swptr<='9')
1808
if(!debug_enabled||strchr(debug_opt, 's')==NULL)
1811
error(M_INVALID_SWITCH, sw);
1813
*index[num]=(int)(*(swptr++)+1-'0');
1816
*index[num]=!*index[num];
1817
/* ARJSFXV parameters */
1818
#elif SFX_LEVEL==ARJSFXV
1823
garble_password=swptr;
1825
else if(c=='+'&&sw_tail)
1830
error(M_INVALID_SWITCH, sw);
1845
extr_cmd_text=swptr;
1847
else if(c=='$'&&sw_tail)
1851
label_drive=toupper(*swptr);
1852
if(!isalpha(*swptr)||strlen(swptr)>2)
1853
error(M_INVALID_SWITCH, sw);
1854
if(swptr[1]!=':'&&swptr[1]!='\0')
1855
error(M_INVALID_SWITCH, sw);
1857
else if(c=='W'&&sw_tail)
1861
extraction_filename=swptr;
1863
else if(c=='D'&&sw_tail)
1867
minfree=stoul(swptr, &swptr);
1869
else if(c=='#'&&sw_tail)
1873
first_volume_number=stoul(swptr, &swptr);
1875
else if(c=='O'&&sw_tail)
1878
gost_cipher=GOST256;
1879
arjcrypt_name=swptr;
1881
else if(c=='Z'&&sw_tail)
1885
yes_query_list=swptr;
1886
parse_yes_queries(yes_query_list);
1888
else if(*swptr=='+')
1893
else if(*swptr=='-')
1898
else if(*swptr>='0'&&*swptr<='3')
1900
if(!debug_enabled||strchr(debug_opt, 's')==NULL)
1903
error(M_INVALID_SWITCH, sw);
1905
*index[num]=(int)(*(swptr++)+1-'0');
1908
*index[num]=!*index[num];
1909
/* ARJSFX parameters */
1910
#elif SFX_LEVEL==ARJSFX
1912
if(c=='G'&&*swptr!='\0')
1914
garble_password=swptr;
1920
extr_cmd_text=swptr;
1925
#if SFX_LEVEL>=ARJSFXV
1933
/* This will become obsolete as COLOR_OUTPUT has changed the semantics of
1934
quiet_mode - ASR fix 23/01/2003 */
1935
#ifndef COLOR_OUTPUT
1936
if(quiet_mode&&!arjdisp_enabled)
1944
#if SFX_LEVEL>=ARJSFXV
1946
/* Initializes system variables with default settings prior to setup
1954
multivolume_option=0;
1956
multivolume_option=1;
1959
for(i=0; i<SEARCH_STR_MAX; i++)
1961
search_reserve=NULL;
1964
for(i=0; i<params_max; i++)
1967
for(i=0; i<TOTAL_QUERIES; i++)
1968
queries_assume_yes[i]=queries_assume_no[i]=0;
1971
primary_file_type=ARJT_BINARY;
1973
listchar=LISTCHAR_DEFAULT;
1975
lines_per_page=query_screen_height();
1977
listchars_allowed=1;
1984
#if SFX_LEVEL<=ARJSFXV
1995
max_filenames=EXT_FILELIST_CAPACITY;
2002
ts_store(&tested_ftime_newer, OS_SPECIAL, 0);
2003
ts_store(&tested_ftime_older, OS_SPECIAL, 0);
2006
arch_wildcard_allowed=0;
2007
file_attr_mask=TAG_FILES;
2008
recursion_order=RO_LAST;
2018
set_target_directory=0;
2022
#if SFX_LEVEL<=ARJSFXV
2023
prompt_for_directory=0;
2035
subdir_extraction=0;
2037
override_archive_exts=0;
2038
disable_comment_series=0;
2039
skip_century=CENT_DEFAULT;
2040
show_filenames_only=0;
2043
freshen_criteria=FC_NONE;
2046
clear_archive_bit=0;
2047
ignore_archive_errors=0;
2048
ignore_open_errors=0;
2063
yes_on_all_queries=0;
2065
skip_switch_processing=0;
2068
filter_same_or_newer=0;
2071
marksym_expansion=0;
2075
priority.class=priority.delta=0;
2078
#if SFX_LEVEL<=ARJSFXV
2079
subdir_extraction=0;
2081
show_filenames_only=0;
2083
freshen_criteria=FC_NONE;
2084
validate_style=VALIDATE_ALL;
2091
yes_on_all_queries=0;
2093
skip_switch_processing=0;
2100
query_for_each_file=0;
2101
set_string_parameter=0;
2104
ignore_crc_errors=0;
2107
#if SFX_LEVEL<=ARJSFXV
2112
#if SFX_LEVEL<=ARJSFXV
2114
process_lfn_archive=0;
2115
skip_preset_options=0;
2119
select_backup_files=0;
2129
timestamp_override=0;
2131
translate_unix_paths=0;
2133
update_criteria=UC_NONE;
2137
beep_between_volumes=0;
2140
whole_files_in_mv=0;
2142
#if SFX_LEVEL>=ARJSFXV /* To keep v 2.71 order */
2146
assign_work_directory=0;
2150
kbd_cleanup_on_input=0;
2151
skip_append_query=0;
2157
skip_rename_prompt=0;
2158
overwrite_existing=0;
2160
skip_scanned_query=0;
2162
skip_next_vol_query=0;
2164
accept_shortcut_keys=0;
2167
first_volume_number=0;
2171
supply_comment_file=0;
2173
chapter_to_process=0;
2174
resume_volume_num=0;
2183
mv_reserve_space=0L;
2189
av_total_longnames=0;
2192
user_bufsiz=current_bufsiz=BUFSIZ_DEFAULT;
2193
ntext=NULL; /* ASR fix for 2.76.06 */
2195
sl_entries.list=l_entries.list=NULL;
2196
sl_entries.total=sl_entries.alloc=l_entries.total=l_entries.alloc=0;
2199
nonexist_name=nonexistent_name;
2200
archive_suffixes=malloc_fmsg(M_ARCHIVE_SUFFIXES);
2203
work_directory=nullstr;
2209
cmd_to_exec=nullstr;
2210
archive_ext_list=nullstr;
2215
timestr_newer=nullstr;
2216
timestr_older=nullstr;
2218
extr_cmd_text=nullstr;
2219
garble_password=nullstr;
2221
arjdisp_ptr=nullstr;
2223
filename_to_restart=nullstr;
2225
arjsec_env_name=nullstr;
2227
arjcrypt_name=nullstr;
2228
string_parameter=nullstr;
2232
extraction_filename=nullstr;
2233
yes_query_list=nullstr;
2235
archive_cmt_name=nullstr;
2236
comment_file=nullstr;
2238
tmp_tmp_filename[0]='\0';
2239
archive_name[0]='\0';
2240
#if SFX_LEVEL<=ARJSFXV
2245
#if SFX_LEVEL>=ARJSFXV
2256
suppress_hardlinks=0;
2260
/* Returns 1 if the given argument is a command-line switch */
2262
int is_switch(char *arg)
2266
if(!skip_switch_processing&&switch_char!=0&&(int)arg[0]==switch_char)
2268
else if(!skip_switch_processing&&switch_char==0)
2269
rc=(strchr(switch_chars, arg[0])==NULL)?0:1;
2272
if(rc&&switch_char==0)
2273
switch_char=(int)arg[0];
2281
/* Performs general command-line analysis and returns the command being
2284
int preprocess_cmdline(int argc, char *argv[])
2293
skip_switch_processing=0;
2294
rsp_name=nullstr; /* ASR fix -- 15/10/2000 (ARJ/2-32) */
2301
garble_password=nullstr;
2302
arj_env_name=malloc_fmsg(M_ARJ_SW);
2303
for(i=1; i<argc; i++)
2314
free_fmsg(arj_env_name);
2315
arj_env_name=malloc_str(arg+2);
2318
else if(arg[1]=='&'&&arg[2]=='\0')
2320
else if(arg[1]=='*'&&arg[2]=='\0')
2321
quiet_mode=ARJ_QUIET;
2322
else if(arg[1]=='*'&&arg[2]=='1'&&arg[3]=='\0')
2323
quiet_mode=ARJ_SILENT;
2324
else if(arg[1]=='*'&&arg[2]=='2'&&arg[3]=='\0') /* v 2.72 - New function */
2325
quiet_mode=ARJ_QUIET2;
2326
else if(toupper(arg[1])=='G')
2329
garble_password=arg+2;
2331
else if(toupper(arg[1])=='H'&&toupper(arg[2])=='Y')
2333
use_ansi_cp=ANSICP_CONVERT;
2335
use_ansi_cp=ANSICP_SKIP;
2336
else if(arg[3]=='2')
2337
use_ansi_cp=ANSICP_USE_OEM;
2338
else if(arg[3]=='3')
2339
use_ansi_cp=ANSICP_USE_ANSI;
2341
else if(arg[0]==arg[1]&&arg[2]=='\0')
2342
skip_switch_processing=1;
2346
if(i==1&&arg[0]=='@'&&arg[1]!='\0')
2348
else if(cmd==0&&rsp_name[0]=='\0')
2350
if(!stricmp(arg, cmd_ac))
2352
else if(!stricmp(arg, cmd_cc))
2354
else if(!stricmp(arg, cmd_dc))
2357
cmd=toupper(arg[0]);
2361
if(cmd==ARJ_CMD_PRINT||cmd==ARJ_CMD_SAMPLE)
2370
#if SFX_LEVEL>=ARJSFX||defined(REARJ)
2372
/* Splits the given name to pathname and filename. On return, pathname
2373
contains ASCIIZ path specification including path terminator, filename
2374
contains ASCIIZ filename (with no preceding path terminators), and the
2375
return value is the offset of filename within the given name. */
2377
#if SFX_LEVEL>=ARJSFXV||defined(REARJ)
2378
int split_name(char *name, char *pathname, char *filename)
2380
int split_name(char *name)
2383
char *f_sep, *last_sep;
2387
for(i=0; path_separators[i]!='\0'; i++)
2389
if((f_sep=strrchr(name, path_separators[i]))!=NULL)
2391
if(last_sep==NULL||f_sep>last_sep)
2395
sep_offset=(last_sep==NULL)?0:last_sep-name+1;
2396
#if SFX_LEVEL>=ARJSFXV||defined(REARJ)
2398
strcpyn(pathname, name, sep_offset+1);
2400
strcpy(filename, name+sep_offset);
2407
#if SFX_LEVEL>=ARJSFXV
2409
/* Returns the error code for error message given */
2411
int subclass_errors(FMSG *errmsg)
2413
if(errmsg==M_OUT_OF_MEMORY||errmsg==M_OUT_OF_NEAR_MEMORY)
2414
return(ARJ_ERL_NO_MEMORY);
2415
if(errmsg==M_HEADER_CRC_ERROR||errmsg==M_CRC_ERROR)
2416
return(ARJ_ERL_CRC_ERROR);
2418
if(errmsg==M_DAMAGED_SEC_ARCHIVE||errmsg==M_CANT_UPDATE_SEC||errmsg==M_SKIPPING_SEC)
2419
return(ARJ_ERL_ARJSEC_ERROR);
2421
if(errmsg==M_DISK_FULL)
2422
return(ARJ_ERL_DISK_FULL);
2423
if(errmsg==M_CANTOPEN)
2424
return(ARJ_ERL_CANTOPEN);
2425
if(errmsg==M_NOT_ARJ_ARCHIVE)
2426
return(ARJ_ERL_NOT_ARJ_ARCHIVE);
2429
if(errmsg==M_LISTING_XMS_ERROR)
2430
return(ARJ_ERL_XMS_ERROR);
2432
if(errmsg==M_TOO_MANY_CHAPTERS)
2433
return(ARJ_ERL_TOO_MANY_CHAPTERS);
2435
if(errmsg==M_INVALID_SWITCH||errmsg==M_ARGTABLE_OVERFLOW||errmsg==M_NO_FILE_GIVEN||
2437
errmsg==M_NO_DELETE_ARG||errmsg==M_INVALID_VOL_SIZE||
2438
errmsg==M_NO_STR_ENTERED||errmsg==M_JT_UNUSABLE||
2440
errmsg==M_NO_PWD_OPTION||
2441
errmsg==M_MISSING_FILENAME_ARG||errmsg==M_INVALID_DATE_STRING||errmsg==M_BAD_SYNTAX)
2442
return(ARJ_ERL_USER_ERROR);
2443
return(ARJ_ERL_FATAL_ERROR);
2450
/* Retrieves search data from string parameter given by -jq */
2452
static int get_str_from_jq()
2459
sptr=string_parameter;
2460
if(sptr[0]!='+'&&sptr[0]!='-')
2461
error(M_INVALID_PARAM_STR, sptr);
2462
ignore_pcase=sptr[0]=='+';
2463
fdisp_lines=(int)stoul(sptr, &sptr);
2469
/* Tokenize string_parameter */
2470
for(tsptr=sptr; *tsptr!='\0'; tsptr++)
2475
while((unsigned int)tsptr<(unsigned int)endptr&&patterns<SEARCH_STR_MAX)
2479
if((unsigned int)tsptr<(unsigned int)endptr)
2481
search_str[patterns++]=tsptr;
2482
while(*tsptr!='\0'&&(unsigned int)tsptr<(unsigned int)endptr)
2492
#if SFX_LEVEL>=ARJSFXV
2494
/* Performs an optimized seek operation */
2496
void file_seek(FILE *stream, long offset, int whence)
2500
if(whence==SEEK_CUR&&offset>=0L&&offset<=(long)CACHE_SIZE)
2502
buffer=malloc_msg(CACHE_SIZE);
2504
fread(buffer, 1, (int)offset, stream);
2508
fseek(stream, offset, whence);
2515
/* Performs a search operation set-up */
2519
char entry[INPUT_LENGTH];
2522
if(set_string_parameter&&string_parameter[0]!='\0')
2523
patterns=get_str_from_jq();
2526
ignore_pcase=query_action(REPLY_NO, QUERY_CRITICAL, M_QUERY_CASE_IGNORE);
2527
msg_cprintf(0, M_ENTER_NUM_MATCHES);
2528
read_line(entry, sizeof(entry));
2529
fdisp_lines=stoul(entry, NULL);
2530
msg_cprintf(0, M_ENTER_SEARCH_STR, SEARCH_STR_MAX);
2531
for(patterns=0; patterns<SEARCH_STR_MAX; patterns++)
2533
msg_cprintf(0, (FMSG *)le_prompt, patterns+1);
2534
if(read_line(entry, sizeof(entry))<=0)
2536
search_str[patterns]=malloc_str(entry);
2540
error(M_NO_STR_ENTERED);
2544
strupper(search_str[patterns]);
2547
indicator_style=IND_NONE;
2549
search_reserve=malloc_msg(sizeof(entry)*2);
2554
#if (SFX_LEVEL>=ARJSFX)||defined(ARJDISP)
2556
/* Based on the unsigned long values given, calculates their proportion (per
2557
mille, so 42.3% is returned as 423). */
2559
int calc_percentage(unsigned long partial, unsigned long total)
2563
for(dec=0; dec<3; dec++)
2565
if(partial<=0x19999999)
2570
if(partial+total/2<=partial)
2578
return((partial+total/2)/total);
2583
#if SFX_LEVEL>=ARJSFXV
2585
/* Performs a "smart" seeking, depending on file type (special handling is
2586
performed for text files) */
2588
void smart_seek(unsigned long position, FILE *stream)
2593
fseek(stream, 0L, SEEK_SET);
2596
if(file_type==ARJT_BINARY)
2597
fseek(stream, position, SEEK_SET);
2600
tmp_buf=(char *)malloc_msg(PROC_BLOCK_SIZE);
2603
fetch_size=(int)min(position, (unsigned long)PROC_BLOCK_SIZE);
2604
if(fread(tmp_buf, 1, fetch_size, stream)!=fetch_size)
2605
error(M_SEEK_FAILED);
2606
position-=(unsigned long)fetch_size;
2608
fseek(stream, 0L, SEEK_CUR);
2616
#if SFX_LEVEL>=ARJSFX||defined(REARJ)||defined(REGISTER)
2618
/* This procedure trims the extra spaces and tabs at the left and right of line
2621
void alltrim(char *cmd)
2627
for(fchars=strlen(cmd)-1; fchars>=0; fchars--)
2629
if(cmd[fchars]!='\x09'&&cmd[fchars]!=' ')
2634
while(lpos[0]=='\x09'||lpos[0]==' ')
2641
(cmd++)[0]=(lpos++)[0];
2650
#if SFX_LEVEL>=ARJSFX
2652
/* Extracts a stored file */
2654
void unstore(int action)
2657
#if SFX_LEVEL>=ARJSFXV
2658
unsigned int fetch_size;
2659
unsigned long cur_pos;
2661
unsigned long bytes_written;
2664
#if SFX_LEVEL>=ARJSFXV
2666
for(fetch_size=PROC_BLOCK_SIZE; fetch_size>=512; fetch_size-=512)
2668
if((fetch=(char *)malloc(fetch_size))!=NULL)
2672
error(M_OUT_OF_MEMORY);
2677
display_indicator(bytes_written=0L);
2678
#if SFX_LEVEL>=ARJSFXV
2681
cur_pos=ftell(aistream);
2682
count=min(fetch_size-(cur_pos%fetch_size), compsize);
2685
count=min(fetch_size, compsize);
2687
count=min(DICSIZ, compsize);
2693
if(fread(fetch, 1, count, aistream)!=count)
2698
far_memmove((char FAR *)fetch, packblock_ptr, count);
2699
packblock_ptr+=count;
2700
packmem_remain-=count;
2704
garble_decode_stub(fetch, count);
2706
garble_decode(fetch, count);
2708
bytes_written+=(unsigned long)count;
2709
display_indicator(bytes_written);
2710
compsize-=(unsigned long)count;
2711
if(extraction_stub(fetch, count, action))
2713
#if SFX_LEVEL>=ARJSFXV
2714
count=min(fetch_size, compsize);
2716
count=min(DICSIZ, compsize);
2719
#if SFX_LEVEL>=ARJSFXV
2728
/* Performs a "hollow" file decoding (compares the CRC if requested to do so,
2729
otherwise quits). */
2731
void hollow_decode(int action)
2734
unsigned long bytes_written;
2735
unsigned long cur_pos;
2738
if(action==BOP_COMPARE)
2740
fetch=(char *)malloc_msg(PROC_BLOCK_SIZE);
2742
display_indicator(bytes_written=0L);
2744
count=min(cur_pos, (unsigned long)PROC_BLOCK_SIZE);
2747
if(fread(fetch, 1, count, tstream)!=count)
2749
identical_filedata=0;
2752
crc32_for_block(fetch, count);
2753
bytes_written+=(unsigned long)count;
2754
display_indicator(bytes_written);
2755
cur_pos-=(unsigned long)count;
2756
count=min(PROC_BLOCK_SIZE, cur_pos);
2766
/* Packs a memory block. The destination area must be large enough to hold
2767
an unpacked copy. */
2769
void pack_mem(struct mempack *mempack)
2771
unsigned long s_compsize, s_origsize;
2772
int s_method, s_packing;
2776
s_compsize=compsize;
2777
s_origsize=origsize;
2779
s_packing=file_packing;
2781
origsize=mempack->origsize;
2783
method=mempack->method;
2784
encblock_ptr=mempack->orig;
2785
packblock_ptr=mempack->comp+MEMPACK_OVERHEAD;
2786
encmem_remain=mempack->origsize;
2790
file_type=ARJT_BINARY;
2792
garble_init(password_modifier);
2794
if(method==1||method==2||method==3)
2795
encode_stub(method);
2798
if(unpackable) /* Fall back to method #0 */
2800
encblock_ptr=mempack->orig;
2801
packblock_ptr=mempack->comp+MEMPACK_OVERHEAD;
2802
encmem_remain=mempack->origsize;
2805
garble_init(password_modifier);
2810
c_t=crc32term^CRC_MASK;
2811
mempack->comp[0]=c_t&0x000000FF;
2812
mempack->comp[1]=(c_t&0x0000FF00)>>8;
2813
mempack->comp[2]=(c_t&0x00FF0000)>>16;
2814
mempack->comp[3]=(c_t&0xFF000000)>>24;
2815
mempack->compsize=compsize+MEMPACK_OVERHEAD;
2816
mempack->method=method;
2818
file_packing=s_packing;
2819
compsize=s_compsize;
2820
origsize=s_origsize;
2826
#if SFX_LEVEL>=ARJSFXV
2828
/* Unpacks a memory block. The destination area must be large enough to hold
2829
an unpacked copy. */
2831
void unpack_mem(struct mempack *mempack)
2833
unsigned long s_compsize, s_origsize;
2834
int s_method, s_packing, s_type;
2838
s_compsize=compsize;
2839
s_origsize=origsize;
2841
s_packing=file_packing;
2842
file_type=ARJT_BINARY;
2843
origsize=mempack->origsize;
2844
encmem_limit=mempack->origsize;
2845
compsize=mempack->compsize-MEMPACK_OVERHEAD;
2846
method=mempack->method;
2847
encblock_ptr=mempack->orig;
2848
packblock_ptr=mempack->comp+MEMPACK_OVERHEAD;
2851
packmem_remain=mempack->compsize-MEMPACK_OVERHEAD;
2852
/* v 2.76.04+ - to allow for ARJCRYPT modules within SFXV, we reinitialize
2853
the encryption only for garbled files (was for garble_enabled until now) */
2855
garble_init(password_modifier);
2857
if(method==1||method==2||method==3)
2865
c_t=(unsigned long)((unsigned char)mempack->comp[0])+
2866
((unsigned long)((unsigned char)mempack->comp[1])<<8)+
2867
((unsigned long)((unsigned char)mempack->comp[2])<<16)+
2868
((unsigned long)((unsigned char)mempack->comp[3])<<24);
2869
if(c_t!=(crc32term^CRC_MASK))
2872
file_packing=s_packing;
2873
compsize=s_compsize;
2874
origsize=s_origsize;
2880
/* Strips ending LF character from the given string */
2882
#if SFX_LEVEL>=ARJSFX||defined(REGISTER)||defined(REARJ)
2883
void strip_lf(char *str)
2887
if((i=strlen(str))>0)
2895
/* Trims leftmost spaces */
2897
#if SFX_LEVEL>=ARJ||defined(REGISTER)||defined(REARJ)
2898
char *ltrim(char *str)
2902
for(rc=str; *rc==' '; rc++);
2907
#if defined(WORDS_BIGENDIAN)&&!defined(ARJDISP)&&!defined(REGISTER)
2908
/* Model-independent routine to get 2 bytes from far RAM */
2910
unsigned int mget_word(char FAR *p)
2912
unsigned int b0, b1;
2919
/* Model-independent routine to get 4 bytes from far RAM */
2921
unsigned long mget_dword(char FAR *p)
2923
unsigned long w0, w1;
2930
/* Model-independent routine to store 2 bytes in far RAM */
2932
void mput_word(unsigned int w, char FAR *p)
2934
mput_byte(w&0xFF, p);
2935
mput_byte(w>>8 , p+1);
2938
/* Model-independent routine to store 4 bytes in far RAM */
2940
void mput_dword(unsigned long d, char FAR *p)
2942
mput_word(d&0xFFFF, p);
2943
mput_word(d>>16 , p+2);