/* silcos2sockconn.c Author: Pekka Riikonen Copyright (C) 2002 Pekka Riikonen The contents of this file are subject to one of the Licenses specified in the COPYING file; You may not use this file except in compliance with the License. The software distributed under the License is distributed on an "AS IS" basis, in the hope that it will be useful, but WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the COPYING file for more information. */ /* $Id: silcos2sockconn.c,v 1.3 2002/03/19 14:50:08 priikone Exp $ */ /* XXX TODO */ #include "silcincludes.h" /* Writes data from encrypted buffer to the socket connection. If the data cannot be written at once, it will be written later with a timeout. The data is written from the data section of the buffer, not from head or tail section. This automatically pulls the data section towards end after writing the data. */ int silc_socket_write(SilcSocketConnection sock) { int ret = 0, err; SilcBuffer src = sock->outbuf; if (SILC_IS_DISABLED(sock)) return -1; SILC_LOG_DEBUG(("Writing data to socket %d", sock->sock)); if (src->len > 0) { ret = send(sock->sock, src->data, src->len, 0); if (ret == -1) { if (errno == EWOULDBLOCK) { SILC_LOG_DEBUG(("Could not write immediately, will do it later")); return -2; } SILC_LOG_ERROR(("Cannot write to socket: %d", sock->sock)); sock->sock_error = errno; return -1; } if (ret < src->len) { SILC_LOG_DEBUG(("Wrote data %d of %d bytes, will write rest later", ret, src->len)); silc_buffer_pull(src, ret); return -2; } silc_buffer_pull(src, ret); } SILC_LOG_DEBUG(("Wrote data %d bytes", ret)); return ret; } /* Reads data from the socket connection into the incoming data buffer. It reads as much as possible from the socket connection. This returns amount of bytes read or -1 on error or -2 on case where all of the data could not be read at once. */ int silc_socket_read(SilcSocketConnection sock) { int len = 0; unsigned char buf[SILC_SOCKET_READ_SIZE]; if (SILC_IS_DISABLED(sock)) return -1; SILC_LOG_DEBUG(("Reading data from socket %d", sock->sock)); /* Read the data from the socket. */ len = recv(sock->sock, buf, sizeof(buf), 0); if (len == -1) { if (errno == EWOULDBLOCK || errno == EINTR) { SILC_LOG_DEBUG(("Could not read immediately, will do it later")); return -2; } SILC_LOG_ERROR(("Cannot read from socket: %d", sock->sock)); sock->sock_error = errno; return -1; } if (!len) return 0; /* Insert the data to the buffer. */ if (!sock->inbuf) sock->inbuf = silc_buffer_alloc(SILC_SOCKET_BUF_SIZE); /* If the data does not fit to the buffer reallocate it */ if ((sock->inbuf->end - sock->inbuf->tail) < len) sock->inbuf = silc_buffer_realloc(sock->inbuf, sock->inbuf->truelen + (len * 2)); silc_buffer_put_tail(sock->inbuf, buf, len); silc_buffer_pull_tail(sock->inbuf, len); SILC_LOG_DEBUG(("Read %d bytes", len)); return len; } /* Returns human readable socket error message */ bool silc_socket_get_error(SilcSocketConnection sock, char *error, SilcUInt32 error_len) { /* XXX TODO */ return FALSE; }