/* 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);
		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);
					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);
		remaddr = xmalloc_sockaddr2dotted(&remend.sa);
		remhostname = o_nflag ? remaddr : xmalloc_sockaddr2host(&remend.sa);
		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) MAIN_EXTERNALLY_VISIBLE;
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(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);

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