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

« back to all changes in this revision

Viewing changes to misc.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: misc.c,v 1.5 2004/05/31 16:08:41 andrew_belov Exp $
 
3
 * ---------------------------------------------------------------------------
 
4
 * Various system-independent routines are kept here. This module is needed if
 
5
 * the ENVIRON.C is linked, since both of them cross-reference each other.
 
6
 *
 
7
 */
 
8
 
 
9
#include "arj.h"
 
10
 
 
11
DEBUGHDR(__FILE__)                      /* Debug information block */
 
12
 
 
13
/* Compact filelist array */
 
14
 
 
15
#if SFX_LEVEL>=ARJSFXV
 
16
 static unsigned char FAR * FAR *flist_array=NULL;
 
17
 static FILE_COUNT cfa_allocated;       /* # of allocated blocks */
 
18
#endif
 
19
 
 
20
/* Extended wildcard specifiers */
 
21
 
 
22
static char xwild_symbols[]="?*[]^";
 
23
 
 
24
/* Forward references */
 
25
 
 
26
static int xwild_propagate(char *wcstr, char *str);
 
27
 
 
28
#if SFX_LEVEL>=ARJ
 
29
 
 
30
/* Dumb extended wildcard lookup routine */
 
31
 
 
32
static int xwild_lookup(char *str)
 
33
{
 
34
 char *p;
 
35
 char c;
 
36
 
 
37
 for(p=str; *p!='\0'; p++)
 
38
 {
 
39
  c=*p;
 
40
  if(c=='*'||c=='?'||c=='['||c=='^')
 
41
   return(XW_OK);
 
42
 }
 
43
 return(XW_NONE);
 
44
}
 
45
 
 
46
/* An extended wildcard parser */
 
47
 
 
48
static int xwild_parser(char *wcstr, int *rc)
 
49
{
 
50
 char *p;
 
51
 char c;
 
52
 
 
53
 *rc=XWP_NONE;
 
54
 for(p=wcstr; *p!='\0'; p++)
 
55
 {
 
56
  c=*p;
 
57
  if(c=='^')
 
58
  {
 
59
   p++;
 
60
   if(*p=='\0')
 
61
   {
 
62
    *rc=XWP_TERM;
 
63
    return(XW_NONE);
 
64
   }
 
65
  }
 
66
  else if(c=='[')
 
67
  {
 
68
   p++;
 
69
   if((c=*p)==']')
 
70
   {
 
71
    *rc=XWP_NBRACKET;
 
72
    return(XW_NONE);
 
73
   }
 
74
   if(c=='\0')
 
75
   {
 
76
    *rc=XWP_OBRACKET;
 
77
    return(XW_NONE);
 
78
   }
 
79
   while(*p!=']')
 
80
   {
 
81
    if(*p=='^')
 
82
    {
 
83
     p++;
 
84
     if((c=*p)=='\0')
 
85
     {
 
86
      *rc=XWP_TERM;
 
87
      return(XW_NONE);
 
88
     }
 
89
    }
 
90
    else
 
91
     p++;
 
92
    if((c=*p)=='\0')
 
93
    {
 
94
     *rc=XWP_OBRACKET;
 
95
     return(XW_NONE);
 
96
    }
 
97
    if(*p=='-')
 
98
    {
 
99
     c=*++p;
 
100
     if(c=='\0'||c==']')
 
101
     {
 
102
      *rc=XWP_MDASH;
 
103
      return(XW_NONE);
 
104
     }
 
105
     if(*p=='^')
 
106
      p++;
 
107
     if((c=*p++)=='\0')
 
108
     {
 
109
      *rc=XWP_TERM;
 
110
      return(XW_NONE);
 
111
     }
 
112
    }
 
113
   }
 
114
  }
 
115
  else
 
116
   p++;
 
117
 }
 
118
 return(XW_OK);
 
119
}
 
120
 
 
121
/* Extended wildcard expansion and matching routine */
 
122
 
 
123
static int xwild_match(char *wcstr, char *str)
 
