xref: /csrg-svn/libexec/talkd/process.c (revision 23462)
122774Smckusick /*
222774Smckusick  * Copyright (c) 1983 Regents of the University of California.
322774Smckusick  * All rights reserved.  The Berkeley software License Agreement
422774Smckusick  * specifies the terms and conditions for redistribution.
522774Smckusick  */
622774Smckusick 
716365Skarels #ifndef lint
8*23462Sbloom static char sccsid[] = "@(#)process.c	5.2 (Berkeley) 06/08/85";
922774Smckusick #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>
21*23462Sbloom #include <stdio.h>
2216355Skarels 
2316355Skarels char *strcpy();
2416355Skarels CTL_MSG *find_request();
2516355Skarels CTL_MSG *find_match();
2616355Skarels 
2716355Skarels process_request(request, response)
2816365Skarels 	CTL_MSG *request;
2916365Skarels 	CTL_RESPONSE *response;
3016355Skarels {
3116365Skarels 	CTL_MSG *ptr;
3216355Skarels 
3316365Skarels 	response->type = request->type;
3416365Skarels 	response->id_num = 0;
3516355Skarels 
3616365Skarels 	switch (request->type) {
3716355Skarels 
3816355Skarels 	case ANNOUNCE :
3916365Skarels 		do_announce(request, response);
4016365Skarels 		break;
4116355Skarels 
4216355Skarels 	case LEAVE_INVITE :
4316365Skarels 		ptr = find_request(request);
4416365Skarels 		if (ptr != (CTL_MSG *) 0) {
4516365Skarels 			response->id_num = ptr->id_num;
4616365Skarels 			response->answer = SUCCESS;
4716365Skarels 		} else
4816365Skarels 			insert_table(request, response);
4916365Skarels 		break;
5016355Skarels 
5116355Skarels 	case LOOK_UP :
5216365Skarels 		ptr = find_match(request);
5316365Skarels 		if (ptr != (CTL_MSG *) 0) {
5416365Skarels 			response->id_num = ptr->id_num;
5516365Skarels 			response->addr = ptr->addr;
5616365Skarels 			response->answer = SUCCESS;
5716365Skarels 		} else
5816365Skarels 			response->answer = NOT_HERE;
5916365Skarels 		break;
6016355Skarels 
6116355Skarels 	case DELETE :
6216365Skarels 		response->answer = delete_invite(request->id_num);
6316365Skarels 		break;
6416355Skarels 
6516355Skarels 	default :
6616365Skarels 		response->answer = UNKNOWN_REQUEST;
6716365Skarels 		break;
6816365Skarels 	}
6916355Skarels }
7016355Skarels 
7116355Skarels struct hostent *gethostbyaddr();
7216355Skarels 
7316355Skarels do_announce(request, response)
7416365Skarels 	CTL_MSG *request;
7516365Skarels 	CTL_RESPONSE *response;
7616355Skarels {
7716365Skarels 	struct hostent *hp;
7816365Skarels 	CTL_MSG *ptr;
7916365Skarels 	int result;
8016355Skarels 
8116355Skarels 	/* see if the user is logged */
8216365Skarels 	result = find_user(request->r_name, request->r_tty);
8316365Skarels 	if (result != SUCCESS) {
8416365Skarels 		response->answer = result;
8516365Skarels 		return;
8616365Skarels 	}
8716365Skarels 	hp = gethostbyaddr(&request->ctl_addr.sin_addr,
8816365Skarels 		sizeof(struct in_addr), AF_INET);
8916365Skarels 	if (hp == (struct hostent *)0) {
9016365Skarels 		response->answer = MACHINE_UNKNOWN;
9116365Skarels 		return;
9216365Skarels 	}
9316365Skarels 	ptr = find_request(request);
9416365Skarels 	if (ptr == (CTL_MSG *) 0) {
9516365Skarels 		insert_table(request,response);
9616365Skarels 		response->answer = announce(request, hp->h_name);
9716365Skarels 		return;
9816365Skarels 	}
9916365Skarels 	if (request->id_num > ptr->id_num) {
10016365Skarels 		/*
10116365Skarels 		 * this is an explicit re-announce, so update the id_num
10216365Skarels 		 * field to avoid duplicates and re-announce the talk
10316365Skarels 		 */
10416365Skarels 		ptr->id_num = response->id_num = new_id();
10516365Skarels 		response->answer = announce(request, hp->h_name);
10616365Skarels 		return;
10716365Skarels 	}
10816365Skarels 	/* a duplicated request, so ignore it */
10916355Skarels 	response->id_num = ptr->id_num;
11016355Skarels 	response->answer = SUCCESS;
11116355Skarels }
11216355Skarels 
11316355Skarels #include <utmp.h>
11416355Skarels 
11516355Skarels /*
11616355Skarels  * Search utmp for the local user
11716355Skarels  */
11816355Skarels find_user(name, tty)
11916365Skarels 	char *name;
12016365Skarels 	char *tty;
12116355Skarels {
12216365Skarels 	struct utmp ubuf;
123*23462Sbloom 	int status;
124*23462Sbloom 	FILE *fd;
12517560Sbloom 	struct stat statb;
12617560Sbloom 	char ftty[20];
12716355Skarels 
128*23462Sbloom 	if ((fd = fopen("/etc/utmp", "r")) == NULL) {
12916365Skarels 		perror("Can't open /etc/utmp");
13016365Skarels 		return (FAILED);
13116355Skarels 	}
13216365Skarels #define SCMPN(a, b)	strncmp(a, b, sizeof (a))
13316365Skarels 	status = NOT_HERE;
13417560Sbloom 	(void) strcpy(ftty, "/dev/");
135*23462Sbloom 	while (fread((char *) &ubuf, sizeof ubuf, 1, fd) == 1)
13616365Skarels 		if (SCMPN(ubuf.ut_name, name) == 0) {
13716365Skarels 			if (*tty == '\0') {
13817560Sbloom 				status = PERMISSION_DENIED;
13916365Skarels 				/* no particular tty was requested */
14017560Sbloom 				(void) strcpy(ftty+5, ubuf.ut_line);
14117560Sbloom 				if (stat(ftty,&statb) == 0) {
14217560Sbloom 					if (!(statb.st_mode & 02))
14317560Sbloom 						continue;
14417560Sbloom 					(void) strcpy(tty, ubuf.ut_line);
14517560Sbloom 					status = SUCCESS;
14617560Sbloom 					break;
14717560Sbloom 				}
14816365Skarels 			}
14916365Skarels 			if (strcmp(ubuf.ut_line, tty) == 0) {
15016365Skarels 				status = SUCCESS;
15116365Skarels 				break;
15216365Skarels 			}
15316365Skarels 		}
154*23462Sbloom 	fclose(fd);
15516365Skarels 	return (status);
15616355Skarels }
157