CFLAGS="$saved_CFLAGS"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# The big search for OpenSSL
if test "$with_ssl" != "no"; then
saved_LIBS="$LIBS"
/*
*
- * Copyright (c) 1998-2009 by the citadel.org team
+ * Copyright (c) 1998-2012 by the citadel.org team
*
* This program is open source software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#include "event_client.h"
-static void IO_abort_shutdown_callback(struct ev_loop *loop, ev_cleanup *watcher, int revents)
+static void IO_abort_shutdown_callback(struct ev_loop *loop,
+ ev_cleanup *watcher,
+ int revents)
{
AsyncIO *IO = watcher->data;
EV_syslog(LOG_DEBUG, "EVENT Q: %s\n", __FUNCTION__);
}
-/*--------------------------------------------------------------------------------
- * Server DB IO
- */
+/*------------------------------------------------------------------------------
+ * Server DB IO
+ *----------------------------------------------------------------------------*/
extern int evdb_count;
extern pthread_mutex_t DBEventQueueMutex;
extern HashList *DBInboundEventQueue;
extern struct ev_loop *event_db;
-extern ev_async DBAddJob;
+extern ev_async DBAddJob;
extern ev_async DBExitEventLoop;
eNextState QueueDBOperation(AsyncIO *IO, IO_CallBack CB)
h = (IOAddHandler*)malloc(sizeof(IOAddHandler));
h->IO = IO;
h->EvAttch = CB;
- ev_cleanup_init(&IO->db_abort_by_shutdown,
+ ev_cleanup_init(&IO->db_abort_by_shutdown,
IO_abort_shutdown_callback);
IO->db_abort_by_shutdown.data = IO;
ev_cleanup_start(event_db, &IO->db_abort_by_shutdown);
ev_cleanup_stop(event_db, &IO->db_abort_by_shutdown);
assert(IO->Terminate);
- IO->Terminate(IO);
+ IO->Terminate(IO);
}
void
AsyncIO *IO = watcher->data;
EV_syslog(LOG_DEBUG, "event: %s\n", __FUNCTION__);
become_session(IO->CitContext);
-
+
ev_idle_stop(event_db, &IO->db_unwind_stack);
assert(IO->NextDBOperation);
case eSendDNSQuery:
case eReadDNSReply:
case eConnect:
- case eSendReply:
+ case eSendReply:
case eSendMore:
case eSendFile:
- case eReadMessage:
+ case eReadMessage:
case eReadMore:
case eReadPayload:
case eReadFile:
return eDBQuery;
}
-/*--------------------------------------------------------------------------------
- * Client IO
- */
+/*------------------------------------------------------------------------------
+ * Client IO
+ *----------------------------------------------------------------------------*/
extern int evbase_count;
extern pthread_mutex_t EventQueueMutex;
extern HashList *InboundEventQueue;
extern struct ev_loop *event_base;
-extern ev_async AddJob;
+extern ev_async AddJob;
extern ev_async ExitEventLoop;
h = (IOAddHandler*)malloc(sizeof(IOAddHandler));
h->IO = IO;
h->EvAttch = CB;
- ev_cleanup_init(&IO->abort_by_shutdown,
+ ev_cleanup_init(&IO->abort_by_shutdown,
IO_abort_shutdown_callback);
IO->abort_by_shutdown.data = IO;
ev_cleanup_start(event_base, &IO->abort_by_shutdown);
{
const char *Err = NULL;
eReadState Finished = eBufferNotEmpty;
-
+
become_session(IO->CitContext);
- while ((Finished == eBufferNotEmpty) &&
+ while ((Finished == eBufferNotEmpty) &&
((IO->NextState == eReadMessage)||
(IO->NextState == eReadMore)||
(IO->NextState == eReadFile)||
(IO->NextState == eReadPayload)))
{
- if (IO->RecvBuf.nBlobBytesWanted != 0) {
-
- }
- else { /* Reading lines... */
-//// lex line reply in callback, or do it ourselves. as nnn-blabla means continue reading in SMTP
- if ((IO->NextState == eReadFile) &&
- (Finished == eBufferNotEmpty))
+ /* Reading lines...
+ * lex line reply in callback,
+ * or do it ourselves.
+ * i.e. as nnn-blabla means continue reading in SMTP
+ */
+ if ((IO->NextState == eReadFile) &&
+ (Finished == eBufferNotEmpty))
+ {
+ Finished = WriteIOBAlreadyRead(&IO->IOB, &Err);
+ if (Finished == eReadSuccess)
{
- Finished = WriteIOBAlreadyRead(&IO->IOB, &Err);
- if (Finished == eReadSuccess)
- {
- IO->NextState = eSendReply;
- }
- }
- else if (IO->LineReader)
- Finished = IO->LineReader(IO);
- else
- Finished = StrBufChunkSipLine(IO->IOBuf, &IO->RecvBuf);
-
- switch (Finished) {
- case eMustReadMore: /// read new from socket...
- break;
- case eBufferNotEmpty: /* shouldn't happen... */
- case eReadSuccess: /// done for now...
- break;
- case eReadFail: /// WHUT?
- ///todo: shut down!
- break;
+ IO->NextState = eSendReply;
}
-
}
-
+ else if (IO->LineReader)
+ Finished = IO->LineReader(IO);
+ else
+ Finished = StrBufChunkSipLine(IO->IOBuf,
+ &IO->RecvBuf);
+
+ switch (Finished) {
+ case eMustReadMore: /// read new from socket...
+ break;
+ case eBufferNotEmpty: /* shouldn't happen... */
+ case eReadSuccess: /// done for now...
+ break;
+ case eReadFail: /// WHUT?
+ ///todo: shut down!
+ break;
+ }
+
if (Finished != eMustReadMore) {
assert(IO->ReadDone);
ev_io_stop(event_base, &IO->recv_event);
const char *pch = ChrPtr(IO->SendBuf.Buf);
const char *pchh = IO->SendBuf.ReadWritePointer;
long nbytes;
-
+
if (pchh == NULL)
pchh = pch;
-
+
nbytes = StrLength(IO->SendBuf.Buf) - (pchh - pch);
snprintf(fn, SIZ, "/tmp/foolog_ev_%s.%d",
((CitContext*)(IO->CitContext))->ServiceName,
IO->SendBuf.fd);
-
+
fd = fopen(fn, "a+");
fprintf(fd, "Send: BufSize: %ld BufContent: [",
nbytes);
StrBufPlain(IO->ErrMsg, errmsg, -1);
break;
default:
- rc = StrBuf_write_one_chunk_callback(watcher->fd, 0/*TODO*/, &IO->SendBuf);
+ rc = StrBuf_write_one_chunk_callback(watcher->fd,
+ 0/*TODO*/,
+ &IO->SendBuf);
}
#ifdef BIGBAD_IODBG
case eDBQuery:
case eConnect:
break;
- case eSendReply:
+ case eSendReply:
case eSendMore:
case eSendFile:
- ev_io_start(event_base, &IO->send_event);
+ ev_io_start(event_base,
+ &IO->send_event);
break;
- case eReadMessage:
+ case eReadMessage:
case eReadMore:
case eReadPayload:
case eReadFile:
}
break;
case eSendReply:
- if (StrBufCheckBuffer(&IO->SendBuf) != eReadSuccess)
+ if (StrBufCheckBuffer(&IO->SendBuf) != eReadSuccess)
break;
IO->NextState = eReadMore;
case eReadMore:
case eReadMessage:
case eReadPayload:
case eReadFile:
- if (StrBufCheckBuffer(&IO->RecvBuf) == eBufferNotEmpty) {
+ if (StrBufCheckBuffer(&IO->RecvBuf) == eBufferNotEmpty)
+ {
HandleInbound(IO);
}
else {
break;
case eDBQuery:
- /* we now live in another queue, so we have to unregister. */
+ /*
+ * we now live in another queue,
+ * so we have to unregister.
+ */
ev_cleanup_stop(loop, &IO->abort_by_shutdown);
break;
case eSendDNSQuery:
static void
set_start_callback(struct ev_loop *loop, AsyncIO *IO, int revents)
{
-
switch(IO->NextState) {
case eReadMore:
case eReadMessage:
}
assert(IO->Timeout);
- switch (IO->Timeout(IO))
+ switch (IO->Timeout(IO))
{
case eAbort:
ShutDownCLient(IO);
become_session(IO->CitContext);
assert(IO->ConnFail);
- switch (IO->ConnFail(IO))
+ switch (IO->ConnFail(IO))
{
case eAbort:
ShutDownCLient(IO);
}
static void
-IO_connfailimmediate_callback(struct ev_loop *loop, ev_idle *watcher, int revents)
+IO_connfailimmediate_callback(struct ev_loop *loop,
+ ev_idle *watcher,
+ int revents)
{
AsyncIO *IO = watcher->data;
become_session(IO->CitContext);
assert(IO->ConnFail);
- switch (IO->ConnFail(IO))
+ switch (IO->ConnFail(IO))
{
case eAbort:
ShutDownCLient(IO);
nbytes = FileRecvChunked(&IO->IOB, &errmsg);
if (nbytes < 0)
StrBufPlain(IO->ErrMsg, errmsg, -1);
- else
+ else
{
if (IO->IOB.ChunkSendRemain == 0)
{
}
break;
default:
- nbytes = StrBuf_read_one_chunk_callback(watcher->fd, 0 /*TODO */, &IO->RecvBuf);
+ nbytes = StrBuf_read_one_chunk_callback(watcher->fd,
+ 0 /*TODO */,
+ &IO->RecvBuf);
break;
}
#ifdef BIGBAD_IODBG
{
+ long nbytes;
int rv = 0;
char fn [SIZ];
FILE *fd;
const char *pch = ChrPtr(IO->RecvBuf.Buf);
const char *pchh = IO->RecvBuf.ReadWritePointer;
- long nbytes;
-
+
if (pchh == NULL)
pchh = pch;
-
+
nbytes = StrLength(IO->RecvBuf.Buf) - (pchh - pch);
snprintf(fn, SIZ, "/tmp/foolog_ev_%s.%d",
- ((CitContext*)(IO->CitContext))->ServiceName,
+ ((CitContext*)(IO->CitContext))->ServiceName,
IO->SendBuf.fd);
-
+
fd = fopen(fn, "a+");
fprintf(fd, "Read: BufSize: %ld BufContent: [",
nbytes);
rv = fwrite(pchh, nbytes, 1, fd);
if (!rv) printf("failed to write debug to %s!\n", fn);
fprintf(fd, "]\n");
-
-
fclose(fd);
}
#endif
return;
} else if (nbytes == -1) {
/// TODO: FD is gone. kick it. sock_buff_invoke_free(sb, errno);
- EV_syslog(LOG_DEBUG,
+ EV_syslog(LOG_DEBUG,
"EVENT: Socket Invalid! %s \n",
strerror(errno));
ShutDownCLient(IO);
IO->rw_timeout.data = IO;
- /* Bypass it like this: IO->Addr.sin_addr.s_addr = inet_addr("127.0.0.1"); */
-/// ((struct sockaddr_in)IO->ConnectMe->Addr).sin_addr.s_addr = inet_addr("127.0.0.1");
+ /* for debugging you may bypass it like this:
+ * IO->Addr.sin_addr.s_addr = inet_addr("127.0.0.1");
+ * ((struct sockaddr_in)IO->ConnectMe->Addr).sin_addr.s_addr =
+ * inet_addr("127.0.0.1");
+ */
if (IO->ConnectMe->IPv6)
rc = connect(IO->SendBuf.fd,
&IO->ConnectMe->Addr,
+/*
+ *
+ * Copyright (c) 1998-2012 by the citadel.org team
+ *
+ * This program is open source 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
+ */
+
#ifndef __EVENT_CLIENT_H__
#define __EVENT_CLIENT_H__
#define EV_COMPAT3 0
eDBQuery,
eConnect,
- eSendReply,
+ eSendReply,
eSendMore,
eSendFile,
- eReadMessage,
+ eReadMessage,
eReadMore,
eReadPayload,
eReadFile,
long tlen;
int dodot;
- int flushing; /* if we read maxlen, read until nothing more arives and ignore this. */
+ int flushing;
+/* if we read maxlen, read until nothing more arives and ignore this. */
int crlf; /* CRLF newlines instead of LF */
} ReadAsyncMsg;
void *Data;
} DNSQueryParts;
-typedef struct _evcurl_request_data
+typedef struct _evcurl_request_data
{
- CURL *chnd;
- struct curl_slist *headers;
- char errdesc[CURL_ERROR_SIZE];
+ CURL *chnd;
+ struct curl_slist *headers;
+ char errdesc[CURL_ERROR_SIZE];
- int attached;
+ int attached;
- char *PlainPostData;
- long PlainPostDataLen;
- StrBuf *PostData;
+ char *PlainPostData;
+ long PlainPostDataLen;
+ StrBuf *PostData;
- StrBuf *ReplyData;
- long httpcode;
+ StrBuf *ReplyData;
+ long httpcode;
} evcurl_request_data;
/* DNS Related */
typedef struct __evcares_data {
- ev_io recv_event,
+ ev_io recv_event,
send_event;
ev_timer timeout; /* timeout while requesting ips */
#ifdef DEBUG_CARES
struct ares_options Options;
ares_channel Channel;
DNSQueryParts *Query;
-
+
IO_CallBack Fail; /* the dns lookup didn't work out. */
} evcares_data;
struct AsyncIO {
long ID;
- eNextState NextState;
+ eNextState NextState;
/* connection related */
ParsedURL *ConnectMe;
-
+
/* read/send related... */
StrBuf *IOBuf;
- IOBuffer SendBuf,
+ IOBuffer SendBuf,
RecvBuf;
- FDIOBuffer IOB; /* when sending from / reading into files, this is used. */
+ FDIOBuffer IOB;
+ /* when sending from / reading into files, this is used. */
/* our events... */
ev_cleanup abort_by_shutdown, /* server wants to go down... */
IO_CallBack ReadDone, /* Theres new data to read... */
SendDone, /* we may send more data */
Terminate, /* shutting down... */
- Timeout, /* Timeout handler; may also be connection timeout */
+ Timeout, /* Timeout handler;may also be conn. timeout */
ConnFail, /* What to do when one connection failed? */
- ShutdownAbort,/* we're going down. make your piece. */
+ ShutdownAbort,/* we're going down. make your piece. */
NextDBOperation; /* Perform Database IO */
- IO_LineReaderCallback LineReader; /* if we have linereaders, maybe we want to read more lines before the real application logic is called? */
+ /* if we have linereaders, maybe we want to read more lines before
+ * the real application logic is called? */
+ IO_LineReaderCallback LineReader;
evcares_data DNS;
struct CtdlMessage *AsyncMsg;
struct recptypes *AsyncRcp;
- /* Custom data; its expected to contain AsyncIO so we can save malloc()s... */
+ /* Context specific data; Hint: put AsyncIO in there */
void *Data; /* application specific data */
void *CitContext; /* Citadel Session context... */
};
typedef struct _IOAddHandler {
AsyncIO *IO;
IO_CallBack EvAttch;
-}IOAddHandler;
+} IOAddHandler;
#define CCID ((CitContext*)IO->CitContext)->cs_pid
-#define EV_syslog(LEVEL, FORMAT, ...) syslog(LEVEL, "IO[%ld]CC[%d]" FORMAT, IO->ID, CCID, __VA_ARGS__)
-#define EVM_syslog(LEVEL, FORMAT) syslog(LEVEL, "IO[%ld]CC[%d]" FORMAT, IO->ID, CCID)
-#define EVNC_syslog(LEVEL, FORMAT, ...) syslog(LEVEL, "IO[%ld]" FORMAT, IO->ID, __VA_ARGS__)
+#define EV_syslog(LEVEL, FORMAT, ...) \
+ syslog(LEVEL, "IO[%ld]CC[%d]" FORMAT, IO->ID, CCID, __VA_ARGS__)
+
+#define EVM_syslog(LEVEL, FORMAT) \
+ syslog(LEVEL, "IO[%ld]CC[%d]" FORMAT, IO->ID, CCID)
+
+#define EVNC_syslog(LEVEL, FORMAT, ...) \
+ syslog(LEVEL, "IO[%ld]" FORMAT, IO->ID, __VA_ARGS__)
+
#define EVNCM_syslog(LEVEL, FORMAT) syslog(LEVEL, "IO[%ld]" FORMAT, IO->ID)
void FreeAsyncIOContents(AsyncIO *IO);
eNextState QueueEventContext(AsyncIO *IO, IO_CallBack CB);
eNextState QueueCurlContext(AsyncIO *IO);
-eNextState EvConnectSock(AsyncIO *IO,
- double conn_timeout,
+eNextState EvConnectSock(AsyncIO *IO,
+ double conn_timeout,
double first_rw_timeout,
int ReadFirst);
void IO_postdns_callback(struct ev_loop *loop, ev_idle *watcher, int revents);
-int QueueQuery(ns_type Type, const char *name, AsyncIO *IO, DNSQueryParts *QueryParts, IO_CallBack PostDNS);
-void QueueGetHostByName(AsyncIO *IO, const char *Hostname, DNSQueryParts *QueryParts, IO_CallBack PostDNS);
+int QueueQuery(ns_type Type,
+ const char *name,
+ AsyncIO *IO,
+ DNSQueryParts *QueryParts,
+ IO_CallBack PostDNS);
+
+void QueueGetHostByName(AsyncIO *IO,
+ const char *Hostname,
+ DNSQueryParts *QueryParts,
+ IO_CallBack PostDNS);
void QueryCbDone(AsyncIO *IO);
#define OPT(s, v) \
do { \
- sta = curl_easy_setopt(chnd, (CURLOPT_##s), (v)); \
+ sta = curl_easy_setopt(chnd, (CURLOPT_##s), (v)); \
if (sta) { \
- syslog(LOG_ERR, "error setting option " #s " on curl handle: %s", curl_easy_strerror(sta)); \
+ syslog(LOG_ERR, \
+ "error setting option " #s \
+ " on curl handle: %s", \
+ curl_easy_strerror(sta)); \
} } while (0)
void InitIOStruct(AsyncIO *IO,
IO_CallBack Terminate,
IO_CallBack ShutdownAbort);
-eNextState ReAttachIO(AsyncIO *IO,
- void *pData,
+eNextState ReAttachIO(AsyncIO *IO,
+ void *pData,
int ReadFirst);
#endif /* __EVENT_CLIENT_H__ */
static void HostByAddrCb(void *data,
- int status,
- int timeouts,
- struct hostent *hostent)
+ int status,
+ int timeouts,
+ struct hostent *hostent)
{
AsyncIO *IO = data;
#ifdef DEBUG_CARES
return;
}
IO->DNS.Query->Data = hostent;
-/// TODO: howto free this??
}
-static void ParseAnswerA(AsyncIO *IO, unsigned char* abuf, int alen)
+static void ParseAnswerA(AsyncIO *IO, unsigned char* abuf, int alen)
{
struct hostent* host;
#ifdef DEBUG_CARES
IO->DNS.Query->DNSReplyFree(IO->DNS.Query->VParsedDNSReply);
IO->DNS.Query->VParsedDNSReply = NULL;
- IO->DNS.Query->DNSStatus = ares_parse_a_reply(abuf, alen, &host, NULL, NULL);
+ IO->DNS.Query->DNSStatus = ares_parse_a_reply(abuf,
+ alen,
+ &host,
+ NULL,
+ NULL);
if (IO->DNS.Query->DNSStatus != ARES_SUCCESS) {
- StrBufPlain(IO->ErrMsg, ares_strerror(IO->DNS.Query->DNSStatus), -1);
+ StrBufPlain(IO->ErrMsg,
+ ares_strerror(IO->DNS.Query->DNSStatus), -1);
return;
}
IO->DNS.Query->VParsedDNSReply = host;
}
-static void ParseAnswerAAAA(AsyncIO *IO, unsigned char* abuf, int alen)
+static void ParseAnswerAAAA(AsyncIO *IO, unsigned char* abuf, int alen)
{
struct hostent* host;
#ifdef DEBUG_CARES
IO->DNS.Query->DNSReplyFree(IO->DNS.Query->VParsedDNSReply);
IO->DNS.Query->VParsedDNSReply = NULL;
- IO->DNS.Query->DNSStatus = ares_parse_aaaa_reply(abuf, alen, &host, NULL, NULL);
+ IO->DNS.Query->DNSStatus = ares_parse_aaaa_reply(abuf,
+ alen,
+ &host,
+ NULL,
+ NULL);
if (IO->DNS.Query->DNSStatus != ARES_SUCCESS) {
- StrBufPlain(IO->ErrMsg, ares_strerror(IO->DNS.Query->DNSStatus), -1);
+ StrBufPlain(IO->ErrMsg,
+ ares_strerror(IO->DNS.Query->DNSStatus), -1);
return;
}
IO->DNS.Query->VParsedDNSReply = host;
}
-static void ParseAnswerCNAME(AsyncIO *IO, unsigned char* abuf, int alen)
+static void ParseAnswerCNAME(AsyncIO *IO, unsigned char* abuf, int alen)
{
struct hostent* host;
IO->DNS.Query->DNSReplyFree(IO->DNS.Query->VParsedDNSReply);
IO->DNS.Query->VParsedDNSReply = NULL;
- IO->DNS.Query->DNSStatus = ares_parse_a_reply(abuf, alen, &host, NULL, NULL);
+ IO->DNS.Query->DNSStatus = ares_parse_a_reply(abuf,
+ alen,
+ &host,
+ NULL,
+ NULL);
if (IO->DNS.Query->DNSStatus != ARES_SUCCESS) {
- StrBufPlain(IO->ErrMsg, ares_strerror(IO->DNS.Query->DNSStatus), -1);
+ StrBufPlain(IO->ErrMsg,
+ ares_strerror(IO->DNS.Query->DNSStatus), -1);
return;
}
}
-static void ParseAnswerMX(AsyncIO *IO, unsigned char* abuf, int alen)
+static void ParseAnswerMX(AsyncIO *IO, unsigned char* abuf, int alen)
{
struct ares_mx_reply *mx_out;
#ifdef DEBUG_CARES
IO->DNS.Query->DNSStatus = ares_parse_mx_reply(abuf, alen, &mx_out);
if (IO->DNS.Query->DNSStatus != ARES_SUCCESS) {
- StrBufPlain(IO->ErrMsg, ares_strerror(IO->DNS.Query->DNSStatus), -1);
+ StrBufPlain(IO->ErrMsg,
+ ares_strerror(IO->DNS.Query->DNSStatus), -1);
return;
}
}
-static void ParseAnswerNS(AsyncIO *IO, unsigned char* abuf, int alen)
+static void ParseAnswerNS(AsyncIO *IO, unsigned char* abuf, int alen)
{
struct hostent* host;
#ifdef DEBUG_CARES
IO->DNS.Query->DNSStatus = ares_parse_ns_reply(abuf, alen, &host);
if (IO->DNS.Query->DNSStatus != ARES_SUCCESS) {
- StrBufPlain(IO->ErrMsg, ares_strerror(IO->DNS.Query->DNSStatus), -1);
+ StrBufPlain(IO->ErrMsg,
+ ares_strerror(IO->DNS.Query->DNSStatus), -1);
return;
}
IO->DNS.Query->VParsedDNSReply = host;
}
-static void ParseAnswerSRV(AsyncIO *IO, unsigned char* abuf, int alen)
+static void ParseAnswerSRV(AsyncIO *IO, unsigned char* abuf, int alen)
{
struct ares_srv_reply *srv_out;
#ifdef DEBUG_CARES
IO->DNS.Query->DNSStatus = ares_parse_srv_reply(abuf, alen, &srv_out);
if (IO->DNS.Query->DNSStatus != ARES_SUCCESS) {
- StrBufPlain(IO->ErrMsg, ares_strerror(IO->DNS.Query->DNSStatus), -1);
+ StrBufPlain(IO->ErrMsg,
+ ares_strerror(IO->DNS.Query->DNSStatus), -1);
return;
}
}
-static void ParseAnswerTXT(AsyncIO *IO, unsigned char* abuf, int alen)
+static void ParseAnswerTXT(AsyncIO *IO, unsigned char* abuf, int alen)
{
struct ares_txt_reply *txt_out;
#ifdef DEBUG_CARES
IO->DNS.Query->DNSStatus = ares_parse_txt_reply(abuf, alen, &txt_out);
if (IO->DNS.Query->DNSStatus != ARES_SUCCESS) {
- StrBufPlain(IO->ErrMsg, ares_strerror(IO->DNS.Query->DNSStatus), -1);
+ StrBufPlain(IO->ErrMsg,
+ ares_strerror(IO->DNS.Query->DNSStatus), -1);
return;
}
IO->DNS.Query->VParsedDNSReply = txt_out;
int status,
int timeouts,
unsigned char* abuf,
- int alen)
+ int alen)
{
AsyncIO *IO = arg;
#ifdef DEBUG_CARES
StrBufPlain(IO->ErrMsg, ares_strerror(status), -1);
IO->DNS.Query->DNSStatus = status;
}
-
+
ev_idle_init(&IO->unwind_stack,
IO_postdns_callback);
IO->unwind_stack.data = IO;
}
}
-void QueueGetHostByNameDone(void *Ctx,
+void QueueGetHostByNameDone(void *Ctx,
int status,
int timeouts,
struct hostent *hostent)
ev_idle_start(event_base, &IO->unwind_stack);
}
-void QueueGetHostByName(AsyncIO *IO, const char *Hostname, DNSQueryParts *QueryParts, IO_CallBack PostDNS)
+void QueueGetHostByName(AsyncIO *IO,
+ const char *Hostname,
+ DNSQueryParts *QueryParts,
+ IO_CallBack PostDNS)
{
#ifdef DEBUG_CARES
EV_syslog(LOG_DEBUG, "C-ARES: %s\n", __FUNCTION__);
ev_timer_init(&IO->DNS.timeout, DNStimeouttrigger_callback, 10, 1);
IO->DNS.timeout.data = IO;
ares_gethostbyname(IO->DNS.Channel,
- Hostname,
+ Hostname,
AF_INET6, /* it falls back to ipv4 in doubt... */
QueueGetHostByNameDone,
IO);
ev_timer_start(event_base, &IO->DNS.timeout);
}
-int QueueQuery(ns_type Type, const char *name, AsyncIO *IO, DNSQueryParts *QueryParts, IO_CallBack PostDNS)
+
+int QueueQuery(ns_type Type,
+ const char *name,
+ AsyncIO *IO,
+ DNSQueryParts *QueryParts,
+ IO_CallBack PostDNS)
{
int length, family;
char address_b[sizeof(struct in6_addr)];
return -1;
}
- ares_gethostbyaddr(IO->DNS.Channel, address_b, length, family, HostByAddrCb, IO);
+ ares_gethostbyaddr(IO->DNS.Channel,
+ address_b,
+ length,
+ family,
+ HostByAddrCb,
+ IO);
ev_timer_start(event_base, &IO->DNS.timeout);
#ifdef DEBUG_CARES
EV_syslog(LOG_DEBUG, "C-ARES: %s X1\n", __FUNCTION__);
static void DNS_send_callback(struct ev_loop *loop, ev_io *watcher, int revents)
{
AsyncIO *IO = watcher->data;
-
+
#ifdef DEBUG_CARES
EV_syslog(LOG_DEBUG, "C-ARES: %s\n", __FUNCTION__);
#endif
- ares_process_fd(IO->DNS.Channel, ARES_SOCKET_BAD, IO->DNS.send_event.fd);
+ ares_process_fd(IO->DNS.Channel,
+ ARES_SOCKET_BAD,
+ IO->DNS.send_event.fd);
}
static void DNS_recv_callback(struct ev_loop *loop, ev_io *watcher, int revents)
{
AsyncIO *IO = watcher->data;
-
+
#ifdef DEBUG_CARES
EV_syslog(LOG_DEBUG, "C-ARES: %s\n", __FUNCTION__);
#endif
- ares_process_fd(IO->DNS.Channel, IO->DNS.recv_event.fd, ARES_SOCKET_BAD);
+ ares_process_fd(IO->DNS.Channel,
+ IO->DNS.recv_event.fd,
+ ARES_SOCKET_BAD);
}
-void SockStateCb(void *data, int sock, int read, int write)
+void SockStateCb(void *data, int sock, int read, int write)
{
AsyncIO *IO = data;
/* already inside of the event queue. */
{
struct sockaddr_in sin = {};
socklen_t slen;
- slen = sizeof(sin);
- if ((IO->DNS.SourcePort == 0) &&
+ slen = sizeof(sin);
+ if ((IO->DNS.SourcePort == 0) &&
(getsockname(sock, &sin, &slen) == 0))
{
IO->DNS.SourcePort = ntohs(sin.sin_port);
ev_io_stop(event_base, &IO->DNS.recv_event);
}
IO->DNS.recv_event.fd = sock;
- ev_io_init(&IO->DNS.recv_event, DNS_recv_callback, IO->DNS.recv_event.fd, EV_READ);
+ ev_io_init(&IO->DNS.recv_event,
+ DNS_recv_callback,
+ IO->DNS.recv_event.fd,
+ EV_READ);
IO->DNS.recv_event.data = IO;
ev_io_start(event_base, &IO->DNS.recv_event);
- }
+ }
if (write) {
if ((IO->DNS.send_event.fd != sock) &&
(IO->DNS.send_event.fd != 0)) {
ev_io_stop(event_base, &IO->DNS.send_event);
}
IO->DNS.send_event.fd = sock;
- ev_io_init(&IO->DNS.send_event, DNS_send_callback, IO->DNS.send_event.fd, EV_WRITE);
+ ev_io_init(&IO->DNS.send_event,
+ DNS_send_callback,
+ IO->DNS.send_event.fd,
+ EV_WRITE);
IO->DNS.send_event.data = IO;
ev_io_start(event_base, &IO->DNS.send_event);
}
{
int r = ares_library_init(ARES_LIB_INIT_ALL);
if (0 != r) {
- // TODO
- // ThrowException(Exception::Error(String::New(ares_strerror(r))));
-//// assert(r == 0);
+
}
}
return "c-ares";
/*****************************************************************************
* libevent / curl integration *
*****************************************************************************/
-#define MOPT(s, v) \
- do { \
- sta = curl_multi_setopt(mhnd, (CURLMOPT_##s), (v)); \
- if (sta) { \
- syslog(LOG_ERR, "EVCURL: error setting option " #s " on curl multi handle: %s\n", curl_easy_strerror(sta)); \
- exit (1); \
- } \
- } while (0)
+#define MOPT(s, v)\
+ do { \
+ sta = curl_multi_setopt(mhnd, (CURLMOPT_##s), (v)); \
+ if (sta) { \
+ syslog(LOG_ERR, "EVCURL: error setting option " \
+ #s " on curl multi handle: %s\n", \
+ curl_easy_strerror(sta)); \
+ exit (1); \
+ } \
+ } while (0)
typedef struct _evcurl_global_data {
- int magic;
- CURLM *mhnd;
- ev_timer timeev;
- int nrun;
+ int magic;
+ CURLM *mhnd;
+ ev_timer timeev;
+ int nrun;
} evcurl_global_data;
ev_async WakeupCurl;
evcurl_global_data global;
static void
-gotstatus(int nnrun)
+gotstatus(int nnrun)
{
- CURLMsg *msg;
- int nmsg;
-
- global.nrun = nnrun;
-
- syslog(LOG_DEBUG, "CURLEV: gotstatus(): about to call curl_multi_info_read\n");
- while ((msg = curl_multi_info_read(global.mhnd, &nmsg))) {
- syslog(LOG_ERR, "EVCURL: got curl multi_info message msg=%d\n", msg->msg);
- if (CURLMSG_DONE == msg->msg) {
- CURL *chnd;
- char *chandle;
- CURLcode sta;
- CURLMcode msta;
- AsyncIO *IO;
-
- chandle = NULL;;
- chnd = msg->easy_handle;
- sta = curl_easy_getinfo(chnd, CURLINFO_PRIVATE, &chandle);
- syslog(LOG_ERR, "EVCURL: request complete\n");
- if (sta)
- syslog(LOG_ERR, "EVCURL: error asking curl for private cookie of curl handle: %s\n", curl_easy_strerror(sta));
- IO = (AsyncIO *)chandle;
-
- ev_io_stop(event_base, &IO->recv_event);
- ev_io_stop(event_base, &IO->send_event);
-
- sta = msg->data.result;
- if (sta) {
- EV_syslog(LOG_ERR, "EVCURL: error description: %s\n", IO->HttpReq.errdesc);
- EV_syslog(LOG_ERR, "EVCURL: error performing request: %s\n", curl_easy_strerror(sta));
- }
- sta = curl_easy_getinfo(chnd, CURLINFO_RESPONSE_CODE, &IO->HttpReq.httpcode);
- if (sta)
- EV_syslog(LOG_ERR, "EVCURL: error asking curl for response code from request: %s\n", curl_easy_strerror(sta));
- EV_syslog(LOG_ERR, "EVCURL: http response code was %ld\n", (long)IO->HttpReq.httpcode);
-
-
- curl_slist_free_all(IO->HttpReq.headers);
- msta = curl_multi_remove_handle(global.mhnd, chnd);
- if (msta)
- EV_syslog(LOG_ERR, "EVCURL: warning problem detaching completed handle from curl multi: %s\n", curl_multi_strerror(msta));
+ CURLMsg *msg;
+ int nmsg;
+
+ global.nrun = nnrun;
+
+ syslog(LOG_DEBUG,
+ "CURLEV: gotstatus(): about to call curl_multi_info_read\n");
+ while ((msg = curl_multi_info_read(global.mhnd, &nmsg))) {
+ syslog(LOG_ERR,
+ "EVCURL: got curl multi_info message msg=%d\n",
+ msg->msg);
+
+ if (CURLMSG_DONE == msg->msg) {
+ CURL *chnd;
+ char *chandle;
+ CURLcode sta;
+ CURLMcode msta;
+ AsyncIO*IO;
+
+ chandle = NULL;;
+ chnd = msg->easy_handle;
+ sta = curl_easy_getinfo(chnd,
+ CURLINFO_PRIVATE,
+ &chandle);
+ syslog(LOG_ERR, "EVCURL: request complete\n");
+ if (sta)
+ syslog(LOG_ERR,
+ "EVCURL: error asking curl for private"
+ " cookie of curl handle: %s\n",
+ curl_easy_strerror(sta));
+ IO = (AsyncIO *)chandle;
+
+ ev_io_stop(event_base, &IO->recv_event);
+ ev_io_stop(event_base, &IO->send_event);
+
+ sta = msg->data.result;
+ if (sta) {
+ EV_syslog(LOG_ERR,
+ "EVCURL: error description: %s\n",
+ IO->HttpReq.errdesc);
+ EV_syslog(LOG_ERR,
+ "EVCURL: error performing request: %s\n",
+ curl_easy_strerror(sta));
+ }
+ sta = curl_easy_getinfo(chnd,
+ CURLINFO_RESPONSE_CODE,
+ &IO->HttpReq.httpcode);
+ if (sta)
+ EV_syslog(LOG_ERR,
+ "EVCURL: error asking curl for "
+ "response code from request: %s\n",
+ curl_easy_strerror(sta));
+ EV_syslog(LOG_ERR,
+ "EVCURL: http response code was %ld\n",
+ (long)IO->HttpReq.httpcode);
+
+
+ curl_slist_free_all(IO->HttpReq.headers);
+ msta = curl_multi_remove_handle(global.mhnd, chnd);
+ if (msta)
+ EV_syslog(LOG_ERR,
+ "EVCURL: warning problem detaching "
+ "completed handle from curl multi: "
+ "%s\n",
+ curl_multi_strerror(msta));
ev_cleanup_stop(event_base, &IO->abort_by_shutdown);
- IO->HttpReq.attached = 0;
- switch(IO->SendDone(IO))
+ IO->HttpReq.attached = 0;
+ switch(IO->SendDone(IO))
{
case eDBQuery:
curl_easy_cleanup(IO->HttpReq.chnd);
case eSendDNSQuery:
case eReadDNSReply:
case eConnect:
- case eSendReply:
+ case eSendReply:
case eSendMore:
case eSendFile:
- case eReadMessage:
+ case eReadMessage:
case eReadMore:
case eReadPayload:
case eReadFile:
RemoveContext(IO->CitContext);
IO->Terminate(IO);
}
- }
- }
+ }
+ }
}
static void
stepmulti(void *data, curl_socket_t fd, int which)
{
- int running_handles = 0;
- CURLMcode msta;
-
- msta = curl_multi_socket_action(global.mhnd, fd, which, &running_handles);
- syslog(LOG_DEBUG, "EVCURL: stepmulti(): calling gotstatus()\n");
- if (msta)
- syslog(LOG_ERR, "EVCURL: error in curl processing events on multi handle, fd %d: %s\n", (int)fd, curl_multi_strerror(msta));
- if (global.nrun != running_handles)
- gotstatus(running_handles);
+ int running_handles = 0;
+ CURLMcode msta;
+
+ msta = curl_multi_socket_action(global.mhnd,
+ fd,
+ which,
+ &running_handles);
+
+ syslog(LOG_DEBUG, "EVCURL: stepmulti(): calling gotstatus()\n");
+ if (msta)
+ syslog(LOG_ERR,
+ "EVCURL: error in curl processing events"
+ "on multi handle, fd %d: %s\n",
+ (int)fd,
+ curl_multi_strerror(msta));
+
+ if (global.nrun != running_handles)
+ gotstatus(running_handles);
}
static void
-gottime(struct ev_loop *loop, ev_timer *timeev, int events) {
- syslog(LOG_DEBUG, "EVCURL: waking up curl for timeout\n");
- stepmulti(NULL, CURL_SOCKET_TIMEOUT, 0);
+gottime(struct ev_loop *loop, ev_timer *timeev, int events)
+{
+ syslog(LOG_DEBUG, "EVCURL: waking up curl for timeout\n");
+ stepmulti(NULL, CURL_SOCKET_TIMEOUT, 0);
}
static void
-got_in(struct ev_loop *loop, ev_io *ioev, int events) {
- syslog(LOG_DEBUG, "EVCURL: waking up curl for io on fd %d\n", (int)ioev->fd);
- stepmulti(ioev->data, ioev->fd, CURL_CSELECT_IN);
+got_in(struct ev_loop *loop, ev_io *ioev, int events)
+{
+ syslog(LOG_DEBUG,
+ "EVCURL: waking up curl for io on fd %d\n",
+ (int)ioev->fd);
+
+ stepmulti(ioev->data, ioev->fd, CURL_CSELECT_IN);
}
static void
-got_out(struct ev_loop *loop, ev_io *ioev, int events) {
- syslog(LOG_DEBUG, "EVCURL: waking up curl for io on fd %d\n", (int)ioev->fd);
- stepmulti(ioev->data, ioev->fd, CURL_CSELECT_OUT);
+got_out(struct ev_loop *loop, ev_io *ioev, int events)
+{
+ syslog(LOG_DEBUG,
+ "EVCURL: waking up curl for io on fd %d\n",
+ (int)ioev->fd);
+
+ stepmulti(ioev->data, ioev->fd, CURL_CSELECT_OUT);
}
static size_t
gotdata(void *data, size_t size, size_t nmemb, void *cglobal) {
- AsyncIO *IO = (AsyncIO*) cglobal;
+ AsyncIO *IO = (AsyncIO*) cglobal;
- if (IO->HttpReq.ReplyData == NULL)
- {
- IO->HttpReq.ReplyData = NewStrBufPlain(NULL, SIZ);
- }
- return CurlFillStrBuf_callback(data, size, nmemb, IO->HttpReq.ReplyData);
+ if (IO->HttpReq.ReplyData == NULL)
+ {
+ IO->HttpReq.ReplyData = NewStrBufPlain(NULL, SIZ);
+ }
+ return CurlFillStrBuf_callback(data,
+ size,
+ nmemb,
+ IO->HttpReq.ReplyData);
}
static int
gotwatchtime(CURLM *multi, long tblock_ms, void *cglobal) {
- syslog(LOG_DEBUG, "EVCURL: gotwatchtime called %ld ms\n", tblock_ms);
- evcurl_global_data *global = cglobal;
- ev_timer_stop(EV_DEFAULT, &global->timeev);
- if (tblock_ms < 0 || 14000 < tblock_ms)
- tblock_ms = 14000;
- ev_timer_set(&global->timeev, 0.5e-3 + 1.0e-3 * tblock_ms, 14.0);
- ev_timer_start(EV_DEFAULT_UC, &global->timeev);
- curl_multi_perform(global, &global->nrun);
- return 0;
+ syslog(LOG_DEBUG, "EVCURL: gotwatchtime called %ld ms\n", tblock_ms);
+ evcurl_global_data *global = cglobal;
+ ev_timer_stop(EV_DEFAULT, &global->timeev);
+ if (tblock_ms < 0 || 14000 < tblock_ms)
+ tblock_ms = 14000;
+ ev_timer_set(&global->timeev, 0.5e-3 + 1.0e-3 * tblock_ms, 14.0);
+ ev_timer_start(EV_DEFAULT_UC, &global->timeev);
+ curl_multi_perform(global, &global->nrun);
+ return 0;
}
static int
-gotwatchsock(CURL *easy, curl_socket_t fd, int action, void *cglobal, void *vIO) {
- evcurl_global_data *global = cglobal;
- CURLM *mhnd = global->mhnd;
- char *f;
- AsyncIO *IO = (AsyncIO*) vIO;
- CURLcode sta;
+gotwatchsock(CURL *easy,
+ curl_socket_t fd,
+ int action,
+ void *cglobal,
+ void *vIO)
+{
+ evcurl_global_data *global = cglobal;
+ CURLM *mhnd = global->mhnd;
+ char *f;
+ AsyncIO *IO = (AsyncIO*) vIO;
+ CURLcode sta;
const char *Action;
if (IO == NULL) {
- sta = curl_easy_getinfo(easy, CURLINFO_PRIVATE, &f);
- if (sta) {
- EV_syslog(LOG_ERR, "EVCURL: error asking curl for private cookie of curl handle: %s\n", curl_easy_strerror(sta));
- return -1;
- }
- IO = (AsyncIO *) f;
- EV_syslog(LOG_DEBUG, "EVCURL: got socket for URL: %s\n", IO->ConnectMe->PlainUrl);
+ sta = curl_easy_getinfo(easy, CURLINFO_PRIVATE, &f);
+ if (sta) {
+ EV_syslog(LOG_ERR,
+ "EVCURL: error asking curl for private "
+ "cookie of curl handle: %s\n",
+ curl_easy_strerror(sta));
+ return -1;
+ }
+ IO = (AsyncIO *) f;
+ EV_syslog(LOG_DEBUG,
+ "EVCURL: got socket for URL: %s\n",
+ IO->ConnectMe->PlainUrl);
+
if (IO->SendBuf.fd != 0)
{
ev_io_stop(event_base, &IO->recv_event);
switch (action)
{
case CURL_POLL_NONE:
- Action = "CURL_POLL_NONE";
+ Action = "CURL_POLL_NONE";
break;
case CURL_POLL_REMOVE:
- Action = "CURL_POLL_REMOVE";
+ Action = "CURL_POLL_REMOVE";
break;
case CURL_POLL_IN:
- Action = "CURL_POLL_IN";
+ Action = "CURL_POLL_IN";
break;
case CURL_POLL_OUT:
- Action = "CURL_POLL_OUT";
+ Action = "CURL_POLL_OUT";
break;
case CURL_POLL_INOUT:
- Action = "CURL_POLL_INOUT";
+ Action = "CURL_POLL_INOUT";
break;
- }
+ }
- EV_syslog(LOG_DEBUG, "EVCURL: gotwatchsock called fd=%d action=%s[%d]\n", (int)fd, Action, action);
+ EV_syslog(LOG_DEBUG,
+ "EVCURL: gotwatchsock called fd=%d action=%s[%d]\n",
+ (int)fd, Action, action);
switch (action)
{
case CURL_POLL_NONE:
- EVM_syslog(LOG_ERR,"EVCURL: called first time to register this sockwatcker\n");
+ EVM_syslog(LOG_ERR,
+ "EVCURL: called first time "
+ "to register this sockwatcker\n");
break;
case CURL_POLL_REMOVE:
- EVM_syslog(LOG_ERR,"EVCURL: called last time to unregister this sockwatcher\n");
- ev_io_stop(event_base, &IO->recv_event);
- ev_io_stop(event_base, &IO->send_event);
+ EVM_syslog(LOG_ERR,
+ "EVCURL: called last time to unregister "
+ "this sockwatcher\n");
+ ev_io_stop(event_base, &IO->recv_event);
+ ev_io_stop(event_base, &IO->send_event);
break;
case CURL_POLL_IN:
- ev_io_start(event_base, &IO->recv_event);
- ev_io_stop(event_base, &IO->send_event);
+ ev_io_start(event_base, &IO->recv_event);
+ ev_io_stop(event_base, &IO->send_event);
break;
case CURL_POLL_OUT:
- ev_io_start(event_base, &IO->send_event);
- ev_io_stop(event_base, &IO->recv_event);
+ ev_io_start(event_base, &IO->send_event);
+ ev_io_stop(event_base, &IO->recv_event);
break;
case CURL_POLL_INOUT:
- ev_io_start(event_base, &IO->send_event);
- ev_io_start(event_base, &IO->recv_event);
+ ev_io_start(event_base, &IO->send_event);
+ ev_io_start(event_base, &IO->recv_event);
break;
- }
- return 0;
+ }
+ return 0;
}
-void curl_init_connectionpool(void)
+void curl_init_connectionpool(void)
{
- CURLM *mhnd ;
-
- ev_timer_init(&global.timeev, &gottime, 14.0, 14.0);
- global.timeev.data = (void *)&global;
- global.nrun = -1;
- CURLcode sta = curl_global_init(CURL_GLOBAL_ALL);
-
- if (sta)
- {
- syslog(LOG_ERR,"EVCURL: error initializing curl library: %s\n", curl_easy_strerror(sta));
- exit(1);
- }
- mhnd = global.mhnd = curl_multi_init();
- if (!mhnd)
- {
- syslog(LOG_ERR,"EVCURL: error initializing curl multi handle\n");
- exit(3);
- }
-
- MOPT(SOCKETFUNCTION, &gotwatchsock);
- MOPT(SOCKETDATA, (void *)&global);
- MOPT(TIMERFUNCTION, &gotwatchtime);
- MOPT(TIMERDATA, (void *)&global);
-
- return;
+ CURLM *mhnd ;
+
+ ev_timer_init(&global.timeev, &gottime, 14.0, 14.0);
+ global.timeev.data = (void *)&global;
+ global.nrun = -1;
+ CURLcode sta = curl_global_init(CURL_GLOBAL_ALL);
+
+ if (sta)
+ {
+ syslog(LOG_ERR,
+ "EVCURL: error initializing curl library: %s\n",
+ curl_easy_strerror(sta));
+
+ exit(1);
+ }
+ mhnd = global.mhnd = curl_multi_init();
+ if (!mhnd)
+ {
+ syslog(LOG_ERR,
+ "EVCURL: error initializing curl multi handle\n");
+ exit(3);
+ }
+
+ MOPT(SOCKETFUNCTION, &gotwatchsock);
+ MOPT(SOCKETDATA, (void *)&global);
+ MOPT(TIMERFUNCTION, &gotwatchtime);
+ MOPT(TIMERDATA, (void *)&global);
+
+ return;
}
int evcurl_init(AsyncIO *IO)
{
- CURLcode sta;
- CURL *chnd;
-
- EVM_syslog(LOG_DEBUG, "EVCURL: evcurl_init called ms\n");
- IO->HttpReq.attached = 0;
- chnd = IO->HttpReq.chnd = curl_easy_init();
- if (!chnd)
- {
- EVM_syslog(LOG_ERR, "EVCURL: error initializing curl handle\n");
- return 0;
- }
-
- OPT(VERBOSE, (long)1);
- /* unset in production */
- OPT(NOPROGRESS, 1L);
- OPT(NOSIGNAL, 1L);
- OPT(FAILONERROR, (long)1);
- OPT(ENCODING, "");
- OPT(FOLLOWLOCATION, (long)0);
- OPT(MAXREDIRS, (long)0);
- OPT(USERAGENT, CITADEL);
-
- OPT(TIMEOUT, (long)1800);
- OPT(LOW_SPEED_LIMIT, (long)64);
- OPT(LOW_SPEED_TIME, (long)600);
- OPT(CONNECTTIMEOUT, (long)600);
- OPT(PRIVATE, (void *)IO);
-
- OPT(FORBID_REUSE, 1);
- OPT(WRITEFUNCTION, &gotdata);
+ CURLcode sta;
+ CURL *chnd;
+
+ EVM_syslog(LOG_DEBUG, "EVCURL: evcurl_init called ms\n");
+ IO->HttpReq.attached = 0;
+ chnd = IO->HttpReq.chnd = curl_easy_init();
+ if (!chnd)
+ {
+ EVM_syslog(LOG_ERR, "EVCURL: error initializing curl handle\n");
+ return 0;
+ }
+
+#if DEBUG
+ OPT(VERBOSE, (long)1);
+#endif
+ OPT(NOPROGRESS, 1L);
+
+ OPT(NOSIGNAL, 1L);
+ OPT(FAILONERROR, (long)1);
+ OPT(ENCODING, "");
+ OPT(FOLLOWLOCATION, (long)0);
+ OPT(MAXREDIRS, (long)0);
+ OPT(USERAGENT, CITADEL);
+
+ OPT(TIMEOUT, (long)1800);
+ OPT(LOW_SPEED_LIMIT, (long)64);
+ OPT(LOW_SPEED_TIME, (long)600);
+ OPT(CONNECTTIMEOUT, (long)600);
+ OPT(PRIVATE, (void *)IO);
+
+ OPT(FORBID_REUSE, 1);
+ OPT(WRITEFUNCTION, &gotdata);
OPT(WRITEDATA, (void *)IO);
OPT(ERRORBUFFER, IO->HttpReq.errdesc);
- if (
- (!IsEmptyStr(config.c_ip_addr))
+ 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);
}
OPT(ENCODING, "");
#endif
- IO->HttpReq.headers = curl_slist_append(IO->HttpReq.headers, "Connection: close");
+ IO->HttpReq.headers = curl_slist_append(IO->HttpReq.headers,
+ "Connection: close");
return 1;
}
-static void IOcurl_abort_shutdown_callback(struct ev_loop *loop, ev_cleanup *watcher, int revents)
+static void IOcurl_abort_shutdown_callback(struct ev_loop *loop,
+ ev_cleanup *watcher,
+ int revents)
{
- CURLMcode msta;
+ CURLMcode msta;
AsyncIO *IO = watcher->data;
EV_syslog(LOG_DEBUG, "EVENT Curl: %s\n", __FUNCTION__);
curl_slist_free_all(IO->HttpReq.headers);
msta = curl_multi_remove_handle(global.mhnd, IO->HttpReq.chnd);
if (msta)
- EV_syslog(LOG_ERR, "EVCURL: warning problem detaching completed handle from curl multi: %s\n", curl_multi_strerror(msta));
-
+ {
+ EV_syslog(LOG_ERR,
+ "EVCURL: warning problem detaching completed handle "
+ "from curl multi: %s\n",
+ curl_multi_strerror(msta));
+ }
+
curl_easy_cleanup(IO->HttpReq.chnd);
IO->HttpReq.chnd = NULL;
ev_cleanup_stop(event_base, &IO->abort_by_shutdown);
IO->ShutdownAbort(IO);
}
eNextState
-evcurl_handle_start(AsyncIO *IO)
+evcurl_handle_start(AsyncIO *IO)
{
CURLMcode msta;
- CURLcode sta;
- CURL *chnd;
+ CURLcode sta;
+ CURL *chnd;
- chnd = IO->HttpReq.chnd;
- EV_syslog(LOG_DEBUG, "EVCURL: Loading URL: %s\n", IO->ConnectMe->PlainUrl);
+ 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(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))
+ else if ((IO->HttpReq.PlainPostDataLen != 0) &&
+ (IO->HttpReq.PlainPostData != NULL))
{
OPT(POSTFIELDS, IO->HttpReq.PlainPostData);
OPT(POSTFIELDSIZE, IO->HttpReq.PlainPostDataLen);
EVM_syslog(LOG_DEBUG, "EVCURL: attaching to curl multi handle\n");
msta = curl_multi_add_handle(global.mhnd, IO->HttpReq.chnd);
if (msta)
- EV_syslog(LOG_ERR, "EVCURL: error attaching to curl multi handle: %s\n", curl_multi_strerror(msta));
+ {
+ EV_syslog(LOG_ERR,
+ "EVCURL: error attaching to curl multi handle: %s\n",
+ curl_multi_strerror(msta));
+ }
+
IO->HttpReq.attached = 1;
ev_async_send (event_base, &WakeupCurl);
- ev_cleanup_init(&IO->abort_by_shutdown,
+ ev_cleanup_init(&IO->abort_by_shutdown,
IOcurl_abort_shutdown_callback);
+
ev_cleanup_start(event_base, &IO->abort_by_shutdown);
return eReadMessage;
}
HashList *InboundEventQueue = NULL;
HashList *InboundEventQueues[2] = { NULL, NULL };
-ev_async AddJob;
+ev_async AddJob;
ev_async ExitEventLoop;
static void QueueEventAddCallback(EV_P_ ev_async *w, int revents)
{
HashList *q;
void *v;
- HashPos *It;
+ HashPos*It;
long len;
const char *Key;
pthread_mutex_init(&EventQueueMutex, NULL);
if (pipe(event_add_pipe) != 0) {
- syslog(LOG_EMERG, "Unable to create pipe for libev queueing: %s\n", strerror(errno));
+ syslog(LOG_EMERG,
+ "Unable to create pipe for libev queueing: %s\n",
+ strerror(errno));
abort();
}
LimitSet.rlim_cur = 1;
InboundEventQueues[1] = NewHash(1, Flathash);
InboundEventQueue = InboundEventQueues[0];
}
+
/*
* this thread operates the select() etc. via libev.
- *
- *
*/
void *client_event_thread(void *arg)
{
return(NULL);
}
-/*------------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------*/
/*
* DB-Queue; does async bdb operations.
* has its own set of handlers.
HashList *DBInboundEventQueue = NULL;
HashList *DBInboundEventQueues[2] = { NULL, NULL };
-ev_async DBAddJob;
+ev_async DBAddJob;
ev_async DBExitEventLoop;
extern void ShutDownDBCLient(AsyncIO *IO);
{
HashList *q;
void *v;
- HashPos *It;
+ HashPos *It;
long len;
const char *Key;
switch (rc)
{
case eAbort:
- ShutDownDBCLient(h->IO);
+ ShutDownDBCLient(h->IO);
default:
- break;
+ break;
}
}
DeleteHashPos(&It);
/*
* this thread operates writing to the message database via libev.
- *
- *
*/
-void *db_event_thread(void *arg)
+void *db_event_thread(void *arg)
{
struct CitContext libev_msg_CC;
-/*
+/*
* File: extnotify.h
* Author: Mathew McBride <matt@mcbridematt.dhs.org> / <matt@comalies>
* Copyright (c) 2008-2009
#include "../eventclient/serv_curl.h"
#define PAGER_CONFIG_MESSAGE "__ Push email settings __"
#define FUNAMBOL_CONFIG_TEXT "funambol"
-#define PAGER_CONFIG_SYSTEM "textmessage"
-#define PAGER_CONFIG_HTTP "httpmessage"
-
+#define PAGER_CONFIG_SYSTEM "textmessage"
+#define PAGER_CONFIG_HTTP "httpmessage"
typedef enum _eNotifyType {
- eNone,
- eFunambol,
+ eNone,
+ eFunambol,
eHttpMessages,
eTextMessage
}eNotifyType;
AsyncIO IO;
} NotifyContext;
-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);
void ExtNotify_PutErrorMessage(NotifyContext *Ctx, StrBuf *ErrMsg);
///void process_notify(long msgnum, void *usrdata);
-
-
-
Ctx->NotifyErrors = NewHash(1, Flathash);
nNext = GetCount(Ctx->NotifyErrors) + 1;
- Put(Ctx->NotifyErrors,
- (char*)&nNext,
- sizeof(int),
- ErrMsg,
+ Put(Ctx->NotifyErrors,
+ (char*)&nNext,
+ sizeof(int),
+ ErrMsg,
HFreeStrBuf);
}
if (Ctx->nNotifyHosts < 1)
return 0;
- Ctx->NotifyHostList = malloc(sizeof(StrBuf*) * 2 * (Ctx->nNotifyHosts + 1));
- memset(Ctx->NotifyHostList, 0, sizeof(StrBuf*) * 2 * (Ctx->nNotifyHosts + 1));
-
+ Ctx->NotifyHostList = malloc(sizeof(StrBuf*) *
+ 2 *
+ (Ctx->nNotifyHosts + 1));
+ memset(Ctx->NotifyHostList, 0,
+ sizeof(StrBuf*) * 2 * (Ctx->nNotifyHosts + 1));
+
NotifyBuf = NewStrBufPlain(NotifyHostsBuf, -1);
/* get all configured notifiers's */
- for (notify=0; notify<Ctx->nNotifyHosts; notify++) {
-
+ for (notify=0; notify<Ctx->nNotifyHosts; notify++) {
+
Host = GetNHBuf(notify * 2, 1, Ctx->NotifyHostList);
StrBufExtract_NextToken(Host, NotifyBuf, &NextHost, '|');
pchs = ChrPtr(Host);
pche = strchr(pchs, ':');
if (pche == NULL) {
- syslog(LOG_ERR,
- "extnotify: filename of notification template not found in %s.\n",
+ syslog(LOG_ERR,
+ "extnotify: filename of notification "
+ "template not found in %s.\n",
pchs);
continue;
}
/*! \brief Get configuration message for pager/funambol system from the
* users "My Citadel Config" room
*/
-eNotifyType extNotify_getConfigMessage(char *username, char **PagerNumber, char **FreeMe)
+eNotifyType extNotify_getConfigMessage(char *username,
+ char **PagerNumber,
+ char **FreeMe)
{
struct ctdlroom qrbuf; // scratch for room
struct ctdluser user; // ctdl user instance
// Get the user
CtdlGetUser(&user, username);
-
- CtdlMailboxName(configRoomName, sizeof configRoomName, &user, USERCONFIGROOM);
+
+ CtdlMailboxName(configRoomName,
+ sizeof(configRoomName),
+ &user,
+ USERCONFIGROOM);
// Fill qrbuf
CtdlGetRoom(&qrbuf, configRoomName);
/* Do something really, really stoopid here. Raid the room on ourselves,
cdbfr = cdb_fetch(CDB_MSGLISTS, &qrbuf.QRnumber, sizeof(long));
if (cdbfr != NULL) {
msglist = (long *) cdbfr->ptr;
- cdbfr->ptr = NULL; /* CtdlForEachMessage() now owns this memory */
+ cdbfr->ptr = NULL;
+ /* CtdlForEachMessage() now owns this memory */
num_msgs = cdbfr->len / sizeof(long);
cdb_free(cdbfr);
} else {
- syslog(LOG_DEBUG, "extNotify_getConfigMessage: No config messages found\n");
+ syslog(LOG_DEBUG,
+ "extNotify_getConfigMessage: "
+ "No config messages found\n");
return eNone; /* No messages at all? No further action. */
}
for (a = 0; a < num_msgs; ++a) {
msg = CtdlFetchMessage(msglist[a], 1);
if (msg != NULL) {
- if ((msg->cm_fields['U'] != NULL) &&
- (strncasecmp(msg->cm_fields['U'], PAGER_CONFIG_MESSAGE,
- strlen(PAGER_CONFIG_MESSAGE)) == 0)) {
+ if ((msg->cm_fields['U'] != NULL) &&
+ (strncasecmp(msg->cm_fields['U'],
+ PAGER_CONFIG_MESSAGE,
+ strlen(PAGER_CONFIG_MESSAGE)) == 0))
+ {
break;
}
CtdlFreeMessage(msg);
msg = NULL;
}
}
-
+
free(msglist);
if (msg == NULL)
return eNone;
if (!pch || (*pch == '\0'))
{
free(configMsg);
-
+
return eNone;
}
- while (isspace(*pch))
+ while (isspace(*pch))
pch ++;
*PagerNumber = pch;
while (isdigit(*pch) || (*pch == '+'))
/*
* Process messages in the external notification queue
*/
-void process_notify(long NotifyMsgnum, void *usrdata)
+void process_notify(long NotifyMsgnum, void *usrdata)
{
NotifyContext *Ctx;
long msgnum = 0;
Ctx = (NotifyContext*) usrdata;
msg = CtdlFetchMessage(NotifyMsgnum, 1);
- if ( msg->cm_fields['2'] != NULL)
+ if ( msg->cm_fields['2'] != NULL)
{
- Type = extNotify_getConfigMessage(msg->cm_fields['2'], &PagerNo, &FreeMe);
-
+ Type = extNotify_getConfigMessage(
+ msg->cm_fields['2'],
+ &PagerNo,
+ &FreeMe);
+
pch = strstr(msg->cm_fields['M'], "msgid|");
- if (pch != NULL)
+ if (pch != NULL)
msgnum = atol(pch + sizeof("msgid"));
switch (Type)
config.c_funambol_port,
FUNAMBOL_WS);
- notify_http_server(remoteurl,
+ notify_http_server(remoteurl,
file_funambol_msg,
strlen(file_funambol_msg),/*GNA*/
- msg->cm_fields['2'],
+ msg->cm_fields['2'],
msg->cm_fields['I'],
- msgnum,
+ msgnum,
NULL);
break;
case eHttpMessages:
char URLBuf[SIZ];
StrBuf *File;
StrBuf *FileBuf = NewStrBuf();
-
+
for (i = 0; i < Ctx->nNotifyHosts; i++)
{
URL = GetNHBuf(i*2, 0, Ctx->NotifyHostList);
if (URL==NULL) break;
- File = GetNHBuf(i*2 + 1, 0, Ctx->NotifyHostList);
+ File = GetNHBuf(i*2 + 1, 0,
+ Ctx->NotifyHostList);
if (File==NULL) break;
if (StrLength(File)>0)
- StrBufPrintf(FileBuf, "%s/%s",
- ctdl_shared_dir,
+ StrBufPrintf(FileBuf, "%s/%s",
+ ctdl_shared_dir,
ChrPtr(File));
else
FlushStrBuf(FileBuf);
memcpy(URLBuf, ChrPtr(URL), StrLength(URL) + 1);
- notify_http_server(URLBuf,
+ notify_http_server(URLBuf,
ChrPtr(FileBuf),
StrLength(FileBuf),
- msg->cm_fields['2'],
+ msg->cm_fields['2'],
msg->cm_fields['I'],
- msgnum,
+ msgnum,
NULL);
}
FreeStrBuf(&FileBuf);
- }
+ }
break;
case eTextMessage:
{
int commandSiz;
char *command;
- commandSiz = sizeof(config.c_pager_program) + strlen(PagerNo) + strlen(msg->cm_fields['2']) + 5;
+ commandSiz = sizeof(config.c_pager_program) +
+ strlen(PagerNo) +
+ strlen(msg->cm_fields['2']) + 5;
+
command = malloc(commandSiz);
- snprintf(command, commandSiz, "%s %s -u %s", config.c_pager_program, PagerNo, msg->cm_fields['2']);
+
+ snprintf(command,
+ commandSiz,
+ "%s %s -u %s",
+ config.c_pager_program,
+ PagerNo,
+ msg->cm_fields['2']);
+
system(command);
free(command);
}
* \brief Run through the pager room queue
* Checks to see what notification option the user has set
*/
-void do_extnotify_queue(void)
+void do_extnotify_queue(void)
{
NotifyContext Ctx;
static int doing_queue = 0;
int i = 0;
-
+
/*
* This is a simple concurrency check to make sure only one queue 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 (IsEmptyStr(config.c_pager_program) &&
+ if (IsEmptyStr(config.c_pager_program) &&
IsEmptyStr(config.c_funambol_host))
{
- syslog(LOG_ERR, "No external notifiers configured on system/user\n");
+ syslog(LOG_ERR,
+ "No external notifiers configured on system/user\n");
return;
}
- if (doing_queue) return;
+ if (doing_queue)
+ return;
+
doing_queue = 1;
become_session(&extnotify_queue_CC);
syslog(LOG_DEBUG, "serv_extnotify: processing notify queue\n");
memset(&Ctx, 0, sizeof(NotifyContext));
- if ((GetNotifyHosts(&Ctx) > 0) &&
+ if ((GetNotifyHosts(&Ctx) > 0) &&
(CtdlGetRoom(&CC->room, FNBL_QUEUE_ROOM) != 0))
{
syslog(LOG_ERR, "Cannot find room <%s>\n", FNBL_QUEUE_ROOM);
*/
void create_extnotify_queue(void) {
struct ctdlroom qrbuf;
-
+
CtdlCreateRoom(FNBL_QUEUE_ROOM, 3, "", 0, 1, 0, VIEW_MAILBOX);
- CtdlFillSystemContext(&extnotify_queue_CC, "Extnotify");
-
+ CtdlFillSystemContext(&extnotify_queue_CC, "Extnotify");
+
/*
* Make sure it's set to be a "system room" so it doesn't show up
* in the <K>nown rooms list for Aides.
CtdlRegisterSessionHook(do_extnotify_queue, EVT_TIMER);
}
/* return our module name for the log */
- return "extnotify";
+ return "extnotify";
}
-/*
+/*
* funambol65.c
* Author: Mathew McBride
- *
+ *
* This module facilitates notifications to a Funambol server
* for push email
*
#include "event_client.h"
+#define POP3C_OK (strncasecmp(ChrPtr(RecvMsg->IO.IOBuf), "+OK", 3) == 0)
+
+#define POP3C_DBG_SEND() \
+ syslog(LOG_DEBUG, \
+ "POP3 client[%ld]: > %s\n", \
+ RecvMsg->n, ChrPtr(RecvMsg->IO.SendBuf.Buf))
+
+#define POP3C_DBG_READ() \
+ syslog(LOG_DEBUG, \
+ "POP3 client[%ld]: < %s\n", \
+ RecvMsg->n, \
+ ChrPtr(RecvMsg->IO.IOBuf))
+
+
struct CitContext pop3_client_CC;
pthread_mutex_t POP3QueueMutex; /* locks the access to the following vars: */
-HashList *POP3QueueRooms = NULL; /* rss_room_counter */
-HashList *POP3FetchUrls = NULL; /* -> rss_aggregator; ->RefCount access to be locked too. */
+HashList *POP3QueueRooms = NULL;
+HashList *POP3FetchUrls = NULL;
+
+typedef struct pop3aggr pop3aggr;
+typedef eNextState(*Pop3ClientHandler)(pop3aggr* RecvMsg);
+
+eNextState POP3_C_Shutdown(AsyncIO *IO);
+eNextState POP3_C_Timeout(AsyncIO *IO);
+eNextState POP3_C_ConnFail(AsyncIO *IO);
+eNextState POP3_C_DNSFail(AsyncIO *IO);
+eNextState POP3_C_DispatchReadDone(AsyncIO *IO);
+eNextState POP3_C_DispatchWriteDone(AsyncIO *IO);
+eNextState POP3_C_Terminate(AsyncIO *IO);
+eReadState POP3_C_ReadServerStatus(AsyncIO *IO);
+eNextState POP3_C_ReAttachToFetchMessages(AsyncIO *IO);
typedef struct __pop3_room_counter {
int count;
free(Item);
}
-typedef struct __pop3aggr {
- AsyncIO IO;
+struct pop3aggr {
+ AsyncIO IO;
long n;
long RefCount;
-/// ParsedURL *Pop3Host;
DNSQueryParts HostLookup;
-// StrBuf *rooms;
long QRnumber;
HashList *OtherQRnumbers;
StrBuf *Url;
-/// StrBuf *pop3host; -> URL
StrBuf *pop3user;
StrBuf *pop3pass;
StrBuf *RoomName; // TODO: fill me
HashList *MsgNumbers;
HashPos *Pos;
FetchItem *CurrMsg;
-} pop3aggr;
+};
void DeletePOP3Aggregator(void *vptr)
{
free(ptr);
}
-
-typedef eNextState(*Pop3ClientHandler)(pop3aggr* RecvMsg);
-
-eNextState POP3_C_Shutdown(AsyncIO *IO);
-eNextState POP3_C_Timeout(AsyncIO *IO);
-eNextState POP3_C_ConnFail(AsyncIO *IO);
-eNextState POP3_C_DNSFail(AsyncIO *IO);
-eNextState POP3_C_DispatchReadDone(AsyncIO *IO);
-eNextState POP3_C_DispatchWriteDone(AsyncIO *IO);
-eNextState POP3_C_Terminate(AsyncIO *IO);
-eReadState POP3_C_ReadServerStatus(AsyncIO *IO);
-eNextState POP3_C_ReAttachToFetchMessages(AsyncIO *IO);
-
eNextState FinalizePOP3AggrRun(AsyncIO *IO)
{
HashPos *It;
return eAbort;
}
-
-#define POP3C_DBG_SEND() syslog(LOG_DEBUG, "POP3 client[%ld]: > %s\n", RecvMsg->n, ChrPtr(RecvMsg->IO.SendBuf.Buf))
-#define POP3C_DBG_READ() syslog(LOG_DEBUG, "POP3 client[%ld]: < %s\n", RecvMsg->n, ChrPtr(RecvMsg->IO.IOBuf))
-#define POP3C_OK (strncasecmp(ChrPtr(RecvMsg->IO.IOBuf), "+OK", 3) == 0)
-
eNextState POP3C_ReadGreeting(pop3aggr *RecvMsg)
{
POP3C_DBG_READ();
eNextState POP3C_SendUser(pop3aggr *RecvMsg)
{
- /* Identify ourselves. NOTE: we have to append a CR to each command. The LF will
- * automatically be appended by sock_puts(). Believe it or not, leaving out the CR
- * will cause problems if the server happens to be Exchange, which is so b0rken it
- * actually barfs on LF-terminated newlines.
+ /* Identify ourselves. NOTE: we have to append a CR to each command.
+ * The LF will automatically be appended by sock_puts(). Believe it
+ * or not, leaving out the CR will cause problems if the server happens
+ * to be Exchange, which is so b0rken it actually barfs on
+ * LF-terminated newlines.
*/
StrBufPrintf(RecvMsg->IO.SendBuf.Buf,
"USER %s\r\n", ChrPtr(RecvMsg->pop3user));
StrBufPrintf(RecvMsg->IO.SendBuf.Buf,
"PASS %s\r\n", ChrPtr(RecvMsg->pop3pass));
syslog(LOG_DEBUG, "<PASS <password>\n");
-// POP3C_DBG_SEND();
+// POP3C_DBG_SEND(); No, we won't write the passvoid to syslog...
return eReadMessage;
}
POP3C_DBG_READ();
if (!POP3C_OK) return eTerminateConnection;
RecvMsg->MsgNumbers = NewHash(1, NULL);
- RecvMsg->State++;
+ RecvMsg->State++;
return eReadMore;
}
FetchItem *OneMsg = NULL;
POP3C_DBG_READ();
- if ((StrLength(RecvMsg->IO.IOBuf) == 1) &&
+ if ((StrLength(RecvMsg->IO.IOBuf) == 1) &&
(ChrPtr(RecvMsg->IO.IOBuf)[0] == '.'))
{
if (GetCount(RecvMsg->MsgNumbers) == 0)
}
#if 0
rc = TestValidateHash(RecvMsg->MsgNumbers);
- if (rc != 0)
+ if (rc != 0)
syslog(LOG_DEBUG, "Hash Invalid: %d\n", rc);
#endif
-
+
Put(RecvMsg->MsgNumbers, LKEY(OneMsg->MSGID), OneMsg, HfreeFetchItem);
#if 0
rc = TestValidateHash(RecvMsg->MsgNumbers);
- if (rc != 0)
+ if (rc != 0)
syslog(LOG_DEBUG, "Hash Invalid: %d\n", rc);
#endif
//RecvMsg->State --; /* read next Line */
struct cdbdata *cdbut;
pop3aggr *RecvMsg = (pop3aggr *) IO->Data;
- if(GetNextHashPos(RecvMsg->MsgNumbers, RecvMsg->Pos, &HKLen, &HKey, &vData))
+ if(GetNextHashPos(RecvMsg->MsgNumbers,
+ RecvMsg->Pos,
+ &HKLen,
+ &HKey,
+ &vData))
{
struct UseTable ut;
if (server_shutting_down)
return eAbort;
-
+
RecvMsg->CurrMsg = (FetchItem*) vData;
- syslog(LOG_DEBUG, "CHECKING: whether %s has already been seen: ", ChrPtr(RecvMsg->CurrMsg->MsgUID));
+ syslog(LOG_DEBUG,
+ "CHECKING: whether %s has already been seen: ",
+ ChrPtr(RecvMsg->CurrMsg->MsgUID));
+
/* Find out if we've already seen this item */
- safestrncpy(ut.ut_msgid,
+ safestrncpy(ut.ut_msgid,
ChrPtr(RecvMsg->CurrMsg->MsgUID),
sizeof(ut.ut_msgid));
ut.ut_timestamp = time(NULL);/// TODO: libev timestamp!
-
+
cdbut = cdb_fetch(CDB_USETABLE, SKEY(RecvMsg->CurrMsg->MsgUID));
if (cdbut != NULL) {
/* Item has already been seen */
syslog(LOG_DEBUG, "YES\n");
cdb_free(cdbut);
-
+
/* rewrite the record anyway, to update the timestamp */
- cdb_store(CDB_USETABLE,
- SKEY(RecvMsg->CurrMsg->MsgUID),
+ cdb_store(CDB_USETABLE,
+ SKEY(RecvMsg->CurrMsg->MsgUID),
&ut, sizeof(struct UseTable) );
RecvMsg->CurrMsg->NeedFetch = 0; ////TODO0;
}
syslog(LOG_DEBUG, "NO\n");
RecvMsg->CurrMsg->NeedFetch = 1;
}
- return NextDBOperation(&RecvMsg->IO, POP3_FetchNetworkUsetableEntry);
+ return NextDBOperation(&RecvMsg->IO,
+ POP3_FetchNetworkUsetableEntry);
}
else
{
- /* ok, now we know them all, continue with reading the actual messages. */
+ /* ok, now we know them all,
+ * continue with reading the actual messages. */
DeleteHashPos(&RecvMsg->Pos);
return QueueEventContext(IO, POP3_C_ReAttachToFetchMessages);
#if 0
int rc;
rc = TestValidateHash(RecvMsg->MsgNumbers);
- if (rc != 0)
+ if (rc != 0)
syslog(LOG_DEBUG, "Hash Invalid: %d\n", rc);
#endif
- if(GetNextHashPos(RecvMsg->MsgNumbers, RecvMsg->Pos, &HKLen, &HKey, &vData))
+ if(GetNextHashPos(RecvMsg->MsgNumbers,
+ RecvMsg->Pos,
+ &HKLen, &HKey,
+ &vData))
{
RecvMsg->CurrMsg = (FetchItem*) vData;
- /* Find out the UIDL of the message, to determine whether we've already downloaded it */
+ /* Find out the UIDL of the message,
+ * to determine whether we've already downloaded it */
StrBufPrintf(RecvMsg->IO.SendBuf.Buf,
"UIDL %ld\r\n", RecvMsg->CurrMsg->MSGID);
POP3C_DBG_SEND();
DeleteHashPos(&RecvMsg->Pos);
/// done receiving uidls.. start looking them up now.
RecvMsg->Pos = GetNewHashPos(RecvMsg->MsgNumbers, 0);
- return QueueDBOperation(&RecvMsg->IO, POP3_FetchNetworkUsetableEntry);
+ return QueueDBOperation(&RecvMsg->IO,
+ POP3_FetchNetworkUsetableEntry);
}
return eReadMore; /* TODO */
}
#if 0
int rc;
rc = TestValidateHash(RecvMsg->MsgNumbers);
- if (rc != 0)
+ if (rc != 0)
syslog(LOG_DEBUG, "Hash Invalid: %d\n", rc);
#endif
POP3C_DBG_READ();
if (!POP3C_OK) return eTerminateConnection;
- RecvMsg->CurrMsg->MsgUIDL = NewStrBufPlain(NULL, StrLength(RecvMsg->IO.IOBuf));
- RecvMsg->CurrMsg->MsgUID = NewStrBufPlain(NULL, StrLength(RecvMsg->IO.IOBuf) * 2);
+ RecvMsg->CurrMsg->MsgUIDL =
+ NewStrBufPlain(NULL, StrLength(RecvMsg->IO.IOBuf));
+ RecvMsg->CurrMsg->MsgUID =
+ NewStrBufPlain(NULL, StrLength(RecvMsg->IO.IOBuf) * 2);
- StrBufExtract_token(RecvMsg->CurrMsg->MsgUIDL, RecvMsg->IO.IOBuf, 2, ' ');
- StrBufPrintf(RecvMsg->CurrMsg->MsgUID,
- "pop3/%s/%s:%s@%s",
- ChrPtr(RecvMsg->RoomName),
+ StrBufExtract_token(RecvMsg->CurrMsg->MsgUIDL,
+ RecvMsg->IO.IOBuf, 2, ' ');
+
+ StrBufPrintf(RecvMsg->CurrMsg->MsgUID,
+ "pop3/%s/%s:%s@%s",
+ ChrPtr(RecvMsg->RoomName),
ChrPtr(RecvMsg->CurrMsg->MsgUIDL),
RecvMsg->IO.ConnectMe->User,
RecvMsg->IO.ConnectMe->Host);
void *vData;
RecvMsg->CurrMsg = NULL;
- while (GetNextHashPos(RecvMsg->MsgNumbers, RecvMsg->Pos, &HKLen, &HKey, &vData) &&
- (RecvMsg->CurrMsg = (FetchItem*) vData, RecvMsg->CurrMsg->NeedFetch == 0))
+ while (GetNextHashPos(RecvMsg->MsgNumbers,
+ RecvMsg->Pos,
+ &HKLen, &HKey,
+ &vData) &&
+ (RecvMsg->CurrMsg = (FetchItem*) vData,
+ RecvMsg->CurrMsg->NeedFetch == 0))
{}
if ((RecvMsg->CurrMsg != NULL ) && (RecvMsg->CurrMsg->NeedFetch == 1))
{
- /* Message has not been seen. Tell the server to fetch the message... */
+ /* Message has not been seen.
+ * Tell the server to fetch the message... */
StrBufPrintf(RecvMsg->IO.SendBuf.Buf,
"RETR %ld\r\n", RecvMsg->CurrMsg->MSGID);
POP3C_DBG_SEND();
{
POP3C_DBG_READ();
if (!POP3C_OK) return eTerminateConnection;
- RecvMsg->IO.ReadMsg = NewAsyncMsg(HKEY("."),
+ RecvMsg->IO.ReadMsg = NewAsyncMsg(HKEY("."),
RecvMsg->CurrMsg->MSGSize,
- config.c_maxmsglen,
+ config.c_maxmsglen,
NULL, -1,
1);
return eReadPayload;
-}
+}
eNextState POP3C_StoreMsgRead(AsyncIO *IO)
pop3aggr *RecvMsg = (pop3aggr *) IO->Data;
struct UseTable ut;
- syslog(LOG_DEBUG, "MARKING: %s as seen: ", ChrPtr(RecvMsg->CurrMsg->MsgUID));
+ syslog(LOG_DEBUG,
+ "MARKING: %s as seen: ",
+ ChrPtr(RecvMsg->CurrMsg->MsgUID));
- safestrncpy(ut.ut_msgid,
+ safestrncpy(ut.ut_msgid,
ChrPtr(RecvMsg->CurrMsg->MsgUID),
sizeof(ut.ut_msgid));
ut.ut_timestamp = time(NULL); /* TODO: use libev time */
- cdb_store(CDB_USETABLE,
- ChrPtr(RecvMsg->CurrMsg->MsgUID),
+ cdb_store(CDB_USETABLE,
+ ChrPtr(RecvMsg->CurrMsg->MsgUID),
StrLength(RecvMsg->CurrMsg->MsgUID),
- &ut,
+ &ut,
sizeof(struct UseTable) );
return QueueEventContext(&RecvMsg->IO, POP3_C_ReAttachToFetchMessages);
pop3aggr *RecvMsg = (pop3aggr *) IO->Data;
/* Do Something With It (tm) */
- msgnum = CtdlSubmitMsg(RecvMsg->CurrMsg->Msg,
- NULL,
- ChrPtr(RecvMsg->RoomName),
+ msgnum = CtdlSubmitMsg(RecvMsg->CurrMsg->Msg,
+ NULL,
+ ChrPtr(RecvMsg->RoomName),
0);
- if (msgnum > 0L) {
- /* Message has been committed to the store */
- /* write the uidl to the use table so we don't fetch this message again */
+ if (msgnum > 0L)
+ {
+ /* Message has been committed to the store
+ * write the uidl to the use table
+ * so we don't fetch this message again
+ */
}
CtdlFreeMessage(RecvMsg->CurrMsg->Msg);
eNextState POP3C_ReadMessageBody(pop3aggr *RecvMsg)
{
syslog(LOG_DEBUG, "Converting message...\n");
- RecvMsg->CurrMsg->Msg = convert_internet_message_buf(&RecvMsg->IO.ReadMsg->MsgBuf);
+ RecvMsg->CurrMsg->Msg =
+ convert_internet_message_buf(&RecvMsg->IO.ReadMsg->MsgBuf);
return QueueDBOperation(&RecvMsg->IO, POP3C_SaveMsg);
}
Timeout = POP3_C_ReadTimeouts[pMsg->State];
/*
if (pMsg->State == eDATATerminateBody) {
- / *
+ / *
* some mailservers take a nap before accepting the message
* content inspection and such.
* /
syslog(LOG_DEBUG, "POP3: %s\n", __FUNCTION__);
//// pop3aggr *pMsg = IO->Data;
- ////pMsg->MyQEntry->Status = 3;
- ///StrBufPlain(pMsg->MyQEntry->StatusMessage, HKEY("server shutdown during message retrieval."));
+////pMsg->MyQEntry->Status = 3;
+///StrBufPlain(pMsg->MyQEntry->StatusMessage, HKEY("server shutdown during message retrieval."));
FinalizePOP3AggrRun(IO);
return eAbort;
}
/**
- * @brief lineread Handler; understands when to read more POP3 lines, and when this is a one-lined reply.
+ * @brief lineread Handler; understands when to read more POP3 lines,
+ * and when this is a one-lined reply.
*/
eReadState POP3_C_ReadServerStatus(AsyncIO *IO)
{
- eReadState Finished = eBufferNotEmpty;
+ eReadState Finished = eBufferNotEmpty;
switch (IO->NextState) {
case eSendDNSQuery:
Finished = eReadFail;
break;
case eSendFile:
- case eSendReply:
+ case eSendReply:
case eSendMore:
case eReadMore:
- case eReadMessage:
+ case eReadMessage:
Finished = StrBufChunkSipLine(IO->IOBuf, &IO->RecvBuf);
break;
case eReadFile:
memcpy(&cpptr->IO.ConnectMe->Addr.sin6_addr.s6_addr,
&hostent->h_addr_list[0],
sizeof(struct in6_addr));
-
- cpptr->IO.ConnectMe->Addr.sin6_family = hostent->h_addrtype;
- cpptr->IO.ConnectMe->Addr.sin6_port = htons(DefaultPOP3Port);
+
+ cpptr->IO.ConnectMe->Addr.sin6_family =
+ hostent->h_addrtype;
+ cpptr->IO.ConnectMe->Addr.sin6_port =
+ htons(DefaultPOP3Port);
}
else {
- struct sockaddr_in *addr = (struct sockaddr_in*) &cpptr->IO.ConnectMe->Addr;
- /* Bypass the ns lookup result like this: IO->Addr.sin_addr.s_addr = inet_addr("127.0.0.1"); */
-// addr->sin_addr.s_addr = htonl((uint32_t)&hostent->h_addr_list[0]);
- memcpy(&addr->sin_addr.s_addr,
- hostent->h_addr_list[0],
+ struct sockaddr_in *addr =
+ (struct sockaddr_in*)
+ &cpptr->IO.ConnectMe->Addr;
+
+ memcpy(&addr->sin_addr.s_addr,
+ hostent->h_addr_list[0],
sizeof(uint32_t));
-
+
addr->sin_family = hostent->h_addrtype;
addr->sin_port = htons(DefaultPOP3Port);
-
}
return pop3_connect_ip(IO);
}
eNextState pop3_get_one_host_ip(AsyncIO *IO)
{
pop3aggr *cpptr = IO->Data;
- /*
+ /*
* here we start with the lookup of one host. it might be...
* - the relay host *sigh*
* - the direct hostname if there was no mx record
* - one of the mx'es
- */
+ */
InitC_ares_dns(IO);
syslog(LOG_DEBUG, "POP3: %s\n", __FUNCTION__);
syslog(LOG_DEBUG,
- "POP3 client[%ld]: looking up %s-Record %s : %d ...\n",
- cpptr->n,
+ "POP3 client[%ld]: looking up %s-Record %s : %d ...\n",
+ cpptr->n,
(cpptr->IO.ConnectMe->IPv6)? "aaaa": "a",
- cpptr->IO.ConnectMe->Host,
+ cpptr->IO.ConnectMe->Host,
cpptr->IO.ConnectMe->Port);
- QueueQuery((cpptr->IO.ConnectMe->IPv6)? ns_t_aaaa : ns_t_a,
- cpptr->IO.ConnectMe->Host,
- &cpptr->IO,
- &cpptr->HostLookup,
+ QueueQuery((cpptr->IO.ConnectMe->IPv6)? ns_t_aaaa : ns_t_a,
+ cpptr->IO.ConnectMe->Host,
+ &cpptr->IO,
+ &cpptr->HostLookup,
pop3_get_one_host_ip_done);
IO->NextState = eReadDNSReply;
return IO->NextState;
pthread_mutex_lock(&POP3QueueMutex);
if (GetHash(POP3QueueRooms, LKEY(qrbuf->QRnumber), &vptr))
{
- syslog(LOG_DEBUG,
- "pop3client: [%ld] %s already in progress.\n",
- qrbuf->QRnumber,
+ syslog(LOG_DEBUG,
+ "pop3client: [%ld] %s already in progress.\n",
+ qrbuf->QRnumber,
qrbuf->QRname);
pthread_mutex_unlock(&POP3QueueMutex);
}
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);
return;
}
if (server_shutting_down)
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;
}
if (server_shutting_down)
close(fd);
if (server_shutting_down)
return;
-
+
CfgPtr = NULL;
CfgType = NewStrBuf();
Line = NewStrBufPlain(NULL, StrLength(CfgData));
/*
if (Count == NULL)
{
- Count = malloc(sizeof(pop3_room_counter));
+ Count = malloc(sizeof(pop3_room_counter));
Count->count = 0;
}
Count->count ++;
*/
cptr = (pop3aggr *) malloc(sizeof(pop3aggr));
memset(cptr, 0, sizeof(pop3aggr));
- /// TODO do we need this? cptr->roomlist_parts = 1;
- cptr->RoomName = NewStrBufPlain(qrbuf->QRname, -1);
- cptr->pop3user = NewStrBufPlain(NULL, StrLength(Line));
- cptr->pop3pass = NewStrBufPlain(NULL, StrLength(Line));
+ ///TODO do we need this? cptr->roomlist_parts=1;
+ cptr->RoomName =
+ NewStrBufPlain(qrbuf->QRname, -1);
+ cptr->pop3user =
+ NewStrBufPlain(NULL, StrLength(Line));
+ cptr->pop3pass =
+ NewStrBufPlain(NULL, StrLength(Line));
cptr->Url = NewStrBuf();
Tmp = NewStrBuf();
StrBufExtract_NextToken(Tmp, Line, &lPtr, '|');
- StrBufExtract_NextToken(cptr->pop3user, Line, &lPtr, '|');
- StrBufExtract_NextToken(cptr->pop3pass, Line, &lPtr, '|');
- cptr->keep = StrBufExtractNext_long(Line, &lPtr, '|');
- cptr->interval = StrBufExtractNext_long(Line, &lPtr, '|');
-
- StrBufPrintf(cptr->Url, "pop3://%s:%s@%s/%s",
+ StrBufExtract_NextToken(cptr->pop3user,
+ Line,
+ &lPtr,
+ '|');
+
+ StrBufExtract_NextToken(cptr->pop3pass,
+ Line,
+ &lPtr,
+ '|');
+
+ cptr->keep = StrBufExtractNext_long(Line,
+ &lPtr,
+ '|');
+
+ cptr->interval = StrBufExtractNext_long(Line,
+ &lPtr,
+ '|');
+
+ StrBufPrintf(cptr->Url, "pop3://%s:%s@%s/%s",
ChrPtr(cptr->pop3user),
- ChrPtr(cptr->pop3pass),
- ChrPtr(Tmp),
+ ChrPtr(cptr->pop3pass),
+ ChrPtr(Tmp),
ChrPtr(cptr->RoomName));
FreeStrBuf(&Tmp);
ParseURL(&cptr->IO.ConnectMe, cptr->Url, 110);
-#if 0
+#if 0
/* todo: we need to reunite the url to be shure. */
-
+
pthread_mutex_lock(&POP3ueueMutex);
GetHash(POP3FetchUrls, SKEY(ptr->Url), &vptr);
use_this_cptr = (pop3aggr *)vptr;
-
+
if (use_this_rncptr != NULL)
{
/* mustn't attach to an active session */
DeletePOP3Cfg(cptr);
/// Count->count--;
}
- else
+ else
{
long *QRnumber;
- StrBufAppendBufPlain(use_this_cptr->rooms,
- qrbuf->QRname,
- -1, 0);
+ StrBufAppendBufPlain(
+ use_this_cptr->rooms,
+ qrbuf->QRname,
+ -1, 0);
if (use_this_cptr->roomlist_parts == 1)
{
- use_this_cptr->OtherQRnumbers = NewHash(1, lFlathash);
+ use_this_cptr->OtherQRnumbers
+ = NewHash(1, lFlathash);
}
QRnumber = (long*)malloc(sizeof(long));
*QRnumber = qrbuf->QRnumber;
- Put(use_this_cptr->OtherQRnumbers, LKEY(qrbuf->QRnumber), QRnumber, NULL);
+ Put(use_this_cptr->OtherQRnumbers,
+ LKEY(qrbuf->QRnumber),
+ QRnumber,
+ NULL);
+
use_this_cptr->roomlist_parts++;
}
pthread_mutex_unlock(&POP3QueueMutex);
#endif
pthread_mutex_lock(&POP3QueueMutex);
- Put(POP3FetchUrls, SKEY(cptr->Url), cptr, DeletePOP3Aggregator);
+ Put(POP3FetchUrls,
+ SKEY(cptr->Url),
+ cptr,
+ DeletePOP3Aggregator);
+
pthread_mutex_unlock(&POP3QueueMutex);
}
}
/*
- * This is a simple concurrency check to make sure only one pop3client 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 pop3client
+ * 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.
*/
pthread_mutex_lock(&POP3QueueMutex);
it = GetNewHashPos(POP3FetchUrls, 0);
- while (!server_shutting_down &&
- GetNextHashPos(POP3FetchUrls, it, &len, &Key, &vrptr) &&
+ while (!server_shutting_down &&
+ GetNextHashPos(POP3FetchUrls, it, &len, &Key, &vrptr) &&
(vrptr != NULL)) {
cptr = (pop3aggr *)vrptr;
- if (cptr->RefCount == 0)
+ if (cptr->RefCount == 0)
if (!pop3_do_fetching(cptr))
DeletePOP3Aggregator(cptr);////TODO
/*
- if ((palist->interval && time(NULL) > (last_run + palist->interval))
+ if ((palist->interval && time(NULL) > (last_run + palist->interval))
|| (time(NULL) > last_run + config.c_pop3_fetch))
- pop3_do_fetching(palist->roomname, palist->pop3host,
- palist->pop3user, palist->pop3pass, palist->keep);
+ pop3_do_fetching(palist->roomname, palist->pop3host,
+ palist->pop3user, palist->pop3pass, palist->keep);
pptr = palist;
palist = palist->next;
free(pptr);
POP3QueueRooms = NewHash(1, lFlathash);
POP3FetchUrls = NewHash(1, NULL);
CtdlRegisterSessionHook(pop3client_scan, EVT_TIMER);
- CtdlRegisterCleanupHook(pop3_cleanup);
+ CtdlRegisterCleanupHook(pop3_cleanup);
}
/* return our module id for the log */
- return "pop3client";
+ return "pop3client";
}
}
-/*******************************************************************************
- * XML-Handler *
- *******************************************************************************/
+/******************************************************************************
+ * XML-Handler *
+ ******************************************************************************/
-void RSS_item_rss_start (StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, const char** Attr)
+void RSS_item_rss_start (StrBuf *CData,
+ rss_item *ri,
+ rss_aggregator *Cfg,
+ const char** Attr)
{
syslog(LOG_DEBUG, "RSS: This is an RSS feed.\n");
Cfg->ItemType = RSS_RSS;
}
-void RSS_item_rdf_start(StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, const char** Attr)
+void RSS_item_rdf_start(StrBuf *CData,
+ rss_item *ri,
+ rss_aggregator *Cfg,
+ const char** Attr)
{
syslog(LOG_DEBUG, "RSS: This is an RDF feed.\n");
Cfg->ItemType = RSS_RSS;
}
-void ATOM_item_feed_start(StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, const char** Attr)
+void ATOM_item_feed_start(StrBuf *CData,
+ rss_item *ri,
+ rss_aggregator *Cfg,
+ const char** Attr)
{
syslog(LOG_DEBUG, "RSS: This is an ATOM feed.\n");
Cfg->ItemType = RSS_ATOM;
}
-void RSS_item_item_start(StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, const char** Attr)
+void RSS_item_item_start(StrBuf *CData,
+ rss_item *ri,
+ rss_aggregator *Cfg,
+ const char** Attr)
{
ri->item_tag_nesting ++;
flush_rss_item(ri);
}
-void ATOM_item_entry_start(StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, const char** Attr)
+void ATOM_item_entry_start(StrBuf *CData,
+ rss_item *ri,
+ rss_aggregator *Cfg,
+ const char** Attr)
{
/* Atom feed... */
ri->item_tag_nesting ++;
flush_rss_item(ri);
}
-void ATOM_item_link_start (StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, const char** Attr)
+void ATOM_item_link_start (StrBuf *CData,
+ rss_item *ri,
+ rss_aggregator *Cfg,
+ const char** Attr)
{
int i;
const char *pHref = NULL;
if (pHref == NULL)
return; /* WHUT? Pointing... where? */
if ((pType != NULL) && !strcasecmp(pType, "application/atom+xml"))
- return; /* these just point to other rss resources, we're not interested in them. */
+ return;
+ /* these just point to other rss resources,
+ we're not interested in them. */
if (pRel != NULL)
{
if (!strcasecmp (pRel, "replies"))
{
NewStrBufDupAppendFlush(&ri->reLink, NULL, pHref, -1);
StrBufTrim(ri->link);
- NewStrBufDupAppendFlush(&ri->reLinkTitle, NULL, pTitle, -1);
+ NewStrBufDupAppendFlush(&ri->reLinkTitle,
+ NULL,
+ pTitle,
+ -1);
}
- else if (!strcasecmp(pRel, "alternate")) /* Alternative representation of this Item... */
- {
+ else if (!strcasecmp(pRel, "alternate"))
+ { /* Alternative representation of this Item... */
NewStrBufDupAppendFlush(&ri->link, NULL, pHref, -1);
StrBufTrim(ri->link);
- NewStrBufDupAppendFlush(&ri->linkTitle, NULL, pTitle, -1);
+ NewStrBufDupAppendFlush(&ri->linkTitle,
+ NULL,
+ pTitle,
+ -1);
}
#if 0 /* these are also defined, but dunno what to do with them.. */
{
}
else if (!strcasecmp(pRel, "enclosure"))
- {/* this reference can get big, and is probably the full article... */
+ {/*...reference can get big, and is probably the full article*/
}
else if (!strcasecmp(pRel, "via"))
{/* this article was provided via... */
-void ATOMRSS_item_title_end(StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, const char** Attr)
+void ATOMRSS_item_title_end(StrBuf *CData,
+ rss_item *ri,
+ rss_aggregator *Cfg,
+ const char** Attr)
{
if ((ri->item_tag_nesting == 0) && (StrLength(CData) > 0)) {
NewStrBufDupAppendFlush(&ri->channel_title, CData, NULL, 0);
}
}
-void RSS_item_guid_end(StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, const char** Attr)
+void RSS_item_guid_end(StrBuf *CData,
+ rss_item *ri,
+ rss_aggregator *Cfg,
+ const char** Attr)
{
if (StrLength(CData) > 0) {
NewStrBufDupAppendFlush(&ri->guid, CData, NULL, 0);
}
}
-void ATOM_item_id_end(StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, const char** Attr)
+void ATOM_item_id_end(StrBuf *CData,
+ rss_item *ri, rss_aggregator *Cfg, const char** Attr)
{
if (StrLength(CData) > 0) {
NewStrBufDupAppendFlush(&ri->guid, CData, NULL, 0);
}
-void RSS_item_link_end (StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, const char** Attr)
+void RSS_item_link_end (StrBuf *CData,
+ rss_item *ri,
+ rss_aggregator *Cfg,
+ const char** Attr)
{
if (StrLength(CData) > 0) {
NewStrBufDupAppendFlush(&ri->link, CData, NULL, 0);
StrBufTrim(ri->link);
}
}
-void RSS_item_relink_end(StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, const char** Attr)
+void RSS_item_relink_end(StrBuf *CData,
+ rss_item *ri,
+ rss_aggregator *Cfg,
+ const char** Attr)
{
if (StrLength(CData) > 0) {
NewStrBufDupAppendFlush(&ri->reLink, CData, NULL, 0);
}
}
-void RSSATOM_item_title_end (StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, const char** Attr)
+void RSSATOM_item_title_end (StrBuf *CData,
+ rss_item *ri,
+ rss_aggregator *Cfg,
+ const char** Attr)
{
if (StrLength(CData) > 0) {
NewStrBufDupAppendFlush(&ri->title, CData, NULL, 0);
}
}
-void ATOM_item_content_end (StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, const char** Attr)
+void ATOM_item_content_end (StrBuf *CData,
+ rss_item *ri,
+ rss_aggregator *Cfg,
+ const char** Attr)
{
long olen = StrLength (ri->description);
long clen = StrLength (CData);
- if (clen > 0)
+ if (clen > 0)
{
if (olen == 0) {
- NewStrBufDupAppendFlush(&ri->description, CData, NULL, 0);
+ NewStrBufDupAppendFlush(&ri->description,
+ CData,
+ NULL,
+ 0);
StrBufTrim(ri->description);
}
else if (olen < clen) {
FlushStrBuf(ri->description);
- NewStrBufDupAppendFlush(&ri->description, CData, NULL, 0);
+ NewStrBufDupAppendFlush(&ri->description,
+ CData,
+ NULL,
+ 0);
+
StrBufTrim(ri->description);
}
}
}
-void ATOM_item_summary_end (StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, const char** Attr)
+void ATOM_item_summary_end (StrBuf *CData,
+ rss_item *ri,
+ rss_aggregator *Cfg,
+ const char** Attr)
{
- /* this can contain an abstract of the article. but we don't want to verwrite a full document if we already have it. */
+ /*
+ * this can contain an abstract of the article.
+ * but we don't want to verwrite a full document if we already have it.
+ */
if ((StrLength(CData) > 0) && (StrLength(ri->description) == 0))
{
NewStrBufDupAppendFlush(&ri->description, CData, NULL, 0);
}
}
-void RSS_item_description_end (StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, const char** Attr)
+void RSS_item_description_end (StrBuf *CData,
+ rss_item *ri,
+ rss_aggregator *Cfg,
+ const char** Attr)
{
long olen = StrLength (ri->description);
long clen = StrLength (CData);
- if (clen > 0)
+ if (clen > 0)
{
if (olen == 0) {
- NewStrBufDupAppendFlush(&ri->description, CData, NULL, 0);
+ NewStrBufDupAppendFlush(&ri->description,
+ CData,
+ NULL,
+ 0);
StrBufTrim(ri->description);
}
else if (olen < clen) {
FlushStrBuf(ri->description);
- NewStrBufDupAppendFlush(&ri->description, CData, NULL, 0);
+ NewStrBufDupAppendFlush(&ri->description,
+ CData,
+ NULL,
+ 0);
StrBufTrim(ri->description);
}
}
}
-void ATOM_item_published_end (StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, const char** Attr)
-{
+void ATOM_item_published_end (StrBuf *CData,
+ rss_item *ri,
+ rss_aggregator *Cfg,
+ const char** Attr)
+{
if (StrLength(CData) > 0) {
StrBufTrim(CData);
ri->pubdate = rdf_parsedate(ChrPtr(CData));
}
}
-void ATOM_item_updated_end (StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, const char** Attr)
+void ATOM_item_updated_end (StrBuf *CData,
+ rss_item *ri,
+ rss_aggregator *Cfg,
+ const char** Attr)
{
if (StrLength(CData) > 0) {
StrBufTrim(CData);
}
}
-void RSS_item_pubdate_end (StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, const char** Attr)
+void RSS_item_pubdate_end (StrBuf *CData,
+ rss_item *ri,
+ rss_aggregator *Cfg,
+ const char** Attr)
{
if (StrLength(CData) > 0) {
StrBufTrim(CData);
}
-void RSS_item_date_end (StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, const char** Attr)
+void RSS_item_date_end (StrBuf *CData,
+ rss_item *ri,
+ rss_aggregator *Cfg,
+ const char** Attr)
{
if (StrLength(CData) > 0) {
StrBufTrim(CData);
-void RSS_item_author_end(StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, const char** Attr)
+void RSS_item_author_end(StrBuf *CData,
+ rss_item *ri,
+ rss_aggregator *Cfg,
+ const char** Attr)
{
if (StrLength(CData) > 0) {
NewStrBufDupAppendFlush(&ri->author_or_creator, CData, NULL, 0);
}
-void ATOM_item_name_end(StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, const char** Attr)
+void ATOM_item_name_end(StrBuf *CData,
+ rss_item *ri,
+ rss_aggregator *Cfg,
+ const char** Attr)
{
if (StrLength(CData) > 0) {
NewStrBufDupAppendFlush(&ri->author_or_creator, CData, NULL, 0);
}
}
-void ATOM_item_email_end(StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, const char** Attr)
+void ATOM_item_email_end(StrBuf *CData,
+ rss_item *ri,
+ rss_aggregator *Cfg,
+ const char** Attr)
{
if (StrLength(CData) > 0) {
NewStrBufDupAppendFlush(&ri->author_email, CData, NULL, 0);
}
}
-void RSS_item_creator_end(StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, const char** Attr)
+void RSS_item_creator_end(StrBuf *CData,
+ rss_item *ri,
+ rss_aggregator *Cfg,
+ const char** Attr)
{
- if ((StrLength(CData) > 0) &&
+ if ((StrLength(CData) > 0) &&
(StrLength(ri->author_or_creator) == 0))
{
NewStrBufDupAppendFlush(&ri->author_or_creator, CData, NULL, 0);
}
-void ATOM_item_uri_end(StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, const char** Attr)
+void ATOM_item_uri_end(StrBuf *CData,
+ rss_item *ri,
+ rss_aggregator *Cfg,
+ const char** Attr)
{
if (StrLength(CData) > 0) {
NewStrBufDupAppendFlush(&ri->author_url, CData, NULL, 0);
}
}
-void RSS_item_item_end(StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, const char** Attr)
+void RSS_item_item_end(StrBuf *CData,
+ rss_item *ri,
+ rss_aggregator *Cfg,
+ const char** Attr)
{
--ri->item_tag_nesting;
rss_save_item(ri, Cfg);
}
-void ATOM_item_entry_end(StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, const char** Attr)
+void ATOM_item_entry_end(StrBuf *CData,
+ rss_item *ri,
+ rss_aggregator *Cfg,
+ const char** Attr)
{
--ri->item_tag_nesting;
rss_save_item(ri, Cfg);
}
-void RSS_item_rss_end(StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, const char** Attr)
+void RSS_item_rss_end(StrBuf *CData,
+ rss_item *ri,
+ rss_aggregator *Cfg,
+ const char** Attr)
{
// syslog(LOG_DEBUG, "End of feed detected. Closing parser.\n");
ri->done_parsing = 1;
-
}
-void RSS_item_rdf_end(StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, const char** Attr)
+
+void RSS_item_rdf_end(StrBuf *CData,
+ rss_item *ri,
+ rss_aggregator *Cfg,
+ const char** Attr)
{
// syslog(LOG_DEBUG, "End of feed detected. Closing parser.\n");
ri->done_parsing = 1;
}
-void RSSATOM_item_ignore(StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, const char** Attr)
+void RSSATOM_item_ignore(StrBuf *CData,
+ rss_item *ri,
+ rss_aggregator *Cfg,
+ const char** Attr)
{
}
/*
* This callback stores up the data which appears in between tags.
*/
-void rss_xml_cdata_start(void *data)
+void rss_xml_cdata_start(void *data)
{
rss_aggregator *RSSAggr = (rss_aggregator*) data;
FlushStrBuf(RSSAggr->CData);
}
-void rss_xml_cdata_end(void *data)
+void rss_xml_cdata_end(void *data)
{
}
-void rss_xml_chardata(void *data, const XML_Char *s, int len)
+void rss_xml_chardata(void *data, const XML_Char *s, int len)
{
rss_aggregator *RSSAggr = (rss_aggregator*) data;
}
-/*******************************************************************************
- * RSS parser logic *
- *******************************************************************************/
+/******************************************************************************
+ * RSS parser logic *
+ ******************************************************************************/
extern pthread_mutex_t RSSQueueMutex;
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);
+ /*
+ 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,
+
+ 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);
+ syslog(LOG_DEBUG,
+ "RSS: START ignoring "
+ "because of wrong namespace [%s]\n",
+ supplied_el);
#endif
return;
}
{
h = (rss_xml_handler*) pv;
- if (((h->Flags & RSS_UNSET) != 0) &&
+ if (((h->Flags & RSS_UNSET) != 0) &&
(RSSAggr->ItemType == RSS_UNSET))
{
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);
+ h->Handler(RSSAggr->CData,
+ ri,
+ RSSAggr,
+ attr);
}
#ifdef DEBUG_RSS
- else
- syslog(LOG_DEBUG, "RSS: START unhandled: [%s] [%s]...\n", pel, supplied_el);
+ 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);
+ else
+ syslog(LOG_DEBUG,
+ "RSS: START unhandled: [%s] [%s]...\n",
+ pel,
+ supplied_el);
#endif
}
if (pel != supplied_el)
{
void *v;
-
- if (!GetHash(KnownNameSpaces,
- supplied_el,
+
+ 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));
+ syslog(LOG_DEBUG,
+ "RSS: END ignoring because of wrong namespace"
+ "[%s] = [%s]\n",
+ supplied_el,
+ ChrPtr(RSSAggr->CData));
#endif
FlushStrBuf(RSSAggr->CData);
return;
{
h = (rss_xml_handler*) pv;
- if (((h->Flags & RSS_UNSET) != 0) &&
+ if (((h->Flags & RSS_UNSET) != 0) &&
(RSSAggr->ItemType == RSS_UNSET))
{
h->Handler(RSSAggr->CData, ri, RSSAggr, NULL);
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));
+ 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));
+ else
+ syslog(LOG_DEBUG,
+ "RSS: END unhandled: [%s] [%s] = [%s]...\n",
+ pel,
+ supplied_el,
+ ChrPtr(RSSAggr->CData));
#endif
FlushStrBuf(RSSAggr->CData);
}
pche = strchr(ptr, '"');
if (pche != NULL)
StrBufCutAt(RSSAggr->Key, -1, pche);
- else
+ else
ptr = "UTF-8";
}
else
XML_Parse(RSSAggr->xp, "", 0, 1);
- syslog(LOG_DEBUG, "RSS: XML Status [%s] \n",
- XML_ErrorString(
- XML_GetErrorCode(RSSAggr->xp)));
+ syslog(LOG_DEBUG, "RSS: XML Status [%s] \n",
+ XML_ErrorString(XML_GetErrorCode(RSSAggr->xp)));
XML_ParserFree(RSSAggr->xp);
flush_rss_item(ri);
RSSAggr->Pos = GetNewHashPos(RSSAggr->Messages, 1);
- ///Cfg->next_poll = time(NULL) + config.c_net_freq;
- if (GetNextHashPos(RSSAggr->Messages, RSSAggr->Pos, &len, &Key, (void**) &RSSAggr->ThisMsg))
+//Cfg->next_poll = time(NULL) + config.c_net_freq;
+ if (GetNextHashPos(RSSAggr->Messages,
+ RSSAggr->Pos,
+ &len,
+ &Key,
+ (void**) &RSSAggr->ThisMsg))
return QueueDBOperation(IO, RSS_FetchNetworkUsetableEntry);
else
return eAbort;
}
-/*******************************************************************************
- * RSS handler registering logic *
- *******************************************************************************/
+/******************************************************************************
+ * RSS handler registering logic *
+ ******************************************************************************/
-void AddRSSStartHandler(rss_handler_func Handler, int Flags, const char *key, long len)
+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->Handler = Handler;
Put(StartHandlers, key, len, h, NULL);
}
-void AddRSSEndHandler(rss_handler_func Handler, int Flags, const char *key, long len)
+
+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));
void rss_parser_cleanup(void)
{
- DeleteHash(&StartHandlers);
- DeleteHash(&EndHandlers);
+ DeleteHash(&StartHandlers);
+ DeleteHash(&EndHandlers);
DeleteHash(&KnownNameSpaces);
}
AddRSSEndHandler(RSS_item_guid_end, RSS_RSS|RSS_REQUIRE_BUF, HKEY("guid"));
AddRSSEndHandler(ATOM_item_id_end, RSS_ATOM|RSS_REQUIRE_BUF, HKEY("id"));
AddRSSEndHandler(RSS_item_link_end, RSS_RSS|RSS_REQUIRE_BUF, HKEY("link"));
-#if 0
-// hm, rss to the comments of that blog, might be interesting in future, but...
+#if 0
+// hm, rss to the comments of that blog, might be interesting in future, but...
AddRSSEndHandler(RSS_item_relink_end, RSS_RSS|RSS_REQUIRE_BUF, HKEY("commentrss"));
// comment count...
AddRSSEndHandler(RSS_item_relink_end, RSS_RSS|RSS_REQUIRE_BUF, HKEY("comments"));
/* we don't like these namespaces because of they shadow our usefull parameters. */
Put(KnownNameSpaces, HKEY("http://search.yahoo.com/mrss/"), NULL, reference_free_handler);
#endif
- CtdlRegisterCleanupHook(rss_parser_cleanup);
+ CtdlRegisterCleanupHook(rss_parser_cleanup);
}
return "rssparser";
}
*
* 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
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA
*/
#include <stdlib.h>
# include <time.h>
#else
# if HAVE_SYS_TIME_H
-# include <sys/time.h>
+#include <sys/time.h>
# else
-# include <time.h>
+#include <time.h>
# endif
#endif
last_run = time(NULL);
}
-
void DeleteRssCfg(void *vptr)
{
rss_aggregator *RSSAggr = (rss_aggregator *)vptr;
UnlinkRSSAggregator(RSSAggr);
return eAbort;
}
+
eNextState RSSAggregator_ShutdownAbort(AsyncIO *IO)
{
const char *pUrl;
const char *Key;
rss_aggregator *RSSAggr = (rss_aggregator *) IO->Data;
- RSSAggr->ThisMsg->Msg.cm_fields['M'] = SmashStrBuf(&RSSAggr->ThisMsg->Message);
+ RSSAggr->ThisMsg->Msg.cm_fields['M'] =
+ SmashStrBuf(&RSSAggr->ThisMsg->Message);
CtdlSubmitMsg(&RSSAggr->ThisMsg->Msg, &RSSAggr->recp, NULL, 0);
}
}
-
-
/*
* Begin a feed parse
*/
rss_room_counter *Count = NULL;
struct stat statbuf;
char filename[PATH_MAX];
- int fd;
+ int fd;
int Done;
rss_aggregator *RSSAggr = NULL;
rss_aggregator *use_this_RSSAggr = NULL;
close(fd);
FreeStrBuf(&CfgData);
syslog(LOG_DEBUG, "ERROR: reading config '%s' - %s<br>\n",
- filename, strerror(errno));
+ filename, strerror(errno));
return;
}
close(fd);
Done = 0;
while (!Done)
{
- Done = StrBufSipLine(Line, CfgData, &CfgPtr) == 0;
- if (StrLength(Line) > 0)
- {
- lPtr = NULL;
- StrBufExtract_NextToken(CfgType, Line, &lPtr, '|');
- if (!strcasecmp("rssclient", ChrPtr(CfgType)))
+ Done = StrBufSipLine(Line, CfgData, &CfgPtr) == 0;
+ if (StrLength(Line) > 0)
{
- if (Count == NULL)
- {
- Count = malloc(sizeof(rss_room_counter));
- Count->count = 0;
- }
- Count->count ++;
- 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(RSSAggr->Url), &vptr);
- use_this_RSSAggr = (rss_aggregator *)vptr;
- if (use_this_RSSAggr != NULL)
- {
- long *QRnumber;
- StrBufAppendBufPlain(use_this_RSSAggr->rooms,
- qrbuf->QRname,
- -1, 0);
- if (use_this_RSSAggr->roomlist_parts == 1)
- {
- use_this_RSSAggr->OtherQRnumbers =
- NewHash(1, lFlathash);
- }
- QRnumber = (long*)malloc(sizeof(long));
- *QRnumber = qrbuf->QRnumber;
- Put(use_this_RSSAggr->OtherQRnumbers,
- LKEY(qrbuf->QRnumber),
- QRnumber,
- NULL);
- use_this_RSSAggr->roomlist_parts++;
-
- pthread_mutex_unlock(&RSSQueueMutex);
-
- FreeStrBuf(&RSSAggr->Url);
- free(RSSAggr);
- RSSAggr = NULL;
- continue;
- }
- pthread_mutex_unlock(&RSSQueueMutex);
-
- RSSAggr->ItemType = RSS_UNSET;
-
- RSSAggr->rooms = NewStrBufPlain(qrbuf->QRname, -1);
-
- pthread_mutex_lock(&RSSQueueMutex);
- Put(RSSFetchUrls, SKEY(RSSAggr->Url), RSSAggr, DeleteRssCfg);
- pthread_mutex_unlock(&RSSQueueMutex);
+ lPtr = NULL;
+ StrBufExtract_NextToken(CfgType, Line, &lPtr, '|');
+ if (!strcasecmp("rssclient", ChrPtr(CfgType)))
+ {
+ if (Count == NULL)
+ {
+ Count = malloc(
+ sizeof(rss_room_counter));
+ Count->count = 0;
+ }
+ Count->count ++;
+ 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(RSSAggr->Url),
+ &vptr);
+
+ use_this_RSSAggr = (rss_aggregator *)vptr;
+ if (use_this_RSSAggr != NULL)
+ {
+ long *QRnumber;
+ StrBufAppendBufPlain(
+ use_this_RSSAggr->rooms,
+ qrbuf->QRname,
+ -1, 0);
+ if (use_this_RSSAggr->roomlist_parts==1)
+ {
+ use_this_RSSAggr->OtherQRnumbers
+ = NewHash(1, lFlathash);
+ }
+ QRnumber = (long*)malloc(sizeof(long));
+ *QRnumber = qrbuf->QRnumber;
+ Put(use_this_RSSAggr->OtherQRnumbers,
+ LKEY(qrbuf->QRnumber),
+ QRnumber,
+ NULL);
+ use_this_RSSAggr->roomlist_parts++;
+
+ pthread_mutex_unlock(&RSSQueueMutex);
+
+ FreeStrBuf(&RSSAggr->Url);
+ free(RSSAggr);
+ RSSAggr = NULL;
+ continue;
+ }
+ pthread_mutex_unlock(&RSSQueueMutex);
+
+ RSSAggr->ItemType = RSS_UNSET;
+
+ RSSAggr->rooms = NewStrBufPlain(
+ qrbuf->QRname, -1);
+
+ pthread_mutex_lock(&RSSQueueMutex);
+
+ Put(RSSFetchUrls,
+ SKEY(RSSAggr->Url),
+ RSSAggr,
+ DeleteRssCfg);
+
+ pthread_mutex_unlock(&RSSQueueMutex);
+ }
}
- }
}
if (Count != NULL)
{
Count->QRnumber = qrbuf->QRnumber;
pthread_mutex_lock(&RSSQueueMutex);
- syslog(LOG_DEBUG, "rssclient: [%ld] %s now starting.\n",
- qrbuf->QRnumber, qrbuf->QRname);
+ syslog(LOG_DEBUG, "rssclient: [%ld] %s now starting.\n",
+ qrbuf->QRnumber, qrbuf->QRname);
Put(RSSQueueRooms, LKEY(qrbuf->QRnumber), Count, NULL);
pthread_mutex_unlock(&RSSQueueMutex);
}
static int doing_rssclient = 0;
rss_aggregator *rptr = NULL;
void *vrptr = NULL;
- HashPos *it;
+ HashPos *it;
long len;
const char *Key;
/*
* 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
+ * 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 (SendMsg->MyQEntry->Status == 2)
return eAbort;
- /*
- * possible ways here:
- * - connection timeout
+ /*
+ * possible ways here:
+ * - connection timeout
* - dns lookup failed
*/
StopClientWatchers(IO);
return mx_connect_ip(IO);
}
else {
- EVS_syslog(LOG_DEBUG, "SMTP: %s resolving next MX Record\n", __FUNCTION__);
+ EVS_syslog(LOG_DEBUG,
+ "SMTP: %s resolving next MX Record\n",
+ __FUNCTION__);
return get_one_mx_host_ip(IO);
}
}
src = &IO->ConnectMe->Addr.sin6_addr;
}
else {
- struct sockaddr_in *addr = (struct sockaddr_in *)&IO->ConnectMe->Addr;
+ struct sockaddr_in *addr;
+ addr = (struct sockaddr_in *)&IO->ConnectMe->Addr;
src = &addr->sin_addr.s_addr;
}
inet_ntop((IO->ConnectMe->IPv6)?AF_INET6:AF_INET,
src,
- buf,
+ buf,
sizeof(buf));
if (SendMsg->mx_host == NULL)
SendMsg->mx_host = "<no MX-Record>";
EVS_syslog(LOG_DEBUG,
- "SMTP client[%ld]: connecting to %s [%s]:%d ...\n",
- SendMsg->n,
- SendMsg->mx_host,
+ "SMTP client[%ld]: connecting to %s [%s]:%d ...\n",
+ SendMsg->n,
+ SendMsg->mx_host,
buf,
SendMsg->IO.ConnectMe->Port);
- SendMsg->MyQEntry->Status = 5;
- StrBufPrintf(SendMsg->MyQEntry->StatusMessage,
- "Timeout while connecting %s [%s]:%d ",
+ SendMsg->MyQEntry->Status = 5;
+ StrBufPrintf(SendMsg->MyQEntry->StatusMessage,
+ "Timeout while connecting %s [%s]:%d ",
SendMsg->mx_host,
buf,
SendMsg->IO.ConnectMe->Port);
QueryCbDone(IO);
hostent = SendMsg->HostLookup.VParsedDNSReply;
- if ((SendMsg->HostLookup.DNSStatus == ARES_SUCCESS) &&
+ if ((SendMsg->HostLookup.DNSStatus == ARES_SUCCESS) &&
(hostent != NULL) ) {
memset(&SendMsg->pCurrRelay->Addr, 0, sizeof(struct in6_addr));
if (SendMsg->pCurrRelay->IPv6) {
- memcpy(&SendMsg->pCurrRelay->Addr.sin6_addr.s6_addr,
+ memcpy(&SendMsg->pCurrRelay->Addr.sin6_addr.s6_addr,
&hostent->h_addr_list[0],
sizeof(struct in6_addr));
-
- SendMsg->pCurrRelay->Addr.sin6_family = hostent->h_addrtype;
- SendMsg->pCurrRelay->Addr.sin6_port = htons(DefaultMXPort);
+
+ SendMsg->pCurrRelay->Addr.sin6_family =
+ hostent->h_addrtype;
+ SendMsg->pCurrRelay->Addr.sin6_port =
+ htons(DefaultMXPort);
}
else {
- struct sockaddr_in *addr = (struct sockaddr_in*) &SendMsg->pCurrRelay->Addr;
- /* Bypass the ns lookup result like this: IO->Addr.sin_addr.s_addr = inet_addr("127.0.0.1"); */
-// addr->sin_addr.s_addr = htonl((uint32_t)&hostent->h_addr_list[0]);
- memcpy(&addr->sin_addr.s_addr,
- hostent->h_addr_list[0],
+ struct sockaddr_in *addr;
+ /*
+ * Bypass the ns lookup result like this:
+ * IO->Addr.sin_addr.s_addr = inet_addr("127.0.0.1");
+ * addr->sin_addr.s_addr =
+ * htonl((uint32_t)&hostent->h_addr_list[0]);
+ */
+
+ addr = (struct sockaddr_in*) &SendMsg->pCurrRelay->Addr;
+
+ memcpy(&addr->sin_addr.s_addr,
+ hostent->h_addr_list[0],
sizeof(uint32_t));
-
+
addr->sin_family = hostent->h_addrtype;
addr->sin_port = htons(DefaultMXPort);
-
}
SendMsg->mx_host = SendMsg->pCurrRelay->Host;
return mx_connect_ip(IO);
}
- else // TODO: here we need to find out whether there are more mx'es, backup relay, and so on
+ else
return FailOneAttempt(IO);
}
eNextState get_one_mx_host_ip(AsyncIO *IO)
{
SmtpOutMsg * SendMsg = IO->Data;
- /*
+ /*
* here we start with the lookup of one host. it might be...
* - the relay host *sigh*
* - the direct hostname if there was no mx record
* - one of the mx'es
- */
+ */
InitC_ares_dns(IO);
EVS_syslog(LOG_DEBUG, "SMTP: %s\n", __FUNCTION__);
- EVS_syslog(LOG_DEBUG,
- "SMTP client[%ld]: looking up %s-Record %s : %d ...\n",
- SendMsg->n,
+ EVS_syslog(LOG_DEBUG,
+ "SMTP client[%ld]: looking up %s-Record %s : %d ...\n",
+ SendMsg->n,
(SendMsg->pCurrRelay->IPv6)? "aaaa": "a",
- SendMsg->pCurrRelay->Host,
+ SendMsg->pCurrRelay->Host,
SendMsg->pCurrRelay->Port);
- if (!QueueQuery((SendMsg->pCurrRelay->IPv6)? ns_t_aaaa : ns_t_a,
- SendMsg->pCurrRelay->Host,
- &SendMsg->IO,
- &SendMsg->HostLookup,
+ if (!QueueQuery((SendMsg->pCurrRelay->IPv6)? ns_t_aaaa : ns_t_a,
+ SendMsg->pCurrRelay->Host,
+ &SendMsg->IO,
+ &SendMsg->HostLookup,
get_one_mx_host_ip_done))
{
SendMsg->MyQEntry->Status = 5;
- StrBufPrintf(SendMsg->MyQEntry->StatusMessage,
+ StrBufPrintf(SendMsg->MyQEntry->StatusMessage,
"No MX hosts found for <%s>", SendMsg->node);
SendMsg->IO.NextState = eTerminateConnection;
return IO->NextState;
while ((pp != NULL) && (*pp != NULL) && ((*pp)->Next != NULL))
pp = &(*pp)->Next;
- if ((IO->DNS.Query->DNSStatus == ARES_SUCCESS) &&
+ if ((IO->DNS.Query->DNSStatus == ARES_SUCCESS) &&
(IO->DNS.Query->VParsedDNSReply != NULL))
{ /* ok, we found mx records. */
SendMsg->IO.ErrMsg = SendMsg->MyQEntry->StatusMessage;
-
- SendMsg->CurrMX = SendMsg->AllMX
- = IO->DNS.Query->VParsedDNSReply;
+
+ SendMsg->CurrMX
+ = SendMsg->AllMX
+ = IO->DNS.Query->VParsedDNSReply;
while (SendMsg->CurrMX) {
int i;
for (i = 0; i < 2; i++) {
p->Port = DefaultMXPort;
p->IPv6 = i == 1;
p->Host = SendMsg->CurrMX->host;
-
+
*pp = p;
pp = &p->Next;
}
p->Port = DefaultMXPort;
p->IPv6 = i == 1;
p->Host = SendMsg->node;
-
+
*pp = p;
pp = &p->Next;
}
EVS_syslog(LOG_DEBUG, "SMTP: %s\n", __FUNCTION__);
/* start resolving MX records here. */
- if (!QueueQuery(ns_t_mx,
- SendMsg->node,
- &SendMsg->IO,
- &SendMsg->MxLookup,
+ if (!QueueQuery(ns_t_mx,
+ SendMsg->node,
+ &SendMsg->IO,
+ &SendMsg->MxLookup,
smtp_resolve_mx_record_done))
{
SendMsg->MyQEntry->Status = 5;
- StrBufPrintf(SendMsg->MyQEntry->StatusMessage,
+ StrBufPrintf(SendMsg->MyQEntry->StatusMessage,
"No MX hosts found for <%s>", SendMsg->node);
return IO->NextState;
}
* so, we're going to start a SMTP delivery. lets get it on. *
******************************************************************************/
-SmtpOutMsg *new_smtp_outmsg(OneQueItem *MyQItem,
+SmtpOutMsg *new_smtp_outmsg(OneQueItem *MyQItem,
MailQEntry *MyQEntry,
int MsgCount)
{
return SendMsg;
}
-void smtp_try_one_queue_entry(OneQueItem *MyQItem,
+void smtp_try_one_queue_entry(OneQueItem *MyQItem,
MailQEntry *MyQEntry,
StrBuf *MsgText,
- int KeepMsgText, /* KeepMsgText allows us to use MsgText as ours. */
+ /*KeepMsgText allows us to use MsgText as ours.*/
+ int KeepMsgText,
int MsgCount)
{
SmtpOutMsg *SendMsg;
safestrncpy(
((CitContext *)SendMsg->IO.CitContext)->cs_host,
SendMsg->node,
- sizeof(((CitContext *)SendMsg->IO.CitContext)->cs_host));
+ sizeof(((CitContext *)
+ SendMsg->IO.CitContext)->cs_host));
syslog(LOG_DEBUG, "SMTP Starting: [%ld] <%s> CC <%d> \n",
SendMsg->MyQItem->MessageID,
QueueEventContext(&SendMsg->IO,
mx_connect_ip);
}
- else { /* uneducated admin has chosen to add DNS to the equation... */
+ else {
+ /* uneducated admin has chosen to
+ add DNS to the equation... */
QueueEventContext(&SendMsg->IO,
get_one_mx_host_ip);
}
case eSendMore:
Timeout = SMTP_C_SendTimeouts[pMsg->State];
if (pMsg->State == eDATABody) {
- /* if we're sending a huge message, we need more time. */
+ /* if we're sending a huge message,
+ * we need more time.
+ */
Timeout += StrLength(pMsg->msgtext) / 1024;
}
break;
case eReadMessage:
Timeout = SMTP_C_ReadTimeouts[pMsg->State];
if (pMsg->State == eDATATerminateBody) {
- /*
- * some mailservers take a nap before accepting the message
- * content inspection and such.
+ /*
+ * some mailservers take a nap before accepting
+ * the message content inspection and such.
*/
Timeout += StrLength(pMsg->msgtext) / 1024;
}
SmtpOutMsg *pMsg = IO->Data;
pMsg->MyQEntry->Status = 3;
- StrBufPlain(pMsg->MyQEntry->StatusMessage, HKEY("server shutdown during message submit."));
+ StrBufPlain(pMsg->MyQEntry->StatusMessage,
+ HKEY("server shutdown during message submit."));
FinalizeMessageSend(pMsg);
return eAbort;
}
/**
- * @brief lineread Handler; understands when to read more SMTP lines, and when this is a one-lined reply.
+ * @brief lineread Handler;
+ * understands when to read more SMTP lines, and when this is a one-lined reply.
*/
eReadState SMTP_C_ReadServerStatus(AsyncIO *IO)
{
- eReadState Finished = eBufferNotEmpty;
+ eReadState Finished = eBufferNotEmpty;
while (Finished == eBufferNotEmpty) {
Finished = StrBufChunkSipLine(IO->IOBuf, &IO->RecvBuf);
-
+
switch (Finished) {
- case eMustReadMore: /// read new from socket...
+ case eMustReadMore: /// read new from socket...
return Finished;
break;
case eBufferNotEmpty: /* shouldn't happen... */
continue;
if (ChrPtr(IO->IOBuf)[3] == '-')
Finished = eBufferNotEmpty;
- else
+ else
return Finished;
break;
case eReadFail: /// WHUT?
- ///todo: shut down!
+ ///todo: shut down!
break;
}
}
int MsgCount = 0;
int run_queue_now = 0; /* Set to 1 to ignore SMTP send retry times */
-void smtp_try_one_queue_entry(OneQueItem *MyQItem,
- MailQEntry *MyQEntry,
- StrBuf *MsgText,
- int KeepMsgText, /* KeepMsgText allows us to use MsgText as ours. */
- int MsgCount,
+void smtp_try_one_queue_entry(OneQueItem *MyQItem,
+ MailQEntry *MyQEntry,
+ StrBuf *MsgText,
+/* KeepMsgText allows us to use MsgText as ours. */
+ int KeepMsgText,
+ int MsgCount,
ParsedURL *RelayUrls);
DeleteEntryFromHash(ActiveQItems, It);
else
{
- syslog(LOG_WARNING,
+ syslog(LOG_WARNING,
"SMTP cleanup: unable to find QItem with ID[%ld]",
MyQItem->MessageID);
while (GetNextHashPos(ActiveQItems, It, &len, &Key, &VData))
- syslog(LOG_WARNING,
+ syslog(LOG_WARNING,
"SMTP cleanup: have_: ID[%ld]",
- ((OneQueItem *)VData)->MessageID);
+ ((OneQueItem *)VData)->MessageID);
}
pthread_mutex_unlock(&ActiveQItemsLock);
DeleteHashPos(&It);
FreeQueItem((OneQueItem**)&Item);
}
-/* inspect recipients with a status of:
- * - 0 (no delivery yet attempted)
+/* inspect recipients with a status of:
+ * - 0 (no delivery yet attempted)
* - 3/4 (transient errors
* were experienced and it's time to try again)
*/
while (GetNextHashPos(MyQItem->MailQEntries, It, &len, &Key, &vQE))
{
MailQEntry *ThisItem = vQE;
- if ((ThisItem->Status == 0) ||
+ if ((ThisItem->Status == 0) ||
(ThisItem->Status == 3) ||
(ThisItem->Status == 4))
{
ActiveDeliveries++;
ThisItem->Active = 1;
}
- else
+ else
ThisItem->Active = 0;
}
DeleteHashPos(&It);
FreeStrBuf(&Token);
pthread_mutex_lock(&ActiveQItemsLock);
- if (GetHash(ActiveQItems,
+ if (GetHash(ActiveQItems,
LKEY(Item->MessageID),
&v))
{
}
else {
/* mark our claim on this. */
- Put(ActiveQItems,
+ Put(ActiveQItems,
LKEY(Item->MessageID),
Item,
HFreeQueItem);
QMessage = NewStrBufPlain(NULL, SIZ);
StrBufPrintf(QMessage, "Content-type: %s\n", SPOOLMIME);
-
-// "attempted|%ld\n" "retry|%ld\n",, (long)time(NULL), (long)retry );
+// "attempted|%ld\n" "retry|%ld\n",, (long)time(NULL), (long)retry );
StrBufAppendBufPlain(QMessage, HKEY("\nmsgid|"), 0);
StrBufAppendPrintf(QMessage, "%ld", MyQItem->MessageID);
int i;
if (!ThisItem->Active)
- continue; /* skip already sent ones from the spoolfile. */
+ {
+ /* skip already sent ones from the spoolfile. */
+ continue;
+ }
for (i=0; i < ThisItem->nAttempts; i++) {
- /* TODO: most probably there is just one retry/attempted per message! */
+ /* TODO: most probably
+ * there is just one retry/attempted per message!
+ */
StrBufAppendBufPlain(QMessage, HKEY("\nretry|"), 0);
- StrBufAppendPrintf(QMessage, "%ld",
+ StrBufAppendPrintf(QMessage, "%ld",
ThisItem->Attempts[i].retry);
StrBufAppendBufPlain(QMessage, HKEY("\nattempted|"), 0);
- StrBufAppendPrintf(QMessage, "%ld",
+ StrBufAppendPrintf(QMessage, "%ld",
ThisItem->Attempts[i].when);
}
StrBufAppendBufPlain(QMessage, HKEY("\nremote|"), 0);
StrBufAppendBuf(QMessage, ThisItem->StatusMessage, 0);
}
DeleteHashPos(&It);
- StrBufAppendBufPlain(QMessage, HKEY("\n"), 0);
+ StrBufAppendBufPlain(QMessage, HKEY("\n"), 0);
return QMessage;
}
Item->MailQEntries = NewHash(1, Flathash);
Item->Current->StatusMessage = NewStrBuf();
Item->Current->n = GetCount(Item->MailQEntries);
- Put(Item->MailQEntries, IKEY(Item->Current->n), Item->Current, FreeMailQEntry);
+ Put(Item->MailQEntries,
+ IKEY(Item->Current->n),
+ Item->Current,
+ FreeMailQEntry);
}
void QItem_Handle_MsgID(OneQueItem *Item, StrBuf *Line, const char **Pos)
if (Item->Current == NULL)
NewMailQEntry(Item);
if (Item->Current->Recipient == NULL)
- Item->Current->Recipient = NewStrBufPlain(NULL, StrLength(Line));
+ Item->Current->Recipient=NewStrBufPlain(NULL, StrLength(Line));
StrBufExtract_NextToken(Item->Current->Recipient, Line, Pos, '|');
Item->Current->Status = StrBufExtractNext_int(Line, Pos, '|');
StrBufExtract_NextToken(Item->Current->StatusMessage, Line, Pos, '|');
Item->FailNow = 1;
return;
}
- Item->Current->Attempts[Item->Current->nAttempts].retry = StrBufExtractNext_int(Line, Pos, '|');
+ Item->Current->Attempts[Item->Current->nAttempts].retry =
+ StrBufExtractNext_int(Line, Pos, '|');
}
Item->FailNow = 1;
return;
}
-
- Item->Current->Attempts[Item->Current->nAttempts].when = StrBufExtractNext_int(Line, Pos, '|');
- if (Item->Current->Attempts[Item->Current->nAttempts].when > Item->LastAttempt.when)
+
+ Item->Current->Attempts[Item->Current->nAttempts].when =
+ StrBufExtractNext_int(Line, Pos, '|');
+ if (Item->Current->Attempts[Item->Current->nAttempts].when >
+ Item->LastAttempt.when)
{
- Item->LastAttempt.when = Item->Current->Attempts[Item->Current->nAttempts].when;
- Item->LastAttempt.retry = Item->Current->Attempts[Item->Current->nAttempts].retry * 2;
+ Item->LastAttempt.when =
+ Item->Current->Attempts[Item->Current->nAttempts].when;
+
+ Item->LastAttempt.retry =
+ Item->Current->Attempts[
+ Item->Current->nAttempts
+ ].retry * 2;
+
if (Item->LastAttempt.retry > SMTP_RETRY_MAX)
Item->LastAttempt.retry = SMTP_RETRY_MAX;
}
{
CitContext *CCC=CC;
StrBuf *SendMsg;
-
+
CCC->redirect_buffer = NewStrBufPlain(NULL, SIZ);
- CtdlOutputMsg(MyQItem->MessageID, MT_RFC822, HEADERS_ALL, 0, 1, NULL, (ESC_DOT|SUPPRESS_ENV_TO) );
+ CtdlOutputMsg(MyQItem->MessageID,
+ MT_RFC822, HEADERS_ALL,
+ 0, 1, NULL,
+ (ESC_DOT|SUPPRESS_ENV_TO) );
+
SendMsg = CCC->redirect_buffer;
CCC->redirect_buffer = NULL;
- if ((StrLength(SendMsg) > 0) &&
+ if ((StrLength(SendMsg) > 0) &&
ChrPtr(SendMsg)[StrLength(SendMsg) - 1] != '\n') {
- syslog(LOG_WARNING,
+ syslog(LOG_WARNING,
"SMTP client[%d]: Possible problem: message did not "
"correctly terminate. (expecting 0x10, got 0x%02x)\n",
- MsgCount, //yes uncool, but best choice here...
+ MsgCount, //yes uncool, but best choice here...
ChrPtr(SendMsg)[StrLength(SendMsg) - 1] );
StrBufAppendBufPlain(SendMsg, HKEY("\r\n"), 0);
}
* instructions for "5" codes (permanent fatal errors) and produce/deliver
* a "bounce" message (delivery status notification).
*/
-void smtpq_do_bounce(OneQueItem *MyQItem, StrBuf *OMsgTxt)
+void smtpq_do_bounce(OneQueItem *MyQItem, StrBuf *OMsgTxt)
{
static int seq = 0;
struct CtdlMessage *bmsg = NULL;
StrBuf *boundary;
- StrBuf *Msg = NULL;
+ StrBuf *Msg = NULL;
StrBuf *BounceMB;
struct recptypes *valid;
-
+
HashPos *It;
void *vQE;
long len;
{
MailQEntry *ThisItem = vQE;
if ((ThisItem->Status == 5) || /* failed now? */
- ((give_up == 1) && (ThisItem->Status != 2))) /* giving up after failed attempts... */
+ ((give_up == 1) &&
+ (ThisItem->Status != 2)))
+ /* giving up after failed attempts... */
{
if (num_bounces == 0)
Msg = NewStrBufPlain(NULL, 1024);
++num_bounces;
-
+
StrBufAppendBuf(Msg, ThisItem->Recipient, 0);
StrBufAppendBufPlain(Msg, HKEY(": "), 0);
StrBufAppendBuf(Msg, ThisItem->StatusMessage, 0);
}
boundary = NewStrBufPlain(HKEY("=_Citadel_Multipart_"));
- StrBufAppendPrintf(boundary, "%s_%04x%04x", config.c_fqdn, getpid(), ++seq);
+ StrBufAppendPrintf(boundary,
+ "%s_%04x%04x",
+ config.c_fqdn,
+ getpid(),
+ ++seq);
/* Start building our bounce message; go shopping for memory first. */
- BounceMB = NewStrBufPlain(NULL,
- 1024 + /* mime stuff.... */
- StrLength(Msg) + /* the bounce information... */
- StrLength(OMsgTxt)); /* the original message */
+ BounceMB = NewStrBufPlain(
+ NULL,
+ 1024 + /* mime stuff.... */
+ StrLength(Msg) + /* the bounce information... */
+ StrLength(OMsgTxt)); /* the original message */
if (BounceMB == NULL) {
FreeStrBuf(&boundary);
syslog(LOG_ERR, "Failed to alloc() bounce message.\n");
StrBufAppendBufPlain(BounceMB, HKEY("Content-type: multipart/mixed; boundary=\""), 0);
StrBufAppendBuf(BounceMB, boundary, 0);
- StrBufAppendBufPlain(BounceMB, HKEY("\"\r\n"), 0);
+ StrBufAppendBufPlain(BounceMB, HKEY("\"\r\n"), 0);
StrBufAppendBufPlain(BounceMB, HKEY("MIME-Version: 1.0\r\n"), 0);
StrBufAppendBufPlain(BounceMB, HKEY("X-Mailer: " CITADEL "\r\n"), 0);
- StrBufAppendBufPlain(BounceMB, HKEY("\r\nThis is a multipart message in MIME format.\r\n\r\n"), 0);
- StrBufAppendBufPlain(BounceMB, HKEY("--"), 0);
- StrBufAppendBuf(BounceMB, boundary, 0);
+ StrBufAppendBufPlain(BounceMB, HKEY("\r\nThis is a multipart message in MIME format.\r\n\r\n"), 0);
+ StrBufAppendBufPlain(BounceMB, HKEY("--"), 0);
+ StrBufAppendBuf(BounceMB, boundary, 0);
StrBufAppendBufPlain(BounceMB, HKEY("\r\n"), 0);
- StrBufAppendBufPlain(BounceMB, HKEY("Content-type: text/plain\r\n\r\n"), 0);
+ StrBufAppendBufPlain(BounceMB, HKEY("Content-type: text/plain\r\n\r\n"), 0);
- if (give_up)
+ if (give_up)
StrBufAppendBufPlain(
- BounceMB,
+ BounceMB,
HKEY(
- "A message you sent could not be delivered to some or all of its recipients\n"
- "due to prolonged unavailability of its destination(s).\n"
+ "A message you sent could not be delivered "
+ "to some or all of its recipients\n"
+ "due to prolonged unavailability "
+ "of its destination(s).\n"
"Giving up on the following addresses:\n\n"
), 0);
- else
+ else
StrBufAppendBufPlain(
- BounceMB,
+ BounceMB,
HKEY(
- "A message you sent could not be delivered to some or all of its recipients.\n"
- "The following addresses were undeliverable:\n\n"
+ "A message you sent could not be delivered "
+ "to some or all of its recipients.\n"
+ "The following addresses "
+ "were undeliverable:\n\n"
), 0);
StrBufAppendBuf(BounceMB, Msg, 0);
StrBufAppendBufPlain(BounceMB, HKEY("--"), 0);
StrBufAppendBuf(BounceMB, boundary, 0);
StrBufAppendBufPlain(BounceMB, HKEY("\r\n"), 0);
- StrBufAppendBufPlain(BounceMB, HKEY("Content-type: message/rfc822\r\n"), 0);
- StrBufAppendBufPlain(BounceMB, HKEY("Content-Transfer-Encoding: 7bit\r\n"), 0);
- StrBufAppendBufPlain(BounceMB, HKEY("Content-Disposition: inline\r\n"), 0);
+ StrBufAppendBufPlain(BounceMB,
+ HKEY("Content-type: message/rfc822\r\n"), 0);
+ StrBufAppendBufPlain(BounceMB,
+ HKEY("Content-Transfer-Encoding: 7bit\r\n"), 0);
+ StrBufAppendBufPlain(BounceMB,
+ HKEY("Content-Disposition: inline\r\n"), 0);
StrBufAppendBufPlain(BounceMB, HKEY("\r\n"), 0);
StrBufAppendBuf(BounceMB, OMsgTxt, 0);
/* Close the multipart MIME scope */
- StrBufAppendBufPlain(BounceMB, HKEY("--"), 0);
+ StrBufAppendBufPlain(BounceMB, HKEY("--"), 0);
StrBufAppendBuf(BounceMB, boundary, 0);
StrBufAppendBufPlain(BounceMB, HKEY("--\r\n"), 0);
+ bmsg->cm_magic = CTDLMESSAGE_MAGIC;
+ bmsg->cm_anon_type = MES_NORMAL;
+ bmsg->cm_format_type = FMT_RFC822;
-
- bmsg->cm_magic = CTDLMESSAGE_MAGIC;
- bmsg->cm_anon_type = MES_NORMAL;
- bmsg->cm_format_type = FMT_RFC822;
-
- bmsg->cm_fields['O'] = strdup(MAILROOM);
- bmsg->cm_fields['A'] = strdup("Citadel");
- bmsg->cm_fields['N'] = strdup(config.c_nodename);
- bmsg->cm_fields['U'] = strdup("Delivery Status Notification (Failure)");
+ bmsg->cm_fields['O'] = strdup(MAILROOM);
+ bmsg->cm_fields['A'] = strdup("Citadel");
+ bmsg->cm_fields['N'] = strdup(config.c_nodename);
+ bmsg->cm_fields['U'] = strdup("Delivery Status Notification (Failure)");
bmsg->cm_fields['M'] = SmashStrBuf(&BounceMB);
/* First try the user who sent the message */
- if (StrLength(MyQItem->BounceTo) == 0)
+ if (StrLength(MyQItem->BounceTo) == 0)
syslog(LOG_ERR, "No bounce address specified\n");
else
- syslog(LOG_DEBUG, "bounce to user? <%s>\n", ChrPtr(MyQItem->BounceTo));
+ syslog(LOG_DEBUG, "bounce to user? <%s>\n",
+ ChrPtr(MyQItem->BounceTo));
/* Can we deliver the bounce to the original sender? */
valid = validate_recipients(ChrPtr(MyQItem->BounceTo), NULL, 0);
syslog(LOG_DEBUG, "Done processing bounces\n");
}
-
-
-/*
-{
-
- if (threadding)
- n_smarthosts = get_hosts(char *mxbuf, char *rectype);
-}
-*/
/*
* smtp_do_procmsg()
*
*/
void smtp_do_procmsg(long msgnum, void *userdata) {
struct CtdlMessage *msg = NULL;
- char *instr = NULL;
+ char *instr = NULL;
StrBuf *PlainQItem;
OneQueItem *MyQItem;
char *pch;
ParsedURL *RelayUrls = NULL;
int HaveBuffers = 0;
StrBuf *Msg =NULL;
-
+
syslog(LOG_DEBUG, "SMTP Queue: smtp_do_procmsg(%ld)\n", msgnum);
///strcpy(envelope_from, "");
msg = CtdlFetchMessage(msgnum, 1);
if (msg == NULL) {
- syslog(LOG_ERR, "SMTP Queue: tried %ld but no such message!\n", msgnum);
+ syslog(LOG_ERR, "SMTP Queue: tried %ld but no such message!\n",
+ msgnum);
return;
}
FreeStrBuf(&PlainQItem);
if (MyQItem == NULL) {
- syslog(LOG_ERR, "SMTP Queue: Msg No %ld: already in progress!\n", msgnum);
+ syslog(LOG_ERR,
+ "SMTP Queue: Msg No %ld: already in progress!\n",
+ msgnum);
return; /* s.b. else is already processing... */
}
/*
* Postpone delivery if we've already tried recently.
*/
- if (((time(NULL) - MyQItem->LastAttempt.when) < MyQItem->LastAttempt.retry) && (run_queue_now == 0)) {
+ if (((time(NULL) - MyQItem->LastAttempt.when) <
+ MyQItem->LastAttempt.retry) &&
+ (run_queue_now == 0))
+ {
syslog(LOG_DEBUG, "SMTP client: Retry time not yet reached.\n");
It = GetNewHashPos(MyQItem->MailQEntries, 0);
pthread_mutex_lock(&ActiveQItemsLock);
{
- if (GetHashPosFromKey(ActiveQItems, LKEY(MyQItem->MessageID), It))
+ if (GetHashPosFromKey(ActiveQItems,
+ LKEY(MyQItem->MessageID),
+ It))
+ {
DeleteEntryFromHash(ActiveQItems, It);
+ }
}
pthread_mutex_unlock(&ActiveQItemsLock);
////FreeQueItem(&MyQItem); TODO: DeleteEntryFromHash frees this?
It = GetNewHashPos(MyQItem->MailQEntries, 0);
pthread_mutex_lock(&ActiveQItemsLock);
{
- if (GetHashPosFromKey(ActiveQItems, LKEY(MyQItem->MessageID), It))
+ if (GetHashPosFromKey(ActiveQItems,
+ LKEY(MyQItem->MessageID),
+ It))
+ {
DeleteEntryFromHash(ActiveQItems, It);
+ }
}
pthread_mutex_unlock(&ActiveQItemsLock);
DeleteHashPos(&It);
const char *Pos = NULL;
All = NewStrBufPlain(mxbuf, -1);
One = NewStrBufPlain(NULL, StrLength(All) + 1);
-
- while ((Pos != StrBufNOTNULL) && ((Pos == NULL) || !IsEmptyStr(Pos))) {
+
+ while ((Pos != StrBufNOTNULL) &&
+ ((Pos == NULL) ||
+ !IsEmptyStr(Pos)))
+ {
StrBufExtract_NextToken(One, All, &Pos, '|');
if (!ParseURL(Url, One, 25))
- syslog(LOG_DEBUG, "Failed to parse: %s\n", ChrPtr(One));
+ syslog(LOG_DEBUG,
+ "Failed to parse: %s\n",
+ ChrPtr(One));
else {
- ///if (!Url->IsIP)) /// todo dupe me fork ipv6
+ ///if (!Url->IsIP)) // todo dupe me fork ipv6
Url = &(*Url)->Next;
-
}
}
FreeStrBuf(&All);
const char *Pos = NULL;
All = NewStrBufPlain(mxbuf, -1);
One = NewStrBufPlain(NULL, StrLength(All) + 1);
-
- while ((Pos != StrBufNOTNULL) && ((Pos == NULL) || !IsEmptyStr(Pos))) {
+
+ while ((Pos != StrBufNOTNULL) &&
+ ((Pos == NULL) ||
+ !IsEmptyStr(Pos)))
+ {
StrBufExtract_NextToken(One, All, &Pos, '|');
if (!ParseURL(Url, One, 25))
- syslog(LOG_DEBUG, "Failed to parse: %s\n", ChrPtr(One));
- else
+ syslog(LOG_DEBUG,
+ "Failed to parse: %s\n",
+ ChrPtr(One));
+ else
Url = &(*Url)->Next;
}
FreeStrBuf(&All);
while (GetNextHashPos(MyQItem->MailQEntries, It, &len, &Key, &vQE))
{
MailQEntry *ThisItem = vQE;
- syslog(LOG_DEBUG, "SMTP Queue: Task: <%s> %d\n",
- ChrPtr(ThisItem->Recipient),
+ syslog(LOG_DEBUG, "SMTP Queue: Task: <%s> %d\n",
+ ChrPtr(ThisItem->Recipient),
ThisItem->Active);
}
DeleteHashPos(&It);
int i = 1;
Msg = smtp_load_msg(MyQItem, n);
It = GetNewHashPos(MyQItem->MailQEntries, 0);
- while ((i <= m) &&
- (GetNextHashPos(MyQItem->MailQEntries, It, &len, &Key, &vQE)))
+ while ((i <= m) &&
+ (GetNextHashPos(MyQItem->MailQEntries,
+ It, &len, &Key, &vQE)))
{
MailQEntry *ThisItem = vQE;
- if (ThisItem->Active == 1) {
+
+ if (ThisItem->Active == 1)
+ {
int KeepBuffers = (i == m);
if (i > 1) n = MsgCount++;
- syslog(LOG_DEBUG,
- "SMTP Queue: Trying <%ld> <%s> %d / %d \n",
+ syslog(LOG_DEBUG,
+ "SMTPQ: Trying <%ld> <%s> %d / %d \n",
MyQItem->MessageID,
- ChrPtr(ThisItem->Recipient),
- i,
+ ChrPtr(ThisItem->Recipient),
+ i,
m);
- smtp_try_one_queue_entry(MyQItem,
- ThisItem,
- Msg,
- KeepBuffers,
- n,
+ smtp_try_one_queue_entry(MyQItem,
+ ThisItem,
+ Msg,
+ KeepBuffers,
+ n,
RelayUrls);
+
if (KeepBuffers) HaveBuffers = 1;
+
i++;
}
}
DeleteHashPos(&It);
}
- else
+ else
{
It = GetNewHashPos(MyQItem->MailQEntries, 0);
pthread_mutex_lock(&ActiveQItemsLock);
{
- if (GetHashPosFromKey(ActiveQItems, LKEY(MyQItem->MessageID), It))
+ if (GetHashPosFromKey(ActiveQItems,
+ LKEY(MyQItem->MessageID),
+ It))
+ {
DeleteEntryFromHash(ActiveQItems, It);
+ }
else
{
long len;
const char* Key;
void *VData;
- syslog(LOG_WARNING,
- "SMTP cleanup: unable to find QItem with ID[%ld]",
+
+ syslog(LOG_WARNING,
+ "SMTP cleanup: unable to find "
+ "QItem with ID[%ld]",
MyQItem->MessageID);
- while (GetNextHashPos(ActiveQItems, It, &len, &Key, &VData))
- syslog(LOG_WARNING,
+ while (GetNextHashPos(ActiveQItems,
+ It,
+ &len,
+ &Key,
+ &VData))
+ {
+ syslog(LOG_WARNING,
"SMTP cleanup: have: ID[%ld]",
- ((OneQueItem *)VData)->MessageID);
+ ((OneQueItem *)VData)->MessageID);
+ }
}
}
/*
* smtp_queue_thread()
- *
+ *
* Run through the queue sending out messages.
*/
void smtp_do_queue(void) {
static int is_running = 0;
int num_processed = 0;
- if (is_running) return; /* Concurrency check - only one can run */
+ if (is_running)
+ return; /* Concurrency check - only one can run */
is_running = 1;
pthread_setspecific(MyConKey, (void *)&smtp_queue_CC);
syslog(LOG_ERR, "Cannot find room <%s>", SMTP_SPOOLOUT_ROOM);
}
else {
- num_processed = CtdlForEachMessage(MSGS_ALL, 0L, NULL, SPOOLMIME, NULL, smtp_do_procmsg, NULL);
+ num_processed = CtdlForEachMessage(MSGS_ALL,
+ 0L,
+ NULL,
+ SPOOLMIME,
+ NULL,
+ smtp_do_procmsg,
+ NULL);
}
- syslog(LOG_INFO, "SMTP client: queue run completed; %d messages processed", num_processed);
+ syslog(LOG_INFO,
+ "SMTP client: queue run completed; %d messages processed",
+ num_processed);
+
run_queue_now = 0;
is_running = 0;
}
Put(QItemHandlers, HKEY("remote"), QItem_Handle_Recipient, reference_free_handler);
Put(QItemHandlers, HKEY("bounceto"), QItem_Handle_BounceTo, reference_free_handler);
Put(QItemHandlers, HKEY("submitted"), QItem_Handle_Submitted, reference_free_handler);
-////TODO: flush qitemhandlers on exit
+
smtp_init_spoolout();
CtdlRegisterCleanupHook(smtp_evq_cleanup);
CtdlRegisterProtoHook(cmd_smtp, "SMTP", "SMTP utility commands");
CtdlRegisterSessionHook(smtp_do_queue, EVT_TIMER);
}
-
+
/* return our Subversion id for the Log */
return "smtpeventclient";
}
* RFC 2821 - Simple Mail Transfer Protocol
* RFC 2822 - Internet Message Format
* RFC 2920 - SMTP Service Extension for Command Pipelining
- *
- * The VRFY and EXPN commands have been removed from this implementation
- * because nobody uses these commands anymore, except for spammers.
*
- * Copyright (c) 1998-2009 by the citadel.org team
+ * Copyright (c) 1998-2012 by the citadel.org team
*
* 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
#include "smtp_clienthandlers.h"
-#define SMTP_ERROR(WHICH_ERR, ERRSTR) do {\
- SendMsg->MyQEntry->Status = WHICH_ERR; \
- StrBufAppendBufPlain(SendMsg->MyQEntry->StatusMessage, HKEY(ERRSTR), 0); \
- return eAbort; } \
+#define SMTP_ERROR(WHICH_ERR, ERRSTR) do { \
+ SendMsg->MyQEntry->Status = WHICH_ERR; \
+ StrBufAppendBufPlain(SendMsg->MyQEntry->StatusMessage, \
+ HKEY(ERRSTR), 0); \
+ return eAbort; } \
while (0)
-#define SMTP_VERROR(WHICH_ERR) do {\
- SendMsg->MyQEntry->Status = WHICH_ERR; \
- StrBufPlain(SendMsg->MyQEntry->StatusMessage, \
- ChrPtr(SendMsg->IO.IOBuf) + 4, \
+#define SMTP_VERROR(WHICH_ERR) do { \
+ SendMsg->MyQEntry->Status = WHICH_ERR; \
+ StrBufPlain(SendMsg->MyQEntry->StatusMessage, \
+ ChrPtr(SendMsg->IO.IOBuf) + 4, \
StrLength(SendMsg->IO.IOBuf) - 4); \
- return eAbort; } \
+ return eAbort; } \
while (0)
#define SMTP_IS_STATE(WHICH_STATE) (ChrPtr(SendMsg->IO.IOBuf)[0] == WHICH_STATE)
-#define SMTP_DBG_SEND() EVS_syslog(LOG_DEBUG, "SMTP: > %s\n", ChrPtr(SendMsg->IO.SendBuf.Buf))
-#define SMTP_DBG_READ() EVS_syslog(LOG_DEBUG, "SMTP: < %s\n", ChrPtr(SendMsg->IO.IOBuf))
+#define SMTP_DBG_SEND() \
+ EVS_syslog(LOG_DEBUG, "SMTP: > %s\n", ChrPtr(SendMsg->IO.SendBuf.Buf))
+
+#define SMTP_DBG_READ() \
+ EVS_syslog(LOG_DEBUG, "SMTP: < %s\n", ChrPtr(SendMsg->IO.IOBuf))
/*****************************************************************************/
SMTP_DBG_READ();
if (!SMTP_IS_STATE('2')) {
- if (SMTP_IS_STATE('4'))
+ if (SMTP_IS_STATE('4'))
SMTP_VERROR(4);
- else
+ else
SMTP_VERROR(5);
}
return eSendReply;
if (SMTP_IS_STATE('2')) {
SendMsg->State ++;
- if ((SendMsg->pCurrRelay == NULL) ||
+ if ((SendMsg->pCurrRelay == NULL) ||
(SendMsg->pCurrRelay->User == NULL))
SendMsg->State ++; /* Skip auth... */
}
AsyncIO *IO = &SendMsg->IO;
SMTP_DBG_READ();
- if (!SMTP_IS_STATE('2')) {
+ if (!SMTP_IS_STATE('2'))
+ {
if (SMTP_IS_STATE('4'))
SMTP_VERROR(4);
- else
+ else
SMTP_VERROR(5);
}
- if ((SendMsg->pCurrRelay == NULL) ||
- (SendMsg->pCurrRelay->User == NULL))
+ if ((SendMsg->pCurrRelay == NULL) ||
+ (SendMsg->pCurrRelay->User == NULL))
SendMsg->State ++; /* Skip auth... */
+
return eSendReply;
}
char buf[SIZ];
char encoded[1024];
- if ((SendMsg->pCurrRelay == NULL) ||
+ if ((SendMsg->pCurrRelay == NULL) ||
(SendMsg->pCurrRelay->User == NULL))
SendMsg->State ++; /* Skip auth, shouldn't even come here!... */
else {
- /* Do an AUTH command if necessary */
- sprintf(buf, "%s%c%s%c%s",
- SendMsg->pCurrRelay->User, '\0',
- SendMsg->pCurrRelay->User, '\0',
- SendMsg->pCurrRelay->Pass);
- CtdlEncodeBase64(encoded, buf,
- strlen(SendMsg->pCurrRelay->User) * 2 +
- strlen(SendMsg->pCurrRelay->Pass) + 2, 0);
- StrBufPrintf(SendMsg->IO.SendBuf.Buf,
- "AUTH PLAIN %s\r\n", encoded);
+ /* Do an AUTH command if necessary */
+ sprintf(buf, "%s%c%s%c%s",
+ SendMsg->pCurrRelay->User, '\0',
+ SendMsg->pCurrRelay->User, '\0',
+ SendMsg->pCurrRelay->Pass);
+
+ CtdlEncodeBase64(encoded, buf,
+ strlen(SendMsg->pCurrRelay->User) * 2 +
+ strlen(SendMsg->pCurrRelay->Pass) + 2, 0);
+
+ StrBufPrintf(SendMsg->IO.SendBuf.Buf,
+ "AUTH PLAIN %s\r\n", encoded);
}
SMTP_DBG_SEND();
return eReadMessage;
{
AsyncIO *IO = &SendMsg->IO;
/* Do an AUTH command if necessary */
-
+
SMTP_DBG_READ();
-
+
if (!SMTP_IS_STATE('2')) {
if (SMTP_IS_STATE('4'))
SMTP_VERROR(4);
- else
+ else
SMTP_VERROR(5);
}
return eSendReply;
AsyncIO *IO = &SendMsg->IO;
/* previous command succeeded, now try the MAIL FROM: command */
StrBufPrintf(SendMsg->IO.SendBuf.Buf,
- "MAIL FROM:<%s>\r\n",
+ "MAIL FROM:<%s>\r\n",
SendMsg->envelope_from);
SMTP_DBG_SEND();
if (!SMTP_IS_STATE('2')) {
if (SMTP_IS_STATE('4'))
SMTP_VERROR(4);
- else
+ else
SMTP_VERROR(5);
}
return eSendReply;
AsyncIO *IO = &SendMsg->IO;
/* MAIL succeeded, now try the RCPT To: command */
StrBufPrintf(SendMsg->IO.SendBuf.Buf,
- "RCPT TO:<%s@%s>\r\n",
- SendMsg->user,
+ "RCPT TO:<%s@%s>\r\n",
+ SendMsg->user,
SendMsg->node);
SMTP_DBG_SEND();
SMTP_DBG_READ();
if (!SMTP_IS_STATE('2')) {
- if (SMTP_IS_STATE('4'))
+ if (SMTP_IS_STATE('4'))
SMTP_VERROR(4);
- else
+ else
SMTP_VERROR(5);
}
return eSendReply;
SMTP_DBG_READ();
if (!SMTP_IS_STATE('3')) {
- if (SMTP_IS_STATE('4'))
+ if (SMTP_IS_STATE('4'))
SMTP_VERROR(3);
- else
+ else
SMTP_VERROR(5);
}
return eSendReply;
if (!SMTP_IS_STATE('2')) {
if (SMTP_IS_STATE('4'))
SMTP_VERROR(4);
- else
+ else
SMTP_VERROR(5);
}
/* We did it! */
- StrBufPlain(SendMsg->MyQEntry->StatusMessage,
+ StrBufPlain(SendMsg->MyQEntry->StatusMessage,
&ChrPtr(SendMsg->IO.RecvBuf.Buf)[4],
StrLength(SendMsg->IO.RecvBuf.Buf) - 4);
SendMsg->MyQEntry->Status = 2;
AsyncIO *IO = &SendMsg->IO;
SMTP_DBG_READ();
- EVS_syslog(LOG_INFO, "SMTP client[%ld]: delivery to <%s> @ <%s> (%s) succeeded\n",
- SendMsg->n, SendMsg->user, SendMsg->node, SendMsg->name);
+ EVS_syslog(LOG_INFO,
+ "SMTP client[%ld]: delivery to <%s> @ <%s> (%s) succeeded\n",
+ SendMsg->n,
+ SendMsg->user,
+ SendMsg->node,
+ SendMsg->name);
+
return eTerminateConnection;
}
{HKEY("Connection broken during SMTP RCPT")},
{HKEY("Connection broken during SMTP DATA")},
{HKEY("Connection broken during SMTP message transmit")},
- {HKEY("")},/* quit reply, don't care. */
- {HKEY("")},/* quit reply, don't care. */
+ {HKEY("")},/* quit reply, don't care. */
+ {HKEY("")},/* quit reply, don't care. */
{HKEY("")}/* quit reply, don't care. */
};
EVNCS_syslog(LOG_DEBUG, "SMTP: %s\n", __FUNCTION__);
- if ((SendMsg==NULL) ||
- (SendMsg->MyQEntry == NULL) ||
+ if ((SendMsg==NULL) ||
+ (SendMsg->MyQEntry == NULL) ||
(StrLength(SendMsg->MyQEntry->Recipient) == 0)) {
return 0;
}
/* Parse out the host portion of the recipient address */
- process_rfc822_addr(ChrPtr(SendMsg->MyQEntry->Recipient),
- SendMsg->user,
- SendMsg->node,
+ process_rfc822_addr(ChrPtr(SendMsg->MyQEntry->Recipient),
+ SendMsg->user,
+ SendMsg->node,
SendMsg->name);
- EVNCS_syslog(LOG_DEBUG, "SMTP client[%ld]: Attempting delivery to <%s> @ <%s> (%s)\n",
- SendMsg->n, SendMsg->user, SendMsg->node, SendMsg->name);
+ EVNCS_syslog(LOG_DEBUG,
+ "SMTP client[%ld]: Attempting delivery to "
+ "<%s> @ <%s> (%s)\n",
+ SendMsg->n,
+ SendMsg->user,
+ SendMsg->node,
+ SendMsg->name);
+
/* If no envelope_from is supplied, extract one from the message */
SendMsg->envelope_from = ChrPtr(SendMsg->MyQItem->EnvelopeFrom);
- if ( (SendMsg->envelope_from == NULL) ||
+ if ( (SendMsg->envelope_from == NULL) ||
(IsEmptyStr(SendMsg->envelope_from)) ) {
SendMsg->mailfrom[0] = '\0';
scan_done = 0;
ptr = ChrPtr(SendMsg->msgtext);
do {
- if (ptr = cmemreadline(ptr, buf, sizeof buf), *ptr == 0) {
+ if (ptr = cmemreadline(ptr, buf, sizeof buf), *ptr == 0)
+ {
scan_done = 1;
}
- if (!strncasecmp(buf, "From:", 5)) {
- safestrncpy(SendMsg->mailfrom, &buf[5], sizeof SendMsg->mailfrom);
+ if (!strncasecmp(buf, "From:", 5))
+ {
+ safestrncpy(SendMsg->mailfrom,
+ &buf[5],
+ sizeof SendMsg->mailfrom);
+
striplt(SendMsg->mailfrom);
for (i=0; SendMsg->mailfrom[i]; ++i) {
- if (!isprint(SendMsg->mailfrom[i])) {
- strcpy(&SendMsg->mailfrom[i], &SendMsg->mailfrom[i+1]);
+ if (!isprint(SendMsg->mailfrom[i]))
+ {
+ strcpy(&SendMsg->mailfrom[i],
+ &SendMsg->mailfrom[i+1]);
i=0;
}
}
-
+
/* Strip out parenthesized names */
lp = (-1);
rp = (-1);
- for (i=0; !IsEmptyStr(SendMsg->mailfrom + i); ++i) {
+ for (i=0;
+ !IsEmptyStr(SendMsg->mailfrom + i);
+ ++i)
+ {
if (SendMsg->mailfrom[i] == '(') lp = i;
if (SendMsg->mailfrom[i] == ')') rp = i;
}
- if ((lp>0)&&(rp>lp)) {
- strcpy(&SendMsg->mailfrom[lp-1], &SendMsg->mailfrom[rp+1]);
+ if ((lp>0)&&(rp>lp))
+ {
+ strcpy(&SendMsg->mailfrom[lp-1],
+ &SendMsg->mailfrom[rp+1]);
}
-
+
/* Prefer brokketized names */
lp = (-1);
rp = (-1);
- for (i=0; !IsEmptyStr(SendMsg->mailfrom + i); ++i) {
+ for (i=0;
+ !IsEmptyStr(SendMsg->mailfrom + i);
+ ++i)
+ {
if (SendMsg->mailfrom[i] == '<') lp = i;
if (SendMsg->mailfrom[i] == '>') rp = i;
}
if ( (lp>=0) && (rp>lp) ) {
SendMsg->mailfrom[rp] = 0;
- memmove(SendMsg->mailfrom,
- &SendMsg->mailfrom[lp + 1],
+ memmove(SendMsg->mailfrom,
+ &SendMsg->mailfrom[lp + 1],
rp - lp);
}
-
+
scan_done = 1;
}
} while (scan_done == 0);
- if (IsEmptyStr(SendMsg->mailfrom)) strcpy(SendMsg->mailfrom, "someone@somewhere.org");
+ if (IsEmptyStr(SendMsg->mailfrom))
+ strcpy(SendMsg->mailfrom, "someone@somewhere.org");
+
stripallbut(SendMsg->mailfrom, '<', '>');
SendMsg->envelope_from = SendMsg->mailfrom;
}
+/*
+ *
+ * Copyright (c) 1998-2012 by the citadel.org team
+ *
+ * This program is open source 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
+ */
+
typedef enum _eSMTP_C_States {
- eConnectMX,
+ eConnectMX,
eEHLO,
eHELO,
eSMTPAuth,
#define F_RELAY (1<<0) /* we have a Relay host configuration */
#define F_HAVE_FALLBACK (1<<1) /* we have a fallback host configuration */
#define F_FALLBACK (1<<2)
-#define F_HAVE_MX (1<<3) /* we have a list of mx records to go through. */
+#define F_HAVE_MX (1<<3) /* we have a list of mx records to go through.*/
#define F_DIRECT (1<<4) /* no mx record found, trying direct connect. */
#define QID ((SmtpOutMsg*)IO->Data)->MyQItem->MessageID
#define N ((SmtpOutMsg*)IO->Data)->n
-#define EVS_syslog(LEVEL, FORMAT, ...) syslog(LEVEL, "IO[%ld]CC[%d]S[%ld][%ld]" FORMAT, IO->ID, CCID, QID, N, __VA_ARGS__)
-#define EVSM_syslog(LEVEL, FORMAT) syslog(LEVEL, "IO[%ld]CC[%d]S[%ld][%ld]" FORMAT, IO->ID, CCID, QID, N)
-#define EVNCS_syslog(LEVEL, FORMAT, ...) syslog(LEVEL, "IO[%ld]S[%ld][%ld]" FORMAT, IO->ID, QID, N, __VA_ARGS__)
-#define EVNCSM_syslog(LEVEL, FORMAT) syslog(LEVEL, "IO[%ld]S[%ld][%ld]" FORMAT, IO->ID, QID, N)
+
+#define EVS_syslog(LEVEL, FORMAT, ...) \
+ syslog(LEVEL, \
+ "IO[%ld]CC[%d]S[%ld][%ld]" FORMAT, \
+ IO->ID, CCID, QID, N, __VA_ARGS__)
+
+#define EVSM_syslog(LEVEL, FORMAT) \
+ syslog(LEVEL, \
+ "IO[%ld]CC[%d]S[%ld][%ld]" FORMAT, \
+ IO->ID, CCID, QID, N)
+
+#define EVNCS_syslog(LEVEL, FORMAT, ...) \
+ syslog(LEVEL, "IO[%ld]S[%ld][%ld]" FORMAT, \
+ IO->ID, QID, N, __VA_ARGS__)
+
+#define EVNCSM_syslog(LEVEL, FORMAT) \
+ syslog(LEVEL, "IO[%ld]S[%ld][%ld]" FORMAT, \
+ IO->ID, QID, N)
* instructions for "5" codes (permanent fatal errors) and produce/deliver
* a "bounce" message (delivery status notification).
*/
-void smtp_do_bounce(char *instr, StrBuf *OMsgTxt)
+void smtp_do_bounce(char *instr, StrBuf *OMsgTxt)
{
int i;
int lines;
syslog(LOG_DEBUG, "smtp_do_bounce() called\n");
strcpy(bounceto, "");
boundary = NewStrBufPlain(HKEY("=_Citadel_Multipart_"));
- StrBufAppendPrintf(boundary, "%s_%04x%04x", config.c_fqdn, getpid(), ++seq);
+
+ StrBufAppendPrintf(boundary,
+ "%s_%04x%04x",
+ config.c_fqdn,
+ getpid(),
+ ++seq);
+
lines = num_tokens(instr, '\n');
/* See if it's time to give up on delivery of this message */
memset(bmsg, 0, sizeof(struct CtdlMessage));
BounceMB = NewStrBufPlain(NULL, 1024);
- bmsg->cm_magic = CTDLMESSAGE_MAGIC;
- bmsg->cm_anon_type = MES_NORMAL;
- bmsg->cm_format_type = FMT_RFC822;
- bmsg->cm_fields['A'] = strdup("Citadel");
- bmsg->cm_fields['O'] = strdup(MAILROOM);
- bmsg->cm_fields['N'] = strdup(config.c_nodename);
- bmsg->cm_fields['U'] = strdup("Delivery Status Notification (Failure)");
- StrBufAppendBufPlain(BounceMB, HKEY("Content-type: multipart/mixed; boundary=\""), 0);
+ bmsg->cm_magic = CTDLMESSAGE_MAGIC;
+ bmsg->cm_anon_type = MES_NORMAL;
+ bmsg->cm_format_type = FMT_RFC822;
+ bmsg->cm_fields['A'] = strdup("Citadel");
+ bmsg->cm_fields['O'] = strdup(MAILROOM);
+ bmsg->cm_fields['N'] = strdup(config.c_nodename);
+ bmsg->cm_fields['U'] = strdup("Delivery Status Notification (Failure)");
+ StrBufAppendBufPlain(
+ BounceMB,
+ HKEY("Content-type: multipart/mixed; boundary=\""), 0);
StrBufAppendBuf(BounceMB, boundary, 0);
- StrBufAppendBufPlain(BounceMB, HKEY("\"\r\n"), 0);
+ StrBufAppendBufPlain(BounceMB, HKEY("\"\r\n"), 0);
StrBufAppendBufPlain(BounceMB, HKEY("MIME-Version: 1.0\r\n"), 0);
StrBufAppendBufPlain(BounceMB, HKEY("X-Mailer: " CITADEL "\r\n"), 0);
- StrBufAppendBufPlain(BounceMB, HKEY("\r\nThis is a multipart message in MIME format.\r\n\r\n"), 0);
- StrBufAppendBufPlain(BounceMB, HKEY("--"), 0);
- StrBufAppendBuf(BounceMB, boundary, 0);
- StrBufAppendBufPlain(BounceMB, HKEY("\r\n"), 0);
- StrBufAppendBufPlain(BounceMB, HKEY("Content-type: text/plain\r\n\r\n"), 0);
- if (give_up) StrBufAppendBufPlain(BounceMB, HKEY(
-"A message you sent could not be delivered to some or all of its recipients\n"
-"due to prolonged unavailability of its destination(s).\n"
-"Giving up on the following addresses:\n\n"
- ), 0);
+ StrBufAppendBufPlain(
+ BounceMB,
+ HKEY("\r\nThis is a multipart message in MIME format."
+ "\r\n\r\n"), 0);
- else StrBufAppendBufPlain(BounceMB, HKEY(
-"A message you sent could not be delivered to some or all of its recipients.\n"
-"The following addresses were undeliverable:\n\n"
- ), 0);
+ StrBufAppendBufPlain(BounceMB, HKEY("--"), 0);
+ StrBufAppendBuf(BounceMB, boundary, 0);
+ StrBufAppendBufPlain(BounceMB, HKEY("\r\n"), 0);
+ StrBufAppendBufPlain(BounceMB,
+ HKEY("Content-type: text/plain\r\n\r\n"), 0);
+
+ if (give_up)
+ {
+ StrBufAppendBufPlain(
+ BounceMB,
+ HKEY("A message you sent could not be delivered "
+ "to some or all of its recipients\ndue to "
+ "prolonged unavailability of its destination(s).\n"
+ "Giving up on the following addresses:\n\n"), 0);
+ }
+ else
+ {
+ StrBufAppendBufPlain(
+ BounceMB,
+ HKEY("A message you sent could not be delivered "
+ "to some or all of its recipients.\n"
+ "The following addresses were undeliverable:\n\n"
+ ), 0);
+ }
/*
* Now go through the instructions checking for stuff.
/* Attach the original message */
if (omsgid >= 0) {
- StrBufAppendBufPlain(BounceMB, HKEY("--"), 0);
+ StrBufAppendBufPlain(BounceMB, HKEY("--"), 0);
StrBufAppendBuf(BounceMB, boundary, 0);
- StrBufAppendBufPlain(BounceMB, HKEY("\r\n"), 0);
- StrBufAppendBufPlain(BounceMB, HKEY("Content-type: message/rfc822\r\n"), 0);
- StrBufAppendBufPlain(BounceMB, HKEY("Content-Transfer-Encoding: 7bit\r\n"), 0);
- StrBufAppendBufPlain(BounceMB, HKEY("Content-Disposition: inline\r\n"), 0);
- StrBufAppendBufPlain(BounceMB, HKEY("\r\n"), 0);
-
+ StrBufAppendBufPlain(BounceMB, HKEY("\r\n"), 0);
+
+ StrBufAppendBufPlain(
+ BounceMB,
+ HKEY("Content-type: message/rfc822\r\n"), 0);
+
+ StrBufAppendBufPlain(
+ BounceMB,
+ HKEY("Content-Transfer-Encoding: 7bit\r\n"), 0);
+
+ StrBufAppendBufPlain(
+ BounceMB,
+ HKEY("Content-Disposition: inline\r\n"), 0);
+
+ StrBufAppendBufPlain(BounceMB, HKEY("\r\n"), 0);
+
if (OMsgTxt == NULL) {
CC->redirect_buffer = NewStrBufPlain(NULL, SIZ);
- CtdlOutputMsg(omsgid, MT_RFC822, HEADERS_ALL, 0, 1, NULL, 0);
+ CtdlOutputMsg(omsgid,
+ MT_RFC822,
+ HEADERS_ALL,
+ 0, 1, NULL, 0);
+
StrBufAppendBuf(BounceMB, CC->redirect_buffer, 0);
FreeStrBuf(&CC->redirect_buffer);
}
}
/* Close the multipart MIME scope */
- StrBufAppendBufPlain(BounceMB, HKEY("--"), 0);
+ StrBufAppendBufPlain(BounceMB, HKEY("--"), 0);
StrBufAppendBuf(BounceMB, boundary, 0);
StrBufAppendBufPlain(BounceMB, HKEY("--\r\n"), 0);
if (bmsg->cm_fields['A'] != NULL)
if (num_bounces > 0) {
/* First try the user who sent the message */
- if (IsEmptyStr(bounceto))
+ if (IsEmptyStr(bounceto))
syslog(LOG_ERR, "No bounce address specified\n");
else
syslog(LOG_DEBUG, "bounce to user <%s>\n", bounceto);
/* Can we deliver the bounce to the original sender? */
- valid = validate_recipients(bounceto, smtp_get_Recipients (), 0);
+ valid = validate_recipients(bounceto,
+ smtp_get_Recipients (),
+ 0);
if (valid != NULL) {
if (valid->num_error == 0) {
CtdlSubmitMsg(bmsg, valid, "", QP_EADDR);
+/*
+ *
+ * Copyright (c) 1998-2012 by the citadel.org team
+ *
+ * This program is open source 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
+ */
+
/*****************************************************************************/
/* SMTP CLIENT (Queue Management) STUFF */
/*****************************************************************************/
* 2 = Delivery was successful
* 4 = A transient error was experienced ... try again later
* 5 = Delivery to this address failed permanently. The error message
- * should be placed in the fourth field so that a bounce message may
+ * should be placed in the fourth field so that a bounce message may
* be generated.
*/
long Submitted;
int FailNow;
HashList *MailQEntries;
- MailQEntry *Current; /* copy of the currently parsed item in the MailQEntries list; if null add a new one. */
+/* copy of the currently parsed item in the MailQEntries list;
+ * if null add a new one.
+ */
+ MailQEntry *Current;
DeliveryAttempt LastAttempt;
long ActiveDeliveries;
StrBuf *EnvelopeFrom;
ParsedURL *URL;
ParsedURL *FallBackHost;
} OneQueItem;
+
typedef void (*QItemHandler)(OneQueItem *Item, StrBuf *Line, const char **Pos);
-int DecreaseQReference(OneQueItem *MyQItem);
-void RemoveQItem(OneQueItem *MyQItem);
-int CountActiveQueueEntries(OneQueItem *MyQItem);
+int DecreaseQReference(OneQueItem *MyQItem);
+void RemoveQItem(OneQueItem *MyQItem);
+int CountActiveQueueEntries(OneQueItem *MyQItem);
StrBuf *SerializeQueueItem(OneQueItem *MyQItem);
-
-void smtpq_do_bounce(OneQueItem *MyQItem, StrBuf *OMsgTxt);
+void smtpq_do_bounce(OneQueItem *MyQItem, StrBuf *OMsgTxt);