NeoMutt  2020-06-26-89-g172cd3
Teaching an old dog new tricks
DOXYGEN
socket.c File Reference

Low-level socket handling. More...

#include "config.h"
#include <errno.h>
#include <string.h>
#include <time.h>
#include "private.h"
#include "mutt/lib.h"
#include "socket.h"
#include "lib.h"
#include "connaccount.h"
#include "connection.h"
#include "mutt_globals.h"
#include "protos.h"
#include "ssl.h"
+ Include dependency graph for socket.c:

Go to the source code of this file.

Functions

static int socket_preconnect (void)
 Execute a command before opening a socket. More...
 
int mutt_socket_open (struct Connection *conn)
 Simple wrapper. More...
 
int mutt_socket_close (struct Connection *conn)
 Close a socket. More...
 
int mutt_socket_read (struct Connection *conn, char *buf, size_t len)
 read from a Connection More...
 
int mutt_socket_write (struct Connection *conn, const char *buf, size_t len)
 write to a Connection More...
 
int mutt_socket_write_d (struct Connection *conn, const char *buf, int len, int dbg)
 Write data to a socket. More...
 
int mutt_socket_poll (struct Connection *conn, time_t wait_secs)
 Checks whether reads would block. More...
 
int mutt_socket_readchar (struct Connection *conn, char *c)
 simple read buffering to speed things up More...
 
int mutt_socket_readln_d (char *buf, size_t buflen, struct Connection *conn, int dbg)
 Read a line from a socket. More...
 
struct Connectionmutt_socket_new (enum ConnectionType type)
 allocate and initialise a new connection More...
 
void mutt_socket_empty (struct Connection *conn)
 Clear out any queued data. More...
 

Detailed Description

Low-level socket handling.

Authors
  • Michael R. Elkins
  • Brendan Cully
  • Tommi Komulainen

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 socket.c.

Function Documentation

◆ socket_preconnect()

static int socket_preconnect ( void  )
static

Execute a command before opening a socket.

Return values
0Success
>0An errno, e.g. EPERM

Definition at line 50 of file socket.c.

51 {
52  if (!C_Preconnect)
53  return 0;
54 
55  mutt_debug(LL_DEBUG2, "Executing preconnect: %s\n", C_Preconnect);
56  const int rc = mutt_system(C_Preconnect);
57  mutt_debug(LL_DEBUG2, "Preconnect result: %d\n", rc);
58  if (rc != 0)
59  {
60  const int save_errno = errno;
61  mutt_perror(_("Preconnect command failed"));
62 
63  return save_errno;
64  }
65 
66  return 0;
67 }
#define mutt_perror(...)
Definition: logging.h:85
#define _(a)
Definition: message.h:28
Log at debug level 2.
Definition: logging.h:41
const char * C_Preconnect
Config: External command to run prior to opening a socket.
Definition: config.c:37
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
int mutt_system(const char *cmd)
Run an external command.
Definition: system.c:51
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_socket_open()

int mutt_socket_open ( struct Connection conn)

Simple wrapper.

Parameters
connConnection to a server
Return values
0Success
-1Error

Definition at line 75 of file socket.c.

76 {
77  int rc;
78 
79  if (socket_preconnect())
80  return -1;
81 
82  rc = conn->open(conn);
83 
84  mutt_debug(LL_DEBUG2, "Connected to %s:%d on fd=%d\n", conn->account.host,
85  conn->account.port, conn->fd);
86 
87  return rc;
88 }
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:36
int(* open)(struct Connection *conn)
Note about ssf: in actuality, NeoMutt uses this as a boolean to determine if the connection is "secur...
Definition: connection.h:62
char host[128]
Server to login to.
Definition: connaccount.h:53
Log at debug level 2.
Definition: logging.h:41
unsigned short port
Port to connect to.
Definition: connaccount.h:57
int fd
Socket file descriptor.
Definition: connection.h:40
static int socket_preconnect(void)
Execute a command before opening a socket.
Definition: socket.c:50
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_socket_close()

int mutt_socket_close ( struct Connection conn)

Close a socket.

Parameters
connConnection to a server
Return values
0Success
-1Error

Definition at line 96 of file socket.c.

97 {
98  if (!conn)
99  return 0;
100 
101  int rc = -1;
102 
103  if (conn->fd < 0)
104  mutt_debug(LL_DEBUG1, "Attempt to close closed connection\n");
105  else
106  rc = conn->close(conn);
107 
108  conn->fd = -1;
109  conn->ssf = 0;
110  conn->bufpos = 0;
111  conn->available = 0;
112 
113  return rc;
114 }
unsigned int ssf
Security strength factor, in bits (see below)
Definition: connection.h:37
int(* close)(struct Connection *conn)
Close a socket Connection.
Definition: connection.h:100
int fd
Socket file descriptor.
Definition: connection.h:40
int available
Amount of data waiting to be read.
Definition: connection.h:41
Log at debug level 1.
Definition: logging.h:40
int bufpos
Current position in the buffer.
Definition: connection.h:39
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
+ Here is the caller graph for this function:

