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