* 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$
+ 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 <bryant@cs.usm.maine.edu>
 
 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);
-       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);
        }
index 34027331d5296957599fd73cc3914d690a57b3d7..b8498a53680d53af4c2ecb25be75cd5bc2491e78 100644 (file)
@@ -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);
index b746ab133d90adab9b817fbc6ceee3ade8be3a97..aa1e0f87dcfbb982601512a7e7e3ac9be50a86f5 100644 (file)
@@ -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 {
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);
-       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);
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);
-               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);
index 2e362ba7fe5ecc9f7b27471dccbb7dab59279134..ff548b2ccf6fae3ea6146b8a1b3859cad3bb1892 100644 (file)
@@ -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
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.
-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: