diff options
| author | Gregory Neil Shapiro <gshapiro@FreeBSD.org> | 2002-04-10 03:05:00 +0000 | 
|---|---|---|
| committer | Gregory Neil Shapiro <gshapiro@FreeBSD.org> | 2002-04-10 03:05:00 +0000 | 
| commit | 605302a5c9939b7eeda0a31f38901d9a8348e8cb (patch) | |
| tree | 348e6162af337e0b74db963f6e4dcc567e2f99e9 /contrib/sendmail/src/mime.c | |
| parent | 04bb1e1f1766450d87d6cc51bb4918e8d653211a (diff) | |
Notes
Diffstat (limited to 'contrib/sendmail/src/mime.c')
| -rw-r--r-- | contrib/sendmail/src/mime.c | 110 | 
1 files changed, 79 insertions, 31 deletions
diff --git a/contrib/sendmail/src/mime.c b/contrib/sendmail/src/mime.c index f5980bb481bea..32c0b478b597a 100644 --- a/contrib/sendmail/src/mime.c +++ b/contrib/sendmail/src/mime.c @@ -1,5 +1,5 @@  /* - * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2002 Sendmail, Inc. and its suppliers.   *	All rights reserved.   * Copyright (c) 1994, 1996-1997 Eric P. Allman.  All rights reserved.   * Copyright (c) 1994 @@ -14,7 +14,7 @@  #include <sendmail.h>  #include <string.h> -SM_RCSID("@(#)$Id: mime.c,v 8.125 2001/09/11 04:05:15 gshapiro Exp $") +SM_RCSID("@(#)$Id: mime.c,v 8.129 2002/03/13 07:28:05 gshapiro Exp $")  /*  **  MIME support. @@ -924,7 +924,7 @@ isboundary(line, boundaries)  #endif /* MIME8TO7 */  #if MIME7TO8 -static int	mime_fromqp __P((unsigned char *, unsigned char **, int, int)); +static int	mime_fromqp __P((unsigned char *, unsigned char **, int));  /*  **  MIME7TO8 -- output 7 bit encoded MIME body in 8 bit format @@ -936,7 +936,7 @@ static int	mime_fromqp __P((unsigned char *, unsigned char **, int, int));  **  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 +**  Note also that we won't be called unless it is a text/plain MIME  **  message, encoded base64 or QP and mailer flag '9' has been defined  **  on mailer.  ** @@ -971,6 +971,7 @@ mime7to8(mci, header, e)  	HDR *header;  	register ENVELOPE *e;  { +	int pxflags;  	register char *p;  	char *cte;  	char **pvp; @@ -1024,6 +1025,7 @@ mime7to8(mci, header, e)  	**  it is not base64.  	*/ +	pxflags = PXLF_MAPFROM;  	if (sm_strcasecmp(cte, "base64") == 0)  	{  		int c1, c2, c3, c4; @@ -1066,9 +1068,13 @@ mime7to8(mci, header, e)  			{  				if (*--fbufp != '\n' ||  				    (fbufp > fbuf && *--fbufp != '\r')) +				{ +					pxflags |= PXLF_NOADDEOL;  					fbufp++; +				}  				putxline((char *) fbuf, fbufp - fbuf, -					 mci, PXLF_MAPFROM); +					 mci, pxflags); +				pxflags &= ~PXLF_NOADDEOL;  				fbufp = fbuf;  			}  			if (c3 == '=') @@ -1079,9 +1085,13 @@ mime7to8(mci, header, e)  			{  				if (*--fbufp != '\n' ||  				    (fbufp > fbuf && *--fbufp != '\r')) +				{ +					pxflags |= PXLF_NOADDEOL;  					fbufp++; +				}  				putxline((char *) fbuf, fbufp - fbuf, -					 mci, PXLF_MAPFROM); +					 mci, pxflags); +				pxflags &= ~PXLF_NOADDEOL;  				fbufp = fbuf;  			}  			if (c4 == '=') @@ -1092,28 +1102,44 @@ mime7to8(mci, header, e)  			{  				if (*--fbufp != '\n' ||  				    (fbufp > fbuf && *--fbufp != '\r')) +				{ +					pxflags |= PXLF_NOADDEOL;  					fbufp++; +				}  				putxline((char *) fbuf, fbufp - fbuf, -					 mci, PXLF_MAPFROM); +					 mci, pxflags); +				pxflags &= ~PXLF_NOADDEOL;  				fbufp = fbuf;  			}  		}  	}  	else  	{ +		int off; +  		/* quoted-printable */ +		pxflags |= PXLF_NOADDEOL;  		fbufp = fbuf; -		while (sm_io_fgets(e->e_dfp, SM_TIME_DEFAULT, buf, sizeof buf) -			!= NULL) +		while (sm_io_fgets(e->e_dfp, SM_TIME_DEFAULT, buf, +				   sizeof buf) != NULL)  		{ -			if (mime_fromqp((unsigned char *) buf, &fbufp, 0, -					&fbuf[MAXLINE] - fbufp) == 0) +			off = mime_fromqp((unsigned char *) buf, &fbufp, +					  &fbuf[MAXLINE] - fbufp); +again: +			if (off < -1)  				continue;  			if (fbufp - fbuf > 0)  				putxline((char *) fbuf, fbufp - fbuf - 1, mci, -					 PXLF_MAPFROM); +					 pxflags);  			fbufp = fbuf; +			if (off >= 0 && buf[off] != '\0') +			{ +				off = mime_fromqp((unsigned char *) (buf + off), +						  &fbufp, +						  &fbuf[MAXLINE] - fbufp); +				goto again; +			}  		}  	} @@ -1121,8 +1147,18 @@ mime7to8(mci, header, e)  	if (fbufp > fbuf)  	{  		*fbufp = '\0'; -		putxline((char *) fbuf, fbufp - fbuf, mci, PXLF_MAPFROM); +		putxline((char *) fbuf, fbufp - fbuf, mci, pxflags);  	} + +	/* +	**  The decoded text may end without an EOL.  Since this function +	**  is only called for text/plain MIME messages, it is safe to +	**  add an extra one at the end just in case.  This is a hack, +	**  but so is auto-converting MIME in the first place. +	*/ + +	putline("", mci); +  	if (tTd(43, 3))  		sm_dprintf("\t\t\tmime7to8 => %s to 8bit done\n", cte);  } @@ -1149,31 +1185,47 @@ static char index_hex[128] =  # define HEXCHAR(c)  (((c) < 0 || (c) > 127) ? -1 : index_hex[(c)]) +/* +**  MIME_FROMQP -- decode quoted printable string +** +**	Parameters: +**		infile -- input (encoded) string +**		outfile -- output string +**		maxlen -- size of output buffer +** +**	Returns: +**		-2 if decoding failure +**		-1 if infile completely decoded into outfile +**		>= 0 is the position in infile decoding +**			reached before maxlen was reached +*/ +  static int -mime_fromqp(infile, outfile, state, maxlen) +mime_fromqp(infile, outfile, maxlen)  	unsigned char *infile;  	unsigned char **outfile; -	int state;		/* Decoding body (0) or header (1) */  	int maxlen;		/* Max # of chars allowed in outfile */  {  	int c1, c2;  	int nchar = 0; +	unsigned char *b; -	if (maxlen < 0) +	/* decrement by one for trailing '\0', at least one other char */ +	if (--maxlen < 1)  		return 0; -	while ((c1 = *infile++) != '\0') +	b = infile; +	while ((c1 = *infile++) != '\0' && nchar < maxlen)  	{  		if (c1 == '=')  		{ -			if ((c1 = *infile++) == 0) +			if ((c1 = *infile++) == '\0')  				break;  			if (c1 == '\n' || (c1 = HEXCHAR(c1)) == -1)  			{ -				/* ignore it */ -				if (state == 0) -					return 0; +				/* ignore it and the rest of the buffer */ +				return -2;  			}  			else  			{ @@ -1186,27 +1238,23 @@ mime_fromqp(infile, outfile, state, maxlen)  					}  				} while ((c2 = HEXCHAR(c2)) == -1); -				if (c2 == -1 || ++nchar > maxlen) +				if (c2 == -1)  					break; - +				nchar++;  				*(*outfile)++ = c1 << 4 | c2;  			}  		}  		else  		{ -			if (state == 1 && c1 == '_') -				c1 = ' '; - -			if (++nchar > maxlen) -				break; - +			nchar++;  			*(*outfile)++ = c1; -  			if (c1 == '\n')  				break;  		}  	}  	*(*outfile)++ = '\0'; -	return 1; +	if (nchar >= maxlen) +		return (infile - b - 1); +	return -1;  }  #endif /* MIME7TO8 */  | 
