From 66f72c07b70ed9500c49e8ff3c3f895e5269d339 Mon Sep 17 00:00:00 2001 From: Wilfried Goesgens Date: Fri, 30 Dec 2011 19:31:58 +0100 Subject: [PATCH] Style cleanup --- citadel/configure.ac | 17 - citadel/event_client.c | 160 +++--- citadel/event_client.h | 110 ++-- citadel/modules/c-ares-dns/serv_c-ares-dns.c | 121 +++-- .../modules/eventclient/serv_eventclient.c | 508 ++++++++++-------- citadel/modules/extnotify/extnotify.h | 24 +- citadel/modules/extnotify/extnotify_main.c | 131 +++-- citadel/modules/extnotify/funambol65.c | 4 +- citadel/modules/pop3client/serv_pop3client.c | 350 +++++++----- citadel/modules/rssclient/rss_atom_parser.c | 328 +++++++---- citadel/modules/rssclient/serv_rssclient.c | 158 +++--- citadel/modules/smtp/serv_smtpeventclient.c | 146 ++--- citadel/modules/smtp/serv_smtpqueue.c | 323 ++++++----- citadel/modules/smtp/smtp_clienthandlers.c | 179 +++--- citadel/modules/smtp/smtp_clienthandlers.h | 45 +- citadel/modules/smtp/smtp_util.c | 110 ++-- citadel/modules/smtp/smtpqueue.h | 36 +- 17 files changed, 1692 insertions(+), 1058 deletions(-) diff --git a/citadel/configure.ac b/citadel/configure.ac index 80be74e7c..a4140b822 100644 --- a/citadel/configure.ac +++ b/citadel/configure.ac @@ -626,23 +626,6 @@ AC_CHECK_HEADER(ev.h, CFLAGS="$saved_CFLAGS" - - - - - - - - - - - - - - - - - # The big search for OpenSSL if test "$with_ssl" != "no"; then saved_LIBS="$LIBS" diff --git a/citadel/event_client.c b/citadel/event_client.c index cea9a24f7..833a270a7 100644 --- a/citadel/event_client.c +++ b/citadel/event_client.c @@ -1,6 +1,6 @@ /* * - * 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 @@ -67,7 +67,9 @@ #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__); @@ -77,14 +79,14 @@ static void IO_abort_shutdown_callback(struct ev_loop *loop, ev_cleanup *watcher } -/*-------------------------------------------------------------------------------- - * 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) @@ -95,7 +97,7 @@ 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); @@ -120,7 +122,7 @@ void ShutDownDBCLient(AsyncIO *IO) ev_cleanup_stop(event_db, &IO->db_abort_by_shutdown); assert(IO->Terminate); - IO->Terminate(IO); + IO->Terminate(IO); } void @@ -129,7 +131,7 @@ DB_PerformNext(struct ev_loop *loop, ev_idle *watcher, int revents) 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); @@ -140,10 +142,10 @@ DB_PerformNext(struct ev_loop *loop, ev_idle *watcher, int revents) case eSendDNSQuery: case eReadDNSReply: case eConnect: - case eSendReply: + case eSendReply: case eSendMore: case eSendFile: - case eReadMessage: + case eReadMessage: case eReadMore: case eReadPayload: case eReadFile: @@ -167,14 +169,14 @@ eNextState NextDBOperation(AsyncIO *IO, IO_CallBack CB) 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; @@ -186,7 +188,7 @@ eNextState QueueEventContext(AsyncIO *IO, IO_CallBack CB) 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); @@ -282,47 +284,46 @@ eReadState HandleInbound(AsyncIO *IO) { 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); @@ -379,15 +380,15 @@ IO_send_callback(struct ev_loop *loop, ev_io *watcher, int revents) 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); @@ -402,7 +403,9 @@ IO_send_callback(struct ev_loop *loop, ev_io *watcher, int revents) 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 @@ -437,12 +440,13 @@ IO_send_callback(struct ev_loop *loop, ev_io *watcher, int revents) 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: @@ -454,14 +458,15 @@ IO_send_callback(struct ev_loop *loop, ev_io *watcher, int revents) } 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 { @@ -470,7 +475,10 @@ IO_send_callback(struct ev_loop *loop, ev_io *watcher, int revents) 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: @@ -490,7 +498,6 @@ IO_send_callback(struct ev_loop *loop, ev_io *watcher, int revents) static void set_start_callback(struct ev_loop *loop, AsyncIO *IO, int revents) { - switch(IO->NextState) { case eReadMore: case eReadMessage: @@ -533,7 +540,7 @@ IO_Timeout_callback(struct ev_loop *loop, ev_timer *watcher, int revents) } assert(IO->Timeout); - switch (IO->Timeout(IO)) + switch (IO->Timeout(IO)) { case eAbort: ShutDownCLient(IO); @@ -561,7 +568,7 @@ IO_connfail_callback(struct ev_loop *loop, ev_timer *watcher, int revents) become_session(IO->CitContext); assert(IO->ConnFail); - switch (IO->ConnFail(IO)) + switch (IO->ConnFail(IO)) { case eAbort: ShutDownCLient(IO); @@ -572,7 +579,9 @@ IO_connfail_callback(struct ev_loop *loop, ev_timer *watcher, int revents) } 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; @@ -586,7 +595,7 @@ IO_connfailimmediate_callback(struct ev_loop *loop, ev_idle *watcher, int revent become_session(IO->CitContext); assert(IO->ConnFail); - switch (IO->ConnFail(IO)) + switch (IO->ConnFail(IO)) { case eAbort: ShutDownCLient(IO); @@ -617,7 +626,7 @@ IO_recv_callback(struct ev_loop *loop, ev_io *watcher, int revents) nbytes = FileRecvChunked(&IO->IOB, &errmsg); if (nbytes < 0) StrBufPlain(IO->ErrMsg, errmsg, -1); - else + else { if (IO->IOB.ChunkSendRemain == 0) { @@ -628,35 +637,35 @@ IO_recv_callback(struct ev_loop *loop, ev_io *watcher, int revents) } 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 @@ -675,7 +684,7 @@ IO_recv_callback(struct ev_loop *loop, ev_io *watcher, int revents) 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); @@ -776,8 +785,11 @@ eNextState EvConnectSock(AsyncIO *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, diff --git a/citadel/event_client.h b/citadel/event_client.h index 9c4fd2ba1..8fcef9fde 100644 --- a/citadel/event_client.h +++ b/citadel/event_client.h @@ -1,3 +1,22 @@ +/* + * + * 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 @@ -19,11 +38,11 @@ typedef enum _eNextState { eDBQuery, eConnect, - eSendReply, + eSendReply, eSendMore, eSendFile, - eReadMessage, + eReadMessage, eReadMore, eReadPayload, eReadFile, @@ -46,7 +65,8 @@ typedef struct __ReadAsyncMsg { 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; @@ -62,25 +82,25 @@ typedef struct _DNSQueryParts { 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 @@ -89,23 +109,24 @@ typedef struct __evcares_data { 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... */ @@ -125,12 +146,14 @@ struct AsyncIO { 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; @@ -141,7 +164,7 @@ struct AsyncIO { 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... */ }; @@ -149,13 +172,19 @@ struct AsyncIO { 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); @@ -165,14 +194,22 @@ eNextState QueueDBOperation(AsyncIO *IO, IO_CallBack CB); 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); @@ -188,9 +225,12 @@ void InitC_ares_dns(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, @@ -212,8 +252,8 @@ int InitcURLIOStruct(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__ */ diff --git a/citadel/modules/c-ares-dns/serv_c-ares-dns.c b/citadel/modules/c-ares-dns/serv_c-ares-dns.c index 6c56fd633..a22d6c557 100644 --- a/citadel/modules/c-ares-dns/serv_c-ares-dns.c +++ b/citadel/modules/c-ares-dns/serv_c-ares-dns.c @@ -64,9 +64,9 @@ void SockStateCb(void *data, int sock, int read, int write); 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 @@ -80,10 +80,9 @@ static void HostByAddrCb(void *data, 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 @@ -94,9 +93,14 @@ static void ParseAnswerA(AsyncIO *IO, unsigned char* abuf, int alen) 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; @@ -104,7 +108,7 @@ static void ParseAnswerA(AsyncIO *IO, unsigned char* abuf, int alen) } -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 @@ -115,9 +119,14 @@ static void ParseAnswerAAAA(AsyncIO *IO, unsigned char* abuf, int alen) 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; @@ -125,7 +134,7 @@ static void ParseAnswerAAAA(AsyncIO *IO, unsigned char* abuf, int alen) } -static void ParseAnswerCNAME(AsyncIO *IO, unsigned char* abuf, int alen) +static void ParseAnswerCNAME(AsyncIO *IO, unsigned char* abuf, int alen) { struct hostent* host; @@ -137,9 +146,14 @@ static void ParseAnswerCNAME(AsyncIO *IO, unsigned char* abuf, int alen) 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; } @@ -149,7 +163,7 @@ static void ParseAnswerCNAME(AsyncIO *IO, unsigned char* abuf, int alen) } -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 @@ -162,7 +176,8 @@ static void ParseAnswerMX(AsyncIO *IO, unsigned char* abuf, int alen) 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; } @@ -171,7 +186,7 @@ static void ParseAnswerMX(AsyncIO *IO, unsigned char* abuf, int alen) } -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 @@ -184,7 +199,8 @@ static void ParseAnswerNS(AsyncIO *IO, unsigned char* abuf, int alen) 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; @@ -192,7 +208,7 @@ static void ParseAnswerNS(AsyncIO *IO, unsigned char* abuf, int alen) } -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 @@ -205,7 +221,8 @@ static void ParseAnswerSRV(AsyncIO *IO, unsigned char* abuf, int alen) 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; } @@ -214,7 +231,7 @@ static void ParseAnswerSRV(AsyncIO *IO, unsigned char* abuf, int alen) } -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 @@ -227,7 +244,8 @@ static void ParseAnswerTXT(AsyncIO *IO, unsigned char* abuf, int alen) 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; @@ -238,7 +256,7 @@ void QueryCb(void *arg, int status, int timeouts, unsigned char* abuf, - int alen) + int alen) { AsyncIO *IO = arg; #ifdef DEBUG_CARES @@ -256,7 +274,7 @@ void QueryCb(void *arg, 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; @@ -320,7 +338,7 @@ DNStimeouttrigger_callback(struct ev_loop *loop, ev_timer *watcher, int revents) } } -void QueueGetHostByNameDone(void *Ctx, +void QueueGetHostByNameDone(void *Ctx, int status, int timeouts, struct hostent *hostent) @@ -340,7 +358,10 @@ void QueueGetHostByNameDone(void *Ctx, 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__); @@ -355,14 +376,19 @@ void QueueGetHostByName(AsyncIO *IO, const char *Hostname, DNSQueryParts *QueryP 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)]; @@ -421,7 +447,12 @@ int QueueQuery(ns_type Type, const char *name, AsyncIO *IO, DNSQueryParts *Query 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__); @@ -452,25 +483,29 @@ int QueueQuery(ns_type Type, const char *name, AsyncIO *IO, DNSQueryParts *Query 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. */ @@ -478,8 +513,8 @@ void SockStateCb(void *data, int sock, int read, int write) { 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); @@ -499,17 +534,23 @@ void SockStateCb(void *data, int sock, int read, int write) 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); } @@ -525,9 +566,7 @@ CTDL_MODULE_INIT(c_ares_client) { 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"; diff --git a/citadel/modules/eventclient/serv_eventclient.c b/citadel/modules/eventclient/serv_eventclient.c index 00ff1f722..b49c63673 100644 --- a/citadel/modules/eventclient/serv_eventclient.c +++ b/citadel/modules/eventclient/serv_eventclient.c @@ -65,74 +65,100 @@ long EvIDSource = 1; /***************************************************************************** * 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); @@ -141,10 +167,10 @@ gotstatus(int nnrun) case eSendDNSQuery: case eReadDNSReply: case eConnect: - case eSendReply: + case eSendReply: case eSendMore: case eSendFile: - case eReadMessage: + case eReadMessage: case eReadMore: case eReadPayload: case eReadFile: @@ -160,83 +186,115 @@ gotstatus(int nnrun) 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); @@ -252,121 +310,133 @@ gotwatchsock(CURL *easy, curl_socket_t fd, int action, void *cglobal, void *vIO) 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); } @@ -375,23 +445,31 @@ int evcurl_init(AsyncIO *IO) 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); @@ -401,14 +479,15 @@ static void IOcurl_abort_shutdown_callback(struct ev_loop *loop, ev_cleanup *wat 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)) { @@ -416,12 +495,13 @@ evcurl_handle_start(AsyncIO *IO) 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); @@ -432,11 +512,17 @@ evcurl_handle_start(AsyncIO *IO) 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; } @@ -468,14 +554,14 @@ HashList *QueueEvents = NULL; 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; @@ -522,7 +608,9 @@ void InitEventQueue(void) 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; @@ -534,10 +622,9 @@ void InitEventQueue(void) InboundEventQueues[1] = NewHash(1, Flathash); InboundEventQueue = InboundEventQueues[0]; } + /* * this thread operates the select() etc. via libev. - * - * */ void *client_event_thread(void *arg) { @@ -574,7 +661,8 @@ void *client_event_thread(void *arg) return(NULL); } -/*------------------------------------------------------------------------------*/ + +/*----------------------------------------------------------------------------*/ /* * DB-Queue; does async bdb operations. * has its own set of handlers. @@ -587,7 +675,7 @@ HashList *DBQueueEvents = NULL; HashList *DBInboundEventQueue = NULL; HashList *DBInboundEventQueues[2] = { NULL, NULL }; -ev_async DBAddJob; +ev_async DBAddJob; ev_async DBExitEventLoop; extern void ShutDownDBCLient(AsyncIO *IO); @@ -596,7 +684,7 @@ static void DBQueueEventAddCallback(EV_P_ ev_async *w, int revents) { HashList *q; void *v; - HashPos *It; + HashPos *It; long len; const char *Key; @@ -624,9 +712,9 @@ static void DBQueueEventAddCallback(EV_P_ ev_async *w, int revents) switch (rc) { case eAbort: - ShutDownDBCLient(h->IO); + ShutDownDBCLient(h->IO); default: - break; + break; } } DeleteHashPos(&It); @@ -665,10 +753,8 @@ void DBInitEventQueue(void) /* * 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; diff --git a/citadel/modules/extnotify/extnotify.h b/citadel/modules/extnotify/extnotify.h index efe6b9136..3cc476790 100644 --- a/citadel/modules/extnotify/extnotify.h +++ b/citadel/modules/extnotify/extnotify.h @@ -1,4 +1,4 @@ -/* +/* * File: extnotify.h * Author: Mathew McBride / * Copyright (c) 2008-2009 @@ -21,12 +21,11 @@ #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; @@ -41,17 +40,14 @@ typedef struct _NotifyContext { 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); - - - diff --git a/citadel/modules/extnotify/extnotify_main.c b/citadel/modules/extnotify/extnotify_main.c index 302932295..123a8771b 100644 --- a/citadel/modules/extnotify/extnotify_main.c +++ b/citadel/modules/extnotify/extnotify_main.c @@ -77,10 +77,10 @@ void ExtNotify_PutErrorMessage(NotifyContext *Ctx, StrBuf *ErrMsg) 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); } @@ -107,20 +107,24 @@ int GetNotifyHosts(NotifyContext *Ctx) 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; notifynNotifyHosts; notify++) { - + for (notify=0; notifynNotifyHosts; 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; } @@ -137,7 +141,9 @@ int GetNotifyHosts(NotifyContext *Ctx) /*! \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 @@ -152,8 +158,11 @@ eNotifyType extNotify_getConfigMessage(char *username, char **PagerNumber, char // 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, @@ -163,26 +172,31 @@ eNotifyType extNotify_getConfigMessage(char *username, char **PagerNumber, char 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; @@ -230,10 +244,10 @@ eNotifyType extNotify_getConfigMessage(char *username, char **PagerNumber, char if (!pch || (*pch == '\0')) { free(configMsg); - + return eNone; } - while (isspace(*pch)) + while (isspace(*pch)) pch ++; *PagerNumber = pch; while (isdigit(*pch) || (*pch == '+')) @@ -251,7 +265,7 @@ eNotifyType extNotify_getConfigMessage(char *username, char **PagerNumber, char /* * 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; @@ -267,12 +281,15 @@ void process_notify(long NotifyMsgnum, void *usrdata) 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) @@ -284,12 +301,12 @@ void process_notify(long NotifyMsgnum, void *usrdata) 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: @@ -299,42 +316,53 @@ void process_notify(long NotifyMsgnum, void *usrdata) 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); } @@ -354,26 +382,29 @@ void process_notify(long NotifyMsgnum, void *usrdata) * \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); @@ -386,7 +417,7 @@ void do_extnotify_queue(void) 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); @@ -420,11 +451,11 @@ void do_extnotify_queue(void) */ 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 nown rooms list for Aides. @@ -444,5 +475,5 @@ CTDL_MODULE_INIT(extnotify) CtdlRegisterSessionHook(do_extnotify_queue, EVT_TIMER); } /* return our module name for the log */ - return "extnotify"; + return "extnotify"; } diff --git a/citadel/modules/extnotify/funambol65.c b/citadel/modules/extnotify/funambol65.c index bff95fbb4..77a2dacee 100644 --- a/citadel/modules/extnotify/funambol65.c +++ b/citadel/modules/extnotify/funambol65.c @@ -1,7 +1,7 @@ -/* +/* * funambol65.c * Author: Mathew McBride - * + * * This module facilitates notifications to a Funambol server * for push email * diff --git a/citadel/modules/pop3client/serv_pop3client.c b/citadel/modules/pop3client/serv_pop3client.c index 32426e0c3..51f1d62db 100644 --- a/citadel/modules/pop3client/serv_pop3client.c +++ b/citadel/modules/pop3client/serv_pop3client.c @@ -53,11 +53,38 @@ #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; @@ -96,20 +123,17 @@ void HfreeFetchItem(void *vItem) 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 @@ -119,7 +143,7 @@ typedef struct __pop3aggr { HashList *MsgNumbers; HashPos *Pos; FetchItem *CurrMsg; -} pop3aggr; +}; void DeletePOP3Aggregator(void *vptr) { @@ -142,19 +166,6 @@ 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; @@ -178,11 +189,6 @@ eNextState FailAggregationRun(AsyncIO *IO) 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(); @@ -193,10 +199,11 @@ eNextState POP3C_ReadGreeting(pop3aggr *RecvMsg) 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)); @@ -217,7 +224,7 @@ eNextState POP3C_SendPassword(pop3aggr *RecvMsg) StrBufPrintf(RecvMsg->IO.SendBuf.Buf, "PASS %s\r\n", ChrPtr(RecvMsg->pop3pass)); syslog(LOG_DEBUG, "\n"); -// POP3C_DBG_SEND(); +// POP3C_DBG_SEND(); No, we won't write the passvoid to syslog... return eReadMessage; } @@ -241,7 +248,7 @@ eNextState POP3C_GetListCommandState(pop3aggr *RecvMsg) POP3C_DBG_READ(); if (!POP3C_OK) return eTerminateConnection; RecvMsg->MsgNumbers = NewHash(1, NULL); - RecvMsg->State++; + RecvMsg->State++; return eReadMore; } @@ -255,7 +262,7 @@ eNextState POP3C_GetListOneLine(pop3aggr *RecvMsg) 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) @@ -280,14 +287,14 @@ eNextState POP3C_GetListOneLine(pop3aggr *RecvMsg) } #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 */ @@ -302,29 +309,36 @@ eNextState POP3_FetchNetworkUsetableEntry(AsyncIO *IO) 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; } @@ -333,11 +347,13 @@ eNextState POP3_FetchNetworkUsetableEntry(AsyncIO *IO) 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); @@ -353,13 +369,17 @@ eNextState POP3C_GetOneMessagID(pop3aggr *RecvMsg) #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(); @@ -370,7 +390,8 @@ eNextState POP3C_GetOneMessagID(pop3aggr *RecvMsg) 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 */ } @@ -380,19 +401,23 @@ eNextState POP3C_GetOneMessageIDState(pop3aggr *RecvMsg) #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); @@ -408,13 +433,18 @@ eNextState POP3C_SendGetOneMsg(pop3aggr *RecvMsg) 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(); @@ -431,14 +461,14 @@ eNextState POP3C_ReadMessageBodyFollowing(pop3aggr *RecvMsg) { 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) @@ -446,16 +476,18 @@ 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); @@ -466,13 +498,16 @@ eNextState POP3C_SaveMsg(AsyncIO *IO) 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); @@ -482,7 +517,8 @@ eNextState POP3C_SaveMsg(AsyncIO *IO) 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); } @@ -612,7 +648,7 @@ void POP3SetTimeout(eNextState NextTCPState, pop3aggr *pMsg) Timeout = POP3_C_ReadTimeouts[pMsg->State]; /* if (pMsg->State == eDATATerminateBody) { - / * + / * * some mailservers take a nap before accepting the message * content inspection and such. * / @@ -699,19 +735,20 @@ eNextState POP3_C_Shutdown(AsyncIO *IO) 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: @@ -723,10 +760,10 @@ eReadState POP3_C_ReadServerStatus(AsyncIO *IO) 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: @@ -780,21 +817,23 @@ eNextState pop3_get_one_host_ip_done(AsyncIO *IO) 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); } @@ -805,28 +844,28 @@ eNextState pop3_get_one_host_ip_done(AsyncIO *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; @@ -886,9 +925,9 @@ void pop3client_scan_room(struct ctdlroom *qrbuf, void *data) 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); } @@ -900,18 +939,19 @@ void pop3client_scan_room(struct ctdlroom *qrbuf, void *data) 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) @@ -927,7 +967,7 @@ void pop3client_scan_room(struct ctdlroom *qrbuf, void *data) close(fd); if (server_shutting_down) return; - + CfgPtr = NULL; CfgType = NewStrBuf(); Line = NewStrBufPlain(NULL, StrLength(CfgData)); @@ -947,42 +987,58 @@ void pop3client_scan_room(struct ctdlroom *qrbuf, void *data) /* 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 */ @@ -991,19 +1047,25 @@ void pop3client_scan_room(struct ctdlroom *qrbuf, void *data) 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); @@ -1013,7 +1075,11 @@ void pop3client_scan_room(struct ctdlroom *qrbuf, void *data) #endif pthread_mutex_lock(&POP3QueueMutex); - Put(POP3FetchUrls, SKEY(cptr->Url), cptr, DeletePOP3Aggregator); + Put(POP3FetchUrls, + SKEY(cptr->Url), + cptr, + DeletePOP3Aggregator); + pthread_mutex_unlock(&POP3QueueMutex); } @@ -1054,8 +1120,8 @@ void pop3client_scan(void) { } /* - * 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. */ @@ -1067,19 +1133,19 @@ void pop3client_scan(void) { 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); @@ -1111,9 +1177,9 @@ CTDL_MODULE_INIT(pop3client) 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"; } diff --git a/citadel/modules/rssclient/rss_atom_parser.c b/citadel/modules/rssclient/rss_atom_parser.c index dd92e2d78..16899b88d 100644 --- a/citadel/modules/rssclient/rss_atom_parser.c +++ b/citadel/modules/rssclient/rss_atom_parser.c @@ -119,44 +119,62 @@ void flush_rss_item(rss_item *ri) } -/******************************************************************************* - * 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; @@ -186,20 +204,28 @@ void ATOM_item_link_start (StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, con 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.. */ @@ -210,7 +236,7 @@ void ATOM_item_link_start (StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, con { } 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... */ @@ -228,7 +254,10 @@ void ATOM_item_link_start (StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, con -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); @@ -236,14 +265,18 @@ void ATOMRSS_item_title_end(StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, co } } -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); @@ -251,14 +284,20 @@ void ATOM_item_id_end(StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, const ch } -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); @@ -266,7 +305,10 @@ void RSS_item_relink_end(StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, const } } -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); @@ -274,26 +316,42 @@ void RSSATOM_item_title_end (StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, c } } -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); @@ -301,33 +359,48 @@ void ATOM_item_summary_end (StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, co } } -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); @@ -335,7 +408,10 @@ void ATOM_item_updated_end (StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, co } } -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); @@ -344,7 +420,10 @@ void RSS_item_pubdate_end (StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, con } -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); @@ -354,7 +433,10 @@ void RSS_item_date_end (StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, const -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); @@ -363,7 +445,10 @@ void RSS_item_author_end(StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, const } -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); @@ -371,7 +456,10 @@ void ATOM_item_name_end(StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, const } } -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); @@ -379,9 +467,12 @@ void ATOM_item_email_end(StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, const } } -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); @@ -390,7 +481,10 @@ void RSS_item_creator_end(StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, cons } -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); @@ -398,33 +492,48 @@ void ATOM_item_uri_end(StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, const c } } -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) { } @@ -433,17 +542,17 @@ void RSSATOM_item_ignore(StrBuf *CData, rss_item *ri, rss_aggregator *Cfg, const /* * 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; @@ -451,9 +560,9 @@ void rss_xml_chardata(void *data, const XML_Char *s, int len) } -/******************************************************************************* - * RSS parser logic * - *******************************************************************************/ +/****************************************************************************** + * RSS parser logic * + ******************************************************************************/ extern pthread_mutex_t RSSQueueMutex; @@ -673,7 +782,10 @@ void rss_xml_start(void *data, const char *supplied_el, const char **attr) 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; @@ -682,15 +794,17 @@ void rss_xml_start(void *data, const char *supplied_el, const char **attr) 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; } @@ -702,7 +816,7 @@ void rss_xml_start(void *data, const char *supplied_el, const char **attr) { 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); @@ -715,16 +829,25 @@ void rss_xml_start(void *data, const char *supplied_el, const char **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 } @@ -746,15 +869,18 @@ void rss_xml_end(void *data, const char *supplied_el) 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; @@ -767,7 +893,7 @@ void rss_xml_end(void *data, const char *supplied_el) { 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); @@ -783,13 +909,21 @@ void rss_xml_end(void *data, const char *supplied_el) 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); } @@ -842,7 +976,7 @@ eNextState RSSAggregator_ParseReply(AsyncIO *IO) pche = strchr(ptr, '"'); if (pche != NULL) StrBufCutAt(RSSAggr->Key, -1, pche); - else + else ptr = "UTF-8"; } else @@ -874,9 +1008,8 @@ eNextState RSSAggregator_ParseReply(AsyncIO *IO) 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); @@ -888,19 +1021,26 @@ eNextState RSSAggregator_ParseReply(AsyncIO *IO) 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)); @@ -908,7 +1048,11 @@ void AddRSSStartHandler(rss_handler_func Handler, int Flags, const char *key, lo 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)); @@ -919,8 +1063,8 @@ void AddRSSEndHandler(rss_handler_func Handler, int Flags, const char *key, long void rss_parser_cleanup(void) { - DeleteHash(&StartHandlers); - DeleteHash(&EndHandlers); + DeleteHash(&StartHandlers); + DeleteHash(&EndHandlers); DeleteHash(&KnownNameSpaces); } @@ -943,8 +1087,8 @@ CTDL_MODULE_INIT(rssparser) 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")); @@ -1011,7 +1155,7 @@ CTDL_MODULE_INIT(rssparser) /* 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"; } diff --git a/citadel/modules/rssclient/serv_rssclient.c b/citadel/modules/rssclient/serv_rssclient.c index 9f27b307f..c6f065fa9 100644 --- a/citadel/modules/rssclient/serv_rssclient.c +++ b/citadel/modules/rssclient/serv_rssclient.c @@ -10,12 +10,12 @@ * * 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 @@ -27,9 +27,9 @@ # include #else # if HAVE_SYS_TIME_H -# include +#include # else -# include +#include # endif #endif @@ -140,7 +140,6 @@ void UnlinkRSSAggregator(rss_aggregator *Cfg) last_run = time(NULL); } - void DeleteRssCfg(void *vptr) { rss_aggregator *RSSAggr = (rss_aggregator *)vptr; @@ -180,6 +179,7 @@ eNextState RSSAggregator_Terminate(AsyncIO *IO) UnlinkRSSAggregator(RSSAggr); return eAbort; } + eNextState RSSAggregator_ShutdownAbort(AsyncIO *IO) { const char *pUrl; @@ -208,7 +208,8 @@ eNextState RSSSaveMessage(AsyncIO *IO) 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); @@ -271,8 +272,6 @@ eNextState RSS_FetchNetworkUsetableEntry(AsyncIO *IO) } } - - /* * Begin a feed parse */ @@ -324,7 +323,7 @@ void rssclient_scan_room(struct ctdlroom *qrbuf, void *data) 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; @@ -378,7 +377,7 @@ void rssclient_scan_room(struct ctdlroom *qrbuf, void *data) close(fd); FreeStrBuf(&CfgData); syslog(LOG_DEBUG, "ERROR: reading config '%s' - %s
\n", - filename, strerror(errno)); + filename, strerror(errno)); return; } close(fd); @@ -391,72 +390,89 @@ void rssclient_scan_room(struct ctdlroom *qrbuf, void *data) 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); } @@ -472,7 +488,7 @@ void rssclient_scan(void) { static int doing_rssclient = 0; rss_aggregator *rptr = NULL; void *vrptr = NULL; - HashPos *it; + HashPos *it; long len; const char *Key; @@ -483,7 +499,7 @@ void rssclient_scan(void) { /* * 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. */ diff --git a/citadel/modules/smtp/serv_smtpeventclient.c b/citadel/modules/smtp/serv_smtpeventclient.c index 664dec247..e4b79821f 100644 --- a/citadel/modules/smtp/serv_smtpeventclient.c +++ b/citadel/modules/smtp/serv_smtpeventclient.c @@ -186,9 +186,9 @@ eNextState FailOneAttempt(AsyncIO *IO) if (SendMsg->MyQEntry->Status == 2) return eAbort; - /* - * possible ways here: - * - connection timeout + /* + * possible ways here: + * - connection timeout * - dns lookup failed */ StopClientWatchers(IO); @@ -205,7 +205,9 @@ eNextState FailOneAttempt(AsyncIO *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); } } @@ -223,29 +225,30 @@ void SetConnectStatus(AsyncIO *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 = ""; 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); @@ -279,65 +282,73 @@ eNextState get_one_mx_host_ip_done(AsyncIO *IO) 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; @@ -362,13 +373,14 @@ eNextState smtp_resolve_mx_record_done(AsyncIO *IO) 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++) { @@ -380,7 +392,7 @@ eNextState smtp_resolve_mx_record_done(AsyncIO *IO) p->Port = DefaultMXPort; p->IPv6 = i == 1; p->Host = SendMsg->CurrMX->host; - + *pp = p; pp = &p->Next; } @@ -399,7 +411,7 @@ eNextState smtp_resolve_mx_record_done(AsyncIO *IO) p->Port = DefaultMXPort; p->IPv6 = i == 1; p->Host = SendMsg->node; - + *pp = p; pp = &p->Next; } @@ -416,14 +428,14 @@ eNextState resolve_mx_records(AsyncIO *IO) 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; } @@ -437,7 +449,7 @@ eNextState resolve_mx_records(AsyncIO *IO) * 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) { @@ -466,10 +478,11 @@ SmtpOutMsg *new_smtp_outmsg(OneQueItem *MyQItem, 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; @@ -485,7 +498,8 @@ void smtp_try_one_queue_entry(OneQueItem *MyQItem, 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, @@ -499,7 +513,9 @@ void smtp_try_one_queue_entry(OneQueItem *MyQItem, 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); } @@ -539,16 +555,18 @@ void SMTPSetTimeout(eNextState NextTCPState, SmtpOutMsg *pMsg) 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; } @@ -630,24 +648,26 @@ eNextState SMTP_C_Shutdown(AsyncIO *IO) 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... */ @@ -656,11 +676,11 @@ eReadState SMTP_C_ReadServerStatus(AsyncIO *IO) continue; if (ChrPtr(IO->IOBuf)[3] == '-') Finished = eBufferNotEmpty; - else + else return Finished; break; case eReadFail: /// WHUT? - ///todo: shut down! + ///todo: shut down! break; } } diff --git a/citadel/modules/smtp/serv_smtpqueue.c b/citadel/modules/smtp/serv_smtpqueue.c index 3057ae6ca..3e20779a1 100644 --- a/citadel/modules/smtp/serv_smtpqueue.c +++ b/citadel/modules/smtp/serv_smtpqueue.c @@ -97,11 +97,12 @@ HashList *QItemHandlers = NULL; 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); @@ -140,13 +141,13 @@ void RemoveQItem(OneQueItem *MyQItem) 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); @@ -174,8 +175,8 @@ void HFreeQueItem(void *Item) 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) */ @@ -192,14 +193,14 @@ int CountActiveQueueEntries(OneQueItem *MyQItem) 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); @@ -240,7 +241,7 @@ OneQueItem *DeserializeQueueItem(StrBuf *RawQItem, long QueMsgID) FreeStrBuf(&Token); pthread_mutex_lock(&ActiveQItemsLock); - if (GetHash(ActiveQItems, + if (GetHash(ActiveQItems, LKEY(Item->MessageID), &v)) { @@ -251,7 +252,7 @@ OneQueItem *DeserializeQueueItem(StrBuf *RawQItem, long QueMsgID) } else { /* mark our claim on this. */ - Put(ActiveQItems, + Put(ActiveQItems, LKEY(Item->MessageID), Item, HFreeQueItem); @@ -271,8 +272,7 @@ StrBuf *SerializeQueueItem(OneQueItem *MyQItem) 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); @@ -296,16 +296,21 @@ StrBuf *SerializeQueueItem(OneQueItem *MyQItem) 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); @@ -316,7 +321,7 @@ StrBuf *SerializeQueueItem(OneQueItem *MyQItem) StrBufAppendBuf(QMessage, ThisItem->StatusMessage, 0); } DeleteHashPos(&It); - StrBufAppendBufPlain(QMessage, HKEY("\n"), 0); + StrBufAppendBufPlain(QMessage, HKEY("\n"), 0); return QMessage; } @@ -333,7 +338,10 @@ void NewMailQEntry(OneQueItem *Item) 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) @@ -360,7 +368,7 @@ void QItem_Handle_Recipient(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, '|'); @@ -378,7 +386,8 @@ void QItem_Handle_retry(OneQueItem *Item, StrBuf *Line, const char **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, '|'); } @@ -398,12 +407,20 @@ void QItem_Handle_Attempted(OneQueItem *Item, StrBuf *Line, const char **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; } @@ -418,17 +435,21 @@ StrBuf *smtp_load_msg(OneQueItem *MyQItem, int n) { 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); } @@ -442,16 +463,16 @@ StrBuf *smtp_load_msg(OneQueItem *MyQItem, int n) * 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; @@ -475,12 +496,14 @@ void smtpq_do_bounce(OneQueItem *MyQItem, StrBuf *OMsgTxt) { 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); @@ -498,13 +521,18 @@ void smtpq_do_bounce(OneQueItem *MyQItem, StrBuf *OMsgTxt) } 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"); @@ -525,29 +553,33 @@ void smtpq_do_bounce(OneQueItem *MyQItem, StrBuf *OMsgTxt) 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); @@ -557,34 +589,36 @@ void smtpq_do_bounce(OneQueItem *MyQItem, StrBuf *OMsgTxt) 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); @@ -605,15 +639,6 @@ void smtpq_do_bounce(OneQueItem *MyQItem, StrBuf *OMsgTxt) syslog(LOG_DEBUG, "Done processing bounces\n"); } - - -/* -{ - - if (threadding) - n_smarthosts = get_hosts(char *mxbuf, char *rectype); -} -*/ /* * smtp_do_procmsg() * @@ -621,7 +646,7 @@ void smtpq_do_bounce(OneQueItem *MyQItem, StrBuf *OMsgTxt) */ void smtp_do_procmsg(long msgnum, void *userdata) { struct CtdlMessage *msg = NULL; - char *instr = NULL; + char *instr = NULL; StrBuf *PlainQItem; OneQueItem *MyQItem; char *pch; @@ -633,13 +658,14 @@ void smtp_do_procmsg(long msgnum, void *userdata) { 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; } @@ -659,21 +685,30 @@ void smtp_do_procmsg(long msgnum, void *userdata) { 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? @@ -689,8 +724,12 @@ void smtp_do_procmsg(long msgnum, void *userdata) { 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); @@ -708,15 +747,19 @@ void smtp_do_procmsg(long msgnum, void *userdata) { 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); @@ -731,12 +774,17 @@ void smtp_do_procmsg(long msgnum, void *userdata) { 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); @@ -748,8 +796,8 @@ void smtp_do_procmsg(long msgnum, void *userdata) { 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); @@ -762,50 +810,67 @@ void smtp_do_procmsg(long msgnum, void *userdata) { 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); + } } } @@ -826,14 +891,15 @@ void smtp_do_procmsg(long msgnum, void *userdata) { /* * 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); @@ -843,9 +909,18 @@ void smtp_do_queue(void) { 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; } @@ -935,7 +1010,7 @@ CTDL_MODULE_INIT(smtp_queu) 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); @@ -943,7 +1018,7 @@ CTDL_MODULE_INIT(smtp_queu) CtdlRegisterProtoHook(cmd_smtp, "SMTP", "SMTP utility commands"); CtdlRegisterSessionHook(smtp_do_queue, EVT_TIMER); } - + /* return our Subversion id for the Log */ return "smtpeventclient"; } diff --git a/citadel/modules/smtp/smtp_clienthandlers.c b/citadel/modules/smtp/smtp_clienthandlers.c index 677d9afa5..b41ab4f9c 100644 --- a/citadel/modules/smtp/smtp_clienthandlers.c +++ b/citadel/modules/smtp/smtp_clienthandlers.c @@ -16,11 +16,8 @@ * 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 @@ -91,24 +88,28 @@ #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)) /*****************************************************************************/ @@ -121,9 +122,9 @@ eNextState SMTPC_read_greeting(SmtpOutMsg *SendMsg) 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; @@ -150,7 +151,7 @@ eNextState SMTPC_read_EHLO_reply(SmtpOutMsg *SendMsg) if (SMTP_IS_STATE('2')) { SendMsg->State ++; - if ((SendMsg->pCurrRelay == NULL) || + if ((SendMsg->pCurrRelay == NULL) || (SendMsg->pCurrRelay->User == NULL)) SendMsg->State ++; /* Skip auth... */ } @@ -173,15 +174,17 @@ eNextState SMTPC_read_HELO_reply(SmtpOutMsg *SendMsg) 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; } @@ -191,20 +194,22 @@ eNextState SMTPC_send_auth(SmtpOutMsg *SendMsg) 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; @@ -214,13 +219,13 @@ eNextState SMTPC_read_auth_reply(SmtpOutMsg *SendMsg) { 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; @@ -231,7 +236,7 @@ eNextState SMTPC_send_FROM(SmtpOutMsg *SendMsg) 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(); @@ -246,7 +251,7 @@ eNextState SMTPC_read_FROM_reply(SmtpOutMsg *SendMsg) if (!SMTP_IS_STATE('2')) { if (SMTP_IS_STATE('4')) SMTP_VERROR(4); - else + else SMTP_VERROR(5); } return eSendReply; @@ -258,8 +263,8 @@ eNextState SMTPC_send_RCPT(SmtpOutMsg *SendMsg) 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(); @@ -272,9 +277,9 @@ eNextState SMTPC_read_RCPT_reply(SmtpOutMsg *SendMsg) 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; @@ -297,9 +302,9 @@ eNextState SMTPC_read_DATAcmd_reply(SmtpOutMsg *SendMsg) 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; @@ -341,12 +346,12 @@ eNextState SMTPC_read_data_body_reply(SmtpOutMsg *SendMsg) 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; @@ -368,8 +373,13 @@ eNextState SMTPC_read_QUIT_reply(SmtpOutMsg *SendMsg) 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; } @@ -447,8 +457,8 @@ const ConstStr ReadErrors[eMaxSMTPC + 1] = { {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. */ }; @@ -467,70 +477,93 @@ int smtp_resolve_recipients(SmtpOutMsg *SendMsg) 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; } diff --git a/citadel/modules/smtp/smtp_clienthandlers.h b/citadel/modules/smtp/smtp_clienthandlers.h index ba51001af..02b84e75f 100644 --- a/citadel/modules/smtp/smtp_clienthandlers.h +++ b/citadel/modules/smtp/smtp_clienthandlers.h @@ -1,5 +1,24 @@ +/* + * + * 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, @@ -60,7 +79,7 @@ const double SMTP_C_ConnTimeout; #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. */ @@ -68,7 +87,21 @@ int smtp_resolve_recipients(SmtpOutMsg *SendMsg); #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) diff --git a/citadel/modules/smtp/smtp_util.c b/citadel/modules/smtp/smtp_util.c index 1db154635..adb6fa86d 100644 --- a/citadel/modules/smtp/smtp_util.c +++ b/citadel/modules/smtp/smtp_util.c @@ -103,7 +103,7 @@ const char *smtp_get_Recipients(void) * 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; @@ -128,7 +128,13 @@ void smtp_do_bounce(char *instr, StrBuf *OMsgTxt) 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 */ @@ -152,34 +158,50 @@ void smtp_do_bounce(char *instr, StrBuf *OMsgTxt) 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. @@ -226,17 +248,31 @@ void smtp_do_bounce(char *instr, StrBuf *OMsgTxt) /* 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); } @@ -246,7 +282,7 @@ void smtp_do_bounce(char *instr, StrBuf *OMsgTxt) } /* 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) @@ -257,12 +293,14 @@ void smtp_do_bounce(char *instr, StrBuf *OMsgTxt) 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); diff --git a/citadel/modules/smtp/smtpqueue.h b/citadel/modules/smtp/smtpqueue.h index 2b252899a..12b2ad387 100644 --- a/citadel/modules/smtp/smtpqueue.h +++ b/citadel/modules/smtp/smtpqueue.h @@ -1,3 +1,22 @@ +/* + * + * 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 */ /*****************************************************************************/ @@ -21,7 +40,7 @@ typedef struct _mailq_entry { * 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. */ @@ -35,7 +54,10 @@ typedef struct queueitem { 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; @@ -43,11 +65,11 @@ typedef struct queueitem { 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); -- 2.30.2