broehl@watdcsu.UUCP (Bernie Roehl) (10/10/85)
<bug line> Below you'll find source code for uuencode and uudecode. They are based on a net posting of many moons ago; my apologies to the original author for losing his name (speak up and take credit!). I have used them for moving binary files between Unix and the PC, and have had no problems so far. They should compile under any reasonable C compiler for the PC; I use DeSmet (C-Ware), but others should work just as well. The function efopen() is part of a library... I'll post the source separately once I dig it up... Enjoy. ----------- CUT HERE ----------- /* * * Uuencode -- 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 * */ #include <stdio.h> char *progname = "UUENCODE"; #define USAGE "Usage: UUENCODE file [>outfile]\n" /* ENC is the basic 1 character encoding function to make a char printing */ #define ENC(c) (((c) & 077) + ' ') main(argc, argv) int argc; char *argv[]; { FILE *in; int mode; if (argc < 2) { fprintf(stderr, USAGE); exit(2); } in = efopen(argv[1], "r"); printf("begin %o %s\n", 0777, argv[1]); encode(in, stdout); printf("end\n"); } /* * copy from in to out, encoding as you go along. */ encode(in, out) FILE *in, *out; { char buf[80]; int i, n; for (;;) { 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); } ---- END OF UUENCODE.C; UUDECODE.C follows ---- /* * Uudecode -- decode a uuencoded file back to binary form. * * Slightly modified from a version posted to net.sources once; * suitable for compilation on an IBM PC. * */ #include <stdio.h> char *progname = "UUDECODE"; #define USAGE "Usage: UUDECODE [file]\n" /* single character decode */ #define DEC(c) (((c) - ' ') & 077) main(argc, argv) int argc; char *argv[]; { FILE *in, *out; int mode; char dest[128]; char buf[80]; /* optional input arg */ if (argc > 1) { in = efopen(argv[1], "r"); argv++; argc--; } else in = stdin; if (argc != 1) { fprintf(stderr, USAGE); 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); out = efopen(dest, "w"); /* create output file */ decode(in, out); fclose(out); if (fgets(buf, sizeof buf, in) == NULL || strcmp(buf, "end\n")) { fprintf(stderr, "No end line\n"); exit(5); } } /* * copy from in to out, decoding as you go along. */ decode(in, out) FILE *in, *out; { char buf[80]; char *bp; int n; for (;;) { if (fgets(buf, sizeof buf, in) == NULL) { fprintf(stderr, "Short file\n"); break; } 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 n; { 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); } /* If your library already has this function, use it and nuke the code below */ #ifdef noindex /* * Return the ptr in sp at which the character c appears; * NULL if not found */ char *index(sp, c) register char *sp, c; { do { if (*sp == c) return(sp); } while (*sp++); return(NULL); } #endif