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

« back to all changes in this revision

Viewing changes to arj_file.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_file.c,v 1.9 2004/06/18 16:19:37 andrew_belov Exp $
 
3
 * ---------------------------------------------------------------------------
 
4
 * Various archive-management functions (mostly, file-related ones) are stored
 
5
 * here.
 
6
 *
 
7
 */
 
8
 
 
9
#include "arj.h"
 
10
 
 
11
DEBUGHDR(__FILE__)                      /* Debug information block */
 
12
 
 
13
/* Character used in counters */
 
14
#if TARGET!=UNIX
 
15
 #define COUNTER_CHAR           0xB2
 
16
#else
 
17
 #define COUNTER_CHAR            '#'
 
18
#endif
 
19
#define UNDISP_CHAR              '?'    /* Replaces nonprintable characters */
 
20
 
 
21
/* Local variables */
 
22
 
 
23
static char reply_help[]="?";           /* Request for help */
 
24
#if SFX_LEVEL>=ARJ
 
25
static char ext_digits[]=".%03d";       /* Pattern used to serialize
 
26
                                           extensions */
 
27
#endif
 
28
 
 
29
/* Counter formatting sequences */
 
30
 
 
31
#if SFX_LEVEL>=ARJSFXV
 
32
static char del_single[]="\b\b\b\b\b";
 
33
static char del_double[]="\b\b\b\b\b\b\b\b\b\b";
 
34
static char sfmt_single[]="     %s";
 
35
static char sfmt_double[]="          %s";
 
36
static char sfmt_bytes[]="%10ld%s";
 
37
static char sfmt_start_graph[]="   0%%%s";
 
38
static char sfmt_numeric[]="%4d%%%s";
 
39
#if SFX_LEVEL>=ARJ
 
40
static char sfmt_start_num[]="   %d%%";
 
41
#if TARGET!=UNIX
 
42
static char sfmt_graph[]="����������%s";
 
43
static char sfmt_mid_graph[]="�����%s";
 
44
#else
 
45
static char sfmt_graph[]="..........%s";
 
46
static char sfmt_mid_graph[]=".....%s";
 
47
#endif
 
48
static char sfmt_short_numeric[]="%4d%%";
 
49
#endif
 
50
#else
 
51
static char sfmt_sfx[]="%4d%%\b\b\b\b\b";
 
52
#endif
 
53
 
 
54
/* Local forward-referenced functions */
 
55
 
 
56
static int display_block(char *str, int len);
 
57
static int block_op(int action, char *block, int len);
 
58
 
 
59
#if SFX_LEVEL>=ARJSFXV
 
60
 
 
61
/* Closes the file given */
 
62
 
 
63
int file_close(FILE *stream)
 
64
{
 
65
 if(stream!=NULL)
 
66
  return(fclose(stream));
 
67
 else
 
68
  return(-1);
 
69
}
 
70
 
 
71
/* Opens a file, possibly clearing its FA_ARCH attribute (read-only modes are
 
72
   not affected) */
 
73
 
 
74
FILE *file_open_noarch(char *name, char *mode)
 
75
{
 
76
 FILE *stream;
 
77
 
 
78
#if TARGET!=UNIX
 
79
 if(clear_archive_bit&&(mode[0]=='w'||mode[0]=='a'||mode[1]=='+'||mode[2]=='+'))
 
80
  dos_chmod(name, STD_FATTR_NOARCH);
 
81
#endif
 
82
 if((stream=file_open(name, mode))==NULL)
 
83
  error(M_CANTOPEN, name);
 
84
 return(stream);
 
85
}
 
86
 
 
87
#endif
 
88
 
 
89
#if SFX_LEVEL>=ARJ
 
90
 
 
91
/* Overwrites a file, querying user if it exists */
 
92
 
 
93
FILE *file_create(char *name, char *mode)
 
94
{
 
95
 if(file_exists(name))
 
96
 {
 
97
  if(!yes_on_all_queries&&!overwrite_existing)
 
98
  {
 
99
   msg_cprintf(0, M_EXISTS, name);
 
100
   if(!query_action(REPLY_YES, QUERY_OVERWRITE, M_QUERY_OVERWRITE))
 
101
    error(M_CANTOPEN, name);
 
102
  }
 
103
#if TARGET!=UNIX
 
104
  if(clear_archive_bit&&(mode[0]=='w'||mode[0]=='a'||mode[1]=='+'||mode[2]=='+'))
 
105
   dos_chmod(name, STD_FATTR_NOARCH);
 
106
#endif
 
107
 }
 
108
 return(file_open(name, mode));
 
109
}
 
110
 
 
111
#endif
 
112
 
 
113
#ifndef REARJ
 
114
 
 
115
/* Reads a byte from the file */
 
116
 
 
117
int fget_byte(FILE *stream)
 
118
{
 
119
 int buffer;
 
120
 
 
121
 buffer=fgetc(stream);
 
122
 if(buffer==EOF)
 
123
 {
 
124
  if(ignore_archive_errors)
 
125
  {
 
126
   #if SFX_LEVEL>=ARJSFXV
 
127
    msg_cprintf(H_ERR, M_CANTREAD);
 
128
   #else
 
129
    msg_cprintf(H_ERR, M_CANTREAD);
 
130
   #endif
 
131
   return(0);
 
132
  }
 
133
  else
 
134
   error(M_CANTREAD);
 
135
 }
 
136
 return(buffer&0xFF);
 
137
}
 
138
 
 
139
/* Reads two bytes from the file */
 
140
 
 
141
unsigned int fget_word(FILE *stream)
 
142
{
 
143
 unsigned int b0, b1;
 
144
 
 
145
 b0=fget_byte(stream);
 
146
 b1=fget_byte(stream);
 
147
 return((b1<<8)|b0);
 
148
}
 
149
 
 
150
/* Reads four bytes from the file */
 
151
 
 
152
unsigned long fget_longword(FILE *stream)
 
153
{
 
154
 unsigned int w0, w1;
 
155
 
 
156
 w0=fget_word(stream);
 
157
 w1=fget_word(stream);
 
158
 return(((unsigned long)w1<<16)|(unsigned long)w0);
 
159
}
 
160
 
 
161
/* Reads a block from the file, updating CRC */
 
162
 
 
163
int fread_crc(char *buffer, int count, FILE *stream)
 
164
{
 
165
 int n;
 
166
 
 
167
 n=fread(buffer, 1, count, stream);
 
168
 if(n>0)
 
169
 {
 
170
  origsize+=(unsigned long)n;
 
171
  crc_for_block((char *)buffer, n);
 
172
 }
 
173
 return(n);
 
174
}
 
175
 
 
176
#endif
 
177
 
 
178
#if SFX_LEVEL>=ARJ
 
179
 
 
180
/* Writes a block, updating the CRC term */
 
181
 
 
182
void fwrite_crc(char *buffer, int count, FILE *stream)
 
183
{
 
184
 crc_for_block(buffer, count);
 
185
 if(stream!=NULL)
 
186
  file_write(buffer, 1, count, stream);
 
187
}
 
188
 
 
189
#endif
 
190
 
 
191
#ifndef REARJ
 
192
 
 
193
/* Processes the given block upon extraction. Returns a nonzero value if the
 
194
   extraction is to be terminated. */
 
195
 
 
196
int extraction_stub(char *block, int block_len, int action)
 
