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