/* Based on netcat 1.10 RELEASE 960320 written by hobbit@avian.org.
 * Released into public domain by the author.
 *
 * Copyright (C) 2007 Denys Vlasenko.
 *
 * Licensed under GPLv2, see file LICENSE in this source tree.
 */

/* Author's comments from nc 1.10:
 * =====================
 * Netcat is entirely my own creation, although plenty of other code was used as
 * examples.  It is freely given away to the Internet community in the hope that
 * it will be useful, with no restrictions except giving credit where it is due.
 * No GPLs, Berkeley copyrights or any of that nonsense.  The author assumes NO
 * responsibility for how anyone uses it.  If netcat makes you rich somehow and
 * you're feeling generous, mail me a check.  If you are affiliated in any way
 * with Microsoft Network, get a life.  Always ski in control.  Comments,
 * questions, and patches to hobbit@avian.org.
 * ...
 * Netcat and the associated package is a product of Avian Research, and is freely
 * available in full source form with no restrictions save an obligation to give
 * credit where due.
 * ...
 * A damn useful little "backend" utility begun 950915 or thereabouts,
 * as *Hobbit*'s first real stab at some sockets programming.  Something that
 * should have and indeed may have existed ten years ago, but never became a
 * standard Unix utility.  IMHO, "nc" could take its place right next to cat,
 * cp, rm, mv, dd, ls, and all those other cryptic and Unix-like things.
 * =====================
 *
 * Much of author's comments are still retained in the code.
 *
 * Functionality removed (rationale):
 * - miltiple-port ranges, randomized port scanning (use nmap)
 * - telnet support (use telnet)
 * - source routing
 * - multiple DNS checks
 * Functionalty which is different from nc 1.10:
 * - PROG in '-e PROG' can have ARGS (and options).
 *   Because of this -e option must be last.
//TODO: remove -e incompatibility?
 * - we don't redirect stderr to the network socket for the -e PROG.
 *   (PROG can do it itself if needed, but sometimes it is NOT wanted!)
 * - numeric addresses are printed in (), not [] (IPv6 looks better),
 *   port numbers are inside (): (1.2.3.4:5678)
 * - network read errors are reported on verbose levels > 1
 *   (nc 1.10 treats them as EOF)
 * - TCP connects from wrong ip/ports (if peer ip:port is specified
 *   on the command line, but accept() says that it came from different addr)
 *   are closed, but we don't exit - we continue to listen/accept.
 * Since bbox 1.22:
 * - nc exits when _both_ stdin and network are closed.
 *   This makes these two commands:
 *    echo "Yes" | nc 127.0.0.1 1234
 *    echo "no" | nc -lp 1234
 *   exchange their data _and exit_ instead of being stuck.
 */

/* done in nc.c: #include "libbb.h" */

//usage:#if ENABLE_NC_110_COMPAT
//usage:
//usage:#define nc_trivial_usage
//usage:       "[OPTIONS] HOST PORT  - connect"
//usage:	IF_NC_SERVER("\n"
//usage:       "nc [OPTIONS] -l -p PORT [HOST] [PORT]  - listen"
//usage:	)
//usage:#define nc_full_usage "\n\n"
//usage:       "	-e PROG	Run PROG after connect (must be last)"
//usage:	IF_NC_SERVER(
//usage:     "\n	-l	Listen mode, for inbound connects"
//usage:     "\n	-lk	With -e, provides persistent server"
/* -ll does the same as -lk, but its our extension, while -k is BSD'd,
 * presumably more widely known. Therefore we advertise it, not -ll.
 * I would like to drop -ll support, but our "small" nc supports it,
 * and Rob uses it.
 */
//usage:	)
//usage:     "\n	-p PORT	Local port"
//usage:     "\n	-s ADDR	Local address"
//usage:     "\n	-w SEC	Timeout for connects and final net reads"
//usage:	IF_NC_EXTRA(
//usage:     "\n	-i SEC	Delay interval for lines sent" /* ", ports scanned" */
//usage:	)
//usage:     "\n	-n	Don't do DNS resolution"
//usage:     "\n	-u	UDP mode"
//usage:     "\n	-v	Verbose"
//usage:	IF_NC_EXTRA(
//usage:     "\n	-o FILE	Hex dump traffic"
//usage:     "\n	-z	Zero-I/O mode (scanning)"
//usage:	)
//usage:#endif

/*   "\n	-r		Randomize local and remote ports" */
/*   "\n	-g gateway	Source-routing hop point[s], up to 8" */
/*   "\n	-G num		Source-routing pointer: 4, 8, 12, ..." */
/*   "\nport numbers can be individual or ranges: lo-hi [inclusive]" */

