drw@culdev1.UUCP (Dale Worley) (10/05/87)
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 <sys/stat.h>
#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