/*
 * Telnet clone which does little input/output cooking.
 * 2001 Feb 28 Junichi Uekawa <dancer@debian.org>
 * copyright 2001 Junichi Uekawa
 * See GPL version 2 or later for license.
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <pthread.h>

void write_to_tcp(int * sockptr)
{
  int sock = *sockptr;
  int charbuf ;
  char buf [2];
    
  while ( (charbuf = fgetc(stdin)) != EOF)
    {
      buf [0] = charbuf;
      write(sock, buf, 1);
    }
  exit (EXIT_SUCCESS);		/* exit everything. */
}

void read_from_tcp(int * sockptr)
{
  int sock = *sockptr;
  char buf [2];
  
  while ( read (sock, buf, 1) == 1) 
    {
      fputc(buf[0], stdout);
      fflush(stdout);		/* this might not be necessary */
    }  
}

int connect_to_host(char * stringaddress, int portnumber )
{
  struct sockaddr_in inet_address;
  struct hostent * hostinfo ;
  int sock;
    
  sock = socket (PF_INET, SOCK_STREAM, 0);
  
  inet_address.sin_family = AF_INET;
  inet_address.sin_port = htons(portnumber);
  hostinfo = gethostbyname(stringaddress);
  if (hostinfo == NULL)
    {
      fprintf(stderr, "Unknown host %s\n", stringaddress);
      return -1 ;      
    }
  inet_address.sin_addr = *(struct in_addr * )hostinfo->h_addr ;
  if (connect (sock,
	       (struct sockaddr *)&inet_address,
	       sizeof (inet_address))<0)
    {
      perror("connect");
      return -1 ;
    }
  return sock;  
}

int main (int ac, char ** av)
{
  int socket ;
  pthread_t read_process, write_process;
  
  printf ("teranetto by Junichi Uekawa <dancer@debian.org>\nVersion 0.0.0\n");
  
  
  if (ac != 3)
    {
      fprintf(stderr, "Please give the network address, and the port number\n");
      exit (EXIT_FAILURE);
    }

  if (-1 == (socket = connect_to_host (av[1], atoi(av[2]))))
    {
      fprintf (stderr, "Connection failed \n");
      exit (EXIT_FAILURE);
    }
  if ((0!=pthread_create(&read_process, NULL, (void*)read_from_tcp, &socket))||
       (0!=pthread_create(&write_process, NULL, (void*)write_to_tcp, &socket)))
    {
      fprintf(stderr, "Failed to create threads\n");
      exit (EXIT_FAILURE);
    }
  fprintf(stderr, "Connected to remote host [%s] in port %s\n", av[1], av[2]);
  
  pthread_join (read_process, NULL);
  pthread_cancel(write_process);  
  fprintf(stderr, "Connection reset by peer\n");
  
  exit (EXIT_SUCCESS);
}
