1998-05-01 00:53:59 +04:00
|
|
|
/* -*- 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"
|
|
|
|
|
|
|
|
|
|
|
|
/* 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_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 */
|
1998-05-19 04:54:09 +04:00
|
|
|
if (!PL_strncasecmp(ce->URL_s->address, "mailbox://", 10) )
|
1998-05-01 00:53:59 +04:00
|
|
|
return NET_IMAP4Load(ce);
|
|
|
|
|
1998-05-19 04:54:09 +04:00
|
|
|
if (PL_strcasecmp(ce->URL_s->address, "mailbox:displayattachments") == 0) {
|
1998-05-01 00:53:59 +04:00
|
|
|
MIME_DisplayAttachmentPane(ce->window_id);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1998-05-19 04:54:09 +04:00
|
|
|
cd = PR_NEW(MailboxConData);
|
1998-05-01 00:53:59 +04:00
|
|
|
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 */
|
1998-05-19 04:54:09 +04:00
|
|
|
memset(cd, 0, sizeof(MailboxConData));
|
1998-05-01 00:53:59 +04:00
|
|
|
cd->msgnum = -1;
|
|
|
|
|
1998-05-19 04:54:09 +04:00
|
|
|
wholeUrl = PL_strdup(ce->URL_s->address);
|
1998-05-01 00:53:59 +04:00
|
|
|
|
|
|
|
#ifndef XP_MAC /* #### Giant Evil Mac Pathname Hack */
|
|
|
|
NET_UnEscape (path);
|
|
|
|
NET_UnEscape (wholeUrl);
|
|
|
|
#endif /* !XP_MAC */
|
|
|
|
|
|
|
|
cd->pane = ce->URL_s->msg_pane;
|
|
|
|
if (!cd->pane)
|
|
|
|
{
|
|
|
|
#ifdef DEBUG_phil
|
1998-05-19 04:54:09 +04:00
|
|
|
PR_LogPrint ("NET_MailboxLoad: url->msg_pane NULL for URL: %s\n", ce->URL_s->address);
|
1998-05-01 00:53:59 +04:00
|
|
|
#endif
|
|
|
|
/* If we're displaying a message, there'll be a '?' in the url */
|
1998-05-19 04:54:09 +04:00
|
|
|
if (PL_strchr(wholeUrl, '?'))
|
1998-05-01 00:53:59 +04:00
|
|
|
{
|
1998-05-19 04:54:09 +04:00
|
|
|
if (PL_strstr(wholeUrl, "?compress-folder") || PL_strstr(wholeUrl, "?deliver-queued"))
|
1998-05-01 00:53:59 +04:00
|
|
|
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. */
|
1998-05-19 04:54:09 +04:00
|
|
|
/* PR_ASSERT(cd->pane && MSG_GetContext(cd->pane) == ce->window_id); */
|
1998-05-01 00:53:59 +04:00
|
|
|
}
|
|
|
|
if (cd->pane == NULL)
|
|
|
|
{
|
|
|
|
FREEIF(wholeUrl);
|
|
|
|
return -1; /* ### */
|
|
|
|
}
|
|
|
|
|
1998-05-19 04:54:09 +04:00
|
|
|
if (PL_strcasecmp(wholeUrl, "mailbox:copymessages") == 0)
|
1998-05-01 00:53:59 +04:00
|
|
|
cd->next_state = MAILBOX_COPY_MESSAGES;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
cd->folder_name = path;
|
|
|
|
cd->next_state = MAILBOX_OPEN_FOLDER;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (part && *part == '?') part++;
|
|
|
|
while (part) {
|
1998-05-19 04:54:09 +04:00
|
|
|
char* amp = PL_strchr(part, '&');
|
1998-05-01 00:53:59 +04:00
|
|
|
if (amp) *amp++ = '\0';
|
1998-05-19 04:54:09 +04:00
|
|
|
if (PL_strncmp(part, "id=", 3) == 0) {
|
|
|
|
cd->msg_id = PL_strdup (NET_UnEscape (part+3));
|
|
|
|
} else if (PL_strncmp(part, "number=", 7) == 0) {
|
1998-05-01 00:53:59 +04:00
|
|
|
cd->msgnum = atol(part + 7);
|
|
|
|
if (cd->msgnum == 0 && part[7] != '0') cd->msgnum = -1;
|
1998-05-19 04:54:09 +04:00
|
|
|
} else if (PL_strncmp(part, "uidl=", 5) == 0) {
|
1998-05-01 00:53:59 +04:00
|
|
|
/* ### 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 &&
|
1998-05-19 04:54:09 +04:00
|
|
|
PL_strncmp(part, "compress-folder", 15) == 0) {
|
1998-05-01 00:53:59 +04:00
|
|
|
cd->next_state = MAILBOX_COMPRESS_FOLDER;
|
|
|
|
} else if (ce->URL_s->internal_url &&
|
1998-05-19 04:54:09 +04:00
|
|
|
PL_strncmp(part, "deliver-queued", 14) == 0) {
|
1998-05-01 00:53:59 +04:00
|
|
|
cd->next_state = MAILBOX_DELIVER_QUEUED;
|
|
|
|
} else if (ce->URL_s->internal_url &&
|
1998-05-19 04:54:09 +04:00
|
|
|
PL_strncmp(part, "background", 10) == 0) {
|
1998-05-01 00:53:59 +04:00
|
|
|
cd->next_state = MAILBOX_BACKGROUND;
|
|
|
|
}
|
|
|
|
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)
|
|
|
|
{
|
1998-05-19 04:54:09 +04:00
|
|
|
PR_Free(uidl);
|
1998-05-01 00:53:59 +04:00
|
|
|
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;
|
1998-05-19 04:54:09 +04:00
|
|
|
char *search = (addr ? PL_strchr (addr, '?') : 0);
|
1998-05-01 00:53:59 +04:00
|
|
|
char *id2;
|
|
|
|
char *new_dest;
|
|
|
|
char *result;
|
|
|
|
|
|
|
|
if (!dest || !*dest) return 0;
|
1998-05-19 04:54:09 +04:00
|
|
|
id2 = PL_strdup (dest);
|
1998-05-01 00:53:59 +04:00
|
|
|
if (!id2) return 0;
|
1998-05-19 04:54:09 +04:00
|
|
|
if (id2[PL_strlen (id2)-1] == '>')
|
|
|
|
id2[PL_strlen (id2)-1] = 0;
|
1998-05-01 00:53:59 +04:00
|
|
|
if (id2[0] == '<')
|
|
|
|
new_dest = NET_Escape (id2+1, URL_PATH);
|
|
|
|
else
|
|
|
|
new_dest = NET_Escape (id2, URL_PATH);
|
|
|
|
|
|
|
|
FREEIF (id2);
|
1998-05-19 04:54:09 +04:00
|
|
|
result = (char *) PR_Malloc ((search ? search - addr : 0) +
|
|
|
|
(new_dest ? PL_strlen (new_dest) : 0) +
|
1998-05-01 00:53:59 +04:00
|
|
|
40);
|
|
|
|
if (result && new_dest)
|
|
|
|
{
|
|
|
|
if (search)
|
|
|
|
{
|
1998-05-19 04:54:09 +04:00
|
|
|
memcpy (result, addr, search - addr);
|
1998-05-01 00:53:59 +04:00
|
|
|
result[search - addr] = 0;
|
|
|
|
}
|
|
|
|
else if (addr)
|
1998-05-19 04:54:09 +04:00
|
|
|
PL_strcpy (result, addr);
|
1998-05-01 00:53:59 +04:00
|
|
|
else
|
|
|
|
*result = 0;
|
1998-05-19 04:54:09 +04:00
|
|
|
PL_strcat (result, "?id=");
|
|
|
|
PL_strcat (result, new_dest);
|
1998-05-01 00:53:59 +04:00
|
|
|
|
1998-05-19 04:54:09 +04:00
|
|
|
if (search && PL_strstr (search, "&headers=all"))
|
|
|
|
PL_strcat (result, "&headers=all");
|
1998-05-01 00:53:59 +04:00
|
|
|
}
|
|
|
|
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)
|
|
|
|
{
|
1998-05-19 04:54:09 +04:00
|
|
|
MimeDisplayOptions *opt = PR_NEW (MimeDisplayOptions);
|
1998-05-01 00:53:59 +04:00
|
|
|
if (!opt) return MK_OUT_OF_MEMORY;
|
1998-05-19 04:54:09 +04:00
|
|
|
memset (opt, 0, sizeof(*opt));
|
1998-05-01 00:53:59 +04:00
|
|
|
|
|
|
|
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 */
|
1998-05-19 04:54:09 +04:00
|
|
|
if ((!PL_strncasecmp(ce->URL_s->address, "mailbox://", 10) ) ||
|
|
|
|
(!PL_strncasecmp(ce->URL_s->address, "view-source:mailbox://",22)))
|
1998-05-01 00:53:59 +04:00
|
|
|
return NET_ProcessIMAP4(ce);
|
|
|
|
|
|
|
|
cd->pause_for_read = FALSE; /* already paused; reset */
|
|
|
|
|
|
|
|
while(!cd->pause_for_read)
|
|
|
|
{
|
|
|
|
#ifdef DEBUG_username
|
1998-05-19 04:54:09 +04:00
|
|
|
PR_LogPrint("NET_ProcessMailbox: at top of loop, state %d, status %d", cd->next_state, ce->status);
|
1998-05-01 00:53:59 +04:00
|
|
|
#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;
|
1998-05-19 04:54:09 +04:00
|
|
|
char *s = PL_strrchr (folder, '/');
|
1998-05-01 00:53:59 +04:00
|
|
|
if (s)
|
|
|
|
folder = s+1;
|
1998-05-19 04:54:09 +04:00
|
|
|
s = (char *) PR_Malloc(PL_strlen(fmt) + PL_strlen(folder) + 20);
|
1998-05-01 00:53:59 +04:00
|
|
|
if (s)
|
|
|
|
{
|
1998-05-19 04:54:09 +04:00
|
|
|
sprintf (s, fmt, folder);
|
1998-05-01 00:53:59 +04:00
|
|
|
NET_Progress(ce->window_id, s);
|
1998-05-19 04:54:09 +04:00
|
|
|
PR_Free(s);
|
1998-05-01 00:53:59 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
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
|
1998-05-19 04:54:09 +04:00
|
|
|
PR_LogPrint ("NET_ProcessMailBox: next state is MAILBOX_OPEN_MESSAGE");
|
1998-05-01 00:53:59 +04:00
|
|
|
#endif
|
|
|
|
cd->next_state = MAILBOX_OPEN_MESSAGE;
|
|
|
|
}
|
|
|
|
else if(ce->status > -1)
|
|
|
|
{
|
|
|
|
#ifdef DEBUG_username
|
1998-05-19 04:54:09 +04:00
|
|
|
PR_LogPrint ("NET_ProcessMailBox: next state is MAILBOX_FINISH_OPEN_FOLDER");
|
1998-05-01 00:53:59 +04:00
|
|
|
#endif
|
|
|
|
cd->pause_for_read = TRUE;
|
|
|
|
cd->next_state = MAILBOX_FINISH_OPEN_FOLDER;
|
|
|
|
}
|
|
|
|
#ifdef DEBUG_username
|
1998-05-19 04:54:09 +04:00
|
|
|
PR_LogPrint ("NET_ProcessMailBox: MAILBOX_OPEN_FOLDER got error %d", ce->status);
|
1998-05-01 00:53:59 +04:00
|
|
|
#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;
|
|
|
|
}
|
|
|
|
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
|
|
|
|
{
|
1998-05-19 04:54:09 +04:00
|
|
|
PR_ASSERT (cd->stream);
|
1998-05-01 00:53:59 +04:00
|
|
|
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 =
|
1998-05-19 04:54:09 +04:00
|
|
|
(char*) PR_Malloc(cd->input_buffer_size);
|
1998-05-01 00:53:59 +04:00
|
|
|
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;
|
1998-05-19 04:54:09 +04:00
|
|
|
char *s = PL_strrchr (folder, '/');
|
1998-05-01 00:53:59 +04:00
|
|
|
if (s)
|
|
|
|
folder = s+1;
|
1998-05-19 04:54:09 +04:00
|
|
|
s = (char *)PR_Malloc (PL_strlen(fmt) + PL_strlen(folder) + 20);
|
1998-05-01 00:53:59 +04:00
|
|
|
if (s)
|
|
|
|
{
|
1998-05-19 04:54:09 +04:00
|
|
|
sprintf (s, fmt, folder);
|
1998-05-01 00:53:59 +04:00
|
|
|
NET_Progress(ce->window_id, s);
|
1998-05-19 04:54:09 +04:00
|
|
|
PR_Free(s);
|
1998-05-01 00:53:59 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
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_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) {
|
1998-05-19 04:54:09 +04:00
|
|
|
PR_Free(cd->input_buffer);
|
1998-05-01 00:53:59 +04:00
|
|
|
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!"));
|
1998-05-19 04:54:09 +04:00
|
|
|
PR_ASSERT(0);
|
1998-05-01 00:53:59 +04:00
|
|
|
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
|
1998-05-19 04:54:09 +04:00
|
|
|
PR_LogPrint ("Leaving NET_ProcessMailbox with status %d", ce->status);
|
1998-05-01 00:53:59 +04:00
|
|
|
#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 */
|
1998-05-19 04:54:09 +04:00
|
|
|
if (!PL_strncasecmp(ce->URL_s->address, "mailbox://", 10) )
|
1998-05-01 00:53:59 +04:00
|
|
|
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);
|
|
|
|
}
|