home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 35 Internet
/
35-Internet.zip
/
uuencdec.zip
/
UUENCODE.C
< prev
Wrap
Text File
|
1987-08-26
|
4KB
|
145 lines
/** UUENCODE.C
*
* Binary file encoder program - used primarily for translating files
* to be sent by ASCII mail
*
* MS-DOS Version: Keith D Gregory, August-87
*
******************************************************************************
* Modification History *
* Date Seq Who Description *
* --------- --- --- ------------------------------------------------ *
* 25-Aug-87 1.0 kdg Creation *
*****************************************************************************/
#include "stdio.h"
#include "string.h"
/**
*** Forward definitions . . .
**/
extern void encode();
extern void outbytes( unsigned char * );
/**
*** This macro is what converts a six-bit value into a printable ASCII char
*** (if the value should happen to be >64, it will be chopped to fit)
**/
#define ENC(c) ((c & 0x3F) + ' ')
FILE *inputfile; /* May be real file or STDIN */
void main( argc, argv )
int argc;
char *argv[];
{
int destmode = 0644; /* Desired destination mode */
char filename[64], /* Pathname for desired file */
*optptr; /* Temp ptr for extracting mode */
filename[0] = '\0';
if (argc > 1) /* May have options or inputname */
if (argv[1][0] == '-') /* Has options */
{
if ((optptr = strpbrk( argv[1], "Mm" )) != NULL)
sscanf( ++optptr, "%o", &destmode );
if (argc == 3)
strcpy( filename, argv[2] );
}
else if (argc == 3) /* Options improperly specified */
{
fprintf( stderr, "\nUUENCODE: Arguments improperly specified" );
exit( 1 );
}
else
strcpy( filename, argv[1] );
if (!*filename)
{
inputfile = stdin;
strcpy( filename, "uuencode.000" );
}
else if ((inputfile = fopen( filename, "rb" )) == NULL)
{
fprintf( stderr, "UUENCODE: Unable to open Input File" );
exit( 1 );
}
if (strchr(filename, '\\') != NULL)
printf( "\nbegin %o %s\n", destmode, strrchr(filename, '\\')+1 );
else
printf( "\nbegin %o %s\n", destmode, filename );
encode();
printf( "end\n" );
}
/***
**** Read input, sending coded bytes to standard output. We use a subroutine
**** to output each group of 3 bytes - note that, if a line is less than a
**** multiple of 3 bytes, then 1 or 2 garbage bytes may be put on the end.
***/
void encode()
{
unsigned char buf[47]; /* Input lines may be 1..45 bytes */
int index,
numbytes = 1; /* Number of bytes in this line */
while (numbytes > 0)
{
numbytes = fread( buf, sizeof(char), 45, inputfile );
putchar( ENC(numbytes) );
for (index = 0 ; index < numbytes ; index += 3)
outbytes( &buf[index] );
printf( "\n" );
}
}
/***
**** outbytes
****
**** Given a pointer to a stream of bytes, this routine will encode the
**** next three and output them (as 4 ASCII characters).
****
**** The 3 x 8-bits to 4 x 6-bits conversion results in the following:
**** (A,B,C are subsequent input bytes, D,E,F,G are subsequent output
**** bytes; this routine performs A B C ==> D E F G)
****
**** D = High order 6 bits of A in bits 0..5
**** E = Low order 2 bits of A in bits 4..5
**** High order 4 bits of B in bits 0..3
**** F = Low order 4 bits of B in bits 2..5
**** High order 2 bits of C in buts 0..1
**** G = Low order 6 bits of C in bits 2..5
***/
void outbytes( ptr )
unsigned char *ptr;
{
unsigned d,e,f,g,
a = *ptr++,
b = *ptr++,
c = *ptr;
d = a >> 2;
e = ((a << 4) & 0x30) | ((b >> 4) & 0x0F);
f = ((b << 2) & 0x3C) | ((c >> 6) & 0x03);
g = c & 0x3F;
putchar( ENC(d) );
putchar( ENC(e) );
putchar( ENC(f) );
putchar( ENC(g) );
}