X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;ds=sidebyside;f=coreutils%2Fuuencode.c;h=fd3326d808f80559b6cc6ac0c4e6fc0a7c16483f;hb=a8992635b117723e65078ada845cc88a9cb77aa3;hp=68d6f19a775fb8262aea1cca758ca1bdedcdb6e7;hpb=4e664ac51d974091097aaa436d72105e3446d90a;p=oweals%2Fbusybox.git diff --git a/coreutils/uuencode.c b/coreutils/uuencode.c index 68d6f19a7..fd3326d80 100644 --- a/coreutils/uuencode.c +++ b/coreutils/uuencode.c @@ -21,6 +21,7 @@ */ #include #include +#include #include #include #include @@ -28,7 +29,7 @@ #include "busybox.h" /* Conversion table. for base 64 */ -static char tbl_base64[64] = { +static const 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 +37,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 const char tbl_std[65] = { '`', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', @@ -47,7 +49,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 */ }; /* @@ -56,7 +59,7 @@ static char tbl_std[64] = { * buffer of at least 1+BASE64_LENGTH(length) bytes. * where BASE64_LENGTH(len) = (4 * ((LENGTH + 2) / 3)) */ -static void base64_encode (const char *s, const char *store, const int length, const char *tbl) +static void uuencode (const char *s, const char *store, const int length, const char *tbl) { int i; unsigned char *p = (unsigned char *)store; @@ -71,118 +74,76 @@ static void base64_encode (const char *s, const char *store, const int length, c } /* 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'; } +#define SRC_BUF_SIZE 45 // This *MUST* be a multiple of 3 +#define DST_BUF_SIZE 4 * ((SRC_BUF_SIZE + 2) / 3) int uuencode_main(int argc, char **argv) { - const int src_buf_size = 600; // This *MUST* be a multiple of 3 - const int dst_buf_size = 4 * ((src_buf_size + 2) / 3); - RESERVE_BB_BUFFER(src_buf, src_buf_size + 1); - RESERVE_BB_BUFFER(dst_buf, dst_buf_size + 1); + const int src_buf_size = SRC_BUF_SIZE; + const int dst_buf_size = DST_BUF_SIZE; + int write_size = dst_buf_size; struct stat stat_buf; FILE *src_stream = stdin; - char *tbl = tbl_std; + const char *tbl; size_t size; mode_t mode; - int opt; - int column = 0; - int write_size; - int remaining; - int buffer_offset = 0; + RESERVE_CONFIG_BUFFER(src_buf, SRC_BUF_SIZE + 1); + RESERVE_CONFIG_BUFFER(dst_buf, DST_BUF_SIZE + 1); - while ((opt = getopt(argc, argv, "m")) != -1) { - switch (opt) { - case 'm': - tbl = tbl_base64; - break; - default: - show_usage(); - } + tbl = tbl_std; + if (bb_getopt_ulflags(argc, argv, "m") & 1) { + tbl = tbl_base64; } switch (argc - optind) { case 2: - src_stream = xfopen(argv[optind], "r"); - stat(argv[optind], &stat_buf); + src_stream = bb_xfopen(argv[optind], "r"); + if (stat(argv[optind], &stat_buf) < 0) { + bb_perror_msg_and_die("stat"); + } mode = stat_buf.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO); if (src_stream == stdout) { - printf("NULL\n"); + puts("NULL"); } break; case 1: - mode = umask(0666); + mode = 0666 & ~umask(0666); break; default: - show_usage(); + bb_show_usage(); } - printf("begin%s %o %s", tbl == tbl_std ? "" : "-base64", mode, argv[argc - 1]); + bb_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 */ - base64_encode(src_buf, dst_buf, size, tbl); + 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; - if (remaining > (60 - column)) { - write_size = 60 - column; + putchar('\n'); + if (tbl == tbl_std) { + putchar(tbl[size]); } - else if (remaining < 60) { - write_size = remaining; - } else { - write_size = 60; + if (fwrite(dst_buf, 1, write_size, stdout) != write_size) { + bb_perror_msg_and_die(bb_msg_write_error); } - - /* Write the buffer to stdout, wrapping at 60 chars - * starting from the column the last buffer ran out - */ - do { - /* 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; - } - - /* working next amount to write */ - write_size = (60 - column) % 60; - if (write_size < remaining) { - write_size = remaining; - } - if (write_size == 0) { - write_size = 60; - } - } while (remaining > 0); } - printf(tbl == tbl_std ? "\n`\nend\n" : "\n====\n"); + bb_printf(tbl == tbl_std ? "\n`\nend\n" : "\n====\n"); + + bb_xferror(src_stream, "source"); /* TODO - Fix this! */ - return(EXIT_SUCCESS); + bb_fflush_stdout_and_exit(EXIT_SUCCESS); }