xref: /original-bsd/libexec/talkd/process.c (revision 6219b5e8)
1 #ifndef lint
2 static char sccsid[] = "@(#)process.c	1.3 (Berkeley) 12/20/84";
3 #endif
4 
5 /*
6  * process.c handles the requests, which can be of three types:
7  *	ANNOUNCE - announce to a user that a talk is wanted
8  *	LEAVE_INVITE - insert the request into the table
9  *	LOOK_UP - look up to see if a request is waiting in
10  *		  in the table for the local user
11  *	DELETE - delete invitation
12  */
13 #include "ctl.h"
14 #include <sys/stat.h>
15 
16 char *strcpy();
17 CTL_MSG *find_request();
18 CTL_MSG *find_match();
19 
20 process_request(request, response)
21 	CTL_MSG *request;
22 	CTL_RESPONSE *response;
23 {
24 	CTL_MSG *ptr;
25 
26 	response->type = request->type;
27 	response->id_num = 0;
28 
29 	switch (request->type) {
30 
31 	case ANNOUNCE :
32 		do_announce(request, response);
33 		break;
34 
35 	case LEAVE_INVITE :
36 		ptr = find_request(request);
37 		if (ptr != (CTL_MSG *) 0) {
38 			response->id_num = ptr->id_num;
39 			response->answer = SUCCESS;
40 		} else
41 			insert_table(request, response);
42 		break;
43 
44 	case LOOK_UP :
45 		ptr = find_match(request);
46 		if (ptr != (CTL_MSG *) 0) {
47 			response->id_num = ptr->id_num;
48 			response->addr = ptr->addr;
49 			response->answer = SUCCESS;
50 		} else
51 			response->answer = NOT_HERE;
52 		break;
53 
54 	case DELETE :
55 		response->answer = delete_invite(request->id_num);
56 		break;
57 
58 	default :
59 		response->answer = UNKNOWN_REQUEST;
60 		break;
61 	}
62 }
63 
64 struct hostent *gethostbyaddr();
65 
66 do_announce(request, response)
67 	CTL_MSG *request;
68 	CTL_RESPONSE *response;
69 {
70 	struct hostent *hp;
71 	CTL_MSG *ptr;
72 	int result;
73 
74 	/* see if the user is logged */
75 	result = find_user(request->r_name, request->r_tty);
76 	if (result != SUCCESS) {
77 		response->answer = result;
78 		return;
79 	}
80 	hp = gethostbyaddr(&request->ctl_addr.sin_addr,
81 		sizeof(struct in_addr), AF_INET);
82 	if (hp == (struct hostent *)0) {
83 		response->answer = MACHINE_UNKNOWN;
84 		return;
85 	}
86 	ptr = find_request(request);
87 	if (ptr == (CTL_MSG *) 0) {
88 		insert_table(request,response);
89 		response->answer = announce(request, hp->h_name);
90 		return;
91 	}
92 	if (request->id_num > ptr->id_num) {
93 		/*
94 		 * this is an explicit re-announce, so update the id_num
95 		 * field to avoid duplicates and re-announce the talk
96 		 */
97 		ptr->id_num = response->id_num = new_id();
98 		response->answer = announce(request, hp->h_name);
99 		return;
100 	}
101 	/* a duplicated request, so ignore it */
102 	response->id_num = ptr->id_num;
103 	response->answer = SUCCESS;
104 }
105 
106 #include <utmp.h>
107 
108 /*
109  * Search utmp for the local user
110  */
111 find_user(name, tty)
112 	char *name;
113 	char *tty;
114 {
115 	struct utmp ubuf;
116 	int fd, status;
117 	struct stat statb;
118 	char ftty[20];
119 
120 	if ((fd = open("/etc/utmp", 0)) == -1) {
121 		perror("Can't open /etc/utmp");
122 		return (FAILED);
123 	}
124 #define SCMPN(a, b)	strncmp(a, b, sizeof (a))
125 	status = NOT_HERE;
126 	(void) strcpy(ftty, "/dev/");
127 	while (read(fd, (char *) &ubuf, sizeof ubuf) == sizeof(ubuf))
128 		if (SCMPN(ubuf.ut_name, name) == 0) {
129 			if (*tty == '\0') {
130 				status = PERMISSION_DENIED;
131 				/* no particular tty was requested */
132 				(void) strcpy(ftty+5, ubuf.ut_line);
133 				if (stat(ftty,&statb) == 0) {
134 					if (!(statb.st_mode & 02))
135 						continue;
136 					(void) strcpy(tty, ubuf.ut_line);
137 					status = SUCCESS;
138 					break;
139 				}
140 			}
141 			if (strcmp(ubuf.ut_line, tty) == 0) {
142 				status = SUCCESS;
143 				break;
144 			}
145 		}
146 	close(fd);
147 	return (status);
148 }
149