You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
226 lines
5.6 KiB
226 lines
5.6 KiB
/************************************************************
|
|
* uuencode/decode functions
|
|
************************************************************/
|
|
|
|
//
|
|
// Taken from NCSA HTTP and wwwlib.
|
|
//
|
|
// NOTE: These conform to RFC1113, which is slightly different then the Unix
|
|
// uuencode and uudecode!
|
|
//
|
|
#include "stdafx.h"
|
|
#include "uuencode.h"
|
|
|
|
|
|
// general purpose dynamic buffer structure
|
|
const int pr2six[256]={
|
|
64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
|
|
64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,62,64,64,64,63,
|
|
52,53,54,55,56,57,58,59,60,61,64,64,64,64,64,64,64,0,1,2,3,4,5,6,7,8,9,
|
|
10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,64,64,64,64,64,64,26,27,
|
|
28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,
|
|
64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
|
|
64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
|
|
64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
|
|
64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
|
|
64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
|
|
64,64,64,64,64,64,64,64,64,64,64,64,64
|
|
};
|
|
|
|
char six2pr[64] = {
|
|
'A','B','C','D','E','F','G','H','I','J','K','L','M',
|
|
'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
|
|
'a','b','c','d','e','f','g','h','i','j','k','l','m',
|
|
'n','o','p','q','r','s','t','u','v','w','x','y','z',
|
|
'0','1','2','3','4','5','6','7','8','9','+','/'
|
|
};
|
|
|
|
|
|
PBYTE BufferQueryPtr( BUFFER * pB )
|
|
{
|
|
if(pB)
|
|
{
|
|
return pB->pBuf;
|
|
}
|
|
else
|
|
{
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
|
|
BOOL CheckBufferSize( BUFFER *pB, DWORD cNewL )
|
|
{
|
|
PBYTE pN;
|
|
if (!pB)
|
|
{
|
|
return FALSE;
|
|
}
|
|
if ( cNewL > pB->cLen )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
uudecode(
|
|
char * bufcoded,
|
|
BUFFER * pbuffdecoded,
|
|
DWORD * pcbDecoded )
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
uudecode a string of data
|
|
|
|
Arguments:
|
|
|
|
bufcoded pointer to uuencoded data
|
|
pbuffdecoded pointer to output BUFFER structure
|
|
pcbDecoded number of decode bytes
|
|
|
|
Return Value:
|
|
|
|
Returns TRUE is successful; otherwise FALSE is returned.
|
|
|
|
--*/
|
|
{
|
|
int nbytesdecoded;
|
|
char *bufin = bufcoded;
|
|
unsigned char *bufout;
|
|
int nprbytes;
|
|
|
|
if(NULL == bufcoded ||
|
|
NULL == pbuffdecoded ||
|
|
NULL == pcbDecoded)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
/* Strip leading whitespace. */
|
|
|
|
while(*bufcoded==' ' || *bufcoded == '\t') bufcoded++;
|
|
|
|
/* Figure out how many characters are in the input buffer.
|
|
* If this would decode into more bytes than would fit into
|
|
* the output buffer, adjust the number of input bytes downwards.
|
|
*/
|
|
bufin = bufcoded;
|
|
|
|
while(pr2six[*(bufin++)] <= 63);
|
|
|
|
nprbytes = bufin - bufcoded - 1;
|
|
|
|
nbytesdecoded = ((nprbytes+3)/4) * 3;
|
|
|
|
if ( !CheckBufferSize( pbuffdecoded, nbytesdecoded + 4 ))
|
|
return FALSE;
|
|
|
|
|
|
bufout = (unsigned char *) BufferQueryPtr(pbuffdecoded);
|
|
|
|
if( NULL == bufout )
|
|
return FALSE;
|
|
|
|
bufin = bufcoded;
|
|
|
|
while (nprbytes > 0) {
|
|
*(bufout++) =
|
|
(unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
|
|
*(bufout++) =
|
|
(unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
|
|
*(bufout++) =
|
|
(unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
|
|
bufin += 4;
|
|
nprbytes -= 4;
|
|
}
|
|
|
|
if(nprbytes & 03) {
|
|
if(pr2six[bufin[-2]] > 63)
|
|
nbytesdecoded -= 2;
|
|
else
|
|
nbytesdecoded -= 1;
|
|
}
|
|
|
|
if ( pcbDecoded )
|
|
*pcbDecoded = nbytesdecoded;
|
|
|
|
((CHAR *)BufferQueryPtr(pbuffdecoded))[nbytesdecoded] = '\0';
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
uuencode(
|
|
BYTE * bufin,
|
|
DWORD nbytes,
|
|
BUFFER * pbuffEncoded )
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
uuencode a string of data
|
|
|
|
NOTE: bufin must be either a multiple of three, or be padded at the end to a multiple of three!
|
|
|
|
Arguments:
|
|
|
|
bufin pointer to data to encode
|
|
nbytes number of bytes to encode
|
|
pbuffEncoded pointer to output BUFFER structure
|
|
|
|
Return Value:
|
|
|
|
Returns TRUE is successful; otherwise FALSE is returned.
|
|
|
|
--*/
|
|
{
|
|
unsigned char *outptr;
|
|
unsigned int i;
|
|
|
|
if(NULL == bufin ||
|
|
NULL == pbuffEncoded)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Check size the buffer to 133% of the incoming data
|
|
//
|
|
|
|
if ( !CheckBufferSize( pbuffEncoded, nbytes + ((nbytes + 3) / 3) + 4))
|
|
return FALSE;
|
|
|
|
outptr = (unsigned char *) BufferQueryPtr(pbuffEncoded);
|
|
if( NULL == outptr )
|
|
return FALSE;
|
|
|
|
|
|
for (i = 0; i < nbytes; i += 3) {
|
|
*(outptr++) = six2pr[*bufin >> 2]; /* c1 */
|
|
*(outptr++) = six2pr[((*bufin << 4) & 060) | ((bufin[1] >> 4) & 017)]; /*c2*/
|
|
*(outptr++) = six2pr[((bufin[1] << 2) & 074) | ((bufin[2] >> 6) & 03)];/*c3*/
|
|
*(outptr++) = six2pr[bufin[2] & 077]; /* c4 */
|
|
|
|
bufin += 3;
|
|
}
|
|
|
|
/* If nbytes was not a multiple of 3, then we have encoded too
|
|
* many characters. Adjust appropriately.
|
|
*/
|
|
if(i == nbytes+1) {
|
|
/* There were only 2 bytes in that last group */
|
|
outptr[-1] = '=';
|
|
} else if(i == nbytes+2) {
|
|
/* There was only 1 byte in that last group */
|
|
outptr[-1] = '=';
|
|
outptr[-2] = '=';
|
|
}
|
|
|
|
*outptr = '\0';
|
|
|
|
return TRUE;
|
|
}
|