mirror of
https://github.com/Ponce/slackbuilds
synced 2024-10-21 22:27:10 +02:00
b49d0a636b
Apply the patches locally and added a note about this package being incompatible with nc from Slackware Signed-off-by: Matteo Bernardini <ponce@slackbuilds.org>
121 lines
3.4 KiB
Diff
121 lines
3.4 KiB
Diff
From: Aron Xu <aron@debian.org>
|
|
Date: Mon, 13 Feb 2012 14:43:56 +0800
|
|
Subject: connect timeout
|
|
|
|
---
|
|
netcat.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
|
|
1 file changed, 75 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/netcat.c b/netcat.c
|
|
index 9b2def2..f3cc8c1 100644
|
|
--- a/netcat.c
|
|
+++ b/netcat.c
|
|
@@ -106,6 +106,10 @@
|
|
#define PORT_MAX_LEN 6
|
|
#define UNIX_DG_TMP_SOCKET_SIZE 19
|
|
|
|
+#define CONNECTION_SUCCESS 0
|
|
+#define CONNECTION_FAILED 1
|
|
+#define CONNECTION_TIMEOUT 2
|
|
+
|
|
/* Command Line Options */
|
|
int dflag; /* detached, no stdin */
|
|
unsigned int iflag; /* Interval Flag */
|
|
@@ -151,6 +155,9 @@ void set_common_sockopts(int);
|
|
int map_tos(char *, int *);
|
|
void usage(int);
|
|
|
|
+static int connect_with_timeout(int fd, const struct sockaddr *sa,
|
|
+ socklen_t salen, int ctimeout);
|
|
+
|
|
int
|
|
main(int argc, char *argv[])
|
|
{
|
|
@@ -651,11 +658,14 @@ remote_connect(const char *host, const char *port, struct addrinfo hints)
|
|
|
|
set_common_sockopts(s);
|
|
|
|
- if (timeout_connect(s, res0->ai_addr, res0->ai_addrlen) == 0)
|
|
+ if ((error = connect_with_timeout(s, res0->ai_addr, res0->ai_addrlen, timeout))== CONNECTION_SUCCESS)
|
|
break;
|
|
- else if (vflag)
|
|
+ else if (vflag && error == CONNECTION_FAILED)
|
|
warn("connect to %s port %s (%s) failed", host, port,
|
|
uflag ? "udp" : "tcp");
|
|
+ else if (vflag && error == CONNECTION_TIMEOUT)
|
|
+ warn("connect to %s port %s (%s) timed out", host, port,
|
|
+ uflag ? "udp" : "tcp");
|
|
|
|
close(s);
|
|
s = -1;
|
|
@@ -703,6 +713,69 @@ timeout_connect(int s, const struct sockaddr *name, socklen_t namelen)
|
|
return (ret);
|
|
}
|
|
|
|
+static int connect_with_timeout(int fd, const struct sockaddr *sa,
|
|
+ socklen_t salen, int ctimeout)
|
|
+{
|
|
+ int err;
|
|
+ struct timeval tv, *tvp = NULL;
|
|
+ fd_set connect_fdset;
|
|
+ socklen_t len;
|
|
+ int orig_flags;
|
|
+
|
|
+ orig_flags = fcntl(fd, F_GETFL, 0);
|
|
+ if (fcntl(fd, F_SETFL, orig_flags | O_NONBLOCK) < 0 ) {
|
|
+ warn("can't set O_NONBLOCK - timeout not available");
|
|
+ if (connect(fd, sa, salen) == 0)
|
|
+ return CONNECTION_SUCCESS;
|
|
+ else
|
|
+ return CONNECTION_FAILED;
|
|
+ }
|
|
+
|
|
+ /* set connect timeout */
|
|
+ if (ctimeout > 0) {
|
|
+ tv.tv_sec = (time_t)ctimeout/1000;
|
|
+ tv.tv_usec = 0;
|
|
+ tvp = &tv;
|
|
+ }
|
|
+
|
|
+ /* attempt the connection */
|
|
+ err = connect(fd, sa, salen);
|
|
+ if (err != 0 && errno == EINPROGRESS) {
|
|
+ /* connection is proceeding
|
|
+ * it is complete (or failed) when select returns */
|
|
+
|
|
+ /* initialize connect_fdset */
|
|
+ FD_ZERO(&connect_fdset);
|
|
+ FD_SET(fd, &connect_fdset);
|
|
+
|
|
+ /* call select */
|
|
+ do {
|
|
+ err = select(fd + 1, NULL, &connect_fdset,
|
|
+ NULL, tvp);
|
|
+ } while (err < 0 && errno == EINTR);
|
|
+
|
|
+ /* select error */
|
|
+ if (err < 0)
|
|
+ errx(1,"select error: %s", strerror(errno));
|
|
+ /* we have reached a timeout */
|
|
+ if (err == 0)
|
|
+ return CONNECTION_TIMEOUT;
|
|
+ /* select returned successfully, but we must test socket
|
|
+ * error for result */
|
|
+ len = sizeof(err);
|
|
+ if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &len) < 0)
|
|
+ errx(1, "getsockopt error: %s", strerror(errno));
|
|
+ /* setup errno according to the result returned by
|
|
+ * getsockopt */
|
|
+ if (err != 0)
|
|
+ errno = err;
|
|
+ }
|
|
+
|
|
+ /* return aborted if an error occured, and valid otherwise */
|
|
+ fcntl(fd, F_SETFL, orig_flags);
|
|
+ return (err != 0)? CONNECTION_FAILED : CONNECTION_SUCCESS;
|
|
+}
|
|
+
|
|
/*
|
|
* local_listen()
|
|
* Returns a socket listening on a local port, binds to specified source
|
|
--
|