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