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