diff options
| -rw-r--r-- | Changelog | 2 | ||||
| -rw-r--r-- | coreutils/uuencode.c | 78 |
2 files changed, 25 insertions, 55 deletions
| @@ -32,6 +32,8 @@ | |||
| 32 | applets, fix print nslookup server name if compile without | 32 | applets, fix print nslookup server name if compile without |
| 33 | uClibc, fix route crashe 'route add', fix warnings compile | 33 | uClibc, fix route crashe 'route add', fix warnings compile |
| 34 | networking and pwd_grp applets | 34 | networking and pwd_grp applets |
| 35 | * Tim Riker <Tim@Rikers.org> | ||
| 36 | -- fix and shrink uuencode | ||
| 35 | 37 | ||
| 36 | -Erik Andersen, --not yet released-- | 38 | -Erik Andersen, --not yet released-- |
| 37 | 39 | ||
diff --git a/coreutils/uuencode.c b/coreutils/uuencode.c index 0a362a262..24b9f1c6a 100644 --- a/coreutils/uuencode.c +++ b/coreutils/uuencode.c | |||
| @@ -28,7 +28,7 @@ | |||
| 28 | #include "busybox.h" | 28 | #include "busybox.h" |
| 29 | 29 | ||
| 30 | /* Conversion table. for base 64 */ | 30 | /* Conversion table. for base 64 */ |
| 31 | static char tbl_base64[64] = { | 31 | static char tbl_base64[65] = { |
| 32 | 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', | 32 | 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', |
| 33 | 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', | 33 | 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', |
| 34 | 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', | 34 | 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', |
| @@ -36,10 +36,11 @@ static char tbl_base64[64] = { | |||
| 36 | 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', | 36 | 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', |
| 37 | 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', | 37 | 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', |
| 38 | 'w', 'x', 'y', 'z', '0', '1', '2', '3', | 38 | 'w', 'x', 'y', 'z', '0', '1', '2', '3', |
| 39 | '4', '5', '6', '7', '8', '9', '+', '/' | 39 | '4', '5', '6', '7', '8', '9', '+', '/', |
| 40 | '=' /* termination character */ | ||
| 40 | }; | 41 | }; |
| 41 | 42 | ||
| 42 | static char tbl_std[64] = { | 43 | static char tbl_std[65] = { |
| 43 | '`', '!', '"', '#', '$', '%', '&', '\'', | 44 | '`', '!', '"', '#', '$', '%', '&', '\'', |
| 44 | '(', ')', '*', '+', ',', '-', '.', '/', | 45 | '(', ')', '*', '+', ',', '-', '.', '/', |
| 45 | '0', '1', '2', '3', '4', '5', '6', '7', | 46 | '0', '1', '2', '3', '4', '5', '6', '7', |
| @@ -47,7 +48,8 @@ static char tbl_std[64] = { | |||
| 47 | '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', | 48 | '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', |
| 48 | 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', | 49 | 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', |
| 49 | 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', | 50 | 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', |
| 50 | 'X', 'Y', 'Z', '[', '\\', ']', '^', '_' | 51 | 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', |
| 52 | '\`' /* termination character */ | ||
| 51 | }; | 53 | }; |
| 52 | 54 | ||
| 53 | /* | 55 | /* |
| @@ -71,10 +73,10 @@ static void uuencode (const char *s, const char *store, const int length, const | |||
| 71 | } | 73 | } |
| 72 | /* Pad the result if necessary... */ | 74 | /* Pad the result if necessary... */ |
| 73 | if (i == length + 1) { | 75 | if (i == length + 1) { |
| 74 | *(p - 1) = '='; | 76 | *(p - 1) = tbl[64]; |
| 75 | } | 77 | } |
| 76 | else if (i == length + 2) { | 78 | else if (i == length + 2) { |
| 77 | *(p - 1) = *(p - 2) = '='; | 79 | *(p - 1) = *(p - 2) = tbl[64]; |
| 78 | } | 80 | } |
| 79 | /* ...and zero-terminate it. */ | 81 | /* ...and zero-terminate it. */ |
| 80 | *p = '\0'; | 82 | *p = '\0'; |
| @@ -82,8 +84,9 @@ static void uuencode (const char *s, const char *store, const int length, const | |||
| 82 | 84 | ||
| 83 | int uuencode_main(int argc, char **argv) | 85 | int uuencode_main(int argc, char **argv) |
| 84 | { | 86 | { |
| 85 | const int src_buf_size = 60; // This *MUST* be a multiple of 3 | 87 | const int src_buf_size = 45;// This *MUST* be a multiple of 3 |
| 86 | const int dst_buf_size = 4 * ((src_buf_size + 2) / 3); | 88 | const int dst_buf_size = 4 * ((src_buf_size + 2) / 3); |
| 89 | int write_size = dst_buf_size; | ||
| 87 | RESERVE_CONFIG_BUFFER(src_buf, src_buf_size + 1); | 90 | RESERVE_CONFIG_BUFFER(src_buf, src_buf_size + 1); |
| 88 | RESERVE_CONFIG_BUFFER(dst_buf, dst_buf_size + 1); | 91 | RESERVE_CONFIG_BUFFER(dst_buf, dst_buf_size + 1); |
| 89 | struct stat stat_buf; | 92 | struct stat stat_buf; |
| @@ -92,10 +95,6 @@ int uuencode_main(int argc, char **argv) | |||
| 92 | size_t size; | 95 | size_t size; |
| 93 | mode_t mode; | 96 | mode_t mode; |
| 94 | int opt; | 97 | int opt; |
| 95 | int column = 0; | ||
| 96 | int write_size = 0; | ||
| 97 | int remaining; | ||
| 98 | int buffer_offset = 0; | ||
| 99 | 98 | ||
| 100 | while ((opt = getopt(argc, argv, "m")) != -1) { | 99 | while ((opt = getopt(argc, argv, "m")) != -1) { |
| 101 | switch (opt) { | 100 | switch (opt) { |
| @@ -126,53 +125,22 @@ int uuencode_main(int argc, char **argv) | |||
| 126 | printf("begin%s %o %s", tbl == tbl_std ? "" : "-base64", mode, argv[argc - 1]); | 125 | printf("begin%s %o %s", tbl == tbl_std ? "" : "-base64", mode, argv[argc - 1]); |
| 127 | 126 | ||
| 128 | while ((size = fread(src_buf, 1, src_buf_size, src_stream)) > 0) { | 127 | while ((size = fread(src_buf, 1, src_buf_size, src_stream)) > 0) { |
| 128 | if (size != src_buf_size) { | ||
| 129 | /* write_size is always 60 until the last line */ | ||
| 130 | write_size=(4 * ((size + 2) / 3)); | ||
| 131 | /* pad with 0s so we can just encode extra bits */ | ||
| 132 | memset(&src_buf[size], 0, src_buf_size - size); | ||
| 133 | } | ||
| 129 | /* Encode the buffer we just read in */ | 134 | /* Encode the buffer we just read in */ |
| 130 | uuencode(src_buf, dst_buf, size, tbl); | 135 | uuencode(src_buf, dst_buf, size, tbl); |
| 131 | 136 | ||
| 132 | /* Write the buffer to stdout, wrapping at 60 chars. | 137 | putchar('\n'); |
| 133 | * This looks overly complex, but it gets tricky as | 138 | if (tbl == tbl_std) { |
| 134 | * the line has to continue to wrap correctly if we | 139 | putchar(tbl[size]); |
| 135 | * have to refill the buffer | 140 | } |
| 136 | * | 141 | if (fwrite(dst_buf, 1, write_size, stdout) != write_size) { |
| 137 | * Improvments most welcome | 142 | perror("Couldnt finish writing"); |
| 138 | */ | 143 | } |
| 139 | |||
| 140 | /* Initialise values for the new buffer */ | ||
| 141 | remaining = 4 * ((size + 2) / 3); | ||
| 142 | buffer_offset = 0; | ||
| 143 | |||
| 144 | /* Write the buffer to stdout, wrapping at 60 chars | ||
| 145 | * starting from the column the last buffer ran out | ||
| 146 | */ | ||
| 147 | do { | ||
| 148 | if (remaining > (60 - column)) { | ||
| 149 | write_size = 60 - column; | ||
| 150 | } | ||
| 151 | else if (remaining < 60) { | ||
| 152 | write_size = remaining; | ||
| 153 | } else { | ||
| 154 | write_size = 60; | ||
| 155 | } | ||
| 156 | |||
| 157 | /* Setup a new row if required */ | ||
| 158 | if (column == 0) { | ||
| 159 | putchar('\n'); | ||
| 160 | if (tbl == tbl_std) { | ||
| 161 | putchar('M'); | ||
| 162 | } | ||
| 163 | } | ||
| 164 | /* Write to the 60th column */ | ||
| 165 | if (fwrite(&dst_buf[buffer_offset], 1, write_size, stdout) != write_size) { | ||
| 166 | perror("Couldnt finish writing"); | ||
| 167 | } | ||
| 168 | /* Update variables based on last write */ | ||
| 169 | buffer_offset += write_size; | ||
| 170 | remaining -= write_size; | ||
| 171 | column += write_size; | ||
| 172 | if (column % 60 == 0) { | ||
| 173 | column = 0; | ||
| 174 | } | ||
| 175 | } while (remaining > 0); | ||
| 176 | } | 144 | } |
| 177 | printf(tbl == tbl_std ? "\n`\nend\n" : "\n====\n"); | 145 | printf(tbl == tbl_std ? "\n`\nend\n" : "\n====\n"); |
| 178 | 146 | ||
