NeoMutt  2025-12-11-1039-g550ac6
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches

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() -.
static int ssl_socket_write (struct Connection *conn, const char *buf, size_t count)
 Write data to an SSL socket - Implements Connection::write() -.
int raw_socket_write (struct Connection *conn, const char *buf, size_t count)
 Write data to a socket - Implements Connection::write() -.
static int mutt_sasl_conn_write (struct Connection *conn, const char *buf, size_t count)
 Write to an SASL connection - Implements Connection::write() -.
static int tunnel_socket_write (struct Connection *conn, const char *buf, size_t count)
 Write data to a tunnel socket - Implements Connection::write() -.
static int zstrm_write (struct Connection *conn, const char *buf, size_t count)
 Write compressed data to a socket - Implements Connection::write() -.

Variables

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

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()

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 1096 of file gnutls.c.

1097{
1098 struct TlsSockData *data = conn->sockdata;
1099 size_t sent = 0;
1100
1101 if (!data)
1102 {
1103 mutt_error(_("Error: no TLS socket open"));
1104 return -1;
1105 }
1106
1107 do
1108 {
1109 int rc;
1110 do
1111 {
1112 rc = gnutls_record_send(data->session, buf + sent, count - sent);
1113 if (rc == GNUTLS_E_AGAIN)
1114 {
1115 // Socket would block, wait for data to become available
1117 return -1;
1118 }
1119 } while ((rc == GNUTLS_E_AGAIN) || (rc == GNUTLS_E_INTERRUPTED));
1120
1121 if (rc < 0)
1122 {
1123 mutt_error("tls_socket_write (%s)", gnutls_strerror(rc));
1124 return -1;
1125 }
1126
1127 sent += rc;
1128 } while (sent < count);
1129
1130 // Narrowed to int for the Connection::write() interface; see #4940.
1131 return (int) sent;
1132}
static bool tls_socket_poll_with_timeout(struct Connection *conn)
Poll a socket with configured timeout.
Definition gnutls.c:859
#define mutt_error(...)
Definition logging2.h:94
#define _(a)
Definition message.h:28
void * sockdata
Backend-specific socket data.
Definition connection.h:55
This array needs to be large enough to hold all the possible values support by NeoMutt.
Definition gnutls.c:82
gnutls_session_t session
GNUTLS session.
Definition gnutls.c:83
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ssl_socket_write()

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 1376 of file openssl.c.

1377{
1378 if (!conn || !conn->sockdata || !buf || (count == 0))
1379 return -1;
1380
1381 struct SslSockData *data = sockdata(conn);
1382 int rc;
1383
1384retry:
1385 rc = SSL_write(data->ssl, buf, count);
1386 if (rc > 0)
1387 return rc;
1388
1389 // User hit Ctrl-C
1390 if (SigInt && (errno == EINTR))
1391 {
1392 rc = -1;
1393 }
1394 else if (BIO_should_retry(SSL_get_wbio(data->ssl)))
1395 {
1396 // Temporary failure, e.g. signal received
1397 goto retry;
1398 }
1399
1400 ssl_err(data, rc);
1401 return rc;
1402}
static struct SslSockData * sockdata(struct Connection *conn)
Get a Connection's socket data.
Definition openssl.c:1211
static void ssl_err(struct SslSockData *data, int err)
Display an SSL error message.
Definition openssl.c:241
volatile sig_atomic_t SigInt
true after SIGINT is received
Definition signal.c:68
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 325 of file raw.c.

326{
327 ssize_t rc;
328 size_t sent = 0;
329
331 do
332 {
333 do
334 {
335 rc = write(conn->fd, buf + sent, count - sent);
336 } while (rc < 0 && (errno == EINTR));
337
338 if (rc < 0)
339 {
340 mutt_error(_("Error talking to %s (%s)"), conn->account.host, strerror(errno));
342 return -1;
343 }
344
345 sent += rc;
346 } while ((sent < count) && !SigInt);
347
349 return sent;
350}
void mutt_sig_allow_interrupt(bool allow)
Allow/disallow Ctrl-C (SIGINT).
Definition signal.c:315
char host[128]
Server to login to.
Definition connaccount.h:60
struct ConnAccount account
Account details: username, password, etc.
Definition connection.h:49
int fd
Socket file descriptor.
Definition connection.h:53
Here is the call graph for this function:
Here is the caller graph for this function:

◆ mutt_sasl_conn_write()

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 539 of file sasl.c.

