Module Name:    src
Committed By:   apb
Date:           Mon Jan 28 16:06:42 UTC 2013

Modified Files:
        src/usr.bin/uudecode: uudecode.c

Log Message:
* Add "-o outfile" option.  This is reauired by POSIX.1-2008.
* Recognise "/dev/stdout" as a magic filename, both when embedded in the
  data stream and when specified via "-o".  This is also required by
  POSIX.1-2008.
* Reimplement "-p" as an alias for "-o /dev/stdout".

Thanks to Steffen Daode Nurpmeso for drawing my attention to the problems.


To generate a diff of this commit:
cvs rdiff -u -r1.26 -r1.27 src/usr.bin/uudecode/uudecode.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.bin/uudecode/uudecode.c
diff -u src/usr.bin/uudecode/uudecode.c:1.26 src/usr.bin/uudecode/uudecode.c:1.27
--- src/usr.bin/uudecode/uudecode.c:1.26	Tue Sep  6 18:44:26 2011
+++ src/usr.bin/uudecode/uudecode.c	Mon Jan 28 16:06:42 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: uudecode.c,v 1.26 2011/09/06 18:44:26 joerg Exp $	*/
+/*	$NetBSD: uudecode.c,v 1.27 2013/01/28 16:06:42 apb Exp $	*/
 
 /*-
  * Copyright (c) 1983, 1993
@@ -40,7 +40,7 @@ __COPYRIGHT("@(#) Copyright (c) 1983, 19
 #if 0
 static char sccsid[] = "@(#)uudecode.c	8.2 (Berkeley) 4/2/94";
 #endif
-__RCSID("$NetBSD: uudecode.c,v 1.26 2011/09/06 18:44:26 joerg Exp $");
+__RCSID("$NetBSD: uudecode.c,v 1.27 2013/01/28 16:06:42 apb Exp $");
 #endif /* not lint */
 
 /*
@@ -67,30 +67,33 @@ __RCSID("$NetBSD: uudecode.c,v 1.26 2011
 #include <resolv.h>
 #endif
 
-static int decode(void);
+static int decode(char *);
 __dead static void usage(void);
 static int checkend(const char *, const char *, const char *);
 static int base64_decode(void);
 
-static int base64, pflag;
-static const char *filename;
+static int base64;
+static const char *inputname;
 
 int
 main(int argc, char *argv[])
 {
 	int ch, rval;
+	char *outputname = NULL;
 
 	setlocale(LC_ALL, "");
 	setprogname(argv[0]);
 
-	pflag = 0;
-	while ((ch = getopt(argc, argv, "mp")) != -1)
+	while ((ch = getopt(argc, argv, "mo:p")) != -1)
 		switch (ch) {
 		case 'm':
 			base64 = 1;
 			break;
+		case 'o':
+			outputname = optarg;
+			break;
 		case 'p':
-			pflag = 1;
+			outputname = __UNCONST("/dev/stdout");
 			break;
 		default:
 			usage();
@@ -101,22 +104,26 @@ main(int argc, char *argv[])
 	if (*argv) {
 		rval = 0;
 		do {
-			if (!freopen(filename = *argv, "r", stdin)) {
+			if (!freopen(inputname = *argv, "r", stdin)) {
 				warn("%s", *argv);
 				rval = 1;
 				continue;
 			}
-			rval |= decode();
+			rval |= decode(outputname);
 		} while (*++argv);
 	} else {
-		filename = "stdin";
-		rval = decode();
+		inputname = "stdin";
+		rval = decode(outputname);
 	}
 	exit(rval);
 }
 
+/*
+ * Decode one file from stdin.  If outputname is not NULL
+ * then it overrides the file name embedded in the input data.
+ */
 static int
