xref: /csrg-svn/libexec/talkd/process.c (revision 16355)
1 /* $Header: process.c 1.5 83/03/28 20:16:07 moore Exp $ */
2 
3     /* process.c handles the requests, which can be of three types:
4 
5 		ANNOUNCE - announce to a user that a talk is wanted
6 
7 		LEAVE_INVITE - insert the request into the table
8 
9 		LOOK_UP - look up to see if a request is waiting in
10 			  in the table for the local user
11 
12 		DELETE - delete invitation
13 
14      */
15 
16 #include "ctl.h"
17 char *strcpy();
18 CTL_MSG *find_request();
19 CTL_MSG *find_match();
20 
21 process_request(request, response)
22 CTL_MSG *request;
23 CTL_RESPONSE *response;
24 {
25     CTL_MSG *ptr;
26 
27     response->type = request->type;
28     response->id_num = 0;
29 
30     switch (request->type) {
31 
32 	case ANNOUNCE :
33 
34 	    do_announce(request, response);
35 	    break;
36 
37 	case LEAVE_INVITE :
38 
39 	    ptr = find_request(request);
40 	    if (ptr != (CTL_MSG *) 0) {
41 		response->id_num = ptr->id_num;
42 		response->answer = SUCCESS;
43 	    } else {
44 		insert_table(request, response);
45 	    }
46 	    break;
47 
48 	case LOOK_UP :
49 
50 	    ptr = find_match(request);
51 	    if (ptr != (CTL_MSG *) 0) {
52 		response->id_num = ptr->id_num;
53 		response->addr = ptr->addr;
54 		response->answer = SUCCESS;
55 	    } else {
56 		response->answer = NOT_HERE;
57 	    }
58 	    break;
59 
60 	case DELETE :
61 
62 	    response->answer = delete_invite(request->id_num);
63 	    break;
64 
65 	default :
66 
67 	    response->answer = UNKNOWN_REQUEST;
68 	    break;
69 
70     }
71 }
72 
73 struct hostent *gethostbyaddr();
74 
75 do_announce(request, response)
76 CTL_MSG *request;
77 CTL_RESPONSE *response;
78 {
79     struct hostent *hp;
80     CTL_MSG *ptr;
81     int result;
82 
83 	/* see if the user is logged */
84 
85     result = find_user(request->r_name, request->r_tty);
86 
87     if (result != SUCCESS) {
88 	response->answer = result;
89 	return;
90     }
91 
92     hp = gethostbyaddr(&request->ctl_addr.sin_addr,
93 			  sizeof(struct in_addr), AF_INET);
94 
95     if ( hp == (struct hostent *) 0 ) {
96 	response->answer = MACHINE_UNKNOWN;
97 	return;
98     }
99 
100     ptr = find_request(request);
101     if (ptr == (CTL_MSG *) 0) {
102 	insert_table(request,response);
103 	response->answer = announce(request, hp->h_name);
104     } else if (request->id_num > ptr->id_num) {
105 	    /*
106 	     * this is an explicit re-announce, so update the id_num
107 	     * field to avoid duplicates and re-announce the talk
108 	     */
109 	ptr->id_num = response->id_num = new_id();
110 	response->answer = announce(request, hp->h_name);
111     } else {
112 	    /* a duplicated request, so ignore it */
113 	response->id_num = ptr->id_num;
114 	response->answer = SUCCESS;
115     }
116 
117     return;
118 }
119 
120 #include <utmp.h>
121 
122 /*
123  * Search utmp for the local user
124  */
125 
126 find_user(name, tty)
127 char *name;
128 char *tty;
129 {
130     struct utmp ubuf;
131 
132     int fd;
133 
134     if ((fd = open("/etc/utmp", 0)) == -1) {
135 	print_error("Can't open /etc/utmp");
136 	return(FAILED);
137     }
138 
139     while (read(fd, (char *) &ubuf, sizeof ubuf) == sizeof(ubuf)) {
140 	if (strncmp(ubuf.ut_name, name, sizeof ubuf.ut_name) == 0) {
141 	    if (*tty == '\0') {
142 		    /* no particular tty was requested */
143 		(void) strcpy(tty, ubuf.ut_line);
144 		close(fd);
145 		return(SUCCESS);
146 	    } else if (strcmp(ubuf.ut_line, tty) == 0) {
147 		close(fd);
148 		return(SUCCESS);
149 	    }
150 	}
151     }
152 
153     close(fd);
154     return(NOT_HERE);
155 }
156