[net.sources] Public-domain ARC extraction tool

joe@petsd.UUCP (Joe Orost) (12/16/86)

::
#!/bin/sh
cat >README <<'------ EOF ------'
This directory contains the first cut at public-domain unix commands for 
extracting a file from an ARC archive, and for printing out the name of the
file in an ARC archive.

I use them for extracting the files from the SIMTEL20 public-domain software
archives.

		Usage: arcx <archive>

	Extracts a file from the archive.  Handles image, run-length, and
	compress format archives (crunched).  That is, codes 1, 2, 3, and 8.


		Usage: arct <archive>

	Prints the filename and encoding of the file in the archive.

Warning: ONLY ARCHIVES CONTAINING A SINGLE FILE ARE SUPPORTED.

Prerequisite: Must have my compress(1) program installed.

Please send any comments, upgrades, etc., to me at the address below.

				regards,
				joe

--

 Full-Name:  Joseph M. Orost
 UUCP:       ihnp4!vax135!petsd!joe
 ARPA:	     vax135!petsd!joe@BERKELEY
 Phone:      (201) 758-7284
 US Mail:    MS 313; Concurrent Computer Corporation; 106 Apple St
             Tinton Falls, NJ 07724
------ EOF ------
ls -l README
cat >arcname.c <<'------ EOF ------'
#include <stdio.h>
main()
{
	char fnm[13];
	register unsigned c, i, code;

	if(getchar() != 0x1a) {
		fprintf(stderr, "Not in ARC format\n");
		exit(9);
	}
	code = getchar();	/* code (should be 8) */
	for(i=0; i<13; i++) {
		c = getchar();
		if(c >= 'A' && c <= 'Z') {
			c += 'a' - 'A';
		}
		fnm[i] = c;
	}
	printf("%s\n", fnm);
	return code;
}
------ EOF ------
ls -l arcname.c
cat >arcstrip.c <<'------ EOF ------'
#include <stdio.h>
main()
{
	register c, i, size;

	if(getchar() != 0x1a) {
		fprintf(stderr, "Not in ARC format\n");
		exit(1);
	}
	c = getchar();
	for(i=0; i<13; i++) {
		c = getchar();
	}
	size = getchar(); size = (getchar() << 8) + size; 
	size = (getchar() << 16) + size; size = (getchar() << 24) + size;
	for(i=10; i>0; i--) {
		c = getchar();
	}
	while(size--) {
		c = getchar();
		putchar(c);
	}
	return 0;
}
------ EOF ------
ls -l arcstrip.c
cat >arct <<'------ EOF ------'
if test -z "$1"; then
	echo "Usage: arct archive"
	exit 1
fi
if test -f "$1"; then
	NAME=`arcname <$1`
	CODE="$?"
	case $CODE in
	1)	echo "$NAME: image";;
	2)	echo "$NAME: image";;
	3)	echo "$NAME: run-length";;
	8)	echo "$NAME: crunched";;
	9)	exit 1;;
	*)	echo "$NAME: NOT HANDLED"
		exit 1;;
	esac
else
	echo "arct: Cannot open $1"
	exit 1
fi
------ EOF ------
chmod +x arct
ls -l arct
cat >arctoZ.c <<'------ EOF ------'
#include <stdio.h>
main()
{
	register c, i, size;

	if(getchar() != 0x1a) {
		fprintf(stderr, "Not in ARC format\n");
		exit(1);
	}
	if((c = getchar()) != 8) {
		fprintf(stderr, "Can only handle code 8 ARC files\n");
		fprintf(stderr, "This file is code %d\n", c);
		exit(1);
	}
	for(i=0; i<13; i++) {
		c = getchar();
	}
	size = getchar(); size = (getchar() << 8) + size; 
	size = (getchar() << 16) + size; size = (getchar() << 24) + size;
	for(i=10; i>0; i--) {
		c = getchar();
	}
	c = getchar();
	putchar(0x1f); putchar(0x9d); putchar((0x80 | c));
	while(--size) {
		c = getchar();
		putchar(c);
	}
	return 0;
}
------ EOF ------
ls -l arctoZ.c
cat >arcunrun.c <<'------ EOF ------'
#include <stdio.h>
#define CODE	0x90
main()
{
	register c, lastc;

	while((c = getchar()) != EOF) {
		if(c == CODE) {
			c = getchar();	/* count */
			if(c) {
				while(--c) {
					putchar(lastc);
				}
			} else {
				putchar(CODE);
			}
		} else {
			putchar(c);
			lastc = c;
		}
	}
}
------ EOF ------
ls -l arcunrun.c
cat >arcx <<'------ EOF ------'
if test -z "$1"; then
	echo "Usage: arcx archive"
	exit 1
fi
if test -f "$1"; then
	NAME=`arcname <$1`
	CODE="$?"
	case $CODE in
	1)	arcstrip <$1 > "$NAME";;
	2)	arcstrip <$1 > "$NAME";;
	3)	arcstrip <$1 | arcunrun > "$NAME";;
	8)	arctoZ <$1 | compress -d | arcunrun > "$NAME";;
	9)	exit 1;;
	*)	echo "arcx: Cannot extract $NAME in code $CODE archive"
		exit 1;;
	esac
	echo "arcx: File $NAME extracted"
else
	echo "arcx: Cannot open $1"
	exit 1
fi
------ EOF ------
chmod +x arcx
ls -l arcx
exit