]> code.citadel.org Git - citadel.git/blobdiff - citadel/serv_funambol.c
mk_module_init.sh now tests to see if echo supports -e and -E
[citadel.git] / citadel / serv_funambol.c
index f73ef04b8cff62095b4c48787ca1385ac785dbf9..561be098664567f7c88a7d2eb3364b23573836cd 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 <sys/socket.h>
 #include "citadel.h"
 #include "server.h"
-#include "sysdep_decls.h"
 #include "citserver.h"
 #include "support.h"
 #include "config.h"
 #include "control.h"
-#include "serv_extensions.h"
 #include "room_ops.h"
 #include "user_ops.h"
 #include "policy.h"
 #include "internet_addressing.h"
 #include "domain.h"
 #include "clientsocket.h"
+#include "serv_funambol.h"
 
 
 
+#include "ctdl_module.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);
+       }
+}
+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;
+}
+
 /*
  * Connect to the Funambol server and scan a message.
  */
-int notify_funambol(struct CtdlMessage *msg) {
+void 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);
+               goto nuke;
        }
        /* Are we allowed to push? */
        if ( strlen(config.c_funambol_host) == 0) {
-               return (0);
+               goto nuke;
        } 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.
-                */
-               return(0);
+               /* If the service isn't running, pass for now */
+               return;
        }
        
        /* 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']);
@@ -129,9 +178,8 @@ int notify_funambol(struct CtdlMessage *msg) {
        
        /* Command */
        lprintf(CTDL_DEBUG, "Transmitting command\n");
-       sprintf(buf, "POST %s HTTP/1.0\r\nContent-type: text/xml; charset=utf-8\r\n",
+       sprintf(SOAPHeader, "POST %s HTTP/1.0\r\nContent-type: text/xml; charset=utf-8\r\n",
                FUNAMBOL_WS);
-       strcat(SOAPHeader,buf);
        strcat(SOAPHeader,"Accept: application/soap+xml, application/dime, multipart/related, text/*\r\n");
        sprintf(buf, "User-Agent: %s/%d\r\nHost: %s:%d\r\nCache-control: no-cache\r\n",
                "Citadel",
@@ -159,18 +207,27 @@ 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:           
+       close(sock);
+       nuke:
+       CtdlFreeMessage(msg);
+       long todelete[1];
+       todelete[0] = msgnum;
+       CtdlDeleteMessages(FNBL_QUEUE_ROOM, todelete, 1, "");
 }
 
 
 
-char *serv_funambol_init(void)
+CTDL_MODULE_INIT(funambol)
 {
-       CtdlRegisterMessageHook(notify_funambol, EVT_AFTERSAVE);
-        return "$Id: serv_funambol.c $";
+       create_notify_queue();
+       CtdlRegisterSessionHook(do_notify_queue, EVT_TIMER);
+
+       /* return our Subversion id for the Log */
+        return "$Id$";
 }