124
{
 
125
 char *wptr;
 
126
 char *sptr;
 
127
 char c, sc;
 
128
 char fchar;
 
129
 int xchar;
 
130
 int pflag;
 
131
 int unproc;
 
132
 char xc, xpc;                          /* Wildcard processed characters */
 
133
 
 
134
 wptr=wcstr;
 
135
 sptr=str;
 
136
 while(*wptr!='\0')
 
137
 {
 
138
  if((c=*sptr)=='\0')
 
139
   return((*wptr=='*'&&*++wptr=='\0')?XW_OK:XW_OWC);
 
140
  fchar=*wptr;
 
141
  switch(fchar)
 
142
  {
 
143
   case '*':
 
144
    return(xwild_propagate(wptr, sptr));
 
145
   case '[':
 
146
    xchar=0;
 
147
    wptr++;
 
148
    if(*wptr=='!')
 
149
    {
 
150
     xchar=1;
 
151
     wptr++;
 
152
    }
 
153
    unproc=0;
 
154
    pflag=1;
 
155
    while(pflag!=0)
 
156
    {
 
157
     if(*wptr!=']')
 
158
     {
 
159
      c=(*wptr=='^')?*++wptr:*wptr;     /* Escape character */
 
160
      xpc=xc=toupper(c);
 
161
      if(c=='\0')
 
162
       return(XW_TERM);
 
163
      wptr++;
 
164
      if(*wptr=='-')
 
165
      {
 
166
       c=*++wptr;
 
167
       if(c=='\0'&&c!=']')
 
168
        return(XW_TERM);
 
169
       xc=toupper(c);
 
170
       if(xc=='^')
 
171
       {
 
172
        c=*++wptr;
 
173
        xc=toupper(c);
 
174
        if(xc=='\0')
 
175
         return(XW_TERM);
 
176
       }
 
177
       wptr++;
 
178
      }
 
179
      sc=toupper(*sptr);
 
180
      if((xpc>=xc&&sc>=xc&&sc<=xpc)||(sc>=xpc&&sc<=xc))
 
181
      {
 
182
       unproc=1;
 
183
       pflag=0;
 
184
      }
 
185
     }
 
186
     else
 
187
      pflag=0;
 
188
    }
 
189
    if((xchar!=0&&unproc)||(xchar==0&&!unproc))
 
190
     return(XW_UNPROC);
 
191
    if(!unproc)
 
192
     break;
 
193
    /* Skip the rest, applying usual check-ups */
 
194
    while(*wptr!=']')
 
195
    {
 
196
     if(*wptr=='\0')
 
197
      return(XW_TERM);
 
198
     if(*wptr=='^')
 
199
     {
 
200
      if(*++wptr=='\0')
 
201
       return(XW_TERM);
 
202
     }
 
203
     wptr++;
 
204
    }
 
205
    break;
 
206
   case '?':
 
207
    break;                              /* Skip the comparison */
 
208
   case '^':
 
209
    wptr++;
 
210
    if(*wptr=='\0')
 
211
     return(XW_TERM);
 
212
   default:                             /* fallthru */
 
213
    if(toupper(*wptr)!=toupper(*sptr))
 
214
     return(XW_MISMATCH);
 
215
    break;
 
216
  }
 
217
  wptr++;
 
218
  sptr++;
 
219
 }
 
220
 return((*sptr=='\0')?XW_OK:XW_PREM_END);
 
221
}
 
222
 
 
223
/* Propagates (expands) wildcard markers */
 
224
 
 
225
static int xwild_propagate(char *wcstr, char *str)
 
226
{
 
227
 int rc=0;
 
228
 char c;
 
229
 
 
230
 while(*wcstr=='?'||*wcstr=='*')
 
231
 {
 
232
  if(*wcstr=='?')
 
233
  {
 
234
   if(*++str=='\0')
 
235
    return(XW_OWC);
 
236
  }
 
237
  wcstr++;
 
238
 }
 
239
 if(*wcstr=='\0')
 
240
  return(XW_OK);
 
241
 if((c=*wcstr)=='^')
 
242
 {
 
243
  if((c=*++wcstr)=='\0')
 
244
   return(XW_TERM);
 
245
 }
 
246
 do
 
247
 {
 
248
  if(toupper(c)==toupper(*str)||c=='[')
 
249
   rc=xwild_match(wcstr, str);
 
250
  if(*str++=='\0')
 
251
   rc=XW_OWC;
 
252
 } while(rc!=XW_OK&&rc!=XW_OWC&&rc!=XW_TERM);
 
253
 return(rc);
 
254
}
 
255
 
 
256
/* Wildcard matching routine wrapper (provides boolean RCs) */
 
257
 
 
258
static int xwild_compare(char *wcstr, char *str)
 
259
{
 
260
 int xrc;
 
261
 
 
262
 xrc=xwild_match(wcstr, str);
 
263
 return((xrc==XW_OK)?XW_OK:XW_NONE);
 
264
}
 
265
 
 
266
/* Change all UNIX-style path specifiers to DOS-style ones in a given string */
 
267
 
 
268
void unix_path_to_dos(char *path)
 
