// Sample code file: CLNT.H

// Warning: This code has been marked up for HTML
/*
//赏屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯突
//� (c) 1995 Novell, Inc.  All rights reserved.                              �
//�                                                                          �
//� THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND        �
//� TREATIES.                                                                �
//�                                                                          �
//� NO PART OF THIS WORK MAY BE USED, PRACTICED, PERFORMED, COPIED,          �
//� DISTRIBUTED, REVISED, MODIFIED, TRANSLATED, ABRIDGED, CONDENSED,         �
//� EXPANDED, COLLECTED, COMPILED, LINKED, RECAST, TRANSFORMED OR ADAPTED    �
//� WITHOUT THE PRIOR WRITTEN CONSENT OF NOVELL, INC.                        �
//�                                                                          �
//� ANY USE OR EXPLOITATION OF THIS WORK WITHOUT AUTHORIZATION COULD SUBJECT �
//� THE PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY.                         �
//掏屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯凸
//� Source module name: CLNT.H                                               �
//韧屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯图
*/
/* Inclusion Control */
#if !defined( _RPC_CLNT_H )
   #define _RPC_CLNT_H

#include <rpc/ndpsrpc.h>

#include <nwdsattr.h>

#if defined(NWDOS) || defined(N_PLAT_DOS)

#ifndef _RPC_TYPES_H
#include <rpc/types.h>
#endif

#ifndef _TIUSER_H
#include <rpc/mytiuser.h>        /* struct netbuf     */
#endif

#ifndef __NETCONFIG__
#include <rpc/nconfig.h>      /* struct netconfig  */
#endif

#ifndef _RPC_XDR_H
#include <rpc/xdr.h>
#endif

#ifndef _RPC_AUTH_H
#include <rpc/auth.h>
#endif

/*
 * rpc calls return an enum clnt_stat.  This should be looked at more,
 * since each implementation is required to live with this (implementation
 * independent) list of errors.
 */
enum clnt_stat {
   RPC_SUCCESS=0,             /* call succeeded                      */
   /*
    * local errors
    */
   RPC_CANTENCODEARGS=1,      /* can't encode arguments              */
   RPC_CANTDECODERES=2,       /* can't decode results                */
   RPC_CANTSEND=3,            /* failure in sending call             */
   RPC_CANTRECV=4,            /* failure in receiving result         */
   RPC_TIMEDOUT=5,            /* call timed out                      */
   RPC_INTR=18,               /* call interrupted                    */
   RPC_UDERROR=23,            /* recv got uderr indication           */
   /*
    * remote errors
    */
   RPC_VERSMISMATCH=6,        /* rpc versions not compatible         */
   RPC_AUTHERROR=7,           /* authentication error                */
   RPC_PROGUNAVAIL=8,         /* program not available               */
   RPC_PROGVERSMISMATCH=9,    /* program version mismatched          */
   RPC_PROCUNAVAIL=10,        /* procedure unavailable               */
   RPC_CANTDECODEARGS=11,     /* decode arguments error              */
   RPC_SYSTEMERROR=12,        /* generic "other problem"             */

   /*
    * rpc_call & clnt_create errors
    */
   RPC_UNKNOWNHOST=13,        /* unknown host name                   */
   RPC_UNKNOWNPROTO=17,       /* unknown protocol                    */
   RPC_UNKNOWNADDR=19,        /* Remote address unknown              */
   RPC_NOBROADCAST=21,        /* Broadcasting not supported          */

   /*
    * rpcbind errors
    */
   RPC_RPCBFAILURE=14,        /* the pmapper failed in its call      */
   #define RPC_PMAPFAILURE RPC_RPCBFAILURE
   RPC_PROGNOTREGISTERED=15,  /* remote program is not registered    */
   RPC_N2AXLATEFAILURE=22,    /* Name to address translation failed  */
   /*
    * Misc error in the TLI library
    */
   RPC_PROTOCOL_ERROR = 20,         /* this is either TLI or WINSOCK */
   /*
    * unspecified error
    */
   RPC_FAILED=16,
   RPC_CANCELED=25            /* NetWare */
};
#define RPC_TLIERROR RPC_PROTOCOL_ERROR

/*
 * Error info.
 */
struct rpc_err {
   enum clnt_stat re_status;
   union {
      struct {
         int sys_errno;       /* related system error                */
         int tli_errno;       /* related tli error number            */
      } RE_err;
      enum auth_stat RE_why;  /* why the auth error occurred         */
      struct {
         u_long low;          /* lowest verion supported             */
         u_long high;         /* highest verion supported            */
      } RE_vers;
      struct {                /* maybe meaningful if RPC_FAILED      */
         long s1;
         long s2;
      } RE_lb;                /* life boot & debugging only          */
   } ru;
#define  re_errno    ru.RE_err.sys_errno
#define  re_terrno   ru.RE_err.tli_errno
#define  re_why      ru.RE_why
#define  re_vers     ru.RE_vers
#define  re_lb       ru.RE_lb
};


/*
 * Client rpc handle. Created by individual implementations
 * Client is responsible for initializing auth.
 */
