PRIVATE void rpc__tower_ref_vec_from_binding ( rpc_if_rep_p_t if_spec, rpc_binding_handle_t binding, rpc_tower_ref_vector_p_t *tower_vector, unsigned32 *status ) { unsigned16 lower_flr_count; unsigned32 i, temp_status; twr_p_t lower_floors; rpc_tower_ref_p_t tower_copy; rpc_tower_floor_p_t tower_floor; rpc_if_id_t if_id; rpc_binding_rep_p_t binding_rep; rpc_syntax_id_t *if_syntax_id; CODING_ERROR (status); /* * Create the tower vector. */ RPC_MEM_ALLOC ( *tower_vector, rpc_tower_ref_vector_p_t, sizeof (rpc_tower_ref_vector_t) + ((if_spec->syntax_vector.count -1) * (sizeof (rpc_tower_ref_p_t))) , RPC_C_MEM_TOWER_REF_VECTOR, RPC_C_MEM_WAITOK ); /* * Initialize tower count. */ (*tower_vector)->count = 0; /* * Create the tower for the first transfer syntax * in the interface specification. */ /* * Obtain the rpc address of this binding. */ binding_rep = (rpc_binding_rep_p_t) binding; /* * Create the lower tower floors. */ rpc__naf_tower_flrs_from_addr ( binding_rep->rpc_addr, &lower_floors, status); if (*status != rpc_s_ok) { RPC_MEM_FREE (*tower_vector, RPC_C_MEM_TOWER_REF_VECTOR); return; } /* * Initialize the tower vector with the pointer * to the lower floors. */ (*tower_vector)->lower_flrs = lower_floors; /* * Get the number of lower tower floors returned and * convert to host's representation. */ memcpy ((char *)&lower_flr_count, (char *)lower_floors->tower_octet_string, RPC_C_TOWER_FLR_COUNT_SIZE); RPC_RESOLVE_ENDIAN_INT16 (lower_flr_count); /* * Allocate the tower reference structure to the first tower. * The number of floors is equal to the number of RPC (upper) floors * plus the number of network (lower) floors. */ rpc__tower_ref_alloc (lower_floors->tower_octet_string, RPC_C_NUM_RPC_FLOORS + lower_flr_count, RPC_C_NUM_RPC_FLOORS+1, &((*tower_vector)->tower[0]), status); if (*status != rpc_s_ok) { goto CLEANUP; } /* * Get the interface identifier and create tower floor 1. */ rpc_if_inq_id ((rpc_if_handle_t) if_spec, &if_id, status); if (*status != rpc_s_ok) { goto CLEANUP; } rpc__tower_flr_from_if_id (&if_id, &tower_floor, status); if (*status != rpc_s_ok) { goto CLEANUP; } /* * Add floor 1 to the tower. */ rpc__tower_ref_add_floor (1, tower_floor, (*tower_vector)->tower[0], status); if (*status != rpc_s_ok) { goto CLEANUP; } /* * Create tower floor 2 from the transfer syntax from the ifspec. */ if_syntax_id = if_spec->syntax_vector.syntax_id; rpc__tower_flr_from_drep (if_syntax_id, &tower_floor, status); if (*status != rpc_s_ok) { goto CLEANUP; } /* * Add floor 2 to the tower. */ rpc__tower_ref_add_floor (2, tower_floor, (*tower_vector)->tower[0], status); if (*status != rpc_s_ok) { goto CLEANUP; } /* * Create tower floor 3 from the RPC protocol id. */ rpc__tower_flr_from_rpc_prot_id (binding_rep->rpc_addr->rpc_protseq_id, binding_rep->protocol_version, &tower_floor, status); if (*status != rpc_s_ok) { goto CLEANUP; } /* * Add floor 3 to the tower. */ rpc__tower_ref_add_floor (3, tower_floor, (*tower_vector)->tower[0], status); if (*status != rpc_s_ok) { goto CLEANUP; } /* * Increment the number of towers in the vector. */ (*tower_vector)->count++; /* * Create the towers for the remaining transfer syntaxes * in the interface specification. */ if_syntax_id++; for (i=1; i < if_spec->syntax_vector.count; i++, if_syntax_id++, (*tower_vector)->count++) { /* * Copy the initial tower created. */ rpc__tower_ref_copy ((*tower_vector)->tower[0], &tower_copy, status); if (*status != rpc_s_ok) { goto CLEANUP; } /* * Create floor 2 for this tower from the next transfer syntax. */ rpc__tower_flr_from_drep (if_syntax_id, &tower_floor, status); if (*status != rpc_s_ok) { goto CLEANUP; } /* * Add floor 2 to the tower. */ rpc__tower_ref_add_floor (2, tower_floor, tower_copy, status); if (*status != rpc_s_ok) { goto CLEANUP; } (*tower_vector)->tower[i] = tower_copy; } CLEANUP: /* * If status is anything other than successful, * free the tower vector. */ if (*status != rpc_s_ok) { rpc__tower_ref_vec_free (tower_vector, &temp_status); } return; }
PUBLIC void rpc_tower_vector_from_binding ( rpc_if_handle_t if_spec, rpc_binding_handle_t binding, rpc_tower_vector_p_t *twr_vector, unsigned32 *status ) { rpc_tower_ref_vector_t *tower_ref_vector; unsigned int i; unsigned32 temp_status; CODING_ERROR (status); RPC_VERIFY_INIT (); /* * Null the twr_vector in case of error before finishing. */ *twr_vector = NULL; if (if_spec == NULL) { *status = rpc_s_no_interfaces; return; } /* * Convert the binding to a vector of tower refs. */ rpc__tower_ref_vec_from_binding ((rpc_if_rep_p_t)if_spec, binding, &tower_ref_vector, status); if (*status != rpc_s_ok) { /* * No need to goto CLEANUP; since a tower_ref_vector wasn't * returned to us. */ return; } /* * Allocate a rpc_tower_vector_t based on the number of returned * tower refs. */ RPC_MEM_ALLOC ( *twr_vector, rpc_tower_vector_p_t, sizeof (rpc_tower_vector_t) + (tower_ref_vector->count - 1) * sizeof (twr_p_t), RPC_C_MEM_TOWER_VECTOR, RPC_C_MEM_WAITOK ); (*twr_vector)->count = tower_ref_vector->count; /* * For each returned tower ref convert the tower ref to a twr_t and * store the twr_t in the rpc_tower_vector_t. */ for (i = 0; i < tower_ref_vector->count; i++) { rpc__tower_from_tower_ref (tower_ref_vector->tower[i], &(*twr_vector)->tower[i], status); if (*status != rpc_s_ok) { RPC_MEM_FREE (*twr_vector, RPC_C_MEM_TOWER_VECTOR); goto CLEANUP; } } CLEANUP: /* * Free the tower_ref_vector returned from * rpc__tower_ref_vec_from_binding(). */ rpc__tower_ref_vec_free (&tower_ref_vector, &temp_status); /* * If we got this far successfully, return whatever the result from * rpc__tower_ref_vec_free(). Otherwise, return the previous error * in status. */ if (*status == rpc_s_ok) { *status = temp_status; } return; }