xref: /csrg-svn/libexec/talkd/process.c (revision 22774)
1*22774Smckusick /*
2*22774Smckusick  * Copyright (c) 1983 Regents of the University of California.
3*22774Smckusick  * All rights reserved.  The Berkeley software License Agreement
4*22774Smckusick  * specifies the terms and conditions for redistribution.
5*22774Smckusick  */
6*22774Smckusick 
716365Skarels #ifndef lint
8*22774Smckusick static char sccsid[] = "@(#)process.c	5.1 (Berkeley) 06/07/85";
9*22774Smckusick #endif not lint
1016355Skarels 
1116365Skarels /*
1216365Skarels  * process.c handles the requests, which can be of three types:
1316365Skarels  *	ANNOUNCE - announce to a user that a talk is wanted
1416365Skarels  *	LEAVE_INVITE - insert the request into the table
1516365Skarels  *	LOOK_UP - look up to see if a request is waiting in
1616365Skarels  *		  in the table for the local user
1716365Skarels  *	DELETE - delete invitation
1816365Skarels  */
1916365Skarels #include "ctl.h"
2017560Sbloom #include <sys/stat.h>
2116355Skarels 
2216355Skarels char *strcpy();
2316355Skarels CTL_MSG *find_request();
2416355Skarels CTL_MSG *find_match();
2516355Skarels 
2616355Skarels process_request(request, response)
2716365Skarels 	CTL_MSG *request;
2816365Skarels 	CTL_RESPONSE *response;
2916355Skarels {
3016365Skarels 	CTL_MSG *ptr;
3116355Skarels 
3216365Skarels 	response->type = request->type;
3316365Skarels 	response->id_num = 0;
3416355Skarels 
3516365Skarels 	switch (request->type) {
3616355Skarels 
3716355Skarels 	case ANNOUNCE :
3816365Skarels 		do_announce(request, response);
3916365Skarels 		break;
4016355Skarels 
4116355Skarels 	case LEAVE_INVITE :
4216365Skarels 		ptr = find_request(request);
4316365Skarels 		if (ptr != (CTL_MSG *) 0) {
4416365Skarels 			response->id_num = ptr->id_num;
4516365Skarels 			response->answer = SUCCESS;
4616365Skarels 		} else
4716365Skarels 			insert_table(request, response);
4816365Skarels 		break;
4916355Skarels 
5016355Skarels 	case LOOK_UP :
5116365Skarels 		ptr = find_match(request);
5216365Skarels 		if (ptr != (CTL_MSG *) 0) {
5316365Skarels 			response->id_num = ptr->id_num;
5416365Skarels 			response->addr = ptr->addr;
5516365Skarels 			response->answer = SUCCESS;
5616365Skarels 		} else
5716365Skarels 			response->answer = NOT_HERE;
5816365Skarels 		break;
5916355Skarels 
6016355Skarels 	case DELETE :
6116365Skarels 		response->answer = delete_invite(request->id_num);
6216365Skarels 		break;
6316355Skarels 
6416355Skarels 	default :
6516365Skarels 		response->answer = UNKNOWN_REQUEST;
6616365Skarels 		break;
6716365Skarels 	}
6816355Skarels }
6916355Skarels 
7016355Skarels struct hostent *gethostbyaddr();
7116355Skarels 
7216355Skarels do_announce(request, response)
7316365Skarels 	CTL_MSG *request;
7416365Skarels 	CTL_RESPONSE *response;
7516355Skarels {
7616365Skarels 	struct hostent *hp;
7716365Skarels 	CTL_MSG *ptr;
7816365Skarels 	int result;
7916355Skarels 
8016355Skarels 	/* see if the user is logged */
8116365Skarels 	result = find_user(request->r_name, request->r_tty);
8216365Skarels 	if (result != SUCCESS) {
8316365Skarels 		response->answer = result;
8416365Skarels 		return;
8516365Skarels 	}
8616365Skarels 	hp = gethostbyaddr(&request->ctl_addr.sin_addr,
8716365Skarels 		sizeof(struct in_addr), AF_INET);
8816365Skarels 	if (hp == (struct hostent *)0) {
8916365Skarels 		response->answer = MACHINE_UNKNOWN;
9016365Skarels 		return;
9116365Skarels 	}
9216365Skarels 	ptr = find_request(request);
9316365Skarels 	if (ptr == (CTL_MSG *) 0) {
9416365Skarels 		insert_table(request,response);
9516365Skarels 		response->answer = announce(request, hp->h_name);
9616365Skarels 		return;
9716365Skarels 	}
9816365Skarels 	if (request->id_num > ptr->id_num) {
9916365Skarels 		/*
10016365Skarels 		 * this is an explicit re-announce, so update the id_num
10116365Skarels 		 * field to avoid duplicates and re-announce the talk
10216365Skarels 		 */
10316365Skarels 		ptr->id_num = response->id_num = new_id();
10416365Skarels 		response->answer = announce(request, hp->h_name);
10516365Skarels 		return;
10616365Skarels 	}
10716365Skarels 	/* a duplicated request, so ignore it */
10816355Skarels 	response->id_num = ptr->id_num;
10916355Skarels 	response->answer = SUCCESS;
11016355Skarels }
11116355Skarels 
11216355Skarels #include <utmp.h>
11316355Skarels 
11416355Skarels /*
11516355Skarels  * Search utmp for the local user
11616355Skarels  */
11716355Skarels find_user(name, tty)
11816365Skarels 	char *name;
11916365Skarels 	char *tty;
12016355Skarels {
12116365Skarels 	struct utmp ubuf;
12216365Skarels 	int fd, status;
12317560Sbloom 	struct stat statb;
12417560Sbloom 	char ftty[20];
12516355Skarels 
12616365Skarels 	if ((fd = open("/etc/utmp", 0)) == -1) {
12716365Skarels 		perror("Can't open /etc/utmp");
12816365Skarels 		return (FAILED);
12916355Skarels 	}
13016365Skarels #define SCMPN(a, b)	strncmp(a, b, sizeof (a))
13116365Skarels 	status = NOT_HERE;
13217560Sbloom 	(void) strcpy(ftty, "/dev/");
13316365Skarels 	while (read(fd, (char *) &ubuf, sizeof ubuf) == sizeof(ubuf))
13416365Skarels 		if (SCMPN(ubuf.ut_name, name) == 0) {
13516365Skarels 			if (*tty == '\0') {
13617560Sbloom 				status = PERMISSION_DENIED;
13716365Skarels 				/* no particular tty was requested */
13817560Sbloom 				(void) strcpy(ftty+5, ubuf.ut_line);
13917560Sbloom 				if (stat(ftty,&statb) == 0) {
14017560Sbloom 					if (!(statb.st_mode & 02))
14117560Sbloom 						continue;
14217560Sbloom 					(void) strcpy(tty, ubuf.ut_line);
14317560Sbloom 					status = SUCCESS;
14417560Sbloom 					break;
14517560Sbloom 				}
14616365Skarels 			}
14716365Skarels 			if (strcmp(ubuf.ut_line, tty) == 0) {
14816365Skarels 				status = SUCCESS;
14916365Skarels 				break;
15016365Skarels 			}
15116365Skarels 		}
15216365Skarels 	close(fd);
15316365Skarels 	return (status);
15416355Skarels }
155