269
{
 
270
 int i=0;
 
271
 if(translate_unix_paths)
 
272
 {
 
273
  while(path[i]!='\0')
 
274
  {
 
275
   if(path[i]==PATHSEP_UNIX)
 
276
    path[i]=PATHSEP_DEFAULT;
 
277
   i++;
 
278
  }
 
279
 }
 
280
}
 
281
 
 
282
#endif
 
283
 
 
284
#if SFX_LEVEL>=ARJSFXV
 
285
 
 
286
/* Allocate a block of memory that will exactly fit the length of string,
 
287
   and copy the string into this newly-created block. */
 
288
 
 
289
void *malloc_str(char *str)
 
290
{
 
291
 return(strcpy((char *)malloc_msg(strlen(str)+1), str));
 
292
}
 
293
 
 
294
#endif
 
295
 
 
296
#if SFX_LEVEL>=ARJ
 
297
 
 
298
/* The same as malloc_str, but it allocates near memory for far strings */
 
299
 
 
300
void *malloc_far_str(char FAR *str)
 
301
{
 
302
 char *k;
 
303
 
 
304
 k=malloc_msg(far_strlen(str)+1);
 
305
 far_strcpy((char FAR *)k, str);
 
306
 return(k);
 
307
}
 
308
 
 
309
#endif
 
310
 
 
311
#if SFX_LEVEL>=ARJ
 
312
 
 
313
/* Converts current time to a standard timestamp */
 
314
 
 
315
void cur_time_stamp(struct timestamp *dest)
 
316
{
 
317
 time_t cur_unixtime;
 
318
 
 
319
 cur_unixtime=time(NULL);
 
320
 ts_store(dest, OS_UNIX, cur_unixtime);
 
321
}
 
322
 
 
323
/* A strchr() function for far strings */
 
324
 
 
325
#if COMPILER!=MSC&&defined(TILED)
 
326
char FAR *far_strchr(char FAR *str, char chr)
 
327
{
 
328
 while(str[0]!=chr)
 
329
 {
 
330
  if(str[0]=='\0') return(NULL);
 
331
  str++;
 
332
 }
 
333
 return(str);
 
334
}
 
335
#endif
 
336
 
 
337
#endif
 
338
 
 
339
#if SFX_LEVEL>=ARJSFXV||defined(REARJ)
 
340
 
 
341
/* A strcmp() function for far strings */
 
342
 
 
343
#if COMPILER!=MSC&&defined(TILED)
 
344
int far_strcmp(char FAR *str1, char FAR *str2)
 
345
{
 
346
 unsigned int k;
 
347
 
 
348
 for(k=0; str1[k]!='\0'&&str2[k]!='\0'; k++);
 
349
 return((int)(str1[k]-str2[k]));
 
350
}
 
351
#endif
 
352
 
 
353
/* A stricmp() function for far strings */
 
354
 
 
355
#if COMPILER!=MSC&&defined(TILED)
 
356
int far_stricmp(char FAR *str1, char FAR *str2)
 
357
{
 
358
 unsigned int k;
 
359
 
 
360
 for(k=0; toupper(str1[k]!='\0')&&toupper(str2[k]!='\0'); k++);
 
361
 return(toupper(str1[k])-toupper(str2[k]));
 
362
}
 
363
#endif
 
364
 
 
365
#endif
 
366
 
 
367
#if SFX_LEVEL>=ARJ||defined(REARJ)
 
368
 
 
369
/* A strcat() function for far strings */
 
370
 
 
371
#if COMPILER!=MSC&&defined(TILED)
 
372
char FAR *far_strcat(char FAR *dest, char FAR *src)
 
373
{
 
374
 char FAR *tmp_dest;
 
375
 
 
376
 tmp_dest=dest;
 
377
 while(tmp_dest[0]!='\0')
 
378
  tmp_dest++;
 
379
 do
 
380
  (tmp_dest++)[0]=src[0];
 
381
 while((src++)[0]!='\0');
 
382
 return(dest);
 
383
}
 
384
#endif
 
385
 
 
386
#endif
 
387
 
 
388
#if SFX_LEVEL>=ARJSFXV||defined(REARJ)
 
389
 
 
390
/* A strcpy() function for far strings */
 
391
 
 
392
#if COMPILER!=MSC&&defined(TILED)
 
393
char FAR *far_strcpy(char FAR *dest, char FAR *src)
 
394
{
 
395
 int k;
 
396
 
 
397
 for(k=0; src[k]!='\0'; k++)
 
398
  dest[k]=src[k];
 
399
 dest[k]='\0';
 
400
 return(dest);
 
401
}
 
