Index: usr.bin/uuencode/uuencode.1 =================================================================== --- usr.bin/uuencode/uuencode.1 +++ usr.bin/uuencode/uuencode.1 @@ -52,6 +52,7 @@ .Fl o Ar output_file .Nm b64encode .Op Fl r +.Op Fl w Ar column .Op Fl o Ar output_file .Op Ar file .Ar name @@ -176,6 +177,15 @@ deletes any prefix ending with the last slash '/' for security reasons. .El +.Pp +Additionally, +.Nm b64encode +accepts the following option: +.Bl -tag -width ident +.It Fl w Ar column +Wrap encoded output after +.Ar column . +.El .Sh EXAMPLES The following example packages up a source tree, compresses it, uuencodes it and mails it to a user on another system. Index: usr.bin/uuencode/uuencode.c =================================================================== --- usr.bin/uuencode/uuencode.c +++ usr.bin/uuencode/uuencode.c @@ -55,6 +55,7 @@ #include #include +#include #include #include #include @@ -73,6 +74,7 @@ static int mode; static bool raw; static char **av; +static int columns = 76; int main_encode(int argc, char *argv[]) @@ -88,7 +90,10 @@ if (strcmp(basename(argv[0]), "b64encode") == 0) base64 = 1; - while ((ch = getopt(argc, argv, "mo:r")) != -1) { + while ((ch = getopt(argc, argv, "mo:rw:")) != -1) { + char *ep; + long optarg_long; + switch (ch) { case 'm': base64 = 1; @@ -99,6 +104,22 @@ case 'r': raw = 1; break; + case 'w': + errno = 0; + optarg_long = strtol(optarg, &ep, 10); + if (optarg_long > INT_MAX) + errno = ERANGE; + if (errno == ERANGE || errno == EINVAL) + err(2, NULL); + else if (ep[0] != '\0') { + errno = EINVAL; + err(2, NULL); + } else if (columns < 0) { + errno = EINVAL; + err(2, "columns argument must be non-negative"); + } + columns = optarg_long; + break; case '?': default: usage(); @@ -150,28 +171,33 @@ static void base64_encode(void) { - /* - * Output must fit into 80 columns, chunks come in 4, leave 1. - */ -#define GROUPS ((80 / 4) - 1) - unsigned char buf[3]; + unsigned char buf[1023]; char buf2[sizeof(buf) * 2 + 1]; size_t n; - int rv, sequence; - - sequence = 0; + unsigned carry = 0; + int rv, written; if (!raw) fprintf(output, "begin-base64 %o %s\n", mode, *av); while ((n = fread(buf, 1, sizeof(buf), stdin))) { - ++sequence; rv = b64_ntop(buf, n, buf2, nitems(buf2)); if (rv == -1) errx(1, "b64_ntop: error encoding base64"); - fprintf(output, "%s%s", buf2, (sequence % GROUPS) ? "" : "\n"); + if (columns == 0) { + fputs(buf2, output); + continue; + } + for (int i = 0; i < rv; i += written) { + written = fprintf(output, "%.*s", columns - carry, + &buf2[i]); + + carry = (carry + written) % columns; + if (carry == 0) + fputc('\n', output); + } } - if (sequence % GROUPS) - fprintf(output, "\n"); + if (columns == 0 || carry != 0) + fputc('\n', output); if (!raw) fprintf(output, "====\n"); }