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
process_request(request,response)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
do_announce(request,response)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 */
find_user(name,tty)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