PreviousNext

Sample Server Code

Here is an example of an internationalized RPC server that exports the cs_test interface defined in Writing the Interface Definition File.

#include <stdio.h>

#include <stdlib.h>

#include <dce/rpc.h>

#include <dce/nsattrid.h>

#include <dce/dce_error.h>

#include <locale.h>

#include <pthread.h>

#include <dce/codesets.h>

#include "cs_test.h"


/*

* Macro for result checking

*/


#define CHECK_STATUS(t, func, returned_st, expected_st) \

{ \

if (returned_st == expected_st) { \

} \

else { \

dce_error_inq_text(returned_st, \

(unsigned char *)unexpected, &dce_status); \

dce_error_inq_text(expected_st,\

(unsigned char *)expected, &dce_status); \

printf("FAILED %s()\nresult: %s\nexpected: %s\n\n", \

func, unexpected, expected); \

} \

} \


static unsigned char unexpected[dce_c_error_string_len];

static unsigned char expected[dce_c_error_string_len];

static int dce_status;


int

main(int argc, char *argv[])

{

error_status_t status;

int i;

rpc_ns_handle_t inq_contxt;

rpc_binding_vector_t *binding_vector;

rpc_codeset_mgmt_p_t arr;

pthread_t this_thread = pthread_self();

sigset_t sigset;

char *nsi_entry_name;

char *server_locale_name;

error_status_t expected = rpc_s_ok;

int server_pid;


/* The environment variable I18N_SERVER_ENTRY needs

* to be set before running this program. This is

* not a DCE environment variable, so you can set up

* your own environment variable if you like.

*/


nsi_entry_name = getenv("I18N_SERVER_ENTRY");


(void)pthread_mutex_init(&mutex, pthread_mutexattr_default);


/* Set the locale. In this way, the current locale

* information is extracted from XPG/POSIX defined

* environment variable LANG or LC_ALL.

*/


setlocale(LC_ALL, "");


/*

* Get supported code sets.

*/

rpc_rgy_get_codesets (

&arr,

&status );


CHECK_STATUS(TRUE, "rpc_rgy_get_codesets", status, expected);



rpc_server_register_if (

cs_test_v1_0_s_ifspec,

NULL,

NULL,

&status );


CHECK_STATUS(TRUE, "rpc_server_register_if", status, expected);



rpc_server_use_all_protseqs (

rpc_c_protseq_max_reqs_default,

&status );


CHECK_STATUS(TRUE, "rpc_server_use_all_protseqs", status, expected);



rpc_server_inq_bindings (

&binding_vector,

&status );


CHECK_STATUS(TRUE, "rpc_server_inq_bindings", status, expected);



rpc_ns_binding_export (

rpc_c_ns_syntax_default,

(unsigned_char_p_t)nsi_entry_name,

cs_test_v1_0_s_ifspec,

binding_vector,

NULL,

&status );


CHECK_STATUS(TRUE, "rpc_ns_binding_export", status, expected);



rpc_ep_register (

cs_test_v1_0_s_ifspec,

binding_vector,

NULL,

NULL,

&status );


CHECK_STATUS(TRUE, "rpc_ep_register", status, expected);



/*

* Register the server's supported code sets into the name space.

*/

rpc_ns_mgmt_set_attribute (

rpc_c_ns_syntax_default,

(unsigned_char_p_t)nsi_entry_name,

rpc_c_attr_codesets,

(void *)arr,

&status );


CHECK_STATUS(TRUE, "rpc_ns_mgmt_set_attribute", status, expected);



/*

* Free memory allocated by getting code sets.

*/

rpc_ns_mgmt_free_codesets (&arr, &status);


CHECK_STATUS(TRUE, "rpc_ns_mgmt_free_codeset", status, expected);



sigemptyset(&sigset);

sigaddset(&sigset, SIGINT);


if (pthread_signal_to_cancel_np(&sigset, &this_thread) != 0)

{

printf("pthread_signal_to_cancel_np failed\n");

exit(1);

}

TRY

{

server_pid = getpid();


printf("Listening for remote procedure calls...\n");


rpc_server_listen (

rpc_c_listen_max_calls_default,

&status );


CHECK_STATUS(TRUE, "rpc_server_listen", status, expected);



/*

* Remove code set attributes from namespace on return.

*/


rpc_ns_mgmt_remove_attribute (

rpc_c_ns_syntax_default,

(unsigned_char_p_t)nsi_entry_name,

rpc_c_attr_codesets,

&status );


CHECK_STATUS(TRUE, "rpc_ns_mgmt_remove_attribute", status, expected);


rpc_ns_binding_unexport (

rpc_c_ns_syntax_default,

(unsigned_char_p_t)nsi_entry_name,

cs_test_v1_0_s_ifspec,

(uuid_vector_p_t)NULL,

&status );


CHECK_STATUS(TRUE, "rpc_ns_binding_unexport", status, expected);


rpc_ep_unregister (

cs_test_v1_0_s_ifspec,

binding_vector,

NULL,

&status );


CHECK_STATUS(TRUE, "rpc_ep_unregister", status, expected);


rpc_binding_vector_free (

&binding_vector,

&status );


CHECK_STATUS(TRUE, "rpc_binding_vector_free", status, expected);



rpc_server_unregister_if (

cs_test_v1_0_s_ifspec,

NULL,

&status );


CHECK_STATUS(TRUE, "rpc_server_unregister_if", status, expected);


(void)pthread_mutex_destroy(&mutex);

}

CATCH_ALL

{

/*

* Remove code set attribute from namespace on a signal.

*/


rpc_ns_mgmt_remove_attribute (

rpc_c_ns_syntax_default,

(unsigned_char_p_t)nsi_entry_name,

rpc_c_attr_codesets,

&status );


CHECK_STATUS(TRUE, "rpc_ns_mgmt_remove_attribute", status, expected);


rpc_ns_binding_unexport (

rpc_c_ns_syntax_default,

(unsigned_char_p_t)nsi_entry_name,

cs_test_v1_0_s_ifspec,

(uuid_vector_p_t)NULL,

&status );


CHECK_STATUS(TRUE, "rpc_ns_binding_unexport", status, expected);


rpc_ep_unregister (

cs_test_v1_0_s_ifspec,

binding_vector,

NULL,

&status );


CHECK_STATUS(TRUE, "rpc_ep_unregister", status, expected);


rpc_binding_vector_free (

&binding_vector,

&status );


CHECK_STATUS(TRUE, "rpc_binding_vector_free", status, expected);



rpc_server_unregister_if (

cs_test_v1_0_s_ifspec,

NULL,

&status );


CHECK_STATUS(TRUE, "rpc_server_unregister_if", status, expected);


(void)pthread_mutex_destroy(&mutex);

}

ENDTRY;

}