/* ** ** 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 #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; }