/* @(#)91    1.21  src/examples/type_mgr/server_shutdown.c, examples.src, os2dce21.dss, 960602a.1 1/12/96 14:30:57 */
/*
 * COMPONENT_NAME:  examples.src
 *
 * FUNCTIONS:
 *
 * ORIGINS: 27
 *
 * (C) COPYRIGHT International Business Machines Corp. 1992, 1994
 * All Rights Reserved
 * Licensed Materials - Property of IBM
 *
 * US Government Users Restricted Rights - Use, duplication or
 * disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
 *
 */

/*********************************************************************
 *  File      :  server_shutdown.c                                   *
 *********************************************************************
 *                                                                   *
 *  Functions :  server_shutdown()                                   *
 *                                                                   *
 *  Comments  :  Routines that should be run before a server         *
 *               process closes up shop.  These include tasks        *
 *               such as removing endpoints, unexporting objects,    *
 *               etc...                                              *
 *                                                                   *
 *********************************************************************/

#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
#include <dce/dce_error.h>
#include <dce/rpc.h>
#include "cust_if.h"
#include "tm_admin_if.h"
#include "tm_admin.h"
#include "type_mgr.h"
#include <util.h>
#include "server.h"
#include "server_object_db.h"


/*********************************************************************
 *   Function    :  server_shutdown()                                *
 *********************************************************************
 *                                                                   *
 *   Description :  Makes all necessary RPC calls to carry out a     *
 *                  clean shutdown of the server process.            *
 *                                                                   *
 *   Returns     :  (0) success, or appropriate error code.          *
 *                                                                   *
 *********************************************************************/

unsigned32 server_shutdown(void)
{
    unsigned32           status;
    rpc_binding_vector_t *binding_vector;
    uuid_vector_t        *obj_uuid_vector_p;
    char                 *obj_name;
    char                 *type_name;
    object_db_handle_t   obj_db_context;
    uuid_t               obj_uuid;
    rpc_ns_handle_t      obj_inq_context;
    char                 full_obj_name[128];

    /*
     *  Under all circumstances, we want to unregister all endpoints this
     *  server is using, before it exits.  This way, the endpoint map
     *  will not contain stale endpoints in it, and the client will not
     *  waste its time trying to bind to server endpoints that are not
     *  valid.
     */

    rpc_server_inq_bindings( &binding_vector,
                             &status );

    CHECK_STATUS( "rpc_server_inq_bindings()\n",
                  status,
                  RETURN );

    /*
     *  Since the object uuid vector for the type manager administrative
     *  interface only has one element, we could have simply
     *  allocated sizeof(uuid_vector_t).  This is an example of how
     *  to allocate a larger vector (replace 1 by the number of
     *  uuids in the vector).
     */

    obj_uuid_vector_p = ( uuid_vector_t *)malloc( sizeof(unsigned32)
                         + (1 * sizeof( uuid_t *)));
    obj_uuid_vector_p->count = 1 ;
    obj_uuid_vector_p->uuid[0] = &g_server_object_uuid ;

    rpc_ep_unregister( tm_admin_v1_0_s_ifspec,
                       binding_vector,
                       obj_uuid_vector_p,
                       &status );

    /*
     *  Don't worry about the status code, since we may have
     *  called server_shutdown() when nothing was registered,
     *  in which case, we expect an error.  Just indicate that
     *  it was successful.
     */

    if (!status)
    {
        TRACE("Unregistered the admin endpoint from the endpoint map\n");
    }

    /*
     *  For each object entry in the object database, do the following:
     *  - get its name
     *  - get object associated with the name from the namespace.
     *  - unregister the endpoint associated with the object entry.
     */

    if (status = object_db_entry_inq_begin( &obj_db_context ))
    {
        PRINT("Error:  object_db_entry_inq_begin(): %d\n", status);
        return( status );
    }

    while ((status = object_db_entry_inq_next( &obj_db_context,
                                           &obj_name,
                                           &type_name )) != NO_MORE_ENTRIES)
    {
        sprintf( full_obj_name, "%s%s", NAME_SERVICE_PATH, obj_name );

        /* get the object from the namespace entry. */
        rpc_ns_entry_object_inq_begin( rpc_c_ns_syntax_default,
                                       full_obj_name,
                                       &obj_inq_context,
                                       &status );

        CHECK_STATUS( "rpc_ns_entry_object_inq_begin()\n",
                      status,
                      RETURN );

        rpc_ns_entry_object_inq_next( obj_inq_context,
                                      &obj_uuid,
                                      &status );

        CHECK_STATUS( "rpc_ns_entry_object_inq_next()\n",
                      status,
                      RETURN );

        /* fill in the object uuid vector */

        obj_uuid_vector_p->count = 1 ;
        obj_uuid_vector_p->uuid[0] = &obj_uuid ;

        /* unregister the endpoint */
        rpc_ep_unregister( type_mgr_v1_0_s_ifspec,
                           binding_vector,
                           obj_uuid_vector_p,
                           &status );

        /*
         *  Don't worry about the status code, since we may have
         *  called server_shutdown() when nothing was registered,
         *  in which case, we expect an error.  Just indicate that
         *  it was successful.
         */
        if (!status)
        {
            TRACE("Unregistered a customer endpoint from the endpoint map\n");
        }

        rpc_ns_entry_object_inq_done( &obj_inq_context,
                               &status );

        free((char *)obj_name);
        free((char *)type_name);
    }

    if (status = object_db_entry_inq_done( &obj_db_context ))
    {
        PRINT("Error:  object_db_entry_inq_done(): %d\n", status);
        return( status );
    }

    free((char *)obj_uuid_vector_p);
    rpc_binding_vector_free( &binding_vector,
                             &status );

    CHECK_STATUS( "rpc_binding_vector_free()\n",
                  status,
                  CONTINUE );

    return(status);

} /* end server_shutdown() */

/* EOF server_shutdown.c */