-decode(void)
+decode(char *outputname)
 {
 	struct passwd *pw;
 	int n;
@@ -129,7 +136,7 @@ decode(void)
 	/* search for header line */
 	for (;;) {
 		if (!fgets(buf, sizeof(buf), stdin)) {
-			warnx("%s: no \"%s\" line", filename, base64 ? 
+			warnx("%s: no \"%s\" line", inputname, base64 ? 
 					"begin-base64" : "begin");
 			return(1);
 		}
@@ -149,14 +156,14 @@ decode(void)
 	mode = strtol(p, &fn, 8);
 	if (fn == (p) || !isspace((unsigned char)*fn) || mode==LONG_MIN || mode==LONG_MAX)
 	{
-	        warnx("%s: invalid mode on \"%s\" line", filename,
+	        warnx("%s: invalid mode on \"%s\" line", inputname,
 			base64 ? "begin-base64" : "begin");
 		return(1);
 	}
 	/* skip whitespace for file name */
 	while (*fn && isspace((unsigned char)*fn)) fn++;
 	if (*fn == 0) {
-                warnx("%s: no filename on \"%s\" line", filename,
+                warnx("%s: no filename on \"%s\" line", inputname,
 			base64 ? "begin-base64" : "begin");
 		return(1);
 	}
@@ -164,22 +171,26 @@ decode(void)
 	for (p = fn; *p && *p != '\n'; p++) 
 	        ;
 	if (*p) *p = 0;
+
+	/* outputname overrides fn */
+	if (outputname)
+		fn = outputname;
 	
 	/* handle ~user/file format */
 	if (*fn == '~') {
 		if (!(p = strchr(fn, '/'))) {
-			warnx("%s: illegal ~user.", filename);
+			warnx("%s: illegal ~user.", inputname);
 			return(1);
 		}
 		*p++ = '\0';
 		if (!(pw = getpwnam(fn + 1))) {
-			warnx("%s: no user %s.", filename, buf);
+			warnx("%s: no user %s.", inputname, buf);
 			return(1);
 		}
 		n = strlen(pw->pw_dir);
 		n1 = strlen(p);
 		if (n + n1 + 2 > MAXPATHLEN) {
-			warnx("%s: path too long.", filename);
+			warnx("%s: path too long.", inputname);
 			return(1);
 		}
 		/* make space at beginning of buf by moving end of pathname */
@@ -189,11 +200,15 @@ decode(void)
 		fn = buf;
 	}
 
-	/* create output file, set mode */
-	if (!pflag && (!freopen(fn, "w", stdout) ||
-	    fchmod(fileno(stdout), mode & 0666))) { 
-		warn("%s: %s", fn, filename);
-		return(1);
+	if (strcmp(fn, "/dev/stdout") == 0) {
+		/* use stdout */
+	} else {
+		/* create output file, set mode */
+		if (freopen(fn, "w", stdout) == NULL ||
+		    fchmod(fileno(stdout), mode & 0666) != 0) { 
+			warn("%s: %s", fn, inputname);
+			return(1);
+		}
 	}
 
 	if (base64)
@@ -202,7 +217,7 @@ decode(void)
 		/* for each input line */
 		for (;;) {
 			if (!fgets(p = buf, sizeof(buf), stdin)) {
-				warnx("%s: short file.", filename);
+				warnx("%s: short file.", inputname);
 				return(1);
 			}
 #define	DEC(c)	(((c) - ' ') & 077)		/* single character decode */
@@ -237,7 +252,7 @@ decode(void)
 				}
 		}
 		if (!fgets(buf, sizeof(buf), stdin) || strcmp(buf, "end\n")) {
-			warnx("%s: no \"end\" line.", filename);
+			warnx("%s: no \"end\" line.", inputname);
 			return(1);
 		}
 		return(0);
@@ -267,11 +282,11 @@ base64_decode(void)
 
 	for (;;) {
 		if (!fgets(inbuf, sizeof(inbuf), stdin)) {
-			warnx("%s: short file.", filename);
+			warnx("%s: short file.", inputname);
 			return (1);
 		}
 #ifdef NO_BASE64
-		warnx("%s: base64 decoding is not supported", filename);
+		warnx("%s: base64 decoding is not supported", inputname);
 		return (1);
 #else
 		n = b64_pton(inbuf, outbuf, sizeof(outbuf));
@@ -287,7 +302,8 @@ base64_decode(void)
 static void
 usage(void)
 {
-	(void)fprintf(stderr, "usage: %s [-m | -p] [encoded-file ...]\n",
+	(void)fprintf(stderr,
+		      "usage: %s [-m] [-p | -o outfile] [encoded-file ...]\n",
 		      getprogname());
 	exit(1);
 }

Reply via email to