From ea019e9659fb07d24ec113afdb264c235f1683be Mon Sep 17 00:00:00 2001
From: Puck Meerburg <puck@puckipedia.nl>
Date: Sat, 11 Jan 2014 10:56:27 +0100
Subject: Add Haiku fixes


diff --git a/Makefile b/Makefile
index 99f2795..ce1ebe5 100644
--- a/Makefile
+++ b/Makefile
@@ -69,6 +69,9 @@ aix:
 linux:
 	make -e $(ALL) $(MFLAGS) XFLAGS='-DLINUX' STATIC=-static
 
+haiku:
+	make -e $(ALL) $(MFLAGS) XFLAGS='-DHAIKU -lnetwork' STATIC=-static
+
 # irix 5.2, dunno 'bout earlier versions.  If STATIC='-non_shared' doesn't
 # work for you, null it out and yell at SGI for their STUPID default
 # of apparently not installing /usr/lib/nonshared/*.  Sheesh.
diff --git a/generic.h b/generic.h
index b3dd5f5..568e3b3 100644
--- a/generic.h
+++ b/generic.h
@@ -42,6 +42,9 @@
 /* random() is generally considered better than rand() */
 #define HAVE_RANDOM
 
+/* moved here to be able to turn it off per platform */
+#define HAVE_BIND
+
 /* the srand48/lrand48/etc family is s'posedly even better */
 #define HAVE_RAND48
 /* bmc@telebase and others have suggested these macros if a box *does* have
@@ -360,6 +363,12 @@ There's a BIG swamp lurking where network code of any sort lives.
 #undef HAVE_SELECT_X
 #endif /* NeXTSTEP 3.2 motorola */
 
+/* Haiku contains this version of netcat by default,
+   and doesn't like res_init for some reason */
+#ifdef HAIKU
+#undef HAVE_BIND
+#endif
+
 /* Make some "generic" assumptions if all else fails */
 #ifdef GENERIC
 #undef HAVE_FLOCK
diff --git a/netcat.c b/netcat.c
index 3cab37d..37bc104 100644
--- a/netcat.c
+++ b/netcat.c
@@ -31,7 +31,6 @@
 /* conditional includes -- a very messy section which you may have to dink
    for your own architecture [and please send diffs...]: */
 /* #undef _POSIX_SOURCE		/* might need this for something? */
-#define HAVE_BIND		/* ASSUMPTION -- seems to work everywhere! */
 #define HAVE_HELP		/* undefine if you dont want the help text */
 /* #define ANAL			/* if you want case-sensitive DNS matching */
 
@@ -158,6 +157,7 @@ USHORT o_random = 0;
 USHORT o_udpmode = 0;
 USHORT o_verbose = 0;
 unsigned int o_wait = 0;
+unsigned int o_quittimeout = 0;
 USHORT o_zero = 0;
 /* o_tn in optional section */
 
@@ -170,6 +170,9 @@ USHORT o_zero = 0;
 #define Debug(x)	/* nil... */
 #endif
 
+#ifdef HAVE_HELP
+void helpme();
+#endif
 
 /* support routines -- the bulk of this thing.  Placed in such an order that
    we don't have to forward-declare anything: */
@@ -224,6 +227,14 @@ void catch ()
   bail (" punt!");
 }
 
+/* quitaftertimeout :
+    signal handler which quits after user given seconds after close of stdin */
+void quitaftertimeout ()
+{
+  close(netfd);
+  exit(0);
+}
+
 /* timeout and other signal handling cruft */
 void tmtravel ()
 {
@@ -1171,15 +1182,19 @@ int readwrite (fd)
     } /* select fuckup */
 /* if we have a timeout AND stdin is closed AND we haven't heard anything
    from the net during that time, assume it's dead and close it too. */
-    if (rr == 0) {
-	if (! FD_ISSET (0, ding1))
-	  netretry--;			/* we actually try a coupla times. */
-	if (! netretry) {
-	  if (o_verbose > 1)		/* normally we don't care */
-	    holler ("net timeout");
-	  close (fd);
-	  return (0);			/* not an error! */
+/* we need this section if -q is not given, otherwise we don't quit if we
+   don't receive from net, we quit after timeout given with -q */
+	if (o_quittimeout == 0) {
+      if (rr == 0) {
+	  if (! FD_ISSET (0, ding1))
+	    netretry--;			/* we actually try a coupla times. */
+	  if (! netretry) {
+	    if (o_verbose > 1)		/* normally we don't care */
+	      holler ("net timeout");
+	    close (fd);
+	    return (0);			/* not an error! */
 	}
+      }
     } /* select timeout */
 /* xxx: should we check the exception fds too?  The read fds seem to give
    us the right info, and none of the examples I found bothered. */
@@ -1214,6 +1229,15 @@ Debug (("got %d from the net, errno %d", rr, errno))
 	if (rr <= 0) {			/* at end, or fukt, or ... */
 	  FD_CLR (0, ding1);		/* disable and close stdin */
 	  close (0);
+	  if (o_quittimeout > 0) {
+	    if (o_verbose > 1)
+	      fprintf (stderr, "STDIN closed, quit after %d seconds\n", o_quittimeout);
+	    signal (SIGALRM, quitaftertimeout);
+	    alarm (o_quittimeout);
+	    // if -q argument is < 0 we don't trigger any signal and we also don't
+	    // check for rr == 0 above, hence this is an infinite loop, essentially
+	    // waiting forever on fd or net.
+	  }
 	} else {
 	  rzleft = rr;
 	  zp = bigbuf_in;
@@ -1387,7 +1411,7 @@ main (argc, argv)
 
 /* 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, "ae: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':
@@ -1439,6 +1463,9 @@ main (argc, argv)
 	if (o_lport == 0)
 	  bail ("invalid local port %s", optarg);
 	break;
+      case 'q':				/* set the quit timeout */
+	o_quittimeout = atoi(optarg);
+	break;
       case 'r':				/* randomize various things */
 	o_random++; break;
       case 's':				/* local source address */
@@ -1625,7 +1652,7 @@ Debug (("netfd %d from port %d to port %d", netfd, ourport, curport))
 #ifdef HAVE_HELP		/* unless we wanna be *really* cryptic */
 /* helpme :
    the obvious */
-helpme()
+void helpme()
 {
   o_verbose = 1;
   holler ("[v1.10]\n\
@@ -1648,6 +1675,7 @@ options:");
 	-n			numeric-only IP addresses, no DNS\n\
 	-o file			hex dump of traffic\n\
 	-p port			local port number\n\
+	-q timeout		set timeout for connecting\n\
 	-r			randomize local and remote ports\n\
 	-s addr			local source address");
 #ifdef TELNET
-- 
1.8.3.4

