1 /* base64.c - Encode and decode base64
2 *
3 * Copyright 2014 Rob Landley <rob@landley.net>
4 *
5 * No standard
6
7 USE_BASE64(NEWTOY(base64, "diw#<0=76[!dw]", TOYFLAG_USR|TOYFLAG_BIN))
8
9 config BASE64
10 bool "base64"
11 default y
12 help
13 usage: base64 [-di] [-w COLUMNS] [FILE...]
14
15 Encode or decode in base64.
16
17 -d Decode
18 -i Ignore non-alphabetic characters
19 -w Wrap output at COLUMNS (default 76 or 0 for no wrap)
20 */
21
22 #define FOR_base64
23 #include "toys.h"
24
GLOBALS(long w;unsigned total;)25 GLOBALS(
26 long w;
27
28 unsigned total;
29 )
30
31 static void wraputchar(int c, int *x)
32 {
33 putchar(c);
34 TT.total++;
35 if (TT.w && ++*x == TT.w) {
36 *x = 0;
37 xputc('\n');
38 };
39 }
40
do_base64(int fd,char * name)41 static void do_base64(int fd, char *name)
42 {
43 int out = 0, bits = 0, x = 0, i, len;
44 char *buf = toybuf+128;
45
46 TT.total = 0;
47
48 for (;;) {
49 // If no more data, flush buffer
50 if (!(len = xread(fd, buf, sizeof(toybuf)-128))) {
51 if (!(toys.optflags & FLAG_d)) {
52 if (bits) wraputchar(toybuf[out<<(6-bits)], &x);
53 while (TT.total&3) wraputchar('=', &x);
54 if (x) xputc('\n');
55 }
56
57 return;
58 }
59
60 for (i=0; i<len; i++) {
61 if (toys.optflags & FLAG_d) {
62 if (buf[i] == '=') return;
63
64 if ((x = stridx(toybuf, buf[i])) != -1) {
65 out = (out<<6) + x;
66 bits += 6;
67 if (bits >= 8) {
68 putchar(out >> (bits -= 8));
69 out &= (1<<bits)-1;
70 if (ferror(stdout)) perror_exit(0);
71 }
72
73 continue;
74 }
75 if (buf[i] == '\n' || (toys.optflags & FLAG_i)) continue;
76
77 break;
78 } else {
79 out = (out<<8) + buf[i];
80 bits += 8;
81 while (bits >= 6) {
82 wraputchar(toybuf[out >> (bits -= 6)], &x);
83 out &= (1<<bits)-1;
84 }
85 }
86 }
87 }
88 }
89
base64_main(void)90 void base64_main(void)
91 {
92 base64_init(toybuf);
93 loopfiles(toys.optargs, do_base64);
94 }
95