#ifdef AIX_PROD
/* @(#)22    1.6  src/examples/pubsex/greet/greet_cds/greet.c, examples.src, os2dce21.dss, 960602a.1 2/14/96 13:17:37 */
/*
 *   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 nil UUID which it supplies
   in registrations as an object UUID and object type UUID. */

#ifdef __BORLANDC__
extern uuid_t _pascal uuid_nil;
#else
extern uuid_t uuid_nil;
#endif

/* In the first part of the main function, the server calls
   the rpc_network_is_protseq_valid to check 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;

    if (ac != 2) {
        fprintf (stderr, "Invoke as: greet greet\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);
    }



    /* Calling rpc_server_register_if to register its interface with
       the RPC runtime by supplying its interface specifier  */

    rpc_server_register_if(greet_v1_0_s_ifspec, &uuid_nil, NULL, &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);

    }

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

    rpc_ep_register(greet_v1_0_s_ifspec, bvec,
                    (uuid_vector_p_t) NULL,
                    (unsigned_char_p_t) "greet version 1.0 server",
                    &st);
    if (st != error_status_ok) {
          dce_error_inq_text (st, error_string, &error_inq_st);
          fprintf (stderr, "Cannot register end point: %s\n", error_string);
          fflush(stdout);
          exit(1);
    }


    /* export the binding vector the runtime gave us to the namespace */

    rpc_ns_binding_export(rpc_c_ns_syntax_dce,
                          (unsigned_char_p_t) "/.:/servers/greet",
                          greet_v1_0_s_ifspec, bvec,
                          (uuid_vector_t *)NULL, &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("Listening...\n");
        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_dce,
                              "/.:/servers/greet", greet_v1_0_s_ifspec,
                              (uuid_vector_t *)NULL, &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) NULL, &st);
    }
    ENDTRY;
    return (0);
}

