xref: /csrg-svn/libexec/talkd/process.c (revision 17560)
116365Skarels #ifndef lint
2*17560Sbloom static char sccsid[] = "@(#)process.c	1.3 (Berkeley) 12/20/84";
316365Skarels #endif
416355Skarels 
516365Skarels /*
616365Skarels  * process.c handles the requests, which can be of three types:
716365Skarels  *	ANNOUNCE - announce to a user that a talk is wanted
816365Skarels  *	LEAVE_INVITE - insert the request into the table
916365Skarels  *	LOOK_UP - look up to see if a request is waiting in
1016365Skarels  *		  in the table for the local user
1116365Skarels  *	DELETE - delete invitation
1216365Skarels  */
1316365Skarels #include "ctl.h"
14*17560Sbloom #include <sys/stat.h>
1516355Skarels 
1616355Skarels char *strcpy();
1716355Skarels CTL_MSG *find_request();
1816355Skarels CTL_MSG *find_match();
1916355Skarels 
2016355Skarels process_request(request, response)
2116365Skarels 	CTL_MSG *request;
2216365Skarels 	CTL_RESPONSE *response;
2316355Skarels {
2416365Skarels 	CTL_MSG *ptr;
2516355Skarels 
2616365Skarels 	response->type = request->type;
2716365Skarels 	response->id_num = 0;
2816355Skarels 
2916365Skarels 	switch (request->type) {
3016355Skarels 
3116355Skarels 	case ANNOUNCE :
3216365Skarels 		do_announce(request, response);
3316365Skarels 		break;
3416355Skarels 
3516355Skarels 	case LEAVE_INVITE :
3616365Skarels 		ptr = find_request(request);
3716365Skarels 		if (ptr != (CTL_MSG *) 0) {
3816365Skarels 			response->id_num = ptr->id_num;
3916365Skarels 			response->answer = SUCCESS;
4016365Skarels 		} else
4116365Skarels 			insert_table(request, response);
4216365Skarels 		break;
4316355Skarels 
4416355Skarels 	case LOOK_UP :
4516365Skarels 		ptr = find_match(request);
4616365Skarels 		if (ptr != (CTL_MSG *) 0) {
4716365Skarels 			response->id_num = ptr->id_num;
4816365Skarels 			response->addr = ptr->addr;
4916365Skarels 			response->answer = SUCCESS;
5016365Skarels 		} else
5116365Skarels 			response->answer = NOT_HERE;
5216365Skarels 		break;
5316355Skarels 
5416355Skarels 	case DELETE :
5516365Skarels 		response->answer = delete_invite(request->id_num);
5616365Skarels 		break;
5716355Skarels 
5816355Skarels 	default :
5916365Skarels 		response->answer = UNKNOWN_REQUEST;
6016365Skarels 		break;
6116365Skarels 	}
6216355Skarels }
6316355Skarels 
6416355Skarels struct hostent *gethostbyaddr();
6516355Skarels 
6616355Skarels do_announce(request, response)
6716365Skarels 	CTL_MSG *request;
6816365Skarels 	CTL_RESPONSE *response;
6916355Skarels {
7016365Skarels 	struct hostent *hp;
7116365Skarels 	CTL_MSG *ptr;
7216365Skarels 	int result;
7316355Skarels 
7416355Skarels 	/* see if the user is logged */
7516365Skarels 	result = find_user(request->r_name, request->r_tty);
7616365Skarels 	if (result != SUCCESS) {
7716365Skarels 		response->answer = result;
7816365Skarels 		return;
7916365Skarels 	}
8016365Skarels 	hp = gethostbyaddr(&request->ctl_addr.sin_addr,
8116365Skarels 		sizeof(struct in_addr), AF_INET);
8216365Skarels 	if (hp == (struct hostent *)0) {
8316365Skarels 		response->answer = MACHINE_UNKNOWN;
8416365Skarels 		return;
8516365Skarels 	}
8616365Skarels 	ptr = find_request(request);
8716365Skarels 	if (ptr == (CTL_MSG *) 0) {
8816365Skarels 		insert_table(request,response);
8916365Skarels 		response->answer = announce(request, hp->h_name);
9016365Skarels 		return;
9116365Skarels 	}
9216365Skarels 	if (request->id_num > ptr->id_num) {
9316365Skarels 		/*
9416365Skarels 		 * this is an explicit re-announce, so update the id_num
9516365Skarels 		 * field to avoid duplicates and re-announce the talk
9616365Skarels 		 */
9716365Skarels 		ptr->id_num = response->id_num = new_id();
9816365Skarels 		response->answer = announce(request, hp->h_name);
9916365Skarels 		return;
10016365Skarels 	}
10116365Skarels 	/* a duplicated request, so ignore it */
10216355Skarels 	response->id_num = ptr->id_num;
10316355Skarels 	response->answer = SUCCESS;
10416355Skarels }
10516355Skarels 
10616355Skarels #include <utmp.h>
10716355Skarels 
10816355Skarels /*
10916355Skarels  * Search utmp for the local user
11016355Skarels  */
11116355Skarels find_user(name, tty)
11216365Skarels 	char *name;
11316365Skarels 	char *tty;
11416355Skarels {
11516365Skarels 	struct utmp ubuf;
11616365Skarels 	int fd, status;
117*17560Sbloom 	struct stat statb;
118*17560Sbloom 	char ftty[20];
11916355Skarels 
12016365Skarels 	if ((fd = open("/etc/utmp", 0)) == -1) {
12116365Skarels 		perror("Can't open /etc/utmp");
12216365Skarels 		return (FAILED);
12316355Skarels 	}
12416365Skarels #define SCMPN(a, b)	strncmp(a, b, sizeof (a))
12516365Skarels 	status = NOT_HERE;
126*17560Sbloom 	(void) strcpy(ftty, "/dev/");
12716365Skarels 	while (read(fd, (char *) &ubuf, sizeof ubuf) == sizeof(ubuf))
12816365Skarels 		if (SCMPN(ubuf.ut_name, name) == 0) {
12916365Skarels 			if (*tty == '\0') {
130*17560Sbloom 				status = PERMISSION_DENIED;
13116365Skarels 				/* no particular tty was requested */
132*17560Sbloom 				(void) strcpy(ftty+5, ubuf.ut_line);
133*17560Sbloom 				if (stat(ftty,&statb) == 0) {
134*17560Sbloom 					if (!(statb.st_mode & 02))
135*17560Sbloom 						continue;
136*17560Sbloom 					(void) strcpy(tty, ubuf.ut_line);
137*17560Sbloom 					status = SUCCESS;
138*17560Sbloom 					break;
139*17560Sbloom 				}
14016365Skarels 			}
14116365Skarels 			if (strcmp(ubuf.ut_line, tty) == 0) {
14216365Skarels 				status = SUCCESS;
14316365Skarels 				break;
14416365Skarels 			}
14516365Skarels 		}
14616365Skarels 	close(fd);
14716365Skarels 	return (status);
14816355Skarels }
149