X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fmodules%2Fextnotify%2Fextnotify_main.c;h=8eafc036a61b09e39fbbd54583cc2768dd59e10c;hb=55013f95f08eafe1b375df4241e8defe387c6cdc;hp=aa85ab610fdc9d05317f588bf7632ad1d9320069;hpb=0428f9c321bffd2afbd5c41c1170b74d240a5c64;p=citadel.git diff --git a/citadel/modules/extnotify/extnotify_main.c b/citadel/modules/extnotify/extnotify_main.c index aa85ab610..8eafc036a 100644 --- a/citadel/modules/extnotify/extnotify_main.c +++ b/citadel/modules/extnotify/extnotify_main.c @@ -77,10 +77,10 @@ void ExtNotify_PutErrorMessage(NotifyContext *Ctx, StrBuf *ErrMsg) Ctx->NotifyErrors = NewHash(1, Flathash); nNext = GetCount(Ctx->NotifyErrors) + 1; - Put(Ctx->NotifyErrors, - (char*)&nNext, - sizeof(int), - ErrMsg, + Put(Ctx->NotifyErrors, + (char*)&nNext, + sizeof(int), + ErrMsg, HFreeStrBuf); } @@ -107,20 +107,24 @@ int GetNotifyHosts(NotifyContext *Ctx) if (Ctx->nNotifyHosts < 1) return 0; - Ctx->NotifyHostList = malloc(sizeof(StrBuf*) * 2 * (Ctx->nNotifyHosts + 1)); - memset(Ctx->NotifyHostList, 0, sizeof(StrBuf*) * 2 * (Ctx->nNotifyHosts + 1)); - + Ctx->NotifyHostList = malloc(sizeof(StrBuf*) * + 2 * + (Ctx->nNotifyHosts + 1)); + memset(Ctx->NotifyHostList, 0, + sizeof(StrBuf*) * 2 * (Ctx->nNotifyHosts + 1)); + NotifyBuf = NewStrBufPlain(NotifyHostsBuf, -1); /* get all configured notifiers's */ - for (notify=0; notifynNotifyHosts; notify++) { - + for (notify=0; notifynNotifyHosts; notify++) { + Host = GetNHBuf(notify * 2, 1, Ctx->NotifyHostList); StrBufExtract_NextToken(Host, NotifyBuf, &NextHost, '|'); pchs = ChrPtr(Host); pche = strchr(pchs, ':'); if (pche == NULL) { - syslog(LOG_ERR, - "extnotify: filename of notification template not found in %s.\n", + syslog(LOG_ERR, + "extnotify: filename of notification " + "template not found in %s.\n", pchs); continue; } @@ -137,7 +141,9 @@ int GetNotifyHosts(NotifyContext *Ctx) /*! \brief Get configuration message for pager/funambol system from the * users "My Citadel Config" room */ -eNotifyType extNotify_getConfigMessage(char *username, char **PagerNumber, char **FreeMe) +eNotifyType extNotify_getConfigMessage(char *username, + char **PagerNumber, + char **FreeMe) { struct ctdlroom qrbuf; // scratch for room struct ctdluser user; // ctdl user instance @@ -148,12 +154,16 @@ eNotifyType extNotify_getConfigMessage(char *username, char **PagerNumber, char int num_msgs = 0; int a; char *configMsg; + long clen; char *pch; // Get the user CtdlGetUser(&user, username); - - CtdlMailboxName(configRoomName, sizeof configRoomName, &user, USERCONFIGROOM); + + CtdlMailboxName(configRoomName, + sizeof(configRoomName), + &user, + USERCONFIGROOM); // Fill qrbuf CtdlGetRoom(&qrbuf, configRoomName); /* Do something really, really stoopid here. Raid the room on ourselves, @@ -163,26 +173,31 @@ eNotifyType extNotify_getConfigMessage(char *username, char **PagerNumber, char cdbfr = cdb_fetch(CDB_MSGLISTS, &qrbuf.QRnumber, sizeof(long)); if (cdbfr != NULL) { msglist = (long *) cdbfr->ptr; - cdbfr->ptr = NULL; /* CtdlForEachMessage() now owns this memory */ + cdbfr->ptr = NULL; + /* CtdlForEachMessage() now owns this memory */ num_msgs = cdbfr->len / sizeof(long); cdb_free(cdbfr); } else { - syslog(LOG_DEBUG, "extNotify_getConfigMessage: No config messages found\n"); + syslog(LOG_DEBUG, + "extNotify_getConfigMessage: " + "No config messages found\n"); return eNone; /* 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)) { + if (!CM_IsEmpty(msg, eMsgSubject) && + (strncasecmp(msg->cm_fields[eMsgSubject], + PAGER_CONFIG_MESSAGE, + strlen(PAGER_CONFIG_MESSAGE)) == 0)) + { break; } - CtdlFreeMessage(msg); + CM_Free(msg); msg = NULL; } } - + free(msglist); if (msg == NULL) return eNone; @@ -190,9 +205,8 @@ eNotifyType extNotify_getConfigMessage(char *username, char **PagerNumber, char // 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. - configMsg = msg->cm_fields['M']; - msg->cm_fields['M'] = NULL; - CtdlFreeMessage(msg); + CM_GetAsField(msg, eMesageText, &configMsg, &clen); + CM_Free(msg); /* here we would find the pager number... */ pch = strchr(configMsg, '\n'); @@ -230,10 +244,10 @@ eNotifyType extNotify_getConfigMessage(char *username, char **PagerNumber, char if (!pch || (*pch == '\0')) { free(configMsg); - + return eNone; } - while (isspace(*pch)) + while (isspace(*pch)) pch ++; *PagerNumber = pch; while (isdigit(*pch) || (*pch == '+')) @@ -251,7 +265,7 @@ eNotifyType extNotify_getConfigMessage(char *username, char **PagerNumber, char /* * Process messages in the external notification queue */ -void process_notify(long NotifyMsgnum, void *usrdata) +void process_notify(long NotifyMsgnum, void *usrdata) { NotifyContext *Ctx; long msgnum = 0; @@ -262,17 +276,19 @@ void process_notify(long NotifyMsgnum, void *usrdata) char remoteurl[SIZ]; char *FreeMe = NULL; char *PagerNo; - CitContext *SubC; Ctx = (NotifyContext*) usrdata; msg = CtdlFetchMessage(NotifyMsgnum, 1); - if ( msg->cm_fields['W'] != NULL) + if (!CM_IsEmpty(msg, eExtnotify)) { - Type = extNotify_getConfigMessage(msg->cm_fields['W'], &PagerNo, &FreeMe); - - pch = strstr(msg->cm_fields['M'], "msgid|"); - if (pch != NULL) + Type = extNotify_getConfigMessage( + msg->cm_fields[eExtnotify], + &PagerNo, + &FreeMe); + + pch = strstr(msg->cm_fields[eMesageText], "msgid|"); + if (pch != NULL) msgnum = atol(pch + sizeof("msgid")); switch (Type) @@ -284,15 +300,12 @@ void process_notify(long NotifyMsgnum, void *usrdata) config.c_funambol_port, FUNAMBOL_WS); - SubC = CloneContext (CC); - SubC->session_specific_data = NULL;// (char*) DupNotifyContext(Ctx); - - notify_http_server(remoteurl, + notify_http_server(remoteurl, file_funambol_msg, strlen(file_funambol_msg),/*GNA*/ - msg->cm_fields['W'], - msg->cm_fields['I'], - msgnum, + msg->cm_fields[eExtnotify], + msg->cm_fields[emessageId], + msgnum, NULL); break; case eHttpMessages: @@ -302,44 +315,53 @@ void process_notify(long NotifyMsgnum, void *usrdata) char URLBuf[SIZ]; StrBuf *File; StrBuf *FileBuf = NewStrBuf(); - + for (i = 0; i < Ctx->nNotifyHosts; i++) { URL = GetNHBuf(i*2, 0, Ctx->NotifyHostList); if (URL==NULL) break; - File = GetNHBuf(i*2 + 1, 0, Ctx->NotifyHostList); + File = GetNHBuf(i*2 + 1, 0, + Ctx->NotifyHostList); if (File==NULL) break; if (StrLength(File)>0) - StrBufPrintf(FileBuf, "%s/%s", - ctdl_shared_dir, + StrBufPrintf(FileBuf, "%s/%s", + ctdl_shared_dir, ChrPtr(File)); else FlushStrBuf(FileBuf); memcpy(URLBuf, ChrPtr(URL), StrLength(URL) + 1); - SubC = CloneContext (CC); - SubC->session_specific_data = NULL;// (char*) DupNotifyContext(Ctx); - notify_http_server(URLBuf, + notify_http_server(URLBuf, ChrPtr(FileBuf), StrLength(FileBuf), - msg->cm_fields['W'], - msg->cm_fields['I'], - msgnum, + msg->cm_fields[eExtnotify], + msg->cm_fields[emessageId], + msgnum, NULL); } FreeStrBuf(&FileBuf); - } + } break; case eTextMessage: { int commandSiz; char *command; - commandSiz = sizeof(config.c_pager_program) + strlen(PagerNo) + strlen(msg->cm_fields['W']) + 5; + commandSiz = sizeof(config.c_pager_program) + + strlen(PagerNo) + + msg->cm_lengths[eExtnotify] + 5; + command = malloc(commandSiz); - snprintf(command, commandSiz, "%s %s -u %s", config.c_pager_program, PagerNo, msg->cm_fields['W']); + + snprintf(command, + commandSiz, + "%s %s -u %s", + config.c_pager_program, + PagerNo, + msg->cm_fields[eExtnotify]); + system(command); free(command); } @@ -350,7 +372,7 @@ void process_notify(long NotifyMsgnum, void *usrdata) } if (FreeMe != NULL) free(FreeMe); - CtdlFreeMessage(msg); + CM_Free(msg); todelete[0] = NotifyMsgnum; CtdlDeleteMessages(FNBL_QUEUE_ROOM, todelete, 1, ""); } @@ -359,29 +381,33 @@ void process_notify(long NotifyMsgnum, void *usrdata) * \brief Run through the pager room queue * Checks to see what notification option the user has set */ -void do_extnotify_queue(void) +void do_extnotify_queue(void) { NotifyContext Ctx; static int doing_queue = 0; int i = 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 (IsEmptyStr(config.c_pager_program) && + if (IsEmptyStr(config.c_pager_program) && IsEmptyStr(config.c_funambol_host)) { - syslog(LOG_ERR, "No external notifiers configured on system/user\n"); + syslog(LOG_ERR, + "No external notifiers configured on system/user\n"); return; } - if (doing_queue) return; + if (doing_queue) + return; + doing_queue = 1; + become_session(&extnotify_queue_CC); + pthread_setspecific(MyConKey, (void *)&extnotify_queue_CC); /* @@ -390,7 +416,7 @@ void do_extnotify_queue(void) syslog(LOG_DEBUG, "serv_extnotify: processing notify queue\n"); memset(&Ctx, 0, sizeof(NotifyContext)); - if ((GetNotifyHosts(&Ctx) > 0) && + if ((GetNotifyHosts(&Ctx) > 0) && (CtdlGetRoom(&CC->room, FNBL_QUEUE_ROOM) != 0)) { syslog(LOG_ERR, "Cannot find room <%s>\n", FNBL_QUEUE_ROOM); @@ -424,11 +450,11 @@ void do_extnotify_queue(void) */ void create_extnotify_queue(void) { struct ctdlroom qrbuf; - - CtdlCreateRoom(FNBL_QUEUE_ROOM, 3, "", 0, 1, 0, VIEW_MAILBOX); - CtdlFillSystemContext(&extnotify_queue_CC, "Extnotify"); - + CtdlCreateRoom(FNBL_QUEUE_ROOM, 3, "", 0, 1, 0, VIEW_QUEUE); + + CtdlFillSystemContext(&extnotify_queue_CC, "Extnotify"); + /* * Make sure it's set to be a "system room" so it doesn't show up * in the nown rooms list for Aides. @@ -439,14 +465,58 @@ void create_extnotify_queue(void) { } } +int extnotify_after_mbox_save(struct CtdlMessage *msg, + recptypes *recps) + +{ + /* If this is private, local mail, make a copy in the + * recipient's mailbox and bump the reference count. + */ + if (!IsEmptyStr(config.c_funambol_host) || !IsEmptyStr(config.c_pager_program)) + { + /* Generate a instruction message for the Funambol notification + * server, in the same style as the SMTP queue + */ + StrBuf *instr; + struct CtdlMessage *imsg; + + instr = NewStrBufPlain(NULL, 1024); + StrBufPrintf(instr, + "Content-type: "SPOOLMIME"\n" + "\n" + "msgid|%s\n" + "submitted|%ld\n" + "bounceto|%s\n", + msg->cm_fields[eVltMsgNum], + (long)time(NULL), //todo: time() is expensive! + recps->bounce_to + ); + + 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; + CM_SetField(imsg, eMsgSubject, HKEY("QMSG")); + CM_SetField(imsg, eAuthor, HKEY("Citadel")); + CM_SetField(imsg, eJournal, HKEY("do not journal")); + CM_SetAsFieldSB(imsg, eMesageText, &instr); + CM_SetField(imsg, eExtnotify, recps->recp_local, strlen(recps->recp_local)); + CtdlSubmitMsg(imsg, NULL, FNBL_QUEUE_ROOM, 0); + CM_Free(imsg); + } + return 0; +} CTDL_MODULE_INIT(extnotify) { if (!threading) { create_extnotify_queue(); - CtdlRegisterSessionHook(do_extnotify_queue, EVT_TIMER); + CtdlRegisterMessageHook(extnotify_after_mbox_save, EVT_AFTERUSRMBOXSAVE); + + CtdlRegisterSessionHook(do_extnotify_queue, EVT_TIMER, PRIO_SEND + 10); } /* return our module name for the log */ - return "extnotify"; + return "extnotify"; }