$Log$
+ Revision 580.83 2001/12/01 19:23:26 ajc
+ * clientsocket.c: implement socket timeouts for read operations
+
Revision 580.82 2001/12/01 17:00:23 ajc
* serv_smtp.c: when multiple MX's are the same preference, randomize them
Fri Jul 10 1998 Art Cancro <ajc@uncensored.citadel.org>
* Initial CVS import
-
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
+#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "snprintf.h"
#endif
#include "sysdep_decls.h"
+#include <clientsocket.h>
#ifndef INADDR_NONE
#define INADDR_NONE 0xffffffff
return (s);
}
+
+
/*
- * sock_read() - input binary data from socket.
+ * sock_read_to() - input binary data from socket, with a settable timeout.
* Returns the number of bytes read, or -1 for error.
*/
-int sock_read(int sock, char *buf, int bytes)
+int sock_read_to(int sock, char *buf, int bytes, int timeout)
{
- int len, rlen;
+ int len,rlen;
+ fd_set rfds;
+ struct timeval tv;
+ int retval;
len = 0;
- while (len < bytes) {
- rlen = read(sock, &buf[len], bytes - len);
- if (rlen < 1) {
- return (-1);
+ while(len<bytes) {
+ FD_ZERO(&rfds);
+ FD_SET(sock, &rfds);
+ tv.tv_sec = timeout;
+ tv.tv_usec = 0;
+
+ retval = select(sock+1, &rfds, NULL, NULL, &tv);
+
+ if (FD_ISSET(sock, &rfds) == 0) { /* timed out */
+ lprintf(9, "sock_read() timed out.\n");
+ return(-1);
+ }
+
+ rlen = read(sock, &buf[len], bytes-len);
+ if (rlen<1) {
+ lprintf(2, "sock_read() failed: %s\n",
+ strerror(errno));
+ return(-1);
}
len = len + rlen;
}
- return (len);
+ return(bytes);
+}
+
+
+/*
+ * sock_read() - input binary data from socket.
+ * Returns the number of bytes read, or -1 for error.
+ */
+inline int sock_read(int sock, char *buf, int bytes)
+{
+ return sock_read_to(sock, buf, bytes, CLIENT_TIMEOUT);
}
*/
int sock_connect(char *host, char *service, char *protocol);
+int sock_read_to(int sock, char *buf, int bytes, int timeout);
int sock_read(int sock, char *buf, int bytes);
int sock_write(int sock, char *buf, int nbytes);
int ml_sock_gets(int sock, char *buf);
* This looks dumb, but it's being done for future portability
*/
#define sock_close(sock) close(sock)
+
+/*
+ * Default timeout for client sessions
+ */
+#define CLIENT_TIMEOUT 90
* (This is implemented in terms of client_read_to() and could be
* justifiably moved out of sysdep.c)
*/
-int client_read(char *buf, int bytes)
+inline int client_read(char *buf, int bytes)
{
return(client_read_to(buf, bytes, config.c_sleeping));
}