]> code.citadel.org Git - citadel.git/blobdiff - citadel/serv_smtp.c
* Coded up some more of the SMTP-sender (still not done)
[citadel.git] / citadel / serv_smtp.c
index 60dd06d4f67da712b752f9b8c2a2b639fe696dde..4c694c342b534ed86c117365256898483682ebdc 100644 (file)
@@ -667,12 +667,146 @@ void smtp_command_loop(void) {
 /*               SMTP CLIENT (OUTBOUND PROCESSING) STUFF                     */
 /*****************************************************************************/
 
+
+
+/*
+ * smtp_try()
+ *
+ * Called by smtp_do_procmsg() to attempt delivery to one SMTP host
+ *
+ */
+void smtp_try(char *key, char *addr, int *status, char *dsn) {
+
+       *status = 3;
+       strcpy(dsn, "smtp_try() is not finished yet");
+}
+
+
+
+/*
+ * smtp_do_procmsg()
+ *
+ * Called by smtp_do_queue() to handle an individual message.
+ */
+void smtp_do_procmsg(long msgnum) {
+       struct CtdlMessage *msg;
+       char *instr = NULL;
+       char *results = NULL;
+       int i;
+       int lines;
+       int status;
+       char buf[1024];
+       char key[1024];
+       char addr[1024];
+       char dsn[1024];
+       long text_msgid = (-1);
+
+       msg = CtdlFetchMessage(msgnum);
+       if (msg == NULL) {
+               lprintf(3, "SMTP: tried %ld but no such message!\n", msgnum);
+               return;
+       }
+
+       instr = strdoop(msg->cm_fields['M']);
+       CtdlFreeMessage(msg);
+
+       /* Strip out the headers amd any other non-instruction line */
+       lines = num_tokens(instr, '\n');
+       for (i=0; i<lines; ++i) {
+               extract_token(buf, instr, i, '\n');
+               if (num_tokens(buf, '|') < 2) {
+                       lprintf(9, "removing <%s>\n", buf);
+                       remove_token(instr, i, '|');
+                       --lines;
+                       --i;
+               }
+       }
+
+       /* Learn the message ID */
+       lines = num_tokens(instr, '\n');
+       for (i=0; i<lines; ++i) {
+               extract_token(buf, instr, i, '\n');
+               extract(key, buf, 0);
+               if (!strcasecmp(key, "msgid")) {
+                       text_msgid = extract_long(buf, 1);
+               }
+       }
+
+       if (text_msgid < 0L) {
+               lprintf(3, "SMTP: no 'msgid' directive found!\n", msgnum);
+               phree(instr);
+               return;
+       }
+
+       /* Plow through the instructions looking for 'remote' directives and
+        * a status of 0 (no delivery yet attempted) or 3 (transient errors
+        * were experienced and it's time to try again)
+        */
+       lines = num_tokens(instr, '\n');
+       for (i=0; i<lines; ++i) {
+               extract_token(buf, instr, i, '\n');
+               extract(key, buf, 0);
+               extract(addr, buf, 1);
+               status = extract_int(buf, 2);
+               extract(dsn, buf, 3);
+               if ( (!strcasecmp(key, "remote"))
+                  && ((status==0)||(status==3)) ) {
+                       remove_token(instr, i, '\n');
+                       --i;
+                       --lines;
+                       lprintf(9, "SMTP: Trying <%s>\n", addr);
+                       smtp_try(key, addr, &status, dsn);
+                       if (status != 2) {
+                               if (results == NULL) {
+                                       results = mallok(1024);
+                                       memset(results, 0, 1024);
+                               }
+                               else {
+                                       results = reallok(results,
+                                               strlen(results) + 1024);
+                               }
+                               sprintf(&results[strlen(results)],
+                                       "%s|%s|%d|%s\n",
+                                       key, addr, status, dsn);
+                       }
+               }
+       }
+
+       if (results != NULL) {
+               instr = reallok(instr, strlen(instr) + strlen(results) + 2);
+               strcat(instr, results);
+               phree(results);
+       }
+
+       /* Delete the instructions and replace with the updated ones */
+       CtdlDeleteMessages(SMTP_SPOOLOUT_ROOM, msgnum, NULL);    
+        msg = mallok(sizeof(struct CtdlMessage));
+       memset(msg, 0, sizeof(struct CtdlMessage));
+       msg->cm_magic = CTDLMESSAGE_MAGIC;
+       msg->cm_anon_type = MES_NORMAL;
+       msg->cm_format_type = FMT_RFC822;
+       msg->cm_fields['M'] = instr;
+       CtdlSaveMsg(msg, "", SMTP_SPOOLOUT_ROOM, MES_LOCAL, 1);
+       CtdlFreeMessage(msg);
+}
+
+
+
 /*
  * smtp_do_queue()
  * 
  * Run through the queue sending out messages.
  */
 void smtp_do_queue(void) {
+       lprintf(5, "SMTP: processing outbound queue\n");
+
+       if (getroom(&CC->quickroom, SMTP_SPOOLOUT_ROOM) != 0) {
+               lprintf(3, "Cannot find room <%s>\n", SMTP_SPOOLOUT_ROOM);
+               return;
+       }
+       CtdlForEachMessage(MSGS_ALL, 0L, SPOOLMIME, NULL, smtp_do_procmsg);
+
+       lprintf(5, "SMTP: queue run completed\n");
 }