402
#endif
 
403
 
 
404
#endif
 
405
 
 
406
#if SFX_LEVEL>=ARJ
 
407
 
 
408
/* A strlen() function for far strings */
 
409
 
 
410
#if COMPILER!=MSC&&defined(TILED)
 
411
unsigned int far_strlen(char FAR *str)
 
412
{
 
413
 unsigned int k=0;
 
414
 
 
415
 while(str[k]!='\0')
 
416
  k++;
 
417
 return(k);
 
418
}
 
419
#endif
 
420
 
 
421
#endif
 
422
 
 
423
#if SFX_LEVEL>=ARJSFXV
 
424
 
 
425
/* Fills a buffer with the specified value */
 
426
 
 
427
#if COMPILER!=MSC&&defined(TILED)
 
428
void FAR *far_memset(void FAR *buf, int filler, unsigned int size)
 
429
{
 
430
 char FAR *p;
 
431
 unsigned int l;
 
432
 
 
433
 p=(char FAR *)buf;
 
434
 for(l=0; l<size; l++)
 
435
  *p++=(char)filler;
 
436
 return(buf);
 
437
}
 
438
#endif
 
439
 
 
440
#endif
 
441
 
 
442
#if SFX_LEVEL>=ARJSFXV
 
443
 
 
444
/* Copies at most n characters */
 
445
 
 
446
char FAR *far_strcpyn(char FAR *dest, char FAR *src, int limit)
 
447
{
 
448
 int k;
 
449
 
 
450
 for(k=1; k<limit&&src[0]!='\0'; k++)
 
451
 {
 
452
  (dest++)[0]=(src++)[0];
 
453
 }
 
454
 if(limit>0)
 
455
  dest[0]='\0';
 
456
 return(dest);
 
457
}
 
458
 
 
459
#endif
 
460
 
 
461
#if SFX_LEVEL>=ARJSFX
 
462
 
 
463
/* Converts the given string to 7-bit */
 
464
 
 
465
void to_7bit(char *str)
 
466
{
 
467
 while(*str!='\0')
 
468
  *str++&=0x7F;
 
469
}
 
470
 
 
471
#endif
 
472
 
 
473
#if SFX_LEVEL>=ARJSFX||defined(REARJ)
 
474
 
 
475
/* Convert a string to uppercase, depending on locale */
 
476
 
 
477
void strupper(char *s)
 
478
{
 
479
 #if SFX_LEVEL>=ARJSFXV||defined(REARJ)
 
480
  toupper_loc(s, strlen(s));
 
481
 #else
 
482
  while(*s!='\0')
 
483
  {
 
484
   *s=toupper(*s);
 
485
   s++;
 
486
  }
 
487
 #endif
 
488
}
 
489
 
 
490
#endif
 
491
 
 
492
#if SFX_LEVEL>=ARJSFXV
 
493
 
 
494
/* Convert a string to lowercase (note: no locale hack here - the one in
 
495
   strupper() was made exclusively for filename matching under DOS) */
 
496
 
 
497
void strlower(char *s)
 
498
{
 
499
 while(*s!='\0')
 
500
 {
 
501
  *s=tolower(*s);
 
502
  s++;
 
503
 }
 
504
}
 
505
 
 
506
#endif
 
507
 
 
508
#if SFX_LEVEL>=ARJ
 
509
 
 
510
/* Finds an entry in the filelist, returns 1 if matched. Wildcards allowed. */
 
511
 
 
512
int flist_find(struct flist_root *root, char *name)
 
513
{
 
514
 char tmp_name[FILENAME_MAX];           /* Hash filename storage */
 
515
 char n_path[FILENAME_MAX], f_path[FILENAME_MAX];
 
516
 FILE_COUNT entry;
 
517
 int pathname_length;
 
518
 int tmp_pathname_length;
 
519
 
 
520
 if(root==NULL)
 
521
  return(0);
 
522
 pathname_length=split_name(name, n_path, NULL);
 
523
 for(entry=0; entry<root->files; entry++)
 
524
 {
 
525
  flist_retrieve(tmp_name, NULL, root, entry);
 
526
  tmp_pathname_length=split_name(tmp_name, f_path, NULL);
 
527
  if(marksym_expansion)
 
528
  {
 
529
   if(tmp_pathname_length!=0&&strlen(tmp_name)==tmp_pathname_length&&xwild_compare(f_path, n_path)==XW_OK)
 
530
     return(1);
 
531
   if(tmp_pathname_length==0||xwild_compare(f_path, n_path)==XW_OK)
 
532
   {
 
533
    if(xwild_compare(tmp_name+tmp_pathname_length, name+pathname_length)==XW_OK)
 
534
     return(1);
 
535
   }
 
536
  }
 
537
  else
 
538
  {
 
539
   /* If it was a directory specification, return OK */
 
540
   if(tmp_pathname_length!=0&&strlen(tmp_name)==tmp_pathname_length&&!strncmp_os(tmp_name, name, tmp_pathname_length))
 
541
    return(1);
 
542
   /* For filename specifications, proceed with compare */
 
543
   if(tmp_pathname_length==0||(tmp_pathname_length==pathname_length&&!strncmp_os(tmp_name, name, tmp_pathname_length)))
 
544
    if(match_wildcard(&name[pathname_length], &tmp_name[tmp_pathname_length]))
 
545
     return(1);
 
546
  }
 
547
 }
 
548
 return(0);
 
549
}
 
