+ syslog(LOG_DEBUG, "pop3client: room=<%s> host=<%s> user=<%s> keep=<%d> interval=<%ld>", room, host, user, keep, interval);
+
+ char url[SIZ];
+ CURL *curl;
+ CURLcode res = CURLE_OK;
+ StrBuf *Uidls = NULL;
+ int i;
+ char cmd[1024];
+
+ curl = curl_easy_init();
+ if (!curl) {
+ return;
+ }
+
+ Uidls = NewStrBuf();
+
+ curl_easy_setopt(curl, CURLOPT_USERNAME, user);
+ curl_easy_setopt(curl, CURLOPT_PASSWORD, pass);
+ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
+ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
+ curl_easy_setopt(curl, CURLOPT_TIMEOUT, 15);
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlFillStrBuf_callback); // What to do with downloaded data
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, Uidls); // Give it our StrBuf to work with
+ curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "UIDL");
+
+ /* Try POP3S (SSL encrypted) first */
+ snprintf(url, sizeof url, "pop3s://%s", host);
+ curl_easy_setopt(curl, CURLOPT_URL, url);
+ res = curl_easy_perform(curl);
+ if (res == CURLE_OK) {
+ } else {
+ syslog(LOG_DEBUG, "pop3client: POP3S connection failed: %s , trying POP3 next", curl_easy_strerror(res));
+ snprintf(url, sizeof url, "pop3://%s", host); // try unencrypted next
+ curl_easy_setopt(curl, CURLOPT_URL, url);
+ FlushStrBuf(Uidls);
+ res = curl_easy_perform(curl);
+ }
+
+ if (res != CURLE_OK) {
+ syslog(LOG_DEBUG, "pop3client: POP3 connection failed: %s", curl_easy_strerror(res));
+ curl_easy_cleanup(curl);
+ FreeStrBuf(&Uidls);
+ return;
+ }
+
+ // If we got this far, a connection was established, we know whether it's pop3s or pop3, and UIDL is supported.
+ // Now go through the UIDL list and look for messages.
+
+ int num_msgs = num_tokens(ChrPtr(Uidls), '\n');
+ syslog(LOG_DEBUG, "pop3client: there are %d messages", num_msgs);
+ for (i=0; i<num_msgs; ++i) {
+ char oneuidl[1024];
+ extract_token(oneuidl, ChrPtr(Uidls), i, '\n', sizeof oneuidl);
+ if (strlen(oneuidl) > 2) {
+ if (oneuidl[strlen(oneuidl)-1] == '\r') {
+ oneuidl[strlen(oneuidl)-1] = 0;
+ }
+ int this_msg = atoi(oneuidl);
+ char *c = strchr(oneuidl, ' ');
+ if (c) strcpy(oneuidl, ++c);
+
+ // Make up the Use Table record so we can check if we've already seen this message.
+ StrBuf *UT = NewStrBuf();
+ StrBufPrintf(UT, "pop3/%s/%s:%s@%s", room, oneuidl, user, host);
+ int already_seen = CheckIfAlreadySeen(UT);
+ FreeStrBuf(&UT);
+
+ // Only fetch the message if we haven't seen it before.
+ if (already_seen == 0) {
+ StrBuf *TheMsg = NewStrBuf();
+ snprintf(cmd, sizeof cmd, "RETR %d", this_msg);
+ curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, cmd);
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, TheMsg);
+ res = curl_easy_perform(curl);
+ if (res == CURLE_OK) {
+ struct CtdlMessage *msg = convert_internet_message_buf(&TheMsg);
+ CtdlSubmitMsg(msg, NULL, room, 0);
+ CM_Free(msg);
+ }
+ else {
+ FreeStrBuf(&TheMsg);
+ }
+
+ // Unless the configuration says to keep the message on the server, delete it.
+ if (keep == 0) {
+ snprintf(cmd, sizeof cmd, "DELE %d", this_msg);
+ curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, cmd);
+ res = curl_easy_perform(curl);
+ }
+ }
+ else {
+ syslog(LOG_DEBUG, "pop3client: %s has already been retrieved", oneuidl);
+ }
+ }
+ }
+
+ curl_easy_cleanup(curl);
+ FreeStrBuf(&Uidls);
+ return;