NeoMutt  2021-02-05-666-ge300cd
Teaching an old dog new tricks
DOXYGEN
lib.c File Reference

POP helper routines. More...

#include "config.h"
#include <errno.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "private.h"
#include "mutt/lib.h"
#include "config/lib.h"
#include "email/lib.h"
#include "core/lib.h"
#include "conn/lib.h"
#include "question/lib.h"
#include "progress/lib.h"
#include "adata.h"
#include "edata.h"
#include "mutt_account.h"
#include "mutt_logging.h"
#include "mutt_socket.h"
+ Include dependency graph for lib.c:

Go to the source code of this file.

Functions

const char * pop_get_field (enum ConnAccountField field, void *gf_data)
 Get connection login credentials - Implements ConnAccount::get_field() More...
 
int pop_parse_path (const char *path, struct ConnAccount *cac)
 Parse a POP mailbox name. More...
 
static void pop_error (struct PopAccountData *adata, char *msg)
 Copy error message to err_msg buffer. More...
 
static int fetch_capa (const char *line, void *data)
 Parse CAPA output - Implements pop_fetch_t. More...
 
static int fetch_auth (const char *line, void *data)
 Fetch list of the authentication mechanisms - Implements pop_fetch_t. More...
 
static int pop_capabilities (struct PopAccountData *adata, int mode)
 Get capabilities from a POP server. More...
 
int pop_connect (struct PopAccountData *adata)
 Open connection. More...
 
int pop_open_connection (struct PopAccountData *adata)
 Open connection and authenticate. More...
 
void pop_logout (struct Mailbox *m)
 logout from a POP server More...
 
int pop_query_d (struct PopAccountData *adata, char *buf, size_t buflen, char *msg)
 Send data from buffer and receive answer to the same buffer. More...
 
int pop_fetch_data (struct PopAccountData *adata, const char *query, struct Progress *progress, pop_fetch_t callback, void *data)
 Read Headers with callback function. More...
 
static int check_uidl (const char *line, void *data)
 find message with this UIDL and set refno - Implements pop_fetch_t More...
 
int pop_reconnect (struct Mailbox *m)
 reconnect and verify indexes if connection was lost More...
 

Detailed Description

POP helper routines.

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.c.

Function Documentation

◆ pop_get_field()

const char* pop_get_field ( enum ConnAccountField  field,
void *  gf_data 
)

Get connection login credentials - Implements ConnAccount::get_field()

Definition at line 57 of file lib.c.

58 {
59  switch (field)
60  {
61  case MUTT_CA_LOGIN:
62  case MUTT_CA_USER:
63  return cs_subset_string(NeoMutt->sub, "pop_user");
64  case MUTT_CA_PASS:
65  return cs_subset_string(NeoMutt->sub, "pop_pass");
66  case MUTT_CA_OAUTH_CMD:
67  return cs_subset_string(NeoMutt->sub, "pop_oauth_refresh_command");
68  case MUTT_CA_HOST:
69  default:
70  return NULL;
71  }
72 }
Password.
Definition: connaccount.h:36
Container for Accounts, Notifications.
Definition: neomutt.h:36
User name.
Definition: connaccount.h:35
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
OAuth refresh command.
Definition: connaccount.h:37
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
Login name.
Definition: connaccount.h:34
Server name.
Definition: connaccount.h:33
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pop_parse_path()

int pop_parse_path ( const char *  path,
struct ConnAccount cac 
)

Parse a POP mailbox name.

Parameters
pathPath to parse
cacAccount to store details
Return values
0success
-1error

Split a POP path into host, port, username and password

Definition at line 83 of file lib.c.

