home *** CD-ROM | disk | FTP | other *** search
/ World of A1200 / World_Of_A1200.iso / programs / compress / misc / uucode / source.lha / uuencode.c < prev    next >
C/C++ Source or Header  |  1995-01-10  |  5KB  |  192 lines

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