Subject: pkg/24680: pkgsrc "netcat" lacks -q option
To: None <gnats-bugs@gnats.NetBSD.org>
From: None <duck@shangtai.net>
List: netbsd-bugs
Date: 03/05/2004 16:57:33
>Number:         24680
>Category:       pkg
>Synopsis:       pkgsrc "netcat" lacks the -q option (quit on EOF)
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    pkg-manager
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Fri Mar 05 14:58:00 UTC 2004
>Closed-Date:
>Last-Modified:
>Originator:     
>Release:        current
>Organization:
>Environment:
System: NetBSD knightrider.shangtai.net 1.6ZK NetBSD 1.6ZK (KITT) #0: Tue Feb 17 01:42:49 EET 2004 root@:/usr/obj/sys/arch/alpha/compile.alpha/KITT alpha
Architecture: alpha
Machine: alpha
>Description:
I needed to send some data from one nc to another for various reasons
as data piped from a shell command. However, nc does not quit on EOF received,
but continues until both network and stdin stream is closed (by default)
>How-To-Repeat:
>Fix:
The patch below fixes this problem, by adding the (GNU licensed) patch extracted
from debian linux' patches to their netcat package.

it will work as a drop-in addition to patches/ in the pkgsrc dir as of march
5:th 2004.

File: patch-ag
--- netcat.c.orig	Fri Mar  5 16:45:46 EET 2004
+++ netcat.c
@@ -161,6 +161,7 @@
 USHORT o_verbose = 0;
 unsigned int o_wait = 0;
 USHORT o_zero = 0;
+int o_quit = -1; /* 0 == quit-now; >0 == quit after o_quit seconds */
 /* o_tn in optional section */
 
 /* Debug macro: squirt whatever message and sleep a bit so we can see it go
@@ -223,7 +224,15 @@
   errno = 0;
   if (o_verbose > 1)		/* normally we don't care */
     bail (wrote_txt, wrote_net, wrote_out);
   bail (" punt!");
+}
+
+/* quit :
+   handler for a "-q" timeout (exit 0 instead of 1) */
+void quit()
+{
+  close(netfd);
+  exit(0);
 }
 
 /* timeout and other signal handling cruft */
@@ -1225,6 +1234,18 @@
 	if (rr <= 0) {			/* at end, or fukt, or ... */
 	  FD_CLR (0, ding1);		/* disable and close stdin */
 	  close (0);
+	  /* if the user asked to exit on EOF, do it */
+	  if (o_quit == 0) {
+	    shutdown(netfd, 1);
+	    close (fd);
+	    exit (0);
+	  }
+	  /* if user asked to die after a while, arrange for it */
+	  if (o_quit > 0) {
+	    shutdown(netfd, 1);
+	    signal (SIGALRM, quit);
+	    alarm(o_quit);
+	  }
 	} else {
 	  rzleft = rr;
 	  zp = bigbuf_in;
@@ -1395,10 +1416,10 @@
 /* If your shitbox doesn't have getopt, step into the nineties already. */
 /* optarg, optind = next-argv-component [i.e. flag arg]; optopt = last-char */
-  while ((x = getopt (argc, argv, "abe:g:G:hi:lno:p:rs:tuvw:z")) != EOF) {
+  while ((x = getopt (argc, argv, "abe:g:G:hi:lno:p:q:rs:tuvw:z")) != EOF) {
 /* Debug (("in go: x now %c, optarg %x optind %d", x, optarg, optind)) */
     switch (x) {
       case 'a':
 	bail ("all-A-records NIY");
 	o_alla++; break;
       case 'b':
 	o_allowbroad++; break;
@@ -1450,6 +1471,8 @@
 	break;
       case 'r':				/* randomize various things */
 	o_random++; break;
+      case 'q':				/* quit after stdin does EOF */
+	o_quit = atoi(optarg); break;
       case 's':				/* local source address */
 /* do a full lookup [since everything else goes through the same mill],
    unless -n was previously specified.  In fact, careful placement of -n can
@@ -1659,6 +1680,7 @@
 	-o file			hex dump of traffic\n\
 	-p port			local port number\n\
 	-r			randomize local and remote ports\n\
+	-q secs			quit after EOF on stdin and delay of secs\n\
 	-s addr			local source address");
 #ifdef TELNET
   holler ("\

>Release-Note:
>Audit-Trail:
>Unformatted: