diff options
author | fgsch <> | 2011-10-04 08:34:34 +0000 |
---|---|---|
committer | fgsch <> | 2011-10-04 08:34:34 +0000 |
commit | d8df5f35946db56b630db60f4869ba5d9cb12a99 (patch) | |
tree | afe30c6696bc88421be1c64cdbdcb5930a293c77 /src/usr.bin/nc/netcat.c | |
parent | d0c429847ac53ca168183bfe6fe005f1cc960182 (diff) | |
download | openbsd-d8df5f35946db56b630db60f4869ba5d9cb12a99.tar.gz openbsd-d8df5f35946db56b630db60f4869ba5d9cb12a99.tar.bz2 openbsd-d8df5f35946db56b630db60f4869ba5d9cb12a99.zip |
change -w to apply to the connection as well. manpage bit from jmc@
nicm@ ok.
Diffstat (limited to 'src/usr.bin/nc/netcat.c')
-rw-r--r-- | src/usr.bin/nc/netcat.c | 42 |
1 files changed, 40 insertions, 2 deletions
diff --git a/src/usr.bin/nc/netcat.c b/src/usr.bin/nc/netcat.c index 952bfb7dda..7880c7f452 100644 --- a/src/usr.bin/nc/netcat.c +++ b/src/usr.bin/nc/netcat.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: netcat.c,v 1.102 2011/09/17 14:10:05 haesbaert Exp $ */ | 1 | /* $OpenBSD: netcat.c,v 1.103 2011/10/04 08:34:34 fgsch Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2001 Eric Jackson <ericj@monkey.org> | 3 | * Copyright (c) 2001 Eric Jackson <ericj@monkey.org> |
4 | * | 4 | * |
@@ -98,6 +98,7 @@ void help(void); | |||
98 | int local_listen(char *, char *, struct addrinfo); | 98 | int local_listen(char *, char *, struct addrinfo); |
99 | void readwrite(int); | 99 | void readwrite(int); |
100 | int remote_connect(const char *, const char *, struct addrinfo); | 100 | int remote_connect(const char *, const char *, struct addrinfo); |
101 | int timeout_connect(int, const struct sockaddr *, socklen_t); | ||
101 | int socks_connect(const char *, const char *, struct addrinfo, | 102 | int socks_connect(const char *, const char *, struct addrinfo, |
102 | const char *, const char *, struct addrinfo, int, const char *); | 103 | const char *, const char *, struct addrinfo, int, const char *); |
103 | int udptest(int); | 104 | int udptest(int); |
@@ -590,7 +591,7 @@ remote_connect(const char *host, const char *port, struct addrinfo hints) | |||
590 | 591 | ||
591 | set_common_sockopts(s); | 592 | set_common_sockopts(s); |
592 | 593 | ||
593 | if (connect(s, res0->ai_addr, res0->ai_addrlen) == 0) | 594 | if (timeout_connect(s, res0->ai_addr, res0->ai_addrlen) == 0) |
594 | break; | 595 | break; |
595 | else if (vflag) | 596 | else if (vflag) |
596 | warn("connect to %s port %s (%s) failed", host, port, | 597 | warn("connect to %s port %s (%s) failed", host, port, |
@@ -605,6 +606,43 @@ remote_connect(const char *host, const char *port, struct addrinfo hints) | |||
605 | return (s); | 606 | return (s); |
606 | } | 607 | } |
607 | 608 | ||
609 | int | ||
610 | timeout_connect(int s, const struct sockaddr *name, socklen_t namelen) | ||
611 | { | ||
612 | struct pollfd pfd; | ||
613 | socklen_t optlen; | ||
614 | int flags, optval; | ||
615 | int ret; | ||
616 | |||
617 | if (timeout != -1) { | ||
618 | flags = fcntl(s, F_GETFL, 0); | ||
619 | if (fcntl(s, F_SETFL, flags | O_NONBLOCK) == -1) | ||
620 | err(1, "set non-blocking mode"); | ||
621 | } | ||
622 | |||
623 | if ((ret = connect(s, name, namelen)) != 0 && errno == EINPROGRESS) { | ||
624 | pfd.fd = s; | ||
625 | pfd.events = POLLOUT; | ||
626 | if ((ret = poll(&pfd, 1, timeout)) == 1) { | ||
627 | optlen = sizeof(optval); | ||
628 | if ((ret = getsockopt(s, SOL_SOCKET, SO_ERROR, | ||
629 | &optval, &optlen)) == 0) { | ||
630 | errno = optval; | ||
631 | ret = optval == 0 ? 0 : -1; | ||
632 | } | ||
633 | } else if (ret == 0) { | ||
634 | errno = ETIMEDOUT; | ||
635 | ret = -1; | ||
636 | } else | ||
637 | err(1, "poll failed"); | ||
638 | } | ||
639 | |||
640 | if (timeout != -1 && fcntl(s, F_SETFL, flags) == -1) | ||
641 | err(1, "restoring flags"); | ||
642 | |||
643 | return (ret); | ||
644 | } | ||
645 | |||
608 | /* | 646 | /* |
609 | * local_listen() | 647 | * local_listen() |
610 | * Returns a socket listening on a local port, binds to specified source | 648 | * Returns a socket listening on a local port, binds to specified source |