|
|
1.1 ! root 1: /* base64.c */ ! 2: ! 3: /* Base64 encoding/decoding routines */ ! 4: ! 5: /* $Id: base64.c,v 1.23 2006/05/08 21:11:40 deuce 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: #include "gen_defs.h" ! 42: ! 43: static const char * base64alphabet = ! 44: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; ! 45: ! 46: int b64_decode(char *target, size_t tlen, const char *source, size_t slen) ! 47: { ! 48: const char *inp; ! 49: char *outp; ! 50: char *outend; ! 51: const char *inend; ! 52: int bits=0; ! 53: int working=0; ! 54: char * i; ! 55: ! 56: if(slen==0) ! 57: slen=strlen(source); ! 58: outp=target; ! 59: inp=source; ! 60: outend=target+tlen; ! 61: inend=source+slen; ! 62: for(;outp<outend && inp<inend;inp++) { ! 63: working<<=6; ! 64: i=strchr(base64alphabet,(char)*inp); ! 65: if(i==NULL) { ! 66: return(-1); ! 67: } ! 68: if(*i=='=') { /* pad char */ ! 69: if((working&0xFF) != 0) ! 70: return(-1); ! 71: break; ! 72: } ! 73: bits+=6; ! 74: working |= (i-base64alphabet); ! 75: if(bits>=8) { ! 76: *(outp++)=(char)((working&(0xFF<<(bits-8)))>>(bits-8)); ! 77: bits-=8; ! 78: } ! 79: } ! 80: if(outp == outend) { ! 81: *(--outp)=0; ! 82: return(-1); ! 83: } ! 84: *outp=0; ! 85: return(outp-target); ! 86: } ! 87: ! 88: static int add_char(char *pos, char ch, int done, char *end) ! 89: { ! 90: if(pos>=end) { ! 91: return(1); ! 92: } ! 93: if(done) ! 94: *pos=base64alphabet[64]; ! 95: else ! 96: *pos=base64alphabet[(int)ch]; ! 97: return(0); ! 98: } ! 99: ! 100: int b64_encode(char *target, size_t tlen, const char *source, size_t slen) { ! 101: const char *inp; ! 102: char *outp; ! 103: char *outend; ! 104: const char *inend; ! 105: char *tmpbuf=NULL; ! 106: int done=0; ! 107: char enc; ! 108: int buf; ! 109: ! 110: if(slen==0) ! 111: slen=strlen(source); ! 112: inp=source; ! 113: if(source==target) { ! 114: tmpbuf=(char *)malloc(tlen); ! 115: if(tmpbuf==NULL) ! 116: return(-1); ! 117: outp=tmpbuf; ! 118: } ! 119: else ! 120: outp=target; ! 121: ! 122: outend=outp+tlen; ! 123: inend=inp+slen; ! 124: for(;(inp < inend) && !done;) { ! 125: enc=*(inp++); ! 126: buf=(enc & 0x03)<<4; ! 127: enc=(enc&0xFC)>>2; ! 128: if(add_char(outp++, enc, done, outend)) { ! 129: FREE_AND_NULL(tmpbuf); ! 130: return(-1); ! 131: } ! 132: enc=buf|((*inp & 0xF0) >> 4); ! 133: if(add_char(outp++, enc, done, outend)) { ! 134: FREE_AND_NULL(tmpbuf); ! 135: return(-1); ! 136: } ! 137: if(inp==inend) ! 138: done=1; ! 139: buf=(*(inp++)<<2)&0x3C; ! 140: enc=buf|((*inp & 0xC0)>>6); ! 141: if(add_char(outp++, enc, done, outend)) { ! 142: FREE_AND_NULL(tmpbuf); ! 143: return(-1); ! 144: } ! 145: if(inp==inend) ! 146: done=1; ! 147: enc=((int)*(inp++))&0x3F; ! 148: if(add_char(outp++, enc, done, outend)) { ! 149: FREE_AND_NULL(tmpbuf); ! 150: return(-1); ! 151: } ! 152: if(inp==inend) ! 153: done=1; ! 154: } ! 155: if(outp<outend) ! 156: *outp=0; ! 157: if(target==source) { ! 158: memcpy(target,tmpbuf,tlen); ! 159: free(tmpbuf); ! 160: } ! 161: ! 162: return(outp-target); ! 163: } ! 164: ! 165: #ifdef BASE64_TEST ! 166: int main(int argc, char**argv) ! 167: { ! 168: int i,j; ! 169: char buf[512]; ! 170: ! 171: for(i=1;i<argc;i++) { ! 172: j=b64_decode(buf,sizeof(buf),argv[i],0); ! 173: printf("%s (%d)\n",buf,j); ! 174: } ! 175: ! 176: return 0; ! 177: } ! 178: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.