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