routines for reading and writing data.
+2003-11-06 Hrvoje Niksic <hniksic@xemacs.org>
+
+ * connect.c: Updated all callers of
+ iread/ssl_iread/iwrite/ssl_iwrite to use xread and xwrite instead.
+
+ * rbuf.h (struct rbuf): Removed the SSL member because SSL is
+ handled automatically by xread.
+
+ * hash.c (ptrhash): Made private.
+ (ptrcmp): Ditto.
+ (inthash): Removed.
+
+ * connect.c (select_fd): Don't set errno, leave it to the caller.
+
+ * gen_sslfunc.c (connect_ssl): Use register_extended to register
+ SSL callbacks for communication with SSL-enabled endpoints.
+ (ssl_read): New function.
+ (ssl_write): Ditto.
+ (ssl_poll): Ditto.
+ (ssl_close): Ditto.
+
+ * connect.c (register_extended): New function -- register
+ callbacks for basic socket operations.
+ (xread): Ditto.
+ (xwrite): Ditto.
+ (xclose): Ditto.
+ (sock_read): New function, default implementation for reading.
+ (sock_write): Ditto for writing.
+ (sock_poll): Ditto for polling.
+ (sock_close): Ditto for closing.
+
2003-11-05 Hrvoje Niksic <hniksic@xemacs.org>
* connect.c (bindport): Fix compilation under pre-C99 compilers.
#include "utils.h"
#include "host.h"
#include "connect.h"
+#include "hash.h"
#ifndef errno
extern int errno;
logprintf. */
int save_errno = errno;
if (sock >= 0)
- CLOSE (sock);
+ xclose (sock);
if (print)
logprintf (LOG_VERBOSE, "failed: %s.\n", strerror (errno));
errno = save_errno;
sockaddr_set_data (sa, bind_address, *port);
if (bind (sock, sa, sockaddr_size (sa)) < 0)
{
- CLOSE (sock);
+ xclose (sock);
return BINDERR;
}
DEBUGP (("Local socket fd %d bound.\n", sock));
socklen_t sa_len = sockaddr_size (sa);
if (getsockname (sock, sa, &sa_len) < 0)
{
- CLOSE (sock);
+ xclose (sock);
return CONPORTERR;
}
sockaddr_get_data (sa, NULL, port);
}
if (listen (sock, 1) < 0)
{
- CLOSE (sock);
+ xclose (sock);
return LISTENERR;
}
*local_sock = sock;
#ifdef HAVE_SELECT
/* Wait for file descriptor FD to be readable or writable or both,
timing out after MAXTIME seconds. Returns 1 if FD is available, 0
- for timeout and -1 for error. The argument WHAT can be a
+ for timeout and -1 for error. The argument WAIT_FOR can be a
combination of WAIT_READ and WAIT_WRITE.
This is a mere convenience wrapper around the select call, and
should be taken as such. */
int
-select_fd (int fd, double maxtime, int wait)
+select_fd (int fd, double maxtime, int wait_for)
{
fd_set fdset;
fd_set *rd = NULL, *wr = NULL;
FD_ZERO (&fdset);
FD_SET (fd, &fdset);
- if (wait & WAIT_READ)
+ if (wait_for & WAIT_FOR_READ)
rd = &fdset;
- if (wait & WAIT_WRITE)
+ if (wait_for & WAIT_FOR_WRITE)
wr = &fdset;
- tmout.tv_sec = (long)maxtime;
- tmout.tv_usec = 1000000L * (maxtime - (long)maxtime);
+ tmout.tv_sec = (long) maxtime;
+ tmout.tv_usec = 1000000L * (maxtime - (long) maxtime);
do
result = select (fd + 1, rd, wr, NULL, &tmout);
while (result < 0 && errno == EINTR);
- /* When we've timed out, set errno to ETIMEDOUT for the convenience
- of the caller. */
- if (result == 0)
- errno = ETIMEDOUT;
-
return result;
}
#endif /* HAVE_SELECT */
#ifdef HAVE_SELECT
if (opt.connect_timeout)
- if (select_fd (local_sock, opt.connect_timeout, WAIT_READ) <= 0)
+ if (select_fd (local_sock, opt.connect_timeout, WAIT_FOR_READ) <= 0)
return ACCEPTERR;
#endif
if ((*sock = accept (local_sock, sa, &addrlen)) < 0)
return 0;
}
+\f
+/* Basic socket operations, mostly EINTR wrappers. */
+
+#ifdef WINDOWS
+# define read(fd, buf, cnt) recv (fd, buf, cnt, 0)
+# define write(fd, buf, cnt) send (fd, buf, cnt, 0)
+# define close(fd) closesocket (fd)
+#endif
-/* Read at most LEN bytes from FD, storing them to BUF. This is
- virtually the same as read(), but takes care of EINTR braindamage
- and uses select() to timeout the stale connections (a connection is
- stale if more than OPT.READ_TIMEOUT time is spent in select() or
- read()). */
+#ifdef __BEOS__
+# define read(fd, buf, cnt) recv (fd, buf, cnt, 0)
+# define write(fd, buf, cnt) send (fd, buf, cnt, 0)
+#endif
-int
-iread (int fd, char *buf, int len)
+static int
+sock_read (int fd, char *buf, int bufsize)
{
int res;
-
-#ifdef HAVE_SELECT
- if (opt.read_timeout)
- if (select_fd (fd, opt.read_timeout, WAIT_READ) <= 0)
- return -1;
-#endif
do
- res = READ (fd, buf, len);
+ res = read (fd, buf, bufsize);
while (res == -1 && errno == EINTR);
+ return res;
+}
+static int
+sock_write (int fd, char *buf, int bufsize)
+{
+ int res = 0;
+ do
+ res = write (fd, buf, bufsize);
+ while (res == -1 && errno == EINTR);
return res;
}
-/* Write LEN bytes from BUF to FD. This is similar to iread(), but
- unlike iread(), it makes sure that all of BUF is actually written
- to FD, so callers needn't bother with checking that the return
- value equals to LEN. Instead, you should simply check for -1. */
+static int
+sock_poll (int fd, double timeout, int wait_for)
+{
+#ifdef HAVE_SELECT
+ return select_fd (fd, timeout, wait_for);
+#else
+ return 1;
+#endif
+}
+
+static void
+sock_close (int fd)
+{
+ close (fd);
+ DEBUGP (("Closed fd %d\n", fd));
+}
+#undef read
+#undef write
+#undef close
+\f
+/* Reading and writing from the network. We build around the socket
+ (file descriptor) API, but support "extended" operations for things
+ that are not mere file descriptors under the hood, such as SSL
+ sockets.
+
+ That way the user code can call xread(fd, ...) and we'll run read
+ or SSL_read or whatever is necessary. */
+
+static struct hash_table *extended_map;
+static long extended_map_modified_tick;
+
+struct extended_info {
+ xreader_t reader;
+ xwriter_t writer;
+ xpoller_t poller;
+ xcloser_t closer;
+ void *ctx;
+};
+
+void
+register_extended (int fd, xreader_t reader, xwriter_t writer,
+ xpoller_t poller, xcloser_t closer, void *ctx)
+{
+ struct extended_info *info = xnew (struct extended_info);
+ info->reader = reader;
+ info->writer = writer;
+ info->poller = poller;
+ info->closer = closer;
+ info->ctx = ctx;
+ if (!extended_map)
+ extended_map = hash_table_new (0, NULL, NULL);
+ hash_table_put (extended_map, (void *) fd, info);
+ ++extended_map_modified_tick;
+}
+
+/* When xread/xwrite are called multiple times in a loop, they should
+ remember the INFO pointer instead of fetching it every time. It is
+ not enough to compare FD to LAST_FD because FD might have been
+ closed and reopened. modified_tick ensures that changes to
+ extended_map will not be unnoticed.
+
+ This is a macro because we want the static storage variables to be
+ per-function. */
+
+#define LAZY_RETRIEVE_INFO(info) do { \
+ static struct extended_info *last_info; \
+ static int last_fd = -1, last_tick; \
+ if (!extended_map) \
+ info = NULL; \
+ else if (last_fd == fd && last_tick == extended_map_modified_tick) \
+ info = last_info; \
+ else \
+ { \
+ info = hash_table_get (extended_map, (void *) fd); \
+ last_fd = fd; \
+ last_tick = extended_map_modified_tick; \
+ } \
+} while (0)
+
+/* Read no more than BUFSIZE bytes of data from FD, storing them to
+ BUF. If TIMEOUT is non-zero, the operation aborts if no data is
+ received after that many seconds. If TIMEOUT is -1, the value of
+ opt.timeout is used for TIMEOUT. */
int
-iwrite (int fd, char *buf, int len)
+xread (int fd, char *buf, int bufsize, double timeout)
{
- int res = 0;
+ struct extended_info *info;
+ LAZY_RETRIEVE_INFO (info);
+ if (timeout == -1)
+ timeout = opt.read_timeout;
+ if (timeout)
+ {
+ int test;
+ if (info && info->poller)
+ test = info->poller (fd, timeout, WAIT_FOR_READ, info->ctx);
+ else
+ test = sock_poll (fd, timeout, WAIT_FOR_READ);
+ if (test == 0)
+ errno = ETIMEDOUT;
+ if (test <= 0)
+ return -1;
+ }
+ if (info && info->reader)
+ return info->reader (fd, buf, bufsize, info->ctx);
+ else
+ return sock_read (fd, buf, bufsize);
+}
- /* `write' may write less than LEN bytes, thus the outward loop
- keeps trying it until all was written, or an error occurred. The
- inner loop is reserved for the usual EINTR f*kage, and the
- innermost loop deals with the same during select(). */
- while (len > 0)
+/* Write the entire contents of BUF to FD. If TIMEOUT is non-zero,
+ the operation aborts if no data is received after that many
+ seconds. If TIMEOUT is -1, the value of opt.timeout is used for
+ TIMEOUT. */
+
+int
+xwrite (int fd, char *buf, int bufsize, double timeout)
+{
+ int res;
+ struct extended_info *info;
+ LAZY_RETRIEVE_INFO (info);
+ if (timeout == -1)
+ timeout = opt.read_timeout;
+
+ /* `write' may write less than LEN bytes, thus the loop keeps trying
+ it until all was written, or an error occurred. */
+ res = 0;
+ while (bufsize > 0)
{
-#ifdef HAVE_SELECT
- if (opt.read_timeout)
- if (select_fd (fd, opt.read_timeout, WAIT_WRITE) <= 0)
- return -1;
-#endif
- do
- res = WRITE (fd, buf, len);
- while (res == -1 && errno == EINTR);
+ if (timeout)
+ {
+ int test;
+ if (info && info->poller)
+ test = info->poller (fd, timeout, WAIT_FOR_WRITE, info->ctx);
+ else
+ test = sock_poll (fd, timeout, WAIT_FOR_WRITE);
+ if (test == 0)
+ errno = ETIMEDOUT;
+ if (test <= 0)
+ return -1;
+ }
+ if (info && info->writer)
+ res = info->writer (fd, buf, bufsize, info->ctx);
+ else
+ res = sock_write (fd, buf, bufsize);
if (res <= 0)
break;
buf += res;
- len -= res;
+ bufsize -= res;
}
return res;
}
+
+/* Close the file descriptor FD. */
+
+void
+xclose (int fd)
+{
+ struct extended_info *info;
+ if (fd < 0)
+ return;
+
+ /* We don't need to be extra-fast here, so save some code by
+ avoiding LAZY_RETRIEVE_INFO. */
+ info = NULL;
+ if (extended_map)
+ info = hash_table_get (extended_map, (void *) fd);
+
+ if (info && info->closer)
+ {
+ info->closer (fd, info->ctx);
+ hash_table_remove (extended_map, (void *) fd);
+ xfree (info);
+ ++extended_map_modified_tick;
+ }
+ else
+ sock_close (fd);
+}
#include "host.h" /* for definition of ip_address */
-/* Returned by connect_to_host when host name cannot be resolved. */
-enum {
- E_HOST = -100
-};
-
-/* Flags for select_fd's WAIT argument. */
-enum {
- WAIT_READ = 1,
- WAIT_WRITE = 2
-};
-
/* bindport flags */
#define BIND_ON_IPV4_ONLY LH_IPV4_ONLY
#define BIND_ON_IPV6_ONLY LH_IPV6_ONLY
/* Function declarations */
-int connect_to_ip PARAMS ((const ip_address *, int, const char *));
+/* Returned by connect_to_host when host name cannot be resolved. */
+enum {
+ E_HOST = -100
+};
int connect_to_host PARAMS ((const char *, int));
+int connect_to_ip PARAMS ((const ip_address *, int, const char *));
void sockaddr_get_data PARAMS ((const struct sockaddr *, ip_address *, int *));
-
-int test_socket_open PARAMS ((int));
-int select_fd PARAMS ((int, double, int));
uerr_t bindport PARAMS ((const ip_address *, int *, int *));
uerr_t acceptport PARAMS ((int, int *));
int conaddr PARAMS ((int, ip_address *));
-int iread PARAMS ((int, char *, int));
-int iwrite PARAMS ((int, char *, int));
+/* Flags for select_fd's WAIT_FOR argument. */
+enum {
+ WAIT_FOR_READ = 1,
+ WAIT_FOR_WRITE = 2
+};
+int select_fd PARAMS ((int, double, int));
+int test_socket_open PARAMS ((int));
+typedef int (*xreader_t) PARAMS ((int, char *, int, void *));
+typedef int (*xwriter_t) PARAMS ((int, char *, int, void *));
+typedef int (*xpoller_t) PARAMS ((int, double, int, void *));
+typedef void (*xcloser_t) PARAMS ((int, void *));
+void register_extended PARAMS ((int,
+ xreader_t, xwriter_t, xpoller_t, xcloser_t,
+ void *));
+
+int xread PARAMS ((int, char *, int, double));
+int xwrite PARAMS ((int, char *, int, double));
+void xclose PARAMS ((int));
#endif /* CONNECT_H */
xfree (respline);
/* Send USER username. */
request = ftp_request ("USER", acc);
- nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
+ nwritten = xwrite (RBUF_FD (rbuf), request, strlen (request), -1);
if (nwritten < 0)
{
xfree (request);
xfree (respline);
/* Send PASS password. */
request = ftp_request ("PASS", pass);
- nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
+ nwritten = xwrite (RBUF_FD (rbuf), request, strlen (request), -1);
if (nwritten < 0)
{
xfree (request);
/* Send PORT request. */
request = ftp_request ("PORT", bytes);
- nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
+ nwritten = xwrite (RBUF_FD (rbuf), request, strlen (request), -1);
if (nwritten < 0)
{
xfree (request);
- CLOSE (*local_sock);
+ xclose (*local_sock);
return WRITEFAILED;
}
xfree (request);
if (err != FTPOK)
{
xfree (respline);
- CLOSE (*local_sock);
+ xclose (*local_sock);
return err;
}
if (*respline != '2')
{
xfree (respline);
- CLOSE (*local_sock);
+ xclose (*local_sock);
return FTPPORTERR;
}
xfree (respline);
/* Send PORT request. */
request = ftp_request ("LPRT", bytes);
- nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
+ nwritten = xwrite (RBUF_FD (rbuf), request, strlen (request), -1);
if (nwritten < 0)
{
xfree (request);
- CLOSE (*local_sock);
+ xclose (*local_sock);
return WRITEFAILED;
}
xfree (request);
if (err != FTPOK)
{
xfree (respline);
- CLOSE (*local_sock);
+ xclose (*local_sock);
return err;
}
if (*respline != '2')
{
xfree (respline);
- CLOSE (*local_sock);
+ xclose (*local_sock);
return FTPPORTERR;
}
xfree (respline);
/* Send PORT request. */
request = ftp_request ("EPRT", bytes);
- nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
+ nwritten = xwrite (RBUF_FD (rbuf), request, strlen (request), -1);
if (nwritten < 0)
{
xfree (request);
- CLOSE (*local_sock);
+ xclose (*local_sock);
return WRITEFAILED;
}
xfree (request);
if (err != FTPOK)
{
xfree (respline);
- CLOSE (*local_sock);
+ xclose (*local_sock);
return err;
}
if (*respline != '2')
{
xfree (respline);
- CLOSE (*local_sock);
+ xclose (*local_sock);
return FTPPORTERR;
}
xfree (respline);
/* Form the request. */
request = ftp_request ("PASV", NULL);
/* And send it. */
- nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
+ nwritten = xwrite (RBUF_FD (rbuf), request, strlen (request), -1);
if (nwritten < 0)
{
xfree (request);
request = ftp_request ("LPSV", NULL);
/* And send it. */
- nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
+ nwritten = xwrite (RBUF_FD (rbuf), request, strlen (request), -1);
if (nwritten < 0)
{
xfree (request);
request = ftp_request ("EPSV", (sa->sa_family == AF_INET ? "1" : "2"));
/* And send it. */
- nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
+ nwritten = xwrite (RBUF_FD (rbuf), request, strlen (request), -1);
if (nwritten < 0)
{
xfree (request);
stype[1] = 0;
/* Send TYPE request. */
request = ftp_request ("TYPE", stype);
- nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
+ nwritten = xwrite (RBUF_FD (rbuf), request, strlen (request), -1);
if (nwritten < 0)
{
xfree (request);
/* Send CWD request. */
request = ftp_request ("CWD", dir);
- nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
+ nwritten = xwrite (RBUF_FD (rbuf), request, strlen (request), -1);
if (nwritten < 0)
{
xfree (request);
number_to_string (numbuf, offset);
request = ftp_request ("REST", numbuf);
- nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
+ nwritten = xwrite (RBUF_FD (rbuf), request, strlen (request), -1);
if (nwritten < 0)
{
xfree (request);
/* Send RETR request. */
request = ftp_request ("RETR", file);
- nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
+ nwritten = xwrite (RBUF_FD (rbuf), request, strlen (request), -1);
if (nwritten < 0)
{
xfree (request);
/* Send LIST request. */
request = ftp_request ("LIST", file);
- nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
+ nwritten = xwrite (RBUF_FD (rbuf), request, strlen (request), -1);
if (nwritten < 0)
{
xfree (request);
/* Send SYST request. */
request = ftp_request ("SYST", NULL);
- nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
+ nwritten = xwrite (RBUF_FD (rbuf), request, strlen (request), -1);
if (nwritten < 0)
{
xfree (request);
/* Send PWD request. */
request = ftp_request ("PWD", NULL);
- nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
+ nwritten = xwrite (RBUF_FD (rbuf), request, strlen (request), -1);
if (nwritten < 0)
{
xfree (request);
/* Send PWD request. */
request = ftp_request ("SIZE", file);
- nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
+ nwritten = xwrite (RBUF_FD (rbuf), request, strlen (request), -1);
if (nwritten < 0)
{
xfree (request);
logputs (LOG_VERBOSE, "\n");
logputs (LOG_NOTQUIET, _("\
Error in server response, closing control connection.\n"));
- CLOSE (csock);
+ xclose (csock);
rbuf_uninitialize (&con->rbuf);
return err;
break;
case FTPSRVERR:
logputs (LOG_VERBOSE, "\n");
logputs (LOG_NOTQUIET, _("Error in server greeting.\n"));
- CLOSE (csock);
+ xclose (csock);
rbuf_uninitialize (&con->rbuf);
return err;
break;
logputs (LOG_VERBOSE, "\n");
logputs (LOG_NOTQUIET,
_("Write failed, closing control connection.\n"));
- CLOSE (csock);
+ xclose (csock);
rbuf_uninitialize (&con->rbuf);
return err;
break;
case FTPLOGREFUSED:
logputs (LOG_VERBOSE, "\n");
logputs (LOG_NOTQUIET, _("The server refuses login.\n"));
- CLOSE (csock);
+ xclose (csock);
rbuf_uninitialize (&con->rbuf);
return FTPLOGREFUSED;
break;
case FTPLOGINC:
logputs (LOG_VERBOSE, "\n");
logputs (LOG_NOTQUIET, _("Login incorrect.\n"));
- CLOSE (csock);
+ xclose (csock);
rbuf_uninitialize (&con->rbuf);
return FTPLOGINC;
break;
logputs (LOG_VERBOSE, "\n");
logputs (LOG_NOTQUIET, _("\
Error in server response, closing control connection.\n"));
- CLOSE (csock);
+ xclose (csock);
rbuf_uninitialize (&con->rbuf);
return err;
break;
logputs (LOG_VERBOSE, "\n");
logputs (LOG_NOTQUIET, _("\
Error in server response, closing control connection.\n"));
- CLOSE (csock);
+ xclose (csock);
rbuf_uninitialize (&con->rbuf);
return err;
break;
logputs (LOG_VERBOSE, "\n");
logputs (LOG_NOTQUIET, _("\
Error in server response, closing control connection.\n"));
- CLOSE (csock);
+ xclose (csock);
rbuf_uninitialize (&con->rbuf);
return err;
break;
logputs (LOG_VERBOSE, "\n");
logputs (LOG_NOTQUIET,
_("Write failed, closing control connection.\n"));
- CLOSE (csock);
+ xclose (csock);
rbuf_uninitialize (&con->rbuf);
return err;
break;
logprintf (LOG_NOTQUIET,
_("Unknown type `%c', closing control connection.\n"),
type_char);
- CLOSE (csock);
+ xclose (csock);
rbuf_uninitialize (&con->rbuf);
return err;
case FTPOK:
logputs (LOG_VERBOSE, "\n");
logputs (LOG_NOTQUIET, _("\
Error in server response, closing control connection.\n"));
- CLOSE (csock);
+ xclose (csock);
rbuf_uninitialize (&con->rbuf);
return err;
break;
logputs (LOG_VERBOSE, "\n");
logputs (LOG_NOTQUIET,
_("Write failed, closing control connection.\n"));
- CLOSE (csock);
+ xclose (csock);
rbuf_uninitialize (&con->rbuf);
return err;
break;
logputs (LOG_VERBOSE, "\n");
logprintf (LOG_NOTQUIET, _("No such directory `%s'.\n\n"),
u->dir);
- CLOSE (csock);
+ xclose (csock);
rbuf_uninitialize (&con->rbuf);
return err;
break;
logputs (LOG_VERBOSE, "\n");
logputs (LOG_NOTQUIET, _("\
Error in server response, closing control connection.\n"));
- CLOSE (csock);
+ xclose (csock);
rbuf_uninitialize (&con->rbuf);
return err;
break;
logputs (LOG_VERBOSE, "\n");
logputs (LOG_NOTQUIET, _("\
Error in server response, closing control connection.\n"));
- CLOSE (csock);
+ xclose (csock);
rbuf_uninitialize (&con->rbuf);
return err;
break;
logputs (LOG_VERBOSE, "\n");
logputs (LOG_NOTQUIET,
_("Write failed, closing control connection.\n"));
- CLOSE (csock);
+ xclose (csock);
rbuf_uninitialize (&con->rbuf);
return err;
break;
if (dtsock < 0)
{
int save_errno = errno;
- CLOSE (csock);
+ xclose (csock);
rbuf_uninitialize (&con->rbuf);
logprintf (LOG_VERBOSE, _("couldn't connect to %s port %hu: %s\n"),
pretty_print_address (&passive_addr), passive_port,
logputs (LOG_VERBOSE, "\n");
logputs (LOG_NOTQUIET, _("\
Error in server response, closing control connection.\n"));
- CLOSE (csock);
- CLOSE (dtsock);
- CLOSE (local_sock);
+ xclose (csock);
+ xclose (dtsock);
+ xclose (local_sock);
rbuf_uninitialize (&con->rbuf);
return err;
break;
logputs (LOG_VERBOSE, "\n");
logputs (LOG_NOTQUIET,
_("Write failed, closing control connection.\n"));
- CLOSE (csock);
- CLOSE (dtsock);
- CLOSE (local_sock);
+ xclose (csock);
+ xclose (dtsock);
+ xclose (local_sock);
rbuf_uninitialize (&con->rbuf);
return err;
break;
case CONSOCKERR:
logputs (LOG_VERBOSE, "\n");
logprintf (LOG_NOTQUIET, "socket: %s\n", strerror (errno));
- CLOSE (csock);
- CLOSE (dtsock);
- CLOSE (local_sock);
+ xclose (csock);
+ xclose (dtsock);
+ xclose (local_sock);
rbuf_uninitialize (&con->rbuf);
return err;
break;
logputs (LOG_VERBOSE, "\n");
logprintf (LOG_NOTQUIET, _("Bind error (%s).\n"),
strerror (errno));
- CLOSE (dtsock);
- CLOSE (local_sock);
+ xclose (dtsock);
+ xclose (local_sock);
return err;
break;
case FTPPORTERR:
logputs (LOG_VERBOSE, "\n");
logputs (LOG_NOTQUIET, _("Invalid PORT.\n"));
- CLOSE (csock);
- CLOSE (dtsock);
- CLOSE (local_sock);
+ xclose (csock);
+ xclose (dtsock);
+ xclose (local_sock);
rbuf_uninitialize (&con->rbuf);
return err;
break;
logputs (LOG_VERBOSE, "\n");
logputs (LOG_NOTQUIET, _("\
Error in server response, closing control connection.\n"));
- CLOSE (csock);
- CLOSE (dtsock);
- CLOSE (local_sock);
+ xclose (csock);
+ xclose (dtsock);
+ xclose (local_sock);
rbuf_uninitialize (&con->rbuf);
return err;
break;
logputs (LOG_VERBOSE, "\n");
logputs (LOG_NOTQUIET,
_("Write failed, closing control connection.\n"));
- CLOSE (csock);
- CLOSE (dtsock);
- CLOSE (local_sock);
+ xclose (csock);
+ xclose (dtsock);
+ xclose (local_sock);
rbuf_uninitialize (&con->rbuf);
return err;
break;
logprintf (LOG_NOTQUIET,
_("\nREST failed; will not truncate `%s'.\n"),
con->target);
- CLOSE (csock);
- CLOSE (dtsock);
- CLOSE (local_sock);
+ xclose (csock);
+ xclose (dtsock);
+ xclose (local_sock);
rbuf_uninitialize (&con->rbuf);
return CONTNOTSUPPORTED;
}
request. */
if (opt.spider)
{
- CLOSE (csock);
- CLOSE (dtsock);
- CLOSE (local_sock);
+ xclose (csock);
+ xclose (dtsock);
+ xclose (local_sock);
rbuf_uninitialize (&con->rbuf);
return RETRFINISHED;
}
logputs (LOG_VERBOSE, "\n");
logputs (LOG_NOTQUIET, _("\
Error in server response, closing control connection.\n"));
- CLOSE (csock);
- CLOSE (dtsock);
- CLOSE (local_sock);
+ xclose (csock);
+ xclose (dtsock);
+ xclose (local_sock);
rbuf_uninitialize (&con->rbuf);
return err;
break;
logputs (LOG_VERBOSE, "\n");
logputs (LOG_NOTQUIET,
_("Write failed, closing control connection.\n"));
- CLOSE (csock);
- CLOSE (dtsock);
- CLOSE (local_sock);
+ xclose (csock);
+ xclose (dtsock);
+ xclose (local_sock);
rbuf_uninitialize (&con->rbuf);
return err;
break;
case FTPNSFOD:
logputs (LOG_VERBOSE, "\n");
logprintf (LOG_NOTQUIET, _("No such file `%s'.\n\n"), u->file);
- CLOSE (dtsock);
- CLOSE (local_sock);
+ xclose (dtsock);
+ xclose (local_sock);
return err;
break;
case FTPOK:
logputs (LOG_VERBOSE, "\n");
logputs (LOG_NOTQUIET, _("\
Error in server response, closing control connection.\n"));
- CLOSE (csock);
- CLOSE (dtsock);
- CLOSE (local_sock);
+ xclose (csock);
+ xclose (dtsock);
+ xclose (local_sock);
rbuf_uninitialize (&con->rbuf);
return err;
break;
logputs (LOG_VERBOSE, "\n");
logputs (LOG_NOTQUIET,
_("Write failed, closing control connection.\n"));
- CLOSE (csock);
- CLOSE (dtsock);
- CLOSE (local_sock);
+ xclose (csock);
+ xclose (dtsock);
+ xclose (local_sock);
rbuf_uninitialize (&con->rbuf);
return err;
break;
logputs (LOG_VERBOSE, "\n");
logprintf (LOG_NOTQUIET, _("No such file or directory `%s'.\n\n"),
".");
- CLOSE (dtsock);
- CLOSE (local_sock);
+ xclose (dtsock);
+ xclose (local_sock);
return err;
break;
case FTPOK:
if (!fp)
{
logprintf (LOG_NOTQUIET, "%s: %s\n", con->target, strerror (errno));
- CLOSE (csock);
+ xclose (csock);
rbuf_uninitialize (&con->rbuf);
- CLOSE (dtsock);
- CLOSE (local_sock);
+ xclose (dtsock);
+ xclose (local_sock);
return FOPENERR;
}
}
tms = time_str (NULL);
tmrate = retr_rate (*len - restval, con->dltime, 0);
/* Close data connection socket. */
- CLOSE (dtsock);
- CLOSE (local_sock);
+ xclose (dtsock);
+ xclose (local_sock);
/* Close the local file. */
{
/* Close or flush the file. We have to be careful to check for
{
logprintf (LOG_NOTQUIET, _("%s: %s, closing control connection.\n"),
con->target, strerror (errno));
- CLOSE (csock);
+ xclose (csock);
rbuf_uninitialize (&con->rbuf);
return FWRITEERR;
}
return FTPRETRINT, since there is a possibility that the
whole file was retrieved nevertheless (but that is for
ftp_loop_internal to decide). */
- CLOSE (csock);
+ xclose (csock);
rbuf_uninitialize (&con->rbuf);
return FTPRETRINT;
} /* err != FTPOK */
{
/* I should probably send 'QUIT' and check for a reply, but this
is faster. #### Is it OK, though? */
- CLOSE (csock);
+ xclose (csock);
rbuf_uninitialize (&con->rbuf);
}
/* If it was a listing, and opt.server_response is true,
if (con->st & ON_YOUR_OWN)
{
- CLOSE (RBUF_FD (&con->rbuf));
+ xclose (RBUF_FD (&con->rbuf));
rbuf_uninitialize (&con->rbuf);
}
if (!opt.spider)
if (rbuf_initialized_p (&con->rbuf) && (con->st & ON_YOUR_OWN))
{
- CLOSE (RBUF_FD (&con->rbuf));
+ xclose (RBUF_FD (&con->rbuf));
rbuf_uninitialize (&con->rbuf);
}
return TRYLIMEXC;
*dt |= RETROKF;
/* If a connection was left, quench it. */
if (rbuf_initialized_p (&con.rbuf))
- CLOSE (RBUF_FD (&con.rbuf));
+ xclose (RBUF_FD (&con.rbuf));
xfree_null (con.id);
con.id = NULL;
xfree_null (con.target);
#include <config.h>
-#ifdef HAVE_SSL
-
#include <assert.h>
#include <errno.h>
#ifdef HAVE_UNISTD_H
return 0; /* Succeded */
}
-void
-shutdown_ssl (SSL* con)
+static
+int ssl_read (int fd, char *buf, int bufsize, void *ctx)
{
- if (con == NULL)
- return;
- if (0==SSL_shutdown (con))
- SSL_shutdown (con);
- SSL_free (con);
+ int res;
+ SSL *ssl = (SSL *) ctx;
+ /* #### Does SSL_read actually set EINTR? */
+ do
+ res = SSL_read (ssl, buf, bufsize);
+ while (res == -1 && errno == EINTR);
+ return res;
}
-/* Sets up a SSL structure and performs the handshake on fd
- Returns 0 if everything went right
- Returns 1 if something went wrong ----- TODO: More exit codes
-*/
-int
-connect_ssl (SSL **con, SSL_CTX *ctx, int fd)
+static int
+ssl_write (int fd, char *buf, int bufsize, void *ctx)
{
- if (NULL == (*con = SSL_new (ctx)))
- {
- ssl_printerrors ();
- return 1;
- }
- if (!SSL_set_fd (*con, fd))
- {
- ssl_printerrors ();
- return 1;
- }
- SSL_set_connect_state (*con);
- switch (SSL_connect (*con))
- {
- case 1 :
- return (*con)->state != SSL_ST_OK;
- default:
- ssl_printerrors ();
- shutdown_ssl (*con);
- *con = NULL;
- return 1;
- case 0 :
- ssl_printerrors ();
- SSL_free (*con);
- *con = NULL;
- return 1;
- }
- return 0;
+ int res = 0;
+ SSL *ssl = (SSL *) ctx;
+ /* #### Does SSL_write actually set EINTR? */
+ do
+ res = SSL_write (ssl, buf, bufsize);
+ while (res == -1 && errno == EINTR);
+ return res;
}
-void
-free_ssl_ctx (SSL_CTX * ctx)
+static int
+ssl_poll (int fd, double timeout, int wait_for, void *ctx)
{
- SSL_CTX_free (ctx);
+ SSL *ssl = (SSL *) ctx;
+ if (timeout == 0)
+ return 1;
+ if (SSL_pending (ssl))
+ return 1;
+#ifdef HAVE_SELECT
+ return select_fd (fd, timeout, wait_for);
+#else
+ return 1;
+#endif
}
-/* SSL version of iread. Only exchanged read for SSL_read Read at
- most LEN bytes from FD, storing them to BUF. */
-
-int
-ssl_iread (SSL *con, char *buf, int len)
+static void
+ssl_close (int fd, void *ctx)
{
- int res, fd;
- BIO_get_fd (con->rbio, &fd);
-#ifdef HAVE_SELECT
- if (opt.read_timeout && !SSL_pending (con))
- if (select_fd (fd, opt.read_timeout, WAIT_READ) <= 0)
- return -1;
+ SSL *ssl = (SSL *) ctx;
+ SSL_shutdown (ssl);
+ SSL_free (ssl);
+
+#ifdef WINDOWS
+ closesocket (fd);
+#else
+ close (fd);
#endif
- do
- res = SSL_read (con, buf, len);
- while (res == -1 && errno == EINTR);
- return res;
+ DEBUGP (("Closed %d/SSL 0x%0lx\n", fd, (unsigned long) ssl));
}
-/* SSL version of iwrite. Only exchanged write for SSL_write Write
- LEN bytes from BUF to FD. */
+/* Sets up a SSL structure and performs the handshake on fd. */
-int
-ssl_iwrite (SSL *con, char *buf, int len)
+SSL *
+connect_ssl (int fd, SSL_CTX *ctx)
{
- int res = 0, fd;
- BIO_get_fd (con->rbio, &fd);
- /* `write' may write less than LEN bytes, thus the outward loop
- keeps trying it until all was written, or an error occurred. The
- inner loop is reserved for the usual EINTR f*kage, and the
- innermost loop deals with the same during select(). */
- while (len > 0)
- {
-#ifdef HAVE_SELECT
- if (opt.read_timeout)
- if (select_fd (fd, opt.read_timeout, WAIT_WRITE) <= 0)
- return -1;
-#endif
- do
- res = SSL_write (con, buf, len);
- while (res == -1 && errno == EINTR);
- if (res <= 0)
- break;
- buf += res;
- len -= res;
- }
- return res;
+ SSL *ssl = SSL_new (ctx);
+ if (!ssl)
+ goto err;
+ if (!SSL_set_fd (ssl, fd))
+ goto err;
+ SSL_set_connect_state (ssl);
+ if (SSL_connect (ssl) <= 0 || ssl->state != SSL_ST_OK)
+ goto err;
+
+ /* Register the FD to use our functions for read, write, etc. That
+ way the rest of Wget can keep using xread, xwrite, and
+ friends. */
+ register_extended (fd, ssl_read, ssl_write, ssl_poll, ssl_close, ssl);
+ DEBUGP (("Connected %d to SSL 0x%0lx\n", fd, (unsigned long) ssl));
+ return ssl;
+
+ err:
+ ssl_printerrors ();
+ if (ssl)
+ SSL_free (ssl);
+ return NULL;
+}
+
+void
+free_ssl_ctx (SSL_CTX * ctx)
+{
+ SSL_CTX_free (ctx);
}
-#endif /* HAVE_SSL */
void ssl_init_prng PARAMS ((void));
int init_ssl PARAMS ((SSL_CTX **));
-int connect_ssl PARAMS ((SSL **, SSL_CTX *, int));
-void shutdown_ssl PARAMS ((SSL*));
+SSL *connect_ssl PARAMS ((int, SSL_CTX *));
void free_ssl_ctx PARAMS ((SSL_CTX *));
int verify_callback PARAMS ((int, X509_STORE_CTX *));
-int ssl_iread PARAMS ((SSL *, char *, int));
-int ssl_iwrite PARAMS ((SSL *, char *, int));
int ssl_printerrors PARAMS ((void));
#endif /* GEN_SSLFUNC_H */
return 0;
}
+static unsigned long ptrhash PARAMS ((const void *));
+static int ptrcmp PARAMS ((const void *, const void *));
+
/* Create a hash table with hash function HASH_FUNCTION and test
function TEST_FUNCTION. The table is empty (its count is 0), but
pre-allocated to store at least ITEMS items.
pointer identity. (Common Lisp calls them EQ hash tables, and Java
calls them IdentityHashMaps.) */
-unsigned long
+static unsigned long
ptrhash (const void *ptr)
{
unsigned long key = (unsigned long)ptr;
return key;
}
-int
+static int
ptrcmp (const void *ptr1, const void *ptr2)
{
return ptr1 == ptr2;
}
-
-#if 0
-/* Currently unused: hashing of integers. */
-
-unsigned long
-inthash (unsigned int key)
-{
- key += (key << 12);
- key ^= (key >> 22);
- key += (key << 4);
- key ^= (key >> 9);
- key += (key << 10);
- key ^= (key >> 2);
- key += (key << 7);
- key ^= (key >> 12);
- return key;
-}
-#endif
\f
#ifdef STANDALONE
struct hash_table *make_string_hash_table PARAMS ((int));
struct hash_table *make_nocase_string_hash_table PARAMS ((int));
-unsigned long ptrhash PARAMS ((const void *));
-int ptrcmp PARAMS ((const void *, const void *));
-
#endif /* HASH_H */
longer, read only that much; if the file is shorter, report an error. */
static int
-post_file (int sock, void *ssl, const char *file_name, long promised_size)
+post_file (int sock, const char *file_name, long promised_size)
{
static char chunk[8192];
long written = 0;
int write_error;
FILE *fp;
- /* Only one of SOCK and SSL may be active at the same time. */
- assert (sock > -1 || ssl != NULL);
- assert (sock == -1 || ssl == NULL);
-
DEBUGP (("[writing POST file %s ... ", file_name));
fp = fopen (file_name, "rb");
if (length == 0)
break;
towrite = WMIN (promised_size - written, length);
-#ifdef HAVE_SSL
- if (ssl)
- write_error = ssl_iwrite (ssl, chunk, towrite);
- else
-#endif
- write_error = iwrite (sock, chunk, towrite);
+ write_error = xwrite (sock, chunk, towrite, -1);
if (write_error < 0)
{
fclose (fp);
/* Whether a persistent connection is active. */
static int pc_active_p;
+
/* Host and port of currently active persistent connection. */
static struct address_list *pc_last_host_ip;
static unsigned short pc_last_port;
/* File descriptor of the currently active persistent connection. */
static int pc_last_fd;
-#ifdef HAVE_SSL
/* Whether a ssl handshake has occoured on this connection */
-static int pc_active_ssl;
-/* SSL connection of the currently active persistent connection. */
-static SSL *pc_last_ssl;
-#endif /* HAVE_SSL */
+static int pc_last_ssl_p;
/* Mark the persistent connection as invalid. This is used by the
CLOSE_* macros after they forcefully close a registered persistent
invalidate_persistent (void)
{
pc_active_p = 0;
-#ifdef HAVE_SSL
- pc_active_ssl = 0;
-#endif /* HAVE_SSL */
+ pc_last_ssl_p = 0;
if (pc_last_host_ip != NULL)
{
address_list_release (pc_last_host_ip);
If a previous connection was persistent, it is closed. */
-#ifdef HAVE_SSL
static void
-register_persistent (const char *host, unsigned short port, int fd, SSL *ssl)
+register_persistent (const char *host, unsigned short port, int fd, int ssl)
{
-#else
-static void
-register_persistent (const char *host, unsigned short port, int fd)
-{
-#endif
if (pc_active_p)
{
if (pc_last_fd == fd)
persistent connection exists, but we then connect to a
different host, and try to register a persistent
connection to that one. */
-#ifdef HAVE_SSL
- /* The ssl disconnect has to take place before the closing
- of pc_last_fd. */
- if (pc_last_ssl)
- shutdown_ssl(pc_last_ssl);
-#endif
- CLOSE (pc_last_fd);
+ xclose (pc_last_fd);
invalidate_persistent ();
}
}
pc_last_port = port;
pc_last_fd = fd;
pc_active_p = 1;
-#ifdef HAVE_SSL
- pc_last_ssl = ssl;
- pc_active_ssl = ssl ? 1 : 0;
-#endif
+ pc_last_ssl_p = ssl;
DEBUGP (("Registered fd %d for persistent reuse.\n", fd));
}
-#ifdef HAVE_SSL
-# define SHUTDOWN_SSL(ssl) do { \
- if (ssl) \
- shutdown_ssl (ssl); \
-} while (0)
-#else
-# define SHUTDOWN_SSL(ssl)
-#endif
-
/* Return non-zero if a persistent connection is available for
connecting to HOST:PORT. */
-#ifdef HAVE_SSL
static int
persistent_available_p (const char *host, unsigned short port, int ssl)
{
-#else
-static int
-persistent_available_p (const char *host, unsigned short port)
-{
-#endif
int success;
struct address_list *this_host_ip;
if (port != pc_last_port)
return 0;
-#ifdef HAVE_SSL
/* Second, a): check if current connection is (not) ssl, too. This
test is unlikely to fail because HTTP and HTTPS typicaly use
different ports. Yet it is possible, or so I [Christian
Fraenkel] have been told, to run HTTPS and HTTP simultaneus on
the same port. */
- if (ssl != pc_active_ssl)
+ if (ssl != pc_last_ssl_p)
return 0;
-#endif /* HAVE_SSL */
this_host_ip = lookup_host (host, LH_SILENT);
if (!this_host_ip)
/* Oops, the socket is no longer open. Now that we know that,
let's invalidate the persistent connection before returning
0. */
- CLOSE (pc_last_fd);
-#ifdef HAVE_SSL
- SHUTDOWN_SSL (pc_last_ssl);
- pc_last_ssl = NULL;
-#endif
+ xclose (pc_last_fd);
invalidate_persistent ();
return 0;
}
#define CLOSE_FINISH(fd) do { \
if (!keep_alive) \
{ \
- SHUTDOWN_SSL (ssl); \
- CLOSE (fd); \
+ xclose (fd); \
if (pc_active_p && (fd) == pc_last_fd) \
invalidate_persistent (); \
} \
} while (0)
#define CLOSE_INVALIDATE(fd) do { \
- SHUTDOWN_SSL (ssl); \
- CLOSE (fd); \
+ xclose (fd); \
if (pc_active_p && (fd) == pc_last_fd) \
invalidate_persistent (); \
} while (0)
struct rbuf rbuf;
#ifdef HAVE_SSL
static SSL_CTX *ssl_ctx = NULL;
- SSL *ssl = NULL;
#endif
+ int using_ssl = 0;
char *cookies = NULL;
/* Whether this connection will be kept alive after the HTTP request
/* First: establish the connection. */
if (inhibit_keep_alive
- ||
-#ifndef HAVE_SSL
- !persistent_available_p (conn->host, conn->port)
+ || !persistent_available_p (conn->host, conn->port,
+#ifdef HAVE_SSL
+ u->scheme == SCHEME_HTTPS
#else
- !persistent_available_p (conn->host, conn->port,
- u->scheme == SCHEME_HTTPS)
-#endif /* HAVE_SSL */
- )
+ 0
+#endif
+ ))
{
sock = connect_to_host (conn->host, conn->port);
if (sock == E_HOST)
#ifdef HAVE_SSL
if (conn->scheme == SCHEME_HTTPS)
- if (connect_ssl (&ssl, ssl_ctx,sock) != 0)
- {
- logputs (LOG_VERBOSE, "\n");
- logprintf (LOG_NOTQUIET, _("Unable to establish SSL connection.\n"));
- ssl_printerrors ();
- CLOSE (sock);
- return CONSSLERR;
- }
+ {
+ if (!connect_ssl (sock, ssl_ctx))
+ {
+ logputs (LOG_VERBOSE, "\n");
+ logprintf (LOG_NOTQUIET,
+ _("Unable to establish SSL connection.\n"));
+ xclose (sock);
+ return CONSSLERR;
+ }
+ using_ssl = 1;
+ }
#endif /* HAVE_SSL */
}
else
/* #### pc_last_fd should be accessed through an accessor
function. */
sock = pc_last_fd;
-#ifdef HAVE_SSL
- ssl = pc_last_ssl;
-#endif /* HAVE_SSL */
+ using_ssl = pc_last_ssl_p;
DEBUGP (("Reusing fd %d.\n", sock));
}
xfree (full_path);
/* Send the request to server. */
-#ifdef HAVE_SSL
- if (conn->scheme == SCHEME_HTTPS)
- write_error = ssl_iwrite (ssl, request, strlen (request));
- else
-#endif
- write_error = iwrite (sock, request, strlen (request));
+ write_error = xwrite (sock, request, strlen (request), -1);
if (write_error >= 0)
{
if (opt.post_data)
{
DEBUGP (("[POST data: %s]\n", opt.post_data));
-#ifdef HAVE_SSL
- if (conn->scheme == SCHEME_HTTPS)
- write_error = ssl_iwrite (ssl, opt.post_data, post_data_size);
- else
-#endif
- write_error = iwrite (sock, opt.post_data, post_data_size);
+ write_error = xwrite (sock, opt.post_data, post_data_size, -1);
}
else if (opt.post_file_name && post_data_size != 0)
- {
-#ifdef HAVE_SSL
- if (conn->scheme == SCHEME_HTTPS)
- write_error = post_file (-1, ssl, opt.post_file_name,
- post_data_size);
- else
-#endif
- write_error = post_file (sock, NULL, opt.post_file_name,
- post_data_size);
- }
+ write_error = post_file (sock, opt.post_file_name, post_data_size);
}
DEBUGP (("---request end---\n"));
/* Before reading anything, initialize the rbuf. */
rbuf_initialize (&rbuf, sock);
-#ifdef HAVE_SSL
- if (conn->scheme == SCHEME_HTTPS)
- rbuf.ssl = ssl;
- else
- rbuf.ssl = NULL;
-#endif /* HAVE_SSL */
all_headers = NULL;
all_length = 0;
/* Header-fetching loop. */
if (keep_alive)
/* The server has promised that it will not close the connection
when we're done. This means that we can register it. */
-#ifndef HAVE_SSL
- register_persistent (conn->host, conn->port, sock);
-#else
- register_persistent (conn->host, conn->port, sock, ssl);
-#endif /* HAVE_SSL */
+ register_persistent (conn->host, conn->port, sock, using_ssl);
if ((statcode == HTTP_STATUS_UNAUTHORIZED)
&& authenticate_h)
#define REALCLOSE(x) closesocket (x)
-/* read & write don't work with sockets on Windows 95. */
-#define READ(fd, buf, cnt) recv ((fd), (buf), (cnt), 0)
-#define WRITE(fd, buf, cnt) send ((fd), (buf), (cnt), 0)
-
/* #### Do we need this? */
#include <direct.h>
#include "rbuf.h"
#include "connect.h"
-#ifdef HAVE_SSL
-#include <openssl/bio.h>
-#include <openssl/crypto.h>
-#include <openssl/x509.h>
-#include <openssl/ssl.h>
-#include <openssl/err.h>
-#include <openssl/pem.h>
-#include "gen_sslfunc.h" /* for ssl_iread */
-#endif /* HAVE_SSL */
-
void
rbuf_initialize (struct rbuf *rbuf, int fd)
{
rbuf->fd = fd;
-#ifdef HAVE_SSL
-/* pointing ssl to NULL results in an unchanged behaviour */
- rbuf->ssl = NULL;
-#endif /* HAVE_SSL */
rbuf->buffer_pos = rbuf->buffer;
rbuf->buffer_left = 0;
}
int
rbuf_read_bufferful (struct rbuf *rbuf)
{
-#ifdef HAVE_SSL
- if (rbuf->ssl)
- return ssl_iread (rbuf->ssl, rbuf->buffer, sizeof (rbuf->buffer));
- else
-#endif
- return iread (rbuf->fd, rbuf->buffer, sizeof (rbuf->buffer));
+ return xread (rbuf->fd, rbuf->buffer, sizeof (rbuf->buffer), -1);
}
/* Currently unused -- see RBUF_READCHAR. */
int res;
rbuf->buffer_pos = rbuf->buffer;
rbuf->buffer_left = 0;
-#ifdef HAVE_SSL
- if (rbuf->ssl != NULL) {
- res = ssl_iread (rbuf->ssl, rbuf->buffer, sizeof (rbuf->buffer));
- } else {
-#endif /* HAVE_SSL */
- res = iread (rbuf->fd, rbuf->buffer, sizeof (rbuf->buffer));
-#ifdef HAVE_SSL
- }
-#endif /* HAVE_SSL */
+ res = xread (rbuf->fd, rbuf->buffer, sizeof (rbuf->buffer), -1);
if (res <= 0)
return res;
rbuf->buffer_left = res;
#ifndef RBUF_H
#define RBUF_H
-#ifdef HAVE_SSL
-# include <openssl/ssl.h>
-#endif
-
/* Retrieval stream */
struct rbuf
{
int fd;
-#ifdef HAVE_SSL
- SSL *ssl; /* the ssl structure -- replaces fd for ssl connections */
-#endif /* HAVE_SSL */
char buffer[4096]; /* the input buffer */
char *buffer_pos; /* current position in the buffer */
size_t buffer_left; /* number of bytes left in the buffer:
/* Return the file descriptor of RBUF. */
#define RBUF_FD(rbuf) ((rbuf)->fd)
-/* Return the file descriptor of RBUF. */
-#define RBUF_SSL(rbuf) ((rbuf)->ssl)
-
/* Function declarations */
void rbuf_initialize PARAMS ((struct rbuf *, int));
int rbuf_initialized_p PARAMS ((struct rbuf *));
{
int amount_to_read = (use_expected
? MIN (expected - *len, dlbufsize) : dlbufsize);
-#ifdef HAVE_SSL
- if (rbuf->ssl!=NULL)
- res = ssl_iread (rbuf->ssl, dlbuf, amount_to_read);
- else
-#endif /* HAVE_SSL */
- res = iread (fd, dlbuf, amount_to_read);
+ res = xread (fd, dlbuf, amount_to_read, -1);
if (res <= 0)
break;
#endif
#endif
-#ifdef __BEOS__
-# undef READ
-# undef WRITE
-# define READ(fd, buf, cnt) recv ((fd), (buf), (cnt), 0)
-# define WRITE(fd, buf, cnt) send ((fd), (buf), (cnt), 0)
-#endif
-
-/* mswindows.h defines these. */
-#ifndef READ
-# define READ(fd, buf, cnt) read ((fd), (buf), (cnt))
-#endif
-#ifndef WRITE
-# define WRITE(fd, buf, cnt) write ((fd), (buf), (cnt))
-#endif
-#ifndef REALCLOSE
-# define REALCLOSE(x) close (x)
-#endif
-
-#define CLOSE(x) do { \
- int C_sock = (x); \
- if (C_sock >= 0) \
- { \
- REALCLOSE (C_sock); \
- DEBUGP (("Closing fd %d\n", C_sock)); \
- } \
-} while (0)
-
/* Define a large integral type useful for storing large sizes that
exceed sizes of one download, such as when printing the sum of all
downloads. Note that this has nothing to do with large file