Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
6725 siemargl 1
/*
2
  Copyright (c) 1990-2002 Info-ZIP.  All rights reserved.
3
 
4
  See the accompanying file LICENSE, version 2000-Apr-09 or later
5
  (the contents of which are also included in zip.h) for terms of use.
6
  If, for some reason, all these files are missing, the Info-ZIP license
7
  also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
8
*/
9
/*
10
 * routines common to TANDEM (ZIP and UNZIP)
11
 */
12
 
13
#include "zip.h"   /* This sets up ZIP / UNZIP define */
14
 
15
#include 
16
#include "$system.zsysdefs.zsysc" nolist
17
#include  nolist
18
#include "tannsk.h"
19
 
20
static time_t gmt_to_time_t (long long *);
21
 
22
int isatty (fnum)
23
int fnum;
24
{
25
  return 1;
26
}
27
 
28
/********************/
29
/* Function in2ex() */
30
/********************/
31
 
32
#ifdef UNZIP
33
char *in2ex(__G__ n)
34
  __GDEF
35
#else
36
char *in2ex(n)
37
#endif
38
  char *n;              /* internal file name */
39
/* Convert the zip file name to an external file name, returning the malloc'ed
40
   string or NULL if not enough memory. */
41
{
42
  char *x;              /* external file name buffer */
43
  char *y;              /* pointer to external buffer */
44
  char *max;            /* pointer to max end of next file part */
45
  char *t;              /* pointer to internal - start of substring */
46
  char *p;              /* pointer to internal - TANDEM delimiter */
47
  char *e;              /* pointer to internal - DOS extension delimiter */
48
  char *z;              /* pointer to internal - end of substring */
49
  int len;              /* length of substring to copy to external name */
50
  int allow_dollar;     /* $ symbol allowed as next character */
51
 
52
  if ((x = malloc(strlen(n) + 4)) == NULL)  /* + 4 for safety */
53
    return NULL;
54
 
55
  *x = '\0';
56
 
57
  /* Junk pathname as requested */
58
#ifdef UNZIP
59
  if (uO.jflag && (t = strrchr(n, INTERNAL_DELIMITER)) != NULL)
60
    ++t;
61
  else
62
    t = n;
63
#endif /* UNZIP */
64
#ifdef ZIP
65
  if (!pathput)
66
    t = last(n, INTERNAL_DELIMITER);
67
  else
68
    t = n;
69
#endif /* ZIP */
70
 
71
  allow_dollar = TRUE;
72
 
73
  while (*t != '\0') {  /* File part could be sys, vol, subvol or file */
74
    if (*t == INTERNAL_DELIMITER) {    /* System, Volume or Subvol Name */
75
      t++;
76
      if (*t == INTERNAL_DELIMITER) {  /* System */
77
        strcat(x, TANDEM_NODE_STR);
78
        t++;
79
      }
80
      else {
81
        strcat(x, TANDEM_DELIMITER_STR);
82
        allow_dollar = FALSE;
83
      }
84
    }
85
    /* Work out where end of current external string is */
86
    y = x + strlen(x);
87
 
88
    /* Work out substring to copy and externalise */
89
    p = strchr(t, INTERNAL_DELIMITER);
90
    e = strchr(t, DOS_EXTENSION);
91
    if (p != NULL) {
92
      if (e > p)
93
        e = NULL;
94
    }
95
 
96
    z = e;
97
    if (z == NULL)
98
      z = p;
99
    if (z == NULL)
100
      z = t + strlen(t);
101
 
102
    /* can't have Tandem name longer than 8 characters */
103
    max = y + MAXFILEPARTLEN;
104
 
105
    /* Allow $ symbol as first character in some cases */
106
    if (*t == '$') {
107
      if (allow_dollar)
108
        *y++ = *t++;
109
      else;
110
        *t++;
111
    }
112
 
113
    /* Make sure first real character is alpha */
114
    if (! isalpha(*t) )
115
      *y++ = 'A';
116
 
117
    /* Characters left to process */
118
    len = z - t;
119
 
120
    while ( len > 0 ) {
121
      if ( isalnum(*t) ) {
122
        *y++ = toupper(*t++);
123
        if (y >= max)
124
          break;
125
      }
126
      else
127
        t++;
128
      len--;
129
    }
130
    *y = '\0';
131
    t = p;
132
 
133
    if (p == NULL) {
134
      /* Last part of filename, store pseudo extension if available */
135
      if (e != NULL) {
136
        strcat(x, TANDEM_EXTENSION_STR);
137
        y = x + strlen(x);
138
 
139
        /* no restriction on extension length as its virtual */
140
        z = e + 1;
141
        while ( *z != '\0' ) {
142
          *y++ = toupper(*z++);
143
        }
144
        *y = '\0';
145
      }
146
      break;
147
    }
148
  }
149
 
150
  return x;
151
}
152
 
