static char rcsid[] = "@(#)$Id: mparser.c,v 1.9 2006/05/07 08:35:31 hurtta Exp $";
/******************************************************************************
* The Elm (ME+) Mail System - $Revision: 1.9 $ $State: Exp $
*
* Author: Kari Hurtta <hurtta+elm@posti.FMI.FI> (was hurtta+elm@ozone.FMI.FI)
*****************************************************************************/
#include "def_melib.h"
#include "mpar_imp.h"
DEBUG_VAR(Debug,__FILE__,"mime");
#define MPAR_magic 0xFD01
void mime_parser_free(P)
struct mime_parser_data **P;
{
if ((*P)->magic != MPAR_magic)
panic("MIME PARSER PANIC",__FILE__,__LINE__,"mime_parser_free",
"Bad magic number",0);
if ((*P)->parser_code)
(*P)->parser_code->free_data(*P);
(*P)->parser_code = NULL; /* NOT determined yet */
if ((*P)->p.any) {
panic("MIME PARSER PANIC",__FILE__,__LINE__,"mime_parser_free",
"Parsed data not empty",0);
}
/* bzero is defined on hdrs/defs.h */
bzero((void *)*P,sizeof (**P));
free(*P);
*P = NULL;
}
void copy_parser_data(target,source)
struct mime_parser_data **target;
struct mime_parser_data *source;
{
struct mime_parser *f;
if (*target) {
if ((*target)->magic != MPAR_magic)
panic("MIME PARSER PANIC",__FILE__,__LINE__,"copy_parser_data",
"Bad magic number",0);
if ((*target)->parser_code)
(*target)->parser_code->free_data((*target));
(*target)->parser_code = NULL; /* NOT determined yet */
} else {
(*target) = safe_malloc(sizeof (*((*target))));
/* bzero is defined on hdrs/defs.h */
bzero((void *)(*target),sizeof (*((*target))));
(*target)->magic = MPAR_magic;
(*target)->parser_code = NULL;
(*target)->p.any = NULL;
}
if (source->magic != MPAR_magic)
panic("MIME PARSER PANIC",__FILE__,__LINE__,"copy_parser_data",
"Bad magic number",0);
if (! source->parser_code)
panic("MIME PARSER PANIC",__FILE__,__LINE__,"copy_parser_data",
"No parser code",0);
f = source->parser_code;
if ((*target)->p.any) {
panic("MIME PARSER PANIC",__FILE__,__LINE__,"copy_parser_data",
"Parsed data not empty",0);
}
(*target)->parser_code = f;
f->alloc_data(*target);
f->copy_data(*target,source);
}
int mime_parser_subparts(P)
struct mime_parser_data *P;
{
int ret;
if (P->magic != MPAR_magic)
panic("MIME PARSER PANIC",__FILE__,__LINE__,"mime_parser_subparts",
"Bad magic number",0);
if (! P->parser_code)
panic("MIME PARSER PANIC",__FILE__,__LINE__,"mime_parser_subparts",
"No parser code",0);
ret = P->parser_code->count_subparts(P);
DPRINT(Debug,10,(&Debug,
"mime_parser_subparts = %d\n",
ret));
return ret;
}
struct mimeinfo * mime_parser_index(P,idx)
struct mime_parser_data *P;
int idx;
{
struct mimeinfo *ret;
if (P->magic != MPAR_magic)
panic("MIME PARSER PANIC",__FILE__,__LINE__,"mime_parser_index",
"Bad magic number",0);
if (! P->parser_code)
panic("MIME PARSER PANIC",__FILE__,__LINE__,"mime_parser_index",
"No parser code",0);
ret = P->parser_code->index_subpart(P,idx);
DPRINT(Debug,10,(&Debug,
"mime_parser_index[%d] = %p\n",
idx,ret));
return ret;
}
static int mime_register_parsers_called = 0;
static void mime_register_parsers P_((void));
static void mime_register_parsers()
{
register_rfc822_parser();
register_multipart_parser();
register_leaf_parser();
mime_register_parsers_called++;
}
int mime_parser_parse(P,defcharset,fp, header_error)
struct mimeinfo *P;
charset_t defcharset;
FILE *fp;
struct header_errors **header_error;
{
struct media_type_handle *H = NULL;
int is_default = 0;
if (!mime_register_parsers_called)
mime_register_parsers();
if (P->parser_data) {
/* Already alloced */
DPRINT(Debug,8,(&Debug,
"mime_parser_parse: Reparsing type\n"));
if (P->parser_data->magic != MPAR_magic)
panic("MIME PARSER PANIC",__FILE__,__LINE__,"mime_parser_parse",
"Bad magic number",0);
if (P->parser_data->parser_code)
P->parser_data->parser_code->free_data(P->parser_data);
P->parser_data->parser_code = NULL; /* NOT determined yet */
} else {
P->parser_data = safe_malloc(sizeof (*(P->parser_data)));
/* bzero is defined on hdrs/defs.h */
bzero((void *)(P->parser_data),sizeof (*(P->parser_data)));
P->parser_data->magic = MPAR_magic;
P->parser_data->parser_code = NULL;
P->parser_data->p.any = NULL;
}
/* RESET loop variables */
H = NULL;
is_default = 0;
while (walk_mt_handler(P->TYPE,&H,&is_default,handle_mime_parser)) {
struct mime_parser *f;
if (H->type != handle_mime_parser)
panic("MIME PARSER PANIC",__FILE__,__LINE__,
"mime_parser_alloc",
"walk_mt_handler returned bad handler type",0);
if (! H->p.parser_code)
panic("MIME PARSER PANIC",__FILE__,__LINE__,
"mime_parser_alloc",
"walk_mt_handler did not returned parser code",0);
if (P->parser_data->p.any) {
panic("MIME PARSER PANIC",__FILE__,__LINE__,"mime_parser_parse",
"Parsed data not empty",0);
}
DPRINT(Debug,10,(&Debug,
"mime_parser_parse: Traying handler %p (%p) for type %p\n",
H,H->p.parser_code,P->TYPE));
f=H->p.parser_code;
P->parser_data->parser_code = f;
f->alloc_data(P->parser_data);
if (f->parse_data(P->parser_data,P,defcharset,fp, header_error)) {
/* SUCCEED */
DPRINT(Debug,10,(&Debug,
"mime_parser_parse: parse_data succeed\n"));
return 1;
}
f->free_data(P->parser_data);
P->parser_data->parser_code = NULL;
}
DPRINT(Debug,8,(&Debug,
"mime_parser_parse: No one parser succeed for type %p\n",
P->TYPE));
if (P->parser_data->p.any) {
panic("MIME PARSER PANIC",__FILE__,__LINE__,"mime_parser_parse",
"Parsed data not empty on failure",0);
}
if (P->parser_data) {
DPRINT(Debug,8,(&Debug,
"mime_parser_parse: FREEing parser data on failure\n"));
mime_parser_free( & (P->parser_data) );
}
/* FAILURE */
return 0;
}
/*
* Local Variables:
* mode:c
* c-basic-offset:4
* buffer-file-coding-system: iso-8859-1
* End:
*/
syntax highlighted by Code2HTML, v. 0.9.1