typedef struct client {
   AUTH far *cl_auth;         /* authenticator handle */
   struct clnt_ops {
      enum clnt_stat (far *cl_call)(struct client far *, u_long, 
                                    xdrproc_t, caddr_t, 
                                    xdrproc_t, caddr_t, struct timeval); 
      void     (far *cl_abort)(struct client far *);
      void     (far *cl_geterr)(struct client far *, struct rpc_err far *);
      bool_t   (far *cl_freeres)(struct client far *, xdrproc_t, caddr_t);
      void     (far *cl_destroy)(struct client far *);
      bool_t   (far *cl_control)(struct client far *, int, char far *);     
   }   far  *cl_ops;          /* operations defined on CLIENT handle */
   caddr_t   cl_private;      /* private stuff                       */
   char far *cl_netid;        /* network token                       */
   char far *cl_tp;           /* device name                         */
} CLIENT;

/*
 * Operations defined on CLIENT handle
 * client side rpc interface operations
 */
#define  CLNT_CALL(rh, proc, xargs, argsp, xres, resp, secs)   \
   ((*(rh)->cl_ops->cl_call)((CLIENT far *)rh, proc,           \
      (xdrproc_t)xargs, (caddr_t)argsp, (xdrproc_t)xres, (caddr_t)resp, secs))
#define  clnt_call(rh, proc, xargs, argsp, xres, resp, secs)   \
   ((*(rh)->cl_ops->cl_call)((CLIENT far *)rh, proc,           \
      (xdrproc_t)xargs, (caddr_t)argsp, (xdrproc_t)xres, (caddr_t)resp, secs))

#define CLNT_ABORT(rh) ((*(rh)->cl_ops->cl_abort)((CLIENT far *)rh))
#define clnt_abort(rh) ((*(rh)->cl_ops->cl_abort)((CLIENT far *)rh))

#define CLNT_GETERR(rh,errp) \
   ((*(rh)->cl_ops->cl_geterr)((CLIENT far *)rh,(struct rpc_err far *)errp))
#define clnt_geterr(rh,errp) \
   ((*(rh)->cl_ops->cl_geterr)((CLIENT far *)rh,(struct rpc_err far *)errp))

#define CLNT_FREERES(rh,xres,resp) \
   ((*(rh)->cl_ops->cl_freeres)((CLIENT far *)rh,(xdrproc_t)xres,(caddr_t)resp))
#define clnt_freeres(rh,xres,resp) \
   ((*(rh)->cl_ops->cl_freeres)((CLIENT far *)rh,(xdrproc_t)xres,(caddr_t)resp))

#define CLNT_DESTROY(rh) ((*(rh)->cl_ops->cl_destroy)((CLIENT far *)rh))
#define clnt_destroy(rh) ((*(rh)->cl_ops->cl_destroy)((CLIENT far *)rh))

#define CLNT_CONTROL(cl,rq,in) \
   ((*(cl)->cl_ops->cl_control)((CLIENT far *)cl,rq,(char far *)in))
#define clnt_control(cl,rq,in) \
   ((*(cl)->cl_ops->cl_control)((CLIENT far *)cl,rq,(char far *)in))


/*
 * Timers used for the pseudo-transport protocol when using datagrams
 */
struct rpc_timers {
   u_short rt_srtt;           /* smoothed round-trip time            */
   u_short rt_deviate;        /* estimated deviation                 */
   u_long  rt_rtxcur;         /* current (backed-off) rto            */
};

/*
 * Feedback values used for possible congestion and rate control
 */
#define FEEDBACK_REXMIT1  1   /* first retransmit                    */
#define FEEDBACK_OK       2   /* no retransmits                      */

#define RPCSMALLMSGSIZE   400 /* a more reasonable packet size       */
#define KNC_STRSIZE       128 /* max length of knetconfig strings    */

struct knetconfig {
   u_long    knc_semantics;    /* token name                          */
   char far *knc_protofmly;    /* protocol family                     */
   char far *knc_proto;        /* protocol                            */
   short     knc_rdev;         /* device id                           */
   u_long    knc_unused[8];
};


/*
 * control operations that apply to all transports
 */
#define CLSET_TIMEOUT     1   /* set timeout (timeval)               */
#define CLGET_TIMEOUT     2   /* get timeout (timeval)               */
#define CLGET_SERVER_ADDR 3   /* get server's address (sockaddr)     */
#define CLGET_FD          6   /* get connections file descriptor     */
#define CLGET_SVC_ADDR    7   /* get server's address (netbuf)       */
#define CLSET_FD_CLOSE    8   /* close fd while clnt_destroy         */
#define CLSET_FD_NCLOSE   9   /* Do not close fd while clnt_destroy  */
/*
 * Connectionless only control operations
 */
#define CLSET_RETRY_TIMEOUT 4 /* set retry timeout (timeval)         */
#define CLGET_RETRY_TIMEOUT 5 /* get retry timeout (timeval)         */

/*
 * RPCTEST is a test program which is accessable on every rpc
 * transport/port.  It is used for testing, performance evaluation,
 * and network administration.
 */
