summaryrefslogblamecommitdiffstats
path: root/c/src/librdbg/src/servcon.c
blob: 30570760db0d4bc429718b57ea77a23d9add290f (plain) (tree)
1
2
3
4
5
6
7
8
9
10







                                                                           

       































































































































                                                                               
/*
 **************************************************************************
 *
 *  Component:	RDBG
 *  Module:	servcon.c
 *
 *  Synopsis:	Management of RPC client connections.
 *
 * $Id$
 *
 **************************************************************************
 */

#include <sys/errno.h>	
#include <rdbg/rdbg.h>		
#include <rdbg/servrpc.h>	
 
    /*
     *  ConnCreate - create a new connection entry for a client.
     *
     *  This function finds an empty entry in the connection array
     *  or makes space. It fills in the fields that are passed to it.
     *  It does not do any validation on net addresses nor does it
     *  start a validation cycle on other clients. This is done by
     *  the caller.
     */

    int
ConnCreate (struct svc_req* rqstp, open_in* in)
{
    NET_OPAQUE	sender;
    int		idx;
    CONN_LIST*	clst;
    
    setErrno (0);

    /* Convert to valid Net address */
    if (! TspTranslateRpcAddr (rqstp, &sender)) {
	DPRINTF (("ConnCreate: TspTranslateRpcAddr failed\n"));
	return -1;
    }
    if (! TspValidateAddr ((NET_OPAQUE*) in->back_port, &sender)) {
	DPRINTF (("ConnCreate: TspValidateAddr failed\n"));
	return -1;			/* errno now setup with error */
    }

	/* look for an empty connection entry */
    for (idx = 0; idx < conn_list_cnt; idx++) {
	if (!conn_list[idx].in_use)
	    break;			/* an empty one found */
    }

    if (idx >= conn_list_cnt) {		/* no empties, create space */
	CONN_LIST*	tmp_conn_list = conn_list;

	conn_list_cnt += CONN_LIST_INC;
	if (conn_list) {
	    conn_list = (CONN_LIST *) Realloc (conn_list,  /* extend */
		conn_list_cnt * sizeof (CONN_LIST));
	} else {
	    conn_list = (CONN_LIST *)Malloc(conn_list_cnt * sizeof(CONN_LIST));
	}

	if (!conn_list) {		/* unable to get space */
	    if ((conn_list_cnt -= CONN_LIST_INC)) {
		    /* was realloc, restore space */
		conn_list = tmp_conn_list;
	    }
	    return -1;		/* errno set by failed alloc */
	}
	    /* clear newly created memory */
	memset (conn_list + idx, 0, CONN_LIST_INC * sizeof (CONN_LIST));
    } else {			/* clear new entry */
	memset (conn_list + idx, 0, sizeof (CONN_LIST));
    }
    clst = conn_list + idx;

    clst->in_use = True; /* now in use */
    clst->sender = sender;
    memcpy (&clst->back_port, &in->back_port, sizeof (NET_OPAQUE));
    memcpy (&clst->route, &in->destination, sizeof (NET_OPAQUE));
    clst->debug_type = (UCHAR) in->debug_type;
    clst->flags = in->flags;
    strncpy (clst->user_name, in->user_name, NAMEMAX-1);
    clst->user_name [NAMEMAX-1] = 0;

    return idx;
}

    /*
     *  ConnDelete - remove connection entry when shutdown.
     *
     */

    void
ConnDelete (int conn, struct svc_req* rqstp, close_control control)
{
    CONN_LIST*	clst = conn_list + conn;
    int		idx;
    Boolean	prim;

    if (! clst->in_use) return;	/* not active */

    for (idx = 0; idx < pid_list_cnt; idx++) {
	PID_LIST* plst = pid_list + idx;

	if (! PIDMAP_TEST (conn, idx)) continue;

	    /* found a controlled pid */
	prim = (plst->primary_conn == conn) ? True : False;
	TgtDetachCon (conn, idx, True);

	    /* if still running or alive, we use close control on it */
	if (! plst->pid)
	    continue;		/* entry gone */

	if (prim && control == CLOSE_KILL) {
		/* kill off process */
	    TgtKillAndDelete (plst, rqstp, True);
	} else if (! plst->owners) {
		/* no owners left */
	    if (control == CLOSE_DETACH) {
		TgtKillAndDelete (plst, rqstp, False);
	    }
	    if (control == CLOSE_DETACH || PROC_TERMINATED (plst)) {
		TgtDelete (plst, conn, (control==CLOSE_DETACH) ? 
		    BMSG_DETACH : 0);
	    }
	}
    }
    if (clst->list) {
	Free (clst->list);	/* free allocated memory */
    }
    DPRINTF (("ConnDelete: Connection closed for port %u\n",
	HL_W(*((UINT16*) &clst->back_port.c[2]))));

    clst->in_use = False;	/* free it back */
}