Changeset 2725 in MondoRescue for branches/2.2.9/mindi-busybox/coreutils/uudecode.c
- Timestamp:
- Feb 25, 2011, 9:26:54 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2.2.9/mindi-busybox/coreutils/uudecode.c
r1765 r2725 1 1 /* vi: set sw=4 ts=4: */ 2 2 /* 3 * Copyright 2003, Glenn McGrath <bug1@iinet.net.au>3 * Copyright 2003, Glenn McGrath 4 4 * 5 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.5 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 6 6 * 7 * 8 * 7 * Based on specification from 8 * http://www.opengroup.org/onlinepubs/007904975/utilities/uuencode.html 9 9 * 10 * 11 * 10 * Bugs: the spec doesn't mention anything about "`\n`\n" prior to the 11 * "end" line 12 12 */ 13 14 15 13 #include "libbb.h" 16 14 17 static void read_stduu(FILE *src_stream, FILE *dst_stream) 15 #if ENABLE_UUDECODE 16 static void FAST_FUNC read_stduu(FILE *src_stream, FILE *dst_stream, int flags UNUSED_PARAM) 18 17 { 19 18 char *line; 20 19 21 while ((line = xmalloc_ getline(src_stream)) != NULL) {22 int length;23 char *line_ptr = line;20 while ((line = xmalloc_fgetline(src_stream)) != NULL) { 21 int encoded_len, str_len; 22 char *line_ptr, *dst; 24 23 25 24 if (strcmp(line, "end") == 0) { 26 return; 27 } 28 length = ((*line_ptr - 0x20) & 0x3f)* 4 / 3; 29 30 if (length <= 0) { 25 return; /* the only non-error exit */ 26 } 27 28 line_ptr = line; 29 while (*line_ptr) { 30 *line_ptr = (*line_ptr - 0x20) & 0x3f; 31 line_ptr++; 32 } 33 str_len = line_ptr - line; 34 35 encoded_len = line[0] * 4 / 3; 36 /* Check that line is not too short. (we tolerate 37 * overly _long_ line to accomodate possible extra '`'). 38 * Empty line case is also caught here. */ 39 if (str_len <= encoded_len) { 40 break; /* go to bb_error_msg_and_die("short file"); */ 41 } 42 if (encoded_len <= 0) { 31 43 /* Ignore the "`\n" line, why is it even in the encode file ? */ 44 free(line); 32 45 continue; 33 46 } 34 if ( length> 60) {47 if (encoded_len > 60) { 35 48 bb_error_msg_and_die("line too long"); 36 49 } 37 50 38 line_ptr++; 39 /* Tolerate an overly long line to accomodate a possible exta '`' */ 40 if (strlen(line_ptr) < (size_t)length) { 41 bb_error_msg_and_die("short file"); 42 } 43 44 while (length > 0) { 51 dst = line; 52 line_ptr = line + 1; 53 do { 45 54 /* Merge four 6 bit chars to three 8 bit chars */ 46 fputc(((line_ptr[0] - 0x20) & 077) << 2 | ((line_ptr[1] - 0x20) & 077) >> 4, dst_stream); 47 line_ptr++; 48 length--; 49 if (length == 0) { 55 *dst++ = line_ptr[0] << 2 | line_ptr[1] >> 4; 56 encoded_len--; 57 if (encoded_len == 0) { 50 58 break; 51 59 } 52 60 53 fputc(((line_ptr[0] - 0x20) & 077) << 4 | ((line_ptr[1] - 0x20) & 077) >> 2, dst_stream); 54 line_ptr++; 55 length--; 56 if (length == 0) { 61 *dst++ = line_ptr[1] << 4 | line_ptr[2] >> 2; 62 encoded_len--; 63 if (encoded_len == 0) { 57 64 break; 58 65 } 59 66 60 fputc(((line_ptr[0] - 0x20) & 077) << 6 | ((line_ptr[1] - 0x20) & 077), dst_stream); 61 line_ptr += 2; 62 length -= 2; 63 } 67 *dst++ = line_ptr[2] << 6 | line_ptr[3]; 68 line_ptr += 4; 69 encoded_len -= 2; 70 } while (encoded_len > 0); 71 fwrite(line, 1, dst - line, dst_stream); 64 72 free(line); 65 73 } 66 74 bb_error_msg_and_die("short file"); 67 75 } 68 69 static void read_base64(FILE *src_stream, FILE *dst_stream) 76 #endif 77 78 #if ENABLE_UUDECODE 79 int uudecode_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 80 int uudecode_main(int argc UNUSED_PARAM, char **argv) 70 81 { 71 int term_count = 1; 72 73 while (1) { 74 char translated[4]; 75 int count = 0; 76 77 while (count < 4) { 78 char *table_ptr; 79 int ch; 80 81 /* Get next _valid_ character. 82 * global vector bb_uuenc_tbl_base64[] contains this string: 83 * "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n" 84 */ 85 do { 86 ch = fgetc(src_stream); 87 if (ch == EOF) { 88 bb_error_msg_and_die("short file"); 89 } 90 table_ptr = strchr(bb_uuenc_tbl_base64, ch); 91 } while (table_ptr == NULL); 92 93 /* Convert encoded character to decimal */ 94 ch = table_ptr - bb_uuenc_tbl_base64; 95 96 if (*table_ptr == '=') { 97 if (term_count == 0) { 98 translated[count] = '\0'; 99 break; 100 } 101 term_count++; 102 } else if (*table_ptr == '\n') { 103 /* Check for terminating line */ 104 if (term_count == 5) { 105 return; 106 } 107 term_count = 1; 108 continue; 109 } else { 110 translated[count] = ch; 111 count++; 112 term_count = 0; 113 } 114 } 115 116 /* Merge 6 bit chars to 8 bit */ 117 if (count > 1) { 118 fputc(translated[0] << 2 | translated[1] >> 4, dst_stream); 119 } 120 if (count > 2) { 121 fputc(translated[1] << 4 | translated[2] >> 2, dst_stream); 122 } 123 if (count > 3) { 124 fputc(translated[2] << 6 | translated[3], dst_stream); 125 } 126 } 127 } 128 129 int uudecode_main(int argc, char **argv); 130 int uudecode_main(int argc, char **argv) 131 { 132 FILE *src_stream = stdin; 82 FILE *src_stream; 133 83 char *outname = NULL; 134 84 char *line; … … 138 88 argv += optind; 139 89 140 if (argv[0]) 141 src_stream = xfopen(argv[0], "r"); 90 if (!argv[0]) 91 *--argv = (char*)"-"; 92 src_stream = xfopen_stdin(argv[0]); 142 93 143 94 /* Search for the start of the encoding */ 144 while ((line = xmalloc_ getline(src_stream)) != NULL) {145 void (*decode_fn_ptr)(FILE * src, FILE * dst);95 while ((line = xmalloc_fgetline(src_stream)) != NULL) { 96 void FAST_FUNC (*decode_fn_ptr)(FILE *src, FILE *dst, int flags); 146 97 char *line_ptr; 147 98 FILE *dst_stream; … … 160 111 161 112 /* begin line found. decode and exit */ 162 mode = strtoul(line_ptr, NULL, 8);113 mode = bb_strtou(line_ptr, NULL, 8); 163 114 if (outname == NULL) { 164 115 outname = strchr(line_ptr, ' '); … … 170 121 dst_stream = stdout; 171 122 if (NOT_LONE_DASH(outname)) { 172 dst_stream = xfopen (outname, "w");173 chmod(outname, mode & (S_IRWXU | S_IRWXG | S_IRWXO));123 dst_stream = xfopen_for_write(outname); 124 fchmod(fileno(dst_stream), mode & (S_IRWXU | S_IRWXG | S_IRWXO)); 174 125 } 175 126 free(line); 176 decode_fn_ptr(src_stream, dst_stream );127 decode_fn_ptr(src_stream, dst_stream, /*flags:*/ BASE64_FLAG_UU_STOP + BASE64_FLAG_NO_STOP_CHAR); 177 128 /* fclose_if_not_stdin(src_stream); - redundant */ 178 129 return EXIT_SUCCESS; … … 180 131 bb_error_msg_and_die("no 'begin' line"); 181 132 } 133 #endif 134 135 //applet:IF_BASE64(APPLET(base64, _BB_DIR_BIN, _BB_SUID_DROP)) 136 137 //kbuild:lib-$(CONFIG_BASE64) += uudecode.o 138 139 //config:config BASE64 140 //config: bool "base64" 141 //config: default y 142 //config: help 143 //config: Base64 encode and decode 144 145 //usage:#define base64_trivial_usage 146 //usage: "[-d] [FILE]" 147 //usage:#define base64_full_usage "\n\n" 148 //usage: "Base64 encode or decode FILE to standard output" 149 //usage: "\nOptions:" 150 //usage: "\n -d Decode data" 151 ////usage: "\n -w COL Wrap lines at COL (default 76, 0 disables)" 152 ////usage: "\n -i When decoding, ignore non-alphabet characters" 153 154 #if ENABLE_BASE64 155 int base64_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 156 int base64_main(int argc UNUSED_PARAM, char **argv) 157 { 158 FILE *src_stream; 159 unsigned opts; 160 161 opt_complementary = "?1"; /* 1 argument max */ 162 opts = getopt32(argv, "d"); 163 argv += optind; 164 165 if (!argv[0]) 166 *--argv = (char*)"-"; 167 src_stream = xfopen_stdin(argv[0]); 168 if (opts) { 169 read_base64(src_stream, stdout, /*flags:*/ (char)EOF); 170 } else { 171 enum { 172 SRC_BUF_SIZE = 76/4*3, /* This *MUST* be a multiple of 3 */ 173 DST_BUF_SIZE = 4 * ((SRC_BUF_SIZE + 2) / 3), 174 }; 175 char src_buf[SRC_BUF_SIZE]; 176 char dst_buf[DST_BUF_SIZE + 1]; 177 int src_fd = fileno(src_stream); 178 while (1) { 179 size_t size = full_read(src_fd, src_buf, SRC_BUF_SIZE); 180 if (!size) 181 break; 182 if ((ssize_t)size < 0) 183 bb_perror_msg_and_die(bb_msg_read_error); 184 /* Encode the buffer we just read in */ 185 bb_uuencode(dst_buf, src_buf, size, bb_uuenc_tbl_base64); 186 xwrite(STDOUT_FILENO, dst_buf, 4 * ((size + 2) / 3)); 187 bb_putchar('\n'); 188 fflush(stdout); 189 } 190 } 191 192 fflush_stdout_and_exit(EXIT_SUCCESS); 193 } 194 #endif 182 195 183 196 /* Test script.
Note:
See TracChangeset
for help on using the changeset viewer.