ARC for BSD4.2 (part 4 of 5)

turner at imagen.UUCP turner at imagen.UUCP
Tue Aug 5 08:43:41 AEST 1986


This is my hacked version of the arc program that was posted to the net, I
have modified it to run under Unix BSD4.2. if you want it to run under 
SVR2 you probably will have to change the opendir, scandir, and closedir
calls, I don't really know System 5. IMPORTANT: this is a BETA test version
i doubt severly that there are no bugs, please report any that you find to me.

1) I don't have a PC handy so i have no idea if it still works on the PC; to
	compile it for the PC edit arc.h and arcs.c and change the #defines,
	the define ST is for the Atari 520ST and with luck that will be done
	shortly. If you compile it for the PC you will need the routines for 
	opendir etc. that are in shar part 5, otherwise you can ignore that 
	shar file.
2) the Makefile is configured to compile for debugging (-g) (shows ya what 
	kind of faith i have in my code (:-)
3) everything seems to work for both arc files created on the PC and on BSD4.2
	with the exception of the t (test) option which gives strange results,
	i suspect the problem is in the code not the archive
4) there is one bug that i know of, if you archive a 0 length file, arc will
	blow up (floating point exception) when you try to extract it; the
	question is should the check happen when you add the file, extract
	it, or should if create a 0 length file ? you decide.
5) send flames etc. to me, because of the way postnews works here my signature
	will probably be at the end of each shar file, if not its:
----
Name:	James M. Turner
Mail:	Imagen Corp. 2650 San Tomas Expressway, P.O. Box 58101
        Santa Clara, CA 95052-8101
AT&T:	(408) 986-9400
UUCP:	...{decvax,ucbvax}!decwrl!imagen!turner
CompuServe: 76327,1575
GEnie     : D-ARCANGEL
----

#! /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:
#	arctst.c
#	arcunp.c
#	arcusq.c
#	arcvax.c
# This archive created: Mon Aug  4 14:48:03 1986
# By:	D'arc Angel (The Houses of the Holy)
export PATH; PATH=/bin:/usr/bin:$PATH
echo shar: "extracting 'arctst.c'" '(1724 characters)'
if test -f 'arctst.c'
then
	echo shar: "will not over-write existing file 'arctst.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'arctst.c'
	Xstatic char *RCSid = "$Header: arctst.c,v 1.1 86/06/26 15:01:02 turner Exp $";
	X
	X/*
	X * $Log:	arctst.c,v $
	X * Revision 1.1  86/06/26  15:01:02  turner
	X * initial version
	X * 
	X * 
	X */
	X
	X/*  ARC - Archive utility - ARCTST
	X
	X$define(tag,$$segment(@1,$$index(@1,=)+1))#
	X$define(version,Version $tag(
	XTED_VERSION DB =2.12), created on $tag(
	XTED_DATE DB =02/03/86) at $tag(
	XTED_TIME DB =23:00:40))#
	X$undefine(tag)#
	X    $version
	X
	X(C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED
	X
	X    By:  Thom Henderson
	X
	X    Description:
	X         This file contains the routines used to test archive integrity.
	X
	X    Language:
	X         Computer Innovations Optimizing C86
	X*/
	X#include <stdio.h>
	X#include "arc.h"
	X
	Xtstarc()                               /* test integrity of an archive */
	X{
	X    struct heads hdr;                  /* file header */
	X    long arcsize, ftell();             /* archive size */
	X
	X    openarc(0);                        /* open archive for reading */
	X    fseek(arc,0L,2);                   /* move to end of archive */
	X    arcsize = ftell(arc);              /* see how big it is */
	X    fseek(arc,0L,0);                   /* return to top of archive */
	X
	X    while(readhdr(&hdr,arc))
	X    {    if(ftell(arc)+hdr.size>arcsize)
	X         {    printf("Archive truncated in file %s\n",hdr.name);
	X              nerrs++;
	X              break;
	X         }
	X
	X         else
	X         {    printf("Testing file: %-12s  ",hdr.name);
	X              if(unpack(arc,NULL,&hdr))
	X                   nerrs++;
	X              else printf("okay\n");
	X         }
	X    }
	X
	X    if(nerrs<1)
	X         printf("No errors detected\n");
	X    else if(nerrs==1)
	X         printf("One error detected\n");
	X    else printf("%d errors detected\n",nerrs);
	X}
SHAR_EOF
if test 1724 -ne "`wc -c < 'arctst.c'`"
then
	echo shar: "error transmitting 'arctst.c'" '(should have been 1724 characters)'
