home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / uuencdec.zip / UUENCODE.C < prev   
Text File  |  1987-08-26  |  4KB  |  145 lines

  1. /** UUENCODE.C
  2. *
  3. *   Binary file encoder 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 encode();
  23. extern void outbytes( unsigned char * );
  24.  
  25.  
  26. /**
  27. *** This macro is what converts a six-bit value into a printable ASCII char
  28. *** (if the value should happen to be >64, it will be chopped to fit)
  29. **/
  30. #define ENC(c)  ((c & 0x3F) + ' ')
  31.  
  32.  
  33. FILE       *inputfile;                      /* May be real file or STDIN     */
  34.  
  35.  
  36. void main( argc, argv )
  37.     int    argc;
  38.     char  *argv[];
  39. {
  40.     int         destmode = 0644;            /* Desired destination mode      */
  41.     char        filename[64],               /* Pathname for desired file     */
  42.                *optptr;                     /* Temp ptr for extracting mode  */
  43.  
  44.  
  45.     filename[0] = '\0';
  46.     if (argc > 1)                           /* May have options or inputname */
  47.         if (argv[1][0] == '-')              /* Has options                   */
  48.            {
  49.             if ((optptr = strpbrk( argv[1], "Mm" )) != NULL)
  50.                 sscanf( ++optptr, "%o", &destmode );
  51.             if (argc == 3)
  52.                 strcpy( filename, argv[2] );
  53.            }
  54.         else if (argc == 3)                 /* Options improperly specified  */
  55.            {
  56.             fprintf( stderr, "\nUUENCODE: Arguments improperly specified" );
  57.             exit( 1 );
  58.            }
  59.         else
  60.             strcpy( filename, argv[1] );
  61.  
  62.     if (!*filename)
  63.        {
  64.         inputfile = stdin;
  65.         strcpy( filename, "uuencode.000" );
  66.        }
  67.     else if ((inputfile = fopen( filename, "rb" )) == NULL)
  68.        {
  69.         fprintf( stderr, "UUENCODE: Unable to open Input File" );
  70.         exit( 1 );
  71.        }
  72.  
  73.     if (strchr(filename, '\\') != NULL)
  74.         printf( "\nbegin %o %s\n", destmode, strrchr(filename, '\\')+1 );
  75.     else
  76.         printf( "\nbegin %o %s\n", destmode, filename );
  77.  
  78.     encode();
  79.  
  80.     printf( "end\n" );
  81. }
  82.  
  83.  
  84. /***
  85. **** Read input, sending coded bytes to standard output.  We use a subroutine
  86. **** to output each group of 3 bytes - note that, if a line is less than a
  87. **** multiple of 3 bytes, then 1 or 2 garbage bytes may be put on the end.
  88. ***/
  89.  
  90. void encode()
  91. {
  92.     unsigned char   buf[47];            /* Input lines may be 1..45 bytes    */
  93.     int     index,
  94.             numbytes = 1;               /* Number of bytes in this line      */
  95.  
  96.     while (numbytes > 0)
  97.        {
  98.         numbytes = fread( buf, sizeof(char), 45, inputfile );
  99.         putchar( ENC(numbytes) );
  100.  
  101.         for (index = 0  ;  index < numbytes  ;  index += 3)
  102.             outbytes( &buf[index] );
  103.  
  104.         printf( "\n" );
  105.        }
  106. }
  107.  
  108.  
  109. /***
  110. **** outbytes
  111. ****
  112. **** Given a pointer to a stream of bytes, this routine will encode the
  113. **** next three and output them (as 4 ASCII characters).
  114. ****
  115. **** The 3 x 8-bits to 4 x 6-bits conversion results in the following:
  116. **** (A,B,C are subsequent input bytes, D,E,F,G are subsequent output
  117. ****  bytes; this routine performs A B C ==> D E F G)
  118. ****
  119. ****    D = High order 6 bits of A in bits 0..5
  120. ****    E = Low  order 2 bits of A in bits 4..5
  121. ****        High order 4 bits of B in bits 0..3
  122. ****    F = Low  order 4 bits of B in bits 2..5
  123. ****        High order 2 bits of C in buts 0..1
  124. ****    G = Low  order 6 bits of C in bits 2..5
  125. ***/
  126.  
  127. void outbytes( ptr )
  128.     unsigned char   *ptr;
  129. {
  130.     unsigned    d,e,f,g,
  131.                 a = *ptr++,
  132.                 b = *ptr++,
  133.                 c = *ptr;
  134.  
  135.     d = a >> 2;
  136.     e = ((a << 4) & 0x30) | ((b >> 4) & 0x0F);
  137.     f = ((b << 2) & 0x3C) | ((c >> 6) & 0x03);
  138.     g = c & 0x3F;
  139.  
  140.     putchar( ENC(d) );
  141.     putchar( ENC(e) );
  142.     putchar( ENC(f) );
  143.     putchar( ENC(g) );
  144. }
  145.