

/****    Example of server using TCP protocol   */

#include  "inet.h"

main(argc, argv)
int argc;
char *argv[];
{
          int                  sockfd, newsockfd, clilen, childpid; 
          struct sockaddr_in   cli_addr, serv_addr;

          pname = argv[0];
          /*** Open  a TCP socket (an Internet stream socket).   ****/

          if (  (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
                err_dump("server: can't open stream socket");

          /**  Bind our local address so that the client can send to us.  **/
    
          bzero((char *) &serv_addr, sizeof(serv_addr));
          serv_addr.sin_family       =  AF_INET;
          serv_addr.sin_addr.s_addr  =  htonl(INADDR_ANY);
          serv_addr.sin_port         =  htons(SERV_TCP_PORT);

          if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) <0)
                 err_dump("server: can't bind local address");

          listen(sockfd, 5);
          for (; ; ){
                      /*
                       *  Wait for a connection from a client process.
                       *  This is an example of a concurrent server.
                       */
                       clilen = sizeof(cli_addr);

                       newsockfd  = accept(sockfd, (struct sockaddr *) &cli_addr,
                                            &clilen);

                       if (newsockfd < 0)
                              err_dump("server: accept error");
                       if( (childpid = fork())<0)
                               err_dump("server: fork error");
                       else  if (childpid == 0) {
                                 close(sockfd);
                                 str_echo(newsockfd);
                                 exit(0);
                       }
                       close(newsockfd);
           }
}
 

#define MAXLINE 512

str_echo(sockfd)
int sockfd;
{  
    int       n;
    char      line[MAXLINE];

    for ( ; ; ) {
         n = readline(sockfd, line, MAXLINE);
         if  (n == 0)
             return;
         else  if (n<0)
               err_dump("Str_echo: readline error");

         if (written(sockfd, line, n)  !=n) 
                 err_dump("str_echo: written error");
    }

} 

err_dump(a)
char *a;
{
int i;
        for (i=0; i<=20; i++)
            {  printf("%c", *a);
               a++;
            }
}


int
readline(fd, ptr, maxlen)
register int fd;
register char *ptr;
register int maxlen;
{

       int n, rc;
       char c;
 
       for (n = 1; n < maxlen; n++)  {
               if ( (rc = read(fd, &c, 1)) == 1) {
                     *ptr ++=c;
                     if (c == '\n')
                           break;
                  } else if (rc == 0) {
                              if ( n == 1)
                                 return (0);
                              else 
                                  break;
                           }else 
                                 return (-1);
         }

              *ptr=0;

              return (n);
}


          
int 
written(fd, ptr, nbytes)
register int fd;
register char *ptr;
register nbytes;
{
int   nleft, nwritten;

      nleft = nbytes;
      while (nleft > 0) {
                nwritten = write(fd, ptr, nleft);
                if (nwritten <=0)
                    return(nwritten);
 
                 nleft -= nwritten;
                 ptr   += nwritten;
       }
       return(nbytes - nleft);

}
