home *** CD-ROM | disk | FTP | other *** search
- /*
- * $Id: uudecode.c,v 36.9 1994/09/28 15:03:59 zodiac Rel zodiac $
- *
- * uudecode 36.9 -- Copyright (c) 1994 Ralph Seichter.
- *
- * Decodes binary files encoded with uuencode. This tool is pure.
- *
- * This tool is FREELY DISTRIBUTABLE. Copying and spreading is encouraged,
- * as long as you don't charge anyone for giving him/her this tool. Please
- * note that the Copyright is mine, this is *NOT* public domain software!
- * Permission is hereby granted to include the complete (!) archive in all
- * non-profit public domain software series like Fred Fish, SaarAG, etc.
- *
- * $Log: uudecode.c,v $
- * Revision 36.9 1994/09/28 15:03:59 zodiac
- * Files with IBM-style EOL sequences (CR/LF pairs) are now
- * processed correctly. This was suggested by Patrick Ohly.
- *
- * Revision 36.8 1994/09/28 14:18:47 zodiac
- * First release with 'pure' executables.
- *
- */
-
- #define VERSION "\0$VER: uudecode 36.9 (28.9.94)"
- #define TEMPLATE "FROM/A/M,PATH=TO/K,NC=NOCHECKSUM/S,QUIET/S"
-
- #define NO_DATA_FOUND -3
- #define BAD_CHECKSUM -4
- #define LINESIZE 128
- #define SIXBIT 0x40 /* 6 bit = 0x40 */
-
- enum { ARG_FROM, ARG_PATH, ARG_NOCHKSUM, ARG_QUIET, ARG_TOTAL };
-
- #define DECODE(c) ((c - 0x20) & 0x3F) /* decode one single byte */
- #define ISEOL(c) (c == '\n' || c == '\r') /* check for LF or CR */
-
-
-
- /* function prototypes ******************************************************/
-
- LONG entryPoint (VOID);
- LONG decodeFile (struct DosLibrary *, struct Library *, STRPTR *, BPTR, BOOL);
-
-
-
- /* the main program *********************************************************/
-
- LONG __saveds entryPoint (VOID)
- {
- LONG rc = RETURN_FAIL;
- struct DosLibrary *DOSBase;
-
- /* uudecode will *NOT* run without dos.library V36 or better! */
- if (DOSBase = (struct DosLibrary *)OpenLibrary (DOSNAME, 36))
- {
- struct Library *UtilityBase;
-
- if (UtilityBase = OpenLibrary ("utility.library", 37))
- {
- struct RDArgs *rda;
- STRPTR arg[ARG_TOTAL];
-
- rc = RETURN_ERROR;
- memset (arg, 0, sizeof (arg));
- if (rda = ReadArgs (TEMPLATE, (LONG *)arg, NULL))
- {
- LONG i, err;
- BPTR in;
- STRPTR *name = (STRPTR *)arg[ARG_FROM];
- static UBYTE ver[] = VERSION;
-
- if (!arg[ARG_QUIET])
- Printf ("%s Copyright \xA9 Ralph Seichter\n", &ver[7]);
- for (err = 0, i = 0; err == 0 && (name[i]); ++i)
- if (in = Open (name[i], MODE_OLDFILE))
- {
- BPTR oldPath, path = NULL;
-
- if (arg[ARG_PATH] && (path = Lock (arg[ARG_PATH], SHARED_LOCK)))
- oldPath = CurrentDir (path);
- if (!arg[ARG_QUIET])
- Printf ("Processing input file %s\n", name[i]);
- err = decodeFile (DOSBase, UtilityBase, arg, in, (BOOL)arg[ARG_NOCHKSUM]);
- if (path)
- {
- CurrentDir (oldPath);
- UnLock (path);
- }
- Close (in);
- }
- else
- break;
- if (err <= NO_DATA_FOUND)
- rc = RETURN_WARN;
- else if (err > 0 || (err = IoErr ()) > 0)
- PrintFault (err, NULL);
- else
- rc = RETURN_OK;
- FreeArgs (rda);
- }
- CloseLibrary (UtilityBase);
- }
- CloseLibrary ((struct Library *)DOSBase);
- }
- return (rc);
- }
-
-
-
- /* decode a complete file ***************************************************/
-
- LONG decodeFile (struct DosLibrary *DOSBase, struct Library *UtilityBase, STRPTR *arg, BPTR in, BOOL ignoreChecksum)
- {
- BOOL done, gotBegin = FALSE, badChecksum = FALSE;
- LONG line = 0;
- UBYTE buf[LINESIZE], outbuf[LINESIZE];
- static UBYTE error[] = "\7\23331;42m ERROR \2330m -- ";
- static UBYTE warning[] = "\23331;42m WARNING \2330m -- ";
- STRPTR s, t;
-
- do
- {
- done = TRUE;
-
- /* find the next `begin' line */
- while (s = FGets (in, buf, LINESIZE - 1))
- {
- ++line;
- if (0 == Strnicmp (buf, "begin ", 6))
- {
- gotBegin = TRUE;
- /* skip over `begin xyz ' to find the file name. */
- t = s = FilePart (&buf[10]);
- while (!ISEOL(*t))
- ++t;
- *t = 0;
- break;
- }
- }
-
- /* is there a file to decode? */
- if (s)
- {
- BPTR out;
-
- if (out = Open (s, MODE_NEWFILE))
- {
- LONG expected = ~0, size = 0;
-
- if (!arg[ARG_QUIET])
- Printf ("Line %ld: decoding file %s\n", line, s);
- memset (buf, 0, LINESIZE);
- while (s = FGets (in, buf, LINESIZE - 1))
- {
- ++line;
- if (0 == Strnicmp (buf, "end", 3) && ISEOL(buf[3]))
- {
- if (FGets (in, buf, LINESIZE - 1))
- {
- ++line;
- if (0 == Strnicmp (buf, "size ", 5))
- StrToLong (&buf[5], &expected);
- }
- break;
- }
- else
- {
- LONG l, c, checksum = 0;
-
- t = outbuf;
- c = *s++;
- l = DECODE(c);
- if (c != '\n' && l > 0)
- {
- /* decode one line. four input bytes will
- result in three output bytes. */
- while (l >= 4)
- {
- c = DECODE(s[0]) << 2 | DECODE(s[1]) >> 4;
- checksum += c;
- *t++ = c;
-
- c = DECODE(s[1]) << 4 | DECODE(s[2]) >> 2;
- checksum += c;
- *t++ = c;
-
- c = DECODE(s[2]) << 6 | DECODE(s[3]);
- checksum += c;
- *t++ = c;
-
- checksum = checksum % SIXBIT;
- s += 4;
- l -= 3;
- }
- c = DECODE(s[0]) << 2 | DECODE(s[1]) >> 4;
- checksum += c;
- if (l >= 1)
- *t++ = c;
- c = DECODE(s[1]) << 4 | DECODE(s[2]) >> 2;
- checksum += c;
- if (l >= 2)
- *t++ = c;
- c = DECODE(s[2]) << 6 | DECODE(s[3]);
- checksum += c;
- if (l >= 3)
- *t++ = c;
- checksum = checksum % SIXBIT;
- s += 4;
- if (!ignoreChecksum && *s >= 0x20 && *s <= 0x60 && checksum != DECODE(*s))
- {
- badChecksum = TRUE;
- if (!arg[ARG_QUIET])
- Printf ("Line %ld: %sbad checksum!\n", line, error);
- break;
- }
- l = t - outbuf;
- if (1 == FWrite (out, outbuf, l, 1))
- size += l;
- else
- break;
- }
- }
- }
- if (s)
- {
- done = FALSE;
- if (!arg[ARG_QUIET])
- {
- if (expected != ~0 && expected != size)
- Printf ("Line %ld: %sfile size mismatch!\n%ld bytes expected, ", line, warning, expected);
- Printf ("%ld bytes written.\n", size);
- }
- }
- else if (!arg[ARG_QUIET])
- Printf ("Line %ld: %sunexpected end of file!\n", line, error);
- Close (out);
- }
- }
- }
- while (!done);
- if (badChecksum)
- return (BAD_CHECKSUM);
- else if (gotBegin)
- return (IoErr ());
- else
- {
- if (!arg[ARG_QUIET])
- Printf ("%sno encoded data found.\n", warning);
- return (NO_DATA_FOUND);
- }
- }
-
- /* EOF */
-