koreth@ssyx.ucsc.edu (Steven Grimm) (03/12/89)
Submitted-by: uunet!mcvax!unido!klute (Rainer Klute) Posting-number: Volume 2, Issue 24 Archive-name: uuduue Here are the latest sources of Dumas' UUD/UUE package. They were posted a while ago here in europe. They are *not* uuencoded to give you a chance to retrieve them. Rainer Klute ---- klute@irb.informatik.uni-dortmund.de Universitaet Dortmund, IRB |)|/ klute@unido.uucp, klute@unido.bitnet Postfach 500500 |\|\ ...uunet!mcvax!unido!klute D-4600 Dortmund 50 ---- Tel.: +49 231 7554663 #! /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: # UUD.C # UUE.C # This archive created: Wed Feb 8 10:57:34 1989 export PATH; PATH=/bin:/usr/bin:$PATH if test -f 'UUD.C' then echo shar: "will not over-write existing file 'UUD.C'" else cat << \SHAR_EOF > 'UUD.C' /* * Uud -- decode a uuencoded file back to binary form. * * From the Berkeley original, modified by MSD, RDR, JPHD & WLS. * The Atari GEMDOS version compiled with MWC 2.x. * The MSDOS version with TurboC. * The Unix version with cc. * this version is made: 25 Nov 1988. */ /* * Be sure to have the proper symbol at this point. (GEMDOS, MSDOS, UNIX...) */ #ifndef GEMDOS #define GEMDOS 1 #endif /* #ifndef UNIX #define UNIX 1 #endif */ /* #ifndef MSDOS #define MSDOS 1 #endif */ #ifdef GEMDOS #define SYSNAME "gemdos" #define SMALL 1 #endif #ifdef MSDOS #define SYSNAME "msdos" #define SMALL 1 #endif #ifdef UNIX #define SYSNAME "unix" #endif #include <stdio.h> #ifdef GEMDOS #include <osbind.h> #define Error(n) { Bconin(2); exit(n); } #define WRITE "wb" #else #define Error(n) exit(n) #define WRITE "w" #endif #define loop while (1) extern FILE *fopen(); extern char *strcpy(); extern char *strcat(); char *getnword(); #define MAXCHAR 256 #define LINELEN 256 #define FILELEN 64 #define NORMLEN 60 /* allows for 80 encoded chars per line */ #define SEQMAX 'z' #define SEQMIN 'a' char seqc; int first, secnd, check, numl; FILE *in, *out; char *pos; char ifname[FILELEN], ofname[FILELEN]; char *source = NULL, *target = NULL; char blank, part = '\0'; int partn, lens; int debug = 0, nochk = 0, onedone = 0; int chtbl[MAXCHAR], cdlen[NORMLEN + 3]; main(argc, argv) int argc; char *argv[]; { int mode; register int i, j; char *curarg; char dest[FILELEN], buf[LINELEN]; if (argc < 2) { format("Almost foolproof uudecode v3.4 (%s) 25-Nov-88\n", SYSNAME); format("\n"); format("Usage: uud [-n] [-d] [-s dir] [-t dir] input-file\n"); format("\n"); format("Option: -n -> No line sequence check\n"); format("Option: -d -> Debug/verbose mode\n"); format("Option: -s + Source directory for all input files\n"); format(" (MUST be terminated by directory separator)\n"); format("Option: -t + Target directory for all output files\n"); format(" (MUST be terminated by directory separator)\n"); format("If input-file is - then stdin is used as input-file\n"); Error(1); } curarg = argv[1]; while (curarg[0] == '-') { if (((curarg[1] == 'd') || (curarg[1] == 'D')) && (curarg[2] == '\0')) { debug = 1; } else if (((curarg[1] == 'n') || (curarg[1] == 'N')) && (curarg[2] == '\0')) { nochk = 1; } else if (((curarg[1] == 't') || (curarg[1] == 'T')) && (curarg[2] == '\0')) { argv++; argc--; if (argc < 2) { format("uud: Missing target directory.\n"); Error(15); } target = argv[1]; if (debug) format("Target dir = %s\n",target); } else if (((curarg[1] == 's') || (curarg[1] == 'S')) && (curarg[2] == '\0')) { argv++; argc--; if (argc < 2) { format("uud: Missing source directory.\n"); Error(15); } source = argv[1]; if (debug) format("Source dir = %s\n",source); } else if (curarg[1] != '\0') { format("uud: Unknown option <%s>\n", curarg); Error(15); } else break; argv++; argc--; if (argc < 2) { format("uud: Missing file name.\n"); Error(15); } curarg = argv[1]; } if ((curarg[0] == '-') && (curarg[1] == '\0')) { in = stdin; strcpy(ifname, "<stdin>"); } else { if (source != NULL) { strcpy(ifname, source); strcat(ifname, curarg); } else strcpy(ifname, curarg); if ((in = fopen(ifname, "r")) == NULL) { format("uud: Can't open %s\n", ifname); Error(2); } numl = 0; } /* * Set up the default translation table. */ for (i = 0; i < ' '; i++) chtbl[i] = -1; for (i = ' ', j = 0; i < ' ' + 64; i++, j++) chtbl[i] = j; for (i = ' ' + 64; i < MAXCHAR; i++) chtbl[i] = -1; chtbl['`'] = chtbl[' ']; /* common mutation */ chtbl['~'] = chtbl['^']; /* an other common mutation */ blank = ' '; /* * set up the line length table, to avoid computing lotsa * and / ... */ cdlen[0] = 1; for (i = 1, j = 5; i <= NORMLEN; i += 3, j += 4) cdlen[i] = (cdlen[i + 1] = (cdlen[i + 2] = j)); /* * search for header or translation table line. */ loop { /* master loop for multiple decodes in one file */ partn = 'a'; loop { if (fgets(buf, sizeof buf, in) == NULL) { if (onedone) { if (debug) format("End of file.\n"); exit(0); } else { format("uud: No begin line.\n"); Error(3); } } numl++; if (strncmp(buf, "table", 5) == 0) { gettable(); continue; } if (strncmp(buf, "begin", 5) == 0) { break; } } lens = strlen(buf); if (lens) buf[--lens] = '\0'; #ifdef SMALL if ((pos = getnword(buf, 3))) { strcpy(dest, pos); } else #else if(sscanf(buf,"begin%o%s", &mode, dest) != 2) #endif { format("uud: Missing filename in begin line.\n"); Error(10); } if (target != NULL) { strcpy(ofname, target); strcat(ofname, dest); } else strcpy(ofname, dest); if((out = fopen(ofname, WRITE)) == NULL) { format("uud: Cannot open output file: %s\n", ofname); Error(4); } if (debug) format("Begin uudecoding: %s\n", ofname); seqc = SEQMAX; check = nochk ? 0 : 1; first = 1; secnd = 0; decode(); fclose(out); #ifdef UNIX chmod(ofname, mode); #endif onedone = 1; if (debug) format("End uudecoding: %s\n", ofname); } /* master loop for multiple decodes in one file */ } /* * Bring back a pointer to the start of the nth word. */ char *getnword(str, n) register char *str; register int n; { while((*str == '\t') || (*str == ' ')) str++; if (! *str) return NULL; while(--n) { while ((*str != '\t') && (*str != ' ') && (*str)) str++; if (! *str) return NULL; while((*str == '\t') || (*str == ' ')) str++; if (! *str) return NULL; } return str; } /* * Install the table in memory for later use. */ gettable() { char buf[LINELEN]; register int c, n = 0; register char *cpt; for (c = 0; c <= MAXCHAR; c++) chtbl[c] = -1; again: if (fgets(buf, sizeof buf, in) == NULL) { format("uud: EOF while in translation table.\n"); Error(5); } numl++; if (strncmp(buf, "begin", 5) == 0) { format("uud: Incomplete translation table.\n"); Error(6); } cpt = buf + strlen(buf) - 1; *cpt = ' '; while (*(cpt) == ' ') { *cpt = 0; cpt--; } cpt = buf; while (c = *cpt) { if (chtbl[c] != -1) { format("uud: Duplicate char in translation table.\n"); Error(7); } if (n == 0) blank = c; chtbl[c] = n++; if (n >= 64) return; cpt++; } goto again; } /* * copy from in to out, decoding as you go along. */ decode() { char buf[LINELEN], outl[LINELEN]; register char *bp, *ut; register int *trtbl = chtbl; register int n, c, rlen; register unsigned int len; loop { if (fgets(buf, sizeof buf, in) == NULL) { format("uud: EOF before end.\n"); fclose(out); Error(8); } numl++; len = strlen(buf); if (len) buf[--len] = '\0'; /* * Is it an unprotected empty line before the end line ? */ if (len == 0) continue; /* * Get the binary line length. */ n = trtbl[*buf]; if (n >= 0) goto decod; /* * end of uuencoded file ? */ if (strncmp(buf, "end", 3) == 0) return; /* * end of current file ? : get next one. */ if (strncmp(buf, "include", 7) == 0) { getfile(buf); continue; } format("uud: Bad prefix line %d in file: %s\n",numl, ifname); if (debug) format("Bad line =%s\n",buf); Error(11); /* * Sequence checking ? */ decod: rlen = cdlen[n]; /* * Is it the empty line before the end line ? */ if (n == 0) continue; /* * Pad with blanks. */ for (bp = &buf[c = len]; c < rlen; c++, bp++) *bp = blank; /* * Verify if asked for. */ if (debug) { for (len = 0, bp = buf; len < rlen; len++) { if (trtbl[*bp] < 0) { format( "Non uuencoded char <%c>, line %d in file: %s\n", *bp, numl, ifname); format("Bad line =%s\n",buf); Error(16); } bp++; } } /* * All this just to check for uuencodes that append a 'z' to each line.... */ if (secnd && check) { secnd = 0; if (buf[rlen] == SEQMAX) { check = 0; if (debug) format("Sequence check turned off (2).\n"); } else if (debug) format("Sequence check on (2).\n"); } else if (first && check) { first = 0; secnd = 1; if (buf[rlen] != SEQMAX) { check = 0; if (debug) format("No sequence check (1).\n"); } else if (debug) format("Sequence check on (1).\n"); } /* * There we check. */ if (check) { if (buf[rlen] != seqc) { format("uud: Wrong sequence line %d in %s\n", numl, ifname); if (debug) format( "Sequence char is <%c> instead of <%c>.\n", buf[rlen], seqc); Error(18); } seqc--; if (seqc < SEQMIN) seqc = SEQMAX; } /* * output a group of 3 bytes (4 input characters). * the input chars are pointed to by p, they are to * be output to file f.n is used to tell us not to * output all of them at the end of the file. */ ut = outl; len = n; bp = &buf[1]; while (n > 0) { *(ut++) = trtbl[*bp] << 2 | trtbl[bp[1]] >> 4; n--; if (n) { *(ut++) = (trtbl[bp[1]] << 4) | (trtbl[bp[2]] >> 2); n--; } if (n) { *(ut++) = trtbl[bp[2]] << 6 | trtbl[bp[3]]; n--; } bp += 4; } if ((n = fwrite(outl, 1, len, out)) <= 0) { format("uud: Error on writing decoded file.\n"); Error(18); } } } /* * Find the next needed file, if existing, otherwise try further * on next file. */ getfile(buf) register char *buf; { if ((pos = getnword(buf, 2)) == NULL) { format("uud: Missing include file name.\n"); Error(17); } else if (source != NULL) { strcpy(ifname, source); strcat(ifname, pos); } else strcpy(ifname, pos); #ifdef GEMDOS if (Fattrib(ifname, 0, 0) < 0) #else if (access(ifname, 04)) #endif { if (debug) { format("Cant find: %s\n", ifname); format("Continuing to read same file.\n"); } } else { if (freopen(ifname, "r", in) == in) { numl = 0; if (debug) format("Reading next section from: %s\n", ifname); } else { format("uud: Freopen abort: %s\n", ifname); Error(9); } } loop { if (fgets(buf, LINELEN, in) == NULL) { format("uud: No begin line after include: %s\n", ifname); Error(12); } numl++; if (strncmp(buf, "table", 5) == 0) { gettable(); continue; } if (strncmp(buf, "begin", 5) == 0) break; } lens = strlen(buf); if (lens) buf[--lens] = '\0'; /* * Check the part suffix. */ if ((pos = getnword(buf, 3)) == NULL ) { format("uud: Missing part name, in included file: %s\n", ifname); Error(13); } else { part = *pos; partn++; if (partn > 'z') partn = 'a'; if (part != partn) { format("uud: Part suffix mismatch: <%c> instead of <%c>.\n", part, partn); Error(14); } if (debug) format("Reading part %c\n", *pos); } } /* * Printf style formatting. (Borrowed from MicroEmacs by Dave Conroy.) * A lot smaller than the full fledged printf. */ /* VARARGS1 */ format(fp, args) char *fp; { doprnt(fp, (char *)&args); } doprnt(fp, ap) register char *fp; register char *ap; { register int c, k; register char *s; while ((c = *fp++) != '\0') { if (c != '%') outc(c); else { c = *fp++; switch (c) { case 'd': puti(*(int *)ap, 10); ap += sizeof(int); break; case 's': s = *(char **)ap; while ((k = *s++) != '\0') outc(k); ap += sizeof(char *); break; case 'c': outc(*(int *)ap); ap += sizeof(int); break; default: outc(c); } } } } /* * Put integer, in radix "r". */ puti(i, r) register unsigned int i; register unsigned int r; { register unsigned int q, s; if ((q = i / r) != 0) puti(q, r); s = i % r; if (s <= 9) outc(s + '0'); else outc(s - 10 + 'A'); } outc(c) register char c; { #ifdef GEMDOS if (c == '\n') Bconout(2, '\r'); Bconout(2, c); #else putchar(c); #endif } SHAR_EOF fi if test -f 'UUE.C' then echo shar: "will not over-write existing file 'UUE.C'" else cat << \SHAR_EOF > 'UUE.C' /* * * Uue -- encode a file so that it's printable ascii, short lines * * Slightly modified from a version posted to net.sources a while back, * and suitable for compilation on the IBM PC * * modified for Lattice C on the ST - 11.05.85 by MSD * modified for ALCYON on the ST - 10-24-86 by RDR * modified a little more for MWC... 02/09/87 by JPHD * (An optional first argument of the form: -nnumber (e.g. -500), will * produce a serie of files that long, linked by the include statement, * such files are automatically uudecoded by the companion program.) * More mods, - ... 05/06/87 by jphd * Mods for TOPS 20, and more. 08/06/87 by jphd * (remove freopen and rindex...change filename generation...) * (A lot more to do about I/O speed, avoiding completely the stdio.h...) * */ #include <stdio.h> #include <ctype.h> #define USAGE /* ENC is the basic 1 character encoding function to make a char printing */ #define ENC(c) (((c) & 077) + ' ') extern FILE *fopen(); FILE *fp, *outp; char ofname[80]; int lenofname; int stdo = 0; #ifdef ST #define READ "rb" #else #define READ "r" #endif int part = 'a', chap = 'a'; #define SEQMAX 'z' #define SEQMIN 'a' char seqc = SEQMAX; int split = 0; fileln = 32000; main(argc, argv) int argc; char *argv[]; { char *fname; if (argc < 2) { fprintf(stderr, "Almost foolproof uuencode v3.1 06 Aug 1987\n"); fprintf(stderr, "Usage: uue [-n] inputfile [-]\n"); exit(2); } if (argv[1][0] == '-') { fileln = -atoi(argv[1]); if (fileln <= 0) { fprintf(stderr, "Wrong file length arg.\n"); exit(); } split = 1; argv++; argc--; } if ((fp=fopen(argv[1], READ))==NULL) { /* binary input !!! */ fprintf(stderr,"Cannot open %s\n",argv[1]); exit(1); } strcpy(ofname, argv[1]); fname = ofname; do { if (*fname == '.') *fname = '\0'; } while (*fname++); /* 8 char prefix + .uue -> 12 chars MAX */ lenofname = strlen(ofname); if (lenofname > 8) ofname[8] = '\0'; strcat(ofname,".uue"); lenofname = strlen(ofname); if (!split && (argc > 2) && (argv[2][0] == '-')) { stdo = 1; outp = stdout; } else { makename(); if((outp = fopen(ofname, "w")) == NULL) { fprintf(stderr,"Cannot open %s\n", ofname); exit(1); } } maketable(); fprintf(outp,"begin %o %s\n", 0644, argv[1]); encode(); fprintf(outp,"end\n"); fclose(outp); exit(0); } /* create ASCII table so a mailer can screw it up and the decode * program can restore the error. */ maketable() { register int i, j; fputs("table\n", outp); for(i = ' ', j = 0; i < '`' ; j++) { if (j == 32) putc('\n', outp); fputc(i++, outp); } putc('\n', outp); } /* * Generate the names needed for single and multiple part encoding. */ makename() { if (split) { ofname[lenofname - 1] = part; ofname[lenofname - 2] = chap; } } /* * copy from in to out, encoding as you go along. */ encode() { char buf[80]; register int i, n; register int lines; lines = 6; for (;;) { n = fr(buf, 45); putc(ENC(n), outp); for (i = 0; i < n; i += 3) outdec(&buf[i]); putc(seqc, outp); seqc--; if (seqc < SEQMIN) seqc = SEQMAX; putc('\n', outp); ++lines; if (split && (lines > fileln)) { part++; if (part > 'z') { part = 'a'; if (chap == 'z') chap = 'a'; /* loop ... */ else chap++; } makename(); fprintf(outp,"include %s\n",ofname); fclose(outp); if((outp = fopen(ofname, "w")) == NULL) { fprintf(stderr,"Cannot open %s\n",ofname); exit(1); } maketable(); fprintf(outp,"begin part %c %s\n",part,ofname); lines = 6; } if (n <= 0) break; } } /* * output one group of 3 bytes, pointed at by p, on file f. */ outdec(p) register char *p; { register int c1, c2, c3, c4; c1 = *p >> 2; c2 = (*p << 4) & 060 | (p[1] >> 4) & 017; c3 = (p[1] << 2) & 074 | (p[2] >> 6) & 03; c4 = p[2] & 077; putc(ENC(c1), outp); putc(ENC(c2), outp); putc(ENC(c3), outp); putc(ENC(c4), outp); } /* fr: like read but stdio */ int fr(buf, cnt) register char *buf; register int cnt; { register int c, i; for (i = 0; i < cnt; i++) { c = fgetc(fp); if (feof(fp)) return(i); buf[i] = c; } return (cnt); } SHAR_EOF fi exit 0 # End of shell archive