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

/* 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 prog's parameters and options.
 *   Because of this -e option must be last.
 * - nc doesn't redirect stderr to the network socket for the -e prog.
 * - 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 nc doesn't exit - continues to listen/accept.
 */

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

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
	/* ouraddr is never NULL and goes thru 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 */

	/* will malloc up the following globals: */
	fd_set ding1;                /* for select loop */
	fd_set ding2;
	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 ding1      (G.ding1     )
#define ding2      (G.ding2     )
#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

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

#define o_nflag   (option_mask32 & OPT_n)
#define o_udpmode (option_mask32 & OPT_u)
#if ENABLE_NC_SERVER
#define o_listen  (option_mask32 & OPT_l)
#else
#define o_listen  0
#endif
#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(stdout); 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");
	exit(1);
}

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

/* timeout and other signal handling cruft */
static void tmtravel(int sig)
{
	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) ATTRIBUTE_NORETURN;
static int doexec(char **proggie)
{
	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 */
	execvp(proggie[0], proggie);
	bb_perror_msg_and_die("exec");
}

/* 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->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(void)
{
	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;
		rr = getsockname(netfd, &ouraddr->sa, &ouraddr->len);
		if (rr < 0)
			bb_perror_msg_and_die("getsockname after bind");
		addr = xmalloc_sockaddr2dotted(&ouraddr->sa, ouraddr->len);
		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->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.sa, &ouraddr->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->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.sa, ouraddr->len);
	} else {
		/* TCP */
		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.sa, &remend.len);
			if (rr < 0)
				bb_perror_msg_and_die("accept");
			if (themaddr && memcmp(&remend.sa, &themaddr->sa, remend.len) != 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.sa, remend.len);
					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");
		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. */
		rr = getsockname(netfd, &ouraddr->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];
		int x = sizeof(optbuf);

		rr = getsockopt(netfd, IPPROTO_IP, IP_OPTIONS, optbuf, &x);
		if (rr < 0)
			bb_perror_msg("getsockopt failed");
		else if (x) {    /* we've got options, lessee em... */
			bin2hex(bigbuf_net, optbuf, x);
			bigbuf_net[2*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->sa, ouraddr->len);
		remaddr = xmalloc_sockaddr2dotted(&remend.sa, remend.len);
		remhostname = o_nflag ? remaddr : xmalloc_sockaddr2host(&remend.sa, remend.len);
		fprintf(stderr, "connect to %s from %s (%s)\n",
				lcladdr, remhostname, remaddr);
		free(lcladdr);
		free(remaddr);
		if (!o_nflag)
			free(remhostname);
	}
}