153
void zexit(status)
154
  int status;
155
{
156
  /* Exit(>0) creates saveabend files */
157
  terminate_program (0,0,(short)status,,,);
158
}
159
 
160
/************************/
161
/*  Function zputc()    */
162
/************************/
163
 
164
#ifdef putc
165
#  undef putc
166
#endif
167
 
168
int zputc(ch, fptr)
169
  int ch;
170
  FILE *fptr;
171
{
172
  int err;
173
  err = putc(ch,fptr);
174
  fflush(fptr);
175
  return err;
176
}
177
#define putc zputc
178
 
179
#ifdef LICENSED
180
_tal _priv short FILE_CHANGELABEL_ (
181
 short,          /* IN */
182
 short,          /* IN */
183
 const short _far *    /* IN */
184
 );
185
 
186
_c _callable int changelabel OF((short, const short *, const short *));
187
 
188
_c _callable int changelabel(fnum, modtime, actime)
189
  short fnum;
190
  const short *modtime;
191
  const short *actime;
192
{
193
  int err;
194
 
195
  err = FILE_CHANGELABEL_(fnum, 16, modtime);
196
  if (!err)
197
    err = FILE_CHANGELABEL_(fnum, 17, actime);
198
  return err;
199
}
200
 
201
int islicensed(void)
202
{
203
  #define plist_items 1
204
  #define plist_size 10
205
 
206
  short myphandle[ZSYS_VAL_PHANDLE_WLEN];
207
  short licensetag[plist_items] = {37};
208
  short licensed[plist_size];
209
  short maxlen = plist_size;
210
  short items = plist_items;
211
  short resultlen[1], err;
212
 
213
  err = PROCESSHANDLE_NULLIT_(myphandle);
214
 
215
  if (!err)
216
    err = PROCESS_GETINFO_(myphandle);
217
 
218
  if (!err)
219
    err = PROCESS_GETINFOLIST_(/*cpu*/,
220
                               /*pin*/,
221
                               /*nodename*/,
222
                               /*nodenamelen*/,
223
                               myphandle,
224
                               licensetag,
225
                               items,
226
                               licensed,
227
                               maxlen,
228
                               resultlen
229
                              );
230
 
231
  if (err != 0)
232
    return 0;
233
  else
234
    return licensed[0];
235
}
236
#endif /* LICENSED */
237
 
238
int utime(file, time)
239
  const char *file;
240
  const ztimbuf *time;
