diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2015-09-07 00:59:09 +0200 |
---|---|---|
committer | Damien Zammit <damien@zamaudio.com> | 2023-06-23 22:34:40 +1000 |
commit | 7713a0a39c96ef4327ac6a7bf3ecf5b9e6e8b746 (patch) | |
tree | bba2fef0e7c908a32098fe2bccd96b4acdca06e9 /buildrump.sh/src/usr.bin/rpcgen |
Imported Upstream version 0~20150715upstream/0_20150715
Diffstat (limited to 'buildrump.sh/src/usr.bin/rpcgen')
-rw-r--r-- | buildrump.sh/src/usr.bin/rpcgen/Makefile | 7 | ||||
-rw-r--r-- | buildrump.sh/src/usr.bin/rpcgen/rpc_clntout.c | 264 | ||||
-rw-r--r-- | buildrump.sh/src/usr.bin/rpcgen/rpc_cout.c | 726 | ||||
-rw-r--r-- | buildrump.sh/src/usr.bin/rpcgen/rpc_hout.c | 542 | ||||
-rw-r--r-- | buildrump.sh/src/usr.bin/rpcgen/rpc_main.c | 1137 | ||||
-rw-r--r-- | buildrump.sh/src/usr.bin/rpcgen/rpc_parse.c | 618 | ||||
-rw-r--r-- | buildrump.sh/src/usr.bin/rpcgen/rpc_parse.h | 168 | ||||
-rw-r--r-- | buildrump.sh/src/usr.bin/rpcgen/rpc_sample.c | 275 | ||||
-rw-r--r-- | buildrump.sh/src/usr.bin/rpcgen/rpc_scan.c | 492 | ||||
-rw-r--r-- | buildrump.sh/src/usr.bin/rpcgen/rpc_scan.h | 108 | ||||
-rw-r--r-- | buildrump.sh/src/usr.bin/rpcgen/rpc_svcout.c | 966 | ||||
-rw-r--r-- | buildrump.sh/src/usr.bin/rpcgen/rpc_tblout.c | 181 | ||||
-rw-r--r-- | buildrump.sh/src/usr.bin/rpcgen/rpc_util.c | 479 | ||||
-rw-r--r-- | buildrump.sh/src/usr.bin/rpcgen/rpc_util.h | 178 | ||||
-rw-r--r-- | buildrump.sh/src/usr.bin/rpcgen/rpcgen.1 | 501 |
15 files changed, 6642 insertions, 0 deletions
diff --git a/buildrump.sh/src/usr.bin/rpcgen/Makefile b/buildrump.sh/src/usr.bin/rpcgen/Makefile new file mode 100644 index 00000000..cd057676 --- /dev/null +++ b/buildrump.sh/src/usr.bin/rpcgen/Makefile @@ -0,0 +1,7 @@ +# $NetBSD: Makefile,v 1.13 2013/08/11 08:03:10 dholland Exp $ + +PROG= rpcgen +SRCS= rpc_clntout.c rpc_cout.c rpc_hout.c rpc_main.c rpc_parse.c rpc_scan.c \ + rpc_svcout.c rpc_util.c rpc_sample.c rpc_tblout.c + +.include <bsd.prog.mk> diff --git a/buildrump.sh/src/usr.bin/rpcgen/rpc_clntout.c b/buildrump.sh/src/usr.bin/rpcgen/rpc_clntout.c new file mode 100644 index 00000000..0f750a4f --- /dev/null +++ b/buildrump.sh/src/usr.bin/rpcgen/rpc_clntout.c @@ -0,0 +1,264 @@ +/* $NetBSD: rpc_clntout.c,v 1.15 2013/12/15 00:40:17 christos Exp $ */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user or with the express written consent of + * Sun Microsystems, Inc. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if HAVE_NBTOOL_CONFIG_H +#include "nbtool_config.h" +#endif + +#include <sys/cdefs.h> +#if defined(__RCSID) && !defined(lint) +#if 0 +static char sccsid[] = "@(#)rpc_clntout.c 1.11 89/02/22 (C) 1987 SMI"; +#else +__RCSID("$NetBSD: rpc_clntout.c,v 1.15 2013/12/15 00:40:17 christos Exp $"); +#endif +#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_scan.h" +#include "rpc_parse.h" +#include "rpc_util.h" + +static void write_program(definition *); +static const char *ampr(const char *); +static const char *aster(const char *); +static void printbody(proc_list *); + +#define DEFAULT_TIMEOUT 25 /* in seconds */ +static char RESULT[] = "clnt_res"; + + +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"); + if (Mflag) + f_print(fout, "enum clnt_stat\n"); + else { + ptype(proc->res_prefix, proc->res_type, 1); + f_print(fout, "*\n"); + } + pvname(proc->proc_name, vp->vers_num); + printarglist(proc, RESULT, "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, const char *result, + const char *addargname, const char *addargtype) +{ + + decl_list *l; + + if (!newstyle) { /* old style: always pass argument by + * reference */ + f_print(fout, "("); + ptype(proc->args.decls->decl.prefix, proc->args.decls->decl.type, 1); + f_print(fout, "*argp, "); + if (Mflag) { + if (streq(proc->res_type, "void")) + f_print(fout, "char "); + else + ptype(proc->res_prefix, proc->res_type, 0); + f_print(fout, "%s%s, ", aster(proc->res_type), + result); + } + f_print(fout, "%s%s)\n", addargtype, addargname); + } else { + f_print(fout, "("); + if (!streq(proc->args.decls->decl.type, "void")) { + /* new style, 1 or multiple arguments */ + for (l = proc->args.decls; l != NULL; l = l->next) + pdeclaration(proc->args.argname, + &l->decl, 0, ", "); + } + if (Mflag) { + if (streq(proc->res_type, "void")) + f_print(fout, "char "); + else + ptype(proc->res_prefix, proc->res_type, 0); + f_print(fout, "%s%s, ", aster(proc->res_type), + result); + } + f_print(fout, "%s%s)\n", addargtype, addargname); + } +} + + +static const char * +ampr(const char *type) +{ + if (isvectordef(type, REL_ALIAS)) { + return (""); + } else { + return ("&"); + } +} + +static const char * +aster(const 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"); + } + if (!Mflag) { + 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"); + if (!Mflag) + 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 */ + if (Mflag) { + f_print(fout, "\treturn (clnt_call(clnt, %s, xdr_void", + proc->proc_name); + f_print(fout, ", NULL, xdr_%s, %s, TIMEOUT));\n", + stringfix(proc->res_type), RESULT); + } else { + f_print(fout, "\tif (clnt_call(clnt, %s, xdr_void, ", + proc->proc_name); + f_print(fout, + "NULL, xdr_%s, %s%s, TIMEOUT) != RPC_SUCCESS)\n", + 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); + } + if (Mflag) { + f_print(fout, + "\treturn (clnt_call(clnt, %s, xdr_%s, &arg, xdr_%s, %s, TIMEOUT));\n", + proc->proc_name, proc->args.argname, + stringfix(proc->res_type), RESULT); + } else { + f_print(fout, + "\tif (clnt_call(clnt, %s, xdr_%s, &arg, xdr_%s, %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 */ + if (Mflag) { + f_print(fout, + "\treturn (clnt_call(clnt, %s, xdr_%s, %s%s, xdr_%s, %s, TIMEOUT));\n", + proc->proc_name, + stringfix(proc->args.decls->decl.type), + (newstyle ? "&" : ""), + (newstyle ? proc->args.decls->decl.name : "argp"), + stringfix(proc->res_type), RESULT); + } else { + f_print(fout, + "\tif (clnt_call(clnt, %s, xdr_%s, %s%s, xdr_%s, %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); + } + } + } + if (!Mflag) { + f_print(fout, "\t\treturn (NULL);\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/buildrump.sh/src/usr.bin/rpcgen/rpc_cout.c b/buildrump.sh/src/usr.bin/rpcgen/rpc_cout.c new file mode 100644 index 00000000..65cb389a --- /dev/null +++ b/buildrump.sh/src/usr.bin/rpcgen/rpc_cout.c @@ -0,0 +1,726 @@ +/* $NetBSD: rpc_cout.c,v 1.36 2015/05/09 23:16:51 dholland Exp $ */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user or with the express written consent of + * Sun Microsystems, Inc. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if HAVE_NBTOOL_CONFIG_H +#include "nbtool_config.h" +#endif + +#include <sys/cdefs.h> +#if defined(__RCSID) && !defined(lint) +#if 0 +static char sccsid[] = "@(#)rpc_cout.c 1.13 89/02/22 (C) 1987 SMI"; +#else +__RCSID("$NetBSD: rpc_cout.c,v 1.36 2015/05/09 23:16:51 dholland Exp $"); +#endif +#endif + +/* + * rpc_cout.c, XDR routine outputter for the RPC protocol compiler + */ +#include <ctype.h> +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "rpc_scan.h" +#include "rpc_parse.h" +#include "rpc_util.h" + +static int findtype(definition *, const char *); +static int undefined(const char *); +static void print_generic_header(const char *, int); +static void print_header(definition *); +static void print_prog_header(proc_list *); +static void print_trailer(void); +static void print_ifopen(int, const char *); +static void print_ifarg(const char *); +static void print_ifsizeof(const char *, const char *); +static void print_ifclose(int); +static void print_ifstat(int, const char *, const char *, relation, + const char *, const char *, const char *); +static void emit_enum(definition *); +static void emit_program(definition *); +static void emit_union(definition *); +static void emit_struct(definition *); +static void emit_typedef(definition *); +static void print_stat(int, declaration *); + +/* + * 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; + case DEF_PROGRAM: + case DEF_CONST: + errx(1, "Internal error at %s:%d: Case %d not handled", + __FILE__, __LINE__, def->def_kind); + break; + } + print_trailer(); +} + +static int +findtype(definition *def, const 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(const char *type) +{ + definition *def; + + def = (definition *) FINDVAL(defined, type, findtype); + + + return (def == NULL); +} + +static void +print_generic_header(const char *procname, int pointerp) +{ + f_print(fout, "\n"); + f_print(fout, "bool_t\n"); + 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"); +} + +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)); +} + +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, const char *name) +{ + char _t_kludge[32]; + /* + * XXX Solaris seems to strip the _t. No idea why. + */ + if (!strcmp(name, "rpcprog_t") || !strcmp(name, "rpcvers_t") || + !strcmp(name, "rpcproc_t") || !strcmp(name, "rpcprot_t") || + !strcmp(name, "rpcport_t") || !strcmp(name, "rpcpinline_t")) { + strncpy(_t_kludge, name, strlen(name) - 2); + name = _t_kludge; + } + tabify(fout, indent); + f_print(fout, "if (!xdr_%s(xdrs", name); +} + +static void +print_ifarg(const char *arg) +{ + f_print(fout, ", %s", arg); +} + +static void +print_ifsizeof(const char *prefix, const char *type) +{ + if (streq(type, "bool")) { + f_print(fout, ", (u_int)sizeof(bool_t), (xdrproc_t)xdr_bool"); + } else { + f_print(fout, ", (u_int)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, "\treturn (FALSE);\n"); +} + +static void +print_ifstat(int indent, const char *prefix, const char *type, relation rel, + const char *amax, const char *objname, const char *name) +{ + const char *alt = NULL; + + switch (rel) { + case REL_POINTER: + print_ifopen(indent, "pointer"); + print_ifarg("(char **)(void *)"); + 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 *)(void *)"); + 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"); + } + 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); +} +/* ARGSUSED */ +static void +emit_enum(definition *def) +{ + tabify(fout, 1); + f_print(fout, "{\n"); + tabify(fout, 2); + f_print(fout, "enum_t et = (enum_t)*objp;\n"); + print_ifopen(2, "enum"); + print_ifarg("&et"); + print_ifclose(2); + tabify(fout, 2); + f_print(fout, "*objp = (%s)et;\n", def->def_name); + tabify(fout, 1); + f_print(fout, "}\n"); +} + +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; + static const char vecformat[] = "objp->%s_u.%s"; + static const char format[] = "&objp->%s_u.%s"; + + f_print(fout, "\n"); + 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; + f_print(fout, "\tdefault:\n"); + if (dflt != NULL) { + if (!streq(dflt->type, "void")) { + 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 { + 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; + const char *plus; + char ptemp[256]; + int can_inline; + + + if (doinline == 0) { + f_print(fout, "\n"); + for (dl = def->def.st.decls; dl != NULL; dl = dl->next) + print_stat(1, &dl->decl); + return; + } + 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 >= doinline) { + can_inline = 1; + break; /* can be inlined */ + } + size = 0; + } + if (size > doinline) + can_inline = 1; + + if (can_inline == 0) { /* can not inline, drop back to old mode */ + f_print(fout, "\n"); + for (dl = def->def.st.decls; dl != NULL; dl = dl->next) + print_stat(1, &dl->decl); + return; + }; + + /* May cause lint to complain. but ... */ + f_print(fout, "\tint32_t *buf;\n"); + + flag = PUT; + f_print(fout, "\n\tif (xdrs->x_op == XDR_ENCODE) {\n"); + + for (j = 0; j < 2; j++) { + i = 0; + size = 0; + sizestr = NULL; + 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 { + char *nsizestr; + + nsizestr = realloc(sizestr, strlen(sizestr) + strlen(ptemp) + 1); + if (nsizestr == NULL) { + + errx(EXIT_FAILURE, "Out of memory"); + } + sizestr = nsizestr; + sizestr = strcat(sizestr, ptemp); /* build up length of + * array */ + + } + } + + } else { + if (i > 0) { + if (sizestr == NULL && size < doinline) { + /* don't expand into inline + * code if size < doinline */ + while (cur != dl) { + print_stat(2, &cur->decl); + cur = cur->next; + } + } else { + + + + /* were already looking at a + * xdr_inlineable structure */ + if (sizestr == NULL) + f_print(fout, "\t\tbuf = (int32_t *)XDR_INLINE(xdrs, %d * BYTES_PER_XDR_UNIT);\n", + size); + else + if (size == 0) + f_print(fout, + "\t\tbuf = (int32_t *)XDR_INLINE(xdrs, %s * BYTES_PER_XDR_UNIT);\n", + sizestr); + else + f_print(fout, + "\t\tbuf = (int32_t *)XDR_INLINE(xdrs, (%d + %s) * BYTES_PER_XDR_UNIT);\n", + size, sizestr); + + f_print(fout, "\t\tif (buf == NULL) {\n"); + + psav = cur; + while (cur != dl) { + print_stat(3, &cur->decl); + cur = cur->next; + } + + f_print(fout, "\t\t} else {\n"); + + cur = psav; + while (cur != dl) { + emit_inline(&cur->decl, flag); + cur = cur->next; + } + + f_print(fout, "\t\t}\n"); + } + } + size = 0; + i = 0; + if (sizestr) { + free(sizestr); + sizestr = NULL; + } + print_stat(2, &dl->decl); + } + + } + if (i > 0) { + if (sizestr == NULL && size < doinline) { + /* don't expand into inline code if size < + * doinline */ + while (cur != dl) { + print_stat(2, &cur->decl); + cur = cur->next; + } + } else { + + /* were already looking at a xdr_inlineable + * structure */ + if (sizestr == NULL) + f_print(fout, "\t\tbuf = (int32_t *)XDR_INLINE(xdrs, %d * BYTES_PER_XDR_UNIT);\n", + size); + else + if (size == 0) + f_print(fout, + "\t\tbuf = (int32_t *)XDR_INLINE(xdrs, %s * BYTES_PER_XDR_UNIT);\n", + sizestr); + else + f_print(fout, + "\t\tbuf = (int32_t *)XDR_INLINE(xdrs, (%d + %s) * BYTES_PER_XDR_UNIT);\n", + size, sizestr); + + f_print(fout, "\t\tif (buf == NULL) {\n"); + + psav = cur; + while (cur != NULL) { + print_stat(3, &cur->decl); + cur = cur->next; + } + f_print(fout, "\t\t} else {\n"); + + cur = psav; + while (cur != dl) { + emit_inline(&cur->decl, flag); + cur = cur->next; + } + + f_print(fout, "\t\t}\n"); + + } + } + if (flag == PUT) { + flag = GET; + f_print(fout, "\t} else if (xdrs->x_op == XDR_DECODE) {\n"); + } + } + + f_print(fout, "\t} else {\n"); + + /* now take care of XDR_FREE case */ + + for (dl = def->def.st.decls; dl != NULL; dl = dl->next) + print_stat(2, &dl->decl); + + f_print(fout, "\t}\n"); +} + +static void +emit_typedef(definition *def) +{ + const char *prefix = def->def.ty.old_prefix; + const char *type = def->def.ty.old_type; + const char *amax = def->def.ty.array_max; + relation rel = def->def.ty.rel; + + f_print(fout, "\n"); + print_ifstat(1, prefix, type, rel, amax, "objp", def->def_name); +} + +static void +print_stat(int indent, declaration *dec) +{ + const char *prefix = dec->prefix; + const char *type = dec->type; + const 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); +} + + +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\t{\n"); + f_print(fout, "\t\t\t\tint i;\n"); + f_print(fout, "\t\t\t\t%s *genp;\n", decl->type); + f_print(fout, "\n"); + f_print(fout, "\t\t\t\tfor (i = 0, genp = objp->%s;\n", + decl->name); + f_print(fout, "\t\t\t\t i < %s; i++) {\n\t\t", + decl->array_max); + emit_single_in_line(decl, flag, REL_VECTOR); + f_print(fout, "\t\t\t\t}\n\t\t\t}\n"); + break; + case REL_ARRAY: + case REL_POINTER: + errx(1, "Internal error at %s:%d: Case %d not handled", + __FILE__, __LINE__, decl->rel); + } +} + +void +emit_single_in_line(declaration *decl, int flag, relation rel) +{ + const char *upp_case; + char *freeable; + int freed = 0; + + if (flag == PUT) + f_print(fout, "\t\t\tIXDR_PUT_"); + else + if (rel == REL_ALIAS) + f_print(fout, "\t\t\tobjp->%s = IXDR_GET_", decl->name); + else + f_print(fout, "\t\t\t*genp++ = IXDR_GET_"); + + upp_case = freeable = upcase(decl->type); + + /* hack - XX */ + if (strcmp(upp_case, "INT") == 0) { + free(freeable); + freed = 1; + upp_case = "INT32"; + } else if (strcmp(upp_case, "U_INT") == 0) { + free(freeable); + 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(freeable); + +} + + +char * +upcase(const char *str) +{ + char *ptr, *hptr; + + + ptr = malloc(strlen(str) + 1); + if (ptr == NULL) { + errx(EXIT_FAILURE, "Out of memory"); + } + + hptr = ptr; + while (*str != '\0') + *ptr++ = toupper((unsigned char)*str++); + + *ptr = '\0'; + return (hptr); + +} diff --git a/buildrump.sh/src/usr.bin/rpcgen/rpc_hout.c b/buildrump.sh/src/usr.bin/rpcgen/rpc_hout.c new file mode 100644 index 00000000..741f00cd --- /dev/null +++ b/buildrump.sh/src/usr.bin/rpcgen/rpc_hout.c @@ -0,0 +1,542 @@ +/* $NetBSD: rpc_hout.c,v 1.23 2015/05/09 23:12:57 dholland Exp $ */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user or with the express written consent of + * Sun Microsystems, Inc. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if HAVE_NBTOOL_CONFIG_H +#include "nbtool_config.h" +#endif + +#include <sys/cdefs.h> +#if defined(__RCSID) && !defined(lint) +#if 0 +static char sccsid[] = "@(#)rpc_hout.c 1.12 89/02/22 (C) 1987 SMI"; +#else +__RCSID("$NetBSD: rpc_hout.c,v 1.23 2015/05/09 23:12:57 dholland Exp $"); +#endif +#endif + +/* + * rpc_hout.c, Header file outputter for the RPC protocol compiler + */ +#include <ctype.h> +#include <err.h> +#include <stdio.h> +#include "rpc_scan.h" +#include "rpc_parse.h" +#include "rpc_util.h" + +static void pconstdef(definition *); +static void pargdef(definition *); +static void pstructdef(definition *); +static void puniondef(definition *); +static void pdefine(const char *, const char *); +static void puldefine(const char *, const char *); +static int define_printed(proc_list *, version_list *); +static void pprogramdef(definition *); +static void penumdef(definition *); +static void ptypedef(definition *); +static int undefined2(const char *, const char *); +static void cplusplusstart(void); +static void cplusplusend(void); + +/* + * 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; + } +} + +void +print_progdef(definition *def) +{ + switch (def->def_kind) { + case DEF_PROGRAM: + f_print(fout, "\n"); + pprogramdef(def); + break; + case DEF_CONST: + case DEF_TYPEDEF: + case DEF_ENUM: + case DEF_UNION: + case DEF_STRUCT: + break; + } +} + +void +print_funcdef(definition *def, int *did) +{ + switch (def->def_kind) { + case DEF_PROGRAM: + case DEF_CONST: + break; + case DEF_TYPEDEF: + case DEF_ENUM: + case DEF_UNION: + case DEF_STRUCT: + if (!*did) { + f_print(fout, "\n"); + cplusplusstart(); + *did = 1; + } + pxdrfuncdecl(def->def_name, + def->def_kind != DEF_TYPEDEF || + !isvectordef(def->def.ty.old_type, def->def.ty.rel)); + break; + } +} + +void +print_funcend(int did) { + if (did) { + cplusplusend(); + } +} + +void +pxdrfuncdecl(const char *name, int pointerp) +{ + + f_print(fout, "bool_t xdr_%s(XDR *, %s%s);\n", name, + name, pointerp ? (" *") : ""); +} + + +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; + int did; + + + 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); + } + } + did = 0; + for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) { + if (!newstyle || plist->arg_num < 2) { + continue; /* old style or single args */ + } + for (plist = vers->procs; plist != NULL; plist = plist->next) { + if (!did) { + cplusplusstart(); + did = 1; + } + pxdrfuncdecl(plist->args.argname, 1); + } + } + if (did) { + cplusplusend(); + } + +} + + +static void +pstructdef(definition *def) +{ + decl_list *l; + const 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; + const 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(const char *name, const char *num) +{ + f_print(fout, "#define %s %s\n", name, num); +} + +static void +puldefine(const char *name, const char *num) +{ + f_print(fout, "#define %s %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); + } + } + } + errx(1, "Internal error at %s:%d: procedure not found", + __FILE__, __LINE__); + /* NOTREACHED */ +} + +static void +cplusplusstart(void) +{ + if (BSDflag) + f_print(fout, "__BEGIN_DECLS\n"); + else + f_print(fout, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n"); +} + +static void +cplusplusend(void) +{ + if (BSDflag) + f_print(fout, "__END_DECLS\n"); + else + f_print(fout, "#ifdef __cplusplus\n};\n#endif\n"); +} + +static void +pprogramdef(definition *def) +{ + version_list *vers; + proc_list *proc; + + 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); + for (proc = vers->procs; proc != NULL; proc = proc->next) { + if (!define_printed(proc, def->def.pr.versions)) { + puldefine(proc->proc_name, proc->proc_num); + } + } + } + + /* + * Print out 3 definitions, one for ANSI-C, another for C++, a + * third for old style C + */ + f_print(fout, "\n"); + cplusplusstart(); + for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) { + for (proc = vers->procs; proc != NULL; proc = proc->next) { + pprocdef(proc, vers, "CLIENT *", 0); + pprocdef(proc, vers, "struct svc_req *", 1); + } + } + cplusplusend(); +} + +void +pprocdef(proc_list *proc, version_list *vp, const char *addargtype, + int server_p) +{ + decl_list *dl; + + if (Mflag) { + if (server_p) + f_print(fout, "bool_t "); + else + f_print(fout, "enum clnt_stat "); + } else { + 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); + + 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, "*"); + f_print(fout, ", "); + } + } + if (Mflag) { + if (streq(proc->res_type, "void")) + f_print(fout, "char"); + else + ptype(proc->res_prefix, proc->res_type, 0); + if (!isvectordef(proc->res_type, REL_ALIAS)) + f_print(fout, "*"); + f_print(fout, ", "); + } + f_print(fout, "%s);\n", addargtype); +} + + +static void +penumdef(definition *def) +{ + const char *name = def->def_name; + enumval_list *l; + const char *last = NULL; + int count = 0; + const char *first = ""; + + f_print(fout, "enum %s {\n", name); + for (l = def->def.en.vals; l != NULL; l = l->next) { + f_print(fout, "%s\t%s", first, 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++); + } + } + first = ",\n"; + } + f_print(fout, "\n};\n"); + f_print(fout, "typedef enum %s %s;\n", name, name); +} + +static void +ptypedef(definition *def) +{ + const char *name = def->def_name; + const 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(const char *name, declaration *dec, int tab, + const char *separator) +{ + char buf[8]; /* enough to hold "struct ", include NUL */ + const char *prefix; + const 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, "%s", separator); +} + +static int +undefined2(const char *type, const 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/buildrump.sh/src/usr.bin/rpcgen/rpc_main.c b/buildrump.sh/src/usr.bin/rpcgen/rpc_main.c new file mode 100644 index 00000000..1e660453 --- /dev/null +++ b/buildrump.sh/src/usr.bin/rpcgen/rpc_main.c @@ -0,0 +1,1137 @@ +/* $NetBSD: rpc_main.c,v 1.42 2015/05/09 23:12:57 dholland Exp $ */ + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user or with the express written consent of + * Sun Microsystems, Inc. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if HAVE_NBTOOL_CONFIG_H +#include "nbtool_config.h" +#endif + +#include <sys/cdefs.h> +#if defined(__RCSID) && !defined(lint) +#if 0 +static char sccsid[] = "@(#)rpc_main.c 1.30 89/03/30 (C) 1987 SMI"; +#else +__RCSID("$NetBSD: rpc_main.c,v 1.42 2015/05/09 23:12:57 dholland Exp $"); +#endif +#endif + +/* + * rpc_main.c, Top level of the RPC protocol compiler. + */ + +#define RPCGEN_VERSION "199506"/* This program's version (year & month) */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/file.h> +#include <sys/stat.h> +#include <ctype.h> +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include "rpc_scan.h" +#include "rpc_parse.h" +#include "rpc_util.h" + +#define EXTEND 1 /* alias for TRUE */ +#define DONT_EXTEND 0 /* alias for FALSE */ + +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 *cmdname; + +static const char *svcclosetime = "120"; +static const char *CPP; +static char CPPFLAGS[] = "-C"; +static char pathbuf[MAXPATHLEN + 1]; + +/* these cannot be const */ +static char allv0[] = "rpcgen"; +static char allv1[] = "-s"; +static char allv2[] = "udp"; +static char allv3[] = "-s"; +static char allv4[] = "tcp"; +static char *allv[] = { + allv0, + allv1, + allv2, + allv3, + allv4, +}; +static int allc = sizeof(allv) / sizeof(allv[0]); + +/* these cannot be const */ +static char allnv0[] = "rpcgen"; +static char allnv1[] = "-s"; +static char allnv2[] = "netpath"; +static char *allnv[] = { + allnv0, + allnv1, + allnv2, +}; +static int allnc = sizeof(allnv) / sizeof(allnv[0]); + +#define ARGLISTLEN 20 +#define FIXEDARGS 2 + +static const 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 */ +int BSDflag; /* use BSD cplusplus macros */ +int callerflag; /* Generate svc_caller() function */ +int docleanup = 1; /* cause atexit to remove files */ + +#define INLINE 3 +/*length at which to start doing an inline */ + +int doinline = 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 Mflag = 0; /* multithread safe */ +static int allfiles; /* generate all files */ +int tirpcflag = 1; /* generating code for tirpc, by default */ + +#ifdef __MSDOS__ +static char *dos_cppfile = NULL; +#endif + +static char *extendfile(const char *, const char *); +static void open_output(const char *, const char *); +static void add_warning(void); +static void clear_args(void); +static void open_input(const char *, const char *); +static int check_nettype(const char *, const char *[]); +static void c_output(const char *, const char *, int, const char *); +static void c_initialize(void); +static char *generate_guard(const char *); +static void h_output(const char *, const char *, int, const char *); +static void s_output(int, char *[], char *, const char *, int, const char *, + int, int); +static void l_output(const char *, const char *, int, const char *); +static void t_output(const char *, const char *, int, const char *); +static void svc_output(const char *, const char *, int, const char *); +static void clnt_output(const char *, const char *, int, const char *); +static int do_registers(int, char *[]); +static void addarg(const char *); +static void putarg(int, const char *); +static void checkfiles(const char *, const char *); +static int parseargs(int, char *[], struct commandline *); +static void usage(void) __dead; +static void options_usage(void) __dead; + +int +main(int argc, char *argv[]) +{ + struct commandline cmd; + + setprogname(argv[0]); + if ((CPP = getenv("RPCGEN_CPP")) == NULL) { + CPP = "/usr/bin/cpp"; + if (access(CPP, X_OK)) + CPP = "/usr/bin/clang-cpp"; + } + + (void) memset((char *) &cmd, 0, sizeof(struct commandline)); + clear_args(); + atexit(crash); + 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"); + } + } +#ifdef __MSDOS__ + if (dos_cppfile != NULL) { + (void) fclose(fin); + (void) unlink(dos_cppfile); + } +#endif + docleanup = 0; + exit(nonfatalerrors); + /* NOTREACHED */ +} +/* + * add extension to filename + */ +static char * +extendfile(const char *path, const char *ext) +{ + const char *file; + char *res; + const char *p; + + if ((file = strrchr(path, '/')) == NULL) + file = path; + else + file++; + + res = alloc(strlen(file) + strlen(ext) + 1); + if (res == NULL) { + errx(1, "Out of memory"); + } + 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(const char *infile, const char *outfile) +{ + + if (outfile == NULL) { + fout = stdout; + return; + } + if (infile != NULL && streq(outfile, infile)) { + errx(EXIT_FAILURE, "Output would overwrite `%s'", infile); + } + fout = fopen(outfile, "w"); + if (fout == NULL) { + err(EXIT_FAILURE, "Can't open `%s'", outfile); + } + 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(const char *infile, const char *define) +{ + int pd[2]; + + infilename = (infile == NULL) ? "<stdin>" : infile; +#ifdef __MSDOS__ +#define DOSCPP "\\prog\\bc31\\bin\\cpp.exe" + { + int retval; + char drive[MAXDRIVE], dir[MAXDIR], name[MAXFILE], ext[MAXEXT]; + char cppfile[MAXPATH]; + char *cpp; + + if ((cpp = getenv("RPCGEN_CPP")) == NULL && + (cpp = searchpath("cpp.exe")) == NULL) + cpp = DOSCPP; + + putarg(0, cpp); + putarg(1, "-P-"); + putarg(2, CPPFLAGS); + addarg(define); + addarg(infile); + addarg(NULL); + + retval = spawnvp(P_WAIT, arglist[0], arglist); + if (retval != 0) { + err(EXIT_FAILURE, "C preprocessor failed"); + } + fnsplit(infile, drive, dir, name, ext); + fnmerge(cppfile, drive, dir, name, ".i"); + + fin = fopen(cppfile, "r"); + if (fin == NULL) { + err(EXIT_FAILURE, "Can't open `%s'", cppfile); + } + dos_cppfile = strdup(cppfile); + if (dos_cppfile == NULL) { + err(EXIT_FAILURE, "Can't copy `%s'", cppfile); + } + } +#else + (void) pipe(pd); + switch (fork()) { + case 0: + putarg(0, CPP); + putarg(1, CPPFLAGS); + addarg(define); + addarg(infile); + addarg(NULL); + (void) close(1); + (void) dup2(pd[1], 1); + (void) close(pd[0]); + execvp(arglist[0], __UNCONST(arglist)); + err(EXIT_FAILURE, "$RPCGEN_CPP: %s", CPP); + case -1: + err(EXIT_FAILURE, "fork"); + } + (void) close(pd[1]); + fin = fdopen(pd[0], "r"); +#endif + if (fin == NULL) { + err(EXIT_FAILURE, "Can't open `%s'", infilename); + } +} +/* valid tirpc nettypes */ +static const char *valid_ti_nettypes[] = +{ + "netpath", + "visible", + "circuit_v", + "datagram_v", + "circuit_n", + "datagram_n", + "udp", + "tcp", + "raw", + NULL +}; +/* valid inetd nettypes */ +static const char *valid_i_nettypes[] = +{ + "udp", + "tcp", + NULL +}; + +static int +check_nettype(const char *name, const 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(const char *infile, const char *define, int extend, + const char *outfile) +{ + definition *def; + char *include; + const 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, "long"); + add_type(1, "short"); + add_type(1, "bool"); + + add_type(1, "u_int"); + add_type(1, "u_long"); + add_type(1, "u_short"); + +} + +const 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(const char *pathname) +{ + const char *filename; + char *guard, *tmp, *tmp2; + + filename = strrchr(pathname, '/'); /* find last component */ + filename = ((filename == 0) ? pathname : filename + 1); + guard = strdup(filename); + /* convert to upper case */ + tmp = guard; + while (*tmp) { + *tmp = toupper((unsigned char)*tmp); + tmp++; + } + + tmp2 = extendfile(guard, "_H_RPCGEN"); + free(guard); + guard = tmp2; + return (guard); +} + +/* + * Compile into an XDR header file + */ +static void +h_output(const char *infile, const char *define, int extend, + const char *outfile) +{ + definition *def; + const char *outfilename; + long tell; + char *guard; + list *l; + int did; + + open_input(infile, define); + outfilename = extend ? extendfile(infile, outfile) : outfile; + open_output(infile, outfilename); + add_warning(); + if (outfilename || infile) + guard = generate_guard(outfilename ? outfilename : infile); + else { + guard = strdup("STDIN_"); + if (guard == NULL) { + err(EXIT_FAILURE, "strdup"); + } + } + + f_print(fout, "#ifndef _%s\n#define _%s\n\n", guard, + guard); + + f_print(fout, "#define RPCGEN_VERSION\t%s\n\n", RPCGEN_VERSION); + f_print(fout, "#include <rpc/rpc.h>\n\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 */ + did = 0; + for (l = defined; l != NULL; l = l->next) { + print_funcdef(l->val, &did); + } + print_funcend(did); + + for (l = defined; l != NULL; l = l->next) { + print_progdef(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); + + free(guard); +} + +/* + * Compile into an RPC service + */ +static void +s_output(int argc, char *argv[], char *infile, + const char *define, int extend, const char *outfile, int nomain, + int netflag) +{ + char *include; + definition *def; + int foundprogram = 0; + const 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 <sys/ioctl.h>\n"); + f_print(fout, "#include <fcntl.h>\n"); + f_print(fout, "#include <stdio.h>\n"); + f_print(fout, "#include <err.h>\n"); + f_print(fout, "#include <stdlib.h>\n"); + f_print(fout, "#include <unistd.h>\n"); + f_print(fout, "#include <rpc/pmap_clnt.h>\n"); + f_print(fout, "#include <string.h>\n"); + f_print(fout, "#include <netdb.h>\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; + } + if (!tirpcflag && inetdflag) + f_print(fout, "#include <sys/ttycom.h>\n"); + if (inetdflag || pmflag) { + f_print(fout, "#ifdef __cplusplus\n"); + f_print(fout, "#include <sysent.h>\n"); + f_print(fout, "#endif /* __cplusplus */\n"); + } + if (tirpcflag) + f_print(fout, "#include <sys/types.h>\n"); + + f_print(fout, "#include <memory.h>\n"); + + 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>\n"); + if (logflag || inetdflag || pmflag) + f_print(fout, "#include <syslog.h>\n"); + + f_print(fout, "\n#define SIG_PF void(*)(int)\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; + } + if (callerflag) /* EVAS */ + f_print(fout, "\nstatic SVCXPRT *caller;\n"); /* EVAS */ + 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(const char *infile, const char *define, int extend, + const char *outfile) +{ + char *include; + definition *def; + int foundprogram = 0; + const char *outfilename; + + open_input(infile, define); + outfilename = extend ? extendfile(infile, outfile) : outfile; + open_output(infile, outfilename); + add_warning(); + f_print(fout, "#include <memory.h>\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(const char *infile, const char *define, int extend, + const char *outfile) +{ + definition *def; + int foundprogram = 0; + const 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(const char *infile, const char *define, int extend, + const char *outfile) +{ + definition *def; + char *include; + const 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(const char *infile, const char *define, int extend, + const char *outfile) +{ + definition *def; + char *include; + const 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(); + f_print(fout, "#include <stdio.h>\n"); + f_print(fout, "#include <err.h>\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"); + 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(const char *cp) +{ + if (argcount >= ARGLISTLEN) { + errx(EXIT_FAILURE, "Internal error: too many defines"); + /* NOTREACHED */ + } + arglist[argcount++] = cp; + +} + +static void +putarg(int pwhere, const char *cp) +{ + if (pwhere >= ARGLISTLEN) { + errx(EXIT_FAILURE, "Internal error: arglist coding error"); + /* NOTREACHED */ + } + arglist[pwhere] = 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(const char *infile, const char *outfile) +{ + + struct stat buf; + + if (infile) /* infile ! = NULL */ + if (stat(infile, &buf) < 0) { + err(EXIT_FAILURE, "Can't stat `%s'", infile); + }; +#if 0 + if (outfile) { + if (stat(outfile, &buf) < 0) + return; /* file does not exist */ + else { + errx(EXIT_FAILURE, + "`%s' already exists and would be overwritten", + outfile); + } + } +#endif +} +/* + * Parse command line arguments + */ +static int +parseargs(int argc, char *argv[], struct commandline *cmd) +{ + int i; + int j; + int c; + char flag[1 << CHAR_BIT]; + 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': + callerflag = 1; + break; + case 'a': + allfiles = 1; + break; + case 'B': + BSDflag = 1; + break; + case 'c': + case 'h': + case 'l': + case 'm': + case 't': + if (flag[c]) { + return (0); + } + flag[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[c]) { + return (0); + } + flag[c] = 1; + break; + case 'C': /* deprecated ANSI C syntax */ + break; + + case 'b': /* turn TIRPC flag off for + * generating backward + * compatible */ + tirpcflag = 0; + break; + + case 'I': + inetdflag = 1; + break; + case 'M': + Mflag = 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); + } + doinline = atoi(argv[i]); + goto nextarg; + case 'n': + case 'o': + case 's': + if (argv[i][j - 1] != '-' || + argv[i][j + 1] != 0) { + return (0); + } + flag[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) strlcpy(pathbuf, argv[i], + sizeof(pathbuf)); + (void) strlcat(pathbuf, "/cpp", + sizeof(pathbuf)); + CPP = pathbuf; + goto nextarg; + + case 'v': + printf("version 1.0\n"); + exit(0); + + 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 [-AaBbILMNTv] [-Dname[=value]] [-i size] [-K seconds] [-Y pathname] 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 svc_caller() function\n"); + f_print(stderr, "-a\t\tgenerate all files, including samples\n"); + f_print(stderr, "-B\t\tgenerate BSD c++ macros\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, "-Dname[=value]\tdefine a symbol (same as #define)\n"); + f_print(stderr, "-h\t\tgenerate header file\n"); + f_print(stderr, "-I\t\tgenerate code for inetd support in server (for SunOS 4.1)\n"); + f_print(stderr, "-i size\t\tsize at which to start generating inline code\n"); + f_print(stderr, "-K seconds\tserver exits after K seconds of inactivity\n"); + f_print(stderr, "-L\t\tserver errors will be printed to syslog\n"); + f_print(stderr, "-l\t\tgenerate client side stubs\n"); + f_print(stderr, "-M\t\tgenerate thread-safe stubs\n"); + f_print(stderr, "-m\t\tgenerate server side stubs\n"); + f_print(stderr, "-N\t\tsupports multiple arguments and call-by-value\n"); + f_print(stderr, "-n netid\tgenerate server code that supports named netid\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 code to support RPC dispatch tables\n"); + f_print(stderr, "-t\t\tgenerate RPC dispatch table\n"); + f_print(stderr, "-v\t\tdisplay version number\n"); + f_print(stderr, "-Y path\t\tdirectory name to find C preprocessor (cpp)\n"); + + exit(1); +} diff --git a/buildrump.sh/src/usr.bin/rpcgen/rpc_parse.c b/buildrump.sh/src/usr.bin/rpcgen/rpc_parse.c new file mode 100644 index 00000000..3a59e8d1 --- /dev/null +++ b/buildrump.sh/src/usr.bin/rpcgen/rpc_parse.c @@ -0,0 +1,618 @@ +/* $NetBSD: rpc_parse.c,v 1.21 2015/05/09 23:29:51 dholland Exp $ */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user or with the express written consent of + * Sun Microsystems, Inc. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if HAVE_NBTOOL_CONFIG_H +#include "nbtool_config.h" +#endif + +#include <sys/cdefs.h> +#if defined(__RCSID) && !defined(lint) +#if 0 +static char sccsid[] = "@(#)rpc_parse.c 1.8 89/02/22 (C) 1987 SMI"; +#else +__RCSID("$NetBSD: rpc_parse.c,v 1.21 2015/05/09 23:29:51 dholland Exp $"); +#endif +#endif + +/* + * rpc_parse.c, Parser for the RPC protocol compiler + * Copyright (C) 1987 Sun Microsystems, Inc. + */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "rpc/types.h" +#include "rpc_scan.h" +#include "rpc_parse.h" +#include "rpc_util.h" + +#define ARGNAME "arg" + +static void isdefined(definition *); +static void def_struct(definition *); +static void def_program(definition *); +static void def_enum(definition *); +static void def_const(definition *); +static void def_union(definition *); +static void check_type_name(const char *, int); +static void def_typedef(definition *); +static void get_declaration(declaration *, defkind); +static void get_prog_declaration(declaration *, defkind, int); +static void get_type(const char **, const char **, defkind); +static void unsigned_dec(const char **); + +/* + * 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("Expected definition keyword"); + } + 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 const char *const reserved_words[] = { + "array", + "bytes", + "destroy", + "free", + "getpos", + "inline", + "pointer", + "reference", + "setpos", + "sizeof", + "union", + "vector", + NULL +}; + +static const char *const 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(const char *name, int new_type) +{ + int i; + + for (i = 0; reserved_words[i] != NULL; i++) { + if (strcmp(name, reserved_words[i]) == 0) { + error("Illegal (reserved) name '%s' in type definition", name); + } + } + if (new_type) { + for (i = 0; reserved_types[i] != NULL; i++) { + if (strcmp(name, reserved_types[i]) == 0) { + error("Illegal (reserved) name '%s' in type definition", name); + } + } + } +} + +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 = "(u_int)~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 /* arg number */) +{ + token tok; + char name[255]; /* 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 = 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 = "(u_int)~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 = "(u_int)~0"; + /* unspecified size, use max */ + } + } +} + + + +static void +get_type(const char **prefixp, const 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_LONG: + *typep = "long"; + (void) peekscan(TOK_INT, &tok); + break; + case TOK_HYPER: + *typep = "longlong_t"; + (void) peekscan(TOK_INT, &tok); + break; + case TOK_VOID: + if (dkind != DEF_UNION && dkind != DEF_PROGRAM) { + error("Void is 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: + case TOK_QUAD: + *typep = tok.str; + break; + default: + error("Type specifier expected"); + } +} + +static void +unsigned_dec(const 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_LONG: + get_token(&tok); + *typep = "u_long"; + (void) peekscan(TOK_INT, &tok); + break; + case TOK_HYPER: + get_token(&tok); + *typep = "u_longlong_t"; + (void) peekscan(TOK_INT, &tok); + break; + case TOK_INT: + get_token(&tok); + *typep = "u_int"; + break; + default: + *typep = "u_int"; + break; + } +} diff --git a/buildrump.sh/src/usr.bin/rpcgen/rpc_parse.h b/buildrump.sh/src/usr.bin/rpcgen/rpc_parse.h new file mode 100644 index 00000000..05f7f6cd --- /dev/null +++ b/buildrump.sh/src/usr.bin/rpcgen/rpc_parse.h @@ -0,0 +1,168 @@ +/* $NetBSD: rpc_parse.h,v 1.6 2015/05/09 21:44:47 christos Exp $ */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user or with the express written consent of + * Sun Microsystems, Inc. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* @(#)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 const 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 { + const char *old_prefix; + const char *old_type; + relation rel; + const char *array_max; +}; +typedef struct typedef_def typedef_def; + +struct enumval_list { + const char *name; + const 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 { + const char *prefix; + const char *type; + const char *name; + relation rel; + const 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 { + const 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 { + const char *proc_name; + const char *proc_num; + arg_list args; + int arg_num; + const char *res_type; + const char *res_prefix; + struct proc_list *next; +}; +typedef struct proc_list proc_list; + +struct version_list { + const char *vers_name; + const char *vers_num; + proc_list *procs; + struct version_list *next; +}; +typedef struct version_list version_list; + +struct program_def { + const char *prog_num; + version_list *versions; +}; +typedef struct program_def program_def; + +struct definition { + const 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(void); + +struct bas_type +{ + const char *name; + int length; + struct bas_type *next; +}; + +typedef struct bas_type bas_type; diff --git a/buildrump.sh/src/usr.bin/rpcgen/rpc_sample.c b/buildrump.sh/src/usr.bin/rpcgen/rpc_sample.c new file mode 100644 index 00000000..5aa88628 --- /dev/null +++ b/buildrump.sh/src/usr.bin/rpcgen/rpc_sample.c @@ -0,0 +1,275 @@ +/* $NetBSD: rpc_sample.c,v 1.13 2013/12/15 00:40:17 christos Exp $ */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user or with the express written consent of + * Sun Microsystems, Inc. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if HAVE_NBTOOL_CONFIG_H +#include "nbtool_config.h" +#endif + +#include <sys/cdefs.h> +#if defined(__RCSID) && !defined(lint) +#if 0 +static char sccsid[] = "@(#)rpc_sample.c 1.1 90/08/30 (C) 1987 SMI"; +#else +__RCSID("$NetBSD: rpc_sample.c,v 1.13 2013/12/15 00:40:17 christos Exp $"); +#endif +#endif + +/* + * rpc_sample.c, Sample client-server code outputter for the RPC protocol compiler + */ + +#include <stdio.h> +#include <string.h> +#include "rpc_scan.h" +#include "rpc_parse.h" +#include "rpc_util.h" + +static char RQSTP[] = "rqstp"; + +static void write_sample_client(const char *, version_list *); +static void write_sample_server(definition *); +static void return_type(proc_list *); + +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(const char *program_name, version_list *vp) +{ + proc_list *proc; + decl_list *l; + + f_print(fout, "\n\nvoid\n"); + pvname(program_name, vp->vers_num); + f_print(fout, "(char *host)\n{\n"); + f_print(fout, "\tCLIENT *clnt;\n"); + + for (proc = vp->procs; proc != NULL; proc = proc->next) { + /* print out declarations for arguments */ + if (proc->arg_num < 2 && !newstyle) { + f_print(fout, "\t"); + if (streq(proc->args.decls->decl.type, "void")) + f_print(fout, "char "); /* cannot have "void" + * type */ + else + ptype(proc->args.decls->decl.prefix, proc->args.decls->decl.type, 1); + 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); + pvname(proc->proc_name, vp->vers_num); + f_print(fout, "_%s;\n", l->decl.name); +/* pdeclaration(proc->args.argname, &l->decl, 1, ";\n" );*/ + } + } + } + /* print out declarations for results */ + f_print(fout, "\t"); + if (streq(proc->res_type, "void")) + f_print(fout, "char"); /* cannot have "void" + * type */ + else + ptype(proc->res_prefix, proc->res_type, 1); + if (!Mflag) + f_print(fout, "*"); + pvname(proc->proc_name, vp->vers_num); + f_print(fout, "_res;\n"); + } + f_print(fout, "\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 */ + for (proc = vp->procs; proc != NULL; proc = proc->next) { + if (Mflag) + f_print(fout, "\tif ("); + else { + f_print(fout, "\t"); + pvname(proc->proc_name, vp->vers_num); + f_print(fout, "_res = "); + } + 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, "); + } 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); + } + } + } + if (Mflag) { + f_print(fout, "&"); + pvname(proc->proc_name, vp->vers_num); + f_print(fout, "_res, clnt) != RPC_SUCCESS)\n"); + } else { + f_print(fout, "clnt);\n"); + f_print(fout, "\tif ("); + pvname(proc->proc_name, vp->vers_num); + f_print(fout, "_res == NULL)\n"); + } + f_print(fout, "\t\tclnt_perror(clnt, \"call failed\");\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 (Mflag) + f_print(fout, "bool_t\n"); + else { + return_type(proc); + f_print(fout, "*\n"); + } + pvname_svc(proc->proc_name, vp->vers_num); + printarglist(proc, "result", RQSTP, "struct svc_req *"); + + f_print(fout, "{\n"); + if (Mflag) { + f_print(fout, "\tbool_t retval = TRUE;\n"); + } else { + f_print(fout, "\tstatic "); + if (streq(proc->res_type, "void")) + f_print(fout, "char "); /* cannot have void type */ + else + return_type(proc); + f_print(fout, "result;\n"); + } + f_print(fout, + "\n\t/*\n\t * insert server code here\n\t */\n\n"); + if (Mflag) { + f_print(fout, "\treturn (retval);\n"); + } else { + if (streq(proc->res_type, "void")) + f_print(fout, "\treturn ((void *)&result);\n"); + else + f_print(fout, "\treturn (&result);\n"); + } + 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"); + f_print(fout, "int\nmain(int argc, char *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, "\texit(0);\n"); + f_print(fout, "}\n"); +} diff --git a/buildrump.sh/src/usr.bin/rpcgen/rpc_scan.c b/buildrump.sh/src/usr.bin/rpcgen/rpc_scan.c new file mode 100644 index 00000000..4e236f88 --- /dev/null +++ b/buildrump.sh/src/usr.bin/rpcgen/rpc_scan.c @@ -0,0 +1,492 @@ +/* $NetBSD: rpc_scan.c,v 1.15 2015/05/09 23:28:43 dholland Exp $ */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user or with the express written consent of + * Sun Microsystems, Inc. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if HAVE_NBTOOL_CONFIG_H +#include "nbtool_config.h" +#endif + +#include <sys/cdefs.h> +#if defined(__RCSID) && !defined(lint) +#if 0 +static char sccsid[] = "@(#)rpc_scan.c 1.11 89/02/22 (C) 1987 SMI"; +#else +__RCSID("$NetBSD: rpc_scan.c,v 1.15 2015/05/09 23:28:43 dholland Exp $"); +#endif +#endif + +/* + * rpc_scan.c, Scanner for the RPC protocol compiler + * Copyright (C) 1987, Sun Microsystems, Inc. + */ +#include <stdlib.h> +#include <stdio.h> +#include <ctype.h> +#include <string.h> +#include "rpc_scan.h" +#include "rpc_parse.h" +#include "rpc_util.h" + +#define startcomment(where) (where[0] == '/' && where[1] == '*') +#define endcomment(where) (where[-1] == '*' && where[0] == '/') + +static void unget_token(token *); +static void findstrconst(char **, const char **); +static void findchrconst(char **, const char **); +static void findconst(char **, const char **); +static void findkind(char **, token *); +static int cppline(const char *); +static int directive(const char *); +static void printdirective(const char *); +static void docppline(char *, int *, const char **); + +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("Expected constant or identifier"); + } +} +/* + * 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((unsigned char)*where)) { + while (isspace((unsigned char)*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((unsigned char)*where) || *where == '_')) { + if (isprint((unsigned char)*where)) { + error("Illegal character '%c' in file", *where); + } else { + error("Illegal character %d in file", *where); + } + } + findkind(&where, tokp); + break; + } +} + +static void +unget_token(token *tokp) +{ + lasttok = *tokp; + pushed = 1; +} + +static void +findstrconst(char **str, const char **val) +{ + char *p; + int size; + char *tmp; + + p = *str; + do { + p++; + } while (*p && *p != '"'); + if (*p == 0) { + error("Unterminated string constant"); + } + p++; + size = p - *str; + tmp = alloc(size + 1); + (void) strncpy(tmp, *str, size); + tmp[size] = 0; + *val = tmp; + *str = p; +} + +static void +findchrconst(char **str, const char **val) +{ + char *p; + int size; + char *tmp; + + p = *str; + do { + p++; + } while (*p && *p != '\''); + if (*p == 0) { + error("Unterminated string constant"); + } + p++; + size = p - *str; + if (size != 3) { + error("Empty character"); + } + tmp = alloc(size + 1); + (void) strncpy(tmp, *str, size); + tmp[size] = 0; + *val = tmp; + *str = p; +} + +static void +findconst(char **str, const char **val) +{ + char *p; + int size; + char *tmp; + + p = *str; + if (*p == '0' && *(p + 1) == 'x') { + p++; + do { + p++; + } while (isxdigit((unsigned char)*p)); + } else { + do { + p++; + } while (isdigit((unsigned char)*p)); + } + size = p - *str; + tmp = alloc(size + 1); + (void) strncpy(tmp, *str, size); + tmp[size] = 0; + *val = tmp; + *str = p; +} + +static const 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_LONG, "long"}, + {TOK_HYPER, "hyper"}, + {TOK_FLOAT, "float"}, + {TOK_DOUBLE, "double"}, + {TOK_QUAD, "quadruple"}, + {TOK_STRING, "string"}, + {TOK_PROGRAM, "program"}, + {TOK_VERSION, "version"}, + {TOK_EOF, "??????"}, +}; + +static void +findkind(char **mark, token *tokp) +{ + int len; + const token *s; + char *str; + char *tmp; + + str = *mark; + for (s = symbols; s->kind != TOK_EOF; s++) { + len = strlen(s->str); + if (strncmp(str, s->str, len) == 0) { + if (!isalnum((unsigned char)str[len]) && + str[len] != '_') { + tokp->kind = s->kind; + tokp->str = s->str; + *mark = str + len; + return; + } + } + } + tokp->kind = TOK_IDENT; + for (len = 0; isalnum((unsigned char)str[len]) || + str[len] == '_'; len++); + tmp = alloc(len + 1); + (void) strncpy(tmp, str, len); + tmp[len] = 0; + tokp->str = tmp; + *mark = str + len; +} + +static int +cppline(const char *line) +{ + return (line == curline && *line == '#'); +} + +static int +directive(const char *line) +{ + return (line == curline && *line == '%'); +} + +static void +printdirective(const char *line) +{ + f_print(fout, "%s", line + 1); +} + +static void +docppline(char *line, int *lineno, const char **fname) +{ + char *file; + int num; + char *p; + + line++; + while (isspace((unsigned char)*line)) { + line++; + } + num = atoi(line); + while (isdigit((unsigned char)*line)) { + line++; + } + while (isspace((unsigned char)*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/buildrump.sh/src/usr.bin/rpcgen/rpc_scan.h b/buildrump.sh/src/usr.bin/rpcgen/rpc_scan.h new file mode 100644 index 00000000..1b63a067 --- /dev/null +++ b/buildrump.sh/src/usr.bin/rpcgen/rpc_scan.h @@ -0,0 +1,108 @@ +/* $NetBSD: rpc_scan.h,v 1.10 2015/05/09 21:44:47 christos Exp $ */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user or with the express written consent of + * Sun Microsystems, Inc. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* @(#)rpc_scan.h 1.3 90/08/29 (C) 1987 SMI */ + +#if HAVE_NBTOOL_CONFIG_H +#include "nbtool_config.h" +#endif + +/* + * 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_LONG, + TOK_HYPER, + TOK_UNSIGNED, + TOK_FLOAT, + TOK_DOUBLE, + TOK_QUAD, + 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; + const char *str; +}; +typedef struct token token; + + +/* + * routine interface + */ +void scan(tok_kind, token *); +void scan2(tok_kind, tok_kind, token *); +void scan3(tok_kind, tok_kind, tok_kind, token *); +void scan_num(token *); +void peek(token *); +int peekscan(tok_kind, token *); +void get_token(token *); diff --git a/buildrump.sh/src/usr.bin/rpcgen/rpc_svcout.c b/buildrump.sh/src/usr.bin/rpcgen/rpc_svcout.c new file mode 100644 index 00000000..0f11d790 --- /dev/null +++ b/buildrump.sh/src/usr.bin/rpcgen/rpc_svcout.c @@ -0,0 +1,966 @@ +/* $NetBSD: rpc_svcout.c,v 1.29 2015/05/09 21:44:47 christos Exp $ */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user or with the express written consent of + * Sun Microsystems, Inc. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if HAVE_NBTOOL_CONFIG_H +#include "nbtool_config.h" +#endif + +#include <sys/cdefs.h> +#if defined(__RCSID) && !defined(lint) +#if 0 +static char sccsid[] = "@(#)rpc_svcout.c 1.29 89/03/30 (C) 1987 SMI"; +#else +__RCSID("$NetBSD: rpc_svcout.c,v 1.29 2015/05/09 21:44:47 christos Exp $"); +#endif +#endif + +/* + * rpc_svcout.c, Server-skeleton outputter for the RPC protocol compiler + */ +#include <stdio.h> +#include <string.h> +#include "rpc_scan.h" +#include "rpc_parse.h" +#include "rpc_util.h" + +static char RQSTP[] = "rqstp"; +static char TRANSP[] = "transp"; +static char ARG[] = "argument"; +static char RESULT[] = "result"; +static char ROUTINE[] = "local"; + +static void p_xdrfunc(const char *, const char *); +static void internal_proctype(proc_list *); +static void write_real_program(definition *); +static void write_program(definition *, const char *); +static void printerr(const char *, const char *); +static void printif(const char *, const char *, const char *, const char *); +static void write_inetmost(char *); +static void print_return(const char *); +static void print_pmapunset(const char *); +static void print_err_message(const char *); +static void write_timeout_func(void); +static void write_caller_func(void); +static void write_pm_most(char *, int); +static void write_rpc_svc_fg(char *, const char *); +static void open_log_file(char *, const char *); +static const char *aster(const char *); + +char _errbuf[256]; /* For all messages */ + +static void +p_xdrfunc(const char *rname, const char *typename) +{ + f_print(fout, "\t\txdr_%s = (xdrproc_t)xdr_%s;\n", rname, + stringfix(typename)); +} + +static void +internal_proctype(proc_list *plist) +{ + f_print(fout, "static "); + ptype(plist->res_prefix, plist->res_type, 1); + if (!Mflag) + f_print(fout, "*"); +} + + +/* + * write most of the service, that is, everything but the registrations. + */ +void +write_most(char *infile /* our name */, int netflag, int nomain) +{ + if (inetdflag || pmflag) { + const char *var_type; + var_type = (nomain ? "" : "static "); + f_print(fout, "%sint _rpcpmstart;", var_type); + f_print(fout, "\t\t/* Started by a port monitor ? */\n"); + f_print(fout, "%sint _rpcfdtype;", var_type); + f_print(fout, "\t\t/* Whether Stream or Datagram ? */\n"); + if (timerflag) { + f_print(fout, "%sint _rpcsvcdirty;", var_type); + f_print(fout, "\t/* Still serving ? */\n"); + } + write_svc_aux(nomain); + } + /* write out dispatcher and stubs */ + write_programs(nomain ? NULL : "static"); + + if (nomain) + return; + + f_print(fout, "\n\n"); + f_print(fout, "int main(int, char *[]);\n"); + f_print(fout, "\nint\n"); + f_print(fout, "main(int argc, char *argv[])\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, "\tSVCXPRT *%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, "\tSVCXPRT *%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(const char *transp) +{ + list *l; + definition *def; + version_list *vp; + const 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(const 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 == 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, (SIG_PF)closedown);\n"); + 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(const 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 definition 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); + f_print(fout, "("); + /* arg name */ + if (proc->arg_num > 1) + f_print(fout, "%s ", + proc->args.argname); + else + ptype(proc->args.decls->decl.prefix, + proc->args.decls->decl.type, 0); + f_print(fout, "*argp, "); + if (Mflag) { + if (streq(proc->res_type, "void")) + f_print(fout, "char "); + else + ptype(proc->res_prefix, + proc->res_type, 0); + f_print(fout, "%sresult, ", + aster(proc->res_type)); + } + f_print(fout, "struct svc_req *%s)\n", RQSTP); + f_print(fout, "{\n"); + f_print(fout, "\treturn ("); + pvname_svc(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, const 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 "); + pvname(def->def_name, vp->vers_num); + f_print(fout, "(struct svc_req *%s, ", RQSTP); + f_print(fout, "SVCXPRT *%s);\n", TRANSP); + f_print(fout, "\n"); + if (storage != NULL) { + f_print(fout, "%s ", storage); + } + f_print(fout, "void\n"); + pvname(def->def_name, vp->vers_num); + + f_print(fout, "(struct svc_req *%s, ", RQSTP); + f_print(fout, "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); + if (Mflag) { + f_print(fout, "\tunion {\n"); + for (proc = vp->procs; proc != NULL; proc = proc->next) { + f_print(fout, "\t\t"); + if (streq(proc->res_type, "void")) + f_print(fout, "char "); + else + ptype(proc->res_prefix, proc->res_type, + 1); + pvname(proc->proc_name, vp->vers_num); + f_print(fout, "_res;\n"); + } + f_print(fout, "\t} %s;\n", RESULT); + f_print(fout, "\tbool_t retval;\n"); + } else + f_print(fout, "\tchar *%s;\n", RESULT); + + f_print(fout, "\txdrproc_t xdr_%s, xdr_%s;\n", ARG, RESULT); + if (Mflag) + f_print(fout, + "\tbool_t (*%s)(char *, void *, struct svc_req *);\n", + ROUTINE); + else + f_print(fout, + "\tchar *(*%s)(char *, struct svc_req *);\n", + ROUTINE); + + f_print(fout, "\n"); + + if (callerflag) + f_print(fout, "\tcaller = transp;\n"); /* EVAS */ + 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, 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 (Mflag) + f_print(fout, + "\t\t%s = (bool_t (*)(char *, void *, struct svc_req *))", + ROUTINE); + else + f_print(fout, + "\t\t%s = (char *(*)(char *, struct svc_req *))", + ROUTINE); + + if (newstyle) /* new style: calls internal routine */ + f_print(fout, "_"); + pvname_svc(proc->proc_name, vp->vers_num); + 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(&%s, 0, sizeof(%s));\n", ARG, ARG); + printif("getargs", TRANSP, "(caddr_t)&", ARG); + printerr("decode", TRANSP); + print_return("\t\t"); + f_print(fout, "\t}\n"); + + if (Mflag) + f_print(fout, "\tretval = (*%s)((char *)&%s, (void *)&%s, %s);\n", + ROUTINE, ARG, RESULT, RQSTP); + else + f_print(fout, "\t%s = (*%s)((char *)&%s, %s);\n", + RESULT, ROUTINE, ARG, RQSTP); + if (Mflag) + f_print(fout, + "\tif (retval > 0 && !svc_sendreply(%s, xdr_%s, (char *)&%s)) {\n", + TRANSP, RESULT, RESULT); + else + f_print(fout, + "\tif (%s != NULL && !svc_sendreply(%s, xdr_%s, %s)) {\n", + RESULT, TRANSP, RESULT, RESULT); + printerr("systemerr", TRANSP); + f_print(fout, "\t}\n"); + + printif("freeargs", TRANSP, "(caddr_t)&", 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"); + + if (Mflag) { + f_print(fout, "\tif (!"); + pvname(def->def_name, vp->vers_num); + f_print(fout, "_freeresult"); + f_print(fout, "(%s, xdr_%s, (caddr_t)&%s)) {\n", + TRANSP, RESULT, RESULT); + (void) sprintf(_errbuf, "unable to free results"); + 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(const char *err, const char *transp) +{ + f_print(fout, "\t\tsvcerr_%s(%s);\n", err, transp); +} + +static void +printif(const char *proc, const char *transp, const char *prefix, const char *arg) +{ + f_print(fout, "\tif (!svc_%s(%s, xdr_%s, %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, "\tSVCXPRT *%s = NULL;\n", TRANSP); + f_print(fout, "\tint sock;\n"); + f_print(fout, "\tint proto = 0;\n"); + f_print(fout, "\tstruct sockaddr_in saddr;\n"); + f_print(fout, "\tsocklen_t asize = (socklen_t)sizeof(saddr);\n"); + f_print(fout, "\n"); + f_print(fout, + "\tif (getsockname(0, (struct sockaddr *)&saddr, &asize) == 0) {\n"); + f_print(fout, "\t\tsocklen_t ssize = (socklen_t)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(void *)&_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(const 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(const 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(const 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(); + if (callerflag) /* EVAS */ + write_caller_func(); /* EVAS */ +} +/* + * Write the _msgout function + */ +void +write_msg_out(void) +{ + f_print(fout, "\n"); + f_print(fout, "static\n"); + f_print(fout, "void _msgout(const 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 closedown(void);\n"); + f_print(fout, "\n"); + f_print(fout, "static void\n"); + f_print(fout, "closedown(void)\n"); + f_print(fout, "{\n"); + f_print(fout, "\tif (_rpcsvcdirty == 0) {\n"); + f_print(fout, "\t\textern fd_set svc_fdset;\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\tif (getrlimit(RLIMIT_NOFILE, &rl) == -1)\n"); + f_print(fout, "\t\t\t\treturn;\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 <= (_rpcpmstart?0: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"); +} + +static void +write_caller_func(void) +{ /* EVAS */ +#define P(s) f_print(fout, s); + + P("\n"); + P("char *svc_caller()\n"); + P("{\n"); + P(" struct sockaddr_in actual;\n"); + P(" struct hostent *hp;\n"); + P(" static struct in_addr prev;\n"); + P(" static char cname[128];\n\n"); + + P(" actual = *svc_getcaller(caller);\n\n"); + + P(" if (memcmp((char *)&actual.sin_addr, (char *)&prev,\n"); + P(" sizeof(struct in_addr)) == 0)\n"); + P(" return (cname);\n\n"); + + P(" prev = actual.sin_addr;\n\n"); + + P(" hp = gethostbyaddr((char *)&actual.sin_addr, sizeof(actual.sin_addr), AF_INET);\n"); + P(" if (hp == NULL) { /* dummy one up */\n"); + P(" extern char *inet_ntoa();\n"); + P(" strlcpy(cname, inet_ntoa(actual.sin_addr), sizeof(cname));\n"); + P(" } else {\n"); + P(" strlcpy(cname, hp->h_name, sizeof(cname));\n"); + P(" }\n\n"); + + P(" return (cname);\n"); + P("}\n"); + +#undef P +} +/* + * 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, (SIGPF)closedown);\n"); + 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, const 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\terr(EXIT_FAILURE, \"cannot fork\");\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, "%sif (getrlimit(RLIMIT_NOFILE, &rl) == -1)\n", sp); + f_print(fout, "%s\terr(EXIT_FAILURE, \"getrlimit(RLIMIT_NOFILE)\");\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, 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, const char *sp) +{ + char *s, *p; + + s = strrchr(infile, '.'); + if (s) + *s = '\0'; + p = strrchr(infile, '/'); + if (p) + p++; + else + p = infile; + f_print(fout, "%sopenlog(\"%s\", LOG_PID, LOG_DAEMON);\n", sp, p); + if (s) + *s = '.'; +} + +/* + * write a registration for the given transport for Inetd + */ +void +write_inetd_register(const char *transp) +{ + list *l; + definition *def; + version_list *vp; + const 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"); + } + if (inetdflag && streq(transp, "tcp")) { + f_print(fout, "%s\tif (_rpcpmstart)\n", sp); + + f_print(fout, "%s\t\t%s = svc%s_create(%s", + sp, TRANSP, "fd", inetdflag ? "sock" : "RPC_ANYSOCK"); + if (!isudp) + f_print(fout, ", 0, 0"); + f_print(fout, ");\n"); + + f_print(fout, "%s\telse\n", sp); + + f_print(fout, "%s\t\t%s = svc%s_create(%s", + sp, TRANSP, transp, inetdflag ? "sock" : "RPC_ANYSOCK"); + if (!isudp) + f_print(fout, ", 0, 0"); + f_print(fout, ");\n"); + + } else { + 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"); +} + +static const char * +aster(const char *type) +{ + if (isvectordef(type, REL_ALIAS)) { + return (""); + } else { + return ("*"); + } +} diff --git a/buildrump.sh/src/usr.bin/rpcgen/rpc_tblout.c b/buildrump.sh/src/usr.bin/rpcgen/rpc_tblout.c new file mode 100644 index 00000000..7726f6fe --- /dev/null +++ b/buildrump.sh/src/usr.bin/rpcgen/rpc_tblout.c @@ -0,0 +1,181 @@ +/* $NetBSD: rpc_tblout.c,v 1.14 2013/12/15 00:40:17 christos Exp $ */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user or with the express written consent of + * Sun Microsystems, Inc. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if HAVE_NBTOOL_CONFIG_H +#include "nbtool_config.h" +#endif + +#include <sys/cdefs.h> +#if defined(__RCSID) && !defined(lint) +#if 0 +static char sccsid[] = "@(#)rpc_tblout.c 1.4 89/02/22 (C) 1988 SMI"; +#else +__RCSID("$NetBSD: rpc_tblout.c,v 1.14 2013/12/15 00:40:17 christos Exp $"); +#endif +#endif + +/* + * rpc_tblout.c, Dispatch table outputter for the RPC protocol compiler + */ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include "rpc_scan.h" +#include "rpc_parse.h" +#include "rpc_util.h" + +#define TABSIZE 8 +#define TABCOUNT 5 +#define TABSTOP (TABSIZE*TABCOUNT) + +static char tabstr[TABCOUNT + 1] = "\t\t\t\t\t"; + +static const char tbl_hdr[] = "struct rpcgen_table %s_table[] = {\n"; +static const char tbl_end[] = "};\n"; + +static const char null_entry[] = "\t(char *(*)())0,\n\ + \t(xdrproc_t)xdr_void,\t\t0,\n\ + \t(xdrproc_t)xdr_void,\t\t0,\n"; + +static const char tbl_nproc[] = + "u_int %s_nproc =\n\t(u_int)(sizeof(%s_table)/sizeof(%s_table[0]));\n\n"; + +static void write_table(definition *); +static void printit(const char *, const char *); + +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) { + if (expected != 0) + f_print(fout, "\n"); + current = atoi(proc->proc_num); + if (current != expected++) { + f_print(fout, + "/*\n * WARNING: table out of order\n */\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, "\t(char *(*)())RPCGEN_ACTION("); + + /* routine to invoke */ + if (!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(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(const char *prefix, const 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, "(u_int)sizeof("); + /* XXX: should "follow" be 1 ??? */ + ptype(prefix, type, 0); + f_print(fout, ")"); + } + f_print(fout, ",\n"); +} diff --git a/buildrump.sh/src/usr.bin/rpcgen/rpc_util.c b/buildrump.sh/src/usr.bin/rpcgen/rpc_util.c new file mode 100644 index 00000000..4ef77397 --- /dev/null +++ b/buildrump.sh/src/usr.bin/rpcgen/rpc_util.c @@ -0,0 +1,479 @@ +/* $NetBSD: rpc_util.c,v 1.17 2015/05/09 23:28:43 dholland Exp $ */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user or with the express written consent of + * Sun Microsystems, Inc. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if HAVE_NBTOOL_CONFIG_H +#include "nbtool_config.h" +#endif + +#include <sys/cdefs.h> +#if defined(__RCSID) && !defined(lint) +#if 0 +static char sccsid[] = "@(#)rpc_util.c 1.11 89/02/22 (C) 1987 SMI"; +#else +__RCSID("$NetBSD: rpc_util.c,v 1.17 2015/05/09 23:28:43 dholland Exp $"); +#endif +#endif + +/* + * rpc_util.c, Utility routines for the RPC protocol compiler + */ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <err.h> +#include <ctype.h> +#include "rpc_scan.h" +#include "rpc_parse.h" +#include "rpc_util.h" + +#define ARGEXT "argument" + +static void printwhere(void); + +char curline[MAXLINESIZE]; /* current read line */ +char *where = curline; /* current point in line */ +int linenum = 0; /* current line number */ + +const char *infilename; /* input filename */ + +#define NFILES 7 +static const 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 */ + +static const char *toktostr(tok_kind); +static void printbuf(void); +static void printwhere(void); +static int findit(definition *, const char *); +static const char *fixit(const char *, const char *); +static int typedefed(definition *, const char *); + +/* + * Reinitialize the world + */ +void +reinitialize(void) +{ + memset(curline, 0, MAXLINESIZE); + where = curline; + linenum = 0; + defined = NULL; +} +/* + * string equality + */ +int +streq(const char *a, const char *b) +{ + return (strcmp(a, b) == 0); +} +/* + * find a value in a list + */ +definition * +findval(list *lst, const char *val, int (*cmp)(definition *, const 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(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, const char *type) +{ + return (streq(def->def_name, type)); +} + +static const char * +fixit(const char *type, const 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); + } +} + +const char * +fixtype(const char *type) +{ + return (fixit(type, type)); +} + +const char * +stringfix(const char *type) +{ + if (streq(type, "string")) { + return ("wrapstring"); + } else { + return (type); + } +} + +void +ptype(const char *prefix, const 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, const 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(const 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(const 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(const char *pname, const char *vnum) +{ + f_print(fout, "%s_%s_svc", locase(pname), vnum); +} + +void +pvname(const char *pname, const char *vnum) +{ + f_print(fout, "%s_%s", locase(pname), vnum); +} +/* + * print a useful (?) error message, and then die + */ +__printflike(1, 2) void +error(const char *msg, ...) +{ + va_list ap; + + printwhere(); + fprintf(stderr, "%s:%d: ", infilename, linenum); + va_start(ap, msg); + vfprintf(stderr, msg, ap); + va_end(ap); + fprintf(stderr, "\n"); + errx(EXIT_FAILURE, "Cannot recover from this error"); +} +/* + * Something went wrong, unlink any files that we may have created and then + * die. + */ +void +crash(void) +{ + int i; + + if (!docleanup) + return; + + for (i = 0; i < nfiles; i++) { + (void) unlink(outfiles[i]); + } +} + +void +record_open(const char *file) +{ + if (nfiles < NFILES) { + outfiles[nfiles++] = file; + } else { + errx(EXIT_FAILURE, "Too many files!"); + } +} + +/* + * error, token encountered was not the expected one + */ +void +expected1(tok_kind exp1) +{ + error("Expected '%s'", toktostr(exp1)); +} +/* + * error, token encountered was not one of two expected ones + */ +void +expected2(tok_kind exp1, tok_kind exp2) +{ + error("Expected '%s' or '%s'", + toktostr(exp1), + toktostr(exp2)); +} +/* + * error, token encountered was not one of 3 expected ones + */ +void +expected3(tok_kind exp1, tok_kind exp2, tok_kind exp3) +{ + error("Expected '%s', '%s', or '%s'", + toktostr(exp1), + toktostr(exp2), + toktostr(exp3)); +} + +void +tabify(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_LONG, "long"}, + {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 const char * +toktostr(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(const char *pname, const char *vname) +{ + char *name; + size_t len; + + len = strlen(pname) + strlen(vname) + strlen(ARGEXT) + 3; + name = malloc(len); + if (!name) { + errx(EXIT_FAILURE, "Out of memory"); + } + snprintf(name, len, "%s_%s_%s", locase(pname), vname, ARGEXT); + return (name); +} + +bas_type *typ_list_h; +bas_type *typ_list_t; + +void +add_type(int len, const char *type) +{ + bas_type *ptr; + + if ((ptr = malloc(sizeof(bas_type))) == NULL) { + errx(EXIT_FAILURE, "Out of memory"); + } + 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(const 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/buildrump.sh/src/usr.bin/rpcgen/rpc_util.h b/buildrump.sh/src/usr.bin/rpcgen/rpc_util.h new file mode 100644 index 00000000..45c3e14f --- /dev/null +++ b/buildrump.sh/src/usr.bin/rpcgen/rpc_util.h @@ -0,0 +1,178 @@ +/* $NetBSD: rpc_util.h,v 1.12 2015/05/13 20:13:21 joerg Exp $ */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user or with the express written consent of + * Sun Microsystems, Inc. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* @(#)rpc_util.h 1.5 90/08/29 (C) 1987 SMI */ + +/* + * rpc_util.h, Useful definitions for the RPC protocol compiler + */ + +#define alloc(size) ((char *)malloc((size_t)(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 int docleanup; + +extern const 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 BSDflag; +extern int logflag; +extern int newstyle; +extern int Mflag; /* multithread flag */ +extern int tirpcflag; /* flag for generating tirpc code */ +extern int doinline; /* if this is 0, then do not generate inline code */ +extern int callerflag; + +/* + * Other flags related with inetd jumpstart. + */ +extern int indefinitewait; +extern int exitnow; +extern int timerflag; + +extern int nonfatalerrors; + +/* + * rpc_util routines + */ + +#define STOREVAL(list,item) \ + storeval(list,item) + +#define FINDVAL(list,item,finder) \ + findval(list, item, finder) + +void reinitialize(void); +int streq(const char *, const char *); +definition *findval(list *, const char *, + int (*)(definition *, const char *)); +void storeval(list **, definition *); +const char *fixtype(const char *); +const char *stringfix(const char *); +void ptype(const char *, const char *, int); +int isvectordef(const char *, relation); +char *locase(const char *); +void pvname_svc(const char *, const char *); +void pvname(const char *, const char *); +__dead __printflike(1, 2) void error(const char *, ...); +void crash(void); +void record_open(const char *); +void expected1(tok_kind) __dead; +void expected2(tok_kind, tok_kind) __dead; +void expected3(tok_kind, tok_kind, tok_kind) __dead; +void tabify(FILE *, int); +char *make_argname(const char *, const char *); +void add_type(int, const char *); +bas_type *find_type(const char *); +/* + * rpc_cout routines + */ +void emit(definition *); +void emit_inline(declaration *, int); +void emit_single_in_line(declaration *, int, relation); +char *upcase(const char *); + +/* + * rpc_hout routines + */ + +void print_datadef(definition *); +void print_progdef(definition *); +void print_funcdef(definition *, int *); +void print_funcend(int); +void pxdrfuncdecl(const char *, int); +void pprocdef(proc_list *, version_list *, const char *, int); +void pdeclaration(const char *, declaration *, int, const char *); + +/* + * rpc_svcout routines + */ +void write_most(char *, int, int); +void write_netid_register(const char *); +void write_nettype_register(const char *); +void write_rest(void); +void write_programs(const char *); +int nullproc(proc_list *); +void write_svc_aux(int); +void write_msg_out(void); +void write_inetd_register(const char *); + +/* + * rpc_clntout routines + */ +void write_stubs(void); +void printarglist(proc_list *, const char *, const char *, const char *); + + +/* + * rpc_tblout routines + */ +void write_tables(void); + +/* + * rpc_sample routines + */ +void write_sample_svc(definition *); +int write_sample_clnt(definition *); +void add_sample_msg(void); +void write_sample_clnt_main(void); diff --git a/buildrump.sh/src/usr.bin/rpcgen/rpcgen.1 b/buildrump.sh/src/usr.bin/rpcgen/rpcgen.1 new file mode 100644 index 00000000..d4e91d0d --- /dev/null +++ b/buildrump.sh/src/usr.bin/rpcgen/rpcgen.1 @@ -0,0 +1,501 @@ +.\" $NetBSD: rpcgen.1,v 1.24 2013/12/15 09:18:14 wiz Exp $ +.\" from: @(#)rpcgen.new.1 1.1 90/11/09 TIRPC 1.0; from 40.10 of 10/10/89 +.\" Copyright (c) 1988,1990 Sun Microsystems, Inc. - All Rights Reserved. +.Dd December 14, 2013 +.Dt RPCGEN 1 +.Os +.Sh NAME +.Nm rpcgen +.Nd Remote Procedure Call (RPC) protocol compiler +.Sh SYNOPSIS +.Nm +.Ar infile +.Nm +.Op Fl AaBbILMNTv +.Op Fl D Ar name Op =value +.Op Fl i Ar size +.Op Fl K Ar secs +.Op Fl Y Ar pathname +.Ar infile +.Nm +.Fl c Li | +.Fl h Li | +.Fl l Li | +.Fl m Li | +.Fl t Li | +.Fl S\&c Li | +.Fl S\&s +.\" .Fl S\&m +.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 DESCRIPTION +.Nm +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). +.Nm +is normally used as in the first synopsis where +it takes an input file and generates up to four output files. +If the +.Ar infile +is named +.Pa proto.x , +then +.Nm +will generate a header file in +.Pa proto.h , +.Tn 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 will also generate the +.Tn RPC +dispatch table in +.Pa proto_tbl.i . +With the +.Fl S\&c +option, +it will also generate sample code which would illustrate how to use the +remote procedures on the client side. +This code would be created in +.Pa proto_client.c . +With the +.Fl S\&s +option, +it will also generate a sample server code which would illustrate how to write +the remote procedures. +This code would be created in +.Pa proto_server.c . +.Pp +The server created can be started both by the port monitors +(for example, +.Em inetd +or +.Em listen ) +or by itself. +When it is started by a port monitor, +it creates servers only for the transport for which +the file descriptor 0 was passed. +The name of the transport must be specified +by setting up the environmental 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. +.Pp +.Em 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 +.Dv 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 +.Li #defines +and +.Tn RPC +dispatch tables. +The entries in the +.Tn RPC +dispatch table contain: +.Pp +.Bl -inset -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 +.Pp +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 +.Tn 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. +Some examples of their usage is described in the +.Sx EXAMPLES +section below. +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 +.Em netid . +If +.Ar infile +is not specified, +.Nm +accepts the standard input. +.Pp +The C preprocessor, +.Xr cpp 1 +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 RPC_CLNT +.It Dv RPC_HDR +defined when compiling into header files +.It Dv RPC_XDR +defined when compiling into +.Tn XDR +routines +.It Dv RPC_SVC +defined when compiling into server-side stubs +.It Dv RPC_CLNT +defined when compiling into client-side stubs +.It Dv RPC_TBL +defined when compiling into +.Tn RPC +dispatch tables +.El +.Pp +Any line beginning with +.Sq % +is passed directly into the output file, +uninterpreted by +.Nm . +.Pp +For every data type referred to in +.Ar infile +.Nm +assumes that there exists a +routine with the string +.Dq 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 +.Tn XDR +routines. +.Sh OPTIONS +.Bl -tag -width indent +.It Fl A +Generate an +.Fn svc_caller +function. +.It Fl a +Generate all the files including sample code for client and server side. +.It Fl B +Generate BSD cplusplus macros (__BEGIN_DECLS, __END_DECLS). +.It Fl b +Compile stubs in "backwards compatible" mode, disabling support for +transport-independent RPC. +The +.Fl b +should always be specified when generating files for +.Nx , +since there is no transport-independent RPC support in +.Nx . +.It Fl c +Compile into +.Tn XDR +routines. +.It Fl D Ar name Ns Op Ar =value +Define a symbol +.Dv name . +Equivalent to the +.Dv #define +directive in the source. +If no +.Dv value +is given, +.Dv value +is defined as 1. +This option may be specified more than once. +.It Fl h +Compile into C data-definitions (a header file). +The +.Fl T +option can be used in conjunction to produce a +header file which supports +.Tn RPC +dispatch tables. +.It Fl I +Support +.Xr inetd 8 +in the server side stubs. +Servers generated using this flag can either be standalone or +started from +.Xr inetd 8 . +If a server is started as standalone, then it places itself +in the background, unless +.Dv RCP_SVC_FG +is defined, or the server is compiled without +.Fl I . +.It Fl i Ar size +Size to decide when to start generating inline code. +The default size is 3. +.It Fl K Ar secs +By default, services created using +.Nm +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, +.Dq Fl K No 0 +can be used. +To create a server that never exits, the appropriate argument is +.Dq Fl K No -1 . +.Pp +When monitoring for a server, +some port monitors, like the +.At V.4 +utility +.Ic listen , +.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 +.Dq Fl K No -1 . +.It Fl L +Server errors will be sent to syslog instead of stderr. +.It Fl l +Compile into client-side stubs. +.Xr inetd 8 . +.It Fl M +Generate thread-safe stubs. +This alters the calling pattern of client and +server stubs so that storage for results is allocated by the caller. +Note +that all components for a particular service (stubs, client and service +wrappers, etc.) must be built either with or without the +.Fl M +flag. +.It Fl m +Compile into server-side stubs, +but do not generate a +.Fn main +routine. +This option is useful for doing callback-routines +and for users who need to write their own +.Fn main +routine to do initialization. +.It Fl N +Use the newstyle of +.Nm . +This 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 the argument itself. +This behaviour is different from the oldstyle +of +.Nm +generated code. +The newstyle is not the default case because of backward compatibility. +.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 +.Po +.Fl c Fl h Fl l +.Fl m Fl n Fl s +modes only +.Pc +.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. +.Em Note : +.Bx +currently supports only the +.Em tcp +and +.Em udp +classes]. +This option may be specified more than once. +.Em Note : +the transports are chosen at run time and not at compile time. +.It Fl S\&c +Generate sample code to show the use of remote procedure and how to bind +to the server before calling the client side stubs generated by +.Nm . +.It Fl S\&s +Generate skeleton code for the remote procedures on the server side. +You would need +to fill in the actual code for the remote procedures. +.\" .It Fl S\&m +.\" Generate a sample Makefile that can be used to compile the application. +.It Fl T +Generate the code to support +.Tn RPC +dispatch tables. +.It Fl t +Compile into +.Tn RPC +dispatch table. +.It Fl v +Display the version number. +.It Fl Y Ar pathname +Specify the directory where +.Nm +looks for the C pre-processor. +.El +.Pp +The options +.Fl c , +.Fl h , +.Fl l , +.Fl m , +.Fl s , +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. +.Sh ENVIRONMENT +If the +.Ev RPCGEN_CPP +environment variable is set, its value is used as the pathname of the +C preprocessor to be run on the input file. +.Sh NOTES +The +.Tn RPC +Language does not support nesting of structures. +As a work-around, +structures can be declared at the top-level, +and their name used inside other structures in +order to achieve the same effect. +.Pp +Name clashes can occur when using program definitions, +since the apparent scoping does not really apply. +Most of these can be avoided by giving +unique names for programs, +versions, +procedures and types. +.Pp +The server code generated with +.Fl n +option refers to the transport indicated by +.Em netid +and hence is very site specific. +.Sh EXAMPLES +The command +.Pp +.Bd -literal -offset indent +$ rpcgen -T prot.x +.Ed +.Pp +generates 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 file) +to standard output. +.Pp +.Bd -literal -offset indent +$ rpcgen -h prot.x +.Ed +.Pp +To send the test version of the +.Dv -DTEST , +server side stubs for +all the transport belonging to the class +.Em datagram_n +to standard output, use: +.Pp +.Bd -literal -offset indent +$ rpcgen -s datagram_n -DTEST prot.x +.Ed +.Pp +To create the server side stubs for the transport indicated by +.Em netid +.Em tcp , +use: +.Pp +.Bd -literal -offset indent +$ rpcgen -n tcp -o prot_svc.c prot.x +.Ed +.Sh SEE ALSO +.Xr cpp 1 , +.Xr inetd 8 +.Sh HISTORY +The +.Fl M +option was first implemented in RedHat Linux, and was reimplemented by +Charles M. Hannum in +.Nx 1.6 . |