84 {
85  /* Defaults */
86  cac->flags = 0;
87  cac->type = MUTT_ACCT_TYPE_POP;
88  cac->port = 0;
89  cac->service = "pop";
90  cac->get_field = pop_get_field;
91 
92  struct Url *url = url_parse(path);
93 
94  if (!url || ((url->scheme != U_POP) && (url->scheme != U_POPS)) ||
95  !url->host || (mutt_account_fromurl(cac, url) < 0))
96  {
97  url_free(&url);
98  mutt_error(_("Invalid POP URL: %s"), path);
99  return -1;
100  }
101 
102  if (url->scheme == U_POPS)
103  cac->flags |= MUTT_ACCT_SSL;
104 
105  struct servent *service =
106  getservbyname((url->scheme == U_POP) ? "pop3" : "pop3s", "tcp");
107  if (cac->port == 0)
108  {
109  if (service)
110  cac->port = ntohs(service->s_port);
111  else
112  cac->port = (url->scheme == U_POP) ? POP_PORT : POP_SSL_PORT;
113  }
114 
115  url_free(&url);
116  return 0;
117 }
int mutt_account_fromurl(struct ConnAccount *cac, const struct Url *url)
Fill ConnAccount with information from url.
Definition: mutt_account.c:43
#define mutt_error(...)
Definition: logging.h:88
#define POP_SSL_PORT
Definition: private.h:36
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:68
enum UrlScheme scheme
Scheme, e.g. U_SMTPS.
Definition: url.h:70
#define POP_PORT
Definition: private.h:35
#define _(a)
Definition: message.h:28
void url_free(struct Url **ptr)
Free the contents of a URL.
Definition: url.c:123
unsigned short port
Port to connect to.
Definition: connaccount.h:57
const char *(* get_field)(enum ConnAccountField field, void *gf_data)
Function to get some login credentials.
Definition: connaccount.h:67
const char * pop_get_field(enum ConnAccountField field, void *gf_data)
Get connection login credentials - Implements ConnAccount::get_field()
Definition: lib.c:57
unsigned char type
Connection type, e.g. MUTT_ACCT_TYPE_IMAP.
Definition: connaccount.h:58
char * host
Host.
Definition: url.h:73
const char * service
Name of the service, e.g. "imap".
Definition: connaccount.h:60
char * path
Path.
Definition: url.h:75
Pop Account.
Definition: mutt_account.h:38
Url is pop://.
Definition: url.h:37
#define MUTT_ACCT_SSL
Account uses SSL/TLS.
Definition: connaccount.h:46
Url is pops://.
Definition: url.h:38
MuttAccountFlags flags
Which fields are initialised, e.g. MUTT_ACCT_USER.
Definition: connaccount.h:59
struct Url * url_parse(const char *src)
Fill in Url.
Definition: url.c:234
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pop_error()

static void pop_error ( struct PopAccountData adata,
char *  msg 
)
static

Copy error message to err_msg buffer.

Parameters
adataPOP Account data
msgError message to save

Definition at line 124 of file lib.c.

125 {
126  char *t = strchr(adata->err_msg, '\0');
127  char *c = msg;
128 
129  size_t plen = mutt_str_startswith(msg, "-ERR ");
130  if (plen != 0)
131  {
132  char *c2 = mutt_str_skip_email_wsp(msg + plen);
133 
134  if (*c2)
135  c = c2;
136  }
137 
138  mutt_str_copy(t, c, sizeof(adata->err_msg) - strlen(adata->err_msg));
140 }
char err_msg[POP_CMD_RESPONSE]
Definition: adata.h:56
static size_t plen
Length of cached packet.
Definition: pgppacket.c:39
void mutt_str_remove_trailing_ws(char *s)
Trim trailing whitespace from a string.
Definition: string.c:733
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:160
char * mutt_str_skip_email_wsp(const char *s)
Skip over whitespace as defined by RFC5322.
Definition: string.c:776
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
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fetch_capa()

static int fetch_capa ( const char *  line,
void *  data 
)
static

Parse CAPA output - Implements pop_fetch_t.

Parameters
lineList of capabilities
dataPOP data
Return values
0(always)

Definition at line 148 of file lib.c.