/* -e PROG can take ARGS too: "nc ... -e ls -l", but we don't document it
 * in help text: nc 1.10 does not allow that. We don't want to entice
 * users to use this incompatibility */

enum {
	SLEAZE_PORT = 31337,               /* for UDP-scan RTT trick, change if ya want */
	BIGSIZ = 8192,                     /* big buffers */

	netfd = 3,
	ofd = 4,
};

struct globals {
	/* global cmd flags: */
	unsigned o_verbose;
	unsigned o_wait;
#if ENABLE_NC_EXTRA
	unsigned o_interval;
#endif

	/*int netfd;*/
	/*int ofd;*/                     /* hexdump output fd */
#if ENABLE_LFS
#define SENT_N_RECV_M "sent %llu, rcvd %llu\n"
	unsigned long long wrote_out;          /* total stdout bytes */
	unsigned long long wrote_net;          /* total net bytes */
#else
#define SENT_N_RECV_M "sent %u, rcvd %u\n"
	unsigned wrote_out;          /* total stdout bytes */
	unsigned wrote_net;          /* total net bytes */
#endif
	char *proggie0saved;
	/* ouraddr is never NULL and goes through three states as we progress:
	 1 - local address before bind (IP/port possibly zero)
	 2 - local address after bind (port is nonzero)
	 3 - local address after connect??/recv/accept (IP and port are nonzero) */
	struct len_and_sockaddr *ouraddr;
	/* themaddr is NULL if no peer hostname[:port] specified on command line */
	struct len_and_sockaddr *themaddr;
	/* remend is set after connect/recv/accept to the actual ip:port of peer */
	struct len_and_sockaddr remend;

	jmp_buf jbuf;                /* timer crud */

	char bigbuf_in[BIGSIZ];      /* data buffers */
	char bigbuf_net[BIGSIZ];
};

#define G (*ptr_to_globals)
#define wrote_out  (G.wrote_out )
#define wrote_net  (G.wrote_net )
#define ouraddr    (G.ouraddr   )
#define themaddr   (G.themaddr  )
#define remend     (G.remend    )
#define jbuf       (G.jbuf      )
#define bigbuf_in  (G.bigbuf_in )
#define bigbuf_net (G.bigbuf_net)
#define o_verbose  (G.o_verbose )
#define o_wait     (G.o_wait    )
#if ENABLE_NC_EXTRA
#define o_interval (G.o_interval)
#else
#define o_interval 0
#endif
#define INIT_G() do { \
	SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
} while (0)


/* Must match getopt32 call! */
enum {
	OPT_n = (1 << 0),
	OPT_p = (1 << 1),
	OPT_s = (1 << 2),
	OPT_u = (1 << 3),
	OPT_v = (1 << 4),
	OPT_w = (1 << 5),
	OPT_l = (1 << 6) * ENABLE_NC_SERVER,
	OPT_k = (1 << 7) * ENABLE_NC_SERVER,
	OPT_i = (1 << (6+2*ENABLE_NC_SERVER)) * ENABLE_NC_EXTRA,
	OPT_o = (1 << (7+2*ENABLE_NC_SERVER)) * ENABLE_NC_EXTRA,
	OPT_z = (1 << (8+2*ENABLE_NC_SERVER)) * ENABLE_NC_EXTRA,
};

#define o_nflag   (option_mask32 & OPT_n)
#define o_udpmode (option_mask32 & OPT_u)
#if ENABLE_NC_EXTRA
#define o_ofile   (option_mask32 & OPT_o)
#define o_zero    (option_mask32 & OPT_z)
#else
#define o_ofile   0
#define o_zero    0
#endif

/* Debug: squirt whatever message and sleep a bit so we can see it go by. */
/* Beware: writes to stdOUT... */
#if 0
#define Debug(...) do { printf(__VA_ARGS__); printf("\n"); fflush_all(); sleep(1); } while (0)
#else
#define Debug(...) do { } while (0)
#endif

#define holler_error(...)  do { if (o_verbose) bb_error_msg(__VA_ARGS__); } while (0)
#define holler_perror(...) do { if (o_verbose) bb_perror_msg(__VA_ARGS__); } while (0)

/* catch: no-brainer interrupt handler */
static void catch(int sig)
{
	if (o_verbose > 1)                /* normally we don't care */
		fprintf(stderr, SENT_N_RECV_M, wrote_net, wrote_out);
	fprintf(stderr, "punt!\n");
	kill_myself_with_sig(sig);
}

/* unarm  */
static void unarm(void)
{
	signal(SIGALRM, SIG_IGN);
	alarm(0);
}

