fix and shrink uuencode
authorTim Riker <tim@rikers.org>
Wed, 1 May 2002 05:57:16 +0000 (05:57 -0000)
committerTim Riker <tim@rikers.org>
Wed, 1 May 2002 05:57:16 +0000 (05:57 -0000)
Changelog
coreutils/uuencode.c

index aa4cd401af452ebfaed392cb75604b4541ffac67..7ff9f9e323d1eea30bc9594b1162f53409bffe45 100644 (file)
--- a/Changelog
+++ b/Changelog
@@ -32,6 +32,8 @@
                applets, fix print nslookup server name if compile without
                uClibc, fix route crashe 'route add', fix warnings compile
                networking and pwd_grp applets
+       * Tim Riker <Tim@Rikers.org>
+               -- fix and shrink uuencode
 
         -Erik Andersen, --not yet released--
 
index 0a362a2622f5ed3d22df906d7151097f531a9b4d..24b9f1c6ae2ae3433b8f9a0a69443bba6a8ac5ac 100644 (file)
@@ -28,7 +28,7 @@
 #include "busybox.h"
 
 /* Conversion table.  for base 64 */
-static char tbl_base64[64] = {
+static char tbl_base64[65] = {
        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
        'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
        'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
@@ -36,10 +36,11 @@ static char tbl_base64[64] = {
        'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
        'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
        'w', 'x', 'y', 'z', '0', '1', '2', '3',
-       '4', '5', '6', '7', '8', '9', '+', '/'
+       '4', '5', '6', '7', '8', '9', '+', '/',
+       '=' /* termination character */
 };
 
-static char tbl_std[64] = {
+static char tbl_std[65] = {
        '`', '!', '"', '#', '$', '%', '&', '\'',
        '(', ')', '*', '+', ',', '-', '.', '/',
        '0', '1', '2', '3', '4', '5', '6', '7',
@@ -47,7 +48,8 @@ static char tbl_std[64] = {
        '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
        'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
        'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
-       'X', 'Y', 'Z', '[', '\\', ']', '^', '_'
+       'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
+       '\`' /* termination character */
 };
 
 /*
@@ -71,10 +73,10 @@ static void uuencode (const char *s, const char *store, const int length, const
        }
        /* Pad the result if necessary...  */
        if (i == length + 1) {
-               *(p - 1) = '=';
+               *(p - 1) = tbl[64];
        }
        else if (i == length + 2) {
-               *(p - 1) = *(p - 2) = '=';
+               *(p - 1) = *(p - 2) = tbl[64];
        }
        /* ...and zero-terminate it.  */
        *p = '\0';
@@ -82,8 +84,9 @@ static void uuencode (const char *s, const char *store, const int length, const
 
 int uuencode_main(int argc, char **argv)
 {
-       const int src_buf_size = 60;    // This *MUST* be a multiple of 3
+       const int src_buf_size = 45;// This *MUST* be a multiple of 3
        const int dst_buf_size = 4 * ((src_buf_size + 2) / 3);
+       int write_size = dst_buf_size;
        RESERVE_CONFIG_BUFFER(src_buf, src_buf_size + 1);
        RESERVE_CONFIG_BUFFER(dst_buf, dst_buf_size + 1);
        struct stat stat_buf;
@@ -92,10 +95,6 @@ int uuencode_main(int argc, char **argv)
        size_t size;
        mode_t mode;
        int opt;
-       int column = 0;
-       int write_size = 0;
-       int remaining;
-       int buffer_offset = 0;
 
        while ((opt = getopt(argc, argv, "m")) != -1) {
                switch (opt) {
@@ -126,53 +125,22 @@ int uuencode_main(int argc, char **argv)
        printf("begin%s %o %s", tbl == tbl_std ? "" : "-base64", mode, argv[argc - 1]);
 
        while ((size = fread(src_buf, 1, src_buf_size, src_stream)) > 0) {
+               if (size != src_buf_size) {
+                       /* write_size is always 60 until the last line */
+                       write_size=(4 * ((size + 2) / 3));
+                       /* pad with 0s so we can just encode extra bits */
+                       memset(&src_buf[size], 0, src_buf_size - size);
+               }
                /* Encode the buffer we just read in */
                uuencode(src_buf, dst_buf, size, tbl);
 
-               /* Write the buffer to stdout, wrapping at 60 chars.
-                * This looks overly complex, but it gets tricky as
-                * the line has to continue to wrap correctly if we
-                * have to refill the buffer
-                *
-                * Improvments most welcome
-                */
-
-               /* Initialise values for the new buffer */
-               remaining = 4 * ((size + 2) / 3);
-               buffer_offset = 0;
-
-               /* Write the buffer to stdout, wrapping at 60 chars
-                * starting from the column the last buffer ran out
-                */
-               do {
-                       if (remaining > (60 - column)) {
-                               write_size = 60 - column;
-                       }
-                       else if (remaining < 60) {
-                               write_size = remaining;
-                       } else {
-                               write_size = 60;
-                       }
-
-                       /* Setup a new row if required */
-                       if (column == 0) {
-                               putchar('\n');
-                               if (tbl == tbl_std) {
-                                       putchar('M');
-                               }
-                       }
-                       /* Write to the 60th column */
-                       if (fwrite(&dst_buf[buffer_offset], 1, write_size, stdout) != write_size) {
-                               perror("Couldnt finish writing");
-                       }
-                       /* Update variables based on last write */
-                       buffer_offset += write_size;
-                       remaining -= write_size;
-                       column += write_size;
-                       if (column % 60 == 0) {
-                               column = 0;
-                       }
-               } while (remaining > 0);
+               putchar('\n');
+               if (tbl == tbl_std) {
+                       putchar(tbl[size]);
+               }
+               if (fwrite(dst_buf, 1, write_size, stdout) != write_size) {
+                       perror("Couldnt finish writing");
+               }
        }
        printf(tbl == tbl_std ? "\n`\nend\n" : "\n====\n");