550
 
 
551
/* Checks if a file already exists in the archive */
 
552
 
 
553
int flist_is_in_archive(struct flist_root *root, char *name)
 
554
{
 
555
 char tmp_name[CCHMAXPATHCOMP];         /* For names retrieved from the hash */
 
556
 char case_name[CCHMAXPATHCOMP];        /* and for converting them to u-case */
 
557
 FILE_COUNT entry;
 
558
 
 
559
 for(entry=0; entry<root->files; entry++)
 
560
 {
 
561
  if(cfa_get(entry)==FLFLAG_PROCESSED)
 
562
  {
 
563
   flist_retrieve(tmp_name, NULL, root, entry);
 
564
   default_case_path(case_name, tmp_name);
 
565
   if(!stricmp(name, case_name))
 
566
    return(1);
 
567
  }
 
568
 }
 
569
 return(0);
 
570
}
 
571
 
 
572
/* Returns 1 if the file properties given match the current search narrowing
 
573
   criteria (such as "same or newer", and so on) */
 
574
 
 
575
int match_attrib(struct file_properties *properties)
 
576
{
 
577
 int matched;
 
578
 
 
579
 /* First, check if the attributes match */
 
580
 if(filter_attrs)
 
581
 {
 
582
  matched=0;
 
583
  if(file_attr_mask&TAG_DIREC&&properties->type==ARJT_DIR)
 
584
   matched=1;
 
585
  if(file_attr_mask&TAG_UXSPECIAL&&properties->type==ARJT_UXSPECIAL)
 
586
   matched=1;
 
587
  if(file_attr_mask&TAG_NORMAL&&
 
588
   !(properties->attrib&FATTR_DIREC)&&
 
589
   !(properties->attrib&FATTR_RDONLY)&&
 
590
   !(properties->attrib&FATTR_SYSTEM)&&
 
591
   !(properties->attrib&FATTR_HIDDEN)&&
 
592
     properties->type!=ARJT_UXSPECIAL)
 
593
   matched=1;
 
594
  if(file_attr_mask&TAG_RDONLY&&properties->attrib&FATTR_RDONLY)
 
595
   matched=1;
 
596
  if(file_attr_mask&TAG_HIDDEN&&properties->attrib&FATTR_HIDDEN)
 
597
   matched=1;
 
598
  if(file_attr_mask&TAG_SYSTEM&&properties->attrib&FATTR_SYSTEM)
 
599
   matched=1;
 
600
  if(file_attr_mask&TAG_ARCH&&!(properties->attrib&FATTR_ARCH))
 
601
   return(0);
 
602
  if(file_attr_mask&TAG_NOT_ARCH&&properties->attrib&FATTR_ARCH)
 
603
   return(0);
 
604
  if(!matched)
 
605
   return(0);
 
606
 }
 
607
 if(filter_fa_arch==FAA_BACKUP||filter_fa_arch==FAA_BACKUP_CLEAR)
 
608
 {
 
609
  if(!properties->isarchive)
 
610
   return(0);
 
611
 }
 
612
 /* Now, check the file against the time limits for it */
 
613
 /* ftime */
 
614
 if(ts_valid(tested_ftime_newer)&&(filter_same_or_newer==TCHECK_NDAYS||filter_same_or_newer==TCHECK_FTIME))
 
615
 {
 
616
  if(properties->ftime<ts_native(&tested_ftime_newer, OS))
 
617
   return(0);
 
618
 }
 
619
 if(ts_valid(tested_ftime_older)&&(filter_older==TCHECK_NDAYS||filter_older==TCHECK_FTIME))
 
620
 {
 
621
  if(properties->ftime>=ts_native(&tested_ftime_older, OS))
 
622
   return(0);
 
623
 }
 
624
 /* ctime */
 
625
 if(ts_valid(tested_ftime_newer)&&filter_same_or_newer==TCHECK_CTIME)
 
626
 {
 
627
  if(properties->ctime<ts_native(&tested_ftime_newer, OS))
 
628
   return(0);
 
629
 }
 
630
 if(ts_valid(tested_ftime_older)&&filter_older==TCHECK_CTIME)
 
631
 {
 
632
  if(properties->ctime>=ts_native(&tested_ftime_older, OS))
 
633
   return(0);
 
634
 }
 
635
 /* atime */
 
636
 if(ts_valid(tested_ftime_newer)&&filter_same_or_newer==TCHECK_ATIME)
 
637
 {
 
638
  if(properties->atime<ts_native(&tested_ftime_newer, OS))
 
639
   return(0);
 
640
 }
 
641
 if(ts_valid(tested_ftime_older)&&filter_older==TCHECK_ATIME)
 
642
 {
 
643
  if(properties->atime>=ts_native(&tested_ftime_older, OS))
 
644
   return(0);
 
645
 }
 
646
 return(1);
 
647
}
 
