1 | /* |
---|
2 | * Copyright (c) 1983 Regents of the University of California. |
---|
3 | * All rights reserved. |
---|
4 | * |
---|
5 | * Redistribution and use in source and binary forms, with or without |
---|
6 | * modification, are permitted provided that the following conditions |
---|
7 | * are met: |
---|
8 | * 1. Redistributions of source code must retain the above copyright |
---|
9 | * notice, this list of conditions and the following disclaimer. |
---|
10 | * 2. Redistributions in binary form must reproduce the above copyright |
---|
11 | * notice, this list of conditions and the following disclaimer in the |
---|
12 | * documentation and/or other materials provided with the distribution. |
---|
13 | * 3. All advertising materials mentioning features or use of this software |
---|
14 | * must display the following acknowledgement: |
---|
15 | * This product includes software developed by the University of |
---|
16 | * California, Berkeley and its contributors. |
---|
17 | * 4. Neither the name of the University nor the names of its contributors |
---|
18 | * may be used to endorse or promote products derived from this software |
---|
19 | * without specific prior written permission. |
---|
20 | * |
---|
21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
---|
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
---|
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
---|
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
---|
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
---|
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
---|
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
---|
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
---|
29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
---|
30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
---|
31 | * SUCH DAMAGE. |
---|
32 | */ |
---|
33 | |
---|
34 | #ifndef lint |
---|
35 | /*static char sccsid[] = "from: @(#)process.c 5.10 (Berkeley) 2/26/91";*/ |
---|
36 | static char rcsid[] = "$Id: process.c,v 1.6 2002-05-24 18:37:50 zacheiss Exp $"; |
---|
37 | #endif /* not lint */ |
---|
38 | |
---|
39 | /* |
---|
40 | * process.c handles the requests, which can be of three types: |
---|
41 | * ANNOUNCE - announce to a user that a talk is wanted |
---|
42 | * LEAVE_INVITE - insert the request into the table |
---|
43 | * LOOK_UP - look up to see if a request is waiting in |
---|
44 | * in the table for the local user |
---|
45 | * DELETE - delete invitation |
---|
46 | */ |
---|
47 | #include <sys/param.h> |
---|
48 | #include <sys/stat.h> |
---|
49 | #include <sys/socket.h> |
---|
50 | #include <netinet/in.h> |
---|
51 | #include <protocols/talkd.h> |
---|
52 | #include <netdb.h> |
---|
53 | #include <syslog.h> |
---|
54 | #include <stdio.h> |
---|
55 | #include <string.h> |
---|
56 | #ifdef HAVE_PATHS_H |
---|
57 | #include <paths.h> |
---|
58 | #endif |
---|
59 | #ifndef _PATH_DEV |
---|
60 | #define _PATH_DEV "/dev/" |
---|
61 | #endif |
---|
62 | |
---|
63 | CTL_MSG *find_request(); |
---|
64 | CTL_MSG *find_match(); |
---|
65 | |
---|
66 | process_request(mp, rp) |
---|
67 | register CTL_MSG *mp; |
---|
68 | register CTL_RESPONSE *rp; |
---|
69 | { |
---|
70 | register CTL_MSG *ptr; |
---|
71 | extern int debug; |
---|
72 | |
---|
73 | rp->vers = TALK_VERSION; |
---|
74 | rp->type = mp->type; |
---|
75 | rp->id_num = htonl(0); |
---|
76 | if (mp->vers != TALK_VERSION) { |
---|
77 | syslog(LOG_WARNING, "Bad protocol version %d", mp->vers); |
---|
78 | rp->answer = BADVERSION; |
---|
79 | return; |
---|
80 | } |
---|
81 | mp->id_num = ntohl(mp->id_num); |
---|
82 | mp->addr.family = ntohs(mp->addr.family); |
---|
83 | if (mp->addr.family != AF_INET) { |
---|
84 | syslog(LOG_WARNING, "Bad address, family %d", |
---|
85 | mp->addr.family); |
---|
86 | rp->answer = BADADDR; |
---|
87 | return; |
---|
88 | } |
---|
89 | mp->ctl_addr.family = ntohs(mp->ctl_addr.family); |
---|
90 | if (mp->ctl_addr.family != AF_INET) { |
---|
91 | syslog(LOG_WARNING, "Bad control address, family %d", |
---|
92 | mp->ctl_addr.family); |
---|
93 | rp->answer = BADCTLADDR; |
---|
94 | return; |
---|
95 | } |
---|
96 | mp->pid = ntohl(mp->pid); |
---|
97 | if (debug) |
---|
98 | print_request("process_request", mp); |
---|
99 | switch (mp->type) { |
---|
100 | |
---|
101 | case ANNOUNCE: |
---|
102 | do_announce(mp, rp); |
---|
103 | break; |
---|
104 | |
---|
105 | case LEAVE_INVITE: |
---|
106 | ptr = find_request(mp); |
---|
107 | if (ptr != (CTL_MSG *)0) { |
---|
108 | rp->id_num = htonl(ptr->id_num); |
---|
109 | rp->answer = SUCCESS; |
---|
110 | } else |
---|
111 | insert_table(mp, rp); |
---|
112 | break; |
---|
113 | |
---|
114 | case LOOK_UP: |
---|
115 | ptr = find_match(mp); |
---|
116 | if (ptr != (CTL_MSG *)0) { |
---|
117 | rp->id_num = htonl(ptr->id_num); |
---|
118 | rp->addr = ptr->addr; |
---|
119 | rp->addr.family = htons(ptr->addr.family); |
---|
120 | rp->answer = SUCCESS; |
---|
121 | } else |
---|
122 | rp->answer = NOT_HERE; |
---|
123 | break; |
---|
124 | |
---|
125 | case DELETE: |
---|
126 | rp->answer = delete_invite(mp->id_num); |
---|
127 | break; |
---|
128 | |
---|
129 | default: |
---|
130 | rp->answer = UNKNOWN_REQUEST; |
---|
131 | break; |
---|
132 | } |
---|
133 | if (debug) |
---|
134 | print_response("process_request", rp); |
---|
135 | } |
---|
136 | |
---|
137 | do_announce(mp, rp) |
---|
138 | register CTL_MSG *mp; |
---|
139 | CTL_RESPONSE *rp; |
---|
140 | { |
---|
141 | struct hostent *hp; |
---|
142 | CTL_MSG *ptr; |
---|
143 | int result; |
---|
144 | |
---|
145 | /* see if the user is logged */ |
---|
146 | result = find_user(mp->r_name, mp->r_tty); |
---|
147 | if (result != SUCCESS) { |
---|
148 | rp->answer = result; |
---|
149 | return; |
---|
150 | } |
---|
151 | #define satosin(sa) ((struct sockaddr_in *)(sa)) |
---|
152 | hp = gethostbyaddr((char *)&satosin(&mp->ctl_addr)->sin_addr, |
---|
153 | sizeof (struct in_addr), AF_INET); |
---|
154 | if (hp == (struct hostent *)0) { |
---|
155 | rp->answer = MACHINE_UNKNOWN; |
---|
156 | return; |
---|
157 | } |
---|
158 | ptr = find_request(mp); |
---|
159 | if (ptr == (CTL_MSG *) 0) { |
---|
160 | insert_table(mp, rp); |
---|
161 | rp->answer = announce(mp, hp->h_name); |
---|
162 | return; |
---|
163 | } |
---|
164 | if (mp->id_num > ptr->id_num) { |
---|
165 | /* |
---|
166 | * This is an explicit re-announce, so update the id_num |
---|
167 | * field to avoid duplicates and re-announce the talk. |
---|
168 | */ |
---|
169 | ptr->id_num = new_id(); |
---|
170 | rp->id_num = htonl(ptr->id_num); |
---|
171 | rp->answer = announce(mp, hp->h_name); |
---|
172 | } else { |
---|
173 | /* a duplicated request, so ignore it */ |
---|
174 | rp->id_num = htonl(ptr->id_num); |
---|
175 | rp->answer = SUCCESS; |
---|
176 | } |
---|
177 | } |
---|
178 | |
---|
179 | #include <utmp.h> |
---|
180 | |
---|
181 | /* |
---|
182 | * Search utmp for the local user |
---|
183 | */ |
---|
184 | find_user(name, tty) |
---|
185 | char *name, *tty; |
---|
186 | { |
---|
187 | struct utmp *uptr; |
---|
188 | int status; |
---|
189 | struct stat statb; |
---|
190 | char ftty[20]; |
---|
191 | |
---|
192 | #define SCMPN(a, b) strncmp(a, b, sizeof (a)) |
---|
193 | status = NOT_HERE; |
---|
194 | (void) strcpy(ftty, _PATH_DEV); |
---|
195 | while ((uptr = getutent()) != NULL) { |
---|
196 | #ifdef USER_PROCESS |
---|
197 | if (uptr->ut_type != USER_PROCESS) |
---|
198 | continue; |
---|
199 | #endif |
---|
200 | if (SCMPN(uptr->ut_name, name) == 0) { |
---|
201 | if (*tty == '\0') { |
---|
202 | status = PERMISSION_DENIED; |
---|
203 | /* no particular tty was requested */ |
---|
204 | (void) strcpy(ftty+5, uptr->ut_line); |
---|
205 | if (stat(ftty,&statb) == 0) { |
---|
206 | if (!(statb.st_mode & 020)) |
---|
207 | continue; |
---|
208 | (void) strcpy(tty, uptr->ut_line); |
---|
209 | status = SUCCESS; |
---|
210 | break; |
---|
211 | } |
---|
212 | } |
---|
213 | if (strcmp(uptr->ut_line, tty) == 0) { |
---|
214 | status = SUCCESS; |
---|
215 | break; |
---|
216 | } |
---|
217 | } |
---|
218 | } |
---|
219 | endutent(); |
---|
220 | return (status); |
---|
221 | } |
---|