NeoMutt  2025-12-11-1039-g550ac6
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
lib.h File Reference

POP network mailbox. More...

#include "core/lib.h"
Include dependency graph for lib.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void pop_fetch_mail (void)
 Fetch messages and save them in $spool_file.
enum MailboxType pop_path_probe (const char *path, const struct stat *st)
 Is this a POP Mailbox?

Variables

const struct MxOps MxPopOps
 POP Mailbox - Implements MxOps -.

Detailed Description

POP network mailbox.

Authors
  • Vsevolod Volkov
  • Richard Russon

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file lib.h.

Function Documentation

◆ pop_fetch_mail()

void pop_fetch_mail ( void )

Fetch messages and save them in $spool_file.

Definition at line 533 of file pop.c.

534{
535 const char *const c_pop_host = cs_subset_string(NeoMutt->sub, "pop_host");
536 if (!c_pop_host)
537 {
538 mutt_error(_("POP host is not defined"));
539 return;
540 }
541
542 char buf[1024] = { 0 };
543 char msgbuf[128] = { 0 };
544 int last = 0;
545 int msgs = 0;
546 int bytes = 0;
547 int rset = 0;
548 int rc;
549 struct ConnAccount cac = { { 0 } };
550
551 char *url = NULL;
552 if (url_check_scheme(c_pop_host) == U_UNKNOWN)
553 mutt_str_asprintf(&url, "pop://%s", c_pop_host);
554 else
555 url = mutt_str_dup(c_pop_host);
556
557 rc = pop_parse_path(url, &cac);
558 FREE(&url);
559 if (rc)
560 {
561 mutt_error(_("%s is an invalid POP path"), c_pop_host);
562 return;
563 }
564
565 struct Connection *conn = mutt_conn_find(&cac);
566 if (!conn)
567 return;
568
570 adata->conn = conn;
571
572 if (pop_open_connection(adata) < 0)
573 {
574 pop_adata_free((void **) &adata);
575 return;
576 }
577
578 mutt_message(_("Checking for new messages..."));
579
580 /* find out how many messages are in the mailbox. */
581 mutt_str_copy(buf, "STAT\r\n", sizeof(buf));
582 rc = pop_query(adata, buf, sizeof(buf), NULL);
583 if (rc == -1)
584 goto fail;
585 if (rc == -2)
586 {
587 mutt_error("%s", adata->err_msg);
588 goto finish;
589 }
590
591 sscanf(buf, "+OK %d %d", &msgs, &bytes);
592
593 /* only get unread messages */
594 const bool c_pop_last = cs_subset_bool(NeoMutt->sub, "pop_last");
595 if ((msgs > 0) && c_pop_last)
596 {
597 mutt_str_copy(buf, "LAST\r\n", sizeof(buf));
598 rc = pop_query(adata, buf, sizeof(buf), NULL);
599 if (rc == -1)
600 goto fail;
601 if (rc == 0)
602 sscanf(buf, "+OK %d", &last);
603 }
604
605 if (msgs <= last)
606 {
607 mutt_message(_("No new mail in POP mailbox"));
608 goto finish;
609 }
610
611 const char *const c_spool_file = cs_subset_string(NeoMutt->sub, "spool_file");
612 struct Mailbox *m_spool = mx_path_resolve(c_spool_file);
613
614 if (!mx_mbox_open(m_spool, MUTT_OPEN_NONE))
615 {
616 mailbox_free(&m_spool);
617 goto finish;
618 }
619 bool old_append = m_spool->append;
620 m_spool->append = true;
621
622 enum QuadOption delanswer = query_quadoption(_("Delete messages from server?"),
623 NeoMutt->sub, "pop_delete");
624
625 snprintf(msgbuf, sizeof(msgbuf),
626 ngettext("Reading new messages (%d byte)...",
627 "Reading new messages (%d bytes)...", bytes),
628 bytes);
629 mutt_message("%s", msgbuf);
630
631 for (int i = last + 1; i <= msgs; i++)
632 {
633 struct Message *msg = mx_msg_open_new(m_spool, NULL, MUTT_ADD_FROM);
634 if (msg)
635 {
636 snprintf(buf, sizeof(buf), "RETR %d\r\n", i);
637 rc = pop_fetch_data(adata, buf, NULL, fetch_message, msg->fp);
638 if (rc == -3)
639 rset = 1;
640
641 if ((rc == 0) && (mx_msg_commit(m_spool, msg) != 0))
642 {
643 rset = 1;
644 rc = -3;
645 }
646
647 mx_msg_close(m_spool, &msg);
648 }
649 else
650 {
651 rc = -3;
652 }
653
654 if ((rc == 0) && (delanswer == MUTT_YES))
655 {
656 /* delete the message on the server */
657 snprintf(buf, sizeof(buf), "DELE %d\r\n", i);
658 rc = pop_query(adata, buf, sizeof(buf), NULL);
659 }
660
661 if (rc == -1)
662 {
663 m_spool->append = old_append;
664 mx_mbox_close(m_spool);
665 goto fail;
666 }
667 if (rc == -2)
668 {
669 mutt_error("%s", adata->err_msg);
670 break;
671 }
672 if (rc == -3)
673 {
674 mutt_error(_("Error while writing mailbox"));
675 break;
676 }
677
678 /* L10N: The plural is picked by the second numerical argument, i.e.
679 the %d right before 'messages', i.e. the total number of messages. */
680 mutt_message(ngettext("%s [%d of %d message read]",
681 "%s [%d of %d messages read]", msgs - last),
682 msgbuf, i - last, msgs - last);
683 }
684
685 m_spool->append = old_append;
686 mx_mbox_close(m_spool);
687
688 if (rset)
689 {
690 /* make sure no messages get deleted */
691 mutt_str_copy(buf, "RSET\r\n", sizeof(buf));
692 if (pop_query(adata, buf, sizeof(buf), NULL) == -1)
693 goto fail;
694 }
695
696finish:
697 /* exit gracefully */
698 mutt_str_copy(buf, "QUIT\r\n", sizeof(buf));
699 if (pop_query(adata, buf, sizeof(buf), NULL) == -1)
700 goto fail;
701 mutt_socket_close(conn);
702 pop_adata_free((void **) &adata);
703 return;
704
705fail:
706 mutt_error(_("Server closed connection"));
707 mutt_socket_close(conn);
708 pop_adata_free((void **) &adata);
709}
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition helpers.c:291
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition helpers.c:47
void mailbox_free(struct Mailbox **ptr)
Free a Mailbox.
Definition mailbox.c:90
void pop_adata_free(void **ptr)
Free the private Account data - Implements Account::adata_free() -.
Definition adata.c:41
#define mutt_error(...)
Definition logging2.h:94
#define mutt_message(...)
Definition logging2.h:93
static int fetch_message(const char *line, void *data)
Parse a Message response - Implements pop_fetch_t -.
Definition pop.c:102
#define FREE(x)
Free memory and set the pointer to NULL.
Definition memory.h:68
#define _(a)
Definition message.h:28
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition string.c:257
int mutt_str_asprintf(char **strp, const char *fmt,...)
Definition string.c:809
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination).
Definition string.c:587
struct Connection * mutt_conn_find(const struct ConnAccount *cac)
Find a connection from a list.
Definition mutt_socket.c:88
int mx_msg_close(struct Mailbox *m, struct Message **ptr)
Close a message.
Definition mx.c:1185
bool mx_mbox_open(struct Mailbox *m, OpenMailboxFlags flags)
Open a mailbox and parse it.
Definition mx.c:285
struct Message * mx_msg_open_new(struct Mailbox *m, const struct Email *e, MsgOpenFlags flags)
Open a new message.
Definition mx.c:1044
int mx_msg_commit(struct Mailbox *m, struct Message *msg)
Commit a message to a folder - Wrapper for MxOps::msg_commit().
Definition mx.c:1164
struct Mailbox * mx_path_resolve(const char *path)
Get a Mailbox for a path.
Definition mx.c:1650
enum MxStatus mx_mbox_close(struct Mailbox *m)
Save changes and close mailbox.
Definition mx.c:595
@ MUTT_ADD_FROM
add a From_ line
Definition mx.h:43
@ MUTT_OPEN_NONE
No flags are set.
Definition mxapi.h:42
struct PopAccountData * pop_adata_new(void)
Create a new PopAccountData object.
Definition adata.c:63
int pop_open_connection(struct PopAccountData *adata)
Open connection and authenticate.
Definition lib.c:317
int pop_parse_path(const char *path, struct ConnAccount *cac)
Parse a POP mailbox name.
Definition lib.c:82
int pop_fetch_data(struct PopAccountData *adata, const char *query, struct Progress *progress, pop_fetch_t callback, void *data)
Read Headers with callback function.
Definition lib.c:512
int pop_query(struct PopAccountData *adata, char *buf, size_t buflen, char *msg)
Send data from buffer and receive answer to the same buffer.
Definition lib.c:467
QuadOption
Possible values for a quad-option.
Definition quad.h:36
@ MUTT_YES
User answered 'Yes', or assume 'Yes'.
Definition quad.h:39
enum QuadOption query_quadoption(const char *prompt, struct ConfigSubset *sub, const char *name)
Ask the user a quad-question.
Definition question.c:384
int mutt_socket_close(struct Connection *conn)
Close a socket.
Definition socket.c:100
void * adata
Private data (for Mailbox backends).
Definition account.h:42
Login details for a remote server.
Definition connaccount.h:59
A mailbox.
Definition mailbox.h:81
bool append
Mailbox is opened in append mode.
Definition mailbox.h:111
A local copy of an email.
Definition message.h:34
FILE * fp
pointer to the message data
Definition message.h:35
Container for Accounts, Notifications.
Definition neomutt.h:41
struct ConfigSubset * sub
Inherited config items.
Definition neomutt.h:49
POP-specific Account data -.
Definition adata.h:37
char err_msg[POP_CMD_RESPONSE]
Last error message.
Definition adata.h:57
struct Connection * conn
Connection to POP server.
Definition adata.h:38
enum UrlScheme url_check_scheme(const char *str)
Check the protocol of a URL.
Definition url.c:229
@ U_UNKNOWN
Url wasn't recognised.
Definition url.h:35
Here is the call graph for this function:
Here is the caller graph for this function: