xref: /csrg-svn/libexec/talkd/process.c (revision 26839)
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*26839Smckusick static char sccsid[] = "@(#)process.c	5.3 (Berkeley) 03/13/86";
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  */
19*26839Smckusick #include <sys/types.h>
2017560Sbloom #include <sys/stat.h>
2123462Sbloom #include <stdio.h>
22*26839Smckusick #include <syslog.h>
23*26839Smckusick #include <netdb.h>
24*26839Smckusick #include <netinet/in.h>
2516355Skarels 
26*26839Smckusick #include <protocols/talkd.h>
27*26839Smckusick 
28*26839Smckusick char	*strcpy();
2916355Skarels CTL_MSG *find_request();
3016355Skarels CTL_MSG *find_match();
3116355Skarels 
32*26839Smckusick process_request(mp, rp)
33*26839Smckusick 	register CTL_MSG *mp;
34*26839Smckusick 	register CTL_RESPONSE *rp;
3516355Skarels {
36*26839Smckusick 	register CTL_MSG *ptr;
37*26839Smckusick 	extern int debug;
3816355Skarels 
39*26839Smckusick 	rp->vers = TALK_VERSION;
40*26839Smckusick 	rp->type = mp->type;
41*26839Smckusick 	rp->id_num = htonl(0);
42*26839Smckusick 	if (mp->vers != TALK_VERSION) {
43*26839Smckusick 		syslog(LOG_WARNING, "Bad protocol version %d", mp->vers);
44*26839Smckusick 		rp->answer = BADVERSION;
45*26839Smckusick 		return;
46*26839Smckusick 	}
47*26839Smckusick 	mp->id_num = ntohl(mp->id_num);
48*26839Smckusick 	mp->addr.sa_family = ntohs(mp->addr.sa_family);
49*26839Smckusick 	if (mp->addr.sa_family != AF_INET) {
50*26839Smckusick 		syslog(LOG_WARNING, "Bad address, family %d",
51*26839Smckusick 		    mp->addr.sa_family);
52*26839Smckusick 		rp->answer = BADADDR;
53*26839Smckusick 		return;
54*26839Smckusick 	}
55*26839Smckusick 	mp->ctl_addr.sa_family = ntohs(mp->ctl_addr.sa_family);
56*26839Smckusick 	if (mp->ctl_addr.sa_family != AF_INET) {
57*26839Smckusick 		syslog(LOG_WARNING, "Bad control address, family %d",
58*26839Smckusick 		    mp->ctl_addr.sa_family);
59*26839Smckusick 		rp->answer = BADCTLADDR;
60*26839Smckusick 		return;
61*26839Smckusick 	}
62*26839Smckusick 	mp->pid = ntohl(mp->pid);
63*26839Smckusick 	if (debug)
64*26839Smckusick 		print_request("process_request", mp);
65*26839Smckusick 	switch (mp->type) {
6616355Skarels 
67*26839Smckusick 	case ANNOUNCE:
68*26839Smckusick 		do_announce(mp, rp);
6916365Skarels 		break;
7016355Skarels 
71*26839Smckusick 	case LEAVE_INVITE:
72*26839Smckusick 		ptr = find_request(mp);
73*26839Smckusick 		if (ptr != (CTL_MSG *)0) {
74*26839Smckusick 			rp->id_num = htonl(ptr->id_num);
75*26839Smckusick 			rp->answer = SUCCESS;
7616365Skarels 		} else
77*26839Smckusick 			insert_table(mp, rp);
7816365Skarels 		break;
7916355Skarels 
80*26839Smckusick 	case LOOK_UP:
81*26839Smckusick 		ptr = find_match(mp);
82*26839Smckusick 		if (ptr != (CTL_MSG *)0) {
83*26839Smckusick 			rp->id_num = htonl(ptr->id_num);
84*26839Smckusick 			rp->addr = ptr->addr;
85*26839Smckusick 			rp->addr.sa_family = htons(ptr->addr.sa_family);
86*26839Smckusick 			rp->answer = SUCCESS;
8716365Skarels 		} else
88*26839Smckusick 			rp->answer = NOT_HERE;
8916365Skarels 		break;
9016355Skarels 
91*26839Smckusick 	case DELETE:
92*26839Smckusick 		rp->answer = delete_invite(mp->id_num);
9316365Skarels 		break;
9416355Skarels 
95*26839Smckusick 	default:
96*26839Smckusick 		rp->answer = UNKNOWN_REQUEST;
9716365Skarels 		break;
9816365Skarels 	}
99*26839Smckusick 	if (debug)
100*26839Smckusick 		print_response("process_request", rp);
10116355Skarels }
10216355Skarels 
103*26839Smckusick do_announce(mp, rp)
104*26839Smckusick 	register CTL_MSG *mp;
105*26839Smckusick 	CTL_RESPONSE *rp;
10616355Skarels {
10716365Skarels 	struct hostent *hp;
10816365Skarels 	CTL_MSG *ptr;
10916365Skarels 	int result;
11016355Skarels 
11116355Skarels 	/* see if the user is logged */
112*26839Smckusick 	result = find_user(mp->r_name, mp->r_tty);
11316365Skarels 	if (result != SUCCESS) {
114*26839Smckusick 		rp->answer = result;
11516365Skarels 		return;
11616365Skarels 	}
117*26839Smckusick #define	satosin(sa)	((struct sockaddr_in *)(sa))
118*26839Smckusick 	hp = gethostbyaddr(&satosin(&mp->ctl_addr)->sin_addr,
119*26839Smckusick 		sizeof (struct in_addr), AF_INET);
12016365Skarels 	if (hp == (struct hostent *)0) {
121*26839Smckusick 		rp->answer = MACHINE_UNKNOWN;
12216365Skarels 		return;
12316365Skarels 	}
124*26839Smckusick 	ptr = find_request(mp);
12516365Skarels 	if (ptr == (CTL_MSG *) 0) {
126*26839Smckusick 		insert_table(mp, rp);
127*26839Smckusick 		rp->answer = announce(mp, hp->h_name);
12816365Skarels 		return;
12916365Skarels 	}
130*26839Smckusick 	if (mp->id_num > ptr->id_num) {
13116365Skarels 		/*
132*26839Smckusick 		 * This is an explicit re-announce, so update the id_num
133*26839Smckusick 		 * field to avoid duplicates and re-announce the talk.
13416365Skarels 		 */
135*26839Smckusick 		ptr->id_num = new_id();
136*26839Smckusick 		rp->id_num = htonl(ptr->id_num);
137*26839Smckusick 		rp->answer = announce(mp, hp->h_name);
138*26839Smckusick 	} else {
139*26839Smckusick 		/* a duplicated request, so ignore it */
140*26839Smckusick 		rp->id_num = htonl(ptr->id_num);
141*26839Smckusick 		rp->answer = SUCCESS;
14216365Skarels 	}
14316355Skarels }
14416355Skarels 
14516355Skarels #include <utmp.h>
14616355Skarels 
14716355Skarels /*
14816355Skarels  * Search utmp for the local user
14916355Skarels  */
15016355Skarels find_user(name, tty)
151*26839Smckusick 	char *name, *tty;
15216355Skarels {
15316365Skarels 	struct utmp ubuf;
15423462Sbloom 	int status;
15523462Sbloom 	FILE *fd;
15617560Sbloom 	struct stat statb;
15717560Sbloom 	char ftty[20];
15816355Skarels 
15923462Sbloom 	if ((fd = fopen("/etc/utmp", "r")) == NULL) {
16016365Skarels 		perror("Can't open /etc/utmp");
16116365Skarels 		return (FAILED);
16216355Skarels 	}
16316365Skarels #define SCMPN(a, b)	strncmp(a, b, sizeof (a))
16416365Skarels 	status = NOT_HERE;
16517560Sbloom 	(void) strcpy(ftty, "/dev/");
16623462Sbloom 	while (fread((char *) &ubuf, sizeof ubuf, 1, fd) == 1)
16716365Skarels 		if (SCMPN(ubuf.ut_name, name) == 0) {
16816365Skarels 			if (*tty == '\0') {
16917560Sbloom 				status = PERMISSION_DENIED;
17016365Skarels 				/* no particular tty was requested */
17117560Sbloom 				(void) strcpy(ftty+5, ubuf.ut_line);
17217560Sbloom 				if (stat(ftty,&statb) == 0) {
17317560Sbloom 					if (!(statb.st_mode & 02))
17417560Sbloom 						continue;
17517560Sbloom 					(void) strcpy(tty, ubuf.ut_line);
17617560Sbloom 					status = SUCCESS;
17717560Sbloom 					break;
17817560Sbloom 				}
17916365Skarels 			}
18016365Skarels 			if (strcmp(ubuf.ut_line, tty) == 0) {
18116365Skarels 				status = SUCCESS;
18216365Skarels 				break;
18316365Skarels 			}
18416365Skarels 		}
18523462Sbloom 	fclose(fd);
18616365Skarels 	return (status);
18716355Skarels }
188