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