Index: ncat/ncat_core.h =================================================================== --- ncat/ncat_core.h (revision 12996) +++ ncat/ncat_core.h (working copy) @@ -21,6 +21,7 @@ int af; int broker; int listen; + int keepopen; int sendonly; int recvonly; int telnet; Index: ncat/ncat_listen.c =================================================================== --- ncat/ncat_listen.c (revision 12996) +++ ncat/ncat_listen.c (working copy) @@ -33,7 +33,7 @@ static void handle_connection(void); static void read_stdin(void); -static void read_socket(int recv_fd); +static int read_socket(int recv_fd); /* reap child processes */ static void sig_chld(int signo) @@ -114,7 +114,8 @@ read_stdin(); } else { /* Read from a client and write to stdout. */ - read_socket(i); + if (!read_socket(i) && !o.keepopen) + return 0; } fds_ready--; @@ -242,8 +243,9 @@ broadcast(&fds, &fdlist, buf, nbytes); } -/* Read from a client socket and write to stdout. */ -void read_socket(int recv_fd) +/* Read from a client socket and write to stdout. + * Returns zero if connection has been closed, non-zero otherwise. */ +int read_socket(int recv_fd) { char buf[DEFAULT_TCP_BUF_LEN]; struct fdinfo *fdn = get_fdinfo(&fdlist, recv_fd); @@ -279,7 +281,7 @@ if (conn_count == 0) FD_CLR(STDIN_FILENO, &master); - return; + return 0; } if(o.linedelay) @@ -301,6 +303,7 @@ if (o.ssl && fdn->ssl && SSL_pending(fdn->ssl)) goto readagain; #endif + return 1; } /* This is sufficiently different from the TCP code (wrt SSL, etc) that it Index: ncat/ncat_main.c =================================================================== --- ncat/ncat_main.c (revision 12996) +++ ncat/ncat_main.c (working copy) @@ -153,6 +153,7 @@ {"help", no_argument, NULL, 'h'}, {"delay", required_argument, NULL, 'd'}, {"listen", no_argument, NULL, 'l'}, + {"keep-open", no_argument, NULL, 'k'}, {"output", required_argument, NULL, 'o'}, {"hex-dump", required_argument, NULL, 'x'}, {"idle-timeout", required_argument, NULL, 'i'}, @@ -191,7 +192,7 @@ while (1) { /* handle command line arguments */ int option_index; - int c = getopt_long(argc, argv, "46Cc:e:g:G:i:m:hp:d:lo:x:ts:uvw:n", + int c = getopt_long(argc, argv, "46Cc:e:g:G:i:m:hp:d:klo:x:ts:uvw:n", long_options, &option_index); /* That's the end of the options. */ @@ -263,6 +264,9 @@ case 's': source = optarg; break; + case 'k': + o.keepopen = 1; + break; case 'l': o.listen = 1; break; @@ -371,6 +375,7 @@ printf(" -p, --source-port port Specify source port to use (doesn't affect -l)\n"); printf(" -s, --source addr Specify source address to use (doesn't affect -l)\n"); printf(" -l, --listen Bind and listen for incoming connections\n"); + printf(" -k, --keep-open Keep listening after first connection is closed\n"); printf(" -n, --nodns Do not resolve hostnames via DNS\n"); printf(" -t, --telnet Answer Telnet negotiations\n"); printf(" -u, --udp Use UDP instead of default TCP\n"); @@ -553,6 +558,10 @@ if (o.cmdexec && o.hexlogfd != -1) bye("Invalid option combination: `-e' and `-x'."); + /* keep-open requires listen mode. */ + if (o.keepopen && !o.listen) + bye("Invalid option combination: `-k' without `-l'."); + if (o.listen) return ncat_listen_mode(); else Index: ncat/ncat_core.c =================================================================== --- ncat/ncat_core.c (revision 12996) +++ ncat/ncat_core.c (working copy) @@ -38,6 +38,7 @@ o.af = AF_INET; o.broker = 0; o.listen = 0; + o.keepopen = 0; o.sendonly = 0; o.recvonly = 0; o.telnet = 0;