Back to index

courier  0.68.2
base64.c
Go to the documentation of this file.
00001 /*
00002 ** Copyright 2002 Double Precision, Inc.  See COPYING for
00003 ** distribution information.
00004 */
00005 
00006 #include "rfc2045_config.h"
00007 #include "base64.h"
00008 
00009 #include <string.h>
00010 #include <stdio.h>
00011 
00012 void base64_decode_init(struct base64decode *b,
00013                      int (*f)(const char *, int, void *),
00014                      void *a)
00015 {
00016        b->workbuflen=0;
00017        b->decode_func=f;
00018        b->decode_func_arg=a;
00019 }
00020 
00021 static int doflush(struct base64decode *);
00022 
00023 static const char base64tab[]=
00024 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
00025 
00026 int base64_decode(struct base64decode *b, const char *p, int l)
00027 {
00028        while (l)
00029        {
00030               char c;
00031 
00032               if (b->workbuflen >= sizeof(b->workbuf))
00033               {
00034                      int rc=doflush(b);
00035 
00036                      if (rc)
00037                             return (rc);
00038               }
00039 
00040 
00041               if (*p == '=')
00042               {
00043                      c=100;
00044               }
00045               else
00046               {
00047                      char *s=strchr(base64tab, *p);
00048 
00049                      if (s == NULL)
00050                      {
00051                             ++p;
00052                             --l;
00053                             continue;
00054                      }
00055 
00056                      c= s-base64tab;
00057               }
00058               b->workbuf[b->workbuflen++]=c;
00059               ++p;
00060               --l;
00061        }
00062        return (0);
00063 }
00064 
00065 int base64_decode_end(struct base64decode *b)
00066 {
00067        return (doflush(b));
00068 }
00069 
00070 static int doflush(struct base64decode *p)
00071 {
00072        int i=p->workbuflen / 4;
00073        int j;
00074        int k=0;
00075 
00076        i= i * 4;
00077 
00078        for (j=0; j<i; j += 4)
00079        {
00080               char   a,b,c;
00081 
00082               int    w=p->workbuf[j];
00083               int    x=p->workbuf[j+1];
00084               int    y=p->workbuf[j+2];
00085               int    z=p->workbuf[j+3];
00086 
00087               a= (w << 2) | (x >> 4);
00088               b= (x << 4) | (y >> 2);
00089               c= (y << 6) | z;
00090               p->workbuf[k++]=a;
00091               if ( y != 100)
00092                      p->workbuf[k++]=b;
00093               if ( z != 100)
00094                      p->workbuf[k++]=c;
00095        }
00096 
00097        j= (*p->decode_func)(p->workbuf, k, p->decode_func_arg);
00098 
00099        k=0;
00100        while (i < p->workbuflen)
00101        {
00102               p->workbuf[k]=p->workbuf[i];
00103               ++k;
00104               ++i;
00105        }
00106        p->workbuflen=k;
00107        return (j);
00108 }
00109 
00110 /* ---- */
00111 
00112 static int save_str(const char *p, int l, void *vp)
00113 {
00114        memcpy(*(char **)vp, p, l);
00115 
00116        *(char **)vp += l;
00117        return (0);
00118 }
00119 
00120 char *base64_decode_str(const char *s)
00121 {
00122        struct base64decode b;
00123 
00124        char *p=strdup(s);
00125        char *pp;
00126 
00127        if (!p)
00128               return (NULL);
00129 
00130        pp= p;
00131 
00132        base64_decode_init(&b, save_str, &pp);
00133        base64_decode(&b, s, strlen(s));
00134        base64_decode_end(&b);
00135        *pp=0;
00136        return p;
00137 }