/* Check for new messages and fetch headers */ int pop_check_mailbox(CONTEXT *ctx, int *index_hint) { int ret; POP_DATA *pop_data = (POP_DATA *)ctx->data; if ((pop_data->check_time + PopCheckTimeout) > time(NULL)) return 0; pop_logout(ctx); mutt_socket_close(pop_data->conn); if (pop_open_connection(pop_data) < 0) return -1; ctx->size = pop_data->size; mutt_message _("Checking for new messages..."); ret = pop_fetch_headers(ctx); pop_clear_cache(pop_data); if (ret < 0) return -1; if (ret > 0) return M_NEW_MAIL; return 0; }
/* reconnect and verify idnexes if connection was lost */ int pop_reconnect (CONTEXT *ctx) { int ret; POP_DATA *pop_data = (POP_DATA *)ctx->data; progress_t progressbar; if (pop_data->status == POP_CONNECTED) return 0; if (pop_data->status == POP_BYE) return -1; FOREVER { mutt_socket_close (pop_data->conn); ret = pop_open_connection (pop_data); if (ret == 0) { int i; mutt_progress_init (&progressbar, _("Verifying message indexes..."), M_PROGRESS_SIZE, NetInc, 0); for (i = 0; i < ctx->msgcount; i++) ctx->hdrs[i]->refno = -1; ret = pop_fetch_data (pop_data, "UIDL\r\n", &progressbar, check_uidl, ctx); if (ret == -2) { mutt_error ("%s", pop_data->err_msg); mutt_sleep (2); } } if (ret == 0) return 0; pop_logout (ctx); if (ret < -1) return -1; if (query_quadoption (OPT_POPRECONNECT, _("Connection lost. Reconnect to POP server?")) != M_YES) return -1; } }
/* Fetch messages and save them in $spoolfile */ void pop_fetch_mail(void) { char buffer[LONG_STRING]; char msgbuf[SHORT_STRING]; char *url, *p; int i, delanswer, last = 0, msgs, bytes, rset = 0, ret; CONNECTION *conn; CONTEXT ctx; MESSAGE *msg = NULL; ACCOUNT acct; POP_DATA *pop_data; if (!PopHost) { mutt_error _("POP host is not defined."); return; } url = p = safe_calloc(strlen(PopHost) + 7, sizeof(char)); if (url_check_scheme(PopHost) == U_UNKNOWN) { strcpy(url, "pop://"); /* __STRCPY_CHECKED__ */ p = strchr(url, '\0'); } strcpy(p, PopHost); /* __STRCPY_CHECKED__ */ ret = pop_parse_path(url, &acct); safe_free(&url); if (ret) { mutt_error(_("%s is an invalid POP path"), PopHost); return; } conn = mutt_conn_find(NULL, &acct); if (!conn) return; pop_data = safe_calloc(1, sizeof(POP_DATA)); pop_data->conn = conn; if (pop_open_connection(pop_data) < 0) { mutt_socket_free(pop_data->conn); safe_free(&pop_data); return; } conn->data = pop_data; mutt_message _("Checking for new messages..."); /* find out how many messages are in the mailbox. */ strfcpy(buffer, "STAT\r\n", sizeof(buffer)); ret = pop_query(pop_data, buffer, sizeof(buffer)); if (ret == -1) goto fail; if (ret == -2) { mutt_error("%s", pop_data->err_msg); goto finish; } sscanf(buffer, "+OK %d %d", &msgs, &bytes); /* only get unread messages */ if ((msgs > 0) && option(OPTPOPLAST)) { strfcpy(buffer, "LAST\r\n", sizeof(buffer)); ret = pop_query(pop_data, buffer, sizeof(buffer)); if (ret == -1) goto fail; if (ret == 0) sscanf(buffer, "+OK %d", &last); } if (msgs <= last) { mutt_message _("No new mail in POP mailbox."); goto finish; } if (mx_open_mailbox(NONULL(Spoolfile), M_APPEND, &ctx) == NULL) goto finish; delanswer = query_quadoption(OPT_POPDELETE, _( "Delete messages from server?")); snprintf(msgbuf, sizeof(msgbuf), _( "Reading new messages (%d bytes)..."), bytes); mutt_message("%s", msgbuf); for (i = last + 1; i <= msgs; i++) { if ((msg = mx_open_new_message(&ctx, NULL, M_ADD_FROM)) == NULL) ret = -3; else { snprintf(buffer, sizeof(buffer), "RETR %d\r\n", i); ret = pop_fetch_data(pop_data, buffer, NULL, fetch_message, msg->fp); if (ret == -3) rset = 1; if ((ret == 0) && (mx_commit_message(msg, &ctx) != 0)) { rset = 1; ret = -3; } mx_close_message(&msg); } if ((ret == 0) && (delanswer == M_YES)) { /* delete the message on the server */ snprintf(buffer, sizeof(buffer), "DELE %d\r\n", i); ret = pop_query(pop_data, buffer, sizeof(buffer)); } if (ret == -1) { mx_close_mailbox(&ctx, NULL); goto fail; } if (ret == -2) { mutt_error("%s", pop_data->err_msg); break; } if (ret == -3) { mutt_error _("Error while writing mailbox!"); break; } mutt_message(_( "%s [%d of %d messages read]"), msgbuf, i - last, msgs - last); } mx_close_mailbox(&ctx, NULL); if (rset) { /* make sure no messages get deleted */ strfcpy(buffer, "RSET\r\n", sizeof(buffer)); if (pop_query(pop_data, buffer, sizeof(buffer)) == -1) goto fail; } finish: /* exit gracefully */ strfcpy(buffer, "QUIT\r\n", sizeof(buffer)); if (pop_query(pop_data, buffer, sizeof(buffer)) == -1) goto fail; mutt_socket_close(conn); safe_free(&pop_data); return; fail: mutt_error _("Server closed connection!"); mutt_socket_close(conn); safe_free(&pop_data); }
/* open POP mailbox - fetch only headers */ int pop_open_mailbox(CONTEXT *ctx) { int ret; char buf[LONG_STRING]; CONNECTION *conn; ACCOUNT acct; POP_DATA *pop_data; ciss_url_t url; if (pop_parse_path(ctx->path, &acct)) { mutt_error(_("%s is an invalid POP path"), ctx->path); mutt_sleep(2); return -1; } mutt_account_tourl(&acct, &url); url.path = NULL; url_ciss_tostring(&url, buf, sizeof(buf), 0); conn = mutt_conn_find(NULL, &acct); if (!conn) return -1; safe_free(&ctx->path); ctx->path = safe_strdup(buf); pop_data = safe_calloc(1, sizeof(POP_DATA)); pop_data->conn = conn; ctx->data = pop_data; ctx->mx_close = pop_close_mailbox; if (pop_open_connection(pop_data) < 0) return -1; conn->data = pop_data; pop_data->bcache = mutt_bcache_open(&acct, NULL); /* init (hard-coded) ACL rights */ memset(ctx->rights, 0, sizeof(ctx->rights)); mutt_bit_set(ctx->rights, M_ACL_SEEN); mutt_bit_set(ctx->rights, M_ACL_DELETE); FOREVER { if (pop_reconnect(ctx) < 0) return -1; ctx->size = pop_data->size; mutt_message _("Fetching list of messages..."); ret = pop_fetch_headers(ctx); if (ret >= 0) return 0; if (ret < -1) { mutt_sleep(2); return -1; } } }