540{
541 int rc;
542 const char *pbuf = NULL;
543 unsigned int olen;
544 unsigned int plen;
545
546 struct SaslSockData *sasldata = conn->sockdata;
547 conn->sockdata = sasldata->sockdata;
548
549 /* encode data, if necessary */
550 if (*sasldata->ssf != 0)
551 {
552 /* handle data larger than MAXOUTBUF */
553 do
554 {
555 olen = (count > *sasldata->pbufsize) ? *sasldata->pbufsize : count;
556
557 rc = sasl_encode(sasldata->saslconn, buf, olen, &pbuf, &plen);
558 if (rc != SASL_OK)
559 {
560 mutt_debug(LL_DEBUG1, "SASL encoding failed: %s\n", sasl_errstring(rc, NULL, NULL));
561 goto fail;
562 }
563
564 rc = sasldata->write(conn, pbuf, plen);
565 if (rc != plen)
566 goto fail;
567
568 count -= olen;
569 buf += olen;
570 } while (count > *sasldata->pbufsize);
571 }
572 else
573 {
574 /* just write using the underlying socket function */
575 rc = sasldata->write(conn, buf, count);
576 }
577
578 conn->sockdata = sasldata;
579
580 return rc;
581
582fail:
583 conn->sockdata = sasldata;
584 return -1;
585}
int(* write)(struct Connection *conn, const char *buf, size_t count)
Write to a socket Connection - Implements Connection::write() -.
Definition sasl.c:91
#define mutt_debug(LEVEL,...)
Definition logging2.h:91
@ LL_DEBUG1
Log at debug level 1.
Definition logging2.h:45
SASL authentication API -.
Definition sasl.c:66
void * sockdata
Underlying socket data.
Definition sasl.c:76
const sasl_ssf_t * ssf
Security strength factor, in bits.
Definition sasl.c:68
const unsigned int * pbufsize
Buffer size.
Definition sasl.c:69
const char * buf
Buffer for data read from the connection.
Definition sasl.c:72
sasl_conn_t * saslconn
Raw SASL connection.
Definition sasl.c:67
Here is the caller graph for this function:

◆ tunnel_socket_write()

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 169 of file tunnel.c.

170{
171 struct TunnelSockData *tunnel = conn->sockdata;
172 ssize_t rc;
173 size_t sent = 0;
174
175 do
176 {
177 do
178 {
179 rc = write(tunnel->fd_write, buf + sent, count - sent);
180 } while (rc < 0 && errno == EINTR);
181
182 if (rc < 0)
183 {
184 mutt_error(_("Tunnel error talking to %s: %s"), conn->account.host, strerror(errno));
185 return -1;
186 }
187
188 sent += rc;
189 } while (sent < count);
190
191 return sent;
192}
A network tunnel (pair of sockets).
Definition tunnel.c:49
int fd_write
File descriptor to write to.
Definition tunnel.c:52
Here is the caller graph for this function:

◆ zstrm_write()

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 238 of file zstrm.c.

239{
240 struct ZstrmContext *zctx = conn->sockdata;
241 int rc;
242
243 zctx->write.z.avail_in = (uInt) count;
244 zctx->write.z.next_in = (Bytef *) buf;
245 zctx->write.z.avail_out = (uInt) zctx->write.len;
246 zctx->write.z.next_out = (Bytef *) zctx->write.buf;
247
248 do
249 {
250 int zrc = deflate(&zctx->write.z, Z_PARTIAL_FLUSH);
251 if (zrc == Z_OK)
252 {
253 /* push out produced data to the underlying stream */
254 zctx->write.pos = zctx->write.len - zctx->write.z.avail_out;
255 char *wbufp = zctx->write.buf;
256 mutt_debug(LL_DEBUG5, "deflate consumed %zu/%zu bytes\n",
257 count - zctx->write.z.avail_in, count);
258 while (zctx->write.pos > 0)
259 {
260 rc = zctx->next_conn.write(&zctx->next_conn, wbufp, zctx->write.pos);
261 mutt_debug(LL_DEBUG5, "next stream wrote: %d bytes\n", rc);
262 if (rc < 0)
263 return -1; /* we can't recover from write failure */
264
265 wbufp += rc;
266 zctx->write.pos -= rc;
267 }
268
269 /* see if there's more for us to do, retry if the output buffer
270 * was full (there may be something in zlib buffers), and retry
271 * when there is still available input data */
272 if ((zctx->write.z.avail_out != 0) && (zctx->write.z.avail_in == 0))
273 break;
274
275 zctx->write.z.avail_out = (uInt) zctx->write.len;
276 zctx->write.z.next_out = (Bytef *) zctx->write.buf;
277 }
278 else
279 {
280 /* compression went wrong, but this is basically impossible
281 * according to the docs */
282 return -1;
283 }
284 } while (true);
285
286 // Guard overflow when narrowing to int for Connection::write(); see #4940.
287 if (count > INT_MAX)
288 {
289 mutt_debug(LL_DEBUG1, "zstrm_write: count %zu exceeds INT_MAX\n", count);
290 return -1;
291 }
292 return (int) count;
293}
@ LL_DEBUG5
Log at debug level 5.
Definition logging2.h:49
Data compression layer.
Definition zstrm.c:59
struct ZstrmDirection write
Data being compressed and written.
Definition zstrm.c:61
unsigned int len
Length of data.
Definition zstrm.c:49
z_stream z
zlib compression handle
Definition zstrm.c:47
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 91 of file sasl.c.