fi
fi
echo shar: "extracting 'arcunp.c'" '(6288 characters)'
if test -f 'arcunp.c'
then
	echo shar: "will not over-write existing file 'arcunp.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'arcunp.c'
	Xstatic char *RCSid = "$Header: arcunp.c,v 1.2 86/07/15 07:54:25 turner Exp $";
	X
	X/*
	X * $Log:	arcunp.c,v $
	X * Revision 1.2  86/07/15  07:54:25  turner
	X * 
	X * 
	X * Revision 1.1  86/06/26  15:01:04  turner
	X * initial version
	X * 
	X * 
	X */
	X
	X/*  ARC - Archive utility - ARCUNP
	X
	X$define(tag,$$segment(@1,$$index(@1,=)+1))#
	X$define(version,Version $tag(
	XTED_VERSION DB =3.16), created on $tag(
	XTED_DATE DB =02/03/86) at $tag(
	XTED_TIME DB =23:01:16))#
	X$undefine(tag)#
	X    $version
	X
	X(C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED
	X
	X    By:  Thom Henderson
	X
	X    Description:
	X         This file contains the routines used to expand a file
	X         when taking it out of an archive.
	X
	X    Language:
	X         Computer Innovations Optimizing C86
	X*/
	X#include <stdio.h>
	X#include "arc.h"
	X
	X/* stuff for repeat unpacking */
	X
	X#define DLE 0x90                       /* repeat byte flag */
	X
	Xstatic int state;                      /* repeat unpacking state */
	X
	X/* repeat unpacking states */
	X
	X#define NOHIST 0                       /* no relevant history */
	X#define INREP 1                        /* sending a repeated value */
	X
	Xstatic int crcval;                     /* CRC check value */
	Xstatic long size;                      /* bytes to read */
	X
	Xint unpack(f,t,hdr)                    /* unpack an archive entry */
	XFILE *f, *t;                           /* source, destination */
	Xstruct heads *hdr;                     /* pointer to file header data */
	X{
	X int c;                             /* one char of stream */
	X
	X    /* setups common to all methods */
	X
	X    crcval = 0;                        /* reset CRC check value */
	X    size = hdr->size;                  /* set input byte counter */
	X    state = NOHIST;                    /* initial repeat unpacking state */
	X    setcode();                         /* set up for decoding */
	X
	X    /* use whatever method is appropriate */
	X
	X    switch(hdrver)                     /* choose proper unpack method */
	X    {
	X    case 1:                            /* standard packing */
	X    case 2:
	X         while((c=getc_unp(f))!=EOF)
	X              putc_unp(c,t);
	X         break;
	X
	X    case 3:                            /* non-repeat packing */
	X         while((c=getc_unp(f))!=EOF)
	X              putc_ncr(c,t);
	X         break;
	X
	X    case 4:                            /* Huffman squeezing */
	X         init_usq(f);
	X         while((c=getc_usq(f))!=EOF)
	X              putc_ncr(c,t);
	X         break;
	X
	X    case 5:                            /* Lempel-Zev compression */
	X         init_ucr(0);
	X         while((c=getc_ucr(f))!=EOF)
	X              putc_unp(c,t);
	X         break;
	X
	X    case 6:                            /* Lempel-Zev plus non-repeat */
	X         init_ucr(0);
	X         while((c=getc_ucr(f))!=EOF)
	X              putc_ncr(c,t);
	X         break;
	X
	X    case 7:                            /* L-Z plus ncr with new hash */
	X         init_ucr(1);
	X         while((c=getc_ucr(f))!=EOF)
	X              putc_ncr(c,t);
	X         break;
	X
	X    case 8:                            /* dynamic Lempel-Zev */
	X         decomp(f,t);
	X         break;
	X
	X    default:                           /* unknown method */
	X         if(warn)
	X         {    printf("I don't know how to unpack file %s\n",hdr->name);
	X              printf("I think you need a newer version of ARC\n");
	X              nerrs++;
	X         }
	X         fseek(f,hdr->size,1);         /* skip over bad file */
	X         return 1;                     /* note defective file */
	X    }
	X
	X    /* cleanups common to all methods */
	X
	X    if(crcval!=hdr->crc)
	X    {    if(warn)
	X         {    printf("WARNING: File %s fails CRC check\n",hdr->name);
	X              nerrs++;
	X         }
	X         return 1;                     /* note defective file */
	X    }
	X    return 0;                          /* file is okay */
	X}
	X
	X/*  This routine is used to put bytes in the output file.  It also
	X    performs various housekeeping functions, such as maintaining the
	X    CRC check value.
	X*/
	X
	Xstatic putc_unp(c,t)                   /* output an unpacked byte */
	Xchar c;                                /* byte to output */
	XFILE *t;                               /* file to output to */
	X{
	X    crcval = addcrc(crcval,c);         /* update the CRC check value */
	X    putc_tst(c,t);
	X}
	X
	X/*  This routine is used to decode non-repeat compression.  Bytes are
	X    passed one at a time in coded format, and are written out uncoded.
	X    The data is stored normally, except that runs of more than two
	X    characters are represented as:
	X
	X         <char> <DLE> <count>
	X
	X    With a special case that a count of zero indicates a DLE as data,
	X    not as a repeat marker.
	X*/
	X
	Xputc_ncr(c,t)                          /* put NCR coded bytes */
	Xunsigned char c;                       /* next byte of stream */
	XFILE *t;                               /* file to receive data */
	X{
	X    static int lastc;                  /* last character seen */
	X
	X    switch(state)                      /* action depends on our state */
	X    {
	X    case NOHIST:                       /* no previous history */
	X         if(c==DLE)                    /* if starting a series */
	X              state = INREP;           /* then remember it next time */
	X         else putc_unp(lastc=c,t);     /* else nothing unusual */
	X         return;
	X
	X    case INREP:                        /* in a repeat */
	X         if(c)                         /* if count is nonzero */
	X              while(--c)               /* then repeatedly ... */
	X                   putc_unp(lastc,t);  /* ... output the byte */
	X         else putc_unp(DLE,t);         /* else output DLE as data */
	X         state = NOHIST;               /* back to no history */
	X         return;
	X
	X    default:
	X         abort("Bad NCR unpacking state (%d)",state);
	X    }
	X}
	X
	X/*  This routine provides low-level byte input from an archive.  This
	X    routine MUST be used, as end-of-file is simulated at the end of
	X    the archive entry.
	X*/
	X
	Xint getc_unp(f)                        /* get a byte from an archive */
	XFILE *f;                               /* archive file to read */
	X{
	X    if(!size)                          /* if no data left */
	X         return EOF;                   /* then pretend end of file */
	X
	X    size--;                            /* deduct from input counter */
	X    return code(fgetc(f));             /* and return next decoded byte */
	X}