241
{
242
#ifdef LICENSED
243
  int result, err;
244
  union timestamp_ov {
245
    long long fulltime;
246
    short wordtime[4];
247
  };
248
  union timestamp_ov lasttime, opentime;
249
  struct tm *modt, *opent;
250
  short datetime[8], errormask[1];
251
  short len, fnum, access, exclus, options;
252
  char fname[FILENAME_MAX + 1];
253
  short extension;
254
  char ext[EXTENSION_MAX + 1];
255
 
256
  if (islicensed() ) {
257
    /* Attempt to update file label */
258
    modt = gmtime( &time->modtime );
259
 
260
    datetime[0] = modt->tm_year + 1900;
261
    datetime[1] = modt->tm_mon + 1;
262
    datetime[2] = modt->tm_mday;
263
    datetime[3] = modt->tm_hour;
264
    datetime[4] = modt->tm_min;
265
    datetime[5] = modt->tm_sec;
266
    datetime[6] = datetime[7] = 0;
267
    errormask[0] = 0;
268
    lasttime.fulltime = COMPUTETIMESTAMP (datetime, errormask);
269
 
270
    opent = gmtime( &time->actime );
271
 
272
    datetime[0] = opent->tm_year + 1900;
273
    datetime[1] = opent->tm_mon + 1;
274
    datetime[2] = opent->tm_mday;
275
    datetime[3] = opent->tm_hour;
276
    datetime[4] = opent->tm_min;
277
    datetime[5] = opent->tm_sec;
278
    datetime[6] = datetime[7] = 0;
279
    errormask[0] = 0;
280
    opentime.fulltime = COMPUTETIMESTAMP (datetime, errormask);
281
 
282
    /* Remove any (pseudo) file extension */
283
    extension = parsename (file,fname,ext);
284
    len = strlen(fname);
285
 
286
    access = NSK_WRONLY;
287
    exclus = NSK_SHARED;
288
    options = NSK_NOUPDATEOPENTIME;
289
 
290
    extension = parsename (file,fname,ext);
291
    len = strlen(fname);
292
 
293
    err = FILE_OPEN_((char *)fname, len, &fnum, access, exclus,,,options,,,);
294
    result = changelabel(fnum,lasttime.wordtime,opentime.wordtime);
295
    err = FILE_CLOSE_(fnum);
296
    return result;
297
  }
298
  return -1;
299
#else  /* !LICENSED */
300
  return 0;             /* "no error", to suppress annoying failure messages */
301
#endif  /* ?LICENSED */
302
}
303
 
304
/* TANDEM version of chmod() function */
305
 
306
int chmod(file, unix_sec)
307
  const char *file;
308
  mode_t unix_sec;
309
{
310
  FILE *stream;
311
  struct nsk_sec_type {
312
    unsigned progid : 1;
313
    unsigned clear  : 1;
314
    unsigned null   : 2;
315
    unsigned read   : 3;
316
    unsigned write  : 3;
317
    unsigned execute: 3;
318
    unsigned purge  : 3;
319
  };
320
  union nsk_sec_ov {
321
    struct nsk_sec_type bit_ov;
322
    short int_ov;
323
  };
324
  union nsk_sec_ov nsk_sec;
325
  short fnum, err, nsk_sec_int;
326
  short len, access, exclus, extension, options;
327
  char fname[FILENAME_MAX + 1];
328
  char ext[EXTENSION_MAX + 1];
329
 
330
  nsk_sec.bit_ov.progid = 0;
331
  nsk_sec.bit_ov.clear  = 0;
332
  nsk_sec.bit_ov.null   = 0;
333
 
334
  /*  4="N", 5="C", 6="U", 7="-"   */
335
 
336
  if (unix_sec & S_IROTH) nsk_sec.bit_ov.read = 4;
337
  else if (unix_sec & S_IRGRP) nsk_sec.bit_ov.read = 5;
338
  else if (unix_sec & S_IRUSR) nsk_sec.bit_ov.read = 6;
339
  else nsk_sec.bit_ov.read = 7;
340
 
341
  if (unix_sec & S_IWOTH) nsk_sec.bit_ov.write = 4;
342
  else if (unix_sec & S_IWGRP) nsk_sec.bit_ov.write = 5;
343
  else if (unix_sec & S_IWUSR) nsk_sec.bit_ov.write = 6;
344
  else nsk_sec.bit_ov.write = 7;
345
 
346
  if (unix_sec & S_IXOTH) nsk_sec.bit_ov.execute = 4;
347
  else if (unix_sec & S_IXGRP) nsk_sec.bit_ov.execute = 5;
348
  else if (unix_sec & S_IXUSR) nsk_sec.bit_ov.execute = 6;
349
  else nsk_sec.bit_ov.execute = 7;
350
 
351
  nsk_sec.bit_ov.purge = nsk_sec.bit_ov.write;
352
 
353
  nsk_sec_int = nsk_sec.int_ov;
354
 
355
  access = NSK_RDONLY;
356
  exclus = NSK_SHARED;
357
  options = NSK_NOUPDATEOPENTIME;
358
 
359
  extension = parsename (file,fname,ext);
360
  len = strlen(fname);
361
 
362
  err = FILE_OPEN_((char *)fname, len, &fnum, access, exclus,,,options,,,);
363
  err = (SETMODE(fnum, SET_FILE_SECURITY, nsk_sec_int) != CCE);
364
  err = FILE_CLOSE_(fnum);
365
 
366
  return (err != 0 ? -1 : 0);
367
}
368
 
