/* mutt_conn_find: find a connection off the list of connections whose * account matches account. If start is not null, only search for * connections after the given connection (allows higher level socket code * to make more fine-grained searches than account info - eg in IMAP we may * wish to find a connection which is not in IMAP_SELECTED state) */ CONNECTION* mutt_conn_find (const CONNECTION* start, const ACCOUNT* account) { CONNECTION* conn; ciss_url_t url; char hook[LONG_STRING]; /* account isn't actually modified, since url isn't either */ mutt_account_tourl ((ACCOUNT*) account, &url); url.path = NULL; url_ciss_tostring (&url, hook, sizeof (hook), 0); mutt_account_hook (hook); conn = start ? start->next : Connections; while (conn) { if (mutt_account_match (account, &(conn->account))) return conn; conn = conn->next; } conn = socket_new_conn (); memcpy (&conn->account, account, sizeof (ACCOUNT)); conn->next = Connections; Connections = conn; if (Tunnel && *Tunnel) mutt_tunnel_socket_setup (conn); else if (account->flags & M_ACCT_SSL) { #if defined(USE_SSL) if (mutt_ssl_socket_setup (conn) < 0) { mutt_socket_free (conn); return NULL; } #else mutt_error _("SSL is unavailable."); mutt_sleep (2); mutt_socket_free (conn); return NULL; #endif } else { conn->conn_read = raw_socket_read; conn->conn_write = raw_socket_write; conn->conn_open = raw_socket_open; conn->conn_close = raw_socket_close; conn->conn_poll = raw_socket_poll; } return conn; }
/* close POP mailbox */ int pop_close_mailbox(CONTEXT *ctx) { POP_DATA *pop_data = (POP_DATA *)ctx->data; if (!pop_data) return 0; pop_logout(ctx); if (pop_data->status != POP_NONE) mutt_socket_close(pop_data->conn); pop_data->status = POP_NONE; pop_data->clear_cache = 1; pop_clear_cache(pop_data); if (!pop_data->conn->data) mutt_socket_free(pop_data->conn); mutt_bcache_close(&pop_data->bcache); return 0; }
/* 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); }