00001 #include <stdio.h>
00002 #include <stdlib.h>
00003
00004 #include "encode.h"
00005
00006
00007
00008
00009
00010
00011
00012
00013 void encodeblock( unsigned char in[3], unsigned char out[4], int len )
00014 {
00015 out[0] = cb64[ in[0] >> 2 ];
00016 out[1] = cb64[ ((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4) ];
00017 out[2] = (unsigned char) (len > 1 ? cb64[ ((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6) ] : '=');
00018 out[3] = (unsigned char) (len > 2 ? cb64[ in[2] & 0x3f ] : '=');
00019 }
00020
00021
00022
00023
00024
00025
00026 void encode( FILE *infile, FILE *outfile, int linesize )
00027 {
00028 unsigned char in[3], out[4];
00029 int i, len, blocksout = 0;
00030
00031 while( !feof( infile ) ) {
00032 len = 0;
00033 for( i = 0; i < 3; i++ ) {
00034 in[i] = (unsigned char) getc( infile );
00035 if( !feof( infile ) ) {
00036 len++;
00037 }
00038 else {
00039 in[i] = 0;
00040 }
00041 }
00042 if( len ) {
00043 encodeblock( in, out, len );
00044 for( i = 0; i < 4; i++ ) {
00045 putc( out[i], outfile );
00046 }
00047 blocksout++;
00048 }
00049 if( blocksout >= (linesize/4) || feof( infile ) ) {
00050 if( blocksout ) {
00051 fprintf( outfile, "\r\n" );
00052 }
00053 blocksout = 0;
00054 }
00055 }
00056 }
00057
00058
00059
00060
00061
00062
00063 void decodeblock( unsigned char in[4], unsigned char out[3] )
00064 {
00065 out[ 0 ] = (unsigned char ) (in[0] << 2 | in[1] >> 4);
00066 out[ 1 ] = (unsigned char ) (in[1] << 4 | in[2] >> 2);
00067 out[ 2 ] = (unsigned char ) (((in[2] << 6) & 0xc0) | in[3]);
00068 }
00069
00070
00071
00072
00073
00074
00075 void decode( FILE *infile, FILE *outfile )
00076 {
00077 unsigned char in[4], out[3], v;
00078 int i, len;
00079
00080 while( !feof( infile ) ) {
00081 for( len = 0, i = 0; i < 4 && !feof( infile ); i++ ) {
00082 v = 0;
00083 while( !feof( infile ) && v == 0 ) {
00084 v = (unsigned char) getc( infile );
00085 v = (unsigned char) ((v < 43 || v > 122) ? 0 : cd64[ v - 43 ]);
00086 if( v ) {
00087 v = (unsigned char) ((v == '$') ? 0 : v - 61);
00088 }
00089 }
00090 if( !feof( infile ) ) {
00091 len++;
00092 if( v ) {
00093 in[ i ] = (unsigned char) (v - 1);
00094 }
00095 }
00096 else {
00097 in[i] = 0;
00098 }
00099 }
00100 if( len ) {
00101 decodeblock( in, out );
00102 for( i = 0; i < len - 1; i++ ) {
00103 putc( out[i], outfile );
00104 }
00105 }
00106 }
00107 }
00108
00109
00110
00111
00112
00113
00114
00115
00116 char *b64_message( int errcode )
00117 {
00118 #define B64_MAX_MESSAGES 6
00119 char *msgs[ B64_MAX_MESSAGES ] = {
00120 "b64:000:Invalid Message Code.",
00121 "b64:001:Syntax Error -- check help for usage.",
00122 "b64:002:File Error Opening/Creating Files.",
00123 "b64:003:File I/O Error -- Note: output file not removed.",
00124 "b64:004:Error on output file close.",
00125 "b64:004:linesize set to minimum."
00126 };
00127 char *msg = msgs[ 0 ];
00128
00129 if( errcode > 0 && errcode < B64_MAX_MESSAGES ) {
00130 msg = msgs[ errcode ];
00131 }
00132
00133 return( msg );
00134 }
00135
00136
00137
00138
00139
00140
00141
00142 int b64( int opt, char *infilename, char *outfilename, int linesize )
00143 {
00144 FILE *infile;
00145 int retcode = B64_FILE_ERROR;
00146
00147 if( !infilename ) {
00148 infile = stdin;
00149 }
00150 else {
00151 infile = fopen( infilename, "rb" );
00152 }
00153 if( !infile ) {
00154 perror( infilename );
00155 }
00156 else {
00157 FILE *outfile;
00158 if( !outfilename ) {
00159 outfile = stdout;
00160 }
00161 else {
00162 outfile = fopen( outfilename, "wb" );
00163 }
00164 if( !outfile ) {
00165 perror( outfilename );
00166 }
00167 else {
00168 if( opt == 'e' ) {
00169 encode( infile, outfile, linesize );
00170 }
00171 else {
00172 decode( infile, outfile );
00173 }
00174 if (ferror( infile ) || ferror( outfile )) {
00175 retcode = B64_FILE_IO_ERROR;
00176 }
00177 else {
00178 retcode = 0;
00179 }
00180 if( outfile != stdout ) {
00181 if( fclose( outfile ) != 0 ) {
00182 perror( b64_message( B64_ERROR_OUT_CLOSE ) );
00183 retcode = B64_FILE_IO_ERROR;
00184 }
00185 }
00186 }
00187 if( infile != stdin ) {
00188 fclose( infile );
00189 }
00190 }
00191
00192 return( retcode );
00193 }
00194
00195
00196
00197
00198
00199
00200 void showuse( int morehelp )
00201 {
00202 {
00203 printf( "\n" );
00204 printf( " b64 (Base64 Encode/Decode) Bob Trower 08/03/01 \n" );
00205 printf( " (C) Copr Bob Trower 1986-01. Version 0.00B \n" );
00206 printf( " Usage: b64 -option [ -l num ] [<FileIn> [<FileOut>]] \n" );
00207 printf( " Purpose: This program is a simple utility that implements\n" );
00208 printf( " Base64 Content-Transfer-Encoding (RFC1113). \n" );
00209 }
00210 if( !morehelp ) {
00211 printf( " Use -h option for additional help. \n" );
00212 }
00213 else {
00214 printf( " Options: -e encode to Base64 -h This help text. \n" );
00215 printf( " -d decode from Base64 -? This help text. \n" );
00216 printf( " Note: -l use to change line size (from 72 characters)\n" );
00217 printf( " Returns: 0 = success. Non-zero is an error code. \n" );
00218 printf( " ErrCode: 1 = Bad Syntax, 2 = File Open, 3 = File I/O \n" );
00219 printf( " Example: b64 -e binfile b64file <- Encode to b64 \n" );
00220 printf( " b64 -d b64file binfile <- Decode from b64 \n" );
00221 printf( " b64 -e -l40 infile outfile <- Line Length of 40 \n" );
00222 printf( " Note: Will act as a filter, but this should only be \n" );
00223 printf( " used on text files due to translations made by \n" );
00224 printf( " operating systems. \n" );
00225 printf( " Release: 0.00.00, Tue Aug 7 2:00:00 2001, ANSI-SOURCE C\n" );
00226 }
00227 }
00228
00229 #define B64_DEF_LINE_SIZE 72
00230 #define B64_MIN_LINE_SIZE 4
00231
00232 #define THIS_OPT(ac, av) (ac > 1 ? av[1][0] == '-' ? av[1][1] : 0 : 0)
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292