Annotation of sbbs/sbbs3/base64.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.