X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fmodules%2Fextnotify%2Ffunambol65.c;h=bff95fbb49fc0c7b399e47303ab6f801e38603d3;hb=c855d497545dad80942a194624c111a54cd1fdc7;hp=1c499446cadd638e856de5e84666c7459d663a3a;hpb=5aa754ca552f822b57d7a37b5ae0031ac94e1c61;p=citadel.git diff --git a/citadel/modules/extnotify/funambol65.c b/citadel/modules/extnotify/funambol65.c index 1c499446c..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 @@ -29,69 +44,50 @@ #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_http_server(char *remoteurl, - const char* template, long tlen, +int notify_http_server(char *remoteurl, + const char* template, long tlen, char *user, - char *msgid, - long MsgNum) + char *msgid, + long MsgNum, + NotifyContext *Ctx) { - char curl_errbuf[CURL_ERROR_SIZE]; - char *pchs, *pche; - char userpass[SIZ]; + CURLcode sta; char msgnumstr[128]; char *buf = NULL; - CURL *curl; - CURLcode res; - struct curl_slist * headers=NULL; - char errmsg[1024] = ""; char *SOAPMessage = NULL; char *contenttype = NULL; StrBuf *ReplyBuf; + StrBuf *Buf; + CURL *chnd; + AsyncIO *IO; - curl = curl_easy_init(); - if (!curl) { - CtdlLogPrintf(CTDL_ALERT, "Unable to initialize libcurl.\n"); - return 1; - } - - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0); - ReplyBuf = NewStrBuf(); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, ReplyBuf); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlFillStrBuf_callback); - curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errmsg); - curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); - curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_errbuf); - - pchs = strchr(remoteurl, ':'); - pche = strchr(remoteurl, '@'); - if ((pche != NULL) && - (pchs != NULL) && - (pchs < pche) && ((pche - pchs) < SIZ)) { - memcpy(userpass, pchs + 3, pche - pchs - 3); - - userpass[pche - pchs - 3] = '\0'; - curl_easy_setopt(curl, CURLOPT_HTTPAUTH, (long)CURLAUTH_BASIC); - curl_easy_setopt(curl, CURLOPT_USERPWD, userpass); + IO = (AsyncIO*) malloc(sizeof(AsyncIO)); + memset(IO, 0, sizeof(AsyncIO)); - } -#ifdef CURLOPT_HTTP_CONTENT_DECODING - curl_easy_setopt(curl, CURLOPT_HTTP_CONTENT_DECODING, 1); - curl_easy_setopt(curl, CURLOPT_ENCODING, ""); -#endif - curl_easy_setopt(curl, CURLOPT_USERAGENT, CITADEL); - curl_easy_setopt(curl, CURLOPT_TIMEOUT, 180); /* die after 180 seconds */ - if (!IsEmptyStr(config.c_ip_addr)) { - curl_easy_setopt(curl, CURLOPT_INTERFACE, config.c_ip_addr); + 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; } - headers = curl_slist_append(headers,"Accept: application/soap+xml, application/dime, multipart/related, text/*"); - headers = curl_slist_append(headers,"Pragma: no-cache"); + snprintf(msgnumstr, 128, "%ld", MsgNum); if (tlen > 0) { /* Load the template message. Get mallocs done too */ @@ -102,105 +98,210 @@ int notify_http_server(char *remoteurl, 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)); - CtdlLogPrintf(CTDL_ERR, buf); - - aide_message(buf, "External notifier unable to find message template!"); - goto free; + 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); - snprintf(msgnumstr, 128, "%ld", MsgNum); - 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", + snprintf(buf, SIZ, + "Cannot load template file %s;" + " won't send notification\r\n", file_funambol_msg); - CtdlLogPrintf(CTDL_ERR, buf); + syslog(LOG_ERR, "%s", buf); - aide_message(buf, "External notifier unable to load message template!"); - goto free; + 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, "^syncsource", + config.c_funambol_source); help_subst(SOAPMessage, "^msgid", msgid); help_subst(SOAPMessage, "^msgnum", msgnumstr); - curl_easy_setopt(curl, CURLOPT_URL, remoteurl); - /* pass our list of custom made headers */ contenttype=(char*) malloc(40+strlen(mimetype)); - sprintf(contenttype,"Content-type: %s; charset=utf-8", mimetype); + sprintf(contenttype, + "Content-Type: %s; charset=utf-8", + mimetype); - headers = curl_slist_append(headers, "SOAPAction: \"\""); - headers = curl_slist_append(headers, contenttype); + IO->HttpReq.headers = curl_slist_append( + IO->HttpReq.headers, + "SOAPAction: \"\""); - /* Now specify the POST binary data */ + IO->HttpReq.headers = curl_slist_append( + IO->HttpReq.headers, + contenttype); - curl_easy_setopt(curl, CURLOPT_POSTFIELDS, SOAPMessage); - curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strlen(SOAPMessage)); - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + 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); } else { help_subst(remoteurl, "^notifyuser", user); help_subst(remoteurl, "^syncsource", config.c_funambol_source); help_subst(remoteurl, "^msgid", msgid); help_subst(remoteurl, "^msgnum", msgnumstr); - curl_easy_setopt(curl, CURLOPT_URL, remoteurl); - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); - } - res = curl_easy_perform(curl); - if (res) { - StrBuf *ErrMsg; + IO->HttpReq.headers = curl_slist_append( + IO->HttpReq.headers, + "Accept: application/soap+xml, " + "application/mime, multipart/related, text/*"); - CtdlLogPrintf(CTDL_ALERT, "libcurl error %d: %s\n", res, errmsg); - ErrMsg = NewStrBufPlain(HKEY("Error sending your Notification\n")); - StrBufAppendPrintf(ErrMsg, "\nlibcurl error %d: %s\n", res, errmsg); - StrBufAppendBufPlain(ErrMsg, curl_errbuf, -1, 0); - StrBufAppendBufPlain(ErrMsg, HKEY("\nWas Trying to send: \n"), 0); - StrBufAppendBufPlain(ErrMsg, remoteurl, -1, 0); - if (tlen > 0) { - StrBufAppendBufPlain(ErrMsg, HKEY("\nThe Post document was: \n"), 0); - StrBufAppendBufPlain(ErrMsg, SOAPMessage, -1, 0); - StrBufAppendBufPlain(ErrMsg, HKEY("\n\n"), 0); - } - if (StrLength(ReplyBuf) > 0) { - StrBufAppendBufPlain(ErrMsg, HKEY("\n\nThe Serverreply was: \n\n"), 0); - StrBufAppendBuf(ErrMsg, ReplyBuf, 0); - } - else - StrBufAppendBufPlain(ErrMsg, HKEY("\n\nThere was no Serverreply.\n\n"), 0); -/* TODO: this will change the floor we're in :( - quickie_message("Citadel", NULL, NULL, AIDEROOM, ChrPtr(ErrMsg), FMT_FIXED, - "Failed to notify external service about inbound mail"); -*/ - FreeStrBuf(&ErrMsg); + IO->HttpReq.headers = curl_slist_append( + IO->HttpReq.headers, + "Pragma: no-cache"); } - CtdlLogPrintf(CTDL_DEBUG, "Funambol notified\n"); -free: - curl_slist_free_all (headers); - curl_easy_cleanup(curl); + 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); 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; +}