Commit | Line | Data |
---|---|---|
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 | 9 | static 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 |
31 | CTL_MSG *find_request(); |
32 | CTL_MSG *find_match(); | |
33 | ||
595cdd5e KM |
34 | process_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 |
105 | do_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 | 152 | find_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 | } |