NeoMutt  2023-03-22-27-g3cb248
Teaching an old dog new tricks
DOXYGEN
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. More...
 
enum MailboxType pop_path_probe (const char *path, const struct stat *st)
 Is this a POP Mailbox? - Implements MxOps::path_probe() -. More...
 

Variables

struct MxOps MxPopOps
 POP Mailbox - Implements MxOps -. More...
 

Detailed Description

POP network mailbox.

Authors
  • Vsevolod Volkov

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 510 of file pop.c.

511{
512 const char *const c_pop_host = cs_subset_string(NeoMutt->sub, "pop_host");
513 if (!c_pop_host)
514 {
515 mutt_error(_("POP host is not defined"));
516 return;
517 }
518
519 char buf[1024] = { 0 };
520 char msgbuf[128] = { 0 };
521 int last = 0, msgs, bytes, rset = 0, rc;
522 struct ConnAccount cac = { { 0 } };
523
524 char *p = mutt_mem_calloc(strlen(c_pop_host) + 7, sizeof(char));
525 char *url = p;
526 if (url_check_scheme(c_pop_host) == U_UNKNOWN)
527 {
528 strcpy(url, "pop://");
529 p = strchr(url, '\0');
530 }
531 strcpy(p, c_pop_host);
532
533 rc = pop_parse_path(url, &cac);
534 FREE(&url);
535 if (rc)
536 {
537 mutt_error(_("%s is an invalid POP path"), c_pop_host);
538 return;
539 }
540
541 struct Connection *conn = mutt_conn_find(&cac);
542 if (!conn)
543 return;
544
546 adata->conn = conn;
547
548 if (pop_open_connection(adata) < 0)
549 {
550 //XXX mutt_socket_free(adata->conn);
551 pop_adata_free((void **) &adata);
552 return;
553 }
554
555 mutt_message(_("Checking for new messages..."));
556
557 /* find out how many messages are in the mailbox. */
558 mutt_str_copy(buf, "STAT\r\n", sizeof(buf));
559 rc = pop_query(adata, buf, sizeof(buf));
560 if (rc == -1)
561 goto fail;
562 if (rc == -2)
563 {
564 mutt_error("%s", adata->err_msg);
565 goto finish;
566 }
567
568 sscanf(buf, "+OK %d %d", &msgs, &bytes);
569
570 /* only get unread messages */
571 const bool c_pop_last = cs_subset_bool(NeoMutt->sub, "pop_last");
572 if ((msgs > 0) && c_pop_last)
573 {
574 mutt_str_copy(buf, "LAST\r\n", sizeof(buf));
575 rc = pop_query(adata, buf, sizeof(buf));
576 if (rc == -1)
577 goto fail;
578 if (rc == 0)
579 sscanf(buf, "+OK %d", &last);
580 }
581
582 if (msgs <= last)
583 {
584 mutt_message(_("No new mail in POP mailbox"));
585 goto finish;
586 }
587
588 const char *const c_spool_file = cs_subset_string(NeoMutt->sub, "spool_file");
589 struct Mailbox *m_spool = mx_path_resolve(c_spool_file);
590
591 if (!mx_mbox_open(m_spool, MUTT_OPEN_NO_FLAGS))
592 {
593 mailbox_free(&m_spool);
594 goto finish;
595 }
596 bool old_append = m_spool->append;
597 m_spool->append = true;
598
599 const enum QuadOption c_pop_delete = cs_subset_quad(NeoMutt->sub, "pop_delete");
600 enum QuadOption delanswer = query_quadoption(c_pop_delete, _("Delete messages from server?"));
601
602 snprintf(msgbuf, sizeof(msgbuf),
603 ngettext("Reading new messages (%d byte)...",
604 "Reading new messages (%d bytes)...", bytes),
605 bytes);
606 mutt_message("%s", msgbuf);
607
608 for (int i = last + 1; i <= msgs; i++)
609 {
610 struct Message *msg = mx_msg_open_new(m_spool, NULL, MUTT_ADD_FROM);
611 if (msg)
612 {
613 snprintf(buf, sizeof(buf), "RETR %d\r\n", i);
614 rc = pop_fetch_data(adata, buf, NULL, fetch_message, msg->fp);
615 if (rc == -3)
616 rset = 1;
617
618 if ((rc == 0) && (mx_msg_commit(m_spool, msg) != 0))
619 {
620 rset = 1;
621 rc = -3;
622 }
623
624 mx_msg_close(m_spool, &msg);
625 }
626 else
627 {
628 rc = -3;
629 }
630
631 if ((rc == 0) && (delanswer == MUTT_YES))
632 {
633 /* delete the message on the server */
634 snprintf(buf, sizeof(buf), "DELE %d\r\n", i);
635 rc = pop_query(adata, buf, sizeof(buf));
636 }
637
638 if (rc == -1)
639 {
640 m_spool->append = old_append;
641 mx_mbox_close(m_spool);
642 goto fail;
643 }
644 if (rc == -2)
645 {
646 mutt_error("%s", adata->err_msg);
647 break;
648 }
649 if (rc == -3)
650 {
651 mutt_error(_("Error while writing mailbox"));
652 break;
653 }
654
655 /* L10N: The plural is picked by the second numerical argument, i.e.
656 the %d right before 'messages', i.e. the total number of messages. */
657 mutt_message(ngettext("%s [%d of %d message read]",
658 "%s [%d of %d messages read]", msgs - last),
659 msgbuf, i - last, msgs - last);
660 }
661
662 m_spool->append = old_append;
663 mx_mbox_close(m_spool);
664
665 if (rset)
666 {
667 /* make sure no messages get deleted */
668 mutt_str_copy(buf, "RSET\r\n", sizeof(buf));
669 if (pop_query(adata, buf, sizeof(buf)) == -1)
670 goto fail;
671 }
672
673finish:
674 /* exit gracefully */
675 mutt_str_copy(buf, "QUIT\r\n", sizeof(buf));
676 if (pop_query(adata, buf, sizeof(buf)) == -1)
677 goto fail;
678 mutt_socket_close(conn);
679 pop_adata_free((void **) &adata);
680 return;
681
682fail:
683 mutt_error(_("Server closed connection"));
684 mutt_socket_close(conn);
685 pop_adata_free((void **) &adata);
686}
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
enum QuadOption cs_subset_quad(const struct ConfigSubset *sub, const char *name)
Get a quad-value config item by name.
Definition: helpers.c:218
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
#define mutt_error(...)
Definition: logging.h:87
#define mutt_message(...)
Definition: logging.h:86
static int fetch_message(const char *line, void *data)
Write line to file - Implements pop_fetch_t -.
Definition: pop.c:97
void mailbox_free(struct Mailbox **ptr)
Free a Mailbox.
Definition: mailbox.c:87
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
#define FREE(x)
Definition: memory.h:43
#define _(a)
Definition: message.h:28
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:652
struct Connection * mutt_conn_find(const struct ConnAccount *cac)
Find a connection from a list.
Definition: mutt_socket.c:89
int mx_msg_close(struct Mailbox *m, struct Message **msg)
Close a message.
Definition: mx.c:1200
bool mx_mbox_open(struct Mailbox *m, OpenMailboxFlags flags)
Open a mailbox and parse it.
Definition: mx.c:305
struct Message * mx_msg_open_new(struct Mailbox *m, const struct Email *e, MsgOpenFlags flags)
Open a new message.
Definition: mx.c:1062
int mx_msg_commit(struct Mailbox *m, struct Message *msg)
Commit a message to a folder - Wrapper for MxOps::msg_commit()
Definition: mx.c:1179
struct Mailbox * mx_path_resolve(const char *path)
Get a Mailbox for a path.
Definition: mx.c:1684
enum MxStatus mx_mbox_close(struct Mailbox *m)
Save changes and close mailbox.
Definition: mx.c:616
#define MUTT_ADD_FROM
add a From_ line
Definition: mx.h:43
#define MUTT_OPEN_NO_FLAGS
No flags are set.
Definition: mxapi.h:61
struct PopAccountData * pop_adata_new(void)
Create a new PopAccountData object.
Definition: adata.c:63
void pop_adata_free(void **ptr)
Free the private Account data - Implements Account::adata_free()
Definition: adata.c:41
int pop_open_connection(struct PopAccountData *adata)
Open connection and authenticate.
Definition: lib.c:308
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:502
#define pop_query(adata, buf, buflen)
Definition: private.h:109
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(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: question.c:386
int mutt_socket_close(struct Connection *conn)
Close a socket.
Definition: socket.c:101
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
Login details for a remote server.
Definition: connaccount.h:53
A mailbox.
Definition: mailbox.h:79
bool append
Mailbox is opened in append mode.
Definition: mailbox.h:109
A local copy of an email.
Definition: mxapi.h:43
FILE * fp
pointer to the message data
Definition: mxapi.h:44
Container for Accounts, Notifications.
Definition: neomutt.h:37
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
POP-specific Account data -.
Definition: adata.h:37
char err_msg[POP_CMD_RESPONSE]
Definition: adata.h:56
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:223
@ 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: