NeoMutt  2021-02-05-666-ge300cd
Teaching an old dog new tricks
DOXYGEN

Read from a socket Connection. More...

+ Collaboration diagram for read():

Functions

static int tls_socket_read (struct Connection *conn, char *buf, size_t count)
 Read data from a TLS socket - Implements Connection::read() -. More...
 
static int ssl_socket_read (struct Connection *conn, char *buf, size_t count)
 Read data from an SSL socket - Implements Connection::read() -. More...
 
int raw_socket_read (struct Connection *conn, char *buf, size_t count)
 Read data from a socket - Implements Connection::read() -. More...
 
static int mutt_sasl_conn_read (struct Connection *conn, char *buf, size_t count)
 Read data from an SASL connection - Implements Connection::read() -. More...
 
static int tunnel_socket_read (struct Connection *conn, char *buf, size_t count)
 Read data from a tunnel socket - Implements Connection::read() -. More...
 
static int zstrm_read (struct Connection *conn, char *buf, size_t len)
 Read compressed data from a socket - Implements Connection::read() -. More...
 

Variables

int(* SaslSockData::read )(struct Connection *conn, char *buf, size_t count)
 Read from a socket Connection - Implements Connection::read() -. More...
 

Detailed Description

Read from a socket Connection.

Parameters
connConnection to a server
bufBuffer to store the data
countNumber of bytes to read
Return values
>0Success, number of bytes read
-1Error, see errno

Function Documentation

◆ tls_socket_read()

static int tls_socket_read ( struct Connection conn,
char *  buf,
size_t  count 
)
static

Read data from a TLS socket - Implements Connection::read() -.

Definition at line 1067 of file gnutls.c.

1068 {
1069  struct TlsSockData *data = conn->sockdata;
1070  if (!data)
1071  {
1072  mutt_error(_("Error: no TLS socket open"));
1073  return -1;
1074  }
1075 
1076  int rc;
1077  do
1078  {
1079  rc = gnutls_record_recv(data->state, buf, count);
1080  } while ((rc == GNUTLS_E_AGAIN) || (rc == GNUTLS_E_INTERRUPTED));
1081 
1082  if (rc < 0)
1083  {
1084  mutt_error("tls_socket_read (%s)", gnutls_strerror(rc));
1085  return -1;
1086  }
1087 
1088  return rc;
1089 }
#define mutt_error(...)
Definition: logging.h:88
void * sockdata
Backend-specific socket data.
Definition: connection.h:46
#define _(a)
Definition: message.h:28
gnutls_session_t state
Definition: gnutls.c:81
TLS socket data -.
Definition: gnutls.c:79
+ Here is the caller graph for this function:

◆ ssl_socket_read()

static int ssl_socket_read ( struct Connection conn,
char *  buf,
size_t  count 
)
static

Read data from an SSL socket - Implements Connection::read() -.

Definition at line 1347 of file openssl.c.

1348 {
1349  struct SslSockData *data = sockdata(conn);
1350  int rc;
1351 
1352  rc = SSL_read(data->ssl, buf, count);
1353  if ((rc <= 0) || (errno == EINTR))
1354  {
1355  if (errno == EINTR)
1356  {
1357  rc = -1;
1358  }
1359  data->isopen = 0;
1360  ssl_err(data, rc);
1361  }
1362 
1363  return rc;
1364 }
static void ssl_err(struct SslSockData *data, int err)
Display an SSL error message.
Definition: openssl.c:238
static struct SslSockData * sockdata(struct Connection *conn)
Get a Connection&#39;s socket data.
Definition: openssl.c:1198
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ raw_socket_read()

int raw_socket_read ( struct Connection conn,
char *  buf,
size_t  count 
)

Read data from a socket - Implements Connection::read() -.

Definition at line 267 of file raw.c.

268 {
269  int rc;
270 
272  do
273  {
274  rc = read(conn->fd, buf, count);
275  } while (rc < 0 && (errno == EINTR));
276 
277  if (rc < 0)
278  {
279  mutt_error(_("Error talking to %s (%s)"), conn->account.host, strerror(errno));
280  SigInt = false;
281  }
283 
284  if (SigInt)
285  {
286  mutt_error(_("Connection to %s has been aborted"), conn->account.host);
287  SigInt = false;
288  rc = -1;
289  }
290 
291  return rc;
292 }
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:40
#define mutt_error(...)
Definition: logging.h:88
WHERE SIG_ATOMIC_VOLATILE_T SigInt
true after SIGINT is received
Definition: mutt_globals.h:67
#define _(a)
Definition: message.h:28
void mutt_sig_allow_interrupt(bool allow)
Allow/disallow Ctrl-C (SIGINT)
Definition: signal.c:238
char host[128]
Server to login to.
Definition: connaccount.h:53
int fd
Socket file descriptor.
Definition: connection.h:44
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_sasl_conn_read()