#define RPCTEST_PROGRAM            ((u_long)1)
#define RPCTEST_VERSION            ((u_long)1)
#define RPCTEST_NULL_PROC          ((u_long)2)
#define RPCTEST_NULL_BATCH_PROC    ((u_long)3)

/*
 * By convention, procedure 0 takes null arguments and returns them
 */
#define  NULLPROC ((u_long)0)

/*
 * If a CLIENT creation fails, the following allows the user to 
 * figure out why.
 */
struct rpc_createerr {
   enum clnt_stat cf_stat;
   struct rpc_err cf_error;   /* useful when cf_stat==RPC_PMAPFAILURE */
};

extern struct rpc_createerr rpc_createerr;
#define tirpc_createerr rpc_createerr   /* compatibility with NetWare */

/*
 * Below are the client handle creation routines for the various
 * implementations of client side rpc.  They can return NULL if a
 * creation failure occurs.
 */
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Generic client creation routine. Supported protocols are which belong
 * to the nettype name space
 */
CLIENT far * 
clnt_create( char far *host, 
             u_long prog, 
             u_long vers, 
             char far *nettype ); 

/*
 * Generic client creation routine. It takes a netconfig structure
 * instead of nettype
 */
CLIENT far * 
clnt_tp_create( char far *host, 
                u_long prog,
                u_long vers, 
                struct netconfig far *nconf ); 

/*
 * Generic client creation routine. It takes a netconfig structure
 * instead of nettype
 */
CLIENT far * 
clnt_ndps_create( Net_Address_T far *addr, 
                u_long prog,
                u_long vers);

/*
 * Generic TLI create routine
 */
CLIENT far *  
clnt_tli_create( int fd, 
                 struct netconfig far *nconf,
                 struct netbuf far *svcaddr, /* servers address   */
                 u_long prog,                /* program number    */
                 u_long vers,                /* version number    */
                 u_int  sendsize,            /* buffer recv size  */
                 u_int  recvsize );          /* buffer send size  */
/*
 * Low level clnt create routine for connectionful transports, e.g. tcp, spx.
 */
CLIENT far * 
clnt_vc_create( int fd,                 /* fd must be opened */
                 struct netbuf far *svcaddr, /* servers address   */
                 u_long prog,            /* program number    */
                 u_long vers,            /* version number    */
                 u_int  sendsize,        /* buffer recv size  */
                 u_int  recvsize );      /* buffer send size  */
 
/*
 * Low level clnt create routine for connectionless transports, e.g. udp.
 */
CLIENT far *  
clnt_dg_create( int fd,                 /* fd must be opened */
                struct netbuf far *svcaddr, /* servers address   */
                u_long prog,            /* program number    */
                u_long vers,            /* version number    */
                u_int  sendsz,          /* buffer recv size  */
                u_int  recvsz );        /* buffer send size  */

/*
 * Memory based rpc (for speed check and testing)
 */
CLIENT far * 
clnt_raw_create( u_long prog,           /* program number    */
                 u_long vers );         /* version number    */

void        clnt_pcreateerror(char far *message);  /* why creation failed */        
char far *  clnt_spcreateerror(char far *message);  

void        clnt_perrno(enum clnt_stat num);
char far *  clnt_sperrno(enum clnt_stat num);

/*
 * Prints error message for given CLIENT handle
 */
void        clnt_perror(CLIENT far *clnt, char far *message);
char far *  clnt_sperror(CLIENT far *clnt, char far *message);

/*
 * The simplified interface:
 */
enum clnt_stat  
rpc_call( char far *host,           /* host name                     */
          u_long  prognum,          /* program number                */
          u_long  versnum,          /* version number                */
          u_long  procnum,          /* procedure number              */
          xdrproc_t inproc,         /* xdr routine for args          */
          caddr_t in,               /* pointer to results            */
          xdrproc_t outproc,        /* xdr routine for results       */
          caddr_t out,              /* pointer to args               */
          char far *nettype );      /* transport type                */


#ifdef  __cplusplus
}
#endif

#endif /* NWDOS */



#if defined(NWWIN) || defined(N_PLAT_MSW) /* Both WIN31 and WIN95 */
#include <rpc/types.h>

#include <rpc/mytiuser.h>        /* struct netbuf     */
#include <rpc/nconfig.h>      /* struct netconfig  */

#include <rpc/xdr.h>
#include <rpc/auth.h>

#if !defined(N_PLAT_MSW4)
   typedef void FAR *PVOID;
   #define IN
   typedef void FAR *LPOVERLAPPED;
#endif
#include <winsock.h>

#ifndef _SYS_TIME_H_INCLUDED
#include <rpc/time.h>           /* james */
#endif

/* FIX THIS - The following constant is defined here until it is added to the 
   enum for the addressType field of the Net_Address_T structure.  The enum
   exists in nwdsdefs.h, while the Net_Address_T structure is in nwdsattr.h.
*/
#define NT_IP6 7 // Anticipating NET_ADDRESS_TYPE name for IP V6 (HLB, 10/3/97)


/*
 * rpc calls return an enum clnt_stat.  This should be looked at more,
 * since each implementation is required to live with this (implementation
 * independent) list of errors.
 */
