static char rcsid[] = "@(#)$Id: mpar_rfc822.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)
*
* Some code based on mime_parse.c, which is
* initially written by: Michael Elkins <elkins@aero.org>, 1995
* -- specially function mpar_rfc822_parse() is based on function
* rfc822_parse()
*
*****************************************************************************/
#include "def_melib.h"
#include "mpar_imp.h"
#include "s_me.h"
DEBUG_VAR(Debug,__FILE__,"mime");
#if ANSI_C
#define S_(x) static x;
#else
#define S_(x)
#endif
#define MPAR_rfc822_magic 0xFD02
struct mpar_rfc822 {
unsigned short magic; /* MPAR_rfc822_magic */
struct mimeinfo X;
};
S_(mpar_alloc mpar_rfc822_alloc)
static void mpar_rfc822_alloc(D)
struct mime_parser_data *D;
{
D->p.rfc822 = safe_malloc(sizeof (* (D->p.rfc822)));
/* bzero is defined on hdrs/defs.h */
bzero((void *)(D->p.rfc822),sizeof (*(D->p.rfc822)));
D->p.rfc822->magic = MPAR_rfc822_magic;
mime_t_zero( & (D->p.rfc822->X));
}
S_(mpar_free mpar_rfc822_free)
static void mpar_rfc822_free(D)
struct mime_parser_data *D;
{
if (D->p.rfc822) {
if (D->p.rfc822->magic != MPAR_rfc822_magic)
panic("MIME PARSER PANIC",__FILE__,__LINE__,"mpar_rfc822_free",
"Bad magic number",0);
/* mime_t_clear will call mime_parser_free() if needed */
mime_t_clear(& (D->p.rfc822->X));
/* bzero is defined on hdrs/defs.h */
bzero((void *)(D->p.rfc822),sizeof (*(D->p.rfc822)));
free(D->p.rfc822);
D->p.rfc822 = NULL;
}
}
S_(mpar_parse mpar_rfc822_parse)
static int mpar_rfc822_parse(D,s,defcharset,fp,header_error)
struct mime_parser_data *D;
struct mimeinfo *s;
charset_t defcharset;
FILE *fp;
struct header_errors **header_error;
{
int ret = 1; /* Always succeed ... */
long part_offset;
long body_offset;
long end_offset;
header_list_ptr headers = NULL, mime_version, content_type;
int pre_mime_content_type = 0;
if (D->p.rfc822->magic != MPAR_rfc822_magic)
panic("MIME PARSER PANIC",__FILE__,__LINE__,"mpar_rfc822_parse",
"Bad magic number",0);
DPRINT(Debug,9,(&Debug,
"mpar_rfc822_parse- (parsing) RFC822\n"));
fseek (fp, s->offset, SEEK_SET);
part_offset = ftell (fp);
if (part_offset != s->offset) {
DPRINT(Debug,9,(&Debug,
"mpar_rfc822_parse: seek to %ld gives pos %ld\n",
(long) s->offset,part_offset));
return 0;
}
end_offset = part_offset + s->length;
DPRINT(Debug,9,(&Debug,
"mpar_rfc822_parse --> len=%d\n",s->length));
/* Called to read MESSAGE/RFC822 data. First reads the header of the
* message for MIME information, then (when necessary) calls other
* functions to determine the content of MULTIPART or MESSAGE/RFC822
* data contained.
*/
headers = file_read_headers(fp,0);
body_offset = ftell(fp);
DPRINT(Debug,9,(&Debug,
"mpar_rfc822_parse- part_offset=%ld, body_offset=%ld, end_offset=%ld\n",
part_offset, body_offset, end_offset));
if (!locate_header_by_name(headers,"From") &&
!locate_header_by_name(headers,"Subject") &&
!locate_header_by_name(headers,"To") &&
!locate_header_by_name(headers,"CC")) {
lib_error(CATGETS(elm_msg_cat, MeSet, MeParseRFC822Corrupted,
"Seems that message/rfc822 data was corrupted."));
}
mime_version = locate_header_by_name(headers,"MIME-Version");
content_type = locate_header_by_name(headers,"Content-Type");
mime_t_clear(& (D->p.rfc822->X));
D->p.rfc822->X.begin_offset = part_offset;
D->p.rfc822->X.offset = body_offset;
D->p.rfc822->X.length = -1;
/* FIXME? update defcharset? */
if (content_type && content_type ->body)
pre_mime_content_type =
is_pre_mime_content_type(&(D->p.rfc822->X),
content_type->body);
if (mime_version && pre_mime_content_type) {
lib_error(CATGETS(elm_msg_cat, MeSet, MeParseRFC822PreWarn,
"Warning: message/rfc822 data with MIME-Version and pre-mime Content-type"));
}
if (mime_version ||
(!pre_mime_content_type && req_mime_bodyencoding)) {
parse_mime_headers1(& (D->p.rfc822->X),
headers,part_offset,
body_offset,
MIME_MIXED,defcharset,
header_error);
}
DPRINT(Debug,9,(&Debug,
"mpar_rfc822_parse: content-type=%s/%s; flags=%d\n",
get_major_type_name(D->p.rfc822->X.TYPE),
get_subtype_name(D->p.rfc822->X.TYPE),
get_type_flags(D->p.rfc822->X.TYPE)));
if (D->p.rfc822->X.length < 0) {
D->p.rfc822->X.length = end_offset - body_offset;
DPRINT(Debug,9,(&Debug,
"mpar_rfc822_parse: fixing length=%ld\n",
(long) D->p.rfc822->X.length));
}
mime_parser_parse(& (D->p.rfc822->X),defcharset,fp,header_error);
delete_headers(&headers);
/* Make sure the leave the stream at the end of the data! */
fseek (fp, end_offset, SEEK_SET);
DPRINT(Debug,9,(&Debug,
"mpar_rfc822_parse=%d <-- DONE\n",
ret));
return ret;
}
S_(mpar_subparts mpar_rfc822_subparts)
static int mpar_rfc822_subparts(D)
struct mime_parser_data *D;
{
return 1; /* CONSTANT */
}
S_(mpar_index mpar_rfc822_index)
static struct mimeinfo *mpar_rfc822_index(P,idx)
struct mime_parser_data *P;
int idx;
{
if (P->p.rfc822->magic != MPAR_rfc822_magic)
panic("MIME PARSER PANIC",__FILE__,__LINE__,"mpar_rfc822_index",
"Bad magic number",0);
if (idx != 0)
panic("MIME PARSER PANIC",__FILE__,__LINE__,"mpar_rfc822_index",
"Index out of range",0);
return (& (P->p.rfc822->X));
}
S_(mpar_copy mpar_rfc822_copy)
static void mpar_rfc822_copy(T,S)
struct mime_parser_data *T;
struct mime_parser_data *S;
{
if (S->p.rfc822->magic != MPAR_rfc822_magic)
panic("MIME PARSER PANIC",__FILE__,__LINE__,"mpar_rfc822_copy",
"Bad magic number",0);
if (T->p.rfc822->magic != MPAR_rfc822_magic)
panic("MIME PARSER PANIC",__FILE__,__LINE__,"mpar_rfc822_copy",
"Bad magic number",0);
mime_t_copy(& (T->p.rfc822->X), & (S->p.rfc822->X));
}
static struct mime_parser RFC822_PARSER = {
mpar_rfc822_alloc,
mpar_rfc822_free,
mpar_rfc822_parse,
mpar_rfc822_subparts,
mpar_rfc822_index,
mpar_rfc822_copy
};
#if __GNUC__
#define MTH struct media_type_handle
#define PARSER(A) handle_mime_parser, { parser_code: & A }
#define CAST1
#else
#define MTH struct COMPAT_media_type_handle
#define PARSER(A) handle_mime_parser, (void *) & A
#define CAST1 ( struct media_type_handle *)
#endif
static MTH rfc822_parser_1 = { PARSER(RFC822_PARSER) };
void register_rfc822_parser() {
register_mt_handler(give_media_type2(MIME_TYPE_MESSAGE,"rfc822",1),
CAST1 &rfc822_parser_1);
}
/*
* Local Variables:
* mode:c
* c-basic-offset:4
* buffer-file-coding-system: iso-8859-1
* End:
*/
syntax highlighted by Code2HTML, v. 0.9.1