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 25 GLOBALS( 26 long columns; 27 28 unsigned total; 29 ) 30 31 static void wraputchar(int c, int *x) 32 { 33 putchar(c); 34 TT.total++; 35 if (TT.columns && ++*x == TT.columns) { 36 *x = 0; 37 xputc('\n'); 38 }; 39 } 40 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 90 void base64_main(void) 91 { 92 base64_init(toybuf); 93 loopfiles(toys.optargs, do_base64); 94 } 95