From ncr-sd!hp-sdd!hplabs!sri-unix!husc6!necntc!ncoast!allbery Tue Oct 6 12:55:03 PDT 1987 The following is a patch to the p.d. uudecode posted here recently. It adds an option "-f", which cures what I consider to be the most annoying feature of uudecode: it insists on writing its output to the file name specified in the input. When "-f" is given, output goes to stdout, so uudecode can be used as a filter. (If there is more than one file in the encoded file, they are concatenated together.) Dale ---------------------------------------- *** uudecode.old Tue Sep 29 12:51:21 1987 --- uudecode.c Tue Sep 29 13:43:11 1987 *************** *** 13,21 **** loop for multiple decodes from a single file, and to handle common BITNET mangling. Also kludged around a missing string function in Aztec C */ /* ! * uudecode [input] * * Decode a file encoded with uuencode. WIll extract multiple encoded * modules from a single file. Can deal with most mangled files, including --- 13,26 ---- loop for multiple decodes from a single file, and to handle common BITNET mangling. Also kludged around a missing string function in Aztec C */ + /* Modified by drw (Dale Worley, drw@math.mit.edu) to add the -f switch, which + forces the output to be on stdout. This makes uudecode into a filter, and + frees the user from perversions in the file name and mode given in the + input file. These changes Copyright (C) 1987 Dale R. Worley, and are hereby + put in the public domain. */ /* ! * uudecode [-f] [input] * * Decode a file encoded with uuencode. WIll extract multiple encoded * modules from a single file. Can deal with most mangled files, including *************** *** 37,42 **** --- 42,50 ---- #include #endif + long written_size; /* number of bytes written to output, used instead of + of ftell, because ftell doesn't work with -f */ + #define SUMSIZE 64 #define DEC(c) (((c) - ' ') & 077) /* single character decode */ *************** *** 49,54 **** --- 57,63 ---- long filesize; /* theoretical file size (from header) */ char dest[128]; char buf[80]; + int f_option = 0; /* set to 1 if -f option is present */ #ifdef AMIGA_LATTICE extern int Enable_Abort; *************** *** 55,60 **** --- 64,76 ---- Enable_Abort=1; #endif + /* First, check for the -f option */ + if (argc >= 2 && strcmp(argv[1], "-f") == 0) + { + f_option = 1; + argc--; argv++; + } + /* A filename can be specified to be uudecoded, or nothing can be specified, and the input will come from STDIN */ *************** *** 68,80 **** if ((in = fopen(argv[1], "r")) == NULL) { fprintf(stderr, "ERROR: can't find %s\n", argv[1]); ! fprintf(stderr, "USAGE: uudecode [infile]\n"); exit(10); } break; default: ! fprintf(stderr, "USAGE: uudecode [infile]\n"); exit(11); break; } --- 84,96 ---- if ((in = fopen(argv[1], "r")) == NULL) { fprintf(stderr, "ERROR: can't find %s\n", argv[1]); ! fprintf(stderr, "USAGE: uudecode [-f] [infile]\n"); exit(10); } break; default: ! fprintf(stderr, "USAGE: uudecode [-f] [infile]\n"); exit(11); break; } *************** *** 104,149 **** } sscanf(buf, "begin %o %s", &mode, dest); #ifdef unix ! /* 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(13); } - *sl++ = 0; - user = getpwnam(dest+1); - if (user == NULL) - { - fprintf(stderr, "No such user as %s\n", dest); - exit(14); - } - strcpy(dnbuf, user->pw_dir); - strcat(dnbuf, "/"); - strcat(dnbuf, sl); - strcpy(dest, dnbuf); - } #endif ! /* create output file */ ! if ((out = fopen(dest, "w")) == NULL) ! { ! fprintf(stderr, "ERROR: can't open output file %s\n", dest); ! exit(15); ! } #ifdef unix ! chmod(dest, mode); #endif decode(in, out, dest); if (fgets(buf, sizeof buf, in) == NULL || strncmp(buf,"end",3)) --- 120,177 ---- } sscanf(buf, "begin %o %s", &mode, dest); + /* set up the output file */ + if (f_option) + { + /* the -f option is used, so use stdout */ + out = stdout; + } + else + { + /* the -f option is not used, so use the filename (and mode) in the + * begin line */ #ifdef unix ! /* 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(13); ! } ! *sl++ = 0; ! user = getpwnam(dest+1); ! if (user == NULL) ! { ! fprintf(stderr, "No such user as %s\n", dest); ! exit(14); ! } ! strcpy(dnbuf, user->pw_dir); ! strcat(dnbuf, "/"); ! strcat(dnbuf, sl); ! strcpy(dest, dnbuf); } #endif ! /* create output file */ ! if ((out = fopen(dest, "w")) == NULL) ! { ! fprintf(stderr, "ERROR: can't open output file %s\n", dest); ! exit(15); ! } #ifdef unix ! chmod(dest, mode); #endif + } + /* actually decode the data */ decode(in, out, dest); if (fgets(buf, sizeof buf, in) == NULL || strncmp(buf,"end",3)) *************** *** 155,166 **** if (!(fgets(buf,sizeof buf,in) == NULL || strncmp(buf,"size ",3))) { sscanf(buf, "size %ld", &filesize); ! if (ftell(out) != filesize) { ! fprintf(stderr, "ERROR: file should have been %ld bytes long but was %ld.\n", filesize, ftell(out)); exit(17); } } through_loop = 1; } /* forever */ } /* main */ --- 183,203 ---- if (!(fgets(buf,sizeof buf,in) == NULL || strncmp(buf,"size ",3))) { sscanf(buf, "size %ld", &filesize); ! if (written_size != filesize) { ! fprintf(stderr, "ERROR: file should have been %ld bytes long but was %ld.\n", filesize, written_size); exit(17); } } + + /* close the output file */ + if (!f_option) + if (fclose(out) != 0) + { + fprintf(stderr, "ERROR: error closing file %s.\n", dest); + exit(20); + } + through_loop = 1; } /* forever */ } /* main */ *************** *** 185,190 **** --- 222,230 ---- register int n; int checksum, line; + /* zero the byte count */ + written_size = 0; + for (line = 1; ; line++) /* for each input line */ { if (fgets(buf, sizeof buf, in) == NULL) *************** *** 220,228 **** while (n >= 4) { ! j = DEC(bp[0]) << 2 | DEC(bp[1]) >> 4; putc(j, out); checksum += j; ! j = DEC(bp[1]) << 4 | DEC(bp[2]) >> 2; putc(j, out); checksum += j; ! j = DEC(bp[2]) << 6 | DEC(bp[3]); putc(j, out); checksum += j; checksum = checksum % SUMSIZE; bp += 4; n -= 3; --- 260,280 ---- while (n >= 4) { ! j = DEC(bp[0]) << 2 | DEC(bp[1]) >> 4; ! putc(j, out); ! checksum += j; ! written_size++; ! ! j = DEC(bp[1]) << 4 | DEC(bp[2]) >> 2; ! putc(j, out); ! checksum += j; ! written_size++; ! ! j = DEC(bp[2]) << 6 | DEC(bp[3]); ! putc(j, out); ! checksum += j; ! written_size++; ! checksum = checksum % SUMSIZE; bp += 4; n -= 3; *************** *** 231,245 **** --- 283,306 ---- j = DEC(bp[0]) << 2 | DEC(bp[1]) >> 4; checksum += j; if (n >= 1) + { putc(j, out); + written_size++; + } j = DEC(bp[1]) << 4 | DEC(bp[2]) >> 2; checksum += j; if (n >= 2) + { putc(j, out); + written_size++; + } j = DEC(bp[2]) << 6 | DEC(bp[3]); checksum += j; if (n >= 3) + { putc(j, out); + written_size++; + } checksum = checksum % SUMSIZE; bp += 4; n -= 3; ---------------------------------------- -- Dale Worley Cullinet Software ARPA: culdev1!drw@eddie.mit.edu UUCP: ...!seismo!harvard!mit-eddie!culdev1!drw "Thank you for your cooperation. Goodnight." -- Robocop "Don't f--k with the babysitter." -- Adventures in Babysitting