Mod.sources:  Volume 2, Issue 29
Submitted by: vax135!petsd!joe (Joe Orost)

#! /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 the files:
#	README
#	README3.0
#	atob.c
#	btoa.1
#	btoa.c
#	compressdir
#	compressdir.1
#	tarmail
#	uncompressdir
#	untarmail
#	zcmp
#	zcmp.1
#	zdiff
#	zmore
#	zmore.1
# This archive created: Thu Aug  1 11:53:09 1985
export PATH; PATH=/bin:$PATH
echo shar: extracting "'README'" '(3194 characters)'
if test -f 'README'
then
	echo shar: will not over-write existing file "'README'"
else
sed 's/^X//' << \SHAR_EOF > 'README'
Compress version 4.0 improvements:
	o compress() speedup (10-50%) by changing division hash to xor
	o decompress() speedup (5-10%)
	o Memory requirements reduced (3-30%)
	o Stack requirements reduced to less than 4kb
	o Removed 'Big+Fast' compress code (FBITS) because of compress speedup
    	o Portability mods for Z8000 and PC/XT (but not zeus 3.2)
	o Default to 'quiet' mode
	o Unification of 'force' flags
	o Manual page overhaul
	o Portability enhancement for M_XENIX
	o Removed text on #else and #endif
	o Added "-V" switch to print version and options
	o Added #defines for SIGNED_COMPARE_SLOW
	o Added Makefile and "usermem" program
	o Removed all floating point computations
	o New programs:
		compressdir - compress all files on a directory
		uncompressdir - uncompress all files on a directory
		zcmp - cmp compressed files
		zdiff - diff compressed files
	  The following are with thanks to philabs!per:
		btoa - convert binary to ascii for mailing
		atob - convert ascii to binary with checksum
		tarmail - tar, compress, btoa, and mail files
		untarmail - restore "tarmail" files

		WARNING: These last few programs are not compatible 
		with the original ones from the net.  The encoding
		has changed.  See btoa.c for more info.

The "usermem" script attempts to determine the maximum process size.  Some
editing of the script may be necessary (see the comments).  If you can't get
it to work at all, just create file "USERMEM" containing the maximum process
size in decimal.

The following preprocessor symbols control the compilation of "compress.c":

	o USERMEM		Maximum process memory on the system
	o SACREDMEM		Amount to reserve for other proceses
	o SIGNED_COMPARE_SLOW	Unsigned compare instructions are faster
	o NO_UCHAR		Don't use "unsigned char" types
	o BITS			Overrules default set by USERMEM-SACREDMEM
	o vax			Generate inline assembler
	o interdata		Defines SIGNED_COMPARE_SLOW
	o M_XENIX		Makes arrays < 65536 bytes each
	o pdp11			BITS=12, NO_UCHAR
	o z8000			BITS=12
	o pcxt			BITS=12
	o BSD4_2		Allow long filenames ( > 14 characters) &
				Call setlinebuf(stderr)

The difference "usermem-sacredmem" determines the maximum BITS that can be
specified with the "-b" flag.

memory: at least		BITS
------  -- -----                ----
     433,484			 16
     229,600			 15
     127,536			 14
      73,464			 13
           0			 12

The default is BITS=16.

The maximum bits can be overrulled by specifying "-DBITS=bits" at
compilation time.

WARNING: files compressed on a large machine with more bits than allowed by 
a version of compress on a smaller machine cannot be decompressed!  Use the
"-b12" flag to generate a file on a large machine that can be uncompressed 
on a 16-bit machine.

The output of compress 4.0 is fully compatible with that of compress 3.0.
In other words, the output of compress 4.0 may be fed into uncompress 3.0 or
the output of compress 3.0 may be fed into uncompress 4.0.

The output of compress 4.0 not compatable with that of
compress 2.0.  However, compress 4.0 still accepts the output of
compress 2.0.  To generate output that is compatable with compress
2.0, use the undocumented "-C" flag.

Check the Makefile, then "make".
SHAR_EOF
if test 3194 -ne "`wc -c < 'README'`"
then
	echo shar: error transmitting "'README'" '(should have been 3194 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'README3.0'" '(8142 characters)'
if test -f 'README3.0'
then
	echo shar: will not over-write existing file "'README3.0'"
else
sed 's/^X//' << \SHAR_EOF > 'README3.0'
Enclosed is compress version 3.0 with the following changes:

1.	"Block" compression is performed.  After the BITS run out, the
	compression ratio is checked every so often.  If it is decreasing,
	the table is cleared and a new set of substrings are generated.

	This makes the output of compress 3.0 not compatable with that of
	compress 2.0.  However, compress 3.0 still accepts the output of
	compress 2.0.  To generate output that is compatable with compress
	2.0, use the undocumented "-C" flag.

