Commit | Line | Data |
---|---|---|
ca2cf5a5 KM |
1 | /* |
2 | * Copyright (c) 1983 Regents of the University of California. | |
9e678aa5 KB |
3 | * All rights reserved. |
4 | * | |
af359dea C |
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. | |
ca2cf5a5 KM |
32 | */ |
33 | ||
963ce42e | 34 | #ifndef lint |
af359dea | 35 | static char sccsid[] = "@(#)process.c 5.10 (Berkeley) 2/26/91"; |
9e678aa5 | 36 | #endif /* not lint */ |
d6f29ffb | 37 | |
963ce42e MK |
38 | /* |
39 | * process.c handles the requests, which can be of three types: | |
40 | * ANNOUNCE - announce to a user that a talk is wanted | |
41 | * LEAVE_INVITE - insert the request into the table | |
42 | * LOOK_UP - look up to see if a request is waiting in | |
43 | * in the table for the local user | |
44 | * DELETE - delete invitation | |
45 | */ | |
b26f7bc4 | 46 | #include <sys/param.h> |
03240ef4 | 47 | #include <sys/stat.h> |
b26f7bc4 | 48 | #include <sys/socket.h> |
595cdd5e | 49 | #include <netinet/in.h> |
595cdd5e | 50 | #include <protocols/talkd.h> |
b26f7bc4 KB |
51 | #include <netdb.h> |
52 | #include <syslog.h> | |
53 | #include <stdio.h> | |
54 | #include <string.h> | |
7abf8d65 | 55 | #include <paths.h> |
595cdd5e | 56 | |
d6f29ffb MK |
57 | CTL_MSG *find_request(); |
58 | CTL_MSG *find_match(); | |
59 | ||
595cdd5e KM |
60 | process_request(mp, rp) |
61 | register CTL_MSG *mp; | |
62 | register CTL_RESPONSE *rp; | |
d6f29ffb | 63 | { |
595cdd5e KM |
64 | register CTL_MSG *ptr; |
65 | extern int debug; | |
66 | ||
67 | rp->vers = TALK_VERSION; | |
68 | rp->type = mp->type; | |
69 | rp->id_num = htonl(0); | |
70 | if (mp->vers != TALK_VERSION) { | |
71 | syslog(LOG_WARNING, "Bad protocol version %d", mp->vers); | |
72 | rp->answer = BADVERSION; | |
73 | return; | |
74 | } | |
75 | mp->id_num = ntohl(mp->id_num); | |
76 | mp->addr.sa_family = ntohs(mp->addr.sa_family); | |
77 | if (mp->addr.sa_family != AF_INET) { | |
78 | syslog(LOG_WARNING, "Bad address, family %d", | |
79 | mp->addr.sa_family); | |
80 | rp->answer = BADADDR; | |
81 | return; | |
82 | } | |
83 | mp->ctl_addr.sa_family = ntohs(mp->ctl_addr.sa_family); | |
84 | if (mp->ctl_addr.sa_family != AF_INET) { | |
85 | syslog(LOG_WARNING, "Bad control address, family %d", | |
86 | mp->ctl_addr.sa_family); | |
87 | rp->answer = BADCTLADDR; | |
88 | return; | |
89 | } | |
90 | mp->pid = ntohl(mp->pid); | |
91 | if (debug) | |
92 | print_request("process_request", mp); | |
93 | switch (mp->type) { | |
d6f29ffb | 94 | |
595cdd5e KM |
95 | case ANNOUNCE: |
96 | do_announce(mp, rp); | |
963ce42e | 97 | break; |
d6f29ffb | 98 | |
595cdd5e KM |
99 | case LEAVE_INVITE: |
100 | ptr = find_request(mp); | |
101 | if (ptr != (CTL_MSG *)0) { | |
102 | rp->id_num = htonl(ptr->id_num); | |
103 | rp->answer = SUCCESS; | |
963ce42e | 104 | } else |
595cdd5e | 105 | insert_table(mp, rp); |
963ce42e | 106 | break; |
d6f29ffb | 107 | |
595cdd5e KM |
108 | case LOOK_UP: |
109 | ptr = find_match(mp); | |
110 | if (ptr != (CTL_MSG *)0) { | |
111 | rp->id_num = htonl(ptr->id_num); | |
112 | rp->addr = ptr->addr; | |
113 | rp->addr.sa_family = htons(ptr->addr.sa_family); | |
114 | rp->answer = SUCCESS; | |
963ce42e | 115 | } else |
595cdd5e | 116 | rp->answer = NOT_HERE; |
963ce42e | 117 | break; |
d6f29ffb | 118 | |
595cdd5e KM |
119 | case DELETE: |
120 | rp->answer = delete_invite(mp->id_num); | |
963ce42e | 121 | break; |
d6f29ffb | 122 | |
595cdd5e KM |
123 | default: |
124 | rp->answer = UNKNOWN_REQUEST; | |
963ce42e MK |
125 | break; |
126 | } | |
595cdd5e KM |
127 | if (debug) |
128 | print_response("process_request", rp); | |
d6f29ffb MK |
129 | } |
130 | ||
595cdd5e KM |
131 | do_announce(mp, rp) |
132 | register CTL_MSG *mp; | |
133 | CTL_RESPONSE *rp; | |
d6f29ffb | 134 | { |
963ce42e MK |
135 | struct hostent *hp; |
136 | CTL_MSG *ptr; | |
137 | int result; | |
d6f29ffb MK |
138 | |
139 | /* see if the user is logged */ | |
595cdd5e | 140 | result = find_user(mp->r_name, mp->r_tty); |
963ce42e | 141 | if (result != SUCCESS) { |
595cdd5e | 142 | rp->answer = result; |
963ce42e MK |
143 | return; |
144 | } | |
595cdd5e | 145 | #define satosin(sa) ((struct sockaddr_in *)(sa)) |
b26f7bc4 | 146 | hp = gethostbyaddr((char *)&satosin(&mp->ctl_addr)->sin_addr, |
595cdd5e | 147 | sizeof (struct in_addr), AF_INET); |
963ce42e | 148 | if (hp == (struct hostent *)0) { |
595cdd5e | 149 | rp->answer = MACHINE_UNKNOWN; |
963ce42e MK |
150 | return; |
151 | } | |
595cdd5e | 152 | ptr = find_request(mp); |
963ce42e | 153 | if (ptr == (CTL_MSG *) 0) { |
595cdd5e KM |
154 | insert_table(mp, rp); |
155 | rp->answer = announce(mp, hp->h_name); | |
963ce42e MK |
156 | return; |
157 | } | |
595cdd5e | 158 | if (mp->id_num > ptr->id_num) { |
963ce42e | 159 | /* |
595cdd5e KM |
160 | * This is an explicit re-announce, so update the id_num |
161 | * field to avoid duplicates and re-announce the talk. | |
963ce42e | 162 | */ |
595cdd5e KM |
163 | ptr->id_num = new_id(); |
164 | rp->id_num = htonl(ptr->id_num); | |
165 | rp->answer = announce(mp, hp->h_name); | |
166 | } else { | |
167 | /* a duplicated request, so ignore it */ | |
168 | rp->id_num = htonl(ptr->id_num); | |
169 | rp->answer = SUCCESS; | |
963ce42e | 170 | } |
d6f29ffb MK |
171 | } |
172 | ||
173 | #include <utmp.h> | |
174 | ||
175 | /* | |
176 | * Search utmp for the local user | |
177 | */ | |
d6f29ffb | 178 | find_user(name, tty) |
595cdd5e | 179 | char *name, *tty; |
d6f29ffb | 180 | { |
963ce42e | 181 | struct utmp ubuf; |
2ee2174b JB |
182 | int status; |
183 | FILE *fd; | |
03240ef4 JB |
184 | struct stat statb; |
185 | char ftty[20]; | |
d6f29ffb | 186 | |
ed77c2a4 KB |
187 | if ((fd = fopen(_PATH_UTMP, "r")) == NULL) { |
188 | fprintf(stderr, "talkd: can't read %s.\n", _PATH_UTMP); | |
963ce42e MK |
189 | return (FAILED); |
190 | } | |
191 | #define SCMPN(a, b) strncmp(a, b, sizeof (a)) | |
192 | status = NOT_HERE; | |
7abf8d65 | 193 | (void) strcpy(ftty, _PATH_DEV); |
2ee2174b | 194 | while (fread((char *) &ubuf, sizeof ubuf, 1, fd) == 1) |
963ce42e MK |
195 | if (SCMPN(ubuf.ut_name, name) == 0) { |
196 | if (*tty == '\0') { | |
03240ef4 | 197 | status = PERMISSION_DENIED; |
963ce42e | 198 | /* no particular tty was requested */ |
03240ef4 JB |
199 | (void) strcpy(ftty+5, ubuf.ut_line); |
200 | if (stat(ftty,&statb) == 0) { | |
ec72c538 | 201 | if (!(statb.st_mode & 020)) |
03240ef4 JB |
202 | continue; |
203 | (void) strcpy(tty, ubuf.ut_line); | |
204 | status = SUCCESS; | |
205 | break; | |
206 | } | |
963ce42e MK |
207 | } |
208 | if (strcmp(ubuf.ut_line, tty) == 0) { | |
209 | status = SUCCESS; | |
210 | break; | |
211 | } | |
212 | } | |
2ee2174b | 213 | fclose(fd); |
963ce42e | 214 | return (status); |
d6f29ffb | 215 | } |