~ubuntu-branches/ubuntu/precise/arj/precise-security

« back to all changes in this revision

Viewing changes to arj_proc.c

  • Committer: Bazaar Package Importer
  • Author(s): Guillem Jover
  • Date: 2004-06-27 08:07:09 UTC
  • Revision ID: james.westby@ubuntu.com-20040627080709-1gkxm72ex66gkwe4
Tags: upstream-3.10.21
ImportĀ upstreamĀ versionĀ 3.10.21

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
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
 
6
 * moved to ENVIRON.C.
 
7
 *
 
8
 */
 
9
 
 
10
#include "arj.h"
 
11
 
 
12
DEBUGHDR(__FILE__)                      /* Debug information block */
 
13
 
 
14
/* Other defines */
 
15
 
 
16
#define FNAME_FLEN                27    /* Length of formatted filename */
 
17
 
 
18
/* String table (may need some localization in the future...) */
 
19
 
 
20
#if SFX_LEVEL>=ARJ||defined(REARJ)
 
21
static char strtime_filler[]="00000000000000";
 
22
#endif
 
23
#if SFX_LEVEL>=ARJ
 
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 */
 
28
#endif
 
29
#if SFX_LEVEL>=ARJSFXV
 
30
static char nonexistent_name[]="...";
 
31
#endif
 
32
 
 
33
#if SFX_LEVEL>=ARJSFXV||defined(REARJ)
 
34
 
 
35
/* The first byte in integrity_pattern[] is changed to avoid confusion with the
 
36
   pattern to search */
 
37
 
 
38
static unsigned char integrity_pattern[]={0xB1, 0x03, 0xB0, 0x02, 0xB0, 0x03, 0xB0,
 
39
                                          0x04, 0xB0, 0x05, 0};
 
40
 
 
41
#endif
 
42
 
 
43
#if SFX_LEVEL>=ARJ
 
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) */
 
47
static int noswitch;
 
48
#endif
 
49
 
 
50
#if SFX_LEVEL>=ARJ
 
51
static
 
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, &timestamp_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};
 
63
static
 
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,
 
72
                  NULL};
 
73
static
 
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};
 
83
static
 
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,
 
88
                    &exclude_eas, NULL};
 
89
 
 
90
static
 
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
 
96
static
 
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};
 
107
static
 
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
 
112
static
 
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};
 
121
#endif
 
122
 
 
123
/* Local functions */
 
124
 
 
125
#if SFX_LEVEL>=ARJ
 
126
 static int compare_exts(char *name, char *pad);
 
127
#endif
 
128
 
 
129
#if SFX_LEVEL>=ARJ
 
130
 
 
131
/* Encodes a block of data */
 
132
 
 
133
void garble_encode_stub(char *data, int len)
 
134
{
 
135
 garble_encode(data, len);
 
136
}
 
137
 
 
138
/* Decodes a block of data */
 
139
 
 
140
void garble_decode_stub(char *data, int len)
 
141
{
 
142
 garble_decode(data, len);
 
143
}
 
144
 
 
145
#endif
 
146
 
 
147
#if SFX_LEVEL>=ARJ
 
148
 
 
149
/* Returns day of year */
 
150
 
 
151
static int day_of_year(struct tm *tms)
 
152
{
 
153
 int m, y, rc;
 
154
 
 
155
 rc=0;
 
156
 for(m=tms->tm_mon; m>0; m--)
 
157
 {
 
158
  switch(m)
 
159
  {
 
160
   case 1: rc+=31; break;
 
161
   case 2:
 
162
    rc+=28;
 
163
    y=tms->tm_year+1900;
 
164
    if((y%4==0)&&(y%100!=0||y%400==0))
 
165
     rc++;
 
166
    break;
 
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;
 
176
  }
 
177
 }
 
178
 return(rc+tms->tm_mday);
 
179
}
 
180
 
 
181
/* Appends current date/time to the archive filename in accordance with the
 
182
   "-h#" option */
 
183
 
 
184
void append_curtime_proc()
 
185
{
 
186
 time_t curtime;
 
187
 struct tm *tms;
 
188
 char time_pad[19];
 
189
 char ext[32];
 
190
 char *ext_pos;
 
191
 char *aptr, *tptr;
 
192
 char *dptr=time_pad;                   /* ASR fix for High C -- 29/03/2001 */
 
193
 int l, lim;
 
194
 int doy;                               /* Day of year */
 
195
 
 
196
 curtime=time(NULL);
 
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)
 
202
 {
 
203
  strncpy(ext, ext_pos, sizeof(ext));
 
204
  *ext_pos='\0';
 
205
 }
 
206
 else
 
207
  ext[0]='\0';
 
208
 if(time_str[0]=='\0')
 
209
 {
 
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)
 
215
  {
 
216
   time_pad[8]='\0';
 
217
   strcat(archive_name, time_pad+2);
 
218
  }
 
219
 }
 
220
 else                                   /* Custom format */
 
221
 {
 
222
  l=strlen(time_str);
 
223
  aptr=archive_name+strlen(archive_name)+l;
 
224
  *aptr='\0';
 
225
  lim=0;
 
226
  for(tptr=time_str+l-1; (tptr-time_str)>=0; tptr--)
 
227
  {
 
228
   if(*tptr==*(tptr+1))
 
229
    *(--aptr)=(lim>0)?dptr[--lim]:*tptr;
 
230
   else
 
231
   {
 
232
    switch(*tptr)
 
233
    {
 
234
     case 'Y':
 
235
      dptr=time_pad;
 
236
      lim=4;
 
237
      *(--aptr)=dptr[--lim];
 
238
      break;
 
239
     case 'M':
 
240
      dptr=time_pad+4;
 
241
      lim=2;
 
242
      *(--aptr)=dptr[--lim];
 
243
      break;
 
244
     case 'D':
 
245
      dptr=time_pad+6;
 
246
      lim=2;
 
247
      *(--aptr)=dptr[--lim];
 
248
      break;
 
249
     case 'N':
 
250
      dptr=time_pad+8;
 
251
      lim=3;
 
252
      *(--aptr)=dptr[--lim];
 
253
      break;
 
254
     case 'h':
 
255
      dptr=time_pad+11;
 
256
      lim=2;
 
257
      *(--aptr)=dptr[--lim];
 
258
      break;
 
259
     case 'm':
 
260
      dptr=time_pad+13;
 
261
      lim=2;
 
262
      *(--aptr)=dptr[--lim];
 
263
      break;
 
264
     case 's':
 
265
      dptr=time_pad+15;
 
266
      lim=2;
 
267
      *(--aptr)=dptr[--lim];
 
268
      break;
 
269
     default:
 
270
      *(--aptr)=*tptr;
 
271
    }
 
272
   }
 
273
  }
 
274
 }
 
275
 strcat(archive_name, ext);
 
276
}
 
277
 
 
278
/* Adds an ending backslash to the given pathname if it doesn't contain one */
 
279
 
 
280
void add_pathsep(char *path)
 
281
{
 
282
 int len;
 
283
 
 
284
 if((len=strlen(path))==0)              /* Maybe current path? */
 
285
  return;
 
286
 if(strchr(path_separators, path[len-1])==NULL)
 
287
 {
 
288
  path[len]=PATHSEP_DEFAULT;
 
289
  path[len+1]='\0';
 
290
 }
 
291
}
 
292
 
 
293
/* Converts the timestamps given by the user to the internal storage format */
 
294
 
 
295
void convert_time_limits()
 
296
{
 
297
 char *cptr;
 
298
 time_t tmp_ts;
 
299
 time_t ts;
 
300
 struct tm *tms;
 
301
 struct timestamp arj_ts;               /* ARJ-format timestamp storage */
 
302
 
 
303
 if(filter_same_or_newer==TCHECK_NDAYS)
 
304
 {
 
305
  tmp_ts=strtoul(timestr_newer, &cptr, 10)*(-86400L);
 
306
  ts=sum_time(tmp_ts, time(NULL));
 
307
  tms=localtime(&ts);
 
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) */
 
312
 }
 
313
 if(filter_older==TCHECK_NDAYS)
 
314
 {
 
315
  tmp_ts=strtoul(timestr_older, &cptr, 10)*(-86400L);
 
316
  ts=sum_time(tmp_ts, time(NULL));
 
317
  tms=localtime(&ts);
 
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) */
 
322
 }
 
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'&&timestr_newer[0]=='\0')
 
328
 {
 
329
  ts=time(NULL);
 
330
  tms=localtime(&ts);
 
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;
 
336
 }
 
337
}
 
338
 
 
339
/* Analyzes ARJ_SW settings */
 
340
 
 
341
void parse_arj_sw(int cmd, char *arj_sw, char *dest)
 
342
{
 
343
 int use_file;                          /* 1 if ARJ_SW represents a file */
 
344
 char *buf;
 
345
 char *dptr, *varname;
 
346
 char *sptr;
 
347
 FILE *stream;
 
348
 char *sw, *sw_p;
 
349
 
 
350
 use_file=0;
 
351
 while(arj_sw[0]==' ')
 
352
  arj_sw++;
 
353
 if(strchr(switch_chars, arj_sw[0])==NULL)
 
354
 {
 
355
  buf=dest;
 
356
  dptr=dest+FILENAME_MAX+1;
 
357
  sptr=dest+FILENAME_MAX*2+2;
 
358
  sptr[0]='\0';
 
359
  dptr[0]='\0';
 
360
  stream=file_open_noarch(arj_sw, m_r);
 
361
  while(fgets(buf, FILENAME_MAX, stream)!=NULL)
 
362
  {
 
363
   strip_lf(buf);
 
364
   if(buf[0]=='#')
 
365
    continue;
 
366
   else if(!use_file&&buf[0]=='+'&&buf[1]==' ')
 
367
   {
 
368
    strcpy(sptr, buf+1);
 
369
    use_file=1;
 
370
   }
 
371
   else if(!use_file&&buf[0]=='-'&&buf[1]==' ')
 
372
   {
 
373
    strcat(dptr, buf+2);
 
374
    strcat(dptr, " ");
 
375
    use_file=1;
 
376
   }
 
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)))
 
380
   {
 
381
    strcpy(dptr, buf+3);
 
382
    use_file=1;
 
383
    break;
 
384
   }
 
385
   else
 
386
   {
 
387
    if(toupper((int)buf[0])==cmd&&buf[1]==' ')
 
388
    {
 
389
     strcpy(dptr, buf+2);
 
390
     use_file=1;
 
391
     break;
 
392
    }
 
393
   }
 
394
  }
 
395
  fclose(stream);
 
396
  strcat(dptr, sptr);
 
397
  sw=malloc_str(dptr);
 
398
 }
 
399
 else
 
400
  sw=malloc_str(arj_sw);
 
401
 varname=use_file?arj_sw:arj_env_name;
 
402
 sw_p=malloc_str(sw);
 
403
 /* Tokenize switch */
 
404
 for(dptr=sw; *dptr!='\0'; dptr++)
 
405
  if(*dptr==' ')
 
406
   *dptr='\0';
 
407
 sptr=dptr;
 
408
 dptr=sw;
 
409
 while((dptr-sptr)<0)
 
410
 {
 
411
  while(*dptr=='\0')
 
412
   dptr++;
 
413
  if((dptr-sptr)<0)
 
414
  {
 
415
   if(is_switch(dptr))
 
416
    analyze_arg(dptr);
 
417
   while(*dptr!='\0'&&(dptr-sptr)<0)
 
418
    dptr++;
 
419
  }
 
420
 }
 
421
 if(!translate_unix_paths)
 
422
  switch_char=0;
 
423
 msg_cprintf(H_HL|H_NFMT, M_USING_ENV_VAR, varname, sw_p);
 
424
 free(sw_p);
 
425
}
 
426
 
 
427
/* Copies a part of archive */
 
428
 
 
429
void copy_bytes(unsigned long nbytes)
 
430
{
 
431
 char *buf;
 
432
 unsigned int fetch_size;
 
433
 
 
434
 buf=malloc_msg(PROC_BLOCK_SIZE);
 
435
 fseek(aistream, 0L, SEEK_SET);
 
436
 while(nbytes>0L)
 
437
 {
 
438
  fetch_size=(unsigned int)min(PROC_BLOCK_SIZE, nbytes);
 
439
  if(fread(buf, 1, fetch_size, aistream)!=fetch_size)
 
440
   error(M_CANTREAD);
 
441
  if(fwrite(buf, 1, fetch_size, aostream)!=fetch_size)
 
442
   error(M_DISK_FULL);
 
443
  nbytes-=(unsigned long)fetch_size;
 
444
 }
 
445
 free(buf);
 
446
}
 
447
 
 
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
 
452
   procedure. */
 
453
 
 
454
int translate_path(char *name)
 
455
{
 
456
 int i;
 
457
 
 
458
 if(strchr(name, PATHSEP_UNIX)!=NULL)
 
459
  return(0);
 
460
 for(i=0; name[i]!=0; i++)
 
461
  if(name[i]==PATHSEP_DEFAULT)
 
462
   name[i]=PATHSEP_UNIX;
 
463
 return(1);
 
464
}
 
465
 
 
466
/* Restarts archive processing from the specified file */
 
467
 
 
468
void restart_proc(char *dest)
 
469
{
 
470
 char *r_name, *c_name;
 
471
 char *dptr;
 
472
 char vol_stats[40];
 
473
 char *vs_ptr;
 
474
 int i;
 
475
 int vs_match;
 
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 */
 
478
 FILE_COUNT cur_file;
 
479
 int nd;
 
480
 
 
481
 dptr=dest;
 
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);
 
486
 vs_ptr=vol_stats;
 
487
 i=0;
 
488
 while(*vs_ptr!='\0')
 
489
 {
 
490
  if(!strncmp(vs_ptr, vol_st_id, sizeof(vol_st_id)-1))
 
491
   break;
 
492
  i++;
 
493
  vs_ptr++;
 
494
 }
 
495
 i+=sizeof(vol_st_id)-1;
 
496
 if(filename_to_restart[0]=='\0'&&index_name[0]!='\0')
 
497
 {
 
498
  vs_match=0;
 
499
  r_name[0]='\0';
 
500
  idxstream=file_open_noarch(index_name, m_r);
 
501
  while(fgets(dptr, FILENAME_MAX, idxstream)!=NULL)
 
502
  {
 
503
   strip_lf(dptr);
 
504
   if(!memcmp(dptr, vol_stats, i))
 
505
   {
 
506
    vs_match=1;
 
507
    vn=atoi(dptr+i);
 
508
    vc=atoi(dptr+i+4);
 
509
    vs=atoi(dptr+i+6);
 
510
    strcpy(r_name, dptr+i+17);
 
511
   }
 
512
  }
 
513
  fclose(idxstream);
 
514
  if(vs_match==0)
 
515
   error(M_RESTART_INFO_NF);
 
516
  else
 
517
  {
 
518
   resume_volume_num=vn;
 
519
   if(vc==1)
 
520
   {
 
521
    start_at_ext_pos=1;
 
522
    ext_pos=vs;
 
523
   }
 
524
   else if(vc==2)
 
525
    error(M_NOTHING_TO_DO);
 
526
  }
 
527
 }
 
528
 for(cur_file=0L; cur_file<flist_main.files; cur_file++)
 
529
 {
 
530
  flist_retrieve(c_name, NULL, &flist_main, cur_file);
 
531
  if(!strcmp_os(c_name, r_name))
 
532
   break;
 
533
  cfa_store(cur_file, FLFLAG_DELETED);
 
534
 }
 
535
 if(cur_file>=flist_main.files)
 
536
  error(M_CANT_FIND_RST_FILE, r_name);
 
537
 free(c_name);
 
538
 free(r_name);
 
539
 if(create_sfx)
 
540
 {
 
541
  nd=split_name(archive_name, NULL, NULL);
 
542
  vs_ptr=strchr(archive_name+nd, '.');
 
543
  if(vs_ptr==NULL)
 
544
   msg_strcat(archive_name, M_EXE_EXT);
 
545
  else
 
546
   msg_strcpy(vs_ptr, M_EXE_EXT);
 
547
 }
 
548
}
 
549
 
 
550
/* Looks for an extension of the given filename in the extension list */
 
551
 
 
552
int search_for_extension(char *name, char *ext_list)
 
553
{
 
554
 int match;
 
555
 char *endptr;
 
556
 char ext_pad[EXTENSION_MAX+1];
 
557
 char *t_ptr;
 
558
 int i;
 
559
 
 
560
 match=0;
 
561
 endptr=&ext_list[strlen(ext_list)];
 
562
 t_ptr=ext_list;
 
563
 while(t_ptr!=endptr)
 
564
 {
 
565
  if(*t_ptr=='.')
 
566
   t_ptr++;
 
567
  ext_pad[0]='.';
 
568
  for(i=0; i<EXTENSION_MAX&&t_ptr[i]!='\0'&&t_ptr[i]!='.'; i++)
 
569
   ext_pad[i+1]=t_ptr[i];
 
570
  ext_pad[i+1]='\0';
 
571
  if(compare_exts(name, ext_pad))
 
572
  {
 
573
   match=1;
 
574
   break;
 
575
  }
 
576
  else
 
577
  {
 
578
   while(*t_ptr!='\0'&&*t_ptr!='.')
 
579
    t_ptr++;
 
580
  }
 
581
 }
 
582
 return(match);
 
583
}
 
584
 
 
585
/* Returns the exact amount of data that could be safely written to the
 
586
   destination volume */
 
587
 
 
588
unsigned long get_volfree(unsigned int increment)
 
589
{
 
590
 unsigned long pvol;
 
591
 unsigned int arjsec_overhead;
 
592
 long remain;
 
593
 
 
594
 if(increment==0||volume_flag_set)
 
595
 {
 
596
  volume_flag_set=1;
 
597
  return(0);
 
598
 }
 
599
 pvol=0L;
 
600
 if(arjprot_tail)
 
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));
 
609
}
 
610
 
 
611
/* Performs various checks when multivolume data is packed to predict an
 
612
   overrun. Returns number of bytes that could be successfully written. */
 
613
 
 
614
unsigned int check_multivolume(unsigned int increment)
 
615
{
 
616
 unsigned long pvol;
 
617
 unsigned int arjsec_overhead;
 
618
 long remain;
 
619
 unsigned int inc, rc;
 
620
 
 
621
 if(!file_packing)
 
622
  return(increment);
 
623
 if(increment==0||volume_flag_set)
 
624
 {
 
625
  volume_flag_set=1;
 
626
  return(0);
 
627
 }
 
628
 pvol=0L;
 
629
 if(protfile_option)
 
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;
 
634
 stop_optimizer();
 
635
 remain-=(long)out_bytes+(long)cpos+(long)ext_voldata;
 
636
 stop_optimizer();
 
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)
 
640
  bufsiz>>=1;
 
641
 if(bufsiz<MIN_CRITICAL_BUFSIZ)
 
642
  bufsiz=MIN_CRITICAL_BUFSIZ;
 
643
 if((long)increment+1000L<remain&&(long)increment*2L<remain)
 
644
  return(increment);
 
645
 inc=0;
 
646
 if((long)increment<remain)
 
647
  inc=increment;
 
648
 else if(remain>0)
 
649
  inc=remain;
 
650
 if(inc<=0)
 
651
 {
 
652
  volume_flag_set=1;
 
653
  return(0);
 
654
 }
 
655
 if((long)increment*2L>remain)
 
656
 {
 
657
  if(inc>1000)
 
658
   rc=(inc-inc%500)>>1;
 
659
  else if(inc>2000)
 
660
   rc=inc-1000;
 
661
  else
 
662
   rc=(inc>512)?inc>>1:inc;
 
663
 }
 
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));
 
668
}
 
669
 
 
670
/* Compares the extension from pad with the file's extension. Returns 1 if
 
671
   there was a match. */
 
672
 
 
673
static int compare_exts(char *name, char *pad)
 
674
{
 
675
 int k;
 
676
 
 
677
 /* si = name, di = pad */
 
678
 if(strlen(pad)==1&&strchr(name, '.')==NULL)
 
679
  return(1);
 
680
 k=strlen(name)-strlen(pad);
 
681
 if(k<0)
 
682
  return(0);
 
683
 else
 
684
  return(strcmp_os(name+k, pad)==0);
 
685
}
 
686
 
 
687
/* "Stores" a file by simply copying it */
 
688
 
 
689
void store()
 
690
{
 
691
 int fetch_size;
 
692
 unsigned int mem_size;
 
693
 char *fetch;
 
694
 int to_read;
 
695
 
 
696
 fetch=(char *)malloc_msg(PROC_BLOCK_SIZE);
 
697
 mem_stats();
 
698
 origsize=0L;
 
699
 cpos=0;
 
700
 ext_voldata=0;
 
701
 display_indicator(0L);
 
702
 crc32term=CRC_MASK;
 
703
 to_read=PROC_BLOCK_SIZE;
 
704
 if(multivolume_option&&file_packing)
 
705
  to_read=check_multivolume(to_read);
 
706
 if(file_packing)
 
707
 {
 
708
  while((fetch_size=fread_crc(fetch, to_read, encstream))>0)
 
709
  {
 
710
   if(garble_enabled)
 
711
    garble_encode_stub(fetch, fetch_size);
 
712
   if(!no_file_activity)
 
713
   {
 
714
    file_write(fetch, 1, fetch_size, aostream);
 
715
   }
 
716
   display_indicator(origsize);
 
717
   if(multivolume_option)
 
718
    to_read=check_multivolume(to_read);
 
719
  }
 
720
 }
 
721
 else
 
722
 {
 
723
  while(encmem_remain!=0)
 
724
  {
 
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);
 
728
   if(garble_enabled)
 
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;
 
733
   origsize+=mem_size;
 
734
   encmem_remain-=mem_size;             /* Changed this order. This is an ASR
 
735
                                           fix for High C beta -- 05/04/2001 */
 
736
  }
 
737
 }
 
738
 free(fetch);
 
739
 compsize=origsize;
 
740
}
 
741
 
 
742
/* Performs a "hollow" file processing (just calculates the CRC) */
 
743
 
 
744
void hollow_encode()
 
745
{
 
746
 int fetch_size;
 
747
 char *fetch;
 
748
 
 
749
 fetch=(char *)malloc_msg(PROC_BLOCK_SIZE);
 
750
 mem_stats();
 
751
 origsize=0L;
 
752
 out_bytes=0;
 
753
 cpos=0;
 
754
 ext_voldata=0;
 
755
 display_indicator(0L);
 
756
 crc32term=CRC_MASK;
 
757
 fetch_size=PROC_BLOCK_SIZE;
 
758
 while(fread_crc(fetch, fetch_size, encstream)!=0)
 
759
  display_indicator(origsize);
 
760
 free(fetch);
 
761
 compsize=0L;
 
762
}
 
763
 
 
764
#endif
 
765
 
 
766
#if SFX_LEVEL>=ARJ||defined(REARJ)
 
767
 
 
768
/* Retrieves a pair of decimal digits from the given pointer */
 
769
 
 
770
static int get_dec_pair(char *str)
 
771
{
 
772
 if(str[0]=='\0')
 
773
  return(0);
 
774
 if(str[1]=='\0')
 
775
  return((int)str[0]-'0');
 
776
 return((int)(str[0]-'0')*10+(int)(str[1]-'0'));
 
777
}
 
778
 
 
779
/* Converts the given time string ("yyyymmddhhmmss") to the internal timestamp
 
780
   format */
 
781
 
 
782
void convert_strtime(struct timestamp *dest, char *str)
 
783
{
 
784
 char tmp_strtime[30];
 
785
 int y, m, d, hh, mm, ss;               /* Timestamp components */
 
786
 
 
787
 strncpy(tmp_strtime, str, 14);
 
788
 tmp_strtime[14]='\0';
 
789
 strcat(tmp_strtime, strtime_filler);
 
790
 y=get_dec_pair(tmp_strtime);
 
791
 if(y>=19&&y<80)
 
792
 {
 
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);
 
799
 }
 
800
 else
 
801
 {
 
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;
 
808
 }
 
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);
 
812
}
 
813
 
 
814
#endif
 
815
 
 
816
#if SFX_LEVEL>=ARJSFXV||defined(REARJ)
 
817
 
 
818
/* Checks integrity of the executable file */
 
819
 
 
820
int check_integrity(char *name)
 