2.	A quiet "-q" flag has been added for use by the news system.

3.	The character chaining has been deleted and the program now uses
	hashing.  This improves the speed of the program, especially
	during decompression.  Other speed improvements have been made,
	such as using putc() instead of fwrite().

4.	A large table is used on large machines when a relatively small
	number of bits is specified.  This saves much time when compressing
	for a 16-bit machine on a 32-bit virtual machine.  Note that the
	speed improvement only occurs when the input file is > 30000
	characters, and the -b BITS is less than or equal to the cutoff
	described below.

Most of these changes were made by James A. Woods (ames!jaw).  Thank you
James!

Version 3.0 has been beta tested on many machines.

To compile compress:

	cc -O -DUSERMEM=usermem -o compress compress.c

Where "usermem" is the amount of physical user memory available (in bytes).  
If any physical memory is to be reserved for other processes, put in 
"-DSACREDMEM sacredmem", where "sacredmem" is the amount to be reserved.

The difference "usermem-sacredmem" determines the maximum BITS that can be
specified, and the cutoff bits where the large+fast table is used.

memory: at least		BITS		cutoff
------  -- -----                ----            ------
   4,718,592 			 16		  13
   2,621,440 			 16		  12
   1,572,864			 16		  11
   1,048,576			 16		  10
     631,808			 16               --
     329,728			 15               --
     178,176			 14		  --
      99,328			 13		  --
           0			 12		  --

The default memory size is 750,000 which gives a maximum BITS=16 and no
large+fast table.

The maximum bits can be overrulled by specifying "-DBITS=bits" at
compilation time.

If your machine doesn't support unsigned characters, define "NO_UCHAR" 
when compiling.

If your machine has "int" as 16-bits, define "SHORT_INT" when compiling.

After compilation, move "compress" to a standard executable location, such 
as /usr/local.  Then:
	cd /usr/local
	ln compress uncompress
	ln compress zcat

On machines that have a fixed stack size (such as Perkin-Elmer), set the
stack to at least 12kb.  ("setstack compress 12" on Perkin-Elmer).

Next, install the manual (compress.l).
	cp compress.l /usr/man/manl
	cd /usr/man/manl
	ln compress.l uncompress.l
	ln compress.l zcat.l

		- or -

	cp compress.l /usr/man/man1/compress.1
	cd /usr/man/man1
	ln compress.1 uncompress.1
	ln compress.1 zcat.1

The zmore shell script and manual page are for use on systems that have a
"more(1)" program.  Install the shell script and the manual page in a "bin"
and "man" directory, respectively.  If your system doesn't have the
"more(1)" program, just skip "zmore".

					regards,
					petsd!joe

Here is the README file from the previous version of compress (2.0):

