[alt.sources] ARC 5.20 w/Squashing, 4/9

hyc@umix.cc.umich.edu (Howard Chu) (04/14/88)

XX#include <stdio.h>
XX#include "arc.h"
XX
XXINT
XXaddarc(num, arg, move, update, fresh)		/* add files to archive */
XX	INT             num;	/* number of arguments */
XX	char           *arg[];	/* pointers to arguments */
XXINT             move;		/* true if moving file */
XXINT             update;		/* true if updating */
XXINT             fresh;		/* true if freshening */
XX{
XX	char           *d, *dir();	/* directory junk */
XX	char            buf[100];	/* pathname buffer */
XX	char          **path = NULL;	/* pointer to pointers to paths */
XX	char          **name = NULL;	/* pointer to pointers to names */
XX	INT             nfiles = 0;	/* number of files in lists */
XX	INT             notemp;	/* true until a template works */
XX	INT             nowork = 1;	/* true until files are added */
XX	char           *i, *rindex();	/* string indexing junk */
XX	char           *malloc(), *realloc();	/* memory allocators */
XX	INT             m, n;	/* indices */
XX	unsigned INT    coreleft();	/* remaining memory reporter */
XX	INT             addbunch();
XX	INT             addfile();
XX
XX	if (num < 1) {		/* if no files named */
XX		num = 1;	/* then fake one */
XX#ifdef MSDOS
XX		arg[0] = "*.*";	/* add everything */
XX#endif
XX#ifdef BSD
XX		arg[0] = "*";
XX#endif
XX#ifdef MTS
XX		arg[0] = "?";
XX#endif
XX	}
XX	path = (char **) malloc(sizeof(char **));
XX	name = (char **) malloc(sizeof(char **));
XX
XX
XX	for (n = 0; n < num; n++) {	/* for each template supplied */
XX		strcpy(buf, arg[n]);	/* get ready to fix path */
XX#ifndef MTS
XX		if (!(i = rindex(buf, '\\')))
XX			if (!(i = rindex(buf, '/')))
XX				if (!(i = rindex(buf, ':')))
XX					i = buf - 1;
XX#else
XX		if (!(i = rindex(buf, sepchr[0])))
XX			if (buf[0] != tmpchr[0])
XX				i = buf - 1;
XX			else
XX				i = buf;
XX#endif
XX		i++;		/* pointer to where name goes */
XX
XX		notemp = 1;	/* reset files flag */
XX		for (d = dir(arg[n], 0); d; d = dir(NULL, 0)) {
XX			notemp = 0;	/* template is giving results */
XX			nfiles++;	/* add each matching file */
XX			path = (char **) realloc(path, nfiles * sizeof(char **));
XX			name = (char **) realloc(name, nfiles * sizeof(char **));
XX			strcpy(i, d);	/* put name in path */
XX			path[nfiles - 1] = malloc(strlen(buf) + 1);
XX			strcpy(path[nfiles - 1], buf);
XX			name[nfiles - 1] = d;	/* save name */
XX#ifdef MSDOS
XX			if (coreleft() < 5120) {
XX				nfiles = addbunch(nfiles, path, name, move, update, fresh);
XX				nowork = nowork && !nfiles;
XX				while (nfiles) {
XX					free(path[--nfiles]);
XX					free(name[nfiles]);
XX				}
XX				free(path);
XX				free(name);
XX				path = name = NULL;
XX			}
XX#endif
XX		}
XX		if (notemp && warn)
XX			printf("No files match: %s\n", arg[n]);
XX	}
XX
XX	if (nfiles) {
XX		nfiles = addbunch(nfiles, path, name, move, update, fresh);
XX		nowork = nowork && !nfiles;
XX		while (nfiles) {
XX			free(path[--nfiles]);
XX			free(name[nfiles]);
XX		}
XX		free(path);
XX		free(name);
XX	}
XX	if (nowork && warn)
XX		printf("No files were added.\n");
XX}
XX
XXINT
XXaddbunch(nfiles, path, name, move, update, fresh)	/* add a bunch of files */
XX	INT             nfiles;	/* number of files to add */
XX	char          **path;	/* pointers to pathnames */
XX	char          **name;	/* pointers to filenames */
XX	INT             move;	/* true if moving file */
XX	INT             update;	/* true if updating */
XX	INT             fresh;	/* true if freshening */
XX{
XX	char            buf[100];	/* pathname buffer */
XX	INT             m, n;	/* indices */
XX	char           *d;	/* swap pointer */
XX	struct heads    hdr;	/* file header data storage */
XX
XX	for (n = 0; n < nfiles - 1; n++) {	/* sort the list of names */
XX		for (m = n + 1; m < nfiles; m++) {
XX			if (strcmp(name[n], name[m]) > 0) {
XX				d = path[n];
XX				path[n] = path[m];
XX				path[m] = d;
XX				d = name[n];
XX				name[n] = name[m];
XX				name[m] = d;
XX			}
XX		}
XX	}
XX
XX	for (n = 0; n < nfiles - 1;) {	/* consolidate the list of names */
XX		if (!strcmp(path[n], path[n + 1])	/* if duplicate names */
XX		    ||!strcmp(path[n], arcname)	/* or this archive */
XX		    ||izadir(path[n])	/* or a directory */
XX		    ||!strcmp(path[n], newname)	/* or the new version */
XX		    ||!strcmp(path[n], bakname)) {	/* or its backup */
XX			free(path[n]);	/* then forget the file */
XX			free(name[n]);
XX			for (m = n; m < nfiles - 1; m++) {
XX				path[m] = path[m + 1];
XX				name[m] = name[m + 1];
XX			}
XX			nfiles--;
XX		} else
XX			n++;	/* else test the next one */
XX	}
XX
XX	if (!strcmp(path[n], arcname)	/* special check for last file */
XX	    ||!strcmp(path[n], newname)	/* courtesy of Rick Moore */
XX	    ||izadir(path[n])
XX	    || !strcmp(path[n], bakname)) {
XX		free(path[n]);
XX		free(name[n]);
XX		nfiles--;
XX	}
XX	if (!nfiles)		/* make sure we got some */
XX		return 0;
XX
XX	for (n = 0; n < nfiles - 1; n++) {	/* watch out for duplicate
XX						 * names */
XX		if (!strcmp(name[n], name[n + 1]))
XX			abort("Duplicate filenames:\n  %s\n  %s", path[n], path[n + 1]);
XX	}
XX	openarc(1);		/* open archive for changes */
XX
XX	for (n = 0; n < nfiles; n++)	/* add each file in the list */
XX		addfile(path[n], name[n], update, fresh);
XX
XX	/* now we must copy over all files that follow our additions */
XX
XX	while (readhdr(&hdr, arc)) {	/* while more entries to copy */
XX		writehdr(&hdr, new);
XX		filecopy(arc, new, hdr.size);
XX	}
XX	hdrver = 0;		/* archive EOF type */
XX	writehdr(&hdr, new);	/* write out our end marker */
XX	closearc(1);		/* close archive after changes */
XX
XX	if (move) {		/* if this was a move */
XX		for (n = 0; n < nfiles; n++) {	/* then delete each file
XX						 * added */
XX			if (unlink(path[n]) && warn) {
XX				printf("Cannot unsave %s\n", path[n]);
XX				nerrs++;
XX			}
XX		}
XX	}
XX	return nfiles;		/* say how many were added */
XX}
XX
XXstatic          INT
XXaddfile(path, name, update, fresh)	/* add named file to archive */
XX	char           *path;	/* path name of file to add */
XX	char           *name;	/* name of file to add */
XX	INT             update;	/* true if updating */
XX	INT             fresh;	/* true if freshening */
XX{
XX	struct heads    nhdr;	/* data regarding the new file */
XX	struct heads    ohdr;	/* data regarding an old file */
XX	FILE           *f, *fopen();	/* file to add, opener */
XX	LONG            starts, ftell();	/* file locations */
XX	INT             c;	/* one char of file */
XX	INT             upd = 0;/* true if replacing an entry */
XX
XX#ifndef MTS
XX	if (!(f = fopen(path, "r"))) {
XX#else
XX	if (image)
XX		f = fopen(path, "rb");
XX	else
XX		f = fopen(path, "r");
XX	if (!f) {
XX#endif
XX		if (warn) {
XX			printf("Cannot read file: %s\n", path);
XX			nerrs++;
XX		}
XX		return;
XX	}
XX	strcpy(nhdr.name, name);/* save name */
XX	nhdr.size = 0;		/* clear out size storage */
XX	nhdr.crc = 0;		/* clear out CRC check storage */
XX#ifndef MTS
XX	getstamp(f, &nhdr.date, &nhdr.time);
XX#else
XX	getstamp(path, &nhdr.date, &nhdr.time);
XX#endif
XX
XX	/* position archive to spot for new file */
XX
XX	if (arc) {		/* if adding to existing archive */
XX		starts = ftell(arc);	/* where are we? */
XX		while (readhdr(&ohdr, arc)) {	/* while more files to check */
XX			if (!strcmp(ohdr.name, nhdr.name)) {
XX				upd = 1;	/* replace existing entry */
XX				if (update || fresh) {	/* if updating or
XX							 * freshening */
XX					if (nhdr.date < ohdr.date
XX					    || (nhdr.date == ohdr.date && nhdr.time <= ohdr.time)) {
XX						fseek(arc, starts, 0);
XX						fclose(f);
XX						return;	/* skip if not newer */
XX					}
XX				}
XX			}
XX			if (strcmp(ohdr.name, nhdr.name) >= 0)
XX				break;	/* found our spot */
XX
XX			writehdr(&ohdr, new);	/* entry preceeds update;
XX						 * keep it */
XX			filecopy(arc, new, ohdr.size);
XX			starts = ftell(arc);	/* now where are we? */
XX		}
XX
XX		if (upd) {	/* if an update */
XX			if (note) {
XX				printf("Updating file: %-12s  ", name);
XX				fflush(stdout);
XX			}
XX			fseek(arc, ohdr.size, 1);
XX		} else if (fresh) {	/* else if freshening */
XX			fseek(arc, starts, 0);	/* then do not add files */
XX			fclose(f);
XX			return;
XX		} else {	/* else adding a new file */
XX			if (note) {
XX				printf("Adding file:   %-12s  ", name);
XX				fflush(stdout);
XX			}
XX			fseek(arc, starts, 0);	/* reset for next time */
XX		}
XX	} else {		/* no existing archive */
XX		if (fresh) {	/* cannot freshen nothing */
XX			fclose(f);
XX			return;
XX		} else if (note) {	/* else adding a file */
XX			printf("Adding file:   %-12s  ", name);
XX			fflush(stdout);
XX		}
XX	}
XX
XX	starts = ftell(new);	/* note where header goes */
XX	hdrver = 8;		/* anything but end marker */
XX	writehdr(&nhdr, new);	/* write out header skeleton */
XX	pack(f, new, &nhdr);	/* pack file into archive */
XX	strcpy(nhdr.name, name);
XX	fseek(new, starts, 0);	/* move back to header skeleton */
XX	writehdr(&nhdr, new);	/* write out real header */
XX	fseek(new, nhdr.size, 1);	/* skip over data to next header */
XX	fclose(f);		/* all done with the file */
XX}
SHAR_EOF
if test 9205 -ne "`wc -c arcadd.c`"
then
echo shar: error transmitting arcadd.c '(should have been 9205 characters)'
fi
echo shar: extracting arccode.c '(1314 characters)'
sed 's/^XX//' << \SHAR_EOF > arccode.c
XX/*
XX * $Log:        arccode.c,v $
XX * Revision 1.3  87/08/13  17:03:05  hyc
XX * Run thru the indent program...
XX *  Revision 1.2  87/07/21  06:52:58  hyc *** empty
XX * log message ***
XX * 
XX */
XX
XX/*
XX * ARC - Archive utility - ARCCODE
XX * 
XX * Version 1.02, created on 01/20/86 at 13:33:35
XX * 
XX * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED
XX * 
XX * By:  Thom Henderson
XX * 
XX * Description: This file contains the routines used to encrypt and decrypt data
XX * in an archive.  The encryption method is nothing fancy, being just a
XX * routine XOR, but it is used on the packed data, and uses a variable length
XX * key.  The end result is something that is in theory crackable, but I'd
XX * hate to try it.  It should be more than sufficient for casual use.
XX * 
XX * Language: Computer Innovations Optimizing C86
XX */
XX#include <stdio.h>
XX#include "arc.h"
XX
XXstatic char    *p;		/* password pointer */
XX
XXINT
XXsetcode()
XX{				/* get set for encoding/decoding */
XX	p = password;		/* reset password pointer */
XX}
XX
XXINT
XXcode(c)				/* encode some character */
XX	INT             c;	/* character to encode */
XX{
XX	if (p) {		/* if password is in use */
XX		if (!*p)	/* if we reached the end */
XX			p = password;	/* then wrap back to the start */
XX		return c ^ *p++;/* very simple here */
XX	} else
XX		return c;	/* else no encryption */
XX}
SHAR_EOF
if test 1314 -ne "`wc -c arccode.c`"
then
echo shar: error transmitting arccode.c '(should have been 1314 characters)'
fi
echo shar: extracting arccvt.c '(3800 characters)'
sed 's/^XX//' << \SHAR_EOF > arccvt.c
XX/*
XX * $Log:	arccvt.c,v $
XX * Revision 1.2  88/04/11  17:51:28  hyc
XX * re-synch wuth MTS, minor formatting
XX * 
XX * Revision 1.1  88/04/11  17:50:00  hyc
XX * Initial revision
XX * 
XX * Revision 1.1  87/12/19  04:02:03  hyc
XX * Initial revision
XX * 
XX * Revision 1.3  87/08/13  17:03:07  hyc
XX * Run thru the indent program...
XX *  Revision 1.2  87/07/21  06:57:53  hyc *** empty
XX * log message ***
XX * 
XX */
XX
XX/*
XX * ARC - Archive utility - ARCCVT
XX * 
XX * Version 1.16, created on 02/03/86 at 22:53:02
XX * 
XX * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED
XX * 
XX * By:  Thom Henderson
XX * 
XX * Description: This file contains the routines used to convert archives to use
XX * newer file storage methods.
XX * 
XX * Language: Computer Innovations Optimizing C86
XX */
XX#include <stdio.h>
XX#include "arc.h"
XX
XXstatic char     tempname[100];	/* temp file name */
XX
XXINT
XXcvtarc(num, arg)		/* convert archive */
XX	INT             num;	/* number of arguments */
XX	char           *arg[];	/* pointers to arguments */
XX{
XX	struct heads    hdr;	/* file header */
XX	INT             cvt;	/* true to convert current file */
XX	INT             did[25];/* true when argument was used */
XX	INT             n;	/* index */
XX	char           *makefnam();	/* filename fixer */
XX	FILE           *fopen();/* file opener */
XX	INT             cvtfile();
XX
XX	if (arctemp)		/* use temp area if specified */
XX		sprintf(tempname, "%s.CVT", arctemp);
XX	else
XX		makefnam("$ARCTEMP.CVT", arcname, tempname);
XX#ifdef MTS
XX	image = 1;
XX#endif
XX
XX	openarc(1);		/* open archive for changes */
XX
XX	for (n = 0; n < num; n++)	/* for each argument */
XX		did[n] = 0;	/* reset usage flag */
XX	rempath(num, arg);	/* strip off paths */
XX
XX	if (num) {		/* if files were named */
XX		while (readhdr(&hdr, arc)) {	/* while more files to check */
XX			cvt = 0;/* reset convert flag */
XX			for (n = 0; n < num; n++) {	/* for each template
XX							 * given */
XX				if (match(hdr.name, arg[n])) {
XX					cvt = 1;	/* turn on convert flag */
XX					did[n] = 1;	/* turn on usage flag */
XX					break;	/* stop looking */
XX				}
XX			}
XX
XX			if (cvt)/* if converting this one */
XX				cvtfile(&hdr);	/* then do it */
XX			else {	/* else just copy it */
XX				writehdr(&hdr, new);
XX				filecopy(arc, new, hdr.size);
XX			}
XX		}
XX	} else
XX		while (readhdr(&hdr, arc))	/* else convert all files */
XX			cvtfile(&hdr);
XX
XX	hdrver = 0;		/* archive EOF type */
XX	writehdr(&hdr, new);	/* write out our end marker */
XX	closearc(1);		/* close archive after changes */
XX
XX	if (note) {
XX		for (n = 0; n < num; n++) {	/* report unused args */
XX			if (!did[n]) {
XX				printf("File not found: %s\n", arg[n]);
XX				nerrs++;
XX			}
XX		}
XX	}
XX}
XX
XXINT
XXcvtfile(hdr)			/* convert a file */
XX	struct heads   *hdr;	/* pointer to header data */
XX{
XX	LONG            starts, ftell();	/* where the file goes */
XX	FILE           *tmp, *fopen();	/* temporary file */
XX#ifdef MTS
XX	char            name[16];
XX#endif
XX
XX#ifdef MTS
XX	if (!(tmp = fopen(tempname, "w+b")))
XX#else
XX	if (!(tmp = fopen(tempname, "w+")))
XX#endif
XX		abort("Unable to create temporary file %s", tempname);
XX
XX	if (note) {
XX		printf("Converting file: %-12s   reading, ", hdr->name);
XX		fflush(stdout);
XX	}
XX#ifdef MTS
XX	strcpy(name, hdr->name);
XX	fseek(tmp, 0, 0);
XX#endif
XX	unpack(arc, tmp, hdr);	/* unpack the entry */
XX	fseek(tmp, 0L, 0);	/* reset temp for reading */
XX
XX	starts = ftell(new);	/* note where header goes */
XX	hdrver = 8;		/* anything but end marker */
XX	writehdr(hdr, new);	/* write out header skeleton */
XX	pack(tmp, new, hdr);	/* pack file into archive */
XX	fseek(new, starts, 0);	/* move back to header skeleton */
XX#ifdef MTS
XX	strcpy(hdr->name, name);
XX#endif
XX	writehdr(hdr, new);	/* write out real header */
XX	fseek(new, hdr->size, 1);	/* skip over data to next header */
XX	fclose(tmp);		/* all done with the file */
XX	if (unlink(tempname) && warn) {
XX		printf("Cannot unsave %s\n", tempname);
XX		nerrs++;
XX	}
XX}
SHAR_EOF
if test 3800 -ne "`wc -c arccvt.c`"
then
echo shar: error transmitting arccvt.c '(should have been 3800 characters)'
fi
echo shar: extracting arcdata.c '(1838 characters)'
sed 's/^XX//' << \SHAR_EOF > arcdata.c
XX/*
XX * ARC - Archive utility - ARCDATA
XX * 
XX * Version 2.16, created on 10/24/86 at 14:54:17
XX * 
XX * (C) COPYRIGHT 1985,86 by System Enhancement Associates; ALL RIGHTS RESERVED
XX * 
XX * By:  Thom Henderson
XX * 
XX * Description: This file defines the external data storage used by the ARC
XX * archive utility.
XX * 
XX * 
XX * Language: Computer Innovations Optimizing C86
XX */
XX#include <stdio.h>
XX
XX#define DONT_DEFINE
XX#include "arc.h"
XX
XXINT             keepbak = 0;	/* true if saving the old archive */
XX#ifndef	MSDOS
XXINT             image = 0;	/* true to suppress CRLF/LF x-late */
XX#endif
XX#ifdef MTS
XXchar            sepchr[2] = ":";/* Shared file separator */
XXchar            tmpchr[2] = "-";/* Temporary file prefix */
XX#endif
XXINT             warn = 1;	/* true to print warnings */
XXINT             note = 1;	/* true to print comments */
XXINT             bose = 0;	/* true to be verbose */
XXINT             nocomp = 0;	/* true to suppress compression */
XXINT             overlay = 0;	/* true to overlay on extract */
XXINT             kludge = 0;	/* kludge flag */
XXchar           *arctemp = NULL;	/* arc temp file prefix */
XXchar           *password = NULL;/* encryption password pointer */
XXINT             nerrs = 0;	/* number of errors encountered */
XX
XXchar            hdrver;		/* header version */
XX
XXFILE           *arc;		/* the old archive */
XXFILE           *new;		/* the new archive */
XXchar            arcname[100];	/* storage for archive name */
XXchar            bakname[100];	/* storage for backup copy name */
XXchar            newname[100];	/* storage for new archive name */
XXunsigned INT    arcdate = 0;	/* archive date stamp */
XXunsigned INT    arctime = 0;	/* archive time stamp */
XXunsigned INT    olddate = 0;	/* old archive date stamp */
XXunsigned INT    oldtime = 0;	/* old archive time stamp */
XXINT		dosquash = 0;	/* true to squash instead of crunch */
SHAR_EOF
if test 1838 -ne "`wc -c arcdata.c`"
then
echo shar: error transmitting arcdata.c '(should have been 1838 characters)'
fi
echo shar: extracting arcdel.c '(2077 characters)'
sed 's/^XX//' << \SHAR_EOF > arcdel.c
XX/*
XX * $Log:        arcdel.c,v $
XX * Revision 1.3  87/08/13  17:03:13  hyc
XX * Run thru the indent program...
XX *  Revision 1.2  87/07/21  07:00:45  hyc *** empty
XX * log message ***
XX * 
XX */
XX
XX/*
XX * ARC - Archive utility - ARCDEL
XX * 
XX * Version 2.09, created on 02/03/86 at 22:53:27
XX * 
XX * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED
XX * 
XX * By:  Thom Henderson
XX * 
XX * Description: This file contains the routines used to delete entries in an
XX * archive.
XX * 
XX * Language: Computer Innovations Optimizing C86
XX */
XX#include <stdio.h>
XX#include "arc.h"
XX
XXINT
XXdelarc(num, arg)		/* remove files from archive */
XX	INT             num;	/* number of arguments */
XX	char           *arg[];	/* pointers to arguments */
XX{
XX	struct heads    hdr;	/* header data */
XX	INT             del;	/* true to delete a file */
XX	INT             did[25];/* true when argument used */
XX	INT             n;	/* index */
XX
XX	if (!num)		/* she must specify which */
XX		abort("You must tell me which files to delete!");
XX
XX	for (n = 0; n < num; n++)	/* for each argument */
XX		did[n] = 0;	/* reset usage flag */
XX	rempath(num, arg);	/* strip off paths */
XX
XX	openarc(1);		/* open archive for changes */
XX
XX	while (readhdr(&hdr, arc)) {	/* while more entries in archive */
XX		del = 0;	/* reset delete flag */
XX		for (n = 0; n < num; n++) {	/* for each template given */
XX			if (match(hdr.name, arg[n])) {
XX				del = 1;	/* turn on delete flag */
XX				did[n] = 1;	/* turn on usage flag */
XX				break;	/* stop looking */
XX			}
XX		}
XX
XX		if (del) {	/* skip over unwanted files */
XX			fseek(arc, hdr.size, 1);
XX			if (note)
XX				printf("Deleting file: %s\n", hdr.name);
XX		} else {	/* else copy over file data */
XX			writehdr(&hdr, new);	/* write out header and file */
XX			filecopy(arc, new, hdr.size);
XX		}
XX	}
XX
XX	hdrver = 0;		/* special end of archive type */
XX	writehdr(&hdr, new);	/* write out archive end marker */
XX	closearc(1);		/* close archive after changes */
XX
XX	if (note) {
XX		for (n = 0; n < num; n++) {	/* report unused arguments */
XX			if (!did[n]) {
XX				printf("File not found: %s\n", arg[n]);
XX				nerrs++;
XX			}
XX		}
XX	}
XX}
SHAR_EOF
if test 2077 -ne "`wc -c arcdel.c`"
then
echo shar: error transmitting arcdel.c '(should have been 2077 characters)'
fi
echo shar: extracting arcdos.c '(5048 characters)'
sed 's/^XX//' << \SHAR_EOF > arcdos.c
XX/*
XX * $Log:	arcdos.c,v $
XX * Revision 1.1  88/04/11  17:53:31  hyc
XX * Initial revision
XX * 
XX * Revision 1.2  87/12/19  04:20:26  hyc
XX * Replace reference to f->_file with fileno(f)
XX * 
XX * Revision 1.1  87/12/19  04:19:40  hyc
XX * Initial revision
XX * 
XX * Revision 1.4  87/08/13  17:03:16  hyc
XX * Run thru the indent program...
XX *  Revision 1.3  87/07/21  11:40:35  hyc *** empty
XX * log message ***
XX * 
XX * Revision 1.2  87/07/21  07:22:17  hyc added BSD goodies
XX * 
XX */
XX
XX/*
XX * ARC - Archive utility - ARCDOS
XX * 
XX * Version 1.44, created on 07/25/86 at 14:17:38
XX * 
XX * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED
XX * 
XX * By:  Thom Henderson
XX * 
XX * Description: This file contains certain DOS level routines that assist in
XX * doing fancy things with an archive, primarily reading and setting the date
XX * and time last modified.
XX * 
XX * These are, by nature, system dependant functions.  But they are also, by
XX * nature, very expendable.
XX * 
XX * Language: Computer Innovations Optimizing C86
XX */
XX#include <stdio.h>
XX#include "arc.h"
XX#ifdef MSDOS
XX#include "fileio2.h"		/* needed for filehand */
XX#endif
XX#ifdef BSD
XX#include <sys/types.h>
XX#include <sys/stat.h>
XX#include <sys/time.h>
XX#include "tws.h"
XX#endif
XX
XXINT
XXgetstamp(f, date, time)		/* get a file's date/time stamp */
XX#  ifndef MTS
XX	FILE           *f;	/* file to get stamp from */
XX#else
XX	char           *f;	/* filename "" "" */
XX#endif
XX	unsigned INT   *date, *time;	/* storage for the stamp */
XX{
XX#ifdef MSDOS
XX	struct {
XX		int             ax, bx, cx, dx, si, di, ds, es;
XX	}               reg;
XX
XX	reg.ax = 0x5700;	/* get date/time */
XX	reg.bx = filehand(f);	/* file handle */
XX	if (sysint21(&reg, &reg) & 1)	/* DOS call */
XX		printf("Get timestamp fail (%d)\n", reg.ax);
XX
XX	*date = reg.dx;		/* save date/time */
XX	*time = reg.cx;
XX#endif
XX#ifdef BSD
XX	struct stat    *buf;
XX	int             day, hr, min, sec, yr, imon;
XX	static char     mon[4], *mons[12] = {
XX				   "Jan", "Feb", "Mar", "Apr", "May", "Jun",
XX				    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
XX	};
XX
XX	buf = (struct stat *) malloc(sizeof(struct stat));
XX	fstat(fileno(f), buf);
XX
XX	sscanf(ctime(&(buf->st_mtime)), "%*4s%3s%d%d:%d:%d%d", mon, &day, &hr, &min,
XX	       &sec, &yr);
XX	for (imon = 0; imon < 12 && strcmp(mon, mons[imon]); imon++);
XX
XX	*date = (unsigned INT) (((yr - 1980) << 9) + ((imon + 1) << 5) + day);
XX	*time = (unsigned INT) ((hr << 11) + (min << 5) + sec / 2);
XX#endif
XX#ifdef MTS
XX	fortran         timein(),
XX#ifdef USEGFINFO
XX	                gfinfo();
XX#else
XX	                fileinfo();
XX#endif
XX	int             stclk[2];
XX	char            name[24];
XX	struct bigtime {
XX		int             greg;
XX		int             year;
XX		int             mon;
XX		int             day;
XX		int             hour;
XX		int             min;
XX		int             sec;
XX		int             usec;
XX		int             week;
XX		int             toff;
XX		int             tzn1;
XX		int             tzn2;
XX	}               tvec;
XX#ifdef USEGFINFO
XX	static int      gfflag = 0x0009, gfdummy[2] = {
XX						       0, 0
XX	};
XX	int             gfcinfo[18];
XX#else
XX	static int      cattype = 2;
XX#endif
XX
XX	strcpy(name, f);
XX	strcat(name, " ");
XX#ifdef USEGFINFO
XX	gfcinfo[0] = 18;
XX	gfinfo(name, name, &gfflag, gfcinfo, gfdummy, gfdummy);
XX	timein("*IBM MICROSECONDS*", &gfcinfo[16], &tvec);
XX#else
XX	fileinfo(name, &cattype, "CILCCT  ", stclk);
XX	timein("*IBM MICROSECONDS*", stclk, &tvec);
XX#endif
XX
XX	*date = (unsigned INT) (((tvec.year - 1980) << 9) + ((tvec.mon) << 5) + tvec.day);
XX	*time = (unsigned INT) ((tvec.hour << 11) + (tvec.min << 5) + tvec.sec / 2);
XX#endif
XX}
XX
XXINT
XXsetstamp(f, date, time)		/* set a file's date/time stamp */
XX#  ifdef  BSD
XX	char           *f;	/* filename to stamp */
XX#else
XX	FILE           *f;	/* file to set stamp on */
XX#endif
XX	unsigned INT    date, time;	/* desired date, time */
XX{
XX#ifdef MSDOS
XX	struct {
XX		int             ax, bx, cx, dx, si, di, ds, es;
XX	}               reg;
XX
XX	fflush(f);		/* force any pending output */
XX
XX	reg.ax = 0x5701;	/* set date/time */
XX	reg.bx = filehand(f);	/* file handle */
XX	reg.cx = time;		/* desired time */
XX	reg.dx = date;		/* desired date */
XX	if (sysint21(&reg, &reg) & 1)	/* DOS call */
XX		printf("Set timestamp fail (%d)\n", reg.ax);
XX#endif
XX#ifdef BSD
XX	struct tws      tms;
XX	struct timeval  tvp[2];
XX	twscopy(&tms, dtwstime());
XX	tms.tw_sec = (time & 31) * 2;
XX	tms.tw_min = (time >> 5) & 63;
XX	tms.tw_hour = (time >> 11);
XX	tms.tw_mday = date & 31;
XX	tms.tw_mon = ((date >> 5) & 15) - 1;
XX	tms.tw_year = (date >> 9) + 80;
XX	tms.tw_clock = 0L;
XX	tvp[0].tv_sec = twclock(&tms);
XX	tvp[1].tv_sec = tvp[0].tv_sec;
XX	tvp[0].tv_usec = tvp[1].tv_usec = 0;
XX	utimes(f, tvp);
XX#endif
XX}
XX
XXINT
XXfilehand(stream)		/* find handle on a file */
XX	struct bufstr  *stream;	/* file to grab onto */
XX{
XX#ifdef MSDOS
XX	return stream->bufhand;	/* return DOS 2.0 file handle */
XX#endif
XX}
XX
XXINT
XXizadir(filename)		/* Is filename a directory? */
XX	char           *filename;
XX{
XX#ifndef BSD
XX	return (0);
XX#else
XX	struct stat     buf;
XX
XX	if (stat(filename, &buf) != 0)
XX		return (0);	/* Ignore if stat fails since */
XX	else
XX		return (buf.st_mode & S_IFDIR);	/* bad files trapped later */
XX#endif
XX}
SHAR_EOF
if test 5048 -ne "`wc -c arcdos.c`"
then
echo shar: error transmitting arcdos.c '(should have been 5048 characters)'
fi
echo shar: extracting arcext.c '(5231 characters)'
sed 's/^XX//' << \SHAR_EOF > arcext.c
XX/*
XX * $Log:	arcext.c,v $
XX * Revision 1.2  88/04/11  17:59:09  hyc
XX * re-synch with MTS, formatting
XX * 
XX * Revision 1.1  88/04/11  17:56:12  hyc
XX * Initial revision
XX * 
XX * Revision 1.4  87/08/13  17:03:21  hyc
XX * Run thru the indent program...
XX *  Revision 1.3  87/07/21  11:39:59  hyc minor
XX * fixups
XX * 
XX * Revision 1.2  87/07/21  07:32:17  hyc added BSD goodies
XX * 
XX */
XX
XX/*
XX * ARC - Archive utility - ARCEXT
XX * 
XX * Version 2.19, created on 10/24/86 at 14:53:32
XX * 
XX * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED
XX * 
XX * By:  Thom Henderson
XX * 
XX * Description: This file contains the routines used to extract files from an
XX * archive.
XX * 
XX * Language: Computer Innovations Optimizing C86
XX */
XX#include <stdio.h>
XX#include "arc.h"
XX
XXINT
XXextarc(num, arg, prt)		/* extract files from archive */
XX	INT             num;	/* number of arguments */
XX	char           *arg[];	/* pointers to arguments */
XXINT             prt;		/* true if printing */
XX{
XX	struct heads    hdr;	/* file header */
XX	INT             save;	/* true to save current file */
XX	INT             did[25];/* true when argument was used */
XX	char           *i, *rindex();	/* string index */
XX	char          **name, *malloc();	/* name pointer list,
XX						 * allocator */
XX	INT             n;	/* index */
XX	INT             extfile();
XX
XX	name = (char **) malloc(num * sizeof(char *));	/* get storage for name
XX							 * pointers */
XX
XX	for (n = 0; n < num; n++) {	/* for each argument */
XX		did[n] = 0;	/* reset usage flag */
XX#ifndef MTS
XX		if (!(i = rindex(arg[n], '\\')))	/* find start of name */
XX			if (!(i = rindex(arg[n], '/')))
XX				if (!(i = rindex(arg[n], ':')))
XX					i = arg[n] - 1;
XX#else
XX		if (!(i = rindex(arg[n], sepchr[0])))
XX			if (arg[n][0] != tmpchr[0])
XX				i = arg[n] - 1;
XX			else
XX				i = arg[n];
XX#endif
XX		name[n] = i + 1;
XX	}
XX
XX
XX	openarc(0);		/* open archive for reading */
XX
XX	if (num) {		/* if files were named */
XX		while (readhdr(&hdr, arc)) {	/* while more files to check */
XX			save = 0;	/* reset save flag */
XX			for (n = 0; n < num; n++) {	/* for each template
XX							 * given */
XX				if (match(hdr.name, name[n])) {
XX					save = 1;	/* turn on save flag */
XX					did[n] = 1;	/* turn on usage flag */
XX					break;	/* stop looking */
XX				}
XX			}
XX
XX			if (save)	/* extract if desired, else skip */
XX				extfile(&hdr, arg[n], prt);
XX			else
XX				fseek(arc, hdr.size, 1);
XX		}
XX	} else
XX		while (readhdr(&hdr, arc))	/* else extract all files */
XX			extfile(&hdr, "", prt);
XX
XX	closearc(0);		/* close archive after reading */
XX
XX	if (note) {
XX		for (n = 0; n < num; n++) {	/* report unused args */
XX			if (!did[n]) {
XX				printf("File not found: %s\n", arg[n]);
XX				nerrs++;
XX			}
XX		}
XX	}
XX	free(name);
XX}
XX
XXINT
XXextfile(hdr, path, prt)		/* extract a file */
XX	struct heads   *hdr;	/* pointer to header data */
XX	char           *path;	/* pointer to path name */
XX	INT             prt;	/* true if printing */
XX{
XX	FILE           *f, *fopen();	/* extracted file, opener */
XX	char            buf[100];	/* input buffer */
XX	char            fix[100];	/* fixed name buffer */
XX	char           *i, *rindex();	/* string index */
XX
XX	if (prt) {		/* printing is much easier */
XX		unpack(arc, stdout, hdr);	/* unpack file from archive */
XX		printf("\f");	/* eject the form */
XX		return;		/* see? I told you! */
XX	}
XX	strcpy(fix, path);	/* note path name template */
XX#ifndef MTS
XX	if (!(i = rindex(fix, '\\')))	/* find start of name */
XX		if (!(i = rindex(fix, '/')))
XX			if (!(i = rindex(fix, ':')))
XX				i = fix - 1;
XX#else
XX	if (!(i = rindex(fix, sepchr[0])))
XX		if (fix[0] != tmpchr[0])
XX			i = fix - 1;
XX		else
XX			i = fix;
XX#endif
XX	strcpy(i + 1, hdr->name);	/* replace template with name */
XX
XX	if (note)
XX		printf("Extracting file: %s\n", fix);
XX
XX	if (warn && !overlay) {
XX		if (f = fopen(fix, "r")) {	/* see if it exists */
XX#ifdef MTS
XX			if ((buf[0] = fgetc(f)) != EOF) {	/* kludge for temp files */
XX#endif
XX				fclose(f);
XX				printf("WARNING: File %s already exists!", fix);