/* ** ** 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 "emil.h" /* * int * parse_message(inbuf, message) * * Parse message and divide into a hierarchical structure of message parts. * */ int parse_sun_message(struct message *m) { struct data *inbuf; /* Initialize inbuf */ inbuf = (struct data *)m->sd; #ifdef DEBUG if (edebug) fprintf(stderr, "+ (parse_sun_message) Parsing body part %d at level %d and offset %lu.\n", inbuf->count, m->level, inbuf->offset); #endif /* Exit on empty input */ if (inbuf->size == 0 || (inbuf->end <= inbuf->offset)) { #ifdef DEBUG if (edebug) fprintf(stderr, "*** Empty input (failed).\n"); #endif logger(LOG_ERR, "parse_message: Empty input"); return(NOK); } /* If Multipart create a child and run parse_message * on the child. */ if (inbuf->encoding == EMULTI) { int status; #ifdef DEBUG if (edebug) fprintf(stderr, "+ Tried (MAILTOOL) multipart %d at level %d starting at %lu and ending at %lu.\n", inbuf->count, m->level, inbuf->bodystart, inbuf->bodyend); #endif if ((status = parse_sun_multi(m)) == OK) { #ifdef DEBUG if (edebug) fprintf(stderr, "+ Marked up (MAILTOOL) multipart %d at level %d starting at %lu and ending at %lu.\n", inbuf->count, m->level, inbuf->bodystart, inbuf->bodyend); #endif return(OK); } if (status == NOK) { #ifdef DEBUG if (edebug) fprintf(stderr, "+ MAILTOOL body part %d at level %d failed.\n", inbuf->count, m->level); #endif return(NOK); } } else { /* Body starts here */ inbuf->bodystart = inbuf->offset; inbuf->linestart = inbuf->loffset; } if (check_encoding(m) != OK) m->sd->encoding = E7BIT; if (m->sd->bodyend == 0) m->sd->bodyend = m->sd->end; return(OK); } int parse_sun_multi(struct message *m) { struct data *inbuf; struct data *childbuf; struct message *childm; inbuf = (struct data *)m->sd; /* Copy off a child */ childm = (struct message *)copy_mstruct(m, 0); /* Body end is end of data */ inbuf->bodyend = inbuf->end; inbuf->lineend = inbuf->lend; /* Set more child data */ childbuf = childm->sd; childm->level = m->level + 1; childm->parent = m; childm->bigsib = childm; /* Loop back */ childbuf->end = (inbuf->bodyend != 0) ? inbuf->bodyend: inbuf->end; childbuf->lend = (inbuf->lineend != 0) ? inbuf->lineend: inbuf->lend; /* Parse child */ if (parse_sun_siblings(childm) == OK) { /* Parse successful. * Connect child to current part and beware that data * now belongs to the children. If the contents was * only one part, fix this here, to reduce the depth * of this part of the structure. */ /* Attach child */ m->child = childm; m->children += 1; if (m->level == 0) return(OK); /* All data processed */ } else { /* Erroneous multipart, set type to text instead and * run test check below */ m->sd->encoding = E7BIT; m->sd->type = NEWSTR("TEXT"); check_bits(m->sd); return(FAIL); } return(OK); } int parse_sun_siblings(struct message *m) { struct data *inbuf, *sibbuf; struct message *sibm; int status; inbuf = m->sd; #ifdef DEBUG if (edebug) fprintf(stderr, "+ parse_sun_siblings\n"); #endif /* Parse child */ /* If this is a body part in a multipart with startbound set * find the start of this body part */ if (m->parent != NULL && m->parent->sd->startbound != NULL) { if (move_past_boundary(m, m->parent->sd->startbound) != OK) return(SKIP); } /* Check header if possible */ if (!m->headerdone && (m->sd->format != RFC822 || m->level == 0)) if (check_header(m) != OK) return(NOK); /* Body starts here */ inbuf->bodystart = inbuf->offset; inbuf->linestart = inbuf->loffset; /* Find end of bodypart */ set_end_by_lines(m, m->sd->bodylines); parse_sun_message(m); #ifdef DEBUG if (edebug) fprintf(stderr, "+ Marked up (MAILTOOL) body part %d at level %d starting at %lu and ending at %lu.\n", inbuf->count, m->level, inbuf->bodystart, inbuf->bodyend); #endif if (m->sd->offset < m->sd->end) { /* Allocate siblings data sructure */ sibm = (struct message *)copy_mstruct(m, 0); sibbuf = sibm->sd; sibbuf->end = inbuf->end; sibbuf->lend = inbuf->lend; sibbuf->offset = inbuf->bodyend; sibm->bigsib = m->bigsib; sibm->level = m->level; sibm->parent = m->parent; /* Run Sibling */ if ((status = parse_sun_siblings(sibm)) == OK) { #ifdef DEBUG if (edebug) fprintf(stderr, "* sibling ended at offset %lu\n", sibbuf->offset); #endif m->sibling = sibm; if (m->parent) m->parent->children += 1; return(OK); } else { if (status == SKIP) return(OK); else return(NOK); } } return(OK); }