/*-
 * rpc.h --
 *	Declarations required by users of the rpc module.
 *
 * Copyright (c) 1988, 1989 by the Regents of the University of California
 * Copyright (c) 1988, 1989 by Adam de Boor
 * Copyright (c) 1989 by Berkeley Softworks
 *
 * Permission to use, copy, modify, and distribute this
 * software and its documentation for any non-commercial purpose
 * and without fee is hereby granted, provided that the above copyright
 * notice appears in all copies.  The University of California,
 * Berkeley Softworks and Adam de Boor make no representations about
 * the suitability of this software for any purpose.  It is provided
 * "as is" without express or implied warranty.
 *
 *	"$Id: rpc.h,v 1.24 1999/06/28 22:20:44 stolcke Exp $ ICSI (Berkeley)"
 */
#ifndef _RPC_H_
#define _RPC_H_

/*
 * Beware! Some systems are brain-dead when it comes to sys/types...
 */
#include    <sys/param.h>
#include    <sys/types.h>
#ifndef SOCK_STREAM /* ultrix doesn't guard against multiple inclusion ... */
#include    <sys/socket.h>
#endif
#ifndef IPPROTO_IP /* bsdi doesn't guard against multiple inclusion ... */
#include    <netinet/in.h>
#endif
#include    <arpa/inet.h>

#include    "sprite.h"

/*
 * Boolean arguments
 */
#define True	  1
#define False	  0

/*
 * What are signal handlers supposed to return ?
 */
#ifndef SIGRET
#define SIGRET void
#endif

/*
 * Integer types used in RPC calls.
 * These used to be called int32, int16, etc., but that could conflict
 * with system header files on some system.  Notice that
 * sizeof(Rpc_Long) != sizeof(long) on 64-bit systems.
 */
typedef	int		Rpc_Long;
typedef unsigned int	Rpc_ULong;
typedef	short		Rpc_Short;
typedef unsigned short	Rpc_UShort;

/*
 * Macro to deal with incompatible calling conventions between gcc and cc on
 * a sparc (gcc 1.x passes the address in a register, since the structure is
 * small enough, while cc still passes the address).
 */
#if (__GNUC__ == 1) && defined(sparc)
#define InetNtoA(addr)	inet_ntoa(&(addr))
#else
#define InetNtoA(addr)	inet_ntoa(addr)
#endif

/*
 * Define macros for select bitmap manipulation. What this will do on
 * systems that don't allow this many open descriptors, I don't know.
 */
#ifndef FD_SET

#define	NBBY	8		/* number of bits in a byte */
/*
 * Select uses bit masks of file descriptors in longs.
 * These macros manipulate such bit fields (the filesystem macros use chars).
 * FD_SETSIZE may be defined by the user, but the default here
 * should be >= NOFILE (param.h).
 */
#ifndef	FD_SETSIZE
#define	FD_SETSIZE	256
#endif

typedef long	fd_mask;
#define NFDBITS	(sizeof(fd_mask) * NBBY)	/* bits per mask */
#ifndef howmany
#define	howmany(x, y)	((unsigned int)(((x)+((y)-1)))/(unsigned int)(y))
#endif

#define fd_set my_fd_set
typedef	struct fd_set {
	fd_mask	fds_bits[howmany(FD_SETSIZE, NFDBITS)];
} fd_set;

#define	FD_SET(n, p)	((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
#define	FD_CLR(n, p)	((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
#define	FD_ISSET(n, p)	((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
#define FD_ZERO(p)	memset(p, 0, sizeof(*(p)))

#endif /* FD_SET */

#ifndef __FDS_BITS
# define __FDS_BITS(set) ((set)->fds_bits)	/* For Linux compatibility */
#endif

#ifndef MAX_DATA_SIZE
#define MAX_DATA_SIZE	    	(8*1024)	/* Largest RPC arg packet */
#endif

/*
 * Flags for Rpc_Watch
 */
#define RPC_READABLE	1
#define RPC_WRITABLE	2
#define RPC_EXCEPTABLE	4

