process.c revision 3793
111819Sjulian/* 211819Sjulian * Copyright (c) 1983, 1993 311819Sjulian * The Regents of the University of California. All rights reserved. 411819Sjulian * 511819Sjulian * Redistribution and use in source and binary forms, with or without 611819Sjulian * modification, are permitted provided that the following conditions 711819Sjulian * are met: 811819Sjulian * 1. Redistributions of source code must retain the above copyright 911819Sjulian * notice, this list of conditions and the following disclaimer. 1011819Sjulian * 2. Redistributions in binary form must reproduce the above copyright 1111819Sjulian * notice, this list of conditions and the following disclaimer in the 1211819Sjulian * documentation and/or other materials provided with the distribution. 1311819Sjulian * 3. All advertising materials mentioning features or use of this software 1411819Sjulian * must display the following acknowledgement: 1511819Sjulian * This product includes software developed by the University of 1611819Sjulian * California, Berkeley and its contributors. 1711819Sjulian * 4. Neither the name of the University nor the names of its contributors 1811819Sjulian * may be used to endorse or promote products derived from this software 1911819Sjulian * without specific prior written permission. 2011819Sjulian * 2111819Sjulian * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2211819Sjulian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2311819Sjulian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2411819Sjulian * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2511819Sjulian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2611819Sjulian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2711819Sjulian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2811819Sjulian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2911819Sjulian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3011819Sjulian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3111819Sjulian * SUCH DAMAGE. 3211819Sjulian */ 3311819Sjulian 3412057Sjulian#ifndef lint 3511819Sjulianstatic char sccsid[] = "@(#)process.c 8.2 (Berkeley) 11/16/93"; 3611819Sjulian#endif /* not lint */ 37116189Sobrien 38116189Sobrien/* 39116189Sobrien * process.c handles the requests, which can be of three types: 4031742Seivind * ANNOUNCE - announce to a user that a talk is wanted 4131742Seivind * LEAVE_INVITE - insert the request into the table 4211819Sjulian * LOOK_UP - look up to see if a request is waiting in 4319947Sjhay * in the table for the local user 4495759Stanimura * DELETE - delete invitation 4511819Sjulian */ 4611819Sjulian#include <sys/param.h> 4795759Stanimura#include <sys/stat.h> 4811819Sjulian#include <sys/socket.h> 4911819Sjulian#include <netinet/in.h> 5095759Stanimura#include <protocols/talkd.h> 5119947Sjhay#include <netdb.h> 5295759Stanimura#include <syslog.h> 5311819Sjulian#include <stdio.h> 5411819Sjulian#include <string.h> 5511819Sjulian#include <ctype.h> 5611819Sjulian#include <paths.h> 5711947Sjulian 5811947SjulianCTL_MSG *find_request(); 5911819SjulianCTL_MSG *find_match(); 6095759Stanimura 6195759Stanimuraprocess_request(mp, rp) 6211819Sjulian register CTL_MSG *mp; 6311819Sjulian register CTL_RESPONSE *rp; 6411819Sjulian{ 6511819Sjulian register CTL_MSG *ptr; 6611819Sjulian extern int debug; 6711819Sjulian char *s; 6811819Sjulian 6933181Seivind rp->vers = TALK_VERSION; 7019947Sjhay rp->type = mp->type; 7119947Sjhay rp->id_num = htonl(0); 7233181Seivind if (mp->vers != TALK_VERSION) { 7319947Sjhay syslog(LOG_WARNING, "Bad protocol version %d", mp->vers); 7419947Sjhay rp->answer = BADVERSION; 7519947Sjhay return; 7624659Sjhay } 7783366Sjulian mp->id_num = ntohl(mp->id_num); 7883366Sjulian mp->addr.sa_family = ntohs(mp->addr.sa_family); 7928270Swollman if (mp->addr.sa_family != AF_INET) { 8083366Sjulian syslog(LOG_WARNING, "Bad address, family %d", 8124659Sjhay mp->addr.sa_family); 8224659Sjhay rp->answer = BADADDR; 8324659Sjhay return; 8428270Swollman } 8583366Sjulian mp->ctl_addr.sa_family = ntohs(mp->ctl_addr.sa_family); 8624659Sjhay if (mp->ctl_addr.sa_family != AF_INET) { 8783366Sjulian syslog(LOG_WARNING, "Bad control address, family %d", 8825652Sjhay mp->ctl_addr.sa_family); 8924659Sjhay rp->answer = BADCTLADDR; 9025652Sjhay return; 91137386Sphk } 92137386Sphk for (s = mp->l_name; *s; s++) 93137386Sphk if (!isprint(*s)) { 94137386Sphk syslog(LOG_NOTICE, "Illegal user name. Aborting"); 95137386Sphk rp->answer = FAILED; 96137386Sphk return; 97137386Sphk } 98137386Sphk mp->pid = ntohl(mp->pid); 99137386Sphk if (debug) 100137386Sphk print_request("process_request", mp); 101137386Sphk switch (mp->type) { 10224659Sjhay 10324659Sjhay case ANNOUNCE: 10425652Sjhay do_announce(mp, rp); 105137386Sphk break; 106137386Sphk 107137386Sphk case LEAVE_INVITE: 108137386Sphk ptr = find_request(mp); 109137386Sphk if (ptr != (CTL_MSG *)0) { 110137386Sphk rp->id_num = htonl(ptr->id_num); 111137386Sphk rp->answer = SUCCESS; 112137386Sphk } else 113137386Sphk insert_table(mp, rp); 114137386Sphk break; 115137386Sphk 11624659Sjhay case LOOK_UP: 11724659Sjhay ptr = find_match(mp); 11811819Sjulian if (ptr != (CTL_MSG *)0) { 11911819Sjulian rp->id_num = htonl(ptr->id_num); 12011819Sjulian rp->addr = ptr->addr; 12111819Sjulian rp->addr.sa_family = htons(ptr->addr.sa_family); 12211819Sjulian rp->answer = SUCCESS; 12311819Sjulian } else 12411819Sjulian rp->answer = NOT_HERE; 12511819Sjulian break; 12611819Sjulian 12711819Sjulian case DELETE: 12815245Sjhay rp->answer = delete_invite(mp->id_num); 12911819Sjulian break; 13025652Sjhay 13111819Sjulian default: 13211819Sjulian rp->answer = UNKNOWN_REQUEST; 13311819Sjulian break; 13411819Sjulian } 13511819Sjulian if (debug) 13615245Sjhay print_response("process_request", rp); 13715245Sjhay} 13811819Sjulian 13915245Sjhaydo_announce(mp, rp) 14015245Sjhay register CTL_MSG *mp; 14125652Sjhay CTL_RESPONSE *rp; 14211819Sjulian{ 14311819Sjulian struct hostent *hp; 14471999Sphk CTL_MSG *ptr; 14571999Sphk int result; 14611819Sjulian 14711819Sjulian /* see if the user is logged */ 14811819Sjulian result = find_user(mp->r_name, mp->r_tty); 14911819Sjulian if (result != SUCCESS) { 15011819Sjulian rp->answer = result; 15111819Sjulian return; 15211819Sjulian } 15311819Sjulian#define satosin(sa) ((struct sockaddr_in *)(sa)) 15425652Sjhay hp = gethostbyaddr((char *)&satosin(&mp->ctl_addr)->sin_addr, 15525652Sjhay sizeof (struct in_addr), AF_INET); 15625652Sjhay if (hp == (struct hostent *)0) { 15725652Sjhay rp->answer = MACHINE_UNKNOWN; 15811819Sjulian return; 15911819Sjulian } 16025652Sjhay ptr = find_request(mp); 16111819Sjulian if (ptr == (CTL_MSG *) 0) { 16211819Sjulian insert_table(mp, rp); 16311819Sjulian rp->answer = announce(mp, hp->h_name); 16411819Sjulian return; 16511819Sjulian } 16611819Sjulian if (mp->id_num > ptr->id_num) { 16711819Sjulian /* 16811819Sjulian * This is an explicit re-announce, so update the id_num 16911819Sjulian * field to avoid duplicates and re-announce the talk. 17011819Sjulian */ 17111819Sjulian ptr->id_num = new_id(); 17211819Sjulian rp->id_num = htonl(ptr->id_num); 17311819Sjulian rp->answer = announce(mp, hp->h_name); 17411819Sjulian } else { 17511819Sjulian /* a duplicated request, so ignore it */ 17611819Sjulian rp->id_num = htonl(ptr->id_num); 17725652Sjhay rp->answer = SUCCESS; 17811819Sjulian } 17911819Sjulian} 18011819Sjulian 18111819Sjulian#include <utmp.h> 18211819Sjulian 18311819Sjulian/* 18411819Sjulian * Search utmp for the local user 18511819Sjulian */ 18611819Sjulianfind_user(name, tty) 18711819Sjulian char *name, *tty; 18811819Sjulian{ 18911819Sjulian struct utmp ubuf; 19025652Sjhay int status; 19111819Sjulian FILE *fd; 19211819Sjulian struct stat statb; 19325652Sjhay char line[sizeof(ubuf.ut_line) + 1]; 19425652Sjhay char ftty[sizeof(_PATH_DEV) - 1 + sizeof(line)]; 19511819Sjulian 19611819Sjulian if ((fd = fopen(_PATH_UTMP, "r")) == NULL) { 19711819Sjulian fprintf(stderr, "talkd: can't read %s.\n", _PATH_UTMP); 19825652Sjhay return (FAILED); 19911819Sjulian } 20011819Sjulian#define SCMPN(a, b) strncmp(a, b, sizeof (a)) 20111819Sjulian status = NOT_HERE; 20211819Sjulian (void) strcpy(ftty, _PATH_DEV); 20311819Sjulian while (fread((char *) &ubuf, sizeof ubuf, 1, fd) == 1) 20411819Sjulian if (SCMPN(ubuf.ut_name, name) == 0) { 20525652Sjhay strncpy(line, ubuf.ut_line, sizeof(ubuf.ut_line)); 20611819Sjulian line[sizeof(ubuf.ut_line)] = '\0'; 20711819Sjulian if (*tty == '\0') { 20811819Sjulian status = PERMISSION_DENIED; 20911819Sjulian /* no particular tty was requested */ 21011819Sjulian (void) strcpy(ftty + sizeof(_PATH_DEV) - 1, 21111819Sjulian line); 21211819Sjulian if (stat(ftty, &statb) == 0) { 21311819Sjulian if (!(statb.st_mode & 020)) 21454799Sgreen continue; 21511819Sjulian (void) strcpy(tty, line); 21611819Sjulian status = SUCCESS; 21711819Sjulian break; 21811819Sjulian } 21911819Sjulian } 22025652Sjhay if (strcmp(line, tty) == 0) { 22111819Sjulian status = SUCCESS; 22211819Sjulian break; 22311819Sjulian } 22411819Sjulian } 22511819Sjulian fclose(fd); 22611819Sjulian return (status); 22711819Sjulian} 22811819Sjulian