* Applied matt's funambol patch
authorArt Cancro <ajc@citadel.org>
Tue, 23 Jan 2007 05:02:37 +0000 (05:02 +0000)
committerArt Cancro <ajc@citadel.org>
Tue, 23 Jan 2007 05:02:37 +0000 (05:02 +0000)
citadel/msgbase.c
citadel/routines2.c
citadel/serv_funambol.c
citadel/serv_vandelay.c
citadel/sysconfig.h

index 5442bcfcede9a983241a9b4a543d20801dc9d364..a5f2b89b064b53b1ba0e23113c4e988178990c3d 100644 (file)
@@ -2580,6 +2580,29 @@ long CtdlSubmitMsg(struct CtdlMessage *msg,      /* message to save */
                                        &userbuf, MAILROOM);
                        CtdlSaveMsgPointerInRoom(actual_rm, newmsgid, 0, msg);
                        BumpNewMailCounter(userbuf.usernum);
+                       if (strlen(config.c_funambol_host) > 0) {
+                       /* Generate a instruction message for the Funambol notification
+                          server, in the same style as the SMTP queue */
+                          instr = malloc(SIZ * 2);
+                          snprintf(instr, SIZ * 2,
+                       "Content-type: %s\n\nmsgid|%ld\nsubmitted|%ld\n"
+                       "bounceto|%s@%s\n",
+                       SPOOLMIME, newmsgid, (long)time(NULL),
+                       msg->cm_fields['A'], msg->cm_fields['N']
+                       );
+
+                          imsg = malloc(sizeof(struct CtdlMessage));
+                          memset(imsg, 0, sizeof(struct CtdlMessage));
+                          imsg->cm_magic = CTDLMESSAGE_MAGIC;
+                          imsg->cm_anon_type = MES_NORMAL;
+                          imsg->cm_format_type = FMT_RFC822;
+                          imsg->cm_fields['A'] = strdup("Citadel");
+                          imsg->cm_fields['J'] = strdup("do not journal");
+                          imsg->cm_fields['M'] = instr;
+                          imsg->cm_fields['W'] = strdup(recipient);
+                          CtdlSubmitMsg(imsg, NULL, FNBL_QUEUE_ROOM);
+                          CtdlFreeMessage(imsg);
+                       }
                }
                else {
                        lprintf(CTDL_DEBUG, "No user <%s>\n", recipient);
index 71baa4e50df68e4994a9e583a4e3d99c2cd6c9bd..50f5aff9a215ef25290235a19bc0c00a91a99f7c 100644 (file)
@@ -644,7 +644,7 @@ void read_bio(CtdlIPC *ipc)
 void do_system_configuration(CtdlIPC *ipc)
 {
 
-#define NUM_CONFIGS 52
+#define NUM_CONFIGS 57
 
        char buf[256];
        char sc[NUM_CONFIGS][256];
@@ -722,7 +722,9 @@ void do_system_configuration(CtdlIPC *ipc)
        else {
                sc[18][0] = 0;
        }
-
+       snprintf(sc[52], sizeof sc[52], "%d", (boolprompt(
+               "Use system authentication",
+               atoi(&sc[52][0]))));
 
        /* Server tuning */
 
@@ -745,7 +747,6 @@ void do_system_configuration(CtdlIPC *ipc)
        strprompt("SMTPS server port (-1 to disable)", &sc[41][0], 5);
        strprompt("Postfix TCP Dictionary Port server port (-1 to disable)", &sc[50][0], 5);
        strprompt("ManageSieve server port (-1 to disable)", &sc[51][0], 5);
-
        /* This logic flips the question around, because it's one of those
         * situations where 0=yes and 1=no
         */
@@ -855,6 +856,12 @@ void do_system_configuration(CtdlIPC *ipc)
                        &sc[48][0], 127);
        }
 
