1/* 2 * echo_client : demo DCE RPC application 3 * 4 * Jim Doyle, jrd@bu.edu, 09-05-1998 5 * 6 * 7 */ 8#if HAVE_CONFIG_H 9#include <config.h> 10#endif 11 12#define getopt getopt_system 13 14#include <stdio.h> 15#include <string.h> 16#include <stdlib.h> 17#include <dce/rpc.h> 18#define DCETHREAD_CHECKED 19#define DCETHREAD_USE_THROW 20#include <dce/dcethread.h> 21#include "echou.h" 22#include <misc.h> 23 24#undef getopt 25 26#ifdef HAVE_GETOPT_H 27#include <getopt.h> 28#endif 29 30#define MAX_USER_INPUT 128 31#define MAX_LINE 128 32 33/* 34 * Forward declarations 35 */ 36 37static int 38get_client_rpc_binding(rpc_binding_handle_t *, const char *, 39 rpc_if_handle_t, const char *); 40 41/* 42 * usage() 43 */ 44 45static void usage(void) 46{ 47 printf("usage: echon_client [-h hostname] [-u] [-t] [-i number]\n"); 48 printf(" -u: use UDP protocol \n"); 49 printf(" -t: use TCP protocol (default) \n"); 50 printf(" -v: more verbosity\n"); 51 printf(" -h: specify host where RPC server lives \n"); 52 printf(" -i: long int to be sent (5 - if not specified)\n"); 53 printf(" -f: float to be sent (2.5 - if not specified)\n\n"); 54 exit(0); 55} 56 57int main(int argc, char *argv[]) 58{ 59 60 /* 61 * command line processing and options stuff 62 */ 63 64 extern char *optarg; 65 extern int optind, opterr, optopt; 66 int c; 67 68 int verbose = 1; 69 int use_udp = 0; 70 int use_tcp = 0; 71 char rpc_host[128] = "localhost"; 72 const char * protocol; 73 74 /* 75 * stuff needed to make RPC calls 76 */ 77 78 unsigned32 status; 79 rpc_binding_handle_t echo_server; 80 int ok; 81 long int in_type = -1; 82 EchoUnion *in_value = NULL; 83 EchoUnion *out_value = NULL; 84 85 /* 86 * Process the cmd line args 87 */ 88 89 while ((c = getopt(argc, argv, "h:utvi:f:s:")) != EOF) 90 { 91 switch (c) 92 { 93 case 'u': 94 use_udp = 1; 95 break; 96 case 't': 97 use_tcp = 1; 98 break; 99 case 'v': 100 verbose = 0; 101 break; 102 case 'h': 103 strncpy(rpc_host, optarg, sizeof(rpc_host)-1); 104 break; 105 case 'i': 106 in_type = 1; 107 in_value = malloc(sizeof(EchoUnion)); 108 in_value->integer = atoi(optarg); 109 break; 110 case 'f': 111 in_type = 2; 112 in_value = malloc(sizeof(EchoUnion)); 113 in_value->fp = (idl_short_float)atof(optarg); 114 break; 115 case 's': 116 in_type = 3; 117 in_value = malloc(sizeof(EchoUnion)); 118 in_value->str = (unsigned_char_p_t)optarg; 119 printf("in_value is string @ %p\n", (void*) optarg); 120 break; 121 default: 122 usage(); 123 } 124 } 125 126 if (!use_tcp && !use_udp) use_tcp=1; 127 128 if (use_udp) 129 protocol = "udp"; 130 else 131 protocol = "tcp"; 132 133 /* 134 * Get a binding handle to the server using the following params: 135 * 136 * 1. the hostname where the server lives 137 * 2. the interface description structure of the IDL interface 138 * 3. the desired transport protocol (UDP or TCP) 139 */ 140 141 if (get_client_rpc_binding(&echo_server, 142 rpc_host, 143 echou_v1_0_c_ifspec, 144 protocol) == 0) 145 { 146 printf ("Couldnt obtain RPC server binding. exiting.\n"); 147 exit(1); 148 } 149 150 151 /* 152 * Do the RPC call 153 */ 154 155 printf ("calling server\n"); 156 ok = ReplyBack(echo_server, in_type, in_value, &out_value, &status); 157 158 /* 159 * Print the results 160 */ 161 162 if (ok && status == error_status_ok) 163 { 164 printf ("got response from server. results: \n"); 165 166 if (out_value == NULL) 167 { 168 printf("out_value = [null]\n"); 169 } 170 else if (in_type == 1) 171 { 172 printf("out_value = [int] %li\n", (long int) out_value->integer); 173 } 174 else if (in_type == 2) 175 { 176 printf("out_value = [float] %f\n", (double) out_value->fp); 177 } 178 else if (in_type == 3) 179 { 180 printf("out_value = [string@%p] %s\n", (void*) out_value->str, (char*) out_value->str); 181 midl_user_free(out_value->str); 182 } 183 184 printf("\n===================================\n"); 185 186 } 187 188 if (out_value) 189 midl_user_free(out_value); 190 191 if (status != error_status_ok) 192 chk_dce_err(status, "ReverseIt()", "main()", 1); 193 194 /* 195 * Done. Now gracefully teardown the RPC binding to the server 196 */ 197 198 rpc_binding_free(&echo_server, &status); 199 exit(0); 200 201} 202 203/*========================================================================== 204 * 205 * get_client_rpc_binding() 206 * 207 *========================================================================== 208 * 209 * Gets a binding handle to an RPC interface. 210 * 211 * parameters: 212 * 213 * [in/out] binding_handle 214 * [in] hostname <- Internet hostname where server lives 215 * [in] interface_uuid <- DCE Interface UUID for service 216 * [in] protocol <- "udp", "tcp" or "any" 217 * 218 *==========================================================================*/ 219 220static int 221get_client_rpc_binding( 222 rpc_binding_handle_t * binding_handle, 223 const char * hostname, 224 rpc_if_handle_t interface_spec, 225 const char * protocol) 226{ 227 char * resolved_binding; 228 char * printable_uuid ATTRIBUTE_UNUSED; 229 const char * protocol_family; 230 char partial_string_binding[128]; 231 rpc_if_id_t interface ATTRIBUTE_UNUSED; 232 idl_uuid_t ifc_uuid ATTRIBUTE_UNUSED; 233 error_status_t status; 234 235 /* 236 * create a string binding given the command line parameters and 237 * resolve it into a full binding handle using the endpoint mapper. 238 * The binding handle resolution is handled by the runtime library 239 */ 240 241 242 if (strcmp(protocol, "udp")==0) 243 protocol_family = "ncadg_ip_udp"; 244 else 245 protocol_family = "ncacn_ip_tcp"; 246 247 248 sprintf(partial_string_binding, "%s:%s[]", 249 protocol_family, 250 hostname); 251 252 rpc_binding_from_string_binding((unsigned char *)partial_string_binding, 253 binding_handle, 254 &status); 255 chk_dce_err(status, "string2binding()", "get_client_rpc_binding", 1); 256 257 /* 258 * Resolve the partial binding handle using the endpoint mapper 259 */ 260 261 rpc_ep_resolve_binding(*binding_handle, 262 interface_spec, 263 &status); 264 chk_dce_err(status, "rpc_ep_resolve_binding()", "get_client_rpc_binding", 1); 265 266/* 267 * Get a printable rendition of the binding handle and echo to 268 * the user. 269 */ 270 271 rpc_binding_to_string_binding(*binding_handle, 272 (unsigned char **)&resolved_binding, 273 &status); 274 chk_dce_err(status, "binding2string()", "get_client_rpc_binding", 1); 275 276 printf("fully resolving binding for server is: %s\n", resolved_binding); 277 278 279 return 1; 280} 281