NeoMutt  2022-04-29-323-g5fcc6c
Teaching an old dog new tricks
DOXYGEN

Write to a socket Connection. More...

+ Collaboration diagram for write():

Functions

static int tls_socket_write (struct Connection *conn, const char *buf, size_t count)
 Write data to a TLS socket - Implements Connection::write() -. More...
 
static int ssl_socket_write (struct Connection *conn, const char *buf, size_t count)
 Write data to an SSL socket - Implements Connection::write() -. More...
 
int raw_socket_write (struct Connection *conn, const char *buf, size_t count)
 Write data to a socket - Implements Connection::write() -. More...
 
static int mutt_sasl_conn_write (struct Connection *conn, const char *buf, size_t count)
 Write to an SASL connection - Implements Connection::write() -. More...
 
static int tunnel_socket_write (struct Connection *conn, const char *buf, size_t count)
 Write data to a tunnel socket - Implements Connection::write() -. More...
 
static int zstrm_write (struct Connection *conn, const char *buf, size_t count)
 Write compressed data to a socket - Implements Connection::write() -. More...
 

Variables

int(* SaslSockData::write )(struct Connection *conn, const char *buf, size_t count)
 Write to a socket Connection - Implements Connection::write() -. More...
 

Detailed Description

Write to a socket Connection.

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

Function Documentation

◆ tls_socket_write()

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

Write data to a TLS socket - Implements Connection::write() -.

Definition at line 1070 of file gnutls.c.

1071{
1072 struct TlsSockData *data = conn->sockdata;
1073 size_t sent = 0;
1074
1075 if (!data)
1076 {
1077 mutt_error(_("Error: no TLS socket open"));
1078 return -1;
1079 }
1080
1081 do
1082 {
1083 int rc;
1084 do
1085 {
1086 rc = gnutls_record_send(data->state, buf + sent, count - sent);
1087 } while ((rc == GNUTLS_E_AGAIN) || (rc == GNUTLS_E_INTERRUPTED));
1088
1089 if (rc < 0)
1090 {
1091 mutt_error("tls_socket_write (%s)", gnutls_strerror(rc));
1092 return -1;
1093 }
1094
1095 sent += rc;
1096 } while (sent < count);
1097
1098 return sent;
1099}
#define mutt_error(...)
Definition: logging.h:87
#define _(a)
Definition: message.h:28
void * sockdata
Backend-specific socket data.
Definition: connection.h:56
TLS socket data -.
Definition: gnutls.c:81
gnutls_session_t state
Definition: gnutls.c:82
+ Here is the caller graph for this function:

◆ ssl_socket_write()

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

Write data to an SSL socket - Implements Connection::write() -.

Definition at line 1348 of file openssl.c.

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

◆ raw_socket_write()

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

Write data to a socket - Implements Connection::write() -.

Definition at line 294 of file raw.c.

295{
296 int rc;
297 size_t sent = 0;
298
300 do
301 {
302 do
303 {
304 rc = write(conn->fd, buf + sent, count - sent);
305 } while (rc < 0 && (errno == EINTR));
306
307 if (rc < 0)
308 {
309 mutt_error(_("Error talking to %s (%s)"), conn->account.host, strerror(errno));
311 return -1;
312 }
313
314 sent += rc;
315 } while ((sent < count) && !SigInt);
316
318 return sent;
319}
SIG_ATOMIC_VOLATILE_T SigInt
true after SIGINT is received
Definition: mutt_globals.h:69
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:54
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:50
int fd
Socket file descriptor.
Definition: connection.h:54
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_sasl_conn_write()

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

Write to an SASL connection - Implements Connection::write() -.

Definition at line 527 of file sasl.c.

528{
529 int rc;
530 const char *pbuf = NULL;
531 unsigned int olen, plen;
532
533 struct SaslSockData *sasldata = conn->sockdata;
534 conn->sockdata = sasldata->sockdata;
535
536 /* encode data, if necessary */
537 if (*sasldata->ssf != 0)
538 {
539 /* handle data larger than MAXOUTBUF */
540 do
541 {
542 olen = (count > *sasldata->pbufsize) ? *sasldata->pbufsize : count;
543
544 rc = sasl_encode(sasldata->saslconn, buf, olen, &pbuf, &plen);
545 if (rc != SASL_OK)
546 {
547 mutt_debug(LL_DEBUG1, "SASL encoding failed: %s\n", sasl_errstring(rc, NULL, NULL));
548 goto fail;
549 }
550
551 rc = sasldata->write(conn, pbuf, plen);
552 if (rc != plen)
553 goto fail;
554
555 count -= olen;
556 buf += olen;
557 } while (count > *sasldata->pbufsize);
558 }
559 else
560 {
561 /* just write using the underlying socket function */
562 rc = sasldata->write(conn, buf, count);
563 }
564
565 conn->sockdata = sasldata;
566
567 return rc;
568
569fail:
570 conn->sockdata = sasldata;
571 return -1;
572}
int(* write)(struct Connection *conn, const char *buf, size_t count)
Write to a socket Connection - Implements Connection::write() -.
Definition: sasl.c:87
#define mutt_debug(LEVEL,...)
Definition: logging.h:84
@ LL_DEBUG1
Log at debug level 1.
Definition: logging.h:40
static unsigned char * pbuf
Cached PGP data packet.
Definition: pgppacket.c:38
static size_t plen
Length of cached packet.
Definition: pgppacket.c:39
SASL authentication API -.
Definition: sasl.c:62
void * sockdata
Underlying socket data.
Definition: sasl.c:72
const sasl_ssf_t * ssf
Definition: sasl.c:64
const unsigned int * pbufsize
Definition: sasl.c:65
const char * buf
Buffer for data read from the connection.
Definition: sasl.c:68
sasl_conn_t * saslconn
Definition: sasl.c:63
+ Here is the caller graph for this function:

