W8SDZ@SIMTEL20.ARPA (Keith Petersen) (04/13/88)
Here is uudecode for Unix, the companion program for the uuencode I posted to the comp.binaries.ibm.pc newsgroup. As you know, I have been trying to get posters to use the newer uuencode because it uses the accent grave (`) in place of the space character to get around problems with some mailers that strip trailing blanks. This program is for Unix - it is not intended to be used on MSDOS. There are sources on SIMTEL20 for uuencode and uudecode for MSDOS that I can send along if you need them. Personally I prefer to transfer binaries to/from the Unix host with DSZ and rz/sz, uuencoding and uudecoding them there. It is much faster. Compile with the command: cc -O uudecode.c -o uudecode Don't forget to trim off the trailing cut and signature lines before compiling. --cut-here--UUDECODE.C--cut-here-- #ifndef lint static char sccsid[] = "@(#)uudecode.c 5.3 (Berkeley) 4/10/85"; #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; 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); } --cut-here-- --Keith Petersen Maintainer of the MSDOS archives at SIMTEL20.ARPA Arpa: W8SDZ@SIMTEL20.ARPA Uucp: {decwrl,harvard,lll-crg,ucbvax,uunet,uw-beaver}!simtel20.arpa!w8sdz