/* * echo_server : demo DCE RPC application * * Jim Doyle, jrd@bu.edu 09-05-1998 * * */ #if HAVE_CONFIG_H #include #endif #ifndef _POSIX_PTHREAD_SEMANTICS #define _POSIX_PTHREAD_SEMANTICS 1 #endif #define getopt getopt_system #include #include #include #include #include "echo.h" #include "misc.h" #undef getopt #ifdef HAVE_GETOPT_H #include #endif #ifndef _WIN32 static void wait_for_signals(); #endif /* * * A template DCE RPC server * * main() contains the basic calls needed to register an interface, * get communications endpoints, and register the endpoints * with the endpoint mapper. * * ReverseIt() implements the interface specified in echo.idl * */ static void bind_server( rpc_binding_vector_p_t * server_binding, rpc_if_handle_t interface_spec, char * protocol, char * endpoint ) { char * function = "n/a"; unsigned32 status; /* * Prepare the server binding handle * use all avail protocols (UDP and TCP). This basically allocates * new sockets for us and associates the interface UUID and * object UUID of with those communications endpoints. */ #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(protocol, rpc_c_protseq_max_calls_default, &status); } } else { function = "rpc_server_use_protseq_ep()"; rpc_server_use_protseq_ep(protocol, rpc_c_protseq_max_calls_default, 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() { 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; char * protocol = NULL; char * endpoint = NULL; int c; char * function = NULL; /* * Process the cmd line args */ 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 /* Temporarily disable using all protocols because something is currently busted on Unix */ if (!protocol) { protocol = PROTOCOL_TCP; } #endif /* * Register the Interface with the local endpoint mapper (rpcd) */ 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); /* * Register bindings with the endpoint mapper */ 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"); /* * Print out the servers endpoints (TCP and UDP port numbers) */ printf ("Server's communications endpoints are:\n"); for (i=0; iargc; i++) printf("\t[arg %ld]: %s\n", i, in_text->argv[i]); printf ("\n=========================================\n"); /* * Allocate the output args as dynamic storage bound * to this RPC. The output args are the same size as the * input args since we are simply reversing strings. */ 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(in_text->argv[i]) + 1); } /* * do the string reversal */ for (i=0; i < in_text->argc; i++) { l = strlen(in_text->argv[i]); for (j=0; jargv[i][j] = in_text->argv[i][l-j-1]; } result->argv[i][l]=0; /* make sure its null terminated! */ } *out_text = result; *status = error_status_ok; return 1; } #ifndef _WIN32 /*========================================================================= * * wait_for_signals() * * * Set up the process environment to properly deal with signals. * By default, we isolate all threads from receiving asynchronous * signals. We create a thread that handles all async signals. * The signal handling actions are handled in the handler thread. * * For AIX, we cant use a thread that sigwaits() on a specific signal, * we use a plain old, lame old Unix signal handler. * *=========================================================================*/ void wait_for_signals() { sigset_t signals; sigemptyset(&signals); sigaddset(&signals, SIGINT); dcethread_signal_to_interrupt(&signals, dcethread_self()); } #endif