home *** CD-ROM | disk | FTP | other *** search
- Path: uunet!rs
- From: rs@uunet.UU.NET (Rich Salz)
- Newsgroups: comp.sources.unix
- Subject: v11i012: File archive program, Part03/07
- Message-ID: <967@uunet.UU.NET>
- Date: 18 Aug 87 02:01:12 GMT
- Organization: UUNET Communications Services, Arlington, VA
- Lines: 1121
- Approved: rs@uunet.UU.NET
-
- Submitted-by: iuvax!bsu-cs!dhesi@seismo.CSS.GOV (Rahul Dhesi)
- Posting-number: Volume 11, Issue 12
- Archive-name: zoo/Part03
-
- #! /bin/sh
- #
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create:
- # needed.c
- # nextfile.c
- # nixtime.i
- # options.c
- # options.h
- # parse.c
- # parse.h
- export PATH; PATH=/bin:/usr/bin:$PATH
- if test -f 'needed.c'
- then
- echo shar: "will not over-write existing file 'needed.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'needed.c'
- X#ifndef LINT
- Xstatic char sccsid[]="@(#) needed.c 1.6 87/05/29 12:54:43";
- X#endif /* LINT */
- X
- X/*
- XCopyright (C) 1986, 1987 Rahul Dhesi -- All rights reserved
- X*/
- X#include "options.h"
- X/* 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
- X#include "zoo.h"
- X
- X#ifdef NEEDCTYP
- X#include <ctype.h> /* for tolower() */
- X#endif
- X
- X#include <stdio.h> /* solely to define NULL */
- X#include "various.h"
- X#include "zoofns.h"
- X#include "debug.h"
- X
- Xextern int next_arg; /* filenames start at this position */
- Xextern int arg_count; /* count of arguments supplied to program */
- Xextern char **arg_vector; /* vector of arguments supplied to program */
- X/* Uses FIRST_ARG in zoo.h, so must be recompiled when switching
- X between Ooz and Zoo */
- X
- Xint needed(pathname)
- Xchar *pathname;
- X{
- X register int i;
- X register char *arg;
- X char *justname;
- X
- X if (arg_count <= FIRST_ARG) /* if no filenames supplied */
- X return (1); /* .. then all files are needed */
- X justname = nameptr(pathname); /* filename without any pathname */
- X
- X /* count backwards and stop if '+' is encountered */
- X for (i = arg_count-1; i >= next_arg; i--) {
- X arg = arg_vector[i];
- X#ifdef FOLD
- X strlwr(pathname); strlwr(arg);
- X#endif
- X if (strcmp(arg,"+") == 0)
- 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, *PATH_CH) != NULL) { /* found slash */
- X char *p;
- X char arg_prefix[PATHSIZE];
- X char path_prefix[PATHSIZE];
- X strcpy(arg_prefix,arg);
- X strcpy(path_prefix,pathname);
- X p = findlast(arg_prefix, PATH_CH);
- X if (p != NULL)
- X *p = '\0';
- X p = findlast(path_prefix, PATH_CH);
- X if (p != NULL)
- X *p = '\0';
- X if (!match_half(path_prefix, arg_prefix)) {
- 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
- X had a slash but the path prefixes matched. Now we test to see
- X if the filename parts match.
- X */
- X if (match_half (justname, nameptr(arg)))
- X return (1);
- 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
- X} /* needed */
- X
- X/***********************/
- X/*
- Xmatch_half() compares a pattern with a string. Wildcards accepted in
- Xthe pattern are: "*" for zero or more arbitrary characters; "?"
- Xfor any one characters. Unlike the MS-DOS wildcard match, "*" is
- Xcorrectly handled even if it isn't at the end of the pattern. ".'
- Xis not special.
- X
- XOriginally written by Jeff Damens of Columbia University Center for
- XComputing Activities. Taken from the source code for C-Kermit version
- X4C.
- X*/
- X
- Xint match_half (string, pattern)
- Xregister char *string, *pattern;
- X{
- X char *psave,*ssave; /* back up pointers for failure */
- X psave = ssave = NULL;
- X while (1) {
- X#ifdef IGNORECASE
- X for (;
- X tolower(*pattern) == tolower(*string);
- X pattern++,string++ ) /* skip first */
- X#else
- X for (; *pattern == *string; pattern++,string++) /* skip first */
- X#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}
- X
- SHAR_EOF
- fi
- if test -f 'nextfile.c'
- then
- echo shar: "will not over-write existing file 'nextfile.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'nextfile.c'
- X#ifndef LINT
- Xstatic char sccsid[]="@(#) nextfile.c 1.4 87/05/29 12:54:55";
- X#endif /* LINT */
- X
- X#include "options.h"
- X/*
- XCopyright (C) 1986, 1987 Rahul Dhesi -- All rights reserved
- X*/
- X/*
- XFunctions to collect filenames from command line etc. Nextfile() is
- Xused by both Atoz and Zoo. Wildcard expansion by nextfile() is specific to
- XMS-DOS and this implementation is specific to Microsoft C. If the symbol
- XPORTABLE is defined, nextfile() becomes effectively a no-op that will return
- Xthe original filespec the first time and NULL subsequently.
- X*/
- X
- X#define FMAX 3 /* Number of different filename patterns */
- X
- X#include <stdio.h> /* solely to define NULL */
- X#include "various.h"
- X#include "zoo.h" /* solely to define PATHSIZE */
- X
- X#ifdef PORTABLE
- X#ifndef SPECNEXT
- X/* If portable version, nextfile() is effectively a no-op and any wildcard
- Xexpansion must be done by the runtime system before the command line
- Xis received by this program
- X*/
- Xchar *nextfile (what, filespec, fileset)
- Xint what; /* whether to initialize or match */
- Xregister char *filespec; /* filespec to match if initializing */
- Xregister int fileset; /* which set of files */
- X{
- 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 }
- X}
- X#endif /* SPECNEXT */
- X#else
- X/* if not PORTABLE then */
- X
- X#include "intdos.h" /* registers for MS-DOS interrupts */
- X#include "dta.h" /* format of MS-DOS disk transfer area (dta) */
- X#include "assert.h" /* macro definition: assert() macro */
- X
- Xvoid setdta (struct dta_t *);
- Xvoid fcbpath (struct dta_t *, char *, char *);
- X
- X
- X/*******************/
- X/*
- Xnextfile() returns the name of the next source file matching a filespec.
- X
- XINPUT
- 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
- XOUTPUT
- 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
- XNOTE
- 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
- XUSAGE HINTS
- X
- Xnextfile() 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*/
- X
- Xchar *nextfile (what, filespec, fileset)
- Xint what; /* whether to initialize or match */
- Xregister char *filespec; /* filespec to match if initializing */
- Xregister int fileset; /* which set of files */
- X{
- X static struct dta_t new_dta [FMAX+1]; /* our own private dta */
- 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 union REGS regs;
- 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 setdta (&new_dta[fileset]); /* set new dta -- our very own */
- 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 /* find first matching file */
- X regs.h.ah = 0x4e; /* FindFirst DOS call */
- X regs.x.dx = (unsigned int) saved_fspec[fileset]; /* filespec to match */
- X regs.x.cx = 0; /* search attributes */
- X intdos (®s, ®s);
- X } else {
- X /* find next matching file */
- X regs.h.ah = 0x4f; /* FindNext DOS call */
- X intdos (®s, ®s);
- X }
- X
- X if (regs.x.carry != 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 (&new_dta[fileset], saved_fspec[fileset], pathholder[fileset]);
- X return (pathholder[fileset]); /* matching path */
- X }
- X} /* nextfile */
- X
- X/*******************/
- X/* This function sets the dta to a new dta */
- Xvoid setdta (dta)
- Xstruct dta_t *dta;
- X{
- X union REGS regs;
- X regs.h.ah = 0x1a; /* SetDTA Call */
- X regs.x.dx = (unsigned int) dta; /* new DTA address */
- X intdos (®s, ®s);
- X}
- X
- X/*******************/
- X/*
- Xfcbpath() accepts a pointer to the Disk Transfer Area (the DTA format is
- Xdescribed on page 131 of Tandy-1000 programmers reference manual), a
- Xcharacter pointer to a pathname that may contain wildcards, and a character
- Xpointer to a buffer. Copies into buffer the path prefix from the pathname
- Xand the filename prefix from the DTA so that it forms a complete path
- X*/
- X
- Xvoid fcbpath (dta, old_path, new_path)
- Xstruct dta_t *dta;
- Xchar *old_path;
- Xregister char *new_path;
- X{
- 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] = dta->fname[i];
- X new_path[start_pos+13] = '\0';
- X}
- X#endif /* PORTABLE */
- X
- SHAR_EOF
- fi
- if test -f 'nixtime.i'
- then
- echo shar: "will not over-write existing file 'nixtime.i'"
- else
- sed 's/^X//' << \SHAR_EOF > 'nixtime.i'
- X#ifndef LINT
- Xstatic char nixtimeid[]="@(#) nixtime.i 1.2 87/05/03 16:00:16";
- X#endif /* LINT */
- X
- X/*
- XTime handling routines for UNIX systems. These are included by the file
- Xmachine.c as needed.
- X
- XThe contents of this file are hereby released to the public domain.
- X
- X -- Rahul Dhesi 1986/12/31
- X*/
- X
- Xstruct tm *localtime();
- X
- X/*****************
- XFunction gettime() gets the date and time of the file handle supplied.
- XDate and time is in MSDOS format.
- X*/
- Xgettime(handle,date,time)
- Xint handle, *date, *time;
- X{
- X struct stat buf; /* buffer to hold file information */
- X struct tm *tm; /* will hold year/month/day etc. */
- 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}
- X
- X/*****************
- XFunction setutime() sets the date and time of the filename supplied.
- XDate and time is in MSDOS format. It assumes the existence of a function
- Xgettz() that returns the the difference (localtime - gmt) in seconds.
- X*/
- Xint setutime(path,date,time)
- Xchar *path;
- Xunsigned int date, time;
- X{
- 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 /* part of following code is common to zoolist.c -- if memory
- X space is tight, try to share the code */
- 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
- X#ifdef DEBUG
- X printf (setutime: "year=%d month=%d day=%d hour=%d min=%d sec=%d\n",
- X year, month, day, hour, min, sec);
- X#endif
- X
- X /* Calculate days since 1970/01/01 */
- X daycount = 365 * (year - 1970) + /* days due to whole years */
- X (year - 1970) / 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
- X longtime = longtime + gettz(); /* adjust for timezone */
- X
- X /* special case: if MSDOS format date and time were zero, then we set
- X time to be zero here too. */
- X if (date == 0 && time == 0)
- X longtime = 0;
- X
- X /* longtime is now the time of the file, in seconds, since
- X 1970/01/01 00:00:00. Now we set both access and modification times */
- X {
- X long utimbuf[2];
- X utimbuf[0] = utimbuf[1] = longtime;
- X return (utime (path, utimbuf));
- X }
- X}
- SHAR_EOF
- fi
- if test -f 'options.c'
- then
- echo shar: "will not over-write existing file 'options.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'options.c'
- X#ifndef LINT
- Xstatic char sccsid[]="@(#) options.c 1.2 87/05/03 16:00:21";
- X#endif /* LINT */
- X
- X/*
- XCopyright (C) 1986, 1987 Rahul Dhesi -- All rights reserved
- X*/
- X/*
- XHere we define routines specific to only a few systems. Routines are
- Xselected based on defined symbols. Routines specific to only one
- Xsystem are in machine.c for the appropriate system.
- X*/
- X
- X#include "options.h"
- X#include <stdio.h>
- X#include "various.h"
- X#include "zoo.h"
- X#include "zoofns.h"
- X#include "errors.i"
- X
- X#ifdef REN_LINK
- X/* rename using link() followed by unlink() */
- X/*
- XThe following code assumes that if unlink() returns nonzero, then the
- Xattempt to unlink failed. If unlink() ever returns nonzero after actually
- Xunlinking the file, then the file being renamed will be lost!!! Test this
- Xthoroughly. It is assumed that link() and unlink() return zero if no
- Xerror else nonzero.
- X*/
- Xint chname (newname, oldname)
- Xchar *newname, *oldname;
- X{
- 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);
- X}
- X#else
- X/* else not REN_LINK */
- X
- Xint chname (newname, oldname)
- Xchar *newname, *oldname;
- X{
- X#ifdef REN_NORM
- X if (rename(newname, oldname) != 0) /* normal order */
- X#else
- X if (rename(oldname, newname) != 0) /* reverse order */
- X#endif
- X return (-1);
- X else
- X return (0);
- X}
- X#endif /* end of not REN_LINK */
- X
- SHAR_EOF
- fi
- if test -f 'options.h'
- then
- echo shar: "will not over-write existing file 'options.h'"
- else
- sed 's/^X//' << \SHAR_EOF > 'options.h'
- X/* @(#) options.h 1.16 87/05/03 16:00:25 */
- X
- X/*
- XThe contents of this file are hereby released to the public domain.
- X
- X -- Rahul Dhesi 1986/11/14
- X*/
- X
- X/*
- XThis file defines various symbols and macros that are needed to ensure
- Xsystem-independence. The basic philosophy is to use a distinct symbol for
- Xeach attribute that varies from machine to machine. Then, for each new
- Xsystem, we define symbols corresponding to its attributes. Thus, ideally,
- Xthe only place in Zoo code that we actually use the name of a machine is in
- Xthis file, portable.h, and possibly in machine.h and options.c. Everywhere
- Xelse in the code we only use names of attributes. If you need to define a
- Xnew machine name, please refer first to the guidelines in the implementor's
- Xdocumentation.
- X
- XMachine names:
- X
- XMSC Microsoft C under MS-DOS
- XDLC Datalight C under MS-DOS
- XSYS_V UNIX System V release 2.1
- XVMS VAX/VMS 4.4
- XBSD4_3 4.3BSD
- XMCH_AMIGA AmigaDOS with Aztec/Manx C compiler
- X
- XAttributes of systems:
- X
- XCHEKDIR
- 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 include function isadir() that
- X tests a supplied handle and returns 1 if it corresponds to a
- X directory or other special type of file.
- XCHEKUDIR
- X Like CHEKDIR but use function isuadir() that tests a pathname, not
- X a handle. Only one of CHEKDIR, CHEKUDIR may be defined.
- XDISK_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 (':').
- XEXISTS
- 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.
- XLINT_ARGS
- X Use ANSI-style function argument lists in declarations
- XLINT
- 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.
- XFLAT
- X include files are all in one place (no sys/anything)
- XFOLD
- X fold filenames to lowercase. Define this for case-insensitive filesystems
- XFPUTCHAR
- 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() functio.
- XPORTABLE
- X use portable functions --- define for every system except MS-DOS
- XPURIFY
- 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.
- XDONT_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
- XNOENUM
- X compiler does not support enumerations
- XDUMB_ASS
- X dumb assertions must be used because the preprocessor doesn't define
- X the symbols __FILE__ and __LINE__ (which hold the name of the current
- X file and the number of the current line)
- XFNLIMIT
- X Pathname length limit for this system
- XNEEDCTYP
- X the header file ctype.h is needed because functions such as tolower() are
- X defined only as macros
- XNIXTIME
- 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 file handle.
- XGETUTIME
- 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 supplied handle instead of a filename.
- XNOFCNTL
- X if defined, system expects "file.h" to be included rather than "fcntl.h"
- XNOSIGNAL
- X don't use signals because library doesn't support them
- XPATH_CH
- X the character that should separate the directory name from the filename
- X in the listing of the contents of an archive. String value.
- XPATH_SEP
- X the set of characters that may separate preceding directory/device
- X information from the filename. String value.
- XEXT_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.
- XEXT_CH
- X character that separates base part of filename from extension. Char value.
- XMEMSET
- X If defined, a library function memset() is assumed available that
- X conforms to that available under System V. If not defined, Zoo uses
- X its own memset() function.
- XEXT_DFLT
- X default extension for archives. String. Usually ".zoo"
- XNIXFNAME
- X if defined, PATH_CH, PATH_SEP, EXT_SEP, EXT_CH, and EXT_DFLT get defined
- X to conform to UNIX conventions and should not be separately defined
- XFORCESLASH
- 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.
- XREN_LINK
- X rename a file by using link() followed by unlink() (e.g. Xenix, System V)
- XREN_NORM
- X use normal rename function: "int rename(new, old)" (e.g. Microsoft C)
- XREN_REV
- X use reverse rename function: "int rename(old, new)" (e.g. 4.3BSD)
- X Note: define exactly one of REN_LINK, REN_NORM, and REN_REV.
- XSETMODE
- X change mode of standard output to binary when piping output, then change
- X it back to text. Macros MODE_BIN(handle) and MODE_TEXT(handle) must also
- X be defined.
- XSETBUF
- X Standard output should be set to be unbuffered so output shows up
- X quickly. Currently used only in Fiz, not in Zoo.
- XSPECNEXT
- 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.
- XSTRLWR
- X If defined, a library function strlwr() is assumed available that converts
- X a supplied string to lowercase and returns a pointer it. If not
- X defined, Zoo uses its own strlwr() function.
- XTELL
- X If defined, a library function tell() is assumed available that returns
- X the current file pointer position for a file handle. If not
- X defined, Zoo uses its own tell() function.
- X*/
- X
- X/* ZOO is always defined currently */
- X#define ZOO
- X
- X#ifdef SYS_V
- X#define EXISTS(f) (access(f, 00) == 0)
- X#define MEMSET
- X#define FNLIMIT 14
- X#define CHEKDIR
- X#define NIXTIME
- X#define NIXFNAME
- X#define NEEDCTYP
- X#define NOENUM
- X#define PORTABLE
- X#define REN_LINK
- X#define SETBUF
- X#endif
- X
- X#ifdef MSC
- X/* #define STRDUP */
- X/* #define FPUTCHAR */
- X/* #define TELL */
- X/* #define EXISTS(f) (access(f, 00) == 0) made code size bigger */
- X/* #define MEMSET */
- X/* #define STRLWR */
- X#define PURIFY
- X#define DISK_CH ':'
- X#define IGNORECASE
- X#define WILDCARD "*.*"
- X#define FOLD
- X#define FORCESLASH
- X#define FNLIMIT 12
- X#define NEEDCTYP
- X#define CUR_DIR "."
- X#define PATH_CH "/"
- X#define PATH_SEP ":/\\"
- X#define EXT_CH '.'
- X#define EXT_SEP ":/\\."
- X#define EXT_DFLT ".zoo"
- X#define SETMODE
- X#define MODE_BIN(handle) setmode(handle, O_BINARY)
- X#define MODE_TEXT(handle) setmode(handle, O_TEXT)
- X#define LINT_ARGS
- X#define REN_NORM
- X
- X#ifdef PORTABLE
- X#define SPECNEXT
- X#define NIXTIME
- X#endif
- X
- X#endif /* MSC */
- X
- X#ifdef DLC
- X#define STRDUP
- X#define STRLWR
- X/* #define EXISTS */
- X#define NOSIGNAL
- X#define PURIFY
- X#define DISK_CH ':'
- X#define IGNORECASE
- X/* #define WILDCARD "*.*" */
- X#define FOLD
- X#define FORCESLASH
- X#define FNLIMIT 12
- X#define NEEDCTYP
- X#define CUR_DIR "."
- X#define PATH_CH "/"
- X#define PATH_SEP ":/\\"
- X#define EXT_CH '.'
- X#define EXT_SEP ":/\\."
- X#define EXT_DFLT ".zoo"
- X#define SETMODE
- X/* #define LINT_ARGS */
- X#define REN_REV
- X#define SPECNEXT
- X#define NIXTIME
- X#endif /* DLC */
- X
- X#ifdef BSD4_3
- X#define EXISTS(f) (access(f, 00) == 0)
- X#define FNLIMIT 1023
- X#define CHEKDIR
- X#define NIXTIME
- X#define NIXFNAME
- X#define NEEDCTYP
- X#define PORTABLE
- X#define NOENUM
- X#define REN_REV
- X#define SETBUF
- X#endif
- X
- X#ifdef VMS
- X#define FNLIMIT 78
- X#define PATH_SEP ":]"
- X#define EXT_CH '.'
- X#define EXT_SEP ":]."
- X#define EXT_DFLT ".zoo"
- X#define NOENUM
- X#define FLAT
- X#define PORTABLE
- X#define DUMB_ASS
- X#define NOFCNTL
- X#endif
- X
- X#ifdef MCH_AMIGA
- X#define PURIFY
- X#define DISK_CH ':'
- X#define SPECNEXT
- X#define WILDCARD "*"
- X#define IGNORECASE
- X#define FNLIMIT 30
- X#define NEEDCTYP
- X#define CUR_DIR "."
- X#define PATH_CH "/"
- X#define PATH_SEP ":/"
- X#define EXT_CH '.'
- X#define EXT_SEP ":/."
- X#define EXT_DFLT ".zoo"
- X#define PORTABLE
- X#define NOSIGNAL
- X#define REN_REV
- X#define NOENUM
- X#define SETBUF
- X#define CHEKUDIR
- X#define GETUTIME
- X#define NIXTIME
- X#endif
- X
- X#ifdef NIXFNAME
- X#define CUR_DIR "."
- X#define PATH_CH "/"
- X#define PATH_SEP "/"
- X#define EXT_CH '.'
- X#define EXT_SEP "/."
- X#define EXT_DFLT ".zoo"
- X#endif
- X
- X#ifdef GENERIC
- X/* #define SPECNEXT */
- X#define IGNORECASE
- X#define FNLIMIT 11
- X#define NEEDCTYP
- X#define CUR_DIR "."
- X#define PATH_CH "/"
- X#define PATH_SEP ":/"
- X#define EXT_CH '.'
- X#define EXT_SEP ":/."
- X#define EXT_DFLT ".zoo"
- X#define PORTABLE
- X#define NOSIGNAL
- X/* REN_LINK is UNIX-specific. Can't find a generic rename() function */
- X#define REN_LINK
- X/* #define FLAT */
- X#define NOENUM
- X#define SETBUF
- X#define CHEKUDIR
- X#define GETUTIME
- X#define NIXTIME
- X#endif
- SHAR_EOF
- fi
- if test -f 'parse.c'
- then
- echo shar: "will not over-write existing file 'parse.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'parse.c'
- X#ifndef LINT
- Xstatic char sccsid[]="@(#) parse.c 1.10 87/05/29 12:55:08";
- X#endif /* LINT */
- X
- X/*
- XThe contents of this file are hereby released to the public domain.
- X
- X -- Rahul Dhesi 1986/11/14
- X
- X*/
- X
- X#include "options.h"
- X#include "zoo.h"
- X#include <stdio.h>
- X#include "various.h"
- X#include "zoofns.h"
- X
- X#include "parse.h"
- X#include "assert.h"
- X
- X/*
- Xparse() accepts a filename and return its component parts in a structure.
- XThe component parts are: disk drive, path prefix, root name of filename,
- Xand extension.
- X
- XIf DISK_CH is not defined, it is assumed that filenames may be
- Xpreceded with a disk prefix terminated by the character DISK_CH.
- XThe first character of the disk prefix, followed by DISK_CH,
- Xis returned in the drive field.
- X
- XIf the symbol DISK_CH is defined, a null string is returned in the
- Xdisk field.
- X*/
- Xvoid parse (path_st, fname)
- Xregister struct path_st *path_st;
- Xchar *fname;
- X{
- X char tempname[LFNAMESIZE]; /* working copy of supplied fname */
- X char *namep; /* points to relevant part of tempname */
- X
- X char *p;
- X strcpy (tempname, fname);
- X
- X#ifdef DEBUG
- Xprintf ("parse: supplied name is [%s].\n", tempname);
- X#endif
- X
- X#ifndef DISK_CH
- X path_st->drive[0] = '\0';
- X namep = tempname; /* points to pathname+filename */
- X#else
- X path_st->drive[0] = '\0';
- X p = strchr (tempname, DISK_CH); /* point to first ':' */
- X
- X if (p != NULL) {
- X path_st->drive[0] = *tempname;/* use only first char of drive name */
- X path_st->drive[1] = DISK_CH;
- X path_st->drive[2] = '\0';
- X namep = ++p; /* point to pathname+filename */
- X } else {
- X path_st->drive[0] = '\0';
- X namep = tempname; /* points to pathname+filename */
- X }
- X#endif /* end of not DISK_CH */
- X
- X /* Note: findlast() finds last occurrence in the subject string of
- X any one of a set of chars */
- X
- X /* save the long filename */
- X p = findlast (namep, PATH_SEP);
- X
- X /* if path separator found, copy next char onwards; else entire string */
- X strncpy (path_st->lfname,
- X (p != NULL) ? p+1 : namep,
- X LFNAMESIZE);
- X path_st->lfname[LFNAMESIZE-1] = '\0'; /* force null termination */
- X
- X#ifdef DEBUG
- Xprintf ("parse: path = [%s] long filename = [%s]\n",
- X namep, path_st->lfname);
- X#endif
- X
- X/* Separate out the extension */
- Xp = findlast (namep, EXT_SEP); /* look for . or / */
- Xif (p != NULL && *p != EXT_CH) /* found .? */
- X p = NULL; /* ... if not, ignore / */
- X
- X#ifdef DEBUG
- Xif (p == NULL)
- X printf ("parse: no extension found for [%s]\n", namep);
- Xelse
- X printf ("parse: extension for [%s] is [%s]\n", namep, p);
- X#endif
- X
- X path_st->ext[0] = '\0'; /* assume no extension */
- X if (p != NULL) { /* found extension */
- X strncpy (path_st->ext, (p+1), EXTLEN); /* save extension */
- X path_st->ext[EXTLEN] = '\0'; /* force termination */
- X *p = '\0'; /* null out extension */
- X }
- X
- X /* separate out root of filename if any */
- X p = findlast (namep, PATH_SEP);
- X
- X if (p != NULL) {
- X ++p;
- X strncpy (path_st->fname, p, ROOTSIZE); /* save filename */
- X *p = '\0'; /* null out filename */
- X } else {
- X strncpy (path_st->fname, namep, ROOTSIZE);
- X *namep = '\0'; /* null out filename */
- X }
- X path_st->fname[ROOTSIZE] = '\0'; /* force termination */
- X
- X /* what remains, whether null or not, is the path prefix */
- X path_st->dir[0] = '\0'; /* in case *namep is '\0' */
- X
- X strncpy (path_st->dir, namep, PATHSIZE);
- X
- X /* remove trailing path-separater from directory name, but don't
- X remove it if it is also the leading separater */
- X {
- X int n;
- X n = strlen(path_st->dir);
- X if (n != 1)
- X path_st->dir[n-1] = '\0';
- X }
- X
- X#ifdef DEBUG
- Xprintf ("parse: path prefix = [%s].\n", namep);
- X#endif
- X /* if extension is null, and if long filename contains more than
- X ROOTSIZE characters, transfer some of them to extension */
- X if (path_st->ext[0] == '\0' && strlen(path_st->lfname) > ROOTSIZE) {
- X strncpy(path_st->ext, &path_st->lfname[ROOTSIZE], EXTLEN);
- X path_st->ext[3] = '\0';
- X }
- X}
- X
- X/*******************/
- X/*
- Xfindlast() finds last occurrence in provided string of any of the characters
- Xexcept the null character in the provided set.
- X
- XIf found, return value is pointer to character found, else it is NULL.
- X*/
- X
- Xchar *findlast (str, set)
- Xregister char *str; /* subject string */
- Xchar *set; /* set of characters to look for */
- X
- X{
- X register char *p;
- X
- X if (str == NULL || set == NULL || *str == '\0' || *set == '\0')
- X return (NULL);
- X
- X p = lastptr (str); /* pointer to last char of string */
- X assert(p != NULL);
- X
- X while (p != str && strchr (set, *p) == NULL) {
- X --p;
- X }
- X
- X /* either p == str or we found a character or both */
- X if (strchr (set, *p) == NULL)
- X return (NULL);
- X else
- X return (p);
- X}
- X
- X/*******************/
- X/*
- Xlastptr() returns a pointer to the last non-null character in the string, if
- Xany. If the string is null it returns NULL
- X*/
- X
- Xchar *lastptr (str)
- Xregister char *str; /* string in which to find last char */
- X{
- X register char *p;
- X if (str == NULL)
- X prterror ('f', "lastptr: received null pointer\n");
- X if (*str == '\0')
- X return (NULL);
- X p = str;
- X while (*p != '\0') /* find trailing null char */
- X ++p;
- X --p; /* point to just before it */
- X return (p);
- X}
- SHAR_EOF
- fi
- if test -f 'parse.h'
- then
- echo shar: "will not over-write existing file 'parse.h'"
- else
- sed 's/^X//' << \SHAR_EOF > 'parse.h'
- X/* @(#) parse.h 1.2 87/05/03 16:01:02 */
- X
- X/*
- XThe contents of this file are hereby released to the public domain.
- X
- X -- Rahul Dhesi 1986/11/14
- X*/
- X
- X/*
- Xdefines structure used in call to parse()
- X*/
- X#define XTRA 2 /* extra space to avoid off-by-one errors */
- X
- X
- Xstruct path_st {
- X char drive[2+1+XTRA]; /* drive name */
- X char dir[PATHSIZE+1+XTRA]; /* path prefix */
- X char fname[8+1+XTRA]; /* root name of filename */
- X char lfname[LFNAMESIZE+1+XTRA]; /* long filename */
- X char ext[EXTLEN+1+XTRA]; /* extension */
- X};
- X
- X#ifdef LINT_ARGS
- Xvoid parse (struct path_st *, char *);
- X#else
- Xvoid parse();
- X#endif
- X
- SHAR_EOF
- fi
- exit 0
- # End of shell archive
- --
- Rahul Dhesi UUCP: {ihnp4,seismo}!{iuvax,pur-ee}!bsu-cs!dhesi
-
- --
-
- Rich $alz
- Cronus Project, BBN Labs rsalz@bbn.com
- Moderator, comp.sources.unix sources@uunet.uu.net
-