/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* svc_door.c, Server side for doors IPC based RPC.
*/
#include "mt.h"
#include "rpc_mt.h"
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <syslog.h>
#include <stdlib.h>
#include <string.h>
#include <door.h>
#include <alloca.h>
#include <dlfcn.h>
#include <limits.h>
static void svc_door_destroy_pvt();
static int return_xprt_copy();
static struct xp_ops *svc_door_ops();
int svc_ndoorfds = 0;
/*
* Dispatch information for door calls.
*/
typedef struct {
void (*dispatch)();
} call_info_t;
/*
* kept in xprt->xp_p2
*/
struct svc_door_data {
};
static SVCXPRT *get_xprt_copy();
static bool_t svc_door_recv();
static void svc_door_destroy();
/*
* List management routines.
*/
{
SVCXPRT_LIST *l;
return (FALSE);
(void) mutex_lock(lockp);
*list = l;
(void) mutex_unlock(lockp);
return (TRUE);
}
void
{
(void) mutex_lock(lockp);
free(*l);
*l = tmp;
break;
}
}
(void) mutex_unlock(lockp);
}
void
{
(void) mutex_lock(lockp);
}
(void) mutex_unlock(lockp);
}
/*
* Destroy all door based service handles.
*/
void
__svc_cleanup_door_xprts(void)
{
(void) mutex_lock(&svc_door_mutex);
svc_door_destroy_pvt(l->xprt);
}
(void) mutex_unlock(&svc_door_mutex);
}
static bool_t
make_tmp_dir(void)
{
return (FALSE);
}
}
static void
{
/* LINTED pointer alignment */
return;
}
r->rq_vers) {
return;
}
/*
* if we got here, the program or version
* is not served ...
*/
else
}
/*
* This is the door server procedure.
*/
/* ARGSUSED */
static void
{
struct svc_req *r;
char *cred_area;
char *result_buf;
int len;
/*
* allocate result buffer
*/
/* LINTED pointer alignment */
if (result_buf == NULL) {
/*NOTREACHED*/
}
(void) mutex_lock(&svc_door_mutex);
"door_server: memory allocation failure");
(void) mutex_unlock(&svc_door_mutex);
/*NOTREACHED*/
}
(void) mutex_unlock(&svc_door_mutex);
/* LINTED pointer alignment */
/* LINTED pointer alignment */
/* LINTED pointer alignment */
/* LINTED pointer alignment */
/*NOTREACHED*/
} else {
/*NOTREACHED*/
}
}
/*
* Usage:
* xprt = svc_door_create(dispatch, prognum, versnum, sendsize);
* Once *xprt is initialized, it is registered.
* see (svc.h, xprt_register). If recvsize or sendsize are 0 suitable
* system defaults are chosen.
* The routines returns NULL if a problem occurred.
*/
void
{
/* LINTED pointer alignment */
return;
}
SVCXPRT *
{
int fd;
(void) mutex_lock(&svc_door_mutex);
if (!make_tmp_dir()) {
(void) mutex_unlock(&svc_door_mutex);
return (NULL);
}
goto freedata;
}
/* LINTED pointer alignment */
(int)versnum);
if (fd < 0) {
if (unlink(rendezvous) < 0) {
"svc_door_create: %s %s:%m", rendezvous,
"exists and could not be removed");
goto freedata;
}
O_TRUNC, 0644);
if (fd < 0) {
"svc_door_create: %s %s:%m",
"could not create", rendezvous);
goto freedata;
}
} else {
"svc_door_create: could not create %s:%m",
goto freedata;
}
}
if (did < 0) {
"svc_door_create: door_create failed: %m");
goto freedata;
}
"svc_door_create: fattach failed: %m");
goto freedata;
}
}
/*
* Determine send size
*/
if (sendsize < __rpc_min_door_buf_size)
else
goto freedata;
}
goto freedata;
}
goto freedata;
}
svc_ndoorfds++;
goto freedata;
}
(void) mutex_unlock(&svc_door_mutex);
return (xprt);
(void) fdetach(rendezvous);
(void) unlink(rendezvous);
if (did >= 0)
(void) door_revoke(did);
if (xprt)
(void) mutex_unlock(&svc_door_mutex);
return (NULL);
}
static SVCXPRT *
{
return (NULL);
/* LINTED pointer alignment */
/* LINTED pointer alignment */
return (NULL);
}
}
return (NULL);
}
}
return (NULL);
}
/* LINTED pointer alignment */
/* LINTED pointer alignment */
return (xprt);
}
static SVCXPRT *
{
/* LINTED pointer alignment */
if (xret) {
/* LINTED pointer alignment */
} else
if (xprt) {
/* LINTED pointer alignment */
/* LINTED pointer alignment */
}
return (xprt);
}
int
{
/* LINTED pointer alignment */
(void) mutex_lock(&svc_door_mutex);
/* LINTED pointer alignment */
(void) mutex_unlock(&svc_door_mutex);
return (0);
}
/* LINTED pointer alignment */
/* LINTED pointer alignment */
/* LINTED pointer alignment */
/*
* Propagate any error flags. This is done in both directions to
* ensure that if one child gets an error, everyone will see it
* (even if there are multiple outstanding children) and the
* door will get closed.
*/
/* LINTED pointer alignment */
/* LINTED pointer alignment */
if (svc_defunct(xprt)) {
/* LINTED pointer alignment */
/* LINTED pointer cast */
}
(void) mutex_unlock(&svc_door_mutex);
return (len);
}
/* ARGSUSED */
static enum xprt_stat
{
return (XPRT_IDLE);
}
static bool_t
{
/* LINTED pointer alignment */
return (FALSE);
return (TRUE);
}
static bool_t
{
/* LINTED pointer alignment */
return (TRUE);
}
return (FALSE);
}
static bool_t
{
/* LINTED pointer alignment */
}
static bool_t
{
/* LINTED pointer alignment */
}
static void
{
(void) mutex_lock(&svc_door_mutex);
(void) mutex_unlock(&svc_door_mutex);
}
static void
{
/* LINTED pointer alignment */
/* LINTED pointer alignment */
/* LINTED pointer alignment */
/* LINTED pointer alignment */
return;
}
if (--svc_ndoorfds == 0)
/* wake up door dispatching */
(void) cond_signal(&svc_door_waitcv);
}
/* ARGSUSED */
static bool_t
{
extern int __rpc_legal_connmaxrec(int);
int tmp;
switch (rq) {
case SVCSET_CONNMAXREC:
if (tmp >= 0) {
door_param) == 0)
return (TRUE);
return (FALSE);
}
return (FALSE);
case SVCGET_CONNMAXREC:
&door_param) == 0) {
if (door_param == SIZE_MAX)
tmp = 0;
else if (door_param > INT_MAX)
else if (door_param > 0)
tmp = (int)door_param;
else
return (FALSE);
return (TRUE);
}
return (FALSE);
}
return (FALSE);
}
static struct xp_ops *
svc_door_ops(void)
{
(void) mutex_lock(&ops_lock);
}
(void) mutex_unlock(&ops_lock);
return (&ops);
}
/*
* Return door credentials.
*/
/* ARGSUSED */
{
return (FALSE);
return (TRUE);
}
/* ARGSUSED */
{
return (door_ucred(&ucp) == 0);
}