|
|
1.1 root 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 are permitted
6: * provided that: (1) source distributions retain this entire copyright
7: * notice and comment, and (2) distributions including binaries display
8: * the following acknowledgement: ``This product includes software
9: * developed by the University of California, Berkeley and its contributors''
10: * in the documentation or other materials provided with the distribution
11: * and in all advertising materials mentioning features or use of this
12: * software. Neither the name of the University nor the names of its
13: * contributors may be used to endorse or promote products derived
14: * from this software without specific prior written permission.
15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18: */
19:
20: #ifndef lint
21: static char sccsid[] = "@(#)process.c 5.9 (Berkeley) 6/1/90";
22: #endif /* not lint */
23:
24: /*
25: * process.c handles the requests, which can be of three types:
26: * ANNOUNCE - announce to a user that a talk is wanted
27: * LEAVE_INVITE - insert the request into the table
28: * LOOK_UP - look up to see if a request is waiting in
29: * in the table for the local user
30: * DELETE - delete invitation
31: */
32: #include <sys/types.h>
33: #include <sys/stat.h>
34: #include <stdio.h>
35: #include <syslog.h>
36: #include <netdb.h>
37: #include <netinet/in.h>
38:
39: #include <protocols/talkd.h>
40: #include <paths.h>
41:
42: char *strcpy();
43: CTL_MSG *find_request();
44: CTL_MSG *find_match();
45:
46: process_request(mp, rp)
47: register CTL_MSG *mp;
48: register CTL_RESPONSE *rp;
49: {
50: register CTL_MSG *ptr;
51: extern int debug;
52:
53: rp->vers = TALK_VERSION;
54: rp->type = mp->type;
55: rp->id_num = htonl(0);
56: if (mp->vers != TALK_VERSION) {
57: syslog(LOG_WARNING, "Bad protocol version %d", mp->vers);
58: rp->answer = BADVERSION;
59: return;
60: }
61: mp->id_num = ntohl(mp->id_num);
62: mp->addr.sa_family = ntohs(mp->addr.sa_family);
63: if (mp->addr.sa_family != AF_INET) {
64: syslog(LOG_WARNING, "Bad address, family %d",
65: mp->addr.sa_family);
66: rp->answer = BADADDR;
67: return;
68: }
69: mp->ctl_addr.sa_family = ntohs(mp->ctl_addr.sa_family);
70: if (mp->ctl_addr.sa_family != AF_INET) {
71: syslog(LOG_WARNING, "Bad control address, family %d",
72: mp->ctl_addr.sa_family);
73: rp->answer = BADCTLADDR;
74: return;
75: }
76: mp->pid = ntohl(mp->pid);
77: if (debug)
78: print_request("process_request", mp);
79: switch (mp->type) {
80:
81: case ANNOUNCE:
82: do_announce(mp, rp);
83: break;
84:
85: case LEAVE_INVITE:
86: ptr = find_request(mp);
87: if (ptr != (CTL_MSG *)0) {
88: rp->id_num = htonl(ptr->id_num);
89: rp->answer = SUCCESS;
90: } else
91: insert_table(mp, rp);
92: break;
93:
94: case LOOK_UP:
95: ptr = find_match(mp);
96: if (ptr != (CTL_MSG *)0) {
97: rp->id_num = htonl(ptr->id_num);
98: rp->addr = ptr->addr;
99: rp->addr.sa_family = htons(ptr->addr.sa_family);
100: rp->answer = SUCCESS;
101: } else
102: rp->answer = NOT_HERE;
103: break;
104:
105: case DELETE:
106: rp->answer = delete_invite(mp->id_num);
107: break;
108:
109: default:
110: rp->answer = UNKNOWN_REQUEST;
111: break;
112: }
113: if (debug)
114: print_response("process_request", rp);
115: }
116:
117: do_announce(mp, rp)
118: register CTL_MSG *mp;
119: CTL_RESPONSE *rp;
120: {
121: struct hostent *hp;
122: CTL_MSG *ptr;
123: int result;
124:
125: /* see if the user is logged */
126: result = find_user(mp->r_name, mp->r_tty);
127: if (result != SUCCESS) {
128: rp->answer = result;
129: return;
130: }
131: #define satosin(sa) ((struct sockaddr_in *)(sa))
132: hp = gethostbyaddr(&satosin(&mp->ctl_addr)->sin_addr,
133: sizeof (struct in_addr), AF_INET);
134: if (hp == (struct hostent *)0) {
135: rp->answer = MACHINE_UNKNOWN;
136: return;
137: }
138: ptr = find_request(mp);
139: if (ptr == (CTL_MSG *) 0) {
140: insert_table(mp, rp);
141: rp->answer = announce(mp, hp->h_name);
142: return;
143: }
144: if (mp->id_num > ptr->id_num) {
145: /*
146: * This is an explicit re-announce, so update the id_num
147: * field to avoid duplicates and re-announce the talk.
148: */
149: ptr->id_num = new_id();
150: rp->id_num = htonl(ptr->id_num);
151: rp->answer = announce(mp, hp->h_name);
152: } else {
153: /* a duplicated request, so ignore it */
154: rp->id_num = htonl(ptr->id_num);
155: rp->answer = SUCCESS;
156: }
157: }
158:
159: #include <utmp.h>
160:
161: /*
162: * Search utmp for the local user
163: */
164: find_user(name, tty)
165: char *name, *tty;
166: {
167: struct utmp ubuf;
168: int status;
169: FILE *fd;
170: struct stat statb;
171: char ftty[20];
172:
173: if ((fd = fopen(_PATH_UTMP, "r")) == NULL) {
174: fprintf(stderr, "talkd: can't read %s.\n", _PATH_UTMP);
175: return (FAILED);
176: }
177: #define SCMPN(a, b) strncmp(a, b, sizeof (a))
178: status = NOT_HERE;
179: (void) strcpy(ftty, _PATH_DEV);
180: while (fread((char *) &ubuf, sizeof ubuf, 1, fd) == 1)
181: if (SCMPN(ubuf.ut_name, name) == 0) {
182: if (*tty == '\0') {
183: status = PERMISSION_DENIED;
184: /* no particular tty was requested */
185: (void) strcpy(ftty+5, ubuf.ut_line);
186: if (stat(ftty,&statb) == 0) {
187: if (!(statb.st_mode & 020))
188: continue;
189: (void) strcpy(tty, ubuf.ut_line);
190: status = SUCCESS;
191: break;
192: }
193: }
194: if (strcmp(ubuf.ut_line, tty) == 0) {
195: status = SUCCESS;
196: break;
197: }
198: }
199: fclose(fd);
200: return (status);
201: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.