Index: control.c =================================================================== --- control.c (revision 4872) +++ control.c (working copy) @@ -242,6 +242,11 @@ cprintf("%s\n", config.c_default_cal_zone); 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); cprintf("000\n"); } @@ -447,6 +452,25 @@ case 51: config.c_managesieve_port = atoi(buf); break; + case 52: + config.c_auth_mode = atoi(buf); + case 53: + safestrncpy(config.c_funambol_host, buf, + sizeof config.c_funambol_host); + break; + case 54: + config.c_funambol_port = atoi(buf); + break; + case 55: + safestrncpy(config.c_funambol_source, + buf, + sizeof config.c_funambol_source); + break; + case 56: + safestrncpy(config.c_funambol_auth, + buf, + sizeof config.c_funambol_auth); + break; } ++a; } Index: msgbase.c =================================================================== --- msgbase.c (revision 4872) +++ msgbase.c (working copy) @@ -2571,6 +2571,29 @@ &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|[EMAIL PROTECTED]", + 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: routines2.c =================================================================== --- routines2.c (revision 4872) +++ routines2.c (working copy) @@ -644,7 +644,7 @@ void do_system_configuration(CtdlIPC *ipc) { -#define NUM_CONFIGS 52 +#define NUM_CONFIGS 57 char buf[256]; char sc[NUM_CONFIGS][256]; @@ -722,8 +722,10 @@ else { sc[18][0] = 0; } + snprintf(sc[52], sizeof sc[52], "%d", (boolprompt( + "Use system authentication", + atoi(&sc[52][0])))); - /* Server tuning */ strprompt("Server connection idle timeout (in seconds)", &sc[5][0], 4); @@ -745,7 +747,6 @@ 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 @@ &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: Makefile.in =================================================================== --- Makefile.in (revision 4872) +++ Makefile.in (working copy) @@ -53,7 +53,8 @@ serv_managesieve.o \ ical_dezonify.o \ serv_ldap.o \ - serv_autocompletion.o + serv_autocompletion.o \ + serv_funambol.o UTIL_TARGETS=aidepost msgform \ citmail userlist sendcommand \ @@ -102,7 +103,7 @@ serv_newuser.c serv_pas2.c serv_pop3.c serv_rwho.c serv_smtp.c \ serv_spam.c serv_test.c serv_mrtg.c serv_spam.c serv_upgrade.c \ serv_vandelay.c serv_vcard.c serv_managesieve.c server_main.c \ - serv_sieve.c setup.c snprintf.c imap_acl.c \ + serv_sieve.c serv_funambol.c setup.c snprintf.c imap_acl.c \ stress.c support.c sysdep.c tools.c user_ops.c userlist.c \ whobbs.c vcard.c serv_notes.c serv_fulltext.c ft_wordbreaker.c \ crc16.c journaling.c citadel_dirs.c Index: config.h =================================================================== --- config.h (revision 4872) +++ config.h (working copy) @@ -76,6 +76,10 @@ int c_pftcpdict_port; /* postfix tcptable support, see http://www.postfix.org/tcp_table.5.html */ int c_managesieve_port; /* managesieve port. */ int c_auth_mode; /* 0 = built-in Citadel auth; 1 = underlying host system auth */ + char c_funambol_host[256]; /* Funambol host. Blank to disable */ + int c_funambol_port; /* Funambol port */ + char c_funambol_source[256]; /* Funambol sync source */ + char c_funambol_auth[256]; /* Funambol auth details */ }; Index: serv_funambol.c =================================================================== --- serv_funambol.c (revision 0) +++ serv_funambol.c (revision 0) @@ -0,0 +1,239 @@ +/* + * This module implements a notifier for Funambol push email. + * Based on bits of serv_spam, serv_smtp + */ + +#define FUNAMBOL_WS "/funambol/services/admin" +#include "sysdep.h" +#include <stdlib.h> +#include <unistd.h> +#include <stdio.h> +#include <fcntl.h> +#include <signal.h> +#include <pwd.h> +#include <errno.h> +#include <sys/types.h> + +#if TIME_WITH_SYS_TIME +# include <sys/time.h> +# include <time.h> +#else +# if HAVE_SYS_TIME_H +# include <sys/time.h> +# else +# include <time.h> +# endif +#endif + +#include <sys/wait.h> +#include <string.h> +#include <limits.h> +#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 "database.h" +#include "msgbase.h" +#include "tools.h" +#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 the room. This will silently fail if the room already + * exists, and that's perfectly ok, because we want it to exist. + */ + 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(long msgnum, void *userdata) { + struct CtdlMessage *msg; + int sock = (-1); + char fnblhosts[SIZ]; + int num_fnblhosts; + char buf[SIZ]; + int is_spam = 0; + int fnbl; + char *msgtext; + size_t msglen; + char host[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); + } + /* Are we allowed to push? */ + if ( strlen(config.c_funambol_host) == 0) { + return (0); + } 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); + } + + /* 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\">"); + 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']); + strcat(SOAPData, "</arg0>"); + strcat(SOAPData, "<arg1 xsi:type=\"soapenc:string\" xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\"><?xml version="1.0" encoding="UTF-8"?>\r\n"); + strcat(SOAPData, "<java version="1.5.0_10" class="java.beans.XMLDecoder"> \r\n"); + strcat(SOAPData, " <array class="com.funambol.framework.core.Alert" length="1">\r\n"); + strcat(SOAPData, " <void index="0">\r\n"); + strcat(SOAPData, " <object class="com.funambol.framework.core.Alert">\r\n"); + strcat(SOAPData, " <void property="cmdID">\r\n"); + strcat(SOAPData, " <object class="com.funambol.framework.core.CmdID"/>\r\n"); + strcat(SOAPData, " </void>"); + strcat(SOAPData, " <void property="data">\r\n"); + strcat(SOAPData, " <int>210</int>\r\n"); + strcat(SOAPData, " </void>\r\n"); + strcat(SOAPData, " <void property="items">\r\n"); + strcat(SOAPData, " <void method="add">\r\n"); + strcat(SOAPData, " <object class="com.funambol.framework.core.Item">\r\n"); + strcat(SOAPData, " <void property="meta">\r\n"); + strcat(SOAPData, " <object class="com.funambol.framework.core.Meta">\r\n"); + strcat(SOAPData, " <void property="metInf">\r\n"); + strcat(SOAPData, " <void property="type">\r\n"); + strcat(SOAPData, " <string>application/vnd.omads-email+xml</string>\r\n"); + strcat(SOAPData, " </void>\r\n"); + strcat(SOAPData, " </void>\r\n"); + strcat(SOAPData, " </object>\r\n"); + strcat(SOAPData, " </void>\r\n"); + strcat(SOAPData, " <void property="target">\r\n"); + strcat(SOAPData, " <object class="com.funambol.framework.core.Target">\r\n"); + strcat(SOAPData, " <void property="locURI">\r\n"); + strcat(SOAPData, " <string>"); + strcat(SOAPData, config.c_funambol_source); + strcat(SOAPData, "</string>\r\n"); + strcat(SOAPData, " </void>\r\n"); + strcat(SOAPData, " </object>\r\n"); + strcat(SOAPData, " </void>\r\n"); + strcat(SOAPData, " </object>\r\n"); + strcat(SOAPData, " </void>\r\n"); + strcat(SOAPData, " </void>\r\n"); + strcat(SOAPData, " </object>\r\n"); + strcat(SOAPData, " </void>\r\n"); + strcat(SOAPData, " </array>\r\n"); + strcat(SOAPData, "</java>"); + strcat(SOAPData,"</arg1><arg2 href=\"#id0\"/></sendNotificationMessages><multiRef id=\"id0\" soapenc:root=\"0\"\r\n"); + strcat(SOAPData,"soapenv:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xsi:type=\"soapenc:int\" xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\">1</multiRef></soapenv:Body></soapenv:Envelope>"); + + /* Command */ + lprintf(CTDL_DEBUG, "Transmitting command\n"); + sprintf(buf, "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", + REV_LEVEL, + config.c_funambol_host, + config.c_funambol_port + ); + strcat(SOAPHeader,buf); + strcat(SOAPHeader,"Pragma: no-cache\r\nSOAPAction: \"\"\r\n"); + sprintf(buf, "Content-Length: %d\r\n", + strlen(SOAPData)); + strcat(SOAPHeader, buf); + sprintf(buf, "Authorization: Basic %s\r\n\r\n", + config.c_funambol_auth); + strcat(SOAPHeader, buf); + + sock_write(sock, SOAPHeader, strlen(SOAPHeader)); + sock_write(sock, SOAPData, strlen(SOAPData)); + sock_shutdown(sock, SHUT_WR); + + /* Response */ + lprintf(CTDL_DEBUG, "Awaiting response\n"); + if (sock_gets(sock, buf) < 0) { + goto bail; + } + 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"); + CtdlFreeMessage(msg); + long todelete[1]; + todelete[0] = msgnum; + CtdlDeleteMessages(FNBL_QUEUE_ROOM, todelete, 1, ""); + bail: close(sock); + +} + + + +char *serv_funambol_init(void) +{ + create_notify_queue(); + CtdlRegisterSessionHook(do_notify_queue, EVT_TIMER); + return "$Id: serv_funambol.c $"; +} Index: sysconfig.h =================================================================== --- sysconfig.h (revision 4872) +++ sysconfig.h (working copy) @@ -112,7 +112,7 @@ #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 Index: serv_extensions.c =================================================================== --- serv_extensions.c (revision 4872) +++ serv_extensions.c (working copy) @@ -234,7 +234,7 @@ lprintf(CTDL_INFO, "%s\n", serv_postfix_tcpdict()); lprintf(CTDL_INFO, "%s\n", serv_sieve_init()); lprintf(CTDL_INFO, "%s\n", serv_managesieve_init()); - + lprintf(CTDL_INFO, "%s\n", serv_funambol_init()); for (filter = 1; filter != 0; filter = filter << 1) if ((filter & DetailErrorFlags) != 0) LogPrintMessages(filter); Index: serv_vandelay.c =================================================================== --- serv_vandelay.c (revision 4872) +++ serv_vandelay.c (working copy) @@ -320,7 +320,10 @@ cprintf("%d\n", config.c_pftcpdict_port); cprintf("%d\n", config.c_managesieve_port); cprintf("%d\n", config.c_auth_mode); - + cprintf("%d\n", config.c_funambol_host); + cprintf("%d\n", config.c_funambol_port); + cprintf("%d\n", config.c_funambol_source); + cprintf("%d\n", config.c_funambol_auth); /* Export the control file */ get_control(); @@ -405,6 +408,11 @@ 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");
Here we go - another queue room has been established for push notification and notify_funambol now fires off EVT_TIMER. Relevant config options have been added to vandelay and the text client.
- [Citadel Development] (no subject) IGnatius T Foobar
- [Citadel Development] (no subject) Ford II
- [Citadel Development] (no subject) IGnatius T Foobar
- [Citadel Development] (no subject) IGnatius T Foobar
- [Citadel Development] (no subject) IGnatius T Foobar
- [Citadel Development] (no subject) IGnatius T Foobar
- [Citadel Development] (no subject) IGnatius T Foobar
- [Citadel Development] (no subject) IO ERROR
- [Citadel Development] (no subject) IO ERROR
- [Citadel Development] (no subject) IGnatius T Foobar
- [Citadel Development] (no subject) matt
- [Citadel Development] (no subject) IGnatius T Foobar
- [Citadel Development] (no subject) fleeb
- [Citadel Development] (no subject) IGnatius T Foobar
- [Citadel Development] (no subject) IGnatius T Foobar
- [Citadel Development] (no subject) IGnatius T Foobar
- [Citadel Development] (no subject) IGnatius T Foobar
- [Citadel Development] (no subject) fleeb
- [Citadel Development] (no subject) dothebart
- [Citadel Development] (no subject) IO ERROR
- [Citadel Development] (no subject) fleeb