From e70a21b32b83dcbd33bd8661c875c21640a82f8d Mon Sep 17 00:00:00 2001 From: =?utf8?q?Wilfried=20G=C3=B6esgens?= Date: Sun, 28 Jun 2009 22:18:22 +0000 Subject: [PATCH] * add support for custom notifiers * fix some tiny hickups, code cleanup --- citadel/modules/extnotify/extnotify.h | 2 +- citadel/modules/extnotify/extnotify_main.c | 384 +++++++++++++-------- citadel/modules/extnotify/funambol65.c | 9 +- 3 files changed, 250 insertions(+), 145 deletions(-) diff --git a/citadel/modules/extnotify/extnotify.h b/citadel/modules/extnotify/extnotify.h index 2d1874f27..0639acbd5 100644 --- a/citadel/modules/extnotify/extnotify.h +++ b/citadel/modules/extnotify/extnotify.h @@ -17,7 +17,7 @@ extern "C" { #define FUNAMBOL_WS "/funambol/services/admin" int notify_http_server(char *remoteurl, - char* template, + const char* template, long tlen, char *user, char *msgid, diff --git a/citadel/modules/extnotify/extnotify_main.c b/citadel/modules/extnotify/extnotify_main.c index 0e2731d1a..d15b3b07b 100644 --- a/citadel/modules/extnotify/extnotify_main.c +++ b/citadel/modules/extnotify/extnotify_main.c @@ -52,6 +52,56 @@ #include "ctdl_module.h" +StrBuf* GetNHBuf(int i, int allocit, StrBuf **NotifyHostList) +{ + if ((NotifyHostList[i] == NULL) && (allocit != 0)) + NotifyHostList[i] = NewStrBuf(); + return NotifyHostList[i]; +} + + +StrBuf** GetNotifyHosts(void) +{ + char NotifyHostsBuf[SIZ]; + StrBuf *Host; + StrBuf *File; + StrBuf *NotifyBuf; + int notify; + const char *pchs, *pche; + const char *NextHost = NULL; + StrBuf **NotifyHostList; + int num_notify; + + /* See if we have any Notification Hosts configured */ + num_notify = get_hosts(NotifyHostsBuf, "notify"); + if (num_notify < 1) + return(NULL); + + NotifyHostList = malloc(sizeof(StrBuf*) * 2 * (num_notify + 1)); + memset(NotifyHostList, 0, sizeof(StrBuf*) * 2 * (num_notify + 1)); + + NotifyBuf = NewStrBufPlain(NotifyHostsBuf, -1); + /* get all configured notifiers's */ + for (notify=0; notifynown rooms list for Aides. - */ - if (lgetroom(&qrbuf, FNBL_QUEUE_ROOM) == 0) { - qrbuf.QRflags2 |= QR2_SYSTEM; - lputroom(&qrbuf); - } + /* + * Make sure it's set to be a "system room" so it doesn't show up + * in the nown rooms list for Aides. + */ + if (lgetroom(&qrbuf, FNBL_QUEUE_ROOM) == 0) { + qrbuf.QRflags2 |= QR2_SYSTEM; + lputroom(&qrbuf); + } } /*! * \brief Run through the pager room queue */ void do_extnotify_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; + static int doing_queue = 0; + StrBuf **NotifyHosts; + int i = 0; - /* - * Go ahead and run the queue - */ - CtdlLogPrintf(CTDL_DEBUG, "serv_extnotify: processing notify queue\n"); + /* + * 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; - if (getroom(&CC->room, FNBL_QUEUE_ROOM) != 0) { - CtdlLogPrintf(CTDL_ERR, "Cannot find room <%s>\n", FNBL_QUEUE_ROOM); - return; - } - CtdlForEachMessage(MSGS_ALL, 0L, NULL, - SPOOLMIME, NULL, process_notify, NULL); + /* + * Go ahead and run the queue + */ + CtdlLogPrintf(CTDL_DEBUG, "serv_extnotify: processing notify queue\n"); + NotifyHosts = GetNotifyHosts(); + if (getroom(&CC->room, FNBL_QUEUE_ROOM) != 0) { + CtdlLogPrintf(CTDL_ERR, "Cannot find room <%s>\n", FNBL_QUEUE_ROOM); + return; + } + CtdlForEachMessage(MSGS_ALL, 0L, NULL, + SPOOLMIME, NULL, process_notify, NotifyHosts); + + while ((NotifyHosts != NULL) && (NotifyHosts[i] != NULL)) + FreeStrBuf(&NotifyHosts[i]); + CtdlLogPrintf(CTDL_DEBUG, "serv_extnotify: queue run completed\n"); doing_queue = 0; } /*! * \brief Process messages in the external notification queue */ -void process_notify(long msgnum, void *usrdata) { - struct CtdlMessage *msg; - msg = CtdlFetchMessage(msgnum, 1); - if ( msg->cm_fields['W'] == NULL) { - goto nuke; - } - - long configMsgNum = extNotify_getConfigMessage(msg->cm_fields['W']); - char configMsg[SIZ]; +void process_notify(long msgnum, void *usrdata) +{ + long todelete[1]; + int fnblAllowed; + int extPagerAllowedHttp; + int extPagerAllowedSystem; + char *pch; + long configMsgNum; + char configMsg[SIZ]; + StrBuf **NotifyHostList; + struct CtdlMessage *msg; + + + NotifyHostList = (StrBuf**) usrdata; + msg = CtdlFetchMessage(msgnum, 1); + if ( msg->cm_fields['W'] == NULL) { + goto nuke; + } - extNotify_getPrefs(configMsgNum, &configMsg[0]); + configMsgNum = extNotify_getConfigMessage(msg->cm_fields['W']); - /* Check to see if: - * 1. The user has configured paging / They have and disabled it - * AND 2. There is an external pager program - * 3. A Funambol server has been entered - * - */ - if ((configMsgNum == -1) || - ((strncasecmp(configMsg, "none", 4) == 0) && - IsEmptyStr(config.c_pager_program) && - IsEmptyStr(config.c_funambol_host))) { - CtdlLogPrintf(CTDL_DEBUG, "No external notifiers configured on system/user"); - goto nuke; - } - // Can Funambol take the message? - int fnblAllowed = strncasecmp(configMsg, HKEY(FUNAMBOL_CONFIG_TEXT)); - int extPagerAllowedHttp = strncasecmp(configMsg, HKEY(PAGER_CONFIG_HTTP)); - int extPagerAllowedSystem = strncasecmp(configMsg, HKEY(PAGER_CONFIG_SYSTEM)); - if (fnblAllowed == 0) { - char remoteurl[SIZ]; - snprintf(remoteurl, SIZ, "http://%s@%s:%d/%s", - config.c_funambol_auth, - config.c_funambol_host, - config.c_funambol_port, - FUNAMBOL_WS); - notify_http_server(remoteurl, - file_funambol_msg, - strlen(file_funambol_msg),/*GNA*/ - msg->cm_fields['W'], - msg->cm_fields['I'], - msgnum); - } else if (extPagerAllowedHttp) { -/* - notify_http_server(remoteurl, - file_funambol_msg, - strlen(file_funambol_msg),/ *GNA* / - msg->cm_fields['W'], + extNotify_getPrefs(configMsgNum, &configMsg[0]); + + /* Check to see if: + * 1. The user has configured paging / They have and disabled it + * AND 2. There is an external pager program + * 3. A Funambol server has been entered + * + */ + if ((configMsgNum == -1) || + ((strncasecmp(configMsg, "none", 4) == 0) && + IsEmptyStr(config.c_pager_program) && + IsEmptyStr(config.c_funambol_host))) { + CtdlLogPrintf(CTDL_DEBUG, "No external notifiers configured on system/user"); + goto nuke; + } + + // Can Funambol take the message? + pch = strchr(configMsg, '\n'); + if (*pch == '\n') + *pch = '\0'; + fnblAllowed = strncasecmp(configMsg, HKEY(FUNAMBOL_CONFIG_TEXT)); + extPagerAllowedHttp = strncasecmp(configMsg, HKEY(PAGER_CONFIG_HTTP)); + extPagerAllowedSystem = strncasecmp(configMsg, HKEY(PAGER_CONFIG_SYSTEM)); + + if (fnblAllowed == 0) { + char remoteurl[SIZ]; + snprintf(remoteurl, SIZ, "http://%s@%s:%d/%s", + config.c_funambol_auth, + config.c_funambol_host, + config.c_funambol_port, + FUNAMBOL_WS); + notify_http_server(remoteurl, + file_funambol_msg, + strlen(file_funambol_msg),/*GNA*/ + msg->cm_fields['W'], msg->cm_fields['I'], msgnum); -*/ - } else if (extPagerAllowedSystem == 0) { - char *number = strtok(configMsg, "textmessage\n"); - int commandSiz = sizeof(config.c_pager_program) + strlen(number) + strlen(msg->cm_fields['W']) + 5; - char *command = malloc(commandSiz); - snprintf(command, commandSiz, "%s %s -u %s", config.c_pager_program, number, msg->cm_fields['W']); - system(command); - free(command); - } + } else if (extPagerAllowedHttp == 0) { + int i = 0; + StrBuf *URL; + char URLBuf[SIZ]; + StrBuf *File; + StrBuf *FileBuf = NewStrBuf(); + + while(1) + { + + URL = GetNHBuf(i*2, 0, NotifyHostList); + if (URL==NULL) break; + File = GetNHBuf(i*2 + 1, 0, NotifyHostList); + if (File==NULL) break; + + if (StrLength(File)>0) + StrBufPrintf(FileBuf, "%s/%s", + ctdl_shared_dir, + ChrPtr(File)); + else + FlushStrBuf(FileBuf); + memcpy(URLBuf, ChrPtr(URL), StrLength(URL) + 1); + + notify_http_server(URLBuf, + ChrPtr(FileBuf), + StrLength(FileBuf), + msg->cm_fields['W'], + msg->cm_fields['I'], + msgnum); + i++; + } + FreeStrBuf(&FileBuf); + } + else if (extPagerAllowedSystem == 0) { + char *number; + int commandSiz; + char *command; + + number = strtok(configMsg, "textmessage\n"); + commandSiz = sizeof(config.c_pager_program) + strlen(number) + strlen(msg->cm_fields['W']) + 5; + command = malloc(commandSiz); + snprintf(command, commandSiz, "%s %s -u %s", config.c_pager_program, number, msg->cm_fields['W']); + system(command); + free(command); + } nuke: - CtdlFreeMessage(msg); - memset(configMsg, 0, sizeof(configMsg)); - long todelete[1]; - todelete[0] = msgnum; - CtdlDeleteMessages(FNBL_QUEUE_ROOM, todelete, 1, ""); + CtdlFreeMessage(msg); + memset(configMsg, 0, sizeof(configMsg)); + todelete[0] = msgnum; + CtdlDeleteMessages(FNBL_QUEUE_ROOM, todelete, 1, ""); } /*! \brief Checks to see what notification option the user has set * */ -void extNotify_getPrefs(long configMsgNum, char *configMsg) { - // Do a simple string search to see if 'funambol' is selected as the - // type. This string would be at the very top of the message contents. - if (configMsgNum == -1) { - CtdlLogPrintf(CTDL_ERR, "extNotify_isAllowedByPrefs was passed a non-existant config message id\n"); - return; - } - struct CtdlMessage *prefMsg; - prefMsg = CtdlFetchMessage(configMsgNum, 1); - strncpy(configMsg, prefMsg->cm_fields['M'], strlen(prefMsg->cm_fields['M'])); - CtdlFreeMessage(prefMsg); +void extNotify_getPrefs(long configMsgNum, char *configMsg) +{ + struct CtdlMessage *prefMsg; + // Do a simple string search to see if 'funambol' is selected as the + // type. This string would be at the very top of the message contents. + if (configMsgNum == -1) { + CtdlLogPrintf(CTDL_ERR, "extNotify_isAllowedByPrefs was passed a non-existant config message id\n"); + return; + } + prefMsg = CtdlFetchMessage(configMsgNum, 1); + strncpy(configMsg, prefMsg->cm_fields['M'], strlen(prefMsg->cm_fields['M'])); + CtdlFreeMessage(prefMsg); } + /*! \brief Get configuration message for pager/funambol system from the * users "My Citadel Config" room */ long extNotify_getConfigMessage(char *username) { - struct ctdlroom qrbuf; // scratch for room - struct ctdluser user; // ctdl user instance - char configRoomName[ROOMNAMELEN]; - struct CtdlMessage *msg; - struct cdbdata *cdbfr; - long *msglist = NULL; - int num_msgs = 0; - long confMsgNum = -1; - // Get the user - getuser(&user, username); + struct ctdlroom qrbuf; // scratch for room + struct ctdluser user; // ctdl user instance + char configRoomName[ROOMNAMELEN]; + struct CtdlMessage *msg; + struct cdbdata *cdbfr; + long *msglist = NULL; + int num_msgs = 0; + long confMsgNum = -1; + int a; + + // Get the user + getuser(&user, username); - MailboxName(configRoomName, sizeof configRoomName, &user, USERCONFIGROOM); - // Fill qrbuf - getroom(&qrbuf, configRoomName); - /* Do something really, really stoopid here. Raid the room on ourselves, - * loop through the messages manually and find it. I don't want - * to use a CtdlForEachMessage callback here, as we would be - * already in one */ - cdbfr = cdb_fetch(CDB_MSGLISTS, &qrbuf.QRnumber, sizeof(long)); - if (cdbfr != NULL) { - msglist = (long *) cdbfr->ptr; - cdbfr->ptr = NULL; /* CtdlForEachMessage() now owns this memory */ - num_msgs = cdbfr->len / sizeof(long); - cdb_free(cdbfr); - } else { - CtdlLogPrintf(CTDL_DEBUG, "extNotify_getConfigMessage: No config messages found\n"); - return -1; /* No messages at all? No further action. */ - } - int a; - for (a = 0; a < num_msgs; ++a) { - msg = CtdlFetchMessage(msglist[a], 1); - if (msg != NULL) { - if (msg->cm_fields['U'] != NULL && strncasecmp(msg->cm_fields['U'], PAGER_CONFIG_MESSAGE, - strlen(PAGER_CONFIG_MESSAGE)) == 0) { - confMsgNum = msglist[a]; - } - CtdlFreeMessage(msg); - } - } - return confMsgNum; + MailboxName(configRoomName, sizeof configRoomName, &user, USERCONFIGROOM); + // Fill qrbuf + getroom(&qrbuf, configRoomName); + /* Do something really, really stoopid here. Raid the room on ourselves, + * loop through the messages manually and find it. I don't want + * to use a CtdlForEachMessage callback here, as we would be + * already in one */ + cdbfr = cdb_fetch(CDB_MSGLISTS, &qrbuf.QRnumber, sizeof(long)); + if (cdbfr != NULL) { + msglist = (long *) cdbfr->ptr; + cdbfr->ptr = NULL; /* CtdlForEachMessage() now owns this memory */ + num_msgs = cdbfr->len / sizeof(long); + cdb_free(cdbfr); + } else { + CtdlLogPrintf(CTDL_DEBUG, "extNotify_getConfigMessage: No config messages found\n"); + return -1; /* No messages at all? No further action. */ + } + for (a = 0; a < num_msgs; ++a) { + msg = CtdlFetchMessage(msglist[a], 1); + if (msg != NULL) { + if ((msg->cm_fields['U'] != NULL) && + (strncasecmp(msg->cm_fields['U'], PAGER_CONFIG_MESSAGE, + strlen(PAGER_CONFIG_MESSAGE)) == 0)) { + confMsgNum = msglist[a]; + } + CtdlFreeMessage(msg); + } + } + return confMsgNum; } + CTDL_MODULE_INIT(extnotify) { if (!threading) diff --git a/citadel/modules/extnotify/funambol65.c b/citadel/modules/extnotify/funambol65.c index af46df28c..d4c13de6b 100644 --- a/citadel/modules/extnotify/funambol65.c +++ b/citadel/modules/extnotify/funambol65.c @@ -48,7 +48,7 @@ struct fh_data { * Returns 0 if unsuccessful */ int notify_http_server(char *remoteurl, - char* template, long tlen, + const char* template, long tlen, char *user, char *msgid, long MsgNum) @@ -63,7 +63,7 @@ int notify_http_server(char *remoteurl, struct curl_slist * headers=NULL; char errmsg[1024] = ""; char *SOAPMessage = NULL; - char *contenttype; + char *contenttype = NULL; struct fh_data fh = { retbuf, 0, @@ -114,8 +114,7 @@ int notify_http_server(char *remoteurl, const char *mimetype; Ftemplate = fopen(template, "r"); - mimetype = GuessMimeByFilename(template, tlen); - if (template == NULL) { + if (Ftemplate == NULL) { char buf[SIZ]; snprintf(buf, SIZ, @@ -126,6 +125,8 @@ int notify_http_server(char *remoteurl, aide_message(buf, "External notifier unable to find message template!"); goto free; } + mimetype = GuessMimeByFilename(template, tlen); + snprintf(msgnumstr, 128, "%ld", MsgNum); buf = malloc(SIZ); -- 2.30.2