197
{
 
198
 char c;
 
199
 char *block_ptr;
 
200
 int cn;
 
201
 
 
202
 #if SFX_LEVEL>=ARJ
 
203
  if(!debug_enabled||strchr(debug_opt, 'c')==NULL)
 
204
   crc_for_block(block, block_len);
 
205
 #else
 
206
  crc32_for_block(block, block_len);
 
207
 #endif
 
208
 if(!file_packing)                      /* Not applicable for memory data */
 
209
 {
 
210
  if(encmem_limit<block_len)            /* Check for overrun */
 
211
   error(M_BAD_HEADER);
 
212
  encmem_limit-=block_len;
 
213
  far_memmove(encblock_ptr, (char FAR *)block, block_len);
 
214
  encblock_ptr+=block_len;
 
215
  encmem_remain+=block_len;
 
216
  return(0);
 
217
 }
 
218
 /* Postprocessing */
 
219
 #if SFX_LEVEL>=ARJ
 
220
  if(action==BOP_LIST||action==BOP_SEARCH||action==BOP_COMPARE||action==BOP_DISPLAY)
 
221
   return(block_op(action, block, block_len));
 
222
 #endif
 
223
 if(atstream==NULL)
 
224
  return(0);
 
225
 /* Strip high bit from files created by different OS */
 
226
 if(file_type==ARJT_TEXT&&host_os!=OS
 
227
 #if SFX_LEVEL>=ARJ
 
228
  &&type_override!=FT_BINARY
 
229
 #endif
 
230
 )
 
231
 {
 
232
  block_ptr=block;
 
233
  while(block_len-->0)
 
234
  {
 
235
   c=*(block_ptr++);
 
236
   c&=0x7F;
 
237
   if(fputc((int)c, atstream)==EOF)
 
238
    error(M_DISK_FULL);
 
239
  }
 
240
 }
 
241
 else
 
242
 {
 
243
  /* HACK for IBM LIBC implementations under 32-bit OS/2 */
 
244
  #if SFX_LEVEL>=ARJSFXV&&TARGET==OS2&&(COMPILER==ICC||defined(LIBC))
 
245
   int fn=fileno(atstream);
 
246
 
 
247
   if(fn<6)
 
248
   {
 
249
    _setmode(fn, file_type?0x4000:0x8000); /* O_TEXT:O_BINARY */
 
250
    cn=write(fn, block, block_len);
 
251
   }
 
252
   else
 
253
    cn=fwrite(block, 1, block_len, atstream);
 
254
  #else
 
255
   cn=fwrite(block, 1, block_len, atstream);
 
256
  #endif
 
257
  #if SFX_LEVEL>=ARJSFXV
 
258
   if(is_tty(atstream))
 
259
    cn=block_len;
 
260
  #endif
 
261
  if(cn!=block_len)
 
262
   error(M_DISK_FULL);
 
263
 }
 
264
 return(0);
 
265
}
 
266
 
 
267
/* Executed when decoding is initialized */
 
268
 
 
269
void decode_start_stub()
 
270
{
 
271
 #if SFX_LEVEL>=ARJ
 
272
  subbitbuf=0;
 
273
 #endif
 
274
 bitbuf=0;
 
275
 byte_buf=0;
 
276
 bitcount=0;
 
277
 fillbuf(CHAR_BIT*2);
 
278
 #if SFX_LEVEL>=ARJSFXV
 
279
  mem_stats();
 
280
 #endif
 
281
}
 
282
 
 
283
#endif
 
284
 
 
285
#if SFX_LEVEL>=ARJSFXV
 
286
 
 
287
/* Executed when the decoding memory variables are released */
 
288
 
 
289
void decode_end_stub()
 
290
{
 
291
 /* Currently empty, may contain debugging checks if needed. */
 
292
}
 
293
 
 
294
#endif
 
295
 
 
296
#if SFX_LEVEL>=ARJ
 
297
 
 
298
/* Finds an non-existent filename that matches the given format string. The
 
299
   format string must contain "%d" somewhere because the names are numbered. */
 
300
 
 
301
char *find_tmp_filename(char *name_format)
 
302
{
 
303
 char tmp_name[CCHMAXPATH];
 
304
 int i;
 
305
 
 
306
 for(i=0; i<=99; i++)
 
307
 {
 
308
  sprintf(tmp_name, name_format, i);
 
309
  if(!file_exists(tmp_name))
 
310
   return(strcpy(name_format, tmp_name));
 
311
 }
 
312
 error(M_CANTOPEN, name_format);
 
313
 return(0); /* not reached, avoid warning */
 
314
}
 
315
 
 
316
/* Creates an numeric extension to the name, returns -1 if failed */
 
317
 
 
318
int find_num_ext(char *name, int mode)
 
319
{
 
320
 char tmp_name[CCHMAXPATHCOMP];
 
321
 char tmp_ext[CCHMAXPATHCOMP];
 
322
 int name_offset;
 
323
 char *ext_offset;
 
324
 int ext_num;
 
325
 
 
326
 strcpy(tmp_name, name);
 
327
 name_offset=split_name(tmp_name, NULL, NULL);
 
328
 if((ext_offset=strchr(&tmp_name[name_offset], '.'))==NULL)
 
329
  strcat(tmp_name, ext_digits);
 
330
 else
 
331
 {
 
332
  strcpy(tmp_ext, ext_offset);          /* Remember the original extension */
 
333
  strcpy(ext_offset, ext_digits);       /* Substitute extension */
 
334
  if(mode==EXT_INSERT)
 
335
   strcat(tmp_name, tmp_ext);           /* Complete with original extension */
 
336
 }
 
337
 for(ext_num=0; ext_num<999; ext_num++)
 
338
 {
 
339
  sprintf(name, tmp_name, ext_num);
 
340
  if(!file_exists(name))
 
341
   return(0);
 
342
 }
 
343
 msg_cprintf(0, M_EXISTS, name);
 
344
 return(-1);
 
345
}
 
346
 
 
347
/* Treats filename as an ARCmail packet and finds a suitable name for it */
 
348
 
 
349
int find_arcmail_name(char *name)
 
350
{
 
351
 unsigned long counter;
 
352
 char *nptr;
 
353
 char c;
 
354
 
 
355
 for(counter=0L; counter<100000000L; counter++)
 
356
 {
 
357
  if((nptr=strchr(name+1, '.'))==NULL)
 
358
   nptr=name+strlen(name);
 
359
  nptr--;
 
360
  do
 
361
  {
 
362
   c=*nptr;
 
363
   if(!isdigit(c))
 
364
    c='0';
 
365
   else
 
366
    c++;
 
367
   if(c>'9')
 
368
   {
 
369
    *nptr='0';
 
370
    if(nptr==name)
 
371
    {
 
372
     msg_cprintf(0, M_RANGE_EXCEEDED, name);
 
373
     return(-1);
 
374
    }
 
375
    nptr--;
 
376
   }
 
377
   else
 
378
    *nptr=c;
 
379
  } while(c>'9');
 
380
  if(!file_exists(name))
 
381
   return(0);
 
382
 }
 
383
 msg_cprintf(0, M_EXISTS, name);
 
384
 return(-1);
 
385
}
 
386
 
 
387
#endif
 
388
 
 
389
#if SFX_LEVEL>=ARJSFXV
 
390
 
 
391
/* Puts the given character to the console */
 
392
 
 
393
static int nputc(int c)
 
394
{
 
395
 msg_cprintf(0, (FMSG *)"%c", c);
 
396
 return(c);
 
397
}
 
398
 
 
399
#endif
 
400
 
 
401
#if SFX_LEVEL>=ARJ
 
402
 
 
403
/* Reads a command for execution from the stdin */
 
404
 
 
405
void query_cmd()
 