369
/* TANDEM version of chown() function */
370
 
371
int chown(file, uid, gid)
372
  const char *file;
373
  uid_t uid;
374
  gid_t gid;
375
{
376
  FILE *stream;
377
  struct nsk_own_type {
378
    unsigned group  : 8;
379
    unsigned user   : 8;
380
  };
381
  union nsk_own_ov {
382
    struct nsk_own_type bit_ov;
383
    short int_ov;
384
  };
385
  union nsk_own_ov nsk_own;
386
  short fnum, err, nsk_own_int;
387
  short len, access, exclus, extension, options;
388
  char fname[FILENAME_MAX + 1];
389
  char ext[EXTENSION_MAX + 1];
390
 
391
  nsk_own.bit_ov.group = gid;
392
  nsk_own.bit_ov.user  = uid;
393
 
394
  nsk_own_int = nsk_own.int_ov;
395
 
396
  access = NSK_RDONLY;
397
  exclus = NSK_SHARED;
398
  options = NSK_NOUPDATEOPENTIME;
399
 
400
  extension = parsename (file,fname,ext);
401
  len = strlen(fname);
402
 
403
  err = FILE_OPEN_((char *)fname, len, &fnum, access, exclus,,,options,,,);
404
  err = (SETMODE(fnum, SET_FILE_OWNER, nsk_own_int) != CCE);
405
  err = FILE_CLOSE_(fnum);
406
  return (err != 0 ? -1 : 0);
407
}
408
 
409
/* TANDEM version of getch() - non-echo character reading */
410
int zgetch(void)
411
{
412
  char ch;
413
  short f, err, count, fnum, rlen;
414
 
415
  rlen = 1;
416
  f = (short)fileno(stdin);
417
  fnum = fdtogfn (f);
418
  #define ECHO_MODE 20
419
  err = (SETMODE(fnum, ECHO_MODE, 0) != CCE);
420
  err = (READX(fnum, &ch, rlen, (short *) &count) != CCE);
421
  err = (SETMODE(fnum, ECHO_MODE, 1) != CCE);
422
 
423
  if (err)
424
    if (err != 1)
425
      return EOF;
426
    else
427
      ch = 'q';
428
  else
429
    if (count == 0)
430
      ch = '\r';
431
 
432
  return (int)ch;
433
}
434
 
435
short parsename(srce, fname, ext)
436
  const char *srce;
437
  char *fname;
438
  char *ext;
439
{
440
  /* As a way of supporting DOS extensions from Tandem we look for a space
441
     separated extension string after the Guardian filename
442
     e.g. ZIP ZIPFILE "$DATA4.TESTING.INVOICE TXT"
443
  */
444
 
445
  char *fstart;
446
  char *fptr;
447
  short extension = 0;
448
 
449
  *fname = *ext = '\0';  /* set to null string */
450
 
451
  fstart = (char *) srce;
452
 
453
  if ((fptr = strrchr(fstart, TANDEM_EXTENSION)) != NULL) {
454
    extension = 1;
455
 
456
    fptr++;
457
    strncat(ext, fptr, _min(EXTENSION_MAX, strlen(fptr)));
458
 
459
    fptr = strchr(fstart, TANDEM_EXTENSION);  /* End of filename */
460
    strncat(fname, fstart, _min(FILENAME_MAX, (fptr - fstart)));
461
  }
462
  else {
463
    /* just copy string */
464
    strncat(fname, srce, _min(FILENAME_MAX, strlen(srce)));
465
  }
466
 
467
  return extension;
468
}
469
 
470
static time_t gmt_to_time_t (gmt)
471
  long long *gmt;
