From f2c6d1760ac6971fcc63c9dbde8752dc721c6bc3 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sat, 9 Jan 1999 23:52:27 +0000 Subject: Henrik's fix for mimedecode. svn path=/trunk/; revision=2345 --- unmime.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 55 insertions(+), 10 deletions(-) (limited to 'unmime.c') diff --git a/unmime.c b/unmime.c index cedc6737..753c9aa1 100644 --- a/unmime.c +++ b/unmime.c @@ -250,6 +250,7 @@ static int BodyState = S_BODY_DATA; * a quoted-printable body part. */ static int CurrEncodingIsQP = 0; +static int CurrTypeNeedsDecode = 0; /* * Delimiter for multipart messages. RFC 2046 states that this must @@ -325,6 +326,36 @@ static char *GetBoundary(char *CntType) } +int CheckContentType(char *CntType) +{ + /* + * Static array of Content-Type's for which we will do + * quoted-printable decoding, if requested. + * It is probably wise to do this only on known text-only types; + * be really careful if you change this. + */ + + static char *DecodedTypes[] = { + "text/", /* Will match ALL content-type's starting with 'text/' */ + "message/rfc822", + NULL + }; + + char *p = CntType; + int i; + + /* Skip whitespace, if any */ + for (; isspace(*p); p++) ; + + for (i=0; + (DecodedTypes[i] && + (strncasecmp(p, DecodedTypes[i], strlen(DecodedTypes[i])))); + i++) ; + + return (DecodedTypes[i] != NULL); +} + + /* * This routine does three things: * 1) It determines - based on the message headers - whether the @@ -336,8 +367,9 @@ static char *GetBoundary(char *CntType) * - All other messages are assumed NOT to include 8-bit data. * 2) It determines the delimiter-string used in multi-part message * bodies. - * 3) It sets the initial values of the CurrEncodingIsQP and BodyState - * variables, from the header contents. + * 3) It sets the initial values of the CurrEncodingIsQP, + * CurrTypeNeedsDecode, and BodyState variables, from the header + * contents. * * The return value is a bitmask. */ @@ -350,7 +382,7 @@ int MimeBodyType(unsigned char *hdrs, int WantDecode) /* Setup for a standard (no MIME, no QP, 7-bit US-ASCII) message */ MultipartDelimiter[0] = '\0'; - CurrEncodingIsQP = 0; + CurrEncodingIsQP = CurrTypeNeedsDecode = 0; BodyState = S_BODY_DATA; BodyType = 0; @@ -418,6 +450,8 @@ int MimeBodyType(unsigned char *hdrs, int WantDecode) /* Done looking through the headers, now check what they say */ if ((MimeVer != NULL) && (strcmp(MimeVer, "1.0") == 0)) { + CurrTypeNeedsDecode = CheckContentType(CntType); + /* Check Content-Type to see if this is a multipart message */ if ( (CntType != NULL) && ((strncasecmp(CntType, "multipart/", 10) == 0) || @@ -442,7 +476,7 @@ int MimeBodyType(unsigned char *hdrs, int WantDecode) if (strcasecmp(XferEnc, "quoted-printable") == 0) { CurrEncodingIsQP = 1; BodyType = (MSG_IS_8BIT | MSG_NEEDS_DECODE); - if (WantDecode) { + if (WantDecode && CurrTypeNeedsDecode) { SetEncoding8bit(XferEncOfs); } } @@ -546,17 +580,27 @@ int UnMimeBodyline(unsigned char **bufp, int collapsedoubledot) switch (BodyState) { case S_BODY_HDR: UnMimeHeader(buf); /* Headers in body-parts can be encoded, too! */ - if (strncasecmp("Content-Transfer-Encoding:", buf, 26) == 0) { + if ((*buf == '\0') || (*buf == '\n') || (strcmp(buf, "\r\n") == 0)) { + BodyState = S_BODY_DATA; + } + else if (strncasecmp("Content-Transfer-Encoding:", buf, 26) == 0) { char *XferEnc; XferEnc = nxtaddr(buf); if ((XferEnc != NULL) && (strcasecmp(XferEnc, "quoted-printable") == 0)) { CurrEncodingIsQP = 1; - SetEncoding8bit(buf); + + /* Hmm ... we cannot be really sure that CurrTypeNeedsDecode + has been set - we may not have seen the Content-Type header + yet. But *usually* the Content-Type header comes first, so + this will work. And there is really no way of doing it + "right" as long as we stick with the line-by-line processing. */ + if (CurrTypeNeedsDecode) SetEncoding8bit(buf); } } - else if ((*buf == '\0') || (*buf == '\n') || (strcmp(buf, "\r\n") == 0)) - BodyState = S_BODY_DATA; + else if (strncasecmp("Content-Type:", buf, 13) == 0) { + CurrTypeNeedsDecode = CheckContentType(nxtaddr(buf)); + } *bufp = (buf + strlen(buf)); break; @@ -565,10 +609,10 @@ int UnMimeBodyline(unsigned char **bufp, int collapsedoubledot) if ((*MultipartDelimiter) && (strncmp(buf, MultipartDelimiter, strlen(MultipartDelimiter)) == 0)) { BodyState = S_BODY_HDR; - CurrEncodingIsQP = 0; + CurrEncodingIsQP = CurrTypeNeedsDecode = 0; } - if (CurrEncodingIsQP) + if (CurrEncodingIsQP && CurrTypeNeedsDecode) ret = DoOneQPLine(bufp, collapsedoubledot); else *bufp = (buf + strlen(buf)); @@ -584,6 +628,7 @@ int UnMimeBodyline(unsigned char **bufp, int collapsedoubledot) #include char *program_name = "unmime"; +int outlevel = 0; #define BUFSIZE_INCREMENT 4096 -- cgit v1.2.3 olor: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } .highlight .hll { background-color: #ffffcc } .highlight .c { color: #888888 } /* Comment */ .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ .highlight .k { color: #008800; font-weight: bold } /* Keyword */ .highlight .ch { color: #888888 } /* Comment.Hashbang */ .highlight .cm { color: #888888 } /* Comment.Multiline */ .highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */ .highlight .cpf { color: #888888 } /* Comment.PreprocFile */ .highlight .c1 { color: #888888 } /* Comment.Single */ .highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */ .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ .highlight .gr { color: #aa0000 } /* Generic.Error */ .highlight .gh { color: #333333 } /* Generic.Heading */ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ .highlight .go { color: #888888 } /* Generic.Output */ .highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
#!/bin/sh
#
#  Build RPMs from the source in the current directory.  This script sets
#  up an RPM "_topdir" and builds the RPMs under there, then copies the
#  binary and source RPMs to the current directory.
#
#  Written by Sean Reifschneider <jafo-rpms@tummy.com>, 2003

TARBALL=$1		#  tarball to build from

#  set up temporary directory
TMPDIR=`pwd`/rpm-build.$$
[ ! -z "$TMPDIR" -a "$TMPDIR" != / ] && rm -rf "$TMPDIR"
mkdir -p "$TMPDIR"/BUILD
mkdir -p "$TMPDIR"/RPMS
mkdir -p "$TMPDIR"/SOURCES
mkdir -p "$TMPDIR"/SPECS
mkdir -p "$TMPDIR"/SRPMS

#  set up rpmmacros file
MACROFILE="$TMPDIR"/rpmmacros
RCFILE="$TMPDIR"/rpmrc
sed "s|~/.rpmmacros|$MACROFILE|" /usr/lib/rpm/rpmrc >"$RCFILE"
echo "%_topdir $TMPDIR" >"$MACROFILE"
echo "%_topdir $TMPDIR" >"$MACROFILE"

#  build RPMs
rpmbuild --rcfile "$RCFILE" $ARCH -ta $TARBALL \
|| rpm --rcfile "$RCFILE" $ARCH -ta $TARBALL
status=$?

if [ $status = '0' ]
then
    # copy RPMs to this directory
    cp "$TMPDIR"/RPMS/*/*.rpm .
    cp "$TMPDIR"/SRPMS/*.rpm .
fi

#  clean up build directory
[ ! -z "$TMPDIR" -a "$TMPDIR" != / ] && rm -rf "$TMPDIR"

exit $status