723 lines
21 KiB
C
723 lines
21 KiB
C
/*
|
|
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 */
|