122774Smckusick /* 222774Smckusick * Copyright (c) 1983 Regents of the University of California. 322774Smckusick * All rights reserved. The Berkeley software License Agreement 422774Smckusick * specifies the terms and conditions for redistribution. 522774Smckusick */ 622774Smckusick 716365Skarels #ifndef lint 8*26839Smckusick static char sccsid[] = "@(#)process.c 5.3 (Berkeley) 03/13/86"; 922774Smckusick #endif not lint 1016355Skarels 1116365Skarels /* 1216365Skarels * process.c handles the requests, which can be of three types: 1316365Skarels * ANNOUNCE - announce to a user that a talk is wanted 1416365Skarels * LEAVE_INVITE - insert the request into the table 1516365Skarels * LOOK_UP - look up to see if a request is waiting in 1616365Skarels * in the table for the local user 1716365Skarels * DELETE - delete invitation 1816365Skarels */ 19*26839Smckusick #include <sys/types.h> 2017560Sbloom #include <sys/stat.h> 2123462Sbloom #include <stdio.h> 22*26839Smckusick #include <syslog.h> 23*26839Smckusick #include <netdb.h> 24*26839Smckusick #include <netinet/in.h> 2516355Skarels 26*26839Smckusick #include <protocols/talkd.h> 27*26839Smckusick 28*26839Smckusick char *strcpy(); 2916355Skarels CTL_MSG *find_request(); 3016355Skarels CTL_MSG *find_match(); 3116355Skarels 32*26839Smckusick process_request(mp, rp) 33*26839Smckusick register CTL_MSG *mp; 34*26839Smckusick register CTL_RESPONSE *rp; 3516355Skarels { 36*26839Smckusick register CTL_MSG *ptr; 37*26839Smckusick extern int debug; 3816355Skarels 39*26839Smckusick rp->vers = TALK_VERSION; 40*26839Smckusick rp->type = mp->type; 41*26839Smckusick rp->id_num = htonl(0); 42*26839Smckusick if (mp->vers != TALK_VERSION) { 43*26839Smckusick syslog(LOG_WARNING, "Bad protocol version %d", mp->vers); 44*26839Smckusick rp->answer = BADVERSION; 45*26839Smckusick return; 46*26839Smckusick } 47*26839Smckusick mp->id_num = ntohl(mp->id_num); 48*26839Smckusick mp->addr.sa_family = ntohs(mp->addr.sa_family); 49*26839Smckusick if (mp->addr.sa_family != AF_INET) { 50*26839Smckusick syslog(LOG_WARNING, "Bad address, family %d", 51*26839Smckusick mp->addr.sa_family); 52*26839Smckusick rp->answer = BADADDR; 53*26839Smckusick return; 54*26839Smckusick } 55*26839Smckusick mp->ctl_addr.sa_family = ntohs(mp->ctl_addr.sa_family); 56*26839Smckusick if (mp->ctl_addr.sa_family != AF_INET) { 57*26839Smckusick syslog(LOG_WARNING, "Bad control address, family %d", 58*26839Smckusick mp->ctl_addr.sa_family); 59*26839Smckusick rp->answer = BADCTLADDR; 60*26839Smckusick return; 61*26839Smckusick } 62*26839Smckusick mp->pid = ntohl(mp->pid); 63*26839Smckusick if (debug) 64*26839Smckusick print_request("process_request", mp); 65*26839Smckusick switch (mp->type) { 6616355Skarels 67*26839Smckusick case ANNOUNCE: 68*26839Smckusick do_announce(mp, rp); 6916365Skarels break; 7016355Skarels 71*26839Smckusick case LEAVE_INVITE: 72*26839Smckusick ptr = find_request(mp); 73*26839Smckusick if (ptr != (CTL_MSG *)0) { 74*26839Smckusick rp->id_num = htonl(ptr->id_num); 75*26839Smckusick rp->answer = SUCCESS; 7616365Skarels } else 77*26839Smckusick insert_table(mp, rp); 7816365Skarels break; 7916355Skarels 80*26839Smckusick case LOOK_UP: 81*26839Smckusick ptr = find_match(mp); 82*26839Smckusick if (ptr != (CTL_MSG *)0) { 83*26839Smckusick rp->id_num = htonl(ptr->id_num); 84*26839Smckusick rp->addr = ptr->addr; 85*26839Smckusick rp->addr.sa_family = htons(ptr->addr.sa_family); 86*26839Smckusick rp->answer = SUCCESS; 8716365Skarels } else 88*26839Smckusick rp->answer = NOT_HERE; 8916365Skarels break; 9016355Skarels 91*26839Smckusick case DELETE: 92*26839Smckusick rp->answer = delete_invite(mp->id_num); 9316365Skarels break; 9416355Skarels 95*26839Smckusick default: 96*26839Smckusick rp->answer = UNKNOWN_REQUEST; 9716365Skarels break; 9816365Skarels } 99*26839Smckusick if (debug) 100*26839Smckusick print_response("process_request", rp); 10116355Skarels } 10216355Skarels 103*26839Smckusick do_announce(mp, rp) 104*26839Smckusick register CTL_MSG *mp; 105*26839Smckusick CTL_RESPONSE *rp; 10616355Skarels { 10716365Skarels struct hostent *hp; 10816365Skarels CTL_MSG *ptr; 10916365Skarels int result; 11016355Skarels 11116355Skarels /* see if the user is logged */ 112*26839Smckusick result = find_user(mp->r_name, mp->r_tty); 11316365Skarels if (result != SUCCESS) { 114*26839Smckusick rp->answer = result; 11516365Skarels return; 11616365Skarels } 117*26839Smckusick #define satosin(sa) ((struct sockaddr_in *)(sa)) 118*26839Smckusick hp = gethostbyaddr(&satosin(&mp->ctl_addr)->sin_addr, 119*26839Smckusick sizeof (struct in_addr), AF_INET); 12016365Skarels if (hp == (struct hostent *)0) { 121*26839Smckusick rp->answer = MACHINE_UNKNOWN; 12216365Skarels return; 12316365Skarels } 124*26839Smckusick ptr = find_request(mp); 12516365Skarels if (ptr == (CTL_MSG *) 0) { 126*26839Smckusick insert_table(mp, rp); 127*26839Smckusick rp->answer = announce(mp, hp->h_name); 12816365Skarels return; 12916365Skarels } 130*26839Smckusick if (mp->id_num > ptr->id_num) { 13116365Skarels /* 132*26839Smckusick * This is an explicit re-announce, so update the id_num 133*26839Smckusick * field to avoid duplicates and re-announce the talk. 13416365Skarels */ 135*26839Smckusick ptr->id_num = new_id(); 136*26839Smckusick rp->id_num = htonl(ptr->id_num); 137*26839Smckusick rp->answer = announce(mp, hp->h_name); 138*26839Smckusick } else { 139*26839Smckusick /* a duplicated request, so ignore it */ 140*26839Smckusick rp->id_num = htonl(ptr->id_num); 141*26839Smckusick rp->answer = SUCCESS; 14216365Skarels } 14316355Skarels } 14416355Skarels 14516355Skarels #include <utmp.h> 14616355Skarels 14716355Skarels /* 14816355Skarels * Search utmp for the local user 14916355Skarels */ 15016355Skarels find_user(name, tty) 151*26839Smckusick char *name, *tty; 15216355Skarels { 15316365Skarels struct utmp ubuf; 15423462Sbloom int status; 15523462Sbloom FILE *fd; 15617560Sbloom struct stat statb; 15717560Sbloom char ftty[20]; 15816355Skarels 15923462Sbloom if ((fd = fopen("/etc/utmp", "r")) == NULL) { 16016365Skarels perror("Can't open /etc/utmp"); 16116365Skarels return (FAILED); 16216355Skarels } 16316365Skarels #define SCMPN(a, b) strncmp(a, b, sizeof (a)) 16416365Skarels status = NOT_HERE; 16517560Sbloom (void) strcpy(ftty, "/dev/"); 16623462Sbloom while (fread((char *) &ubuf, sizeof ubuf, 1, fd) == 1) 16716365Skarels if (SCMPN(ubuf.ut_name, name) == 0) { 16816365Skarels if (*tty == '\0') { 16917560Sbloom status = PERMISSION_DENIED; 17016365Skarels /* no particular tty was requested */ 17117560Sbloom (void) strcpy(ftty+5, ubuf.ut_line); 17217560Sbloom if (stat(ftty,&statb) == 0) { 17317560Sbloom if (!(statb.st_mode & 02)) 17417560Sbloom continue; 17517560Sbloom (void) strcpy(tty, ubuf.ut_line); 17617560Sbloom status = SUCCESS; 17717560Sbloom break; 17817560Sbloom } 17916365Skarels } 18016365Skarels if (strcmp(ubuf.ut_line, tty) == 0) { 18116365Skarels status = SUCCESS; 18216365Skarels break; 18316365Skarels } 18416365Skarels } 18523462Sbloom fclose(fd); 18616365Skarels return (status); 18716355Skarels } 188