	$NetBSD: patch-ad,v 1.4 2011/01/13 15:09:58 pooka Exp $

--- netcat.c.orig	1996-03-21 01:38:04.000000000 +0100
+++ netcat.c	2011-01-13 16:06:00.000000000 +0100
@@ -44,12 +44,7 @@
 #include <sys/select.h>
 #endif
 
-/* have to do this *before* including types.h. xxx: Linux still has it wrong */
-#ifdef FD_SETSIZE		/* should be in types.h, butcha never know. */
-#undef FD_SETSIZE		/* if we ever need more than 16 active */
-#endif				/* fd's, something is horribly wrong! */
-#define FD_SETSIZE 16		/* <-- this'll give us a long anyways, wtf */
-#include <sys/types.h>		/* *now* do it.  Sigh, this is broken */
+#include <sys/types.h>
 
 #ifdef HAVE_RANDOM		/* aficionados of ?rand48() should realize */
 #define SRAND srandom		/* that this doesn't need *strong* random */
@@ -151,6 +146,7 @@
 
 /* global cmd flags: */
 USHORT o_alla = 0;
+USHORT o_allowbroad = 0;
 unsigned int o_interval = 0;
 USHORT o_listen = 0;
 USHORT o_nflag = 0;
@@ -160,6 +156,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
@@ -225,6 +222,14 @@
   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 */
 void tmtravel ()
 {
@@ -333,6 +338,7 @@
   struct in_addr iaddr;
   register HINF * poop = NULL;
   register int x;
+  int rc;
 
 /* I really want to strangle the twit who dreamed up all these sockaddr and
    hostent abstractions, and then forced them all to be incompatible with
@@ -361,9 +367,9 @@
     bail ("gethostpoop fuxored");
   strcpy (poop->name, unknown);		/* preload it */
 /* see wzv:workarounds.c for dg/ux return-a-struct inet_addr lossage */
-  iaddr.s_addr = inet_addr (name);
+  rc = inet_aton(name, &iaddr);
 
-  if (iaddr.s_addr == INADDR_NONE) {	/* here's the great split: names... */
+  if (rc == 0) {	/* here's the great split: names... */
     if (numeric)
       bail ("Can't parse %s as an IP address", name);
     hostent = gethostbyname (name);
@@ -620,6 +626,13 @@
   rr = setsockopt (nnetfd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof (x));
   if (rr == -1)
     holler ("nnetfd reuseaddr failed");		/* ??? */
+#ifdef SO_BROADCAST
+  if (o_allowbroad) {
+    rr = setsockopt (nnetfd, SOL_SOCKET, SO_BROADCAST, &x, sizeof (x));
+    if (rr == -1)
+       holler ("nnetfd reuseaddr failed");         /* ??? */
+  }
+#endif
 #ifdef SO_REUSEPORT	/* doesnt exist everywhere... */
   rr = setsockopt (nnetfd, SOL_SOCKET, SO_REUSEPORT, &x, sizeof (x));
   if (rr == -1)
@@ -1216,6 +1229,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;
@@ -1314,10 +1339,6 @@
   USHORT curport = 0;
   char * randports = NULL;
 
-#ifdef HAVE_BIND
-/* can *you* say "cc -yaddayadda netcat.c -lresolv -l44bsd" on SunLOSs? */
-  res_init();
-#endif
 /* I was in this barbershop quartet in Skokie IL ... */
 /* round up the usual suspects, i.e. malloc up all the stuff we need */
   lclend = (SAI *) Hmalloc (sizeof (SA));
@@ -1354,7 +1375,8 @@
     argv[1] = cp;			/* head of new arg block */
     fprintf (stderr, "Cmd line: ");
     fflush (stderr);		/* I dont care if it's unbuffered or not! */
-    insaved = read (0, cp, BIGSIZ);	/* we're gonna fake fgets() here */
+    insaved = read (0, cp, BIGSIZ-1);	/* we're gonna fake fgets() here */
+    cp[BIGSIZ-1] = '\0';
     if (insaved <= 0)
       bail ("wrong");
     x = findline (cp, insaved);
@@ -1389,12 +1411,14 @@
 
 /* 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, "ae: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;
 #ifdef GAPING_SECURITY_HOLE
       case 'e':				/* prog to exec */
 	pr00gie = optarg;
@@ -1443,6 +1467,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
@@ -1642,6 +1668,7 @@
 	-e prog			program to exec after connect [dangerous!!]");
 #endif
   holler ("\
+	-b			allow broadcasts\n\
 	-g gateway		source-routing hop point[s], up to 8\n\
 	-G num			source-routing pointer: 4, 8, 12, ...\n\
 	-h			this cruft\n\
@@ -1651,6 +1678,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 ("\