821
{
 
822
 #if SFX_LEVEL>=ARJ
 
823
  char *buf;
 
824
  int f_len=PROC_BLOCK_SIZE;
 
825
 #else
 
826
  char buf[CACHE_SIZE];
 
827
  int f_len=CACHE_SIZE;
 
828
 #endif
 
829
 FILE *stream;
 
830
 int p_len;
 
831
 int fetch, i;
 
832
 int c;
 
833
 char *bptr;
 
834
 unsigned long wr_pos;
 
835
 unsigned long fsize, cur_pos;
 
836
 char pattern[20];
 
837
 unsigned long st_crc, st_fsize;        /* Stored parameters */
 
838
 
 
839
 #if SFX_LEVEL>=ARJ
 
840
  buf=(char *)malloc_msg(f_len);
 
841
 #endif
 
842
 stream=file_open(name, m_rb);
 
843
 if(stream==NULL)
 
844
 {
 
845
  msg_cprintf(H_ERR, M_CANTOPEN, name);
 
846
  #if SFX_LEVEL>=ARJ
 
847
   nputlf();
 
848
   return(0);
 
849
  #else
 
850
   return(1);
 
851
  #endif
 
852
 }
 
853
 strcpy(pattern, (char *)integrity_pattern);
 
854
 pattern[0]--;
 
855
 p_len=strlen(pattern);
 
856
 fseek(stream, 0L, SEEK_END);
 
857
 fsize=ftell(stream);
 
858
 fseek(stream, 0L, SEEK_SET);
 
859
 crc32term=CRC_MASK;
 
860
 cur_pos=0L;
 
861
 while(1)
 
862
 {
 
863
  fseek(stream, cur_pos, SEEK_SET);
 
864
  fetch=fread(buf, 1, f_len, stream);
 
865
  if(fetch==0)
 
866
   #if SFX_LEVEL>=ARJSFXV
 
867
    error(M_CANTREAD);
 
868
   #else
 
869
    pause_error(M_NO_INTEGRITY_PATTERN);
 
870
   #endif
 
871
  fetch-=p_len;
 
872
  bptr=buf;
 
873
  for(i=0; i<fetch; i++)
 
874
  {
 
875
   if(!memcmp(bptr, pattern, p_len))
 
876
    break;
 
877
   bptr++;
 
878
  }
 
879
  if(i<fetch)
 
880
   break;
 
881
  cur_pos+=f_len/2;                     /* Dirty hack */
 
882
 }
 
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
 
887
   error(M_CANTREAD);
 
888
  #else
 
889
   pause_error(M_NO_INTEGRITY_PATTERN);
 
890
  #endif
 
891
 if(fread(&st_fsize, 1, 4, stream)!=4)
 
892
  #if SFX_LEVEL>=ARJSFXV
 
893
   error(M_CANTREAD);
 
894
  #else
 
895
   pause_error(M_NO_INTEGRITY_PATTERN);
 
896
  #endif
 
897
 #ifdef WORDS_BIGENDIAN   /* Another dirty hack */
 
898
 st_crc   = mget_dword((char*) &st_crc);
 
899
 st_fsize = mget_dword((char*) &st_fsize);
 
900
 #endif 
 
901
 crc32term=CRC_MASK;
 
902
 fseek(stream, 0L, SEEK_SET);
 
903
 for(cur_pos=0L; cur_pos<wr_pos; cur_pos++)
 
904
 {
 
905
  if((c=fgetc(stream))==-1)
 
906
   #if SFX_LEVEL>=ARJSFXV
 
907
    error(M_CANTREAD);
 
908
   #else
 
909
    pause_error(M_NO_INTEGRITY_PATTERN);
 
910
   #endif
 
911
  crc32term=crc32_for_char(crc32term, (unsigned char)c);
 
912
 }
 
913
 cur_pos+=8L;
 
914
 fseek(stream, cur_pos, SEEK_SET);
 
915
 while(cur_pos<fsize)
 
916
 {
 
917
  if((c=fgetc(stream))==-1)
 
918
   #if SFX_LEVEL>=ARJSFXV
 
919
    error(M_CANTREAD);
 
920
   #else
 
921
    pause_error(M_NO_INTEGRITY_PATTERN);
 
922
   #endif
 
923
  crc32term=crc32_for_char(crc32term, (unsigned char)c);
 
924
  cur_pos++;
 
925
 }
 
926
 fsize+=2L;
 
927
 #if SFX_LEVEL>=ARJ
 
928
  free(buf);
 
929
 #endif
 
930
 fclose(stream);
 
931
 #if SFX_LEVEL>=ARJSFXV
 
932
  return(crc32term==st_crc&&fsize==st_fsize);
 
933
 #else
 
934
  if(crc32term==st_crc&&fsize==st_fsize)
 
935
   msg_cprintf(0, M_INTEGRITY_OK);
 
936
  else
 
937
   pause_error(M_INTEGRITY_VIOLATED);
 
938
  return(0);
 
939
 #endif
 
940
}
 
941
 
 
942
#endif
 
943
 
 
944
/* Converts a filename to the format used in current OS (simply substitutes
 
945
   the UNIX separators with DOS ones) */
 
946
 
 
947
void name_to_hdr(char *name)
 
948
{
 
949
 int i;
 
950
 
 
951
 for(i=0; name[i]!='\0'; i++)
 
952
 {
 
953
  if(name[i]==PATHSEP_UNIX)
 
954
   name[i]=PATHSEP_DEFAULT;
 
955
 }
 
956
}
 
957
 
 
958
#if SFX_LEVEL>=ARJSFXV
 
959
 
 
960
/* Formats the given filename to look properly in the "Adding..." and other
 
961
   messages. */
 
962
 
 
963
char *format_filename(char *name)
 
964
{
 
965
 int f_pos, tf_pos;
 
966
 char *result;
 
967
 int ctr;                               /* Path delimiter counter */
 
968
 int len;
 
969
 static char name_holder[FNAME_FLEN+1];
 
970
 int i;
 
971
 
 
972
 if(show_filenames_only)
 
973
  f_pos=split_name(name, NULL, NULL);
 
974
 else
 
975
  f_pos=0;
 
976
 tf_pos=f_pos;
 
977
 ctr=1;
 
978
 while(name[tf_pos]!='\0')
 
979
 {
 
980
  if(tf_pos>0&&name[tf_pos]==PATHSEP_DEFAULT)
 
981
   ctr++;
 
982
  tf_pos++;
 
983
 }
 
984
 len=ctr*CCHMAXPATH+ctr;
 
985
 if(len>FNAME_FLEN-1)
 
986
  len=FNAME_FLEN-1;
 
987
 result=&name[f_pos];
 
988
 if(strlen(result)<len)
 
989
 {
 
990
  strcpy(name_holder, result);
 
991
  for(i=strlen(name_holder); i<len; i++)
 
992
   strcat(name_holder, " ");
 
993
  result=name_holder;
 
994
 }
 
995
 return(result);
 
996
}
 
997
 
 
998
#endif
 
999
 
 
1000
#if SFX_LEVEL>=ARJ
 
1001
 
 
1002
/* Parses the given argument to a file attribute bitmap */
 
1003
 
 
1004
static void parse_attrs(char *str)
 
1005
{
 
1006
 char *sptr, *attrptr;
 
1007
 char *g_attr;
 
1008
 char c;
 
1009
 int attrno;
 
1010
 
 
1011
 file_attr_mask=TAG_FILES;
 
1012
 if(*str=='\0')
 
1013
  file_attr_mask=TAG_RDONLY|TAG_SYSTEM|TAG_HIDDEN|TAG_DIREC|TAG_LABEL|
 
1014
                 TAG_CHAPTER|TAG_NORMAL|TAG_WINLFN;
 
1015
 else
 
1016
 {
 
1017
  sptr=str;
 
1018
  attrptr=allowed_attrs;
 
1019
  while((c=*sptr++)!='\0')
 
1020
  {
 
1021
   c=toupper(c);
 
1022
   if((g_attr=strchr(attrptr, c))==NULL)
 
1023
    error(M_INVALID_SWITCH, str);
 
1024
   attrno=g_attr-attrptr-1;
 
1025
   if(attrno>=0)
 
1026
    file_attr_mask|=1<<attrno;
 
1027
   else if(attrno==-1)
 
1028
    file_attr_mask=TAG_RDONLY|TAG_SYSTEM|TAG_HIDDEN|TAG_DIREC|TAG_NORMAL;
 
1029
  }
 
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;
 
1032
 }
 
1033
}
 
1034
 
 
1035
/* Returns real size in bytes for diskette size shortcuts (i.e., 360, 720, and
 
1036
   so on...) */
 
1037
 
 
1038
static unsigned long select_preset_size(unsigned long rsize)
 
1039
{
 
1040
 if(rsize==360)
 
1041
  return(362000L);
 
1042
 else if(rsize==720)
 
1043
  return(730000L);
 
1044
 else if(rsize==1200)
 
1045
  return(1213000L);
 
1046
 else if(rsize==1440)
 
1047
  return(1457000L);
 
1048
 return(rsize);
 
1049
}
 
1050
 
 
1051
#endif
 
1052
 
 
1053
#if SFX_LEVEL>=ARJSFXV
 
1054
 
 
1055
/* Returns 1 if the switch has a "tail" of extra dataa */
 
1056
 
 
1057
static int get_switch_state(char *sw)
 
1058
{
 
1059
 if(sw[0]=='\0')
 
1060
  return(0);
 
1061
 if((sw[0]=='+'||sw[0]=='-')&&sw[1]=='\0')
 
1062
  return(0);
 
1063
 return(1);
 
1064
}
 
1065
 
 
1066
/* Parses query list given by -jy for ARJ and -y for ARJSFX */
 
1067
 
 
1068
static void parse_yes_queries(char *sw)
 
1069
{
 
1070
 char *swptr;
 
1071
 unsigned int c;
 
1072
 int **index;
 
1073
 FMSG *table;
 
1074
 FMSG *entry;
 
1075
 int num;
 
1076
 
 
1077
 swptr=sw;
 
1078
 while((c=(unsigned int)*(swptr++))!='\0')
 
1079
 {
 
1080
  c=toupper(c);
 
1081
  index=jysw_index;
 
1082
  table=M_JYSW_TABLE;
 
1083
  if((entry=msg_strchr(table, (char)c))==NULL)
 
1084
   error(M_INVALID_SWITCH, sw);
 
1085
  num=entry-table;
 
1086
  if(*swptr=='+')
 
1087
  {
 
1088
   *index[num]=1;
 
1089
   swptr++;
 
1090
  }
 
1091
  else if(*swptr=='-')
 
1092
  {
 
1093
   *index[num]=0;
 
1094
   swptr++;
 
1095
  }
 
1096
  *index[num]=!*index[num];
 
1097
 }
 
1098
}
 
1099
 
 
1100
#endif
 
1101
 
 
1102
#if SFX_LEVEL>=ARJ&&TARGET==UNIX
 
1103
 
 
1104
/* Disables/enables archiving for a particular block device */
 
1105
 
 
1106
static void add_blkdev_spec(char *swptr)
 
1107
{
 
1108
 int is_excl=0;
 
1109
 char *fnm;
 
1110
 
 
1111
 if(swptr[0]=='-')
 
1112
 {
 
1113
  is_excl=1;
 
1114
  swptr++;
 
1115
 }
 
1116
 else if(swptr[0]=='+')
 
1117
  swptr++;
 
1118
 fnm=(swptr[0]=='\0')?".":swptr;
 
1119
 set_dev_mode(is_excl);
 
1120
 if(add_dev(fnm))
 
1121
  msg_cprintf(H_ALERT, M_BAD_DEV_SPEC, fnm);
 
1122
}
 
1123
 
 
1124
#endif
 
1125
 
 
1126
#if SFX_LEVEL>=ARKSFXV
 
1127
 
 
1128
/* A user-friendly strtoul(). Can tell between hex and decimal notations */
 
1129
 
 
1130
unsigned long stoul(char *p, char **rp)
 
1131
{
 
1132
 unsigned int radix;
 
1133
 unsigned long rc;
 
1134
 char c;
 
1135
 
 
1136
 if(rp==NULL)
 
1137
  rp=&p;
 
1138
 if(p==NULL)
 
1139
 {
 
1140
  *rp=p;
 
1141
  return(0);
 
1142
 }
 
1143
 if(p[0]=='0'&&p[1]=='x')
 
1144
 {
 
1145
  p+=2;
 
1146
  radix=16;
 
1147
 }
 
1148
 else
 
1149
  radix=10;
 
1150
 rc=strtoul(p, rp, radix);
 
1151
 c=toupper(**rp);
 
1152
 if(c=='K')
 
1153
 {
 
1154
  *rp++;
 
1155
  rc*=1000L;
 
1156
 }
 
1157
 else if(c=='M')
 
1158
 {
 
1159
  *rp++;
 
1160
  rc*=1000000L;
 
1161
 }
 
1162
 else if(c=='G')
 
1163
 {
 
1164
  *rp++;
 
1165
  rc*=1000000000L;
 
1166
 }
 
1167
 else if(c=='T'||c=='P'||c=='E')        /* BUGBUG: Reserved */
 
1168
 {
 
1169
  *rp++;
 
1170
  rc*=0xFFFFFFFF;
 
1171
 }
 
1172
 return(rc);
 
1173
}
 
1174
 
 
1175
#endif
 
1176
 
 
1177
#if SFX_LEVEL>=ARJSFXJR
 
1178
 
 
1179
/* Sets internal variables depending on the switch given */
 
1180
 
 
1181
void analyze_arg(char *sw)
 