406
{
 
407
 char cmd[CMDLINE_LENGTH];
 
408
 
 
409
 msg_cprintf(0, M_COMMAND);
 
410
 read_line(cmd, sizeof(cmd));
 
411
 alltrim(cmd);
 
412
 if(cmd[0]!='\0')
 
413
  exec_cmd(cmd);
 
414
}
 
415
 
 
416
#endif
 
417
 
 
418
/* Compares the first n characters of two MSG-strings (used exclusively by
 
419
   query_action_proc()) */
 
420
 
 
421
#if SFX_LEVEL>=ARJ
 
422
 
 
423
static int cmp_far_str(char FAR *str1, char FAR *str2, int length)
 
424
{
 
425
 int result;
 
426
 char *nstr1, *nstr2;
 
427
 
 
428
 nstr1=malloc_far_str(str1);
 
429
 nstr2=malloc_far_str(str2);
 
430
 result=strncmp(nstr1, nstr2, length);
 
431
 free(nstr1);
 
432
 free(nstr2);
 
433
 return(result);
 
434
}
 
435
 
 
436
#define msg_strncmp(str1, str2, length) cmp_far_str((char FAR *)str1, (char FAR *)str2, length)
 
437
 
 
438
#else
 
439
 #define msg_strncmp strncmp
 
440
#endif
 
441
 
 
442
/* Query routine - used exclusively by query_action() */
 
443
 
 
444
#if SFX_LEVEL>=ARJSFXV
 
445
 
 
446
static int query_action_proc(int def, int qtype, char *query)
 
447
{
 
448
 char reply_text[INPUT_LENGTH];
 
449
 int sel, key, ukey;
 
450
 char *sel_ptr, *rt_ptr;
 
451
 int rt_len;
 
452
 
 
453
 if(query!=NULL)
 
454
  msg_cprintf(H_PROMPT, (FMSG *)strform, query);
 
455
 #if SFX_LEVEL>=ARJ
 
456
  if(qtype!=QUERY_CRITICAL&&queries_assume_no[qtype])
 
457
  {
 
458
   msg_cprintf(H_OPER, M_NO);
 
459
   msg_cprintf(0, (FMSG *)lf);
 
460
   return(0);
 
461
  }
 
462
  if(qtype!=QUERY_CRITICAL&&queries_assume_yes[qtype])
 
463
  {
 
464
   msg_cprintf(H_OPER, M_YES);
 
465
   msg_cprintf(0, (FMSG *)lf);
 
466
   return(1);
 
467
  }
 
468
 #endif
 
469
 if(kbd_cleanup_on_input)
 
470
  fetch_keystrokes();
 
471
 #if SFX_LEVEL>=ARJ
 
472
  if(accept_shortcut_keys)
 
473
  {
 
474
   while(1)
 
475
   {
 
476
    do
 
477
    {
 
478
     while(1)
 
479
     {
 
480
      key=uni_getch();
 
481
      /* If possible default action selected */
 
482
      if(def!=0&&key==LF)
 
483
      {
 
484
       msg_cprintf(0, (FMSG *)lf);
 
485
       if(def==1)
 
486
        return(1);
 
487
       if(def==2)
 
488
        return(0);
 
489
      }
 
490
      ukey=toupper(key);
 
491
      far_strcpy(strcpy_buf, M_REPLIES);
 
492
      sel_ptr=strchr(strcpy_buf, ukey);
 
493
      sel=sel_ptr-strcpy_buf;
 
494
      if(ukey!=0&&sel_ptr!=NULL&&(qtype!=QUERY_CRITICAL||sel<=REPLY_QUIT))
 
495
       break;
 
496
      fetch_keystrokes();
 
497
      nputc(BEL);
 
498
     }
 
499
     nputc(key);
 
500
     msg_cprintf(0, (FMSG *)lf);
 
501
    } while(sel>MAX_REPLY);
 
502
    switch(sel)
 
503
    {
 
504
     case REPLY_YES:
 
505
      return(1);
 
506
     case REPLY_NO:
 
507
      return(0);
 
508
     case REPLY_QUIT:
 
509
      exit(ARJ_ERL_WARNING);
 
510
     case REPLY_ALL:
 
511
      if(qtype!=QUERY_CRITICAL)
 
512
       queries_assume_yes[qtype]=1;
 
513
      return(1);
 
514
     case REPLY_SKIP:
 
515
      if(qtype!=QUERY_CRITICAL)
 
516
       queries_assume_no[qtype]=1;
 
517
      return(0);
 
518
     case REPLY_GLOBAL:
 
519
      yes_on_all_queries=1;
 
520
      return(1);
 
521
     case REPLY_COMMAND:
 
522
      query_cmd();
 
523
      if(query!=NULL)
 
524
       msg_cprintf(H_PROMPT, (FMSG *)strform, query);
 
525
    }
 
526
   }
 
527
   /* There is no way down here */
 
528
  }
 
529
 #endif
 
530
 /* Use an editable field */
 
531
 while(1)
 
532
 {
 
533
  read_line(reply_text, INPUT_LENGTH);
 
534
  for(rt_ptr=reply_text; rt_ptr[0]==' '; rt_ptr++);
 
535
  if((rt_len=strlen(rt_ptr))>0)
 
536
  {
 
537
   strupper(rt_ptr);
 
538
   if(!msg_strncmp(rt_ptr, reply_help, rt_len))
 
539
   {
 
540
    far_strcpy(strcpy_buf, (qtype==QUERY_CRITICAL)?M_REPLIES_HELP:M_ALL_REPLIES_HELP);
 
541
    msg_cprintf(0, (FMSG *)strcpy_buf);
 
542
    continue;
 
543
   }
 
544
   else if(!msg_strncmp(rt_ptr, M_NO, rt_len))
 
545
    return(0);
 
546
   else if(!msg_strncmp(rt_ptr, M_YES, rt_len))
 
547
    return(1);
 
548
   else if(!msg_strncmp(rt_ptr, M_QUIT, rt_len))
 
549
    exit(1);
 
550
   else if(qtype!=QUERY_CRITICAL)
 
551
   {
 
552
    #if SFX_LEVEL>=ARJ
 
553
     if(!msg_strncmp(rt_ptr, M_ALWAYS, rt_len))
 
554
     {
 
555
      if(qtype!=QUERY_CRITICAL)
 
556
       queries_assume_yes[qtype]=1;
 
557
      return(1);
 
558
     }
 
559
     if(!msg_strncmp(rt_ptr, M_SKIP, rt_len))
 
560
     {
 
561
      if(qtype!=QUERY_CRITICAL)
 
562
       queries_assume_no[qtype]=1;
 
563
      return(0);
 
564
     }
 
565
    #endif
 
566
    if(!msg_strncmp(rt_ptr, M_GLOBAL, rt_len))
 
567
    {
 
568
     yes_on_all_queries=1;
 
569
     return(1);
 
570
    }
 
571
    #if SFX_LEVEL>=ARJ
 
572
     if(!msg_strncmp(rt_ptr, M_COMMAND, rt_len))
 
573
     {
 
574
      query_cmd();
 
575
      if(query!=NULL)
 
576
       msg_cprintf(H_PROMPT, (FMSG *)strform, query);
 
577
      continue;
 
578
     }
 
579
    #endif
 
580
   }
 
581
  }
 
582
  else
 
583
  {
 
584
   if(def==1)
 
585
    return(1);
 
586
   if(def==2)
 
587
    return(0);
 
588
  }
 
589
  fetch_keystrokes();
 
590
  nputc(BEL);
 
591
  msg_cprintf(0, M_REPLIES_HELP);
 
592
 }
 
593
}
 