149 {
150  struct PopAccountData *adata = data;
151 
152  if (mutt_istr_startswith(line, "SASL"))
153  {
154  const char *c = mutt_str_skip_email_wsp(line + 4);
155  mutt_buffer_strcpy(&adata->auth_list, c);
156  }
157  else if (mutt_istr_startswith(line, "STLS"))
158  adata->cmd_stls = true;
159  else if (mutt_istr_startswith(line, "USER"))
160  adata->cmd_user = 1;
161  else if (mutt_istr_startswith(line, "UIDL"))
162  adata->cmd_uidl = 1;
163  else if (mutt_istr_startswith(line, "TOP"))
164  adata->cmd_top = 1;
165 
166  return 0;
167 }
bool cmd_stls
optional command STLS
Definition: adata.h:43
unsigned int cmd_user
optional command USER
Definition: adata.h:44
struct Buffer auth_list
list of auth mechanisms
Definition: adata.h:53
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
unsigned int cmd_uidl
optional command UIDL
Definition: adata.h:45
char * mutt_str_skip_email_wsp(const char *s)
Skip over whitespace as defined by RFC5322.
Definition: string.c:776
size_t mutt_istr_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix, ignoring case.
Definition: string.c:172
unsigned int cmd_top
optional command TOP
Definition: adata.h:46
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
POP-specific Account data -.
Definition: adata.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fetch_auth()

static int fetch_auth ( const char *  line,
void *  data 
)
static

Fetch list of the authentication mechanisms - Implements pop_fetch_t.

Parameters
lineList of authentication methods
dataPOP data
Return values
0(always)

Definition at line 175 of file lib.c.

176 {
177  struct PopAccountData *adata = data;
178 
179  if (!mutt_buffer_is_empty(&adata->auth_list))
180  {
181  mutt_buffer_addstr(&adata->auth_list, " ");
182  }
183  mutt_buffer_addstr(&adata->auth_list, line);
184 
185  return 0;
186 }
struct Buffer auth_list
list of auth mechanisms
Definition: adata.h:53
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
POP-specific Account data -.
Definition: adata.h:36
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:252
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pop_capabilities()

static int pop_capabilities ( struct PopAccountData adata,
int  mode 
)
static

Get capabilities from a POP server.

Parameters
adataPOP Account data
modeInitial capabilities
Return values
0Successful
-1Connection lost
-2Execution error

Definition at line 196 of file lib.c.

197 {
198  char buf[1024];
199 
200  /* don't check capabilities on reconnect */
201  if (adata->capabilities)
202  return 0;
203 
204  /* init capabilities */
205  if (mode == 0)
206  {
207  adata->cmd_capa = false;
208  adata->cmd_stls = false;
209  adata->cmd_user = 0;
210  adata->cmd_uidl = 0;
211  adata->cmd_top = 0;
212  adata->resp_codes = false;
213  adata->expire = true;
214  adata->login_delay = 0;
215  mutt_buffer_init(&adata->auth_list);
216  }
217 
218  /* Execute CAPA command */
219  if ((mode == 0) || adata->cmd_capa)
220  {
221  mutt_str_copy(buf, "CAPA\r\n", sizeof(buf));
222  switch (pop_fetch_data(adata, buf, NULL, fetch_capa, adata))
223  {
224  case 0:
225  {
226  adata->cmd_capa = true;
227  break;
228  }
229  case -1:
230  return -1;
231  }
232  }
233 
234  /* CAPA not supported, use defaults */
235  if ((mode == 0) && !adata->cmd_capa)
236  {
237  adata->cmd_user = 2;
238  adata->cmd_uidl = 2;
239  adata->cmd_top = 2;
240 
241  mutt_str_copy(buf, "AUTH\r\n", sizeof(buf));
242  if (pop_fetch_data(adata, buf, NULL, fetch_auth, adata) == -1)
243  return -1;
244  }
245 
246  /* Check capabilities */
247  if (mode == 2)
248  {
249  char *msg = NULL;
250 
251  if (!adata->expire)
252  msg = _("Unable to leave messages on server");
253  if (adata->cmd_top == 0)
254  msg = _("Command TOP is not supported by server");
255  if (adata->cmd_uidl == 0)
256  msg = _("Command UIDL is not supported by server");
257  if (msg && adata->cmd_capa)
258  {
259  mutt_error(msg);
260  return -2;
261  }
262  adata->capabilities = true;
263  }
264 
265  return 0;
266 }
bool resp_codes
server supports extended response codes
Definition: adata.h:47
#define mutt_error(...)
Definition: logging.h:88
bool cmd_stls
optional command STLS
Definition: adata.h:43
bool expire
expire is greater than 0
Definition: adata.h:48
#define _(a)
Definition: message.h:28
static int fetch_auth(const char *line, void *data)
Fetch list of the authentication mechanisms - Implements pop_fetch_t.
Definition: lib.c:175
unsigned int cmd_user
optional command USER
Definition: adata.h:44
struct Buffer auth_list
list of auth mechanisms
Definition: adata.h:53
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
static int fetch_capa(const char *line, void *data)
Parse CAPA output - Implements pop_fetch_t.
Definition: lib.c:148
unsigned int cmd_uidl
optional command UIDL
Definition: adata.h:45
bool cmd_capa
optional command CAPA
Definition: adata.h:42
bool capabilities
Definition: adata.h:40
time_t login_delay
minimal login delay capability
Definition: adata.h:52
unsigned int cmd_top
optional command TOP
Definition: adata.h:46
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
struct Buffer * mutt_buffer_init(struct Buffer *buf)
Initialise a new Buffer.
Definition: buffer.c:46
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pop_connect()

