diff --git a/ncat/ncat_listen.c b/ncat/ncat_listen.c index f05cbfb79..de38ea622 100644 --- a/ncat/ncat_listen.c +++ b/ncat/ncat_listen.c @@ -131,7 +131,7 @@ static int crlf_state = 0; static void handle_connection(int socket_accept, int type, fd_set *listen_fds); static int read_stdin(struct timeval *qtv); -static int read_socket(int recv_fd); +static int read_socket(int recv_fd, ssize_t (*writefunc)(int, const void *, size_t)); static void post_handle_connection(struct fdinfo *sinfo); static void close_fd(struct fdinfo *fdn, int eof); static void read_and_broadcast(int recv_socket); @@ -397,32 +397,26 @@ restart_fd_loop: if (checked_fd_isset(cfd, &listen_fds)) { /* we have a new connection request */ handle_connection(cfd, type, &listen_fds); + } else if (o.broker) { + read_and_broadcast(cfd); } else if (cfd == STDIN_FILENO) { - if (o.broker) { - read_and_broadcast(cfd); - } else { - /* Read from stdin and write to all clients. */ - rc = read_stdin(&qtv); - if (rc == 0 && (type == SOCK_STREAM || o.ssl)) { - if (!o.noshutdown) shutdown_sockets(SHUT_WR); - if (o.quitafter == 0 && (o.proto != IPPROTO_TCP || (o.proto == IPPROTO_TCP && o.sendonly))) { - /* There will be nothing more to send. If we're not - receiving anything, we can quit here. */ - return 0; - } + /* Read from stdin and write to all clients. */ + rc = read_stdin(&qtv); + if (rc == 0 && (type == SOCK_STREAM || o.ssl)) { + if (!o.noshutdown) shutdown_sockets(SHUT_WR); + if (o.quitafter == 0 && (o.proto != IPPROTO_TCP || (o.proto == IPPROTO_TCP && o.sendonly))) { + /* There will be nothing more to send. If we're not + receiving anything, we can quit here. */ + return 0; } - if (rc < 0) - return 1; - } - } else if (!o.sendonly) { - if (o.broker) { - read_and_broadcast(cfd); - } else { - /* Read from a client and write to stdout. */ - rc = read_socket(cfd); - if (rc <= 0 && !o.keepopen) - return rc == 0 ? 0 : 1; } + if (rc < 0) + return 1; + } else { + /* Read from a client and write to stdout. */ + rc = read_socket(cfd, o.sendonly ? Ignore : Write); + if (rc <= 0 && !o.keepopen) + return rc == 0 ? 0 : 1; } fds_ready--; @@ -605,20 +599,18 @@ static void post_handle_connection(struct fdinfo *sinfo) /* Now that a client is connected, pay attention to stdin. */ if (!stdin_eof && !o.recvonly) checked_fd_set(STDIN_FILENO, &master_readfds); - if (!o.sendonly) { - /* add to our lists */ - checked_fd_set(sinfo->fd, &master_readfds); - /* add it to our list of fds for maintaining maxfd */ + /* add to our lists */ + checked_fd_set(sinfo->fd, &master_readfds); + /* add it to our list of fds for maintaining maxfd */ #ifdef HAVE_OPENSSL - /* Don't add it twice (see handle_connection above) */ - if (!o.ssl) { + /* Don't add it twice (see handle_connection above) */ + if (!o.ssl) { #endif - if (add_fdinfo(&client_fdlist, sinfo) < 0) - bye("add_fdinfo() failed."); + if (add_fdinfo(&client_fdlist, sinfo) < 0) + bye("add_fdinfo() failed."); #ifdef HAVE_OPENSSL - } -#endif } +#endif checked_fd_set(sinfo->fd, &master_broadcastfds); if (add_fdinfo(&broadcast_fdlist, sinfo) < 0) bye("add_fdinfo() failed."); @@ -703,7 +695,7 @@ int read_stdin(struct timeval *qtv) /* Read from a client socket and write to stdout. Return the number of bytes read from the socket, or -1 on error. */ -int read_socket(int recv_fd) +int read_socket(int recv_fd, ssize_t (*writefunc)(int, const void *, size_t)) { char buf[DEFAULT_TCP_BUF_LEN]; struct fdinfo *fdn; @@ -728,7 +720,7 @@ int read_socket(int recv_fd) return n; } else { - Write(STDOUT_FILENO, buf, n); + writefunc(STDOUT_FILENO, buf, n); nbytes += n; } } while (pending); @@ -795,6 +787,10 @@ static void read_and_broadcast(int recv_fd) close_fd(fdn, n == 0); return; } + /* Ignore any read data in sendonly mode */ + if (o.sendonly) { + continue; + } } if (o.debug > 1) diff --git a/ncat/sys_wrap.c b/ncat/sys_wrap.c index 20d7a5508..934d7d736 100644 --- a/ncat/sys_wrap.c +++ b/ncat/sys_wrap.c @@ -189,3 +189,15 @@ ssize_t Write(int fd, const void *buf, size_t count) return ret; } + +#ifndef UNUSED +#define UNUSED(x) ((void) x) +#endif +/* Like Write, but does nothing. */ +ssize_t Ignore(int fd, const void *buf, size_t count) +{ + UNUSED(fd); + UNUSED(buf); + UNUSED(count); + return 0; +} diff --git a/ncat/sys_wrap.h b/ncat/sys_wrap.h index 98933b8ba..7ae2f0a11 100644 --- a/ncat/sys_wrap.h +++ b/ncat/sys_wrap.h @@ -108,5 +108,6 @@ sighandler_t Signal(int signum, sighandler_t handler); int Socket(int domain, int type, int protocol); char *Strdup(const char *s); ssize_t Write(int fd, const void *buf, size_t count); +ssize_t Ignore(int fd, const void *buf, size_t count); #endif