assert(IO->Terminate);
IO->Terminate(IO);
-
- Ctx->state = CON_IDLE;
- Ctx->kill_me = 1;
}
void
return eSendReply;
}
+void DestructCAres(AsyncIO *IO);
void FreeAsyncIOContents(AsyncIO *IO)
{
+ CitContext *Ctx = IO->CitContext;
+
FreeStrBuf(&IO->IOBuf);
FreeStrBuf(&IO->SendBuf.Buf);
FreeStrBuf(&IO->RecvBuf.Buf);
+
+ DestructCAres(IO);
+
+ FreeURL(&IO->ConnectMe);
+ FreeStrBuf(&IO->HttpReq.ReplyData);
+
+ Ctx->state = CON_IDLE;
+ Ctx->kill_me = 1;
}
void StopClientWatchers(AsyncIO *IO)
{
+ ev_timer_stop (event_base, &IO->rw_timeout);
ev_timer_stop(event_base, &IO->conn_fail);
- ev_io_stop(event_base, &IO->conn_event);
ev_idle_stop(event_base, &IO->unwind_stack);
+ ev_io_stop(event_base, &IO->conn_event);
ev_io_stop(event_base, &IO->send_event);
ev_io_stop(event_base, &IO->recv_event);
- ev_timer_stop (event_base, &IO->rw_timeout);
close(IO->SendBuf.fd);
IO->SendBuf.fd = 0;
IO->RecvBuf.fd = 0;
}
assert(IO->Terminate);
IO->Terminate(IO);
- Ctx->state = CON_IDLE;
- Ctx->kill_me = 1;
}
ShutDownCLient(IO);
default:
break;
-
}
default:
break;
IO->IOBuf = NewStrBuf();
}
+
+extern int evcurl_init(AsyncIO *IO);
+
+int InitcURLIOStruct(AsyncIO *IO,
+ void *Data,
+ const char* Desc,
+ IO_CallBack SendDone,
+ IO_CallBack Terminate,
+ IO_CallBack ShutdownAbort)
+{
+ IO->Data = Data;
+
+ IO->CitContext = CloneContext(CC);
+ ((CitContext *)IO->CitContext)->session_specific_data = (char*) Data;
+
+ IO->SendDone = SendDone;
+ IO->Terminate = Terminate;
+ IO->ShutdownAbort = ShutdownAbort;
+
+ strcpy(IO->HttpReq.errdesc, Desc);
+
+
+ return evcurl_init(IO);
+
+}
syslog(LOG_ERR, "error setting option " #s " on curl handle: %s", curl_easy_strerror(sta)); \
} } while (0)
-int evcurl_init(AsyncIO *IO,
- void *CustomData,
- const char* Desc,
- IO_CallBack CallBack,
- IO_CallBack Terminate,
- IO_CallBack ShutdownAbort);
-
void InitIOStruct(AsyncIO *IO,
void *Data,
eNextState NextState,
IO_CallBack Timeout,
IO_CallBack ShutdownAbort);
+int InitcURLIOStruct(AsyncIO *IO,
+ void *Data,
+ const char* Desc,
+ IO_CallBack SendDone,
+ IO_CallBack Terminate,
+ IO_CallBack ShutdownAbort);
+
eNextState ReAttachIO(AsyncIO *IO,
void *pData,
int ReadFirst);
ev_idle_stop(event_base, &IO->unwind_stack);
}
+void DestructCAres(AsyncIO *IO)
+{
+ ares_destroy_options(&IO->DNS.Options);
+}
+
void InitC_ares_dns(AsyncIO *IO)
{
return;
}
-
-
-
-int evcurl_init(AsyncIO *IO,
- void *CustomData,
- const char* Desc,
- IO_CallBack CallBack,
- IO_CallBack Terminate,
- IO_CallBack ShutdownAbort)
+int evcurl_init(AsyncIO *IO)
{
CURLcode sta;
CURL *chnd;
EVM_syslog(LOG_DEBUG, "EVCURL: evcurl_init called ms\n");
IO->HttpReq.attached = 0;
- IO->SendDone = CallBack;
- IO->Terminate = Terminate;
- IO->ShutdownAbort = ShutdownAbort;
chnd = IO->HttpReq.chnd = curl_easy_init();
if (!chnd)
{
EVM_syslog(LOG_ERR, "EVCURL: error initializing curl handle\n");
- return 1;
+ return 0;
}
- strcpy(IO->HttpReq.errdesc, Desc);
-
OPT(VERBOSE, (long)1);
/* unset in production */
OPT(NOPROGRESS, 1L);
) {
OPT(INTERFACE, config.c_ip_addr);
}
- /* point to a structure that points back to the perl structure and stuff */
- EV_syslog(LOG_DEBUG, "EVCURL: Loading URL: %s\n", IO->ConnectMe->PlainUrl);
- OPT(URL, IO->ConnectMe->PlainUrl);
- if (StrLength(IO->ConnectMe->CurlCreds))
- {
- OPT(HTTPAUTH, (long)CURLAUTH_BASIC);
- OPT(USERPWD, ChrPtr(IO->ConnectMe->CurlCreds));
- }
+
#ifdef CURLOPT_HTTP_CONTENT_DECODING
OPT(HTTP_CONTENT_DECODING, 1);
OPT(ENCODING, "");
#endif
- if (StrLength(IO->HttpReq.PostData) > 0)
- {
- OPT(POSTFIELDS, ChrPtr(IO->HttpReq.PostData));
- OPT(POSTFIELDSIZE, StrLength(IO->HttpReq.PostData));
-
- }
- else if ((IO->HttpReq.PlainPostDataLen != 0) && (IO->HttpReq.PlainPostData != NULL))
- {
- OPT(POSTFIELDS, IO->HttpReq.PlainPostData);
- OPT(POSTFIELDSIZE, IO->HttpReq.PlainPostDataLen);
- }
IO->HttpReq.headers = curl_slist_append(IO->HttpReq.headers, "Connection: close");
- OPT(HTTPHEADER, IO->HttpReq.headers);
return 1;
}
evcurl_handle_start(AsyncIO *IO)
{
CURLMcode msta;
+ CURLcode sta;
+ CURL *chnd;
+
+ chnd = IO->HttpReq.chnd;
+ EV_syslog(LOG_DEBUG, "EVCURL: Loading URL: %s\n", IO->ConnectMe->PlainUrl);
+ OPT(URL, IO->ConnectMe->PlainUrl);
+ if (StrLength(IO->ConnectMe->CurlCreds))
+ {
+ OPT(HTTPAUTH, (long)CURLAUTH_BASIC);
+ OPT(USERPWD, ChrPtr(IO->ConnectMe->CurlCreds));
+ }
+ if (StrLength(IO->HttpReq.PostData) > 0)
+ {
+ OPT(POSTFIELDS, ChrPtr(IO->HttpReq.PostData));
+ OPT(POSTFIELDSIZE, StrLength(IO->HttpReq.PostData));
+
+ }
+ else if ((IO->HttpReq.PlainPostDataLen != 0) && (IO->HttpReq.PlainPostData != NULL))
+ {
+ OPT(POSTFIELDS, IO->HttpReq.PlainPostData);
+ OPT(POSTFIELDSIZE, IO->HttpReq.PlainPostDataLen);
+ }
+ OPT(HTTPHEADER, IO->HttpReq.headers);
+
IO->NextState = eConnect;
EVM_syslog(LOG_DEBUG, "EVCURL: attaching to curl multi handle\n");
msta = curl_multi_add_handle(global.mhnd, IO->HttpReq.chnd);
DeleteHash(&InboundEventQueues[1]);
/* citthread_mutex_destroy(&EventQueueMutex); TODO */
evcurl_shutdown();
+ close(event_add_pipe[0]);
+ close(event_add_pipe[1]);
return(NULL);
}
DBInboundEventQueue = NULL;
DeleteHash(&DBInboundEventQueues[0]);
DeleteHash(&DBInboundEventQueues[1]);
+
+ close(evdb_add_pipe[0]);
+ close(evdb_add_pipe[1]);
/* citthread_mutex_destroy(&DBEventQueueMutex); TODO */
return(NULL);
CtdlRegisterCleanupHook(ShutDownEventQueues);
InitEventQueue();
DBInitEventQueue();
- CtdlThreadCreate(/*"Client event", */ client_event_thread);
- CtdlThreadCreate(/*"DB event", */db_event_thread);
-/// todo register shutdown callback.
+ CtdlThreadCreate(client_event_thread);
+ CtdlThreadCreate(db_event_thread);
}
return "event";
}
config.c_funambol_port,
FUNAMBOL_WS);
- SubC = CloneContext (CC);
- SubC->session_specific_data = NULL;// (char*) DupNotifyContext(Ctx);
-
notify_http_server(remoteurl,
file_funambol_msg,
strlen(file_funambol_msg),/*GNA*/
FlushStrBuf(FileBuf);
memcpy(URLBuf, ChrPtr(URL), StrLength(URL) + 1);
- SubC = CloneContext (CC);
- SubC->session_specific_data = NULL;// (char*) DupNotifyContext(Ctx);
notify_http_server(URLBuf,
ChrPtr(FileBuf),
StrLength(FileBuf),
* don't really require extremely fine granularity here, we'll do it
* with a static variable instead.
*/
-
if (IsEmptyStr(config.c_pager_program) &&
IsEmptyStr(config.c_funambol_host))
{
if (doing_queue) return;
doing_queue = 1;
+ become_session(&extnotify_queue_CC);
+
pthread_setspecific(MyConKey, (void *)&extnotify_queue_CC);
/*
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,
- NotifyContext *Ctx)
+ char *msgid,
+ long MsgNum,
+ NotifyContext *Ctx)
{
CURLcode sta;
char msgnumstr[128];
IO = (AsyncIO*) malloc(sizeof(AsyncIO));
memset(IO, 0, sizeof(AsyncIO));
- IO->CitContext = CloneContext(CC);
+
+ 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;
+ }
snprintf(msgnumstr, 128, "%ld", MsgNum);
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));
+ 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);
-
- CtdlAideMessage(buf, "External notifier unable to find message template!");
+ // TODO: once an hour!
+ CtdlAideMessage(
+ buf,
+ "External notifier: "
+ "unable to find message template!");
goto abort;
}
mimetype = GuessMimeByFilename(template, tlen);
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);
syslog(LOG_ERR, "%s", buf);
- CtdlAideMessage(buf, "External notifier unable to load message template!");
+ 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);
/* 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);
+
+ 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, "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");
+ 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;
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");
+
+ 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");
}
Buf = NewStrBufPlain (remoteurl, -1);
ParseURL(&IO->ConnectMe, Buf, 80);
FreeStrBuf(&Buf); /* TODO: this is uncool... */
CurlPrepareURL(IO->ConnectMe);
- if (! evcurl_init(IO,
-// Ctx,
- NULL,
- "Citadel ExtNotify",
- EvaluateResult,
- ExtNotifyTerminate,
- ExtNotifyShutdownAbort))
- {
- syslog(LOG_ALERT, "Unable to initialize libcurl.\n");
- goto abort;
- }
+
chnd = IO->HttpReq.chnd;
OPT(SSL_VERIFYPEER, 0);
OPT(SSL_VERIFYHOST, 0);
-/*
- ReplyBuf = NewStrBuf();
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, ReplyBuf);
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlFillStrBuf_callback);
-*/
- if (
- (!IsEmptyStr(config.c_ip_addr))
- && (strcmp(config.c_ip_addr, "*"))
- && (strcmp(config.c_ip_addr, "::"))
- && (strcmp(config.c_ip_addr, "0.0.0.0"))
- ) {
- OPT(INTERFACE, config.c_ip_addr);
- }
QueueCurlContext(IO);
return 0;
abort:
-/// curl_slist_free_all (headers);
-/// curl_easy_cleanup(curl);
+
if (contenttype) free(contenttype);
if (SOAPMessage != NULL) free(SOAPMessage);
if (buf != NULL) free(buf);
if (IO->HttpReq.httpcode != 200) {
StrBuf *ErrMsg;
- syslog(LOG_ALERT, "libcurl error %ld: %s\n",
- IO->HttpReq.httpcode,
+ 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,
+ 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,
+ 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,
+ StrBufAppendBufPlain(
+ ErrMsg,
+ HKEY("\nThe Post document was: \n"),
+ 0);
+ StrBufAppendBufPlain(ErrMsg,
+ IO->HttpReq.PlainPostData,
IO->HttpReq.PlainPostDataLen, 0);
- StrBufAppendBufPlain(ErrMsg, HKEY("\n\n"), 0);
+ StrBufAppendBufPlain(ErrMsg, HKEY("\n\n"), 0);
}
- if (StrLength(IO->HttpReq.ReplyData) > 0) {
- StrBufAppendBufPlain(ErrMsg, HKEY("\n\nThe Serverreply was: \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);
+ else
+ StrBufAppendBufPlain(
+ ErrMsg,
+ HKEY("\n\nThere was no Serverreply.\n\n"),
+ 0);
///ExtNotify_PutErrorMessage(Ctx, ErrMsg);
- CtdlAideMessage(ChrPtr(ErrMsg), "External notifier unable to load message template!");
+ CtdlAideMessage(ChrPtr(ErrMsg),
+ "External notifier: "
+ "unable to contact notification host!");
}
syslog(LOG_DEBUG, "Funambol notified\n");
StrBuf *ErrMsg;
It = GetNewHashPos(Ctx.NotifyErrors, 0);
- while (GetNextHashPos(Ctx.NotifyErrors, It, &len, &Key, &vErr) &&
+ 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");
+ quickie_message("Citadel", NULL, NULL,
+ AIDEROOM, ChrPtr(ErrMsg), FMT_FIXED,
+ "Failed to notify external service about inbound mail");
}
DeleteHashPos(&It);
#include "event_client.h"
#include "rss_atom_parser.h"
-extern pthread_mutex_t RSSQueueMutex;
-
-HashList *StartHandlers = NULL;
-HashList *EndHandlers = NULL;
-HashList *KnownNameSpaces = NULL;
-void AddRSSStartHandler(rss_handler_func Handler, int Flags, const char *key, long len)
-{
- rss_xml_handler *h;
- h = (rss_xml_handler*) malloc(sizeof (rss_xml_handler));
- h->Flags = Flags;
- h->Handler = Handler;
- Put(StartHandlers, key, len, h, NULL);
-}
-void AddRSSEndHandler(rss_handler_func Handler, int Flags, const char *key, long len)
-{
- rss_xml_handler *h;
- h = (rss_xml_handler*) malloc(sizeof (rss_xml_handler));
- h->Flags = Flags;
- h->Handler = Handler;
- Put(EndHandlers, key, len, h, NULL);
-}
-
+void rss_save_item(rss_item *ri, rss_aggregator *Cfg);
/*
FreeStrBuf(&ri->author_email);
FreeStrBuf(&ri->author_url);
FreeStrBuf(&ri->description);
-}
-
-void rss_xml_start(void *data, const char *supplied_el, const char **attr)
-{
- rss_xml_handler *h;
- rss_aggregator *rssc = (rss_aggregator*) data;
- rss_item *ri = rssc->Item;
- void *pv;
- const char *pel;
- char *sep = NULL;
- /* Axe the namespace, we don't care about it */
-/// syslog(LOG_DEBUG, "RSS: supplied el %d: %s...\n", rssc->Cfg->ItemType, supplied_el);
- pel = supplied_el;
- while (sep = strchr(pel, ':'), sep) {
- pel = sep + 1;
- }
-
- if (pel != supplied_el)
- {
- void *v;
-
- if (!GetHash(KnownNameSpaces,
- supplied_el,
- pel - supplied_el - 1,
- &v))
- {
-#ifdef DEBUG_RSS
- syslog(LOG_DEBUG, "RSS: START ignoring because of wrong namespace [%s]\n",
- supplied_el);
-#endif
- return;
- }
- }
-
- StrBufPlain(rssc->Key, pel, -1);
- StrBufLowerCase(rssc->Key);
- if (GetHash(StartHandlers, SKEY(rssc->Key), &pv))
- {
- rssc->Current = h = (rss_xml_handler*) pv;
-
- if (((h->Flags & RSS_UNSET) != 0) &&
- (rssc->ItemType == RSS_UNSET))
- {
- h->Handler(rssc->CData, ri, rssc, attr);
- }
- else if (((h->Flags & RSS_RSS) != 0) &&
- (rssc->ItemType == RSS_RSS))
- {
- h->Handler(rssc->CData, ri, rssc, attr);
- }
- else if (((h->Flags & RSS_ATOM) != 0) &&
- (rssc->ItemType == RSS_ATOM))
- {
- h->Handler(rssc->CData, ri, rssc, attr);
- }
-#ifdef DEBUG_RSS
- else
- syslog(LOG_DEBUG, "RSS: START unhandled: [%s] [%s]...\n", pel, supplied_el);
-#endif
- }
-#ifdef DEBUG_RSS
- else
- syslog(LOG_DEBUG, "RSS: START unhandled: [%s] [%s]...\n", pel, supplied_el);
-#endif
-}
-
-void rss_xml_end(void *data, const char *supplied_el)
-{
- rss_xml_handler *h;
- rss_aggregator *rssc = (rss_aggregator*) data;
- rss_item *ri = rssc->Item;
- const char *pel;
- char *sep = NULL;
- void *pv;
-
- /* Axe the namespace, we don't care about it */
- pel = supplied_el;
- while (sep = strchr(pel, ':'), sep) {
- pel = sep + 1;
- }
-// syslog(LOG_DEBUG, "RSS: END %s...\n", el);
- if (pel != supplied_el)
- {
- void *v;
-
- if (!GetHash(KnownNameSpaces,
- supplied_el,
- pel - supplied_el - 1,
- &v))
- {
-#ifdef DEBUG_RSS
- syslog(LOG_DEBUG, "RSS: END ignoring because of wrong namespace [%s] = [%s]\n",
- supplied_el, ChrPtr(rssc->CData));
-#endif
- FlushStrBuf(rssc->CData);
- return;
- }
- }
-
- StrBufPlain(rssc->Key, pel, -1);
- StrBufLowerCase(rssc->Key);
- if (GetHash(EndHandlers, SKEY(rssc->Key), &pv))
- {
- h = (rss_xml_handler*) pv;
-
- if (((h->Flags & RSS_UNSET) != 0) &&
- (rssc->ItemType == RSS_UNSET))
- {
- h->Handler(rssc->CData, ri, rssc, NULL);
- }
- else if (((h->Flags & RSS_RSS) != 0) &&
- (rssc->ItemType == RSS_RSS))
- {
- h->Handler(rssc->CData, ri, rssc, NULL);
- }
- else if (((h->Flags & RSS_ATOM) != 0) &&
- (rssc->ItemType == RSS_ATOM))
- {
- h->Handler(rssc->CData, ri, rssc, NULL);
- }
-#ifdef DEBUG_RSS
- else
- syslog(LOG_DEBUG, "RSS: END unhandled: [%s] [%s] = [%s]...\n", pel, supplied_el, ChrPtr(rssc->CData));
-#endif
- }
-#ifdef DEBUG_RSS
- else
- syslog(LOG_DEBUG, "RSS: END unhandled: [%s] [%s] = [%s]...\n", pel, supplied_el, ChrPtr(rssc->CData));
-#endif
- FlushStrBuf(rssc->CData);
- rssc->Current = NULL;
+ FreeStrBuf(&ri->linkTitle);
+ FreeStrBuf(&ri->reLink);
+ FreeStrBuf(&ri->reLinkTitle);
+ FreeStrBuf(&ri->channel_title);
}
-
+/*******************************************************************************
+ * XML-Handler *
+ *******************************************************************************/
void RSS_item_rss_start (StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, const char** Attr)
*/
void rss_xml_cdata_start(void *data)
{
- rss_aggregator *rssc = (rss_aggregator*) data;
+ rss_aggregator *RSSAggr = (rss_aggregator*) data;
- FlushStrBuf(rssc->CData);
+ FlushStrBuf(RSSAggr->CData);
}
void rss_xml_cdata_end(void *data)
}
void rss_xml_chardata(void *data, const XML_Char *s, int len)
{
- rss_aggregator *rssc = (rss_aggregator*) data;
+ rss_aggregator *RSSAggr = (rss_aggregator*) data;
+
+ StrBufAppendBufPlain (RSSAggr->CData, s, len, 0);
+}
+
+
+/*******************************************************************************
+ * RSS parser logic *
+ *******************************************************************************/
+
+extern pthread_mutex_t RSSQueueMutex;
+
+HashList *StartHandlers = NULL;
+HashList *EndHandlers = NULL;
+HashList *KnownNameSpaces = NULL;
+
+void FreeNetworkSaveMessage (void *vMsg)
+{
+ networker_save_message *Msg = (networker_save_message *) vMsg;
+
+ CtdlFreeMessageContents(&Msg->Msg);
+ FreeStrBuf(&Msg->Message);
+ FreeStrBuf(&Msg->MsgGUID);
+ free(Msg);
+}
+
- StrBufAppendBufPlain (rssc->CData, s, len, 0);
+void AppendLink(StrBuf *Message,
+ StrBuf *link,
+ StrBuf *LinkTitle,
+ const char *Title)
+{
+ if (StrLength(link) > 0)
+ {
+ StrBufAppendBufPlain(Message, HKEY("<a href=\""), 0);
+ StrBufAppendBuf(Message, link, 0);
+ StrBufAppendBufPlain(Message, HKEY("\">"), 0);
+ if (StrLength(LinkTitle) > 0)
+ StrBufAppendBuf(Message, LinkTitle, 0);
+ else if ((Title != NULL) && !IsEmptyStr(Title))
+ StrBufAppendBufPlain(Message, Title, -1, 0);
+ else
+ StrBufAppendBuf(Message, link, 0);
+ StrBufAppendBufPlain(Message, HKEY("</a><br>\n"), 0);
+ }
}
/*
- * Callback function for passing libcurl's output to expat for parsing
+ * Commit a fetched and parsed RSS item to disk
*/
+void rss_save_item(rss_item *ri, rss_aggregator *Cfg)
+{
+ networker_save_message *SaveMsg;
+ struct MD5Context md5context;
+ u_char rawdigest[MD5_DIGEST_LEN];
+ int msglen = 0;
+ StrBuf *Message;
+ StrBuf *guid;
+ AsyncIO *IO = &Cfg->IO;
+ int n;
+
+
+ SaveMsg = (networker_save_message *) malloc(
+ sizeof(networker_save_message));
+ memset(SaveMsg, 0, sizeof(networker_save_message));
+
+ /* Construct a GUID to use in the S_USETABLE table.
+ * If one is not present in the item itself, make one up.
+ */
+ if (ri->guid != NULL) {
+ StrBufSpaceToBlank(ri->guid);
+ StrBufTrim(ri->guid);
+ guid = NewStrBufPlain(HKEY("rss/"));
+ StrBufAppendBuf(guid, ri->guid, 0);
+ }
+ else {
+ MD5Init(&md5context);
+ if (ri->title != NULL) {
+ MD5Update(&md5context,
+ (const unsigned char*)SKEY(ri->title));
+ }
+ if (ri->link != NULL) {
+ MD5Update(&md5context,
+ (const unsigned char*)SKEY(ri->link));
+ }
+ MD5Final(rawdigest, &md5context);
+ guid = NewStrBufPlain(NULL,
+ MD5_DIGEST_LEN * 2 + 12 /* _rss2ctdl*/);
+ StrBufHexEscAppend(guid, NULL, rawdigest, MD5_DIGEST_LEN);
+ StrBufAppendBufPlain(guid, HKEY("_rss2ctdl"), 0);
+ }
+
+ /* translate Item into message. */
+ EVM_syslog(LOG_DEBUG, "RSS: translating item...\n");
+ if (ri->description == NULL) ri->description = NewStrBufPlain(HKEY(""));
+ StrBufSpaceToBlank(ri->description);
+ SaveMsg->Msg.cm_magic = CTDLMESSAGE_MAGIC;
+ SaveMsg->Msg.cm_anon_type = MES_NORMAL;
+ SaveMsg->Msg.cm_format_type = FMT_RFC822;
+
+ if (ri->guid != NULL) {
+ SaveMsg->Msg.cm_fields['E'] = strdup(ChrPtr(ri->guid));
+ }
+
+ if (ri->author_or_creator != NULL) {
+ char *From;
+ StrBuf *Encoded = NULL;
+ int FromAt;
+
+ From = html_to_ascii(ChrPtr(ri->author_or_creator),
+ StrLength(ri->author_or_creator),
+ 512, 0);
+ StrBufPlain(ri->author_or_creator, From, -1);
+ StrBufTrim(ri->author_or_creator);
+ free(From);
+
+ FromAt = strchr(ChrPtr(ri->author_or_creator), '@') != NULL;
+ if (!FromAt && StrLength (ri->author_email) > 0)
+ {
+ StrBufRFC2047encode(&Encoded, ri->author_or_creator);
+ SaveMsg->Msg.cm_fields['A'] = SmashStrBuf(&Encoded);
+ SaveMsg->Msg.cm_fields['P'] =
+ SmashStrBuf(&ri->author_email);
+ }
+ else
+ {
+ if (FromAt)
+ {
+ SaveMsg->Msg.cm_fields['A'] =
+ SmashStrBuf(&ri->author_or_creator);
+ SaveMsg->Msg.cm_fields['P'] =
+ strdup(SaveMsg->Msg.cm_fields['A']);
+ }
+ else
+ {
+ StrBufRFC2047encode(&Encoded,
+ ri->author_or_creator);
+ SaveMsg->Msg.cm_fields['A'] =
+ SmashStrBuf(&Encoded);
+ SaveMsg->Msg.cm_fields['P'] =
+ strdup("rss@localhost");
+
+ }
+ if (ri->pubdate <= 0) {
+ ri->pubdate = time(NULL);
+ }
+ }
+ }
+ else {
+ SaveMsg->Msg.cm_fields['A'] = strdup("rss");
+ }
+
+ SaveMsg->Msg.cm_fields['N'] = strdup(NODENAME);
+ if (ri->title != NULL) {
+ long len;
+ char *Sbj;
+ StrBuf *Encoded, *QPEncoded;
+
+ QPEncoded = NULL;
+ StrBufSpaceToBlank(ri->title);
+ len = StrLength(ri->title);
+ Sbj = html_to_ascii(ChrPtr(ri->title), len, 512, 0);
+ len = strlen(Sbj);
+ if (Sbj[len - 1] == '\n')
+ {
+ len --;
+ Sbj[len] = '\0';
+ }
+ Encoded = NewStrBufPlain(Sbj, len);
+ free(Sbj);
+
+ StrBufTrim(Encoded);
+ StrBufRFC2047encode(&QPEncoded, Encoded);
+
+ SaveMsg->Msg.cm_fields['U'] = SmashStrBuf(&QPEncoded);
+ FreeStrBuf(&Encoded);
+ }
+ SaveMsg->Msg.cm_fields['T'] = malloc(64);
+ snprintf(SaveMsg->Msg.cm_fields['T'], 64, "%ld", ri->pubdate);
+ if (ri->channel_title != NULL) {
+ if (StrLength(ri->channel_title) > 0) {
+ SaveMsg->Msg.cm_fields['O'] =
+ strdup(ChrPtr(ri->channel_title));
+ }
+ }
+ if (ri->link == NULL)
+ ri->link = NewStrBufPlain(HKEY(""));
+
+#if 0 /* temporarily disable shorter urls. */
+ SaveMsg->Msg.cm_fields[TMP_SHORTER_URLS] =
+ GetShorterUrls(ri->description);
+#endif
+
+ msglen += 1024 + StrLength(ri->link) + StrLength(ri->description) ;
+
+ Message = NewStrBufPlain(NULL, StrLength(ri->description));
+
+ StrBufPlain(Message, HKEY(
+ "Content-type: text/html; charset=\"UTF-8\"\r\n\r\n"
+ "<html><body>\n"));
+#if 0 /* disable shorter url for now. */
+ SaveMsg->Msg.cm_fields[TMP_SHORTER_URL_OFFSET] = StrLength(Message);
+#endif
+ StrBufAppendBuf(Message, ri->description, 0);
+ StrBufAppendBufPlain(Message, HKEY("<br><br>\n"), 0);
+
+ AppendLink(Message, ri->link, ri->linkTitle, NULL);
+ AppendLink(Message, ri->reLink, ri->reLinkTitle, "Reply to this");
+ StrBufAppendBufPlain(Message, HKEY("</body></html>\n"), 0);
+
+ SaveMsg->MsgGUID = guid;
+ SaveMsg->Message = Message;
+
+ n = GetCount(Cfg->Messages) + 1;
+ Put(Cfg->Messages, IKEY(n), SaveMsg, FreeNetworkSaveMessage);
+}
+
+
+void rss_xml_start(void *data, const char *supplied_el, const char **attr)
+{
+ rss_xml_handler *h;
+ rss_aggregator *RSSAggr = (rss_aggregator*) data;
+ rss_item *ri = RSSAggr->Item;
+ void *pv;
+ const char *pel;
+ char *sep = NULL;
+
+ /* Axe the namespace, we don't care about it */
+/// syslog(LOG_DEBUG, "RSS: supplied el %d: %s...\n", RSSAggr->Cfg->ItemType, supplied_el);
+ pel = supplied_el;
+ while (sep = strchr(pel, ':'), sep) {
+ pel = sep + 1;
+ }
+
+ if (pel != supplied_el)
+ {
+ void *v;
+
+ if (!GetHash(KnownNameSpaces,
+ supplied_el,
+ pel - supplied_el - 1,
+ &v))
+ {
+#ifdef DEBUG_RSS
+ syslog(LOG_DEBUG, "RSS: START ignoring because of wrong namespace [%s]\n",
+ supplied_el);
+#endif
+ return;
+ }
+ }
+
+ StrBufPlain(RSSAggr->Key, pel, -1);
+ StrBufLowerCase(RSSAggr->Key);
+ if (GetHash(StartHandlers, SKEY(RSSAggr->Key), &pv))
+ {
+ h = (rss_xml_handler*) pv;
+
+ if (((h->Flags & RSS_UNSET) != 0) &&
+ (RSSAggr->ItemType == RSS_UNSET))
+ {
+ h->Handler(RSSAggr->CData, ri, RSSAggr, attr);
+ }
+ else if (((h->Flags & RSS_RSS) != 0) &&
+ (RSSAggr->ItemType == RSS_RSS))
+ {
+ h->Handler(RSSAggr->CData, ri, RSSAggr, attr);
+ }
+ else if (((h->Flags & RSS_ATOM) != 0) &&
+ (RSSAggr->ItemType == RSS_ATOM))
+ {
+ h->Handler(RSSAggr->CData, ri, RSSAggr, attr);
+ }
+#ifdef DEBUG_RSS
+ else
+ syslog(LOG_DEBUG, "RSS: START unhandled: [%s] [%s]...\n", pel, supplied_el);
+#endif
+ }
+#ifdef DEBUG_RSS
+ else
+ syslog(LOG_DEBUG, "RSS: START unhandled: [%s] [%s]...\n", pel, supplied_el);
+#endif
+}
+
+void rss_xml_end(void *data, const char *supplied_el)
+{
+ rss_xml_handler *h;
+ rss_aggregator *RSSAggr = (rss_aggregator*) data;
+ rss_item *ri = RSSAggr->Item;
+ const char *pel;
+ char *sep = NULL;
+ void *pv;
+
+ /* Axe the namespace, we don't care about it */
+ pel = supplied_el;
+ while (sep = strchr(pel, ':'), sep) {
+ pel = sep + 1;
+ }
+// syslog(LOG_DEBUG, "RSS: END %s...\n", el);
+ if (pel != supplied_el)
+ {
+ void *v;
+
+ if (!GetHash(KnownNameSpaces,
+ supplied_el,
+ pel - supplied_el - 1,
+ &v))
+ {
+#ifdef DEBUG_RSS
+ syslog(LOG_DEBUG, "RSS: END ignoring because of wrong namespace [%s] = [%s]\n",
+ supplied_el, ChrPtr(RSSAggr->CData));
+#endif
+ FlushStrBuf(RSSAggr->CData);
+ return;
+ }
+ }
+
+ StrBufPlain(RSSAggr->Key, pel, -1);
+ StrBufLowerCase(RSSAggr->Key);
+ if (GetHash(EndHandlers, SKEY(RSSAggr->Key), &pv))
+ {
+ h = (rss_xml_handler*) pv;
+
+ if (((h->Flags & RSS_UNSET) != 0) &&
+ (RSSAggr->ItemType == RSS_UNSET))
+ {
+ h->Handler(RSSAggr->CData, ri, RSSAggr, NULL);
+ }
+ else if (((h->Flags & RSS_RSS) != 0) &&
+ (RSSAggr->ItemType == RSS_RSS))
+ {
+ h->Handler(RSSAggr->CData, ri, RSSAggr, NULL);
+ }
+ else if (((h->Flags & RSS_ATOM) != 0) &&
+ (RSSAggr->ItemType == RSS_ATOM))
+ {
+ h->Handler(RSSAggr->CData, ri, RSSAggr, NULL);
+ }
+#ifdef DEBUG_RSS
+ else
+ syslog(LOG_DEBUG, "RSS: END unhandled: [%s] [%s] = [%s]...\n", pel, supplied_el, ChrPtr(RSSAggr->CData));
+#endif
+ }
+#ifdef DEBUG_RSS
+ else
+ syslog(LOG_DEBUG, "RSS: END unhandled: [%s] [%s] = [%s]...\n", pel, supplied_el, ChrPtr(RSSAggr->CData));
+#endif
+ FlushStrBuf(RSSAggr->CData);
+}
+
+/*
+ * Callback function for passing libcurl's output to expat for parsing
+ * we don't do streamed parsing so expat can handle non-utf8 documents
size_t rss_libcurl_callback(void *ptr, size_t size, size_t nmemb, void *stream)
{
XML_Parse((XML_Parser)stream, ptr, (size * nmemb), 0);
return (size*nmemb);
}
+ */
-
-
-eNextState ParseRSSReply(AsyncIO *IO)
+eNextState RSSAggregator_ParseReply(AsyncIO *IO)
{
StrBuf *Buf;
- rss_aggregator *rssc;
+ rss_aggregator *RSSAggr;
rss_item *ri;
const char *at;
char *ptr;
return eAbort;
}
- rssc = IO->Data;
- ri = rssc->Item;
- rssc->CData = NewStrBufPlain(NULL, SIZ);
- rssc->Key = NewStrBuf();
+ RSSAggr = IO->Data;
+ ri = RSSAggr->Item;
+ RSSAggr->CData = NewStrBufPlain(NULL, SIZ);
+ RSSAggr->Key = NewStrBuf();
at = NULL;
- StrBufSipLine(rssc->Key, IO->HttpReq.ReplyData, &at);
+ StrBufSipLine(RSSAggr->Key, IO->HttpReq.ReplyData, &at);
ptr = NULL;
#define encoding "encoding=\""
- ptr = strstr(ChrPtr(rssc->Key), encoding);
+ ptr = strstr(ChrPtr(RSSAggr->Key), encoding);
if (ptr != NULL)
{
char *pche;
ptr += sizeof (encoding) - 1;
pche = strchr(ptr, '"');
if (pche != NULL)
- StrBufCutAt(rssc->Key, -1, pche);
+ StrBufCutAt(RSSAggr->Key, -1, pche);
else
ptr = "UTF-8";
}
else
ptr = "UTF-8";
- syslog(LOG_DEBUG, "RSS: Now parsing [%s] \n", ChrPtr(rssc->Url));
+ syslog(LOG_DEBUG, "RSS: Now parsing [%s] \n", ChrPtr(RSSAggr->Url));
- rssc->xp = XML_ParserCreateNS(ptr, ':');
- if (!rssc->xp) {
+ RSSAggr->xp = XML_ParserCreateNS(ptr, ':');
+ if (!RSSAggr->xp) {
syslog(LOG_DEBUG, "Cannot create XML parser!\n");
return eAbort;
}
- FlushStrBuf(rssc->Key);
+ FlushStrBuf(RSSAggr->Key);
- rssc->Messages = NewHash(1, Flathash);
- XML_SetElementHandler(rssc->xp, rss_xml_start, rss_xml_end);
- XML_SetCharacterDataHandler(rssc->xp, rss_xml_chardata);
- XML_SetUserData(rssc->xp, rssc);
- XML_SetCdataSectionHandler(rssc->xp,
+ RSSAggr->Messages = NewHash(1, Flathash);
+ XML_SetElementHandler(RSSAggr->xp, rss_xml_start, rss_xml_end);
+ XML_SetCharacterDataHandler(RSSAggr->xp, rss_xml_chardata);
+ XML_SetUserData(RSSAggr->xp, RSSAggr);
+ XML_SetCdataSectionHandler(RSSAggr->xp,
rss_xml_cdata_start,
rss_xml_cdata_end);
len = StrLength(IO->HttpReq.ReplyData);
ptr = SmashStrBuf(&IO->HttpReq.ReplyData);
- XML_Parse(rssc->xp, ptr, len, 0);
+ XML_Parse(RSSAggr->xp, ptr, len, 0);
free (ptr);
if (ri->done_parsing == 0)
- XML_Parse(rssc->xp, "", 0, 1);
+ XML_Parse(RSSAggr->xp, "", 0, 1);
syslog(LOG_DEBUG, "RSS: XML Status [%s] \n",
XML_ErrorString(
- XML_GetErrorCode(rssc->xp)));
+ XML_GetErrorCode(RSSAggr->xp)));
- XML_ParserFree(rssc->xp);
+ XML_ParserFree(RSSAggr->xp);
flush_rss_item(ri);
- FreeStrBuf(&rssc->CData);
- FreeStrBuf(&rssc->Key);
- Buf = NewStrBufDup(rssc->rooms);
- rssc->recp.recp_room = SmashStrBuf(&Buf);
- rssc->recp.num_room = rssc->roomlist_parts;
- rssc->recp.recptypes_magic = RECPTYPES_MAGIC;
+ Buf = NewStrBufDup(RSSAggr->rooms);
+ RSSAggr->recp.recp_room = SmashStrBuf(&Buf);
+ RSSAggr->recp.num_room = RSSAggr->roomlist_parts;
+ RSSAggr->recp.recptypes_magic = RECPTYPES_MAGIC;
- rssc->Pos = GetNewHashPos(rssc->Messages, 1);
+ RSSAggr->Pos = GetNewHashPos(RSSAggr->Messages, 1);
///Cfg->next_poll = time(NULL) + config.c_net_freq;
- if (GetNextHashPos(rssc->Messages, rssc->Pos, &len, &Key, (void**) &rssc->ThisMsg))
+ if (GetNextHashPos(RSSAggr->Messages, RSSAggr->Pos, &len, &Key, (void**) &RSSAggr->ThisMsg))
return QueueDBOperation(IO, RSS_FetchNetworkUsetableEntry);
else
return eAbort;
}
+/*******************************************************************************
+ * RSS handler registering logic *
+ *******************************************************************************/
+
+void AddRSSStartHandler(rss_handler_func Handler, int Flags, const char *key, long len)
+{
+ rss_xml_handler *h;
+ h = (rss_xml_handler*) malloc(sizeof (rss_xml_handler));
+ h->Flags = Flags;
+ h->Handler = Handler;
+ Put(StartHandlers, key, len, h, NULL);
+}
+void AddRSSEndHandler(rss_handler_func Handler, int Flags, const char *key, long len)
+{
+ rss_xml_handler *h;
+ h = (rss_xml_handler*) malloc(sizeof (rss_xml_handler));
+ h->Flags = Flags;
+ h->Handler = Handler;
+ Put(EndHandlers, key, len, h, NULL);
+}
+
void rss_parser_cleanup(void)
{
DeleteHash(&StartHandlers);
AddRSSStartHandler(RSS_item_rss_start, RSS_UNSET, HKEY("rss"));
AddRSSStartHandler(RSS_item_rdf_start, RSS_UNSET, HKEY("rdf"));
- AddRSSStartHandler(ATOM_item_feed_start, RSS_UNSET, HKEY("feed"));
+ AddRSSStartHandler(ATOM_item_feed_start, RSS_UNSET, HKEY("feed"));
AddRSSStartHandler(RSS_item_item_start, RSS_RSS, HKEY("item"));
AddRSSStartHandler(ATOM_item_entry_start, RSS_ATOM, HKEY("entry"));
AddRSSStartHandler(ATOM_item_link_start, RSS_ATOM, HKEY("link"));
StrBuf *author_url;
StrBuf *author_email;
};
+void flush_rss_item(rss_item *ri);
struct rss_room_counter {
int count;
};
typedef struct __networker_save_message {
- struct CtdlMessage *Msg;
+ struct CtdlMessage Msg;
StrBuf *MsgGUID;
StrBuf *Message;
struct UseTable ut;
HashPos *Pos;
HashList *Messages;
networker_save_message *ThisMsg;
- const rss_xml_handler *Current;
};
-eNextState ParseRSSReply(AsyncIO *IO);
-
-void rss_save_item(rss_item *ri, rss_aggregator *Cfg);
+eNextState RSSAggregator_ParseReply(AsyncIO *IO);
eNextState RSS_FetchNetworkUsetableEntry(AsyncIO *IO);
pthread_mutex_t RSSQueueMutex; /* locks the access to the following vars: */
HashList *RSSQueueRooms = NULL; /* rss_room_counter */
-HashList *RSSFetchUrls = NULL; /* -> rss_aggregator; ->RefCount access to be locked too. */
+HashList *RSSFetchUrls = NULL; /*->rss_aggregator;->RefCount access locked*/
-eNextState RSSAggregatorTerminate(AsyncIO *IO);
-eNextState RSSAggregatorShutdownAbort(AsyncIO *IO);
+eNextState RSSAggregator_Terminate(AsyncIO *IO);
+eNextState RSSAggregator_ShutdownAbort(AsyncIO *IO);
struct CitContext rss_CC;
struct rssnetcfg *rnclist = NULL;
-void AppendLink(StrBuf *Message, StrBuf *link, StrBuf *LinkTitle, const char *Title)
-{
- if (StrLength(link) > 0)
- {
- StrBufAppendBufPlain(Message, HKEY("<a href=\""), 0);
- StrBufAppendBuf(Message, link, 0);
- StrBufAppendBufPlain(Message, HKEY("\">"), 0);
- if (StrLength(LinkTitle) > 0)
- StrBufAppendBuf(Message, LinkTitle, 0);
- else if ((Title != NULL) && !IsEmptyStr(Title))
- StrBufAppendBufPlain(Message, Title, -1, 0);
- else
- StrBufAppendBuf(Message, link, 0);
- StrBufAppendBufPlain(Message, HKEY("</a><br>\n"), 0);
- }
-}
void DeleteRoomReference(long QRnumber)
void UnlinkRooms(rss_aggregator *Cfg)
{
-
DeleteRoomReference(Cfg->QRnumber);
if (Cfg->OtherQRnumbers != NULL)
{
void *vData;
At = GetNewHashPos(Cfg->OtherQRnumbers, 0);
- while (GetNextHashPos(Cfg->OtherQRnumbers, At, &HKLen, &HK, &vData) &&
+ while (! server_shutting_down &&
+ GetNextHashPos(Cfg->OtherQRnumbers,
+ At,
+ &HKLen, &HK,
+ &vData) &&
(vData != NULL))
{
long *lData = (long*) vData;
DeleteRoomReference(*lData);
}
-/*
- if (server_shutting_down)
- break; / * TODO */
DeleteHashPos(&At);
}
DeleteHashPos(&At);
last_run = time(NULL);
}
-/*
-eNextState FreeNetworkSaveMessage (AsyncIO *IO)
+
+
+void DeleteRssCfg(void *vptr)
{
- networker_save_message *Ctx = (networker_save_message *) IO->Data;
+ rss_aggregator *RSSAggr = (rss_aggregator *)vptr;
+ AsyncIO *IO = &RSSAggr->IO;
+ EVM_syslog(LOG_DEBUG, "RSS: destroying\n");
- pthread_mutex_lock(&RSSQueueMutex);
- Ctx->Cfg->RefCount --;
+ FreeStrBuf(&RSSAggr->Url);
+ FreeStrBuf(&RSSAggr->rooms);
+ FreeStrBuf(&RSSAggr->CData);
+ FreeStrBuf(&RSSAggr->Key);
+ DeleteHash(&RSSAggr->OtherQRnumbers);
- if (Ctx->Cfg->RefCount == 0)
+ DeleteHashPos (&RSSAggr->Pos);
+ DeleteHash (&RSSAggr->Messages);
+ if (RSSAggr->recp.recp_room != NULL)
+ free(RSSAggr->recp.recp_room);
+
+
+ if (RSSAggr->Item != NULL)
{
- UnlinkRSSAggregator(Ctx->Cfg);
+ flush_rss_item(RSSAggr->Item);
+ free(RSSAggr->Item);
}
- pthread_mutex_unlock(&RSSQueueMutex);
- CtdlFreeMessage(Ctx->Msg);
- free_recipients(Ctx->recp);
- FreeStrBuf(&Ctx->Message);
- FreeStrBuf(&Ctx->MsgGUID);
- ((struct CitContext*)IO->CitContext)->state = CON_IDLE;
- ((struct CitContext*)IO->CitContext)->kill_me = 1;
- free(Ctx);
- last_run = time(NULL);
+ FreeAsyncIOContents(&RSSAggr->IO);
+ free(RSSAggr);
+}
+
+eNextState RSSAggregator_Terminate(AsyncIO *IO)
+{
+ rss_aggregator *RSSAggr = (rss_aggregator *)IO->Data;
+
+ EVM_syslog(LOG_DEBUG, "RSS: Terminating.\n");
+
+
+ UnlinkRSSAggregator(RSSAggr);
return eAbort;
}
-*/
-void FreeNetworkSaveMessage (void *vMsg)
+eNextState RSSAggregator_ShutdownAbort(AsyncIO *IO)
{
- networker_save_message *Msg = (networker_save_message *) vMsg;
+ const char *pUrl;
+ rss_aggregator *RSSAggr = (rss_aggregator *)IO->Data;
+
+ pUrl = IO->ConnectMe->PlainUrl;
+ if (pUrl == NULL)
+ pUrl = "";
+
+ EV_syslog(LOG_DEBUG, "RSS: Aborting by shutdown: %s.\n", pUrl);
+
- CtdlFreeMessage(Msg->Msg);
- FreeStrBuf(&Msg->Message);
- FreeStrBuf(&Msg->MsgGUID);
- free(Msg);
+ UnlinkRSSAggregator(RSSAggr);
+ return eAbort;
}
+
eNextState AbortNetworkSaveMessage (AsyncIO *IO)
{
return eAbort; ///TODO
{
long len;
const char *Key;
- rss_aggregator *Ctx = (rss_aggregator *) IO->Data;
+ rss_aggregator *RSSAggr = (rss_aggregator *) IO->Data;
- Ctx->ThisMsg->Msg->cm_fields['M'] = SmashStrBuf(&Ctx->ThisMsg->Message);
+ RSSAggr->ThisMsg->Msg.cm_fields['M'] = SmashStrBuf(&RSSAggr->ThisMsg->Message);
- CtdlSubmitMsg(Ctx->ThisMsg->Msg, &Ctx->recp, NULL, 0);
+ CtdlSubmitMsg(&RSSAggr->ThisMsg->Msg, &RSSAggr->recp, NULL, 0);
/* write the uidl to the use table so we don't store this item again */
- cdb_store(CDB_USETABLE, SKEY(Ctx->ThisMsg->MsgGUID), &Ctx->ThisMsg->ut, sizeof(struct UseTable) );
-
- if (GetNextHashPos(Ctx->Messages, Ctx->Pos, &len, &Key, (void**) &Ctx->ThisMsg))
+ cdb_store(CDB_USETABLE,
+ SKEY(RSSAggr->ThisMsg->MsgGUID),
+ &RSSAggr->ThisMsg->ut,
+ sizeof(struct UseTable) );
+
+ if (GetNextHashPos(RSSAggr->Messages,
+ RSSAggr->Pos,
+ &len, &Key,
+ (void**) &RSSAggr->ThisMsg))
return NextDBOperation(IO, RSS_FetchNetworkUsetableEntry);
else
return eAbort;
struct cdbdata *cdbut;
rss_aggregator *Ctx = (rss_aggregator *) IO->Data;
-
/* Find out if we've already seen this item */
- strcpy(Ctx->ThisMsg->ut.ut_msgid, ChrPtr(Ctx->ThisMsg->MsgGUID)); /// TODO
+ strcpy(Ctx->ThisMsg->ut.ut_msgid,
+ ChrPtr(Ctx->ThisMsg->MsgGUID)); /// TODO
Ctx->ThisMsg->ut.ut_timestamp = time(NULL);
cdbut = cdb_fetch(CDB_USETABLE, SKEY(Ctx->ThisMsg->MsgGUID));
#ifndef DEBUG_RSS
if (cdbut != NULL) {
/* Item has already been seen */
- EV_syslog(LOG_DEBUG, "%s has already been seen\n", ChrPtr(Ctx->ThisMsg->MsgGUID));
+ EV_syslog(LOG_DEBUG,
+ "%s has already been seen\n",
+ ChrPtr(Ctx->ThisMsg->MsgGUID));
cdb_free(cdbut);
/* rewrite the record anyway, to update the timestamp */
- cdb_store(CDB_USETABLE,
- SKEY(Ctx->ThisMsg->MsgGUID),
+ cdb_store(CDB_USETABLE,
+ SKEY(Ctx->ThisMsg->MsgGUID),
&Ctx->ThisMsg->ut, sizeof(struct UseTable) );
- if (GetNextHashPos(Ctx->Messages, Ctx->Pos, &len, &Key, (void**) &Ctx->ThisMsg))
- return NextDBOperation(IO, RSS_FetchNetworkUsetableEntry);
+ if (GetNextHashPos(Ctx->Messages,
+ Ctx->Pos,
+ &len, &Key,
+ (void**) &Ctx->ThisMsg))
+ return NextDBOperation(
+ IO,
+ RSS_FetchNetworkUsetableEntry);
else
return eAbort;
}
return eSendMore;
}
}
-/*
-void RSSAddSaveMessage(struct CtdlMessage *Msg, struct recptypes *recp, StrBuf *MsgGUID, StrBuf *MessageBody, rss_aggregat *Cfg)
-{
- networker_save_message *Ctx;
-
- pthread_mutex_lock(&RSSQueueMutex);
- Cfg->RefCount ++;
- pthread_mutex_unlock(&RSSQueueMutex);
-
-
- Ctx = (networker_save_message *) malloc(sizeof(networker_save_message));
- memset(Ctx, 0, sizeof(networker_save_message));
-
- Ctx->MsgGUID = MsgGUID;
- Ctx->Message = MessageBody;
- Ctx->Msg = Msg;
- Ctx->Cfg = Cfg;
- Ctx->recp = recp;
- Ctx->IO.Data = Ctx;
- Ctx->IO.CitContext = CloneContext(&rss_CC);
- Ctx->IO.Terminate = FreeNetworkSaveMessage;
- Ctx->IO.ShutdownAbort = AbortNetworkSaveMessage;
- QueueDBOperation(&Ctx->IO, RSS_FetchNetworkUsetableEntry);
-}
-*/
-
-/*
- * Commit a fetched and parsed RSS item to disk
- */
-void rss_save_item(rss_item *ri, rss_aggregator *Cfg)
-{
-
- struct MD5Context md5context;
- u_char rawdigest[MD5_DIGEST_LEN];
- struct CtdlMessage *msg;
- int msglen = 0;
- StrBuf *Message;
- StrBuf *guid;
- AsyncIO *IO = &Cfg->IO;
-
- int n;
-
- /* Construct a GUID to use in the S_USETABLE table.
- * If one is not present in the item itself, make one up.
- */
- if (ri->guid != NULL) {
- StrBufSpaceToBlank(ri->guid);
- StrBufTrim(ri->guid);
- guid = NewStrBufPlain(HKEY("rss/"));
- StrBufAppendBuf(guid, ri->guid, 0);
- }
- else {
- MD5Init(&md5context);
- if (ri->title != NULL) {
- MD5Update(&md5context, (const unsigned char*)ChrPtr(ri->title), StrLength(ri->title));
- }
- if (ri->link != NULL) {
- MD5Update(&md5context, (const unsigned char*)ChrPtr(ri->link), StrLength(ri->link));
- }
- MD5Final(rawdigest, &md5context);
- guid = NewStrBufPlain(NULL, MD5_DIGEST_LEN * 2 + 12 /* _rss2ctdl*/);
- StrBufHexEscAppend(guid, NULL, rawdigest, MD5_DIGEST_LEN);
- StrBufAppendBufPlain(guid, HKEY("_rss2ctdl"), 0);
- }
-
- /* translate Item into message. */
- EVM_syslog(LOG_DEBUG, "RSS: translating item...\n");
- if (ri->description == NULL) ri->description = NewStrBufPlain(HKEY(""));
- StrBufSpaceToBlank(ri->description);
- msg = malloc(sizeof(struct CtdlMessage));
- memset(msg, 0, sizeof(struct CtdlMessage));
- msg->cm_magic = CTDLMESSAGE_MAGIC;
- msg->cm_anon_type = MES_NORMAL;
- msg->cm_format_type = FMT_RFC822;
-
- if (ri->guid != NULL) {
- msg->cm_fields['E'] = strdup(ChrPtr(ri->guid));
- }
-
- if (ri->author_or_creator != NULL) {
- char *From;
- StrBuf *Encoded = NULL;
- int FromAt;
-
- From = html_to_ascii(ChrPtr(ri->author_or_creator),
- StrLength(ri->author_or_creator),
- 512, 0);
- StrBufPlain(ri->author_or_creator, From, -1);
- StrBufTrim(ri->author_or_creator);
- free(From);
-
- FromAt = strchr(ChrPtr(ri->author_or_creator), '@') != NULL;
- if (!FromAt && StrLength (ri->author_email) > 0)
- {
- StrBufRFC2047encode(&Encoded, ri->author_or_creator);
- msg->cm_fields['A'] = SmashStrBuf(&Encoded);
- msg->cm_fields['P'] = SmashStrBuf(&ri->author_email);
- }
- else
- {
- if (FromAt)
- {
- msg->cm_fields['A'] = SmashStrBuf(&ri->author_or_creator);
- msg->cm_fields['P'] = strdup(msg->cm_fields['A']);
- }
- else
- {
- StrBufRFC2047encode(&Encoded, ri->author_or_creator);
- msg->cm_fields['A'] = SmashStrBuf(&Encoded);
- msg->cm_fields['P'] = strdup("rss@localhost");
-
- }
- if (ri->pubdate <= 0) {
- ri->pubdate = time(NULL);
- }
- }
- }
- else {
- msg->cm_fields['A'] = strdup("rss");
- }
-
- msg->cm_fields['N'] = strdup(NODENAME);
- if (ri->title != NULL) {
- long len;
- char *Sbj;
- StrBuf *Encoded, *QPEncoded;
-
- QPEncoded = NULL;
- StrBufSpaceToBlank(ri->title);
- len = StrLength(ri->title);
- Sbj = html_to_ascii(ChrPtr(ri->title), len, 512, 0);
- len = strlen(Sbj);
- if (Sbj[len - 1] == '\n')
- {
- len --;
- Sbj[len] = '\0';
- }
- Encoded = NewStrBufPlain(Sbj, len);
- free(Sbj);
-
- StrBufTrim(Encoded);
- StrBufRFC2047encode(&QPEncoded, Encoded);
-
- msg->cm_fields['U'] = SmashStrBuf(&QPEncoded);
- FreeStrBuf(&Encoded);
- }
- msg->cm_fields['T'] = malloc(64);
- snprintf(msg->cm_fields['T'], 64, "%ld", ri->pubdate);
- if (ri->channel_title != NULL) {
- if (StrLength(ri->channel_title) > 0) {
- msg->cm_fields['O'] = strdup(ChrPtr(ri->channel_title));
- }
- }
- if (ri->link == NULL)
- ri->link = NewStrBufPlain(HKEY(""));
-
-#if 0 /* temporarily disable shorter urls. */
- msg->cm_fields[TMP_SHORTER_URLS] = GetShorterUrls(ri->description);
-#endif
-
- msglen += 1024 + StrLength(ri->link) + StrLength(ri->description) ;
-
- Message = NewStrBufPlain(NULL, StrLength(ri->description));
-
- StrBufPlain(Message, HKEY(
- "Content-type: text/html; charset=\"UTF-8\"\r\n\r\n"
- "<html><body>\n"));
-#if 0 /* disable shorter url for now. */
- msg->cm_fields[TMP_SHORTER_URL_OFFSET] = StrLength(Message);
-#endif
- StrBufAppendBuf(Message, ri->description, 0);
- StrBufAppendBufPlain(Message, HKEY("<br><br>\n"), 0);
-
- AppendLink(Message, ri->link, ri->linkTitle, NULL);
- AppendLink(Message, ri->reLink, ri->reLinkTitle, "Reply to this");
- StrBufAppendBufPlain(Message, HKEY("</body></html>\n"), 0);
-
-
-
- networker_save_message *SaveMsg;
-
- SaveMsg = (networker_save_message *) malloc(sizeof(networker_save_message));
- memset(SaveMsg, 0, sizeof(networker_save_message));
-
- SaveMsg->MsgGUID = guid;
- SaveMsg->Message = Message;
- SaveMsg->Msg = msg;
-
- n = GetCount(Cfg->Messages) + 1;
- Put(Cfg->Messages, IKEY(n), SaveMsg, FreeNetworkSaveMessage);
-}
int rss_do_fetching(rss_aggregator *Cfg)
{
rss_item *ri;
-
time_t now;
- AsyncIO *IO;
- now = time(NULL);
+ now = time(NULL);
if ((Cfg->next_poll != 0) && (now < Cfg->next_poll))
return 0;
ri = (rss_item*) malloc(sizeof(rss_item));
memset(ri, 0, sizeof(rss_item));
Cfg->Item = ri;
- IO = &Cfg->IO;
- IO->CitContext = CloneContext(&rss_CC);
- IO->Data = Cfg;
-
- safestrncpy(((CitContext*)IO->CitContext)->cs_host,
- ChrPtr(Cfg->Url),
- sizeof(((CitContext*)IO->CitContext)->cs_host));
- syslog(LOG_DEBUG, "Fetching RSS feed <%s>\n", ChrPtr(Cfg->Url));
- ParseURL(&IO->ConnectMe, Cfg->Url, 80);
- CurlPrepareURL(IO->ConnectMe);
-
- if (! evcurl_init(IO,
-// Ctx,
- NULL,
- "Citadel RSS Client",
- ParseRSSReply,
- RSSAggregatorTerminate,
- RSSAggregatorShutdownAbort))
+ if (! InitcURLIOStruct(&Cfg->IO,
+ Cfg,
+ "Citadel RSS Client",
+ RSSAggregator_ParseReply,
+ RSSAggregator_Terminate,
+ RSSAggregator_ShutdownAbort))
{
- syslog(LOG_DEBUG, "Unable to initialize libcurl.\n");
+ syslog(LOG_ALERT, "Unable to initialize libcurl.\n");
return 0;
}
- QueueCurlContext(IO);
- return 1;
-}
-
-
-void DeleteRssCfg(void *vptr)
-{
- rss_aggregator *rncptr = (rss_aggregator *)vptr;
- AsyncIO *IO = &rncptr->IO;
- EVM_syslog(LOG_DEBUG, "RSS: destroying\n");
-
- FreeStrBuf(&rncptr->Url);
- FreeStrBuf(&rncptr->rooms);
- FreeStrBuf(&rncptr->CData);
- FreeStrBuf(&rncptr->Key);
- FreeStrBuf(&rncptr->IO.HttpReq.ReplyData);
- DeleteHash(&rncptr->OtherQRnumbers);
- FreeURL(&rncptr->IO.ConnectMe);
-
- DeleteHashPos (&rncptr->Pos);
- DeleteHash (&rncptr->Messages);
- if (rncptr->recp.recp_room != NULL)
- free(rncptr->recp.recp_room);
-
-
- if (rncptr->Item != NULL)
- {
- FreeStrBuf(&rncptr->Item->guid);
- FreeStrBuf(&rncptr->Item->title);
- FreeStrBuf(&rncptr->Item->link);
- FreeStrBuf(&rncptr->Item->linkTitle);
- FreeStrBuf(&rncptr->Item->reLink);
- FreeStrBuf(&rncptr->Item->reLinkTitle);
- FreeStrBuf(&rncptr->Item->description);
- FreeStrBuf(&rncptr->Item->channel_title);
- FreeStrBuf(&rncptr->Item->author_or_creator);
- FreeStrBuf(&rncptr->Item->author_url);
- FreeStrBuf(&rncptr->Item->author_email);
-
- free(rncptr->Item);
- }
- free(rncptr);
-}
-
-eNextState RSSAggregatorTerminate(AsyncIO *IO)
-{
- rss_aggregator *rncptr = (rss_aggregator *)IO->Data;
-
- EVM_syslog(LOG_DEBUG, "RSS: Terminating.\n");
-
-
- UnlinkRSSAggregator(rncptr);
- return eAbort;
-}
-eNextState RSSAggregatorShutdownAbort(AsyncIO *IO)
-{
- const char *pUrl;
- rss_aggregator *rncptr = (rss_aggregator *)IO->Data;
-
- pUrl = IO->ConnectMe->PlainUrl;
- if (pUrl == NULL)
- pUrl = "";
-
- EV_syslog(LOG_DEBUG, "RSS: Aborting by shutdown: %s.\n", pUrl);
+ safestrncpy(((CitContext*)Cfg->IO.CitContext)->cs_host,
+ ChrPtr(Cfg->Url),
+ sizeof(((CitContext*)Cfg->IO.CitContext)->cs_host));
+ syslog(LOG_DEBUG, "Fetching RSS feed <%s>\n", ChrPtr(Cfg->Url));
+ ParseURL(&Cfg->IO.ConnectMe, Cfg->Url, 80);
+ CurlPrepareURL(Cfg->IO.ConnectMe);
- UnlinkRSSAggregator(rncptr);
- return eAbort;
+ QueueCurlContext(&Cfg->IO);
+ return 1;
}
/*
char filename[PATH_MAX];
int fd;
int Done;
- rss_aggregator *rncptr = NULL;
- rss_aggregator *use_this_rncptr = NULL;
+ rss_aggregator *RSSAggr = NULL;
+ rss_aggregator *use_this_RSSAggr = NULL;
void *vptr;
const char *CfgPtr, *lPtr;
const char *Err;
pthread_mutex_lock(&RSSQueueMutex);
if (GetHash(RSSQueueRooms, LKEY(qrbuf->QRnumber), &vptr))
{
- syslog(LOG_DEBUG,
- "rssclient: [%ld] %s already in progress.\n",
- qrbuf->QRnumber,
- qrbuf->QRname);
+ syslog(LOG_DEBUG,
+ "rssclient: [%ld] %s already in progress.\n",
+ qrbuf->QRnumber,
+ qrbuf->QRname);
pthread_mutex_unlock(&RSSQueueMutex);
return;
}
if (server_shutting_down)
return;
-
+
/* Only do net processing for rooms that have netconfigs */
fd = open(filename, 0);
if (fd <= 0) {
- //syslog(LOG_DEBUG, "rssclient: %s no config.\n", qrbuf->QRname);
+ /* syslog(LOG_DEBUG,
+ "rssclient: %s no config.\n",
+ qrbuf->QRname); */
return;
}
return;
if (fstat(fd, &statbuf) == -1) {
- syslog(LOG_DEBUG, "ERROR: could not stat configfile '%s' - %s\n",
- filename, strerror(errno));
+ syslog(LOG_DEBUG,
+ "ERROR: could not stat configfile '%s' - %s\n",
+ filename,
+ strerror(errno));
return;
}
close(fd);
if (server_shutting_down)
return;
-
+
CfgPtr = NULL;
CfgType = NewStrBuf();
Line = NewStrBufPlain(NULL, StrLength(CfgData));
Count->count = 0;
}
Count->count ++;
- rncptr = (rss_aggregator *) malloc(sizeof(rss_aggregator));
- memset (rncptr, 0, sizeof(rss_aggregator));
- rncptr->roomlist_parts = 1;
- rncptr->Url = NewStrBuf();
- StrBufExtract_NextToken(rncptr->Url, Line, &lPtr, '|');
+ RSSAggr = (rss_aggregator *) malloc(sizeof(rss_aggregator));
+ memset (RSSAggr, 0, sizeof(rss_aggregator));
+ RSSAggr->roomlist_parts = 1;
+ RSSAggr->Url = NewStrBuf();
+ StrBufExtract_NextToken(RSSAggr->Url, Line, &lPtr, '|');
pthread_mutex_lock(&RSSQueueMutex);
- GetHash(RSSFetchUrls, SKEY(rncptr->Url), &vptr);
- use_this_rncptr = (rss_aggregator *)vptr;
- if (use_this_rncptr != NULL)
+ GetHash(RSSFetchUrls, SKEY(RSSAggr->Url), &vptr);
+ use_this_RSSAggr = (rss_aggregator *)vptr;
+ if (use_this_RSSAggr != NULL)
{
long *QRnumber;
- StrBufAppendBufPlain(use_this_rncptr->rooms,
- qrbuf->QRname,
+ StrBufAppendBufPlain(use_this_RSSAggr->rooms,
+ qrbuf->QRname,
-1, 0);
- if (use_this_rncptr->roomlist_parts == 1)
+ if (use_this_RSSAggr->roomlist_parts == 1)
{
- use_this_rncptr->OtherQRnumbers = NewHash(1, lFlathash);
+ use_this_RSSAggr->OtherQRnumbers =
+ NewHash(1, lFlathash);
}
QRnumber = (long*)malloc(sizeof(long));
*QRnumber = qrbuf->QRnumber;
- Put(use_this_rncptr->OtherQRnumbers, LKEY(qrbuf->QRnumber), QRnumber, NULL);
- use_this_rncptr->roomlist_parts++;
+ Put(use_this_RSSAggr->OtherQRnumbers,
+ LKEY(qrbuf->QRnumber),
+ QRnumber,
+ NULL);
+ use_this_RSSAggr->roomlist_parts++;
pthread_mutex_unlock(&RSSQueueMutex);
- FreeStrBuf(&rncptr->Url);
- free(rncptr);
- rncptr = NULL;
+ FreeStrBuf(&RSSAggr->Url);
+ free(RSSAggr);
+ RSSAggr = NULL;
continue;
}
pthread_mutex_unlock(&RSSQueueMutex);
- rncptr->ItemType = RSS_UNSET;
-
- rncptr->rooms = NewStrBufPlain(qrbuf->QRname, -1);
+ RSSAggr->ItemType = RSS_UNSET;
+
+ RSSAggr->rooms = NewStrBufPlain(qrbuf->QRname, -1);
pthread_mutex_lock(&RSSQueueMutex);
- Put(RSSFetchUrls, SKEY(rncptr->Url), rncptr, DeleteRssCfg);
+ Put(RSSFetchUrls, SKEY(RSSAggr->Url), RSSAggr, DeleteRssCfg);
pthread_mutex_unlock(&RSSQueueMutex);
}
}
}
/*
- * This is a simple concurrency check to make sure only one rssclient run
- * is done at a time. We could do this with a mutex, but since we
+ * This is a simple concurrency check to make sure only one rssclient
+ * 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 ((GetCount(RSSQueueRooms) > 0) || (GetCount(RSSFetchUrls) > 0))
return;
+ become_session(&rss_CC);
syslog(LOG_DEBUG, "rssclient started\n");
CtdlForEachRoom(rssclient_scan_room, NULL);
it = GetNewHashPos(RSSFetchUrls, 0);
while (!server_shutting_down &&
- GetNextHashPos(RSSFetchUrls, it, &len, &Key, &vrptr) &&
+ GetNextHashPos(RSSFetchUrls, it, &len, &Key, &vrptr) &&
(vrptr != NULL)) {
rptr = (rss_aggregator *)vrptr;
if (!rss_do_fetching(rptr))
RSSFetchUrls = NewHash(1, NULL);
syslog(LOG_INFO, "%s\n", curl_version());
CtdlRegisterSessionHook(rssclient_scan, EVT_TIMER);
- CtdlRegisterCleanupHook(rss_cleanup);
+ CtdlRegisterCleanupHook(rss_cleanup);
}
return "rssclient";
}
{
SmtpOutMsg *Msg = v;
+ /* these are kept in our own space and free'd below */
+ Msg->IO.ConnectMe = NULL;
+
ares_free_data(Msg->AllMX);
if (Msg->HostLookup.VParsedDNSReply != NULL)
Msg->HostLookup.DNSReplyFree(Msg->HostLookup.VParsedDNSReply);
return 1;
}
+void CtdlFreeMessageContents(struct CtdlMessage *msg)
+{
+ int i;
+ for (i = 0; i < 256; ++i)
+ if (msg->cm_fields[i] != NULL) {
+ free(msg->cm_fields[i]);
+ }
+
+ msg->cm_magic = 0; /* just in case */
+}
/*
* 'Destructor' for struct CtdlMessage
*/
void CtdlFreeMessage(struct CtdlMessage *msg)
{
- int i;
-
if (is_valid_message(msg) == 0)
{
if (msg != NULL) free (msg);
return;
}
-
- for (i = 0; i < 256; ++i)
- if (msg->cm_fields[i] != NULL) {
- free(msg->cm_fields[i]);
- }
-
- msg->cm_magic = 0; /* just in case */
+ CtdlFreeMessageContents(msg);
free(msg);
}
);
struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body);
void CtdlFreeMessage(struct CtdlMessage *msg);
+void CtdlFreeMessageContents(struct CtdlMessage *msg);
void serialize_message(struct ser_ret *, struct CtdlMessage *);
void dump_message(struct CtdlMessage *msg, long Siz);
int is_valid_message(struct CtdlMessage *);