472
{
473
  #define GMT_TO_LCT 0
474
  #define GMT_TO_LST 1
475
 
476
  struct tm temp_tm;
477
  short  date_time[8];
478
  long   julian_dayno;
479
  long long lct, lst, itime;
480
  short  err[1], type;
481
 
482
  type = GMT_TO_LCT;
483
  lct = CONVERTTIMESTAMP(*gmt, type,, err);
484
 
485
  if (!err[0]) {
486
    type = GMT_TO_LST;
487
    lst = CONVERTTIMESTAMP(*gmt, type,, err);
488
  }
489
 
490
  itime = (err[0] ? *gmt : lct);
491
  /* If we have no DST in force then make sure we give it a value,
492
     else mktime screws up if we set the isdst flag to -1 */
493
  temp_tm.tm_isdst = (err[0] ? 0 : ((lct == lst) ? 0 : 1));
494
 
495
  julian_dayno = INTERPRETTIMESTAMP(itime, date_time);
496
 
497
  temp_tm.tm_sec   = date_time[5];
498
  temp_tm.tm_min   = date_time[4];
499
  temp_tm.tm_hour  = date_time[3];
500
  temp_tm.tm_mday  = date_time[2];
501
  temp_tm.tm_mon   = date_time[1] - 1;     /* C's so sad */
502
  temp_tm.tm_year  = date_time[0] - 1900;  /* it's almost funny */
503
 
504
  return (mktime(&temp_tm));
505
}
506
 
507
/* TANDEM version of stat() function */
508
int stat(n, s)
509
  const char *n;
510
  struct stat *s;
