home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume25 / fsp / part02 / server_lib.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-12  |  5.8 KB  |  209 lines

  1.     /*********************************************************************\
  2.     *  Copyright (c) 1991 by Wen-King Su (wen-king@vlsi.cs.caltech.edu)   *
  3.     *                                                                     *
  4.     *  You may copy or modify this file in any manner you wish, provided  *
  5.     *  that this notice is always included, and that you hold the author  *
  6.     *  harmless for any loss or damage resulting from the installation or *
  7.     *  use of this software.                                              *
  8.     \*********************************************************************/
  9.  
  10. #include "server_def.h"
  11.  
  12. extern int errno;
  13.  
  14. static int myport = 0;
  15. static int myfd;
  16. static int interrupted = 0;
  17.  
  18. server_interrupt()
  19. {
  20.     interrupted = 1;
  21.     signal(SIGALRM,server_interrupt);
  22. }
  23.  
  24. /****************************************************************************
  25. *  This is the message filter.  It is called by main with a timeout value.
  26. *  If timeout is -1, it will never time out.  Otherwise, it waits for a
  27. *  message.  If timed out, it returns.  Otherwise it pass it through checks.
  28. *  Those message that passed get sent to the dispatch loop.
  29. ****************************************************************************/
  30.  
  31. server_loop(timeout)
  32.     unsigned long timeout;
  33. {
  34.     unsigned long cur_time;
  35.     HTAB *hp;
  36.     UBUF rbuf;
  37.     struct sockaddr_in from;
  38.     unsigned u, sum, mask;
  39.     int retval, bytes, old;
  40.     unsigned char *s, *d, *t;
  41.  
  42.     while(1)
  43.     {
  44.     mask = 1 << myfd;
  45.     if(interrupted) { dump_htab(); interrupted = 0; }
  46.     retval = _x_select(&mask, timeout);
  47.  
  48.     if(retval == -1) { if(errno = EINTR) continue;
  49.                perror("select"); exit(1); }
  50.  
  51.     if(retval == 1)    /* an incoming message is waiting */
  52.     {
  53.         bytes = sizeof(from);
  54.         if((bytes = recvfrom(myfd,(char*)&rbuf,sizeof(rbuf),0,
  55.                     &from,&bytes)) < UBUF_HSIZE) continue;
  56.  
  57.         rbuf.len = ntohs(rbuf.len);
  58.         if(rbuf.len+UBUF_HSIZE > bytes) continue;    /* truncated.  */
  59.  
  60.         if(!(hp = find_host(from.sin_addr.s_addr)))
  61.             { fputs("find host failed\n",stderr); exit(0); }
  62.  
  63.         if(hp->inhibit) continue;
  64.  
  65.         old = 0;
  66.         cur_time = time((time_t *) 0);
  67.  
  68.         if(hp->next_key != rbuf.key)
  69.         {
  70.         if(hp->last_key == rbuf.key)
  71.         {
  72.             if(hp->active && (cur_time < hp->last_acc + 3)) continue;
  73.             old = 1;
  74.  
  75.         } else
  76.         if(hp->active && (cur_time < hp->last_acc + 60)) continue;
  77.         }
  78.  
  79.         hp->active   =        1;
  80.         hp->last_acc = cur_time;
  81.  
  82.         s = (unsigned char *) &rbuf;
  83.         d = s + bytes;
  84.         u = rbuf.sum; rbuf.sum = 0;
  85.         for(t = s, sum = bytes; t < d; sum += *t++);
  86.         sum = (sum + (sum >> 8)) & 0xff;
  87.         if(sum != u) continue;            /* wrong check sum */
  88.  
  89.         rbuf.pos = ntohl(rbuf.pos);
  90.         server_get_packet(bytes,&rbuf,old,hp,&from);
  91.  
  92.     } else return(0);                /* got a timeout */
  93.     }
  94. }
  95.  
  96. /****************************************************************************
  97. * Routine to return a 16-bit key with random number in the first 8-bits and
  98. * zero in the second 8-bits.
  99. ****************************************************************************/
  100.  
  101. get_next_key()
  102. {
  103.     unsigned long k;
  104.  
  105.     k = random();
  106.     k = k ^ (k >> 8) ^ (k >> 16) ^ (k << 8);
  107.  
  108.     return(k & 0xff00);
  109. }
  110.  
  111. /****************************************************************************
  112. * Generic routine for sending reply back to clients.
  113. *        from: client address structure.
  114. *          ub: pointer to the message buffer.
  115. *  len1, len2: lengths of the two data regions in the message buffer.
  116. ****************************************************************************/
  117.  
  118. server_reply(from,ub,len1,len2)
  119.     struct sockaddr_in *from;
  120.     UBUF *ub;
  121.     int   len1, len2;
  122. {
  123.     unsigned char *s, *t, *d;
  124.     unsigned sum;
  125.  
  126.     if(dbug) fprintf(stderr,"snd (%c,%d,%d,%lu) ---> %d.%d.%d.%d\n",
  127.                 ub->cmd, len1, len2, ub->pos,
  128.                 ((unsigned char *)(&(from->sin_addr.s_addr)))[0],
  129.                 ((unsigned char *)(&(from->sin_addr.s_addr)))[1],
  130.                 ((unsigned char *)(&(from->sin_addr.s_addr)))[2],
  131.                 ((unsigned char *)(&(from->sin_addr.s_addr)))[3]);
  132.  
  133.     ub->len = htons(len1);
  134.     ub->pos = htonl(ub->pos);
  135.  
  136.     ub->sum = 0;
  137.     s = (unsigned char *) ub;
  138.     d = s + (len1 + len2 + UBUF_HSIZE);
  139.     for(t = s, sum = 0; t < d; sum += *t++);
  140.     ub->sum = sum + (sum >> 8);
  141.  
  142.     if(sendto(myfd,(char *)ub,(len1 + len2 + UBUF_HSIZE),0,
  143.             from,sizeof(struct sockaddr_in)) == -1)
  144.                         { perror("sendto"); exit(1); }
  145. }
  146.  
  147. /****************************************************************************
  148. * Send an error string.
  149. ****************************************************************************/
  150.  
  151. send_error(from,ub,msg)
  152.     struct sockaddr_in *from;
  153.     UBUF *ub;
  154.     char *msg;
  155. {
  156.     char *d;
  157.  
  158.     for(d = ub->buf; *d++ = *msg++; );
  159.     ub->cmd = CC_ERR;
  160.  
  161.     server_reply(from,ub,d-ub->buf,0);
  162. }
  163.  
  164. /****************************************************************************
  165. * Send a block of data read from the file 'fp'.  Offset information is
  166. * contained in the input ub message buffer, which also doubles as the output
  167. * message buffer.
  168. ****************************************************************************/
  169.  
  170. send_file(from,ub,fp)
  171.     struct sockaddr_in *from;
  172.     UBUF *ub;
  173.     FILE *fp;
  174. {
  175.     int bytes;
  176.  
  177.     fseek(fp,ub->pos,0);
  178.     bytes = fread(ub->buf, 1, UBUF_SPACE, fp);
  179.     server_reply(from,ub,bytes,0);
  180. }
  181.  
  182. /****************************************************************************
  183. * The tow UDP socket initialization routines.  One for running alone.
  184. * The other for running under inetd.
  185. ****************************************************************************/
  186.  
  187. init_network(port)
  188.     int port;
  189. {
  190.     myport = port;
  191.  
  192.     if((myfd = _x_udp(&myport)) == -1) { perror("socket open"); exit(1); }
  193.  
  194.     if(dbug)
  195.     {
  196.     fprintf(stderr,"listening on port %d\n",myport);
  197.     fflush(stderr);
  198.     }
  199.  
  200.     signal(SIGALRM,server_interrupt);
  201. }
  202.  
  203. init_inetd()
  204. {
  205.     myfd = dup(0);
  206.  
  207.     signal(SIGALRM,server_interrupt);
  208. }
  209.