enum clnt_stat {
    RPC_SUCCESS = 0,      /* call succeeded */

    /*
     * local errors
     */
    RPC_CANTENCODEARGS = 1,   /* can't encode arguments */
    RPC_CANTDECODERES = 2,   /* can't decode results */
    RPC_CANTSEND = 3,      /* failure in sending call */
    RPC_CANTRECV = 4,      /* failure in receiving result */
    RPC_TIMEDOUT = 5,      /* call timed out */
    RPC_INTR = 18,      /* call interrupted */
    RPC_UDERROR = 23,      /* recv got uderr indication */

    /*
     * remote errors
     */
    RPC_VERSMISMATCH = 6,   /* rpc versions not compatible */
    RPC_AUTHERROR = 7,      /* authentication error */
    RPC_PROGUNAVAIL = 8,   /* program not available */
    RPC_PROGVERSMISMATCH = 9,   /* program version mismatched */
    RPC_PROCUNAVAIL = 10,   /* procedure unavailable */
    RPC_CANTDECODEARGS = 11,   /* decode arguments error */
    RPC_SYSTEMERROR = 12,   /* generic "other problem" */

    /*
     * rpc_call & clnt_create errors
     */
    RPC_UNKNOWNHOST = 13,   /* unknown host name */
    RPC_UNKNOWNPROTO = 17,   /* unknown protocol */
    RPC_UNKNOWNADDR = 19,   /* Remote address unknown */
    RPC_NOBROADCAST = 21,   /* Broadcasting not supported */

    /*
     * rpcbind errors
     */
    RPC_RPCBFAILURE = 14,   /* the pmapper failed in its call */
#define RPC_PMAPFAILURE RPC_RPCBFAILURE
    RPC_PROGNOTREGISTERED = 15,   /* remote program is not registered */
    RPC_N2AXLATEFAILURE = 22,   /* Name to address translation failed */

    /*
     * Misc error in the WinSock library
     */
    RPC_PROTOCOL_ERROR = 20,         /* this is either TLI or WINSOCK */

    /*
     * unspecified error
     */
    RPC_FAILED = 16
};


/*
 * Error info.
 */
struct rpc_err {
    enum clnt_stat  re_status;
    union {
   struct {
       int             sys_errno;   /* related system error */
       int             ws_errno;   /* related winsock error number */
   }               RE_err;
   enum auth_stat  RE_why;   /* why the auth error occurred */
   struct {
       unsigned long   low;/* lowest verion supported */
       unsigned long   high;   /* highest verion supported */
   }               RE_vers;
   struct {      /* maybe meaningful if RPC_FAILED */
       long            s1;
       long            s2;
   }               RE_lb;   /* life boot & debugging only */
    }               ru;
#define   re_errno   ru.RE_err.sys_errno
#define   re_terrno   ru.RE_err.ws_errno
#define   re_why      ru.RE_why
#define   re_vers      ru.RE_vers
#define   re_lb      ru.RE_lb
};


/*
 * Client rpc handle.
 * Created by individual implementations
 * Client is responsible for initializing auth, see e.g. auth_none.c.
 */
typedef struct client_tag CLIENT;
struct client_tag {
    AUTH FAR       *cl_auth;   /* authenticator */
    struct clnt_ops {
   enum clnt_stat  (N_API *cl_call) (CLIENT FAR *, u_long, xdrproc_t, caddr_t, xdrproc_t, caddr_t, struct timeval);   /* call remote procedure */
   void            (N_API *cl_abort) (CLIENT FAR *);                           /* abort a call */
   void            (N_API *cl_geterr) (CLIENT FAR *, struct rpc_err FAR *);                  /* get specific error code */
   bool_t          (N_API *cl_freeres) (CLIENT FAR *, xdrproc_t, caddr_t);                  /* frees results */
   void            (N_API *cl_destroy) (CLIENT FAR *);                        /* destroy this structure */
   bool_t          (N_API *cl_control) (CLIENT FAR *, u_int, char FAR *);                  /* the ioctl() of rpc */
    } FAR          *cl_ops;
    caddr_t         cl_private;   /* private stuff */
    char FAR       *cl_netid;   /* network token */
//HLB    char FAR       *cl_tp;   /* device name */
};


/*
 * Timers used for the pseudo-transport protocol when using datagrams
 */
struct rpc_timers {
    unsigned short  rt_srtt;   /* smoothed round-trip time */
    unsigned short  rt_deviate;   /* estimated deviation */
    unsigned long   rt_rtxcur;   /* current (backed-off) rto */
};

/*
 * Feedback values used for possible congestion and rate control
 */
#define   FEEDBACK_REXMIT1   1   /* first retransmit */
#define   FEEDBACK_OK      2   /* no retransmits */

#define   RPCSMALLMSGSIZE   400      /* a more reasonable packet size */

#define   KNC_STRSIZE   128      /* max length of knetconfig strings */
struct knetconfig {
    unsigned long   knc_semantics;   /* token name */
    char FAR       *knc_protofmly;   /* protocol family */
    char FAR       *knc_proto;      /* protocol */
    short           knc_rdev;      /* device id */
    unsigned long   knc_unused[8];
};

