coulter@hplabsc.UUCP (Michael Coulter) (05/22/86)
# This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # # Wrapped by coulter at hplmac on Thu May 22 12:54:36 1986 # # This archive contains: # README uudecode.bas uudecode.c uuencode.1c # uuencode.c echo x - README cat >README <<'@EOF' This shar file contains the C source for uuencode and uudecode. It also has the MSDOS BASIC code for uudecode. There is a man page in uuencode.1c. P.S. - I didn't write any of it. -- Michael Coulter ...hplabs!coulter @EOF size=`wc -c <README`; if test $size -ne 222 ; then echo ERROR: README is $size bytes but should be 222. fi chmod 644 README echo x - uudecode.bas cat >uudecode.bas <<'@EOF' # Written 1:32 am Feb 17, 1986 by rde@ukc.ac.uk in net.sources # In Real Life: R.D.Eager at U of Kent at Canterbury, Canterbury, UK # Subject: uudecode in MS-BASIC [food for line eater] There has been some discussion about public domain versions of uudecode for those souls who didn't get it in a distribution. I thought it was time to post the updated version of uudecode in Microsoft BASIC; I have made a minor change to cater for a variation in coding encountered on some uuencoded files. This program is short enough that it can be typed in by hand if necessary. I hope it is of some use to micro owners without direct access to other uudecodes. ---------CUT HERE--------CUT HERE----------CUT HERE---------CUT HERE------ 1000 DEFINT A-Z 1010 REM Trap filing errors 1020 ON ERROR GOTO 1600 1030 CLS 1040 LOCATE 5,11 1050 PRINT STRING$(40," ") 1060 LOCATE 5,11 1070 INPUT "Enter name of input file: ", INFILE$ 1080 OPEN INFILE$ FOR INPUT AS #1 1090 LOCATE 8,10 1100 PRINT STRING$(40," ") 1110 LOCATE 8,10 1120 INPUT "Enter name of output file: ", OUTFILE$ 1130 OPEN "R", #2,OUTFILE$, 1 1140 FIELD #2, 1 AS N$ 1150 REM Search for header line 1160 LINE INPUT #1,A$ 1170 IF LEFT$(A$,5) <>"begin" THEN 1160 1180 LOCATE 11,10 1190 PRINT "Header = ";A$ 1200 SP = ASC(" ") 1210 DIM BUF(5000) 1220 P = 0 1230 REM Main loop 1240 LINE INPUT #1, A$ 1250 P = 0 1260 COUNT = ASC(LEFT$(A$,1)) - SP 1270 IF COUNT <> 64 THEN 1290 1280 COUNT = 0 1290 IF COUNT = 0 THEN 1560 1300 ADJ = COUNT MOD 4 1310 FOR I = 2 TO LEN(A$) STEP 4 1320 X1 = ASC(MID$(A$,I,I)) - SP 1330 IF X1 <> 64 THEN 1350 1340 X1 = 0 1350 X2 = ASC(MID$(A$,I+1,I+1)) - SP 1360 IF X2 <> 64 THEN 1380 1370 X2 = 0 1380 X3 = ASC(MID$(A$,I+2,I+2)) - SP 1390 IF X3 <> 64 THEN 1410 1400 X3 = 0 1410 X4 = ASC(MID$(A$,I+3,I+3)) - SP 1420 IF X4 <> 64 THEN 1440 1430 X4 = 0 1440 P = P + 1 1450 BUF(P) = (X2\16) + (X1*4) 1460 P = P + 1 1470 BUF(P) = (X3\4) + ((X2 MOD 16) * 16) 1480 P = P + 1 1490 BUF(P) = X4 + ((X3 MOD 4) * 64) 1500 NEXT I 1510 FOR I = 1 TO P 1520 LSET N$ = CHR$(BUF(I)) 1530 PUT #2 1540 NEXT I 1550 GOTO 1240 1560 END 1570 REM 1580 REM Error trapping routine for file handling 1590 REM 1600 IF ERL <> 1080 GOTO 1650 ' not input file problem 1610 LOCATE 22,20 1620 PRINT "Can't open input file" 1630 GOSUB 1780 1640 RESUME 1040 1650 IF ERL <> 1130 GOTO 1700 ' not output file problem 1660 LOCATE 22,20 1670 PRINT "Can't open output file" 1680 GOSUB 1780 1690 RESUME 1090 1700 IF ERL <> 1160 THEN 1770 1710 LOCATE 22,20 1720 PRINT "Header line not found" 1730 GOSUB 1780 1740 GOSUB 1780 1750 LOCATE 24,1 1760 END 1770 ERROR ERR 1780 FOR I = 1 TO 5000: NEXT I 1790 LOCATE 22,20 1800 PRINT STRING$(30," ") 1810 RETURN TE 24,1 1760 END 1770 ERROR ERR 1780 FOR I = 1 TO 5000: NEXT I 1 ---------CUT HERE--------CUT HERE----------CUT HERE---------CUT HERE------ -- Bob Eager rde@ukc.UUCP rde@ukc ...!mcvax!ukc!rde Phone: +44 227 66822 ext 7589 # End of text from net.sources on hplabsc.UUCP @EOF size=`wc -c <uudecode.bas`; if test $size -ne 3106 ; then echo ERROR: uudecode.bas is $size bytes but should be 3106. fi chmod 644 uudecode.bas echo x - uudecode.c cat >uudecode.c <<'@EOF' #ifndef lint static char sccsid[] = "@(#)uudecode.c 5.1 (Berkeley) 7/2/83"; #endif /* * uudecode [input] * * create the specified file, decoding as you go. * used with uuencode. */ #include <stdio.h> #include <pwd.h> #include <sys/types.h> #include <sys/stat.h> /* single character decode */ #define DEC(c) (((c) - ' ') & 077) main(argc, argv) char **argv; { FILE *in, *out; struct stat sbuf; int mode; char dest[128]; char buf[80]; /* optional input arg */ if (argc > 1) { if ((in = fopen(argv[1], "r")) == NULL) { perror(argv[1]); exit(1); } argv++; argc--; } else in = stdin; if (argc != 1) { printf("Usage: uudecode [infile]\n"); exit(2); } /* search for header line */ for (;;) { if (fgets(buf, sizeof buf, in) == NULL) { fprintf(stderr, "No begin line\n"); exit(3); } if (strncmp(buf, "begin ", 6) == 0) break; } sscanf(buf, "begin %o %s", &mode, dest); /* handle ~user/file format */ if (dest[0] == '~') { char *sl; struct passwd *getpwnam(); char *index(); struct passwd *user; char dnbuf[100]; sl = index(dest, '/'); if (sl == NULL) { fprintf(stderr, "Illegal ~user\n"); exit(3); } *sl++ = 0; user = getpwnam(dest+1); if (user == NULL) { fprintf(stderr, "No such user as %s\n", dest); exit(4); } strcpy(dnbuf, user->pw_dir); strcat(dnbuf, "/"); strcat(dnbuf, sl); strcpy(dest, dnbuf); } /* create output file */ out = fopen(dest, "w"); if (out == NULL) { perror(dest); exit(4); } chmod(dest, mode); decode(in, out); if (fgets(buf, sizeof buf, in) == NULL || strcmp(buf, "end\n")) { fprintf(stderr, "No end line\n"); exit(5); } exit(0); } /* * copy from in to out, decoding as you go along. */ decode(in, out) FILE *in; FILE *out; { char buf[80]; char *bp; int n; for (;;) { /* for each input line */ if (fgets(buf, sizeof buf, in) == NULL) { printf("Short file\n"); exit(10); } n = DEC(buf[0]); if (n <= 0) break; bp = &buf[1]; while (n > 0) { outdec(bp, out, n); bp += 4; n -= 3; } } } /* * 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. */ outdec(p, f, n) char *p; FILE *f; { int c1, c2, c3; c1 = DEC(*p) << 2 | DEC(p[1]) >> 4; c2 = DEC(p[1]) << 4 | DEC(p[2]) >> 2; c3 = DEC(p[2]) << 6 | DEC(p[3]); if (n >= 1) putc(c1, f); if (n >= 2) putc(c2, f); if (n >= 3) putc(c3, f); } /* fr: like read but stdio */ int fr(fd, buf, cnt) FILE *fd; char *buf; int cnt; { int c, i; for (i=0; i<cnt; i++) { c = getc(fd); if (c == EOF) return(i); buf[i] = c; } return (cnt); } /* * Return the ptr in sp at which the character c appears; * NULL if not found */ #define NULL 0 char * index(sp, c) register char *sp, c; { do { if (*sp == c) return(sp); } while (*sp++); return(NULL); } @EOF size=`wc -c <uudecode.c`; if test $size -ne 2949 ; then echo ERROR: uudecode.c is $size bytes but should be 2949. fi chmod 644 uudecode.c echo x - uuencode.1c cat >uuencode.1c <<'@EOF' .TH UUENCODE 1C "1 June 1980" .UC 4 .SH NAME uuencode,uudecode \- encode/decode a binary file for transmission via mail .SH SYNOPSIS .B uuencode [ source ] remotedest | .B mail sys1!sys2!..!decode .br .B uudecode [ file ] .SH DESCRIPTION .I Uuencode and .I uudecode are used to send a binary file via uucp (or other) mail. This combination can be used over indirect mail links even when .IR uusend (1C) is not available. .PP .I Uuencode takes the named source file (default standard input) and produces an encoded version on the standard output. The encoding uses only printing ASCII characters, and includes the mode of the file and the .I remotedest for recreation on the remote system. .PP .I Uudecode reads an encoded file, strips off any leading and trailing lines added by mailers, and recreates the original file with the specified mode and name. .PP The intent is that all mail to the user ``decode'' should be filtered through the uudecode program. This way the file is created automatically without human intervention. This is possible on the uucp network by either using .I sendmail or by making .I rmail be a link to .I Mail instead of .I mail. In each case, an alias must be created in a master file to get the automatic invocation of uudecode. .PP If these facilities are not available, the file can be sent to a user on the remote machine who can uudecode it manually. .PP The encode file has an ordinary text form and can be edited by any text editor to change the mode or remote name. .SH SEE\ ALSO uuencode(5), uusend(1C), uucp(1C), uux(1C), mail(1) .SH AUTHOR Mark Horton .SH BUGS The file is expanded by 35% (3 bytes become 4 plus control information) causing it to take longer to transmit. .PP The user on the remote system who is invoking .I uudecode (often .I uucp) must have write permission on the specified file. @EOF size=`wc -c <uuencode.1c`; if test $size -ne 1840 ; then echo ERROR: uuencode.1c is $size bytes but should be 1840. fi chmod 644 uuencode.1c echo x - uuencode.c cat >uuencode.c <<'@EOF' #ifndef lint static char sccsid[] = "@(#)uuencode.c 5.1 (Berkeley) 7/2/83"; #endif /* * uuencode [input] output * * Encode a file so it can be mailed to a remote system. */ #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> /* ENC is the basic 1 character encoding function to make a char printing */ #define ENC(c) (((c) & 077) + ' ') main(argc, argv) char **argv; { FILE *in; struct stat sbuf; int mode; /* optional 1st argument */ if (argc > 2) { if ((in = fopen(argv[1], "r")) == NULL) { perror(argv[1]); exit(1); } argv++; argc--; } else in = stdin; if (argc != 2) { printf("Usage: uuencode [infile] remotefile\n"); exit(2); } /* figure out the input file mode */ fstat(fileno(in), &sbuf); mode = sbuf.st_mode & 0777; printf("begin %o %s\n", mode, argv[1]); encode(in, stdout); printf("end\n"); exit(0); } /* * copy from in to out, encoding as you go along. */ encode(in, out) FILE *in; FILE *out; { char buf[80]; int i, n; for (;;) { /* 1 (up to) 45 character line */ n = fr(in, buf, 45); putc(ENC(n), out); for (i=0; i<n; i += 3) outdec(&buf[i], out); putc('\n', out); if (n <= 0) break; } } /* * output one group of 3 bytes, pointed at by p, on file f. */ outdec(p, f) char *p; FILE *f; { 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), f); putc(ENC(c2), f); putc(ENC(c3), f); putc(ENC(c4), f); } /* fr: like read but stdio */ int fr(fd, buf, cnt) FILE *fd; char *buf; int cnt; { int c, i; for (i=0; i<cnt; i++) { c = getc(fd); if (c == EOF) return(i); buf[i] = c; } return (cnt); } @EOF size=`wc -c <uuencode.c`; if test $size -ne 1707 ; then echo ERROR: uuencode.c is $size bytes but should be 1707. fi chmod 644 uuencode.c exit 0