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