#if HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <compat/dcerpc.h>
#include "echo.h"
#include "misc.h"
#ifndef HAVE_GETOPT_H
#include "getopt.h"
#endif
#define MAX_USER_INPUT 128
#define MAX_LINE 100 * 1024
#ifdef _WIN32
#define EOF_STRING "^Z"
#else
#define EOF_STRING "^D"
#endif
static int
get_client_rpc_binding(
rpc_binding_handle_t * binding_handle,
rpc_if_handle_t interface_spec,
const char * hostname,
const char * protocol,
const char * endpoint
);
static void usage(void)
{
printf("usage: echo_server [-h hostname] -e endpoint -n|-u|-t\n");
printf(" -h: specify host of RPC server (default is localhost)\n");
printf(" -e: specify endpoint for protocol\n");
printf(" -n: use named pipe protocol\n");
printf(" -u: use UDP protocol\n");
printf(" -t: use TCP protocol (default)\n");
printf(" -g: instead of prompting, generate a data string of the specified length\n");
printf(" -d: turn on debugging\n");
printf("\n");
exit(1);
}
extern void rpc__dbg_set_switches(
const char * ,
unsigned32 *
);
int
main(
int argc,
char *argv[]
)
{
extern char *optarg;
extern int optind, opterr, optopt;
int c;
const char * rpc_host = "127.0.0.1";
const char * protocol = PROTOCOL_TCP;
const char * endpoint = NULL;
char buf[MAX_LINE+1];
unsigned32 status;
rpc_binding_handle_t echo_server;
args * inargs;
args * outargs;
int ok;
unsigned32 i;
int generate_length = -1;
char * nl;
while ((c = getopt(argc, argv, "h:e:nutdg:")) != EOF)
{
switch (c)
{
case 'h':
rpc_host = optarg;
break;
case 'e':
endpoint = optarg;
break;
case 'n':
protocol = PROTOCOL_NP;
break;
case 'u':
protocol = PROTOCOL_UDP;
break;
case 't':
protocol = PROTOCOL_TCP;
break;
case 'd':
#ifdef _WIN32
printf("This option is only supported on Linux.\n");
#else
rpc__dbg_set_switches("0-19.10", &status);
rpc__dbg_set_switches("21-43.10", &status);
#endif
break;
case 'g':
generate_length = strtol(optarg, NULL, 10);
break;
default:
usage();
}
}
if(!endpoint || !protocol)
{
usage();
exit(1);
}
if (get_client_rpc_binding(&echo_server,
echo_v1_0_c_ifspec,
rpc_host,
protocol,
endpoint) == 0)
{
printf ("Couldn't obtain RPC server binding. exiting.\n");
exit(1);
}
inargs = (args *)malloc(sizeof(args) + MAX_USER_INPUT * sizeof(string_t));
if (inargs == NULL) printf("FAULT. Didn't allocate inargs.\n");
if (generate_length < 0)
{
printf ("enter stuff (%s on an empty line when done):\n\n\n", EOF_STRING);
i = 0;
while (!feof(stdin) && i < MAX_USER_INPUT )
{
if (NULL==fgets(buf, MAX_LINE, stdin))
break;
if ((nl=strchr(buf, '\n')))
*nl=0;
inargs->argv[i] = (string_t)strdup(buf);
i++;
}
inargs->argc = i;
}
else
{
inargs->argv[0] = malloc(generate_length + 1);
inargs->argv[0][0] = 's';
for(i = 1; i < (unsigned long)generate_length; i++)
{
inargs->argv[0][i] = i%10 + '0';
}
if(generate_length > 0)
inargs->argv[0][generate_length - 1] = 'e';
inargs->argv[0][generate_length] = '\0';
inargs->argc = 1;
}
printf ("calling server\n");
ok = ReverseIt(echo_server, inargs, &outargs, &status);
if (ok && status == error_status_ok)
{
printf ("got response from server. results: \n");
for (i=0; i<outargs->argc; i++)
printf("\t[%d]: %s\n", i, outargs->argv[i]);
printf("\n===================================\n");
}
if (status != error_status_ok)
chk_dce_err(status, "ReverseIt()", "main()", 1);
rpc_binding_free(&echo_server, &status);
exit(0);
}
static int
get_client_rpc_binding(
rpc_binding_handle_t * binding_handle,
rpc_if_handle_t interface_spec,
const char * hostname,
const char * protocol,
const char * endpoint
)
{
unsigned_char_p_t string_binding = NULL;
error_status_t status;
rpc_string_binding_compose(NULL,
(unsigned_char_p_t)protocol,
(unsigned_char_p_t)hostname,
(unsigned_char_p_t)endpoint,
NULL,
&string_binding,
&status);
chk_dce_err(status, "rpc_string_binding_compose()", "get_client_rpc_binding", 1);
rpc_binding_from_string_binding(string_binding,
binding_handle,
&status);
chk_dce_err(status, "rpc_binding_from_string_binding()", "get_client_rpc_binding", 1);
if (!endpoint)
{
rpc_ep_resolve_binding(*binding_handle,
interface_spec,
&status);
chk_dce_err(status, "rpc_ep_resolve_binding()", "get_client_rpc_binding", 1);
}
rpc_string_free(&string_binding, &status);
chk_dce_err(status, "rpc_string_free()", "get_client_rpc_binding", 1);
rpc_binding_to_string_binding(*binding_handle,
(unsigned char **)&string_binding,
&status);
chk_dce_err(status, "rpc_binding_to_string_binding()", "get_client_rpc_binding", 1);
printf("fully resolving binding for server is: %s\n", string_binding);
rpc_string_free(&string_binding, &status);
chk_dce_err(status, "rpc_string_free()", "get_client_rpc_binding", 1);
return 1;
}