◆ tunnel_socket_write()

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

Write data to a tunnel socket - Implements Connection::write() -.

Definition at line 159 of file tunnel.c.

160{
161 struct TunnelSockData *tunnel = conn->sockdata;
162 int rc;
163 size_t sent = 0;
164
165 do
166 {
167 do
168 {
169 rc = write(tunnel->fd_write, buf + sent, count - sent);
170 } while (rc < 0 && errno == EINTR);
171
172 if (rc < 0)
173 {
174 mutt_error(_("Tunnel error talking to %s: %s"), conn->account.host, strerror(errno));
175 return -1;
176 }
177
178 sent += rc;
179 } while (sent < count);
180
181 return sent;
182}
A network tunnel (pair of sockets)
Definition: tunnel.c:48
int fd_write
File descriptor to write to.
Definition: tunnel.c:51
+ Here is the caller graph for this function:

◆ zstrm_write()

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

Write compressed data to a socket - Implements Connection::write() -.

Definition at line 228 of file zstrm.c.

229{
230 struct ZstrmContext *zctx = conn->sockdata;
231 int rc;
232
233 zctx->write.z.avail_in = (uInt) count;
234 zctx->write.z.next_in = (Bytef *) buf;
235 zctx->write.z.avail_out = (uInt) zctx->write.len;
236 zctx->write.z.next_out = (Bytef *) zctx->write.buf;
237
238 do
239 {
240 int zrc = deflate(&zctx->write.z, Z_PARTIAL_FLUSH);
241 if (zrc == Z_OK)
242 {
243 /* push out produced data to the underlying stream */
244 zctx->write.pos = zctx->write.len - zctx->write.z.avail_out;
245 char *wbufp = zctx->write.buf;
246 mutt_debug(LL_DEBUG5, "deflate consumed %lu/%lu bytes\n",
247 count - zctx->write.z.avail_in, count);
248 while (zctx->write.pos > 0)
249 {
250 rc = zctx->next_conn.write(&zctx->next_conn, wbufp, zctx->write.pos);
251 mutt_debug(LL_DEBUG5, "next stream wrote: %d bytes\n", rc);
252 if (rc < 0)
253 return -1; /* we can't recover from write failure */
254
255 wbufp += rc;
256 zctx->write.pos -= rc;
257 }
258
259 /* see if there's more for us to do, retry if the output buffer
260 * was full (there may be something in zlib buffers), and retry
261 * when there is still available input data */
262 if ((zctx->write.z.avail_out != 0) && (zctx->write.z.avail_in == 0))
263 break;
264
265 zctx->write.z.avail_out = (uInt) zctx->write.len;
266 zctx->write.z.next_out = (Bytef *) zctx->write.buf;
267 }
268 else
269 {
270 /* compression went wrong, but this is basically impossible
271 * according to the docs */
272 return -1;
273 }
274 } while (true);
275
276 rc = (int) count;
277 return (rc <= 0) ? 1 : rc; /* avoid wrong behaviour due to overflow */
278}
@ LL_DEBUG5
Log at debug level 5.
Definition: logging.h:44
int(* write)(struct Connection *conn, const char *buf, size_t count)
Definition: connection.h:93
Data compression layer.
Definition: zstrm.c:55
struct ZstrmDirection write
Data being compressed and written.
Definition: zstrm.c:57
struct Connection next_conn
Underlying stream.
Definition: zstrm.c:58
unsigned int pos
Current position.
Definition: zstrm.c:46
unsigned int len
Length of data.
Definition: zstrm.c:45
z_stream z
zlib compression handle
Definition: zstrm.c:43
char * buf
Buffer for data being (de-)compressed.
Definition: zstrm.c:44
+ Here is the caller graph for this function:

Variable Documentation

◆ write

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

Write to a socket Connection - Implements Connection::write() -.

Definition at line 87 of file sasl.c.