>Enclosed is compress.c version 2.0 with the following bugs fixed:
>
>1.	The packed files produced by compress are different on different
>	machines and dependent on the vax sysgen option.
>		The bug was in the different byte/bit ordering on the
>		various machines.  This has been fixed.
>
>		This version is NOT compatible with the original vax posting
>		unless the '-DCOMPATIBLE' option is specified to the C
>		compiler.  The original posting has a bug which I fixed, 
>		causing incompatible files.  I recommend you NOT to use this
>		option unless you already have a lot of packed files from
>		the original posting by thomas.
>2.	The exit status is not well defined (on some machines) causing the
>	scripts to fail.
>		The exit status is now 0,1 or 2 and is documented in
>		compress.l.
>3.	The function getopt() is not available in all C libraries.
>		The function getopt() is no longer referenced by the
>		program.
>4.	Error status is not being checked on the fwrite() and fflush() calls.
>		Fixed.
>
>The following enhancements have been made:
>
>1.	Added facilities of "compact" into the compress program.  "Pack",
>	"Unpack", and "Pcat" are no longer required (no longer supplied).
>2.	Installed work around for C compiler bug with "-O".
>3.	Added a magic number header (\037\235).  Put the bits specified
>	in the file.
>4.	Added "-f" flag to force overwrite of output file.
>5.	Added "-c" flag and "zcat" program.  'ln compress zcat' after you
>	compile.
>6.	The 'uncompress' script has been deleted; simply 
>	'ln compress uncompress' after you compile and it will work.
>7.	Removed extra bit masking for machines that support unsigned
>	characters.  If your machine doesn't support unsigned characters,
>	define "NO_UCHAR" when compiling.
>
>Compile "compress.c" with "-O -o compress" flags.  Move "compress" to a
>standard executable location, such as /usr/local.  Then:
>	cd /usr/local
>	ln compress uncompress
>	ln compress zcat
>
>On machines that have a fixed stack size (such as Perkin-Elmer), set the
>stack to at least 12kb.  ("setstack compress 12" on Perkin-Elmer).
>
>Next, install the manual (compress.l).
>	cp compress.l /usr/man/manl		- or -
>	cp compress.l /usr/man/man1/compress.1
>
>Here is the README that I sent with my first posting:
>
>>Enclosed is a modified version of compress.c, along with scripts to make it
>>run identically to pack(1), unpack(1), an pcat(1).  Here is what I
>>(petsd!joe) and a colleague (petsd!peora!srd) did:
>>
>>1. Removed VAX dependencies.
>>2. Changed the struct to separate arrays; saves mucho memory.
>>3. Did comparisons in unsigned, where possible.  (Faster on Perkin-Elmer.)
>>4. Sorted the character next chain and changed the search to stop
>>prematurely.  This saves a lot on the execution time when compressing.
>>
>>This version is totally compatible with the original version.  Even though
>>lint(1) -p has no complaints about compress.c, it won't run on a 16-bit
>>machine, due to the size of the arrays.
>>
>>Here is the README file from the original author:
>> 
>>>Well, with all this discussion about file compression (for news batching
>>>in particular) going around, I decided to implement the text compression
>>>algorithm described in the June Computer magazine.  The author claimed
>>>blinding speed and good compression ratios.  It's certainly faster than
>>>compact (but, then, what wouldn't be), but it's also the same speed as
>>>pack, and gets better compression than both of them.  On 350K bytes of
>>>unix-wizards, compact took about 8 minutes of CPU, pack took about 80
>>>seconds, and compress (herein) also took 80 seconds.  But, compact and
>>>pack got about 30% compression, whereas compress got over 50%.  So, I
>>>decided I had something, and that others might be interested, too.
>>>
>>>As is probably true of compact and pack (although I haven't checked),
>>>the byte order within a word is probably relevant here, but as long as
>>>you stay on a single machine type, you should be ok.  (Can anybody
>>>elucidate on this?)  There are a couple of asm's in the code (extv and
>>>insv instructions), so anyone porting it to another machine will have to
>>>deal with this anyway (and could probably make it compatible with Vax
>>>byte order at the same time).  Anyway, I've linted the code (both with
>>>and without -p), so it should run elsewhere.  Note the longs in the
>>>code, you can take these out if you reduce BITS to <= 15.
>>>
>>>Have fun, and as always, if you make good enhancements, or bug fixes,
>>>I'd like to see them.
>>>
>>>=Spencer (thomas@utah-20, {harpo,hplabs,arizona}!utah-cs!thomas)
>>
>>					regards,
>>					joe
>>
>>--
>>Full-Name:  Joseph M. Orost
>>UUCP:       ..!{decvax,ucbvax,ihnp4}!vax135!petsd!joe
>>US Mail:    MS 313; Perkin-Elmer; 106 Apple St; Tinton Falls, NJ 07724
>>Phone:      (201) 870-5844
SHAR_EOF
if test 8142 -ne "`wc -c < 'README3.0'`"
then
	echo shar: error transmitting "'README3.0'" '(should have been 8142 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'atob.c'" '(2505 characters)'
if test -f 'atob.c'
then
	echo shar: will not over-write existing file "'atob.c'"
else
sed 's/^X//' << \SHAR_EOF > 'atob.c'
/* atob: version 4.0
 * stream filter to change printable ascii from "btoa" back into 8 bit bytes
 * if bad chars, or Csums do not match: exit(1) [and NO output]
 *
 *  Paul Rutter		Joe Orost
 *  philabs!per		petsd!joe
 */

#include <stdio.h>

#define reg register

#define streq(s0, s1)  strcmp(s0, s1) == 0

#define times85(x)	((((((x<<2)+x)<<2)+x)<<2)+x)

long int Ceor = 0;
long int Csum = 0;
long int Crot = 0;
long int word = 0;
long int bcount = 0;

fatal() {
  fprintf(stderr, "bad format or Csum to atob\n");
  exit(1);
}

#define DE(c) ((c) - '!')

decode(c) 
  reg c;
{
  if (c == 'z') {
    if (bcount != 0) {
      fatal();
    } else {
      byteout(0);
      byteout(0);
      byteout(0);
      byteout(0);
    }
  } else if ((c >= '!') && (c < ('!' + 85))) {
    if (bcount == 0) {
      word = DE(c);
      ++bcount;
    } else if (bcount < 4) {
      word = times85(word);
      word += DE(c);
      ++bcount;
    } else {
      word = times85(word) + DE(c);
      byteout((int)((word >> 24) & 255));
      byteout((int)((word >> 16) & 255));
      byteout((int)((word >> 8) & 255));
      byteout((int)(word & 255));
      word = 0;
      bcount = 0;
    }
  } else {
    fatal();
  }
}

