diff options
author | Joel Sherrill <joel.sherrill@OARcorp.com> | 2000-06-12 15:00:15 +0000 |
---|---|---|
committer | Joel Sherrill <joel.sherrill@OARcorp.com> | 2000-06-12 15:00:15 +0000 |
commit | df49c60c9671e4a28e636964d744c1f59fb6cb68 (patch) | |
tree | eabd85e189514ad412a35414ba5d483dcda3ef1f /cpukit/librpc | |
parent | Purged as many egcs references as possible. (diff) | |
download | rtems-df49c60c9671e4a28e636964d744c1f59fb6cb68.tar.bz2 |
Merged from 4.5.0-beta3a
Diffstat (limited to 'cpukit/librpc')
133 files changed, 35655 insertions, 338 deletions
diff --git a/cpukit/librpc/Makefile.am b/cpukit/librpc/Makefile.am index e74c9e748c..d9429399ec 100644 --- a/cpukit/librpc/Makefile.am +++ b/cpukit/librpc/Makefile.am @@ -7,5 +7,7 @@ ACLOCAL_AMFLAGS = -I $(RTEMS_TOPdir)/aclocal SUBDIRS = include src +EXTRA_DIST = README_RTEMS + include $(top_srcdir)/../../../automake/subdirs.am include $(top_srcdir)/../../../automake/local.am diff --git a/cpukit/librpc/README_RTEMS b/cpukit/librpc/README_RTEMS index e69de29bb2..e60f8799aa 100644 --- a/cpukit/librpc/README_RTEMS +++ b/cpukit/librpc/README_RTEMS @@ -0,0 +1,64 @@ +USING RPC/XDR ON RTEMS +====================== +For the most part, programmers using RPC/XDR routines on RTEMS +can proceed as if they were to be using a POSIX/UNIX system. +The only significant changes are those to start the portmapper +and to allow use of RPC/XDR by multiple threads. + +Starting the portmapper +======================= +The SUN portmapper program has been modified to run as an RTEMS +task. Applications which need the portmapper can start this +task by calling: + int rtems_rpc_start_portmapper (int priority); +The return value is an RTEMS status code. + +Multi-threaded operation +======================== +The RPC/XDR package has been modified to allow for multiple RTEMS +tasks to use RPC/XDR routines. If more than one task is to call +an RPC/XDR routine, the additional tasks must call: + int rtems_rpc_task_init(void); +before calling any RPC/XDR routines. For example, the portmapper +calls this routine since the portmapper uses RPC/XDR routines in +a separate thread. +The return value is an RTEMS status code. + + +Porting Notes +============= +Most of the FreeBSD rpc library ports to RTEMS with little +or no modification beyond that required to provide for operation +in a multitasking environment. Multitasking operation was +provided by moving all `static persistence' variables into +a single structure and using an RTEMS task variable to point +to that structure. + +Some of the library, however, has not made it into the RTEMS +implementation. FreeBSD source files which have been left out include: +- Files which provide RPC to the AF_UNIX address family: + clnt_unix.c + svc_unix.c + An `ifndef __rtems__' was added to clnt_generic.c because clnt_unix.c + was omitted. +- Files which need NIS: + auth_time.c +- Files which provide DES authentication: + auth_des.c + authdes_prot.c + crypt_client.c + des_crypt.c + des_soft.c + getpublickey.c + key_call.c + key_prot_xdr.c + svc_auth_des.c + +The FreeBSD xdr source compiles and runs on RTEMS without modification. + +The original source was obtained from: + ftp://ftp.FreeBSD.org/pub/FreeBSD/ + branches/4.0-stable/src/lib/libc/rpc + branches/4.0-stable/src/lib/libc/xdr + branches/4.0-stable/src/include/rpc + branches/4.0-stable/src/include/rpcsvc diff --git a/cpukit/librpc/include/Makefile.am b/cpukit/librpc/include/Makefile.am index d5385c1f70..bb33b0a8b6 100644 --- a/cpukit/librpc/include/Makefile.am +++ b/cpukit/librpc/include/Makefile.am @@ -4,7 +4,7 @@ AUTOMAKE_OPTIONS = foreign 1.4 -SUBDIRS = rpc +SUBDIRS = rpc rpcsvc include $(top_srcdir)/../../../automake/subdirs.am include $(top_srcdir)/../../../automake/local.am diff --git a/cpukit/librpc/include/rpc/Makefile.am b/cpukit/librpc/include/rpc/Makefile.am index 5ca801b3c9..a917bd86dc 100644 --- a/cpukit/librpc/include/rpc/Makefile.am +++ b/cpukit/librpc/include/rpc/Makefile.am @@ -4,14 +4,15 @@ AUTOMAKE_OPTIONS = foreign 1.4 -H_FILES = auth.h rpc.h svc.h types.h clnt.h rpc_msg.h svc_auth.h xdr.h +H_FILES = auth.h auth_des.h auth_unix.h clnt.h des.h des_crypt.h pmap_clnt.h \ + pmap_prot.h pmap_rmt.h rpc.h rpc_com.h rpc_msg.h svc.h svc_auth.h \ + types.h xdr.h noinst_HEADERS = $(H_FILES) if HAS_NETWORKING -PREINSTALL_FILES = \ -$(PROJECT_INCLUDE)/rpc \ -$(H_FILES:%=$(PROJECT_INCLUDE)/rpc/%) +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rpc \ + $(H_FILES:%=$(PROJECT_INCLUDE)/rpc/%) $(PROJECT_INCLUDE)/rpc: @$(mkinstalldirs) $@ @@ -19,8 +20,6 @@ $(PROJECT_INCLUDE)/rpc/%.h: %.h $(INSTALL_DATA) $< $@ endif -all-am: $(PREINSTALL_FILES) -debug-am: $(PREINSTALL_FILES) -profile-am: $(PREINSTALL_FILES) +all-local: $(PREINSTALL_FILES) include $(top_srcdir)/../../../automake/local.am diff --git a/cpukit/librpc/include/rpc/auth.h b/cpukit/librpc/include/rpc/auth.h index 8f14d144f6..a15be39185 100644 --- a/cpukit/librpc/include/rpc/auth.h +++ b/cpukit/librpc/include/rpc/auth.h @@ -1,7 +1,3 @@ -#ifndef RPC_AUTH_H -#define RPC_AUTH_H - -/* @(#)auth.h 2.3 88/08/07 4.0 RPCSRC; from 1.17 88/02/08 SMI */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape @@ -9,26 +5,30 @@ * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or * program developed by the user. - * + * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * + * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. - * + * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. - * + * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. - * + * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 + * + * from: @(#)auth.h 1.17 88/02/08 SMI + * from: @(#)auth.h 2.3 88/08/07 4.0 RPCSRC + * $FreeBSD: src/include/rpc/auth.h,v 1.15 1999/08/27 23:45:02 peter Exp $ */ /* @@ -41,6 +41,10 @@ * "sessions". */ +#ifndef _RPC_AUTH_H +#define _RPC_AUTH_H +#include <sys/cdefs.h> +#include <sys/socket.h> #define MAX_AUTH_BYTES 400 #define MAXNETNAMELEN 255 /* maximum length of network user's name */ @@ -67,13 +71,15 @@ enum auth_stat { union des_block { struct { - u_int32 high; - u_int32 low; + u_int32_t high; + u_int32_t low; } key; char c[8]; }; typedef union des_block des_block; -extern bool_t xdr_des_block(); +__BEGIN_DECLS +extern bool_t xdr_des_block __P((XDR *, des_block *)); +__END_DECLS /* * Authentication info. Opaque to client. @@ -83,21 +89,29 @@ struct opaque_auth { caddr_t oa_base; /* address of more auth stuff */ u_int oa_length; /* not to exceed MAX_AUTH_BYTES */ }; +__BEGIN_DECLS +bool_t xdr_opaque_auth __P((XDR *xdrs, struct opaque_auth *ap)); +__END_DECLS /* * Auth handle, interface to client side authenticators. */ -typedef struct { +typedef struct __rpc_auth { struct opaque_auth ah_cred; struct opaque_auth ah_verf; union des_block ah_key; struct auth_ops { - void (*ah_nextverf)(); - int (*ah_marshal)(); /* nextverf & serialize */ - int (*ah_validate)(); /* validate varifier */ - int (*ah_refresh)(); /* refresh credentials */ - void (*ah_destroy)(); /* destroy this structure */ + void (*ah_nextverf) __P((struct __rpc_auth *)); + /* nextverf & serialize */ + int (*ah_marshal) __P((struct __rpc_auth *, XDR *)); + /* validate verifier */ + int (*ah_validate) __P((struct __rpc_auth *, + struct opaque_auth *)); + /* refresh credentials */ + int (*ah_refresh) __P((struct __rpc_auth *)); + /* destroy this structure */ + void (*ah_destroy) __P((struct __rpc_auth *)); } *ah_ops; caddr_t ah_private; } AUTH; @@ -139,7 +153,6 @@ typedef struct { extern struct opaque_auth _null_auth; - /* * These are the various implementations of client side authenticators. */ @@ -153,15 +166,95 @@ extern struct opaque_auth _null_auth; * int len; * int *aup_gids; */ -extern AUTH *authunix_create(); -extern AUTH *authunix_create_default(); /* takes no parameters */ -extern AUTH *authnone_create(); /* takes no parameters */ -extern AUTH *authdes_create(); +__BEGIN_DECLS +struct sockaddr_in; +extern AUTH *authunix_create __P((char *, int, int, int, int *)); +extern AUTH *authunix_create_default __P((void)); +extern AUTH *authnone_create __P((void)); +__END_DECLS + +/* Forward compatibility with TI-RPC */ +#define authsys_create authunix_create +#define authsys_create_default authunix_create_default + +/* + * DES style authentication + * AUTH *authdes_create(servername, window, timehost, ckey) + * char *servername; - network name of server + * u_int window; - time to live + * struct sockaddr *timehost; - optional hostname to sync with + * des_block *ckey; - optional conversation key to use + */ +__BEGIN_DECLS +extern AUTH *authdes_create __P(( char *, u_int, struct sockaddr *, des_block * )); +#ifdef NOTYET +/* + * TI-RPC supports this call, but it requires the inclusion of + * NIS+-specific headers which would require the inclusion of other + * headers which would result in a tangled mess. For now, the NIS+ + * code prototypes this routine internally. + */ +extern AUTH *authdes_pk_create __P(( char *, netobj *, u_int, + struct sockaddr *, des_block *, + nis_server * )); +#endif +__END_DECLS + +/* + * Netname manipulation routines. + */ +__BEGIN_DECLS +extern int netname2user __P(( char *, uid_t *, gid_t *, int *, gid_t *)); +extern int netname2host __P(( char *, char *, int )); +extern int getnetname __P(( char * )); +extern int user2netname __P(( char *, uid_t, char * )); +extern int host2netname __P(( char *, char *, char * )); +extern void passwd2des __P(( char *, char * )); +__END_DECLS + +/* + * Keyserv interface routines. + * XXX Should not be here. + */ +#ifndef HEXKEYBYTES +#define HEXKEYBYTES 48 +#endif +typedef char kbuf[HEXKEYBYTES]; +typedef char *namestr; + +struct netstarg { + kbuf st_priv_key; + kbuf st_pub_key; + namestr st_netname; +}; + +__BEGIN_DECLS +extern int key_decryptsession __P(( const char *, des_block * )); +extern int key_decryptsession_pk __P(( char *, netobj *, des_block * )); +extern int key_encryptsession __P(( const char *, des_block * )); +extern int key_encryptsession_pk __P(( char *, netobj *, des_block * )); +extern int key_gendes __P(( des_block * )); +extern int key_setsecret __P(( const char * )); +extern int key_secretkey_is_set __P(( void )); +extern int key_setnet __P(( struct netstarg * )); +extern int key_get_conv __P(( char *, des_block * )); +__END_DECLS + +/* + * Publickey routines. + */ +__BEGIN_DECLS +extern int getpublickey __P(( char *, char * )); +extern int getpublicandprivatekey __P(( char *, char * )); +extern int getsecretkey __P(( char *, char *, char * )); +__END_DECLS + #define AUTH_NONE 0 /* no authentication */ #define AUTH_NULL 0 /* backward compatibility */ #define AUTH_UNIX 1 /* unix style (uid, gids) */ +#define AUTH_SYS 1 /* forward compatibility */ #define AUTH_SHORT 2 /* short hand unix style */ #define AUTH_DES 3 /* des style (encrypted timestamps) */ -#endif /* RPC_AUTH_H */ +#endif /* !_RPC_AUTH_H */ diff --git a/cpukit/librpc/include/rpc/auth_des.h b/cpukit/librpc/include/rpc/auth_des.h index e69de29bb2..a7635f87e1 100644 --- a/cpukit/librpc/include/rpc/auth_des.h +++ b/cpukit/librpc/include/rpc/auth_des.h @@ -0,0 +1,109 @@ +/* @(#)auth_des.h 2.2 88/07/29 4.0 RPCSRC; from 1.3 88/02/08 SMI */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * Copyright (c) 1988 by Sun Microsystems, Inc. + */ + +/* + * auth_des.h, Protocol for DES style authentication for RPC + */ + +#ifndef _AUTH_DES_ +#define _AUTH_DES_ + +/* + * There are two kinds of "names": fullnames and nicknames + */ +enum authdes_namekind { + ADN_FULLNAME, + ADN_NICKNAME +}; + +/* + * A fullname contains the network name of the client, + * a conversation key and the window + */ +struct authdes_fullname { + char *name; /* network name of client, up to MAXNETNAMELEN */ + des_block key; /* conversation key */ + u_long window; /* associated window */ +}; + + +/* + * A credential + */ +struct authdes_cred { + enum authdes_namekind adc_namekind; + struct authdes_fullname adc_fullname; + u_long adc_nickname; +}; + + + +/* + * A des authentication verifier + */ +struct authdes_verf { + union { + struct timeval adv_ctime; /* clear time */ + des_block adv_xtime; /* crypt time */ + } adv_time_u; + u_long adv_int_u; +}; + +/* + * des authentication verifier: client variety + * + * adv_timestamp is the current time. + * adv_winverf is the credential window + 1. + * Both are encrypted using the conversation key. + */ +#define adv_timestamp adv_time_u.adv_ctime +#define adv_xtimestamp adv_time_u.adv_xtime +#define adv_winverf adv_int_u + +/* + * des authentication verifier: server variety + * + * adv_timeverf is the client's timestamp + client's window + * adv_nickname is the server's nickname for the client. + * adv_timeverf is encrypted using the conversation key. + */ +#define adv_timeverf adv_time_u.adv_ctime +#define adv_xtimeverf adv_time_u.adv_xtime +#define adv_nickname adv_int_u + +__BEGIN_DECLS +extern int authdes_getucred __P(( struct authdes_cred *, uid_t *, gid_t *, int *, gid_t * )); +__END_DECLS + +#endif /* ndef _AUTH_DES_ */ diff --git a/cpukit/librpc/include/rpc/auth_unix.h b/cpukit/librpc/include/rpc/auth_unix.h index e69de29bb2..4b015b67ab 100644 --- a/cpukit/librpc/include/rpc/auth_unix.h +++ b/cpukit/librpc/include/rpc/auth_unix.h @@ -0,0 +1,84 @@ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + * + * from: @(#)auth_unix.h 1.8 88/02/08 SMI + * from: @(#)auth_unix.h 2.2 88/07/29 4.0 RPCSRC + * $FreeBSD: src/include/rpc/auth_unix.h,v 1.10 1999/08/27 23:45:03 peter Exp $ + */ + +/* + * auth_unix.h, Protocol for UNIX style authentication parameters for RPC + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +/* + * The system is very weak. The client uses no encryption for it + * credentials and only sends null verifiers. The server sends backs + * null verifiers or optionally a verifier that suggests a new short hand + * for the credentials. + */ + +#ifndef _RPC_AUTH_UNIX_H +#define _RPC_AUTH_UNIX_H +#include <sys/cdefs.h> + +/* The machine name is part of a credential; it may not exceed 255 bytes */ +#define MAX_MACHINE_NAME 255 + +/* gids compose part of a credential; there may not be more than 16 of them */ +#define NGRPS 16 + +/* + * Unix style credentials. + */ +struct authunix_parms { + u_long aup_time; + char *aup_machname; + int aup_uid; + int aup_gid; + u_int aup_len; + int *aup_gids; +}; + +#define authsys_parms authunix_parms + +__BEGIN_DECLS +extern bool_t xdr_authunix_parms __P((XDR *, struct authunix_parms *)); +__END_DECLS + +/* + * If a response verifier has flavor AUTH_SHORT, + * then the body of the response verifier encapsulates the following structure; + * again it is serialized in the obvious fashion. + */ +struct short_hand_verf { + struct opaque_auth new_cred; +}; + +#endif /* !_RPC_AUTH_UNIX_H */ diff --git a/cpukit/librpc/include/rpc/clnt.h b/cpukit/librpc/include/rpc/clnt.h index faefdb5d50..dc0f12d25c 100644 --- a/cpukit/librpc/include/rpc/clnt.h +++ b/cpukit/librpc/include/rpc/clnt.h @@ -1,7 +1,3 @@ -#ifndef RPC_CLNT_H -#define RPC_CLNT_H - -/* @(#)clnt.h 2.1 88/07/29 4.0 RPCSRC; from 1.31 88/02/08 SMI*/ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape @@ -9,26 +5,30 @@ * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or * program developed by the user. - * + * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * + * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. - * + * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. - * + * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. - * + * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 + * + * from: @(#)clnt.h 1.31 88/02/08 SMI + * from: @(#)clnt.h 2.1 88/07/29 4.0 RPCSRC + * $FreeBSD: src/include/rpc/clnt.h,v 1.11 1999/08/27 23:45:03 peter Exp $ */ /* @@ -37,8 +37,10 @@ * Copyright (C) 1984, Sun Microsystems, Inc. */ -#ifndef _CLNT_ -#define _CLNT_ +#ifndef _RPC_CLNT_H_ +#define _RPC_CLNT_H_ +#include <sys/cdefs.h> +#include <sys/un.h> /* * Rpc calls return an enum clnt_stat. This should be looked at more, @@ -90,15 +92,15 @@ enum clnt_stat { struct rpc_err { enum clnt_stat re_status; union { - int RE_errno; /* realated system error */ + int RE_errno; /* related system error */ enum auth_stat RE_why; /* why the auth error occurred */ struct { - u_long low; /* lowest verion supported */ - u_long high; /* highest verion supported */ + u_int32_t low; /* lowest verion supported */ + u_int32_t high; /* highest verion supported */ } RE_vers; struct { /* maybe meaningful if RPC_FAILED */ - long s1; - long s2; + int32_t s1; + int32_t s2; } RE_lb; /* life boot & debugging only */ } ru; #define re_errno ru.RE_errno @@ -113,15 +115,26 @@ struct rpc_err { * Created by individual implementations, see e.g. rpc_udp.c. * Client is responsible for initializing auth, see e.g. auth_none.c. */ -typedef struct { +typedef struct __rpc_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 */ + /* call remote procedure */ + enum clnt_stat (*cl_call) __P((struct __rpc_client *, + u_long, xdrproc_t, caddr_t, xdrproc_t, + caddr_t, struct timeval)); + /* abort a call */ + void (*cl_abort) __P((struct __rpc_client *)); + /* get specific error code */ + void (*cl_geterr) __P((struct __rpc_client *, + struct rpc_err *)); + /* frees results */ + bool_t (*cl_freeres) __P((struct __rpc_client *, + xdrproc_t, caddr_t)); + /* destroy this structure */ + void (*cl_destroy) __P((struct __rpc_client *)); + /* the ioctl() of rpc */ + bool_t (*cl_control) __P((struct __rpc_client *, u_int, + void *)); } *cl_ops; caddr_t cl_private; /* private stuff */ } CLIENT; @@ -146,9 +159,11 @@ typedef struct { * 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)) + ((*(rh)->cl_ops->cl_call)(rh, proc, xargs, (caddr_t)argsp, \ + xres, (caddr_t)resp, secs)) #define clnt_call(rh, proc, xargs, argsp, xres, resp, secs) \ - ((*(rh)->cl_ops->cl_call)(rh, proc, xargs, argsp, xres, resp, secs)) + ((*(rh)->cl_ops->cl_call)(rh, proc, xargs, (caddr_t)argsp, \ + xres, (caddr_t)resp, secs)) /* * void @@ -188,11 +203,30 @@ typedef struct { #define clnt_control(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in)) /* - * control operations that apply to both udp and tcp transports + * control operations that apply to udp, tcp and unix transports + * + * Note: options marked XXX are no-ops in this implementation of RPC. + * The are present in TI-RPC but can't be implemented here since they + * depend on the presence of STREAMS/TLI, which we don't have. + * */ #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) XXX */ +#define CLSET_FD_CLOSE 8 /* close fd while clnt_destroy */ +#define CLSET_FD_NCLOSE 9 /* Do not close fd while clnt_destroy */ +#define CLGET_XID 10 /* Get xid */ +#define CLSET_XID 11 /* Set xid */ +#define CLGET_VERS 12 /* Get version number */ +#define CLSET_VERS 13 /* Set version number */ +#define CLGET_PROG 14 /* Get program number */ +#define CLSET_PROG 15 /* Set program number */ +#define CLSET_SVC_ADDR 16 /* get server's address (netbuf) XXX */ +#define CLSET_PUSH_TIMOD 17 /* push timod if not already present XXX */ +#define CLSET_POP_TIMOD 18 /* pop timod XXX */ + /* * udp only control operations */ @@ -200,6 +234,12 @@ typedef struct { #define CLGET_RETRY_TIMEOUT 5 /* get retry timeout (timeval) */ /* + * Operations which GSSAPI needs. (Bletch.) + */ +#define CLGET_LOCAL_ADDR 19 /* get local addr (sockaddr) */ + + +/* * void * CLNT_DESTROY(rh); * CLIENT *rh; @@ -209,7 +249,7 @@ typedef struct { /* - * RPCTEST is a test program which is accessable on every rpc + * RPCTEST is a test program which is accessible on every rpc * transport/port. It is used for testing, performance evaluation, * and network administration. */ @@ -227,7 +267,7 @@ typedef struct { /* * Below are the client handle creation routines for the various - * implementations of client side rpc. They can return NULL if a + * implementations of client side rpc. They can return NULL if a * creation failure occurs. */ @@ -238,21 +278,24 @@ typedef struct { * u_long prog; * u_long vers; */ -extern CLIENT *clntraw_create(); +__BEGIN_DECLS +extern CLIENT *clntraw_create __P((u_long, u_long)); +__END_DECLS /* - * Generic client creation routine. Supported protocols are "udp" and "tcp" + * Generic client creation routine. Supported protocols are "udp", "tcp" + * and "unix". + * CLIENT * + * clnt_create(host, prog, vers, prot); + * char *host; -- hostname + * u_long prog; -- program number + * u_long vers; -- version number + * char *prot; -- protocol */ -extern CLIENT * -clnt_create(/*host, prog, vers, prot*/); /* - char *host; -- hostname - u_long prog; -- program number - u_long vers; -- version number - char *prot; -- protocol -*/ - - +__BEGIN_DECLS +extern CLIENT *clnt_create __P((char *, u_long, u_long, char *)); +__END_DECLS /* @@ -266,7 +309,15 @@ clnt_create(/*host, prog, vers, prot*/); /* * u_int sendsz; * u_int recvsz; */ -extern CLIENT *clnttcp_create(); +__BEGIN_DECLS +extern CLIENT *clnttcp_create __P((struct sockaddr_in *, + u_long, + u_long, + int *, + u_int, + u_int)); +__END_DECLS + /* * UDP based rpc. @@ -289,27 +340,69 @@ extern CLIENT *clnttcp_create(); * u_int sendsz; * u_int recvsz; */ -extern CLIENT *clntudp_create(); -extern CLIENT *clntudp_bufcreate(); +__BEGIN_DECLS +extern CLIENT *clntudp_create __P((struct sockaddr_in *, + u_long, + u_long, + struct timeval, + int *)); +extern CLIENT *clntudp_bufcreate __P((struct sockaddr_in *, + u_long, + u_long, + struct timeval, + int *, + u_int, + u_int)); +__END_DECLS + + +/* + * AF_UNIX based rpc + * CLIENT * + * clntunix_create(raddr, prog, vers, sockp, sendsz, recvsz) + * struct sockaddr_un *raddr; + * u_long prog; + * u_long version; + * register int *sockp; + * u_int sendsz; + * u_int recvsz; + */ +__BEGIN_DECLS +extern CLIENT *clntunix_create __P((struct sockaddr_un *, + u_long, + u_long, + int *, + u_int, + u_int)); +__END_DECLS + /* * Print why creation failed */ -void clnt_pcreateerror(/* char *msg */); /* stderr */ -char *clnt_spcreateerror(/* char *msg */); /* string */ +__BEGIN_DECLS +extern void clnt_pcreateerror __P((char *)); /* stderr */ +extern char *clnt_spcreateerror __P((char *)); /* string */ +__END_DECLS /* * Like clnt_perror(), but is more verbose in its output - */ -void clnt_perrno(/* enum clnt_stat num */); /* stderr */ + */ +__BEGIN_DECLS +extern void clnt_perrno __P((enum clnt_stat)); /* stderr */ +extern char *clnt_sperrno __P((enum clnt_stat)); /* string */ +__END_DECLS /* * Print an English error message, given the client error code */ -void clnt_perror(/* CLIENT *clnt, char *msg */); /* stderr */ -char *clnt_sperror(/* CLIENT *clnt, char *msg */); /* string */ +__BEGIN_DECLS +extern void clnt_perror __P((CLIENT *, char *)); /* stderr */ +extern char *clnt_sperror __P((CLIENT *, char *)); /* string */ +__END_DECLS -/* + +/* * If a creation fails, the following allows the user to figure out why. */ struct rpc_createerr { @@ -320,17 +413,7 @@ struct rpc_createerr { extern struct rpc_createerr rpc_createerr; - -/* - * Copy error message to buffer. - */ -char *clnt_sperrno(/* enum clnt_stat num */); /* string */ - - - #define UDPMSGSIZE 8800 /* rpc imposed limit on udp msg size */ #define RPCSMALLMSGSIZE 400 /* a more reasonable packet size */ -#endif /*!_CLNT_*/ - -#endif /* RPC_CLNT_H */ +#endif /* !_RPC_CLNT_H */ diff --git a/cpukit/librpc/include/rpc/des.h b/cpukit/librpc/include/rpc/des.h index e69de29bb2..f41e5a7804 100644 --- a/cpukit/librpc/include/rpc/des.h +++ b/cpukit/librpc/include/rpc/des.h @@ -0,0 +1,82 @@ +/* @(#)des.h 2.2 88/08/10 4.0 RPCSRC; from 2.7 88/02/08 SMI */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +/* + * Generic DES driver interface + * Keep this file hardware independent! + * Copyright (c) 1986 by Sun Microsystems, Inc. + */ + +#define DES_MAXLEN 65536 /* maximum # of bytes to encrypt */ +#define DES_QUICKLEN 16 /* maximum # of bytes to encrypt quickly */ + +enum desdir { ENCRYPT, DECRYPT }; +enum desmode { CBC, ECB }; + +/* + * parameters to ioctl call + */ +struct desparams { + u_char des_key[8]; /* key (with low bit parity) */ + enum desdir des_dir; /* direction */ + enum desmode des_mode; /* mode */ + u_char des_ivec[8]; /* input vector */ + unsigned des_len; /* number of bytes to crypt */ + union { + u_char UDES_data[DES_QUICKLEN]; + u_char *UDES_buf; + } UDES; +# define des_data UDES.UDES_data /* direct data here if quick */ +# define des_buf UDES.UDES_buf /* otherwise, pointer to data */ +}; + +#ifdef notdef + +/* + * These ioctls are only implemented in SunOS. Maybe someday + * if somebody writes a driver for DES hardware that works + * with FreeBSD, we can being that back. + */ + +/* + * Encrypt an arbitrary sized buffer + */ +#define DESIOCBLOCK _IOWR(d, 6, struct desparams) + +/* + * Encrypt of small amount of data, quickly + */ +#define DESIOCQUICK _IOWR(d, 7, struct desparams) + +#endif + +/* + * Software DES. + */ +extern int _des_crypt __P(( char *, int, struct desparams * )); diff --git a/cpukit/librpc/include/rpc/des_crypt.h b/cpukit/librpc/include/rpc/des_crypt.h index e69de29bb2..c9458fcf24 100644 --- a/cpukit/librpc/include/rpc/des_crypt.h +++ b/cpukit/librpc/include/rpc/des_crypt.h @@ -0,0 +1,120 @@ +/* + * @(#)des_crypt.h 2.1 88/08/11 4.0 RPCSRC; from 1.4 88/02/08 (C) 1986 SMI + * $FreeBSD: src/include/rpc/des_crypt.h,v 1.2 1999/12/29 05:00:42 peter Exp $ + * + * des_crypt.h, des library routine interface + * Copyright (C) 1986, Sun Microsystems, Inc. + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#include <sys/cdefs.h> +#include <rpc/rpc.h> + +#define DES_MAXDATA 8192 /* max bytes encrypted in one call */ +#define DES_DIRMASK (1 << 0) +#define DES_ENCRYPT (0*DES_DIRMASK) /* Encrypt */ +#define DES_DECRYPT (1*DES_DIRMASK) /* Decrypt */ + + +#define DES_DEVMASK (1 << 1) +#define DES_HW (0*DES_DEVMASK) /* Use hardware device */ +#define DES_SW (1*DES_DEVMASK) /* Use software device */ + + +#define DESERR_NONE 0 /* succeeded */ +#define DESERR_NOHWDEVICE 1 /* succeeded, but hw device not available */ +#define DESERR_HWERROR 2 /* failed, hardware/driver error */ +#define DESERR_BADPARAM 3 /* failed, bad parameter to call */ + +#define DES_FAILED(err) \ + ((err) > DESERR_NOHWDEVICE) + +/* + * cbc_crypt() + * ecb_crypt() + * + * Encrypt (or decrypt) len bytes of a buffer buf. + * The length must be a multiple of eight. + * The key should have odd parity in the low bit of each byte. + * ivec is the input vector, and is updated to the new one (cbc only). + * The mode is created by oring together the appropriate parameters. + * DESERR_NOHWDEVICE is returned if DES_HW was specified but + * there was no hardware to do it on (the data will still be + * encrypted though, in software). + */ + + +/* + * Cipher Block Chaining mode + */ +__BEGIN_DECLS +#ifdef __STDC__ +int cbc_crypt __P(( char *, char *, unsigned int, unsigned int, char *)); +#else +cbc_crypt(/* key, buf, len, mode, ivec */); /* + char *key; + char *buf; + unsigned len; + unsigned mode; + char *ivec; +*/ +#endif + +/* + * Electronic Code Book mode + */ +#ifdef __STDC__ +int ecb_crypt __P(( char *, char *, unsigned int, unsigned int )); +#else +ecb_crypt(/* key, buf, len, mode */); /* + char *key; + char *buf; + unsigned len; + unsigned mode; +*/ +#endif +__END_DECLS + +#ifndef _KERNEL +/* + * Set des parity for a key. + * DES parity is odd and in the low bit of each byte + */ +__BEGIN_DECLS +#ifdef __STDC__ +void des_setparity __P(( char *)); +#else +void +des_setparity(/* key */); /* + char *key; +*/ +#endif +__END_DECLS +#endif diff --git a/cpukit/librpc/include/rpc/pmap_clnt.h b/cpukit/librpc/include/rpc/pmap_clnt.h index e69de29bb2..2f4a2780dd 100644 --- a/cpukit/librpc/include/rpc/pmap_clnt.h +++ b/cpukit/librpc/include/rpc/pmap_clnt.h @@ -0,0 +1,85 @@ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + * + * from: @(#)pmap_clnt.h 1.11 88/02/08 SMI + * from: @(#)pmap_clnt.h 2.1 88/07/29 4.0 RPCSRC + * $FreeBSD: src/include/rpc/pmap_clnt.h,v 1.11 1999/08/27 23:45:04 peter Exp $ + */ + +/* + * pmap_clnt.h + * Supplies C routines to get to portmap services. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +/* + * Usage: + * success = pmap_set(program, version, protocol, port); + * success = pmap_unset(program, version); + * port = pmap_getport(address, program, version, protocol); + * head = pmap_getmaps(address); + * clnt_stat = pmap_rmtcall(address, program, version, procedure, + * xdrargs, argsp, xdrres, resp, tout, port_ptr) + * (works for udp only.) + * clnt_stat = clnt_broadcast(program, version, procedure, + * xdrargs, argsp, xdrres, resp, eachresult) + * (like pmap_rmtcall, except the call is broadcasted to all + * locally connected nets. For each valid response received, + * the procedure eachresult is called. Its form is: + * done = eachresult(resp, raddr) + * bool_t done; + * caddr_t resp; + * struct sockaddr_in raddr; + * where resp points to the results of the call and raddr is the + * address if the responder to the broadcast. + */ + +#ifndef _RPC_PMAPCLNT_H +#define _RPC_PMAPCLNT_H +#include <sys/cdefs.h> + +__BEGIN_DECLS +extern bool_t pmap_set __P((u_long, u_long, int, int)); +extern bool_t pmap_unset __P((u_long, u_long)); +extern struct pmaplist *pmap_getmaps __P((struct sockaddr_in *)); +extern enum clnt_stat pmap_rmtcall __P((struct sockaddr_in *, + u_long, u_long, u_long, + xdrproc_t, caddr_t, + xdrproc_t, caddr_t, + struct timeval, u_long *)); +extern enum clnt_stat clnt_broadcast __P((u_long, u_long, u_long, + xdrproc_t, char *, + xdrproc_t, char *, + bool_t (*) __P((caddr_t, + struct sockaddr_in *)))); +extern u_short pmap_getport __P((struct sockaddr_in *, + u_long, u_long, u_int)); +__END_DECLS + +#endif /* !_RPC_PMAPCLNT_H */ diff --git a/cpukit/librpc/include/rpc/pmap_prot.h b/cpukit/librpc/include/rpc/pmap_prot.h index e69de29bb2..14f0837bfe 100644 --- a/cpukit/librpc/include/rpc/pmap_prot.h +++ b/cpukit/librpc/include/rpc/pmap_prot.h @@ -0,0 +1,104 @@ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + * + * from: @(#)pmap_prot.h 1.14 88/02/08 SMI + * from: @(#)pmap_prot.h 2.1 88/07/29 4.0 RPCSRC + * $FreeBSD: src/include/rpc/pmap_prot.h,v 1.10 1999/08/27 23:45:04 peter Exp $ + */ + +/* + * pmap_prot.h + * Protocol for the local binder service, or pmap. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * The following procedures are supported by the protocol: + * + * PMAPPROC_NULL() returns () + * takes nothing, returns nothing + * + * PMAPPROC_SET(struct pmap) returns (bool_t) + * TRUE is success, FALSE is failure. Registers the tuple + * [prog, vers, prot, port]. + * + * PMAPPROC_UNSET(struct pmap) returns (bool_t) + * TRUE is success, FALSE is failure. Un-registers pair + * [prog, vers]. prot and port are ignored. + * + * PMAPPROC_GETPORT(struct pmap) returns (long unsigned). + * 0 is failure. Otherwise returns the port number where the pair + * [prog, vers] is registered. It may lie! + * + * PMAPPROC_DUMP() RETURNS (struct pmaplist *) + * + * PMAPPROC_CALLIT(unsigned, unsigned, unsigned, string<>) + * RETURNS (port, string<>); + * usage: encapsulatedresults = PMAPPROC_CALLIT(prog, vers, proc, encapsulatedargs); + * Calls the procedure on the local machine. If it is not registered, + * this procedure is quite; ie it does not return error information!!! + * This procedure only is supported on rpc/udp and calls via + * rpc/udp. This routine only passes null authentication parameters. + * This file has no interface to xdr routines for PMAPPROC_CALLIT. + * + * The service supports remote procedure calls on udp/ip or tcp/ip socket 111. + */ + +#ifndef _RPC_PMAPPROT_H +#define _RPC_PMAPPROT_H +#include <sys/cdefs.h> + +#define PMAPPORT ((u_short)111) +#define PMAPPROG ((u_long)100000) +#define PMAPVERS ((u_long)2) +#define PMAPVERS_PROTO ((u_long)2) +#define PMAPVERS_ORIG ((u_long)1) +#define PMAPPROC_NULL ((u_long)0) +#define PMAPPROC_SET ((u_long)1) +#define PMAPPROC_UNSET ((u_long)2) +#define PMAPPROC_GETPORT ((u_long)3) +#define PMAPPROC_DUMP ((u_long)4) +#define PMAPPROC_CALLIT ((u_long)5) + +struct pmap { + long unsigned pm_prog; + long unsigned pm_vers; + long unsigned pm_prot; + long unsigned pm_port; +}; + +struct pmaplist { + struct pmap pml_map; + struct pmaplist *pml_next; +}; + +__BEGIN_DECLS +extern bool_t xdr_pmap __P((XDR *, struct pmap *)); +extern bool_t xdr_pmaplist __P((XDR *, struct pmaplist **)); +__END_DECLS + +#endif /* !_RPC_PMAPPROT_H */ diff --git a/cpukit/librpc/include/rpc/pmap_rmt.h b/cpukit/librpc/include/rpc/pmap_rmt.h index e69de29bb2..e632f8deca 100644 --- a/cpukit/librpc/include/rpc/pmap_rmt.h +++ b/cpukit/librpc/include/rpc/pmap_rmt.h @@ -0,0 +1,63 @@ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + * + * from: @(#)pmap_rmt.h 1.2 88/02/08 SMI + * from: @(#)pmap_rmt.h 2.1 88/07/29 4.0 RPCSRC + * $FreeBSD: src/include/rpc/pmap_rmt.h,v 1.10 1999/08/27 23:45:05 peter Exp $ + */ + +/* + * Structures and XDR routines for parameters to and replies from + * the portmapper remote-call-service. + * + * Copyright (C) 1986, Sun Microsystems, Inc. + */ + +#ifndef _RPC_PMAPRMT_H +#define _RPC_PMAPRMT_H +#include <sys/cdefs.h> + +struct rmtcallargs { + u_long prog, vers, proc, arglen; + caddr_t args_ptr; + xdrproc_t xdr_args; +}; + +struct rmtcallres { + u_long *port_ptr; + u_long resultslen; + caddr_t results_ptr; + xdrproc_t xdr_results; +}; + +__BEGIN_DECLS +extern bool_t xdr_rmtcall_args __P((XDR *, struct rmtcallargs *)); +extern bool_t xdr_rmtcallres __P((XDR *, struct rmtcallres *)); +__END_DECLS + +#endif /* !_RPC_PMAPRMT_H */ diff --git a/cpukit/librpc/include/rpc/rpc.h b/cpukit/librpc/include/rpc/rpc.h index 0a0affd82a..f68dc1be89 100644 --- a/cpukit/librpc/include/rpc/rpc.h +++ b/cpukit/librpc/include/rpc/rpc.h @@ -1,7 +1,3 @@ -#ifndef RPC_H -#define RPC_H - -/* @(#)rpc.h 2.4 89/07/11 4.0 RPCSRC; from 1.9 88/02/08 SMI */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape @@ -9,11 +5,11 @@ * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or * program developed by the user. - * + * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * + * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. @@ -29,6 +25,10 @@ * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 + * + * from: @(#)rpc.h 1.9 88/02/08 SMI + * from: @(#)rpc.h 2.4 89/07/11 4.0 RPCSRC + * $FreeBSD: src/include/rpc/rpc.h,v 1.12 2000/01/26 09:02:40 shin Exp $ */ /* @@ -37,12 +37,11 @@ * * Copyright (C) 1984, Sun Microsystems, Inc. */ -#ifndef __RPC_HEADER__ -#define __RPC_HEADER__ +#ifndef _RPC_RPC_H +#define _RPC_RPC_H #include <rpc/types.h> /* some typedefs */ #include <netinet/in.h> -#include <sys/socket.h> /* external data representation interfaces */ #include <rpc/xdr.h> /* generic (de)serializer */ @@ -55,12 +54,12 @@ /* semi-private protocol headers */ #include <rpc/rpc_msg.h> /* protocol for rpc messages */ -/*#include "auth_unix.h" * protocol for unix style cred */ +#include <rpc/auth_unix.h> /* protocol for unix style cred */ /* - * Uncomment-out the next line if you are building the rpc library with + * Uncomment-out the next line if you are building the rpc library with * DES Authentication (see the README file in the secure_rpc/ directory). */ -/*#include "auth_des.h" * protocol for des style cred */ +#include <rpc/auth_des.h> /* protocol for des style cred */ /* Server side only remote procedure callee */ #include <rpc/svc.h> /* service manager and multiplexer */ @@ -79,8 +78,60 @@ struct rpcent { int r_number; /* rpc program number */ }; -struct rpcent *getrpcbyname(), *getrpcbynumber(), *getrpcent(); +__BEGIN_DECLS +extern struct rpcent *getrpcbyname __P((char *)); +extern struct rpcent *getrpcbynumber __P((int)); +extern struct rpcent *getrpcent __P((void)); +extern int getrpcport __P((char *host, int prognum, int versnum, int proto)); +extern void setrpcent __P((int)); +extern void endrpcent __P((void)); + +extern int bindresvport __P((int, struct sockaddr_in *)); +extern int bindresvport_sa __P((int, struct sockaddr *)); +extern int get_myaddress __P((struct sockaddr_in *)); +__END_DECLS + +int rtems_rpc_task_init (void); +int rtems_rpc_start_portmapper (int priority); + +#ifdef _RTEMS_RPC_INTERNAL_ +/* + * Multi-threaded support + * Group all global and static variables into a single spot. + * This area will be allocated on a per-task basis + */ +struct rtems_rpc_task_variables { + int svc_svc_maxfd; + fd_set svc_svc_fdset; + void *svc_xports; + int svc_xportssize; + int svc__svc_fdsetsize; + void *svc__svc_fdset; + void *svc_svc_head; + + void *clnt_perror_buf; + + void *clnt_raw_private; + + void *call_rpc_private; + + void *svc_raw_private; + + void *svc_simple_proglst; + void *svc_simple_pl; + void *svc_simple_transp; + + void *rpcdname_default_domain; + + void *svc_auths_Auths; +}; +extern void *rtems_rpc_task_variables; + +#define svc_maxfd (((struct rtems_rpc_task_variables *)rtems_rpc_task_variables)->svc_svc_maxfd) +#define svc_fdset (((struct rtems_rpc_task_variables *)rtems_rpc_task_variables)->svc_svc_fdset) +#define __svc_fdsetsize (((struct rtems_rpc_task_variables *)rtems_rpc_task_variables)->svc__svc_fdsetsize) +#define __svc_fdset (fd_set *)(((struct rtems_rpc_task_variables *)rtems_rpc_task_variables)->svc__svc_fdset) -#endif /* ndef __RPC_HEADER__ */ +#endif /* _RTEMS_RPC_INTERNAL_ */ -#endif /* RPC_H */ +#endif /* !_RPC_RPC_H */ diff --git a/cpukit/librpc/include/rpc/rpc_com.h b/cpukit/librpc/include/rpc/rpc_com.h index e69de29bb2..2cf5995d2d 100644 --- a/cpukit/librpc/include/rpc/rpc_com.h +++ b/cpukit/librpc/include/rpc/rpc_com.h @@ -0,0 +1,78 @@ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +/* + * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc. + */ + +/* + * rpc_com.h, Common definitions for both the server and client side. + * All for the topmost layer of rpc + * + */ + +#ifndef _RPC_RPCCOM_H +#define _RPC_RPCCOM_H + +/* From: #pragma ident "@(#)rpc_com.h 1.11 93/07/05 SMI" */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * File descriptor to be used on xxx_create calls to get default descriptor + */ +#define RPC_ANYSOCK -1 +#define RPC_ANYFD RPC_ANYSOCK +/* + * The max size of the transport, if the size cannot be determined + * by other means. + */ +#define RPC_MAXDATASIZE 9000 +#define RPC_MAXADDRSIZE 1024 + +#if defined(__STDC__) || defined(__cplusplus) +extern u_int __rpc_get_t_size (int, long); +extern u_int __rpc_get_a_size (long); +extern int __rpc_dtbsize (void); +extern int _rpc_dtablesize (void); +extern int _rpc_get_default_domain(char **); +#else +extern u_int __rpc_get_t_size (); +extern u_int __rpc_get_a_size (); +extern int __rpc_dtbsize (); +extern int _rpc_dtablesize (); +extern int _rpc_get_default_domain(); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _RPC_RPCCOM_H */ diff --git a/cpukit/librpc/include/rpc/rpc_msg.h b/cpukit/librpc/include/rpc/rpc_msg.h index 2f34fb614c..bc5dc223fd 100644 --- a/cpukit/librpc/include/rpc/rpc_msg.h +++ b/cpukit/librpc/include/rpc/rpc_msg.h @@ -1,7 +1,3 @@ -#ifndef RPC_MSG_H -#define RPC_MSG_H - -/* @(#)rpc_msg.h 2.1 88/07/29 4.0 RPCSRC */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape @@ -9,28 +5,31 @@ * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or * program developed by the user. - * + * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * + * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. - * + * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. - * + * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. - * + * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 + * + * from: @(#)rpc_msg.h 1.7 86/07/16 SMI + * from: @(#)rpc_msg.h 2.1 88/07/29 4.0 RPCSRC + * $FreeBSD: src/include/rpc/rpc_msg.h,v 1.12 1999/08/27 23:45:05 peter Exp $ */ -/* @(#)rpc_msg.h 1.7 86/07/16 SMI */ /* * rpc_msg.h @@ -39,6 +38,9 @@ * Copyright (C) 1984, Sun Microsystems, Inc. */ +#ifndef _RPC_RPCMSG_H +#define _RPC_RPCMSG_H + #define RPC_MSG_VERSION ((u_long) 2) #define RPC_SERVICE_PORT ((u_short) 2048) @@ -86,8 +88,8 @@ struct accepted_reply { enum accept_stat ar_stat; union { struct { - u_long low; - u_long high; + u_int32_t low; + u_int32_t high; } AR_versions; struct { caddr_t where; @@ -106,8 +108,8 @@ struct rejected_reply { enum reject_stat rj_stat; union { struct { - u_long low; - u_long high; + u_int32_t low; + u_int32_t high; } RJ_versions; enum auth_stat RJ_why; /* why authentication did not work */ } ru; @@ -132,10 +134,10 @@ struct reply_body { * Body of an rpc request call. */ struct call_body { - u_long cb_rpcvers; /* must be equal to two */ - u_long cb_prog; - u_long cb_vers; - u_long cb_proc; + u_int32_t cb_rpcvers; /* must be equal to two */ + u_int32_t cb_prog; + u_int32_t cb_vers; + u_int32_t cb_proc; struct opaque_auth cb_cred; struct opaque_auth cb_verf; /* protocol specific - provided by client */ }; @@ -144,7 +146,7 @@ struct call_body { * The rpc message */ struct rpc_msg { - u_long rm_xid; + u_int32_t rm_xid; enum msg_type rm_direction; union { struct call_body RM_cmb; @@ -156,14 +158,14 @@ struct rpc_msg { #define acpted_rply ru.RM_rmb.ru.RP_ar #define rjcted_rply ru.RM_rmb.ru.RP_dr - +__BEGIN_DECLS /* * XDR routine to handle a rpc message. * xdr_callmsg(xdrs, cmsg) * XDR *xdrs; * struct rpc_msg *cmsg; */ -extern bool_t xdr_callmsg(); +extern bool_t xdr_callmsg __P((XDR *, struct rpc_msg *)); /* * XDR routine to pre-serialize the static part of a rpc message. @@ -171,7 +173,7 @@ extern bool_t xdr_callmsg(); * XDR *xdrs; * struct rpc_msg *cmsg; */ -extern bool_t xdr_callhdr(); +extern bool_t xdr_callhdr __P((XDR *, struct rpc_msg *)); /* * XDR routine to handle a rpc reply. @@ -179,7 +181,7 @@ extern bool_t xdr_callhdr(); * XDR *xdrs; * struct rpc_msg *rmsg; */ -extern bool_t xdr_replymsg(); +extern bool_t xdr_replymsg __P((XDR *, struct rpc_msg *)); /* * Fills in the error part of a reply message. @@ -187,6 +189,8 @@ extern bool_t xdr_replymsg(); * struct rpc_msg *msg; * struct rpc_err *error; */ -extern void _seterr_reply(); +struct rpc_err; +extern void _seterr_reply __P((struct rpc_msg *, struct rpc_err *)); +__END_DECLS -#endif /* RPC_MSG_H */ +#endif /* !_RPC_RPCMSG_H */ diff --git a/cpukit/librpc/include/rpc/svc.h b/cpukit/librpc/include/rpc/svc.h index c576b5538b..e57a7454be 100644 --- a/cpukit/librpc/include/rpc/svc.h +++ b/cpukit/librpc/include/rpc/svc.h @@ -1,8 +1,3 @@ - -#ifndef RPC_SVC_H -#define RPC_SVC_H - -/* @(#)svc.h 2.2 88/07/29 4.0 RPCSRC; from 1.20 88/02/08 SMI */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape @@ -10,26 +5,30 @@ * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or * program developed by the user. - * + * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * + * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. - * + * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. - * + * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. - * + * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 + * + * from: @(#)svc.h 1.20 88/02/08 SMI + * from: @(#)svc.h 2.2 88/07/29 4.0 RPCSRC + * $FreeBSD: src/include/rpc/svc.h,v 1.16 1999/12/29 05:00:43 peter Exp $ */ /* @@ -38,8 +37,9 @@ * Copyright (C) 1984, Sun Microsystems, Inc. */ -#ifndef __SVC_HEADER__ -#define __SVC_HEADER__ +#ifndef _RPC_SVC_H +#define _RPC_SVC_H +#include <sys/cdefs.h> /* * This interface must manage two items concerning remote procedure calling: @@ -69,19 +69,31 @@ enum xprt_stat { XPRT_IDLE }; +struct rpc_msg; + /* * Server side transport handle */ -typedef struct { +typedef struct __rpc_svcxprt { int xp_sock; u_short xp_port; /* associated port number */ struct xp_ops { - bool_t (*xp_recv)(); /* receive incomming requests */ - enum xprt_stat (*xp_stat)(); /* get transport status */ - bool_t (*xp_getargs)(); /* get arguments */ - bool_t (*xp_reply)(); /* send reply */ - bool_t (*xp_freeargs)();/* free mem allocated for args */ - void (*xp_destroy)(); /* destroy this struct */ + /* receive incoming requests */ + bool_t (*xp_recv) __P((struct __rpc_svcxprt *, + struct rpc_msg *)); + /* get transport status */ + enum xprt_stat (*xp_stat) __P((struct __rpc_svcxprt *)); + /* get arguments */ + bool_t (*xp_getargs) __P((struct __rpc_svcxprt *, xdrproc_t, + caddr_t)); + /* send reply */ + bool_t (*xp_reply) __P((struct __rpc_svcxprt *, + struct rpc_msg *)); + /* free mem allocated for args */ + bool_t (*xp_freeargs) __P((struct __rpc_svcxprt *, xdrproc_t, + caddr_t)); + /* destroy this struct */ + void (*xp_destroy) __P((struct __rpc_svcxprt *)); } *xp_ops; int xp_addrlen; /* length of remote address */ struct sockaddr_in xp_raddr; /* remote address */ @@ -138,9 +150,9 @@ typedef struct { * Service request */ struct svc_req { - u_long rq_prog; /* service program number */ - u_long rq_vers; /* service protocol version */ - u_long rq_proc; /* the desired procedure */ + u_int32_t rq_prog; /* service program number */ + u_int32_t rq_vers; /* service protocol version */ + u_int32_t rq_proc; /* the desired procedure */ struct opaque_auth rq_cred; /* raw creds from the wire */ caddr_t rq_clntcred; /* read only cooked cred */ SVCXPRT *rq_xprt; /* associated transport */ @@ -155,9 +167,12 @@ struct svc_req { * u_long prog; * u_long vers; * void (*dispatch)(); - * int protocol; (like TCP or UDP, zero means do not register) + * int protocol; (like TCP or UDP, zero means do not register) */ -extern bool_t svc_register(); +__BEGIN_DECLS +extern bool_t svc_register __P((SVCXPRT *, u_long, u_long, + void (*) __P((struct svc_req *, SVCXPRT *)), int)); +__END_DECLS /* * Service un-registration @@ -166,7 +181,9 @@ extern bool_t svc_register(); * u_long prog; * u_long vers; */ -extern void svc_unregister(); +__BEGIN_DECLS +extern void svc_unregister __P((u_long, u_long)); +__END_DECLS /* * Transport registration. @@ -174,7 +191,9 @@ extern void svc_unregister(); * xprt_register(xprt) * SVCXPRT *xprt; */ -extern void xprt_register(); +__BEGIN_DECLS +extern void xprt_register __P((SVCXPRT *)); +__END_DECLS /* * Transport un-register @@ -182,7 +201,9 @@ extern void xprt_register(); * xprt_unregister(xprt) * SVCXPRT *xprt; */ -extern void xprt_unregister(); +__BEGIN_DECLS +extern void xprt_unregister __P((SVCXPRT *)); +__END_DECLS @@ -190,7 +211,7 @@ extern void xprt_unregister(); /* * When the service routine is called, it must first check to see if it * knows about the procedure; if not, it should call svcerr_noproc - * and return. If so, it should deserialize its arguments via + * and return. If so, it should deserialize its arguments via * SVC_GETARGS (defined above). If the deserialization does not work, * svcerr_decode should be called followed by a return. Successful * decoding of the arguments should be followed the execution of the @@ -201,7 +222,7 @@ extern void xprt_unregister(); * Note: do not confuse access-control failure with weak authentication! * * NB: In pure implementations of rpc, the caller always waits for a reply - * msg. This message is sent when svc_sendreply is called. + * msg. This message is sent when svc_sendreply is called. * Therefore pure service implementations should always call * svc_sendreply even if the function logically returns void; use * xdr.h - xdr_void for the xdr routine. HOWEVER, tcp based rpc allows @@ -213,15 +234,17 @@ extern void xprt_unregister(); * deadlock the caller and server processes! */ -extern bool_t svc_sendreply(); -extern void svcerr_decode(); -extern void svcerr_weakauth(); -extern void svcerr_noproc(); -extern void svcerr_progvers(); -extern void svcerr_auth(); -extern void svcerr_noprog(); -extern void svcerr_systemerr(); - +__BEGIN_DECLS +extern bool_t svc_sendreply __P((SVCXPRT *, xdrproc_t, char *)); +extern void svcerr_decode __P((SVCXPRT *)); +extern void svcerr_weakauth __P((SVCXPRT *)); +extern void svcerr_noproc __P((SVCXPRT *)); +extern void svcerr_progvers __P((SVCXPRT *, u_long, u_long)); +extern void svcerr_auth __P((SVCXPRT *, enum auth_stat)); +extern void svcerr_noprog __P((SVCXPRT *)); +extern void svcerr_systemerr __P((SVCXPRT *)); +__END_DECLS + /* * Lowest level dispatching -OR- who owns this process anyway. * Somebody has to wait for incoming requests and then call the correct @@ -235,24 +258,26 @@ extern void svcerr_systemerr(); /* * Global keeper of rpc service descriptors in use - * dynamic; must be inspected before each call to select + * dynamic; must be inspected before each call to select */ -#ifdef FD_SETSIZE +extern int svc_maxfd; extern fd_set svc_fdset; #define svc_fds svc_fdset.fds_bits[0] /* compatibility */ -#else -extern int svc_fds; -#endif /* def FD_SETSIZE */ +#ifndef _KERNEL /* * a small program implemented by the svc_rpc implementation itself; * also see clnt.h for protocol numbers. */ extern void rpctest_service(); +#endif -extern void svc_getreq(); -extern void svc_getreqset(); /* takes fdset instead of int */ -extern void svc_run(); /* never returns */ +__BEGIN_DECLS +extern void svc_getreq __P((int)); +extern void svc_getreqset __P((fd_set *)); +extern void svc_getreqset2 __P((fd_set *, int)); /* XXX: nonstd, undoc */ +extern void svc_run __P((void)); +__END_DECLS /* * Socket to use on svcxxx_create call to get default socket @@ -266,26 +291,34 @@ extern void svc_run(); /* never returns */ /* * Memory based rpc for testing and timing. */ -extern SVCXPRT *svcraw_create(); +__BEGIN_DECLS +extern SVCXPRT *svcraw_create __P((void)); +__END_DECLS + /* * Udp based rpc. */ -extern SVCXPRT *svcudp_create(); -extern SVCXPRT *svcudp_bufcreate(); -extern int svcudp_enablecache(SVCXPRT *transp, u_long size); +__BEGIN_DECLS +extern SVCXPRT *svcudp_create __P((int)); +extern SVCXPRT *svcudp_bufcreate __P((int, u_int, u_int)); +__END_DECLS + /* * Tcp based rpc. */ -extern SVCXPRT *svctcp_create(); - +__BEGIN_DECLS +extern SVCXPRT *svctcp_create __P((int, u_int, u_int)); +extern SVCXPRT *svcfd_create __P((int, u_int, u_int)); +__END_DECLS +/* + * AF_UNIX socket based rpc. + */ +__BEGIN_DECLS +extern SVCXPRT *svcunix_create __P((int, u_int, u_int, char *)); +extern SVCXPRT *svcunixfd_create __P((int, u_int, u_int)); +__END_DECLS -#endif /* !__SVC_HEADER__ */ - -extern int _rpcsvccount; -extern int _rpcsvcstate; -extern int _SERVED; - -#endif /* RPC_SVC_H */ +#endif /* !_RPC_SVC_H */ diff --git a/cpukit/librpc/include/rpc/svc_auth.h b/cpukit/librpc/include/rpc/svc_auth.h index 5c233a6a47..a203d8cbeb 100644 --- a/cpukit/librpc/include/rpc/svc_auth.h +++ b/cpukit/librpc/include/rpc/svc_auth.h @@ -1,7 +1,3 @@ -#ifndef RPC_SVC_AUTH_H -#define RPC_SVC_AUTH_H - -/* @(#)svc_auth.h 2.1 88/07/29 4.0 RPCSRC */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape @@ -9,39 +5,52 @@ * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or * program developed by the user. - * + * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * + * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. - * + * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. - * + * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. - * + * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 + * + * from: @(#)svc_auth.h 1.6 86/07/16 SMI + * from: @(#)svc_auth.h 2.1 88/07/29 4.0 RPCSRC + * $FreeBSD: src/include/rpc/svc_auth.h,v 1.12 1999/08/27 23:45:05 peter Exp $ */ -/* @(#)svc_auth.h 1.6 86/07/16 SMI */ /* * svc_auth.h, Service side of rpc authentication. - * + * * Copyright (C) 1984, Sun Microsystems, Inc. */ +#ifndef _RPC_SVCAUTH_H +#define _RPC_SVCAUTH_H + +struct rpc_msg; +struct svc_req; /* * Server side authenticator */ -extern enum auth_stat _authenticate(); +__BEGIN_DECLS +extern enum auth_stat _authenticate __P((struct svc_req *, struct rpc_msg *)); +extern int svc_auth_reg __P((int, enum auth_stat (*)(struct svc_req *, + struct rpc_msg *))); +extern enum auth_stat _svcauth_des __P((struct svc_req *, struct rpc_msg *)); +__END_DECLS -#endif /* SVC_AUTH_H */ +#endif /* !_RPC_SVCAUTH_H */ diff --git a/cpukit/librpc/include/rpc/types.h b/cpukit/librpc/include/rpc/types.h index b6d7eb3ccc..c907674c51 100644 --- a/cpukit/librpc/include/rpc/types.h +++ b/cpukit/librpc/include/rpc/types.h @@ -1,7 +1,3 @@ -#ifndef RPC_TYPES_H -#define RPC_TYPES_H - -/* @(#)types.h 2.3 88/08/15 4.0 RPCSRC */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape @@ -9,52 +5,52 @@ * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or * program developed by the user. - * + * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * + * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. - * + * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. - * + * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. - * + * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 + * + * from: @(#)types.h 1.18 87/07/24 SMI + * from: @(#)types.h 2.3 88/08/15 4.0 RPCSRC + * $FreeBSD: src/include/rpc/types.h,v 1.9 1999/08/27 23:45:06 peter Exp $ */ -/* @(#)types.h 1.18 87/07/24 SMI */ /* * Rpc additions to <sys/types.h> */ -#ifndef __TYPES_RPC_HEADER__ -#define __TYPES_RPC_HEADER__ +#ifndef _RPC_TYPES_H +#define _RPC_TYPES_H -/*#include <network/types.h>*/ -typedef unsigned long u_int32; /* 32-bit unsigned integers */ +#define bool_t int32_t +#define enum_t int32_t +#define __dontcare__ -1 -#define bool_t int -#define enum_t int #ifndef FALSE -# define FALSE (0) +# define FALSE (0) #endif #ifndef TRUE -# define TRUE (1) +# define TRUE (1) #endif -#define __dontcare__ -1 #ifndef NULL -# define NULL 0 +# define NULL 0 #endif -void *malloc(); #define mem_alloc(bsize) malloc(bsize) #define mem_free(ptr, bsize) free(ptr) @@ -63,13 +59,4 @@ void *malloc(); #endif #include <sys/time.h> -#ifndef INADDR_LOOPBACK -#define INADDR_LOOPBACK (u_long)0x7F000001 -#endif -#ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN 64 -#endif - -#endif /* ndef __TYPES_RPC_HEADER__ */ - -#endif /* RPC_TYPES_H */ +#endif /* !_RPC_TYPES_H */ diff --git a/cpukit/librpc/include/rpc/xdr.h b/cpukit/librpc/include/rpc/xdr.h index ef2df51d93..460a1da5fb 100644 --- a/cpukit/librpc/include/rpc/xdr.h +++ b/cpukit/librpc/include/rpc/xdr.h @@ -1,7 +1,3 @@ -#ifndef RPC_XDR_H -#define RPC_XDR_H - -/* @(#)xdr.h 2.2 88/07/29 4.0 RPCSRC */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape @@ -9,28 +5,31 @@ * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or * program developed by the user. - * + * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * + * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. - * + * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. - * + * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. - * + * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 + * + * from: @(#)xdr.h 1.19 87/04/22 SMI + * from: @(#)xdr.h 2.2 88/07/29 4.0 RPCSRC + * $FreeBSD: src/include/rpc/xdr.h,v 1.14 1999/12/29 05:00:44 peter Exp $ */ -/* @(#)xdr.h 1.19 87/04/22 SMI */ /* * xdr.h, External Data Representation Serialization Routines. @@ -38,8 +37,9 @@ * Copyright (C) 1984, Sun Microsystems, Inc. */ -#ifndef __XDR_HEADER__ -#define __XDR_HEADER__ +#ifndef _RPC_XDR_H +#define _RPC_XDR_H +#include <sys/cdefs.h> /* * XDR provides a conventional way for converting between C data @@ -90,33 +90,30 @@ enum xdr_op { * BYTES_PER_XDR_UNIT) /* - * A xdrproc_t exists for each data type which is to be encoded or decoded. - * - * The second argument to the xdrproc_t is a pointer to an opaque pointer. - * The opaque pointer generally points to a structure of the data type - * to be decoded. If this pointer is 0, then the type routines should - * allocate dynamic storage of the appropriate size and return it. - * bool_t (*xdrproc_t)(XDR *, caddr_t *); - */ -typedef bool_t (*xdrproc_t)(); - -/* * The XDR handle. * Contains operation which is being applied to the stream, - * an operations vector for the paticular implementation (e.g. see xdr_mem.c), - * and two private fields for the use of the particular impelementation. + * an operations vector for the particular implementation (e.g. see xdr_mem.c), + * and two private fields for the use of the particular implementation. */ -typedef struct { +typedef struct __rpc_xdr { enum xdr_op x_op; /* operation; fast additional param */ struct xdr_ops { - bool_t (*x_getlong)(); /* get a long from underlying stream */ - bool_t (*x_putlong)(); /* put a long to " */ - bool_t (*x_getbytes)();/* get some bytes from " */ - bool_t (*x_putbytes)();/* put some bytes to " */ - u_int (*x_getpostn)();/* returns bytes off from beginning */ - bool_t (*x_setpostn)();/* lets you reposition the stream */ - long * (*x_inline)(); /* buf quick ptr to buffered data */ - void (*x_destroy)(); /* free privates of this xdr_stream */ + /* get a long from underlying stream */ + bool_t (*x_getlong) __P((struct __rpc_xdr *, long *)); + /* put a long to underlying stream */ + bool_t (*x_putlong) __P((struct __rpc_xdr *, long *)); + /* get some bytes from underlying stream */ + bool_t (*x_getbytes) __P((struct __rpc_xdr *, caddr_t, u_int)); + /* put some bytes to underlying stream */ + bool_t (*x_putbytes) __P((struct __rpc_xdr *, caddr_t, u_int)); + /* returns bytes off from beginning */ + u_int (*x_getpostn) __P((struct __rpc_xdr *)); + /* lets you reposition the stream */ + bool_t (*x_setpostn) __P((struct __rpc_xdr *, u_int)); + /* buf quick ptr to buffered data */ + int32_t *(*x_inline) __P((struct __rpc_xdr *, u_int)); + /* free privates of this xdr_stream */ + void (*x_destroy) __P((struct __rpc_xdr *)); } *x_ops; caddr_t x_public; /* users' data */ caddr_t x_private; /* pointer to private data */ @@ -125,6 +122,23 @@ typedef struct { } XDR; /* + * A xdrproc_t exists for each data type which is to be encoded or decoded. + * + * The second argument to the xdrproc_t is a pointer to an opaque pointer. + * The opaque pointer generally points to a structure of the data type + * to be decoded. If this pointer is 0, then the type routines should + * allocate dynamic storage of the appropriate size and return it. + */ +#ifdef _KERNEL +typedef bool_t (*xdrproc_t) __P((XDR *, void *, u_int)); +#else +/* + * XXX can't actually prototype it, because some take two args!!! + */ +typedef bool_t (*xdrproc_t) __P((/* XDR *, void *, u_int */)); +#endif + +/* * Operations defined on a XDR handle * * XDR *xdrs; @@ -192,7 +206,7 @@ struct xdr_discrim { }; /* - * In-line routines for fast encode/decode of primitve data types. + * In-line routines for fast encode/decode of primitive data types. * Caveat emptor: these use single memory cycles to get the * data from the underlying buffer, and will fail to operate * properly if the data is not aligned. The standard way to use these @@ -224,52 +238,77 @@ struct xdr_discrim { /* * These are the "generic" xdr routines. */ -extern bool_t xdr_void(); -extern bool_t xdr_int(); -extern bool_t xdr_u_int(); -extern bool_t xdr_long(); -extern bool_t xdr_u_long(); -extern bool_t xdr_short(); -extern bool_t xdr_u_short(); -extern bool_t xdr_bool(); -extern bool_t xdr_enum(); -extern bool_t xdr_array(); -extern bool_t xdr_bytes(); -extern bool_t xdr_opaque(); -extern bool_t xdr_string(); -extern bool_t xdr_union(); -extern bool_t xdr_char(); -extern bool_t xdr_u_char(); -extern bool_t xdr_vector(); -extern bool_t xdr_float(); -extern bool_t xdr_double(); -extern bool_t xdr_reference(); -extern bool_t xdr_pointer(); -extern bool_t xdr_wrapstring(); +__BEGIN_DECLS +extern bool_t xdr_void __P((void)); +extern bool_t xdr_int __P((XDR *, int *)); +extern bool_t xdr_u_int __P((XDR *, u_int *)); +extern bool_t xdr_long __P((XDR *, long *)); +extern bool_t xdr_u_long __P((XDR *, u_long *)); +extern bool_t xdr_short __P((XDR *, short *)); +extern bool_t xdr_u_short __P((XDR *, u_short *)); +extern bool_t xdr_int16_t __P((XDR *, int16_t *)); +extern bool_t xdr_u_int16_t __P((XDR *, u_int16_t *)); +extern bool_t xdr_int32_t __P((XDR *, int32_t *)); +extern bool_t xdr_u_int32_t __P((XDR *, u_int32_t *)); +extern bool_t xdr_int64_t __P((XDR *, int64_t *)); +extern bool_t xdr_u_int64_t __P((XDR *, u_int64_t *)); +extern bool_t xdr_bool __P((XDR *, bool_t *)); +extern bool_t xdr_enum __P((XDR *, enum_t *)); +extern bool_t xdr_array __P((XDR *, char **, u_int *, u_int, u_int, xdrproc_t)); +extern bool_t xdr_bytes __P((XDR *, char **, u_int *, u_int)); +extern bool_t xdr_opaque __P((XDR *, caddr_t, u_int)); +extern bool_t xdr_string __P((XDR *, char **, u_int)); +extern bool_t xdr_union __P((XDR *, enum_t *, char *, struct xdr_discrim *, xdrproc_t)); +extern unsigned long xdr_sizeof __P((xdrproc_t, void *)); +extern bool_t xdr_char __P((XDR *, char *)); +extern bool_t xdr_u_char __P((XDR *, u_char *)); +extern bool_t xdr_vector __P((XDR *, char *, u_int, u_int, xdrproc_t)); +extern bool_t xdr_float __P((XDR *, float *)); +extern bool_t xdr_double __P((XDR *, double *)); +extern bool_t xdr_reference __P((XDR *, caddr_t *, u_int, xdrproc_t)); +extern bool_t xdr_pointer __P((XDR *, caddr_t *, u_int, xdrproc_t)); +extern bool_t xdr_wrapstring __P((XDR *, char **)); +extern void xdr_free __P((xdrproc_t, char *)); +__END_DECLS /* * Common opaque bytes objects used by many rpc protocols; * declared here due to commonality. */ -#define MAX_NETOBJ_SZ 1024 +#define MAX_NETOBJ_SZ 1024 struct netobj { u_int n_len; char *n_bytes; }; typedef struct netobj netobj; -extern bool_t xdr_netobj(); +extern bool_t xdr_netobj __P((XDR *, struct netobj *)); /* * These are the public routines for the various implementations of * xdr streams. */ -extern void xdrmem_create(); /* XDR using memory buffers */ -extern void xdrstdio_create(); /* XDR using stdio library */ -extern void xdrrec_create(); /* XDR pseudo records for tcp */ -extern bool_t xdrrec_endofrecord(); /* make end of xdr record */ -extern bool_t xdrrec_skiprecord(); /* move to beginning of next record */ -extern bool_t xdrrec_eof(); /* true if no more input */ +__BEGIN_DECLS +/* XDR using memory buffers */ +extern void xdrmem_create __P((XDR *, char *, u_int, enum xdr_op)); + +#ifdef _STDIO_H_ +/* XDR using stdio library */ +extern void xdrstdio_create __P((XDR *, FILE *, enum xdr_op)); +#endif + +/* XDR pseudo records for tcp */ +extern void xdrrec_create __P((XDR *, u_int, u_int, char *, + int (*) __P((caddr_t, caddr_t, int)), + int (*) __P((caddr_t, caddr_t, int)))); + +/* make end of xdr record */ +extern bool_t xdrrec_endofrecord __P((XDR *, int)); + +/* move to beginning of next record */ +extern bool_t xdrrec_skiprecord __P((XDR *)); -#endif /* !__XDR_HEADER__ */ +/* true if no more input */ +extern bool_t xdrrec_eof __P((XDR *)); +__END_DECLS -#endif /* RPC_XDR_H */ +#endif /* !_RPC_XDR_H */ diff --git a/cpukit/librpc/include/rpcsvc/.cvsignore b/cpukit/librpc/include/rpcsvc/.cvsignore index e69de29bb2..282522db03 100644 --- a/cpukit/librpc/include/rpcsvc/.cvsignore +++ b/cpukit/librpc/include/rpcsvc/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/cpukit/librpc/include/rpcsvc/Makefile.am b/cpukit/librpc/include/rpcsvc/Makefile.am index e69de29bb2..c5de0f9e6f 100644 --- a/cpukit/librpc/include/rpcsvc/Makefile.am +++ b/cpukit/librpc/include/rpcsvc/Makefile.am @@ -0,0 +1,13 @@ +## $Id$ + +AUTOMAKE_OPTIONS = foreign 1.4 + +## Currently unused + +EXTRA_DIST = bootparam_prot.x crypt.x key_prot.x klm_prot.x mount.x \ + nfs_prot.x nis.x nis_cache.x nis_callback.x nis_db.h nis_object.x \ + nis_tags.h nislib.h nlm_prot.x pmap_prot.x rex.x rnusers.x rquota.x \ + rstat.x rwall.x sm_inter.x spray.x yp.x yp_prot.h ypclnt.h yppasswd.x \ + ypupdate_prot.x ypxfrd.x + +include $(top_srcdir)/../../../automake/local.am diff --git a/cpukit/librpc/include/rpcsvc/bootparam_prot.x b/cpukit/librpc/include/rpcsvc/bootparam_prot.x index e69de29bb2..0f74c8f8ad 100644 --- a/cpukit/librpc/include/rpcsvc/bootparam_prot.x +++ b/cpukit/librpc/include/rpcsvc/bootparam_prot.x @@ -0,0 +1,103 @@ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * RPC for bootparms service. + * There are two procedures: + * WHOAMI takes a net address and returns a client name and also a + * likely net address for routing + * GETFILE takes a client name and file identifier and returns the + * server name, server net address and pathname for the file. + * file identifiers typically include root, swap, pub and dump + */ + +#ifdef RPC_HDR +%#include <rpc/types.h> +%#include <sys/time.h> +%#include <sys/errno.h> +%#include <sys/param.h> +%#include <sys/syslimits.h> +%#include <sys/ucred.h> +#else +%#ifndef lint +%/*static char sccsid[] = "from: @(#)bootparam_prot.x 1.2 87/06/24 Copyr 1987 Sun Micro";*/ +%/*static char sccsid[] = "from: @(#)bootparam_prot.x 2.1 88/08/01 4.0 RPCSRC";*/ +%static const char rcsid[] = +% "$FreeBSD: src/include/rpcsvc/bootparam_prot.x,v 1.5 1999/08/27 23:45:07 peter Exp $"; +%#endif /* not lint */ +#endif + +const MAX_MACHINE_NAME = 255; +const MAX_PATH_LEN = 1024; +const MAX_FILEID = 32; +const IP_ADDR_TYPE = 1; + +typedef string bp_machine_name_t<MAX_MACHINE_NAME>; +typedef string bp_path_t<MAX_PATH_LEN>; +typedef string bp_fileid_t<MAX_FILEID>; + +struct ip_addr_t { + char net; + char host; + char lh; + char impno; +}; + +union bp_address switch (int address_type) { + case IP_ADDR_TYPE: + ip_addr_t ip_addr; +}; + +struct bp_whoami_arg { + bp_address client_address; +}; + +struct bp_whoami_res { + bp_machine_name_t client_name; + bp_machine_name_t domain_name; + bp_address router_address; +}; + +struct bp_getfile_arg { + bp_machine_name_t client_name; + bp_fileid_t file_id; +}; + +struct bp_getfile_res { + bp_machine_name_t server_name; + bp_address server_address; + bp_path_t server_path; +}; + +program BOOTPARAMPROG { + version BOOTPARAMVERS { + bp_whoami_res BOOTPARAMPROC_WHOAMI(bp_whoami_arg) = 1; + bp_getfile_res BOOTPARAMPROC_GETFILE(bp_getfile_arg) = 2; + } = 1; +} = 100026; diff --git a/cpukit/librpc/include/rpcsvc/crypt.x b/cpukit/librpc/include/rpcsvc/crypt.x index e69de29bb2..8df1654440 100644 --- a/cpukit/librpc/include/rpcsvc/crypt.x +++ b/cpukit/librpc/include/rpcsvc/crypt.x @@ -0,0 +1,91 @@ +/* + * Copyright (c) 1996 + * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Bill Paul. + * 4. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/include/rpcsvc/crypt.x,v 1.3 1999/08/27 23:45:08 peter Exp $ + */ + +#ifndef RPC_HDR +%#ifndef lint +%static const char rcsid[] = +% "$FreeBSD: src/include/rpcsvc/crypt.x,v 1.3 1999/08/27 23:45:08 peter Exp $"; +%#endif +#endif + +/* + * This protocol definition exists because of the U.S. government and + * its stupid export laws. We can't export DES code from the United + * States to other countries (even though the code already exists + * outside the U.S. -- go figure that one out) but we need to make + * Secure RPC work. The normal way around this is to break the DES + * code out into a shared library; we can then provide a dummy lib + * in the base OS and provide the real lib in the secure dist, which + * the user can install later. But we need Secure RPC for NIS+, and + * there are several system programs that use NIS+ which are statically + * linked. We would have to provide replacements for these programs + * in the secure dist, but there are a lot, and this is a pain. The + * shared lib trick won't work for these programs, and we can't change + * them once they're compiled. + * + * One solution for this problem is to do the DES encryption as a system + * call; no programs need to be changed and we can even supply the DES + * support as an LKM. But this bloats the kernel. Maybe if we have + * Secure NFS one day this will be worth it, but for now we should keep + * this mess in user space. + * + * So we have this second solution: we provide a server that does the + * DES encryption for us. In this case, the server is keyserv (we need + * it to make Secure RPC work anyway) and we use this protocol to ship + * the data back and forth between keyserv and the application. + */ + +enum des_dir { ENCRYPT_DES, DECRYPT_DES }; +enum des_mode { CBC_DES, ECB_DES }; + +struct desargs { + u_char des_key[8]; /* key (with low bit parity) */ + des_dir des_dir; /* direction */ + des_mode des_mode; /* mode */ + u_char des_ivec[8]; /* input vector */ + opaque desbuf<>; +}; + +struct desresp { + opaque desbuf<>; + u_char des_ivec[8]; + int stat; +}; + +program CRYPT_PROG { + version CRYPT_VERS { + desresp + DES_CRYPT(desargs) = 1; + } = 1; +} = 600100029; diff --git a/cpukit/librpc/include/rpcsvc/key_prot.x b/cpukit/librpc/include/rpcsvc/key_prot.x index e69de29bb2..ab3196cfc0 100644 --- a/cpukit/librpc/include/rpcsvc/key_prot.x +++ b/cpukit/librpc/include/rpcsvc/key_prot.x @@ -0,0 +1,284 @@ +%/* +% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for +% * unrestricted use provided that this legend is included on all tape +% * media and as a part of the software program in whole or part. Users +% * may copy or modify Sun RPC without charge, but are not authorized +% * to license or distribute it to anyone else except as part of a product or +% * program developed by the user. +% * +% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE +% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR +% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. +% * +% * Sun RPC is provided with no support and without any obligation on the +% * part of Sun Microsystems, Inc. to assist in its use, correction, +% * modification or enhancement. +% * +% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE +% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC +% * OR ANY PART THEREOF. +% * +% * In no event will Sun Microsystems, Inc. be liable for any lost revenue +% * or profits or other special, indirect and consequential damages, even if +% * Sun has been advised of the possibility of such damages. +% * +% * Sun Microsystems, Inc. +% * 2550 Garcia Avenue +% * Mountain View, California 94043 +% */ +/* + * Key server protocol definition + * Copyright (C) 1990, 1991 Sun Microsystems, Inc. + * + * The keyserver is a public key storage/encryption/decryption service + * The encryption method used is based on the Diffie-Hellman exponential + * key exchange technology. + * + * The key server is local to each machine, akin to the portmapper. + * Under TI-RPC, communication with the keyserver is through the + * loopback transport. + * + * NOTE: This .x file generates the USER level headers for the keyserver. + * the KERNEL level headers are created by hand as they kernel has special + * requirements. + */ + +%/* From: #pragma ident "@(#)key_prot.x 1.7 94/04/29 SMI" */ +% +%/* Copyright (c) 1990, 1991 Sun Microsystems, Inc. */ +% +%/* +% * Compiled from key_prot.x using rpcgen. +% * DO NOT EDIT THIS FILE! +% * This is NOT source code! +% */ + +/* + * PROOT and MODULUS define the way the Diffie-Hellman key is generated. + * + * MODULUS should be chosen as a prime of the form: MODULUS == 2*p + 1, + * where p is also prime. + * + * PROOT satisfies the following two conditions: + * (1) (PROOT ** 2) % MODULUS != 1 + * (2) (PROOT ** p) % MODULUS != 1 + * + */ + +const PROOT = 3; +const HEXMODULUS = "d4a0ba0250b6fd2ec626e7efd637df76c716e22d0944b88b"; + +const HEXKEYBYTES = 48; /* HEXKEYBYTES == strlen(HEXMODULUS) */ +const KEYSIZE = 192; /* KEYSIZE == bit length of key */ +const KEYBYTES = 24; /* byte length of key */ + +/* + * The first 16 hex digits of the encrypted secret key are used as + * a checksum in the database. + */ +const KEYCHECKSUMSIZE = 16; + +/* + * status of operation + */ +enum keystatus { + KEY_SUCCESS, /* no problems */ + KEY_NOSECRET, /* no secret key stored */ + KEY_UNKNOWN, /* unknown netname */ + KEY_SYSTEMERR /* system error (out of memory, encryption failure) */ +}; + +typedef opaque keybuf[HEXKEYBYTES]; /* store key in hex */ + +typedef string netnamestr<MAXNETNAMELEN>; + +/* + * Argument to ENCRYPT or DECRYPT + */ +struct cryptkeyarg { + netnamestr remotename; + des_block deskey; +}; + +/* + * Argument to ENCRYPT_PK or DECRYPT_PK + */ +struct cryptkeyarg2 { + netnamestr remotename; + netobj remotekey; /* Contains a length up to 1024 bytes */ + des_block deskey; +}; + + +/* + * Result of ENCRYPT, DECRYPT, ENCRYPT_PK, and DECRYPT_PK + */ +union cryptkeyres switch (keystatus status) { +case KEY_SUCCESS: + des_block deskey; +default: + void; +}; + +const MAXGIDS = 16; /* max number of gids in gid list */ + +/* + * Unix credential + */ +struct unixcred { + u_int uid; + u_int gid; + u_int gids<MAXGIDS>; +}; + +/* + * Result returned from GETCRED + */ +union getcredres switch (keystatus status) { +case KEY_SUCCESS: + unixcred cred; +default: + void; +}; +/* + * key_netstarg; + */ + +struct key_netstarg { + keybuf st_priv_key; + keybuf st_pub_key; + netnamestr st_netname; +}; + +union key_netstres switch (keystatus status){ +case KEY_SUCCESS: + key_netstarg knet; +default: + void; +}; + +#ifdef RPC_HDR +% +%#ifndef opaque +%#define opaque char +%#endif +% +#endif +program KEY_PROG { + version KEY_VERS { + + /* + * This is my secret key. + * Store it for me. + */ + keystatus + KEY_SET(keybuf) = 1; + + /* + * I want to talk to X. + * Encrypt a conversation key for me. + */ + cryptkeyres + KEY_ENCRYPT(cryptkeyarg) = 2; + + /* + * X just sent me a message. + * Decrypt the conversation key for me. + */ + cryptkeyres + KEY_DECRYPT(cryptkeyarg) = 3; + + /* + * Generate a secure conversation key for me + */ + des_block + KEY_GEN(void) = 4; + + /* + * Get me the uid, gid and group-access-list associated + * with this netname (for kernel which cannot use NIS) + */ + getcredres + KEY_GETCRED(netnamestr) = 5; + } = 1; + version KEY_VERS2 { + + /* + * ####### + * Procedures 1-5 are identical to version 1 + * ####### + */ + + /* + * This is my secret key. + * Store it for me. + */ + keystatus + KEY_SET(keybuf) = 1; + + /* + * I want to talk to X. + * Encrypt a conversation key for me. + */ + cryptkeyres + KEY_ENCRYPT(cryptkeyarg) = 2; + + /* + * X just sent me a message. + * Decrypt the conversation key for me. + */ + cryptkeyres + KEY_DECRYPT(cryptkeyarg) = 3; + + /* + * Generate a secure conversation key for me + */ + des_block + KEY_GEN(void) = 4; + + /* + * Get me the uid, gid and group-access-list associated + * with this netname (for kernel which cannot use NIS) + */ + getcredres + KEY_GETCRED(netnamestr) = 5; + + /* + * I want to talk to X. and I know X's public key + * Encrypt a conversation key for me. + */ + cryptkeyres + KEY_ENCRYPT_PK(cryptkeyarg2) = 6; + + /* + * X just sent me a message. and I know X's public key + * Decrypt the conversation key for me. + */ + cryptkeyres + KEY_DECRYPT_PK(cryptkeyarg2) = 7; + + /* + * Store my public key, netname and private key. + */ + keystatus + KEY_NET_PUT(key_netstarg) = 8; + + /* + * Retrieve my public key, netname and private key. + */ + key_netstres + KEY_NET_GET(void) = 9; + + /* + * Return me the conversation key that is constructed + * from my secret key and this publickey. + */ + + cryptkeyres + KEY_GET_CONV(keybuf) = 10; + + + } = 2; +} = 100029; + + diff --git a/cpukit/librpc/include/rpcsvc/klm_prot.x b/cpukit/librpc/include/rpcsvc/klm_prot.x index e69de29bb2..c4cfe36d42 100644 --- a/cpukit/librpc/include/rpcsvc/klm_prot.x +++ b/cpukit/librpc/include/rpcsvc/klm_prot.x @@ -0,0 +1,139 @@ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * Kernel/lock manager protocol definition + * Copyright (C) 1986 Sun Microsystems, Inc. + * + * protocol used between the UNIX kernel (the "client") and the + * local lock manager. The local lock manager is a deamon running + * above the kernel. + */ + +#ifndef RPC_HDR +%#ifndef lint +%/*static char sccsid[] = "from: @(#)klm_prot.x 1.7 87/07/08 Copyr 1987 Sun Micro";*/ +%/*static char sccsid[] = "from: @(#)klm_prot.x 2.1 88/08/01 4.0 RPCSRC";*/ +%static const char rcsid[] = +% "$FreeBSD: src/include/rpcsvc/klm_prot.x,v 1.6 1999/08/27 23:45:08 peter Exp $"; +%#endif /* not lint */ +#endif + +const LM_MAXSTRLEN = 1024; + +/* + * lock manager status returns + */ +enum klm_stats { + klm_granted = 0, /* lock is granted */ + klm_denied = 1, /* lock is denied */ + klm_denied_nolocks = 2, /* no lock entry available */ + klm_working = 3 /* lock is being processed */ +}; + +/* + * lock manager lock identifier + */ +struct klm_lock { + string server_name<LM_MAXSTRLEN>; + netobj fh; /* a counted file handle */ + int pid; /* holder of the lock */ + unsigned l_offset; /* beginning offset of the lock */ + unsigned l_len; /* byte length of the lock; + * zero means through end of file */ +}; + +/* + * lock holder identifier + */ +struct klm_holder { + bool exclusive; /* FALSE if shared lock */ + int svid; /* holder of the lock (pid) */ + unsigned l_offset; /* beginning offset of the lock */ + unsigned l_len; /* byte length of the lock; + * zero means through end of file */ +}; + +/* + * reply to KLM_LOCK / KLM_UNLOCK / KLM_CANCEL + */ +struct klm_stat { + klm_stats stat; +}; + +/* + * reply to a KLM_TEST call + */ +union klm_testrply switch (klm_stats stat) { + case klm_denied: + struct klm_holder holder; + default: /* All other cases return no arguments */ + void; +}; + + +/* + * arguments to KLM_LOCK + */ +struct klm_lockargs { + bool block; + bool exclusive; + struct klm_lock alock; +}; + +/* + * arguments to KLM_TEST + */ +struct klm_testargs { + bool exclusive; + struct klm_lock alock; +}; + +/* + * arguments to KLM_UNLOCK + */ +struct klm_unlockargs { + struct klm_lock alock; +}; + +program KLM_PROG { + version KLM_VERS { + + klm_testrply KLM_TEST (struct klm_testargs) = 1; + + klm_stat KLM_LOCK (struct klm_lockargs) = 2; + + klm_stat KLM_CANCEL (struct klm_lockargs) = 3; + /* klm_granted=> the cancel request fails due to lock is already granted */ + /* klm_denied=> the cancel request successfully aborts +lock request */ + + klm_stat KLM_UNLOCK (struct klm_unlockargs) = 4; + } = 1; +} = 100020; diff --git a/cpukit/librpc/include/rpcsvc/mount.x b/cpukit/librpc/include/rpcsvc/mount.x index e69de29bb2..f68a06fe9b 100644 --- a/cpukit/librpc/include/rpcsvc/mount.x +++ b/cpukit/librpc/include/rpcsvc/mount.x @@ -0,0 +1,257 @@ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * Protocol description for the mount program + */ + +#ifndef RPC_HDR +%#ifndef lint +%/*static char sccsid[] = "from: @(#)mount.x 1.2 87/09/18 Copyr 1987 Sun Micro";*/ +%/*static char sccsid[] = "from: @(#)mount.x 2.1 88/08/01 4.0 RPCSRC";*/ +%static const char rcsid[] = +% "$FreeBSD: src/include/rpcsvc/mount.x,v 1.6 1999/08/27 23:45:08 peter Exp $"; +%#endif /* not lint */ +#endif + +const MNTPATHLEN = 1024; /* maximum bytes in a pathname argument */ +const MNTNAMLEN = 255; /* maximum bytes in a name argument */ +const FHSIZE = 32; /* size in bytes of a file handle */ +#ifdef WANT_NFS3 +const FHSIZE3 = 64; /* size in bytes of a file handle (v3) */ +#endif + +/* + * The fhandle is the file handle that the server passes to the client. + * All file operations are done using the file handles to refer to a file + * or a directory. The file handle can contain whatever information the + * server needs to distinguish an individual file. + */ +typedef opaque fhandle[FHSIZE]; +#ifdef WANT_NFS3 +typedef opaque fhandle3<FHSIZE3>; +#endif + +/* + * If a status of zero is returned, the call completed successfully, and + * a file handle for the directory follows. A non-zero status indicates + * some sort of error. The status corresponds with UNIX error numbers. + */ +union fhstatus switch (unsigned fhs_status) { +case 0: + fhandle fhs_fhandle; +default: + void; +}; + +#ifdef WANT_NFS3 +/* + * Status codes returned by the version 3 mount call. + */ +enum mountstat3 { + MNT3_OK = 0, /* no error */ + MNT3ERR_PERM = 1, /* Not owner */ + MNT3ERR_NOENT = 2, /* No such file or directory */ + MNT3ERR_IO = 5, /* I/O error */ + MNT3ERR_ACCES = 13, /* Permission denied */ + MNT3ERR_NOTDIR = 20, /* Not a directory */ + MNT3ERR_INVAL = 22, /* Invalid argument */ + MNT3ERR_NAMETOOLONG = 63, /* Filename too long */ + MNT3ERR_NOTSUPP = 10004, /* Operation not supported */ + MNT3ERR_SERVERFAULT = 10006 /* A failure on the server */ +}; + +struct mountres3_ok { + fhandle3 fhandle; + int auth_flavors<>; +}; + +union mountres3 switch (mountstat3 fhs_status) { +case 0: + mountres3_ok mountinfo; +default: + void; +}; +#endif + +/* + * The type dirpath is the pathname of a directory + */ +typedef string dirpath<MNTPATHLEN>; + +/* + * The type name is used for arbitrary names (hostnames, groupnames) + */ +typedef string name<MNTNAMLEN>; + +/* + * A list of who has what mounted + */ +typedef struct mountbody *mountlist; +struct mountbody { + name ml_hostname; + dirpath ml_directory; + mountlist ml_next; +}; + +/* + * A list of netgroups + */ +typedef struct groupnode *groups; +struct groupnode { + name gr_name; + groups gr_next; +}; + +/* + * A list of what is exported and to whom + */ +typedef struct exportnode *exports; +struct exportnode { + dirpath ex_dir; + groups ex_groups; + exports ex_next; +}; + +program MOUNTPROG { + /* + * Version one of the mount protocol communicates with version two + * of the NFS protocol. Version three communicates with + * version three of the NFS protocol. The only connecting + * point is the fhandle structure, which is the same for both + * protocols. + */ + version MOUNTVERS { + /* + * Does no work. It is made available in all RPC services + * to allow server reponse testing and timing + */ + void + MOUNTPROC_NULL(void) = 0; + + /* + * If fhs_status is 0, then fhs_fhandle contains the + * file handle for the directory. This file handle may + * be used in the NFS protocol. This procedure also adds + * a new entry to the mount list for this client mounting + * the directory. + * Unix authentication required. + */ + fhstatus + MOUNTPROC_MNT(dirpath) = 1; + + /* + * Returns the list of remotely mounted filesystems. The + * mountlist contains one entry for each hostname and + * directory pair. + */ + mountlist + MOUNTPROC_DUMP(void) = 2; + + /* + * Removes the mount list entry for the directory + * Unix authentication required. + */ + void + MOUNTPROC_UMNT(dirpath) = 3; + + /* + * Removes all of the mount list entries for this client + * Unix authentication required. + */ + void + MOUNTPROC_UMNTALL(void) = 4; + + /* + * Returns a list of all the exported filesystems, and which + * machines are allowed to import it. + */ + exports + MOUNTPROC_EXPORT(void) = 5; + + /* + * Identical to MOUNTPROC_EXPORT above + */ + exports + MOUNTPROC_EXPORTALL(void) = 6; + } = 1; +#ifdef WANT_NFS3 + version MOUNTVERS3 { + /* + * Does no work. It is made available in all RPC services + * to allow server reponse testing and timing + */ + void + MOUNTPROC_NULL(void) = 0; + + /* + * If mountres3.fhs_status is MNT3_OK, then + * mountres3.mountinfo contains the file handle for + * the directory and a list of acceptable + * authentication flavors. This file handle may only + * be used in the NFS version 3 protocol. This + * procedure also results in the server adding a new + * entry to its mount list recording that this client + * has mounted the directory. AUTH_UNIX authentication + * or better is required. + */ + mountres3 + MOUNTPROC_MNT(dirpath) = 1; + + /* + * Returns the list of remotely mounted filesystems. The + * mountlist contains one entry for each hostname and + * directory pair. + */ + mountlist + MOUNTPROC_DUMP(void) = 2; + + /* + * Removes the mount list entry for the directory + * Unix authentication required. + */ + void + MOUNTPROC_UMNT(dirpath) = 3; + + /* + * Removes all of the mount list entries for this client + * Unix authentication required. + */ + void + MOUNTPROC_UMNTALL(void) = 4; + + /* + * Returns a list of all the exported filesystems, and which + * machines are allowed to import it. + */ + exports + MOUNTPROC_EXPORT(void) = 5; + } = 3; +#endif +} = 100005; diff --git a/cpukit/librpc/include/rpcsvc/nfs_prot.x b/cpukit/librpc/include/rpcsvc/nfs_prot.x index e69de29bb2..01564f895e 100644 --- a/cpukit/librpc/include/rpcsvc/nfs_prot.x +++ b/cpukit/librpc/include/rpcsvc/nfs_prot.x @@ -0,0 +1,1266 @@ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#ifndef RPC_HDR +%#ifndef lint +%/*static char sccsid[] = "from: @(#)nfs_prot.x 1.2 87/10/12 Copyr 1987 Sun Micro";*/ +%/*static char sccsid[] = "from: @(#)nfs_prot.x 2.1 88/08/01 4.0 RPCSRC";*/ +%static const char rcsid[] = +% "$FreeBSD: src/include/rpcsvc/nfs_prot.x,v 1.7 1999/08/27 23:45:08 peter Exp $"; +%#endif /* not lint */ +#endif + +const NFS_PORT = 2049; +const NFS_MAXDATA = 8192; +const NFS_MAXPATHLEN = 1024; +const NFS_MAXNAMLEN = 255; +const NFS_FHSIZE = 32; +const NFS_COOKIESIZE = 4; +const NFS_FIFO_DEV = -1; /* size kludge for named pipes */ + +/* + * File types + */ +const NFSMODE_FMT = 0170000; /* type of file */ +const NFSMODE_DIR = 0040000; /* directory */ +const NFSMODE_CHR = 0020000; /* character special */ +const NFSMODE_BLK = 0060000; /* block special */ +const NFSMODE_REG = 0100000; /* regular */ +const NFSMODE_LNK = 0120000; /* symbolic link */ +const NFSMODE_SOCK = 0140000; /* socket */ +const NFSMODE_FIFO = 0010000; /* fifo */ + +/* + * Error status + */ +enum nfsstat { + NFS_OK= 0, /* no error */ + NFSERR_PERM=1, /* Not owner */ + NFSERR_NOENT=2, /* No such file or directory */ + NFSERR_IO=5, /* I/O error */ + NFSERR_NXIO=6, /* No such device or address */ + NFSERR_ACCES=13, /* Permission denied */ + NFSERR_EXIST=17, /* File exists */ + NFSERR_NODEV=19, /* No such device */ + NFSERR_NOTDIR=20, /* Not a directory*/ + NFSERR_ISDIR=21, /* Is a directory */ + NFSERR_FBIG=27, /* File too large */ + NFSERR_NOSPC=28, /* No space left on device */ + NFSERR_ROFS=30, /* Read-only file system */ + NFSERR_NAMETOOLONG=63, /* File name too long */ + NFSERR_NOTEMPTY=66, /* Directory not empty */ + NFSERR_DQUOT=69, /* Disc quota exceeded */ + NFSERR_STALE=70, /* Stale NFS file handle */ + NFSERR_WFLUSH=99 /* write cache flushed */ +}; + +/* + * File types + */ +enum ftype { + NFNON = 0, /* non-file */ + NFREG = 1, /* regular file */ + NFDIR = 2, /* directory */ + NFBLK = 3, /* block special */ + NFCHR = 4, /* character special */ + NFLNK = 5, /* symbolic link */ + NFSOCK = 6, /* unix domain sockets */ + NFBAD = 7, /* unused */ + NFFIFO = 8 /* named pipe */ +}; + +/* + * File access handle + */ +struct nfs_fh { + opaque data[NFS_FHSIZE]; +}; + +/* + * Timeval + */ +struct nfstime { + unsigned seconds; + unsigned useconds; +}; + + +/* + * File attributes + */ +struct fattr { + ftype type; /* file type */ + unsigned mode; /* protection mode bits */ + unsigned nlink; /* # hard links */ + unsigned uid; /* owner user id */ + unsigned gid; /* owner group id */ + unsigned size; /* file size in bytes */ + unsigned blocksize; /* prefered block size */ + unsigned rdev; /* special device # */ + unsigned blocks; /* Kb of disk used by file */ + unsigned fsid; /* device # */ + unsigned fileid; /* inode # */ + nfstime atime; /* time of last access */ + nfstime mtime; /* time of last modification */ + nfstime ctime; /* time of last change */ +}; + +/* + * File attributes which can be set + */ +struct sattr { + unsigned mode; /* protection mode bits */ + unsigned uid; /* owner user id */ + unsigned gid; /* owner group id */ + unsigned size; /* file size in bytes */ + nfstime atime; /* time of last access */ + nfstime mtime; /* time of last modification */ +}; + + +typedef string filename<NFS_MAXNAMLEN>; +typedef string nfspath<NFS_MAXPATHLEN>; + +/* + * Reply status with file attributes + */ +union attrstat switch (nfsstat status) { +case NFS_OK: + fattr attributes; +default: + void; +}; + +struct sattrargs { + nfs_fh file; + sattr attributes; +}; + +/* + * Arguments for directory operations + */ +struct diropargs { + nfs_fh dir; /* directory file handle */ + filename name; /* name (up to NFS_MAXNAMLEN bytes) */ +}; + +struct diropokres { + nfs_fh file; + fattr attributes; +}; + +/* + * Results from directory operation + */ +union diropres switch (nfsstat status) { +case NFS_OK: + diropokres diropres; +default: + void; +}; + +union readlinkres switch (nfsstat status) { +case NFS_OK: + nfspath data; +default: + void; +}; + +/* + * Arguments to remote read + */ +struct readargs { + nfs_fh file; /* handle for file */ + unsigned offset; /* byte offset in file */ + unsigned count; /* immediate read count */ + unsigned totalcount; /* total read count (from this offset)*/ +}; + +/* + * Status OK portion of remote read reply + */ +struct readokres { + fattr attributes; /* attributes, need for pagin*/ + opaque data<NFS_MAXDATA>; +}; + +union readres switch (nfsstat status) { +case NFS_OK: + readokres reply; +default: + void; +}; + +/* + * Arguments to remote write + */ +struct writeargs { + nfs_fh file; /* handle for file */ + unsigned beginoffset; /* beginning byte offset in file */ + unsigned offset; /* current byte offset in file */ + unsigned totalcount; /* total write count (to this offset)*/ + opaque data<NFS_MAXDATA>; +}; + +struct createargs { + diropargs where; + sattr attributes; +}; + +struct renameargs { + diropargs from; + diropargs to; +}; + +struct linkargs { + nfs_fh from; + diropargs to; +}; + +struct symlinkargs { + diropargs from; + nfspath to; + sattr attributes; +}; + + +typedef opaque nfscookie[NFS_COOKIESIZE]; + +/* + * Arguments to readdir + */ +struct readdirargs { + nfs_fh dir; /* directory handle */ + nfscookie cookie; + unsigned count; /* number of directory bytes to read */ +}; + +struct entry { + unsigned fileid; + filename name; + nfscookie cookie; + entry *nextentry; +}; + +struct dirlist { + entry *entries; + bool eof; +}; + +union readdirres switch (nfsstat status) { +case NFS_OK: + dirlist reply; +default: + void; +}; + +struct statfsokres { + unsigned tsize; /* preferred transfer size in bytes */ + unsigned bsize; /* fundamental file system block size */ + unsigned blocks; /* total blocks in file system */ + unsigned bfree; /* free blocks in fs */ + unsigned bavail; /* free blocks avail to non-superuser */ +}; + +union statfsres switch (nfsstat status) { +case NFS_OK: + statfsokres reply; +default: + void; +}; + +#ifdef WANT_NFS3 + +/* + * NFSv3 constants and types + */ +const NFS3_FHSIZE = 64; /* maximum size in bytes of a file handle */ +const NFS3_COOKIEVERFSIZE = 8; /* size of a cookie verifier for READDIR */ +const NFS3_CREATEVERFSIZE = 8; /* size of the verifier used for CREATE */ +const NFS3_WRITEVERFSIZE = 8; /* size of the verifier used for WRITE */ + +typedef unsigned hyper uint64; +typedef hyper int64; +typedef unsigned long uint32; +typedef long int32; +typedef string filename3<>; +typedef string nfspath3<>; +typedef uint64 fileid3; +typedef uint64 cookie3; +typedef opaque cookieverf3[NFS3_COOKIEVERFSIZE]; +typedef opaque createverf3[NFS3_CREATEVERFSIZE]; +typedef opaque writeverf3[NFS3_WRITEVERFSIZE]; +typedef uint32 uid3; +typedef uint32 gid3; +typedef uint64 size3; +typedef uint64 offset3; +typedef uint32 mode3; +typedef uint32 count3; + +/* + * Error status (v3) + */ +enum nfsstat3 { + NFS3_OK = 0, + NFS3ERR_PERM = 1, + NFS3ERR_NOENT = 2, + NFS3ERR_IO = 5, + NFS3ERR_NXIO = 6, + NFS3ERR_ACCES = 13, + NFS3ERR_EXIST = 17, + NFS3ERR_XDEV = 18, + NFS3ERR_NODEV = 19, + NFS3ERR_NOTDIR = 20, + NFS3ERR_ISDIR = 21, + NFS3ERR_INVAL = 22, + NFS3ERR_FBIG = 27, + NFS3ERR_NOSPC = 28, + NFS3ERR_ROFS = 30, + NFS3ERR_MLINK = 31, + NFS3ERR_NAMETOOLONG = 63, + NFS3ERR_NOTEMPTY = 66, + NFS3ERR_DQUOT = 69, + NFS3ERR_STALE = 70, + NFS3ERR_REMOTE = 71, + NFS3ERR_BADHANDLE = 10001, + NFS3ERR_NOT_SYNC = 10002, + NFS3ERR_BAD_COOKIE = 10003, + NFS3ERR_NOTSUPP = 10004, + NFS3ERR_TOOSMALL = 10005, + NFS3ERR_SERVERFAULT = 10006, + NFS3ERR_BADTYPE = 10007, + NFS3ERR_JUKEBOX = 10008 +}; + +/* + * File types (v3) + */ +enum ftype3 { + NF3REG = 1, /* regular file */ + NF3DIR = 2, /* directory */ + NF3BLK = 3, /* block special */ + NF3CHR = 4, /* character special */ + NF3LNK = 5, /* symbolic link */ + NF3SOCK = 6, /* unix domain sockets */ + NF3FIFO = 7 /* named pipe */ +}; + +struct specdata3 { + uint32 specdata1; + uint32 specdata2; +}; + +/* + * File access handle (v3) + */ +struct nfs_fh3 { + opaque data<NFS3_FHSIZE>; +}; + +/* + * Timeval (v3) + */ +struct nfstime3 { + uint32 seconds; + uint32 nseconds; +}; + + +/* + * File attributes (v3) + */ +struct fattr3 { + ftype3 type; /* file type */ + mode3 mode; /* protection mode bits */ + uint32 nlink; /* # hard links */ + uid3 uid; /* owner user id */ + gid3 gid; /* owner group id */ + size3 size; /* file size in bytes */ + size3 used; /* prefered block size */ + specdata3 rdev; /* special device # */ + uint64 fsid; /* device # */ + fileid3 fileid; /* inode # */ + nfstime3 atime; /* time of last access */ + nfstime3 mtime; /* time of last modification */ + nfstime3 ctime; /* time of last change */ +}; + +union post_op_attr switch (bool attributes_follow) { +case TRUE: + fattr3 attributes; +case FALSE: + void; +}; + +struct wcc_attr { + size3 size; + nfstime3 mtime; + nfstime3 ctime; +}; + +union pre_op_attr switch (bool attributes_follow) { +case TRUE: + wcc_attr attributes; +case FALSE: + void; +}; + +struct wcc_data { + pre_op_attr before; + post_op_attr after; +}; + +union post_op_fh3 switch (bool handle_follows) { +case TRUE: + nfs_fh3 handle; +case FALSE: + void; +}; + +/* + * File attributes which can be set (v3) + */ +enum time_how { + DONT_CHANGE = 0, + SET_TO_SERVER_TIME = 1, + SET_TO_CLIENT_TIME = 2 +}; + +union set_mode3 switch (bool set_it) { +case TRUE: + mode3 mode; +default: + void; +}; + +union set_uid3 switch (bool set_it) { +case TRUE: + uid3 uid; +default: + void; +}; + +union set_gid3 switch (bool set_it) { +case TRUE: + gid3 gid; +default: + void; +}; + +union set_size3 switch (bool set_it) { +case TRUE: + size3 size; +default: + void; +}; + +union set_atime switch (time_how set_it) { +case SET_TO_CLIENT_TIME: + nfstime3 atime; +default: + void; +}; + +union set_mtime switch (time_how set_it) { +case SET_TO_CLIENT_TIME: + nfstime3 mtime; +default: + void; +}; + +struct sattr3 { + set_mode3 mode; + set_uid3 uid; + set_gid3 gid; + set_size3 size; + set_atime atime; + set_mtime mtime; +}; + +/* + * Arguments for directory operations (v3) + */ +struct diropargs3 { + nfs_fh3 dir; /* directory file handle */ + filename3 name; /* name (up to NFS_MAXNAMLEN bytes) */ +}; + +/* + * Arguments to getattr (v3). + */ +struct GETATTR3args { + nfs_fh3 object; +}; + +struct GETATTR3resok { + fattr3 obj_attributes; +}; + +union GETATTR3res switch (nfsstat3 status) { +case NFS3_OK: + GETATTR3resok resok; +default: + void; +}; + +/* + * Arguments to setattr (v3). + */ +union sattrguard3 switch (bool check) { +case TRUE: + nfstime3 obj_ctime; +case FALSE: + void; +}; + +struct SETATTR3args { + nfs_fh3 object; + sattr3 new_attributes; + sattrguard3 guard; +}; + +struct SETATTR3resok { + wcc_data obj_wcc; +}; + +struct SETATTR3resfail { + wcc_data obj_wcc; +}; + +union SETATTR3res switch (nfsstat3 status) { +case NFS3_OK: + SETATTR3resok resok; +default: + SETATTR3resfail resfail; +}; + +/* + * Arguments to lookup (v3). + */ +struct LOOKUP3args { + diropargs3 what; +}; + +struct LOOKUP3resok { + nfs_fh3 object; + post_op_attr obj_attributes; + post_op_attr dir_attributes; +}; + +struct LOOKUP3resfail { + post_op_attr dir_attributes; +}; + +union LOOKUP3res switch (nfsstat3 status) { +case NFS3_OK: + LOOKUP3resok resok; +default: + LOOKUP3resfail resfail; +}; + +/* + * Arguments to access (v3). + */ +const ACCESS3_READ = 0x0001; +const ACCESS3_LOOKUP = 0x0002; +const ACCESS3_MODIFY = 0x0004; +const ACCESS3_EXTEND = 0x0008; +const ACCESS3_DELETE = 0x0010; +const ACCESS3_EXECUTE = 0x0020; + +struct ACCESS3args { + nfs_fh3 object; + uint32 access; +}; + +struct ACCESS3resok { + post_op_attr obj_attributes; + uint32 access; +}; + +struct ACCESS3resfail { + post_op_attr obj_attributes; +}; + +union ACCESS3res switch (nfsstat3 status) { +case NFS3_OK: + ACCESS3resok resok; +default: + ACCESS3resfail resfail; +}; + +/* + * Arguments to readlink (v3). + */ +struct READLINK3args { + nfs_fh3 symlink; +}; + +struct READLINK3resok { + post_op_attr symlink_attributes; + nfspath3 data; +}; + +struct READLINK3resfail { + post_op_attr symlink_attributes; +}; + +union READLINK3res switch (nfsstat3 status) { +case NFS3_OK: + READLINK3resok resok; +default: + READLINK3resfail resfail; +}; + +/* + * Arguments to read (v3). + */ +struct READ3args { + nfs_fh3 file; + offset3 offset; + count3 count; +}; + +struct READ3resok { + post_op_attr file_attributes; + count3 count; + bool eof; + opaque data<>; +}; + +struct READ3resfail { + post_op_attr file_attributes; +}; + +/* XXX: solaris 2.6 uses ``nfsstat'' here */ +union READ3res switch (nfsstat3 status) { +case NFS3_OK: + READ3resok resok; +default: + READ3resfail resfail; +}; + +/* + * Arguments to write (v3). + */ +enum stable_how { + UNSTABLE = 0, + DATA_SYNC = 1, + FILE_SYNC = 2 +}; + +struct WRITE3args { + nfs_fh3 file; + offset3 offset; + count3 count; + stable_how stable; + opaque data<>; +}; + +struct WRITE3resok { + wcc_data file_wcc; + count3 count; + stable_how committed; + writeverf3 verf; +}; + +struct WRITE3resfail { + wcc_data file_wcc; +}; + +union WRITE3res switch (nfsstat3 status) { +case NFS3_OK: + WRITE3resok resok; +default: + WRITE3resfail resfail; +}; + +/* + * Arguments to create (v3). + */ +enum createmode3 { + UNCHECKED = 0, + GUARDED = 1, + EXCLUSIVE = 2 +}; + +union createhow3 switch (createmode3 mode) { +case UNCHECKED: +case GUARDED: + sattr3 obj_attributes; +case EXCLUSIVE: + createverf3 verf; +}; + +struct CREATE3args { + diropargs3 where; + createhow3 how; +}; + +struct CREATE3resok { + post_op_fh3 obj; + post_op_attr obj_attributes; + wcc_data dir_wcc; +}; + +struct CREATE3resfail { + wcc_data dir_wcc; +}; + +union CREATE3res switch (nfsstat3 status) { +case NFS3_OK: + CREATE3resok resok; +default: + CREATE3resfail resfail; +}; + +/* + * Arguments to mkdir (v3). + */ +struct MKDIR3args { + diropargs3 where; + sattr3 attributes; +}; + +struct MKDIR3resok { + post_op_fh3 obj; + post_op_attr obj_attributes; + wcc_data dir_wcc; +}; + +struct MKDIR3resfail { + wcc_data dir_wcc; +}; + +union MKDIR3res switch (nfsstat3 status) { +case NFS3_OK: + MKDIR3resok resok; +default: + MKDIR3resfail resfail; +}; + +/* + * Arguments to symlink (v3). + */ +struct symlinkdata3 { + sattr3 symlink_attributes; + nfspath3 symlink_data; +}; + +struct SYMLINK3args { + diropargs3 where; + symlinkdata3 symlink; +}; + +struct SYMLINK3resok { + post_op_fh3 obj; + post_op_attr obj_attributes; + wcc_data dir_wcc; +}; + +struct SYMLINK3resfail { + wcc_data dir_wcc; +}; + +union SYMLINK3res switch (nfsstat3 status) { +case NFS3_OK: + SYMLINK3resok resok; +default: + SYMLINK3resfail resfail; +}; + +/* + * Arguments to mknod (v3). + */ +struct devicedata3 { + sattr3 dev_attributes; + specdata3 spec; +}; + +union mknoddata3 switch (ftype3 type) { +case NF3CHR: +case NF3BLK: + devicedata3 device; +case NF3SOCK: +case NF3FIFO: + sattr3 pipe_attributes; +default: + void; +}; + +struct MKNOD3args { + diropargs3 where; + mknoddata3 what; +}; + +struct MKNOD3resok { + post_op_fh3 obj; + post_op_attr obj_attributes; + wcc_data dir_wcc; +}; + +struct MKNOD3resfail { + wcc_data dir_wcc; +}; + +union MKNOD3res switch (nfsstat3 status) { +case NFS3_OK: + MKNOD3resok resok; +default: + MKNOD3resfail resfail; +}; + +/* + * Arguments to remove (v3). + */ +struct REMOVE3args { + diropargs3 object; +}; + +struct REMOVE3resok { + wcc_data dir_wcc; +}; + +struct REMOVE3resfail { + wcc_data dir_wcc; +}; + +union REMOVE3res switch (nfsstat3 status) { +case NFS3_OK: + REMOVE3resok resok; +default: + REMOVE3resfail resfail; +}; + +/* + * Arguments to rmdir (v3). + */ +struct RMDIR3args { + diropargs3 object; +}; + +struct RMDIR3resok { + wcc_data dir_wcc; +}; + +struct RMDIR3resfail { + wcc_data dir_wcc; +}; + +union RMDIR3res switch (nfsstat3 status) { +case NFS3_OK: + RMDIR3resok resok; +default: + RMDIR3resfail resfail; +}; + +/* + * Arguments to rename (v3). + */ +struct RENAME3args { + diropargs3 from; + diropargs3 to; +}; + +struct RENAME3resok { + wcc_data fromdir_wcc; + wcc_data todir_wcc; +}; + +struct RENAME3resfail { + wcc_data fromdir_wcc; + wcc_data todir_wcc; +}; + +union RENAME3res switch (nfsstat3 status) { +case NFS3_OK: + RENAME3resok resok; +default: + RENAME3resfail resfail; +}; + +/* + * Arguments to link (v3). + */ +struct LINK3args { + nfs_fh3 file; + diropargs3 link; +}; + +struct LINK3resok { + post_op_attr file_attributes; + wcc_data linkdir_wcc; +}; + +struct LINK3resfail { + post_op_attr file_attributes; + wcc_data linkdir_wcc; +}; + +union LINK3res switch (nfsstat3 status) { +case NFS3_OK: + LINK3resok resok; +default: + LINK3resfail resfail; +}; + +/* + * Arguments to readdir (v3). + */ +struct READDIR3args { + nfs_fh3 dir; + cookie3 cookie; + cookieverf3 cookieverf; + count3 count; +}; + +struct entry3 { + fileid3 fileid; + filename3 name; + cookie3 cookie; + entry3 *nextentry; +}; + +struct dirlist3 { + entry3 *entries; + bool eof; +}; + +struct READDIR3resok { + post_op_attr dir_attributes; + cookieverf3 cookieverf; + dirlist3 reply; +}; + +struct READDIR3resfail { + post_op_attr dir_attributes; +}; + +union READDIR3res switch (nfsstat3 status) { +case NFS3_OK: + READDIR3resok resok; +default: + READDIR3resfail resfail; +}; + +/* + * Arguments to readdirplus (v3). + */ +struct READDIRPLUS3args { + nfs_fh3 dir; + cookie3 cookie; + cookieverf3 cookieverf; + count3 dircount; + count3 maxcount; +}; + +struct entryplus3 { + fileid3 fileid; + filename3 name; + cookie3 cookie; + post_op_attr name_attributes; + post_op_fh3 name_handle; + entryplus3 *nextentry; +}; + +struct dirlistplus3 { + entryplus3 *entries; + bool eof; +}; + +struct READDIRPLUS3resok { + post_op_attr dir_attributes; + cookieverf3 cookieverf; + dirlistplus3 reply; +}; + +struct READDIRPLUS3resfail { + post_op_attr dir_attributes; +}; + +union READDIRPLUS3res switch (nfsstat3 status) { +case NFS3_OK: + READDIRPLUS3resok resok; +default: + READDIRPLUS3resfail resfail; +}; + +/* + * Arguments to fsstat (v3). + */ +struct FSSTAT3args { + nfs_fh3 fsroot; +}; + +struct FSSTAT3resok { + post_op_attr obj_attributes; + size3 tbytes; + size3 fbytes; + size3 abytes; + size3 tfiles; + size3 ffiles; + size3 afiles; + uint32 invarsec; +}; + +struct FSSTAT3resfail { + post_op_attr obj_attributes; +}; + +union FSSTAT3res switch (nfsstat3 status) { +case NFS3_OK: + FSSTAT3resok resok; +default: + FSSTAT3resfail resfail; +}; + +/* + * Arguments to fsinfo (v3). + */ +const FSF3_LINK = 0x0001; +const FSF3_SYMLINK = 0x0002; +const FSF3_HOMOGENEOUS = 0x0008; +const FSF3_CANSETTIME = 0x0010; + +struct FSINFO3args { + nfs_fh3 fsroot; +}; + +struct FSINFO3resok { + post_op_attr obj_attributes; + uint32 rtmax; + uint32 rtpref; + uint32 rtmult; + uint32 wtmax; + uint32 wtpref; + uint32 wtmult; + uint32 dtpref; + size3 maxfilesize; + nfstime3 time_delta; + uint32 properties; +}; + +struct FSINFO3resfail { + post_op_attr obj_attributes; +}; + +union FSINFO3res switch (nfsstat3 status) { +case NFS3_OK: + FSINFO3resok resok; +default: + FSINFO3resfail resfail; +}; + +/* + * Arguments to pathconf (v3). + */ +struct PATHCONF3args { + nfs_fh3 object; +}; + +struct PATHCONF3resok { + post_op_attr obj_attributes; + uint32 linkmax; + uint32 name_max; + bool no_trunc; + bool chown_restricted; + bool case_insensitive; + bool case_preserving; +}; + +struct PATHCONF3resfail { + post_op_attr obj_attributes; +}; + +union PATHCONF3res switch (nfsstat3 status) { +case NFS3_OK: + PATHCONF3resok resok; +default: + PATHCONF3resfail resfail; +}; + +/* + * Arguments to commit (v3). + */ +struct COMMIT3args { + nfs_fh3 file; + offset3 offset; + count3 count; +}; + +struct COMMIT3resok { + wcc_data file_wcc; + writeverf3 verf; +}; + +struct COMMIT3resfail { + wcc_data file_wcc; +}; + +union COMMIT3res switch (nfsstat3 status) { +case NFS3_OK: + COMMIT3resok resok; +default: + COMMIT3resfail resfail; +}; + +#endif /* WANT_NFS3 */ + +/* + * Remote file service routines + */ +program NFS_PROGRAM { + version NFS_VERSION { + void + NFSPROC_NULL(void) = 0; + + attrstat + NFSPROC_GETATTR(nfs_fh) = 1; + + attrstat + NFSPROC_SETATTR(sattrargs) = 2; + + void + NFSPROC_ROOT(void) = 3; + + diropres + NFSPROC_LOOKUP(diropargs) = 4; + + readlinkres + NFSPROC_READLINK(nfs_fh) = 5; + + readres + NFSPROC_READ(readargs) = 6; + + void + NFSPROC_WRITECACHE(void) = 7; + + attrstat + NFSPROC_WRITE(writeargs) = 8; + + diropres + NFSPROC_CREATE(createargs) = 9; + + nfsstat + NFSPROC_REMOVE(diropargs) = 10; + + nfsstat + NFSPROC_RENAME(renameargs) = 11; + + nfsstat + NFSPROC_LINK(linkargs) = 12; + + nfsstat + NFSPROC_SYMLINK(symlinkargs) = 13; + + diropres + NFSPROC_MKDIR(createargs) = 14; + + nfsstat + NFSPROC_RMDIR(diropargs) = 15; + + readdirres + NFSPROC_READDIR(readdirargs) = 16; + + statfsres + NFSPROC_STATFS(nfs_fh) = 17; + } = 2; +} = 100003; +#ifdef WANT_NFS3 +program NFS3_PROGRAM { + version NFS_V3 { + void + NFSPROC3_NULL(void) = 0; + + GETATTR3res + NFSPROC3_GETATTR(GETATTR3args) = 1; + + SETATTR3res + NFSPROC3_SETATTR(SETATTR3args) = 2; + + LOOKUP3res + NFSPROC3_LOOKUP(LOOKUP3args) = 3; + + ACCESS3res + NFSPROC3_ACCESS(ACCESS3args) = 4; + + READLINK3res + NFSPROC3_READLINK(READLINK3args) = 5; + + READ3res + NFSPROC3_READ(READ3args) = 6; + + WRITE3res + NFSPROC3_WRITE(WRITE3args) = 7; + + CREATE3res + NFSPROC3_CREATE(CREATE3args) = 8; + + MKDIR3res + NFSPROC3_MKDIR(MKDIR3args) = 9; + + SYMLINK3res + NFSPROC3_SYMLINK(SYMLINK3args) = 10; + + MKNOD3res + NFSPROC3_MKNOD(MKNOD3args) = 11; + + REMOVE3res + NFSPROC3_REMOVE(REMOVE3args) = 12; + + RMDIR3res + NFSPROC3_RMDIR(RMDIR3args) = 13; + + RENAME3res + NFSPROC3_RENAME(RENAME3args) = 14; + + LINK3res + NFSPROC3_LINK(LINK3args) = 15; + + READDIR3res + NFSPROC3_READDIR(READDIR3args) = 16; + + READDIRPLUS3res + NFSPROC3_READDIRPLUS(READDIRPLUS3args) = 17; + + FSSTAT3res + NFSPROC3_FSSTAT(FSSTAT3args) = 18; + + FSINFO3res + NFSPROC3_FSINFO(FSINFO3args) = 19; + + PATHCONF3res + NFSPROC3_PATHCONF(PATHCONF3args) = 20; + + COMMIT3res + NFSPROC3_COMMIT(COMMIT3args) = 21; + } = 3; +} = 100003; +#endif + diff --git a/cpukit/librpc/include/rpcsvc/nis.x b/cpukit/librpc/include/rpcsvc/nis.x index e69de29bb2..ba6c6d1576 100644 --- a/cpukit/librpc/include/rpcsvc/nis.x +++ b/cpukit/librpc/include/rpcsvc/nis.x @@ -0,0 +1,466 @@ +%/* +% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for +% * unrestricted use provided that this legend is included on all tape +% * media and as a part of the software program in whole or part. Users +% * may copy or modify Sun RPC without charge, but are not authorized +% * to license or distribute it to anyone else except as part of a product or +% * program developed by the user or with the express written consent of +% * Sun Microsystems, Inc. +% * +% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE +% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR +% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. +% * +% * Sun RPC is provided with no support and without any obligation on the +% * part of Sun Microsystems, Inc. to assist in its use, correction, +% * modification or enhancement. +% * +% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE +% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC +% * OR ANY PART THEREOF. +% * +% * In no event will Sun Microsystems, Inc. be liable for any lost revenue +% * or profits or other special, indirect and consequential damages, even if +% * Sun has been advised of the possibility of such damages. +% * +% * Sun Microsystems, Inc. +% * 2550 Garcia Avenue +% * Mountain View, California 94043 +% */ + +#ifndef RPC_HDR +%#ifndef lint +%static const char rcsid[] = +% "$FreeBSD: src/include/rpcsvc/nis.x,v 1.3 1999/08/27 23:45:09 peter Exp $"; +%#endif /* not lint */ +#endif + +/* + * From 4.1 : @(#)nis.x 1.61 Copyright 1989 Sun Microsystems + * + * RPC Language Protocol description file for NIS Plus + * This version : 1.61 + * Last Modified : 3/19/91 + */ +#ifdef RPC_HDR +%/* +% * nis.h +% * +% * This file is the main include file for NIS clients. It contains +% * both the client library function defines and the various data +% * structures used by the NIS service. It includes the file nis_tags.h +% * which defines the tag values. This allows the tags to change without +% * having to change the nis.x file. +% * +% * NOTE : DO NOT EDIT THIS FILE! It is automatically generated when +% * rpcgen is run on the nis.x file. Note that there is a +% * simple sed script to remove some unneeded lines. (See the +% * Makefile target nis.h) +% * +% */ +%#include <rpcsvc/nis_tags.h> +#endif + +/* This gets stuffed into the source files. */ +#if RPC_HDR +%#include <rpc/xdr.h> +#endif +/* + * This is just pointless. + */ +#ifdef SUN_STUPIDITY +#if RPC_SVC +%#include "nis_svc.h" +#endif +#endif + +/* Include the RPC Language description of NIS objects */ +#include "nis_object.x" + +/* Errors that can be returned by the service */ +enum nis_error { + NIS_SUCCESS = 0, /* A-ok, let's rock n roll */ + NIS_S_SUCCESS = 1, /* Name found (maybe) */ + NIS_NOTFOUND = 2, /* Name definitely not found */ + NIS_S_NOTFOUND = 3, /* Name maybe not found */ + NIS_CACHEEXPIRED = 4, /* Name exists but cache out of date */ + NIS_NAMEUNREACHABLE = 5, /* Can't get there from here */ + NIS_UNKNOWNOBJ = 6, /* Object type is bogus */ + NIS_TRYAGAIN = 7, /* I'm busy, call back */ + NIS_SYSTEMERROR = 8, /* Out of band failure */ + NIS_CHAINBROKEN = 9, /* First/Next warning */ + NIS_PERMISSION = 10, /* Not enough permission to access */ + NIS_NOTOWNER = 11, /* You don't own it, sorry */ + NIS_NOT_ME = 12, /* I don't serve this name */ + NIS_NOMEMORY = 13, /* Outta VM! Help! */ + NIS_NAMEEXISTS = 14, /* Can't create over another name */ + NIS_NOTMASTER = 15, /* I'm justa secondaray, don't ask me */ + NIS_INVALIDOBJ = 16, /* Object is broken somehow */ + NIS_BADNAME = 17, /* Unparsable name */ + NIS_NOCALLBACK = 18, /* Couldn't talk to call back proc */ + NIS_CBRESULTS = 19, /* Results being called back to you */ + NIS_NOSUCHNAME = 20, /* Name unknown */ + NIS_NOTUNIQUE = 21, /* Value is not uniques (entry) */ + NIS_IBMODERROR = 22, /* Inf. Base. Modify error. */ + NIS_NOSUCHTABLE = 23, /* Name for table was wrong */ + NIS_TYPEMISMATCH = 24, /* Entry and table type mismatch */ + NIS_LINKNAMEERROR = 25, /* Link points to bogus name */ + NIS_PARTIAL = 26, /* Partial success, found table */ + NIS_TOOMANYATTRS = 27, /* Too many attributes */ + NIS_RPCERROR = 28, /* RPC error encountered */ + NIS_BADATTRIBUTE = 29, /* Bad or invalid attribute */ + NIS_NOTSEARCHABLE = 30, /* Non-searchable object searched */ + NIS_CBERROR = 31, /* Error during callback (svc crash) */ + NIS_FOREIGNNS = 32, /* Foreign Namespace */ + NIS_BADOBJECT = 33, /* Malformed object structure */ + NIS_NOTSAMEOBJ = 34, /* Object swapped during deletion */ + NIS_MODFAIL = 35, /* Failure during a Modify. */ + NIS_BADREQUEST = 36, /* Illegal query for table */ + NIS_NOTEMPTY = 37, /* Attempt to remove a non-empty tbl */ + NIS_COLDSTART_ERR = 38, /* Error accesing the cold start file */ + NIS_RESYNC = 39, /* Transaction log too far out of date */ + NIS_FAIL = 40, /* NIS operation failed. */ + NIS_UNAVAIL = 41, /* NIS+ service is unavailable (client) */ + NIS_RES2BIG = 42, /* NIS+ result too big for datagram */ + NIS_SRVAUTH = 43, /* NIS+ server wasn't authenticated. */ + NIS_CLNTAUTH = 44, /* NIS+ Client wasn't authenticated. */ + NIS_NOFILESPACE = 45, /* NIS+ server ran out of disk space */ + NIS_NOPROC = 46, /* NIS+ server couldn't create new proc */ + NIS_DUMPLATER = 47 /* NIS+ server already has dump child */ +}; + + +/* + * Structure definitions for the parameters and results of the actual + * NIS RPC calls. + * + * This is the standard result (in the protocol) of most of the nis + * requests. + */ + +struct nis_result { + nis_error status; /* Status of the response */ + nis_object objects<>; /* objects found */ + netobj cookie; /* Cookie Data */ + u_long zticks; /* server ticks */ + u_long dticks; /* DBM ticks. */ + u_long aticks; /* Cache (accel) ticks */ + u_long cticks; /* Client ticks */ +}; + +/* + * A Name Service request + * This request is used to access the name space, ns_name is the name + * of the object within the namespace and the object is it's value, for + * add/modify, a copy of the original for remove. + */ + +struct ns_request { + nis_name ns_name; /* Name in the NIS name space */ + nis_object ns_object<1>; /* Optional Object (add/remove) */ +}; + +/* + * An information base request + * This request includes the NIS name of the table we wish to search, the + * search criteria in the form of attribute/value pairs and an optional + * callback program number. If the callback program number is provided + * the server will send back objects one at a time, otherwise it will + * return them all in the response. + */ + +struct ib_request { + nis_name ibr_name; /* The name of the Table */ + nis_attr ibr_srch<>; /* The search critereia */ + u_long ibr_flags; /* Optional flags */ + nis_object ibr_obj<1>; /* optional object (add/modify) */ + nis_server ibr_cbhost<1>; /* Optional callback info */ + u_long ibr_bufsize; /* Optional first/next bufsize */ + netobj ibr_cookie; /* The first/next cookie */ +}; + +/* + * This argument to the PING call notifies the replicas that something in + * a directory has changed and this is it's timestamp. The replica will use + * the timestamp to determine if its resync operation was successful. + */ +struct ping_args { + nis_name dir; /* Directory that had the change */ + u_long stamp; /* timestamp of the transaction */ +}; + +/* + * These are the type of entries that are stored in the transaction log, + * note that modifications will appear as two entries, for names, they have + * a "OLD" entry followed by a "NEW" entry. For entries in tables, there + * is a remove followed by an add. It is done this way so that we can read + * the log backwards to back out transactions and forwards to propogate + * updated. + */ +enum log_entry_t { + LOG_NOP = 0, + ADD_NAME = 1, /* Name Added to name space */ + REM_NAME = 2, /* Name removed from name space */ + MOD_NAME_OLD = 3, /* Name was modified in the name space */ + MOD_NAME_NEW = 4, /* Name was modified in the name space */ + ADD_IBASE = 5, /* Entry added to information base */ + REM_IBASE = 6, /* Entry removed from information base */ + MOD_IBASE = 7, /* Entry was modified in information base */ + UPD_STAMP = 8 /* Update timestamp (used as fenceposts) */ +}; + +/* + * This result is returned from the name service when it is requested to + * dump logged entries from its transaction log. Information base updates + * will have the name of the information base in the le_name field and + * a canonical set of attribute/value pairs to fully specify the entry's + * 'name'. + */ +struct log_entry { + u_long le_time; /* Time in seconds */ + log_entry_t le_type; /* Type of log entry */ + nis_name le_princp; /* Principal making the change */ + nis_name le_name; /* Name of table/dir involved */ + nis_attr le_attrs<>; /* List of AV pairs. */ + nis_object le_object; /* Actual object value */ +}; + +struct log_result { + nis_error lr_status; /* The status itself */ + netobj lr_cookie; /* Used by the dump callback */ + log_entry lr_entries<>; /* zero or more entries */ +}; + +struct cp_result { + nis_error cp_status; /* Status of the checkpoint */ + u_long cp_zticks; /* Service 'ticks' */ + u_long cp_dticks; /* Database 'ticks' */ +}; + +/* + * This structure defines a generic NIS tag list. The taglist contains + * zero or tags, each of which is a type and a value. (u_long). + * These are used to report statistics (see tag definitions below) + * and to set or reset state variables. + */ +struct nis_tag { + u_long tag_type; /* Statistic tag (may vary) */ + string tag_val<1024>; /* Statistic value may also vary */ +}; + +struct nis_taglist { + nis_tag tags<>; /* List of tags */ +}; + +struct dump_args { + nis_name da_dir; /* Directory to dump */ + u_long da_time; /* From this timestamp */ + nis_server da_cbhost<1>; /* Callback to use. */ +}; + +struct fd_args { + nis_name dir_name; /* The directory we're looking for */ + nis_name requester; /* Host principal name for signature */ +}; + +struct fd_result { + nis_error status; /* Status returned by function */ + nis_name source; /* Source of this answer */ + opaque dir_data<>; /* Directory Data (XDR'ed) */ + opaque signature<>; /* Signature of the source */ +}; + + +/* + * What's going on here? Well, it's like this. When the service + * is being compiled it wants to have the service definition specific + * info included, and when the client is being compiled it wants that + * info. This includes the appropriate file which was generated by + * make in the protocols directory (probably /usr/include/rpcsvc). + * + * Uhm... guys? With RPC, you aren't supposed to have seperate + * server-specific and client-specific header files. You have one header + * file that's suitable for both. If your code doesn't work using just + * the one header file, I submit to you that it's broken. + * -Bill + */ +#ifdef SUN_STUPIDITY +#ifdef RPC_SVC +%#include "nis_svc.h" +#endif +#ifdef RPC_CLNT +%#include "nis_clnt.h" +#endif +#endif + +program NIS_PROG { + + /* RPC Language description of the NIS+ protocol */ + version NIS_VERSION { + /* The name service functions */ + nis_result NIS_LOOKUP(ns_request) = 1; + nis_result NIS_ADD(ns_request) = 2; + nis_result NIS_MODIFY(ns_request) = 3; + nis_result NIS_REMOVE(ns_request) = 4; + + /* The information base functions */ + nis_result NIS_IBLIST(ib_request) = 5; + nis_result NIS_IBADD(ib_request) = 6; + nis_result NIS_IBMODIFY(ib_request) = 7; + nis_result NIS_IBREMOVE(ib_request) = 8; + nis_result NIS_IBFIRST(ib_request) = 9; + nis_result NIS_IBNEXT(ib_request) = 10; + + /* NIS Administrative functions */ + fd_result NIS_FINDDIRECTORY(fd_args) = 12; + + /* If fetch and optionally reset statistics */ + nis_taglist NIS_STATUS(nis_taglist) = 14; + + /* Dump changes to directory since time in da_time */ + log_result NIS_DUMPLOG(dump_args) = 15; + + /* Dump contents of directory named */ + log_result NIS_DUMP(dump_args) = 16; + + /* Check status of callback thread */ + bool NIS_CALLBACK(netobj) = 17; + + /* Return last update time for named dir */ + u_long NIS_CPTIME(nis_name) = 18; + + /* Checkpoint directory or table named */ + cp_result NIS_CHECKPOINT(nis_name) = 19; + + /* Send 'status changed' ping to replicates */ + void NIS_PING(ping_args) = 20; + + /* Modify server behaviour (such as debugging) */ + nis_taglist NIS_SERVSTATE(nis_taglist) = 21; + + /* Create a Directory */ + nis_error NIS_MKDIR(nis_name) = 22; + + /* Remove a Directory */ + nis_error NIS_RMDIR(nis_name) = 23; + + /* Update public keys of a directory object */ + nis_error NIS_UPDKEYS(nis_name) = 24; + } = 3; +} = 100300; + +/* + * Included below are the defines that become part of nis.h, + * they are technically not part of the protocol, but do define + * key aspects of the implementation and are therefore useful + * in building a conforming server or client. + */ +#if RPC_HDR +%/* +% * Generic "hash" datastructures, used by all types of hashed data. +% */ +%struct nis_hash_data { +% nis_name name; /* NIS name of hashed item */ +% int keychain; /* It's hash key (for pop) */ +% struct nis_hash_data *next; /* Hash collision pointer */ +% struct nis_hash_data *prv_item; /* A serial, doubly linked list */ +% struct nis_hash_data *nxt_item; /* of items in the hash table */ +%}; +%typedef struct nis_hash_data NIS_HASH_ITEM; +% +%struct nis_hash_table { +% NIS_HASH_ITEM *keys[64]; /* A hash table of items */ +% NIS_HASH_ITEM *first; /* The first "item" in serial list */ +%}; +%typedef struct nis_hash_table NIS_HASH_TABLE; +% +%/* Structure for storing dynamically allocated static data */ +%struct nis_sdata { +% void *buf; /* Memory allocation pointer */ +% u_long size; /* Buffer size */ +%}; +% +%/* Generic client creating flags */ +%#define ZMH_VC 1 +%#define ZMH_DG 2 +%#define ZMH_AUTH 4 +% +%/* Testing Access rights for objects */ +% +%#define NIS_READ_ACC 1 +%#define NIS_MODIFY_ACC 2 +%#define NIS_CREATE_ACC 4 +%#define NIS_DESTROY_ACC 8 +%/* Test macros. a == access rights, m == desired rights. */ +%#define WORLD(a, m) (((a) & (m)) != 0) +%#define GROUP(a, m) (((a) & ((m) << 8)) != 0) +%#define OWNER(a, m) (((a) & ((m) << 16)) != 0) +%#define NOBODY(a, m) (((a) & ((m) << 24)) != 0) +% +%#define OATYPE(d, n) (((d)->do_armask.do_armask_val+n)->oa_otype) +%#define OARIGHTS(d, n) (((d)->do_armask.do_armask_val+n)->oa_rights) +%#define WORLD_DEFAULT (NIS_READ_ACC) +%#define GROUP_DEFAULT (NIS_READ_ACC << 8) +%#define OWNER_DEFAULT ((NIS_READ_ACC +\ + NIS_MODIFY_ACC +\ + NIS_CREATE_ACC +\ + NIS_DESTROY_ACC) << 16) +%#define DEFAULT_RIGHTS (WORLD_DEFAULT | GROUP_DEFAULT | OWNER_DEFAULT) +% +%/* Result manipulation defines ... */ +%#define NIS_RES_NUMOBJ(x) ((x)->objects.objects_len) +%#define NIS_RES_OBJECT(x) ((x)->objects.objects_val) +%#define NIS_RES_COOKIE(x) ((x)->cookie) +%#define NIS_RES_STATUS(x) ((x)->status) +% +%/* These defines make getting at the variant part of the object easier. */ +%#define TA_data zo_data.objdata_u.ta_data +%#define EN_data zo_data.objdata_u.en_data +%#define DI_data zo_data.objdata_u.di_data +%#define LI_data zo_data.objdata_u.li_data +%#define GR_data zo_data.objdata_u.gr_data +% +%#define __type_of(o) ((o)->zo_data.zo_type) +% +%/* Declarations for the internal subroutines in nislib.c */ +%enum name_pos {SAME_NAME, HIGHER_NAME, LOWER_NAME, NOT_SEQUENTIAL, BAD_NAME}; +%typedef enum name_pos name_pos; +% +%/* +% * Defines for getting at column data in entry objects. Because RPCGEN +% * generates some rather wordy structures, we create some defines that +% * collapse the needed keystrokes to access a particular value using +% * these definitions they take an nis_object *, and an int and return +% * a u_char * for Value, and an int for length. +% */ +%#define ENTRY_VAL(obj, col) \ + (obj)->EN_data.en_cols.en_cols_val[col].ec_value.ec_value_val +%#define ENTRY_LEN(obj, col) \ + (obj)->EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len +% +%#ifdef __cplusplus +%} +%#endif +% +%/* Prototypes, and extern declarations for the NIS library functions. */ +%#include <rpcsvc/nislib.h> +%#endif /* __NIS_RPCGEN_H */ +%/* EDIT_START */ +% +%/* +% * nis_3.h +% * +% * This file contains definitions that are only of interest to the actual +% * service daemon and client stubs. Normal users of NIS will not include +% * this file. +% * +% * NOTE : This include file is automatically created by a combination +% * of rpcgen and sed. DO NOT EDIT IT, change the nis.x file instead +% * and then remake this file. +% */ +%#ifndef __nis_3_h +%#define __nis_3_h +%#ifdef __cplusplus +%extern "C" { +%#endif +#endif diff --git a/cpukit/librpc/include/rpcsvc/nis_cache.x b/cpukit/librpc/include/rpcsvc/nis_cache.x index e69de29bb2..8343cfd050 100644 --- a/cpukit/librpc/include/rpcsvc/nis_cache.x +++ b/cpukit/librpc/include/rpcsvc/nis_cache.x @@ -0,0 +1,87 @@ +%/* +% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for +% * unrestricted use provided that this legend is included on all tape +% * media and as a part of the software program in whole or part. Users +% * may copy or modify Sun RPC without charge, but are not authorized +% * to license or distribute it to anyone else except as part of a product or +% * program developed by the user or with the express written consent of +% * Sun Microsystems, Inc. +% * +% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE +% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR +% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. +% * +% * Sun RPC is provided with no support and without any obligation on the +% * part of Sun Microsystems, Inc. to assist in its use, correction, +% * modification or enhancement. +% * +% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE +% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC +% * OR ANY PART THEREOF. +% * +% * In no event will Sun Microsystems, Inc. be liable for any lost revenue +% * or profits or other special, indirect and consequential damages, even if +% * Sun has been advised of the possibility of such damages. +% * +% * Sun Microsystems, Inc. +% * 2550 Garcia Avenue +% * Mountain View, California 94043 +% */ + +/* + * nis_cache.x + * + * Copyright (c) 1988-1992 Sun Microsystems Inc + * All Rights Reserved. + */ + +/* From: %#pragma ident "@(#)nis_cache.x 1.11 94/05/03 SMI" */ + +#ifndef RPC_HDR +%#ifndef lint +%static const char rcsid[] = +% "$FreeBSD: src/include/rpcsvc/nis_cache.x,v 1.3 1999/08/27 23:45:09 peter Exp $"; +%#endif /* not lint */ +#endif + +#ifdef RPC_HDR +%#include <rpc/types.h> +%#include <rpcsvc/nis.h> +% +%/* default cache file */ +%#define CACHEFILE "/var/nis/NIS_SHARED_DIRCACHE" +% +%/* clients have to read-lock the cache file, and SVR4 locking requires that */ +%/* the file be writable, but we don't want a world-writable cache file. */ +%/* So... everyone agrees to use a different, world-writable file for the */ +%/* locking operations, but the data is in CACHEFILE. */ +%#define CACHELOCK "/usr/tmp/.NIS_DIR_CACHELOCK" +% +%/* the file containing one trusted XDR'ed directory object. +% * This has to be present for the system to work. +% */ +%#define COLD_START_FILE "/var/nis/NIS_COLD_START" +% +%enum pc_status {HIT, MISS, NEAR_MISS}; +% +%extern int __nis_debuglevel; +% +% +#endif + +#ifdef RPC_CLNT +#ifdef SOLARIS +%#include "../gen/nis_clnt.h" +#else +%#include "nis.h" +#endif +#endif + +program CACHEPROG { + version CACHE_VER_1 { + void NIS_CACHE_ADD_ENTRY(fd_result) = 1; + void NIS_CACHE_REMOVE_ENTRY(directory_obj) = 2; + void NIS_CACHE_READ_COLDSTART(void) = 3; + void NIS_CACHE_REFRESH_ENTRY(string<>) = 4; + } = 1; +} = 100301; diff --git a/cpukit/librpc/include/rpcsvc/nis_callback.x b/cpukit/librpc/include/rpcsvc/nis_callback.x index e69de29bb2..4e74aa0a2e 100644 --- a/cpukit/librpc/include/rpcsvc/nis_callback.x +++ b/cpukit/librpc/include/rpcsvc/nis_callback.x @@ -0,0 +1,76 @@ +%/* +% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for +% * unrestricted use provided that this legend is included on all tape +% * media and as a part of the software program in whole or part. Users +% * may copy or modify Sun RPC without charge, but are not authorized +% * to license or distribute it to anyone else except as part of a product or +% * program developed by the user or with the express written consent of +% * Sun Microsystems, Inc. +% * +% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE +% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR +% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. +% * +% * Sun RPC is provided with no support and without any obligation on the +% * part of Sun Microsystems, Inc. to assist in its use, correction, +% * modification or enhancement. +% * +% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE +% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC +% * OR ANY PART THEREOF. +% * +% * In no event will Sun Microsystems, Inc. be liable for any lost revenue +% * or profits or other special, indirect and consequential damages, even if +% * Sun has been advised of the possibility of such damages. +% * +% * Sun Microsystems, Inc. +% * 2550 Garcia Avenue +% * Mountain View, California 94043 +% */ + +/* + * nis_callback.x + * + * Copyright (c) 1988-1992 Sun Microsystems Inc + * All Rights Reserved. + */ + +/* From: %#pragma ident "@(#)nis_callback.x 1.7 94/05/03 SMI" */ + +#ifndef RPC_HDR +%#ifndef lint +%static const char rcsid[] = +% "$FreeBSD: src/include/rpcsvc/nis_callback.x,v 1.3 1999/08/27 23:45:09 peter Exp $"; +%#endif /* not lint */ +#endif + +/* + * "@(#)zns_cback.x 1.2 90/09/10 Copyr 1990 Sun Micro" + * + * RPCL description of the Callback Service. + */ + +#ifdef RPC_HDR +%#include <rpcsvc/nis.h> +#endif +#ifdef RPC_XDR +#ifdef SOLARIS +%#include "nis_clnt.h" +#else +%#include "nis.h" +#endif +#endif + +typedef nis_object *obj_p; + +struct cback_data { + obj_p entries<>; /* List of objects */ +}; + +program CB_PROG { + version CB_VERS { + bool CBPROC_RECEIVE(cback_data) = 1; + void CBPROC_FINISH(void) = 2; + void CBPROC_ERROR(nis_error) = 3; + } = 1; +} = 100302; diff --git a/cpukit/librpc/include/rpcsvc/nis_db.h b/cpukit/librpc/include/rpcsvc/nis_db.h index e69de29bb2..dbdee5aac8 100644 --- a/cpukit/librpc/include/rpcsvc/nis_db.h +++ b/cpukit/librpc/include/rpcsvc/nis_db.h @@ -0,0 +1,162 @@ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + * + * $FreeBSD: src/include/rpcsvc/nis_db.h,v 1.5 1999/08/27 23:45:09 peter Exp $ + */ + +/* + * Copyright (c) 1991, by Sun Microsystems Inc. + */ + +/* + * This header file defines the interface to the NIS database. All + * implementations of the database must export at least these routines. + * They must also follow the conventions set herein. See the implementors + * guide for specific semantics that are required. + */ + +#ifndef _RPCSVC_NIS_DB_H +#define _RPCSVC_NIS_DB_H + + +/* From: #pragma ident "@(#)nis_db.h 1.8 94/05/03 SMI" */ + +/* + * Note: although the version of <rpcsvc/nis_db.h> shipped with Solaris + * 2.5/2.5.x is actually older than this one (according to the ident + * string), it contains changes and a few added functions. Those changes + * have been hand merged into this file to bring it up to date. + */ + +#include <rpc/rpc.h> +#include <rpcsvc/nis.h> + +#ifdef __cplusplus +extern "C" { +#endif + +enum db_status { + DB_SUCCESS = 0, + DB_NOTFOUND = 1, + DB_NOTUNIQUE = 2, + DB_BADTABLE = 3, + DB_BADQUERY = 4, + DB_BADOBJECT = 5, + DB_MEMORY_LIMIT = 6, + DB_STORAGE_LIMIT = 7, + DB_INTERNAL_ERROR = 8 +}; +typedef enum db_status db_status; + +enum db_action { + DB_LOOKUP = 0, + DB_REMOVE = 1, + DB_ADD = 2, + DB_FIRST = 3, + DB_NEXT = 4, + DB_ALL = 5, + DB_RESET_NEXT = 6 +}; +typedef enum db_action db_action; + +typedef entry_obj *entry_object_p; + +typedef struct { + u_int db_next_desc_len; + char *db_next_desc_val; +} db_next_desc; + +struct db_result { + db_status status; + db_next_desc nextinfo; + struct { + u_int objects_len; + entry_object_p *objects_val; + } objects; + long ticks; +}; +typedef struct db_result db_result; + +/* + * Prototypes for the database functions. + */ + +#if (__STDC__) + +extern bool_t db_initialize(char *); +#ifdef ORIGINAL_DECLS +extern bool_t db_create_table(char *, table_obj *); +extern bool_t db_destroy_table(char *); +#else +extern db_status db_create_table(char *, table_obj *); +extern db_status db_destroy_table(char *); +#endif +extern db_result *db_first_entry(char *, int, nis_attr *); +extern db_result *db_next_entry(char *, db_next_desc *); +extern db_result *db_reset_next_entry(char *, db_next_desc *); +extern db_result *db_list_entries(char *, int, nis_attr *); +extern db_result *db_add_entry(char *, int, nis_attr *, entry_obj *); +extern db_result *db_remove_entry(char *, int, nis_attr *); +extern db_status db_checkpoint(char *); +extern db_status db_standby(char *); +#ifndef ORIGINAL_DECLS +extern db_status db_table_exists(char *); +extern db_status db_unload_table(char *); +extern void db_free_result(db_result *); +#endif + +#else /* Non-prototype definitions */ + +extern bool_t db_initialize(); +#ifdef ORIGINAL_DECLS +extern bool_t db_create_table(); +extern bool_t db_destroy_table(); +#else +extern db_status db_create_table(); +extern db_status db_destroy_table(); +#endif +extern db_result *db_first_entry(); +extern db_result *db_next_entry(); +extern db_result *db_reset_next_entry(); +extern db_result *db_list_entries(); +extern db_result *db_add_entry(); +extern db_result *db_remove_entry(); +extern db_status db_checkpoint(); +extern db_status db_standby(); +#ifndef ORIGINAL_DECLS +extern db_status db_table_exists(); +extern db_status db_unload_table(); +extern void db_free_result(); +#endif +#endif /* __STDC__ */ + +#ifdef __cplusplus +} +#endif + +#endif /* _RPCSVC_NIS_DB_H */ diff --git a/cpukit/librpc/include/rpcsvc/nis_object.x b/cpukit/librpc/include/rpcsvc/nis_object.x index e69de29bb2..3156724f1b 100644 --- a/cpukit/librpc/include/rpcsvc/nis_object.x +++ b/cpukit/librpc/include/rpcsvc/nis_object.x @@ -0,0 +1,317 @@ +%/* +% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for +% * unrestricted use provided that this legend is included on all tape +% * media and as a part of the software program in whole or part. Users +% * may copy or modify Sun RPC without charge, but are not authorized +% * to license or distribute it to anyone else except as part of a product or +% * program developed by the user or with the express written consent of +% * Sun Microsystems, Inc. +% * +% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE +% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR +% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. +% * +% * Sun RPC is provided with no support and without any obligation on the +% * part of Sun Microsystems, Inc. to assist in its use, correction, +% * modification or enhancement. +% * +% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE +% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC +% * OR ANY PART THEREOF. +% * +% * In no event will Sun Microsystems, Inc. be liable for any lost revenue +% * or profits or other special, indirect and consequential damages, even if +% * Sun has been advised of the possibility of such damages. +% * +% * Sun Microsystems, Inc. +% * 2550 Garcia Avenue +% * Mountain View, California 94043 +% */ + +/* + * nis_object.x + * + * Copyright (c) 1988-1992 Sun Microsystems Inc + * All Rights Reserved. + */ + +/* From: %#pragma ident "@(#)nis_object.x 1.10 94/05/03 SMI" */ + +#if RPC_HDR +% +%#ifndef __nis_object_h +%#define __nis_object_h +% +#endif +/* + * This file defines the format for a NIS object in RPC language. + * It is included by the main .x file and the database access protocol + * file. It is common because both of them need to deal with the same + * type of object. Generating the actual code though is a bit messy because + * the nis.x file and the nis_dba.x file will generate xdr routines to + * encode/decode objects when only one set is needed. Such is life when + * one is using rpcgen. + * + * Note, the protocol doesn't specify any limits on such things as + * maximum name length, number of attributes, etc. These are enforced + * by the database backend. When you hit them you will no. Also see + * the db_getlimits() function for fetching the limit values. + * + */ + +/* Some manifest constants, chosen to maximize flexibility without + * plugging the wire full of data. + */ +const NIS_MAXSTRINGLEN = 255; +const NIS_MAXNAMELEN = 1024; +const NIS_MAXATTRNAME = 32; +const NIS_MAXATTRVAL = 2048; +const NIS_MAXCOLUMNS = 64; +const NIS_MAXATTR = 16; +const NIS_MAXPATH = 1024; +const NIS_MAXREPLICAS = 128; +const NIS_MAXLINKS = 16; + +const NIS_PK_NONE = 0; /* no public key (unix/sys auth) */ +const NIS_PK_DH = 1; /* Public key is Diffie-Hellman type */ +const NIS_PK_RSA = 2; /* Public key if RSA type */ +const NIS_PK_KERB = 3; /* Use kerberos style authentication */ + +/* + * The fundamental name type of NIS. The name may consist of two parts, + * the first being the fully qualified name, and the second being an + * optional set of attribute/value pairs. + */ +struct nis_attr { + string zattr_ndx<>; /* name of the index */ + opaque zattr_val<>; /* Value for the attribute. */ +}; + +typedef string nis_name<>; /* The NIS name itself. */ + +/* NIS object types are defined by the following enumeration. The numbers + * they use are based on the following scheme : + * 0 - 1023 are reserved for Sun, + * 1024 - 2047 are defined to be private to a particular tree. + * 2048 - 4095 are defined to be user defined. + * 4096 - ... are reserved for future use. + */ + +enum zotypes { + BOGUS_OBJ = 0, /* Uninitialized object structure */ + NO_OBJ = 1, /* NULL object (no data) */ + DIRECTORY_OBJ = 2, /* Directory object describing domain */ + GROUP_OBJ = 3, /* Group object (a list of names) */ + TABLE_OBJ = 4, /* Table object (a database schema) */ + ENTRY_OBJ = 5, /* Entry object (a database record) */ + LINK_OBJ = 6, /* A name link. */ + PRIVATE_OBJ = 7 /* Private object (all opaque data) */ +}; + +/* + * The types of Name services NIS knows about. They are enumerated + * here. The Binder code will use this type to determine if it has + * a set of library routines that will access the indicated name service. + */ +enum nstype { + UNKNOWN = 0, + NIS = 1, /* Nis Plus Service */ + SUNYP = 2, /* Old NIS Service */ + IVY = 3, /* Nis Plus Plus Service */ + DNS = 4, /* Domain Name Service */ + X500 = 5, /* ISO/CCCIT X.500 Service */ + DNANS = 6, /* Digital DECNet Name Service */ + XCHS = 7, /* Xerox ClearingHouse Service */ + CDS= 8 +}; + +/* + * DIRECTORY - The name service object. These objects identify other name + * servers that are serving some portion of the name space. Each has a + * type associated with it. The resolver library will note whether or not + * is has the needed routines to access that type of service. + * The oarmask structure defines an access rights mask on a per object + * type basis for the name spaces. The only bits currently used are + * create and destroy. By enabling or disabling these access rights for + * a specific object type for a one of the accessor entities (owner, + * group, world) the administrator can control what types of objects + * may be freely added to the name space and which require the + * administrator's approval. + */ +struct oar_mask { + u_long oa_rights; /* Access rights mask */ + zotypes oa_otype; /* Object type */ +}; + +struct endpoint { + string uaddr<>; + string family<>; /* Transport family (INET, OSI, etc) */ + string proto<>; /* Protocol (TCP, UDP, CLNP, etc) */ +}; + +/* + * Note: pkey is a netobj which is limited to 1024 bytes which limits the + * keysize to 8192 bits. This is consider to be a reasonable limit for + * the expected lifetime of this service. + */ +struct nis_server { + nis_name name; /* Principal name of the server */ + endpoint ep<>; /* Universal addr(s) for server */ + u_long key_type; /* Public key type */ + netobj pkey; /* server's public key */ +}; + +struct directory_obj { + nis_name do_name; /* Name of the directory being served */ + nstype do_type; /* one of NIS, DNS, IVY, YP, or X.500 */ + nis_server do_servers<>; /* <0> == Primary name server */ + u_long do_ttl; /* Time To Live (for caches) */ + oar_mask do_armask<>; /* Create/Destroy rights by object type */ +}; + +/* + * ENTRY - This is one row of data from an information base. + * The type value is used by the client library to convert the entry to + * it's internal structure representation. The Table name is a back pointer + * to the table where the entry is stored. This allows the client library + * to determine where to send a request if the client wishes to change this + * entry but got to it through a LINK rather than directly. + * If the entry is a "standalone" entry then this field is void. + */ +const EN_BINARY = 1; /* Indicates value is binary data */ +const EN_CRYPT = 2; /* Indicates the value is encrypted */ +const EN_XDR = 4; /* Indicates the value is XDR encoded */ +const EN_MODIFIED = 8; /* Indicates entry is modified. */ +const EN_ASN1 = 64; /* Means contents use ASN.1 encoding */ + +struct entry_col { + u_long ec_flags; /* Flags for this value */ + opaque ec_value<>; /* It's textual value */ +}; + +struct entry_obj { + string en_type<>; /* Type of entry such as "passwd" */ + entry_col en_cols<>; /* Value for the entry */ +}; + +/* + * GROUP - The group object contains a list of NIS principal names. Groups + * are used to authorize principals. Each object has a set of access rights + * for members of its group. Principal names in groups are in the form + * name.directory and recursive groups are expressed as @groupname.directory + */ +struct group_obj { + u_long gr_flags; /* Flags controlling group */ + nis_name gr_members<>; /* List of names in group */ +}; + +/* + * LINK - This is the LINK object. It is quite similar to a symbolic link + * in the UNIX filesystem. The attributes in the main object structure are + * relative to the LINK data and not what it points to (like the file system) + * "modify" privleges here indicate the right to modify what the link points + * at and not to modify that actual object pointed to by the link. + */ +struct link_obj { + zotypes li_rtype; /* Real type of the object */ + nis_attr li_attrs<>; /* Attribute/Values for tables */ + nis_name li_name; /* The object's real NIS name */ +}; + +/* + * TABLE - This is the table object. It implements a simple + * data base that applications and use for configuration or + * administration purposes. The role of the table is to group together + * a set of related entries. Tables are the simple database component + * of NIS. Like many databases, tables are logically divided into columns + * and rows. The columns are labeled with indexes and each ENTRY makes + * up a row. Rows may be addressed within the table by selecting one + * or more indexes, and values for those indexes. Each row which has + * a value for the given index that matches the desired value is returned. + * Within the definition of each column there is a flags variable, this + * variable contains flags which determine whether or not the column is + * searchable, contains binary data, and access rights for the entry objects + * column value. + */ + +const TA_BINARY = 1; /* Means table data is binary */ +const TA_CRYPT = 2; /* Means value should be encrypted */ +const TA_XDR = 4; /* Means value is XDR encoded */ +const TA_SEARCHABLE = 8; /* Means this column is searchable */ +const TA_CASE = 16; /* Means this column is Case Sensitive */ +const TA_MODIFIED = 32; /* Means this columns attrs are modified*/ +const TA_ASN1 = 64; /* Means contents use ASN.1 encoding */ + +struct table_col { + string tc_name<64>; /* Column Name */ + u_long tc_flags; /* control flags */ + u_long tc_rights; /* Access rights mask */ +}; + +struct table_obj { + string ta_type<64>; /* Table type such as "passwd" */ + int ta_maxcol; /* Total number of columns */ + u_char ta_sep; /* Separator character */ + table_col ta_cols<>; /* The number of table indexes */ + string ta_path<>; /* A search path for this table */ +}; + +/* + * This union joins together all of the currently known objects. + */ +union objdata switch (zotypes zo_type) { + case DIRECTORY_OBJ : + struct directory_obj di_data; + case GROUP_OBJ : + struct group_obj gr_data; + case TABLE_OBJ : + struct table_obj ta_data; + case ENTRY_OBJ: + struct entry_obj en_data; + case LINK_OBJ : + struct link_obj li_data; + case PRIVATE_OBJ : + opaque po_data<>; + case NO_OBJ : + void; + case BOGUS_OBJ : + void; + default : + void; +}; + +/* + * This is the basic NIS object data type. It consists of a generic part + * which all objects contain, and a specialized part which varies depending + * on the type of the object. All of the specialized sections have been + * described above. You might have wondered why they all start with an + * integer size, followed by the useful data. The answer is, when the + * server doesn't recognize the type returned it treats it as opaque data. + * And the definition for opaque data is {int size; char *data;}. In this + * way, servers and utility routines that do not understand a given type + * may still pass it around. One has to be careful in setting + * this variable accurately, it must take into account such things as + * XDR padding of structures etc. The best way to set it is to note one's + * position in the XDR encoding stream, encode the structure, look at the + * new position and calculate the size. + */ +struct nis_oid { + u_long ctime; /* Time of objects creation */ + u_long mtime; /* Time of objects modification */ +}; + +struct nis_object { + nis_oid zo_oid; /* object identity verifier. */ + nis_name zo_name; /* The NIS name for this object */ + nis_name zo_owner; /* NIS name of object owner. */ + nis_name zo_group; /* NIS name of access group. */ + nis_name zo_domain; /* The administrator for the object */ + u_long zo_access; /* Access rights (owner, group, world) */ + u_long zo_ttl; /* Object's time to live in seconds. */ + objdata zo_data; /* Data structure for this type */ +}; +#if RPC_HDR +% +%#endif /* if __nis_object_h */ +% +#endif diff --git a/cpukit/librpc/include/rpcsvc/nis_tags.h b/cpukit/librpc/include/rpcsvc/nis_tags.h index e69de29bb2..0eaee6d442 100644 --- a/cpukit/librpc/include/rpcsvc/nis_tags.h +++ b/cpukit/librpc/include/rpcsvc/nis_tags.h @@ -0,0 +1,137 @@ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * Copyright (c) 1991, Sun Microsystems Inc. + */ + +/* + * nis_tags.h + * + * This file contains the tags and statistics definitions. It is + * automatically included by nis.h + */ + +#ifndef _RPCSVC_NIS_TAGS_H +#define _RPCSVC_NIS_TAGS_H + +/* From: #pragma ident "@(#)nis_tags.h 1.10 94/05/03 SMI" */ +/* from file: zns_tags.h 1.7 Copyright (c) 1990 Sun Microsystems */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef ORIGINAL_DECLS +#define NIS_DIR "data" +#endif + +/* Lookup and List function flags */ +#define FOLLOW_LINKS (1<<0) /* Follow link objects */ +#define FOLLOW_PATH (1<<1) /* Follow the path in a table */ +#define HARD_LOOKUP (1<<2) /* Block until successful */ +#define ALL_RESULTS (1<<3) /* Retrieve all results */ +#define NO_CACHE (1<<4) /* Do not return 'cached' results */ +#define MASTER_ONLY (1<<5) /* Get value only from master server */ +#define EXPAND_NAME (1<<6) /* Expand partitially qualified names */ + +/* Semantic modification for table operations flags */ +#define RETURN_RESULT (1<<7) /* Return resulting object to client */ +#define ADD_OVERWRITE (1<<8) /* Allow overwrites on ADD */ +#define REM_MULTIPLE (1<<9) /* Allow wildcard deletes */ +#define MOD_SAMEOBJ (1<<10) /* Check modified object before write */ +#define ADD_RESERVED (1<<11) /* Spare ADD semantic */ +#define REM_RESERVED (1<<12) /* Spare REM semantic */ +#ifdef ORIGINAL_DECLS +#define MOD_RESERVED (1<<13) /* Spare MOD semantic */ +#else +#define MOD_EXCLUSIVE (1<<13) /* Modify no overwrite on modified keys */ +#endif + +/* Transport specific modifications to the operation */ +#define USE_DGRAM (1<<16) /* Use a datagram transport */ +#define NO_AUTHINFO (1<<17) /* Don't bother attaching auth info */ + +/* + * Declarations for "standard" NIS+ tags + * State variable tags have values 0 - 2047 + * Statistic tags have values 2048 - 65535 + * User Tags have values >2^16 + */ +#define TAG_DEBUG 1 /* set debug level */ +#define TAG_STATS 2 /* Enable/disable statistics */ +#define TAG_GCACHE 3 /* Flush the Group Cache */ +#ifndef ORIGINAL_DECLS +#define TAG_GCACHE_ALL TAG_GCACHE +#endif +#define TAG_DCACHE 4 /* Flush the directory cache */ +#ifndef ORIGINAL_DECLS +#define TAG_DCACHE_ONE TAG_DCACHE +#endif +#define TAG_OCACHE 5 /* Flush the Object Cache */ +#define TAG_SECURE 6 /* Set the security level */ +#ifndef ORIGINAL_DECLS +#define TAG_TCACHE_ONE 7 /* Flush the table cache */ +#define TAG_DCACHE_ALL 8 /* Flush entire directory cache */ +#define TAG_TCACHE_ALL 9 /* Flush entire table cache */ +#define TAG_GCACHE_ONE 10 /* Flush one group object */ +#define TAG_DCACHE_ONE_REFRESH 11 /* Flush and refresh one DO */ +#endif + +#define TAG_OPSTATS 2048 /* NIS+ operations statistics */ +#define TAG_THREADS 2049 /* Child process/thread status */ +#define TAG_HEAP 2050 /* Heap usage statistics */ +#define TAG_UPDATES 2051 /* Updates to this service */ +#define TAG_VISIBLE 2052 /* First update that isn't replicated */ +#define TAG_S_DCACHE 2053 /* Directory cache statistics */ +#define TAG_S_OCACHE 2054 /* Object cache statistics */ +#define TAG_S_GCACHE 2055 /* Group cache statistics */ +#define TAG_S_STORAGE 2056 /* Group cache statistics */ +#define TAG_UPTIME 2057 /* Time that server has been up */ +#ifndef ORIGINAL_DECLS +#define TAG_DIRLIST 2058 /* Dir served by this server */ +#define TAG_NISCOMPAT 2059 /* Whether supports NIS compat mode */ +#define TAG_DNSFORWARDING 2060 /* Whether DNS forwarding supported*/ +#define TAG_SECURITY_LEVEL 2061 /* Security level of the server */ +#define TAG_ROOTSERVER 2062 /* Whether root server */ +#endif + +/* + * Declarations for the Group object flags. Currently + * there are only 3. + */ +#define IMPMEM_GROUPS 1 /* Implicit Membership allowed */ +#define RECURS_GROUPS 2 /* Recursive Groups allowed */ +#define NEGMEM_GROUPS 4 /* Negative Groups allowed */ + +#ifdef __cplusplus +} +#endif + +#endif /* _RPCSVC_NIS_TAGS_H */ diff --git a/cpukit/librpc/include/rpcsvc/nislib.h b/cpukit/librpc/include/rpcsvc/nislib.h index e69de29bb2..9f874d270e 100644 --- a/cpukit/librpc/include/rpcsvc/nislib.h +++ b/cpukit/librpc/include/rpcsvc/nislib.h @@ -0,0 +1,317 @@ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * Copyright (c) 1991, Sun Microsystems Inc. + */ + +/* + * This file contains the interfaces that are visible in the SunOS 5.x + * implementation of NIS Plus. When using C++ the defined __cplusplus and + * __STDC__ should both be true. + */ + +#ifndef _RPCSVC_NISLIB_H +#define _RPCSVC_NISLIB_H + +/* From: #pragma ident "@(#)nislib.h 1.16 94/05/03 SMI" */ + +#ifdef __cplusplus +extern "C" { +#endif + +struct signature { + int signature_len; + char *signature_val; +}; + +#ifdef __STDC__ +extern void nis_freeresult(nis_result *); +extern nis_result * nis_lookup(nis_name, u_long); +extern nis_result * nis_list(nis_name, u_long, + int (*)(nis_name, nis_object *, void *), void *); +extern nis_result * nis_add(nis_name, nis_object *); +extern nis_result * nis_remove(nis_name, nis_object *); +extern nis_result * nis_modify(nis_name, nis_object *); + +extern nis_result * nis_add_entry(nis_name, nis_object *, u_long); +extern nis_result * nis_remove_entry(nis_name, nis_object *, u_long); +extern nis_result * nis_modify_entry(nis_name, nis_object *, u_long); +extern nis_result * nis_first_entry(nis_name); +extern nis_result * nis_next_entry(nis_name, netobj *); + +extern nis_error nis_mkdir(nis_name, nis_server *); +extern nis_error nis_rmdir(nis_name, nis_server *); +extern name_pos nis_dir_cmp(nis_name, nis_name); + +extern nis_name * nis_getnames(nis_name); +extern void nis_freenames(nis_name *); +extern nis_name nis_domain_of(nis_name); +extern nis_name nis_leaf_of(nis_name); +extern nis_name nis_leaf_of_r(const nis_name, char *, size_t); +extern nis_name nis_name_of(nis_name); +extern nis_name nis_local_group(void); +extern nis_name nis_local_directory(void); +extern nis_name nis_local_principal(void); +extern nis_name nis_local_host(void); + +extern void nis_destroy_object(nis_object *); +extern nis_object * nis_clone_object(nis_object *, nis_object *); +extern void nis_print_object(nis_object *); + +extern char * nis_sperrno(nis_error); +extern void nis_perror(nis_error, char *); +extern char * nis_sperror(nis_error, char *); +extern void nis_lerror(nis_error, char *); + +extern void nis_print_group_entry(nis_name); +extern bool_t nis_ismember(nis_name, nis_name); +extern nis_error nis_creategroup(nis_name, u_long); +extern nis_error nis_destroygroup(nis_name); +extern nis_error nis_addmember(nis_name, nis_name); +extern nis_error nis_removemember(nis_name, nis_name); +extern nis_error nis_verifygroup(nis_name); + +extern void nis_freeservlist(nis_server **); +extern nis_server ** nis_getservlist(nis_name); +extern nis_error nis_stats(nis_server *, nis_tag *, int, nis_tag **); +extern nis_error nis_servstate(nis_server *, nis_tag *, int, nis_tag **); +extern void nis_freetags(nis_tag *, int); + +extern nis_result * nis_checkpoint(nis_name); +extern void nis_ping(nis_name, u_long, nis_object *); + +/* + * XXX: PLEASE NOTE THAT THE FOLLOWING FUNCTIONS ARE INTERNAL + * TO NIS+ AND SHOULD NOT BE USED BY ANY APPLICATION PROGRAM. + * THEIR SEMANTICS AND/OR SIGNATURE CAN CHANGE WITHOUT NOTICE. + * SO, PLEASE DO NOT USE THEM. YOU ARE WARNED!!!! + */ + +extern char ** __break_name(nis_name, int *); +extern int __name_distance(char **, char **); +extern nis_result * nis_make_error(nis_error, u_long, u_long, u_long, u_long); +extern nis_attr * __cvt2attr(int *, char **); +extern void nis_free_request(ib_request *); +extern nis_error nis_get_request(nis_name, nis_object *, netobj*, ib_request*); +extern nis_object * nis_read_obj(char *); +extern int nis_write_obj(char *, nis_object *); +extern int nis_in_table(nis_name, NIS_HASH_TABLE *, int *); +extern int nis_insert_item(NIS_HASH_ITEM *, NIS_HASH_TABLE *); +extern NIS_HASH_ITEM * nis_find_item(nis_name, NIS_HASH_TABLE *); +extern NIS_HASH_ITEM * nis_remove_item(nis_name, NIS_HASH_TABLE *); +extern void nis_insert_name(nis_name, NIS_HASH_TABLE *); +extern void nis_remove_name(nis_name, NIS_HASH_TABLE *); +extern CLIENT * nis_make_rpchandle(nis_server *, int, u_long, u_long, u_long, + int, int); +extern void * nis_get_static_storage(struct nis_sdata *, u_long, u_long); +extern char * nis_data(char *); +extern void nis_print_rights(u_long); +extern void nis_print_directory(directory_obj *); +extern void nis_print_group(group_obj *); +extern void nis_print_table(table_obj *); +extern void nis_print_link(link_obj *); +extern void nis_print_entry(entry_obj *); +extern nis_object * nis_get_object(char *, char *, char *, u_long, u_long, + zotypes); +extern nis_server * __nis_init_callback(CLIENT *, + int (*)(nis_name, nis_object *, void *), void *); +extern int nis_getdtblsize(void); +extern int __nis_run_callback(netobj *, u_long, struct timeval *, CLIENT *); + +extern log_result *nis_dumplog(nis_server *, nis_name, u_long); +extern log_result *nis_dump(nis_server *, nis_name, + int (*)(nis_name, nis_object *, void *)); + +extern bool_t __do_ismember(nis_name, nis_name, + nis_result *(*)(nis_name, u_long)); +extern nis_name __nis_map_group(nis_name); +extern nis_name __nis_map_group_r(nis_name, char*, size_t); + +extern nis_error __nis_CacheBind(char *, directory_obj *); +extern nis_error __nis_CacheSearch(char *, directory_obj *); +extern bool_t __nis_CacheRemoveEntry(directory_obj *); +extern void __nis_CacheRestart(void); +extern void __nis_CachePrint(void); +extern void __nis_CacheDumpStatistics(void); +extern bool_t writeColdStartFile(directory_obj *); + +extern CLIENT * __get_ti_clnt(char *, CLIENT *, char **, pid_t *); +extern int __strcmp_case_insens(char *, char *); +extern int __strncmp_case_insens(char *, char *); + +extern fd_result * nis_finddirectory(directory_obj *, nis_name); +extern int __start_clock(int); +extern u_long __stop_clock(int); + +/* + * This particular function is part of the FreeBSD NIS+ implementation + * only. Ideally it should be somewhere else, but it is used by both + * rpc.nisd and nis_cachemgr, and there aren't that many headers common + * to both programs. + */ + +extern struct signature *__nis_calculate_encrypted_cksum(unsigned char *, unsigned int, char *, int); + +#else + +/* Non-prototype definitions (old fashioned C) */ + +extern void nis_freeresult(); +extern nis_result * nis_lookup(); +extern nis_result * nis_list(); +extern nis_result * nis_add(); +extern nis_result * nis_remove(); +extern nis_result * nis_modify(); + +extern nis_result * nis_add_entry(); +extern nis_result * nis_remove_entry(); +extern nis_result * nis_modify_entry(); +extern nis_result * nis_first_entry(); +extern nis_result * nis_next_entry(); + +extern nis_error nis_mkdir(); +extern nis_error nis_rmdir(); +extern name_pos nis_dir_cmp(); + +extern nis_name *nis_getnames(); +extern void nis_freenames(); +extern nis_name nis_domain_of(); +extern nis_name nis_leaf_of(); +extern nis_name nis_leaf_of_r(); +extern nis_name nis_name_of(); +extern nis_name nis_local_group(); +extern nis_name nis_local_directory(); +extern nis_name nis_local_principal(); +extern nis_name nis_local_host(); + +extern void nis_destroy_object(); +extern nis_object * nis_clone_object(); +extern void nis_print_object(); + +extern char * nis_sperrno(); +extern void nis_perror(); +extern char * nis_sperror(); +extern void nis_lerror(); + +extern void nis_print_group_entry(); +extern bool_t nis_ismember(); +extern nis_error nis_creategroup(); +extern nis_error nis_destroygroup(); +extern nis_error nis_addmember(); +extern nis_error nis_removemember(); +extern nis_error nis_verifygroup(); + +extern void nis_freeservlist(); +extern nis_server ** nis_getservlist(); +extern nis_error nis_stats(); +extern nis_error nis_servstate(); +extern void nis_freetags(); + +extern nis_result * nis_checkpoint(); +extern void nis_ping(); + +/* + * XXX: PLEASE NOTE THAT THE FOLLOWING FUNCTIONS ARE INTERNAL + * TO NIS+ AND SHOULD NOT BE USED BY ANY APPLICATION PROGRAM. + * THEIR SEMANTICS AND/OR SIGNATURE CAN CHANGE WITHOUT NOTICE. + * SO, PLEASE DO NOT USE THEM. YOU ARE WARNED!!!! + */ +extern char ** __break_name(); +extern int __name_distance(); +extern nis_result * nis_make_error(); +extern nis_attr * __cvt2attr(); +extern void nis_free_request(); +extern nis_error nis_get_request(); +extern nis_object * nis_read_obj(); +extern int nis_write_obj(); +extern int nis_in_table(); +extern int nis_insert_item(); +extern NIS_HASH_ITEM * nis_find_item(); +extern NIS_HASH_ITEM * nis_remove_item(); +extern void nis_insert_name(); +extern void nis_remove_name(); +extern CLIENT * nis_make_rpchandle(); +extern void * nis_get_static_storage(); +extern char * nis_data(); + +extern void nis_print_rights(); +extern void nis_print_directory(); +extern void nis_print_group(); +extern void nis_print_table(); +extern void nis_print_link(); +extern void nis_print_entry(); +extern nis_object * nis_get_object(); + +extern nis_server * __nis_init_callback(); +extern int nis_getdtblsize(); +extern int __nis_run_callback(); + +extern log_result * nis_dump(); +extern log_result * nis_dumplog(); + +extern bool_t __do_ismember(); +extern nis_name __nis_map_group(); +extern nis_name __nis_map_group_r(); + + +extern nis_error __nis_CacheBind(); +extern directory_obj * __nis_CacheSearch(); +extern bool_t __nis_CacheRemoveEntry(); +extern void __nis_CacheRestart(); +extern void __nis_CachePrint(); +extern void __nis_CacheDumpStatistics(); +extern bool_t writeColdStartFile(); + +extern CLIENT * __get_ti_clnt(); +extern int __strcmp_case_insens(); +extern int __strncmp_case_insens(); + +extern fd_result * nis_finddirectory(); +extern int __start_clock(); +extern u_long __stop_clock(); + +/* + * This particular function is part of the FreeBSD NIS+ implementation + * only. Ideally it should be somewhere else, but it is used by both + * rpc.nisd and nis_cachemgr, and there aren't that many headers common + * to both programs. + */ + +extern struct signature *__nis_calculate_encrypted_cksum(); + +#endif + +#define NUL '\0' + +#ifdef __cplusplus +} +#endif + +#endif /* _RPCSVC_NISLIB_H */ diff --git a/cpukit/librpc/include/rpcsvc/nlm_prot.x b/cpukit/librpc/include/rpcsvc/nlm_prot.x index e69de29bb2..675bb6d1bc 100644 --- a/cpukit/librpc/include/rpcsvc/nlm_prot.x +++ b/cpukit/librpc/include/rpcsvc/nlm_prot.x @@ -0,0 +1,184 @@ +/* @(#)nlm_prot.x 2.1 88/08/01 4.0 RPCSRC */ +/* @(#)nlm_prot.x 1.8 87/09/21 Copyr 1987 Sun Micro */ + +/* + * Network lock manager protocol definition + * Copyright (C) 1986 Sun Microsystems, Inc. + * + * protocol used between local lock manager and remote lock manager + */ + +#ifdef RPC_HDR +%#define LM_MAXSTRLEN 1024 +%#define MAXNAMELEN LM_MAXSTRLEN+1 +#else +%#ifndef lint +%static const char rcsid[] = +% "$FreeBSD: src/include/rpcsvc/nlm_prot.x,v 1.8 1999/08/27 23:45:10 peter Exp $"; +%#endif /* not lint */ +#endif + +/* + * status of a call to the lock manager + */ +enum nlm_stats { + nlm_granted = 0, + nlm_denied = 1, + nlm_denied_nolocks = 2, + nlm_blocked = 3, + nlm_denied_grace_period = 4 +}; + +struct nlm_holder { + bool exclusive; + int svid; + netobj oh; + unsigned l_offset; + unsigned l_len; +}; + +union nlm_testrply switch (nlm_stats stat) { + case nlm_denied: + struct nlm_holder holder; + default: + void; +}; + +struct nlm_stat { + nlm_stats stat; +}; + +struct nlm_res { + netobj cookie; + nlm_stat stat; +}; + +struct nlm_testres { + netobj cookie; + nlm_testrply stat; +}; + +struct nlm_lock { + string caller_name<LM_MAXSTRLEN>; + netobj fh; /* identify a file */ + netobj oh; /* identify owner of a lock */ + int svid; /* generated from pid for svid */ + unsigned l_offset; + unsigned l_len; +}; + +struct nlm_lockargs { + netobj cookie; + bool block; + bool exclusive; + struct nlm_lock alock; + bool reclaim; /* used for recovering locks */ + int state; /* specify local status monitor state */ +}; + +struct nlm_cancargs { + netobj cookie; + bool block; + bool exclusive; + struct nlm_lock alock; +}; + +struct nlm_testargs { + netobj cookie; + bool exclusive; + struct nlm_lock alock; +}; + +struct nlm_unlockargs { + netobj cookie; + struct nlm_lock alock; +}; + + +#ifdef RPC_HDR +%/* +% * The following enums are actually bit encoded for efficient +% * boolean algebra.... DON'T change them..... +% */ +#endif +enum fsh_mode { + fsm_DN = 0, /* deny none */ + fsm_DR = 1, /* deny read */ + fsm_DW = 2, /* deny write */ + fsm_DRW = 3 /* deny read/write */ +}; + +enum fsh_access { + fsa_NONE = 0, /* for completeness */ + fsa_R = 1, /* read only */ + fsa_W = 2, /* write only */ + fsa_RW = 3 /* read/write */ +}; + +struct nlm_share { + string caller_name<LM_MAXSTRLEN>; + netobj fh; + netobj oh; + fsh_mode mode; + fsh_access access; +}; + +struct nlm_shareargs { + netobj cookie; + nlm_share share; + bool reclaim; +}; + +struct nlm_shareres { + netobj cookie; + nlm_stats stat; + int sequence; +}; + +struct nlm_notify { + string name<MAXNAMELEN>; + long state; +}; + +/* + * Over-the-wire protocol used between the network lock managers + */ + +program NLM_PROG { + version NLM_VERS { + + nlm_testres NLM_TEST(struct nlm_testargs) = 1; + + nlm_res NLM_LOCK(struct nlm_lockargs) = 2; + + nlm_res NLM_CANCEL(struct nlm_cancargs) = 3; + nlm_res NLM_UNLOCK(struct nlm_unlockargs) = 4; + + /* + * remote lock manager call-back to grant lock + */ + nlm_res NLM_GRANTED(struct nlm_testargs)= 5; + /* + * message passing style of requesting lock + */ + void NLM_TEST_MSG(struct nlm_testargs) = 6; + void NLM_LOCK_MSG(struct nlm_lockargs) = 7; + void NLM_CANCEL_MSG(struct nlm_cancargs) =8; + void NLM_UNLOCK_MSG(struct nlm_unlockargs) = 9; + void NLM_GRANTED_MSG(struct nlm_testargs) = 10; + void NLM_TEST_RES(nlm_testres) = 11; + void NLM_LOCK_RES(nlm_res) = 12; + void NLM_CANCEL_RES(nlm_res) = 13; + void NLM_UNLOCK_RES(nlm_res) = 14; + void NLM_GRANTED_RES(nlm_res) = 15; + } = 1; + + version NLM_VERSX { + nlm_shareres NLM_SHARE(nlm_shareargs) = 20; + nlm_shareres NLM_UNSHARE(nlm_shareargs) = 21; + nlm_res NLM_NM_LOCK(nlm_lockargs) = 22; + void NLM_FREE_ALL(nlm_notify) = 23; + } = 3; + +} = 100021; + diff --git a/cpukit/librpc/include/rpcsvc/pmap_prot.x b/cpukit/librpc/include/rpcsvc/pmap_prot.x index e69de29bb2..d90e2c503b 100644 --- a/cpukit/librpc/include/rpcsvc/pmap_prot.x +++ b/cpukit/librpc/include/rpcsvc/pmap_prot.x @@ -0,0 +1,285 @@ +%/* +% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for +% * unrestricted use provided that this legend is included on all tape +% * media and as a part of the software program in whole or part. Users +% * may copy or modify Sun RPC without charge, but are not authorized +% * to license or distribute it to anyone else except as part of a product or +% * program developed by the user. +% * +% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE +% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR +% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. +% * +% * Sun RPC is provided with no support and without any obligation on the +% * part of Sun Microsystems, Inc. to assist in its use, correction, +% * modification or enhancement. +% * +% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE +% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC +% * OR ANY PART THEREOF. +% * +% * In no event will Sun Microsystems, Inc. be liable for any lost revenue +% * or profits or other special, indirect and consequential damages, even if +% * Sun has been advised of the possibility of such damages. +% * +% * Sun Microsystems, Inc. +% * 2550 Garcia Avenue +% * Mountain View, California 94043 +% */ +%/* +% * Copyright (c) 1984,1989 by Sun Microsystems, Inc. +% */ + +%/* from pmap_prot.x */ + +#ifdef RPC_HDR +% +%#pragma ident "@(#)pmap_prot.x 1.6 94/04/29 SMI" +% +%#ifndef _KERNEL +% +#endif + +/* + * Port Mapper Protocol Specification (in RPC Language) + * derived from RFC 1057 + */ + +%/* +% * Protocol for the local binder service, or pmap. +% * +% * Copyright (C) 1984, Sun Microsystems, Inc. +% * +% * The following procedures are supported by the protocol: +% * +% * PMAPPROC_NULL() returns () +% * takes nothing, returns nothing +% * +% * PMAPPROC_SET(struct pmap) returns (bool_t) +% * TRUE is success, FALSE is failure. Registers the tuple +% * [prog, vers, prot, port]. +% * +% * PMAPPROC_UNSET(struct pmap) returns (bool_t) +% * TRUE is success, FALSE is failure. Un-registers pair +% * [prog, vers]. prot and port are ignored. +% * +% * PMAPPROC_GETPORT(struct pmap) returns (long unsigned). +% * 0 is failure. Otherwise returns the port number where the pair +% * [prog, vers] is registered. It may lie! +% * +% * PMAPPROC_DUMP() RETURNS (struct pmaplist_ptr) +% * +% * PMAPPROC_CALLIT(unsigned, unsigned, unsigned, string<>) +% * RETURNS (port, string<>); +% * usage: encapsulatedresults = PMAPPROC_CALLIT(prog, vers, proc, +% * encapsulatedargs); +% * Calls the procedure on the local machine. If it is not registered, +% * this procedure is quite; ie it does not return error information!!! +% * This procedure only is supported on rpc/udp and calls via +% * rpc/udp. This routine only passes null authentication parameters. +% * This file has no interface to xdr routines for PMAPPROC_CALLIT. +% * +% * The service supports remote procedure calls on udp/ip or tcp/ip socket 111. +% */ +% +const PMAPPORT = 111; /* portmapper port number */ +% +% +%/* +% * A mapping of (program, version, protocol) to port number +% */ + +struct pmap { + unsigned long pm_prog; + unsigned long pm_vers; + unsigned long pm_prot; + unsigned long pm_port; +}; +#ifdef RPC_HDR +% +%typedef pmap PMAP; +% +#endif +% +%/* +% * Supported values for the "prot" field +% */ +% +const PMAP_IPPROTO_TCP = 6; /* protocol number for TCP/IP */ +const PMAP_IPPROTO_UDP = 17; /* protocol number for UDP/IP */ +% +% +%/* +% * A list of mappings +% * +% * Below are two definitions for the pmaplist structure. This is done because +% * xdr_pmaplist() is specified to take a struct pmaplist **, rather than a +% * struct pmaplist * that rpcgen would produce. One version of the pmaplist +% * structure (actually called pm__list) is used with rpcgen, and the other is +% * defined only in the header file for compatibility with the specified +% * interface. +% */ + +struct pm__list { + pmap pml_map; + struct pm__list *pml_next; +}; + +typedef pm__list *pmaplist_ptr; /* results of PMAPPROC_DUMP */ + +#ifdef RPC_HDR +% +%typedef struct pm__list pmaplist; +%typedef struct pm__list PMAPLIST; +% +%#ifndef __cplusplus +%struct pmaplist { +% PMAP pml_map; +% struct pmaplist *pml_next; +%}; +%#endif +% +%#ifdef __cplusplus +%extern "C" { +%#endif +%#ifdef __STDC__ +%extern bool_t xdr_pmaplist(XDR *, pmaplist**); +%#else /* K&R C */ +%bool_t xdr_pmaplist(); +%#endif +%#ifdef __cplusplus +%} +%#endif +% +#endif + +% +%/* +% * Arguments to callit +% */ + +struct rmtcallargs { + unsigned long prog; + unsigned long vers; + unsigned long proc; + opaque args<>; +}; +#ifdef RPC_HDR +% +%/* +% * Client-side only representation of rmtcallargs structure. +% * +% * The routine that XDRs the rmtcallargs structure must deal with the +% * opaque arguments in the "args" structure. xdr_rmtcall_args() needs to be +% * passed the XDR routine that knows the args' structure. This routine +% * doesn't need to go over-the-wire (and it wouldn't make sense anyway) since +% * the application being called knows the args structure already. So we use a +% * different "XDR" structure on the client side, p_rmtcallargs, which includes +% * the args' XDR routine. +% */ +%struct p_rmtcallargs { +% u_long prog; +% u_long vers; +% u_long proc; +% struct { +% u_int args_len; +% char *args_val; +% } args; +% xdrproc_t xdr_args; /* encodes args */ +%}; +% +#endif /* def RPC_HDR */ +% +% +%/* +% * Results of callit +% */ + +struct rmtcallres { + unsigned long port; + opaque res<>; +}; +#ifdef RPC_HDR +% +%/* +% * Client-side only representation of rmtcallres structure. +% */ +%struct p_rmtcallres { +% u_long port; +% struct { +% u_int res_len; +% char *res_val; +% } res; +% xdrproc_t xdr_res; /* decodes res */ +%}; +% +#endif /* def RPC_HDR */ + +/* + * Port mapper procedures + */ + +program PMAPPROG { + version PMAPVERS { + void + PMAPPROC_NULL(void) = 0; + + bool + PMAPPROC_SET(pmap) = 1; + + bool + PMAPPROC_UNSET(pmap) = 2; + + unsigned long + PMAPPROC_GETPORT(pmap) = 3; + + pmaplist_ptr + PMAPPROC_DUMP(void) = 4; + + rmtcallres + PMAPPROC_CALLIT(rmtcallargs) = 5; + } = 2; +} = 100000; +% +#ifdef RPC_HDR +%#define PMAPVERS_PROTO ((u_long)2) +%#define PMAPVERS_ORIG ((u_long)1) +% +%#else /* ndef _KERNEL */ +% +%#include <rpc/pmap_rmt.h> +% +%#ifdef __cplusplus +%extern "C" { +%#endif +% +%#define PMAPPORT 111 +% +%struct pmap { +% long unsigned pm_prog; +% long unsigned pm_vers; +% long unsigned pm_prot; +% long unsigned pm_port; +%}; +%typedef struct pmap PMAP; +%#ifdef __STDC__ +%extern bool_t xdr_pmap (XDR *, struct pmap *); +%#else +%extern bool_t xdr_pmap (); +%#endif +% +%struct pmaplist { +% struct pmap pml_map; +% struct pmaplist *pml_next; +%}; +%typedef struct pmaplist PMAPLIST; +%typedef struct pmaplist *pmaplist_ptr; +% +% +%#ifdef __cplusplus +%} +%#endif +% +%#endif /* ndef _KERNEL */ +#endif + diff --git a/cpukit/librpc/include/rpcsvc/rex.x b/cpukit/librpc/include/rpcsvc/rex.x index e69de29bb2..928efa21e7 100644 --- a/cpukit/librpc/include/rpcsvc/rex.x +++ b/cpukit/librpc/include/rpcsvc/rex.x @@ -0,0 +1,235 @@ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * Remote execution (rex) protocol specification + */ + +#ifndef RPC_HDR +%#ifndef lint +%/*static char sccsid[] = "from: @(#)rex.x 1.3 87/09/18 Copyr 1987 Sun Micro";*/ +%/*static char sccsid[] = "from: @(#)rex.x 2.1 88/08/01 4.0 RPCSRC";*/ +%static const char rcsid[] = +% "$FreeBSD: src/include/rpcsvc/rex.x,v 1.6 1999/08/27 23:45:10 peter Exp $"; +%#endif /* not lint */ +#endif + +const STRINGSIZE = 1024; +typedef string rexstring<1024>; + +/* + * values to pass to REXPROC_SIGNAL + */ +const SIGINT = 2; /* interrupt */ + +/* + * Values for rst_flags, below + */ +const REX_INTERACTIVE = 1; /* interactive mode */ + +struct rex_start { + rexstring rst_cmd<>; /* list of command and args */ + rexstring rst_host; /* working directory host name */ + rexstring rst_fsname; /* working directory file system name */ + rexstring rst_dirwithin;/* working directory within file system */ + rexstring rst_env<>; /* list of environment */ + unsigned int rst_port0; /* port for stdin */ + unsigned int rst_port1; /* port for stdout */ + unsigned int rst_port2; /* port for stderr */ + unsigned int rst_flags; /* options - see const above */ +}; + +struct rex_result { + int rlt_stat; /* integer status code */ + rexstring rlt_message; /* string message for human consumption */ +}; + + +struct sgttyb { + unsigned four; /* always equals 4 */ + opaque chars[4]; + /* chars[0] == input speed */ + /* chars[1] == output speed */ + /* chars[2] == kill character */ + /* chars[3] == erase character */ + unsigned flags; +}; +/* values for speeds above (baud rates) */ +const B0 = 0; +const B50 = 1; +const B75 = 2; +const B110 = 3; +const B134 = 4; +const B150 = 5; +const B200 = 6; +const B300 = 7; +const B600 = 8; +const B1200 = 9; +const B1800 = 10; +const B2400 = 11; +const B4800 = 12; +const B9600 = 13; +const B19200 = 14; +const B38400 = 15; + +/* values for flags above */ +const TANDEM = 0x00000001; /* send stopc on out q full */ +const CBREAK = 0x00000002; /* half-cooked mode */ +const LCASE = 0x00000004; /* simulate lower case */ +const ECHO = 0x00000008; /* echo input */ +const CRMOD = 0x00000010; /* map \r to \r\n on output */ +const RAW = 0x00000020; /* no i/o processing */ +const ODDP = 0x00000040; /* get/send odd parity */ +const EVENP = 0x00000080; /* get/send even parity */ +const ANYP = 0x000000c0; /* get any parity/send none */ +const NLDELAY = 0x00000300; /* \n delay */ +const NL0 = 0x00000000; +const NL1 = 0x00000100; /* tty 37 */ +const NL2 = 0x00000200; /* vt05 */ +const NL3 = 0x00000300; +const TBDELAY = 0x00000c00; /* horizontal tab delay */ +const TAB0 = 0x00000000; +const TAB1 = 0x00000400; /* tty 37 */ +const TAB2 = 0x00000800; +const XTABS = 0x00000c00; /* expand tabs on output */ +const CRDELAY = 0x00003000; /* \r delay */ +const CR0 = 0x00000000; +const CR1 = 0x00001000; /* tn 300 */ +const CR2 = 0x00002000; /* tty 37 */ +const CR3 = 0x00003000; /* concept 100 */ +const VTDELAY = 0x00004000; /* vertical tab delay */ +const FF0 = 0x00000000; +const FF1 = 0x00004000; /* tty 37 */ +const BSDELAY = 0x00008000; /* \b delay */ +const BS0 = 0x00000000; +const BS1 = 0x00008000; +const CRTBS = 0x00010000; /* do backspacing for crt */ +const PRTERA = 0x00020000; /* \ ... / erase */ +const CRTERA = 0x00040000; /* " \b " to wipe out char */ +const TILDE = 0x00080000; /* hazeltine tilde kludge */ +const MDMBUF = 0x00100000; /* start/stop output on carrier intr */ +const LITOUT = 0x00200000; /* literal output */ +const TOSTOP = 0x00400000; /* SIGTTOU on background output */ +const FLUSHO = 0x00800000; /* flush output to terminal */ +const NOHANG = 0x01000000; /* no SIGHUP on carrier drop */ +const L001000 = 0x02000000; +const CRTKIL = 0x04000000; /* kill line with " \b " */ +const PASS8 = 0x08000000; +const CTLECH = 0x10000000; /* echo control chars as ^X */ +const PENDIN = 0x20000000; /* tp->t_rawq needs reread */ +const DECCTQ = 0x40000000; /* only ^Q starts after ^S */ +const NOFLSH = 0x80000000; /* no output flush on signal */ + +struct tchars { + unsigned six; /* always equals 6 */ + opaque chars[6]; + /* chars[0] == interrupt char */ + /* chars[1] == quit char */ + /* chars[2] == start output char */ + /* chars[3] == stop output char */ + /* chars[4] == end-of-file char */ + /* chars[5] == input delimeter (like nl) */ +}; + +struct ltchars { + unsigned six; /* always equals 6 */ + opaque chars[6]; + /* chars[0] == stop process signal */ + /* chars[1] == delayed stop process signal */ + /* chars[2] == reprint line */ + /* chars[3] == flush output */ + /* chars[4] == word erase */ + /* chars[5] == literal next character */ + unsigned mode; +}; + +struct rex_ttysize { + int ts_lines; + int ts_cols; +}; + +struct rex_ttymode { + sgttyb basic; /* standard unix tty flags */ + tchars more; /* interrupt, kill characters, etc. */ + ltchars yetmore; /* special Berkeley characters */ + unsigned andmore; /* and Berkeley modes */ +}; + +/* values for andmore above */ +const LCRTBS = 0x0001; /* do backspacing for crt */ +const LPRTERA = 0x0002; /* \ ... / erase */ +const LCRTERA = 0x0004; /* " \b " to wipe out char */ +const LTILDE = 0x0008; /* hazeltine tilde kludge */ +const LMDMBUF = 0x0010; /* start/stop output on carrier intr */ +const LLITOUT = 0x0020; /* literal output */ +const LTOSTOP = 0x0040; /* SIGTTOU on background output */ +const LFLUSHO = 0x0080; /* flush output to terminal */ +const LNOHANG = 0x0100; /* no SIGHUP on carrier drop */ +const LL001000 = 0x0200; +const LCRTKIL = 0x0400; /* kill line with " \b " */ +const LPASS8 = 0x0800; +const LCTLECH = 0x1000; /* echo control chars as ^X */ +const LPENDIN = 0x2000; /* needs reread */ +const LDECCTQ = 0x4000; /* only ^Q starts after ^S */ +const LNOFLSH = 0x8000; /* no output flush on signal */ + +program REXPROG { + version REXVERS { + + /* + * Start remote execution + */ + rex_result + REXPROC_START(rex_start) = 1; + + /* + * Wait for remote execution to terminate + */ + rex_result + REXPROC_WAIT(void) = 2; + + /* + * Send tty modes + */ + void + REXPROC_MODES(rex_ttymode) = 3; + + /* + * Send window size change + */ + void + REXPROC_WINCH(rex_ttysize) = 4; + + /* + * Send other signal + */ + void + REXPROC_SIGNAL(int) = 5; + } = 1; +} = 100017; diff --git a/cpukit/librpc/include/rpcsvc/rnusers.x b/cpukit/librpc/include/rpcsvc/rnusers.x index e69de29bb2..f862c6192b 100644 --- a/cpukit/librpc/include/rpcsvc/rnusers.x +++ b/cpukit/librpc/include/rpcsvc/rnusers.x @@ -0,0 +1,123 @@ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * Find out about remote users + */ + +#ifndef RPC_HDR +%#ifndef lint +%/*static char sccsid[] = "from: @(#)rnusers.x 1.2 87/09/20 Copyr 1987 Sun Micro";*/ +%/*static char sccsid[] = "from: @(#)rnusers.x 2.1 88/08/01 4.0 RPCSRC";*/ +%static const char rcsid[] = +% "$FreeBSD: src/include/rpcsvc/rnusers.x,v 1.6 1999/08/27 23:45:10 peter Exp $"; +%#endif /* not lint */ +#endif + +const MAXUSERS = 100; +const MAXUTLEN = 256; + +struct utmp { + string ut_line<MAXUTLEN>; + string ut_name<MAXUTLEN>; + string ut_host<MAXUTLEN>; + int ut_time; +}; + + +struct utmpidle { + utmp ui_utmp; + unsigned int ui_idle; +}; + +typedef utmp utmparr<MAXUSERS>; + +typedef utmpidle utmpidlearr<MAXUSERS>; + +const RUSERS_MAXUSERLEN = 32; +const RUSERS_MAXLINELEN = 32; +const RUSERS_MAXHOSTLEN = 257; + +struct rusers_utmp { + string ut_user<RUSERS_MAXUSERLEN>; /* aka ut_name */ + string ut_line<RUSERS_MAXLINELEN>; /* device */ + string ut_host<RUSERS_MAXHOSTLEN>; /* host user logged on from */ + int ut_type; /* type of entry */ + int ut_time; /* time entry was made */ + unsigned int ut_idle; /* minutes idle */ +}; + +typedef rusers_utmp utmp_array<>; + +program RUSERSPROG { + /* + * Old version does not include idle information + */ + version RUSERSVERS_ORIG { + int + RUSERSPROC_NUM(void) = 1; + + utmparr + RUSERSPROC_NAMES(void) = 2; + + utmparr + RUSERSPROC_ALLNAMES(void) = 3; + } = 1; + + /* + * Includes idle information + */ + version RUSERSVERS_IDLE { + int + RUSERSPROC_NUM(void) = 1; + + utmpidlearr + RUSERSPROC_NAMES(void) = 2; + + utmpidlearr + RUSERSPROC_ALLNAMES(void) = 3; + } = 2; + + /* + * Version 3 rusers procedures (from Solaris). + * (Thanks a lot Sun.) + */ + version RUSERSVERS_3 { + int + RUSERSPROC_NUM(void) = 1; + + utmp_array + RUSERSPROC_NAMES(void) = 2; + + utmp_array + RUSERSPROC_ALLNAMES(void) = 3; + } = 3; + +} = 100002; + diff --git a/cpukit/librpc/include/rpcsvc/rquota.x b/cpukit/librpc/include/rpcsvc/rquota.x index e69de29bb2..72864d1c69 100644 --- a/cpukit/librpc/include/rpcsvc/rquota.x +++ b/cpukit/librpc/include/rpcsvc/rquota.x @@ -0,0 +1,67 @@ +/* + * Remote quota protocol + * Requires unix authentication + */ + +#ifndef RPC_HDR +%#ifndef lint +%/*static char sccsid[] = "from: @(#)rquota.x 1.2 87/09/20 Copyr 1987 Sun Micro";*/ +%/*static char sccsid[] = "from: @(#)rquota.x 2.1 88/08/01 4.0 RPCSRC";*/ +%static const char rcsid[] = +% "$FreeBSD: src/include/rpcsvc/rquota.x,v 1.6 1999/08/27 23:45:10 peter Exp $"; +%#endif /* not lint */ +#endif + +const RQ_PATHLEN = 1024; + +struct getquota_args { + string gqa_pathp<RQ_PATHLEN>; /* path to filesystem of interest */ + int gqa_uid; /* inquire about quota for uid */ +}; + +/* + * remote quota structure + */ +struct rquota { + int rq_bsize; /* block size for block counts */ + bool rq_active; /* indicates whether quota is active */ + unsigned int rq_bhardlimit; /* absolute limit on disk blks alloc */ + unsigned int rq_bsoftlimit; /* preferred limit on disk blks */ + unsigned int rq_curblocks; /* current block count */ + unsigned int rq_fhardlimit; /* absolute limit on allocated files */ + unsigned int rq_fsoftlimit; /* preferred file limit */ + unsigned int rq_curfiles; /* current # allocated files */ + unsigned int rq_btimeleft; /* time left for excessive disk use */ + unsigned int rq_ftimeleft; /* time left for excessive files */ +}; + +enum gqr_status { + Q_OK = 1, /* quota returned */ + Q_NOQUOTA = 2, /* noquota for uid */ + Q_EPERM = 3 /* no permission to access quota */ +}; + +union getquota_rslt switch (gqr_status status) { +case Q_OK: + rquota gqr_rquota; /* valid if status == Q_OK */ +case Q_NOQUOTA: + void; +case Q_EPERM: + void; +}; + +program RQUOTAPROG { + version RQUOTAVERS { + /* + * Get all quotas + */ + getquota_rslt + RQUOTAPROC_GETQUOTA(getquota_args) = 1; + + /* + * Get active quotas only + */ + getquota_rslt + RQUOTAPROC_GETACTIVEQUOTA(getquota_args) = 2; + } = 1; +} = 100011; diff --git a/cpukit/librpc/include/rpcsvc/rstat.x b/cpukit/librpc/include/rpcsvc/rstat.x index e69de29bb2..fee9d52032 100644 --- a/cpukit/librpc/include/rpcsvc/rstat.x +++ b/cpukit/librpc/include/rpcsvc/rstat.x @@ -0,0 +1,151 @@ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * Gather statistics on remote machines + */ + +#ifdef RPC_HDR + +%#ifndef FSCALE +%/* +% * Scale factor for scaled integers used to count load averages. +% */ +%#define FSHIFT 8 /* bits to right of fixed binary point */ +%#define FSCALE (1<<FSHIFT) +% +%#endif /* ndef FSCALE */ + +#else + +%#ifndef lint +%/*static char sccsid[] = "from: @(#)rstat.x 1.2 87/09/18 Copyr 1987 Sun Micro";*/ +%/*static char sccsid[] = "from: @(#)rstat.x 2.2 88/08/01 4.0 RPCSRC";*/ +%static const char rcsid[] = +% "$FreeBSD: src/include/rpcsvc/rstat.x,v 1.6 1999/08/27 23:45:11 peter Exp $"; +%#endif /* not lint */ + +#endif /* def RPC_HDR */ + +const RSTAT_CPUSTATES = 4; +const RSTAT_DK_NDRIVE = 4; + +/* + * GMT since 0:00, January 1, 1970 + */ +struct rstat_timeval { + unsigned int tv_sec; /* seconds */ + unsigned int tv_usec; /* and microseconds */ +}; + +struct statstime { /* RSTATVERS_TIME */ + int cp_time[RSTAT_CPUSTATES]; + int dk_xfer[RSTAT_DK_NDRIVE]; + unsigned int v_pgpgin; /* these are cumulative sum */ + unsigned int v_pgpgout; + unsigned int v_pswpin; + unsigned int v_pswpout; + unsigned int v_intr; + int if_ipackets; + int if_ierrors; + int if_oerrors; + int if_collisions; + unsigned int v_swtch; + int avenrun[3]; /* scaled by FSCALE */ + rstat_timeval boottime; + rstat_timeval curtime; + int if_opackets; +}; + +struct statsswtch { /* RSTATVERS_SWTCH */ + int cp_time[RSTAT_CPUSTATES]; + int dk_xfer[RSTAT_DK_NDRIVE]; + unsigned int v_pgpgin; /* these are cumulative sum */ + unsigned int v_pgpgout; + unsigned int v_pswpin; + unsigned int v_pswpout; + unsigned int v_intr; + int if_ipackets; + int if_ierrors; + int if_oerrors; + int if_collisions; + unsigned int v_swtch; + unsigned int avenrun[3];/* scaled by FSCALE */ + rstat_timeval boottime; + int if_opackets; +}; + +struct stats { /* RSTATVERS_ORIG */ + int cp_time[RSTAT_CPUSTATES]; + int dk_xfer[RSTAT_DK_NDRIVE]; + unsigned int v_pgpgin; /* these are cumulative sum */ + unsigned int v_pgpgout; + unsigned int v_pswpin; + unsigned int v_pswpout; + unsigned int v_intr; + int if_ipackets; + int if_ierrors; + int if_oerrors; + int if_collisions; + int if_opackets; +}; + + +program RSTATPROG { + /* + * Newest version includes current time and context switching info + */ + version RSTATVERS_TIME { + statstime + RSTATPROC_STATS(void) = 1; + + unsigned int + RSTATPROC_HAVEDISK(void) = 2; + } = 3; + /* + * Does not have current time + */ + version RSTATVERS_SWTCH { + statsswtch + RSTATPROC_STATS(void) = 1; + + unsigned int + RSTATPROC_HAVEDISK(void) = 2; + } = 2; + /* + * Old version has no info about current time or context switching + */ + version RSTATVERS_ORIG { + stats + RSTATPROC_STATS(void) = 1; + + unsigned int + RSTATPROC_HAVEDISK(void) = 2; + } = 1; +} = 100001; diff --git a/cpukit/librpc/include/rpcsvc/rwall.x b/cpukit/librpc/include/rpcsvc/rwall.x index e69de29bb2..6c26c1f18f 100644 --- a/cpukit/librpc/include/rpcsvc/rwall.x +++ b/cpukit/librpc/include/rpcsvc/rwall.x @@ -0,0 +1,57 @@ +%/* +% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for +% * unrestricted use provided that this legend is included on all tape +% * media and as a part of the software program in whole or part. Users +% * may copy or modify Sun RPC without charge, but are not authorized +% * to license or distribute it to anyone else except as part of a product or +% * program developed by the user or with the express written consent of +% * Sun Microsystems, Inc. +% * +% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE +% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR +% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. +% * +% * Sun RPC is provided with no support and without any obligation on the +% * part of Sun Microsystems, Inc. to assist in its use, correction, +% * modification or enhancement. +% * +% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE +% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC +% * OR ANY PART THEREOF. +% * +% * In no event will Sun Microsystems, Inc. be liable for any lost revenue +% * or profits or other special, indirect and consequential damages, even if +% * Sun has been advised of the possibility of such damages. +% * +% * Sun Microsystems, Inc. +% * 2550 Garcia Avenue +% * Mountain View, California 94043 +% */ + +%/* +% * Copyright (c) 1984, 1990 by Sun Microsystems, Inc. +% */ +% +%/* from @(#)rwall.x 1.6 91/03/11 TIRPC 1.0 */ + +#ifdef RPC_HDR +% +%#ifndef _rpcsvc_rwall_h +%#define _rpcsvc_rwall_h +% +%typedef char *wrapstring; +% +#endif + +program WALLPROG { + version WALLVERS { + void + WALLPROC_WALL(wrapstring) = 2; + + } = 1; +} = 100008; + +#ifdef RPC_HDR +% +%#endif /* ! _rpcsvc_rwall_h */ +#endif diff --git a/cpukit/librpc/include/rpcsvc/sm_inter.x b/cpukit/librpc/include/rpcsvc/sm_inter.x index e69de29bb2..2071516a7f 100644 --- a/cpukit/librpc/include/rpcsvc/sm_inter.x +++ b/cpukit/librpc/include/rpcsvc/sm_inter.x @@ -0,0 +1,122 @@ +/* @(#)sm_inter.x 2.2 88/08/01 4.0 RPCSRC */ +/* @(#)sm_inter.x 1.7 87/06/24 Copyr 1987 Sun Micro */ + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * Status monitor protocol specification + * Copyright (C) 1986 Sun Microsystems, Inc. + * + */ + +#ifndef RPC_HDR +%#ifndef lint +%static const char rcsid[] = +% "$FreeBSD: src/include/rpcsvc/sm_inter.x,v 1.8 1999/08/27 23:45:11 peter Exp $"; +%#endif /* not lint */ +#endif + +program SM_PROG { + version SM_VERS { + /* res_stat = stat_succ if status monitor agrees to monitor */ + /* res_stat = stat_fail if status monitor cannot monitor */ + /* if res_stat == stat_succ, state = state number of site sm_name */ + struct sm_stat_res SM_STAT(struct sm_name) = 1; + + /* res_stat = stat_succ if status monitor agrees to monitor */ + /* res_stat = stat_fail if status monitor cannot monitor */ + /* stat consists of state number of local site */ + struct sm_stat_res SM_MON(struct mon) = 2; + + /* stat consists of state number of local site */ + struct sm_stat SM_UNMON(struct mon_id) = 3; + + /* stat consists of state number of local site */ + struct sm_stat SM_UNMON_ALL(struct my_id) = 4; + + void SM_SIMU_CRASH(void) = 5; + + } = 1; +} = 100024; + +const SM_MAXSTRLEN = 1024; + +struct sm_name { + string mon_name<SM_MAXSTRLEN>; +}; + +struct my_id { + string my_name<SM_MAXSTRLEN>; /* name of the site iniates the monitoring request*/ + int my_prog; /* rpc program # of the requesting process */ + int my_vers; /* rpc version # of the requesting process */ + int my_proc; /* rpc procedure # of the requesting process */ +}; + +struct mon_id { + string mon_name<SM_MAXSTRLEN>; /* name of the site to be monitored */ + struct my_id my_id; +}; + + +struct mon{ + struct mon_id mon_id; + opaque priv[16]; /* private information to store at monitor for requesting process */ +}; + + +/* + * state # of status monitor monitonically increases each time + * status of the site changes: + * an even number (>= 0) indicates the site is down and + * an odd number (> 0) indicates the site is up; + */ +struct sm_stat { + int state; /* state # of status monitor */ +}; + +enum res { + stat_succ = 0, /* status monitor agrees to monitor */ + stat_fail = 1 /* status monitor cannot monitor */ +}; + +struct sm_stat_res { + res res_stat; + int state; +}; + +/* + * structure of the status message sent back by the status monitor + * when monitor site status changes + */ +struct status { + string mon_name<SM_MAXSTRLEN>; + int state; + opaque priv[16]; /* stored private information */ +}; diff --git a/cpukit/librpc/include/rpcsvc/spray.x b/cpukit/librpc/include/rpcsvc/spray.x index e69de29bb2..a4d086af48 100644 --- a/cpukit/librpc/include/rpcsvc/spray.x +++ b/cpukit/librpc/include/rpcsvc/spray.x @@ -0,0 +1,90 @@ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * Spray a server with packets + * Useful for testing flakiness of network interfaces + */ + +#ifndef RPC_HDR +%#ifndef lint +%/*static char sccsid[] = "from: @(#)spray.x 1.2 87/09/18 Copyr 1987 Sun Micro";*/ +%/*static char sccsid[] = "from: @(#)spray.x 2.1 88/08/01 4.0 RPCSRC";*/ +%static const char rcsid[] = +% "$FreeBSD: src/include/rpcsvc/spray.x,v 1.6 1999/08/27 23:45:11 peter Exp $"; +%#endif /* not lint */ +#endif + +const SPRAYMAX = 8845; /* max amount can spray */ + +/* + * GMT since 0:00, 1 January 1970 + */ +struct spraytimeval { + unsigned int sec; + unsigned int usec; +}; + +/* + * spray statistics + */ +struct spraycumul { + unsigned int counter; + spraytimeval clock; +}; + +/* + * spray data + */ +typedef opaque sprayarr<SPRAYMAX>; + +program SPRAYPROG { + version SPRAYVERS { + /* + * Just throw away the data and increment the counter + * This call never returns, so the client should always + * time it out. + */ + void + SPRAYPROC_SPRAY(sprayarr) = 1; + + /* + * Get the value of the counter and elapsed time since + * last CLEAR. + */ + spraycumul + SPRAYPROC_GET(void) = 2; + + /* + * Clear the counter and reset the elapsed time + */ + void + SPRAYPROC_CLEAR(void) = 3; + } = 1; +} = 100012; diff --git a/cpukit/librpc/include/rpcsvc/yp.x b/cpukit/librpc/include/rpcsvc/yp.x index e69de29bb2..aa872653ff 100644 --- a/cpukit/librpc/include/rpcsvc/yp.x +++ b/cpukit/librpc/include/rpcsvc/yp.x @@ -0,0 +1,379 @@ +/* @(#)yp.x 2.1 88/08/01 4.0 RPCSRC */ + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * Protocol description file for the Yellow Pages Service + */ + +#ifndef RPC_HDR +%#ifndef lint +%static const char rcsid[] = +% "$FreeBSD: src/include/rpcsvc/yp.x,v 1.12 1999/08/27 23:45:12 peter Exp $"; +%#endif /* not lint */ +#endif + +const YPMAXRECORD = 1024; +const YPMAXDOMAIN = 64; +const YPMAXMAP = 64; +const YPMAXPEER = 64; + + +enum ypstat { + YP_TRUE = 1, + YP_NOMORE = 2, + YP_FALSE = 0, + YP_NOMAP = -1, + YP_NODOM = -2, + YP_NOKEY = -3, + YP_BADOP = -4, + YP_BADDB = -5, + YP_YPERR = -6, + YP_BADARGS = -7, + YP_VERS = -8 +}; + + +enum ypxfrstat { + YPXFR_SUCC = 1, + YPXFR_AGE = 2, + YPXFR_NOMAP = -1, + YPXFR_NODOM = -2, + YPXFR_RSRC = -3, + YPXFR_RPC = -4, + YPXFR_MADDR = -5, + YPXFR_YPERR = -6, + YPXFR_BADARGS = -7, + YPXFR_DBM = -8, + YPXFR_FILE = -9, + YPXFR_SKEW = -10, + YPXFR_CLEAR = -11, + YPXFR_FORCE = -12, + YPXFR_XFRERR = -13, + YPXFR_REFUSED = -14 +}; + + +typedef string domainname<YPMAXDOMAIN>; +typedef string mapname<YPMAXMAP>; +typedef string peername<YPMAXPEER>; +typedef opaque keydat<YPMAXRECORD>; +typedef opaque valdat<YPMAXRECORD>; + + +struct ypmap_parms { + domainname domain; + mapname map; + unsigned int ordernum; + peername peer; +}; + +struct ypreq_key { + domainname domain; + mapname map; + keydat key; +}; + +struct ypreq_nokey { + domainname domain; + mapname map; +}; + +struct ypreq_xfr { + ypmap_parms map_parms; + unsigned int transid; + unsigned int prog; + unsigned int port; +}; + + +struct ypresp_val { + ypstat stat; + valdat val; +}; + +struct ypresp_key_val { + ypstat stat; +#ifdef STUPID_SUN_BUG /* These are backwards */ + keydat key; + valdat val; +#else + valdat val; + keydat key; +#endif +}; + + +struct ypresp_master { + ypstat stat; + peername peer; +}; + +struct ypresp_order { + ypstat stat; + unsigned int ordernum; +}; + +union ypresp_all switch (bool more) { +case TRUE: + ypresp_key_val val; +case FALSE: + void; +}; + +struct ypresp_xfr { + unsigned int transid; + ypxfrstat xfrstat; +}; + +struct ypmaplist { + mapname map; + ypmaplist *next; +}; + +struct ypresp_maplist { + ypstat stat; + ypmaplist *maps; +}; + +enum yppush_status { + YPPUSH_SUCC = 1, /* Success */ + YPPUSH_AGE = 2, /* Master's version not newer */ + YPPUSH_NOMAP = -1, /* Can't find server for map */ + YPPUSH_NODOM = -2, /* Domain not supported */ + YPPUSH_RSRC = -3, /* Local resource alloc failure */ + YPPUSH_RPC = -4, /* RPC failure talking to server */ + YPPUSH_MADDR = -5, /* Can't get master address */ + YPPUSH_YPERR = -6, /* YP server/map db error */ + YPPUSH_BADARGS = -7, /* Request arguments bad */ + YPPUSH_DBM = -8, /* Local dbm operation failed */ + YPPUSH_FILE = -9, /* Local file I/O operation failed */ + YPPUSH_SKEW = -10, /* Map version skew during transfer */ + YPPUSH_CLEAR = -11, /* Can't send "Clear" req to local ypserv */ + YPPUSH_FORCE = -12, /* No local order number in map use -f flag. */ + YPPUSH_XFRERR = -13, /* ypxfr error */ + YPPUSH_REFUSED = -14 /* Transfer request refused by ypserv */ +}; + +struct yppushresp_xfr { + unsigned transid; + yppush_status status; +}; + +/* + * Response structure and overall result status codes. Success and failure + * represent two separate response message types. + */ + +enum ypbind_resptype { + YPBIND_SUCC_VAL = 1, + YPBIND_FAIL_VAL = 2 +}; + +struct ypbind_binding { + opaque ypbind_binding_addr[4]; /* In network order */ + opaque ypbind_binding_port[2]; /* In network order */ +}; + +union ypbind_resp switch (ypbind_resptype ypbind_status) { +case YPBIND_FAIL_VAL: + unsigned ypbind_error; +case YPBIND_SUCC_VAL: + ypbind_binding ypbind_bindinfo; +}; + +/* Detailed failure reason codes for response field ypbind_error*/ + +const YPBIND_ERR_ERR = 1; /* Internal error */ +const YPBIND_ERR_NOSERV = 2; /* No bound server for passed domain */ +const YPBIND_ERR_RESC = 3; /* System resource allocation failure */ + + +/* + * Request data structure for ypbind "Set domain" procedure. + */ +struct ypbind_setdom { + domainname ypsetdom_domain; + ypbind_binding ypsetdom_binding; + unsigned ypsetdom_vers; +}; + + +/* + * NIS v1 support for backwards compatibility + */ +enum ypreqtype { + YPREQ_KEY = 1, + YPREQ_NOKEY = 2, + YPREQ_MAP_PARMS = 3 +}; + +enum ypresptype { + YPRESP_VAL = 1, + YPRESP_KEY_VAL = 2, + YPRESP_MAP_PARMS = 3 +}; + +union yprequest switch (ypreqtype yp_reqtype) { +case YPREQ_KEY: + ypreq_key yp_req_keytype; +case YPREQ_NOKEY: + ypreq_nokey yp_req_nokeytype; +case YPREQ_MAP_PARMS: + ypmap_parms yp_req_map_parmstype; +}; + +union ypresponse switch (ypresptype yp_resptype) { +case YPRESP_VAL: + ypresp_val yp_resp_valtype; +case YPRESP_KEY_VAL: + ypresp_key_val yp_resp_key_valtype; +case YPRESP_MAP_PARMS: + ypmap_parms yp_resp_map_parmstype; +}; + +#if !defined(YPBIND_ONLY) && !defined(YPPUSH_ONLY) +/* + * YP access protocol + */ +program YPPROG { +/* + * NIS v1 support for backwards compatibility + */ + version YPOLDVERS { + void + YPOLDPROC_NULL(void) = 0; + + bool + YPOLDPROC_DOMAIN(domainname) = 1; + + bool + YPOLDPROC_DOMAIN_NONACK(domainname) = 2; + + ypresponse + YPOLDPROC_MATCH(yprequest) = 3; + + ypresponse + YPOLDPROC_FIRST(yprequest) = 4; + + ypresponse + YPOLDPROC_NEXT(yprequest) = 5; + + ypresponse + YPOLDPROC_POLL(yprequest) = 6; + + ypresponse + YPOLDPROC_PUSH(yprequest) = 7; + + ypresponse + YPOLDPROC_PULL(yprequest) = 8; + + ypresponse + YPOLDPROC_GET(yprequest) = 9; + } = 1; + + version YPVERS { + void + YPPROC_NULL(void) = 0; + + bool + YPPROC_DOMAIN(domainname) = 1; + + bool + YPPROC_DOMAIN_NONACK(domainname) = 2; + + ypresp_val + YPPROC_MATCH(ypreq_key) = 3; + + ypresp_key_val +#ifdef STUPID_SUN_BUG /* should be ypreq_nokey */ + YPPROC_FIRST(ypreq_key) = 4; +#else + YPPROC_FIRST(ypreq_nokey) = 4; +#endif + ypresp_key_val + YPPROC_NEXT(ypreq_key) = 5; + + ypresp_xfr + YPPROC_XFR(ypreq_xfr) = 6; + + void + YPPROC_CLEAR(void) = 7; + + ypresp_all + YPPROC_ALL(ypreq_nokey) = 8; + + ypresp_master + YPPROC_MASTER(ypreq_nokey) = 9; + + ypresp_order + YPPROC_ORDER(ypreq_nokey) = 10; + + ypresp_maplist + YPPROC_MAPLIST(domainname) = 11; + } = 2; +} = 100004; +#endif +#if !defined(YPSERV_ONLY) && !defined(YPBIND_ONLY) +/* + * YPPUSHPROC_XFRRESP is the callback routine for result of YPPROC_XFR + */ +program YPPUSH_XFRRESPPROG { + version YPPUSH_XFRRESPVERS { + void + YPPUSHPROC_NULL(void) = 0; +#ifdef STUPID_SUN_BUG /* argument and return value are backwards */ + yppushresp_xfr + YPPUSHPROC_XFRRESP(void) = 1; +#else + void + YPPUSHPROC_XFRRESP(yppushresp_xfr) = 1; +#endif + } = 1; +} = 0x40000000; /* transient: could be anything up to 0x5fffffff */ +#endif +#if !defined(YPSERV_ONLY) && !defined(YPPUSH_ONLY) +/* + * YP binding protocol + */ +program YPBINDPROG { + version YPBINDVERS { + void + YPBINDPROC_NULL(void) = 0; + + ypbind_resp + YPBINDPROC_DOMAIN(domainname) = 1; + + void + YPBINDPROC_SETDOM(ypbind_setdom) = 2; + } = 2; +} = 100007; + +#endif diff --git a/cpukit/librpc/include/rpcsvc/yp_prot.h b/cpukit/librpc/include/rpcsvc/yp_prot.h index e69de29bb2..92de593611 100644 --- a/cpukit/librpc/include/rpcsvc/yp_prot.h +++ b/cpukit/librpc/include/rpcsvc/yp_prot.h @@ -0,0 +1,329 @@ +/* + * Copyright (c) 1992/3 Theo de Raadt <deraadt@fsa.ca> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/include/rpcsvc/yp_prot.h,v 1.10 1999/08/27 23:45:12 peter Exp $ + */ + +#ifndef _RPCSVC_YP_PROT_H_ +#define _RPCSVC_YP_PROT_H_ + +/* + * YPSERV PROTOCOL: + * + * ypserv supports the following procedures: + * + * YPPROC_NULL takes (void), returns (void). + * called to check if server is alive. + * YPPROC_DOMAIN takes (char *), returns (bool_t). + * true if ypserv serves the named domain. + * YPPROC_DOMAIN_NOACK takes (char *), returns (bool_t). + * true if ypserv serves the named domain. + * used for broadcasts, does not ack if ypserv + * doesn't handle named domain. + * YPPROC_MATCH takes (struct ypreq_key), returns (struct ypresp_val) + * does a lookup. + * YPPROC_FIRST takes (struct ypreq_nokey) returns (ypresp_key_val). + * gets the first key/datum from the map. + * YPPROC_NEXT takes (struct ypreq_key) returns (ypresp_key_val). + * gets the next key/datum from the map. + * YPPROC_XFR takes (struct ypreq_xfr), returns (void). + * tells ypserv to check if there is a new version of + * the map. + * YPPROC_CLEAR takes (void), returns (void). + * tells ypserv to flush it's file cache, so that + * newly transferred files will get read. + * YPPROC_ALL takes (struct ypreq_nokey), returns (bool_t and + * struct ypresp_key_val). + * returns an array of data, with the bool_t being + * false on the last datum. read the source, it's + * convoluted. + * YPPROC_MASTER takes (struct ypreq_nokey), returns (ypresp_master). + * YPPROC_ORDER takes (struct ypreq_nokey), returns (ypresp_order). + * YPPROC_MAPLIST takes (char *), returns (struct ypmaplist *). + */ + +#ifndef BOOL_DEFINED +typedef u_int bool; +#define BOOL_DEFINED +#endif + +/* Program and version symbols, magic numbers */ + +#define YPPROG ((u_long)100004) +#define YPVERS ((u_long)2) +#define YPVERS_ORIG ((u_long)1) +#define YPMAXRECORD ((u_long)1024) +#define YPMAXDOMAIN ((u_long)64) +#define YPMAXMAP ((u_long)64) +#define YPMAXPEER ((u_long)256) + +/* + * I don't know if anything of sun's depends on this, or if they + * simply defined it so that their own code wouldn't try to send + * packets over the ethernet MTU. This YP code doesn't use it. + */ +#define YPMSGSZ 1600 + +#ifndef DATUM +typedef struct { + char *dptr; + int dsize; +} datum; +#define DATUM +#endif + +struct ypmap_parms { + char *domain; + char *map; + u_long ordernum; + char *owner; +}; + +struct ypreq_key { + char *domain; + char *map; + datum keydat; +}; + +struct ypreq_nokey { + char *domain; + char *map; +}; + +struct ypreq_xfr { + struct ypmap_parms map_parms; + u_long transid; + u_long proto; + u_short port; +}; +#define ypxfr_domain map_parms.domain +#define ypxfr_map map_parms.map +#define ypxfr_ordernum map_parms.ordernum +#define ypxfr_owner map_parms.owner + +struct ypresp_val { + u_long status; + datum valdat; +}; + +struct ypresp_key_val { + u_long status; + datum keydat; + datum valdat; +}; + +struct ypresp_master { + u_long status; + char *master; +}; + +struct ypresp_order { + u_long status; + u_long ordernum; +}; + +struct ypmaplist { + char ypml_name[YPMAXMAP + 1]; + struct ypmaplist *ypml_next; +}; + +struct ypresp_maplist { + u_long status; + struct ypmaplist *list; +}; + +/* ypserv procedure numbers */ +#define YPPROC_NULL ((u_long)0) +#define YPPROC_DOMAIN ((u_long)1) +#define YPPROC_DOMAIN_NONACK ((u_long)2) +#define YPPROC_MATCH ((u_long)3) +#define YPPROC_FIRST ((u_long)4) +#define YPPROC_NEXT ((u_long)5) +#define YPPROC_XFR ((u_long)6) +#define YPPROC_CLEAR ((u_long)7) +#define YPPROC_ALL ((u_long)8) +#define YPPROC_MASTER ((u_long)9) +#define YPPROC_ORDER ((u_long)10) +#define YPPROC_MAPLIST ((u_long)11) + +/* ypserv procedure return status values */ +#define YP_TRUE ((long)1) /* general purpose success code */ +#define YP_NOMORE ((long)2) /* no more entries in map */ +#define YP_FALSE ((long)0) /* general purpose failure code */ +#define YP_NOMAP ((long)-1) /* no such map in domain */ +#define YP_NODOM ((long)-2) /* domain not supported */ +#define YP_NOKEY ((long)-3) /* no such key in map */ +#define YP_BADOP ((long)-4) /* invalid operation */ +#define YP_BADDB ((long)-5) /* server data base is bad */ +#define YP_YPERR ((long)-6) /* YP server error */ +#define YP_BADARGS ((long)-7) /* request arguments bad */ +#define YP_VERS ((long)-8) /* YP server version mismatch */ + +/* + * Sun's header file says: + * "Domain binding data structure, used by ypclnt package and ypserv modules. + * Users of the ypclnt package (or of this protocol) don't HAVE to know about + * it, but it must be available to users because _yp_dobind is a public + * interface." + * + * This is totally bogus! Nowhere else does Sun state that _yp_dobind() is + * a public interface, and I don't know any reason anyone would want to call + * it. But, just in case anyone does actually expect it to be available.. + * we provide this.. exactly as Sun wants it. + */ +struct dom_binding { + struct dom_binding *dom_pnext; + char dom_domain[YPMAXDOMAIN + 1]; + struct sockaddr_in dom_server_addr; + u_short dom_server_port; + int dom_socket; + CLIENT *dom_client; + u_short dom_local_port; + long dom_vers; +}; + +/* + * YPBIND PROTOCOL: + * + * ypbind supports the following procedures: + * + * YPBINDPROC_NULL takes (void), returns (void). + * to check if ypbind is running. + * YPBINDPROC_DOMAIN takes (char *), returns (struct ypbind_resp). + * requests that ypbind start to serve the + * named domain (if it doesn't already) + * YPBINDPROC_SETDOM takes (struct ypbind_setdom), returns (void). + * used by ypset. + */ + +#define YPBINDPROG ((u_long)100007) +#define YPBINDVERS ((u_long)2) +#define YPBINDVERS_ORIG ((u_long)1) + +/* ypbind procedure numbers */ +#define YPBINDPROC_NULL ((u_long)0) +#define YPBINDPROC_DOMAIN ((u_long)1) +#define YPBINDPROC_SETDOM ((u_long)2) + +/* error code in ypbind_resp.ypbind_status */ +enum ypbind_resptype { + YPBIND_SUCC_VAL = 1, + YPBIND_FAIL_VAL = 2 +}; + +/* network order, of course */ +struct ypbind_binding { + struct in_addr ypbind_binding_addr; + u_short ypbind_binding_port; +}; + +struct ypbind_resp { + enum ypbind_resptype ypbind_status; + union { + u_long ypbind_error; + struct ypbind_binding ypbind_bindinfo; + } ypbind_respbody; +}; + +/* error code in ypbind_resp.ypbind_respbody.ypbind_error */ +#define YPBIND_ERR_ERR 1 /* internal error */ +#define YPBIND_ERR_NOSERV 2 /* no bound server for passed domain */ +#define YPBIND_ERR_RESC 3 /* system resource allocation failure */ + +/* + * Request data structure for ypbind "Set domain" procedure. + */ +struct ypbind_setdom { + char ypsetdom_domain[YPMAXDOMAIN + 1]; + struct ypbind_binding ypsetdom_binding; + u_short ypsetdom_vers; +}; +#define ypsetdom_addr ypsetdom_binding.ypbind_binding_addr +#define ypsetdom_port ypsetdom_binding.ypbind_binding_port + +/* + * YPPUSH PROTOCOL: + * + * Sun says: + * "Protocol between clients (ypxfr, only) and yppush + * yppush speaks a protocol in the transient range, which + * is supplied to ypxfr as a command-line parameter when it + * is activated by ypserv." + * + * This protocol is not implemented, naturally, because this YP + * implementation only does the client side. + */ +#define YPPUSHVERS ((u_long)1) +#define YPPUSHVERS_ORIG ((u_long)1) + +/* yppush procedure numbers */ +#define YPPUSHPROC_NULL ((u_long)0) +#define YPPUSHPROC_XFRRESP ((u_long)1) + +struct yppushresp_xfr { + u_long transid; + u_long status; +}; + +/* yppush status value in yppushresp_xfr.status */ +#define YPPUSH_SUCC ((long)1) /* Success */ +#define YPPUSH_AGE ((long)2) /* Master's version not newer */ +#define YPPUSH_NOMAP ((long)-1) /* Can't find server for map */ +#define YPPUSH_NODOM ((long)-2) /* Domain not supported */ +#define YPPUSH_RSRC ((long)-3) /* Local resource alloc failure */ +#define YPPUSH_RPC ((long)-4) /* RPC failure talking to server */ +#define YPPUSH_MADDR ((long)-5) /* Can't get master address */ +#define YPPUSH_YPERR ((long)-6) /* YP server/map db error */ +#define YPPUSH_BADARGS ((long)-7) /* Request arguments bad */ +#define YPPUSH_DBM ((long)-8) /* Local dbm operation failed */ +#define YPPUSH_FILE ((long)-9) /* Local file I/O operation failed */ +#define YPPUSH_SKEW ((long)-10) /* Map version skew during transfer */ +#define YPPUSH_CLEAR ((long)-11) /* Can't send "Clear" req to local ypserv */ +#define YPPUSH_FORCE ((long)-12) /* No local order number in map - use -f */ +#define YPPUSH_XFRERR ((long)-13) /* ypxfr error */ +#define YPPUSH_REFUSED ((long)-14) /* Transfer request refused by ypserv */ + +struct inaddr; +__BEGIN_DECLS +bool_t xdr_datum __P((XDR *, datum *)); +bool_t xdr_ypreq_key __P((XDR *, struct ypreq_key *)); +bool_t xdr_ypreq_nokey __P((XDR *, struct ypreq_nokey *)); +bool_t xdr_ypreq_xfr __P((XDR *, struct ypreq_xfr *)); +bool_t xdr_ypresp_val __P((XDR *, struct ypresp_val *)); +bool_t xdr_ypresp_key_val __P((XDR *, struct ypresp_key_val *)); +bool_t xdr_ypbind_resp __P((XDR *, struct ypbind_resp *)); +bool_t xdr_ypbind_setdom __P((XDR *, struct ypbind_setdom *)); +bool_t xdr_yp_inaddr __P((XDR *, struct inaddr *)); +bool_t xdr_ypmap_parms __P((XDR *, struct ypmap_parms *)); +bool_t xdr_yppushresp_xfr __P((XDR *, struct yppushresp_xfr *)); +bool_t xdr_ypresp_order __P((XDR *, struct ypresp_order *)); +bool_t xdr_ypresp_master __P((XDR *, struct ypresp_master *)); +bool_t xdr_ypresp_maplist __P((XDR *, struct ypresp_maplist *)); +__END_DECLS + +#endif /* _RPCSVC_YP_PROT_H_ */ diff --git a/cpukit/librpc/include/rpcsvc/ypclnt.h b/cpukit/librpc/include/rpcsvc/ypclnt.h index e69de29bb2..9636ba2d84 100644 --- a/cpukit/librpc/include/rpcsvc/ypclnt.h +++ b/cpukit/librpc/include/rpcsvc/ypclnt.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 1992/3 Theo de Raadt <deraadt@fsa.ca> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/include/rpcsvc/ypclnt.h,v 1.11 1999/08/27 23:45:12 peter Exp $ + */ + +#ifndef _RPCSVC_YPCLNT_H_ +#define _RPCSVC_YPCLNT_H_ + +#include <sys/cdefs.h> + +#define YPERR_BADARGS 1 /* args to function are bad */ +#define YPERR_RPC 2 /* RPC failure */ +#define YPERR_DOMAIN 3 /* can't bind to a server for domain */ +#define YPERR_MAP 4 /* no such map in server's domain */ +#define YPERR_KEY 5 /* no such key in map */ +#define YPERR_YPERR 6 /* some internal YP server or client error */ +#define YPERR_RESRC 7 /* local resource allocation failure */ +#define YPERR_NOMORE 8 /* no more records in map database */ +#define YPERR_PMAP 9 /* can't communicate with portmapper */ +#define YPERR_YPBIND 10 /* can't communicate with ypbind */ +#define YPERR_YPSERV 11 /* can't communicate with ypserv */ +#define YPERR_NODOM 12 /* local domain name not set */ +#define YPERR_BADDB 13 /* YP data base is bad */ +#define YPERR_VERS 14 /* YP version mismatch */ +#define YPERR_ACCESS 15 /* access violation */ +#define YPERR_BUSY 16 /* database is busy */ + +/* + * Types of update operations + */ +#define YPOP_CHANGE 1 /* change, do not add */ +#define YPOP_INSERT 2 /* add, do not change */ +#define YPOP_DELETE 3 /* delete this entry */ +#define YPOP_STORE 4 /* add, or change */ + +struct ypall_callback { + /* return non-0 to stop getting called */ + int (*foreach) __P((unsigned long, char *, int, char *, int, void *)); + char *data; /* opaque pointer for use of callback fn */ +}; + +struct dom_binding; + +__BEGIN_DECLS +int yp_bind __P((char *dom)); +int _yp_dobind __P((char *dom, struct dom_binding **ypdb)); +void yp_unbind __P((char *dom)); +int yp_get_default_domain __P((char **domp)); +int yp_match __P((char *indomain, char *inmap, + const char *inkey, int inkeylen, char **outval, + int *outvallen)); +int yp_first __P((char *indomain, char *inmap, + char **outkey, int *outkeylen, char **outval, + int *outvallen)); +int yp_next __P((char *indomain, char *inmap, + char *inkey, int inkeylen, char **outkey, + int *outkeylen, char **outval, int *outvallen)); +int yp_master __P((char *indomain, char *inmap, char **outname)); +int yp_order __P((char *indomain, char *inmap, int *outorder)); +int yp_all __P((char *indomain, char *inmap, + struct ypall_callback *incallback)); +char * yperr_string __P((int incode)); +char * ypbinderr_string __P((int incode)); +int ypprot_err __P((unsigned int incode)); +__END_DECLS + +#endif /* _RPCSVC_YPCLNT_H_ */ + diff --git a/cpukit/librpc/include/rpcsvc/yppasswd.x b/cpukit/librpc/include/rpcsvc/yppasswd.x index e69de29bb2..bcc83a1346 100644 --- a/cpukit/librpc/include/rpcsvc/yppasswd.x +++ b/cpukit/librpc/include/rpcsvc/yppasswd.x @@ -0,0 +1,75 @@ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * YP password update protocol + * Requires unix authentication + */ + +#ifndef RPC_HDR +%#ifndef lint +%/*static char sccsid[] = "from: @(#)yppasswd.x 1.1 87/04/13 Copyr 1987 Sun Micro";*/ +%/*static char sccsid[] = "from: @(#)yppasswd.x 2.1 88/08/01 4.0 RPCSRC";*/ +%static const char rcsid[] = +% "$FreeBSD: src/include/rpcsvc/yppasswd.x,v 1.6 1999/08/27 23:45:12 peter Exp $"; +%#endif /* not lint */ +#endif + +program YPPASSWDPROG { + version YPPASSWDVERS { + /* + * Update my passwd entry + */ + int + YPPASSWDPROC_UPDATE(yppasswd) = 1; + } = 1; +} = 100009; + + +struct x_passwd { + string pw_name<>; /* username */ + string pw_passwd<>; /* encrypted password */ + int pw_uid; /* user id */ + int pw_gid; /* group id */ + string pw_gecos<>; /* in real life name */ + string pw_dir<>; /* home directory */ + string pw_shell<>; /* default shell */ +}; + +struct yppasswd { + string oldpass<>; /* unencrypted old password */ + x_passwd newpw; /* new passwd entry */ +}; + + +#ifdef RPC_HDR +%#include <sys/cdefs.h> +%extern int _yppasswd __P(( char * , struct x_passwd * )); +%#define yppasswd(x,y) _yppasswd(x,y) +#endif diff --git a/cpukit/librpc/include/rpcsvc/ypupdate_prot.x b/cpukit/librpc/include/rpcsvc/ypupdate_prot.x index e69de29bb2..f16d5ee45e 100644 --- a/cpukit/librpc/include/rpcsvc/ypupdate_prot.x +++ b/cpukit/librpc/include/rpcsvc/ypupdate_prot.x @@ -0,0 +1,88 @@ +%/* +% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for +% * unrestricted use provided that this legend is included on all tape +% * media and as a part of the software program in whole or part. Users +% * may copy or modify Sun RPC without charge, but are not authorized +% * to license or distribute it to anyone else except as part of a product or +% * program developed by the user or with the express written consent of +% * Sun Microsystems, Inc. +% * +% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE +% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR +% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. +% * +% * Sun RPC is provided with no support and without any obligation on the +% * part of Sun Microsystems, Inc. to assist in its use, correction, +% * modification or enhancement. +% * +% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE +% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC +% * OR ANY PART THEREOF. +% * +% * In no event will Sun Microsystems, Inc. be liable for any lost revenue +% * or profits or other special, indirect and consequential damages, even if +% * Sun has been advised of the possibility of such damages. +% * +% * Sun Microsystems, Inc. +% * 2550 Garcia Avenue +% * Mountain View, California 94043 +% */ + +%/* +% * Copyright (c) 1986, 1990 by Sun Microsystems, Inc. +% */ +% +%/* from @(#)ypupdate_prot.x 1.3 91/03/11 TIRPC 1.0 */ +#ifndef RPC_HDR +%#ifndef lint +%static const char rcsid[] = +% "$FreeBSD: src/include/rpcsvc/ypupdate_prot.x,v 1.3 1999/08/27 23:45:13 peter Exp $"; +%#endif +#endif +% +%/* +% * Compiled from ypupdate_prot.x using rpcgen +% * This is NOT source code! +% * DO NOT EDIT THIS FILE! +% */ + +/* + * YP update service protocol + */ +#ifdef RPC_HDR +% +%#ifndef _rpcsvc_ypupdate_prot_h +%#define _rpcsvc_ypupdate_prot_h +% +#endif + +const MAXMAPNAMELEN = 255; +const MAXYPDATALEN = 1023; +const MAXERRMSGLEN = 255; + +program YPU_PROG { + version YPU_VERS { + u_int YPU_CHANGE(ypupdate_args) = 1; + u_int YPU_INSERT(ypupdate_args) = 2; + u_int YPU_DELETE(ypdelete_args) = 3; + u_int YPU_STORE(ypupdate_args) = 4; + } = 1; +} = 100028; + +typedef opaque yp_buf<MAXYPDATALEN>; + +struct ypupdate_args { + string mapname<MAXMAPNAMELEN>; + yp_buf key; + yp_buf datum; +}; + +struct ypdelete_args { + string mapname<MAXMAPNAMELEN>; + yp_buf key; +}; + +#ifdef RPC_HDR +% +%#endif /* !_rpcsvc_ypupdate_prot_h */ +#endif diff --git a/cpukit/librpc/include/rpcsvc/ypxfrd.x b/cpukit/librpc/include/rpcsvc/ypxfrd.x index e69de29bb2..1845a4f43b 100644 --- a/cpukit/librpc/include/rpcsvc/ypxfrd.x +++ b/cpukit/librpc/include/rpcsvc/ypxfrd.x @@ -0,0 +1,173 @@ +/* + * Copyright (c) 1995, 1996 + * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Bill Paul. + * 4. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/include/rpcsvc/ypxfrd.x,v 1.7 1999/08/27 23:45:13 peter Exp $ + */ + +/* + * This protocol definition file describes a file transfer + * system used to very quickly move NIS maps from one host to + * another. This is similar to what Sun does with their ypxfrd + * protocol, but it must be stressed that this protocol is _NOT_ + * compatible with Sun's. There are a couple of reasons for this: + * + * 1) Sun's protocol is proprietary. The protocol definition is + * not freely available in any of the SunRPC source distributions, + * even though the NIS v2 protocol is. + * + * 2) The idea here is to transfer entire raw files rather than + * sending just the records. Sun uses ndbm for its NIS map files, + * while FreeBSD uses Berkeley DB. Both are hash databases, but the + * formats are incompatible, making it impossible for them to + * use each others' files. Even if FreeBSD adopted ndbm for its + * database format, FreeBSD/i386 is a little-endian OS and + * SunOS/SPARC is big-endian; ndbm is byte-order sensitive and + * not very smart about it, which means an attempt to read a + * database on a little-endian box that was created on a big-endian + * box (or vice-versa) can cause the ndbm code to eat itself. + * Luckily, Berkeley DB is able to deal with this situation in + * a more graceful manner. + * + * While the protocol is incompatible, the idea is the same: we just open + * up a TCP pipe to the client and transfer the raw map database + * from the master server to the slave. This is many times faster than + * the standard yppush/ypxfr transfer method since it saves us from + * having to recreate the map databases via the DB library each time. + * For example: creating a passwd database with 30,000 entries with yp_mkdb + * can take a couple of minutes, but to just copy the file takes only a few + * seconds. + */ + +#ifndef RPC_HDR +%#ifndef lint +%static const char rcsid[] = +% "$FreeBSD: src/include/rpcsvc/ypxfrd.x,v 1.7 1999/08/27 23:45:13 peter Exp $"; +%#endif /* not lint */ +#endif + +/* XXX cribbed from yp.x */ +const _YPMAXRECORD = 1024; +const _YPMAXDOMAIN = 64; +const _YPMAXMAP = 64; +const _YPMAXPEER = 64; + +/* Suggested default -- not necesarrily the one used. */ +const YPXFRBLOCK = 32767; + +/* + * Possible return codes from the remote server. + */ +enum xfrstat { + XFR_REQUEST_OK = 1, /* Transfer request granted */ + XFR_DENIED = 2, /* Transfer request denied */ + XFR_NOFILE = 3, /* Requested map file doesn't exist */ + XFR_ACCESS = 4, /* File exists, but I couldn't access it */ + XFR_BADDB = 5, /* File is not a hash database */ + XFR_READ_OK = 6, /* Block read successfully */ + XFR_READ_ERR = 7, /* Read error during transfer */ + XFR_DONE = 8, /* Transfer completed */ + XFR_DB_ENDIAN_MISMATCH = 9, /* Database byte order mismatch */ + XFR_DB_TYPE_MISMATCH = 10 /* Database type mismatch */ +}; + +/* + * Database type specifications. The client can use this to ask + * the server for a particular type of database or just take whatever + * the server has to offer. + */ +enum xfr_db_type { + XFR_DB_ASCII = 1, /* Flat ASCII text */ + XFR_DB_BSD_HASH = 2, /* Berkeley DB, hash method */ + XFR_DB_BSD_BTREE = 3, /* Berkeley DB, btree method */ + XFR_DB_BSD_RECNO = 4, /* Berkeley DB, recno method */ + XFR_DB_BSD_MPOOL = 5, /* Berkeley DB, mpool method */ + XFR_DB_BSD_NDBM = 6, /* Berkeley DB, hash, ndbm compat */ + XFR_DB_GNU_GDBM = 7, /* GNU GDBM */ + XFR_DB_DBM = 8, /* Old, deprecated dbm format */ + XFR_DB_NDBM = 9, /* ndbm format (used by Sun's NISv2) */ + XFR_DB_OPAQUE = 10, /* Mystery format -- just pass along */ + XFR_DB_ANY = 11, /* I'll take any format you've got */ + XFR_DB_UNKNOWN = 12 /* Unknown format */ +}; + +/* + * Machine byte order specification. This allows the client to check + * that it's copying a map database from a machine of similar byte sex. + * This is necessary for handling database libraries that are fatally + * byte order sensitive. + * + * The XFR_ENDIAN_ANY type is for use with the Berkeley DB database + * formats; Berkeley DB is smart enough to make up for byte order + * differences, so byte sex isn't important. + */ +enum xfr_byte_order { + XFR_ENDIAN_BIG = 1, /* We want big endian */ + XFR_ENDIAN_LITTLE = 2, /* We want little endian */ + XFR_ENDIAN_ANY = 3 /* We'll take whatever you got */ +}; + +typedef string xfrdomain<_YPMAXDOMAIN>; +typedef string xfrmap<_YPMAXMAP>; +typedef string xfrmap_filename<_YPMAXMAP>; /* actual name of map file */ + +/* + * Ask the remote ypxfrd for a map using this structure. + * Note: we supply both a map name and a map file name. These are not + * the same thing. In the case of ndbm, maps are stored in two files: + * map.bykey.pag and may.bykey.dir. We may also have to deal with + * file extensions (on the off chance that the remote server is supporting + * multiple DB formats). To handle this, we tell the remote server both + * what map we want and, in the case of ndbm, whether we want the .dir + * or the .pag part. This name should not be a fully qualified path: + * it's up to the remote server to decide which directories to look in. + */ +struct ypxfr_mapname { + xfrmap xfrmap; + xfrdomain xfrdomain; + xfrmap_filename xfrmap_filename; + xfr_db_type xfr_db_type; + xfr_byte_order xfr_byte_order; +}; + +/* Read response using this structure. */ +union xfr switch (bool ok) { +case TRUE: + opaque xfrblock_buf<>; +case FALSE: + xfrstat xfrstat; +}; + +program YPXFRD_FREEBSD_PROG { + version YPXFRD_FREEBSD_VERS { + union xfr + YPXFRD_GETMAP(ypxfr_mapname) = 1; + } = 1; +} = 600100069; /* 100069 + 60000000 -- 100069 is the Sun ypxfrd prog number */ diff --git a/cpukit/librpc/src/Makefile.am b/cpukit/librpc/src/Makefile.am index efa6a1cadb..8a1c7a987b 100644 --- a/cpukit/librpc/src/Makefile.am +++ b/cpukit/librpc/src/Makefile.am @@ -1,35 +1,10 @@ ## -## $Id$ +## $Id$ ## AUTOMAKE_OPTIONS = foreign 1.4 -LIBNAME = librpc -LIB = ${ARCH}/${LIBNAME}.a - -C_FILES = rpc_callmsg.c rpc_prot.c svc.c svc_auth.c svc_udp.c xdr.c \ - xdr_array.c xdr_mem.c -C_O_FILES = $(C_FILES:%.c=${ARCH}/%.o) - -SRCS = $(C_FILES) -OBJS = $(C_O_FILES) - -include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg -include $(top_srcdir)/../../../automake/lib.am - -AM_CFLAGS += $(LIBC_DEFINES) - -TMPINSTALL_FILES += \ -$(PROJECT_RELEASE)/lib/$(LIBNAME)$(LIB_VARIANT).a - -$(LIB): ${OBJS} - $(make-library) - -$(PROJECT_RELEASE)/lib/$(LIBNAME)$(LIB_VARIANT).a: $(LIB) - $(INSTALL_DATA) $< $@ - -all: ${ARCH} $(PREINSTALL_FILES) $(TMPINSTALL_FILES) - -EXTRA_DIST = $(C_FILES) +SUBDIRS = xdr rpc +include $(top_srcdir)/../../../automake/subdirs.am include $(top_srcdir)/../../../automake/local.am diff --git a/cpukit/librpc/src/rpc/DISCLAIMER b/cpukit/librpc/src/rpc/DISCLAIMER index e69de29bb2..1a66d5f4c9 100644 --- a/cpukit/librpc/src/rpc/DISCLAIMER +++ b/cpukit/librpc/src/rpc/DISCLAIMER @@ -0,0 +1,28 @@ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ diff --git a/cpukit/librpc/src/rpc/Makefile.am b/cpukit/librpc/src/rpc/Makefile.am index e69de29bb2..1c7542fb1b 100644 --- a/cpukit/librpc/src/rpc/Makefile.am +++ b/cpukit/librpc/src/rpc/Makefile.am @@ -0,0 +1,57 @@ +## +## $Id$ +## + +AUTOMAKE_OPTIONS = foreign 1.4 no-installman + +SUBDIRS = PSD.doc + +LIBNAME = librpc +LIB = $(ARCH)/$(LIBNAME).a + +C_FILES = auth_none.c auth_unix.c authunix_prot.c bindresvport.c \ + clnt_generic.c clnt_perror.c clnt_raw.c clnt_simple.c clnt_tcp.c \ + clnt_udp.c get_myaddress.c getrpcent.c getrpcport.c netname.c netnamer.c \ + pmap_clnt.c pmap_getmaps.c pmap_getport.c pmap_prot.c pmap_prot2.c \ + pmap_rmt.c rpc_callmsg.c rpc_commondata.c rpc_dtablesize.c rpc_prot.c \ + rpcdname.c rtime.c svc.c svc_auth.c svc_auth_unix.c svc_raw.c svc_run.c \ + svc_simple.c svc_tcp.c svc_udp.c rtems_portmapper.c rtems_rpc.c +UNUSED_C_FILES = auth_des.c auth_time.c authdes_prot.c clnt_unix.c \ + crypt_client.c des_crypt.c des_soft.c getpublickey.c key_call.c \ + key_prot_xdr.c svc_auth_des.c svc_unix.c + +C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o) + +OBJS = $(C_O_FILES) + +include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg +include $(top_srcdir)/../../../automake/lib.am + +TMPINSTALL_FILES += $(PROJECT_RELEASE)/lib/$(LIBNAME)$(LIB_VARIANT).a + +# +# Add local stuff here using += +# + +AM_CPPFLAGS += '-D__P(x)=x' -D_read=read -D_write=write -D_close=close -D_RTEMS_RPC_INTERNAL_ + +$(LIB): $(OBJS) + $(make-library) + +$(PROJECT_RELEASE)/lib/$(LIBNAME)$(LIB_VARIANT).a: $(LIB) + $(INSTALL_DATA) $< $@ + +noinst_MANS = bindresvport.3 getrpcent.3 publickey.3 rpc.3 rpc_secure.3 \ + rstat_svc.8 des_crypt.3 getrpcport.3 publickey.5 rpc.5 rstat.1 rtime.3 + +if HAS_NETWORKING +man_MANS = $(noinst_MANS) +all-local: $(ARCH) $(OBJS) $(TMPINSTALL_FILES) +endif + +.PRECIOUS: $(LIB) + +EXTRA_DIST = $(C_FILES) DISCLAIMER $(UNUSED_C_FILES) $(noinst_MANS) + +include $(top_srcdir)/../../../automake/subdirs.am +include $(top_srcdir)/../../../automake/local.am diff --git a/cpukit/librpc/src/rpc/PSD.doc/.cvsignore b/cpukit/librpc/src/rpc/PSD.doc/.cvsignore index e69de29bb2..282522db03 100644 --- a/cpukit/librpc/src/rpc/PSD.doc/.cvsignore +++ b/cpukit/librpc/src/rpc/PSD.doc/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/cpukit/librpc/src/rpc/PSD.doc/Makefile.am b/cpukit/librpc/src/rpc/PSD.doc/Makefile.am index e69de29bb2..cd8172dbfd 100644 --- a/cpukit/librpc/src/rpc/PSD.doc/Makefile.am +++ b/cpukit/librpc/src/rpc/PSD.doc/Makefile.am @@ -0,0 +1,8 @@ +## $Id$ + +AUTOMAKE_OPTIONS = foreign 1.4 + +EXTRA_DIST = nfs.rfc.ms rpc.prog.ms rpc.rfc.ms rpcgen.ms xdr.nts.ms \ + xdr.rfc.ms + +include $(top_srcdir)/../../../automake/local.am diff --git a/cpukit/librpc/src/rpc/PSD.doc/nfs.rfc.ms b/cpukit/librpc/src/rpc/PSD.doc/nfs.rfc.ms index e69de29bb2..0c9a8995b5 100644 --- a/cpukit/librpc/src/rpc/PSD.doc/nfs.rfc.ms +++ b/cpukit/librpc/src/rpc/PSD.doc/nfs.rfc.ms @@ -0,0 +1,1372 @@ +.\" +.\" Must use -- tbl -- with this one +.\" +.\" @(#)nfs.rfc.ms 2.2 88/08/05 4.0 RPCSRC +.de BT +.if \\n%=1 .tl ''- % -'' +.. +.ND +.\" prevent excess underlining in nroff +.if n .fp 2 R +.OH 'Network File System: Version 2 Protocol Specification''Page %' +.EH 'Page %''Network File System: Version 2 Protocol Specification' +.if \\n%=1 .bp +.SH +\&Network File System: Version 2 Protocol Specification +.IX NFS "" "" "" PAGE MAJOR +.IX "Network File System" "" "" "" PAGE MAJOR +.IX NFS "version-2 protocol specification" +.IX "Network File System" "version-2 protocol specification" +.LP +.NH 0 +\&Status of this Standard +.LP +Note: This document specifies a protocol that Sun Microsystems, Inc., +and others are using. It specifies it in standard ARPA RFC form. +.NH 1 +\&Introduction +.IX NFS introduction +.LP +The Sun Network Filesystem (NFS) protocol provides transparent remote +access to shared filesystems over local area networks. The NFS +protocol is designed to be machine, operating system, network architecture, +and transport protocol independent. This independence is +achieved through the use of Remote Procedure Call (RPC) primitives +built on top of an External Data Representation (XDR). Implementations +exist for a variety of machines, from personal computers to +supercomputers. +.LP +The supporting mount protocol allows the server to hand out remote +access privileges to a restricted set of clients. It performs the +operating system-specific functions that allow, for example, to +attach remote directory trees to some local file system. +.NH 2 +\&Remote Procedure Call +.IX "Remote Procedure Call" +.LP +Sun's remote procedure call specification provides a procedure- +oriented interface to remote services. Each server supplies a +program that is a set of procedures. NFS is one such "program". +The combination of host address, program number, and procedure +number specifies one remote service procedure. RPC does not depend +on services provided by specific protocols, so it can be used with +any underlying transport protocol. See the +.I "Remote Procedure Calls: Protocol Specification" +chapter of this manual. +.NH 2 +\&External Data Representation +.IX "External Data Representation" +.LP +The External Data Representation (XDR) standard provides a common +way of representing a set of data types over a network. +The NFS +Protocol Specification is written using the RPC data description +language. +For more information, see the +.I " External Data Representation Standard: Protocol Specification." +Sun provides implementations of XDR and +RPC, but NFS does not require their use. Any software that +provides equivalent functionality can be used, and if the encoding +is exactly the same it can interoperate with other implementations +of NFS. +.NH 2 +\&Stateless Servers +.IX "stateless servers" +.IX servers stateless +.LP +The NFS protocol is stateless. That is, a server does not need to +maintain any extra state information about any of its clients in +order to function correctly. Stateless servers have a distinct +advantage over stateful servers in the event of a failure. With +stateless servers, a client need only retry a request until the +server responds; it does not even need to know that the server has +crashed, or the network temporarily went down. The client of a +stateful server, on the other hand, needs to either detect a server +crash and rebuild the server's state when it comes back up, or +cause client operations to fail. +.LP +This may not sound like an important issue, but it affects the +protocol in some unexpected ways. We feel that it is worth a bit +of extra complexity in the protocol to be able to write very simple +servers that do not require fancy crash recovery. +.LP +On the other hand, NFS deals with objects such as files and +directories that inherently have state -- what good would a file be +if it did not keep its contents intact? The goal is to not +introduce any extra state in the protocol itself. Another way to +simplify recovery is by making operations "idempotent" whenever +possible (so that they can potentially be repeated). +.NH 1 +\&NFS Protocol Definition +.IX NFS "protocol definition" +.IX NFS protocol +.LP +Servers have been known to change over time, and so can the +protocol that they use. So RPC provides a version number with each +RPC request. This RFC describes version two of the NFS protocol. +Even in the second version, there are various obsolete procedures +and parameters, which will be removed in later versions. An RFC +for version three of the NFS protocol is currently under +preparation. +.NH 2 +\&File System Model +.IX filesystem model +.LP +NFS assumes a file system that is hierarchical, with directories as +all but the bottom-level files. Each entry in a directory (file, +directory, device, etc.) has a string name. Different operating +systems may have restrictions on the depth of the tree or the names +used, as well as using different syntax to represent the "pathname", +which is the concatenation of all the "components" (directory and +file names) in the name. A "file system" is a tree on a single +server (usually a single disk or physical partition) with a specified +"root". Some operating systems provide a "mount" operation to make +all file systems appear as a single tree, while others maintain a +"forest" of file systems. Files are unstructured streams of +uninterpreted bytes. Version 3 of NFS uses a slightly more general +file system model. +.LP +NFS looks up one component of a pathname at a time. It may not be +obvious why it does not just take the whole pathname, traipse down +the directories, and return a file handle when it is done. There are +several good reasons not to do this. First, pathnames need +separators between the directory components, and different operating +systems use different separators. We could define a Network Standard +Pathname Representation, but then every pathname would have to be +parsed and converted at each end. Other issues are discussed in +\fINFS Implementation Issues\fP below. +.LP +Although files and directories are similar objects in many ways, +different procedures are used to read directories and files. This +provides a network standard format for representing directories. The +same argument as above could have been used to justify a procedure +that returns only one directory entry per call. The problem is +efficiency. Directories can contain many entries, and a remote call +to return each would be just too slow. +.NH 2 +\&RPC Information +.IX NFS "RPC information" +.IP \fIAuthentication\fP +The NFS service uses +.I AUTH_UNIX , +.I AUTH_DES , +or +.I AUTH_SHORT +style +authentication, except in the NULL procedure where +.I AUTH_NONE +is also allowed. +.IP "\fITransport Protocols\fP" +NFS currently is supported on UDP/IP only. +.IP "\fIPort Number\fP" +The NFS protocol currently uses the UDP port number 2049. This is +not an officially assigned port, so later versions of the protocol +use the \*QPortmapping\*U facility of RPC. +.NH 2 +\&Sizes of XDR Structures +.IX "XDR structure sizes" +.LP +These are the sizes, given in decimal bytes, of various XDR +structures used in the protocol: +.DS +/* \fIThe maximum number of bytes of data in a READ or WRITE request\fP */ +const MAXDATA = 8192; + +/* \fIThe maximum number of bytes in a pathname argument\fP */ +const MAXPATHLEN = 1024; + +/* \fIThe maximum number of bytes in a file name argument\fP */ +const MAXNAMLEN = 255; + +/* \fIThe size in bytes of the opaque "cookie" passed by READDIR\fP */ +const COOKIESIZE = 4; + +/* \fIThe size in bytes of the opaque file handle\fP */ +const FHSIZE = 32; +.DE +.NH 2 +\&Basic Data Types +.IX "NFS data types" +.IX NFS "basic data types" +.LP +The following XDR definitions are basic structures and types used +in other structures described further on. +.KS +.NH 3 +\&stat +.IX "NFS data types" stat "" \fIstat\fP +.DS +enum stat { + NFS_OK = 0, + NFSERR_PERM=1, + NFSERR_NOENT=2, + NFSERR_IO=5, + NFSERR_NXIO=6, + NFSERR_ACCES=13, + NFSERR_EXIST=17, + NFSERR_NODEV=19, + NFSERR_NOTDIR=20, + NFSERR_ISDIR=21, + NFSERR_FBIG=27, + NFSERR_NOSPC=28, + NFSERR_ROFS=30, + NFSERR_NAMETOOLONG=63, + NFSERR_NOTEMPTY=66, + NFSERR_DQUOT=69, + NFSERR_STALE=70, + NFSERR_WFLUSH=99 +}; +.DE +.KE +.LP +The +.I stat +type is returned with every procedure's results. A +value of +.I NFS_OK +indicates that the call completed successfully and +the results are valid. The other values indicate some kind of +error occurred on the server side during the servicing of the +procedure. The error values are derived from UNIX error numbers. +.IP \fBNFSERR_PERM\fP: +Not owner. The caller does not have correct ownership +to perform the requested operation. +.IP \fBNFSERR_NOENT\fP: +No such file or directory. The file or directory +specified does not exist. +.IP \fBNFSERR_IO\fP: +Some sort of hard error occurred when the operation was +in progress. This could be a disk error, for example. +.IP \fBNFSERR_NXIO\fP: +No such device or address. +.IP \fBNFSERR_ACCES\fP: +Permission denied. The caller does not have the +correct permission to perform the requested operation. +.IP \fBNFSERR_EXIST\fP: +File exists. The file specified already exists. +.IP \fBNFSERR_NODEV\fP: +No such device. +.IP \fBNFSERR_NOTDIR\fP: +Not a directory. The caller specified a +non-directory in a directory operation. +.IP \fBNFSERR_ISDIR\fP: +Is a directory. The caller specified a directory in +a non- directory operation. +.IP \fBNFSERR_FBIG\fP: +File too large. The operation caused a file to grow +beyond the server's limit. +.IP \fBNFSERR_NOSPC\fP: +No space left on device. The operation caused the +server's filesystem to reach its limit. +.IP \fBNFSERR_ROFS\fP: +Read-only filesystem. Write attempted on a read-only filesystem. +.IP \fBNFSERR_NAMETOOLONG\fP: +File name too long. The file name in an operation was too long. +.IP \fBNFSERR_NOTEMPTY\fP: +Directory not empty. Attempted to remove a +directory that was not empty. +.IP \fBNFSERR_DQUOT\fP: +Disk quota exceeded. The client's disk quota on the +server has been exceeded. +.IP \fBNFSERR_STALE\fP: +The "fhandle" given in the arguments was invalid. +That is, the file referred to by that file handle no longer exists, +or access to it has been revoked. +.IP \fBNFSERR_WFLUSH\fP: +The server's write cache used in the +.I WRITECACHE +call got flushed to disk. +.LP +.KS +.NH 3 +\&ftype +.IX "NFS data types" ftype "" \fIftype\fP +.DS +enum ftype { + NFNON = 0, + NFREG = 1, + NFDIR = 2, + NFBLK = 3, + NFCHR = 4, + NFLNK = 5 +}; +.DE +.KE +The enumeration +.I ftype +gives the type of a file. The type +.I NFNON +indicates a non-file, +.I NFREG +is a regular file, +.I NFDIR +is a directory, +.I NFBLK +is a block-special device, +.I NFCHR +is a character-special device, and +.I NFLNK +is a symbolic link. +.KS +.NH 3 +\&fhandle +.IX "NFS data types" fhandle "" \fIfhandle\fP +.DS +typedef opaque fhandle[FHSIZE]; +.DE +.KE +The +.I fhandle +is the file handle passed between the server and the client. +All file operations are done using file handles to refer to a file or +directory. The file handle can contain whatever information the server +needs to distinguish an individual file. +.KS +.NH 3 +\&timeval +.IX "NFS data types" timeval "" \fItimeval\fP +.DS +struct timeval { + unsigned int seconds; + unsigned int useconds; +}; +.DE +.KE +The +.I timeval +structure is the number of seconds and microseconds +since midnight January 1, 1970, Greenwich Mean Time. It is used to +pass time and date information. +.KS +.NH 3 +\&fattr +.IX "NFS data types" fattr "" \fIfattr\fP +.DS +struct fattr { + ftype type; + unsigned int mode; + unsigned int nlink; + unsigned int uid; + unsigned int gid; + unsigned int size; + unsigned int blocksize; + unsigned int rdev; + unsigned int blocks; + unsigned int fsid; + unsigned int fileid; + timeval atime; + timeval mtime; + timeval ctime; +}; +.DE +.KE +The +.I fattr +structure contains the attributes of a file; "type" is the type of +the file; "nlink" is the number of hard links to the file (the number +of different names for the same file); "uid" is the user +identification number of the owner of the file; "gid" is the group +identification number of the group of the file; "size" is the size in +bytes of the file; "blocksize" is the size in bytes of a block of the +file; "rdev" is the device number of the file if it is type +.I NFCHR +or +.I NFBLK ; +"blocks" is the number of blocks the file takes up on disk; "fsid" is +the file system identifier for the filesystem containing the file; +"fileid" is a number that uniquely identifies the file within its +filesystem; "atime" is the time when the file was last accessed for +either read or write; "mtime" is the time when the file data was last +modified (written); and "ctime" is the time when the status of the +file was last changed. Writing to the file also changes "ctime" if +the size of the file changes. +.LP +"mode" is the access mode encoded as a set of bits. Notice that the +file type is specified both in the mode bits and in the file type. +This is really a bug in the protocol and will be fixed in future +versions. The descriptions given below specify the bit positions +using octal numbers. +.TS +box tab (&) ; +cfI cfI +lfL l . +Bit&Description +_ +0040000&This is a directory; "type" field should be NFDIR. +0020000&This is a character special file; "type" field should be NFCHR. +0060000&This is a block special file; "type" field should be NFBLK. +0100000&This is a regular file; "type" field should be NFREG. +0120000&This is a symbolic link file; "type" field should be NFLNK. +0140000&This is a named socket; "type" field should be NFNON. +0004000&Set user id on execution. +0002000&Set group id on execution. +0001000&Save swapped text even after use. +0000400&Read permission for owner. +0000200&Write permission for owner. +0000100&Execute and search permission for owner. +0000040&Read permission for group. +0000020&Write permission for group. +0000010&Execute and search permission for group. +0000004&Read permission for others. +0000002&Write permission for others. +0000001&Execute and search permission for others. +.TE +.KS +Notes: +.IP +The bits are the same as the mode bits returned by the +.I stat(2) +system call in the UNIX system. The file type is specified both in +the mode bits and in the file type. This is fixed in future +versions. +.IP +The "rdev" field in the attributes structure is an operating system +specific device specifier. It will be removed and generalized in +the next revision of the protocol. +.KE +.LP +.KS +.NH 3 +\&sattr +.IX "NFS data types" sattr "" \fIsattr\fP +.DS +struct sattr { + unsigned int mode; + unsigned int uid; + unsigned int gid; + unsigned int size; + timeval atime; + timeval mtime; +}; +.DE +.KE +The +.I sattr +structure contains the file attributes which can be set +from the client. The fields are the same as for +.I fattr +above. A "size" of zero means the file should be truncated. +A value of -1 indicates a field that should be ignored. +.LP +.KS +.NH 3 +\&filename +.IX "NFS data types" filename "" \fIfilename\fP +.DS +typedef string filename<MAXNAMLEN>; +.DE +.KE +The type +.I filename +is used for passing file names or pathname components. +.LP +.KS +.NH 3 +\&path +.IX "NFS data types" path "" \fIpath\fP +.DS +typedef string path<MAXPATHLEN>; +.DE +.KE +The type +.I path +is a pathname. The server considers it as a string +with no internal structure, but to the client it is the name of a +node in a filesystem tree. +.LP +.KS +.NH 3 +\&attrstat +.IX "NFS data types" attrstat "" \fIattrstat\fP +.DS +union attrstat switch (stat status) { + case NFS_OK: + fattr attributes; + default: + void; +}; +.DE +.KE +The +.I attrstat +structure is a common procedure result. It contains +a "status" and, if the call succeeded, it also contains the +attributes of the file on which the operation was done. +.LP +.KS +.NH 3 +\&diropargs +.IX "NFS data types" diropargs "" \fIdiropargs\fP +.DS +struct diropargs { + fhandle dir; + filename name; +}; +.DE +.KE +The +.I diropargs +structure is used in directory operations. The +"fhandle" "dir" is the directory in which to find the file "name". +A directory operation is one in which the directory is affected. +.LP +.KS +.NH 3 +\&diropres +.IX "NFS data types" diropres "" \fIdiropres\fP +.DS +union diropres switch (stat status) { + case NFS_OK: + struct { + fhandle file; + fattr attributes; + } diropok; + default: + void; +}; +.DE +.KE +The results of a directory operation are returned in a +.I diropres +structure. If the call succeeded, a new file handle "file" and the +"attributes" associated with that file are returned along with the +"status". +.NH 2 +\&Server Procedures +.IX "NFS server procedures" "" "" "" PAGE MAJOR +.LP +The protocol definition is given as a set of procedures with +arguments and results defined using the RPC language. A brief +description of the function of each procedure should provide enough +information to allow implementation. +.LP +All of the procedures in the NFS protocol are assumed to be +synchronous. When a procedure returns to the client, the client +can assume that the operation has completed and any data associated +with the request is now on stable storage. For example, a client +.I WRITE +request may cause the server to update data blocks, +filesystem information blocks (such as indirect blocks), and file +attribute information (size and modify times). When the +.I WRITE +returns to the client, it can assume that the write is safe, even +in case of a server crash, and it can discard the data written. +This is a very important part of the statelessness of the server. +If the server waited to flush data from remote requests, the client +would have to save those requests so that it could resend them in +case of a server crash. +.ie t .DS +.el .DS L + +.ft I +/* +* Remote file service routines +*/ +.ft CW +program NFS_PROGRAM { + version NFS_VERSION { + void NFSPROC_NULL(void) = 0; + attrstat NFSPROC_GETATTR(fhandle) = 1; + attrstat NFSPROC_SETATTR(sattrargs) = 2; + void NFSPROC_ROOT(void) = 3; + diropres NFSPROC_LOOKUP(diropargs) = 4; + readlinkres NFSPROC_READLINK(fhandle) = 5; + readres NFSPROC_READ(readargs) = 6; + void NFSPROC_WRITECACHE(void) = 7; + attrstat NFSPROC_WRITE(writeargs) = 8; + diropres NFSPROC_CREATE(createargs) = 9; + stat NFSPROC_REMOVE(diropargs) = 10; + stat NFSPROC_RENAME(renameargs) = 11; + stat NFSPROC_LINK(linkargs) = 12; + stat NFSPROC_SYMLINK(symlinkargs) = 13; + diropres NFSPROC_MKDIR(createargs) = 14; + stat NFSPROC_RMDIR(diropargs) = 15; + readdirres NFSPROC_READDIR(readdirargs) = 16; + statfsres NFSPROC_STATFS(fhandle) = 17; + } = 2; +} = 100003; +.DE +.KS +.NH 3 +\&Do Nothing +.IX "NFS server procedures" NFSPROC_NULL() "" \fINFSPROC_NULL()\fP +.DS +void +NFSPROC_NULL(void) = 0; +.DE +.KE +This procedure does no work. It is made available in all RPC +services to allow server response testing and timing. +.KS +.NH 3 +\&Get File Attributes +.IX "NFS server procedures" NFSPROC_GETATTR() "" \fINFSPROC_GETATTR()\fP +.DS +attrstat +NFSPROC_GETATTR (fhandle) = 1; +.DE +.KE +If the reply status is +.I NFS_OK , +then the reply attributes contains +the attributes for the file given by the input fhandle. +.KS +.NH 3 +\&Set File Attributes +.IX "NFS server procedures" NFSPROC_SETATTR() "" \fINFSPROC_SETATTR()\fP +.DS +struct sattrargs { + fhandle file; + sattr attributes; + }; + +attrstat +NFSPROC_SETATTR (sattrargs) = 2; +.DE +.KE +The "attributes" argument contains fields which are either -1 or +are the new value for the attributes of "file". If the reply +status is +.I NFS_OK , +then the reply attributes have the attributes of +the file after the "SETATTR" operation has completed. +.LP +Note: The use of -1 to indicate an unused field in "attributes" is +changed in the next version of the protocol. +.KS +.NH 3 +\&Get Filesystem Root +.IX "NFS server procedures" NFSPROC_ROOT "" \fINFSPROC_ROOT\fP +.DS +void +NFSPROC_ROOT(void) = 3; +.DE +.KE +Obsolete. This procedure is no longer used because finding the +root file handle of a filesystem requires moving pathnames between +client and server. To do this right we would have to define a +network standard representation of pathnames. Instead, the +function of looking up the root file handle is done by the +.I MNTPROC_MNT() +procedure. (See the +.I "Mount Protocol Definition" +later in this chapter for details). +.KS +.NH 3 +\&Look Up File Name +.IX "NFS server procedures" NFSPROC_LOOKUP() "" \fINFSPROC_LOOKUP()\fP +.DS +diropres +NFSPROC_LOOKUP(diropargs) = 4; +.DE +.KE +If the reply "status" is +.I NFS_OK , +then the reply "file" and reply +"attributes" are the file handle and attributes for the file "name" +in the directory given by "dir" in the argument. +.KS +.NH 3 +\&Read From Symbolic Link +.IX "NFS server procedures" NFSPROC_READLINK() "" \fINFSPROC_READLINK()\fP +.DS +union readlinkres switch (stat status) { + case NFS_OK: + path data; + default: + void; +}; + +readlinkres +NFSPROC_READLINK(fhandle) = 5; +.DE +.KE +If "status" has the value +.I NFS_OK , +then the reply "data" is the data in +the symbolic link given by the file referred to by the fhandle argument. +.LP +Note: since NFS always parses pathnames on the client, the +pathname in a symbolic link may mean something different (or be +meaningless) on a different client or on the server if a different +pathname syntax is used. +.KS +.NH 3 +\&Read From File +.IX "NFS server procedures" NFSPROC_READ "" \fINFSPROC_READ\fP +.DS +struct readargs { + fhandle file; + unsigned offset; + unsigned count; + unsigned totalcount; +}; + +union readres switch (stat status) { + case NFS_OK: + fattr attributes; + opaque data<NFS_MAXDATA>; + default: + void; +}; + +readres +NFSPROC_READ(readargs) = 6; +.DE +.KE +Returns up to "count" bytes of "data" from the file given by +"file", starting at "offset" bytes from the beginning of the file. +The first byte of the file is at offset zero. The file attributes +after the read takes place are returned in "attributes". +.LP +Note: The argument "totalcount" is unused, and is removed in the +next protocol revision. +.KS +.NH 3 +\&Write to Cache +.IX "NFS server procedures" NFSPROC_WRITECACHE() "" \fINFSPROC_WRITECACHE()\fP +.DS +void +NFSPROC_WRITECACHE(void) = 7; +.DE +.KE +To be used in the next protocol revision. +.KS +.NH 3 +\&Write to File +.IX "NFS server procedures" NFSPROC_WRITE() "" \fINFSPROC_WRITE()\fP +.DS +struct writeargs { + fhandle file; + unsigned beginoffset; + unsigned offset; + unsigned totalcount; + opaque data<NFS_MAXDATA>; +}; + +attrstat +NFSPROC_WRITE(writeargs) = 8; +.DE +.KE +Writes "data" beginning "offset" bytes from the beginning of +"file". The first byte of the file is at offset zero. If the +reply "status" is NFS_OK, then the reply "attributes" contains the +attributes of the file after the write has completed. The write +operation is atomic. Data from this call to +.I WRITE +will not be mixed with data from another client's calls. +.LP +Note: The arguments "beginoffset" and "totalcount" are ignored and +are removed in the next protocol revision. +.KS +.NH 3 +\&Create File +.IX "NFS server procedures" NFSPROC_CREATE() "" \fINFSPROC_CREATE()\fP +.DS +struct createargs { + diropargs where; + sattr attributes; +}; + +diropres +NFSPROC_CREATE(createargs) = 9; +.DE +.KE +The file "name" is created in the directory given by "dir". The +initial attributes of the new file are given by "attributes". A +reply "status" of NFS_OK indicates that the file was created, and +reply "file" and reply "attributes" are its file handle and +attributes. Any other reply "status" means that the operation +failed and no file was created. +.LP +Note: This routine should pass an exclusive create flag, meaning +"create the file only if it is not already there". +.KS +.NH 3 +\&Remove File +.IX "NFS server procedures" NFSPROC_REMOVE() "" \fINFSPROC_REMOVE()\fP +.DS +stat +NFSPROC_REMOVE(diropargs) = 10; +.DE +.KE +The file "name" is removed from the directory given by "dir". A +reply of NFS_OK means the directory entry was removed. +.LP +Note: possibly non-idempotent operation. +.KS +.NH 3 +\&Rename File +.IX "NFS server procedures" NFSPROC_RENAME() "" \fINFSPROC_RENAME()\fP +.DS +struct renameargs { + diropargs from; + diropargs to; +}; + +stat +NFSPROC_RENAME(renameargs) = 11; +.DE +.KE +The existing file "from.name" in the directory given by "from.dir" +is renamed to "to.name" in the directory given by "to.dir". If the +reply is +.I NFS_OK , +the file was renamed. The +RENAME +operation is +atomic on the server; it cannot be interrupted in the middle. +.LP +Note: possibly non-idempotent operation. +.KS +.NH 3 +\&Create Link to File +.IX "NFS server procedures" NFSPROC_LINK() "" \fINFSPROC_LINK()\fP +.DS +struct linkargs { + fhandle from; + diropargs to; +}; + +stat +NFSPROC_LINK(linkargs) = 12; +.DE +.KE +Creates the file "to.name" in the directory given by "to.dir", +which is a hard link to the existing file given by "from". If the +return value is +.I NFS_OK , +a link was created. Any other return value +indicates an error, and the link was not created. +.LP +A hard link should have the property that changes to either of the +linked files are reflected in both files. When a hard link is made +to a file, the attributes for the file should have a value for +"nlink" that is one greater than the value before the link. +.LP +Note: possibly non-idempotent operation. +.KS +.NH 3 +\&Create Symbolic Link +.IX "NFS server procedures" NFSPROC_SYMLINK() "" \fINFSPROC_SYMLINK()\fP +.DS +struct symlinkargs { + diropargs from; + path to; + sattr attributes; +}; + +stat +NFSPROC_SYMLINK(symlinkargs) = 13; +.DE +.KE +Creates the file "from.name" with ftype +.I NFLNK +in the directory +given by "from.dir". The new file contains the pathname "to" and +has initial attributes given by "attributes". If the return value +is +.I NFS_OK , +a link was created. Any other return value indicates an +error, and the link was not created. +.LP +A symbolic link is a pointer to another file. The name given in +"to" is not interpreted by the server, only stored in the newly +created file. When the client references a file that is a symbolic +link, the contents of the symbolic link are normally transparently +reinterpreted as a pathname to substitute. A +.I READLINK +operation returns the data to the client for interpretation. +.LP +Note: On UNIX servers the attributes are never used, since +symbolic links always have mode 0777. +.KS +.NH 3 +\&Create Directory +.IX "NFS server procedures" NFSPROC_MKDIR() "" \fINFSPROC_MKDIR()\fP +.DS +diropres +NFSPROC_MKDIR (createargs) = 14; +.DE +.KE +The new directory "where.name" is created in the directory given by +"where.dir". The initial attributes of the new directory are given +by "attributes". A reply "status" of NFS_OK indicates that the new +directory was created, and reply "file" and reply "attributes" are +its file handle and attributes. Any other reply "status" means +that the operation failed and no directory was created. +.LP +Note: possibly non-idempotent operation. +.KS +.NH 3 +\&Remove Directory +.IX "NFS server procedures" NFSPROC_RMDIR() "" \fINFSPROC_RMDIR()\fP +.DS +stat +NFSPROC_RMDIR(diropargs) = 15; +.DE +.KE +The existing empty directory "name" in the directory given by "dir" +is removed. If the reply is +.I NFS_OK , +the directory was removed. +.LP +Note: possibly non-idempotent operation. +.KS +.NH 3 +\&Read From Directory +.IX "NFS server procedures" NFSPROC_READDIR() "" \fINFSPROC_READDIR()\fP +.DS +struct readdirargs { + fhandle dir; + nfscookie cookie; + unsigned count; +}; + +struct entry { + unsigned fileid; + filename name; + nfscookie cookie; + entry *nextentry; +}; + +union readdirres switch (stat status) { + case NFS_OK: + struct { + entry *entries; + bool eof; + } readdirok; + default: + void; +}; + +readdirres +NFSPROC_READDIR (readdirargs) = 16; +.DE +.KE +Returns a variable number of directory entries, with a total size +of up to "count" bytes, from the directory given by "dir". If the +returned value of "status" is +.I NFS_OK , +then it is followed by a +variable number of "entry"s. Each "entry" contains a "fileid" +which consists of a unique number to identify the file within a +filesystem, the "name" of the file, and a "cookie" which is an +opaque pointer to the next entry in the directory. The cookie is +used in the next +.I READDIR +call to get more entries starting at a +given point in the directory. The special cookie zero (all bits +zero) can be used to get the entries starting at the beginning of +the directory. The "fileid" field should be the same number as the +"fileid" in the the attributes of the file. (See the +.I "Basic Data Types" +section.) +The "eof" flag has a value of +.I TRUE +if there are no more entries in the directory. +.KS +.NH 3 +\&Get Filesystem Attributes +.IX "NFS server procedures" NFSPROC_STATFS() "" \fINFSPROC_STATFS()\fP +.DS +union statfsres (stat status) { + case NFS_OK: + struct { + unsigned tsize; + unsigned bsize; + unsigned blocks; + unsigned bfree; + unsigned bavail; + } info; + default: + void; +}; + +statfsres +NFSPROC_STATFS(fhandle) = 17; +.DE +.KE +If the reply "status" is +.I NFS_OK , +then the reply "info" gives the +attributes for the filesystem that contains file referred to by the +input fhandle. The attribute fields contain the following values: +.IP tsize: +The optimum transfer size of the server in bytes. This is +the number of bytes the server would like to have in the +data part of READ and WRITE requests. +.IP bsize: +The block size in bytes of the filesystem. +.IP blocks: +The total number of "bsize" blocks on the filesystem. +.IP bfree: +The number of free "bsize" blocks on the filesystem. +.IP bavail: +The number of "bsize" blocks available to non-privileged users. +.LP +Note: This call does not work well if a filesystem has variable +size blocks. +.NH 1 +\&NFS Implementation Issues +.IX NFS implementation +.LP +The NFS protocol is designed to be operating system independent, but +since this version was designed in a UNIX environment, many +operations have semantics similar to the operations of the UNIX file +system. This section discusses some of the implementation-specific +semantic issues. +.NH 2 +\&Server/Client Relationship +.IX NFS "server/client relationship" +.LP +The NFS protocol is designed to allow servers to be as simple and +general as possible. Sometimes the simplicity of the server can be a +problem, if the client wants to implement complicated filesystem +semantics. +.LP +For example, some operating systems allow removal of open files. A +process can open a file and, while it is open, remove it from the +directory. The file can be read and written as long as the process +keeps it open, even though the file has no name in the filesystem. +It is impossible for a stateless server to implement these semantics. +The client can do some tricks such as renaming the file on remove, +and only removing it on close. We believe that the server provides +enough functionality to implement most file system semantics on the +client. +.LP +Every NFS client can also potentially be a server, and remote and +local mounted filesystems can be freely intermixed. This leads to +some interesting problems when a client travels down the directory +tree of a remote filesystem and reaches the mount point on the server +for another remote filesystem. Allowing the server to follow the +second remote mount would require loop detection, server lookup, and +user revalidation. Instead, we decided not to let clients cross a +server's mount point. When a client does a LOOKUP on a directory on +which the server has mounted a filesystem, the client sees the +underlying directory instead of the mounted directory. A client can +do remote mounts that match the server's mount points to maintain the +server's view. +.LP +.NH 2 +\&Pathname Interpretation +.IX NFS "pathname interpretation" +.LP +There are a few complications to the rule that pathnames are always +parsed on the client. For example, symbolic links could have +different interpretations on different clients. Another common +problem for non-UNIX implementations is the special interpretation of +the pathname ".." to mean the parent of a given directory. The next +revision of the protocol uses an explicit flag to indicate the parent +instead. +.NH 2 +\&Permission Issues +.IX NFS "permission issues" +.LP +The NFS protocol, strictly speaking, does not define the permission +checking used by servers. However, it is expected that a server +will do normal operating system permission checking using +.I AUTH_UNIX +style authentication as the basis of its protection mechanism. The +server gets the client's effective "uid", effective "gid", and groups +on each call and uses them to check permission. There are various +problems with this method that can been resolved in interesting ways. +.LP +Using "uid" and "gid" implies that the client and server share the +same "uid" list. Every server and client pair must have the same +mapping from user to "uid" and from group to "gid". Since every +client can also be a server, this tends to imply that the whole +network shares the same "uid/gid" space. +.I AUTH_DES +(and the next +revision of the NFS protocol) uses string names instead of numbers, +but there are still complex problems to be solved. +.LP +Another problem arises due to the usually stateful open operation. +Most operating systems check permission at open time, and then check +that the file is open on each read and write request. With stateless +servers, the server has no idea that the file is open and must do +permission checking on each read and write call. On a local +filesystem, a user can open a file and then change the permissions so +that no one is allowed to touch it, but will still be able to write +to the file because it is open. On a remote filesystem, by contrast, +the write would fail. To get around this problem, the server's +permission checking algorithm should allow the owner of a file to +access it regardless of the permission setting. +.LP +A similar problem has to do with paging in from a file over the +network. The operating system usually checks for execute permission +before opening a file for demand paging, and then reads blocks from +the open file. The file may not have read permission, but after it +is opened it doesn't matter. An NFS server can not tell the +difference between a normal file read and a demand page-in read. To +make this work, the server allows reading of files if the "uid" given +in the call has execute or read permission on the file. +.LP +In most operating systems, a particular user (on the user ID zero) +has access to all files no matter what permission and ownership they +have. This "super-user" permission may not be allowed on the server, +since anyone who can become super-user on their workstation could +gain access to all remote files. The UNIX server by default maps +user id 0 to -2 before doing its access checking. This works except +for NFS root filesystems, where super-user access cannot be avoided. +.NH 2 +\&Setting RPC Parameters +.IX NFS "setting RPC parameters" +.LP +Various file system parameters and options should be set at mount +time. The mount protocol is described in the appendix below. For +example, "Soft" mounts as well as "Hard" mounts are usually both +provided. Soft mounted file systems return errors when RPC +operations fail (after a given number of optional retransmissions), +while hard mounted file systems continue to retransmit forever. +Clients and servers may need to keep caches of recent operations to +help avoid problems with non-idempotent operations. +.NH 1 +\&Mount Protocol Definition +.IX "mount protocol" "" "" "" PAGE MAJOR +.sp 1 +.NH 2 +\&Introduction +.IX "mount protocol" introduction +.LP +The mount protocol is separate from, but related to, the NFS +protocol. It provides operating system specific services to get the +NFS off the ground -- looking up server path names, validating user +identity, and checking access permissions. Clients use the mount +protocol to get the first file handle, which allows them entry into a +remote filesystem. +.LP +The mount protocol is kept separate from the NFS protocol to make it +easy to plug in new access checking and validation methods without +changing the NFS server protocol. +.LP +Notice that the protocol definition implies stateful servers because +the server maintains a list of client's mount requests. The mount +list information is not critical for the correct functioning of +either the client or the server. It is intended for advisory use +only, for example, to warn possible clients when a server is going +down. +.LP +Version one of the mount protocol is used with version two of the NFS +protocol. The only connecting point is the +.I fhandle +structure, which is the same for both protocols. +.NH 2 +\&RPC Information +.IX "mount protocol" "RPC information" +.IP \fIAuthentication\fP +The mount service uses +.I AUTH_UNIX +and +.I AUTH_DES +style authentication only. +.IP "\fITransport Protocols\fP" +The mount service is currently supported on UDP/IP only. +.IP "\fIPort Number\fP" +Consult the server's portmapper, described in the chapter +.I "Remote Procedure Calls: Protocol Specification", +to find the port number on which the mount service is registered. +.NH 2 +\&Sizes of XDR Structures +.IX "mount protocol" "XDR structure sizes" +.LP +These are the sizes, given in decimal bytes, of various XDR +structures used in the protocol: +.DS +/* \fIThe maximum number of bytes in a pathname argument\fP */ +const MNTPATHLEN = 1024; + +/* \fIThe maximum number of bytes in a name argument\fP */ +const MNTNAMLEN = 255; + +/* \fIThe size in bytes of the opaque file handle\fP */ +const FHSIZE = 32; +.DE +.NH 2 +\&Basic Data Types +.IX "mount protocol" "basic data types" +.IX "mount data types" +.LP +This section presents the data types used by the mount protocol. +In many cases they are similar to the types used in NFS. +.KS +.NH 3 +\&fhandle +.IX "mount data types" fhandle "" \fIfhandle\fP +.DS +typedef opaque fhandle[FHSIZE]; +.DE +.KE +The type +.I fhandle +is the file handle that the server passes to the +client. All file operations are done using file handles to refer +to a file or directory. The file handle can contain whatever +information the server needs to distinguish an individual file. +.LP +This is the same as the "fhandle" XDR definition in version 2 of +the NFS protocol; see +.I "Basic Data Types" +in the definition of the NFS protocol, above. +.KS +.NH 3 +\&fhstatus +.IX "mount data types" fhstatus "" \fIfhstatus\fP +.DS +union fhstatus switch (unsigned status) { + case 0: + fhandle directory; + default: + void; +}; +.DE +.KE +The type +.I fhstatus +is a union. If a "status" of zero is returned, +the call completed successfully, and a file handle for the +"directory" follows. A non-zero status indicates some sort of +error. In this case the status is a UNIX error number. +.KS +.NH 3 +\&dirpath +.IX "mount data types" dirpath "" \fIdirpath\fP +.DS +typedef string dirpath<MNTPATHLEN>; +.DE +.KE +The type +.I dirpath +is a server pathname of a directory. +.KS +.NH 3 +\&name +.IX "mount data types" name "" \fIname\fP +.DS +typedef string name<MNTNAMLEN>; +.DE +.KE +The type +.I name +is an arbitrary string used for various names. +.NH 2 +\&Server Procedures +.IX "mount server procedures" +.LP +The following sections define the RPC procedures supplied by a +mount server. +.ie t .DS +.el .DS L +.ft I +/* +* Protocol description for the mount program +*/ +.ft CW + +program MOUNTPROG { +.ft I +/* +* Version 1 of the mount protocol used with +* version 2 of the NFS protocol. +*/ +.ft CW + version MOUNTVERS { + void MOUNTPROC_NULL(void) = 0; + fhstatus MOUNTPROC_MNT(dirpath) = 1; + mountlist MOUNTPROC_DUMP(void) = 2; + void MOUNTPROC_UMNT(dirpath) = 3; + void MOUNTPROC_UMNTALL(void) = 4; + exportlist MOUNTPROC_EXPORT(void) = 5; + } = 1; +} = 100005; +.DE +.KS +.NH 3 +\&Do Nothing +.IX "mount server procedures" MNTPROC_NULL() "" \fIMNTPROC_NULL()\fP +.DS +void +MNTPROC_NULL(void) = 0; +.DE +.KE +This procedure does no work. It is made available in all RPC +services to allow server response testing and timing. +.KS +.NH 3 +\&Add Mount Entry +.IX "mount server procedures" MNTPROC_MNT() "" \fIMNTPROC_MNT()\fP +.DS +fhstatus +MNTPROC_MNT(dirpath) = 1; +.DE +.KE +If the reply "status" is 0, then the reply "directory" contains the +file handle for the directory "dirname". This file handle may be +used in the NFS protocol. This procedure also adds a new entry to +the mount list for this client mounting "dirname". +.KS +.NH 3 +\&Return Mount Entries +.IX "mount server procedures" MNTPROC_DUMP() "" \fIMNTPROC_DUMP()\fP +.DS +struct *mountlist { + name hostname; + dirpath directory; + mountlist nextentry; +}; + +mountlist +MNTPROC_DUMP(void) = 2; +.DE +.KE +Returns the list of remote mounted filesystems. The "mountlist" +contains one entry for each "hostname" and "directory" pair. +.KS +.NH 3 +\&Remove Mount Entry +.IX "mount server procedures" MNTPROC_UMNT() "" \fIMNTPROC_UMNT()\fP +.DS +void +MNTPROC_UMNT(dirpath) = 3; +.DE +.KE +Removes the mount list entry for the input "dirpath". +.KS +.NH 3 +\&Remove All Mount Entries +.IX "mount server procedures" MNTPROC_UMNTALL() "" \fIMNTPROC_UMNTALL()\fP +.DS +void +MNTPROC_UMNTALL(void) = 4; +.DE +.KE +Removes all of the mount list entries for this client. +.KS +.NH 3 +\&Return Export List +.IX "mount server procedures" MNTPROC_EXPORT() "" \fIMNTPROC_EXPORT()\fP +.DS +struct *groups { + name grname; + groups grnext; +}; + +struct *exportlist { + dirpath filesys; + groups groups; + exportlist next; +}; + +exportlist +MNTPROC_EXPORT(void) = 5; +.DE +.KE +Returns a variable number of export list entries. Each entry +contains a filesystem name and a list of groups that are allowed to +import it. The filesystem name is in "filesys", and the group name +is in the list "groups". +.LP +Note: The exportlist should contain +more information about the status of the filesystem, such as a +read-only flag. diff --git a/cpukit/librpc/src/rpc/PSD.doc/rpc.prog.ms b/cpukit/librpc/src/rpc/PSD.doc/rpc.prog.ms index e69de29bb2..3b02447fe8 100644 --- a/cpukit/librpc/src/rpc/PSD.doc/rpc.prog.ms +++ b/cpukit/librpc/src/rpc/PSD.doc/rpc.prog.ms @@ -0,0 +1,2684 @@ +.\" +.\" Must use -- tbl and pic -- with this one +.\" +.\" @(#)rpc.prog.ms 2.3 88/08/11 4.0 RPCSRC +.de BT +.if \\n%=1 .tl ''- % -'' +.. +.IX "Network Programming" "" "" "" PAGE MAJOR +.nr OF 0 +.ND +.\" prevent excess underlining in nroff +.if n .fp 2 R +.OH 'Remote Procedure Call Programming Guide''Page %' +.EH 'Page %''Remote Procedure Call Programming Guide' +.SH +\&Remote Procedure Call Programming Guide +.nr OF 1 +.IX "RPC Programming Guide" +.LP +This document assumes a working knowledge of network theory. It is +intended for programmers who wish to write network applications using +remote procedure calls (explained below), and who want to understand +the RPC mechanisms usually hidden by the +.I rpcgen(1) +protocol compiler. +.I rpcgen +is described in detail in the previous chapter, the +.I "\fBrpcgen\fP \fIProgramming Guide\fP". +.SH +Note: +.I +.IX rpcgen "" \fIrpcgen\fP +Before attempting to write a network application, or to convert an +existing non-network application to run over the network, you may want to +understand the material in this chapter. However, for most applications, +you can circumvent the need to cope with the details presented here by using +.I rpcgen . +The +.I "Generating XDR Routines" +section of that chapter contains the complete source for a working RPC +service\(ema remote directory listing service which uses +.I rpcgen +to generate XDR routines as well as client and server stubs. +.LP +.LP +What are remote procedure calls? Simply put, they are the high-level +communications paradigm used in the operating system. +RPC presumes the existence of +low-level networking mechanisms (such as TCP/IP and UDP/IP), and upon them +it implements a logical client to server communications system designed +specifically for the support of network applications. With RPC, the client +makes a procedure call to send a data packet to the server. When the +packet arrives, the server calls a dispatch routine, performs whatever +service is requested, sends back the reply, and the procedure call returns +to the client. +.NH 0 +\&Layers of RPC +.IX "layers of RPC" +.IX "RPC" "layers" +.LP +The RPC interface can be seen as being divided into three layers.\** +.FS +For a complete specification of the routines in the remote procedure +call Library, see the +.I rpc(3N) +manual page. +.FE +.LP +.I "The Highest Layer:" +.IX RPC "The Highest Layer" +The highest layer is totally transparent to the operating system, +machine and network upon which is is run. It's probably best to +think of this level as a way of +.I using +RPC, rather than as +a \fIpart of\fP RPC proper. Programmers who write RPC routines +should (almost) always make this layer available to others by way +of a simple C front end that entirely hides the networking. +.LP +To illustrate, at this level a program can simply make a call to +.I rnusers (), +a C routine which returns the number of users on a remote machine. +The user is not explicitly aware of using RPC \(em they simply +call a procedure, just as they would call +.I malloc() . +.LP +.I "The Middle Layer:" +.IX RPC "The Middle Layer" +The middle layer is really \*QRPC proper.\*U Here, the user doesn't +need to consider details about sockets, the UNIX system, or other low-level +implementation mechanisms. They simply make remote procedure calls +to routines on other machines. The selling point here is simplicity. +It's this layer that allows RPC to pass the \*Qhello world\*U test \(em +simple things should be simple. The middle-layer routines are used +for most applications. +.LP +RPC calls are made with the system routines +.I registerrpc() +.I callrpc() +and +.I svc_run (). +The first two of these are the most fundamental: +.I registerrpc() +obtains a unique system-wide procedure-identification number, and +.I callrpc() +actually executes a remote procedure call. At the middle level, a +call to +.I rnusers() +is implemented by way of these two routines. +.LP +The middle layer is unfortunately rarely used in serious programming +due to its inflexibility (simplicity). It does not allow timeout +specifications or the choice of transport. It allows no UNIX +process control or flexibility in case of errors. It doesn't support +multiple kinds of call authentication. The programmer rarely needs +all these kinds of control, but one or two of them is often necessary. +.LP +.I "The Lowest Layer:" +.IX RPC "The Lowest Layer" +The lowest layer does allow these details to be controlled by the +programmer, and for that reason it is often necessary. Programs +written at this level are also most efficient, but this is rarely a +real issue \(em since RPC clients and servers rarely generate +heavy network loads. +.LP +Although this document only discusses the interface to C, +remote procedure calls can be made from any language. +Even though this document discusses RPC +when it is used to communicate +between processes on different machines, +it works just as well for communication +between different processes on the same machine. +.br +.KS +.NH 2 +\&The RPC Paradigm +.IX RPC paradigm +.LP +Here is a diagram of the RPC paradigm: +.LP +\fBFigure 1-1\fI Network Communication with the Remote Reocedure Call\fR +.LP +.PS +L1: arrow down 1i "client " rjust "program " rjust +L2: line right 1.5i "\fIcallrpc\fP" "function" +move up 1.5i; line dotted down 6i; move up 4.5i +arrow right 1i +L3: arrow down 1i "invoke " rjust "service " rjust +L4: arrow right 1.5i "call" "service" +L5: arrow down 1i " service" ljust " executes" ljust +L6: arrow left 1.5i "\fIreturn\fP" "answer" +L7: arrow down 1i "request " rjust "completed " rjust +L8: line left 1i +arrow left 1.5i "\fIreturn\fP" "reply" +L9: arrow down 1i "program " rjust "continues " rjust +line dashed down from L2 to L9 +line dashed down from L4 to L7 +line dashed up 1i from L3 "service " rjust "daemon " rjust +arrow dashed down 1i from L8 +move right 1i from L3 +box invis "Machine B" +move left 1.2i from L2; move down +box invis "Machine A" +.PE +.KE +.KS +.NH 1 +\&Higher Layers of RPC +.NH 2 +\&Highest Layer +.IX "highest layer of RPC" +.IX RPC "highest layer" +.LP +Imagine you're writing a program that needs to know +how many users are logged into a remote machine. +You can do this by calling the RPC library routine +.I rnusers() +as illustrated below: +.ie t .DS +.el .DS L +.ft CW +#include <stdio.h> + +main(argc, argv) + int argc; + char **argv; +{ + int num; + + if (argc != 2) { + fprintf(stderr, "usage: rnusers hostname\en"); + exit(1); + } + if ((num = rnusers(argv[1])) < 0) { + fprintf(stderr, "error: rnusers\en"); + exit(-1); + } + printf("%d users on %s\en", num, argv[1]); + exit(0); +} +.DE +.KE +RPC library routines such as +.I rnusers() +are in the RPC services library +.I librpcsvc.a +Thus, the program above should be compiled with +.DS +.ft CW +% cc \fIprogram.c -lrpcsvc\fP +.DE +.I rnusers (), +like the other RPC library routines, is documented in section 3R +of the +.I "System Interface Manual for the Sun Workstation" , +the same section which documents the standard Sun RPC services. +.IX "RPC Services" +See the +.I intro(3R) +manual page for an explanation of the documentation strategy +for these services and their RPC protocols. +.LP +Here are some of the RPC service library routines available to the +C programmer: +.LP +\fBTable 3-3\fI RPC Service Library Routines\RP +.TS +box tab (&) ; +cfI cfI +lfL l . +Routine&Description +_ +.sp.5 +rnusers&Return number of users on remote machine +rusers&Return information about users on remote machine +havedisk&Determine if remote machine has disk +rstats&Get performance data from remote kernel +rwall&Write to specified remote machines +yppasswd&Update user password in Yellow Pages +.TE +.LP +Other RPC services \(em for example +.I ether() +.I mount +.I rquota() +and +.I spray +\(em are not available to the C programmer as library routines. +They do, however, +have RPC program numbers so they can be invoked with +.I callrpc() +which will be discussed in the next section. Most of them also +have compilable +.I rpcgen(1) +protocol description files. (The +.I rpcgen +protocol compiler radically simplifies the process of developing +network applications. +See the \fBrpcgen\fI Programming Guide\fR +for detailed information about +.I rpcgen +and +.I rpcgen +protocol description files). +.KS +.NH 2 +\&Intermediate Layer +.IX "intermediate layer of RPC" +.IX "RPC" "intermediate layer" +.LP +The simplest interface, which explicitly makes RPC calls, uses the +functions +.I callrpc() +and +.I registerrpc() +Using this method, the number of remote users can be gotten as follows: +.ie t .DS +.el .DS L +#include <stdio.h> +#include <rpc/rpc.h> +#include <utmp.h> +#include <rpcsvc/rusers.h> + +main(argc, argv) + int argc; + char **argv; +{ + unsigned long nusers; + int stat; + + if (argc != 2) { + fprintf(stderr, "usage: nusers hostname\en"); + exit(-1); + } + if (stat = callrpc(argv[1], + RUSERSPROG, RUSERSVERS, RUSERSPROC_NUM, + xdr_void, 0, xdr_u_long, &nusers) != 0) { + clnt_perrno(stat); + exit(1); + } + printf("%d users on %s\en", nusers, argv[1]); + exit(0); +} +.DE +.KE +Each RPC procedure is uniquely defined by a program number, +version number, and procedure number. The program number +specifies a group of related remote procedures, each of +which has a different procedure number. Each program also +has a version number, so when a minor change is made to a +remote service (adding a new procedure, for example), a new +program number doesn't have to be assigned. When you want +to call a procedure to find the number of remote users, you +look up the appropriate program, version and procedure numbers +in a manual, just as you look up the name of a memory allocator +when you want to allocate memory. +.LP +The simplest way of making remote procedure calls is with the the RPC +library routine +.I callrpc() +It has eight parameters. The first is the name of the remote server +machine. The next three parameters are the program, version, and procedure +numbers\(emtogether they identify the procedure to be called. +The fifth and sixth parameters are an XDR filter and an argument to +be encoded and passed to the remote procedure. +The final two parameters are a filter for decoding the results +returned by the remote procedure and a pointer to the place where +the procedure's results are to be stored. Multiple arguments and +results are handled by embedding them in structures. If +.I callrpc() +completes successfully, it returns zero; else it returns a nonzero +value. The return codes (of type +.IX "enum clnt_stat (in RPC programming)" "" "\fIenum clnt_stat\fP (in RPC programming)" +cast into an integer) are found in +.I <rpc/clnt.h> . +.LP +Since data types may be represented differently on different machines, +.I callrpc() +needs both the type of the RPC argument, as well as +a pointer to the argument itself (and similarly for the result). For +.I RUSERSPROC_NUM , +the return value is an +.I "unsigned long" +so +.I callrpc() +has +.I xdr_u_long() +as its first return parameter, which says +that the result is of type +.I "unsigned long" +and +.I &nusers +as its second return parameter, +which is a pointer to where the long result will be placed. Since +.I RUSERSPROC_NUM +takes no argument, the argument parameter of +.I callrpc() +is +.I xdr_void (). +.LP +After trying several times to deliver a message, if +.I callrpc() +gets no answer, it returns with an error code. +The delivery mechanism is UDP, +which stands for User Datagram Protocol. +Methods for adjusting the number of retries +or for using a different protocol require you to use the lower +layer of the RPC library, discussed later in this document. +The remote server procedure +corresponding to the above might look like this: +.ie t .DS +.el .DS L +.ft CW +.ft CW +char * +nuser(indata) + char *indata; +{ + unsigned long nusers; + +.ft I + /* + * Code here to compute the number of users + * and place result in variable \fInusers\fP. + */ +.ft CW + return((char *)&nusers); +} +.DE +.LP +It takes one argument, which is a pointer to the input +of the remote procedure call (ignored in our example), +and it returns a pointer to the result. +In the current version of C, +character pointers are the generic pointers, +so both the input argument and the return value are cast to +.I "char *" . +.LP +Normally, a server registers all of the RPC calls it plans +to handle, and then goes into an infinite loop waiting to service requests. +In this example, there is only a single procedure +to register, so the main body of the server would look like this: +.ie t .DS +.el .DS L +.ft CW +#include <stdio.h> +#include <rpc/rpc.h> +#include <utmp.h> +#include <rpcsvc/rusers.h> + +char *nuser(); + +main() +{ + registerrpc(RUSERSPROG, RUSERSVERS, RUSERSPROC_NUM, + nuser, xdr_void, xdr_u_long); + svc_run(); /* \fINever returns\fP */ + fprintf(stderr, "Error: svc_run returned!\en"); + exit(1); +} +.DE +.LP +The +.I registerrpc() +routine registers a C procedure as corresponding to a +given RPC procedure number. The first three parameters, +.I RUSERPROG , +.I RUSERSVERS , +and +.I RUSERSPROC_NUM +are the program, version, and procedure numbers +of the remote procedure to be registered; +.I nuser() +is the name of the local procedure that implements the remote +procedure; and +.I xdr_void() +and +.I xdr_u_long() +are the XDR filters for the remote procedure's arguments and +results, respectively. (Multiple arguments or multiple results +are passed as structures). +.LP +Only the UDP transport mechanism can use +.I registerrpc() +thus, it is always safe in conjunction with calls generated by +.I callrpc() . +.SH +.IX "UDP 8K warning" +Warning: the UDP transport mechanism can only deal with +arguments and results less than 8K bytes in length. +.LP +.LP +After registering the local procedure, the server program's +main procedure calls +.I svc_run (), +the RPC library's remote procedure dispatcher. It is this +function that calls the remote procedures in response to RPC +call messages. Note that the dispatcher takes care of decoding +remote procedure arguments and encoding results, using the XDR +filters specified when the remote procedure was registered. +.NH 2 +\&Assigning Program Numbers +.IX "program number assignment" +.IX "assigning program numbers" +.LP +Program numbers are assigned in groups of +.I 0x20000000 +according to the following chart: +.DS +.ft CW + 0x0 - 0x1fffffff \fRDefined by Sun\fP +0x20000000 - 0x3fffffff \fRDefined by user\fP +0x40000000 - 0x5fffffff \fRTransient\fP +0x60000000 - 0x7fffffff \fRReserved\fP +0x80000000 - 0x9fffffff \fRReserved\fP +0xa0000000 - 0xbfffffff \fRReserved\fP +0xc0000000 - 0xdfffffff \fRReserved\fP +0xe0000000 - 0xffffffff \fRReserved\fP +.ft R +.DE +Sun Microsystems administers the first group of numbers, which +should be identical for all Sun customers. If a customer +develops an application that might be of general interest, that +application should be given an assigned number in the first +range. The second group of numbers is reserved for specific +customer applications. This range is intended primarily for +debugging new programs. The third group is reserved for +applications that generate program numbers dynamically. The +final groups are reserved for future use, and should not be +used. +.LP +To register a protocol specification, send a request by network +mail to +.I rpc@sun +or write to: +.DS +RPC Administrator +Sun Microsystems +2550 Garcia Ave. +Mountain View, CA 94043 +.DE +Please include a compilable +.I rpcgen +\*Q.x\*U file describing your protocol. +You will be given a unique program number in return. +.IX RPC administration +.IX administration "of RPC" +.LP +The RPC program numbers and protocol specifications +of standard Sun RPC services can be +found in the include files in +.I "/usr/include/rpcsvc" . +These services, however, constitute only a small subset +of those which have been registered. The complete list of +registered programs, as of the time when this manual was +printed, is: +.LP +\fBTable 3-2\fI RPC Registered Programs\fR +.TS H +box tab (&) ; +lfBI lfBI lfBI +lfL lfL lfI . +RPC Number&Program&Description +_ +.TH +.sp.5 +100000&PMAPPROG&portmapper +100001&RSTATPROG&remote stats +100002&RUSERSPROG&remote users +100003&NFSPROG&nfs +100004&YPPROG&Yellow Pages +100005&MOUNTPROG&mount demon +100006&DBXPROG&remote dbx +100007&YPBINDPROG&yp binder +100008&WALLPROG&shutdown msg +100009&YPPASSWDPROG&yppasswd server +100010ÐERSTATPROGðer stats +100011&RQUOTAPROG&disk quotas +100012&SPRAYPROG&spray packets +100013&IBM3270PROG&3270 mapper +100014&IBMRJEPROG&RJE mapper +100015&SELNSVCPROG&selection service +100016&RDATABASEPROG&remote database access +100017&REXECPROG&remote execution +100018&ALICEPROG&Alice Office Automation +100019&SCHEDPROG&scheduling service +100020&LOCKPROG&local lock manager +100021&NETLOCKPROG&network lock manager +100022&X25PROG&x.25 inr protocol +100023&STATMON1PROG&status monitor 1 +100024&STATMON2PROG&status monitor 2 +100025&SELNLIBPROG&selection library +100026&BOOTPARAMPROG&boot parameters service +100027&MAZEPROG&mazewars game +100028&YPUPDATEPROG&yp update +100029&KEYSERVEPROG&key server +100030&SECURECMDPROG&secure login +100031&NETFWDIPROG&nfs net forwarder init +100032&NETFWDTPROG&nfs net forwarder trans +100033&SUNLINKMAP_PROG&sunlink MAP +100034&NETMONPROG&network monitor +100035&DBASEPROG&lightweight database +100036&PWDAUTHPROG&password authorization +100037&TFSPROG&translucent file svc +100038&NSEPROG&nse server +100039&NSE_ACTIVATE_PROG&nse activate daemon +.sp .2i +150001&PCNFSDPROG&pc passwd authorization +.sp .2i +200000&PYRAMIDLOCKINGPROG&Pyramid-locking +200001&PYRAMIDSYS5&Pyramid-sys5 +200002&CADDS_IMAGE&CV cadds_image +.sp .2i +300001&ADT_RFLOCKPROG&ADT file locking +.TE +.NH 2 +\&Passing Arbitrary Data Types +.IX "arbitrary data types" +.LP +In the previous example, the RPC call passes a single +.I "unsigned long" +RPC can handle arbitrary data structures, regardless of +different machines' byte orders or structure layout conventions, +by always converting them to a network standard called +.I "External Data Representation" +(XDR) before +sending them over the wire. +The process of converting from a particular machine representation +to XDR format is called +.I serializing , +and the reverse process is called +.I deserializing . +The type field parameters of +.I callrpc() +and +.I registerrpc() +can be a built-in procedure like +.I xdr_u_long() +in the previous example, or a user supplied one. +XDR has these built-in type routines: +.IX RPC "built-in routines" +.DS +.ft CW +xdr_int() xdr_u_int() xdr_enum() +xdr_long() xdr_u_long() xdr_bool() +xdr_short() xdr_u_short() xdr_wrapstring() +xdr_char() xdr_u_char() +.DE +Note that the routine +.I xdr_string() +exists, but cannot be used with +.I callrpc() +and +.I registerrpc (), +which only pass two parameters to their XDR routines. +.I xdr_wrapstring() +has only two parameters, and is thus OK. It calls +.I xdr_string (). +.LP +As an example of a user-defined type routine, +if you wanted to send the structure +.DS +.ft CW +struct simple { + int a; + short b; +} simple; +.DE +then you would call +.I callrpc() +as +.DS +.ft CW +callrpc(hostname, PROGNUM, VERSNUM, PROCNUM, + xdr_simple, &simple ...); +.DE +where +.I xdr_simple() +is written as: +.ie t .DS +.el .DS L +.ft CW +#include <rpc/rpc.h> + +xdr_simple(xdrsp, simplep) + XDR *xdrsp; + struct simple *simplep; +{ + if (!xdr_int(xdrsp, &simplep->a)) + return (0); + if (!xdr_short(xdrsp, &simplep->b)) + return (0); + return (1); +} +.DE +.LP +An XDR routine returns nonzero (true in the sense of C) if it +completes successfully, and zero otherwise. +A complete description of XDR is in the +.I "XDR Protocol Specification" +section of this manual, only few implementation examples are +given here. +.LP +In addition to the built-in primitives, +there are also the prefabricated building blocks: +.DS +.ft CW +xdr_array() xdr_bytes() xdr_reference() +xdr_vector() xdr_union() xdr_pointer() +xdr_string() xdr_opaque() +.DE +To send a variable array of integers, +you might package them up as a structure like this +.DS +.ft CW +struct varintarr { + int *data; + int arrlnth; +} arr; +.DE +and make an RPC call such as +.DS +.ft CW +callrpc(hostname, PROGNUM, VERSNUM, PROCNUM, + xdr_varintarr, &arr...); +.DE +with +.I xdr_varintarr() +defined as: +.ie t .DS +.el .DS L +.ft CW +xdr_varintarr(xdrsp, arrp) + XDR *xdrsp; + struct varintarr *arrp; +{ + return (xdr_array(xdrsp, &arrp->data, &arrp->arrlnth, + MAXLEN, sizeof(int), xdr_int)); +} +.DE +This routine takes as parameters the XDR handle, +a pointer to the array, a pointer to the size of the array, +the maximum allowable array size, +the size of each array element, +and an XDR routine for handling each array element. +.KS +.LP +If the size of the array is known in advance, one can use +.I xdr_vector (), +which serializes fixed-length arrays. +.ie t .DS +.el .DS L +.ft CW +int intarr[SIZE]; + +xdr_intarr(xdrsp, intarr) + XDR *xdrsp; + int intarr[]; +{ + int i; + + return (xdr_vector(xdrsp, intarr, SIZE, sizeof(int), + xdr_int)); +} +.DE +.KE +.LP +XDR always converts quantities to 4-byte multiples when serializing. +Thus, if either of the examples above involved characters +instead of integers, each character would occupy 32 bits. +That is the reason for the XDR routine +.I xdr_bytes() +which is like +.I xdr_array() +except that it packs characters; +.I xdr_bytes() +has four parameters, similar to the first four parameters of +.I xdr_array (). +For null-terminated strings, there is also the +.I xdr_string() +routine, which is the same as +.I xdr_bytes() +without the length parameter. +On serializing it gets the string length from +.I strlen (), +and on deserializing it creates a null-terminated string. +.LP +Here is a final example that calls the previously written +.I xdr_simple() +as well as the built-in functions +.I xdr_string() +and +.I xdr_reference (), +which chases pointers: +.ie t .DS +.el .DS L +.ft CW +struct finalexample { + char *string; + struct simple *simplep; +} finalexample; + +xdr_finalexample(xdrsp, finalp) + XDR *xdrsp; + struct finalexample *finalp; +{ + + if (!xdr_string(xdrsp, &finalp->string, MAXSTRLEN)) + return (0); + if (!xdr_reference(xdrsp, &finalp->simplep, + sizeof(struct simple), xdr_simple); + return (0); + return (1); +} +.DE +Note that we could as easily call +.I xdr_simple() +here instead of +.I xdr_reference (). +.NH 1 +\&Lowest Layer of RPC +.IX "lowest layer of RPC" +.IX "RPC" "lowest layer" +.LP +In the examples given so far, +RPC takes care of many details automatically for you. +In this section, we'll show you how you can change the defaults +by using lower layers of the RPC library. +It is assumed that you are familiar with sockets +and the system calls for dealing with them. +.LP +There are several occasions when you may need to use lower layers of +RPC. First, you may need to use TCP, since the higher layer uses UDP, +which restricts RPC calls to 8K bytes of data. Using TCP permits calls +to send long streams of data. +For an example, see the +.I TCP +section below. Second, you may want to allocate and free memory +while serializing or deserializing with XDR routines. +There is no call at the higher level to let +you free memory explicitly. +For more explanation, see the +.I "Memory Allocation with XDR" +section below. +Third, you may need to perform authentication +on either the client or server side, by supplying +credentials or verifying them. +See the explanation in the +.I Authentication +section below. +.NH 2 +\&More on the Server Side +.IX RPC "server side" +.LP +The server for the +.I nusers() +program shown below does the same thing as the one using +.I registerrpc() +above, but is written using a lower layer of the RPC package: +.ie t .DS +.el .DS L +.ft CW +#include <stdio.h> +#include <rpc/rpc.h> +#include <utmp.h> +#include <rpcsvc/rusers.h> + +main() +{ + SVCXPRT *transp; + int nuser(); + + transp = svcudp_create(RPC_ANYSOCK); + if (transp == NULL){ + fprintf(stderr, "can't create an RPC server\en"); + exit(1); + } + pmap_unset(RUSERSPROG, RUSERSVERS); + if (!svc_register(transp, RUSERSPROG, RUSERSVERS, + nuser, IPPROTO_UDP)) { + fprintf(stderr, "can't register RUSER service\en"); + exit(1); + } + svc_run(); /* \fINever returns\fP */ + fprintf(stderr, "should never reach this point\en"); +} + +nuser(rqstp, transp) + struct svc_req *rqstp; + SVCXPRT *transp; +{ + unsigned long nusers; + + switch (rqstp->rq_proc) { + case NULLPROC: + if (!svc_sendreply(transp, xdr_void, 0)) + fprintf(stderr, "can't reply to RPC call\en"); + return; + case RUSERSPROC_NUM: +.ft I + /* + * Code here to compute the number of users + * and assign it to the variable \fInusers\fP + */ +.ft CW + if (!svc_sendreply(transp, xdr_u_long, &nusers)) + fprintf(stderr, "can't reply to RPC call\en"); + return; + default: + svcerr_noproc(transp); + return; + } +} +.DE +.LP +First, the server gets a transport handle, which is used +for receiving and replying to RPC messages. +.I registerrpc() +uses +.I svcudp_create() +to get a UDP handle. +If you require a more reliable protocol, call +.I svctcp_create() +instead. +If the argument to +.I svcudp_create() +is +.I RPC_ANYSOCK +the RPC library creates a socket +on which to receive and reply to RPC calls. Otherwise, +.I svcudp_create() +expects its argument to be a valid socket number. +If you specify your own socket, it can be bound or unbound. +If it is bound to a port by the user, the port numbers of +.I svcudp_create() +and +.I clnttcp_create() +(the low-level client routine) must match. +.LP +If the user specifies the +.I RPC_ANYSOCK +argument, the RPC library routines will open sockets. +Otherwise they will expect the user to do so. The routines +.I svcudp_create() +and +.I clntudp_create() +will cause the RPC library routines to +.I bind() +their socket if it is not bound already. +.LP +A service may choose to register its port number with the +local portmapper service. This is done is done by specifying +a non-zero protocol number in +.I svc_register (). +Incidently, a client can discover the server's port number by +consulting the portmapper on their server's machine. This can +be done automatically by specifying a zero port number in +.I clntudp_create() +or +.I clnttcp_create (). +.LP +After creating an +.I SVCXPRT , +the next step is to call +.I pmap_unset() +so that if the +.I nusers() +server crashed earlier, +any previous trace of it is erased before restarting. +More precisely, +.I pmap_unset() +erases the entry for +.I RUSERSPROG +from the port mapper's tables. +.LP +Finally, we associate the program number for +.I nusers() +with the procedure +.I nuser (). +The final argument to +.I svc_register() +is normally the protocol being used, +which, in this case, is +.I IPPROTO_UDP +Notice that unlike +.I registerrpc (), +there are no XDR routines involved +in the registration process. +Also, registration is done on the program, +rather than procedure, level. +.LP +The user routine +.I nuser() +must call and dispatch the appropriate XDR routines +based on the procedure number. +Note that +two things are handled by +.I nuser() +that +.I registerrpc() +handles automatically. +The first is that procedure +.I NULLPROC +(currently zero) returns with no results. +This can be used as a simple test +for detecting if a remote program is running. +Second, there is a check for invalid procedure numbers. +If one is detected, +.I svcerr_noproc() +is called to handle the error. +.KS +.LP +The user service routine serializes the results and returns +them to the RPC caller via +.I svc_sendreply() +Its first parameter is the +.I SVCXPRT +handle, the second is the XDR routine, +and the third is a pointer to the data to be returned. +Not illustrated above is how a server +handles an RPC program that receives data. +As an example, we can add a procedure +.I RUSERSPROC_BOOL +which has an argument +.I nusers (), +and returns +.I TRUE +or +.I FALSE +depending on whether there are nusers logged on. +It would look like this: +.ie t .DS +.el .DS L +.ft CW +case RUSERSPROC_BOOL: { + int bool; + unsigned nuserquery; + + if (!svc_getargs(transp, xdr_u_int, &nuserquery) { + svcerr_decode(transp); + return; + } +.ft I + /* + * Code to set \fInusers\fP = number of users + */ +.ft CW + if (nuserquery == nusers) + bool = TRUE; + else + bool = FALSE; + if (!svc_sendreply(transp, xdr_bool, &bool)) { + fprintf(stderr, "can't reply to RPC call\en"); + return (1); + } + return; +} +.DE +.KE +.LP +The relevant routine is +.I svc_getargs() +which takes an +.I SVCXPRT +handle, the XDR routine, +and a pointer to where the input is to be placed as arguments. +.NH 2 +\&Memory Allocation with XDR +.IX "memory allocation with XDR" +.IX XDR "memory allocation" +.LP +XDR routines not only do input and output, +they also do memory allocation. +This is why the second parameter of +.I xdr_array() +is a pointer to an array, rather than the array itself. +If it is +.I NULL , +then +.I xdr_array() +allocates space for the array and returns a pointer to it, +putting the size of the array in the third argument. +As an example, consider the following XDR routine +.I xdr_chararr1() +which deals with a fixed array of bytes with length +.I SIZE . +.ie t .DS +.el .DS L +.ft CW +xdr_chararr1(xdrsp, chararr) + XDR *xdrsp; + char chararr[]; +{ + char *p; + int len; + + p = chararr; + len = SIZE; + return (xdr_bytes(xdrsp, &p, &len, SIZE)); +} +.DE +If space has already been allocated in +.I chararr , +it can be called from a server like this: +.ie t .DS +.el .DS L +.ft CW +char chararr[SIZE]; + +svc_getargs(transp, xdr_chararr1, chararr); +.DE +If you want XDR to do the allocation, +you would have to rewrite this routine in the following way: +.ie t .DS +.el .DS L +.ft CW +xdr_chararr2(xdrsp, chararrp) + XDR *xdrsp; + char **chararrp; +{ + int len; + + len = SIZE; + return (xdr_bytes(xdrsp, charrarrp, &len, SIZE)); +} +.DE +Then the RPC call might look like this: +.ie t .DS +.el .DS L +.ft CW +char *arrptr; + +arrptr = NULL; +svc_getargs(transp, xdr_chararr2, &arrptr); +.ft I +/* + * Use the result here + */ +.ft CW +svc_freeargs(transp, xdr_chararr2, &arrptr); +.DE +Note that, after being used, the character array can be freed with +.I svc_freeargs() +.I svc_freeargs() +will not attempt to free any memory if the variable indicating it +is NULL. For example, in the the routine +.I xdr_finalexample (), +given earlier, if +.I finalp->string +was NULL, then it would not be freed. The same is true for +.I finalp->simplep . +.LP +To summarize, each XDR routine is responsible +for serializing, deserializing, and freeing memory. +When an XDR routine is called from +.I callrpc() +the serializing part is used. +When called from +.I svc_getargs() +the deserializer is used. +And when called from +.I svc_freeargs() +the memory deallocator is used. When building simple examples like those +in this section, a user doesn't have to worry +about the three modes. +See the +.I "External Data Representation: Sun Technical Notes" +for examples of more sophisticated XDR routines that determine +which of the three modes they are in and adjust their behavior accordingly. +.KS +.NH 2 +\&The Calling Side +.IX RPC "calling side" +.LP +When you use +.I callrpc() +you have no control over the RPC delivery +mechanism or the socket used to transport the data. +To illustrate the layer of RPC that lets you adjust these +parameters, consider the following code to call the +.I nusers +service: +.ie t .DS +.el .DS L +.ft CW +.vs 11 +#include <stdio.h> +#include <rpc/rpc.h> +#include <utmp.h> +#include <rpcsvc/rusers.h> +#include <sys/socket.h> +#include <sys/time.h> +#include <netdb.h> + +main(argc, argv) + int argc; + char **argv; +{ + struct hostent *hp; + struct timeval pertry_timeout, total_timeout; + struct sockaddr_in server_addr; + int sock = RPC_ANYSOCK; + register CLIENT *client; + enum clnt_stat clnt_stat; + unsigned long nusers; + + if (argc != 2) { + fprintf(stderr, "usage: nusers hostname\en"); + exit(-1); + } + if ((hp = gethostbyname(argv[1])) == NULL) { + fprintf(stderr, "can't get addr for %s\en",argv[1]); + exit(-1); + } + pertry_timeout.tv_sec = 3; + pertry_timeout.tv_usec = 0; + bcopy(hp->h_addr, (caddr_t)&server_addr.sin_addr, + hp->h_length); + server_addr.sin_family = AF_INET; + server_addr.sin_port = 0; + if ((client = clntudp_create(&server_addr, RUSERSPROG, + RUSERSVERS, pertry_timeout, &sock)) == NULL) { + clnt_pcreateerror("clntudp_create"); + exit(-1); + } + total_timeout.tv_sec = 20; + total_timeout.tv_usec = 0; + clnt_stat = clnt_call(client, RUSERSPROC_NUM, xdr_void, + 0, xdr_u_long, &nusers, total_timeout); + if (clnt_stat != RPC_SUCCESS) { + clnt_perror(client, "rpc"); + exit(-1); + } + clnt_destroy(client); + close(sock); + exit(0); +} +.vs +.DE +.KE +The low-level version of +.I callrpc() +is +.I clnt_call() +which takes a +.I CLIENT +pointer rather than a host name. The parameters to +.I clnt_call() +are a +.I CLIENT +pointer, the procedure number, +the XDR routine for serializing the argument, +a pointer to the argument, +the XDR routine for deserializing the return value, +a pointer to where the return value will be placed, +and the time in seconds to wait for a reply. +.LP +The +.I CLIENT +pointer is encoded with the transport mechanism. +.I callrpc() +uses UDP, thus it calls +.I clntudp_create() +to get a +.I CLIENT +pointer. To get TCP (Transmission Control Protocol), you would use +.I clnttcp_create() . +.LP +The parameters to +.I clntudp_create() +are the server address, the program number, the version number, +a timeout value (between tries), and a pointer to a socket. +The final argument to +.I clnt_call() +is the total time to wait for a response. +Thus, the number of tries is the +.I clnt_call() +timeout divided by the +.I clntudp_create() +timeout. +.LP +Note that the +.I clnt_destroy() +call +always deallocates the space associated with the +.I CLIENT +handle. It closes the socket associated with the +.I CLIENT +handle, however, only if the RPC library opened it. It the +socket was opened by the user, it stays open. This makes it +possible, in cases where there are multiple client handles +using the same socket, to destroy one handle without closing +the socket that other handles are using. +.LP +To make a stream connection, the call to +.I clntudp_create() +is replaced with a call to +.I clnttcp_create() . +.DS +.ft CW +clnttcp_create(&server_addr, prognum, versnum, &sock, + inputsize, outputsize); +.DE +There is no timeout argument; instead, the receive and send buffer +sizes must be specified. When the +.I clnttcp_create() +call is made, a TCP connection is established. +All RPC calls using that +.I CLIENT +handle would use this connection. +The server side of an RPC call using TCP has +.I svcudp_create() +replaced by +.I svctcp_create() . +.DS +.ft CW +transp = svctcp_create(RPC_ANYSOCK, 0, 0); +.DE +The last two arguments to +.I svctcp_create() +are send and receive sizes respectively. If `0' is specified for +either of these, the system chooses a reasonable default. +.KS +.NH 1 +\&Other RPC Features +.IX "RPC" "miscellaneous features" +.IX "miscellaneous RPC features" +.LP +This section discusses some other aspects of RPC +that are occasionally useful. +.NH 2 +\&Select on the Server Side +.IX RPC select() RPC \fIselect()\fP +.IX select() "" \fIselect()\fP "on the server side" +.LP +Suppose a process is processing RPC requests +while performing some other activity. +If the other activity involves periodically updating a data structure, +the process can set an alarm signal before calling +.I svc_run() +But if the other activity +involves waiting on a a file descriptor, the +.I svc_run() +call won't work. +The code for +.I svc_run() +is as follows: +.ie t .DS +.el .DS L +.ft CW +.vs 11 +void +svc_run() +{ + fd_set readfds; + int dtbsz = getdtablesize(); + + for (;;) { + readfds = svc_fds; + switch (select(dtbsz, &readfds, NULL,NULL,NULL)) { + + case -1: + if (errno == EINTR) + continue; + perror("select"); + return; + case 0: + break; + default: + svc_getreqset(&readfds); + } + } +} +.vs +.DE +.KE +.LP +You can bypass +.I svc_run() +and call +.I svc_getreqset() +yourself. +All you need to know are the file descriptors +of the socket(s) associated with the programs you are waiting on. +Thus you can have your own +.I select() +.IX select() "" \fIselect()\fP +that waits on both the RPC socket, +and your own descriptors. Note that +.I svc_fds() +is a bit mask of all the file descriptors that RPC is using for +services. It can change everytime that +.I any +RPC library routine is called, because descriptors are constantly +being opened and closed, for example for TCP connections. +.NH 2 +\&Broadcast RPC +.IX "broadcast RPC" +.IX RPC "broadcast" +.LP +The +.I portmapper +is a daemon that converts RPC program numbers +into DARPA protocol port numbers; see the +.I portmap +man page. You can't do broadcast RPC without the portmapper. +Here are the main differences between +broadcast RPC and normal RPC calls: +.IP 1. +Normal RPC expects one answer, whereas +broadcast RPC expects many answers +(one or more answer from each responding machine). +.IP 2. +Broadcast RPC can only be supported by packet-oriented (connectionless) +transport protocols like UPD/IP. +.IP 3. +The implementation of broadcast RPC +treats all unsuccessful responses as garbage by filtering them out. +Thus, if there is a version mismatch between the +broadcaster and a remote service, +the user of broadcast RPC never knows. +.IP 4. +All broadcast messages are sent to the portmap port. +Thus, only services that register themselves with their portmapper +are accessible via the broadcast RPC mechanism. +.IP 5. +Broadcast requests are limited in size to the MTU (Maximum Transfer +Unit) of the local network. For Ethernet, the MTU is 1500 bytes. +.KS +.NH 3 +\&Broadcast RPC Synopsis +.IX "broadcast RPC" synopsis +.IX "RPC" "broadcast synopsis" +.ie t .DS +.el .DS L +.ft CW +#include <rpc/pmap_clnt.h> + . . . +enum clnt_stat clnt_stat; + . . . +clnt_stat = clnt_broadcast(prognum, versnum, procnum, + inproc, in, outproc, out, eachresult) + u_long prognum; /* \fIprogram number\fP */ + u_long versnum; /* \fIversion number\fP */ + u_long procnum; /* \fIprocedure number\fP */ + xdrproc_t inproc; /* \fIxdr routine for args\fP */ + caddr_t in; /* \fIpointer to args\fP */ + xdrproc_t outproc; /* \fIxdr routine for results\fP */ + caddr_t out; /* \fIpointer to results\fP */ + bool_t (*eachresult)();/* \fIcall with each result gotten\fP */ +.DE +.KE +The procedure +.I eachresult() +is called each time a valid result is obtained. +It returns a boolean that indicates +whether or not the user wants more responses. +.ie t .DS +.el .DS L +.ft CW +bool_t done; + . . . +done = eachresult(resultsp, raddr) + caddr_t resultsp; + struct sockaddr_in *raddr; /* \fIAddr of responding machine\fP */ +.DE +If +.I done +is +.I TRUE , +then broadcasting stops and +.I clnt_broadcast() +returns successfully. +Otherwise, the routine waits for another response. +The request is rebroadcast +after a few seconds of waiting. +If no responses come back, +the routine returns with +.I RPC_TIMEDOUT . +.NH 2 +\&Batching +.IX "batching" +.IX RPC "batching" +.LP +The RPC architecture is designed so that clients send a call message, +and wait for servers to reply that the call succeeded. +This implies that clients do not compute +while servers are processing a call. +This is inefficient if the client does not want or need +an acknowledgement for every message sent. +It is possible for clients to continue computing +while waiting for a response, +using RPC batch facilities. +.LP +RPC messages can be placed in a \*Qpipeline\*U of calls +to a desired server; this is called batching. +Batching assumes that: +1) each RPC call in the pipeline requires no response from the server, +and the server does not send a response message; and +2) the pipeline of calls is transported on a reliable +byte stream transport such as TCP/IP. +Since the server does not respond to every call, +the client can generate new calls in parallel +with the server executing previous calls. +Furthermore, the TCP/IP implementation can buffer up +many call messages, and send them to the server in one +.I write() +system call. This overlapped execution +greatly decreases the interprocess communication overhead of +the client and server processes, +and the total elapsed time of a series of calls. +.LP +Since the batched calls are buffered, +the client should eventually do a nonbatched call +in order to flush the pipeline. +.LP +A contrived example of batching follows. +Assume a string rendering service (like a window system) +has two similar calls: one renders a string and returns void results, +while the other renders a string and remains silent. +The service (using the TCP/IP transport) may look like: +.ie t .DS +.el .DS L +.ft CW +#include <stdio.h> +#include <rpc/rpc.h> +#include <suntool/windows.h> + +void windowdispatch(); + +main() +{ + SVCXPRT *transp; + + transp = svctcp_create(RPC_ANYSOCK, 0, 0); + if (transp == NULL){ + fprintf(stderr, "can't create an RPC server\en"); + exit(1); + } + pmap_unset(WINDOWPROG, WINDOWVERS); + if (!svc_register(transp, WINDOWPROG, WINDOWVERS, + windowdispatch, IPPROTO_TCP)) { + fprintf(stderr, "can't register WINDOW service\en"); + exit(1); + } + svc_run(); /* \fINever returns\fP */ + fprintf(stderr, "should never reach this point\en"); +} + +void +windowdispatch(rqstp, transp) + struct svc_req *rqstp; + SVCXPRT *transp; +{ + char *s = NULL; + + switch (rqstp->rq_proc) { + case NULLPROC: + if (!svc_sendreply(transp, xdr_void, 0)) + fprintf(stderr, "can't reply to RPC call\en"); + return; + case RENDERSTRING: + if (!svc_getargs(transp, xdr_wrapstring, &s)) { + fprintf(stderr, "can't decode arguments\en"); +.ft I + /* + * Tell caller he screwed up + */ +.ft CW + svcerr_decode(transp); + break; + } +.ft I + /* + * Code here to render the string \fIs\fP + */ +.ft CW + if (!svc_sendreply(transp, xdr_void, NULL)) + fprintf(stderr, "can't reply to RPC call\en"); + break; + case RENDERSTRING_BATCHED: + if (!svc_getargs(transp, xdr_wrapstring, &s)) { + fprintf(stderr, "can't decode arguments\en"); +.ft I + /* + * We are silent in the face of protocol errors + */ +.ft CW + break; + } +.ft I + /* + * Code here to render string s, but send no reply! + */ +.ft CW + break; + default: + svcerr_noproc(transp); + return; + } +.ft I + /* + * Now free string allocated while decoding arguments + */ +.ft CW + svc_freeargs(transp, xdr_wrapstring, &s); +} +.DE +Of course the service could have one procedure +that takes the string and a boolean +to indicate whether or not the procedure should respond. +.LP +In order for a client to take advantage of batching, +the client must perform RPC calls on a TCP-based transport +and the actual calls must have the following attributes: +1) the result's XDR routine must be zero +.I NULL ), +and 2) the RPC call's timeout must be zero. +.KS +.LP +Here is an example of a client that uses batching to render a +bunch of strings; the batching is flushed when the client gets +a null string (EOF): +.ie t .DS +.el .DS L +.ft CW +.vs 11 +#include <stdio.h> +#include <rpc/rpc.h> +#include <sys/socket.h> +#include <sys/time.h> +#include <netdb.h> +#include <suntool/windows.h> + +main(argc, argv) + int argc; + char **argv; +{ + struct hostent *hp; + struct timeval pertry_timeout, total_timeout; + struct sockaddr_in server_addr; + int sock = RPC_ANYSOCK; + register CLIENT *client; + enum clnt_stat clnt_stat; + char buf[1000], *s = buf; + + if ((client = clnttcp_create(&server_addr, + WINDOWPROG, WINDOWVERS, &sock, 0, 0)) == NULL) { + perror("clnttcp_create"); + exit(-1); + } + total_timeout.tv_sec = 0; + total_timeout.tv_usec = 0; + while (scanf("%s", s) != EOF) { + clnt_stat = clnt_call(client, RENDERSTRING_BATCHED, + xdr_wrapstring, &s, NULL, NULL, total_timeout); + if (clnt_stat != RPC_SUCCESS) { + clnt_perror(client, "batched rpc"); + exit(-1); + } + } + + /* \fINow flush the pipeline\fP */ + + total_timeout.tv_sec = 20; + clnt_stat = clnt_call(client, NULLPROC, xdr_void, NULL, + xdr_void, NULL, total_timeout); + if (clnt_stat != RPC_SUCCESS) { + clnt_perror(client, "rpc"); + exit(-1); + } + clnt_destroy(client); + exit(0); +} +.vs +.DE +.KE +Since the server sends no message, +the clients cannot be notified of any of the failures that may occur. +Therefore, clients are on their own when it comes to handling errors. +.LP +The above example was completed to render +all of the (2000) lines in the file +.I /etc/termcap . +The rendering service did nothing but throw the lines away. +The example was run in the following four configurations: +1) machine to itself, regular RPC; +2) machine to itself, batched RPC; +3) machine to another, regular RPC; and +4) machine to another, batched RPC. +The results are as follows: +1) 50 seconds; +2) 16 seconds; +3) 52 seconds; +4) 10 seconds. +Running +.I fscanf() +on +.I /etc/termcap +only requires six seconds. +These timings show the advantage of protocols +that allow for overlapped execution, +though these protocols are often hard to design. +.NH 2 +\&Authentication +.IX "authentication" +.IX "RPC" "authentication" +.LP +In the examples presented so far, +the caller never identified itself to the server, +and the server never required an ID from the caller. +Clearly, some network services, such as a network filesystem, +require stronger security than what has been presented so far. +.LP +In reality, every RPC call is authenticated by +the RPC package on the server, and similarly, +the RPC client package generates and sends authentication parameters. +Just as different transports (TCP/IP or UDP/IP) +can be used when creating RPC clients and servers, +different forms of authentication can be associated with RPC clients; +the default authentication type used as a default is type +.I none . +.LP +The authentication subsystem of the RPC package is open ended. +That is, numerous types of authentication are easy to support. +.NH 3 +\&UNIX Authentication +.IX "UNIX Authentication" +.IP "\fIThe Client Side\fP" +.LP +When a caller creates a new RPC client handle as in: +.DS +.ft CW +clnt = clntudp_create(address, prognum, versnum, + wait, sockp) +.DE +the appropriate transport instance defaults +the associate authentication handle to be +.DS +.ft CW +clnt->cl_auth = authnone_create(); +.DE +The RPC client can choose to use +.I UNIX +style authentication by setting +.I clnt\->cl_auth +after creating the RPC client handle: +.DS +.ft CW +clnt->cl_auth = authunix_create_default(); +.DE +This causes each RPC call associated with +.I clnt +to carry with it the following authentication credentials structure: +.ie t .DS +.el .DS L +.ft I +/* + * UNIX style credentials. + */ +.ft CW +struct authunix_parms { + u_long aup_time; /* \fIcredentials creation time\fP */ + char *aup_machname; /* \fIhost name where client is\fP */ + int aup_uid; /* \fIclient's UNIX effective uid\fP */ + int aup_gid; /* \fIclient's current group id\fP */ + u_int aup_len; /* \fIelement length of aup_gids\fP */ + int *aup_gids; /* \fIarray of groups user is in\fP */ +}; +.DE +These fields are set by +.I authunix_create_default() +by invoking the appropriate system calls. +Since the RPC user created this new style of authentication, +the user is responsible for destroying it with: +.DS +.ft CW +auth_destroy(clnt->cl_auth); +.DE +This should be done in all cases, to conserve memory. +.sp +.IP "\fIThe Server Side\fP" +.LP +Service implementors have a harder time dealing with authentication issues +since the RPC package passes the service dispatch routine a request +that has an arbitrary authentication style associated with it. +Consider the fields of a request handle passed to a service dispatch routine: +.ie t .DS +.el .DS L +.ft I +/* + * An RPC Service request + */ +.ft CW +struct svc_req { + u_long rq_prog; /* \fIservice program number\fP */ + u_long rq_vers; /* \fIservice protocol vers num\fP */ + u_long rq_proc; /* \fIdesired procedure number\fP */ + struct opaque_auth rq_cred; /* \fIraw credentials from wire\fP */ + caddr_t rq_clntcred; /* \fIcredentials (read only)\fP */ +}; +.DE +The +.I rq_cred +is mostly opaque, except for one field of interest: +the style or flavor of authentication credentials: +.ie t .DS +.el .DS L +.ft I +/* + * Authentication info. Mostly opaque to the programmer. + */ +.ft CW +struct opaque_auth { + enum_t oa_flavor; /* \fIstyle of credentials\fP */ + caddr_t oa_base; /* \fIaddress of more auth stuff\fP */ + u_int oa_length; /* \fInot to exceed \fIMAX_AUTH_BYTES */ +}; +.DE +.IX RPC guarantees +The RPC package guarantees the following +to the service dispatch routine: +.IP 1. +That the request's +.I rq_cred +is well formed. Thus the service implementor may inspect the request's +.I rq_cred.oa_flavor +to determine which style of authentication the caller used. +The service implementor may also wish to inspect the other fields of +.I rq_cred +if the style is not one of the styles supported by the RPC package. +.IP 2. +That the request's +.I rq_clntcred +field is either +.I NULL +or points to a well formed structure +that corresponds to a supported style of authentication credentials. +Remember that only +.I unix +style is currently supported, so (currently) +.I rq_clntcred +could be cast to a pointer to an +.I authunix_parms +structure. If +.I rq_clntcred +is +.I NULL , +the service implementor may wish to inspect the other (opaque) fields of +.I rq_cred +in case the service knows about a new type of authentication +that the RPC package does not know about. +.LP +Our remote users service example can be extended so that +it computes results for all users except UID 16: +.ie t .DS +.el .DS L +.ft CW +.vs 11 +nuser(rqstp, transp) + struct svc_req *rqstp; + SVCXPRT *transp; +{ + struct authunix_parms *unix_cred; + int uid; + unsigned long nusers; + +.ft I + /* + * we don't care about authentication for null proc + */ +.ft CW + if (rqstp->rq_proc == NULLPROC) { + if (!svc_sendreply(transp, xdr_void, 0)) { + fprintf(stderr, "can't reply to RPC call\en"); + return (1); + } + return; + } +.ft I + /* + * now get the uid + */ +.ft CW + switch (rqstp->rq_cred.oa_flavor) { + case AUTH_UNIX: + unix_cred = + (struct authunix_parms *)rqstp->rq_clntcred; + uid = unix_cred->aup_uid; + break; + case AUTH_NULL: + default: + svcerr_weakauth(transp); + return; + } + switch (rqstp->rq_proc) { + case RUSERSPROC_NUM: +.ft I + /* + * make sure caller is allowed to call this proc + */ +.ft CW + if (uid == 16) { + svcerr_systemerr(transp); + return; + } +.ft I + /* + * Code here to compute the number of users + * and assign it to the variable \fInusers\fP + */ +.ft CW + if (!svc_sendreply(transp, xdr_u_long, &nusers)) { + fprintf(stderr, "can't reply to RPC call\en"); + return (1); + } + return; + default: + svcerr_noproc(transp); + return; + } +} +.vs +.DE +A few things should be noted here. +First, it is customary not to check +the authentication parameters associated with the +.I NULLPROC +(procedure number zero). +Second, if the authentication parameter's type is not suitable +for your service, you should call +.I svcerr_weakauth() . +And finally, the service protocol itself should return status +for access denied; in the case of our example, the protocol +does not have such a status, so we call the service primitive +.I svcerr_systemerr() +instead. +.LP +The last point underscores the relation between +the RPC authentication package and the services; +RPC deals only with +.I authentication +and not with individual services' +.I "access control" . +The services themselves must implement their own access control policies +and reflect these policies as return statuses in their protocols. +.NH 2 +\&DES Authentication +.IX RPC DES +.IX RPC authentication +.LP +UNIX authentication is quite easy to defeat. Instead of using +.I authunix_create_default (), +one can call +.I authunix_create() +and then modify the RPC authentication handle it returns by filling in +whatever user ID and hostname they wish the server to think they have. +DES authentication is thus recommended for people who want more security +than UNIX authentication offers. +.LP +The details of the DES authentication protocol are complicated and +are not explained here. +See +.I "Remote Procedure Calls: Protocol Specification" +for the details. +.LP +In order for DES authentication to work, the +.I keyserv(8c) +daemon must be running on both the server and client machines. The +users on these machines need public keys assigned by the network +administrator in the +.I publickey(5) +database. And, they need to have decrypted their secret keys +using their login password. This automatically happens when one +logs in using +.I login(1) , +or can be done manually using +.I keylogin(1) . +The +.I "Network Services" +chapter +./" XXX +explains more how to setup secure networking. +.sp +.IP "\fIClient Side\fP" +.LP +If a client wishes to use DES authentication, it must set its +authentication handle appropriately. Here is an example: +.DS +cl->cl_auth = + authdes_create(servername, 60, &server_addr, NULL); +.DE +The first argument is the network name or \*Qnetname\*U of the owner of +the server process. Typically, server processes are root processes +and their netname can be derived using the following call: +.DS +char servername[MAXNETNAMELEN]; + +host2netname(servername, rhostname, NULL); +.DE +Here, +.I rhostname +is the hostname of the machine the server process is running on. +.I host2netname() +fills in +.I servername +to contain this root process's netname. If the +server process was run by a regular user, one could use the call +.I user2netname() +instead. Here is an example for a server process with the same user +ID as the client: +.DS +char servername[MAXNETNAMELEN]; + +user2netname(servername, getuid(), NULL); +.DE +The last argument to both of these calls, +.I user2netname() +and +.I host2netname (), +is the name of the naming domain where the server is located. The +.I NULL +used here means \*Quse the local domain name.\*U +.LP +The second argument to +.I authdes_create() +is a lifetime for the credential. Here it is set to sixty +seconds. What that means is that the credential will expire 60 +seconds from now. If some mischievous user tries to reuse the +credential, the server RPC subsystem will recognize that it has +expired and not grant any requests. If the same mischievous user +tries to reuse the credential within the sixty second lifetime, +he will still be rejected because the server RPC subsystem +remembers which credentials it has already seen in the near past, +and will not grant requests to duplicates. +.LP +The third argument to +.I authdes_create() +is the address of the host to synchronize with. In order for DES +authentication to work, the server and client must agree upon the +time. Here we pass the address of the server itself, so the +client and server will both be using the same time: the server's +time. The argument can be +.I NULL , +which means \*Qdon't bother synchronizing.\*U You should only do this +if you are sure the client and server are already synchronized. +.LP +The final argument to +.I authdes_create() +is the address of a DES encryption key to use for encrypting +timestamps and data. If this argument is +.I NULL , +as it is in this example, a random key will be chosen. The client +may find out the encryption key being used by consulting the +.I ah_key +field of the authentication handle. +.sp +.IP "\fIServer Side\fP" +.LP +The server side is a lot simpler than the client side. Here is the +previous example rewritten to use +.I AUTH_DES +instead of +.I AUTH_UNIX : +.ie t .DS +.el .DS L +.ft CW +.vs 11 +#include <sys/time.h> +#include <rpc/auth_des.h> + . . . + . . . +nuser(rqstp, transp) + struct svc_req *rqstp; + SVCXPRT *transp; +{ + struct authdes_cred *des_cred; + int uid; + int gid; + int gidlen; + int gidlist[10]; +.ft I + /* + * we don't care about authentication for null proc + */ +.ft CW + + if (rqstp->rq_proc == NULLPROC) { + /* \fIsame as before\fP */ + } + +.ft I + /* + * now get the uid + */ +.ft CW + switch (rqstp->rq_cred.oa_flavor) { + case AUTH_DES: + des_cred = + (struct authdes_cred *) rqstp->rq_clntcred; + if (! netname2user(des_cred->adc_fullname.name, + &uid, &gid, &gidlen, gidlist)) + { + fprintf(stderr, "unknown user: %s\n", + des_cred->adc_fullname.name); + svcerr_systemerr(transp); + return; + } + break; + case AUTH_NULL: + default: + svcerr_weakauth(transp); + return; + } + +.ft I + /* + * The rest is the same as before + */ +.ft CW +.vs +.DE +Note the use of the routine +.I netname2user (), +the inverse of +.I user2netname (): +it takes a network ID and converts to a unix ID. +.I netname2user () +also supplies the group IDs which we don't use in this example, +but which may be useful to other UNIX programs. +.NH 2 +\&Using Inetd +.IX inetd "" "using \fIinetd\fP" +.LP +An RPC server can be started from +.I inetd +The only difference from the usual code is that the service +creation routine should be called in the following form: +.ie t .DS +.el .DS L +.ft CW +transp = svcudp_create(0); /* \fIFor UDP\fP */ +transp = svctcp_create(0,0,0); /* \fIFor listener TCP sockets\fP */ +transp = svcfd_create(0,0,0); /* \fIFor connected TCP sockets\fP */ +.DE +since +.I inet +passes a socket as file descriptor 0. +Also, +.I svc_register() +should be called as +.ie t .DS +.el .DS L +.ft CW +svc_register(transp, PROGNUM, VERSNUM, service, 0); +.DE +with the final flag as 0, +since the program would already be registered by +.I inetd +Remember that if you want to exit +from the server process and return control to +.I inet +you need to explicitly exit, since +.I svc_run() +never returns. +.LP +The format of entries in +.I /etc/inetd.conf +for RPC services is in one of the following two forms: +.ie t .DS +.el .DS L +.ft CW +p_name/version dgram rpc/udp wait/nowait user server args +p_name/version stream rpc/tcp wait/nowait user server args +.DE +where +.I p_name +is the symbolic name of the program as it appears in +.I rpc(5) , +.I server +is the program implementing the server, +and +.I program +and +.I version +are the program and version numbers of the service. +For more information, see +.I inetd.conf(5) . +.LP +If the same program handles multiple versions, +then the version number can be a range, +as in this example: +.ie t .DS +.el .DS L +.ft CW +rstatd/1-2 dgram rpc/udp wait root /usr/etc/rpc.rstatd +.DE +.NH 1 +\&More Examples +.sp 1 +.NH 2 +\&Versions +.IX "versions" +.IX "RPC" "versions" +.LP +By convention, the first version number of program +.I PROG +is +.I PROGVERS_ORIG +and the most recent version is +.I PROGVERS +Suppose there is a new version of the +.I user +program that returns an +.I "unsigned short" +rather than a +.I long . +If we name this version +.I RUSERSVERS_SHORT +then a server that wants to support both versions +would do a double register. +.ie t .DS +.el .DS L +.ft CW +if (!svc_register(transp, RUSERSPROG, RUSERSVERS_ORIG, + nuser, IPPROTO_TCP)) { + fprintf(stderr, "can't register RUSER service\en"); + exit(1); +} +if (!svc_register(transp, RUSERSPROG, RUSERSVERS_SHORT, + nuser, IPPROTO_TCP)) { + fprintf(stderr, "can't register RUSER service\en"); + exit(1); +} +.DE +Both versions can be handled by the same C procedure: +.ie t .DS +.el .DS L +.ft CW +.vs 11 +nuser(rqstp, transp) + struct svc_req *rqstp; + SVCXPRT *transp; +{ + unsigned long nusers; + unsigned short nusers2; + + switch (rqstp->rq_proc) { + case NULLPROC: + if (!svc_sendreply(transp, xdr_void, 0)) { + fprintf(stderr, "can't reply to RPC call\en"); + return (1); + } + return; + case RUSERSPROC_NUM: +.ft I + /* + * Code here to compute the number of users + * and assign it to the variable \fInusers\fP + */ +.ft CW + nusers2 = nusers; + switch (rqstp->rq_vers) { + case RUSERSVERS_ORIG: + if (!svc_sendreply(transp, xdr_u_long, + &nusers)) { + fprintf(stderr,"can't reply to RPC call\en"); + } + break; + case RUSERSVERS_SHORT: + if (!svc_sendreply(transp, xdr_u_short, + &nusers2)) { + fprintf(stderr,"can't reply to RPC call\en"); + } + break; + } + default: + svcerr_noproc(transp); + return; + } +} +.vs +.DE +.KS +.NH 2 +\&TCP +.IX "TCP" +.LP +Here is an example that is essentially +.I rcp. +The initiator of the RPC +.I snd +call takes its standard input and sends it to the server +.I rcv +which prints it on standard output. +The RPC call uses TCP. +This also illustrates an XDR procedure that behaves differently +on serialization than on deserialization. +.ie t .DS +.el .DS L +.vs 11 +.ft I +/* + * The xdr routine: + * on decode, read from wire, write onto fp + * on encode, read from fp, write onto wire + */ +.ft CW +#include <stdio.h> +#include <rpc/rpc.h> + +xdr_rcp(xdrs, fp) + XDR *xdrs; + FILE *fp; +{ + unsigned long size; + char buf[BUFSIZ], *p; + + if (xdrs->x_op == XDR_FREE)/* nothing to free */ + return 1; + while (1) { + if (xdrs->x_op == XDR_ENCODE) { + if ((size = fread(buf, sizeof(char), BUFSIZ, + fp)) == 0 && ferror(fp)) { + fprintf(stderr, "can't fread\en"); + return (1); + } + } + p = buf; + if (!xdr_bytes(xdrs, &p, &size, BUFSIZ)) + return 0; + if (size == 0) + return 1; + if (xdrs->x_op == XDR_DECODE) { + if (fwrite(buf, sizeof(char), size, + fp) != size) { + fprintf(stderr, "can't fwrite\en"); + return (1); + } + } + } +} +.vs +.DE +.KE +.ie t .DS +.el .DS L +.vs 11 +.ft I +/* + * The sender routines + */ +.ft CW +#include <stdio.h> +#include <netdb.h> +#include <rpc/rpc.h> +#include <sys/socket.h> +#include <sys/time.h> + +main(argc, argv) + int argc; + char **argv; +{ + int xdr_rcp(); + int err; + + if (argc < 2) { + fprintf(stderr, "usage: %s servername\en", argv[0]); + exit(-1); + } + if ((err = callrpctcp(argv[1], RCPPROG, RCPPROC, + RCPVERS, xdr_rcp, stdin, xdr_void, 0) != 0)) { + clnt_perrno(err); + fprintf(stderr, "can't make RPC call\en"); + exit(1); + } + exit(0); +} + +callrpctcp(host, prognum, procnum, versnum, + inproc, in, outproc, out) + char *host, *in, *out; + xdrproc_t inproc, outproc; +{ + struct sockaddr_in server_addr; + int socket = RPC_ANYSOCK; + enum clnt_stat clnt_stat; + struct hostent *hp; + register CLIENT *client; + struct timeval total_timeout; + + if ((hp = gethostbyname(host)) == NULL) { + fprintf(stderr, "can't get addr for '%s'\en", host); + return (-1); + } + bcopy(hp->h_addr, (caddr_t)&server_addr.sin_addr, + hp->h_length); + server_addr.sin_family = AF_INET; + server_addr.sin_port = 0; + if ((client = clnttcp_create(&server_addr, prognum, + versnum, &socket, BUFSIZ, BUFSIZ)) == NULL) { + perror("rpctcp_create"); + return (-1); + } + total_timeout.tv_sec = 20; + total_timeout.tv_usec = 0; + clnt_stat = clnt_call(client, procnum, + inproc, in, outproc, out, total_timeout); + clnt_destroy(client); + return (int)clnt_stat; +} +.vs +.DE +.ie t .DS +.el .DS L +.vs 11 +.ft I +/* + * The receiving routines + */ +.ft CW +#include <stdio.h> +#include <rpc/rpc.h> + +main() +{ + register SVCXPRT *transp; + int rcp_service(), xdr_rcp(); + + if ((transp = svctcp_create(RPC_ANYSOCK, + BUFSIZ, BUFSIZ)) == NULL) { + fprintf("svctcp_create: error\en"); + exit(1); + } + pmap_unset(RCPPROG, RCPVERS); + if (!svc_register(transp, + RCPPROG, RCPVERS, rcp_service, IPPROTO_TCP)) { + fprintf(stderr, "svc_register: error\en"); + exit(1); + } + svc_run(); /* \fInever returns\fP */ + fprintf(stderr, "svc_run should never return\en"); +} + +rcp_service(rqstp, transp) + register struct svc_req *rqstp; + register SVCXPRT *transp; +{ + switch (rqstp->rq_proc) { + case NULLPROC: + if (svc_sendreply(transp, xdr_void, 0) == 0) { + fprintf(stderr, "err: rcp_service"); + return (1); + } + return; + case RCPPROC_FP: + if (!svc_getargs(transp, xdr_rcp, stdout)) { + svcerr_decode(transp); + return; + } + if (!svc_sendreply(transp, xdr_void, 0)) { + fprintf(stderr, "can't reply\en"); + return; + } + return (0); + default: + svcerr_noproc(transp); + return; + } +} +.vs +.DE +.NH 2 +\&Callback Procedures +.IX RPC "callback procedures" +.LP +Occasionally, it is useful to have a server become a client, +and make an RPC call back to the process which is its client. +An example is remote debugging, +where the client is a window system program, +and the server is a debugger running on the remote machine. +Most of the time, +the user clicks a mouse button at the debugging window, +which converts this to a debugger command, +and then makes an RPC call to the server +(where the debugger is actually running), +telling it to execute that command. +However, when the debugger hits a breakpoint, the roles are reversed, +and the debugger wants to make an rpc call to the window program, +so that it can inform the user that a breakpoint has been reached. +.LP +In order to do an RPC callback, +you need a program number to make the RPC call on. +Since this will be a dynamically generated program number, +it should be in the transient range, +.I "0x40000000 - 0x5fffffff" . +The routine +.I gettransient() +returns a valid program number in the transient range, +and registers it with the portmapper. +It only talks to the portmapper running on the same machine as the +.I gettransient() +routine itself. The call to +.I pmap_set() +is a test and set operation, +in that it indivisibly tests whether a program number +has already been registered, +and if it has not, then reserves it. On return, the +.I sockp +argument will contain a socket that can be used +as the argument to an +.I svcudp_create() +or +.I svctcp_create() +call. +.ie t .DS +.el .DS L +.ft CW +.vs 11 +#include <stdio.h> +#include <rpc/rpc.h> +#include <sys/socket.h> + +gettransient(proto, vers, sockp) + int proto, vers, *sockp; +{ + static int prognum = 0x40000000; + int s, len, socktype; + struct sockaddr_in addr; + + switch(proto) { + case IPPROTO_UDP: + socktype = SOCK_DGRAM; + break; + case IPPROTO_TCP: + socktype = SOCK_STREAM; + break; + default: + fprintf(stderr, "unknown protocol type\en"); + return 0; + } + if (*sockp == RPC_ANYSOCK) { + if ((s = socket(AF_INET, socktype, 0)) < 0) { + perror("socket"); + return (0); + } + *sockp = s; + } + else + s = *sockp; + addr.sin_addr.s_addr = 0; + addr.sin_family = AF_INET; + addr.sin_port = 0; + len = sizeof(addr); +.ft I + /* + * may be already bound, so don't check for error + */ +.ft CW + bind(s, &addr, len); + if (getsockname(s, &addr, &len)< 0) { + perror("getsockname"); + return (0); + } + while (!pmap_set(prognum++, vers, proto, + ntohs(addr.sin_port))) continue; + return (prognum-1); +} +.vs +.DE +.SH +Note: +.I +The call to +.I ntohs() +is necessary to ensure that the port number in +.I "addr.sin_port" , +which is in +.I network +byte order, is passed in +.I host +byte order (as +.I pmap_set() +expects). See the +.I byteorder(3N) +man page for more details on the conversion of network +addresses from network to host byte order. +.KS +.LP +The following pair of programs illustrate how to use the +.I gettransient() +routine. +The client makes an RPC call to the server, +passing it a transient program number. +Then the client waits around to receive a callback +from the server at that program number. +The server registers the program +.I EXAMPLEPROG +so that it can receive the RPC call +informing it of the callback program number. +Then at some random time (on receiving an +.I ALRM +signal in this example), it sends a callback RPC call, +using the program number it received earlier. +.ie t .DS +.el .DS L +.vs 11 +.ft I +/* + * client + */ +.ft CW +#include <stdio.h> +#include <rpc/rpc.h> + +int callback(); +char hostname[256]; + +main() +{ + int x, ans, s; + SVCXPRT *xprt; + + gethostname(hostname, sizeof(hostname)); + s = RPC_ANYSOCK; + x = gettransient(IPPROTO_UDP, 1, &s); + fprintf(stderr, "client gets prognum %d\en", x); + if ((xprt = svcudp_create(s)) == NULL) { + fprintf(stderr, "rpc_server: svcudp_create\en"); + exit(1); + } +.ft I + /* protocol is 0 - gettransient does registering + */ +.ft CW + (void)svc_register(xprt, x, 1, callback, 0); + ans = callrpc(hostname, EXAMPLEPROG, EXAMPLEVERS, + EXAMPLEPROC_CALLBACK, xdr_int, &x, xdr_void, 0); + if ((enum clnt_stat) ans != RPC_SUCCESS) { + fprintf(stderr, "call: "); + clnt_perrno(ans); + fprintf(stderr, "\en"); + } + svc_run(); + fprintf(stderr, "Error: svc_run shouldn't return\en"); +} + +callback(rqstp, transp) + register struct svc_req *rqstp; + register SVCXPRT *transp; +{ + switch (rqstp->rq_proc) { + case 0: + if (!svc_sendreply(transp, xdr_void, 0)) { + fprintf(stderr, "err: exampleprog\en"); + return (1); + } + return (0); + case 1: + if (!svc_getargs(transp, xdr_void, 0)) { + svcerr_decode(transp); + return (1); + } + fprintf(stderr, "client got callback\en"); + if (!svc_sendreply(transp, xdr_void, 0)) { + fprintf(stderr, "err: exampleprog"); + return (1); + } + } +} +.vs +.DE +.KE +.ie t .DS +.el .DS L +.vs 11 +.ft I +/* + * server + */ +.ft CW +#include <stdio.h> +#include <rpc/rpc.h> +#include <sys/signal.h> + +char *getnewprog(); +char hostname[256]; +int docallback(); +int pnum; /* \fIprogram number for callback routine\fP */ + +main() +{ + gethostname(hostname, sizeof(hostname)); + registerrpc(EXAMPLEPROG, EXAMPLEVERS, + EXAMPLEPROC_CALLBACK, getnewprog, xdr_int, xdr_void); + fprintf(stderr, "server going into svc_run\en"); + signal(SIGALRM, docallback); + alarm(10); + svc_run(); + fprintf(stderr, "Error: svc_run shouldn't return\en"); +} + +char * +getnewprog(pnump) + char *pnump; +{ + pnum = *(int *)pnump; + return NULL; +} + +docallback() +{ + int ans; + + ans = callrpc(hostname, pnum, 1, 1, xdr_void, 0, + xdr_void, 0); + if (ans != 0) { + fprintf(stderr, "server: "); + clnt_perrno(ans); + fprintf(stderr, "\en"); + } +} +.vs +.DE diff --git a/cpukit/librpc/src/rpc/PSD.doc/rpc.rfc.ms b/cpukit/librpc/src/rpc/PSD.doc/rpc.rfc.ms index e69de29bb2..af9c2df2ed 100644 --- a/cpukit/librpc/src/rpc/PSD.doc/rpc.rfc.ms +++ b/cpukit/librpc/src/rpc/PSD.doc/rpc.rfc.ms @@ -0,0 +1,1302 @@ +.\" +.\" Must use -- tbl -- with this one +.\" +.\" @(#)rpc.rfc.ms 2.2 88/08/05 4.0 RPCSRC +.de BT +.if \\n%=1 .tl ''- % -'' +.. +.ND +.\" prevent excess underlining in nroff +.if n .fp 2 R +.OH 'Remote Procedure Calls: Protocol Specification''Page %' +.EH 'Page %''Remote Procedure Calls: Protocol Specification' +.if \\n%=1 .bp +.SH +\&Remote Procedure Calls: Protocol Specification +.LP +.NH 0 +\&Status of this Memo +.LP +Note: This chapter specifies a protocol that Sun Microsystems, Inc., +and others are using. +It has been designated RFC1050 by the ARPA Network +Information Center. +.LP +.NH 1 +\&Introduction +.LP +This chapter specifies a message protocol used in implementing +Sun's Remote Procedure Call (RPC) package. (The message protocol is +specified with the External Data Representation (XDR) language. +See the +.I "External Data Representation Standard: Protocol Specification" +for the details. Here, we assume that the reader is familiar +with XDR and do not attempt to justify it or its uses). The paper +by Birrell and Nelson [1] is recommended as an excellent background +to and justification of RPC. +.NH 2 +\&Terminology +.LP +This chapter discusses servers, services, programs, procedures, +clients, and versions. A server is a piece of software where network +services are implemented. A network service is a collection of one +or more remote programs. A remote program implements one or more +remote procedures; the procedures, their parameters, and results are +documented in the specific program's protocol specification (see the +\fIPort Mapper Program Protocol\fP\, below, for an example). Network +clients are pieces of software that initiate remote procedure calls +to services. A server may support more than one version of a remote +program in order to be forward compatible with changing protocols. +.LP +For example, a network file service may be composed of two programs. +One program may deal with high-level applications such as file system +access control and locking. The other may deal with low-level file +IO and have procedures like "read" and "write". A client machine of +the network file service would call the procedures associated with +the two programs of the service on behalf of some user on the client +machine. +.NH 2 +\&The RPC Model +.LP +The remote procedure call model is similar to the local procedure +call model. In the local case, the caller places arguments to a +procedure in some well-specified location (such as a result +register). It then transfers control to the procedure, and +eventually gains back control. At that point, the results of the +procedure are extracted from the well-specified location, and the +caller continues execution. +.LP +The remote procedure call is similar, in that one thread of control +logically winds through two processes\(emone is the caller's process, +the other is a server's process. That is, the caller process sends a +call message to the server process and waits (blocks) for a reply +message. The call message contains the procedure's parameters, among +other things. The reply message contains the procedure's results, +among other things. Once the reply message is received, the results +of the procedure are extracted, and caller's execution is resumed. +.LP +On the server side, a process is dormant awaiting the arrival of a +call message. When one arrives, the server process extracts the +procedure's parameters, computes the results, sends a reply message, +and then awaits the next call message. +.LP +Note that in this model, only one of the two processes is active at +any given time. However, this model is only given as an example. +The RPC protocol makes no restrictions on the concurrency model +implemented, and others are possible. For example, an implementation +may choose to have RPC calls be asynchronous, so that the client may +do useful work while waiting for the reply from the server. Another +possibility is to have the server create a task to process an +incoming request, so that the server can be free to receive other +requests. +.NH 2 +\&Transports and Semantics +.LP +The RPC protocol is independent of transport protocols. That is, RPC +does not care how a message is passed from one process to another. +The protocol deals only with specification and interpretation of +messages. +.LP +It is important to point out that RPC does not try to implement any +kind of reliability and that the application must be aware of the +type of transport protocol underneath RPC. If it knows it is running +on top of a reliable transport such as TCP/IP[6], then most of the +work is already done for it. On the other hand, if it is running on +top of an unreliable transport such as UDP/IP[7], it must implement +is own retransmission and time-out policy as the RPC layer does not +provide this service. +.LP +Because of transport independence, the RPC protocol does not attach +specific semantics to the remote procedures or their execution. +Semantics can be inferred from (but should be explicitly specified +by) the underlying transport protocol. For example, consider RPC +running on top of an unreliable transport such as UDP/IP. If an +application retransmits RPC messages after short time-outs, the only +thing it can infer if it receives no reply is that the procedure was +executed zero or more times. If it does receive a reply, then it can +infer that the procedure was executed at least once. +.LP +A server may wish to remember previously granted requests from a +client and not regrant them in order to insure some degree of +execute-at-most-once semantics. A server can do this by taking +advantage of the transaction ID that is packaged with every RPC +request. The main use of this transaction is by the client RPC layer +in matching replies to requests. However, a client application may +choose to reuse its previous transaction ID when retransmitting a +request. The server application, knowing this fact, may choose to +remember this ID after granting a request and not regrant requests +with the same ID in order to achieve some degree of +execute-at-most-once semantics. The server is not allowed to examine +this ID in any other way except as a test for equality. +.LP +On the other hand, if using a reliable transport such as TCP/IP, the +application can infer from a reply message that the procedure was +executed exactly once, but if it receives no reply message, it cannot +assume the remote procedure was not executed. Note that even if a +connection-oriented protocol like TCP is used, an application still +needs time-outs and reconnection to handle server crashes. +.LP +There are other possibilities for transports besides datagram- or +connection-oriented protocols. For example, a request-reply protocol +such as VMTP[2] is perhaps the most natural transport for RPC. +.SH +.I +NOTE: At Sun, RPC is currently implemented on top of both TCP/IP +and UDP/IP transports. +.LP +.NH 2 +\&Binding and Rendezvous Independence +.LP +The act of binding a client to a service is NOT part of the remote +procedure call specification. This important and necessary function +is left up to some higher-level software. (The software may use RPC +itself\(emsee the \fIPort Mapper Program Protocol\fP\, below). +.LP +Implementors should think of the RPC protocol as the jump-subroutine +instruction ("JSR") of a network; the loader (binder) makes JSR +useful, and the loader itself uses JSR to accomplish its task. +Likewise, the network makes RPC useful, using RPC to accomplish this +task. +.NH 2 +\&Authentication +.LP +The RPC protocol provides the fields necessary for a client to +identify itself to a service and vice-versa. Security and access +control mechanisms can be built on top of the message authentication. +Several different authentication protocols can be supported. A field +in the RPC header indicates which protocol is being used. More +information on specific authentication protocols can be found in the +\fIAuthentication Protocols\fP\, +below. +.KS +.NH 1 +\&RPC Protocol Requirements +.LP +The RPC protocol must provide for the following: +.IP 1. +Unique specification of a procedure to be called. +.IP 2. +Provisions for matching response messages to request messages. +.KE +.IP 3. +Provisions for authenticating the caller to service and vice-versa. +.LP +Besides these requirements, features that detect the following are +worth supporting because of protocol roll-over errors, implementation +bugs, user error, and network administration: +.IP 1. +RPC protocol mismatches. +.IP 2. +Remote program protocol version mismatches. +.IP 3. +Protocol errors (such as misspecification of a procedure's parameters). +.IP 4. +Reasons why remote authentication failed. +.IP 5. +Any other reasons why the desired procedure was not called. +.NH 2 +\&Programs and Procedures +.LP +The RPC call message has three unsigned fields: remote program +number, remote program version number, and remote procedure number. +The three fields uniquely identify the procedure to be called. +Program numbers are administered by some central authority (like +Sun). Once an implementor has a program number, he can implement his +remote program; the first implementation would most likely have the +version number of 1. Because most new protocols evolve into better, +stable, and mature protocols, a version field of the call message +identifies which version of the protocol the caller is using. +Version numbers make speaking old and new protocols through the same +server process possible. +.LP +The procedure number identifies the procedure to be called. These +numbers are documented in the specific program's protocol +specification. For example, a file service's protocol specification +may state that its procedure number 5 is "read" and procedure number +12 is "write". +.LP +Just as remote program protocols may change over several versions, +the actual RPC message protocol could also change. Therefore, the +call message also has in it the RPC version number, which is always +equal to two for the version of RPC described here. +.LP +The reply message to a request message has enough information to +distinguish the following error conditions: +.IP 1. +The remote implementation of RPC does speak protocol version 2. +The lowest and highest supported RPC version numbers are returned. +.IP 2. +The remote program is not available on the remote system. +.IP 3. +The remote program does not support the requested version number. +The lowest and highest supported remote program version numbers are +returned. +.IP 4. +The requested procedure number does not exist. (This is usually a +caller side protocol or programming error.) +.IP 5. +The parameters to the remote procedure appear to be garbage from the +server's point of view. (Again, this is usually caused by a +disagreement about the protocol between client and service.) +.NH 2 +\&Authentication +.LP +Provisions for authentication of caller to service and vice-versa are +provided as a part of the RPC protocol. The call message has two +authentication fields, the credentials and verifier. The reply +message has one authentication field, the response verifier. The RPC +protocol specification defines all three fields to be the following +opaque type: +.DS +.ft CW +.vs 11 +enum auth_flavor { + AUTH_NULL = 0, + AUTH_UNIX = 1, + AUTH_SHORT = 2, + AUTH_DES = 3 + /* \fIand more to be defined\fP */ +}; + +struct opaque_auth { + auth_flavor flavor; + opaque body<400>; +}; +.DE +.LP +In simple English, any +.I opaque_auth +structure is an +.I auth_flavor +enumeration followed by bytes which are opaque to the RPC protocol +implementation. +.LP +The interpretation and semantics of the data contained within the +authentication fields is specified by individual, independent +authentication protocol specifications. (See +\fIAuthentication Protocols\fP\, +below, for definitions of the various authentication protocols.) +.LP +If authentication parameters were rejected, the response message +contains information stating why they were rejected. +.NH 2 +\&Program Number Assignment +.LP +Program numbers are given out in groups of +.I 0x20000000 +(decimal 536870912) according to the following chart: +.TS +box tab (&) ; +lfI lfI +rfL cfI . +Program Numbers&Description +_ +.sp .5 +0 - 1fffffff&Defined by Sun +20000000 - 3fffffff&Defined by user +40000000 - 5fffffff&Transient +60000000 - 7fffffff&Reserved +80000000 - 9fffffff&Reserved +a0000000 - bfffffff&Reserved +c0000000 - dfffffff&Reserved +e0000000 - ffffffff&Reserved +.TE +.LP +The first group is a range of numbers administered by Sun +Microsystems and should be identical for all sites. The second range +is for applications peculiar to a particular site. This range is +intended primarily for debugging new programs. When a site develops +an application that might be of general interest, that application +should be given an assigned number in the first range. The third +group is for applications that generate program numbers dynamically. +The final groups are reserved for future use, and should not be used. +.NH 2 +\&Other Uses of the RPC Protocol +.LP +The intended use of this protocol is for calling remote procedures. +That is, each call message is matched with a response message. +However, the protocol itself is a message-passing protocol with which +other (non-RPC) protocols can be implemented. Sun currently uses, or +perhaps abuses, the RPC message protocol for the following two +(non-RPC) protocols: batching (or pipelining) and broadcast RPC. +These two protocols are discussed but not defined below. +.NH 3 +\&Batching +.LP +Batching allows a client to send an arbitrarily large sequence of +call messages to a server; batching typically uses reliable byte +stream protocols (like TCP/IP) for its transport. In the case of +batching, the client never waits for a reply from the server, and the +server does not send replies to batch requests. A sequence of batch +calls is usually terminated by a legitimate RPC in order to flush the +pipeline (with positive acknowledgement). +.NH 3 +\&Broadcast RPC +.LP +In broadcast RPC-based protocols, the client sends a broadcast packet +to the network and waits for numerous replies. Broadcast RPC uses +unreliable, packet-based protocols (like UDP/IP) as its transports. +Servers that support broadcast protocols only respond when the +request is successfully processed, and are silent in the face of +errors. Broadcast RPC uses the Port Mapper RPC service to achieve +its semantics. See the \fIPort Mapper Program Protocol\fP\, below, +for more information. +.KS +.NH 1 +\&The RPC Message Protocol +.LP +This section defines the RPC message protocol in the XDR data +description language. The message is defined in a top-down style. +.ie t .DS +.el .DS L +.ft CW +enum msg_type { + CALL = 0, + REPLY = 1 +}; + +.ft I +/* +* A reply to a call message can take on two forms: +* The message was either accepted or rejected. +*/ +.ft CW +enum reply_stat { + MSG_ACCEPTED = 0, + MSG_DENIED = 1 +}; + +.ft I +/* +* Given that a call message was accepted, the following is the +* status of an attempt to call a remote procedure. +*/ +.ft CW +enum accept_stat { + SUCCESS = 0, /* \fIRPC executed successfully \fP*/ + PROG_UNAVAIL = 1, /* \fIremote hasn't exported program \fP*/ + PROG_MISMATCH = 2, /* \fIremote can't support version # \fP*/ + PROC_UNAVAIL = 3, /* \fIprogram can't support procedure \fP*/ + GARBAGE_ARGS = 4 /* \fIprocedure can't decode params \fP*/ +}; +.DE +.ie t .DS +.el .DS L +.ft I +/* +* Reasons why a call message was rejected: +*/ +.ft CW +enum reject_stat { + RPC_MISMATCH = 0, /* \fIRPC version number != 2 \fP*/ + AUTH_ERROR = 1 /* \fIremote can't authenticate caller \fP*/ +}; + +.ft I +/* +* Why authentication failed: +*/ +.ft CW +enum auth_stat { + AUTH_BADCRED = 1, /* \fIbad credentials \fP*/ + AUTH_REJECTEDCRED = 2, /* \fIclient must begin new session \fP*/ + AUTH_BADVERF = 3, /* \fIbad verifier \fP*/ + AUTH_REJECTEDVERF = 4, /* \fIverifier expired or replayed \fP*/ + AUTH_TOOWEAK = 5 /* \fIrejected for security reasons \fP*/ +}; +.DE +.KE +.ie t .DS +.el .DS L +.ft I +/* +* The RPC message: +* All messages start with a transaction identifier, xid, +* followed by a two-armed discriminated union. The union's +* discriminant is a msg_type which switches to one of the two +* types of the message. The xid of a \fIREPLY\fP message always +* matches that of the initiating \fICALL\fP message. NB: The xid +* field is only used for clients matching reply messages with +* call messages or for servers detecting retransmissions; the +* service side cannot treat this id as any type of sequence +* number. +*/ +.ft CW +struct rpc_msg { + unsigned int xid; + union switch (msg_type mtype) { + case CALL: + call_body cbody; + case REPLY: + reply_body rbody; + } body; +}; +.DE +.ie t .DS +.el .DS L +.ft I +/* +* Body of an RPC request call: +* In version 2 of the RPC protocol specification, rpcvers must +* be equal to 2. The fields prog, vers, and proc specify the +* remote program, its version number, and the procedure within +* the remote program to be called. After these fields are two +* authentication parameters: cred (authentication credentials) +* and verf (authentication verifier). The two authentication +* parameters are followed by the parameters to the remote +* procedure, which are specified by the specific program +* protocol. +*/ +.ft CW +struct call_body { + unsigned int rpcvers; /* \fImust be equal to two (2) \fP*/ + unsigned int prog; + unsigned int vers; + unsigned int proc; + opaque_auth cred; + opaque_auth verf; + /* \fIprocedure specific parameters start here \fP*/ +}; +.DE +.ie t .DS +.el .DS L +.ft I +/* +* Body of a reply to an RPC request: +* The call message was either accepted or rejected. +*/ +.ft CW +union reply_body switch (reply_stat stat) { + case MSG_ACCEPTED: + accepted_reply areply; + case MSG_DENIED: + rejected_reply rreply; +} reply; +.DE +.ie t .DS +.el .DS L +.ft I +/* +* Reply to an RPC request that was accepted by the server: +* there could be an error even though the request was accepted. +* The first field is an authentication verifier that the server +* generates in order to validate itself to the caller. It is +* followed by a union whose discriminant is an enum +* accept_stat. The \fISUCCESS\fP arm of the union is protocol +* specific. The \fIPROG_UNAVAIL\fP, \fIPROC_UNAVAIL\fP, and \fIGARBAGE_ARGP\fP +* arms of the union are void. The \fIPROG_MISMATCH\fP arm specifies +* the lowest and highest version numbers of the remote program +* supported by the server. +*/ +.ft CW +struct accepted_reply { + opaque_auth verf; + union switch (accept_stat stat) { + case SUCCESS: + opaque results[0]; + /* \fIprocedure-specific results start here\fP */ + case PROG_MISMATCH: + struct { + unsigned int low; + unsigned int high; + } mismatch_info; + default: +.ft I + /* + * Void. Cases include \fIPROG_UNAVAIL, PROC_UNAVAIL\fP, + * and \fIGARBAGE_ARGS\fP. + */ +.ft CW + void; + } reply_data; +}; +.DE +.ie t .DS +.el .DS L +.ft I +/* +* Reply to an RPC request that was rejected by the server: +* The request can be rejected for two reasons: either the +* server is not running a compatible version of the RPC +* protocol (\fIRPC_MISMATCH\fP), or the server refuses to +* authenticate the caller (\fIAUTH_ERROR\fP). In case of an RPC +* version mismatch, the server returns the lowest and highest +* supported RPC version numbers. In case of refused +* authentication, failure status is returned. +*/ +.ft CW +union rejected_reply switch (reject_stat stat) { + case RPC_MISMATCH: + struct { + unsigned int low; + unsigned int high; + } mismatch_info; + case AUTH_ERROR: + auth_stat stat; +}; +.DE +.NH 1 +\&Authentication Protocols +.LP +As previously stated, authentication parameters are opaque, but +open-ended to the rest of the RPC protocol. This section defines +some "flavors" of authentication implemented at (and supported by) +Sun. Other sites are free to invent new authentication types, with +the same rules of flavor number assignment as there is for program +number assignment. +.NH 2 +\&Null Authentication +.LP +Often calls must be made where the caller does not know who he is or +the server does not care who the caller is. In this case, the flavor +value (the discriminant of the \fIopaque_auth\fP's union) of the RPC +message's credentials, verifier, and response verifier is +.I AUTH_NULL . +The bytes of the opaque_auth's body are undefined. +It is recommended that the opaque length be zero. +.NH 2 +\&UNIX Authentication +.LP +The caller of a remote procedure may wish to identify himself as he +is identified on a UNIX system. The value of the credential's +discriminant of an RPC call message is +.I AUTH_UNIX . +The bytes of +the credential's opaque body encode the following structure: +.DS +.ft CW +struct auth_unix { + unsigned int stamp; + string machinename<255>; + unsigned int uid; + unsigned int gid; + unsigned int gids<10>; +}; +.DE +The +.I stamp +is an arbitrary ID which the caller machine may +generate. The +.I machinename +is the name of the caller's machine (like "krypton"). The +.I uid +is the caller's effective user ID. The +.I gid +is the caller's effective group ID. The +.I gids +is a +counted array of groups which contain the caller as a member. The +verifier accompanying the credentials should be of +.I AUTH_NULL +(defined above). +.LP +The value of the discriminant of the response verifier received in +the reply message from the server may be +.I AUTH_NULL +or +.I AUTH_SHORT . +In the case of +.I AUTH_SHORT , +the bytes of the response verifier's string encode an opaque +structure. This new opaque structure may now be passed to the server +instead of the original +.I AUTH_UNIX +flavor credentials. The server keeps a cache which maps shorthand +opaque structures (passed back by way of an +.I AUTH_SHORT +style response verifier) to the original credentials of the caller. +The caller can save network bandwidth and server cpu cycles by using +the new credentials. +.LP +The server may flush the shorthand opaque structure at any time. If +this happens, the remote procedure call message will be rejected due +to an authentication error. The reason for the failure will be +.I AUTH_REJECTEDCRED . +At this point, the caller may wish to try the original +.I AUTH_UNIX +style of credentials. +.KS +.NH 2 +\&DES Authentication +.LP +UNIX authentication suffers from two major problems: +.IP 1. +The naming is too UNIX-system oriented. +.IP 2. +There is no verifier, so credentials can easily be faked. +.LP +DES authentication attempts to fix these two problems. +.KE +.NH 3 +\&Naming +.LP +The first problem is handled by addressing the caller by a simple +string of characters instead of by an operating system specific +integer. This string of characters is known as the "netname" or +network name of the caller. The server is not allowed to interpret +the contents of the caller's name in any other way except to +identify the caller. Thus, netnames should be unique for every +caller in the internet. +.LP +It is up to each operating system's implementation of DES +authentication to generate netnames for its users that insure this +uniqueness when they call upon remote servers. Operating systems +already know how to distinguish users local to their systems. It is +usually a simple matter to extend this mechanism to the network. +For example, a UNIX user at Sun with a user ID of 515 might be +assigned the following netname: "unix.515@sun.com". This netname +contains three items that serve to insure it is unique. Going +backwards, there is only one naming domain called "sun.com" in the +internet. Within this domain, there is only one UNIX user with +user ID 515. However, there may be another user on another +operating system, for example VMS, within the same naming domain +that, by coincidence, happens to have the same user ID. To insure +that these two users can be distinguished we add the operating +system name. So one user is "unix.515@sun.com" and the other is +"vms.515@sun.com". +.LP +The first field is actually a naming method rather than an +operating system name. It just happens that today there is almost +a one-to-one correspondence between naming methods and operating +systems. If the world could agree on a naming standard, the first +field could be the name of that standard, instead of an operating +system name. +.LP +.NH 3 +\&DES Authentication Verifiers +.LP +Unlike UNIX authentication, DES authentication does have a verifier +so the server can validate the client's credential (and +vice-versa). The contents of this verifier is primarily an +encrypted timestamp. The server can decrypt this timestamp, and if +it is close to what the real time is, then the client must have +encrypted it correctly. The only way the client could encrypt it +correctly is to know the "conversation key" of the RPC session. And +if the client knows the conversation key, then it must be the real +client. +.LP +The conversation key is a DES [5] key which the client generates +and notifies the server of in its first RPC call. The conversation +key is encrypted using a public key scheme in this first +transaction. The particular public key scheme used in DES +authentication is Diffie-Hellman [3] with 192-bit keys. The +details of this encryption method are described later. +.LP +The client and the server need the same notion of the current time +in order for all of this to work. If network time synchronization +cannot be guaranteed, then client can synchronize with the server +before beginning the conversation, perhaps by consulting the +Internet Time Server (TIME[4]). +.LP +The way a server determines if a client timestamp is valid is +somewhat complicated. For any other transaction but the first, the +server just checks for two things: +.IP 1. +the timestamp is greater than the one previously seen from the +same client. +.IP 2. +the timestamp has not expired. +.LP +A timestamp is expired if the server's time is later than the sum +of the client's timestamp plus what is known as the client's +"window". The "window" is a number the client passes (encrypted) +to the server in its first transaction. You can think of it as a +lifetime for the credential. +.LP +This explains everything but the first transaction. In the first +transaction, the server checks only that the timestamp has not +expired. If this was all that was done though, then it would be +quite easy for the client to send random data in place of the +timestamp with a fairly good chance of succeeding. As an added +check, the client sends an encrypted item in the first transaction +known as the "window verifier" which must be equal to the window +minus 1, or the server will reject the credential. +.LP +The client too must check the verifier returned from the server to +be sure it is legitimate. The server sends back to the client the +encrypted timestamp it received from the client, minus one second. +If the client gets anything different than this, it will reject it. +.LP +.NH 3 +\&Nicknames and Clock Synchronization +.LP +After the first transaction, the server's DES authentication +subsystem returns in its verifier to the client an integer +"nickname" which the client may use in its further transactions +instead of passing its netname, encrypted DES key and window every +time. The nickname is most likely an index into a table on the +server which stores for each client its netname, decrypted DES key +and window. +.LP +Though they originally were synchronized, the client's and server's +clocks can get out of sync again. When this happens the client RPC +subsystem most likely will get back +.I RPC_AUTHERROR +at which point it should resynchronize. +.LP +A client may still get the +.I RPC_AUTHERROR +error even though it is +synchronized with the server. The reason is that the server's +nickname table is a limited size, and it may flush entries whenever +it wants. A client should resend its original credential in this +case and the server will give it a new nickname. If a server +crashes, the entire nickname table gets flushed, and all clients +will have to resend their original credentials. +.KS +.NH 3 +\&DES Authentication Protocol (in XDR language) +.ie t .DS +.el .DS L +.ft I +/* +* There are two kinds of credentials: one in which the client uses +* its full network name, and one in which it uses its "nickname" +* (just an unsigned integer) given to it by the server. The +* client must use its fullname in its first transaction with the +* server, in which the server will return to the client its +* nickname. The client may use its nickname in all further +* transactions with the server. There is no requirement to use the +* nickname, but it is wise to use it for performance reasons. +*/ +.ft CW +enum authdes_namekind { + ADN_FULLNAME = 0, + ADN_NICKNAME = 1 +}; + +.ft I +/* +* A 64-bit block of encrypted DES data +*/ +.ft CW +typedef opaque des_block[8]; + +.ft I +/* +* Maximum length of a network user's name +*/ +.ft CW +const MAXNETNAMELEN = 255; + +.ft I +/* +* A fullname contains the network name of the client, an encrypted +* conversation key and the window. The window is actually a +* lifetime for the credential. If the time indicated in the +* verifier timestamp plus the window has past, then the server +* should expire the request and not grant it. To insure that +* requests are not replayed, the server should insist that +* timestamps are greater than the previous one seen, unless it is +* the first transaction. In the first transaction, the server +* checks instead that the window verifier is one less than the +* window. +*/ +.ft CW +struct authdes_fullname { +string name<MAXNETNAMELEN>; /* \fIname of client \f(CW*/ +des_block key; /* \fIPK encrypted conversation key \f(CW*/ +unsigned int window; /* \fIencrypted window \f(CW*/ +}; + +.ft I +/* +* A credential is either a fullname or a nickname +*/ +.ft CW +union authdes_cred switch (authdes_namekind adc_namekind) { + case ADN_FULLNAME: + authdes_fullname adc_fullname; + case ADN_NICKNAME: + unsigned int adc_nickname; +}; + +.ft I +/* +* A timestamp encodes the time since midnight, January 1, 1970. +*/ +.ft CW +struct timestamp { + unsigned int seconds; /* \fIseconds \fP*/ + unsigned int useconds; /* \fIand microseconds \fP*/ +}; + +.ft I +/* +* Verifier: client variety +* The window verifier is only used in the first transaction. In +* conjunction with a fullname credential, these items are packed +* into the following structure before being encrypted: +* +* \f(CWstruct {\fP +* \f(CWadv_timestamp; \fP-- one DES block +* \f(CWadc_fullname.window; \fP-- one half DES block +* \f(CWadv_winverf; \fP-- one half DES block +* \f(CW}\fP +* This structure is encrypted using CBC mode encryption with an +* input vector of zero. All other encryptions of timestamps use +* ECB mode encryption. +*/ +.ft CW +struct authdes_verf_clnt { + timestamp adv_timestamp; /* \fIencrypted timestamp \fP*/ + unsigned int adv_winverf; /* \fIencrypted window verifier \fP*/ +}; + +.ft I +/* +* Verifier: server variety +* The server returns (encrypted) the same timestamp the client +* gave it minus one second. It also tells the client its nickname +* to be used in future transactions (unencrypted). +*/ +.ft CW +struct authdes_verf_svr { +timestamp adv_timeverf; /* \fIencrypted verifier \fP*/ +unsigned int adv_nickname; /* \fInew nickname for client \fP*/ +}; +.DE +.KE +.NH 3 +\&Diffie-Hellman Encryption +.LP +In this scheme, there are two constants, +.I BASE +and +.I MODULUS . +The +particular values Sun has chosen for these for the DES +authentication protocol are: +.ie t .DS +.el .DS L +.ft CW +const BASE = 3; +const MODULUS = + "d4a0ba0250b6fd2ec626e7efd637df76c716e22d0944b88b"; /* \fIhex \fP*/ +.DE +.ft R +The way this scheme works is best explained by an example. Suppose +there are two people "A" and "B" who want to send encrypted +messages to each other. So, A and B both generate "secret" keys at +random which they do not reveal to anyone. Let these keys be +represented as SK(A) and SK(B). They also publish in a public +directory their "public" keys. These keys are computed as follows: +.ie t .DS +.el .DS L +.ft CW +PK(A) = ( BASE ** SK(A) ) mod MODULUS +PK(B) = ( BASE ** SK(B) ) mod MODULUS +.DE +.ft R +The "**" notation is used here to represent exponentiation. Now, +both A and B can arrive at the "common" key between them, +represented here as CK(A, B), without revealing their secret keys. +.LP +A computes: +.ie t .DS +.el .DS L +.ft CW +CK(A, B) = ( PK(B) ** SK(A)) mod MODULUS +.DE +.ft R +while B computes: +.ie t .DS +.el .DS L +.ft CW +CK(A, B) = ( PK(A) ** SK(B)) mod MODULUS +.DE +.ft R +These two can be shown to be equivalent: +.ie t .DS +.el .DS L +.ft CW +(PK(B) ** SK(A)) mod MODULUS = (PK(A) ** SK(B)) mod MODULUS +.DE +.ft R +We drop the "mod MODULUS" parts and assume modulo arithmetic to +simplify things: +.ie t .DS +.el .DS L +.ft CW +PK(B) ** SK(A) = PK(A) ** SK(B) +.DE +.ft R +Then, replace PK(B) by what B computed earlier and likewise for +PK(A). +.ie t .DS +.el .DS L +.ft CW +((BASE ** SK(B)) ** SK(A) = (BASE ** SK(A)) ** SK(B) +.DE +.ft R +which leads to: +.ie t .DS +.el .DS L +.ft CW +BASE ** (SK(A) * SK(B)) = BASE ** (SK(A) * SK(B)) +.DE +.ft R +This common key CK(A, B) is not used to encrypt the timestamps used +in the protocol. Rather, it is used only to encrypt a conversation +key which is then used to encrypt the timestamps. The reason for +doing this is to use the common key as little as possible, for fear +that it could be broken. Breaking the conversation key is a far +less serious offense, since conversations are relatively +short-lived. +.LP +The conversation key is encrypted using 56-bit DES keys, yet the +common key is 192 bits. To reduce the number of bits, 56 bits are +selected from the common key as follows. The middle-most 8-bytes +are selected from the common key, and then parity is added to the +lower order bit of each byte, producing a 56-bit key with 8 bits of +parity. +.KS +.NH 1 +\&Record Marking Standard +.LP +When RPC messages are passed on top of a byte stream protocol (like +TCP/IP), it is necessary, or at least desirable, to delimit one +message from another in order to detect and possibly recover from +user protocol errors. This is called record marking (RM). Sun uses +this RM/TCP/IP transport for passing RPC messages on TCP streams. +One RPC message fits into one RM record. +.LP +A record is composed of one or more record fragments. A record +fragment is a four-byte header followed by 0 to (2**31) - 1 bytes of +fragment data. The bytes encode an unsigned binary number; as with +XDR integers, the byte order is from highest to lowest. The number +encodes two values\(ema boolean which indicates whether the fragment +is the last fragment of the record (bit value 1 implies the fragment +is the last fragment) and a 31-bit unsigned binary value which is the +length in bytes of the fragment's data. The boolean value is the +highest-order bit of the header; the length is the 31 low-order bits. +(Note that this record specification is NOT in XDR standard form!) +.KE +.KS +.NH 1 +\&The RPC Language +.LP +Just as there was a need to describe the XDR data-types in a formal +language, there is also need to describe the procedures that operate +on these XDR data-types in a formal language as well. We use the RPC +Language for this purpose. It is an extension to the XDR language. +The following example is used to describe the essence of the +language. +.NH 2 +\&An Example Service Described in the RPC Language +.LP +Here is an example of the specification of a simple ping program. +.ie t .DS +.el .DS L +.vs 11 +.ft I +/* +* Simple ping program +*/ +.ft CW +program PING_PROG { + /* \fILatest and greatest version\fP */ + version PING_VERS_PINGBACK { + void + PINGPROC_NULL(void) = 0; + +.ft I + /* + * Ping the caller, return the round-trip time + * (in microseconds). Returns -1 if the operation + * timed out. + */ +.ft CW + int + PINGPROC_PINGBACK(void) = 1; +} = 2; + +.ft I +/* +* Original version +*/ +.ft CW +version PING_VERS_ORIG { + void + PINGPROC_NULL(void) = 0; + } = 1; +} = 1; + +const PING_VERS = 2; /* \fIlatest version \fP*/ +.vs +.DE +.KE +.LP +The first version described is +.I PING_VERS_PINGBACK +with two procedures, +.I PINGPROC_NULL +and +.I PINGPROC_PINGBACK . +.I PINGPROC_NULL +takes no arguments and returns no results, but it is useful for +computing round-trip times from the client to the server and back +again. By convention, procedure 0 of any RPC protocol should have +the same semantics, and never require any kind of authentication. +The second procedure is used for the client to have the server do a +reverse ping operation back to the client, and it returns the amount +of time (in microseconds) that the operation used. The next version, +.I PING_VERS_ORIG , +is the original version of the protocol +and it does not contain +.I PINGPROC_PINGBACK +procedure. It is useful +for compatibility with old client programs, and as this program +matures it may be dropped from the protocol entirely. +.KS +.NH 2 +\&The RPC Language Specification +.LP +The RPC language is identical to the XDR language, except for the +added definition of a +.I program-def +described below. +.DS +.ft CW +program-def: + "program" identifier "{" + version-def + version-def * + "}" "=" constant ";" + +version-def: + "version" identifier "{" + procedure-def + procedure-def * + "}" "=" constant ";" + +procedure-def: + type-specifier identifier "(" type-specifier ")" + "=" constant ";" +.DE +.KE +.NH 2 +\&Syntax Notes +.IP 1. +The following keywords are added and cannot be used as +identifiers: "program" and "version"; +.IP 2. +A version name cannot occur more than once within the scope of +a program definition. Nor can a version number occur more than once +within the scope of a program definition. +.IP 3. +A procedure name cannot occur more than once within the scope +of a version definition. Nor can a procedure number occur more than +once within the scope of version definition. +.IP 4. +Program identifiers are in the same name space as constant and +type identifiers. +.IP 5. +Only unsigned constants can be assigned to programs, versions +and procedures. +.NH 1 +\&Port Mapper Program Protocol +.LP +The port mapper program maps RPC program and version numbers to +transport-specific port numbers. This program makes dynamic binding +of remote programs possible. +.LP +This is desirable because the range of reserved port numbers is very +small and the number of potential remote programs is very large. By +running only the port mapper on a reserved port, the port numbers of +other remote programs can be ascertained by querying the port mapper. +.LP +The port mapper also aids in broadcast RPC. A given RPC program will +usually have different port number bindings on different machines, so +there is no way to directly broadcast to all of these programs. The +port mapper, however, does have a fixed port number. So, to +broadcast to a given program, the client actually sends its message +to the port mapper located at the broadcast address. Each port +mapper that picks up the broadcast then calls the local service +specified by the client. When the port mapper gets the reply from +the local service, it sends the reply on back to the client. +.KS +.NH 2 +\&Port Mapper Protocol Specification (in RPC Language) +.ie t .DS +.el .DS L +.ft CW +.vs 11 +const PMAP_PORT = 111; /* \fIportmapper port number \fP*/ + +.ft I +/* +* A mapping of (program, version, protocol) to port number +*/ +.ft CW +struct mapping { + unsigned int prog; + unsigned int vers; + unsigned int prot; + unsigned int port; +}; + +.ft I +/* +* Supported values for the "prot" field +*/ +.ft CW +const IPPROTO_TCP = 6; /* \fIprotocol number for TCP/IP \fP*/ +const IPPROTO_UDP = 17; /* \fIprotocol number for UDP/IP \fP*/ + +.ft I +/* +* A list of mappings +*/ +.ft CW +struct *pmaplist { + mapping map; + pmaplist next; +}; +.vs +.DE +.ie t .DS +.el .DS L +.vs 11 +.ft I +/* +* Arguments to callit +*/ +.ft CW +struct call_args { + unsigned int prog; + unsigned int vers; + unsigned int proc; + opaque args<>; +}; + +.ft I +/* +* Results of callit +*/ +.ft CW +struct call_result { + unsigned int port; + opaque res<>; +}; +.vs +.DE +.KE +.ie t .DS +.el .DS L +.vs 11 +.ft I +/* +* Port mapper procedures +*/ +.ft CW +program PMAP_PROG { + version PMAP_VERS { + void + PMAPPROC_NULL(void) = 0; + + bool + PMAPPROC_SET(mapping) = 1; + + bool + PMAPPROC_UNSET(mapping) = 2; + + unsigned int + PMAPPROC_GETPORT(mapping) = 3; + + pmaplist + PMAPPROC_DUMP(void) = 4; + + call_result + PMAPPROC_CALLIT(call_args) = 5; + } = 2; +} = 100000; +.vs +.DE +.NH 2 +\&Port Mapper Operation +.LP +The portmapper program currently supports two protocols (UDP/IP and +TCP/IP). The portmapper is contacted by talking to it on assigned +port number 111 (SUNRPC [8]) on either of these protocols. The +following is a description of each of the portmapper procedures: +.IP \fBPMAPPROC_NULL:\fP +This procedure does no work. By convention, procedure zero of any +protocol takes no parameters and returns no results. +.IP \fBPMAPPROC_SET:\fP +When a program first becomes available on a machine, it registers +itself with the port mapper program on the same machine. The program +passes its program number "prog", version number "vers", transport +protocol number "prot", and the port "port" on which it awaits +service request. The procedure returns a boolean response whose +value is +.I TRUE +if the procedure successfully established the mapping and +.I FALSE +otherwise. The procedure refuses to establish +a mapping if one already exists for the tuple "(prog, vers, prot)". +.IP \fBPMAPPROC_UNSET:\fP +When a program becomes unavailable, it should unregister itself with +the port mapper program on the same machine. The parameters and +results have meanings identical to those of +.I PMAPPROC_SET . +The protocol and port number fields of the argument are ignored. +.IP \fBPMAPPROC_GETPORT:\fP +Given a program number "prog", version number "vers", and transport +protocol number "prot", this procedure returns the port number on +which the program is awaiting call requests. A port value of zeros +means the program has not been registered. The "port" field of the +argument is ignored. +.IP \fBPMAPPROC_DUMP:\fP +This procedure enumerates all entries in the port mapper's database. +The procedure takes no parameters and returns a list of program, +version, protocol, and port values. +.IP \fBPMAPPROC_CALLIT:\fP +This procedure allows a caller to call another remote procedure on +the same machine without knowing the remote procedure's port number. +It is intended for supporting broadcasts to arbitrary remote programs +via the well-known port mapper's port. The parameters "prog", +"vers", "proc", and the bytes of "args" are the program number, +version number, procedure number, and parameters of the remote +procedure. +.LP +.B Note: +.RS +.IP 1. +This procedure only sends a response if the procedure was +successfully executed and is silent (no response) otherwise. +.IP 2. +The port mapper communicates with the remote program using UDP/IP +only. +.RE +.LP +The procedure returns the remote program's port number, and the bytes +of results are the results of the remote procedure. +.bp +.NH 1 +\&References +.LP +[1] Birrell, Andrew D. & Nelson, Bruce Jay; "Implementing Remote +Procedure Calls"; XEROX CSL-83-7, October 1983. +.LP +[2] Cheriton, D.; "VMTP: Versatile Message Transaction Protocol", +Preliminary Version 0.3; Stanford University, January 1987. +.LP +[3] Diffie & Hellman; "New Directions in Cryptography"; IEEE +Transactions on Information Theory IT-22, November 1976. +.LP +[4] Harrenstien, K.; "Time Server", RFC 738; Information Sciences +Institute, October 1977. +.LP +[5] National Bureau of Standards; "Data Encryption Standard"; Federal +Information Processing Standards Publication 46, January 1977. +.LP +[6] Postel, J.; "Transmission Control Protocol - DARPA Internet +Program Protocol Specification", RFC 793; Information Sciences +Institute, September 1981. +.LP +[7] Postel, J.; "User Datagram Protocol", RFC 768; Information Sciences +Institute, August 1980. +.LP +[8] Reynolds, J. & Postel, J.; "Assigned Numbers", RFC 923; Information +Sciences Institute, October 1984. diff --git a/cpukit/librpc/src/rpc/PSD.doc/rpcgen.ms b/cpukit/librpc/src/rpc/PSD.doc/rpcgen.ms index e69de29bb2..b4e50e5d6f 100644 --- a/cpukit/librpc/src/rpc/PSD.doc/rpcgen.ms +++ b/cpukit/librpc/src/rpc/PSD.doc/rpcgen.ms @@ -0,0 +1,1299 @@ +.\" +.\" Must use -- tbl -- for this one +.\" +.\" @(#)rpcgen.ms 2.2 88/08/04 4.0 RPCSRC +.de BT +.if \\n%=1 .tl ''- % -'' +.. +.ND +.\" prevent excess underlining in nroff +.if n .fp 2 R +.OH '\fBrpcgen\fP Programming Guide''Page %' +.EH 'Page %''\fBrpcgen\fP Programming Guide' +.if \\n%=1 .bp +.SH +\&\fBrpcgen\fP Programming Guide +.NH 0 +\&The \fBrpcgen\fP Protocol Compiler +.IX rpcgen "" \fIrpcgen\fP "" PAGE MAJOR +.LP +.IX RPC "" "" \fIrpcgen\fP +The details of programming applications to use Remote Procedure Calls +can be overwhelming. Perhaps most daunting is the writing of the XDR +routines necessary to convert procedure arguments and results into +their network format and vice-versa. +.LP +Fortunately, +.I rpcgen(1) +exists to help programmers write RPC applications simply and directly. +.I rpcgen +does most of the dirty work, allowing programmers to debug +the main features of their application, instead of requiring them to +spend most of their time debugging their network interface code. +.LP +.I rpcgen +is a compiler. It accepts a remote program interface definition written +in a language, called RPC Language, which is similar to C. It produces a C +language output which includes stub versions of the client routines, a +server skeleton, XDR filter routines for both parameters and results, and a +header file that contains common definitions. The client stubs interface +with the RPC library and effectively hide the network from their callers. +The server stub similarly hides the network from the server procedures that +are to be invoked by remote clients. +.I rpcgen 's +output files can be compiled and linked in the usual way. The developer +writes server procedures\(emin any language that observes Sun calling +conventions\(emand links them with the server skeleton produced by +.I rpcgen +to get an executable server program. To use a remote program, a programmer +writes an ordinary main program that makes local procedure calls to the +client stubs produced by +.I rpcgen . +Linking this program with +.I rpcgen 's +stubs creates an executable program. (At present the main program must be +written in C). +.I rpcgen +options can be used to suppress stub generation and to specify the transport +to be used by the server stub. +.LP +Like all compilers, +.I rpcgen +reduces development time +that would otherwise be spent coding and debugging low-level routines. +All compilers, including +.I rpcgen , +do this at a small cost in efficiency +and flexibility. However, many compilers allow escape hatches for +programmers to mix low-level code with high-level code. +.I rpcgen +is no exception. In speed-critical applications, hand-written routines +can be linked with the +.I rpcgen +output without any difficulty. Also, one may proceed by using +.I rpcgen +output as a starting point, and then rewriting it as necessary. +(If you need a discussion of RPC programming without +.I rpcgen , +see the +.I "Remote Procedure Call Programming Guide)\. +.NH 1 +\&Converting Local Procedures into Remote Procedures +.IX rpcgen "local procedures" \fIrpcgen\fP +.IX rpcgen "remote procedures" \fIrpcgen\fP +.LP +Assume an application that runs on a single machine, one which we want +to convert to run over the network. Here we will demonstrate such a +conversion by way of a simple example\(ema program that prints a +message to the console: +.ie t .DS +.el .DS L +.ft I +/* + * printmsg.c: print a message on the console + */ +.ft CW +#include <stdio.h> + +main(argc, argv) + int argc; + char *argv[]; +{ + char *message; + + if (argc < 2) { + fprintf(stderr, "usage: %s <message>\en", argv[0]); + exit(1); + } + message = argv[1]; + + if (!printmessage(message)) { + fprintf(stderr, "%s: couldn't print your message\en", + argv[0]); + exit(1); + } + printf("Message Delivered!\en"); + exit(0); +} +.ft I +/* + * Print a message to the console. + * Return a boolean indicating whether the message was actually printed. + */ +.ft CW +printmessage(msg) + char *msg; +{ + FILE *f; + + f = fopen("/dev/console", "w"); + if (f == NULL) { + return (0); + } + fprintf(f, "%s\en", msg); + fclose(f); + return(1); +} +.DE +.LP +And then, of course: +.ie t .DS +.el .DS L +.ft CW +example% \fBcc printmsg.c -o printmsg\fP +example% \fBprintmsg "Hello, there."\fP +Message delivered! +example% +.DE +.LP +If +.I printmessage() +was turned into a remote procedure, +then it could be called from anywhere in the network. +Ideally, one would just like to stick a keyword like +.I remote +in front of a +procedure to turn it into a remote procedure. Unfortunately, +we have to live within the constraints of the C language, since +it existed long before RPC did. But even without language +support, it's not very difficult to make a procedure remote. +.LP +In general, it's necessary to figure out what the types are for +all procedure inputs and outputs. In this case, we have a +procedure +.I printmessage() +which takes a string as input, and returns an integer +as output. Knowing this, we can write a protocol specification in RPC +language that describes the remote version of +.I printmessage (). +Here it is: +.ie t .DS +.el .DS L +.ft I +/* + * msg.x: Remote message printing protocol + */ +.ft CW + +program MESSAGEPROG { + version MESSAGEVERS { + int PRINTMESSAGE(string) = 1; + } = 1; +} = 99; +.DE +.LP +Remote procedures are part of remote programs, so we actually declared +an entire remote program here which contains the single procedure +.I PRINTMESSAGE . +This procedure was declared to be in version 1 of the +remote program. No null procedure (procedure 0) is necessary because +.I rpcgen +generates it automatically. +.LP +Notice that everything is declared with all capital letters. This is +not required, but is a good convention to follow. +.LP +Notice also that the argument type is \*Qstring\*U and not \*Qchar *\*U. This +is because a \*Qchar *\*U in C is ambiguous. Programmers usually intend it +to mean a null-terminated string of characters, but it could also +represent a pointer to a single character or a pointer to an array of +characters. In RPC language, a null-terminated string is +unambiguously called a \*Qstring\*U. +.LP +There are just two more things to write. First, there is the remote +procedure itself. Here's the definition of a remote procedure +to implement the +.I PRINTMESSAGE +procedure we declared above: +.ie t .DS +.el .DS L +.vs 11 +.ft I +/* + * msg_proc.c: implementation of the remote procedure "printmessage" + */ +.ft CW + +#include <stdio.h> +#include <rpc/rpc.h> /* \fIalways needed\fP */ +#include "msg.h" /* \fIneed this too: msg.h will be generated by rpcgen\fP */ + +.ft I +/* + * Remote verson of "printmessage" + */ +.ft CW +int * +printmessage_1(msg) + char **msg; +{ + static int result; /* \fImust be static!\fP */ + FILE *f; + + f = fopen("/dev/console", "w"); + if (f == NULL) { + result = 0; + return (&result); + } + fprintf(f, "%s\en", *msg); + fclose(f); + result = 1; + return (&result); +} +.vs +.DE +.LP +Notice here that the declaration of the remote procedure +.I printmessage_1() +differs from that of the local procedure +.I printmessage() +in three ways: +.IP 1. +It takes a pointer to a string instead of a string itself. This +is true of all remote procedures: they always take pointers to their +arguments rather than the arguments themselves. +.IP 2. +It returns a pointer to an integer instead of an integer itself. This is +also generally true of remote procedures: they always return a pointer +to their results. +.IP 3. +It has an \*Q_1\*U appended to its name. In general, all remote +procedures called by +.I rpcgen +are named by the following rule: the name in the program definition +(here +.I PRINTMESSAGE ) +is converted to all +lower-case letters, an underbar (\*Q_\*U) is appended to it, and +finally the version number (here 1) is appended. +.LP +The last thing to do is declare the main client program that will call +the remote procedure. Here it is: +.ie t .DS +.el .DS L +.ft I +/* + * rprintmsg.c: remote version of "printmsg.c" + */ +.ft CW +#include <stdio.h> +#include <rpc/rpc.h> /* \fIalways needed\fP */ +#include "msg.h" /* \fIneed this too: msg.h will be generated by rpcgen\fP */ + +main(argc, argv) + int argc; + char *argv[]; +{ + CLIENT *cl; + int *result; + char *server; + char *message; + + if (argc < 3) { + fprintf(stderr, "usage: %s host message\en", argv[0]); + exit(1); + } + +.ft I + /* + * Save values of command line arguments + */ +.ft CW + server = argv[1]; + message = argv[2]; + +.ft I + /* + * Create client "handle" used for calling \fIMESSAGEPROG\fP on the + * server designated on the command line. We tell the RPC package + * to use the "tcp" protocol when contacting the server. + */ +.ft CW + cl = clnt_create(server, MESSAGEPROG, MESSAGEVERS, "tcp"); + if (cl == NULL) { +.ft I + /* + * Couldn't establish connection with server. + * Print error message and die. + */ +.ft CW + clnt_pcreateerror(server); + exit(1); + } + +.ft I + /* + * Call the remote procedure "printmessage" on the server + */ +.ft CW + result = printmessage_1(&message, cl); + if (result == NULL) { +.ft I + /* + * An error occurred while calling the server. + * Print error message and die. + */ +.ft CW + clnt_perror(cl, server); + exit(1); + } + +.ft I + /* + * Okay, we successfully called the remote procedure. + */ +.ft CW + if (*result == 0) { +.ft I + /* + * Server was unable to print our message. + * Print error message and die. + */ +.ft CW + fprintf(stderr, "%s: %s couldn't print your message\en", + argv[0], server); + exit(1); + } + +.ft I + /* + * The message got printed on the server's console + */ +.ft CW + printf("Message delivered to %s!\en", server); +} +.DE +There are two things to note here: +.IP 1. +.IX "client handle, used by rpcgen" "" "client handle, used by \fIrpcgen\fP" +First a client \*Qhandle\*U is created using the RPC library routine +.I clnt_create (). +This client handle will be passed to the stub routines +which call the remote procedure. +.IP 2. +The remote procedure +.I printmessage_1() +is called exactly the same way as it is declared in +.I msg_proc.c +except for the inserted client handle as the first argument. +.LP +Here's how to put all of the pieces together: +.ie t .DS +.el .DS L +.ft CW +example% \fBrpcgen msg.x\fP +example% \fBcc rprintmsg.c msg_clnt.c -o rprintmsg\fP +example% \fBcc msg_proc.c msg_svc.c -o msg_server\fP +.DE +Two programs were compiled here: the client program +.I rprintmsg +and the server program +.I msg_server . +Before doing this though, +.I rpcgen +was used to fill in the missing pieces. +.LP +Here is what +.I rpcgen +did with the input file +.I msg.x : +.IP 1. +It created a header file called +.I msg.h +that contained +.I #define 's +for +.I MESSAGEPROG , +.I MESSAGEVERS +and +.I PRINTMESSAGE +for use in the other modules. +.IP 2. +It created client \*Qstub\*U routines in the +.I msg_clnt.c +file. In this case there is only one, the +.I printmessage_1() +that was referred to from the +.I printmsg +client program. The name of the output file for +client stub routines is always formed in this way: if the name of the +input file is +.I FOO.x , +the client stubs output file is called +.I FOO_clnt.c . +.IP 3. +It created the server program which calls +.I printmessage_1() +in +.I msg_proc.c . +This server program is named +.I msg_svc.c . +The rule for naming the server output file is similar to the +previous one: for an input file called +.I FOO.x , +the output server file is named +.I FOO_svc.c . +.LP +Now we're ready to have some fun. First, copy the server to a +remote machine and run it. For this example, the +machine is called \*Qmoon\*U. Server processes are run in the +background, because they never exit. +.ie t .DS +.el .DS L +.ft CW +moon% \fBmsg_server &\fP +.DE +Then on our local machine (\*Qsun\*U) we can print a message on \*Qmoon\*Us +console. +.ie t .DS +.el .DS L +.ft CW +sun% \fBprintmsg moon "Hello, moon."\fP +.DE +The message will get printed to \*Qmoon\*Us console. You can print a +message on anybody's console (including your own) with this program if +you are able to copy the server to their machine and run it. +.NH 1 +\&Generating XDR Routines +.IX RPC "generating XDR routines" +.LP +The previous example only demonstrated the automatic generation of +client and server RPC code. +.I rpcgen +may also be used to generate XDR routines, that is, the routines +necessary to convert local data +structures into network format and vice-versa. This example presents +a complete RPC service\(ema remote directory listing service, which uses +.I rpcgen +not only to generate stub routines, but also to generate the XDR +routines. Here is the protocol description file: +.ie t .DS +.el .DS L +.ft I +/* + * dir.x: Remote directory listing protocol + */ +.ft CW +const MAXNAMELEN = 255; /* \fImaximum length of a directory entry\fP */ + +typedef string nametype<MAXNAMELEN>; /* \fIa directory entry\fP */ + +typedef struct namenode *namelist; /* \fIa link in the listing\fP */ + +.ft I +/* + * A node in the directory listing + */ +.ft CW +struct namenode { + nametype name; /* \fIname of directory entry\fP */ + namelist next; /* \fInext entry\fP */ +}; + +.ft I +/* + * The result of a READDIR operation. + */ +.ft CW +union readdir_res switch (int errno) { +case 0: + namelist list; /* \fIno error: return directory listing\fP */ +default: + void; /* \fIerror occurred: nothing else to return\fP */ +}; + +.ft I +/* + * The directory program definition + */ +.ft CW +program DIRPROG { + version DIRVERS { + readdir_res + READDIR(nametype) = 1; + } = 1; +} = 76; +.DE +.SH +Note: +.I +Types (like +.I readdir_res +in the example above) can be defined using +the \*Qstruct\*U, \*Qunion\*U and \*Qenum\*U keywords, but those keywords +should not be used in subsequent declarations of variables of those types. +For example, if you define a union \*Qfoo\*U, you should declare using +only \*Qfoo\*U and not \*Qunion foo\*U. In fact, +.I rpcgen +compiles +RPC unions into C structures and it is an error to declare them using the +\*Qunion\*U keyword. +.LP +Running +.I rpcgen +on +.I dir.x +creates four output files. Three are the same as before: header file, +client stub routines and server skeleton. The fourth are the XDR routines +necessary for converting the data types we declared into XDR format and +vice-versa. These are output in the file +.I dir_xdr.c . +.LP +Here is the implementation of the +.I READDIR +procedure. +.ie t .DS +.el .DS L +.vs 11 +.ft I +/* + * dir_proc.c: remote readdir implementation + */ +.ft CW +#include <rpc/rpc.h> +#include <sys/dir.h> +#include "dir.h" + +extern int errno; +extern char *malloc(); +extern char *strdup(); + +readdir_res * +readdir_1(dirname) + nametype *dirname; +{ + DIR *dirp; + struct direct *d; + namelist nl; + namelist *nlp; + static readdir_res res; /* \fImust be static\fP! */ + +.ft I + /* + * Open directory + */ +.ft CW + dirp = opendir(*dirname); + if (dirp == NULL) { + res.errno = errno; + return (&res); + } + +.ft I + /* + * Free previous result + */ +.ft CW + xdr_free(xdr_readdir_res, &res); + +.ft I + /* + * Collect directory entries. + * Memory allocated here will be freed by \fIxdr_free\fP + * next time \fIreaddir_1\fP is called + */ +.ft CW + nlp = &res.readdir_res_u.list; + while (d = readdir(dirp)) { + nl = *nlp = (namenode *) malloc(sizeof(namenode)); + nl->name = strdup(d->d_name); + nlp = &nl->next; + } + *nlp = NULL; + +.ft I + /* + * Return the result + */ +.ft CW + res.errno = 0; + closedir(dirp); + return (&res); +} +.vs +.DE +Finally, there is the client side program to call the server: +.ie t .DS +.el .DS L +.ft I +/* + * rls.c: Remote directory listing client + */ +.ft CW +#include <stdio.h> +#include <rpc/rpc.h> /* \fIalways need this\fP */ +#include "dir.h" /* \fIwill be generated by rpcgen\fI */ + +extern int errno; + +main(argc, argv) + int argc; + char *argv[]; +{ + CLIENT *cl; + char *server; + char *dir; + readdir_res *result; + namelist nl; + + + if (argc != 3) { + fprintf(stderr, "usage: %s host directory\en", + argv[0]); + exit(1); + } + +.ft I + /* + * Remember what our command line arguments refer to + */ +.ft CW + server = argv[1]; + dir = argv[2]; + +.ft I + /* + * Create client "handle" used for calling \fIMESSAGEPROG\fP on the + * server designated on the command line. We tell the RPC package + * to use the "tcp" protocol when contacting the server. + */ +.ft CW + cl = clnt_create(server, DIRPROG, DIRVERS, "tcp"); + if (cl == NULL) { +.ft I + /* + * Couldn't establish connection with server. + * Print error message and die. + */ +.ft CW + clnt_pcreateerror(server); + exit(1); + } + +.ft I + /* + * Call the remote procedure \fIreaddir\fP on the server + */ +.ft CW + result = readdir_1(&dir, cl); + if (result == NULL) { +.ft I + /* + * An error occurred while calling the server. + * Print error message and die. + */ +.ft CW + clnt_perror(cl, server); + exit(1); + } + +.ft I + /* + * Okay, we successfully called the remote procedure. + */ +.ft CW + if (result->errno != 0) { +.ft I + /* + * A remote system error occurred. + * Print error message and die. + */ +.ft CW + errno = result->errno; + perror(dir); + exit(1); + } + +.ft I + /* + * Successfully got a directory listing. + * Print it out. + */ +.ft CW + for (nl = result->readdir_res_u.list; nl != NULL; + nl = nl->next) { + printf("%s\en", nl->name); + } + exit(0); +} +.DE +Compile everything, and run. +.DS +.ft CW +sun% \fBrpcgen dir.x\fP +sun% \fBcc rls.c dir_clnt.c dir_xdr.c -o rls\fP +sun% \fBcc dir_svc.c dir_proc.c dir_xdr.c -o dir_svc\fP + +sun% \fBdir_svc &\fP + +moon% \fBrls sun /usr/pub\fP +\&. +\&.. +ascii +eqnchar +greek +kbd +marg8 +tabclr +tabs +tabs4 +moon% +.DE +.LP +.IX "debugging with rpcgen" "" "debugging with \fIrpcgen\fP" +A final note about +.I rpcgen : +The client program and the server procedure can be tested together +as a single program by simply linking them with each other rather +than with the client and server stubs. The procedure calls will be +executed as ordinary local procedure calls and the program can be +debugged with a local debugger such as +.I dbx . +When the program is working, the client program can be linked to +the client stub produced by +.I rpcgen +and the server procedures can be linked to the server stub produced +by +.I rpcgen . +.SH +.I NOTE : +\fIIf you do this, you may want to comment out calls to RPC library +routines, and have client-side routines call server routines +directly.\fP +.LP +.NH 1 +\&The C-Preprocessor +.IX rpcgen "C-preprocessor" \fIrpcgen\fP +.LP +The C-preprocessor is run on all input files before they are +compiled, so all the preprocessor directives are legal within a \*Q.x\*U +file. Four symbols may be defined, depending upon which output file is +getting generated. The symbols are: +.TS +box tab (&); +lfI lfI +lfL l . +Symbol&Usage +_ +RPC_HDR&for header-file output +RPC_XDR&for XDR routine output +RPC_SVC&for server-skeleton output +RPC_CLNT&for client stub output +.TE +.LP +Also, +.I rpcgen +does a little preprocessing of its own. Any line that +begins with a percent sign is passed directly into the output file, +without any interpretation of the line. Here is a simple example that +demonstrates the preprocessing features. +.ie t .DS +.el .DS L +.ft I +/* + * time.x: Remote time protocol + */ +.ft CW +program TIMEPROG { + version TIMEVERS { + unsigned int TIMEGET(void) = 1; + } = 1; +} = 44; + +#ifdef RPC_SVC +%int * +%timeget_1() +%{ +% static int thetime; +% +% thetime = time(0); +% return (&thetime); +%} +#endif +.DE +The '%' feature is not generally recommended, as there is no guarantee +that the compiler will stick the output where you intended. +.NH 1 +\&\fBrpcgen\fP Programming Notes +.IX rpcgen "other operations" \fIrpcgen\fP +.sp +.NH 2 +\&Timeout Changes +.IX rpcgen "timeout changes" \fIrpcgen\fP +.LP +RPC sets a default timeout of 25 seconds for RPC calls when +.I clnt_create() +is used. This timeout may be changed using +.I clnt_control() +Here is a small code fragment to demonstrate use of +.I clnt_control (): +.ID +struct timeval tv; +CLIENT *cl; +.sp .5 +cl = clnt_create("somehost", SOMEPROG, SOMEVERS, "tcp"); +if (cl == NULL) { + exit(1); +} +tv.tv_sec = 60; /* \fIchange timeout to 1 minute\fP */ +tv.tv_usec = 0; +clnt_control(cl, CLSET_TIMEOUT, &tv); +.DE +.NH 2 +\&Handling Broadcast on the Server Side +.IX "broadcast RPC" +.IX rpcgen "broadcast RPC" \fIrpcgen\fP +.LP +When a procedure is known to be called via broadcast RPC, +it is usually wise for the server to not reply unless it can provide +some useful information to the client. This prevents the network +from getting flooded by useless replies. +.LP +To prevent the server from replying, a remote procedure can +return NULL as its result, and the server code generated by +.I rpcgen +will detect this and not send out a reply. +.LP +Here is an example of a procedure that replies only if it +thinks it is an NFS server: +.ID +void * +reply_if_nfsserver() +{ + char notnull; /* \fIjust here so we can use its address\fP */ +.sp .5 + if (access("/etc/exports", F_OK) < 0) { + return (NULL); /* \fIprevent RPC from replying\fP */ + } +.ft I + /* + * return non-null pointer so RPC will send out a reply + */ +.ft L + return ((void *)¬null); +} +.DE +Note that if procedure returns type \*Qvoid *\*U, they must return a non-NULL +pointer if they want RPC to reply for them. +.NH 2 +\&Other Information Passed to Server Procedures +.LP +Server procedures will often want to know more about an RPC call +than just its arguments. For example, getting authentication information +is important to procedures that want to implement some level of security. +This extra information is actually supplied to the server procedure as a +second argument. Here is an example to demonstrate its use. What we've +done here is rewrite the previous +.I printmessage_1() +procedure to only allow root users to print a message to the console. +.ID +int * +printmessage_1(msg, rq) + char **msg; + struct svc_req *rq; +{ + static in result; /* \fIMust be static\fP */ + FILE *f; + struct suthunix_parms *aup; +.sp .5 + aup = (struct authunix_parms *)rq->rq_clntcred; + if (aup->aup_uid != 0) { + result = 0; + return (&result); + } +.sp +.ft I + /* + * Same code as before. + */ +.ft L +} +.DE +.NH 1 +\&RPC Language +.IX RPCL +.IX rpcgen "RPC Language" \fIrpcgen\fP +.LP +RPC language is an extension of XDR language. The sole extension is +the addition of the +.I program +type. For a complete description of the XDR language syntax, see the +.I "External Data Representation Standard: Protocol Specification" +chapter. For a description of the RPC extensions to the XDR language, +see the +.I "Remote Procedure Calls: Protocol Specification" +chapter. +.LP +However, XDR language is so close to C that if you know C, you know most +of it already. We describe here the syntax of the RPC language, +showing a few examples along the way. We also show how the various +RPC and XDR type definitions get compiled into C type definitions in +the output header file. +.KS +.NH 2 +Definitions +\& +.IX rpcgen definitions \fIrpcgen\fP +.LP +An RPC language file consists of a series of definitions. +.DS L +.ft CW + definition-list: + definition ";" + definition ";" definition-list +.DE +.KE +It recognizes five types of definitions. +.DS L +.ft CW + definition: + enum-definition + struct-definition + union-definition + typedef-definition + const-definition + program-definition +.DE +.NH 2 +Structures +\& +.IX rpcgen structures \fIrpcgen\fP +.LP +An XDR struct is declared almost exactly like its C counterpart. It +looks like the following: +.DS L +.ft CW + struct-definition: + "struct" struct-ident "{" + declaration-list + "}" + + declaration-list: + declaration ";" + declaration ";" declaration-list +.DE +As an example, here is an XDR structure to a two-dimensional +coordinate, and the C structure that it gets compiled into in the +output header file. +.DS +.ft CW + struct coord { struct coord { + int x; --> int x; + int y; int y; + }; }; + typedef struct coord coord; +.DE +The output is identical to the input, except for the added +.I typedef +at the end of the output. This allows one to use \*Qcoord\*U instead of +\*Qstruct coord\*U when declaring items. +.NH 2 +Unions +\& +.IX rpcgen unions \fIrpcgen\fP +.LP +XDR unions are discriminated unions, and look quite different from C +unions. They are more analogous to Pascal variant records than they +are to C unions. +.DS L +.ft CW + union-definition: + "union" union-ident "switch" "(" declaration ")" "{" + case-list + "}" + + case-list: + "case" value ":" declaration ";" + "default" ":" declaration ";" + "case" value ":" declaration ";" case-list +.DE +Here is an example of a type that might be returned as the result of a +\*Qread data\*U operation. If there is no error, return a block of data. +Otherwise, don't return anything. +.DS L +.ft CW + union read_result switch (int errno) { + case 0: + opaque data[1024]; + default: + void; + }; +.DE +It gets compiled into the following: +.DS L +.ft CW + struct read_result { + int errno; + union { + char data[1024]; + } read_result_u; + }; + typedef struct read_result read_result; +.DE +Notice that the union component of the output struct has the name as +the type name, except for the trailing \*Q_u\*U. +.NH 2 +Enumerations +\& +.IX rpcgen enumerations \fIrpcgen\fP +.LP +XDR enumerations have the same syntax as C enumerations. +.DS L +.ft CW + enum-definition: + "enum" enum-ident "{" + enum-value-list + "}" + + enum-value-list: + enum-value + enum-value "," enum-value-list + + enum-value: + enum-value-ident + enum-value-ident "=" value +.DE +Here is a short example of an XDR enum, and the C enum that it gets +compiled into. +.DS L +.ft CW + enum colortype { enum colortype { + RED = 0, RED = 0, + GREEN = 1, --> GREEN = 1, + BLUE = 2 BLUE = 2, + }; }; + typedef enum colortype colortype; +.DE +.NH 2 +Typedef +\& +.IX rpcgen typedef \fIrpcgen\fP +.LP +XDR typedefs have the same syntax as C typedefs. +.DS L +.ft CW + typedef-definition: + "typedef" declaration +.DE +Here is an example that defines a +.I fname_type +used for declaring +file name strings that have a maximum length of 255 characters. +.DS L +.ft CW +typedef string fname_type<255>; --> typedef char *fname_type; +.DE +.NH 2 +Constants +\& +.IX rpcgen constants \fIrpcgen\fP +.LP +XDR constants symbolic constants that may be used wherever a +integer constant is used, for example, in array size specifications. +.DS L +.ft CW + const-definition: + "const" const-ident "=" integer +.DE +For example, the following defines a constant +.I DOZEN +equal to 12. +.DS L +.ft CW + const DOZEN = 12; --> #define DOZEN 12 +.DE +.NH 2 +Programs +\& +.IX rpcgen programs \fIrpcgen\fP +.LP +RPC programs are declared using the following syntax: +.DS L +.ft CW + program-definition: + "program" program-ident "{" + version-list + "}" "=" value + + version-list: + version ";" + version ";" version-list + + version: + "version" version-ident "{" + procedure-list + "}" "=" value + + procedure-list: + procedure ";" + procedure ";" procedure-list + + procedure: + type-ident procedure-ident "(" type-ident ")" "=" value +.DE +For example, here is the time protocol, revisited: +.ie t .DS +.el .DS L +.ft I +/* + * time.x: Get or set the time. Time is represented as number of seconds + * since 0:00, January 1, 1970. + */ +.ft CW +program TIMEPROG { + version TIMEVERS { + unsigned int TIMEGET(void) = 1; + void TIMESET(unsigned) = 2; + } = 1; +} = 44; +.DE +This file compiles into #defines in the output header file: +.ie t .DS +.el .DS L +.ft CW +#define TIMEPROG 44 +#define TIMEVERS 1 +#define TIMEGET 1 +#define TIMESET 2 +.DE +.NH 2 +Declarations +\& +.IX rpcgen declarations \fIrpcgen\fP +.LP +In XDR, there are only four kinds of declarations. +.DS L +.ft CW + declaration: + simple-declaration + fixed-array-declaration + variable-array-declaration + pointer-declaration +.DE +\fB1) Simple declarations\fP are just like simple C declarations. +.DS L +.ft CW + simple-declaration: + type-ident variable-ident +.DE +Example: +.DS L +.ft CW + colortype color; --> colortype color; +.DE +\fB2) Fixed-length Array Declarations\fP are just like C array declarations: +.DS L +.ft CW + fixed-array-declaration: + type-ident variable-ident "[" value "]" +.DE +Example: +.DS L +.ft CW + colortype palette[8]; --> colortype palette[8]; +.DE +\fB3) Variable-Length Array Declarations\fP have no explicit syntax +in C, so XDR invents its own using angle-brackets. +.DS L +.ft CW +variable-array-declaration: + type-ident variable-ident "<" value ">" + type-ident variable-ident "<" ">" +.DE +The maximum size is specified between the angle brackets. The size may +be omitted, indicating that the array may be of any size. +.DS L +.ft CW + int heights<12>; /* \fIat most 12 items\fP */ + int widths<>; /* \fIany number of items\fP */ +.DE +Since variable-length arrays have no explicit syntax in C, these +declarations are actually compiled into \*Qstruct\*Us. For example, the +\*Qheights\*U declaration gets compiled into the following struct: +.DS L +.ft CW + struct { + u_int heights_len; /* \fI# of items in array\fP */ + int *heights_val; /* \fIpointer to array\fP */ + } heights; +.DE +Note that the number of items in the array is stored in the \*Q_len\*U +component and the pointer to the array is stored in the \*Q_val\*U +component. The first part of each of these component's names is the +same as the name of the declared XDR variable. +.LP +\fB4) Pointer Declarations\fP are made in +XDR exactly as they are in C. You can't +really send pointers over the network, but you can use XDR pointers +for sending recursive data types such as lists and trees. The type is +actually called \*Qoptional-data\*U, not \*Qpointer\*U, in XDR language. +.DS L +.ft CW + pointer-declaration: + type-ident "*" variable-ident +.DE +Example: +.DS L +.ft CW + listitem *next; --> listitem *next; +.DE +.NH 2 +\&Special Cases +.IX rpcgen "special cases" \fIrpcgen\fP +.LP +There are a few exceptions to the rules described above. +.LP +.B Booleans: +C has no built-in boolean type. However, the RPC library does a +boolean type called +.I bool_t +that is either +.I TRUE +or +.I FALSE . +Things declared as type +.I bool +in XDR language are compiled into +.I bool_t +in the output header file. +.LP +Example: +.DS L +.ft CW + bool married; --> bool_t married; +.DE +.B Strings: +C has no built-in string type, but instead uses the null-terminated +\*Qchar *\*U convention. In XDR language, strings are declared using the +\*Qstring\*U keyword, and compiled into \*Qchar *\*Us in the output header +file. The maximum size contained in the angle brackets specifies the +maximum number of characters allowed in the strings (not counting the +.I NULL +character). The maximum size may be left off, indicating a string +of arbitrary length. +.LP +Examples: +.DS L +.ft CW + string name<32>; --> char *name; + string longname<>; --> char *longname; +.DE +.B "Opaque Data:" +Opaque data is used in RPC and XDR to describe untyped data, that is, +just sequences of arbitrary bytes. It may be declared either as a +fixed or variable length array. +.DS L +Examples: +.ft CW + opaque diskblock[512]; --> char diskblock[512]; + + opaque filedata<1024>; --> struct { + u_int filedata_len; + char *filedata_val; + } filedata; +.DE +.B Voids: +In a void declaration, the variable is not named. The declaration is +just \*Qvoid\*U and nothing else. Void declarations can only occur in two +places: union definitions and program definitions (as the argument or +result of a remote procedure). diff --git a/cpukit/librpc/src/rpc/PSD.doc/xdr.nts.ms b/cpukit/librpc/src/rpc/PSD.doc/xdr.nts.ms index e69de29bb2..6c2d482dea 100644 --- a/cpukit/librpc/src/rpc/PSD.doc/xdr.nts.ms +++ b/cpukit/librpc/src/rpc/PSD.doc/xdr.nts.ms @@ -0,0 +1,1966 @@ +.\" +.\" Must use -- eqn -- with this one +.\" +.\" @(#)xdr.nts.ms 2.2 88/08/05 4.0 RPCSRC +.EQ +delim $$ +.EN +.de BT +.if \\n%=1 .tl ''- % -'' +.. +.ND +.\" prevent excess underlining in nroff +.if n .fp 2 R +.OH 'External Data Representation: Sun Technical Notes''Page %' +.EH 'Page %''External Data Representation: Sun Technical Notes' +.if \\n%=1 .bp +.SH +\&External Data Representation: Sun Technical Notes +.IX XDR "Sun technical notes" +.LP +This chapter contains technical notes on Sun's implementation of the +External Data Representation (XDR) standard, a set of library routines +that allow a C programmer to describe arbitrary data structures in a +machinex-independent fashion. +For a formal specification of the XDR +standard, see the +.I "External Data Representation Standard: Protocol Specification". +XDR is the backbone of Sun's Remote Procedure Call package, in the +sense that data for remote procedure calls is transmitted using the +standard. XDR library routines should be used to transmit data +that is accessed (read or written) by more than one type of machine.\** +.FS +.IX XDR "system routines" +For a compete specification of the system External Data Representation +routines, see the +.I xdr(3N) +manual page. +.FE +.LP +This chapter contains a short tutorial overview of the XDR library +routines, a guide to accessing currently available XDR streams, and +information on defining new streams and data types. XDR was designed +to work across different languages, operating systems, and machine +architectures. Most users (particularly RPC users) will only need +the information in the +.I "Number Filters", +.I "Floating Point Filters", +and +.I "Enumeration Filters" +sections. +Programmers wishing to implement RPC and XDR on new machines +will be interested in the rest of the chapter, as well as the +.I "External Data Representaiton Standard: Protocol Specification", +which will be their primary reference. +.SH +Note: +.I +.I rpcgen +can be used to write XDR routines even in cases where no RPC calls are +being made. +.LP +On Sun systems, +C programs that want to use XDR routines +must include the file +.I <rpc/rpc.h> , +which contains all the necessary interfaces to the XDR system. +Since the C library +.I libc.a +contains all the XDR routines, +compile as normal. +.DS +example% \fBcc\0\fIprogram\fP.c\fI +.DE +.ne 3i +.NH 0 +\&Justification +.IX XDR justification +.LP +Consider the following two programs, +.I writer : +.ie t .DS +.el .DS L +.ft CW +#include <stdio.h> +.sp.5 +main() /* \fIwriter.c\fP */ +{ + long i; +.sp.5 + for (i = 0; i < 8; i++) { + if (fwrite((char *)&i, sizeof(i), 1, stdout) != 1) { + fprintf(stderr, "failed!\en"); + exit(1); + } + } + exit(0); +} +.DE +and +.I reader : +.ie t .DS +.el .DS L +.ft CW +#include <stdio.h> +.sp.5 +main() /* \fIreader.c\fP */ +{ + long i, j; +.sp.5 + for (j = 0; j < 8; j++) { + if (fread((char *)&i, sizeof (i), 1, stdin) != 1) { + fprintf(stderr, "failed!\en"); + exit(1); + } + printf("%ld ", i); + } + printf("\en"); + exit(0); +} +.DE +The two programs appear to be portable, because (a) they pass +.I lint +checking, and (b) they exhibit the same behavior when executed +on two different hardware architectures, a Sun and a VAX. +.LP +Piping the output of the +.I writer +program to the +.I reader +program gives identical results on a Sun or a VAX. +.DS +.ft CW +sun% \fBwriter | reader\fP +0 1 2 3 4 5 6 7 +sun% + + +vax% \fBwriter | reader\fP +0 1 2 3 4 5 6 7 +vax% +.DE +With the advent of local area networks and 4.2BSD came the concept +of \*Qnetwork pipes\*U \(em a process produces data on one machine, +and a second process consumes data on another machine. +A network pipe can be constructed with +.I writer +and +.I reader . +Here are the results if the first produces data on a Sun, +and the second consumes data on a VAX. +.DS +.ft CW +sun% \fBwriter | rsh vax reader\fP +0 16777216 33554432 50331648 67108864 83886080 100663296 +117440512 +sun% +.DE +Identical results can be obtained by executing +.I writer +on the VAX and +.I reader +on the Sun. These results occur because the byte ordering +of long integers differs between the VAX and the Sun, +even though word size is the same. +Note that $16777216$ is $2 sup 24$ \(em +when four bytes are reversed, the 1 winds up in the 24th bit. +.LP +Whenever data is shared by two or more machine types, there is +a need for portable data. Programs can be made data-portable by +replacing the +.I read() +and +.I write() +calls with calls to an XDR library routine +.I xdr_long() , +a filter that knows the standard representation +of a long integer in its external form. +Here are the revised versions of +.I writer : +.ie t .DS +.el .DS L +.ft CW +#include <stdio.h> +#include <rpc/rpc.h> /* \fIxdr is a sub-library of rpc\fP */ +.sp.5 +main() /* \fIwriter.c\fP */ +{ + XDR xdrs; + long i; +.sp.5 + xdrstdio_create(&xdrs, stdout, XDR_ENCODE); + for (i = 0; i < 8; i++) { + if (!xdr_long(&xdrs, &i)) { + fprintf(stderr, "failed!\en"); + exit(1); + } + } + exit(0); +} +.DE +and +.I reader : +.ie t .DS +.el .DS L +.ft CW +#include <stdio.h> +#include <rpc/rpc.h> /* \fIxdr is a sub-library of rpc\fP */ +.sp.5 +main() /* \fIreader.c\fP */ +{ + XDR xdrs; + long i, j; +.sp.5 + xdrstdio_create(&xdrs, stdin, XDR_DECODE); + for (j = 0; j < 8; j++) { + if (!xdr_long(&xdrs, &i)) { + fprintf(stderr, "failed!\en"); + exit(1); + } + printf("%ld ", i); + } + printf("\en"); + exit(0); +} +.DE +The new programs were executed on a Sun, +on a VAX, and from a Sun to a VAX; +the results are shown below. +.DS +.ft CW +sun% \fBwriter | reader\fP +0 1 2 3 4 5 6 7 +sun% + +vax% \fBwriter | reader\fP +0 1 2 3 4 5 6 7 +vax% + +sun% \fBwriter | rsh vax reader\fP +0 1 2 3 4 5 6 7 +sun% +.DE +.SH +Note: +.I +.IX XDR "portable data" +Integers are just the tip of the portable-data iceberg. Arbitrary +data structures present portability problems, particularly with +respect to alignment and pointers. Alignment on word boundaries +may cause the size of a structure to vary from machine to machine. +And pointers, which are very convenient to use, have no meaning +outside the machine where they are defined. +.LP +.NH 1 +\&A Canonical Standard +.IX XDR "canonical standard" +.LP +XDR's approach to standardizing data representations is +.I canonical . +That is, XDR defines a single byte order (Big Endian), a single +floating-point representation (IEEE), and so on. Any program running on +any machine can use XDR to create portable data by translating its +local representation to the XDR standard representations; similarly, any +program running on any machine can read portable data by translating the +XDR standard representaions to its local equivalents. The single standard +completely decouples programs that create or send portable data from those +that use or receive portable data. The advent of a new machine or a new +language has no effect upon the community of existing portable data creators +and users. A new machine joins this community by being \*Qtaught\*U how to +convert the standard representations and its local representations; the +local representations of other machines are irrelevant. Conversely, to +existing programs running on other machines, the local representations of +the new machine are also irrelevant; such programs can immediately read +portable data produced by the new machine because such data conforms to the +canonical standards that they already understand. +.LP +There are strong precedents for XDR's canonical approach. For example, +TCP/IP, UDP/IP, XNS, Ethernet, and, indeed, all protocols below layer five +of the ISO model, are canonical protocols. The advantage of any canonical +approach is simplicity; in the case of XDR, a single set of conversion +routines is written once and is never touched again. The canonical approach +has a disadvantage, but it is unimportant in real-world data transfer +applications. Suppose two Little-Endian machines are transferring integers +according to the XDR standard. The sending machine converts the integers +from Little-Endian byte order to XDR (Big-Endian) byte order; the receiving +machine performs the reverse conversion. Because both machines observe the +same byte order, their conversions are unnecessary. The point, however, is +not necessity, but cost as compared to the alternative. +.LP +The time spent converting to and from a canonical representation is +insignificant, especially in networking applications. Most of the time +required to prepare a data structure for transfer is not spent in conversion +but in traversing the elements of the data structure. To transmit a tree, +for example, each leaf must be visited and each element in a leaf record must +be copied to a buffer and aligned there; storage for the leaf may have to be +deallocated as well. Similarly, to receive a tree, storage must be +allocated for each leaf, data must be moved from the buffer to the leaf and +properly aligned, and pointers must be constructed to link the leaves +together. Every machine pays the cost of traversing and copying data +structures whether or not conversion is required. In networking +applications, communications overhead\(emthe time required to move the data +down through the sender's protocol layers, across the network and up through +the receiver's protocol layers\(emdwarfs conversion overhead. +.NH 1 +\&The XDR Library +.IX "XDR" "library" +.LP +The XDR library not only solves data portability problems, it also +allows you to write and read arbitrary C constructs in a consistent, +specified, well-documented manner. Thus, it can make sense to use the +library even when the data is not shared among machines on a network. +.LP +The XDR library has filter routines for +strings (null-terminated arrays of bytes), +structures, unions, and arrays, to name a few. +Using more primitive routines, +you can write your own specific XDR routines +to describe arbitrary data structures, +including elements of arrays, arms of unions, +or objects pointed at from other structures. +The structures themselves may contain arrays of arbitrary elements, +or pointers to other structures. +.LP +Let's examine the two programs more closely. +There is a family of XDR stream creation routines +in which each member treats the stream of bits differently. +In our example, data is manipulated using standard I/O routines, +so we use +.I xdrstdio_create (). +.IX xdrstdio_create() "" "\fIxdrstdio_create()\fP" +The parameters to XDR stream creation routines +vary according to their function. +In our example, +.I xdrstdio_create() +takes a pointer to an XDR structure that it initializes, +a pointer to a +.I FILE +that the input or output is performed on, and the operation. +The operation may be +.I XDR_ENCODE +for serializing in the +.I writer +program, or +.I XDR_DECODE +for deserializing in the +.I reader +program. +.LP +Note: RPC users never need to create XDR streams; +the RPC system itself creates these streams, +which are then passed to the users. +.LP +The +.I xdr_long() +.IX xdr_long() "" "\fIxdr_long()\fP" +primitive is characteristic of most XDR library +primitives and all client XDR routines. +First, the routine returns +.I FALSE +(0) if it fails, and +.I TRUE +(1) if it succeeds. +Second, for each data type, +.I xxx , +there is an associated XDR routine of the form: +.DS +.ft CW +xdr_xxx(xdrs, xp) + XDR *xdrs; + xxx *xp; +{ +} +.DE +In our case, +.I xxx +is long, and the corresponding XDR routine is +a primitive, +.I xdr_long() . +The client could also define an arbitrary structure +.I xxx +in which case the client would also supply the routine +.I xdr_xxx (), +describing each field by calling XDR routines +of the appropriate type. +In all cases the first parameter, +.I xdrs +can be treated as an opaque handle, +and passed to the primitive routines. +.LP +XDR routines are direction independent; +that is, the same routines are called to serialize or deserialize data. +This feature is critical to software engineering of portable data. +The idea is to call the same routine for either operation \(em +this almost guarantees that serialized data can also be deserialized. +One routine is used by both producer and consumer of networked data. +This is implemented by always passing the address +of an object rather than the object itself \(em +only in the case of deserialization is the object modified. +This feature is not shown in our trivial example, +but its value becomes obvious when nontrivial data structures +are passed among machines. +If needed, the user can obtain the +direction of the XDR operation. +See the +.I "XDR Operation Directions" +section below for details. +.LP +Let's look at a slightly more complicated example. +Assume that a person's gross assets and liabilities +are to be exchanged among processes. +Also assume that these values are important enough +to warrant their own data type: +.ie t .DS +.el .DS L +.ft CW +struct gnumbers { + long g_assets; + long g_liabilities; +}; +.DE +The corresponding XDR routine describing this structure would be: +.ie t .DS +.el .DS L +.ft CW +bool_t /* \fITRUE is success, FALSE is failure\fP */ +xdr_gnumbers(xdrs, gp) + XDR *xdrs; + struct gnumbers *gp; +{ + if (xdr_long(xdrs, &gp->g_assets) && + xdr_long(xdrs, &gp->g_liabilities)) + return(TRUE); + return(FALSE); +} +.DE +Note that the parameter +.I xdrs +is never inspected or modified; +it is only passed on to the subcomponent routines. +It is imperative to inspect the return value of each XDR routine call, +and to give up immediately and return +.I FALSE +if the subroutine fails. +.LP +This example also shows that the type +.I bool_t +is declared as an integer whose only values are +.I TRUE +(1) and +.I FALSE +(0). This document uses the following definitions: +.ie t .DS +.el .DS L +.ft CW +#define bool_t int +#define TRUE 1 +#define FALSE 0 +.DE +.LP +Keeping these conventions in mind, +.I xdr_gnumbers() +can be rewritten as follows: +.ie t .DS +.el .DS L +.ft CW +xdr_gnumbers(xdrs, gp) + XDR *xdrs; + struct gnumbers *gp; +{ + return(xdr_long(xdrs, &gp->g_assets) && + xdr_long(xdrs, &gp->g_liabilities)); +} +.DE +This document uses both coding styles. +.NH 1 +\&XDR Library Primitives +.IX "library primitives for XDR" +.IX XDR "library primitives" +.LP +This section gives a synopsis of each XDR primitive. +It starts with basic data types and moves on to constructed data types. +Finally, XDR utilities are discussed. +The interface to these primitives +and utilities is defined in the include file +.I <rpc/xdr.h> , +automatically included by +.I <rpc/rpc.h> . +.NH 2 +\&Number Filters +.IX "XDR library" "number filters" +.LP +The XDR library provides primitives to translate between numbers +and their corresponding external representations. +Primitives cover the set of numbers in: +.DS +.ft CW +[signed, unsigned] * [short, int, long] +.DE +.ne 2i +Specifically, the eight primitives are: +.DS +.ft CW +bool_t xdr_char(xdrs, cp) + XDR *xdrs; + char *cp; +.sp.5 +bool_t xdr_u_char(xdrs, ucp) + XDR *xdrs; + unsigned char *ucp; +.sp.5 +bool_t xdr_int(xdrs, ip) + XDR *xdrs; + int *ip; +.sp.5 +bool_t xdr_u_int(xdrs, up) + XDR *xdrs; + unsigned *up; +.sp.5 +bool_t xdr_long(xdrs, lip) + XDR *xdrs; + long *lip; +.sp.5 +bool_t xdr_u_long(xdrs, lup) + XDR *xdrs; + u_long *lup; +.sp.5 +bool_t xdr_short(xdrs, sip) + XDR *xdrs; + short *sip; +.sp.5 +bool_t xdr_u_short(xdrs, sup) + XDR *xdrs; + u_short *sup; +.DE +The first parameter, +.I xdrs , +is an XDR stream handle. +The second parameter is the address of the number +that provides data to the stream or receives data from it. +All routines return +.I TRUE +if they complete successfully, and +.I FALSE +otherwise. +.NH 2 +\&Floating Point Filters +.IX "XDR library" "floating point filters" +.LP +The XDR library also provides primitive routines +for C's floating point types: +.DS +.ft CW +bool_t xdr_float(xdrs, fp) + XDR *xdrs; + float *fp; +.sp.5 +bool_t xdr_double(xdrs, dp) + XDR *xdrs; + double *dp; +.DE +The first parameter, +.I xdrs +is an XDR stream handle. +The second parameter is the address +of the floating point number that provides data to the stream +or receives data from it. +Both routines return +.I TRUE +if they complete successfully, and +.I FALSE +otherwise. +.LP +Note: Since the numbers are represented in IEEE floating point, +routines may fail when decoding a valid IEEE representation +into a machine-specific representation, or vice-versa. +.NH 2 +\&Enumeration Filters +.IX "XDR library" "enumeration filters" +.LP +The XDR library provides a primitive for generic enumerations. +The primitive assumes that a C +.I enum +has the same representation inside the machine as a C integer. +The boolean type is an important instance of the +.I enum . +The external representation of a boolean is always +.I TRUE +(1) or +.I FALSE +(0). +.DS +.ft CW +#define bool_t int +#define FALSE 0 +#define TRUE 1 +.sp.5 +#define enum_t int +.sp.5 +bool_t xdr_enum(xdrs, ep) + XDR *xdrs; + enum_t *ep; +.sp.5 +bool_t xdr_bool(xdrs, bp) + XDR *xdrs; + bool_t *bp; +.DE +The second parameters +.I ep +and +.I bp +are addresses of the associated type that provides data to, or +receives data from, the stream +.I xdrs . +.NH 2 +\&No Data +.IX "XDR library" "no data" +.LP +Occasionally, an XDR routine must be supplied to the RPC system, +even when no data is passed or required. +The library provides such a routine: +.DS +.ft CW +bool_t xdr_void(); /* \fIalways returns TRUE\fP */ +.DE +.NH 2 +\&Constructed Data Type Filters +.IX "XDR library" "constructed data type filters" +.LP +Constructed or compound data type primitives +require more parameters and perform more complicated functions +then the primitives discussed above. +This section includes primitives for +strings, arrays, unions, and pointers to structures. +.LP +Constructed data type primitives may use memory management. +In many cases, memory is allocated when deserializing data with +.I XDR_DECODE +Therefore, the XDR package must provide means to deallocate memory. +This is done by an XDR operation, +.I XDR_FREE +To review, the three XDR directional operations are +.I XDR_ENCODE , +.I XDR_DECODE +and +.I XDR_FREE . +.NH 3 +\&Strings +.IX "XDR library" "strings" +.LP +In C, a string is defined as a sequence of bytes +terminated by a null byte, +which is not considered when calculating string length. +However, when a string is passed or manipulated, +a pointer to it is employed. +Therefore, the XDR library defines a string to be a +.I "char *" +and not a sequence of characters. +The external representation of a string is drastically different +from its internal representation. +Externally, strings are represented as +sequences of ASCII characters, +while internally, they are represented with character pointers. +Conversion between the two representations +is accomplished with the routine +.I xdr_string (): +.IX xdr_string() "" \fIxdr_string()\fP +.DS +.ft CW +bool_t xdr_string(xdrs, sp, maxlength) + XDR *xdrs; + char **sp; + u_int maxlength; +.DE +The first parameter +.I xdrs +is the XDR stream handle. +The second parameter +.I sp +is a pointer to a string (type +.I "char **" . +The third parameter +.I maxlength +specifies the maximum number of bytes allowed during encoding or decoding. +its value is usually specified by a protocol. For example, a protocol +specification may say that a file name may be no longer than 255 characters. +.LP +The routine returns +.I FALSE +if the number of characters exceeds +.I maxlength , +and +.I TRUE +if it doesn't. +.SH +Keep +.I maxlength +small. If it is too big you can blow the heap, since +.I xdr_string() +will call +.I malloc() +for space. +.LP +The behavior of +.I xdr_string() +.IX xdr_string() "" \fIxdr_string()\fP +is similar to the behavior of other routines +discussed in this section. The direction +.I XDR_ENCODE +is easiest to understand. The parameter +.I sp +points to a string of a certain length; +if the string does not exceed +.I maxlength , +the bytes are serialized. +.LP +The effect of deserializing a string is subtle. +First the length of the incoming string is determined; +it must not exceed +.I maxlength . +Next +.I sp +is dereferenced; if the the value is +.I NULL , +then a string of the appropriate length is allocated and +.I *sp +is set to this string. +If the original value of +.I *sp +is non-null, then the XDR package assumes +that a target area has been allocated, +which can hold strings no longer than +.I maxlength . +In either case, the string is decoded into the target area. +The routine then appends a null character to the string. +.LP +In the +.I XDR_FREE +operation, the string is obtained by dereferencing +.I sp . +If the string is not +.I NULL , +it is freed and +.I *sp +is set to +.I NULL . +In this operation, +.I xdr_string() +ignores the +.I maxlength +parameter. +.NH 3 +\&Byte Arrays +.IX "XDR library" "byte arrays" +.LP +Often variable-length arrays of bytes are preferable to strings. +Byte arrays differ from strings in the following three ways: +1) the length of the array (the byte count) is explicitly +located in an unsigned integer, +2) the byte sequence is not terminated by a null character, and +3) the external representation of the bytes is the same as their +internal representation. +The primitive +.I xdr_bytes() +.IX xdr_bytes() "" \fIxdr_bytes()\fP +converts between the internal and external +representations of byte arrays: +.DS +.ft CW +bool_t xdr_bytes(xdrs, bpp, lp, maxlength) + XDR *xdrs; + char **bpp; + u_int *lp; + u_int maxlength; +.DE +The usage of the first, second and fourth parameters +are identical to the first, second and third parameters of +.I xdr_string (), +respectively. +The length of the byte area is obtained by dereferencing +.I lp +when serializing; +.I *lp +is set to the byte length when deserializing. +.NH 3 +\&Arrays +.IX "XDR library" "arrays" +.LP +The XDR library package provides a primitive +for handling arrays of arbitrary elements. +The +.I xdr_bytes() +routine treats a subset of generic arrays, +in which the size of array elements is known to be 1, +and the external description of each element is built-in. +The generic array primitive, +.I xdr_array() , +.IX xdr_array() "" \fIxdr_array()\fP +requires parameters identical to those of +.I xdr_bytes() +plus two more: +the size of array elements, +and an XDR routine to handle each of the elements. +This routine is called to encode or decode +each element of the array. +.DS +.ft CW +bool_t +xdr_array(xdrs, ap, lp, maxlength, elementsiz, xdr_element) + XDR *xdrs; + char **ap; + u_int *lp; + u_int maxlength; + u_int elementsiz; + bool_t (*xdr_element)(); +.DE +The parameter +.I ap +is the address of the pointer to the array. +If +.I *ap +is +.I NULL +when the array is being deserialized, +XDR allocates an array of the appropriate size and sets +.I *ap +to that array. +The element count of the array is obtained from +.I *lp +when the array is serialized; +.I *lp +is set to the array length when the array is deserialized. +The parameter +.I maxlength +is the maximum number of elements that the array is allowed to have; +.I elementsiz +is the byte size of each element of the array +(the C function +.I sizeof() +can be used to obtain this value). +The +.I xdr_element() +.IX xdr_element() "" \fIxdr_element()\fP +routine is called to serialize, deserialize, or free +each element of the array. +.br +.LP +Before defining more constructed data types, it is appropriate to +present three examples. +.LP +.I "Example A:" +.br +A user on a networked machine can be identified by +(a) the machine name, such as +.I krypton : +see the +.I gethostname +man page; (b) the user's UID: see the +.I geteuid +man page; and (c) the group numbers to which the user belongs: +see the +.I getgroups +man page. A structure with this information and its associated +XDR routine could be coded like this: +.ie t .DS +.el .DS L +.ft CW +struct netuser { + char *nu_machinename; + int nu_uid; + u_int nu_glen; + int *nu_gids; +}; +#define NLEN 255 /* \fImachine names < 256 chars\fP */ +#define NGRPS 20 /* \fIuser can't be in > 20 groups\fP */ +.sp.5 +bool_t +xdr_netuser(xdrs, nup) + XDR *xdrs; + struct netuser *nup; +{ + return(xdr_string(xdrs, &nup->nu_machinename, NLEN) && + xdr_int(xdrs, &nup->nu_uid) && + xdr_array(xdrs, &nup->nu_gids, &nup->nu_glen, + NGRPS, sizeof (int), xdr_int)); +} +.DE +.LP +.I "Example B:" +.br +A party of network users could be implemented +as an array of +.I netuser +structure. +The declaration and its associated XDR routines +are as follows: +.ie t .DS +.el .DS L +.ft CW +struct party { + u_int p_len; + struct netuser *p_nusers; +}; +#define PLEN 500 /* \fImax number of users in a party\fP */ +.sp.5 +bool_t +xdr_party(xdrs, pp) + XDR *xdrs; + struct party *pp; +{ + return(xdr_array(xdrs, &pp->p_nusers, &pp->p_len, PLEN, + sizeof (struct netuser), xdr_netuser)); +} +.DE +.LP +.I "Example C:" +.br +The well-known parameters to +.I main , +.I argc +and +.I argv +can be combined into a structure. +An array of these structures can make up a history of commands. +The declarations and XDR routines might look like: +.ie t .DS +.el .DS L +.ft CW +struct cmd { + u_int c_argc; + char **c_argv; +}; +#define ALEN 1000 /* \fIargs cannot be > 1000 chars\fP */ +#define NARGC 100 /* \fIcommands cannot have > 100 args\fP */ + +struct history { + u_int h_len; + struct cmd *h_cmds; +}; +#define NCMDS 75 /* \fIhistory is no more than 75 commands\fP */ + +bool_t +xdr_wrap_string(xdrs, sp) + XDR *xdrs; + char **sp; +{ + return(xdr_string(xdrs, sp, ALEN)); +} +.DE +.ie t .DS +.el .DS L +.ft CW +bool_t +xdr_cmd(xdrs, cp) + XDR *xdrs; + struct cmd *cp; +{ + return(xdr_array(xdrs, &cp->c_argv, &cp->c_argc, NARGC, + sizeof (char *), xdr_wrap_string)); +} +.DE +.ie t .DS +.el .DS L +.ft CW +bool_t +xdr_history(xdrs, hp) + XDR *xdrs; + struct history *hp; +{ + return(xdr_array(xdrs, &hp->h_cmds, &hp->h_len, NCMDS, + sizeof (struct cmd), xdr_cmd)); +} +.DE +The most confusing part of this example is that the routine +.I xdr_wrap_string() +is needed to package the +.I xdr_string() +routine, because the implementation of +.I xdr_array() +only passes two parameters to the array element description routine; +.I xdr_wrap_string() +supplies the third parameter to +.I xdr_string (). +.LP +By now the recursive nature of the XDR library should be obvious. +Let's continue with more constructed data types. +.NH 3 +\&Opaque Data +.IX "XDR library" "opaque data" +.LP +In some protocols, handles are passed from a server to client. +The client passes the handle back to the server at some later time. +Handles are never inspected by clients; +they are obtained and submitted. +That is to say, handles are opaque. +The +.I xdr_opaque() +.IX xdr_opaque() "" \fIxdr_opaque()\fP +primitive is used for describing fixed sized, opaque bytes. +.DS +.ft CW +bool_t xdr_opaque(xdrs, p, len) + XDR *xdrs; + char *p; + u_int len; +.DE +The parameter +.I p +is the location of the bytes; +.I len +is the number of bytes in the opaque object. +By definition, the actual data +contained in the opaque object are not machine portable. +.NH 3 +\&Fixed Sized Arrays +.IX "XDR library" "fixed sized arrays" +.LP +The XDR library provides a primitive, +.I xdr_vector (), +for fixed-length arrays. +.ie t .DS +.el .DS L +.ft CW +#define NLEN 255 /* \fImachine names must be < 256 chars\fP */ +#define NGRPS 20 /* \fIuser belongs to exactly 20 groups\fP */ +.sp.5 +struct netuser { + char *nu_machinename; + int nu_uid; + int nu_gids[NGRPS]; +}; +.sp.5 +bool_t +xdr_netuser(xdrs, nup) + XDR *xdrs; + struct netuser *nup; +{ + int i; +.sp.5 + if (!xdr_string(xdrs, &nup->nu_machinename, NLEN)) + return(FALSE); + if (!xdr_int(xdrs, &nup->nu_uid)) + return(FALSE); + if (!xdr_vector(xdrs, nup->nu_gids, NGRPS, sizeof(int), + xdr_int)) { + return(FALSE); + } + return(TRUE); +} +.DE +.NH 3 +\&Discriminated Unions +.IX "XDR library" "discriminated unions" +.LP +The XDR library supports discriminated unions. +A discriminated union is a C union and an +.I enum_t +value that selects an \*Qarm\*U of the union. +.DS +.ft CW +struct xdr_discrim { + enum_t value; + bool_t (*proc)(); +}; +.sp.5 +bool_t xdr_union(xdrs, dscmp, unp, arms, defaultarm) + XDR *xdrs; + enum_t *dscmp; + char *unp; + struct xdr_discrim *arms; + bool_t (*defaultarm)(); /* \fImay equal NULL\fP */ +.DE +First the routine translates the discriminant of the union located at +.I *dscmp . +The discriminant is always an +.I enum_t . +Next the union located at +.I *unp +is translated. +The parameter +.I arms +is a pointer to an array of +.I xdr_discrim +structures. +Each structure contains an ordered pair of +.I [value,proc] . +If the union's discriminant is equal to the associated +.I value , +then the +.I proc +is called to translate the union. +The end of the +.I xdr_discrim +structure array is denoted by a routine of value +.I NULL +(0). If the discriminant is not found in the +.I arms +array, then the +.I defaultarm +procedure is called if it is non-null; +otherwise the routine returns +.I FALSE . +.LP +.I "Example D:" +Suppose the type of a union may be integer, +character pointer (a string), or a +.I gnumbers +structure. +Also, assume the union and its current type +are declared in a structure. +The declaration is: +.ie t .DS +.el .DS L +.ft CW +enum utype { INTEGER=1, STRING=2, GNUMBERS=3 }; +.sp.5 +struct u_tag { + enum utype utype; /* \fIthe union's discriminant\fP */ + union { + int ival; + char *pval; + struct gnumbers gn; + } uval; +}; +.DE +The following constructs and XDR procedure (de)serialize +the discriminated union: +.ie t .DS +.el .DS L +.ft CW +struct xdr_discrim u_tag_arms[4] = { + { INTEGER, xdr_int }, + { GNUMBERS, xdr_gnumbers } + { STRING, xdr_wrap_string }, + { __dontcare__, NULL } + /* \fIalways terminate arms with a NULL xdr_proc\fP */ +} +.sp.5 +bool_t +xdr_u_tag(xdrs, utp) + XDR *xdrs; + struct u_tag *utp; +{ + return(xdr_union(xdrs, &utp->utype, &utp->uval, + u_tag_arms, NULL)); +} +.DE +The routine +.I xdr_gnumbers() +was presented above in +.I "The XDR Library" +section. +.I xdr_wrap_string() +was presented in example C. +The default +.I arm +parameter to +.I xdr_union() +(the last parameter) is +.I NULL +in this example. Therefore the value of the union's discriminant +may legally take on only values listed in the +.I u_tag_arms +array. This example also demonstrates that +the elements of the arm's array do not need to be sorted. +.LP +It is worth pointing out that the values of the discriminant +may be sparse, though in this example they are not. +It is always good +practice to assign explicitly integer values to each element of the +discriminant's type. +This practice both documents the external +representation of the discriminant and guarantees that different +C compilers emit identical discriminant values. +.LP +Exercise: Implement +.I xdr_union() +using the other primitives in this section. +.NH 3 +\&Pointers +.IX "XDR library" "pointers" +.LP +In C it is often convenient to put pointers +to another structure within a structure. +The +.I xdr_reference() +.IX xdr_reference() "" \fIxdr_reference()\fP +primitive makes it easy to serialize, deserialize, and free +these referenced structures. +.DS +.ft CW +bool_t xdr_reference(xdrs, pp, size, proc) + XDR *xdrs; + char **pp; + u_int ssize; + bool_t (*proc)(); +.DE +.LP +Parameter +.I pp +is the address of +the pointer to the structure; +parameter +.I ssize +is the size in bytes of the structure (use the C function +.I sizeof() +to obtain this value); and +.I proc +is the XDR routine that describes the structure. +When decoding data, storage is allocated if +.I *pp +is +.I NULL . +.LP +There is no need for a primitive +.I xdr_struct() +to describe structures within structures, +because pointers are always sufficient. +.LP +Exercise: Implement +.I xdr_reference() +using +.I xdr_array (). +Warning: +.I xdr_reference() +and +.I xdr_array() +are NOT interchangeable external representations of data. +.LP +.I "Example E:" +Suppose there is a structure containing a person's name +and a pointer to a +.I gnumbers +structure containing the person's gross assets and liabilities. +The construct is: +.DS +.ft CW +struct pgn { + char *name; + struct gnumbers *gnp; +}; +.DE +The corresponding XDR routine for this structure is: +.DS +.ft CW +bool_t +xdr_pgn(xdrs, pp) + XDR *xdrs; + struct pgn *pp; +{ + if (xdr_string(xdrs, &pp->name, NLEN) && + xdr_reference(xdrs, &pp->gnp, + sizeof(struct gnumbers), xdr_gnumbers)) + return(TRUE); + return(FALSE); +} +.DE +.IX "pointer semantics and XDR" +.I "Pointer Semantics and XDR" +.LP +In many applications, C programmers attach double meaning to +the values of a pointer. Typically the value +.I NULL +(or zero) means data is not needed, +yet some application-specific interpretation applies. +In essence, the C programmer is encoding +a discriminated union efficiently +by overloading the interpretation of the value of a pointer. +For instance, in example E a +.I NULL +pointer value for +.I gnp +could indicate that +the person's assets and liabilities are unknown. +That is, the pointer value encodes two things: +whether or not the data is known; +and if it is known, where it is located in memory. +Linked lists are an extreme example of the use +of application-specific pointer interpretation. +.LP +The primitive +.I xdr_reference() +.IX xdr_reference() "" \fIxdr_reference()\fP +cannot and does not attach any special +meaning to a null-value pointer during serialization. +That is, passing an address of a pointer whose value is +.I NULL +to +.I xdr_reference() +when serialing data will most likely cause a memory fault and, on the UNIX +system, a core dump. +.LP +.I xdr_pointer() +correctly handles +.I NULL +pointers. For more information about its use, see +the +.I "Linked Lists" +topics below. +.LP +.I Exercise: +After reading the section on +.I "Linked Lists" , +return here and extend example E so that +it can correctly deal with +.I NULL +pointer values. +.LP +.I Exercise: +Using the +.I xdr_union (), +.I xdr_reference() +and +.I xdr_void() +primitives, implement a generic pointer handling primitive +that implicitly deals with +.I NULL +pointers. That is, implement +.I xdr_pointer (). +.NH 2 +\&Non-filter Primitives +.IX "XDR" "non-filter primitives" +.LP +XDR streams can be manipulated with +the primitives discussed in this section. +.DS +.ft CW +u_int xdr_getpos(xdrs) + XDR *xdrs; +.sp.5 +bool_t xdr_setpos(xdrs, pos) + XDR *xdrs; + u_int pos; +.sp.5 +xdr_destroy(xdrs) + XDR *xdrs; +.DE +The routine +.I xdr_getpos() +.IX xdr_getpos() "" \fIxdr_getpos()\fP +returns an unsigned integer +that describes the current position in the data stream. +Warning: In some XDR streams, the returned value of +.I xdr_getpos() +is meaningless; +the routine returns a \-1 in this case +(though \-1 should be a legitimate value). +.LP +The routine +.I xdr_setpos() +.IX xdr_setpos() "" \fIxdr_setpos()\fP +sets a stream position to +.I pos . +Warning: In some XDR streams, setting a position is impossible; +in such cases, +.I xdr_setpos() +will return +.I FALSE . +This routine will also fail if the requested position is out-of-bounds. +The definition of bounds varies from stream to stream. +.LP +The +.I xdr_destroy() +.IX xdr_destroy() "" \fIxdr_destroy()\fP +primitive destroys the XDR stream. +Usage of the stream +after calling this routine is undefined. +.NH 2 +\&XDR Operation Directions +.IX XDR "operation directions" +.IX "direction of XDR operations" +.LP +At times you may wish to optimize XDR routines by taking +advantage of the direction of the operation \(em +.I XDR_ENCODE +.I XDR_DECODE +or +.I XDR_FREE +The value +.I xdrs->x_op +always contains the direction of the XDR operation. +Programmers are not encouraged to take advantage of this information. +Therefore, no example is presented here. However, an example in the +.I "Linked Lists" +topic below, demonstrates the usefulness of the +.I xdrs->x_op +field. +.NH 2 +\&XDR Stream Access +.IX "XDR" "stream access" +.LP +An XDR stream is obtained by calling the appropriate creation routine. +These creation routines take arguments that are tailored to the +specific properties of the stream. +.LP +Streams currently exist for (de)serialization of data to or from +standard I/O +.I FILE +streams, TCP/IP connections and UNIX files, and memory. +.NH 3 +\&Standard I/O Streams +.IX "XDR" "standard I/O streams" +.LP +XDR streams can be interfaced to standard I/O using the +.I xdrstdio_create() +.IX xdrstdio_create() "" \fIxdrstdio_create()\fP +routine as follows: +.DS +.ft CW +#include <stdio.h> +#include <rpc/rpc.h> /* \fIxdr streams part of rpc\fP */ +.sp.5 +void +xdrstdio_create(xdrs, fp, x_op) + XDR *xdrs; + FILE *fp; + enum xdr_op x_op; +.DE +The routine +.I xdrstdio_create() +initializes an XDR stream pointed to by +.I xdrs . +The XDR stream interfaces to the standard I/O library. +Parameter +.I fp +is an open file, and +.I x_op +is an XDR direction. +.NH 3 +\&Memory Streams +.IX "XDR" "memory streams" +.LP +Memory streams allow the streaming of data into or out of +a specified area of memory: +.DS +.ft CW +#include <rpc/rpc.h> +.sp.5 +void +xdrmem_create(xdrs, addr, len, x_op) + XDR *xdrs; + char *addr; + u_int len; + enum xdr_op x_op; +.DE +The routine +.I xdrmem_create() +.IX xdrmem_create() "" \fIxdrmem_create()\fP +initializes an XDR stream in local memory. +The memory is pointed to by parameter +.I addr ; +parameter +.I len +is the length in bytes of the memory. +The parameters +.I xdrs +and +.I x_op +are identical to the corresponding parameters of +.I xdrstdio_create (). +Currently, the UDP/IP implementation of RPC uses +.I xdrmem_create (). +Complete call or result messages are built in memory before calling the +.I sendto() +system routine. +.NH 3 +\&Record (TCP/IP) Streams +.IX "XDR" "record (TCP/IP) streams" +.LP +A record stream is an XDR stream built on top of +a record marking standard that is built on top of the +UNIX file or 4.2 BSD connection interface. +.DS +.ft CW +#include <rpc/rpc.h> /* \fIxdr streams part of rpc\fP */ +.sp.5 +xdrrec_create(xdrs, + sendsize, recvsize, iohandle, readproc, writeproc) + XDR *xdrs; + u_int sendsize, recvsize; + char *iohandle; + int (*readproc)(), (*writeproc)(); +.DE +The routine +.I xdrrec_create() +provides an XDR stream interface that allows for a bidirectional, +arbitrarily long sequence of records. +The contents of the records are meant to be data in XDR form. +The stream's primary use is for interfacing RPC to TCP connections. +However, it can be used to stream data into or out of normal +UNIX files. +.LP +The parameter +.I xdrs +is similar to the corresponding parameter described above. +The stream does its own data buffering similar to that of standard I/O. +The parameters +.I sendsize +and +.I recvsize +determine the size in bytes of the output and input buffers, respectively; +if their values are zero (0), then predetermined defaults are used. +When a buffer needs to be filled or flushed, the routine +.I readproc() +or +.I writeproc() +is called, respectively. +The usage and behavior of these +routines are similar to the UNIX system calls +.I read() +and +.I write (). +However, +the first parameter to each of these routines is the opaque parameter +.I iohandle . +The other two parameters +.I buf "" +and +.I nbytes ) +and the results +(byte count) are identical to the system routines. +If +.I xxx +is +.I readproc() +or +.I writeproc (), +then it has the following form: +.DS +.ft CW +.ft I +/* + * returns the actual number of bytes transferred. + * -1 is an error + */ +.ft CW +int +xxx(iohandle, buf, len) + char *iohandle; + char *buf; + int nbytes; +.DE +The XDR stream provides means for delimiting records in the byte stream. +The implementation details of delimiting records in a stream are +discussed in the +.I "Advanced Topics" +topic below. +The primitives that are specific to record streams are as follows: +.DS +.ft CW +bool_t +xdrrec_endofrecord(xdrs, flushnow) + XDR *xdrs; + bool_t flushnow; +.sp.5 +bool_t +xdrrec_skiprecord(xdrs) + XDR *xdrs; +.sp.5 +bool_t +xdrrec_eof(xdrs) + XDR *xdrs; +.DE +The routine +.I xdrrec_endofrecord() +.IX xdrrec_endofrecord() "" \fIxdrrec_endofrecord()\fP +causes the current outgoing data to be marked as a record. +If the parameter +.I flushnow +is +.I TRUE , +then the stream's +.I writeproc +will be called; otherwise, +.I writeproc +will be called when the output buffer has been filled. +.LP +The routine +.I xdrrec_skiprecord() +.IX xdrrec_skiprecord() "" \fIxdrrec_skiprecord()\fP +causes an input stream's position to be moved past +the current record boundary and onto the +beginning of the next record in the stream. +.LP +If there is no more data in the stream's input buffer, +then the routine +.I xdrrec_eof() +.IX xdrrec_eof() "" \fIxdrrec_eof()\fP +returns +.I TRUE . +That is not to say that there is no more data +in the underlying file descriptor. +.NH 2 +\&XDR Stream Implementation +.IX "XDR" "stream implementation" +.IX "stream implementation in XDR" +.LP +This section provides the abstract data types needed +to implement new instances of XDR streams. +.NH 3 +\&The XDR Object +.IX "XDR" "object" +.LP +The following structure defines the interface to an XDR stream: +.ie t .DS +.el .DS L +.ft CW +enum xdr_op { XDR_ENCODE=0, XDR_DECODE=1, XDR_FREE=2 }; +.sp.5 +typedef struct { + enum xdr_op x_op; /* \fIoperation; fast added param\fP */ + struct xdr_ops { + bool_t (*x_getlong)(); /* \fIget long from stream\fP */ + bool_t (*x_putlong)(); /* \fIput long to stream\fP */ + bool_t (*x_getbytes)(); /* \fIget bytes from stream\fP */ + bool_t (*x_putbytes)(); /* \fIput bytes to stream\fP */ + u_int (*x_getpostn)(); /* \fIreturn stream offset\fP */ + bool_t (*x_setpostn)(); /* \fIreposition offset\fP */ + caddr_t (*x_inline)(); /* \fIptr to buffered data\fP */ + VOID (*x_destroy)(); /* \fIfree private area\fP */ + } *x_ops; + caddr_t x_public; /* \fIusers' data\fP */ + caddr_t x_private; /* \fIpointer to private data\fP */ + caddr_t x_base; /* \fIprivate for position info\fP */ + int x_handy; /* \fIextra private word\fP */ +} XDR; +.DE +The +.I x_op +field is the current operation being performed on the stream. +This field is important to the XDR primitives, +but should not affect a stream's implementation. +That is, a stream's implementation should not depend +on this value. +The fields +.I x_private , +.I x_base , +and +.I x_handy +are private to the particular +stream's implementation. +The field +.I x_public +is for the XDR client and should never be used by +the XDR stream implementations or the XDR primitives. +.I x_getpostn() , +.I x_setpostn() +and +.I x_destroy() +are macros for accessing operations. The operation +.I x_inline() +takes two parameters: +an XDR *, and an unsigned integer, which is a byte count. +The routine returns a pointer to a piece of +the stream's internal buffer. +The caller can then use the buffer segment for any purpose. +From the stream's point of view, the bytes in the +buffer segment have been consumed or put. +The routine may return +.I NULL +if it cannot return a buffer segment of the requested size. +(The +.I x_inline() +routine is for cycle squeezers. +Use of the resulting buffer is not data-portable. +Users are encouraged not to use this feature.) +.LP +The operations +.I x_getbytes() +and +.I x_putbytes() +blindly get and put sequences of bytes +from or to the underlying stream; +they return +.I TRUE +if they are successful, and +.I FALSE +otherwise. The routines have identical parameters (replace +.I xxx ): +.DS +.ft CW +bool_t +xxxbytes(xdrs, buf, bytecount) + XDR *xdrs; + char *buf; + u_int bytecount; +.DE +The operations +.I x_getlong() +and +.I x_putlong() +receive and put +long numbers from and to the data stream. +It is the responsibility of these routines +to translate the numbers between the machine representation +and the (standard) external representation. +The UNIX primitives +.I htonl() +and +.I ntohl() +can be helpful in accomplishing this. +The higher-level XDR implementation assumes that +signed and unsigned long integers contain the same number of bits, +and that nonnegative integers +have the same bit representations as unsigned integers. +The routines return +.I TRUE +if they succeed, and +.I FALSE +otherwise. They have identical parameters: +.DS +.ft CW +bool_t +xxxlong(xdrs, lp) + XDR *xdrs; + long *lp; +.DE +Implementors of new XDR streams must make an XDR structure +(with new operation routines) available to clients, +using some kind of create routine. +.NH 1 +\&Advanced Topics +.IX XDR "advanced topics" +.LP +This section describes techniques for passing data structures that +are not covered in the preceding sections. Such structures include +linked lists (of arbitrary lengths). Unlike the simpler examples +covered in the earlier sections, the following examples are written +using both the XDR C library routines and the XDR data description +language. +The +.I "External Data Representation Standard: Protocol Specification" +describes this +language in complete detail. +.NH 2 +\&Linked Lists +.IX XDR "linked lists" +.LP +The last example in the +.I Pointers +topic earlier in this chapter +presented a C data structure and its associated XDR +routines for a individual's gross assets and liabilities. +The example is duplicated below: +.ie t .DS +.el .DS L +.ft CW +struct gnumbers { + long g_assets; + long g_liabilities; +}; +.sp.5 +bool_t +xdr_gnumbers(xdrs, gp) + XDR *xdrs; + struct gnumbers *gp; +{ + if (xdr_long(xdrs, &(gp->g_assets))) + return(xdr_long(xdrs, &(gp->g_liabilities))); + return(FALSE); +} +.DE +.LP +Now assume that we wish to implement a linked list of such information. +A data structure could be constructed as follows: +.ie t .DS +.el .DS L +.ft CW +struct gnumbers_node { + struct gnumbers gn_numbers; + struct gnumbers_node *gn_next; +}; +.sp .5 +typedef struct gnumbers_node *gnumbers_list; +.DE +.LP +The head of the linked list can be thought of as the data object; +that is, the head is not merely a convenient shorthand for a +structure. Similarly the +.I gn_next +field is used to indicate whether or not the object has terminated. +Unfortunately, if the object continues, the +.I gn_next +field is also the address of where it continues. The link addresses +carry no useful information when the object is serialized. +.LP +The XDR data description of this linked list is described by the +recursive declaration of +.I gnumbers_list : +.ie t .DS +.el .DS L +.ft CW +struct gnumbers { + int g_assets; + int g_liabilities; +}; +.sp .5 +struct gnumbers_node { + gnumbers gn_numbers; + gnumbers_node *gn_next; +}; +.DE +.LP +In this description, the boolean indicates whether there is more data +following it. If the boolean is +.I FALSE , +then it is the last data field of the structure. If it is +.I TRUE , +then it is followed by a gnumbers structure and (recursively) by a +.I gnumbers_list . +Note that the C declaration has no boolean explicitly declared in it +(though the +.I gn_next +field implicitly carries the information), while the XDR data +description has no pointer explicitly declared in it. +.LP +Hints for writing the XDR routines for a +.I gnumbers_list +follow easily from the XDR description above. Note how the primitive +.I xdr_pointer() +is used to implement the XDR union above. +.ie t .DS +.el .DS L +.ft CW +bool_t +xdr_gnumbers_node(xdrs, gn) + XDR *xdrs; + gnumbers_node *gn; +{ + return(xdr_gnumbers(xdrs, &gn->gn_numbers) && + xdr_gnumbers_list(xdrs, &gp->gn_next)); +} +.sp .5 +bool_t +xdr_gnumbers_list(xdrs, gnp) + XDR *xdrs; + gnumbers_list *gnp; +{ + return(xdr_pointer(xdrs, gnp, + sizeof(struct gnumbers_node), + xdr_gnumbers_node)); +} +.DE +.LP +The unfortunate side effect of XDR'ing a list with these routines +is that the C stack grows linearly with respect to the number of +node in the list. This is due to the recursion. The following +routine collapses the above two mutually recursive into a single, +non-recursive one. +.ie t .DS +.el .DS L +.ft CW +bool_t +xdr_gnumbers_list(xdrs, gnp) + XDR *xdrs; + gnumbers_list *gnp; +{ + bool_t more_data; + gnumbers_list *nextp; +.sp .5 + for (;;) { + more_data = (*gnp != NULL); + if (!xdr_bool(xdrs, &more_data)) { + return(FALSE); + } + if (! more_data) { + break; + } + if (xdrs->x_op == XDR_FREE) { + nextp = &(*gnp)->gn_next; + } + if (!xdr_reference(xdrs, gnp, + sizeof(struct gnumbers_node), xdr_gnumbers)) { + + return(FALSE); + } + gnp = (xdrs->x_op == XDR_FREE) ? + nextp : &(*gnp)->gn_next; + } + *gnp = NULL; + return(TRUE); +} +.DE +.LP +The first task is to find out whether there is more data or not, +so that this boolean information can be serialized. Notice that +this statement is unnecessary in the +.I XDR_DECODE +case, since the value of more_data is not known until we +deserialize it in the next statement. +.LP +The next statement XDR's the more_data field of the XDR union. +Then if there is truly no more data, we set this last pointer to +.I NULL +to indicate the end of the list, and return +.I TRUE +because we are done. Note that setting the pointer to +.I NULL +is only important in the +.I XDR_DECODE +case, since it is already +.I NULL +in the +.I XDR_ENCODE +and +XDR_FREE +cases. +.LP +Next, if the direction is +.I XDR_FREE , +the value of +.I nextp +is set to indicate the location of the next pointer in the list. +We do this now because we need to dereference gnp to find the +location of the next item in the list, and after the next +statement the storage pointed to by +.I gnp +will be freed up and no be longer valid. We can't do this for all +directions though, because in the +.I XDR_DECODE +direction the value of +.I gnp +won't be set until the next statement. +.LP +Next, we XDR the data in the node using the primitive +.I xdr_reference (). +.I xdr_reference() +is like +.I xdr_pointer() +which we used before, but it does not +send over the boolean indicating whether there is more data. +We use it instead of +.I xdr_pointer() +because we have already XDR'd this information ourselves. Notice +that the xdr routine passed is not the same type as an element +in the list. The routine passed is +.I xdr_gnumbers (), +for XDR'ing gnumbers, but each element in the list is actually of +type +.I gnumbers_node . +We don't pass +.I xdr_gnumbers_node() +because it is recursive, and instead use +.I xdr_gnumbers() +which XDR's all of the non-recursive part. Note that this trick +will work only if the +.I gn_numbers +field is the first item in each element, so that their addresses +are identical when passed to +.I xdr_reference (). +.LP +Finally, we update +.I gnp +to point to the next item in the list. If the direction is +.I XDR_FREE , +we set it to the previously saved value, otherwise we can +dereference +.I gnp +to get the proper value. Though harder to understand than the +recursive version, this non-recursive routine is far less likely +to blow the C stack. It will also run more efficiently since +a lot of procedure call overhead has been removed. Most lists +are small though (in the hundreds of items or less) and the +recursive version should be sufficient for them. +.EQ +delim off +.EN diff --git a/cpukit/librpc/src/rpc/PSD.doc/xdr.rfc.ms b/cpukit/librpc/src/rpc/PSD.doc/xdr.rfc.ms index e69de29bb2..d4baff5391 100644 --- a/cpukit/librpc/src/rpc/PSD.doc/xdr.rfc.ms +++ b/cpukit/librpc/src/rpc/PSD.doc/xdr.rfc.ms @@ -0,0 +1,1058 @@ +.\" +.\" Must use -- tbl -- with this one +.\" +.\" @(#)xdr.rfc.ms 2.2 88/08/05 4.0 RPCSRC +.de BT +.if \\n%=1 .tl ''- % -'' +.. +.ND +.\" prevent excess underlining in nroff +.if n .fp 2 R +.OH 'External Data Representation Standard''Page %' +.EH 'Page %''External Data Representation Standard' +.IX "External Data Representation" +.if \\n%=1 .bp +.SH +\&External Data Representation Standard: Protocol Specification +.IX XDR RFC +.IX XDR "protocol specification" +.LP +.NH 0 +\&Status of this Standard +.nr OF 1 +.IX XDR "RFC status" +.LP +Note: This chapter specifies a protocol that Sun Microsystems, Inc., and +others are using. It has been designated RFC1014 by the ARPA Network +Information Center. +.NH 1 +Introduction +\& +.LP +XDR is a standard for the description and encoding of data. It is +useful for transferring data between different computer +architectures, and has been used to communicate data between such +diverse machines as the Sun Workstation, VAX, IBM-PC, and Cray. +XDR fits into the ISO presentation layer, and is roughly analogous in +purpose to X.409, ISO Abstract Syntax Notation. The major difference +between these two is that XDR uses implicit typing, while X.409 uses +explicit typing. +.LP +XDR uses a language to describe data formats. The language can only +be used only to describe data; it is not a programming language. +This language allows one to describe intricate data formats in a +concise manner. The alternative of using graphical representations +(itself an informal language) quickly becomes incomprehensible when +faced with complexity. The XDR language itself is similar to the C +language [1], just as Courier [4] is similar to Mesa. Protocols such +as Sun RPC (Remote Procedure Call) and the NFS (Network File System) +use XDR to describe the format of their data. +.LP +The XDR standard makes the following assumption: that bytes (or +octets) are portable, where a byte is defined to be 8 bits of data. +A given hardware device should encode the bytes onto the various +media in such a way that other hardware devices may decode the bytes +without loss of meaning. For example, the Ethernet standard +suggests that bytes be encoded in "little-endian" style [2], or least +significant bit first. +.NH 2 +\&Basic Block Size +.IX XDR "basic block size" +.IX XDR "block size" +.LP +The representation of all items requires a multiple of four bytes (or +32 bits) of data. The bytes are numbered 0 through n-1. The bytes +are read or written to some byte stream such that byte m always +precedes byte m+1. If the n bytes needed to contain the data are not +a multiple of four, then the n bytes are followed by enough (0 to 3) +residual zero bytes, r, to make the total byte count a multiple of 4. +.LP +We include the familiar graphic box notation for illustration and +comparison. In most illustrations, each box (delimited by a plus +sign at the 4 corners and vertical bars and dashes) depicts a byte. +Ellipses (...) between boxes show zero or more additional bytes where +required. +.ie t .DS +.el .DS L +\fIA Block\fP + +\f(CW+--------+--------+...+--------+--------+...+--------+ +| byte 0 | byte 1 |...|byte n-1| 0 |...| 0 | ++--------+--------+...+--------+--------+...+--------+ +|<-----------n bytes---------->|<------r bytes------>| +|<-----------n+r (where (n+r) mod 4 = 0)>----------->|\fP + +.DE +.NH 1 +\&XDR Data Types +.IX XDR "data types" +.IX "XDR data types" +.LP +Each of the sections that follow describes a data type defined in the +XDR standard, shows how it is declared in the language, and includes +a graphic illustration of its encoding. +.LP +For each data type in the language we show a general paradigm +declaration. Note that angle brackets (< and >) denote +variable length sequences of data and square brackets ([ and ]) denote +fixed-length sequences of data. "n", "m" and "r" denote integers. +For the full language specification and more formal definitions of +terms such as "identifier" and "declaration", refer to +.I "The XDR Language Specification" , +below. +.LP +For some data types, more specific examples are included. +A more extensive example of a data description is in +.I "An Example of an XDR Data Description" +below. +.NH 2 +\&Integer +.IX XDR integer +.LP +An XDR signed integer is a 32-bit datum that encodes an integer in +the range [-2147483648,2147483647]. The integer is represented in +two's complement notation. The most and least significant bytes are +0 and 3, respectively. Integers are declared as follows: +.ie t .DS +.el .DS L +\fIInteger\fP + +\f(CW(MSB) (LSB) ++-------+-------+-------+-------+ +|byte 0 |byte 1 |byte 2 |byte 3 | ++-------+-------+-------+-------+ +<------------32 bits------------>\fP +.DE +.NH 2 +\&Unsigned Integer +.IX XDR "unsigned integer" +.IX XDR "integer, unsigned" +.LP +An XDR unsigned integer is a 32-bit datum that encodes a nonnegative +integer in the range [0,4294967295]. It is represented by an +unsigned binary number whose most and least significant bytes are 0 +and 3, respectively. An unsigned integer is declared as follows: +.ie t .DS +.el .DS L +\fIUnsigned Integer\fP + +\f(CW(MSB) (LSB) ++-------+-------+-------+-------+ +|byte 0 |byte 1 |byte 2 |byte 3 | ++-------+-------+-------+-------+ +<------------32 bits------------>\fP +.DE +.NH 2 +\&Enumeration +.IX XDR enumeration +.LP +Enumerations have the same representation as signed integers. +Enumerations are handy for describing subsets of the integers. +Enumerated data is declared as follows: +.ft CW +.DS +enum { name-identifier = constant, ... } identifier; +.DE +For example, the three colors red, yellow, and blue could be +described by an enumerated type: +.DS +.ft CW +enum { RED = 2, YELLOW = 3, BLUE = 5 } colors; +.DE +It is an error to encode as an enum any other integer than those that +have been given assignments in the enum declaration. +.NH 2 +\&Boolean +.IX XDR boolean +.LP +Booleans are important enough and occur frequently enough to warrant +their own explicit type in the standard. Booleans are declared as +follows: +.DS +.ft CW +bool identifier; +.DE +This is equivalent to: +.DS +.ft CW +enum { FALSE = 0, TRUE = 1 } identifier; +.DE +.NH 2 +\&Hyper Integer and Unsigned Hyper Integer +.IX XDR "hyper integer" +.IX XDR "integer, hyper" +.LP +The standard also defines 64-bit (8-byte) numbers called hyper +integer and unsigned hyper integer. Their representations are the +obvious extensions of integer and unsigned integer defined above. +They are represented in two's complement notation. The most and +least significant bytes are 0 and 7, respectively. Their +declarations: +.ie t .DS +.el .DS L +\fIHyper Integer\fP +\fIUnsigned Hyper Integer\fP + +\f(CW(MSB) (LSB) ++-------+-------+-------+-------+-------+-------+-------+-------+ +|byte 0 |byte 1 |byte 2 |byte 3 |byte 4 |byte 5 |byte 6 |byte 7 | ++-------+-------+-------+-------+-------+-------+-------+-------+ +<----------------------------64 bits---------------------------->\fP +.DE +.NH 2 +\&Floating-point +.IX XDR "integer, floating point" +.IX XDR "floating-point integer" +.LP +The standard defines the floating-point data type "float" (32 bits or +4 bytes). The encoding used is the IEEE standard for normalized +single-precision floating-point numbers [3]. The following three +fields describe the single-precision floating-point number: +.RS +.IP \fBS\fP: +The sign of the number. Values 0 and 1 represent positive and +negative, respectively. One bit. +.IP \fBE\fP: +The exponent of the number, base 2. 8 bits are devoted to this +field. The exponent is biased by 127. +.IP \fBF\fP: +The fractional part of the number's mantissa, base 2. 23 bits +are devoted to this field. +.RE +.LP +Therefore, the floating-point number is described by: +.DS +(-1)**S * 2**(E-Bias) * 1.F +.DE +It is declared as follows: +.ie t .DS +.el .DS L +\fISingle-Precision Floating-Point\fP + +\f(CW+-------+-------+-------+-------+ +|byte 0 |byte 1 |byte 2 |byte 3 | +S| E | F | ++-------+-------+-------+-------+ +1|<- 8 ->|<-------23 bits------>| +<------------32 bits------------>\fP +.DE +Just as the most and least significant bytes of a number are 0 and 3, +the most and least significant bits of a single-precision floating- +point number are 0 and 31. The beginning bit (and most significant +bit) offsets of S, E, and F are 0, 1, and 9, respectively. Note that +these numbers refer to the mathematical positions of the bits, and +NOT to their actual physical locations (which vary from medium to +medium). +.LP +The IEEE specifications should be consulted concerning the encoding +for signed zero, signed infinity (overflow), and denormalized numbers +(underflow) [3]. According to IEEE specifications, the "NaN" (not a +number) is system dependent and should not be used externally. +.NH 2 +\&Double-precision Floating-point +.IX XDR "integer, double-precision floating point" +.IX XDR "double-precision floating-point integer" +.LP +The standard defines the encoding for the double-precision floating- +point data type "double" (64 bits or 8 bytes). The encoding used is +the IEEE standard for normalized double-precision floating-point +numbers [3]. The standard encodes the following three fields, which +describe the double-precision floating-point number: +.RS +.IP \fBS\fP: +The sign of the number. Values 0 and 1 represent positive and +negative, respectively. One bit. +.IP \fBE\fP: +The exponent of the number, base 2. 11 bits are devoted to this +field. The exponent is biased by 1023. +.IP \fBF\fP: +The fractional part of the number's mantissa, base 2. 52 bits +are devoted to this field. +.RE +.LP +Therefore, the floating-point number is described by: +.DS +(-1)**S * 2**(E-Bias) * 1.F +.DE +It is declared as follows: +.ie t .DS +.el .DS L +\fIDouble-Precision Floating-Point\fP + +\f(CW+------+------+------+------+------+------+------+------+ +|byte 0|byte 1|byte 2|byte 3|byte 4|byte 5|byte 6|byte 7| +S| E | F | ++------+------+------+------+------+------+------+------+ +1|<--11-->|<-----------------52 bits------------------->| +<-----------------------64 bits------------------------->\fP +.DE +Just as the most and least significant bytes of a number are 0 and 3, +the most and least significant bits of a double-precision floating- +point number are 0 and 63. The beginning bit (and most significant +bit) offsets of S, E , and F are 0, 1, and 12, respectively. Note +that these numbers refer to the mathematical positions of the bits, +and NOT to their actual physical locations (which vary from medium to +medium). +.LP +The IEEE specifications should be consulted concerning the encoding +for signed zero, signed infinity (overflow), and denormalized numbers +(underflow) [3]. According to IEEE specifications, the "NaN" (not a +number) is system dependent and should not be used externally. +.NH 2 +\&Fixed-length Opaque Data +.IX XDR "fixed-length opaque data" +.IX XDR "opaque data, fixed length" +.LP +At times, fixed-length uninterpreted data needs to be passed among +machines. This data is called "opaque" and is declared as follows: +.DS +.ft CW +opaque identifier[n]; +.DE +where the constant n is the (static) number of bytes necessary to +contain the opaque data. If n is not a multiple of four, then the n +bytes are followed by enough (0 to 3) residual zero bytes, r, to make +the total byte count of the opaque object a multiple of four. +.ie t .DS +.el .DS L +\fIFixed-Length Opaque\fP + +\f(CW0 1 ... ++--------+--------+...+--------+--------+...+--------+ +| byte 0 | byte 1 |...|byte n-1| 0 |...| 0 | ++--------+--------+...+--------+--------+...+--------+ +|<-----------n bytes---------->|<------r bytes------>| +|<-----------n+r (where (n+r) mod 4 = 0)------------>|\fP +.DE +.NH 2 +\&Variable-length Opaque Data +.IX XDR "variable-length opaque data" +.IX XDR "opaque data, variable length" +.LP +The standard also provides for variable-length (counted) opaque data, +defined as a sequence of n (numbered 0 through n-1) arbitrary bytes +to be the number n encoded as an unsigned integer (as described +below), and followed by the n bytes of the sequence. +.LP +Byte m of the sequence always precedes byte m+1 of the sequence, and +byte 0 of the sequence always follows the sequence's length (count). +enough (0 to 3) residual zero bytes, r, to make the total byte count +a multiple of four. Variable-length opaque data is declared in the +following way: +.DS +.ft CW +opaque identifier<m>; +.DE +or +.DS +.ft CW +opaque identifier<>; +.DE +The constant m denotes an upper bound of the number of bytes that the +sequence may contain. If m is not specified, as in the second +declaration, it is assumed to be (2**32) - 1, the maximum length. +The constant m would normally be found in a protocol specification. +For example, a filing protocol may state that the maximum data +transfer size is 8192 bytes, as follows: +.DS +.ft CW +opaque filedata<8192>; +.DE +This can be illustrated as follows: +.ie t .DS +.el .DS L +\fIVariable-Length Opaque\fP + +\f(CW0 1 2 3 4 5 ... ++-----+-----+-----+-----+-----+-----+...+-----+-----+...+-----+ +| length n |byte0|byte1|...| n-1 | 0 |...| 0 | ++-----+-----+-----+-----+-----+-----+...+-----+-----+...+-----+ +|<-------4 bytes------->|<------n bytes------>|<---r bytes--->| +|<----n+r (where (n+r) mod 4 = 0)---->|\fP +.DE +.LP +It is an error to encode a length greater than the maximum +described in the specification. +.NH 2 +\&String +.IX XDR string +.LP +The standard defines a string of n (numbered 0 through n-1) ASCII +bytes to be the number n encoded as an unsigned integer (as described +above), and followed by the n bytes of the string. Byte m of the +string always precedes byte m+1 of the string, and byte 0 of the +string always follows the string's length. If n is not a multiple of +four, then the n bytes are followed by enough (0 to 3) residual zero +bytes, r, to make the total byte count a multiple of four. Counted +byte strings are declared as follows: +.DS +.ft CW +string object<m>; +.DE +or +.DS +.ft CW +string object<>; +.DE +The constant m denotes an upper bound of the number of bytes that a +string may contain. If m is not specified, as in the second +declaration, it is assumed to be (2**32) - 1, the maximum length. +The constant m would normally be found in a protocol specification. +For example, a filing protocol may state that a file name can be no +longer than 255 bytes, as follows: +.DS +.ft CW +string filename<255>; +.DE +Which can be illustrated as: +.ie t .DS +.el .DS L +\fIA String\fP + +\f(CW0 1 2 3 4 5 ... ++-----+-----+-----+-----+-----+-----+...+-----+-----+...+-----+ +| length n |byte0|byte1|...| n-1 | 0 |...| 0 | ++-----+-----+-----+-----+-----+-----+...+-----+-----+...+-----+ +|<-------4 bytes------->|<------n bytes------>|<---r bytes--->| +|<----n+r (where (n+r) mod 4 = 0)---->|\fP +.DE +.LP +It is an error to encode a length greater than the maximum +described in the specification. +.NH 2 +\&Fixed-length Array +.IX XDR "fixed-length array" +.IX XDR "array, fixed length" +.LP +Declarations for fixed-length arrays of homogeneous elements are in +the following form: +.DS +.ft CW +type-name identifier[n]; +.DE +Fixed-length arrays of elements numbered 0 through n-1 are encoded by +individually encoding the elements of the array in their natural +order, 0 through n-1. Each element's size is a multiple of four +bytes. Though all elements are of the same type, the elements may +have different sizes. For example, in a fixed-length array of +strings, all elements are of type "string", yet each element will +vary in its length. +.ie t .DS +.el .DS L +\fIFixed-Length Array\fP + +\f(CW+---+---+---+---+---+---+---+---+...+---+---+---+---+ +| element 0 | element 1 |...| element n-1 | ++---+---+---+---+---+---+---+---+...+---+---+---+---+ +|<--------------------n elements------------------->|\fP +.DE +.NH 2 +\&Variable-length Array +.IX XDR "variable-length array" +.IX XDR "array, variable length" +.LP +Counted arrays provide the ability to encode variable-length arrays +of homogeneous elements. The array is encoded as the element count n +(an unsigned integer) followed by the encoding of each of the array's +elements, starting with element 0 and progressing through element n- +1. The declaration for variable-length arrays follows this form: +.DS +.ft CW +type-name identifier<m>; +.DE +or +.DS +.ft CW +type-name identifier<>; +.DE +The constant m specifies the maximum acceptable element count of an +array; if m is not specified, as in the second declaration, it is +assumed to be (2**32) - 1. +.ie t .DS +.el .DS L +\fICounted Array\fP + +\f(CW0 1 2 3 ++--+--+--+--+--+--+--+--+--+--+--+--+...+--+--+--+--+ +| n | element 0 | element 1 |...|element n-1| ++--+--+--+--+--+--+--+--+--+--+--+--+...+--+--+--+--+ +|<-4 bytes->|<--------------n elements------------->|\fP +.DE +It is an error to encode a value of n that is greater than the +maximum described in the specification. +.NH 2 +\&Structure +.IX XDR structure +.LP +Structures are declared as follows: +.DS +.ft CW +struct { + component-declaration-A; + component-declaration-B; + \&... +} identifier; +.DE +The components of the structure are encoded in the order of their +declaration in the structure. Each component's size is a multiple of +four bytes, though the components may be different sizes. +.ie t .DS +.el .DS L +\fIStructure\fP + +\f(CW+-------------+-------------+... +| component A | component B |... ++-------------+-------------+...\fP +.DE +.NH 2 +\&Discriminated Union +.IX XDR "discriminated union" +.IX XDR union discriminated +.LP +A discriminated union is a type composed of a discriminant followed +by a type selected from a set of prearranged types according to the +value of the discriminant. The type of discriminant is either "int", +"unsigned int", or an enumerated type, such as "bool". The component +types are called "arms" of the union, and are preceded by the value +of the discriminant which implies their encoding. Discriminated +unions are declared as follows: +.DS +.ft CW +union switch (discriminant-declaration) { + case discriminant-value-A: + arm-declaration-A; + case discriminant-value-B: + arm-declaration-B; + \&... + default: default-declaration; +} identifier; +.DE +Each "case" keyword is followed by a legal value of the discriminant. +The default arm is optional. If it is not specified, then a valid +encoding of the union cannot take on unspecified discriminant values. +The size of the implied arm is always a multiple of four bytes. +.LP +The discriminated union is encoded as its discriminant followed by +the encoding of the implied arm. +.ie t .DS +.el .DS L +\fIDiscriminated Union\fP + +\f(CW0 1 2 3 ++---+---+---+---+---+---+---+---+ +| discriminant | implied arm | ++---+---+---+---+---+---+---+---+ +|<---4 bytes--->|\fP +.DE +.NH 2 +\&Void +.IX XDR void +.LP +An XDR void is a 0-byte quantity. Voids are useful for describing +operations that take no data as input or no data as output. They are +also useful in unions, where some arms may contain data and others do +not. The declaration is simply as follows: +.DS +.ft CW +void; +.DE +Voids are illustrated as follows: +.ie t .DS +.el .DS L +\fIVoid\fP + +\f(CW ++ + || + ++ +--><-- 0 bytes\fP +.DE +.NH 2 +\&Constant +.IX XDR constant +.LP +The data declaration for a constant follows this form: +.DS +.ft CW +const name-identifier = n; +.DE +"const" is used to define a symbolic name for a constant; it does not +declare any data. The symbolic constant may be used anywhere a +regular constant may be used. For example, the following defines a +symbolic constant DOZEN, equal to 12. +.DS +.ft CW +const DOZEN = 12; +.DE +.NH 2 +\&Typedef +.IX XDR typedef +.LP +"typedef" does not declare any data either, but serves to define new +identifiers for declaring data. The syntax is: +.DS +.ft CW +typedef declaration; +.DE +The new type name is actually the variable name in the declaration +part of the typedef. For example, the following defines a new type +called "eggbox" using an existing type called "egg": +.DS +.ft CW +typedef egg eggbox[DOZEN]; +.DE +Variables declared using the new type name have the same type as the +new type name would have in the typedef, if it was considered a +variable. For example, the following two declarations are equivalent +in declaring the variable "fresheggs": +.DS +.ft CW +eggbox fresheggs; +egg fresheggs[DOZEN]; +.DE +When a typedef involves a struct, enum, or union definition, there is +another (preferred) syntax that may be used to define the same type. +In general, a typedef of the following form: +.DS +.ft CW +typedef <<struct, union, or enum definition>> identifier; +.DE +may be converted to the alternative form by removing the "typedef" +part and placing the identifier after the "struct", "union", or +"enum" keyword, instead of at the end. For example, here are the two +ways to define the type "bool": +.DS +.ft CW +typedef enum { /* \fIusing typedef\fP */ + FALSE = 0, + TRUE = 1 + } bool; + +enum bool { /* \fIpreferred alternative\fP */ + FALSE = 0, + TRUE = 1 + }; +.DE +The reason this syntax is preferred is one does not have to wait +until the end of a declaration to figure out the name of the new +type. +.NH 2 +\&Optional-data +.IX XDR "optional data" +.IX XDR "data, optional" +.LP +Optional-data is one kind of union that occurs so frequently that we +give it a special syntax of its own for declaring it. It is declared +as follows: +.DS +.ft CW +type-name *identifier; +.DE +This is equivalent to the following union: +.DS +.ft CW +union switch (bool opted) { + case TRUE: + type-name element; + case FALSE: + void; +} identifier; +.DE +It is also equivalent to the following variable-length array +declaration, since the boolean "opted" can be interpreted as the +length of the array: +.DS +.ft CW +type-name identifier<1>; +.DE +Optional-data is not so interesting in itself, but it is very useful +for describing recursive data-structures such as linked-lists and +trees. For example, the following defines a type "stringlist" that +encodes lists of arbitrary length strings: +.DS +.ft CW +struct *stringlist { + string item<>; + stringlist next; +}; +.DE +It could have been equivalently declared as the following union: +.DS +.ft CW +union stringlist switch (bool opted) { + case TRUE: + struct { + string item<>; + stringlist next; + } element; + case FALSE: + void; +}; +.DE +or as a variable-length array: +.DS +.ft CW +struct stringlist<1> { + string item<>; + stringlist next; +}; +.DE +Both of these declarations obscure the intention of the stringlist +type, so the optional-data declaration is preferred over both of +them. The optional-data type also has a close correlation to how +recursive data structures are represented in high-level languages +such as Pascal or C by use of pointers. In fact, the syntax is the +same as that of the C language for pointers. +.NH 2 +\&Areas for Future Enhancement +.IX XDR futures +.LP +The XDR standard lacks representations for bit fields and bitmaps, +since the standard is based on bytes. Also missing are packed (or +binary-coded) decimals. +.LP +The intent of the XDR standard was not to describe every kind of data +that people have ever sent or will ever want to send from machine to +machine. Rather, it only describes the most commonly used data-types +of high-level languages such as Pascal or C so that applications +written in these languages will be able to communicate easily over +some medium. +.LP +One could imagine extensions to XDR that would let it describe almost +any existing protocol, such as TCP. The minimum necessary for this +are support for different block sizes and byte-orders. The XDR +discussed here could then be considered the 4-byte big-endian member +of a larger XDR family. +.NH 1 +\&Discussion +.sp 2 +.NH 2 +\&Why a Language for Describing Data? +.IX XDR language +.LP +There are many advantages in using a data-description language such +as XDR versus using diagrams. Languages are more formal than +diagrams and lead to less ambiguous descriptions of data. +Languages are also easier to understand and allow one to think of +other issues instead of the low-level details of bit-encoding. +Also, there is a close analogy between the types of XDR and a +high-level language such as C or Pascal. This makes the +implementation of XDR encoding and decoding modules an easier task. +Finally, the language specification itself is an ASCII string that +can be passed from machine to machine to perform on-the-fly data +interpretation. +.NH 2 +\&Why Only one Byte-Order for an XDR Unit? +.IX XDR "byte order" +.LP +Supporting two byte-orderings requires a higher level protocol for +determining in which byte-order the data is encoded. Since XDR is +not a protocol, this can't be done. The advantage of this, though, +is that data in XDR format can be written to a magnetic tape, for +example, and any machine will be able to interpret it, since no +higher level protocol is necessary for determining the byte-order. +.NH 2 +\&Why does XDR use Big-Endian Byte-Order? +.LP +Yes, it is unfair, but having only one byte-order means you have to +be unfair to somebody. Many architectures, such as the Motorola +68000 and IBM 370, support the big-endian byte-order. +.NH 2 +\&Why is the XDR Unit Four Bytes Wide? +.LP +There is a tradeoff in choosing the XDR unit size. Choosing a small +size such as two makes the encoded data small, but causes alignment +problems for machines that aren't aligned on these boundaries. A +large size such as eight means the data will be aligned on virtually +every machine, but causes the encoded data to grow too big. We chose +four as a compromise. Four is big enough to support most +architectures efficiently, except for rare machines such as the +eight-byte aligned Cray. Four is also small enough to keep the +encoded data restricted to a reasonable size. +.NH 2 +\&Why must Variable-Length Data be Padded with Zeros? +.IX XDR "variable-length data" +.LP +It is desirable that the same data encode into the same thing on all +machines, so that encoded data can be meaningfully compared or +checksummed. Forcing the padded bytes to be zero ensures this. +.NH 2 +\&Why is there No Explicit Data-Typing? +.LP +Data-typing has a relatively high cost for what small advantages it +may have. One cost is the expansion of data due to the inserted type +fields. Another is the added cost of interpreting these type fields +and acting accordingly. And most protocols already know what type +they expect, so data-typing supplies only redundant information. +However, one can still get the benefits of data-typing using XDR. One +way is to encode two things: first a string which is the XDR data +description of the encoded data, and then the encoded data itself. +Another way is to assign a value to all the types in XDR, and then +define a universal type which takes this value as its discriminant +and for each value, describes the corresponding data type. +.NH 1 +\&The XDR Language Specification +.IX XDR language +.sp 1 +.NH 2 +\&Notational Conventions +.IX "XDR language" notation +.LP +This specification uses an extended Backus-Naur Form notation for +describing the XDR language. Here is a brief description of the +notation: +.IP 1. +The characters +.I | , +.I ( , +.I ) , +.I [ , +.I ] , +.I " , +and +.I * +are special. +.IP 2. +Terminal symbols are strings of any characters surrounded by +double quotes. +.IP 3. +Non-terminal symbols are strings of non-special characters. +.IP 4. +Alternative items are separated by a vertical bar ("\fI|\fP"). +.IP 5. +Optional items are enclosed in brackets. +.IP 6. +Items are grouped together by enclosing them in parentheses. +.IP 7. +A +.I * +following an item means 0 or more occurrences of that item. +.LP +For example, consider the following pattern: +.DS L +"a " "very" (", " " very")* [" cold " "and"] " rainy " ("day" | "night") +.DE +.LP +An infinite number of strings match this pattern. A few of them +are: +.DS +"a very rainy day" +"a very, very rainy day" +"a very cold and rainy day" +"a very, very, very cold and rainy night" +.DE +.NH 2 +\&Lexical Notes +.IP 1. +Comments begin with '/*' and terminate with '*/'. +.IP 2. +White space serves to separate items and is otherwise ignored. +.IP 3. +An identifier is a letter followed by an optional sequence of +letters, digits or underbar ('_'). The case of identifiers is +not ignored. +.IP 4. +A constant is a sequence of one or more decimal digits, +optionally preceded by a minus-sign ('-'). +.NH 2 +\&Syntax Information +.IX "XDR language" syntax +.DS +.ft CW +declaration: + type-specifier identifier + | type-specifier identifier "[" value "]" + | type-specifier identifier "<" [ value ] ">" + | "opaque" identifier "[" value "]" + | "opaque" identifier "<" [ value ] ">" + | "string" identifier "<" [ value ] ">" + | type-specifier "*" identifier + | "void" +.DE +.DS +.ft CW +value: + constant + | identifier + +type-specifier: + [ "unsigned" ] "int" + | [ "unsigned" ] "hyper" + | "float" + | "double" + | "bool" + | enum-type-spec + | struct-type-spec + | union-type-spec + | identifier +.DE +.DS +.ft CW +enum-type-spec: + "enum" enum-body + +enum-body: + "{" + ( identifier "=" value ) + ( "," identifier "=" value )* + "}" +.DE +.DS +.ft CW +struct-type-spec: + "struct" struct-body + +struct-body: + "{" + ( declaration ";" ) + ( declaration ";" )* + "}" +.DE +.DS +.ft CW +union-type-spec: + "union" union-body + +union-body: + "switch" "(" declaration ")" "{" + ( "case" value ":" declaration ";" ) + ( "case" value ":" declaration ";" )* + [ "default" ":" declaration ";" ] + "}" + +constant-def: + "const" identifier "=" constant ";" +.DE +.DS +.ft CW +type-def: + "typedef" declaration ";" + | "enum" identifier enum-body ";" + | "struct" identifier struct-body ";" + | "union" identifier union-body ";" + +definition: + type-def + | constant-def + +specification: + definition * +.DE +.NH 3 +\&Syntax Notes +.IX "XDR language" syntax +.LP +.IP 1. +The following are keywords and cannot be used as identifiers: +"bool", "case", "const", "default", "double", "enum", "float", +"hyper", "opaque", "string", "struct", "switch", "typedef", "union", +"unsigned" and "void". +.IP 2. +Only unsigned constants may be used as size specifications for +arrays. If an identifier is used, it must have been declared +previously as an unsigned constant in a "const" definition. +.IP 3. +Constant and type identifiers within the scope of a specification +are in the same name space and must be declared uniquely within this +scope. +.IP 4. +Similarly, variable names must be unique within the scope of +struct and union declarations. Nested struct and union declarations +create new scopes. +.IP 5. +The discriminant of a union must be of a type that evaluates to +an integer. That is, "int", "unsigned int", "bool", an enumerated +type or any typedefed type that evaluates to one of these is legal. +Also, the case values must be one of the legal values of the +discriminant. Finally, a case value may not be specified more than +once within the scope of a union declaration. +.NH 1 +\&An Example of an XDR Data Description +.LP +Here is a short XDR data description of a thing called a "file", +which might be used to transfer files from one machine to another. +.ie t .DS +.el .DS L +.ft CW + +const MAXUSERNAME = 32; /*\fI max length of a user name \fP*/ +const MAXFILELEN = 65535; /*\fI max length of a file \fP*/ +const MAXNAMELEN = 255; /*\fI max length of a file name \fP*/ + +.ft I +/* + * Types of files: + */ +.ft CW + +enum filekind { + TEXT = 0, /*\fI ascii data \fP*/ + DATA = 1, /*\fI raw data \fP*/ + EXEC = 2 /*\fI executable \fP*/ +}; + +.ft I +/* + * File information, per kind of file: + */ +.ft CW + +union filetype switch (filekind kind) { + case TEXT: + void; /*\fI no extra information \fP*/ + case DATA: + string creator<MAXNAMELEN>; /*\fI data creator \fP*/ + case EXEC: + string interpretor<MAXNAMELEN>; /*\fI program interpretor \fP*/ +}; + +.ft I +/* + * A complete file: + */ +.ft CW + +struct file { + string filename<MAXNAMELEN>; /*\fI name of file \fP*/ + filetype type; /*\fI info about file \fP*/ + string owner<MAXUSERNAME>; /*\fI owner of file \fP*/ + opaque data<MAXFILELEN>; /*\fI file data \fP*/ +}; +.DE +.LP +Suppose now that there is a user named "john" who wants to store +his lisp program "sillyprog" that contains just the data "(quit)". +His file would be encoded as follows: +.TS +box tab (&) ; +lfI lfI lfI lfI +rfL rfL rfL l . +Offset&Hex Bytes&ASCII&Description +_ +0&00 00 00 09&....&Length of filename = 9 +4&73 69 6c 6c&sill&Filename characters +8&79 70 72 6f&ypro& ... and more characters ... +12&67 00 00 00&g...& ... and 3 zero-bytes of fill +16&00 00 00 02&....&Filekind is EXEC = 2 +20&00 00 00 04&....&Length of interpretor = 4 +24&6c 69 73 70&lisp&Interpretor characters +28&00 00 00 04&....&Length of owner = 4 +32&6a 6f 68 6e&john&Owner characters +36&00 00 00 06&....&Length of file data = 6 +40&28 71 75 69&(qui&File data bytes ... +44&74 29 00 00&t)..& ... and 2 zero-bytes of fill +.TE +.NH 1 +\&References +.LP +[1] Brian W. Kernighan & Dennis M. Ritchie, "The C Programming +Language", Bell Laboratories, Murray Hill, New Jersey, 1978. +.LP +[2] Danny Cohen, "On Holy Wars and a Plea for Peace", IEEE Computer, +October 1981. +.LP +[3] "IEEE Standard for Binary Floating-Point Arithmetic", ANSI/IEEE +Standard 754-1985, Institute of Electrical and Electronics +Engineers, August 1985. +.LP +[4] "Courier: The Remote Procedure Call Protocol", XEROX +Corporation, XSIS 038112, December 1981. diff --git a/cpukit/librpc/src/rpc/README b/cpukit/librpc/src/rpc/README index e69de29bb2..ad9d70f990 100644 --- a/cpukit/librpc/src/rpc/README +++ b/cpukit/librpc/src/rpc/README @@ -0,0 +1,233 @@ +RPCSRC 4.0 7/11/89 + +This distribution contains Sun Microsystem's implementation of the +RPC and XDR protocols and is compatible with 4.2BSD and 4.3BSD. Also +included is complete documentation, utilities, RPC service +specification files, and demonstration services in the format used by +the RPC protocol compiler (rpcgen). See WHAT'S NEW below for +details. + +NOTE ABOUT SECURE RPC: + +This release of RPCSRC contains most of the code needed to implement +Secure RPC (see "DES Authentication" in the RPC Protocol Specification, +doc/rpc.rfc.ms). Due to legal considerations, we are unable to +distribute an implementation of DES, the Data Encryption Standard, which +Secure RPC requires. For this reason, all of the files, documentation, and +programs associated with Secure RPC have been placed into a separate +directory, secure_rpc. The RPC library contained in the main body of this +release *DOES NOT* support Secure RPC. See secure_rpc/README for more +details. (A DES library was posted in Volume 18 of comp.sources.unix.) + +If you wish to report bugs found in this release, send mail to: + +Portable ONC/NFS +Sun Microsystems, Inc +MS 12-33 +2550 Garcia Avenue +Mountain View, CA 94043 + +or send Email to nfsnet@sun.com (the Internet) or sun!nfsnet (Usenet). + +ROADMAP + +The directory hierarchy is as follows: + + demo/ Various demonstration services + demo/dir Remote directory lister + demo/msg Remote console message delivery service + demo/sort Remote sort service + + doc/ Documentation for RPC, XDR and NFS in "-ms" format. + + etc/ Utilities (rpcinfo and portmap). portmap must be + started by root before any other RPC network services are + used. SEE BELOW FOR BUGFIX TO 4.3BSD COMPILER. + + man/ Manual pages for RPC library, rpcgen, and utilities. + + rpc/ The RPC and XDR library. SEE BELOW + FOR BUGFIX TO 4.2BSD COMPILER. + + rpcgen/ The RPC Language compiler (for .x files) + + rpcsvc/ Service definition files for various services and the + server and client code for the Remote Status service. + + secure_rpc/ The files in this directory are used to build a version of + the RPC library with DES Authentication. See the README + file in that directory for more details. + +BUILD INSTRUCTIONS + +Makefiles can be found in all directories except for man. The +Makefile in the top directory will cause these others to be invoked +(except for in the doc, man and demo directories), in turn building the +entire release. + +WARNING! THE DEFAULT INSTALLATION PROCEDURES WILL INSTALL FILES +IN /usr/include, /usr/lib, /usr/bin and /etc. + +The master RPC include file, rpc/rpc.h, is used by all programs and +routines that use RPC. It includes other RPC and system include files +needed by the RPC system. PLEASE NOTE: If your system has NFS, it +may have been based on Sun's NFS Source. The include files installed +by this package may duplicate include files you will find on your NFS +system. The RPCSRC 4.0 include files are upwardly compatible to all +NFS Source include files as of the date of this distribution (not +including any new definitions or declarations added by your system +vendor). HOWEVER: Please read the comments towards the end of +rpc/rpc.h regarding rpc/netdb.h. You may need to uncomment the +inclusion of that file if the structures it defines are already +defined by your system's include files. + +After making any compiler fixes that are needed (see below), at +the top directory, type: + + make install + +For all installations, the Makefile macro DESTDIR is prepended to the +installation path. It is defined to be null in the Makefiles, so +installations are relative to root. (You will probably need root +privileges for installing the files under the default path.) To +install the files under some other tree (e.g., /usr/local), use the +command: + + make install DESTDIR=/usr/local + +This will place the include files in /usr/local/usr/include, the RPC +library in /usr/local/usr/lib, rpcgen in /usr/local/usr/bin, and the +utilities in /usr/local/etc. You'll have to edit the Makefiles or +install the files by hand if you want to do anything other than this +kind of relocation of the installation tree. + +The RPC library will be built and installed first. By default it is +installed in /usr/lib as "librpclib.a". The directory +/usr/include/rpc will also be created, and several header files will +be installed there. ALL RPC SERVICES INCLUDE THESE HEADER FILES. + +The programs in etc/ link in routines from librpclib.a. If you change +where it is installed, be sure to edit etc/'s Makefile to reflect this. +These programs are installed in /etc. PORTMAP MUST BE RUNNING ON +YOUR SYSTEM BEFORE YOU START ANY OTHER RPC SERVICE. + +rpcgen is installed in /usr/bin. This program is required to build +the demonstration services in demo and the rstat client and server in +rpcsvc/. + +The rpcsvc/ directory will install its files in the directory +/usr/include/rpcsvc. The Remote Status service (rstat_svc) will be +compiled and installed in /etc. If you wish to make this service +available, you should either start this service when needed or have +it started at boot time by invoking it in your /etc/rc.local script. +(Be sure that portmap is started first!) Sun has modified its +version of inetd to automatically start RPC services. (Use "make +LIB=" when building rstat on a Sun Workstation.) The Remote Status +client (rstat) will be installed in /usr/bin. This program queries +the rstat_svc on a remote host and prints a system status summary +similar to the one printed by "uptime". + +The documentation is not built during the "make install" command. +Typing "make" in the doc directory will cause all of the manuals to +be formatted using nroff into a single file. We have had a report +that certain "troff" equivalents have trouble processing the full +manual. If you have trouble, try building the manuals i |