diff options
6 files changed, 9252 insertions, 0 deletions
diff --git a/package/libtirpc/libtirpc-0005-rpcent-mark-getrpcbyname-name-argument-as-const-char.patch b/package/libtirpc/libtirpc-0005-rpcent-mark-getrpcbyname-name-argument-as-const-char.patch new file mode 100644 index 000000000..b1865aee7 --- /dev/null +++ b/package/libtirpc/libtirpc-0005-rpcent-mark-getrpcbyname-name-argument-as-const-char.patch @@ -0,0 +1,43 @@ +From 88147b753b86df7e7505ef8150f1329f7c6951cc Mon Sep 17 00:00:00 2001 +From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +Date: Fri, 9 Nov 2012 19:37:24 +0100 +Subject: [PATCH] rpcent: mark getrpcbyname name argument as const char * + +This allows to match the glibc prototype and avoid compiling error +when building libtirpc against a C library that has RPC support. + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +--- + src/getrpcent.c | 2 +- + tirpc/rpc/rpcent.h | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/getrpcent.c b/src/getrpcent.c +index 645f18f..1b54b6d 100644 +--- a/src/getrpcent.c ++++ b/src/getrpcent.c +@@ -138,7 +138,7 @@ no_yp: + + struct rpcent * + getrpcbyname(name) +- char *name; ++ const char *name; + { + struct rpcent *rpc = NULL; + char **rp; +diff --git a/tirpc/rpc/rpcent.h b/tirpc/rpc/rpcent.h +index 8ce05ed..120801d 100644 +--- a/tirpc/rpc/rpcent.h ++++ b/tirpc/rpc/rpcent.h +@@ -61,7 +61,7 @@ extern struct rpcent *getrpcbynumber_r(int, struct rpcent *, char *, int); + extern struct rpcent *getrpcent_r(struct rpcent *, char *, int); + + /* Old interfaces that return a pointer to a static area; MT-unsafe */ +-extern struct rpcent *getrpcbyname(char *); ++extern struct rpcent *getrpcbyname(const char *); + extern struct rpcent *getrpcbynumber(int); + extern struct rpcent *getrpcent(void); + #endif +-- +1.7.9.5 + diff --git a/package/libtirpc/libtirpc-0006-rpcent-remove-prototypes-of-reentrant-variants.patch b/package/libtirpc/libtirpc-0006-rpcent-remove-prototypes-of-reentrant-variants.patch new file mode 100644 index 000000000..1fdc310ef --- /dev/null +++ b/package/libtirpc/libtirpc-0006-rpcent-remove-prototypes-of-reentrant-variants.patch @@ -0,0 +1,33 @@ +From 8e02780905a3e13405a5a1b9f5b2e77655d5c7fb Mon Sep 17 00:00:00 2001 +From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +Date: Sat, 10 Nov 2012 00:05:23 +0100 +Subject: [PATCH] rpcent: remove prototypes of reentrant variants + +The reentrant variants of getrpcbynumber() and al. are not implemented +by libtirpc, so there is no point in advertising them in this header +file. + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +--- + tirpc/rpc/rpcent.h | 5 ----- + 1 file changed, 5 deletions(-) + +diff --git a/tirpc/rpc/rpcent.h b/tirpc/rpc/rpcent.h +index 120801d..45775ed 100644 +--- a/tirpc/rpc/rpcent.h ++++ b/tirpc/rpc/rpcent.h +@@ -55,11 +55,6 @@ struct rpcent { + int r_number; /* rpc program number */ + }; + +-extern struct rpcent *getrpcbyname_r(const char *, struct rpcent *, +- char *, int); +-extern struct rpcent *getrpcbynumber_r(int, struct rpcent *, char *, int); +-extern struct rpcent *getrpcent_r(struct rpcent *, char *, int); +- + /* Old interfaces that return a pointer to a static area; MT-unsafe */ + extern struct rpcent *getrpcbyname(const char *); + extern struct rpcent *getrpcbynumber(int); +-- +1.7.9.5 + diff --git a/package/libtirpc/libtirpc-0007-doc-Makefile.am-fix-out-of-tree-installation.patch b/package/libtirpc/libtirpc-0007-doc-Makefile.am-fix-out-of-tree-installation.patch new file mode 100644 index 000000000..c31992c12 --- /dev/null +++ b/package/libtirpc/libtirpc-0007-doc-Makefile.am-fix-out-of-tree-installation.patch @@ -0,0 +1,24 @@ +From 4cf0371c96abf83483835daf50d3fc3bf793bdc4 Mon Sep 17 00:00:00 2001 +From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +Date: Sat, 10 Nov 2012 17:29:12 +0100 +Subject: [PATCH] doc/Makefile.am: fix out-of-tree installation + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +--- + doc/Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/doc/Makefile.am b/doc/Makefile.am +index cc4fa76..bac7c0f 100644 +--- a/doc/Makefile.am ++++ b/doc/Makefile.am +@@ -1,5 +1,5 @@ + + install: install-am + $(mkinstalldirs) $(DESTDIR)/etc +- cp -p ./etc_netconfig $(DESTDIR)/etc/netconfig ++ cp -p $(srcdir)/etc_netconfig $(DESTDIR)/etc/netconfig + chmod 0644 $(DESTDIR)/etc/netconfig +-- +1.7.9.5 + diff --git a/package/libtirpc/libtirpc-0008-Add-rpcgen-program-from-nfs-utils-sources.patch b/package/libtirpc/libtirpc-0008-Add-rpcgen-program-from-nfs-utils-sources.patch new file mode 100644 index 000000000..27c60649d --- /dev/null +++ b/package/libtirpc/libtirpc-0008-Add-rpcgen-program-from-nfs-utils-sources.patch @@ -0,0 +1,6504 @@ +From 8a1ee148ea860c20fa4e076839e5681412a11f7e Mon Sep 17 00:00:00 2001 +From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +Date: Sat, 10 Nov 2012 16:21:01 +0100 +Subject: [PATCH] Add rpcgen program from nfs-utils sources + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +--- + Makefile.am | 2 +- + configure.ac | 12 +- + rpcgen/Makefile.am | 22 ++ + rpcgen/rpc_clntout.c | 217 ++++++++++ + rpcgen/rpc_cout.c | 706 +++++++++++++++++++++++++++++++++ + rpcgen/rpc_hout.c | 490 +++++++++++++++++++++++ + rpcgen/rpc_main.c | 1067 ++++++++++++++++++++++++++++++++++++++++++++++++++ + rpcgen/rpc_output.h | 16 + + rpcgen/rpc_parse.c | 609 ++++++++++++++++++++++++++++ + rpcgen/rpc_parse.h | 166 ++++++++ + rpcgen/rpc_sample.c | 247 ++++++++++++ + rpcgen/rpc_scan.c | 474 ++++++++++++++++++++++ + rpcgen/rpc_scan.h | 103 +++++ + rpcgen/rpc_svcout.c | 882 +++++++++++++++++++++++++++++++++++++++++ + rpcgen/rpc_tblout.c | 165 ++++++++ + rpcgen/rpc_util.c | 479 ++++++++++++++++++++++ + rpcgen/rpc_util.h | 166 ++++++++ + rpcgen/rpcgen.1 | 521 ++++++++++++++++++++++++ + 18 files changed, 6342 insertions(+), 2 deletions(-) + create mode 100644 rpcgen/Makefile.am + create mode 100644 rpcgen/rpc_clntout.c + create mode 100644 rpcgen/rpc_cout.c + create mode 100644 rpcgen/rpc_hout.c + create mode 100644 rpcgen/rpc_main.c + create mode 100644 rpcgen/rpc_output.h + create mode 100644 rpcgen/rpc_parse.c + create mode 100644 rpcgen/rpc_parse.h + create mode 100644 rpcgen/rpc_sample.c + create mode 100644 rpcgen/rpc_scan.c + create mode 100644 rpcgen/rpc_scan.h + create mode 100644 rpcgen/rpc_svcout.c + create mode 100644 rpcgen/rpc_tblout.c + create mode 100644 rpcgen/rpc_util.c + create mode 100644 rpcgen/rpc_util.h + create mode 100644 rpcgen/rpcgen.1 + +diff --git a/Makefile.am b/Makefile.am +index 1a7596b..afb4e38 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -1,4 +1,4 @@ +-SUBDIRS = src man doc ++SUBDIRS = src man doc rpcgen + ACLOCAL_AMFLAGS = -I m4 + + nobase_include_HEADERS = tirpc/netconfig.h \ +diff --git a/configure.ac b/configure.ac +index 487ec83..7f35b48 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -29,6 +29,16 @@ AC_CHECK_HEADER(netinet/ip6.h, + + AC_CHECK_LIB([pthread], [pthread_create]) + ++AM_CONDITIONAL(CROSS_COMPILING, test $cross_compiling = yes) + +-AC_CONFIG_FILES([Makefile src/Makefile man/Makefile doc/Makefile]) ++AC_MSG_CHECKING([for a C compiler for build tools]) ++if test $cross_compiling = yes; then ++ AC_CHECK_PROGS(CC_FOR_BUILD, gcc cc) ++else ++ CC_FOR_BUILD=$CC ++fi ++AC_MSG_RESULT([$CC_FOR_BUILD]) ++AC_SUBST(CC_FOR_BUILD) ++ ++AC_CONFIG_FILES([Makefile src/Makefile man/Makefile doc/Makefile rpcgen/Makefile]) + AC_OUTPUT(libtirpc.pc) +diff --git a/rpcgen/Makefile.am b/rpcgen/Makefile.am +new file mode 100644 +index 0000000..2277b6f +--- /dev/null ++++ b/rpcgen/Makefile.am +@@ -0,0 +1,22 @@ ++COMPILE = $(CC_FOR_BUILD) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ ++ $(CPPFLAGS_FOR_BUILD) $(AM_CFLAGS) $(CFLAGS_FOR_BUILD) ++LINK = $(CC_FOR_BUILD) $(AM_CFLAGS) $(CFLAGS_FOR_BUILD) $(AM_LDFLAGS) $(LDFLAGS_FOR_BUILD) -o $@ ++ ++bin_PROGRAMS = rpcgen ++ ++rpcgen_SOURCES = \ ++ rpc_clntout.c \ ++ rpc_cout.c \ ++ rpc_hout.c \ ++ rpc_main.c \ ++ rpc_parse.c \ ++ rpc_sample.c \ ++ rpc_scan.c \ ++ rpc_svcout.c \ ++ rpc_tblout.c \ ++ rpc_util.c \ ++ rpc_parse.h \ ++ rpc_scan.h \ ++ rpc_util.h ++ ++dist_man1_MANS = rpcgen.1 +diff --git a/rpcgen/rpc_clntout.c b/rpcgen/rpc_clntout.c +new file mode 100644 +index 0000000..e2f4382 +--- /dev/null ++++ b/rpcgen/rpc_clntout.c +@@ -0,0 +1,217 @@ ++/* ++ * Copyright (c) 2009, Sun Microsystems, Inc. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions are met: ++ * - Redistributions of source code must retain the above copyright notice, ++ * this list of conditions and the following disclaimer. ++ * - 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. ++ * - Neither the name of Sun Microsystems, Inc. nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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. ++ */ ++ ++#if 0 ++static char sccsid[] = "@(#)rpc_clntout.c 1.11 89/02/22 (C) 1987 SMI"; ++#endif ++ ++/* ++ * rpc_clntout.c, Client-stub outputter for the RPC protocol compiler ++ * Copyright (C) 1987, Sun Microsytsems, Inc. ++ */ ++#include <stdio.h> ++#include <string.h> ++#include <rpc/types.h> ++#include "rpc_parse.h" ++#include "rpc_util.h" ++#include "rpc_output.h" ++ ++/* extern pdeclaration(); */ ++/* void printarglist(); */ ++ ++#define DEFAULT_TIMEOUT 25 /* in seconds */ ++static char RESULT[] = "clnt_res"; ++ ++static void write_program(definition *def); ++static void printbody(proc_list *proc); ++ ++ ++void ++write_stubs(void) ++{ ++ list *l; ++ definition *def; ++ ++ f_print(fout, ++ "\n/* Default timeout can be changed using clnt_control() */\n"); ++ f_print(fout, "static struct timeval TIMEOUT = { %d, 0 };\n", ++ DEFAULT_TIMEOUT); ++ for (l = defined; l != NULL; l = l->next) { ++ def = (definition *) l->val; ++ if (def->def_kind == DEF_PROGRAM) { ++ write_program(def); ++ } ++ } ++} ++ ++static void ++write_program(definition *def) ++{ ++ version_list *vp; ++ proc_list *proc; ++ ++ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { ++ for (proc = vp->procs; proc != NULL; proc = proc->next) { ++ f_print(fout, "\n"); ++ ptype(proc->res_prefix, proc->res_type, 1); ++ f_print(fout, "*\n"); ++ pvname(proc->proc_name, vp->vers_num); ++ printarglist(proc, "clnt", "CLIENT *"); ++ f_print(fout, "{\n"); ++ printbody(proc); ++ f_print(fout, "}\n"); ++ } ++ } ++} ++ ++/* ++ * Writes out declarations of procedure's argument list. ++ * In either ANSI C style, in one of old rpcgen style (pass by reference), ++ * or new rpcgen style (multiple arguments, pass by value); ++ */ ++ ++/* sample addargname = "clnt"; sample addargtype = "CLIENT * " */ ++ ++void ++printarglist(proc_list *proc, char *addargname, char *addargtype) ++{ ++ ++ decl_list *l; ++ ++ if (!newstyle) { /* old style: always pass arg by reference */ ++ if (Cflag) { /* C++ style heading */ ++ f_print(fout, "("); ++ ptype(proc->args.decls->decl.prefix, proc->args.decls->decl.type, 1); ++ f_print(fout, "*argp, %s%s)\n", addargtype, addargname); ++ } else { ++ f_print(fout, "(argp, %s)\n", addargname); ++ f_print(fout, "\t"); ++ ptype(proc->args.decls->decl.prefix, proc->args.decls->decl.type, 1); ++ f_print(fout, "*argp;\n"); ++ } ++ } else if (streq(proc->args.decls->decl.type, "void")) { ++ /* newstyle, 0 argument */ ++ if (Cflag) ++ f_print(fout, "(%s%s)\n", addargtype, addargname); ++ else ++ f_print(fout, "(%s)\n", addargname); ++ } else { ++ /* new style, 1 or multiple arguments */ ++ if (!Cflag) { ++ f_print(fout, "("); ++ for (l = proc->args.decls; l != NULL; l = l->next) ++ f_print(fout, "%s, ", l->decl.name); ++ f_print(fout, "%s)\n", addargname); ++ for (l = proc->args.decls; l != NULL; l = l->next) { ++ pdeclaration(proc->args.argname, &l->decl, 1, ";\n"); ++ } ++ } else { /* C++ style header */ ++ f_print(fout, "("); ++ for (l = proc->args.decls; l != NULL; l = l->next) { ++ pdeclaration(proc->args.argname, &l->decl, 0, ", "); ++ } ++ f_print(fout, " %s%s)\n", addargtype, addargname); ++ } ++ } ++ ++ if (!Cflag) ++ f_print(fout, "\t%s%s;\n", addargtype, addargname); ++} ++ ++ ++ ++static char * ++ampr(char *type) ++{ ++ if (isvectordef(type, REL_ALIAS)) { ++ return (""); ++ } else { ++ return ("&"); ++ } ++} ++ ++static void ++printbody(proc_list *proc) ++{ ++ decl_list *l; ++ bool_t args2 = (proc->arg_num > 1); ++ ++ /* For new style with multiple arguments, need a structure in which ++ * to stuff the arguments. */ ++ if (newstyle && args2) { ++ f_print(fout, "\t%s", proc->args.argname); ++ f_print(fout, " arg;\n"); ++ } ++ f_print(fout, "\tstatic "); ++ if (streq(proc->res_type, "void")) { ++ f_print(fout, "char "); ++ } else { ++ ptype(proc->res_prefix, proc->res_type, 0); ++ } ++ f_print(fout, "%s;\n", RESULT); ++ f_print(fout, "\n"); ++ f_print(fout, "\tmemset((char *)%s%s, 0, sizeof(%s));\n", ++ ampr(proc->res_type), RESULT, RESULT); ++ if (newstyle && !args2 && (streq(proc->args.decls->decl.type, "void"))) { ++ /* newstyle, 0 arguments */ ++ f_print(fout, ++ "\tif (clnt_call(clnt, %s, (xdrproc_t) xdr_void, (caddr_t) NULL, " ++ "(xdrproc_t) xdr_%s, (caddr_t) %s%s, TIMEOUT) != RPC_SUCCESS) {\n", ++ proc->proc_name, ++ stringfix(proc->res_type), ampr(proc->res_type), RESULT); ++ ++ } else if (newstyle && args2) { ++ /* newstyle, multiple arguments: stuff arguments into structure */ ++ for (l = proc->args.decls; l != NULL; l = l->next) { ++ f_print(fout, "\targ.%s = %s;\n", ++ l->decl.name, l->decl.name); ++ } ++ f_print(fout, ++ "\tif (clnt_call(clnt, %s, (xdrproc_t) xdr_%s, (caddr_t) &arg, " ++ "(xdrproc_t) xdr_%s, (caddr_t) %s%s, TIMEOUT) != RPC_SUCCESS) {\n", ++ proc->proc_name, proc->args.argname, ++ stringfix(proc->res_type), ampr(proc->res_type), RESULT); ++ } else { /* single argument, new or old style */ ++ f_print(fout, ++ "\tif (clnt_call(clnt, %s, (xdrproc_t) xdr_%s, " ++ "(caddr_t) %s%s, (xdrproc_t) xdr_%s, (caddr_t) %s%s, TIMEOUT) != RPC_SUCCESS) {\n", ++ proc->proc_name, ++ stringfix(proc->args.decls->decl.type), ++ (newstyle ? "&" : ""), ++ (newstyle ? proc->args.decls->decl.name : "argp"), ++ stringfix(proc->res_type), ampr(proc->res_type), RESULT); ++ } ++ f_print(fout, "\t\treturn (NULL);\n"); ++ f_print(fout, "\t}\n"); ++ if (streq(proc->res_type, "void")) { ++ f_print(fout, "\treturn ((void *)%s%s);\n", ++ ampr(proc->res_type), RESULT); ++ } else { ++ f_print(fout, "\treturn (%s%s);\n", ampr(proc->res_type), RESULT); ++ } ++} +diff --git a/rpcgen/rpc_cout.c b/rpcgen/rpc_cout.c +new file mode 100644 +index 0000000..a61214f +--- /dev/null ++++ b/rpcgen/rpc_cout.c +@@ -0,0 +1,706 @@ ++/* ++ * Copyright (c) 2009, Sun Microsystems, Inc. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions are met: ++ * - Redistributions of source code must retain the above copyright notice, ++ * this list of conditions and the following disclaimer. ++ * - 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. ++ * - Neither the name of Sun Microsystems, Inc. nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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. ++ */ ++ ++#if 0 ++static char sccsid[] = "@(#)rpc_cout.c 1.13 89/02/22 (C) 1987 SMI"; ++#endif ++ ++/* ++ * rpc_cout.c, XDR routine outputter for the RPC protocol compiler ++ */ ++#include <stdio.h> ++#include <string.h> ++#include <stdlib.h> ++#include <malloc.h> ++#include <ctype.h> ++#include "rpc_parse.h" ++#include "rpc_util.h" ++ ++static int findtype(definition *def, char *type); ++static int undefined(char *type); ++static void print_generic_header(char *procname, int pointerp); ++static void print_header(definition *def); ++static void print_prog_header(proc_list *plist); ++static void print_trailer(void); ++static void print_ifopen(int indent, char *name); ++static void print_ifarg(char *arg); ++static void print_ifsizeof(char *prefix, char *type); ++static void print_ifclose(int indent); ++static void print_ifstat(int indent, char *prefix, char *type, relation rel, ++ char *amax, char *objname, char *name); ++static void emit_enum(definition *def); ++static void emit_program(definition *def); ++static void emit_union(definition *def); ++static void emit_struct(definition *def); ++static void emit_typedef(definition *def); ++static void print_stat(int indent, declaration *dec); ++static void emit_inline(declaration *decl, int flag); ++static void emit_single_in_line(declaration *decl, int flag, relation rel); ++static char * upcase(char *str); ++ ++/* ++ * Emit the C-routine for the given definition ++ */ ++void ++emit(definition *def) ++{ ++ if (def->def_kind == DEF_CONST) { ++ return; ++ } ++ if (def->def_kind == DEF_PROGRAM) { ++ emit_program(def); ++ return; ++ } ++ if (def->def_kind == DEF_TYPEDEF) { ++ /* now we need to handle declarations like ++ * struct typedef foo foo; ++ * since we dont want this to be expanded into 2 calls ++ * to xdr_foo */ ++ ++ if (strcmp(def->def.ty.old_type, def->def_name) == 0) ++ return; ++ }; ++ ++ print_header(def); ++ switch (def->def_kind) { ++ case DEF_UNION: ++ emit_union(def); ++ break; ++ case DEF_ENUM: ++ emit_enum(def); ++ break; ++ case DEF_STRUCT: ++ emit_struct(def); ++ break; ++ case DEF_TYPEDEF: ++ emit_typedef(def); ++ break; ++ default: ++ break; ++ } ++ print_trailer(); ++} ++ ++static int ++findtype(definition *def, char *type) ++{ ++ ++ if (def->def_kind == DEF_PROGRAM || def->def_kind == DEF_CONST) { ++ return (0); ++ } else { ++ return (streq(def->def_name, type)); ++ } ++} ++ ++static int ++undefined(char *type) ++{ ++ definition *def; ++ ++ def = (definition *) FINDVAL(defined, type, findtype); ++ ++ return (def == NULL); ++} ++ ++ ++static void ++print_generic_header(char *procname, int pointerp) ++{ ++ f_print(fout, "\n"); ++ f_print(fout, "bool_t\n"); ++ if (Cflag) { ++ f_print(fout, "xdr_%s(", procname); ++ f_print(fout, "XDR *xdrs, "); ++ f_print(fout, "%s ", procname); ++ if (pointerp) ++ f_print(fout, "*"); ++ f_print(fout, "objp)\n{\n\n"); ++ } else { ++ f_print(fout, "xdr_%s(xdrs, objp)\n", procname); ++ f_print(fout, "\tXDR *xdrs;\n"); ++ f_print(fout, "\t%s ", procname); ++ if (pointerp) ++ f_print(fout, "*"); ++ f_print(fout, "objp;\n{\n\n"); ++ } ++} ++ ++static void ++print_header(definition *def) ++{ ++ print_generic_header(def->def_name, ++ def->def_kind != DEF_TYPEDEF || ++ !isvectordef(def->def.ty.old_type, def->def.ty.rel)); ++ ++ /* Now add Inline support */ ++ ++ ++ if (Inline == 0) ++ return; ++} ++ ++static void ++print_prog_header(proc_list *plist) ++{ ++ print_generic_header(plist->args.argname, 1); ++} ++ ++static void ++print_trailer(void) ++{ ++ f_print(fout, "\treturn (TRUE);\n"); ++ f_print(fout, "}\n"); ++} ++ ++ ++static void ++print_ifopen(int indent, char *name) ++{ ++ tabify(fout, indent); ++ f_print(fout, " if (!xdr_%s(xdrs", name); ++} ++ ++static void ++print_ifarg(char *arg) ++{ ++ f_print(fout, ", %s", arg); ++} ++ ++static void ++print_ifsizeof(char *prefix, char *type) ++{ ++ if (streq(type, "bool")) { ++ f_print(fout, ", sizeof(bool_t), (xdrproc_t)xdr_bool"); ++ } else { ++ f_print(fout, ", sizeof("); ++ if (undefined(type) && prefix) { ++ f_print(fout, "%s ", prefix); ++ } ++ f_print(fout, "%s), (xdrproc_t)xdr_%s", type, type); ++ } ++} ++ ++static void ++print_ifclose(int indent) ++{ ++ f_print(fout, ")) {\n"); ++ tabify(fout, indent); ++ f_print(fout, "\t return (FALSE);\n"); ++ tabify(fout, indent); ++ f_print(fout, " }\n"); ++} ++ ++static void ++print_ifstat(int indent, char *prefix, char *type, relation rel, ++ char *amax, char *objname, char *name) ++{ ++ char *alt = NULL; ++ ++ switch (rel) { ++ case REL_POINTER: ++ print_ifopen(indent, "pointer"); ++ print_ifarg("(char **)"); ++ f_print(fout, "%s", objname); ++ print_ifsizeof(prefix, type); ++ break; ++ case REL_VECTOR: ++ if (streq(type, "string")) { ++ alt = "string"; ++ } else if (streq(type, "opaque")) { ++ alt = "opaque"; ++ } ++ if (alt) { ++ print_ifopen(indent, alt); ++ print_ifarg(objname); ++ } else { ++ print_ifopen(indent, "vector"); ++ print_ifarg("(char *)"); ++ f_print(fout, "%s", objname); ++ } ++ print_ifarg(amax); ++ if (!alt) { ++ print_ifsizeof(prefix, type); ++ } ++ break; ++ case REL_ARRAY: ++ if (streq(type, "string")) { ++ alt = "string"; ++ } else if (streq(type, "opaque")) { ++ alt = "bytes"; ++ } ++ if (streq(type, "string")) { ++ print_ifopen(indent, alt); ++ print_ifarg(objname); ++ } else { ++ if (alt) { ++ print_ifopen(indent, alt); ++ } else { ++ print_ifopen(indent, "array"); ++ } ++ /* The (void*) avoids a gcc-4.1 warning */ ++ print_ifarg("(char **)(void*)"); ++ if (*objname == '&') { ++ f_print(fout, "%s.%s_val, (u_int *)%s.%s_len", ++ objname, name, objname, name); ++ } else { ++ f_print(fout, "&%s->%s_val, (u_int *)&%s->%s_len", ++ objname, name, objname, name); ++ } ++ } ++ print_ifarg(amax); ++ if (!alt) { ++ print_ifsizeof(prefix, type); ++ } ++ break; ++ case REL_ALIAS: ++ print_ifopen(indent, type); ++ print_ifarg(objname); ++ break; ++ } ++ print_ifclose(indent); ++} ++ ++static void ++emit_enum(definition *def) ++{ ++ print_ifopen(1, "enum"); ++ print_ifarg("(enum_t *)objp"); ++ print_ifclose(1); ++} ++ ++static void ++emit_program(definition *def) ++{ ++ decl_list *dl; ++ version_list *vlist; ++ proc_list *plist; ++ ++ for (vlist = def->def.pr.versions; vlist != NULL; vlist = vlist->next) ++ for (plist = vlist->procs; plist != NULL; plist = plist->next) { ++ if (!newstyle || plist->arg_num < 2) ++ continue;/* old style, or single argument */ ++ print_prog_header(plist); ++ for (dl = plist->args.decls; dl != NULL; dl = dl->next) ++ print_stat(1, &dl->decl); ++ print_trailer(); ++ } ++} ++ ++ ++static void ++emit_union(definition *def) ++{ ++ declaration *dflt; ++ case_list *cl; ++ declaration *cs; ++ char *object; ++ char *vecformat = "objp->%s_u.%s"; ++ char *format = "&objp->%s_u.%s"; ++ ++ print_stat(1,&def->def.un.enum_decl); ++ f_print(fout, "\tswitch (objp->%s) {\n", def->def.un.enum_decl.name); ++ for (cl = def->def.un.cases; cl != NULL; cl = cl->next) { ++ ++ f_print(fout, "\tcase %s:\n", cl->case_name); ++ if(cl->contflag == 1) /* a continued case statement */ ++ continue; ++ cs = &cl->case_decl; ++ if (!streq(cs->type, "void")) { ++ object = alloc(strlen(def->def_name) + strlen(format) + ++ strlen(cs->name) + 1); ++ if (isvectordef (cs->type, cs->rel)) { ++ s_print(object, vecformat, def->def_name, ++ cs->name); ++ } else { ++ s_print(object, format, def->def_name, ++ cs->name); ++ } ++ print_ifstat(2, cs->prefix, cs->type, cs->rel, cs->array_max, ++ object, cs->name); ++ free(object); ++ } ++ f_print(fout, "\t\tbreak;\n"); ++ } ++ dflt = def->def.un.default_decl; ++ if (dflt != NULL) { ++ if (!streq(dflt->type, "void")) { ++ f_print(fout, "\tdefault:\n"); ++ object = alloc(strlen(def->def_name) + strlen(format) + ++ strlen(dflt->name) + 1); ++ if (isvectordef (dflt->type, dflt->rel)) { ++ s_print(object, vecformat, def->def_name, ++ dflt->name); ++ } else { ++ s_print(object, format, def->def_name, ++ dflt->name); ++ } ++ ++ print_ifstat(2, dflt->prefix, dflt->type, dflt->rel, ++ dflt->array_max, object, dflt->name); ++ free(object); ++ f_print(fout, "\t\tbreak;\n"); ++ } else { ++ /* Avoid gcc warnings about `value not handled in switch' */ ++ f_print(fout, "\tdefault:\n"); ++ f_print(fout, "\t\tbreak;\n"); ++ } ++ } else { ++ f_print(fout, "\tdefault:\n"); ++ f_print(fout, "\t\treturn (FALSE);\n"); ++ } ++ ++ f_print(fout, "\t}\n"); ++} ++ ++static void ++emit_struct(definition *def) ++{ ++ decl_list *dl; ++ int i, j, size, flag; ++ decl_list *cur = NULL, *psav; ++ bas_type *ptr; ++ char *sizestr, *plus; ++ char ptemp[256]; ++ int can_inline; ++ const char *buf_declaration; ++ ++ ++ if (Inline == 0) { ++ for (dl = def->def.st.decls; dl != NULL; dl = dl->next) ++ print_stat(1, &dl->decl); ++ } else { ++ size = 0; ++ can_inline = 0; ++ for (dl = def->def.st.decls; dl != NULL; dl = dl->next) ++ if ((dl->decl.prefix == NULL) && ((ptr = find_type(dl->decl.type)) != NULL) && ((dl->decl.rel == REL_ALIAS) || (dl->decl.rel == REL_VECTOR))) { ++ ++ if (dl->decl.rel == REL_ALIAS) ++ size += ptr->length; ++ else { ++ can_inline = 1; ++ break; /* can be inlined */ ++ }; ++ } else { ++ if (size >= Inline) { ++ can_inline = 1; ++ break; /* can be inlined */ ++ } ++ size = 0; ++ } ++ if (size > Inline) ++ can_inline = 1; ++ ++ if (can_inline == 0) { /* can not inline, drop back to old mode */ ++ for (dl = def->def.st.decls; dl != NULL; dl = dl->next) ++ print_stat(1, &dl->decl); ++ return; ++ }; ++ ++ ++ ++ ++ flag = PUT; ++ for (j = 0; j < 2; j++) { ++ ++ if (flag == PUT) ++ f_print(fout, "\n\t if (xdrs->x_op == XDR_ENCODE) {\n"); ++ else ++ f_print(fout, "\n \t return (TRUE);\n\t} else if (xdrs->x_op == XDR_DECODE) {\n"); ++ ++ ++ i = 0; ++ size = 0; ++ sizestr = NULL; ++ buf_declaration = "int32_t *"; ++ for (dl = def->def.st.decls; dl != NULL; dl = dl->next) { /* xxx */ ++ ++ /* now walk down the list and check for basic types */ ++ if ((dl->decl.prefix == NULL) && ((ptr = find_type(dl->decl.type)) != NULL) && ((dl->decl.rel == REL_ALIAS) || (dl->decl.rel == REL_VECTOR))) { ++ if (i == 0) ++ cur = dl; ++ i++; ++ ++ if (dl->decl.rel == REL_ALIAS) ++ size += ptr->length; ++ else { ++ /* this is required to handle arrays */ ++ ++ if (sizestr == NULL) ++ plus = " "; ++ else ++ plus = "+"; ++ ++ if (ptr->length != 1) ++ s_print(ptemp, " %s %s * %d", plus, dl->decl.array_max, ptr->length); ++ else ++ s_print(ptemp, " %s %s ", plus, dl->decl.array_max); ++ ++ /*now concatenate to sizestr !!!! */ ++ if (sizestr == NULL) ++ sizestr = strdup(ptemp); ++ else { ++ sizestr = realloc(sizestr, strlen(sizestr) + strlen(ptemp) + 1); ++ if (sizestr == NULL) { ++ ++ f_print(stderr, "Fatal error : no memory \n"); ++ crash(); ++ }; ++ sizestr = strcat(sizestr, ptemp); /*build up length of array */ ++ ++ } ++ } ++ ++ } else { ++ if (i > 0) ++ { ++ if (sizestr == NULL && size < Inline) { ++ /* don't expand into inline code if size < inline */ ++ while (cur != dl) { ++ print_stat(1, &cur->decl); ++ cur = cur->next; ++ } ++ } else { ++ ++ ++ ++ /* were already looking at a xdr_inlineable structure */ ++ if (sizestr == NULL) ++ f_print(fout, "\t %sbuf = XDR_INLINE(xdrs,%d * BYTES_PER_XDR_UNIT);", ++ buf_declaration, size); ++ else if (size == 0) ++ f_print(fout, ++ "\t %sbuf = XDR_INLINE(xdrs,%s * BYTES_PER_XDR_UNIT);", ++ buf_declaration, sizestr); ++ else ++ f_print(fout, ++ "\t %sbuf = XDR_INLINE(xdrs,(%d + %s)* BYTES_PER_XDR_UNIT);", ++ buf_declaration, size, sizestr); ++ buf_declaration = ""; ++ ++ f_print(fout, "\n\t if (buf == NULL) {\n"); ++ ++ psav = cur; ++ while (cur != dl) { ++ print_stat(2, &cur->decl); ++ cur = cur->next; ++ } ++ ++ f_print(fout, "\n\t }\n\t else {\n"); ++ ++ cur = psav; ++ while (cur != dl) { ++ emit_inline(&cur->decl, flag); ++ cur = cur->next; ++ } ++ ++ f_print(fout, "\t }\n"); ++ } ++ } ++ size = 0; ++ i = 0; ++ sizestr = NULL; ++ print_stat(1, &dl->decl); ++ } ++ ++ } ++ if (i > 0) ++ { ++ if (sizestr == NULL && size < Inline) { ++ /* don't expand into inline code if size < inline */ ++ while (cur != dl) { ++ print_stat(1, &cur->decl); ++ cur = cur->next; ++ } ++ } else { ++ ++ /* were already looking at a xdr_inlineable structure */ ++ if (sizestr == NULL) ++ f_print(fout, "\t\t%sbuf = XDR_INLINE(xdrs,%d * BYTES_PER_XDR_UNIT);", ++ buf_declaration, size); ++ else if (size == 0) ++ f_print(fout, ++ "\t\t%sbuf = XDR_INLINE(xdrs,%s * BYTES_PER_XDR_UNIT);", ++ buf_declaration, sizestr); ++ else ++ f_print(fout, ++ "\t\t%sbuf = XDR_INLINE(xdrs,(%d + %s)* BYTES_PER_XDR_UNIT);", ++ buf_declaration, size, sizestr); ++ buf_declaration = ""; ++ ++ f_print(fout, "\n\t\tif (buf == NULL) {\n"); ++ ++ psav = cur; ++ while (cur != NULL) { ++ print_stat(2, &cur->decl); ++ cur = cur->next; ++ } ++ f_print(fout, "\n\t }\n\t else {\n"); ++ ++ cur = psav; ++ while (cur != dl) { ++ emit_inline(&cur->decl, flag); ++ cur = cur->next; ++ } ++ ++ f_print(fout, "\t }\n"); ++ ++ } ++ } ++ flag = GET; ++ } ++ f_print(fout, "\t return(TRUE);\n\t}\n\n"); ++ ++ /* now take care of XDR_FREE case */ ++ ++ for (dl = def->def.st.decls; dl != NULL; dl = dl->next) ++ print_stat(1, &dl->decl); ++ } ++} ++ ++ ++ ++ ++static void ++emit_typedef(definition *def) ++{ ++ char *prefix = def->def.ty.old_prefix; ++ char *type = def->def.ty.old_type; ++ char *amax = def->def.ty.array_max; ++ relation rel = def->def.ty.rel; ++ ++ ++ print_ifstat(1, prefix, type, rel, amax, "objp", def->def_name); ++} ++ ++static void ++print_stat(int indent, declaration *dec) ++{ ++ char *prefix = dec->prefix; ++ char *type = dec->type; ++ char *amax = dec->array_max; ++ relation rel = dec->rel; ++ char name[256]; ++ ++ if (isvectordef(type, rel)) { ++ s_print(name, "objp->%s", dec->name); ++ } else { ++ s_print(name, "&objp->%s", dec->name); ++ } ++ print_ifstat(indent, prefix, type, rel, amax, name, dec->name); ++} ++ ++ ++static void ++emit_inline(declaration *decl, int flag) ++{ ++ ++ /*check whether an array or not */ ++ ++ switch (decl->rel) { ++ case REL_ALIAS: ++ emit_single_in_line(decl, flag, REL_ALIAS); ++ break; ++ case REL_VECTOR: ++ f_print(fout, "\t\t{ register %s *genp; \n", decl->type); ++ f_print(fout, "\t\t int i;\n"); ++ f_print(fout, "\t\t for ( i = 0,genp=objp->%s;\n \t\t\ti < %s; i++){\n\t\t", ++ decl->name, decl->array_max); ++ emit_single_in_line(decl, flag, REL_VECTOR); ++ f_print(fout, "\t\t }\n\t\t };\n"); ++ break; ++ default: ++ break; ++ } ++} ++ ++static void ++emit_single_in_line(declaration *decl, int flag, relation rel) ++{ ++ char *upp_case; ++ int freed=0; ++ ++ if(flag == PUT) ++ f_print(fout,"\t\t (void) IXDR_PUT_"); ++ else ++ if(rel== REL_ALIAS) ++ f_print(fout,"\t\t objp->%s = IXDR_GET_",decl->name); ++ else ++ f_print(fout,"\t\t *genp++ = IXDR_GET_"); ++ ++ upp_case=upcase(decl->type); ++ ++ /* hack - XX */ ++ if(strcmp(upp_case,"INT") == 0) ++ { ++ free(upp_case); ++ freed=1; ++ upp_case="INT32"; ++ } ++ ++ if(strcmp(upp_case,"U_INT") == 0) ++ { ++ free(upp_case); ++ freed=1; ++ upp_case="U_INT32"; ++ } ++ ++ ++ if(flag == PUT) ++ if(rel== REL_ALIAS) ++ f_print(fout,"%s(buf,objp->%s);\n",upp_case,decl->name); ++ else ++ f_print(fout,"%s(buf,*genp++);\n",upp_case); ++ ++ else ++ f_print(fout,"%s(buf);\n",upp_case); ++ if(!freed) ++ free(upp_case); ++ ++} ++ ++ ++static char * ++upcase(char *str) ++{ ++ char *ptr, *hptr; ++ ++ ++ ptr = (char *) malloc(strlen(str)+1); ++ if (ptr == (char *) NULL) { ++ f_print(stderr, "malloc failed \n"); ++ exit(1); ++ }; ++ ++ hptr = ptr; ++ while (*str != '\0') ++ *ptr++ = toupper(*str++); ++ ++ *ptr = '\0'; ++ return (hptr); ++ ++} +diff --git a/rpcgen/rpc_hout.c b/rpcgen/rpc_hout.c +new file mode 100644 +index 0000000..ea1cb24 +--- /dev/null ++++ b/rpcgen/rpc_hout.c +@@ -0,0 +1,490 @@ ++/* ++ * Copyright (c) 2009, Sun Microsystems, Inc. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions are met: ++ * - Redistributions of source code must retain the above copyright notice, ++ * this list of conditions and the following disclaimer. ++ * - 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. ++ * - Neither the name of Sun Microsystems, Inc. nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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. ++ */ ++ ++#if 0 ++static char sccsid[] = "@(#)rpc_hout.c 1.12 89/02/22 (C) 1987 SMI"; ++#endif ++ ++/* ++ * rpc_hout.c, Header file outputter for the RPC protocol compiler ++ */ ++#include <stdio.h> ++#include <ctype.h> ++#include "rpc_parse.h" ++#include "rpc_util.h" ++#include "rpc_output.h" ++ ++ ++static int undefined2(char *type, char *stop); ++static void pxdrfuncdecl(char *name, int pointerp); ++static void pconstdef(definition *def); ++static void pargdef(definition *def); ++static void pstructdef(definition *def); ++static void puniondef(definition *def); ++static void pdefine(char *name, char *num); ++static void puldefine(char *name, char *num); ++static int define_printed(proc_list *stop, version_list *start); ++static void pprogramdef(definition *def); ++static void pprocdef(proc_list *proc, version_list *vp, ++ char *addargtype, int server_p, int mode); ++static void parglist(proc_list *proc, char *addargtype); ++static void penumdef(definition *def); ++static void ptypedef(definition *def); ++ ++/* ++ * Print the C-version of an xdr definition ++ */ ++void ++print_datadef(definition *def) ++{ ++ ++ if (def->def_kind == DEF_PROGRAM ) /* handle data only */ ++ return; ++ ++ if (def->def_kind != DEF_CONST) { ++ f_print(fout, "\n"); ++ } ++ switch (def->def_kind) { ++ case DEF_STRUCT: ++ pstructdef(def); ++ break; ++ case DEF_UNION: ++ puniondef(def); ++ break; ++ case DEF_ENUM: ++ penumdef(def); ++ break; ++ case DEF_TYPEDEF: ++ ptypedef(def); ++ break; ++ case DEF_PROGRAM: ++ pprogramdef(def); ++ break; ++ case DEF_CONST: ++ pconstdef(def); ++ break; ++ } ++ if (def->def_kind != DEF_PROGRAM && def->def_kind != DEF_CONST) { ++ pxdrfuncdecl( def->def_name, ++ def->def_kind != DEF_TYPEDEF || ++ !isvectordef(def->def.ty.old_type, def->def.ty.rel)); ++ ++ } ++} ++ ++ ++void ++print_funcdef(definition *def) ++{ ++ switch (def->def_kind) { ++ case DEF_PROGRAM: ++ f_print(fout, "\n"); ++ pprogramdef(def); ++ break; ++ default: ++ break; ++ } ++} ++ ++static void ++pxdrfuncdecl(char *name, int pointerp) ++{ ++ f_print(fout, ++ "#ifdef __cplusplus \n" ++ "extern \"C\" bool_t xdr_%s(XDR *, %s%s);\n" ++ "#elif __STDC__ \n" ++ "extern bool_t xdr_%s(XDR *, %s%s);\n" ++ "#else /* Old Style C */ \n" ++ "bool_t xdr_%s();\n" ++ "#endif /* Old Style C */ \n\n", ++ name, name, pointerp ? "*" : "", ++ name, name, pointerp ? "*" : "", ++ name); ++} ++ ++ ++static void ++pconstdef(definition *def) ++{ ++ pdefine(def->def_name, def->def.co); ++} ++ ++/* print out the definitions for the arguments of functions in the ++ header file ++*/ ++static void ++pargdef(definition *def) ++{ ++ decl_list *l; ++ version_list *vers; ++ char *name; ++ proc_list *plist; ++ ++ ++ for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) { ++ for(plist = vers->procs; plist != NULL; ++ plist = plist->next) { ++ ++ if (!newstyle || plist->arg_num < 2) { ++ continue; /* old style or single args */ ++ } ++ name = plist->args.argname; ++ f_print(fout, "struct %s {\n", name); ++ for (l = plist->args.decls; ++ l != NULL; l = l->next) { ++ pdeclaration(name, &l->decl, 1, ";\n" ); ++ } ++ f_print(fout, "};\n"); ++ f_print(fout, "typedef struct %s %s;\n", name, name); ++ pxdrfuncdecl(name, 0); ++ f_print( fout, "\n" ); ++ } ++ } ++ ++} ++ ++ ++static void ++pstructdef(definition *def) ++{ ++ decl_list *l; ++ char *name = def->def_name; ++ ++ f_print(fout, "struct %s {\n", name); ++ for (l = def->def.st.decls; l != NULL; l = l->next) { ++ pdeclaration(name, &l->decl, 1, ";\n"); ++ } ++ f_print(fout, "};\n"); ++ f_print(fout, "typedef struct %s %s;\n", name, name); ++} ++ ++static void ++puniondef(definition *def) ++{ ++ case_list *l; ++ char *name = def->def_name; ++ declaration *decl; ++ ++ f_print(fout, "struct %s {\n", name); ++ decl = &def->def.un.enum_decl; ++ if (streq(decl->type, "bool")) { ++ f_print(fout, "\tbool_t %s;\n", decl->name); ++ } else { ++ f_print(fout, "\t%s %s;\n", decl->type, decl->name); ++ } ++ f_print(fout, "\tunion {\n"); ++ for (l = def->def.un.cases; l != NULL; l = l->next) { ++ if (l->contflag == 0) ++ pdeclaration(name, &l->case_decl, 2, ";\n"); ++ } ++ decl = def->def.un.default_decl; ++ if (decl && !streq(decl->type, "void")) { ++ pdeclaration(name, decl, 2, ";\n"); ++ } ++ f_print(fout, "\t} %s_u;\n", name); ++ f_print(fout, "};\n"); ++ f_print(fout, "typedef struct %s %s;\n", name, name); ++} ++ ++static void ++pdefine(char *name, char *num) ++{ ++ f_print(fout, "#define %s %s\n", name, num); ++} ++ ++static void ++puldefine(char *name, char *num) ++{ ++ f_print(fout, "#define %s ((u_int32_t)%s)\n", name, num); ++} ++ ++static int ++define_printed(proc_list *stop, version_list *start) ++{ ++ version_list *vers; ++ proc_list *proc; ++ ++ for (vers = start; vers != NULL; vers = vers->next) { ++ for (proc = vers->procs; proc != NULL; proc = proc->next) { ++ if (proc == stop) { ++ return (0); ++ } else if (streq(proc->proc_name, stop->proc_name)) { ++ return (1); ++ } ++ } ++ } ++ abort(); ++ /* NOTREACHED */ ++} ++ ++static void ++pprogramdef(definition *def) ++{ ++ version_list *vers; ++ proc_list *proc; ++ int i; ++ char *ext; ++ ++ pargdef(def); ++ ++ puldefine(def->def_name, def->def.pr.prog_num); ++ for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) { ++ if (tblflag) { ++ f_print(fout, "extern struct rpcgen_table %s_%s_table[];\n", ++ locase(def->def_name), vers->vers_num); ++ f_print(fout, "extern %s_%s_nproc;\n", ++ locase(def->def_name), vers->vers_num); ++ } ++ puldefine(vers->vers_name, vers->vers_num); ++ ++ /* ++ * Print out 3 definitions, one for ANSI-C, another for C++, ++ * a third for old style C ++ */ ++ ++ for (i = 0; i < 3; i++) { ++ if (i == 0) { ++ f_print(fout, "\n#ifdef __cplusplus\n"); ++ ext = "extern \"C\" "; ++ } else if (i == 1) { ++ f_print(fout, "\n#elif __STDC__\n"); ++ ext = "extern "; ++ } else { ++ f_print(fout, "\n#else /* Old Style C */ \n"); ++ ext = "extern "; ++ } ++ ++ ++ for (proc = vers->procs; proc != NULL; proc = proc->next) { ++ if (!define_printed(proc, def->def.pr.versions)) { ++ puldefine(proc->proc_name, proc->proc_num); ++ } ++ f_print(fout, "%s", ext); ++ pprocdef(proc, vers, "CLIENT *", 0, i); ++ f_print(fout, "%s", ext); ++ pprocdef(proc, vers, "struct svc_req *", 1, i); ++ ++ } ++ ++ } ++ f_print(fout, "#endif /* Old Style C */ \n"); ++ } ++} ++ ++static void ++pprocdef(proc_list *proc, version_list *vp, char *addargtype, ++ int server_p, int mode) ++{ ++ ptype(proc->res_prefix, proc->res_type, 1); ++ f_print(fout, "* "); ++ if (server_p) ++ pvname_svc(proc->proc_name, vp->vers_num); ++ else ++ pvname(proc->proc_name, vp->vers_num); ++ ++ /* ++ * mode 0 == cplusplus, mode 1 = ANSI-C, mode 2 = old style C ++ */ ++ if (mode == 0 || mode == 1) ++ parglist(proc, addargtype); ++ else ++ f_print(fout, "();\n"); ++} ++ ++ ++ ++/* print out argument list of procedure */ ++static void ++parglist(proc_list *proc, char *addargtype) ++{ ++ decl_list *dl; ++ ++ f_print(fout, "("); ++ ++ if (proc->arg_num < 2 && newstyle && ++ streq(proc->args.decls->decl.type, "void")) { ++ /* 0 argument in new style: do nothing */ ++ } else { ++ for (dl = proc->args.decls; dl != NULL; dl = dl->next) { ++ ptype(dl->decl.prefix, dl->decl.type, 1); ++ if (!newstyle) ++ f_print(fout, "*"); /* old style passes by reference */ ++ ++ f_print(fout, ", "); ++ } ++ } ++ ++ f_print(fout, "%s);\n", addargtype); ++} ++ ++static void ++penumdef(definition *def) ++{ ++ char *name = def->def_name; ++ enumval_list *l; ++ char *last = NULL; ++ int count = 0; ++ ++ f_print(fout, "enum %s {\n", name); ++ for (l = def->def.en.vals; l != NULL; l = l->next) { ++ f_print(fout, "\t%s", l->name); ++ if (l->assignment) { ++ f_print(fout, " = %s", l->assignment); ++ last = l->assignment; ++ count = 1; ++ } else { ++ if (last == NULL) { ++ f_print(fout, " = %d", count++); ++ } else { ++ f_print(fout, " = %s + %d", last, count++); ++ } ++ } ++ f_print(fout, ",\n"); ++ } ++ f_print(fout, "};\n"); ++ f_print(fout, "typedef enum %s %s;\n", name, name); ++} ++ ++static void ++ptypedef(definition *def) ++{ ++ char *name = def->def_name; ++ char *old = def->def.ty.old_type; ++ char prefix[8]; /* enough to contain "struct ", including NUL */ ++ relation rel = def->def.ty.rel; ++ ++ ++ if (!streq(name, old)) { ++ if (streq(old, "string")) { ++ old = "char"; ++ rel = REL_POINTER; ++ } else if (streq(old, "opaque")) { ++ old = "char"; ++ } else if (streq(old, "bool")) { ++ old = "bool_t"; ++ } ++ if (undefined2(old, name) && def->def.ty.old_prefix) { ++ s_print(prefix, "%s ", def->def.ty.old_prefix); ++ } else { ++ prefix[0] = 0; ++ } ++ f_print(fout, "typedef "); ++ switch (rel) { ++ case REL_ARRAY: ++ f_print(fout, "struct {\n"); ++ f_print(fout, "\tu_int %s_len;\n", name); ++ f_print(fout, "\t%s%s *%s_val;\n", prefix, old, name); ++ f_print(fout, "} %s", name); ++ break; ++ case REL_POINTER: ++ f_print(fout, "%s%s *%s", prefix, old, name); ++ break; ++ case REL_VECTOR: ++ f_print(fout, "%s%s %s[%s]", prefix, old, name, ++ def->def.ty.array_max); ++ break; ++ case REL_ALIAS: ++ f_print(fout, "%s%s %s", prefix, old, name); ++ break; ++ } ++ f_print(fout, ";\n"); ++ } ++} ++ ++void ++pdeclaration(char *name, declaration *dec, int tab, char *separator) ++{ ++ char buf[8]; /* enough to hold "struct ", include NUL */ ++ char *prefix; ++ char *type; ++ ++ if (streq(dec->type, "void")) { ++ return; ++ } ++ tabify(fout, tab); ++ if (streq(dec->type, name) && !dec->prefix) { ++ f_print(fout, "struct "); ++ } ++ if (streq(dec->type, "string")) { ++ f_print(fout, "char *%s", dec->name); ++ } else { ++ prefix = ""; ++ if (streq(dec->type, "bool")) { ++ type = "bool_t"; ++ } else if (streq(dec->type, "opaque")) { ++ type = "char"; ++ } else { ++ if (dec->prefix) { ++ s_print(buf, "%s ", dec->prefix); ++ prefix = buf; ++ } ++ type = dec->type; ++ } ++ switch (dec->rel) { ++ case REL_ALIAS: ++ f_print(fout, "%s%s %s", prefix, type, dec->name); ++ break; ++ case REL_VECTOR: ++ f_print(fout, "%s%s %s[%s]", prefix, type, dec->name, ++ dec->array_max); ++ break; ++ case REL_POINTER: ++ f_print(fout, "%s%s *%s", prefix, type, dec->name); ++ break; ++ case REL_ARRAY: ++ f_print(fout, "struct {\n"); ++ tabify(fout, tab); ++ f_print(fout, "\tu_int %s_len;\n", dec->name); ++ tabify(fout, tab); ++ f_print(fout, "\t%s%s *%s_val;\n", prefix, type, dec->name); ++ tabify(fout, tab); ++ f_print(fout, "} %s", dec->name); ++ break; ++ } ++ } ++ f_print(fout, separator ); ++} ++ ++static int ++undefined2(char *type, char *stop) ++{ ++ list *l; ++ definition *def; ++ ++ for (l = defined; l != NULL; l = l->next) { ++ def = (definition *) l->val; ++ if (def->def_kind != DEF_PROGRAM) { ++ if (streq(def->def_name, stop)) { ++ return (1); ++ } else if (streq(def->def_name, type)) { ++ return (0); ++ } ++ } ++ } ++ return (1); ++} +diff --git a/rpcgen/rpc_main.c b/rpcgen/rpc_main.c +new file mode 100644 +index 0000000..28aa60c +--- /dev/null ++++ b/rpcgen/rpc_main.c +@@ -0,0 +1,1067 @@ ++/* ++ * Copyright (c) 2009, Sun Microsystems, Inc. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions are met: ++ * - Redistributions of source code must retain the above copyright notice, ++ * this list of conditions and the following disclaimer. ++ * - 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. ++ * - Neither the name of Sun Microsystems, Inc. nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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. ++ */ ++ ++#if 0 ++static char sccsid[] = "@(#)rpc_main.c 1.30 89/03/30 (C) 1987 SMI"; ++#endif ++ ++/* ++ * rpc_main.c, Top level of the RPC protocol compiler. ++ */ ++ ++#include <sys/types.h> ++#include <sys/param.h> ++#include <sys/file.h> ++#include <sys/stat.h> ++#include <stdio.h> ++#include <string.h> ++#include <stdlib.h> ++#include <unistd.h> ++#include <ctype.h> ++#include <errno.h> ++#include "rpc_parse.h" ++#include "rpc_util.h" ++#include "rpc_scan.h" ++ ++struct commandline { ++ int cflag; /* xdr C routines */ ++ int hflag; /* header file */ ++ int lflag; /* client side stubs */ ++ int mflag; /* server side stubs */ ++ int nflag; /* netid flag */ ++ int sflag; /* server stubs for the given transport */ ++ int tflag; /* dispatch Table file */ ++ int Ssflag; /* produce server sample code */ ++ int Scflag; /* produce client sample code */ ++ char *infile; /* input module name */ ++ char *outfile; /* output module name */ ++}; ++ ++static char * extendfile(char *file, char *ext); ++static void open_output(char *infile, char *outfile); ++static void add_warning(void); ++static void clear_args(void); ++static void open_input(char *infile, char *define); ++static int check_nettype(char *name, char **list_to_check); ++static void c_output(char *infile, char *define, int extend, char *outfile); ++static void c_initialize(void); ++static char * generate_guard(char *pathname); ++static void h_output(char *infile, char *define, int extend, char *outfile); ++static void s_output(int argc, char **argv, char *infile, ++ char *define, int extend, char *outfile, ++ int nomain, int netflag); ++static void l_output(char *infile, char *define, int extend, char *outfile); ++static void t_output(char *infile, char *define, int extend, char *outfile); ++static void svc_output(char *, char *, int, char *); ++static void clnt_output(char *, char *, int, char *); ++static int do_registers(int argc, char **argv); ++static void addarg(char *cp); ++static void putarg(int where, char *cp); ++static void checkfiles(char *infile, char *outfile); ++static int parseargs(int argc, char **argv, struct commandline *cmd); ++static void usage(void); ++static void options_usage(void); ++ ++/* ++extern void write_sample_svc(); ++int write_sample_clnt(); ++void write_sample_clnt_main(); ++ ++static svc_output(); ++ */ ++ ++#define EXTEND 1 /* alias for TRUE */ ++#define DONT_EXTEND 0 /* alias for FALSE */ ++ ++#define SVR4_CPP "/usr/ccs/lib/cpp" ++#define SUNOS_CPP "/lib/cpp" ++static int cppDefined = 0; /* explicit path for C preprocessor */ ++ ++ ++static char *cmdname; ++ ++static char *svcclosetime = "120"; ++static char *CPP = SVR4_CPP; ++static char CPPFLAGS[] = "-C"; ++static char pathbuf[MAXPATHLEN + 1]; ++static char *allv[] = { ++ "rpcgen", "-s", "udp", "-s", "tcp", ++}; ++static int allc = sizeof(allv)/sizeof(allv[0]); ++static char *allnv[] = { ++ "rpcgen", "-s", "netpath", ++}; ++static int allnc = sizeof(allnv)/sizeof(allnv[0]); ++ ++/* ++ * machinations for handling expanding argument list ++ */ ++#if 0 ++static void addarg(); /* add another argument to the list */ ++static void putarg(); /* put argument at specified location */ ++static void clear_args(); /* clear argument list */ ++static void checkfiles(); /* check if out file already exists */ ++#endif ++ ++ ++ ++#define ARGLISTLEN 20 ++#define FIXEDARGS 2 ++ ++static char *arglist[ARGLISTLEN]; ++static int argcount = FIXEDARGS; ++ ++ ++int nonfatalerrors; /* errors */ ++int inetdflag/* = 1*/; /* Support for inetd */ /* is now the default */ ++int pmflag; /* Support for port monitors */ ++int logflag; /* Use syslog instead of fprintf for errors */ ++int tblflag; /* Support for dispatch table file */ ++ ++/* length at which to start doing an inline */ ++#define INLINE 3 ++ ++int Inline = INLINE; /* length at which to start doing an inline. 3 = default ++ * if 0, no xdr_inline code */ ++ ++int indefinitewait; /* If started by port monitors, hang till it wants */ ++int exitnow; /* If started by port monitors, exit after the call */ ++int timerflag; /* TRUE if !indefinite && !exitnow */ ++int newstyle; /* newstyle of passing arguments (by value) */ ++int Cflag = 0 ; /* ANSI C syntax */ ++static int allfiles; /* generate all files */ ++#ifdef linux ++int tirpcflag = 0; /* no tirpc by default */ ++#else ++int tirpcflag = 1; /* generating code for tirpc, by default */ ++#endif ++ ++int ++main(int argc, char **argv) ++{ ++ struct commandline cmd; ++ ++ (void) memset((char *) &cmd, 0, sizeof(struct commandline)); ++ clear_args(); ++ if (!parseargs(argc, argv, &cmd)) ++ usage(); ++ ++ if (cmd.cflag || cmd.hflag || cmd.lflag || cmd.tflag || cmd.sflag || ++ cmd.mflag || cmd.nflag || cmd.Ssflag || cmd.Scflag) { ++ checkfiles(cmd.infile, cmd.outfile); ++ } else ++ checkfiles(cmd.infile, NULL); ++ ++ if (cmd.cflag) { ++ c_output(cmd.infile, "-DRPC_XDR", DONT_EXTEND, cmd.outfile); ++ } else if (cmd.hflag) { ++ h_output(cmd.infile, "-DRPC_HDR", DONT_EXTEND, cmd.outfile); ++ } else if (cmd.lflag) { ++ l_output(cmd.infile, "-DRPC_CLNT", DONT_EXTEND, cmd.outfile); ++ } else if (cmd.sflag || cmd.mflag || (cmd.nflag)) { ++ s_output(argc, argv, cmd.infile, "-DRPC_SVC", DONT_EXTEND, ++ cmd.outfile, cmd.mflag, cmd.nflag); ++ } else if (cmd.tflag) { ++ t_output(cmd.infile, "-DRPC_TBL", DONT_EXTEND, cmd.outfile); ++ } else if (cmd.Ssflag) { ++ svc_output(cmd.infile, "-DRPC_SERVER", DONT_EXTEND, cmd.outfile); ++ } else if (cmd.Scflag) { ++ clnt_output(cmd.infile, "-DRPC_CLIENT", DONT_EXTEND, cmd.outfile); ++ } else { ++ /* the rescans are required, since cpp may effect input */ ++ c_output(cmd.infile, "-DRPC_XDR", EXTEND, "_xdr.c"); ++ reinitialize(); ++ h_output(cmd.infile, "-DRPC_HDR", EXTEND, ".h"); ++ reinitialize(); ++ l_output(cmd.infile, "-DRPC_CLNT", EXTEND, "_clnt.c"); ++ reinitialize(); ++ if (inetdflag || !tirpcflag) ++ s_output(allc, allv, cmd.infile, "-DRPC_SVC", EXTEND, ++ "_svc.c", cmd.mflag, cmd.nflag); ++ else ++ s_output(allnc, allnv, cmd.infile, "-DRPC_SVC", ++ EXTEND, "_svc.c", cmd.mflag, cmd.nflag); ++ if (tblflag) { ++ reinitialize(); ++ t_output(cmd.infile, "-DRPC_TBL", EXTEND, "_tbl.i"); ++ } ++ if (allfiles) { ++ reinitialize(); ++ svc_output(cmd.infile, "-DRPC_SERVER", EXTEND, "_server.c"); ++ } ++ if (allfiles) { ++ reinitialize(); ++ clnt_output(cmd.infile, "-DRPC_CLIENT", EXTEND, "_client.c"); ++ } ++ } ++ exit(nonfatalerrors); ++ /* NOTREACHED */ ++} ++ ++/* ++ * add extension to filename ++ */ ++static char * ++extendfile(char *file, char *ext) ++{ ++ char *res; ++ char *p; ++ ++ res = alloc(strlen(file) + strlen(ext) + 1); ++ if (res == NULL) { ++ abort(); ++ } ++ p = strrchr(file, '.'); ++ if (p == NULL) { ++ p = file + strlen(file); ++ } ++ (void) strcpy(res, file); ++ (void) strcpy(res + (p - file), ext); ++ return (res); ++} ++ ++/* ++ * Open output file with given extension ++ */ ++static void ++open_output(char *infile, char *outfile) ++{ ++ ++ if (outfile == NULL) { ++ fout = stdout; ++ return; ++ } ++ ++ if (infile != NULL && streq(outfile, infile)) { ++ f_print(stderr, "%s: output would overwrite %s\n", cmdname, ++ infile); ++ crash(); ++ } ++ fout = fopen(outfile, "w"); ++ if (fout == NULL) { ++ f_print(stderr, "%s: unable to open ", cmdname); ++ perror(outfile); ++ crash(); ++ } ++ record_open(outfile); ++ ++} ++ ++static void ++add_warning(void) ++{ ++ f_print(fout, "/*\n"); ++ f_print(fout, " * Please do not edit this file.\n"); ++ f_print(fout, " * It was generated using rpcgen.\n"); ++ f_print(fout, " */\n\n"); ++} ++ ++/* clear list of arguments */ ++static void ++clear_args(void) ++{ ++ int i; ++ for( i=FIXEDARGS; i<ARGLISTLEN; i++ ) ++ arglist[i] = NULL; ++ argcount = FIXEDARGS; ++} ++ ++/* ++ * Open input file with given define for C-preprocessor ++ */ ++static void ++open_input(char *infile, char *define) ++{ ++ int pd[2]; ++ ++ infilename = (infile == NULL) ? "<stdin>" : infile; ++ (void) pipe(pd); ++ switch (fork()) { ++ case 0: ++ putarg(0, "cpp"); ++ putarg(1, CPPFLAGS); ++ addarg(define); ++ addarg(infile); ++ addarg((char *)NULL); ++ (void) close(1); ++ (void) dup2(pd[1], 1); ++ (void) close(pd[0]); ++ if (cppDefined) ++ execv(CPP, arglist); ++ else { ++ execvp("cpp", arglist); ++ if (errno == ENOENT) ++ execvp(SVR4_CPP, arglist); ++ if (errno == ENOENT) ++ execvp(SUNOS_CPP, arglist); ++ } ++ perror("execv"); ++ exit(1); ++ case -1: ++ perror("fork"); ++ exit(1); ++ } ++ (void) close(pd[1]); ++ fin = fdopen(pd[0], "r"); ++ if (fin == NULL) { ++ f_print(stderr, "%s: ", cmdname); ++ perror(infilename); ++ crash(); ++ } ++} ++ ++/* valid tirpc nettypes */ ++static char* valid_ti_nettypes[] = ++{ ++ "netpath", ++ "visible", ++ "circuit_v", ++ "datagram_v", ++ "circuit_n", ++ "datagram_n", ++ "udp", ++ "tcp", ++ "raw", ++ NULL ++}; ++ ++/* valid inetd nettypes */ ++static char* valid_i_nettypes[] = ++{ ++ "udp", ++ "tcp", ++ NULL ++}; ++ ++static int ++check_nettype(char *name, char **list_to_check) ++{ ++ int i; ++ for( i = 0; list_to_check[i] != NULL; i++ ) { ++ if( strcmp( name, list_to_check[i] ) == 0 ) { ++ return 1; ++ } ++ } ++ f_print( stderr, "illegal nettype :\'%s\'\n", name ); ++ return 0; ++} ++ ++/* ++ * Compile into an XDR routine output file ++ */ ++ ++static void ++c_output(char *infile, char *define, int extend, char *outfile) ++{ ++ definition *def; ++ char *include; ++ char *outfilename; ++ long tell; ++ ++ c_initialize(); ++ open_input(infile, define); ++ outfilename = extend ? extendfile(infile, outfile) : outfile; ++ open_output(infile, outfilename); ++ add_warning(); ++ if (infile && (include = extendfile(infile, ".h"))) { ++ f_print(fout, "#include \"%s\"\n", include); ++ free(include); ++ /* .h file already contains rpc/rpc.h */ ++ } else ++ f_print(fout, "#include <rpc/rpc.h>\n"); ++ tell = ftell(fout); ++ while ((def = get_definition()) != NULL) { ++ emit(def); ++ } ++ if (extend && tell == ftell(fout)) { ++ (void) unlink(outfilename); ++ } ++} ++ ++ ++static void ++c_initialize(void) ++{ ++ ++ /* add all the starting basic types */ ++ ++ add_type(1,"int"); ++ add_type(1,"int32_t"); ++ add_type(1,"short"); ++ add_type(1,"bool"); ++ ++ add_type(1,"u_int"); ++ add_type(1,"u_int32_t"); ++ add_type(1,"u_short"); ++ ++} ++ ++char rpcgen_table_dcl[] = "struct rpcgen_table {\n\ ++ char *(*proc)();\n\ ++ xdrproc_t xdr_arg;\n\ ++ unsigned len_arg;\n\ ++ xdrproc_t xdr_res;\n\ ++ unsigned len_res;\n\ ++};\n"; ++ ++ ++static char * ++generate_guard(char *pathname) ++{ ++ char* filename, *guard, *tmp; ++ ++ filename = strrchr(pathname, '/' ); /* find last component */ ++ filename = ((filename == 0) ? pathname : filename+1); ++ guard = strdup(filename); ++ /* convert to upper case */ ++ tmp = guard; ++ while (*tmp) { ++ if (islower(*tmp)) ++ *tmp = toupper(*tmp); ++ tmp++; ++ } ++ ++ guard = extendfile(guard, "_H_RPCGEN"); ++ return( guard ); ++} ++ ++/* ++ * Compile into an XDR header file ++ */ ++static void ++h_output(char *infile, char *define, int extend, char *outfile) ++{ ++ definition *def; ++ char *outfilename; ++ long tell; ++ char *guard; ++ list *l; ++ ++ open_input(infile, define); ++ outfilename = extend ? extendfile(infile, outfile) : outfile; ++ open_output(infile, outfilename); ++ add_warning(); ++ guard = generate_guard( outfilename ? outfilename: infile ); ++ ++ f_print(fout,"#ifndef _%s\n#define _%s\n\n", guard, ++ guard); ++ ++ f_print(fout, "#include <rpc/rpc.h>\n\n"); ++ ++ f_print(fout, "#ifndef IXDR_GET_INT32\n"); ++ f_print(fout, "#define IXDR_GET_INT32(buf) IXDR_GET_LONG((buf))\n"); ++ f_print(fout, "#endif\n"); ++ f_print(fout, "#ifndef IXDR_PUT_INT32\n"); ++ f_print(fout, "#define IXDR_PUT_INT32(buf, v) IXDR_PUT_LONG((buf), (v))\n"); ++ f_print(fout, "#endif\n"); ++ f_print(fout, "#ifndef IXDR_GET_U_INT32\n"); ++ f_print(fout, "#define IXDR_GET_U_INT32(buf) IXDR_GET_U_LONG((buf))\n"); ++ f_print(fout, "#endif\n"); ++ f_print(fout, "#ifndef IXDR_PUT_U_INT32\n"); ++ f_print(fout, "#define IXDR_PUT_U_INT32(buf, v) IXDR_PUT_U_LONG((buf), (v))\n"); ++ f_print(fout, "#endif\n"); ++ ++ tell = ftell(fout); ++ /* print data definitions */ ++ while ((def = get_definition()) != NULL) { ++ print_datadef(def); ++ } ++ ++ /* print function declarations. ++ Do this after data definitions because they might be used as ++ arguments for functions */ ++ for (l = defined; l != NULL; l = l->next) { ++ print_funcdef(l->val); ++ } ++ if (extend && tell == ftell(fout)) { ++ (void) unlink(outfilename); ++ } else if (tblflag) { ++ f_print(fout, rpcgen_table_dcl); ++ } ++ f_print(fout, "\n#endif /* !_%s */\n", guard); ++} ++ ++/* ++ * Compile into an RPC service ++ */ ++static void ++s_output(int argc, char **argv, char *infile, char *define, int extend, ++ char *outfile, int nomain, int netflag) ++{ ++ char *include; ++ definition *def; ++ int foundprogram = 0; ++ char *outfilename; ++ ++ open_input(infile, define); ++ outfilename = extend ? extendfile(infile, outfile) : outfile; ++ open_output(infile, outfilename); ++ add_warning(); ++ if (infile && (include = extendfile(infile, ".h"))) { ++ f_print(fout, "#include \"%s\"\n", include); ++ free(include); ++ } else ++ f_print(fout, "#include <rpc/rpc.h>\n"); ++ ++ f_print(fout, "#include <stdio.h>\n"); ++ f_print(fout, "#include <stdlib.h>/* getenv, exit */\n"); ++ if (Cflag) { ++ f_print (fout, "#include <rpc/pmap_clnt.h> /* for pmap_unset */\n"); ++ f_print (fout, "#include <string.h> /* strcmp */ \n"); ++ } ++ if (strcmp(svcclosetime, "-1") == 0) ++ indefinitewait = 1; ++ else if (strcmp(svcclosetime, "0") == 0) ++ exitnow = 1; ++ else if (inetdflag || pmflag) { ++ f_print(fout, "#include <signal.h>\n"); ++ timerflag = 1; ++ } ++ ++#ifndef linux ++ if( !tirpcflag && inetdflag ) ++ f_print(fout, "#include <sys/ttycom.h>/* TIOCNOTTY */\n"); ++#else ++ if( !tirpcflag ) ++ f_print(fout, "#include <sys/ioctl.h>/* TIOCNOTTY */\n"); ++#endif ++ if( Cflag && (inetdflag || pmflag ) ) { ++ f_print(fout, "#ifdef __cplusplus\n"); ++ f_print(fout, "#include <sysent.h> /* getdtablesize, open */\n"); ++ f_print(fout, "#endif /* __cplusplus */\n"); ++ ++ if( tirpcflag ) ++ f_print(fout, "#include <unistd.h> /* setsid */\n"); ++ } ++ if( tirpcflag ) ++ f_print(fout, "#include <sys/types.h>\n"); ++ ++ f_print(fout, "#include <memory.h>\n"); ++#ifndef linux ++ f_print(fout, "#include <stropts.h>\n"); ++#endif ++ if (inetdflag || !tirpcflag ) { ++ f_print(fout, "#include <sys/socket.h>\n"); ++ f_print(fout, "#include <netinet/in.h>\n"); ++ } ++ ++ if ( (netflag || pmflag) && tirpcflag ) { ++ f_print(fout, "#include <netconfig.h>\n"); ++ } ++ if (/*timerflag &&*/ tirpcflag) ++ f_print(fout, "#include <sys/resource.h> /* rlimit */\n"); ++ if (logflag || inetdflag || pmflag) { ++#ifdef linux ++ f_print(fout, "#include <syslog.h>\n"); ++#else ++ f_print(fout, "#ifdef SYSLOG\n"); ++ f_print(fout, "#include <syslog.h>\n"); ++ f_print(fout, "#else\n"); ++ f_print(fout, "#define LOG_ERR 1\n"); ++ f_print(fout, "#define openlog(a, b, c)\n"); ++ f_print(fout, "#endif\n"); ++#endif ++ } ++ ++ /* for ANSI-C */ ++ f_print(fout, "\n#ifdef __STDC__\n#define SIG_PF void(*)(int)\n#endif\n"); ++ ++ f_print(fout, "\n#ifdef DEBUG\n#define RPC_SVC_FG\n#endif\n"); ++ if (timerflag) ++ f_print(fout, "\n#define _RPCSVC_CLOSEDOWN %s\n", svcclosetime); ++ while ((def = get_definition()) != NULL) { ++ foundprogram |= (def->def_kind == DEF_PROGRAM); ++ } ++ if (extend && !foundprogram) { ++ (void) unlink(outfilename); ++ return; ++ } ++ write_most(infile, netflag, nomain); ++ if (!nomain) { ++ if( !do_registers(argc, argv) ) { ++ if (outfilename) ++ (void) unlink(outfilename); ++ usage(); ++ } ++ write_rest(); ++ } ++} ++ ++/* ++ * generate client side stubs ++ */ ++static void ++l_output(char *infile, char *define, int extend, char *outfile) ++{ ++ char *include; ++ definition *def; ++ int foundprogram = 0; ++ char *outfilename; ++ ++ open_input(infile, define); ++ outfilename = extend ? extendfile(infile, outfile) : outfile; ++ open_output(infile, outfilename); ++ add_warning(); ++ if (Cflag) ++ f_print (fout, "#include <memory.h> /* for memset */\n"); ++ if (infile && (include = extendfile(infile, ".h"))) { ++ f_print(fout, "#include \"%s\"\n", include); ++ free(include); ++ } else ++ f_print(fout, "#include <rpc/rpc.h>\n"); ++ while ((def = get_definition()) != NULL) { ++ foundprogram |= (def->def_kind == DEF_PROGRAM); ++ } ++ if (extend && !foundprogram) { ++ (void) unlink(outfilename); ++ return; ++ } ++ write_stubs(); ++} ++ ++/* ++ * generate the dispatch table ++ */ ++static void ++t_output(char *infile, char *define, int extend, char *outfile) ++{ ++ definition *def; ++ int foundprogram = 0; ++ char *outfilename; ++ ++ open_input(infile, define); ++ outfilename = extend ? extendfile(infile, outfile) : outfile; ++ open_output(infile, outfilename); ++ add_warning(); ++ while ((def = get_definition()) != NULL) { ++ foundprogram |= (def->def_kind == DEF_PROGRAM); ++ } ++ if (extend && !foundprogram) { ++ (void) unlink(outfilename); ++ return; ++ } ++ write_tables(); ++} ++ ++/* sample routine for the server template */ ++static void ++svc_output(char *infile, char *define, int extend, char *outfile) ++{ ++ definition *def; ++ char *include; ++ char *outfilename; ++ long tell; ++ ++ open_input(infile, define); ++ outfilename = extend ? extendfile(infile, outfile) : outfile; ++ checkfiles(infile,outfilename); /*check if outfile already exists. ++ if so, print an error message and exit*/ ++ open_output(infile, outfilename); ++ add_sample_msg(); ++ ++ if (infile && (include = extendfile(infile, ".h"))) { ++ f_print(fout, "#include \"%s\"\n", include); ++ free(include); ++ } else ++ f_print(fout, "#include <rpc/rpc.h>\n"); ++ ++ tell = ftell(fout); ++ while ((def = get_definition()) != NULL) { ++ write_sample_svc(def); ++ } ++ if (extend && tell == ftell(fout)) { ++ (void) unlink(outfilename); ++ } ++} ++ ++ ++/* sample main routine for client */ ++static void ++clnt_output(char *infile, char *define, int extend, char *outfile) ++{ ++ definition *def; ++ char *include; ++ char *outfilename; ++ long tell; ++ int has_program = 0; ++ ++ open_input(infile, define); ++ outfilename = extend ? extendfile(infile, outfile) : outfile; ++ checkfiles(infile, outfilename); /*check if outfile already exists. ++ if so, print an error message and exit*/ ++ ++ open_output(infile, outfilename); ++ add_sample_msg(); ++ if (infile && (include = extendfile(infile, ".h"))) { ++ f_print(fout, "#include \"%s\"\n", include); ++ free(include); ++ } else ++ f_print(fout, "#include <rpc/rpc.h>\n"); ++ tell = ftell(fout); ++ while ((def = get_definition()) != NULL) { ++ has_program += write_sample_clnt(def); ++ } ++ ++ if (has_program) ++ write_sample_clnt_main(); ++ ++ if (extend && tell == ftell(fout)) { ++ (void) unlink(outfilename); ++ } ++} ++ ++/* ++ * Perform registrations for service output ++ * Return 0 if failed; 1 otherwise. ++ */ ++static int ++do_registers(int argc, char **argv) ++{ ++ int i; ++ ++ if (inetdflag || !tirpcflag) { ++ for (i = 1; i < argc; i++) { ++ if (streq(argv[i], "-s")) { ++ if (!check_nettype(argv[i + 1], valid_i_nettypes)) ++ return 0; ++ write_inetd_register(argv[i + 1]); ++ i++; ++ } ++ } ++ } else { ++ for (i = 1; i < argc; i++) ++ if (streq(argv[i], "-s")) { ++ if (!check_nettype(argv[i + 1], valid_ti_nettypes)) ++ return 0; ++ write_nettype_register(argv[i + 1]); ++ i++; ++ } else if (streq(argv[i], "-n")) { ++ write_netid_register(argv[i + 1]); ++ i++; ++ } ++ } ++ return 1; ++} ++ ++/* ++ * Add another argument to the arg list ++ */ ++static void ++addarg(char *cp) ++{ ++ if (argcount >= ARGLISTLEN) { ++ f_print(stderr, "rpcgen: too many defines\n"); ++ crash(); ++ /*NOTREACHED*/ ++ } ++ arglist[argcount++] = cp; ++ ++} ++ ++static void ++putarg(int where, char *cp) ++{ ++ if (where >= ARGLISTLEN) { ++ f_print(stderr, "rpcgen: arglist coding error\n"); ++ crash(); ++ /*NOTREACHED*/ ++ } ++ arglist[where] = cp; ++ ++} ++ ++/* ++ * if input file is stdin and an output file is specified then complain ++ * if the file already exists. Otherwise the file may get overwritten ++ * If input file does not exist, exit with an error ++ */ ++ ++static void ++checkfiles(char *infile, char *outfile) ++{ ++ ++ struct stat buf; ++ ++ if(infile) /* infile ! = NULL */ ++ if(stat(infile,&buf) < 0) ++ { ++ perror(infile); ++ crash(); ++ }; ++ if (outfile) { ++ if (stat(outfile, &buf) < 0) ++ return; /* file does not exist */ ++ else { ++ f_print(stderr, ++ "file '%s' already exists and may be overwritten\n", outfile); ++ crash(); ++ } ++ } ++} ++ ++/* ++ * Parse command line arguments ++ */ ++static int ++parseargs(int argc, char **argv, struct commandline *cmd) ++{ ++ int i; ++ int j; ++ char c; ++ char flag[(1 << 8 * sizeof(char))]; ++ int nflags; ++ ++ cmdname = argv[0]; ++ cmd->infile = cmd->outfile = NULL; ++ if (argc < 2) { ++ return (0); ++ } ++ allfiles = 0; ++ flag['c'] = 0; ++ flag['h'] = 0; ++ flag['l'] = 0; ++ flag['m'] = 0; ++ flag['o'] = 0; ++ flag['s'] = 0; ++ flag['n'] = 0; ++ flag['t'] = 0; ++ flag['S'] = 0; ++ flag['C'] = 0; ++ for (i = 1; i < argc; i++) { ++ if (argv[i][0] != '-') { ++ if (cmd->infile) { ++ f_print( stderr, "Cannot specify more than one input file!\n"); ++ ++ return (0); ++ } ++ cmd->infile = argv[i]; ++ } else { ++ for (j = 1; argv[i][j] != 0; j++) { ++ c = argv[i][j]; ++ switch (c) { ++ case 'a': ++ allfiles = 1; ++ break; ++ case 'c': ++ case 'h': ++ case 'l': ++ case 'm': ++ case 't': ++ if (flag[(int) c]) { ++ return (0); ++ } ++ flag[(int) c] = 1; ++ break; ++ case 'S': ++ /* sample flag: Ss or Sc. ++ Ss means set flag['S']; ++ Sc means set flag['C']; */ ++ c = argv[i][++j]; /* get next char */ ++ if( c == 's' ) ++ c = 'S'; ++ else if( c == 'c' ) ++ c = 'C'; ++ else ++ return( 0 ); ++ ++ if (flag[(int) c]) { ++ return (0); ++ } ++ flag[(int) c] = 1; ++ break; ++ case 'C': /* ANSI C syntax */ ++ Cflag = 1; ++ break; ++ ++ case 'b': /* turn TIRPC flag off for ++ generating backward compatible ++ */ ++ tirpcflag = 0; ++ break; ++ ++ case 'I': ++ inetdflag = 1; ++ break; ++ case 'N': ++ newstyle = 1; ++ break; ++ case 'L': ++ logflag = 1; ++ break; ++ case 'K': ++ if (++i == argc) { ++ return (0); ++ } ++ svcclosetime = argv[i]; ++ goto nextarg; ++ case 'T': ++ tblflag = 1; ++ break; ++ case 'i' : ++ if (++i == argc) { ++ return (0); ++ } ++ Inline = atoi(argv[i]); ++ goto nextarg; ++ case 'n': ++ case 'o': ++ case 's': ++ if (argv[i][j - 1] != '-' || ++ argv[i][j + 1] != 0) { ++ return (0); ++ } ++ flag[(int) c] = 1; ++ if (++i == argc) { ++ return (0); ++ } ++ if (c == 's') { ++ if (!streq(argv[i], "udp") && ++ !streq(argv[i], "tcp")) { ++ return (0); ++ } ++ } else if (c == 'o') { ++ if (cmd->outfile) { ++ return (0); ++ } ++ cmd->outfile = argv[i]; ++ } ++ goto nextarg; ++ case 'D': ++ if (argv[i][j - 1] != '-') { ++ return (0); ++ } ++ (void) addarg(argv[i]); ++ goto nextarg; ++ case 'Y': ++ if (++i == argc) { ++ return (0); ++ } ++ (void) strcpy(pathbuf, argv[i]); ++ (void) strcat(pathbuf, "/cpp"); ++ CPP = pathbuf; ++ cppDefined = 1; ++ goto nextarg; ++ ++ ++ ++ default: ++ return (0); ++ } ++ } ++ nextarg: ++ ; ++ } ++ } ++ ++ cmd->cflag = flag['c']; ++ cmd->hflag = flag['h']; ++ cmd->lflag = flag['l']; ++ cmd->mflag = flag['m']; ++ cmd->nflag = flag['n']; ++ cmd->sflag = flag['s']; ++ cmd->tflag = flag['t']; ++ cmd->Ssflag = flag['S']; ++ cmd->Scflag = flag['C']; ++ ++ if( tirpcflag ) { ++ pmflag = inetdflag ? 0 : 1; /* pmflag or inetdflag is always TRUE */ ++ if( (inetdflag && cmd->nflag)) { /* netid not allowed with inetdflag */ ++ f_print(stderr, "Cannot use netid flag with inetd flag!\n"); ++ return (0); ++ } ++ } else { /* 4.1 mode */ ++ pmflag = 0; /* set pmflag only in tirpcmode */ ++ inetdflag = 1; /* inetdflag is TRUE by default */ ++ if( cmd->nflag ) { /* netid needs TIRPC */ ++ f_print( stderr, "Cannot use netid flag without TIRPC!\n"); ++ return( 0 ); ++ } ++ } ++ ++ if( newstyle && ( tblflag || cmd->tflag) ) { ++ f_print( stderr, "Cannot use table flags with newstyle!\n"); ++ return( 0 ); ++ } ++ ++ /* check no conflicts with file generation flags */ ++ nflags = cmd->cflag + cmd->hflag + cmd->lflag + cmd->mflag + ++ cmd->sflag + cmd->nflag + cmd->tflag + cmd->Ssflag + cmd->Scflag; ++ ++ if (nflags == 0) { ++ if (cmd->outfile != NULL || cmd->infile == NULL) { ++ return (0); ++ } ++ } else if (nflags > 1) { ++ f_print( stderr, "Cannot have more than one file generation flag!\n"); ++ return (0); ++ } ++ return (1); ++} ++ ++static void ++usage(void) ++{ ++ f_print(stderr, "usage: %s infile\n", cmdname); ++ f_print(stderr, "\t%s [-a][-b][-C][-Dname[=value]] -i size [-I [-K seconds]] [-L][-N][-T] infile\n", ++ cmdname); ++ f_print(stderr, "\t%s [-c | -h | -l | -m | -t | -Sc | -Ss] [-o outfile] [infile]\n", ++ cmdname); ++ f_print(stderr, "\t%s [-s nettype]* [-o outfile] [infile]\n", cmdname); ++ f_print(stderr, "\t%s [-n netid]* [-o outfile] [infile]\n", cmdname); ++ options_usage(); ++ exit(1); ++} ++ ++static void ++options_usage(void) ++{ ++ f_print(stderr, "options:\n"); ++ f_print(stderr, "-a\t\tgenerate all files, including samples\n"); ++ f_print(stderr, "-b\t\tbackward compatibility mode (generates code for SunOS 4.1)\n"); ++ f_print(stderr, "-c\t\tgenerate XDR routines\n"); ++ f_print(stderr, "-C\t\tANSI C mode\n"); ++ f_print(stderr, "-Dname[=value]\tdefine a symbol (same as #define)\n"); ++ f_print(stderr, "-h\t\tgenerate header file\n"); ++ f_print(stderr, "-i size\t\tsize at which to start generating inline code\n"); ++ f_print(stderr, "-I\t\tgenerate code for inetd support in server (for SunOS 4.1)\n"); ++ f_print(stderr, "-K seconds\tserver exits after K seconds of inactivity\n"); ++ f_print(stderr, "-l\t\tgenerate client side stubs\n"); ++ f_print(stderr, "-L\t\tserver errors will be printed to syslog\n"); ++ f_print(stderr, "-m\t\tgenerate server side stubs\n"); ++ f_print(stderr, "-n netid\tgenerate server code that supports named netid\n"); ++ f_print(stderr, "-N\t\tsupports multiple arguments and call-by-value\n"); ++ f_print(stderr, "-o outfile\tname of the output file\n"); ++ f_print(stderr, "-s nettype\tgenerate server code that supports named nettype\n"); ++ f_print(stderr, "-Sc\t\tgenerate sample client code that uses remote procedures\n"); ++ f_print(stderr, "-Ss\t\tgenerate sample server code that defines remote procedures\n"); ++ f_print(stderr, "-t\t\tgenerate RPC dispatch table\n"); ++ f_print(stderr, "-T\t\tgenerate code to support RPC dispatch tables\n"); ++ f_print(stderr, "-Y path\t\tdirectory name to find C preprocessor (cpp)\n"); ++ ++ exit(1); ++} +diff --git a/rpcgen/rpc_output.h b/rpcgen/rpc_output.h +new file mode 100644 +index 0000000..eb25a60 +--- /dev/null ++++ b/rpcgen/rpc_output.h +@@ -0,0 +1,16 @@ ++/* ++ * rpc_output.h ++ * ++ * Declarations for output functions ++ * ++ */ ++ ++#ifndef RPCGEN_NEW_OUTPUT_H ++#define RPCGEN_NEW_OUTPUT_H ++ ++void write_msg_out(void); ++int nullproc(proc_list *); ++void printarglist(proc_list *, char *, char *); ++void pdeclaration(char *, declaration *, int, char *); ++ ++#endif /* RPCGEN_NEW_OUTPUT_H */ +diff --git a/rpcgen/rpc_parse.c b/rpcgen/rpc_parse.c +new file mode 100644 +index 0000000..b53a553 +--- /dev/null ++++ b/rpcgen/rpc_parse.c +@@ -0,0 +1,609 @@ ++/* ++ * Copyright (c) 2009, Sun Microsystems, Inc. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions are met: ++ * - Redistributions of source code must retain the above copyright notice, ++ * this list of conditions and the following disclaimer. ++ * - 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. ++ * - Neither the name of Sun Microsystems, Inc. nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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. ++ */ ++ ++#if 0 ++static char sccsid[] = "@(#)rpc_parse.c 1.8 89/02/22 (C) 1987 SMI"; ++#endif ++ ++/* ++ * rpc_parse.c, Parser for the RPC protocol compiler ++ * Copyright (C) 1987 Sun Microsystems, Inc. ++ */ ++#include <stdio.h> ++#include <string.h> ++#include "rpc/types.h" ++#include "rpc_scan.h" ++#include "rpc_parse.h" ++#include "rpc_util.h" ++ ++#define ARGNAME "arg" ++ ++/* ++extern char *make_argname(); ++extern char *strdup(); ++ */ ++ ++static void isdefined(definition *defp); ++static void def_struct(definition *defp); ++static void def_program(definition *defp); ++static void def_enum(definition *defp); ++static void def_const(definition *defp); ++static void def_union(definition *defp); ++static void check_type_name(char *name, int new_type); ++static void def_typedef(definition *defp); ++static void get_declaration(declaration *dec, defkind dkind); ++static void get_prog_declaration(declaration *dec, defkind dkind, int num); ++static void get_type(char **prefixp, char **typep, defkind dkind); ++static void unsigned_dec(char **typep); ++ ++/* ++ * return the next definition you see ++ */ ++definition * ++get_definition(void) ++{ ++ definition *defp; ++ token tok; ++ ++ defp = ALLOC(definition); ++ get_token(&tok); ++ switch (tok.kind) { ++ case TOK_STRUCT: ++ def_struct(defp); ++ break; ++ case TOK_UNION: ++ def_union(defp); ++ break; ++ case TOK_TYPEDEF: ++ def_typedef(defp); ++ break; ++ case TOK_ENUM: ++ def_enum(defp); ++ break; ++ case TOK_PROGRAM: ++ def_program(defp); ++ break; ++ case TOK_CONST: ++ def_const(defp); ++ break; ++ case TOK_EOF: ++ free(defp); ++ return (NULL); ++ default: ++ error("definition keyword expected"); ++ } ++ scan(TOK_SEMICOLON, &tok); ++ isdefined(defp); ++ return (defp); ++} ++ ++static void ++isdefined(definition *defp) ++{ ++ STOREVAL(&defined, defp); ++} ++ ++static void ++def_struct(definition *defp) ++{ ++ token tok; ++ declaration dec; ++ decl_list *decls; ++ decl_list **tailp; ++ ++ defp->def_kind = DEF_STRUCT; ++ ++ scan(TOK_IDENT, &tok); ++ defp->def_name = tok.str; ++ scan(TOK_LBRACE, &tok); ++ tailp = &defp->def.st.decls; ++ do { ++ get_declaration(&dec, DEF_STRUCT); ++ decls = ALLOC(decl_list); ++ decls->decl = dec; ++ *tailp = decls; ++ tailp = &decls->next; ++ scan(TOK_SEMICOLON, &tok); ++ peek(&tok); ++ } while (tok.kind != TOK_RBRACE); ++ get_token(&tok); ++ *tailp = NULL; ++} ++ ++static void ++def_program(definition *defp) ++{ ++ token tok; ++ declaration dec; ++ decl_list *decls; ++ decl_list **tailp; ++ version_list *vlist; ++ version_list **vtailp; ++ proc_list *plist; ++ proc_list **ptailp; ++ int num_args; ++ bool_t isvoid = FALSE; /* whether first argument is void */ ++ defp->def_kind = DEF_PROGRAM; ++ scan(TOK_IDENT, &tok); ++ defp->def_name = tok.str; ++ scan(TOK_LBRACE, &tok); ++ vtailp = &defp->def.pr.versions; ++ tailp = &defp->def.st.decls; ++ scan(TOK_VERSION, &tok); ++ do { ++ scan(TOK_IDENT, &tok); ++ vlist = ALLOC(version_list); ++ vlist->vers_name = tok.str; ++ scan(TOK_LBRACE, &tok); ++ ptailp = &vlist->procs; ++ do { ++ /* get result type */ ++ plist = ALLOC(proc_list); ++ get_type(&plist->res_prefix, &plist->res_type, ++ DEF_PROGRAM); ++ if (streq(plist->res_type, "opaque")) { ++ error("illegal result type"); ++ } ++ scan(TOK_IDENT, &tok); ++ plist->proc_name = tok.str; ++ scan(TOK_LPAREN, &tok); ++ /* get args - first one*/ ++ num_args = 1; ++ isvoid = FALSE; ++ /* type of DEF_PROGRAM in the first ++ * get_prog_declaration and DEF_STURCT in the next ++ * allows void as argument if it is the only argument ++ */ ++ get_prog_declaration(&dec, DEF_PROGRAM, num_args); ++ if (streq(dec.type, "void")) ++ isvoid = TRUE; ++ decls = ALLOC(decl_list); ++ plist->args.decls = decls; ++ decls->decl = dec; ++ tailp = &decls->next; ++ /* get args */ ++ while(peekscan(TOK_COMMA, &tok)) { ++ num_args++; ++ get_prog_declaration(&dec, DEF_STRUCT, ++ num_args); ++ decls = ALLOC(decl_list); ++ decls->decl = dec; ++ *tailp = decls; ++ if (streq(dec.type, "void")) ++ isvoid = TRUE; ++ tailp = &decls->next; ++ } ++ /* multiple arguments are only allowed in newstyle */ ++ if( !newstyle && num_args > 1 ) { ++ error("only one argument is allowed" ); ++ } ++ if (isvoid && num_args > 1) { ++ error("illegal use of void in program definition"); ++ } ++ *tailp = NULL; ++ scan(TOK_RPAREN, &tok); ++ scan(TOK_EQUAL, &tok); ++ scan_num(&tok); ++ scan(TOK_SEMICOLON, &tok); ++ plist->proc_num = tok.str; ++ plist->arg_num = num_args; ++ *ptailp = plist; ++ ptailp = &plist->next; ++ peek(&tok); ++ } while (tok.kind != TOK_RBRACE); ++ *ptailp = NULL; ++ *vtailp = vlist; ++ vtailp = &vlist->next; ++ scan(TOK_RBRACE, &tok); ++ scan(TOK_EQUAL, &tok); ++ scan_num(&tok); ++ vlist->vers_num = tok.str; ++ /* make the argument structure name for each arg*/ ++ for(plist = vlist->procs; plist != NULL; ++ plist = plist->next) { ++ plist->args.argname = make_argname(plist->proc_name, ++ vlist->vers_num); ++ /* free the memory ??*/ ++ } ++ scan(TOK_SEMICOLON, &tok); ++ scan2(TOK_VERSION, TOK_RBRACE, &tok); ++ } while (tok.kind == TOK_VERSION); ++ scan(TOK_EQUAL, &tok); ++ scan_num(&tok); ++ defp->def.pr.prog_num = tok.str; ++ *vtailp = NULL; ++} ++ ++ ++static void ++def_enum(definition *defp) ++{ ++ token tok; ++ enumval_list *elist; ++ enumval_list **tailp; ++ ++ defp->def_kind = DEF_ENUM; ++ scan(TOK_IDENT, &tok); ++ defp->def_name = tok.str; ++ scan(TOK_LBRACE, &tok); ++ tailp = &defp->def.en.vals; ++ do { ++ scan(TOK_IDENT, &tok); ++ elist = ALLOC(enumval_list); ++ elist->name = tok.str; ++ elist->assignment = NULL; ++ scan3(TOK_COMMA, TOK_RBRACE, TOK_EQUAL, &tok); ++ if (tok.kind == TOK_EQUAL) { ++ scan_num(&tok); ++ elist->assignment = tok.str; ++ scan2(TOK_COMMA, TOK_RBRACE, &tok); ++ } ++ *tailp = elist; ++ tailp = &elist->next; ++ } while (tok.kind != TOK_RBRACE); ++ *tailp = NULL; ++} ++ ++static void ++def_const(definition *defp) ++{ ++ token tok; ++ ++ defp->def_kind = DEF_CONST; ++ scan(TOK_IDENT, &tok); ++ defp->def_name = tok.str; ++ scan(TOK_EQUAL, &tok); ++ scan2(TOK_IDENT, TOK_STRCONST, &tok); ++ defp->def.co = tok.str; ++} ++ ++static void ++def_union(definition *defp) ++{ ++ token tok; ++ declaration dec; ++ case_list *cases; ++ case_list **tailp; ++ ++ defp->def_kind = DEF_UNION; ++ scan(TOK_IDENT, &tok); ++ defp->def_name = tok.str; ++ scan(TOK_SWITCH, &tok); ++ scan(TOK_LPAREN, &tok); ++ get_declaration(&dec, DEF_UNION); ++ defp->def.un.enum_decl = dec; ++ tailp = &defp->def.un.cases; ++ scan(TOK_RPAREN, &tok); ++ scan(TOK_LBRACE, &tok); ++ scan(TOK_CASE, &tok); ++ while (tok.kind == TOK_CASE) { ++ scan2(TOK_IDENT, TOK_CHARCONST, &tok); ++ cases = ALLOC(case_list); ++ cases->case_name = tok.str; ++ scan(TOK_COLON, &tok); ++ /* now peek at next token */ ++ if(peekscan(TOK_CASE,&tok)) ++ { ++ ++ do ++ { ++ scan2(TOK_IDENT, TOK_CHARCONST, &tok); ++ cases->contflag=1; /* continued case statement */ ++ *tailp = cases; ++ tailp = &cases->next; ++ cases = ALLOC(case_list); ++ cases->case_name = tok.str; ++ scan(TOK_COLON, &tok); ++ ++ }while(peekscan(TOK_CASE,&tok)); ++ } ++ ++ get_declaration(&dec, DEF_UNION); ++ cases->case_decl = dec; ++ cases->contflag=0; /* no continued case statement */ ++ *tailp = cases; ++ tailp = &cases->next; ++ scan(TOK_SEMICOLON, &tok); ++ ++ scan3(TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok); ++ } ++ *tailp = NULL; ++ if (tok.kind == TOK_DEFAULT) { ++ scan(TOK_COLON, &tok); ++ get_declaration(&dec, DEF_UNION); ++ defp->def.un.default_decl = ALLOC(declaration); ++ *defp->def.un.default_decl = dec; ++ scan(TOK_SEMICOLON, &tok); ++ scan(TOK_RBRACE, &tok); ++ } else { ++ defp->def.un.default_decl = NULL; ++ } ++} ++ ++static char* reserved_words[] = ++{ ++ "array", ++ "bytes", ++ "destroy", ++ "free", ++ "getpos", ++ "inline", ++ "pointer", ++ "reference", ++ "setpos", ++ "sizeof", ++ "union", ++ "vector", ++ NULL ++ }; ++ ++static char* reserved_types[] = ++{ ++ "opaque", ++ "string", ++ NULL ++ }; ++ ++/* check that the given name is not one that would eventually result in ++ xdr routines that would conflict with internal XDR routines. */ ++static void ++check_type_name(char *name, int new_type) ++{ ++ int i; ++ char tmp[100]; ++ ++ for( i = 0; reserved_words[i] != NULL; i++ ) { ++ if( strcmp( name, reserved_words[i] ) == 0 ) { ++ sprintf(tmp, ++ "illegal (reserved) name :\'%s\' in type definition", name ); ++ error(tmp); ++ } ++ } ++ if( new_type ) { ++ for( i = 0; reserved_types[i] != NULL; i++ ) { ++ if( strcmp( name, reserved_types[i] ) == 0 ) { ++ sprintf(tmp, ++ "illegal (reserved) name :\'%s\' in type definition", name ); ++ error(tmp); ++ } ++ } ++ } ++} ++ ++static void ++def_typedef(definition *defp) ++{ ++ declaration dec; ++ ++ defp->def_kind = DEF_TYPEDEF; ++ get_declaration(&dec, DEF_TYPEDEF); ++ defp->def_name = dec.name; ++ check_type_name( dec.name, 1 ); ++ defp->def.ty.old_prefix = dec.prefix; ++ defp->def.ty.old_type = dec.type; ++ defp->def.ty.rel = dec.rel; ++ defp->def.ty.array_max = dec.array_max; ++} ++ ++static void ++get_declaration(declaration *dec, defkind dkind) ++{ ++ token tok; ++ ++ get_type(&dec->prefix, &dec->type, dkind); ++ dec->rel = REL_ALIAS; ++ if (streq(dec->type, "void")) { ++ return; ++ } ++ ++ check_type_name( dec->type, 0 ); ++ ++ scan2(TOK_STAR, TOK_IDENT, &tok); ++ if (tok.kind == TOK_STAR) { ++ dec->rel = REL_POINTER; ++ scan(TOK_IDENT, &tok); ++ } ++ dec->name = tok.str; ++ if (peekscan(TOK_LBRACKET, &tok)) { ++ if (dec->rel == REL_POINTER) { ++ error("no array-of-pointer declarations -- use typedef"); ++ } ++ dec->rel = REL_VECTOR; ++ scan_num(&tok); ++ dec->array_max = tok.str; ++ scan(TOK_RBRACKET, &tok); ++ } else if (peekscan(TOK_LANGLE, &tok)) { ++ if (dec->rel == REL_POINTER) { ++ error("no array-of-pointer declarations -- use typedef"); ++ } ++ dec->rel = REL_ARRAY; ++ if (peekscan(TOK_RANGLE, &tok)) { ++ dec->array_max = "~0"; /* unspecified size, use max */ ++ } else { ++ scan_num(&tok); ++ dec->array_max = tok.str; ++ scan(TOK_RANGLE, &tok); ++ } ++ } ++ if (streq(dec->type, "opaque")) { ++ if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR) { ++ error("array declaration expected"); ++ } ++ } else if (streq(dec->type, "string")) { ++ if (dec->rel != REL_ARRAY) { ++ error("variable-length array declaration expected"); ++ } ++ } ++} ++ ++ ++static void ++get_prog_declaration(declaration *dec, defkind dkind, int num) ++{ ++ token tok; ++ char name[10]; /* argument name */ ++ ++ if (dkind == DEF_PROGRAM) { ++ peek(&tok); ++ if (tok.kind == TOK_RPAREN) { /* no arguments */ ++ dec->rel = REL_ALIAS; ++ dec->type = "void"; ++ dec->prefix = NULL; ++ dec->name = NULL; ++ return; ++ } ++ } ++ get_type(&dec->prefix, &dec->type, dkind); ++ dec->rel = REL_ALIAS; ++ if (peekscan(TOK_IDENT, &tok)) /* optional name of argument */ ++ strcpy(name, tok.str); ++ else ++ sprintf(name, "%s%d", ARGNAME, num); /* default name of argument */ ++ ++ dec->name = (char *) strdup(name); ++ ++ if (streq(dec->type, "void")) { ++ return; ++ } ++ ++ if (streq(dec->type, "opaque")) { ++ error("opaque -- illegal argument type"); ++ } ++ if (peekscan(TOK_STAR, &tok)) { ++ if (streq(dec->type, "string")) { ++ error("pointer to string not allowed in program arguments\n"); ++ } ++ dec->rel = REL_POINTER; ++ if (peekscan(TOK_IDENT, &tok)) /* optional name of argument */ ++ dec->name = strdup(tok.str); ++ } ++ if (peekscan(TOK_LANGLE, &tok)) { ++ if (!streq(dec->type, "string")) { ++ error("arrays cannot be declared as arguments to procedures -- use typedef"); ++ } ++ dec->rel = REL_ARRAY; ++ if (peekscan(TOK_RANGLE, &tok)) { ++ dec->array_max = "~0";/* unspecified size, use max */ ++ } else { ++ scan_num(&tok); ++ dec->array_max = tok.str; ++ scan(TOK_RANGLE, &tok); ++ } ++ } ++ if (streq(dec->type, "string")) { ++ if (dec->rel != REL_ARRAY) { /* .x specifies just string as ++ * type of argument ++ * - make it string<> ++ */ ++ dec->rel = REL_ARRAY; ++ dec->array_max = "~0";/* unspecified size, use max */ ++ } ++ } ++} ++ ++ ++ ++static void ++get_type(char **prefixp, char **typep, defkind dkind) ++{ ++ token tok; ++ ++ *prefixp = NULL; ++ get_token(&tok); ++ switch (tok.kind) { ++ case TOK_IDENT: ++ *typep = tok.str; ++ break; ++ case TOK_STRUCT: ++ case TOK_ENUM: ++ case TOK_UNION: ++ *prefixp = tok.str; ++ scan(TOK_IDENT, &tok); ++ *typep = tok.str; ++ break; ++ case TOK_UNSIGNED: ++ unsigned_dec(typep); ++ break; ++ case TOK_SHORT: ++ *typep = "short"; ++ (void) peekscan(TOK_INT, &tok); ++ break; ++ case TOK_INT32: ++ *typep = "int32_t"; ++ (void) peekscan(TOK_INT, &tok); ++ break; ++ case TOK_VOID: ++ if (dkind != DEF_UNION && dkind != DEF_PROGRAM) { ++ error("voids allowed only inside union and program definitions with one argument"); ++ } ++ *typep = tok.str; ++ break; ++ case TOK_STRING: ++ case TOK_OPAQUE: ++ case TOK_CHAR: ++ case TOK_INT: ++ case TOK_FLOAT: ++ case TOK_DOUBLE: ++ case TOK_BOOL: ++ *typep = tok.str; ++ break; ++ default: ++ error("expected type specifier"); ++ } ++} ++ ++static void ++unsigned_dec(char **typep) ++{ ++ token tok; ++ ++ peek(&tok); ++ switch (tok.kind) { ++ case TOK_CHAR: ++ get_token(&tok); ++ *typep = "u_char"; ++ break; ++ case TOK_SHORT: ++ get_token(&tok); ++ *typep = "u_short"; ++ (void) peekscan(TOK_INT, &tok); ++ break; ++ case TOK_INT32: ++ get_token(&tok); ++ *typep = "u_int32_"; ++ (void) peekscan(TOK_INT, &tok); ++ break; ++ case TOK_INT: ++ get_token(&tok); ++ *typep = "u_int"; ++ break; ++ default: ++ *typep = "u_int"; ++ break; ++ } ++} +diff --git a/rpcgen/rpc_parse.h b/rpcgen/rpc_parse.h +new file mode 100644 +index 0000000..2afae10 +--- /dev/null ++++ b/rpcgen/rpc_parse.h +@@ -0,0 +1,166 @@ ++/* ++ * Copyright (c) 2009, Sun Microsystems, Inc. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions are met: ++ * - Redistributions of source code must retain the above copyright notice, ++ * this list of conditions and the following disclaimer. ++ * - 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. ++ * - Neither the name of Sun Microsystems, Inc. nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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. ++ */ ++ ++/* @(#)rpc_parse.h 1.3 90/08/29 (C) 1987 SMI */ ++ ++/* ++ * rpc_parse.h, Definitions for the RPCL parser ++ */ ++ ++enum defkind { ++ DEF_CONST, ++ DEF_STRUCT, ++ DEF_UNION, ++ DEF_ENUM, ++ DEF_TYPEDEF, ++ DEF_PROGRAM ++}; ++typedef enum defkind defkind; ++ ++typedef char *const_def; ++ ++enum relation { ++ REL_VECTOR, /* fixed length array */ ++ REL_ARRAY, /* variable length array */ ++ REL_POINTER, /* pointer */ ++ REL_ALIAS, /* simple */ ++}; ++typedef enum relation relation; ++ ++struct typedef_def { ++ char *old_prefix; ++ char *old_type; ++ relation rel; ++ char *array_max; ++}; ++typedef struct typedef_def typedef_def; ++ ++struct enumval_list { ++ char *name; ++ char *assignment; ++ struct enumval_list *next; ++}; ++typedef struct enumval_list enumval_list; ++ ++struct enum_def { ++ enumval_list *vals; ++}; ++typedef struct enum_def enum_def; ++ ++struct declaration { ++ char *prefix; ++ char *type; ++ char *name; ++ relation rel; ++ char *array_max; ++}; ++typedef struct declaration declaration; ++ ++struct decl_list { ++ declaration decl; ++ struct decl_list *next; ++}; ++typedef struct decl_list decl_list; ++ ++struct struct_def { ++ decl_list *decls; ++}; ++typedef struct struct_def struct_def; ++ ++struct case_list { ++ char *case_name; ++ int contflag; ++ declaration case_decl; ++ struct case_list *next; ++}; ++typedef struct case_list case_list; ++ ++struct union_def { ++ declaration enum_decl; ++ case_list *cases; ++ declaration *default_decl; ++}; ++typedef struct union_def union_def; ++ ++struct arg_list { ++ char *argname; /* name of struct for arg*/ ++ decl_list *decls; ++}; ++ ++typedef struct arg_list arg_list; ++ ++struct proc_list { ++ char *proc_name; ++ char *proc_num; ++ arg_list args; ++ int arg_num; ++ char *res_type; ++ char *res_prefix; ++ struct proc_list *next; ++}; ++typedef struct proc_list proc_list; ++ ++struct version_list { ++ char *vers_name; ++ char *vers_num; ++ proc_list *procs; ++ struct version_list *next; ++}; ++typedef struct version_list version_list; ++ ++struct program_def { ++ char *prog_num; ++ version_list *versions; ++}; ++typedef struct program_def program_def; ++ ++struct definition { ++ char *def_name; ++ defkind def_kind; ++ union { ++ const_def co; ++ struct_def st; ++ union_def un; ++ enum_def en; ++ typedef_def ty; ++ program_def pr; ++ } def; ++}; ++typedef struct definition definition; ++ ++definition *get_definition(); ++ ++ ++struct bas_type ++{ ++ char *name; ++ int length; ++ struct bas_type *next; ++}; ++ ++typedef struct bas_type bas_type; +diff --git a/rpcgen/rpc_sample.c b/rpcgen/rpc_sample.c +new file mode 100644 +index 0000000..2b5c81b +--- /dev/null ++++ b/rpcgen/rpc_sample.c +@@ -0,0 +1,247 @@ ++/* ++ * Copyright (c) 2009, Sun Microsystems, Inc. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions are met: ++ * - Redistributions of source code must retain the above copyright notice, ++ * this list of conditions and the following disclaimer. ++ * - 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. ++ * - Neither the name of Sun Microsystems, Inc. nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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. ++ */ ++ ++#if 0 ++static char sccsid[] = "@(#)rpc_sample.c 1.1 90/08/30 (C) 1987 SMI"; ++ ++#endif ++ ++/* ++ * rpc_sample.c, Sample client-server code outputter for the RPC protocol compiler ++ */ ++ ++#include <stdio.h> ++#include <string.h> ++#include "rpc_parse.h" ++#include "rpc_util.h" ++ ++ ++static char RQSTP[] = "rqstp"; ++ ++static void write_sample_client(char *program_name, version_list *vp); ++static void write_sample_server(definition * def); ++static void return_type(proc_list *plist); ++ ++void ++write_sample_svc(definition *def) ++{ ++ if (def->def_kind != DEF_PROGRAM) ++ return; ++ write_sample_server(def); ++} ++ ++ ++int ++write_sample_clnt(definition *def) ++{ ++ version_list *vp; ++ int count = 0; ++ ++ if (def->def_kind != DEF_PROGRAM) ++ return (0); ++ /* generate sample code for each version */ ++ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { ++ write_sample_client(def->def_name, vp); ++ ++count; ++ } ++ return (count); ++} ++ ++ ++static void ++write_sample_client(char *program_name, version_list *vp) ++{ ++ proc_list *proc; ++ int i; ++ decl_list *l; ++ ++ f_print(fout, "\n\nvoid\n"); ++ pvname(program_name, vp->vers_num); ++ if (Cflag) ++ f_print(fout, "( char* host )\n{\n"); ++ else ++ f_print(fout, "(host)\nchar *host;\n{\n"); ++ f_print(fout, "\tCLIENT *clnt;\n"); ++ ++ i = 0; ++ for (proc = vp->procs; proc != NULL; proc = proc->next) { ++ f_print(fout, "\t"); ++ ptype(proc->res_prefix, proc->res_type, 1); ++ f_print(fout, " *result_%d;\n", ++i); ++ /* print out declarations for arguments */ ++ if (proc->arg_num < 2 && !newstyle) { ++ f_print(fout, "\t"); ++ if (!streq(proc->args.decls->decl.type, "void")) ++ ptype(proc->args.decls->decl.prefix, proc->args.decls->decl.type, 1); ++ else ++ f_print(fout, "char* "); /* cannot have "void" type */ ++ f_print(fout, " "); ++ pvname(proc->proc_name, vp->vers_num); ++ f_print(fout, "_arg;\n"); ++ } else if (!streq(proc->args.decls->decl.type, "void")) { ++ for (l = proc->args.decls; l != NULL; l = l->next) { ++ f_print(fout, "\t"); ++ ptype(l->decl.prefix, l->decl.type, 1); ++ f_print(fout, " "); ++ pvname(proc->proc_name, vp->vers_num); ++ f_print(fout, "_%s;\n", l->decl.name); ++ /* pdeclaration(proc->args.argname, &l->decl, 1, ";\n" );*/ ++ } ++ } ++ } ++ ++ /* generate creation of client handle */ ++ f_print(fout, "\tclnt = clnt_create(host, %s, %s, \"%s\");\n", ++ program_name, vp->vers_name, tirpcflag ? "netpath" : "udp"); ++ f_print(fout, "\tif (clnt == NULL) {\n"); ++ f_print(fout, "\t\tclnt_pcreateerror(host);\n"); ++ f_print(fout, "\t\texit(1);\n\t}\n"); ++ ++ /* generate calls to procedures */ ++ i = 0; ++ for (proc = vp->procs; proc != NULL; proc = proc->next) { ++ f_print(fout, "\tresult_%d = ", ++i); ++ pvname(proc->proc_name, vp->vers_num); ++ if (proc->arg_num < 2 && !newstyle) { ++ f_print(fout, "("); ++ if (streq(proc->args.decls->decl.type, "void")) /* cast to void* */ ++ f_print(fout, "(void*)"); ++ f_print(fout, "&"); ++ pvname(proc->proc_name, vp->vers_num); ++ f_print(fout, "_arg, clnt);\n"); ++ } else if (streq(proc->args.decls->decl.type, "void")) { ++ f_print(fout, "(clnt);\n"); ++ } else { ++ f_print(fout, "("); ++ for (l = proc->args.decls; l != NULL; l = l->next) { ++ pvname(proc->proc_name, vp->vers_num); ++ f_print(fout, "_%s, ", l->decl.name); ++ } ++ f_print(fout, "clnt);\n"); ++ } ++ f_print(fout, "\tif (result_%d == NULL) {\n", i); ++ f_print(fout, "\t\tclnt_perror(clnt, \"call failed:\");\n"); ++ f_print(fout, "\t}\n"); ++ } ++ ++ f_print(fout, "\tclnt_destroy( clnt );\n"); ++ f_print(fout, "}\n"); ++} ++ ++static void ++write_sample_server(definition * def) ++{ ++ version_list *vp; ++ proc_list *proc; ++ ++ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { ++ for (proc = vp->procs; proc != NULL; proc = proc->next) { ++ f_print(fout, "\n"); ++ /* if( Cflag ) ++ f_print( fout, "extern \"C\"{\n"); ++*/ ++ return_type(proc); ++ f_print(fout, "* \n"); ++ if (Cflag) ++ pvname_svc(proc->proc_name, vp->vers_num); ++ else ++ pvname(proc->proc_name, vp->vers_num); ++ printarglist(proc, RQSTP, "struct svc_req *"); ++ ++ f_print(fout, "{\n"); ++ f_print(fout, "\n\tstatic "); ++ if (!streq(proc->res_type, "void")) ++ return_type(proc); ++ else ++ f_print(fout, "char*"); /* cannot have void type */ ++ /* f_print(fout, " result;\n", proc->res_type); */ ++ f_print(fout, " result;\n"); ++ f_print(fout, ++ "\n\t/*\n\t * insert server code here\n\t */\n\n"); ++ if (!streq(proc->res_type, "void")) ++ f_print(fout, "\treturn(&result);\n}\n"); ++ else /* cast back to void * */ ++ f_print(fout, "\treturn((void*) &result);\n}\n"); ++ /* if( Cflag) ++ f_print( fout, "};\n"); ++*/ ++ ++ } ++ } ++} ++ ++ ++ ++static void ++return_type(proc_list *plist) ++{ ++ ptype( plist->res_prefix, plist->res_type, 1 ); ++} ++ ++void ++add_sample_msg(void) ++{ ++ f_print(fout, "/*\n"); ++ f_print(fout, " * This is sample code generated by rpcgen.\n"); ++ f_print(fout, " * These are only templates and you can use them\n"); ++ f_print(fout, " * as a guideline for developing your own functions.\n"); ++ f_print(fout, " */\n\n"); ++} ++ ++void ++write_sample_clnt_main(void) ++{ ++ list *l; ++ definition *def; ++ version_list *vp; ++ ++ f_print(fout, "\n\n" ); ++ if( Cflag ) ++ f_print(fout,"main( int argc, char* argv[] )\n{\n" ); ++ else ++ f_print(fout, "main(argc, argv)\nint argc;\nchar *argv[];\n{\n" ); ++ ++ f_print(fout, "\tchar *host;"); ++ f_print(fout, "\n\n\tif(argc < 2) {"); ++ f_print(fout, "\n\t\tprintf(\"usage: %%s server_host\\n\", argv[0]);\n" ); ++ f_print(fout, "\t\texit(1);\n\t}"); ++ f_print(fout, "\n\thost = argv[1];\n"); ++ ++ for (l = defined; l != NULL; l = l->next) { ++ def = l->val; ++ if (def->def_kind != DEF_PROGRAM) { ++ continue; ++ } ++ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { ++ f_print( fout, "\t" ); ++ pvname(def->def_name, vp->vers_num); ++ f_print( fout, "( host );\n" ); ++ } ++ } ++ f_print(fout, "}\n"); ++} +diff --git a/rpcgen/rpc_scan.c b/rpcgen/rpc_scan.c +new file mode 100644 +index 0000000..f58fa9f +--- /dev/null ++++ b/rpcgen/rpc_scan.c +@@ -0,0 +1,474 @@ ++/* ++ * Copyright (c) 2009, Sun Microsystems, Inc. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions are met: ++ * - Redistributions of source code must retain the above copyright notice, ++ * this list of conditions and the following disclaimer. ++ * - 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. ++ * - Neither the name of Sun Microsystems, Inc. nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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. ++ */ ++ ++#if 0 ++static char sccsid[] = "@(#)rpc_scan.c 1.11 89/02/22 (C) 1987 SMI"; ++#endif ++ ++/* ++ * rpc_scan.c, Scanner for the RPC protocol compiler ++ * Copyright (C) 1987, Sun Microsystems, Inc. ++ */ ++#include <stdio.h> ++#include <ctype.h> ++#include <string.h> ++#include "rpc_scan.h" ++#include "rpc_parse.h" ++#include "rpc_util.h" ++ ++static void unget_token(token *tokp); ++static void findstrconst(char **str, char **val); ++static void findchrconst(char **str, char **val); ++static void findconst(char **str, char **val); ++static void findkind(char **mark, token *tokp); ++static int cppline(char *line); ++static int directive(char *line); ++static void printdirective(char *line); ++static void docppline(char *line, int *lineno, char **fname); ++ ++#define startcomment(where) (where[0] == '/' && where[1] == '*') ++#define endcomment(where) (where[-1] == '*' && where[0] == '/') ++ ++static int pushed = 0; /* is a token pushed */ ++static token lasttok; /* last token, if pushed */ ++ ++/* ++ * scan expecting 1 given token ++ */ ++void ++scan(tok_kind expect, token *tokp) ++{ ++ get_token(tokp); ++ if (tokp->kind != expect) { ++ expected1(expect); ++ } ++} ++ ++/* ++ * scan expecting any of the 2 given tokens ++ */ ++void ++scan2(tok_kind expect1, tok_kind expect2, token *tokp) ++{ ++ get_token(tokp); ++ if (tokp->kind != expect1 && tokp->kind != expect2) { ++ expected2(expect1, expect2); ++ } ++} ++ ++/* ++ * scan expecting any of the 3 given token ++ */ ++void ++scan3(tok_kind expect1, tok_kind expect2, tok_kind expect3, token *tokp) ++{ ++ get_token(tokp); ++ if (tokp->kind != expect1 && tokp->kind != expect2 ++ && tokp->kind != expect3) { ++ expected3(expect1, expect2, expect3); ++ } ++} ++ ++/* ++ * scan expecting a constant, possibly symbolic ++ */ ++void ++scan_num(token *tokp) ++{ ++ get_token(tokp); ++ switch (tokp->kind) { ++ case TOK_IDENT: ++ break; ++ default: ++ error("constant or identifier expected"); ++ } ++} ++ ++/* ++ * Peek at the next token ++ */ ++void ++peek(token *tokp) ++{ ++ get_token(tokp); ++ unget_token(tokp); ++} ++ ++/* ++ * Peek at the next token and scan it if it matches what you expect ++ */ ++int ++peekscan(tok_kind expect, token *tokp) ++{ ++ peek(tokp); ++ if (tokp->kind == expect) { ++ get_token(tokp); ++ return (1); ++ } ++ return (0); ++} ++ ++/* ++ * Get the next token, printing out any directive that are encountered. ++ */ ++void ++get_token(token *tokp) ++{ ++ int commenting; ++ ++ if (pushed) { ++ pushed = 0; ++ *tokp = lasttok; ++ return; ++ } ++ commenting = 0; ++ for (;;) { ++ if (*where == 0) { ++ for (;;) { ++ if (!fgets(curline, MAXLINESIZE, fin)) { ++ tokp->kind = TOK_EOF; ++ *where = 0; ++ return; ++ } ++ linenum++; ++ if (commenting) { ++ break; ++ } else if (cppline(curline)) { ++ docppline(curline, &linenum, ++ &infilename); ++ } else if (directive(curline)) { ++ printdirective(curline); ++ } else { ++ break; ++ } ++ } ++ where = curline; ++ } else if (isspace(*where)) { ++ while (isspace(*where)) { ++ where++; /* eat */ ++ } ++ } else if (commenting) { ++ for (where++; *where; where++) { ++ if (endcomment(where)) { ++ where++; ++ commenting--; ++ break; ++ } ++ } ++ } else if (startcomment(where)) { ++ where += 2; ++ commenting++; ++ } else { ++ break; ++ } ++ } ++ ++ /* ++ * 'where' is not whitespace, comment or directive Must be a token! ++ */ ++ switch (*where) { ++ case ':': ++ tokp->kind = TOK_COLON; ++ where++; ++ break; ++ case ';': ++ tokp->kind = TOK_SEMICOLON; ++ where++; ++ break; ++ case ',': ++ tokp->kind = TOK_COMMA; ++ where++; ++ break; ++ case '=': ++ tokp->kind = TOK_EQUAL; ++ where++; ++ break; ++ case '*': ++ tokp->kind = TOK_STAR; ++ where++; ++ break; ++ case '[': ++ tokp->kind = TOK_LBRACKET; ++ where++; ++ break; ++ case ']': ++ tokp->kind = TOK_RBRACKET; ++ where++; ++ break; ++ case '{': ++ tokp->kind = TOK_LBRACE; ++ where++; ++ break; ++ case '}': ++ tokp->kind = TOK_RBRACE; ++ where++; ++ break; ++ case '(': ++ tokp->kind = TOK_LPAREN; ++ where++; ++ break; ++ case ')': ++ tokp->kind = TOK_RPAREN; ++ where++; ++ break; ++ case '<': ++ tokp->kind = TOK_LANGLE; ++ where++; ++ break; ++ case '>': ++ tokp->kind = TOK_RANGLE; ++ where++; ++ break; ++ ++ case '"': ++ tokp->kind = TOK_STRCONST; ++ findstrconst(&where, &tokp->str); ++ break; ++ case '\'': ++ tokp->kind = TOK_CHARCONST; ++ findchrconst(&where, &tokp->str); ++ break; ++ ++ case '-': ++ case '0': ++ case '1': ++ case '2': ++ case '3': ++ case '4': ++ case '5': ++ case '6': ++ case '7': ++ case '8': ++ case '9': ++ tokp->kind = TOK_IDENT; ++ findconst(&where, &tokp->str); ++ break; ++ ++ default: ++ if (!(isalpha(*where) || *where == '_')) { ++ char buf[100]; ++ char *p; ++ ++ s_print(buf, "illegal character in file: "); ++ p = buf + strlen(buf); ++ if (isprint(*where)) { ++ s_print(p, "%c", *where); ++ } else { ++ s_print(p, "%d", *where); ++ } ++ error(buf); ++ } ++ findkind(&where, tokp); ++ break; ++ } ++} ++ ++static void ++unget_token(token *tokp) ++{ ++ lasttok = *tokp; ++ pushed = 1; ++} ++ ++static void ++findstrconst(char **str, char **val) ++{ ++ char *p; ++ int size; ++ ++ p = *str; ++ do { ++ *p++; ++ } while (*p && *p != '"'); ++ if (*p == 0) { ++ error("unterminated string constant"); ++ } ++ p++; ++ size = p - *str; ++ *val = alloc(size + 1); ++ (void) strncpy(*val, *str, size); ++ (*val)[size] = 0; ++ *str = p; ++} ++ ++static void ++findchrconst(char **str, char **val) ++{ ++ char *p; ++ int size; ++ ++ p = *str; ++ do { ++ *p++; ++ } while (*p && *p != '\''); ++ if (*p == 0) { ++ error("unterminated string constant"); ++ } ++ p++; ++ size = p - *str; ++ if (size != 3) { ++ error("empty char string"); ++ } ++ *val = alloc(size + 1); ++ (void) strncpy(*val, *str, size); ++ (*val)[size] = 0; ++ *str = p; ++} ++ ++static void ++findconst(char **str, char **val) ++{ ++ char *p; ++ int size; ++ ++ p = *str; ++ if (*p == '0' && *(p + 1) == 'x') { ++ p++; ++ do { ++ p++; ++ } while (isxdigit(*p)); ++ } else { ++ do { ++ p++; ++ } while (isdigit(*p)); ++ } ++ size = p - *str; ++ *val = alloc(size + 1); ++ (void) strncpy(*val, *str, size); ++ (*val)[size] = 0; ++ *str = p; ++} ++ ++static token symbols[] = { ++ {TOK_CONST, "const"}, ++ {TOK_UNION, "union"}, ++ {TOK_SWITCH, "switch"}, ++ {TOK_CASE, "case"}, ++ {TOK_DEFAULT, "default"}, ++ {TOK_STRUCT, "struct"}, ++ {TOK_TYPEDEF, "typedef"}, ++ {TOK_ENUM, "enum"}, ++ {TOK_OPAQUE, "opaque"}, ++ {TOK_BOOL, "bool"}, ++ {TOK_VOID, "void"}, ++ {TOK_CHAR, "char"}, ++ {TOK_INT, "int"}, ++ {TOK_UNSIGNED, "unsigned"}, ++ {TOK_SHORT, "short"}, ++ {TOK_INT32, "int32"}, ++ {TOK_FLOAT, "float"}, ++ {TOK_DOUBLE, "double"}, ++ {TOK_STRING, "string"}, ++ {TOK_PROGRAM, "program"}, ++ {TOK_VERSION, "version"}, ++ {TOK_EOF, "??????"}, ++}; ++ ++static void ++findkind(char **mark, token *tokp) ++{ ++ int len; ++ token *s; ++ char *str; ++ ++ str = *mark; ++ for (s = symbols; s->kind != TOK_EOF; s++) { ++ len = strlen(s->str); ++ if (strncmp(str, s->str, len) == 0) { ++ if (!isalnum(str[len]) && str[len] != '_') { ++ tokp->kind = s->kind; ++ tokp->str = s->str; ++ *mark = str + len; ++ return; ++ } ++ } ++ } ++ tokp->kind = TOK_IDENT; ++ for (len = 0; isalnum(str[len]) || str[len] == '_'; len++); ++ tokp->str = alloc(len + 1); ++ (void) strncpy(tokp->str, str, len); ++ tokp->str[len] = 0; ++ *mark = str + len; ++} ++ ++static int ++cppline(char *line) ++{ ++ return (line == curline && *line == '#'); ++} ++ ++static int ++directive(char *line) ++{ ++ return (line == curline && *line == '%'); ++} ++ ++static void ++printdirective(char *line) ++{ ++ f_print(fout, "%s", line + 1); ++} ++ ++static void ++docppline(char *line, int *lineno, char **fname) ++{ ++ char *file; ++ int num; ++ char *p; ++ ++ line++; ++ while (isspace(*line)) { ++ line++; ++ } ++ num = atoi(line); ++ while (isdigit(*line)) { ++ line++; ++ } ++ while (isspace(*line)) { ++ line++; ++ } ++ if (*line != '"') { ++ error("preprocessor error"); ++ } ++ line++; ++ p = file = alloc(strlen(line) + 1); ++ while (*line && *line != '"') { ++ *p++ = *line++; ++ } ++ if (*line == 0) { ++ error("preprocessor error"); ++ } ++ *p = 0; ++ if (*file == 0) { ++ *fname = NULL; ++ free(file); ++ } else { ++ *fname = file; ++ } ++ *lineno = num - 1; ++} +diff --git a/rpcgen/rpc_scan.h b/rpcgen/rpc_scan.h +new file mode 100644 +index 0000000..16f688c +--- /dev/null ++++ b/rpcgen/rpc_scan.h +@@ -0,0 +1,103 @@ ++/* ++ * Copyright (c) 2009, Sun Microsystems, Inc. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions are met: ++ * - Redistributions of source code must retain the above copyright notice, ++ * this list of conditions and the following disclaimer. ++ * - 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. ++ * - Neither the name of Sun Microsystems, Inc. nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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. ++ */ ++ ++/* @(#)rpc_scan.h 1.3 90/08/29 (C) 1987 SMI */ ++ ++/* ++ * rpc_scan.h, Definitions for the RPCL scanner ++ */ ++ ++/* ++ * kinds of tokens ++ */ ++enum tok_kind { ++ TOK_IDENT, ++ TOK_CHARCONST, ++ TOK_STRCONST, ++ TOK_LPAREN, ++ TOK_RPAREN, ++ TOK_LBRACE, ++ TOK_RBRACE, ++ TOK_LBRACKET, ++ TOK_RBRACKET, ++ TOK_LANGLE, ++ TOK_RANGLE, ++ TOK_STAR, ++ TOK_COMMA, ++ TOK_EQUAL, ++ TOK_COLON, ++ TOK_SEMICOLON, ++ TOK_CONST, ++ TOK_STRUCT, ++ TOK_UNION, ++ TOK_SWITCH, ++ TOK_CASE, ++ TOK_DEFAULT, ++ TOK_ENUM, ++ TOK_TYPEDEF, ++ TOK_INT, ++ TOK_SHORT, ++ TOK_INT32, ++ TOK_UNSIGNED, ++ TOK_FLOAT, ++ TOK_DOUBLE, ++ TOK_OPAQUE, ++ TOK_CHAR, ++ TOK_STRING, ++ TOK_BOOL, ++ TOK_VOID, ++ TOK_PROGRAM, ++ TOK_VERSION, ++ TOK_EOF ++}; ++typedef enum tok_kind tok_kind; ++ ++/* ++ * a token ++ */ ++struct token { ++ tok_kind kind; ++ char *str; ++}; ++typedef struct token token; ++ ++ ++/* ++ * routine interface ++ */ ++void scan(); ++void scan2(); ++void scan3(); ++void scan_num(); ++void peek(); ++int peekscan(); ++void get_token(); ++void expected1(tok_kind); ++void expected2(tok_kind, tok_kind); ++void expected3(tok_kind, tok_kind, tok_kind); ++ +diff --git a/rpcgen/rpc_svcout.c b/rpcgen/rpc_svcout.c +new file mode 100644 +index 0000000..284a529 +--- /dev/null ++++ b/rpcgen/rpc_svcout.c +@@ -0,0 +1,882 @@ ++/* ++ * Copyright (c) 2009, Sun Microsystems, Inc. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions are met: ++ * - Redistributions of source code must retain the above copyright notice, ++ * this list of conditions and the following disclaimer. ++ * - 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. ++ * - Neither the name of Sun Microsystems, Inc. nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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. ++ */ ++ ++#if 0 ++ static char sccsid[] = "@(#)rpc_svcout.c 1.29 89/03/30 (C) 1987 SMI"; ++#endif ++ ++/* ++ * rpc_svcout.c, Server-skeleton outputter for the RPC protocol compiler ++ */ ++#include <stdio.h> ++#include <string.h> ++#include "rpc_parse.h" ++#include "rpc_util.h" ++#include "rpc_output.h" ++ ++static void write_real_program(definition *def); ++static void write_program(definition *def, char *storage); ++static void printerr(char *err, char *transp); ++static void printif(char *proc, char *transp, char *prefix, char *arg); ++static void write_inetmost(char *infile); ++static void print_return(char *space); ++static void print_pmapunset(char *space); ++static void print_err_message(char *space); ++static void write_timeout_func(void); ++static void write_pm_most(char *infile, int netflag); ++static void write_rpc_svc_fg(char *infile, char *sp); ++static void open_log_file(char *infile, char *sp); ++ ++static char RQSTP[] = "rqstp"; ++static char TRANSP[] = "transp"; ++static char ARG[] = "argument"; ++static char RESULT[] = "result"; ++static char ROUTINE[] = "local"; ++ ++char _errbuf[256]; /* For all messages */ ++ ++static void ++p_xdrfunc(char *rname, char *typename) ++{ ++ if (Cflag) ++ f_print(fout, "\t\txdr_%s = (xdrproc_t) xdr_%s;\n", rname, ++ stringfix(typename)); ++ else ++ f_print(fout, "\t\txdr_%s = xdr_%s;\n", rname, stringfix(typename)); ++} ++ ++void ++internal_proctype(proc_list *plist) ++{ ++ f_print(fout, "static "); ++ ptype( plist->res_prefix, plist->res_type, 1 ); ++ f_print( fout, "*" ); ++} ++ ++ ++/* ++ * write most of the service, that is, everything but the registrations. ++ */ ++void ++write_most(char *infile, int netflag, int nomain) ++{ ++ if (inetdflag || pmflag) { ++ char* var_type; ++ var_type = (nomain? "extern" : "static"); ++ f_print(fout, "%s int _rpcpmstart;", var_type ); ++ f_print(fout, "\t\t/* Started by a port monitor ? */\n"); ++ f_print(fout, "%s int _rpcfdtype;", var_type ); ++ f_print(fout, "\t\t/* Whether Stream or Datagram ? */\n"); ++ if (timerflag) { ++ f_print(fout, "%s int _rpcsvcdirty;", var_type ); ++ f_print(fout, "\t/* Still serving ? */\n"); ++ } ++ write_svc_aux( nomain ); ++ } ++ /* write out dispatcher and stubs */ ++ write_programs( nomain? (char *)NULL : "static" ); ++ ++ if( nomain ) ++ return; ++ ++ f_print(fout, "\nmain()\n"); ++ f_print(fout, "{\n"); ++ if (inetdflag) { ++ write_inetmost(infile); /* Includes call to write_rpc_svc_fg() */ ++ } else { ++ if( tirpcflag ) { ++ if (netflag) { ++ f_print(fout, "\tregister SVCXPRT *%s;\n", TRANSP); ++ f_print(fout, "\tstruct netconfig *nconf = NULL;\n"); ++ } ++ f_print(fout, "\tpid_t pid;\n"); ++ f_print(fout, "\tint i;\n"); ++ f_print(fout, "\tchar mname[FMNAMESZ + 1];\n\n"); ++ write_pm_most(infile, netflag); ++ f_print(fout, "\telse {\n"); ++ write_rpc_svc_fg(infile, "\t\t"); ++ f_print(fout, "\t}\n"); ++ } else { ++ f_print(fout, "\tregister SVCXPRT *%s;\n", TRANSP); ++ f_print(fout, "\n"); ++ print_pmapunset("\t"); ++ } ++ } ++ ++ if (logflag && !inetdflag) { ++ open_log_file(infile, "\t"); ++ } ++} ++ ++/* ++ * write a registration for the given transport ++ */ ++void ++write_netid_register(char *transp) ++{ ++ list *l; ++ definition *def; ++ version_list *vp; ++ char *sp; ++ char tmpbuf[32]; ++ ++ sp = ""; ++ f_print(fout, "\n"); ++ f_print(fout, "%s\tnconf = getnetconfigent(\"%s\");\n", sp, transp); ++ f_print(fout, "%s\tif (nconf == NULL) {\n", sp); ++ (void) sprintf(_errbuf, "cannot find %s netid.", transp); ++ sprintf(tmpbuf, "%s\t\t", sp); ++ print_err_message(tmpbuf); ++ f_print(fout, "%s\t\texit(1);\n", sp); ++ f_print(fout, "%s\t}\n", sp); ++ f_print(fout, "%s\t%s = svc_tli_create(RPC_ANYFD, nconf, 0, 0, 0);\n", ++ sp, TRANSP); ++ f_print(fout, "%s\tif (%s == NULL) {\n", sp, TRANSP); ++ (void) sprintf(_errbuf, "cannot create %s service.", transp); ++ print_err_message(tmpbuf); ++ f_print(fout, "%s\t\texit(1);\n", sp); ++ f_print(fout, "%s\t}\n", sp); ++ ++ for (l = defined; l != NULL; l = l->next) { ++ def = (definition *) l->val; ++ if (def->def_kind != DEF_PROGRAM) { ++ continue; ++ } ++ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { ++ f_print(fout, ++ "%s\t(void) rpcb_unset(%s, %s, nconf);\n", ++ sp, def->def_name, vp->vers_name); ++ f_print(fout, ++ "%s\tif (!svc_reg(%s, %s, %s, ", ++ sp, TRANSP, def->def_name, vp->vers_name); ++ pvname(def->def_name, vp->vers_num); ++ f_print(fout, ", nconf)) {\n"); ++ (void) sprintf(_errbuf, "unable to register (%s, %s, %s).", ++ def->def_name, vp->vers_name, transp); ++ print_err_message(tmpbuf); ++ f_print(fout, "%s\t\texit(1);\n", sp); ++ f_print(fout, "%s\t}\n", sp); ++ } ++ } ++ f_print(fout, "%s\tfreenetconfigent(nconf);\n", sp); ++} ++ ++/* ++ * write a registration for the given transport for TLI ++ */ ++void ++write_nettype_register(char *transp) ++{ ++ list *l; ++ definition *def; ++ version_list *vp; ++ ++ for (l = defined; l != NULL; l = l->next) { ++ def = (definition *) l->val; ++ if (def->def_kind != DEF_PROGRAM) { ++ continue; ++ } ++ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { ++ f_print(fout, "\tif (!svc_create("); ++ pvname(def->def_name, vp->vers_num); ++ f_print(fout, ", %s, %s, \"%s\")) {\n ", ++ def->def_name, vp->vers_name, transp); ++ (void) sprintf(_errbuf, ++ "unable to create (%s, %s) for %s.", ++ def->def_name, vp->vers_name, transp); ++ print_err_message("\t\t"); ++ f_print(fout, "\t\texit(1);\n"); ++ f_print(fout, "\t}\n"); ++ } ++ } ++} ++ ++/* ++ * write the rest of the service ++ */ ++void ++write_rest(void) ++{ ++ f_print(fout, "\n"); ++ if (inetdflag) { ++ f_print(fout, "\tif (%s == (SVCXPRT *)NULL) {\n", TRANSP); ++ (void) sprintf(_errbuf, "could not create a handle"); ++ print_err_message("\t\t"); ++ f_print(fout, "\t\texit(1);\n"); ++ f_print(fout, "\t}\n"); ++ if (timerflag) { ++ f_print(fout, "\tif (_rpcpmstart) {\n"); ++ f_print(fout, ++ "\t\t(void) signal(SIGALRM, %s closedown);\n", ++ Cflag? "(SIG_PF)" : "(void(*)())" ); ++ f_print(fout, "\t\t(void) alarm(_RPCSVC_CLOSEDOWN);\n"); ++ f_print(fout, "\t}\n"); ++ } ++ } ++ f_print(fout, "\tsvc_run();\n"); ++ (void) sprintf(_errbuf, "svc_run returned"); ++ print_err_message("\t"); ++ f_print(fout, "\texit(1);\n"); ++ f_print(fout, "\t/* NOTREACHED */\n"); ++ f_print(fout, "}\n"); ++} ++ ++void ++write_programs(char *storage) ++{ ++ list *l; ++ definition *def; ++ ++ /* write out stubs for procedure definitions */ ++ for (l = defined; l != NULL; l = l->next) { ++ def = (definition *) l->val; ++ if (def->def_kind == DEF_PROGRAM) { ++ write_real_program(def); ++ } ++ } ++ ++ /* write out dispatcher for each program */ ++ for (l = defined; l != NULL; l = l->next) { ++ def = (definition *) l->val; ++ if (def->def_kind == DEF_PROGRAM) { ++ write_program(def, storage); ++ } ++ } ++ ++ ++} ++ ++/* write out definition of internal function (e.g. _printmsg_1(...)) ++ which calls server's defintion of actual function (e.g. printmsg_1(...)). ++ Unpacks single user argument of printmsg_1 to call-by-value format ++ expected by printmsg_1. */ ++static void ++write_real_program(definition *def) ++{ ++ version_list *vp; ++ proc_list *proc; ++ decl_list *l; ++ ++ if( !newstyle ) return; /* not needed for old style */ ++ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { ++ for (proc = vp->procs; proc != NULL; proc = proc->next) { ++ f_print(fout, "\n"); ++ internal_proctype(proc); ++ f_print(fout, "\n_"); ++ pvname(proc->proc_name, vp->vers_num); ++ if( Cflag ) { ++ f_print(fout, "(" ); ++ /* arg name */ ++ if (proc->arg_num > 1) ++ f_print(fout, proc->args.argname); ++ else ++ ptype(proc->args.decls->decl.prefix, ++ proc->args.decls->decl.type, 0); ++ f_print(fout, " *argp, struct svc_req *%s)\n", ++ RQSTP); ++ } else { ++ f_print(fout, "(argp, %s)\n", RQSTP ); ++ /* arg name */ ++ if (proc->arg_num > 1) ++ f_print(fout, "\t%s *argp;\n", proc->args.argname); ++ else { ++ f_print(fout, "\t"); ++ ptype(proc->args.decls->decl.prefix, ++ proc->args.decls->decl.type, 0); ++ f_print(fout, " *argp;\n"); ++ } ++ f_print(fout, " struct svc_req *%s;\n", RQSTP); ++ } ++ ++ f_print(fout, "{\n"); ++ f_print(fout, "\treturn("); ++ if( Cflag ) ++ pvname_svc(proc->proc_name, vp->vers_num); ++ else ++ pvname(proc->proc_name, vp->vers_num); ++ f_print(fout, "("); ++ if (proc->arg_num < 2) { /* single argument */ ++ if (!streq( proc->args.decls->decl.type, "void")) ++ f_print(fout, "*argp, "); /* non-void */ ++ } else { ++ for (l = proc->args.decls; l != NULL; l = l->next) ++ f_print(fout, "argp->%s, ", l->decl.name); ++ } ++ f_print(fout, "%s));\n}\n", RQSTP); ++ } ++ } ++} ++ ++static void ++write_program(definition *def, char *storage) ++{ ++ version_list *vp; ++ proc_list *proc; ++ int filled; ++ ++ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { ++ f_print(fout, "\n"); ++ if (storage != NULL) { ++ f_print(fout, "%s ", storage); ++ } ++ f_print(fout, "void\n"); ++ pvname(def->def_name, vp->vers_num); ++ ++ if (Cflag) { ++ f_print(fout, "(struct svc_req *%s, ", RQSTP); ++ f_print(fout, "register SVCXPRT *%s)\n", TRANSP); ++ } else { ++ f_print(fout, "(%s, %s)\n", RQSTP, TRANSP); ++ f_print(fout, " struct svc_req *%s;\n", RQSTP); ++ f_print(fout, " register SVCXPRT *%s;\n", TRANSP); ++ } ++ ++ f_print(fout, "{\n"); ++ ++ filled = 0; ++ f_print(fout, "\tunion {\n"); ++ for (proc = vp->procs; proc != NULL; proc = proc->next) { ++ if (proc->arg_num < 2) { /* single argument */ ++ if (streq(proc->args.decls->decl.type, ++ "void")) { ++ continue; ++ } ++ filled = 1; ++ f_print(fout, "\t\t"); ++ ptype(proc->args.decls->decl.prefix, ++ proc->args.decls->decl.type, 0); ++ pvname(proc->proc_name, vp->vers_num); ++ f_print(fout, "_arg;\n"); ++ ++ } ++ else { ++ filled = 1; ++ f_print(fout, "\t\t%s", proc->args.argname); ++ f_print(fout, " "); ++ pvname(proc->proc_name, vp->vers_num); ++ f_print(fout, "_arg;\n"); ++ } ++ } ++ if (!filled) { ++ f_print(fout, "\t\tint fill;\n"); ++ } ++ f_print(fout, "\t} %s;\n", ARG); ++ f_print(fout, "\tchar *%s;\n", RESULT); ++ ++ if (Cflag) { ++ f_print(fout, "\txdrproc_t xdr_%s, xdr_%s;\n", ARG, RESULT); ++ f_print(fout, ++ "\tchar *(*%s)(char *, struct svc_req *);\n", ++ ROUTINE); ++ } else { ++ f_print(fout, "\tbool_t (*xdr_%s)(), (*xdr_%s)();\n", ARG, RESULT); ++ f_print(fout, "\tchar *(*%s)();\n", ROUTINE); ++ } ++ ++ f_print(fout, "\n"); ++ ++ if (timerflag) ++ f_print(fout, "\t_rpcsvcdirty = 1;\n"); ++ f_print(fout, "\tswitch (%s->rq_proc) {\n", RQSTP); ++ if (!nullproc(vp->procs)) { ++ f_print(fout, "\tcase NULLPROC:\n"); ++ f_print(fout, ++ "\t\t(void) svc_sendreply(%s, (xdrproc_t) xdr_void, (char *)NULL);\n", ++ TRANSP); ++ print_return("\t\t"); ++ f_print(fout, "\n"); ++ } ++ for (proc = vp->procs; proc != NULL; proc = proc->next) { ++ f_print(fout, "\tcase %s:\n", proc->proc_name); ++ if (proc->arg_num < 2) { /* single argument */ ++ p_xdrfunc( ARG, proc->args.decls->decl.type); ++ } else { ++ p_xdrfunc( ARG, proc->args.argname); ++ } ++ p_xdrfunc( RESULT, proc->res_type); ++ if( Cflag ) ++ f_print(fout, ++ "\t\t%s = (char *(*)(char *, struct svc_req *)) ", ++ ROUTINE); ++ else ++ f_print(fout, "\t\t%s = (char *(*)()) ", ROUTINE); ++ ++ if (newstyle) { /* new style: calls internal routine */ ++ f_print(fout,"_"); ++ } ++ /* Not sure about the following... ++ * rpc_hout always generates foobar_1_svc for ++ * the service procedure, so why should we use ++ * foobar_1 here?! --okir */ ++#if 0 ++ if( Cflag && !newstyle ) ++ pvname_svc(proc->proc_name, vp->vers_num); ++ else ++ pvname(proc->proc_name, vp->vers_num); ++#else ++ pvname_svc(proc->proc_name, vp->vers_num); ++#endif ++ f_print(fout, ";\n"); ++ f_print(fout, "\t\tbreak;\n\n"); ++ } ++ f_print(fout, "\tdefault:\n"); ++ printerr("noproc", TRANSP); ++ print_return("\t\t"); ++ f_print(fout, "\t}\n"); ++ ++ f_print(fout, "\t(void) memset((char *)&%s, 0, sizeof (%s));\n", ARG, ARG); ++ if (Cflag) ++ printif("getargs", TRANSP, "(caddr_t) &", ARG); ++ else ++ printif("getargs", TRANSP, "&", ARG); ++ printerr("decode", TRANSP); ++ print_return("\t\t"); ++ f_print(fout, "\t}\n"); ++ ++ if (Cflag) ++ f_print(fout, "\t%s = (*%s)((char *)&%s, %s);\n", ++ RESULT, ROUTINE, ARG, RQSTP); ++ else ++ f_print(fout, "\t%s = (*%s)(&%s, %s);\n", ++ RESULT, ROUTINE, ARG, RQSTP); ++ f_print(fout, ++ "\tif (%s != NULL && !svc_sendreply(%s, " ++ "(xdrproc_t) xdr_%s, %s)) {\n", ++ RESULT, TRANSP, RESULT, RESULT); ++ printerr("systemerr", TRANSP); ++ f_print(fout, "\t}\n"); ++ ++ if (Cflag) ++ printif("freeargs", TRANSP, "(caddr_t) &", ARG); ++ else ++ printif("freeargs", TRANSP, "&", ARG); ++ (void) sprintf(_errbuf, "unable to free arguments"); ++ print_err_message("\t\t"); ++ f_print(fout, "\t\texit(1);\n"); ++ f_print(fout, "\t}\n"); ++ print_return("\t"); ++ f_print(fout, "}\n"); ++ } ++} ++ ++static void ++printerr(char *err, char *transp) ++{ ++ f_print(fout, "\t\tsvcerr_%s(%s);\n", err, transp); ++} ++ ++static void ++printif(char *proc, char *transp, char *prefix, char *arg) ++{ ++ f_print(fout, "\tif (!svc_%s(%s, (xdrproc_t) xdr_%s, (caddr_t) %s%s)) {\n", ++ proc, transp, arg, prefix, arg); ++} ++ ++int ++nullproc(proc_list *proc) ++{ ++ for (; proc != NULL; proc = proc->next) { ++ if (streq(proc->proc_num, "0")) { ++ return (1); ++ } ++ } ++ return (0); ++} ++ ++static void ++write_inetmost(char *infile) ++{ ++ f_print(fout, "\tregister SVCXPRT *%s;\n", TRANSP); ++ f_print(fout, "\tint sock;\n"); ++ f_print(fout, "\tint proto;\n"); ++ f_print(fout, "\tstruct sockaddr_in saddr;\n"); ++ f_print(fout, "\tint asize = sizeof (saddr);\n"); ++ f_print(fout, "\n"); ++ f_print(fout, ++ "\tif (getsockname(0, (struct sockaddr *)&saddr, &asize) == 0) {\n"); ++ f_print(fout, "\t\tint ssize = sizeof (int);\n\n"); ++ f_print(fout, "\t\tif (saddr.sin_family != AF_INET)\n"); ++ f_print(fout, "\t\t\texit(1);\n"); ++ f_print(fout, "\t\tif (getsockopt(0, SOL_SOCKET, SO_TYPE,\n"); ++ f_print(fout, "\t\t\t\t(char *)&_rpcfdtype, &ssize) == -1)\n"); ++ f_print(fout, "\t\t\texit(1);\n"); ++ f_print(fout, "\t\tsock = 0;\n"); ++ f_print(fout, "\t\t_rpcpmstart = 1;\n"); ++ f_print(fout, "\t\tproto = 0;\n"); ++ open_log_file(infile, "\t\t"); ++ f_print(fout, "\t} else {\n"); ++ write_rpc_svc_fg(infile, "\t\t"); ++ f_print(fout, "\t\tsock = RPC_ANYSOCK;\n"); ++ print_pmapunset("\t\t"); ++ f_print(fout, "\t}\n"); ++} ++ ++static void ++print_return(char *space) ++{ ++ if (exitnow) ++ f_print(fout, "%sexit(0);\n", space); ++ else { ++ if (timerflag) ++ f_print(fout, "%s_rpcsvcdirty = 0;\n", space); ++ f_print(fout, "%sreturn;\n", space); ++ } ++} ++ ++static void ++print_pmapunset(char *space) ++{ ++ list *l; ++ definition *def; ++ version_list *vp; ++ ++ for (l = defined; l != NULL; l = l->next) { ++ def = (definition *) l->val; ++ if (def->def_kind == DEF_PROGRAM) { ++ for (vp = def->def.pr.versions; vp != NULL; ++ vp = vp->next) { ++ f_print(fout, "%s(void) pmap_unset(%s, %s);\n", ++ space, def->def_name, vp->vers_name); ++ } ++ } ++ } ++} ++ ++static void ++print_err_message(char *space) ++{ ++ if (logflag) ++ f_print(fout, "%ssyslog(LOG_ERR, \"%s\");\n", space, _errbuf); ++ else if (inetdflag || pmflag) ++ f_print(fout, "%s_msgout(\"%s\");\n", space, _errbuf); ++ else ++ f_print(fout, "%sfprintf(stderr, \"%s\");\n", space, _errbuf); ++} ++ ++/* ++ * Write the server auxiliary function ( _msgout, timeout) ++ */ ++void ++write_svc_aux(int nomain) ++{ ++ if (!logflag) ++ write_msg_out(); ++ if( !nomain ) ++ write_timeout_func(); ++} ++ ++/* ++ * Write the _msgout function ++ */ ++void ++write_msg_out(void) ++{ ++ f_print(fout, "\n"); ++ f_print(fout, "static\n"); ++ if( !Cflag ) { ++ f_print(fout, "void _msgout(msg)\n"); ++ f_print(fout, "\tchar *msg;\n"); ++ } else { ++ f_print(fout, "void _msgout(char* msg)\n"); ++ } ++ f_print(fout, "{\n"); ++ f_print(fout, "#ifdef RPC_SVC_FG\n"); ++ if (inetdflag || pmflag) ++ f_print(fout, "\tif (_rpcpmstart)\n"); ++ f_print(fout, "\t\tsyslog(LOG_ERR, \"%%s\", msg);\n"); ++ f_print(fout, "\telse\n"); ++ f_print(fout, "\t\t(void) fprintf(stderr, \"%%s\\n\", msg);\n"); ++ f_print(fout, "#else\n"); ++ f_print(fout, "\tsyslog(LOG_ERR, \"%%s\", msg);\n"); ++ f_print(fout, "#endif\n"); ++ f_print(fout, "}\n"); ++} ++ ++/* ++ * Write the timeout function ++ */ ++static void ++write_timeout_func(void) ++{ ++ if (!timerflag) ++ return; ++ f_print(fout, "\n"); ++ f_print(fout, "static void\n"); ++ f_print(fout, "closedown()\n"); ++ f_print(fout, "{\n"); ++ f_print(fout, "\tif (_rpcsvcdirty == 0) {\n"); ++ f_print(fout, "\t\tstatic int size;\n"); ++ f_print(fout, "\t\tint i, openfd;\n"); ++ if (tirpcflag && pmflag) { ++ f_print(fout, "\t\tstruct t_info tinfo;\n\n"); ++ f_print(fout, "\t\tif (!t_getinfo(0, &tinfo) && (tinfo.servtype == T_CLTS))\n"); ++ } else { ++ f_print(fout, "\n\t\tif (_rpcfdtype == SOCK_DGRAM)\n"); ++ } ++ f_print(fout, "\t\t\texit(0);\n"); ++ f_print(fout, "\t\tif (size == 0) {\n"); ++ if( tirpcflag ) { ++ f_print(fout, "\t\t\tstruct rlimit rl;\n\n"); ++ f_print(fout, "\t\t\trl.rlim_max = 0;\n"); ++ f_print(fout, "\t\t\tgetrlimit(RLIMIT_NOFILE, &rl);\n"); ++ f_print(fout, "\t\t\tif ((size = rl.rlim_max) == 0)\n"); ++ f_print(fout, "\t\t\t\treturn;\n"); ++ } else { ++ f_print(fout, "\t\t\tsize = getdtablesize();\n"); ++ } ++ f_print(fout, "\t\t}\n"); ++ f_print(fout, "\t\tfor (i = 0, openfd = 0; i < size && openfd < 2; i++)\n"); ++ f_print(fout, "\t\t\tif (FD_ISSET(i, &svc_fdset))\n"); ++ f_print(fout, "\t\t\t\topenfd++;\n"); ++ f_print(fout, "\t\tif (openfd <= 1)\n"); ++ f_print(fout, "\t\t\texit(0);\n"); ++ f_print(fout, "\t}\n"); ++ f_print(fout, "\t(void) alarm(_RPCSVC_CLOSEDOWN);\n"); ++ f_print(fout, "}\n"); ++} ++ ++/* ++ * Write the most of port monitor support ++ */ ++static void ++write_pm_most(char *infile, int netflag) ++{ ++ list *l; ++ definition *def; ++ version_list *vp; ++ ++ f_print(fout, "\tif (!ioctl(0, I_LOOK, mname) &&\n"); ++ f_print(fout, "\t\t(!strcmp(mname, \"sockmod\") ||"); ++ f_print(fout, " !strcmp(mname, \"timod\"))) {\n"); ++ f_print(fout, "\t\tchar *netid;\n"); ++ if (!netflag) { /* Not included by -n option */ ++ f_print(fout, "\t\tstruct netconfig *nconf = NULL;\n"); ++ f_print(fout, "\t\tSVCXPRT *%s;\n", TRANSP); ++ } ++ if( timerflag ) ++ f_print(fout, "\t\tint pmclose;\n"); ++/* not necessary, defined in /usr/include/stdlib */ ++/* f_print(fout, "\t\textern char *getenv();\n");*/ ++ f_print(fout, "\n"); ++ f_print(fout, "\t\t_rpcpmstart = 1;\n"); ++ if (logflag) ++ open_log_file(infile, "\t\t"); ++ f_print(fout, "\t\tif ((netid = getenv(\"NLSPROVIDER\")) == NULL) {\n"); ++ sprintf(_errbuf, "cannot get transport name"); ++ print_err_message("\t\t\t"); ++ f_print(fout, "\t\t} else if ((nconf = getnetconfigent(netid)) == NULL) {\n"); ++ sprintf(_errbuf, "cannot get transport info"); ++ print_err_message("\t\t\t"); ++ f_print(fout, "\t\t}\n"); ++ /* ++ * A kludgy support for inetd services. Inetd only works with ++ * sockmod, and RPC works only with timod, hence all this jugglery ++ */ ++ f_print(fout, "\t\tif (strcmp(mname, \"sockmod\") == 0) {\n"); ++ f_print(fout, "\t\t\tif (ioctl(0, I_POP, 0) || ioctl(0, I_PUSH, \"timod\")) {\n"); ++ sprintf(_errbuf, "could not get the right module"); ++ print_err_message("\t\t\t\t"); ++ f_print(fout, "\t\t\t\texit(1);\n"); ++ f_print(fout, "\t\t\t}\n"); ++ f_print(fout, "\t\t}\n"); ++ if( timerflag ) ++ f_print(fout, "\t\tpmclose = (t_getstate(0) != T_DATAXFER);\n"); ++ f_print(fout, "\t\tif ((%s = svc_tli_create(0, nconf, NULL, 0, 0)) == NULL) {\n", ++ TRANSP); ++ sprintf(_errbuf, "cannot create server handle"); ++ print_err_message("\t\t\t"); ++ f_print(fout, "\t\t\texit(1);\n"); ++ f_print(fout, "\t\t}\n"); ++ f_print(fout, "\t\tif (nconf)\n"); ++ f_print(fout, "\t\t\tfreenetconfigent(nconf);\n"); ++ for (l = defined; l != NULL; l = l->next) { ++ def = (definition *) l->val; ++ if (def->def_kind != DEF_PROGRAM) { ++ continue; ++ } ++ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { ++ f_print(fout, ++ "\t\tif (!svc_reg(%s, %s, %s, ", ++ TRANSP, def->def_name, vp->vers_name); ++ pvname(def->def_name, vp->vers_num); ++ f_print(fout, ", 0)) {\n"); ++ (void) sprintf(_errbuf, "unable to register (%s, %s).", ++ def->def_name, vp->vers_name); ++ print_err_message("\t\t\t"); ++ f_print(fout, "\t\t\texit(1);\n"); ++ f_print(fout, "\t\t}\n"); ++ } ++ } ++ if (timerflag) { ++ f_print(fout, "\t\tif (pmclose) {\n"); ++ f_print(fout, "\t\t\t(void) signal(SIGALRM, %s closedown);\n", ++ Cflag? "(SIG_PF)" : "(void(*)())" ); ++ f_print(fout, "\t\t\t(void) alarm(_RPCSVC_CLOSEDOWN);\n"); ++ f_print(fout, "\t\t}\n"); ++ } ++ f_print(fout, "\t\tsvc_run();\n"); ++ f_print(fout, "\t\texit(1);\n"); ++ f_print(fout, "\t\t/* NOTREACHED */\n"); ++ f_print(fout, "\t}\n"); ++} ++ ++/* ++ * Support for backgrounding the server if self started. ++ */ ++static void ++write_rpc_svc_fg(char *infile, char *sp) ++{ ++ f_print(fout, "#ifndef RPC_SVC_FG\n"); ++ f_print(fout, "%sint size;\n", sp); ++ if( tirpcflag ) ++ f_print(fout, "%sstruct rlimit rl;\n", sp); ++ if (inetdflag) ++ f_print(fout, "%sint pid, i;\n\n", sp); ++ f_print(fout, "%spid = fork();\n", sp); ++ f_print(fout, "%sif (pid < 0) {\n", sp); ++ f_print(fout, "%s\tperror(\"cannot fork\");\n", sp); ++ f_print(fout, "%s\texit(1);\n", sp); ++ f_print(fout, "%s}\n", sp); ++ f_print(fout, "%sif (pid)\n", sp); ++ f_print(fout, "%s\texit(0);\n", sp); ++ /* get number of file descriptors */ ++ if( tirpcflag ) { ++ f_print(fout, "%srl.rlim_max = 0;\n", sp); ++ f_print(fout, "%sgetrlimit(RLIMIT_NOFILE, &rl);\n", sp); ++ f_print(fout, "%sif ((size = rl.rlim_max) == 0)\n", sp); ++ f_print(fout, "%s\texit(1);\n", sp); ++ } else { ++ f_print(fout, "%ssize = getdtablesize();\n", sp); ++ } ++ ++ f_print(fout, "%sfor (i = 0; i < size; i++)\n", sp); ++ f_print(fout, "%s\t(void) close(i);\n", sp); ++ /* Redirect stderr and stdout to console */ ++ f_print(fout, "%si = open(\"/dev/console\", 2);\n", sp); ++ f_print(fout, "%s(void) dup2(i, 1);\n", sp); ++ f_print(fout, "%s(void) dup2(i, 2);\n", sp); ++ /* This removes control of the controlling terminal */ ++ if( tirpcflag ) ++ f_print(fout, "%ssetsid();\n", sp); ++ else { ++ f_print(fout, "%si = open(\"/dev/tty\", 2);\n", sp); ++ f_print(fout, "%sif (i >= 0) {\n", sp); ++ f_print(fout, "%s\t(void) ioctl(i, TIOCNOTTY, (char *)NULL);\n", sp);; ++ f_print(fout, "%s\t(void) close(i);\n", sp); ++ f_print(fout, "%s}\n", sp); ++ } ++ if (!logflag) ++ open_log_file(infile, sp); ++ f_print(fout, "#endif\n"); ++ if (logflag) ++ open_log_file(infile, sp); ++} ++ ++static void ++open_log_file(char *infile, char *sp) ++{ ++ char *s; ++ ++ s = strrchr(infile, '.'); ++ if (s) ++ *s = '\0'; ++ f_print(fout,"%sopenlog(\"%s\", LOG_PID, LOG_DAEMON);\n", sp, infile); ++ if (s) ++ *s = '.'; ++} ++ ++ ++ ++ ++/* ++ * write a registration for the given transport for Inetd ++ */ ++void ++write_inetd_register(char *transp) ++{ ++ list *l; ++ definition *def; ++ version_list *vp; ++ char *sp; ++ int isudp; ++ char tmpbuf[32]; ++ ++ if (inetdflag) ++ sp = "\t"; ++ else ++ sp = ""; ++ if (streq(transp, "udp")) ++ isudp = 1; ++ else ++ isudp = 0; ++ f_print(fout, "\n"); ++ if (inetdflag) { ++ f_print(fout, "\tif ((_rpcfdtype == 0) || (_rpcfdtype == %s)) {\n", ++ isudp ? "SOCK_DGRAM" : "SOCK_STREAM"); ++ } ++ f_print(fout, "%s\t%s = svc%s_create(%s", ++ sp, TRANSP, transp, inetdflag? "sock": "RPC_ANYSOCK"); ++ if (!isudp) ++ f_print(fout, ", 0, 0"); ++ f_print(fout, ");\n"); ++ f_print(fout, "%s\tif (%s == NULL) {\n", sp, TRANSP); ++ (void) sprintf(_errbuf, "cannot create %s service.", transp); ++ (void) sprintf(tmpbuf, "%s\t\t", sp); ++ print_err_message(tmpbuf); ++ f_print(fout, "%s\t\texit(1);\n", sp); ++ f_print(fout, "%s\t}\n", sp); ++ ++ if (inetdflag) { ++ f_print(fout, "%s\tif (!_rpcpmstart)\n\t", sp); ++ f_print(fout, "%s\tproto = IPPROTO_%s;\n", ++ sp, isudp ? "UDP": "TCP"); ++ } ++ for (l = defined; l != NULL; l = l->next) { ++ def = (definition *) l->val; ++ if (def->def_kind != DEF_PROGRAM) { ++ continue; ++ } ++ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { ++ f_print(fout, "%s\tif (!svc_register(%s, %s, %s, ", ++ sp, TRANSP, def->def_name, vp->vers_name); ++ pvname(def->def_name, vp->vers_num); ++ if (inetdflag) ++ f_print(fout, ", proto)) {\n"); ++ else ++ f_print(fout, ", IPPROTO_%s)) {\n", ++ isudp ? "UDP": "TCP"); ++ (void) sprintf(_errbuf, "unable to register (%s, %s, %s).", ++ def->def_name, vp->vers_name, transp); ++ print_err_message(tmpbuf); ++ f_print(fout, "%s\t\texit(1);\n", sp); ++ f_print(fout, "%s\t}\n", sp); ++ } ++ } ++ if (inetdflag) ++ f_print(fout, "\t}\n"); ++} +diff --git a/rpcgen/rpc_tblout.c b/rpcgen/rpc_tblout.c +new file mode 100644 +index 0000000..ae002f7 +--- /dev/null ++++ b/rpcgen/rpc_tblout.c +@@ -0,0 +1,165 @@ ++/* ++ * Copyright (c) 2009, Sun Microsystems, Inc. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions are met: ++ * - Redistributions of source code must retain the above copyright notice, ++ * this list of conditions and the following disclaimer. ++ * - 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. ++ * - Neither the name of Sun Microsystems, Inc. nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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. ++ */ ++ ++#if 0 ++static char sccsid[] = "@(#)rpc_tblout.c 1.4 89/02/22 (C) 1988 SMI"; ++#endif ++ ++/* ++ * rpc_tblout.c, Dispatch table outputter for the RPC protocol compiler ++ */ ++#include <stdio.h> ++#include <string.h> ++#include "rpc_parse.h" ++#include "rpc_util.h" ++#include "rpc_output.h" ++ ++static void write_table(definition *def); ++static void printit(char *prefix, char *type); ++ ++#define TABSIZE 8 ++#define TABCOUNT 5 ++#define TABSTOP (TABSIZE*TABCOUNT) ++ ++static char tabstr[TABCOUNT+1] = "\t\t\t\t\t"; ++ ++static char tbl_hdr[] = "struct rpcgen_table %s_table[] = {\n"; ++static char tbl_end[] = "};\n"; ++ ++static char null_entry[] = "\n\t(char *(*)())0,\n\ ++ \t(xdrproc_t) xdr_void,\t\t\t0,\n\ ++ \t(xdrproc_t) xdr_void,\t\t\t0,\n"; ++ ++ ++static char tbl_nproc[] = "int %s_nproc =\n\tsizeof(%s_table)/sizeof(%s_table[0]);\n\n"; ++ ++void ++write_tables(void) ++{ ++ list *l; ++ definition *def; ++ ++ f_print(fout, "\n"); ++ for (l = defined; l != NULL; l = l->next) { ++ def = (definition *) l->val; ++ if (def->def_kind == DEF_PROGRAM) { ++ write_table(def); ++ } ++ } ++} ++ ++static void ++write_table(definition *def) ++{ ++ version_list *vp; ++ proc_list *proc; ++ int current; ++ int expected; ++ char progvers[100]; ++ int warning; ++ ++ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { ++ warning = 0; ++ s_print(progvers, "%s_%s", ++ locase(def->def_name), vp->vers_num); ++ /* print the table header */ ++ f_print(fout, tbl_hdr, progvers); ++ ++ if (nullproc(vp->procs)) { ++ expected = 0; ++ } else { ++ expected = 1; ++ f_print(fout, null_entry); ++ } ++ for (proc = vp->procs; proc != NULL; proc = proc->next) { ++ current = atoi(proc->proc_num); ++ if (current != expected++) { ++ f_print(fout, ++ "\n/*\n * WARNING: table out of order\n */\n"); ++ if (warning == 0) { ++ f_print(stderr, ++ "WARNING %s table is out of order\n", ++ progvers); ++ warning = 1; ++ nonfatalerrors = 1; ++ } ++ expected = current + 1; ++ } ++ f_print(fout, "\n\t(char *(*)())RPCGEN_ACTION("); ++ ++ /* routine to invoke */ ++ if( Cflag && !newstyle ) ++ pvname_svc(proc->proc_name, vp->vers_num); ++ else { ++ if( newstyle ) ++ f_print( fout, "_"); /* calls internal func */ ++ pvname(proc->proc_name, vp->vers_num); ++ } ++ f_print(fout, "),\n"); ++ ++ /* argument info */ ++ if( proc->arg_num > 1 ) ++ printit((char*) NULL, proc->args.argname ); ++ else ++ /* do we have to do something special for newstyle */ ++ printit( proc->args.decls->decl.prefix, ++ proc->args.decls->decl.type ); ++ /* result info */ ++ printit(proc->res_prefix, proc->res_type); ++ } ++ ++ /* print the table trailer */ ++ f_print(fout, tbl_end); ++ f_print(fout, tbl_nproc, progvers, progvers, progvers); ++ } ++} ++ ++static void ++printit(char *prefix, char *type) ++{ ++ int len; ++ int tabs; ++ ++ ++ len = fprintf(fout, "\txdr_%s,", stringfix(type)); ++ /* account for leading tab expansion */ ++ len += TABSIZE - 1; ++ /* round up to tabs required */ ++ tabs = (TABSTOP - len + TABSIZE - 1)/TABSIZE; ++ f_print(fout, "%s", &tabstr[TABCOUNT-tabs]); ++ ++ if (streq(type, "void")) { ++ f_print(fout, "0"); ++ } else { ++ f_print(fout, "sizeof ( "); ++ /* XXX: should "follow" be 1 ??? */ ++ ptype(prefix, type, 0); ++ f_print(fout, ")"); ++ } ++ f_print(fout, ",\n"); ++} +diff --git a/rpcgen/rpc_util.c b/rpcgen/rpc_util.c +new file mode 100644 +index 0000000..b67be57 +--- /dev/null ++++ b/rpcgen/rpc_util.c +@@ -0,0 +1,479 @@ ++/* ++ * Copyright (c) 2009, Sun Microsystems, Inc. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions are met: ++ * - Redistributions of source code must retain the above copyright notice, ++ * this list of conditions and the following disclaimer. ++ * - 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. ++ * - Neither the name of Sun Microsystems, Inc. nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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. ++ */ ++ ++#if 0 ++static char sccsid[] = "@(#)rpc_util.c 1.11 89/02/22 (C) 1987 SMI"; ++#endif ++ ++/* ++ * rpc_util.c, Utility routines for the RPC protocol compiler ++ */ ++#include <stdio.h> ++#include <memory.h> ++#include <ctype.h> ++#include <unistd.h> ++#include "rpc_scan.h" ++#include "rpc_parse.h" ++#include "rpc_util.h" ++ ++static void printwhere(void); ++ ++ ++#define ARGEXT "argument" ++ ++char curline[MAXLINESIZE]; /* current read line */ ++char *where = curline; /* current point in line */ ++int linenum = 0; /* current line number */ ++ ++char *infilename; /* input filename */ ++ ++#define NFILES 7 ++char *outfiles[NFILES]; /* output file names */ ++int nfiles; ++ ++FILE *fout; /* file pointer of current output */ ++FILE *fin; /* file pointer of current input */ ++ ++list *defined; /* list of defined things */ ++ ++/* ++ * Reinitialize the world ++ */ ++void ++reinitialize(void) ++{ ++ memset(curline, 0, MAXLINESIZE); ++ where = curline; ++ linenum = 0; ++ defined = NULL; ++} ++ ++/* ++ * string equality ++ */ ++int ++streq(char *a, char *b) ++{ ++ return (strcmp(a, b) == 0); ++} ++ ++/* ++ * find a value in a list ++ */ ++definition * ++findval(list *lst, char *val, int (*cmp)(definition *, char *)) ++{ ++ ++ for (; lst != NULL; lst = lst->next) { ++ if ((*cmp) (lst->val, val)) { ++ return (lst->val); ++ } ++ } ++ return (NULL); ++} ++ ++/* ++ * store a value in a list ++ */ ++void ++storeval(lstp, val) ++ list **lstp; ++ definition *val; ++{ ++ list **l; ++ list *lst; ++ ++ ++ for (l = lstp; *l != NULL; l = (list **) & (*l)->next); ++ lst = ALLOC(list); ++ lst->val = val; ++ lst->next = NULL; ++ *l = lst; ++} ++ ++static int ++findit(definition *def, char *type) ++{ ++ return (streq(def->def_name, type)); ++} ++ ++static char * ++fixit(char *type, char *orig) ++{ ++ definition *def; ++ ++ def = (definition *) FINDVAL(defined, type, findit); ++ if (def == NULL || def->def_kind != DEF_TYPEDEF) { ++ return (orig); ++ } ++ switch (def->def.ty.rel) { ++ case REL_VECTOR: ++ return (def->def.ty.old_type); ++ case REL_ALIAS: ++ return (fixit(def->def.ty.old_type, orig)); ++ default: ++ return (orig); ++ } ++} ++ ++char * ++fixtype(char *type) ++{ ++ return (fixit(type, type)); ++} ++ ++char * ++stringfix(char *type) ++{ ++ if (streq(type, "string")) { ++ return ("wrapstring"); ++ } else { ++ return (type); ++ } ++} ++ ++void ++ptype(char *prefix, char *type, int follow) ++{ ++ if (prefix != NULL) { ++ if (streq(prefix, "enum")) { ++ f_print(fout, "enum "); ++ } else { ++ f_print(fout, "struct "); ++ } ++ } ++ if (streq(type, "bool")) { ++ f_print(fout, "bool_t "); ++ } else if (streq(type, "string")) { ++ f_print(fout, "char *"); ++ } else { ++ f_print(fout, "%s ", follow ? fixtype(type) : type); ++ } ++} ++ ++static int ++typedefed(definition *def, char *type) ++{ ++ if (def->def_kind != DEF_TYPEDEF || def->def.ty.old_prefix != NULL) { ++ return (0); ++ } else { ++ return (streq(def->def_name, type)); ++ } ++} ++ ++int ++isvectordef(char *type, relation rel) ++{ ++ definition *def; ++ ++ for (;;) { ++ switch (rel) { ++ case REL_VECTOR: ++ return (!streq(type, "string")); ++ case REL_ARRAY: ++ return (0); ++ case REL_POINTER: ++ return (0); ++ case REL_ALIAS: ++ def = (definition *) FINDVAL(defined, type, typedefed); ++ if (def == NULL) { ++ return (0); ++ } ++ type = def->def.ty.old_type; ++ rel = def->def.ty.rel; ++ } ++ } ++} ++ ++char * ++locase(char *str) ++{ ++ char c; ++ static char buf[100]; ++ char *p = buf; ++ ++ while ((c = *str++) != '\0') { ++ *p++ = (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c; ++ } ++ *p = 0; ++ return (buf); ++} ++ ++void ++pvname_svc(char *pname, char *vnum) ++{ ++ f_print(fout, "%s_%s_svc", locase(pname), vnum); ++} ++ ++void ++pvname(char *pname, char *vnum) ++{ ++ f_print(fout, "%s_%s", locase(pname), vnum); ++} ++ ++/* ++ * print a useful (?) error message, and then die ++ */ ++void ++error(char *msg) ++{ ++ printwhere(); ++ f_print(stderr, "%s, line %d: ", infilename, linenum); ++ f_print(stderr, "%s\n", msg); ++ crash(); ++} ++ ++/* ++ * Something went wrong, unlink any files that we may have created and then ++ * die. ++ */ ++void ++crash(void) ++{ ++ int i; ++ ++ for (i = 0; i < nfiles; i++) { ++ (void) unlink(outfiles[i]); ++ } ++ exit(1); ++} ++ ++void ++record_open(char *file) ++{ ++ if (nfiles < NFILES) { ++ outfiles[nfiles++] = file; ++ } else { ++ f_print(stderr, "too many files!\n"); ++ crash(); ++ } ++} ++ ++static char expectbuf[100]; ++static char *toktostr(); ++ ++/* ++ * error, token encountered was not the expected one ++ */ ++void ++expected1(exp1) ++ tok_kind exp1; ++{ ++ s_print(expectbuf, "expected '%s'", ++ toktostr(exp1)); ++ error(expectbuf); ++} ++ ++/* ++ * error, token encountered was not one of two expected ones ++ */ ++void ++expected2(exp1, exp2) ++ tok_kind exp1, exp2; ++{ ++ s_print(expectbuf, "expected '%s' or '%s'", ++ toktostr(exp1), ++ toktostr(exp2)); ++ error(expectbuf); ++} ++ ++/* ++ * error, token encountered was not one of 3 expected ones ++ */ ++void ++expected3(exp1, exp2, exp3) ++ tok_kind exp1, exp2, exp3; ++{ ++ s_print(expectbuf, "expected '%s', '%s' or '%s'", ++ toktostr(exp1), ++ toktostr(exp2), ++ toktostr(exp3)); ++ error(expectbuf); ++} ++ ++void ++tabify(f, tab) ++ FILE *f; ++ int tab; ++{ ++ while (tab--) { ++ (void) fputc('\t', f); ++ } ++} ++ ++ ++static token tokstrings[] = { ++ {TOK_IDENT, "identifier"}, ++ {TOK_CONST, "const"}, ++ {TOK_RPAREN, ")"}, ++ {TOK_LPAREN, "("}, ++ {TOK_RBRACE, "}"}, ++ {TOK_LBRACE, "{"}, ++ {TOK_LBRACKET, "["}, ++ {TOK_RBRACKET, "]"}, ++ {TOK_STAR, "*"}, ++ {TOK_COMMA, ","}, ++ {TOK_EQUAL, "="}, ++ {TOK_COLON, ":"}, ++ {TOK_SEMICOLON, ";"}, ++ {TOK_UNION, "union"}, ++ {TOK_STRUCT, "struct"}, ++ {TOK_SWITCH, "switch"}, ++ {TOK_CASE, "case"}, ++ {TOK_DEFAULT, "default"}, ++ {TOK_ENUM, "enum"}, ++ {TOK_TYPEDEF, "typedef"}, ++ {TOK_INT, "int"}, ++ {TOK_SHORT, "short"}, ++ {TOK_INT32, "int32"}, ++ {TOK_UNSIGNED, "unsigned"}, ++ {TOK_DOUBLE, "double"}, ++ {TOK_FLOAT, "float"}, ++ {TOK_CHAR, "char"}, ++ {TOK_STRING, "string"}, ++ {TOK_OPAQUE, "opaque"}, ++ {TOK_BOOL, "bool"}, ++ {TOK_VOID, "void"}, ++ {TOK_PROGRAM, "program"}, ++ {TOK_VERSION, "version"}, ++ {TOK_EOF, "??????"} ++}; ++ ++static char * ++toktostr(kind) ++ tok_kind kind; ++{ ++ token *sp; ++ ++ for (sp = tokstrings; sp->kind != TOK_EOF && sp->kind != kind; sp++); ++ return (sp->str); ++} ++ ++static void ++printbuf(void) ++{ ++ char c; ++ int i; ++ int cnt; ++ ++# define TABSIZE 4 ++ ++ for (i = 0; (c = curline[i]) != '\0'; i++) { ++ if (c == '\t') { ++ cnt = 8 - (i % TABSIZE); ++ c = ' '; ++ } else { ++ cnt = 1; ++ } ++ while (cnt--) { ++ (void) fputc(c, stderr); ++ } ++ } ++} ++ ++static void ++printwhere(void) ++{ ++ int i; ++ char c; ++ int cnt; ++ ++ printbuf(); ++ for (i = 0; i < where - curline; i++) { ++ c = curline[i]; ++ if (c == '\t') { ++ cnt = 8 - (i % TABSIZE); ++ } else { ++ cnt = 1; ++ } ++ while (cnt--) { ++ (void) fputc('^', stderr); ++ } ++ } ++ (void) fputc('\n', stderr); ++} ++ ++char * ++make_argname(char *pname, char *vname) ++{ ++ char *name; ++ ++ name = malloc(strlen(pname) + strlen(vname) + strlen(ARGEXT) + 3); ++ if (!name) { ++ fprintf(stderr, "failed in malloc"); ++ exit(1); ++ } ++ sprintf(name, "%s_%s_%s", locase(pname), vname, ARGEXT); ++ return(name); ++} ++ ++bas_type *typ_list_h; ++bas_type *typ_list_t; ++ ++void ++add_type(int len, char *type) ++{ ++ bas_type *ptr; ++ ++ ++ if ((ptr = (bas_type *) malloc(sizeof(bas_type))) == (bas_type *) NULL) { ++ fprintf(stderr, "failed in malloc"); ++ exit(1); ++ } ++ ptr->name = type; ++ ptr->length = len; ++ ptr->next = NULL; ++ if (typ_list_t == NULL) { ++ ++ typ_list_t = ptr; ++ typ_list_h = ptr; ++ } else { ++ ++ typ_list_t->next = ptr; ++ typ_list_t = ptr; ++ } ++} ++ ++ ++bas_type * ++find_type(char *type) ++{ ++ bas_type *ptr; ++ ++ ptr = typ_list_h; ++ ++ ++ while (ptr != NULL) { ++ if (strcmp(ptr->name, type) == 0) ++ return (ptr); ++ else ++ ptr = ptr->next; ++ }; ++ return (NULL); ++} ++ +diff --git a/rpcgen/rpc_util.h b/rpcgen/rpc_util.h +new file mode 100644 +index 0000000..fa115be +--- /dev/null ++++ b/rpcgen/rpc_util.h +@@ -0,0 +1,166 @@ ++/* ++ * Copyright (c) 2009, Sun Microsystems, Inc. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions are met: ++ * - Redistributions of source code must retain the above copyright notice, ++ * this list of conditions and the following disclaimer. ++ * - 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. ++ * - Neither the name of Sun Microsystems, Inc. nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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. ++ */ ++ ++/* @(#)rpc_util.h 1.5 90/08/29 (C) 1987 SMI */ ++ ++/* ++ * rpc_util.h, Useful definitions for the RPC protocol compiler ++ */ ++ ++#include <stdlib.h> ++ ++#define alloc(size) malloc((unsigned)(size)) ++#define ALLOC(object) (object *) malloc(sizeof(object)) ++ ++#define s_print (void) sprintf ++#define f_print (void) fprintf ++ ++struct list { ++ definition *val; ++ struct list *next; ++}; ++typedef struct list list; ++ ++#define PUT 1 ++#define GET 2 ++ ++/* ++ * Global variables ++ */ ++#define MAXLINESIZE 1024 ++extern char curline[MAXLINESIZE]; ++extern char *where; ++extern int linenum; ++ ++extern char *infilename; ++extern FILE *fout; ++extern FILE *fin; ++ ++extern list *defined; ++ ++ ++extern bas_type *typ_list_h; ++extern bas_type *typ_list_t; ++ ++/* ++ * All the option flags ++ */ ++extern int inetdflag; ++extern int pmflag; ++extern int tblflag; ++extern int logflag; ++extern int newstyle; ++extern int Cflag; /* C++ flag */ ++extern int tirpcflag; /* flag for generating tirpc code */ ++extern int Inline; /* if this is 0, then do not generate inline code */ ++ ++/* ++ * Other flags related with inetd jumpstart. ++ */ ++extern int indefinitewait; ++extern int exitnow; ++extern int timerflag; ++ ++extern int nonfatalerrors; ++ ++/* ++ * rpc_util routines ++ */ ++void storeval(); ++ ++#define STOREVAL(list,item) \ ++ storeval(list,item) ++ ++definition *findval(); ++ ++#define FINDVAL(list,item,finder) \ ++ findval(list, item, finder) ++ ++ ++/* ++ * rpc_cout routines ++ */ ++void cprint(void); ++void emit(definition *); ++ ++/* ++ * rpc_hout routines ++ */ ++void print_datadef(definition *); ++void print_funcdef(definition *); ++ ++/* ++ * rpc_svcout routines ++ */ ++void write_most(char *, int, int); ++void write_register(void); ++void write_netid_register(char *); ++void write_nettype_register(char *); ++void write_inetd_register(char *); ++void write_rest(void); ++void write_programs(char *); ++void write_svc_aux(int); ++ ++/* ++ * rpc_clntout routines ++ */ ++void write_stubs(void); ++void printarglist(proc_list *, char *, char *); ++ ++/* ++ * rpc_tblout routines ++ */ ++void write_tables(void); ++ ++/* ++ * rpc_util ++ */ ++void pvname_svc(char *, char *); ++void pvname(char *, char *); ++void ptype(char *, char *, int); ++char * make_argname(char *, char *); ++void add_type(int, char *); ++void reinitialize(void); ++void crash(void); ++void error(char *); ++char *fixtype(char *); ++char *stringfix(char *); ++char *locase(char *); ++int isvectordef(char *, relation); ++int streq(char *, char *); ++void tabify(FILE *, int); ++void record_open(char *); ++bas_type *find_type(char *type); ++ ++/* ++ * rpc_sample ++ */ ++void write_sample_svc(definition *); ++int write_sample_clnt(definition *); ++void write_sample_clnt_main(void); ++void add_sample_msg(void); +diff --git a/rpcgen/rpcgen.1 b/rpcgen/rpcgen.1 +new file mode 100644 +index 0000000..89df7ed +--- /dev/null ++++ b/rpcgen/rpcgen.1 +@@ -0,0 +1,521 @@ ++.\" @(#)rpcgen.1 1.35 93/06/02 SMI ++.\" $FreeBSD: src/usr.bin/rpcgen/rpcgen.1,v 1.12.2.4 2002/06/21 15:28:50 charnier Exp $ ++.\" Copyright 1985-1993 Sun Microsystems, Inc. ++.Dd March 28, 1993 ++.Dt RPCGEN 1 ++.Os ++.Sh NAME ++.Nm rpcgen ++.Nd an RPC protocol compiler ++.Sh SYNOPSIS ++.Nm ++.Ar infile ++.Nm ++.Op Fl a ++.Op Fl b ++.Op Fl C ++.Oo ++.Fl D Ns Ar name Ns Op Ar =value ++.Oc ++.Op Fl i Ar size ++.Op Fl I Op Fl K Ar seconds ++.Op Fl L ++.Op Fl M ++.Op Fl N ++.Op Fl T ++.Op Fl Y Ar pathname ++.Ar infile ++.Nm ++.Oo ++.Fl c | ++.Fl h | ++.Fl l | ++.Fl m | ++.Fl t | ++.Fl \&Sc | ++.Fl \&Ss | ++.Fl \&Sm ++.Oc ++.Op Fl o Ar outfile ++.Op Ar infile ++.Nm ++.Op Fl s Ar nettype ++.Op Fl o Ar outfile ++.Op Ar infile ++.Nm ++.Op Fl n Ar netid ++.Op Fl o Ar outfile ++.Op Ar infile ++.\" .SH AVAILABILITY ++.\" .LP ++.\" SUNWcsu ++.Sh DESCRIPTION ++The ++.Nm ++utility is a tool that generates C code to implement an ++.Tn RPC ++protocol. ++The input to ++.Nm ++is a language similar to C known as ++.Tn RPC ++Language (Remote Procedure Call Language). ++.Pp ++The ++.Nm ++utility is normally used as in the first synopsis where ++it takes an input file and generates three output files. ++If the ++.Ar infile ++is named ++.Pa proto.x , ++then ++.Nm ++generates a header in ++.Pa proto.h , ++XDR routines in ++.Pa proto_xdr.c , ++server-side stubs in ++.Pa proto_svc.c , ++and client-side stubs in ++.Pa proto_clnt.c . ++With the ++.Fl T ++option, ++it also generates the ++.Tn RPC ++dispatch table in ++.Pa proto_tbl.i . ++.Pp ++The ++.Nm ++utility can also generate sample client and server files ++that can be customized to suit a particular application. ++The ++.Fl \&Sc , ++.Fl \&Ss ++and ++.Fl \&Sm ++options generate sample client, server and makefile, respectively. ++The ++.Fl a ++option generates all files, including sample files. ++If the ++.Ar infile ++is ++.Pa proto.x , ++then the client side sample file is written to ++.Pa proto_client.c , ++the server side sample file to ++.Pa proto_server.c ++and the sample makefile to ++.Pa makefile.proto . ++.Pp ++The server created can be started both by the port monitors ++(for example, ++.Xr inetd 8 ) ++or by itself. ++When it is started by a port monitor, ++it creates servers only for the transport for which ++the file descriptor ++.Em 0 ++was passed. ++The name of the transport must be specified ++by setting up the environment variable ++.Ev PM_TRANSPORT . ++When the server generated by ++.Nm ++is executed, ++it creates server handles for all the transports ++specified in ++.Ev NETPATH ++environment variable, ++or if it is unset, ++it creates server handles for all the visible transports from ++.Pa /etc/netconfig ++file. ++Note: ++the transports are chosen at run time and not at compile time. ++When the server is self-started, ++it backgrounds itself by default. ++A special define symbol ++.Em RPC_SVC_FG ++can be used to run the server process in foreground. ++.Pp ++The second synopsis provides special features which allow ++for the creation of more sophisticated ++.Tn RPC ++servers. ++These features include support for user provided ++.Em #defines ++and ++.Tn RPC ++dispatch tables. ++The entries in the ++.Tn RPC ++dispatch table contain: ++.Bl -bullet -offset indent -compact ++.It ++pointers to the service routine corresponding to that procedure, ++.It ++a pointer to the input and output arguments, ++.It ++the size of these routines. ++.El ++A server can use the dispatch table to check authorization ++and then to execute the service routine; ++a client library may use it to deal with the details of storage ++management and XDR data conversion. ++.Pp ++The other three synopses shown above are used when ++one does not want to generate all the output files, ++but only a particular one. ++See the ++.Sx EXAMPLES ++section below for examples of ++.Nm ++usage. ++When ++.Nm ++is executed with the ++.Fl s ++option, ++it creates servers for that particular class of transports. ++When ++executed with the ++.Fl n ++option, ++it creates a server for the transport specified by ++.Ar netid . ++If ++.Ar infile ++is not specified, ++.Nm ++accepts the standard input. ++.Pp ++The C preprocessor, ++.Em cc -E ++is run on the input file before it is actually interpreted by ++.Nm . ++For each type of output file, ++.Nm ++defines a special preprocessor symbol for use by the ++.Nm ++programmer: ++.Bl -tag -width indent ++.It RPC_HDR ++defined when compiling into headers ++.It RPC_XDR ++defined when compiling into XDR routines ++.It RPC_SVC ++defined when compiling into server-side stubs ++.It RPC_CLNT ++defined when compiling into client-side stubs ++.It RPC_TBL ++defined when compiling into RPC dispatch tables ++.El ++.Pp ++Any line beginning with ++.Dq % ++is passed directly into the output file, ++uninterpreted by ++.Nm . ++To specify the path name of the C preprocessor use ++.Fl Y ++flag. ++.Pp ++For every data type referred to in ++.Ar infile , ++.Nm ++assumes that there exists a ++routine with the string ++.Em xdr_ ++prepended to the name of the data type. ++If this routine does not exist in the ++.Tn RPC/XDR ++library, it must be provided. ++Providing an undefined data type ++allows customization of ++.Xr xdr 3 ++routines. ++.Sh OPTIONS ++The following options are available: ++.Bl -tag -width indent ++.It Fl a ++Generate all files, including sample files. ++.It Fl b ++Backward compatibility mode. ++Generate transport specific ++.Tn RPC ++code for older versions ++of the operating system. ++.Pp ++Note: in ++.Fx , ++this compatibility flag is turned on by ++default since ++.Fx ++supports only the older ++.Tn ONC RPC ++library. ++.It Fl c ++Compile into ++.Tn XDR ++routines. ++.It Fl C ++Generate header and stub files which can be used with ++.Tn ANSI ++C compilers. Headers generated with this flag can also be ++used with C++ programs. ++.It Fl D Ns Ar name ++.It Fl D Ns Ar name=value ++.\".It Fl D Ns Ar name Ns Op Ar =value ++Define a symbol ++.Ar name . ++Equivalent to the ++.Em #define ++directive in the source. ++If no ++.Ar value ++is given, ++.Ar value ++is defined as ++.Em 1 . ++This option may be specified more than once. ++.It Fl h ++Compile into C data-definitions (a header). ++.Fl T ++option can be used in conjunction to produce a ++header which supports ++.Tn RPC ++dispatch tables. ++.It Fl i Ar size ++Size at which to start generating inline code. ++This option is useful for optimization. ++The default size is 5. ++.Pp ++Note: in order to provide backwards compatibility with the older ++.Nm ++on the ++.Fx ++platform, the default is actually 0 (which means ++that inline code generation is disabled by default). You must specify ++a non-zero value explicitly to override this default. ++.It Fl I ++Compile support for ++.Xr inetd 8 ++in the server side stubs. ++Such servers can be self-started or can be started by ++.Nm inetd . ++When the server is self-started, it backgrounds itself by default. ++A special define symbol ++.Em RPC_SVC_FG ++can be used to run the ++server process in foreground, or the user may simply compile without ++the ++.Fl I ++option. ++.Pp ++If there are no pending client requests, the ++.Nm inetd ++servers exit after 120 seconds (default). ++The default can be changed with the ++.Fl K ++option. ++All the error messages for ++.Nm inetd ++servers ++are always logged with ++.Xr syslog 3 . ++.\" .IP ++.\" Note: ++.\" this option is supported for backward compatibility only. ++.\" By default, ++.\" .B rpcgen ++.\" generates servers that can be invoked through portmonitors. ++.Pp ++.It Fl K Ar seconds ++By default, services created using ++.Nm ++and invoked through ++port monitors wait 120 seconds ++after servicing a request before exiting. ++That interval can be changed using the ++.Fl K ++flag. ++To create a server that exits immediately upon servicing a request, ++use ++.Fl K Ar 0 . ++To create a server that never exits, the appropriate argument is ++.Fl k Ar -1 . ++.Pp ++When monitoring for a server, ++some portmonitors ++.Em always ++spawn a new process in response to a service request. ++If it is known that a server will be used with such a monitor, the ++server should exit immediately on completion. ++For such servers, ++.Nm ++should be used with ++.Fl K Ar 0 . ++.It Fl l ++Compile into client-side stubs. ++.It Fl L ++When the servers are started in foreground, use ++.Xr syslog 3 ++to log the server errors instead of printing them on the standard ++error. ++.It Fl m ++Compile into server-side stubs, ++but do not generate a ++.Qq main ++routine. ++This option is useful for doing callback-routines ++and for users who need to write their own ++.Qq main ++routine to do initialization. ++.It Fl M ++Generate multithread-safe stubs for passing arguments and results between ++rpcgen generated code and user written code. ++This option is useful ++for users who want to use threads in their code. ++However, the ++.Xr rpc_svc_calls 3 ++functions are not yet MT-safe, which means that rpcgen generated server-side ++code will not be MT-safe. ++.It Fl N ++This option allows procedures to have multiple arguments. ++It also uses the style of parameter passing that closely resembles C. ++So, when passing an argument to a remote procedure, you do not have to ++pass a pointer to the argument, but can pass the argument itself. ++This behavior is different from the old style of ++.Nm ++generated code. ++To maintain backward compatibility, ++this option is not the default. ++.It Fl n Ar netid ++Compile into server-side stubs for the transport ++specified by ++.Ar netid . ++There should be an entry for ++.Ar netid ++in the ++netconfig database. ++This option may be specified more than once, ++so as to compile a server that serves multiple transports. ++.It Fl o Ar outfile ++Specify the name of the output file. ++If none is specified, ++standard output is used ++( ++.Fl c , ++.Fl h , ++.Fl l , ++.Fl m , ++.Fl n , ++.Fl s , ++.Fl \&Sc , ++.Fl \&Sm , ++.Fl \&Ss , ++and ++.Fl t ++modes only). ++.It Fl s Ar nettype ++Compile into server-side stubs for all the ++transports belonging to the class ++.Ar nettype . ++The supported classes are ++.Em netpath , ++.Em visible , ++.Em circuit_n , ++.Em circuit_v , ++.Em datagram_n , ++.Em datagram_v , ++.Em tcp , ++and ++.Em udp ++(see ++.Xr rpc 3 ++for the meanings associated with these classes). ++This option may be specified more than once. ++Note: ++the transports are chosen at run time and not at compile time. ++.It Fl \&Sc ++Generate sample client code that uses remote procedure calls. ++.It Fl \&Sm ++Generate a sample ++.Pa Makefile ++which can be used for compiling the application. ++.It Fl \&Ss ++Generate sample server code that uses remote procedure calls. ++.It Fl t ++Compile into ++.Tn RPC ++dispatch table. ++.It Fl T ++Generate the code to support ++.Tn RPC ++dispatch tables. ++.Pp ++The options ++.Fl c , ++.Fl h , ++.Fl l , ++.Fl m , ++.Fl s , ++.Fl \&Sc , ++.Fl \&Sm , ++.Fl \&Ss , ++and ++.Fl t ++are used exclusively to generate a particular type of file, ++while the options ++.Fl D ++and ++.Fl T ++are global and can be used with the other options. ++.It Fl Y Ar pathname ++Give the name of the directory where ++.Nm ++will start looking for the C-preprocessor. ++.El ++.Sh EXAMPLES ++The following example: ++.Dl example% rpcgen -T prot.x ++.Pp ++generates all the five files: ++.Pa prot.h , ++.Pa prot_clnt.c , ++.Pa prot_svc.c , ++.Pa prot_xdr.c ++and ++.Pa prot_tbl.i . ++.Pp ++The following example sends the C data-definitions (header) ++to the standard output. ++.Dl example% rpcgen -h prot.x ++.Pp ++To send the test version of the ++.Fl D Ns Ar TEST , ++server side stubs for ++all the transport belonging to the class ++.Ar datagram_n ++to standard output, use: ++.Dl example% rpcgen -s datagram_n -DTEST prot.x ++.Pp ++To create the server side stubs for the transport indicated ++by ++.Ar netid ++tcp, ++use: ++.Dl example% rpcgen -n tcp -o prot_svc.c prot.x ++.Sh SEE ALSO ++.Xr cc 1 , ++.Xr rpc 3 , ++.Xr syslog 3 , ++.Xr inetd 8 ++.\" .BR rpc_svc_calls (3) ++.Rs ++.%T The rpcgen chapter in the NETP manual ++.Re +-- +1.7.9.5 + diff --git a/package/libtirpc/libtirpc-0009-Automatically-generate-XDR-header-files-from-.x-sour.patch b/package/libtirpc/libtirpc-0009-Automatically-generate-XDR-header-files-from-.x-sour.patch new file mode 100644 index 000000000..787452a6d --- /dev/null +++ b/package/libtirpc/libtirpc-0009-Automatically-generate-XDR-header-files-from-.x-sour.patch @@ -0,0 +1,999 @@ +From 30fac06891c59a7fb784f6faa4e92921a84c73db Mon Sep 17 00:00:00 2001 +From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +Date: Sat, 10 Nov 2012 17:29:53 +0100 +Subject: [PATCH] Automatically generate XDR header files from .x sources + using rpcgen + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +--- + Makefile.am | 23 +- + src/Makefile.am | 2 +- + tirpc/rpc/rpcb_prot.h | 797 ------------------------------------------------- + tirpc/rpcsvc/crypt.h | 109 ------- + 4 files changed, 21 insertions(+), 910 deletions(-) + delete mode 100644 tirpc/rpc/rpcb_prot.h + delete mode 100644 tirpc/rpcsvc/crypt.h + +diff --git a/Makefile.am b/Makefile.am +index afb4e38..7e63f78 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -1,9 +1,12 @@ + SUBDIRS = src man doc rpcgen + ACLOCAL_AMFLAGS = -I m4 + ++GENFILES = \ ++ tirpc/rpcsvc/crypt.h \ ++ tirpc/rpc/rpcb_prot.h ++ + nobase_include_HEADERS = tirpc/netconfig.h \ + tirpc/rpcsvc/crypt.x \ +- tirpc/rpcsvc/crypt.h \ + tirpc/rpc/xdr.h \ + tirpc/rpc/types.h \ + tirpc/rpc/svc_soc.h \ +@@ -15,7 +18,6 @@ nobase_include_HEADERS = tirpc/netconfig.h \ + tirpc/rpc/rpcent.h \ + tirpc/rpc/rpc_com.h \ + tirpc/rpc/rpcb_prot.x \ +- tirpc/rpc/rpcb_prot.h \ + tirpc/rpc/rpcb_clnt.h \ + tirpc/rpc/raw.h \ + tirpc/rpc/pmap_rmt.h \ +@@ -32,6 +34,21 @@ nobase_include_HEADERS = tirpc/netconfig.h \ + tirpc/rpc/auth.h \ + tirpc/rpc/auth_gss.h \ + tirpc/rpc/auth_des.h +- ++ ++nobase_nodist_include_HEADERS = $(GENFILES) ++ ++BUILT_SOURCES = $(GENFILES) ++ + pkgconfigdir=$(libdir)/pkgconfig + pkgconfig_DATA = libtirpc.pc ++ ++$(GENFILES): %.h: %.x $(top_builddir)/rpcgen/rpcgen ++ mkdir -p $(dir $@) ++ $(top_builddir)/rpcgen/rpcgen -h -o $@ $< ++ ++$(top_builddir)/rpcgen/rpcgen: force ++ cd rpcgen && $(MAKE) ++ ++force: ++ ++CLEANFILES = $(GENFILES) +diff --git a/src/Makefile.am b/src/Makefile.am +index 6dc259e..bd276cf 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -7,7 +7,7 @@ + + + INCLUDES = -I$(top_srcdir)/tirpc -DPORTMAP -DVERSION="\"$(VERSION)\"" \ +- -D_GNU_SOURCE -Wall -pipe ++ -D_GNU_SOURCE -Wall -pipe -I$(top_builddir)/tirpc + + lib_LTLIBRARIES = libtirpc.la + +diff --git a/tirpc/rpc/rpcb_prot.h b/tirpc/rpc/rpcb_prot.h +deleted file mode 100644 +index 7ae48b8..0000000 +--- a/tirpc/rpc/rpcb_prot.h ++++ /dev/null +@@ -1,797 +0,0 @@ +-/* +- * Please do not edit this file. +- * It was generated using rpcgen. +- */ +- +-#ifndef _RPCB_PROT_H_RPCGEN +-#define _RPCB_PROT_H_RPCGEN +- +-#include <rpc/rpc.h> +- +-#ifndef IXDR_GET_INT32 +-#define IXDR_GET_INT32(buf) IXDR_GET_LONG((buf)) +-#endif +-#ifndef IXDR_PUT_INT32 +-#define IXDR_PUT_INT32(buf, v) IXDR_PUT_LONG((buf), (v)) +-#endif +-#ifndef IXDR_GET_U_INT32 +-#define IXDR_GET_U_INT32(buf) IXDR_GET_U_LONG((buf)) +-#endif +-#ifndef IXDR_PUT_U_INT32 +-#define IXDR_PUT_U_INT32(buf, v) IXDR_PUT_U_LONG((buf), (v)) +-#endif +-/* +- * $FreeBSD: src/include/rpc/rpcb_prot.x,v 1.3 2002/03/13 10:29:06 obrien Exp $ +- * +- * Copyright (c) 2009, Sun Microsystems, Inc. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions are met: +- * - Redistributions of source code must retain the above copyright notice, +- * this list of conditions and the following disclaimer. +- * - 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. +- * - Neither the name of Sun Microsystems, Inc. nor the names of its +- * contributors may be used to endorse or promote products derived +- * from this software without specific prior written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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. +- */ +-/* +- * Copyright (c) 1988 by Sun Microsystems, Inc. +- */ +-/* from rpcb_prot.x */ +- +-/* #pragma ident "@(#)rpcb_prot.x 1.5 94/04/29 SMI" */ +- +-#ifndef _KERNEL +- +- +-/* +- * The following procedures are supported by the protocol in version 3: +- * +- * RPCBPROC_NULL() returns () +- * takes nothing, returns nothing +- * +- * RPCBPROC_SET(rpcb) returns (bool_t) +- * TRUE is success, FALSE is failure. Registers the tuple +- * [prog, vers, address, owner, netid]. +- * Finds out owner and netid information on its own. +- * +- * RPCBPROC_UNSET(rpcb) returns (bool_t) +- * TRUE is success, FALSE is failure. Un-registers tuple +- * [prog, vers, netid]. addresses is ignored. +- * If netid is NULL, unregister all. +- * +- * RPCBPROC_GETADDR(rpcb) returns (string). +- * 0 is failure. Otherwise returns the universal address where the +- * triple [prog, vers, netid] is registered. Ignore address and owner. +- * +- * RPCBPROC_DUMP() RETURNS (rpcblist_ptr) +- * used to dump the entire rpcbind maps +- * +- * RPCBPROC_CALLIT(rpcb_rmtcallargs) +- * RETURNS (rpcb_rmtcallres); +- * Calls the procedure on the remote machine. If it is not registered, +- * this procedure is quiet; i.e. it does not return error information!!! +- * This routine only passes null authentication parameters. +- * It has no interface to xdr routines for RPCBPROC_CALLIT. +- * +- * RPCBPROC_GETTIME() returns (int). +- * Gets the remote machines time +- * +- * RPCBPROC_UADDR2TADDR(strint) RETURNS (struct netbuf) +- * Returns the netbuf address from universal address. +- * +- * RPCBPROC_TADDR2UADDR(struct netbuf) RETURNS (string) +- * Returns the universal address from netbuf address. +- * +- * END OF RPCBIND VERSION 3 PROCEDURES +- */ +-/* +- * Except for RPCBPROC_CALLIT, the procedures above are carried over to +- * rpcbind version 4. Those below are added or modified for version 4. +- * NOTE: RPCBPROC_BCAST HAS THE SAME FUNCTIONALITY AND PROCEDURE NUMBER +- * AS RPCBPROC_CALLIT. +- * +- * RPCBPROC_BCAST(rpcb_rmtcallargs) +- * RETURNS (rpcb_rmtcallres); +- * Calls the procedure on the remote machine. If it is not registered, +- * this procedure IS quiet; i.e. it DOES NOT return error information!!! +- * This routine should be used for broadcasting and nothing else. +- * +- * RPCBPROC_GETVERSADDR(rpcb) returns (string). +- * 0 is failure. Otherwise returns the universal address where the +- * triple [prog, vers, netid] is registered. Ignore address and owner. +- * Same as RPCBPROC_GETADDR except that if the given version number +- * is not available, the address is not returned. +- * +- * RPCBPROC_INDIRECT(rpcb_rmtcallargs) +- * RETURNS (rpcb_rmtcallres); +- * Calls the procedure on the remote machine. If it is not registered, +- * this procedure is NOT quiet; i.e. it DOES return error information!!! +- * as any normal application would expect. +- * +- * RPCBPROC_GETADDRLIST(rpcb) returns (rpcb_entry_list_ptr). +- * Same as RPCBPROC_GETADDR except that it returns a list of all the +- * addresses registered for the combination (prog, vers) (for all +- * transports). +- * +- * RPCBPROC_GETSTAT(void) returns (rpcb_stat_byvers) +- * Returns the statistics about the kind of requests received by rpcbind. +- */ +- +-/* +- * A mapping of (program, version, network ID) to address +- */ +- +-struct rpcb { +- rpcprog_t r_prog; +- rpcvers_t r_vers; +- char *r_netid; +- char *r_addr; +- char *r_owner; +-}; +-typedef struct rpcb rpcb; +-#ifdef __cplusplus +-extern "C" bool_t xdr_rpcb(XDR *, rpcb*); +-#elif __STDC__ +-extern bool_t xdr_rpcb(XDR *, rpcb*); +-#else /* Old Style C */ +-bool_t xdr_rpcb(); +-#endif /* Old Style C */ +- +- +-typedef rpcb RPCB; +- +- +-/* +- * A list of mappings +- * +- * Below are two definitions for the rpcblist structure. This is done because +- * xdr_rpcblist() is specified to take a struct rpcblist **, rather than a +- * struct rpcblist * that rpcgen would produce. One version of the rpcblist +- * structure (actually called rp__list) is used with rpcgen, and the other is +- * defined only in the header file for compatibility with the specified +- * interface. +- */ +- +-struct rp__list { +- rpcb rpcb_map; +- struct rp__list *rpcb_next; +-}; +-typedef struct rp__list rp__list; +-#ifdef __cplusplus +-extern "C" bool_t xdr_rp__list(XDR *, rp__list*); +-#elif __STDC__ +-extern bool_t xdr_rp__list(XDR *, rp__list*); +-#else /* Old Style C */ +-bool_t xdr_rp__list(); +-#endif /* Old Style C */ +- +- +-typedef rp__list *rpcblist_ptr; +-#ifdef __cplusplus +-extern "C" bool_t xdr_rpcblist_ptr(XDR *, rpcblist_ptr*); +-#elif __STDC__ +-extern bool_t xdr_rpcblist_ptr(XDR *, rpcblist_ptr*); +-#else /* Old Style C */ +-bool_t xdr_rpcblist_ptr(); +-#endif /* Old Style C */ +- +- +-typedef struct rp__list rpcblist; +-typedef struct rp__list RPCBLIST; +- +-#ifndef __cplusplus +-struct rpcblist { +- RPCB rpcb_map; +- struct rpcblist *rpcb_next; +-}; +-#endif +- +-#ifdef __cplusplus +-extern "C" { +-#endif +-extern bool_t xdr_rpcblist(XDR *, rpcblist**); +-#ifdef __cplusplus +-} +-#endif +- +- +-/* +- * Arguments of remote calls +- */ +- +-struct rpcb_rmtcallargs { +- rpcprog_t prog; +- rpcvers_t vers; +- rpcproc_t proc; +- struct { +- u_int args_len; +- char *args_val; +- } args; +-}; +-typedef struct rpcb_rmtcallargs rpcb_rmtcallargs; +-#ifdef __cplusplus +-extern "C" bool_t xdr_rpcb_rmtcallargs(XDR *, rpcb_rmtcallargs*); +-#elif __STDC__ +-extern bool_t xdr_rpcb_rmtcallargs(XDR *, rpcb_rmtcallargs*); +-#else /* Old Style C */ +-bool_t xdr_rpcb_rmtcallargs(); +-#endif /* Old Style C */ +- +- +-/* +- * Client-side only representation of rpcb_rmtcallargs structure. +- * +- * The routine that XDRs the rpcb_rmtcallargs structure must deal with the +- * opaque arguments in the "args" structure. xdr_rpcb_rmtcallargs() 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 already knows the args structure. So we use a +- * different "XDR" structure on the client side, r_rpcb_rmtcallargs, which +- * includes the args' XDR routine. +- */ +-struct r_rpcb_rmtcallargs { +- rpcprog_t prog; +- rpcvers_t vers; +- rpcproc_t proc; +- struct { +- u_int args_len; +- char *args_val; +- } args; +- xdrproc_t xdr_args; /* encodes args */ +-}; +- +- +-/* +- * Results of the remote call +- */ +- +-struct rpcb_rmtcallres { +- char *addr; +- struct { +- u_int results_len; +- char *results_val; +- } results; +-}; +-typedef struct rpcb_rmtcallres rpcb_rmtcallres; +-#ifdef __cplusplus +-extern "C" bool_t xdr_rpcb_rmtcallres(XDR *, rpcb_rmtcallres*); +-#elif __STDC__ +-extern bool_t xdr_rpcb_rmtcallres(XDR *, rpcb_rmtcallres*); +-#else /* Old Style C */ +-bool_t xdr_rpcb_rmtcallres(); +-#endif /* Old Style C */ +- +- +-/* +- * Client-side only representation of rpcb_rmtcallres structure. +- */ +-struct r_rpcb_rmtcallres { +- char *addr; +- struct { +- u_int32_t results_len; +- char *results_val; +- } results; +- xdrproc_t xdr_res; /* decodes results */ +-}; +- +-/* +- * rpcb_entry contains a merged address of a service on a particular +- * transport, plus associated netconfig information. A list of rpcb_entrys +- * is returned by RPCBPROC_GETADDRLIST. See netconfig.h for values used +- * in r_nc_* fields. +- */ +- +-struct rpcb_entry { +- char *r_maddr; +- char *r_nc_netid; +- u_int r_nc_semantics; +- char *r_nc_protofmly; +- char *r_nc_proto; +-}; +-typedef struct rpcb_entry rpcb_entry; +-#ifdef __cplusplus +-extern "C" bool_t xdr_rpcb_entry(XDR *, rpcb_entry*); +-#elif __STDC__ +-extern bool_t xdr_rpcb_entry(XDR *, rpcb_entry*); +-#else /* Old Style C */ +-bool_t xdr_rpcb_entry(); +-#endif /* Old Style C */ +- +- +-/* +- * A list of addresses supported by a service. +- */ +- +-struct rpcb_entry_list { +- rpcb_entry rpcb_entry_map; +- struct rpcb_entry_list *rpcb_entry_next; +-}; +-typedef struct rpcb_entry_list rpcb_entry_list; +-#ifdef __cplusplus +-extern "C" bool_t xdr_rpcb_entry_list(XDR *, rpcb_entry_list*); +-#elif __STDC__ +-extern bool_t xdr_rpcb_entry_list(XDR *, rpcb_entry_list*); +-#else /* Old Style C */ +-bool_t xdr_rpcb_entry_list(); +-#endif /* Old Style C */ +- +- +-typedef rpcb_entry_list *rpcb_entry_list_ptr; +-#ifdef __cplusplus +-extern "C" bool_t xdr_rpcb_entry_list_ptr(XDR *, rpcb_entry_list_ptr*); +-#elif __STDC__ +-extern bool_t xdr_rpcb_entry_list_ptr(XDR *, rpcb_entry_list_ptr*); +-#else /* Old Style C */ +-bool_t xdr_rpcb_entry_list_ptr(); +-#endif /* Old Style C */ +- +- +-/* +- * rpcbind statistics +- */ +- +-#define rpcb_highproc_2 RPCBPROC_CALLIT +-#define rpcb_highproc_3 RPCBPROC_TADDR2UADDR +-#define rpcb_highproc_4 RPCBPROC_GETSTAT +-#define RPCBSTAT_HIGHPROC 13 +-#define RPCBVERS_STAT 3 +-#define RPCBVERS_4_STAT 2 +-#define RPCBVERS_3_STAT 1 +-#define RPCBVERS_2_STAT 0 +- +-/* Link list of all the stats about getport and getaddr */ +- +-struct rpcbs_addrlist { +- rpcprog_t prog; +- rpcvers_t vers; +- int success; +- int failure; +- char *netid; +- struct rpcbs_addrlist *next; +-}; +-typedef struct rpcbs_addrlist rpcbs_addrlist; +-#ifdef __cplusplus +-extern "C" bool_t xdr_rpcbs_addrlist(XDR *, rpcbs_addrlist*); +-#elif __STDC__ +-extern bool_t xdr_rpcbs_addrlist(XDR *, rpcbs_addrlist*); +-#else /* Old Style C */ +-bool_t xdr_rpcbs_addrlist(); +-#endif /* Old Style C */ +- +- +-/* Link list of all the stats about rmtcall */ +- +-struct rpcbs_rmtcalllist { +- rpcprog_t prog; +- rpcvers_t vers; +- rpcproc_t proc; +- int success; +- int failure; +- int indirect; +- char *netid; +- struct rpcbs_rmtcalllist *next; +-}; +-typedef struct rpcbs_rmtcalllist rpcbs_rmtcalllist; +-#ifdef __cplusplus +-extern "C" bool_t xdr_rpcbs_rmtcalllist(XDR *, rpcbs_rmtcalllist*); +-#elif __STDC__ +-extern bool_t xdr_rpcbs_rmtcalllist(XDR *, rpcbs_rmtcalllist*); +-#else /* Old Style C */ +-bool_t xdr_rpcbs_rmtcalllist(); +-#endif /* Old Style C */ +- +- +-typedef int rpcbs_proc[RPCBSTAT_HIGHPROC]; +-#ifdef __cplusplus +-extern "C" bool_t xdr_rpcbs_proc(XDR *, rpcbs_proc); +-#elif __STDC__ +-extern bool_t xdr_rpcbs_proc(XDR *, rpcbs_proc); +-#else /* Old Style C */ +-bool_t xdr_rpcbs_proc(); +-#endif /* Old Style C */ +- +- +-typedef rpcbs_addrlist *rpcbs_addrlist_ptr; +-#ifdef __cplusplus +-extern "C" bool_t xdr_rpcbs_addrlist_ptr(XDR *, rpcbs_addrlist_ptr*); +-#elif __STDC__ +-extern bool_t xdr_rpcbs_addrlist_ptr(XDR *, rpcbs_addrlist_ptr*); +-#else /* Old Style C */ +-bool_t xdr_rpcbs_addrlist_ptr(); +-#endif /* Old Style C */ +- +- +-typedef rpcbs_rmtcalllist *rpcbs_rmtcalllist_ptr; +-#ifdef __cplusplus +-extern "C" bool_t xdr_rpcbs_rmtcalllist_ptr(XDR *, rpcbs_rmtcalllist_ptr*); +-#elif __STDC__ +-extern bool_t xdr_rpcbs_rmtcalllist_ptr(XDR *, rpcbs_rmtcalllist_ptr*); +-#else /* Old Style C */ +-bool_t xdr_rpcbs_rmtcalllist_ptr(); +-#endif /* Old Style C */ +- +- +-struct rpcb_stat { +- rpcbs_proc info; +- int setinfo; +- int unsetinfo; +- rpcbs_addrlist_ptr addrinfo; +- rpcbs_rmtcalllist_ptr rmtinfo; +-}; +-typedef struct rpcb_stat rpcb_stat; +-#ifdef __cplusplus +-extern "C" bool_t xdr_rpcb_stat(XDR *, rpcb_stat*); +-#elif __STDC__ +-extern bool_t xdr_rpcb_stat(XDR *, rpcb_stat*); +-#else /* Old Style C */ +-bool_t xdr_rpcb_stat(); +-#endif /* Old Style C */ +- +- +-/* +- * One rpcb_stat structure is returned for each version of rpcbind +- * being monitored. +- */ +- +-typedef rpcb_stat rpcb_stat_byvers[RPCBVERS_STAT]; +-#ifdef __cplusplus +-extern "C" bool_t xdr_rpcb_stat_byvers(XDR *, rpcb_stat_byvers); +-#elif __STDC__ +-extern bool_t xdr_rpcb_stat_byvers(XDR *, rpcb_stat_byvers); +-#else /* Old Style C */ +-bool_t xdr_rpcb_stat_byvers(); +-#endif /* Old Style C */ +- +- +-/* +- * We don't define netbuf in RPCL, since it would contain structure member +- * names that would conflict with the definition of struct netbuf in +- * <tiuser.h>. Instead we merely declare the XDR routine xdr_netbuf() here, +- * and implement it ourselves in rpc/rpcb_prot.c. +- */ +-#ifdef __cplusplus +-extern "C" bool_t xdr_netbuf(XDR *, struct netbuf *); +- +-#else /* __STDC__ */ +-extern bool_t xdr_netbuf(XDR *, struct netbuf *); +- +-#endif +- +-#define RPCBVERS_3 RPCBVERS +-#define RPCBVERS_4 RPCBVERS4 +- +-#define _PATH_RPCBINDSOCK "/var/run/rpcbind.sock" +- +-#else /* ndef _KERNEL */ +-#ifdef __cplusplus +-extern "C" { +-#endif +- +-/* +- * A mapping of (program, version, network ID) to address +- */ +-struct rpcb { +- rpcprog_t r_prog; /* program number */ +- rpcvers_t r_vers; /* version number */ +- char *r_netid; /* network id */ +- char *r_addr; /* universal address */ +- char *r_owner; /* owner of the mapping */ +-}; +-typedef struct rpcb RPCB; +- +-/* +- * A list of mappings +- */ +-struct rpcblist { +- RPCB rpcb_map; +- struct rpcblist *rpcb_next; +-}; +-typedef struct rpcblist RPCBLIST; +-typedef struct rpcblist *rpcblist_ptr; +- +-/* +- * Remote calls arguments +- */ +-struct rpcb_rmtcallargs { +- rpcprog_t prog; /* program number */ +- rpcvers_t vers; /* version number */ +- rpcproc_t proc; /* procedure number */ +- u_int32_t arglen; /* arg len */ +- caddr_t args_ptr; /* argument */ +- xdrproc_t xdr_args; /* XDR routine for argument */ +-}; +-typedef struct rpcb_rmtcallargs rpcb_rmtcallargs; +- +-/* +- * Remote calls results +- */ +-struct rpcb_rmtcallres { +- char *addr_ptr; /* remote universal address */ +- u_int32_t resultslen; /* results length */ +- caddr_t results_ptr; /* results */ +- xdrproc_t xdr_results; /* XDR routine for result */ +-}; +-typedef struct rpcb_rmtcallres rpcb_rmtcallres; +- +-struct rpcb_entry { +- char *r_maddr; +- char *r_nc_netid; +- unsigned int r_nc_semantics; +- char *r_nc_protofmly; +- char *r_nc_proto; +-}; +-typedef struct rpcb_entry rpcb_entry; +- +-/* +- * A list of addresses supported by a service. +- */ +- +-struct rpcb_entry_list { +- rpcb_entry rpcb_entry_map; +- struct rpcb_entry_list *rpcb_entry_next; +-}; +-typedef struct rpcb_entry_list rpcb_entry_list; +- +-typedef rpcb_entry_list *rpcb_entry_list_ptr; +- +-/* +- * rpcbind statistics +- */ +- +-#define rpcb_highproc_2 RPCBPROC_CALLIT +-#define rpcb_highproc_3 RPCBPROC_TADDR2UADDR +-#define rpcb_highproc_4 RPCBPROC_GETSTAT +-#define RPCBSTAT_HIGHPROC 13 +-#define RPCBVERS_STAT 3 +-#define RPCBVERS_4_STAT 2 +-#define RPCBVERS_3_STAT 1 +-#define RPCBVERS_2_STAT 0 +- +-/* Link list of all the stats about getport and getaddr */ +- +-struct rpcbs_addrlist { +- rpcprog_t prog; +- rpcvers_t vers; +- int success; +- int failure; +- char *netid; +- struct rpcbs_addrlist *next; +-}; +-typedef struct rpcbs_addrlist rpcbs_addrlist; +- +-/* Link list of all the stats about rmtcall */ +- +-struct rpcbs_rmtcalllist { +- rpcprog_t prog; +- rpcvers_t vers; +- rpcproc_t proc; +- int success; +- int failure; +- int indirect; +- char *netid; +- struct rpcbs_rmtcalllist *next; +-}; +-typedef struct rpcbs_rmtcalllist rpcbs_rmtcalllist; +- +-typedef int rpcbs_proc[RPCBSTAT_HIGHPROC]; +- +-typedef rpcbs_addrlist *rpcbs_addrlist_ptr; +- +-typedef rpcbs_rmtcalllist *rpcbs_rmtcalllist_ptr; +- +-struct rpcb_stat { +- rpcbs_proc info; +- int setinfo; +- int unsetinfo; +- rpcbs_addrlist_ptr addrinfo; +- rpcbs_rmtcalllist_ptr rmtinfo; +-}; +-typedef struct rpcb_stat rpcb_stat; +- +-/* +- * One rpcb_stat structure is returned for each version of rpcbind +- * being monitored. +- */ +- +-typedef rpcb_stat rpcb_stat_byvers[RPCBVERS_STAT]; +- +-#ifdef __cplusplus +-} +-#endif +- +-#endif /* ndef _KERNEL */ +- +-#define RPCBPROG ((u_int32_t)100000) +-#define RPCBVERS ((u_int32_t)3) +- +-#ifdef __cplusplus +-#define RPCBPROC_SET ((u_int32_t)1) +-extern "C" bool_t * rpcbproc_set_3(rpcb *, CLIENT *); +-extern "C" bool_t * rpcbproc_set_3_svc(rpcb *, struct svc_req *); +-#define RPCBPROC_UNSET ((u_int32_t)2) +-extern "C" bool_t * rpcbproc_unset_3(rpcb *, CLIENT *); +-extern "C" bool_t * rpcbproc_unset_3_svc(rpcb *, struct svc_req *); +-#define RPCBPROC_GETADDR ((u_int32_t)3) +-extern "C" char ** rpcbproc_getaddr_3(rpcb *, CLIENT *); +-extern "C" char ** rpcbproc_getaddr_3_svc(rpcb *, struct svc_req *); +-#define RPCBPROC_DUMP ((u_int32_t)4) +-extern "C" rpcblist_ptr * rpcbproc_dump_3(void *, CLIENT *); +-extern "C" rpcblist_ptr * rpcbproc_dump_3_svc(void *, struct svc_req *); +-#define RPCBPROC_CALLIT ((u_int32_t)5) +-extern "C" rpcb_rmtcallres * rpcbproc_callit_3(rpcb_rmtcallargs *, CLIENT *); +-extern "C" rpcb_rmtcallres * rpcbproc_callit_3_svc(rpcb_rmtcallargs *, struct svc_req *); +-#define RPCBPROC_GETTIME ((u_int32_t)6) +-extern "C" u_int * rpcbproc_gettime_3(void *, CLIENT *); +-extern "C" u_int * rpcbproc_gettime_3_svc(void *, struct svc_req *); +-#define RPCBPROC_UADDR2TADDR ((u_int32_t)7) +-extern "C" struct netbuf * rpcbproc_uaddr2taddr_3(char **, CLIENT *); +-extern "C" struct netbuf * rpcbproc_uaddr2taddr_3_svc(char **, struct svc_req *); +-#define RPCBPROC_TADDR2UADDR ((u_int32_t)8) +-extern "C" char ** rpcbproc_taddr2uaddr_3(struct netbuf *, CLIENT *); +-extern "C" char ** rpcbproc_taddr2uaddr_3_svc(struct netbuf *, struct svc_req *); +- +-#elif __STDC__ +-#define RPCBPROC_SET ((u_int32_t)1) +-extern bool_t * rpcbproc_set_3(rpcb *, CLIENT *); +-extern bool_t * rpcbproc_set_3_svc(rpcb *, struct svc_req *); +-#define RPCBPROC_UNSET ((u_int32_t)2) +-extern bool_t * rpcbproc_unset_3(rpcb *, CLIENT *); +-extern bool_t * rpcbproc_unset_3_svc(rpcb *, struct svc_req *); +-#define RPCBPROC_GETADDR ((u_int32_t)3) +-extern char ** rpcbproc_getaddr_3(rpcb *, CLIENT *); +-extern char ** rpcbproc_getaddr_3_svc(rpcb *, struct svc_req *); +-#define RPCBPROC_DUMP ((u_int32_t)4) +-extern rpcblist_ptr * rpcbproc_dump_3(void *, CLIENT *); +-extern rpcblist_ptr * rpcbproc_dump_3_svc(void *, struct svc_req *); +-#define RPCBPROC_CALLIT ((u_int32_t)5) +-extern rpcb_rmtcallres * rpcbproc_callit_3(rpcb_rmtcallargs *, CLIENT *); +-extern rpcb_rmtcallres * rpcbproc_callit_3_svc(rpcb_rmtcallargs *, struct svc_req *); +-#define RPCBPROC_GETTIME ((u_int32_t)6) +-extern u_int * rpcbproc_gettime_3(void *, CLIENT *); +-extern u_int * rpcbproc_gettime_3_svc(void *, struct svc_req *); +-#define RPCBPROC_UADDR2TADDR ((u_int32_t)7) +-extern struct netbuf * rpcbproc_uaddr2taddr_3(char **, CLIENT *); +-extern struct netbuf * rpcbproc_uaddr2taddr_3_svc(char **, struct svc_req *); +-#define RPCBPROC_TADDR2UADDR ((u_int32_t)8) +-extern char ** rpcbproc_taddr2uaddr_3(struct netbuf *, CLIENT *); +-extern char ** rpcbproc_taddr2uaddr_3_svc(struct netbuf *, struct svc_req *); +- +-#else /* Old Style C */ +-#define RPCBPROC_SET ((u_int32_t)1) +-extern bool_t * rpcbproc_set_3(); +-extern bool_t * rpcbproc_set_3_svc(); +-#define RPCBPROC_UNSET ((u_int32_t)2) +-extern bool_t * rpcbproc_unset_3(); +-extern bool_t * rpcbproc_unset_3_svc(); +-#define RPCBPROC_GETADDR ((u_int32_t)3) +-extern char ** rpcbproc_getaddr_3(); +-extern char ** rpcbproc_getaddr_3_svc(); +-#define RPCBPROC_DUMP ((u_int32_t)4) +-extern rpcblist_ptr * rpcbproc_dump_3(); +-extern rpcblist_ptr * rpcbproc_dump_3_svc(); +-#define RPCBPROC_CALLIT ((u_int32_t)5) +-extern rpcb_rmtcallres * rpcbproc_callit_3(); +-extern rpcb_rmtcallres * rpcbproc_callit_3_svc(); +-#define RPCBPROC_GETTIME ((u_int32_t)6) +-extern u_int * rpcbproc_gettime_3(); +-extern u_int * rpcbproc_gettime_3_svc(); +-#define RPCBPROC_UADDR2TADDR ((u_int32_t)7) +-extern struct netbuf * rpcbproc_uaddr2taddr_3(); +-extern struct netbuf * rpcbproc_uaddr2taddr_3_svc(); +-#define RPCBPROC_TADDR2UADDR ((u_int32_t)8) +-extern char ** rpcbproc_taddr2uaddr_3(); +-extern char ** rpcbproc_taddr2uaddr_3_svc(); +-#endif /* Old Style C */ +-#define RPCBVERS4 ((u_int32_t)4) +- +-#ifdef __cplusplus +-extern "C" bool_t * rpcbproc_set_4(rpcb *, CLIENT *); +-extern "C" bool_t * rpcbproc_set_4_svc(rpcb *, struct svc_req *); +-extern "C" bool_t * rpcbproc_unset_4(rpcb *, CLIENT *); +-extern "C" bool_t * rpcbproc_unset_4_svc(rpcb *, struct svc_req *); +-extern "C" char ** rpcbproc_getaddr_4(rpcb *, CLIENT *); +-extern "C" char ** rpcbproc_getaddr_4_svc(rpcb *, struct svc_req *); +-extern "C" rpcblist_ptr * rpcbproc_dump_4(void *, CLIENT *); +-extern "C" rpcblist_ptr * rpcbproc_dump_4_svc(void *, struct svc_req *); +-#define RPCBPROC_BCAST ((u_int32_t)RPCBPROC_CALLIT) +-extern "C" rpcb_rmtcallres * rpcbproc_bcast_4(rpcb_rmtcallargs *, CLIENT *); +-extern "C" rpcb_rmtcallres * rpcbproc_bcast_4_svc(rpcb_rmtcallargs *, struct svc_req *); +-extern "C" u_int * rpcbproc_gettime_4(void *, CLIENT *); +-extern "C" u_int * rpcbproc_gettime_4_svc(void *, struct svc_req *); +-extern "C" struct netbuf * rpcbproc_uaddr2taddr_4(char **, CLIENT *); +-extern "C" struct netbuf * rpcbproc_uaddr2taddr_4_svc(char **, struct svc_req *); +-extern "C" char ** rpcbproc_taddr2uaddr_4(struct netbuf *, CLIENT *); +-extern "C" char ** rpcbproc_taddr2uaddr_4_svc(struct netbuf *, struct svc_req *); +-#define RPCBPROC_GETVERSADDR ((u_int32_t)9) +-extern "C" char ** rpcbproc_getversaddr_4(rpcb *, CLIENT *); +-extern "C" char ** rpcbproc_getversaddr_4_svc(rpcb *, struct svc_req *); +-#define RPCBPROC_INDIRECT ((u_int32_t)10) +-extern "C" rpcb_rmtcallres * rpcbproc_indirect_4(rpcb_rmtcallargs *, CLIENT *); +-extern "C" rpcb_rmtcallres * rpcbproc_indirect_4_svc(rpcb_rmtcallargs *, struct svc_req *); +-#define RPCBPROC_GETADDRLIST ((u_int32_t)11) +-extern "C" rpcb_entry_list_ptr * rpcbproc_getaddrlist_4(rpcb *, CLIENT *); +-extern "C" rpcb_entry_list_ptr * rpcbproc_getaddrlist_4_svc(rpcb *, struct svc_req *); +-#define RPCBPROC_GETSTAT ((u_int32_t)12) +-extern "C" rpcb_stat * rpcbproc_getstat_4(void *, CLIENT *); +-extern "C" rpcb_stat * rpcbproc_getstat_4_svc(void *, struct svc_req *); +- +-#elif __STDC__ +-extern bool_t * rpcbproc_set_4(rpcb *, CLIENT *); +-extern bool_t * rpcbproc_set_4_svc(rpcb *, struct svc_req *); +-extern bool_t * rpcbproc_unset_4(rpcb *, CLIENT *); +-extern bool_t * rpcbproc_unset_4_svc(rpcb *, struct svc_req *); +-extern char ** rpcbproc_getaddr_4(rpcb *, CLIENT *); +-extern char ** rpcbproc_getaddr_4_svc(rpcb *, struct svc_req *); +-extern rpcblist_ptr * rpcbproc_dump_4(void *, CLIENT *); +-extern rpcblist_ptr * rpcbproc_dump_4_svc(void *, struct svc_req *); +-#define RPCBPROC_BCAST ((u_int32_t)RPCBPROC_CALLIT) +-extern rpcb_rmtcallres * rpcbproc_bcast_4(rpcb_rmtcallargs *, CLIENT *); +-extern rpcb_rmtcallres * rpcbproc_bcast_4_svc(rpcb_rmtcallargs *, struct svc_req *); +-extern u_int * rpcbproc_gettime_4(void *, CLIENT *); +-extern u_int * rpcbproc_gettime_4_svc(void *, struct svc_req *); +-extern struct netbuf * rpcbproc_uaddr2taddr_4(char **, CLIENT *); +-extern struct netbuf * rpcbproc_uaddr2taddr_4_svc(char **, struct svc_req *); +-extern char ** rpcbproc_taddr2uaddr_4(struct netbuf *, CLIENT *); +-extern char ** rpcbproc_taddr2uaddr_4_svc(struct netbuf *, struct svc_req *); +-#define RPCBPROC_GETVERSADDR ((u_int32_t)9) +-extern char ** rpcbproc_getversaddr_4(rpcb *, CLIENT *); +-extern char ** rpcbproc_getversaddr_4_svc(rpcb *, struct svc_req *); +-#define RPCBPROC_INDIRECT ((u_int32_t)10) +-extern rpcb_rmtcallres * rpcbproc_indirect_4(rpcb_rmtcallargs *, CLIENT *); +-extern rpcb_rmtcallres * rpcbproc_indirect_4_svc(rpcb_rmtcallargs *, struct svc_req *); +-#define RPCBPROC_GETADDRLIST ((u_int32_t)11) +-extern rpcb_entry_list_ptr * rpcbproc_getaddrlist_4(rpcb *, CLIENT *); +-extern rpcb_entry_list_ptr * rpcbproc_getaddrlist_4_svc(rpcb *, struct svc_req *); +-#define RPCBPROC_GETSTAT ((u_int32_t)12) +-extern rpcb_stat * rpcbproc_getstat_4(void *, CLIENT *); +-extern rpcb_stat * rpcbproc_getstat_4_svc(void *, struct svc_req *); +- +-#else /* Old Style C */ +-extern bool_t * rpcbproc_set_4(); +-extern bool_t * rpcbproc_set_4_svc(); +-extern bool_t * rpcbproc_unset_4(); +-extern bool_t * rpcbproc_unset_4_svc(); +-extern char ** rpcbproc_getaddr_4(); +-extern char ** rpcbproc_getaddr_4_svc(); +-extern rpcblist_ptr * rpcbproc_dump_4(); +-extern rpcblist_ptr * rpcbproc_dump_4_svc(); +-#define RPCBPROC_BCAST ((u_int32_t)RPCBPROC_CALLIT) +-extern rpcb_rmtcallres * rpcbproc_bcast_4(); +-extern rpcb_rmtcallres * rpcbproc_bcast_4_svc(); +-extern u_int * rpcbproc_gettime_4(); +-extern u_int * rpcbproc_gettime_4_svc(); +-extern struct netbuf * rpcbproc_uaddr2taddr_4(); +-extern struct netbuf * rpcbproc_uaddr2taddr_4_svc(); +-extern char ** rpcbproc_taddr2uaddr_4(); +-extern char ** rpcbproc_taddr2uaddr_4_svc(); +-#define RPCBPROC_GETVERSADDR ((u_int32_t)9) +-extern char ** rpcbproc_getversaddr_4(); +-extern char ** rpcbproc_getversaddr_4_svc(); +-#define RPCBPROC_INDIRECT ((u_int32_t)10) +-extern rpcb_rmtcallres * rpcbproc_indirect_4(); +-extern rpcb_rmtcallres * rpcbproc_indirect_4_svc(); +-#define RPCBPROC_GETADDRLIST ((u_int32_t)11) +-extern rpcb_entry_list_ptr * rpcbproc_getaddrlist_4(); +-extern rpcb_entry_list_ptr * rpcbproc_getaddrlist_4_svc(); +-#define RPCBPROC_GETSTAT ((u_int32_t)12) +-extern rpcb_stat * rpcbproc_getstat_4(); +-extern rpcb_stat * rpcbproc_getstat_4_svc(); +-#endif /* Old Style C */ +- +-#endif /* !_RPCB_PROT_H_RPCGEN */ +diff --git a/tirpc/rpcsvc/crypt.h b/tirpc/rpcsvc/crypt.h +deleted file mode 100644 +index da1f9cc..0000000 +--- a/tirpc/rpcsvc/crypt.h ++++ /dev/null +@@ -1,109 +0,0 @@ +-/* +- * Please do not edit this file. +- * It was generated using rpcgen. +- */ +- +-#ifndef _CRYPT_H_RPCGEN +-#define _CRYPT_H_RPCGEN +- +-#include <rpc/rpc.h> +- +-#ifndef IXDR_GET_INT32 +-#define IXDR_GET_INT32(buf) IXDR_GET_LONG((buf)) +-#endif +-#ifndef IXDR_PUT_INT32 +-#define IXDR_PUT_INT32(buf, v) IXDR_PUT_LONG((buf), (v)) +-#endif +-#ifndef IXDR_GET_U_INT32 +-#define IXDR_GET_U_INT32(buf) IXDR_GET_U_LONG((buf)) +-#endif +-#ifndef IXDR_PUT_U_INT32 +-#define IXDR_PUT_U_INT32(buf, v) IXDR_PUT_U_LONG((buf), (v)) +-#endif +- +-enum des_dir { +- ENCRYPT_DES = 0, +- DECRYPT_DES = 1, +-}; +-typedef enum des_dir des_dir; +-#ifdef __cplusplus +-extern "C" bool_t xdr_des_dir(XDR *, des_dir*); +-#elif __STDC__ +-extern bool_t xdr_des_dir(XDR *, des_dir*); +-#else /* Old Style C */ +-bool_t xdr_des_dir(); +-#endif /* Old Style C */ +- +- +-enum des_mode { +- CBC_DES = 0, +- ECB_DES = 1, +-}; +-typedef enum des_mode des_mode; +-#ifdef __cplusplus +-extern "C" bool_t xdr_des_mode(XDR *, des_mode*); +-#elif __STDC__ +-extern bool_t xdr_des_mode(XDR *, des_mode*); +-#else /* Old Style C */ +-bool_t xdr_des_mode(); +-#endif /* Old Style C */ +- +- +-struct desargs { +- u_char des_key[8]; +- des_dir des_dir; +- des_mode des_mode; +- u_char des_ivec[8]; +- struct { +- u_int desbuf_len; +- char *desbuf_val; +- } desbuf; +-}; +-typedef struct desargs desargs; +-#ifdef __cplusplus +-extern "C" bool_t xdr_desargs(XDR *, desargs*); +-#elif __STDC__ +-extern bool_t xdr_desargs(XDR *, desargs*); +-#else /* Old Style C */ +-bool_t xdr_desargs(); +-#endif /* Old Style C */ +- +- +-struct desresp { +- struct { +- u_int desbuf_len; +- char *desbuf_val; +- } desbuf; +- u_char des_ivec[8]; +- int stat; +-}; +-typedef struct desresp desresp; +-#ifdef __cplusplus +-extern "C" bool_t xdr_desresp(XDR *, desresp*); +-#elif __STDC__ +-extern bool_t xdr_desresp(XDR *, desresp*); +-#else /* Old Style C */ +-bool_t xdr_desresp(); +-#endif /* Old Style C */ +- +- +-#define CRYPT_PROG ((u_int32_t)600100029) +-#define CRYPT_VERS ((u_int32_t)1) +- +-#ifdef __cplusplus +-#define DES_CRYPT ((u_int32_t)1) +-extern "C" desresp * des_crypt_1(desargs *, CLIENT *); +-extern "C" desresp * des_crypt_1_svc(desargs *, struct svc_req *); +- +-#elif __STDC__ +-#define DES_CRYPT ((u_int32_t)1) +-extern desresp * des_crypt_1(desargs *, CLIENT *); +-extern desresp * des_crypt_1_svc(desargs *, struct svc_req *); +- +-#else /* Old Style C */ +-#define DES_CRYPT ((u_int32_t)1) +-extern desresp * des_crypt_1(); +-extern desresp * des_crypt_1_svc(); +-#endif /* Old Style C */ +- +-#endif /* !_CRYPT_H_RPCGEN */ +-- +1.7.9.5 + diff --git a/package/libtirpc/libtirpc-0010-Add-more-XDR-files-needed-to-build-rpcbind-on-top-of.patch b/package/libtirpc/libtirpc-0010-Add-more-XDR-files-needed-to-build-rpcbind-on-top-of.patch new file mode 100644 index 000000000..360a27f83 --- /dev/null +++ b/package/libtirpc/libtirpc-0010-Add-more-XDR-files-needed-to-build-rpcbind-on-top-of.patch @@ -0,0 +1,1649 @@ +From 52aecb645b2e45d120a941f42fdbe193e22c27e1 Mon Sep 17 00:00:00 2001 +From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +Date: Sat, 10 Nov 2012 17:45:03 +0100 +Subject: [PATCH] Add more XDR files needed to build rpcbind on top of + libtirpc + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +--- + Makefile.am | 6 + + tirpc/rpcsvc/mount.x | 257 ++++++++++ + tirpc/rpcsvc/nfs_prot.x | 1266 +++++++++++++++++++++++++++++++++++++++++++++++ + tirpc/rpcsvc/rquota.x | 67 +++ + 4 files changed, 1596 insertions(+) + create mode 100644 tirpc/rpcsvc/mount.x + create mode 100644 tirpc/rpcsvc/nfs_prot.x + create mode 100644 tirpc/rpcsvc/rquota.x + +diff --git a/Makefile.am b/Makefile.am +index 7e63f78..351c5df 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -3,10 +3,16 @@ ACLOCAL_AMFLAGS = -I m4 + + GENFILES = \ + tirpc/rpcsvc/crypt.h \ ++ tirpc/rpcsvc/mount.h \ ++ tirpc/rpcsvc/nfs_prot.h \ ++ tirpc/rpcsvc/rquota.h \ + tirpc/rpc/rpcb_prot.h + + nobase_include_HEADERS = tirpc/netconfig.h \ + tirpc/rpcsvc/crypt.x \ ++ tirpc/rpcsvc/mount.x \ ++ tirpc/rpcsvc/nfs_prot.x \ ++ tirpc/rpcsvc/rquota.x \ + tirpc/rpc/xdr.h \ + tirpc/rpc/types.h \ + tirpc/rpc/svc_soc.h \ +diff --git a/tirpc/rpcsvc/mount.x b/tirpc/rpcsvc/mount.x +new file mode 100644 +index 0000000..f68a06f +--- /dev/null ++++ b/tirpc/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/tirpc/rpcsvc/nfs_prot.x b/tirpc/rpcsvc/nfs_prot.x +new file mode 100644 +index 0000000..01564f8 +--- /dev/null ++++ b/tirpc/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/tirpc/rpcsvc/rquota.x b/tirpc/rpcsvc/rquota.x +new file mode 100644 +index 0000000..72864d1 +--- /dev/null ++++ b/tirpc/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; +-- +1.7.9.5 + |