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 only used by TANDEM ZIP
11  */
12 
13 #include "zip.h"
14 #include "crypt.h"
15 #include <tal.h>
16 #include "$system.zsysdefs.zsysc" nolist
17 #include <cextdecs> nolist
18 #include "tannsk.h"
19 
20 /******************************/
21 /*  Function version_local()  */
22 /******************************/
23 
version_local()24 void version_local()
25 {
26     static ZCONST char CompiledWith[] = "Compiled with %s%s for %s%s%s%s.\n\n";
27 #if 0
28     char buf[40];
29 #endif
30 
31     printf(CompiledWith,
32 
33 #ifdef __GNUC__
34       "gcc ", __VERSION__,
35 #else
36      "C ", "T9255D44 - (16OCT98)",
37 #endif
38 
39      "NonStop ", "(Tandem/NSK)",
40 
41 #ifdef __DATE__
42       " on ", __DATE__
43 #else
44       "", ""
45 #endif
46       );
47 
48 } /* end function version_local() */
49 
50 
51 /************************/
52 /*  Function nskopen()  */
53 /************************/
54 
55 #ifdef fopen
56 #  undef fopen
57 #endif
58 
nskopen(fname,opt)59 FILE *nskopen(fname, opt)
60 const char *fname;
61 const char *opt;
62 {
63   int fdesc;
64   short fnum, err, len;
65   int priext, secext;
66   short maxext, filecode, blocksize;
67 
68   #define alist_items 1
69   #define vlist_bytes 2
70   short alist[alist_items]={42};
71   unsigned short vlist[alist_items];
72   short extra, *err_item=&extra;
73 
74   char nsk_work[FILENAME_MAX + 1], *nsk_fname=&nsk_work[0];
75 
76   /* See if we want to create a new file */
77   if ((strcmp(opt,FOPW) == 0) || (strcmp(opt,FOPWT) == 0)) {
78     blocksize = TANDEM_BLOCKSIZE;
79     priext = 100;
80     secext = 500;
81     maxext = 978;
82     filecode = NSK_ZIPFILECODE;
83 
84     if ((fdesc = creat(fname,,priext,secext)) != -1){
85       fnum = fdtogfn ((short)fdesc);
86       err = (SETMODE (fnum, SET_FILE_BUFFERSIZE, blocksize) != CCE);
87       err = (SETMODE (fnum, SET_FILE_BUFFERED, 0, 0) != CCE);
88       err = (SETMODE (fnum, SET_FILE_BUFFERED, 0, 1) != CCE);
89       err = (SETMODE (fnum, SET_FILE_MAXEXTENTS, maxext) != CCE);
90       err = close(fdesc);
91 
92       vlist[0] = filecode;
93 
94       /* Note that FILE_ALTERLIST_ expects uppercase names */
95       /* Need to call strlen and upshift                   */
96       len = strlen(fname);
97       err = STRING_UPSHIFT_((char *)fname,
98                             len,
99                             nsk_fname,
100                             len);
101 
102       err = FILE_ALTERLIST_(nsk_fname,
103                             len,
104                             alist,
105                             alist_items,
106                             vlist,
107                             vlist_bytes,
108                             ,
109                             err_item);
110     };
111   };
112 
113   return fopen(fname,opt);
114 }
115 #define fopen nskopen
116 
117 
118   int Bflag = 0;            /* Special formatting options for Tandem        */
119                             /* Bit 0 = Add delimiter (0 = Yes, 1 = No)      */
120                             /* Bit 1 = Delimiter Type (0 = CR/LF, 1 = LF)   */
121                             /* Bit 2 = Space Fill records (0 = No, 1 = Yes) */
122                             /* Bit 3 = Trim trailing space(0 = No, 1 = Yes) */
123                             /* Thus, default is to add CR/LF, no padding    */
124                             /* Bit 8 = Use 'safe' large read size (Expand)  */
125   char nsk_delim[2] = {'\r', '\n'}; /* CR/LF */
126   int nsk_delim_len = 2;
127   int nsk_space_fill = 0;   /* 0 = No, 1 = Yes          */
128   int nsk_trim_space = 0;   /* 0 = No, 1 = Yes          */
129   unsigned short nsk_large_read = MAX_LARGE_READ;
130 
131   /* Following holds details of file currently used by zopen & zread */
132   struct stat znsk_stat;
133   nsk_stat_ov *znsk_ov = (nsk_stat_ov *)&znsk_stat.st_reserved[0];
134   nsk_file_attrs *znsk_attr = (nsk_file_attrs *)
135     ( (char *)(&znsk_stat.st_reserved[0]) +
136       offsetof (struct nsk_stat_overlay, nsk_ef_region) );
137 
138   /* Following items used by zread to avoid overwriting window */
139   char zreadbuf[MAX_LARGE_READ];       /* Buffer as large as biggest read */
140   char *zreadptr = (char *) zreadbuf;  /* pointer to start of buffer      */
141   char *zread_ovptr = NULL;            /* pointer to left overs           */
142   long zread_ovlen = 0;                /* size of remaining left overs    */
143 
zopen(filename,opt)144   int zopen (filename, opt)
145     const char *filename;
146     int opt;
147   {
148     /* Currently ignore opt.  Choose method of I/O based on NSK file type */
149     short err, len, fnum, access, exclus, bufferlen, options;
150     long recnum;
151     char fname[FILENAME_MAX + 1];
152     short extension;
153     char ext[EXTENSION_MAX + 1];
154 
155     /* Remove any (pseudo) file extension */
156     extension = parsename (filename,fname,ext);
157     len = strlen(fname);
158 
159     fnum = 0;
160     access = NSK_RDONLY;
161     exclus = NSK_SHARED;
162 
163     err = stat(fname, &znsk_stat); /* Setup global struct, used by zread */
164 
165     if (znsk_attr->filetype == NSK_UNSTRUCTURED)
166       if (znsk_attr->filecode == NSK_EDITFILECODE) {
167         /* Edit File */
168         fnum = -1; /* Ask OPENEDIT_ to open the file for us */
169         err = OPENEDIT_ ((char *)fname, len, &fnum, access, exclus);
170         if (!err) {
171           recnum = -1; /* Position to first line */
172           err = POSITIONEDIT (fnum, recnum);
173         }
174       }
175       else {
176         /* Unstructured File */
177         options = NSK_UNSTRUCTUREDACCESS;
178         err = FILE_OPEN_((char *)fname, len, &fnum, access, exclus,
179                          ,,options,,,);
180         if (!err)
181           /* Ask for large transfer mode */
182           err = (SETMODE (fnum, SET_LARGE_TRANSFERS, 1) != CCE);
183       }
184     else {
185       /* Structured File */
186       bufferlen = 4096;  /* request SBB */
187       err = FILE_OPEN_((char *)fname, len, &fnum, access, exclus,
188                        ,,,, bufferlen ,);
189       if (err == 4)
190         err = 0;  /* Allow saving of files that have missing altkeys */
191     }
192 
193     return (err == 0 ? (int)fnum : -1);
194   }
195 
zread(fnum,buf,len)196   unsigned zread (fnum, buf, len)
197     int fnum;
198     char *buf;
199     unsigned len;
200   {
201     short err, trail;
202     long total, movelen;
203     unsigned short countread;
204     unsigned readlen;  /* typed to match incoming arg */
205     char *bufptr, *readptr;
206 
207     total = err = 0;
208     bufptr = buf;
209 
210     /* We use a separate buffer to read in data as it can be larger than
211        WSIZE, and hence would overwrite memory */
212 
213     /* We always attempt to give the user the exact requested size
214        Hence we make use of an overfow buffer for previously truncated data */
215 
216     /* see if we have some left over characters from last time */
217     if (zread_ovlen) {
218        movelen = _min(len,zread_ovlen);
219        memcpy(bufptr, zread_ovptr, movelen);
220        bufptr += movelen;
221        total += movelen;
222        zread_ovptr += movelen;
223        zread_ovlen -= movelen;
224     }
225 
226     while (!err && (total < len)) {
227       readptr = zreadptr;
228 
229       if (znsk_attr->filetype == NSK_UNSTRUCTURED)
230         if (znsk_attr->filecode == NSK_EDITFILECODE){
231           /* Edit File */
232           trail = 1;
233           readlen = MAX_EDIT_READ; /* guarantee it fits in buffer */
234 
235           /* get line and preserve any trailing space characters */
236           err = READEDIT (fnum,, zreadptr, (short) readlen,
237                             (short *) &countread,,, trail);
238           /* if countread is ever negative then we will skip a line */
239 
240           if (!err) {
241             readptr = zreadptr + countread;
242             /* Note it is possible for Edit files to hold trailing space */
243             if (nsk_trim_space)
244               while (*(readptr-1) == ' ') {
245                 readptr--;
246                 countread--;
247               }
248 
249             if (nsk_delim_len) {
250               memcpy(readptr, nsk_delim, nsk_delim_len);
251               readptr += nsk_delim_len;
252               countread += nsk_delim_len;
253             }
254           }
255         }
256         else {
257           /* Unstructured File */
258 
259           /* Using large transfer mode so we have to use 2K multiples
260              Use largest size possible and put remains in overflow    */
261 
262           readlen = nsk_large_read; /* use largest read, overflow into buffer*/
263 
264           err = (READX(fnum, zreadptr, readlen, (short *)&countread) != CCE);
265           if (err && (errno == EINVAL)) {
266             /* Read too big so scale back to smaller value */
267             readlen = nsk_large_read = MAX_LARGE_READ_EXPAND;
268             err = (READX(fnum, zreadptr, readlen, (short *)&countread) != CCE);
269           }
270           if (!err)
271             readptr = zreadptr + countread;
272         }
273       else {
274         /* Structured File */
275         readlen = znsk_attr->reclen;
276 
277         err = (READX(fnum, zreadptr, readlen, (short *)&countread)!= CCE);
278 
279         if (!err) {
280           readptr = zreadptr + countread;
281           if (nsk_space_fill)
282             while (countread < readlen) {
283               *readptr++ = ' ';
284               countread++;
285             }
286           else
287             if (nsk_trim_space)
288               while (*(readptr-1) == ' ') {
289                 readptr--;
290                 countread--;
291               }
292 
293           if (nsk_delim_len) {
294             memcpy(readptr, nsk_delim, nsk_delim_len);
295             readptr += nsk_delim_len;
296             countread += nsk_delim_len;
297           }
298         }
299       }
300       if (!err) {
301          movelen = _min((len-total), countread);
302          memcpy(bufptr, zreadptr, movelen);
303          bufptr += movelen;
304          total += movelen;
305          if (movelen < countread) { /* still stuff in Read buffer */
306            zread_ovptr = zreadptr + movelen;   /* pointer to whats left */
307            zread_ovlen = countread - movelen;  /* how much is left      */
308          }
309       }
310     }
311 
312     return ((unsigned)total);
313   }
314 
zclose(fnum)315   int zclose (fnum)
316     int fnum;
317   {
318     short err;
319 
320     if ((znsk_attr->filetype == NSK_UNSTRUCTURED)
321       && (znsk_attr->filecode == NSK_EDITFILECODE))
322       err = CLOSEEDIT_(fnum);
323     else
324       err = FILE_CLOSE_(fnum);
325 
326     return (err != 0);
327   }
328 
329 /* modified to work with get_option which returns
330    a string with the number value without leading option */
nskformatopt(p)331 void nskformatopt(p)
332 char *p;
333 {
334   /* set up formatting options for ZIP */
335 
336   Bflag = 0; /* default option */
337 
338   Bflag = strtoul(p, NULL, 10);
339 
340   if (Bflag & NSK_SPACE_FILL)
341     nsk_space_fill = 1;
342   else
343     nsk_space_fill = 0;
344 
345   if (Bflag & NSK_TRIM_TRAILING_SPACE)
346     nsk_trim_space = 1;
347   else
348     nsk_trim_space = 0;
349 
350   if (Bflag & NSK_NO_DELIMITER)
351     nsk_delim_len = 0;
352   else {
353     if (Bflag & NSK_USE_FF_DELIMITER) {
354       nsk_delim[0] = '\n';
355       nsk_delim_len = 1;
356     }
357     else {   /* CR/LF */
358       nsk_delim[0] = '\r';
359       nsk_delim[1] = '\n';
360       nsk_delim_len = 2;
361     }
362   }
363 
364   if (Bflag & NSK_LARGE_READ_EXPAND)
365     nsk_large_read = MAX_LARGE_READ_EXPAND;
366   else
367     nsk_large_read = MAX_LARGE_READ;
368 
369 }
370 
371 
deletedir(d)372   int deletedir(d)
373     char *d;                /* directory to delete */
374   /* Delete the directory *d if it is empty, do nothing otherwise.
375      Return the result of rmdir(), delete(), or system().
376      For VMS, d must be in format [x.y]z.dir;1  (not [x.y.z]).
377    */
378   {
379       return rmdir(d);
380   }
381 
readd(d)382   local char *readd(d)
383     DIR *d;                 /* directory stream to read from */
384   /* Return a pointer to the next name in the directory stream d, or NULL if
385      no more entries or an error occurs. */
386   {
387     struct dirent *e;
388 
389     e = readdir(d);
390     return e == NULL ? (char *) NULL : e->d_name;
391   }
392 
procname(n,caseflag)393   int procname(n, caseflag)
394     char *n;                /* name to process */
395     int caseflag;           /* true to force case-sensitive match */
396   /* Process a name or sh expression to operate on (or exclude).  Return
397      an error code in the ZE_ class. */
398   {
399     char *a;              /* path and name for recursion */
400     DIR *d;               /* directory stream from opendir() */
401     char *e;              /* pointer to name from readd() */
402     int m;                /* matched flag */
403     char *p;              /* path for recursion */
404     struct stat s;        /* result of stat() */
405     struct zlist far *z;  /* steps through zfiles list */
406 
407     if (strcmp(n, "-") == 0)   /* if compressing stdin */
408       return newname(n, 0, caseflag);
409     else if (stat(n, &s))
410     {
411       /* Not a file or directory--search for shell expression in zip file */
412       p = ex2in(n, 0, (int *)NULL);       /* shouldn't affect matching chars */
413       m = 1;
414       for (z = zfiles; z != NULL; z = z->nxt) {
415         if (MATCH(p, z->zname, caseflag))
416         {
417           z->mark = pcount ? filter(z->zname, caseflag) : 1;
418           if (verbose)
419               fprintf(mesg, "zip diagnostic: %scluding %s\n",
420                  z->mark ? "in" : "ex", z->name);
421           m = 0;
422         }
423       }
424       free((zvoid *)p);
425       return m ? ZE_MISS : ZE_OK;
426     }
427 
428     /* Live name--use if file, recurse if directory */
429     if ((s.st_mode & S_IFDIR) == 0)
430     {
431       /* add or remove name of file */
432       if ((m = newname(n, 0, caseflag)) != ZE_OK)
433         return m;
434     } else {
435       if ((p = malloc(strlen(n)+4)) == NULL)
436         return ZE_MEM;
437 
438       strcpy(p, n);
439 
440       /* No concept of directories on Tandem - so do not store them ...*/
441       /* code removed from which attempted to save dir name if dirnames set */
442 
443       /*  Test for recurse being set removed, since Tandem has no dir concept*/
444       /*  recurse into template */
445       if ((d = opendir(n)) != NULL)
446       {
447         while ((e = readd(d)) != NULL) {
448           if ((m = procname(e, caseflag)) != ZE_OK)   /* recurse on name */
449           {
450             if (m == ZE_MISS)
451               zipwarn("name not matched: ", e);
452             else
453               ziperr(m, e);
454           }
455         }
456         closedir(d);
457       }
458       free((zvoid *)p);
459     } /* (s.st_mode & S_IFDIR) == 0) */
460     return ZE_OK;
461   }
462 
ex2in(x,isdir,pdosflag)463   char *ex2in(x, isdir, pdosflag)
464     char *x;                /* external file name */
465     int isdir;              /* input: x is a directory */
466     int *pdosflag;          /* output: force MSDOS file attributes? */
467   /* Convert the external file name to a zip file name, returning the malloc'ed
468      string or NULL if not enough memory. */
469   {
470     char *n;              /* internal file name (malloc'ed) */
471     char *t;              /* shortened name */
472     int dosflag;
473     char *p;               /* pointer to temp area */
474     char fname[FILENAME_MAX + 1]= ""; /* file name */
475     char ext[EXTENSION_MAX + 1] = ""; /* extension name */
476     short extension;    /* does the filename contain an extension */
477 
478     dosflag = dosify;  /* default for non-DOS non-OS/2 */
479 
480     /* Find starting point in name before doing malloc */
481     if (*x == '=')
482       t = x + 1;   /* store DEFINE names without the '=' */
483     else
484       t = x;
485 
486     /* Make changes, if any, to the copied name (leave original intact) */
487 
488     if (!pathput)
489       t = last(t, TANDEM_DELIMITER);
490 
491     /* Malloc space for internal name and copy it */
492     if ((n = malloc(strlen(t) + 4)) == NULL) /* + 4 for safety */
493       return NULL;
494 
495     extension = parsename(t,fname,ext);
496     t = fname;
497 
498     *n= '\0';
499 
500     while (*t != '\0') {  /* File part could be sys,vol,subvol or file */
501       if (*t == TANDEM_NODE) {    /* System Name */
502         strcat(n, INTERNAL_NODE_STR);
503         t++;
504       }
505       else if (*t == TANDEM_DELIMITER) {  /* Volume or Subvol */
506              strcat(n, INTERNAL_DELIMITER_STR);
507              t++;
508            };
509       p = strchr(t,TANDEM_DELIMITER);
510       if (p == NULL) break;
511       strncat(n,t,(p - t));
512       t = p;
513     }
514 
515     strcat(n,t);  /* mop up any left over characters */
516 
517     if (extension) {
518       strcat(n,DOS_EXTENSION_STR);
519       strcat(n,ext);
520     };
521 
522     if (isdir == 42) return n;      /* avoid warning on unused variable */
523 
524     if (dosify)
525       msname(n);
526 
527     /* Returned malloc'ed name */
528     if (pdosflag)
529       *pdosflag = dosflag;
530 
531     return n;
532   }
533 
stamp(f,d)534   void stamp(f, d)
535     char *f;                /* name of file to change */
536     ulg d;                  /* dos-style time to change it to */
537   /* Set last updated and accessed time of file f to the DOS time d. */
538   {
539     ztimbuf u;            /* argument for utime() */
540 
541     /* Convert DOS time to time_t format in u.actime and u.modtime */
542     u.actime = u.modtime = dos2unixtime(d);
543 
544     utime(f, &u);
545   }
546 
filetime(f,a,n,t)547   ulg filetime(f, a, n, t)
548     char *f;                /* name of file to get info on */
549     ulg *a;                 /* return value: file attributes */
550     long *n;                /* return value: file size */
551     iztimes *t;             /* return value: access and modification time */
552   {
553     struct stat s;
554     nsk_stat_ov *nsk_ov;
555 
556     if (strcmp(f, "-") == 0) {    /* if compressing stdin */
557       if (n != NULL) {
558         *n = -1L;
559       }
560     }
561 
562     if (stat(f, &s) != 0) return 0;
563 
564     if (a!= NULL) {
565       *a = ((ulg)s.st_mode << 16) | !(s.st_mode & S_IWUSR);
566       if ((s.st_mode & S_IFMT) == S_IFDIR) {
567         *a |= MSDOS_DIR_ATTR;
568       }
569     }
570 
571     if (n!= NULL)
572       *n = (s.st_mode & S_IFMT) == S_IFREG ? s.st_size : -1L;
573 
574     if (t != NULL) {
575       t->atime = s.st_atime;
576       t->mtime = s.st_mtime;
577       nsk_ov = (nsk_stat_ov *)&s.st_reserved[0];
578       t->ctime = nsk_ov->ov.creation_time;
579     }
580 
581     return unix2dostime(&s.st_mtime);
582   }
583 
set_extra_field(z,z_utim)584   int set_extra_field(z, z_utim)
585     struct zlist far *z;
586     iztimes *z_utim;
587     /* create extra field and change z->att if desired */
588     /* store full data in local header but just modification time stamp info
589        in central header */
590   {
591     struct stat s;
592     nsk_stat_ov *nsk_ov = (nsk_stat_ov *)&s.st_reserved[0];
593     nsk_file_attrs *nsk_attr = (nsk_file_attrs *)&nsk_ov->ov.nsk_ef_region;
594     char *ext, *cext;
595     int lsize, csize;
596 #ifdef USE_EF_UT_TIME
597     char *UTptr, *Uxptr;
598 #endif /* USE_EF_UT_TIME */
599 
600     /* For the Tandem and UT local field including the UID/GID fields, we
601        have to stat the file again. */
602     if (LSSTAT(z->name, &s))
603       return ZE_OPEN;
604 
605     z->ext = z->cext = 0;
606 
607   #define EB_TANDEM_SIZE 20
608   #define EF_TANDEM_SIZE (EB_HEADSIZE + EB_TANDEM_SIZE)
609 
610     /* allocate size of buffers to allow Tandem field */
611     lsize = EF_TANDEM_SIZE;
612     csize = EF_TANDEM_SIZE;
613 
614 #ifdef USE_EF_UT_TIME
615 
616   #define EB_L_UT_SIZE    (EB_HEADSIZE + EB_UT_LEN(3))
617   #define EB_C_UT_SIZE    (EB_HEADSIZE + EB_UT_LEN(1))
618   #define EB_L_UX2_SIZE   (EB_HEADSIZE + EB_UX2_MINLEN)
619   #define EB_C_UX2_SIZE   EB_HEADSIZE
620   #define EF_L_UNIX_SIZE  (EB_L_UT_SIZE + EB_L_UX2_SIZE)
621   #define EF_C_UNIX_SIZE  (EB_C_UT_SIZE + EB_C_UX2_SIZE)
622 
623     /* resize to allow for UT fields */
624     lsize += EF_L_UNIX_SIZE;
625     csize += EF_C_UNIX_SIZE;
626 
627 #endif /* USE_EF_UT_TIME */
628 
629     if ((z->extra = (char *)malloc(lsize)) == NULL)
630       return ZE_MEM;
631     ext = z->extra;
632 
633     if ((z->cextra = (char *)malloc(csize)) == NULL)
634       return ZE_MEM;
635     cext = z->cextra;
636 
637     /* Place Tandem field first so its on an even boundary */
638     *ext++ = *cext++ = 'T';
639     *ext++ = *cext++ = 'A';
640     *ext++ = *cext++ = (char)EB_TANDEM_SIZE;  /*length of data part of e.f.*/
641     *ext++ = *cext++  = 0;
642 
643     /* Copy Tandem specific file information */
644     memcpy(ext, (char *)nsk_attr, EB_TANDEM_SIZE);
645     ext += EB_TANDEM_SIZE;
646     z->ext += EF_TANDEM_SIZE;
647 
648     /* Copy same data to central field */
649     memcpy(cext, (char *)nsk_attr, EB_TANDEM_SIZE);
650     cext += EB_TANDEM_SIZE;
651     z->cext += EF_TANDEM_SIZE;
652 
653 #ifdef USE_EF_UT_TIME
654     UTptr = ext;
655     *ext++  = 'U';
656     *ext++  = 'T';
657     *ext++  = (char)EB_UT_LEN(3);    /* length of data part of local e.f. */
658     *ext++  = 0;
659     *ext++  = EB_UT_FL_MTIME | EB_UT_FL_ATIME | EB_UT_FL_CTIME;
660     *ext++  = (char)(s.st_mtime);
661     *ext++  = (char)(s.st_mtime >> 8);
662     *ext++  = (char)(s.st_mtime >> 16);
663     *ext++  = (char)(s.st_mtime >> 24);
664     *ext++  = (char)(s.st_atime);
665     *ext++ = (char)(s.st_atime >> 8);
666     *ext++ = (char)(s.st_atime >> 16);
667     *ext++ = (char)(s.st_atime >> 24);
668 
669     *ext++ = (char)(nsk_ov->ov.creation_time);
670     *ext++ = (char)(nsk_ov->ov.creation_time >> 8);
671     *ext++ = (char)(nsk_ov->ov.creation_time >> 16);
672     *ext++ = (char)(nsk_ov->ov.creation_time >> 24);
673 
674     Uxptr = ext;
675     *ext++ = 'U';
676     *ext++ = 'x';
677     *ext++ = (char)EB_UX2_MINLEN;   /* length of data part of local e.f. */
678     *ext++ = 0;
679     *ext++ = (char)(s.st_uid);
680     *ext++ = (char)(s.st_uid >> 8);
681     *ext++ = (char)(s.st_gid);
682     *ext++ = (char)(s.st_gid >> 8);
683 
684     z->ext += EF_L_UNIX_SIZE;
685 
686     memcpy(cext, UTptr, EB_C_UT_SIZE);
687     cext[EB_LEN] = (char)EB_UT_LEN(1);
688     memcpy(cext+EB_C_UT_SIZE, Uxptr, EB_C_UX2_SIZE);
689     cext[EB_LEN+EB_C_UT_SIZE] = 0;
690 
691     z->cext += EF_C_UNIX_SIZE;
692     cext += EF_C_UNIX_SIZE;
693 
694 #endif /* USE_EF_UT_TIME */
695 
696     return ZE_OK;
697   }
698 
699 #if CRYPT
700   /* getpid() only available on OSS so make up dummy version using NSK PID */
zgetpid(void)701   unsigned zgetpid (void)
702   {
703     short myphandle[ZSYS_VAL_PHANDLE_WLEN];
704     short err;
705     unsigned retval;
706 
707     err = PROCESSHANDLE_NULLIT_(myphandle);
708 
709     if (!err)
710       err = PROCESS_GETINFO_(myphandle);
711 
712     if (!err)
713       retval = (unsigned) myphandle[ZSYS_VAL_PHANDLE_WLEN - 3];
714     else
715 #ifndef __INT32
716       retval = (unsigned) 31415;
717 #else
718       retval = (unsigned) 3141592654L;
719 #endif /* __INT32 */
720 
721     return retval;
722   }
723 #endif  /* CRYPT */
724