XFILE *tmp_file;

byteout(c) 
  reg c;
{
  Ceor ^= c;
  Csum += c;
  Csum += 1;
  if ((Crot & 0x80000000)) {
    Crot <<= 1;
    Crot += 1;
  } else {
    Crot <<= 1;
  }
  Crot += c;
  putc(c, tmp_file);
}

main(argc, argv) 
  char **argv;
{
  reg c;
  reg long int i;
  char tmp_name[100];
  char buf[100];
  long int n1, n2, oeor, osum, orot;

  if (argc != 1) {
    fprintf(stderr,"bad args to %s\n", argv[0]);
    exit(2);
  }
  sprintf(tmp_name, "/usr/tmp/atob.%x", getpid());
  tmp_file = fopen(tmp_name, "w+");
  if (tmp_file == NULL) {
    fatal();
  }
  unlink(tmp_name);	/* Make file disappear */
  /*search for header line*/
  for (;;) {
    if (fgets(buf, sizeof buf, stdin) == NULL) {
      fatal();
    }
    if (streq(buf, "xbtoa Begin\n")) {
      break;
    }
  }

  while ((c = getchar()) != EOF) {
    if (c == '\n') {
      continue;
    } else if (c == 'x') {
      break;
    } else {
      decode(c);
    }
  }
  if(scanf("btoa End N %ld %lx E %lx S %lx R %lx\n",
         &n1, &n2, &oeor, &osum, &orot) != 5) {
    fatal();
  }
  if ((n1 != n2) || (oeor != Ceor) || (osum != Csum) || (orot != Crot)) {
    fatal();
  } else {
    /*copy OK tmp file to stdout*/;
    fseek(tmp_file, 0L, 0);
    for (i = n1; --i >= 0;) {
      putchar(getc(tmp_file));
    }
  }
  exit(0);
}
SHAR_EOF
if test 2505 -ne "`wc -c < 'atob.c'`"
then
	echo shar: error transmitting "'atob.c'" '(should have been 2505 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'btoa.1'" '(2483 characters)'
if test -f 'btoa.1'
then
	echo shar: will not over-write existing file "'btoa.1'"
else
sed 's/^X//' << \SHAR_EOF > 'btoa.1'
X.TH BTOA 1 local
X.SH NAME
btoa, atob, tarmail, untarmail \- encode/decode binary to printable ASCII
X.SH SYNOPSIS
X.B btoa
X.br
X.B atob
X.br
X.B tarmail
who subject files ...
X.br
X.B untarmail
[ file ]
X.SH DESCRIPTION
X.I Btoa
is a filter that reads anything from the standard input, and encodes it into
printable ASCII on the standard output.  It also attaches a header and checksum
information used by the reverse filter 
X.I atob 
to find the start of the data and to check integrity.
X.PP
X.I Atob
reads an encoded file, strips off any leading and
trailing lines added by mailers, and recreates a copy of the original file
on the standard output.
X.I Atob 
gives NO output (and exits with an error message) if its input is garbage or 
the checksums do not check.
X.PP
X.I Tarmail
is a shell script that tar's up all the given files, pipes them 
through 
X.IR compress ","
X.IR btoa ","
and mails them to the given person with the given subject phrase.  For
example:
X.PP
X.in 1i
tarmail ralph "here it is ralph" foo.c a.out
X.in -1i
X.PP
Will package up files "foo.c" and "a.out" and mail them to "ralph" using
subject "here it is ralph".  Notice the quotes on the subject.  They are
necessary to make it one argument to the shell.
X.PP
X.I Tarmail 
with no args will print a short message reminding you what the required args 
are.  When the mail is received at the other end, that person should use
mail to save the message in some temporary file name (say "xx").
Then saying "untarmail xx"
will decode the message and untar it.  
X.I Untarmail 
can also be used as a filter.  By using 
X.IR tarmail ","
binary files and
entire directory structures can be easily transmitted between machines.
Naturally, you should understand what tar itself does before you use 
X.IR tarmail "."
X.PP
Other uses:
X.PP
compress < secrets | crypt | btoa | mail ralph
X.PP
will mail the encrypted contents of the file "secrets" to ralph.  If ralph
knows the encryption key, he can decode it by saving the mail (say in "xx"),
and then running:
X.PP
atob < xx | crypt | uncompress
X.PP
(crypt requests the key from the terminal,
and the "secrets" come out on the terminal).
X.SH AUTHOR
Paul Rutter (modified by Joe Orost)
X.SH FEATURES
X.I Btoa
uses a compact base-85 encoding so that
4 bytes are encoded into 5 characters (file is expanded by 25%).
As a special case, 32-bit zero is encoded as one character.  This encoding
produces less output than
X.IR uuencode "(1)."
X.SH "SEE ALSO"
compress(1), crypt(1), uuencode(1), mail(1)
SHAR_EOF
if test 2483 -ne "`wc -c < 'btoa.1'`"
then
	echo shar: error transmitting "'btoa.1'" '(should have been 2483 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'btoa.c'" '(2333 characters)'
