156577Sbostic /* 256577Sbostic * Copyright (c) 1983 Regents of the University of California. 356577Sbostic * All rights reserved. The Berkeley software License Agreement 456577Sbostic * specifies the terms and conditions for redistribution. 556577Sbostic */ 656577Sbostic 756577Sbostic #ifndef lint 856577Sbostic static char sccsid[] = "@(#)process.c 5.2 (Berkeley) 6/8/85"; 956577Sbostic #endif not lint 1056577Sbostic 1156577Sbostic /* 1256577Sbostic * process.c handles the requests, which can be of three types: 1356577Sbostic * ANNOUNCE - announce to a user that a talk is wanted 1456577Sbostic * LEAVE_INVITE - insert the request into the table 1556577Sbostic * LOOK_UP - look up to see if a request is waiting in 1656577Sbostic * in the table for the local user 1756577Sbostic * DELETE - delete invitation 1856577Sbostic */ 1956577Sbostic #include "ctl.h" 2056577Sbostic #include <sys/stat.h> 2156577Sbostic #include <stdio.h> 2256577Sbostic 2356577Sbostic char *strcpy(); 2456577Sbostic CTL_MSG *find_request(); 2556577Sbostic CTL_MSG *find_match(); 2656577Sbostic 2756577Sbostic process_request(request, response) 2856577Sbostic CTL_MSG *request; 2956577Sbostic CTL_RESPONSE *response; 3056577Sbostic { 3156577Sbostic CTL_MSG *ptr; 3256577Sbostic 3356577Sbostic response->type = request->type; 3456577Sbostic response->id_num = 0; 3556577Sbostic 3656577Sbostic switch (request->type) { 3756577Sbostic 3856577Sbostic case ANNOUNCE : 3956577Sbostic do_announce(request, response); 4056577Sbostic break; 4156577Sbostic 4256577Sbostic case LEAVE_INVITE : 4356577Sbostic ptr = find_request(request); 4456577Sbostic if (ptr != (CTL_MSG *) 0) { 4556577Sbostic response->id_num = ptr->id_num; 4656577Sbostic response->answer = SUCCESS; 4756577Sbostic } else 4856577Sbostic insert_table(request, response); 4956577Sbostic break; 5056577Sbostic 5156577Sbostic case LOOK_UP : 5256577Sbostic ptr = find_match(request); 5356577Sbostic if (ptr != (CTL_MSG *) 0) { 5456577Sbostic response->id_num = ptr->id_num; 5556577Sbostic response->addr = ptr->addr; 5656577Sbostic response->answer = SUCCESS; 5756577Sbostic } else 5856577Sbostic response->answer = NOT_HERE; 5956577Sbostic break; 6056577Sbostic 6156577Sbostic case DELETE : 6256577Sbostic response->answer = delete_invite(request->id_num); 6356577Sbostic break; 6456577Sbostic 6556577Sbostic default : 6656577Sbostic response->answer = UNKNOWN_REQUEST; 6756577Sbostic break; 6856577Sbostic } 6956577Sbostic } 7056577Sbostic 7156577Sbostic struct hostent *gethostbyaddr(); 7256577Sbostic 7356577Sbostic do_announce(request, response) 7456577Sbostic CTL_MSG *request; 7556577Sbostic CTL_RESPONSE *response; 7656577Sbostic { 7756577Sbostic struct hostent *hp; 7856577Sbostic CTL_MSG *ptr; 7956577Sbostic int result; 8056577Sbostic 8156577Sbostic /* see if the user is logged */ 8256577Sbostic result = find_user(request->r_name, request->r_tty); 8356577Sbostic if (result != SUCCESS) { 8456577Sbostic response->answer = result; 8556577Sbostic return; 8656577Sbostic } 87*56579Sbostic hp = gethostbyaddr((char *)&request->ctl_addr.sin_addr, 8856577Sbostic sizeof(struct in_addr), AF_INET); 8956577Sbostic if (hp == (struct hostent *)0) { 9056577Sbostic response->answer = MACHINE_UNKNOWN; 9156577Sbostic return; 9256577Sbostic } 9356577Sbostic ptr = find_request(request); 9456577Sbostic if (ptr == (CTL_MSG *) 0) { 9556577Sbostic insert_table(request,response); 9656577Sbostic response->answer = announce(request, hp->h_name); 9756577Sbostic return; 9856577Sbostic } 9956577Sbostic if (request->id_num > ptr->id_num) { 10056577Sbostic /* 10156577Sbostic * this is an explicit re-announce, so update the id_num 10256577Sbostic * field to avoid duplicates and re-announce the talk 10356577Sbostic */ 10456577Sbostic ptr->id_num = response->id_num = new_id(); 10556577Sbostic response->answer = announce(request, hp->h_name); 10656577Sbostic return; 10756577Sbostic } 10856577Sbostic /* a duplicated request, so ignore it */ 10956577Sbostic response->id_num = ptr->id_num; 11056577Sbostic response->answer = SUCCESS; 11156577Sbostic } 11256577Sbostic 11356577Sbostic #include <utmp.h> 11456577Sbostic 11556577Sbostic /* 11656577Sbostic * Search utmp for the local user 11756577Sbostic */ 11856577Sbostic find_user(name, tty) 11956577Sbostic char *name; 12056577Sbostic char *tty; 12156577Sbostic { 12256577Sbostic struct utmp ubuf; 12356577Sbostic int status; 12456577Sbostic FILE *fd; 12556577Sbostic struct stat statb; 12656577Sbostic char ftty[20]; 12756577Sbostic 12856577Sbostic if ((fd = fopen("/etc/utmp", "r")) == NULL) { 12956577Sbostic perror("Can't open /etc/utmp"); 13056577Sbostic return (FAILED); 13156577Sbostic } 13256577Sbostic #define SCMPN(a, b) strncmp(a, b, sizeof (a)) 13356577Sbostic status = NOT_HERE; 13456577Sbostic (void) strcpy(ftty, "/dev/"); 13556577Sbostic while (fread((char *) &ubuf, sizeof ubuf, 1, fd) == 1) 13656577Sbostic if (SCMPN(ubuf.ut_name, name) == 0) { 13756577Sbostic if (*tty == '\0') { 13856577Sbostic status = PERMISSION_DENIED; 13956577Sbostic /* no particular tty was requested */ 14056577Sbostic (void) strcpy(ftty+5, ubuf.ut_line); 14156577Sbostic if (stat(ftty,&statb) == 0) { 14256577Sbostic if (!(statb.st_mode & 020)) 14356577Sbostic continue; 14456577Sbostic (void) strcpy(tty, ubuf.ut_line); 14556577Sbostic status = SUCCESS; 14656577Sbostic break; 14756577Sbostic } 14856577Sbostic } 14956577Sbostic if (strcmp(ubuf.ut_line, tty) == 0) { 15056577Sbostic status = SUCCESS; 15156577Sbostic break; 15256577Sbostic } 15356577Sbostic } 15456577Sbostic fclose(fd); 15556577Sbostic return (status); 15656577Sbostic } 157