int pop_connect ( struct PopAccountData adata)

Open connection.

Parameters
adataPOP Account data
Return values
0Successful
-1Connection lost
-2Invalid response

Definition at line 275 of file lib.c.

276 {
277  char buf[1024];
278 
279  adata->status = POP_NONE;
280  if ((mutt_socket_open(adata->conn) < 0) ||
281  (mutt_socket_readln(buf, sizeof(buf), adata->conn) < 0))
282  {
283  mutt_error(_("Error connecting to server: %s"), adata->conn->account.host);
284  return -1;
285  }
286 
287  adata->status = POP_CONNECTED;
288 
289  if (!mutt_str_startswith(buf, "+OK"))
290  {
291  *adata->err_msg = '\0';
292  pop_error(adata, buf);
293  mutt_error("%s", adata->err_msg);
294  return -2;
295  }
296 
297  pop_apop_timestamp(adata, buf);
298 
299  return 0;
300 }
char err_msg[POP_CMD_RESPONSE]
Definition: adata.h:56
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:40
#define mutt_error(...)
Definition: logging.h:88
#define _(a)
Definition: message.h:28
struct Connection * conn
Definition: adata.h:38
int mutt_socket_open(struct Connection *conn)
Simple wrapper.
Definition: socket.c:76
char host[128]
Server to login to.
Definition: connaccount.h:53
No connected to server.
Definition: private.h:49
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:160
static void pop_error(struct PopAccountData *adata, char *msg)
Copy error message to err_msg buffer.
Definition: lib.c:124
void pop_apop_timestamp(struct PopAccountData *adata, char *buf)
Get the server timestamp for APOP authentication.
Definition: auth.c:207
unsigned int status
Definition: adata.h:39
#define mutt_socket_readln(buf, buflen, conn)
Definition: mutt_socket.h:36
Connected to server.
Definition: private.h:50
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pop_open_connection()

int pop_open_connection ( struct PopAccountData adata)

Open connection and authenticate.

Parameters
adataPOP Account data
Return values
0Successful
-1Connection lost
-2Invalid command or execution error
-3Authentication cancelled

Definition at line 310 of file lib.c.

