home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 9 / FreshFishVol9-CD2.bin / bbs / util / uucode-36.9.lha / UUCode / uuencode.c < prev    next >
Text File  |  1994-09-28  |  5KB  |  186 lines

  1. /*
  2.  * $Id: uuencode.c,v 36.9 1994/09/28 15:03:59 zodiac Rel zodiac $
  3.  *
  4.  * uuencode 36.9 -- Copyright (c) 1994 Ralph Seichter.
  5.  *
  6.  * Encodes binary files so that they can be posted to the Internet. This
  7.  * tool is pure.
  8.  *
  9.  * This tool is FREELY DISTRIBUTABLE. Copying and spreading is encouraged,
  10.  * as long as you don't charge anyone for giving him/her this tool. Please
  11.  * note that the Copyright is mine, this is *NOT* public domain software!
  12.  * Permission is hereby granted to include the complete (!) archive in all
  13.  * non-profit public domain software series like Fred Fish, SaarAG, etc.
  14.  *
  15.  * $Log: uuencode.c,v $
  16.  * Revision 36.9  1994/09/28  15:03:59  zodiac
  17.  * No changes. Revision number was bumped to match uudecode.
  18.  *
  19.  * Revision 36.8  1994/09/28  14:18:47  zodiac
  20.  * First release with 'pure' executables.
  21.  *
  22.  */
  23.  
  24. #define    VERSION        "\0$VER: uuencode 36.9 (28.9.94)"
  25. #define    TEMPLATE        "FROM/A/M,TO=AS/A/K,NC=NOCHECKSUM/S,XC=XCHECKSUM/S,QUIET/S"
  26.  
  27. #define    MODE_NOCHKSUM    0x01
  28. #define    MODE_XCHKSUM    0x02
  29. #define    SIXBIT        0x40        /* 6 bit = 0x40 */
  30.  
  31. enum { ARG_FROM, ARG_TO, ARG_NOCHKSUM, ARG_XCHKSUM, ARG_QUIET, ARG_TOTAL };
  32.  
  33. /*
  34.     Encoding (c == 0) returns (0x60).
  35.     Encoding (c  > 0) returns ((c & 0x3F) + 0x20).
  36.  
  37.     There is always (0x20 <= c <= 0x60), which means
  38.     that c is guaranteed to be a printable character!
  39. */
  40.  
  41. #define ENCODE(c) (c ? (c & 0x3F) + 0x20 : 0x60)
  42.  
  43.  
  44.  
  45. /* function prototypes and globals ******************************************/
  46.  
  47. LONG entryPoint (VOID);
  48. BOOL encodeFile (struct DosLibrary *, BPTR, BPTR, STRPTR, BYTE);
  49.  
  50.  
  51.  
  52. /* the main program *********************************************************/
  53.  
  54. LONG __saveds entryPoint (VOID)
  55. {
  56.     LONG rc = RETURN_FAIL;
  57.     struct DosLibrary *DOSBase;
  58.  
  59.     /* uuencode will *NOT* run without dos.library V36 or better! */
  60.     if (DOSBase = (struct DosLibrary *)OpenLibrary (DOSNAME, 36))
  61.     {
  62.         LONG err;
  63.         STRPTR arg[ARG_TOTAL];
  64.         struct RDArgs *rda;
  65.  
  66.         rc = RETURN_ERROR;
  67.         memset (arg, 0, sizeof (arg));
  68.         if (rda = ReadArgs (TEMPLATE, (LONG *)arg, NULL))
  69.         {
  70.             BPTR out;
  71.             STRPTR *name = (STRPTR *)arg[ARG_FROM];
  72.             static UBYTE ver[] = VERSION;
  73.  
  74.             if (!arg[ARG_QUIET])
  75.                 Printf ("%s Copyright \xA9 Ralph Seichter\n", &ver[7]);
  76.             if (out = Open (arg[ARG_TO], MODE_NEWFILE))
  77.             {
  78.                 WORD i;
  79.                 BPTR in;
  80.                 BYTE mode;
  81.                 BOOL ok = TRUE;
  82.  
  83.                 if (arg[ARG_NOCHKSUM])
  84.                     mode = MODE_NOCHKSUM;
  85.                 else if (arg[ARG_XCHKSUM])
  86.                     mode = MODE_XCHKSUM;
  87.                 else
  88.                     mode = 0;
  89.                 for (i = 0; ok && (name[i]); ++i)
  90.                     if (in = Open (name[i], MODE_OLDFILE))
  91.                     {
  92.                         if (!arg[ARG_QUIET])
  93.                             Printf ("Encoding file %s\n", name[i]);
  94.                         ok = encodeFile (DOSBase, in, out, FilePart (name[i]), mode);
  95.                         Close (in);
  96.                     }
  97.                 Close (out);
  98.                 if ((err = IoErr ()) > 0)
  99.                     PrintFault (err, NULL);
  100.                 else
  101.                     rc = RETURN_OK;
  102.             }
  103.             FreeArgs (rda);
  104.         }
  105.         CloseLibrary ((struct Library *)DOSBase);
  106.     }
  107.     return (rc);
  108. }
  109.  
  110.  
  111.  
  112. /* encode a complete file ***************************************************/
  113.  
  114. BOOL encodeFile (struct DosLibrary *DOSBase, BPTR in, BPTR out, STRPTR name, BYTE mode)
  115. {
  116.     BOOL ok = FALSE;
  117.  
  118.     if (0 < FPrintf (out, "begin 644 %s\n", name))
  119.     {
  120.         LONG n, i, triple, checksum, size = 0;
  121.         UBYTE c, buf[45], outbuf[80];
  122.         STRPTR s, t;
  123.  
  124.         do
  125.         {
  126.             /* read a maximum of 45 bytes at a time */
  127.             n = FRead (in, buf, 1, 45);
  128.             size += n;
  129.  
  130.             /* the first byte in each output line is the */
  131.             /* encoded number of encoded bytes in the line */
  132.             s = outbuf;
  133.             *s++ = ENCODE(n);
  134.  
  135.             /* now encode data in buffer. three input bytes
  136.                     will always result in four output bytes */
  137.             for (checksum = 0, i = 0; i < n; i += 3)
  138.             {
  139.                 t = &buf[i];
  140.  
  141.                 /* first six bits (7-2) of byte 0 */
  142.                 c = t[0] >> 2;
  143.                 *s++ = ENCODE(c);
  144.  
  145.                 /* last two bits (1-0) of byte 0 OR'ed with first
  146.                         four bits (7-4) of byte 1 */
  147.                 c = (t[0] << 4) & 0x30 | (t[1] >> 4) & 0x0F;
  148.                 *s++ = ENCODE(c);
  149.  
  150.                 /* last four bits (3-0) of byte 1 OR'ed with first
  151.                         two bits (7-6) of byte 2 */
  152.                 c = (t[1] << 2) & 0x3C | (t[2] >> 6) & 0x03;
  153.                 *s++ = ENCODE(c);
  154.  
  155.                 /* last six bits (5-0) of byte 2 */
  156.                 c = t[2] & 0x3F;
  157.                 *s++ = ENCODE(c);
  158.  
  159.                 /* calculate checksum of current triplet */
  160.                 triple = (t[0] + t[1] + t[2]) % SIXBIT;
  161.  
  162.                 /* and add this to total line checksum */
  163.                 checksum = (checksum + triple) % SIXBIT;
  164.             }
  165.  
  166.             if (mode & MODE_XCHKSUM)
  167.                 *s++ = 'X';
  168.             else if (!(mode & MODE_NOCHKSUM))
  169.                 /* the last byte in each line is the line checksum */
  170.                 *s++ = ENCODE(checksum);
  171.  
  172.             /* add a newline character and write line string to file */
  173.             *s++ = '\n';
  174.             *s = 0;
  175.             if (0 != FPuts (out, outbuf))
  176.                 n = -1;
  177.         }
  178.         while (n > 0);
  179.         if (n != -1)
  180.             ok = (0 < FPrintf (out, "end\nsize %ld\n\n", size));
  181.     }
  182.     return (ok);
  183. }
  184.  
  185. /* EOF */
  186.