#include <stdio.h>
#define STANDALONE_QP_8to7
#include "quoted.h"

/*
**  MIME7TO8 -- output 7 bit encoded MIME body in 8 bit format
**
**  This is a hack. Supports translating the two 7-bit body-encodings
**  (quoted-printable and base64) to 8-bit coded bodies.
**
**  There is not much point in supporting multipart here, as the UA
**  will be able to deal with encoded MIME bodies if it can parse MIME
**  multipart messages.
**
**  Note also that we wont be called unless it is a text/plain MIME
**  message, encoded base64 or QP and mailer flag '9' has been defined
**  on mailer.
**
**  Contributed by Marius Olaffson <marius@rhi.hi.is>.
**
**	Parameters:
**		mci -- mailer connection information.
**		header -- the header for this body part.
**		e -- envelope.
**
**	Returns:
**		none.
*/

static int	mime_fromqp __P((u_char *, u_char **, int, int));

#define putxline(buf, size, fp, flag) fwrite(buf, 1, size, fp)

void
mime7to8(fpo, E_dfp)
	FILE *fpo, *E_dfp;				/* e->e_dfp */
{
	register char *p;
	char **pvp;
	u_char *fbufp;
	char buf[MAXLINE];
	u_char fbuf[MAXLINE + 1];

	/*
	**  Translate body encoding to 8-bit.  Supports two types of
	**  encodings; "base64" and "quoted-printable". Assume qp if
	**  it is not base64.
	*/

		/* quoted-printable */
		fbufp = fbuf;
		while (fgets(buf, sizeof buf, E_dfp) != NULL)
		{
			if (mime_fromqp((u_char *) buf, &fbufp, 0,
					&fbuf[MAXLINE] - fbufp) == 0)
				continue;

			if (fbufp - fbuf > 0)
				putxline((char *) fbuf, fbufp - fbuf - 1, fpo,
					 PXLF_MAPFROM);
			fbufp = fbuf;
		}

	/* force out partial last line */
	if (fbufp > fbuf)
	{
		*fbufp = '\0';
		putxline((char *) fbuf, fbufp - fbuf, fpo, PXLF_MAPFROM);
	}
}
/*
**  The following is based on Borenstein's "codes.c" module, with simplifying
**  changes as we do not deal with multipart, and to do the translation in-core,
**  with an attempt to prevent overrun of output buffers.
**
**  What is needed here are changes to defned this code better against
**  bad encodings. Questionable to always return 0xFF for bad mappings.
*/

static char index_hex[128] =
{
	-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
	-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
	-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
	0, 1, 2, 3,  4, 5, 6, 7,  8, 9,-1,-1, -1,-1,-1,-1,
	-1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1,
	-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
	-1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1,
	-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1
};

#define HEXCHAR(c)  (((c) < 0 || (c) > 127) ? -1 : index_hex[(c)])

static int
mime_fromqp(infile, outfile, state, maxlen)
	u_char *infile;
	u_char **outfile;
	int state;		/* Decoding body (0) or header (1) */
	int maxlen;		/* Max # of chars allowed in outfile */
{
	int c1, c2;
	int nchar = 0;

	while ((c1 = *infile++) != '\0')
	{
		if (c1 == '=')
		{
			if ((c1 = *infile++) == 0)
				break;

			if (c1 == '\n') /* ignore it */
			{
				if (state == 0)
					return 0;
			}
			else
			{
				if ((c2 = *infile++) == '\0')
					break;

				c1 = HEXCHAR(c1);
				c2 = HEXCHAR(c2);

				if (++nchar > maxlen)
					break;

				*(*outfile)++ = c1 << 4 | c2;
			}
		}
		else
		{
			if (state == 1 && c1 == '_')
				c1 = ' ';

			if (++nchar > maxlen)
				break;

			*(*outfile)++ = c1;

			if (c1 == '\n')
				break;
		}
	}
	*(*outfile)++ = '\0';
	return 1;
}


main()
{
	mime7to8(stdout, stdin);
	return(0);
}

