1/* 2 * echo_server : 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#ifndef _POSIX_PTHREAD_SEMANTICS 13#define _POSIX_PTHREAD_SEMANTICS 1 14#endif 15 16#include <stdio.h> 17#include <stdlib.h> 18#include <string.h> 19#include <signal.h> 20#include <compat/dcerpc.h> 21#include "echon.h" 22#include "misc.h" 23 24#ifndef _WIN32 25static void wait_for_signals(void); 26#endif 27 28/* 29 * 30 * A template DCE RPC server 31 * 32 * main() contains the basic calls needed to register an interface, 33 * get communications endpoints, and register the endpoints 34 * with the endpoint mapper. 35 * 36 * ReverseIt() implements the interface specified in echo.idl 37 * 38 */ 39 40 41int main(int ac ATTRIBUTE_UNUSED, char *av[] ATTRIBUTE_UNUSED) 42{ 43 unsigned32 status; 44 rpc_binding_vector_p_t server_binding; 45 char * string_binding; 46 unsigned32 i; 47 48 /* 49 * Register the Interface with the local endpoint mapper (rpcd) 50 */ 51 52 printf ("Registering server.... \n"); 53 rpc_server_register_if(echon_v1_0_s_ifspec, 54 NULL, 55 NULL, 56 &status); 57 chk_dce_err(status, "rpc_server_register_if()", "", 1); 58 59 printf("registered.\nPreparing binding handle...\n"); 60 61 rpc_server_use_protseq((unsigned_char_p_t)"ncacn_ip_tcp", 62 rpc_c_protseq_max_calls_default, &status); 63 64 chk_dce_err(status, "rpc_server_use_all_protseqs()", "", 1); 65 rpc_server_inq_bindings(&server_binding, &status); 66 chk_dce_err(status, "rpc_server_inq_bindings()", "", 1); 67 68 /* 69 * Register bindings with the endpoint mapper 70 */ 71 72 printf("registering bindings with endpoint mapper\n"); 73 74 rpc_ep_register(echon_v1_0_s_ifspec, 75 server_binding, 76 NULL, 77 (unsigned char *)"QDA application server", 78 &status); 79 chk_dce_err(status, "rpc_ep_register()", "", 1); 80 81 printf("registered.\n"); 82 83 /* 84 * Print out the servers endpoints (TCP and UDP port numbers) 85 */ 86 87 printf ("Server's communications endpoints are:\n"); 88 89 for (i=0; i<RPC_FIELD_COUNT(server_binding); i++) 90 { 91 rpc_binding_to_string_binding(RPC_FIELD_BINDING_H(server_binding)[i], 92 (unsigned char **)&string_binding, 93 &status 94 ); 95 if (string_binding) 96 printf("\t%s\n",string_binding); 97 } 98 99 100#ifndef _WIN32 101 /* 102 * Start the signal waiting thread in background. This thread will 103 * Catch SIGINT and gracefully shutdown the server. 104 */ 105 106 wait_for_signals(); 107#endif 108 109 /* 110 * Begin listening for calls 111 */ 112 113 printf ("listening for calls.... \n"); 114 115 DCETHREAD_TRY 116 { 117 rpc_server_listen(rpc_c_listen_max_calls_default, &status); 118 } 119 DCETHREAD_CATCH_ALL(THIS_CATCH) 120 { 121 printf ("Server stoppped listening\n"); 122 } 123 DCETHREAD_ENDTRY 124 125 /* 126 * If we reached this point, then the server was stopped, most likely 127 * by the signal handler thread called rpc_mgmt_stop_server(). 128 * gracefully cleanup and unregister the bindings from the 129 * endpoint mapper. 130 */ 131 132#ifndef _WIN32 133 /* 134 * Kill the signal handling thread 135 */ 136 137#endif 138 139 printf ("Unregistering server from the endpoint mapper.... \n"); 140 rpc_ep_unregister(echon_v1_0_s_ifspec, 141 server_binding, 142 NULL, 143 &status); 144 chk_dce_err(status, "rpc_ep_unregister()", "", 0); 145 146 /* 147 * retire the binding information 148 */ 149 150 printf("Cleaning up communications endpoints... \n"); 151 rpc_server_unregister_if(echon_v1_0_s_ifspec, 152 NULL, 153 &status); 154 chk_dce_err(status, "rpc_server_unregister_if()", "", 0); 155 156 exit(0); 157 158} 159 160 161/*========================================================================= 162 * 163 * Server implementation of ReverseIt() 164 * 165 *=========================================================================*/ 166 167idl_boolean 168ReplyBack(h, in_num, out_num, status) 169 rpc_binding_handle_t h; 170 unsigned32 in_num; 171 unsigned32* out_num; 172 error_status_t * status; 173{ 174 175 char * binding_info; 176 error_status_t e; 177 178 /* 179 * Get some info about the client binding 180 */ 181 182 rpc_binding_to_string_binding(h, (unsigned char **)&binding_info, &e); 183 if (e == rpc_s_ok) 184 { 185 printf ("ReplyBack() called by client: %s\n", binding_info); 186 } 187 188 printf("\n\nFunction ReplyBack() -- input argments\n"); 189 190 printf("\tin_num = %ld\n", (long)in_num); 191 192 printf ("\n=========================================\n"); 193 194 *out_num = in_num; 195 *status = error_status_ok; 196 197 return 1; 198 199} 200 201 202#ifndef _WIN32 203/*========================================================================= 204 * 205 * wait_for_signals() 206 * 207 * 208 * Set up the process environment to properly deal with signals. 209 * By default, we isolate all threads from receiving asynchronous 210 * signals. We create a thread that handles all async signals. 211 * The signal handling actions are handled in the handler thread. 212 * 213 * For AIX, we cant use a thread that sigwaits() on a specific signal, 214 * we use a plain old, lame old Unix signal handler. 215 * 216 *=========================================================================*/ 217 218 219void 220wait_for_signals(void) 221{ 222 sigset_t signals; 223 224 sigemptyset(&signals); 225 sigaddset(&signals, SIGINT); 226 227 dcethread_signal_to_interrupt(&signals, dcethread_self()); 228} 229 230#endif 231