comparison toys/pending/uuencode.c @ 830:ce155547bca2

First round of uuencode cleanup: generate table, tweak help text, remove unnecessary output buffers, simplify base64 functions..
author Rob Landley <rob@landley.net>
date Sun, 24 Mar 2013 22:35:32 -0500
parents 1fdaba9a7124
children
comparison
equal deleted inserted replaced
1:7900ba3be71a 2:1a94d73a9d14
10 bool "uuencode" 10 bool "uuencode"
11 default n 11 default n
12 help 12 help
13 usage: uuencode [-m] [file] encode-filename 13 usage: uuencode [-m] [file] encode-filename
14 14
15 Uuencode or (with -m option) base64-encode stdin or [file], 15 Uuencode stdin (or file) to stdout, with encode-filename in the output.
16 with encode-filename in the output, which is sent to stdout. 16
17 -m base64-encode
17 */ 18 */
18 19
19 #define FOR_uuencode 20 #define FOR_uuencode
20 #include "toys.h" 21 #include "toys.h"
21 22
23 // Convert 3 bytes of input to 4 bytes of output
24 static void uuencode_b64_3bytes(const char *in, int bytes)
25 {
26 unsigned int i, x;
22 27
23 28 for (i = x = 0; i<4; i++) {
24 static void uuencode_b64_3bytes(char *out, const char *in, int bytes) 29 if (i < bytes) x |= (in[i] & 0x0ff) << (8*(2-i));
25 { 30 xputc(i > bytes ? '=' : toybuf[(x>>((3-i)*6)) & 0x3f]);
26 static const char *table = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 31 }
27 "abcdefghijklmnopqrstuvwxyz"
28 "0123456789+/";
29 unsigned int i,x=0;
30 for (i = 0; i < bytes; i++) {
31 x |= (in[i] & 0x0ff) << (8*(2-i));
32 }
33 out[0] = table[(x>>(3*6)) & 0x3f];
34 out[1] = table[(x>>(2*6)) & 0x3f];
35 out[2] = table[(x>>(1*6)) & 0x3f];
36 out[3] = table[(x>>(0*6)) & 0x3f];
37 if (bytes <= 1) out[2] = '=';
38 if (bytes <= 2) out[3] = '=';
39 } 32 }
40 33
41 static void uuencode_b64_line(char *out, const char *in, int len) 34 static void uuencode_b64_line(const char *in, int len)
42 { 35 {
43 while (len > 0) { 36 while (len > 0) {
44 uuencode_b64_3bytes(out,in,len < 3 ? len : 3); 37 uuencode_b64_3bytes(in, len < 3 ? len : 3);
45 xprintf("%c%c%c%c",out[0],out[1],out[2],out[3]);
46 in += 3; 38 in += 3;
47 len -= 3; 39 len -= 3;
48 }; 40 };
49 xprintf("\n"); 41 xprintf("\n");
50 } 42 }
51 43
52 static void uuencode_b64(int fd, const char *name) 44 static void uuencode_b64(int fd, const char *name)
53 { 45 {
54 int len; 46 int len;
55 char *inbuf = toybuf; 47 char buf[(76/4)*3];
56 char *outbuf = toybuf+64; 48
57 xprintf("begin-base64 744 %s\n",name); 49 xprintf("begin-base64 744 %s\n",name);
58 do { 50 do {
59 len = xread(fd,inbuf,48); 51 len = xread(fd, buf, sizeof(buf));
60 if (len > 0) uuencode_b64_line(outbuf,inbuf,len); 52
53 uuencode_b64_line(buf, len);
61 } while (len > 0); 54 } while (len > 0);
62 xprintf("====\n"); 55 xprintf("====\n");
63 } 56 }
64 57
65 58
66 static void uuencode_uu_3bytes(char *out, const char *in) 59 static void uuencode_uu_3bytes(const char *in)
67 { 60 {
68 unsigned int i,x=0; 61 unsigned int i, x = 0;
69 for (i = 0; i <= 2; i++) { 62
70 x |= (in[i] & 0x0ff) << (8*(2-i)); 63 for (i = 0; i <= 2; i++) x |= (in[i] & 0x0ff) << (8*(2-i));
71 } 64 for (i = 0; i <= 3; i++) xputc(32 + ((x >> (6*(3-i))) & 0x3f));
72 for (i = 0; i <= 3; i++) {
73 out[i] = 32 + ((x >> (6*(3-i))) & 0x3f);
74 }
75 } 65 }
76 66
77 static void uuencode_uu_line(char *out, const char *in, int len) 67 static void uuencode_uu_line(char *in, int len)
78 { 68 {
79 int i; 69 if (len > 0) {
80 if (len == 0) { 70 int i;
81 xprintf("`\n"); 71
82 return; 72 xputc(len+32);
83 } 73 for (i = 0; i < len; i += 3) uuencode_uu_3bytes(in+i);
84 xprintf("%c",len+32);
85 for (i = 0; i < len; i += 3) {
86 uuencode_uu_3bytes(out,in+i);
87 xprintf("%c%c%c%c",out[0],out[1],out[2],out[3]);
88 } 74 }
89 xprintf("\n"); 75 xprintf("\n");
90 } 76 }
91 77
92 static void uuencode_uu(int fd, const char *name) 78 static void uuencode_uu(int fd, const char *name)
93 { 79 {
94 int len; 80 int len;
95 char *inbuf = toybuf; 81 char buf[45];
96 char *outbuf = toybuf+64; 82
97 xprintf("begin 744 %s\n",name); 83 xprintf("begin 744 %s\n",name);
98 do { 84 do {
99 len = xread(fd,inbuf,45); 85 len = xread(fd, buf, 45);
100 uuencode_uu_line(outbuf,inbuf,len); 86 uuencode_uu_line(buf, len);
101 } while (len > 0); 87 } while (len > 0);
102 xprintf("end\n"); 88 xprintf("end\n");
103 } 89 }
104 90
105 void uuencode_main(void) 91 void uuencode_main(void)
106 { 92 {
107 char *encode_filename = toys.optargs[0]; 93 char *p, *name = toys.optargs[0];
108 int fd = 0; /* STDIN */ 94 int i, fd = 0;
95
96 // base64 table
97
98 p = toybuf;
99 for (i = 'A'; i != ':'; i++) {
100 if (i == 'Z'+1) i = 'a';
101 if (i == 'z'+1) i = '0';
102 *(p++) = i;
103 }
104 *(p++) = '+';
105 *(p++) = '/';
109 106
110 if (toys.optc == 2) { 107 if (toys.optc == 2) {
111 fd = xopen(toys.optargs[0],O_RDONLY); // dies if error 108 fd = xopen(toys.optargs[0], O_RDONLY); // dies if error
112 encode_filename = toys.optargs[1]; 109 name = toys.optargs[1];
113 } 110 }
114 if (toys.optflags & FLAG_m) uuencode_b64(fd,encode_filename); 111 if (toys.optflags & FLAG_m) uuencode_b64(fd, name);
115 else uuencode_uu(fd,encode_filename); 112 else uuencode_uu(fd, name);
116 } 113 }