diff options
author | wollman <wollman@FreeBSD.org> | 1994-08-07 18:01:39 +0000 |
---|---|---|
committer | wollman <wollman@FreeBSD.org> | 1994-08-07 18:01:39 +0000 |
commit | 2698777ee390d989343d1f90a2bdbe7c248741c2 (patch) | |
tree | 7349fd6e301b184356b655f800a02a507d28008e /usr.bin/rpcgen | |
parent | 5f96899afd71cd76db4e154abb60bdfa6bd25637 (diff) | |
download | FreeBSD-src-2698777ee390d989343d1f90a2bdbe7c248741c2.zip FreeBSD-src-2698777ee390d989343d1f90a2bdbe7c248741c2.tar.gz |
Move RPC stub generator program over from 1.1.5.
Submitted by: Original work in 1.x by J. T. Conklin.
Diffstat (limited to 'usr.bin/rpcgen')
-rw-r--r-- | usr.bin/rpcgen/Makefile | 7 | ||||
-rw-r--r-- | usr.bin/rpcgen/rpc_clntout.c | 130 | ||||
-rw-r--r-- | usr.bin/rpcgen/rpc_cout.c | 355 | ||||
-rw-r--r-- | usr.bin/rpcgen/rpc_hout.c | 374 | ||||
-rw-r--r-- | usr.bin/rpcgen/rpc_main.c | 438 | ||||
-rw-r--r-- | usr.bin/rpcgen/rpc_parse.c | 423 | ||||
-rw-r--r-- | usr.bin/rpcgen/rpc_parse.h | 159 | ||||
-rw-r--r-- | usr.bin/rpcgen/rpc_scan.c | 476 | ||||
-rw-r--r-- | usr.bin/rpcgen/rpc_scan.h | 103 | ||||
-rw-r--r-- | usr.bin/rpcgen/rpc_svcout.c | 276 | ||||
-rw-r--r-- | usr.bin/rpcgen/rpc_util.c | 439 | ||||
-rw-r--r-- | usr.bin/rpcgen/rpc_util.h | 113 | ||||
-rw-r--r-- | usr.bin/rpcgen/rpcgen.1 | 156 |
13 files changed, 3449 insertions, 0 deletions
diff --git a/usr.bin/rpcgen/Makefile b/usr.bin/rpcgen/Makefile new file mode 100644 index 0000000..fefab49 --- /dev/null +++ b/usr.bin/rpcgen/Makefile @@ -0,0 +1,7 @@ +# $Id: Makefile,v 1.1 1993/09/13 23:20:11 jtc 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 + +.include <bsd.prog.mk> diff --git a/usr.bin/rpcgen/rpc_clntout.c b/usr.bin/rpcgen/rpc_clntout.c new file mode 100644 index 0000000..73cb97d --- /dev/null +++ b/usr.bin/rpcgen/rpc_clntout.c @@ -0,0 +1,130 @@ +/* @(#)rpc_clntout.c 2.1 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#ifndef lint +/*static char sccsid[] = "from: @(#)rpc_clntout.c 1.2 87/06/24 (C) 1987 SMI";*/ +static char rcsid[] = "$Id: rpc_clntout.c,v 1.1 1993/09/13 23:20:12 jtc Exp $"; +#endif + +/* + * rpc_clntout.c, Client-stub outputter for the RPC protocol compiler + * Copyright (C) 1987, Sun Microsytsems, Inc. + */ +#include <stdio.h> +#include <strings.h> +#include "rpc_parse.h" +#include "rpc_util.h" + +#define DEFAULT_TIMEOUT 25 /* in seconds */ + +static int write_program(), printbody(); + + +void +write_stubs() +{ + 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 +write_program(def) + definition *def; +{ + version_list *vp; + proc_list *proc; + + for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { + for (proc = vp->procs; proc != NULL; proc = proc->next) { + f_print(fout, "\n"); + ptype(proc->res_prefix, proc->res_type, 1); + f_print(fout, "*\n"); + pvname(proc->proc_name, vp->vers_num); + f_print(fout, "(argp, clnt)\n"); + f_print(fout, "\t"); + ptype(proc->arg_prefix, proc->arg_type, 1); + f_print(fout, "*argp;\n"); + f_print(fout, "\tCLIENT *clnt;\n"); + f_print(fout, "{\n"); + printbody(proc); + f_print(fout, "}\n\n"); + } + } +} + +static char * +ampr(type) + char *type; +{ + if (isvectordef(type, REL_ALIAS)) { + return (""); + } else { + return ("&"); + } +} + +static +printbody(proc) + proc_list *proc; +{ + 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, "res;\n"); + f_print(fout, "\n"); + f_print(fout, "\tbzero((char *)%sres, sizeof(res));\n", + ampr(proc->res_type)); + f_print(fout, + "\tif (clnt_call(clnt, %s, xdr_%s, argp, xdr_%s, %sres, TIMEOUT) != RPC_SUCCESS) {\n", + proc->proc_name, stringfix(proc->arg_type), + stringfix(proc->res_type), ampr(proc->res_type)); + f_print(fout, "\t\treturn (NULL);\n"); + f_print(fout, "\t}\n"); + if (streq(proc->res_type, "void")) { + f_print(fout, "\treturn ((void *)%sres);\n", + ampr(proc->res_type)); + } else { + f_print(fout, "\treturn (%sres);\n", ampr(proc->res_type)); + } +} diff --git a/usr.bin/rpcgen/rpc_cout.c b/usr.bin/rpcgen/rpc_cout.c new file mode 100644 index 0000000..9e2e361 --- /dev/null +++ b/usr.bin/rpcgen/rpc_cout.c @@ -0,0 +1,355 @@ +/* @(#)rpc_cout.c 2.1 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#ifndef lint +/*static char sccsid[] = "from: @(#)rpc_cout.c 1.8 87/06/24 (C) 1987 SMI";*/ +static char rcsid[] = "$Id: rpc_cout.c,v 1.1 1993/09/13 23:20:13 jtc Exp $"; +#endif + +/* + * rpc_cout.c, XDR routine outputter for the RPC protocol compiler + * Copyright (C) 1987, Sun Microsystems, Inc. + */ +#include <stdio.h> +#include <strings.h> +#include "rpc_util.h" +#include "rpc_parse.h" + +static int print_header(), print_trailer(), space(), emit_enum(), + emit_union(), emit_struct(), emit_typedef(), print_stat(); + + +/* + * Emit the C-routine for the given definition + */ +void +emit(def) + definition *def; +{ + if (def->def_kind == DEF_PROGRAM || def->def_kind == DEF_CONST) { + 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; + } + print_trailer(); +} + +static +findtype(def, type) + definition *def; + char *type; +{ + if (def->def_kind == DEF_PROGRAM || def->def_kind == DEF_CONST) { + return (0); + } else { + return (streq(def->def_name, type)); + } +} + +static +undefined(type) + char *type; +{ + definition *def; + + def = (definition *) FINDVAL(defined, type, findtype); + return (def == NULL); +} + + +static +print_header(def) + definition *def; +{ + space(); + f_print(fout, "bool_t\n"); + f_print(fout, "xdr_%s(xdrs, objp)\n", def->def_name); + f_print(fout, "\tXDR *xdrs;\n"); + f_print(fout, "\t%s ", def->def_name); + if (def->def_kind != DEF_TYPEDEF || + !isvectordef(def->def.ty.old_type, def->def.ty.rel)) { + f_print(fout, "*"); + } + f_print(fout, "objp;\n"); + f_print(fout, "{\n"); +} + +static +print_trailer() +{ + f_print(fout, "\treturn (TRUE);\n"); + f_print(fout, "}\n"); + space(); +} + + +static +print_ifopen(indent, name) + int indent; + char *name; +{ + tabify(fout, indent); + f_print(fout, "if (!xdr_%s(xdrs", name); +} + + +static +print_ifarg(arg) + char *arg; +{ + f_print(fout, ", %s", arg); +} + + +static +print_ifsizeof(prefix, type) + char *prefix; + char *type; +{ + if (streq(type, "bool")) { + f_print(fout, ", sizeof(bool_t), xdr_bool"); + } else { + f_print(fout, ", sizeof("); + if (undefined(type) && prefix) { + f_print(fout, "%s ", prefix); + } + f_print(fout, "%s), xdr_%s", type, type); + } +} + +static +print_ifclose(indent) + int indent; +{ + f_print(fout, ")) {\n"); + tabify(fout, indent); + f_print(fout, "\treturn (FALSE);\n"); + tabify(fout, indent); + f_print(fout, "}\n"); +} + +static +space() +{ + f_print(fout, "\n\n"); +} + +static +print_ifstat(indent, prefix, type, rel, amax, objname, name) + int indent; + char *prefix; + char *type; + relation rel; + char *amax; + char *objname; + char *name; +{ + char *alt = NULL; + + switch (rel) { + case REL_POINTER: + print_ifopen(indent, "pointer"); + print_ifarg("(char **)"); + f_print(fout, "%s", objname); + print_ifsizeof(prefix, type); + break; + case REL_VECTOR: + if (streq(type, "string")) { + alt = "string"; + } else if (streq(type, "opaque")) { + alt = "opaque"; + } + if (alt) { + print_ifopen(indent, alt); + print_ifarg(objname); + } else { + print_ifopen(indent, "vector"); + print_ifarg("(char *)"); + f_print(fout, "%s", objname); + } + print_ifarg(amax); + if (!alt) { + print_ifsizeof(prefix, type); + } + break; + case REL_ARRAY: + if (streq(type, "string")) { + alt = "string"; + } else if (streq(type, "opaque")) { + alt = "bytes"; + } + if (streq(type, "string")) { + print_ifopen(indent, alt); + print_ifarg(objname); + } else { + if (alt) { + print_ifopen(indent, alt); + } else { + print_ifopen(indent, "array"); + } + print_ifarg("(char **)"); + 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 +emit_enum(def) + definition *def; +{ + print_ifopen(1, "enum"); + print_ifarg("(enum_t *)objp"); + print_ifclose(1); +} + + +static +emit_union(def) + definition *def; +{ + declaration *dflt; + case_list *cl; + declaration *cs; + char *object; + char *format = "&objp->%s_u.%s"; + + print_stat(&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) { + cs = &cl->case_decl; + f_print(fout, "\tcase %s:\n", cl->case_name); + if (!streq(cs->type, "void")) { + object = alloc(strlen(def->def_name) + strlen(format) + + strlen(cs->name) + 1); + s_print(object, format, def->def_name, cs->name); + print_ifstat(2, cs->prefix, cs->type, cs->rel, cs->array_max, + object, cs->name); + free(object); + } + f_print(fout, "\t\tbreak;\n"); + } + dflt = def->def.un.default_decl; + if (dflt != NULL) { + if (!streq(dflt->type, "void")) { + f_print(fout, "\tdefault:\n"); + object = alloc(strlen(def->def_name) + strlen(format) + + strlen(dflt->name) + 1); + 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, "\tdefault:\n"); + f_print(fout, "\t\treturn (FALSE);\n"); + } + f_print(fout, "\t}\n"); +} + + + +static +emit_struct(def) + definition *def; +{ + decl_list *dl; + + for (dl = def->def.st.decls; dl != NULL; dl = dl->next) { + print_stat(&dl->decl); + } +} + + + + +static +emit_typedef(def) + definition *def; +{ + char *prefix = def->def.ty.old_prefix; + char *type = def->def.ty.old_type; + char *amax = def->def.ty.array_max; + relation rel = def->def.ty.rel; + + print_ifstat(1, prefix, type, rel, amax, "objp", def->def_name); +} + + + + + +static +print_stat(dec) + declaration *dec; +{ + char *prefix = dec->prefix; + char *type = dec->type; + char *amax = dec->array_max; + relation rel = dec->rel; + char name[256]; + + if (isvectordef(type, rel)) { + s_print(name, "objp->%s", dec->name); + } else { + s_print(name, "&objp->%s", dec->name); + } + print_ifstat(1, prefix, type, rel, amax, name, dec->name); +} diff --git a/usr.bin/rpcgen/rpc_hout.c b/usr.bin/rpcgen/rpc_hout.c new file mode 100644 index 0000000..8ccd433 --- /dev/null +++ b/usr.bin/rpcgen/rpc_hout.c @@ -0,0 +1,374 @@ +/* @(#)rpc_hout.c 2.1 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#ifndef lint +/*static char sccsid[] = "from: @(#)rpc_hout.c 1.6 87/07/28 (C) 1987 SMI";*/ +static char rcsid[] = "$Id: rpc_hout.c,v 1.1 1993/09/13 23:20:14 jtc Exp $"; +#endif + +static int pconstdef(), pstructdef(), puniondef(), pdefine(), pprogramdef(), + penumdef(), ptypedef(), pdeclaration(), undefined2(); + +/* + * rpc_hout.c, Header file outputter for the RPC protocol compiler + * Copyright (C) 1987, Sun Microsystems, Inc. + */ +#include <stdio.h> +#include <ctype.h> +#include "rpc_util.h" +#include "rpc_parse.h" + + +/* + * Print the C-version of an xdr definition + */ +void +print_datadef(def) + definition *def; +{ + if (def->def_kind != DEF_CONST) { + f_print(fout, "\n"); + } + switch (def->def_kind) { + case DEF_STRUCT: + pstructdef(def); + break; + case DEF_UNION: + puniondef(def); + break; + case DEF_ENUM: + penumdef(def); + break; + case DEF_TYPEDEF: + ptypedef(def); + break; + case DEF_PROGRAM: + pprogramdef(def); + break; + case DEF_CONST: + pconstdef(def); + break; + } + if (def->def_kind != DEF_PROGRAM && def->def_kind != DEF_CONST) { + f_print(fout, "bool_t xdr_%s();\n", def->def_name); + } + if (def->def_kind != DEF_CONST) { + f_print(fout, "\n"); + } +} + +static +pconstdef(def) + definition *def; +{ + pdefine(def->def_name, def->def.co); +} + +static +pstructdef(def) + definition *def; +{ + decl_list *l; + char *name = def->def_name; + + f_print(fout, "struct %s {\n", name); + for (l = def->def.st.decls; l != NULL; l = l->next) { + pdeclaration(name, &l->decl, 1); + } + f_print(fout, "};\n"); + f_print(fout, "typedef struct %s %s;\n", name, name); +} + +static +puniondef(def) + definition *def; +{ + case_list *l; + char *name = def->def_name; + declaration *decl; + + f_print(fout, "struct %s {\n", name); + decl = &def->def.un.enum_decl; + if (streq(decl->type, "bool")) { + f_print(fout, "\tbool_t %s;\n", decl->name); + } else { + f_print(fout, "\t%s %s;\n", decl->type, decl->name); + } + f_print(fout, "\tunion {\n"); + for (l = def->def.un.cases; l != NULL; l = l->next) { + pdeclaration(name, &l->case_decl, 2); + } + decl = def->def.un.default_decl; + if (decl && !streq(decl->type, "void")) { + pdeclaration(name, decl, 2); + } + f_print(fout, "\t} %s_u;\n", name); + f_print(fout, "};\n"); + f_print(fout, "typedef struct %s %s;\n", name, name); +} + + + +static +pdefine(name, num) + char *name; + char *num; +{ + f_print(fout, "#define %s %s\n", name, num); +} + +static +puldefine(name, num) + char *name; + char *num; +{ + f_print(fout, "#define %s ((u_long)%s)\n", name, num); +} + +static +define_printed(stop, start) + proc_list *stop; + version_list *start; +{ + version_list *vers; + proc_list *proc; + + for (vers = start; vers != NULL; vers = vers->next) { + for (proc = vers->procs; proc != NULL; proc = proc->next) { + if (proc == stop) { + return (0); + } else if (streq(proc->proc_name, stop->proc_name)) { + return (1); + } + } + } + abort(); + /* NOTREACHED */ +} + + +static +pprogramdef(def) + definition *def; +{ + version_list *vers; + proc_list *proc; + + puldefine(def->def_name, def->def.pr.prog_num); + for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) { + 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); + } + pprocdef(proc, vers); + } + } +} + + +pprocdef(proc, vp) + proc_list *proc; + version_list *vp; +{ + f_print(fout, "extern "); + if (proc->res_prefix) { + if (streq(proc->res_prefix, "enum")) { + f_print(fout, "enum "); + } else { + f_print(fout, "struct "); + } + } + if (streq(proc->res_type, "bool")) { + f_print(fout, "bool_t *"); + } else if (streq(proc->res_type, "string")) { + f_print(fout, "char **"); + } else { + f_print(fout, "%s *", fixtype(proc->res_type)); + } + pvname(proc->proc_name, vp->vers_num); + f_print(fout, "();\n"); +} + +static +penumdef(def) + definition *def; +{ + char *name = def->def_name; + enumval_list *l; + char *last = NULL; + int count = 0; + + f_print(fout, "enum %s {\n", name); + for (l = def->def.en.vals; l != NULL; l = l->next) { + f_print(fout, "\t%s", l->name); + if (l->assignment) { + f_print(fout, " = %s", l->assignment); + last = l->assignment; + count = 1; + } else { + if (last == NULL) { + f_print(fout, " = %d", count++); + } else { + f_print(fout, " = %s + %d", last, count++); + } + } + f_print(fout, ",\n"); + } + f_print(fout, "};\n"); + f_print(fout, "typedef enum %s %s;\n", name, name); +} + +static +ptypedef(def) + definition *def; +{ + char *name = def->def_name; + char *old = def->def.ty.old_type; + char prefix[8]; /* enough to contain "struct ", including NUL */ + relation rel = def->def.ty.rel; + + + if (!streq(name, old)) { + if (streq(old, "string")) { + old = "char"; + rel = REL_POINTER; + } else if (streq(old, "opaque")) { + old = "char"; + } else if (streq(old, "bool")) { + old = "bool_t"; + } + if (undefined2(old, name) && def->def.ty.old_prefix) { + s_print(prefix, "%s ", def->def.ty.old_prefix); + } else { + prefix[0] = 0; + } + f_print(fout, "typedef "); + switch (rel) { + case REL_ARRAY: + f_print(fout, "struct {\n"); + f_print(fout, "\tu_int %s_len;\n", name); + f_print(fout, "\t%s%s *%s_val;\n", prefix, old, name); + f_print(fout, "} %s", name); + break; + case REL_POINTER: + f_print(fout, "%s%s *%s", prefix, old, name); + break; + case REL_VECTOR: + f_print(fout, "%s%s %s[%s]", prefix, old, name, + def->def.ty.array_max); + break; + case REL_ALIAS: + f_print(fout, "%s%s %s", prefix, old, name); + break; + } + f_print(fout, ";\n"); + } +} + + +static +pdeclaration(name, dec, tab) + char *name; + declaration *dec; + int tab; +{ + char buf[8]; /* enough to hold "struct ", include NUL */ + char *prefix; + char *type; + + if (streq(dec->type, "void")) { + return; + } + tabify(fout, tab); + if (streq(dec->type, name) && !dec->prefix) { + f_print(fout, "struct "); + } + if (streq(dec->type, "string")) { + f_print(fout, "char *%s", dec->name); + } else { + prefix = ""; + if (streq(dec->type, "bool")) { + type = "bool_t"; + } else if (streq(dec->type, "opaque")) { + type = "char"; + } else { + if (dec->prefix) { + s_print(buf, "%s ", dec->prefix); + prefix = buf; + } + type = dec->type; + } + switch (dec->rel) { + case REL_ALIAS: + f_print(fout, "%s%s %s", prefix, type, dec->name); + break; + case REL_VECTOR: + f_print(fout, "%s%s %s[%s]", prefix, type, dec->name, + dec->array_max); + break; + case REL_POINTER: + f_print(fout, "%s%s *%s", prefix, type, dec->name); + break; + case REL_ARRAY: + f_print(fout, "struct {\n"); + tabify(fout, tab); + f_print(fout, "\tu_int %s_len;\n", dec->name); + tabify(fout, tab); + f_print(fout, "\t%s%s *%s_val;\n", prefix, type, dec->name); + tabify(fout, tab); + f_print(fout, "} %s", dec->name); + break; + } + } + f_print(fout, ";\n"); +} + + + +static +undefined2(type, stop) + char *type; + char *stop; +{ + list *l; + definition *def; + + for (l = defined; l != NULL; l = l->next) { + def = (definition *) l->val; + if (def->def_kind != DEF_PROGRAM) { + if (streq(def->def_name, stop)) { + return (1); + } else if (streq(def->def_name, type)) { + return (0); + } + } + } + return (1); +} diff --git a/usr.bin/rpcgen/rpc_main.c b/usr.bin/rpcgen/rpc_main.c new file mode 100644 index 0000000..981c94d --- /dev/null +++ b/usr.bin/rpcgen/rpc_main.c @@ -0,0 +1,438 @@ +/* @(#)rpc_main.c 2.2 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#ifndef lint +/*static char sccsid[] = "from: @(#)rpc_main.c 1.7 87/06/24 (C) 1987 SMI";*/ +static char rcsid[] = "$Id: rpc_main.c,v 1.1 1993/09/13 23:20:15 jtc Exp $"; +#endif + +/* + * rpc_main.c, Top level of the RPC protocol compiler. + * Copyright (C) 1987, Sun Microsystems, Inc. + */ + +#include <stdio.h> +#include <strings.h> +#include <sys/file.h> +#include "rpc_util.h" +#include "rpc_parse.h" +#include "rpc_scan.h" + +#define EXTEND 1 /* alias for TRUE */ + +struct commandline { + int cflag; + int hflag; + int lflag; + int sflag; + int mflag; + char *infile; + char *outfile; +}; + +static char *cmdname; +static char CPP[] = "/usr/bin/cpp"; +static char CPPFLAGS[] = "-C"; +static char *allv[] = { + "rpcgen", "-s", "udp", "-s", "tcp", +}; +static int allc = sizeof(allv)/sizeof(allv[0]); + + +static int h_output(), c_output(), s_output(), l_output(), do_registers(), + parseargs(); + +main(argc, argv) + int argc; + char *argv[]; + +{ + struct commandline cmd; + + if (!parseargs(argc, argv, &cmd)) { + f_print(stderr, + "usage: %s infile\n", cmdname); + f_print(stderr, + " %s [-c | -h | -l | -m] [-o outfile] [infile]\n", + cmdname); + f_print(stderr, + " %s [-s udp|tcp]* [-o outfile] [infile]\n", + cmdname); + exit(1); + } + if (cmd.cflag) { + c_output(cmd.infile, "-DRPC_XDR", !EXTEND, cmd.outfile); + } else if (cmd.hflag) { + h_output(cmd.infile, "-DRPC_HDR", !EXTEND, cmd.outfile); + } else if (cmd.lflag) { + l_output(cmd.infile, "-DRPC_CLNT", !EXTEND, cmd.outfile); + } else if (cmd.sflag || cmd.mflag) { + s_output(argc, argv, cmd.infile, "-DRPC_SVC", !EXTEND, + cmd.outfile, cmd.mflag); + } else { + 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(); + s_output(allc, allv, cmd.infile, "-DRPC_SVC", EXTEND, + "_svc.c", cmd.mflag); + } + exit(0); +} + +/* + * add extension to filename + */ +static char * +extendfile(file, ext) + char *file; + char *ext; +{ + char *res; + char *p; + + res = alloc(strlen(file) + strlen(ext) + 1); + if (res == NULL) { + abort(); + } + p = rindex(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 +open_output(infile, outfile) + char *infile; + char *outfile; +{ + if (outfile == NULL) { + fout = stdout; + return; + } + if (infile != NULL && streq(outfile, infile)) { + f_print(stderr, "%s: output would overwrite %s\n", cmdname, + infile); + crash(); + } + fout = fopen(outfile, "w"); + if (fout == NULL) { + f_print(stderr, "%s: unable to open ", cmdname); + perror(outfile); + crash(); + } + record_open(outfile); +} + +/* + * Open input file with given define for C-preprocessor + */ +static +open_input(infile, define) + char *infile; + char *define; +{ + int pd[2]; + + infilename = (infile == NULL) ? "<stdin>" : infile; + (void) pipe(pd); + switch (fork()) { + case 0: + (void) close(1); + (void) dup2(pd[1], 1); + (void) close(pd[0]); + execl(CPP, CPP, CPPFLAGS, define, infile, NULL); + perror("execl"); + exit(1); + case -1: + perror("fork"); + exit(1); + } + (void) close(pd[1]); + fin = fdopen(pd[0], "r"); + if (fin == NULL) { + f_print(stderr, "%s: ", cmdname); + perror(infilename); + crash(); + } +} + +/* + * Compile into an XDR routine output file + */ +static +c_output(infile, define, extend, outfile) + char *infile; + char *define; + int extend; + char *outfile; +{ + definition *def; + char *include; + char *outfilename; + long tell; + + open_input(infile, define); + outfilename = extend ? extendfile(infile, outfile) : outfile; + open_output(infile, outfilename); + f_print(fout, "#include <rpc/rpc.h>\n"); + if (infile && (include = extendfile(infile, ".h"))) { + f_print(fout, "#include \"%s\"\n", include); + free(include); + } + tell = ftell(fout); + while (def = get_definition()) { + emit(def); + } + if (extend && tell == ftell(fout)) { + (void) unlink(outfilename); + } +} + +/* + * Compile into an XDR header file + */ +static +h_output(infile, define, extend, outfile) + char *infile; + char *define; + int extend; + char *outfile; +{ + definition *def; + char *outfilename; + long tell; + + open_input(infile, define); + outfilename = extend ? extendfile(infile, outfile) : outfile; + open_output(infile, outfilename); + tell = ftell(fout); + while (def = get_definition()) { + print_datadef(def); + } + if (extend && tell == ftell(fout)) { + (void) unlink(outfilename); + } +} + +/* + * Compile into an RPC service + */ +static +s_output(argc, argv, infile, define, extend, outfile, nomain) + int argc; + char *argv[]; + char *infile; + char *define; + int extend; + char *outfile; + int nomain; +{ + char *include; + definition *def; + int foundprogram; + char *outfilename; + + open_input(infile, define); + outfilename = extend ? extendfile(infile, outfile) : outfile; + open_output(infile, outfilename); + f_print(fout, "#include <stdio.h>\n"); + f_print(fout, "#include <rpc/rpc.h>\n"); + if (infile && (include = extendfile(infile, ".h"))) { + f_print(fout, "#include \"%s\"\n", include); + free(include); + } + foundprogram = 0; + while (def = get_definition()) { + foundprogram |= (def->def_kind == DEF_PROGRAM); + } + if (extend && !foundprogram) { + (void) unlink(outfilename); + return; + } + if (nomain) { + write_programs((char *)NULL); + } else { + write_most(); + do_registers(argc, argv); + write_rest(); + write_programs("static"); + } +} + +static +l_output(infile, define, extend, outfile) + char *infile; + char *define; + int extend; + char *outfile; +{ + char *include; + definition *def; + int foundprogram; + char *outfilename; + + open_input(infile, define); + outfilename = extend ? extendfile(infile, outfile) : outfile; + open_output(infile, outfilename); + f_print(fout, "#include <rpc/rpc.h>\n"); + if (infile && (include = extendfile(infile, ".h"))) { + f_print(fout, "#include \"%s\"\n", include); + free(include); + } + foundprogram = 0; + while (def = get_definition()) { + foundprogram |= (def->def_kind == DEF_PROGRAM); + } + if (extend && !foundprogram) { + (void) unlink(outfilename); + return; + } + write_stubs(); +} + +/* + * Perform registrations for service output + */ +static +do_registers(argc, argv) + int argc; + char *argv[]; + +{ + int i; + + for (i = 1; i < argc; i++) { + if (streq(argv[i], "-s")) { + write_register(argv[i + 1]); + i++; + } + } +} + +/* + * Parse command line arguments + */ +static +parseargs(argc, argv, cmd) + int argc; + char *argv[]; + struct commandline *cmd; + +{ + int i; + int j; + char c; + char flag[(1 << 8 * sizeof(char))]; + int nflags; + + cmdname = argv[0]; + cmd->infile = cmd->outfile = NULL; + if (argc < 2) { + return (0); + } + flag['c'] = 0; + flag['h'] = 0; + flag['s'] = 0; + flag['o'] = 0; + flag['l'] = 0; + flag['m'] = 0; + for (i = 1; i < argc; i++) { + if (argv[i][0] != '-') { + if (cmd->infile) { + return (0); + } + cmd->infile = argv[i]; + } else { + for (j = 1; argv[i][j] != 0; j++) { + c = argv[i][j]; + switch (c) { + case 'c': + case 'h': + case 'l': + case 'm': + if (flag[c]) { + return (0); + } + flag[c] = 1; + break; + 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; + + default: + return (0); + } + } + nextarg: + ; + } + } + cmd->cflag = flag['c']; + cmd->hflag = flag['h']; + cmd->sflag = flag['s']; + cmd->lflag = flag['l']; + cmd->mflag = flag['m']; + nflags = cmd->cflag + cmd->hflag + cmd->sflag + cmd->lflag + cmd->mflag; + if (nflags == 0) { + if (cmd->outfile != NULL || cmd->infile == NULL) { + return (0); + } + } else if (nflags > 1) { + return (0); + } + return (1); +} diff --git a/usr.bin/rpcgen/rpc_parse.c b/usr.bin/rpcgen/rpc_parse.c new file mode 100644 index 0000000..b780851 --- /dev/null +++ b/usr.bin/rpcgen/rpc_parse.c @@ -0,0 +1,423 @@ +/* @(#)rpc_parse.c 2.1 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#ifndef lint +/*static char sccsid[] = "from: @(#)rpc_parse.c 1.4 87/04/28 (C) 1987 SMI";*/ +static char rcsid[] = "$Id: rpc_parse.c,v 1.1 1993/09/13 23:20:16 jtc Exp $"; +#endif + +/* + * rpc_parse.c, Parser for the RPC protocol compiler + * Copyright (C) 1987 Sun Microsystems, Inc. + */ +#include <stdio.h> +#include "rpc_util.h" +#include "rpc_scan.h" +#include "rpc_parse.h" + +static int isdefined(), def_struct(), def_program(), def_enum(), def_const(), + def_union(), def_typedef(), get_declaration(), get_type(), + unsigned_dec(); +/* + * return the next definition you see + */ +definition * +get_definition() +{ + 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: + return (NULL); + break; + default: + error("definition keyword expected"); + } + scan(TOK_SEMICOLON, &tok); + isdefined(defp); + return (defp); +} + +static +isdefined(defp) + definition *defp; +{ + STOREVAL(&defined, defp); +} + + +static +def_struct(defp) + 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 +def_program(defp) + definition *defp; +{ + token tok; + version_list *vlist; + version_list **vtailp; + proc_list *plist; + proc_list **ptailp; + + defp->def_kind = DEF_PROGRAM; + scan(TOK_IDENT, &tok); + defp->def_name = tok.str; + scan(TOK_LBRACE, &tok); + vtailp = &defp->def.pr.versions; + 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 { + 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_type(&plist->arg_prefix, &plist->arg_type, DEF_PROGRAM); + if (streq(plist->arg_type, "opaque")) { + error("illegal argument type"); + } + scan(TOK_RPAREN, &tok); + scan(TOK_EQUAL, &tok); + scan_num(&tok); + scan(TOK_SEMICOLON, &tok); + plist->proc_num = tok.str; + *ptailp = plist; + ptailp = &plist->next; + peek(&tok); + } while (tok.kind != TOK_RBRACE); + *vtailp = vlist; + vtailp = &vlist->next; + scan(TOK_RBRACE, &tok); + scan(TOK_EQUAL, &tok); + scan_num(&tok); + vlist->vers_num = tok.str; + 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 +def_enum(defp) + 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 +def_const(defp) + 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 +def_union(defp) + 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) { + scan(TOK_IDENT, &tok); + cases = ALLOC(case_list); + cases->case_name = tok.str; + scan(TOK_COLON, &tok); + get_declaration(&dec, DEF_UNION); + cases->case_decl = dec; + *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 +def_typedef(defp) + definition *defp; +{ + declaration dec; + + defp->def_kind = DEF_TYPEDEF; + get_declaration(&dec, DEF_TYPEDEF); + defp->def_name = dec.name; + 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 +get_declaration(dec, dkind) + declaration *dec; + defkind dkind; +{ + token tok; + + get_type(&dec->prefix, &dec->type, dkind); + dec->rel = REL_ALIAS; + if (streq(dec->type, "void")) { + return; + } + scan2(TOK_STAR, TOK_IDENT, &tok); + if (tok.kind == TOK_STAR) { + dec->rel = REL_POINTER; + scan(TOK_IDENT, &tok); + } + dec->name = tok.str; + if (peekscan(TOK_LBRACKET, &tok)) { + if (dec->rel == REL_POINTER) { + error("no array-of-pointer declarations -- use typedef"); + } + dec->rel = REL_VECTOR; + scan_num(&tok); + dec->array_max = tok.str; + scan(TOK_RBRACKET, &tok); + } else if (peekscan(TOK_LANGLE, &tok)) { + if (dec->rel == REL_POINTER) { + error("no array-of-pointer declarations -- use typedef"); + } + dec->rel = REL_ARRAY; + if (peekscan(TOK_RANGLE, &tok)) { + dec->array_max = "~0"; /* unspecified size, use max */ + } else { + scan_num(&tok); + dec->array_max = tok.str; + scan(TOK_RANGLE, &tok); + } + } + if (streq(dec->type, "opaque")) { + if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR) { + error("array declaration expected"); + } + } else if (streq(dec->type, "string")) { + if (dec->rel != REL_ARRAY) { + error("variable-length array declaration expected"); + } + } +} + + +static +get_type(prefixp, typep, dkind) + char **prefixp; + char **typep; + defkind dkind; +{ + token tok; + + *prefixp = NULL; + get_token(&tok); + switch (tok.kind) { + case TOK_IDENT: + *typep = tok.str; + break; + case TOK_STRUCT: + case TOK_ENUM: + case TOK_UNION: + *prefixp = tok.str; + scan(TOK_IDENT, &tok); + *typep = tok.str; + break; + case TOK_UNSIGNED: + unsigned_dec(typep); + break; + case TOK_SHORT: + *typep = "short"; + (void) peekscan(TOK_INT, &tok); + break; + case TOK_LONG: + *typep = "long"; + (void) peekscan(TOK_INT, &tok); + break; + case TOK_VOID: + if (dkind != DEF_UNION && dkind != DEF_PROGRAM) { + error("voids allowed only inside union and program definitions"); + } + *typep = tok.str; + break; + case TOK_STRING: + case TOK_OPAQUE: + case TOK_CHAR: + case TOK_INT: + case TOK_FLOAT: + case TOK_DOUBLE: + case TOK_BOOL: + *typep = tok.str; + break; + default: + error("expected type specifier"); + } +} + + +static +unsigned_dec(typep) + 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_INT: + get_token(&tok); + *typep = "u_int"; + break; + default: + *typep = "u_int"; + break; + } +} diff --git a/usr.bin/rpcgen/rpc_parse.h b/usr.bin/rpcgen/rpc_parse.h new file mode 100644 index 0000000..0a4eb1e --- /dev/null +++ b/usr.bin/rpcgen/rpc_parse.h @@ -0,0 +1,159 @@ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + * + * from: @(#)rpc_parse.h 1.3 87/03/09 (C) 1987 SMI + * $Id: rpc_parse.h,v 1.1 1993/09/13 23:20:17 jtc Exp $ + */ + +/* + * rpc_parse.h, Definitions for the RPCL parser + * Copyright (C) 1987, Sun Microsystems, Inc. + */ + +enum defkind { + DEF_CONST, + DEF_STRUCT, + DEF_UNION, + DEF_ENUM, + DEF_TYPEDEF, + DEF_PROGRAM +}; +typedef enum defkind defkind; + +typedef char *const_def; + +enum relation { + REL_VECTOR, /* fixed length array */ + REL_ARRAY, /* variable length array */ + REL_POINTER, /* pointer */ + REL_ALIAS, /* simple */ +}; +typedef enum relation relation; + +struct typedef_def { + char *old_prefix; + char *old_type; + relation rel; + char *array_max; +}; +typedef struct typedef_def typedef_def; + + +struct enumval_list { + char *name; + char *assignment; + struct enumval_list *next; +}; +typedef struct enumval_list enumval_list; + +struct enum_def { + enumval_list *vals; +}; +typedef struct enum_def enum_def; + + +struct declaration { + char *prefix; + char *type; + char *name; + relation rel; + char *array_max; +}; +typedef struct declaration declaration; + + +struct decl_list { + declaration decl; + struct decl_list *next; +}; +typedef struct decl_list decl_list; + +struct struct_def { + decl_list *decls; +}; +typedef struct struct_def struct_def; + + +struct case_list { + char *case_name; + 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 proc_list { + char *proc_name; + char *proc_num; + char *arg_type; + char *arg_prefix; + char *res_type; + char *res_prefix; + struct proc_list *next; +}; +typedef struct proc_list proc_list; + + +struct version_list { + char *vers_name; + char *vers_num; + proc_list *procs; + struct version_list *next; +}; +typedef struct version_list version_list; + +struct program_def { + char *prog_num; + version_list *versions; +}; +typedef struct program_def program_def; + +struct definition { + char *def_name; + defkind def_kind; + union { + const_def co; + struct_def st; + union_def un; + enum_def en; + typedef_def ty; + program_def pr; + } def; +}; +typedef struct definition definition; + +/* @(#)rpc_parse.h 2.1 88/08/01 4.0 RPCSRC */ +definition *get_definition(); diff --git a/usr.bin/rpcgen/rpc_scan.c b/usr.bin/rpcgen/rpc_scan.c new file mode 100644 index 0000000..c531bba --- /dev/null +++ b/usr.bin/rpcgen/rpc_scan.c @@ -0,0 +1,476 @@ +/* @(#)rpc_scan.c 2.1 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#ifndef lint +/*static char sccsid[] = "from: @(#)rpc_scan.c 1.6 87/06/24 (C) 1987 SMI";*/ +static char rcsid[] = "$Id: rpc_scan.c,v 1.1 1993/09/13 23:20:18 jtc Exp $"; +#endif + +/* + * rpc_scan.c, Scanner for the RPC protocol compiler + * Copyright (C) 1987, Sun Microsystems, Inc. + */ +#include <stdio.h> +#include <ctype.h> +#include <strings.h> +#include "rpc_scan.h" +#include "rpc_util.h" + +#define startcomment(where) (where[0] == '/' && where[1] == '*') +#define endcomment(where) (where[-1] == '*' && where[0] == '/') + +static int pushed = 0; /* is a token pushed */ +static token lasttok; /* last token, if pushed */ + +static int unget_token(), findstrconst(), findconst(), findkind(), cppline(), + directive(), printdirective(), docppline(); +/* + * scan expecting 1 given token + */ +void +scan(expect, tokp) + tok_kind expect; + token *tokp; +{ + get_token(tokp); + if (tokp->kind != expect) { + expected1(expect); + } +} + +/* + * scan expecting 2 given tokens + */ +void +scan2(expect1, expect2, tokp) + tok_kind expect1; + tok_kind expect2; + token *tokp; +{ + get_token(tokp); + if (tokp->kind != expect1 && tokp->kind != expect2) { + expected2(expect1, expect2); + } +} + +/* + * scan expecting 3 given token + */ +void +scan3(expect1, expect2, expect3, tokp) + 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(tokp) + token *tokp; +{ + get_token(tokp); + switch (tokp->kind) { + case TOK_IDENT: + break; + default: + error("constant or identifier expected"); + } +} + + +/* + * Peek at the next token + */ +void +peek(tokp) + token *tokp; +{ + get_token(tokp); + unget_token(tokp); +} + + +/* + * Peek at the next token and scan it if it matches what you expect + */ +int +peekscan(expect, tokp) + 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(tokp) + token *tokp; +{ + int commenting; + + if (pushed) { + pushed = 0; + *tokp = lasttok; + return; + } + commenting = 0; + for (;;) { + if (*where == 0) { + for (;;) { + if (!fgets(curline, MAXLINESIZE, fin)) { + tokp->kind = TOK_EOF; + *where = 0; + return; + } + linenum++; + if (commenting) { + break; + } else if (cppline(curline)) { + docppline(curline, &linenum, + &infilename); + } else if (directive(curline)) { + printdirective(curline); + } else { + break; + } + } + where = curline; + } else if (isspace(*where)) { + while (isspace(*where)) { + where++; /* eat */ + } + } else if (commenting) { + where++; + if (endcomment(where)) { + where++; + commenting--; + } + } 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 '-': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + tokp->kind = TOK_IDENT; + findconst(&where, &tokp->str); + break; + + + default: + if (!(isalpha(*where) || *where == '_')) { + char buf[100]; + char *p; + + s_print(buf, "illegal character in file: "); + p = buf + strlen(buf); + if (isprint(*where)) { + s_print(p, "%c", *where); + } else { + s_print(p, "%d", *where); + } + error(buf); + } + findkind(&where, tokp); + break; + } +} + + + +static +unget_token(tokp) + token *tokp; +{ + lasttok = *tokp; + pushed = 1; +} + + +static +findstrconst(str, val) + char **str; + char **val; +{ + char *p; + int size; + + p = *str; + do { + *p++; + } while (*p && *p != '"'); + if (*p == 0) { + error("unterminated string constant"); + } + p++; + size = p - *str; + *val = alloc(size + 1); + (void) strncpy(*val, *str, size); + (*val)[size] = 0; + *str = p; +} + +static +findconst(str, val) + char **str; + char **val; +{ + char *p; + int size; + + p = *str; + if (*p == '0' && *(p + 1) == 'x') { + p++; + do { + p++; + } while (isxdigit(*p)); + } else { + do { + p++; + } while (isdigit(*p)); + } + size = p - *str; + *val = alloc(size + 1); + (void) strncpy(*val, *str, size); + (*val)[size] = 0; + *str = p; +} + + + +static token symbols[] = { + {TOK_CONST, "const"}, + {TOK_UNION, "union"}, + {TOK_SWITCH, "switch"}, + {TOK_CASE, "case"}, + {TOK_DEFAULT, "default"}, + {TOK_STRUCT, "struct"}, + {TOK_TYPEDEF, "typedef"}, + {TOK_ENUM, "enum"}, + {TOK_OPAQUE, "opaque"}, + {TOK_BOOL, "bool"}, + {TOK_VOID, "void"}, + {TOK_CHAR, "char"}, + {TOK_INT, "int"}, + {TOK_UNSIGNED, "unsigned"}, + {TOK_SHORT, "short"}, + {TOK_LONG, "long"}, + {TOK_FLOAT, "float"}, + {TOK_DOUBLE, "double"}, + {TOK_STRING, "string"}, + {TOK_PROGRAM, "program"}, + {TOK_VERSION, "version"}, + {TOK_EOF, "??????"}, +}; + + +static +findkind(mark, tokp) + char **mark; + token *tokp; +{ + + int len; + token *s; + char *str; + + str = *mark; + for (s = symbols; s->kind != TOK_EOF; s++) { + len = strlen(s->str); + if (strncmp(str, s->str, len) == 0) { + if (!isalnum(str[len]) && str[len] != '_') { + tokp->kind = s->kind; + tokp->str = s->str; + *mark = str + len; + return; + } + } + } + tokp->kind = TOK_IDENT; + for (len = 0; isalnum(str[len]) || str[len] == '_'; len++); + tokp->str = alloc(len + 1); + (void) strncpy(tokp->str, str, len); + tokp->str[len] = 0; + *mark = str + len; +} + +static +cppline(line) + char *line; +{ + return (line == curline && *line == '#'); +} + +static +directive(line) + char *line; +{ + return (line == curline && *line == '%'); +} + +static +printdirective(line) + char *line; +{ + f_print(fout, "%s", line + 1); +} + +static +docppline(line, lineno, fname) + char *line; + int *lineno; + char **fname; +{ + char *file; + int num; + char *p; + + line++; + while (isspace(*line)) { + line++; + } + num = atoi(line); + while (isdigit(*line)) { + line++; + } + while (isspace(*line)) { + line++; + } + if (*line != '"') { + error("preprocessor error"); + } + line++; + p = file = alloc(strlen(line) + 1); + while (*line && *line != '"') { + *p++ = *line++; + } + if (*line == 0) { + error("preprocessor error"); + } + *p = 0; + if (*file == 0) { + *fname = NULL; + } else { + *fname = file; + } + *lineno = num - 1; +} diff --git a/usr.bin/rpcgen/rpc_scan.h b/usr.bin/rpcgen/rpc_scan.h new file mode 100644 index 0000000..fdb7e7b --- /dev/null +++ b/usr.bin/rpcgen/rpc_scan.h @@ -0,0 +1,103 @@ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + * + * from: @(#)rpc_scan.h 1.3 87/03/09 (C) 1987 SMI + * from: @(#)rpc_scan.h 2.1 88/08/01 4.0 RPCSRC + * $Id: rpc_scan.h,v 1.1 1993/09/13 23:20:18 jtc Exp $ + */ + +/* + * rpc_scan.h, Definitions for the RPCL scanner + * Copyright (C) 1987, Sun Microsystems, Inc. + */ + +/* + * kinds of tokens + */ +enum tok_kind { + TOK_IDENT, + 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_UNSIGNED, + TOK_FLOAT, + TOK_DOUBLE, + TOK_OPAQUE, + TOK_CHAR, + TOK_STRING, + TOK_BOOL, + TOK_VOID, + TOK_PROGRAM, + TOK_VERSION, + TOK_EOF +}; +typedef enum tok_kind tok_kind; + +/* + * a token + */ +struct token { + tok_kind kind; + char *str; +}; +typedef struct token token; + + +/* + * routine interface + */ +void scanprint(); +void scan(); +void scan2(); +void scan3(); +void scan_num(); +void peek(); +int peekscan(); +void get_token(); diff --git a/usr.bin/rpcgen/rpc_svcout.c b/usr.bin/rpcgen/rpc_svcout.c new file mode 100644 index 0000000..7f375c5 --- /dev/null +++ b/usr.bin/rpcgen/rpc_svcout.c @@ -0,0 +1,276 @@ +/* @(#)rpc_svcout.c 2.1 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#ifndef lint +/*static char sccsid[] = "from: @(#)rpc_svcout.c 1.6 87/06/24 (C) 1987 SMI";*/ +static char rcsid[] = "$Id: rpc_svcout.c,v 1.1 1993/09/13 23:20:19 jtc Exp $"; +#endif + +/* + * rpc_svcout.c, Server-skeleton outputter for the RPC protocol compiler + * Copyright (C) 1987, Sun Microsytsems, Inc. + */ +#include <stdio.h> +#include <strings.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 int write_program(), printerr(), printif(); +/* + * write most of the service, that is, everything but the registrations. + */ +void +write_most() +{ + 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, "\nstatic void "); + pvname(def->def_name, vp->vers_num); + f_print(fout, "();"); + } + } + } + f_print(fout, "\n\n"); + f_print(fout, "main()\n"); + f_print(fout, "{\n"); + f_print(fout, "\tSVCXPRT *%s;\n", TRANSP); + f_print(fout, "\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(void)pmap_unset(%s, %s);\n", def->def_name, vp->vers_name); + } + } +} + + +/* + * write a registration for the given transport + */ +void +write_register(transp) + char *transp; +{ + list *l; + definition *def; + version_list *vp; + + f_print(fout, "\n"); + f_print(fout, "\t%s = svc%s_create(RPC_ANYSOCK", TRANSP, transp); + if (streq(transp, "tcp")) { + f_print(fout, ", 0, 0"); + } + f_print(fout, ");\n"); + f_print(fout, "\tif (%s == NULL) {\n", TRANSP); + f_print(fout, "\t\t(void)fprintf(stderr, \"cannot create %s service.\\n\");\n", transp); + f_print(fout, "\t\texit(1);\n"); + f_print(fout, "\t}\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, + "\tif (!svc_register(%s, %s, %s, ", + TRANSP, def->def_name, vp->vers_name); + pvname(def->def_name, vp->vers_num); + f_print(fout, ", IPPROTO_%s)) {\n", + streq(transp, "udp") ? "UDP" : "TCP"); + f_print(fout, + "\t\t(void)fprintf(stderr, \"unable to register (%s, %s, %s).\\n\");\n", + def->def_name, vp->vers_name, transp); + f_print(fout, "\t\texit(1);\n"); + f_print(fout, "\t}\n"); + } + } +} + + +/* + * write the rest of the service + */ +void +write_rest() +{ + f_print(fout, "\tsvc_run();\n"); + f_print(fout, "\t(void)fprintf(stderr, \"svc_run returned\\n\");\n"); + f_print(fout, "\texit(1);\n"); + f_print(fout, "}\n"); +} + +void +write_programs(storage) + char *storage; +{ + list *l; + definition *def; + + for (l = defined; l != NULL; l = l->next) { + def = (definition *) l->val; + if (def->def_kind == DEF_PROGRAM) { + write_program(def, storage); + } + } +} + + +static +write_program(def, storage) + definition *def; + char *storage; +{ + version_list *vp; + proc_list *proc; + int filled; + + for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { + f_print(fout, "\n"); + if (storage != NULL) { + f_print(fout, "%s ", storage); + } + f_print(fout, "void\n"); + pvname(def->def_name, vp->vers_num); + f_print(fout, "(%s, %s)\n", RQSTP, TRANSP); + f_print(fout, " struct svc_req *%s;\n", 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 (streq(proc->arg_type, "void")) { + continue; + } + filled = 1; + f_print(fout, "\t\t"); + ptype(proc->arg_prefix, proc->arg_type, 0); + pvname(proc->proc_name, vp->vers_num); + f_print(fout, "_arg;\n"); + } + if (!filled) { + f_print(fout, "\t\tint fill;\n"); + } + f_print(fout, "\t} %s;\n", ARG); + f_print(fout, "\tchar *%s;\n", RESULT); + f_print(fout, "\tbool_t (*xdr_%s)(), (*xdr_%s)();\n", ARG, RESULT); + f_print(fout, "\tchar *(*%s)();\n", ROUTINE); + f_print(fout, "\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, xdr_void, (char *)NULL);\n", TRANSP); + f_print(fout, "\t\treturn;\n\n"); + } + for (proc = vp->procs; proc != NULL; proc = proc->next) { + f_print(fout, "\tcase %s:\n", proc->proc_name); + f_print(fout, "\t\txdr_%s = xdr_%s;\n", ARG, + stringfix(proc->arg_type)); + f_print(fout, "\t\txdr_%s = xdr_%s;\n", RESULT, + stringfix(proc->res_type)); + f_print(fout, "\t\t%s = (char *(*)()) ", ROUTINE); + pvname(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); + f_print(fout, "\t\treturn;\n"); + f_print(fout, "\t}\n"); + + f_print(fout, "\tbzero((char *)&%s, sizeof(%s));\n", ARG, ARG); + printif("getargs", TRANSP, "&", ARG); + printerr("decode", TRANSP); + f_print(fout, "\t\treturn;\n"); + f_print(fout, "\t}\n"); + + f_print(fout, "\t%s = (*%s)(&%s, %s);\n", RESULT, ROUTINE, ARG, + RQSTP); + 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, "&", ARG); + f_print(fout, "\t\t(void)fprintf(stderr, \"unable to free arguments\\n\");\n"); + f_print(fout, "\t\texit(1);\n"); + f_print(fout, "\t}\n"); + + f_print(fout, "}\n\n"); + } +} + +static +printerr(err, transp) + char *err; + char *transp; +{ + f_print(fout, "\t\tsvcerr_%s(%s);\n", err, transp); +} + +static +printif(proc, transp, prefix, arg) + char *proc; + char *transp; + char *prefix; + char *arg; +{ + f_print(fout, "\tif (!svc_%s(%s, xdr_%s, %s%s)) {\n", + proc, transp, arg, prefix, arg); +} + + +nullproc(proc) + proc_list *proc; +{ + for (; proc != NULL; proc = proc->next) { + if (streq(proc->proc_num, "0")) { + return (1); + } + } + return (0); +} diff --git a/usr.bin/rpcgen/rpc_util.c b/usr.bin/rpcgen/rpc_util.c new file mode 100644 index 0000000..6d5b18e --- /dev/null +++ b/usr.bin/rpcgen/rpc_util.c @@ -0,0 +1,439 @@ +/* @(#)rpc_util.c 2.1 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#ifndef lint +/*static char sccsid[] = "from: @(#)rpc_util.c 1.5 87/06/24 (C) 1987 SMI";*/ +static char rcsid[] = "$Id: rpc_util.c,v 1.1 1993/09/13 23:20:20 jtc Exp $"; +#endif + +/* + * rpc_util.c, Utility routines for the RPC protocol compiler + * Copyright (C) 1987, Sun Microsystems, Inc. + */ +#include <stdio.h> +#include "rpc_scan.h" +#include "rpc_parse.h" +#include "rpc_util.h" + +char curline[MAXLINESIZE]; /* current read line */ +char *where = curline; /* current point in line */ +int linenum = 0; /* current line number */ + +char *infilename; /* input filename */ + +#define NFILES 4 +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 int printwhere(); + +/* + * Reinitialize the world + */ +reinitialize() +{ + bzero(curline, MAXLINESIZE); + where = curline; + linenum = 0; + defined = NULL; +} + +/* + * string equality + */ +streq(a, b) + char *a; + char *b; +{ + return (strcmp(a, b) == 0); +} + +/* + * find a value in a list + */ +char * +findval(lst, val, cmp) + list *lst; + char *val; + int (*cmp) (); + +{ + for (; lst != NULL; lst = lst->next) { + if ((*cmp) (lst->val, val)) { + return (lst->val); + } + } + return (NULL); +} + +/* + * store a value in a list + */ +void +storeval(lstp, val) + list **lstp; + char *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 +findit(def, type) + definition *def; + char *type; +{ + return (streq(def->def_name, type)); +} + + +static char * +fixit(type, orig) + char *type; + char *orig; +{ + definition *def; + + def = (definition *) FINDVAL(defined, type, findit); + if (def == NULL || def->def_kind != DEF_TYPEDEF) { + return (orig); + } + switch (def->def.ty.rel) { + case REL_VECTOR: + return (def->def.ty.old_type); + case REL_ALIAS: + return (fixit(def->def.ty.old_type, orig)); + default: + return (orig); + } +} + +char * +fixtype(type) + char *type; +{ + return (fixit(type, type)); +} + +char * +stringfix(type) + char *type; +{ + if (streq(type, "string")) { + return ("wrapstring"); + } else { + return (type); + } +} + +void +ptype(prefix, type, follow) + char *prefix; + char *type; + int follow; +{ + if (prefix != NULL) { + if (streq(prefix, "enum")) { + f_print(fout, "enum "); + } else { + f_print(fout, "struct "); + } + } + if (streq(type, "bool")) { + f_print(fout, "bool_t "); + } else if (streq(type, "string")) { + f_print(fout, "char *"); + } else { + f_print(fout, "%s ", follow ? fixtype(type) : type); + } +} + + +static +typedefed(def, type) + definition *def; + char *type; +{ + if (def->def_kind != DEF_TYPEDEF || def->def.ty.old_prefix != NULL) { + return (0); + } else { + return (streq(def->def_name, type)); + } +} + +isvectordef(type, rel) + 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; + } + } +} + + +static char * +locase(str) + char *str; +{ + char c; + static char buf[100]; + char *p = buf; + + while (c = *str++) { + *p++ = (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c; + } + *p = 0; + return (buf); +} + + +void +pvname(pname, vnum) + char *pname; + char *vnum; +{ + f_print(fout, "%s_%s", locase(pname), vnum); +} + + +/* + * print a useful (?) error message, and then die + */ +void +error(msg) + char *msg; +{ + printwhere(); + f_print(stderr, "%s, line %d: ", infilename, linenum); + f_print(stderr, "%s\n", msg); + crash(); +} + +/* + * Something went wrong, unlink any files that we may have created and then + * die. + */ +crash() +{ + int i; + + for (i = 0; i < nfiles; i++) { + (void) unlink(outfiles[i]); + } + exit(1); +} + + +void +record_open(file) + char *file; +{ + if (nfiles < NFILES) { + outfiles[nfiles++] = file; + } else { + f_print(stderr, "too many files!\n"); + crash(); + } +} + +static char expectbuf[100]; +static char *toktostr(); + +/* + * error, token encountered was not the expected one + */ +void +expected1(exp1) + tok_kind exp1; +{ + s_print(expectbuf, "expected '%s'", + toktostr(exp1)); + error(expectbuf); +} + +/* + * error, token encountered was not one of two expected ones + */ +void +expected2(exp1, exp2) + tok_kind exp1, exp2; +{ + s_print(expectbuf, "expected '%s' or '%s'", + toktostr(exp1), + toktostr(exp2)); + error(expectbuf); +} + +/* + * error, token encountered was not one of 3 expected ones + */ +void +expected3(exp1, exp2, exp3) + tok_kind exp1, exp2, exp3; +{ + s_print(expectbuf, "expected '%s', '%s' or '%s'", + toktostr(exp1), + toktostr(exp2), + toktostr(exp3)); + error(expectbuf); +} + +void +tabify(f, tab) + FILE *f; + int tab; +{ + while (tab--) { + (void) fputc('\t', f); + } +} + + + +static token tokstrings[] = { + {TOK_IDENT, "identifier"}, + {TOK_CONST, "const"}, + {TOK_RPAREN, ")"}, + {TOK_LPAREN, "("}, + {TOK_RBRACE, "}"}, + {TOK_LBRACE, "{"}, + {TOK_LBRACKET, "["}, + {TOK_RBRACKET, "]"}, + {TOK_STAR, "*"}, + {TOK_COMMA, ","}, + {TOK_EQUAL, "="}, + {TOK_COLON, ":"}, + {TOK_SEMICOLON, ";"}, + {TOK_UNION, "union"}, + {TOK_STRUCT, "struct"}, + {TOK_SWITCH, "switch"}, + {TOK_CASE, "case"}, + {TOK_DEFAULT, "default"}, + {TOK_ENUM, "enum"}, + {TOK_TYPEDEF, "typedef"}, + {TOK_INT, "int"}, + {TOK_SHORT, "short"}, + {TOK_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 char * +toktostr(kind) + tok_kind kind; +{ + token *sp; + + for (sp = tokstrings; sp->kind != TOK_EOF && sp->kind != kind; sp++); + return (sp->str); +} + + + +static +printbuf() +{ + char c; + int i; + int cnt; + +# define TABSIZE 4 + + for (i = 0; c = curline[i]; i++) { + if (c == '\t') { + cnt = 8 - (i % TABSIZE); + c = ' '; + } else { + cnt = 1; + } + while (cnt--) { + (void) fputc(c, stderr); + } + } +} + + +static +printwhere() +{ + 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); +} diff --git a/usr.bin/rpcgen/rpc_util.h b/usr.bin/rpcgen/rpc_util.h new file mode 100644 index 0000000..dcca92f --- /dev/null +++ b/usr.bin/rpcgen/rpc_util.h @@ -0,0 +1,113 @@ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + * + * from: @(#)rpc_util.h 1.6 87/06/24 (C) 1987 SMI + * from: @(#)rpc_util.h 2.1 88/08/01 4.0 RPCSRC + * $Id: rpc_util.h,v 1.1 1993/09/13 23:20:21 jtc Exp $ + */ + +/* + * rpc_util.h, Useful definitions for the RPC protocol compiler + * Copyright (C) 1987, Sun Microsystems, Inc. + */ +extern char *malloc(); + +#define alloc(size) malloc((unsigned)(size)) +#define ALLOC(object) (object *) malloc(sizeof(object)) + +#define s_print (void) sprintf +#define f_print (void) fprintf + +struct list { + char *val; + struct list *next; +}; +typedef struct list list; + +/* + * Global variables + */ +#define MAXLINESIZE 1024 +extern char curline[MAXLINESIZE]; +extern char *where; +extern int linenum; + +extern char *infilename; +extern FILE *fout; +extern FILE *fin; + +extern list *defined; + +/* + * rpc_util routines + */ +void storeval(); + +#define STOREVAL(list,item) \ + storeval(list,(char *)item) + +char *findval(); + +#define FINDVAL(list,item,finder) \ + findval(list, (char *) item, finder) + +char *fixtype(); +char *stringfix(); +void pvname(); +void ptype(); +int isvectordef(); +int streq(); +void error(); +void expected1(); +void expected2(); +void expected3(); +void tabify(); +void record_open(); + +/* + * rpc_cout routines + */ +void cprint(); +void emit(); + +/* + * rpc_hout routines + */ +void print_datadef(); + +/* + * rpc_svcout routines + */ +void write_most(); +void write_register(); +void write_rest(); + +/* + * rpc_clntout routines + */ +void write_stubs(); diff --git a/usr.bin/rpcgen/rpcgen.1 b/usr.bin/rpcgen/rpcgen.1 new file mode 100644 index 0000000..5fd9274 --- /dev/null +++ b/usr.bin/rpcgen/rpcgen.1 @@ -0,0 +1,156 @@ +.\" from: @(#)rpcgen.1 2.2 88/08/02 4.0 RPCSRC +.\" $Id: rpcgen.1,v 1.1 1993/09/13 23:20:21 jtc Exp $ +.\" +.Dd January 18, 1988 +.Dt RPCGEN 1 +.Os +.Sh NAME +.Nm rpcgen +.Nd RPC protocol compiler +.Sh SYNOPSIS +.Nm rpcgen +.Ar infile +.Nm rpcgen +.Fl c Li | +.Fl h Li | +.Fl l Li | +.Fl m +.Op Fl o Ar outfile +.Op Ar infile +.Nm rpcgen +.Fl s Ar transport +.Op Fl o Ar outfile +.Op Ar infile +.Sh DESCRIPTION +.Nm rpcgen +is a tool that generates C code to implement an +.Tn RPC +protocol. The input to +.Nm rpcgen +is a language similar to C known as +.Tn RPC +Language (Remote Procedure Call Language). Information about the +syntax of +.Tn RPC +Language is available in the +.Rs +.%T "rpcgen Programming Guide" +.Re +.Pp +.Nm rpcgen +is normally used as in the first synopsis where it takes an input file +and generates four output files. If the +.Ar infile +is named +.Pa proto.x , +then +.Nm rpcgen +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 . +.Pp +The other synopses shown above are used when one does not want to +generate all the output files, but only a particular one. +.\" Their usage is described in the +.\" .Sx USAGE +.\" section below. +.Pp +The C-preprocessor, +.Xr cpp 1 , +is run on all input files before they are actually +interpreted by +.Nm rpcgen , +so all the +.Xr cpp +directives are legal within an +.Nm rpcgen +input file. For each type of output file, +.Nm rpcgen +defines a special +.Xr cpp +symbol for use by the +.Nm rpcgen +programmer: +.Pp +.Bl -tag -width RPC_CLNT -compact +.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 +.El +.Pp +In addition, +.Nm rpcgen +does a little preprocessing of its own. Any line beginning with +.Sq % +is passed directly into the output file, uninterpreted by +.Nm rpcgen . +.Pp +You can customize some of your +.Tn XDR +routines by leaving those data types undefined. For every data type +that is undefined, +.Nm rpcgen +will assume that there exists a routine with the name +.Tn xdr_ +prepended to the name of the undefined type. +.Sh OPTIONS +.Bl -tag -width indent +.It Fl c +Compile into +.Tn XDR +routines. +.It Fl h +Compile into C data-definitions (a header file). +.It Fl l +Compile into client-side stubs. +.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 +people who need to write their own +.Fn main +routine to do initialization. +.It Fl o Ar outfile +Specify the name of the output file. If none is specified, standard +output is used ( +.Fl c , +.Fl h , +.Fl l +and +.Fl s +modes only). +.It Fl s Ar transport +Compile into server-side stubs, using the the given transport. The +supported transports are +.Tn udp +and +.Tn tcp . +This option may be invoked more than once so as to compile a server +that serves multiple transports. +.El +.Sh SEE ALSO +.Xr cpp 1 +.Rs +.%T "rpcgen Programming Guide" +.Re +.Sh BUGS +Nesting is not supported. As a work-around, structures can be +declared at 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. |