if test -f 'btoa.c'
then
	echo shar: will not over-write existing file "'btoa.c'"
else
sed 's/^X//' << \SHAR_EOF > 'btoa.c'
/* btoa: version 4.0
 * stream filter to change 8 bit bytes into printable ascii
 * computes the number of bytes, and three kinds of simple checksums
 * incoming bytes are collected into 32-bit words, then printed in base 85
 *  exp(85,5) > exp(2,32)
 * the ASCII characters used are between '!' and 'u'
 * 'z' encodes 32-bit zero; 'x' is used to mark the end of encoded data.
 *
 *  Paul Rutter		Joe Orost
 *  philabs!per		petsd!joe
 *
 *  WARNING: this version is not compatible with the original as sent out
 *  on the net.  The original encoded from ' ' to 't'; which cause problems
 *  with some mailers (stripping off trailing blanks).
 */

#include <stdio.h>

#define reg register

#define MAXPERLINE 78

long int Ceor = 0;
long int Csum = 0;
long int Crot = 0;

long int ccount = 0;
long int bcount = 0;
long int word;

#define EN(c)	(int) ((c) + '!')

encode(c) 
  reg c;
{
  Ceor ^= c;
  Csum += c;
  Csum += 1;
  if ((Crot & 0x80000000)) {
    Crot <<= 1;
    Crot += 1;
  } else {
    Crot <<= 1;
  }
  Crot += c;

  word <<= 8;
  word |= c;
  if (bcount == 3) {
    wordout(word);
    bcount = 0;
  } else {
    bcount += 1;
  }
}

wordout(word) 
  reg long int word;
{
  if (word == 0) {
    charout('z');
  } else {
    reg int tmp = 0;
    
    if(word < 0) {	/* Because some don't support unsigned long */
      tmp = 32;
      word = word - (long)(85 * 85 * 85 * 85 * 32);
    }
    if(word < 0) {
      tmp = 64;
      word = word - (long)(85 * 85 * 85 * 85 * 32);
    }
    charout(EN((word / (long)(85 * 85 * 85 * 85)) + tmp));
    word %= (long)(85 * 85 * 85 * 85);
    charout(EN(word / (85 * 85 * 85)));
    word %= (85 * 85 * 85);
    charout(EN(word / (85 * 85)));
    word %= (85 * 85);
    charout(EN(word / 85));
    word %= 85;
    charout(EN(word));
  }
}

charout(c) {
  putchar(c);
  ccount += 1;
  if (ccount == MAXPERLINE) {
    putchar('\n');
    ccount = 0;
  }
}

main(argc,argv) 
  char **argv;
{
  reg c;
  reg long int n;

  if (argc != 1) {
    fprintf(stderr,"bad args to %s\n", argv[0]);
    exit(2);
  }
  printf("xbtoa Begin\n");
  n = 0;
  while ((c = getchar()) != EOF) {
    encode(c);
    n += 1;
  }
  while (bcount != 0) {
    encode(0);
  }
  /* n is written twice as crude cross check*/
  printf("\nxbtoa End N %ld %lx E %lx S %lx R %lx\n", n, n, Ceor, Csum, Crot);
  exit(0);
}
SHAR_EOF
if test 2333 -ne "`wc -c < 'btoa.c'`"
then
	echo shar: error transmitting "'btoa.c'" '(should have been 2333 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'compressdir'" '(302 characters)'
if test -f 'compressdir'
then
	echo shar: will not over-write existing file "'compressdir'"
else
sed 's/^X//' << \SHAR_EOF > 'compressdir'
OPTIONS=
XFILES=
for ARG
do
	case "$ARG" in
	-*)	OPTIONS="$OPTIONS $ARG";;
	*)	FILES="$FILES $ARG";;
	esac
done
if test -z "$FILES"; then
	FILES="."
fi
set $FILES
find $@ -type f -links 1 -exec test -r {} -a -s {} \; \
-exec expr '(' {} : '.*\.Z' ')' '=' 0 \; \
-exec compress $OPTIONS {} \; >/dev/null
SHAR_EOF
if test 302 -ne "`wc -c < 'compressdir'`"
then
	echo shar: error transmitting "'compressdir'" '(should have been 302 characters)'
