diff options
Diffstat (limited to 'tandem/tanzip.c')
-rw-r--r-- | tandem/tanzip.c | 723 |
1 files changed, 723 insertions, 0 deletions
diff --git a/tandem/tanzip.c b/tandem/tanzip.c new file mode 100644 index 0000000..5985b33 --- /dev/null +++ b/tandem/tanzip.c @@ -0,0 +1,723 @@ +/* + Copyright (c) 1990-2002 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* + * routines only used by TANDEM ZIP + */ + +#include "zip.h" +#include "crypt.h" +#include <tal.h> +#include "$system.zsysdefs.zsysc" nolist +#include <cextdecs> nolist +#include "tannsk.h" + +/******************************/ +/* Function version_local() */ +/******************************/ + +void version_local() +{ + static ZCONST char CompiledWith[] = "Compiled with %s%s for %s%s%s%s.\n\n"; +#if 0 + char buf[40]; +#endif + + printf(CompiledWith, + +#ifdef __GNUC__ + "gcc ", __VERSION__, +#else + "C ", "T9255D44 - (16OCT98)", +#endif + + "NonStop ", "(Tandem/NSK)", + +#ifdef __DATE__ + " on ", __DATE__ +#else + "", "" +#endif + ); + +} /* end function version_local() */ + + +/************************/ +/* Function nskopen() */ +/************************/ + +#ifdef fopen +# undef fopen +#endif + +FILE *nskopen(fname, opt) +const char *fname; +const char *opt; +{ + int fdesc; + short fnum, err, len; + int priext, secext; + short maxext, filecode, blocksize; + + #define alist_items 1 + #define vlist_bytes 2 + short alist[alist_items]={42}; + unsigned short vlist[alist_items]; + short extra, *err_item=&extra; + + char nsk_work[FILENAME_MAX + 1], *nsk_fname=&nsk_work[0]; + + /* See if we want to create a new file */ + if ((strcmp(opt,FOPW) == 0) || (strcmp(opt,FOPWT) == 0)) { + blocksize = TANDEM_BLOCKSIZE; + priext = 100; + secext = 500; + maxext = 978; + filecode = NSK_ZIPFILECODE; + + if ((fdesc = creat(fname,,priext,secext)) != -1){ + fnum = fdtogfn ((short)fdesc); + err = (SETMODE (fnum, SET_FILE_BUFFERSIZE, blocksize) != CCE); + err = (SETMODE (fnum, SET_FILE_BUFFERED, 0, 0) != CCE); + err = (SETMODE (fnum, SET_FILE_BUFFERED, 0, 1) != CCE); + err = (SETMODE (fnum, SET_FILE_MAXEXTENTS, maxext) != CCE); + err = close(fdesc); + + vlist[0] = filecode; + + /* Note that FILE_ALTERLIST_ expects uppercase names */ + /* Need to call strlen and upshift */ + len = strlen(fname); + err = STRING_UPSHIFT_((char *)fname, + len, + nsk_fname, + len); + + err = FILE_ALTERLIST_(nsk_fname, + len, + alist, + alist_items, + vlist, + vlist_bytes, + , + err_item); + }; + }; + + return fopen(fname,opt); +} +#define fopen nskopen + + + int Bflag = 0; /* Special formatting options for Tandem */ + /* Bit 0 = Add delimiter (0 = Yes, 1 = No) */ + /* Bit 1 = Delimiter Type (0 = CR/LF, 1 = LF) */ + /* Bit 2 = Space Fill records (0 = No, 1 = Yes) */ + /* Bit 3 = Trim trailing space(0 = No, 1 = Yes) */ + /* Thus, default is to add CR/LF, no padding */ + /* Bit 8 = Use 'safe' large read size (Expand) */ + char nsk_delim[2] = {'\r', '\n'}; /* CR/LF */ + int nsk_delim_len = 2; + int nsk_space_fill = 0; /* 0 = No, 1 = Yes */ + int nsk_trim_space = 0; /* 0 = No, 1 = Yes */ + unsigned short nsk_large_read = MAX_LARGE_READ; + + /* Following holds details of file currently used by zopen & zread */ + struct stat znsk_stat; + nsk_stat_ov *znsk_ov = (nsk_stat_ov *)&znsk_stat.st_reserved[0]; + nsk_file_attrs *znsk_attr = (nsk_file_attrs *) + ( (char *)(&znsk_stat.st_reserved[0]) + + offsetof (struct nsk_stat_overlay, nsk_ef_region) ); + + /* Following items used by zread to avoid overwriting window */ + char zreadbuf[MAX_LARGE_READ]; /* Buffer as large as biggest read */ + char *zreadptr = (char *) zreadbuf; /* pointer to start of buffer */ + char *zread_ovptr = NULL; /* pointer to left overs */ + long zread_ovlen = 0; /* size of remaining left overs */ + + int zopen (filename, opt) + const char *filename; + int opt; + { + /* Currently ignore opt. Choose method of I/O based on NSK file type */ + short err, len, fnum, access, exclus, bufferlen, options; + long recnum; + char fname[FILENAME_MAX + 1]; + short extension; + char ext[EXTENSION_MAX + 1]; + + /* Remove any (pseudo) file extension */ + extension = parsename (filename,fname,ext); + len = strlen(fname); + + fnum = 0; + access = NSK_RDONLY; + exclus = NSK_SHARED; + + err = stat(fname, &znsk_stat); /* Setup global struct, used by zread */ + + if (znsk_attr->filetype == NSK_UNSTRUCTURED) + if (znsk_attr->filecode == NSK_EDITFILECODE) { + /* Edit File */ + fnum = -1; /* Ask OPENEDIT_ to open the file for us */ + err = OPENEDIT_ ((char *)fname, len, &fnum, access, exclus); + if (!err) { + recnum = -1; /* Position to first line */ + err = POSITIONEDIT (fnum, recnum); + } + } + else { + /* Unstructured File */ + options = NSK_UNSTRUCTUREDACCESS; + err = FILE_OPEN_((char *)fname, len, &fnum, access, exclus, + ,,options,,,); + if (!err) + /* Ask for large transfer mode */ + err = (SETMODE (fnum, SET_LARGE_TRANSFERS, 1) != CCE); + } + else { + /* Structured File */ + bufferlen = 4096; /* request SBB */ + err = FILE_OPEN_((char *)fname, len, &fnum, access, exclus, + ,,,, bufferlen ,); + if (err == 4) + err = 0; /* Allow saving of files that have missing altkeys */ + } + + return (err == 0 ? (int)fnum : -1); + } + + unsigned zread (fnum, buf, len) + int fnum; + char *buf; + unsigned len; + { + short err, trail; + long total, movelen; + unsigned short countread; + unsigned readlen; /* typed to match incoming arg */ + char *bufptr, *readptr; + + total = err = 0; + bufptr = buf; + + /* We use a separate buffer to read in data as it can be larger than + WSIZE, and hence would overwrite memory */ + + /* We always attempt to give the user the exact requested size + Hence we make use of an overfow buffer for previously truncated data */ + + /* see if we have some left over characters from last time */ + if (zread_ovlen) { + movelen = _min(len,zread_ovlen); + memcpy(bufptr, zread_ovptr, movelen); + bufptr += movelen; + total += movelen; + zread_ovptr += movelen; + zread_ovlen -= movelen; + } + + while (!err && (total < len)) { + readptr = zreadptr; + + if (znsk_attr->filetype == NSK_UNSTRUCTURED) + if (znsk_attr->filecode == NSK_EDITFILECODE){ + /* Edit File */ + trail = 1; + readlen = MAX_EDIT_READ; /* guarantee it fits in buffer */ + + /* get line and preserve any trailing space characters */ + err = READEDIT (fnum,, zreadptr, (short) readlen, + (short *) &countread,,, trail); + /* if countread is ever negative then we will skip a line */ + + if (!err) { + readptr = zreadptr + countread; + /* Note it is possible for Edit files to hold trailing space */ + if (nsk_trim_space) + while (*(readptr-1) == ' ') { + readptr--; + countread--; + } + + if (nsk_delim_len) { + memcpy(readptr, nsk_delim, nsk_delim_len); + readptr += nsk_delim_len; + countread += nsk_delim_len; + } + } + } + else { + /* Unstructured File */ + + /* Using large transfer mode so we have to use 2K multiples + Use largest size possible and put remains in overflow */ + + readlen = nsk_large_read; /* use largest read, overflow into buffer*/ + + err = (READX(fnum, zreadptr, readlen, (short *)&countread) != CCE); + if (err && (errno == EINVAL)) { + /* Read too big so scale back to smaller value */ + readlen = nsk_large_read = MAX_LARGE_READ_EXPAND; + err = (READX(fnum, zreadptr, readlen, (short *)&countread) != CCE); + } + if (!err) + readptr = zreadptr + countread; + } + else { + /* Structured File */ + readlen = znsk_attr->reclen; + + err = (READX(fnum, zreadptr, readlen, (short *)&countread)!= CCE); + + if (!err) { + readptr = zreadptr + countread; + if (nsk_space_fill) + while (countread < readlen) { + *readptr++ = ' '; + countread++; + } + else + if (nsk_trim_space) + while (*(readptr-1) == ' ') { + readptr--; + countread--; + } + + if (nsk_delim_len) { + memcpy(readptr, nsk_delim, nsk_delim_len); + readptr += nsk_delim_len; + countread += nsk_delim_len; + } + } + } + if (!err) { + movelen = _min((len-total), countread); + memcpy(bufptr, zreadptr, movelen); + bufptr += movelen; + total += movelen; + if (movelen < countread) { /* still stuff in Read buffer */ + zread_ovptr = zreadptr + movelen; /* pointer to whats left */ + zread_ovlen = countread - movelen; /* how much is left */ + } + } + } + + return ((unsigned)total); + } + + int zclose (fnum) + int fnum; + { + short err; + + if ((znsk_attr->filetype == NSK_UNSTRUCTURED) + && (znsk_attr->filecode == NSK_EDITFILECODE)) + err = CLOSEEDIT_(fnum); + else + err = FILE_CLOSE_(fnum); + + return (err != 0); + } + +/* modified to work with get_option which returns + a string with the number value without leading option */ +void nskformatopt(p) +char *p; +{ + /* set up formatting options for ZIP */ + + Bflag = 0; /* default option */ + + Bflag = strtoul(p, NULL, 10); + + if (Bflag & NSK_SPACE_FILL) + nsk_space_fill = 1; + else + nsk_space_fill = 0; + + if (Bflag & NSK_TRIM_TRAILING_SPACE) + nsk_trim_space = 1; + else + nsk_trim_space = 0; + + if (Bflag & NSK_NO_DELIMITER) + nsk_delim_len = 0; + else { + if (Bflag & NSK_USE_FF_DELIMITER) { + nsk_delim[0] = '\n'; + nsk_delim_len = 1; + } + else { /* CR/LF */ + nsk_delim[0] = '\r'; + nsk_delim[1] = '\n'; + nsk_delim_len = 2; + } + } + + if (Bflag & NSK_LARGE_READ_EXPAND) + nsk_large_read = MAX_LARGE_READ_EXPAND; + else + nsk_large_read = MAX_LARGE_READ; + +} + + + int deletedir(d) + char *d; /* directory to delete */ + /* Delete the directory *d if it is empty, do nothing otherwise. + Return the result of rmdir(), delete(), or system(). + For VMS, d must be in format [x.y]z.dir;1 (not [x.y.z]). + */ + { + return rmdir(d); + } + + local char *readd(d) + DIR *d; /* directory stream to read from */ + /* Return a pointer to the next name in the directory stream d, or NULL if + no more entries or an error occurs. */ + { + struct dirent *e; + + e = readdir(d); + return e == NULL ? (char *) NULL : e->d_name; + } + + int procname(n, caseflag) + char *n; /* name to process */ + int caseflag; /* true to force case-sensitive match */ + /* Process a name or sh expression to operate on (or exclude). Return + an error code in the ZE_ class. */ + { + char *a; /* path and name for recursion */ + DIR *d; /* directory stream from opendir() */ + char *e; /* pointer to name from readd() */ + int m; /* matched flag */ + char *p; /* path for recursion */ + struct stat s; /* result of stat() */ + struct zlist far *z; /* steps through zfiles list */ + + if (strcmp(n, "-") == 0) /* if compressing stdin */ + return newname(n, 0, caseflag); + else if (stat(n, &s)) + { + /* Not a file or directory--search for shell expression in zip file */ + p = ex2in(n, 0, (int *)NULL); /* shouldn't affect matching chars */ + m = 1; + for (z = zfiles; z != NULL; z = z->nxt) { + if (MATCH(p, z->zname, caseflag)) + { + z->mark = pcount ? filter(z->zname, caseflag) : 1; + if (verbose) + fprintf(mesg, "zip diagnostic: %scluding %s\n", + z->mark ? "in" : "ex", z->name); + m = 0; + } + } + free((zvoid *)p); + return m ? ZE_MISS : ZE_OK; + } + + /* Live name--use if file, recurse if directory */ + if ((s.st_mode & S_IFDIR) == 0) + { + /* add or remove name of file */ + if ((m = newname(n, 0, caseflag)) != ZE_OK) + return m; + } else { + if ((p = malloc(strlen(n)+4)) == NULL) + return ZE_MEM; + + strcpy(p, n); + + /* No concept of directories on Tandem - so do not store them ...*/ + /* code removed from which attempted to save dir name if dirnames set */ + + /* Test for recurse being set removed, since Tandem has no dir concept*/ + /* recurse into template */ + if ((d = opendir(n)) != NULL) + { + while ((e = readd(d)) != NULL) { + if ((m = procname(e, caseflag)) != ZE_OK) /* recurse on name */ + { + if (m == ZE_MISS) + zipwarn("name not matched: ", e); + else + ziperr(m, e); + } + } + closedir(d); + } + free((zvoid *)p); + } /* (s.st_mode & S_IFDIR) == 0) */ + return ZE_OK; + } + + char *ex2in(x, isdir, pdosflag) + char *x; /* external file name */ + int isdir; /* input: x is a directory */ + int *pdosflag; /* output: force MSDOS file attributes? */ + /* Convert the external file name to a zip file name, returning the malloc'ed + string or NULL if not enough memory. */ + { + char *n; /* internal file name (malloc'ed) */ + char *t; /* shortened name */ + int dosflag; + char *p; /* pointer to temp area */ + char fname[FILENAME_MAX + 1]= ""; /* file name */ + char ext[EXTENSION_MAX + 1] = ""; /* extension name */ + short extension; /* does the filename contain an extension */ + + dosflag = dosify; /* default for non-DOS non-OS/2 */ + + /* Find starting point in name before doing malloc */ + if (*x == '=') + t = x + 1; /* store DEFINE names without the '=' */ + else + t = x; + + /* Make changes, if any, to the copied name (leave original intact) */ + + if (!pathput) + t = last(t, TANDEM_DELIMITER); + + /* Malloc space for internal name and copy it */ + if ((n = malloc(strlen(t) + 4)) == NULL) /* + 4 for safety */ + return NULL; + + extension = parsename(t,fname,ext); + t = fname; + + *n= '\0'; + + while (*t != '\0') { /* File part could be sys,vol,subvol or file */ + if (*t == TANDEM_NODE) { /* System Name */ + strcat(n, INTERNAL_NODE_STR); + t++; + } + else if (*t == TANDEM_DELIMITER) { /* Volume or Subvol */ + strcat(n, INTERNAL_DELIMITER_STR); + t++; + }; + p = strchr(t,TANDEM_DELIMITER); + if (p == NULL) break; + strncat(n,t,(p - t)); + t = p; + } + + strcat(n,t); /* mop up any left over characters */ + + if (extension) { + strcat(n,DOS_EXTENSION_STR); + strcat(n,ext); + }; + + if (isdir == 42) return n; /* avoid warning on unused variable */ + + if (dosify) + msname(n); + + /* Returned malloc'ed name */ + if (pdosflag) + *pdosflag = dosflag; + + return n; + } + + void stamp(f, d) + char *f; /* name of file to change */ + ulg d; /* dos-style time to change it to */ + /* Set last updated and accessed time of file f to the DOS time d. */ + { + ztimbuf u; /* argument for utime() */ + + /* Convert DOS time to time_t format in u.actime and u.modtime */ + u.actime = u.modtime = dos2unixtime(d); + + utime(f, &u); + } + + ulg filetime(f, a, n, t) + char *f; /* name of file to get info on */ + ulg *a; /* return value: file attributes */ + long *n; /* return value: file size */ + iztimes *t; /* return value: access and modification time */ + { + struct stat s; + nsk_stat_ov *nsk_ov; + + if (strcmp(f, "-") == 0) { /* if compressing stdin */ + if (n != NULL) { + *n = -1L; + } + } + + if (stat(f, &s) != 0) return 0; + + if (a!= NULL) { + *a = ((ulg)s.st_mode << 16) | !(s.st_mode & S_IWUSR); + if ((s.st_mode & S_IFMT) == S_IFDIR) { + *a |= MSDOS_DIR_ATTR; + } + } + + if (n!= NULL) + *n = (s.st_mode & S_IFMT) == S_IFREG ? s.st_size : -1L; + + if (t != NULL) { + t->atime = s.st_atime; + t->mtime = s.st_mtime; + nsk_ov = (nsk_stat_ov *)&s.st_reserved[0]; + t->ctime = nsk_ov->ov.creation_time; + } + + return unix2dostime(&s.st_mtime); + } + + int set_extra_field(z, z_utim) + struct zlist far *z; + iztimes *z_utim; + /* create extra field and change z->att if desired */ + /* store full data in local header but just modification time stamp info + in central header */ + { + struct stat s; + nsk_stat_ov *nsk_ov = (nsk_stat_ov *)&s.st_reserved[0]; + nsk_file_attrs *nsk_attr = (nsk_file_attrs *)&nsk_ov->ov.nsk_ef_region; + char *ext, *cext; + int lsize, csize; +#ifdef USE_EF_UT_TIME + char *UTptr, *Uxptr; +#endif /* USE_EF_UT_TIME */ + + /* For the Tandem and UT local field including the UID/GID fields, we + have to stat the file again. */ + if (LSSTAT(z->name, &s)) + return ZE_OPEN; + + z->ext = z->cext = 0; + + #define EB_TANDEM_SIZE 20 + #define EF_TANDEM_SIZE (EB_HEADSIZE + EB_TANDEM_SIZE) + + /* allocate size of buffers to allow Tandem field */ + lsize = EF_TANDEM_SIZE; + csize = EF_TANDEM_SIZE; + +#ifdef USE_EF_UT_TIME + + #define EB_L_UT_SIZE (EB_HEADSIZE + EB_UT_LEN(3)) + #define EB_C_UT_SIZE (EB_HEADSIZE + EB_UT_LEN(1)) + #define EB_L_UX2_SIZE (EB_HEADSIZE + EB_UX2_MINLEN) + #define EB_C_UX2_SIZE EB_HEADSIZE + #define EF_L_UNIX_SIZE (EB_L_UT_SIZE + EB_L_UX2_SIZE) + #define EF_C_UNIX_SIZE (EB_C_UT_SIZE + EB_C_UX2_SIZE) + + /* resize to allow for UT fields */ + lsize += EF_L_UNIX_SIZE; + csize += EF_C_UNIX_SIZE; + +#endif /* USE_EF_UT_TIME */ + + if ((z->extra = (char *)malloc(lsize)) == NULL) + return ZE_MEM; + ext = z->extra; + + if ((z->cextra = (char *)malloc(csize)) == NULL) + return ZE_MEM; + cext = z->cextra; + + /* Place Tandem field first so its on an even boundary */ + *ext++ = *cext++ = 'T'; + *ext++ = *cext++ = 'A'; + *ext++ = *cext++ = (char)EB_TANDEM_SIZE; /*length of data part of e.f.*/ + *ext++ = *cext++ = 0; + + /* Copy Tandem specific file information */ + memcpy(ext, (char *)nsk_attr, EB_TANDEM_SIZE); + ext += EB_TANDEM_SIZE; + z->ext += EF_TANDEM_SIZE; + + /* Copy same data to central field */ + memcpy(cext, (char *)nsk_attr, EB_TANDEM_SIZE); + cext += EB_TANDEM_SIZE; + z->cext += EF_TANDEM_SIZE; + +#ifdef USE_EF_UT_TIME + UTptr = ext; + *ext++ = 'U'; + *ext++ = 'T'; + *ext++ = (char)EB_UT_LEN(3); /* length of data part of local e.f. */ + *ext++ = 0; + *ext++ = EB_UT_FL_MTIME | EB_UT_FL_ATIME | EB_UT_FL_CTIME; + *ext++ = (char)(s.st_mtime); + *ext++ = (char)(s.st_mtime >> 8); + *ext++ = (char)(s.st_mtime >> 16); + *ext++ = (char)(s.st_mtime >> 24); + *ext++ = (char)(s.st_atime); + *ext++ = (char)(s.st_atime >> 8); + *ext++ = (char)(s.st_atime >> 16); + *ext++ = (char)(s.st_atime >> 24); + + *ext++ = (char)(nsk_ov->ov.creation_time); + *ext++ = (char)(nsk_ov->ov.creation_time >> 8); + *ext++ = (char)(nsk_ov->ov.creation_time >> 16); + *ext++ = (char)(nsk_ov->ov.creation_time >> 24); + + Uxptr = ext; + *ext++ = 'U'; + *ext++ = 'x'; + *ext++ = (char)EB_UX2_MINLEN; /* length of data part of local e.f. */ + *ext++ = 0; + *ext++ = (char)(s.st_uid); + *ext++ = (char)(s.st_uid >> 8); + *ext++ = (char)(s.st_gid); + *ext++ = (char)(s.st_gid >> 8); + + z->ext += EF_L_UNIX_SIZE; + + memcpy(cext, UTptr, EB_C_UT_SIZE); + cext[EB_LEN] = (char)EB_UT_LEN(1); + memcpy(cext+EB_C_UT_SIZE, Uxptr, EB_C_UX2_SIZE); + cext[EB_LEN+EB_C_UT_SIZE] = 0; + + z->cext += EF_C_UNIX_SIZE; + cext += EF_C_UNIX_SIZE; + +#endif /* USE_EF_UT_TIME */ + + return ZE_OK; + } + +#if CRYPT + /* getpid() only available on OSS so make up dummy version using NSK PID */ + unsigned zgetpid (void) + { + short myphandle[ZSYS_VAL_PHANDLE_WLEN]; + short err; + unsigned retval; + + err = PROCESSHANDLE_NULLIT_(myphandle); + + if (!err) + err = PROCESS_GETINFO_(myphandle); + + if (!err) + retval = (unsigned) myphandle[ZSYS_VAL_PHANDLE_WLEN - 3]; + else +#ifndef __INT32 + retval = (unsigned) 31415; +#else + retval = (unsigned) 3141592654L; +#endif /* __INT32 */ + + return retval; + } +#endif /* CRYPT */ |