/* timeout and other signal handling cruft */
static void tmtravel(int sig UNUSED_PARAM)
{
	unarm();
	longjmp(jbuf, 1);
}

/* arm: set the timer.  */
static void arm(unsigned secs)
{
	signal(SIGALRM, tmtravel);
	alarm(secs);
}

/* findline:
 find the next newline in a buffer; return inclusive size of that "line",
 or the entire buffer size, so the caller knows how much to then write().
 Not distinguishing \n vs \r\n for the nonce; it just works as is... */
static unsigned findline(char *buf, unsigned siz)
{
	char * p;
	int x;
	if (!buf)                        /* various sanity checks... */
		return 0;
	if (siz > BIGSIZ)
		return 0;
	x = siz;
	for (p = buf; x > 0; x--) {
		if (*p == '\n') {
			x = (int) (p - buf);
			x++;                        /* 'sokay if it points just past the end! */
Debug("findline returning %d", x);
			return x;
		}
		p++;
	} /* for */
Debug("findline returning whole thing: %d", siz);
	return siz;
} /* findline */

/* doexec:
 fiddle all the file descriptors around, and hand off to another prog.  Sort
 of like a one-off "poor man's inetd".  This is the only section of code
 that would be security-critical, which is why it's ifdefed out by default.
 Use at your own hairy risk; if you leave shells lying around behind open
 listening ports you deserve to lose!! */
static int doexec(char **proggie) NORETURN;
static int doexec(char **proggie)
{
	if (G.proggie0saved)
		proggie[0] = G.proggie0saved;
	xmove_fd(netfd, 0);
	dup2(0, 1);
	/* dup2(0, 2); - do we *really* want this? NO!
	 * exec'ed prog can do it yourself, if needed */
	BB_EXECVP_or_die(proggie);
}

/* connect_w_timeout:
 return an fd for one of
 an open outbound TCP connection, a UDP stub-socket thingie, or
 an unconnected TCP or UDP socket to listen on.
 Examines various global o_blah flags to figure out what to do.
 lad can be NULL, then socket is not bound to any local ip[:port] */
static int connect_w_timeout(int fd)
{
	int rr;

	/* wrap connect inside a timer, and hit it */
	arm(o_wait);
	if (setjmp(jbuf) == 0) {
		rr = connect(fd, &themaddr->u.sa, themaddr->len);
		unarm();
	} else { /* setjmp: connect failed... */
		rr = -1;
		errno = ETIMEDOUT; /* fake it */
	}
	return rr;
}

/* dolisten:
 listens for
 incoming and returns an open connection *from* someplace.  If we were
 given host/port args, any connections from elsewhere are rejected.  This
 in conjunction with local-address binding should limit things nicely... */