/* 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->sa.sa_family, SOCK_STREAM, 0);
		set_nport(themaddr, 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(&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 wretry;                /* net-write sanity counter */
	unsigned wfirst;                /* one-shot flag to skip first net read */

	/* 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(netfd, &ding1);                /* global: the net is open */
	netretry = 2;
	wfirst = 0;
	rzleft = rnleft = 0;
	if (o_interval)
		sleep(o_interval);                /* pause *before* sending stuff, too */

	errno = 0;                        /* clear from sleep, close, whatever */
	/* and now the big ol' select shoveling loop ... */
	while (FD_ISSET(netfd, &ding1)) {        /* i.e. till the *net* closes! */
		wretry = 8200;                        /* more than we'll ever hafta write */
		if (wfirst) {                        /* any saved stdin buffer? */
			wfirst = 0;                        /* clear flag for the duration */
			goto shovel;                        /* and go handle it first */
		}
		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(0, &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);
				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, we'll finish up... */
				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(0, &ding2)) {                /* stdin: ding! */
			rr = read(0, 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(0, &ding1);                /* disable and close stdin */
				close(0);
			} 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. */

	/* sanity check.  Works because they're both unsigned... */
		if ((rzleft > 8200) || (rnleft > 8200)) {
			holler_error("bogus buffers: %u, %u", rzleft, rnleft);
			rzleft = rnleft = 0;
		}
	/* net write retries sometimes happen on UDP connections */
		if (!wretry) {                        /* is something hung? */
			holler_error("too many output retries");
			return 1;
		}
		if (rnleft) {
			rr = write(1, np, rnleft);
			if (rr > 0) {
				if (o_ofile)
					oprint('<', np, rr);                /* log the stdout */
				np += rr;                        /* fix up ptrs and whatnot */
				rnleft -= rr;                        /* will get sanity-checked above */
				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)
					oprint('>', zp, rr);                /* log what got sent */
				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);
			errno = 0;                        /* clear from sleep */
			continue;                        /* ...with hairy select loop... */
		}
		if ((rzleft) || (rnleft)) {                /* shovel that shit till they ain't */
			wretry--;                        /* none left, and get another load */
			goto shovel;
		}
	} /* while ding1:netfd is 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);
int nc_main(int argc, char **argv)
{
	char *str_p, *str_s, *str_w;
	USE_NC_EXTRA(char *str_i, *str_o;)
	char *themdotted = themdotted; /* gcc */
	char **proggie;
	int x;
	unsigned o_lport = 0;

	/* I was in this barbershop quartet in Skokie IL ... */
	/* round up the usual suspects, i.e. malloc up all the stuff we need */
	PTR_TO_GLOBALS = xzalloc(sizeof(G));

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

	proggie = argv;
	while (*++proggie) {
		if (strcmp(*proggie, "-e") == 0) {
			*proggie = NULL;
			argc = proggie - argv;
			proggie++;
			goto e_found;
		}
	}
	proggie = NULL;
 e_found:

	// -g -G -t -r deleted, unimplemented -a deleted too
	opt_complementary = "?2:vv"; /* max 2 params, -v is a counter */
	getopt32(argc, argv, "hnp:s:uvw:" USE_NC_SERVER("l")
			USE_NC_EXTRA("i:o:z"),
			&str_p, &str_s, &str_w
			USE_NC_EXTRA(, &str_i, &str_o, &o_verbose));
	argv += optind;
#if ENABLE_NC_EXTRA
	if (option_mask32 & OPT_i) /* line-interval time */
		o_interval = xatou_range(str_i, 1, 0xffff);
#endif
	//if (option_mask32 & OPT_l) /* listen mode */
	//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 */
		o_wait = xatoi_u(str_w);
	}
	//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);
		x = xsocket(ouraddr->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,
				USE_FEATURE_IPV6((themaddr ? themaddr->sa.sa_family : AF_UNSPEC),)
				x);
		if (o_lport)
			set_nport(ouraddr, htons(o_lport));
	}
	xmove_fd(x, netfd);
	setsockopt_reuseaddr(netfd);
	if (o_udpmode)
		socket_want_pktinfo(netfd);
	xbind(netfd, &ouraddr->sa, ouraddr->len);
#if 0
	setsockopt(netfd, SOL_SOCKET, SO_RCVBUF, &o_rcvbuf, sizeof o_rcvbuf);
	setsockopt(netfd, SOL_SOCKET, SO_SNDBUF, &o_sndbuf, sizeof o_sndbuf);
#endif

	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");
	}

	FD_SET(0, &ding1);                        /* stdin *is* initially open */
	if (proggie) {
		close(0); /* 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 (o_listen) {
		dolisten();
		/* dolisten does its own connect reporting */
		if (proggie) /* -e given? */
			doexec(proggie);
		x = readwrite(); /* it even works with UDP! */
	} else {
		/* Outbound connects.  Now we're more picky about args... */
		if (!themaddr)
			bb_error_msg_and_die("no destination");

		remend = *themaddr;
		if (o_verbose)
			themdotted = xmalloc_sockaddr2dotted(&themaddr->sa, themaddr->len);

		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;
}
