~ubuntu-branches/ubuntu/precise/unzip/precise-proposed

« back to all changes in this revision

Viewing changes to tandem/tandem.c

  • Committer: Bazaar Package Importer
  • Author(s): Santiago Vila
  • Date: 2004-06-06 17:57:46 UTC
  • Revision ID: james.westby@ubuntu.com-20040606175746-nl7p2dgp3aobyc2c
Tags: upstream-5.51
ImportĀ upstreamĀ versionĀ 5.51

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 <tal.h>
 
16
#include "$system.zsysdefs.zsysc" nolist
 
17
#include <cextdecs> 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 */