311 {
312  char buf[1024];
313 
314  int rc = pop_connect(adata);
315  if (rc < 0)
316  return rc;
317 
318  rc = pop_capabilities(adata, 0);
319  if (rc == -1)
320  goto err_conn;
321  if (rc == -2)
322  return -2;
323 
324 #ifdef USE_SSL
325  /* Attempt STLS if available and desired. */
326  const bool c_ssl_force_tls = cs_subset_bool(NeoMutt->sub, "ssl_force_tls");
327  if ((adata->conn->ssf == 0) && (adata->cmd_stls || c_ssl_force_tls))
328  {
329  if (c_ssl_force_tls)
330  adata->use_stls = 2;
331  if (adata->use_stls == 0)
332  {
333  const enum QuadOption c_ssl_starttls =
334  cs_subset_quad(NeoMutt->sub, "ssl_starttls");
335  enum QuadOption ans =
336  query_quadoption(c_ssl_starttls, _("Secure connection with TLS?"));
337  if (ans == MUTT_ABORT)
338  return -2;
339  adata->use_stls = 1;
340  if (ans == MUTT_YES)
341  adata->use_stls = 2;
342  }
343  if (adata->use_stls == 2)
344  {
345  mutt_str_copy(buf, "STLS\r\n", sizeof(buf));
346  rc = pop_query(adata, buf, sizeof(buf));
347  // Clear any data after the STLS acknowledgement
348  mutt_socket_empty(adata->conn);
349  if (rc == -1)
350  goto err_conn;
351  if (rc != 0)
352  {
353  mutt_error("%s", adata->err_msg);
354  }
355  else if (mutt_ssl_starttls(adata->conn))
356  {
357  mutt_error(_("Could not negotiate TLS connection"));
358  return -2;
359  }
360  else
361  {
362  /* recheck capabilities after STLS completes */
363  rc = pop_capabilities(adata, 1);
364  if (rc == -1)
365  goto err_conn;
366  if (rc == -2)
367  return -2;
368  }
369  }
370  }
371 
372  if (c_ssl_force_tls && (adata->conn->ssf == 0))
373  {
374  mutt_error(_("Encrypted connection unavailable"));
375  return -2;
376  }
377 #endif
378 
379  rc = pop_authenticate(adata);
380  if (rc == -1)
381  goto err_conn;
382  if (rc == -3)
384  if (rc != 0)
385  return rc;
386 
387  /* recheck capabilities after authentication */
388  rc = pop_capabilities(adata, 2);
389  if (rc == -1)
390  goto err_conn;
391  if (rc == -2)
392  return -2;
393 
394  /* get total size of mailbox */
395  mutt_str_copy(buf, "STAT\r\n", sizeof(buf));
396  rc = pop_query(adata, buf, sizeof(buf));
397  if (rc == -1)
398  goto err_conn;
399  if (rc == -2)
400  {
401  mutt_error("%s", adata->err_msg);
402  return rc;
403  }
404 
405  unsigned int n = 0, size = 0;
406  sscanf(buf, "+OK %u %u", &n, &size);
407  adata->size = size;
408  return 0;
409 
410 err_conn:
411  adata->status = POP_DISCONNECTED;
412  mutt_error(_("Server closed connection"));
413  return -1;
414 }
unsigned int use_stls
Definition: adata.h:41
#define pop_query(adata, buf, buflen)
Definition: private.h:106
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
size_t size
Definition: adata.h:50
unsigned int ssf
Security strength factor, in bits (see below)
Definition: connection.h:41
#define mutt_error(...)
Definition: logging.h:88
bool cmd_stls
optional command STLS
Definition: adata.h:43
int pop_connect(struct PopAccountData *adata)
Open connection.
Definition: lib.c:275
#define _(a)
Definition: message.h:28
struct Connection * conn
Definition: adata.h:38
int pop_authenticate(struct PopAccountData *adata)
Authenticate with a POP server.
Definition: auth.c:428
Disconnected from server.
Definition: private.h:51
Container for Accounts, Notifications.
Definition: neomutt.h:36
QuadOption
Possible values for a quad-option.
Definition: quad.h:35
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: question.c:347
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:112
User aborted the question (with Ctrl-G)
Definition: quad.h:37
static int pop_capabilities(struct PopAccountData *adata, int mode)
Get capabilities from a POP server.
Definition: lib.c:196
unsigned int status
Definition: adata.h:39
enum QuadOption cs_subset_quad(const struct ConfigSubset *sub, const char *name)
Get a quad-value config item by name.
Definition: helpers.c:218
void mutt_socket_empty(struct Connection *conn)
Clear out any queued data.
Definition: socket.c:313
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
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
int mutt_ssl_starttls(struct Connection *conn)
Negotiate TLS over an already opened connection.
Definition: gnutls.c:1167
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pop_logout()

