static CURL *newFetchmailHandle(const char *mailbox, const char *username, const char *password) { CURLcode res; CURL *handle = curl_easy_init(); if (!handle) i_printfExit(MSG_LibcurlNoInit); curl_easy_setopt(handle, CURLOPT_CONNECTTIMEOUT, mailTimeout); curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, eb_curl_callback); curl_easy_setopt(handle, CURLOPT_WRITEDATA, &callback_data); if (debugLevel >= 4) curl_easy_setopt(handle, CURLOPT_VERBOSE, 1); curl_easy_setopt(handle, CURLOPT_DEBUGFUNCTION, ebcurl_debug_handler); res = curl_easy_setopt(handle, CURLOPT_CAINFO, sslCerts); if (res != CURLE_OK) i_printfExit(MSG_LibcurlNoInit); res = curl_easy_setopt(handle, CURLOPT_USERNAME, username); if (res != CURLE_OK) { ebcurl_setError(res, mailbox); showErrorAbort(); } res = curl_easy_setopt(handle, CURLOPT_PASSWORD, password); if (res != CURLE_OK) { ebcurl_setError(res, mailbox); showErrorAbort(); } return handle; } /* newFetchmailHandle */
/* I'm assuming I can read the cookie file, process it, * and if necessary, write it out again, with the expired cookies deleted, * all before another edbrowse process interferes. * I've given it some thought, and I think I can ignore the race conditions. */ void cookiesFromJar(void) { char *cbuf, *s, *t; FILE *f; int n, cnt, expired, displaced; char *cbuf_end; time_t now; struct cookie *c; if (!cookieFile) return; if (!fileIntoMemory(cookieFile, &cbuf, &n)) showErrorAbort(); cbuf[n] = 0; cbuf_end = cbuf + n; time(&now); cnt = expired = displaced = 0; s = cbuf; while (s < cbuf_end) { t = s + strcspn(s, "\r\n"); /* t points to the first newline past s. If there is no newline in s, * then it points to the NUL byte at end of s. */ *t = '\0'; c = cookie_from_netscape_line(s); if (c) { /* Got a valid cookie line. */ cnt++; if (c->expires < now) { freeCookie(c); nzFree(c); ++expired; } else { acceptCookie(c); displaced += displacedCookie; } } s = t + 1; /* Get ready to read more lines. */ /* Skip over blank lines, if necessary. */ while (s < cbuf_end && (*s == '\r' || *s == '\n')) s++; } debugPrint(3, "%d persistent cookies, %d expired, %d displaced", cnt, expired, displaced); nzFree(cbuf); if (!(expired + displaced)) return; /* Pour the cookies back into the jar */ f = fopen(cookieFile, "w"); if (!f) i_printfExit(MSG_NoRebCookie, cookieFile); foreach(c, cookies) { char *cookLine = netscapeCookieLine(c); fputs(cookLine, f); nzFree(cookLine); }
void scanMail(void) { int nmsgs, m; if (!isInteractive) i_printfExit(MSG_FetchNotBackgnd); if (!mailDir) i_printfExit(MSG_NoMailDir); if (chdir(mailDir)) i_printfExit(MSG_NoDirChange, mailDir); if (!umf) { umf = allocMem(strlen(mailUnread) + 12); sprintf(umf, "%s/", mailUnread); umf_end = umf + strlen(umf); } /* How many mail messages? */ unreadBase = 0; unreadStats(); nmsgs = unreadCount; if (!nmsgs) { i_puts(MSG_NoMail); exit(0); } i_printf(MSG_MessagesX, nmsgs); loadAddressBook(); for (m = 1; m <= nmsgs; ++m) { nzFree(lastMailText); lastMailText = 0; /* Now grab the entire message */ unreadStats(); sprintf(umf_end, "%d", unreadMin); if (!fileIntoMemory(umf, &mailstring, &mailstring_l)) showErrorAbort(); unreadBase = unreadMin; if (presentMail() == 1) unlink(umf); } /* loop over mail messages */ exit(0); } /* scanMail */
/* Return 0 for ok, 1 to delete the mail, -1 to stop. * stop is only meaningful for imap. */ static int presentMail(void) { int j, k; const char *redirect = NULL; /* send mail elsewhere */ char key = 0; const char *atname = NULL; /* name of file or attachment */ bool delflag = false; /* delete this mail */ bool scanat = false; /* scan for attachments */ int displine; int stashNumber = -1; /* clear things out from the last message */ if (lastMailInfo) freeMailInfo(lastMailInfo); lastMailInfo = 0; if (sessionList[1].lw) cxQuit(1, 2); cs = 0; cxSwitch(1, false); iuReformat(mailstring, mailstring_l, &mailu8, &mailu8_l); if (mailu8) { if (!addTextToBuffer((pst) mailu8, mailu8_l, 0, false)) showErrorAbort(); } else { if (!addTextToBuffer((pst) mailstring, mailstring_l, 0, false)) showErrorAbort(); } browseCurrentBuffer(); if (!passMail) { redirect = mailRedirect(lastMailInfo->to, lastMailInfo->from, lastMailInfo->reply, lastMailInfo->subject); } if (redirect) { if (!isimap) { delflag = true; key = 'w'; if (*redirect == '-') ++redirect, key = 'u'; if (stringEqual(redirect, "x")) i_puts(MSG_Junk); else printf("> %s\n", redirect); } else { if (*redirect == '-') ++redirect; if (stringEqual(redirect, "x")) redirect = NULL; } } /* display the next page of mail and get a command from the keyboard */ displine = 1; paging: if (!delflag) { /* show next page */ if (displine <= cw->dol) { for (j = 0; j < 20 && displine <= cw->dol; ++j, ++displine) { char *showline = (char *)fetchLine(displine, 1); k = pstLength((pst) showline); showline[--k] = 0; printf("%s\n", showline); nzFree(showline); } } } /* get key command from user */ key_command: if (delflag) goto writeMail; /* interactive prompt depends on whether there is more text or not */ printf("%c ", displine > cw->dol ? '?' : '*'); fflush(stdout); key = getLetter((isimap ? "q? nwWuUasd" : "q? nwud")); printf("\b\b\b"); fflush(stdout); switch (key) { case 'q': i_puts(MSG_Quit); exit(0); case 'n': i_puts(MSG_Next); goto afterinput; case 's': i_puts(MSG_Stop); goto afterinput; case 'd': i_puts(MSG_Delete); delflag = true; goto afterinput; case ' ': if (displine > cw->dol) i_puts(MSG_EndMessage); goto paging; case '?': i_puts(isimap ? MSG_ImapReadHelp : MSG_MailHelp); goto key_command; case 'a': key = 'w'; /* this will scan attachments */ scanat = true; case 'w': case 'W': case 'u': case 'U': break; default: i_puts(MSG_NYI); goto key_command; } /* switch */ /* At this point we're saving the mail somewhere. */ writeMail: if (!isimap || isupper(key)) delflag = true; atname = 0; if (!isimap) atname = redirect; if (scanat) goto attachOnly; saveMail: if (!atname) atname = getFileName(MSG_FileName, redirect, false, false); if (stringEqual(atname, "x")) goto afterinput; char exists = fileTypeByName(atname, false); int fsize; /* file size */ int fh = open(atname, O_WRONLY | O_TEXT | O_CREAT | O_APPEND, 0666); if (fh < 0) { i_printf(MSG_NoCreate, atname); goto saveMail; } if (exists) write(fh, "======================================================================\n", 71); if (key == 'u') { if (write(fh, mailstring, mailstring_l) < mailstring_l) { badsave: i_printf(MSG_NoWrite, atname); close(fh); goto saveMail; } close(fh); fsize = mailstring_l; } else { /* key = w, write the file - if pop then save the original unformatted */ if (!isimap && mailStash) { char *rmf; /* raw mail file */ int rmfh; /* file handle to same */ /* I want a fairly easy filename, in case I want to go look at the original. * Not a 30 character message ID that I am forced to cut&paste. * 4 or 5 digits would be nice. * So the filename looks like /home/foo/.Trash/rawmail/36921 * I pick the digits randomly. * Please don't accumulate 100,000 emails before you empty your trash. * It's good to have a cron job empty the trash early Sunday morning. */ k = strlen(mailStash); rmf = allocMem(k + 12); /* Try 20 times, then give up. */ for (j = 0; j < 20; ++j) { int rn = rand() % 100000; /* random number */ sprintf(rmf, "%s/%05d", mailStash, rn); if (fileTypeByName(rmf, false)) continue; /* dump the original mail into the file */ rmfh = open(rmf, O_WRONLY | O_TEXT | O_CREAT | O_APPEND, 0666); if (rmfh < 0) break; if (write(rmfh, mailstring, mailstring_l) < mailstring_l) { close(rmfh); unlink(rmf); break; } close(rmfh); /* written successfully, remember the stash number */ stashNumber = rn; break; } } fsize = 0; for (j = 1; j <= cw->dol; ++j) { char *showline = (char *)fetchLine(j, 1); int len = pstLength((pst) showline); if (write(fh, showline, len) < len) goto badsave; nzFree(showline); fsize += len; } /* loop over lines */ if (stashNumber >= 0) { char addstash[60]; sprintf(addstash, "\nUnformatted %05d\n", stashNumber); k = strlen(addstash); if (write(fh, addstash, k) < k) goto badsave; fsize += k; } close(fh); attachOnly: if (nattach) writeAttachments(lastMailInfo); else if (scanat) i_puts(MSG_NoAttachments); } /* unformat or format */ if (scanat) goto afterinput; /* print "mail saved" message */ i_printf(MSG_MailSaved, fsize); if (exists) i_printf(MSG_Appended); nl(); afterinput: nzFree(mailstring); mailstring = 0; nzFree(mailu8); mailu8 = 0; if (delflag) return 1; if (key == 's') return -1; return 0; } /* presentMail */