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 (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: */