* Augmented the "headers only" functionality of the message reading API (as
authorArt Cancro <ajc@citadel.org>
Sun, 28 Jul 2002 20:33:13 +0000 (20:33 +0000)
committerArt Cancro <ajc@citadel.org>
Sun, 28 Jul 2002 20:33:13 +0000 (20:33 +0000)
  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
citadel/imap_fetch.c
citadel/msgbase.c
citadel/msgbase.h
citadel/serv_pop3.c
citadel/serv_smtp.c
citadel/serv_spam.c
citadel/techdoc/session.txt

index c7c2c9ae07c5c54c15020df94c188b72aa733b6d..9b625a96c75b42997ed3e701d559eba62a853b0f 100644 (file)
@@ -1,4 +1,11 @@
  $Log$
  $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.
  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 <bryant@cs.usm.maine.edu>
 
 Fri Jul 10 1998 Art Cancro <ajc@uncensored.citadel.org>
        * Initial CVS import
 
 Fri Jul 10 1998 Art Cancro <ajc@uncensored.citadel.org>
        * Initial CVS import
-
index e4697c5838f921e03a78dedb28a21a12959e442b..c1751fa0586a4942fc29e5596e38d1069e27e017 100644 (file)
@@ -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);
         * 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");
        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 */
 
 
        /* 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);
                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);
        }
 
                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);
         */
        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);
        }
                CtdlRedirectOutput(NULL, -1);
                imap_strip_headers(tmp, section);
        }
index 34027331d5296957599fd73cc3914d690a57b3d7..b8498a53680d53af4c2ecb25be75cd5bc2491e78 100644 (file)
@@ -1156,6 +1156,9 @@ int CtdlOutputPreLoadedMsg(struct CtdlMessage *TheMessage,
                return((CC->download_fp != NULL) ? om_ok : om_mime_error);
        }
 
                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);
 
        /* 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 */
        }
 
        /* 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 */
        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);
        }
                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;
 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);
 
        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;
 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);
 
        msgid = extract_long(cmdbuf, 0);
        headers_only = extract_int(cmdbuf, 1);
index b746ab133d90adab9b817fbc6ceee3ade8be3a97..aa1e0f87dcfbb982601512a7e7e3ac9be50a86f5 100644 (file)
@@ -28,7 +28,13 @@ enum {
        om_no_such_msg,
        om_mime_error
 };
        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 {
 
 
 struct ma_info {
index 093764746427c5d4b6936a490073e905615b7dd9..68e60d95da886f6548270453d211a2a46c9b83a5 100644 (file)
@@ -144,7 +144,7 @@ void pop3_add_message(long msgnum, void *userdata) {
        POP3->msgs[POP3->num_msgs-1].temp = fp;
 
        CtdlRedirectOutput(fp, -1);
        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);
        CtdlRedirectOutput(NULL, -1);
 
        POP3->msgs[POP3->num_msgs-1].rfc822_length = ftell(fp);
index 2602c083d25150a97ebb9866a92680ac8141d88d..953f0b0de71f8212b50eed075bcc7879278ae057 100644 (file)
@@ -671,7 +671,7 @@ void smtp_try(const char *key, const char *addr, int *status,
        }
        else {
                CtdlRedirectOutput(msg_fp, -1);
        }
        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);
                CtdlRedirectOutput(NULL, -1);
                fseek(msg_fp, 0L, SEEK_END);
                msg_size = ftell(msg_fp);
index 2e362ba7fe5ecc9f7b27471dccbb7dab59279134..ff548b2ccf6fae3ea6146b8a1b3859cad3bb1892 100644 (file)
@@ -138,7 +138,7 @@ int spam_assassin(struct CtdlMessage *msg) {
 
        /* Message */
        CtdlRedirectOutput(NULL, sock);
 
        /* 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
        CtdlRedirectOutput(NULL, -1);
 
        /* Close one end of the socket connection; this tells SpamAssassin
index 2a559f5631a621e362302cd9eca77a855e656bf4..ad0629daa14d6c6c0720ff699b140e8425023291 100644 (file)
@@ -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.
  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:
  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: