#ifdef AIX_PROD
/* @(#)37    1.6  src/examples/pubsex/greet/greet_multi/greet.c, examples.src, os2dce21.dss, 960602a.1 2/14/96 13:17:43 */
/*
 *   COMPONENT_NAME: examples.src
 *
 *   FUNCTIONS: main
 *
 *   ORIGINS: 72
 *
 */
#endif /* AIX_PROD */

#include <stdio.h>
#include <stdlib.h>
#include <dce/pthread_exc.h>
#include <dce/dce_error.h>
#include <dce/rpc.h>
#include "greet.h"

#define MAX_CONCURRENT_CALLS 5

/* The server declares the manager EPVs defined in the
   manager.c module.  There are three EPVs in this example,one
   for each operation TYPE coded in the manager routine.  */

extern greet_v1_0_epv_t greet_v1_0_english;
extern greet_v1_0_epv_t greet_v1_0_french;
extern greet_v1_0_epv_t greet_v1_0_spanish;
extern uuid_t uuid_nil;

/* In the first part of the main function, the server assigns
   its name (read in as an input parameter) to variable entry_name.
   The rpc_network_is_protseq_valid function checks that its argument
   specifies a protocol sequence that is supported on its host
   both by the runtime library and the operating system.  */

int main (int ac, char *av[])
{
    rpc_binding_vector_p_t  bvec;
    error_status_t          st;
    boolean32               validfamily;
    idl_char                *string_binding;
    char                    *entry_name, error_string[1024];
    int                     i, error_inq_st;
    uuid_t                  uuid_english, uuid_french, uuid_spanish;
    uuid_t                  canadian, british, american, french,
                            belgian, mexican, spanish;
    unsigned32              rpc_c_ns_syntax_osf_dce = 0;


    typedef struct {
        unsigned32          count;
        uuid_t              *uuid[7];
        } UUID_VECTOR;

    UUID_VECTOR             obj_uuids;



    if (ac != 2) {
        fprintf (stderr, "Usage: %s family\n", av[0]);
        exit(1);
    }

    entry_name = av[1];

    validfamily = rpc_network_is_protseq_valid("ncadg_ip_udp", &st);
    if (st != error_status_ok) {
        dce_error_inq_text (st, error_string, &error_inq_st);
        fprintf (stderr, "Cannot check protocol sequence - %s\n", error_string);
        exit(1);
    }

    if (!validfamily)  {
        fprintf(stderr,
        "Protocol sequence is not valid\n");
        exit (1);
    }
    /* Calling rpc_server_use_protseq to obtain an endpoint
       on which to listen */

    rpc_server_use_protseq("ncadg_ip_udp", MAX_CONCURRENT_CALLS, &st);
    if (st != error_status_ok) {
        dce_error_inq_text (st, error_string, &error_inq_st);
        fprintf (stderr, "Cannot use protocol sequence - %s\n", error_string);
        fflush(stdout);
        exit(1);
    }


    /* create 3 uuids....english, french, spanish */
    /* one for each type */

     uuid_create(&uuid_english, &st);
     if (st != error_status_ok)  {
         dce_error_inq_text (st, error_string, &error_inq_st);
         fprintf (stderr, "Cannot create UUID - %s\n", error_string);
         fflush(stdout);
         exit(1);
    }

     uuid_create(&uuid_french, &st);
     if (st != error_status_ok)  {
         dce_error_inq_text (st, error_string, &error_inq_st);
         fprintf (stderr, "Cannot create UUID - %s\n", error_string);
         fflush(stdout);
         exit(1);
    }

     uuid_create(&uuid_spanish, &st);

     if (st != error_status_ok)  {
         dce_error_inq_text (st, error_string, &error_inq_st);
         fprintf (stderr, "Cannot create UUID - %s\n", error_string);
         fflush(stdout);
         exit(1);
    }


     /* generate seven object uuids from object strings defined  */
     /* in idl file                                              */

     uuid_from_string(CANADIAN_OBJECT,&canadian, &st);
     uuid_from_string(BRITISH_OBJECT,&british, &st);
     uuid_from_string(AMERICAN_OBJECT,&american, &st);
     uuid_from_string(FRENCH_OBJECT,&french, &st);
     uuid_from_string(BELGIAN_OBJECT,&belgian, &st);
     uuid_from_string(MEXICAN_OBJECT,&mexican, &st);
     uuid_from_string(SPANISH_OBJECT,&spanish, &st);


     rpc_object_set_type(&canadian,&uuid_english,&st);
     if (st != error_status_ok) {
        dce_error_inq_text (st, error_string, &error_inq_st);
        fprintf (stderr, "Cannot set object type - %s\n", error_string);
        fflush(stdout);
        exit(1);
    }

     rpc_object_set_type(&british,&uuid_english,&st);
     if (st != error_status_ok) {
        dce_error_inq_text (st, error_string, &error_inq_st);
        fprintf (stderr, "Cannot set object type - %s\n", error_string);
        fflush(stdout);
        exit(1);
    }

     rpc_object_set_type(&american,&uuid_english,&st);
     if (st != error_status_ok) {
        dce_error_inq_text (st, error_string, &error_inq_st);
        fprintf (stderr, "Cannot set object type - %s\n", error_string);
        fflush(stdout);
        exit(1);
    }

     rpc_object_set_type(&french,&uuid_french,&st);
     if (st != error_status_ok) {
        dce_error_inq_text (st, error_string, &error_inq_st);
        fprintf (stderr, "Cannot set object type - %s\n", error_string);
        fflush(stdout);
        exit(1);
    }

    rpc_object_set_type(&belgian,&uuid_french,&st);
    if (st != error_status_ok) {
       dce_error_inq_text (st, error_string, &error_inq_st);
       fprintf (stderr, "Cannot set object type - %s\n", error_string);
       fflush(stdout);
       exit(1);
    }

    rpc_object_set_type(&mexican,&uuid_spanish,&st);
    if (st != error_status_ok) {
        dce_error_inq_text (st, error_string, &error_inq_st);
        fprintf (stderr, "Cannot set object type - %s\n", error_string);
        fflush(stdout);
        exit(1);
    }

    rpc_object_set_type(&spanish,&uuid_spanish,&st);
    if (st != error_status_ok) {
        dce_error_inq_text (st, error_string, &error_inq_st);
        fprintf (stderr, "Cannot set object type - %s\n", error_string);
        fflush(stdout);
        exit(1);
    }

     /* Calling rpc_server_register_if to register its interface with
        the RPC runtime by supplying its interface specifier and EPV.
        Must be called three times, once for each TYPE -
        english, french, and spanish  */

     rpc_server_register_if(greet_v1_0_s_ifspec, &uuid_english,
              (rpc_mgr_epv_t) &greet_v1_0_english, &st);
     if (st != error_status_ok) {
         dce_error_inq_text (st, error_string, &error_inq_st);
         fprintf (stderr, "Cannot register interface - %s\n", error_string);
         fflush(stdout);
         exit(1);
     }

     rpc_server_register_if(greet_v1_0_s_ifspec, &uuid_french,
              (rpc_mgr_epv_t) &greet_v1_0_french, &st);
     if (st != error_status_ok) {
         dce_error_inq_text (st, error_string, &error_inq_st);
         fprintf (stderr, "Cannot register interface - %s\n", error_string);
         fflush(stdout);
         exit(1);
     }

     rpc_server_register_if(greet_v1_0_s_ifspec, &uuid_spanish,
              (rpc_mgr_epv_t) &greet_v1_0_spanish, &st);
     if (st != error_status_ok) {
         dce_error_inq_text (st, error_string, &error_inq_st);
         fprintf (stderr, "Cannot register interface - %s\n", error_string);
         fflush(stdout);
         exit(1);
    }

    /* Calling rpc_server_inq_bindings to obtain a vector of
       binding handles that can be used to register the server's
       endpoint. The server then obtains, prints, and frees a
       string binding */

     rpc_server_inq_bindings(&bvec, &st);
     if (st != error_status_ok)  {
         dce_error_inq_text (st, error_string, &error_inq_st);
         fprintf (stderr, "Cannot inquire bindings - %s\n", error_string);
         fflush(stdout);
         exit(1);
    }

    printf("Server %s bindings:\n", entry_name);
    fflush(stdout);

    for (i = 0; i < bvec->count; i++)  {
         rpc_binding_to_string_binding(bvec->binding_h[i],
              &string_binding, &st);

         printf("%s\n", (char *)string_binding);
         fflush(stdout);
         rpc_string_free(&string_binding, &st);

     }

    /* Define the array of object uuids for the seven objects */

    obj_uuids.count   = 7;
    obj_uuids.uuid[0] = &canadian;
    obj_uuids.uuid[1] = &british;
    obj_uuids.uuid[2] = &american;
    obj_uuids.uuid[3] = &french;
    obj_uuids.uuid[4] = &belgian;
    obj_uuids.uuid[5] = &mexican;
    obj_uuids.uuid[6] = &spanish;


    /* The server endpoint is registered in the local Endpoint Map */

    rpc_ep_register(greet_v1_0_s_ifspec, bvec,
                   (uuid_vector_t *) &obj_uuids,
            (unsigned_char_p_t) "greet version 1.0 server", &st);

    /* export the binding vector the runtime gave us to the namespace */
    rpc_ns_binding_export(rpc_c_ns_syntax_osf_dce,
        (unsigned_char_p_t) "/.:/servers/greet",
        greet_v1_0_s_ifspec, bvec, (uuid_vector_t *) &obj_uuids, &st);
    if (st != error_status_ok) {
        dce_error_inq_text (st, error_string, &error_inq_st);
        fprintf (stderr, "Cannot export binding vector: %s\n", error_string);
        fflush(stdout);
        exit(1);
    }

     /*  To begin listening for RPC requests, the server calls
       rpc_server_listen.  This call is placed within the TRY of a
       TRY, CATCH_ALL, ENDTRY sequence, so that if the server receives
       a signal while it is listening, it can unregister its interface
       and its endpoint before it exits.   */


     TRY {

          printf("Server %s is listening...\n", entry_name);
          fflush(stdout);

         rpc_server_listen(MAX_CONCURRENT_CALLS, &st);
         if (st != error_status_ok)
             dce_error_inq_text (st, error_string, &error_inq_st);
             fprintf(stderr, "Error: %s\n", error_string);
         }

         CATCH_ALL {

           /* unexport binding vector from namespace --
              not usually done for a persistent server */

           fprintf(stdout, "Server %s unexporting\n", entry_name);
           fflush(stdout);

           rpc_ns_binding_unexport(rpc_c_ns_syntax_osf_dce, "/.:/servers/greet",
               greet_v1_0_s_ifspec, (uuid_vector_t *) &obj_uuids, &st);
           if (st != error_status_ok) {
               dce_error_inq_text (st, error_string, &error_inq_st);
               fprintf (stderr, "Cannot unexport binding vector: %s\n", error_string);
               fflush(stdout);
           /* don't exit here */
           }

            printf("Unregistering endpoint \n");
            fflush(stdout);
            rpc_ep_unregister(greet_v1_0_s_ifspec, bvec,(uuid_vector_p_t) &obj_uuids,&st);
          }

          ENDTRY;
    return (0);
   }