/*
 * client side rpc interface ops
 */

/*
 * enum clnt_stat
 * CLNT_CALL(rh, proc, xargs, argsp, xres, resp, timeout)
 *    CLIENT *rh;
 *   u_long proc;
 *   xdrproc_t xargs;
 *   caddr_t argsp;
 *   xdrproc_t xres;
 *   caddr_t resp;
 *   struct timeval timeout;
 */
#define   CLNT_CALL(rh, proc, xargs, argsp, xres, resp, secs)   \
   ((*(rh)->cl_ops->cl_call)((CLIENT FAR *)rh, proc, (xdrproc_t)xargs, \
      (caddr_t)argsp, (xdrproc_t)xres, (caddr_t)resp, secs))
#define   clnt_call(rh, proc, xargs, argsp, xres, resp, secs)   \
   ((*(rh)->cl_ops->cl_call)((CLIENT FAR *)rh, proc, (xdrproc_t)xargs, \
      (caddr_t)argsp, (xdrproc_t)xres, (caddr_t)resp, secs))

/*
 * void
 * CLNT_ABORT(rh);
 *    CLIENT *rh;
 */
#define   CLNT_ABORT(rh)   ((*(rh)->cl_ops->cl_abort)((CLIENT FAR *)rh))
#define   clnt_abort(rh)   ((*(rh)->cl_ops->cl_abort)((CLIENT FAR *)rh))

/*
 * void
 * CLNT_GETERR(rh,errp);
 *    CLIENT *rh;
 *    struct rpc_err *errp;
 */
#define   CLNT_GETERR(rh, errp)   ((*(rh)->cl_ops->cl_geterr)((CLIENT FAR *)rh, \
                                  (struct rpc_err FAR *)errp))
#define   clnt_geterr(rh, errp)   ((*(rh)->cl_ops->cl_geterr)((CLIENT FAR *)rh, \
                                    (struct rpc_err FAR *)errp))

/*
 * bool_t
 * CLNT_FREERES(rh, xres, resp);
 *    CLIENT *rh;
 *   xdrproc_t xres;
 *   caddr_t resp;
 */
#define   CLNT_FREERES(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)((CLIENT FAR *)rh, \
                                    (xdrproc_t)xres,(caddr_t)resp))
#define   clnt_freeres(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)((CLIENT FAR *)rh, \
                                    (xdrproc_t)xres,(caddr_t)resp))

/*
 * bool_t
 * CLNT_CONTROL(cl, request, info)
 *   CLIENT *cl;
 *   u_int request;
 *   char *info;
 */
#define   CLNT_CONTROL(cl, rq, in) ((*(cl)->cl_ops->cl_control)((CLIENT FAR *)cl, \
                                  rq, (char FAR *)in))
#define   clnt_control(cl, rq, in) ((*(cl)->cl_ops->cl_control)((CLIENT FAR *)cl, \
                                  rq, (char FAR *)in))


/*
 * control operations that apply to all transports
 */
#define   CLSET_TIMEOUT      1   /* set timeout (timeval) */
#define   CLGET_TIMEOUT      2   /* get timeout (timeval) */
#define   CLGET_SERVER_ADDR   3   /* get server's address (sockaddr) */
#define   CLGET_FD      6   /* get connections file descriptor */
#define   CLGET_SVC_ADDR      7   /* get server's address (netbuf) */
#define   CLSET_FD_CLOSE      8   /* close socket with clnt_destroy */
#define   CLSET_FD_NCLOSE      9   /* Do not close socket with clnt_destroy */
/*
 * Connectionless only control operations
 */
#define   CLSET_RETRY_TIMEOUT 4   /* set retry timeout (timeval) */
#define   CLGET_RETRY_TIMEOUT 5   /* get retry timeout (timeval) */

/*
 * void
 * CLNT_DESTROY(rh);
 *    CLIENT *rh;
 */
#define   CLNT_DESTROY(rh)   ((*(rh)->cl_ops->cl_destroy)((CLIENT FAR *)rh))
#define   clnt_destroy(rh)   ((*(rh)->cl_ops->cl_destroy)((CLIENT FAR *)rh))


/*
 * RPCTEST is a test program which is accessable on every rpc
 * transport/port.  It is used for testing, performance evaluation,
 * and network administration.
 */

#define   RPCTEST_PROGRAM      ((unsigned long)1)
#define   RPCTEST_VERSION      ((unsigned long)1)
#define   RPCTEST_NULL_PROC   ((unsigned long)2)
#define   RPCTEST_NULL_BATCH_PROC   ((unsigned long)3)

/*
 * By convention, procedure 0 takes null arguments and returns them
 */

#define   NULLPROC ((unsigned long)0)

/*
 * Below are the client handle creation routines for the various
 * implementations of client side rpc.  They can return NULL if a
 * creation failure occurs.
 */

/*
 * Generic client creation routine. Supported protocols are which belong
 * to the nettype name space
 */
extern CLIENT FAR * N_API 
clnt_create(char FAR *, unsigned long, unsigned long, char FAR *);
/*
   char *hostname;         -- hostname
   u_long prog;         -- program number
   u_long vers;         -- version number
   char *nettype;         -- network type
*/

