/*
 * nexus.h
 *
 * rcsid = "$Header: /home/globdev/CVS/globus-packages/nexus/source/nexus/globus_nexus.h,v 1.35 2002/04/18 17:30:11 bresnaha Exp $"
 *
 * This header contains the exported interface of Nexus.
 */


#ifndef _NEXUS_INCLUDE_NEXUS_H
#define _NEXUS_INCLUDE_NEXUS_H

#ifndef GLOBUS_NEXUS_BACKWARD_COMPATIBLE
#define GLOBUS_NEXUS_BACKWARD_COMPATIBLE
#endif

/* EXTERN_C_BEGIN and EXTERN_C_END should surround any Nexus prototypes in
   nexus.h or Nexus .h files that are included by nexus.h.  This will
   allow C++ codes to include nexus.h and properly link against the
   Nexus library.
*/
#ifndef EXTERN_C_BEGIN
#ifdef __cplusplus
#define EXTERN_C_BEGIN extern "C" {
#define EXTERN_C_END }
#else
#define EXTERN_C_BEGIN
#define EXTERN_C_END
#endif
#endif

/*
 * Include the various Globus Component Library headers.
 */
#include "globus_config.h"
#include "globus_common.h"
#include "globus_dc.h"

/*********************************************************************
 * Various types and defines
 *********************************************************************/


#define NEXUS_VERSION_MAJOR 4
#define NEXUS_VERSION_MINOR 1

#ifdef _ALL_SOURCE
#include <standards.h>
#endif

EXTERN_C_BEGIN

/*
 * NEXUS_PROTO_TYPE_*
 *
 * Each different Nexus protocol module should have a unique
 * type identifier for all times...
 */
typedef enum globus_nexus_proto_type_enum
{
    NEXUS_PROTO_TYPE_LOCAL	= 0,
    NEXUS_PROTO_TYPE_TCP	= 1,
    NEXUS_PROTO_TYPE_SHMEM	= 2,
    NEXUS_PROTO_TYPE_INX	= 3,
    NEXUS_PROTO_TYPE_PVM	= 4,
    NEXUS_PROTO_TYPE_EUI	= 5,
    NEXUS_PROTO_TYPE_ATM	= 6,
    NEXUS_PROTO_TYPE_MPL	= 7,
    NEXUS_PROTO_TYPE_MPINX	= 8,
    NEXUS_PROTO_TYPE_UDP	= 9,
    NEXUS_PROTO_TYPE_MN_UDP	= 10,
    NEXUS_PROTO_TYPE_MPI	= 11,
    NEXUS_PROTO_TYPE_TOTEM	= 12,
/*    NEXUS_PROTO_TYPE_XTP	= 13,
*/    NEXUS_PROTO_TYPE_MAXVAL, /* do not assign a value.. should float to one plus maximum valid number */
    NEXUS_PROTO_TYPE_ALL,
    NEXUS_PROTO_TYPE_INTERNAL1	= 1000001,
    NEXUS_PROTO_TYPE_INTERNAL2	= 1000002
} globus_nexus_proto_type_t;

EXTERN_C_END

/*********************************************************************
 * General defines and macros
 *********************************************************************/

EXTERN_C_BEGIN

#ifdef NEXUS_DEFINE_GLOBALS
#define NEXUS_GLOBAL
#else
#define NEXUS_GLOBAL extern
#endif

#define NEXUS_MAX_LIBA_SIZE 64

#ifndef NEXUS_DEFAULT_LIBA_SIZE
#define NEXUS_DEFAULT_LIBA_SIZE (2*sizeof(unsigned long))
#endif

#define NEXUS_MAX_EXECUTABLE_PATH_LENGTH 1023

#define NEXUS_MAX_DEBUG_LEVELS 10

#ifdef BUILD_DEBUG
EXTERN_C_END
#include <assert.h>
EXTERN_C_BEGIN
#define NexusAssert(assertion) \
    if (!(assertion)) \
    { \
        globus_fatal("Assertion " #assertion " failed in file %s at line %d\n",\
		   __FILE__, __LINE__); \
	assert(0); \
    }
#define NexusAssert2(assertion, print_args) \
    if (!(assertion)) \
    { \
        globus_fatal("Assertion " #assertion " failed in file %s at line %d: %s", \
		   __FILE__, __LINE__, globus_assert_sprintf print_args); \
	assert(0); \
    }
#else /* BUILD_DEBUG */
#define NexusAssert(assertion)
#define NexusAssert2(assertion, print_args)
#endif /* BUILD_DEBUG */


#define NexusMalloc(Func, Var, Type, Size) \
{ \
    size_t NexusMalloc_size = (Size); \
    if (NexusMalloc_size > 0) \
    { \
	if (((Var) = (Type) globus_malloc (NexusMalloc_size)) == (Type) NULL) \
	{ \
	    globus_fatal("%s: malloc of size %d failed for %s %s in file %s line %d\n", \
                        #Func, NexusMalloc_size, #Type, #Var, \
			__FILE__, __LINE__); \
	} \
    } \
    else \
    { \
	(Var) = (Type) NULL; \
    } \
}

#define NexusFree(Ptr) \
{ \
    if ((Ptr) != NULL) \
    { \
	globus_free(Ptr); \
    } \
}


/*********************************************************************
 * Data tranform defines
 *********************************************************************/

#define NEXUS_MAX_TRANSFORM_INFO_SIZE 64

#define NEXUS_TRANSFORM_NONE    0
#define NEXUS_TRANSFORM_GZIP_ID 1
#define NEXUS_TRANSFORM_EXAMPLE 4
#define NEXUS_TRANSFORM_RTP     5
#define NEXUS_TRANSFORM_PERF	6

typedef void globus_nexus_transformattr_t;
typedef void globus_nexus_transformstate_t;


/*********************************************************************
 * Some forward typedef declarations...
 *********************************************************************/

typedef struct globus_nexus_proto_funcs_s	globus_nexus_proto_funcs_t;
typedef struct globus_nexus_buffer_s *		globus_nexus_buffer_t;
typedef struct globus_nexus_endpointattr_s	globus_nexus_endpointattr_t;
typedef struct globus_nexus_endpoint_s		globus_nexus_endpoint_t;
typedef struct globus_nexus_startpoint_s	globus_nexus_startpoint_t;
typedef struct globus_nexus_proto_s		globus_nexus_proto_t;
typedef struct globus_nexus_mi_proto_s		globus_nexus_mi_proto_t;


/*********************************************************************
 * Handler stuff
 *********************************************************************/

typedef void
(*globus_nexus_handler_func_t)(globus_nexus_endpoint_t *endpoint,
			       globus_nexus_buffer_t *buffer,
			       globus_bool_t called_from_non_threaded_handler);
typedef void
(*globus_nexus_unknown_handler_func_t)(globus_nexus_endpoint_t *endpoint,
				       globus_nexus_buffer_t *buffer,
				       int handler_id);

typedef enum globus_nexus_handler_type_enum
{
    GLOBUS_NEXUS_HANDLER_TYPE_THREADED		= 0,
    GLOBUS_NEXUS_HANDLER_TYPE_NON_THREADED	= 1
} globus_nexus_handler_type_t;

typedef struct globus_nexus_handler_s {
    globus_nexus_handler_type_t	type;
    globus_nexus_handler_func_t	func;
} globus_nexus_handler_t;

/* System handlers */
#define GLOBUS_NEXUS_STARTPOINT_COPY_HANDLER_ID		-1
#define GLOBUS_NEXUS_STARTPOINT_DESTROY_AND_NOTIFY_HANDLER_ID	-2


/*********************************************************************
 * nexus_module_list_t
 *********************************************************************/

/*
 * The user must provide a variable containing an initial set of
 * modules that are staticly linked into the executable.
 * This variables contains an array of the triples:
 *	{family_name, module_name, info_function_ptr}
 * Where:
 *   family_name is:
 *	"startups"	startup module
 *	"protocols"	protocol module
 *	"database"	database module
 *	"transform"	transform module
 *   module_name is a unique (within the family) string name for the module.
 *   info_function_ptr is a function pointer to the module's info function.
 *
 * The general form of a module information function is
 *	_nx_<family_name>_<module_name>_info().
 * So the user might supply a table that looks like:
 *
 * extern void *_nx_st_rsh_info(void);
 * extern void *_nx_pr_tcp_info(void);
 * nexus_module_list_t nexus_module_list[] =
 * {
 *     {"startups", "rsh", _nx_st_rsh_info},
 *     {"protocols", "tcp", _nx_pr_tcp_info},
 *     {NULL, NULL, NULL},
 * };
 *
 * This would specify that the rsh startup module, and the tcp protocol
 * module are staticly linked into the program.
 *
 * Note: On machines that provide dynamic linking, this list can be
 * empty.  All necessary modules will be dynamically loaded.  However,
 * linking some in using this list may provide for quicker startup.
 * Also, some startup modules need to be staticly linked to bootstrap
 * properly.
 */
typedef struct globus_nexus_module_list_s
{
    char *family_name;
    char *module_name;
    void *(*info_func)(void);
} globus_nexus_module_list_t;

EXTERN_C_END


/*********************************************************************
 * Some typdefs and structures
 *********************************************************************/

EXTERN_C_BEGIN

/*
 * nexus_list_t
 *
 * A generic linked list structure
 */
typedef struct globus_nexus_list_s
{
    void *                    value;
    struct globus_nexus_list_s *    next;
} globus_nexus_list_t;


/*
 * globus_nexus_barrier_t
 *
 * A generic barrier structure
 */
typedef struct globus_nexus_barrier_s
{
    globus_mutex_t	mutex;
    globus_cond_t	cond;
    int			count;
} globus_nexus_barrier_t;


/*********************************************************************
 * Buffer management structures
 *********************************************************************/

/*
 * globus_nexus_base_segment_t
 */
typedef struct globus_nexus_base_segment_s
{
    struct globus_nexus_base_segment_s *	next;
    unsigned long				size;
    unsigned long				size_used;
    globus_byte_t *				storage;
    globus_byte_t *				current;
    globus_bool_t				storage_is_inline;
    globus_byte_t *				rtphdr;
} globus_nexus_base_segment_t;

/*
 * globus_nexus_direct_info_t
 */
