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