122774Smckusick /* 222774Smckusick * Copyright (c) 1983 Regents of the University of California. 334360Sbostic * All rights reserved. 434360Sbostic * 542673Sbostic * %sccs.include.redist.c% 622774Smckusick */ 722774Smckusick 816365Skarels #ifndef lint 9*46683Sbostic static char sccsid[] = "@(#)process.c 5.10 (Berkeley) 02/26/91"; 1034360Sbostic #endif /* not lint */ 1116355Skarels 1216365Skarels /* 1316365Skarels * process.c handles the requests, which can be of three types: 1416365Skarels * ANNOUNCE - announce to a user that a talk is wanted 1516365Skarels * LEAVE_INVITE - insert the request into the table 1616365Skarels * LOOK_UP - look up to see if a request is waiting in 1716365Skarels * in the table for the local user 1816365Skarels * DELETE - delete invitation 1916365Skarels */ 20*46683Sbostic #include <sys/param.h> 2117560Sbloom #include <sys/stat.h> 22*46683Sbostic #include <sys/socket.h> 2326839Smckusick #include <netinet/in.h> 2426839Smckusick #include <protocols/talkd.h> 25*46683Sbostic #include <netdb.h> 26*46683Sbostic #include <syslog.h> 27*46683Sbostic #include <stdio.h> 28*46683Sbostic #include <string.h> 2937991Sbostic #include <paths.h> 3026839Smckusick 3116355Skarels CTL_MSG *find_request(); 3216355Skarels CTL_MSG *find_match(); 3316355Skarels 3426839Smckusick process_request(mp, rp) 3526839Smckusick register CTL_MSG *mp; 3626839Smckusick register CTL_RESPONSE *rp; 3716355Skarels { 3826839Smckusick register CTL_MSG *ptr; 3926839Smckusick extern int debug; 4016355Skarels 4126839Smckusick rp->vers = TALK_VERSION; 4226839Smckusick rp->type = mp->type; 4326839Smckusick rp->id_num = htonl(0); 4426839Smckusick if (mp->vers != TALK_VERSION) { 4526839Smckusick syslog(LOG_WARNING, "Bad protocol version %d", mp->vers); 4626839Smckusick rp->answer = BADVERSION; 4726839Smckusick return; 4826839Smckusick } 4926839Smckusick mp->id_num = ntohl(mp->id_num); 5026839Smckusick mp->addr.sa_family = ntohs(mp->addr.sa_family); 5126839Smckusick if (mp->addr.sa_family != AF_INET) { 5226839Smckusick syslog(LOG_WARNING, "Bad address, family %d", 5326839Smckusick mp->addr.sa_family); 5426839Smckusick rp->answer = BADADDR; 5526839Smckusick return; 5626839Smckusick } 5726839Smckusick mp->ctl_addr.sa_family = ntohs(mp->ctl_addr.sa_family); 5826839Smckusick if (mp->ctl_addr.sa_family != AF_INET) { 5926839Smckusick syslog(LOG_WARNING, "Bad control address, family %d", 6026839Smckusick mp->ctl_addr.sa_family); 6126839Smckusick rp->answer = BADCTLADDR; 6226839Smckusick return; 6326839Smckusick } 6426839Smckusick mp->pid = ntohl(mp->pid); 6526839Smckusick if (debug) 6626839Smckusick print_request("process_request", mp); 6726839Smckusick switch (mp->type) { 6816355Skarels 6926839Smckusick case ANNOUNCE: 7026839Smckusick do_announce(mp, rp); 7116365Skarels break; 7216355Skarels 7326839Smckusick case LEAVE_INVITE: 7426839Smckusick ptr = find_request(mp); 7526839Smckusick if (ptr != (CTL_MSG *)0) { 7626839Smckusick rp->id_num = htonl(ptr->id_num); 7726839Smckusick rp->answer = SUCCESS; 7816365Skarels } else 7926839Smckusick insert_table(mp, rp); 8016365Skarels break; 8116355Skarels 8226839Smckusick case LOOK_UP: 8326839Smckusick ptr = find_match(mp); 8426839Smckusick if (ptr != (CTL_MSG *)0) { 8526839Smckusick rp->id_num = htonl(ptr->id_num); 8626839Smckusick rp->addr = ptr->addr; 8726839Smckusick rp->addr.sa_family = htons(ptr->addr.sa_family); 8826839Smckusick rp->answer = SUCCESS; 8916365Skarels } else 9026839Smckusick rp->answer = NOT_HERE; 9116365Skarels break; 9216355Skarels 9326839Smckusick case DELETE: 9426839Smckusick rp->answer = delete_invite(mp->id_num); 9516365Skarels break; 9616355Skarels 9726839Smckusick default: 9826839Smckusick rp->answer = UNKNOWN_REQUEST; 9916365Skarels break; 10016365Skarels } 10126839Smckusick if (debug) 10226839Smckusick print_response("process_request", rp); 10316355Skarels } 10416355Skarels 10526839Smckusick do_announce(mp, rp) 10626839Smckusick register CTL_MSG *mp; 10726839Smckusick CTL_RESPONSE *rp; 10816355Skarels { 10916365Skarels struct hostent *hp; 11016365Skarels CTL_MSG *ptr; 11116365Skarels int result; 11216355Skarels 11316355Skarels /* see if the user is logged */ 11426839Smckusick result = find_user(mp->r_name, mp->r_tty); 11516365Skarels if (result != SUCCESS) { 11626839Smckusick rp->answer = result; 11716365Skarels return; 11816365Skarels } 11926839Smckusick #define satosin(sa) ((struct sockaddr_in *)(sa)) 120*46683Sbostic hp = gethostbyaddr((char *)&satosin(&mp->ctl_addr)->sin_addr, 12126839Smckusick sizeof (struct in_addr), AF_INET); 12216365Skarels if (hp == (struct hostent *)0) { 12326839Smckusick rp->answer = MACHINE_UNKNOWN; 12416365Skarels return; 12516365Skarels } 12626839Smckusick ptr = find_request(mp); 12716365Skarels if (ptr == (CTL_MSG *) 0) { 12826839Smckusick insert_table(mp, rp); 12926839Smckusick rp->answer = announce(mp, hp->h_name); 13016365Skarels return; 13116365Skarels } 13226839Smckusick if (mp->id_num > ptr->id_num) { 13316365Skarels /* 13426839Smckusick * This is an explicit re-announce, so update the id_num 13526839Smckusick * field to avoid duplicates and re-announce the talk. 13616365Skarels */ 13726839Smckusick ptr->id_num = new_id(); 13826839Smckusick rp->id_num = htonl(ptr->id_num); 13926839Smckusick rp->answer = announce(mp, hp->h_name); 14026839Smckusick } else { 14126839Smckusick /* a duplicated request, so ignore it */ 14226839Smckusick rp->id_num = htonl(ptr->id_num); 14326839Smckusick rp->answer = SUCCESS; 14416365Skarels } 14516355Skarels } 14616355Skarels 14716355Skarels #include <utmp.h> 14816355Skarels 14916355Skarels /* 15016355Skarels * Search utmp for the local user 15116355Skarels */ 15216355Skarels find_user(name, tty) 15326839Smckusick char *name, *tty; 15416355Skarels { 15516365Skarels struct utmp ubuf; 15623462Sbloom int status; 15723462Sbloom FILE *fd; 15817560Sbloom struct stat statb; 15917560Sbloom char ftty[20]; 16016355Skarels 16137303Sbostic if ((fd = fopen(_PATH_UTMP, "r")) == NULL) { 16237303Sbostic fprintf(stderr, "talkd: can't read %s.\n", _PATH_UTMP); 16316365Skarels return (FAILED); 16416355Skarels } 16516365Skarels #define SCMPN(a, b) strncmp(a, b, sizeof (a)) 16616365Skarels status = NOT_HERE; 16737991Sbostic (void) strcpy(ftty, _PATH_DEV); 16823462Sbloom while (fread((char *) &ubuf, sizeof ubuf, 1, fd) == 1) 16916365Skarels if (SCMPN(ubuf.ut_name, name) == 0) { 17016365Skarels if (*tty == '\0') { 17117560Sbloom status = PERMISSION_DENIED; 17216365Skarels /* no particular tty was requested */ 17317560Sbloom (void) strcpy(ftty+5, ubuf.ut_line); 17417560Sbloom if (stat(ftty,&statb) == 0) { 17526854Smckusick if (!(statb.st_mode & 020)) 17617560Sbloom continue; 17717560Sbloom (void) strcpy(tty, ubuf.ut_line); 17817560Sbloom status = SUCCESS; 17917560Sbloom break; 18017560Sbloom } 18116365Skarels } 18216365Skarels if (strcmp(ubuf.ut_line, tty) == 0) { 18316365Skarels status = SUCCESS; 18416365Skarels break; 18516365Skarels } 18616365Skarels } 18723462Sbloom fclose(fd); 18816365Skarels return (status); 18916355Skarels } 190