#include <stdio.h>
#include <unistd.h>		/* funzioni su file, es. close() */
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>	/* rete internet */
#include <arpa/inet.h> /* funzioni di utilità es. inet_addr() */
#include <errno.h>

void err_fatal(char *mes);
void showAddr (char *msg, struct sockaddr_in *saddr);
extern int errno;

int main (int argc, char **argv) {

  char rc[1024];
  unsigned long taddr_n, taddr_h; /* IP addr.(net/host order) */
  unsigned short tport_n, tport_h;	/* port number */
  struct sockaddr_in saddr;	/* server address */
  int s;
  int result;

  if (argc < 2) {
    fprintf (stderr, "Provide: host address (dotted notation)\n");
    return 1;
  }

  /* converte l'indirizio nella forma puntata (es. 130.192.3.81)
   * in un intero formato dai corrispondenti ottetti */
  taddr_n = inet_addr (argv[1]);
  /* mette gli ottetti nell'ordinamento di rete (BE) */
  taddr_h = ntohl (taddr_n);

  if(argc>2){
	  tport_h = atoi(argv[2]);
  }else{
	  tport_h = 25;			/* SMTP service */
  }
  tport_n = htons (tport_h);

  /* creazione del socket */
  printf ("Creating socket\n");
  s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
  if (s == -1)
    err_fatal ("socket() failed");
  printf ("done. Socket number: %d\n", s);

  /* preparazione dell'indirizzo */
  saddr.sin_family = AF_INET;
  saddr.sin_port = tport_n;
  saddr.sin_addr.s_addr = taddr_n;

  /* connessione */
  showAddr ("Connecting to target address ", &saddr);
  result = connect (s, (struct sockaddr *) &saddr, sizeof (saddr));
  if (result == -1)
    err_fatal ("connect() failed");
  printf ("done.\n");

  printf ("waiting for response...\n");
  memset(rc,0,sizeof(rc));
  result = recv (s, rc, sizeof (rc), 0);
  if (result <= 0) {
    printf ("Read error/Connection closed\n");
    close (s);
    return 3;
  }
  else {
    printf ("Received response from socket %03u : \n[%s]\n", s, rc);
  }


  close(s);

  return 0;
}

void err_fatal(char *mes) {
	printf("%s, errno=%d\n", mes, errno);
	perror(""); exit(1);
}

void showAddr (char *msg, struct sockaddr_in *saddr){
  /* vede i singoli ottetti come caratteri senza segno (byte) */
  unsigned char *ptr_addr = &(saddr->sin_addr.s_addr);
  printf ("%s %u.%u.%u.%u:%u\n", msg, 
	  ptr_addr[0],
	  ptr_addr[1], 
	  ptr_addr[2],
	  ptr_addr[3], 
	  ntohs (saddr->sin_port));
}

