diff options
author | fanf <fanf@FreeBSD.org> | 2002-11-01 02:08:51 +0000 |
---|---|---|
committer | fanf <fanf@FreeBSD.org> | 2002-11-01 02:08:51 +0000 |
commit | c1d0f70dee4de285a39f098ba26240829e19ea6d (patch) | |
tree | 5c9e0e18a14f2a222873644e3d10dbb2273f0c0b /usr.bin | |
parent | 863ee4199c2cdc0c4c71deff86857e9f2bb90ebe (diff) | |
download | FreeBSD-src-c1d0f70dee4de285a39f098ba26240829e19ea6d.zip FreeBSD-src-c1d0f70dee4de285a39f098ba26240829e19ea6d.tar.gz |
Variables that come in in and out pairs should be named accordingly.
Different code that processes the input in similar ways should be
called in similar ways. File-local stuff should be static. Output
errors should be checked for. Diffs sometimes have to be big.
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/uudecode/uudecode.c | 152 |
1 files changed, 84 insertions, 68 deletions
diff --git a/usr.bin/uudecode/uudecode.c b/usr.bin/uudecode/uudecode.c index 95046ae..3b30be1 100644 --- a/usr.bin/uudecode/uudecode.c +++ b/usr.bin/uudecode/uudecode.c @@ -68,15 +68,15 @@ __FBSDID("$FreeBSD$"); #include <string.h> #include <unistd.h> -const char *filename; -char *outfile; -FILE *infp, *outfp; -int cflag, iflag, oflag, pflag, sflag; +static const char *infile, *outfile; +static FILE *infp, *outfp; +static int cflag, iflag, oflag, pflag, sflag; -static void usage(void); -int decode(void); -int decode2(void); -int base64_decode(const char *); +static void usage(void); +static int decode(void); +static int decode2(void); +static int uu_decode(void); +static int base64_decode(void); int main(int argc, char *argv[]) @@ -120,7 +120,7 @@ main(int argc, char *argv[]) if (*argv) { rval = 0; do { - infp = fopen(filename = *argv, "r"); + infp = fopen(infile = *argv, "r"); if (infp == NULL) { warn("%s", *argv); rval = 1; @@ -130,21 +130,21 @@ main(int argc, char *argv[]) fclose(infp); } while (*++argv); } else { - filename = "stdin"; + infile = "stdin"; infp = stdin; rval = decode(); } exit(rval); } -int +static int decode(void) { int r, v; v = decode2(); if (v == EOF) { - warnx("%s: missing or bad \"begin\" line", filename); + warnx("%s: missing or bad \"begin\" line", infile); return (1); } for (r = v; cflag; r |= v) { @@ -155,17 +155,16 @@ decode(void) return (r); } -int +static int decode2(void) { - int base64, i; - size_t n; - char ch, *p, *q; - void *mode; + int base64, flags, fd, mode; + size_t n, m; + char *p, *q; + void *handle; struct passwd *pw; struct stat st; char buf[MAXPATHLEN+1]; - char buffn[MAXPATHLEN+1]; /* file name buffer */ base64 = 0; /* search for header line */ @@ -194,16 +193,15 @@ decode2(void) break; } - mode = setmode(p); - if (mode == NULL) { - warnx("%s: unable to parse file mode", filename); + handle = setmode(p); + if (handle == NULL) { + warnx("%s: unable to parse file mode", infile); return (1); } + mode = getmode(handle, 0) & 0666; + free(handle); - if (oflag) { - /* use command-line filename */ - n = strlcpy(buffn, outfile, sizeof(buffn)); - } else if (sflag) { + if (sflag) { /* don't strip, so try ~user/file expansion */ p = NULL; pw = NULL; @@ -215,43 +213,47 @@ decode2(void) *p = '/'; } if (pw != NULL) { - strlcpy(buffn, pw->pw_dir, sizeof(buffn)); - n = strlcat(buffn, p, sizeof(buffn)); - } else { - n = strlcpy(buffn, q, sizeof(buffn)); + n = strlen(pw->pw_dir); + if (buf + n > p) { + /* make room */ + m = strlen(p); + if (sizeof(buf) < n + m) { + warnx("%s: bad output filename", + infile); + return (1); + } + p = memmove(buf + n, p, m); + } + q = memcpy(p - n, pw->pw_dir, n); } } else { /* strip down to leaf name */ p = strrchr(q, '/'); if (p != NULL) - n = strlcpy(buffn, p+1, sizeof(buffn)); - else - n = strlcpy(buffn, q, sizeof(buffn)); - } - if (n >= sizeof(buffn) || *buffn == '\0') { - warnx("%s: bad output filename", filename); - return (1); + q = p + 1; } + if (!oflag) + outfile = q; if (pflag) outfp = stdout; else { - int flags = O_WRONLY|O_CREAT|O_EXCL; - if (lstat(buffn, &st) == 0) { + flags = O_WRONLY|O_CREAT|O_EXCL; + if (lstat(outfile, &st) == 0) { if (iflag) { - warnc(EEXIST, "%s: %s", filename, buffn); + warnc(EEXIST, "%s: %s", infile, outfile); return (0); } switch (st.st_mode & S_IFMT) { case S_IFREG: case S_IFLNK: /* avoid symlink attacks */ - if (unlink(buffn) == 0 || errno == ENOENT) + if (unlink(outfile) == 0 || errno == ENOENT) break; - warn("%s: unlink %s", filename, buffn); + warn("%s: unlink %s", infile, outfile); return (1); case S_IFDIR: - warnc(EISDIR, "%s: %s", filename, buffn); + warnc(EISDIR, "%s: %s", infile, outfile); return (1); default: if (oflag) { @@ -259,28 +261,37 @@ decode2(void) flags &= ~O_EXCL; break; } - warnc(EEXIST, "%s: %s", filename, buffn); + warnc(EEXIST, "%s: %s", infile, outfile); return (1); } } else if (errno != ENOENT) { - warn("%s: %s", filename, buffn); + warn("%s: %s", infile, outfile); return (1); } - if ((i = open(buffn, flags, getmode(mode, 0) & 0666)) < 0 || - (outfp = fdopen(i, "w")) == NULL) { - warn("%s: %s", filename, buffn); + if ((fd = open(outfile, flags, mode)) < 0 || + (outfp = fdopen(fd, "w")) == NULL) { + warn("%s: %s", infile, outfile); return (1); } } - free(mode); if (base64) - return (base64_decode(buffn)); + return (base64_decode()); + else + return (uu_decode()); +} + +static int +uu_decode(void) +{ + int i, ch; + char *p; + char buf[MAXPATHLEN+1]; /* for each input line */ for (;;) { if (fgets(p = buf, sizeof(buf), infp) == NULL) { - warnx("%s: short file", filename); + warnx("%s: short file", infile); return (1); } @@ -289,7 +300,7 @@ decode2(void) #define OUT_OF_RANGE do { \ warnx("%s: %s: character out of range: [%d-%d]", \ - filename, buffn, 1 + ' ', 077 + ' ' + 1); \ + infile, outfile, 1 + ' ', 077 + ' ' + 1); \ return (1); \ } while (0) @@ -339,41 +350,46 @@ decode2(void) if (fgets(buf, sizeof(buf), infp) == NULL || (strcmp(buf, "end") && strcmp(buf, "end\n") && strcmp(buf, "end\r\n"))) { - warnx("%s: no \"end\" line", filename); + warnx("%s: no \"end\" line", infile); return (1); } if (fclose(outfp) != 0) { - warnx("%s: %s", filename, buffn); + warnx("%s: %s", infile, outfile); return (1); } return (0); } -int -base64_decode(const char *outname) +static int +base64_decode(void) { int n; - char buf[MAXPATHLEN+1]; - unsigned char out[MAXPATHLEN * 4]; + char inbuf[MAXPATHLEN+1]; + unsigned char outbuf[MAXPATHLEN * 4]; for (;;) { - if (fgets(buf, sizeof(buf), infp) == NULL) { - warnx("%s: short file", filename); + if (fgets(inbuf, sizeof(inbuf), infp) == NULL) { + warnx("%s: short file", infile); return (1); } - if (strcmp(buf, "====") == 0 || - strcmp(buf, "====\n") == 0 || - strcmp(buf, "====\r\n") == 0) + if (strcmp(inbuf, "====") == 0 || + strcmp(inbuf, "====\n") == 0 || + strcmp(inbuf, "====\r\n") == 0) { + if (fclose(outfp) != 0) { + warnx("%s: %s", infile, outfile); + return (1); + } return (0); - n = strlen(buf); - while (n > 0 && (buf[n-1] == '\n' || buf[n-1] == '\r')) - buf[--n] = '\0'; - n = b64_pton(buf, out, sizeof(out)); + } + n = strlen(inbuf); + while (n > 0 && (inbuf[n-1] == '\n' || inbuf[n-1] == '\r')) + inbuf[--n] = '\0'; + n = b64_pton(inbuf, outbuf, sizeof(outbuf)); if (n < 0) { - warnx("%s: %s: error decoding base64 input stream", filename, outname); + warnx("%s: %s: error decoding base64 input stream", infile, outfile); return (1); } - fwrite(out, 1, n, outfp); + fwrite(outbuf, 1, n, outfp); } } |