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 <ctype.h> 21#include <dce/rpc.h> 22#define DCETHREAD_CHECKED 23#define DCETHREAD_USE_THROW 24#include <dce/dcethread.h> 25#include "echou.h" 26#include "misc.h" 27 28static void wait_for_signals(void); 29 30/* 31 * 32 * A template DCE RPC server 33 * 34 * main() contains the basic calls needed to register an interface, 35 * get communications endpoints, and register the endpoints 36 * with the endpoint mapper. 37 * 38 * ReverseIt() implements the interface specified in echo.idl 39 * 40 */ 41 42 43int main(int ac ATTRIBUTE_UNUSED, char *av[] ATTRIBUTE_UNUSED) 44{ 45 unsigned32 status; 46 rpc_binding_vector_p_t server_binding; 47 char * string_binding; 48 unsigned32 i; 49 50 /* 51 * Register the Interface with the local endpoint mapper (rpcd) 52 */ 53 54 printf ("Registering server.... \n"); 55 rpc_server_register_if(echou_v1_0_s_ifspec, 56 NULL, 57 NULL, 58 &status); 59 chk_dce_err(status, "rpc_server_register_if()", "", 1); 60 61 printf("registered.\nPreparing binding handle...\n"); 62 63 rpc_server_use_protseq((unsigned_char_p_t)"ncacn_ip_tcp", 64 rpc_c_protseq_max_calls_default, &status); 65 66 chk_dce_err(status, "rpc_server_use_all_protseqs()", "", 1); 67 rpc_server_inq_bindings(&server_binding, &status); 68 chk_dce_err(status, "rpc_server_inq_bindings()", "", 1); 69 70 /* 71 * Register bindings with the endpoint mapper 72 */ 73 74 printf("registering bindings with endpoint mapper\n"); 75 76 rpc_ep_register(echou_v1_0_s_ifspec, 77 server_binding, 78 NULL, 79 (unsigned char *)"QDA application server", 80 &status); 81 chk_dce_err(status, "rpc_ep_register()", "", 1); 82 83 printf("registered.\n"); 84 85 /* 86 * Print out the servers endpoints (TCP and UDP port numbers) 87 */ 88 89 printf ("Server's communications endpoints are:\n"); 90 91 for (i=0; i<server_binding->count; i++) 92 { 93 rpc_binding_to_string_binding(server_binding->binding_h[i], 94 (unsigned char **)&string_binding, 95 &status 96 ); 97 if (string_binding) 98 printf("\t%s\n",string_binding); 99 } 100 101 102 /* 103 * Start the signal waiting thread in background. This thread will 104 * Catch SIGINT and gracefully shutdown the server. 105 */ 106 107 wait_for_signals(); 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 /* 133 * Kill the signal handling thread 134 */ 135 136 printf ("Unregistering server from the endpoint mapper.... \n"); 137 rpc_ep_unregister(echou_v1_0_s_ifspec, 138 server_binding, 139 NULL, 140 &status); 141 chk_dce_err(status, "rpc_ep_unregister()", "", 0); 142 143 /* 144 * retire the binding information 145 */ 146 147 printf("Cleaning up communications endpoints... \n"); 148 rpc_server_unregister_if(echou_v1_0_s_ifspec, 149 NULL, 150 &status); 151 chk_dce_err(status, "rpc_server_unregister_if()", "", 0); 152 153 exit(0); 154 155} 156 157 158/*========================================================================= 159 * 160 * Server implementation of ReverseIt() 161 * 162 *=========================================================================*/ 163 164idl_boolean 165ReplyBack(h, in_type, in_value, out_value, status) 166 rpc_binding_handle_t h; 167 idl_long_int in_type; 168 EchoUnion *in_value; 169 EchoUnion **out_value; 170 error_status_t * status; 171{ 172 173 char * binding_info; 174 error_status_t e; 175 *out_value = (EchoUnion*) rpc_ss_allocate(sizeof(EchoUnion)); 176 177 /* 178 * Get some info about the client binding 179 */ 180 181 rpc_binding_to_string_binding(h, (unsigned char **)&binding_info, &e); 182 if (e == rpc_s_ok) 183 { 184 printf ("ReplyBack() called by client: %s\n", binding_info); 185 } 186 187 printf("\n\nFunction ReplyBack() -- input argments\n"); 188 189 if (in_value == NULL) 190 { 191 printf("in_value = [null]\n"); 192 *out_value = NULL; 193 } 194 else if (in_type == 1) 195 { 196 printf("in_value = [int] %li\n", (long int) in_value->integer); 197 (*out_value)->integer = -in_value->integer; 198 } 199 else if (in_type == 2) 200 { 201 printf("in_value = [float] %f\n", (double) in_value->fp); 202 (*out_value)->fp = -in_value->fp; 203 } 204 else if (in_type == 3) 205 { 206 int i, len; 207 printf("in_value = [string] %s\n", (char*) in_value->str); 208 len = strlen((const char *)in_value->str); 209 (*out_value)->str = rpc_ss_allocate(sizeof(*in_value->str) * (len+1)); 210 211 for (i = 0; i < len; i++) 212 { 213 (*out_value)->str[i] = in_value->str[len-1-i]; 214 } 215 216 (*out_value)->str[len] = 0; 217 } 218 219 printf ("\n=========================================\n"); 220 221 //*out_value = NULL; 222 *status = error_status_ok; 223 224 return 1; 225} 226 227 228/*========================================================================= 229 * 230 * wait_for_signals() 231 * 232 * 233 * Set up the process environment to properly deal with signals. 234 * By default, we isolate all threads from receiving asynchronous 235 * signals. We create a thread that handles all async signals. 236 * The signal handling actions are handled in the handler thread. 237 * 238 * For AIX, we cant use a thread that sigwaits() on a specific signal, 239 * we use a plain old, lame old Unix signal handler. 240 * 241 *=========================================================================*/ 242 243 244void 245wait_for_signals(void) 246{ 247 sigset_t signals; 248 249 sigemptyset(&signals); 250 sigaddset(&signals, SIGINT); 251 252 dcethread_signal_to_interrupt(&signals, dcethread_self()); 253} 254