void pop_logout ( struct Mailbox m)

logout from a POP server

Parameters
mMailbox

Definition at line 420 of file lib.c.

421 {
422  struct PopAccountData *adata = pop_adata_get(m);
423 
424  if (adata->status == POP_CONNECTED)
425  {
426  int ret = 0;
427  char buf[1024];
428  mutt_message(_("Closing connection to POP server..."));
429 
430  if (m->readonly)
431  {
432  mutt_str_copy(buf, "RSET\r\n", sizeof(buf));
433  ret = pop_query(adata, buf, sizeof(buf));
434  }
435 
436  if (ret != -1)
437  {
438  mutt_str_copy(buf, "QUIT\r\n", sizeof(buf));
439  ret = pop_query(adata, buf, sizeof(buf));
440  }
441 
442  if (ret < 0)
443  mutt_debug(LL_DEBUG1, "Error closing POP connection\n");
444 
446  }
447 
448  adata->status = POP_DISCONNECTED;
449 }
#define pop_query(adata, buf, buflen)
Definition: private.h:106
#define _(a)
Definition: message.h:28
Disconnected from server.
Definition: private.h:51
struct PopAccountData * pop_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: adata.c:64
bool readonly
Don&#39;t allow changes to the mailbox.
Definition: mailbox.h:119
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:112
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
unsigned int status
Definition: adata.h:39
Log at debug level 1.
Definition: logging.h:40
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
Connected to server.
Definition: private.h:50
#define mutt_message(...)
Definition: logging.h:87
POP-specific Account data -.
Definition: adata.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pop_query_d()

int pop_query_d ( struct PopAccountData adata,
char *  buf,
size_t  buflen,
char *  msg 
)

Send data from buffer and receive answer to the same buffer.

Parameters
adataPOP Account data
bufBuffer to send/store data
buflenBuffer length
msgProgress message
Return values
0Successful
-1Connection lost
-2Invalid command or execution error

Definition at line 461 of file lib.c.

462 {
463  if (adata->status != POP_CONNECTED)
464  return -1;
465 
466  /* print msg instead of real command */
467  if (msg)
468  {
469  mutt_debug(MUTT_SOCK_LOG_CMD, "> %s", msg);
470  }
471 
473 
474  char *c = strpbrk(buf, " \r\n");
475  if (c)
476  *c = '\0';
477  snprintf(adata->err_msg, sizeof(adata->err_msg), "%s: ", buf);
478 
479  if (mutt_socket_readln_d(buf, buflen, adata->conn, MUTT_SOCK_LOG_FULL) < 0)
480  {
481  adata->status = POP_DISCONNECTED;
482  return -1;
483  }
484  if (mutt_str_startswith(buf, "+OK"))
485  return 0;
486 
487  pop_error(adata, buf);
488  return -2;
489 }
char err_msg[POP_CMD_RESPONSE]
Definition: adata.h:56
struct Connection * conn
Definition: adata.h:38
#define MUTT_SOCK_LOG_CMD
Definition: mutt_socket.h:29
Disconnected from server.
Definition: private.h:51
#define MUTT_SOCK_LOG_FULL
Definition: mutt_socket.h:31
#define mutt_socket_send_d(conn, buf, dbg)
Definition: mutt_socket.h:38
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:160
static void pop_error(struct PopAccountData *adata, char *msg)
Copy error message to err_msg buffer.
Definition: lib.c:124
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
unsigned int status
Definition: adata.h:39
Connected to server.
Definition: private.h:50
int mutt_socket_readln_d(char *buf, size_t buflen, struct Connection *conn, int dbg)
Read a line from a socket.
Definition: socket.c:246
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pop_fetch_data()

