From be49c58d77ce855f902728b0c68fc10bafee6257 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Sun, 6 Dec 2015 10:24:52 +0100 Subject: libtirpc: update to latest stable version --- package/libtirpc/src/rpcgen/Makefile.am | 22 + package/libtirpc/src/rpcgen/rpc_clntout.c | 217 +++++ package/libtirpc/src/rpcgen/rpc_cout.c | 706 ++++++++++++++ package/libtirpc/src/rpcgen/rpc_hout.c | 490 ++++++++++ package/libtirpc/src/rpcgen/rpc_main.c | 1067 ++++++++++++++++++++++ package/libtirpc/src/rpcgen/rpc_output.h | 16 + package/libtirpc/src/rpcgen/rpc_parse.c | 609 +++++++++++++ package/libtirpc/src/rpcgen/rpc_parse.h | 166 ++++ package/libtirpc/src/rpcgen/rpc_sample.c | 247 +++++ package/libtirpc/src/rpcgen/rpc_scan.c | 474 ++++++++++ package/libtirpc/src/rpcgen/rpc_scan.h | 103 +++ package/libtirpc/src/rpcgen/rpc_svcout.c | 882 ++++++++++++++++++ package/libtirpc/src/rpcgen/rpc_tblout.c | 165 ++++ package/libtirpc/src/rpcgen/rpc_util.c | 479 ++++++++++ package/libtirpc/src/rpcgen/rpc_util.h | 166 ++++ package/libtirpc/src/rpcgen/rpcgen.1 | 521 +++++++++++ package/libtirpc/src/tirpc/rpcsvc/mount.x | 257 ++++++ package/libtirpc/src/tirpc/rpcsvc/nfs_prot.x | 1266 ++++++++++++++++++++++++++ package/libtirpc/src/tirpc/rpcsvc/rquota.x | 67 ++ 19 files changed, 7920 insertions(+) create mode 100644 package/libtirpc/src/rpcgen/Makefile.am create mode 100644 package/libtirpc/src/rpcgen/rpc_clntout.c create mode 100644 package/libtirpc/src/rpcgen/rpc_cout.c create mode 100644 package/libtirpc/src/rpcgen/rpc_hout.c create mode 100644 package/libtirpc/src/rpcgen/rpc_main.c create mode 100644 package/libtirpc/src/rpcgen/rpc_output.h create mode 100644 package/libtirpc/src/rpcgen/rpc_parse.c create mode 100644 package/libtirpc/src/rpcgen/rpc_parse.h create mode 100644 package/libtirpc/src/rpcgen/rpc_sample.c create mode 100644 package/libtirpc/src/rpcgen/rpc_scan.c create mode 100644 package/libtirpc/src/rpcgen/rpc_scan.h create mode 100644 package/libtirpc/src/rpcgen/rpc_svcout.c create mode 100644 package/libtirpc/src/rpcgen/rpc_tblout.c create mode 100644 package/libtirpc/src/rpcgen/rpc_util.c create mode 100644 package/libtirpc/src/rpcgen/rpc_util.h create mode 100644 package/libtirpc/src/rpcgen/rpcgen.1 create mode 100644 package/libtirpc/src/tirpc/rpcsvc/mount.x create mode 100644 package/libtirpc/src/tirpc/rpcsvc/nfs_prot.x create mode 100644 package/libtirpc/src/tirpc/rpcsvc/rquota.x (limited to 'package/libtirpc/src') diff --git a/package/libtirpc/src/rpcgen/Makefile.am b/package/libtirpc/src/rpcgen/Makefile.am new file mode 100644 index 000000000..18026f832 --- /dev/null +++ b/package/libtirpc/src/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 $@ + +noinst_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/package/libtirpc/src/rpcgen/rpc_clntout.c b/package/libtirpc/src/rpcgen/rpc_clntout.c new file mode 100644 index 000000000..e2f4382c5 --- /dev/null +++ b/package/libtirpc/src/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 +#include +#include +#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/package/libtirpc/src/rpcgen/rpc_cout.c b/package/libtirpc/src/rpcgen/rpc_cout.c new file mode 100644 index 000000000..a61214fdb --- /dev/null +++ b/package/libtirpc/src/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 +#include +#include +#include +#include +#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/package/libtirpc/src/rpcgen/rpc_hout.c b/package/libtirpc/src/rpcgen/rpc_hout.c new file mode 100644 index 000000000..ea1cb24f5 --- /dev/null +++ b/package/libtirpc/src/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 +#include +#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/package/libtirpc/src/rpcgen/rpc_main.c b/package/libtirpc/src/rpcgen/rpc_main.c new file mode 100644 index 000000000..28aa60c9e --- /dev/null +++ b/package/libtirpc/src/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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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" : 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 \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 \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 \n"); + + f_print(fout, "#include \n"); + f_print(fout, "#include /* getenv, exit */\n"); + if (Cflag) { + f_print (fout, "#include /* for pmap_unset */\n"); + f_print (fout, "#include /* 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 \n"); + timerflag = 1; + } + +#ifndef linux + if( !tirpcflag && inetdflag ) + f_print(fout, "#include /* TIOCNOTTY */\n"); +#else + if( !tirpcflag ) + f_print(fout, "#include /* TIOCNOTTY */\n"); +#endif + if( Cflag && (inetdflag || pmflag ) ) { + f_print(fout, "#ifdef __cplusplus\n"); + f_print(fout, "#include /* getdtablesize, open */\n"); + f_print(fout, "#endif /* __cplusplus */\n"); + + if( tirpcflag ) + f_print(fout, "#include /* setsid */\n"); + } + if( tirpcflag ) + f_print(fout, "#include \n"); + + f_print(fout, "#include \n"); +#ifndef linux + f_print(fout, "#include \n"); +#endif + if (inetdflag || !tirpcflag ) { + f_print(fout, "#include \n"); + f_print(fout, "#include \n"); + } + + if ( (netflag || pmflag) && tirpcflag ) { + f_print(fout, "#include \n"); + } + if (/*timerflag &&*/ tirpcflag) + f_print(fout, "#include /* rlimit */\n"); + if (logflag || inetdflag || pmflag) { +#ifdef linux + f_print(fout, "#include \n"); +#else + f_print(fout, "#ifdef SYSLOG\n"); + f_print(fout, "#include \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 /* for memset */\n"); + if (infile && (include = extendfile(infile, ".h"))) { + f_print(fout, "#include \"%s\"\n", include); + free(include); + } else + f_print(fout, "#include \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 \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 \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