511
{
512
  #define ilist_items 26
513
  #define klist_items 4
514
  #define slist_items 3
515
  #define ulist_items 1
516
  #define flist_size 100
517
 
518
  short err, i, extension;
519
  char fname[FILENAME_MAX + 1];
520
  short fnamelen;
521
  char ext[EXTENSION_MAX + 1];
522
 
523
                         /* #0  #1  #2  #3  #4  #5  #6  #7  #8  #9 */
524
  short ilist[ilist_items]={56,144, 54,142, 58, 62, 60, 41, 42, 44,
525
                            50, 51, 52, 61, 63, 66, 67, 70, 72, 73,
526
                            74, 75, 76, 77, 78, 79                 };
527
  short ilen[ilist_items] ={ 4,  4,  4,  2,  1,  2,  1,  1,  1,  1,
528
                             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
529
                             1,  1,  1,  1,  1,  1                 };
530
  short ioff[ilist_items];
531
 
532
                         /* #0  #1  #2  #3  #4  #5  #6  #7  #8  #9 */
533
  short klist[klist_items]={45, 46, 68, 69                         };
534
  short klen[klist_items] ={ 1,  1,  1,  1                         };
535
  short koff[klist_items];
536
 
537
                         /* #0  #1  #2  #3  #4  #5  #6  #7  #8  #9 */
538
  short slist[slist_items]={43, 80, 90                             };
539
  short slen[slist_items] ={ 1,  1,  1                             };
540
  short soff[slist_items];
541
 
542
                         /* #0  #1  #2  #3  #4  #5  #6  #7  #8  #9 */
543
  short ulist[ulist_items]={65                                     };
544
  short ulen[ulist_items] ={ 1                                     };
545
  short uoff[ulist_items];
546
 
547
  short flist[flist_size];
548
  short extra[2];
549
  short *rlen=&extra[0];
550
  short *err_item=&extra[1];
551
  unsigned short *fowner;
552
  unsigned short *fprogid;
553
  char *fsec;
554
 
555
  nsk_stat_ov *nsk_ov;
556
  nsk_file_attrs *nsk_attr;
557
 
558
  short end, count, kind, level, options, searchid;
559
  short info[5];
560
 
561
  /* Initialise stat structure */
562
  s->st_dev = _S_GUARDIANOBJECT;
563
  s->st_ino = 0;
564
  s->st_nlink = 0;
565
  s->st_rdev = 0;
566
  s->st_uid = s->st_gid = 0;
567
  s->st_size = 0;
568
  s->st_atime = s->st_ctime = s->st_mtime = 0;
569
  s->st_reserved[0] = 0;
570
  s->st_reserved[1] = 0;
571
  s->st_reserved[2] = 0;
572
  nsk_ov = (nsk_stat_ov *)&s->st_reserved[0];
573
  nsk_attr = (nsk_file_attrs *)&nsk_ov->ov.nsk_ef_region;
574
 
575
  /* Check to see if name contains a (pseudo) file extension */
576
  extension = parsename (n,fname,ext);
577
 
578
  fnamelen = strlen(fname);
579
 
580
  options = 3; /* Allow Subvols and Templates */
581
  err = FILENAME_SCAN_( fname,
582
                        fnamelen,
583
                        &count,
584
                        &kind,
585
                        &level,
586
                        options
587
                      );
588
 
589
  /* allow kind == 2 (DEFINE names) */
590
  if (err != 0) return -1;
591
 
592
  if (kind == 1 || (kind == 0 && level < 2)) {
593
    /* Pattern, Subvol Name or One part Filename - lets see if it exists */
594
    err = FILENAME_FINDSTART_ ( &searchid,
595
                                fname,
596
                                fnamelen,
597
                                ,
598
                                DISK_DEVICE
599
                              );
600
 
601
    if (err != 0) {
602
      end = FILENAME_FINDFINISH_ ( searchid );
603
      return -1;
604
    }
605
 
606
    err = FILENAME_FINDNEXT_ ( searchid,
607
                               fname,
608
                               FILENAME_MAX,
609
                               &fnamelen,
610
                               info
611
                              );
612
    end = FILENAME_FINDFINISH_ ( searchid );
613
 
614
    if (err != 0)
615
      return -1;  /* Non existing template, subvol or file */
616
 
617
    if (kind == 1 || info[2] == -1) {
618
      s->st_mode = S_IFDIR;    /* Its an existing template or directory */
619
      return 0;
620
    }
621
 
622
    /* Must be a real file so drop to code below to get info on it */
623
  }
624
 
625
  err = FILE_GETINFOLISTBYNAME_( fname,
626
                                 fnamelen,
627
                                 ilist,
628
                                 ilist_items,
629
                                 flist,
630
                                 flist_size,
631
                                 rlen,
632
                                 err_item
633
                               );
634
  if (err != 0) return -1;
635
 
636
  ioff[0] = 0;
637
 
638
  /*  Build up table of offets into result list */
639
  for (i=1; i < ilist_items; i++)
640
    ioff[i] = ioff[i-1] + ilen[i-1];
641
 
642
  /* Set up main stat fields */
643
 
644
  /* Setup timestamps */
645
  s->st_atime = gmt_to_time_t ((long long *)&flist[ioff[0]]);
646
  s->st_mtime = s->st_ctime = gmt_to_time_t ((long long *)&flist[ioff[1]]);
647
  nsk_ov->ov.creation_time = gmt_to_time_t ((long long *)&flist[ioff[2]]);
648
 
649
  s->st_size = *(off_t *)&flist[ioff[3]];
650
 
651
  fowner = (unsigned short *)&flist[ioff[4]];
652
  s->st_uid = *fowner & 0x00ff;
653
  s->st_gid = *fowner >> 8;
654
 
655
  /* Note that Purge security (fsec[3]) in NSK has no relevance to stat() */
656
  fsec = (char *)&flist[ioff[5]];
657
  fprogid = (unsigned short *)&flist[ioff[6]];
658
 
659
  s->st_mode = S_IFREG |  /* Regular File */
660
  /*  Parse Read Flag */
661
               ((fsec[0] & 0x03) == 0x00 ? S_IROTH : 0) |
662
               ((fsec[0] & 0x02) == 0x00 ? S_IRGRP : 0) |
663
               ((fsec[0] & 0x03) != 0x03 ? S_IRUSR : 0) |
664
  /*  Parse Write Flag */
665
               ((fsec[1] & 0x03) == 0x00 ? S_IWOTH : 0) |
666
               ((fsec[1] & 0x02) == 0x00 ? S_IWGRP : 0) |
667
               ((fsec[1] & 0x03) != 0x03 ? S_IWUSR : 0) |
668
  /*  Parse Execute Flag */
669
               ((fsec[2] & 0x03) == 0x00 ? S_IXOTH : 0) |
670
               ((fsec[2] & 0x02) == 0x00 ? S_IXGRP : 0) |
671
               ((fsec[2] & 0x03) != 0x03 ? S_IXUSR : 0) |
672
  /*  Parse Progid */
673
               (*fprogid == 1 ? (S_ISUID | S_ISGID) : 0) ;
674
 
675
  /* Set up NSK additional stat fields */
676
  nsk_attr->progid   = (unsigned) flist[ioff[6]];
677
  nsk_attr->filetype = (unsigned) flist[ioff[7]];
678
  nsk_attr->filecode = (unsigned) flist[ioff[8]];
679
  nsk_attr->block    = (unsigned short) flist[ioff[9]];
680
  nsk_attr->priext   = (unsigned short) flist[ioff[10]];
681
  nsk_attr->secext   = (unsigned short) flist[ioff[11]];
682
  nsk_attr->maxext   = (unsigned short) flist[ioff[12]];
683
  nsk_attr->flags.clearonpurge = (unsigned) flist[ioff[13]];
684
  nsk_attr->licensed     = (unsigned) flist[ioff[14]];
685
  nsk_attr->flags.audited      = (unsigned) flist[ioff[15]];
686
  nsk_attr->flags.acompress    = (unsigned) flist[ioff[16]];
687
  nsk_attr->flags.refresheof   = (unsigned) flist[ioff[17]];
688
  nsk_attr->flags.buffered     = (unsigned) (flist[ioff[18]] == 0 ? 1 : 0);
689
  nsk_attr->flags.verified     = (unsigned) flist[ioff[19]];
690
  nsk_attr->flags.serial       = (unsigned) flist[ioff[20]];
691
  nsk_attr->flags.crashopen    = (unsigned) flist[ioff[22]];
692
  nsk_attr->flags.rollforward  = (unsigned) flist[ioff[23]];
693
  nsk_attr->flags.broken       = (unsigned) flist[ioff[24]];
694
  nsk_attr->flags.corrupt      = (unsigned) flist[ioff[25]];
695
  nsk_attr->fileopen     = (unsigned) flist[ioff[21]];
696
 
697
 
698
  if (nsk_attr->filetype == NSK_UNSTRUCTURED) {
699
    /* extra info for Unstructured files */
700
    err = FILE_GETINFOLISTBYNAME_( fname,
701
                                   fnamelen,
702
                                   ulist,
703
                                   ulist_items,
704
                                   flist,
705
                                   flist_size,
706
                                   rlen,
707
                                   err_item
708
                                 );
709
    if (err != 0) return -1;
710
 
711
    uoff[0] = 0;
712
 
713
    /*  Build up table of offets into result list */
714
    for (i=1; i < ulist_items; i++)
715
      uoff[i] = uoff[i-1] + ulen[i-1];
716
  }
717
  else {
718
    /* extra info for Structured files */
719
    err = FILE_GETINFOLISTBYNAME_( fname,
720
                                   fnamelen,
721
                                   slist,
722
                                   slist_items,
723
                                   flist,
724
                                   flist_size,
725
                                   rlen,
726
                                   err_item
727
                                 );
728
    if (err != 0) return -1;
729
 
730
    soff[0] = 0;
731
 
732
    /*  Build up table of offets into result list */
733
    for (i=1; i < slist_items; i++)
734
      soff[i] = soff[i-1] + slen[i-1];
735
 
736
    nsk_attr->reclen   = (unsigned) flist[soff[0]];
737
    nsk_attr->flags.secpart   = (unsigned) flist[soff[1]];
738
    nsk_attr->flags.primpart  = (unsigned)
739
     ( (flist[soff[2]] > 0 && nsk_attr->flags.secpart == 0) ? 1 : 0 );
740
 
741
    if (nsk_attr->filetype == NSK_KEYSEQUENCED) {
742
      /* extra info for Key Sequenced files */
743
      err = FILE_GETINFOLISTBYNAME_( fname,
744
                                     fnamelen,
745
                                     klist,
746
                                     klist_items,
747
                                     flist,
748
                                     flist_size,
749
                                     rlen,
750
                                     err_item
751
                                   );
752
      if (err != 0) return -1;
753
 
754
      koff[0] = 0;
755
 
756
      /*  Build up table of offets into result list */
757
      for (i=1; i < klist_items; i++)
758
        koff[i] = koff[i-1] + klen[i-1];
759
 
760
      nsk_attr->keyoff   = (unsigned) flist[koff[0]];
761
      nsk_attr->keylen   = (unsigned) flist[koff[1]];
762
      nsk_attr->flags.dcompress = (unsigned) flist[koff[2]];
763
      nsk_attr->flags.icompress = (unsigned) flist[koff[3]];
764
    }
765
  }
766
 
767
  return 0;
768
}
769
 
