NeoMutt  2020-04-24
Teaching an old dog new tricks
DOXYGEN
pop_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 "pop_private.h"
#include "mutt/lib.h"
#include "config/lib.h"
#include "email/lib.h"
#include "core/lib.h"
#include "conn/lib.h"
#include "init.h"
#include "mutt_account.h"
#include "mutt_logging.h"
#include "mutt_socket.h"
#include "progress.h"
#include "globals.h"
+ Include dependency graph for pop_lib.c:

Go to the source code of this file.

Functions

const char * pop_get_field (enum ConnAccountField field)
 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...
 
struct PopEmailDatapop_edata_get (struct Email *e)
 Get the private data for this Email. 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...
 
struct PopAccountDatapop_adata_get (struct Mailbox *m)
 Get the Account data for this mailbox. More...
 

Variables

char * C_PopOauthRefreshCommand
 Config: (pop) External command to generate OAUTH refresh token. More...
 
char * C_PopPass
 Config: (pop) Password of the POP server. More...
 
unsigned char C_PopReconnect
 Config: (pop) Reconnect to the server is the connection is lost. More...
 
char * C_PopUser
 Config: (pop) Username of the POP server. 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 pop_lib.c.

Function Documentation

◆ pop_get_field()

const char* pop_get_field ( enum ConnAccountField  field)

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

Definition at line 62 of file pop_lib.c.

63 {
64  switch (field)
65  {
66  case MUTT_CA_LOGIN:
67  case MUTT_CA_USER:
68  return C_PopUser;
69  case MUTT_CA_PASS:
70  return C_PopPass;
71  case MUTT_CA_OAUTH_CMD:
73  case MUTT_CA_HOST:
74  default:
75  return NULL;
76  }
77 }
char * C_PopUser
Config: (pop) Username of the POP server.
Definition: pop_lib.c:57
Password.
Definition: connaccount.h:36
User name.
Definition: connaccount.h:35
char * C_PopOauthRefreshCommand
Config: (pop) External command to generate OAUTH refresh token.
Definition: pop_lib.c:54
OAuth refresh command.
Definition: connaccount.h:37
char * C_PopPass
Config: (pop) Password of the POP server.
Definition: pop_lib.c:55
Login name.
Definition: connaccount.h:34
Server name.
Definition: connaccount.h:33
+ 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 88 of file pop_lib.c.

89 {
90  /* Defaults */
91  cac->flags = 0;
92  cac->type = MUTT_ACCT_TYPE_POP;
93  cac->port = 0;
94  cac->service = "pop";
95  cac->get_field = pop_get_field;
96 
97  struct Url *url = url_parse(path);
98 
99  if (!url || ((url->scheme != U_POP) && (url->scheme != U_POPS)) ||
100  !url->host || (mutt_account_fromurl(cac, url) < 0))
101  {
102  url_free(&url);
103  mutt_error(_("Invalid POP URL: %s"), path);
104  return -1;
105  }
106 
107  if (url->scheme == U_POPS)
108  cac->flags |= MUTT_ACCT_SSL;
109 
110  struct servent *service =
111  getservbyname((url->scheme == U_POP) ? "pop3" : "pop3s", "tcp");
112  if (cac->port == 0)
113  {
114  if (service)
115  cac->port = ntohs(service->s_port);
116  else
117  cac->port = (url->scheme == U_POP) ? POP_PORT : POP_SSL_PORT;
118  }
119 
120  url_free(&url);
121  return 0;
122 }
int mutt_account_fromurl(struct ConnAccount *cac, const struct Url *url)
Fill ConnAccount with information from url.
Definition: mutt_account.c:43
const char * pop_get_field(enum ConnAccountField field)
Get connection login credentials - Implements ConnAccount::get_field()
Definition: pop_lib.c:62
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:66
enum UrlScheme scheme
Scheme, e.g. U_SMTPS.
Definition: url.h:68
#define _(a)
Definition: message.h:28
#define POP_PORT
Definition: pop_private.h:36
void url_free(struct Url **ptr)
Free the contents of a URL.
Definition: url.c:121
const char *(* get_field)(enum ConnAccountField field)
Function to get some login credentials.
Definition: connaccount.h:67
unsigned short port
Port to connect to.
Definition: connaccount.h:57
unsigned char type
Connection type, e.g. MUTT_ACCT_TYPE_IMAP.
Definition: connaccount.h:58
char * host
Host.
Definition: url.h:71
const char * service
Name of the service, e.g. "imap".
Definition: connaccount.h:60
char * path
Path.
Definition: url.h:73
Pop Account.
Definition: mutt_account.h:38
Url is pop://.
Definition: url.h:36
#define mutt_error(...)
Definition: logging.h:84
#define MUTT_ACCT_SSL
Account uses SSL/TLS.
Definition: connaccount.h:46
#define POP_SSL_PORT
Definition: pop_private.h:37
Url is pops://.
Definition: url.h:37
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:232
+ 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 129 of file pop_lib.c.

