3 * Author: Mathew McBride
5 * This module facilitates notifications to a Funambol server
8 * Based on bits of the previous serv_funambol
9 * Contact: <matt@mcbridematt.dhs.org> / <matt@comalies>
11 * Copyright (c) 2008-2010
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 3 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 #include <sys/socket.h>
33 #include <libcitadel.h>
36 #include <curl/curl.h>
39 #include "citadel_dirs.h"
40 #include "clientsocket.h"
43 #include "sysdep_decls.h"
45 #include "ctdl_module.h"
47 #include "extnotify.h"
50 * \brief Sends a message to the Funambol server notifying
51 * of new mail for a user
52 * Returns 0 if unsuccessful
54 int notify_http_server(char *remoteurl,
55 const char* template, long tlen,
61 char curl_errbuf[CURL_ERROR_SIZE];
68 struct curl_slist * headers=NULL;
69 char errmsg[1024] = "";
70 char *SOAPMessage = NULL;
71 char *contenttype = NULL;
74 curl = curl_easy_init();
76 syslog(LOG_ALERT, "Unable to initialize libcurl.\n");
80 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
81 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
82 ReplyBuf = NewStrBuf();
83 curl_easy_setopt(curl, CURLOPT_WRITEDATA, ReplyBuf);
84 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlFillStrBuf_callback);
85 curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errmsg);
86 curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
87 curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_errbuf);
89 pchs = strchr(remoteurl, ':');
90 pche = strchr(remoteurl, '@');
93 (pchs < pche) && ((pche - pchs) < SIZ)) {
94 memcpy(userpass, pchs + 3, pche - pchs - 3);
96 userpass[pche - pchs - 3] = '\0';
97 curl_easy_setopt(curl, CURLOPT_HTTPAUTH, (long)CURLAUTH_BASIC);
98 curl_easy_setopt(curl, CURLOPT_USERPWD, userpass);
101 #ifdef CURLOPT_HTTP_CONTENT_DECODING
102 curl_easy_setopt(curl, CURLOPT_HTTP_CONTENT_DECODING, 1);
103 curl_easy_setopt(curl, CURLOPT_ENCODING, "");
105 curl_easy_setopt(curl, CURLOPT_USERAGENT, CITADEL);
106 curl_easy_setopt(curl, CURLOPT_TIMEOUT, 180); /* die after 180 seconds */
108 (!IsEmptyStr(config.c_ip_addr))
109 && (strcmp(config.c_ip_addr, "*"))
110 && (strcmp(config.c_ip_addr, "::"))
111 && (strcmp(config.c_ip_addr, "0.0.0.0"))
113 curl_easy_setopt(curl, CURLOPT_INTERFACE, config.c_ip_addr);
116 headers = curl_slist_append(headers,"Accept: application/soap+xml, application/mime, multipart/related, text/*");
117 headers = curl_slist_append(headers,"Pragma: no-cache");
120 /* Load the template message. Get mallocs done too */
121 FILE *Ftemplate = NULL;
122 const char *mimetype;
124 Ftemplate = fopen(template, "r");
125 if (Ftemplate == NULL) {
129 "Cannot load template file %s [%s]won't send notification\r\n",
130 file_funambol_msg, strerror(errno));
131 syslog(LOG_ERR, buf);
133 CtdlAideMessage(buf, "External notifier unable to find message template!");
136 mimetype = GuessMimeByFilename(template, tlen);
138 snprintf(msgnumstr, 128, "%ld", MsgNum);
142 SOAPMessage = malloc(3072);
143 memset(SOAPMessage, 0, 3072);
145 while(fgets(buf, SIZ, Ftemplate) != NULL) {
146 strcat(SOAPMessage, buf);
150 if (strlen(SOAPMessage) < 0) {
154 "Cannot load template file %s; won't send notification\r\n",
156 syslog(LOG_ERR, buf);
158 CtdlAideMessage(buf, "External notifier unable to load message template!");
162 help_subst(SOAPMessage, "^notifyuser", user);
163 help_subst(SOAPMessage, "^syncsource", config.c_funambol_source);
164 help_subst(SOAPMessage, "^msgid", msgid);
165 help_subst(SOAPMessage, "^msgnum", msgnumstr);
167 curl_easy_setopt(curl, CURLOPT_URL, remoteurl);
169 /* pass our list of custom made headers */
171 contenttype=(char*) malloc(40+strlen(mimetype));
172 sprintf(contenttype,"Content-Type: %s; charset=utf-8", mimetype);
174 headers = curl_slist_append(headers, "SOAPAction: \"\"");
175 headers = curl_slist_append(headers, contenttype);
177 /* Now specify the POST binary data */
179 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, SOAPMessage);
180 curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strlen(SOAPMessage));
181 curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
184 help_subst(remoteurl, "^notifyuser", user);
185 help_subst(remoteurl, "^syncsource", config.c_funambol_source);
186 help_subst(remoteurl, "^msgid", msgid);
187 help_subst(remoteurl, "^msgnum", msgnumstr);
188 curl_easy_setopt(curl, CURLOPT_URL, remoteurl);
189 curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
192 res = curl_easy_perform(curl);
196 syslog(LOG_ALERT, "libcurl error %d: %s\n", res, errmsg);
197 ErrMsg = NewStrBufPlain(HKEY("Error sending your Notification\n"));
198 StrBufAppendPrintf(ErrMsg, "\nlibcurl error %d: %s\n", res, errmsg);
199 StrBufAppendBufPlain(ErrMsg, curl_errbuf, -1, 0);
200 StrBufAppendBufPlain(ErrMsg, HKEY("\nWas Trying to send: \n"), 0);
201 StrBufAppendBufPlain(ErrMsg, remoteurl, -1, 0);
203 StrBufAppendBufPlain(ErrMsg, HKEY("\nThe Post document was: \n"), 0);
204 StrBufAppendBufPlain(ErrMsg, SOAPMessage, -1, 0);
205 StrBufAppendBufPlain(ErrMsg, HKEY("\n\n"), 0);
207 if (StrLength(ReplyBuf) > 0) {
208 StrBufAppendBufPlain(ErrMsg, HKEY("\n\nThe Serverreply was: \n\n"), 0);
209 StrBufAppendBuf(ErrMsg, ReplyBuf, 0);
212 StrBufAppendBufPlain(ErrMsg, HKEY("\n\nThere was no Serverreply.\n\n"), 0);
213 ExtNotify_PutErrorMessage(Ctx, ErrMsg);
216 syslog(LOG_DEBUG, "Funambol notified\n");
218 curl_slist_free_all (headers);
219 curl_easy_cleanup(curl);
220 if (contenttype) free(contenttype);
221 if (SOAPMessage != NULL) free(SOAPMessage);
222 if (buf != NULL) free(buf);
223 FreeStrBuf (&ReplyBuf);