NeoMutt  2024-04-16-36-g75b6fb
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()

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

1077{
1078 struct TlsSockData *data = conn->sockdata;
1079 size_t sent = 0;
1080
1081 if (!data)
1082 {
1083 mutt_error(_("Error: no TLS socket open"));
1084 return -1;
1085 }
1086
1087 do
1088 {
1089 int rc;
1090 do
1091 {
1092 rc = gnutls_record_send(data->session, buf + sent, count - sent);
1093 } while ((rc == GNUTLS_E_AGAIN) || (rc == GNUTLS_E_INTERRUPTED));
1094
1095 if (rc < 0)
1096 {
1097 mutt_error("tls_socket_write (%s)", gnutls_strerror(rc));
1098 return -1;
1099 }
1100
1101 sent += rc;
1102 } while (sent < count);
1103
1104 return sent;
1105}
#define mutt_error(...)
Definition: logging2.h:92
#define _(a)
Definition: message.h:28
void * sockdata
Backend-specific socket data.
Definition: connection.h:55
TLS socket data -.
Definition: gnutls.c:82
gnutls_session_t session
Definition: gnutls.c:83
+ 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 1370 of file openssl.c.

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

324{
325 int rc;
326 size_t sent = 0;
327
329 do
330 {
331 do
332 {
333 rc = write(conn->fd, buf + sent, count - sent);
334 } while (rc < 0 && (errno == EINTR));
335
336 if (rc < 0)
337 {
338 mutt_error(_("Error talking to %s (%s)"), conn->account.host, strerror(errno));
340 return -1;
341 }
342
343 sent += rc;
344 } while ((sent < count) && !SigInt);
345
347 return sent;
348}
void mutt_sig_allow_interrupt(bool allow)
Allow/disallow Ctrl-C (SIGINT)
Definition: signal.c:254
char host[128]
Server to login to.
Definition: connaccount.h:54
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()

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

535{
536 int rc;
537 const char *pbuf = NULL;
538 unsigned int olen, plen;
539
540 struct SaslSockData *sasldata = conn->sockdata;
541 conn->sockdata = sasldata->sockdata;
542
543 /* encode data, if necessary */
544 if (*sasldata->ssf != 0)
545 {
546 /* handle data larger than MAXOUTBUF */
547 do
548 {
549 olen = (count > *sasldata->pbufsize) ? *sasldata->pbufsize : count;
550
551 rc = sasl_encode(sasldata->saslconn, buf, olen, &pbuf, &plen);
552 if (rc != SASL_OK)
553 {
554 mutt_debug(LL_DEBUG1, "SASL encoding failed: %s\n", sasl_errstring(rc, NULL, NULL));
555 goto fail;
556 }
557
558 rc = sasldata->write(conn, pbuf, plen);
559 if (rc != plen)
560 goto fail;
561
562 count -= olen;
563 buf += olen;
564 } while (count > *sasldata->pbufsize);
565 }
566 else
567 {
568 /* just write using the underlying socket function */
569 rc = sasldata->write(conn, buf, count);
570 }
571
572 conn->sockdata = sasldata;
573
574 return rc;
575
576fail:
577 conn->sockdata = sasldata;
578 return -1;
579}
int(* write)(struct Connection *conn, const char *buf, size_t count)
Write to a socket Connection - Implements Connection::write() -.
Definition: sasl.c:90
#define mutt_debug(LEVEL,...)
Definition: logging2.h:89
@ LL_DEBUG1
Log at debug level 1.
Definition: logging2.h:43
SASL authentication API -.
Definition: sasl.c:65
void * sockdata
Underlying socket data.
Definition: sasl.c:75
const sasl_ssf_t * ssf
Definition: sasl.c:67
const unsigned int * pbufsize
Definition: sasl.c:68
const char * buf
Buffer for data read from the connection.
Definition: sasl.c:71
sasl_conn_t * saslconn
Definition: sasl.c:66
+ 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 168 of file tunnel.c.

169{
170 struct TunnelSockData *tunnel = conn->sockdata;
171 int rc;
172 size_t sent = 0;
173
174 do
175 {
176 do
177 {
178 rc = write(tunnel->fd_write, buf + sent, count - sent);
179 } while (rc < 0 && errno == EINTR);
180
181 if (rc < 0)
182 {
183 mutt_error(_("Tunnel error talking to %s: %s"), conn->account.host, strerror(errno));
184 return -1;
185 }
186
187 sent += rc;
188 } while (sent < count);
189
190 return sent;
191}
A network tunnel (pair of sockets)
Definition: tunnel.c:50
int fd_write
File descriptor to write to.
Definition: tunnel.c:53
+ 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 231 of file zstrm.c.

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