static int mutt_sasl_conn_read ( struct Connection conn,
char *  buf,
size_t  count 
)
static

Read data from an SASL connection - Implements Connection::read() -.

Definition at line 467 of file sasl.c.

468 {
469  int rc;
470  unsigned int olen;
471 
472  struct SaslSockData *sasldata = conn->sockdata;
473 
474  /* if we still have data in our read buffer, copy it into buf */
475  if (sasldata->blen > sasldata->bpos)
476  {
477  olen = ((sasldata->blen - sasldata->bpos) > count) ?
478  count :
479  sasldata->blen - sasldata->bpos;
480 
481  memcpy(buf, sasldata->buf + sasldata->bpos, olen);
482  sasldata->bpos += olen;
483 
484  return olen;
485  }
486 
487  conn->sockdata = sasldata->sockdata;
488 
489  sasldata->bpos = 0;
490  sasldata->blen = 0;
491 
492  /* and decode the result, if necessary */
493  if (*sasldata->ssf != 0)
494  {
495  do
496  {
497  /* call the underlying read function to fill the buffer */
498  rc = sasldata->read(conn, buf, count);
499  if (rc <= 0)
500  goto out;
501 
502  rc = sasl_decode(sasldata->saslconn, buf, rc, &sasldata->buf, &sasldata->blen);
503  if (rc != SASL_OK)
504  {
505  mutt_debug(LL_DEBUG1, "SASL decode failed: %s\n", sasl_errstring(rc, NULL, NULL));
506  goto out;
507  }
508  } while (sasldata->blen == 0);
509 
510  olen = ((sasldata->blen - sasldata->bpos) > count) ?
511  count :
512  sasldata->blen - sasldata->bpos;
513 
514  memcpy(buf, sasldata->buf, olen);
515  sasldata->bpos += olen;
516 
517  rc = olen;
518  }
519  else
520  rc = sasldata->read(conn, buf, count);
521 
522 out:
523  conn->sockdata = sasldata;
524 
525  return rc;
526 }
SASL authentication API -.
Definition: sasl.c:60
void * sockdata
Backend-specific socket data.
Definition: connection.h:46
sasl_conn_t * saslconn
Definition: sasl.c:62
unsigned int bpos
Definition: sasl.c:69
void * sockdata
Underlying socket data.
Definition: sasl.c:71
unsigned int blen
Definition: sasl.c:68
const sasl_ssf_t * ssf
Definition: sasl.c:63
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
Log at debug level 1.
Definition: logging.h:40
int(* read)(struct Connection *conn, char *buf, size_t count)
Read from a socket Connection - Implements Connection::read() -.
Definition: sasl.c:81
const char * buf
Definition: sasl.c:67
+ Here is the caller graph for this function:

◆ tunnel_socket_read()

static int tunnel_socket_read ( struct Connection conn,
char *  buf,
size_t  count 
)
static

Read data from a tunnel socket - Implements Connection::read() -.

Definition at line 137 of file tunnel.c.

138 {
139  struct TunnelSockData *tunnel = conn->sockdata;
140  int rc;
141 
142  do
143  {
144  rc = read(tunnel->fd_read, buf, count);
145  } while (rc < 0 && errno == EINTR);
146 
147  if (rc < 0)
148  {
149  mutt_error(_("Tunnel error talking to %s: %s"), conn->account.host, strerror(errno));
150  return -1;
151  }
152 
153  return rc;
154 }
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:40
#define mutt_error(...)
Definition: logging.h:88
int fd_read
File descriptor to read from.
Definition: tunnel.c:50
void * sockdata
Backend-specific socket data.
Definition: connection.h:46
#define _(a)
Definition: message.h:28
A network tunnel (pair of sockets)
Definition: tunnel.c:47
char host[128]
Server to login to.
Definition: connaccount.h:53
+ Here is the caller graph for this function:

◆ zstrm_read()

static int zstrm_read ( struct Connection conn,
char *  buf,
size_t  len 
)
static

Read compressed data from a socket - Implements Connection::read() -.

Definition at line 129 of file zstrm.c.

130 {
131  struct ZstrmContext *zctx = conn->sockdata;
132  int rc = 0;
133  int zrc = 0;
134 
135 retry:
136  if (zctx->read.stream_eof)
137  return 0;
138 
139  /* when avail_out was 0 on last call, we need to call inflate again, because
140  * more data might be available using the current input, so avoid callling
141  * read on the underlying stream in that case (for it might block) */
142  if ((zctx->read.pos == 0) && !zctx->read.conn_eof)
143  {
144  rc = zctx->next_conn.read(&zctx->next_conn, zctx->read.buf, zctx->read.len);
145  mutt_debug(LL_DEBUG5, "consuming data from next stream: %d bytes\n", rc);
146  if (rc < 0)
147  return rc;
148  else if (rc == 0)
149  zctx->read.conn_eof = true;
150  else
151  zctx->read.pos += rc;
152  }
153 
154  zctx->read.z.avail_in = (uInt) zctx->read.pos;
155  zctx->read.z.next_in = (Bytef *) zctx->read.buf;
156  zctx->read.z.avail_out = (uInt) len;
157  zctx->read.z.next_out = (Bytef *) buf;
158 
159  zrc = inflate(&zctx->read.z, Z_SYNC_FLUSH);
160  mutt_debug(LL_DEBUG5, "rc=%d, consumed %u/%u bytes, produced %u/%u bytes\n",
161  zrc, zctx->read.pos - zctx->read.z.avail_in, zctx->read.pos,
162  len - zctx->read.z.avail_out, len);
163 
164  /* shift any remaining input data to the front of the buffer */
165  if ((Bytef *) zctx->read.buf != zctx->read.z.next_in)
166  {
167  memmove(zctx->read.buf, zctx->read.z.next_in, zctx->read.z.avail_in);
168  zctx->read.pos = zctx->read.z.avail_in;
169  }
170 
171  switch (zrc)
172  {
173  case Z_OK: /* progress has been made */
174  zrc = len - zctx->read.z.avail_out; /* "returned" bytes */
175  if (zrc == 0)
176  {
177  /* there was progress, so must have been reading input */
178  mutt_debug(LL_DEBUG5, "inflate just consumed\n");
179  goto retry;
180  }
181  break;
182 
183  case Z_STREAM_END: /* everything flushed, nothing remaining */
184  mutt_debug(LL_DEBUG5, "inflate returned Z_STREAM_END.\n");
185  zrc = len - zctx->read.z.avail_out; /* "returned" bytes */
186  zctx->read.stream_eof = true;
187  break;
188 
189  case Z_BUF_ERROR: /* no progress was possible */
190  if (!zctx->read.conn_eof)
191  {
192  mutt_debug(LL_DEBUG5, "inflate returned Z_BUF_ERROR. retrying.\n");
193  goto retry;
194  }
195  zrc = 0;
196  break;
197 
198  default:
199  /* bail on other rcs, such as Z_DATA_ERROR, or Z_MEM_ERROR */
200  mutt_debug(LL_DEBUG5, "inflate returned %d. aborting.\n", zrc);
201  zrc = -1;
202  break;
203  }
204 
205  return zrc;
206 }
Data compression layer.
Definition: zstrm.c:54
int(* read)(struct Connection *conn, char *buf, size_t count)
Definition: connection.h:82
void * sockdata
Backend-specific socket data.
Definition: connection.h:46
bool conn_eof
Connection end-of-file reached.
Definition: zstrm.c:47
struct Connection next_conn
Underlying stream.
Definition: zstrm.c:58
struct ZstrmDirection read
Data being read and de-compressed.
Definition: zstrm.c:56
bool stream_eof
Stream end-of-file reached.
Definition: zstrm.c:48
unsigned int len
Length of data.
Definition: zstrm.c:45
unsigned int pos
Current position.
Definition: zstrm.c:46
char * buf
Buffer for data being (de-)compressed.
Definition: zstrm.c:44
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
z_stream z
zlib compression handle
Definition: zstrm.c:43
Log at debug level 5.
Definition: logging.h:44
+ Here is the caller graph for this function:

Variable Documentation

◆ read

int(* SaslSockData::read) (struct Connection *conn, char *buf, size_t count)

Read from a socket Connection - Implements Connection::read() -.

Definition at line 81 of file sasl.c.