X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fmodules%2Fextnotify%2Ffunambol65.c;h=328dc9e7cc43e402d771d4851f4ea5abe98824c7;hb=8c47559cb5ae97ec0fa35660ee16fd61a9451c72;hp=96b9008db241d5bbb54096d4bc11e4ab1f4edc7e;hpb=a2fda4eafb51bbf58c04471522aa2d0f116c797e;p=citadel.git diff --git a/citadel/modules/extnotify/funambol65.c b/citadel/modules/extnotify/funambol65.c index 96b9008db..328dc9e7c 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-2009 + * + * 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,6 +31,9 @@ #include #include #include +#include +#include +#include #include "citadel.h" #include "citadel_dirs.h" @@ -26,101 +44,177 @@ #include "msgbase.h" #include "ctdl_module.h" +#include "extnotify.h" + /* * \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) - CtdlLogPrintf(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) +{ + char curl_errbuf[CURL_ERROR_SIZE]; + char *pchs, *pche; + char userpass[SIZ]; + 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; + + curl = curl_easy_init(); + if (!curl) { + CtdlLogPrintf(CTDL_ALERT, "Unable to initialize libcurl.\n"); + return 1; } - fclose(template); - - if (strlen(SOAPMessage) < 0) { - printf("Cannot load template file\r\n"); - goto free; + + 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); + + } +#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); } - // 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); - - + headers = curl_slist_append(headers,"Accept: application/soap+xml, application/mime, multipart/related, text/*"); + headers = curl_slist_append(headers,"Pragma: no-cache"); - 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); + 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)); + CtdlLogPrintf(CTDL_ERR, buf); + + aide_message(buf, "External notifier unable to find message template!"); + goto free; + } + mimetype = GuessMimeByFilename(template, tlen); + + snprintf(msgnumstr, 128, "%ld", MsgNum); + + buf = malloc(SIZ); + memset(buf, 0, SIZ); + SOAPMessage = malloc(3072); + memset(SOAPMessage, 0, 3072); - sock_write(sock, SOAPHeader, strlen(SOAPHeader)); - sock_write(sock, SOAPMessage, strlen(SOAPMessage)); - sock_shutdown(sock, SHUT_WR); + while(fgets(buf, SIZ, Ftemplate) != NULL) { + strcat(SOAPMessage, buf); + } + fclose(Ftemplate); - /* Response */ - CtdlLogPrintf(CTDL_DEBUG, "Awaiting response\n"); - if (sock_getln(sock, buf, SIZ) < 0) { - goto free; - } - CtdlLogPrintf(CTDL_DEBUG, "<%s\n", buf); - if (strncasecmp(buf, "HTTP/1.1 200 OK", strlen("HTTP/1.1 200 OK"))) { - - goto free; + if (strlen(SOAPMessage) < 0) { + char buf[SIZ]; + + snprintf(buf, SIZ, + "Cannot load template file %s; won't send notification\r\n", + file_funambol_msg); + CtdlLogPrintf(CTDL_ERR, buf); + + aide_message(buf, "External notifier unable to load message template!"); + goto free; + } + // 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); + + 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); + + headers = curl_slist_append(headers, "SOAPAction: \"\""); + headers = curl_slist_append(headers, contenttype); + + /* Now specify the POST binary data */ + + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, SOAPMessage); + curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strlen(SOAPMessage)); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + } + 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; + + 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); + ExtNotify_PutErrorMessage(Ctx, ErrMsg); + } + CtdlLogPrintf(CTDL_DEBUG, "Funambol notified\n"); free: - if (funambolCreds != NULL) free(funambolCreds); + curl_slist_free_all (headers); + curl_easy_cleanup(curl); + 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 0; } -