770
#ifndef SFX
771
/* TANDEM Directory processing */
772
 
773
DIR *opendir(const char *dirname)
774
{
775
   short i, resolve;
776
   char sname[FILENAME_MAX + 1];
777
   short snamelen;
778
   char fname[FILENAME_MAX + 1];
779
   short fnamelen;
780
   char *p;
781
   short searchid, err, end;
782
   struct dirent *entry;
783
   DIR *dirp;
784
   char ext[EXTENSION_MAX + 1];
785
   short extension;
786
 
787
   extension = parsename(dirname, sname, ext);
788
   snamelen = strlen(sname);
789
 
790
   /*  First we work out how detailed the template is...
791
    *  e.g. If the template is DAVES*.* we want the search result
792
    *       in the same format
793
    */
794
 
795
   p = sname;
796
   i = 0;
797
   while ((p = strchr(p, TANDEM_DELIMITER)) != NULL){
798
     i++;
799
     p++;
800
   };
801
   resolve = 2 - i;
802
 
803
   /*  Attempt to start a filename template */
804
   err = FILENAME_FINDSTART_ ( &searchid,
805
                               sname,
806
                               snamelen,
807
                               resolve,
808
                               DISK_DEVICE
809
                             );
810
   if (err != 0) {
811
     end = FILENAME_FINDFINISH_(searchid);
812
     return NULL;
813
   }
814
 
815
   /* Create DIR structure */
816
   if ((dirp = malloc(sizeof(DIR))) == NULL ) {
817
     end = FILENAME_FINDFINISH_(searchid);
818
     return NULL;
819
   }
820
   dirp->D_list = dirp->D_curpos = NULL;
821
   strcpy(dirp->D_path, dirname);
822
 
823
   while ((err = FILENAME_FINDNEXT_(searchid,
824
                                    fname,
825
                                    FILENAME_MAX,
826
                                    &fnamelen
827
                                   )
828
           ) == 0 ){
829
     /*  Create space for entry */
830
     if ((entry = malloc (sizeof(struct dirent))) == NULL) {
831
       end = FILENAME_FINDFINISH_(searchid);
832
       return NULL;
833
     }
834
 
835
     /*  Link to last entry */
836
     if (dirp->D_curpos == NULL)
837
       dirp->D_list = dirp->D_curpos = entry;  /* First name */
838
     else {
839
       dirp->D_curpos->d_next = entry;         /* Link */
840
       dirp->D_curpos = entry;
841
     };
842
     /* Add directory entry */
843
     *dirp->D_curpos->d_name = '\0';
844
     strncat(dirp->D_curpos->d_name,fname,fnamelen);
845
     if (extension) {
846
       strcat(dirp->D_curpos->d_name,TANDEM_EXTENSION_STR);
847
       strcat(dirp->D_curpos->d_name,ext);
848
     };
849
     dirp->D_curpos->d_next = NULL;
850
   };
851
 
852
   end = FILENAME_FINDFINISH_(searchid);
853
 
854
   if (err == 1) {  /*  Should return EOF at end of search */
855
     dirp->D_curpos = dirp->D_list;        /* Set current pos to start */
856
     return dirp;
857
   }
858
   else
859
     return NULL;
860
}
861
 
862
struct dirent *readdir(DIR *dirp)
863
{
864
   struct dirent *cur;
865
 
866
   cur = dirp->D_curpos;
867
   dirp->D_curpos = dirp->D_curpos->d_next;
868
   return cur;
869
}
870
 
871
void rewinddir(DIR *dirp)
872
{
873
   dirp->D_curpos = dirp->D_list;
874
}
875
 
876
int closedir(DIR *dirp)
877
{
878
   struct dirent *node;
879
 
880
   while (dirp->D_list != NULL) {
881
      node = dirp->D_list;
882
      dirp->D_list = dirp->D_list->d_next;
883
      free( node );
884
   }
885
   free( dirp );
886
   return 0;
887
}
888
 
889
#endif /* !SFX */