aboutsummaryrefslogtreecommitdiff
path: root/coreutils/uuencode.c
diff options
context:
space:
mode:
Diffstat (limited to 'coreutils/uuencode.c')
-rw-r--r--coreutils/uuencode.c62
1 files changed, 25 insertions, 37 deletions
diff --git a/coreutils/uuencode.c b/coreutils/uuencode.c
index b54e317a2..c1458f7fb 100644
--- a/coreutils/uuencode.c
+++ b/coreutils/uuencode.c
@@ -10,64 +10,52 @@
10 10
11#include "libbb.h" 11#include "libbb.h"
12 12
13enum {
14 SRC_BUF_SIZE = 45, /* This *MUST* be a multiple of 3 */
15 DST_BUF_SIZE = 4 * ((SRC_BUF_SIZE + 2) / 3),
16};
13 17
14#define SRC_BUF_SIZE 45 // This *MUST* be a multiple of 3
15#define DST_BUF_SIZE 4 * ((SRC_BUF_SIZE + 2) / 3)
16int uuencode_main(int argc, char **argv); 18int uuencode_main(int argc, char **argv);
17int uuencode_main(int argc, char **argv) 19int uuencode_main(int argc, char **argv)
18{ 20{
19 const size_t src_buf_size = SRC_BUF_SIZE;
20 const size_t dst_buf_size = DST_BUF_SIZE;
21 size_t write_size = dst_buf_size;
22 struct stat stat_buf; 21 struct stat stat_buf;
23 FILE *src_stream = stdin; 22 int src_fd = STDIN_FILENO;
24 const char *tbl; 23 const char *tbl;
25 size_t size;
26 mode_t mode; 24 mode_t mode;
27 RESERVE_CONFIG_BUFFER(src_buf, SRC_BUF_SIZE + 1); 25 char src_buf[SRC_BUF_SIZE];
28 RESERVE_CONFIG_BUFFER(dst_buf, DST_BUF_SIZE + 1); 26 char dst_buf[DST_BUF_SIZE + 1];
29 27
30 tbl = bb_uuenc_tbl_std; 28 tbl = bb_uuenc_tbl_std;
29 mode = 0666 & ~umask(0666);
30 opt_complementary = "-1:?2"; /* must have 1 or 2 args */
31 if (getopt32(argc, argv, "m")) { 31 if (getopt32(argc, argv, "m")) {
32 tbl = bb_uuenc_tbl_base64; 32 tbl = bb_uuenc_tbl_base64;
33 } 33 }
34 34 argv += optind;
35 switch (argc - optind) { 35 if (argc == optind + 2) {
36 case 2: 36 src_fd = xopen(*argv, O_RDONLY);
37 src_stream = xfopen(argv[optind], "r"); 37 fstat(src_fd, &stat_buf);
38 xstat(argv[optind], &stat_buf); 38 mode = stat_buf.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
39 mode = stat_buf.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO); 39 argv++;
40 break;
41 case 1:
42 mode = 0666 & ~umask(0666);
43 break;
44 default:
45 bb_show_usage();
46 } 40 }
47 41
48 printf("begin%s %o %s", tbl == bb_uuenc_tbl_std ? "" : "-base64", mode, argv[argc - 1]); 42 printf("begin%s %o %s", tbl == bb_uuenc_tbl_std ? "" : "-base64", mode, *argv);
49 43 while (1) {
50 while ((size = fread(src_buf, 1, src_buf_size, src_stream)) > 0) { 44 size_t size = full_read(src_fd, src_buf, SRC_BUF_SIZE);
51 if (size != src_buf_size) { 45 if (!size)
52 /* write_size is always 60 until the last line */ 46 break;
53 write_size = (4 * ((size + 2) / 3)); 47 if ((ssize_t)size < 0)
54 /* pad with 0s so we can just encode extra bits */ 48 bb_perror_msg_and_die(bb_msg_read_error);
55 memset(&src_buf[size], 0, src_buf_size - size);
56 }
57 /* Encode the buffer we just read in */ 49 /* Encode the buffer we just read in */
58 bb_uuencode((unsigned char*)src_buf, dst_buf, size, tbl); 50 bb_uuencode(dst_buf, src_buf, size, tbl);
59
60 putchar('\n'); 51 putchar('\n');
61 if (tbl == bb_uuenc_tbl_std) { 52 if (tbl == bb_uuenc_tbl_std) {
62 putchar(tbl[size]); 53 putchar(tbl[size]);
63 } 54 }
64 if (fwrite(dst_buf, 1, write_size, stdout) != write_size) { 55 fflush(stdout);
65 bb_perror_msg_and_die(bb_msg_write_error); 56 xwrite(STDOUT_FILENO, dst_buf, 4 * ((size + 2) / 3));
66 }
67 } 57 }
68 printf(tbl == bb_uuenc_tbl_std ? "\n`\nend\n" : "\n====\n"); 58 printf(tbl == bb_uuenc_tbl_std ? "\n`\nend\n" : "\n====\n");
69 59
70 die_if_ferror(src_stream, "source"); /* TODO - Fix this! */
71
72 fflush_stdout_and_exit(EXIT_SUCCESS); 60 fflush_stdout_and_exit(EXIT_SUCCESS);
73} 61}