#if HAVE_CONFIG_H
#include <config.h>
#endif
#ifndef _POSIX_PTHREAD_SEMANTICS
#define _POSIX_PTHREAD_SEMANTICS 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <compat/dcerpc.h>
#include "echo.h"
#include "misc.h"
#ifndef HAVE_GETOPT_H
#include "getopt.h"
#endif
#ifndef _WIN32
static void wait_for_signals(void);
#endif
static void
bind_server(
rpc_binding_vector_p_t * server_binding,
rpc_if_handle_t interface_spec ATTRIBUTE_UNUSED,
const char * protocol,
const char * endpoint)
{
const char * function = "n/a";
unsigned32 status;
#if 0
rpc_server_use_all_protseqs_if(0, interface_spec, &status);
#else
if (!endpoint)
{
if (!protocol)
{
function = "rpc_server_use_all_protseqs()";
rpc_server_use_all_protseqs(rpc_c_protseq_max_calls_default, &status);
}
else
{
function = "rpc_server_use_protseq()";
rpc_server_use_protseq((unsigned_char_p_t)protocol,
rpc_c_protseq_max_calls_default, &status);
}
}
else
{
function = "rpc_server_use_protseq_ep()";
rpc_server_use_protseq_ep((unsigned_char_p_t)protocol,
rpc_c_protseq_max_calls_default, (unsigned_char_p_t)endpoint, &status);
}
#endif
chk_dce_err(status, function, "", 1);
rpc_server_inq_bindings(server_binding, &status);
chk_dce_err(status, "rpc_server_inq_bindings()", "", 1);
}
static void usage(void)
{
printf("usage: echo_server [-e endpoint] [-n] [-u] [-t]\n");
printf(" -e: specify endpoint\n");
printf(" -n: use named pipe protocol\n");
printf(" -u: use UDP protocol\n");
printf(" -t: use TCP protocol (default)\n");
printf("\n");
exit(1);
}
int main(int argc, char *argv[])
{
unsigned32 status;
rpc_binding_vector_p_t server_binding;
char * string_binding;
unsigned32 i;
const char * protocol = NULL;
const char * endpoint = NULL;
int c;
while ((c = getopt(argc, argv, "e:nut")) != EOF)
{
switch (c)
{
case 'e':
endpoint = optarg;
break;
case 'n':
protocol = PROTOCOL_NP;
break;
case 'u':
protocol = PROTOCOL_UDP;
break;
case 't':
protocol = PROTOCOL_TCP;
break;
default:
usage();
}
}
if (endpoint && !protocol)
{
printf("ERROR: protocol is required when endpoint is specified\n");
exit(1);
}
#ifndef _WIN32
if (!protocol)
{
protocol = PROTOCOL_TCP;
}
#endif
printf ("Registering server.... \n");
rpc_server_register_if(echo_v1_0_s_ifspec,
NULL,
NULL,
&status);
chk_dce_err(status, "rpc_server_register_if()", "", 1);
printf("registered.\nPreparing binding handle...\n");
bind_server(&server_binding, echo_v1_0_s_ifspec, protocol, endpoint);
printf("registering bindings with endpoint mapper\n");
rpc_ep_register(echo_v1_0_s_ifspec,
server_binding,
NULL,
(unsigned char *)"QDA application server",
&status);
chk_dce_err(status, "rpc_ep_register()", "", 1);
printf("registered.\n");
printf ("Server's communications endpoints are:\n");
for (i=0; i<RPC_FIELD_COUNT(server_binding); i++)
{
rpc_binding_to_string_binding(RPC_FIELD_BINDING_H(server_binding)[i],
(unsigned char **)&string_binding,
&status);
if (string_binding)
printf("\t%s\n", string_binding);
}
#ifndef _WIN32
wait_for_signals();
#endif
printf ("listening for calls....\n");
DCETHREAD_TRY
{
rpc_server_listen(rpc_c_listen_max_calls_default, &status);
}
DCETHREAD_CATCH_ALL(THIS_CATCH)
{
printf ("Server stoppped listening\n");
}
DCETHREAD_ENDTRY;
#ifndef _WIN32
#endif
printf ("Unregistering server from the endpoint mapper....\n");
rpc_ep_unregister(echo_v1_0_s_ifspec,
server_binding,
NULL,
&status);
chk_dce_err(status, "rpc_ep_unregister()", "", 0);
printf("Cleaning up communications endpoints...\n");
rpc_server_unregister_if(echo_v1_0_s_ifspec,
NULL,
&status);
chk_dce_err(status, "rpc_server_unregister_if()", "", 0);
exit(0);
}
idl_boolean
ReverseIt(
rpc_binding_handle_t h,
args * in_text,
args ** out_text,
error_status_t * status
)
{
char * binding_info;
error_status_t e;
unsigned result_size;
args * result;
unsigned32 i,j,l;
rpc_transport_info_handle_t transport_info = NULL;
unsigned32 rpcstatus = 0;
#if 0
unsigned char* sesskey = NULL;
unsigned32 sesskey_len = 0;
unsigned char* principal_name = NULL;
#endif
rpc_binding_to_string_binding(h, (unsigned char **)&binding_info, &e);
if (e == rpc_s_ok)
{
printf ("ReverseIt() called by client: %s\n", binding_info);
}
rpc_binding_inq_transport_info(h, &transport_info, &rpcstatus);
printf("SMB transport session calls temporarily disabled -- jpeach\n");
#if 0
if (transport_info)
{
rpc_smb_transport_info_inq_peer_principal_name(transport_info, &principal_name);
rpc_smb_transport_info_inq_session_key(transport_info, &sesskey, &sesskey_len);
printf ("Client principal name: %s\n", (char*) principal_name);
printf ("Session key: ");
for (i = 0; i < sesskey_len; i++)
{
printf("%X", sesskey[i]);
}
printf ("\n");
}
#endif
if (in_text == NULL) return 0;
printf("\n\nFunction ReverseIt() -- input argments\n");
for (i=0; i<in_text->argc; i++)
printf("\t[arg %d]: %s\n", i, in_text->argv[i]);
printf ("\n=========================================\n");
result_size = sizeof(args) + in_text->argc * sizeof(string_t *);
result = (args * )rpc_ss_allocate(result_size);
result->argc = in_text->argc;
for (i=0; i < in_text->argc; i++)
{
result->argv[i] =
(string_t)rpc_ss_allocate(strlen((const char *)in_text->argv[i]) + 1);
}
for (i=0; i < in_text->argc; i++)
{
l = strlen((const char *)in_text->argv[i]);
for (j=0; j<l; j++)
{
result->argv[i][j] = in_text->argv[i][l-j-1];
}
result->argv[i][l]=0;
}
*out_text = result;
*status = error_status_ok;
return 1;
}
#ifndef _WIN32
void
wait_for_signals(void)
{
sigset_t signals;
sigemptyset(&signals);
sigaddset(&signals, SIGINT);
dcethread_signal_to_interrupt(&signals, dcethread_self());
}
#endif