comparison toys/posix/uudecode.c @ 840:8a6b36696ca6

Clean uudecode up the rest of the way, move pending->posix and default y.
author Rob Landley <rob@landley.net>
date Tue, 02 Apr 2013 01:34:34 -0500
parents toys/pending/uudecode.c@a315fb343e2b
children
comparison
equal deleted inserted replaced
5:1644cacb0cc0 0:ba4d714274b6
6 6
7 USE_UUDECODE(NEWTOY(uudecode, ">1o:", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_UMASK)) 7 USE_UUDECODE(NEWTOY(uudecode, ">1o:", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_UMASK))
8 8
9 config UUDECODE 9 config UUDECODE
10 bool "uudecode" 10 bool "uudecode"
11 default n 11 default y
12 help 12 help
13 usage: uudecode [-o OUTFILE] [INFILE] 13 usage: uudecode [-o OUTFILE] [INFILE]
14 14
15 Decode file from stdin (or INFILE). 15 Decode file from stdin (or INFILE).
16 16
22 22
23 GLOBALS( 23 GLOBALS(
24 char *o; 24 char *o;
25 ) 25 )
26 26
27 static int uudecode_b64_4bytes(char *out, char *in)
28 {
29 int i, len = 3;
30 unsigned x = 0;
31
32 for (i=0; i<4; i++) {
33 int c = in[i];
34
35 if (c == '=') {
36 len--;
37 c = 'A';
38 } else if (len != 3) len = 0;
39 if (!len) goto bad;
40
41 if (c >= 'A' && c <= 'Z') c -= 'A';
42 else if (c >= 'a' && c <= 'z') c += 26 - 'a';
43 else if (c >= '0' && c <= '9') c += 52 - '0';
44 else if (c == '+') c = 62;
45 else if (c == '/') c =63;
46 else goto bad;
47
48 x |= c << (6*(3-i));
49 if (i && i <= len) *(out++) = (x>>(8*(3-i))) & 0xff;
50 }
51
52 return len;
53
54 bad:
55 error_exit("bad input");
56 }
57
58 static void uudecode_b64_line(int ofd, char *in, int ilen)
59 {
60 int olen;
61 char out[4];
62
63 while (ilen >= 4) {
64 olen = uudecode_b64_4bytes(out, in);
65 xwrite(ofd,out,olen);
66 in += 4;
67 ilen -= 4;
68 };
69 }
70
71 static void uudecode_uu_4bytes(char *out, char *in, int len)
72 {
73 unsigned int i,x=0;
74
75 for (i = 0; i < 4; i++) x |= ((in[i] - 32) & 0x03f) << (6*(3-i));
76 if (len > 3) len = 3;
77 for (i = 0; i < len; i++) *out++ = x >> (8*(2-i));
78 }
79
80 static void uudecode_uu_line(int ofd, char *in)
81 {
82 int olen = (in[0] - 32) & 0x3f;
83 char buf[4];
84
85 in++;
86 while (olen > 0) {
87 uudecode_uu_4bytes(buf,in,olen);
88 xwrite(ofd,buf,olen < 3 ? olen : 3);
89 olen -= 3;
90 in += 4;
91 }
92 }
93
94 void uudecode_main(void) 27 void uudecode_main(void)
95 { 28 {
96 int ifd = 0, ofd, idx = 0, m; 29 int ifd = 0, ofd, idx = 0, m = m;
97 char *line = 0, 30 char *line = 0, mode[16],
98 *class[] = {"begin%*[ ]%15s%*[ ]%n", "begin-base64%*[ ]%15s%*[ ]%n"}; 31 *class[] = {"begin%*[ ]%15s%*[ ]%n", "begin-base64%*[ ]%15s%*[ ]%n"};
99
100 32
101 if (toys.optc) ifd = xopen(*toys.optargs, O_RDONLY); 33 if (toys.optc) ifd = xopen(*toys.optargs, O_RDONLY);
102 34
103 for (;;) { 35 while (!idx) {
104 char mode[16];
105
106 free(line); 36 free(line);
107 if (!(line = get_line(ifd))) error_exit("bad EOF"); 37 if (!(line = get_line(ifd))) error_exit("bad EOF");
108 for (m=0; m < 2; m++) { 38 for (m=0; m < 2; m++) {
109 sscanf(line, class[m], mode, &idx); 39 sscanf(line, class[m], mode, &idx);
110 if (idx) break; 40 if (idx) break;
111 } 41 }
112
113 if (!idx) continue;
114
115 ofd = xcreate(TT.o ? TT.o : line+idx, O_WRONLY|O_CREAT|O_TRUNC,
116 string_to_mode(mode, 0777^toys.old_umask));
117 free(line);
118 break;
119 } 42 }
120 43
121 while ((line = get_line(ifd)) != NULL) { 44 ofd = xcreate(TT.o ? TT.o : line+idx, O_WRONLY|O_CREAT|O_TRUNC,
122 if (strcmp(line, m ? "====" : "end")) { 45 string_to_mode(mode, 0777^toys.old_umask));
123 if (m) uudecode_b64_line(ofd, line, strlen(line)); 46
124 else uudecode_uu_line(ofd, line); 47 for(;;) {
125 } else m = 2; 48 char *in, *out;
49 int olen;
50
126 free(line); 51 free(line);
127 if (m == 2) break; 52 if (m == 2 || !(line = get_line(ifd))) break;
53 if (!strcmp(line, m ? "====" : "end")) {
54 m = 2;
55 continue;
56 }
57
58 olen = 0;
59 in = out = line;
60 if (!m) olen = (*(in++) - 32) & 0x3f;
61
62 for (;;) {
63 int i = 0, x = 0, len = 4;
64 char c = 0;
65
66 if (!m) {
67 if (olen < 1) break;
68 if (olen < 3) len = olen + 1;
69 }
70
71 while (i < len) {
72 if (!(c = *(in++))) goto line_done;
73
74 if (m) {
75 if (c == '=') {
76 len--;
77 continue;
78 } else if (len != 4) break;
79
80 if (c >= 'A' && c <= 'Z') c -= 'A';
81 else if (c >= 'a' && c <= 'z') c += 26 - 'a';
82 else if (c >= '0' && c <= '9') c += 52 - '0';
83 else if (c == '+') c = 62;
84 else if (c == '/') c = 63;
85 else continue;
86 } else c = (c - 32) & 0x3f;
87
88 x |= c << (6*(3-i));
89
90 if (i && i < len) {
91 *(out++) = (x>>(8*(3-i))) & 0xff;
92 olen--;
93 }
94 i++;
95 }
96
97 if (i && i!=len) error_exit("bad %s", line);
98 }
99 line_done:
100 xwrite(ofd, line, out-line);
128 } 101 }
129 102
130 if (CFG_TOYBOX_FREE) { 103 if (CFG_TOYBOX_FREE) {
131 if (ifd) close(ifd); 104 if (ifd) close(ifd);
132 close(ofd); 105 close(ofd);