static void dolisten(int is_persistent, char **proggie)
{
	int rr;

	if (!o_udpmode)
		xlisten(netfd, 1); /* TCP: gotta listen() before we can get */

	/* Various things that follow temporarily trash bigbuf_net, which might contain
	 a copy of any recvfrom()ed packet, but we'll read() another copy later. */

	/* I can't believe I have to do all this to get my own goddamn bound address
	 and port number.  It should just get filled in during bind() or something.
	 All this is only useful if we didn't say -p for listening, since if we
	 said -p we *know* what port we're listening on.  At any rate we won't bother
	 with it all unless we wanted to see it, although listening quietly on a
	 random unknown port is probably not very useful without "netstat". */
	if (o_verbose) {
		char *addr;
		getsockname(netfd, &ouraddr->u.sa, &ouraddr->len);
		//if (rr < 0)
		//	bb_perror_msg_and_die("getsockname after bind");
		addr = xmalloc_sockaddr2dotted(&ouraddr->u.sa);
		fprintf(stderr, "listening on %s ...\n", addr);
		free(addr);
	}

	if (o_udpmode) {
		/* UDP is a speeeeecial case -- we have to do I/O *and* get the calling
		 party's particulars all at once, listen() and accept() don't apply.
		 At least in the BSD universe, however, recvfrom/PEEK is enough to tell
		 us something came in, and we can set things up so straight read/write
		 actually does work after all.  Yow.  YMMV on strange platforms!  */

		/* I'm not completely clear on how this works -- BSD seems to make UDP
		 just magically work in a connect()ed context, but we'll undoubtedly run
		 into systems this deal doesn't work on.  For now, we apparently have to
		 issue a connect() on our just-tickled socket so we can write() back.
		 Again, why the fuck doesn't it just get filled in and taken care of?!
		 This hack is anything but optimal.  Basically, if you want your listener
		 to also be able to send data back, you need this connect() line, which
		 also has the side effect that now anything from a different source or even a
		 different port on the other end won't show up and will cause ICMP errors.
		 I guess that's what they meant by "connect".
		 Let's try to remember what the "U" is *really* for, eh? */

		/* If peer address is specified, connect to it */
		remend.len = LSA_SIZEOF_SA;
		if (themaddr) {
			remend = *themaddr;
			xconnect(netfd, &themaddr->u.sa, themaddr->len);
		}
		/* peek first packet and remember peer addr */
		arm(o_wait);                /* might as well timeout this, too */
		if (setjmp(jbuf) == 0) {       /* do timeout for initial connect */
			/* (*ouraddr) is prefilled with "default" address */
			/* and here we block... */
			rr = recv_from_to(netfd, NULL, 0, MSG_PEEK, /*was bigbuf_net, BIGSIZ*/
				&remend.u.sa, &ouraddr->u.sa, ouraddr->len);
			if (rr < 0)
				bb_perror_msg_and_die("recvfrom");
			unarm();
		} else
			bb_error_msg_and_die("timeout");
/* Now we learned *to which IP* peer has connected, and we want to anchor
our socket on it, so that our outbound packets will have correct local IP.
Unfortunately, bind() on already bound socket will fail now (EINVAL):
	xbind(netfd, &ouraddr->u.sa, ouraddr->len);
Need to read the packet, save data, close this socket and
create new one, and bind() it. TODO */
		if (!themaddr)
			xconnect(netfd, &remend.u.sa, ouraddr->len);
	} else {
		/* TCP */
 another:
		arm(o_wait); /* wrap this in a timer, too; 0 = forever */
		if (setjmp(jbuf) == 0) {
 again:
			remend.len = LSA_SIZEOF_SA;
			rr = accept(netfd, &remend.u.sa, &remend.len);
			if (rr < 0)
				bb_perror_msg_and_die("accept");
			if (themaddr) {
				int sv_port, port, r;

				sv_port = get_nport(&remend.u.sa); /* save */
				port = get_nport(&themaddr->u.sa);
				if (port == 0) {
					/* "nc -nl -p LPORT RHOST" (w/o RPORT!):
					 * we should accept any remote port */
					set_nport(&remend.u.sa, 0); /* blot out remote port# */
				}
				r = memcmp(&remend.u.sa, &themaddr->u.sa, remend.len);
				set_nport(&remend.u.sa, sv_port); /* restore */
				if (r != 0) {
					/* nc 1.10 bails out instead, and its error message
					 * is not suppressed by o_verbose */
					if (o_verbose) {
						char *remaddr = xmalloc_sockaddr2dotted(&remend.u.sa);
						bb_error_msg("connect from wrong ip/port %s ignored", remaddr);
						free(remaddr);
					}
					close(rr);
					goto again;
				}
			}
			unarm();
		} else
			bb_error_msg_and_die("timeout");

		if (is_persistent && proggie) {
			/* -l -k -e PROG */
			signal(SIGCHLD, SIG_IGN); /* no zombies please */
			if (xvfork() != 0) {
				/* parent: go back and accept more connections */
				close(rr);
				goto another;
			}
			/* child */
			signal(SIGCHLD, SIG_DFL);
		}

		xmove_fd(rr, netfd); /* dump the old socket, here's our new one */
		/* find out what address the connection was *to* on our end, in case we're
		 doing a listen-on-any on a multihomed machine.  This allows one to
		 offer different services via different alias addresses, such as the
		 "virtual web site" hack. */
		getsockname(netfd, &ouraddr->u.sa, &ouraddr->len);
		//if (rr < 0)
		//	bb_perror_msg_and_die("getsockname after accept");
	}

	if (o_verbose) {
		char *lcladdr, *remaddr, *remhostname;

#if ENABLE_NC_EXTRA && defined(IP_OPTIONS)
	/* If we can, look for any IP options.  Useful for testing the receiving end of
	 such things, and is a good exercise in dealing with it.  We do this before
	 the connect message, to ensure that the connect msg is uniformly the LAST
	 thing to emerge after all the intervening crud.  Doesn't work for UDP on
	 any machines I've tested, but feel free to surprise me. */
		char optbuf[40];
		socklen_t x = sizeof(optbuf);

		rr = getsockopt(netfd, IPPROTO_IP, IP_OPTIONS, optbuf, &x);
		if (rr >= 0 && x) {    /* we've got options, lessee em... */
			*bin2hex(bigbuf_net, optbuf, x) = '\0';
			fprintf(stderr, "IP options: %s\n", bigbuf_net);
		}
#endif

	/* now check out who it is.  We don't care about mismatched DNS names here,
	 but any ADDR and PORT we specified had better fucking well match the caller.
	 Converting from addr to inet_ntoa and back again is a bit of a kludge, but
	 gethostpoop wants a string and there's much gnarlier code out there already,
	 so I don't feel bad.
	 The *real* question is why BFD sockets wasn't designed to allow listens for
	 connections *from* specific hosts/ports, instead of requiring the caller to
	 accept the connection and then reject undesireable ones by closing.
	 In other words, we need a TCP MSG_PEEK. */
	/* bbox: removed most of it */
		lcladdr = xmalloc_sockaddr2dotted(&ouraddr->u.sa);
		remaddr = xmalloc_sockaddr2dotted(&remend.u.sa);
		remhostname = o_nflag ? remaddr : xmalloc_sockaddr2host(&remend.u.sa);
		fprintf(stderr, "connect to %s from %s (%s)\n",
				lcladdr, remhostname, remaddr);
		free(lcladdr);
		free(remaddr);
		if (!o_nflag)
			free(remhostname);
	}

	if (proggie)
		doexec(proggie);
}

