uudecode: fix to base64 decode by Jorgen Cederlof <jcz@google.com>
authorDenis Vlasenko <vda.linux@googlemail.com>
Mon, 4 Jun 2007 23:32:35 +0000 (23:32 -0000)
committerDenis Vlasenko <vda.linux@googlemail.com>
Mon, 4 Jun 2007 23:32:35 +0000 (23:32 -0000)
improved help texts

# make bloatcheck
function                                             old     new   delta
.rodata                                           127000  127032     +32
packed_usage                                       22156   22151      -5
uudecode_main                                        360     348     -12
uuencode_main                                        490     468     -22
read_base64                                          283     254     -29
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/4 up/down: 32/-68)            Total: -36 bytes

coreutils/uudecode.c
coreutils/uuencode.c
include/usage.h

index 779710edda07e6e6ad2c6edc0d6997e914f15e89..287386d9dee990e0c296644e4aaa077b72c51e79 100644 (file)
@@ -70,7 +70,7 @@ static void read_base64(FILE *src_stream, FILE *dst_stream)
 {
        static const char base64_table[] =
                "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n";
-       int term_count = 0;
+       int term_count = 1;
 
        while (1) {
                char translated[4];
@@ -86,19 +86,19 @@ static void read_base64(FILE *src_stream, FILE *dst_stream)
                                if (ch == EOF) {
                                        bb_error_msg_and_die("short file");
                                }
-                       } while ((table_ptr = strchr(base64_table, ch)) == NULL);
+                               table_ptr = strchr(base64_table, ch);
+                       } while (table_ptr == NULL);
 
                        /* Convert encoded charcter to decimal */
                        ch = table_ptr - base64_table;
 
                        if (*table_ptr == '=') {
                                if (term_count == 0) {
-                                       translated[count] = 0;
+                                       translated[count] = '\0';
                                        break;
                                }
                                term_count++;
-                       }
-                       else if (*table_ptr == '\n') {
+                       } else if (*table_ptr == '\n') {
                                /* Check for terminating line */
                                if (term_count == 5) {
                                        return;
@@ -113,7 +113,9 @@ static void read_base64(FILE *src_stream, FILE *dst_stream)
                }
 
                /* Merge 6 bit chars to 8 bit */
-           fputc(translated[0] << 2 | translated[1] >> 4, dst_stream);
+               if (count > 1) {
+                       fputc(translated[0] << 2 | translated[1] >> 4, dst_stream);
+               }
                if (count > 2) {
                        fputc(translated[1] << 4 | translated[2] >> 2, dst_stream);
                }
@@ -126,19 +128,16 @@ static void read_base64(FILE *src_stream, FILE *dst_stream)
 int uudecode_main(int argc, char **argv);
 int uudecode_main(int argc, char **argv)
 {
-       FILE *src_stream;
+       FILE *src_stream = stdin;
        char *outname = NULL;
        char *line;
 
+       opt_complementary = "?1"; /* 1 argument max */
        getopt32(argc, argv, "o:", &outname);
+       argv += optind;
 
-       if (optind == argc) {
-               src_stream = stdin;
-       } else if (optind + 1 == argc) {
-               src_stream = xfopen(argv[optind], "r");
-       } else {
-               bb_show_usage();
-       }
+       if (argv[0])
+               src_stream = xfopen(argv[0], "r");
 
        /* Search for the start of the encoding */
        while ((line = xmalloc_getline(src_stream)) != NULL) {
@@ -158,6 +157,7 @@ int uudecode_main(int argc, char **argv)
                        continue;
                }
 
+               /* begin line found. decode and exit */
                mode = strtoul(line_ptr, NULL, 8);
                if (outname == NULL) {
                        outname = strchr(line_ptr, ' ');
@@ -166,16 +166,48 @@ int uudecode_main(int argc, char **argv)
                        }
                        outname++;
                }
-               if (LONE_DASH(outname)) {
-                       dst_stream = stdout;
-               } else {
+               dst_stream = stdout;
+               if (NOT_LONE_DASH(outname)) {
                        dst_stream = xfopen(outname, "w");
                        chmod(outname, mode & (S_IRWXU | S_IRWXG | S_IRWXO));
                }
                free(line);
                decode_fn_ptr(src_stream, dst_stream);
-               fclose_if_not_stdin(src_stream);
+               /* fclose_if_not_stdin(src_stream); - redundant */
                return EXIT_SUCCESS;
        }
        bb_error_msg_and_die("no 'begin' line");
 }
+
+/* Test script.
+Put this into an empty dir with busybox binary, an run.
+
+#!/bin/sh
+test -x busybox || { echo "No ./busybox?"; exit; }
+ln -sf busybox uudecode
+ln -sf busybox uuencode
+>A_null
+echo -n A >A
+echo -n AB >AB
+echo -n ABC >ABC
+echo -n ABCD >ABCD
+echo -n ABCDE >ABCDE
+echo -n ABCDEF >ABCDEF
+cat busybox >A_bbox
+for f in A*; do
+    echo uuencode $f
+    ./uuencode    $f <$f >u_$f
+    ./uuencode -m $f <$f >m_$f
+done
+mkdir unpk_u unpk_m 2>/dev/null
+for f in u_*; do
+    ./uudecode <$f -o unpk_u/${f:2}
+    diff -a ${f:2} unpk_u/${f:2} >/dev/null 2>&1
+    echo uudecode $f: $?
+done
+for f in m_*; do
+    ./uudecode <$f -o unpk_m/${f:2}
+    diff -a ${f:2} unpk_m/${f:2} >/dev/null 2>&1
+    echo uudecode $f: $?
+done
+*/
index 9490474b9f0b8293a52c1ea7632ddba952b2fa7c..b54e317a2744efd11d5b163698fe89080bf878ff 100644 (file)
@@ -28,7 +28,7 @@ int uuencode_main(int argc, char **argv)
        RESERVE_CONFIG_BUFFER(dst_buf, DST_BUF_SIZE + 1);
 
        tbl = bb_uuenc_tbl_std;
-       if (getopt32(argc, argv, "m") & 1) {
+       if (getopt32(argc, argv, "m")) {
                tbl = bb_uuenc_tbl_base64;
        }
 
@@ -37,9 +37,6 @@ int uuencode_main(int argc, char **argv)
                        src_stream = xfopen(argv[optind], "r");
                        xstat(argv[optind], &stat_buf);
                        mode = stat_buf.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
-                       if (src_stream == stdout) {
-                               puts("NULL");
-                       }
                        break;
                case 1:
                        mode = 0666 & ~umask(0666);
index 085bbdd7bd60ec4de99c560ae0249783fde71769..13d79b639f4fc85404b87579c553474144321c4a 100644 (file)
@@ -3664,20 +3664,19 @@ USE_FEATURE_RUN_PARTS_FANCY("\n -l      Prints names of all matching files even when
        "[pauses for 1 second]\n"
 
 #define uudecode_trivial_usage \
-       "[FILE]..."
+       "[-o outfile] [infile]"
 #define uudecode_full_usage \
-       "Uudecode a file" \
-       "\n\nOptions:\n" \
-       "       -o FILE Direct output to FILE"
+       "Uudecode a file\n" \
+       "NB: finds outfile name in uuencoded source unless -o is given"
 #define uudecode_example_usage \
        "$ uudecode -o busybox busybox.uu\n" \
        "$ ls -l busybox\n" \
        "-rwxr-xr-x   1 ams      ams        245264 Jun  7 21:35 busybox\n"
 
 #define uuencode_trivial_usage \
-       "[OPTION] [INFILE] REMOTEFILE"
+       "[-m] [infile] stored_filename"
 #define uuencode_full_usage \
-       "Uuencode a file" \
+       "Uuencode a file to stdout" \
        "\n\nOptions:\n" \
        "       -m      Use base64 encoding per RFC1521"
 #define uuencode_example_usage \