fi
chmod +x 'compressdir'
fi # end of overwriting check
echo shar: extracting "'compressdir.1'" '(736 characters)'
if test -f 'compressdir.1'
then
	echo shar: will not over-write existing file "'compressdir.1'"
else
sed 's/^X//' << \SHAR_EOF > 'compressdir.1'
X.PU
X.TH COMPRESSDIR 1 local
X.SH NAME
compressdir, uncompressdir \-  compress and uncompress directories of files
X.SH SYNOPSIS
X.ll +8
X.B compressdir
[ flags ] [
X.I "directory \&..."
]
X.ll -8
X.br
X.B uncompressdir
[ flags ] [
X.I "directory \&..."
]
X.SH DESCRIPTION
Recursively decends each specified directory and compresses each
file.
Each file is replaced by a file with the extension
X.B "\&.Z,"
but only if the file got smaller.
If no directories are specified,
the compression is applied to all files starting with the current directory.
Compressed files can be restored to their original form by running
X.I uncompressdir
on the directories.
X.PP
The
X.I flags
specified are passed to the compress(1) program.
X.SH "SEE ALSO"
compress(1)
SHAR_EOF
if test 736 -ne "`wc -c < 'compressdir.1'`"
then
	echo shar: error transmitting "'compressdir.1'" '(should have been 736 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'tarmail'" '(303 characters)'
if test -f 'tarmail'
then
	echo shar: will not over-write existing file "'tarmail'"
else
sed 's/^X//' << \SHAR_EOF > 'tarmail'
if test $# -lt 3; then
  echo "Usage: tarmail mailpath \"subject-string\" directory-or-file(s)"
  exit
else
  mailpath=$1
  echo "mailpath = $mailpath"
  shift
  subject="$1"
  echo "subject-string = $subject"
  shift
  echo files = $*
  tar cvf - $* | compress | btoa | mail -s "$subject" $mailpath
fi
SHAR_EOF
if test 303 -ne "`wc -c < 'tarmail'`"
then
	echo shar: error transmitting "'tarmail'" '(should have been 303 characters)'
fi
chmod +x 'tarmail'
fi # end of overwriting check
echo shar: extracting "'uncompressdir'" '(290 characters)'
if test -f 'uncompressdir'
then
	echo shar: will not over-write existing file "'uncompressdir'"
else
sed 's/^X//' << \SHAR_EOF > 'uncompressdir'
OPTIONS=
XFILES=
for ARG
do
	case "$ARG" in
	-*)	OPTIONS="$OPTIONS $ARG";;
	*)	FILES="$FILES $ARG";;
	esac
done
if test -z "$FILES"; then
	FILES="."
fi
set $FILES
find $@ -type f -links 1 -exec test -r {} -a -s {} \; \
-exec expr {} : '.*\.Z' \; \
-exec uncompress $OPTIONS {} \; >/dev/null
SHAR_EOF
if test 290 -ne "`wc -c < 'uncompressdir'`"
then
	echo shar: error transmitting "'uncompressdir'" '(should have been 290 characters)'
fi
chmod +x 'uncompressdir'
fi # end of overwriting check
echo shar: extracting "'untarmail'" '(174 characters)'
if test -f 'untarmail'
then
	echo shar: will not over-write existing file "'untarmail'"
else
sed 's/^X//' << \SHAR_EOF > 'untarmail'
if test $# -ge 1; then
   atob < $1 | uncompress | tar xvpf -
   mv $1 /usr/tmp/$1.$$
   echo tarmail file moved to: /usr/tmp/$1.$$
else
   atob | uncompress | tar xvpf -
fi
SHAR_EOF
if test 174 -ne "`wc -c < 'untarmail'`"
then
	echo shar: error transmitting "'untarmail'" '(should have been 174 characters)'
fi
chmod +x 'untarmail'
fi # end of overwriting check
echo shar: extracting "'zcmp'" '(760 characters)'
if test -f 'zcmp'
then
	echo shar: will not over-write existing file "'zcmp'"
else
sed 's/^X//' << \SHAR_EOF > 'zcmp'

OPTIONS=
XFILES=
for ARG
do
	case "$ARG" in
	-*)	OPTIONS="$OPTIONS $ARG";;
	*)	FILES="$FILES $ARG";;
	esac
done
if test -z "$FILES"; then
	echo "Usage: zcmp [cmp_options] file [file]"
	exit 1
fi
set $FILES
if test $# -eq 1; then
	FILE=`expr $1 : '\(.*\)\.Z' '|' $1`
	zcat $FILE | cmp $OPTIONS - $FILE
	STAT="$?"
