base64.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C), 2000-2002 by Contributors to the monit codebase. 
00003  * All Rights Reserved.
00004  *
00005  * This program is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU General Public License as
00007  * published by the Free Software Foundation; either version 2 of the
00008  * License, or (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful, but
00011  * WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * General Public License for more details.
00014  * 
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software Foundation,
00017  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00018  */
00019 
00020 #include <config.h>
00021 
00022 #include <stdio.h>
00023 #include <string.h>
00024 #include <stdlib.h>
00025 
00026 #ifdef HAVE_STRING_H
00027 #include <string.h>
00028 #endif
00029 
00030 #include "monitor.h"
00031 #include "base64.h"
00032 
00033 /* Private prototypes */
00034 static int is_base64(char c);
00035 static char encode(unsigned char u);
00036 static unsigned char decode(char c);
00037 
00038 
00051 /* ------------------------------------------------------------------ Public */
00052 
00053 
00054 
00065 int encode_base64(char **dest, int size, unsigned char *src) {
00066 
00067   if(src ) {
00068     
00069     int i;
00070     char *out, *p;
00071     
00072     if(0 == size ) {
00073       
00074       size= strlen(src);
00075       
00076     }
00077     
00078     out= xmalloc(size*4/3+4);
00079     
00080     memset(out, 0, (size*4/3+4));
00081 
00082     p= out;
00083     
00084     for(i=0; i<size; i+=3) {
00085       
00086       unsigned char b1=0, b2=0, b3=0, b4=0, b5=0, b6=0, b7=0;
00087       
00088       b1 = src[i];
00089       
00090       if(i+1<size) {
00091     
00092     b2 = src[i+1];
00093     
00094       }
00095       
00096       if(i+2<size) {
00097     
00098     b3 = src[i+2];
00099     
00100       }
00101       
00102       b4= b1>>2;
00103       b5= ((b1&0x3)<<4)|(b2>>4);
00104       b6= ((b2&0xf)<<2)|(b3>>6);
00105       b7= b3&0x3f;
00106       
00107       
00108       *p++= encode(b4);
00109       *p++= encode(b5);
00110       
00111       if(i+1<size) {
00112     
00113     *p++= encode(b6);
00114     
00115       } else {
00116     
00117     *p++= '=';
00118     
00119       }
00120       
00121       if(i+2<size) {
00122     
00123     *p++= encode(b7);
00124     
00125       } else {
00126     
00127     *p++= '=';
00128     
00129       }
00130 
00131     }
00132 
00133     *dest= out;
00134     
00135     return((p-out));
00136 
00137   }
00138   
00139   return FALSE;
00140   
00141 }
00142 
00143 
00153 int decode_base64(unsigned char *dest, const char *src) {
00154 
00155   if(src ) {
00156   
00157     unsigned char *p= dest;
00158     int k, l= strlen(src)+1;
00159     unsigned char *buf= xmalloc(l);
00160 
00161     
00162     /* Ignore non base64 chars as per the POSIX standard */
00163     for(k=0, l=0; src[k]; k++) {
00164       
00165       if(is_base64(src[k])) {
00166     
00167     buf[l++]= src[k];
00168     
00169       }
00170       
00171     } 
00172     
00173     for(k=0; k<l; k+=4) {
00174       
00175       char c1='A', c2='A', c3='A', c4='A';
00176       unsigned char b1=0, b2=0, b3=0, b4=0;
00177       
00178       c1= buf[k];
00179       
00180       if(k+1<l) {
00181     
00182     c2= buf[k+1];
00183     
00184       }
00185       
00186       if(k+2<l) {
00187     
00188     c3= buf[k+2];
00189     
00190       }
00191       
00192       if(k+3<l) {
00193     
00194     c4= buf[k+3];
00195     
00196       }
00197       
00198       b1= decode(c1);
00199       b2= decode(c2);
00200       b3= decode(c3);
00201       b4= decode(c4);
00202       
00203       *p++=((b1<<2)|(b2>>4) );
00204       
00205       if(c3 != '=') {
00206     
00207     *p++=(((b2&0xf)<<4)|(b3>>2) );
00208     
00209       }
00210       
00211       if(c4 != '=') {
00212     
00213     *p++=(((b3&0x3)<<6)|b4 );
00214     
00215       }
00216       
00217     }
00218     
00219     free(buf);
00220     
00221     return(p-dest);
00222 
00223   }
00224 
00225   return FALSE;
00226   
00227 }
00228 
00229 
00230 /* ----------------------------------------------------------------- Private */
00231 
00232 
00236 static char encode(unsigned char u) {
00237 
00238   if(u < 26)  return 'A'+u;
00239   if(u < 52)  return 'a'+(u-26);
00240   if(u < 62)  return '0'+(u-52);
00241   if(u == 62) return '+';
00242   
00243   return '/';
00244 
00245 }
00246 
00247 
00251 static unsigned char decode(char c) {
00252   
00253   if(c >= 'A' && c <= 'Z') return(c - 'A');
00254   if(c >= 'a' && c <= 'z') return(c - 'a' + 26);
00255   if(c >= '0' && c <= '9') return(c - '0' + 52);
00256   if(c == '+')             return 62;
00257   
00258   return 63;
00259   
00260 }
00261 
00262 
00266 static int is_base64(char c) {
00267 
00268   if((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
00269      (c >= '0' && c <= '9') || (c == '+')             ||
00270      (c == '/')             || (c == '=')) {
00271     
00272     return TRUE;
00273     
00274   }
00275   
00276   return FALSE;
00277 
00278 }
00279 
00280