NeoMutt  2021-02-05-666-ge300cd
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 515 of file pop.c.

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