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