1182
{
 
1183
 char *swptr;
 
1184
 unsigned int c;
 
1185
 FMSG *entry;
 
1186
 int num;                               /* Switch number within the table */
 
1187
 #if SFX_LEVEL>=ARJSFXV
 
1188
  int done;
 
1189
  FMSG *table;
 
1190
  FMSG *params;
 
1191
  int **index;
 
1192
  char lim;
 
1193
  int sw_tail;
 
1194
 #endif
 
1195
 #if SFX_LEVEL>=ARJ
 
1196
  int type;
 
1197
  char vol_sw;                          /* -v... subswitch storage */
 
1198
  int p_len;
 
1199
  char *p_ptr;
 
1200
  unsigned long cnv_num;
 
1201
 #endif
 
1202
 
 
1203
 swptr=sw;
 
1204
 if(swptr[0]==swptr[1]&&swptr[2]=='\0')
 
1205
  skip_switch_processing=1;
 
1206
 else
 
1207
 {
 
1208
  swptr++;
 
1209
  #if SFX_LEVEL>=ARJ
 
1210
   hswitch=jswitch=os2switch=0;
 
1211
   if(toupper(*swptr)=='H'&&*(swptr+1)=='2')
 
1212
    swptr++;
 
1213
   if(*swptr=='2')
 
1214
   {
 
1215
    os2switch=1;
 
1216
    swptr++;
 
1217
   }
 
1218
  #endif
 
1219
  #if SFX_LEVEL>=ARJSFXV
 
1220
   done=0;
 
1221
  #endif
 
1222
  while((c=(unsigned int)*(swptr++))!='\0')
 
1223
  {
 
1224
   c=toupper(c);
 
1225
   #if SFX_LEVEL>=ARJ
 
1226
    if(jswitch)
 
1227
    {
 
1228
     table=M_JSW_TABLE;
 
1229
     params=M_JSW_PARAMS;
 
1230
     index=jsw_index;
 
1231
    }
 
1232
    else if(hswitch)
 
1233
    {
 
1234
     table=M_HSW_TABLE;
 
1235
     params=M_HSW_PARAMS;
 
1236
     index=hsw_index;
 
1237
    }
 
1238
    else if(os2switch)
 
1239
    {
 
1240
     table=M_OS2SW_TABLE;
 
1241
     params=M_OS2SW_PARAMS;
 
1242
     index=os2sw_index;
 
1243
    }
 
1244
    else
 
1245
    {
 
1246
     table=M_SW_TABLE;
 
1247
     params=M_SW_PARAMS;
 
1248
     index=sw_index;
 
1249
    }
 
1250
   #elif SFX_LEVEL>=ARJSFXV
 
1251
    table=M_SW_TABLE;
 
1252
    params=M_SW_PARAMS;
 
1253
    index=sw_index;
 
1254
   #endif
 
1255
   #if SFX_LEVEL>=ARJSFXV
 
1256
    entry=msg_strchr(table, (char)c);
 
1257
   #else
 
1258
    entry=msg_strchr(M_SW_TABLE, (char)c);
 
1259
   #endif
 
1260
   if(entry==NULL)
 
1261
   {
 
1262
    #if SFX_LEVEL>=ARJSFXV
 
1263
     error(M_INVALID_SWITCH, sw);
 
1264
    #else
 
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);
 
1269
    #endif
 
1270
   }
 
1271
   #if SFX_LEVEL>=ARJSFXV
 
1272
    num=entry-table;
 
1273
   #else
 
1274
    num=entry-M_SW_TABLE;
 
1275
   #endif
 
1276
   #if SFX_LEVEL>=ARJSFXV
 
1277
    lim=params[num];
 
1278
    sw_tail=get_switch_state(swptr);
 
1279
   #endif
 
1280
   /* ARJ parameters */
 
1281
   #if SFX_LEVEL>=ARJ
 
1282
    if(!jswitch&&!hswitch&&!os2switch&&c=='G'&&sw_tail)
 
1283
    {
 
1284
     done=1;
 
1285
     garble_enabled=1;
 
1286
     garble_password=swptr;
 
1287
    }
 
1288
    else if(!jswitch&&!hswitch&&!os2switch&&c=='E'&&sw_tail)
 
1289
    {
 
1290
     done=1;
 
1291
     left_trim=(unsigned int)stoul(swptr, &swptr);
 
1292
     exclude_paths=(left_trim==0)?EP_PATH:EP_BASEDIR;
 
1293
    }
 
1294
    else if(!jswitch&&!hswitch&&!os2switch&&c=='L'&&sw_tail)
 
1295
    {
 
1296
     done=1;
 
1297
     create_list_file=1;
 
1298
     list_file=swptr;
 
1299
    }
 
1300
    else if(!jswitch&&!hswitch&&!os2switch&&c=='O'&&sw_tail)
 
1301
    {
 
1302
     done=1;
 
1303
     if(toupper(*swptr)=='B')
 
1304
     {
 
1305
      if(*++swptr=='-')
 
1306
       filter_older=TCHECK_NOTHING;
 
1307
      else
 
1308
      {
 
1309
       filter_older=TCHECK_FTIME;
 
1310
       timestr_older=swptr;
 
1311
      }
 
1312
     }
 
1313
     else if(toupper(*swptr)=='D')
 
1314
     {
 
1315
      swptr++;
 
1316
      if(*swptr=='-')
 
1317
       filter_same_or_newer=TCHECK_NOTHING;
 
1318
      else if(toupper(*swptr)=='B')
 
1319
      {
 
1320
       filter_older=TCHECK_NDAYS;
 
1321
       swptr++;
 
1322
       timestr_older=swptr;
 
1323
      }
 
1324
      else
 
1325
      {
 
1326
       filter_same_or_newer=TCHECK_NDAYS;
 
1327
       timestr_newer=swptr;
 
1328
      }
 
1329
     }
 
1330
     else if(toupper(*swptr)=='C')
 
1331
     {
 
1332
      swptr++;
 
1333
      if(toupper(*swptr)=='B')
 
1334
      {
 
1335
       filter_older=TCHECK_CTIME;
 
1336
       swptr++;
 
1337
       timestr_older=swptr;
 
1338
      }
 
1339
      else
 
1340
      {
 
1341
       filter_same_or_newer=TCHECK_CTIME;
 
1342
       timestr_newer=swptr;
 
1343
      }
 
1344
     }
 
1345
     else if(toupper(*swptr)=='A')
 
1346
     {
 
1347
      swptr++;
 
1348
      if(toupper(*swptr)=='B')
 
1349
      {
 
1350
       filter_older=TCHECK_ATIME;
 
1351
       swptr++;
 
1352
       timestr_older=swptr;
 
1353
      }
 
1354
      else
 
1355
      {
 
1356
       filter_same_or_newer=TCHECK_ATIME;
 
1357
       timestr_newer=swptr;
 
1358
      }
 
1359
     }
 
1360
     else
 
1361
     {
 
1362
      filter_same_or_newer=TCHECK_FTIME;
 
1363
      timestr_newer=swptr;
 
1364
     }
 
1365
    }
 
1366
    else if(!jswitch&&!hswitch&&!os2switch&&c=='T'&&sw_tail)
 
1367
    {
 
1368
     done=1;
 
1369
     type_override=FT_BINARY;
 
1370
     type=(int)(*swptr-'0');
 
1371
     if(type!=ARJT_BINARY&&type!=ARJT_TEXT)
 
1372
      error(M_INVALID_SWITCH, sw);
 
1373
     swptr++;
 
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. */
 
1377
     if(type==ARJT_TEXT)
 
1378
      type_override=FT_TEXT;
 
1379
     while((c=toupper(*swptr))=='G'||c=='F')
 
1380
     {
 
1381
      if(c=='G')
 
1382
       type_override=FT_TEXT_GRAPHICS;
 
1383
      else if(c=='F'&&type_override<FT_TEXT_FORCED)
 
1384
       type_override=FT_TEXT_FORCED;
 
1385
      swptr++;
 
1386
     }
 
1387
     if(*swptr=='.')
 
1388
     {
 
1389
      swptr_t=swptr;
 
1390
      secondary_file_type=type;
 
1391
     }
 
1392
     else
 
1393
      primary_file_type=type;
 
1394
    }
 
1395
    else if(!jswitch&&!hswitch&&!os2switch&&c=='V'&&sw_tail)
 
1396
    {
 
1397
     done=1;
 
1398
     multivolume_option=MV_STD;
 
1399
     while(*swptr!='\0')
 
1400
     {
 
1401
      vol_sw=(char)toupper(*swptr);
 
1402
      if(vol_sw=='V')
 
1403
      {
 
1404
       swptr++;
 
1405
       beep_between_volumes=1;
 
1406
      }
 
1407
      else if(vol_sw=='W')
 
1408
      {
 
1409
       swptr++;
 
1410
       whole_files_in_mv=1;
 
1411
      }
 
1412
      else if(vol_sw=='A')
 
1413
      {
 
1414
       swptr++;
 
1415
       multivolume_option=MV_AVAIL;
 
1416
       volume_limit=MIN_VOLUME_SIZE;
 
1417
      }
 
1418
      else if(vol_sw=='E')
 
1419
      {
 
1420
       swptr++;
 
1421
       use_sfxstub=1;
 
1422
      }
 
1423
      else if(vol_sw=='I')
 
1424
      {
 
1425
       swptr++;
 
1426
       inhibit_change_test=1;
 
1427
      }
 
1428
      else if(vol_sw=='P')
 
1429
      {
 
1430
       swptr++;
 
1431
       pause_between_volumes=1;
 
1432
       if((change_vol_delay=(int)stoul(swptr, &swptr))==0)
 
1433
        change_vol_delay=STD_CHANGE_VOL_DELAY;
 
1434
      }
 
1435
      else if(vol_sw=='R')
 
1436
      {
 
1437
       swptr++;
 
1438
       mv_reserve_space=stoul(swptr, &swptr);
 
1439
      }
 
1440
      else if(vol_sw=='S'||vol_sw=='Z'||vol_sw=='D')
 
1441
      {
 
1442
       swptr++;
 
1443
       mv_cmd_state=MVC_RUN_CMD;
 
1444
       if(vol_sw=='Z')
 
1445
        mv_cmd_state=MVC_RUN_CMD_NOECHO;
 
1446
       else if(vol_sw=='D')
 
1447
       {
 
1448
        mv_cmd_state=MVC_DELETION;
 
1449
        if(*swptr=='\0')
 
1450
         error(M_INVALID_SWITCH, sw);
 
1451
       }
 
1452
       if(*swptr!='\0')
 
1453
       {
 
1454
        mv_cmd=swptr;
 
1455
        while(*swptr!='\0')
 
1456
         swptr++;
 
1457
       }
 
1458
      }
 
1459
      else if(isdigit(vol_sw))
 
1460
      {
 
1461
       volume_limit=stoul(swptr, &swptr);
 
1462
       break;
 
1463
      }
 
1464
      else
 
1465
       error(M_INVALID_SWITCH, sw);
 
1466
     }
 
1467
     volume_limit=select_preset_size(volume_limit);
 
1468
     mv_reserve_space=select_preset_size(mv_reserve_space);
 
1469
    }
 
1470
    else if(!jswitch&&!hswitch&&!os2switch&&c=='W'&&sw_tail)
 
1471
    {
 
1472
     done=1;
 
1473
     assign_work_directory=1;
 
1474
     work_directory=swptr;
 
1475
    }
 
1476
    else if(!jswitch&&!hswitch&&!os2switch&&c=='X'&&sw_tail)
 
1477
    {
 
1478
     if(!exclude_files)
 
1479
     {
 
1480
      flist_cleanup(&flist_exclusion);
 
1481
      flist_init(&flist_exclusion, FCLIM_EXCLUSION, FL_STANDARD);
 
1482
     }
 
1483
     done=1;
 
1484
     exclude_files=1;
 
1485
     create_excl_list(swptr);
 
1486
    }
 
1487
    else if(!jswitch&&!hswitch&&!os2switch&&c=='Z'&&sw_tail)
 
1488
    {
 
1489
     done=1;
 
1490
     use_comment=1;
 
1491
     archive_cmt_name=swptr;
 
1492
    }
 
1493
    else if(!jswitch&&!hswitch&&!os2switch&&c=='!'&&sw_tail)
 
1494
    {
 
1495
     done=1;
 
1496
     listchars_allowed=1;
 
1497
     listchar=toupper(*swptr);
 
1498
    }
 
1499
    else if(!jswitch&&!hswitch&&!os2switch&&c=='$'&&sw_tail)
 
1500
    {
 
1501
     done=1;
 
1502
     handle_labels=1;
 
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);
 
1508
    }
 
1509
    else if(!jswitch&&!hswitch&&!os2switch&&c=='+'&&sw_tail)
 
1510
     done=1;
 
1511
    else if(hswitch&&c=='B')
 
1512
    {
 
1513
     done=1;
 
1514
     filter_attrs=1;
 
1515
     parse_attrs(swptr);
 
1516
    }
 
1517
    else if(hswitch&&c=='C'&&sw_tail)
 
1518
    {
 
1519
     done=1;
 
1520
     run_cmd_at_start=1;
 
1521
     start_cmd=swptr;
 
1522
    }
 
1523
    else if(hswitch&&c=='D')
 
1524
    {
 
1525
     if(*swptr=='\0')
 
1526
      error(M_INVALID_SWITCH, sw);
 
1527
     done=1;
 
1528
     debug_enabled=1;
 
1529
     debug_opt=swptr;
 
1530
    }
 
1531
    else if(hswitch&&c=='G')
 
1532
    {
 
1533
     done=1;
 
1534
     gost_cipher=GOST256;
 
1535
     if(*swptr=='!'&&swptr[1]=='\0')
 
1536
      gost_cipher=GOST40;
 
1537
     else
 
1538
      arjcrypt_name=swptr;
 
1539
    }
 
1540
    else if(hswitch&&c=='M')
 
1541
    {
 
1542
     done=1;
 
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')
 
1548
      swptr_hm=++swptr;
 
1549
    #if TARGET==DOS
 
1550
     else if(*swptr=='!'&&swptr[1]=='\0')
 
1551
      filelist_storage=BST_XMS;
 
1552
    #endif
 
1553
    }
 
1554
    else if(hswitch&&c=='N')
 
1555
    {
 
1556
     done=1;
 
1557
     nonexist_filespec=1;
 
1558
     nonexist_name=swptr;
 
1559
    }
 
1560
    else if(hswitch&&c=='P')
 
1561
    {
 
1562
     done=1;
 
1563
     arjdisp_enabled=1;
 
1564
     arjdisp_ptr=swptr;
 
1565
    }
 
1566
    else if(hswitch&&c=='T')
 
1567
    {
 
1568
     done=1;
 
1569
     set_target_directory=1;
 
1570
     p_len=strlen(swptr);
 
1571
     p_ptr=&swptr[p_len-1];
 
1572
     while(*p_ptr==' ')
 
1573
      p_ptr--;
 
1574
     if(strchr(path_separators, *p_ptr)!=NULL)
 
1575
      target_dir=swptr;
 
1576
     else
 
1577
     {
 
1578
      strcpy(target_dir=malloc_msg(p_len+2), swptr);
 
1579
      target_dir[p_len]=PATHSEP_DEFAULT;
 
1580
      target_dir[p_len+1]='\0';
 
1581
     }
 
1582
    }
 
1583
    else if(hswitch&&c=='V')
 
1584
    {
 
1585
     done=1;
 
1586
     chk_arj_version=1;
 
1587
     swptr_hv=swptr;
 
1588
    }
 
1589
    else if(hswitch&&c=='X')
 
1590
    {
 
1591
     done=1;
 
1592
     override_archive_exts=1;
 
1593
     archive_ext_list=swptr;
 
1594
     if(swptr[0]!='.'||swptr[1]=='\0')
 
1595
      error(M_INVALID_SWITCH, sw);
 
1596
    }
 
1597
    else if(hswitch&&c=='Z')
 
1598
    {
 
1599
     done=1;
 
1600
     sign_with_arjsec=1;
 
1601
     arjsec_env_name=swptr;
 
1602
    }
 
1603
    else if(hswitch&&c=='#'&&*swptr!='\0'&&!isdigit(*swptr))
 
1604
    {
 
1605
     done=1;
 
1606
     append_curtime=1;
 
1607
     time_str=swptr;
 
1608
    }
 
1609
    else if(jswitch&&c=='C'&&sw_tail)
 
1610
    {
 
1611
     done=1;
 
1612
     exit_after_count=1;
 
1613
     exit_count=(FILE_COUNT)stoul(swptr, &swptr);
 
1614
    }
 
1615
    else if(jswitch&&c=='D'&&sw_tail)
 
1616
    {
 
1617
     done=1;
 
1618
     chk_free_space=1;
 
1619
     minfree=stoul(swptr, &swptr);
 
1620
    }
 
1621
    else if(jswitch&&c=='B'&&sw_tail)
 
1622
    {
 
1623
     done=1;
 
1624
     chapter_mode=CHAP_USE;
 
1625
     if(*swptr=='*')
 
1626
     {
 
1627
      swptr++;
 
1628
      current_chapter=1;
 
1629
      chapter_to_process=RESERVED_CHAPTER;
 
1630
     }
 
1631
     else
 
1632
     {
 
1633
      cnv_num=stoul(swptr, &swptr);
 
1634
      chapter_to_process=current_chapter=(int)cnv_num;
 
1635
      if(*swptr++=='-')
 
1636
      {
 
1637
       if(*swptr=='\0')
 
1638
        chapter_to_process=RESERVED_CHAPTER;
 
1639
       else
 
1640
       {
 
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);
 
1645
       }
 
1646
      }
 
1647
      if(current_chapter==0&&chapter_to_process==0)
 
1648
       chapter_mode=CHAP_REMOVE;
 
1649
     }
 
1650
    }
 