594
 
 
595
#else
 
596
 
 
597
int query_action()
 
598
{
 
599
 #ifndef REARJ
 
600
  char buf[40];
 
601
 #else
 
602
  char buf[80];
 
603
 #endif
 
604
 char *buf_ptr;
 
605
 int sl, rc;
 
606
 char *fmsg_ptr;
 
607
 
 
608
 while(1)
 
609
 {
 
610
  read_line(buf, sizeof(buf));
 
611
  buf_ptr=buf;
 
612
  while(*buf_ptr==' ')
 
613
   buf_ptr++;
 
614
  if((sl=strlen(buf_ptr))!=0)
 
615
  {
 
616
   strupper(buf_ptr);
 
617
   fmsg_ptr=malloc_fmsg(M_NO);
 
618
   rc=strncmp(buf_ptr, fmsg_ptr, sl);
 
619
   free_fmsg(fmsg_ptr);
 
620
   if(!rc)
 
621
    return(0);
 
622
   fmsg_ptr=malloc_fmsg(M_YES);
 
623
   rc=strncmp(buf_ptr, fmsg_ptr, sl);
 
624
   free_fmsg(fmsg_ptr);
 
625
   if(!rc)
 
626
    return(1);
 
627
   #ifndef REARJ
 
628
    fmsg_ptr=malloc_fmsg(M_QUIT);
 
629
    rc=strncmp(buf_ptr, fmsg_ptr, sl);
 
630
    free_fmsg(fmsg_ptr);
 
631
    if(!rc)
 
632
     exit(ARJSFX_ERL_ERROR);
 
633
   #endif
 
634
  }
 
635
  msg_cprintf(0, M_REPLIES_HELP);
 
636
 }
 
637
}
 
638
 
 
639
#endif
 
640
 
 
641
#if SFX_LEVEL>=ARJSFXV
 
642
 
 
643
/* Standard procedure that queries user. Accepts the following parameters:
 
644
   - def=0 if no default action, or number of reply to be selected w/ENTER.
 
645
   - qtype is the standard query number to allow pre-selections.
 
646
   - query is the query text. */
 
647
 
 
648
int query_action(int def, int qtype, FMSG *query)
 
649
{
 
650
 #if SFX_LEVEL>=ARJ
 
651
  char *nquery;
 
652
  int result;
 
653
  FILE *tmp_stdout;
 
654
 
 
655
  if((tmp_stdout=new_stdout)==new_stderr)
 
656
   new_stdout=stderr;
 
657
  result=query_action_proc(def, qtype, nquery=malloc_fmsg(query));
 
658
  free(nquery);
 
659
  new_stdout=tmp_stdout;
 
660
  return(result);
 
661
 #else
 
662
  return(query_action_proc(def, qtype, query));
 
663
 #endif
 
664
}
 
665
 
 
666
/* Prompts the user to press ENTER */
 
667
 
 
668
int pause()
 
669
{
 
670
 char *tmp_query;
 
671
 FILE *tmp_stdout;
 
672
 int rc;
 
673
 
 
674
 if((tmp_stdout=new_stdout)==new_stderr)
 
675
  new_stdout=stderr;
 
676
 tmp_query=malloc_fmsg(M_PRESS_ENTER);
 
677
 rc=query_action_proc(1, QUERY_PRESS_ENTER, tmp_query);
 
678
 new_stdout=tmp_stdout;
 
679
 free(tmp_query);
 
680
 return(rc);
 
681
}
 
682
 
 
683
/* Puts a LF character to the stdout */
 
684
 
 
685
void nputlf()
 
686
{
 
687
 msg_cprintf(0, (FMSG *)lf);
 
688
}
 
689
 
 
690
#endif
 
691
 
 
692
#if SFX_LEVEL>=ARJ
 
693
 
 
694
/* Deletes files specified by the given wildcard. Returns 1 if no files were
 
695
   found to delete. */
 
696
 
 
697
int delete_files(char *name)
 
698
{
 
699
 char tmp_name[CCHMAXPATHCOMP];
 
700
 struct flist_root root;
 
701
 FILE_COUNT curfile;
 
702
 
 
703
 flist_init(&root, FCLIM_DELETION, FL_STANDARD);
 
704
 if(flist_add_files(&root, NULL, name, 1, 0, FETCH_FILES, NULL))
 
705
  return(1);
 
706
 for(curfile=0; curfile<root.files; curfile++)
 
707
 {
 
708
  flist_retrieve(tmp_name, NULL, &root, curfile);
 
709
  msg_cprintf(0, M_DELETING, tmp_name);
 
710
  if(is_directory(tmp_name)?file_rmdir(tmp_name):file_unlink(tmp_name))
 
711
   msg_cprintf(H_ERR, M_CANT_DELETE, tmp_name);
 
712
 }
 
713
 flist_cleanup(&root);
 
714
 return(0);
 
715
}
 
716
 
 
717
#endif
 
718
 
 
719
#ifndef REARJ
 
720
 
 
721
/* Displays the given comment string */
 
722
 
 
723
#if SFX_LEVEL>=ARJSFXV
 
724
void display_comment(char FAR *cmt)
 
725
#else
 
726
void display_comment(char *cmt)
 
727
#endif
 
728
{
 
729
 unsigned char c;
 
730
 #if SFX_LEVEL>=ARJSFXV
 
731
  int is_ansi=0;
 
732
 #endif
 
733
 #if TARGET==OS2
 
734
  USHORT af;
 
735
 #endif
 
736
 
 
737
 #if SFX_LEVEL>=ARJ
 
738
  if(new_stderr==new_stdout)
 
739
   return;
 
740
 #endif
 
741
 #if TARGET==OS2
 
742
  fflush(stdout);
 
743
  VioGetAnsi(&af, 0);
 
744
  VioSetAnsi(ANSI_ON, 0);
 
745
 #endif
 
746
 while((c=*(cmt++))!='\0')
 
747
 {
 
748
  #if SFX_LEVEL>=ARJSFXV
 
749
   if(c==ANSI_ESC)
 
750
    is_ansi=1;
 
751
  #endif
 
752
 #if SFX_LEVEL>=ARJSFXV&&!defined(DIRECT_TO_ANSI)
 
753
  if(is_ansi)
 
754
  {
 
755
   display_ansi(c);
 
756
   if(c==LF)
 
757
    display_ansi(CR);
 
758
  }
 
759
  else
 
760
  {
 
761
 #endif
 
762
   /* Substitute non-printable control characters with "?"'s */
 
763
   #ifndef DIRECT_TO_ANSI
 
764
    if(c<' '&&c!=TAB&&c!=LF&&c!=CR)
 
765
     c=UNDISP_CHAR;
 
766
   #endif
 
767
   #if SFX_LEVEL>=ARJSFXV
 
768
    nputc((int)c);
 
769
   #else
 
770
    fputc((int)c, stdout);
 
771
   #endif
 
772
   #if SFX_LEVEL>=ARJ
 
773
    if(c==LF)
 
774
    {
 
775
     lines_scrolled++;
 
776
     if(lines_scrolled>=lines_per_page-1)
 
777
     {
 
778
      lines_scrolled=0;
 
779
      if(!yes_on_all_queries&&prompt_for_more&&is_tty(stdout))
 
780
      {
 
781
       if(!pause())
 
782
        return;
 
783
      }
 
784
     }
 
785
    }
 
786
   #endif
 
787
 #if SFX_LEVEL>=ARJSFXV&&!defined(DIRECT_TO_ANSI)
 
788
  }
 
789
 #endif
 
790
 }
 
791
 #if SFX_LEVEL>=ARJSFXV
 
792
  if(is_ansi)
 
793
  {
 
794
   #ifdef DIRECT_TO_ANSI
 
795
    printf("\x1B[0m\n");
 
796
   #else
 
797
    display_ansi(LF);
 
798
   #endif
 
799
  }
 
800
 #endif
 
801
 #if TARGET==OS2
 
802
  VioSetAnsi(af, 0);
 
803
 #endif
 
804
}
 