130 {
131  char *t = strchr(adata->err_msg, '\0');
132  char *c = msg;
133 
134  size_t plen = mutt_str_startswith(msg, "-ERR ", CASE_MATCH);
135  if (plen != 0)
136  {
137  char *c2 = mutt_str_skip_email_wsp(msg + plen);
138 
139  if (*c2)
140  c = c2;
141  }
142 
143  mutt_str_strfcpy(t, c, sizeof(adata->err_msg) - strlen(adata->err_msg));
145 }
char err_msg[POP_CMD_RESPONSE]
Definition: pop_private.h:98
static size_t plen
Length of cached packet.
Definition: pgppacket.c:39
Match case when comparing strings.
Definition: string2.h:67
void mutt_str_remove_trailing_ws(char *s)
Trim trailing whitespace from a string.
Definition: string.c:760
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:776
char * mutt_str_skip_email_wsp(const char *s)
Skip over whitespace as defined by RFC5322.
Definition: string.c:802
size_t mutt_str_startswith(const char *str, const char *prefix, enum CaseSensitivity cs)
Check whether a string starts with a prefix.
Definition: string.c:168
+ 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 153 of file pop_lib.c.

154 {
155  struct PopAccountData *adata = data;
156 
157  if (mutt_str_startswith(line, "SASL", CASE_IGNORE))
158  {
159  const char *c = mutt_str_skip_email_wsp(line + 4);
160  mutt_buffer_strcpy(&adata->auth_list, c);
161  }
162  else if (mutt_str_startswith(line, "STLS", CASE_IGNORE))
163  adata->cmd_stls = true;
164  else if (mutt_str_startswith(line, "USER", CASE_IGNORE))
165  adata->cmd_user = 1;
166  else if (mutt_str_startswith(line, "UIDL", CASE_IGNORE))
167  adata->cmd_uidl = 1;
168  else if (mutt_str_startswith(line, "TOP", CASE_IGNORE))
169  adata->cmd_top = 1;
170 
171  return 0;
172 }
bool cmd_stls
optional command STLS
Definition: pop_private.h:85
unsigned int cmd_user
optional command USER
Definition: pop_private.h:86
struct Buffer auth_list
list of auth mechanisms
Definition: pop_private.h:95
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
unsigned int cmd_uidl
optional command UIDL
Definition: pop_private.h:87
Ignore case when comparing strings.
Definition: string2.h:68
char * mutt_str_skip_email_wsp(const char *s)
Skip over whitespace as defined by RFC5322.
Definition: string.c:802
unsigned int cmd_top
optional command TOP
Definition: pop_private.h:88
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
size_t mutt_str_startswith(const char *str, const char *prefix, enum CaseSensitivity cs)
Check whether a string starts with a prefix.
Definition: string.c:168
POP-specific Account data -.
Definition: pop_private.h:78
int const char int line
Definition: acutest.h:617
+ 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 180 of file pop_lib.c.

181 {
182  struct PopAccountData *adata = data;
183 
184  if (!mutt_buffer_is_empty(&adata->auth_list))
185  {
186  mutt_buffer_addstr(&adata->auth_list, " ");
187  }
189 
190  return 0;
191 }
struct Buffer auth_list
list of auth mechanisms
Definition: pop_private.h:95
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: pop_private.h:78
int const char int line
Definition: acutest.h:617
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 201 of file pop_lib.c.

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

◆ pop_edata_get()

struct PopEmailData* pop_edata_get ( struct Email e)

Get the private data for this Email.

Parameters
eEmail
Return values
ptrPrivate Email data

Definition at line 278 of file pop_lib.c.

279 {
280  if (!e)
281  return NULL;
282  return e->edata;
283 }
void * edata
Driver-specific data.
Definition: email.h:106
+ 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 292 of file pop_lib.c.

