/*
**
** 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);
}
syntax highlighted by Code2HTML, v. 0.9.1