typedef Rpc_UShort	Rpc_Proc;
typedef void 	  	*Rpc_Opaque;

typedef Rpc_Opaque  	Rpc_Event;  	/* Type returned by Rpc_EventCreate */
typedef Rpc_Opaque  	Rpc_Message;	/* Handle for replying to a call */

/*
 * For prefix's sunrpc module, we need to avoid defining this thing as an
 * enumerated type, since Sun RPC uses these same names (funny how that works)
 */
#ifndef NO_RPC_STAT
typedef enum {
    RPC_SUCCESS,	    /* Call succeeded, here's reply data */
    RPC_CANTSEND, 	    /* Couldn't send message, for some reason */
    RPC_TIMEDOUT,  	    /* Message timed out */
    RPC_TOOBIG,	  	    /* Results (or message) too big */
    RPC_NOPROC,	  	    /* No such procedure on remote machine */
    RPC_ACCESS,	  	    /* Permission denied */
    RPC_BADARGS,  	    /* Arguments were improper */
    RPC_SYSTEMERR,	    /* Undefined system error */
    RPC_BADSOCKET,	    /* Bad file descriptor passed */
    RPC_NOREPLY	    	    /* Disable replies and acks */
} Rpc_Stat;
#else
typedef Rpc_Long Rpc_Stat;
#endif

/*
 * Swapping definitions
 */
#define Rpc_SwapNull	((void (*)())0)	/* Constant for no swapping */
extern void	  Rpc_SwapShort();  	/* Swap a short integer (two bytes) */
extern void	  Rpc_SwapLong();   	/* Swap a long integer (four bytes) */

/*
 * Other definitions
 */
extern void	  Rpc_ServerCreate();	/* Create a service on a socket */
extern void	  Rpc_ServerDelete();	/* Delete a service on a socket */
extern Rpc_Event  Rpc_EventCreate();	/* Create a timer event */
extern Rpc_Event  Rpc_EventOnce();	/* Create a once-only event */
extern void	  Rpc_EventDelete();	/* Delete a timer event */
extern void	  Rpc_EventReset();	/* Reset the time of an event */
extern void	  Rpc_Watch();    	/* Watch a stream */
extern void	  Rpc_Ignore();   	/* Ignore a stream */
extern void	  Rpc_Error();    	/* Return an error to an RPC call */
extern void	  Rpc_Return();   	/* Return a reply to an RPC call */
extern Rpc_Stat   Rpc_Call();	    	/* Call a remote procedure */
extern Rpc_Stat   Rpc_Broadcast();	/* Broadcast a call to a remote
					 * procedure */
extern void	  Rpc_Wait();	    	/* Wait for something to happen */
extern void	  Rpc_Run();	    	/* Wait forever for something to
					 * happen */
extern int	  Rpc_TcpCreate();	/* Create a TCP socket with a name */
extern int	  Rpc_UdpCreate();	/* Create a UDP socket with a name */
extern void	  Rpc_Debug();    	/* Turn on debugging printouts */
extern int	  Rpc_MessageSocket();	/* Return the socket for a message */
extern char	  *Rpc_ErrorMessage();	/* Return a string describing an error
					 * status */
extern void	  Rpc_Reset();    	/* Reset the module, deleting all
					 * services, timer events and watched
					 * streams */
extern Boolean	  Rpc_IsLocal();    	/* See if an internet socket address
					 * is for the local machine */
extern Boolean	  Rpc_IsAllowed();	/* Check if address has RPC access */
extern Boolean	  Rpc_Allow();		/* Allow RPC access for address */
extern Boolean	  Rpc_Deny();		/* Deny RPC access from address */

extern fd_set	  rpc_readMask;	    	/* Mask of streams to check for
					 * reading */
extern fd_set	  rpc_writeMask;    	/* Mask of streams to check for
					 * writing */
extern fd_set	  rpc_exceptMask;   	/* Mask of streams to check for an
					 * exceptional condition */

#endif /* _RPC_H_ */
