]> code.citadel.org Git - citadel.git/blobdiff - citadel/imap_misc.c
* extract_token() now expects to be supplied with the size of the
[citadel.git] / citadel / imap_misc.c
index 551605f306d9f14c5307b7a8a28d2a5bf6d42eda..0ddd8d401ea553310776285422f834fdc8843f19 100644 (file)
@@ -70,7 +70,9 @@ int imap_do_copy(char *destination_folder) {
                for (i = 0; i < IMAP->num_msgs; ++i) {
                        if (IMAP->flags[i] & IMAP_SELECTED) {
                                CtdlCopyMsgToRoom(
-                                       IMAP->msgids[i], roomname);
+                                       IMAP->msgids[i],
+                                       roomname
+                               );
                        }
                }
        }
@@ -205,6 +207,34 @@ void imap_print_instant_messages(void) {
 }
 
 
+/*
+ * imap_do_append_flags() is called by imap_append() to set any flags that
+ * the client specified at append time.
+ *
+ * FIXME find a way to do these in bulk so we don't max out our db journal
+ */
+void imap_do_append_flags(long new_msgnum, char *new_message_flags) {
+       char flags[32];
+       char this_flag[sizeof flags];
+       int i;
+
+       if (new_message_flags == NULL) return;
+       if (strlen(new_message_flags) == 0) return;
+
+       safestrncpy(flags, new_message_flags, sizeof flags);
+
+       for (i=0; i<num_tokens(flags, ' '); ++i) {
+               extract_token(this_flag, flags, i, ' ', sizeof this_flag);
+               if (this_flag[0] == '\\') strcpy(this_flag, &this_flag[1]);
+               if (!strcasecmp(this_flag, "Seen")) {
+                       CtdlSetSeen(new_msgnum, 1, ctdlsetseen_seen);
+               }
+               if (!strcasecmp(this_flag, "Answered")) {
+                       CtdlSetSeen(new_msgnum, 1, ctdlsetseen_answered);
+               }
+       }
+}
+
 
 /*
  * This function is called by the main command loop.
@@ -214,14 +244,14 @@ void imap_append(int num_parms, char *parms[]) {
        long bytes_transferred;
        long stripped_length = 0;
        struct CtdlMessage *msg;
+       long new_msgnum = (-1L);
        int ret = 0;
-       size_t blksize;
        char roomname[ROOMNAMELEN];
        char buf[SIZ];
        char savedroom[ROOMNAMELEN];
        int msgs, new;
        int i;
-
+       char new_message_flags[SIZ];
 
        if (num_parms < 4) {
                cprintf("%s BAD usage error\r\n", parms[0]);
@@ -234,6 +264,21 @@ void imap_append(int num_parms, char *parms[]) {
                return;
        }
 
+       strcpy(new_message_flags, "");
+       if (num_parms >= 5) {
+               for (i=3; i<num_parms; ++i) {
+                       strcat(new_message_flags, parms[i]);
+                       strcat(new_message_flags, " ");
+               }
+               stripallbut(new_message_flags, '(', ')');
+       }
+
+       /* This is how we'd do this if it were relevant in our data store.
+        * if (num_parms >= 6) {
+        *  new_message_internaldate = parms[4];
+        * }
+        */
+
        literal_length = atol(&parms[num_parms-1][1]);
        if (literal_length < 1) {
                cprintf("%s BAD Message length must be at least 1.\r\n",
@@ -250,51 +295,30 @@ void imap_append(int num_parms, char *parms[]) {
        IMAP->transmitted_length = literal_length;
 
        cprintf("+ Transmit message now.\r\n");
-       lprintf(CTDL_DEBUG, "imap_append() expecting %ld bytes\n",
-               literal_length);
 
        bytes_transferred = 0;
 
-       do {
-               blksize = literal_length - bytes_transferred;
-               if (blksize > SIZ) blksize = SIZ;
-
-               flush_output();
-               ret = client_read(&IMAP->transmitted_message[bytes_transferred], blksize);
-               if (ret < 1) {
-                       bytes_transferred = literal_length;     /* bail out */
-               }
-               else {
-                       bytes_transferred += blksize;           /* keep going */
-               }
-               lprintf(CTDL_DEBUG, "Received %ld of %ld bytes (%ld%%)\n",
-                       bytes_transferred,
-                       literal_length,
-                       ((bytes_transferred * 100) / literal_length)
-               );
-       } while (bytes_transferred < literal_length);
-
+       ret = client_read(IMAP->transmitted_message, literal_length);
        IMAP->transmitted_message[literal_length] = 0;
+
        if (ret != 1) {
                cprintf("%s NO Read failed.\r\n", parms[0]);
                return;
        }
-       lprintf(CTDL_DEBUG, "imap_append() finished reading message\n");
 
-       /* I think there's supposed to be a trailing CRLF after the
-        * literal (the message text) is received.  This call to
-        * client_getln() absorbs it.
+       /* Client will transmit a trailing CRLF after the literal (the message
+        * text) is received.  This call to client_getln() absorbs it.
         */
        flush_output();
        client_getln(buf, sizeof buf);
-       lprintf(CTDL_DEBUG, "Trailing CRLF: %s\n", buf);
 
        /* Convert RFC822 newlines (CRLF) to Unix newlines (LF) */
-       lprintf(CTDL_DEBUG, "Converting newline format\n");
+       lprintf(CTDL_DEBUG, "Converting CRLF to LF\n");
        stripped_length = 0;
        for (i=0; i<literal_length; ++i) {
                if (strncmp(&IMAP->transmitted_message[i], "\r\n", 2)) {
-                       IMAP->transmitted_message[stripped_length++] = IMAP->transmitted_message[i];
+                       IMAP->transmitted_message[stripped_length++] =
+                               IMAP->transmitted_message[i];
                }
        }
        literal_length = stripped_length;
@@ -352,9 +376,15 @@ void imap_append(int num_parms, char *parms[]) {
        else {
                /* Yes ... go ahead and post! */
                if (msg != NULL) {
-                       CtdlSubmitMsg(msg, NULL, "");
+                       new_msgnum = CtdlSubmitMsg(msg, NULL, "");
+               }
+               if (new_msgnum >= 0L) {
+                       cprintf("%s OK APPEND completed\r\n", parms[0]);
+               }
+               else {
+                       cprintf("%s BAD Error %ld saving message to disk.\r\n",
+                               parms[0], new_msgnum);
                }
-               cprintf("%s OK APPEND completed\r\n", parms[0]);
        }
 
        /*
@@ -369,4 +399,8 @@ void imap_append(int num_parms, char *parms[]) {
 
        /* We don't need this buffer anymore */
        CtdlFreeMessage(msg);
+
+       if (new_message_flags != NULL) {
+               imap_do_append_flags(new_msgnum, new_message_flags);
+       }
 }