SHAR_EOF
if test 6288 -ne "`wc -c < 'arcunp.c'`"
then
	echo shar: "error transmitting 'arcunp.c'" '(should have been 6288 characters)'
fi
fi
echo shar: "extracting 'arcusq.c'" '(3170 characters)'
if test -f 'arcusq.c'
then
	echo shar: "will not over-write existing file 'arcusq.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'arcusq.c'
	Xstatic char *RCSid = "$Header: arcusq.c,v 1.2 86/07/15 07:54:30 turner Exp $";
	X
	X/*
	X * $Log:	arcusq.c,v $
	X * Revision 1.2  86/07/15  07:54:30  turner
	X * 
	X * 
	X * Revision 1.1  86/06/26  15:01:07  turner
	X * initial version
	X * 
	X * 
	X */
	X
	X/*  ARC - Archive utility - ARCUSQ
	X
	X$define(tag,$$segment(@1,$$index(@1,=)+1))#
	X$define(version,Version $tag(
	XTED_VERSION DB =3.13), created on $tag(
	XTED_DATE DB =01/30/86) at $tag(
	XTED_TIME DB =20:11:42))#
	X$undefine(tag)#
	X    $version
	X
	X(C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED
	X
	X    By:  Thom Henderson
	X
	X    Description:
	X         This file contains the routines used to expand a file
	X         which was packed using Huffman squeezing.
	X
	X         Most of this code is taken from an USQ program by Richard
	X         Greenlaw, which was adapted to CI-C86 by Robert J. Beilstein.
	X
	X    Language:
	X         Computer Innovations Optimizing C86
	X*/
	X#include <stdio.h>
	X#include "arc.h"
	X
	X/* stuff for Huffman unsqueezing */
	X
	X#define ERROR (-1)
	X
	X#define SPEOF 256                      /* special endfile token */
	X#define NUMVALS 257                    /* 256 data values plus SPEOF */
	X
	Xextern struct nd                       /* decoding tree */
	X{ int child[2];                      /* left, right */
	X}   node[NUMVALS];                     /* use large buffer */
	X
	Xstatic int bpos;                       /* last bit position read */
	Xstatic int curin;                      /* last byte value read */
	Xstatic int numnodes;                   /* number of nodes in decode tree */
	X
	Xstatic int get_int(f)                  /* get an integer */
	XFILE *f;                               /* file to get it from */
	X{
	X    return getc_unp(f) | (getc_unp(f)<<8);
	X}
	X
	Xinit_usq(f)                            /* initialize Huffman unsqueezing */
	XFILE *f;                               /* file containing squeezed data */
	X{
	X int i;                             /* node index */
	X
	X    bpos = 99;                         /* force initial read */
	X
	X    numnodes = get_int(f);
	X
	X    if(numnodes<0 || numnodes>=NUMVALS)
	X         abort("File has an invalid decode tree");
	X
	X    /* initialize for possible empty tree (SPEOF only) */
	X
	X    node[0].child[0] = -(SPEOF + 1);
	X    node[0].child[1] = -(SPEOF + 1);
	X
	X    for(i=0; i<numnodes; ++i)          /* get decoding tree from file */
	X    {    node[i].child[0] = get_int(f);
	X         node[i].child[1] = get_int(f);
	X    }
	X}
	X
	Xint getc_usq(f)                        /* get byte from squeezed file */
	XFILE *f;                               /* file containing squeezed data */
	X{
	X int i;                             /* tree index */
	X
	X    /* follow bit stream in tree to a leaf */
	X
	X    for(i=0; i>=0; )                   /* work down(up?) from root */
	X    {    if(++bpos>7)
	X         {    if((curin=getc_unp(f)) == ERROR)
	X                   return(ERROR);
	X              bpos = 0;
	X
	X              /* move a level deeper in tree */
	X              i = node[i].child[1&curin];
	X         }
	X         else i = node[i].child[1 & (curin >>= 1)];
	X    }
	X
	X    /* decode fake node index to original data value */
	X
	X    i = -(i + 1);
	X
	X    /* decode special endfile token to normal EOF */
	X
	X    i = (i==SPEOF) ? EOF : i;
	X    return i;
	X}
