A Simple Cookie Example
#include "funcs.h"
#define BUFSIZE   50
#define NOT_USED -1

int readsock;
sigjmp_buf env;
fd_set saveset;

struct timetable
{
    int socket;
    time_t requesttime;
};
struct timetable reqtimes[100];

main()
{
    int readn(int readsock, char *string, int bufsize);
    int writen(int readsock, char *string, int bufsize);
    int makeNonBlocking(int socket);
    void set_up_SIGPIPE(void);
    fd_set readset;
    int socket, passive, active, lowwater = 50, i;
    char string[50];
    int set_up_passive_socket(void);
    long flags;
    socklen_t socklen; 

    set_up_SIGPIPE();
    passive = set_up_passive_socket();

    FD_ZERO(&saveset);
    FD_SET(passive, &saveset);
    for (i = 0; i < 100; i++) reqtimes[i].socket  = NOT_USED;

    for(;;)
    {
         memcpy(&readset, &saveset, sizeof(fd_set));
         select(FD_SETSIZE, &readset, NULL, NULL, NULL);

         for (socket = 0; socket < 100; socket++)
         {
              if (reqtimes[socket].socket == NOT_USED) continue;
              if (time(NULL) - reqtimes[socket].requesttime > 10)
              {
                  close(socket);
                  FD_CLR(socket, &saveset);
                  reqtimes[socket].socket = NOT_USED;
              }
         }

         if (FD_ISSET(passive, &readset))
         {
              active = accept(passive, NULL, NULL);
              active = makeNonBlocking(active);
           
              reqtimes[active].socket      = active;
              reqtimes[active].requesttime = time(NULL);
              FD_SET(active, &saveset);
         }
  

         for(readsock = passive; readsock < FD_SETSIZE  ; readsock++)
         {
              sigsetjmp(env, 1);
              if (readsock != passive && FD_ISSET(readsock, &readset))
              {
                    printf("Inside server!  Socket is %d.\n", readsock);

                    memset(string, 0, BUFSIZE);
                    readn(readsock, string, BUFSIZE);

                    if (strcmp(string, "quit") == 0)
                    {
                         FD_CLR(readsock, &saveset);
                         close(readsock);
                         reqtimes[readsock].socket = NOT_USED; 
                         continue;
                    }

                    reqtimes[readsock].requesttime = time(NULL);
                    printf("Got %s from client!\n", string);
                    writen(readsock, string, 1);
                    writen(readsock, string + 1, BUFSIZE - 1);
              }
         }  
     }           
}    




int set_up_passive_socket(void)
{
    struct sockaddr_in sin;
    int passive, makeNonBlocking(int passive);;
    long flags;

    sin.sin_family = AF_INET;
    sin.sin_port   = htons(3014);
    sin.sin_addr.s_addr = htonl(INADDR_ANY);
 
    if  ((passive = socket(AF_INET,SOCK_STREAM,0)) < 0) 
    {
         perror("Server: socket error!");
         exit(1);
    }
    if (bind(passive, (struct sockaddr *) &sin, sizeof(sin)) < 0)
    {
         perror("Binding error in server!");
         exit(2);
    }
    if (listen(passive, 5) < 0)
    {
         perror("Listen error in server!");
         exit(3);
    }

    passive = makeNonBlocking(passive);
    return passive;
}


int makeNonBlocking(int socket)
{
     long flags;


     if ((flags = fcntl(socket, F_GETFL, 0)) < 0) 
     {
         perror("Get flags");
         exit(1);
     }
     if (fcntl(socket, F_GETFL, flags | O_NONBLOCK) < 0) 
     {
         perror("Set flags");
         exit(1);
     }

     return socket;
} 



void set_up_SIGPIPE(void)
{
      void handler(int signum);
      struct sigaction sa;

      sa.sa_handler = handler;
      sa.sa_flags   = 0;
      sigfillset(&sa.sa_mask);
      sigaction(SIGPIPE, &sa, NULL);
}



void handler(int signum)
{
      close(readsock);
      FD_CLR(readsock, &saveset);
      reqtimes[readsock].socket = NOT_USED;
      readsock++;
      siglongjmp(env, 1);
} 



int readn(int fd, char *buf, int bytes)
{
     int nleft;
     int nread;
     char *mover = buf;

     nleft = bytes;
     while (nleft > 0){
         if ((nread = read(fd,mover,nleft)) < 0)
              if (errno == EAGAIN)
              {
                  errno = 0;
                  continue;
              }
              else raise(SIGPIPE);
         else if (nread == 0)
              raise(SIGPIPE);      /****  EOF!   ****/
         nleft -= nread;
         mover += nread;
     }
     return (bytes - nleft);
}


int writen(int fd, char *buf, int bytes)
{
     int nleft;
     int nwritten;
     char *mover = buf;

     nleft = bytes;
     while (nleft > 0){
         if ((nwritten = write(fd,mover,nleft)) < 0)
              raise(SIGPIPE);  /**** Error!! ****/
         nleft -= nwritten;
         mover += nwritten;
     }
     return bytes;
}