summaryrefslogtreecommitdiffstats
path: root/c/src/librdbg/src/servcon.c
blob: 30570760db0d4bc429718b57ea77a23d9add290f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/*
 **************************************************************************
 *
 *  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 */
}