293 {
294  char buf[1024];
295 
296  adata->status = POP_NONE;
297  if ((mutt_socket_open(adata->conn) < 0) ||
298  (mutt_socket_readln(buf, sizeof(buf), adata->conn) < 0))
299  {
300  mutt_error(_("Error connecting to server: %s"), adata->conn->account.host);
301  return -1;
302  }
303 
304  adata->status = POP_CONNECTED;
305 
306  if (!mutt_str_startswith(buf, "+OK", CASE_MATCH))
307  {
308  *adata->err_msg = '\0';
309  pop_error(adata, buf);
310  mutt_error("%s", adata->err_msg);
311  return -2;
312  }
313 
314  pop_apop_timestamp(adata, buf);
315 
316  return 0;
317 }
char err_msg[POP_CMD_RESPONSE]
Definition: pop_private.h:98
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:36
No connected to server.
Definition: pop_private.h:50
static void pop_error(struct PopAccountData *adata, char *msg)
Copy error message to err_msg buffer.
Definition: pop_lib.c:129
#define _(a)
Definition: message.h:28
struct Connection * conn
Definition: pop_private.h:80
Match case when comparing strings.
Definition: string2.h:67
int mutt_socket_open(struct Connection *conn)
Simple wrapper.
Definition: socket.c:74
char host[128]
Server to login to.
Definition: connaccount.h:53
void pop_apop_timestamp(struct PopAccountData *adata, char *buf)
Get the server timestamp for APOP authentication.
Definition: pop_auth.c:211
Connected to server.
Definition: pop_private.h:51
unsigned int status
Definition: pop_private.h:81
size_t mutt_str_startswith(const char *str, const char *prefix, enum CaseSensitivity cs)
Check whether a string starts with a prefix.
Definition: string.c:168
#define mutt_socket_readln(buf, buflen, conn)
Definition: mutt_socket.h:36
#define mutt_error(...)
Definition: logging.h:84
+ 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 327 of file pop_lib.c.

328 {
329  char buf[1024];
330 
331  int rc = pop_connect(adata);
332  if (rc < 0)
333  return rc;
334 
335  rc = pop_capabilities(adata, 0);
336  if (rc == -1)
337  goto err_conn;
338  if (rc == -2)
339  return -2;
340 
341 #ifdef USE_SSL
342  /* Attempt STLS if available and desired. */
343  if (!adata->conn->ssf && (adata->cmd_stls || C_SslForceTls))
344  {
345  if (C_SslForceTls)
346  adata->use_stls = 2;
347  if (adata->use_stls == 0)
348  {
349  enum QuadOption ans =
350  query_quadoption(C_SslStarttls, _("Secure connection with TLS?"));
351  if (ans == MUTT_ABORT)
352  return -2;
353  adata->use_stls = 1;
354  if (ans == MUTT_YES)
355  adata->use_stls = 2;
356  }
357  if (adata->use_stls == 2)
358  {
359  mutt_str_strfcpy(buf, "STLS\r\n", sizeof(buf));
360  rc = pop_query(adata, buf, sizeof(buf));
361  if (rc == -1)
362  goto err_conn;
363  if (rc != 0)
364  {
365  mutt_error("%s", adata->err_msg);
366  }
367  else if (mutt_ssl_starttls(adata->conn))
368  {
369  mutt_error(_("Could not negotiate TLS connection"));
370  return -2;
371  }
372  else
373  {
374  /* recheck capabilities after STLS completes */
375  rc = pop_capabilities(adata, 1);
376  if (rc == -1)
377  goto err_conn;
378  if (rc == -2)
379  return -2;
380  }
381  }
382  }
383 
384  if (C_SslForceTls && !adata->conn->ssf)
385  {
386  mutt_error(_("Encrypted connection unavailable"));
387  return -2;
388  }
389 #endif
390 
391  rc = pop_authenticate(adata);
392  if (rc == -1)
393  goto err_conn;
394  if (rc == -3)
396  if (rc != 0)
397  return rc;
398 
399  /* recheck capabilities after authentication */
400  rc = pop_capabilities(adata, 2);
401  if (rc == -1)
402  goto err_conn;
403  if (rc == -2)
404  return -2;
405 
406  /* get total size of mailbox */
407  mutt_str_strfcpy(buf, "STAT\r\n", sizeof(buf));
408  rc = pop_query(adata, buf, sizeof(buf));
409  if (rc == -1)
410  goto err_conn;
411  if (rc == -2)
412  {
413  mutt_error("%s", adata->err_msg);
414  return rc;
415  }
416 
417  unsigned int n = 0, size = 0;
418  sscanf(buf, "+OK %u %u", &n, &size);
419  adata->size = size;
420  return 0;
421 
422 err_conn:
423  adata->status = POP_DISCONNECTED;
424  mutt_error(_("Server closed connection"));
425  return -1;
426 }
unsigned int use_stls
Definition: pop_private.h:83
char err_msg[POP_CMD_RESPONSE]
Definition: pop_private.h:98
unsigned int ssf
Security strength factor, in bits.
Definition: connection.h:37
static int pop_capabilities(struct PopAccountData *adata, int mode)
Get capabilities from a POP server.
Definition: pop_lib.c:201
#define pop_query(adata, buf, buflen)
Definition: pop_private.h:142
bool cmd_stls
optional command STLS
Definition: pop_private.h:85
User aborted the question (with Ctrl-G)
Definition: quad.h:38
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:1112
int pop_authenticate(struct PopAccountData *adata)
Authenticate with a POP server.
Definition: pop_auth.c:408
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
#define _(a)
Definition: message.h:28
struct Connection * conn
Definition: pop_private.h:80
WHERE bool C_SslForceTls
Config: (ssl) Require TLS encryption for all connections.
Definition: globals.h:231
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:113
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:776
Disconnected from server.
Definition: pop_private.h:52
unsigned int status
Definition: pop_private.h:81
int n
Definition: acutest.h:492
#define mutt_error(...)
Definition: logging.h:84
int mutt_ssl_starttls(struct Connection *conn)
Negotiate TLS over an already opened connection.
Definition: gnutls.c:1135
QuadOption
Possible values for a quad-option.
Definition: quad.h:36
WHERE unsigned char C_SslStarttls
Config: (ssl) Use STARTTLS on servers advertising the capability.
Definition: globals.h:187
int pop_connect(struct PopAccountData *adata)
Open connection.
Definition: pop_lib.c:292
+ 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 432 of file pop_lib.c.

433 {
434  struct PopAccountData *adata = pop_adata_get(m);
435 
436  if (adata->status == POP_CONNECTED)
437  {
438  int ret = 0;
439  char buf[1024];
440  mutt_message(_("Closing connection to POP server..."));
441 
442  if (m->readonly)
443  {
444  mutt_str_strfcpy(buf, "RSET\r\n", sizeof(buf));
445  ret = pop_query(adata, buf, sizeof(buf));
446  }
447 
448  if (ret != -1)
449  {
450  mutt_str_strfcpy(buf, "QUIT\r\n", sizeof(buf));
451  ret = pop_query(adata, buf, sizeof(buf));
452  }
453 
454  if (ret < 0)
455  mutt_debug(LL_DEBUG1, "Error closing POP connection\n");
456 
458  }
459 
460  adata->status = POP_DISCONNECTED;
461 }
#define pop_query(adata, buf, buflen)
Definition: pop_private.h:142
#define mutt_message(...)
Definition: logging.h:83
struct PopAccountData * pop_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: pop_lib.c:666
#define _(a)
Definition: message.h:28
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:113
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:776
Disconnected from server.
Definition: pop_private.h:52
Connected to server.
Definition: pop_private.h:51
unsigned int status
Definition: pop_private.h:81
Log at debug level 1.
Definition: logging.h:40
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
POP-specific Account data -.
Definition: pop_private.h:78
+ 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 473 of file pop_lib.c.

474 {
475  if (adata->status != POP_CONNECTED)
476  return -1;
477 
478  /* print msg instead of real command */
479  if (msg)
480  {
481  mutt_debug(MUTT_SOCK_LOG_CMD, "> %s", msg);
482  }
483 
485 
486  char *c = strpbrk(buf, " \r\n");
487  if (c)
488  *c = '\0';
489  snprintf(adata->err_msg, sizeof(adata->err_msg), "%s: ", buf);
490 
491  if (mutt_socket_readln_d(buf, buflen, adata->conn, MUTT_SOCK_LOG_FULL) < 0)
492  {
493  adata->status = POP_DISCONNECTED;
494  return -1;
495  }
496  if (mutt_str_startswith(buf, "+OK", CASE_MATCH))
497  return 0;
498 
499  pop_error(adata, buf);
500  return -2;
501 }
char err_msg[POP_CMD_RESPONSE]
Definition: pop_private.h:98
static void pop_error(struct PopAccountData *adata, char *msg)
Copy error message to err_msg buffer.
Definition: pop_lib.c:129
struct Connection * conn
Definition: pop_private.h:80
Match case when comparing strings.
Definition: string2.h:67
#define MUTT_SOCK_LOG_CMD
Definition: mutt_socket.h:29
#define MUTT_SOCK_LOG_FULL
Definition: mutt_socket.h:31
#define mutt_socket_send_d(conn, buf, dbg)
Definition: mutt_socket.h:38
Disconnected from server.
Definition: pop_private.h:52
Connected to server.
Definition: pop_private.h:51
unsigned int status
Definition: pop_private.h:81
size_t mutt_str_startswith(const char *str, const char *prefix, enum CaseSensitivity cs)
Check whether a string starts with a prefix.
Definition: string.c:168
int mutt_socket_readln_d(char *buf, size_t buflen, struct Connection *conn, int dbg)
Read a line from a socket.
Definition: socket.c:244
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
+ 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 518 of file pop_lib.c.

520 {
521  char buf[1024];
522  long pos = 0;
523  size_t lenbuf = 0;
524 
525  mutt_str_strfcpy(buf, query, sizeof(buf));
526  int rc = pop_query(adata, buf, sizeof(buf));
527  if (rc < 0)
528  return rc;
529 
530  char *inbuf = mutt_mem_malloc(sizeof(buf));
531 
532  while (true)
533  {
534  const int chunk =
535  mutt_socket_readln_d(buf, sizeof(buf), adata->conn, MUTT_SOCK_LOG_FULL);
536  if (chunk < 0)
537  {
538  adata->status = POP_DISCONNECTED;
539  rc = -1;
540  break;
541  }
542 
543  char *p = buf;
544  if (!lenbuf && (buf[0] == '.'))
545  {
546  if (buf[1] != '.')
547  break;
548  p++;
549  }
550 
551  mutt_str_strfcpy(inbuf + lenbuf, p, sizeof(buf));
552  pos += chunk;
553 
554  /* cast is safe since we break out of the loop when chunk<=0 */
555  if ((size_t) chunk >= sizeof(buf))
556  {
557  lenbuf += strlen(p);
558  }
559  else
560  {
561  if (progress)
562  mutt_progress_update(progress, pos, -1);
563  if ((rc == 0) && (callback(inbuf, data) < 0))
564  rc = -3;
565  lenbuf = 0;
566  }
567 
568  mutt_mem_realloc(&inbuf, lenbuf + sizeof(buf));
569  }
570 
571  FREE(&inbuf);
572  return rc;
573 }
#define pop_query(adata, buf, buflen)
Definition: pop_private.h:142
struct Connection * conn
Definition: pop_private.h:80
#define MUTT_SOCK_LOG_FULL
Definition: mutt_socket.h:31
void mutt_progress_update(struct Progress *progress, size_t pos, int percent)
Update the state of the progress bar.
Definition: progress.c:212
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
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:776
Disconnected from server.
Definition: pop_private.h:52
unsigned int status
Definition: pop_private.h:81
#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:244
+ 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 582 of file pop_lib.c.

583 {
584  if (!line || !data)
585  return -1;
586 
587  char *endp = NULL;
588 
589  errno = 0;
590  unsigned int index = strtoul(line, &endp, 10);
591  if (errno != 0)
592  return -1;
593  while (*endp == ' ')
594  endp++;
595 
596  struct Mailbox *m = data;
597  for (int i = 0; i < m->msg_count; i++)
598  {
599  struct PopEmailData *edata = pop_edata_get(m->emails[i]);
600  if (mutt_str_strcmp(edata->uid, endp) == 0)
601  {
602  edata->refno = index;
603  break;
604  }
605  }
606 
607  return 0;
608 }
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: pop_private.h:108
struct PopEmailData * pop_edata_get(struct Email *e)
Get the private data for this Email.
Definition: pop_lib.c:278
const char * uid
Definition: pop_private.h:107
A mailbox.
Definition: mailbox.h:81
POP-specific Email data -.
Definition: pop_private.h:105
void * edata
Driver-specific data.
Definition: email.h:106
int index
The absolute (unsorted) message number.
Definition: email.h:85
int const char int line
Definition: acutest.h:617
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:641
+ 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 616 of file pop_lib.c.

617 {
618  struct PopAccountData *adata = pop_adata_get(m);
619 
620  if (adata->status == POP_CONNECTED)
621  return 0;
622 
623  while (true)
624  {
625  mutt_socket_close(adata->conn);
626 
627  int ret = pop_open_connection(adata);
628  if (ret == 0)
629  {
630  struct Progress progress;
631  mutt_progress_init(&progress, _("Verifying message indexes..."), MUTT_PROGRESS_NET, 0);
632 
633  for (int i = 0; i < m->msg_count; i++)
634  {
635  struct PopEmailData *edata = pop_edata_get(m->emails[i]);
636  edata->refno = -1;
637  }
638 
639  ret = pop_fetch_data(adata, "UIDL\r\n", &progress, check_uidl, m);
640  if (ret == -2)
641  {
642  mutt_error("%s", adata->err_msg);
643  }
644  }
645  if (ret == 0)
646  return 0;
647 
648  pop_logout(m);
649 
650  if (ret < -1)
651  return -1;
652 
654  _("Connection lost. Reconnect to POP server?")) != MUTT_YES)
655  {
656  return -1;
657  }
658  }
659 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:99
Progress tracks bytes, according to C_NetInc.
Definition: progress.h:43
int msg_count
Total number of messages.
Definition: mailbox.h:91
char err_msg[POP_CMD_RESPONSE]
Definition: pop_private.h:98
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:1112
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
static int check_uidl(const char *line, void *data)
find message with this UIDL and set refno - Implements pop_fetch_t
Definition: pop_lib.c:582
struct PopAccountData * pop_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: pop_lib.c:666
#define _(a)
Definition: message.h:28
struct Connection * conn
Definition: pop_private.h:80
int refno
Message number on server.
Definition: pop_private.h:108
struct PopEmailData * pop_edata_get(struct Email *e)
Get the private data for this Email.
Definition: pop_lib.c:278
A progress bar.
Definition: progress.h:49
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
void mutt_progress_init(struct Progress *progress, const char *msg, enum ProgressType type, size_t size)
Set up a progress bar.
Definition: progress.c:153
Connected to server.
Definition: pop_private.h:51
unsigned int status
Definition: pop_private.h:81
int mutt_socket_close(struct Connection *conn)
Close a socket.
Definition: socket.c:95
POP-specific Email data -.
Definition: pop_private.h:105
void * edata
Driver-specific data.
Definition: email.h:106
#define mutt_error(...)
Definition: logging.h:84
unsigned char C_PopReconnect
Config: (pop) Reconnect to the server is the connection is lost.
Definition: pop_lib.c:56
POP-specific Account data -.
Definition: pop_private.h:78
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: pop_lib.c:518
int pop_open_connection(struct PopAccountData *adata)
Open connection and authenticate.
Definition: pop_lib.c:327
void pop_logout(struct Mailbox *m)
logout from a POP server
Definition: pop_lib.c:432
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pop_adata_get()

struct PopAccountData* pop_adata_get ( struct Mailbox m)

Get the Account data for this mailbox.

Parameters
mMailbox
Return values
ptrPopAccountData

Definition at line 666 of file pop_lib.c.

667 {
668  if (!m || (m->type != MUTT_POP))
669  return NULL;
670  struct Account *a = m->account;
671  if (!a)
672  return NULL;
673  return a->adata;
674 }
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
A group of associated Mailboxes.
Definition: account.h:36
&#39;POP3&#39; Mailbox type
Definition: mailbox.h:55
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
struct Account * account
Account that owns this Mailbox.
Definition: mailbox.h:131
+ Here is the caller graph for this function:

Variable Documentation

◆ C_PopOauthRefreshCommand

char* C_PopOauthRefreshCommand

Config: (pop) External command to generate OAUTH refresh token.

Definition at line 54 of file pop_lib.c.

◆ C_PopPass

char* C_PopPass

Config: (pop) Password of the POP server.

Definition at line 55 of file pop_lib.c.

◆ C_PopReconnect

unsigned char C_PopReconnect

Config: (pop) Reconnect to the server is the connection is lost.

Definition at line 56 of file pop_lib.c.

◆ C_PopUser

char* C_PopUser

Config: (pop) Username of the POP server.

Definition at line 57 of file pop_lib.c.