/*
 * Generic client creation routine. It takes a netconfig structure
 * instead of nettype
 */
//TWT 10-24-97 extern CLIENT FAR * N_API
//TWT 10-24-97 clnt_tp_create(char FAR *, unsigned long, unsigned long, struct netconfig FAR *);
/*
   char *hostname;         -- hostname
   u_long prog;         -- program number
   u_long vers;         -- version number
   struct netconfig *netconf;    -- network config structure
*/

/*
 * Generic client creation routine. It takes a network address and a
 * netconfig structure instead of a hostname and nettype
 */
extern CLIENT FAR * N_API
clnt_ndps_create(
   Net_Address_T  *addr,               /* I: Service provider's net address */
   unsigned long  prog,               /* I: program number */
   unsigned long  vers);               /* I: version number */
//TWT 10-24-97 register struct netconfig *nconf); /* I: net config struct */


/*
 * Low level clnt create routine for connectionful transports, e.g. tcp, spx.
 */

extern CLIENT FAR * N_API
clnt_wsvc_create(
   SOCKET wsocket,         // open socket
   Net_Address_T *addr,      // servers address
   u_long prog,         // program number
   u_long vers,         // version number
   u_int sendsz,         // buffer recv size
   u_int recvsz);         // buffer send size

/*
 * Memory based rpc (for speed check and testing)
 * CLIENT *
 * clnt_raw_create(prog, vers)
 *   u_long prog;         -- program number
 *   u_long vers;         -- version number
 */
extern CLIENT FAR * N_API clnt_raw_create(u_long, u_long);


/*
 * Print why creation failed
 */
void N_API clnt_pcreateerror(char FAR *);   /* stderr */
/*
        char *msg;
*/

char FAR * N_API clnt_spcreateerror(char FAR *);   /* string */
/*
        char *msg;
*/

/*
 * Like clnt_perror(), but is more verbose in its output
 */
void N_API clnt_perrno(enum clnt_stat);   /* stderr */
/*
        enum clnt_stat num;
*/

/*
 * Copy error message to buffer.
 */
char FAR * N_API clnt_sperrno(enum clnt_stat);   /* string */
/*
        enum clnt_stat num;
*/

/*
 * Print an error message, given the client error code
 */
void N_API clnt_perror(CLIENT FAR *, char FAR *);   /* stderr */
/*
        CLIENT *clnt;
        char *msg;
*/

char FAR * N_API clnt_sperror(CLIENT FAR *, char FAR *);   /* string */
/*
        CLIENT *clnt;
        char *msg
*/

/*
 * If a creation fails, the following allows the user to figure out why.
 */
struct rpc_createerr {
    enum clnt_stat  cf_stat;
    struct rpc_err  cf_error;   /* useful when cf_stat == RPC_PMAPFAILURE */
};

/*
 * Application must free resources allocaed by get_rpc_createerr() with
 * free_rpc_createerr().
 */
LPSTR N_API get_rpc_createerr(void);
int N_API free_rpc_createerr(LPSTR);


/*
 * The simplified interface:
 * enum clnt_stat
 * rpc_call(host, prognum, versnum, procnum, inproc, in, outproc, out, nettype)
 *   char *host;
 *   u_long prognum, versnum, procnum;
 *   xdrproc_t inproc, outproc;
 *   char *in, *out;
 *   char *nettype;
 */
extern enum clnt_stat N_API
rpc_call(char FAR *, unsigned long, unsigned long, unsigned long, \
    xdrproc_t, char FAR *, xdrproc_t, char FAR *, char FAR *);

/*
 * RPC broadcast interface
 * extern enum clnt_stat
 * rpc_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp,
 *         eachresult, nettype)
 *   u_long      prog;      -- program number
 *   u_long      vers;      -- version number
 *   u_long      proc;      -- procedure number
 *   xdrproc_t   xargs;      -- xdr routine for args
 *   caddr_t      argsp;      -- pointer to args
 *   xdrproc_t   xresults;   -- xdr routine for results
 *   caddr_t      resultsp;   -- pointer to results
 *   resultproc_t   eachresult;   -- call with each result obtained
 *   char      *nettype;   -- Transport type
 */

//TWT 10-24-97 typedef bool_t (N_API *resultproc_t)(caddr_t, struct netbuf FAR *, struct netconfig FAR *);
//DJB -- typedef bool_t (N_API *rproc_t)(caddr_t, struct sockaddr_in FAR *);

//TWT 10-24-97 extern enum clnt_stat N_API 
//TWT 10-24-97 rpc_broadcast(unsigned long, unsigned long, unsigned long, \
//TWT 10-24-97    xdrproc_t, caddr_t, xdrproc_t, caddr_t, resultproc_t, char FAR *);

//extern enum clnt_stat N_API
//DJB -- clnt_broadcast(unsigned long, unsigned long, unsigned long, \
//   xdrproc_t, caddr_t,   xdrproc_t, caddr_t, rproc_t);

#endif /* NWWIN */


#if defined(NWNLM) || defined(N_PLAT_NLM)

