/*
**
** Copyright (C) 1993 Swedish University Network (SUNET)
**
**
** This program is developed by UDAC, Uppsala University by commission
** of the Swedish University Network (SUNET).
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITTNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
**
**
** Martin.Wendel@its.uu.se
** Torbjorn.Wictorin@its.uu.se
**
** ITS
** P.O. Box 887
** S-751 08 Uppsala
** Sweden
**
*/
#include "emil.h"
char tob64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int fromb64[] = {
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
FAIL, SKIP, SKIP, FAIL, FAIL, SKIP, FAIL, FAIL,
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
SKIP, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
FAIL, FAIL, FAIL, 0x3e, FAIL, FAIL, FAIL, 0x3f,
0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
0x3c, 0x3d, FAIL, FAIL, FAIL, SKIP, FAIL, FAIL,
FAIL, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
0x17, 0x18, 0x19, FAIL, FAIL, FAIL, FAIL, FAIL,
FAIL, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
0x31, 0x32, 0x33, FAIL, FAIL, FAIL, FAIL, FAIL,
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL
};
int
encode_base64(struct message *m)
{
struct data *inbuf, *outbuf;
int linelen;
int i, l, left;
unsigned long triple;
unsigned char *inb;
inbuf = m->td;
inbuf->offset = inbuf->bodystart;
logger(LOG_DEBUG, "encode base64");
/* Exit on empty input */
if (!inbuf->size)
return(NOK);
#ifdef DEBUG
if (edebug)
fprintf(stderr, "Encoding base64");
#endif
linelen = 1;
outbuf = (struct data *)Yalloc(sizeof(struct data ));
outbuf->encoding = EBASE64;
/* Initialize working pointers */
inb = (unsigned char *)inbuf->contents + inbuf->offset;
i = 0;
triple = 0;
left = inbuf->bodyend - inbuf->offset;
#ifdef DEBUG
if (edebug)
fprintf(stderr, ", data length: %d\n", left);
#endif
/*
* Process entire inbuf.
*/
while (left != 0)
{
i++;
left--;
triple = (triple <<8) | *inb;
if (i == 3 || left == 0)
{
switch (i)
{
case 1:
triple = triple<<4;
break;
case 2:
triple = triple<<2;
break;
default:
break;
}
for (l = i; l >= 0; l--)
{
/* register */
int rr; rr = 0x3f & (triple>>(6*l)); assert (rr < 64);
append_char(outbuf, tob64[rr], pz);
if (linelen == 72)
{
append_char(outbuf, '\n', pz);
outbuf->lineend += 1;
linelen = 1;
}
else
{
linelen++;
}
}
if (left == 0)
switch(i)
{
case 2:
append_data(outbuf, "=\n", 2, pz);
break;
case 1:
append_data(outbuf, "==\n", 3, pz);
break;
default:
break;
}
triple = 0;
i = 0;
}
inb++;
inbuf->offset += 1;
}
safe_mchange(m, outbuf);
return(OK);
}
int
decode_base64(struct message *m)
{
struct data *inbuf, *outbuf;
char *inb;
int i;
int l;
int left;
unsigned long triple;
inbuf = m->td;
inbuf->offset = inbuf->bodystart;
#ifdef DEBUG
if (edebug)
fprintf(stderr, "Decoding base64 from offset %lu to bodyend %lu\n",
inbuf->offset, inbuf->bodyend);
#endif
logger(LOG_DEBUG, "decode base64");
/* Exit on empty input */
if (!inbuf->size)
return(NOK);
/* Initialize working pointers */
inb = inbuf->contents + inbuf->offset;
if (process)
{
outbuf = (struct data *)Yalloc(sizeof(struct data ));
}
l = 0;
triple = 0;
left = inbuf->bodyend - inbuf->offset;
/*
* Process entire inbuf.
*/
while (left != 0)
{
left--;
i = fromb64[(unsigned char)*inb];
switch(i)
{
case FAIL:
#ifdef DEBUG
if (edebug)
fprintf(stderr, ", illegal char at %lu: %d (failed).\n",
inbuf->offset, *inb);
#endif
sprintf(ebuf, "decode_base64: Illegal character: %d", *inb);
logger(LOG_WARNING, ebuf);
return(NOK);
break;
case SKIP:
break;
default:
triple = triple<<6 | (0x3f & i);
l++;
break;
}
if (l == 4 || left == 0)
{
switch(l)
{
case 2:
triple = triple>>4;
break;
case 3:
triple = triple>>2;
break;
default:
break;
}
if (process)
for (l -= 2; l >= 0; l--)
{
append_char(outbuf,( 0xff & (triple>>(l*8))), pz);
}
triple = 0;
l = 0;
}
inb++;
inbuf->offset += 1;
}
if (process)
{
safe_mchange(m, outbuf);
if (match(m->sd->type, "TEXT"))
{
outbuf->encoding = E7BIT;
check_bits(m->td);
}
else
outbuf->encoding = EBINARY;
}
#ifdef DEBUG
if (edebug)
fprintf(stderr, ", done.\n");
#endif
return(OK);
}
syntax highlighted by Code2HTML, v. 0.9.1