X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fmodules%2Fpop3client%2Fserv_pop3client.c;h=bf235b2110899982ce502167499cd6d08f16a1e5;hb=1493fd8ff0de73d30336607b43b1c8113ffcffa2;hp=ec744849f8af80e4d6aa4ff34015027349702995;hpb=ff7f36e7a7ad88d75d1201a78cb60dc6b2cce299;p=citadel.git diff --git a/citadel/modules/pop3client/serv_pop3client.c b/citadel/modules/pop3client/serv_pop3client.c index ec744849f..bf235b211 100644 --- a/citadel/modules/pop3client/serv_pop3client.c +++ b/citadel/modules/pop3client/serv_pop3client.c @@ -63,42 +63,42 @@ int POP3ClientDebugEnabled = 0; #define EVP3C_syslog(LEVEL, FORMAT, ...) \ DBGLOG(LEVEL) syslog(LEVEL, \ - "IO[%ld]CC[%d][%ld]POP3: " FORMAT, \ - IO->ID, CCID, N, __VA_ARGS__) + "%s[%ld]CC[%d][%ld]POP3: " FORMAT, \ + IOSTR, IO->ID, CCID, N, __VA_ARGS__) #define EVP3CM_syslog(LEVEL, FORMAT) \ DBGLOG(LEVEL) syslog(LEVEL, \ - "IO[%ld]CC[%d][%ld]POP3: " FORMAT, \ - IO->ID, CCID, N) + "%s[%ld]CC[%d][%ld]POP3: " FORMAT, \ + IOSTR, IO->ID, CCID, N) #define EVP3CQ_syslog(LEVEL, FORMAT, ...) \ DBGLOG(LEVEL) syslog(LEVEL, \ - "P3Q:" FORMAT, \ - __VA_ARGS__) + "%s P3Q:" FORMAT, \ + IOSTR, __VA_ARGS__) #define EVP3CQM_syslog(LEVEL, FORMAT) \ DBGLOG(LEVEL) syslog(LEVEL, \ - "P3Q" FORMAT \ - ) + "%s P3Q" FORMAT, \ + IOSTR) #define EVP3CCS_syslog(LEVEL, FORMAT, ...) \ - DBGLOG(LEVEL) syslog(LEVEL, "IO[%ld][%ld]POP3: " FORMAT, \ - IO->ID, N, __VA_ARGS__) + DBGLOG(LEVEL) syslog(LEVEL, "%s[%ld][%ld]POP3: " FORMAT, \ + IOSTR, IO->ID, N, __VA_ARGS__) #define EVP3CCSM_syslog(LEVEL, FORMAT) \ - DBGLOG(LEVEL) syslog(LEVEL, "IO[%ld][%ld]POP3: " FORMAT, \ - IO->ID, N) + DBGLOG(LEVEL) syslog(LEVEL, "%s[%ld][%ld]POP3: " FORMAT, \ + IOSTR, IO->ID, N) #define POP3C_DBG_SEND() \ EVP3C_syslog(LOG_DEBUG, \ - "IO[%ld]CC[%d][%ld]POP3: > %s\n", \ - IO->ID, CCID, N, \ + "%s[%ld]CC[%d][%ld]POP3: > %s\n", \ + IOSTR, IO->ID, CCID, N, \ ChrPtr(RecvMsg->IO.SendBuf.Buf)) #define POP3C_DBG_READ() \ EVP3C_syslog(LOG_DEBUG, \ - "IO[%ld]CC[%d][%ld]POP3: < %s\n", \ - IO->ID, CCID, N, \ + "%s[%ld]CC[%d][%ld]POP3: < %s\n", \ + IOSTR, IO->ID, CCID, N, \ ChrPtr(RecvMsg->IO.IOBuf)) @@ -158,6 +158,44 @@ void HfreeFetchItem(void *vItem) free(Item); } + + +typedef enum _POP3State { + eCreated, + eGreeting, + eUser, + ePassword, + eListing, + eUseTable, + eGetMsgID, + eGetMsg, + eStoreMsg, + eDelete, + eQuit +} POP3State; + +ConstStr POP3States[] = { + {HKEY("Aggregator created")}, + {HKEY("Reading Greeting")}, + {HKEY("Sending User")}, + {HKEY("Sending Password")}, + {HKEY("Listing")}, + {HKEY("Fetching Usetable")}, + {HKEY("Get MSG ID")}, + {HKEY("Get Message")}, + {HKEY("Store Msg")}, + {HKEY("Delete Upstream")}, + {HKEY("Quit")} +}; + +static void SetPOP3State(AsyncIO *IO, POP3State State) +{ + CitContext* CCC = IO->CitContext; + if (CCC != NULL) + memcpy(CCC->cs_clientname, POP3States[State].Key, POP3States[State].len + 1); +} + + struct pop3aggr { AsyncIO IO; @@ -240,6 +278,7 @@ eNextState FailAggregationRun(AsyncIO *IO) eNextState POP3C_ReadGreeting(pop3aggr *RecvMsg) { AsyncIO *IO = &RecvMsg->IO; + SetPOP3State(IO, eGreeting); POP3C_DBG_READ(); /* Read the server greeting */ if (!POP3C_OK) return eTerminateConnection; @@ -249,6 +288,7 @@ eNextState POP3C_ReadGreeting(pop3aggr *RecvMsg) eNextState POP3C_SendUser(pop3aggr *RecvMsg) { AsyncIO *IO = &RecvMsg->IO; + SetPOP3State(IO, eUser); /* 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 @@ -272,6 +312,7 @@ eNextState POP3C_GetUserState(pop3aggr *RecvMsg) eNextState POP3C_SendPassword(pop3aggr *RecvMsg) { AsyncIO *IO = &RecvMsg->IO; + SetPOP3State(IO, ePassword); /* Password */ StrBufPrintf(RecvMsg->IO.SendBuf.Buf, "PASS %s\r\n", ChrPtr(RecvMsg->pop3pass)); @@ -291,6 +332,8 @@ eNextState POP3C_GetPassState(pop3aggr *RecvMsg) eNextState POP3C_SendListCommand(pop3aggr *RecvMsg) { AsyncIO *IO = &RecvMsg->IO; + SetPOP3State(IO, eListing); + /* Get the list of messages */ StrBufPlain(RecvMsg->IO.SendBuf.Buf, HKEY("LIST\r\n")); POP3C_DBG_SEND(); @@ -332,6 +375,17 @@ eNextState POP3C_GetListOneLine(pop3aggr *RecvMsg) return eSendReply; } + + /* + * work around buggy pop3 servers which send + * empty lines in their listings. + */ + if ((StrLength(RecvMsg->IO.IOBuf) == 0) || + !isdigit(ChrPtr(RecvMsg->IO.IOBuf)[0])) + { + return eReadMore; + } + OneMsg = (FetchItem*) malloc(sizeof(FetchItem)); memset(OneMsg, 0, sizeof(FetchItem)); OneMsg->MSGID = atol(ChrPtr(RecvMsg->IO.IOBuf)); @@ -362,9 +416,10 @@ eNextState POP3_FetchNetworkUsetableEntry(AsyncIO *IO) long HKLen; const char *HKey; void *vData; - struct cdbdata *cdbut; pop3aggr *RecvMsg = (pop3aggr *) IO->Data; + SetPOP3State(IO, eUseTable); + if((RecvMsg->Pos != NULL) && GetNextHashPos(RecvMsg->MsgNumbers, RecvMsg->Pos, @@ -372,32 +427,19 @@ eNextState POP3_FetchNetworkUsetableEntry(AsyncIO *IO) &HKey, &vData)) { - struct UseTable ut; if (server_shutting_down) return eAbort; - RecvMsg->CurrMsg = (FetchItem*) vData; - EVP3CCS_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, - 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) { + if (CheckIfAlreadySeen("POP3 Item Seen", + RecvMsg->CurrMsg->MsgUID, + IO->Now, + IO->Now, //// todo + eCheckUpdate, + IO->ID, CCID) + != 0) + { /* Item has already been seen */ - EVP3CCSM_syslog(LOG_DEBUG, "YES\n"); - cdb_free(cdbut); - - /* rewrite the record anyway, to update the timestamp */ - cdb_store(CDB_USETABLE, - SKEY(RecvMsg->CurrMsg->MsgUID), - &ut, sizeof(struct UseTable) ); - RecvMsg->CurrMsg->NeedFetch = 0; ////TODO0; + RecvMsg->CurrMsg->NeedFetch = 0; } else { @@ -412,8 +454,7 @@ eNextState POP3_FetchNetworkUsetableEntry(AsyncIO *IO) /* ok, now we know them all, * continue with reading the actual messages. */ DeleteHashPos(&RecvMsg->Pos); - StopDBWatchers(IO); - return QueueEventContext(IO, POP3_C_ReAttachToFetchMessages); + return DBQueueEventContext(IO, POP3_C_ReAttachToFetchMessages); } } @@ -424,6 +465,7 @@ eNextState POP3C_GetOneMessagID(pop3aggr *RecvMsg) const char *HKey; void *vData; + SetPOP3State(IO, eGetMsgID); #if 0 int rc; rc = TestValidateHash(RecvMsg->MsgNumbers); @@ -449,8 +491,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 EventQueueDBOperation(&RecvMsg->IO, + POP3_FetchNetworkUsetableEntry); } return eReadMore; /* TODO */ } @@ -493,6 +535,8 @@ eNextState POP3C_SendGetOneMsg(pop3aggr *RecvMsg) const char *HKey; void *vData; + SetPOP3State(IO, eGetMsg); + RecvMsg->CurrMsg = NULL; while ((RecvMsg->Pos != NULL) && GetNextHashPos(RecvMsg->MsgNumbers, @@ -537,23 +581,20 @@ eNextState POP3C_ReadMessageBodyFollowing(pop3aggr *RecvMsg) eNextState POP3C_StoreMsgRead(AsyncIO *IO) { pop3aggr *RecvMsg = (pop3aggr *) IO->Data; - struct UseTable ut; + + SetPOP3State(IO, eStoreMsg); EVP3CCS_syslog(LOG_DEBUG, "MARKING: %s as seen: ", ChrPtr(RecvMsg->CurrMsg->MsgUID)); - - 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), - StrLength(RecvMsg->CurrMsg->MsgUID), - &ut, - sizeof(struct UseTable) ); - StopDBWatchers(IO); - return QueueEventContext(&RecvMsg->IO, POP3_C_ReAttachToFetchMessages); + CheckIfAlreadySeen("POP3 Item Seen", + RecvMsg->CurrMsg->MsgUID, + IO->Now, + IO->Now, //// todo + eWrite, + IO->ID, CCID); + + return DBQueueEventContext(&RecvMsg->IO, POP3_C_ReAttachToFetchMessages); } eNextState POP3C_SaveMsg(AsyncIO *IO) { @@ -572,7 +613,7 @@ eNextState POP3C_SaveMsg(AsyncIO *IO) * so we don't fetch this message again */ } - CtdlFreeMessage(RecvMsg->CurrMsg->Msg); + CM_Free(RecvMsg->CurrMsg->Msg); RecvMsg->count ++; return NextDBOperation(&RecvMsg->IO, POP3C_StoreMsgRead); @@ -584,13 +625,15 @@ eNextState POP3C_ReadMessageBody(pop3aggr *RecvMsg) EVP3CM_syslog(LOG_DEBUG, "Converting message..."); RecvMsg->CurrMsg->Msg = convert_internet_message_buf(&RecvMsg->IO.ReadMsg->MsgBuf); - StopClientWatchers(IO, 0); - return QueueDBOperation(&RecvMsg->IO, POP3C_SaveMsg); + return EventQueueDBOperation(&RecvMsg->IO, POP3C_SaveMsg); } eNextState POP3C_SendDelete(pop3aggr *RecvMsg) { AsyncIO *IO = &RecvMsg->IO; + + SetPOP3State(IO, eDelete); + if (!RecvMsg->keep) { StrBufPrintf(RecvMsg->IO.SendBuf.Buf, "DELE %ld\r\n", RecvMsg->CurrMsg->MSGID); @@ -613,6 +656,8 @@ eNextState POP3C_ReadDeleteState(pop3aggr *RecvMsg) eNextState POP3C_SendQuit(pop3aggr *RecvMsg) { AsyncIO *IO = &RecvMsg->IO; + SetPOP3State(IO, eQuit); + /* Log out */ StrBufPlain(RecvMsg->IO.SendBuf.Buf, HKEY("QUIT\r\n3)")); @@ -1083,6 +1128,7 @@ void pop3client_scan_room(struct ctdlroom *qrbuf, void *data, OneRoomNetCfg *One DeletePOP3Aggregator); pthread_mutex_unlock(&POP3QueueMutex); + pLine = pLine->next; } }