typedef struct globus_nexus_direct_info_s
{
    int			datatype;
    unsigned long	size;
    void *		data;
    int			action;
    unsigned long	custom_info;
} globus_nexus_direct_info_t;

#define GLOBUS_NEXUS_DIRECT_INFO_ACTION_INLINE		0
#define GLOBUS_NEXUS_DIRECT_INFO_ACTION_POINTER		1
#define GLOBUS_NEXUS_DIRECT_INFO_ACTION_CUSTOM		2

/*
 * globus_nexus_direct_segment_t
 */
typedef struct globus_nexus_direct_segment_s
{
    struct globus_nexus_direct_segment_s *	next;
    unsigned long				size;
    unsigned long				n_left;
    globus_nexus_direct_info_t *		storage;
    globus_nexus_direct_info_t *		current;
} globus_nexus_direct_segment_t;

/*
 * globus_nexus_buffer_t
 */
struct globus_nexus_buffer_s
{
    int					magic;
    globus_nexus_proto_t *		proto;
    globus_nexus_buffer_t 		next;
    unsigned long			reserved_header_size;
    int					format;
    int					saved_state;
    					    /* NEXUS_BUFFER_SAVED_STATE_* */
    globus_nexus_base_segment_t *	base_segments;
    globus_nexus_base_segment_t *	current_base_segment;
    globus_nexus_direct_segment_t *	direct_segments;
    globus_nexus_direct_segment_t *	current_direct_segment;
    unsigned long			n_direct;
    globus_byte_t *			direct_info;
    globus_bool_t			iovec_formatted;
    globus_nexus_barrier_t		barrier;
    globus_bool_t			using_barrier;
    globus_nexus_endpoint_t *		endpoint;
};

enum
{
    GLOBUS_NEXUS_BUFFER_SAVED_STATE_SENDING		= 0,
    GLOBUS_NEXUS_BUFFER_SAVED_STATE_UNSAVED		= 1,
    GLOBUS_NEXUS_BUFFER_SAVED_STATE_SAVED_IN_HANDLER	= 2,
    GLOBUS_NEXUS_BUFFER_SAVED_STATE_SAVED		= 3,
    GLOBUS_NEXUS_BUFFER_SAVED_STATE_FREED		= 4
};

/*
 * All messages will be aligned to word boundaries of this size.
 * If this is changed, the pad_size field in the message header
 * need to be changed to hold a value up to this.
 */
#define NEXUS_ALIGN_MESSAGE_SIZE 8

/*********************************************************************
 * Protocol module typedefs and structures
 *********************************************************************/

/*
 * globus_nexus_proto_t
 *
 * globus_nexus_proto_t is similar to globus_nexus_buffer_t.
 * Each protocol will have to add data to its version of a proto_t.
 * This structure is the common root to all of them -- all proto_t's
 * should start with these same fields.
 *
 * This part of the globus_nexus_proto_t needs to live here so that
 * macros below can work.
 */
struct globus_nexus_proto_s
{
    globus_nexus_proto_type_t		type;
    globus_nexus_proto_funcs_t *	funcs;
    int					version;
    unsigned long			direct_custom_min_size;
    unsigned long			direct_custom_max_size;
    unsigned long			direct_pointer_min_size;
    unsigned long			direct_pointer_max_size;
    globus_bool_t			can_use_iovec;
    unsigned long			reserved_header_size;
    /* reserved_header_size must be a multiple of NEXUS_ALIGN_MESSAGE_SIZE */
};


/*
 * globus_nexus_mi_proto_t
 *
 * This structure contains a "machine independent" representation
 * of the protocols that can be used by a global pointer (gp) to
 * deliver a message for that gp.
 *
 * The protocols are stored in the packed byte array.
 * The contents of this byte array are:
 *	node number (4 byte, big endian integer)
 *		The node number to which this mi_proto points.
 *	context differentiator (4 byte, big endian integer)
 *		When contexts are implemented as processes, it is
 *		possible for the node number, node name, and
 *		context address (stored in the gp->liba)
 *		to be identical between two gp's
 *		even though they really point to different
 * 		contexts.  This can happen because the context
 *		address which is stored in the gp->liba is _not_
 *		a unique context id within this node, but
 *		rather is only unique within a single process that
 *		is part of a node.
 *		The context differentiator disambiguates this situation.
 *		Generally it contains the process id of the process
 *		representing this mi_proto.
 *	node number (null terminated string)
 *	protocols: 0 or more entries of the following form
 *	    protocol type (2 byte, big endian integer)
 *	    size of next array (2 byte, big endian integer)
 *	    protocol specific byte array
 *		This contains information that a protocol module can
 *		use to deliver a message.
 *
 * The 'proto' field is an instantiated version on one of the protocols
 * in the byte 'array'.
 *
 * This structure is _not_ reference counted, though the globus_nexus_proto_t
 * object stored in this structure is.  The globus_nexus_proto_t reference
 * count is of the number of global pointers which point through this
 * globus_nexus_mi_proto_t structure to the given globus_nexus_proto_t object.
 */
struct globus_nexus_mi_proto_s
{
    globus_nexus_proto_t *		proto;
    struct globus_nexus_mi_proto_s *	next;
    int					size;
    globus_byte_t *			array;
};



/*********************************************************************
 * Miscellaneous typedefs and structures
 *********************************************************************/

/*
 * Nexus resources
 */
#ifdef BUILD_RESOURCE

typedef enum {
#define NEXUS_RESOURCE_NTYPES	4
        RESOURCE_SOCKET = 0,
        RESOURCE_PROCESS = 1,
        RESOURCE_THREAD = 2,
        RESOURCE_MEMORY = 3
} nexus_resource_type;

typedef struct globus_nexus_resource_name_s {
	int			id;
	nexus_resource_type	type;
} nexus_resource_name_t;
#define nexus_resource_macro_sizeof_name(Count) \
	(Count * nexus_sizeof_int(2))

typedef enum {
#define NEXUS_RUSAGE_N_OPS   3
        RUSAGE_CREATE,
        RUSAGE_DESTROY,
        RUSAGE_MODIFY
} nexus_rusage_op;

typedef struct _nexus_rusage_obj {
	nexus_resource_name_t*	who;
        nexus_rusage_op 	op;
} nexus_rusage_obj;

#endif /* BUILD_RESOURCE */


/*
 * globus_nexus_context_t
 *
 * Hold context info.
 *
 * The segment_list is a circular, doubly linked list, with a dummy
 * first segment.
 */
typedef struct globus_nexus_context_s
{
    globus_mutex_t			mutex;
    int					id;
    struct globus_nexus_context_s *	context_list_next;

    /* nexus_malloc() segments */
    int					n_segments;
    struct globus_nexus_segment_s *	segment_list;

#ifdef NEXUS_CONTEXT_CREATE_LOCAL
    /* dynamic context loading stuff */
    void *                      handle;
    int                         (*entry_point)(void *);
    void                        (*switchingfunc)(void *);
    int                         (*destructofunc)(struct globus_nexus_context_s *);
    int                         (*pfnNexusBoot)(globus_nexus_startpoint_t *sp);
#endif /* NEXUS_CONTEXT_CREATE_LOCAL */

#ifdef BUILD_RESOURCE
    nexus_resource_name_t	resource_name;
#endif /* BUILD_RESOURCE */

} globus_nexus_context_t;

typedef struct globus_nexus_proto_info_udp_s
{
    unsigned int		pi_id;
    char *			host;
    unsigned short		port;
    globus_byte_t		ttl;
    globus_bool_t		loopback;
    globus_bool_t		multi_sender;
} globus_nexus_proto_info_udp_t;

typedef struct globus_nexus_proto_info_totem_s
{
    long			process_group;
} globus_nexus_proto_info_totem_t;

/*
typedef struct
{

    globus_bool_t sender;     / * sender flag * /
    int diameter;             / * multicast diameter * /
    struct in_addr addr;      / * multicast group address * /
    short port;               / * port numbers * /
    int sreq_freq;	      / * how often to send SREQ flag * /
}
nexus_proto_info_xtp_t;
*/
struct globus_nexus_endpointattr_s
{
    globus_nexus_handler_t *		handler_table;
    int					handler_table_size;
    globus_nexus_unknown_handler_func_t	unknown_handler;
    globus_nexus_handler_type_t		unknown_handler_type;
    int					transform_id;
    globus_nexus_transformattr_t *	transform_attr;
    globus_nexus_proto_type_t		proto_type;
    void *				proto_info;
    globus_nexus_context_t *		context;
};

#if (SIZEOF_LONG <= 4)
    typedef unsigned long globus_i_nexus_endpoint_id_t;
#else
    typedef unsigned globus_i_nexus_endpoint_id_t;
#endif

struct globus_nexus_endpoint_s
{
    globus_nexus_handler_t *		handler_table;
    int					handler_table_size;
    globus_nexus_unknown_handler_func_t	unknown_handler;
    globus_nexus_handler_type_t		unknown_handler_type;
    int					transform_id;
    globus_nexus_transformstate_t *	transform_state;
    globus_nexus_proto_type_t		proto_type;
    globus_nexus_mi_proto_t *		mi_proto;
    globus_nexus_context_t *		context;
    void *				user_pointer;
    globus_i_nexus_endpoint_id_t	id;
};

struct globus_nexus_startpoint_s
{
    globus_nexus_mi_proto_t *  mi_proto;
    unsigned int	dont_copy	: 1; /* TODO: 1==cannot copy sp */
    unsigned int	copy_locally	: 1; /* 0==sp_copy must roundtrip */
    unsigned int	destroy_locally	: 1; /* 0==sp_destroy must roundtrip */
    unsigned int        liba_is_inline  : 1; /* 0==array, 1==pointer */
    unsigned int	liba_size       : 8;
    unsigned int	transform_id	: 8;
    globus_nexus_transformstate_t *	transform_state;
    globus_i_nexus_endpoint_id_t	endpoint_id;
    union
    {
        globus_byte_t *  pointer;                        /* liba_is_inline==0*/
        globus_byte_t    array[NEXUS_DEFAULT_LIBA_SIZE]; /* liba_is_inline==1*/
    } liba;
};


/*
 * globus_nexus_segment_t
 *
 * Holds one data segment in a context.
 */
typedef struct globus_nexus_segment_s
{
    void *				data;
    unsigned int			size;
    struct globus_nexus_context_s *	context;
    struct globus_nexus_segment_s *	prev;
    struct globus_nexus_segment_s *	next;
} globus_nexus_segment_t;


#define globus_nexus_stdio_lock()      globus_libc_lock()
#define globus_nexus_stdio_unlock()    globus_libc_unlock()

/*********************************************************************
 * Protocol module function indirection table
 *********************************************************************/

struct globus_nexus_proto_funcs_s
{
    globus_nexus_proto_type_t	(*proto_type)(void);
    void		(*init)(globus_bool_t * add_to_my_mi_proto);
    void		(*shutdown)(void);
    void                (*increment_reference_count)(globus_nexus_proto_t *proto);
    globus_bool_t	(*decrement_reference_count)(globus_nexus_proto_t *proto);
    int			(*get_my_mi_proto)(globus_byte_t **array,
					   int *size,
					   void *proto_info,
					   globus_nexus_endpoint_t *endpoint);
    globus_bool_t	(*construct_from_mi_proto)(globus_nexus_proto_t **proto,
						   globus_nexus_mi_proto_t *mi_proto,
						   globus_byte_t *array,
						   int size);
    int			(*destroy_my_mi_proto)(globus_nexus_endpoint_t * endpoint,
					       globus_byte_t * array,
					       int size);
    int			(*test_proto)(globus_nexus_proto_t *proto);
    int			(*send_rsr)(struct globus_nexus_buffer_s *buffer);
    globus_bool_t	(*send_rsr_outstanding)(globus_nexus_proto_t *nproto);
    int                 (*direct_info_size)(void);
    int                 (*direct_get)(globus_byte_t *dest,
				      size_t n_bytes,
				      int action,
				      unsigned long info);
    globus_bool_t       (*startpoint_proto_match)(globus_nexus_mi_proto_t * mi_proto0,
						  int             offset0,
						  globus_byte_t * subarray0,
					          int             sub_length0,
						  globus_nexus_mi_proto_t * mi_proto1,
						  int             offset1,
						  globus_byte_t * subarray1,
						  int             sub_length1);
    int                 (*proto_count)(void);
#ifdef BUILD_RESOURCE
    nexus_resource_name_t * (*get_resource_name_sp)(globus_nexus_startpoint_t *);
    nexus_resource_name_t * (*get_resource_name_ep)(globus_nexus_endpoint_t *);
#endif /* BUILD_RESOURCE */
};


/*********************************************************************
 *
 * Exported interface declarations
 *
 *********************************************************************/

/*********************************************************************
 * nexus_endpointattr_*() prototypes
 *********************************************************************/
extern int
nexus_endpointattr_init(globus_nexus_endpointattr_t *endpointattr);

extern int
nexus_endpointattr_destroy(globus_nexus_endpointattr_t *endpointattr);

extern int
nexus_endpointattr_set_handler_table(globus_nexus_endpointattr_t *endpointattr,
				     globus_nexus_handler_t *handler_table,
				     int handler_table_size);

extern int
nexus_endpointattr_get_handler_table(globus_nexus_endpointattr_t *endpointattr,
				     globus_nexus_handler_t **handler_table,
				     int *handler_table_size);

extern int
nexus_endpointattr_set_unknown_handler(globus_nexus_endpointattr_t *endpointattr,
				       globus_nexus_unknown_handler_func_t func,
				       globus_nexus_handler_type_t type);

extern int
nexus_endpointattr_get_unknown_handler(globus_nexus_endpointattr_t *endpointattr,
				       globus_nexus_unknown_handler_func_t *func,
				       globus_nexus_handler_type_t *type);

extern int
nexus_endpointattr_set_transform(globus_nexus_endpointattr_t *endpointattr,
				 int transform_id,
				 void *transform_info);

extern int
nexus_endpointattr_get_transform(globus_nexus_endpointattr_t *endpointattr,
				 int *transform_id,
				 void **transform_info);

extern int
nexus_endpointattr_set_protocol(globus_nexus_endpointattr_t *epattr,
				globus_nexus_proto_type_t proto_type,
				void *proto_info,
				int proto_info_length);

extern int
nexus_endpointattr_get_protocol(globus_nexus_endpointattr_t *epattr,
				globus_nexus_proto_type_t *proto_type,
				void **proto_info);
/*********************************************************************
 * nexus_endpointstate_*() prototypes
 *********************************************************************/
extern int
nexus_endpointstate_get_transform(globus_nexus_endpoint_t *ep,
                                        void *info);

extern int
nexus_startpointstate_get_transform(globus_nexus_startpoint_t *sp,
                                        void *info);

/*********************************************************************
 * nexus_endpoint_*() prototypes
 *********************************************************************/
extern
void
globus_nexus_proto_info_udp_init(
    globus_nexus_proto_info_udp_t *		pi);

extern int
nexus_endpoint_init(globus_nexus_endpoint_t *endpoint,
		    globus_nexus_endpointattr_t *endpointattr);

extern int
nexus_endpoint_destroy(globus_nexus_endpoint_t *endpoint);

extern int
nexus_endpoint_string(globus_nexus_endpoint_t *endpoint,
		      char *string,
		      int length);

/*********************************************************************
 * nexus_startpoint_*() prototypes
 *********************************************************************/
extern int
nexus_startpoint_bind(globus_nexus_startpoint_t *startpoint,
		      globus_nexus_endpoint_t *endpoint);

extern int
nexus_startpoint_copy(globus_nexus_startpoint_t *dest_startpoint,
		      globus_nexus_startpoint_t *src_startpoint);

extern int
nexus_startpoint_destroy(globus_nexus_startpoint_t *startpoint);

extern int
nexus_startpoint_destroy_and_notify(globus_nexus_startpoint_t *sp);

extern int
nexus_startpoint_equal_context(globus_nexus_startpoint_t *sp1,
			       globus_nexus_startpoint_t *sp2);

extern int
nexus_startpoint_equal(globus_nexus_startpoint_t *sp1,
		       globus_nexus_startpoint_t *sp2);

extern int
nexus_startpoint_to_current_context(globus_nexus_startpoint_t *sp);

extern int
nexus_startpoint_get_endpoint(globus_nexus_startpoint_t *sp,
			      globus_nexus_endpoint_t **ep);

extern int
nexus_startpoint_string(globus_nexus_startpoint_t *startpoint,
			char *string,
			int length);

extern void
globus_nexus_startpoint_flush(globus_nexus_startpoint_t *startpoint);

extern int
globus_nexus_startpoint_num_protos(globus_nexus_startpoint_t * sp);

extern globus_bool_t
globus_nexus_startpoint_proto_match(globus_nexus_startpoint_t * sp0,
				    int                         proto_index_0,
				    globus_nexus_startpoint_t * sp1,
				    int                         proto_index_1);

/*********************************************************************
 * Buffer management function prototypes
 *********************************************************************/
/* temporary addition for mpichG QoS */

extern globus_bool_t
globus_i_nexus_get_host_port_pairs(
    globus_nexus_startpoint_t *            sp,
    char                                   localhost[16],
    int *                                  localport,
    char                                   remotehost[16],
    int *                                  remoteport);

extern int
globus_i_nexus_startpoint_to_fd(globus_nexus_startpoint_t * sp);

extern int
nexus_put_startpoint_transfer(globus_nexus_buffer_t *buffer,
			      globus_nexus_startpoint_t *sp,
			      unsigned long count);

extern int
nexus_user_put_startpoint_transfer(globus_byte_t **user_buffer,
				   globus_nexus_startpoint_t *sp,
				   unsigned long count);

extern int
nexus_get_startpoint(globus_nexus_buffer_t *buffer,
		     globus_nexus_startpoint_t *sp,
		     unsigned long count);

extern int
nexus_user_get_startpoint(globus_byte_t **user_buffer,
			  globus_nexus_startpoint_t *sp,
			  unsigned long count,
			  int format);

extern int
nexus_sizeof_startpoint(globus_nexus_startpoint_t *sp, int count);

extern int
nexus_buffer_init(globus_nexus_buffer_t *buffer,
		  unsigned long buffer_size,
		  unsigned long num_direct_puts);

extern int
nexus_buffer_destroy(globus_nexus_buffer_t *buffer);

extern int
nexus_check_buffer_size(globus_nexus_buffer_t *buffer,
			int size_needed,
			int size_increment,
			int num_direct_puts_needed,
			int num_direct_puts_increment);

extern int
nexus_send_rsr(globus_nexus_buffer_t *buffer,
	       globus_nexus_startpoint_t *startpoint,
	       int handler_id,
	       globus_bool_t destroy_buffer,
	       globus_bool_t called_from_non_threaded_handler);

extern int
nexus_buffer_save(globus_nexus_buffer_t *buffer);

extern int
nexus_buffer_save_linearly(globus_nexus_buffer_t *buffer);

/*********************************************************************
 * Error codes and fault tolerance stuff
 *********************************************************************/

#define GLOBUS_NEXUS_ERROR_NONE				 0
#define GLOBUS_NEXUS_ERROR_UNKNOWN			-1
#define GLOBUS_NEXUS_ERROR_PROCESS_DIED			-2
#define GLOBUS_NEXUS_ERROR_PROCESS_SHUTDOWN_ABNORMALLY	-3
#define GLOBUS_NEXUS_ERROR_PROCESS_SHUTDOWN_NORMALLY	-4
#define GLOBUS_NEXUS_ERROR_ACCEPT_ATTACH_FAILED		-5
#define GLOBUS_NEXUS_ERROR_CONNECT_FAILED		-6
#define GLOBUS_NEXUS_ERROR_BAD_PROTOCOL			-7
#define GLOBUS_NEXUS_ERROR_READ_FAILED			-8
#define GLOBUS_NEXUS_ERROR_BAD_URL			-9
#define GLOBUS_NEXUS_ERROR_BUFFER_OVERFLOW		-10
#define GLOBUS_NEXUS_ERROR_INVALID_PARAMETER		-11
#define GLOBUS_NEXUS_ERROR_INVALID_RETURN		-12
#define GLOBUS_NEXUS_ERROR_ALREADY_INITIALIZED		-13
#define GLOBUS_NEXUS_ERROR_NOT_INITIALIZED		-14
#define GLOBUS_NEXUS_ERROR_ENDPOINT_DESTROYED		-15
#define GLOBUS_NEXUS_ERROR_UNIMPLEMENTED                -16
#define GLOBUS_NEXUS_ERROR_VERSION_MISMATCH             -17
#define GLOBUS_NEXUS_ERROR_BUFFER_TOO_LONG              -18
#define GLOBUS_NEXUS_ERROR_NO_COMPATIBLE_PROTOCOLS      -19
#define GLOBUS_NEXUS_ERROR_RESOURCE_UNAVAILABLE		-20

