|
|
1.1 ! root 1: /* base64.c */ ! 2: ! 3: /* Base64 encoding/decoding routines */ ! 4: ! 5: /* $Id: base64.c,v 1.21 2004/09/17 07:56:56 rswindell Exp $ */ ! 6: ! 7: /**************************************************************************** ! 8: * @format.tab-size 4 (Plain Text/Source Code File Header) * ! 9: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * ! 10: * * ! 11: * Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html * ! 12: * * ! 13: * This program is free software; you can redistribute it and/or * ! 14: * modify it under the terms of the GNU General Public License * ! 15: * as published by the Free Software Foundation; either version 2 * ! 16: * of the License, or (at your option) any later version. * ! 17: * See the GNU General Public License for more details: gpl.txt or * ! 18: * http://www.fsf.org/copyleft/gpl.html * ! 19: * * ! 20: * Anonymous FTP access to the most recent released source is available at * ! 21: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * ! 22: * * ! 23: * Anonymous CVS access to the development source and modification history * ! 24: * is available at cvs.synchro.net:/cvsroot/sbbs, example: * ! 25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login * ! 26: * (just hit return, no password is necessary) * ! 27: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src * ! 28: * * ! 29: * For Synchronet coding style and modification guidelines, see * ! 30: * http://www.synchro.net/source.html * ! 31: * * ! 32: * You are encouraged to submit any modifications (preferably in Unix diff * ! 33: * format) via e-mail to [email protected] * ! 34: * * ! 35: * Note: If this box doesn't appear square, then you need to fix your tabs. * ! 36: ****************************************************************************/ ! 37: ! 38: #include <stdlib.h> ! 39: #include <string.h> ! 40: #include "base64.h" ! 41: ! 42: static const char * base64alphabet = ! 43: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; ! 44: ! 45: int b64_decode(char *target, size_t tlen, const char *source, size_t slen) ! 46: { ! 47: const char *inp; ! 48: char *outp; ! 49: char *outend; ! 50: const char *inend; ! 51: int bits=0; ! 52: int working=0; ! 53: char * i; ! 54: ! 55: if(slen==0) ! 56: slen=strlen(source); ! 57: outp=target; ! 58: inp=source; ! 59: outend=target+tlen; ! 60: inend=source+slen; ! 61: for(;outp<outend && inp<inend;inp++) { ! 62: working<<=6; ! 63: i=strchr(base64alphabet,(char)*inp); ! 64: if(i==NULL) { ! 65: return(-1); ! 66: } ! 67: if(*i=='=') { /* pad char */ ! 68: if((working&0xFF) != 0) ! 69: return(-1); ! 70: break; ! 71: } ! 72: bits+=6; ! 73: working |= (i-base64alphabet); ! 74: if(bits>=8) { ! 75: *(outp++)=(char)((working&(0xFF<<(bits-8)))>>(bits-8)); ! 76: bits-=8; ! 77: } ! 78: } ! 79: if(outp == outend) { ! 80: *(--outp)=0; ! 81: return(-1); ! 82: } ! 83: *outp=0; ! 84: return(outp-target); ! 85: } ! 86: ! 87: static int add_char(char *pos, char ch, int done, char *end) ! 88: { ! 89: if(pos>=end) { ! 90: return(1); ! 91: } ! 92: if(done) ! 93: *pos=base64alphabet[64]; ! 94: else ! 95: *pos=base64alphabet[(int)ch]; ! 96: return(0); ! 97: } ! 98: ! 99: int b64_encode(char *target, size_t tlen, const char *source, size_t slen) { ! 100: const char *inp; ! 101: char *outp; ! 102: char *outend; ! 103: const char *inend; ! 104: char *tmpbuf=NULL; ! 105: int done=0; ! 106: char enc; ! 107: int buf; ! 108: ! 109: if(slen==0) ! 110: slen=strlen(source); ! 111: inp=source; ! 112: if(source==target) { ! 113: tmpbuf=(char *)malloc(tlen); ! 114: if(tmpbuf==NULL) ! 115: return(-1); ! 116: outp=tmpbuf; ! 117: } ! 118: else ! 119: outp=target; ! 120: ! 121: outend=outp+tlen; ! 122: inend=inp+slen; ! 123: for(;(inp < inend) && !done;) { ! 124: enc=*(inp++); ! 125: buf=(enc & 0x03)<<4; ! 126: enc=(enc&0xFC)>>2; ! 127: if(add_char(outp++, enc, done, outend)) { ! 128: if(target==source) ! 129: free(tmpbuf); ! 130: return(-1); ! 131: } ! 132: enc=buf|((*inp & 0xF0) >> 4); ! 133: if(add_char(outp++, enc, done, outend)) { ! 134: if(target==source) ! 135: free(tmpbuf); ! 136: return(-1); ! 137: } ! 138: if(inp==inend) ! 139: done=1; ! 140: buf=(*(inp++)<<2)&0x3C; ! 141: enc=buf|((*inp & 0xC0)>>6); ! 142: if(add_char(outp++, enc, done, outend)) { ! 143: if(target==source) ! 144: free(tmpbuf); ! 145: return(-1); ! 146: } ! 147: if(inp==inend) ! 148: done=1; ! 149: enc=((int)*(inp++))&0x3F; ! 150: if(add_char(outp++, enc, done, outend)) { ! 151: if(target==source) ! 152: free(tmpbuf); ! 153: return(-1); ! 154: } ! 155: if(inp==inend) ! 156: done=1; ! 157: } ! 158: if(outp<outend) ! 159: *outp=0; ! 160: if(target==source) { ! 161: memcpy(target,tmpbuf,tlen); ! 162: free(tmpbuf); ! 163: } ! 164: return(outp-target); ! 165: } ! 166: ! 167: #ifdef BASE64_TEST ! 168: int main(int argc, char**argv) ! 169: { ! 170: int i,j; ! 171: char buf[512]; ! 172: ! 173: for(i=1;i<argc;i++) { ! 174: j=b64_decode(buf,sizeof(buf),argv[i],0); ! 175: printf("%s (%d)\n",buf,j); ! 176: } ! 177: ! 178: return 0; ! 179: } ! 180: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.