X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fmodules%2Fextnotify%2Ffunambol65.c;h=bff95fbb49fc0c7b399e47303ab6f801e38603d3;hb=c855d497545dad80942a194624c111a54cd1fdc7;hp=2a9ee25408da2bee9a979a6378914f3478a3af90;hpb=1fd44d1efd6c40d142dffe76dea0026818ec102f;p=citadel.git diff --git a/citadel/modules/extnotify/funambol65.c b/citadel/modules/extnotify/funambol65.c index 2a9ee2540..bff95fbb4 100644 --- a/citadel/modules/extnotify/funambol65.c +++ b/citadel/modules/extnotify/funambol65.c @@ -1,14 +1,29 @@ /* -* \file funambol65.c -* @author Mathew McBride -* -* This module facilitates notifications to a Funambol server -* for push email -* -* Based on bits of the previous serv_funambol -* Contact: / -*/ -#include "extnotify.h" + * funambol65.c + * Author: Mathew McBride + * + * This module facilitates notifications to a Funambol server + * for push email + * + * Based on bits of the previous serv_funambol + * Contact: / + * + * Copyright (c) 2008-2010 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ #include #include @@ -16,110 +31,277 @@ #include #include #include +#include +#include +#include +#include "citadel.h" #include "citadel_dirs.h" #include "clientsocket.h" #include "sysdep.h" -#include "sysconfig.h" #include "config.h" #include "sysdep_decls.h" #include "msgbase.h" +#include "ctdl_module.h" + +#include "event_client.h" +#include "extnotify.h" + +eNextState EvaluateResult(AsyncIO *IO); +eNextState ExtNotifyTerminate(AsyncIO *IO); +eNextState ExtNotifyShutdownAbort(AsyncIO *IO); /* -* \brief Sends a message to the Funambol server notifying +* \brief Sends a message to the Funambol server notifying * of new mail for a user * Returns 0 if unsuccessful */ -int notify_funambol_server(char *user) { - char port[1024]; - int sock = -1; - char *buf; - char *SOAPMessage; - char *SOAPHeader; - char *funambolCreds; - FILE *template; - - sprintf(port, "%d", config.c_funambol_port); - sock = sock_connect(config.c_funambol_host, port, "tcp"); - if (sock >= 0) - lprintf(CTDL_DEBUG, "Connected to Funambol!\n"); - else - goto bail; - // Load the template SOAP message. Get mallocs done too - template = fopen(file_funambol_msg, "r"); - buf = malloc(SIZ); - memset(buf, 0, SIZ); - SOAPMessage = malloc(3072); - memset(SOAPMessage, 0, 3072); - - SOAPHeader = malloc(SIZ); - memset(SOAPHeader, 0, SIZ); - - funambolCreds = malloc(strlen(config.c_funambol_auth)*2); - memset(funambolCreds, 0, strlen(config.c_funambol_auth)*2); - - while(fgets(buf, SIZ, template) != NULL) { - strcat(SOAPMessage, buf); +int notify_http_server(char *remoteurl, + const char* template, long tlen, + char *user, + char *msgid, + long MsgNum, + NotifyContext *Ctx) +{ + CURLcode sta; + char msgnumstr[128]; + char *buf = NULL; + char *SOAPMessage = NULL; + char *contenttype = NULL; + StrBuf *ReplyBuf; + StrBuf *Buf; + CURL *chnd; + AsyncIO *IO; + + IO = (AsyncIO*) malloc(sizeof(AsyncIO)); + memset(IO, 0, sizeof(AsyncIO)); + + if (! InitcURLIOStruct(IO, + NULL, /* we don't have personal data anymore. */ + "Citadel ExtNotify", + EvaluateResult, + ExtNotifyTerminate, + ExtNotifyShutdownAbort)) + { + syslog(LOG_ALERT, "Unable to initialize libcurl.\n"); + goto abort; } - fclose(template); - - if (strlen(SOAPMessage) < 0) { - printf("Cannot load template file\r\n"); - goto free; + + snprintf(msgnumstr, 128, "%ld", MsgNum); + + if (tlen > 0) { + /* Load the template message. Get mallocs done too */ + FILE *Ftemplate = NULL; + const char *mimetype; + + Ftemplate = fopen(template, "r"); + if (Ftemplate == NULL) { + char buf[SIZ]; + + snprintf(buf, SIZ, + "Cannot load template file %s [%s] " + "won't send notification\r\n", + file_funambol_msg, + strerror(errno)); + syslog(LOG_ERR, "%s", buf); + // TODO: once an hour! + CtdlAideMessage( + buf, + "External notifier: " + "unable to find message template!"); + goto abort; + } + mimetype = GuessMimeByFilename(template, tlen); + + buf = malloc(SIZ); + memset(buf, 0, SIZ); + SOAPMessage = malloc(3072); + memset(SOAPMessage, 0, 3072); + + while(fgets(buf, SIZ, Ftemplate) != NULL) { + strcat(SOAPMessage, buf); + } + fclose(Ftemplate); + + if (strlen(SOAPMessage) < 0) { + char buf[SIZ]; + + snprintf(buf, SIZ, + "Cannot load template file %s;" + " won't send notification\r\n", + file_funambol_msg); + syslog(LOG_ERR, "%s", buf); + + CtdlAideMessage(buf, "External notifier: " + "unable to load message template!"); + goto abort; + } + // Do substitutions + help_subst(SOAPMessage, "^notifyuser", user); + help_subst(SOAPMessage, "^syncsource", + config.c_funambol_source); + help_subst(SOAPMessage, "^msgid", msgid); + help_subst(SOAPMessage, "^msgnum", msgnumstr); + + /* pass our list of custom made headers */ + + contenttype=(char*) malloc(40+strlen(mimetype)); + sprintf(contenttype, + "Content-Type: %s; charset=utf-8", + mimetype); + + IO->HttpReq.headers = curl_slist_append( + IO->HttpReq.headers, + "SOAPAction: \"\""); + + IO->HttpReq.headers = curl_slist_append( + IO->HttpReq.headers, + contenttype); + + IO->HttpReq.headers = curl_slist_append( + IO->HttpReq.headers, + "Accept: application/soap+xml, " + "application/mime, multipart/related, text/*"); + + IO->HttpReq.headers = curl_slist_append( + IO->HttpReq.headers, + "Pragma: no-cache"); + + /* Now specify the POST binary data */ + IO->HttpReq.PlainPostData = SOAPMessage; + IO->HttpReq.PlainPostDataLen = strlen(SOAPMessage); } - // Do substitutions - help_subst(SOAPMessage, "^notifyuser", user); - help_subst(SOAPMessage, "^syncsource", config.c_funambol_source); - - /* Build the HTTP request header */ - - - sprintf(SOAPHeader, "POST %s HTTP/1.0\r\nContent-type: text/xml; charset=utf-8\r\n", - FUNAMBOL_WS); - 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(SOAPMessage)); - strcat(SOAPHeader, buf); - - - - CtdlEncodeBase64(funambolCreds, config.c_funambol_auth, strlen(config.c_funambol_auth), 0); - - - sprintf(buf, "Authorization: Basic %s\r\n\r\n", - funambolCreds); - strcat(SOAPHeader, buf); - - sock_write(sock, SOAPHeader, strlen(SOAPHeader)); - sock_write(sock, SOAPMessage, strlen(SOAPMessage)); - sock_shutdown(sock, SHUT_WR); - - /* Response */ - lprintf(CTDL_DEBUG, "Awaiting response\n"); - if (sock_getln(sock, buf, SIZ) < 0) { - goto free; - } - lprintf(CTDL_DEBUG, "<%s\n", buf); - if (strncasecmp(buf, "HTTP/1.1 200 OK", strlen("HTTP/1.1 200 OK"))) { - - goto free; + else { + help_subst(remoteurl, "^notifyuser", user); + help_subst(remoteurl, "^syncsource", config.c_funambol_source); + help_subst(remoteurl, "^msgid", msgid); + help_subst(remoteurl, "^msgnum", msgnumstr); + + IO->HttpReq.headers = curl_slist_append( + IO->HttpReq.headers, + "Accept: application/soap+xml, " + "application/mime, multipart/related, text/*"); + + IO->HttpReq.headers = curl_slist_append( + IO->HttpReq.headers, + "Pragma: no-cache"); } - lprintf(CTDL_DEBUG, "Funambol notified\n"); -free: - if (funambolCreds != NULL) free(funambolCreds); + + Buf = NewStrBufPlain (remoteurl, -1); + ParseURL(&IO->ConnectMe, Buf, 80); + FreeStrBuf(&Buf); /* TODO: this is uncool... */ + CurlPrepareURL(IO->ConnectMe); + + chnd = IO->HttpReq.chnd; + OPT(SSL_VERIFYPEER, 0); + OPT(SSL_VERIFYHOST, 0); + + QueueCurlContext(IO); + + return 0; +abort: + + if (contenttype) free(contenttype); if (SOAPMessage != NULL) free(SOAPMessage); if (buf != NULL) free(buf); - if (SOAPHeader != NULL) free(SOAPHeader); -bail: - close(sock); + FreeStrBuf (&ReplyBuf); + return 1; +} + + +eNextState EvaluateResult(AsyncIO *IO) +{ + + if (IO->HttpReq.httpcode != 200) { + StrBuf *ErrMsg; + + syslog(LOG_ALERT, "libcurl error %ld: %s\n", + IO->HttpReq.httpcode, + IO->HttpReq.errdesc); + + ErrMsg = NewStrBufPlain( + HKEY("Error sending your Notification\n")); + StrBufAppendPrintf(ErrMsg, "\nlibcurl error %ld: \n\t\t%s\n", + IO->HttpReq.httpcode, + IO->HttpReq.errdesc); + + StrBufAppendBufPlain(ErrMsg, + HKEY("\nWas Trying to send: \n"), + 0); + + StrBufAppendBufPlain(ErrMsg, IO->ConnectMe->PlainUrl, -1, 0); + if (IO->HttpReq.PlainPostDataLen > 0) { + StrBufAppendBufPlain( + ErrMsg, + HKEY("\nThe Post document was: \n"), + 0); + StrBufAppendBufPlain(ErrMsg, + IO->HttpReq.PlainPostData, + IO->HttpReq.PlainPostDataLen, 0); + StrBufAppendBufPlain(ErrMsg, HKEY("\n\n"), 0); + } + if (StrLength(IO->HttpReq.ReplyData) > 0) { + StrBufAppendBufPlain( + ErrMsg, + HKEY("\n\nThe Serverreply was: \n\n"), + 0); + StrBufAppendBuf(ErrMsg, IO->HttpReq.ReplyData, 0); + } + else + StrBufAppendBufPlain( + ErrMsg, + HKEY("\n\nThere was no Serverreply.\n\n"), + 0); + ///ExtNotify_PutErrorMessage(Ctx, ErrMsg); + CtdlAideMessage(ChrPtr(ErrMsg), + "External notifier: " + "unable to contact notification host!"); + } + + syslog(LOG_DEBUG, "Funambol notified\n"); +/* + while ((Ctx.NotifyHostList != NULL) && (Ctx.NotifyHostList[i] != NULL)) + FreeStrBuf(&Ctx.NotifyHostList[i]); + + if (Ctx.NotifyErrors != NULL) + { + long len; + const char *Key; + HashPos *It; + void *vErr; + StrBuf *ErrMsg; + + It = GetNewHashPos(Ctx.NotifyErrors, 0); + while (GetNextHashPos(Ctx.NotifyErrors, + It, &len, &Key, &vErr) && + (vErr != NULL)) { + ErrMsg = (StrBuf*) vErr; + quickie_message("Citadel", NULL, NULL, + AIDEROOM, ChrPtr(ErrMsg), FMT_FIXED, + "Failed to notify external service about inbound mail"); + } + + DeleteHashPos(&It); + DeleteHash(&Ctx.NotifyErrors); + } +*/ + +//// curl_slist_free_all (headers); +/// curl_easy_cleanup(curl); + ///if (contenttype) free(contenttype); + ///if (SOAPMessage != NULL) free(SOAPMessage); + ///if (buf != NULL) free(buf); + ///FreeStrBuf (&ReplyBuf); return 0; } +eNextState ExtNotifyTerminate(AsyncIO *IO) +{ + free(IO); + return eAbort; +} +eNextState ExtNotifyShutdownAbort(AsyncIO *IO) +{ + free(IO); + return eAbort; +}