extern void
nexus_enable_fault_tolerance(int (*callback_func)(void *user_arg,
						  int fault_code),
			     void *callback_func_user_arg);

extern int
nexus_startpoint_test(globus_nexus_startpoint_t *sp);



/*********************************************************************
 * Event driver interface
 *********************************************************************/

/*
 * TODO: This should move into a separate Nexus Component Library
 */

/*********************************************************************
 * Function prototypes that are not part of the official interface
 *********************************************************************/

/*
 * attach.c
 */
extern int	nexus_allow_attach(unsigned short *port,
				   char **host,
				   int (*approval_func)(void *user_arg,
							char *url,
							globus_nexus_startpoint_t *sp),
				   void *approval_func_user_arg);
extern void	nexus_disallow_attach(unsigned short port);
extern int	nexus_attach(char *url,
			     globus_nexus_startpoint_t *sp);
extern int	nexus_split_url(char *url,
				char **host,
				unsigned short *port,
				char ***specifiers);
extern void	nexus_split_url_free(char **host,
				     char ***specifiers);


/*
 * option.c
 */
extern char *
globus_nexus_option_find(char *option);


/*
 * rdb_iface.c
 */
extern char *   nexus_rdb_lookup(char *node_name, char *key);
extern void     nexus_rdb_free(char *value);


/*
 * utils.c
 */
extern void		nexus_ids(int *context_id,
				  int *thread_id);



/******************************************************************************
 *			       Module definition
 *****************************************************************************/

extern int
globus_i_nexus_activate(void);

extern int
globus_i_nexus_deactivate(void);

/* REFERENCED */
extern globus_module_descriptor_t	globus_nexus_module;

#define GLOBUS_NEXUS_MODULE (&globus_nexus_module)

/*********************************************************************
 * Interface routines that can be implemented as macros
 *********************************************************************/

#define nexus_macro_endpoint_set_user_pointer(endpoint, address) \
    (endpoint)->user_pointer = (address)
#define nexus_macro_endpoint_get_user_pointer(endpoint) \
    (endpoint)->user_pointer
#define nexus_macro_startpoint_set_null(startpoint) \
    (startpoint)->mi_proto = (globus_nexus_mi_proto_t *) NULL
#define nexus_macro_startpoint_is_null(startpoint) \
    ((startpoint)->mi_proto == (globus_nexus_mi_proto_t *) NULL)

#ifndef USE_MACROS

extern void     nexus_endpoint_set_user_pointer(globus_nexus_endpoint_t *endpoint,
						void *address);
extern void *   nexus_endpoint_get_user_pointer(globus_nexus_endpoint_t *endpoint);
extern void     nexus_startpoint_set_null(globus_nexus_startpoint_t *startpoint);
extern int      nexus_startpoint_is_null(globus_nexus_startpoint_t *startpoint);

#else  /* USE_MACROS */

#define nexus_endpoint_set_user_pointer(endpoint, address) \
    nexus_macro_endpoint_set_user_pointer(endpoint, address)
#define nexus_endpoint_get_user_pointer(endpoint) \
    nexus_macro_endpoint_get_user_pointer(endpoint)
#define nexus_startpoint_set_null(startpoint) \
    nexus_macro_startpoint_set_null(startpoint)
#define nexus_startpoint_is_null(startpoint) \
    nexus_macro_startpoint_is_null(startpoint)

#endif /* USE_MACROS */


/*
 * nexus_user_format()
 */
#define nexus_user_format() (GLOBUS_DC_FORMAT_LOCAL)


/*********************************************************************
 * nexus_sizeof_DATATYPE()
 *********************************************************************/

#define nexus_macro_sizeof_float(Count) \
    (nexus_dc_sizeof_float(Count))
#define nexus_macro_sizeof_double(Count) \
    (nexus_dc_sizeof_double(Count))
#define nexus_macro_sizeof_short(Count) \
    (nexus_dc_sizeof_short(Count))
#define nexus_macro_sizeof_u_short(Count) \
    (nexus_dc_sizeof_u_short(Count))
#define nexus_macro_sizeof_int(Count) \
    (nexus_dc_sizeof_int(Count))
#define nexus_macro_sizeof_u_int(Count) \
    (nexus_dc_sizeof_u_int(Count))
#define nexus_macro_sizeof_long(Count) \
    (nexus_dc_sizeof_long(Count))
#define nexus_macro_sizeof_u_long(Count) \
    (nexus_dc_sizeof_u_long(Count))
#define nexus_macro_sizeof_char(Count) \
    (nexus_dc_sizeof_char(Count))
#define nexus_macro_sizeof_u_char(Count) \
    (nexus_dc_sizeof_u_char(Count))
#define nexus_macro_sizeof_byte(Count) \
    (nexus_dc_sizeof_byte(Count))

#ifndef USE_MACROS

extern int	nexus_sizeof_float(int count);
extern int	nexus_sizeof_double(int count);
extern int	nexus_sizeof_short(int count);
extern int	nexus_sizeof_u_short(int count);
extern int	nexus_sizeof_int(int count);
extern int	nexus_sizeof_u_int(int count);
extern int	nexus_sizeof_long(int count);
extern int	nexus_sizeof_u_long(int count);
extern int	nexus_sizeof_char(int count);
extern int	nexus_sizeof_u_char(int count);
extern int	nexus_sizeof_byte(int count);

#else  /* USE_MACROS */

#define nexus_sizeof_float(count) \
    nexus_macro_sizeof_float(count)
#define nexus_sizeof_double(count) \
    nexus_macro_sizeof_double(count)
#define nexus_sizeof_short(count) \
    nexus_macro_sizeof_short(count)
#define nexus_sizeof_u_short(count) \
    nexus_macro_sizeof_u_short(count)
#define nexus_sizeof_int(count) \
    nexus_macro_sizeof_int(count)
#define nexus_sizeof_u_int(count) \
    nexus_macro_sizeof_u_int(count)
#define nexus_sizeof_long(count) \
    nexus_macro_sizeof_long(count)
#define nexus_sizeof_u_long(count) \
    nexus_macro_sizeof_u_long(count)
#define nexus_sizeof_char(count) \
    nexus_macro_sizeof_char(count)
#define nexus_sizeof_u_char(count) \
    nexus_macro_sizeof_u_char(count)
#define nexus_sizeof_byte(count) \
    nexus_macro_sizeof_byte(count)

#endif /* USE_MACROS */


/*********************************************************************
 * nexus_put_DATATYPE()
 *********************************************************************/

extern void nexus_put_float(globus_nexus_buffer_t *buffer,
			    float *data,
			    int count);
extern void nexus_put_double(globus_nexus_buffer_t *buffer,
			     double *data,
			     int count);
extern void nexus_put_short(globus_nexus_buffer_t *buffer,
			    short *data,
			    int count);
extern void nexus_put_u_short(globus_nexus_buffer_t *buffer,
			      unsigned short *data,
			      int count);
extern void nexus_put_int(globus_nexus_buffer_t *buffer,
			  int *data,
			  int count);
extern void nexus_put_u_int(globus_nexus_buffer_t *buffer,
			    unsigned int *data,
			    int count);
extern void nexus_put_long(globus_nexus_buffer_t *buffer,
			   long *data,
			   int count);
extern void nexus_put_u_long(globus_nexus_buffer_t *buffer,
			     unsigned long *data,
			     int count);
extern void nexus_put_char(globus_nexus_buffer_t *buffer,
			   char *data,
			   int count);
extern void nexus_put_u_char(globus_nexus_buffer_t *buffer,
			     unsigned char *data,
			     int count);
extern void nexus_put_byte(globus_nexus_buffer_t *buffer,
			   globus_byte_t *data,
			   int count);
extern void nexus_put_user(globus_nexus_buffer_t *buffer,
			   globus_byte_t *data,
			   int count);

/*********************************************************************
 * nexus_get_DATATYPE()
 *********************************************************************/

extern void nexus_get_float(globus_nexus_buffer_t *buffer,
			    float *dest,
			    int count);
extern void nexus_get_double(globus_nexus_buffer_t *buffer,
			     double *dest,
			     int count);
extern void nexus_get_short(globus_nexus_buffer_t *buffer,
			    short *dest,
			    int count);
extern void nexus_get_u_short(globus_nexus_buffer_t *buffer,
			      unsigned short *dest,
			      int count);
extern void nexus_get_int(globus_nexus_buffer_t *buffer,
			  int *dest,
			  int count);
extern void nexus_get_u_int(globus_nexus_buffer_t *buffer,
			    unsigned int *dest,
			    int count);
extern void nexus_get_long(globus_nexus_buffer_t *buffer,
			   long *dest,
			   int count);
extern void nexus_get_u_long(globus_nexus_buffer_t *buffer,
			     unsigned long *dest,
			     int count);
extern void nexus_get_char(globus_nexus_buffer_t *buffer,
			   char *dest,
			   int count);
extern void nexus_get_u_char(globus_nexus_buffer_t *buffer,
			     unsigned char *dest,
			     int count);
extern void nexus_get_byte(globus_nexus_buffer_t *buffer,
			   globus_byte_t *dest,
			   int count);
extern void nexus_get_user(globus_nexus_buffer_t *buffer,
			   globus_byte_t *dest,
			   int count);
extern void nexus_get_rtphdr(globus_nexus_buffer_t *buffer,
			     globus_byte_t *dest,
			     int count);

/*********************************************************************
 * nexus_direct_put_DATATYPE()
 *********************************************************************/

extern void _nx_direct_put(globus_nexus_buffer_t *buffer,
			   void *data,
			   unsigned long count,
			   int datatype,
			   int sizeof_datatype);

#define nexus_macro_direct_put_float(buffer, data, count) \
    _nx_direct_put(buffer, data, count, \
		   NEXUS_DC_DATATYPE_FLOAT, \
		   nexus_dc_sizeof_float(1))
#define nexus_macro_direct_put_double(buffer, data, count) \
    _nx_direct_put(buffer, data, count, \
		   NEXUS_DC_DATATYPE_DOUBLE, \
		   nexus_dc_sizeof_double(1))
#define nexus_macro_direct_put_short(buffer, data, count) \
    _nx_direct_put(buffer, data, count, \
		   NEXUS_DC_DATATYPE_SHORT, \
		   nexus_dc_sizeof_short(1))
#define nexus_macro_direct_put_u_short(buffer, data, count) \
    _nx_direct_put(buffer, data, count, \
		   NEXUS_DC_DATATYPE_U_SHORT, \
		   nexus_dc_sizeof_u_short(1))
#define nexus_macro_direct_put_int(buffer, data, count) \
    _nx_direct_put(buffer, data, count, \
		   NEXUS_DC_DATATYPE_INT, \
		   nexus_dc_sizeof_int(1))
#define nexus_macro_direct_put_u_int(buffer, data, count) \
    _nx_direct_put(buffer, data, count, \
		   NEXUS_DC_DATATYPE_U_INT, \
		   nexus_dc_sizeof_u_int(1))
#define nexus_macro_direct_put_long(buffer, data, count) \
    _nx_direct_put(buffer, data, count, \
		   NEXUS_DC_DATATYPE_LONG, \
		   nexus_dc_sizeof_long(1))
#define nexus_macro_direct_put_u_long(buffer, data, count) \
    _nx_direct_put(buffer, data, count, \
		   NEXUS_DC_DATATYPE_U_LONG, \
		   nexus_dc_sizeof_u_long(1))
#define nexus_macro_direct_put_char(buffer, data, count) \
    _nx_direct_put(buffer, data, count, \
		   NEXUS_DC_DATATYPE_CHAR, \
		   nexus_dc_sizeof_char(1))
#define nexus_macro_direct_put_u_char(buffer, data, count) \
    _nx_direct_put(buffer, data, count, \
		   NEXUS_DC_DATATYPE_U_CHAR, \
		   nexus_dc_sizeof_u_char(1))
#define nexus_macro_direct_put_byte(buffer, data, count) \
    _nx_direct_put(buffer, data, count, \
		   NEXUS_DC_DATATYPE_BYTE, \
		   nexus_dc_sizeof_byte(1))
#define nexus_macro_direct_put_user(buffer, data, count) \
    _nx_direct_put(buffer, data, count, \
		   NEXUS_DC_DATATYPE_BYTE, \
		   nexus_dc_sizeof_byte(1))

#ifndef USE_MACROS

extern void nexus_direct_put_float(globus_nexus_buffer_t *buffer,
				   float *data,
				   int count);
extern void nexus_direct_put_double(globus_nexus_buffer_t *buffer,
				    double *data,
				    int count);
extern void nexus_direct_put_short(globus_nexus_buffer_t *buffer,
				   short *data,
				   int count);
extern void nexus_direct_put_u_short(globus_nexus_buffer_t *buffer,
				     unsigned short *data,
				     int count);
extern void nexus_direct_put_int(globus_nexus_buffer_t *buffer,
				 int *data,
				 int count);
extern void nexus_direct_put_u_int(globus_nexus_buffer_t *buffer,
				   unsigned int *data,
				   int count);
extern void nexus_direct_put_long(globus_nexus_buffer_t *buffer,
				  long *data, int count);
extern void nexus_direct_put_u_long(globus_nexus_buffer_t *buffer,
				    unsigned long *data,
				    int count);
extern void nexus_direct_put_char(globus_nexus_buffer_t *buffer,
				  char *data,
				  int count);
extern void nexus_direct_put_u_char(globus_nexus_buffer_t *buffer,
				    unsigned char *data,
				    int count);
extern void nexus_direct_put_byte(globus_nexus_buffer_t *buffer,
				  globus_byte_t *data,
				  int count);
extern void nexus_direct_put_user(globus_nexus_buffer_t *buffer,
				  globus_byte_t *data,
				  int count);

#else  /* USE_MACROS */

#define nexus_direct_put_float(buffer, data, count) \
    nexus_macro_direct_put_float(buffer, data, count)
#define nexus_direct_put_double(buffer, data, count) \
    nexus_macro_direct_put_double(buffer, data, count)
#define nexus_direct_put_short(buffer, data, count) \
    nexus_macro_direct_put_short(buffer, data, count)
#define nexus_direct_put_u_short(buffer, data, count) \
    nexus_macro_direct_put_u_short(buffer, data, count)
#define nexus_direct_put_int(buffer, data, count) \
    nexus_macro_direct_put_int(buffer, data, count)
#define nexus_direct_put_u_int(buffer, data, count) \
    nexus_macro_direct_put_u_int(buffer, data, count)
#define nexus_direct_put_long(buffer, data, count) \
    nexus_macro_direct_put_long(buffer, data, count)
#define nexus_direct_put_u_long(buffer, data, count) \
    nexus_macro_direct_put_u_long(buffer, data, count)
#define nexus_direct_put_char(buffer, data, count) \
    nexus_macro_direct_put_char(buffer, data, count)
#define nexus_direct_put_u_char(buffer, data, count) \
    nexus_macro_direct_put_u_char(buffer, data, count)
#define nexus_direct_put_byte(buffer, data, count) \
    nexus_macro_direct_put_byte(buffer, data, count)
#define nexus_direct_put_user(buffer, data, count) \
    nexus_macro_direct_put_user(buffer, data, count)

#endif /* USE_MACROS */


/*********************************************************************
 * nexus_direct_get_DATATYPE()
 *********************************************************************/

extern void nexus_direct_get_float(globus_nexus_buffer_t *buffer,
				   float *dest,
				   int count);
extern void nexus_direct_get_double(globus_nexus_buffer_t *buffer,
				    double *dest,
				    int count);
extern void nexus_direct_get_short(globus_nexus_buffer_t *buffer,
				   short *dest,
				   int count);
extern void nexus_direct_get_u_short(globus_nexus_buffer_t *buffer,
				     unsigned short *dest,
				     int count);
extern void nexus_direct_get_int(globus_nexus_buffer_t *buffer,
				 int *dest,
				 int count);
extern void nexus_direct_get_u_int(globus_nexus_buffer_t *buffer,
				   unsigned int *dest,
				   int count);
extern void nexus_direct_get_long(globus_nexus_buffer_t *buffer,
				  long *dest,
				  int count);
extern void nexus_direct_get_u_long(globus_nexus_buffer_t *buffer,
				    unsigned long *dest,
				    int count);
extern void nexus_direct_get_char(globus_nexus_buffer_t *buffer,
				  char *dest,
				  int count);
extern void nexus_direct_get_u_char(globus_nexus_buffer_t *buffer,
				    unsigned char *dest,
				    int count);
extern void nexus_direct_get_byte(globus_nexus_buffer_t *buffer,
				  globus_byte_t *dest,
				  int count);
extern void nexus_direct_get_user(globus_nexus_buffer_t *buffer,
				  globus_byte_t *dest,
				  int count);

/*********************************************************************
 * nexus_user_put_DATATYPE()
 *********************************************************************/

#define nexus_macro_user_put_float(User_buffer, Data, Count) \
    nexus_dc_put_float(User_buffer, Data, Count)
#define nexus_macro_user_put_double(User_buffer, Data, Count) \
    nexus_dc_put_double(User_buffer, Data, Count)
#define nexus_macro_user_put_short(User_buffer, Data, Count) \
    nexus_dc_put_short(User_buffer, Data, Count)
#define nexus_macro_user_put_u_short(User_buffer, Data, Count) \
    nexus_dc_put_u_short(User_buffer, Data, Count)
#define nexus_macro_user_put_int(User_buffer, Data, Count) \
    nexus_dc_put_int(User_buffer, Data, Count)
#define nexus_macro_user_put_u_int(User_buffer, Data, Count) \
    nexus_dc_put_u_int(User_buffer, Data, Count)
#define nexus_macro_user_put_long(User_buffer, Data, Count) \
    nexus_dc_put_long(User_buffer, Data, Count)
#define nexus_macro_user_put_u_long(User_buffer, Data, Count) \
    nexus_dc_put_u_long(User_buffer, Data, Count)
#define nexus_macro_user_put_char(User_buffer, Data, Count) \
    nexus_dc_put_char(User_buffer, Data, Count)
#define nexus_macro_user_put_u_char(User_buffer, Data, Count) \
    nexus_dc_put_u_char(User_buffer, Data, Count)
#define nexus_macro_user_put_byte(User_buffer, Data, Count) \
    nexus_dc_put_byte(User_buffer, Data, Count)

#ifndef USE_MACROS

extern void nexus_user_put_float(globus_byte_t **user_buffer,
				 float *data,
				 unsigned long count);
extern void nexus_user_put_double(globus_byte_t **user_buffer,
				  double *data,
				  unsigned long count);
extern void nexus_user_put_short(globus_byte_t **user_buffer,
				 short *data,
				 unsigned long count);
extern void nexus_user_put_u_short(globus_byte_t **user_buffer,
				   unsigned short *data,
				   unsigned long count);
extern void nexus_user_put_int(globus_byte_t **user_buffer,
			       int *data,
			       unsigned long count);
extern void nexus_user_put_u_int(globus_byte_t **user_buffer,
				 unsigned int *data,
				 unsigned long count);
extern void nexus_user_put_long(globus_byte_t **user_buffer,
				long *data,
				unsigned long count);
extern void nexus_user_put_u_long(globus_byte_t **user_buffer,
				  unsigned long *data,
				  unsigned long count);
extern void nexus_user_put_char(globus_byte_t **user_buffer,
				char *data,
				unsigned long count);
extern void nexus_user_put_u_char(globus_byte_t **user_buffer,
				  unsigned char *data,
				  unsigned long count);
extern void nexus_user_put_byte(globus_byte_t **user_buffer,
				globus_byte_t *data,
				unsigned long count);

#else /* USE_MACROS */

#define nexus_user_put_float(User_buffer, Data, Count) \
    nexus_macro_user_put_float(User_buffer, Data, Count)
#define nexus_user_put_double(User_buffer, Data, Count) \
    nexus_macro_user_put_double(User_buffer, Data, Count)
#define nexus_user_put_short(User_buffer, Data, Count) \
    nexus_macro_user_put_short(User_buffer, Data, Count)
#define nexus_user_put_u_short(User_buffer, Data, Count) \
    nexus_macro_user_put_u_short(User_buffer, Data, Count)
#define nexus_user_put_int(User_buffer, Data, Count) \
    nexus_macro_user_put_int(User_buffer, Data, Count)
#define nexus_user_put_u_int(User_buffer, Data, Count) \
    nexus_macro_user_put_u_int(User_buffer, Data, Count)
#define nexus_user_put_long(User_buffer, Data, Count) \
    nexus_macro_user_put_long(User_buffer, Data, Count)
#define nexus_user_put_u_long(User_buffer, Data, Count) \
    nexus_macro_user_put_u_long(User_buffer, Data, Count)
#define nexus_user_put_char(User_buffer, Data, Count) \
    nexus_macro_user_put_char(User_buffer, Data, Count)
#define nexus_user_put_u_char(User_buffer, Data, Count) \
    nexus_macro_user_put_u_char(User_buffer, Data, Count)
#define nexus_user_put_byte(User_buffer, Data, Count) \
    nexus_macro_user_put_byte(User_buffer, Data, Count)

#endif /* USE_MACROS */

/*********************************************************************
 * nexus_user_get_DATATYPE()
 *********************************************************************/

#define nexus_macro_user_get_float(User_buffer, Data, Count, Format) \
    nexus_dc_get_float(User_buffer, Data, Count, Format)
#define nexus_macro_user_get_double(User_buffer, Data, Count, Format) \
    nexus_dc_get_double(User_buffer, Data, Count, Format)
#define nexus_macro_user_get_short(User_buffer, Data, Count, Format) \
    nexus_dc_get_short(User_buffer, Data, Count, Format)
#define nexus_macro_user_get_u_short(User_buffer, Data, Count, Format) \
    nexus_dc_get_u_short(User_buffer, Data, Count, Format)
#define nexus_macro_user_get_int(User_buffer, Data, Count, Format) \
    nexus_dc_get_int(User_buffer, Data, Count, Format)
#define nexus_macro_user_get_u_int(User_buffer, Data, Count, Format) \
    nexus_dc_get_u_int(User_buffer, Data, Count, Format)
#define nexus_macro_user_get_long(User_buffer, Data, Count, Format) \
    nexus_dc_get_long(User_buffer, Data, Count, Format)
#define nexus_macro_user_get_u_long(User_buffer, Data, Count, Format) \
    nexus_dc_get_u_long(User_buffer, Data, Count, Format)
#define nexus_macro_user_get_char(User_buffer, Data, Count, Format) \
    nexus_dc_get_char(User_buffer, Data, Count, Format)
#define nexus_macro_user_get_u_char(User_buffer, Data, Count, Format) \
    nexus_dc_get_u_char(User_buffer, Data, Count, Format)
#define nexus_macro_user_get_byte(User_buffer, Data, Count, Format) \
    nexus_dc_get_byte(User_buffer, Data, Count, Format)

#ifndef USE_MACROS

extern void nexus_user_get_float(globus_byte_t **user_buffer,
				 float *data,
				 unsigned long count,
				 int format);
extern void nexus_user_get_double(globus_byte_t **user_buffer,
				  double *data,
				  unsigned long count,
				  int format);
extern void nexus_user_get_short(globus_byte_t **user_buffer,
				 short *data,
				 unsigned long count,
				 int format);
extern void nexus_user_get_u_short(globus_byte_t **user_buffer,
				   unsigned short *data,
				   unsigned long count,
				   int format);
extern void nexus_user_get_int(globus_byte_t **user_buffer,
			       int *data,
			       unsigned long count,
			       int format);
extern void nexus_user_get_u_int(globus_byte_t **user_buffer,
				 unsigned int *data,
				 unsigned long count,
				 int format);
extern void nexus_user_get_long(globus_byte_t **user_buffer,
				long *data,
				unsigned long count,
				int format);
extern void nexus_user_get_u_long(globus_byte_t **user_buffer,
				  unsigned long *data,
				  unsigned long count,
				  int format);
extern void nexus_user_get_char(globus_byte_t **user_buffer,
				char *data,
				unsigned long count,
				int format);
extern void nexus_user_get_u_char(globus_byte_t **user_buffer,
				  unsigned char *data,
				  unsigned long count,
				  int format);
extern void nexus_user_get_byte(globus_byte_t **user_buffer,
				globus_byte_t *data,
				unsigned long count,
				int format);

#else /* USE_MACROS */

#define nexus_user_get_float(User_buffer, Data, Count, Format) \
    nexus_macro_user_get_float(User_buffer, Data, Count, Format)
#define nexus_user_get_double(User_buffer, Data, Count, Format) \
    nexus_macro_user_get_double(User_buffer, Data, Count, Format)
#define nexus_user_get_short(User_buffer, Data, Count, Format) \
    nexus_macro_user_get_short(User_buffer, Data, Count, Format)
#define nexus_user_get_u_short(User_buffer, Data, Count, Format) \
    nexus_macro_user_get_u_short(User_buffer, Data, Count, Format)
#define nexus_user_get_int(User_buffer, Data, Count, Format) \
    nexus_macro_user_get_int(User_buffer, Data, Count, Format)
#define nexus_user_get_u_int(User_buffer, Data, Count, Format) \
    nexus_macro_user_get_u_int(User_buffer, Data, Count, Format)
#define nexus_user_get_long(User_buffer, Data, Count, Format) \
    nexus_macro_user_get_long(User_buffer, Data, Count, Format)
#define nexus_user_get_u_long(User_buffer, Data, Count, Format) \
    nexus_macro_user_get_u_long(User_buffer, Data, Count, Format)
#define nexus_user_get_char(User_buffer, Data, Count, Format) \
    nexus_macro_user_get_char(User_buffer, Data, Count, Format)
#define nexus_user_get_u_char(User_buffer, Data, Count, Format) \
    nexus_macro_user_get_u_char(User_buffer, Data, Count, Format)
#define nexus_user_get_byte(User_buffer, Data, Count, Format) \
    nexus_macro_user_get_byte(User_buffer, Data, Count, Format)

#endif /* USE_MACROS */

EXTERN_C_END

/*********************************************************************
 * Backward compatibility...
 *********************************************************************/

#ifdef GLOBUS_NEXUS_BACKWARD_COMPATIBLE

typedef globus_bool_t			nexus_bool_t;
typedef globus_nexus_proto_type_t	nexus_proto_type_t;
typedef globus_nexus_proto_funcs_t	nexus_proto_funcs_t;
typedef globus_nexus_buffer_t		nexus_buffer_t;
typedef globus_nexus_endpointattr_t	nexus_endpointattr_t;
typedef globus_nexus_endpoint_t		nexus_endpoint_t;
typedef globus_nexus_startpoint_t	nexus_startpoint_t;
typedef globus_nexus_proto_t		nexus_proto_t;
typedef globus_nexus_mi_proto_t		nexus_mi_proto_t;
typedef globus_nexus_transformattr_t	nexus_transformattr_t;
typedef globus_nexus_transformstate_t	nexus_transformstate_t;
typedef globus_nexus_handler_func_t	nexus_handler_func_t;
typedef globus_nexus_unknown_handler_func_t nexus_unknown_handler_func_t;
typedef globus_nexus_handler_type_t	nexus_handler_type_t;
typedef globus_nexus_handler_t		nexus_handler_t;
typedef globus_nexus_module_list_t	nexus_module_list_t;
typedef globus_nexus_list_t		nexus_list_t;
typedef globus_nexus_base_segment_t	nexus_base_segment_t;
typedef globus_nexus_direct_info_t	nexus_direct_info_t;
typedef globus_nexus_direct_segment_t	nexus_direct_segment_t;
typedef globus_nexus_context_t		nexus_context_t;
typedef globus_nexus_proto_info_udp_t	nexus_proto_info_udp_t;
typedef globus_nexus_proto_info_totem_t	nexus_proto_info_totem_t;
typedef globus_nexus_segment_t		nexus_segment_t;

typedef globus_thread_t			nexus_thread_t;
typedef globus_mutex_t			nexus_mutex_t;
typedef globus_mutexattr_t		nexus_mutexattr_t;
typedef globus_cond_t			nexus_cond_t;
typedef globus_condattr_t		nexus_condattr_t;

#ifndef NEXUS_TRUE
#define NEXUS_TRUE			GLOBUS_TRUE
#define NEXUS_FALSE			GLOBUS_FALSE
#endif

#define NEXUS_MAX(V1,V2)		GLOBUS_MAX(V1,V2)
#define NEXUS_MIN(V1,V2)		GLOBUS_MIN(V1,V2)

#define NEXUS_HANDLER_TYPE_THREADED	GLOBUS_NEXUS_HANDLER_TYPE_THREADED
#define NEXUS_HANDLER_TYPE_NON_THREADED	GLOBUS_NEXUS_HANDLER_TYPE_NON_THREADED

#define NEXUS_DIRECT_INFO_ACTION_INLINE GLOBUS_NEXUS_DIRECT_INFO_ACTION_INLINE
#define NEXUS_DIRECT_INFO_ACTION_POINTER GLOBUS_NEXUS_DIRECT_INFO_ACTION_POINTER
#define NEXUS_DIRECT_INFO_ACTION_CUSTOM GLOBUS_NEXUS_DIRECT_INFO_ACTION_CUSTOM

#define NEXUS_SUCCESS				GLOBUS_SUCCESS
#define NEXUS_ERROR_NONE			GLOBUS_NEXUS_ERROR_NONE
#define NEXUS_ERROR_UNKNOWN			GLOBUS_NEXUS_ERROR_UNKNOWN
#define NEXUS_ERROR_PROCESS_DIED		GLOBUS_NEXUS_ERROR_PROCESS_DIED
#define NEXUS_ERROR_PROCESS_SHUTDOWN_ABNORMALLY	GLOBUS_NEXUS_ERROR_PROCESS_SHUTDOWN_ABNORMALLY
#define NEXUS_ERROR_PROCESS_SHUTDOWN_NORMALLY	GLOBUS_NEXUS_ERROR_PROCESS_SHUTDOWN_NORMALLY
#define NEXUS_ERROR_ACCEPT_ATTACH_FAILED	GLOBUS_NEXUS_ERROR_ACCEPT_ATTACH_FAILED
#define NEXUS_ERROR_CONNECT_FAILED		GLOBUS_NEXUS_ERROR_CONNECT_FAILED
#define NEXUS_ERROR_BAD_PROTOCOL		GLOBUS_NEXUS_ERROR_BAD_PROTOCOL
#define NEXUS_ERROR_READ_FAILED			GLOBUS_NEXUS_ERROR_READ_FAILED
#define NEXUS_ERROR_BAD_URL			GLOBUS_NEXUS_ERROR_BAD_URL
#define NEXUS_ERROR_BUFFER_OVERFLOW		GLOBUS_NEXUS_ERROR_BUFFER_OVERFLOW
#define NEXUS_ERROR_INVALID_PARAMETER		GLOBUS_NEXUS_ERROR_INVALID_PARAMETER
#define NEXUS_ERROR_INVALID_RETURN		GLOBUS_NEXUS_ERROR_INVALID_RETURN
#define NEXUS_ERROR_ALREADY_INITIALIZED		GLOBUS_NEXUS_ERROR_ALREADY_INITIALIZED
#define NEXUS_ERROR_NOT_INITIALIZED		GLOBUS_NEXUS_ERROR_NOT_INITIALIZED
#define NEXUS_ERROR_ENDPOINT_DESTROYED		GLOBUS_NEXUS_ERROR_ENDPOINT_DESTROYED
#define NEXUS_ERROR_UNIMPLEMENTED		GLOBUS_NEXUS_ERROR_UNIMPLEMENTED
#define NEXUS_ERROR_VERSION_MISMATCH		GLOBUS_NEXUS_ERROR_VERSION_MISMATCH
#define NEXUS_ERROR_BUFFER_TOO_LONG		GLOBUS_NEXUS_ERROR_BUFFER_TOO_LONG
#define NEXUS_ERROR_NO_COMPATIBLE_PROTOCOLS	GLOBUS_NEXUS_ERROR_NO_COMPATIBLE_PROTOCOLS

#define nexus_mutex_init(M,A)	globus_mutex_init(M,A)
#define nexus_mutex_destroy(M)	globus_mutex_destroy(M)
#define nexus_mutex_lock(M)	globus_mutex_lock(M)
#define nexus_mutex_unlock(M)	globus_mutex_unlock(M)
#define nexus_mutex_trylock(M)	globus_mutex_trylock(M)
#define nexus_cond_init(C,A)	globus_cond_init(C,A)
#define nexus_cond_destroy(C)	globus_cond_destroy(C)
#define nexus_cond_wait(C,M)	globus_cond_wait(C,M)
#define nexus_cond_signal(C)	globus_cond_signal(C)
#define nexus_cond_broadcast(C)	globus_cond_broadcast(C)
#define nexus_thread_yield()	globus_thread_yield()
#define nexus_thread_key_create globus_thread_key_create
#define nexus_malloc(Size)	globus_malloc(Size)
#define nexus_free(Ptr)		globus_free(Ptr)
#define nexus_thread_setspecific globus_thread_setspecific
#define nexus_thread_getspecific globus_thread_getspecific

#define nexus_stdio_lock()	globus_nexus_stdio_lock()
#define nexus_stdio_unlock()	globus_nexus_stdio_unlock()

#define nexus_poll()                 globus_poll()
#define nexus_poll_blocking()        globus_poll_blocking()

#define nexus_startpoint_flush(S) \
    globus_nexus_startpoint_flush(S)

#endif /* GLOBUS_NEXUS_BACKWARD_COMPATIBLE */

/*********************************************************************
 * Forward compatibility...
 *********************************************************************/

#define globus_nexus_endpointattr_init(E) \
    nexus_endpointattr_init(E)
#define globus_nexus_endpointattr_destroy(E) \
    nexus_endpointattr_destroy(E)
#define globus_nexus_endpointattr_set_handler_table(E,H,T) \
    nexus_endpointattr_set_handler_table(E,H,T)
#define globus_nexus_endpointattr_get_handler_table(E,H,T) \
    nexus_endpointattr_get_handler_table(E,H,T)
#define globus_nexus_endpointattr_set_unknown_handler(E,F,T) \
    nexus_endpointattr_set_unknown_handler(E,F,T)
#define globus_nexus_endpointattr_get_unknown_handler(E,F,T) \
    nexus_endpointattr_get_unknown_handler(E,F,T)
#define globus_nexus_endpointattr_set_transform(E,T,I) \
    nexus_endpointattr_set_transform(E,T,I)
#define globus_nexus_endpointattr_get_transform(E,T,I) \
    nexus_endpointattr_get_transform(E,T,I)
#define globus_nexus_endpointattr_set_protocol(E,P,I,L) \
    nexus_endpointattr_set_protocol(E,P,I,L)
#define globus_nexus_endpointattr_get_protocol(E,P,I) \
    nexus_endpointattr_get_protocol(E,P,I)

#define globus_nexus_endpointstate_get_transform(E,P) \
    nexus_endpointstate_get_transform(E,P)
#define globus_nexus_startpointstate_get_transform(E,P) \
    nexus_startpointstate_get_transform(E,P)

#define globus_nexus_endpoint_init(E,A) \
    nexus_endpoint_init(E,A)
#define globus_nexus_endpoint_destroy(E) \
    nexus_endpoint_destroy(E)
#define globus_nexus_endpoint_string(E,S,L) \
    nexus_endpoint_string(E,S,L)

#define globus_nexus_startpoint_bind(S,E) \
    nexus_startpoint_bind(S,E)
#define globus_nexus_startpoint_copy(D,S) \
    nexus_startpoint_copy(D,S)
#define globus_nexus_startpoint_destroy(S) \
    nexus_startpoint_destroy(S)
#define globus_nexus_startpoint_destroy_and_notify(S) \
    nexus_startpoint_destroy_and_notify(S)
#define globus_nexus_startpoint_equal_context(S1,S2) \
    nexus_startpoint_equal_context(S1,S2)
#define globus_nexus_startpoint_equal(S1,S2) \
    nexus_startpoint_equal(S1,S2)
#define globus_nexus_startpoint_to_current_context(S) \
    nexus_startpoint_to_current_context(S)
#define globus_nexus_startpoint_get_endpoint(S,E) \
    nexus_startpoint_get_endpoint(S,E)
#define globus_nexus_startpoint_string(S,T,L) \
    nexus_startpoint_string(S,T,L)

#define globus_nexus_put_startpoint_transfer(B,S,C) \
    nexus_put_startpoint_transfer(B,S,C)
#define globus_nexus_user_put_startpoint_transfer(U,S,C) \
    nexus_user_put_startpoint_transfer(U,S,C)
#define globus_nexus_get_startpoint(B,S,C) \
    nexus_get_startpoint(B,S,C)
#define globus_nexus_user_get_startpoint(U,S,C,F) \
    nexus_user_get_startpoint(U,S,C,F)
#define globus_nexus_sizeof_startpoint(S,C) \
    nexus_sizeof_startpoint(S,C)
#define globus_nexus_buffer_init(B,S,N) \
    nexus_buffer_init(B,S,N)
#define globus_nexus_buffer_destroy(B) \
    nexus_buffer_destroy(B)
#define globus_nexus_check_buffer_size(B,N,I,DN,DI) \
    nexus_check_buffer_size(B,N,I,DN,DI)
#define globus_nexus_send_rsr(B,S,H,D,C) \
    nexus_send_rsr(B,S,H,D,C)
#define globus_nexus_buffer_save(B) \
    nexus_buffer_save(B)
#define globus_nexus_buffer_save_linearly(B) \
    nexus_buffer_save_linearly(B)

#define globus_nexus_enable_fault_tolerance(F,A) \
    nexus_enable_fault_tolerance(F,A)
#define globus_nexus_startpoint_test(S) \
    nexus_startpoint_test(S)

#define globus_nexus_fd_init() \
    nexus_fd_init()
#define globus_nexus_fd_shutdown() \
    nexus_fd_shutdown()
#define globus_nexus_fd_open(P,F,M,FD) \
    nexus_fd_open(P,F,M,FD)
#define globus_nexus_fd_setup_nonblocking(F) \
    nexus_fd_setup_nonblocking(F)
#define globus_nexus_fd_setup_blocking(F) \
    nexus_fd_setup_blocking(F)
#define globus_nexus_fd_setup_socket(F) \
    nexus_fd_setup_socket(F)
#define globus_nexus_fd_close(F) \
    nexus_fd_close(F)
#define globus_nexus_fd_register_for_select(F,R,W,E,A) \
    nexus_fd_register_for_select(F,R,W,E,A)
#define globus_nexus_fd_register_for_read(F,B,M,W,C,E,A) \
    nexus_fd_register_for_read(F,B,M,W,C,E,A)
#define globus_nexus_fd_register_for_write(F,B,N,C,E,A) \
    nexus_fd_register_for_write(F,B,N,C,E,A)
#define globus_nexus_fd_register_for_writev(F,IV,IC,C,E,A) \
    nexus_fd_register_for_writev(F,IV,IC,C,E,A)
#define globus_nexus_fd_write_one_nonblocking(F,C) \
    nexus_fd_write_one_nonblocking(F,C)
#define globus_nexus_fd_unregister(F,C) \
    nexus_fd_unregister(F,C)
#define globus_nexus_fd_handle_events(P,M) \
    nexus_fd_handle_events(P,M)
#define globus_nexus_fd_set_handler_thread(I) \
    nexus_fd_set_handler_thread(I)
#define globus_nexus_fd_create_listener(P,B,C,A) \
    nexus_fd_create_listener(P,B,C,A)
#define globus_nexus_fd_close_listener(P) \
    nexus_fd_close_listener(P)
#define globus_nexus_fd_connect(H,P,F) \
    nexus_fd_connect(H,P,F)
#define globus_nexus_fd_defer(A,R) \
    nexus_fd_defer(A,R)
#define globus_nexus_fd_defer_callback(F) \
    nexus_fd_defer_callback(F)

#define globus_nexus_allow_attach(P,H,F,A) \
    nexus_allow_attach(P,H,F,A)
#define globus_nexus_disallow_attach(P) \
    nexus_disallow_attach(P)
#define globus_nexus_attach(U,S) \
    nexus_attach(U,S)
#define globus_nexus_split_url(U,H,P,S) \
    nexus_split_url(U,H,P,S)
#define globus_nexus_split_url_free(H,S) \
    nexus_split_url_free(H,S)

#define globus_nexus_silent_fatal \
    globus_silent_fatal
#define globus_nexus_fatal \
    globus_fatal
#define globus_nexus_error \
    nexus_error
#define globus_nexus_warning \
    globus_warning
#define globus_nexus_notice \
    nexus_notice
#define globus_nexus_printf \
    globus_libc_printf
#define nexus_printf \
    globus_libc_printf
#define globus_nexus_perror \
    globus_perror
#define globus_nexus_fatal_perror \
    globus_fatal_perror
#define nexus_fatal \
    globus_fatal
#define nexus_silent_fatal \
    globus_silent_fatal
#define globus_nexus_usleep(U) \
    globus_libc_usleep(U)
#define globus_nexus_wallclock() \
    globus_libc_wallclock()
#define nexus_wallclock() \
    globus_libc_wallclock()
#define globus_nexus_pause() \
    nexus_pause()

#define globus_nexus_rdb_lookup(N,K) \
    nexus_rdb_lookup(N,K)
#define globus_nexus_rdb_free(V) \
    nexus_rdb_free(V)

#define globus_nexus_ids(C,T) \
    nexus_ids(C,T)

#define globus_nexus_endpoint_set_user_pointer(E,A) \
    nexus_endpoint_set_user_pointer(E,A)
#define globus_nexus_endpoint_get_user_pointer(E) \
    nexus_endpoint_get_user_pointer(E)
#define globus_nexus_startpoint_set_null(S) \
    nexus_startpoint_set_null(S)
#define globus_nexus_startpoint_is_null(S) \
    nexus_startpoint_is_null(S)
#define globus_nexus_user_format() \
    nexus_user_format()

#define globus_nexus_sizeof_float(C) \
    nexus_sizeof_float(C)
#define globus_nexus_sizeof_double(C) \
    nexus_sizeof_double(C)
#define globus_nexus_sizeof_short(C) \
    nexus_sizeof_short(C)
#define globus_nexus_sizeof_u_short(C) \
    nexus_sizeof_u_short(C)
#define globus_nexus_sizeof_int(C) \
    nexus_sizeof_int(C)
#define globus_nexus_sizeof_u_int(C) \
    nexus_sizeof_u_int(C)
#define globus_nexus_sizeof_long(C) \
    nexus_sizeof_long(C)
#define globus_nexus_sizeof_u_long(C) \
    nexus_sizeof_u_long(C)
#define globus_nexus_sizeof_char(C) \
    nexus_sizeof_char(C)
#define globus_nexus_sizeof_u_char(C) \
    nexus_sizeof_u_char(C)
#define globus_nexus_sizeof_byte(C) \
    nexus_sizeof_byte(C)

#define globus_nexus_put_float(B,D,C) \
    nexus_put_float(B,D,C)
#define globus_nexus_put_double(B,D,C) \
    nexus_put_double(B,D,C)
#define globus_nexus_put_short(B,D,C) \
    nexus_put_short(B,D,C)
#define globus_nexus_put_u_short(B,D,C) \
    nexus_put_u_short(B,D,C)
#define globus_nexus_put_int(B,D,C) \
    nexus_put_int(B,D,C)
#define globus_nexus_put_u_int(B,D,C) \
    nexus_put_u_int(B,D,C)
#define globus_nexus_put_long(B,D,C) \
    nexus_put_long(B,D,C)
#define globus_nexus_put_u_long(B,D,C) \
    nexus_put_u_long(B,D,C)
#define globus_nexus_put_char(B,D,C) \
    nexus_put_char(B,D,C)
#define globus_nexus_put_u_char(B,D,C) \
    nexus_put_u_char(B,D,C)
#define globus_nexus_put_byte(B,D,C) \
    nexus_put_byte(B,D,C)

#define globus_nexus_get_float(B,D,C) \
    nexus_get_float(B,D,C)
#define globus_nexus_get_double(B,D,C) \
    nexus_get_double(B,D,C)
#define globus_nexus_get_short(B,D,C) \
    nexus_get_short(B,D,C)
#define globus_nexus_get_u_short(B,D,C) \
    nexus_get_u_short(B,D,C)
#define globus_nexus_get_int(B,D,C) \
    nexus_get_int(B,D,C)
#define globus_nexus_get_u_int(B,D,C) \
    nexus_get_u_int(B,D,C)
#define globus_nexus_get_long(B,D,C) \
    nexus_get_long(B,D,C)
#define globus_nexus_get_u_long(B,D,C) \
    nexus_get_u_long(B,D,C)
#define globus_nexus_get_char(B,D,C) \
    nexus_get_char(B,D,C)
#define globus_nexus_get_u_char(B,D,C) \
    nexus_get_u_char(B,D,C)
#define globus_nexus_get_byte(B,D,C) \
    nexus_get_byte(B,D,C)

#define globus_nexus_user_put_float(U,D,C) \
    nexus_user_put_float(U,D,C)
#define globus_nexus_user_put_double(U,D,C) \
    nexus_user_put_double(U,D,C)
#define globus_nexus_user_put_short(U,D,C) \
    nexus_user_put_short(U,D,C)
#define globus_nexus_user_put_u_short(U,D,C) \
    nexus_user_put_u_short(U,D,C)
#define globus_nexus_user_put_int(U,D,C) \
    nexus_user_put_int(U,D,C)
#define globus_nexus_user_put_u_int(U,D,C) \
    nexus_user_put_u_int(U,D,C)
#define globus_nexus_user_put_long(U,D,C) \
    nexus_user_put_long(U,D,C)
#define globus_nexus_user_put_u_long(U,D,C) \
    nexus_user_put_u_long(U,D,C)
#define globus_nexus_user_put_char(U,D,C) \
    nexus_user_put_char(U,D,C)
#define globus_nexus_user_put_u_char(U,D,C) \
    nexus_user_put_u_char(U,D,C)
#define globus_nexus_user_put_byte(U,D,C) \
    nexus_user_put_byte(U,D,C)

#define globus_nexus_user_get_float(U,D,C,F) \
    nexus_user_get_float(U,D,C,F)
#define globus_nexus_user_get_double(U,D,C,F) \
    nexus_user_get_double(U,D,C,F)
#define globus_nexus_user_get_short(U,D,C,F) \
    nexus_user_get_short(U,D,C,F)
#define globus_nexus_user_get_u_short(U,D,C,F) \
    nexus_user_get_u_short(U,D,C,F)
#define globus_nexus_user_get_int(U,D,C,F) \
    nexus_user_get_int(U,D,C,F)
#define globus_nexus_user_get_u_int(U,D,C,F) \
    nexus_user_get_u_int(U,D,C,F)
#define globus_nexus_user_get_long(U,D,C,F) \
    nexus_user_get_long(U,D,C,F)
#define globus_nexus_user_get_u_long(U,D,C,F) \
    nexus_user_get_u_long(U,D,C,F)
#define globus_nexus_user_get_char(U,D,C,F) \
    nexus_user_get_char(U,D,C,F)
#define globus_nexus_user_get_u_char(U,D,C,F) \
    nexus_user_get_u_char(U,D,C,F)
#define globus_nexus_user_get_byte(U,D,C,F) \
    nexus_user_get_byte(U,D,C,F)

#define GLOBUS_NEXUS_PROTO_TYPE_LOCAL NEXUS_PROTO_TYPE_LOCAL
#define GLOBUS_NEXUS_PROTO_TYPE_TCP NEXUS_PROTO_TYPE_TCP
#define GLOBUS_NEXUS_PROTO_TYPE_SHMEM  NEXUS_PROTO_TYPE_SHMEM
#define GLOBUS_NEXUS_PROTO_TYPE_INX  NEXUS_PROTO_TYPE_INX
#define GLOBUS_NEXUS_PROTO_TYPE_PVM  NEXUS_PROTO_TYPE_PVM
#define GLOBUS_NEXUS_PROTO_TYPE_EUI  NEXUS_PROTO_TYPE_EUI
#define GLOBUS_NEXUS_PROTO_TYPE_ATM  NEXUS_PROTO_TYPE_ATM
#define GLOBUS_NEXUS_PROTO_TYPE_MPL  NEXUS_PROTO_TYPE_MPL
#define GLOBUS_NEXUS_PROTO_TYPE_MPINX  NEXUS_PROTO_TYPE_MPINX
#define GLOBUS_NEXUS_PROTO_TYPE_UDP  NEXUS_PROTO_TYPE_UDP
#define GLOBUS_NEXUS_PROTO_TYPE_MN_UDP  NEXUS_PROTO_TYPE_MN_UDP
#define GLOBUS_NEXUS_PROTO_TYPE_MPI  NEXUS_PROTO_TYPE_MPI
#define GLOBUS_NEXUS_PROTO_TYPE_TOTEM  NEXUS_PROTO_TYPE_TOTEM
/*
#define GLOBUS_NEXUS_PROTO_TYPE_XTP  NEXUS_PROTO_TYPE_XTP
*/
#define GLOBUS_NEXUS_PROTO_TYPE_MAXVAL  NEXUS_PROTO_TYPE_MAXVAL
#define GLOBUS_NEXUS_PROTO_TYPE_ALL  NEXUS_PROTO_TYPE_ALL
#define GLOBUS_NEXUS_PROTO_TYPE_INTERNAL1  NEXUS_PROTO_TYPE_INTERNAL1
#define GLOBUS_NEXUS_PROTO_TYPE_INTERNAL2  NEXUS_PROTO_TYPE_INTERNAL2


/*
 * At this point, we have defined all of the macros that can effect
 * the size of structures in nexus.h
 */
#include "nx_ver.h"
#endif /* _NEXUS_INCLUDE_NEXUS_H */
