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