#ifndef _RPC_XDR_H
#include <rpc/xdr.h>
#endif
#ifndef _RPC_AUTH_H
#include <rpc/auth.h>
#endif

#ifndef _SYS_TIME_H_INCLUDED
#include <rpc/time.h>
#endif

extern int    RPCLibNLMid;
extern int    RPCLibHandle;

/*
// rpc calls return an enum clnt_stat.  This should be looked at more,
// since each implementation is required to live with this (implementation
// independent) list of errors.
*/
enum clnt_stat
{
   RPC_SUCCESS=0,             /* call succeeded */
   /*
   // local errors
   */
   RPC_CANTENCODEARGS=1,      /* can't encode arguments */
   RPC_CANTDECODERES=2,       /* can't decode results */
   RPC_CANTSEND=3,            /* failure in sending call */
   RPC_CANTRECV=4,            /* failure in receiving result */
   RPC_TIMEDOUT=5,            /* call timed out */
   RPC_INTR=18,               /* call interrupted */
   RPC_UDERROR=23,            /* recv got uderr indication */

   /*
   // remote errors
   */
   RPC_VERSMISMATCH=6,        /* rpc versions not compatible */
   RPC_AUTHERROR=7,           /* authentication error */
   RPC_PROGUNAVAIL=8,         /* program not available */
   RPC_PROGVERSMISMATCH=9,    /* program version mismatched */
   RPC_PROCUNAVAIL=10,        /* procedure unavailable */
   RPC_CANTDECODEARGS=11,     /* decode arguments error */
   RPC_SYSTEMERROR=12,        /* generic "other problem" */

   /*
   // rpc_call & clnt_create errors
   */
   RPC_UNKNOWNHOST=13,        /* unknown host name */
   RPC_UNKNOWNPROTO=17,       /* unknown protocol */
   RPC_UNKNOWNADDR=19,        /* Remote address unknown */
   RPC_NOBROADCAST=21,        /* Broadcasting not supported */

   /*
   // rpcbind errors
   */
   RPC_RPCBFAILURE=14,        /* the pmapper failed in its call */
   RPC_PROGNOTREGISTERED=15,  /* remote program is not registered */
   RPC_N2AXLATEFAILURE=22,    /* Name to address translation failed */
   /*
   // Misc error in the TLI library
   */
   RPC_PROTOCOL_ERROR = 20,         /* this is either TLI or WINSOCK */
   /*
   // unspecified error
   */
   RPC_FAILED=16,
   RPC_CANCELLED=25,
   RPC_INVALIDHANDLE=26,      /* invalid client handle */
   CLNT_STAT_DUMMY=INT_MIN
};

#define RPC_TLIERROR RPC_PROTOCOL_ERROR

/*
// Error info.
*/
struct rpc_err
{
   enum clnt_stat re_status;
   union
   {
      struct
      {
         int sys_errno;       /* related system error */
         int tli_errno;       /* related tli error number */
      } RE_err;
      enum auth_stat RE_why;  /* why the auth error occurred */
      struct
      {
         unsigned long low;   /* lowest verion supported */
         unsigned long high;  /* highest verion supported */
      } RE_vers;
      struct
      {     /* maybe meaningful if RPC_FAILED */
         long s1;
         long s2;
      } RE_lb;                /* life boot & debugging only */
   } ru;
};
#define  re_errno    ru.RE_err.sys_errno
#define  re_terrno   ru.RE_err.tli_errno
#define  re_why      ru.RE_why
#define  re_vers     ru.RE_vers
#define  re_lb       ru.RE_lb


/*
// Client rpc handle.
// Created by individual implementations
// Client is responsible for initializing auth, see e.g. auth_none.c.
*/
typedef struct CLIENT
{
   AUTH  *cl_auth;                     /* authenticator */
   struct clnt_ops
   {
      enum clnt_stat (*cl_call)();     /* call remote procedure */
      void           (*cl_abort)();    /* abort a call */
      void           (*cl_geterr)();   /* get specific error code */
      bool_t         (*cl_freeres)();  /* frees results */
      void           (*cl_destroy)();  /* destroy this structure */
      bool_t         (*cl_control)();  /* the ioctl() of rpc */
   } *cl_ops;
   caddr_t           cl_private;       /* private stuff */
   char              *cl_netid;        /* network token */
   char              *cl_tp;           /* device name */
} CLIENT;


/*
// client side rpc interface ops
*/

/*
// enum clnt_stat CLNT_CALL(
//    CLIENT      *rh,
//    u_long      proc,
//    xdrproc_t   xargs,
//    caddr_t     argsp,
//    xdrproc_t   xres,
//    caddr_t     resp,
//    struct timeval timeout)
*/
#define  CLNT_CALL(rh, proc, xargs, argsp, xres, resp, secs)   \
   ((*(rh)->cl_ops->cl_call)(rh, proc, xargs, argsp, xres, resp, secs))
#define  clnt_call(rh, proc, xargs, argsp, xres, resp, secs)   \
   ((*(rh)->cl_ops->cl_call)(rh, proc, xargs, argsp, xres, resp, secs))

