summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwpaul <wpaul@FreeBSD.org>1995-12-13 03:21:09 +0000
committerwpaul <wpaul@FreeBSD.org>1995-12-13 03:21:09 +0000
commitc4bda74e8af091bd88fd1d338b0408ced2967a4d (patch)
tree7b15f8667f850d441bc04980c58773734aeaad24
parente16baf7a5fe7ac1453381d0017ed1dcdeefbc995 (diff)
downloadFreeBSD-src-c4bda74e8af091bd88fd1d338b0408ced2967a4d.zip
FreeBSD-src-c4bda74e8af091bd88fd1d338b0408ced2967a4d.tar.gz
Import a newer and more functional version of rpcgen.
Obtained from: the Sun TI-RPC 2.3 source distribution
-rw-r--r--usr.bin/rpcgen/Makefile14
-rw-r--r--usr.bin/rpcgen/rpc_clntout.c279
-rw-r--r--usr.bin/rpcgen/rpc_cout.c521
-rw-r--r--usr.bin/rpcgen/rpc_hout.c319
-rw-r--r--usr.bin/rpcgen/rpc_main.c1133
-rw-r--r--usr.bin/rpcgen/rpc_parse.c272
-rw-r--r--usr.bin/rpcgen/rpc_parse.h64
-rw-r--r--usr.bin/rpcgen/rpc_sample.c311
-rw-r--r--usr.bin/rpcgen/rpc_scan.c93
-rw-r--r--usr.bin/rpcgen/rpc_scan.h42
-rw-r--r--usr.bin/rpcgen/rpc_svcout.c970
-rw-r--r--usr.bin/rpcgen/rpc_tblout.c171
-rw-r--r--usr.bin/rpcgen/rpc_util.c213
-rw-r--r--usr.bin/rpcgen/rpc_util.h134
-rw-r--r--usr.bin/rpcgen/rpcgen.1684
15 files changed, 4591 insertions, 629 deletions
diff --git a/usr.bin/rpcgen/Makefile b/usr.bin/rpcgen/Makefile
index fefab49..d0e4c14 100644
--- a/usr.bin/rpcgen/Makefile
+++ b/usr.bin/rpcgen/Makefile
@@ -1,7 +1,13 @@
-# $Id: Makefile,v 1.1 1993/09/13 23:20:11 jtc Exp $
+SRCS= rpc_main.c rpc_clntout.c rpc_cout.c rpc_hout.c rpc_parse.c \
+ rpc_sample.c rpc_scan.c rpc_svcout.c rpc_tblout.c rpc_util.c
-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
+PROG= rpcgen
+MAN1= rpcgen.1
+
+#
+# This is a kludge to work around the fact that this program
+# uses 'inline' as a variable name.
+#
+CFLAGS+=-Dinline=rpcgen_inline
.include <bsd.prog.mk>
diff --git a/usr.bin/rpcgen/rpc_clntout.c b/usr.bin/rpcgen/rpc_clntout.c
index 73cb97d..9137ce1 100644
--- a/usr.bin/rpcgen/rpc_clntout.c
+++ b/usr.bin/rpcgen/rpc_clntout.c
@@ -1,4 +1,3 @@
-/* @(#)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
@@ -27,9 +26,11 @@
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
+
+#ident "@(#)rpc_clntout.c 1.15 94/04/25 SMI"
+
#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 $";
+static char sccsid[] = "@(#)rpc_clntout.c 1.11 89/02/22 (C) 1987 SMI";
#endif
/*
@@ -37,13 +38,20 @@ static char rcsid[] = "$Id: rpc_clntout.c,v 1.1 1993/09/13 23:20:12 jtc Exp $";
* Copyright (C) 1987, Sun Microsytsems, Inc.
*/
#include <stdio.h>
-#include <strings.h>
+#include <string.h>
+#include <rpc/types.h>
#include "rpc_parse.h"
#include "rpc_util.h"
-#define DEFAULT_TIMEOUT 25 /* in seconds */
+extern int pdeclaration __P(( char *, declaration *, int, char * ));
+void printarglist __P(( proc_list *, char *, char *, char *));
+static int write_program __P(( definition * ));
+static int printbody __P(( proc_list * ));
-static int write_program(), printbody();
+static char RESULT[] = "clnt_res";
+
+
+#define DEFAULT_TIMEOUT 25 /* in seconds */
void
@@ -52,9 +60,9 @@ 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",
+ 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;
@@ -64,7 +72,6 @@ write_stubs()
}
}
-
static
write_program(def)
definition *def;
@@ -75,21 +82,131 @@ write_program(def)
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");
+ if (mtflag == 0) {
+ ptype(proc->res_prefix, proc->res_type, 1);
+ f_print(fout, "*\n");
+ pvname(proc->proc_name, vp->vers_num);
+ printarglist(proc, RESULT, "clnt", "CLIENT *");
+ } else {
+ f_print(fout, "enum clnt_stat \n");
+ pvname(proc->proc_name, vp->vers_num);
+ printarglist(proc, RESULT, "clnt", "CLIENT *");
+
+ }
f_print(fout, "{\n");
printbody(proc);
- f_print(fout, "}\n\n");
+
+ 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, result, addargname, addargtype)
+ proc_list *proc;
+ char *result;
+ char* addargname, * addargtype;
+{
+
+ decl_list *l;
+
+ if (!newstyle) {
+ /* old style: always pass argument by reference */
+ if (Cflag) { /* C++ style heading */
+ f_print(fout, "(");
+ ptype(proc->args.decls->decl.prefix,
+ proc->args.decls->decl.type, 1);
+
+ if (mtflag) {/* Generate result field */
+ f_print(fout, "*argp, ");
+ ptype(proc->res_prefix, proc->res_type, 1);
+ f_print(fout, "*%s, %s%s)\n",
+ result, addargtype, addargname);
+ } else
+ f_print(fout, "*argp, %s%s)\n", addargtype, addargname);
+ } else {
+ if (!mtflag)
+ f_print(fout, "(argp, %s)\n", addargname);
+ else
+ f_print(fout, "(argp, %s, %s)\n",
+ result, addargname);
+ f_print(fout, "\t");
+ ptype(proc->args.decls->decl.prefix,
+ proc->args.decls->decl.type, 1);
+ f_print(fout, "*argp;\n");
+ if (mtflag) {
+ f_print(fout, "\t");
+ ptype(proc->res_prefix, proc->res_type, 1);
+ f_print(fout, "*%s;\n", result);
+ }
+ }
+ } else if (streq(proc->args.decls->decl.type, "void")) {
+ /* newstyle, 0 argument */
+ if (mtflag) {
+ f_print(fout, "(");
+
+
+ if (Cflag) {
+ ptype(proc->res_prefix, proc->res_type, 1);
+ f_print(fout, "*%s, %s%s)\n",
+ result, addargtype, addargname);
+ }
+ else
+ f_print(fout, "(%s)\n", addargname);
+
+ } else
+ if (Cflag)
+ f_print(fout, "(%s%s)\n", addargtype, addargname);
+ else
+ f_print(fout, "(%s)\n", addargname);
+ } else {
+ /* new style, 1 or multiple arguments */
+ if (!Cflag) {
+ f_print(fout, "(");
+ for (l = proc->args.decls; l != NULL; l = l->next)
+ f_print(fout, "%s, ", l->decl.name);
+ if (mtflag)
+ f_print(fout, "%s, ", result);
+
+ f_print(fout, "%s)\n", addargname);
+ for (l = proc->args.decls; l != NULL; l = l->next) {
+ pdeclaration(proc->args.argname,
+ &l->decl, 1, ";\n");
+ }
+ if (mtflag) {
+ f_print(fout, "\t");
+ ptype(proc->res_prefix, proc->res_type, 1);
+ f_print(fout, "*%s;\n", result);
+ }
+
+ } else { /* C++ style header */
+ f_print(fout, "(");
+ for (l = proc->args.decls; l != NULL; l = l->next) {
+ pdeclaration(proc->args.argname, &l->decl, 0,
+ ", ");
+ }
+ if (mtflag) {
+ ptype(proc->res_prefix, proc->res_type, 1);
+ f_print(fout, "*%s, ", result);
+
+ }
+ f_print(fout, "%s%s)\n", addargtype, addargname);
+ }
+ }
+
+ if (!Cflag)
+ f_print(fout, "\t%s%s;\n", addargtype, addargname);
+}
+
+
+
static char *
ampr(type)
char *type;
@@ -105,26 +222,110 @@ 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);
+ decl_list *l;
+ bool_t args2 = (proc->arg_num > 1);
+ int i;
+
+ /*
+ * For new style with multiple arguments, need a structure in which
+ * to stuff the arguments.
+ */
+
+
+ if (newstyle && args2) {
+ f_print(fout, "\t%s", proc->args.argname);
+ f_print(fout, " arg;\n");
}
- f_print(fout, "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));
+ if (!mtflag) {
+ f_print(fout, "\tstatic ");
+ if (streq(proc->res_type, "void")) {
+ f_print(fout, "char ");
+ } else {
+ ptype(proc->res_prefix, proc->res_type, 0);
+ }
+ f_print(fout, "%s;\n", RESULT);
+ f_print(fout, "\n");
+ f_print(fout, "\tmemset((char *)%s%s, 0, sizeof (%s));\n",
+ ampr(proc->res_type), RESULT, RESULT);
+
+ }
+ if (newstyle && !args2 &&
+ (streq(proc->args.decls->decl.type, "void"))) {
+ /* newstyle, 0 arguments */
+
+ if (mtflag)
+ f_print(fout, "\t return ");
+ else
+ f_print(fout, "\t if ");
+
+ f_print(fout,
+ "(clnt_call(clnt, %s,\n\t\t(xdrproc_t) xdr_void, ",
+ proc->proc_name);
+ f_print(fout,
+ "(caddr_t) NULL,\n\t\t(xdrproc_t) xdr_%s, (caddr_t) %s%s,",
+ stringfix(proc->res_type), (mtflag)?"":ampr(proc->res_type),
+ RESULT);
+
+ if (mtflag)
+ f_print(fout, "\n\t\tTIMEOUT));\n}\n");
+ else
+ f_print(fout, "\n\t\tTIMEOUT) != RPC_SUCCESS) {\n");
+
+ } 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 (mtflag)
+ f_print(fout, "\treturn ");
+ else
+ f_print(fout, "\tif ");
+ f_print(fout,
+ "(clnt_call(clnt, %s,\n\t\t(xdrproc_t) xdr_%s",
+ proc->proc_name,proc->args.argname);
+ f_print(fout,
+ ", (caddr_t) &arg,\n\t\t(xdrproc_t) xdr_%s, (caddr_t) %s%s,",
+ stringfix(proc->res_type), (mtflag)?"":ampr(proc->res_type),
+ RESULT);
+ if (mtflag)
+ f_print(fout, "\n\t\tTIMEOUT));\n");
+ else
+ f_print(fout, "\n\t\tTIMEOUT) != RPC_SUCCESS) {\n");
+ } else { /* single argument, new or old style */
+ if (!mtflag)
+ f_print(fout,
+ "\tif (clnt_call(clnt, %s,\n\t\t(xdrproc_t) xdr_%s, (caddr_t) %s%s,\n\t\t(xdrproc_t) xdr_%s, (caddr_t) %s%s,\n\t\tTIMEOUT) != 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);
+ else
+
+ f_print(fout,
+ "\treturn (clnt_call(clnt, %s,\n\t\t(xdrproc_t) xdr_%s, (caddr_t) %s%s,\n\t\t(xdrproc_t) xdr_%s, (caddr_t) %s%s,\n\t\tTIMEOUT));\n",
+ proc->proc_name,
+ stringfix(proc->args.decls->decl.type),
+ (newstyle ? "&" : ""),
+ (newstyle ? proc->args.decls->decl.name : "argp"),
+ stringfix(proc->res_type), "",
+ RESULT);
+ }
+ if (!mtflag) {
+ f_print(fout, "\t\treturn (NULL);\n");
+ f_print(fout, "\t}\n");
+
+ if (streq(proc->res_type, "void")) {
+ f_print(fout, "\treturn ((void *)%s%s);\n",
+ ampr(proc->res_type), RESULT);
+ } else {
+ f_print(fout, "\treturn (%s%s);\n",
+ ampr(proc->res_type), RESULT);
+ }
}
}
diff --git a/usr.bin/rpcgen/rpc_cout.c b/usr.bin/rpcgen/rpc_cout.c
index 9e2e361..e79ac9d 100644
--- a/usr.bin/rpcgen/rpc_cout.c
+++ b/usr.bin/rpcgen/rpc_cout.c
@@ -1,4 +1,3 @@
-/* @(#)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
@@ -27,34 +26,55 @@
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
+
+#ident "@(#)rpc_cout.c 1.14 93/07/05 SMI"
+
#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 $";
+static char sccsid[] = "@(#)rpc_cout.c 1.13 89/02/22 (C) 1987 SMI";
#endif
/*
- * rpc_cout.c, XDR routine outputter for the RPC protocol compiler
- * Copyright (C) 1987, Sun Microsystems, Inc.
+ * 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 <string.h>
#include "rpc_parse.h"
+#include "rpc_util.h"
-static int print_header(), print_trailer(), space(), emit_enum(),
- emit_union(), emit_struct(), emit_typedef(), print_stat();
-
+static int print_header __P(( definition * ));
+static int print_trailer __P(( void ));
+static int print_stat __P(( int , declaration * ));
+static int emit_enum __P(( definition * ));
+static int emit_program __P(( definition * ));
+static int emit_union __P(( definition * ));
+static int emit_struct __P(( definition * ));
+static int emit_typedef __P(( definition * ));
/*
- * Emit the C-routine for the given definition
+ * Emit the C-routine for the given definition
*/
void
emit(def)
definition *def;
{
- if (def->def_kind == DEF_PROGRAM || def->def_kind == DEF_CONST) {
+ 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:
@@ -78,6 +98,7 @@ findtype(def, type)
definition *def;
char *type;
{
+
if (def->def_kind == DEF_PROGRAM || def->def_kind == DEF_CONST) {
return (0);
} else {
@@ -97,20 +118,55 @@ undefined(type)
static
-print_header(def)
- definition *def;
+print_generic_header(procname, pointerp)
+ char* procname;
+ int pointerp;
{
- space();
+ f_print(fout, "\n");
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, "*");
+ if (Cflag) {
+ f_print(fout, "xdr_%s(", procname);
+ f_print(fout, "register XDR *xdrs, ");
+ f_print(fout, "%s ", procname);
+ if (pointerp)
+ f_print(fout, "*");
+ f_print(fout, "objp)\n{\n\n");
+ } else {
+ f_print(fout, "xdr_%s(xdrs, objp)\n", procname);
+ f_print(fout, "\tregister XDR *xdrs;\n");
+ f_print(fout, "\t%s ", procname);
+ if (pointerp)
+ f_print(fout, "*");
+ f_print(fout, "objp;\n{\n\n");
}
- f_print(fout, "objp;\n");
- f_print(fout, "{\n");
+}
+
+static
+print_header(def)
+ definition *def;
+{
+
+ decl_list *dl;
+ bas_type *ptr;
+ int i;
+
+ print_generic_header(def->def_name,
+ def->def_kind != DEF_TYPEDEF ||
+ !isvectordef(def->def.ty.old_type,
+ def->def.ty.rel));
+ /* Now add Inline support */
+
+ if (inline == 0)
+ return;
+ /* May cause lint to complain. but ... */
+ f_print(fout, "\tregister long *buf;\n\n");
+}
+
+static
+print_prog_header(plist)
+ proc_list *plist;
+{
+ print_generic_header(plist->args.argname, 1);
}
static
@@ -118,7 +174,6 @@ print_trailer()
{
f_print(fout, "\treturn (TRUE);\n");
f_print(fout, "}\n");
- space();
}
@@ -131,7 +186,6 @@ print_ifopen(indent, name)
f_print(fout, "if (!xdr_%s(xdrs", name);
}
-
static
print_ifarg(arg)
char *arg;
@@ -139,20 +193,26 @@ print_ifarg(arg)
f_print(fout, ", %s", arg);
}
-
static
-print_ifsizeof(prefix, type)
+print_ifsizeof(indent, prefix, type)
+ int indent;
char *prefix;
char *type;
{
+ if (indent) {
+ f_print(fout, ",\n");
+ tabify(fout, indent);
+ } else {
+ f_print(fout, ", ");
+ }
if (streq(type, "bool")) {
- f_print(fout, ", sizeof(bool_t), xdr_bool");
+ f_print(fout, "sizeof (bool_t), (xdrproc_t) xdr_bool");
} else {
- f_print(fout, ", sizeof(");
+ f_print(fout, "sizeof (");
if (undefined(type) && prefix) {
f_print(fout, "%s ", prefix);
}
- f_print(fout, "%s), xdr_%s", type, type);
+ f_print(fout, "%s), (xdrproc_t) xdr_%s", type, type);
}
}
@@ -160,17 +220,9 @@ static
print_ifclose(indent)
int indent;
{
- f_print(fout, ")) {\n");
+ 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
@@ -190,7 +242,7 @@ print_ifstat(indent, prefix, type, rel, amax, objname, name)
print_ifopen(indent, "pointer");
print_ifarg("(char **)");
f_print(fout, "%s", objname);
- print_ifsizeof(prefix, type);
+ print_ifsizeof(0, prefix, type);
break;
case REL_VECTOR:
if (streq(type, "string")) {
@@ -208,7 +260,7 @@ print_ifstat(indent, prefix, type, rel, amax, objname, name)
}
print_ifarg(amax);
if (!alt) {
- print_ifsizeof(prefix, type);
+ print_ifsizeof(indent + 1, prefix, type);
}
break;
case REL_ARRAY:
@@ -228,16 +280,17 @@ print_ifstat(indent, prefix, type, rel, amax, objname, name)
}
print_ifarg("(char **)");
if (*objname == '&') {
- f_print(fout, "%s.%s_val, (u_int *)%s.%s_len",
+ 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",
+ f_print(fout,
+ "&%s->%s_val, (u_int *) &%s->%s_len",
objname, name, objname, name);
}
}
print_ifarg(amax);
if (!alt) {
- print_ifsizeof(prefix, type);
+ print_ifsizeof(indent + 1, prefix, type);
}
break;
case REL_ALIAS:
@@ -248,7 +301,6 @@ print_ifstat(indent, prefix, type, rel, amax, objname, name)
print_ifclose(indent);
}
-
/* ARGSUSED */
static
emit_enum(def)
@@ -259,6 +311,26 @@ emit_enum(def)
print_ifclose(1);
}
+static
+emit_program(def)
+ 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
emit_union(def)
@@ -268,19 +340,29 @@ emit_union(def)
case_list *cl;
declaration *cs;
char *object;
+ char *vecformat = "objp->%s_u.%s";
char *format = "&objp->%s_u.%s";
- print_stat(&def->def.un.enum_decl);
+ 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) {
- cs = &cl->case_decl;
+
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);
- s_print(object, format, def->def_name, cs->name);
- print_ifstat(2, cs->prefix, cs->type, cs->rel, cs->array_max,
- object, cs->name);
+ 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");
@@ -290,10 +372,17 @@ emit_union(def)
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);
+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);
+ dflt->array_max, object, dflt->name);
free(object);
f_print(fout, "\t\tbreak;\n");
}
@@ -301,24 +390,238 @@ emit_union(def)
f_print(fout, "\tdefault:\n");
f_print(fout, "\t\treturn (FALSE);\n");
}
+
f_print(fout, "\t}\n");
}
+static void
+inline_struct(def, flag)
+definition *def;
+int flag;
+{
+ decl_list *dl;
+ int i, size;
+ decl_list *cur, *psav;
+ bas_type *ptr;
+ char *sizestr, *plus;
+ char ptemp[256];
+ int indent = 1;
+
+ if (flag == PUT)
+ f_print(fout, "\n\tif (xdrs->x_op == XDR_ENCODE) {\n");
+ else
+ f_print(fout, "\t\treturn (TRUE);\n\t} else if (xdrs->x_op == XDR_DECODE) {\n");
+
+ 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 code is required to handle arrays */
+ if (sizestr == NULL)
+ plus = "";
+ else
+ plus = " + ";
+
+ if (ptr->length != 1)
+ s_print(ptemp, "%s%s * %d",
+ plus, dl->decl.array_max,
+ ptr->length);
+ else
+ s_print(ptemp, "%s%s", plus,
+ dl->decl.array_max);
+
+ /* now concatenate to sizestr !!!! */
+ if (sizestr == NULL)
+ sizestr = strdup(ptemp);
+ else{
+ sizestr = realloc(sizestr,
+ strlen(sizestr)
+ +strlen(ptemp)+1);
+ if (sizestr == NULL){
+ f_print(stderr,
+ "Fatal error : no memory\n");
+ crash();
+ };
+ sizestr = strcat(sizestr, ptemp);
+ /* build up length of array */
+ }
+ }
+ } else {
+ if (i > 0)
+ if (sizestr == NULL && size < inline){
+ /*
+ * don't expand into inline code
+ * if size < inline
+ */
+ while (cur != dl){
+ print_stat(indent + 1, &cur->decl);
+ cur = cur->next;
+ }
+ } else {
+ /* were already looking at a xdr_inlineable structure */
+ tabify(fout, indent + 1);
+ if (sizestr == NULL)
+ f_print(fout, "buf = XDR_INLINE(xdrs, %d * BYTES_PER_XDR_UNIT);",
+ size);
+ else
+ if (size == 0)
+ f_print(fout,
+ "buf = XDR_INLINE(xdrs, (%s) * BYTES_PER_XDR_UNIT);",
+ sizestr);
+ else
+ f_print(fout,
+ "buf = XDR_INLINE(xdrs, (%d + (%s)) * BYTES_PER_XDR_UNIT);",
+ size, sizestr);
+
+ f_print(fout, "\n");
+ tabify(fout, indent + 1);
+ f_print(fout,
+ "if (buf == NULL) {\n");
+
+ psav = cur;
+ while (cur != dl){
+ print_stat(indent + 2, &cur->decl);
+ cur = cur->next;
+ }
+
+ f_print(fout, "\n\t\t} else {\n");
+
+ cur = psav;
+ while (cur != dl){
+ emit_inline(indent + 2, &cur->decl, flag);
+ cur = cur->next;
+ }
+
+ tabify(fout, indent + 1);
+ f_print(fout, "}\n");
+ }
+ size = 0;
+ i = 0;
+ sizestr = NULL;
+ print_stat(indent + 1, &dl->decl);
+ }
+ }
+
+ if (i > 0)
+ if (sizestr == NULL && size < inline){
+ /* don't expand into inline code if size < inline */
+ while (cur != dl){
+ print_stat(indent + 1, &cur->decl);
+ cur = cur->next;
+ }
+ } else {
+ /* were already looking at a xdr_inlineable structure */
+ if (sizestr == NULL)
+ f_print(fout, "\t\tbuf = XDR_INLINE(xdrs, %d * BYTES_PER_XDR_UNIT);",
+ size);
+ else
+ if (size == 0)
+ f_print(fout,
+ "\t\tbuf = XDR_INLINE(xdrs, (%s) * BYTES_PER_XDR_UNIT);",
+ sizestr);
+ else
+ f_print(fout,
+ "\t\tbuf = XDR_INLINE(xdrs, (%d + (%s)) * BYTES_PER_XDR_UNIT);",
+ size, sizestr);
+
+ f_print(fout, "\n\t\tif (buf == NULL) {\n");
+ psav = cur;
+ while (cur != NULL){
+ print_stat(indent + 2, &cur->decl);
+ cur = cur->next;
+ }
+ f_print(fout, "\t\t} else {\n");
+ cur = psav;
+ while (cur != dl){
+ emit_inline(indent + 2, &cur->decl, flag);
+ cur = cur->next;
+ }
+ f_print(fout, "\t\t}\n");
+ }
+}
static
emit_struct(def)
definition *def;
{
decl_list *dl;
+ int i, j, size, flag;
+ bas_type *ptr;
+ int can_inline;
+
+ if (inline == 0) {
+ /* No xdr_inlining at all */
+ for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
+ print_stat(1, &dl->decl);
+ return;
+ }
+
+ for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
+ if (dl->decl.rel == REL_VECTOR){
+ f_print(fout, "\tint i;\n");
+ break;
+ }
- for (dl = def->def.st.decls; dl != NULL; dl = dl->next) {
- print_stat(&dl->decl);
+ size = 0;
+ can_inline = 0;
+ /*
+ * Make a first pass and see if inling is possible.
+ */
+ for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
+ if ((dl->decl.prefix == NULL) &&
+ ((ptr = find_type(dl->decl.type)) != NULL) &&
+ ((dl->decl.rel == REL_ALIAS)||
+ (dl->decl.rel == REL_VECTOR))){
+ if (dl->decl.rel == REL_ALIAS)
+ size += ptr->length;
+ else {
+ can_inline = 1;
+ break; /* can be inlined */
+ }
+ } else {
+ if (size >= inline){
+ can_inline = 1;
+ break; /* can be inlined */
+ }
+ size = 0;
+ }
+ if (size >= inline)
+ can_inline = 1;
+
+ if (can_inline == 0){ /* can not inline, drop back to old mode */
+ for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
+ print_stat(1, &dl->decl);
+ return;
}
-}
+ flag = PUT;
+ for (j = 0; j < 2; j++){
+ inline_struct(def, flag);
+ if (flag == PUT)
+ flag = GET;
+ }
+
+ f_print(fout, "\t\treturn (TRUE);\n\t}\n\n");
+
+ /* now take care of XDR_FREE case */
+ for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
+ print_stat(1, &dl->decl);
+}
static
emit_typedef(def)
@@ -332,12 +635,9 @@ emit_typedef(def)
print_ifstat(1, prefix, type, rel, amax, "objp", def->def_name);
}
-
-
-
-
static
-print_stat(dec)
+print_stat(indent, dec)
+ int indent;
declaration *dec;
{
char *prefix = dec->prefix;
@@ -351,5 +651,102 @@ print_stat(dec)
} else {
s_print(name, "&objp->%s", dec->name);
}
- print_ifstat(1, prefix, type, rel, amax, name, dec->name);
+ print_ifstat(indent, prefix, type, rel, amax, name, dec->name);
+}
+
+
+char *upcase ();
+
+emit_inline(indent, decl, flag)
+int indent;
+declaration *decl;
+int flag;
+{
+ switch (decl->rel) {
+ case REL_ALIAS :
+ emit_single_in_line(indent, decl, flag, REL_ALIAS);
+ break;
+ case REL_VECTOR :
+ tabify(fout, indent);
+ f_print(fout, "{\n");
+ tabify(fout, indent + 1);
+ f_print(fout, "register %s *genp;\n\n", decl->type);
+ tabify(fout, indent + 1);
+ f_print(fout,
+ "for (i = 0, genp = objp->%s;\n", decl->name);
+ tabify(fout, indent + 2);
+ f_print(fout, "i < %s; i++) {\n", decl->array_max);
+ emit_single_in_line(indent + 2, decl, flag, REL_VECTOR);
+ tabify(fout, indent + 1);
+ f_print(fout, "}\n");
+ tabify(fout, indent);
+ f_print(fout, "}\n");
+ }
+}
+
+emit_single_in_line(indent, decl, flag, rel)
+int indent;
+declaration *decl;
+int flag;
+relation rel;
+{
+ char *upp_case;
+ int freed = 0;
+
+ tabify(fout, indent);
+ if (flag == PUT)
+ f_print(fout, "IXDR_PUT_");
+ else
+ if (rel == REL_ALIAS)
+ f_print(fout, "objp->%s = IXDR_GET_", decl->name);
+ else
+ f_print(fout, "*genp++ = IXDR_GET_");
+
+ upp_case = upcase(decl->type);
+
+ /* hack - XX */
+ if (strcmp(upp_case, "INT") == 0)
+ {
+ free(upp_case);
+ freed = 1;
+ upp_case = "LONG";
+ }
+
+ if (strcmp(upp_case, "U_INT") == 0)
+ {
+ free(upp_case);
+ freed = 1;
+ upp_case = "U_LONG";
+ }
+ if (flag == PUT)
+ if (rel == REL_ALIAS)
+ f_print(fout,
+ "%s(buf, objp->%s);\n", upp_case, decl->name);
+ else
+ f_print(fout, "%s(buf, *genp++);\n", upp_case);
+
+ else
+ f_print(fout, "%s(buf);\n", upp_case);
+ if (!freed)
+ free(upp_case);
+}
+
+char *upcase(str)
+char *str;
+{
+ char *ptr, *hptr;
+
+ ptr = (char *)malloc(strlen(str)+1);
+ if (ptr == (char *) NULL)
+ {
+ f_print(stderr, "malloc failed\n");
+ exit(1);
+ };
+
+ hptr = ptr;
+ while (*str != '\0')
+ *ptr++ = toupper(*str++);
+
+ *ptr = '\0';
+ return (hptr);
}
diff --git a/usr.bin/rpcgen/rpc_hout.c b/usr.bin/rpcgen/rpc_hout.c
index 8ccd433..ae73454 100644
--- a/usr.bin/rpcgen/rpc_hout.c
+++ b/usr.bin/rpcgen/rpc_hout.c
@@ -1,4 +1,3 @@
-/* @(#)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
@@ -27,31 +26,48 @@
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
+
+#ident "@(#)rpc_hout.c 1.16 94/04/25 SMI"
+
#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 $";
+static char sccsid[] = "@(#)rpc_hout.c 1.12 89/02/22 (C) 1987 SMI";
#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.
+ * 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"
+#include "rpc_util.h"
+
+void storexdrfuncdecl __P(( char *, int ));
+static int pconstdef __P(( definition * ));
+static int pstructdef __P(( definition * ));
+static int puniondef __P(( definition * ));
+static int pprogramdef __P(( definition * ));
+static int pstructdef __P(( definition * ));
+static int penumdef __P(( definition * ));
+static int ptypedef __P(( definition * ));
+static int pdefine __P(( char *, char * ));
+static int undefined2 __P(( char *, char * ));
+static int parglist __P(( proc_list *, char * ));
+
+static char RESULT[] = "clnt_res";
/*
- * Print the C-version of an xdr definition
+ * Print the C-version of an xdr definition
*/
void
print_datadef(def)
definition *def;
{
+
+ if (def->def_kind == DEF_PROGRAM) /* handle data only */
+ return;
+
if (def->def_kind != DEF_CONST) {
f_print(fout, "\n");
}
@@ -76,13 +92,71 @@ print_datadef(def)
break;
}
if (def->def_kind != DEF_PROGRAM && def->def_kind != DEF_CONST) {
- f_print(fout, "bool_t xdr_%s();\n", def->def_name);
+ storexdrfuncdecl(def->def_name,
+ def->def_kind != DEF_TYPEDEF ||
+ !isvectordef(def->def.ty.old_type,
+ def->def.ty.rel));
}
- if (def->def_kind != DEF_CONST) {
+}
+
+
+void
+print_funcdef(def)
+ definition *def;
+{
+ switch (def->def_kind) {
+ case DEF_PROGRAM:
f_print(fout, "\n");
+ pprogramdef(def);
+ break;
+ }
+}
+
+/* store away enough information to allow the XDR functions to be spat
+ out at the end of the file */
+
+void
+storexdrfuncdecl(name, pointerp)
+char *name;
+int pointerp;
+{
+ xdrfunc * xdrptr;
+
+ xdrptr = (xdrfunc *) malloc(sizeof (struct xdrfunc));
+
+ xdrptr->name = name;
+ xdrptr->pointerp = pointerp;
+ xdrptr->next = NULL;
+
+ if (xdrfunc_tail == NULL){
+ xdrfunc_head = xdrptr;
+ xdrfunc_tail = xdrptr;
+ } else {
+ xdrfunc_tail->next = xdrptr;
+ xdrfunc_tail = xdrptr;
}
+
+
}
+void
+print_xdr_func_def(name, pointerp, i)
+char* name;
+int pointerp;
+int i;
+{
+ if (i == 2) {
+ f_print(fout, "extern bool_t xdr_%s();\n", name);
+ return;
+ }
+ else
+ f_print(fout, "extern bool_t xdr_%s(XDR *, %s%s);\n", name,
+ name, pointerp ? "*" : "");
+
+
+}
+
+
static
pconstdef(def)
definition *def;
@@ -90,6 +164,43 @@ pconstdef(def)
pdefine(def->def_name, def->def.co);
}
+/* print out the definitions for the arguments of functions in the
+ header file
+*/
+static
+pargdef(def)
+ definition *def;
+{
+ decl_list *l;
+ version_list *vers;
+ char *name;
+ proc_list *plist;
+
+
+ for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) {
+ for (plist = vers->procs; plist != NULL;
+ plist = plist->next) {
+
+ if (!newstyle || plist->arg_num < 2) {
+ continue; /* old style or single args */
+ }
+ name = plist->args.argname;
+ f_print(fout, "struct %s {\n", name);
+ for (l = plist->args.decls;
+ l != NULL; l = l->next) {
+ pdeclaration(name, &l->decl, 1,
+ ";\n");
+ }
+ f_print(fout, "};\n");
+ f_print(fout, "typedef struct %s %s;\n",
+ name, name);
+ storexdrfuncdecl(name, 1);
+ f_print(fout, "\n");
+ }
+ }
+}
+
+
static
pstructdef(def)
definition *def;
@@ -99,7 +210,7 @@ pstructdef(def)
f_print(fout, "struct %s {\n", name);
for (l = def->def.st.decls; l != NULL; l = l->next) {
- pdeclaration(name, &l->decl, 1);
+ pdeclaration(name, &l->decl, 1, ";\n");
}
f_print(fout, "};\n");
f_print(fout, "typedef struct %s %s;\n", name, name);
@@ -122,25 +233,24 @@ puniondef(def)
}
f_print(fout, "\tunion {\n");
for (l = def->def.un.cases; l != NULL; l = l->next) {
- pdeclaration(name, &l->case_decl, 2);
+ 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);
+ 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
pdefine(name, num)
char *name;
char *num;
{
- f_print(fout, "#define %s %s\n", name, num);
+ f_print(fout, "#define\t%s %s\n", name, num);
}
static
@@ -148,7 +258,7 @@ puldefine(name, num)
char *name;
char *num;
{
- f_print(fout, "#define %s ((u_long)%s)\n", name, num);
+ f_print(fout, "#define\t%s ((unsigned long)(%s))\n", name, num);
}
static
@@ -172,6 +282,18 @@ define_printed(stop, start)
/* NOTREACHED */
}
+static
+pfreeprocdef(char * name, char *vers, int mode)
+{
+ f_print(fout, "extern int ");
+ pvname(name, vers);
+ if (mode == 1)
+ f_print(fout,"_freeresult(SVCXPRT *, xdrproc_t, caddr_t);\n");
+ else
+ f_print(fout,"_freeresult();\n");
+
+
+}
static
pprogramdef(def)
@@ -179,41 +301,141 @@ pprogramdef(def)
{
version_list *vers;
proc_list *proc;
+ int i;
+ char *ext;
+
+ pargdef(def);
puldefine(def->def_name, def->def.pr.prog_num);
for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) {
+ if (tblflag) {
+ f_print(fout,
+ "extern struct rpcgen_table %s_%s_table[];\n",
+ locase(def->def_name), vers->vers_num);
+ f_print(fout,
+ "extern %s_%s_nproc;\n",
+ locase(def->def_name), vers->vers_num);
+ }
puldefine(vers->vers_name, vers->vers_num);
- 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 2 definitions, one for ANSI-C, another for
+ * old K & R C
+ */
+
+ if(!Cflag){
+ ext = "extern ";
+ for (proc = vers->procs; proc != NULL;
+ proc = proc->next) {
+ if (!define_printed(proc,
+ def->def.pr.versions)) {
+ puldefine(proc->proc_name,
+ proc->proc_num);
+ }
+ f_print(fout, "%s", ext);
+ pprocdef(proc, vers, NULL, 0, 2);
+
+ if (mtflag) {
+ f_print(fout, "%s", ext);
+ pprocdef(proc, vers, NULL, 1, 2);
+ }
+ }
+ pfreeprocdef(def->def_name, vers->vers_num, 2);
+
+ } else {
+ for (i = 1; i < 3; i++){
+ if (i == 1){
+ f_print(fout, "\n#if defined(__STDC__) || defined(__cplusplus)\n");
+ ext = "extern ";
+ }else{
+ f_print(fout, "\n#else /* K&R C */\n");
+ ext = "extern ";
+ }
+
+ for (proc = vers->procs; proc != NULL;
+ proc = proc->next) {
+ if (!define_printed(proc,
+ def->def.pr.versions)) {
+ puldefine(proc->proc_name,
+ proc->proc_num);
+ }
+ f_print(fout, "%s", ext);
+ pprocdef(proc, vers, "CLIENT *", 0, i);
+ f_print(fout, "%s", ext);
+ pprocdef(proc, vers, "struct svc_req *", 1, i);
+ }
+ pfreeprocdef(def->def_name, vers->vers_num, i);
}
- pprocdef(proc, vers);
+ f_print(fout, "#endif /* K&R C */\n");
}
}
}
-
-pprocdef(proc, vp)
+pprocdef(proc, vp, addargtype, server_p, mode)
proc_list *proc;
version_list *vp;
+ char* addargtype;
+ int server_p;
+ int mode;
{
- f_print(fout, "extern ");
- if (proc->res_prefix) {
- if (streq(proc->res_prefix, "enum")) {
- f_print(fout, "enum ");
- } else {
- f_print(fout, "struct ");
+ if (mtflag) {/* Print MT style stubs */
+ 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);
+
+ /*
+ * mode 1 = ANSI-C, mode 2 = K&R C
+ */
+ if ( mode == 1)
+ parglist(proc, addargtype);
+ else
+ f_print(fout, "();\n");
+
+
+
+}
+
+
+
+/* print out argument list of procedure */
+static
+parglist(proc, addargtype)
+ proc_list *proc;
+ char* addargtype;
+{
+ decl_list *dl;
+
+ f_print(fout, "(");
+ if (proc->arg_num < 2 && newstyle &&
+ streq(proc->args.decls->decl.type, "void")) {
+ /* 0 argument in new style: do nothing*/
+ }
+ else {
+ for (dl = proc->args.decls; dl != NULL; dl = dl->next) {
+ ptype(dl->decl.prefix, dl->decl.type, 1);
+ if (!newstyle)
+ f_print(fout, "*");
+ /* old style passes by reference */
+ f_print(fout, ", ");
}
}
- 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));
+
+ if (mtflag) {
+ ptype(proc->res_prefix, proc->res_type, 1);
+ f_print(fout, "*, ");
}
- pvname(proc->proc_name, vp->vers_num);
- f_print(fout, "();\n");
+
+ f_print(fout, "%s);\n", addargtype);
+
}
static
@@ -239,7 +461,10 @@ penumdef(def)
f_print(fout, " = %s + %d", last, count++);
}
}
- f_print(fout, ",\n");
+ if (l->next)
+ f_print(fout, ",\n");
+ else
+ f_print(fout, "\n");
}
f_print(fout, "};\n");
f_print(fout, "typedef enum %s %s;\n", name, name);
@@ -285,19 +510,18 @@ ptypedef(def)
def->def.ty.array_max);
break;
case REL_ALIAS:
- f_print(fout, "%s%s %s", prefix, old, name);
+ f_print(fout, "%s%s %s", prefix, old, name);
break;
}
f_print(fout, ";\n");
}
}
-
-static
-pdeclaration(name, dec, tab)
+pdeclaration(name, dec, tab, separator)
char *name;
declaration *dec;
int tab;
+ char *separator;
{
char buf[8]; /* enough to hold "struct ", include NUL */
char *prefix;
@@ -341,17 +565,16 @@ pdeclaration(name, dec, tab)
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);
+ 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");
+ f_print(fout, separator);
}
-
-
static
undefined2(type, stop)
char *type;
diff --git a/usr.bin/rpcgen/rpc_main.c b/usr.bin/rpcgen/rpc_main.c
index 981c94d..6902530 100644
--- a/usr.bin/rpcgen/rpc_main.c
+++ b/usr.bin/rpcgen/rpc_main.c
@@ -1,4 +1,3 @@
-/* @(#)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
@@ -27,103 +26,243 @@
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
+
+
+#ident "@(#)rpc_main.c 1.21 94/04/25 SMI"
+
#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 $";
+static char sccsid[] = "@(#)rpc_main.c 1.30 89/03/30 (C) 1987 SMI";
#endif
/*
- * rpc_main.c, Top level of the RPC protocol compiler.
- * Copyright (C) 1987, Sun Microsystems, Inc.
+ * rpc_main.c, Top level of the RPC protocol compiler.
+ * Copyright (C) 1987, Sun Microsystems, Inc.
*/
#include <stdio.h>
-#include <strings.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/param.h>
#include <sys/file.h>
-#include "rpc_util.h"
+#include <sys/stat.h>
#include "rpc_parse.h"
+#include "rpc_util.h"
#include "rpc_scan.h"
-#define EXTEND 1 /* alias for TRUE */
+extern void write_sample_svc __P(( definition * ));
+extern int write_sample_clnt __P(( definition * ));
+extern void write_sample_clnt_main __P(( void ));
+static int c_output __P(( char *, char *, int, char * ));
+static int h_output __P(( char *, char *, int, char * ));
+static int l_output __P(( char *, char *, int, char * ));
+static int t_output __P(( char *, char *, int, char * ));
+static int clnt_output __P(( char *, char *, int, char * ));
+
+#ifndef __FreeBSD__
+char * rindex();
+#endif
+
+static int usage __P(( void ));
+static int options_usage __P (( void ));
+static int do_registers __P(( int, char ** ));
+static int parseargs __P(( int, char **, struct commandline * ));
+static int svc_output __P(( char *, char *, int, char * ));
+static void mkfile_output __P(( struct commandline * ));
+static int s_output __P(( int, char **, char *, char *, int, char *, int, int ));
+
+#define EXTEND 1 /* alias for TRUE */
+#define DONT_EXTEND 0 /* alias for FALSE */
+
+#define SVR4_CPP "/usr/ccs/lib/cpp"
+#ifdef __FreeBSD__
+#define SUNOS_CPP "/usr/libexec/cpp"
+#else
+#define SUNOS_CPP "/usr/lib/cpp"
+#endif
+
+static int cppDefined = 0; /* explicit path for C preprocessor */
-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 *svcclosetime = "120";
+static char *CPP = SVR4_CPP;
static char CPPFLAGS[] = "-C";
+static char pathbuf[MAXPATHLEN + 1];
static char *allv[] = {
"rpcgen", "-s", "udp", "-s", "tcp",
};
-static int allc = sizeof(allv)/sizeof(allv[0]);
+static int allc = sizeof (allv)/sizeof (allv[0]);
+static char *allnv[] = {
+ "rpcgen", "-s", "netpath",
+};
+static int allnc = sizeof (allnv)/sizeof (allnv[0]);
+
+/*
+ * machinations for handling expanding argument list
+ */
+static void addarg(); /* add another argument to the list */
+static void putarg(); /* put argument at specified location */
+static void clear_args(); /* clear argument list */
+static void checkfiles(); /* check if out file already exists */
+
+
+
+#define ARGLISTLEN 20
+#define FIXEDARGS 2
+static char *arglist[ARGLISTLEN];
+static int argcount = FIXEDARGS;
+
+
+int nonfatalerrors; /* errors */
+#ifdef __FreeBSD__
+int inetdflag = 0; /* Support for inetd is now the default */
+#else
+int inetdflag; /* Support for inetd is now the default */
+#endif
+int pmflag; /* Support for port monitors */
+int logflag; /* Use syslog instead of fprintf for errors */
+int tblflag; /* Support for dispatch table file */
+int mtflag = 0; /* Support for MT */
+#ifdef __FreeBSD__
+#define INLINE 0
+#else
+#define INLINE 5
+#endif
+/* length at which to start doing an inline */
+
+int inline = INLINE;
+/*
+ * Length at which to start doing an inline. INLINE = default
+ * if 0, no xdr_inline code
+ */
+
+int indefinitewait; /* If started by port monitors, hang till it wants */
+int exitnow; /* If started by port monitors, exit after the call */
+int timerflag; /* TRUE if !indefinite && !exitnow */
+int newstyle; /* newstyle of passing arguments (by value) */
+int Cflag = 0; /* ANSI C syntax */
+int CCflag = 0; /* C++ files */
+static int allfiles; /* generate all files */
+#ifdef __FreeBSD__
+int tirpcflag = 0; /* generating code for tirpc, by default */
+#else
+int tirpcflag = 1; /* generating code for tirpc, by default */
+#endif
+xdrfunc *xdrfunc_head = NULL; /* xdr function list */
+xdrfunc *xdrfunc_tail = NULL; /* xdr function list */
+pid_t childpid;
-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);
+ (void) memset((char *)&cmd, 0, sizeof (struct commandline));
+ clear_args();
+ if (!parseargs(argc, argv, &cmd))
+ usage();
+ /*
+ * Only the client and server side stubs are likely to be customized,
+ * so in that case only, check if the outfile exists, and if so,
+ * print an error message and exit.
+ */
+ if (cmd.Ssflag || cmd.Scflag || cmd.makefileflag) {
+ checkfiles(cmd.infile, cmd.outfile);
}
+ else
+ checkfiles(cmd.infile, NULL);
+
if (cmd.cflag) {
- c_output(cmd.infile, "-DRPC_XDR", !EXTEND, cmd.outfile);
+ c_output(cmd.infile, "-DRPC_XDR", DONT_EXTEND, cmd.outfile);
} else if (cmd.hflag) {
- h_output(cmd.infile, "-DRPC_HDR", !EXTEND, cmd.outfile);
+ h_output(cmd.infile, "-DRPC_HDR", DONT_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);
+ 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 if (cmd.makefileflag) {
+ mkfile_output(&cmd);
} 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();
- s_output(allc, allv, cmd.infile, "-DRPC_SVC", EXTEND,
- "_svc.c", cmd.mflag);
+ 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");
+ reinitialize();
+ clnt_output(cmd.infile, "-DRPC_CLIENT", EXTEND,
+ "_client.c");
+
+ }
+ if (allfiles || (cmd.makefileflag == 1)){
+ reinitialize();
+ mkfile_output(&cmd);
+ }
+
}
- exit(0);
+ exit(nonfatalerrors);
+ /* NOTREACHED */
}
+
/*
- * add extension to filename
+ * add extension to filename
*/
static char *
+#ifdef __FreeBSD__
+extendfile(path, ext)
+ char *path;
+#else
extendfile(file, ext)
char *file;
+#endif
char *ext;
{
char *res;
char *p;
+#ifdef __FreeBSD__
+ char *file;
+ if ((file = rindex(path, '/')) == NULL)
+ file = path;
+ else
+ file++;
+#endif
res = alloc(strlen(file) + strlen(ext) + 1);
if (res == NULL) {
abort();
}
- p = rindex(file, '.');
+ p = strrchr(file, '.');
if (p == NULL) {
p = file + strlen(file);
}
@@ -133,20 +272,22 @@ extendfile(file, ext)
}
/*
- * Open output file with given extension
+ * 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);
+ f_print(stderr, "%s: %s already exists. No output generated.\n",
+ cmdname, infile);
crash();
}
fout = fopen(outfile, "w");
@@ -156,10 +297,50 @@ open_output(infile, outfile)
crash();
}
record_open(outfile);
+
+}
+
+static
+add_warning()
+{
+ 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()
+{
+ int i;
+ for (i = FIXEDARGS; i < ARGLISTLEN; i++)
+ arglist[i] = NULL;
+ argcount = FIXEDARGS;
+}
+
+/* make sure that a CPP exists */
+static void find_cpp()
+{
+ struct stat buf;
+
+ if (stat(CPP, &buf) < 0) { /* SVR4 or explicit cpp does not exist */
+ if (cppDefined) {
+ fprintf(stderr,
+ "cannot find C preprocessor: %s \n", CPP);
+ crash();
+ } else { /* try the other one */
+ CPP = SUNOS_CPP;
+ if (stat(CPP, &buf) < 0) { /* can't find any cpp */
+ fprintf(stderr,
+ "cannot find any C preprocessor (cpp)\n");
+ crash();
+ }
+ }
+ }
}
/*
- * Open input file with given define for C-preprocessor
+ * Open input file with given define for C-preprocessor
*/
static
open_input(infile, define)
@@ -170,13 +351,20 @@ open_input(infile, define)
infilename = (infile == NULL) ? "<stdin>" : infile;
(void) pipe(pd);
- switch (fork()) {
+ switch (childpid = fork()) {
case 0:
+ find_cpp();
+ putarg(0, CPP);
+ putarg(1, CPPFLAGS);
+ addarg(define);
+ if (infile)
+ addarg(infile);
+ addarg((char *)NULL);
(void) close(1);
(void) dup2(pd[1], 1);
(void) close(pd[0]);
- execl(CPP, CPP, CPPFLAGS, define, infile, NULL);
- perror("execl");
+ execv(arglist[0], arglist);
+ perror("execv");
exit(1);
case -1:
perror("fork");
@@ -191,9 +379,59 @@ open_input(infile, define)
}
}
-/*
- * Compile into an XDR routine output file
- */
+/* valid tirpc nettypes */
+static char* valid_ti_nettypes[] =
+{
+ "netpath",
+ "visible",
+ "circuit_v",
+ "datagram_v",
+ "circuit_n",
+ "datagram_n",
+ "udp",
+ "tcp",
+ "raw",
+ NULL
+ };
+
+/* valid inetd nettypes */
+static char* valid_i_nettypes[] =
+{
+ "udp",
+ "tcp",
+ NULL
+ };
+
+static int check_nettype(name, list_to_check)
+char* name;
+char* list_to_check[];
+{
+ int i;
+ for (i = 0; list_to_check[i] != NULL; i++) {
+ if (strcmp(name, list_to_check[i]) == 0) {
+ return (1);
+ }
+ }
+ f_print(stderr, "illegal nettype :\'%s\'\n", name);
+ return (0);
+}
+
+static char *
+file_name(file, ext)
+char *file;
+char *ext;
+{
+ char *temp;
+ temp = extendfile(file, ext);
+
+ if (access(temp, F_OK) != -1)
+ return (temp);
+ else
+ return ((char *)" ");
+
+}
+
+
static
c_output(infile, define, extend, outfile)
char *infile;
@@ -206,14 +444,17 @@ c_output(infile, define, extend, outfile)
char *outfilename;
long tell;
- open_input(infile, define);
+ c_initialize();
+ open_input(infile, define);
outfilename = extend ? extendfile(infile, outfile) : outfile;
open_output(infile, outfilename);
- f_print(fout, "#include <rpc/rpc.h>\n");
+ 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()) {
emit(def);
@@ -223,9 +464,54 @@ c_output(infile, define, extend, outfile)
}
}
+
+c_initialize()
+{
+
+ /* 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");
+
+}
+
+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";
+
+
+char *generate_guard(pathname)
+ char* pathname;
+{
+ char* filename, *guard, *tmp;
+
+ filename = strrchr(pathname, '/'); /* find last component */
+ filename = ((filename == 0) ? pathname : filename+1);
+ guard = strdup(filename);
+ /* convert to upper case */
+ tmp = guard;
+ while (*tmp) {
+ if (islower(*tmp))
+ *tmp = toupper(*tmp);
+ tmp++;
+ }
+ guard = extendfile(guard, "_H_RPCGEN");
+ return (guard);
+}
+
/*
* Compile into an XDR header file
*/
+
+
static
h_output(infile, define, extend, outfile)
char *infile;
@@ -236,24 +522,113 @@ h_output(infile, define, extend, outfile)
definition *def;
char *outfilename;
long tell;
+ char *guard;
+ list *l;
+ xdrfunc *xdrfuncp;
+ int i;
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 = "STDIN_";
+
+ f_print(fout, "#ifndef _%s\n#define _%s\n\n", guard,
+ guard);
+
+ f_print(fout, "#include <rpc/rpc.h>\n");
+
+ if (mtflag) {
+ f_print(fout, "#include <synch.h>\n");
+ f_print(fout, "#include <thread.h>\n");
+ };
+
+ /* put the C++ support */
+ if (Cflag && !CCflag){
+ f_print(fout, "\n#ifdef __cplusplus\n");
+ f_print(fout, "extern \"C\" {\n");
+ f_print(fout, "#endif\n\n");
+ }
+
+ /* put in a typedef for quadprecision. Only with Cflag */
+
tell = ftell(fout);
+
+ /* print data definitions */
while (def = get_definition()) {
print_datadef(def);
}
+
+ /*
+ * print function declarations.
+ * Do this after data definitions because they might be used as
+ * arguments for functions
+ */
+ for (l = defined; l != NULL; l = l->next) {
+ print_funcdef(l->val);
+ }
+ /* Now print all xdr func declarations */
+ if (xdrfunc_head != NULL){
+
+ f_print(fout,
+ "\n/* the xdr functions */\n");
+
+ if (CCflag){
+ f_print(fout, "\n#ifdef __cplusplus\n");
+ f_print(fout, "extern \"C\" {\n");
+ f_print(fout, "#endif\n");
+ }
+
+ if (!Cflag){
+ xdrfuncp = xdrfunc_head;
+ while (xdrfuncp != NULL){
+ print_xdr_func_def(xdrfuncp->name,
+ xdrfuncp->pointerp, 2);
+ xdrfuncp = xdrfuncp->next;
+ }
+ } else {
+
+ for (i = 1; i < 3; i++){
+ if (i == 1)
+ f_print(fout, "\n#if defined(__STDC__) || defined(__cplusplus)\n");
+
+ else
+ f_print(fout, "\n#else /* K&R C */\n");
+
+ xdrfuncp = xdrfunc_head;
+ while (xdrfuncp != NULL){
+ print_xdr_func_def(xdrfuncp->name,
+ xdrfuncp->pointerp, i);
+ xdrfuncp = xdrfuncp->next;
+ }
+ }
+ f_print(fout, "\n#endif /* K&R C */\n");
+ }
+ }
+
if (extend && tell == ftell(fout)) {
(void) unlink(outfilename);
+ } else if (tblflag) {
+ f_print(fout, rpcgen_table_dcl);
}
+
+ if (Cflag){
+ f_print(fout, "\n#ifdef __cplusplus\n");
+ f_print(fout, "}\n");
+ f_print(fout, "#endif\n");
+ }
+
+ f_print(fout, "\n#endif /* !_%s */\n", guard);
}
/*
* Compile into an RPC service
*/
static
-s_output(argc, argv, infile, define, extend, outfile, nomain)
+s_output(argc, argv, infile, define, extend, outfile, nomain, netflag)
int argc;
char *argv[];
char *infile;
@@ -261,22 +636,80 @@ s_output(argc, argv, infile, define, extend, outfile, nomain)
int extend;
char *outfile;
int nomain;
+ int netflag;
{
char *include;
definition *def;
- int foundprogram;
+ int foundprogram = 0;
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");
+ add_warning();
if (infile && (include = extendfile(infile, ".h"))) {
f_print(fout, "#include \"%s\"\n", include);
free(include);
+ } else
+ f_print(fout, "#include <rpc/rpc.h>\n");
+
+ f_print(fout, "#include <stdio.h>\n");
+ f_print(fout, "#include <stdlib.h> /* getenv, exit */\n");
+ if (Cflag) {
+ f_print (fout,
+ "#include <rpc/pmap_clnt.h> /* for pmap_unset */\n");
+ f_print (fout, "#include <string.h> /* strcmp */\n");
+ }
+ if (strcmp(svcclosetime, "-1") == 0)
+ indefinitewait = 1;
+ else if (strcmp(svcclosetime, "0") == 0)
+ exitnow = 1;
+ else if (inetdflag || pmflag) {
+ f_print(fout, "#include <signal.h>\n");
+ timerflag = 1;
+ }
+
+ if (!tirpcflag && inetdflag)
+ f_print(fout, "#include <sys/ttycom.h> /* TIOCNOTTY */\n");
+ if (Cflag && (inetdflag || pmflag)) {
+ f_print(fout, "#ifdef __cplusplus\n");
+ f_print(fout,
+ "#include <sysent.h> /* getdtablesize, open */\n");
+ f_print(fout, "#endif /* __cplusplus */\n");
+ if (tirpcflag)
+ f_print(fout, "#include <unistd.h> /* setsid */\n");
+ }
+ if (tirpcflag)
+ f_print(fout, "#include <sys/types.h>\n");
+
+ f_print(fout, "#include <memory.h>\n");
+#ifdef __FreeBSD__
+ if (tirpcflag)
+#endif
+ f_print(fout, "#include <stropts.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 && !nomain) {
+ f_print(fout, "#include <netconfig.h>\n");
}
- foundprogram = 0;
+ if (tirpcflag)
+ f_print(fout, "#include <sys/resource.h> /* rlimit */\n");
+ if (logflag || inetdflag || pmflag)
+ f_print(fout, "#include <syslog.h>\n");
+
+ /* for ANSI-C */
+ if (Cflag)
+ f_print(fout,
+ "\n#ifndef SIG_PF\n#define SIG_PF void(*)\
+(int)\n#endif\n");
+
+ f_print(fout, "\n#ifdef DEBUG\n#define RPC_SVC_FG\n#endif\n");
+ if (timerflag)
+ f_print(fout, "\n#define _RPCSVC_CLOSEDOWN %s\n",
+ svcclosetime);
while (def = get_definition()) {
foundprogram |= (def->def_kind == DEF_PROGRAM);
}
@@ -284,16 +717,20 @@ s_output(argc, argv, infile, define, extend, outfile, nomain)
(void) unlink(outfilename);
return;
}
- if (nomain) {
- write_programs((char *)NULL);
- } else {
- write_most();
- do_registers(argc, argv);
+ write_most(infile, netflag, nomain);
+ if (!nomain) {
+ if (!do_registers(argc, argv)) {
+ if (outfilename)
+ (void) unlink(outfilename);
+ usage();
+ }
write_rest();
- write_programs("static");
}
}
+/*
+ * generate client side stubs
+ */
static
l_output(infile, define, extend, outfile)
char *infile;
@@ -303,18 +740,20 @@ l_output(infile, define, extend, outfile)
{
char *include;
definition *def;
- int foundprogram;
+ int foundprogram = 0;
char *outfilename;
open_input(infile, define);
outfilename = extend ? extendfile(infile, outfile) : outfile;
open_output(infile, outfilename);
- f_print(fout, "#include <rpc/rpc.h>\n");
+ add_warning();
+ if (Cflag)
+ f_print (fout, "#include <memory.h> /* for memset */\n");
if (infile && (include = extendfile(infile, ".h"))) {
f_print(fout, "#include \"%s\"\n", include);
free(include);
- }
- foundprogram = 0;
+ } else
+ f_print(fout, "#include <rpc/rpc.h>\n");
while (def = get_definition()) {
foundprogram |= (def->def_kind == DEF_PROGRAM);
}
@@ -326,38 +765,329 @@ l_output(infile, define, extend, outfile)
}
/*
- * Perform registrations for service output
+ * generate the dispatch table
+ */
+static
+t_output(infile, define, extend, outfile)
+ char *infile;
+ char *define;
+ int extend;
+ char *outfile;
+{
+ definition *def;
+ int foundprogram = 0;
+ char *outfilename;
+
+ open_input(infile, define);
+ outfilename = extend ? extendfile(infile, outfile) : outfile;
+ open_output(infile, outfilename);
+ add_warning();
+ while (def = get_definition()) {
+ foundprogram |= (def->def_kind == DEF_PROGRAM);
+ }
+ if (extend && !foundprogram) {
+ (void) unlink(outfilename);
+ return;
+ }
+ write_tables();
+}
+
+/* sample routine for the server template */
+static
+svc_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;
+ 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()) {
+ write_sample_svc(def);
+ }
+ if (extend && tell == ftell(fout)) {
+ (void) unlink(outfilename);
+ }
+}
+
+/* sample main routine for client */
+static
+clnt_output(infile, define, extend, outfile)
+ char *infile;
+ char *define;
+ int extend;
+ char *outfile;
+{
+ definition *def;
+ char *include;
+ char *outfilename;
+ long tell;
+ int has_program = 0;
+
+ open_input(infile, define);
+ outfilename = extend ? extendfile(infile, outfile) : outfile;
+ checkfiles(infile, outfilename);
+ /*
+ * Check if outfile already exists.
+ * if so, print an error message and exit
+ */
+
+ open_output(infile, outfilename);
+ add_sample_msg();
+ if (infile && (include = extendfile(infile, ".h"))) {
+ f_print(fout, "#include \"%s\"\n", include);
+ free(include);
+ } else
+ f_print(fout, "#include <rpc/rpc.h>\n");
+ tell = ftell(fout);
+ while (def = get_definition()) {
+ has_program += write_sample_clnt(def);
+ }
+
+ if (has_program)
+ write_sample_clnt_main();
+
+ if (extend && tell == ftell(fout)) {
+ (void) unlink(outfilename);
+ }
+}
+
+
+static void mkfile_output(cmd)
+struct commandline *cmd;
+{
+ char *mkfilename, *clientname, *clntname, *xdrname, *hdrname;
+ char *servername, *svcname, *servprogname, *clntprogname;
+ char *temp;
+
+ svcname = file_name(cmd->infile, "_svc.c");
+ clntname = file_name(cmd->infile, "_clnt.c");
+ xdrname = file_name(cmd->infile, "_xdr.c");
+ hdrname = file_name(cmd->infile, ".h");
+
+
+ if (allfiles){
+ servername = extendfile(cmd->infile, "_server.c");
+ clientname = extendfile(cmd->infile, "_client.c");
+ }else{
+ servername = " ";
+ clientname = " ";
+ }
+ servprogname = extendfile(cmd->infile, "_server");
+ clntprogname = extendfile(cmd->infile, "_client");
+
+ if (allfiles){
+ mkfilename = alloc(strlen("makefile.") +
+ strlen(cmd->infile) + 1);
+ temp = (char *)rindex(cmd->infile, '.');
+ strcat(mkfilename, "makefile.");
+ (void) strncat(mkfilename, cmd->infile,
+ (temp - cmd->infile));
+ } else
+ mkfilename = cmd->outfile;
+
+
+ checkfiles(NULL, mkfilename);
+ open_output(NULL, mkfilename);
+
+ f_print(fout, "\n# This is a template makefile generated\
+ by rpcgen \n");
+
+ f_print(fout, "\n# Parameters \n\n");
+
+ f_print(fout, "CLIENT = %s\nSERVER = %s\n\n",
+ clntprogname, servprogname);
+ f_print(fout, "SOURCES_CLNT.c = \nSOURCES_CLNT.h = \n");
+ f_print(fout, "SOURCES_SVC.c = \nSOURCES_SVC.h = \n");
+ f_print(fout, "SOURCES.x = %s\n\n", cmd->infile);
+ f_print(fout, "TARGETS_SVC.c = %s %s %s \n",
+ svcname, servername, xdrname);
+ f_print(fout, "TARGETS_CLNT.c = %s %s %s \n",
+ clntname, clientname, xdrname);
+ f_print(fout, "TARGETS = %s %s %s %s %s %s\n\n",
+ hdrname, xdrname, clntname,
+ svcname, clientname, servername);
+
+ f_print(fout, "OBJECTS_CLNT = $(SOURCES_CLNT.c:%%.c=%%.o) \
+$(TARGETS_CLNT.c:%%.c=%%.o) ");
+
+ f_print(fout, "\nOBJECTS_SVC = $(SOURCES_SVC.c:%%.c=%%.o) \
+$(TARGETS_SVC.c:%%.c=%%.o) ");
+
+
+ f_print(fout, "\n# Compiler flags \n");
+ if (mtflag)
+ f_print(fout, "\nCPPFLAGS += -D_REENTRANT\nCFLAGS += -g \nLDLIBS += -lnsl -lthread\n");
+ else
+#ifdef __FreeBSD__
+ f_print(fout, "\nCFLAGS += -g \nLDLIBS +=\n");
+#else
+ f_print(fout, "\nCFLAGS += -g \nLDLIBS += -lnsl\n");
+#endif
+ f_print(fout, "RPCGENFLAGS = \n");
+
+ f_print(fout, "\n# Targets \n\n");
+
+ f_print(fout, "all : $(CLIENT) $(SERVER)\n\n");
+ f_print(fout, "$(TARGETS) : $(SOURCES.x) \n");
+ f_print(fout, "\trpcgen $(RPCGENFLAGS) $(SOURCES.x)\n\n");
+ f_print(fout, "$(OBJECTS_CLNT) : $(SOURCES_CLNT.c) $(SOURCES_CLNT.h) \
+$(TARGETS_CLNT.c) \n\n");
+
+ f_print(fout, "$(OBJECTS_SVC) : $(SOURCES_SVC.c) $(SOURCES_SVC.h) \
+$(TARGETS_SVC.c) \n\n");
+ f_print(fout, "$(CLIENT) : $(OBJECTS_CLNT) \n");
+#ifdef __FreeBSD__
+ f_print(fout, "\t$(CC) -o $(CLIENT) $(OBJECTS_CLNT) \
+$(LDLIBS) \n\n");
+#else
+ f_print(fout, "\t$(LINK.c) -o $(CLIENT) $(OBJECTS_CLNT) \
+$(LDLIBS) \n\n");
+#endif
+ f_print(fout, "$(SERVER) : $(OBJECTS_SVC) \n");
+#ifdef __FreeBSD__
+ f_print(fout, "\t$(CC) -o $(SERVER) $(OBJECTS_SVC) $(LDLIBS)\n\n ");
+ f_print(fout, "clean:\n\t $(RM) -f core $(TARGETS) $(OBJECTS_CLNT) \
+$(OBJECTS_SVC) $(CLIENT) $(SERVER)\n\n");
+#else
+ f_print(fout, "\t$(LINK.c) -o $(SERVER) $(OBJECTS_SVC) $(LDLIBS)\n\n ");
+ f_print(fout, "clean:\n\t $(RM) core $(TARGETS) $(OBJECTS_CLNT) \
+$(OBJECTS_SVC) $(CLIENT) $(SERVER)\n\n");
+#endif
+}
+
+
+
+/*
+ * Perform registrations for service output
+ * Return 0 if failed; 1 otherwise.
*/
static
-do_registers(argc, argv)
+int 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++;
+ 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(cp)
+ char *cp;
+{
+ if (argcount >= ARGLISTLEN) {
+ f_print(stderr, "rpcgen: too many defines\n");
+ crash();
+ /*NOTREACHED*/
+ }
+ arglist[argcount++] = cp;
+
+}
+
+static void
+putarg(where, cp)
+ char *cp;
+ int where;
+{
+ if (where >= ARGLISTLEN) {
+ f_print(stderr, "rpcgen: arglist coding error\n");
+ crash();
+ /*NOTREACHED*/
+ }
+ arglist[where] = cp;
+}
+
+/*
+ * if input file is stdin and an output file is specified then complain
+ * if the file already exists. Otherwise the file may get overwritten
+ * If input file does not exist, exit with an error
+ */
+
+static void
+checkfiles(infile, outfile)
+char *infile;
+char *outfile;
+{
+
+ struct stat buf;
+
+ if (infile) /* infile ! = NULL */
+ if (stat(infile, &buf) < 0)
+ {
+ perror(infile);
+ crash();
+ };
+ if (outfile) {
+ if (stat(outfile, &buf) < 0)
+ return; /* file does not exist */
+ else {
+ f_print(stderr,
+ "file '%s' already exists and may be overwritten\n",
+ outfile);
+ crash();
}
}
}
/*
- * Parse command line arguments
+ * 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))];
+ char c, ch;
+ char flag[(1 << 8 * sizeof (char))];
int nflags;
cmdname = argv[0];
@@ -365,15 +1095,25 @@ parseargs(argc, argv, cmd)
if (argc < 2) {
return (0);
}
+ allfiles = 0;
flag['c'] = 0;
flag['h'] = 0;
- flag['s'] = 0;
- flag['o'] = 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;
+ flag['M'] = 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];
@@ -381,18 +1121,93 @@ parseargs(argc, argv, cmd)
for (j = 1; argv[i][j] != 0; j++) {
c = argv[i][j];
switch (c) {
+ case 'a':
+ allfiles = 1;
+ break;
case 'c':
case 'h':
case 'l':
case 'm':
+ case 't':
if (flag[c]) {
return (0);
}
flag[c] = 1;
break;
+ case 'S':
+ /*
+ * sample flag: Ss or Sc.
+ * Ss means set flag['S'];
+ * Sc means set flag['C'];
+ * Sm means set flag['M'];
+ */
+ ch = argv[i][++j]; /* get next char */
+ if (ch == 's')
+ ch = 'S';
+ else if (ch == 'c')
+ ch = 'C';
+ else if (ch == 'm')
+ ch = 'M';
+ else
+ return (0);
+
+ if (flag[ch]) {
+ return (0);
+ }
+ flag[ch] = 1;
+ break;
+ case 'C': /* ANSI C syntax */
+ Cflag = 1;
+ ch = argv[i][j+1]; /* get next char */
+
+ if (ch != 'C')
+ break;
+ CCflag = 1;
+ break;
+ case 'b':
+ /*
+ * Turn TIRPC flag off for
+ * generating backward compatible
+ * code
+ */
+#ifdef __FreeBSD__
+ tirpcflag = 1;
+#else
+ tirpcflag = 0;
+#endif
+ break;
+
+ case 'I':
+ inetdflag = 1;
+ break;
+ case 'N':
+ newstyle = 1;
+ break;
+ case 'L':
+ logflag = 1;
+ break;
+ case 'K':
+ if (++i == argc) {
+ return (0);
+ }
+ svcclosetime = argv[i];
+ goto nextarg;
+ case 'T':
+ tblflag = 1;
+ break;
+ case 'M':
+ mtflag = 1;
+ break;
+ case 'i' :
+ if (++i == argc) {
+ return (0);
+ }
+ inline = atoi(argv[i]);
+ goto nextarg;
+ case 'n':
case 'o':
case 's':
- if (argv[i][j - 1] != '-' ||
+ if (argv[i][j - 1] != '-' ||
argv[i][j + 1] != 0) {
return (0);
}
@@ -400,39 +1215,167 @@ parseargs(argc, argv, cmd)
if (++i == argc) {
return (0);
}
- if (c == 's') {
- if (!streq(argv[i], "udp") &&
- !streq(argv[i], "tcp")) {
- return (0);
- }
- } else if (c == 'o') {
+ if (c == 'o') {
if (cmd->outfile) {
return (0);
}
cmd->outfile = argv[i];
}
goto nextarg;
+ case 'D':
+ if (argv[i][j - 1] != '-') {
+ return (0);
+ }
+ (void) addarg(argv[i]);
+ goto nextarg;
+ case 'Y':
+ if (++i == argc) {
+ return (0);
+ }
+ (void) strcpy(pathbuf, argv[i]);
+ (void) strcat(pathbuf, "/cpp");
+ CPP = pathbuf;
+ cppDefined = 1;
+ goto nextarg;
+
+
default:
return (0);
}
}
- nextarg:
+ 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;
+ cmd->nflag = flag['n'];
+ cmd->sflag = flag['s'];
+ cmd->tflag = flag['t'];
+ cmd->Ssflag = flag['S'];
+ cmd->Scflag = flag['C'];
+ cmd->makefileflag = flag['M'];
+
+ 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 */
+#ifndef __FreeBSD__
+ inetdflag = 1; /* inetdflag is TRUE by default */
+#endif
+ 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 + cmd->makefileflag;
+
if (nflags == 0) {
if (cmd->outfile != NULL || cmd->infile == NULL) {
return (0);
}
- } else if (nflags > 1) {
+ } else if (cmd->infile == NULL &&
+ (cmd->Ssflag || cmd->Scflag || cmd->makefileflag)) {
+ f_print(stderr,
+ "\"infile\" is required for template generation flags.\n");
+ return (0);
+ } if (nflags > 1) {
+ f_print(stderr,
+ "Cannot have more than one file generation flag.\n");
return (0);
}
return (1);
}
+
+static
+usage()
+{
+ f_print(stderr, "usage: %s infile\n", cmdname);
+ f_print(stderr,
+ "\t%s [-abCLNTM] [-Dname[=value]] [-i size]\
+[-I [-K seconds]] [-Y path] infile\n",
+ cmdname);
+ f_print(stderr,
+ "\t%s [-c | -h | -l | -m | -t | -Sc | -Ss | -Sm]\
+[-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
+options_usage()
+{
+ f_print(stderr, "options:\n");
+ f_print(stderr, "-a\t\tgenerate all files, including samples\n");
+ f_print(stderr, "-b\t\tbackward compatibility mode (generates code\
+for SunOS 4.X)\n");
+ f_print(stderr, "-c\t\tgenerate XDR routines\n");
+ f_print(stderr, "-C\t\tANSI C mode\n");
+ f_print(stderr, "-Dname[=value]\tdefine a symbol (same as #define)\n");
+ f_print(stderr, "-h\t\tgenerate header file\n");
+ f_print(stderr, "-i size\t\tsize at which to start generating\
+inline code\n");
+ f_print(stderr, "-I\t\tgenerate code for inetd support in server\
+(for SunOS 4.X)\n");
+ f_print(stderr, "-K seconds\tserver exits after K seconds of\
+inactivity\n");
+ f_print(stderr, "-l\t\tgenerate client side stubs\n");
+ f_print(stderr, "-L\t\tserver errors will be printed to syslog\n");
+ f_print(stderr, "-m\t\tgenerate server side stubs\n");
+ f_print(stderr, "-M\t\tgenerate MT-safe code\n");
+ f_print(stderr, "-n netid\tgenerate server code that supports\
+named netid\n");
+ f_print(stderr, "-N\t\tsupports multiple arguments and\
+call-by-value\n");
+ f_print(stderr, "-o outfile\tname of the output file\n");
+ f_print(stderr, "-s nettype\tgenerate server code that supports named\
+nettype\n");
+ f_print(stderr, "-Sc\t\tgenerate sample client code that uses remote\
+procedures\n");
+ f_print(stderr, "-Ss\t\tgenerate sample server code that defines\
+remote procedures\n");
+ f_print(stderr, "-Sm \t\tgenerate makefile template \n");
+
+ f_print(stderr, "-t\t\tgenerate RPC dispatch table\n");
+ f_print(stderr, "-T\t\tgenerate code to support RPC dispatch tables\n");
+ f_print(stderr, "-Y path\t\tpath where cpp is found\n");
+ exit(1);
+}
+
+#ifndef __FreeBSD__
+char *
+rindex(sp, c)
+ register char *sp, c;
+{
+ register char *r;
+
+ r = NULL;
+ do {
+ if (*sp == c)
+ r = sp;
+ } while (*sp++);
+ return (r);
+}
+#endif
diff --git a/usr.bin/rpcgen/rpc_parse.c b/usr.bin/rpcgen/rpc_parse.c
index b780851..fb8eec1 100644
--- a/usr.bin/rpcgen/rpc_parse.c
+++ b/usr.bin/rpcgen/rpc_parse.c
@@ -1,4 +1,3 @@
-/* @(#)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
@@ -27,23 +26,43 @@
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
+
+#ident "@(#)rpc_parse.c 1.12 93/07/05 SMI"
+
#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 $";
+static char sccsid[] = "@(#)rpc_parse.c 1.8 89/02/22 (C) 1987 SMI";
#endif
/*
- * rpc_parse.c, Parser for the RPC protocol compiler
+ * rpc_parse.c, Parser for the RPC protocol compiler
* Copyright (C) 1987 Sun Microsystems, Inc.
*/
#include <stdio.h>
-#include "rpc_util.h"
+#include <string.h>
+#include "rpc/types.h"
#include "rpc_scan.h"
#include "rpc_parse.h"
+#include "rpc_util.h"
+
+#define ARGNAME "arg"
+
+extern char *make_argname __P(( char *, char * ));
+static int isdefined __P(( definition * ));
+static int def_struct __P(( definition * ));
+static int def_program __P(( definition * ));
+static int def_enum __P(( definition * ));
+static int def_const __P(( definition * ));
+static int def_union __P(( definition * ));
+static int def_typedef __P(( definition * ));
+static int get_declaration __P(( declaration *, defkind ));
+static int get_prog_declaration __P(( declaration *, defkind, int ));
+static int get_type __P(( char **, char **, defkind ));
+static int unsigned_dec __P(( char ** ));
+
+#ifndef __FreeBSD__
+extern char *strdup();
+#endif
-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
*/
@@ -76,7 +95,6 @@ get_definition()
break;
case TOK_EOF:
return (NULL);
- break;
default:
error("definition keyword expected");
}
@@ -92,7 +110,6 @@ isdefined(defp)
STOREVAL(&defined, defp);
}
-
static
def_struct(defp)
definition *defp;
@@ -126,16 +143,21 @@ def_program(defp)
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);
@@ -144,33 +166,75 @@ def_program(defp)
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);
+ 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");
+ /* 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);
@@ -180,6 +244,7 @@ def_program(defp)
*vtailp = NULL;
}
+
static
def_enum(defp)
definition *defp;
@@ -230,8 +295,9 @@ def_union(defp)
{
token tok;
declaration dec;
- case_list *cases;
+ case_list *cases, *tcase;
case_list **tailp;
+ int flag;
defp->def_kind = DEF_UNION;
scan(TOK_IDENT, &tok);
@@ -245,15 +311,40 @@ def_union(defp)
scan(TOK_LBRACE, &tok);
scan(TOK_CASE, &tok);
while (tok.kind == TOK_CASE) {
- scan(TOK_IDENT, &tok);
+ scan2(TOK_IDENT, TOK_CHARCONST, &tok);
cases = ALLOC(case_list);
cases->case_name = tok.str;
scan(TOK_COLON, &tok);
+ /* now peek at next token */
+ flag = 0;
+ 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));
+ }
+ else
+ if (flag)
+ {
+
+ *tailp = cases;
+ tailp = &cases->next;
+ cases = ALLOC(case_list);
+ };
+
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;
@@ -269,6 +360,62 @@ def_union(defp)
}
}
+static char* reserved_words[] =
+{
+ "array",
+ "bytes",
+ "destroy",
+ "free",
+ "getpos",
+ "inline",
+ "pointer",
+ "reference",
+ "setpos",
+ "sizeof",
+ "union",
+ "vector",
+ NULL
+ };
+
+static char* reserved_types[] =
+{
+ "opaque",
+ "string",
+ NULL
+ };
+
+/*
+ * check that the given name is not one that would eventually result in
+ * xdr routines that would conflict with internal XDR routines.
+ */
+static check_type_name(name, new_type)
+int new_type;
+char* name;
+{
+ int i;
+ char tmp[100];
+
+ for (i = 0; reserved_words[i] != NULL; i++) {
+ if (strcmp(name, reserved_words[i]) == 0) {
+ sprintf(tmp,
+ "illegal (reserved) name :\'%s\' in type definition",
+ name);
+ error(tmp);
+ }
+ }
+ if (new_type) {
+ for (i = 0; reserved_types[i] != NULL; i++) {
+ if (strcmp(name, reserved_types[i]) == 0) {
+ sprintf(tmp,
+ "illegal (reserved) name :\'%s\' in type definition",
+ name);
+ error(tmp);
+ }
+ }
+ }
+}
+
+
static
def_typedef(defp)
@@ -279,13 +426,13 @@ def_typedef(defp)
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
get_declaration(dec, dkind)
declaration *dec;
@@ -298,6 +445,8 @@ get_declaration(dec, dkind)
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;
@@ -338,6 +487,79 @@ get_declaration(dec, dkind)
static
+get_prog_declaration(dec, dkind, num)
+ declaration *dec;
+ defkind dkind;
+ int num; /* arg number */
+{
+ token tok;
+ char name[10]; /* argument name */
+
+ if (dkind == DEF_PROGRAM) {
+ peek(&tok);
+ if (tok.kind == TOK_RPAREN) { /* no arguments */
+ dec->rel = REL_ALIAS;
+ dec->type = "void";
+ dec->prefix = NULL;
+ dec->name = NULL;
+ return;
+ }
+ }
+ get_type(&dec->prefix, &dec->type, dkind);
+ dec->rel = REL_ALIAS;
+ if (peekscan(TOK_IDENT, &tok)) /* optional name of argument */
+ strcpy(name, tok.str);
+ else
+ sprintf(name, "%s%d", ARGNAME, num);
+ /* default name of argument */
+
+ dec->name = (char *) strdup(name);
+ if (streq(dec->type, "void")) {
+ return;
+ }
+
+ if (streq(dec->type, "opaque")) {
+ error("opaque -- illegal argument type");
+ }
+ if (peekscan(TOK_STAR, &tok)) {
+ if (streq(dec->type, "string")) {
+ error("pointer to string not allowed in program arguments\n");
+ }
+ dec->rel = REL_POINTER;
+ if (peekscan(TOK_IDENT, &tok))
+ /* optional name of argument */
+ dec->name = strdup(tok.str);
+ }
+ if (peekscan(TOK_LANGLE, &tok)) {
+ if (!streq(dec->type, "string")) {
+ error("arrays cannot be declared as arguments to procedures -- use typedef");
+ }
+ dec->rel = REL_ARRAY;
+ if (peekscan(TOK_RANGLE, &tok)) {
+ dec->array_max = "~0";
+ /* unspecified size, use max */
+ } else {
+ scan_num(&tok);
+ dec->array_max = tok.str;
+ scan(TOK_RANGLE, &tok);
+ }
+ }
+ if (streq(dec->type, "string")) {
+ if (dec->rel != REL_ARRAY) {
+ /*
+ * .x specifies just string as
+ * type of argument
+ * - make it string<>
+ */
+ dec->rel = REL_ARRAY;
+ dec->array_max = "~0"; /* unspecified size, use max */
+ }
+ }
+}
+
+
+
+static
get_type(prefixp, typep, dkind)
char **prefixp;
char **typep;
@@ -369,9 +591,14 @@ get_type(prefixp, typep, dkind)
*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("voids allowed only inside union and program definitions");
+ error("voids allowed only inside union and program definitions with one argument");
}
*typep = tok.str;
break;
@@ -382,6 +609,7 @@ get_type(prefixp, typep, dkind)
case TOK_FLOAT:
case TOK_DOUBLE:
case TOK_BOOL:
+ case TOK_QUAD:
*typep = tok.str;
break;
default:
@@ -389,7 +617,6 @@ get_type(prefixp, typep, dkind)
}
}
-
static
unsigned_dec(typep)
char **typep;
@@ -412,6 +639,11 @@ unsigned_dec(typep)
*typep = "u_long";
(void) peekscan(TOK_INT, &tok);
break;
+ case TOK_HYPER:
+ get_token(&tok);
+ *typep = "ulonglong_t";
+ (void) peekscan(TOK_INT, &tok);
+ break;
case TOK_INT:
get_token(&tok);
*typep = "u_int";
diff --git a/usr.bin/rpcgen/rpc_parse.h b/usr.bin/rpcgen/rpc_parse.h
index 0a4eb1e..b61db9d 100644
--- a/usr.bin/rpcgen/rpc_parse.h
+++ b/usr.bin/rpcgen/rpc_parse.h
@@ -25,14 +25,42 @@
* 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 $
*/
+#pragma ident "@(#)rpc_parse.h 1.10 94/05/15 SMI"
+
+/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
+/* All Rights Reserved */
+
+/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
+/* The copyright notice above does not evidence any */
+/* actual or intended publication of such source code. */
+
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+* PROPRIETARY NOTICE (Combined)
+*
+* This source code is unpublished proprietary information
+* constituting, or derived under license from AT&T's UNIX(r) System V.
+* In addition, portions of such source code were derived from Berkeley
+* 4.3 BSD under license from the Regents of the University of
+* California.
+*
+*
+*
+* Copyright Notice
+*
+* Notice of copyright on this source code product does not indicate
+* publication.
+*
+* (c) 1986,1987,1988.1989 Sun Microsystems, Inc
+* (c) 1983,1984,1985,1986,1987,1988,1989 AT&T.
+* All rights reserved.
+*/
+
+/* @(#)rpc_parse.h 1.3 90/08/29 (C) 1987 SMI */
/*
* rpc_parse.h, Definitions for the RPCL parser
- * Copyright (C) 1987, Sun Microsystems, Inc.
*/
enum defkind {
@@ -63,7 +91,6 @@ struct typedef_def {
};
typedef struct typedef_def typedef_def;
-
struct enumval_list {
char *name;
char *assignment;
@@ -76,7 +103,6 @@ struct enum_def {
};
typedef struct enum_def enum_def;
-
struct declaration {
char *prefix;
char *type;
@@ -86,7 +112,6 @@ struct declaration {
};
typedef struct declaration declaration;
-
struct decl_list {
declaration decl;
struct decl_list *next;
@@ -98,9 +123,9 @@ struct struct_def {
};
typedef struct struct_def struct_def;
-
struct case_list {
char *case_name;
+ int contflag;
declaration case_decl;
struct case_list *next;
};
@@ -113,20 +138,24 @@ struct union_def {
};
typedef struct union_def union_def;
-
+struct arg_list {
+ char *argname; /* name of struct for arg*/
+ decl_list *decls;
+};
+
+typedef struct arg_list arg_list;
struct proc_list {
char *proc_name;
char *proc_num;
- char *arg_type;
- char *arg_prefix;
+ arg_list args;
+ int arg_num;
char *res_type;
char *res_prefix;
struct proc_list *next;
};
typedef struct proc_list proc_list;
-
struct version_list {
char *vers_name;
char *vers_num;
@@ -155,5 +184,14 @@ struct definition {
};
typedef struct definition definition;
-/* @(#)rpc_parse.h 2.1 88/08/01 4.0 RPCSRC */
definition *get_definition();
+
+
+struct bas_type
+{
+ char *name;
+ int length;
+ struct bas_type *next;
+};
+
+typedef struct bas_type bas_type;
diff --git a/usr.bin/rpcgen/rpc_sample.c b/usr.bin/rpcgen/rpc_sample.c
new file mode 100644
index 0000000..435bb44
--- /dev/null
+++ b/usr.bin/rpcgen/rpc_sample.c
@@ -0,0 +1,311 @@
+/*
+ * 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
+ */
+
+#pragma ident "@(#)rpc_sample.c 1.9 94/04/25 SMI"
+
+/*
+ * rpc_sample.c, Sample client-server code outputter for the RPC protocol compiler
+ * Copyright (C) 1987, Sun Microsystems, Inc.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "rpc_parse.h"
+#include "rpc_util.h"
+
+
+static char RQSTP[] = "rqstp";
+
+extern void printarglist __P(( proc_list *, char *, char *, char *));
+static int write_sample_client __P(( char *, version_list * ));
+static int write_sample_server __P(( definition * ));
+static int return_type __P(( proc_list * ));
+
+void
+write_sample_svc(def)
+ definition *def;
+{
+
+ if (def->def_kind != DEF_PROGRAM)
+ return;
+ write_sample_server(def);
+}
+
+
+int
+write_sample_clnt(def)
+ 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
+write_sample_client(program_name, vp)
+ char *program_name;
+ version_list *vp;
+{
+ proc_list *proc;
+ int i;
+ decl_list *l;
+
+ f_print(fout, "\n\nvoid\n");
+ pvname(program_name, vp->vers_num);
+ if(Cflag)
+ f_print(fout,"(char *host)\n{\n");
+ else
+ f_print(fout, "(host)\n\tchar *host;\n{\n");
+ f_print(fout, "\tCLIENT *clnt;\n");
+
+ i = 0;
+ for (proc = vp->procs; proc != NULL; proc = proc->next) {
+ f_print(fout, "\t");
+ if (mtflag) {
+ f_print(fout, "enum clnt_stat retval_%d;\n\t", ++i);
+ ptype(proc->res_prefix, proc->res_type, 1);
+ f_print(fout, "result_%d;\n", i);
+ } else {
+ ptype(proc->res_prefix, proc->res_type, 1);
+ f_print(fout, " *result_%d;\n",++i);
+ }
+ /* print out declarations for arguments */
+ if(proc->arg_num < 2 && !newstyle) {
+ f_print(fout, "\t");
+ if(!streq(proc->args.decls->decl.type, "void"))
+ ptype(proc->args.decls->decl.prefix,
+ proc->args.decls->decl.type, 1);
+ else
+ f_print(fout, "char * "); /* cannot have "void" type */
+ f_print(fout, " ");
+ pvname(proc->proc_name, vp->vers_num);
+ f_print(fout, "_arg;\n");
+ } else if (!streq(proc->args.decls->decl.type, "void")) {
+ for (l = proc->args.decls; l != NULL; l = l->next) {
+ f_print(fout, "\t");
+ ptype(l->decl.prefix, l->decl.type, 1);
+ if (strcmp(l->decl.type,"string") == 1)
+ f_print(fout, " ");
+ pvname(proc->proc_name, vp->vers_num);
+ f_print(fout, "_%s;\n", l->decl.name);
+ }
+ }
+ }
+
+ /* generate creation of client handle */
+ f_print(fout, "\n#ifndef\tDEBUG\n");
+ f_print(fout, "\tclnt = clnt_create(host, %s, %s, \"%s\");\n",
+ program_name, vp->vers_name, tirpcflag? "netpath" : "udp");
+ f_print(fout, "\tif (clnt == (CLIENT *) NULL) {\n");
+ f_print(fout, "\t\tclnt_pcreateerror(host);\n");
+ f_print(fout, "\t\texit(1);\n\t}\n");
+ f_print(fout, "#endif\t/* DEBUG */\n\n");
+
+ /* generate calls to procedures */
+ i = 0;
+ for (proc = vp->procs; proc != NULL; proc = proc->next) {
+ if (mtflag)
+ f_print(fout, "\tretval_%d = ",++i);
+ else
+ f_print(fout, "\tresult_%d = ",++i);
+ pvname(proc->proc_name, vp->vers_num);
+ if (proc->arg_num < 2 && !newstyle) {
+ f_print(fout, "(");
+ if(streq(proc->args.decls->decl.type, "void"))
+ /* cast to void * */
+ f_print(fout, "(void *)");
+ f_print(fout, "&");
+ pvname(proc->proc_name, vp->vers_num);
+ if (mtflag)
+ f_print(fout, "_arg, &result_%d, clnt);\n",
+ i);
+ else
+ f_print(fout, "_arg, clnt);\n");
+
+ } else if (streq(proc->args.decls->decl.type, "void")) {
+ if (mtflag)
+ f_print(fout, "(&result_%d, clnt);\n", i);
+ else
+ 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 (mtflag)
+ f_print(fout, "&result_%d, ", i);
+
+ f_print(fout, "clnt);\n");
+ }
+ if (mtflag) {
+ f_print(fout, "\tif (retval_%d != RPC_SUCCESS) {\n", i);
+
+ } else {
+ f_print(fout, "\tif (result_%d == (", i);
+ ptype(proc->res_prefix, proc->res_type, 1);
+ f_print(fout, "*) NULL) {\n");
+ }
+ f_print(fout, "\t\tclnt_perror(clnt, \"call failed\");\n");
+ f_print(fout, "\t}\n");
+ }
+
+ f_print(fout, "#ifndef\tDEBUG\n");
+ f_print(fout, "\tclnt_destroy(clnt);\n");
+ f_print(fout, "#endif\t /* DEBUG */\n");
+ f_print(fout, "}\n");
+}
+
+static
+write_sample_server(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");
+ if (!mtflag) {
+ return_type(proc);
+ f_print(fout, "*\n");
+ } else
+ f_print(fout, "bool_t\n");
+ if (Cflag || mtflag)
+ pvname_svc(proc->proc_name, vp->vers_num);
+ else
+ pvname(proc->proc_name, vp->vers_num);
+ printarglist(proc, "result", RQSTP, "struct svc_req *");
+
+ f_print(fout, "{\n");
+ if (!mtflag) {
+ f_print(fout, "\tstatic ");
+ if(!streq(proc->res_type, "void"))
+ return_type(proc);
+ else
+ f_print(fout, "char *");
+ /* cannot have void type */
+ f_print(fout, " result;\n", proc->res_type);
+ }
+ else
+ f_print(fout, "\tbool_t retval;\n");
+ f_print(fout,
+ "\n\t/*\n\t * insert server code here\n\t */\n\n");
+
+ if (!mtflag)
+ if(!streq(proc->res_type, "void"))
+ f_print(fout, "\treturn (&result);\n}\n");
+ else /* cast back to void * */
+ f_print(fout, "\treturn((void *) &result);\n}\n");
+ else
+ f_print(fout, "\treturn (retval);\n}\n");
+ }
+ /* put in sample freeing routine */
+ if (mtflag) {
+ f_print(fout, "\nint\n");
+ pvname(def->def_name, vp->vers_num);
+ if (Cflag)
+ f_print(fout,"_freeresult(SVCXPRT *transp, xdrproc_t xdr_result, caddr_t result)\n");
+ else {
+ f_print(fout,"_freeresult(transp, xdr_result, result)\n");
+ f_print(fout,"\tSVCXPRT *transp;\n");
+ f_print(fout,"\txdrproc_t xdr_result;\n");
+ f_print(fout,"\tcaddr_t result;\n");
+ }
+ f_print(fout, "{\n");
+ f_print(fout, "\t(void) xdr_free(xdr_result, result);\n");
+ f_print(fout,
+ "\n\t/*\n\t * Insert additional freeing code here, if needed\n\t */\n");
+ f_print(fout, "\n}\n");
+
+
+ }
+ }
+}
+
+
+
+static
+return_type(plist)
+ proc_list *plist;
+{
+ ptype(plist->res_prefix, plist->res_type, 1);
+}
+
+add_sample_msg()
+{
+ 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()
+{
+ list *l;
+ definition *def;
+ version_list *vp;
+
+ f_print(fout, "\n\n");
+ if(Cflag)
+ f_print(fout,"main(int argc, char *argv[])\n{\n");
+ else
+ f_print(fout, "main(argc, argv)\n\tint argc;\n\tchar *argv[];\n{\n");
+
+ f_print(fout, "\tchar *host;");
+ f_print(fout, "\n\n\tif (argc < 2) {");
+ f_print(fout, "\n\t\tprintf(\"usage: %%s server_host\\n\", argv[0]);\n");
+ f_print(fout, "\t\texit(1);\n\t}");
+ f_print(fout, "\n\thost = argv[1];\n");
+
+ for (l = defined; l != NULL; l = l->next) {
+ def = l->val;
+ if (def->def_kind != DEF_PROGRAM) {
+ continue;
+ }
+ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
+ f_print(fout, "\t");
+ pvname(def->def_name, vp->vers_num);
+ f_print(fout, "(host);\n");
+ }
+ }
+ f_print(fout, "}\n");
+}
diff --git a/usr.bin/rpcgen/rpc_scan.c b/usr.bin/rpcgen/rpc_scan.c
index c531bba..e65b799 100644
--- a/usr.bin/rpcgen/rpc_scan.c
+++ b/usr.bin/rpcgen/rpc_scan.c
@@ -1,4 +1,3 @@
-/* @(#)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
@@ -27,19 +26,24 @@
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
+
+#ident "@(#)rpc_scan.c 1.13 93/07/05 SMI"
+
#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 $";
+static char sccsid[] = "@(#)rpc_scan.c 1.11 89/02/22 (C) 1987 SMI";
#endif
/*
* rpc_scan.c, Scanner for the RPC protocol compiler
* Copyright (C) 1987, Sun Microsystems, Inc.
*/
+
+#include <sys/wait.h>
#include <stdio.h>
#include <ctype.h>
-#include <strings.h>
+#include <string.h>
#include "rpc_scan.h"
+#include "rpc_parse.h"
#include "rpc_util.h"
#define startcomment(where) (where[0] == '/' && where[1] == '*')
@@ -48,8 +52,16 @@ static char rcsid[] = "$Id: rpc_scan.c,v 1.1 1993/09/13 23:20:18 jtc Exp $";
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();
+static int unget_token __P(( token * ));
+static int findstrconst __P(( char **, char **));
+static int findchrconst __P(( char **, char **));
+static int findconst __P(( char **, char **));
+static int findkind __P(( char **, token * ));
+static int cppline __P(( char * ));
+static int directive __P(( char * ));
+static int printdirective __P(( char * ));
+static int docppline __P(( char *, int *, char ** ));
+
/*
* scan expecting 1 given token
*/
@@ -65,7 +77,7 @@ scan(expect, tokp)
}
/*
- * scan expecting 2 given tokens
+ * scan expecting any of the 2 given tokens
*/
void
scan2(expect1, expect2, tokp)
@@ -80,7 +92,7 @@ scan2(expect1, expect2, tokp)
}
/*
- * scan expecting 3 given token
+ * scan expecting any of the 3 given token
*/
void
scan3(expect1, expect2, expect3, tokp)
@@ -96,7 +108,6 @@ scan3(expect1, expect2, expect3, tokp)
}
}
-
/*
* scan expecting a constant, possibly symbolic
*/
@@ -113,7 +124,6 @@ scan_num(tokp)
}
}
-
/*
* Peek at the next token
*/
@@ -125,7 +135,6 @@ peek(tokp)
unget_token(tokp);
}
-
/*
* Peek at the next token and scan it if it matches what you expect
*/
@@ -142,8 +151,6 @@ peekscan(expect, tokp)
return (0);
}
-
-
/*
* Get the next token, printing out any directive that are encountered.
*/
@@ -152,7 +159,9 @@ get_token(tokp)
token *tokp;
{
int commenting;
-
+ int stat = 0;
+
+
if (pushed) {
pushed = 0;
*tokp = lasttok;
@@ -164,6 +173,12 @@ get_token(tokp)
for (;;) {
if (!fgets(curline, MAXLINESIZE, fin)) {
tokp->kind = TOK_EOF;
+ /* now check if cpp returned non NULL value */
+ waitpid(childpid, &stat, WUNTRACED);
+ if (stat > 0) {
+ /* Set return value from rpcgen */
+ nonfatalerrors = stat >> 8;
+ }
*where = 0;
return;
}
@@ -185,10 +200,12 @@ get_token(tokp)
where++; /* eat */
}
} else if (commenting) {
- where++;
- if (endcomment(where)) {
- where++;
- commenting--;
+ for (where++; *where; where++) {
+ if (endcomment(where)) {
+ where++;
+ commenting--;
+ break;
+ }
}
} else if (startcomment(where)) {
where += 2;
@@ -259,6 +276,10 @@ get_token(tokp)
tokp->kind = TOK_STRCONST;
findstrconst(&where, &tokp->str);
break;
+ case '\'':
+ tokp->kind = TOK_CHARCONST;
+ findchrconst(&where, &tokp->str);
+ break;
case '-':
case '0':
@@ -275,7 +296,6 @@ get_token(tokp)
findconst(&where, &tokp->str);
break;
-
default:
if (!(isalpha(*where) || *where == '_')) {
char buf[100];
@@ -295,8 +315,6 @@ get_token(tokp)
}
}
-
-
static
unget_token(tokp)
token *tokp;
@@ -305,7 +323,6 @@ unget_token(tokp)
pushed = 1;
}
-
static
findstrconst(str, val)
char **str;
@@ -330,6 +347,32 @@ findstrconst(str, val)
}
static
+findchrconst(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;
+ if (size != 3) {
+ error("empty char string");
+ }
+ *val = alloc(size + 1);
+ (void) strncpy(*val, *str, size);
+ (*val)[size] = 0;
+ *str = p;
+}
+
+static
findconst(str, val)
char **str;
char **val;
@@ -355,8 +398,6 @@ findconst(str, val)
*str = p;
}
-
-
static token symbols[] = {
{TOK_CONST, "const"},
{TOK_UNION, "union"},
@@ -374,21 +415,21 @@ static token symbols[] = {
{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
findkind(mark, tokp)
char **mark;
token *tokp;
{
-
int len;
token *s;
char *str;
diff --git a/usr.bin/rpcgen/rpc_scan.h b/usr.bin/rpcgen/rpc_scan.h
index fdb7e7b..cf042d0 100644
--- a/usr.bin/rpcgen/rpc_scan.h
+++ b/usr.bin/rpcgen/rpc_scan.h
@@ -25,15 +25,43 @@
* 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 $
*/
+#pragma ident "@(#)rpc_scan.h 1.11 94/05/15 SMI"
+
+/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
+/* All Rights Reserved */
+
+/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
+/* The copyright notice above does not evidence any */
+/* actual or intended publication of such source code. */
+
+
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+* PROPRIETARY NOTICE (Combined)
+*
+* This source code is unpublished proprietary information
+* constituting, or derived under license from AT&T's UNIX(r) System V.
+* In addition, portions of such source code were derived from Berkeley
+* 4.3 BSD under license from the Regents of the University of
+* California.
+*
+*
+*
+* Copyright Notice
+*
+* Notice of copyright on this source code product does not indicate
+* publication.
+*
+* (c) 1986,1987,1988.1989 Sun Microsystems, Inc
+* (c) 1983,1984,1985,1986,1987,1988,1989 AT&T.
+* All rights reserved.
+*/
+
+/* @(#)rpc_scan.h 1.3 90/08/29 (C) 1987 SMI */
/*
* rpc_scan.h, Definitions for the RPCL scanner
- * Copyright (C) 1987, Sun Microsystems, Inc.
*/
/*
@@ -41,6 +69,7 @@
*/
enum tok_kind {
TOK_IDENT,
+ TOK_CHARCONST,
TOK_STRCONST,
TOK_LPAREN,
TOK_RPAREN,
@@ -66,9 +95,11 @@ enum tok_kind {
TOK_INT,
TOK_SHORT,
TOK_LONG,
+ TOK_HYPER,
TOK_UNSIGNED,
TOK_FLOAT,
TOK_DOUBLE,
+ TOK_QUAD,
TOK_OPAQUE,
TOK_CHAR,
TOK_STRING,
@@ -93,7 +124,6 @@ typedef struct token token;
/*
* routine interface
*/
-void scanprint();
void scan();
void scan2();
void scan3();
diff --git a/usr.bin/rpcgen/rpc_svcout.c b/usr.bin/rpcgen/rpc_svcout.c
index 7f375c5..a7b7d87 100644
--- a/usr.bin/rpcgen/rpc_svcout.c
+++ b/usr.bin/rpcgen/rpc_svcout.c
@@ -1,4 +1,3 @@
-/* @(#)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
@@ -27,17 +26,19 @@
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
+
+#ident "@(#)rpc_svcout.c 1.4 90/04/13 SMI"
+
#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 $";
+static char sccsid[] = "@(#)rpc_svcout.c 1.29 89/03/30 (C) 1987 SMI";
#endif
/*
* rpc_svcout.c, Server-skeleton outputter for the RPC protocol compiler
- * Copyright (C) 1987, Sun Microsytsems, Inc.
+ * Copyright (C) 1987, Sun Microsystems, Inc.
*/
#include <stdio.h>
-#include <strings.h>
+#include <string.h>
#include "rpc_parse.h"
#include "rpc_util.h"
@@ -46,98 +47,244 @@ static char TRANSP[] = "transp";
static char ARG[] = "argument";
static char RESULT[] = "result";
static char ROUTINE[] = "local";
+static char RETVAL[] = "retval";
+
+char _errbuf[256]; /* For all messages */
+
+void internal_proctype __P(( proc_list * ));
+static int write_real_program __P(( definition * ));
+static int write_program __P(( definition *, char * ));
+static int printerr __P(( char *, char * ));
+static int printif __P(( char *, char *, char *, char * ));
+static int write_inetmost __P(( char * ));
+static int print_return __P(( char * ));
+static int print_pmapunset __P(( char * ));
+static int print_err_message __P(( char * ));
+static int write_timeout_func __P(( void ));
+static int write_pm_most __P(( char *, int ));
+static int write_rpc_svc_fg __P(( char *, char * ));
+static int open_log_file __P(( char *, char * ));
+
+
+static
+p_xdrfunc(rname, typename)
+char* rname;
+char* typename;
+{
+ if (Cflag)
+ f_print(fout, "\t\txdr_%s = (xdrproc_t) xdr_%s;\n",
+ rname, stringfix(typename));
+ else
+ f_print(fout, "\t\txdr_%s = xdr_%s;\n",
+ rname, stringfix(typename));
+}
+
+void
+internal_proctype(plist)
+ proc_list *plist;
+{
+ f_print(fout, "static ");
+ ptype(plist->res_prefix, plist->res_type, 1);
+ f_print(fout, "*");
+}
+
-static int write_program(), printerr(), printif();
/*
- * write most of the service, that is, everything but the registrations.
+ * write most of the service, that is, everything but the registrations.
*/
void
-write_most()
+write_most(infile, netflag, nomain)
+ char *infile; /* our name */
+ int netflag;
+ int nomain;
{
- list *l;
- definition *def;
- version_list *vp;
+ if (inetdflag || pmflag) {
+ char* var_type;
+ var_type = (nomain? "extern" : "static");
+ f_print(fout, "%s int _rpcpmstart;", var_type);
+ f_print(fout, "\t\t/* Started by a port monitor ? */\n");
+ if (!tirpcflag) {
+ f_print(fout, "%s int _rpcfdtype;", var_type);
+ f_print(fout, "\n\t\t /* Whether Stream or \
+Datagram ? */\n");
+ }
+
+ if (timerflag) {
+ f_print(fout, " /* States a server can be in \
+wrt request */\n\n");
+ f_print(fout, "#define\t_IDLE 0\n");
+ f_print(fout, "#define\t_SERVED 1\n");
+ f_print(fout, "#define\t_SERVING 2\n\n");
+ f_print(fout, "static int _rpcsvcstate = _IDLE;");
+ f_print(fout, "\t /* Set when a request is \
+serviced */\n");
+
+ if (mtflag) {
+ f_print(fout, "mutex_t _svcstate_lock;");
+ f_print(fout, "\t\t\t/* Mutex lock for variable _rpcsvcstate */\n");
- 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, "();");
}
+
}
+
+ write_svc_aux(nomain);
}
- f_print(fout, "\n\n");
- f_print(fout, "main()\n");
+ /* write out dispatcher and stubs */
+ write_programs(nomain? (char *)NULL : "static");
+
+ if (nomain)
+ return;
+
+ f_print(fout, "\nmain()\n");
f_print(fout, "{\n");
- f_print(fout, "\tSVCXPRT *%s;\n", TRANSP);
+ if (inetdflag) {
+ write_inetmost(infile);
+ /* Includes call to write_rpc_svc_fg() */
+ } else {
+ if (tirpcflag) {
+ if (netflag) {
+ f_print(fout,
+ "\tregister SVCXPRT *%s;\n", TRANSP);
+ f_print(fout,
+ "\tstruct netconfig *nconf = NULL;\n");
+ }
+ f_print(fout, "\tpid_t pid;\n");
+ f_print(fout, "\tint i;\n");
+ f_print(fout, "\tchar mname[FMNAMESZ + 1];\n\n");
+
+ if (mtflag & timerflag)
+ f_print(fout, "\tmutex_init(&_svcstate_lock, USYNC_THREAD, NULL);\n");
+
+ write_pm_most(infile, netflag);
+ f_print(fout, "\telse {\n");
+ write_rpc_svc_fg(infile, "\t\t");
+ f_print(fout, "\t}\n");
+ } else {
+ f_print(fout, "\tregister SVCXPRT *%s;\n", TRANSP);
+ f_print(fout, "\n");
+ print_pmapunset("\t");
+ }
+ }
+
+ if (logflag && !inetdflag) {
+ open_log_file(infile, "\t");
+ }
+}
+
+/*
+ * write a registration for the given transport
+ */
+void
+write_netid_register(transp)
+ char *transp;
+{
+ list *l;
+ definition *def;
+ version_list *vp;
+ char *sp;
+ char tmpbuf[32];
+
+ sp = "";
f_print(fout, "\n");
+ f_print(fout, "%s\tnconf = getnetconfigent(\"%s\");\n", sp, transp);
+ f_print(fout, "%s\tif (nconf == NULL) {\n", sp);
+ (void) sprintf(_errbuf, "cannot find %s netid.", transp);
+ sprintf(tmpbuf, "%s\t\t", sp);
+ print_err_message(tmpbuf);
+ f_print(fout, "%s\t\texit(1);\n", sp);
+ f_print(fout, "%s\t}\n", sp);
+ f_print(fout, "%s\t%s = svc_tli_create(RPC_ANYFD, nconf, 0, 0, 0);\n",
+ sp, TRANSP, 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, "\t(void)pmap_unset(%s, %s);\n", def->def_name, vp->vers_name);
+ 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
+ * write a registration for the given transport for TLI
*/
void
-write_register(transp)
+write_nettype_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);
+ f_print(fout, "\tif (!svc_create(");
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",
+ 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
+ * write the rest of the service
*/
void
write_rest()
{
+ f_print(fout, "\n");
+ if (inetdflag) {
+ f_print(fout, "\tif (%s == (SVCXPRT *)NULL) {\n", TRANSP);
+ (void) sprintf(_errbuf, "could not create a handle");
+ print_err_message("\t\t");
+ f_print(fout, "\t\texit(1);\n");
+ f_print(fout, "\t}\n");
+ if (timerflag) {
+ f_print(fout, "\tif (_rpcpmstart) {\n");
+ f_print(fout,
+ "\t\t(void) signal(SIGALRM, %s closedown);\n",
+ Cflag? "(SIG_PF)":"(void(*)())");
+ f_print(fout, "\t\t(void) \
+alarm(_RPCSVC_CLOSEDOWN/2);\n");
+ f_print(fout, "\t}\n");
+ }
+ }
f_print(fout, "\tsvc_run();\n");
- f_print(fout, "\t(void)fprintf(stderr, \"svc_run returned\\n\");\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");
}
@@ -148,14 +295,109 @@ write_programs(storage)
list *l;
definition *def;
+ /* write out stubs for procedure definitions */
+ for (l = defined; l != NULL; l = l->next) {
+ def = (definition *) l->val;
+ if (def->def_kind == DEF_PROGRAM) {
+ write_real_program(def);
+ }
+ }
+
+ /* write out dispatcher for each program */
for (l = defined; l != NULL; l = l->next) {
def = (definition *) l->val;
if (def->def_kind == DEF_PROGRAM) {
write_program(def, storage);
}
}
+
+
}
+/*
+ * write out definition of internal function (e.g. _printmsg_1(...))
+ * which calls server's defintion of actual function (e.g. printmsg_1(...)).
+ * Unpacks single user argument of printmsg_1 to call-by-value format
+ * expected by printmsg_1.
+ */
+static
+write_real_program(def)
+ 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");
+ if (!mtflag)
+ internal_proctype(proc);
+ else
+ f_print(fout, "int");
+ f_print(fout, "\n_");
+ pvname(proc->proc_name, vp->vers_num);
+ if (Cflag) {
+ f_print(fout, "(");
+ /* arg name */
+ if (proc->arg_num > 1)
+ f_print(fout, proc->args.argname);
+ else
+ ptype(proc->args.decls->decl.prefix,
+ proc->args.decls->decl.type, 0);
+ if (mtflag) {
+ f_print(fout, " *argp, void *%s, struct svc_req *%s)\n",
+ RESULT, RQSTP);
+
+
+ }
+ else
+ f_print(fout, " *argp, struct svc_req *%s)\n",
+ RQSTP);
+
+ } else {
+ if (mtflag)
+ f_print(fout, "(argp, %s, %s)\n", RESULT, RQSTP);
+ else
+ f_print(fout, "(argp, %s)\n", RQSTP);
+ /* arg name */
+ if (proc->arg_num > 1)
+ f_print(fout, "\t%s *argp;\n",
+ proc->args.argname);
+ else {
+ f_print(fout, "\t");
+ ptype(proc->args.decls->decl.prefix,
+ proc->args.decls->decl.type, 0);
+ f_print(fout, " *argp;\n");
+ }
+ if (mtflag)
+ f_print(fout, "\tvoid *%s;\n", RESULT);
+ f_print(fout, "\tstruct svc_req *%s;\n", RQSTP);
+ }
+
+ f_print(fout, "{\n");
+ f_print(fout, "\treturn (");
+ if (Cflag || mtflag) /* for mtflag, arguments are different */
+ pvname_svc(proc->proc_name, vp->vers_num);
+ else
+ pvname(proc->proc_name, vp->vers_num);
+ f_print(fout, "(");
+ if (proc->arg_num < 2) { /* single argument */
+ if (!streq(proc->args.decls->decl.type, "void"))
+ f_print(fout, "*argp, "); /* non-void */
+ } else {
+ for (l = proc->args.decls; l != NULL;
+ l = l->next)
+ f_print(fout, "argp->%s, ",
+ l->decl.name);
+ }
+ if (mtflag)
+ f_print(fout, "%s, ",RESULT);
+ f_print(fout, "%s));\n}\n", RQSTP);
+ }
+ }
+}
static
write_program(def, storage)
@@ -173,74 +415,206 @@ write_program(def, 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);
+
+ if (Cflag) {
+ f_print(fout, "(struct svc_req *%s, ", RQSTP);
+ f_print(fout, "register SVCXPRT *%s)\n", TRANSP);
+ } else {
+ f_print(fout, "(%s, %s)\n", RQSTP, TRANSP);
+ f_print(fout, " struct svc_req *%s;\n", RQSTP);
+ f_print(fout, " register SVCXPRT *%s;\n", TRANSP);
+ }
+
f_print(fout, "{\n");
filled = 0;
f_print(fout, "\tunion {\n");
for (proc = vp->procs; proc != NULL; proc = proc->next) {
- if (streq(proc->arg_type, "void")) {
- continue;
+ 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");
}
- 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);
+
+ if (mtflag) {
+ f_print(fout, "\tunion {\n");
+ for (proc = vp->procs; proc != NULL; proc = proc->next) {
+ f_print(fout, "\t\t");
+ ptype(proc->res_prefix, proc->res_type, 0);
+ pvname(proc->proc_name, vp->vers_num);
+ f_print(fout, "_res;\n");
+ }
+ f_print(fout, "\t} %s;\n", RESULT);
+ f_print(fout, "\tbool_t %s;\n", RETVAL);
+
+ } else
+ f_print(fout, "\tchar *%s;\n", RESULT);
+
+ if (Cflag) {
+ f_print(fout, "\txdrproc_t xdr_%s, xdr_%s;\n",
+ ARG, RESULT);
+ if (mtflag)
+ 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);
+ } else {
+ f_print(fout,
+ "\tbool_t (*xdr_%s)(), (*xdr_%s)();\n",
+ ARG, RESULT);
+ if (mtflag)
+ f_print(fout, "\tbool_t (*%s)();\n", ROUTINE);
+ else
+ f_print(fout, "\tchar *(*%s)();\n", ROUTINE);
+ }
f_print(fout, "\n");
- f_print(fout, "\tswitch (%s->rq_proc) {\n", RQSTP);
+ if (timerflag) {
+ if (mtflag)
+ f_print(fout, "\tmutex_lock(&_svcstate_lock);\n");
+
+ f_print(fout, "\t_rpcsvcstate = _SERVING;\n");
+ if (mtflag)
+ f_print(fout, "\tmutex_unlock(&_svcstate_lock);\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");
+ f_print(fout,
+ Cflag
+ ? "\t\t(void) svc_sendreply(%s,\n\t\t\t\
+(xdrproc_t) xdr_void, (char *)NULL);\n"
+ : "\t\t(void) svc_sendreply(%s, xdr_void,\n\t\t\t\
+(char *)NULL);\n",
+ TRANSP);
+ print_return("\t\t");
+ f_print(fout, "\n");
}
for (proc = vp->procs; proc != NULL; proc = proc->next) {
f_print(fout, "\tcase %s:\n", proc->proc_name);
- 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);
+ if (proc->arg_num < 2) { /* single argument */
+ p_xdrfunc(ARG, proc->args.decls->decl.type);
+ } else {
+ p_xdrfunc(ARG, proc->args.argname);
+ }
+ p_xdrfunc(RESULT, proc->res_type);
+
+ if (Cflag)
+ if (mtflag)
+ 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);
+ else
+ if (mtflag)
+ f_print(fout, "\t\t%s = (bool_t (*)()) ",
+ ROUTINE);
+ else
+
+ f_print(fout, "\t\t%s = (char *(*)()) ",
+ ROUTINE);
+ if (newstyle) { /* new style: calls internal routine */
+ f_print(fout, "_");
+ }
+ if ((Cflag || mtflag) && !newstyle)
+ pvname_svc(proc->proc_name, vp->vers_num);
+ else
+ 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");
+ print_return("\t\t");
f_print(fout, "\t}\n");
- f_print(fout, "\tbzero((char *)&%s, sizeof(%s));\n", ARG, ARG);
- printif("getargs", TRANSP, "&", ARG);
+ f_print(fout,
+ "\t(void) memset((char *)&%s, 0, sizeof (%s));\n",
+ ARG, ARG);
+ if (Cflag)
+ printif("getargs", TRANSP, "(caddr_t) &", ARG);
+ else
+ printif("getargs", TRANSP, "&", ARG);
printerr("decode", TRANSP);
- f_print(fout, "\t\treturn;\n");
+ print_return("\t\t");
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);
+ if (!mtflag)
+ if (Cflag)
+ f_print(fout, "\t%s = (*%s)((char *)&%s, %s);\n",
+ RESULT, ROUTINE, ARG, RQSTP);
+ else
+ f_print(fout, "\t%s = (*%s)(&%s, %s);\n",
+ RESULT, ROUTINE, ARG, RQSTP);
+ else
+ if (Cflag)
+ f_print(fout, "\t%s = (bool_t) (*%s)((char *)&%s, (void *)&%s, %s);\n",
+ RETVAL, ROUTINE, ARG, RESULT, RQSTP);
+ else
+ f_print(fout, "\t%s = (bool_t) (*%s)(&%s, &%s, %s);\n",
+ RETVAL, ROUTINE, ARG, RESULT, RQSTP);
+
+
+
+
+ if (mtflag)
+ f_print(fout,
+ "\tif (%s > 0 && !svc_sendreply(%s, xdr_%s, (char *)&%s)) {\n",
+ RETVAL, 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, "&", ARG);
- f_print(fout, "\t\t(void)fprintf(stderr, \"unable to free arguments\\n\");\n");
+ if (Cflag)
+ printif("freeargs", TRANSP, "(caddr_t) &", ARG);
+ else
+ printif("freeargs", TRANSP, "&", ARG);
+ (void) sprintf(_errbuf, "unable to free arguments");
+ print_err_message("\t\t");
f_print(fout, "\t\texit(1);\n");
f_print(fout, "\t}\n");
-
- f_print(fout, "}\n\n");
+ /* print out free routine */
+ if (mtflag) {
+ f_print(fout,"\tif (!");
+ pvname(def->def_name, vp->vers_num);
+ f_print(fout,"_freeresult(%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, "\n");
+ };
+ print_return("\t");
+ f_print(fout, "}\n");
}
}
@@ -263,7 +637,6 @@ printif(proc, transp, prefix, arg)
proc, transp, arg, prefix, arg);
}
-
nullproc(proc)
proc_list *proc;
{
@@ -274,3 +647,436 @@ nullproc(proc)
}
return (0);
}
+
+static
+write_inetmost(infile)
+ char *infile;
+{
+ f_print(fout, "\tregister SVCXPRT *%s;\n", TRANSP);
+ f_print(fout, "\tint sock;\n");
+ f_print(fout, "\tint proto;\n");
+ f_print(fout, "\tstruct sockaddr_in saddr;\n");
+ f_print(fout, "\tint asize = sizeof (saddr);\n");
+ f_print(fout, "\n");
+ f_print(fout,
+ "\tif (getsockname(0, (struct sockaddr *)&saddr, &asize) == 0) {\n");
+ f_print(fout, "\t\tint ssize = sizeof (int);\n\n");
+ f_print(fout, "\t\tif (saddr.sin_family != AF_INET)\n");
+ f_print(fout, "\t\t\texit(1);\n");
+ f_print(fout, "\t\tif (getsockopt(0, SOL_SOCKET, SO_TYPE,\n");
+ f_print(fout, "\t\t\t\t(char *)&_rpcfdtype, &ssize) == -1)\n");
+ f_print(fout, "\t\t\texit(1);\n");
+ f_print(fout, "\t\tsock = 0;\n");
+ f_print(fout, "\t\t_rpcpmstart = 1;\n");
+ f_print(fout, "\t\tproto = 0;\n");
+ open_log_file(infile, "\t\t");
+ f_print(fout, "\t} else {\n");
+ write_rpc_svc_fg(infile, "\t\t");
+ f_print(fout, "\t\tsock = RPC_ANYSOCK;\n");
+ print_pmapunset("\t\t");
+ f_print(fout, "\t}\n");
+}
+
+static
+print_return(space)
+ char *space;
+{
+ if (exitnow)
+ f_print(fout, "%sexit(0);\n", space);
+ else {
+ if (timerflag) {
+ if (mtflag)
+ f_print(fout, "%smutex_lock(&_svcstate_lock);\n", space);
+ f_print(fout, "%s_rpcsvcstate = _SERVED;\n", space);
+ if (mtflag)
+ f_print(fout, "%smutex_unlock(&_svcstate_lock);\n", space);
+ }
+ f_print(fout, "%sreturn;\n", space);
+ }
+}
+
+static
+print_pmapunset(space)
+ 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
+print_err_message(space)
+ 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(nomain)
+ int nomain;
+{
+ if (!logflag)
+ write_msg_out();
+ if (!nomain)
+ write_timeout_func();
+}
+
+/*
+ * Write the _msgout function
+ */
+
+write_msg_out()
+{
+ f_print(fout, "\n");
+/*
+ * Avoid making _msgout() static -- it's useful to have it visible
+ * in the toplevel RPC server code.
+ */
+ f_print(fout, "static\n");
+
+ if (!Cflag) {
+ f_print(fout, "void _msgout(msg)\n");
+ f_print(fout, "\tchar *msg;\n");
+ } else {
+ f_print(fout, "void _msgout(char* msg)\n");
+ }
+ f_print(fout, "{\n");
+ f_print(fout, "#ifdef RPC_SVC_FG\n");
+ if (inetdflag || pmflag)
+ f_print(fout, "\tif (_rpcpmstart)\n");
+ f_print(fout, "\t\tsyslog(LOG_ERR, 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, msg);\n");
+ f_print(fout, "#endif\n");
+ f_print(fout, "}\n");
+}
+
+/*
+ * Write the timeout function
+ */
+static
+write_timeout_func()
+{
+ if (!timerflag)
+ return;
+
+ f_print(fout, "\n");
+ f_print(fout, "static void\n");
+ if (!Cflag) {
+ f_print(fout, "closedown(sig)\n");
+ f_print(fout, "\tint sig;\n");
+ } else
+ f_print(fout, "closedown(int sig)\n");
+ f_print(fout, "{\n");
+ if (mtflag)
+ f_print(fout, "\tmutex_lock(&_svcstate_lock);\n");
+ f_print(fout, "\tif (_rpcsvcstate == _IDLE) {\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\tgetrlimit(RLIMIT_NOFILE, &rl);\n");
+ f_print(fout, "\t\t\tif ((size = rl.rlim_max) == 0) {\n");
+
+ if (mtflag)
+ f_print(fout, "\t\t\t\tmutex_unlock(&_svcstate_lock);\n");
+
+ f_print(fout, "\t\t\t\treturn;\n\t\t\t}\n");
+ } else {
+ f_print(fout, "\t\t\tsize = getdtablesize();\n");
+ }
+ f_print(fout, "\t\t}\n");
+ f_print(fout,
+ "\t\tfor (i = 0, openfd = 0; i < size && openfd < 2; i++)\n");
+ f_print(fout, "\t\t\tif (FD_ISSET(i, &svc_fdset))\n");
+ f_print(fout, "\t\t\t\topenfd++;\n");
+ f_print(fout, "\t\tif (openfd <= 1)\n");
+ f_print(fout, "\t\t\texit(0);\n");
+ f_print(fout, "\t}\n");
+ f_print(fout, "\tif (_rpcsvcstate == _SERVED)\n");
+ f_print(fout, "\t\t_rpcsvcstate = _IDLE;\n\n");
+ if (mtflag)
+ f_print(fout, "\tmutex_unlock(&_svcstate_lock);\n");
+
+ f_print(fout, "\t(void) signal(SIGALRM, %s closedown);\n",
+ Cflag? "(SIG_PF)" : "(void(*)())");
+ f_print(fout, "\t(void) alarm(_RPCSVC_CLOSEDOWN/2);\n");
+ f_print(fout, "}\n");
+
+}
+
+/*
+ * Write the most of port monitor support
+ */
+static
+write_pm_most(infile, netflag)
+ 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");
+ open_log_file(infile, "\t\t");
+ f_print(fout, "\n\t\tif ((netid = \
+getenv(\"NLSPROVIDER\")) == NULL) {\n");
+
+ if (timerflag) {
+ f_print(fout, "\t\t/* started from inetd */\n");
+ f_print(fout, "\t\t\tpmclose = 1;\n");
+ }
+ f_print(fout,
+ "\t\t} else {\n");
+ f_print(fout, "\t\t\tif ((nconf = getnetconfigent(netid)) == NULL)\n");
+ sprintf(_errbuf, "cannot get transport info");
+ print_err_message("\t\t\t\t");
+ if (timerflag)
+ f_print(fout, "\n\t\t\tpmclose = \
+(t_getstate(0) != T_DATAXFER);\n");
+ 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");
+ f_print(fout,
+ "\t\tif ((%s = svc_tli_create(0, nconf, NULL, 0, 0)) \
+== NULL) {\n",
+ TRANSP);
+ sprintf(_errbuf, "cannot create server handle");
+ print_err_message("\t\t\t");
+ f_print(fout, "\t\t\texit(1);\n");
+ f_print(fout, "\t\t}\n");
+ f_print(fout, "\t\tif (nconf)\n");
+ f_print(fout, "\t\t\tfreenetconfigent(nconf);\n");
+ for (l = defined; l != NULL; l = l->next) {
+ def = (definition *) l->val;
+ if (def->def_kind != DEF_PROGRAM) {
+ continue;
+ }
+ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
+ f_print(fout,
+ "\t\tif (!svc_reg(%s, %s, %s, ",
+ TRANSP, def->def_name, vp->vers_name);
+ pvname(def->def_name, vp->vers_num);
+ f_print(fout, ", 0)) {\n");
+ (void) sprintf(_errbuf, "unable to register (%s, %s).",
+ def->def_name, vp->vers_name);
+ print_err_message("\t\t\t");
+ f_print(fout, "\t\t\texit(1);\n");
+ f_print(fout, "\t\t}\n");
+ }
+ }
+ if (timerflag) {
+ f_print(fout, "\t\tif (pmclose) {\n");
+ f_print(fout, "\t\t\t(void) signal(SIGALRM, %s closedown);\n",
+ Cflag? "(SIG_PF)" : "(void(*)())");
+ f_print(fout, "\t\t\t(void) alarm(_RPCSVC_CLOSEDOWN/2);\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}");
+}
+
+/*
+ * Support for backgrounding the server if self started.
+ */
+static
+write_rpc_svc_fg(infile, sp)
+ char *infile;
+ char *sp;
+{
+ f_print(fout, "#ifndef RPC_SVC_FG\n");
+ f_print(fout, "%sint size;\n", sp);
+ if (tirpcflag)
+ f_print(fout, "%sstruct rlimit rl;\n", sp);
+ if (inetdflag)
+ f_print(fout, "%sint pid, i;\n\n", sp);
+ f_print(fout, "%spid = fork();\n", sp);
+ f_print(fout, "%sif (pid < 0) {\n", sp);
+ f_print(fout, "%s\tperror(\"cannot fork\");\n", sp);
+ f_print(fout, "%s\texit(1);\n", sp);
+ f_print(fout, "%s}\n", sp);
+ f_print(fout, "%sif (pid)\n", sp);
+ f_print(fout, "%s\texit(0);\n", sp);
+ /* get number of file descriptors */
+ if (tirpcflag) {
+ f_print(fout, "%srl.rlim_max = 0;\n", sp);
+ f_print(fout, "%sgetrlimit(RLIMIT_NOFILE, &rl);\n", sp);
+ f_print(fout, "%sif ((size = rl.rlim_max) == 0)\n", sp);
+ f_print(fout, "%s\texit(1);\n", sp);
+ } else {
+ f_print(fout, "%ssize = getdtablesize();\n", sp);
+ }
+
+ f_print(fout, "%sfor (i = 0; i < size; i++)\n", sp);
+ f_print(fout, "%s\t(void) close(i);\n", sp);
+ /* Redirect stderr and stdout to console */
+ f_print(fout, "%si = open(\"/dev/console\", 2);\n", sp);
+ f_print(fout, "%s(void) dup2(i, 1);\n", sp);
+ f_print(fout, "%s(void) dup2(i, 2);\n", sp);
+ /* This removes control of the controlling terminal */
+ if (tirpcflag)
+ f_print(fout, "%ssetsid();\n", sp);
+ else {
+ f_print(fout, "%si = open(\"/dev/tty\", 2);\n", sp);
+ f_print(fout, "%sif (i >= 0) {\n", sp);
+ f_print(fout,
+ "%s\t(void) ioctl(i, TIOCNOTTY, (char *)NULL);\n", sp);
+ f_print(fout, "%s\t(void) close(i);\n", sp);
+ f_print(fout, "%s}\n", sp);
+ }
+ if (!logflag)
+ open_log_file(infile, sp);
+ f_print(fout, "#endif\n");
+ if (logflag)
+ open_log_file(infile, sp);
+}
+
+static
+open_log_file(infile, sp)
+ char *infile;
+ char *sp;
+{
+ char *s;
+
+ s = strrchr(infile, '.');
+ if (s)
+ *s = '\0';
+ f_print(fout, "%sopenlog(\"%s\", LOG_PID, LOG_DAEMON);\n", sp, infile);
+ if (s)
+ *s = '.';
+}
+
+
+
+
+/*
+ * write a registration for the given transport for Inetd
+ */
+void
+write_inetd_register(transp)
+ char *transp;
+{
+ list *l;
+ definition *def;
+ version_list *vp;
+ char *sp;
+ int isudp;
+ char tmpbuf[32];
+
+ if (inetdflag)
+ sp = "\t";
+ else
+ sp = "";
+ if (streq(transp, "udp"))
+ isudp = 1;
+ else
+ isudp = 0;
+ f_print(fout, "\n");
+ if (inetdflag) {
+ f_print(fout,
+ "\tif ((_rpcfdtype == 0) || (_rpcfdtype == %s)) {\n",
+ isudp ? "SOCK_DGRAM" : "SOCK_STREAM");
+ }
+ f_print(fout, "%s\t%s = svc%s_create(%s",
+ sp, TRANSP, transp, inetdflag? "sock": "RPC_ANYSOCK");
+ if (!isudp)
+ f_print(fout, ", 0, 0");
+ f_print(fout, ");\n");
+ f_print(fout, "%s\tif (%s == NULL) {\n", sp, TRANSP);
+ (void) sprintf(_errbuf, "cannot create %s service.", transp);
+ (void) sprintf(tmpbuf, "%s\t\t", sp);
+ print_err_message(tmpbuf);
+ f_print(fout, "%s\t\texit(1);\n", sp);
+ f_print(fout, "%s\t}\n", sp);
+
+ if (inetdflag) {
+ f_print(fout, "%s\tif (!_rpcpmstart)\n\t", sp);
+ f_print(fout, "%s\tproto = IPPROTO_%s;\n",
+ sp, isudp ? "UDP": "TCP");
+ }
+ for (l = defined; l != NULL; l = l->next) {
+ def = (definition *) l->val;
+ if (def->def_kind != DEF_PROGRAM) {
+ continue;
+ }
+ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
+ f_print(fout, "%s\tif (!svc_register(%s, %s, %s, ",
+ sp, TRANSP, def->def_name, vp->vers_name);
+ pvname(def->def_name, vp->vers_num);
+ if (inetdflag)
+ f_print(fout, ", proto)) {\n");
+ else
+ f_print(fout, ", IPPROTO_%s)) {\n",
+ isudp ? "UDP": "TCP");
+ (void) sprintf(_errbuf,
+ "unable to register (%s, %s, %s).",
+ def->def_name, vp->vers_name, transp);
+ print_err_message(tmpbuf);
+ f_print(fout, "%s\t\texit(1);\n", sp);
+ f_print(fout, "%s\t}\n", sp);
+ }
+ }
+ if (inetdflag)
+ f_print(fout, "\t}\n");
+}
diff --git a/usr.bin/rpcgen/rpc_tblout.c b/usr.bin/rpcgen/rpc_tblout.c
new file mode 100644
index 0000000..e851ded
--- /dev/null
+++ b/usr.bin/rpcgen/rpc_tblout.c
@@ -0,0 +1,171 @@
+/*
+ * 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
+ */
+
+#ident "@(#)rpc_tblout.c 1.11 93/07/05 SMI"
+
+#ifndef lint
+static char sccsid[] = "@(#)rpc_tblout.c 1.4 89/02/22 (C) 1988 SMI";
+#endif
+
+/*
+ * rpc_tblout.c, Dispatch table outputter for the RPC protocol compiler
+ * Copyright (C) 1989, Sun Microsystems, Inc.
+ */
+#include <stdio.h>
+#include <string.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 char tbl_hdr[] = "struct rpcgen_table %s_table[] = {\n";
+static char tbl_end[] = "};\n";
+
+static char null_entry[] = "\n\t(char *(*)())0,\n\
+ \t(xdrproc_t) xdr_void,\t\t\t0,\n\
+ \t(xdrproc_t) xdr_void,\t\t\t0,\n";
+
+
+static char tbl_nproc[] = "int %s_nproc =\n\tsizeof(%s_table)/sizeof(%s_table[0]);\n\n";
+
+static int write_table __P(( definition * ));
+static int printit __P(( char *, char * ));
+
+void
+write_tables()
+{
+ 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
+write_table(def)
+ definition *def;
+{
+ version_list *vp;
+ proc_list *proc;
+ int current;
+ int expected;
+ char progvers[100];
+ int warning;
+
+ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
+ warning = 0;
+ s_print(progvers, "%s_%s",
+ locase(def->def_name), vp->vers_num);
+ /* print the table header */
+ f_print(fout, tbl_hdr, progvers);
+
+ if (nullproc(vp->procs)) {
+ expected = 0;
+ } else {
+ expected = 1;
+ f_print(fout, null_entry);
+ }
+ for (proc = vp->procs; proc != NULL; proc = proc->next) {
+ current = atoi(proc->proc_num);
+ if (current != expected++) {
+ f_print(fout,
+ "\n/*\n * WARNING: table out of order\n */\n");
+ if (warning == 0) {
+ f_print(stderr,
+ "WARNING %s table is out of order\n",
+ progvers);
+ warning = 1;
+ nonfatalerrors = 1;
+ }
+ expected = current + 1;
+ }
+ f_print(fout, "\n\t(char *(*)())RPCGEN_ACTION(");
+
+ /* routine to invoke */
+ if( Cflag && !newstyle )
+ pvname_svc(proc->proc_name, vp->vers_num);
+ else {
+ if( newstyle )
+ f_print( fout, "_"); /* calls internal func */
+ pvname(proc->proc_name, vp->vers_num);
+ }
+ f_print(fout, "),\n");
+
+ /* argument info */
+ if( proc->arg_num > 1 )
+ printit((char*) NULL, proc->args.argname );
+ else
+ /* do we have to do something special for newstyle */
+ printit( proc->args.decls->decl.prefix,
+ proc->args.decls->decl.type );
+ /* result info */
+ printit(proc->res_prefix, proc->res_type);
+ }
+
+ /* print the table trailer */
+ f_print(fout, tbl_end);
+ f_print(fout, tbl_nproc, progvers, progvers, progvers);
+ }
+}
+
+static
+printit(prefix, type)
+ char *prefix;
+ char *type;
+{
+ int len;
+ int tabs;
+
+
+ len = fprintf(fout, "\txdr_%s,", stringfix(type));
+ /* account for leading tab expansion */
+ len += TABSIZE - 1;
+ /* round up to tabs required */
+ tabs = (TABSTOP - len + TABSIZE - 1)/TABSIZE;
+ f_print(fout, "%s", &tabstr[TABCOUNT-tabs]);
+
+ if (streq(type, "void")) {
+ f_print(fout, "0");
+ } else {
+ f_print(fout, "sizeof ( ");
+ /* XXX: should "follow" be 1 ??? */
+ ptype(prefix, type, 0);
+ f_print(fout, ")");
+ }
+ f_print(fout, ",\n");
+}
diff --git a/usr.bin/rpcgen/rpc_util.c b/usr.bin/rpcgen/rpc_util.c
index 6d5b18e..5d3fa06 100644
--- a/usr.bin/rpcgen/rpc_util.c
+++ b/usr.bin/rpcgen/rpc_util.c
@@ -1,4 +1,3 @@
-/* @(#)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
@@ -27,50 +26,55 @@
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
+
+#ident "@(#)rpc_util.c 1.14 93/07/05 SMI"
+
#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 $";
+static char sccsid[] = "@(#)rpc_util.c 1.11 89/02/22 (C) 1987 SMI";
#endif
/*
- * rpc_util.c, Utility routines for the RPC protocol compiler
- * Copyright (C) 1987, Sun Microsystems, Inc.
+ * rpc_util.c, Utility routines for the RPC protocol compiler
+ * Copyright (C) 1989, Sun Microsystems, Inc.
*/
#include <stdio.h>
+#include <ctype.h>
#include "rpc_scan.h"
#include "rpc_parse.h"
#include "rpc_util.h"
+#define ARGEXT "argument"
+
char curline[MAXLINESIZE]; /* current read line */
-char *where = curline; /* current point in line */
-int linenum = 0; /* current line number */
+char *where = curline; /* current point in line */
+int linenum = 0; /* current line number */
-char *infilename; /* input filename */
+char *infilename; /* input filename */
-#define NFILES 4
-char *outfiles[NFILES]; /* output file names */
+#define NFILES 7
+char *outfiles[NFILES]; /* output file names */
int nfiles;
-FILE *fout; /* file pointer of current output */
-FILE *fin; /* file pointer of current input */
+FILE *fout; /* file pointer of current output */
+FILE *fin; /* file pointer of current input */
-list *defined; /* list of defined things */
+list *defined; /* list of defined things */
-static int printwhere();
+static int printwhere __P(( void ));
/*
- * Reinitialize the world
+ * Reinitialize the world
*/
reinitialize()
{
- bzero(curline, MAXLINESIZE);
+ memset(curline, 0, MAXLINESIZE);
where = curline;
linenum = 0;
defined = NULL;
}
/*
- * string equality
+ * string equality
*/
streq(a, b)
char *a;
@@ -80,9 +84,9 @@ streq(a, b)
}
/*
- * find a value in a list
+ * find a value in a list
*/
-char *
+definition *
findval(lst, val, cmp)
list *lst;
char *val;
@@ -98,12 +102,12 @@ findval(lst, val, cmp)
}
/*
- * store a value in a list
+ * store a value in a list
*/
void
storeval(lstp, val)
list **lstp;
- char *val;
+ definition *val;
{
list **l;
list *lst;
@@ -115,7 +119,6 @@ storeval(lstp, val)
*l = lst;
}
-
static
findit(def, type)
definition *def;
@@ -124,7 +127,6 @@ findit(def, type)
return (streq(def->def_name, type));
}
-
static char *
fixit(type, orig)
char *type;
@@ -138,7 +140,11 @@ fixit(type, orig)
}
switch (def->def.ty.rel) {
case REL_VECTOR:
- return (def->def.ty.old_type);
+ if (streq(def->def.ty.old_type, "opaque"))
+ return ("char");
+ else
+ return (def->def.ty.old_type);
+
case REL_ALIAS:
return (fixit(def->def.ty.old_type, orig));
default:
@@ -186,7 +192,6 @@ ptype(prefix, type, follow)
}
}
-
static
typedefed(def, type)
definition *def;
@@ -224,8 +229,7 @@ isvectordef(type, rel)
}
}
-
-static char *
+char *
locase(str)
char *str;
{
@@ -240,6 +244,13 @@ locase(str)
return (buf);
}
+void
+pvname_svc(pname, vnum)
+ char *pname;
+ char *vnum;
+{
+ f_print(fout, "%s_%s_svc", locase(pname), vnum);
+}
void
pvname(pname, vnum)
@@ -249,9 +260,8 @@ pvname(pname, vnum)
f_print(fout, "%s_%s", locase(pname), vnum);
}
-
/*
- * print a useful (?) error message, and then die
+ * print a useful (?) error message, and then die
*/
void
error(msg)
@@ -265,7 +275,7 @@ error(msg)
/*
* Something went wrong, unlink any files that we may have created and then
- * die.
+ * die.
*/
crash()
{
@@ -277,7 +287,6 @@ crash()
exit(1);
}
-
void
record_open(file)
char *file;
@@ -294,7 +303,7 @@ static char expectbuf[100];
static char *toktostr();
/*
- * error, token encountered was not the expected one
+ * error, token encountered was not the expected one
*/
void
expected1(exp1)
@@ -306,7 +315,7 @@ expected1(exp1)
}
/*
- * error, token encountered was not one of two expected ones
+ * error, token encountered was not one of two expected ones
*/
void
expected2(exp1, exp2)
@@ -319,7 +328,7 @@ expected2(exp1, exp2)
}
/*
- * error, token encountered was not one of 3 expected ones
+ * error, token encountered was not one of 3 expected ones
*/
void
expected3(exp1, exp2, exp3)
@@ -343,42 +352,41 @@ tabify(f, tab)
}
-
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, "??????"}
+ {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 *
@@ -391,8 +399,6 @@ toktostr(kind)
return (sp->str);
}
-
-
static
printbuf()
{
@@ -415,7 +421,6 @@ printbuf()
}
}
-
static
printwhere()
{
@@ -437,3 +442,67 @@ printwhere()
}
(void) fputc('\n', stderr);
}
+
+char *
+make_argname(pname, vname)
+ char *pname;
+ char *vname;
+{
+ char *name;
+
+ name = malloc(strlen(pname) + strlen(vname) + strlen(ARGEXT) + 3);
+ if (!name) {
+ fprintf(stderr, "failed in malloc");
+ exit(1);
+ }
+ sprintf(name, "%s_%s_%s", locase(pname), vname, ARGEXT);
+ return (name);
+}
+
+bas_type *typ_list_h;
+bas_type *typ_list_t;
+
+add_type(len, type)
+int len;
+char *type;
+{
+ bas_type *ptr;
+
+ if ((ptr = (bas_type *) malloc(sizeof (bas_type))) ==
+ (bas_type *)NULL) {
+ fprintf(stderr, "failed in malloc");
+ exit(1);
+ }
+
+ ptr->name = type;
+ ptr->length = len;
+ ptr->next = NULL;
+ if (typ_list_t == NULL)
+ {
+
+ typ_list_t = ptr;
+ typ_list_h = ptr;
+ }
+ else
+ {
+ typ_list_t->next = ptr;
+ typ_list_t = ptr;
+ };
+}
+
+
+bas_type *find_type(type)
+char *type;
+{
+ bas_type * ptr;
+
+ ptr = typ_list_h;
+ while (ptr != NULL)
+ {
+ if (strcmp(ptr->name, type) == 0)
+ return (ptr);
+ else
+ ptr = ptr->next;
+ };
+ return (NULL);
+}
diff --git a/usr.bin/rpcgen/rpc_util.h b/usr.bin/rpcgen/rpc_util.h
index dcca92f..259860f 100644
--- a/usr.bin/rpcgen/rpc_util.h
+++ b/usr.bin/rpcgen/rpc_util.h
@@ -25,34 +25,87 @@
* 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 $
*/
+#pragma ident "@(#)rpc_util.h 1.16 94/05/15 SMI"
+
+/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
+/* All Rights Reserved */
+
+/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
+/* The copyright notice above does not evidence any */
+/* actual or intended publication of such source code. */
+
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+* PROPRIETARY NOTICE (Combined)
+*
+* This source code is unpublished proprietary information
+* constituting, or derived under license from AT&T's UNIX(r) System V.
+* In addition, portions of such source code were derived from Berkeley
+* 4.3 BSD under license from the Regents of the University of
+* California.
+*
+*
+*
+* Copyright Notice
+*
+* Notice of copyright on this source code product does not indicate
+* publication.
+*
+* (c) 1986,1987,1988.1989 Sun Microsystems, Inc
+* (c) 1983,1984,1985,1986,1987,1988,1989 AT&T.
+* All rights reserved.
+*/
+
+/* @(#)rpc_util.h 1.5 90/08/29 (C) 1987 SMI */
/*
* rpc_util.h, Useful definitions for the RPC protocol compiler
- * Copyright (C) 1987, Sun Microsystems, Inc.
*/
-extern char *malloc();
+#include <sys/types.h>
+#include <stdlib.h>
-#define alloc(size) malloc((unsigned)(size))
-#define ALLOC(object) (object *) malloc(sizeof(object))
+#define alloc(size) malloc((unsigned)(size))
+#define ALLOC(object) (object *) malloc(sizeof(object))
-#define s_print (void) sprintf
-#define f_print (void) fprintf
+#define s_print (void) sprintf
+#define f_print (void) fprintf
struct list {
- char *val;
+ definition *val;
struct list *next;
};
typedef struct list list;
+struct xdrfunc {
+ char *name;
+ int pointerp;
+ struct xdrfunc *next;
+};
+typedef struct xdrfunc xdrfunc;
+
+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 */
+ int makefileflag; /* Generate a template Makefile */
+ char *infile; /* input module name */
+ char *outfile; /* output module name */
+};
+
+#define PUT 1
+#define GET 2
+
/*
* Global variables
*/
-#define MAXLINESIZE 1024
+#define MAXLINESIZE 1024
extern char curline[MAXLINESIZE];
extern char *where;
extern int linenum;
@@ -63,21 +116,53 @@ extern FILE *fin;
extern list *defined;
+
+extern bas_type *typ_list_h;
+extern bas_type *typ_list_t;
+extern xdrfunc *xdrfunc_head, *xdrfunc_tail;
+
+/*
+ * All the option flags
+ */
+extern int inetdflag;
+extern int pmflag;
+extern int tblflag;
+extern int logflag;
+extern int newstyle;
+extern int Cflag; /* ANSI-C/C++ flag */
+extern int CCflag; /* C++ flag */
+extern int tirpcflag; /* flag for generating tirpc code */
+extern int inline; /* if this is 0, then do not generate inline code */
+extern int mtflag;
+
+/*
+ * Other flags related with inetd jumpstart.
+ */
+extern int indefinitewait;
+extern int exitnow;
+extern int timerflag;
+
+extern int nonfatalerrors;
+
+extern pid_t childpid;
+
/*
* rpc_util routines
*/
void storeval();
-#define STOREVAL(list,item) \
- storeval(list,(char *)item)
+#define STOREVAL(list,item) \
+ storeval(list,item)
-char *findval();
+definition *findval();
-#define FINDVAL(list,item,finder) \
- findval(list, (char *) item, finder)
+#define FINDVAL(list,item,finder) \
+ findval(list, item, finder)
char *fixtype();
char *stringfix();
+char *locase();
+void pvname_svc();
void pvname();
void ptype();
int isvectordef();
@@ -88,7 +173,7 @@ void expected2();
void expected3();
void tabify();
void record_open();
-
+bas_type *find_type();
/*
* rpc_cout routines
*/
@@ -99,6 +184,8 @@ void emit();
* rpc_hout routines
*/
void print_datadef();
+void print_funcdef();
+void print_xdr_func_def();
/*
* rpc_svcout routines
@@ -106,8 +193,17 @@ void print_datadef();
void write_most();
void write_register();
void write_rest();
-
+void write_programs();
+void write_svc_aux();
+void write_inetd_register();
+void write_netid_register();
+void write_nettype_register();
/*
* rpc_clntout routines
*/
void write_stubs();
+
+/*
+ * rpc_tblout routines
+ */
+void write_tables();
diff --git a/usr.bin/rpcgen/rpcgen.1 b/usr.bin/rpcgen/rpcgen.1
index 5fd9274..cb81c98 100644
--- a/usr.bin/rpcgen/rpcgen.1
+++ b/usr.bin/rpcgen/rpcgen.1
@@ -1,156 +1,554 @@
-.\" 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
+.\" @(#)rpcgen.1 1.35 93/06/02 SMI
+'\"macro stdmacro
+.\" Copyright 1985-1993 Sun Microsystems, Inc.
+.nr X
+.TH rpcgen 1 "28 Mar 1993"
+.SH NAME
+rpcgen \- an RPC protocol compiler
+.SH SYNOPSIS
+.BI rpcgen " infile"
+.LP
+.B rpcgen
+[
+.B \-a
+] [
+.B \-b
+] [
+.B \-C
+] [
+.BI \-D name
+[ =
+.I value
+] ]
+.if n .ti +5n
+[
+.BI \-i " size"
+]
+[
+.B \-I
+[
+.BI \-K " seconds"
+] ]
+[
+.B \-L
+] [
+.B \-M
+]
+.if n .ti +5n
+.if t .ti +5n
+[
+.B \-N
+]
+[
+.B \-T
+] [
+.BI \-Y " pathname"
+]
+.I infile
+.LP
+.B rpcgen
+[
+.B \-c
+|
+.B \-h
+|
+.B \-l
+|
+.B \-m
+|
+.B \-t
+|
+.B \-Sc
+|
+.B \-Ss
+|
+.B \-Sm
+]
+.if n .ti +5n
+[
+.BI \-o " outfile"
+] [
+.I infile
+]
+.LP
+.B rpcgen
+[
+.BI \-s " nettype"
+] [
+.BI \-o " outfile"
+] [
+.I infile
+]
+.LP
+.B rpcgen
+[
+.BI \-n " netid"
+] [
+.BI \-o " outfile"
+] [
+.I infile
+]
+.\" .SH AVAILABILITY
+.\" .LP
+.\" SUNWcsu
+.SH DESCRIPTION
+.IX "rpcgen" "" "\fLrpcgen\fP \(em RPC protocol compiler"
+.IX "RPC" "protocol compiler" "" "protocol compiler \(em \fLrpcgen\fP"
+.IX "RPC Language" "RPC protocol compiler" "" "RPC protocol compiler \(em \fLrpcgen\fP"
+.IX "compilers" "RPC protocol compiler" "" "RPC protocol compiler \(em \fLrpcgen\fP"
+.IX "programming tools" "RPC protocol compiler" "" "RPC protocol compiler \(em \fLrpcgen\fP"
+.LP
+\f3rpcgen\f1
+is a tool that generates C code to implement an RPC protocol.
+The input to
+\f3rpcgen\f1
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
+RPC Language (Remote Procedure Call Language).
+.LP
+\f3rpcgen\f1
+is normally used as in the first synopsis where
+it takes an input file and generates three output files.
+If the
+\f2infile\f1
is named
-.Pa proto.x ,
+\f3proto.x\f1,
then
-.Nm rpcgen
-will generate a header file in
-.Pa proto.h ,
-.Tn XDR
-routines in
-.Pa proto_xdr.c ,
+\f3rpcgen\f1
+generates a header in
+\f3proto.h\f1,
+XDR routines in
+\f3proto_xdr.c\f1,
server-side stubs in
-.Pa proto_svc.c ,
+\f3proto_svc.c\f1,
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
+\f3proto_clnt.c\f1.
+With the
+\f3\-T\f1
+option,
+it also generates the RPC dispatch table in
+\f3proto_tbl.i\f1.
+.LP
+.B rpcgen
+can also generate sample client and server files
+that can be customized to suit a particular application. The
+\f3\-Sc\f1,
+\f3\-Ss\f1
+and
+\f3\-Sm\f1
+options generate sample client, server and makefile, respectively.
+The
+\f3\-a\f1
+option generates all files, including sample files. If the infile
+is \f3proto.x\f1, then the client side sample file is written to
+\f3proto_client.c\f1, the server side sample file to \f3proto_server.c\f1
+and the sample makefile to \f3makefile.proto\f1.
+.LP
+The server created can be started both by the port monitors
+(for example, \f3inetd\f1 or \f3listen\f1)
+or by itself.
+When it is started by a port monitor,
+it creates servers only for the transport for which
+the file descriptor \f30\fP was passed.
+The name of the transport must be specified
+by setting up the environment variable
+\f3PM_TRANSPORT\f1.
+When the server generated by
+\f3rpcgen\f1
+is executed,
+it creates server handles for all the transports
+specified in
+\f3NETPATH\f1
+environment variable,
+or if it is unset,
+it creates server handles for all the visible transports from
+\f3/etc/netconfig\f1
+file.
+Note:
+the transports are chosen at run time and not at compile time.
+When the server is self-started,
+it backgrounds itself by default.
+A special define symbol
+\f3RPC_SVC_FG\f1
+can be used to run the server process in foreground.
+.LP
+The second synopsis provides special features which allow
+for the creation of more sophisticated RPC servers.
+These features include support for user provided
+\f3#defines\f1
+and RPC dispatch tables.
+The entries in the RPC dispatch table contain:
+.RS
+.PD 0
+.TP 3
+\(bu
+pointers to the service routine corresponding to that procedure,
+.TP
+\(bu
+a pointer to the input and output arguments
+.TP
+\(bu
+the size of these routines
+.PD
+.RE
+A server can use the dispatch table to check authorization
+and then to execute the service routine;
+a client library may use it to deal with the details of storage
+management and XDR data conversion.
+.LP
+The other three synopses shown above are used when
+one does not want to generate all the output files,
+but only a particular one.
+See the
+.SM EXAMPLES
+section below for examples of
+.B rpcgen
+usage.
+When
+\f3rpcgen\f1
+is executed with the
+\f3\-s\f1
+option,
+it creates servers for that particular class of transports.
+When
+executed with the
+\f3\-n\f1
+option,
+it creates a server for the transport specified by
+\f2netid\f1.
+If
+\f2infile\f1
+is not specified,
+\f3rpcgen\f1
+accepts the standard input.
+.LP
+The C preprocessor,
+\f3cc \-E\f1
+is run on the input file before it is actually interpreted by
+\f3rpcgen\f1.
+For each type of output file,
+\f3rpcgen\f1
+defines a special preprocessor symbol for use by the
+\f3rpcgen\f1
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
+.LP
+.PD 0
+.RS
+.TP 12
+\f3RPC_HDR\f1
+defined when compiling into headers
+.TP
+\f3RPC_XDR\f1
+defined when compiling into XDR routines
+.TP
+\f3RPC_SVC\f1
defined when compiling into server-side stubs
-.It Dv RPC_CLNT
+.TP
+\f3RPC_CLNT\f1
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
+.TP
+\f3RPC_TBL\f1
+defined when compiling into RPC dispatch tables
+.RE
+.PD
+.LP
+Any line beginning with
+``\f3%\f1''
+is passed directly into the output file,
+uninterpreted by
+\f3rpcgen\f1.
+To specify the path name of the C preprocessor use \f3\-Y\f1 flag.
+.LP
+For every data type referred to in
+\f2infile\f1,
+\f3rpcgen\f1
+assumes that there exists a
+routine with the string
+\f3xdr_\f1
+prepended to the name of the data type.
+If this routine does not exist in the RPC/XDR
+library, it must be provided.
+Providing an undefined data type
+allows customization of XDR routines.
+.br
+.ne 10
+.SH OPTIONS
+.TP 15
+\f3\-a\f1
+Generate all files, including sample files.
+.TP
+\f3\-b\f1
+Backward compatibility mode.
+Generate transport specific RPC code for older versions
+of the operating system.
+.IP
+Note: in FreeBSD, this compatibility flag is turned on by
+default since FreeBSD supports only the older ONC RPC library.
+.TP
+\f3\-c\f1
+Compile into XDR routines.
+.TP
+\f3\-C\f1
+Generate header and stub files which can be used with
+.SM ANSI C
+compilers. Headers generated with this flag can also be
+used with C++ programs.
+.TP
+\f3\-D\f2name\f3[=\f2value\f3]\f1
+Define a symbol
+\f2name\f1.
+Equivalent to the
+\f3#define\f1
+directive in the source.
+If no
+\f2value\f1
+is given,
+\f2value\f1
+is defined as \f31\f1.
+This option may be specified more than once.
+.TP
+\f3\-h\f1
Compile into
-.Tn XDR
-routines.
-.It Fl h
-Compile into C data-definitions (a header file).
-.It Fl l
+\f3C\f1
+data-definitions (a header).
+\f3\-T\f1
+option can be used in conjunction to produce a
+header which supports RPC dispatch tables.
+.TP
+\f3\-i \f2size\f1
+Size at which to start generating inline code.
+This option is useful for optimization. The default size is 5.
+.IP
+Note: in order to provide backwards compatibility with the older
+.B rpcgen
+on the FreeBSD platform, the default is actually 0 (which means
+that inline code generation is disabled by default). You must specify
+a non-zero value explicitly to override this default.
+.TP
+\f3\-I\f1
+Compile support for
+.BR inetd (1M)
+in the server side stubs.
+Such servers can be self-started or can be started by \f3inetd\f1.
+When the server is self-started, it backgrounds itself by default.
+A special define symbol \f3RPC_SVC_FG\f1 can be used to run the
+server process in foreground, or the user may simply compile without
+the \f3\-I\f1 option.
+.br
+.ne 5
+.IP
+If there are no pending client requests, the
+\f3inetd\f1 servers exit after 120 seconds (default).
+The default can be changed with the
+.B \-K
+option.
+All the error messages for \f3inetd\f1 servers
+are always logged with
+.BR syslog (3).
+.\" .IP
+.\" Note:
+.\" this option is supported for backward compatibility only.
+.\" By default,
+.\" .B rpcgen
+.\" generates servers that can be invoked through portmonitors.
+.TP
+.BI \-K " seconds"
+By default, services created using \f3rpcgen\fP and invoked through
+port monitors wait \f3120\fP seconds
+after servicing a request before exiting.
+That interval can be changed using the \f3\-K\fP flag.
+To create a server that exits immediately upon servicing a request,
+use
+.BR "\-K\ 0".
+To create a server that never exits, the appropriate argument is
+\f3\-K \-1\fP.
+.IP
+When monitoring for a server,
+some portmonitors, like
+.BR listen (1M),
+.I 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, \f3rpcgen\fP should be used with \f3\-K 0\fP.
+.TP
+\f3\-l\f1
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
+.TP
+.B \-L
+When the servers are started in foreground, use
+.BR syslog (3)
+to log the server errors instead of printing them on the standard
+error.
+.TP
+\f3\-m\f1
+Compile into server-side stubs,
+but do not generate a \(lqmain\(rq routine.
+This option is useful for doing callback-routines
+and for users who need to write their own
+\(lqmain\(rq routine to do initialization.
+.TP
+\f3\-M\f1
+Generate multithread-safe stubs for passing arguments and results between
+rpcgen generated code and user written code. This option is useful
+for users who want to use threads in their code. However, the
+.BR rpc_svc_calls (3N)
+functions are not yet MT-safe, which means that rpcgen generated server-side
+code will not be MT-safe.
+.TP
+.B \-N
+This option allows procedures to have multiple arguments.
+It also uses the style of parameter passing that closely resembles C.
+So, when passing an argument to a remote procedure, you do not have to
+pass a pointer to the argument, but can pass the argument itself.
+This behavior is different from the old style of
+.B rpcgen
+generated code.
+To maintain backward compatibility,
+this option is not the default.
+.TP
+\f3\-n \f2netid\f1
+Compile into server-side stubs for the transport
+specified by
+\f2netid\f1.
+There should be an entry for
+\f2netid\f1
+in the
+netconfig database.
+This option may be specified more than once,
+so as to compile a server that serves multiple transports.
+.TP
+\f3\-o \f2outfile\f1
+Specify the name of the output file.
+If none is specified,
+standard output is used
+(\f3\-c\f1,
+\f3\-h\f1,
+\f3\-l\f1,
+\f3\-m\f1,
+\f3\-n\f1,
+\f3\-s\f1,
+\f3\-Sc\f1,
+\f3\-Sm\f1,
+\f3\-Ss\f1,
and
-.Fl s
+\f3\-t\f1
modes only).
-.It Fl s Ar transport
-Compile into server-side stubs, using the the given transport. The
-supported transports are
-.Tn udp
+.TP
+\f3\-s \f2nettype\f1
+Compile into server-side stubs for all the
+transports belonging to the class
+\f2nettype\f1.
+The supported classes are
+\f3netpath\f1,
+\f3visible\f1,
+\f3circuit_n\f1,
+\f3circuit_v\f1,
+\f3datagram_n\f1,
+\f3datagram_v\f1,
+\f3tcp\f1,
+and
+\f3udp\f1
+(see
+.BR rpc (3N)
+for the meanings associated with these classes).
+This option may be specified more than once.
+Note:
+the transports are chosen at run time and not at compile time.
+.TP
+\f3\-Sc\f1
+Generate sample client code that uses remote procedure calls.
+.br
+.ne 5
+.TP
+\f3\-Sm\f1
+Generate a sample Makefile which can be used for compiling the
+application.
+.TP
+\f3\-Ss\f1
+Generate sample server code that uses remote procedure calls.
+.TP
+\f3\-t\f1
+Compile into RPC dispatch table.
+.TP
+\f3\-T\f1
+Generate the code to support RPC dispatch tables.
+.IP
+The options
+\f3\-c\f1,
+\f3\-h\f1,
+\f3\-l\f1,
+\f3\-m\f1,
+\f3\-s\f1,
+\f3\-Sc\f1,
+\f3\-Sm\f1,
+\f3\-Ss\f1,
+and
+\f3\-t\f1
+are used exclusively to generate a particular type of file,
+while the options
+\f3\-D\f1
+and
+\f3\-T\f1
+are global and can be used with the other options.
+.TP
+\f3\-Y\f2 pathname\f1
+Give the name of the directory where
+.B rpcgen
+will start looking for the C-preprocessor.
+.br
+.ne 5
+.SH EXAMPLES
+The following example:
+.LP
+.RS
+.B example% rpcgen \-T prot.x
+.RE
+.LP
+generates all the five files:
+.BR prot.h ,
+.BR prot_clnt.c ,
+.BR prot_svc.c ,
+.B prot_xdr.c
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.
+.BR prot_tbl.i .
+.LP
+The following example sends the C data-definitions (header)
+to the standard output.
+.LP
+.RS
+.B example% rpcgen \-h prot.x
+.RE
+.LP
+To send the test version of the
+.BR -DTEST ,
+server side stubs for
+all the transport belonging to the class
+.B datagram_n
+to standard output, use:
+.LP
+.RS
+.B example% rpcgen \-s datagram_n \-DTEST prot.x
+.RE
+.LP
+To create the server side stubs for the transport indicated
+by
+\f2netid\f1
+\f3tcp\f1,
+use:
+.LP
+.RS
+.B example% rpcgen \-n tcp \-o prot_svc.c prot.x
+.RE
+.SH "SEE ALSO"
+.BR cc (1B),
+.BR inetd (1M),
+.BR listen (1M),
+.BR syslog (3),
+.BR rpc (3N),
+.\" .BR rpc_svc_calls (3N)
+.LP
+The
+.B rpcgen
+chapter in the
+.TZ NETP
+manual.
OpenPOWER on IntegriCloud