648
 
 
649
/* Frees memory allocated for the hash table */
 
650
 
 
651
void flist_cleanup(struct flist_root *root)
 
652
{
 
653
 flist_cleanup_proc(root);
 
654
}
 
655
 
 
656
/* Adds an entry to the filelist if it does not already exist. Returns -1 if
 
657
   an error occured. */
 
658
 
 
659
int flist_add(struct flist_root *root, struct flist_root *search_flist, char *name, FILE_COUNT *count, struct file_properties *properties)
 
660
{
 
661
 FILE_COUNT i;
 
662
 
 
663
 if(search_flist!=NULL)
 
664
 {
 
665
  /* If an existing entry has been found, don't add anything */
 
666
  if(flist_find(search_flist, name))
 
667
  {
 
668
   if(count!=NULL)
 
669
    (*count)++;
 
670
   return(0);
 
671
  }
 
672
 }
 
673
 if(root!=NULL&&root->fsptr!=NULL&&!xwild_compare(root->fsptr, name))
 
674
 {
 
675
  if(count!=NULL)
 
676
   (*count)++;
 
677
  return(0);
 
678
 }
 
679
 if(properties!=NULL&&root==&flist_main&&!match_attrib(properties))
 
680
 {
 
681
  if(count!=NULL)
 
682
   (*count)++;
 
683
  return(0);
 
684
 }
 
685
 #if TARGET==UNIX
 
686
  /* Resolve hard links if there are any */
 
687
  if(properties!=NULL&&
 
688
     properties->l_search.refcount>1&&
 
689
     !suppress_hardlinks)
 
690
   link_search(&l_entries, &properties->l_search, properties, root->files);
 
691
 #endif
 
692
 return(add_entry(root, name, count, properties));
 
693
}
 
694
 
 
695
/* Initializes the filelist storage structures */
 
696
 
 
697
void flist_init(struct flist_root *root, FILE_COUNT maxfiles, char type)
 
698
{
 
699
 flist_init_proc(root, maxfiles, type);
 
700
}
 
701
 
 
702
/* Retrieves an entry from the filelist */
 
703
 
 
704
void flist_retrieve(char *dest, struct file_properties *properties, struct flist_root *root, FILE_COUNT entry)
 
705
{
 
706
 retrieve_entry(dest, properties, root, entry);
 
707
}
 
708
 
 
709
/* Converts an extended wildcard to canonical wildcard */
 
710
 
 
711
static void xwild_to_canonical(char *name)
 
712
{
 
713
 char *tmp_name;
 
714
 char *xwptr;
 
715
 int entry;
 
716
 
 
717
 tmp_name=malloc_str(name);
 
718
 xwptr=strpbrk(tmp_name, xwild_symbols);
 
719
 if(xwptr!=NULL)
 
720
 {
 
721
  *(xwptr+1)='\0';
 
722
  entry=split_name(tmp_name, NULL, NULL);
 
723
  if(entry>0)
 
724
  {
 
725
   tmp_name[entry-1]='\0';
 
726
   sprintf(name, "%s%c%s", tmp_name, PATHSEP_DEFAULT, all_wildcard);
 
727
  }
 
728
  else
 
729
   strcpy(name, all_wildcard);
 
730
 }
 
731
 free(tmp_name);
 
732
}
 
