summaryrefslogtreecommitdiffstats
path: root/usr.bin
diff options
context:
space:
mode:
authorjmallett <jmallett@FreeBSD.org>2002-03-05 03:27:47 +0000
committerjmallett <jmallett@FreeBSD.org>2002-03-05 03:27:47 +0000
commitce51fff754f20521ce32eaf888c654ec967b9781 (patch)
tree650de0ad3b3660ee3fa7b3cd64021350aebe479b /usr.bin
parent66d03d29ff7c7e5018ff773f7ce2a36c67ee067d (diff)
downloadFreeBSD-src-ce51fff754f20521ce32eaf888c654ec967b9781.zip
FreeBSD-src-ce51fff754f20521ce32eaf888c654ec967b9781.tar.gz
Add base64 support to uuencode(1) and uudecode(1), as specified by SUSv3.
Add `-o' option to uuencode(1) to pipe the uuencoded output to an arbitrary file, instead of just stdout. Reviewed by: -standards, mike Approved by: mike
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/uudecode/uudecode.c49
-rw-r--r--usr.bin/uuencode/uuencode.121
-rw-r--r--usr.bin/uuencode/uuencode.c98
3 files changed, 139 insertions, 29 deletions
diff --git a/usr.bin/uudecode/uudecode.c b/usr.bin/uudecode/uudecode.c
index 3630427..b0cc073 100644
--- a/usr.bin/uudecode/uudecode.c
+++ b/usr.bin/uudecode/uudecode.c
@@ -52,11 +52,14 @@ static const char rcsid[] =
* used with uuencode.
*/
#include <sys/param.h>
+#include <sys/socket.h>
#include <sys/stat.h>
+#include <netinet/in.h>
+
#include <err.h>
-#include <fnmatch.h>
#include <pwd.h>
+#include <resolv.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -69,6 +72,7 @@ int cflag, iflag, oflag, pflag, sflag;
static void usage __P((void));
int decode __P((void));
int decode2 __P((int));
+void base64_decode __P((const char *));
int
main(argc, argv)
@@ -155,11 +159,11 @@ decode2(flag)
struct passwd *pw;
register int n;
register char ch, *p;
- int ignore, mode, n1;
+ int base64, ignore, mode, n1;
char buf[MAXPATHLEN];
char buffn[MAXPATHLEN]; /* file name buffer */
- ignore = 0;
+ base64 = ignore = 0;
/* search for header line */
do {
if (!fgets(buf, sizeof(buf), stdin)) {
@@ -169,17 +173,26 @@ decode2(flag)
warnx("%s: no \"begin\" line", filename);
return(1);
}
- } while (strncmp(buf, "begin ", 6) ||
- fnmatch("begin [0-7]* *", buf, 0));
+ } while (strncmp(buf, "begin", 5) != 0);
+
+ if (strncmp(buf, "begin-base64", 12) == 0)
+ base64 = 1;
if (oflag) {
- (void)sscanf(buf, "begin %o ", &mode);
+ if (base64)
+ (void)sscanf(buf, "begin-base64 %o ", &mode);
+ else
+ (void)sscanf(buf, "begin %o ", &mode);
if (strlcpy(buf, outfile, sizeof(buf)) >= sizeof(buf)) {
warnx("%s: filename too long", outfile);
return (1);
}
- } else
- (void)sscanf(buf, "begin %o %[^\n\r]", &mode, buf);
+ } else {
+ if (base64)
+ (void)sscanf(buf, "begin-base64 %o %[^\n\r]", &mode, buf);
+ else
+ (void)sscanf(buf, "begin %o %[^\n\r]", &mode, buf);
+ }
if (!sflag && !pflag) {
strncpy(buffn, buf, sizeof(buffn));
@@ -230,11 +243,18 @@ decode2(flag)
strcpy(buffn, buf); /* store file name from header line */
/* for each input line */
+next:
for (;;) {
if (!fgets(p = buf, sizeof(buf), stdin)) {
warnx("%s: short file", filename);
return(1);
}
+ if (base64) {
+ if (strncmp(buf, "====", 4) == 0)
+ return (0);
+ base64_decode(buf);
+ goto next;
+ }
#define DEC(c) (((c) - ' ') & 077) /* single character decode */
#define IS_DEC(c) ( (((c) - ' ') >= 0) && (((c) - ' ') <= 077 + 1) )
/* #define IS_DEC(c) (1) */
@@ -304,6 +324,19 @@ if (!ignore) \
return(0);
}
+void
+base64_decode(stream)
+ const char *stream;
+{
+ unsigned char out[MAXPATHLEN * 4];
+ int rv;
+
+ rv = b64_pton(stream, out, (sizeof(out) / sizeof(out[0])));
+ if (rv == -1)
+ errx(1, "b64_pton: error decoding base64 input stream");
+ printf("%s", out);
+}
+
static void
usage()
{
diff --git a/usr.bin/uuencode/uuencode.1 b/usr.bin/uuencode/uuencode.1
index b348143..0d4cfe4 100644
--- a/usr.bin/uuencode/uuencode.1
+++ b/usr.bin/uuencode/uuencode.1
@@ -41,6 +41,8 @@
.Nd encode/decode a binary file
.Sh SYNOPSIS
.Nm
+.Op Fl m
+.Op Fl o Ar output_file
.Op Ar file
.Ar name
.Nm uudecode
@@ -63,7 +65,9 @@ data.
reads
.Ar file
(or by default the standard input) and writes an encoded version
-to the standard output.
+to the standard output, or
+.Ar output_file
+if one has been specified.
The encoding uses only printing
.Tn ASCII
characters and includes the
@@ -86,7 +90,20 @@ and execute bits are not retained.
.Nm Uudecode
ignores any leading and trailing lines.
.Pp
-The following options are available for
+The following options are available:
+.Pp
+.Nm uuencode :
+.Bl -tag -width ident
+.It Fl m
+Use the Base64 method of encoding, rather than the traditional
+.Nm
+algorithm.
+.It Fl o Ar output_file
+Output to
+.Ar output_file
+instead of standard output.
+.El
+.Pp
.Nm uudecode :
.Bl -tag -width ident
.It Fl c
diff --git a/usr.bin/uuencode/uuencode.c b/usr.bin/uuencode/uuencode.c
index d85c7f1..64a279c 100644
--- a/usr.bin/uuencode/uuencode.c
+++ b/usr.bin/uuencode/uuencode.c
@@ -50,27 +50,53 @@ static const char rcsid[] =
*
* Encode a file so it can be mailed to a remote system.
*/
-#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
#include <sys/stat.h>
+#include <netinet/in.h>
+
#include <err.h>
+#include <resolv.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
void encode __P((void));
+void base64_encode __P((void));
static void usage __P((void));
+FILE *output = stdout;
+int mode;
+char **av;
+
int
main(argc, argv)
int argc;
char *argv[];
{
struct stat sb;
- int mode;
+ int base64;
+ char ch;
+ char *outfile;
- while (getopt(argc, argv, "") != -1)
- usage();
+ base64 = 0;
+ outfile = NULL;
+
+ while ((ch = getopt(argc, argv, "mo:")) != -1) {
+ switch (ch) {
+ case 'm':
+ base64 = 1;
+ break;
+ case 'o':
+ outfile = optarg;
+ break;
+ case '?':
+ default:
+ usage();
+ }
+ }
argv += optind;
argc -= optind;
@@ -91,10 +117,18 @@ main(argc, argv)
usage();
}
- (void)printf("begin %o %s\n", mode, *argv);
- encode();
- (void)printf("end\n");
- if (ferror(stdout))
+ av = argv;
+
+ if (outfile != NULL) {
+ output = fopen(outfile, "w+");
+ if (output == NULL)
+ err(1, "unable to open %s for output", outfile);
+ }
+ if (base64)
+ base64_encode();
+ else
+ encode();
+ if (ferror(output))
errx(1, "write error");
exit(0);
}
@@ -103,7 +137,34 @@ main(argc, argv)
#define ENC(c) ((c) ? ((c) & 077) + ' ': '`')
/*
- * copy from in to out, encoding as you go along.
+ * Copy from in to out, encoding in base64 as you go along.
+ */
+void
+base64_encode()
+{
+#define GROUPS 8 /* Group output chunks */
+ unsigned char buf[6];
+ char buf2[16];
+ size_t n;
+ int rv, sequence;
+
+ sequence = 0;
+
+ fprintf(output, "begin-base64 %o %s\n", mode, *av);
+ while ((n = fread(buf, 1, sizeof(buf), stdin))) {
+ ++sequence;
+ rv = b64_ntop(buf, n, buf2, (sizeof(buf2) / sizeof(buf2[0])));
+ if (rv == -1)
+ errx(1, "b64_ntop: error encoding base64");
+ fprintf(output, "%s%s", buf2, (sequence % GROUPS) ? "" : "\n");
+ }
+ if (sequence % GROUPS)
+ fprintf(output, "\n");
+ fprintf(output, "====\n");
+}
+
+/*
+ * Copy from in to out, encoding as you go along.
*/
void
encode()
@@ -112,9 +173,10 @@ encode()
register char *p;
char buf[80];
+ (void)fprintf(output, "begin %o %s\n", mode, *av);
while ((n = fread(buf, 1, 45, stdin))) {
ch = ENC(n);
- if (putchar(ch) == EOF)
+ if (fputc(ch, output) == EOF)
break;
for (p = buf; n > 0; n -= 3, p += 3) {
/* Pad with nulls if not a multiple of 3. */
@@ -125,34 +187,32 @@ encode()
}
ch = *p >> 2;
ch = ENC(ch);
- if (putchar(ch) == EOF)
+ if (fputc(ch, output) == EOF)
break;
ch = ((*p << 4) & 060) | ((p[1] >> 4) & 017);
ch = ENC(ch);
- if (putchar(ch) == EOF)
+ if (fputc(ch, output) == EOF)
break;
ch = ((p[1] << 2) & 074) | ((p[2] >> 6) & 03);
ch = ENC(ch);
- if (putchar(ch) == EOF)
+ if (fputc(ch, output) == EOF)
break;
ch = p[2] & 077;
ch = ENC(ch);
- if (putchar(ch) == EOF)
+ if (fputc(ch, output) == EOF)
break;
}
- if (putchar('\n') == EOF)
+ if (fputc('\n', output) == EOF)
break;
}
if (ferror(stdin))
errx(1, "read error");
- ch = ENC('\0');
- (void)putchar(ch);
- (void)putchar('\n');
+ (void)fprintf(output, "%c\nend\n", ENC('\0'));
}
static void
usage()
{
- (void)fprintf(stderr,"usage: uuencode [infile] remotefile\n");
+ (void)fprintf(stderr,"usage: uuencode [-m] [-o outfile] [infile] remotefile\n");
exit(1);
}
OpenPOWER on IntegriCloud