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