[alt.sources] UUD/UUE

ralph@laas.fr (Ralph P. Sobek) (04/13/91)

Submitted-by: ralph@orion.laas.fr
Archive-name: uux/part01

I have been enjoying the manual uudecoding of these files ;-(

So herewith I post a better version.  UUE can automatically encode and
split a file into n parts.  It also provides for better error-checking
and it includes an ASCII table in case the message might traverse
certain BITNET sites.  UUD can automatically decode multipart files
created by UUE.

UUD/UUE compile on Unix, VAX, MSDOS, and GEMDOS.  Updates and comments
are appreciated.


#!/bin/sh
# This is uux, a shell archive (shar 3.32)
# made 04/13/1991 13:24 UTC by ralph@orion
#
# existing files will NOT be overwritten
#
# This shar contains:
# length  mode       name
# ------ ---------- ------------------------------------------
#  11741 -rw-r--r-- uud.c
#   4186 -rw-r--r-- uue.c
#   7035 -rw-r--r-- uux.doc
#
if touch 2>&1 | fgrep 'amc' > /dev/null
 then TOUCH=touch
 else TOUCH=true
fi
# ============= uud.c ==============
if test X"$1" != X"-c" -a -f 'uud.c'; then
	echo "File already exists: skipping 'uud.c'"
else
echo "x - extracting uud.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > uud.c &&
X/*
X * Uud -- decode a uuencoded file back to binary form.
X *
X * From the Berkeley original, modified by MSD, RDR, JPHD & WLS.
X * The Atari GEMDOS version compiled with MWC 2.x.
X * The MSDOS version with TurboC.
X * The Unix version with cc.
X * this version is made: 25 Nov 1988.
X */
X
X/*
X * Be sure to have the proper symbol at this point. (GEMDOS, MSDOS, UNIX...)
X */
X/*
X#ifndef GEMDOS
X#define GEMDOS 1
X#endif
X */
X#ifndef UNIX
X#define UNIX 1
X#endif
X/*
X#ifndef MSDOS
X#define MSDOS 1
X#endif
X */
X
X#ifdef GEMDOS
X#define SYSNAME "gemdos"
X#define SMALL 1
X#endif
X#ifdef MSDOS
X#define SYSNAME "msdos"
X#define SMALL 1
X#endif
X#ifdef UNIX
X#define SYSNAME "unix"
X#endif
X
X#include <stdio.h>
X
X#ifdef GEMDOS
X#include <osbind.h>
X#define Error(n)  { Bconin(2); exit(n); }
X#define WRITE	  "wb"
X#else
X#define Error(n)  exit(n)
X#define WRITE	  "w"
X#endif
X
X#define loop	while (1)
X
Xextern FILE *fopen();
Xextern char *strcpy();
Xextern char *strcat();
X
Xchar *getnword();
X
X#define MAXCHAR 256
X#define LINELEN 256
X#define FILELEN 64
X#define NORMLEN 60	/* allows for 80 encoded chars per line */
X
X#define SEQMAX 'z'
X#define SEQMIN 'a'
Xchar seqc;
Xint first, secnd, check, numl;
X
XFILE *in, *out;
Xchar *pos;
Xchar ifname[FILELEN], ofname[FILELEN];
Xchar *source = NULL, *target = NULL;
Xchar blank, part = '\0';
Xint partn, lens;
Xint debug = 0, nochk = 0, onedone = 0;
Xint chtbl[MAXCHAR], cdlen[NORMLEN + 3];
X
Xmain(argc, argv) int argc; char *argv[];
X{
X	int mode;
X	register int i, j;
X	char *curarg;
X	char dest[FILELEN], buf[LINELEN];
X
X	if (argc < 2) {
X		format("Almost foolproof uudecode v3.4 (%s) 25-Nov-88\n",
X			SYSNAME);
X		format("\n");
X		format("Usage: uud [-n] [-d] [-s dir] [-t dir] input-file\n");
X		format("\n");
X		format("Option: -n -> No line sequence check\n");
X		format("Option: -d -> Debug/verbose mode\n");
X		format("Option: -s + Source directory for all input files\n");
X		format("  (MUST be terminated by directory separator)\n");
X		format("Option: -t + Target directory for all output files\n");
X		format("  (MUST be terminated by directory separator)\n");
X		format("If input-file is - then stdin is used as input-file\n");
X		Error(1);
X	}
X
X	curarg = argv[1];
X	
X	while (curarg[0] == '-') {
X		if (((curarg[1] == 'd') || (curarg[1] == 'D')) &&
X		    (curarg[2] == '\0')) {
X			debug = 1;
X		} else if (((curarg[1] == 'n') || (curarg[1] == 'N')) &&
X			   (curarg[2] == '\0')) {
X			nochk = 1;
X		} else if (((curarg[1] == 't') || (curarg[1] == 'T')) &&
X			   (curarg[2] == '\0')) {
X			argv++;
X			argc--;
X			if (argc < 2) {
X				format("uud: Missing target directory.\n");
X				Error(15);
X			}
X			target = argv[1];
X			if (debug)
X				format("Target dir = %s\n",target);
X		} else if (((curarg[1] == 's') || (curarg[1] == 'S')) &&
X			   (curarg[2] == '\0')) {
X			argv++;
X			argc--;
X			if (argc < 2) {
X				format("uud: Missing source directory.\n");
X				Error(15);
X			}
X			source = argv[1];
X			if (debug)
X				format("Source dir = %s\n",source);
X		} else if (curarg[1] != '\0') {
X			format("uud: Unknown option <%s>\n", curarg);
X			Error(15);
X		} else
X			break;
X		argv++;
X		argc--;
X		if (argc < 2) {
X			format("uud: Missing file name.\n");
X			Error(15);
X		}
X		curarg = argv[1];
X	}
X
X	if ((curarg[0] == '-') && (curarg[1] == '\0')) {
X		in = stdin;
X		strcpy(ifname, "<stdin>");
X	} else {
X		if (source != NULL) {
X			strcpy(ifname, source);
X			strcat(ifname, curarg);
X		} else
X			strcpy(ifname, curarg);
X		if ((in = fopen(ifname, "r")) == NULL) {
X			format("uud: Can't open %s\n", ifname);
X			Error(2);
X		}
X		numl = 0;
X	}
X
X/*
X * Set up the default translation table.
X */
X	for (i = 0; i < ' '; i++) chtbl[i] = -1;
X	for (i = ' ', j = 0; i < ' ' + 64; i++, j++) chtbl[i] = j;
X	for (i = ' ' + 64; i < MAXCHAR; i++) chtbl[i] = -1;
X	chtbl['`'] = chtbl[' '];	/* common mutation */
X	chtbl['~'] = chtbl['^'];	/* an other common mutation */
X	blank = ' ';
X/*
X * set up the line length table, to avoid computing lotsa * and / ...
X */
X	cdlen[0] = 1;
X	for (i = 1, j = 5; i <= NORMLEN; i += 3, j += 4)
X		cdlen[i] = (cdlen[i + 1] = (cdlen[i + 2] = j));
X/*
X * search for header or translation table line.
X */
X	loop {	/* master loop for multiple decodes in one file */
X		partn = 'a';
X		loop {
X			if (fgets(buf, sizeof buf, in) == NULL) {
X				if (onedone) {
X					if (debug) format("End of file.\n");
X					exit(0);
X				} else {
X					format("uud: No begin line.\n");
X					Error(3);
X				}
X			}
X			numl++;
X			if (strncmp(buf, "table", 5) == 0) {
X				gettable();
X				continue;
X			}
X			if (strncmp(buf, "begin", 5) == 0) {
X				break;
X			}
X		}
X		lens = strlen(buf);
X		if (lens) buf[--lens] = '\0';
X#ifdef SMALL
X		if ((pos = getnword(buf, 3))) {
X			strcpy(dest, pos);
X		} else
X#else
X		if(sscanf(buf,"begin%o%s", &mode, dest) != 2)
X#endif
X		{
X			format("uud: Missing filename in begin line.\n");
X			Error(10);
X		}
X
X		if (target != NULL) {
X			strcpy(ofname, target);
X			strcat(ofname, dest);
X		} else
X			strcpy(ofname, dest);
X
X		if((out = fopen(ofname, WRITE)) == NULL) {
X			format("uud: Cannot open output file: %s\n", ofname);
X			Error(4);
X		}
X		if (debug) format("Begin uudecoding: %s\n", ofname);
X		seqc = SEQMAX;
X		check = nochk ? 0 : 1;
X		first = 1;
X		secnd = 0;
X		decode();
X		fclose(out);
X#ifdef UNIX
X		chmod(ofname, mode);
X#endif
X		onedone = 1;
X		if (debug) format("End uudecoding: %s\n", ofname);
X	}	/* master loop for multiple decodes in one file */
X}
X
X/*
X * Bring back a pointer to the start of the nth word.
X */
Xchar *getnword(str, n) register char *str; register int n;
X{
X	while((*str == '\t') || (*str == ' ')) str++;
X	if (! *str) return NULL;
X	while(--n) {
X		while ((*str != '\t') && (*str != ' ') && (*str)) str++;
X		if (! *str) return NULL;
X		while((*str == '\t') || (*str == ' ')) str++;
X		if (! *str) return NULL;
X	}
X	return str;
X}
X
X/*
X * Install the table in memory for later use.
X */
Xgettable()
X{
X	char buf[LINELEN];
X	register int c, n = 0;
X	register char *cpt;
X
X	for (c = 0; c <= MAXCHAR; c++) chtbl[c] = -1;
X
Xagain:	if (fgets(buf, sizeof buf, in) == NULL) {
X		format("uud: EOF while in translation table.\n");
X		Error(5);
X	}
X	numl++;
X	if (strncmp(buf, "begin", 5) == 0) {
X		format("uud: Incomplete translation table.\n");
X		Error(6);
X	}
X	cpt = buf + strlen(buf) - 1;
X	*cpt = ' ';
X	while (*(cpt) == ' ') {
X		*cpt = 0;
X		cpt--;
X	}
X	cpt = buf;
X	while (c = *cpt) {
X		if (chtbl[c] != -1) {
X			format("uud: Duplicate char in translation table.\n");
X			Error(7);
X		}
X		if (n == 0) blank = c;
X		chtbl[c] = n++;
X		if (n >= 64) return;
X		cpt++;
X	}
X	goto again;
X}
X
X/*
X * copy from in to out, decoding as you go along.
X */
X
Xdecode()
X{
X	char buf[LINELEN], outl[LINELEN];
X	register char *bp, *ut;
X	register int *trtbl = chtbl;
X	register int n, c, rlen;
X	register unsigned int len;
X
X	loop {
X		if (fgets(buf, sizeof buf, in) == NULL) {
X			format("uud: EOF before end.\n");
X			fclose(out);
X			Error(8);
X		}
X		numl++;
X		len = strlen(buf);
X		if (len) buf[--len] = '\0';
X/*
X * Is it an unprotected empty line before the end line ?
X */
X		if (len == 0) continue;
X/*
X * Get the binary line length.
X */
X		n = trtbl[*buf];
X		if (n >= 0) goto decod;
X/*
X * end of uuencoded file ?
X */
X		if (strncmp(buf, "end", 3) == 0) return;
X/*
X * end of current file ? : get next one.
X */
X		if (strncmp(buf, "include", 7) == 0) {
X			getfile(buf);
X			continue;
X		}
X		format("uud: Bad prefix line %d in file: %s\n",numl, ifname);
X		if (debug) format("Bad line =%s\n",buf);
X		Error(11);
X/*
X * Sequence checking ?
X */
Xdecod:		rlen = cdlen[n];
X/*
X * Is it the empty line before the end line ?
X */
X		if (n == 0) continue;
X/*
X * Pad with blanks.
X */
X		for (bp = &buf[c = len];
X			c < rlen; c++, bp++) *bp = blank;
X/*
X * Verify if asked for.
X */
X		if (debug) {
X			for (len = 0, bp = buf; len < rlen; len++) {
X				if (trtbl[*bp] < 0) {
X					format(
X	"Non uuencoded char <%c>, line %d in file: %s\n", *bp, numl, ifname);
X					format("Bad line =%s\n",buf);
X					Error(16);
X				}
X				bp++;
X			}
X		}
X/*
X * All this just to check for uuencodes that append a 'z' to each line....
X */
X		if (secnd && check) {
X			secnd = 0;
X			if (buf[rlen] == SEQMAX) {
X				check = 0;
X				if (debug) format("Sequence check turned off (2).\n");
X			} else
X				if (debug) format("Sequence check on (2).\n");
X		} else if (first && check) {
X			first = 0;
X			secnd = 1;
X			if (buf[rlen] != SEQMAX) {
X				check = 0;
X				if (debug) format("No sequence check (1).\n");
X			} else
X				if (debug) format("Sequence check on (1).\n");
X		}
X/*
X * There we check.
X */
X		if (check) {
X			if (buf[rlen] != seqc) {
X				format("uud: Wrong sequence line %d in %s\n",
X					numl, ifname);
X				if (debug)
X					format(
X	"Sequence char is <%c> instead of <%c>.\n", buf[rlen], seqc);
X				Error(18);
X			}
X			seqc--;
X			if (seqc < SEQMIN) seqc = SEQMAX;
X		}
X/*
X * output a group of 3 bytes (4 input characters).
X * the input chars are pointed to by p, they are to
X * be output to file f.n is used to tell us not to
X * output all of them at the end of the file.
X */
X		ut = outl;
X		len = n;
X		bp = &buf[1];
X		while (n > 0) {
X			*(ut++) = trtbl[*bp] << 2 | trtbl[bp[1]] >> 4;
X			n--;
X			if (n) {
X				*(ut++) = (trtbl[bp[1]] << 4) |
X					  (trtbl[bp[2]] >> 2);
X				n--;
X			}
X			if (n) {
X				*(ut++) = trtbl[bp[2]] << 6 | trtbl[bp[3]];
X				n--;
X			}
X			bp += 4;
X		}
X		if ((n = fwrite(outl, 1, len, out)) <= 0) {
X			format("uud: Error on writing decoded file.\n");
X			Error(18);
X		}
X	}
X}
X
X/*
X * Find the next needed file, if existing, otherwise try further
X * on next file.
X */
Xgetfile(buf) register char *buf;
X{
X	if ((pos = getnword(buf, 2)) == NULL) {
X		format("uud: Missing include file name.\n");
X		Error(17);
X	} else
X		if (source != NULL) {
X			strcpy(ifname, source);
X			strcat(ifname, pos);
X		} else
X			strcpy(ifname, pos);
X#ifdef GEMDOS
X	if (Fattrib(ifname, 0, 0) < 0)
X#else
X	if (access(ifname, 04))
X#endif
X	{
X		if (debug) {
X			format("Cant find: %s\n", ifname);
X			format("Continuing to read same file.\n");
X		}
X	}
X	else {
X		if (freopen(ifname, "r", in) == in) {
X			numl = 0;
X			if (debug) 
X				format("Reading next section from: %s\n", ifname);
X		} else {
X			format("uud: Freopen abort: %s\n", ifname);
X			Error(9);
X		}
X	}
X	loop {
X		if (fgets(buf, LINELEN, in) == NULL) {
X			format("uud: No begin line after include: %s\n", ifname);
X			Error(12);
X		}
X		numl++;
X		if (strncmp(buf, "table", 5) == 0) {
X			gettable();
X			continue;
X		}
X		if (strncmp(buf, "begin", 5) == 0) break;
X	}
X	lens = strlen(buf);
X	if (lens) buf[--lens] = '\0';
X/*
X * Check the part suffix.
X */
X	if ((pos = getnword(buf, 3)) == NULL ) {
X		format("uud: Missing part name, in included file: %s\n", ifname);
X		Error(13);
X	} else {
X		part = *pos;
X		partn++;
X		if (partn > 'z') partn = 'a';
X		if (part != partn) {
X			format("uud: Part suffix mismatch: <%c> instead of <%c>.\n",
X				part, partn);
X			Error(14);
X		}
X		if (debug) format("Reading part %c\n", *pos);
X	}
X}
X
X/*
X * Printf style formatting. (Borrowed from MicroEmacs by Dave Conroy.) 
X * A lot smaller than the full fledged printf.
X */
X/* VARARGS1 */
Xformat(fp, args) char *fp;
X{
X	doprnt(fp, (char *)&args);
X}
X
Xdoprnt(fp, ap)
Xregister char	*fp;
Xregister char	*ap;
X{
X	register int	c, k;
X	register char	*s;
X
X	while ((c = *fp++) != '\0') {
X		if (c != '%')
X			outc(c);
X		else {
X			c = *fp++;
X			switch (c) {
X			case 'd':
X				puti(*(int *)ap, 10);
X				ap += sizeof(int);
X				break;
X
X			case 's':
X				s = *(char **)ap;
X				while ((k = *s++) != '\0')
X					outc(k);
X				ap += sizeof(char *);
X				break;
X
X			case 'c':
X				outc(*(int *)ap);
X				ap += sizeof(int);
X				break;
X
X			default:
X				outc(c);
X			}
X		}
X	}
X}
X
X/*
X * Put integer, in radix "r".
X */
Xputi(i, r)
Xregister unsigned int	i;
Xregister unsigned int	r;
X{
X	register unsigned int	q, s;
X
X	if ((q = i / r) != 0)
X		puti(q, r);
X	s = i % r;
X	if (s <= 9)
X		outc(s + '0');
X	else
X		outc(s - 10 + 'A');
X}
Xoutc(c) register char c;
X{
X#ifdef GEMDOS
X	if (c == '\n') Bconout(2, '\r');
X	Bconout(2, c);
X#else
X	putchar(c);
X#endif
X}
SHAR_EOF
$TOUCH -am 0113121589 uud.c &&
chmod 0644 uud.c ||
echo "restore of uud.c failed"
set `wc -c uud.c`;Wc_c=$1
if test "$Wc_c" != "11741"; then
	echo original size 11741, current size $Wc_c
fi
fi
# ============= uue.c ==============
if test X"$1" != X"-c" -a -f 'uue.c'; then
	echo "File already exists: skipping 'uue.c'"
else
echo "x - extracting uue.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > uue.c &&
X/*
X *
X * Uue -- encode a file so that it's printable ascii, short lines
X *
X * Slightly modified from a version posted to net.sources a while back,
X * and suitable for compilation on the IBM PC
X *
X * modified for Lattice C on the ST - 11.05.85 by MSD
X * modified for ALCYON on the ST -    10-24-86 by RDR
X * modified a little more for MWC...  02/09/87 by JPHD
X * (An optional first argument of the form: -nnumber (e.g. -500), will
X * produce a serie of files that long, linked by the include statement,
X * such files are automatically uudecoded by the companion program.)
X * More mods, - ...		   05/06/87 by jphd
X * Mods for TOPS 20, and more.     08/06/87 by jphd
X *     (remove freopen and rindex...change filename generation...)
X * (A lot more to do about I/O speed, avoiding completely the stdio.h...)
X *
X */
X
X
X#include <stdio.h>
X#include <ctype.h>
X
X#define USAGE 
X
X/* ENC is the basic 1 character encoding function to make a char printing */
X#define ENC(c) (((c) & 077) + ' ')
X
Xextern FILE  *fopen();
XFILE *fp, *outp;
Xchar ofname[80];
Xint lenofname;
Xint stdo = 0;
X
X#ifdef ST
X#define READ "rb"
X#else
X#define READ "r"
X#endif
X
Xint part = 'a', chap = 'a';
X#define SEQMAX 'z'
X#define SEQMIN 'a'
Xchar seqc = SEQMAX;
X
Xint split = 0; fileln = 32000;
X
Xmain(argc, argv)
Xint argc; char *argv[];
X{
X	char *fname;
X
X	if (argc < 2) {
X		fprintf(stderr, "Almost foolproof uuencode v3.1 06 Aug 1987\n");
X		fprintf(stderr, "Usage: uue [-n] inputfile [-]\n");
X		exit(2);
X		}
X	if (argv[1][0] == '-') {
X		fileln = -atoi(argv[1]);
X		if (fileln <= 0) {
X			fprintf(stderr, "Wrong file length arg.\n");
X			exit();
X		}
X		split = 1;
X		argv++;
X		argc--;
X	}
X	if ((fp=fopen(argv[1], READ))==NULL) {  /* binary input !!! */
X		fprintf(stderr,"Cannot open %s\n",argv[1]);
X		exit(1);
X	}
X	strcpy(ofname, argv[1]);
X	fname = ofname;
X	do {
X		if (*fname == '.')
X			*fname = '\0';
X	} while (*fname++);
X		/* 8 char prefix + .uue -> 12 chars MAX */
X	lenofname = strlen(ofname);
X	if (lenofname > 8) ofname[8] = '\0';
X	strcat(ofname,".uue");
X	lenofname = strlen(ofname);
X	if (!split && (argc > 2) && (argv[2][0] == '-')) {
X		stdo = 1;
X		outp = stdout;
X	 } else {
X		 makename();
X		 if((outp = fopen(ofname, "w")) == NULL) {
X			 fprintf(stderr,"Cannot open %s\n", ofname);
X			 exit(1);
X			 }
X	}
X	maketable();
X	fprintf(outp,"begin %o %s\n", 0644, argv[1]);
X	encode();
X	fprintf(outp,"end\n");
X	fclose(outp);
X	exit(0);
X}
X
X/* create ASCII table so a mailer can screw it up and the decode
X * program can restore the error.
X */
Xmaketable()
X{
X	register int i, j;
X
X	fputs("table\n", outp);
X	for(i = ' ', j = 0; i < '`' ; j++) {
X		if (j == 32)
X			putc('\n', outp);
X		fputc(i++, outp);
X	}
X	putc('\n', outp);
X}
X
X/*
X * Generate the names needed for single and multiple part encoding.
X */
Xmakename()
X{
X	if (split) {
X		ofname[lenofname - 1] = part;
X		ofname[lenofname - 2] = chap;
X	}
X}
X
X/*
X * copy from in to out, encoding as you go along.
X */
Xencode()
X{
X	char buf[80];
X	register int i, n;
X	register int lines;
X	lines = 6;
X
X	for (;;) {
X		n = fr(buf, 45);
X		putc(ENC(n), outp);
X		for (i = 0; i < n; i += 3)
X		      outdec(&buf[i]);
X		putc(seqc, outp);
X		seqc--;
X		if (seqc < SEQMIN) seqc = SEQMAX;
X		putc('\n', outp);
X		++lines;
X		if (split && (lines > fileln)) {
X			part++;
X			if (part > 'z') {
X				part = 'a';
X				if (chap == 'z')
X					chap = 'a'; /* loop ... */
X				else
X					chap++;
X			}
X			makename();
X			fprintf(outp,"include %s\n",ofname);
X			fclose(outp);
X			if((outp = fopen(ofname, "w")) == NULL) {
X				fprintf(stderr,"Cannot open %s\n",ofname);
X				exit(1);
X			}
X			maketable();
X			fprintf(outp,"begin part %c %s\n",part,ofname);
X			lines = 6;
X		}
X		if (n <= 0)
X			break;
X	}
X}
X
X/*
X * output one group of 3 bytes, pointed at by p, on file f.
X */
Xoutdec(p)
Xregister char *p;
X{
X	register int c1, c2, c3, c4;
X
X	c1 = *p >> 2;
X	c2 = (*p << 4) & 060 | (p[1] >> 4) & 017;
X	c3 = (p[1] << 2) & 074 | (p[2] >> 6) & 03;
X	c4 = p[2] & 077;
X	putc(ENC(c1), outp);
X	putc(ENC(c2), outp);
X	putc(ENC(c3), outp);
X	putc(ENC(c4), outp);
X}
X
X/* fr: like read but stdio */
Xint fr(buf, cnt)
Xregister char *buf;
Xregister int cnt;
X{
X	register int c, i;
X	for (i = 0; i < cnt; i++) {
X		c = fgetc(fp);
X		if (feof(fp))
X			return(i);
X		buf[i] = c;
X	}
X	return (cnt);
X}
SHAR_EOF
$TOUCH -am 0113121789 uue.c &&
chmod 0644 uue.c ||
echo "restore of uue.c failed"
set `wc -c uue.c`;Wc_c=$1
if test "$Wc_c" != "4186"; then
	echo original size 4186, current size $Wc_c
fi
fi
# ============= uux.doc ==============
if test X"$1" != X"-c" -a -f 'uux.doc'; then
	echo "File already exists: skipping 'uux.doc'"
else
echo "x - extracting uux.doc (Text)"
sed 's/^X//' << 'SHAR_EOF' > uux.doc &&
X
X			*** UUE ***
X
Xuue filename
Xuue -n filename
Xuue filename -
X
XIf given no args, uue will tells you what version is this, and the usage.
XThe filename arg will be uuencoded.
Xthe -n option will yield several files, each n lines long.
Xuue -500 niceprog.ttp will give:
Xniceprog.uaa niceprog.uab ... niceprog.uaz (!!! that would be a lot),
Xeach (except the last) will be 500 lines long.
XIf given, the final - character (not valid if -n is present) will send
Xthe output to stdout rather than a disk file.
XThe filenames synthetized by uue will be at most 8 chars + .uue (or .uxx)
Xto be in the accepted pattern for GEMDOS, MS/DOS, UN*X and TOPS20.
X================================================================================
X
XThis is the v3.3 19-Apr-88 version of uud.ttp (and v3.1 of uue.ttp too)
XIt is named uud instead of uudecode, to avoid confusion between different
Ximplementations of the uudecoding functionnality.
XIdem for uue.
X
XThese versions have the following capabilities:
X1- Missing trailing blanks are still OK. (I am on EARN/BITNET ...)
X   Absolutely no need for any procedure to restore 61 chars a line...
X2- **Some** common internetwork transpositions are OK (e.g. 
X   tilde instead of circonflex...but not coma instead of circonflex!) 
X   (I am still on EARN/BITNET)
X   No need to edit the file to change chars...
X   Note: I have been told that the substitution of blanks by grave
X   accent is not a gateway/network bug, but a feature of some recent
X   UN*X uuencode, to avoid the blank compression by some protocols.
X   Note: It is *NOT* BITNET/EARN that damage the files, we transfert non
X   encoded binaries on this network, but put the blame on some brain damaged
X   gateways. (One of them, between Usenet and Bitnet, is really ruining
X   files... Totally wrong ASCII -> EBCDIC table)
X3- Multi-file decoding is OK, by the 'include xxx' and 'begin part n' lines.
X   To allow for identififation of the original file in the parts, the file
X   name is now provided in the 'begin part n' line.
X4- If the included files do not exist, uud.ttp will attempt to go on with the
X   same file, in case the multiple files have just been concatenated upon
X   reception.
X5- There is a line sequence checking possible, allowing the detection of
X   missing, duplicate, corrupted lines or files. (I have sloppy fingers when
X   editing ...)
X   This feature is enabled if the first line of the 1st uuencoded file
X   is postfixed with a 'z', this is done automatically by the uue.ttp
X   companion program.
X   Note: a bug of the previous version is fixed.
X6- A complete check of the uudecoding process is possible, by use of the
X   -d flag. This will tell you about all whats going on in there, plus
X   this is enabling a complete character by character check of the file
X   while decoding. This should make some subtle file corruptions pop up,
X   as all the uudecode do not check whats in a line before doing their job.
X   If this option detect an error, then the file produced will not be
X   correct (uud stops at the first error detected, and close the file).
X7- If there is a character table present before each file, it will be used,
X   this table is produced by the companion uue.
X   The use of this table allows for some incredible recovery of files that
X   went through some really brain damage gateway. No sweat.
X8- You can decode a single file contaning several uuencoded files, at once;
X   You give a complete month of INFO-ATARI16 digest, and voila all the
X   nice PD .prg's, no editing, no sweat. (To be true, it's been a long time
X   without *.prg in the digests..., but you should try it.)
X9- The files are completely compatible with true UN*X uudecode/uuencode.
X   As long as you do not use the multiple part option of uue.ttp.
X10- Compile on the ST, using MWC, on UN*X System V and on TOPS20 using cc.
X
X
XEn resume: get the mail file containing what you want to decode, on the
XAtari ST, and apply uud.ttp on it, without any editing of any sort, including
Xremoving mail header. (except for multiple parts, where the file names must be
Xcorrect, but no need to edit individual files).
X
X
Xuud v3.3 is the result of:
X1. fixing a bug (nobody, but me, complained about it)
X2. Having a source that compile and run successfully on
X   Atari ST, MS-DOS and UNIX. (Nobody got an Amiga around here)
X   I did the coding/compiling/testing for all 3 systems;
X   For UNIX, it is done using cc on a real/certified SystemVr2
X   For Atari, it is done using MWC 2.x.
X   For the PC, it is done with MSC 4.0. (An attempt with
X   Turbo C did not give me any thing that run correctly)
X   (I discovered a slight bug in MSC 4.0 too, but no big deal.)
X3. Adding some requested features:
X   A. The -t option to allow for a full disk/directory target
X      specification, on which the uuencoded filename is appended.
X      The resulting pathname is where the result of the decoding
X      will be written.
X   B. The -s option: idem -t, but for the source file.
X   C. the -n option to disable the line sequence checking, in case
X      of uue'ed files, for any good/bad reason.
X
X
X   The maximum command line can thus be like:
X   uud -d -n -t c:^binaries^ -s d:^encoded^ file.uue
X   -d : enable the verbose/debugging option, telling you what
X      uud is doing, and sometimes even why...
X   -n : suppress the line sequence checking. (Totally useless option)
X      (The line checking is turned off automagically for files
X      that where not uuencoded by uue, even now for the files with
X      lines terminated by the 'z' char... no more fuzz about them...)
X   -t directory : where the output file(s) will be written, in this case
X      must be terminated by the directory separator character;
X   -s directory : where uud is going to find the file(s) to
X      decode.
X4. This uud can decode line with 80 uuencoded char, instead of the
X   usual 60, the next generation of uue will take advantage of that.
X5. If the file name on the command line,
X   is replaced by the character '-' then
X   standard input will be read, instead of a named file.
X   (For the heavy UNIX news reader...)
X6. typing uud alone on a line, or invoking it without arguments
X   from the desktop, will give you the usage with a reminder
X   about the options.
X
XBig news for Atari/PC users with only restricted disks,
Xyou can decode now much larger files, as the uud.ttp, source
Xand destination files can all be on separate disks.
X
XIf given no args, uud will tells you what version is this, and the usage.
XWith the -d option, a whole lot of checking is done, and it is telling
Xyou all that it is doing.
XIn all case if there is anything else that a perfect decoding, you will
Xhave some message and you'll need to press any key to exit. (I anybody
Xtell me how to tell if we are working from the desktop, or from a shell,
XI will make the pause valid only if run from the desktop. Some kind soul
Xwith an exemple ? I suppose I have to look into the base page...)
XIn case of any error, the produced file is not valid.
X
X==============================================================================
SHAR_EOF
$TOUCH -am 0629144590 uux.doc &&
chmod 0644 uux.doc ||
echo "restore of uux.doc failed"
set `wc -c uux.doc`;Wc_c=$1
if test "$Wc_c" != "7035"; then
	echo original size 7035, current size $Wc_c
fi
fi
exit 0
--
Ralph P. Sobek			  Disclaimer: The above ruminations are my own.
ralph@laas.fr				   Addresses are ordered by importance.
ralph@laas.uucp, or ...!uunet!laas!ralph		
If all else fails, try:				      sobek@eclair.Berkeley.EDU
===============================================================================
THINK: Due to IMF & World Bank policies 100 million Latin American children are
living, eating, and sleeping in the streets -- Le Monde Diplomatique