home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / uuencdec.zip / UUDECODE.C < prev    next >
Text File  |  1987-08-26  |  6KB  |  175 lines

  1. /** UUENCODE.C
  2. *
  3. *   Binary file decoder program - used primarily for translating files
  4. *   to be sent by ASCII mail
  5. *
  6. *   MS-DOS Version: Keith D Gregory, August-87
  7. *
  8. ******************************************************************************
  9. *                            Modification History                            *
  10. *   Date       Seq  Who     Description                                      *
  11. *   ---------  ---  ---     ------------------------------------------------ *
  12. *   25-Aug-87  1.0  kdg     Creation                                         *
  13. *****************************************************************************/
  14.  
  15. #include    "stdio.h"
  16. #include    "string.h"
  17.  
  18.  
  19. /**
  20. *** Forward definitions . . .
  21. **/
  22. extern void decode();
  23. extern void decbytes( unsigned char *, unsigned char * );
  24.  
  25.  
  26. /**
  27. *** This macro is what converts a printable ASCII char into a 6 bit value
  28. **/
  29. #define DEC(c)  ((c - ' ') & 0x3F)
  30.  
  31.  
  32. FILE       *inputfile,                      /* May be real file or STDIN     */
  33.            *outputfile;                     /* May be real file or STDOUT    */
  34.     char        inputbuf[80];               /* Generic input buffer          */
  35.  
  36.  
  37. void main( argc, argv )
  38.     int    argc;
  39.     char  *argv[];
  40. {
  41.     char        inputbuf[80];               /* Generic input buffer          */
  42.     char        in_fname[64],               /* Pathname for desired files    */
  43.                 out_fname[64];
  44.     unsigned    destmode;                   /* Destination mode (ignored)    */
  45.  
  46.  
  47.     in_fname[0] = out_fname[0] = '\0';
  48.  
  49.     if (argc > 2)
  50.        {
  51.         fprintf( stderr, "\nUUDECODE: Invalid arguments" );
  52.         fprintf( stderr, "\n\nUsage:  uudecode [infile]" );
  53.         exit( 1 );
  54.        }
  55.  
  56.     if (argc == 2)
  57.        {
  58.         strcpy( in_fname, argv[1] );
  59.         if ((inputfile = fopen(in_fname, "r")) == NULL)
  60.            {
  61.             fprintf( stderr, "UUDECODE: Input File does not exist" );
  62.             exit( 1 );
  63.            }
  64.        }
  65.     else
  66.         inputfile = stdin;
  67.  
  68.  
  69.     while(1)                            /* Find beginning of encoded file   */
  70.        {
  71.         if (fgets( inputbuf, 80, inputfile ) == NULL)
  72.            {
  73.             fprintf( stderr, "UUDECODE: Not a valid encoded file" );
  74.             exit( 2 );
  75.            }
  76.         if (!strncmp( inputbuf, "begin", 5 ))
  77.             break;
  78.        }
  79.  
  80.     sscanf( inputbuf, "begin %o %s", &destmode, out_fname );
  81.     if (strchr( out_fname, '/' ) != NULL)
  82.        {
  83.         strcpy( inputbuf, strrchr( out_fname, '/') );
  84.         strcpy( out_fname, inputbuf );
  85.        }
  86.  
  87.     if (fopen( out_fname, "rb" ) != NULL)
  88.        {
  89.         fprintf( stderr, "UUDECODE: Output File already exists" );
  90.         exit( 1 );
  91.        }
  92.     else
  93.         outputfile = fopen(out_fname, "wb");
  94.  
  95.     decode();
  96.     fcloseall();
  97. }
  98.  
  99.  
  100. /***
  101. **** decode
  102. ****
  103. **** This function works its way through the file, a line at a time,
  104. **** decodeing as it goes.  If the beginning of the line is "end",
  105. **** then a normal return occurs.  If "end" line is not reached before
  106. **** the end of the file, then a message "Short File" is printed, but
  107. **** this routine terminates "normally" - thus, the file is saved.
  108. ***/
  109.  
  110. void decode()
  111. {
  112.     char            inputbuf[80];           /* ASCII input buffer            */
  113.     unsigned char   outputbuf[80];          /* Binary output buffer          */
  114.     int             linesize,               /* How many bytes encoded in line*/
  115.                     index1, index2;         /* Way to move through buffers   */
  116.  
  117.     while(1)
  118.        {
  119.         if (fgets( inputbuf, 80, inputfile ) == NULL)
  120.            {
  121.             fprintf( stderr, "UUDECODE: File too short" );
  122.             return;
  123.            }
  124.         if (!strncmp(inputbuf, "end", 3))
  125.             return;
  126.  
  127.         linesize = DEC( inputbuf[0] );
  128.         for (index1=1, index2=0  ;  index2 < linesize  ;  index1+=4, index2+=3 )
  129.             decbytes( &inputbuf[index1], &outputbuf[index2] );
  130.         fwrite( outputbuf, sizeof(unsigned char), linesize, outputfile );
  131.        }
  132. }
  133.  
  134.  
  135.  
  136.  
  137. /***
  138. **** decbytes
  139. ****
  140. **** Given a pointer to a stream of encoded bytes, this routine will take the
  141. **** four characters following that pointer and decode them.  A temporary
  142. **** buffer should be used by the caller to store the decoded bytes - this
  143. **** routine has no way of knowing when it has reached the end of the line,
  144. **** and will blindly convert garbage bytes.  The temporary buffer allows the
  145. **** caller to select only those bytes desired.
  146. ****
  147. **** The 3 x 8-bits to 4 x 6-bits conversion is as follows:
  148. **** (A,B,C are subsequent input bytes, D,E,F,G are subsequent output
  149. ****  bytes; this routine performs A B C ==> D E F G)
  150. ****
  151. ****    D = High order 6 bits of A in bits 0..5
  152. ****    E = Low  order 2 bits of A in bits 4..5
  153. ****        High order 4 bits of B in bits 0..3
  154. ****    F = Low  order 4 bits of B in bits 2..5
  155. ****        High order 2 bits of C in buts 0..1
  156. ****    G = Low  order 6 bits of C in bits 0..5
  157. ***/
  158.  
  159. void decbytes( inptr, outptr )
  160.     unsigned char   *inptr, *outptr;
  161. {
  162.     unsigned char   *a = outptr,
  163.                     *b = outptr + 1,
  164.                     *c = outptr + 2,
  165.                     *d = inptr,
  166.                     *e = inptr + 1,
  167.                     *f = inptr + 2,
  168.                     *g = inptr + 3;
  169.  
  170.  
  171.     *a = DEC(*d) << 2           | (DEC(*e) & 0x30) >> 4;
  172.     *b = (DEC(*e) & 0x0F) << 4  | (DEC(*f) & 0x3C) >> 2;
  173.     *c = (DEC(*f) & 0x03) << 6  | (DEC(*g) & 0x3F);
  174. }
  175.