805
 
 
806
#if SFX_LEVEL>=ARJ
 
807
 
 
808
/* Puts repeatable character to stdout */
 
809
 
 
810
static char *nputnc(char *dest, int c, int count)
 
811
{
 
812
 while(count-->0)
 
813
  *(dest++)=c;
 
814
 return(dest);
 
815
}
 
816
 
 
817
#endif
 
818
 
 
819
/* Displays progress indicator */
 
820
 
 
821
void display_indicator(long bytes)
 
822
{
 
823
 int pct;
 
824
 char ind[64];
 
825
 char *p;
 
826
 /* Indicator width */
 
827
 static unsigned char ind_sizes[]={5, 0, 11, 5, 8, 11, 11};
 
828
 #if SFX_LEVEL>=ARJ
 
829
  static int prev_pct=0;
 
830
 #endif
 
831
 
 
832
 if(!file_packing)
 
833
  return;
 
834
 p=ind;
 
835
 if(arjdisp_enabled)
 
836
  arjdisp_scrn((unsigned long)bytes);
 
837
 /* Different conditions for ARJ and ARJSFX! */
 
838
 #if SFX_LEVEL>=ARJ
 
839
 else if(indicator_style!=IND_NONE)
 
840
 {
 
841
  check_wrap(ind_sizes[indicator_style]);
 
842
  if(uncompsize<0L)
 
843
  {
 
844
   if(bytes==0L)
 
845
    p+=sprintf(p, sfmt_double, del_double);
 
846
   p+=sprintf(p, sfmt_bytes, bytes, del_double);
 
847
  }
 
848
  else
 
849
  {
 
850
   if(indicator_style==IND_NORMAL||indicator_style==IND_TOTAL_PCT)
 
851
   {
 
852
    if(bytes==0L)
 
853
    {
 
854
     p+=sprintf(p, sfmt_single, del_single);
 
855
     p+=sprintf(p, sfmt_start_graph, del_single);
 
856
    }
 
857
    else
 
858
    {
 
859
     if(total_size!=0&&display_totals&&indicator_style==IND_TOTAL_PCT)
 
860
      pct=calc_percentage(total_written+bytes, total_size);
 
861
     else
 
862
      pct=calc_percentage(bytes, uncompsize);
 
863
     if(pct==prev_pct&&CHECK_SENTRY())
 
864
      return;
 
865
     p+=sprintf(p, sfmt_numeric, pct/10, del_single);
 
866
    }
 
867
   }
 
868
   else if(indicator_style==IND_GRAPH||indicator_style==IND_TOTAL_GRAPH)
 
869
   {
 
870
    if(bytes==0L)
 
871
    {
 
872
     p+=sprintf(p, sfmt_double, del_double);
 
873
     p+=sprintf(p, sfmt_graph, del_double);
 
874
     *p='\0'; p=ind;
 
875
     msg_cprintf(H_HL, (FMSG *)strform, ind);
 
876
    }
 
877
    else
 
878
    {
 
879
     if(total_size!=0&&display_totals&&indicator_style==IND_TOTAL_GRAPH)
 
880
      pct=calc_percentage(total_written+bytes, total_size);
 
881
     else
 
882
      pct=calc_percentage(bytes, uncompsize);
 
883
     if(pct==prev_pct&&CHECK_SENTRY())
 
884
      return;
 
885
     p=nputnc(p, COUNTER_CHAR, pct/100);
 
886
     p=nputnc(p, '\b', pct/100);
 
887
     *p='\0'; p=ind;
 
888
     msg_cprintf(H_OPER, (FMSG *)strform, ind);
 
889
    }
 
890
   }
 
891
   else if(indicator_style==IND_PCT_GRAPH||indicator_style==IND_TOTAL_PCT_GRAPH||indicator_style==IND_TOTAL_PCT_LGRAPH)
 
892
   {
 
893
    if(total_size!=0&&display_totals&&(indicator_style==IND_TOTAL_PCT_GRAPH||indicator_style==IND_TOTAL_PCT_LGRAPH))
 
894
     pct=calc_percentage(total_written+bytes, total_size);
 
895
    else
 
896
     pct=calc_percentage(bytes, uncompsize);
 
897
    if(bytes==0L)
 
898
    {
 
899
     p+=sprintf(p, sfmt_double, del_double);
 
900
     p+=sprintf(p, sfmt_start_num, pct/10);
 
901
     *p='\0'; p=ind;
 
902
     if(pct==prev_pct&&CHECK_SENTRY())
 
903
      return;
 
904
     msg_cprintf(H_OPER, (FMSG *)strform, ind);
 
905
     msg_cprintf(H_HL, sfmt_mid_graph, del_double);
 
906
    }
 
907
    else
 
908
    {
 
909
     p+=sprintf(p, sfmt_short_numeric, pct/10);
 
910
     if(total_size!=0&&indicator_style==IND_TOTAL_PCT_GRAPH)
 
911
      pct=calc_percentage(total_written+bytes, total_size);
 
912
     else
 
913
      pct=calc_percentage(bytes, uncompsize);
 
914
     if(pct==prev_pct&&CHECK_SENTRY())
 
915
      return;
 
916
     p=nputnc(p, COUNTER_CHAR, pct/200);
 
917
     p=nputnc(p, '\b', pct/200+5);
 
918
    }
 
919
   }
 
920
  }
 
921
 }
 
922
 *p='\0';
 
923
 msg_cprintf(H_OPER, (FMSG *)strform, ind);
 
924
 prev_pct=pct;
 
925
 SET_SENTRY();
 
926
 #elif SFX_LEVEL==ARJSFXV
 
927
 else if(indicator_style==IND_NORMAL||indicator_style==IND_GRAPH)
 
928
 {
 
929
  if(uncompsize<0L)
 
930
  {
 
931
   if(bytes==0L)
 
932
    p+=sprintf(p, sfmt_double, del_double);
 
933
   p+=sprintf(p, sfmt_bytes, bytes, del_double);
 
934
  }
 
935
  if(indicator_style==IND_NORMAL)
 
936
  {
 
937
   if(bytes==0L)
 
938
   {
 
939
    p+=sprintf(p, sfmt_single, del_single);
 
940
    p+=sprintf(p, sfmt_start_graph, del_single);
 
941
   }
 
942
   else
 
943
   {
 
944
    pct=calc_percentage(bytes, uncompsize);
 
945
    p+=sprintf(p, sfmt_numeric, pct/10, del_single);
 
946
   }
 
947
  }
 
948
 }
 
949
 *p='\0';
 
950
 msg_cprintf(0, (FMSG *)strform, ind);
 
951
 #else
 
952
 else if(indicator_style==IND_NORMAL)
 
953
 {
 
954
  pct=calc_percentage(bytes, uncompsize);
 
955
  printf(sfmt_sfx, pct/10);
 
956
 }
 
957
 #endif
 
958
}
 
959
 
 
960
#endif
 
961
 
 
962
#if SFX_LEVEL>=ARJ
 