733
 
 
734
#endif
 
735
 
 
736
#if SFX_LEVEL>=ARJSFXV
 
737
 
 
738
/* Expands wildcards and prepares a file list */
 
739
 
 
740
int flist_add_files(struct flist_root *root, struct flist_root *search_flist, char *name, int expand_wildcards, int recurse_subdirs, int file_type, FILE_COUNT *count)
 
741
{
 
742
 int result;
 
743
 char *tmp_name;
 
744
 #if SFX_LEVEL>=ARJ
 
745
  int parse_rc;
 
746
 #endif
 
747
 
 
748
 #if SFX_LEVEL>=ARJ
 
749
  if(expand_wildcards&&marksym_expansion&&xwild_lookup(name)==XW_OK&&
 
750
     xwild_parser(name, &parse_rc)==XW_OK)
 
751
  {
 
752
   /* ASR fix for variable all_wildcard length follows: */
 
753
   tmp_name=(char *)malloc_msg(strlen(name)+strlen(all_wildcard)+1);
 
754
   strcpy(tmp_name, name);
 
755
   root->fsptr=malloc_str(tmp_name);
 
756
   xwild_to_canonical(tmp_name);
 
757
   result=wild_list(root, search_flist, tmp_name, expand_wildcards, recurse_subdirs, file_type, count);
 
758
   root->no_dupl=1;
 
759
   free(tmp_name);
 
760
  }
 
761
  else
 
762
  {
 
763
   result=wild_list(root, search_flist, name, expand_wildcards, recurse_subdirs, file_type, count);
 
764
   root->no_dupl=1;
 
765
  }
 
766
 #else
 
767
  if((tmp_name=(char *)malloc(strlen(name)+1))==NULL)
 
768
  {
 
769
   msg_cprintf(0, M_HASH_MEM_LACK, name);
 
770
   result=-1;
 
771
  }
 
772
  else
 
773
  {
 
774
   result=0;
 
775
   strcpy(tmp_name, name);
 
776
   case_path(tmp_name);
 
777
   if(add_entry(root, search_flist, tmp_name, count))
 
778
    result=-1;
 
779
   free(tmp_name);
 
780
  }
 
781
 #endif
 
782
 return(result);
 
783
}
 
784
 
 
785
#if SFX_LEVEL>=ARJSFXV
 
786
 
 
787
/* Returns pointer to the idx-th element, enlarging the CFA if required */
 
788
 
 
789
static unsigned char FAR *cfa_get_index(FILE_COUNT idx)
 
790
{
 
791
 FILE_COUNT fblock;
 
792
 
 
793
 if(flist_array==NULL)
 
794
  cfa_allocated=0L;
 
795
 fblock=idx/CFA_BLOCK_SIZE;
 
796
 /* Enlarge the CFA */
 
797
 if(fblock>=cfa_allocated)
 
798
 {
 
799
  flist_array=(unsigned char FAR * FAR *)
 
800
              farrealloc_msg(
 
801
               flist_array,
 
802
               (fblock+1)*sizeof(char FAR *)
 
803
              );
 
804
  while(cfa_allocated<=fblock)
 
805
   flist_array[cfa_allocated++]=NULL;
 
806
 }
 
807
 /* Allocate a new block if it has been empty before */
 
808
 if(flist_array[fblock]==NULL)
 
809
  flist_array[fblock]=(char FAR *)farmalloc_msg((CFA_BLOCK_SIZE+3)>>2);
 
810
 return(flist_array[fblock]+((idx%CFA_BLOCK_SIZE)>>2));
 
811
}
 
812
 
 
813
/* Releases the CFA structure */
 
814
 
 
815
void cfa_shutdown()
 
816
{
 
817
 unsigned long i;
 
818
 
 
819
 if(flist_array!=NULL)
 
820
 {
 
821
  for(i=0; i<cfa_allocated; i++)
 
822
  {
 
823
   if(flist_array[i]!=NULL)
 
824
   {
 
825
    farfree(flist_array[i]);
 
826
    flist_array[i]=NULL;
 
827
   }
 
828
  }
 
829
  farfree(flist_array);
 
830
  flist_array=NULL;
 
831
 }
 
832
}
 
833
 
 
834
/* Retrieves a CFA element */
 
835
 
 
836
int cfa_get(FILE_COUNT num)
 
837
{
 
838
 int pos_num;
 
839
 unsigned char bit_mask, value_bits;
 
840
 
 
841
 pos_num=(int)(num%4)<<1;
 
842
 bit_mask=(unsigned char)3<<pos_num;
 
843
 value_bits=*cfa_get_index(num)&bit_mask;
 
844
 return(value_bits>>pos_num);
 
845
}
 
