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