1651
    else if(jswitch&&c=='H'&&sw_tail)
 
1652
    {
 
1653
     done=1;
 
1654
     jh_enabled=1;
 
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)
 
1660
       cnv_num=MAX_BUFSIZ;
 
1661
     #endif
 
1662
     user_bufsiz=(unsigned int)cnv_num;
 
1663
    }
 
1664
    else if(jswitch&&c=='I'&&sw_tail)
 
1665
    {
 
1666
     done=1;
 
1667
     create_index=1;
 
1668
     index_name=swptr;
 
1669
    }
 
1670
    else if(jswitch&&c=='N'&&sw_tail)
 
1671
    {
 
1672
     done=1;
 
1673
     restart_at_filename=1;
 
1674
     filename_to_restart=swptr;
 
1675
    }
 
1676
    else if(jswitch&&c=='Q'&&sw_tail)
 
1677
    {
 
1678
     done=1;
 
1679
     set_string_parameter=1;
 
1680
     string_parameter=swptr;
 
1681
    }
 
1682
    else if(jswitch&&c=='P'&&sw_tail)
 
1683
    {
 
1684
     done=1;
 
1685
     prompt_for_more=1;
 
1686
     cnv_num=stoul(swptr, &swptr);
 
1687
     if(cnv_num>0L)
 
1688
      lines_per_page=(int)cnv_num;
 
1689
    }
 
1690
    else if(jswitch&&c=='S'&&sw_tail)
 
1691
    {
 
1692
     done=1;
 
1693
     store_by_suffix=1;
 
1694
     free(archive_suffixes);
 
1695
     archive_suffixes=swptr;
 
1696
    }
 
1697
    else if(jswitch&&c=='W'&&sw_tail)
 
1698
    {
 
1699
     done=1;
 
1700
     extract_to_file=1;
 
1701
     extraction_filename=swptr;
 
1702
    }
 
1703
    else if(jswitch&&c=='X'&&sw_tail)
 
1704
    {
 
1705
     done=1;
 
1706
     start_at_ext_pos=1;
 
1707
     ext_pos=stoul(swptr, &swptr);
 
1708
    }
 
1709
    else if(jswitch&&c=='Y'&&sw_tail)
 
1710
    {
 
1711
     done=1;
 
1712
     assume_yes=1;
 
1713
     yes_query_list=swptr;
 
1714
     parse_yes_queries(yes_query_list);
 
1715
    }
 
1716
    else if(jswitch&&c=='Z'&&sw_tail)
 
1717
    {
 
1718
     done=1;
 
1719
     supply_comment_file=1;
 
1720
     comment_file=swptr;
 
1721
    }
 
1722
#if TARGET==UNIX    
 
1723
    else if(os2switch&&c=='B')
 
1724
    {
 
1725
     done=1;
 
1726
     add_blkdev_spec(swptr);
 
1727
    }
 
1728
#endif    
 
1729
    else if(os2switch&&c=='E')
 
1730
    {
 
1731
     done=1;
 
1732
     if(!sw_tail)
 
1733
      ea_supported=0;
 
1734
     else
 
1735
     {
 
1736
      include_eas=1;
 
1737
      #if defined(HAVE_EAS)
 
1738
       flist_add_files(&flist_ea, NULL, swptr, 0, 0, 0, NULL);
 
1739
      #endif
 
1740
     }
 
1741
    }
 
1742
    else if(os2switch&&c=='I'&&sw_tail)
 
1743
    {
 
1744
     done=1;
 
1745
     start_with_seek=1;
 
1746
     arcv_ext_pos=stoul(swptr, &swptr);
 
1747
    }
 
1748
    else if(os2switch&&c=='P')
 
1749
    {
 
1750
     if(!sw_tail)
 
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)
 
1757
       priority.delta=0;
 
1758
      else
 
1759
      {
 
1760
       swptr=p_ptr+1;
 
1761
       priority.delta=stoul(swptr, &swptr);
 
1762
       #if TARGET==OS2
 
1763
        if(priority.delta<-31||priority.delta>31)
 
1764
       #elif TARGET==WIN32
 
1765
        if(priority.delta<-2||priority.delta>2)
 
1766
       #else
 
1767
        #error No priority delta limits!
 
1768
       #endif
 
1769
        error(M_INVALID_SWITCH, sw);
 
1770
      }
 
1771
     #else
 
1772
      priority.delta=0;
 
1773
     #endif
 
1774
    }
 
1775
#ifdef COLOR_OUTPUT    
 
1776
    else if(os2switch&&c=='T')
 
1777
    {
 
1778
     done=!parse_colors(swptr);
 
1779
     if(!done)
 
1780
      error(M_INVALID_SWITCH, sw);
 
1781
    }
 
1782
#endif
 
1783
    else if(os2switch&&c=='X')
 
1784
    {
 
1785
     done=1;
 
1786
     if(!sw_tail)
 
1787
      error(M_MISSING_FILENAME_ARG, "-2x");
 
1788
     else
 
1789
     {
 
1790
      exclude_eas=1;
 
1791
      #if defined(HAVE_EAS)
 
1792
       flist_add_files(&flist_xea, NULL, swptr, 0, 0, 0, NULL);
 
1793
      #endif
 
1794
     }
 
1795
    }
 
1796
    else if(*swptr=='+')
 
1797
    {
 
1798
     *index[num]=1;
 
1799
     swptr++;
 
1800
    }
 
1801
    else if(*swptr=='-')
 
1802
    {
 
1803
     *index[num]=0;
 
1804
     swptr++;
 
1805
    }
 
1806
    else if(*swptr>='0'&&*swptr<='9')
 
1807
    {
 
1808
     if(!debug_enabled||strchr(debug_opt, 's')==NULL)
 
1809
     {
 
1810
      if(*swptr>lim)
 
1811
       error(M_INVALID_SWITCH, sw);
 
1812
     }
 
1813
     *index[num]=(int)(*(swptr++)+1-'0');
 
1814
    }
 
1815
    else
 
1816
     *index[num]=!*index[num];
 
1817
   /* ARJSFXV parameters */
 
1818
   #elif SFX_LEVEL==ARJSFXV
 
1819
    if(c=='G'&&sw_tail)
 
1820
    {
 
1821
     done=1;
 
1822
     garble_enabled=1;
 
1823
     garble_password=swptr;
 
1824
    }
 
1825
    else if(c=='+'&&sw_tail)
 
1826
     done=1;
 
1827
    else if(c=='&')
 
1828
    {
 
1829
     if(*swptr=='\0')
 
1830
      error(M_INVALID_SWITCH, sw);
 
1831
     done=1;
 
1832
     debug_enabled=1;
 
1833
     debug_opt=swptr;
 
1834
    }
 
1835
    else if(c=='@')
 
1836
    {
 
1837
     done=1;
 
1838
     arjdisp_enabled=1;
 
1839
     arjdisp_ptr=swptr;
 
1840
    }
 
1841
    else if(c=='!')
 
1842
    {
 
1843
     done=1;
 
1844
     execute_extr_cmd=1;
 
1845
     extr_cmd_text=swptr;
 
1846
    }
 
1847
    else if(c=='$'&&sw_tail)
 
1848
    {
 
1849
     done=1;
 
1850
     handle_labels=1;
 
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);
 
1856
    }
 
1857
    else if(c=='W'&&sw_tail)
 
1858
    {
 
1859
     done=1;
 
1860
     extract_to_file=1;
 
1861
     extraction_filename=swptr;
 
1862
    }
 
1863
    else if(c=='D'&&sw_tail)
 
1864
    {
 
1865
     done=1;
 
1866
     chk_free_space=1;
 
1867
     minfree=stoul(swptr, &swptr);
 
1868
    }
 
1869
    else if(c=='#'&&sw_tail)
 
1870
    {
 
1871
     done=1;
 
1872
     skip_volumes=1;
 
1873
     first_volume_number=stoul(swptr, &swptr);
 
1874
    }
 
1875
    else if(c=='O'&&sw_tail)
 
1876
    {
 
1877
     done=1;
 
1878
     gost_cipher=GOST256;
 
1879
     arjcrypt_name=swptr;
 
1880
    }
 
1881
    else if(c=='Z'&&sw_tail)
 
1882
    {
 
1883
     done=1;
 
1884
     assume_yes=1;
 
1885
     yes_query_list=swptr;
 
1886
     parse_yes_queries(yes_query_list);
 
1887
    }
 
1888
    else if(*swptr=='+')
 
1889
    {
 
1890
     *index[num]=1;
 
1891
     swptr++;
 
1892
    }
 
1893
    else if(*swptr=='-')
 
1894
    {
 
1895
     *index[num]=0;
 
1896
     swptr++;
 
1897
    }
 
1898
    else if(*swptr>='0'&&*swptr<='3')
 
1899
    {
 
1900
     if(!debug_enabled||strchr(debug_opt, 's')==NULL)
 
1901
     {
 
1902
      if(*swptr>lim)
 
1903
       error(M_INVALID_SWITCH, sw);
 
1904
     }
 
1905
     *index[num]=(int)(*(swptr++)+1-'0');
 
1906
    }
 
