home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-10-21 | 54.0 KB | 2,044 lines |
- Newsgroups: comp.sources.misc
- From: kirsch@usasoc.soc.mil (David Kirschbaum)
- Subject: v23i089: zip - Portable zip v1.0, Part02/09
- Message-ID: <1991Oct21.042040.7851@sparky.imd.sterling.com>
- X-Md4-Signature: 669c19bba3344b485495d627dd694d7b
- Date: Mon, 21 Oct 1991 04:20:40 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: kirsch@usasoc.soc.mil (David Kirschbaum)
- Posting-number: Volume 23, Issue 89
- Archive-name: zip/part02
- Environment: UNIX, Minix, MSDOS, OS/2, VMS
-
- #! /bin/sh
- # 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: dir_os2.c fileio.c zip.prj
- # Wrapped by kent@sparky on Sun Oct 20 22:58:52 1991
- 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 9)."'
- if test -f 'dir_os2.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'dir_os2.c'\"
- else
- echo shar: Extracting \"'dir_os2.c'\" \(5569 characters\)
- sed "s/^X//" >'dir_os2.c' <<'END_OF_FILE'
- X/*
- X * @(#)dir.c 1.4 87/11/06 Public Domain.
- X *
- X * A public domain implementation of BSD directory routines for
- X * MS-DOS. Written by Michael Rendell ({uunet,utai}michael@garfield),
- X * August 1897
- X * Ported to OS/2 by Kai Uwe Rommel
- X * December 1989, February 1990
- X * Change for HPFS support, October 1990
- X */
- X
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X
- X#include <stdio.h>
- X#include <stdlib.h>
- X#include <malloc.h>
- X#include <string.h>
- X#include <ctype.h>
- X
- X#define INCL_NOPM
- X#include <os2.h>
- X
- X#include "dir_os2.h"
- X
- X
- Xint attributes = A_DIR | A_HIDDEN;
- X
- X
- Xstatic char *getdirent(char *);
- Xstatic void free_dircontents(struct _dircontents *);
- X
- Xstatic HDIR hdir;
- Xstatic USHORT count;
- Xstatic FILEFINDBUF find;
- X
- X
- XDIR *opendir(char *name)
- X{
- X struct stat statb;
- X DIR *dirp;
- X char c;
- X char *s;
- X struct _dircontents *dp;
- X char nbuf[MAXPATHLEN + 1];
- X int len;
- X
- X strcpy(nbuf, name);
- X len = strlen (nbuf);
- X s = nbuf + len;
- X
- X#if 1
- X if ( ((c = nbuf[strlen(nbuf) - 1]) == '\\' || c == '/') &&
- X (strlen(nbuf) > 1) )
- X {
- X nbuf[strlen(nbuf) - 1] = 0;
- X
- X if ( nbuf[strlen(nbuf) - 1] == ':' )
- X strcat(nbuf, "\\.");
- X }
- X else
- X if ( nbuf[strlen(nbuf) - 1] == ':' )
- X strcat(nbuf, ".");
- X#else
- X if ( len && ((c = nbuf[len-1]) == '\\' || c == '/' || c == ':') )
- X {
- X nbuf[len++] = '.'; /* s now points to '.' */
- X nbuf[len] = 0;
- X }
- X#endif
- X
- X if (stat(nbuf, &statb) < 0 || (statb.st_mode & S_IFMT) != S_IFDIR)
- X return NULL;
- X
- X if ( (dirp = malloc(sizeof(DIR))) == NULL )
- X return NULL;
- X
- X#if 1
- X if ( nbuf[strlen(nbuf) - 1] == '.' )
- X strcpy(nbuf + strlen(nbuf) - 1, "*.*");
- X else
- X if ( ((c = nbuf[strlen(nbuf) - 1]) == '\\' || c == '/') &&
- X (strlen(nbuf) == 1) )
- X strcat(nbuf, "*.*");
- X else
- X strcat(nbuf, "\\*.*");
- X#else
- X if ( *s == 0 )
- X *s++ = '\\';
- X
- X strcpy (s, "*.*");
- X#endif
- X
- X dirp -> dd_loc = 0;
- X dirp -> dd_contents = dirp -> dd_cp = NULL;
- X
- X if ((s = getdirent(nbuf)) == NULL)
- X return dirp;
- X
- X do
- X {
- X if (((dp = malloc(sizeof(struct _dircontents))) == NULL) ||
- X ((dp -> _d_entry = malloc(strlen(s) + 1)) == NULL) )
- X {
- X if (dp)
- X free(dp);
- X free_dircontents(dirp -> dd_contents);
- X
- X return NULL;
- X }
- X
- X if (dirp -> dd_contents)
- X {
- X dirp -> dd_cp -> _d_next = dp;
- X dirp -> dd_cp = dirp -> dd_cp -> _d_next;
- X }
- X else
- X dirp -> dd_contents = dirp -> dd_cp = dp;
- X
- X strcpy(dp -> _d_entry, s);
- X dp -> _d_next = NULL;
- X
- X dp -> _d_size = find.cbFile;
- X dp -> _d_mode = find.attrFile;
- X dp -> _d_time = *(unsigned *) &(find.ftimeLastWrite);
- X dp -> _d_date = *(unsigned *) &(find.fdateLastWrite);
- X }
- X while ((s = getdirent(NULL)) != NULL);
- X
- X dirp -> dd_cp = dirp -> dd_contents;
- X
- X return dirp;
- X}
- X
- X
- Xvoid closedir(DIR * dirp)
- X{
- X free_dircontents(dirp -> dd_contents);
- X free(dirp);
- X}
- X
- X
- Xstruct direct *readdir(DIR * dirp)
- X{
- X static struct direct dp;
- X
- X if (dirp -> dd_cp == NULL)
- X return NULL;
- X
- X dp.d_namlen = dp.d_reclen =
- X strlen(strcpy(dp.d_name, dirp -> dd_cp -> _d_entry));
- X
- X dp.d_ino = 0;
- X
- X dp.d_size = dirp -> dd_cp -> _d_size;
- X dp.d_mode = dirp -> dd_cp -> _d_mode;
- X dp.d_time = dirp -> dd_cp -> _d_time;
- X dp.d_date = dirp -> dd_cp -> _d_date;
- X
- X dirp -> dd_cp = dirp -> dd_cp -> _d_next;
- X dirp -> dd_loc++;
- X
- X return &dp;
- X}
- X
- X
- Xvoid seekdir(DIR * dirp, long off)
- X{
- X long i = off;
- X struct _dircontents *dp;
- X
- X if (off >= 0)
- X {
- X for (dp = dirp -> dd_contents; --i >= 0 && dp; dp = dp -> _d_next);
- X
- X dirp -> dd_loc = off - (i + 1);
- X dirp -> dd_cp = dp;
- X }
- X}
- X
- X
- Xlong telldir(DIR * dirp)
- X{
- X return dirp -> dd_loc;
- X}
- X
- X
- Xstatic void free_dircontents(struct _dircontents * dp)
- X{
- X struct _dircontents *odp;
- X
- X while (dp)
- X {
- X if (dp -> _d_entry)
- X free(dp -> _d_entry);
- X
- X dp = (odp = dp) -> _d_next;
- X free(odp);
- X }
- X}
- X
- X
- Xstatic char *getdirent(char *dir)
- X{
- X int done;
- X
- X if (dir != NULL)
- X { /* get first entry */
- X hdir = HDIR_CREATE;
- X count = 1;
- X done = DosFindFirst(dir, &hdir, attributes,
- X &find, sizeof(find), &count, 0L);
- X }
- X else /* get next entry */
- X done = DosFindNext(hdir, &find, sizeof(find), &count);
- X
- X if (done == 0)
- X return find.achName;
- X else
- X {
- X DosFindClose(hdir);
- X return NULL;
- X }
- X}
- X
- X
- X/* ISFAT.C
- X *
- X * Autor: Kai Uwe Rommel
- X * Datum: Sun 28-Oct-1990
- X *
- X * Compiler: MS C ab 6.00
- X * System: OS/2 ab 1.2
- X */
- X
- X#define LABEL "isfat.c"
- X#define VERSION "1.0"
- X
- X
- X/* #include <stdio.h>
- X#include <stdlib.h>
- X#include <string.h>
- X#include <ctype.h>
- X
- X#define INCL_NOPM
- X#include <os2.h> */
- X
- X
- Xint IsFileSystemFAT(char *dir)
- X{
- X USHORT nDrive;
- X ULONG lMap;
- X BYTE bData[64], bName[3];
- X USHORT cbData;
- X static USHORT nLastDrive = -1, nResult;
- X
- X if ( _osmode == DOS_MODE )
- X return TRUE;
- X else
- X {
- X /* We separate FAT and HPFS+other file systems here.
- X at the moment I consider other systems to be similar to HPFS,
- X i.e. support long file names and beeing case sensitive */
- X
- X if ( isalpha(dir[0]) && (dir[1] == ':') )
- X nDrive = toupper(dir[0]) - '@';
- X else
- X DosQCurDisk(&nDrive, &lMap);
- X
- X if ( nDrive == nLastDrive )
- X return nResult;
- X
- X bName[0] = (char) (nDrive + '@');
- X bName[1] = ':';
- X bName[2] = 0;
- X
- X nLastDrive = nDrive;
- X cbData = sizeof(bData);
- X
- X if ( !DosQFSAttach(bName, 0U, 1U, bData, &cbData, 0L) )
- X nResult = !strcmp(bData + (*(USHORT *) (bData + 2) + 7), "FAT");
- X else
- X nResult = FALSE;
- X
- X /* End of this ugly code */
- X return nResult;
- X }
- X}
- X
- X
- X
- X/* End of ISFAT.C */
- END_OF_FILE
- if test 5569 -ne `wc -c <'dir_os2.c'`; then
- echo shar: \"'dir_os2.c'\" unpacked with wrong size!
- fi
- # end of 'dir_os2.c'
- 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'\" \(44358 characters\)
- sed "s/^X//" >'fileio.c' <<'END_OF_FILE'
- X/*
- X
- X Copyright (C) 1990,1991 Mark Adler, Richard B. Wales, and Jean-loup Gailly.
- 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#include <errno.h>
- X
- X#ifdef S_IWUSR /* For 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 MSDOS
- X# include <io.h>
- X# ifdef __TURBOC__
- X# include <dir.h>
- X# else /* !__TURBOC__ */
- X# include <direct.h>
- 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# endif /* VMS */
- X# define MATCH shmatch
- X#endif /* ?MSDOS */
- 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#ifdef DIRENT
- X# ifndef MINIX
- X# ifndef TERMIO
- X# define TERMIO
- X# endif /* !TERMIO */
- X# endif /* !MINIX */
- X#endif /* DIRENT */
- X
- X
- X#ifndef EXPORT
- X# ifdef MSVMS
- X# ifdef MSDOS
- X# include <conio.h>
- X# else /* !MSDOS */
- X# define getch() getc(stderr)
- 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# else /* !CONVEX */
- X# include <sys/termio.h>
- X# define sgttyb termio
- X# define sg_flags c_lflag
- X# endif /* ?CONVEX */
- X int ioctl OF((int, int, voidp *));
- 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 /* !EXPORT */
- X
- X
- X
- X/* For directory access */
- X#ifndef UTIL
- X#ifdef DIRENT /* use getdents() */
- X# ifdef MINIX
- 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#else /* !DIRENT */ /* use opendir(), etc. */
- X# ifdef CONVEX
- X# include <dirent.h>
- X# define direct dirent
- X# endif /* CONVEX */
- X# ifdef NDIR
- X# include "ndir.h" /* for HPUX */
- X# else /* !NDIR */
- X# ifdef MSDOS
- X# ifdef OS2
- X# include "dir_os2.h"
- X# else /* !OS2 */
- X# include <dos.h>
- X# ifdef __TURBOC__
- 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 } DIR;
- X# endif /* ?OS2 */
- X# else /* !MSDOS */
- X# ifdef VMS
- X# include <rms.h>
- X# include <ssdef.h>
- X# include <descrip.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# include <sys/dir.h>
- 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 /* !UTIL */
- X
- X
- X/* Library functions not in (most) header files */
- Xchar *mktemp OF((char *));
- Xint link OF((char *, char *));
- Xint unlink OF((char *));
- X#ifndef CONVEX
- X# ifndef AIX
- X int chmod OF((char *, int));
- X# endif /* !AIX */
- X#endif /* !CONVEX */
- 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/* 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 *);
- X local int newname(char *);
- X local void inctime(struct tm *);
- X local ulg unix2dostime(time_t *);
- X# ifndef __TURBOC__
- X local int cmptime(struct tm *, struct tm *);
- X local time_t invlocal(struct tm *);
- X# endif /* !__TURBOC__ */
- X#endif /* PROTO */
- X
- X
- X
- X#ifndef OS2
- X#ifdef MSDOS
- 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 if (FFIRST(p, d))
- X {
- X free((voidp *)p);
- X return NULL;
- X }
- X free((voidp *)p);
- 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 if (FNEXT(d))
- X return NULL;
- X return (struct direct *)d;
- X}
- X# define closedir free
- X#endif /* MSDOS */
- X#endif /* !OS2 */
- X
- X
- X#ifdef VMS
- 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 -1;
- 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
- Xint wild(p)
- Xchar *p; /* 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 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 *q; /* temporary variable */
- X int r; /* temporary variable */
- X char v[4]; /* space for device current directory */
- X
- X /* If excluding, don't bother with file system */
- X if (exflag)
- X return procname(p);
- X
- X /* Normalize pattern to upper case, path delimiter as '/'. */
- X#ifndef OS2
- X strupr(p); /* convert to upper case */
- X#endif /* !OS2 */
- X for (q = p; *q; q++) /* use / consistently */
- X if (*q == '\\')
- X *q = '/';
- X
- X /* Only name can have special matching characters */
- X if ((q = isshexp(p)) != NULL &&
- X (strrchr(q, '/') != NULL || strrchr(q, ':') != NULL))
- X return ZE_PARMS;
- X
- X /* Separate path and name */
- X if ((q = strrchr(p, '/')) != NULL)
- X *q++ = 0;
- X else if (*p && *(p+1) == ':')
- X {
- X q = p + 2;
- X v[0] = *p;
- X strcpy(v+1, ":.");
- X p = v;
- X }
- X else
- X {
- X q = p;
- X p = ".";
- X }
- X if (*p == 0)
- X p = "/";
- X
- X /* Search that level for matching names */
- X if ((d = opend(p)) == NULL)
- X return ZE_MISS;
- X if (strcmp(p+1, ":.") == 0)
- X *(p+2) = 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)
- X procname(e);
- X else if (*p && strcmp(p+1, ":") == 0)
- X {
- X if ((n = malloc(strlen(e) + 3)) == NULL)
- X return ZE_MEM;
- X r = procname(strcat(strcpy(n, p), e));
- X free((voidp *)n);
- X if (r)
- X return r;
- X }
- X else
- X {
- X if ((n = malloc(strlen(p) + strlen(e) + 2)) == NULL)
- X return ZE_MEM;
- X if (strcmp(p, "/"))
- X strcpy(n, p);
- X else
- X *n = 0;
- X r = procname(strcat(strcat(n, "/"), e));
- X free((voidp *)n);
- X if (r)
- X return r;
- X }
- X }
- X closed(d);
- X
- X /* Done */
- X return f ? ZE_OK : ZE_MISS;
- 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
- X#define TOUP(c) ((c) >= 'a' && (c) <= 'z' ? (c)-'a'+'A' : (c))
- 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)(TOUP(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 <= 'a')
- X *p -= 'a' - 'A';
- X return s;
- X}
- X#endif /* VMS */
- X
- X
- Xlocal char *ex2in(x)
- Xchar *x; /* external file name */
- 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
- 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 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 /* Make changes, if any, to the copied name (leave original intact) */
- X#ifdef MSDOS
- X for (t = n; *t; t++)
- X if (*t == '\\')
- X *t = '/';
- X#endif /* MSDOS */
- 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#endif /* VMS */
- X if (dosify)
- X msname(n);
- X
- X /* Returned malloc'ed name */
- 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 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 int 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
- 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)) == 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 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 (strcmp(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 *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 (
- X#ifdef S_IFLNK /* if symbolic links exist ... */
- X linkput ? lstat(n, &s) :
- X#endif /* S_IFLNK */
- X stat(n, &s)
- X#ifdef __TURBOC__ /* Borland bug: stat() succeeds on wild card names! */
- X || isshexp(n)
- X#endif /* __TURBOC__ */
- X )
- X {
- X /* Not a file--search for shell expression in zip file */
- X p = ex2in(n); /* 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#ifdef MSDOS
- X#ifndef OS2
- X strupr(n); /* convert to upper case */
- X#endif /* !OS2 */
- X for (p = n; *p; p++) /* use / consistently */
- X if (*p == '\\')
- X *p = '/';
- X#endif /* MSDOS */
- X switch (s.st_mode & S_IFMT)
- X {
- X case S_IFREG: /* add or remove name of file */
- X#ifdef S_IFLNK
- X case S_IFLNK:
- X#endif /* S_IFLNK */
- X if ((m = newname(n)) != ZE_OK)
- X return m;
- X break;
- X case S_IFDIR: /* 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 */
- X else
- X {
- X strcpy(p, n);
- X a = p + strlen(p);
- X if (a[-1] != '/')
- X strcpy(a, "/");
- 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#ifndef __TURBOC__
- 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 ((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 /* !__TURBOC__ */
- 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#ifdef __TURBOC__
- X int h; /* file handle */
- X
- X if ((h = open(f, 0)) != -1)
- X {
- X setftime(h, (struct ftime *)&d);
- X close(h);
- X }
- X#else /* !__TURBOC__ */
- X#ifdef VMS
- X warn("timestamp not implemented yet under VMS", "");
- X#else /* !VMS */
- X struct tm t; /* argument for invlocal() */
- X time_t u[2]; /* argument for utime() */
- 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 u[0] = u[1] = invlocal(&t);
- X
- X /* Set updated and accessed times of f */
- X utime(f, u);
- X#endif /* ?VMS */
- X#endif /* ?__TURBOC__ */
- 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)
- Xtime_t *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{
- X struct stat s; /* results of stat() */
- X
- X#ifdef S_IFLNK
- X if (linkput ? lstat(f, &s) == 0 && ((s.st_mode & S_IFMT) == S_IFREG ||
- X (s.st_mode & S_IFMT) == S_IFLNK) :
- X#else /* !S_IFLNK */
- X if (
- X#endif /* ?S_IFLNK */
- X stat(f, &s) == 0 && (s.st_mode & S_IFMT) == S_IFREG)
- X {
- X if (a != NULL)
- X *a = (s.st_mode << 16) | !(s.st_mode & S_IWRITE);
- X if (n != NULL)
- X *n = s.st_size;
- X#ifdef VMS
- X return unix2dostime(&s.st_ctime); /* Use creation time in VMS */
- X#else /* !VMS */
- X return unix2dostime(&s.st_mtime);
- X#endif /* ?VMS */
- X }
- X else
- X return 0;
- 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 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}
- X
- X
- X#endif /* !UTIL */
- X
- 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 (stat(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#ifndef VMS /* For VMS, assume failure is EXDEV */
- X if (errno != EXDEV)
- X return ZE_CREAT;
- X else
- X#endif /* !VMS */
- X {
- X FILE *f, *g; /* source and destination files */
- X int r; /* temporary variable */
- X
- X if ((f = fopen(s, FOPR)) == NULL)
- X return ZE_TEMP;
- 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 -1 if failure */
- X{
- X struct stat s;
- X
- X return stat(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#ifdef VMS
- X return 0;
- X#else /* !VMS */
- X return chmod(f, a);
- X#endif /* ?VMS */
- X}
- X
- X
- Xchar *tempname(c)
- Xint c; /* character to insert in name */
- X/* Return a temporary file name in its own malloc'ed space, using tempath. */
- X{
- X char *p; /* temporary pointer */
- X char *t; /* malloc'ed space for name */
- X
- X if (tempath != NULL)
- X {
- X if ((t = malloc(strlen(tempath)+10)) == NULL)
- X return NULL;
- X strcpy(t, tempath);
- X if (t[strlen(t)-1] != '/')
- X strcat(t, "/");
- X }
- X else
- X {
- X if ((t = malloc(9)) == NULL)
- X return NULL;
- X *t = 0;
- X }
- X p = t + strlen(t);
- X *p++ = '_';
- X *p++ = (char)c;
- X strcpy(p, "XXXXXX");
- X return mktemp(t);
- X}
- 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(BSZ)) == NULL)
- X return ZE_MEM;
- X m = 0;
- X while (n == -1L || m < n)
- X {
- X if ((k = fread(b, 1, n == -1 ?
- X BSZ : (n - m < BSZ ? (extent)(n - m) : BSZ), 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 return ZE_TEMP;
- X }
- X m += k;
- X }
- X free((voidp *)b);
- X return ZE_OK;
- X}
- X
- X
- X#ifndef EXPORT
- X
- X#ifndef MSVMS
- 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 /* !MSVMS */
- 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 MSVMS
- 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 echoff(f); /* turn echo off */
- X#endif /* !MSVMS */
- X
- X /* Get password */
- X w = "";
- X do {
- 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 MSVMS
- X /* Turn echo back on */
- X echon(); /* turn echo back on */
- X close(f);
- X#endif /* !MSVMS */
- X
- X /* Return pointer to password */
- X return p;
- X}
- X
- X#endif /* !EXPORT */
- 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) - *--((uch *)b2)); /* exit when miscompare */
- X } while (--len);
- X
- X return(0); /* no miscompares, yield 0 result */
- X}
- X
- X#endif /* ZMEM */
- END_OF_FILE
- if test 44358 -ne `wc -c <'fileio.c'`; then
- echo shar: \"'fileio.c'\" unpacked with wrong size!
- fi
- # end of 'fileio.c'
- fi
- if test -f 'zip.prj' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'zip.prj'\"
- else
- echo shar: Extracting \"'zip.prj'\" \(620 characters\)
- sed "s/^X//" >'zip.prj' <<'END_OF_FILE'
- Xzip.c (zip.h ziperr.h tailor.h revision.h)
- Xzipfile.c (zip.h ziperr.h tailor.h)
- Xzipup.c (zip.h ziperr.h tailor.h revision.h)
- Xfileio.c (zip.h ziperr.h tailor.h)
- Xutil.c (zip.h ziperr.h tailor.h)
- Xtempf.c (tempf.h tailor.h)
- Xshrink.c (zip.h ziperr.h tempf.h tailor.h)
- Xcrypt.c (zip.h ziperr.h tailor.h)
- Xglobals.c (zip.h ziperr.h tailor.h)
- Ximplode.c (implode.h crypt.h ziperr.h tempf.h tailor.h)
- Xim_lmat.c (implode.h crypt.h ziperr.h tempf.h tailor.h)
- Xim_ctree.c (implode.h crypt.h ziperr.h tempf.h tailor.h)
- Xim_bits.c (implode.h crypt.h ziperr.h tempf.h tailor.h)
- Xim_lm.obj
- END_OF_FILE
- if test 620 -ne `wc -c <'zip.prj'`; then
- echo shar: \"'zip.prj'\" unpacked with wrong size!
- fi
- # end of 'zip.prj'
- fi
- echo shar: End of archive 2 \(of 9\).
- cp /dev/null ark2isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 9 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...
- --
- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM
- Sterling Software, IMD UUCP: uunet!sparky!kent
- Phone: (402) 291-8300 FAX: (402) 291-4362
- Please send comp.sources.misc-related mail to kent@uunet.uu.net.
-