4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
21 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
22 * Use is subject to license terms.
26 * Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T
27 * All Rights Reserved.
31 * University Copyright- Copyright (c) 1982, 1986, 1988
32 * The Regents of the University of California.
33 * All Rights Reserved.
35 * University Acknowledgment- Portions of this document are derived from
36 * software developed by the University of California, Berkeley, and its
40 #pragma ident "%Z%%M% %I% %E% SMI"
44 * process.c handles the requests, which can be of three types:
46 * ANNOUNCE - announce to a user that a talk is wanted
48 * LEAVE_INVITE - insert the request into the table
50 * LOOK_UP - look up to see if a request is waiting in
51 * in the table for the local user
53 * DELETE - delete invitation
57 #include <sys/types.h>
59 #include <sys/param.h>
67 #include "talkd_impl.h"
69 static void do_announce(CTL_MSG
*request
, CTL_RESPONSE
*response
);
70 static int find_user(char *name
, char *tty
);
73 process_request(CTL_MSG
*request
, CTL_RESPONSE
*response
)
77 response
->type
= request
->type
;
81 * Check if any of the strings within the request structure aren't
82 * NUL terminated, and if so don't bother processing the request
85 if ((memchr(request
->l_name
, '\0', sizeof (request
->l_name
)) == NULL
) ||
86 (memchr(request
->r_name
, '\0', sizeof (request
->r_name
)) == NULL
) ||
87 (memchr(request
->r_tty
, '\0', sizeof (request
->r_tty
)) == NULL
)) {
88 response
->answer
= FAILED
;
89 openlog("talk", 0, LOG_AUTH
);
90 syslog(LOG_CRIT
, "malformed talk request\n");
95 switch (request
->type
) {
99 do_announce(request
, response
);
104 ptr
= find_request(request
);
106 response
->id_num
= ptr
->id_num
;
107 response
->answer
= SUCCESS
;
109 insert_table(request
, response
);
115 ptr
= find_match(request
);
117 response
->id_num
= ptr
->id_num
;
118 response
->addr
= ptr
->addr
;
119 response
->answer
= SUCCESS
;
121 response
->answer
= NOT_HERE
;
127 response
->answer
= delete_invite(request
->id_num
);
132 response
->answer
= UNKNOWN_REQUEST
;
138 do_announce(CTL_MSG
*request
, CTL_RESPONSE
*response
)
145 * See if the user is logged.
147 result
= find_user(request
->r_name
, request
->r_tty
);
148 if (result
!= SUCCESS
) {
149 response
->answer
= result
;
153 hp
= gethostbyaddr((const char *)&request
->ctl_addr
.sin_addr
,
154 sizeof (struct in_addr
), AF_INET
);
156 response
->answer
= MACHINE_UNKNOWN
;
160 ptr
= find_request(request
);
162 insert_table(request
, response
);
163 response
->answer
= announce(request
, hp
->h_name
);
164 } else if (request
->id_num
> ptr
->id_num
) {
166 * This is an explicit re-announce, so update the id_num
167 * field to avoid duplicates and re-announce the talk.
169 ptr
->id_num
= response
->id_num
= new_id();
170 response
->answer
= announce(request
, hp
->h_name
);
172 /* a duplicated request, so ignore it */
173 response
->id_num
= ptr
->id_num
;
174 response
->answer
= SUCCESS
;
179 * Search utmp for the local user.
183 find_user(char *name
, char *tty
)
187 char dev
[MAXPATHLEN
];
189 int problem
= NOT_HERE
;
191 setutxent(); /* reset the utmpx file */
193 while (ubuf
= getutxent()) {
194 if (ubuf
->ut_type
== USER_PROCESS
&&
195 strncmp(ubuf
->ut_user
, name
, sizeof (ubuf
->ut_user
)) == 0) {
197 * Check if this entry is really a tty.
199 (void) snprintf(dev
, sizeof (dev
), "/dev/%.*s",
200 sizeof (ubuf
->ut_line
), ubuf
->ut_line
);
201 if ((tfd
= open(dev
, O_WRONLY
|O_NOCTTY
)) == -1) {
206 openlog("talk", 0, LOG_AUTH
);
207 syslog(LOG_CRIT
, "%.*s in utmp is not a tty\n",
208 sizeof (ubuf
->ut_line
), ubuf
->ut_line
);
214 * No particular tty was requested.
216 if (fstat(tfd
, &stbuf
) < 0 ||
217 (stbuf
.st_mode
&020) == 0) {
219 problem
= PERMISSION_DENIED
;
223 (void) strlcpy(tty
, ubuf
->ut_line
, TTY_SIZE
);
224 endutxent(); /* close the utmpx file */
228 if (strcmp(ubuf
->ut_line
, tty
) == 0) {
229 endutxent(); /* close the utmpx file */
235 endutxent(); /* close the utmpx file */