1907
    else
 
1908
     *index[num]=!*index[num];
 
1909
   /* ARJSFX parameters */
 
1910
   #elif SFX_LEVEL==ARJSFX
 
1911
    *sw_index[num]=1;
 
1912
    if(c=='G'&&*swptr!='\0')
 
1913
    {
 
1914
     garble_password=swptr;
 
1915
     while(*swptr!='\0')
 
1916
      swptr++;
 
1917
    }
 
1918
    if(c=='!')
 
1919
    {
 
1920
     extr_cmd_text=swptr;
 
1921
     while(*swptr!='\0')
 
1922
      swptr++;
 
1923
    }
 
1924
   #endif
 
1925
   #if SFX_LEVEL>=ARJSFXV
 
1926
    if(done)
 
1927
    {
 
1928
     while(*swptr!='\0')
 
1929
      swptr++;
 
1930
    }
 
1931
   #endif
 
1932
  }
 
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)
 
1937
   quiet_mode=0;
 
1938
#endif
 
1939
 }
 
1940
}
 
1941
 
 
1942
#endif
 
1943
 
 
1944
#if SFX_LEVEL>=ARJSFXV
 
1945
 
 
1946
/* Initializes system variables with default settings prior to setup
 
1947
   procedures */
 
1948
 
 
1949
void init()
 
1950
{
 
1951
 unsigned int i;
 
1952
 
 
1953
 #if SFX_LEVEL>=ARJ
 
1954
  multivolume_option=0;
 
1955
 #else
 
1956
  multivolume_option=1;
 
1957
 #endif
 
1958
 #if SFX_LEVEL>=ARJ
 
1959
  for(i=0; i<SEARCH_STR_MAX; i++)
 
1960
   search_str[i]=NULL;
 
1961
  search_reserve=NULL;
 
1962
  reserve_size=0;
 
1963
 #endif
 
1964
 for(i=0; i<params_max; i++)
 
1965
  order[i]=0;
 
1966
 #if SFX_LEVEL>=ARJ
 
1967
  for(i=0; i<TOTAL_QUERIES; i++)
 
1968
   queries_assume_yes[i]=queries_assume_no[i]=0;
 
1969
 #endif
 
1970
 #if SFX_LEVEL>=ARJ
 
1971
  primary_file_type=ARJT_BINARY;
 
1972
 #endif
 
1973
 listchar=LISTCHAR_DEFAULT;
 
1974
 #if SFX_LEVEL>=ARJ
 
1975
  lines_per_page=query_screen_height();
 
1976
 #endif
 
1977
 listchars_allowed=1;
 
1978
 ctrlc_not_busy=1;
 
1979
 #if SFX_LEVEL>=ARJ
 
1980
  file_args=-1;
 
1981
 #else
 
1982
  file_args=0;
 
1983
 #endif
 
1984
 #if SFX_LEVEL<=ARJSFXV
 
1985
  extract_expath=0;
 
1986
  extract_cmd=0;
 
1987
  list_sfx_cmd=0;
 
1988
  verbose_list=0;
 
1989
  test_sfx_cmd=0;
 
1990
  error_occured=0;
 
1991
  licensed_sfx=0;
 
1992
  logo_shown=0;
 
1993
 #endif
 
1994
 #if SFX_LEVEL>=ARJ
 
1995
  max_filenames=EXT_FILELIST_CAPACITY;
 
1996
  ctrlc_processing=0;
 
1997
  display_totals=0;
 
1998
  lines_scrolled=0;
 
1999
 #endif
 
2000
 errors=0;
 
2001
 #if SFX_LEVEL>=ARJ
 
2002
  ts_store(&tested_ftime_newer, OS_SPECIAL, 0);
 
2003
  ts_store(&tested_ftime_older, OS_SPECIAL, 0);
 
2004
  last_hdr_offset=0L;
 
2005
  tmp_archive_used=0;
 
2006
  arch_wildcard_allowed=0;
 
2007
  file_attr_mask=TAG_FILES;
 
2008
  recursion_order=RO_LAST;
 
2009
  encryption_id=0;
 
2010
  use_ansi_cp=0;
 
2011
  filter_fa_arch=0;
 
2012
  serialize_exts=0;
 
2013
 #else
 
2014
  file_garbled=0;
 
2015
 #endif
 
2016
 allow_any_attrs=0;
 
2017
 #if SFX_LEVEL>=ARJ
 
2018
  set_target_directory=0;
 
2019
  chapter_mode=0;
 
2020
 #endif
 
2021
 install_errhdl=0;
 
2022
 #if SFX_LEVEL<=ARJSFXV
 
2023
  prompt_for_directory=0;
 
2024
 #endif
 
2025
 debug_enabled=0;
 
2026
 #if SFX_LEVEL>=ARJ
 
2027
  delete_processed=0;
 
2028
  run_cmd_at_start=0;
 
2029
  arjsec_opt=0;
 
2030
  exclude_paths=0;
 
2031
  execute_cmd=0;
 
2032
  start_at_ext_pos=0;
 
2033
  start_with_seek=0;
 
2034
  arcv_ext_pos=0;
 
2035
  subdir_extraction=0;
 
2036
  extm_mode=0;
 
2037
  override_archive_exts=0;
 
2038
  disable_comment_series=0;
 
2039
  skip_century=CENT_DEFAULT;
 
2040
  show_filenames_only=0;
 
2041
  force_lfn=0;
 
2042
  chk_free_space=0;
 
2043
  freshen_criteria=FC_NONE;
 
2044
  validate_style=0;
 
2045
  jh_enabled=0;
 
2046
  clear_archive_bit=0;
 
2047
  ignore_archive_errors=0;
 
2048
  ignore_open_errors=0;
 
2049
  detailed_index=0;
 
2050
  create_index=0;
 
2051
  keep_bak=0;
 
2052
  keep_tmp_archive=0;
 
2053
  sign_with_arjsec=0;
 
2054
  handle_labels=0;
 
2055
  listfile_err_opt=0;
 
2056
  create_list_file=0;
 
2057
  std_list_cmd=0;
 
2058
  filelist_storage=0;
 
2059
  max_compression=0;
 
2060
  custom_method=0;
 
2061
  skip_time_attrs=0;
 
2062
  indicator_style=0;
 
2063
  yes_on_all_queries=0;
 
2064
  disable_sharing=0;
 
2065
  skip_switch_processing=0;
 
2066
  no_file_activity=0;
 
2067
  new_files_only=0;
 
2068
  filter_same_or_newer=0;
 
2069
  rsp_per_line=0;
 
2070
  gost_cipher=0;
 
2071
  marksym_expansion=0;
 
2072
  fnm_matching=0;
 
2073
  arcmail_sw=0;
 
2074
  dos_host=0;
 
2075
  priority.class=priority.delta=0;
 
2076
 #endif
 
2077
 arjdisp_enabled=0;
 
2078
 #if SFX_LEVEL<=ARJSFXV
 
2079
  subdir_extraction=0;
 
2080
  execute_cmd=0;
 
2081
  show_filenames_only=0;
 
2082
  chk_free_space=0;
 
2083
  freshen_criteria=FC_NONE;
 
2084
  validate_style=VALIDATE_ALL;
 
2085
  garble_enabled=0;
 
2086
  overwrite_ro=0;
 
2087
  handle_labels=0;
 
2088
  listfile_err_opt=0;
 
2089
  std_list_cmd=0;
 
2090
  indicator_style=0;
 
2091
  yes_on_all_queries=0;
 
2092
  disable_sharing=1;
 
2093
  skip_switch_processing=0;
 
2094
  new_files_only=0;
 
2095
  fnm_matching=0;
 
2096
  execute_extr_cmd=0;
 
2097
 #endif
 
2098
 #if SFX_LEVEL>=ARJ
 
2099
  protfile_option=0;
 
2100
  query_for_each_file=0;
 
2101
  set_string_parameter=0;
 
2102
  lowercase_names=0;
 
2103
 #endif
 
2104
 ignore_crc_errors=0;
 
2105
 recurse_subdirs=0;
 
2106
 quiet_mode=0;
 
2107
 #if SFX_LEVEL<=ARJSFXV
 
2108
  skip_volumes=0;
 
2109
 #endif
 
2110
 keep_tmp_file=0;
 
2111
 print_with_more=0;
 
2112
 #if SFX_LEVEL<=ARJSFXV
 
2113
  valid_envelope=0;
 
2114
  process_lfn_archive=0;
 
2115
  skip_preset_options=0;
 
2116
 #endif
 
2117
 #if SFX_LEVEL>=ARJ
 
2118
  search_mode=0;
 
2119
  select_backup_files=0;
 
2120
  filter_attrs=0;
 
2121
  create_sfx=0;
 
2122
  lfn_mode=0;
 
2123
  comment_display=0;
 
2124
 #endif
 
2125
 skip_ts_check=0;
 
2126
 #if SFX_LEVEL>=ARJ
 
2127
  store_by_suffix=0;
 
2128
  test_archive_crc=0;
 
2129
  timestamp_override=0;
 
2130
  type_override=0;
 
2131
  translate_unix_paths=0;
 
2132
 #endif
 
2133
 update_criteria=UC_NONE;
 
2134
 #if SFX_LEVEL>=ARJ
 
2135
  verbose_display=0;
 
2136
  chk_arj_version=0;
 
2137
  beep_between_volumes=0;
 
2138
  allow_mv_update=0;
 
2139
  mv_cmd_state=0;
 
2140
  whole_files_in_mv=0;
 
2141
 #endif
 
2142
 #if SFX_LEVEL>=ARJSFXV                 /* To keep v 2.71 order */
 
2143
  use_sfxstub=0;
 
2144
 #endif
 
2145
 #if SFX_LEVEL>=ARJ
 
2146
  assign_work_directory=0;
 
2147
 #endif
 
2148
 extract_to_file=0;
 
2149
 assume_yes=0;
 
2150
 kbd_cleanup_on_input=0;
 
2151
 skip_append_query=0;
 
2152
 prompt_for_mkdir=0;
 
2153
 #if SFX_LEVEL>=ARJ
 
2154
  query_delete=0;
 
2155
 #endif
 
2156
 skip_space_query=0;
 
2157
 skip_rename_prompt=0;
 
2158
 overwrite_existing=0;
 
2159
 #if SFX_LEVEL>=ARJ
 
2160
  skip_scanned_query=0;
 
2161
 #endif
 
2162
 skip_next_vol_query=0;
 
2163
 #if SFX_LEVEL>=ARJ
 
2164
  accept_shortcut_keys=0;
 
2165
 #else
 
2166
  reg_id=0;
 
2167
  first_volume_number=0;
 
2168
 #endif
 
2169
 #if SFX_LEVEL>=ARJ
 
2170
  use_comment=0;
 
2171
  supply_comment_file=0;
 
2172
  current_chapter=0;
 
2173
  chapter_to_process=0;
 
2174
  resume_volume_num=0;
 
2175
  exit_count=0;
 
2176
  left_trim=0;
 
2177
  ext_pos=0;
 
2178
 #endif
 
2179
 label_drive=0;
 
2180
 minfree=0L;
 
2181
 #if SFX_LEVEL>=ARJ
 
2182
  volume_limit=0L;
 
2183
  mv_reserve_space=0L;
 
2184
  t_volume_offset=0L;
 
2185
 #endif
 
2186
 av_uncompressed=0L;
 
2187
 av_compressed=0L;
 
2188
 av_total_files=0;
 
2189
 av_total_longnames=0;
 
2190
 #if SFX_LEVEL>=ARJ
 
2191
  total_size=0L;
 
2192
  user_bufsiz=current_bufsiz=BUFSIZ_DEFAULT;
 
2193
  ntext=NULL;                           /* ASR fix for 2.76.06 */
 
2194
  #if TARGET==UNIX
 
2195
   sl_entries.list=l_entries.list=NULL;
 
2196
   sl_entries.total=sl_entries.alloc=l_entries.total=l_entries.alloc=0;
 
2197
  #endif
 
2198
 #endif
 
2199
 nonexist_name=nonexistent_name;
 
2200
 archive_suffixes=malloc_fmsg(M_ARCHIVE_SUFFIXES);
 
2201
 #if SFX_LEVEL>=ARJ
 
2202
  swptr_t=nullstr;
 
2203
  work_directory=nullstr;
 
2204
 #endif
 
2205
 target_dir=nullstr;
 
2206
 #if SFX_LEVEL>=ARJ
 
2207
  swptr_hm=nullstr;
 
2208
  start_cmd=nullstr;
 
2209
  cmd_to_exec=nullstr;
 
2210
  archive_ext_list=nullstr;
 
2211
  index_name=nullstr;
 
2212
 #endif
 
2213
 debug_opt=nullstr;
 
2214
 #if SFX_LEVEL>=ARJ
 
2215
  timestr_newer=nullstr;
 
2216
  timestr_older=nullstr;
 
2217
 #else
 
2218
  extr_cmd_text=nullstr;
 
2219
  garble_password=nullstr;
 
2220
 #endif
 
2221
 arjdisp_ptr=nullstr;
 
2222
 #if SFX_LEVEL>=ARJ
 
2223
  filename_to_restart=nullstr;
 
2224
  mv_cmd=nullstr;
 
2225
  arjsec_env_name=nullstr;
 
2226
  list_file=nullstr;
 
2227
  arjcrypt_name=nullstr;
 
2228
  string_parameter=nullstr;
 
2229
  swptr_hv=nullstr;
 
2230
  time_str=nullstr;
 
2231
 #endif
 
2232
 extraction_filename=nullstr;
 
2233
 yes_query_list=nullstr;
 
2234
 #if SFX_LEVEL>=ARJ
 
2235
  archive_cmt_name=nullstr;
 
2236
  comment_file=nullstr;
 
2237
 #endif
 
2238
 tmp_tmp_filename[0]='\0';
 
2239
 archive_name[0]='\0';
 
2240
 #if SFX_LEVEL<=ARJSFXV
 
2241
  aistream=NULL;
 
2242
  atstream=NULL;
 
2243
 #endif
 
2244
 file_packing=1;
 
2245
 #if SFX_LEVEL>=ARJSFXV
 
2246
  eh=NULL;
 
2247
  valid_ext_hdr=0;
 
2248
 #endif
 
2249
 #if SFX_LEVEL>=ARJ
 
2250
  include_eas=0;
 
2251
  exclude_eas=0;
 
2252
  crit_eas=0;
 
2253
  fix_longnames=0;
 
2254
  symlink_accuracy=0;
 
2255
  do_chown=0;
 
2256
  suppress_hardlinks=0;
 
2257
 #endif
 
2258
}
 
2259
 
 
2260
/* Returns 1 if the given argument is a command-line switch */
 
2261
 
 
2262
int is_switch(char *arg)
 
2263
{
 
2264
 int rc;
 
2265
 
 
2266
 if(!skip_switch_processing&&switch_char!=0&&(int)arg[0]==switch_char)
 
2267
  rc=1;
 
2268
 else if(!skip_switch_processing&&switch_char==0)
 
2269
  rc=(strchr(switch_chars, arg[0])==NULL)?0:1;
 
2270
 else
 
2271
  rc=0;
 
2272
 if(rc&&switch_char==0)
 
2273
  switch_char=(int)arg[0];
 
2274
 return(rc);
 
2275
}
 
2276
 
 
2277
#endif
 
2278
 
 
2279
#if SFX_LEVEL>=ARJ
 
2280
 
 
2281
/* Performs general command-line analysis and returns the command being
 
2282
   requested. */
 
2283
 
 
2284
int preprocess_cmdline(int argc, char *argv[])
 
2285
{
 
2286
 int i;
 
2287
 int cmd;
 
2288
 char *arg;
 
2289
 
 
2290
 cmd=0;
 
2291
 new_stdout=stdout;
 
2292
 disable_arj_sw=0;
 
2293
 skip_switch_processing=0;
 
2294
 rsp_name=nullstr;                      /* ASR fix -- 15/10/2000 (ARJ/2-32) */
 
2295
 switch_char=0;
 
2296
 install_errhdl=0;
 
2297
 quiet_mode=0;
 
2298
 use_ansi_cp=0;
 
2299
 file_garbled=0;
 
2300
 garble_enabled=0;
 
2301
 garble_password=nullstr;
 
2302
 arj_env_name=malloc_fmsg(M_ARJ_SW);
 
2303
 for(i=1; i<argc; i++)
 
2304
 {
 
2305
  arg=argv[i];
 
2306
  if(is_switch(arg))
 
2307
  {
 
2308
   if(arg[1]=='+')
 
2309
   {
 
2310
    if(arg[2]=='\0')
 
2311
     disable_arj_sw=1;
 
2312
    else
 
2313
    {
 
2314
     free_fmsg(arj_env_name);
 
2315
     arj_env_name=malloc_str(arg+2);
 
2316
    }
 
2317
   }
 
2318
   else if(arg[1]=='&'&&arg[2]=='\0')
 
2319
    install_errhdl=1;
 
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')
 
2327
   {
 
2328
    garble_enabled=1;
 
2329
    garble_password=arg+2;
 
2330
   }
 
2331
   else if(toupper(arg[1])=='H'&&toupper(arg[2])=='Y')
 
2332
   {
 
2333
    use_ansi_cp=ANSICP_CONVERT;
 
2334
    if(arg[3]=='1')
 
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;
 
2340
   }
 
2341
   else if(arg[0]==arg[1]&&arg[2]=='\0')
 
2342
    skip_switch_processing=1;
 
2343
  }
 
2344
  else
 
2345
  {
 
2346
   if(i==1&&arg[0]=='@'&&arg[1]!='\0')
 
2347
    rsp_name=arg+1;
 
2348
   else if(cmd==0&&rsp_name[0]=='\0')
 
2349
   {
 
2350
    if(!stricmp(arg, cmd_ac))
 
2351
     cmd=ARJ_CMD_ADDC;
 
2352
    else if(!stricmp(arg, cmd_cc))
 
2353
     cmd=ARJ_CMD_CNVC;
 
2354
    else if(!stricmp(arg, cmd_dc))
 
2355
     cmd=ARJ_CMD_DELC;
 
2356
    else
 
2357
     cmd=toupper(arg[0]);
 
2358
   }
 
2359
  }
 
2360
 }
 
2361
 if(cmd==ARJ_CMD_PRINT||cmd==ARJ_CMD_SAMPLE)
 
2362
  new_stdout=stderr;
 
2363
 if(install_errhdl)
 
2364
  ignore_errors=1;
 
2365
 return(cmd);
 
2366
}
 
2367
 
 
2368
#endif
 
2369
 
 
2370
#if SFX_LEVEL>=ARJSFX||defined(REARJ)
 
2371
 
 
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. */
 
2376
 
 
2377
#if SFX_LEVEL>=ARJSFXV||defined(REARJ)
 
2378
int split_name(char *name, char *pathname, char *filename)
 
2379
#else
 
2380
int split_name(char *name)
 
2381
#endif
 
2382
{
 
2383
 char *f_sep, *last_sep;
 
2384
 int i, sep_offset;
 
2385
 
 
2386
 last_sep=NULL;
 
2387
 for(i=0; path_separators[i]!='\0'; i++)
 
2388
 {
 
2389
  if((f_sep=strrchr(name, path_separators[i]))!=NULL)
 
2390
  {
 
2391
   if(last_sep==NULL||f_sep>last_sep)
 
2392
    last_sep=f_sep;
 
2393
  }
 
2394
 }
 
2395
 sep_offset=(last_sep==NULL)?0:last_sep-name+1;
 
2396
 #if SFX_LEVEL>=ARJSFXV||defined(REARJ)
 
2397
  if(pathname!=NULL)
 
2398
   strcpyn(pathname, name, sep_offset+1);
 
2399
  if(filename!=NULL)
 
2400
   strcpy(filename, name+sep_offset);
 
2401
 #endif
 
2402
 return(sep_offset);
 
2403
}
 
2404
 
 
2405
#endif
 
2406
 
 
2407
#if SFX_LEVEL>=ARJSFXV
 
2408
 
 
2409
/* Returns the error code for error message given */
 
2410
 
 
2411
int subclass_errors(FMSG *errmsg)
 
2412
{
 
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);
 
2417
 #if SFX_LEVEL>=ARJ
 
2418
  if(errmsg==M_DAMAGED_SEC_ARCHIVE||errmsg==M_CANT_UPDATE_SEC||errmsg==M_SKIPPING_SEC)
 
2419
   return(ARJ_ERL_ARJSEC_ERROR);
 
2420
 #endif
 
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);
 
2427
 #if SFX_LEVEL>=ARJ
 
2428
  #if TARGET==DOS
 
2429
   if(errmsg==M_LISTING_XMS_ERROR)
 
2430
    return(ARJ_ERL_XMS_ERROR);
 
2431
  #endif
 
2432
  if(errmsg==M_TOO_MANY_CHAPTERS)
 
2433
   return(ARJ_ERL_TOO_MANY_CHAPTERS);
 
2434
 #endif
 
2435
 if(errmsg==M_INVALID_SWITCH||errmsg==M_ARGTABLE_OVERFLOW||errmsg==M_NO_FILE_GIVEN||
 
2436
 #if SFX_LEVEL>=ARJ
 
2437
    errmsg==M_NO_DELETE_ARG||errmsg==M_INVALID_VOL_SIZE||
 
2438
    errmsg==M_NO_STR_ENTERED||errmsg==M_JT_UNUSABLE||
 
2439
 #endif
 
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);
 
2444
}
 
2445
 
 
2446
#endif
 
2447
 
 
2448
#if SFX_LEVEL>=ARJ
 
2449
 
 
2450
/* Retrieves search data from string parameter given by -jq */
 
2451
 
 
2452
static int get_str_from_jq()
 
2453
{
 
2454
 char *sptr, *tsptr;
 
2455
 char *endptr;
 
2456
 int patterns;
 
2457
 char pt;
 
2458
 
 
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);
 
2464
 patterns=0;
 
2465
 if(*sptr!='\0')
 
2466
 {
 
2467
  pt=*sptr;
 
2468
  sptr++;
 
2469
  /* Tokenize string_parameter */
 
2470
  for(tsptr=sptr; *tsptr!='\0'; tsptr++)
 
2471
   if(*tsptr==pt)
 
2472
    *tsptr='\0';
 
2473
  endptr=tsptr;
 
2474
  tsptr=sptr;
 
2475
  while((unsigned int)tsptr<(unsigned int)endptr&&patterns<SEARCH_STR_MAX)
 
2476
  {
 
2477
   while(*tsptr=='\0')
 
2478
    tsptr++;
 
2479
   if((unsigned int)tsptr<(unsigned int)endptr)
 
2480
   {
 
2481
    search_str[patterns++]=tsptr;
 
2482
    while(*tsptr!='\0'&&(unsigned int)tsptr<(unsigned int)endptr)
 
2483
     tsptr++;
 
2484
   }
 
2485
  }
 
2486
 }
 
2487
 return(patterns);
 
2488
}
 
2489
 
 
2490
#endif
 
2491
 
 
2492
#if SFX_LEVEL>=ARJSFXV
 
2493
 
 
2494
/* Performs an optimized seek operation */
 
2495
 
 
2496
void file_seek(FILE *stream, long offset, int whence)
 
2497
{
 
2498
 char *buffer;
 
2499
 
 
2500
 if(whence==SEEK_CUR&&offset>=0L&&offset<=(long)CACHE_SIZE)
 
2501
 {
 
2502
  buffer=malloc_msg(CACHE_SIZE);
 
2503
  if(offset>0L)
 
2504
   fread(buffer, 1, (int)offset, stream);
 
2505
  free(buffer);
 
2506
 }
 
2507
 else
 
2508
  fseek(stream, offset, whence);
 
2509
}
 
2510
 
 
2511
#endif
 
2512
 
 
2513
#if SFX_LEVEL>=ARJ
 
2514
 
 
2515
/* Performs a search operation set-up */
 
2516
 
 
2517
void search_setup()
 
2518
{
 
2519
 char entry[INPUT_LENGTH];
 
2520
 int patterns;
 
2521
 
 
2522
 if(set_string_parameter&&string_parameter[0]!='\0')
 
2523
  patterns=get_str_from_jq();
 
2524
 else
 
2525
 {
 
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++)
 
2532
  {
 
2533
   msg_cprintf(0, (FMSG *)le_prompt, patterns+1);
 
2534
   if(read_line(entry, sizeof(entry))<=0)
 
2535
    break;
 
2536
   search_str[patterns]=malloc_str(entry);
 
2537
  }
 
2538
 }
 
2539
 if(patterns==0)
 
2540
  error(M_NO_STR_ENTERED);
 
2541
 while(patterns-->0)
 
2542
 {
 
2543
  if(ignore_pcase)
 
2544
   strupper(search_str[patterns]);
 
2545
 }
 
2546
 if(fdisp_lines!=0)
 
2547
  indicator_style=IND_NONE;
 
2548
 reserve_size=0;
 
2549
 search_reserve=malloc_msg(sizeof(entry)*2);
 
2550
}
 
2551
 
 
2552
#endif
 
2553
 
 
2554
#if (SFX_LEVEL>=ARJSFX)||defined(ARJDISP)
 
2555
 
 
2556
/* Based on the unsigned long values given, calculates their proportion (per
 
2557
   mille, so 42.3% is returned as 423). */
 
2558
 
 
2559
int calc_percentage(unsigned long partial, unsigned long total)
 
2560
{
 
2561
 int dec;
 
2562
 
 
2563
 for(dec=0; dec<3; dec++)
 
2564
 {
 
2565
  if(partial<=0x19999999)
 
2566
   partial*=10L;
 
2567
  else
 
2568
   total/=10L;
 
2569
 }
 
2570
 if(partial+total/2<=partial)
 
2571
 {
 
2572
  partial/=2;
 
2573
  total/=2;
 
2574
 }
 
2575
 if(total==0)
 
2576
  return(0);
 
2577
 else
 
2578
  return((partial+total/2)/total);
 
2579
}
 
2580
 
 
2581
#endif
 
2582
 
 
2583
#if SFX_LEVEL>=ARJSFXV
 
2584
 
 
2585
/* Performs a "smart" seeking, depending on file type (special handling is
 
2586
   performed for text files) */
 
2587
 
 
2588
void smart_seek(unsigned long position, FILE *stream)
 
2589
{
 
2590
 char *tmp_buf;
 
2591
 int fetch_size;
 
2592
 
 
2593
 fseek(stream, 0L, SEEK_SET);
 
2594
 if(position>0L)
 
2595
 {
 
2596
  if(file_type==ARJT_BINARY)
 
2597
   fseek(stream, position, SEEK_SET);
 
2598
  else
 
2599
  {
 
2600
   tmp_buf=(char *)malloc_msg(PROC_BLOCK_SIZE);
 
2601
   while(position>0L)
 
2602
   {
 
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;
 
2607
   }
 
2608
   fseek(stream, 0L, SEEK_CUR);
 
2609
   free(tmp_buf);
 
2610
  }
 
2611
 }
 
2612
}
 
2613
 
 
2614
#endif
 
2615
 
 
2616
#if SFX_LEVEL>=ARJSFX||defined(REARJ)||defined(REGISTER)
 
2617
 
 
2618
/* This procedure trims the extra spaces and tabs at the left and right of line
 
2619
   given */
 
2620
 
 
2621
void alltrim(char *cmd)
 
2622
{
 
2623
 int fchars;
 
2624
 char *lpos;
 
2625
 
 
2626
 lpos=cmd;
 
2627
 for(fchars=strlen(cmd)-1; fchars>=0; fchars--)
 
2628
 {
 
2629
  if(cmd[fchars]!='\x09'&&cmd[fchars]!=' ')
 
2630
   break;
 
2631
 }
 
2632
 if(fchars>=0)
 
2633
 {
 
2634
  while(lpos[0]=='\x09'||lpos[0]==' ')
 
2635
  {
 
2636
   lpos++;
 
2637
   fchars--;
 
2638
  }
 
2639
  while(fchars>=0)
 
2640
  {
 
2641
   (cmd++)[0]=(lpos++)[0];
 
2642
   fchars--;
 
2643
  }
 
2644
 }
 
2645
 cmd[0]='\0';
 
2646
}
 
2647
 
 
2648
#endif
 
2649
 
 
2650
#if SFX_LEVEL>=ARJSFX
 
2651
 
 
2652
/* Extracts a stored file */
 
2653
 
 
2654
void unstore(int action)
 
2655
{
 
2656
 char *fetch;
 
2657
 #if SFX_LEVEL>=ARJSFXV
 
2658
  unsigned int fetch_size;
 
2659
  unsigned long cur_pos;
 
2660
 #endif
 
2661
 unsigned long bytes_written;
 
2662
 int count;
 
2663
 
 
2664
 #if SFX_LEVEL>=ARJSFXV
 
2665
  fetch=NULL;
 
2666
  for(fetch_size=PROC_BLOCK_SIZE; fetch_size>=512; fetch_size-=512)
 
2667
  {
 
2668
   if((fetch=(char *)malloc(fetch_size))!=NULL)
 
2669
    break;
 
2670
  }
 
2671
  if(fetch==NULL)
 
2672
   error(M_OUT_OF_MEMORY);
 
2673
  mem_stats();
 
2674
 #else
 
2675
  fetch=dec_text;
 
2676
 #endif
 
2677
 display_indicator(bytes_written=0L);
 
2678
 #if SFX_LEVEL>=ARJSFXV
 
2679
  if(file_packing)
 
2680
  {
 
2681
   cur_pos=ftell(aistream);
 
2682
   count=min(fetch_size-(cur_pos%fetch_size), compsize);
 
2683
  }
 
2684
  else
 
2685
   count=min(fetch_size, compsize);
 
2686
 #else
 
2687
  count=min(DICSIZ, compsize);
 
2688
 #endif
 
2689
 while(compsize>0L)
 
2690
 {
 
2691
  if(file_packing)
 
2692
  {
 
2693
   if(fread(fetch, 1, count, aistream)!=count)
 
2694
    error(M_CANTREAD);
 
2695
  }
 
2696
  else
 
2697
  {
 
2698
   far_memmove((char FAR *)fetch, packblock_ptr, count);
 
2699
   packblock_ptr+=count;
 
2700
   packmem_remain-=count;
 
2701
  }
 
2702
  if(file_garbled)
 
2703
   #if SFX_LEVEL>=ARJ
 
2704
    garble_decode_stub(fetch, count);
 
2705
   #else
 
2706
    garble_decode(fetch, count);
 
2707
   #endif
 
2708
  bytes_written+=(unsigned long)count;
 
2709
  display_indicator(bytes_written);
 
2710
  compsize-=(unsigned long)count;
 
2711
  if(extraction_stub(fetch, count, action))
 
2712
   break;
 
2713
  #if SFX_LEVEL>=ARJSFXV
 
2714
   count=min(fetch_size, compsize);
 
2715
  #else
 
2716
   count=min(DICSIZ, compsize);
 
2717
  #endif
 
2718
 }
 
2719
 #if SFX_LEVEL>=ARJSFXV
 
2720
  free(fetch);
 
2721
 #endif
 
2722
}
 
2723
 
 
2724
#endif
 
2725
 
 
2726
#if SFX_LEVEL>=ARJ
 
2727
 
 
2728
/* Performs a "hollow" file decoding (compares the CRC if requested to do so,
 
2729
   otherwise quits). */
 
2730
 
 
2731
void hollow_decode(int action)
 
2732
{
 
2733
 char *fetch;
 
2734
 unsigned long bytes_written;
 
2735
 unsigned long cur_pos;
 
2736
 int count;
 
2737
 
 
2738
 if(action==BOP_COMPARE)
 
2739
 {
 
2740
  fetch=(char *)malloc_msg(PROC_BLOCK_SIZE);
 
2741
  mem_stats();
 
2742
  display_indicator(bytes_written=0L);
 
2743
  cur_pos=origsize;
 
2744
  count=min(cur_pos, (unsigned long)PROC_BLOCK_SIZE);
 
2745
  while(cur_pos>0L)
 
2746
  {
 
2747
   if(fread(fetch, 1, count, tstream)!=count)
 
2748
   {
 
2749
    identical_filedata=0;
 
2750
    break;
 
2751
   }
 
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);
 
2757
  }
 
2758
  free(fetch);
 
2759
 }
 
2760
}
 
2761
 
 
2762
#endif
 
2763
 
 
2764
#if SFX_LEVEL>=ARJ
 
2765
 
 
2766
/* Packs a memory block. The destination area must be large enough to hold
 
2767
   an unpacked copy. */
 
2768
 
 
2769
void pack_mem(struct mempack *mempack)
 
2770
{
 
2771
 unsigned long s_compsize, s_origsize;
 
2772
 int s_method, s_packing;
 
2773
 int s_type;
 
2774
 unsigned long c_t;
 
2775
 
 
2776
 s_compsize=compsize;
 
2777
 s_origsize=origsize;
 
2778
 s_method=method;
 
2779
 s_packing=file_packing;
 
2780
 s_type=file_type;
 
2781
 origsize=mempack->origsize;
 
2782
 compsize=0L;
 
2783
 method=mempack->method;
 
2784
 encblock_ptr=mempack->orig;
 
2785
 packblock_ptr=mempack->comp+MEMPACK_OVERHEAD;
 
2786
 encmem_remain=mempack->origsize;
 
2787
 packmem_remain=0;
 
2788
 unpackable=0;
 
2789
 file_packing=0;
 
2790
 file_type=ARJT_BINARY;
 
2791
 if(garble_enabled)
 
2792
  garble_init(password_modifier);
 
2793
 crc32term=CRC_MASK;
 
2794
 if(method==1||method==2||method==3)
 
2795
  encode_stub(method);
 
2796
 else if(method==4)
 
2797
  encode_f_stub();
 
2798
 if(unpackable)                         /* Fall back to method #0 */
 
2799
 {
 
2800
  encblock_ptr=mempack->orig;
 
2801
  packblock_ptr=mempack->comp+MEMPACK_OVERHEAD;
 
2802
  encmem_remain=mempack->origsize;
 
2803
  method=0;
 
2804
  if(garble_enabled)
 
2805
   garble_init(password_modifier);
 
2806
  crc32term=CRC_MASK;
 
2807
 }
 
2808
 if(method==0)
 
2809
  store();
 
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;
 
2817
 file_type=s_type;
 
2818
 file_packing=s_packing;
 
2819
 compsize=s_compsize;
 
2820
 origsize=s_origsize;
 
2821
 method=s_method;
 
2822
}
 
2823
 
 
2824
#endif
 
2825
 
 
2826
#if SFX_LEVEL>=ARJSFXV
 
2827
 
 
2828
/* Unpacks a memory block. The destination area must be large enough to hold
 
2829
   an unpacked copy. */
 
2830
 
 
2831
void unpack_mem(struct mempack *mempack)
 
2832
{
 
2833
 unsigned long s_compsize, s_origsize;
 
2834
 int s_method, s_packing, s_type;
 
2835
 unsigned long c_t;
 
2836
 
 
2837
 s_type=file_type;
 
2838
 s_compsize=compsize;
 
2839
 s_origsize=origsize;
 
2840
 s_method=method;
 
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;
 
2849
 encmem_remain=0;
 
2850
 file_packing=0;
 
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) */
 
2854
 if(file_garbled)
 
2855
  garble_init(password_modifier);
 
2856
 crc32term=CRC_MASK;
 
2857
 if(method==1||method==2||method==3)
 
2858
  decode(BOP_NONE);
 
2859
 #if SFX_LEVEL>=ARJ
 
2860
 else if(method==4)
 
2861
  decode_f(BOP_NONE);
 
2862
 #endif
 
2863
 else if(method==0)
 
2864
  unstore(BOP_NONE);
 
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))
 
2870
  error(M_CRC_ERROR);
 
2871
 file_type=s_type;
 
2872
 file_packing=s_packing;
 
2873
 compsize=s_compsize;
 
2874
 origsize=s_origsize;
 
2875
 method=s_method;
 
2876
}
 
2877
 
 
2878
#endif
 
2879
 
 
2880
/* Strips ending LF character from the given string */
 
2881
 
 
2882
#if SFX_LEVEL>=ARJSFX||defined(REGISTER)||defined(REARJ)
 
2883
void strip_lf(char *str)
 
2884
{
 
2885
 int i;
 
2886
 
 
2887
 if((i=strlen(str))>0)
 
2888
 {
 
2889
  if(str[i-1]==LF)
 
2890
   str[i-1]='\0';
 
2891
 }
 
2892
}
 
2893
#endif
 
2894
 
 
2895
/* Trims leftmost spaces */
 
2896
 
 
2897
#if SFX_LEVEL>=ARJ||defined(REGISTER)||defined(REARJ)
 
2898
char *ltrim(char *str)
 
2899
{
 
2900
 char *rc;
 
2901
 
 
2902
 for(rc=str; *rc==' '; rc++);
 
2903
 return(rc);
 
2904
}
 
2905
#endif
 
2906
 
 
2907
#if defined(WORDS_BIGENDIAN)&&!defined(ARJDISP)&&!defined(REGISTER)
 
2908
/* Model-independent routine to get 2 bytes from far RAM */
 
2909
 
 
2910
unsigned int mget_word(char FAR *p)
 
2911
{
 
2912
 unsigned int b0, b1;
 
2913
 
 
2914
 b0=mget_byte(p);
 
2915
 b1=mget_byte(p+1);
 
2916
 return (b1<<8)|b0;
 
2917
}
 
2918
 
 
2919
/* Model-independent routine to get 4 bytes from far RAM */
 
2920
 
 
2921
unsigned long mget_dword(char FAR *p)
 
2922
{
 
2923
 unsigned long w0, w1;
 
2924
 
 
2925
 w0=mget_word(p);
 
2926
 w1=mget_word(p+2);
 
2927
 return (w1<<16)|w0;
 
2928
}
 
2929
 
 
2930
/* Model-independent routine to store 2 bytes in far RAM */
 
2931
 
 
2932
void mput_word(unsigned int w, char FAR *p)
 
2933
{
 
2934
 mput_byte(w&0xFF, p);
 
2935
 mput_byte(w>>8  , p+1);
 
2936
}
 
2937
 
 
2938
/* Model-independent routine to store 4 bytes in far RAM */
 
2939
 
 
2940
void mput_dword(unsigned long d, char FAR *p)
 
2941
{
 
2942
 mput_word(d&0xFFFF, p);
 
2943
 mput_word(d>>16   , p+2);
 
2944
}
 
2945
#endif