963
 
 
964
/* Puts a character to the output stream. The cursor position given is only for
 
965
   checking purposes. Returns the new cursor position. */
 
966
 
 
967
static int arj_putc(unsigned char c, int p)
 
968
{
 
969
 unsigned char t[8];
 
970
 unsigned char *q;
 
971
 int rc=p;
 
972
 
 
973
 q=t;
 
974
 if(c==LF)
 
975
 {
 
976
  #if COMPILER==MSC
 
977
   *q++=CR;
 
978
  #endif
 
979
  *q++=c;
 
980
  rc=1;
 
981
 }
 
982
 else if(c==TAB)
 
983
 {
 
984
  do
 
985
  {
 
986
   if(p<CONSOLE_LINE_LENGTH)
 
987
    *q++=' ';
 
988
   p++;
 
989
  } while(p%TAB_POS!=1);
 
990
  rc=p;
 
991
 }
 
992
 else if(c==CR)
 
993
 {
 
994
  *q++=' ';
 
995
  rc++;
 
996
 }
 
997
 else
 
998
 {
 
999
  *q++=(c>=' ')?c:UNDISP_CHAR;
 
1000
  rc++;
 
1001
 }
 
1002
 *q='\0';
 
1003
 msg_cprintf(0, (FMSG *)strform, t);
 
1004
 return(rc);
 
1005
}
 
1006
 
 
1007
/* Prints the given text to stdout, querying for "more?" when needed. Returns
 
1008
   1 if the output was cancelled by the user in response to the "--More--?"
 
1009
   prompt. */
 
1010
 
 
1011
static int list_with_more(char *str, unsigned int len)
 
1012
{
 
1013
 char i_field[CONSOLE_LINE_LENGTH+1];   /* Input field */
 
1014
 char *sptr;
 
1015
 unsigned int i;
 
1016
 int cur_pos;
 
1017
 int cur_line;
 
1018
 unsigned char c;
 
1019
 int sf;
 
1020
 
 
1021
 #if COMPILER==MSC
 
1022
  if(help_issued)
 
1023
   fputc(CR, stdout);
 
1024
 #endif
 
1025
 sptr=str;
 
1026
 far_strcpy((char FAR *)i_field, prompt_for_more?M_QUERY_MORE:M_QUERY_SCANNED_ENOUGH);
 
1027
 nputlf();
 
1028
 cur_line=2;
 
1029
 cur_pos=1;
 
1030
 i=1;
 
1031
 while(i<=len)
 
1032
 {
 
1033
  c=*(sptr++);
 
1034
  if(verbose_display==VERBOSE_NONE&&!help_issued)
 
1035
   c&=0x7F;                             /* Strip high bit from nonlocal text */
 
1036
  i++;
 
1037
  if(i>len)
 
1038
   c=LF;
 
1039
  cur_pos=arj_putc(c, cur_pos);
 
1040
  if(c==LF)
 
1041
  {
 
1042
   cur_line++;
 
1043
   if(cur_line>=lines_per_page-2)
 
1044
   {
 
1045
    cur_line=0;
 
1046
    sf=(yes_on_all_queries|skip_scanned_query);
 
1047
    if(!sf)
 
1048
    {
 
1049
     sf=query_action(REPLY_NO, QUERY_SCANNED_ENOUGH, i_field);
 
1050
     if(prompt_for_more)
 
1051
      sf^=1;
 
1052
    }
 
1053
    if(sf)
 
1054
     return(1);
 
1055
   }
 
1056
  }
 
1057
 }
 
1058
 if(help_issued)
 
1059
  return(0);
 
1060
 sf=(yes_on_all_queries|skip_scanned_query);
 
1061
 if(!sf)
 
1062
 {
 
1063
  sf=query_action(REPLY_NO, QUERY_SCANNED_ENOUGH, i_field);
 
1064
  if(prompt_for_more)
 
1065
   sf^=1;
 
1066
 }
 
1067
 return(sf);
 
1068
}
 
1069
 
 
1070
/* Compares the contents of the block with the input file. */
 
1071
 
 
1072
static int compare_fblock(char *block, int len)
 
1073
{
 
1074
 int bytes_read;
 
1075
 char FAR *tmp_block;
 
1076
 
 
1077
 if(identical_filedata)
 
1078
 {
 
1079
  tmp_block=farmalloc_msg((unsigned long)len);
 
1080
  far_memmove(tmp_block, (char FAR *)block, len);
 
1081
  if((bytes_read=fread(block, 1, len, tstream))!=len)
 
1082
   identical_filedata=0;
 
1083
  else
 
1084
  {
 
1085
   if(bytes_read>0)
 
1086
   {
 
1087
    if(far_memcmp((char FAR *)block, tmp_block, bytes_read))
 
1088
     identical_filedata=0;
 
1089
   }
 
1090
  }
 
1091
  far_memmove((char FAR *)block, tmp_block, len);
 
1092
  farfree(tmp_block);
 
1093
 }
 
1094
 return(0);
 
1095
}
 
1096
 
 
1097
/* Displays the text found in a block. Returns the number of bytes displayed. */
 
1098
 
 
1099
static int display_found_text(unsigned char FAR *block, int offset, int block_len)
 
1100
{
 
1101
 int remain;
 
1102
 int d_offset;
 
1103
 int column;
 
1104
 unsigned int c;
 
1105
 int i;
 
1106
 
 
1107
 d_offset=offset;
 
1108
 remain=min(fdisp_lines*TXTD_LENGTH, block_len);
 
1109
 if(remain>TXTD_LENGTH)
 
1110
 {
 
1111
  msg_cprintf(0, M_MARK_LLINE);
 
1112
  d_offset=(remain/2>offset)?0:offset-remain/2;
 
1113
 }
 
1114
 block+=d_offset;
 
1115
 column=0;
 
1116
 i=0;
 
1117
 while(i<remain&&d_offset<block_len)
 
1118
 {
 
1119
  if(column>=TXTD_LENGTH)
 
1120
  {
 
1121
   msg_cprintf(0, lf);
 
1122
   column=0;
 
1123
  }
 
1124
  c=*(block++);
 
1125
  if(verbose_display)
 
1126
  {
 
1127
   if(c<CON_LBOUND)
 
1128
    c=UNDISP_CHAR;
 
1129
  }
 
1130
  else
 
1131
   if(c<CON_LBOUND||c>CON_UBOUND)
 
1132
    c=UNDISP_CHAR;
 
1133
  fputc(c, new_stdout);
 
1134
  i++;
 
1135
  d_offset++;
 
1136
  column++;
 
1137
 }
 
1138
 msg_cprintf(0, lf);
 
1139
 return(i-(offset-d_offset));
 
1140
}
 
1141
 
 
1142
/* Performs a search for the given pattern in memory block */
 
1143
 
 
1144
static int t_search_stub(char *pattern, char *cmpblock, char FAR *block, int skip, int block_len)
 
