--- src/usr.bin/nc/netcat.c.orig 2005-01-07 08:43:25 +0300 +++ src/usr.bin/nc/netcat.c 2005-01-07 09:21:38 +0300 @@ -303,6 +303,8 @@ main(int argc, char *argv[]) len = sizeof(cliaddr); connfd = accept(s, (struct sockaddr *)&cliaddr, &len); + if (connfd < 0) + err(1, "accept"); } readwrite(connfd); @@ -336,40 +342,48 @@ main(int argc, char *argv[]) if (s) close(s); + /* Don't lookup port if -n */ + if (nflag) + sv = NULL; + else { + sv = getservbyport( + ntohs(atoi(portlist[i])), + uflag ? "udp" : "tcp"); + } + if (xflag) s = socks_connect(host, portlist[i], hints, proxyhost, proxyport, proxyhints, socksv, Pflag); else s = remote_connect(host, portlist[i], hints); - if (s < 0) - continue; - ret = 0; - if (vflag || zflag) { - /* For UDP, make sure we are connected. */ - if (uflag) { - if (udptest(s) == -1) { - ret = 1; - continue; - } - } - /* Don't look up port if -n. */ - if (nflag) - sv = NULL; - else { - sv = getservbyport( - ntohs(atoi(portlist[i])), - uflag ? "udp" : "tcp"); + if (s >= 0) { + if (uflag && zflag) + ret = (udptest(s) == -1) ? 1 : 0; + } else + ret = 1; + + if (vflag) { + if (ret) { + printf("Connection to %s %s port " + "[%s/%s] failed : %s\n", + host, portlist[i], + uflag ? "udp" : "tcp", + sv ? sv->s_name : "*", + strerror(errno)); + } else { + printf("Connection to %s %s port " + "[%s/%s] succeeded!\n", + host, portlist[i], + uflag ? "udp" : "tcp", + sv ? sv->s_name : "*"); } - - printf("Connection to %s %s port [%s/%s] succeeded!\n", - host, portlist[i], uflag ? "udp" : "tcp", - sv ? sv->s_name : "*"); } - if (!zflag) + + if (!zflag && !ret) readwrite(s); } } @@ -390,7 +404,7 @@ unix_connect(char *path) int s; if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) - return (-1); + err(1, "socket"); (void)fcntl(s, F_SETFD, 1); memset(&sun, 0, sizeof(struct sockaddr_un)); @@ -403,8 +417,7 @@ unix_connect(char *path) return (-1); } if (connect(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) { - close(s); - return (-1); + err(1, "connect"); } return (s); @@ -422,7 +435,7 @@ unix_listen(char *path) /* Create unix domain socket. */ if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) - return (-1); + err(1, "socket"); memset(&sun, 0, sizeof(struct sockaddr_un)); sun.sun_family = AF_UNIX; @@ -435,13 +448,11 @@ unix_listen(char *path) } if (bind(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) { - close(s); - return (-1); + err(1, "bind"); } if (listen(s, 5) < 0) { - close(s); - return (-1); + err(1, "listen"); } return (s); } @@ -456,6 +467,7 @@ remote_connect(char *host, char *port, s { struct addrinfo *res, *res0; int s, error; + int saved_errno = 0; if ((error = getaddrinfo(host, port, &hints, &res))) errx(1, "getaddrinfo: %s", gai_strerror(error)); @@ -486,8 +498,13 @@ remote_connect(char *host, char *port, s errx(1, "getaddrinfo: %s", gai_strerror(error)); if (bind(s, (struct sockaddr *)ares->ai_addr, - ares->ai_addrlen) < 0) - errx(1, "bind failed: %s", strerror(errno)); + ares->ai_addrlen) < 0) { + warn("bind"); + freeaddrinfo(ares); + close(s); + s = -1; + continue; + } freeaddrinfo(ares); } if (Sflag) { @@ -503,7 +520,11 @@ remote_connect(char *host, char *port, s if (connect(s, res0->ai_addr, res0->ai_addrlen) == 0) break; - else if (vflag) + + if (!saved_errno) + saved_errno = errno; + + if (vflag) warn("connect to %s port %s (%s) failed", host, port, uflag ? "udp" : "tcp"); @@ -513,6 +534,9 @@ remote_connect(char *host, char *port, s freeaddrinfo(res); + if (!errno && saved_errno) + errno = saved_errno; + return (s); } @@ -549,7 +573,7 @@ local_listen(char *host, char *port, str ret = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x)); if (ret == -1) - err(1, NULL); + err(1, "setsockopt"); set_common_sockopts(s); @@ -565,18 +589,19 @@ local_listen(char *host, char *port, str if (bind(s, (struct sockaddr *)res0->ai_addr, res0->ai_addrlen) == 0) break; + warn("bind"); close(s); s = -1; } while ((res0 = res0->ai_next) != NULL); + freeaddrinfo(res); + if (!uflag && s != -1) { if (listen(s, 1) < 0) err(1, "listen"); } - freeaddrinfo(res); - return (s); } @@ -612,7 +637,7 @@ readwrite(int nfd) if (n == 0) return; - if (pfd[0].revents & POLLIN) { + if (pfd[0].revents & (POLLIN | POLLERR)) { if ((n = read(nfd, buf, plen)) < 0) return; else if (n == 0) { @@ -741,24 +766,14 @@ build_ports(char *p) } } -/* - * udptest() - * Do a few writes to see if the UDP port is there. - * XXX - Better way of doing this? Doesn't work for IPv6. - * Also fails after around 100 ports checked. - */ int udptest(int s) { - int i, ret; + write(s, "X", 1); - for (i = 0; i <= 3; i++) { - if (write(s, "X", 1) == 1) - ret = 1; - else - ret = -1; - } - return (ret); + sleep(3); + + return (write(s, "X", 1) == 1) ? 1 : -1; } void