home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / N / TCPIP / NETKIT-B.05 / NETKIT-B / NetKit-B-0.05 / talkd / process.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-17  |  5.9 KB  |  217 lines

  1. /*
  2.  * Copyright (c) 1983 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. /*static char sccsid[] = "from: @(#)process.c    5.10 (Berkeley) 2/26/91";*/
  36. static char rcsid[] = "$Id: process.c,v 1.2 1993/08/01 18:29:34 mycroft Exp $";
  37. #endif /* not lint */
  38.  
  39. /*
  40.  * process.c handles the requests, which can be of three types:
  41.  *    ANNOUNCE - announce to a user that a talk is wanted
  42.  *    LEAVE_INVITE - insert the request into the table
  43.  *    LOOK_UP - look up to see if a request is waiting in
  44.  *          in the table for the local user
  45.  *    DELETE - delete invitation
  46.  */
  47. #include <sys/param.h>
  48. #include <sys/stat.h>
  49. #include <sys/socket.h>
  50. #include <netinet/in.h>
  51. #include <protocols/talkd.h>
  52. #include <netdb.h>
  53. #include <syslog.h>
  54. #include <stdio.h>
  55. #include <string.h>
  56. #include <paths.h>
  57.  
  58. CTL_MSG *find_request();
  59. CTL_MSG *find_match();
  60.  
  61. process_request(mp, rp)
  62.     register CTL_MSG *mp;
  63.     register CTL_RESPONSE *rp;
  64. {
  65.     register CTL_MSG *ptr;
  66.     extern int debug;
  67.  
  68.     rp->vers = TALK_VERSION;
  69.     rp->type = mp->type;
  70.     rp->id_num = htonl(0);
  71.     if (mp->vers != TALK_VERSION) {
  72.         syslog(LOG_WARNING, "Bad protocol version %d", mp->vers);
  73.         rp->answer = BADVERSION;
  74.         return;
  75.     }
  76.     mp->id_num = ntohl(mp->id_num);
  77.     mp->addr.sa_family = ntohs(mp->addr.sa_family);
  78.     if (mp->addr.sa_family != AF_INET) {
  79.         syslog(LOG_WARNING, "Bad address, family %d",
  80.             mp->addr.sa_family);
  81.         rp->answer = BADADDR;
  82.         return;
  83.     }
  84.     mp->ctl_addr.sa_family = ntohs(mp->ctl_addr.sa_family);
  85.     if (mp->ctl_addr.sa_family != AF_INET) {
  86.         syslog(LOG_WARNING, "Bad control address, family %d",
  87.             mp->ctl_addr.sa_family);
  88.         rp->answer = BADCTLADDR;
  89.         return;
  90.     }
  91.     mp->pid = ntohl(mp->pid);
  92.     if (debug)
  93.         print_request("process_request", mp);
  94.     switch (mp->type) {
  95.  
  96.     case ANNOUNCE:
  97.         do_announce(mp, rp);
  98.         break;
  99.  
  100.     case LEAVE_INVITE:
  101.         ptr = find_request(mp);
  102.         if (ptr != (CTL_MSG *)0) {
  103.             rp->id_num = htonl(ptr->id_num);
  104.             rp->answer = SUCCESS;
  105.         } else
  106.             insert_table(mp, rp);
  107.         break;
  108.  
  109.     case LOOK_UP:
  110.         ptr = find_match(mp);
  111.         if (ptr != (CTL_MSG *)0) {
  112.             rp->id_num = htonl(ptr->id_num);
  113.             rp->addr = ptr->addr;
  114.             rp->addr.sa_family = htons(ptr->addr.sa_family);
  115.             rp->answer = SUCCESS;
  116.         } else
  117.             rp->answer = NOT_HERE;
  118.         break;
  119.  
  120.     case DELETE:
  121.         rp->answer = delete_invite(mp->id_num);
  122.         break;
  123.  
  124.     default:
  125.         rp->answer = UNKNOWN_REQUEST;
  126.         break;
  127.     }
  128.     if (debug)
  129.         print_response("process_request", rp);
  130. }
  131.  
  132. do_announce(mp, rp)
  133.     register CTL_MSG *mp;
  134.     CTL_RESPONSE *rp;
  135. {
  136.     struct hostent *hp;
  137.     CTL_MSG *ptr;
  138.     int result;
  139.  
  140.     /* see if the user is logged */
  141.     result = find_user(mp->r_name, mp->r_tty);
  142.     if (result != SUCCESS) {
  143.         rp->answer = result;
  144.         return;
  145.     }
  146. #define    satosin(sa)    ((struct sockaddr_in *)(sa))
  147.     hp = gethostbyaddr((char *)&satosin(&mp->ctl_addr)->sin_addr,
  148.         sizeof (struct in_addr), AF_INET);
  149.     if (hp == (struct hostent *)0) {
  150.         rp->answer = MACHINE_UNKNOWN;
  151.         return;
  152.     }
  153.     ptr = find_request(mp);
  154.     if (ptr == (CTL_MSG *) 0) {
  155.         insert_table(mp, rp);
  156.         rp->answer = announce(mp, hp->h_name);
  157.         return;
  158.     }
  159.     if (mp->id_num > ptr->id_num) {
  160.         /*
  161.          * This is an explicit re-announce, so update the id_num
  162.          * field to avoid duplicates and re-announce the talk.
  163.          */
  164.         ptr->id_num = new_id();
  165.         rp->id_num = htonl(ptr->id_num);
  166.         rp->answer = announce(mp, hp->h_name);
  167.     } else {
  168.         /* a duplicated request, so ignore it */
  169.         rp->id_num = htonl(ptr->id_num);
  170.         rp->answer = SUCCESS;
  171.     }
  172. }
  173.  
  174. #include <utmp.h>
  175.  
  176. /*
  177.  * Search utmp for the local user
  178.  */
  179. find_user(name, tty)
  180.     char *name, *tty;
  181. {
  182.     struct utmp ubuf;
  183.     int status;
  184.     FILE *fd;
  185.     struct stat statb;
  186.     char ftty[20];
  187.  
  188.     if ((fd = fopen(_PATH_UTMP, "r")) == NULL) {
  189.         fprintf(stderr, "talkd: can't read %s.\n", _PATH_UTMP);
  190.         return (FAILED);
  191.     }
  192. #define SCMPN(a, b)    strncmp(a, b, sizeof (a))
  193.     status = NOT_HERE;
  194.     (void) strcpy(ftty, _PATH_DEV);
  195.     while (fread((char *) &ubuf, sizeof ubuf, 1, fd) == 1)
  196.         if (SCMPN(ubuf.ut_name, name) == 0) {
  197.             if (*tty == '\0') {
  198.                 status = PERMISSION_DENIED;
  199.                 /* no particular tty was requested */
  200.                 (void) strcpy(ftty+5, ubuf.ut_line);
  201.                 if (stat(ftty,&statb) == 0) {
  202.                     if (!(statb.st_mode & 020))
  203.                         continue;
  204.                     (void) strcpy(tty, ubuf.ut_line);
  205.                     status = SUCCESS;
  206.                     break;
  207.                 }
  208.             }
  209.             if (strcmp(ubuf.ut_line, tty) == 0) {
  210.                 status = SUCCESS;
  211.                 break;
  212.             }
  213.         }
  214.     fclose(fd);
  215.     return (status);
  216. }
  217.