◆ mutt_socket_read()

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

read from a Connection

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

Definition at line 124 of file socket.c.

125 {
126  return conn->read(conn, buf, len);
127 }
int(* read)(struct Connection *conn, char *buf, size_t count)
Read from a socket Connection.
Definition: connection.h:72
const char * buf
Definition: sasl.c:67
+ Here is the caller graph for this function:

◆ mutt_socket_write()

int mutt_socket_write ( struct Connection conn,
const char *  buf,
size_t  len 
)

write to a Connection

Parameters
connConnection to a server
bufBuffer with data to write
lenLength of data to write
Return values
>0Number of bytes written
-1Error

Definition at line 137 of file socket.c.

138 {
139  return conn->write(conn, buf, len);
140 }
int(* write)(struct Connection *conn, const char *buf, size_t count)
Write to a socket Connection.
Definition: connection.h:82
const char * buf
Definition: sasl.c:67

◆ mutt_socket_write_d()

int mutt_socket_write_d ( struct Connection conn,
const char *  buf,
int  len,
int  dbg 
)

Write data to a socket.

Parameters
connConnection to a server
bufBuffer with data to write
lenLength of data to write
dbgDebug level for logging
Return values
>0Number of bytes written
-1Error

Definition at line 151 of file socket.c.

152 {
153  int sent = 0;
154 
155  mutt_debug(dbg, "%d> %s", conn->fd, buf);
156 
157  if (conn->fd < 0)
158  {
159  mutt_debug(LL_DEBUG1, "attempt to write to closed connection\n");
160  return -1;
161  }
162 
163  while (sent < len)
164  {
165  const int rc = conn->write(conn, buf + sent, len - sent);
166  if (rc < 0)
167  {
168  mutt_debug(LL_DEBUG1, "error writing (%s), closing socket\n", strerror(errno));
169  mutt_socket_close(conn);
170 
171  return -1;
172  }
173 
174  if (rc < len - sent)
175  mutt_debug(LL_DEBUG3, "short write (%d of %d bytes)\n", rc, len - sent);
176 
177  sent += rc;
178  }
179 
180  return sent;
181 }
int fd
Socket file descriptor.
Definition: connection.h:40
int mutt_socket_close(struct Connection *conn)
Close a socket.
Definition: socket.c:96
Log at debug level 1.
Definition: logging.h:40
int(* write)(struct Connection *conn, const char *buf, size_t count)
Write to a socket Connection.
Definition: connection.h:82
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
const char * buf
Definition: sasl.c:67
Log at debug level 3.
Definition: logging.h:42
+ Here is the call graph for this function:

◆ mutt_socket_poll()

int mutt_socket_poll ( struct Connection conn,
time_t  wait_secs 
)

Checks whether reads would block.

Parameters
connConnection to a server
wait_secsHow long to wait for a response
Return values
>0There is data to read
0Read would block
-1Connection doesn't support polling

Definition at line 191 of file socket.c.

192 {
193  if (conn->bufpos < conn->available)
194  return conn->available - conn->bufpos;
195 
196  if (conn->poll)
197  return conn->poll(conn, wait_secs);
198 
199  return -1;
200 }
int available
Amount of data waiting to be read.
Definition: connection.h:41
int(* poll)(struct Connection *conn, time_t wait_secs)
Check whether a socket read would block.
Definition: connection.h:92
int bufpos
Current position in the buffer.
Definition: connection.h:39
+ Here is the caller graph for this function:

◆ mutt_socket_readchar()

int mutt_socket_readchar ( struct Connection conn,
char *  c 
)

simple read buffering to speed things up

Parameters
[in]connConnection to a server
[out]cCharacter that was read
Return values
1Success
-1Error

Definition at line 209 of file socket.c.

210 {
211  if (conn->bufpos >= conn->available)
212  {
213  if (conn->fd >= 0)
214  conn->available = conn->read(conn, conn->inbuf, sizeof(conn->inbuf));
215  else
216  {
217  mutt_debug(LL_DEBUG1, "attempt to read from closed connection\n");
218  return -1;
219  }
220  conn->bufpos = 0;
221  if (conn->available == 0)
222  {
223  mutt_error(_("Connection to %s closed"), conn->account.host);
224  }
225  if (conn->available <= 0)
226  {
227  mutt_socket_close(conn);
228  return -1;
229  }
230  }
231  *c = conn->inbuf[conn->bufpos];
232  conn->bufpos++;
233  return 1;
234 }
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:36
int(* read)(struct Connection *conn, char *buf, size_t count)
Read from a socket Connection.
Definition: connection.h:72
#define _(a)
Definition: message.h:28
char host[128]
Server to login to.
Definition: connaccount.h:53
char inbuf[1024]
Buffer for incoming traffic.
Definition: connection.h:38
int fd
Socket file descriptor.
Definition: connection.h:40
int available
Amount of data waiting to be read.
Definition: connection.h:41
int mutt_socket_close(struct Connection *conn)
Close a socket.
Definition: socket.c:96
Log at debug level 1.
Definition: logging.h:40
#define mutt_error(...)
Definition: logging.h:84
int bufpos
Current position in the buffer.
Definition: connection.h:39
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_socket_readln_d()