1145
{
 
1146
 int len;
 
1147
 int matches;
 
1148
 int search_offset;
 
1149
 int limit;
 
1150
 char c;
 
1151
 int t_offset;
 
1152
 char *p;
 
1153
 
 
1154
 len=strlen(pattern);
 
1155
 matches=0;
 
1156
 search_offset=0;
 
1157
 c=*pattern;
 
1158
 limit=(len>=block_len)?0:block_len-len;
 
1159
 t_offset=skip;
 
1160
 p=&cmpblock[skip];
 
1161
 while(t_offset<limit)
 
1162
 {
 
1163
  if(*p==c)
 
1164
  {
 
1165
   if(!memcmp(pattern, p, len))
 
1166
   {
 
1167
    if(!pattern_found&&search_mode!=SEARCH_DEFAULT)
 
1168
    {
 
1169
     if(search_mode==SEARCH_SHOW_NAMES)
 
1170
      msg_cprintf(0, strform, misc_buf);
 
1171
     if(search_mode!=SEARCH_DEFAULT)
 
1172
      msg_cprintf(0, strform, lf);
 
1173
    }
 
1174
    pattern_found=1;
 
1175
    matches++;
 
1176
    if(fdisp_lines!=0&&t_offset>search_offset)
 
1177
     search_offset=t_offset+display_found_text(block, t_offset, block_len)-len;
 
1178
    if(extm_mode!=EXTM_NONE)
 
1179
     break;
 
1180
   }
 
1181
  }
 
1182
  t_offset++;
 
1183
  p++;
 
1184
 }
 
1185
 return(matches);
 
1186
}
 
1187
 
 
1188
/* Performs a search in the block of continuous data. */
 
1189
 
 
1190
static int search_in_block(char *block, int block_len)
 
1191
{
 
1192
 int tmp_len, tail_len;
 
1193
 char *sstr_ptr;
 
1194
 char FAR *block_ptr;
 
1195
 char FAR *reserve_ptr;
 
1196
 int i;
 
1197
 
 
1198
 block_ptr=(char FAR *)block;
 
1199
 reserve_ptr=(char FAR *)search_reserve;
 
1200
 if(ignore_pcase)
 
1201
 {
 
1202
  block_ptr=farmalloc_msg((unsigned long)block_len);
 
1203
  far_memmove(block_ptr, (char FAR *)block, block_len);
 
1204
  toupper_loc(block, block_len);
 
1205
  if(reserve_size!=0)
 
1206
  {
 
1207
   reserve_ptr=farmalloc_msg(160L);
 
1208
   far_memmove(reserve_ptr, (char FAR *)search_reserve, reserve_size);
 
1209
   toupper_loc(search_reserve, reserve_size);
 
1210
  }
 
1211
 }
 
1212
 for(i=0; i<SEARCH_STR_MAX&&search_str[i]!=NULL; i++)
 
1213
 {
 
1214
  sstr_ptr=search_str[i];
 
1215
  if(reserve_size!=0)
 
1216
  {
 
1217
   tmp_len=(block_len>INPUT_LENGTH)?INPUT_LENGTH:block_len;
 
1218
   memcpy(search_reserve+reserve_size, block, tmp_len);
 
1219
   if(ignore_pcase)
 
1220
    far_memmove(&reserve_ptr[reserve_size], block_ptr, tmp_len);
 
1221
   tail_len=reserve_size-strlen(sstr_ptr)+1;
 
1222
   search_occurences[i]+=(long)t_search_stub(sstr_ptr, search_reserve, reserve_ptr, tail_len, reserve_size+tmp_len);
 
1223
   if(pattern_found&&extm_mode!=EXTM_NONE)
 
1224
    break;
 
1225
  }
 
1226
  search_occurences[i]+=(long)t_search_stub(sstr_ptr, block, block_ptr, 0, block_len);
 
1227
  if(pattern_found&&extm_mode!=EXTM_NONE)
 
1228
   break;
 
1229
 }
 
1230
 if(ignore_pcase)
 
1231
 {
 
1232
  far_memmove((char FAR *)block, block_ptr, block_len);
 
1233
  farfree(block_ptr);
 
1234
  if(reserve_size!=0)
 
1235
   farfree(reserve_ptr);
 
1236
 }
 
1237
 reserve_size=(block_len>INPUT_LENGTH)?INPUT_LENGTH:block_len;
 
1238
 memcpy(search_reserve, block+(block_len-reserve_size), reserve_size);
 
1239
 return(0);
 
1240
}
 
1241
 
 
1242
/* Displays a block of text using ANSI comment display routine. */
 
1243
 
 
1244
static int display_block(char *str, int len)
 
1245
{
 
1246
 if(new_stdout!=new_stderr)
 
1247
 {
 
1248
  while((len--)>0)
 
1249
  {
 
1250
   #ifndef DIRECT_TO_ANSI
 
1251
    display_ansi(*(str++));
 
1252
   #else
 
1253
    putchar(*(str++));
 
1254
   #endif
 
1255
  }
 
1256
 }
 
1257
 return(0);
 
1258
}
 
1259
 
 
1260
/* Performs various actions involving the given block. */
 
1261
 
 
1262
static int block_op(int action, char *block, int len)
 
1263
{
 
1264
 if(action==BOP_LIST)
 
1265
  return(list_with_more(block, len));
 
1266
 else if(action==BOP_DISPLAY)
 
1267
  return(display_block(block, len));
 
1268
 else if(action==BOP_SEARCH)
 
1269
  return(search_in_block(block, len));
 
1270
 else if(action==BOP_COMPARE)
 
1271
  return(compare_fblock(block, len));
 
1272
 else
 
1273
  return(0);
 
1274
}
 
1275
 
 
1276
#endif
 
1277
 
 
1278
#if SFX_LEVEL>=ARJ||defined(REARJ)
 
1279
 
 
1280
/* Renames file and ensures that it has been successfully renamed */
 
1281
 
 
1282
#ifdef REARJ
 
1283
 
 
1284
int rename_with_check(char *oldname, char *newname)
 
1285
{
 
1286
 if(!no_file_activity)
 
1287
 {
 
1288
  if(file_rename(oldname, newname))
 
1289
   return(-1);
 
1290
  if(file_exists(oldname)||!file_exists(newname))
 
1291
   return(-1);
 
1292
 }
 
1293
 return(0);
 
1294
}
 
1295
 
 
1296
#else
 
1297
 
 
1298
void rename_with_check(char *oldname, char *newname)
 
1299
{
 
1300
 if(!file_test_access(oldname))
 
1301
 {
 
1302
  if(!file_rename(oldname, newname))
 
1303
  {
 
1304
   if(!file_exists(oldname)&&file_exists(newname))
 
1305
    return;
 
1306
  }
 
1307
 }
 
1308
 error(M_CANTRENAME, oldname, newname);
 
1309
}
 
1310
 
 
1311
#endif
 
1312
#endif  /* SFX_LEVEL>=ARJ||defined(REARJ) */
 
1313
 
 
1314
#if SFX_LEVEL>=ARJ
 
1315
 
 
1316
/* Returns number of <c> occurences in the given string */
 
1317
 
 
1318
static int count_chars(char *str, char c)
 
1319
{
 
1320
 int occurs=0;
 
1321
 char *tmp_ptr;
 
1322
 
 
1323
 for(tmp_ptr=str; *tmp_ptr!='\0'; tmp_ptr++)
 
1324
  if(*tmp_ptr==c)
 
1325
   occurs++;
 
1326
 return(occurs);
 
1327
}
 
1328
 
 
1329
/* Deletes the processed files */
 
1330
 
 
1331
int delete_processed_files(struct flist_root *root)
 
1332
{
 
1333
 char name[FILENAME_MAX];
 
1334
 unsigned int count;
 
1335
 int depth, max_depth;
 
1336
 FILE_COUNT i;
 
1337
 FILE *t;
 
1338
 
 
1339
 /* If break is requested, cancel the deletion */
 
1340
 if(ctrlc_processing)
 
1341
  return(0);
 
1342
 max_depth=0;
 
1343
 count=0;
 
1344
 for(i=0; i<root->files; i++)
 
1345
 {
 
1346
  if(cfa_get(i)==FLFLAG_PROCESSED)
 
1347
   count++;
 
1348
 }
 
1349
 if(delete_processed==DP_STD&&!yes_on_all_queries&&!query_delete)
 
1350
 {
 
1351
  msg_sprintf(misc_buf, M_QUERY_DELETE_N_FILES, count);
 
1352
  if(!query_action(REPLY_YES, QUERY_DELETE_N_FILES, (char FAR *)misc_buf))
 
1353
   return(0);
 
1354
 }
 
1355
 msg_cprintf(0, M_DELETE_COUNT, count);
 
1356
 for(i=0; i<root->files; i++)
 
1357
 {
 
1358
  if(cfa_get(i)==FLFLAG_PROCESSED)
 
1359
  {
 
1360
   flist_retrieve(name, NULL, root, i);
 
1361
   depth=count_chars(name, PATHSEP_DEFAULT);
 
1362
   if(depth>max_depth)
 
1363
    max_depth=depth;
 
1364
   if(!is_directory(name))
 
1365
   {
 
1366
    /* ASR fix for 2.78-TCO */
 
1367
    if(delete_processed!=DP_ADD_TRUNC)
 
1368
    {
 
1369
     if(file_unlink(name))
 
1370
     {
 
1371
      msg_cprintf(H_ERR, M_CANT_DELETE, name);
 
1372
      nputlf();
 
1373
     }
 
1374
    }
 
1375
    else
 
1376
    {
 
1377
     if((t=file_open(name, m_rbp))==NULL)
 
1378
     {
 
1379
      msg_cprintf(H_ERR, M_CANT_TRUNCATE, name);
 
1380
      nputlf();
 
1381
     }
 
1382
     file_chsize(t, 0);
 
1383
     fclose(t);
 
1384
    }
 
1385
    cfa_store(i, FLFLAG_DELETED);
 
1386
   }
 
1387
  }
 
1388
 }
 
1389
 for(depth=max_depth; depth>=0; depth--)
 
1390
 {
 
1391
  for(i=0; i<root->files; i++)
 
1392
  {
 
1393
   if(cfa_get(i)==FLFLAG_PROCESSED)
 
1394
   {
 
1395
    flist_retrieve(name, NULL, root, i);
 
1396
    if(count_chars(name, PATHSEP_DEFAULT)>=depth&&is_directory(name))
 
1397
    {
 
1398
     if(file_rmdir(name))
 
1399
     {
 
1400
      msg_cprintf(H_ERR, M_CANT_DELETE, name);
 
1401
      nputlf();
 
1402
     }
 
1403
     cfa_store(i, FLFLAG_DELETED);
 
1404
    }
 
1405
   }
 
1406
  }
 
1407
 }
 
1408
 return(0);
 
1409
}
 
1410
 
 
1411
/* Writes a byte to the file */
 
1412
 
 
1413
void fput_byte(int b, FILE *stream)
 
1414
{
 
1415
 if(!no_file_activity)
 
1416
 {
 
1417
  if(fputc(b, stream)==EOF)
 
1418
   error(M_DISK_FULL);
 
1419
 }
 
1420
}
 
1421
 
 
1422
/* Writes two bytes to the file */
 
1423
 
 
1424
void fput_word(unsigned int w, FILE *stream)
 
1425
{
 
1426
 fput_byte(w&0xFF, stream);
 
1427
 fput_byte(w>>8,   stream);
 
1428
}
 
1429
 
 
1430
/* Writes four bytes to the file */
 
1431
 
 
1432
void fput_dword(unsigned long l, FILE *stream)
 
1433
{
 
1434
#ifdef WORDS_BIGENDIAN
 
1435
fput_word((unsigned int)(l&0xFFFF), stream);
 
1436
fput_word((unsigned int)(l>>16), stream);
 
1437
#else
 
1438
if(!no_file_activity)
 
1439
  {
 
1440
   if(!fwrite(&l,4,1,stream))
 
1441
    error(M_DISK_FULL);
 
1442
  }
 
1443
#endif
 
1444
}
 
1445
 
 
1446
/* Writes the compressed data */
 
1447
 
 
1448
void flush_compdata()
 
1449
{
 
1450
 if(out_bytes>0)
 
1451
 {
 
1452
  compsize+=(unsigned long)out_bytes;
 
1453
  if(compsize>origsize&&(!garble_enabled||!file_packing))
 
1454
   unpackable=1;
 
1455
  else
 
1456
  {
 
1457
   if(!no_file_activity)
 
1458
   {
 
1459
    if(garble_enabled)
 
1460
     garble_encode_stub(out_buffer, out_bytes);
 
1461
    if(file_packing)
 
1462
    {
 
1463
     file_write(out_buffer, 1, out_bytes, aostream);
 
1464
    }
 
1465
    else
 
1466
    {
 
1467
     far_memmove(packblock_ptr, (char FAR *)out_buffer, out_bytes);
 
1468
     packblock_ptr+=out_bytes;
 
1469
    }
 
1470
    out_avail=PUTBIT_SIZE;
 
1471
   }
 
1472
  }
 
1473
  out_bytes=0;
 
1474
 }
 
1475
}
 
1476
 
 
1477
/* Initializes compressed data output */
 
1478
 
 
1479
void init_putbits()
 
1480
{
 
1481
 unsigned long fp;
 
1482
 
 
1483
 bitcount=0;
 
1484
 byte_buf=0;
 
1485
 bitbuf=0;
 
1486
 out_bytes=0;
 
1487
 if(!file_packing||no_file_activity)
 
1488
  fp=0L;
 
1489
 else
 
1490
 {
 
1491
  fp=ftell(aostream);
 
1492
  if(fp>MAX_FILE_SIZE)
 
1493
   error(M_FILE_IS_TOO_LARGE);
 
1494
 }
 
1495
 out_buffer=malloc_msg(PUTBIT_SIZE);
 
1496
 out_avail=PUTBIT_SIZE-(fp%PUTBIT_SIZE);
 
1497
 if(out_avail>PUTBIT_SIZE)
 
1498
  error(M_PUTBIT_SIZE_ERROR);
 
1499
 mem_stats();
 
1500
}
 
1501
 
 
1502
/* Ends the bitwise output */
 
1503
 
 
1504
void shutdown_putbits()
 
1505
{
 
1506
 if(!unpackable)
 
1507
 {
 
1508
  putbits(CHAR_BIT-1, 0);
 
1509
  if(out_bytes!=0)
 
1510
   flush_compdata();
 
1511
 }
 
1512
 free(out_buffer);
 
1513
 out_bytes=0;
 
1514
}
 
1515
 
 
1516
/* Clears the archive attribute for a set of files */
 
1517
 
 
1518
int group_clear_arch(struct flist_root *root)
 
1519
{
 
1520
 char name[FILENAME_MAX];
 
1521
 FILE_COUNT i;
 
1522
 
 
1523
 if(ctrlc_processing)
 
1524
  return(0);
 
1525
 for(i=0; i<root->files; i++)
 
1526
 {
 
1527
  if(cfa_get(i)==FLFLAG_PROCESSED)
 
1528
  {
 
1529
   flist_retrieve(name, NULL, root, i);
 
1530
   if(dos_clear_arch_attr(name))
 
1531
    msg_cprintf(H_ERR, M_CANT_RESET, name);
 
1532
   cfa_store(i, FLFLAG_DELETED);
 
1533
  }
 
1534
 }
 
1535
 return(0);
 
1536
}
 
1537
 
 
1538
#endif