SRAND(time(0));
main(argc, argv)	int     argc;	char  **argv;{	int x, ch;	char *cp;	struct host_info   *gp;	struct host_info   *whereto = NULL;	struct host_info   *wherefrom = NULL;	struct in_addr     *ouraddr = NULL;	struct in_addr     *themaddr = NULL;	u_short  o_lport = 0;	u_short  ourport = 0;	u_short  loport = 0;	/* for scanning stuff */	u_short  hiport = 0;	u_short  curport = 0;	char   *randports = NULL;#ifdef HAVE_BIND	res_init();#endif	lclend = (struct sockaddr_in *) calloc(1, sizeof(struct sockaddr));	remend = (struct sockaddr_in *) calloc(1, sizeof(struct sockaddr));	bigbuf_in = calloc(1, BIGSIZ);	bigbuf_net = calloc(1, BIGSIZ);	pinfo= (struct port_info *) calloc(1, sizeof(struct port_info));	errno = 0;	gatesptr = 4;	h_errno = 0;	/*	 * We want to catch a few of these signals. 	 * Others we disgard.	 */	signal(SIGINT, catch);	signal(SIGQUIT, catch);	signal(SIGTERM, catch);	signal(SIGURG, SIG_IGN);	signal(SIGPIPE, SIG_IGN);	/* important! */	/* 	 * If no args given at all, get 'em from stdin, construct an argv, 	 * and hand anything left over to readwrite().	 */	if (argc == 1) {		cp = argv[0];		/* XXX - 128 ? */		argv = (char **) calloc(1, 128 * sizeof(char *));		argv[0] = cp;	/* leave old prog name intact */		cp = calloc(1, BIGSIZ);		argv[1] = cp;	/* head of new arg block */		fprintf(stderr, "Cmd line: ");		fflush(stderr);	/* I dont care if it's unbuffered or not! */		insaved = read(0, cp, BIGSIZ-1); /* we're gonna fake fgets()						 * here */		cp[BIGSIZ-1] = '\0';		if (insaved <= 0)			nlog(1, "wrong");		x = findline(cp, insaved);		if (x)			insaved -= x;	/* remaining chunk size to be sent */		if (insaved)	/* which might be zero... */			memcpy(bigbuf_in, &cp[x], insaved);		cp = strchr(argv[1], '\n');		if (cp)			*cp = '\0';		cp = strchr(argv[1], '\r');	/* look for ^M too */		if (cp)			*cp = '\0';		/*		 * Find and stash pointers to remaining new "args"		 */		cp = argv[1];		cp++;		/* skip past first char */		x = 2;		/* we know argv 0 and 1 already */		for (; *cp != '\0'; cp++) {			if (*cp == ' ') {				*cp = '\0';	/* smash all spaces */				continue;			} else {				if (*(cp - 1) == '\0') {					argv[x] = cp;					x++;				}			}	/* if space */		}		/* for cp */		argc = x;	}	while ((ch = getopt(argc, argv, "g:G:hi:lno:p:rs:tuvw:z")) != -1) {		switch (ch) {		case 'G':			/* srcrt gateways pointer val */			x = atoi(optarg);			/* Mask of bits */			if ((x) && (x == (x & 0x1c)))				gatesptr = x;			else				nlog(1, "invalid hop pointer %d, must be multiple of 4 <= 28", x);			break;		case 'g':			/* srcroute hop[s] */			if (gatesidx > 8)				nlog(1, "Too many -g hops!");			if (gates == NULL)				gates = (struct host_info **) calloc(1, 						sizeof(struct host_info *) * 10);			gp = gethinfo(optarg, o_nflag);			if (gp)				gates[gatesidx] = gp;			gatesidx++;			break;		case 'h':			help();			break;		case 'i':			/* line-interval time */			o_interval = atoi(optarg) & 0xffff;			if (!o_interval)				nlog(1, "invalid interval time %s", optarg);			break;		case 'l':			/* listen mode */			o_listen++;			break;		case 'n':			/* numeric-only, no DNS lookups */			o_nflag++;			break;		case 'o':			/* hexdump log */			stage = (unsigned char *) optarg;			o_wfile++;			break;		case 'p':			/* local source port */			o_lport = getpinfo(optarg, 0);			if (o_lport == 0)				nlog(1, "invalid local port %s", optarg);			break;		case 'r':			/* randomize various things */			o_random++;			break;		/* 		 * Do a full lookup [since everything else goes through the same 		 * mill], unless -n was previously specified. In fact, careful		 * placement of -n can be useful, so we'll still pass o_nflag		 * here instead of forcing numeric.		 */		case 's':			/* local source address */			wherefrom = gethinfo(optarg, o_nflag);			ouraddr = &wherefrom->iaddrs[0];			break;#ifdef TELNET		case 't':			/* do telnet fakeout */			o_tn++;			break;#endif		case 'u':			/* use UDP */			o_udpmode++;			break;		case 'v':			/* verbose */			o_verbose++;			break;		case 'w':			/* wait time */			o_wait = atoi(optarg);			if (o_wait <= 0)				nlog(1, "invalid wait-time %s", optarg);			timer1.tv_sec = o_wait;			timer1.tv_usec = 0;			break;		case 'z':			/* little or no data xfer */			o_zero++;			break;		default:			usage(1);		}	}	/* other misc initialization */	    FD_SET(0, &fds1);	/* stdin *is* initially open */	if (o_random) {		SRAND(time(0));		randports = calloc(1, 65536);   /* big flag array for ports */	}	if (o_wfile) {		ofd = open(stage, O_WRONLY | O_CREAT | O_TRUNC, 0664);		if (ofd <= 0)	/* must be > extant 0/1/2 */			nlog(1, "Can't open %s", stage);		stage = (unsigned char *) calloc(1, 100);	}	/* optind is now index of first non -x arg */	if (argv[optind])		whereto = gethinfo(argv[optind], o_nflag);	if (whereto && whereto->iaddrs)		themaddr = &whereto->iaddrs[0];	if (themaddr)		optind++;	/* skip past valid host lookup */	errno = 0;	h_errno = 0;	/*	 * Handle listen mode here, and exit afterward.  Only does one connect;	 * this is arguably the right thing to do.  A "persistent listen-and-fork"	 * mode a la inetd has been thought about, but not implemented.  A tiny 	 * wrapper script can handle such things.	 */	if (o_listen) {		curport = 0;		if (argv[optind]) {			curport = getpinfo(argv[optind], 0);			if (curport == 0)				nlog(1, "invalid port %s", argv[optind]);		}		netfd = dolisten(themaddr, curport, ouraddr, o_lport);		if (netfd > 0) {			x = readwrite(netfd);			if (o_verbose)				nlog(0, "Sent %i Rcvd %i", wrote_net, wrote_out);			exit(x);		} else				nlog(1, "no connection");	}	/* fall thru to outbound connects.  Now we're more picky about args... */	if (!themaddr)		nlog(1, "no destination");	if (argv[optind] == NULL)		nlog(1, "no port[s] to connect to");	if (argv[optind + 1])		Single = 0;	ourport = o_lport;	while (argv[optind]) {		hiport = loport = 0;		cp = strchr(argv[optind], '-');		if (cp) {			*cp = '\0';			cp++;			hiport = getpinfo(cp, 0);			if (hiport == 0)				nlog(1, "invalid port %s", cp);		}		/* if found a dash */		loport = getpinfo(argv[optind], 0);		if (loport == 0)			nlog(1, "invalid port %s", argv[optind]);		if (hiport > loport) {	/* was it genuinely a range? */			Single = 0;	/* multi-mode, case B */			if (o_random) {	/* maybe populate the random array */				loadports(randports, loport, hiport);				curport = nextport(randports);			} else				curport = hiport;		} else		/* not a range, including args like "25-25" */			curport = loport;	  	    /*		     * Now start connecting to these things.  		     * curport is already preloaded.		     */		    while (loport <= curport) {			curport = getpinfo(NULL, curport);			netfd = doconnect(themaddr, curport, ouraddr, ourport);			if (netfd > 0)				if (o_zero && o_udpmode)					netfd = udptest(netfd, themaddr);			if (netfd > 0) {				x = 0;				if (o_verbose) {					nlog(0, "%s [%s] %d (%s) open",				    		whereto->name, 						whereto->addrs[0], curport, 						pinfo->name);				}				if (!o_zero)					x = readwrite(netfd);			} else {				x = 1;				if ((Single || (o_verbose > 1)) 				   || (errno != ECONNREFUSED)) {					nlog(0, "%s [%s] %d (%s)",					     whereto->name, whereto->addrs[0], 					     curport, pinfo->name);				}			}			close(netfd);			if (o_interval)				sleep(o_interval);			if (o_random)				curport = nextport(randports);			else				curport--;		}		optind++;	}	errno = 0;	nlog(0, "Sent %i Rcvd %i", wrote_net, wrote_out);	if (Single)		exit(x);	exit(0);}