home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Source Code 1992 March
/
Source_Code_CD-ROM_Walnut_Creek_March_1992.iso
/
usenet
/
altsrcs
/
3
/
3604
< prev
next >
Wrap
Internet Message Format
|
1991-07-10
|
48KB
From: dhesi@bsu-cs.bsu.edu (Rahul Dhesi)
Newsgroups: alt.sources
Subject: zoo 2.1 source part 06/15
Message-ID: <12772@bsu-cs.bsu.edu>
Date: 10 Jul 91 09:49:10 GMT
Checksum: 2199207214 (verify with "brik -cv")
Submitted-by: dhesi@bsu-cs.bsu.edu
Archive-name: zoo210/part06
---- Cut Here and feed the following to sh ----
#!/bin/sh
# This is part 06 of zoo210
# ============= msdos.c ==============
if test -f 'msdos.c' -a X"$1" != X"-c"; then
echo 'x - skipping msdos.c (File already exists)'
else
echo 'x - extracting msdos.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'msdos.c' &&
/* msdos.c */
X
/* Highly system-dependent routines go here */
X
/* settime() */
X
/* Accepts a date/time in DOS format and sets the file time. Returns 1
if OK, 0 if error */
X
#include "options.h"
#include "zoo.h"
#include "zooio.h" /* to satisfy declarations in zoofns.h */
#include "zoofns.h"
#include "errors.i"
#include <stdio.h> /* to get fileno() */
X
/* register definitions specific for Turbo C */
union REGS {
X struct { unsigned ax, bx, cx, dx, si, di, carry, flags; } x;
X struct { unsigned char al, ah, bl, bh, cl, ch, dl, dh; } h;
};
X
int settime (file,date,time)
ZOOFILE file;
unsigned date, time;
{
X extern intdos();
X union REGS regs;
X regs.h.ah = 0x57; /* DOS FileTimes call */
X regs.h.al = 0x01; /* set date/time request */
X regs.x.bx = fileno (file); /* get handle */
X regs.x.cx = time;
X regs.x.dx = date;
X
X /* first flush file so later write won't occur on close */
X fflush (file);
X
X intdos (®s, ®s);
X if (regs.x.carry != 0)
X return (0);
X else
X return (1);
} /* settime */
X
/* gets date and time of file */
gettime (file,date,time)
ZOOFILE file;
unsigned *date, *time;
{
X union REGS regs;
X regs.h.ah = 0x57; /* DOS FileTimes call */
X regs.h.al = 0x00; /* get date/time request */
X regs.x.bx = fileno (file); /* get handle */
X intdos (®s, ®s);
X *time = regs.x.cx;
X *date = regs.x.dx;
X if (regs.x.carry != 0)
X return (0);
X else
X return (1);
} /* settime */
X
X
/* space() */
X
/* Returns free space in bytes on disk n (0 = default, 1 = A, etc.). Returns
X 0 if drive number is invalid. Before getting disk space, the function
X requests DOS to flush its internal buffers */
X
unsigned long space (drive, alloc_size)
int drive;
int *alloc_size;
{
X unsigned long free_space;
X union REGS regs;
X
X regs.h.ah = 0x0d; /* disk reset DOS call */
X intdos (®s, ®s);
X
X regs.h.ah = 0x36; /* GetFreeSpace DOS call */
X regs.h.dl = drive;
X intdos (®s, ®s);
X
X /* space = clusters * sectors/cluster * bytes/sector. */
X /* ax=0xFFFF on error */
X
X /* cluster size = sectors/cluster * bytes/sector */
X *alloc_size = regs.x.ax * regs.x.cx;
X
X /* space = cluster * alloc_size */
X if (regs.x.ax == 0xffff)
X return (0L); /* invalid drive */
X else {
X free_space = ((unsigned long) regs.x.bx) * *alloc_size;
X return (free_space);
X }
}
SHAR_EOF
chmod 0644 msdos.c ||
echo 'restore of msdos.c failed'
Wc_c="`wc -c < 'msdos.c'`"
test 2290 -eq "$Wc_c" ||
echo 'msdos.c: original size 2290, current size' "$Wc_c"
fi
# ============= mstime.i ==============
if test -f 'mstime.i' -a X"$1" != X"-c"; then
echo 'x - skipping mstime.i (File already exists)'
else
echo 'x - extracting mstime.i (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'mstime.i' &&
#ifndef LINT
static char mstimeid[]="@(#) mstime.i 2.2 88/01/24 12:47:58";
#endif /* LINT */
X
/*
(C) Copyright 1987 Rahul Dhesi -- All rights reserved
*/
X
#define BASEYEAR 1970
X
/****************
Function mstime() converts time in seconds since January 1 of BASEYEAR
to MS-DOS format date and time.
*/
mstime(longtime, date, time)
long longtime; /* input: seconds since Jan 1, BASEYEAR */
int *date, *time; /* output: MS-DOS format date and time */
X
{
X static int daysinmo[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
#define FEBRUARY 1
X int year, month, day, hour, min, sec;
X long secsinhour, secsinday, secsinyear, secsinleapyear;
X
X int leapyear; /* is this a leap year? */
X int done; /* control variable */
X
X secsinhour = (long) (60 * 60); /* seconds in an hour */
X secsinday = 24 * secsinhour; /* seconds in a day */
X secsinyear = 365 * secsinday; /* seconds in a year */
X secsinleapyear = secsinyear + secsinday; /* seconds in a leap year */
X
#ifdef DEBUG
printf("mstime: input longtime = %ld\n", longtime);
#endif
X
X /* We can't handle dates before 1970 so force longtime positive */
X if (longtime < 0)
X longtime = 0;
X
X /*
X Step through years from BASEYEAR onwards, subtracting number of
X seconds in each, stopping just before longtime would become negative.
X */
X year = BASEYEAR;
X done = 0;
X while (!done) {
X long yearlength;
X leapyear = (year % 4 == 0 && year % 100 != 0 || year % 400 == 0);
X if (leapyear)
X yearlength = secsinleapyear;
X else
X yearlength = secsinyear;
X
X if (longtime >= yearlength) {
X longtime -= yearlength;
X year++;
X } else
X done++;
X }
X
X /* Now `year' contains year and longtime contains remaining seconds */
X daysinmo[FEBRUARY] = leapyear ? 29 : 28;
X
X month = 0; /* range is 0:11 */
X while (longtime > daysinmo[month] * secsinday) {
X longtime = longtime - daysinmo[month] * secsinday;
X month++;
X }
X month++; /* range now 1:12 */
X
X day = longtime / secsinday; /* day of month, range 0:30 */
X longtime = longtime % secsinday;
X day++; /* day of month, range 1:31 */
X
X hour = longtime / secsinhour; /* hours, range 0:23 */
X longtime = longtime % secsinhour;
X
X min = longtime / 60L; /* minutes, range 0:59 */
X longtime = longtime % 60L;
X
X sec = longtime; /* seconds, range 0:59 */
X
#ifdef DEBUG
printf("mstime: date = %4d/%02d/%02d time = %02d:%02d:%02d\n",
X year, month, day, hour, min, sec);
if (leapyear)
X printf("(leap year)\n");
#endif
X
X if (year < 1980)
X year = 1980;
X *date = day + (month << 5) + ((year - 1980) << 9);
X *time = (sec / 2) + (min << 5) + (hour << 11);
}
SHAR_EOF
chmod 0644 mstime.i ||
echo 'restore of mstime.i failed'
Wc_c="`wc -c < 'mstime.i'`"
test 2860 -eq "$Wc_c" ||
echo 'mstime.i: original size 2860, current size' "$Wc_c"
fi
# ============= needed.c ==============
if test -f 'needed.c' -a X"$1" != X"-c"; then
echo 'x - skipping needed.c (File already exists)'
else
echo 'x - extracting needed.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'needed.c' &&
#ifndef LINT
static char sccsid[]="@(#) needed.c 2.16 88/01/31 15:54:37";
#endif /* LINT */
X
/*
Copyright (C) 1986, 1987 Rahul Dhesi -- All rights reserved
(C) Copyright 1988 Rahul Dhesi -- All rights reserved
*/
X
#define STRCMP(s1,op,s2) (strcmp(s1,s2) op 0)
X
#include "options.h"
/* Accepts a filename from an archive and returns 1 if a command-line
X argument filename matches it. Otherwise returns 0. Returns
X 1 if no arguments were supplied (so by default, all files will
X be extracted */
X
#include "zoo.h"
X
#ifdef NEEDCTYP
#include <ctype.h> /* for tolower() */
#else
#include "portable.h"
#endif
X
#include "zooio.h"
#include "zoofns.h"
#include "various.h"
#include "debug.h"
X
extern int next_arg; /* filenames start at this position */
extern int arg_count; /* count of arguments supplied to program */
extern char **arg_vector; /* vector of arguments supplied to program */
/* Uses FIRST_ARG in zoo.h, so must be recompiled when switching
X between Ooz and Zoo */
X
int needed(pathname, direntry, header)
char *pathname;
struct direntry *direntry;
struct zoo_header *header;
{
X register int i;
X register char *arg;
X char *justname;
X char arg_copy[PATHSIZE]; /* working copy of an argument */
X char path_copy[PATHSIZE]; /* working copy of pathname */
X char *p; /* a temporary pointer */
X char *q; /* a temporary pointer */
X
X /* if no filenames supplied, match latest version of each
X (but match any version if versions not enabled) */
X if (arg_count <= FIRST_ARG &&
X (!(header->vdata & VFL_ON) ||
X !(direntry->vflag & VFL_ON) || (direntry->vflag & VFL_LAST))) {
X
X return (1); /* .. then all files are needed */
X }
X
X /* count backwards and stop if '+' is encountered */
X for (i = arg_count-1; i >= next_arg; i--) {
X arg = arg_vector[i];
#ifdef FOLD
X str_lwr(pathname); str_lwr(arg);
#endif
#ifdef DEBUG
printf("needed: testing [%s] and [%s]\n", pathname, arg);
#endif
X if (STRCMP(arg,==,"+"))
X return (0);
X
X /* If the argument contains a slash, the match fails if the
X path prefixes don't match */
X if (strchr(arg, *(char *)PATH_CH) != NULL) { /* found slash */
X strcpy(arg_copy,arg);
X strcpy(path_copy,pathname);
X p = findlast(arg_copy, PATH_CH);
X if (p != NULL)
X *p = '\0';
X else {
X p = findlast (arg_copy, VER_INPUT);
X if (p != NULL)
X *p = '\0';
X }
X p = findlast(path_copy, PATH_CH);
X if (p != NULL)
X *p = '\0';
X else {
X p = findlast (path_copy, VER_DISPLAY);
X if (p != NULL)
X *p = '\0';
X }
X if (!match_half(path_copy, arg_copy)) {
#ifdef DEBUG
printf ("needed(): match failed for [%s] and [%s]\n",
X path_copy, arg_copy);
#endif
X continue; /* no match this time in loop */
X }
X }
X
X /*
X We reach here either if the pattern had no slashes, or if it had a
X slash but the path prefixes matched. Now we will test to see if the
X filename parts match. If the argument contains VER_INPUT character,
X then this separates the filename from a version number, and only that
X specific version will match. If not, then only the latest version
X will match. However, if the argument has a version character but
X nothing following it, that matches all versions. Also, version
X 0 matches only the latest version and version ^0 matches all
X versions except the latest one.
X */
X strcpy (arg_copy, arg); /* local copy of argument */
X strcpy (path_copy, pathname); /* local copy of pathname */
X p = findlast(arg_copy, VER_INPUT); /* p is version in argument */
X q = findlast(path_copy, VER_DISPLAY); /* q is version in archive */
X if (p != NULL && p != lastptr(arg_copy)) {/* nonnull version in arg */
X if (q != NULL) { /* nonnull ver. in archive */
X char *pp = p+1; /* point to actual version */
X char *qq = q+1;
X if (STRCMP(pp, ==, "0") && !(direntry->vflag & VFL_LAST) ||
X STRCMP(pp, ==, "^0") && (direntry->vflag & VFL_LAST)) {
X debug(("needed: no match versions [%s] and [%s]\n", qq, pp))
X continue;
X }
X if (STRCMP(pp, !=, "0") && STRCMP(pp, !=, "^0") &&
X !match_half (qq, pp)) {
X debug(("needed: no match versions [%s] and [%s]\n", qq, pp))
X continue; /* no match this loop */
X }
X }
X }
X /* Special case test: If argument has version but no filename,
X then filename is assumed to match */
X if (p == arg_copy) { /* 1st char is version char */
X return (1); /* .. so declare a match */
X }
X
X /*
X Reach here if argument has no version character, or if argument has
X version character and it matches version in pathname. Now we check to
X see if argument has no version character and if pathname is latest
X version. If so, the versions do match; if not, then the match fails.
X But if version numbering is not enabled, then versions always match.
X If the match fails, we do a "continue", else we fall through and
X proceed to test the filenames. (Note: It is intuitively better
X to first compare filenames and then see if versions match, but
X since they are both just independent fields, it's equally correct
X to compare versions first, as we are doing here, and then see if
X filenames match. It may even be more efficient.)
X */
X
X if (p == NULL && /* no version char typed */
X !( /* NOT */
X (direntry->vflag & VFL_ON) == 0 || /* no versions */
X (direntry->vflag & VFL_LAST) || /* .. or latest version */
X q == NULL /* .. or no version char */
X )
X )
X {
#ifdef DEBUG
printf("needed: fail--no version typed and not latest version\n");
#endif
X continue; /* match fails */
X }
X /* versions match and we fall through */;
X
X /* reach here if versions match -- so strip them and compare rest */
X if (p != NULL)
X *p = '\0'; /* strips version from arg_copy */
X if (q != NULL)
X *q = '\0'; /* strips version from path_copy */
X
X justname = nameptr(path_copy); /* filename without any pathname */
X if (match_half (justname, nameptr(arg_copy)))
X return (1);
#ifdef DEBUG
printf ("needed: fname-only match failed [%s] and [%s]\n",
X justname, nameptr(arg_copy));
#endif
X
X /* try for a character range */
X if (match_half (arg, "?-?")) { /* character range given */
X if (arg[0] <= *justname && arg[2] >= *justname)
X return (1);
X }
X }
X return (0);
X
} /* needed */
X
/***********************/
/*
match_half() compares a pattern with a string. Wildcards accepted in
the pattern are: "*" for zero or more arbitrary characters; "?"
for any one characters. Unlike the MS-DOS wildcard match, "*" is
correctly handled even if it isn't at the end of the pattern. ".'
is not special.
X
Originally written by Jeff Damens of Columbia University Center for
Computing Activities. Taken from the source code for C-Kermit version
4C.
*/
X
int match_half (string, pattern)
register char *string, *pattern;
{
X char *psave,*ssave; /* back up pointers for failure */
X psave = ssave = NULL;
X while (1) {
#ifdef IGNORECASE
X for (;
X tolower(*pattern) == tolower(*string);
X pattern++,string++ ) /* skip first */
#else
X for (; *pattern == *string; pattern++,string++) /* skip first */
#endif /* IGNORECASE */
X
X if (*string == '\0')
X return(1); /* end of strings, succeed */
X if (*string != '\0' && *pattern == '?') {
X pattern++; /* '?', let it match */
X string++;
X } else if (*pattern == '*') { /* '*' ... */
X psave = ++pattern; /* remember where we saw it */
X ssave = string; /* let it match 0 chars */
X } else if (ssave != NULL && *ssave != '\0') { /* if not at end */
X /* ...have seen a star */
X string = ++ssave; /* skip 1 char from string */
X pattern = psave; /* and back up pattern */
X } else
X return(0); /* otherwise just fail */
X }
}
X
SHAR_EOF
chmod 0644 needed.c ||
echo 'restore of needed.c failed'
Wc_c="`wc -c < 'needed.c'`"
test 8266 -eq "$Wc_c" ||
echo 'needed.c: original size 8266, current size' "$Wc_c"
fi
# ============= nextfile.c ==============
if test -f 'nextfile.c' -a X"$1" != X"-c"; then
echo 'x - skipping nextfile.c (File already exists)'
else
echo 'x - extracting nextfile.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'nextfile.c' &&
#ifndef LINT
static char sccsid[]="@(#) nextfile.c 2.2 87/12/26 12:23:43";
#endif /* LINT */
X
#include "options.h"
/*
Copyright (C) 1986, 1987 Rahul Dhesi -- All rights reserved
*/
/*
Functions to collect filenames from command line etc. Nextfile() is
used by both Atoz and Zoo. Wildcard expansion by nextfile() is specific to
MS-DOS and this implementation is specific to Microsoft C. If the symbol
PORTABLE is defined, nextfile() becomes effectively a no-op that will return
the original filespec the first time and NULL subsequently.
*/
X
#define FMAX 3 /* Number of different filename patterns */
X
#ifndef OK_STDIO
#include <stdio.h>
#define OK_STDIO
#endif
#include "various.h"
#include "zoo.h" /* solely to define PATHSIZE */
X
#ifdef PORTABLE
#ifndef SPECNEXT
/* If portable version, nextfile() is effectively a no-op and any wildcard
expansion must be done by the runtime system before the command line
is received by this program
*/
char *nextfile (what, filespec, fileset)
int what; /* whether to initialize or match */
register char *filespec; /* filespec to match if initializing */
register int fileset; /* which set of files */
{
X static int first_time [FMAX+1];
X static char saved_fspec [FMAX+1][PATHSIZE]; /* our own copy of filespec */
X
X if (what == 0) {
X strcpy (saved_fspec[fileset], filespec); /* save the filespec */
X first_time[fileset] = 1;
X return NULL;
X }
X
X if (first_time[fileset]) {
X first_time[fileset] = 0;
X return saved_fspec[fileset];
X } else {
X return NULL;
X }
}
#endif /* SPECNEXT */
#else
/* if not PORTABLE then */
X
#include <dir.h>
#include <dos.h>
#include "assert.h" /* macro definition: assert() macro */
X
void fcbpath PARMS((struct ffblk *, char *, char *));
X
X
/*******************/
/*
nextfile() returns the name of the next source file matching a filespec.
X
INPUT
X what: A flag specifying what to do. If "what" is 0, nextfile()
X initializes itself. If "what" is 1, nextfile() returns the next
X matching filename.
X filespec: The filespec, usually containing wildcard characters, that
X specifies which files are needed. If "what" is 0, filespec must be
X the filespec for which matching filenames are needed. If "what" is 1,
X nextfile() does not use "filespec" and "filespec" should be NULL to
X avoid an assertion error during debugging.
X fileset: nextfile() can keep track of more than one set of filespecs.
X The fileset specifies which filespec is being matched and therefore
X which set of files is being considered. "fileset" can be in the
X range 0:FMAX. Initialization of one fileset does not affect the
X other filesets.
X
OUTPUT
X IF what == 0 THEN
X return value is NULL
X ELSE IF what == 1 THEN
X IF a matching filename is found THEN
X return value is pointer to matching filename including supplied path
X ELSE
X IF at least one file matched previously but no more match THEN
X return value is NULL
X ELSE IF supplied filespec never matched any filename THEN
X IF this is the first call with what == 1 THEN
X return value is pointer to original filespec
X ELSE
X return value is NULL
X END IF
X END IF
X END IF
X END IF
X
NOTE
X
X Initialization done when "what"=0 is not dependent on the correctness
X of the supplied filespec but simply initializes internal variables
X and makes a local copy of the supplied filespec. If the supplied
X filespec was illegal, the only effect is that the first time that
X nextfile() is called with "what"=1, it will return the original
X filespec instead of a matching filename. That the filespec was
X illegal will become obvious when the caller attempts to open the
X returned filename for input/output and the open attempt fails.
X
USAGE HINTS
X
nextfile() can be used in the following manner:
X
X char *filespec; -- will point to filespec
X char *this_file; -- will point to matching filename
X filespec = parse_command_line(); -- may contain wildcards
X FILE *stream;
X
X nextfile (0, filespec, 0); -- initialize fileset 0
X while ((this_file = nextfile(1, (char *) NULL, 0)) != NULL) {
X stream = fopen (this_file, "whatever");
X if (stream == NULL)
X printf ("could not open %s\n", this_file);
X else
X perform_operations (stream);
X }
*/
X
char *nextfile (what, filespec, fileset)
int what; /* whether to initialize or match */
register char *filespec; /* filespec to match if initializing */
register int fileset; /* which set of files */
{
X static struct ffblk ffblk[FMAX+1];
X static int first_time [FMAX+1];
X static char pathholder [FMAX+1][PATHSIZE]; /* holds a pathname to return */
X static char saved_fspec [FMAX+1][PATHSIZE];/* our own copy of filespec */
X int ffretval; /* return value from findfirst() or findnext() */
X
X assert(fileset >= 0 && fileset <= FMAX);
X if (what == 0) {
X assert(filespec != NULL);
X strcpy (saved_fspec[fileset], filespec); /* save the filespec */
X first_time[fileset] = 1;
X return (NULL);
X }
X
X assert(what == 1);
X assert(filespec == NULL);
X assert(first_time[fileset] == 0 || first_time[fileset] == 1);
X
X if (first_time[fileset]) /* first time -- initialize etc. */
X ffretval = findfirst(saved_fspec[fileset], &ffblk[fileset], 0);
X else
X ffretval = findnext(&ffblk[fileset]);
X
X if (ffretval != 0) { /* if error status */
X if (first_time[fileset]) { /* if file never matched then */
X first_time[fileset] = 0;
X return (saved_fspec[fileset]);/* return original filespec */
X } else { /* else */
X first_time[fileset] = 0; /* */
X return (NULL); /* return (NULL) for no more */
X }
X } else { /* a file matched */
X first_time[fileset] = 0;
X /* add path info */
X fcbpath (&ffblk[fileset], saved_fspec[fileset], pathholder[fileset]);
X return (pathholder[fileset]); /* matching path */
X }
} /* nextfile */
X
/*******************/
/*
fcbpath() accepts a pointer to an ffblk structure, a character pointer
to a pathname that may contain wildcards, and a character pointer to a
buffer. Copies into buffer the path prefix from the pathname and the
filename prefix from the ffblk so that it forms a complete path.
*/
X
void fcbpath (ffblk, old_path, new_path)
struct ffblk *ffblk;
char *old_path;
register char *new_path;
{
X register int i;
X int length, start_pos;
X
X strcpy(new_path, old_path); /* copy the whole thing first */
X length = strlen(new_path);
X i = length - 1; /* i points to end of path */
X while (i >= 0 && new_path[i] != '/' && new_path[i] != '\\' && new_path[i] != ':')
X i--;
X /* either we found a "/", "\", or ":", or we reached the beginning of
X the name. In any case, i points to the last character of the
X path part. */
X start_pos = i + 1;
X for (i = 0; i < 13; i++)
X new_path[start_pos+i] = ffblk->ff_name[i];
X new_path[start_pos+13] = '\0';
}
#endif /* PORTABLE */
SHAR_EOF
chmod 0644 nextfile.c ||
echo 'restore of nextfile.c failed'
Wc_c="`wc -c < 'nextfile.c'`"
test 7588 -eq "$Wc_c" ||
echo 'nextfile.c: original size 7588, current size' "$Wc_c"
fi
# ============= nixmode.i ==============
if test -f 'nixmode.i' -a X"$1" != X"-c"; then
echo 'x - skipping nixmode.i (File already exists)'
else
echo 'x - extracting nixmode.i (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'nixmode.i' &&
#ifndef LINT
/* @(#) nixmode.i 1.2 88/01/24 12:48:57 */
static char modeid[]="@(#) nixmode.i 1.2 88/01/24 12:48:57";
#endif
X
/*
(C) Copyright 1988 Rahul Dhesi -- All rights reserved
X
UNIX-specific routines to get and set file attribute. These might be
usable on other systems that have the following identical things:
fileno(), fstat(), chmod(), sys/types.h and sys/stat.h.
*/
X
/*
Get file attributes. Currently only the lowest nine of the
**IX mode bits are used. Also we return bit 23=0 and bit 22=1,
which means use portable attribute format, and use attribute
value instead of using default at extraction time.
*/
X
unsigned long getfattr (f)
ZOOFILE f;
{
X int fd;
X struct stat buf; /* buffer to hold file information */
X fd = fileno(f);
X if (fstat (fd, &buf) == -1)
X return (NO_FATTR); /* inaccessible -- no attributes */
X else
X return (unsigned long) (buf.st_mode & 0x1ffL) | (1L << 22);
}
X
/*
Set file attributes. Only the lowest nine bits are used.
*/
X
int setfattr (f, a)
char *f; /* filename */
unsigned long a; /* atributes to set */
{
X return (chmod (f, (int) (a & 0x1ff)));
}
SHAR_EOF
chmod 0644 nixmode.i ||
echo 'restore of nixmode.i failed'
Wc_c="`wc -c < 'nixmode.i'`"
test 1127 -eq "$Wc_c" ||
echo 'nixmode.i: original size 1127, current size' "$Wc_c"
fi
# ============= nixtime.i ==============
if test -f 'nixtime.i' -a X"$1" != X"-c"; then
echo 'x - skipping nixtime.i (File already exists)'
else
echo 'x - extracting nixtime.i (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'nixtime.i' &&
#ifndef LINT
static char nixtimeid[]="@(#) nixtime.i 2.3 88/01/24 12:49:28";
#endif /* LINT */
X
/*
Time handling routines for UNIX systems. These are included by the file
machine.c as needed.
X
The contents of this file are hereby released to the public domain.
X
X -- Rahul Dhesi 1986/12/31
*/
X
struct tm *localtime();
X
/*****************
Function gettime() gets the date and time of the file handle supplied.
Date and time is in MSDOS format.
*/
int gettime (file, date, time)
ZOOFILE file;
unsigned *date, *time;
{
X struct stat buf; /* buffer to hold file information */
X struct tm *tm; /* will hold year/month/day etc. */
X int handle;
X handle = fileno(file);
X if (fstat (handle, &buf) == -1) {
X prterror ('w', "Could not get file time\n");
X *date = *time = 0;
X } else {
X tm = localtime (&buf.st_mtime); /* get info about file mod time */
X *date = tm->tm_mday + ((tm->tm_mon + 1) << 5) +
X ((tm->tm_year - 80) << 9);
X *time = tm->tm_sec / 2 + (tm->tm_min << 5) +
X (tm->tm_hour << 11);
X }
X
}
X
/*****************
Function setutime() sets the date and time of the filename supplied.
Date and time is in MSDOS format. It assumes the existence of a function
mstonix() that accepts MSDOS format time and returns **IX format time,
and a function gettz() that returns the difference (localtime - gmt)
in seconds, taking daylight savings time into account.
*/
int setutime(path,date,time)
char *path;
unsigned int date, time;
{
X long mstonix();
X long gettz();
X long utimbuf[2];
X utimbuf[0] = utimbuf[1] = gettz() + mstonix (date, time);
X return (utime (path, utimbuf));
}
X
/****************
Function mstonix() accepts an MSDOS format date and time and returns
a **IX format time. No adjustment is done for timezone.
*/
X
long mstonix (date, time)
unsigned int date, time;
{
X int year, month, day, hour, min, sec, daycount;
X long longtime;
X /* no. of days to beginning of month for each month */
X static int dsboy[12] = { 0, 31, 59, 90, 120, 151, 181, 212,
X 243, 273, 304, 334};
X
X if (date == 0 && time == 0) /* special case! */
X return (0L);
X
X /* part of following code is common to zoolist.c */
X year = (((unsigned int) date >> 9) & 0x7f) + 1980;
X month = ((unsigned int) date >> 5) & 0x0f;
X day = date & 0x1f;
X
X hour = ((unsigned int) time >> 11)& 0x1f;
X min = ((unsigned int) time >> 5) & 0x3f;
X sec = ((unsigned int) time & 0x1f) * 2;
X
/*
DEBUG and leap year fixes thanks to Mark Alexander
<uunet!amdahl!drivax!alexande>
*/
#ifdef DEBUG
X printf ("mstonix: year=%d month=%d day=%d hour=%d min=%d sec=%d\n",
X year, month, day, hour, min, sec);
#endif
X
X /* Calculate days since 1970/01/01 */
X daycount = 365 * (year - 1970) + /* days due to whole years */
X (year - 1969) / 4 + /* days due to leap years */
X dsboy[month-1] + /* days since beginning of this year */
X day-1; /* days since beginning of month */
X
X if (year % 4 == 0 &&
X year % 400 != 0 && month >= 3) /* if this is a leap year and month */
X daycount++; /* is March or later, add a day */
X
X /* Knowing the days, we can find seconds */
X longtime = daycount * 24L * 60L * 60L +
X hour * 60L * 60L + min * 60 + sec;
X return (longtime);
}
SHAR_EOF
chmod 0644 nixtime.i ||
echo 'restore of nixtime.i failed'
Wc_c="`wc -c < 'nixtime.i'`"
test 3434 -eq "$Wc_c" ||
echo 'nixtime.i: original size 3434, current size' "$Wc_c"
fi
# ============= options.c ==============
if test -f 'options.c' -a X"$1" != X"-c"; then
echo 'x - skipping options.c (File already exists)'
else
echo 'x - extracting options.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'options.c' &&
#ifndef LINT
static char sccsid[]="@(#) options.c 2.1 87/12/25 12:23:56";
#endif /* LINT */
X
/*
Copyright (C) 1986, 1987 Rahul Dhesi -- All rights reserved
*/
/*
Here we define routines specific to only a few systems. Routines are
selected based on defined symbols. Routines specific to only one
system are in machine.c for the appropriate system.
*/
X
#include "options.h"
#include "zooio.h"
#include "various.h"
#include "zoo.h"
#include "zoofns.h"
#include "errors.i"
X
#ifdef REN_LINK
/* rename using link() followed by unlink() */
/*
The following code assumes that if unlink() returns nonzero, then the
attempt to unlink failed. If unlink() ever returns nonzero after actually
unlinking the file, then the file being renamed will be lost!!! Test this
thoroughly. It is assumed that link() and unlink() return zero if no
error else nonzero.
*/
int chname (newname, oldname)
char *newname, *oldname;
{
X int status;
X if (link (oldname, newname) == 0) { /* if we can create new name */
X status = unlink (oldname); /* unlink old one */
X if (status != 0) { /* if unlink of old name failed */
X unlink (newname); /* cancel new link */
X return (-1); /* return error */
X } else
X return (0);
X }
X else /* couldn't create new link */
X return (-1);
}
#else
/* else not REN_LINK */
X
int chname (newname, oldname)
char *newname, *oldname;
{
#ifdef REN_STDC
X if (rename(oldname, newname) != 0) /* ANSI standard */
#else
X if (rename(newname, oldname) != 0) /* its reverse */
#endif
X return (-1);
X else
X return (0);
}
#endif /* end of not REN_LINK */
X
/*
Standard exit handler; not used if specific system defines its
own.
*/
#ifndef SPECEXIT
void zooexit (status)
int status;
{
X exit (status);
}
#endif
SHAR_EOF
chmod 0644 options.c ||
echo 'restore of options.c failed'
Wc_c="`wc -c < 'options.c'`"
test 1874 -eq "$Wc_c" ||
echo 'options.c: original size 1874, current size' "$Wc_c"
fi
# ============= options.doc ==============
if test -f 'options.doc' -a X"$1" != X"-c"; then
echo 'x - skipping options.doc (File already exists)'
else
echo 'x - extracting options.doc (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'options.doc' &&
/* derived from: options.doc 1.4 88/08/22 15:24:59 */
/* $Source: /usr/home/dhesi/zoo/RCS/options.doc,v $ */
/* $Id: options.doc,v 1.5 91/07/09 02:53:10 dhesi Exp $ */
X
Documentation about the file options.h.
X
The file options.h defines various symbols and macros that are needed
to ensure system-independence. The basic philosophy is to use a
distinct symbol for each attribute that varies from machine to machine.
Then, for each new system, we define symbols corresponding to its
attributes. Thus, ideally, the only place in Zoo code that we actually
use the name of a machine is in this file, in portable.h, and possibly in
machine.h and options.c. Everywhere else in the code we only use
names of attributes.
X
LOOK IN THE FOLLOWING FILES WHEN MAKING CHANGES TO SUPPORT A NEW SYSTEM:
X
X options.h, portable.h, machine.c
X
ALSO GLANCE AT THESE FILES TO MAKE SURE THEY WILL WORK:
X
X zooio.h, machine.h
X
Machine names:
X
MSC Microsoft C under MS-DOS (not currently in use)
TURBOC Turbo C++ 1.0 under MS-DOS (works, compiled version is
X separately distributed)
SYS_V Most releases of System V (works)
VMS VAX/VMS 5.4 (works, stream-LF files only)
BSD4_3 4.3BSD an most derivatives (works)
MCH_AMIGA AmigaDOS Aztec/Manx C (not tested; compiled version
X will eventually follow)
X
X
MERGED OR MIXED SYSTEMS. Many vendors of **IX systems take one of the
two (System V or BSD) and add features from the other. In some cases
they do a terrible job of reconciling irreconcilable differences between
the two, such that the merged system will now compile neither System V
stuff nor BSD stuff. If you are dealing with such a system, try
compiling with both BSD4_3 and SYS_V in turn, and see if one of them
works. If not, then go through the list of compilation symbols below
and pick a set that matches your system.
X
------------------------------------------------------------------------
NOTE: The term "zoofile" below refers to an open file of type
ZOOFILE. Currently this is defined to be equivalent to a standard
buffered file pointer of type "ZOOFILE *" but this could change in the
future. Dependence on exact definition of ZOOFILE is localized to a
few files: options.h, portable.h, portable.c, and machine.c.
------------------------------------------------------------------------
X
Attributes of systems:
X
CHEKDIR
X Test each supplied filename and if it is a directory or other special
X type of file, do not try to add it to an archive. If CHEKDIR is
X defined, then machine.c must also contain function isadir() that
X tests a supplied zoofile and returns 1 if it corresponds to a
X directory or other special type of file, else 0.
CHEKUDIR
X Like CHEKDIR but use function isuadir() that tests a pathname, not
X a zoofile. Both CHEKDIR and CHEKUDIR may be defined, if both
X functions isadir() and isuadir() are available; in this case
X zoo code will use both and will execute slightly faster.
X (However, simultaneous definition of CHEKDIR and CHEKUDIR has
X not been tested.)
DISK_CH
X If defined, must hold the value of a character that separates a
X disk name from the rest of the pathname. All characters up to and
X including this character will be removed from a pathname before it
X is stored in an archive. Usually a colon (':').
EXISTS
X If defined, is assumed to be a macro that accepts a filename and
X returns an int value of 1 if the file exists and 0 if it doesn't.
X If not defined, existence of files is tested by attempting to open
X them for read or write access.
FATTR
X If defined, file attributes will be preserved. A function
X getfattr(f) must also exist that returns the attributes of a
X zoofile f (or of a pathname f, if the symbol FATTR_FNAME is
X also defined); and a function setfattr(f, a) must exist that
X sets the attributes of a file with pathname f to the value a.
X For more details see the source code in sysv.c and bsd.c. Currently
X the attribute value a is required to be in the zoo portable
X format. The lowest nine bits of this format correspond to
X the **IX mode bits described for chmod(2) and these are the only
X bits currently used.
FATTR_FNAME
X If defined, and if FATTR is also defined, zoo code will
X obtain the attributes of a file by calling the function
X getfattr(f) and supplying it with filename f. If FATTR_FNAME
X is not defined, then getfattr(f) is supplied a zoofile f.
ANSI_PROTO
X Use ANSI-style function prototypes declarations.
VOIDPTR
X The type of a generic pointer, as returned by malloc(). This
X should be defined as void * in an ANSI C environment. In most
X other environments it will be char *.
LINT
X If defined, SCCS identifier strings will not be included in the
X generated code. This will make the code smaller and will also
X avoid complaints from lint about unused variables. This symbol
X should be defined in the Makefile, NOT in `options.h', otherwise
X it will not be fully effective.
FOLD
X Fold filenames to lowercase. Define this for case-insensitive filesystems
FPUTCHAR
X If defined, a library function fputchar() is assumed available
X that is like fput() but is a function, not a macro, to save
X space. If not defined Zoo uses its own fputchar() function.
PORTABLE
X Use portable functions --- define for every system except MS-DOS
PURIFY
X When filenames are being read from standard input, ignore all
X characters begining with the first blank or tab encountered.
X This will allow filenames to be fed from a program that produces
X lines containing filenames followed by other information that
X should be ignored. Should be defined for most non-**IX systems.
DONT_SORT
X Don't sort filename arguments -- files will be stored in the
X exact order in which names are supplied on the command line.
X Not currently used for any system, but could be used if memory
X is really tight.
NOENUM
X Compiler does not support enumerations
FNLIMIT
X Pathname length limit for this system
NEEDCTYP
X If defined, tells the code to include the header file ctype.h for
X use by character conversion macros. If and only if NEEDCTYP is not
X defined, macros or appropriate function declarations can be put in
X portable.h. Zoo uses isupper(), isdigit(), toascii(), and tolower().
X If NEEDCTYP is not defined, the symbol USE_ASCII can be defined to
X cause zoo to assume the ASCII character set and use its own isupper(),
X isdigit(), toascii(), and tolower() functions, possibly making the
X executable code smaller.
USE_ASCII
X See description of NEEDCTYP. USE_ASCII should not be defined if
X NEEDCTYP is defined, else there may be conflicts between macro
X and function names.
NIXTIME
X If defined, a function setutime() must be defined that will set the
X date and time of a file whose pathname is supplied. If not defined,
X a function settime() must be defined that will do the same for
X a zoofile.
GETUTIME
X If defined, a function getutime() must be defined that will return
X the MS-DOS format date and time of the specified filename. If this
X symbol is not defined, then a function gettime() must be defined
X that will do the same for a zoofile instead of a filename.
NOSIGNAL
X Don't use signals because library doesn't support them
T_SIGNAL
X The data type returned by a signal handler. Historically
X "int", but "void" in ANSI C.
PATH_CH
X The character that separates the directory name from the filename
X in a pathname. String value.
PATH_SEP
X The set of characters that may separate preceding directory/device
X information from the filename. String value.
EXT_SEP is the union of PATH_SEP and the set of characters separating a
X filename extension from the rest of the filename. String value.
EXT_CH
X Character that separates base part of filename from extension.
X Char value.
NEED_MEMSET If defined, zoo will define its own equivalent of memset().
X if not defined, zoo will try to link with a standard library function
X memset().
EXT_DFLT
X default extension for archives. String. Currently ".zoo".
NIXFNAME
X If defined, PATH_CH, PATH_SEP, EXT_SEP, EXT_CH, and EXT_DFLT get defined
X to conform to **IX conventions and should not be separately defined
MSFNAME
X if defined, PATH_CH, PATH_SEP, EXT_SEP, EXT_CH, EXT_DFLT, and
X DISK_CH get defined to conform to MS-DOS conventions and should
X not be separately defined (not currently implemented)
FORCESLASH
X If defined any backslashes in names of files will be converted to
X slashes before the files are added to an archive. This is useful
X for MSDOS-like systems that accept both slashes and backslashes,
X since the standard archive format allows only slashes as directory
X separators.
REN_LINK
X Rename a file by using link() followed by unlink() (e.g. Xenix, System V)
REN_STDC
X Use ANSI standard rename function: "int rename(old, new)" (e.g. 4.3BSD,
X Turbo C). Note: define exactly one of REN_LINK, REN_REV, and REN_STDC.
REN_REV
X Use reverse rename function: "int rename(new, old)" (e.g. Microsoft C)
SETMODE
X Change mode of standard output to binary when piping output, then change
X it back to text. Macros MODE_BIN(zoofile) and MODE_TEXT(zoofile) must
X also be defined. Probably specific to MS-DOS.
SETBUF
X Standard output should be set to be unbuffered so output shows up
X quickly.
SPECNEXT
X If defined, a machine-dependent function nextfile() must be defined that
X will expand wildcards in a supplied pathname. If not defined, any
X wildcard expansion must have been done before the command line parameters
X are supplied to the program. For details see the file nextfile.c.
SPECEXIT
X Custom exit handler is needed. A function called zooexit()
X must be defined. If SPECEXIT is not defined, zoo uses its
X own zooexit() function which simply calls exit().
SPECINIT
X If defined, zoo's main() function will call spec_init() before
X doing anything else. Any system-specific initialization may be
X done at this point.
GETTZ
X If defined, a function gettz() must also be defined that will
X return the current timezone, in seconds west of GMT, as a long
X value. Currently such a function is already defined in files
X bsd.c and sysv.c. If and only if GETTZ is defined, zoo will
X store the current timezone for each file that is archived,
X and will list the timezone for each file that has one when it
X lists archive contents.
ALWAYS_INT
X In function prototypes for fgetc(), fread(), and fwrite(),
X traditional practice made certain arguments int, though
X they ought to be char and unsigned respectively. If
X ALWAYS_INT is defined, prototypes will use int only,
X else the correct types are used.
NO_STDIO_FN
X Defining this symbol will cause declarations of fputc(),
X fread(), and fwrite() to not be done by the zoo header files.
X Reported necessary for VMS; may also help in other environments.
IO_MACROS
X If defined, some portable I/O functions are defined as macros,
X saving space.
ZOOCOMMENT
X If defined, archive comments are fully enabled. If not defined,
X zoo code will be smaller at the cost that archive comments will
X be listed but cannot be updated. COMPILATION WITHOUT ZOOCOMMENT
X DEFINED HAS NOT YET BEEN TESTED.
TRACE_IO
X This is for debugging. If defined, it will cause code to
X be compiled that will trace all archive header and directory
X entry I/O by showing it on the screen in human-readable format.
X The tracing will then occur if any Expert command given to zoo
X is preceded by a colon. E.g., if compiled with TRACE_IO on and
X given the command "zoo :l xyz", zoo will give a directory
X listing of xyz.zoo exactly as it would with "zoo l xyz" except
X that all archive header and directory entry reads and writes
X will be shown on the screen. The tracing code is localized
X to the files zoo.c and portable.c, so just these two files
X can be compiled afresh when TRACE_IO is turned on or switched
X off. NOTE: The symbol TRACE_LIST, internal to the file
X "zoolist.c", enables debugging information too. Do not define
X both TRACE_IO and TRACE_LIST because (a) a symbol conflict will
X occur and (b) the debugging information will be duplicated.
UNBUF_IO
X If defined, some I/O is done using low-level system calls read() and
X write(). To do this, the low-level file descriptor is synchronized with
X the buffered zoofile before such I/O is done. To do this, read(),
X write(), and lseek() system calls must be available and the fileno()
X macro must return the file descriptor for a buffered file. This is
X not portable and should definitely not be done by most end users. If
X UNBUF_IO is defined, also defined must be a symbol UNBUF_LIMIT with a
X numerical value that specifies the threshold over which unbuffered I/O
X should be used. For example, if the value of UNBUF_LIMIT is 512, then
X any I/O on a zoofile that reads or writes more than 512 bytes will be
X done using read() or write() system calls. The use of unbuffered I/O
X with a threshold in the range 512 to 1024 can enhance performance by up
X to 50%. The corruption of data is a serious matter. Do not define
X UNBUF_IO unless you are willing to exhaustively test the compiled code
X on your system to make sure it works, and accept full responsibility for
X any adverse consequences. Some standard I/O libraries may attempt to
X optimize the working of fseek() on files opened for read access only,
X and cause UNBUF_IO to fail.
UNBUF_LIMIT
X Needed if and only if UNBUF_IO is defined. Holds a numeric value.
X All I/O done in blocks that are larger than UNBUF_LIMIT bytes
X will be done unbuffered. See UNBUF_IO.
FILTER
X If defined, code will be compiled in to enable the fc and fd
X commands (compress or decompress, reading standard input and
X writing to standard output). These commands are useful only
X on systems that allow programs to easily act as filters.
VER_DISPLAY
X The character that will separate filenames from generation numbers
X in listings of archive contents. Must be a single character
X in double quotes.
VER_INPUT
X The characters that will be accepted as separating filenames
X from generation numbers when typed as an argument to select
X specific files from an archive. String value. May include
X one or more characters; any of them may then be typed and
X will work.
NOSTRCHR
X Although 4.3BSD as distributed from Berkeley includes strchr()
X and strrchr() library functions, 4.2BSD and similar systems
X may not. If so, defining NOSTRCHR will cause zoo to use
X index() and rindex() instead.
STDARG, VARARGS. How to invoke functions that accept a variable
X number of arguments. Define one of these. STDARG causes the
X ANSI-style header stdarg.h to be used. VARARGS causes the **IX-style
X varargs.h header to be used. If you define STDARG, you must also
X define ANSI_PROTO (see above).
DIRECT_CONVERT. Zoo archives use a canonical little-endian byte order,
X and functions are portably defined to convert between this and the
X internal format used by an implementation. If the symbol
X DIRECT_CONVERT is defined, the zoo code will not bother doing this
X portable conversion, but simply assume that the machine's internal
X format is the same as the canonical byte order used in zoo archives.
X DIRECT_CONVERT should be defined *only* if your implementation uses:
X little-endian byte order, 2-byte ints, and 4-byte longs. If there is
X any doubt whatsoever, don't define DIRECT_CONVERT; the overhead of
X portable conversion is not significant.
SZ_SCREEN. If this symbol is not defined, a screen height of 24 lines
X is assumed by the multiscreen help. If desired, this symbol can be
X defined to some other nonnegative value of screen height.
NEED_MEMMOVE. If defined, zoo will define its own equivalent of memmove().
X If not defined, zoo will try to link with a standard library function
X memmove().
NEED_VPRINTF. If this symbol is defined, zoo will use its own jury-
X rigged vprintf function. If this symbol is not defined, zoo will
X try to link with vprintf in the standard library.
SHAR_EOF
chmod 0644 options.doc ||
echo 'restore of options.doc failed'
Wc_c="`wc -c < 'options.doc'`"
test 16246 -eq "$Wc_c" ||
echo 'options.doc: original size 16246, current size' "$Wc_c"
fi
true || echo 'restore of options.h failed'
echo End of part 6, continue with part 7
exit 0