File quit-timer.patch of Package netcat-openbsd

From: Aron Xu <aron@debian.org>
Date: Mon, 13 Feb 2012 15:16:04 +0800
Subject: quit timer

---
 nc.1     |   10 ++++++++++
 netcat.c |   50 +++++++++++++++++++++++++++++++++++++++++---------
 2 files changed, 51 insertions(+), 9 deletions(-)

--- a/nc.1
+++ b/nc.1
@@ -41,6 +41,7 @@
 .Op Fl O Ar length
 .Op Fl P Ar proxy_username
 .Op Fl p Ar source_port
+.Op Fl q Ar seconds
 .Op Fl s Ar source
 .Op Fl T Ar keyword
 .Op Fl V Ar rtable
@@ -173,6 +174,15 @@ Proxy authentication is only supported f
 Specifies the source port
 .Nm
 should use, subject to privilege restrictions and availability.
+.It Fl q Ar seconds
+after EOF on stdin, wait the specified number of
+.Ar seconds
+and then quit. If
+.Ar seconds
+is negative, wait forever (default).  Specifying a non-negative
+.Ar seconds
+implies
+.Fl N .
 .It Fl r
 Specifies that source and/or destination ports should be chosen randomly
 instead of sequentially within a range or in the order that the system
--- a/netcat.c
+++ b/netcat.c
@@ -139,6 +139,7 @@ int	Nflag;					/* shutdown() network soc
 int	nflag;					/* Don't do name look up */
 char   *Pflag;					/* Proxy username */
 char   *pflag;					/* Localport flag */
+int    qflag = -1;				/* Quit after some secs */
 int	rflag;					/* Random ports flag */
 char   *sflag;					/* Source Address */
 int	tflag;					/* Telnet Emulation */
@@ -218,6 +219,8 @@ ssize_t fillbuf(int, unsigned char *, si
 static int connect_with_timeout(int fd, const struct sockaddr *sa,
         socklen_t salen, int ctimeout);
 
+static void quit();
+
 int
 main(int argc, char *argv[])
 {
@@ -246,9 +249,9 @@ main(int argc, char *argv[])
 
 	while ((ch = getopt(argc, argv,
 # if defined(TLS)
-	    "46C:cDde:FH:hI:i:K:klM:m:NnO:o:P:p:R:rSs:T:tUuV:vw:X:x:z")) != -1) {
+	    "46C:cDde:FH:hI:i:K:klM:m:NnO:o:P:p:q:R:rSs:T:tUuV:vw:X:x:z")) != -1) {
 # else
- 	    "46CDdFhI:i:klM:m:NnO:P:p:rSs:T:tUuV:vw:X:x:z")) != -1) {
+	    "46CDdFhI:i:klM:m:NnO:P:p:q:rSs:T:tUuV:vw:X:x:z")) != -1) {
 # endif
 		switch (ch) {
 		case '4':
@@ -339,6 +342,13 @@ main(int argc, char *argv[])
 		case 'p':
 			pflag = optarg;
 			break;
+ 		case 'q':
+			qflag = strtonum(optarg, INT_MIN, INT_MAX, &errstr);
+			if (errstr)
+				errx(1, "quit timer %s: %s", errstr, optarg);
+			if (qflag >= 0)
+				Nflag = 1;
+			break;
 # if defined(TLS)
 		case 'R':
 			tls_cachanged = 1;
@@ -1253,15 +1263,27 @@ readwrite(int net_fd)
 	while (1) {
 		/* both inputs are gone, buffers are empty, we are done */
 		if (pfd[POLL_STDIN].fd == -1 && pfd[POLL_NETIN].fd == -1 &&
-		    stdinbufpos == 0 && netinbufpos == 0)
-			return;
+ 		    stdinbufpos == 0 && netinbufpos == 0) {
+			if (qflag <= 0)
+				return;
+			goto delay_exit;
+		}
 		/* both outputs are gone, we can't continue */
-		if (pfd[POLL_NETOUT].fd == -1 && pfd[POLL_STDOUT].fd == -1)
-			return;
+		if (pfd[POLL_NETOUT].fd == -1 && pfd[POLL_STDOUT].fd == -1) {
+			if (qflag <= 0)
+				return;
+			goto delay_exit;
+ 		}
 		/* listen and net in gone, queues empty, done */
 		if (lflag && pfd[POLL_NETIN].fd == -1 &&
-		    stdinbufpos == 0 && netinbufpos == 0)
-			return;
+		    stdinbufpos == 0 && netinbufpos == 0) {
+			if (qflag <= 0)
+				return;
+delay_exit:
+			close(net_fd);
+			signal(SIGALRM, quit);
+			alarm(qflag);
+ 		}
 
 		/* poll */
 		num_fds = poll(pfd, 4, timeout);
@@ -1936,6 +1958,7 @@ help(void)
 	\t-O length	TCP send buffer length\n\
 	\t-P proxyuser\tUsername for proxy authentication\n\
 	\t-p port\t	Specify local port for remote connects\n\
+	\t-q secs\t	quit after EOF on stdin and delay of secs\n\
 	\t-r		Randomize remote ports\n\
 	\t-S		Enable the TCP MD5 signature option\n\
 	\t-s source	Local source address\n\
@@ -1959,9 +1982,18 @@ usage(int ret)
 	fprintf(stderr,
 	    "usage: nc [-46CDdFhklNnrStUuvz] [-I length] [-i interval] [-M ttl]\n"
 	    "\t  [-m minttl] [-O length] [-P proxy_username] [-p source_port]\n"
-	    "\t  [-s source] [-T keyword] [-V rtable] [-w timeout] "
+	    "\t  [-q seconds] [-s source] [-T keyword] [-V rtable] [-w timeout] "
 	    "[-X proxy_protocol]\n"
 	    "\t  [-x proxy_address[:port]] [destination] [port]\n");
 	if (ret)
 		exit(1);
 }
+
+/*
+ * quit()
+ * handler for a "-q" timeout (exit 0 instead of 1)
+ */
+static void quit()
+{
+	exit(0);
+}