summaryrefslogtreecommitdiff
path: root/contrib/sendmail/src/mime.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/sendmail/src/mime.c')
-rw-r--r--contrib/sendmail/src/mime.c110
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 */