SHAR_EOF
if test 3170 -ne "`wc -c < 'arcusq.c'`"
then
	echo shar: "error transmitting 'arcusq.c'" '(should have been 3170 characters)'
fi
fi
echo shar: "extracting 'arcvax.c'" '(671 characters)'
if test -f 'arcvax.c'
then
	echo shar: "will not over-write existing file 'arcvax.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'arcvax.c'
	X#include <stdio.h>
	X#include <ctype.h>
	X
	X/*
	X * Misc routines to emulate IBM MSDOS functions under BSD
	X */
	Xupper(string)
	Xchar *string;
	X{
	X    char *p;
	X
	X    for(p = string; *p != NULL; p++)
	X	if(islower(*p))
	X	    *p = toupper(*p);
	X}
	Xchar *setmem(dest,size,c)
	Xchar *dest,c;
	Xint size;
	X{
	X int i;
	X
	X    for(i = 0; i < size; dest[i] = c, i++);
	X    return(&dest[0]);
	X}
	Xchar *gcdir(dirname)
	Xchar *dirname;
	X
	X{
	X	if(dirname == NULL || strlen(dirname) == 0)
	X		dirname = (char *)malloc(1024);
	X
	X	getwd(dirname);
	X}
	Xabort(s,arg1,arg2,arg3)
	Xchar *s;
	X{
	X    fprintf(stderr,"ARC: ");
	X    fprintf(stderr,s,arg1,arg2,arg3);
	X    fprintf(stderr,"\n");
	X#if BSD
	X    perror("BSD");
	X#endif
	X    exit(1);
	X}
SHAR_EOF
if test 671 -ne "`wc -c < 'arcvax.c'`"
then
	echo shar: "error transmitting 'arcvax.c'" '(should have been 671 characters)'
fi
fi
exit 0
#	End of shell archive
-- 
----
	"I ain't gay, but there are sure times when i wish i could say
		that i wasn't straight"

Name:	James M. Turner
Mail:	Imagen Corp. 2650 San Tomas Expressway, P.O. Box 58101
        Santa Clara, CA 95052-8101
AT&T:	(408) 986-9400
UUCP:	...{decvax,ucbvax}!decwrl!imagen!turner
CompuServe: 76327,1575
GEnie     : D-ARCANGEL



More information about the Comp.sources.unix mailing list