xref: /csrg-svn/old/talk/talkd/process.c (revision 66683)
1*66683Sbostic /*-
2*66683Sbostic  * Copyright (c) 1983, 1985
3*66683Sbostic  *	The Regents of the University of California.  All rights reserved.
4*66683Sbostic  *
5*66683Sbostic  * %sccs.include.redist.c%
656577Sbostic  */
756577Sbostic 
856577Sbostic #ifndef lint
956577Sbostic static char sccsid[] = "@(#)process.c	5.2 (Berkeley) 6/8/85";
1056577Sbostic #endif not lint
1156577Sbostic 
1256577Sbostic /*
1356577Sbostic  * process.c handles the requests, which can be of three types:
1456577Sbostic  *	ANNOUNCE - announce to a user that a talk is wanted
1556577Sbostic  *	LEAVE_INVITE - insert the request into the table
1656577Sbostic  *	LOOK_UP - look up to see if a request is waiting in
1756577Sbostic  *		  in the table for the local user
1856577Sbostic  *	DELETE - delete invitation
1956577Sbostic  */
2056577Sbostic #include "ctl.h"
2156577Sbostic #include <sys/stat.h>
2256577Sbostic #include <stdio.h>
2356577Sbostic 
2456577Sbostic char *strcpy();
2556577Sbostic CTL_MSG *find_request();
2656577Sbostic CTL_MSG *find_match();
2756577Sbostic 
process_request(request,response)2856577Sbostic process_request(request, response)
2956577Sbostic 	CTL_MSG *request;
3056577Sbostic 	CTL_RESPONSE *response;
3156577Sbostic {
3256577Sbostic 	CTL_MSG *ptr;
3356577Sbostic 
3456577Sbostic 	response->type = request->type;
3556577Sbostic 	response->id_num = 0;
3656577Sbostic 
3756577Sbostic 	switch (request->type) {
3856577Sbostic 
3956577Sbostic 	case ANNOUNCE :
4056577Sbostic 		do_announce(request, response);
4156577Sbostic 		break;
4256577Sbostic 
4356577Sbostic 	case LEAVE_INVITE :
4456577Sbostic 		ptr = find_request(request);
4556577Sbostic 		if (ptr != (CTL_MSG *) 0) {
4656577Sbostic 			response->id_num = ptr->id_num;
4756577Sbostic 			response->answer = SUCCESS;
4856577Sbostic 		} else
4956577Sbostic 			insert_table(request, response);
5056577Sbostic 		break;
5156577Sbostic 
5256577Sbostic 	case LOOK_UP :
5356577Sbostic 		ptr = find_match(request);
5456577Sbostic 		if (ptr != (CTL_MSG *) 0) {
5556577Sbostic 			response->id_num = ptr->id_num;
5656577Sbostic 			response->addr = ptr->addr;
5756577Sbostic 			response->answer = SUCCESS;
5856577Sbostic 		} else
5956577Sbostic 			response->answer = NOT_HERE;
6056577Sbostic 		break;
6156577Sbostic 
6256577Sbostic 	case DELETE :
6356577Sbostic 		response->answer = delete_invite(request->id_num);
6456577Sbostic 		break;
6556577Sbostic 
6656577Sbostic 	default :
6756577Sbostic 		response->answer = UNKNOWN_REQUEST;
6856577Sbostic 		break;
6956577Sbostic 	}
7056577Sbostic }
7156577Sbostic 
7256577Sbostic struct hostent *gethostbyaddr();
7356577Sbostic 
do_announce(request,response)7456577Sbostic do_announce(request, response)
7556577Sbostic 	CTL_MSG *request;
7656577Sbostic 	CTL_RESPONSE *response;
7756577Sbostic {
7856577Sbostic 	struct hostent *hp;
7956577Sbostic 	CTL_MSG *ptr;
8056577Sbostic 	int result;
8156577Sbostic 
8256577Sbostic 	/* see if the user is logged */
8356577Sbostic 	result = find_user(request->r_name, request->r_tty);
8456577Sbostic 	if (result != SUCCESS) {
8556577Sbostic 		response->answer = result;
8656577Sbostic 		return;
8756577Sbostic 	}
8856579Sbostic 	hp = gethostbyaddr((char *)&request->ctl_addr.sin_addr,
8956577Sbostic 		sizeof(struct in_addr), AF_INET);
9056577Sbostic 	if (hp == (struct hostent *)0) {
9156577Sbostic 		response->answer = MACHINE_UNKNOWN;
9256577Sbostic 		return;
9356577Sbostic 	}
9456577Sbostic 	ptr = find_request(request);
9556577Sbostic 	if (ptr == (CTL_MSG *) 0) {
9656577Sbostic 		insert_table(request,response);
9756577Sbostic 		response->answer = announce(request, hp->h_name);
9856577Sbostic 		return;
9956577Sbostic 	}
10056577Sbostic 	if (request->id_num > ptr->id_num) {
10156577Sbostic 		/*
10256577Sbostic 		 * this is an explicit re-announce, so update the id_num
10356577Sbostic 		 * field to avoid duplicates and re-announce the talk
10456577Sbostic 		 */
10556577Sbostic 		ptr->id_num = response->id_num = new_id();
10656577Sbostic 		response->answer = announce(request, hp->h_name);
10756577Sbostic 		return;
10856577Sbostic 	}
10956577Sbostic 	/* a duplicated request, so ignore it */
11056577Sbostic 	response->id_num = ptr->id_num;
11156577Sbostic 	response->answer = SUCCESS;
11256577Sbostic }
11356577Sbostic 
11456577Sbostic #include <utmp.h>
11556577Sbostic 
11656577Sbostic /*
11756577Sbostic  * Search utmp for the local user
11856577Sbostic  */
find_user(name,tty)11956577Sbostic find_user(name, tty)
12056577Sbostic 	char *name;
12156577Sbostic 	char *tty;
12256577Sbostic {
12356577Sbostic 	struct utmp ubuf;
12456577Sbostic 	int status;
12556577Sbostic 	FILE *fd;
12656577Sbostic 	struct stat statb;
12756577Sbostic 	char ftty[20];
12856577Sbostic 
12956577Sbostic 	if ((fd = fopen("/etc/utmp", "r")) == NULL) {
13056577Sbostic 		perror("Can't open /etc/utmp");
13156577Sbostic 		return (FAILED);
13256577Sbostic 	}
13356577Sbostic #define SCMPN(a, b)	strncmp(a, b, sizeof (a))
13456577Sbostic 	status = NOT_HERE;
13556577Sbostic 	(void) strcpy(ftty, "/dev/");
13656577Sbostic 	while (fread((char *) &ubuf, sizeof ubuf, 1, fd) == 1)
13756577Sbostic 		if (SCMPN(ubuf.ut_name, name) == 0) {
13856577Sbostic 			if (*tty == '\0') {
13956577Sbostic 				status = PERMISSION_DENIED;
14056577Sbostic 				/* no particular tty was requested */
14156577Sbostic 				(void) strcpy(ftty+5, ubuf.ut_line);
14256577Sbostic 				if (stat(ftty,&statb) == 0) {
14356577Sbostic 					if (!(statb.st_mode & 020))
14456577Sbostic 						continue;
14556577Sbostic 					(void) strcpy(tty, ubuf.ut_line);
14656577Sbostic 					status = SUCCESS;
14756577Sbostic 					break;
14856577Sbostic 				}
14956577Sbostic 			}
15056577Sbostic 			if (strcmp(ubuf.ut_line, tty) == 0) {
15156577Sbostic 				status = SUCCESS;
15256577Sbostic 				break;
15356577Sbostic 			}
15456577Sbostic 		}
15556577Sbostic 	fclose(fd);
15656577Sbostic 	return (status);
15756577Sbostic }
158