home *** CD-ROM | disk | FTP | other *** search
- #ifndef AuCode_H
- #define AuCode_H
- /* -------------------------------------------------------------------------- **
- * AuCode.h - Amiga uuencode/uudecode toolkit.
- *
- * Written by Christopher R. Hertel; December, 1992
- * email: crh@bubble.mooses.affinity.mn.org
- * -------------------------------------------------------------------------- **
- * Copyright (C) 1993 Christopher R. Hertel
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * -------------------------------------------------------------------------- **
- *
- * $Log: AuCode.h,v $
- * Revision 1.3 94/02/06 14:09:39 CRH
- * With this revision I rewrote the comments for functions Cleanln() and
- * Decodeln(). I fixed some bugs with the checksum calculations (I was
- * getting negative values), and I added an internal function to calculate
- * checksums on bytes triples (au_cdChecksum3()). CRH
- *
- * Revision 1.2 93/09/15 21:29:22 CRH
- * Fixed a small bug in the decoding functions. Plus some general
- * cleanup.
- *
- * Revision 1.1 93/03/25 11:31:56 CRH
- * Cleaned up comments. Clarified License and Copyright.
- *
- * Revision 1.0 93/03/04 00:29:07 CRH
- * Initial revision
- *
- * -------------------------------------------------------------------------- **
- * My understanding of uuencoding/decoding is based on the knowledge that I
- * gained by reading the uuencode source provided with AmigaUUCP V1.16.
- * Many thanks to the authors of that software! The following are comments
- * from their code, which are included as my way of giving credit where
- * credit is due.
- *
- * /begin/
- * [uuencode.c:]
- * Written by Mark Horton
- * Modified by ajr (Alan J Rosenthatl,flaps@utcsri.UUCP) to use checksums
- * Modified by fnf (Fred Fish,well!fnf) to use Keith Pyle's suggestion for
- * compatibility
- * Modified by bcn (Bryce Nesbitt,ucbvax!hoser!bryce) to enable CTRL-C for
- * Amiga Lattice C. Added a transparent file size trailer for later check.
- * Changed fopen from "r" to "rb" for Messy-dos machines (thanks to Andrew
- * Wylie)
- *
- * [uudecode.c:]
- * Modified by bcn (Bryce Nesbitt,ucbvax!cogsci!bryce) to fix a misleading
- * error message on the Amiga port, to fix a bug that prevented decoding
- * certain files, to work even if trailing spaces have been removed from a
- * file, to check the filesize (if present), to add some error checking, to
- * loop for multiple decodes from a single file, and to handle common
- * BITNET mangling. Kludged around a missing string function in Aztec
- * C. Changed "r" to "rb" and "w" to "wb" for Messy-dos machines
- * (Thanks to Andrew Wylie).
- * /end/
- *
- * -------------------------------------------------------------------------- **
- * Initial comments: This module implements the basic uuencode/decode
- * functionality. The functions are designed to be reentrant, so you may
- * use them as part of either a link library or a run-time library.
- * Also, no attempt is made to support any hardware platform other than the
- * Commodore Amiga. In particular, this module is written to compile under
- * SAS C 5.10 or above on an Amiga running OS 2.04 or above. The code is,
- * however, written in a fairly generic style, and should be highly porable.
- *
- * Notes regarding style: I am a Pascal programmer at heart, and most of
- * my style choices are based on my preference for that language and its
- * derivatives. The result is a hybrid format with a few odd quirks of
- * its own. In any case, I intend to produce several modules, so my
- * function, macro, constant, variable, and type naming conventions serve
- * to associate identifiers with modules, and to prevent duplicate names
- * (after all, who else would use such awkward identifiers?).
- *
- * As mentioned above, these modules are designed to work within the
- * multitasking environment of the Commodore Amiga. The code is (should
- * be) reentrant and self contained (I've even avoided ANSI standard
- * functions, because the available libraries are not necessarily
- * reentrant). I have, however, been careful to avoid Amiga-specific
- * functions. It should, therefore, be very easy to port the code to other
- * platforms. (I'm hoping for a microVAX for Christmas. ;-) )
- *
- * Christopher R. Hertel; December, 1992
- * -------------------------------------------------------------------------- **
- */
-
- /* -------------------------------------------------------------------------- **
- * Defines...
- * au_cdMAXPhrase - a "phrase" of input becomes one line of output. In
- * other words, function AuEncode() will encode at most
- * MAXphrase characters at a time, and write them to the
- * output buffer. The output line length will be 8/6ths
- * (or 1 and 1/3 times) the original input, plus three
- * extra bytes per line (length, checksum, and newline).
- * This value should ALWAYS be a multiple of three!
- * Encoding is performed three bytes at a time. Other
- * values will cause a reducion in performance and some
- * oddly encoded (yet correct) translations. This value
- * should also ALWAYS be less than 64, because it will
- * be encoded in six bits just like everything else.
- *
- * au_cdCHKSUMsize - Checksum size, in decimal. A checksum of n indicates
- * that the checksum should be in the range 0..(n-1), so
- * if n = 64, then the checksum would be in the range
- * 0..63 (i.e., six bits).
- *
- * au_cdMAX_LINE - This is, roughly, the maximum length (in bytes) of a
- * "line". A line being a single uuencode "record", so
- * to speak. The value is calculated as follows: The
- * number of source bytes must be <=63 (since only six
- * bits are used to store this value). 63 bytes encodes
- * to (63 * (4 / 3)) == 84 bytes.
- *
- * Add:
- * + one byte for the encoded length
- * + one for the encoded checksum
- * + one for the eoln character
- * + one more, for a nul terminator
- *
- * Total 88. Add 2 for good luck for a total of 90.
- * (I was once told that infinity was "as much as you'll
- * ever need plus one".)
- *
- */
-
- #define au_cdMAXPhrase 45
- #define au_cdCHKSUMsize 64
- #define au_cdMAX_LINE 90
-
- /* -------------------------------------------------------------------------- **
- * Defined Error Codes...
- *
- * au_cdErr_NoError - No error.
- *
- * au_cdErr_Cramped - Output buffer does not contain enough space.
- *
- * au_cdErr_Checksum - The checksum comparison failed.
- */
- #define au_cdErr_NoError 0x00
- #define au_cdErr_Cramped 0x01
- #define au_cdErr_Checksum 0x02
-
- /* -------------------------------------------------------------------------- **
- * Macros...
- * au_cdENCD - encode a character. The character, c, is encoded in a six
- * bit field as follows: If c is not nul, the lower six bits
- * arithmatically added to the value of the space character
- * (ascii 32). If c *is* nul, then the value of the `
- * character is returned. (Note: octal 77 = hex 3F = binary
- * 00111111.)
- *
- * au_cdDECD - decode a character. Subtract the value of the space
- * character, then make sure that you have only the lower six
- * bits.
- *
- * au_cdExpPhrLen-Given the length of a source phrase, calculate the
- * number of bytes required for the encoded line. This macro
- * converts the number of source bytes into bits, then figures
- * out how many bytes are required to store the encoded
- * version (rounding up any fractional part to a whole
- * number). Three bytes are then added to the count (for
- * length, checksum, and newline). Note that the entire
- * calculation is performed using integers.
- *
- * au_cdCleanSixel-A potential error exists because BITNET converts the
- * "^" to a "~". Technically, the "~" (tilde) can't be part
- * of the code, so it's safe to convert it back to "^" (carat)
- * using this macro.
- *
- */
-
- #define au_cdENCD(c) ((c) ? (((c) & 077) + ' ') : '`') /* single char encode */
-
- #define au_cdDECD(c) (((c) - ' ') & 077) /* single character decode */
-
- #define au_cdExpPhrLen(pl) (((((pl) * 80) / 6)+9)/10 +3)
-
- #define au_cdCleanSixel(c) (('~'==(c))?'^':(c))
-
- /* -------------------------------------------------------------------------- **
- * Functions Prototypes...
- */
-
- int au_cdCvt3to4( char *S, char *T );
- /* ------------------------------------------------------------------------ **
- * Uuencode a three-byte value. The result is a four-byte value. The
- * function returns the checksum of the three source bytes.
- *
- * Input:
- * S - A pointer to an array of three bytes. These are the source data.
- * T - A pointer to the four byte target array.
- *
- * Output: a checksum value calculated from the three source bytes.
- * ------------------------------------------------------------------------ **
- */
-
- int au_cdCvt4to3( char *S, char *T );
- /* ------------------------------------------------------------------------ **
- * Uudecode a four-byte value. The result is a three-byte value. The
- * function returns the checksum of the three target bytes.
- *
- * Input:
- * S - A pointer to an array of four bytes. These are the source data.
- * T - A pointer to the three byte target array.
- *
- * Output: a checksum value calculated from the three target bytes.
- * ------------------------------------------------------------------------ **
- */
-
- int au_cdEncode( char *sBufr, int sbSize, char *tBufr, int tbSize );
- /* ------------------------------------------------------------------------ **
- * Encode a block of characters using the UUENCODE coding scheme.
- *
- * Input:
- * sBufr - A pointer to a buffer containing the bytes to be encoded.
- * sbSize - The number of bytes in sBufr to be encoded.
- * tBufr - A pointer to the target buffer.
- * tbSize - The number of bytes available in tBufr.
- *
- * Output: The number of source bytes that were actually converted. If
- * this number is less than sbSize, an error occured during the
- * encoding process (ran out of room in tBufr). The best way to
- * recover is to write out the contents of tBufr (which, if they
- * exist, are valid) and call this function again, passing in a
- * pointer to the remainder of the source bytes.
- * -> However, if zero bytes were processed (i.e., this function
- * returns zero), then tBufr is simply not large enough.
- *
- * Note: This function will not write the terminating line.
- * ------------------------------------------------------------------------ **
- */
-
- int au_cdCleanln( char *sBufr, int sbSize, char *tBufr, int tbSize );
- /* ------------------------------------------------------------------------ **
- * Clean a line of input to ensure that it can be decoded properly.
- *
- * Input: sBufr - A pointer to an array of encoded bytes. The
- * contents of sBufr[] (the "source") are assumed to
- * be a single line of uuencoded text. The line is
- * considered to be terminated by ascii value less
- * than 32.
- *
- * sbSize - The number of significant bytes in sBufr[]. That
- * is, the maximum number of bytes that you wish to
- * have cleaned. Cleanln() will process no more than
- * min( tbSize, sbSize ) bytes.
- *
- * tBufr - A pointer to the target buffer. The target buffer
- * will receive the "cleaned" copy of the source line.
- * Note that, in general, tBufr should be at least
- * sbSize bytes long, and possibly longer. It should
- * always be safe to create a tBufr that is
- * au_cdMAX_LINE bytes long (unless you are using in
- * this module in some new and interesting way that is
- * beyond my ability to extrapolate).
- *
- * tbSize - The number of bytes available in tBufr. Cleanln()
- * will process no more than min( tbSize, sbSize )
- * bytes.
- *
- * Output: The number of characters in sBufr[] that were copied to
- * tBufr[]. This value does not include any spaces that were
- * added to the end of tBufr[] as padding.
- *
- * Notes: The input line is "cleaned" as follows:
- *
- * This function copies the input line to a new buffer. During
- * the copy the function repairs damage that *may* have occurred
- * during transmission.
- *
- * In particular, some UUENCODErs encode a nul sixel as a space
- * (this module encodes a nul as a "`" character, both decode
- * to the same thing). Some editors (and other text utilites)
- * will trim trailing spaces from the ends of lines. This
- * function pads the end of the target buffer with spaces to
- * avoid the problem of lost sixles.
- *
- * Another potential error exists because BITNET converts the
- * "^" to a "~". Technically, the "~" can't be part of the code,
- * so it's safe to convert it back using the au_cdCleanSixel()
- * macro.
- *
- * This function always places a nul byte in the last position
- * in tBufr[]. That is:
- * tBufr[tbSize-1] = '\0';
- * be certain that your tBufr[] is big enough to handle all the
- * valid characters in sBufr[] plus the nul!
- * ------------------------------------------------------------------------ **
- */
-
- int au_cdDecodeln( char *sBufr, char *tBufr, int tbSize, int *ErrCD );
- /* ------------------------------------------------------------------------ **
- * This function will decode one "line" of encoded input.
- *
- * Input: sBufr - A pointer to a buffer containing the encoded data
- * that is to be decoded. The data should be in the
- * form of a "line" of uuencoded text. The line is
- * assumed to be "clean" (see au_cdCleanln()).
- * tBufr - A pointer to the target buffer. tBufr[] will
- * receive the decoded data.
- * tbSize - Number of bytes available in tBufr[].
- * ErrCD - A pointer to an integer that will receive an
- * error code. Check *ErrCD for one of the following
- * values:
- *
- * au_cdErr_NoError - No error. If the function
- * return value is zero *and* the error code is
- * _NoError, then an empty (i.e., terminating) line
- * has been found, indicating end of the (encoded)
- * file.
- *
- * au_cdErr_Cramped - tBufr[] does not contain enough
- * space to receive the decoded information. A
- * single encoded line may contain, at most, 63
- * encoded (source) bytes.
- *
- * au_cdErr_Checksum - the checksum comparison failed.
- * Either the source line is mangled, or the
- * checksum was not written properly by the encoding
- * program.
- *
- * Output: The number of bytes that were generated as a result of
- * decoding the input line.
- *
- * Notes: sBufr[] is assumed to be "clean". See the notes associated
- * with function au_cdCleanln() for an explanation of the term "clean",
- * as used in this context.
- * ------------------------------------------------------------------------ **
- */
-
- /* ========================================================================== */
- #endif /* AuCode_H */
-