int pop_fetch_data ( struct PopAccountData adata,
const char *  query,
struct Progress progress,
pop_fetch_t  callback,
void *  data 
)

Read Headers with callback function.

Parameters
adataPOP Account data
queryPOP query to send to server
progressProgress bar
callbackFunction called for each header read
dataData to pass to the callback
Return values
0Successful
-1Connection lost
-2Invalid command or execution error
-3Error in callback(*line, *data)

This function calls callback(*line, *data) for each received line, callback(NULL, *data) if rewind(*data) needs, exits when fail or done.

Definition at line 506 of file lib.c.

508 {
509  char buf[1024];
510  long pos = 0;
511  size_t lenbuf = 0;
512 
513  mutt_str_copy(buf, query, sizeof(buf));
514  int rc = pop_query(adata, buf, sizeof(buf));
515  if (rc < 0)
516  return rc;
517 
518  char *inbuf = mutt_mem_malloc(sizeof(buf));
519 
520  while (true)
521  {
522  const int chunk =
523  mutt_socket_readln_d(buf, sizeof(buf), adata->conn, MUTT_SOCK_LOG_FULL);
524  if (chunk < 0)
525  {
526  adata->status = POP_DISCONNECTED;
527  rc = -1;
528  break;
529  }
530 
531  char *p = buf;
532  if (!lenbuf && (buf[0] == '.'))
533  {
534  if (buf[1] != '.')
535  break;
536  p++;
537  }
538 
539  mutt_str_copy(inbuf + lenbuf, p, sizeof(buf));
540  pos += chunk;
541 
542  /* cast is safe since we break out of the loop when chunk<=0 */
543  if ((size_t) chunk >= sizeof(buf))
544  {
545  lenbuf += strlen(p);
546  }
547  else
548  {
549  if (progress)
550  progress_update(progress, pos, -1);
551  if ((rc == 0) && (callback(inbuf, data) < 0))
552  rc = -3;
553  lenbuf = 0;
554  }
555 
556  mutt_mem_realloc(&inbuf, lenbuf + sizeof(buf));
557  }
558 
559  FREE(&inbuf);
560  return rc;
561 }
#define pop_query(adata, buf, buflen)
Definition: private.h:106
struct Connection * conn
Definition: adata.h:38
Disconnected from server.
Definition: private.h:51
#define MUTT_SOCK_LOG_FULL
Definition: mutt_socket.h:31
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
unsigned int status
Definition: adata.h:39
void progress_update(struct Progress *progress, size_t pos, int percent)
Update the state of the progress bar.
Definition: progress.c:175
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
#define FREE(x)
Definition: memory.h:40
int mutt_socket_readln_d(char *buf, size_t buflen, struct Connection *conn, int dbg)
Read a line from a socket.
Definition: socket.c:246
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ check_uidl()

static int check_uidl ( const char *  line,
void *  data 
)
static

find message with this UIDL and set refno - Implements pop_fetch_t

Parameters
lineString containing UIDL
dataPOP data
Return values
0Success
-1Error

Definition at line 570 of file lib.c.

571 {
572  if (!line || !data)
573  return -1;
574 
575  char *endp = NULL;
576 
577  errno = 0;
578  unsigned int index = strtoul(line, &endp, 10);
579  if (errno != 0)
580  return -1;
581  while (*endp == ' ')
582  endp++;
583 
584  struct Mailbox *m = data;
585  for (int i = 0; i < m->msg_count; i++)
586  {
587  struct PopEmailData *edata = pop_edata_get(m->emails[i]);
588  if (mutt_str_equal(edata->uid, endp))
589  {
590  edata->refno = index;
591  break;
592  }
593  }
594 
595  return 0;
596 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:904
struct Email ** emails
Array of Emails.
Definition: mailbox.h:99
int msg_count
Total number of messages.
Definition: mailbox.h:91
int refno
Message number on server.
Definition: edata.h:34
const char * uid
Definition: edata.h:33
A mailbox.
Definition: mailbox.h:81
POP-specific Email data -.
Definition: edata.h:31
struct PopEmailData * pop_edata_get(struct Email *e)
Get the private data for this Email.
Definition: edata.c:65
void * edata
Driver-specific data.
Definition: email.h:111
int index
The absolute (unsorted) message number.
Definition: email.h:86
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pop_reconnect()

int pop_reconnect ( struct Mailbox m)

reconnect and verify indexes if connection was lost

Parameters
mMailbox
Return values
0Success
-1Error

Definition at line 604 of file lib.c.

605 {
606  struct PopAccountData *adata = pop_adata_get(m);
607 
608  if (adata->status == POP_CONNECTED)
609  return 0;
610 
611  while (true)
612  {
613  mutt_socket_close(adata->conn);
614 
615  int ret = pop_open_connection(adata);
616  if (ret == 0)
617  {
618  struct Progress *progress =
619  progress_new(_("Verifying message indexes..."), MUTT_PROGRESS_NET, 0);
620 
621  for (int i = 0; i < m->msg_count; i++)
622  {
623  struct PopEmailData *edata = pop_edata_get(m->emails[i]);
624  edata->refno = -1;
625  }
626 
627  ret = pop_fetch_data(adata, "UIDL\r\n", progress, check_uidl, m);
628  progress_free(&progress);
629  if (ret == -2)
630  {
631  mutt_error("%s", adata->err_msg);
632  }
633  }
634 
635  if (ret == 0)
636  return 0;
637 
638  pop_logout(m);
639 
640  if (ret < -1)
641  return -1;
642 
643  const enum QuadOption c_pop_reconnect =
644  cs_subset_quad(NeoMutt->sub, "pop_reconnect");
645  if (query_quadoption(c_pop_reconnect,
646  _("Connection lost. Reconnect to POP server?")) != MUTT_YES)
647  {
648  return -1;
649  }
650  }
651 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:99
static int check_uidl(const char *line, void *data)
find message with this UIDL and set refno - Implements pop_fetch_t
Definition: lib.c:570
int msg_count
Total number of messages.
Definition: mailbox.h:91
char err_msg[POP_CMD_RESPONSE]
Definition: adata.h:56
#define mutt_error(...)
Definition: logging.h:88
int pop_open_connection(struct PopAccountData *adata)
Open connection and authenticate.
Definition: lib.c:310
#define _(a)
Definition: message.h:28
struct Connection * conn
Definition: adata.h:38
int refno
Message number on server.
Definition: edata.h:34
struct PopAccountData * pop_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: adata.c:64
Container for Accounts, Notifications.
Definition: neomutt.h:36
A Progress Bar.
Definition: progress.c:47
QuadOption
Possible values for a quad-option.
Definition: quad.h:35
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: question.c:347
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
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
Progress tracks bytes, according to $net_inc
Definition: lib.h:48
unsigned int status
Definition: adata.h:39
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
void progress_free(struct Progress **ptr)
Free a Progress Bar.
Definition: progress.c:228
POP-specific Email data -.
Definition: edata.h:31
struct PopEmailData * pop_edata_get(struct Email *e)
Get the private data for this Email.
Definition: edata.c:65
void * edata
Driver-specific data.
Definition: email.h:111
Connected to server.
Definition: private.h:50
struct Progress * progress_new(const char *msg, enum ProgressType type, size_t size)
Create a new Progress Bar.
Definition: progress.c:246
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
POP-specific Account data -.
Definition: adata.h:36
void pop_logout(struct Mailbox *m)
logout from a POP server
Definition: lib.c:420
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function: