/*
* Consolidate mail from remote POP3 accounts.
*
- * Copyright (c) 2007-2012 by the citadel.org team
+ * Copyright (c) 2007-2011 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 version 3.
+ * modify it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdlib.h>
#include "citadel_dirs.h"
#include "event_client.h"
+
#define POP3C_OK (strncasecmp(ChrPtr(RecvMsg->IO.IOBuf), "+OK", 3) == 0)
+int Pop3ClientID = 0;
+int POP3ClientDebugEnabled = 0;
+
+#define N ((pop3aggr*)IO->Data)->n
+
+#define DBGLOG(LEVEL) if ((LEVEL != LOG_DEBUG) || (POP3ClientDebugEnabled != 0))
+
+#define EVP3C_syslog(LEVEL, FORMAT, ...) \
+ DBGLOG(LEVEL) syslog(LEVEL, \
+ "IO[%ld]CC[%d][%ld]" FORMAT, \
+ IO->ID, CCID, N, __VA_ARGS__)
+
+#define EVP3CM_syslog(LEVEL, FORMAT) \
+ DBGLOG(LEVEL) syslog(LEVEL, \
+ "IO[%ld]CC[%d][%ld]" FORMAT, \
+ IO->ID, CCID, N)
-#define POP3C_DBG_SEND() \
- syslog(LOG_DEBUG, \
- "POP3 client[%ld]: > %s\n", \
- RecvMsg->n, ChrPtr(RecvMsg->IO.SendBuf.Buf))
+#define EVP3CCS_syslog(LEVEL, FORMAT, ...) \
+ DBGLOG(LEVEL) syslog(LEVEL, "IO[%ld][%ld]" FORMAT, \
+ IO->ID, N, __VA_ARGS__)
+
+#define EVP3CCSM_syslog(LEVEL, FORMAT) \
+ DBGLOG(LEVEL) syslog(LEVEL, "IO[%ld][%ld]" FORMAT, \
+ IO->ID, N)
+
+#define POP3C_DBG_SEND() \
+ EVP3C_syslog(LOG_DEBUG, \
+ "POP3: > %s\n", \
+ ChrPtr(RecvMsg->IO.SendBuf.Buf))
#define POP3C_DBG_READ() \
- syslog(LOG_DEBUG, \
- "POP3 client[%ld]: < %s\n", \
- RecvMsg->n, \
- ChrPtr(RecvMsg->IO.IOBuf))
+ EVP3C_syslog(LOG_DEBUG, \
+ "POP3: < %s\n", \
+ ChrPtr(RecvMsg->IO.IOBuf))
+
struct CitContext pop3_client_CC;
HashPos *It;
pop3aggr *cptr = (pop3aggr *)IO->Data;
- syslog(LOG_DEBUG, "Terminating Aggregator; bye.\n");
+ EVP3CM_syslog(LOG_DEBUG, "Terminating Aggregator; bye.\n");
It = GetNewHashPos(POP3FetchUrls, 0);
pthread_mutex_lock(&POP3QueueMutex);
eNextState POP3C_ReadGreeting(pop3aggr *RecvMsg)
{
+ AsyncIO *IO = &RecvMsg->IO;
POP3C_DBG_READ();
/* Read the server greeting */
if (!POP3C_OK) return eTerminateConnection;
eNextState POP3C_SendUser(pop3aggr *RecvMsg)
{
+ AsyncIO *IO = &RecvMsg->IO;
/* 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
eNextState POP3C_GetUserState(pop3aggr *RecvMsg)
{
+ AsyncIO *IO = &RecvMsg->IO;
POP3C_DBG_READ();
if (!POP3C_OK) return eTerminateConnection;
else return eSendReply;
eNextState POP3C_SendPassword(pop3aggr *RecvMsg)
{
+ AsyncIO *IO = &RecvMsg->IO;
/* Password */
StrBufPrintf(RecvMsg->IO.SendBuf.Buf,
"PASS %s\r\n", ChrPtr(RecvMsg->pop3pass));
- syslog(LOG_DEBUG, "<PASS <password>\n");
-// POP3C_DBG_SEND(); No, we won't write the password to syslog...
+ EVP3CM_syslog(LOG_DEBUG, "<PASS <password>\n");
+// POP3C_DBG_SEND(); No, we won't write the passvoid to syslog...
return eReadMessage;
}
eNextState POP3C_GetPassState(pop3aggr *RecvMsg)
{
+ AsyncIO *IO = &RecvMsg->IO;
POP3C_DBG_READ();
if (!POP3C_OK) return eTerminateConnection;
else return eSendReply;
eNextState POP3C_SendListCommand(pop3aggr *RecvMsg)
{
+ AsyncIO *IO = &RecvMsg->IO;
/* Get the list of messages */
StrBufPlain(RecvMsg->IO.SendBuf.Buf, HKEY("LIST\r\n"));
POP3C_DBG_SEND();
eNextState POP3C_GetListCommandState(pop3aggr *RecvMsg)
{
+ AsyncIO *IO = &RecvMsg->IO;
POP3C_DBG_READ();
if (!POP3C_OK) return eTerminateConnection;
RecvMsg->MsgNumbers = NewHash(1, NULL);
eNextState POP3C_GetListOneLine(pop3aggr *RecvMsg)
{
+ AsyncIO *IO = &RecvMsg->IO;
#if 0
int rc;
#endif
eNextState POP3C_GetOneMessagID(pop3aggr *RecvMsg)
{
+ AsyncIO *IO = &RecvMsg->IO;
long HKLen;
const char *HKey;
void *vData;
eNextState POP3C_GetOneMessageIDState(pop3aggr *RecvMsg)
{
+ AsyncIO *IO = &RecvMsg->IO;
#if 0
int rc;
rc = TestValidateHash(RecvMsg->MsgNumbers);
eNextState POP3C_SendGetOneMsg(pop3aggr *RecvMsg)
{
+ AsyncIO *IO = &RecvMsg->IO;
long HKLen;
const char *HKey;
void *vData;
eNextState POP3C_ReadMessageBodyFollowing(pop3aggr *RecvMsg)
{
+ AsyncIO *IO = &RecvMsg->IO;
POP3C_DBG_READ();
if (!POP3C_OK) return eTerminateConnection;
RecvMsg->IO.ReadMsg = NewAsyncMsg(HKEY("."),
eNextState POP3C_ReadMessageBody(pop3aggr *RecvMsg)
{
- syslog(LOG_DEBUG, "Converting message...\n");
+ AsyncIO *IO = &RecvMsg->IO;
+ EVP3CM_syslog(LOG_DEBUG, "Converting message...");
RecvMsg->CurrMsg->Msg =
convert_internet_message_buf(&RecvMsg->IO.ReadMsg->MsgBuf);
eNextState POP3C_SendDelete(pop3aggr *RecvMsg)
{
+ AsyncIO *IO = &RecvMsg->IO;
if (!RecvMsg->keep) {
StrBufPrintf(RecvMsg->IO.SendBuf.Buf,
"DELE %ld\r\n", RecvMsg->CurrMsg->MSGID);
}
eNextState POP3C_ReadDeleteState(pop3aggr *RecvMsg)
{
+ AsyncIO *IO = &RecvMsg->IO;
POP3C_DBG_READ();
RecvMsg->State = GetOneMessageIDState;
return eReadMessage;
eNextState POP3C_SendQuit(pop3aggr *RecvMsg)
{
+ AsyncIO *IO = &RecvMsg->IO;
/* Log out */
StrBufPlain(RecvMsg->IO.SendBuf.Buf,
HKEY("QUIT\r\n3)"));
eNextState POP3C_ReadQuitState(pop3aggr *RecvMsg)
{
+ AsyncIO *IO = &RecvMsg->IO;
POP3C_DBG_READ();
return eTerminateConnection;
}
void POP3SetTimeout(eNextState NextTCPState, pop3aggr *pMsg)
{
+ AsyncIO *IO = &pMsg->IO;
double Timeout = 0.0;
- syslog(LOG_DEBUG, "POP3: %s\n", __FUNCTION__);
+ EVP3C_syslog(LOG_DEBUG, "POP3: %s\n", __FUNCTION__);
switch (NextTCPState) {
case eSendFile:
}
-/*
- * 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)
{
/*****************************************************************************
* So we connect our Server IP here. *
- *****************************************************************************
- */
+ *****************************************************************************/
eNextState POP3_C_ReAttachToFetchMessages(AsyncIO *IO)
{
pop3aggr *cpptr = IO->Data;
int pop3_do_fetching(pop3aggr *cpptr)
{
- InitIOStruct(&cpptr->IO,
+ AsyncIO *IO = &cpptr->IO;
+
+ InitIOStruct(IO,
cpptr,
eReadMessage,
POP3_C_ReadServerStatus,
}
pthread_mutex_unlock(&RSSQueueMutex);
#endif
-
+ cptr->n = Pop3ClientID++;
pthread_mutex_lock(&POP3QueueMutex);
Put(POP3FetchUrls,
SKEY(cptr->Url),
* Run POP3 aggregation no more frequently than once every n seconds
*/
if ( (time(NULL) - last_run) < fastest_scan ) {
- syslog(LOG_DEBUG,
- "pop3client: polling interval not yet reached; last run was %ldm%lds ago",
- ((time(NULL) - last_run) / 60),
- ((time(NULL) - last_run) % 60)
- );
return;
}
* don't really require extremely fine granularity here, we'll do it
* with a static variable instead.
*/
- if (doing_pop3client) {
- syslog(LOG_DEBUG, "pop3client: concurrency check failed; another poll is already running");
- return;
- }
+ if (doing_pop3client) return;
doing_pop3client = 1;
syslog(LOG_DEBUG, "pop3client started");
DeleteHash(&POP3QueueRooms);
}
+
+
+void LogDebugEnablePOP3Client(void)
+{
+ POP3ClientDebugEnabled = 1;
+}
+
CTDL_MODULE_INIT(pop3client)
{
if (!threading)
POP3FetchUrls = NewHash(1, NULL);
CtdlRegisterSessionHook(pop3client_scan, EVT_TIMER);
CtdlRegisterEVCleanupHook(pop3_cleanup);
+ CtdlRegisterDebugFlagHook(HKEY("pop3client"), LogDebugEnablePOP3Client);
}
/* return our module id for the log */