home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 35 Internet
/
35-Internet.zip
/
uuencdec.zip
/
UUDECODE.C
< prev
next >
Wrap
Text File
|
1987-08-26
|
6KB
|
175 lines
/** UUENCODE.C
*
* Binary file decoder 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 decode();
extern void decbytes( unsigned char *, unsigned char * );
/**
*** This macro is what converts a printable ASCII char into a 6 bit value
**/
#define DEC(c) ((c - ' ') & 0x3F)
FILE *inputfile, /* May be real file or STDIN */
*outputfile; /* May be real file or STDOUT */
char inputbuf[80]; /* Generic input buffer */
void main( argc, argv )
int argc;
char *argv[];
{
char inputbuf[80]; /* Generic input buffer */
char in_fname[64], /* Pathname for desired files */
out_fname[64];
unsigned destmode; /* Destination mode (ignored) */
in_fname[0] = out_fname[0] = '\0';
if (argc > 2)
{
fprintf( stderr, "\nUUDECODE: Invalid arguments" );
fprintf( stderr, "\n\nUsage: uudecode [infile]" );
exit( 1 );
}
if (argc == 2)
{
strcpy( in_fname, argv[1] );
if ((inputfile = fopen(in_fname, "r")) == NULL)
{
fprintf( stderr, "UUDECODE: Input File does not exist" );
exit( 1 );
}
}
else
inputfile = stdin;
while(1) /* Find beginning of encoded file */
{
if (fgets( inputbuf, 80, inputfile ) == NULL)
{
fprintf( stderr, "UUDECODE: Not a valid encoded file" );
exit( 2 );
}
if (!strncmp( inputbuf, "begin", 5 ))
break;
}
sscanf( inputbuf, "begin %o %s", &destmode, out_fname );
if (strchr( out_fname, '/' ) != NULL)
{
strcpy( inputbuf, strrchr( out_fname, '/') );
strcpy( out_fname, inputbuf );
}
if (fopen( out_fname, "rb" ) != NULL)
{
fprintf( stderr, "UUDECODE: Output File already exists" );
exit( 1 );
}
else
outputfile = fopen(out_fname, "wb");
decode();
fcloseall();
}
/***
**** decode
****
**** This function works its way through the file, a line at a time,
**** decodeing as it goes. If the beginning of the line is "end",
**** then a normal return occurs. If "end" line is not reached before
**** the end of the file, then a message "Short File" is printed, but
**** this routine terminates "normally" - thus, the file is saved.
***/
void decode()
{
char inputbuf[80]; /* ASCII input buffer */
unsigned char outputbuf[80]; /* Binary output buffer */
int linesize, /* How many bytes encoded in line*/
index1, index2; /* Way to move through buffers */
while(1)
{
if (fgets( inputbuf, 80, inputfile ) == NULL)
{
fprintf( stderr, "UUDECODE: File too short" );
return;
}
if (!strncmp(inputbuf, "end", 3))
return;
linesize = DEC( inputbuf[0] );
for (index1=1, index2=0 ; index2 < linesize ; index1+=4, index2+=3 )
decbytes( &inputbuf[index1], &outputbuf[index2] );
fwrite( outputbuf, sizeof(unsigned char), linesize, outputfile );
}
}
/***
**** decbytes
****
**** Given a pointer to a stream of encoded bytes, this routine will take the
**** four characters following that pointer and decode them. A temporary
**** buffer should be used by the caller to store the decoded bytes - this
**** routine has no way of knowing when it has reached the end of the line,
**** and will blindly convert garbage bytes. The temporary buffer allows the
**** caller to select only those bytes desired.
****
**** The 3 x 8-bits to 4 x 6-bits conversion is as follows:
**** (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 0..5
***/
void decbytes( inptr, outptr )
unsigned char *inptr, *outptr;
{
unsigned char *a = outptr,
*b = outptr + 1,
*c = outptr + 2,
*d = inptr,
*e = inptr + 1,
*f = inptr + 2,
*g = inptr + 3;
*a = DEC(*d) << 2 | (DEC(*e) & 0x30) >> 4;
*b = (DEC(*e) & 0x0F) << 4 | (DEC(*f) & 0x3C) >> 2;
*c = (DEC(*f) & 0x03) << 6 | (DEC(*g) & 0x3F);
}