elif test $# -eq 2; then
	case "$1" in
	*.Z)	case "$2" in
		*.Z)	F=`basename $2 .Z`
			zcat $2 > /tmp/$F.$$
			zcat $1 | cmp $OPTIONS - /tmp/$F.$$
			STAT="$?";;
		*)	zcat $1 | cmp $OPTIONS - $2;;
		esac;;
	*)	case "$2" in
		*.Z)	F=`basename $2 .Z`
			zcat $2 > /tmp/$F.$$
			cmp $OPTIONS $1 /tmp/$F.$$
			STAT="$?";;
		*)	cmp $OPTIONS $1 $2
			STAT="$?";;
		esac;;
	esac
	exit "$STAT"
else
	echo "Usage: zcmp [cmp_options] file [file]"
	exit 1
fi
SHAR_EOF
if test 760 -ne "`wc -c < 'zcmp'`"
then
	echo shar: error transmitting "'zcmp'" '(should have been 760 characters)'
fi
chmod +x 'zcmp'
fi # end of overwriting check
echo shar: extracting "'zcmp.1'" '(797 characters)'
if test -f 'zcmp.1'
then
	echo shar: will not over-write existing file "'zcmp.1'"
else
sed 's/^X//' << \SHAR_EOF > 'zcmp.1'
X.TH ZCMP 1
X.SH NAME
zcmp, zdiff \- compare compressed files
X.SH SYNOPSIS
X.B zcmp
[ cmp_options ] file1
[ file2 ]
X.br
X.B zdiff
[ diff_options ] file1
[ file2 ]
X.SH DESCRIPTION
X.I  Zcmp
and 
X.I zdiff
are used to invoke the
X.I cmp
or the
X.I diff
program on compressed files.  All options specified are passed directly to
X.I cmp
or
X.IR diff "."
If only 1 file is specified, then the files compared are
X.I file1
and an uncompressed
X.IR file1 ".Z."
If two files are specified, then they are uncompressed (if ending with ".Z")
and fed to
X.I cmp
or
X.IR diff "."
The exit status from 
X.I cmp
or
X.I diff
is preserved.
X.SH "SEE ALSO"
cmp(1), diff(1), zmore(1), zcat(1), compress(1), uncompress(1)
X.SH BUGS
Messages from the
X.I cmp
or
X.I diff
programs refer to temporary filenames instead of those specified.
SHAR_EOF
if test 797 -ne "`wc -c < 'zcmp.1'`"
then
	echo shar: error transmitting "'zcmp.1'" '(should have been 797 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'zdiff'" '(724 characters)'
if test -f 'zdiff'
then
	echo shar: will not over-write existing file "'zdiff'"
else
sed 's/^X//' << \SHAR_EOF > 'zdiff'

OPTIONS=
XFILES=
for ARG
do
	case "$ARG" in
	-*)	OPTIONS="$OPTIONS $ARG";;
	*)	FILES="$FILES $ARG";;
	esac
done
if test -z "$FILES"; then
	echo "Usage: zdiff [diff_options] file [file]"
	exit 1
fi
set $FILES
if test $# -eq 1; then
	FILE=`expr $1 : '\(.*\)\.Z' '|' $1`
	zcat $FILE | diff $OPTIONS - $FILE
	STAT="$?"
elif test $# -eq 2; then
	case "$1" in
	*.Z)	case "$2" in
		*.Z)	F=`basename $2 .Z`
			zcat $2 > /tmp/$F.$$
			zcat $1 | diff $OPTIONS - /tmp/$F.$$
			STAT="$?";;
		*)	zcat $1 | diff $OPTIONS - $2;;
		esac;;
	*)	case "$2" in
		*.Z)	zcat $2 | diff $OPTIONS $1 -
			STAT="$?";;
		*)	diff $OPTIONS $1 $2
			STAT="$?";;
		esac;;
	esac
	exit "$STAT"
else
	echo "Usage: zdiff [diff_options] file [file]"
	exit 1
fi
SHAR_EOF
if test 724 -ne "`wc -c < 'zdiff'`"
then
	echo shar: error transmitting "'zdiff'" '(should have been 724 characters)'
fi
chmod +x 'zdiff'
fi # end of overwriting check
echo shar: extracting "'zmore'" '(306 characters)'
if test -f 'zmore'
then
	echo shar: will not over-write existing file "'zmore'"
else
sed 's/^X//' << \SHAR_EOF > 'zmore'
XFIRST=1
for FILE
do
	if test $FIRST -eq 0; then
		echo "--More--(Next file: $FILE)\c"
		stty cbreak -echo
		ANS=`dd bs=1 count=1 2>/dev/null` 
		stty -cbreak echo
		echo " "
		if test "$ANS" = 'e'; then
			exit
		fi
	fi
	echo "------> $FILE <------"
	zcat $FILE | more
	if test -t; then
		FIRST=0
	fi
