home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-08-22 | 60.4 KB | 2,184 lines |
- Newsgroups: comp.sources.misc
- From: zip-bugs@cs.ucla.edu (Info-ZIP group)
- Subject: v31i094: zip19 - Info-ZIP portable Zip, version 1.9, Part02/11
- Message-ID: <1992Aug23.064513.28972@sparky.imd.sterling.com>
- X-Md4-Signature: cf491d96f8441d411222c18f4edf15b0
- Date: Sun, 23 Aug 1992 06:45:13 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: zip-bugs@cs.ucla.edu (Info-ZIP group)
- Posting-number: Volume 31, Issue 94
- Archive-name: zip19/part02
- Supersedes: zip: Volume 23, Issue 88-96
- Environment: UNIX, VMS, OS/2, MS-DOS, MACINTOSH, WIN-NT, LINUX, MINIX, XOS, !AMIGA, ATARI, symlink, SGI, DEC, Cray, Convex, Amdahl, Sun, PC
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then feed it
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # The tool that generated this appeared in the comp.sources.unix newsgroup;
- # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
- # Contents: atari/stzip.lnk fileio.c
- # Wrapped by kent@sparky on Sun Aug 23 01:00:42 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- echo If this archive is complete, you will see the following message:
- echo ' "shar: End of archive 2 (of 11)."'
- if test -f 'atari/stzip.lnk' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'atari/stzip.lnk'\"
- else
- echo shar: Extracting \"'atari/stzip.lnk'\" \(180 characters\)
- sed "s/^X//" >'atari/stzip.lnk' <<'END_OF_FILE'
- X\TC\lib\c0.o
- Xzip.o
- X\TC\lib\tcstdlib.lib
- Xatari.o
- Xzipfile.o
- Xzipup.o
- Xfileio.o
- Xutil.o
- Xglobals.o
- Xdeflate.o
- Xtrees.o
- Xbits.o
- X\TC\lib\tcstdlib.lib
- X\TC\lib\tcextlib.lib
- X\TC\lib\tctoslib.lib
- END_OF_FILE
- if test 180 -ne `wc -c <'atari/stzip.lnk'`; then
- echo shar: \"'atari/stzip.lnk'\" unpacked with wrong size!
- fi
- # end of 'atari/stzip.lnk'
- fi
- if test -f 'fileio.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'fileio.c'\"
- else
- echo shar: Extracting \"'fileio.c'\" \(57097 characters\)
- sed "s/^X//" >'fileio.c' <<'END_OF_FILE'
- X/*
- X
- X Copyright (C) 1990-1992 Mark Adler, Richard B. Wales, Jean-loup Gailly,
- X Kai Uwe Rommel and Igor Mandrichenko.
- X Permission is granted to any individual or institution to use, copy, or
- X redistribute this software so long as all of the original files are included
- X unmodified, that it is not sold for profit, and that this copyright notice
- X is retained.
- X
- X*/
- X
- X/*
- X * fileio.c by Mark Adler.
- X */
- X
- X#include "zip.h"
- X
- X#include <time.h>
- X
- X#ifdef WIN32
- X# include <sys/utime.h>
- X# include <windows.h> /* for findfirst/findnext */
- X#endif
- X
- X#ifdef MACOS
- X# define EXDEV 1
- X#endif
- X
- X#ifdef OSF
- X# define EXDEV 18 /* avoid a bug in the DEC OSF/1 header files. */
- X#else
- X# include <errno.h>
- X#endif
- X
- X#ifdef MINIX
- X# ifdef S_IWRITE
- X# undef S_IWRITE
- X# endif /* S_IWRITE */
- X# define S_IWRITE S_IWUSR
- X#endif /* S_IWUSR */
- X
- X#ifdef ATARI_ST
- X# undef MSDOS
- X#endif
- X
- X#ifdef MSDOS
- X# include <io.h>
- X# if (defined(__TURBOC__) || defined(__GO32__))
- X# include <dir.h>
- X# else /* !__TURBOC__ */
- X# if !defined(__EMX__) && !defined(__WATCOMC__)
- X# include <direct.h>
- X# endif
- X# endif /* ?__TURBOC__ */
- X# define link rename
- X# ifdef OS2
- X# define MATCH shmatch
- X# else /* !OS2 */
- X# define MATCH dosmatch
- X# endif /* ?OS2 */
- X#else /* !MSDOS */
- X extern int errno; /* error number from system functions */
- X# ifdef VMS
- X# define RMDIR
- X# define link rename
- X# include "VMSmunch.h"
- X# endif /* VMS */
- X# ifdef MACOS
- X# define link rename
- X# define mktemp tmpnam
- X# endif
- X# define MATCH shmatch
- X#endif /* ?MSDOS */
- X
- X#ifdef ATARI_ST
- X# define MSDOS 1
- X#endif
- X
- X#ifdef UTS
- X# define RMDIR
- X#endif /* UTS */
- X
- X
- X/* Extra malloc() space in names for cutpath() */
- X#ifdef VMS
- X# define PAD 3 /* may have to change .FOO] to ]FOO.DIR */
- X#else /* !VMS */
- X# define PAD 0
- X#endif /* ?VMS */
- X
- X
- X/* For now, assume DIRENT implies System V implies TERMIO */
- X#if defined(DIRENT) && !defined(MINIX) && !defined(TERMIO)
- X# define TERMIO
- X#endif
- X
- X
- X#ifdef CRYPT
- X# ifdef MSVMS
- X# ifdef MSDOS
- X# ifdef __EMX__
- X# define getch() _read_kbd(0, 1, 0)
- X# else
- X# ifdef __GO32__
- X# include <pc.h>
- X# define getch() getkey()
- X# else
- X# include <conio.h>
- X# endif
- X# endif
- X# else /* !MSDOS */
- X# define getch() getc(stderr)
- X# define echoff(f) echo(0) /* for echo control */
- X# define echon() echo(1)
- X# include <iodef.h>
- X# include <ttdef.h>
- X# if !defined(SS$_NORMAL)
- X# define SS$_NORMAL 1 /* only thing we need from <ssdef.h> */
- X# endif
- X# endif /* ?MSDOS */
- X# else /* !MSVMS */
- X# ifdef TERMIO /* Amdahl, Cray, all SysV? */
- X# ifdef CONVEX
- X# include <sys/termios.h>
- X# include <sgtty.h>
- X# define O_BINARY 0
- X# else /* !CONVEX */
- X# ifdef LINUX
- X# include <termios.h>
- X# else /* !LINUX */
- X# include <sys/termio.h>
- X# endif /* ?LINUX */
- X# define sgttyb termio
- X# define sg_flags c_lflag
- X int ioctl OF((int, int, voidp *));
- X# endif /* ?CONVEX */
- X# define GTTY(f,s) ioctl(f,TCGETA,s)
- X# define STTY(f,s) ioctl(f,TCSETAW,s)
- X# else /* !TERMIO */
- X# ifndef MINIX
- X# include <sys/ioctl.h>
- X# endif /* !MINIX */
- X# include <sgtty.h>
- X int gtty OF((int, struct sgttyb *));
- X int stty OF((int, struct sgttyb *));
- X# define GTTY gtty
- X# define STTY stty
- X# endif /* ?TERMIO */
- X int isatty OF((int));
- X char *ttyname OF((int));
- X int open OF((char *, int, ...));
- X int close OF((int));
- X int read OF((int, voidp *, int));
- X# endif /* ?MSVMS */
- X#endif /* ?CRYPT */
- X
- X#ifdef VMS
- X# include <descrip.h>
- X# include <rms.h>
- X#endif
- X
- X/* For directory access. (This is getting rather messy. Cleanup
- X * scheduled for version 17.9.)
- X */
- X#ifndef UTIL
- X
- X#ifdef SYSV /* use readdir() */
- X# include <dirent.h>
- X# define dstrm DIR
- X# define direct dirent
- X#else
- X
- X#ifdef DIRENT /* use getdents() */
- X# if defined(MINIX) || defined(OSF)
- X# include <dirent.h>
- X# else /* !MINIX */
- X# include <sys/dirent.h>
- X# endif /* ?MINIX */
- X# define direct dirent
- X# ifdef MINIX
- X int getdents OF((int, char *, unsigned));
- X# else /* !MINIX */
- X int getdents OF((int, char *, int));
- X# endif /* ?MINIX */
- X# define DBSZ 4096 /* This has to be bigger than a directory block */
- X typedef struct { /* directory stream buffer */
- X int f; /* file descriptor for the directory "file" */
- X char *p; /* pointer to next entry in buffer */
- X char *q; /* pointer after end of buffer contents */
- X char b[DBSZ]; /* buffer */
- X } dstrm;
- X
- X#else /* !DIRENT */ /* use opendir(), etc. */
- X# if defined(CONVEX) || defined(ultrix)
- X# include <dirent.h>
- X# ifdef direct
- X# undef direct /* ultrix 4.2, at least if !__POSIX */
- X# endif
- X# define direct dirent
- X# endif /* CONVEX || ultrix */
- X# ifdef NDIR
- X# include "ndir.h" /* for HPUX */
- X# else /* !NDIR */
- X# ifdef MSDOS
- X# ifdef OS2
- X# include "os2zip.h"
- X# else /* !OS2 */
- X# ifndef ATARI_ST
- X# include <dos.h>
- X# endif
- X# if (defined(__TURBOC__) || defined(__GO32__))
- X# define FATTR FA_HIDDEN+FA_SYSTEM+FA_DIREC
- X# define FFIRST(n,d) findfirst(n,(struct ffblk *)d,FATTR)
- X# define FNEXT(d) findnext((struct ffblk *)d)
- X# else /* !__TURBOC__ */
- X# define FATTR _A_HIDDEN+_A_SYSTEM+_A_SUBDIR
- X# define FFIRST(n,d) _dos_findfirst(n,FATTR,(struct find_t *)d)
- X# define FNEXT(d) _dos_findnext((struct find_t *)d)
- X# endif /* ?__TURBOC__ */
- X typedef struct direct {
- X char d_reserved[30];
- X char d_name[13];
- X int d_first;
- X#ifdef WIN32
- X HANDLE d_hFindFile;
- X#endif
- X } DIR;
- X# endif /* ?OS2 */
- X# else /* !MSDOS */
- X# ifdef VMS
- X# include <ssdef.h>
- X typedef struct direct {
- X int d_wild; /* flag for wildcard vs. non-wild */
- X struct FAB fab;
- X struct NAM nam;
- X char d_qualwildname[NAM$C_MAXRSS + 1];
- X char d_name[NAM$C_MAXRSS + 1];
- X } DIR;
- X# else /* !VMS */
- X# ifdef MACOS
- X typedef struct direct {
- X int d_wild; /* flag for wildcard vs. non-wild */
- X char *d_name;
- X } DIR;
- X# endif
- X# ifdef M_XENIX
- X# include <sys/ndir.h>
- X# else /* !M_XENIX */
- X# include <sys/dir.h>
- X# endif /* ?M_XENIX */
- X# ifdef NODIR /* for AT&T 3B1 */
- X# define dirent direct
- X typedef FILE DIR;
- X# define dstrm DIR
- X# endif /* NODIR */
- X# endif /* ?VMS */
- X# endif /* ?MSDOS */
- X# endif /* ?NDIR */
- X# define dstrm DIR
- X# ifndef NODIR
- X DIR *opendir OF((char *));
- X# endif /* !NODIR */
- X# ifndef CONVEX
- X struct direct *readdir OF((DIR *));
- X# endif /* !CONVEX */
- X#endif /* ?DIRENT */
- X#endif /* ?SYSV */
- X#endif /* !UTIL */
- X
- X
- X/* Library functions not in (most) header files */
- X
- X#if defined(__IBMC__) || defined(__WATCOMC__)
- X# define NO_MKTEMP
- X#endif
- Xchar *mktemp OF((char *));
- X
- X#ifdef __GO32__
- X char *strlwr OF((char *));
- X#else
- X int link OF((char *, char *));
- X int unlink OF((char *));
- X# if defined(MSDOS)
- X int chmod OF((char *, int));
- X /* For many targets, chmod is already defined by sys/stat.h, and second
- X * parameter is an unsigned long.
- X */
- X# endif
- X#endif
- X
- X
- X#ifndef UTIL /* the companion #endif is a bit of ways down ... */
- X
- X#ifndef __TURBOC__
- X int utime OF((char *, time_t *));
- X#endif /* !__TURBOC__ */
- X#ifndef MSDOS
- X int open OF((char *, int, ...));
- X int close OF((int));
- X# ifndef RMDIR
- X int rmdir OF((char *));
- X# endif /* !RMDIR */
- X#endif /* !MSDOS */
- X
- X
- X/* Local globals (kinda like "military intelligence" or "broadcast quality") */
- Xlocal int exflag = 0; /* Exclude flag */
- X
- X#ifdef VMS
- X typedef int statime;
- X#else /* !VMS */
- X typedef time_t statime;
- X#endif /* ?VMS */
- X
- X/* Local functions */
- X#ifdef PROTO
- X# ifdef VMS
- X local void vms_wild(char *, dstrm *);
- X# endif /* VMS */
- X# ifdef DIRENT
- X local dstrm *opend(char *);
- X local void closed(dstrm *);
- X# endif /* DIRENT */
- X local char *readd(dstrm *);
- X local int fqcmp(voidp *, voidp *);
- X local int fqcmpz(voidp *, voidp *);
- X local char *last(char *);
- X local char *msname(char *);
- X# ifdef VMS
- X local char *strlower(char *);
- X local char *strupper(char *);
- X# endif /* VMS */
- X local char *ex2in(char *, int *);
- X local int newname(char *);
- X local void inctime(struct tm *);
- X local ulg unix2dostime(statime *);
- X# if !defined(__TURBOC__) && !defined(OS2) && !defined(__GO32__)
- X local int cmptime(struct tm *, struct tm *);
- X local time_t invlocal(struct tm *);
- X# endif /* !__TURBOC__ */
- X#endif /* PROTO */
- X
- X
- X#if defined(MSDOS) && !defined(OS2)
- Xdstrm *opendir(n)
- Xchar *n; /* directory to open */
- X/* Start searching for files in the MSDOS directory n */
- X{
- X dstrm *d; /* malloc'd return value */
- X char *p; /* malloc'd temporary string */
- X
- X if ((d = (dstrm *)malloc(sizeof(dstrm))) == NULL ||
- X (p = malloc(strlen(n) + 5)) == NULL)
- X return NULL;
- X strcat(strcpy(p, n), "/*.*");
- X#ifdef WIN32
- X {
- X WIN32_FIND_DATA fd;
- X DWORD dwAttr;
- X BOOL bAttr;
- X
- X if ((HANDLE)0xFFFFFFFF == (d->d_hFindFile = FindFirstFile(p, &fd)))
- X {
- X free((voidp *)p);
- X return NULL;
- X }
- X else
- X strcpy(d->d_name, fd.cFileName);
- X if (-1 != (dwAttr = GetFileAttributes(fd.cFileName)))
- X {
- X bAttr = FALSE;
- X if (FILE_ATTRIBUTE_SYSTEM == (dwAttr & FILE_ATTRIBUTE_SYSTEM))
- X bAttr = TRUE;
- X if (FILE_ATTRIBUTE_HIDDEN == (dwAttr & FILE_ATTRIBUTE_HIDDEN))
- X bAttr = TRUE;
- X if (FILE_ATTRIBUTE_DIRECTORY == (dwAttr & FILE_ATTRIBUTE_DIRECTORY))
- X bAttr = TRUE;
- X if (!bAttr)
- X {
- X free ((voidp *)p);
- X free ((void *) d);
- X return NULL;
- X }
- X }
- X
- X }
- X#else
- X if (FFIRST(p, d))
- X {
- X free((voidp *)p);
- X return NULL;
- X }
- X free((voidp *)p);
- X#endif
- X d->d_first = 1;
- X return d;
- X}
- X
- Xstruct direct *readdir(d)
- Xdstrm *d; /* directory stream to read from */
- X/* Return pointer to first or next directory entry, or NULL if end. */
- X{
- X if (d->d_first)
- X d->d_first = 0;
- X else
- X#ifdef WIN32
- X {
- X WIN32_FIND_DATA fd;
- X
- X if (!FindNextFile(d->d_hFindFile, &fd))
- X return NULL;
- X else
- X strcpy(d->d_name, fd.cFileName);
- X }
- X#else /* !WIN32 */
- X if (FNEXT(d))
- X return NULL;
- X#endif
- X return (struct direct *)d;
- X}
- X# define closedir free
- X
- X#endif /* MSDOS && !OS2 */
- X
- X
- X#ifdef VMS
- X
- X/*---------------------------------------------------------------------------
- X
- X _vms_findfirst() and _vms_findnext(), based on public-domain DECUS C
- X fwild() and fnext() routines (originally written by Martin Minow, poss-
- X ibly modified by Jerry Leichter for bintnxvms.c), were written by Greg
- X Roelofs and are still in the public domain. Routines approximate the
- X behavior of MS-DOS (MSC and Turbo C) findfirst and findnext functions.
- X
- X ---------------------------------------------------------------------------*/
- Xlocal void vms_wild(p, d)
- Xchar *p;
- Xdstrm *d;
- X{
- X /*
- X * Do wildcard setup
- X */
- X /* set up the FAB and NAM blocks. */
- X d->fab = cc$rms_fab; /* initialize fab */
- X d->nam = cc$rms_nam; /* initialize nam */
- X
- X d->fab.fab$l_nam = &d->nam; /* fab -> nam */
- X d->fab.fab$l_fna = p; /* argument wild name */
- X d->fab.fab$b_fns = strlen(p); /* length */
- X
- X d->nam.nam$l_esa = d->d_qualwildname; /* qualified wild name */
- X d->nam.nam$b_ess = NAM$C_MAXRSS; /* max length */
- X d->nam.nam$l_rsa = d->d_name; /* matching file name */
- X d->nam.nam$b_rss = NAM$C_MAXRSS; /* max length */
- X
- X /* parse the file name */
- X if (sys$parse(&d->fab) != RMS$_NORMAL)
- X return;
- X /* Does this replace d->fab.fab$l_fna with a new string in its own space?
- X I sure hope so, since p is free'ed before this routine returns. */
- X
- X /* have qualified wild name (i.e., disk:[dir.subdir]*.*); null-terminate
- X * and set wild-flag */
- X d->d_qualwildname[d->nam.nam$b_esl] = '\0';
- X d->d_wild = (d->nam.nam$l_fnb & NAM$M_WILDCARD)? 1 : 0; /* not used... */
- X#ifdef DEBUG
- X printf(" incoming wildname: %s\n", p);
- X printf(" qualified wildname: %s\n", d->d_qualwildname);
- X#endif /* DEBUG */
- X}
- X
- Xdstrm *opendir(n)
- Xchar *n; /* directory to open */
- X/* Start searching for files in the VMS directory n */
- X{
- X char *c; /* scans VMS path */
- X dstrm *d; /* malloc'd return value */
- X int m; /* length of name */
- X char *p; /* malloc'd temporary string */
- X
- X if ((d = (dstrm *)malloc(sizeof(dstrm))) == NULL ||
- X (p = malloc((m = strlen(n)) + 4)) == NULL)
- X return NULL;
- X /* Directory may be in form "[DIR.SUB1.SUB2]" or "[DIR.SUB1]SUB2.DIR;1".
- X If latter, convert to former. */
- X if (m > 0 && *(c = strcpy(p,n)+m-1) != ']')
- X {
- X while (--c > p && *c != ';')
- X ;
- X if (c-p < 5 || strncmp(c-4, ".DIR", 4))
- X {
- X free((voidp *)d); free((voidp *)p);
- X return NULL;
- X }
- X c -= 3;
- X *c-- = '\0'; /* terminate at "DIR;#" */
- X *c = ']'; /* "." --> "]" */
- X while (c > p && *--c != ']')
- X ;
- X *c = '.'; /* "]" --> "." */
- X }
- X strcat(p, "*.*");
- X vms_wild(p, d); /* set up wildcard */
- X free((voidp *)p);
- X return d;
- X}
- X
- Xstruct direct *readdir(d)
- Xdstrm *d; /* directory stream to read from */
- X/* Return pointer to first or next directory entry, or NULL if end. */
- X{
- X int r; /* return code */
- X
- X do {
- X d->fab.fab$w_ifi = 0; /* internal file index: what does this do? */
- X
- X /* get next match to possible wildcard */
- X if ((r = sys$search(&d->fab)) == RMS$_NORMAL)
- X {
- X d->d_name[d->nam.nam$b_rsl] = '\0'; /* null terminate */
- X return (struct direct *)d; /* OK */
- X }
- X } while (r == RMS$_PRV);
- X return NULL;
- X}
- X# define closedir free
- X#endif /* VMS */
- X
- X
- X#ifdef NODIR /* for AT&T 3B1 */
- X/*
- X** Apparently originally by Rich Salz.
- X** Cleaned up and modified by James W. Birdsall.
- X*/
- X
- X# define opendir(path) fopen(path, "r")
- X
- Xstruct direct *readdir(dirp)
- XDIR *dirp;
- X{
- X static struct direct entry;
- X
- X if (dirp == NULL)
- X return NULL;
- X for (;;)
- X if (fread (&entry, sizeof (struct direct), 1, dirp) == 0)
- X return NULL;
- X else if (entry.d_ino)
- X return (&entry);
- X} /* end of readdir() */
- X
- X# define closedir(dirp) fclose(dirp)
- X#endif /* NODIR */
- X
- X
- X#ifdef DIRENT
- Xlocal dstrm *opend(n)
- Xchar *n; /* directory name to open */
- X/* Open the directory *n, returning a pointer to an allocated dstrm, or
- X NULL if error. */
- X{
- X dstrm *d; /* pointer to malloc'ed directory stream */
- X
- X if ((d = (dstrm *)malloc(sizeof(dstrm))) == NULL)
- X return NULL;
- X if ((d->f = open(n, 0, 0)) < 0) /* open directory */
- X return NULL;
- X d->p = d->q = d->b; /* buffer is empty */
- X return d;
- X}
- X#else /* !DIRENT */
- X# define opend opendir /* just use opendir() */
- X#endif /* ?DIRENT */
- X
- X
- Xlocal char *readd(d)
- Xdstrm *d; /* directory stream to read from */
- X/* Return a pointer to the next name in the directory stream d, or NULL if
- X no more entries or an error occurs. */
- X{
- X struct direct *e; /* directory entry read */
- X
- X#ifdef DIRENT
- X int n; /* number of entries read by getdents */
- X
- X if (d->p >= d->q) /* if empty, fill buffer */
- X if ((n = getdents(d->f, d->b, DBSZ)) <= 0)
- X return NULL;
- X else
- X d->q = n + (d->p = d->b);
- X e = (struct direct *)(d->p); /* point to entry */
- X d->p += ((struct direct *)(d->p))->d_reclen; /* advance */
- X return e->d_name; /* return name */
- X#else /* !DIRENT */
- X return (e = readdir(d)) == NULL ? (char *)NULL : e->d_name;
- X#endif /* ?DIRENT */
- X}
- X
- X
- X#ifdef DIRENT
- Xlocal void closed(d)
- Xdstrm *d; /* directory stream to close */
- X/* Close the directory stream */
- X{
- X close(d->f);
- X free((voidp *)d);
- X}
- X#else /* !DIRENT */
- X# define closed closedir
- X#endif /* ?DIRENT */
- X
- X
- X#ifdef MSDOS
- X
- Xint wild(w)
- Xchar *w; /* path/pattern to match */
- X/* If not in exclude mode, expand the pattern based on the contents of the
- X file system. Return an error code in the ZE_ class. */
- X{
- X char *a; /* alloc'ed space for name */
- X dstrm *d; /* stream for reading directory */
- X char *e; /* name found in directory */
- X int f; /* true if there was a match */
- X char *n; /* constructed name from directory */
- X char *p; /* path */
- X char *q; /* name */
- X int r; /* temporary variable */
- X char v[5]; /* space for device current directory */
- X
- X /* Allocate and copy pattern */
- X if ((p = a = malloc(strlen(w) + 1)) == NULL)
- X return ZE_MEM;
- X strcpy(p, w);
- X
- X /* Normalize pattern to upper case, path delimiter as '/'. */
- X#if defined(FORCE_UPPER)
- X#ifndef OS2
- X strupr(p); /* convert to upper case */
- X#else /* OS2 */
- X if (IsFileSystemFAT(p)) strupr(p);
- X#endif /* !OS2 */
- X#endif
- X for (q = p; *q; q++) /* use / consistently */
- X if (*q == '\\')
- X *q = '/';
- X
- X /* If excluding, don't bother with file system */
- X if (exflag)
- X {
- X r = procname(p);
- X free((voidp *)a);
- X return r;
- X }
- X
- X /* Only name can have special matching characters */
- X if ((q = isshexp(p)) != NULL &&
- X (strrchr(q, '/') != NULL || strrchr(q, ':') != NULL))
- X {
- X free((voidp *)a);
- X return ZE_PARMS;
- X }
- X
- X /* Separate path and name into p and q */
- X if ((q = strrchr(p, '/')) != NULL && (q == p || q[-1] != ':'))
- X {
- X *q++ = 0; /* path/name -> path, name */
- X if (*p == 0) /* path is just / */
- X p = strcpy(v, "/.");
- X }
- X else if ((q = strrchr(p, ':')) != NULL)
- X { /* has device and no or root path */
- X *q++ = 0;
- X p = strcat(strcpy(v, p), ":"); /* copy device as path */
- X if (*q == '/') /* -> device:/., name */
- X {
- X strcat(p, "/");
- X q++;
- X }
- X strcat(p, ".");
- X }
- X else /* no path or device */
- X {
- X q = p;
- X p = strcpy(v, ".");
- X }
- X
- X /* Search that level for matching names */
- X if ((d = opend(p)) == NULL)
- X {
- X free((voidp *)a);
- X return ZE_MISS;
- X }
- X if ((r = strlen(p)) > 1 &&
- X (strcmp(p + r - 2, ":.") == 0 || strcmp(p + r - 2, "/.") == 0))
- X *(p + r - 1) = 0;
- X f = 0;
- X while ((e = readd(d)) != NULL)
- X if (strcmp(e, ".") && strcmp(e, "..") && MATCH(q, e))
- X {
- X f = 1;
- X if (strcmp(p, ".") == 0) /* path is . */
- X procname(e); /* name is name */
- X else
- X {
- X if ((n = malloc(strlen(p) + strlen(e) + 2)) == NULL)
- X {
- X free((voidp *)a);
- X return ZE_MEM;
- X }
- X n = strcpy(n, p);
- X if (n[r = strlen(n) - 1] != '/' && n[r] != ':')
- X strcat(n, "/");
- X r = procname(strcat(n, e)); /* name is path/name */
- X free((voidp *)n);
- X if (r)
- X {
- X free((voidp *)a);
- X return r;
- X }
- X }
- X }
- X closed(d);
- X
- X /* Done */
- X free((voidp *)a);
- X return f ? ZE_OK : ZE_MISS;
- X}
- X
- X#endif /* MSDOS */
- X
- X
- X#ifdef VMS
- Xint wild(p)
- Xchar *p; /* path/pattern to match */
- X/* Expand the pattern based on the contents of the file system. Return an
- X error code in the ZE_ class. */
- X{
- X dstrm *d; /* stream for reading directory */
- X char *e; /* name found in directory */
- X int f; /* true if there was a match */
- X
- X /* Search given pattern for matching names */
- X if ((d = (dstrm *)malloc(sizeof(dstrm))) == NULL)
- X return ZE_MEM;
- X vms_wild(p, d); /* pattern may be more than just directory name */
- X f = 0;
- X while ((e = readd(d)) != NULL) /* "dosmatch" is already built in */
- X if (procname(e) == ZE_OK)
- X f = 1;
- X closed(d);
- X
- X /* Done */
- X return f ? ZE_OK : ZE_MISS;
- X}
- X#endif /* VMS */
- X
- X
- Xchar *getnam(n)
- Xchar *n; /* where to put name (must have >=FNMAX+1 bytes) */
- X/* Read a space, \n, \r, or \t delimited name from stdin into n, and return
- X n. If EOF, then return NULL. Also, if the name read is too big, return
- X NULL. */
- X{
- X int c; /* last character read */
- X char *p; /* pointer into name area */
- X
- X p = n;
- X while ((c = getchar()) == ' ' || c == '\n' || c == '\r' || c == '\t')
- X ;
- X if (c == EOF)
- X return NULL;
- X do {
- X if (p - n >= FNMAX)
- X return NULL;
- X *p++ = (char)c;
- X c = getchar();
- X } while (c != EOF && c != ' ' && c != '\n' && c != '\r' && c != '\t');
- X *p = 0;
- X return n;
- X}
- X
- X
- Xstruct flist far *fexpel(f)
- Xstruct flist far *f; /* entry to delete */
- X/* Delete the entry *f in the doubly-linked found list. Return pointer to
- X next entry to allow stepping through list. */
- X{
- X struct flist far *t; /* temporary variable */
- X
- X t = f->nxt;
- X *(f->lst) = t; /* point last to next, */
- X if (t != NULL)
- X t->lst = f->lst; /* and next to last */
- X if (f->name != NULL) /* free memory used */
- X free((voidp *)(f->name));
- X if (f->zname != NULL)
- X free((voidp *)(f->zname));
- X farfree((voidp far *)f);
- X fcount--; /* decrement count */
- X return t; /* return pointer to next */
- X}
- X
- X
- Xlocal int fqcmp(a, b)
- Xvoidp *a, *b; /* pointers to pointers to found entries */
- X/* Used by qsort() to compare entries in the found list by name. */
- X{
- X return strcmp((*(struct flist far **)a)->name,
- X (*(struct flist far **)b)->name);
- X}
- X
- X
- Xlocal int fqcmpz(a, b)
- Xvoidp *a, *b; /* pointers to pointers to found entries */
- X/* Used by qsort() to compare entries in the found list by zname. */
- X{
- X return strcmp((*(struct flist far **)a)->zname,
- X (*(struct flist far **)b)->zname);
- X}
- X
- X
- Xlocal char *last(p)
- Xchar *p; /* sequence of / delimited path components */
- X/* Return a pointer to the start of the last path component. */
- X{
- X char *t; /* temporary variable */
- X
- X#ifdef VMS
- X if ((t = strrchr(p, ']')) != NULL)
- X#else /* !VMS */
- X if ((t = strrchr(p, '/')) != NULL)
- X#endif /* ?VMS */
- X return t + 1;
- X else
- X return p;
- X}
- X
- X
- Xlocal char *msname(n)
- Xchar *n;
- X/* Reduce all path components to MSDOS upper case 8.3 style names. Probably
- X should also check for invalid characters, but I don't know which ones
- X those are. */
- X{
- X int c; /* current character */
- X int f; /* characters in current component */
- X char *p; /* source pointer */
- X char *q; /* destination pointer */
- X
- X p = q = n;
- X f = 0;
- X while ((c = *p++) != 0)
- X if (c == '/')
- X {
- X *q++ = (char)c;
- X f = 0; /* new component */
- X }
- X else if (c == '.')
- X if (f < 9)
- X {
- X *q++ = (char)c;
- X f = 9; /* now in file type */
- X }
- X else
- X f = 12; /* now just excess characters */
- X else
- X if (f < 12 && f != 8)
- X {
- X *q++ = (char)(to_up(c));
- X f++; /* do until end of name or type */
- X }
- X *q = 0;
- X return n;
- X}
- X
- X
- X#ifdef VMS
- Xlocal char *strlower(s)
- Xchar *s; /* string to convert */
- X/* Convert all uppercase letters to lowercase in string s */
- X{
- X char *p; /* scans string */
- X
- X for (p = s; *p; p++)
- X if (*p >= 'A' && *p <= 'Z')
- X *p += 'a' - 'A';
- X return s;
- X}
- X
- Xlocal char *strupper(s)
- Xchar *s; /* string to convert */
- X/* Convert all lowercase letters to uppercase in string s */
- X{
- X char *p; /* scans string */
- X
- X for (p = s; *p; p++)
- X if (*p >= 'a' && *p <= 'z')
- X *p -= 'a' - 'A';
- X return s;
- X}
- X#endif /* VMS */
- X
- Xlocal char *ex2in(x, pdosflag)
- Xchar *x; /* external file name */
- Xint *pdosflag; /* output: force MSDOS file attributes? */
- X/* Convert the external file name to a zip file name, returning the malloc'ed
- X string or NULL if not enough memory. */
- X{
- X char *n; /* internal file name (malloc'ed) */
- X char *t; /* shortened name */
- X int dosflag;
- X
- X#ifdef OS2
- X dosflag = dosify || IsFileSystemFAT(x);
- X if ( !dosify && use_longname_ea && (t = GetLongPathEA(x)) != NULL )
- X {
- X x = t;
- X dosflag = 0;
- X }
- X#else
- X# ifdef MSDOS
- X dosflag = 1;
- X# else /* !MSDOS */
- X dosflag = dosify; /* default for non-DOS and non-OS/2 */
- X# endif /* MSDOS */
- X#endif /* OS2 */
- X
- X /* Find starting point in name before doing malloc */
- X#ifdef MSDOS /* msdos */
- X t = *x && *(x + 1) == ':' ? x + 2 : x;
- X while (*t == '/' || *t == '\\')
- X t++;
- X#else /* !MSDOS */
- X# ifdef VMS /* vms */
- X t = x;
- X if ((n = strrchr(t, ':')) != NULL)
- X t = n + 1;
- X if (*t == '[' && (n = strrchr(t, ']')) != NULL)
- X if ((x = strchr(t, '.')) != NULL && x < n)
- X t = x + 1;
- X else
- X t = n + 1;
- X# else /* !VMS */ /* unix */
- X for (t = x; *t == '/'; t++)
- X ;
- X# endif /* ?VMS */
- X#endif /* ?MSDOS */
- X
- X /* Make changes, if any, to the copied name (leave original intact) */
- X#ifdef MSDOS
- X for (n = t; *n; n++)
- X if (*n == '\\')
- X *n = '/';
- X#endif /* MSDOS */
- X
- X if (!pathput)
- X t = last(t);
- X
- X /* Malloc space for internal name and copy it */
- X if ((n = malloc(strlen(t) + 1)) == NULL)
- X return NULL;
- X strcpy(n, t);
- X
- X#ifdef VMS
- X if ((t = strrchr(n, ']')) != NULL)
- X {
- X *t = '/';
- X while (--t > n)
- X if (*t == '.')
- X *t = '/';
- X }
- X
- X /* Fix from Greg Roelofs: */
- X /* Get current working directory and strip from n (t now = n) */
- X {
- X char cwd[256], *p, *q;
- X int c;
- X
- X if (getcwd(cwd, 256) && ((p = strchr(cwd, '.')) != NULL))
- X {
- X ++p;
- X if ((q = strrchr(p, ']')) != NULL)
- X {
- X *q = '/';
- X while (--q > p)
- X if (*q == '.')
- X *q = '/';
- X /* strip bogus path parts from n */
- X if (strncmp(n, p, (c=strlen(p))) == 0)
- X {
- X q = n + c;
- X while (*t++ = *q++)
- X ;
- X }
- X }
- X }
- X }
- X strlower(n);
- X if (!vmsver)
- X if ((t = strrchr(n, ';')) != NULL)
- X *t = 0;
- X
- X if( (t = strrchr(n, '.')) != NULL )
- X {
- X if( t[1] == 0 ) /* "filename." -> "filename" */
- X *t = 0;
- X else if( t[1] == ';' ) /* "filename.;vvv" -> "filename;vvv" */
- X {
- X char *f;
- X for( f=t+1; *t++ = *f++; )
- X ;
- X }
- X }
- X#endif /* VMS */
- X if (dosify)
- X msname(n);
- X#if defined(MSDOS) && !defined(OS2) && !defined(FORCE_UPPER)
- X else
- X strlwr(n);
- X#endif
- X /* Returned malloc'ed name */
- X if (pdosflag)
- X *pdosflag = dosflag;
- X return n;
- X}
- X
- X
- Xchar *in2ex(n)
- Xchar *n; /* internal file name */
- X/* Convert the zip file name to an external file name, returning the malloc'ed
- X string or NULL if not enough memory. */
- X{
- X char *x; /* external file name */
- X#ifdef VMS
- X char *t; /* scans name */
- X
- X if ((t = strrchr(n, '/')) == NULL)
- X#endif /* VMS */
- X {
- X if ((x = malloc(strlen(n) + 1 + PAD)) == NULL)
- X return NULL;
- X strcpy(x, n);
- X }
- X#ifdef VMS
- X else
- X {
- X if ((x = malloc(strlen(n) + 3 + PAD)) == NULL)
- X return NULL;
- X strcpy(x, "[.");
- X strcpy(x + 2, n);
- X *(t = x + 2 + (t - n)) = ']';
- X while (--t > x)
- X if (*t == '/')
- X *t = '.';
- X }
- X strupper(x);
- X#endif /* VMS */
- X#ifdef OS2
- X if ( !IsFileNameValid(x) )
- X ChangeNameForFAT(x);
- X#endif /* !OS2 */
- X#if defined(FORCE_UPPER) && defined(MSDOS)
- X /* Don't convert to upper case, causes wrong warnings. Keep the
- X * name as it was before in the old zip file.
- X */
- X strupr(x);
- X#endif
- X return x;
- X}
- X
- X
- Xint exclude()
- X/* Change from including to excluding names when procname() called. Return
- X an error code in the ZE_ class. */
- X{
- X struct flist far *f; /* steps through found linked list */
- X extent j; /* index for s */
- X struct flist far **s; /* sorted table */
- X
- X /* sort found list, remove duplicates */
- X if (fcount)
- X {
- X if ((s = (struct flist far **)malloc(
- X fcount * sizeof(struct flist far *))) == NULL)
- X return ZE_MEM;
- X for (j = 0, f = found; f != NULL; f = f->nxt)
- X s[j++] = f;
- X qsort((char *)s, fcount, sizeof(struct flist far *), fqcmp);
- X for (j = fcount - 1; j > 0; j--)
- X if (strcmp(s[j - 1]->name, s[j]->name) == 0)
- X fexpel(s[j]); /* fexpel() changes fcount */
- X qsort((char *)s, fcount, sizeof(struct flist far *), fqcmpz);
- X for (j = 1; j < fcount; j++)
- X if (strcmp(s[j - 1]->zname, s[j]->zname) == 0)
- X {
- X warn("name in zip file repeated: ", s[j]->zname);
- X warn(" first full name: ", s[j - 1]->name);
- X warn(" second full name: ", s[j]->name);
- X return ZE_PARMS;
- X }
- X free((voidp *)s);
- X }
- X exflag = 1;
- X return ZE_OK;
- X}
- X
- X
- Xlocal int newname(n)
- Xchar *n; /* name to add (or exclude) */
- X/* Add (or exclude) a name that is not in the zip file. Return an error
- X code in the ZE_ class. */
- X{
- X char *m;
- X struct flist far *f; /* where in found, or new found entry */
- X struct zlist far *z; /* where in zfiles (if found) */
- X int dosflag;
- X
- X /* Search for name in zip file. If there, mark it, else add to
- X list of new names to do (or remove from that list). */
- X if ((m = ex2in(n, &dosflag)) == NULL)
- X return ZE_MEM;
- X if ((z = zsearch(m)) != NULL)
- X if (exflag)
- X {
- X z->mark = 0;
- X free((voidp *)m);
- X if (verbose)
- X printf("zip diagnostic: excluding %s\n", z->name);
- X }
- X else
- X {
- X free((voidp *)(z->name));
- X free((voidp *)(z->zname));
- X if ((z->name = malloc(strlen(n) + 1 + PAD)) == NULL)
- X return ZE_MEM;
- X strcpy(z->name, n);
- X z->zname = m;
- X z->mark = 1;
- X z->dosflag = dosflag;
- X if (verbose)
- X printf("zip diagnostic: including %s\n", z->name);
- X }
- X else
- X if (exflag)
- X {
- X /* search list for name--if there, remove it */
- X for (f = found; f != NULL; f = f->nxt)
- X if (namecmp(n, f->name) == 0)
- X {
- X fexpel(f);
- X break;
- X }
- X free((voidp *)m);
- X }
- X else
- X {
- X /* allocate space and add to list */
- X if ((f = (struct flist far *)farmalloc(sizeof(struct flist))) == NULL ||
- X (f->name = malloc(strlen(n) + 1 + PAD)) == NULL)
- X {
- X if (f != NULL)
- X farfree((voidp far *)f);
- X return ZE_MEM;
- X }
- X strcpy(f->name, n);
- X f->zname = m;
- X f->dosflag = dosflag;
- X *fnxt = f;
- X f->lst = fnxt;
- X f->nxt = NULL;
- X fnxt = &f->nxt;
- X fcount++;
- X }
- X return ZE_OK;
- X}
- X
- X
- Xint procname(n)
- Xchar *n; /* name to process */
- X/* Process a name or sh expression to operate on (or exclude). Return
- X an error code in the ZE_ class. */
- X{
- X char *a; /* path and name for recursion */
- X dstrm *d; /* directory stream from opend() */
- X char *e; /* pointer to name from readd() */
- X struct flist far *f; /* steps through found list */
- X int m; /* matched flag */
- X char *p; /* path for recursion */
- X struct stat s; /* result of stat() */
- X struct zlist far *z; /* steps through zfiles list */
- X
- X if (strcmp(n, "-") == 0) /* if compressing stdin */
- X return newname(n);
- X else if (
- X#ifdef S_IFLNK /* if symbolic links exist ... */
- X linkput ? lstat(n, &s) :
- X#endif /* S_IFLNK */
- X SSTAT(n, &s)
- X#if defined(__TURBOC__) || defined(VMS)
- X /* Borland and VMS C bug: stat() succeeds on wild card names! */
- X || isshexp(n)
- X#endif
- X )
- X {
- X /* Not a file or directory--search for shell expression in zip file */
- X p = ex2in(n, NULL); /* shouldn't affect matching chars */
- X m = 1;
- X for (z = zfiles; z != NULL; z = z->nxt)
- X if (MATCH(p, z->zname))
- X {
- X z->mark = !exflag;
- X if (verbose)
- X printf("zip diagnostic: %scluding %s\n",
- X exflag ? "ex" : "in", z->name);
- X m = 0;
- X }
- X /* If excluding, also search for expression in found list */
- X if (exflag)
- X {
- X for (f = found; f != NULL;)
- X if (MATCH(p, f->zname))
- X {
- X f = fexpel(f);
- X m = 0;
- X }
- X else
- X f = f->nxt;
- X }
- X free((voidp *)p);
- X if (m)
- X return ZE_MISS; /* no match */
- X }
- X else
- X {
- X /* Live name--use if file, recurse if directory */
- X#if defined(FORCE_UPPER) && defined(MSDOS)
- X# ifndef OS2
- X strupr(n); /* convert to upper case */
- X# else /* OS2 */
- X if (IsFileSystemFAT(n)) strupr(n);
- X# endif /* !OS2 */
- X#endif
- X
- X#ifdef MSDOS
- X for (p = n; *p; p++) /* use / consistently */
- X if (*p == '\\')
- X *p = '/';
- X#endif /* MSDOS */
- X if ((s.st_mode & S_IFDIR) == 0)
- X {
- X /* add or remove name of file */
- X if ((m = newname(n)) != ZE_OK)
- X return m;
- X } else {
- X /* recurse into directory */
- X if (recurse && (d = opend(n)) != NULL)
- X {
- X#ifdef VMS
- X while ((e = readd(d)) != NULL)
- X if ((m = procname(e)) != ZE_OK) /* recurse on name */
- X {
- X /* want to just set warning error and continue */
- X closed(d);
- X return m;
- X }
- X#else /* !VMS */
- X if ((p = malloc(strlen(n)+2)) == NULL)
- X return ZE_MEM;
- X if (strcmp(n, ".") == 0)
- X *p = 0; /* avoid "./" prefix and do not create zip entry */
- X else
- X {
- X strcpy(p, n);
- X a = p + strlen(p);
- X if (a[-1] != '/')
- X strcpy(a, "/");
- X if ((m = newname(p)) != ZE_OK)
- X return m;
- X }
- X while ((e = readd(d)) != NULL)
- X if (strcmp(e, ".") && strcmp(e, ".."))
- X {
- X if ((a = malloc(strlen(p) + strlen(e) + 1)) == NULL)
- X {
- X free((voidp *)p);
- X closed(d);
- X return ZE_MEM;
- X }
- X strcat(strcpy(a, p), e);
- X if ((m = procname(a)) != ZE_OK) /* recurse on name */
- X {
- X free((voidp *)a); free((voidp *)p);
- X closed(d);
- X return m;
- X }
- X free((voidp *)a);
- X }
- X free((voidp *)p);
- X#endif /* ?VMS */
- X closed(d);
- X }
- X }
- X }
- X return ZE_OK;
- X}
- X
- X
- X#if !defined(CRAY) && !defined(__TURBOC__) && !defined(OS2) /* and ... */
- X#if !defined( __GO32__)
- X
- Xlocal int cmptime(p, q)
- Xstruct tm *p, *q; /* times to compare */
- X/* Return negative if time p is before time q, positive if after, and
- X zero if the same */
- X{
- X int r; /* temporary variable */
- X
- X if (p == NULL)
- X return -1;
- X else if ((r = p->tm_year - q->tm_year) != 0)
- X return r;
- X else if ((r = p->tm_mon - q->tm_mon) != 0)
- X return r;
- X else if ((r = p->tm_mday - q->tm_mday) != 0)
- X return r;
- X else if ((r = p->tm_hour - q->tm_hour) != 0)
- X return r;
- X else if ((r = p->tm_min - q->tm_min) != 0)
- X return r;
- X else
- X return p->tm_sec - q->tm_sec;
- X}
- X
- X
- Xlocal time_t invlocal(t)
- Xstruct tm *t; /* time to convert */
- X/* Find inverse of localtime() using bisection. This routine assumes that
- X time_t is an integer type, either signed or unsigned. The expectation
- X is that sometime before the year 2038, time_t will be made a 64-bit
- X integer, and this routine will still work. */
- X{
- X time_t i; /* midpoint of current root range */
- X time_t l; /* lower end of root range */
- X time_t u; /* upper end of root range */
- X
- X /* Bracket the root [0,largest time_t]. Note: if time_t is a 32-bit signed
- X integer, then the upper bound is GMT 1/19/2038 03:14:07, after which all
- X the Unix systems in the world come to a grinding halt. Either that, or
- X all those systems will suddenly find themselves transported to December
- X of 1901 ... */
- X l = 0;
- X u = 1;
- X while (u < (u << 1))
- X u = (u << 1) + 1;
- X
- X /* Find the root */
- X while (u - l > 1)
- X {
- X i = l + ((u - l) >> 1);
- X if (cmptime(localtime(&i), t) <= 0)
- X l = i;
- X else
- X u = i;
- X }
- X return l;
- X}
- X#endif
- X#endif
- X
- X
- Xvoid stamp(f, d)
- Xchar *f; /* name of file to change */
- Xulg d; /* dos-style time to change it to */
- X/* Set last updated and accessed time of file f to the DOS time d. */
- X{
- X#if defined(MACOS)
- X warn("timestamp not implemented yet", "");
- X#else
- X#ifdef __TURBOC__
- X int h; /* file handle */
- X
- X if ((h = open(f, 0)) != -1)
- X {
- X#ifdef ATARI_ST
- X d = ( d >> 16 ) | ( d << 16 );
- X#endif
- X setftime(h, (struct ftime *)&d);
- X close(h);
- X }
- X#else /* !__TURBOC__ */
- X#ifdef VMS
- X int tm_sec, tm_min, tm_hour, tm_mday, tm_mon, tm_year;
- X char timbuf[24];
- X static char *month[] = {"JAN", "FEB", "MAR", "APR", "MAY", "JUN",
- X "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"};
- X struct VMStimbuf {
- X char *actime; /* VMS revision date, ASCII format */
- X char *modtime; /* VMS creation date, ASCII format */
- X } ascii_times = {timbuf, timbuf};
- X
- X /* Convert DOS time to ASCII format for VMSmunch */
- X tm_sec = (int)(d << 1) & 0x3e;
- X tm_min = (int)(d >> 5) & 0x3f;
- X tm_hour = (int)(d >> 11) & 0x1f;
- X tm_mday = (int)(d >> 16) & 0x1f;
- X tm_mon = ((int)(d >> 21) & 0xf) - 1;
- X tm_year = ((int)(d >> 25) & 0x7f) + 1980;
- X sprintf(timbuf, "%02d-%3s-%04d %02d:%02d:%02d.00", tm_mday, month[tm_mon],
- X tm_year, tm_hour, tm_min, tm_sec);
- X
- X /* Set updated and accessed times of f */
- X if (VMSmunch(f, SET_TIMES, &ascii_times) != RMS$_NMF)
- X warn("can't set zipfile time: ", f);
- X
- X#else /* !VMS */
- X#ifdef OS2
- X SetFileTime(f, d);
- X#else /* !OS2 */
- X struct tm t; /* argument for mktime() or invlocal() */
- X time_t u[2]; /* argument for utime() */
- X#ifndef __GO32__
- X extern time_t mktime OF((struct tm *));
- X#endif
- X
- X /* Convert DOS time to time_t format in u[0] and u[1] */
- X t.tm_sec = (int)(d << 1) & 0x3e;
- X t.tm_min = (int)(d >> 5) & 0x3f;
- X t.tm_hour = (int)(d >> 11) & 0x1f;
- X t.tm_mday = (int)(d >> 16) & 0x1f;
- X t.tm_mon = ((int)(d >> 21) & 0xf) - 1;
- X t.tm_year = ((int)(d >> 25) & 0x7f) + 80;
- X#if defined(MSDOS) || defined(OS2) || defined(CRAY)
- X /* mktime() is more reliable than invlocal() because the time range is
- X * wider on MSDOS than on Unix; required for Cray because invlocal assumes
- X * 32-bit ints
- X */
- X u[0] = u[1] = mktime(&t);
- X#else
- X u[0] = u[1] = invlocal(&t);
- X#endif
- X
- X /* Set updated and accessed times of f */
- X utime(f, u);
- X#endif /* ?OS2 */
- X#endif /* ?VMS */
- X#endif /* ?__TURBOC__ */
- X#endif /* ?MACOS */
- X}
- X
- X
- Xlocal void inctime(s)
- Xstruct tm *s; /* time to increment in place */
- X/* Increment the time structure *s by one second, return the result in
- X place. */
- X{
- X int y; /* temporary variable */
- X
- X /* days in each month, except for February */
- X static int days[] = {31,0,31,30,31,30,31,31,30,31,30,31};
- X
- X /* Set days in February from year (1900 is a leap year, 2000 is not) */
- X y = s->tm_year + 1900;
- X days[1] = y % 4 == 0 && (y % 100 != 0 || y % 400 == 0) ? 29 : 28;
- X
- X /* Increment time with carry */
- X if (s->tm_sec != 59)
- X s->tm_sec++;
- X else if (s->tm_sec = 0, s->tm_min != 59)
- X s->tm_min++;
- X else if (s->tm_min = 0, s->tm_hour != 23)
- X s->tm_hour++;
- X else if (s->tm_hour = 0, s->tm_mday != days[s->tm_mon])
- X s->tm_mday++;
- X else if (s->tm_mday = 1, s->tm_mon != 11)
- X s->tm_mon++;
- X else
- X {
- X s->tm_mon = 0;
- X s->tm_year++;
- X }
- X}
- X
- X
- Xulg dostime(y, n, d, h, m, s)
- Xint y; /* year */
- Xint n; /* month */
- Xint d; /* day */
- Xint h; /* hour */
- Xint m; /* minute */
- Xint s; /* second */
- X/* Convert the date y/n/d and time h:m:s to a four byte DOS date and
- X time (date in high two bytes, time in low two bytes allowing magnitude
- X comparison). */
- X{
- X return y < 1980 ? dostime(1980, 1, 1, 0, 0, 0) :
- X (((ulg)y - 1980) << 25) | ((ulg)n << 21) | ((ulg)d << 16) |
- X ((ulg)h << 11) | ((ulg)m << 5) | ((ulg)s >> 1);
- X}
- X
- X
- Xlocal ulg unix2dostime(t)
- Xstatime *t; /* unix time to convert */
- X/* Return the Unix time t in DOS format, rounded up to the next two
- X second boundary. */
- X{
- X struct tm *s; /* result of localtime() */
- X
- X s = localtime(t); /* Use local time since MSDOS does */
- X inctime(s); /* Add one second to round up */
- X return dostime(s->tm_year + 1900, s->tm_mon + 1, s->tm_mday,
- X s->tm_hour, s->tm_min, s->tm_sec);
- X}
- X
- X
- Xulg filetime(f, a, n)
- Xchar *f; /* name of file to get info on */
- Xulg *a; /* return value: file attributes */
- Xlong *n; /* return value: file size */
- X/* If file *f does not exist, return 0. Else, return the file's last
- X modified date and time as an MSDOS date and time. The date and
- X time is returned in a long with the date most significant to allow
- X unsigned integer comparison of absolute times. Also, if a is not
- X a NULL pointer, store the file attributes there, with the high two
- X bytes being the Unix attributes, and the low byte being a mapping
- X of that to DOS attributes. If n is not NULL, store the file size
- X there.
- X If f is "-", use standard input as the file. If f is a device, return
- X a file size of -1 */
- X{
- X struct stat s; /* results of stat() */
- X char name[FNMAX];
- X int len = strlen(f);
- X
- X strcpy(name, f);
- X if (name[len - 1] == '/')
- X name[len - 1] = 0;
- X /* not all systems allow stat'ing a file with / appended */
- X
- X if (strcmp(f, "-") == 0) {
- X if (fstat(fileno(stdin), &s) != 0)
- X error("fstat(stdin)");
- X } else if ((
- X#ifdef S_IFLNK
- X linkput ? lstat(name, &s) :
- X#endif
- X SSTAT(name, &s)) != 0 /* || (s.st_mode & S_IFDIR) != 0 */ )
- X /* Accept about any file kind except directories */
- X return 0;
- X
- X if (a != NULL)
- X#ifdef OS2
- X *a = (s.st_mode << 16) | GetFileMode(name);
- X#else
- X *a = (s.st_mode << 16) | !(s.st_mode & S_IWRITE);
- X#endif
- X if (n != NULL)
- X *n = (s.st_mode & S_IFREG) == 0 ? -1L : s.st_size;
- X
- X#ifdef OS2
- X return GetFileTime(name);
- X#else /* !OS2 */
- X# ifdef VMS
- X return unix2dostime(&s.st_ctime); /* Use creation time in VMS */
- X# else /* !VMS */
- X# ifdef ATARI_ST
- X return s.st_mtime; /* Turbo C doesn't use UNIX times */
- X# else
- X return unix2dostime(&s.st_mtime);
- X# endif
- X# endif /* ?VMS */
- X#endif /* ?OS2 */
- X}
- X
- X
- Xint issymlnk(a)
- Xulg a; /* Attributes returned by filetime() */
- X/* Return true if the attributes are those of a symbolic link */
- X{
- X#ifdef S_IFLNK
- X return ((a >> 16) & S_IFMT) == S_IFLNK;
- X#else /* !S_IFLNK */
- X return (int)a & 0; /* avoid warning on unused parameter */
- X#endif /* ?S_IFLNK */
- X}
- X
- X
- Xint deletedir(d)
- Xchar *d; /* directory to delete */
- X/* Delete the (empty) directory *d. Return the result of rmdir(), delete(),
- X or system(). */
- X{
- X#ifdef MACOS
- X warn("deletedir not implemented yet", "");
- X return 127;
- X#else
- X#ifdef RMDIR
- X /* code from Greg Roelofs, who horked it from Mark Edwards (unzip) */
- X int r, len;
- X char *s; /* malloc'd string for system command */
- X
- X len = strlen(d);
- X if ((s = malloc(len + 34)) == NULL)
- X return 127;
- X
- X#ifdef VMS
- X {
- X char *c; /* pointer into VMS path */
- X /* convert "DEV:[DIR.SUB1.SUB2]" form to "DEV:[DIR.SUB1]SUB2.DIR;0" */
- X strcat(strcpy(s, "set prot=(o:rwed) "), d); /* d starts at s+18 */
- X if (*(c = s+17+len) != ']')
- X {
- X free(s);
- X return 127;
- X }
- X strcpy(c, ".DIR;0"); /* 0 translates to highest version */
- X while (--c > s+18 && *c != '.' && *c != '[') ;
- X if (c == s+18)
- X {
- X free(s);
- X return 127;
- X }
- X if (*c == '.')
- X *c = ']';
- X else if (*--c == ']') /* presumably of form "DEV:[DIR.SUB1.][SUB2]" */
- X { /* (possible to have "DEV:[DIR.SUB1.][][SUB2]"?) */
- X char *b = c + 2;
- X c[-1] = ']';
- X while (*c++ = *b++) ;
- X }
- X else /* must have reached device name: can't delete top level */
- X {
- X free(s);
- X return 127;
- X }
- X }
- X /* unprotect directory and delete it as a file. May fail if exists
- X normal file "foo.dir" on top of directory "foo.dir" */
- X system(s);
- X r = delete(s+18);
- X#else /* !VMS */
- X sprintf(s, "IFS=\" \t\n\" /bin/rmdir %s 2>/dev/null", d);
- X r = system(s);
- X#endif /* ?VMS */
- X free(s);
- X return r;
- X#else /* !RMDIR */
- X return rmdir(d);
- X#endif /* ?RMDIR */
- X#endif /* ?MACOS */
- X}
- X
- X
- X#endif /* !UTIL */
- X
- Xint destroy(f)
- Xchar *f; /* file to delete */
- X/* Delete the file *f, returning non-zero on failure. */
- X{
- X return unlink(f);
- X}
- X
- X
- Xint replace(d, s)
- Xchar *d, *s; /* destination and source file names */
- X/* Replace file *d by file *s, removing the old *s. Return an error code
- X in the ZE_ class. */
- X{
- X struct stat t; /* results of stat() */
- X
- X if (SSTAT(d, &t) == 0 && unlink(d))
- X return ZE_CREAT; /* Can't erase zip file--give up */
- X if (link(s, d)) /* Just move s on top of d */
- X#if !defined(VMS) && !defined(ATARI_ST)
- X /* For VMS & ATARI assume failure is EXDEV */
- X if (errno != EXDEV
- X# ifdef ENOTSAM
- X && errno != ENOTSAM /* Used at least on Turbo C */
- X# endif
- X ) return ZE_CREAT;
- X else
- X#endif
- X {
- X FILE *f, *g; /* source and destination files */
- X int r; /* temporary variable */
- X
- X if ((f = fopen(s, FOPR)) == NULL) {
- X fprintf(stderr," replace: can't open %s\n", s);
- X return ZE_TEMP;
- X }
- X if ((g = fopen(d, FOPW)) == NULL)
- X {
- X fclose(f);
- X return ZE_CREAT;
- X }
- X r = fcopy(f, g, (ulg)-1L);
- X fclose(f);
- X if (fclose(g) || r != ZE_OK)
- X {
- X unlink(d);
- X return r ? (r == ZE_TEMP ? ZE_WRITE : r) : ZE_WRITE;
- X }
- X#ifdef VMS /* only delete if rename failed: previous version may exist */
- X unlink(s);
- X }
- X#else /* !VMS */
- X }
- X unlink(s);
- X#endif /* !VMS */
- X return ZE_OK;
- X}
- X
- X
- Xint getfileattr(f)
- Xchar *f; /* file path */
- X/* Return the file attributes for file f or 0 if failure */
- X{
- X struct stat s;
- X
- X return SSTAT(f, &s) == 0 ? s.st_mode : 0;
- X}
- X
- X
- Xint setfileattr(f, a)
- Xchar *f; /* file path */
- Xint a; /* attributes returned by getfileattr() */
- X/* Give the file f the attributes a, return non-zero on failure */
- X{
- X#if defined (VMS) || defined(MACOS)
- X return 0;
- X#else /* !VMS */
- X return chmod(f, a);
- X#endif /* ?VMS */
- X}
- X
- X
- X#ifdef NO_MKTEMP
- X
- Xchar *tempname(zip)
- X char *zip; /* path name of zip file to generate temp name for */
- X
- X/* Return a temporary file name in its own malloc'ed space.
- X * This function might accidentally destroy an existing file
- X * with extension .$z$ . Use mktemp below if you have it on your system.
- X */
- X{
- X char *p; /* temporary pointer */
- X char *t; /* malloc'ed space for name */
- X
- X if ((t = malloc(strlen(zip)+5)) == NULL)
- X return NULL;
- X strcpy(t, zip);
- X if ((p = strrchr(t, '.')) != NULL &&
- X (!strncmp(p, ".zip", 4) || !strncmp(p, ".ZIP", 4)))
- X /* strncmp to avoid problems with VMS ';' */
- X strcpy(p, ".$z$");
- X else
- X strcat(t, ".$z$");
- X
- X return t;
- X}
- X#else /* !NO_MKTEMP */
- X
- Xchar *tempname(zip)
- X char *zip; /* path name of zip file to generate temp name for */
- X
- X/* Return a temporary file name in its own malloc'ed space, using tempath. */
- X{
- X char *t = zip; /* malloc'ed space for name (use zip to avoid warning) */
- X
- X if (tempath != NULL)
- X {
- X if ((t = malloc(strlen(tempath)+10)) == NULL)
- X return NULL;
- X strcpy(t, tempath);
- X#ifndef VMS
- X if (t[strlen(t)-1] != '/')
- X strcat(t, "/");
- X#endif
- X }
- X else
- X {
- X if ((t = malloc(9)) == NULL)
- X return NULL;
- X *t = 0;
- X }
- X strcat(t, "_ZXXXXXX");
- X return mktemp(t);
- X}
- X
- X#endif /* NO_MKTEMP */
- X
- X
- Xint fcopy(f, g, n)
- XFILE *f, *g; /* source and destination files */
- Xulg n; /* number of bytes to copy or -1 for all */
- X/* Copy n bytes from file *f to file *g, or until EOF if n == -1. Return
- X an error code in the ZE_ class. */
- X{
- X char *b; /* malloc'ed buffer for copying */
- X extent k; /* result of fread() */
- X ulg m; /* bytes copied so far */
- X
- X if ((b = malloc(CBSZ)) == NULL)
- X return ZE_MEM;
- X m = 0;
- X while (n == -1L || m < n)
- X {
- X if ((k = fread(b, 1, n == -1 ?
- X CBSZ : (n - m < CBSZ ? (extent)(n - m) : CBSZ), f)) == 0)
- X if (ferror(f))
- X {
- X free((voidp *)b);
- X return ZE_READ;
- X }
- X else
- X break;
- X if (fwrite(b, 1, k, g) != k)
- X {
- X free((voidp *)b);
- X fprintf(stderr," fcopy: write error\n");
- X return ZE_TEMP;
- X }
- X m += k;
- X }
- X free((voidp *)b);
- X return ZE_OK;
- X}
- X
- X
- X#ifdef CRYPT
- X
- X#ifndef MSDOS
- X
- X#ifdef VMS
- X
- Xint echo(opt)
- X int opt;
- X{
- X/*---------------------------------------------------------------------------
- X Based on VMSmunch.c, which in turn was based on Joe Meadows' file.c code.
- X ---------------------------------------------------------------------------
- X * For VMS v5.x:
- X * IO$_SENSEMODE/SETMODE info: Programming, Vol. 7A, System Programming,
- X * I/O User's: Part I, sec. 8.4.1.1, 8.4.3, 8.4.5, 8.6
- X * sys$assign(), sys$qio() info: Programming, Vol. 4B, System Services,
- X * System Services Reference Manual, pp. sys-23, sys-379
- X * fixed-length descriptor info: Programming, Vol. 3, System Services,
- X * Intro to System Routines, sec. 2.9.2
- X * GRR, 15 Aug 91
- X ---------------------------------------------------------------------------*/
- X static struct dsc$descriptor_s DevDesc =
- X {9, DSC$K_DTYPE_T, DSC$K_CLASS_S, "SYS$INPUT"};
- X /* {dsc$w_length, dsc$b_dtype, dsc$b_class, dsc$a_pointer}; */
- X static short DevChan, iosb[4];
- X static long i, status;
- X static unsigned long oldmode[2], newmode[2]; /* each = 8 bytes */
- X
- X
- X/*---------------------------------------------------------------------------
- X Assign a channel to standard input.
- X ---------------------------------------------------------------------------*/
- X
- X status = sys$assign(&DevDesc, &DevChan, 0, 0);
- X if (!(status & 1))
- X return status;
- X
- X/*---------------------------------------------------------------------------
- X Use sys$qio and the IO$_SENSEMODE function to determine the current tty
- X status (for password reading, could use IO$_READVBLK function instead,
- X but echo on/off will be more general).
- X ---------------------------------------------------------------------------*/
- X
- X status = sys$qio(0, DevChan, IO$_SENSEMODE, &iosb, 0, 0,
- X oldmode, 8, 0, 0, 0, 0);
- X if (!(status & 1))
- X return status;
- X status = iosb[0];
- X if (!(status & 1))
- X return status;
- X
- X/*---------------------------------------------------------------------------
- X Copy old mode into new-mode buffer, then modify to be either NOECHO or
- X ECHO (depending on function argument opt).
- X ---------------------------------------------------------------------------*/
- X
- X newmode[0] = oldmode[0];
- X newmode[1] = oldmode[1];
- X if (opt == 0)
- X newmode[1] |= TT$M_NOECHO; /* set NOECHO bit */
- X else
- X newmode[1] &= ~((unsigned long) TT$M_NOECHO); /* clear NOECHO bit */
- X
- X/*---------------------------------------------------------------------------
- X Use the IO$_SETMODE function to change the tty status.
- X ---------------------------------------------------------------------------*/
- X
- X status = sys$qio(0, DevChan, IO$_SETMODE, &iosb, 0, 0,
- X newmode, 8, 0, 0, 0, 0);
- X if (!(status & 1))
- X return status;
- X status = iosb[0];
- X if (!(status & 1))
- X return status;
- X
- X/*---------------------------------------------------------------------------
- X Deassign the sys$input channel by way of clean-up, then exit happily.
- X ---------------------------------------------------------------------------*/
- X
- X status = sys$dassgn(DevChan);
- X if (!(status & 1))
- X return status;
- X
- X return SS$_NORMAL; /* we be happy */
- X
- X} /* end function echo() */
- X
- X
- X#else /* !VMS */
- X
- Xlocal int echofd = -1; /* file descriptor whose echo is off */
- X
- Xvoid echoff(f)
- Xint f; /* file descriptor to turn echo off on */
- X/* Turn echo off for file descriptor f. Assumes that f is a tty device. */
- X{
- X struct sgttyb sg; /* tty device structure */
- X
- X echofd = f;
- X GTTY(f, &sg); /* get settings */
- X sg.sg_flags &= ~ECHO; /* turn echo off */
- X STTY(f, &sg);
- X}
- X
- Xvoid echon()
- X/* Turn echo back on for file descriptor echofd. */
- X{
- X struct sgttyb sg; /* tty device structure */
- X
- X if (echofd != -1)
- X {
- X GTTY(echofd, &sg); /* get settings */
- X sg.sg_flags |= ECHO; /* turn echo on */
- X STTY(echofd, &sg);
- X echofd = -1;
- X }
- X}
- X
- X#endif /* ?VMS */
- X
- X#endif /* !MSDOS */
- X
- X
- Xchar *getp(m, p, n)
- Xchar *m; /* prompt for password */
- Xchar *p; /* return value: line input */
- Xint n; /* bytes available in p[] */
- X/* Get a password of length n-1 or less into *p using the prompt *m.
- X The entered password is not echoed. Return p on success, NULL on
- X failure (can't get controlling tty). */
- X{
- X char c; /* one-byte buffer for read() to use */
- X int i; /* number of characters input */
- X char *w; /* warning on retry */
- X
- X#ifndef MSDOS
- X#ifndef VMS
- X int f; /* file decsriptor for tty device */
- X
- X /* Turn off echo on tty */
- X if (!isatty(2))
- X return NULL; /* error if not tty */
- X if ((f = open(ttyname(2), 0, 0)) == -1)
- X return NULL;
- X#endif /* !VMS */
- X echoff(f); /* turn echo off */
- X#endif /* !MSDOS */
- X
- X /* Get password */
- X w = "";
- X do {
- X#ifdef VMS /* bug: VMS adds '\n' to NULL fputs (apparently) */
- X if (*w)
- X#endif /* VMS */
- X fputs(w, stderr); /* warning if back again */
- X fputs(m, stderr); /* prompt */
- X fflush(stderr);
- X i = 0;
- X do { /* read line, keeping n */
- X#ifdef MSVMS
- X if ((c = (char)getch()) == '\r')
- X c = '\n';
- X#else /* !MSVMS */
- X read(f, &c, 1);
- X#endif /* ?MSVMS */
- X if (i < n)
- X p[i++] = c;
- X } while (c != '\n');
- X putc('\n', stderr); fflush(stderr);
- X w = "(line too long--try again)\n";
- X } while (p[i-1] != '\n');
- X p[i-1] = 0; /* terminate at newline */
- X
- X#ifndef MSDOS
- X echon(); /* turn echo back on */
- X#ifndef VMS
- X close(f);
- X#endif /* !VMS */
- X#endif /* !MSDOS */
- X
- X /* Return pointer to password */
- X return p;
- X}
- X
- X#endif /* ?CRYPT */
- X
- X
- X#ifdef ZMEM
- X
- X/************************/
- X/* Function memset() */
- X/************************/
- X
- X/*
- X * memset - for systems without it
- X * bill davidsen - March 1990
- X */
- X
- Xchar *
- Xmemset(buf, init, len)
- Xregister char *buf; /* buffer loc */
- Xregister int init; /* initializer */
- Xregister unsigned int len; /* length of the buffer */
- X{
- X char *start;
- X
- X start = buf;
- X while (len--) *(buf++) = init;
- X return(start);
- X}
- X
- X
- X/************************/
- X/* Function memcpy() */
- X/************************/
- X
- Xchar *
- Xmemcpy(dst,src,len) /* v2.0f */
- Xregister char *dst, *src;
- Xregister unsigned int len;
- X{
- X char *start;
- X
- X start = dst;
- X while (len--)
- X *dst++ = *src++;
- X return(start);
- X}
- X
- X
- X/************************/
- X/* Function memcmp() */
- X/************************/
- X
- Xint
- Xmemcmp(b1,b2,len) /* jpd@usl.edu -- 11/16/90 */
- Xregister char *b1, *b2;
- Xregister unsigned int len;
- X{
- X
- X if (len) do { /* examine each byte (if any) */
- X if (*b1++ != *b2++)
- X return (*((uch *)b1-1) - *((uch *)b2-1)); /* exit when miscompare */
- X } while (--len);
- X
- X return(0); /* no miscompares, yield 0 result */
- X}
- X
- X#endif /* ZMEM */
- X
- X#ifdef __TURBOC__
- X
- X/************************/
- X/* Function fcalloc() */
- X/************************/
- X
- X/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
- X * and farmalloc(64K) returns a pointer with an offset of 8, so we
- X * must fix the pointer. Warning: the pointer must be put back to its
- X * original form in order to free it.
- X * For MSC, use halloc instead of this function (see tailor.h).
- X */
- Xvoid far * fcalloc(items, size)
- X unsigned items; /* number of items */
- X unsigned size; /* item size */
- X{
- X void far * buf = farmalloc((ulg)items*size + 16L);
- X /* Normalize the pointer to seg:0 */
- X *((int*)&buf+1) += ((unsigned)((uch*)buf-0) + 15) >> 4;
- X *(int*)&buf = 0;
- X return buf; /* buf stays NULL if alloc failed */
- X}
- X
- X#endif /* __TURBOC__ */
- END_OF_FILE
- if test 57097 -ne `wc -c <'fileio.c'`; then
- echo shar: \"'fileio.c'\" unpacked with wrong size!
- fi
- # end of 'fileio.c'
- fi
- echo shar: End of archive 2 \(of 11\).
- cp /dev/null ark2isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 11 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still must unpack the following archives:
- echo " " ${MISSING}
- fi
- exit 0
- exit 0 # Just in case...
-