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*23462Sbloom static char sccsid[] = "@(#)process.c 5.2 (Berkeley) 06/08/85"; 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 */ 1916365Skarels #include "ctl.h" 2017560Sbloom #include <sys/stat.h> 21*23462Sbloom #include <stdio.h> 2216355Skarels 2316355Skarels char *strcpy(); 2416355Skarels CTL_MSG *find_request(); 2516355Skarels CTL_MSG *find_match(); 2616355Skarels 2716355Skarels process_request(request, response) 2816365Skarels CTL_MSG *request; 2916365Skarels CTL_RESPONSE *response; 3016355Skarels { 3116365Skarels CTL_MSG *ptr; 3216355Skarels 3316365Skarels response->type = request->type; 3416365Skarels response->id_num = 0; 3516355Skarels 3616365Skarels switch (request->type) { 3716355Skarels 3816355Skarels case ANNOUNCE : 3916365Skarels do_announce(request, response); 4016365Skarels break; 4116355Skarels 4216355Skarels case LEAVE_INVITE : 4316365Skarels ptr = find_request(request); 4416365Skarels if (ptr != (CTL_MSG *) 0) { 4516365Skarels response->id_num = ptr->id_num; 4616365Skarels response->answer = SUCCESS; 4716365Skarels } else 4816365Skarels insert_table(request, response); 4916365Skarels break; 5016355Skarels 5116355Skarels case LOOK_UP : 5216365Skarels ptr = find_match(request); 5316365Skarels if (ptr != (CTL_MSG *) 0) { 5416365Skarels response->id_num = ptr->id_num; 5516365Skarels response->addr = ptr->addr; 5616365Skarels response->answer = SUCCESS; 5716365Skarels } else 5816365Skarels response->answer = NOT_HERE; 5916365Skarels break; 6016355Skarels 6116355Skarels case DELETE : 6216365Skarels response->answer = delete_invite(request->id_num); 6316365Skarels break; 6416355Skarels 6516355Skarels default : 6616365Skarels response->answer = UNKNOWN_REQUEST; 6716365Skarels break; 6816365Skarels } 6916355Skarels } 7016355Skarels 7116355Skarels struct hostent *gethostbyaddr(); 7216355Skarels 7316355Skarels do_announce(request, response) 7416365Skarels CTL_MSG *request; 7516365Skarels CTL_RESPONSE *response; 7616355Skarels { 7716365Skarels struct hostent *hp; 7816365Skarels CTL_MSG *ptr; 7916365Skarels int result; 8016355Skarels 8116355Skarels /* see if the user is logged */ 8216365Skarels result = find_user(request->r_name, request->r_tty); 8316365Skarels if (result != SUCCESS) { 8416365Skarels response->answer = result; 8516365Skarels return; 8616365Skarels } 8716365Skarels hp = gethostbyaddr(&request->ctl_addr.sin_addr, 8816365Skarels sizeof(struct in_addr), AF_INET); 8916365Skarels if (hp == (struct hostent *)0) { 9016365Skarels response->answer = MACHINE_UNKNOWN; 9116365Skarels return; 9216365Skarels } 9316365Skarels ptr = find_request(request); 9416365Skarels if (ptr == (CTL_MSG *) 0) { 9516365Skarels insert_table(request,response); 9616365Skarels response->answer = announce(request, hp->h_name); 9716365Skarels return; 9816365Skarels } 9916365Skarels if (request->id_num > ptr->id_num) { 10016365Skarels /* 10116365Skarels * this is an explicit re-announce, so update the id_num 10216365Skarels * field to avoid duplicates and re-announce the talk 10316365Skarels */ 10416365Skarels ptr->id_num = response->id_num = new_id(); 10516365Skarels response->answer = announce(request, hp->h_name); 10616365Skarels return; 10716365Skarels } 10816365Skarels /* a duplicated request, so ignore it */ 10916355Skarels response->id_num = ptr->id_num; 11016355Skarels response->answer = SUCCESS; 11116355Skarels } 11216355Skarels 11316355Skarels #include <utmp.h> 11416355Skarels 11516355Skarels /* 11616355Skarels * Search utmp for the local user 11716355Skarels */ 11816355Skarels find_user(name, tty) 11916365Skarels char *name; 12016365Skarels char *tty; 12116355Skarels { 12216365Skarels struct utmp ubuf; 123*23462Sbloom int status; 124*23462Sbloom FILE *fd; 12517560Sbloom struct stat statb; 12617560Sbloom char ftty[20]; 12716355Skarels 128*23462Sbloom if ((fd = fopen("/etc/utmp", "r")) == NULL) { 12916365Skarels perror("Can't open /etc/utmp"); 13016365Skarels return (FAILED); 13116355Skarels } 13216365Skarels #define SCMPN(a, b) strncmp(a, b, sizeof (a)) 13316365Skarels status = NOT_HERE; 13417560Sbloom (void) strcpy(ftty, "/dev/"); 135*23462Sbloom while (fread((char *) &ubuf, sizeof ubuf, 1, fd) == 1) 13616365Skarels if (SCMPN(ubuf.ut_name, name) == 0) { 13716365Skarels if (*tty == '\0') { 13817560Sbloom status = PERMISSION_DENIED; 13916365Skarels /* no particular tty was requested */ 14017560Sbloom (void) strcpy(ftty+5, ubuf.ut_line); 14117560Sbloom if (stat(ftty,&statb) == 0) { 14217560Sbloom if (!(statb.st_mode & 02)) 14317560Sbloom continue; 14417560Sbloom (void) strcpy(tty, ubuf.ut_line); 14517560Sbloom status = SUCCESS; 14617560Sbloom break; 14717560Sbloom } 14816365Skarels } 14916365Skarels if (strcmp(ubuf.ut_line, tty) == 0) { 15016365Skarels status = SUCCESS; 15116365Skarels break; 15216365Skarels } 15316365Skarels } 154*23462Sbloom fclose(fd); 15516365Skarels return (status); 15616355Skarels } 157