int mutt_socket_readln_d ( char *  buf,
size_t  buflen,
struct Connection conn,
int  dbg 
)

Read a line from a socket.

Parameters
bufBuffer to store the line
buflenLength of data to write
connConnection to a server
dbgDebug level for logging
Return values
>0Success, number of bytes read
-1Error

Definition at line 245 of file socket.c.

246 {
247  char ch;
248  int i;
249 
250  for (i = 0; i < buflen - 1; i++)
251  {
252  if (mutt_socket_readchar(conn, &ch) != 1)
253  {
254  buf[i] = '\0';
255  return -1;
256  }
257 
258  if (ch == '\n')
259  break;
260  buf[i] = ch;
261  }
262 
263  /* strip \r from \r\n termination */
264  if (i && (buf[i - 1] == '\r'))
265  i--;
266  buf[i] = '\0';
267 
268  mutt_debug(dbg, "%d< %s\n", conn->fd, buf);
269 
270  /* number of bytes read, not strlen */
271  return i + 1;
272 }
int mutt_socket_readchar(struct Connection *conn, char *c)
simple read buffering to speed things up
Definition: socket.c:209
int fd
Socket file descriptor.
Definition: connection.h:40
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
const char * buf
Definition: sasl.c:67
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_socket_new()

struct Connection* mutt_socket_new ( enum ConnectionType  type)

allocate and initialise a new connection

Parameters
typeType of the new Connection
Return values
ptrNew Connection

Definition at line 279 of file socket.c.

280 {
281  struct Connection *conn = mutt_mem_calloc(1, sizeof(struct Connection));
282  conn->fd = -1;
283 
284  if (type == MUTT_CONNECTION_TUNNEL)
285  {
287  }
288  else if (type == MUTT_CONNECTION_SSL)
289  {
290  int rc = mutt_ssl_socket_setup(conn);
291  if (rc < 0)
292  FREE(&conn);
293  }
294  else
295  {
296  conn->read = raw_socket_read;
297  conn->write = raw_socket_write;
298  conn->open = raw_socket_open;
299  conn->close = raw_socket_close;
300  conn->poll = raw_socket_poll;
301  }
302 
303  return conn;
304 }
Tunnelled connection.
Definition: socket.h:37
int raw_socket_close(struct Connection *conn)
Close a socket - Implements Connection::close()
Definition: raw.c:360
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
int(* read)(struct Connection *conn, char *buf, size_t count)
Read from a socket Connection.
Definition: connection.h:72
An open network connection (socket)
Definition: connection.h:34
int raw_socket_poll(struct Connection *conn, time_t wait_secs)
Checks whether reads would block - Implements Connection::poll()
Definition: raw.c:322
int(* open)(struct Connection *conn)
Note about ssf: in actuality, NeoMutt uses this as a boolean to determine if the connection is "secur...
Definition: connection.h:62
int raw_socket_write(struct Connection *conn, const char *buf, size_t count)
Write data to a socket - Implements Connection::write()
Definition: raw.c:292
int(* close)(struct Connection *conn)
Close a socket Connection.
Definition: connection.h:100
SSL/TLS-encrypted connection.
Definition: socket.h:38
int fd
Socket file descriptor.
Definition: connection.h:40
int raw_socket_read(struct Connection *conn, char *buf, size_t len)
Read data from a socket - Implements Connection::read()
Definition: raw.c:262
int raw_socket_open(struct Connection *conn)
Open a socket - Implements Connection::open()
Definition: raw.c:116
void mutt_tunnel_socket_setup(struct Connection *conn)
sets up tunnel connection functions
Definition: tunnel.c:233
int(* poll)(struct Connection *conn, time_t wait_secs)
Check whether a socket read would block.
Definition: connection.h:92
int mutt_ssl_socket_setup(struct Connection *conn)
Set up SSL socket mulitplexor.
Definition: gnutls.c:1122
int(* write)(struct Connection *conn, const char *buf, size_t count)
Write to a socket Connection.
Definition: connection.h:82
#define FREE(x)
Definition: memory.h:40
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_socket_empty()

void mutt_socket_empty ( struct Connection conn)

Clear out any queued data.

The internal buffer is emptied and any data that has already arrived at this machine (in kernel buffers) is read and dropped.

Definition at line 312 of file socket.c.

313 {
314  if (!conn)
315  return;
316 
317  char buf[1024];
318  int bytes;
319 
320  while ((bytes = mutt_socket_poll(conn, 0)) > 0)
321  {
322  mutt_socket_read(conn, buf, MIN(bytes, sizeof(buf)));
323  }
324 }
#define MIN(a, b)
Definition: memory.h:31
int mutt_socket_poll(struct Connection *conn, time_t wait_secs)
Checks whether reads would block.
Definition: socket.c:191
int mutt_socket_read(struct Connection *conn, char *buf, size_t len)
read from a Connection
Definition: socket.c:124
+ Here is the call graph for this function:
+ Here is the caller graph for this function: