Mercurial > hg > toybox
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
829:792d510b8fef | 830:ce155547bca2 |
---|---|
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 } |