+       /* Funambol push stuff */
+       strprompt("Funambol server (blank to disable)", &sc[53][0], 63);
+       strprompt("Funambol server port", &sc[54][0], 5);
+       strprompt("Funambol sync source", &sc[55][0], 63);
+       strprompt("Funambol authentication details (user:pass in Base64)", &sc[56][0],63);
+       
        /* Save it */
        scr_printf("Save this configuration? ");
        if (yesno()) {
index f73ef04b8cff62095b4c48787ca1385ac785dbf9..cc9e0a192e930efcb54ac7a5f2f2239ebd7c4b76 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * This module implements a notifier for Funambol push email.
+ * Based on bits of serv_spam, serv_smtp
  */
 
 #define FUNAMBOL_WS       "/funambol/services/admin"
 #include "internet_addressing.h"
 #include "domain.h"
 #include "clientsocket.h"
+#include "serv_funambol.h"
+/*
+ * Create the notify message queue
+ */
+void create_notify_queue(void) {
+       struct ctdlroom qrbuf;
 
+       create_room(FNBL_QUEUE_ROOM, 3, "", 0, 1, 0, VIEW_MAILBOX);
 
-
+       /*
+        * Make sure it's set to be a "system room" so it doesn't show up
+        * in the <K>nown rooms list for Aides.
+        */
+       if (lgetroom(&qrbuf, FNBL_QUEUE_ROOM) == 0) {
+               qrbuf.QRflags2 |= QR2_SYSTEM;
+               lputroom(&qrbuf);
+       }
+}
 /*
  * Connect to the Funambol server and scan a message.
  */
-int notify_funambol(struct CtdlMessage *msg) {
+int notify_funambol(long msgnum, void *userdata) {
+       struct CtdlMessage *msg;
        int sock = (-1);
        char buf[SIZ];
        char SOAPHeader[SIZ];
        char SOAPData[SIZ];
        char port[SIZ];
        /* W means 'Wireless'... */
+       msg = CtdlFetchMessage(msgnum, 1);
        if ( msg->cm_fields['W'] == NULL) {
                return(0);
        }
@@ -67,20 +85,19 @@ int notify_funambol(struct CtdlMessage *msg) {
        } else {
                lprintf(CTDL_INFO, "Push enabled\n");
        }
+       
        sprintf(port, "%d", config.c_funambol_port);
                 lprintf(CTDL_INFO, "Connecting to Funambol at <%s>\n", config.c_funambol_host);
                 sock = sock_connect(config.c_funambol_host, port, "tcp");
                 if (sock >= 0) lprintf(CTDL_DEBUG, "Connected!\n");
 
        if (sock < 0) {
-               /* If the service isn't running, just pass the mail
-                * through.  Potentially throwing away mails isn't good.
-                */
+               /* If the service isn't running, pass for now */
                return(0);
        }
        
        /* Build a SOAP message, delicately, by hand */
-       strcat(SOAPData, "<?xml version=\"1.0\" encoding=\"UTF-8\"?><soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">");
+       sprintf(SOAPData, "<?xml version=\"1.0\" encoding=\"UTF-8\"?><soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">");
        strcat(SOAPData, "<soapenv:Body><sendNotificationMessages soapenv:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">");
        strcat(SOAPData, "<arg0 xsi:type=\"soapenc:string\" xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\">");
        strcat(SOAPData, msg->cm_fields['W']);
@@ -159,18 +176,53 @@ int notify_funambol(struct CtdlMessage *msg) {
         }
         lprintf(CTDL_DEBUG, "<%s\n", buf);
        if (strncasecmp(buf, "HTTP/1.1 200 OK", strlen("HTTP/1.1 200 OK"))) {
+               
                goto bail;
        }
        lprintf(CTDL_DEBUG, "Funambol notified\n");
-
-bail:  close(sock);
-       return(0);
+       /* We should allow retries here but for now purge after one go */
+       bail:   
+       CtdlFreeMessage(msg);
+       long todelete[1];
+       todelete[0] = msgnum;
+       CtdlDeleteMessages(FNBL_QUEUE_ROOM, todelete, 1, "");   
+       close(sock);
+       return 0;
 }
 
 
+void do_notify_queue(void) {
+       static int doing_queue = 0;
+
+       /*
+        * This is a simple concurrency check to make sure only one queue run
+        * is done at a time.  We could do this with a mutex, but since we
+        * don't really require extremely fine granularity here, we'll do it
+        * with a static variable instead.
+        */
+       if (doing_queue) return;
+       doing_queue = 1;
+
+       /* 
+        * Go ahead and run the queue
+        */
+       lprintf(CTDL_INFO, "serv_funambol: processing notify queue\n");
+
+       if (getroom(&CC->room, FNBL_QUEUE_ROOM) != 0) {
+               lprintf(CTDL_ERR, "Cannot find room <%s>\n", FNBL_QUEUE_ROOM);
+               return;
+       }
+       CtdlForEachMessage(MSGS_ALL, 0L, NULL,
+               SPOOLMIME, NULL, notify_funambol, NULL);
+
+       lprintf(CTDL_INFO, "serv_funambol: queue run completed\n");
+       doing_queue = 0;
+}
+
 
 char *serv_funambol_init(void)
 {
-       CtdlRegisterMessageHook(notify_funambol, EVT_AFTERSAVE);
+       create_notify_queue();
+       CtdlRegisterSessionHook(do_notify_queue, EVT_TIMER);
         return "$Id: serv_funambol.c $";
 }
index 940e8e222d2d7238daa928ecdb1ed53dff6e3a39..0ab094f054bd2e82dc7f3f1fa9b0cb8972160328 100644 (file)
@@ -320,7 +320,10 @@ void artv_do_export(void) {
        cprintf("%d\n", config.c_pftcpdict_port);
        cprintf("%d\n", config.c_managesieve_port);
        cprintf("%d\n", config.c_auth_mode);
-       
+       cprintf("%s\n", config.c_funambol_host);
+       cprintf("%d\n", config.c_funambol_port);
+       cprintf("%s\n", config.c_funambol_source);
+       cprintf("%s\n", config.c_funambol_auth);
 
        /* Export the control file */
        get_control();
@@ -405,6 +408,11 @@ void artv_import_config(void) {
        client_getln(buf, sizeof buf);  config.c_pftcpdict_port = atoi(buf);
        client_getln(buf, sizeof buf);  config.c_managesieve_port = atoi(buf);
        client_getln(buf, sizeof buf);  config.c_auth_mode = atoi(buf);
+       client_getln(config.c_funambol_host, sizeof config.c_funambol_host);
+       client_getln(buf, sizeof buf); config.c_funambol_port = atoi(buf);
+       client_getln(config.c_funambol_source, sizeof config.c_funambol_source);
+       client_getln(config.c_funambol_auth, sizeof config.c_funambol_auth);
+       
        config.c_enable_fulltext = 0;   /* always disable */
        put_config();
        lprintf(CTDL_INFO, "Imported config file\n");
index 1189c3709653971b8baaa5e18a2d7614554e1739..e32627c8d80f3064617fe25d7f58677fbef744a6 100644 (file)
 #define PAGELOGROOM            "Sent/Received Pages"
 #define SYSCONFIGROOM          "Local System Configuration"
 #define SMTP_SPOOLOUT_ROOM     "__CitadelSMTPspoolout__"
-
+#define FNBL_QUEUE_ROOM                "__CitadelFNBLqueue__"
 /*
  * Where we keep messages containing the vCards that source our directory.  It
  * makes no sense to change this, because you'd have to change it on every