/*
**
** 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 <time.h>
#include "emil.h"
char *getmimebound();
void
encode_mime(struct message *m)
{
char buf[HDRLEN];
char *ct;
char *bb = NULL;
if (m->sd->format == MIME && m->sd == m->td)
return;
if (m->level == 0)
{
rm_header(m, "X-Charset");
rm_header(m, "X-Char-Esc");
add_header(m, "MIME-Version", "1.0", MIME);
}
if ((ct = (char *)confextr("MIME", NULL, m->sd->type)) != NULL ||
(ct = (char *)confextr("MIME", NULL, "DEFAULT")) != NULL)
{
if (match(m->sd->type, "TEXT"))
{
if (m->td->charset != NULL)
snprintf(buf, sizeof(buf), "%s; charset=\"%s\"", ct, m->td->charset);
else
snprintf(buf, sizeof(buf), "%s", ct);
}
else
if (match(m->sd->type, "MULTIPART"))
{
bb = (char *)getmimebound();
if (m->sd->applefile == AMDOUBLE)
snprintf(buf, sizeof(buf), "Multipart/AppleDouble; boundary=\"%s\"", bb);
else
snprintf(buf, sizeof(buf), "%s; boundary=\"%s\"", ct, bb);
m->td->startbound = (char *)Yalloc(MIMEBOUNDLEN + 5);
m->td->endbound = (char *)Yalloc(MIMEBOUNDLEN + 7);
sprintf(m->td->startbound, "--%s", bb);
sprintf(m->td->endbound, "--%s--", bb);
}
else
{
snprintf(buf, sizeof(buf), "%s", ct);
}
}
else
/* Generic default */
sprintf(buf, "Application/Octet-Stream");
if (m->td->encoding == EBINHEX)
sprintf(buf, "application/mac-binhex40");
if (m->sd->name != NULL)
{
char *buf2;
buf2 = strdup(buf);
snprintf(buf, sizeof(buf), "%s; name=\"%s\"", buf2, m->sd->name);
free(buf2);
}
add_header(m, "Content-Type", buf, MIME);
if (bb != NULL)
rm_header(m, "Content-Transfer-Encoding");
else
switch(m->td->encoding)
{
case EQP:
add_header(m, "Content-Transfer-Encoding", "Quoted-Printable", MIME);
break;
case EBASE64:
add_header(m, "Content-Transfer-Encoding", "Base64", MIME);
break;
case E8BIT:
add_header(m, "Content-Transfer-Encoding", "8bit", MIME);
break;
case EUUENCODE:
add_header(m, "Content-Transfer-Encoding", "X-UUENCODE", MIME);
break;
case E7BIT:
case EBINHEX:
add_header(m, "Content-Transfer-Encoding", "7bit", MIME);
break;
default:
break;
}
if (m->sd->description != NULL)
add_header(m, "Content-Description", m->sd->description, MIME);
else
{
if (m->sd->name != NULL)
add_header(m, "Content-Description", m->sd->name, MIME);
}
}
int
decode_mime(struct message *m)
{
if (m->level == 0)
{
if (matchheader(m, "MIME-Version", "1.0", MIME))
{
m->sd->format = MIME;
}
else
return(NOK);
}
if (m->sd->format == MIME)
{
char *line = NULL;
/* Process content-type header line */
if((line = (char *)gethval(m, "Content-Type", MIME)) == NULL)
{
/* Use default if missing */
m->sd->type = NEWSTR("TEXT");
m->sd->charset = NEWSTR("US-ASCII");
m->sd->encoding = E7BIT;
}
else
{
while (isspace(*line))
line++;
/* Set type */
if (strncasecmp(line, "multipart/signed", 16) == 0)
{
m->sd->type = NEWSTR("_SIGNED_");
target->format = NEWSTR("MIME");
target->iformat = MIME;
return(OK);
}
else
if ((m->sd->type = (char *)
confextr("MIME", (char *)clear_end_space(stringpart(line, ";", 0))
, NULL)) == NULL)
{
if (strncasecmp(line, "Multipart", 9) == 0)
m->sd->type = NEWSTR("MULTIPART");
else
if ((m->sd->type = (char *)
confextr("MIME", "DEFAULT", NULL))
== NULL)
m->sd->type = NEWSTR("APPLICATION");
}
/* Get parameters for a few important types */
if (match(m->sd->type, "TEXT"))
{
m->sd->encoding = E7BIT;
/* Get m->charset for text */
m->sd->charset = (char *)fixstring(getpartrest(line, "charset=", ";"), NULL, NULL,
(short) UNQUOTE);
}
else
if (match(m->sd->type, "MULTIPART"))
{
/* Get boundaries for multipart */
m->sd->startbound = (char *)fixstring(getpartrest(line, "boundary=", ";"),
"--", NULL, (short) UNQUOTE);
m->sd->endbound = (char *)fixstring(getpartrest(line, "boundary=", ";"),
"--", "--", (short) UNQUOTE);
m->sd->encoding = EMULTI;
m->sd->check = EMULTI;
if (strncasecmp(line + 10, "appledouble", 11) == 0)
m->sd->applefile = AMDOUBLE;
if (strncasecmp(line + 10, "header-set", 10) == 0)
m->sd->applefile = AMDOUBLE;
}
if (match(m->sd->type, "APPLESINGLE"))
m->sd->applefile = ASINGLE;
if (match(m->sd->type, "BINHEX"))
m->sd->applefile = ABINHEX;
m->sd->name = (char *)fixstring(getpartrest(line, "name=", ";"),
NULL, NULL, (short) UNQUOTE);
}
/* Process content-transfer-m->encoding header line */
if (m->sd->encoding != EMULTI)
{
if ((line =
(char *)gethval(m, "Content-Transfer-encoding", MIME)) == NULL)
{
/* Use default if missing */
if (m->sd->encoding == 0)
{
m->sd->encoding = E7BIT;
}
}
else
{
if (cmatch(line, "7bit"))
m->sd->encoding = E7BIT;
else
if (cmatch(line, "quoted-printable"))
{
m->sd->encoding = EQP;
}
else
if (cmatch(line, "base64"))
{
m->sd->encoding = EBASE64;
}
else
if (cmatch(line, "8bit"))
m->sd->encoding = E8BIT;
else
if (cmatch(line, "binary"))
m->sd->encoding = EBINARY;
else
if (cmatch(line, "x-uuencode"))
{
m->sd->encoding = EUUENCODE;
}
else
if (cmatch(line, "x-binhex"))
{
m->sd->encoding = EBINHEX;
}
}
}
if (cmatch(m->sd->type, "BINHEX"))
{
m->sd->encoding = EBINHEX;
}
m->sd->description = (char *)gethval(m, "Content-description", MIME);
line = (char *)gethval(m, "Content-Disposition", MIME);
}
else
return(NOK);
return OK;
}
char *
getmimebound()
{
char * bound;
static long t;
int i;
bound = Yalloc(MIMEBOUNDLEN + 1);
strcpy(bound, "===_Emil_v2_Boundary_===");
if (t==0) { time(&t); srand((unsigned int) t); }
for (i=24; i < MIMEBOUNDLEN - 2 ; i++)
bound[i]=
"ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvxyz"[rand()%50];
return bound;
}
syntax highlighted by Code2HTML, v. 0.9.1