#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>

int decode_b64char( int ch )
{
    int		sextet;

    if( ('A' <= ch) && (ch <= 'Z') )
	sextet = ch - 'A';
    else if( ('a' <= ch) && (ch <= 'z') )
	sextet = (ch - 'a') + 26;
    else if( ('0' <= ch) && (ch <= '9') )
	sextet = (ch - '0') + 52;
    else if( ch == '+' )
	sextet = 62;
    else if( ch == '/' )
	sextet = 63;
    else {
	fprintf( stderr, (isprint(ch) ? "Illegal base64 character '%c'\n" :
					"Illegal base64 character 0x%02x\n"),
		 ch );
	exit( EXIT_FAILURE );
    }

    return( sextet );
}


main( int argc, char *argv[] )
{
    FILE	*fin;
    FILE	*fout;
    int		flushing = 0;
    int		temp = 0;
    int		bits = 0;
    int		ch;

    if( argc < 2 ) {
	fprintf( stderr, "Usage: b64decode <infile> [outfile]\n" );
	exit( EXIT_SUCCESS );
    }

    fin = fopen( argv[1], "r" );
    if( fin == NULL ) {
	perror( "openin" );
	exit( EXIT_FAILURE );
    }

    if( argc < 3 )
	fout = stdout;
    else {
	fout = fopen( argv[2], "wb" );
	if( fout == NULL ) {
	    perror( "openout" );
	    fclose( fin );
	    exit( EXIT_FAILURE );
	}
    }

    while( (ch = fgetc( fin )) != EOF ) {
	if( !isspace(ch) ) {
	    if( flushing ) {
		if( ch != '=' ) {
		    fprintf( stderr, "Illegal character in EOF padding\n" );
		    exit( EXIT_FAILURE );
		}
	    }
	    else {
		if( ch == '=' )
		    flushing = 1;
		else {
		    temp <<= 6;
		    temp |= decode_b64char( ch );
		    bits += 6;
		    if( bits >= 8 ) {
			bits -= 8;
			fputc( (0xff & (temp >> bits)), fout );
		    }
		}
	    }
	}
    }

    fclose( fout );
    fclose( fin );
}
------------------- End b64decode.c

------------------- Begin b64encode.c
#include <stdlib.h>
#include <stdio.h>

#define	MAXLINELEN	76

static const char	b64chars[] = 
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/*   0000000000000000111111111111111122222222222222223333333333333333	*/
/*   0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF	*/

main( int argc, char *argv[] )
{
    FILE	*fin;
    FILE	*fout;
    int		octet;
    int		temp = 0;
    int		bits = 0;
    int		linelen = 0;

    if( argc < 2 ) {
	fprintf( stderr, "Usage: b64encode <infile> [outfile]\n" );
	exit( EXIT_SUCCESS );
    }

    fin = fopen( argv[1], "rb" );
    if( fin == NULL ) {
	perror( "openin" );
	exit( EXIT_FAILURE );
    }

    if( argc < 3 )
	fout = stdout;
    else {
	fout = fopen( argv[2], "w" );
	if( fout == NULL ) {
	    perror( "openout" );
	    fclose( fin );
	    exit( EXIT_FAILURE );
	}
    }

    while( (octet = fgetc( fin )) != EOF ) {
	temp <<= 8;
	temp |= 0xff & octet;
	bits += 8;
	while( bits >= 6 ) {
	    bits -= 6;
	    fputc( b64chars[ 0x3f & (temp >> bits) ], fout );
	    if( ++linelen >= MAXLINELEN ) {
		fputc( '\n', fout );
		linelen = 0;
	    }
	}
    }
    if( bits > 0 ) {
	temp <<= 6 - bits;
	fputc( b64chars[ 0x3f & temp ], fout );
	if( bits == 4 )
	    fputc( '=', fout );
	else if( bits == 2 ) {
	    fputc( '=', fout );
	    fputc( '=', fout );
	}
	fputc( '\n', fout );
    }

    fclose( fout );
    fclose( fin );
    exit( EXIT_SUCCESS );
}
------------------- End b64encode.c


