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
24void 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
59FILE *nskopen(fname, opt)
60const char *fname;
61const 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
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
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
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 */
331void nskformatopt(p)
332char *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
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
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
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
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
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
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
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 */
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