1 /* 2 * Copyright (c) 1983 Regents of the University of California. 3 * All rights reserved. The Berkeley software License Agreement 4 * specifies the terms and conditions for redistribution. 5 */ 6 7 #ifndef lint 8 static char sccsid[] = "@(#)process.c 5.1 (Berkeley) 06/07/85"; 9 #endif not lint 10 11 /* 12 * process.c handles the requests, which can be of three types: 13 * ANNOUNCE - announce to a user that a talk is wanted 14 * LEAVE_INVITE - insert the request into the table 15 * LOOK_UP - look up to see if a request is waiting in 16 * in the table for the local user 17 * DELETE - delete invitation 18 */ 19 #include "ctl.h" 20 #include <sys/stat.h> 21 22 char *strcpy(); 23 CTL_MSG *find_request(); 24 CTL_MSG *find_match(); 25 26 process_request(request, response) 27 CTL_MSG *request; 28 CTL_RESPONSE *response; 29 { 30 CTL_MSG *ptr; 31 32 response->type = request->type; 33 response->id_num = 0; 34 35 switch (request->type) { 36 37 case ANNOUNCE : 38 do_announce(request, response); 39 break; 40 41 case LEAVE_INVITE : 42 ptr = find_request(request); 43 if (ptr != (CTL_MSG *) 0) { 44 response->id_num = ptr->id_num; 45 response->answer = SUCCESS; 46 } else 47 insert_table(request, response); 48 break; 49 50 case LOOK_UP : 51 ptr = find_match(request); 52 if (ptr != (CTL_MSG *) 0) { 53 response->id_num = ptr->id_num; 54 response->addr = ptr->addr; 55 response->answer = SUCCESS; 56 } else 57 response->answer = NOT_HERE; 58 break; 59 60 case DELETE : 61 response->answer = delete_invite(request->id_num); 62 break; 63 64 default : 65 response->answer = UNKNOWN_REQUEST; 66 break; 67 } 68 } 69 70 struct hostent *gethostbyaddr(); 71 72 do_announce(request, response) 73 CTL_MSG *request; 74 CTL_RESPONSE *response; 75 { 76 struct hostent *hp; 77 CTL_MSG *ptr; 78 int result; 79 80 /* see if the user is logged */ 81 result = find_user(request->r_name, request->r_tty); 82 if (result != SUCCESS) { 83 response->answer = result; 84 return; 85 } 86 hp = gethostbyaddr(&request->ctl_addr.sin_addr, 87 sizeof(struct in_addr), AF_INET); 88 if (hp == (struct hostent *)0) { 89 response->answer = MACHINE_UNKNOWN; 90 return; 91 } 92 ptr = find_request(request); 93 if (ptr == (CTL_MSG *) 0) { 94 insert_table(request,response); 95 response->answer = announce(request, hp->h_name); 96 return; 97 } 98 if (request->id_num > ptr->id_num) { 99 /* 100 * this is an explicit re-announce, so update the id_num 101 * field to avoid duplicates and re-announce the talk 102 */ 103 ptr->id_num = response->id_num = new_id(); 104 response->answer = announce(request, hp->h_name); 105 return; 106 } 107 /* a duplicated request, so ignore it */ 108 response->id_num = ptr->id_num; 109 response->answer = SUCCESS; 110 } 111 112 #include <utmp.h> 113 114 /* 115 * Search utmp for the local user 116 */ 117 find_user(name, tty) 118 char *name; 119 char *tty; 120 { 121 struct utmp ubuf; 122 int fd, status; 123 struct stat statb; 124 char ftty[20]; 125 126 if ((fd = open("/etc/utmp", 0)) == -1) { 127 perror("Can't open /etc/utmp"); 128 return (FAILED); 129 } 130 #define SCMPN(a, b) strncmp(a, b, sizeof (a)) 131 status = NOT_HERE; 132 (void) strcpy(ftty, "/dev/"); 133 while (read(fd, (char *) &ubuf, sizeof ubuf) == sizeof(ubuf)) 134 if (SCMPN(ubuf.ut_name, name) == 0) { 135 if (*tty == '\0') { 136 status = PERMISSION_DENIED; 137 /* no particular tty was requested */ 138 (void) strcpy(ftty+5, ubuf.ut_line); 139 if (stat(ftty,&statb) == 0) { 140 if (!(statb.st_mode & 02)) 141 continue; 142 (void) strcpy(tty, ubuf.ut_line); 143 status = SUCCESS; 144 break; 145 } 146 } 147 if (strcmp(ubuf.ut_line, tty) == 0) { 148 status = SUCCESS; 149 break; 150 } 151 } 152 close(fd); 153 return (status); 154 } 155