/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * The contents of this file are subject to the Netscape Public License * Version 1.0 (the "NPL"); you may not use this file except in * compliance with the NPL. You may obtain a copy of the NPL at * http://www.mozilla.org/NPL/ * * Software distributed under the NPL is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL * for the specific language governing rights and limitations under the * NPL. * * The Initial Developer of this code under the NPL is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998 Netscape Communications Corporation. All Rights * Reserved. */ /* mimedrft.c --- save and restore drafts of unfinished messages */ #include "xp.h" #include "xpgetstr.h" #include "libi18n.h" #include "xp_time.h" #include "msgcom.h" #include "mimeobj.h" #include "mimemsg.h" #include "mimeenc.h" /* jrm - needed to make it build 97/02/21 */ /* ifdef MIME_DRAFTS has to be after the includes * since that's where MIME_DRAFTS will be defined, if it is. */ #ifdef MIME_DRAFTS /* whole file */ #define HEADER_NNTP_POSTING_HOST "NNTP-Posting-Host" extern int MK_UNABLE_TO_OPEN_TMP_FILE; extern int MK_MIME_ERROR_WRITING_FILE; extern int MK_MIMEHTML_DISP_SUBJECT; extern int MK_MIMEHTML_DISP_DATE; extern int MK_MIMEHTML_DISP_FROM; extern int MK_MIMEHTML_DISP_ORGANIZATION; extern int MK_MIMEHTML_DISP_TO; extern int MK_MIMEHTML_DISP_CC; extern int MK_MIMEHTML_DISP_NEWSGROUPS; extern int MK_MIMEHTML_DISP_BCC; int mime_decompose_file_init_fn ( void *stream_closure, MimeHeaders *headers ); int mime_decompose_file_output_fn ( char *buf, int32 size, void *stream_closure ); int mime_decompose_file_close_fn ( void *stream_closure ); extern char * strip_continuations(char *original); /* This struct is the state we used in MIME_ToDraftConverter() */ struct mime_draft_data { URL_Struct *url; /* original url */ int format_out; /* intended output format; should be FO_OPEN_DRAFT */ MWContext *context; NET_StreamClass *stream; /* not used for now */ MimeObject *obj; /* The root */ MimeDisplayOptions *options; /* data for communicating with libmime.a */ MimeHeaders *headers; /* copy of outer most mime header */ int attachments_count; /* how many attachments we have */ MSG_AttachedFile *attachments; /* attachments */ MSG_AttachedFile *messageBody; /* message body */ MSG_AttachedFile *curAttachment; /* temp */ char *tmp_file_name; /* current opened file for output */ XP_File tmp_file; /* output file handle */ MimeDecoderData *decoder_data; int16 mailcsid; /* get it from CHARSET of Content-Type and convert to csid */ }; static int dummy_file_write( char *buf, int32 size, void *fileHandle ) { return XP_FileWrite(buf, size, (XP_File) fileHandle); } static int mime_parse_stream_write ( NET_StreamClass *stream, const char *buf, int32 size ) { struct mime_draft_data *mdd = (struct mime_draft_data *) stream->data_object; XP_ASSERT ( mdd ); if ( !mdd || !mdd->obj ) return -1; return mdd->obj->class->parse_buffer ((char *) buf, size, mdd->obj); } static unsigned int mime_parse_stream_write_ready ( NET_StreamClass *stream ) { struct mime_draft_data *mdd = (struct mime_draft_data *) stream->data_object; XP_ASSERT (mdd); if (!mdd) return MAX_WRITE_READY; if (mdd->stream) return mdd->stream->is_write_ready ( mdd->stream ); else return MAX_WRITE_READY; } static void mime_free_attachments ( MSG_AttachedFile *attachments, int count ) { int i; MSG_AttachedFile *cur = attachments; XP_ASSERT ( attachments && count > 0 ); if ( !attachments || count <= 0 ) return; for ( i = 0; i < count; i++, cur++ ) { FREEIF ( cur->orig_url ); FREEIF ( cur->type ); FREEIF ( cur->encoding ); FREEIF ( cur->description ); FREEIF ( cur->x_mac_type ); FREEIF ( cur->x_mac_creator ); if ( cur->file_name ) { XP_FileRemove( cur->file_name, xpFileToPost ); FREEIF ( cur->file_name ); } } XP_FREE ( attachments ); } static int mime_draft_process_attachments ( struct mime_draft_data *mdd, MSG_Pane *cpane ) { struct MSG_AttachmentData *attachData = NULL, *tmp = NULL; struct MSG_AttachedFile *tmpFile = NULL; int i; XP_ASSERT ( mdd->attachments_count && mdd->attachments ); if ( !mdd->attachments || !mdd->attachments_count ) return -1; attachData = XP_ALLOC( ( (mdd->attachments_count+1) * sizeof (MSG_AttachmentData) ) ); if ( !attachData ) return MK_OUT_OF_MEMORY; XP_MEMSET ( attachData, 0, (mdd->attachments_count+1) * sizeof (MSG_AttachmentData) ); tmpFile = mdd->attachments; tmp = attachData; for ( i=0; i < mdd->attachments_count; i++, tmp++, tmpFile++ ) { if (tmpFile->type) { if (strcasecomp ( tmpFile->type, "text/x-vcard") == 0) StrAllocCopy (tmp->real_name, tmpFile->description); } if ( tmpFile->orig_url ) { StrAllocCopy ( tmp->url, tmpFile->orig_url ); if (!tmp->real_name) StrAllocCopy ( tmp->real_name, tmpFile->orig_url ); } if ( tmpFile->type ) { StrAllocCopy ( tmp->desired_type, tmpFile->type ); StrAllocCopy ( tmp->real_type, tmpFile->type ); } if ( tmpFile->encoding ) { StrAllocCopy ( tmp->real_encoding, tmpFile->encoding ); } if ( tmpFile->description ) { StrAllocCopy ( tmp->description, tmpFile->description ); } if ( tmpFile->x_mac_type ) { StrAllocCopy ( tmp->x_mac_type, tmpFile->x_mac_type ); } if ( tmpFile->x_mac_creator ) { StrAllocCopy ( tmp->x_mac_creator, tmpFile->x_mac_creator ); } } MSG_SetPreloadedAttachments ( cpane, MSG_GetContext (cpane), attachData, mdd->attachments, mdd->attachments_count ); XP_FREE (attachData); return 0; } static void mime_fix_up_html_address( char **addr) { /* We need to replace paired <> they are treated as HTML tag */ if (addr && *addr && XP_STRCHR(*addr, '<') && XP_STRCHR(*addr, '>')) { char *lt = NULL; int32 newLen = 0; do { newLen = XP_STRLEN(*addr) + 3 + 1; *addr = (char *) XP_REALLOC(*addr, newLen); XP_ASSERT (*addr); lt = XP_STRCHR(*addr, '<'); XP_ASSERT(lt); XP_MEMCPY(lt+4, lt+1, newLen - 4 - (lt - *addr)); *lt++ = '&'; *lt++ = 'l'; *lt++ = 't'; *lt = ';'; } while (XP_STRCHR(*addr, '<')); } } static void mime_intl_mimepart_2_str(char **str, int16 mcsid) { if (str && *str) { char *newStr = (char *) IntlDecodeMimePartIIStr (*str, INTL_DocToWinCharSetID(mcsid), FALSE); if (newStr && newStr != *str) { FREEIF(*str); *str = newStr; } else { strip_continuations(*str); } } } static void mime_intl_insert_message_header(char **body, char**hdr_value, char *hdr_str, int html_hdr_id, int16 mailcsid, XP_Bool htmlEdit) { const char *newName = NULL; if (!body || !hdr_value || !hdr_str) return; mime_intl_mimepart_2_str(hdr_value, mailcsid); if (htmlEdit) StrAllocCat(*body, LINEBREAK "
"); else StrAllocCat(*body, LINEBREAK); newName = XP_GetStringForHTML(html_hdr_id, mailcsid, hdr_str); if (!newName) newName = hdr_str; StrAllocCat(*body, newName); if (htmlEdit) StrAllocCat(*body, ": "); else StrAllocCat(*body, ": "); StrAllocCat(*body, *hdr_value); } static void mime_parse_stream_complete (NET_StreamClass *stream) { struct mime_draft_data *mdd = (struct mime_draft_data *) stream->data_object; MSG_Pane * cpane = NULL; MSG_CompositionFields *fields = NULL; int htmlAction = 0; int lineWidth = 0; char *host = 0; char *news_host = 0; char *to_and_cc = 0; char *re_subject = 0; char *new_refs = 0; char *from = 0; char *repl = 0; char *subj = 0; char *id = 0; char *refs = 0; char *to = 0; char *cc = 0; char *bcc = 0; char *fcc = 0; char *org = 0; char *grps = 0; char *foll = 0; char *priority = 0; char *draftInfo = 0; XP_Bool altform_p = FALSE; /* #### how do we determine this? */ XP_Bool sign_p = FALSE; /* #### how do we determine this? */ XP_ASSERT (mdd); if (!mdd) return; if (mdd->obj) { int status; status = mdd->obj->class->parse_eof ( mdd->obj, FALSE ); mdd->obj->class->parse_end( mdd->obj, status < 0 ? TRUE : FALSE ); altform_p = HG09842 ; sign_p = mdd->options->signed_p; XP_ASSERT ( mdd->options == mdd->obj->options ); mime_free (mdd->obj); mdd->obj = 0; if (mdd->options) { FREEIF (mdd->options->part_to_load); XP_FREE(mdd->options); mdd->options = 0; } if (mdd->stream) { mdd->stream->complete (mdd->stream); XP_FREE( mdd->stream ); mdd->stream = 0; } } /* time to bring up the compose windows with all the info gathered */ if ( mdd->headers ) { subj = MimeHeaders_get(mdd->headers, HEADER_SUBJECT, FALSE, FALSE); repl = MimeHeaders_get(mdd->headers, HEADER_REPLY_TO, FALSE, FALSE); to = MimeHeaders_get(mdd->headers, HEADER_TO, FALSE, TRUE); cc = MimeHeaders_get(mdd->headers, HEADER_CC, FALSE, TRUE); bcc = MimeHeaders_get(mdd->headers, HEADER_BCC, FALSE, TRUE); /* These headers should not be RFC-1522-decoded. */ grps = MimeHeaders_get(mdd->headers, HEADER_NEWSGROUPS, FALSE, TRUE); foll = MimeHeaders_get(mdd->headers, HEADER_FOLLOWUP_TO, FALSE, TRUE); host = MimeHeaders_get(mdd->headers, HEADER_X_MOZILLA_NEWSHOST, FALSE, FALSE); if (!host) host = MimeHeaders_get(mdd->headers, HEADER_NNTP_POSTING_HOST, FALSE, FALSE); id = MimeHeaders_get(mdd->headers, HEADER_MESSAGE_ID, FALSE, FALSE); refs = MimeHeaders_get(mdd->headers, HEADER_REFERENCES, FALSE, TRUE); priority = MimeHeaders_get(mdd->headers, HEADER_X_PRIORITY, FALSE, FALSE); mime_intl_mimepart_2_str(&repl, mdd->mailcsid); mime_intl_mimepart_2_str(&to, mdd->mailcsid); mime_intl_mimepart_2_str(&cc, mdd->mailcsid); mime_intl_mimepart_2_str(&bcc, mdd->mailcsid); mime_intl_mimepart_2_str(&grps, mdd->mailcsid); mime_intl_mimepart_2_str(&foll, mdd->mailcsid); mime_intl_mimepart_2_str(&host, mdd->mailcsid); if (host) { char *secure = NULL; secure = strcasestr(host, "secure"); if (secure) { *secure = 0; news_host = PR_smprintf ("snews://%s", host); } else { news_host = PR_smprintf ("news://%s", host); } } mime_intl_mimepart_2_str(&subj, mdd->mailcsid); fields = MSG_CreateCompositionFields( from, repl, to, cc, bcc, fcc, grps, foll, org, subj, refs, 0, priority, 0, news_host, altform_p, sign_p); draftInfo = MimeHeaders_get(mdd->headers, HEADER_X_MOZILLA_DRAFT_INFO, FALSE, FALSE); if (draftInfo && fields) { char *parm = 0; parm = MimeHeaders_get_parameter(draftInfo, "vcard", NULL, NULL); if (parm && !XP_STRCMP(parm, "1")) MSG_SetCompFieldsBoolHeader(fields, MSG_ATTACH_VCARD_BOOL_HEADER_MASK, TRUE); else MSG_SetCompFieldsBoolHeader(fields, MSG_ATTACH_VCARD_BOOL_HEADER_MASK, FALSE); FREEIF(parm); parm = MimeHeaders_get_parameter(draftInfo, "receipt", NULL, NULL); if (parm && !XP_STRCMP(parm, "0")) MSG_SetCompFieldsBoolHeader(fields, MSG_RETURN_RECEIPT_BOOL_HEADER_MASK, FALSE); else { int receiptType = 0; MSG_SetCompFieldsBoolHeader(fields, MSG_RETURN_RECEIPT_BOOL_HEADER_MASK, TRUE); sscanf(parm, "%d", &receiptType); MSG_SetCompFieldsReceiptType(fields, (int32) receiptType); } FREEIF(parm); parm = MimeHeaders_get_parameter(draftInfo, "uuencode", NULL, NULL); if (parm && !XP_STRCMP(parm, "1")) MSG_SetCompFieldsBoolHeader(fields, MSG_UUENCODE_BINARY_BOOL_HEADER_MASK, TRUE); else MSG_SetCompFieldsBoolHeader(fields, MSG_UUENCODE_BINARY_BOOL_HEADER_MASK, FALSE); FREEIF(parm); parm = MimeHeaders_get_parameter(draftInfo, "html", NULL, NULL); if (parm) sscanf(parm, "%d", &htmlAction); FREEIF(parm); parm = MimeHeaders_get_parameter(draftInfo, "linewidth", NULL, NULL); if (parm) sscanf(parm, "%d", &lineWidth); FREEIF(parm); } if (mdd->messageBody) { char *body; XP_StatStruct st; uint32 bodyLen = 0; XP_File file; MSG_EditorType editorType = MSG_DEFAULT; st.st_size = 0; XP_Stat (mdd->messageBody->file_name, &st, xpFileToPost); bodyLen = st.st_size; body = XP_ALLOC (bodyLen + 1); if (body) { XP_MEMSET (body, 0, bodyLen+1); file = XP_FileOpen (mdd->messageBody->file_name, xpFileToPost, XP_FILE_READ_BIN); XP_FileRead (body, bodyLen, file); XP_FileClose(file); if (mdd->messageBody->type && *mdd->messageBody->type) { if( XP_STRSTR(mdd->messageBody->type, "text/html") != NULL ) editorType = MSG_HTML_EDITOR; else if ( XP_STRSTR(mdd->messageBody->type, "text/plain") != NULL ) editorType = MSG_PLAINTEXT_EDITOR; } else { editorType = MSG_PLAINTEXT_EDITOR; } { CCCDataObject conv = INTL_CreateCharCodeConverter(); if(conv) { if (INTL_GetCharCodeConverter(mdd->mailcsid, INTL_DocToWinCharSetID(mdd->mailcsid), conv)) { char *newBody = NULL; newBody = (char *)INTL_CallCharCodeConverter( conv, (unsigned char *) body, (int32) bodyLen); if (newBody) { /* CharCodeConverter return the char* to the orginal string we don't want to free body in that case */ if( newBody != body) FREEIF(body); body = newBody; } } INTL_DestroyCharCodeConverter(conv); } } } cpane = FE_CreateCompositionPane (mdd->context, fields, body, editorType); XP_FREE (body); mime_free_attachments (mdd->messageBody, 1); } else { cpane = FE_CreateCompositionPane(mdd->context, fields, NULL, MSG_DEFAULT); } if (cpane) { /* clear the message body in case someone store the signature string in it */ MSG_SetCompBody(cpane, ""); MSG_SetHTMLAction(cpane, (MSG_HTMLComposeAction) htmlAction); if (lineWidth > 0) MSG_SetLineWidth(cpane, lineWidth); if ( mdd->attachments_count) mime_draft_process_attachments (mdd, cpane); } } else { fields = MSG_CreateCompositionFields( from, repl, to, cc, bcc, fcc, grps, foll, org, subj, refs, 0, priority, 0, news_host, HG09843, HG09844 ); if (fields) cpane = FE_CreateCompositionPane(mdd->context, fields, NULL, MSG_DEFAULT); } if (cpane && mdd->url->fe_data) { #ifdef MOZ_MAIL_NEWS if ( mdd->format_out != FO_CMDLINE_ATTACHMENTS ) { MSG_SetPostDeliveryActionInfo (cpane, mdd->url->fe_data); } else #endif /* MOZ_MAIL_NEWS */ { MSG_SetAttachmentList ( cpane, (MSG_AttachmentData*)(mdd->url->fe_data)); } } if ( mdd->headers ) MimeHeaders_free ( mdd->headers ); if (mdd->attachments) /* do not call mime_free_attachments just use FREEIF() */ FREEIF ( mdd->attachments ); if (fields) MSG_DestroyCompositionFields(fields); XP_FREE (mdd); FREEIF(host); FREEIF(to_and_cc); FREEIF(re_subject); FREEIF(new_refs); FREEIF(from); FREEIF(repl); FREEIF(subj); FREEIF(id); FREEIF(refs); FREEIF(to); FREEIF(cc); FREEIF(grps); FREEIF(foll); FREEIF(priority); FREEIF(draftInfo); } static void mime_parse_stream_abort (NET_StreamClass *stream, int status ) { struct mime_draft_data *mdd = (struct mime_draft_data *) stream->data_object; XP_ASSERT (mdd); if (!mdd) return; if (mdd->obj) { int status=0; if ( !mdd->obj->closed_p ) status = mdd->obj->class->parse_eof ( mdd->obj, TRUE ); if ( !mdd->obj->parsed_p ) mdd->obj->class->parse_end( mdd->obj, TRUE ); XP_ASSERT ( mdd->options == mdd->obj->options ); mime_free (mdd->obj); mdd->obj = 0; if (mdd->options) { FREEIF (mdd->options->part_to_load); XP_FREE(mdd->options); mdd->options = 0; } if (mdd->stream) { mdd->stream->abort (mdd->stream, status); XP_FREE( mdd->stream ); mdd->stream = 0; } } if ( mdd->headers ) MimeHeaders_free (mdd->headers); if (mdd->attachments) mime_free_attachments( mdd->attachments, mdd->attachments_count ); XP_FREE (mdd); } static int make_mime_headers_copy ( void *closure, MimeHeaders *headers ) { struct mime_draft_data *mdd = (struct mime_draft_data *) closure; XP_ASSERT ( mdd && headers ); if ( !mdd || ! headers ) return 0; XP_ASSERT ( mdd->headers == NULL ); mdd->headers = MimeHeaders_copy ( headers ); mdd->options->done_parsing_outer_headers = TRUE; return 0; } int mime_decompose_file_init_fn ( void *stream_closure, MimeHeaders *headers ) { struct mime_draft_data *mdd = (struct mime_draft_data *) stream_closure; MSG_AttachedFile *attachments = 0, *newAttachment = 0; int nAttachments = 0; char *hdr_value = NULL, *parm_value = NULL; XP_Bool needURL = FALSE; XP_Bool creatingMsgBody = FALSE; XP_ASSERT (mdd && headers); if (!mdd || !headers) return -1; if ( !mdd->options->is_multipart_msg ) { if (mdd->options->decompose_init_count) { mdd->options->decompose_init_count++; XP_ASSERT(mdd->curAttachment); if (mdd->curAttachment) { char *ct = MimeHeaders_get(headers, HEADER_CONTENT_TYPE, TRUE, FALSE); if (ct) StrAllocCopy(mdd->curAttachment->type, ct); FREEIF(ct); } return 0; } else { mdd->options->decompose_init_count++; } } nAttachments = mdd->attachments_count; if (!nAttachments && !mdd->messageBody) { char *charset = NULL, *contentType = NULL; contentType = MimeHeaders_get(headers, HEADER_CONTENT_TYPE, FALSE, FALSE); if (contentType) { charset = MimeHeaders_get_parameter(contentType, "charset", NULL, NULL); mdd->mailcsid = INTL_CharSetNameToID(charset); FREEIF(charset); FREEIF(contentType); } mdd->messageBody = XP_NEW_ZAP (MSG_AttachedFile); XP_ASSERT (mdd->messageBody); if (!mdd->messageBody) return MK_OUT_OF_MEMORY; newAttachment = mdd->messageBody; creatingMsgBody = TRUE; } else { /* always allocate one more extra; don't ask me why */ needURL = TRUE; if ( nAttachments ) { XP_ASSERT (mdd->attachments); attachments = XP_REALLOC (mdd->attachments, sizeof (MSG_AttachedFile) * (nAttachments + 2)); if (!attachments) return MK_OUT_OF_MEMORY; mdd->attachments = attachments; mdd->attachments_count++; } else { XP_ASSERT (!mdd->attachments); attachments = XP_ALLOC ( sizeof (MSG_AttachedFile) * 2); if (!attachments) return MK_OUT_OF_MEMORY; mdd->attachments_count++; mdd->attachments = attachments; } newAttachment = attachments + nAttachments; XP_MEMSET ( newAttachment, 0, sizeof (MSG_AttachedFile) * 2 ); } newAttachment->orig_url = MimeHeaders_get_name ( headers ); if (!newAttachment->orig_url) { parm_value = MimeHeaders_get( headers, HEADER_CONTENT_BASE, FALSE, FALSE ); if (parm_value) { char *cp = NULL, *cp1=NULL ; NET_UnEscape(parm_value); /* strip '"' */ cp = parm_value; while (*cp == '"') cp++; if ((cp1 = XP_STRCHR(cp, '"'))) *cp1 = 0; StrAllocCopy(newAttachment->orig_url, cp); FREEIF(parm_value); } } mdd->curAttachment = newAttachment; newAttachment->type = MimeHeaders_get ( headers, HEADER_CONTENT_TYPE, TRUE, FALSE ); /* This is to handle the degenerated Apple Double attachment. */ parm_value = MimeHeaders_get( headers, HEADER_CONTENT_TYPE, FALSE, FALSE ); if (parm_value) { char *boundary = NULL; char *tmp_value = NULL; boundary = MimeHeaders_get_parameter(parm_value, "boundary", NULL, NULL); if (boundary) tmp_value = PR_smprintf("; boundary=\"%s\"", boundary); if (tmp_value) StrAllocCat(newAttachment->type, tmp_value); newAttachment->x_mac_type = MimeHeaders_get_parameter(parm_value, "x-mac-type", NULL, NULL); newAttachment->x_mac_creator = MimeHeaders_get_parameter(parm_value, "x-mac-creator", NULL, NULL); FREEIF(parm_value); FREEIF(boundary); FREEIF(tmp_value); } newAttachment->encoding = MimeHeaders_get ( headers, HEADER_CONTENT_TRANSFER_ENCODING, FALSE, FALSE ); newAttachment->description = MimeHeaders_get( headers, HEADER_CONTENT_DESCRIPTION, FALSE, FALSE ); mdd->tmp_file_name = WH_TempName (xpFileToPost, "nsmail"); if (!mdd->tmp_file_name) return MK_OUT_OF_MEMORY; StrAllocCopy (newAttachment->file_name, mdd->tmp_file_name); mdd->tmp_file = XP_FileOpen ( mdd->tmp_file_name, xpFileToPost, XP_FILE_WRITE_BIN ); if (!mdd->tmp_file) return MK_UNABLE_TO_OPEN_TMP_FILE; /* if need an URL and we don't have one, let's fake one */ if (needURL && !newAttachment->orig_url) { newAttachment->orig_url = PR_smprintf ("file://%s", mdd->tmp_file_name); } if (creatingMsgBody) { MimeDecoderData *(*fn) (int (*) (const char*, int32, void*), void*) = 0; /* Initialize a decoder if necessary. */ if (!newAttachment->encoding || HG89332) ; else if (!strcasecomp(newAttachment->encoding, ENCODING_BASE64)) fn = &MimeB64DecoderInit; else if (!strcasecomp(newAttachment->encoding, ENCODING_QUOTED_PRINTABLE)) fn = &MimeQPDecoderInit; else if (!strcasecomp(newAttachment->encoding, ENCODING_UUENCODE) || !strcasecomp(newAttachment->encoding, ENCODING_UUENCODE2) || !strcasecomp(newAttachment->encoding, ENCODING_UUENCODE3) || !strcasecomp(newAttachment->encoding, ENCODING_UUENCODE4)) fn = &MimeUUDecoderInit; if (fn) { mdd->decoder_data = fn (/* The (int (*) ...) cast is to turn the `void' argument into `MimeObject'. */ ((int (*) (const char *, int32, void *)) dummy_file_write), mdd->tmp_file); if (!mdd->decoder_data) return MK_OUT_OF_MEMORY; } } return 0; } int mime_decompose_file_output_fn ( char *buf, int32 size, void *stream_closure ) { struct mime_draft_data *mdd = (struct mime_draft_data *) stream_closure; int ret = 0; XP_ASSERT (mdd && buf); if (!mdd || !buf) return -1; if (!size) return 0; /****** doesn't seem to be needed ***** XP_ASSERT (mdd->tmp_file && mdd->tmp_file_name); */ if ( !mdd->tmp_file ) return 0; if (mdd->decoder_data) { ret = MimeDecoderWrite(mdd->decoder_data, buf, size); if (ret == -1) return -1; } else { ret = XP_FileWrite(buf, size, mdd->tmp_file); if (ret < size) return MK_MIME_ERROR_WRITING_FILE; } return 0; } int mime_decompose_file_close_fn ( void *stream_closure ) { struct mime_draft_data *mdd = (struct mime_draft_data *) stream_closure; /* relax the rule in case we encountered invalid bigfun situation XP_ASSERT (mdd && mdd->tmp_file); */ if ( !mdd || !mdd->tmp_file ) return -1; if ( !mdd->options->is_multipart_msg ) { if ( --mdd->options->decompose_init_count > 0 ) return 0; } if (mdd->decoder_data) { MimeDecoderDestroy(mdd->decoder_data, FALSE); mdd->decoder_data = 0; } XP_FileClose ( mdd->tmp_file ); mdd->tmp_file = 0; FREEIF ( mdd->tmp_file_name ); mdd->tmp_file_name = 0; return 0; } extern NET_StreamClass * MIME_ToDraftConverter ( int format_out, void *closure, URL_Struct *url, MWContext *context ) { int status = 0; NET_StreamClass * stream = NULL; struct mime_draft_data *mdd = NULL; MimeObject *obj; XP_ASSERT (url && context); if ( !url || !context ) return NULL; mdd = XP_NEW_ZAP (struct mime_draft_data); if (!mdd) return 0; mdd->url = url; mdd->context = context; mdd->format_out = format_out; mdd->options = XP_NEW_ZAP ( MimeDisplayOptions ); if ( !mdd->options ) { XP_FREE (mdd); return 0; } mdd->options->passwd_prompt_fn_arg = context; mdd->options->decompose_file_p = TRUE; /* new field in MimeDisplayOptions */ mdd->options->url = url->address; mdd->options->stream_closure = mdd; mdd->options->html_closure = mdd; mdd->options->decompose_headers_info_fn = make_mime_headers_copy; mdd->options->decompose_file_init_fn = mime_decompose_file_init_fn; mdd->options->decompose_file_output_fn = mime_decompose_file_output_fn; mdd->options->decompose_file_close_fn = mime_decompose_file_close_fn; #ifdef FO_MAIL_MESSAGE_TO /* If we're attaching a message (for forwarding) then we must eradicate all traces of bigfun from it, since forwarding someone else a message that wasn't bigfun for them doesn't work. We have to bigfun it before sending it. */ HG09878 #endif /* FO_MAIL_MESSAGE_TO */ obj = mime_new ( (MimeObjectClass *) &mimeMessageClass, (MimeHeaders *) NULL, MESSAGE_RFC822 ); if ( !obj ) { FREEIF( mdd->options->part_to_load ); XP_FREE ( mdd->options ); XP_FREE ( mdd ); return 0; } obj->options = mdd->options; mdd->obj = obj; stream = XP_NEW_ZAP ( NET_StreamClass ); if ( !stream ) { FREEIF( mdd->options->part_to_load ); XP_FREE ( mdd->options ); XP_FREE ( mdd ); XP_FREE ( obj ); return 0; } stream->name = "MIME To Draft Converter Stream"; stream->complete = mime_parse_stream_complete; stream->abort = mime_parse_stream_abort; stream->put_block = mime_parse_stream_write; stream->is_write_ready = mime_parse_stream_write_ready; stream->data_object = mdd; stream->window_id = context; status = obj->class->initialize ( obj ); if ( status >= 0 ) status = obj->class->parse_begin ( obj ); if ( status < 0 ) { XP_FREE ( stream ); FREEIF( mdd->options->part_to_load ); XP_FREE ( mdd->options ); XP_FREE ( mdd ); XP_FREE ( obj ); return 0; } return stream; } #endif /* MIME_DRAFTS */