#ifdef USE_SVG #include "base64.h" /* ** encodeblock ** ** encode 3 8-bit binary bytes as 4 '6-bit' characters */ void encodeblock( unsigned char in[3], unsigned char out[4], int len ) { out[0] = cb64[ in[0] >> 2 ]; out[1] = cb64[ ((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4) ]; out[2] = (unsigned char) (len > 1 ? cb64[ ((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6) ] : '='); out[3] = (unsigned char) (len > 2 ? cb64[ in[2] & 0x3f ] : '='); } /* ** encode ** ** base64 encode a stream adding padding and line breaks as per spec. */ void encode( FILE *infile, FILE *outfile, int linesize ) { unsigned char in[3], out[4]; int i, len, blocksout = 0; while( !feof( infile ) ) { len = 0; for( i = 0; i < 3; i++ ) { in[i] = (unsigned char) getc( infile ); if( !feof( infile ) ) { len++; } else { in[i] = 0; } } if( len ) { encodeblock( in, out, len ); for( i = 0; i < 4; i++ ) { putc( out[i], outfile ); } blocksout++; } if( blocksout >= (linesize/4) || feof( infile ) ) { if( blocksout ) { fprintf( outfile, "\r\n" ); } blocksout = 0; } } } /* ** decodeblock ** ** decode 4 '6-bit' characters into 3 8-bit binary bytes */ void decodeblock( unsigned char in[4], unsigned char out[3] ) { out[ 0 ] = (unsigned char ) (in[0] << 2 | in[1] >> 4); out[ 1 ] = (unsigned char ) (in[1] << 4 | in[2] >> 2); out[ 2 ] = (unsigned char ) (((in[2] << 6) & 0xc0) | in[3]); } /* ** decode ** ** decode a base64 encoded stream discarding padding, line breaks and noise */ int decodeB64(char* inB64, char* outAscii) { unsigned char in[4], out[3], v; int i, len, outIndex = 0; while(*inB64) { for(len = 0, i = 0; i < 4 && *inB64; i++) { v = 0; while(*inB64 && v == 0) { v = (unsigned char) *(inB64++); v = (unsigned char) ((v < 43 || v > 122) ? 0 : cd64[v - 43]); if(v) { v = (unsigned char) ((v == '$') ? 0 : v - 61); } } if(*inB64) { len++; if(v) { in[i] = (unsigned char) (v - 1); } } else { in[i] = 0; } } if(len) { decodeblock(in, out); for(i = 0; i < len - 1; i++) { outAscii[outIndex++] = out[i]; } } } return outIndex; } /* ** decode ** ** decode a base64 encoded stream discarding padding, line breaks and noise */ void decode( FILE *infile, FILE *outfile ) { unsigned char in[4], out[3], v; int i, len; while( !feof( infile ) ) { for( len = 0, i = 0; i < 4 && !feof( infile ); i++ ) { v = 0; while( !feof( infile ) && v == 0 ) { v = (unsigned char) getc( infile ); v = (unsigned char) ((v < 43 || v > 122) ? 0 : cd64[ v - 43 ]); if( v ) { v = (unsigned char) ((v == '$') ? 0 : v - 61); } } if( !feof( infile ) ) { len++; if( v ) { in[ i ] = (unsigned char) (v - 1); } } else { in[i] = 0; } } if( len ) { decodeblock( in, out ); for( i = 0; i < len - 1; i++ ) { putc( out[i], outfile ); } } } } /* ** b64_message ** ** Gather text messages in one place. ** */ char *b64_message( int errcode ) { #define B64_MAX_MESSAGES 6 char *msgs[ B64_MAX_MESSAGES ] = { "b64:000:Invalid Message Code.", "b64:001:Syntax Error -- check help for usage.", "b64:002:File Error Opening/Creating Files.", "b64:003:File I/O Error -- Note: output file not removed.", "b64:004:Error on output file close.", "b64:004:linesize set to minimum." }; char *msg = msgs[ 0 ]; if( errcode > 0 && errcode < B64_MAX_MESSAGES ) { msg = msgs[ errcode ]; } return( msg ); } /* ** b64 ** ** 'engine' that opens streams and calls encode/decode */ int b64( int opt, char *infilename, char *outfilename, int linesize ) { FILE *infile; int retcode = B64_FILE_ERROR; if( !infilename ) { infile = stdin; } else { infile = CC_fopen( infilename, "rb" ); } if( !infile ) { perror( infilename ); } else { FILE *outfile; if( !outfilename ) { outfile = stdout; } else { outfile = CC_fopen( outfilename, "wb" ); } if( !outfile ) { perror( outfilename ); } else { if( opt == 'e' ) { encode( infile, outfile, linesize ); } else { decode( infile, outfile ); } if (ferror( infile ) || ferror( outfile )) { retcode = B64_FILE_IO_ERROR; } else { retcode = 0; } if( outfile != stdout ) { if( CC_fclose( outfile ) != 0 ) { perror( b64_message( B64_ERROR_OUT_CLOSE ) ); retcode = B64_FILE_IO_ERROR; } } } if( infile != stdin ) { CC_fclose( infile ); } } return( retcode ); } /* ** showuse ** ** display usage information, help, version info */ void showuse( int morehelp ) { { printf( "\n" ); printf( " b64 (Base64 Encode/Decode) Bob Trower 08/03/01 \n" ); printf( " (C) Copr Bob Trower 1986-01. Version 0.00B \n" ); printf( " Usage: b64 -option [ -l num ] [ []] \n" ); printf( " Purpose: This program is a simple utility that implements\n" ); printf( " Base64 Content-Transfer-Encoding (RFC1113). \n" ); } if( !morehelp ) { printf( " Use -h option for additional help. \n" ); } else { printf( " Options: -e encode to Base64 -h This help text. \n" ); printf( " -d decode from Base64 -? This help text. \n" ); printf( " Note: -l use to change line size (from 72 characters)\n" ); printf( " Returns: 0 = success. Non-zero is an error code. \n" ); printf( " ErrCode: 1 = Bad Syntax, 2 = File Open, 3 = File I/O \n" ); printf( " Example: b64 -e binfile b64file <- Encode to b64 \n" ); printf( " b64 -d b64file binfile <- Decode from b64 \n" ); printf( " b64 -e -l40 infile outfile <- Line Length of 40 \n" ); printf( " Note: Will act as a filter, but this should only be \n" ); printf( " used on text files due to translations made by \n" ); printf( " operating systems. \n" ); printf( " Release: 0.00.00, Tue Aug 7 2:00:00 2001, ANSI-SOURCE C\n" ); } } #endif //USE_SVG