Mercurial > hg > toybox
annotate toys/pending/uudecode.c @ 828:1fdaba9a7124
uuencode/decode tests and tweaks from Erich Plondke.
author | Rob Landley <rob@landley.net> |
---|---|
date | Fri, 22 Mar 2013 00:26:12 -0500 |
parents | 0429050a224b |
children | 1c61f2827bf8 |
rev | line source |
---|---|
823
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
1 /* uudecode.c - uudecode / base64 decode |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
2 * |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
3 * Copyright 2013 Erich Plondke <toybox@erich.wreck.org> |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
4 * |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
5 * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/uudecode.html |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
6 |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
7 USE_UUENCODE(NEWTOY(uudecode, ">2o:", TOYFLAG_USR|TOYFLAG_BIN)) |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
8 |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
9 config UUDECODE |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
10 bool "uudecode" |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
11 default n |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
12 help |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
13 usage: uudecode [-o outfile] [file] |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
14 |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
15 Uudecode or base64-decode stdin or [file], sending output to outfile or |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
16 filename specified by input. |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
17 */ |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
18 |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
19 #define FOR_uudecode |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
20 #include "toys.h" |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
21 |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
22 GLOBALS( |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
23 char *o; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
24 ) |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
25 |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
26 /* |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
27 * Turn a character back into a value. |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
28 * The smallest valid character is 0x2B ('+') |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
29 * The biggest valid character is 0x7A ('z') |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
30 * We can make a table of 16*5 entries to cover 0x2B - 0x7A |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
31 */ |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
32 |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
33 static inline int startswith(const char *a, const char *b) |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
34 { |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
35 return (0==strncmp(a,b,strlen(b))); |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
36 } |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
37 |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
38 static inline signed char uudecode_b64_1byte(char in) |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
39 { |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
40 char ret; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
41 static const signed char table[16*5] = { |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
42 /* '+' (0x2B) is 62, '/'(0x2F) is 63, rest invalid */ |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
43 62, -1, -1, -1, 63, |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
44 /* '0'-'9' are values 52-61, rest of 0x3A - 0x3F is invalid, = is special... */ |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
45 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
46 /* '@' is invalid, 'A'-'Z' are values 0-25, 0x5b - 0x5F are invalid */ |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
47 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
48 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
49 /* '`' is invalid, 'a'-'z' are values 26-51, 0x7B - 0x7F are invalid */ |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
50 -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
51 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
52 }; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
53 in &= 0x7f; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
54 if (in < '+') return -1; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
55 if (in > 'z') return -1; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
56 in -= '+'; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
57 ret = table[in]; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
58 return ret; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
59 }; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
60 |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
61 |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
62 /* Returns length put in out */ |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
63 static int uudecode_b64_4bytes(char *out, const char *in) |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
64 { |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
65 unsigned int i,x=0; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
66 signed char b0,b1,b2,b3; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
67 int len = 3; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
68 b0 = uudecode_b64_1byte(in[0]); |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
69 b1 = uudecode_b64_1byte(in[1]); |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
70 b2 = uudecode_b64_1byte(in[2]); |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
71 b3 = uudecode_b64_1byte(in[3]); |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
72 if ((b1 < 0) || (b0 < 0)) return 0; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
73 if (b3 < 0) len--; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
74 if (b2 < 0) len--; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
75 x = ((b0 & 0x3f)<<18) | ((b1 & 0x3f)<<12) | ((b2 & 0x3f) << 6) | (b3 & 0x3f); |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
76 for (i = 0; i < len; i++) { |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
77 *out++ = (x>>(8*(2-i))) & 0x0ff; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
78 } |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
79 return len; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
80 } |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
81 |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
82 static void uudecode_b64_line(int ofd, const char *in, int ilen) |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
83 { |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
84 int olen; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
85 char out[4]; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
86 while (ilen >= 4) { |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
87 olen = uudecode_b64_4bytes(out,in); |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
88 xwrite(ofd,out,olen); |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
89 in += 4; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
90 ilen -= 4; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
91 }; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
92 } |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
93 |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
94 static void uudecode_b64(int ifd, int ofd) |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
95 { |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
96 int len; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
97 char *line; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
98 while ((line = get_line(ifd)) != NULL) { |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
99 if (startswith(line,"====")) return; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
100 if ((len = strlen(line)) < 4) continue; // skip empty lines |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
101 uudecode_b64_line(ofd,line,len); |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
102 free(line); |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
103 } |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
104 } |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
105 |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
106 |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
107 static void uudecode_uu_4bytes(char *out, const char *in, int len) |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
108 { |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
109 unsigned int i,x=0; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
110 for (i = 0; i < 4; i++) { |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
111 x |= ((in[i] - 32) & 0x03f) << (6*(3-i)); |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
112 } |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
113 if (len > 3) len = 3; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
114 for (i = 0; i < len; i++) { |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
115 *out++ = x >> (8*(2-i)); |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
116 } |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
117 } |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
118 |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
119 static void uudecode_uu_line(int ofd, const char *in) |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
120 { |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
121 int olen = in[0] - 32; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
122 char buf[4]; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
123 in++; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
124 while (olen > 0) { |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
125 uudecode_uu_4bytes(buf,in,olen); |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
126 xwrite(ofd,buf,olen < 3 ? olen : 3); |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
127 olen -= 3; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
128 in += 4; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
129 } |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
130 } |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
131 |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
132 static void uudecode_uu(int ifd, int ofd) |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
133 { |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
134 char *line = NULL; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
135 while ((line = get_line(ifd)) != NULL) { |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
136 if (line[0] == '`') break; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
137 if (startswith(line,"end")) break; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
138 if (strlen(line) < 1) break; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
139 uudecode_uu_line(ofd,line); |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
140 free(line); |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
141 } |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
142 } |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
143 |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
144 void uudecode_main(void) |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
145 { |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
146 char *out_filename = NULL; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
147 int ifd = 0; /* STDIN */ |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
148 int ofd = 1; /* STDOUT */ |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
149 char *line; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
150 char *p,*p2; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
151 void (*decoder)(int ifd, int ofd) = NULL; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
152 long mode = 0744; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
153 if (toys.optc == 1) { |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
154 ifd = xopen(toys.optargs[0],O_RDONLY); // dies if error |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
155 } |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
156 do { |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
157 if ((line = get_line(ifd)) == NULL) perror_exit("empty file"); |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
158 } while (strlen(line) == 0); /* skip over empty lines */ |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
159 if (startswith(line,"begin ")) decoder = uudecode_uu; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
160 else if (startswith(line,"begin-base64 ")) decoder = uudecode_b64; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
161 else perror_exit("not a valid uu- or base64-encoded file"); |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
162 for (p = line; !isspace(*p); p++) /* skip first part */; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
163 for (; isspace(*p); p++) /* skip spaces */; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
164 mode = strtoul(p,&p2,8); |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
165 p = p2 + 1; /* skip space */ |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
166 if (toys.optflags & FLAG_o) { |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
167 out_filename = TT.o; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
168 } else { |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
169 out_filename = p; |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
170 } |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
171 ofd = xcreate(out_filename,O_WRONLY|O_CREAT|O_TRUNC,mode); |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
172 free(line); |
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
173 decoder(ifd,ofd); |
828
1fdaba9a7124
uuencode/decode tests and tweaks from Erich Plondke.
Rob Landley <rob@landley.net>
parents:
823
diff
changeset
|
174 if (TOYBOX_CLEANUP) close(ofd); |
823
0429050a224b
uuencode and uudecode by Erich Plondke.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
175 } |