base64.c - rohrpost - A commandline mail client to change the world as we see it.
 (HTM) git clone git://r-36.net/rohrpost
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       base64.c (2214B)
       ---
            1 /*
            2  * Copy me if you can.
            3  * by 20h
            4  */
            5 
            6 #include <unistd.h>
            7 #include <stdlib.h>
            8 #include <string.h>
            9 #include <strings.h>
           10 
           11 #include "ind.h"
           12 
           13 char be[] =
           14         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
           15 
           16 int
           17 readnwstr(char *buf, char *str, int *p, int max, int l)
           18 {
           19         int i, j;
           20 
           21         for (i = 0; *p < max && i < l; (*p)++) {
           22                 for (j = 0; j < strlen(be); j++) {
           23                         if (str[*p] == be[j]) {
           24                                 buf[i++] = str[*p];
           25                                 break;
           26                         }
           27                 }
           28         }
           29 
           30         if (i < l)
           31                 return 1;
           32         return 0;
           33 }
           34 
           35 char *
           36 b64enc(char *str, int l)
           37 {
           38         char *ret;
           39         int p, po, left;
           40 
           41         po = 0;
           42         p = 0;
           43 
           44         ret = mallocz(5, 0);
           45         for (; p < l; p += 3, po += 4) {
           46                 ret = reallocz(ret, po + 5, 0);
           47 
           48                 ret[po] = be[(str[p] & 0xFC) >> 2];
           49                 ret[po+1] = be[(str[p] & 0x03) << 4 \
           50                             | (str[p+1] & 0xF0) >> 4];
           51                 ret[po+2] = be[(str[p+1] & 0x0F) << 2 \
           52                             | (str[p+2] & 0xC0) >> 6];
           53                 ret[po+3] = be[str[p+2] & 0x3F];
           54         }
           55         left = l - p + 3;
           56         po -= 4;
           57         switch (left) {
           58         case 1:
           59                 ret[po+2] = '=';
           60         case 2:
           61                 ret[po+3] = '=';
           62         default:
           63                 break;
           64         }
           65         ret[po+4] = '\0';
           66 
           67         return ret;
           68 }
           69 
           70 char *
           71 b64dec(char *istr, int *len)
           72 {
           73         char *ret, str[5];
           74         int p, po, l, uglyline;
           75         char bd[256];
           76 
           77         memset(bd, 0x80, 256);
           78         /* Without »=«. */
           79         for (p = 0; p < strlen(be)-1; p++)
           80                 bd[(int)be[p]] = p;
           81         bd['='] = 0;
           82 
           83         p = 0;
           84         po = 0;
           85         ret = NULL;
           86 
           87         /*
           88          * If there is something prepended to the base64 block, take it as-is.
           89          */
           90         for (uglyline = 1, l = 0; uglyline == 1; l = p) {
           91                 uglyline = 0;
           92                 for (; istr[l] != '\n' && istr[l]; l++) {
           93                         if (istr[l] == ' ')
           94                                 uglyline = 1;
           95                 }
           96                 /* Take care of empty lines. */
           97                 if ((l - p) == 1 && istr[l-1] == '\r')
           98                         uglyline = 1;
           99                 if ((l - p) == 0)
          100                         uglyline = 1;
          101                 if (uglyline)
          102                         po = p = l + 1;
          103         }
          104         if (p > 0) {
          105                 ret = reallocz(ret, l, 0);
          106                 memmove(ret, istr, p+1);
          107         }
          108 
          109 
          110         for (; !readnwstr(str, istr, &p, *len, 4); po += 3) {
          111                 ret = reallocz(ret, po + 4, 0);
          112 
          113                 ret[po] = bd[(int)str[0]] << 2 | bd[(int)str[1]] >> 4;
          114                 ret[po+1] = bd[(int)str[1]] << 4 | bd[(int)str[2]] >> 2;
          115                 ret[po+2] = bd[(int)str[2]] << 6 | bd[(int)str[3]];
          116         }
          117         if (str[3] == '=')
          118                 po--;
          119         if (str[2] == '=')
          120                 po--;
          121         ret[po] = '\0';
          122         *len = po;
          123 
          124         return ret;
          125 }
          126 
          127 int
          128 b64len(int len)
          129 {
          130         return (len / 3) * 4 + (len % 3 > 0)? 4 : 0;
          131 }
          132