/* **++ ** ** ROUTINE NAME: rpc_server_inq_bindings ** ** SCOPE: PUBLIC - declared in rpc.idl ** ** DESCRIPTION: ** ** Return the bindings for this server to which RPCs may be made. ** Note that object UUIDs are not part of these bindings. ** ** INPUTS: none ** ** INPUTS/OUTPUTS: none ** ** OUTPUTS: ** ** binding_vector The vector of valid bindings to this server. ** ** status The result of the operation. One of: ** rpc_s_ok ** rpc_s_no_bindings ** rpc_s_coding_error ** ** IMPLICIT INPUTS: none ** ** IMPLICIT OUTPUTS: none ** ** FUNCTION VALUE: void ** ** SIDE EFFECTS: none ** **-- **/ PUBLIC void rpc_server_inq_bindings #ifdef _DCE_PROTO_ ( rpc_binding_vector_p_t *binding_vec, unsigned32 *status ) #else (binding_vec, status) rpc_binding_vector_p_t *binding_vec; unsigned32 *status; #endif { unsigned int nd_index; /* network info table index */ unsigned int bv_index; /* binding vector index */ unsigned32 av_index; /* RPC Address vector index */ rpc_binding_vector_p_t bvp, new_bvp; /* local ptr to binding vector */ rpc_naf_id_t nafid; /* network family id */ rpc_addr_vector_p_t addr_vec; /* rpc addrs of network desc */ rpc_binding_rep_p_t binding_rep; unsigned int i; unsigned32 xstatus; CODING_ERROR (status); RPC_VERIFY_INIT (); *binding_vec = NULL; /* assume the worst */ /* * Allocate up an initial binding vector. Note that we might need * to allocate up a larger one later if the one we get now turns out * to not be big enough */ bv_alloc ((rpc_binding_vector_p_t) NULL, &bvp, status); if (*status != rpc_s_ok) { return; } bv_index = 0; /* * For each socket we know about... */ for (nd_index = 0; nd_index < listener_state.high_water; nd_index++) { rpc_listener_sock_p_t lsock = &listener_state.socks[nd_index]; /* * Consider only sockets that are in use and for server usage. */ if (lsock->busy && lsock->is_server) { nafid = RPC_PROTSEQ_INQ_NAF_ID (lsock->protseq_id); /* * Get all the RPC Addresses represented by this descriptor. */ (*RPC_NAF_INQ_EPV(nafid)->naf_desc_inq_addr) (lsock->protseq_id, lsock->desc, &addr_vec, status); if (*status != rpc_s_ok) { break; } /* * For each RPC Address... */ for (av_index = 0; av_index < addr_vec->len; av_index++) { /* * If we've exceeded the size of the current vector, * allocate up a new one. */ if (bv_index >= bvp->count) { bv_alloc (bvp, &new_bvp, status); if (*status != rpc_s_ok) { break; } bvp = new_bvp; } /* * Allocate a binding with this RPC Address. */ binding_rep = rpc__binding_alloc (false, &uuid_g_nil_uuid, lsock->protocol_id, addr_vec->addrs[av_index], status); if (*status != rpc_s_ok) { break; } /* * The rpc_addr reference has been handed off to the * binding, make sure that it isn't freed. */ addr_vec->addrs[av_index] = NULL; binding_rep->addr_is_dynamic = lsock->is_dynamic; bvp->binding_h[bv_index] = (rpc_binding_handle_t) binding_rep; bv_index++; /* bump for next binding vector entry */ } /* * Free up the allocated addr vector (and any addrs that * haven't been given to a binding). */ rpc__naf_addr_vector_free (&addr_vec, &xstatus); /* * If there was previously an error we're done. */ if (*status != rpc_s_ok) break; } } /* * Return with status if there aren't any bindings. */ if (bv_index == 0 && *status == rpc_s_ok) { *status = rpc_s_no_bindings; } /* * If everything went fine, return the bindings. * Otherwise free resources before returning (retain the original error). */ if (*status == rpc_s_ok) { bvp->count = bv_index; *binding_vec = bvp; } else { for (i = 0; i < bv_index; i++) { rpc_binding_free ((rpc_binding_handle_t *) &bvp->binding_h[i], &xstatus); } RPC_MEM_FREE (bvp, RPC_C_MEM_BINDING_VEC); *binding_vec = NULL; } }