home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- * Module : UUdecode --- Test for and decode a uuencoded text.
- *
- * Author : John W. M. Stevens
- ******************************************************************************/
-
- #include "compiler.h"
-
- #include "unpost.h"
- #include "regexp.h"
- #include "parse.h"
- #include "uudec.h"
-
- #define DEC_CHAR(c) (((c) - ' ') & 0x3f)
- #define CHK_SUM_MASK 0x3f
-
- static int FixBitNetTwiddleFlag = 0;
-
- /*-----------------------------------------------------------------------------
- | Routine : UULnDec() --- UU decode a line.
- |
- | Inputs : LnLen - Length of line.
- | Line - Pointer to the line buffer.
- | Outputs : Bfr - Points to buffer for decoded output.
- -----------------------------------------------------------------------------*/
-
- static
- int UULnDec(int LnLen,
- char *Line,
- BYTE *Bfr)
- {
- register int i;
- register int j;
- auto int RecLen;
- auto int tmp;
- auto int Shift;
-
- /* Zero out buffer. */
- RecLen = DEC_CHAR( *Line );
- memset(Bfr, 0, RecLen);
-
- /* Do actual line decoding. Skip first character, as it is line
- * length.
- */
- for (i = 1, j = 0, Shift = 2;
- i <= LnLen;
- i++)
- {
- /* Get six bits. */
- tmp = DEC_CHAR( Line[i] );
-
- /* Put into buffer. */
- Bfr[j] |= tmp << Shift;
- if (Shift > 2)
- Bfr[j - 1] |= tmp >> (8 - Shift);
-
- /* Increment byte pointer if neccesary. */
- if (Shift < 6)
- j++;
-
- /* Adjust shift size. */
- Shift = (Shift + 2) & 0x7;
- }
-
- /* Return size of buffer. */
- return( RecLen );
- }
-
- /*-----------------------------------------------------------------------------
- | Routine : ChkUUChars() --- Check that a line of the proper length has
- | the proper characters.
- |
- | Inputs : LnLen - Length of line.
- | Line - Pointer to the line buffer.
- | Outputs : Line - Pointer to the line buffer with fixes.
- |
- | Returns : Returns TRUE - This is a uuencoded line.
- | FALSE - This is not a uudecoded line.
- -----------------------------------------------------------------------------*/
-
- static
- int ChkUUChars(int LnLen,
- char *Line)
- {
- register int i;
-
- /* Loop through line, checking that all characters are in proper
- * range.
- */
- for (i = 0; i < LnLen; i++)
- if (Line[i] == '~' && FixBitNetTwiddleFlag)
- Line[i] = '^';
- else if (Line[i] < ' ' || Line[i] > '`')
- return( NOT_UU_LINE );
-
- /* Return that this is an encoded line. */
- return( IS_UU_LINE );
- }
-
- /*-----------------------------------------------------------------------------
- | Routine : ChkUULine() --- Check to see if this is a UUencoded line.
- |
- | Inputs : Line - Pointer to line buffer.
- | Outputs : RetStrs - Pointer to array of sub strings.
- | EncLen - Length of unencoded line in bytes.
- |
- | Returns : Returns IS_UU_LINE - This is a uuencoded line.
- | NOT_UU_LINE - This is not a uuencoded line.
- | UU_SPACE - This is a valid uuencoded empty line.
- | UU_BEGIN - This is a uuencode begin line.
- | UU_END - This is a uuencode end line.
- -----------------------------------------------------------------------------*/
-
- CHK_UU_ENC ChkUULine(char *Line,
- char ***RetStrs,
- int *EncLen)
- {
- auto int RecLen;
- auto int BfrLen;
-
- /* Check for a character in the range of 0x20 to 0x60 inclusive. */
- if ((*Line >= ' ' && *Line <= 'M') || *Line == '`')
- {
- /* Get record length. */
- RecLen = DEC_CHAR( *Line );
-
- /* Get line length. */
- BfrLen = strlen( Line );
-
- /* Calculate the line length based on the record size character. */
- if (*Line == 'M')
- *EncLen = 60;
- else if (*Line == ' ' || *Line == '`')
- *EncLen = 0;
- else
- {
- /* This is a short line, so calculate the lenght that it's
- * record length character says it should have.
- *
- * The first calculation assumes that for any number of
- * bytes between 1 and 3 inclusive, that the UU encoder
- * always spits out four characters.
- */
- if (RecLen % 3)
- *EncLen = 4 * (RecLen / 3 + 1);
- else
- *EncLen = 4 * (RecLen / 3);
-
- /* If the UU encoder spits out less than four characters
- * for 1 or 2 bytes, then we need a different calculation.
- */
- if (BfrLen != *EncLen + 1 && BfrLen != *EncLen + 2)
- *EncLen = 4 * (RecLen / 3) + (RecLen % 3 + 1);
- }
-
- /* Check for short or long buffer. */
- if (BfrLen != *EncLen + 1 && BfrLen != *EncLen + 2)
- return( NOT_UU_LINE );
-
- /* Check for the expected UU characters. */
- if (ChkUUChars(BfrLen, Line) == NOT_UU_LINE)
- return( NOT_UU_LINE );
-
- /* Return one of two different flags. */
- if (RecLen == 0)
- return( UU_SPACE );
- return( IS_UU_LINE );
- }
- else
- {
- /* Test for a begin line. */
- if ( MatchBegin(Line, RetStrs) )
- return( UU_BEGIN );
-
- /* Test for end line. */
- if ( MatchEnd( Line ) )
- return( UU_END );
- }
-
- /* This is not a UUencoded line. */
- return( NOT_UU_LINE );
- }
-
- /*-----------------------------------------------------------------------------
- | Routine : DecUULine() --- Decode a UU encoded line.
- |
- | Inputs : Line - Pointer to line buffer.
- | Outputs : Len - Number of bytes in the buffer.
- | Bfr - Points to buffer for decoded output.
- |
- | Returns : Returns IS_UU_LINE - This is a uuencoded line.
- | NOT_UU_LINE - This is not a uuencoded line.
- | UU_SPACE - This is a valid uuencoded empty line.
- | UU_BEGIN - This is a uuencode begin line.
- | UU_END - This is a uuencode end line.
- -----------------------------------------------------------------------------*/
-
- CHK_UU_ENC DecUULine(char *Line,
- int *Len,
- BYTE *Bfr)
- {
- auto int EncLen;
- auto CHK_UU_ENC UULnType;
- auto char **RetStrs;
-
- /* If this is not a uuencoded line, then it cannot be decoded.
- * Check it first.
- */
- *Len = 0;
- UULnType = ChkUULine(Line, &RetStrs, &EncLen);
- if (UULnType != IS_UU_LINE)
- return( UULnType );
-
- /* Do actual UU decode. */
- *Len = UULnDec(EncLen, Line, Bfr);
-
- /* Return the type of line this is. */
- return( IS_UU_LINE );
- }
-
- /*-----------------------------------------------------------------------------
- | Routine : DecTruncUULn() --- Decode a possibly truncated UU encoded
- | line.
- |
- | Inputs : Line - Pointer to line buffer.
- | Outputs : Len - Number of bytes in the buffer.
- | Bfr - Points to buffer for decoded output.
- -----------------------------------------------------------------------------*/
-
- void DecTruncUULn(char *Line,
- int *Len,
- BYTE *Bfr)
- {
- register int i;
- auto int RecLen;
- auto int BfrLen;
- auto int EncLen;
-
- /* Get line length. */
- BfrLen = strlen( Line );
-
- /* Calculate the line length. */
- RecLen = DEC_CHAR( *Line );
- if (RecLen % 3)
- EncLen = 4 * (RecLen / 3 + 1);
- else
- EncLen = 4 * (RecLen / 3);
-
- /* If the actual line is shorter than the record length indicates
- * it ought to be, then pad with spaces.
- */
- if (BfrLen <= EncLen)
- {
- /* Loop, putting spaces at end. */
- for (i = BfrLen; i <= EncLen; i++)
- Line[i] = '`';
- Line[i] = '\0';
- }
-
- /* Do actual UU line decode. */
- *Len = UULnDec(EncLen, Line, Bfr);
- }
-