From bca6b43b4935d723da3f6c89daf94b941bd6d8ff Mon Sep 17 00:00:00 2001 From: Art Cancro Date: Sun, 28 Jul 2002 20:33:13 +0000 Subject: [PATCH] * Augmented the "headers only" functionality of the message reading API (as well as the options of the server commands which expose it) to allow headers+body, headers only, or body only. * Adjusted message output of IMAP command FETCH BODY[1] when message is in legacy Citadel format. This fixes a bug exposed by SquirrelMail. --- citadel/ChangeLog | 8 +++++++- citadel/imap_fetch.c | 17 +++++++++++++---- citadel/msgbase.c | 11 +++++++---- citadel/msgbase.h | 8 +++++++- citadel/serv_pop3.c | 2 +- citadel/serv_smtp.c | 2 +- citadel/serv_spam.c | 2 +- citadel/techdoc/session.txt | 15 ++++++--------- 8 files changed, 43 insertions(+), 22 deletions(-) diff --git a/citadel/ChangeLog b/citadel/ChangeLog index c7c2c9ae0..9b625a96c 100644 --- a/citadel/ChangeLog +++ b/citadel/ChangeLog @@ -1,4 +1,11 @@ $Log$ + Revision 591.74 2002/07/28 20:33:13 ajc + * Augmented the "headers only" functionality of the message reading API (as + well as the options of the server commands which expose it) to allow + headers+body, headers only, or body only. + * Adjusted message output of IMAP command FETCH BODY[1] when message is in + legacy Citadel format. This fixes a bug exposed by SquirrelMail. + Revision 591.73 2002/07/23 04:00:06 ajc * Completed the MSGP and MSG4 commands to set the client's preferred MIME content types, and fetch messages with MIME content types. @@ -3835,4 +3842,3 @@ Sat Jul 11 00:20:48 EDT 1998 Nathan Bryant Fri Jul 10 1998 Art Cancro * Initial CVS import - diff --git a/citadel/imap_fetch.c b/citadel/imap_fetch.c index e4697c583..c1751fa05 100644 --- a/citadel/imap_fetch.c +++ b/citadel/imap_fetch.c @@ -119,7 +119,7 @@ void imap_fetch_rfc822(int msgnum, char *whichfmt, struct CtdlMessage *msg) { * Load the message into a temp file for translation and measurement */ CtdlRedirectOutput(tmp, -1); - CtdlOutputPreLoadedMsg(msg, msgnum, MT_RFC822, 0, 0, 1); + CtdlOutputPreLoadedMsg(msg, msgnum, MT_RFC822, HEADERS_ALL, 0, 1); CtdlRedirectOutput(NULL, -1); if (!is_valid_message(msg)) { lprintf(1, "WARNING: output clobbered the message!\n"); @@ -462,9 +462,17 @@ void imap_fetch_body(long msgnum, char *item, int is_peek, /* Now figure out what the client wants, and get it */ - if (!strcmp(section, "")) { /* the whole thing */ + if ( (!strcmp(section, "1")) && (msg->cm_format_type != 4) ) { CtdlRedirectOutput(tmp, -1); - CtdlOutputPreLoadedMsg(msg, msgnum, MT_RFC822, 0, 0, 1); + CtdlOutputPreLoadedMsg(msg, msgnum, MT_RFC822, + HEADERS_NONE, 0, 1); + CtdlRedirectOutput(NULL, -1); + } + + else if (!strcmp(section, "")) { + CtdlRedirectOutput(tmp, -1); + CtdlOutputPreLoadedMsg(msg, msgnum, MT_RFC822, + HEADERS_ALL, 0, 1); CtdlRedirectOutput(NULL, -1); } @@ -474,7 +482,8 @@ void imap_fetch_body(long msgnum, char *item, int is_peek, */ else if (!strncasecmp(section, "HEADER", 6)) { CtdlRedirectOutput(tmp, -1); - CtdlOutputPreLoadedMsg(msg, msgnum, MT_RFC822, 1, 0, 1); + CtdlOutputPreLoadedMsg(msg, msgnum, MT_RFC822, + HEADERS_ONLY, 0, 1); CtdlRedirectOutput(NULL, -1); imap_strip_headers(tmp, section); } diff --git a/citadel/msgbase.c b/citadel/msgbase.c index 34027331d..b8498a536 100644 --- a/citadel/msgbase.c +++ b/citadel/msgbase.c @@ -1156,6 +1156,9 @@ int CtdlOutputPreLoadedMsg(struct CtdlMessage *TheMessage, return((CC->download_fp != NULL) ? om_ok : om_mime_error); } + /* Does the caller want to skip the headers? */ + if (headers_only == HEADERS_NONE) goto START_TEXT; + /* now for the user-mode message reading loops */ if (do_proto) cprintf("%d Message %ld:\n", LISTING_FOLLOWS, msg_num); @@ -1317,7 +1320,7 @@ int CtdlOutputPreLoadedMsg(struct CtdlMessage *TheMessage, } /* end header processing loop ... at this point, we're in the text */ - +START_TEXT: mptr = TheMessage->cm_fields['M']; /* Tell the client about the MIME parts in this message */ @@ -1345,7 +1348,7 @@ int CtdlOutputPreLoadedMsg(struct CtdlMessage *TheMessage, } } - if (headers_only) { + if (headers_only == HEADERS_ONLY) { if (do_proto) cprintf("000\n"); return(om_ok); } @@ -1436,7 +1439,7 @@ int CtdlOutputPreLoadedMsg(struct CtdlMessage *TheMessage, void cmd_msg0(char *cmdbuf) { long msgid; - int headers_only = 0; + int headers_only = HEADERS_ALL; msgid = extract_long(cmdbuf, 0); headers_only = extract_int(cmdbuf, 1); @@ -1452,7 +1455,7 @@ void cmd_msg0(char *cmdbuf) void cmd_msg2(char *cmdbuf) { long msgid; - int headers_only = 0; + int headers_only = HEADERS_ALL; msgid = extract_long(cmdbuf, 0); headers_only = extract_int(cmdbuf, 1); diff --git a/citadel/msgbase.h b/citadel/msgbase.h index b746ab133..aa1e0f87d 100644 --- a/citadel/msgbase.h +++ b/citadel/msgbase.h @@ -28,7 +28,13 @@ enum { om_no_such_msg, om_mime_error }; - + +/* + * Values of "headers_only" when calling message output routines + */ +#define HEADERS_ALL 0 /* Headers and body */ +#define HEADERS_ONLY 1 /* Headers only */ +#define HEADERS_NONE 2 /* Body only */ struct ma_info { diff --git a/citadel/serv_pop3.c b/citadel/serv_pop3.c index 093764746..68e60d95d 100644 --- a/citadel/serv_pop3.c +++ b/citadel/serv_pop3.c @@ -144,7 +144,7 @@ void pop3_add_message(long msgnum, void *userdata) { POP3->msgs[POP3->num_msgs-1].temp = fp; CtdlRedirectOutput(fp, -1); - CtdlOutputMsg(msgnum, MT_RFC822, 0, 0, 1); + CtdlOutputMsg(msgnum, MT_RFC822, HEADERS_ALL, 0, 1); CtdlRedirectOutput(NULL, -1); POP3->msgs[POP3->num_msgs-1].rfc822_length = ftell(fp); diff --git a/citadel/serv_smtp.c b/citadel/serv_smtp.c index 2602c083d..953f0b0de 100644 --- a/citadel/serv_smtp.c +++ b/citadel/serv_smtp.c @@ -671,7 +671,7 @@ void smtp_try(const char *key, const char *addr, int *status, } else { CtdlRedirectOutput(msg_fp, -1); - CtdlOutputMsg(msgnum, MT_RFC822, 0, 0, 1); + CtdlOutputMsg(msgnum, MT_RFC822, HEADERS_ALL, 0, 1); CtdlRedirectOutput(NULL, -1); fseek(msg_fp, 0L, SEEK_END); msg_size = ftell(msg_fp); diff --git a/citadel/serv_spam.c b/citadel/serv_spam.c index 2e362ba7f..ff548b2cc 100644 --- a/citadel/serv_spam.c +++ b/citadel/serv_spam.c @@ -138,7 +138,7 @@ int spam_assassin(struct CtdlMessage *msg) { /* Message */ CtdlRedirectOutput(NULL, sock); - CtdlOutputPreLoadedMsg(msg, 0L, MT_RFC822, 0, 0, 1); + CtdlOutputPreLoadedMsg(msg, 0L, MT_RFC822, HEADERS_ALL, 0, 1); CtdlRedirectOutput(NULL, -1); /* Close one end of the socket connection; this tells SpamAssassin diff --git a/citadel/techdoc/session.txt b/citadel/techdoc/session.txt index 2a559f563..ad0629daa 100644 --- a/citadel/techdoc/session.txt +++ b/citadel/techdoc/session.txt @@ -483,15 +483,12 @@ criteria. These criteria are applied with an AND logic. This is a command used to read the text of a message. "Mode 0" implies that other MSG commands (MSG1, MSG2, etc.) will probably be added later on to read messages in more robust formats. This command should be passed two arguments. -The first is the message number of the message being requested. In server -version 4.04 and above, the second argument may be set to either 0 to read the -entire message, or 1 to read the headers only. - - The server should, of course, make sure that the client actually has access -to the message being requested before honoring this request. Citadel/UX does -so by checking the message number against the contents of the current room. If -it's not there, the request is denied. - +The first is the message number of the message being requested. The second +argument specifies whether the client wants headers and/or message body: + 0 = Headers and body + 1 = Headers only + 2 = Body only + If the request is denied, an ERROR code will be returned. Otherwise, the LISTING_FOLLOWS code will be returned, followed by the contents of the message. The following fields may be sent: -- 2.39.2