/* Fa l'echo di un messaggio ricevuto 
   Quando e' lanciato, bisogna redirigere lo standard error
   su un file di log di errori ed eseguirlo in background.
   Ricordarsi di killarlo alla fine della prova.
   Funziona in coppia con echoclient.c
*/

#include <errno.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

#define  BACKLOG         5      /* n. max di richieste in coda */
#define  MAXHOSTNAME    32      /* lunghezza massima nome host */
#define  SERVER       3123      /* porta del server */
char    zero[20];

main (argc, argv)
int  argc;
char **argv;

{ int  sfd, tfd;                /* socket descr. */
  int  i,err;                   
  struct  sockaddr_in  sa, isa; /* indirizzi Internet */
  struct  hostent  *hp;         /* risultato host name lookup */
  struct  servent  *sp;         /* risultato service lookup */
  char    *myname;              /* nome di questo eseguibile */
  char    localhost[MAXHOSTNAME+1]; /* local host name come stringa */

  myname=argv[0];

  for (i=1; i<21; i++) {zero[i]='\0';}
  /* chiede l'indirizzo del local host */
  gethostname(localhost,MAXHOSTNAME);
  if ((hp=gethostbyname(localhost))==NULL)  {
     fprintf(stderr, "%s:  errore local host \n", myname);
     exit(1);
    }

  /* inserisce il socket number dentro la struttura del socket */
  sa.sin_port=htons((short int) SERVER);

  /* costruisce la struttura che contiene l'indirizzo del local host */ 
  bcopy((char *) hp->h_addr, (char *) &sa.sin_addr, hp->h_length);
  sa.sin_family=hp->h_addrtype;

  /* richiede un descrittore di socket */
  if (( sfd=socket(hp->h_addrtype, SOCK_STREAM, 0))<0 )   {
     fprintf(stderr, "%s:  errore apertura socket \n", myname);
     exit;
  }
  /* fa il bind alla service port */
  if ((err=bind(sfd, &sa, sizeof sa))<0)   {
     fprintf (stderr, "%s:  errore %d   \n", myname, errno);
     fprintf (stderr, "%s:  bind rifiutato, errore %d   porta %d\n", 
               myname, err, ntohs(sa.sin_port));
     exit(1);
     }

  /* massimo numero di connessioni accettate */
  listen(sfd, BACKLOG);

  /* loop infinita di attesa richieste */
  for (;;)   {
      i=sizeof isa;      
      if (( tfd=accept(sfd, &isa, &i))<0)   {
          printf("%s:  errore accept \n", myname);
          exit(1);
      }
      echo(tfd);        /* esegue quanto richiesto */
      close(tfd);
      }
}


echo(sock)
int sock;

{  char    buf[BUFSIZ], ret[BUFSIZ];
   int     i;

   /* legge una richiesta */
   if ((i=read(sock, buf, BUFSIZ))<= 0)
       strcpy(ret, "non ho letto niente \n");
   else {
          buf[i]=' ';           /* terminatore nullo */
          sprintf(ret, "ho letto %s \n", buf);
        }
   /* invia la risposta */
   write(sock, ret, strlen(ret));
   strcpy(ret, zero);
   return;
}