source: trunk/third/talk/talkd/process.c @ 17609

Revision 17609, 5.9 KB checked in by zacheiss, 23 years ago (diff)
Need to endutent() in case we end up call getutent() again before we exit.
Line 
1/*
2 * Copyright (c) 1983 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 *    must display the following acknowledgement:
15 *      This product includes software developed by the University of
16 *      California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#ifndef lint
35/*static char sccsid[] = "from: @(#)process.c   5.10 (Berkeley) 2/26/91";*/
36static char rcsid[] = "$Id: process.c,v 1.6 2002-05-24 18:37:50 zacheiss Exp $";
37#endif /* not lint */
38
39/*
40 * process.c handles the requests, which can be of three types:
41 *      ANNOUNCE - announce to a user that a talk is wanted
42 *      LEAVE_INVITE - insert the request into the table
43 *      LOOK_UP - look up to see if a request is waiting in
44 *                in the table for the local user
45 *      DELETE - delete invitation
46 */
47#include <sys/param.h>
48#include <sys/stat.h>
49#include <sys/socket.h>
50#include <netinet/in.h>
51#include <protocols/talkd.h>
52#include <netdb.h>
53#include <syslog.h>
54#include <stdio.h>
55#include <string.h>
56#ifdef HAVE_PATHS_H
57#include <paths.h>
58#endif
59#ifndef _PATH_DEV
60#define _PATH_DEV "/dev/"
61#endif
62
63CTL_MSG *find_request();
64CTL_MSG *find_match();
65
66process_request(mp, rp)
67        register CTL_MSG *mp;
68        register CTL_RESPONSE *rp;
69{
70        register CTL_MSG *ptr;
71        extern int debug;
72
73        rp->vers = TALK_VERSION;
74        rp->type = mp->type;
75        rp->id_num = htonl(0);
76        if (mp->vers != TALK_VERSION) {
77                syslog(LOG_WARNING, "Bad protocol version %d", mp->vers);
78                rp->answer = BADVERSION;
79                return;
80        }
81        mp->id_num = ntohl(mp->id_num);
82        mp->addr.family = ntohs(mp->addr.family);
83        if (mp->addr.family != AF_INET) {
84                syslog(LOG_WARNING, "Bad address, family %d",
85                    mp->addr.family);
86                rp->answer = BADADDR;
87                return;
88        }
89        mp->ctl_addr.family = ntohs(mp->ctl_addr.family);
90        if (mp->ctl_addr.family != AF_INET) {
91                syslog(LOG_WARNING, "Bad control address, family %d",
92                    mp->ctl_addr.family);
93                rp->answer = BADCTLADDR;
94                return;
95        }
96        mp->pid = ntohl(mp->pid);
97        if (debug)
98                print_request("process_request", mp);
99        switch (mp->type) {
100
101        case ANNOUNCE:
102                do_announce(mp, rp);
103                break;
104
105        case LEAVE_INVITE:
106                ptr = find_request(mp);
107                if (ptr != (CTL_MSG *)0) {
108                        rp->id_num = htonl(ptr->id_num);
109                        rp->answer = SUCCESS;
110                } else
111                        insert_table(mp, rp);
112                break;
113
114        case LOOK_UP:
115                ptr = find_match(mp);
116                if (ptr != (CTL_MSG *)0) {
117                        rp->id_num = htonl(ptr->id_num);
118                        rp->addr = ptr->addr;
119                        rp->addr.family = htons(ptr->addr.family);
120                        rp->answer = SUCCESS;
121                } else
122                        rp->answer = NOT_HERE;
123                break;
124
125        case DELETE:
126                rp->answer = delete_invite(mp->id_num);
127                break;
128
129        default:
130                rp->answer = UNKNOWN_REQUEST;
131                break;
132        }
133        if (debug)
134                print_response("process_request", rp);
135}
136
137do_announce(mp, rp)
138        register CTL_MSG *mp;
139        CTL_RESPONSE *rp;
140{
141        struct hostent *hp;
142        CTL_MSG *ptr;
143        int result;
144
145        /* see if the user is logged */
146        result = find_user(mp->r_name, mp->r_tty);
147        if (result != SUCCESS) {
148                rp->answer = result;
149                return;
150        }
151#define satosin(sa)     ((struct sockaddr_in *)(sa))
152        hp = gethostbyaddr((char *)&satosin(&mp->ctl_addr)->sin_addr,
153                sizeof (struct in_addr), AF_INET);
154        if (hp == (struct hostent *)0) {
155                rp->answer = MACHINE_UNKNOWN;
156                return;
157        }
158        ptr = find_request(mp);
159        if (ptr == (CTL_MSG *) 0) {
160                insert_table(mp, rp);
161                rp->answer = announce(mp, hp->h_name);
162                return;
163        }
164        if (mp->id_num > ptr->id_num) {
165                /*
166                 * This is an explicit re-announce, so update the id_num
167                 * field to avoid duplicates and re-announce the talk.
168                 */
169                ptr->id_num = new_id();
170                rp->id_num = htonl(ptr->id_num);
171                rp->answer = announce(mp, hp->h_name);
172        } else {
173                /* a duplicated request, so ignore it */
174                rp->id_num = htonl(ptr->id_num);
175                rp->answer = SUCCESS;
176        }
177}
178
179#include <utmp.h>
180
181/*
182 * Search utmp for the local user
183 */
184find_user(name, tty)
185        char *name, *tty;
186{
187        struct utmp *uptr;
188        int status;
189        struct stat statb;
190        char ftty[20];
191
192#define SCMPN(a, b)     strncmp(a, b, sizeof (a))
193        status = NOT_HERE;
194        (void) strcpy(ftty, _PATH_DEV);
195        while ((uptr = getutent()) != NULL) {
196#ifdef USER_PROCESS
197                if (uptr->ut_type != USER_PROCESS)
198                        continue;
199#endif
200                if (SCMPN(uptr->ut_name, name) == 0) {
201                        if (*tty == '\0') {
202                                status = PERMISSION_DENIED;
203                                /* no particular tty was requested */
204                                (void) strcpy(ftty+5, uptr->ut_line);
205                                if (stat(ftty,&statb) == 0) {
206                                        if (!(statb.st_mode & 020))
207                                                continue;
208                                        (void) strcpy(tty, uptr->ut_line);
209                                        status = SUCCESS;
210                                        break;
211                                }
212                        }
213                        if (strcmp(uptr->ut_line, tty) == 0) {
214                                status = SUCCESS;
215                                break;
216                        }
217                }
218        }
219        endutent();
220        return (status);
221}
Note: See TracBrowser for help on using the repository browser.