/* -*- 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. */ /* * state machine to handle mailbox URL */ #include "mkutils.h" #include "mkgeturl.h" #include "mktcp.h" #include "mkparse.h" #include "mkmailbx.h" #include "msgcom.h" #include "msgnet.h" #include "msg_srch.h" #include "libmime.h" #include "merrors.h" #include "mkimap4.h" #include "netutils.h" #ifdef XP_MAC #include "msg_srch.h" #endif /* for XP_GetString() */ #include "xpgetstr.h" extern int XP_MAIL_READING_FOLDER; extern int XP_MAIL_READING_MESSAGE; extern int XP_COMPRESSING_FOLDER; extern int XP_MAIL_DELIVERING_QUEUED_MESSAGES; extern int XP_READING_MESSAGE_DONE; extern int XP_MAIL_READING_FOLDER_DONE; extern int XP_MAIL_COMPRESSING_FOLDER_DONE; extern int XP_MAIL_DELIVERING_QUEUED_MESSAGES_DONE; extern int XP_MAIL_SEARCHING; extern int MK_OUT_OF_MEMORY; /* definitions of states for the state machine design */ typedef enum _MailboxStates { MAILBOX_OPEN_FOLDER, MAILBOX_FINISH_OPEN_FOLDER, MAILBOX_OPEN_MESSAGE, MAILBOX_OPEN_STREAM, MAILBOX_READ_MESSAGE, MAILBOX_COMPRESS_FOLDER, MAILBOX_FINISH_COMPRESS_FOLDER, MAILBOX_BACKGROUND, MAILBOX_NULL, MAILBOX_NULL2, MAILBOX_DELIVER_QUEUED, MAILBOX_FINISH_DELIVER_QUEUED, MAILBOX_DONE, MAILBOX_ERROR_DONE, MAILBOX_FREE, MAILBOX_COPY_MESSAGES, MAILBOX_FINISH_COPY_MESSAGES } MailboxStates; /* structure to hold data pertaining to the active state of * a transfer in progress. * */ typedef struct _MailboxConData { MSG_Pane *pane; int next_state; /* the next state or action to be taken */ int initial_state; /* why we are here */ Bool pause_for_read; /* Pause now for next read? */ void *folder_ptr; void *msg_ptr; void *compress_folder_ptr; void *deliver_queued_ptr; void *mailbox_search_ptr; char *folder_name; char *msg_id; int32 msgnum; /* -1 if none specified. */ NET_StreamClass *stream; XP_Bool destroy_graph_progress; /* do we need to destroy * graph progress? */ int32 original_content_length; /* the content length at the time of * calling graph progress */ char *input_buffer; int32 input_buffer_size; } MailboxConData; #define COMPLETE_STREAM (*cd->stream->complete)(cd->stream) #define ABORT_STREAM(s) (*cd->stream->abort)(cd->stream, s) #define PUT_STREAM(buf, size) (*cd->stream->put_block) \ (cd->stream, buf, size) /* forward decl */ PRIVATE int32 net_ProcessMailbox (ActiveEntry *ce); PRIVATE int32 net_MailboxLoad (ActiveEntry * ce) { /* get memory for Connection Data */ MailboxConData * cd; char *path; char *search; char *part; char *wholeUrl; /* temp, until imap urls have their own identifier */ if (!XP_STRNCASECMP(ce->URL_s->address, "IMAP://", 7) ) return NET_IMAP4Load(ce); if (XP_STRCASECMP(ce->URL_s->address, "mailbox:displayattachments") == 0) { MIME_DisplayAttachmentPane(ce->window_id); return -1; } cd = XP_NEW(MailboxConData); path = NET_ParseURL(ce->URL_s->address, GET_PATH_PART); search = NET_ParseURL(ce->URL_s->address, GET_SEARCH_PART); part = search; ce->con_data = cd; if(!ce->con_data) { ce->URL_s->error_msg = NET_ExplainErrorDetails(MK_OUT_OF_MEMORY); ce->status = MK_OUT_OF_MEMORY; return (ce->status); } /* init */ XP_MEMSET(cd, 0, sizeof(MailboxConData)); cd->msgnum = -1; wholeUrl = XP_STRDUP(ce->URL_s->address); #ifndef XP_MAC /* #### Fix Mac Pathname */ NET_UnEscape (path); NET_UnEscape (wholeUrl); #endif /* !XP_MAC */ cd->pane = ce->URL_s->msg_pane; if (!cd->pane) { #ifdef DEBUG_phil XP_Trace ("NET_MailboxLoad: url->msg_pane NULL for URL: %s\n", ce->URL_s->address); #endif /* If we're displaying a message, there'll be a '?' in the url */ if (XP_STRCHR(wholeUrl, '?')) { if (XP_STRSTR(wholeUrl, "?compress-folder") || XP_STRSTR(wholeUrl, "?deliver-queued")) cd->pane = MSG_FindPane(ce->window_id, MSG_FOLDERPANE); /* ###phil tar to the tarpit */ else { /* find a pane, just to get back to the MSG_Master */ MSG_Pane *someRandomPane = MSG_FindPane (ce->window_id, MSG_ANYPANE); if (someRandomPane) { cd->pane = MSG_FindPaneFromUrl(someRandomPane, wholeUrl, MSG_MESSAGEPANE); /* ** jrm and dmb, 97/02/06: temporary fix, because we MUST have a thread pane ** in order for certain operations to succeed. The macintosh UI can ** forward from the thread pane, with no message pane available, and this ** routine was setting cd->pane to a folderpane, which is a kind of ** pane that really doesn't work. The permanent fix will be to change the ** behavior of MSG_FindPane. */ if (!cd->pane) cd->pane = MSG_FindPaneFromUrl(someRandomPane, wholeUrl, MSG_THREADPANE); } } } else cd->pane = MSG_FindPane(ce->window_id, MSG_FOLDERPANE); if (cd->pane == NULL) { /* find a pane, just to get back to the MSG_Master */ MSG_Pane *someRandomPane = MSG_FindPane (ce->window_id, MSG_ANYPANE); if (someRandomPane) cd->pane = MSG_FindPaneFromUrl (someRandomPane, wholeUrl, MSG_MESSAGEPANE); } /* ###dmb so there! This whole FindPane stuff is too adhoc. */ if (cd->pane == NULL) cd->pane = MSG_FindPane(ce->window_id, MSG_FOLDERPANE); /* km! I agree! */ if (cd->pane == NULL) cd->pane = MSG_FindPane(ce->window_id, MSG_THREADPANE); /* ###whs this isn't really true the way things are set up. */ /* XP_ASSERT(cd->pane && MSG_GetContext(cd->pane) == ce->window_id); */ } if (cd->pane == NULL) { FREEIF(wholeUrl); return -1; /* ### */ } if (XP_STRCASECMP(wholeUrl, "mailbox:copymessages") == 0) cd->next_state = MAILBOX_COPY_MESSAGES; else { cd->folder_name = path; cd->next_state = MAILBOX_OPEN_FOLDER; } if (part && *part == '?') part++; while (part) { char* amp = XP_STRCHR(part, '&'); if (amp) *amp++ = '\0'; if (XP_STRNCMP(part, "id=", 3) == 0) { cd->msg_id = XP_STRDUP (NET_UnEscape (part+3)); } else if (XP_STRNCMP(part, "number=", 7) == 0) { cd->msgnum = atol(part + 7); if (cd->msgnum == 0 && part[7] != '0') cd->msgnum = -1; } else if (XP_STRNCMP(part, "uidl=", 5) == 0) { /* ### Vile hack time. If a UIDL was specified, then tell libmsg about it, giving it a chance to arrange so that when this URL is all done, MSG_GetNewMail gets called. */ MSG_PrepareToIncUIDL(cd->pane, ce->URL_s, NET_UnEscape(part + 5)); } else if (ce->URL_s->internal_url && XP_STRNCMP(part, "compress-folder", 15) == 0) { cd->next_state = MAILBOX_COMPRESS_FOLDER; } else if (ce->URL_s->internal_url && XP_STRNCMP(part, "deliver-queued", 14) == 0) { cd->next_state = MAILBOX_DELIVER_QUEUED; } else if (ce->URL_s->internal_url && XP_STRNCMP(part, "background", 10) == 0) { cd->next_state = MAILBOX_BACKGROUND; } else if (ce->URL_s->internal_url && XP_STRNCMP(part, "null", 10) == 0) { cd->next_state = MAILBOX_NULL; } part = amp; } FREEIF(search); FREEIF(wholeUrl); cd->initial_state = cd->next_state; /* don't cache mailbox url's */ ce->format_out = CLEAR_CACHE_BIT(ce->format_out); ce->local_file = TRUE; ce->socket = NULL; NET_SetCallNetlibAllTheTime(ce->window_id, "mkmailbx"); return(net_ProcessMailbox(ce)); } /* This doesn't actually generate HTML - but it is our hook into the message display code, so that we can get some values out of it after the headers-to-be-displayed have been parsed. */ static char * mail_generate_html_header_fn (const char *dest, void *closure, MimeHeaders *headers) { ActiveEntry *ce = (ActiveEntry *) closure; MailboxConData * cd = (MailboxConData *)ce->con_data; MSG_ActivateReplyOptions (cd->pane, headers); return 0; } static char * mail_generate_html_footer_fn (const char *dest, void *closure, MimeHeaders *headers) { ActiveEntry *cur_entry = (ActiveEntry *) closure; MailboxConData * cd = (MailboxConData *)cur_entry->con_data; char *uidl = (headers ? MimeHeaders_get(headers, HEADER_X_UIDL, FALSE, FALSE) : 0); if (uidl) { XP_FREE(uidl); return MSG_GeneratePartialMessageBlurb (cd->pane, cur_entry->URL_s, closure, headers); } return 0; } static char * mail_generate_reference_url_fn (const char *dest, void *closure, MimeHeaders *headers) { ActiveEntry *cur_entry = (ActiveEntry *) closure; char *addr = cur_entry->URL_s->address; char *search = (addr ? XP_STRCHR (addr, '?') : 0); char *id2; char *new_dest; char *result; if (!dest || !*dest) return 0; id2 = XP_STRDUP (dest); if (!id2) return 0; if (id2[XP_STRLEN (id2)-1] == '>') id2[XP_STRLEN (id2)-1] = 0; if (id2[0] == '<') new_dest = NET_Escape (id2+1, URL_PATH); else new_dest = NET_Escape (id2, URL_PATH); FREEIF (id2); result = (char *) XP_ALLOC ((search ? search - addr : 0) + (new_dest ? XP_STRLEN (new_dest) : 0) + 40); if (result && new_dest) { if (search) { XP_MEMCPY (result, addr, search - addr); result[search - addr] = 0; } else if (addr) XP_STRCPY (result, addr); else *result = 0; XP_STRCAT (result, "?id="); XP_STRCAT (result, new_dest); if (search && XP_STRSTR (search, "&headers=all")) XP_STRCAT (result, "&headers=all"); } FREEIF (new_dest); return result; } static int net_make_mail_msg_stream (ActiveEntry *ce) { MailboxConData * cd = (MailboxConData *)ce->con_data; StrAllocCopy(ce->URL_s->content_type, MESSAGE_RFC822); if (ce->format_out == FO_PRESENT || ce->format_out == FO_CACHE_AND_PRESENT) { MimeDisplayOptions *opt = XP_NEW (MimeDisplayOptions); if (!opt) return MK_OUT_OF_MEMORY; XP_MEMSET (opt, 0, sizeof(*opt)); opt->generate_reference_url_fn = mail_generate_reference_url_fn; opt->generate_header_html_fn = 0; opt->generate_post_header_html_fn = mail_generate_html_header_fn; opt->generate_footer_html_fn = mail_generate_html_footer_fn; opt->html_closure = ce; ce->URL_s->fe_data = opt; } cd->stream = NET_StreamBuilder(ce->format_out, ce->URL_s, ce->window_id); if (!cd->stream) return MK_UNABLE_TO_CONVERT; else return 0; } /* * returns negative if the transfer is finished or error'd out * * returns zero or more if the transfer needs to be continued. */ PRIVATE int32 net_ProcessMailbox (ActiveEntry *ce) { MailboxConData * cd = (MailboxConData *)ce->con_data; /* temp, until imap urls have their own identifier */ if ((!XP_STRNCASECMP(ce->URL_s->address, "IMAP://", 7) ) || (!XP_STRNCASECMP(ce->URL_s->address, "view-source:IMAP://",19))) return NET_ProcessIMAP4(ce); cd->pause_for_read = FALSE; /* already paused; reset */ while(!cd->pause_for_read) { #ifdef DEBUG_username XP_Trace("NET_ProcessMailbox: at top of loop, state %d, status %d", cd->next_state, ce->status); #endif switch(cd->next_state) { case MAILBOX_OPEN_FOLDER: if (!ce->URL_s->load_background) { char *fmt = XP_GetString( XP_MAIL_READING_FOLDER ); char *folder = cd->folder_name; char *s = XP_STRRCHR (folder, '/'); if (s) folder = s+1; s = (char *) XP_ALLOC(XP_STRLEN(fmt) + XP_STRLEN(folder) + 20); if (s) { XP_SPRINTF (s, fmt, folder); NET_Progress(ce->window_id, s); XP_FREE(s); } } ce->status = MSG_BeginOpenFolderSock(cd->pane, cd->folder_name, cd->msg_id, cd->msgnum, &cd->folder_ptr); if(ce->status == MK_CONNECTED) { #ifdef DEBUG_username XP_Trace ("NET_ProcessMailBox: next state is MAILBOX_OPEN_MESSAGE"); #endif cd->next_state = MAILBOX_OPEN_MESSAGE; } else if(ce->status > -1) { #ifdef DEBUG_username XP_Trace ("NET_ProcessMailBox: next state is MAILBOX_FINISH_OPEN_FOLDER"); #endif cd->pause_for_read = TRUE; cd->next_state = MAILBOX_FINISH_OPEN_FOLDER; } #ifdef DEBUG_username XP_Trace ("NET_ProcessMailBox: MAILBOX_OPEN_FOLDER got error %d", ce->status); #endif break; case MAILBOX_FINISH_OPEN_FOLDER: ce->status = MSG_FinishOpenFolderSock(cd->pane, cd->folder_name, cd->msg_id, cd->msgnum, &cd->folder_ptr); if(ce->status == MK_CONNECTED) { cd->next_state = MAILBOX_OPEN_MESSAGE; } else { cd->pause_for_read = TRUE; } break; case MAILBOX_OPEN_MESSAGE: if(cd->msg_id == NULL && cd->msgnum < 0) { /* only open the message if we are actuall * asking for a message */ cd->next_state = MAILBOX_DONE; NET_Progress(ce->window_id, XP_GetString( XP_MAIL_READING_FOLDER_DONE ) ); } else { if (!ce->URL_s->load_background) NET_Progress(ce->window_id, XP_GetString( XP_MAIL_READING_MESSAGE ) ); ce->status = MSG_OpenMessageSock(cd->pane, cd->folder_name, cd->msg_id, cd->msgnum, cd->folder_ptr, &cd->msg_ptr, &ce->URL_s->content_length); cd->next_state = MAILBOX_OPEN_STREAM; } break; case MAILBOX_OPEN_STREAM: { ce->status = net_make_mail_msg_stream (ce); if (ce->status < 0) { ce->URL_s->error_msg = NET_ExplainErrorDetails(ce->status); return(ce->status); } else { XP_ASSERT (cd->stream); cd->next_state = MAILBOX_READ_MESSAGE; } if (!ce->URL_s->load_background) { FE_GraphProgressInit(ce->window_id, ce->URL_s, ce->URL_s->content_length); cd->destroy_graph_progress = TRUE; } cd->original_content_length = ce->URL_s->content_length; } break; case MAILBOX_READ_MESSAGE: { int32 read_size; cd->pause_for_read = TRUE; read_size = (*cd->stream->is_write_ready) (cd->stream); if (cd->input_buffer == NULL) { cd->input_buffer_size = 10240; #ifdef DEBUG_ricardob cd->input_buffer_size *= 2; #endif while (cd->input_buffer == NULL) { cd->input_buffer = (char*) XP_ALLOC(cd->input_buffer_size); if (!cd->input_buffer) { cd->input_buffer_size /= 2; if (cd->input_buffer_size < 512) { ce->status = MK_OUT_OF_MEMORY; break; } } } if (cd->input_buffer == NULL) break; } if(!read_size) { return(0); /* wait until we are ready to write */ } else { read_size = MIN(read_size, cd->input_buffer_size); } ce->status = MSG_ReadMessageSock(cd->pane, cd->folder_name, cd->msg_ptr, cd->msg_id, cd->msgnum, cd->input_buffer, read_size); if(ce->status > 0) { ce->bytes_received += ce->status; if (!ce->URL_s->load_background) FE_GraphProgress(ce->window_id, ce->URL_s, ce->bytes_received, ce->status, ce->URL_s->content_length); ce->status = PUT_STREAM(cd->input_buffer, ce->status); } else if(ce->status == 0) cd->next_state = MAILBOX_DONE; } break; case MAILBOX_COMPRESS_FOLDER: if ((cd->initial_state == MAILBOX_COMPRESS_FOLDER) && (!ce->URL_s->load_background)) { char *fmt= XP_GetString( XP_COMPRESSING_FOLDER ); char *folder = cd->folder_name; char *s = XP_STRRCHR (folder, '/'); if (s) folder = s+1; s = (char *)XP_ALLOC (XP_STRLEN(fmt) + XP_STRLEN(folder) + 20); if (s) { XP_SPRINTF (s, fmt, folder); NET_Progress(ce->window_id, s); XP_FREE(s); } } ce->status = MSG_BeginCompressFolder(cd->pane, ce->URL_s, cd->folder_name, &cd->compress_folder_ptr); if (ce->status == MK_CONNECTED) { cd->next_state = MAILBOX_DONE; } else { cd->pause_for_read = TRUE; cd->next_state = MAILBOX_FINISH_COMPRESS_FOLDER; } break; case MAILBOX_FINISH_COMPRESS_FOLDER: ce->status = MSG_FinishCompressFolder(cd->pane, ce->URL_s, cd->folder_name, cd->compress_folder_ptr); if (ce->status == MK_CONNECTED) { cd->next_state = MAILBOX_DONE; } else { cd->pause_for_read = TRUE; } break; case MAILBOX_BACKGROUND: ce->status = MSG_ProcessBackground(ce->URL_s); if (ce->status == MK_CONNECTED) { cd->next_state = MAILBOX_DONE; } else { cd->pause_for_read = TRUE; } break; case MAILBOX_NULL: ce->status = MK_WAITING_FOR_CONNECTION; cd->next_state = MAILBOX_NULL2; cd->pause_for_read = TRUE; break; case MAILBOX_NULL2: ce->status = MK_CONNECTED; cd->next_state = MAILBOX_DONE; break; case MAILBOX_DELIVER_QUEUED: if (!ce->URL_s->load_background) NET_Progress(ce->window_id, XP_GetString( XP_MAIL_DELIVERING_QUEUED_MESSAGES ) ); ce->status = MSG_BeginDeliverQueued(cd->pane, ce->URL_s, &cd->deliver_queued_ptr); if (ce->status == MK_CONNECTED) { cd->next_state = MAILBOX_DONE; } else { cd->pause_for_read = TRUE; cd->next_state = MAILBOX_FINISH_DELIVER_QUEUED; } break; case MAILBOX_FINISH_DELIVER_QUEUED: ce->status = MSG_FinishDeliverQueued(cd->pane, ce->URL_s, cd->deliver_queued_ptr); if (ce->status == MK_CONNECTED) { cd->next_state = MAILBOX_DONE; } else { cd->pause_for_read = TRUE; } break; case MAILBOX_COPY_MESSAGES: ce->status = MSG_BeginCopyingMessages(ce->window_id); if (ce->status == MK_CONNECTED) cd->next_state = MAILBOX_DONE; else { cd->pause_for_read = TRUE; cd->next_state = MAILBOX_FINISH_COPY_MESSAGES; } break; case MAILBOX_FINISH_COPY_MESSAGES: ce->status = MSG_FinishCopyingMessages(ce->window_id); if (ce->status == MK_CONNECTED) cd->next_state = MAILBOX_DONE; else cd->pause_for_read = TRUE; break; case MAILBOX_DONE: if(cd->stream) { COMPLETE_STREAM; FREE(cd->stream); } cd->next_state = MAILBOX_FREE; break; case MAILBOX_ERROR_DONE: if(cd->stream) { ABORT_STREAM(ce->status); FREE(cd->stream); } cd->next_state = MAILBOX_FREE; if (ce->status < -1 && !ce->URL_s->error_msg) ce->URL_s->error_msg = NET_ExplainErrorDetails(ce->status); break; case MAILBOX_FREE: NET_ClearCallNetlibAllTheTime(ce->window_id, "mkmailbx"); if (cd->input_buffer) { XP_FREE(cd->input_buffer); cd->input_buffer = NULL; } if(cd->destroy_graph_progress) FE_GraphProgressDestroy(ce->window_id, ce->URL_s, cd->original_content_length, ce->bytes_received); if(cd->msg_ptr) { MSG_CloseMessageSock(cd->pane, cd->folder_name, cd->msg_id, cd->msgnum, cd->msg_ptr); cd->msg_ptr = NULL; if (!ce->URL_s->load_background) NET_Progress(ce->window_id, XP_GetString( XP_READING_MESSAGE_DONE ) ); } if(cd->folder_ptr) { MSG_CloseFolderSock(cd->pane, cd->folder_name, cd->msg_id, cd->msgnum, cd->folder_ptr); if ((cd->msg_id == NULL && cd->msgnum < 0) && (!ce->URL_s->load_background)) /* If we read a message, don't hide the previous message with this one. */ NET_Progress(ce->window_id, XP_GetString( XP_MAIL_READING_FOLDER_DONE ) ); } if(cd->compress_folder_ptr) { MSG_CloseCompressFolderSock(cd->pane, ce->URL_s, cd->compress_folder_ptr); cd->compress_folder_ptr = NULL; if ((cd->initial_state == MAILBOX_COMPRESS_FOLDER) && (!ce->URL_s->load_background)) NET_Progress(ce->window_id, XP_GetString( XP_MAIL_COMPRESSING_FOLDER_DONE ) ); } if(cd->deliver_queued_ptr) { MSG_CloseDeliverQueuedSock(cd->pane, ce->URL_s, cd->deliver_queued_ptr); cd->deliver_queued_ptr = NULL; if (!ce->URL_s->load_background) NET_Progress(ce->window_id, XP_GetString( XP_MAIL_DELIVERING_QUEUED_MESSAGES_DONE ) ); } FREEIF(cd->folder_name); FREEIF(cd->msg_id); FREE(cd); return(-1); /* final end */ default: /* should never happen !!! */ TRACEMSG(("MAILBOX: BAD STATE!")); XP_ASSERT(0); cd->next_state = MAILBOX_ERROR_DONE; break; } /* check for errors during load and call error * state if found */ if(ce->status < 0 && cd->next_state != MAILBOX_FREE) { cd->next_state = MAILBOX_ERROR_DONE; /* don't exit! loop around again and do the free case */ cd->pause_for_read = FALSE; } } /* while(!cd->pause_for_read) */ #ifdef DEBUG_username XP_Trace ("Leaving NET_ProcessMailbox with status %d", ce->status); #endif return(ce->status); } /* abort the connection in progress */ PRIVATE int32 net_InterruptMailbox(ActiveEntry * ce) { MailboxConData * cd = (MailboxConData *)ce->con_data; /* temp until imap urls have their own identifier */ if (!XP_STRNCASECMP(ce->URL_s->address, "IMAP://", 7) ) return NET_InterruptIMAP4(ce); cd->next_state = MAILBOX_ERROR_DONE; ce->status = MK_INTERRUPTED; return(net_ProcessMailbox(ce)); } /* Free any memory that might be used in caching etc. */ PRIVATE void net_CleanupMailbox(void) { /* nothing so far needs freeing */ return; } MODULE_PRIVATE void NET_InitMailboxProtocol(void) { static NET_ProtoImpl mailbox_proto_impl; mailbox_proto_impl.init = net_MailboxLoad; mailbox_proto_impl.process = net_ProcessMailbox; mailbox_proto_impl.interrupt = net_InterruptMailbox; mailbox_proto_impl.cleanup = net_CleanupMailbox; NET_RegisterProtocolImplementation(&mailbox_proto_impl, MAILBOX_TYPE_URL); } /* Since each search may be composed of multiple distinct URLs to * process, use a "search:" URL as a meta-URL which schedules the * subparts for processing */ PRIVATE int32 net_ProcessMsgSearch (ActiveEntry *ce) { /* MailboxConData *cd = (MailboxConData *) ce->con_data;*/ int retVal = MSG_ProcessSearch (ce->window_id); ce->status = 0; if (0 != retVal) { /* stop this crazy thing */ NET_ClearCallNetlibAllTheTime(ce->window_id, "mkmailbx"); } return retVal; } PRIVATE int32 net_MsgSearchLoad (ActiveEntry *ce) { /* don't cache search urls */ ce->format_out = CLEAR_CACHE_BIT(ce->format_out); ce->local_file = TRUE; ce->socket = NULL; NET_SetCallNetlibAllTheTime(ce->window_id, "mkmailbx"); return 0; } PRIVATE int32 net_InterruptMsgSearch (ActiveEntry *ce) { return MSG_InterruptSearch (ce->window_id); } /* Free any memory that might be used in caching etc. */ PRIVATE void net_CleanupMsgSearch(void) { /* nothing so far needs freeing */ return; } MODULE_PRIVATE void NET_InitMsgSearchProtocol(void) { static NET_ProtoImpl msgsearch_proto_impl; msgsearch_proto_impl.init = net_MsgSearchLoad; msgsearch_proto_impl.process = net_ProcessMsgSearch; msgsearch_proto_impl.interrupt = net_InterruptMsgSearch; msgsearch_proto_impl.cleanup = net_CleanupMsgSearch; NET_RegisterProtocolImplementation(&msgsearch_proto_impl, MSG_SEARCH_TYPE_URL); }