/*
 * Iconnect.c - A program to test out telnet connections.
 * Usage: Iconnect [host]
 *  ... dialog
 *  ^C or ^D or QUIT
 */

# include <stdio.h>
# include <ctype.h>
# include <fcntl.h>
# include <sys/ioctl.h>
# include <sys/time.h>
# include <sys/types.h>
# include <sys/socket.h>
# include <netinet/in.h>
# include <netdb.h>

#define CLIENT_KRB_TIMEOUT	5

int	debug;

static struct timeval timeout = { CLIENT_KRB_TIMEOUT, 0};

int iconnect(host, port)
	char *host;
	int port;
{
	register int s;
	struct sockaddr_in	Address;
	int pid;
	int on = 1;
	struct servent *sp;
	int raw = 0;
	char buf[1000];
	extern char *index();
	register FILE *f;
	register struct hostent *hp;
	char readbuf[10];
	fd_set read_fd;
	int	state;
	static	char con_string[] = "connected";
#ifndef SO_DONTLINGER
	struct linger linger;
#endif  SO_DONTLINGER


#ifdef DEBUG
	debug = 1;
#endif DEBUG

	s = socket(AF_INET, SOCK_STREAM, 0);
	if (s < 0)
	{
		perror("socket");
		exit(-1);
	}
	(void) setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (char *)&on, sizeof(on));
	(void) setsockopt(s, SOL_SOCKET, SO_REUSEADDR,  (char *) NULL, 0);
	(void) setsockopt(s, SOL_SOCKET, SO_USELOOPBACK,(char *) NULL, 0);
#ifdef  SO_DONTLINGER
	(void) setsockopt(s, SOL_SOCKET, SO_DONTLINGER, (char *) NULL, 0);
#else   SO_DONTLINGER
	linger.l_onoff = 0;
	linger.l_linger = 0;
	(void) setsockopt(s, SOL_SOCKET, SO_LINGER, (char *)&linger, sizeof linger);
#endif  SO_DONTLINGER

	sp = getservbyname("telnet-passthru", "tcp");
	if (sp != NULL)
		Address.sin_port = sp->s_port;

	if (host == NULL)
		host = "localhost";

	hp = gethostbyname("sun-barr");
	if (hp == NULL)
	{
		fprintf(stderr, "iconnect: unknown host %s\r\n", "sun-barr");
		return(-1);
	} else {
		bcopy(hp->h_addr, &Address.sin_addr, hp->h_length);
	}
	Address.sin_family = AF_INET;

	if (debug)
	  printf("connecting to host %s %d port via proxy@sun-barr\r\n", host, port); 
	
	if (connect(s, &Address, sizeof Address) < 0)
	{
		perror("connect");
		close(s);
		return(-1);
	}

	/* Good connection to sun-barr, now we need to send it the
	 * host and port we wish to connect to, and then hope to
	 * get a connection.
	 */

	if (debug)
	  printf("connection open\n"); 
	write(s,host,strlen(host));
	write(s," ",1);
	sprintf(buf, "%d", port);
	write(s,buf,strlen(buf));
	write(s,"\r\n",2);

	/* Right now I need to to find a way to clear the socket.
	 * I'm GOING to have data on it, because the proxy server
	 * is going to give me some.  I need a way to clear it 
	 * off the socket.
	 */

	if (read(s, readbuf, 4) < 4) {
	  if (debug)
	    printf("Error reading from socket\n");
	  close(s);
	  return(-1);
	}

	(void)ioctl(s, FIONBIO, &on);

	if (debug)
	  printf("%s", readbuf);

	timeout.tv_sec = 0;
	timeout.tv_usec = 500000;

	state = 0;
	do {
	  FD_ZERO(&read_fd);
	  FD_SET(s, &read_fd);
	  if (!read(s, readbuf, 1)) {
	    close(s);
	    return(-1);
	  }
	  if (debug)
	      printf("%x ", *readbuf);
	  if (debug)
	      putchar(*readbuf);
	  if (*readbuf == con_string[state])
	      state++;
	  if (state == strlen(con_string))
	      if (*readbuf == 0xa)
		  state++;
	} while ((select(s+1, &read_fd, (fd_set *)0, (fd_set *)0, &timeout) 
		  > 0) && (state <= strlen(con_string)));

/*	fcntl(s, F_SETFL, (fcntl(s, F_GETFL, 0) | FNDELAY)); 
 * I dont think I need this.
 * If the user of this command wants to make the connection
 * asyncronous, then it can go ahead an do it!
 */

	return(s);
};

