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