1*22774Smckusick /* 2*22774Smckusick * Copyright (c) 1983 Regents of the University of California. 3*22774Smckusick * All rights reserved. The Berkeley software License Agreement 4*22774Smckusick * specifies the terms and conditions for redistribution. 5*22774Smckusick */ 6*22774Smckusick 716365Skarels #ifndef lint 8*22774Smckusick static char sccsid[] = "@(#)process.c 5.1 (Berkeley) 06/07/85"; 9*22774Smckusick #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 */ 1916365Skarels #include "ctl.h" 2017560Sbloom #include <sys/stat.h> 2116355Skarels 2216355Skarels char *strcpy(); 2316355Skarels CTL_MSG *find_request(); 2416355Skarels CTL_MSG *find_match(); 2516355Skarels 2616355Skarels process_request(request, response) 2716365Skarels CTL_MSG *request; 2816365Skarels CTL_RESPONSE *response; 2916355Skarels { 3016365Skarels CTL_MSG *ptr; 3116355Skarels 3216365Skarels response->type = request->type; 3316365Skarels response->id_num = 0; 3416355Skarels 3516365Skarels switch (request->type) { 3616355Skarels 3716355Skarels case ANNOUNCE : 3816365Skarels do_announce(request, response); 3916365Skarels break; 4016355Skarels 4116355Skarels case LEAVE_INVITE : 4216365Skarels ptr = find_request(request); 4316365Skarels if (ptr != (CTL_MSG *) 0) { 4416365Skarels response->id_num = ptr->id_num; 4516365Skarels response->answer = SUCCESS; 4616365Skarels } else 4716365Skarels insert_table(request, response); 4816365Skarels break; 4916355Skarels 5016355Skarels case LOOK_UP : 5116365Skarels ptr = find_match(request); 5216365Skarels if (ptr != (CTL_MSG *) 0) { 5316365Skarels response->id_num = ptr->id_num; 5416365Skarels response->addr = ptr->addr; 5516365Skarels response->answer = SUCCESS; 5616365Skarels } else 5716365Skarels response->answer = NOT_HERE; 5816365Skarels break; 5916355Skarels 6016355Skarels case DELETE : 6116365Skarels response->answer = delete_invite(request->id_num); 6216365Skarels break; 6316355Skarels 6416355Skarels default : 6516365Skarels response->answer = UNKNOWN_REQUEST; 6616365Skarels break; 6716365Skarels } 6816355Skarels } 6916355Skarels 7016355Skarels struct hostent *gethostbyaddr(); 7116355Skarels 7216355Skarels do_announce(request, response) 7316365Skarels CTL_MSG *request; 7416365Skarels CTL_RESPONSE *response; 7516355Skarels { 7616365Skarels struct hostent *hp; 7716365Skarels CTL_MSG *ptr; 7816365Skarels int result; 7916355Skarels 8016355Skarels /* see if the user is logged */ 8116365Skarels result = find_user(request->r_name, request->r_tty); 8216365Skarels if (result != SUCCESS) { 8316365Skarels response->answer = result; 8416365Skarels return; 8516365Skarels } 8616365Skarels hp = gethostbyaddr(&request->ctl_addr.sin_addr, 8716365Skarels sizeof(struct in_addr), AF_INET); 8816365Skarels if (hp == (struct hostent *)0) { 8916365Skarels response->answer = MACHINE_UNKNOWN; 9016365Skarels return; 9116365Skarels } 9216365Skarels ptr = find_request(request); 9316365Skarels if (ptr == (CTL_MSG *) 0) { 9416365Skarels insert_table(request,response); 9516365Skarels response->answer = announce(request, hp->h_name); 9616365Skarels return; 9716365Skarels } 9816365Skarels if (request->id_num > ptr->id_num) { 9916365Skarels /* 10016365Skarels * this is an explicit re-announce, so update the id_num 10116365Skarels * field to avoid duplicates and re-announce the talk 10216365Skarels */ 10316365Skarels ptr->id_num = response->id_num = new_id(); 10416365Skarels response->answer = announce(request, hp->h_name); 10516365Skarels return; 10616365Skarels } 10716365Skarels /* a duplicated request, so ignore it */ 10816355Skarels response->id_num = ptr->id_num; 10916355Skarels response->answer = SUCCESS; 11016355Skarels } 11116355Skarels 11216355Skarels #include <utmp.h> 11316355Skarels 11416355Skarels /* 11516355Skarels * Search utmp for the local user 11616355Skarels */ 11716355Skarels find_user(name, tty) 11816365Skarels char *name; 11916365Skarels char *tty; 12016355Skarels { 12116365Skarels struct utmp ubuf; 12216365Skarels int fd, status; 12317560Sbloom struct stat statb; 12417560Sbloom char ftty[20]; 12516355Skarels 12616365Skarels if ((fd = open("/etc/utmp", 0)) == -1) { 12716365Skarels perror("Can't open /etc/utmp"); 12816365Skarels return (FAILED); 12916355Skarels } 13016365Skarels #define SCMPN(a, b) strncmp(a, b, sizeof (a)) 13116365Skarels status = NOT_HERE; 13217560Sbloom (void) strcpy(ftty, "/dev/"); 13316365Skarels while (read(fd, (char *) &ubuf, sizeof ubuf) == sizeof(ubuf)) 13416365Skarels if (SCMPN(ubuf.ut_name, name) == 0) { 13516365Skarels if (*tty == '\0') { 13617560Sbloom status = PERMISSION_DENIED; 13716365Skarels /* no particular tty was requested */ 13817560Sbloom (void) strcpy(ftty+5, ubuf.ut_line); 13917560Sbloom if (stat(ftty,&statb) == 0) { 14017560Sbloom if (!(statb.st_mode & 02)) 14117560Sbloom continue; 14217560Sbloom (void) strcpy(tty, ubuf.ut_line); 14317560Sbloom status = SUCCESS; 14417560Sbloom break; 14517560Sbloom } 14616365Skarels } 14716365Skarels if (strcmp(ubuf.ut_line, tty) == 0) { 14816365Skarels status = SUCCESS; 14916365Skarels break; 15016365Skarels } 15116365Skarels } 15216365Skarels close(fd); 15316365Skarels return (status); 15416355Skarels } 155