/* * uuencode [input] output * * Encode a file so it can be mailed to a remote system. */ #include #include #include /* ENC is the basic 1 character encoding function to make a char printing */ #define ENC(c) (((c) & 077) + ' ') static void encode(int, Biobuf*); static void chunk(char*, int, Biobuf*); static void outdec(char*, Biobuf*); void main(int argc, char **argv) { Dir *d; int fd; Biobuf bout; /* optional 1st argument */ if (argc > 2) { if ((fd = open(argv[1], OREAD)) < 0) { fprint(2, "uuencode: can't open %s: %r\n", argv[1]); exits("open"); } argv++; argc--; USED(argv); } else fd = 0; if (argc != 2) { fprint(2, "Usage: uuencode [infile] remotefile\n"); exits("usage"); } Binit(&bout, 1, OWRITE); d = dirfstat(fd); Bprint(&bout, "begin %ulo %s\n", (d)? d->mode & 0777: 0666, argv[1]); free(d); encode(fd, &bout); Bprint(&bout, "end\n"); if (Bflush(&bout)) { fprint(2, "uuencode: error writing output: %r\n"); exits("output"); } exits(0); } /* * copy from in to out, encoding as you go along. */ static void encode(int in, Biobuf *out) { char buf[(Bsize/45)*45]; /* chunks of up to 45 characters */ char *p; int n, r; r = 0; p = buf; while((n = read(in, buf, sizeof(buf))) > 0) for(p = buf, r = n; r >= 45; r -= 45, p += 45) chunk(p, 45, out); if(n < 0) { fprint(2, "uuencode: read error: %r\n"); exits("read"); } if(r) chunk(p, r, out); chunk(buf, 0, out); } static void chunk(char *p, int n, Biobuf *out) { int i; BPUTC(out, ENC(n)); for(i = 0; i < n; i += 3) outdec(p+i, out); BPUTC(out, '\n'); } /* * output one group of 3 bytes, pointed at by p, on file f. */ static void outdec(char *p, Biobuf *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; BPUTC(f, ENC(c1)); BPUTC(f, ENC(c2)); BPUTC(f, ENC(c3)); BPUTC(f, ENC(c4)); }