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