/*
// void CLNT_ABORT(
//       CLIENT      *rh)
*/
#define  CLNT_ABORT(rh) ((*(rh)->cl_ops->cl_abort)(rh))
#define  clnt_abort(rh) ((*(rh)->cl_ops->cl_abort)(rh))

/*
// struct rpc_err CLNT_GETERR(
//       CLIENT      *rh)
*/
#define  CLNT_GETERR(rh, errp)   ((*(rh)->cl_ops->cl_geterr)(rh, errp))
#define  clnt_geterr(rh, errp)   ((*(rh)->cl_ops->cl_geterr)(rh, errp))

/*
// bool_t CLNT_FREERES(
//    CLIENT      *rh,
//    xdrproc_t   xres,
//    caddr_t     resp)
*/
#define  CLNT_FREERES(rh, xres, resp) \
            ((*(rh)->cl_ops->cl_freeres)(rh, xres, resp))
#define  clnt_freeres(rh, xres, resp) \
            ((*(rh)->cl_ops->cl_freeres)(rh, xres, resp))

/*
// bool_t CLNT_CONTROL(
//    CLIENT   *cl,
//    u_int    request,
//    char     *info)
*/
#define  CLNT_CONTROL(cl, rq, in) ((*(cl)->cl_ops->cl_control)(cl, rq, in))
#define  clnt_control(cl, rq, in) ((*(cl)->cl_ops->cl_control)(cl, rq, in))


/*
// control operations that apply to all transports
*/
#define  CLSET_TIMEOUT     1  /* set timeout (timeval) */
#define  CLGET_TIMEOUT     2  /* get timeout (timeval) */
#define  CLGET_SERVER_ADDR 3  /* get server's address (sockaddr) */
#define  CLGET_FD          6  /* get connections file descriptor */
#define  CLGET_SVC_ADDR    7  /* get server's address (netbuf) */
#define  CLSET_FD_CLOSE    8  /* close fd while clnt_destroy */
#define  CLSET_FD_NCLOSE   9  /* Do not close fd while clnt_destroy */

/*
// allow callout routines to break out of blocking I/O. The callout routine is
// called with an elapsed time timeval* or NULL before the I/O routine returns.
*/
#define CLSET_CALLOUT      16 /* set lowlevel callout */
#define CLGET_CALLOUT      17 /* get lowlevel callout */

typedef  bool_t (*rpc_cout_funct) (struct timeval *);

struct   rpc_cout
{
   struct timeval cout_poll;  /* time between blocking callouts */
   rpc_cout_funct cout_func;  /* callout function */
};
typedef  struct rpc_cout rpc_cout;


/*
// void CLNT_DESTROY(
//    CLIENT   *rh)
*/
#define  CLNT_DESTROY(rh)  ((*(rh)->cl_ops->cl_destroy)(rh))
#define  clnt_destroy(rh)  ((*(rh)->cl_ops->cl_destroy)(rh))


/*
// RPCTEST is a test program which is accessable on every rpc
// transport/port.  It is used for testing, performance evaluation,
// and network administration.
*/

#define  RPCTEST_PROGRAM         ((unsigned long)1)
#define  RPCTEST_VERSION         ((unsigned long)1)
#define  RPCTEST_NULL_PROC       ((unsigned long)2)
#define  RPCTEST_NULL_BATCH_PROC ((unsigned long)3)

/*
// By convention, procedure 0 takes null arguments and returns them
*/
#define  NULLPROC                ((unsigned long)0)


/*
// Below are the client handle creation routines for the various
// implementations of client side rpc.  They can return NULL if a
// creation failure occurs.
*/

/*
// Generic TLI create routine
*/
extern CLIENT *
clnt_tli_create(
   int                  fd,
   struct netconfig *   nconfig,
   struct netbuf *      svcaddr,
   unsigned long        program,    /* Program number */
   unsigned long        version,    /* Program version */
   unsigned int         sendsize,
   unsigned int         recvsize);

/*
// Low level clnt create routine for connectionful transports, e.g. tcp, spx.
*/
extern CLIENT *clnt_vc_create(
   int               fd,
   struct netbuf *   svcaddr,
   unsigned long     program,       /* Program number */
   unsigned long     version,       /* Program version */
   unsigned int      sendsize,
   unsigned int      recvsize);

char *clnt_spcreateerror(char *);   /* string */
char *clnt_sperror(CLIENT *, char *);  /* string */

/*
// If a creation fails, the following allows the user to figure out why.
*/
struct rpc_createerr
{
   enum clnt_stat cf_stat;
   struct rpc_err cf_error; /* useful when cf_stat == RPC_PMAPFAILURE */
};


extern struct rpc_createerr *_get_rpc_createerr_(void);

/*
// Copy error message to buffer.
*/
char *clnt_sperrno(enum clnt_stat); /* string */


CLIENT *clnt_ndps_create(
   Net_Address_T *addr,                /* I: service provider's address */
   unsigned long prog,                 /* I: program number */
   unsigned long vers);                 /* I: version number */

#endif /* NWNLM */ /* N_PLAT_NLM */



#endif /* _RPC_CLNT_H */