Sean CaronStyle cleanupd9937538 years agoHistory
130 lines · 3.0 KB · C
RawDownload
/* bijou HTTP server for plan 9 by sean caron (scaron@umich.edu) */ #include "main.h"#include "base64.h" int base64_encode(char *ip, char **op) {    unsigned long r = 0;     int pi = 0;    int po = 0;     *op = malloc(5*sizeof(char));     if (*op == 0) {        exits("MALLOC");    }     for (pi = 0; pi < strlen(ip)+1; pi = pi + 3) {        if (ip[pi] == '\0') {            *(*op + (4*po)) = '\0';            break;        }         else if (ip[pi+1] == '\0') {            // two characters output, == pad            r = (ip[pi] << 24);             *(*op + (4*po)) = base64_lut[r >> 26];            *(*op + ((4*po)+1)) = base64_lut[(r << 6) >> 26];            *(*op + ((4*po)+2)) = '=';            *(*op + ((4*po)+3)) = '=';             *(*op + ((4*po)+4)) = '\0';             break;        }         else if (ip[pi+2] == '\0') {            // three characters output, = pad             r = (ip[pi] << 24) | (ip[pi+1] << 16);             *(*op + (4*po)) = base64_lut[r >> 26];            *(*op + ((4*po)+1)) = base64_lut[(r << 6) >> 26];            *(*op + ((4*po)+2)) = base64_lut[(r << 12) >> 26];            *(*op + ((4*po)+3)) = '=';             *(*op + ((4*po)+4)) = '\0';             break;        }         else {            // four characters output, no pad            r = (ip[pi] << 24) | (ip[pi+1] << 16) | (ip[pi+2] << 8);             *(*op + (4*po)) = base64_lut[r >> 26];            *(*op + ((4*po)+1)) = base64_lut[(r << 6) >> 26];            *(*op + ((4*po)+2)) = base64_lut[(r << 12) >> 26];            *(*op + ((4*po)+3)) = base64_lut[(r << 18) >> 26];        }         po = po + 1;         *op = realloc(*op, sizeof(char)*((4*po)+5) );         if ( *op == 0 ) {            exits("REALLOC");        }    }     return strlen(*op);} int base64_decode(char *ip, char **op) {    unsigned long r = 0;    unsigned char t[4] = {0, 0, 0, 0};     int pi = 0;    int po = 0;     /* return with -1 to signal malformed input */     if ((strlen(ip) % 4) != 0 ) {        return -1;    }     *op = malloc( 4*sizeof(char) );     if (*op == 0) {        exits("MALLOC");    }     for (pi = 0; pi < strlen(ip); pi = pi + 4) {        t[0] = base64_ilut[ip[pi]] << 2;        t[1] = base64_ilut[ip[pi+1]] << 2;        t[2] = base64_ilut[ip[pi+2]] << 2;        t[3] = base64_ilut[ip[pi+3]] << 2;         r = t[0] << 24;        r = r & 0xFC000000;         r = r | (t[1] << 18);        r = r & 0xFFF00000;         r = r | (t[2] << 12);        r = r & 0xFFFFC000;         r = r | (t[3] << 6);        r = r & 0xFFFFFF00; 	/* the characters are packed in the three high order bytes of long, r. the lower 8 bits of r are zero */         *(*op + (3*po)) = (char)(r>>24);        *(*op + ((3*po)+1)) = (char)((r<<8)>>24);        *(*op + ((3*po)+2)) = (char)((r<<16)>>24);         *(*op + ((3*po)+3)) = '\0';         po = po + 1;         *op = realloc(*op, sizeof(char)*((4*po)+5) );         if (*op == 0) {            exits("REALLOC");        }    }     return strlen(*op);}