Guest User

part3

a guest
May 3rd, 2016
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /** sol13.13
  2.  ** ------------------------------------------------------------
  3.     A version of lserv_funcs1.c that prints the state of
  4.     the ticket table when sent SIGHUP is
  5.     sol13.13.c.
  6.  
  7.  ** ------------------------------------------------------------
  8.  **
  9.  **
  10.  *   A version of lsrv_funcs1.c that prints the state of the ticket table
  11.  *   when it receives SIGHUP.  The handler is set in setup() which is
  12.  *   called by main()
  13.  *
  14.  *   use this to build lserv1 with
  15.  *
  16.  *   build: cc lserv1.c sol13.13.c dgram.c -o sol13.13
  17.  */
  18. /****************************************************************************
  19.  * lsrv_funcs1.c
  20.  * functions for the license server
  21.  */
  22.  
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <unistd.h>
  26. #include <string.h>
  27. #include <sys/types.h>
  28. #include <sys/socket.h>
  29. #include <netinet/in.h>
  30. #include <arpa/inet.h>
  31. #include <netdb.h>
  32. #include <signal.h>
  33. #include <sys/errno.h>
  34. #include <signal.h>
  35. #include "dgram.h"
  36.  
  37. #define SERVER_PORTNUM  2020        /* Our server's port number */
  38. #define MSGLEN      128     /* Size of our datagrams */
  39. #define TICKET_AVAIL    0       /* Slot is available for use */
  40. #define MAXUSERS    3       /* Only 3 users for us */
  41. #define oops(x) { perror(x); exit(-1); }
  42.  
  43. int setup();
  44. void    free_all_tickets();
  45. void    show_ticket_array(int );
  46. void    shut_down();
  47. void    handle_request(char *,struct sockaddr_in *, socklen_t );
  48. char    *do_hello(char *);
  49. char    *do_goodbye(char *);
  50. void    narrate(char *, char *, struct sockaddr_in *);
  51.  
  52. /****************************************************************************
  53.  * Important variables
  54.  */
  55. int ticket_array[MAXUSERS]; /* Our ticket array */
  56. int sd = -1;            /* Our socket */
  57. int num_tickets_out = 0;    /* Number of tickets outstanding */
  58.  
  59. /****************************************************************************
  60.  * setup() - initialize license server
  61.  */
  62. int setup()
  63. {
  64.     void show_ticket_array(int);
  65.  
  66.     sd = make_dgram_server_socket(SERVER_PORTNUM);
  67.     if ( sd == -1 )
  68.         oops("make socket");
  69.     free_all_tickets();
  70.     signal(SIGHUP, show_ticket_array);
  71.     return sd;
  72. }
  73.  
  74. void free_all_tickets()
  75. {
  76.     int i;
  77.  
  78.     for(i=0; i<MAXUSERS; i++)
  79.         ticket_array[i] = TICKET_AVAIL;
  80. }
  81.  
  82. /****************************************************************************
  83.  * void dump_ticket_array(int)
  84.  *  shows to stdout the ticket array
  85.  */
  86. void show_ticket_array(int s)
  87. {
  88.     int i;
  89.  
  90.     signal(SIGHUP, show_ticket_array)/* just in case */
  91.  
  92.     for(i=0 ; i<MAXUSERS ; i++){
  93.         printf("%3d\t", i);
  94.         if ( ticket_array[i] == TICKET_AVAIL )
  95.             printf("FREE\n");
  96.         else
  97.             printf("%5d\n", ticket_array[i]);
  98.     }
  99. }
  100.  
  101. /****************************************************************************
  102.  * shut_down() - close down license server
  103.  */
  104. void shut_down()
  105. {
  106.     close(sd);
  107. }
  108.  
  109. /****************************************************************************
  110.  * handle_request(request, clientaddr, addrlen)
  111.  *   branch on code in request
  112.  */
  113. void handle_request(char *req,struct sockaddr_in *client, socklen_t addlen)
  114. {
  115.     char    *response;
  116.     int ret;
  117.  
  118.     /* act and compose a response */
  119.     if ( strncmp(req, "HELO", 4) == 0 )
  120.         response = do_hello(req);
  121.     else if ( strncmp(req, "GBYE", 4) == 0 )
  122.         response = do_goodbye(req);
  123.     else
  124.         response = "FAIL invalid request";
  125.  
  126.     /* send the response to the client */
  127.     narrate("SAID:", response, client);
  128.     ret = sendto(sd, response, strlen(response),0,
  129.                 (struct sockaddr*) client, addlen);
  130.     if ( ret == -1 )
  131.         perror("SERVER sendto failed");
  132. }
  133.  
  134. /****************************************************************************
  135.  * do_hello
  136.  * Give out a ticket if any are available
  137.  * IN  msg_p            message received from client
  138.  * Results: ptr to response
  139.  *    NOTE: return is in static buffer overwritten by each call
  140.  */
  141. char *do_hello(char *msg_p)
  142. {
  143.     int x;
  144.     static char replybuf[MSGLEN];
  145.  
  146.     if(num_tickets_out >= MAXUSERS)
  147.         return("FAIL no tickets available");
  148.  
  149.     /* else find a free ticket and give it to client */
  150.  
  151.     for(x = 0; x<MAXUSERS && ticket_array[x] != TICKET_AVAIL; x++)
  152.         ;
  153.  
  154.     /* A sanity check - should never happen */
  155.     if(x == MAXUSERS) {
  156.         narrate("database corrupt","",NULL);
  157.         return("FAIL database corrupt");
  158.     }
  159.  
  160.     /* Found a free ticket.  Record "name" of user (pid) in array.
  161.      *  generate ticket of form: pid.slot
  162.      */
  163.     ticket_array[x] = atoi(msg_p + 5); /* get pid in msg */
  164.     sprintf(replybuf, "TICK %d.%d", ticket_array[x], x);
  165.     num_tickets_out++;
  166.     return(replybuf);
  167. } /* do_hello */
  168.  
  169. /****************************************************************************
  170.  * do_goodbye
  171.  * Take back ticket client is returning
  172.  * IN  msg_p            message received from client
  173.  * Results: ptr to response
  174.  *     NOTE: return is in static buffer overwritten by each call
  175.  */
  176. char *do_goodbye(char *msg_p)
  177. {
  178.     int pid, slot;      /* components of ticket */
  179.  
  180.     /* The user's giving us back a ticket.  First we need to get
  181.      * the ticket out of the message, which looks like:
  182.      *
  183.      *  GBYE pid.slot
  184.      */
  185.     if((sscanf((msg_p + 5), "%d.%d", &pid, &slot) != 2) ||
  186.        (ticket_array[slot] != pid)) {
  187.         narrate("Bogus ticket", msg_p+5, NULL);
  188.         return("FAIL invalid ticket");
  189.     }
  190.  
  191.     /* The ticket is valid.  Release it. */
  192.     ticket_array[slot] = TICKET_AVAIL;
  193.     num_tickets_out--;
  194.  
  195.     /* Return response */
  196.     return("THNX See ya!");
  197. } /* do_goodbye */
  198.  
  199. /****************************************************************************
  200.  * narrate() - chatty news for debugging and logging purposes
  201.  */
  202. void narrate(char *msg1, char *msg2, struct sockaddr_in *clientp)
  203. {
  204.     fprintf(stderr,"\t\tSERVER: %s %s ", msg1, msg2);
  205.     if ( clientp )
  206.         fprintf(stderr,"(%s:%d)", inet_ntoa(clientp->sin_addr),
  207.                       ntohs(clientp->sin_port) );
  208.     putc('\n', stderr);
  209. }
Advertisement
Add Comment
Please, Sign In to add comment