/* udptest:
 fire a couple of packets at a UDP target port, just to see if it's really
 there.  On BSD kernels, ICMP host/port-unreachable errors get delivered to
 our socket as ECONNREFUSED write errors.  On SV kernels, we lose; we'll have
 to collect and analyze raw ICMP ourselves a la satan's probe_udp_ports
 backend.  Guess where one could swipe the appropriate code from...

 Use the time delay between writes if given, otherwise use the "tcp ping"
 trick for getting the RTT.  [I got that idea from pluvius, and warped it.]
 Return either the original fd, or clean up and return -1. */
#if ENABLE_NC_EXTRA
static int udptest(void)
{
	int rr;

	rr = write(netfd, bigbuf_in, 1);
	if (rr != 1)
		bb_perror_msg("udptest first write");

	if (o_wait)
		sleep(o_wait); // can be interrupted! while (t) nanosleep(&t)?
	else {
	/* use the tcp-ping trick: try connecting to a normally refused port, which
	 causes us to block for the time that SYN gets there and RST gets back.
	 Not completely reliable, but it *does* mostly work. */
	/* Set a temporary connect timeout, so packet filtration doesnt cause
	 us to hang forever, and hit it */
		o_wait = 5;                     /* enough that we'll notice?? */
		rr = xsocket(ouraddr->u.sa.sa_family, SOCK_STREAM, 0);
		set_nport(&themaddr->u.sa, htons(SLEAZE_PORT));
		connect_w_timeout(rr);
		/* don't need to restore themaddr's port, it's not used anymore */
		close(rr);
		o_wait = 0; /* restore */
	}

	rr = write(netfd, bigbuf_in, 1);
	return (rr != 1); /* if rr == 1, return 0 (success) */
}
#else
int udptest(void);
#endif

/* oprint:
 Hexdump bytes shoveled either way to a running logfile, in the format:
 D offset       -  - - - --- 16 bytes --- - - -  -     # .... ascii .....
 where "which" sets the direction indicator, D:
 0 -- sent to network, or ">"
 1 -- rcvd and printed to stdout, or "<"
 and "buf" and "n" are data-block and length.  If the current block generates
 a partial line, so be it; we *want* that lockstep indication of who sent
 what when.  Adapted from dgaudet's original example -- but must be ripping
 *fast*, since we don't want to be too disk-bound... */
#if ENABLE_NC_EXTRA
static void oprint(int direction, unsigned char *p, unsigned bc)
{
	unsigned obc;           /* current "global" offset */
	unsigned x;
	unsigned char *op;      /* out hexdump ptr */
	unsigned char *ap;      /* out asc-dump ptr */
	unsigned char stage[100];

	if (bc == 0)
		return;

	obc = wrote_net; /* use the globals! */
	if (direction == '<')
		obc = wrote_out;
	stage[0] = direction;
	stage[59] = '#'; /* preload separator */
	stage[60] = ' ';

	do {    /* for chunk-o-data ... */
		x = 16;
		if (bc < 16) {
			/* memset(&stage[bc*3 + 11], ' ', 16*3 - bc*3); */
			memset(&stage[11], ' ', 16*3);
			x = bc;
		}
		sprintf((char *)&stage[1], " %8.8x ", obc);  /* xxx: still slow? */
		bc -= x;          /* fix current count */
		obc += x;         /* fix current offset */
		op = &stage[11];  /* where hex starts */
		ap = &stage[61];  /* where ascii starts */

		do {  /* for line of dump, however long ... */
			*op++ = 0x20 | bb_hexdigits_upcase[*p >> 4];
			*op++ = 0x20 | bb_hexdigits_upcase[*p & 0x0f];
			*op++ = ' ';
			if ((*p > 31) && (*p < 127))
				*ap = *p;   /* printing */
			else
				*ap = '.';  /* nonprinting, loose def */
			ap++;
			p++;
		} while (--x);
		*ap++ = '\n';  /* finish the line */
		xwrite(ofd, stage, ap - stage);
	} while (bc);
}
#else
void oprint(int direction, unsigned char *p, unsigned bc);
#endif

