POP3Client: use URL-Encoder that also encades the '@'
[citadel.git] / citadel / modules / pop3client / serv_pop3client.c
index 0a97df2cc971b402c431c4b6daf5a54dbe9ae3c6..cebd02c1f29dfed6df755562fd1686e0ac81ec2b 100644 (file)
 
 
 #define POP3C_OK (strncasecmp(ChrPtr(RecvMsg->IO.IOBuf), "+OK", 3) == 0)
+int Pop3ClientID = 0;
+int POP3ClientDebugEnabled = 0;
 
-#define POP3C_DBG_SEND()                                       \
-       syslog(LOG_DEBUG,                                       \
-              "POP3 client[%ld]: > %s\n",                      \
-              RecvMsg->n, ChrPtr(RecvMsg->IO.SendBuf.Buf))
+#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 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;
@@ -171,7 +194,7 @@ eNextState FinalizePOP3AggrRun(AsyncIO *IO)
        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);
@@ -191,6 +214,7 @@ eNextState FailAggregationRun(AsyncIO *IO)
 
 eNextState POP3C_ReadGreeting(pop3aggr *RecvMsg)
 {
+       AsyncIO *IO = &RecvMsg->IO;
        POP3C_DBG_READ();
        /* Read the server greeting */
        if (!POP3C_OK) return eTerminateConnection;
@@ -199,6 +223,7 @@ eNextState POP3C_ReadGreeting(pop3aggr *RecvMsg)
 
 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
@@ -213,6 +238,7 @@ eNextState POP3C_SendUser(pop3aggr *RecvMsg)
 
 eNextState POP3C_GetUserState(pop3aggr *RecvMsg)
 {
+       AsyncIO *IO = &RecvMsg->IO;
        POP3C_DBG_READ();
        if (!POP3C_OK) return eTerminateConnection;
        else return eSendReply;
@@ -220,16 +246,18 @@ eNextState POP3C_GetUserState(pop3aggr *RecvMsg)
 
 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");
+       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;
@@ -237,6 +265,7 @@ eNextState POP3C_GetPassState(pop3aggr *RecvMsg)
 
 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();
@@ -245,6 +274,7 @@ eNextState POP3C_SendListCommand(pop3aggr *RecvMsg)
 
 eNextState POP3C_GetListCommandState(pop3aggr *RecvMsg)
 {
+       AsyncIO *IO = &RecvMsg->IO;
        POP3C_DBG_READ();
        if (!POP3C_OK) return eTerminateConnection;
        RecvMsg->MsgNumbers = NewHash(1, NULL);
@@ -255,6 +285,7 @@ eNextState POP3C_GetListCommandState(pop3aggr *RecvMsg)
 
 eNextState POP3C_GetListOneLine(pop3aggr *RecvMsg)
 {
+       AsyncIO *IO = &RecvMsg->IO;
 #if 0
        int rc;
 #endif
@@ -362,6 +393,7 @@ eNextState POP3_FetchNetworkUsetableEntry(AsyncIO *IO)
 
 eNextState POP3C_GetOneMessagID(pop3aggr *RecvMsg)
 {
+       AsyncIO *IO = &RecvMsg->IO;
        long HKLen;
        const char *HKey;
        void *vData;
@@ -398,6 +430,7 @@ eNextState POP3C_GetOneMessagID(pop3aggr *RecvMsg)
 
 eNextState POP3C_GetOneMessageIDState(pop3aggr *RecvMsg)
 {
+       AsyncIO *IO = &RecvMsg->IO;
 #if 0
        int rc;
        rc = TestValidateHash(RecvMsg->MsgNumbers);
@@ -428,6 +461,7 @@ eNextState POP3C_GetOneMessageIDState(pop3aggr *RecvMsg)
 
 eNextState POP3C_SendGetOneMsg(pop3aggr *RecvMsg)
 {
+       AsyncIO *IO = &RecvMsg->IO;
        long HKLen;
        const char *HKey;
        void *vData;
@@ -459,6 +493,7 @@ eNextState POP3C_SendGetOneMsg(pop3aggr *RecvMsg)
 
 eNextState POP3C_ReadMessageBodyFollowing(pop3aggr *RecvMsg)
 {
+       AsyncIO *IO = &RecvMsg->IO;
        POP3C_DBG_READ();
        if (!POP3C_OK) return eTerminateConnection;
        RecvMsg->IO.ReadMsg = NewAsyncMsg(HKEY("."),
@@ -516,7 +551,8 @@ eNextState POP3C_SaveMsg(AsyncIO *IO)
 
 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);
 
@@ -525,6 +561,7 @@ eNextState POP3C_ReadMessageBody(pop3aggr *RecvMsg)
 
 eNextState POP3C_SendDelete(pop3aggr *RecvMsg)
 {
+       AsyncIO *IO = &RecvMsg->IO;
        if (!RecvMsg->keep) {
                StrBufPrintf(RecvMsg->IO.SendBuf.Buf,
                             "DELE %ld\r\n", RecvMsg->CurrMsg->MSGID);
@@ -538,6 +575,7 @@ eNextState POP3C_SendDelete(pop3aggr *RecvMsg)
 }
 eNextState POP3C_ReadDeleteState(pop3aggr *RecvMsg)
 {
+       AsyncIO *IO = &RecvMsg->IO;
        POP3C_DBG_READ();
        RecvMsg->State = GetOneMessageIDState;
        return eReadMessage;
@@ -545,6 +583,7 @@ eNextState POP3C_ReadDeleteState(pop3aggr *RecvMsg)
 
 eNextState POP3C_SendQuit(pop3aggr *RecvMsg)
 {
+       AsyncIO *IO = &RecvMsg->IO;
        /* Log out */
        StrBufPlain(RecvMsg->IO.SendBuf.Buf,
                    HKEY("QUIT\r\n3)"));
@@ -555,6 +594,7 @@ eNextState POP3C_SendQuit(pop3aggr *RecvMsg)
 
 eNextState POP3C_ReadQuitState(pop3aggr *RecvMsg)
 {
+       AsyncIO *IO = &RecvMsg->IO;
        POP3C_DBG_READ();
        return eTerminateConnection;
 }
@@ -627,9 +667,10 @@ const long POP3_C_ReadTimeouts[] = {
 
 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:
@@ -706,6 +747,14 @@ eNextState POP3_C_Terminate(AsyncIO *IO)
        FinalizePOP3AggrRun(IO);
        return eAbort;
 }
+eNextState POP3_C_TerminateDB(AsyncIO *IO)
+{
+///    pop3aggr *pMsg = (pop3aggr *)IO->Data;
+
+       syslog(LOG_DEBUG, "POP3: %s\n", __FUNCTION__);
+       FinalizePOP3AggrRun(IO);
+       return eAbort;
+}
 eNextState POP3_C_Timeout(AsyncIO *IO)
 {
        pop3aggr *pMsg = IO->Data;
@@ -844,14 +893,6 @@ 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__);
 
@@ -875,7 +916,9 @@ eNextState pop3_get_one_host_ip(AsyncIO *IO)
 
 int pop3_do_fetching(pop3aggr *cpptr)
 {
-       InitIOStruct(&cpptr->IO,
+       AsyncIO *IO = &cpptr->IO;
+
+       InitIOStruct(IO,
                     cpptr,
                     eReadMessage,
                     POP3_C_ReadServerStatus,
@@ -883,6 +926,7 @@ int pop3_do_fetching(pop3aggr *cpptr)
                     POP3_C_DispatchWriteDone,
                     POP3_C_DispatchReadDone,
                     POP3_C_Terminate,
+                    POP3_C_TerminateDB,
                     POP3_C_ConnFail,
                     POP3_C_Timeout,
                     POP3_C_Shutdown);
@@ -1023,11 +1067,15 @@ void pop3client_scan_room(struct ctdlroom *qrbuf, void *data)
                                                                        &lPtr,
                                                                        '|');
 
-                               StrBufPrintf(cptr->Url, "pop3://%s:%s@%s/%s",
-                                            ChrPtr(cptr->pop3user),
-                                            ChrPtr(cptr->pop3pass),
-                                            ChrPtr(Tmp),
-                                            ChrPtr(cptr->RoomName));
+                               StrBufAppendBufPlain(cptr->Url, HKEY("pop3://"), 0);
+                               StrBufUrlescUPAppend(cptr->Url, cptr->pop3user, NULL);
+                               StrBufAppendBufPlain(cptr->Url, HKEY(":"), 0);
+                               StrBufUrlescUPAppend(cptr->Url, cptr->pop3pass, NULL);
+                               StrBufAppendBufPlain(cptr->Url, HKEY("@"), 0);
+                               StrBufAppendBuf(cptr->Url, Tmp, 0);
+                               StrBufAppendBufPlain(cptr->Url, HKEY("/"), 0);
+                               StrBufUrlescAppend(cptr->Url, cptr->RoomName, NULL);
+
                                FreeStrBuf(&Tmp);
                                ParseURL(&cptr->IO.ConnectMe, cptr->Url, 110);
 
@@ -1073,7 +1121,7 @@ void pop3client_scan_room(struct ctdlroom *qrbuf, void *data)
                                }
                                pthread_mutex_unlock(&RSSQueueMutex);
 #endif
-
+                               cptr->n = Pop3ClientID++;
                                pthread_mutex_lock(&POP3QueueMutex);
                                Put(POP3FetchUrls,
                                    SKEY(cptr->Url),
@@ -1168,6 +1216,13 @@ void pop3_cleanup(void)
        DeleteHash(&POP3QueueRooms);
 }
 
+
+
+void LogDebugEnablePOP3Client(const int n)
+{
+       POP3ClientDebugEnabled = n;
+}
+
 CTDL_MODULE_INIT(pop3client)
 {
        if (!threading)
@@ -1178,6 +1233,7 @@ CTDL_MODULE_INIT(pop3client)
                POP3FetchUrls = NewHash(1, NULL);
                CtdlRegisterSessionHook(pop3client_scan, EVT_TIMER);
                CtdlRegisterEVCleanupHook(pop3_cleanup);
+               CtdlRegisterDebugFlagHook(HKEY("pop3client"), LogDebugEnablePOP3Client, &POP3ClientDebugEnabled);
        }
 
        /* return our module id for the log */