done
SHAR_EOF
if test 306 -ne "`wc -c < 'zmore'`"
then
	echo shar: error transmitting "'zmore'" '(should have been 306 characters)'
fi
chmod +x 'zmore'
fi # end of overwriting check
echo shar: extracting "'zmore.1'" '(3702 characters)'
if test -f 'zmore.1'
then
	echo shar: will not over-write existing file "'zmore.1'"
else
sed 's/^X//' << \SHAR_EOF > 'zmore.1'
X.TH ZMORE 1
X.SH NAME
zmore \- file perusal filter for crt viewing of compressed text
X.SH SYNOPSIS
X.B zmore
[ name ...  ]
X.SH DESCRIPTION
X.I  Zmore
is a filter which allows examination of compressed text files
one screenful at a time on a soft-copy terminal.
It normally pauses after each screenful, printing --More--
at the bottom of the screen.
If the user then types a carriage return, one more line is displayed.
If the user hits a space,
another screenful is displayed.  Other possibilites are enumerated later.
X.PP
X.I Zmore
looks in the file
X.I /etc/termcap
to determine terminal characteristics,
and to determine the default window size.
On a terminal capable of displaying 24 lines,
the default window size is 22 lines.
X.PP
Other sequences which may be typed when
X.I zmore
pauses, and their effects, are as follows (\fIi\fP is an optional integer
argument, defaulting to 1) :
X.PP
X.IP \fIi\|\fP<space>
display
X.I i
more lines, (or another screenful if no argument is given)
X.PP
X.IP ^D
display 11 more lines (a ``scroll'').
If
X.I i
is given, then the scroll size is set to \fIi\|\fP.
X.PP
X.IP d
same as ^D (control-D)
X.PP
X.IP \fIi\|\fPz
same as typing a space except that \fIi\|\fP, if present, becomes the new
window size.  Note that the window size reverts back to the default at the
end of the current file.
X.PP
X.IP \fIi\|\fPs
skip \fIi\|\fP lines and print a screenful of lines
X.PP
X.IP \fIi\|\fPf
skip \fIi\fP screenfuls and print a screenful of lines
X.PP
X.IP "q or Q"
quit reading the current file; go on to the next (if any)
X.PP
X.IP e
When the prompt --More--(Next file: 
X.IR file )
is printed, this command causes zmore to exit.
X.PP 
X.IP =
Display the current line number.
X.PP
X.IP \fIi\|\fP/expr
search for the \fIi\|\fP-th occurrence of the regular expression \fIexpr.\fP
If the pattern is not found,
X.I zmore
goes on to the next file (if any).
Otherwise, a screenful is displayed, starting two lines before the place
where the expression was found.
The user's erase and kill characters may be used to edit the regular
expression.
Erasing back past the first column cancels the search command.
X.PP
X.IP \fIi\|\fPn
search for the \fIi\|\fP-th occurrence of the last regular expression entered.
X.PP
X.IP !command
invoke a shell with \fIcommand\|\fP. 
The character `!' in "command" are replaced with the
the previous shell command.  The sequence "\\!" is replaced by "!".
X.PP
X.IP ":q or :Q"
quit reading the current file; go on to the next (if any)
(same as q or Q).
X.PP
X.IP .
(dot) repeat the previous command.
X.PP
The commands take effect immediately, i.e., it is not necessary to
type a carriage return.
Up to the time when the command character itself is given,
the user may hit the line kill character to cancel the numerical
argument being formed.
In addition, the user may hit the erase character to redisplay the
--More-- message.
X.PP
At any time when output is being sent to the terminal, the user can
hit the quit key (normally control\-\\).
X.I Zmore
will stop sending output, and will display the usual --More--
prompt.
The user may then enter one of the above commands in the normal manner.
Unfortunately, some output is lost when this is done, due to the
fact that any characters waiting in the terminal's output queue
are flushed when the quit signal occurs.
X.PP
The terminal is set to
X.I noecho
mode by this program so that the output can be continuous.
What you type will thus not show on your terminal, except for the / and !
commands.
X.PP
If the standard output is not a teletype, then
X.I zmore
acts just like
X.I zcat,
except that a header is printed before each file.
X.SH FILES
X.DT
/etc/termcap		Terminal data base
X.SH "SEE ALSO"
more(1), zcat(1), compress(1), uncompress(1)
SHAR_EOF
if test 3702 -ne "`wc -c < 'zmore.1'`"
then
	echo shar: error transmitting "'zmore.1'" '(should have been 3702 characters)'
fi
fi # end of overwriting check
#	End of shell archive
exit 0