/* readwrite:
 handle stdin/stdout/network I/O.  Bwahaha!! -- the select loop from hell.
 In this instance, return what might become our exit status. */
static int readwrite(void)
{
	int rr;
	char *zp = zp; /* gcc */  /* stdin buf ptr */
	char *np = np;            /* net-in buf ptr */
	unsigned rzleft;
	unsigned rnleft;
	unsigned netretry;              /* net-read retry counter */
	unsigned fds_open;

	/* if you don't have all this FD_* macro hair in sys/types.h, you'll have to
	 either find it or do your own bit-bashing: *ding1 |= (1 << fd), etc... */
	fd_set ding1;                   /* for select loop */
	fd_set ding2;
	FD_ZERO(&ding1);
	FD_SET(netfd, &ding1);
	FD_SET(STDIN_FILENO, &ding1);
	fds_open = 2;

	netretry = 2;
	rzleft = rnleft = 0;
	if (o_interval)
		sleep(o_interval);                /* pause *before* sending stuff, too */

	/* and now the big ol' select shoveling loop ... */
	/* nc 1.10 has "while (FD_ISSET(netfd)" here */
	while (fds_open) {
		unsigned wretry = 8200;               /* net-write sanity counter */

		ding2 = ding1;                        /* FD_COPY ain't portable... */
	/* some systems, notably linux, crap into their select timers on return, so
	 we create a expendable copy and give *that* to select.  */
		if (o_wait) {
			struct timeval tmp_timer;
			tmp_timer.tv_sec = o_wait;
			tmp_timer.tv_usec = 0;
		/* highest possible fd is netfd (3) */
			rr = select(netfd+1, &ding2, NULL, NULL, &tmp_timer);
		} else
			rr = select(netfd+1, &ding2, NULL, NULL, NULL);
		if (rr < 0 && errno != EINTR) {                /* might have gotten ^Zed, etc */
			holler_perror("select");
			close(netfd);
			return 1;
		}
	/* 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(STDIN_FILENO, &ding1)) {
				netretry--;                        /* we actually try a coupla times. */
				if (!netretry) {
					if (o_verbose > 1)         /* normally we don't care */
						fprintf(stderr, "net timeout\n");
					/*close(netfd); - redundant, exit will do it */
					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. */

	/* Ding!!  Something arrived, go check all the incoming hoppers, net first */
		if (FD_ISSET(netfd, &ding2)) {                /* net: ding! */
			rr = read(netfd, bigbuf_net, BIGSIZ);
			if (rr <= 0) {
				if (rr < 0 && o_verbose > 1) {
					/* nc 1.10 doesn't do this */
					bb_perror_msg("net read");
				}
				FD_CLR(netfd, &ding1);                /* net closed */
				fds_open--;
				rzleft = 0;                        /* can't write anymore: broken pipe */
			} else {
				rnleft = rr;
				np = bigbuf_net;
			}
Debug("got %d from the net, errno %d", rr, errno);
		} /* net:ding */

	/* if we're in "slowly" mode there's probably still stuff in the stdin
	 buffer, so don't read unless we really need MORE INPUT!  MORE INPUT! */
		if (rzleft)
			goto shovel;

	/* okay, suck more stdin */
		if (FD_ISSET(STDIN_FILENO, &ding2)) {                /* stdin: ding! */
			rr = read(STDIN_FILENO, bigbuf_in, BIGSIZ);
	/* Considered making reads here smaller for UDP mode, but 8192-byte
	 mobygrams are kinda fun and exercise the reassembler. */
			if (rr <= 0) {                        /* at end, or fukt, or ... */
				FD_CLR(STDIN_FILENO, &ding1); /* disable stdin */
				/*close(STDIN_FILENO); - not really necessary */
				/* Let peer know we have no more data */
				/* nc 1.10 doesn't do this: */
				shutdown(netfd, SHUT_WR);
				fds_open--;
			} else {
				rzleft = rr;
				zp = bigbuf_in;
			}
		} /* stdin:ding */
 shovel:
	/* now that we've dingdonged all our thingdings, send off the results.
	 Geez, why does this look an awful lot like the big loop in "rsh"? ...
	 not sure if the order of this matters, but write net -> stdout first. */

		if (rnleft) {
			rr = write(STDOUT_FILENO, np, rnleft);
			if (rr > 0) {
				if (o_ofile) /* log the stdout */
					oprint('<', (unsigned char *)np, rr);
				np += rr;
				rnleft -= rr;
				wrote_out += rr; /* global count */
			}
Debug("wrote %d to stdout, errno %d", rr, errno);
		} /* rnleft */
		if (rzleft) {
			if (o_interval)                        /* in "slowly" mode ?? */
				rr = findline(zp, rzleft);
			else
				rr = rzleft;
			rr = write(netfd, zp, rr);        /* one line, or the whole buffer */
			if (rr > 0) {
				if (o_ofile) /* log what got sent */
					oprint('>', (unsigned char *)zp, rr);
				zp += rr;
				rzleft -= rr;
				wrote_net += rr; /* global count */
			}
Debug("wrote %d to net, errno %d", rr, errno);
		} /* rzleft */
		if (o_interval) {                        /* cycle between slow lines, or ... */
			sleep(o_interval);
			continue;                        /* ...with hairy select loop... */
		}
		if (rzleft || rnleft) {                  /* shovel that shit till they ain't */
			wretry--;                        /* none left, and get another load */
	/* net write retries sometimes happen on UDP connections */
			if (!wretry) {                   /* is something hung? */
				holler_error("too many output retries");
				return 1;
			}
			goto shovel;
		}
	} /* while (fds_open) */

	/* XXX: maybe want a more graceful shutdown() here, or screw around with
	 linger times??  I suspect that I don't need to since I'm always doing
	 blocking reads and writes and my own manual "last ditch" efforts to read
	 the net again after a timeout.  I haven't seen any screwups yet, but it's
	 not like my test network is particularly busy... */
	close(netfd);
	return 0;
} /* readwrite */

/* main: now we pull it all together... */
int nc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int nc_main(int argc UNUSED_PARAM, char **argv)
{
	char *str_p, *str_s;
	IF_NC_EXTRA(char *str_i, *str_o;)
	char *themdotted = themdotted; /* for compiler */
	char **proggie;
	int x;
	unsigned cnt_l = 0;
	unsigned o_lport = 0;

	INIT_G();

	/* catch a signal or two for cleanup */
	bb_signals(0
		+ (1 << SIGINT)
		+ (1 << SIGQUIT)
		+ (1 << SIGTERM)
		, catch);
	/* and suppress others... */
	bb_signals(0
#ifdef SIGURG
		+ (1 << SIGURG)
#endif
		+ (1 << SIGPIPE) /* important! */
		, SIG_IGN);

	proggie = argv;
	while (*++proggie) {
		if (strcmp(*proggie, "-e") == 0) {
			*proggie = NULL;
			proggie++;
			goto e_found;
		}
		/* -<other_opts>e PROG [ARGS] ? */
		/* (aboriginal linux uses this form) */
		if (proggie[0][0] == '-') {
			char *optpos = *proggie + 1;
			/* Skip all valid opts w/o params */
			optpos = optpos + strspn(optpos, "nuv"IF_NC_SERVER("lk")IF_NC_EXTRA("z"));
			if (*optpos == 'e' && !optpos[1]) {
				*optpos = '\0';
				proggie++;
				G.proggie0saved = *proggie;
				*proggie = NULL; /* terminate argv for getopt32 */
				goto e_found;
			}
		}
	}
	proggie = NULL;
 e_found:

	// -g -G -t -r deleted, unimplemented -a deleted too
	opt_complementary = "?2:vv:ll:w+"; /* max 2 params; -v and -l are counters; -w N */
	getopt32(argv, "np:s:uvw:" IF_NC_SERVER("lk")
			IF_NC_EXTRA("i:o:z"),
			&str_p, &str_s, &o_wait
			IF_NC_EXTRA(, &str_i, &str_o), &o_verbose IF_NC_SERVER(, &cnt_l));
	argv += optind;
#if ENABLE_NC_EXTRA
	if (option_mask32 & OPT_i) /* line-interval time */
		o_interval = xatou_range(str_i, 1, 0xffff);
#endif
#if ENABLE_NC_SERVER
	//if (option_mask32 & OPT_l) /* listen mode */
	if (option_mask32 & OPT_k) /* persistent server mode */
		cnt_l = 2;
#endif
	//if (option_mask32 & OPT_n) /* numeric-only, no DNS lookups */
	//if (option_mask32 & OPT_o) /* hexdump log */
	if (option_mask32 & OPT_p) { /* local source port */
		o_lport = bb_lookup_port(str_p, o_udpmode ? "udp" : "tcp", 0);
		if (!o_lport)
			bb_error_msg_and_die("bad local port '%s'", str_p);
	}
	//if (option_mask32 & OPT_r) /* randomize various things */
	//if (option_mask32 & OPT_u) /* use UDP */
	//if (option_mask32 & OPT_v) /* verbose */
	//if (option_mask32 & OPT_w) /* wait time */
	//if (option_mask32 & OPT_z) /* little or no data xfer */

	/* We manage our fd's so that they are never 0,1,2 */
	/*bb_sanitize_stdio(); - not needed */

	if (argv[0]) {
		themaddr = xhost2sockaddr(argv[0],
			argv[1]
			? bb_lookup_port(argv[1], o_udpmode ? "udp" : "tcp", 0)
			: 0);
	}

	/* create & bind network socket */
	x = (o_udpmode ? SOCK_DGRAM : SOCK_STREAM);
	if (option_mask32 & OPT_s) { /* local address */
		/* if o_lport is still 0, then we will use random port */
		ouraddr = xhost2sockaddr(str_s, o_lport);
#ifdef BLOAT
		/* prevent spurious "UDP listen needs !0 port" */
		o_lport = get_nport(ouraddr);
		o_lport = ntohs(o_lport);
#endif
		x = xsocket(ouraddr->u.sa.sa_family, x, 0);
	} else {
		/* We try IPv6, then IPv4, unless addr family is
		 * implicitly set by way of remote addr/port spec */
		x = xsocket_type(&ouraddr,
				(themaddr ? themaddr->u.sa.sa_family : AF_UNSPEC),
				x);
		if (o_lport)
			set_nport(&ouraddr->u.sa, htons(o_lport));
	}
	xmove_fd(x, netfd);
	setsockopt_reuseaddr(netfd);
	if (o_udpmode)
		socket_want_pktinfo(netfd);
	if (!ENABLE_FEATURE_UNIX_LOCAL
	 || cnt_l != 0 /* listen */
	 || ouraddr->u.sa.sa_family != AF_UNIX
	) {
		xbind(netfd, &ouraddr->u.sa, ouraddr->len);
	}
#if 0
	setsockopt_SOL_SOCKET_int(netfd, SO_RCVBUF, o_rcvbuf);
	setsockopt_SOL_SOCKET_int(netfd, SO_SNDBUF, o_sndbuf);
#endif

#ifdef BLOAT
	if (OPT_l && (option_mask32 & (OPT_u|OPT_l)) == (OPT_u|OPT_l)) {
		/* apparently UDP can listen ON "port 0",
		 but that's not useful */
		if (!o_lport)
			bb_error_msg_and_die("UDP listen needs nonzero -p port");
	}
#endif

	if (proggie) {
		close(STDIN_FILENO); /* won't need stdin */
		option_mask32 &= ~OPT_o; /* -o with -e is meaningless! */
	}
#if ENABLE_NC_EXTRA
	if (o_ofile)
		xmove_fd(xopen(str_o, O_WRONLY|O_CREAT|O_TRUNC), ofd);
#endif

	if (cnt_l != 0) {
		dolisten((cnt_l - 1), proggie);
		/* dolisten does its own connect reporting */
		x = readwrite(); /* it even works with UDP! */
	} else {
		/* Outbound connects.  Now we're more picky about args... */
		if (!themaddr)
			bb_show_usage();

		remend = *themaddr;
		if (o_verbose)
			themdotted = xmalloc_sockaddr2dotted(&themaddr->u.sa);

		x = connect_w_timeout(netfd);
		if (o_zero && x == 0 && o_udpmode)        /* if UDP scanning... */
			x = udptest();
		if (x == 0) {                        /* Yow, are we OPEN YET?! */
			if (o_verbose)
				fprintf(stderr, "%s (%s) open\n", argv[0], themdotted);
			if (proggie)                        /* exec is valid for outbound, too */
				doexec(proggie);
			if (!o_zero)
				x = readwrite();
		} else { /* connect or udptest wasn't successful */
			x = 1;                                /* exit status */
			/* if we're scanning at a "one -v" verbosity level, don't print refusals.
			 Give it another -v if you want to see everything. */
			if (o_verbose > 1 || (o_verbose && errno != ECONNREFUSED))
				bb_perror_msg("%s (%s)", argv[0], themdotted);
		}
	}
	if (o_verbose > 1)                /* normally we don't care */
		fprintf(stderr, SENT_N_RECV_M, wrote_net, wrote_out);
	return x;
}