846
 
 
847
/* Stores an element in the CFA */
 
848
 
 
849
void cfa_store(FILE_COUNT num, int value)
 
850
{
 
851
 int pos_num;
 
852
 unsigned char bit_mask, value_bits;
 
853
 unsigned char FAR *p;
 
854
 
 
855
 pos_num=(int)(num%4)<<1;
 
856
 bit_mask=(unsigned char)3<<pos_num;
 
857
 value_bits=(unsigned char)value<<pos_num;
 
858
 p=cfa_get_index(num);
 
859
 *p=(*p&=~bit_mask)|value_bits;
 
860
}
 
861
 
 
862
/* Initializes the CFA structures */
 
863
 
 
864
int cfa_init(FILE_COUNT capacity)
 
865
{
 
866
 unsigned long bytes;
 
867
 FILE_COUNT i;
 
868
 
 
869
 bytes=(unsigned long)capacity>>2;
 
870
 flist_array=farmalloc_msg(bytes+1);
 
871
 for(i=0; i<capacity; i++)
 
872
  cfa_store(i, FLFLAG_TO_PROCESS);
 
873
 return(0);                             /* ASR fix for High C -- 01/04/2001 */
 
874
}
 
875
 
 
876
#endif
 
877
 
 
878
/* Allocates a block of memory, executes error stub if failed */
 
879
 
 
880
void *malloc_msg(unsigned int size)
 
881
{
 
882
 void *tmp;
 
883
 
 
884
 #ifdef DEBUG
 
885
  if(debug_enabled&&strchr(debug_opt, 'm')!=NULL)
 
886
   printf("(Nm%u", size);
 
887
 #endif
 
888
 if((tmp=malloc(size))==NULL)
 
889
  error(M_OUT_OF_NEAR_MEMORY);
 
890
 #ifdef DEBUG
 
891
  if(debug_enabled&&strchr(debug_opt, 'm')!=NULL)
 
892
   printf(")");
 
893
 #endif
 
894
 return(tmp);
 
895
}
 
896
 
 
897
#endif
 
898
 
 
899
#if SFX_LEVEL>=ARJSFXV||defined(ARJUTIL)
 
900
 
 
901
/* Allocates a block of far memory, executes error stub if failed.
 
902
   Implementation-dependent (farmalloc for Borland, _fmalloc for MS C) */
 
903
 
 
904
void FAR *farmalloc_msg(unsigned long size)
 
905
{
 
906
 void FAR *tmp;
 
907
 
 
908
 #if defined(DEBUG)&&!defined(ARJUTIL)
 
909
  if(debug_enabled&&strchr(debug_opt, 'm')!=NULL)
 
910
   printf("(Fm%u", size);
 
911
 #endif
 
912
 if((tmp=farmalloc(size))==NULL)
 
913
  #ifdef ARJUTIL
 
914
   {
 
915
    printf("Failed to farmalloc(%lu)\n", size);
 
916
    exit(1);
 
917
   }
 
918
  #else
 
919
   error(M_OUT_OF_MEMORY);
 
920
  #endif
 
921
 #if defined(DEBUG)&&!defined(ARJUTIL)
 
922
  if(debug_enabled&&strchr(debug_opt, 'm')!=NULL)
 
923
   printf(")");
 
924
 #endif
 
925
 return(tmp);
 
926
}
 
927
 
 
928
#endif
 
929
 
 
930
#if SFX_LEVEL>=ARJSFX
 
931
 
 
932
/* Reallocates a block of far memory, executes error stub if failed.
 
933
   Implementation-dependent (farrealloc for Borland, _frealloc for MS C) */
 
934
 
 
935
void FAR *farrealloc_msg(void FAR *memblock, unsigned long size)
 
936
{
 
937
 void FAR *tmp;
 
938
 
 
939
 if((tmp=farrealloc(memblock, size))==NULL)
 
940
  error(M_OUT_OF_MEMORY);
 
941
 return(tmp);
 
942
}
 
943
 
 
944
#endif
 
945
 
 
946
#ifdef REARJ
 
947
 
 
948
/* Replaces all LF characters with 0's, returning the end of string */
 
949
 
 
950
char *tokenize_lf(char *str)
 
951
{
 
952
 while(*str!='\0')
 
953
 {
 
954
  if(*str=='\n')
 
955
   *str='\0';
 
956
  str++;
 
957
 }
 
958
 return(str);
 
959
}
 
960
 
 
961
#endif