Home | History | Annotate | Download | only in other
      1 /* base64.c - Encode and decode base64
      2  *
      3  * Copyright 2014 Rob Landley <rob (at) 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