From 746204b1b8ee1948ca91637eeb34043e5e4f0aad Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Mon, 4 Jun 2007 23:32:35 +0000 Subject: [PATCH] uudecode: fix to base64 decode by Jorgen Cederlof 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 | 68 ++++++++++++++++++++++++++++++++------------ coreutils/uuencode.c | 5 +--- include/usage.h | 11 ++++--- 3 files changed, 56 insertions(+), 28 deletions(-) diff --git a/coreutils/uudecode.c b/coreutils/uudecode.c index 779710edd..287386d9d 100644 --- a/coreutils/uudecode.c +++ b/coreutils/uudecode.c @@ -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 +*/ diff --git a/coreutils/uuencode.c b/coreutils/uuencode.c index 9490474b9..b54e317a2 100644 --- a/coreutils/uuencode.c +++ b/coreutils/uuencode.c @@ -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); diff --git a/include/usage.h b/include/usage.h index 085bbdd7b..13d79b639 100644 --- a/include/usage.h +++ b/include/usage.h @@ -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 \