From 71a0fb455d8f8c71c5f676c6e8dc37aed01adae8 Mon Sep 17 00:00:00 2001 From: pk Date: Sun, 11 Jun 1995 21:49:50 +0000 Subject: [PATCH] Clean up import & propagate NetBSD changes. Add RCS Ids. Fix a number of bugs. Note: this version supports ANSI C code generation. --- usr.bin/rpcgen/Makefile | 8 +- usr.bin/rpcgen/rpc_clntout.c | 161 +++++-- usr.bin/rpcgen/rpc_cout.c | 579 +++++++++++++++++++---- usr.bin/rpcgen/rpc_hout.c | 252 +++++++--- usr.bin/rpcgen/rpc_main.c | 858 ++++++++++++++++++++++++++++++---- usr.bin/rpcgen/rpc_parse.c | 327 ++++++++++--- usr.bin/rpcgen/rpc_parse.h | 48 +- usr.bin/rpcgen/rpc_sample.c | 10 +- usr.bin/rpcgen/rpc_scan.c | 93 ++-- usr.bin/rpcgen/rpc_scan.h | 41 +- usr.bin/rpcgen/rpc_svcout.c | 864 +++++++++++++++++++++++++++++++---- usr.bin/rpcgen/rpc_tblout.c | 6 +- usr.bin/rpcgen/rpc_util.c | 201 +++++--- usr.bin/rpcgen/rpc_util.h | 120 +++-- usr.bin/rpcgen/rpcgen.1 | 452 ++++++++++++++---- 15 files changed, 3345 insertions(+), 675 deletions(-) diff --git a/usr.bin/rpcgen/Makefile b/usr.bin/rpcgen/Makefile index f3551adf0665..948fb3717f4f 100644 --- a/usr.bin/rpcgen/Makefile +++ b/usr.bin/rpcgen/Makefile @@ -1,7 +1,9 @@ -# $Id: Makefile,v 1.3 1993/08/23 21:21:49 jtc Exp $ - +# $NetBSD: Makefile,v 1.4 1995/06/11 21:49:50 pk Exp $ +# PROG= rpcgen SRCS= rpc_clntout.c rpc_cout.c rpc_hout.c rpc_main.c rpc_parse.c rpc_scan.c \ - rpc_svcout.c rpc_util.c + rpc_svcout.c rpc_util.c rpc_sample.c rpc_tblout.c + +CFLAGS += -ansi .include diff --git a/usr.bin/rpcgen/rpc_clntout.c b/usr.bin/rpcgen/rpc_clntout.c index 922415399d52..82db704c0fac 100644 --- a/usr.bin/rpcgen/rpc_clntout.c +++ b/usr.bin/rpcgen/rpc_clntout.c @@ -1,35 +1,36 @@ -/* @(#)rpc_clntout.c 2.1 88/08/01 4.0 RPCSRC */ +/* $NetBSD: rpc_clntout.c,v 1.4 1995/06/11 21:49:52 pk Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. Users * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * + * program developed by the user or with the express written consent of + * Sun Microsystems, Inc. + * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * + * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. - * + * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. - * + * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. - * + * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 */ + #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.3 1995/03/06 04:59:08 cgd Exp $"; +static char sccsid[] = "@(#)rpc_clntout.c 1.11 89/02/22 (C) 1987 SMI"; #endif /* @@ -37,13 +38,18 @@ static char rcsid[] = "$Id: rpc_clntout.c,v 1.3 1995/03/06 04:59:08 cgd Exp $"; * Copyright (C) 1987, Sun Microsytsems, Inc. */ #include -#include +#include +#include #include "rpc_parse.h" #include "rpc_util.h" -#define DEFAULT_TIMEOUT 25 /* in seconds */ +static write_program __P((definition *)); +static void printbody __P((proc_list *)); -static int write_program(), printbody(); +extern pdeclaration(); + +#define DEFAULT_TIMEOUT 25 /* in seconds */ +static char RESULT[] = "clnt_res"; void @@ -52,9 +58,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 +70,6 @@ write_stubs() } } - static write_program(def) definition *def; @@ -78,18 +83,70 @@ write_program(def) 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"); + printarglist( proc, "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, addargname, addargtype ) + proc_list *proc; + 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); + f_print(fout, "*argp, %s%s)\n", addargtype, addargname ); + } else { + f_print(fout, "(argp, %s)\n", addargname); + f_print(fout, "\t"); + ptype(proc->args.decls->decl.prefix, proc->args.decls->decl.type, 1); + f_print(fout, "*argp;\n"); + } + } else if (streq( proc->args.decls->decl.type, "void")) { + /* newstyle, 0 argument */ + if( Cflag ) + f_print(fout, "(%s%s)\n", addargtype, addargname ); + else + f_print(fout, "(%s)\n", addargname); + } else { + /* new style, 1 or multiple arguments */ + if( !Cflag ) { + f_print(fout, "("); + for (l = proc->args.decls; l != NULL; l = l->next) + f_print(fout, "%s, ", l->decl.name); + f_print(fout, "%s)\n", addargname ); + for (l = proc->args.decls; l != NULL; l = l->next) { + pdeclaration(proc->args.argname, &l->decl, 1, ";\n" ); + } + } else { /* C++ style header */ + f_print(fout, "("); + for(l = proc->args.decls; l != NULL; l = l->next) { + pdeclaration(proc->args.argname, &l->decl, 0, ", " ); + } + f_print(fout, " %s%s)\n", addargtype, addargname ); + } + } + + if( !Cflag ) + f_print(fout, "\t%s%s;\n", addargtype, addargname ); +} + + + static char * ampr(type) char *type; @@ -101,30 +158,68 @@ ampr(type) } } -static +static void printbody(proc) proc_list *proc; { + 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, "\tstatic "); if (streq(proc->res_type, "void")) { f_print(fout, "char "); } else { ptype(proc->res_prefix, proc->res_type, 0); } - f_print(fout, "res;\n"); + f_print(fout, "%s;\n",RESULT); f_print(fout, "\n"); - f_print(fout, "\tmemset((char *)%sres, 0, 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, "\tmemset((char *)%s%s, 0, sizeof(%s));\n", + ampr(proc->res_type ), RESULT, RESULT); + if (newstyle && !args2 && (streq( proc->args.decls->decl.type, "void"))) { + /* newstyle, 0 arguments */ + f_print(fout, + "\tif (clnt_call(clnt, %s, xdr_void", proc->proc_name); + f_print(fout, + ", NULL, xdr_%s, %s,%s, TIMEOUT) != RPC_SUCCESS) {\n", + stringfix(proc->res_type), ampr(proc->res_type), RESULT); + + } else if ( newstyle && args2) { + /* newstyle, multiple arguments: stuff arguments into structure */ + for (l = proc->args.decls; l != NULL; l = l->next) { + f_print(fout, "\targ.%s = %s;\n", + l->decl.name, l->decl.name); + } + f_print(fout, + "\tif (clnt_call(clnt, %s, xdr_%s", proc->proc_name, + proc->args.argname); + f_print(fout, + ", &arg, xdr_%s, %s%s, TIMEOUT) != RPC_SUCCESS) {\n", + stringfix(proc->res_type), + ampr(proc->res_type), RESULT); + } else { /* single argument, new or old style */ + f_print(fout, + "\tif (clnt_call(clnt, %s, xdr_%s, %s%s, xdr_%s, %s%s, TIMEOUT) != RPC_SUCCESS) {\n", + proc->proc_name, + stringfix(proc->args.decls->decl.type), + (newstyle ? "&" : ""), + (newstyle ? proc->args.decls->decl.name : "argp"), + stringfix(proc->res_type), + ampr(proc->res_type),RESULT); + } 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)); + f_print(fout, "\treturn ((void *)%s%s);\n", + ampr(proc->res_type),RESULT); } else { - f_print(fout, "\treturn (%sres);\n", ampr(proc->res_type)); + 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 1e9586d4c6f6..536b25ecbd3b 100644 --- a/usr.bin/rpcgen/rpc_cout.c +++ b/usr.bin/rpcgen/rpc_cout.c @@ -1,60 +1,90 @@ -/* @(#)rpc_cout.c 2.1 88/08/01 4.0 RPCSRC */ +/* $NetBSD: rpc_cout.c,v 1.4 1995/06/11 21:49:53 pk Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. Users * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * + * program developed by the user or with the express written consent of + * Sun Microsystems, Inc. + * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * + * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. - * + * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. - * + * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. - * + * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 */ + #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.3 1993/08/01 18:09:22 mycroft 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 */ +#include #include -#include -#include "rpc_util.h" +#include #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 findtype __P((definition *, char *)); +static undefined __P((char *)); +static print_generic_header __P((char *, int)); +static print_header __P((definition *)); +static print_prog_header __P((proc_list *)); +static print_trailer __P((void)); +static print_ifopen __P((int, char *)); +static print_ifarg __P((char *)); +static print_ifsizeof __P((char *, char *)); +static print_ifclose __P((int)); +static print_ifstat __P((int, char *, char *, relation, char *, char *, char *)); +static emit_num __P((definition *)); +static emit_program __P((definition *)); +static emit_enum __P((definition *)); +static emit_union __P((definition *)); +static emit_struct __P((definition *)); +static emit_typedef __P((definition *)); +static print_stat __P((int, declaration *)); /* - * 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: @@ -76,8 +106,9 @@ emit(def) static findtype(def, type) definition *def; - char *type; + char *type; { + if (def->def_kind == DEF_PROGRAM || def->def_kind == DEF_CONST) { return (0); } else { @@ -87,30 +118,69 @@ findtype(def, type) static undefined(type) - char *type; + char *type; { definition *def; def = (definition *) FINDVAL(defined, type, findtype); + + return (def == NULL); } +static +print_generic_header(procname, pointerp) + char *procname; + int pointerp; +{ + f_print(fout, "\n"); + f_print(fout, "bool_t\n"); + if (Cflag) { + f_print(fout, "xdr_%s(", procname); + f_print(fout, "XDR *xdrs, "); + f_print(fout, "%s ", procname); + if (pointerp) + f_print(fout, "*"); + f_print(fout, "objp)\n{\n\n"); + } else { + f_print(fout, "xdr_%s(xdrs, objp)\n", procname); + f_print(fout, "\tXDR *xdrs;\n"); + f_print(fout, "\t%s ", procname); + if (pointerp) + f_print(fout, "*"); + f_print(fout, "objp;\n{\n\n"); + } +} static print_header(def) definition *def; { - space(); - f_print(fout, "bool_t\n"); - f_print(fout, "xdr_%s(xdrs, objp)\n", def->def_name); - f_print(fout, "\tXDR *xdrs;\n"); - f_print(fout, "\t%s ", def->def_name); - if (def->def_kind != DEF_TYPEDEF || - !isvectordef(def->def.ty.old_type, def->def.ty.rel)) { - f_print(fout, "*"); - } - f_print(fout, "objp;\n"); - f_print(fout, "{\n"); + + 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, "\t register long *buf;\n\n"); + +} + +static +print_prog_header(plist) + proc_list *plist; +{ + print_generic_header(plist->args.argname, 1); } static @@ -118,72 +188,63 @@ print_trailer() { f_print(fout, "\treturn (TRUE);\n"); f_print(fout, "}\n"); - space(); } static print_ifopen(indent, name) - int indent; - char *name; + int indent; + char *name; { tabify(fout, indent); - f_print(fout, "if (!xdr_%s(xdrs", name); + f_print(fout, " if (!xdr_%s(xdrs", name); } - static print_ifarg(arg) - char *arg; + char *arg; { f_print(fout, ", %s", arg); } - static print_ifsizeof(prefix, type) - char *prefix; - char *type; + char *prefix; + char *type; { 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("); 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); } } static print_ifclose(indent) - int indent; + int indent; { f_print(fout, ")) {\n"); tabify(fout, indent); - f_print(fout, "\treturn (FALSE);\n"); + f_print(fout, "\t return (FALSE);\n"); tabify(fout, indent); - f_print(fout, "}\n"); -} - -static -space() -{ - f_print(fout, "\n\n"); + f_print(fout, " }\n"); } static print_ifstat(indent, prefix, type, rel, amax, objname, name) - int indent; - char *prefix; - char *type; + int indent; + char *prefix; + char *type; relation rel; - char *amax; - char *objname; - char *name; + char *amax; + char *objname; + char *name; { - char *alt = NULL; + char *alt = NULL; switch (rel) { case REL_POINTER: @@ -195,9 +256,10 @@ print_ifstat(indent, prefix, type, rel, amax, objname, name) case REL_VECTOR: if (streq(type, "string")) { alt = "string"; - } else if (streq(type, "opaque")) { - alt = "opaque"; - } + } else + if (streq(type, "opaque")) { + alt = "opaque"; + } if (alt) { print_ifopen(indent, alt); print_ifarg(objname); @@ -214,9 +276,10 @@ print_ifstat(indent, prefix, type, rel, amax, objname, name) case REL_ARRAY: if (streq(type, "string")) { alt = "string"; - } else if (streq(type, "opaque")) { - alt = "bytes"; - } + } else + if (streq(type, "opaque")) { + alt = "bytes"; + } if (streq(type, "string")) { print_ifopen(indent, alt); print_ifarg(objname); @@ -229,10 +292,10 @@ 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", - objname, name, objname, name); + objname, name, objname, name); } else { f_print(fout, "&%s->%s_val, (u_int *)&%s->%s_len", - objname, name, objname, name); + objname, name, objname, name); } } print_ifarg(amax); @@ -248,7 +311,6 @@ print_ifstat(indent, prefix, type, rel, amax, objname, name) print_ifclose(indent); } - /* ARGSUSED */ static emit_enum(def) @@ -259,6 +321,27 @@ 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) @@ -267,20 +350,30 @@ emit_union(def) declaration *dflt; case_list *cl; declaration *cs; - char *object; - char *format = "&objp->%s_u.%s"; + 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); + strlen(cs->name) + 1); + if (isvectordef(cs->type, cs->rel)) { + s_print(object, vecformat, def->def_name, + cs->name); + } else { + s_print(object, format, def->def_name, + cs->name); + } print_ifstat(2, cs->prefix, cs->type, cs->rel, cs->array_max, - object, cs->name); + object, cs->name); free(object); } f_print(fout, "\t\tbreak;\n"); @@ -290,10 +383,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,55 +401,342 @@ emit_union(def) f_print(fout, "\tdefault:\n"); f_print(fout, "\t\treturn (FALSE);\n"); } + f_print(fout, "\t}\n"); } - - static emit_struct(def) definition *def; { decl_list *dl; + int i, j, size, flag; + decl_list *cur, *psav; + bas_type *ptr; + char *sizestr, *plus; + char ptemp[256]; + int can_inline; - for (dl = def->def.st.decls; dl != NULL; dl = dl->next) { - print_stat(&dl->decl); + + if (inline == 0) { + 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, "\t int i;\n"); + break; + } + size = 0; + can_inline = 0; + for (dl = def->def.st.decls; dl != NULL; dl = dl->next) + if ((dl->decl.prefix == NULL) && + ((ptr = find_type(dl->decl.type)) != NULL) && + ((dl->decl.rel == REL_ALIAS) || (dl->decl.rel == REL_VECTOR))) { + + if (dl->decl.rel == REL_ALIAS) + size += ptr->length; + else { + can_inline = 1; + break; /* can be inlined */ + }; + } else { + if (size >= inline) { + can_inline = 1; + break; /* can be inlined */ + } + size = 0; + } + if (size > inline) + can_inline = 1; + + if (can_inline == 0) { /* can not inline, drop back to old mode */ + for (dl = def->def.st.decls; dl != NULL; dl = dl->next) + print_stat(1, &dl->decl); + return; + }; + + + + + flag = PUT; + for (j = 0; j < 2; j++) { + + if (flag == PUT) + f_print(fout, "\n\t if (xdrs->x_op == XDR_ENCODE) {\n"); + else + f_print(fout, "\n \t return (TRUE);\n\t} else if (xdrs->x_op == XDR_DECODE) {\n"); + + + i = 0; + size = 0; + sizestr = NULL; + for (dl = def->def.st.decls; dl != NULL; dl = dl->next) { /* xxx */ + + /* now walk down the list and check for basic types */ + if ((dl->decl.prefix == NULL) && ((ptr = find_type(dl->decl.type)) != NULL) && ((dl->decl.rel == REL_ALIAS) || (dl->decl.rel == REL_VECTOR))) { + if (i == 0) + cur = dl; + i++; + + if (dl->decl.rel == REL_ALIAS) + size += ptr->length; + else { + /* this is required to handle arrays */ + + if (sizestr == NULL) + plus = " "; + else + plus = "+"; + + if (ptr->length != 1) + s_print(ptemp, " %s %s * %d", plus, dl->decl.array_max, ptr->length); + else + s_print(ptemp, " %s %s ", plus, dl->decl.array_max); + + /* now concatenate to sizestr !!!! */ + if (sizestr == NULL) + sizestr = strdup(ptemp); + else { + sizestr = (char *)realloc(sizestr, strlen(sizestr) + strlen(ptemp) + 1); + if (sizestr == NULL) { + + f_print(stderr, "Fatal error : no memory \n"); + crash(); + }; + sizestr = strcat(sizestr, ptemp); /* build up length of + * array */ + + } + } + + } else { + if (i > 0) + if (sizestr == NULL && size < inline) { + /* don't expand into inline + * code if size < inline */ + while (cur != dl) { + print_stat(1, &cur->decl); + cur = cur->next; + } + } else { + + + + /* were already looking at a + * xdr_inlineable structure */ + if (sizestr == NULL) + f_print(fout, "\t buf = (long *)XDR_INLINE(xdrs,%d * BYTES_PER_XDR_UNIT);", + size); + else + if (size == 0) + f_print(fout, + "\t buf = (long *)XDR_INLINE(xdrs,%s * BYTES_PER_XDR_UNIT);", + sizestr); + else + f_print(fout, + "\t buf = (long *)XDR_INLINE(xdrs,(%d + %s)* BYTES_PER_XDR_UNIT);", + size, sizestr); + + f_print(fout, "\n\t if (buf == NULL) {\n"); + + psav = cur; + while (cur != dl) { + print_stat(2, &cur->decl); + cur = cur->next; + } + + f_print(fout, "\n\t }\n\t else {\n"); + + cur = psav; + while (cur != dl) { + emit_inline(&cur->decl, flag); + cur = cur->next; + } + + f_print(fout, "\t }\n"); + } + size = 0; + i = 0; + sizestr = NULL; + print_stat(1, &dl->decl); + } + + } + if (i > 0) + if (sizestr == NULL && size < inline) { + /* don't expand into inline code if size < + * inline */ + while (cur != dl) { + print_stat(1, &cur->decl); + cur = cur->next; + } + } else { + + /* were already looking at a xdr_inlineable + * structure */ + if (sizestr == NULL) + f_print(fout, "\t\tbuf = (long *)XDR_INLINE(xdrs,%d * BYTES_PER_XDR_UNIT);", + size); + else + if (size == 0) + f_print(fout, + "\t\tbuf = (long *)XDR_INLINE(xdrs,%s * BYTES_PER_XDR_UNIT);", + sizestr); + else + f_print(fout, + "\t\tbuf = (long *)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(2, &cur->decl); + cur = cur->next; + } + f_print(fout, "\n\t }\n\t else {\n"); + + cur = psav; + while (cur != dl) { + emit_inline(&cur->decl, flag); + cur = cur->next; + } + + f_print(fout, "\t }\n"); + + } + flag = GET; + } + f_print(fout, "\t return(TRUE);\n\t}\n\n"); + + /* now take care of XDR_FREE case */ + + for (dl = def->def.st.decls; dl != NULL; dl = dl->next) + print_stat(1, &dl->decl); } - - - static emit_typedef(def) definition *def; { - char *prefix = def->def.ty.old_prefix; - char *type = def->def.ty.old_type; - char *amax = def->def.ty.array_max; + char *prefix = def->def.ty.old_prefix; + char *type = def->def.ty.old_type; + char *amax = def->def.ty.array_max; relation rel = def->def.ty.rel; + print_ifstat(1, prefix, type, rel, amax, "objp", def->def_name); } - - - - static -print_stat(dec) +print_stat(indent, dec) declaration *dec; + int indent; { - char *prefix = dec->prefix; - char *type = dec->type; - char *amax = dec->array_max; + char *prefix = dec->prefix; + char *type = dec->type; + char *amax = dec->array_max; relation rel = dec->rel; - char name[256]; + char name[256]; if (isvectordef(type, rel)) { s_print(name, "objp->%s", dec->name); } else { s_print(name, "&objp->%s", dec->name); } - print_ifstat(1, prefix, type, rel, amax, name, dec->name); + print_ifstat(indent, prefix, type, rel, amax, name, dec->name); +} + + +char *upcase __P((char *)); + + +emit_inline(decl, flag) + declaration *decl; + int flag; +{ + +/*check whether an array or not */ + + switch (decl->rel) { + case REL_ALIAS: + emit_single_in_line(decl, flag, REL_ALIAS); + break; + case REL_VECTOR: + f_print(fout, "\t\t{ register %s *genp; \n", decl->type); + f_print(fout, "\t\t for ( i = 0,genp=objp->%s;\n \t\t\ti < %s; i++){\n\t\t", + decl->name, decl->array_max); + emit_single_in_line(decl, flag, REL_VECTOR); + f_print(fout, "\t\t }\n\t\t };\n"); + + } +} + +emit_single_in_line(decl, flag, rel) + declaration *decl; + int flag; + relation rel; +{ + char *upp_case; + int freed = 0; + + + + if (flag == PUT) + f_print(fout, "\t\t IXDR_PUT_"); + else + if (rel == REL_ALIAS) + f_print(fout, "\t\t objp->%s = IXDR_GET_", decl->name); + else + f_print(fout, "\t\t *genp++ = IXDR_GET_"); + + upp_case = upcase(decl->type); + + /* hack - XX */ + if (strcmp(upp_case, "INT") == 0) { + free(upp_case); + freed = 1; + upp_case = "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 567cdc9b5d36..4b3784048644 100644 --- a/usr.bin/rpcgen/rpc_hout.c +++ b/usr.bin/rpcgen/rpc_hout.c @@ -1,49 +1,59 @@ -/* @(#)rpc_hout.c 2.1 88/08/01 4.0 RPCSRC */ +/* $NetBSD: rpc_hout.c,v 1.4 1995/06/11 21:49:55 pk Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. Users * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * + * program developed by the user or with the express written consent of + * Sun Microsystems, Inc. + * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * + * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. - * + * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. - * + * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. - * + * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 */ -#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.3 1993/08/01 18:09:21 mycroft Exp $"; -#endif -static int pconstdef(), pstructdef(), puniondef(), pdefine(), pprogramdef(), - penumdef(), ptypedef(), pdeclaration(), undefined2(); +#ifndef lint +static char sccsid[] = "@(#)rpc_hout.c 1.12 89/02/22 (C) 1987 SMI"; +#endif /* * rpc_hout.c, Header file outputter for the RPC protocol compiler - * Copyright (C) 1987, Sun Microsystems, Inc. */ +#include #include #include -#include "rpc_util.h" #include "rpc_parse.h" +#include "rpc_util.h" +static pconstdef __P((definition *)); +static pargdef __P((definition *)); +static pstructdef __P((definition *)); +static puniondef __P((definition *)); +static pprogramdef __P((definition *)); +static penumdef __P((definition *)); +static ptypedef __P((definition *)); +static pdefine __P((char *, char *)); +static puldefine __P((char *, char *)); +static define_printed __P((proc_list *, version_list *)); +static undefined2 __P((char *, char *)); +static parglist __P((proc_list *, char *)); /* * Print the C-version of an xdr definition @@ -52,6 +62,10 @@ 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 +90,45 @@ 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); - } - if (def->def_kind != DEF_CONST) { - f_print(fout, "\n"); + pxdrfuncdecl( def->def_name, + def->def_kind != DEF_TYPEDEF || + !isvectordef(def->def.ty.old_type, def->def.ty.rel)); + } } + +void +print_funcdef(def) + definition *def; +{ + switch (def->def_kind) { + case DEF_PROGRAM: + f_print(fout, "\n"); + pprogramdef(def); + break; + } +} + +pxdrfuncdecl( name, pointerp ) +char* name; +int pointerp; +{ + + f_print(fout,"#ifdef __cplusplus \n"); + f_print(fout, "extern \"C\" bool_t xdr_%s(XDR *, %s%s);\n", + name, + name, pointerp ? ("*") : ""); + f_print(fout,"#elif __STDC__ \n"); + f_print(fout, "extern bool_t xdr_%s(XDR *, %s%s);\n", + name, + name, pointerp ? ("*") : ""); + f_print(fout,"#else /* Old Style C */ \n"); + f_print(fout, "bool_t xdr_%s();\n", name); + f_print(fout,"#endif /* Old Style C */ \n\n"); +} + + static pconstdef(def) definition *def; @@ -90,7 +136,43 @@ pconstdef(def) pdefine(def->def_name, def->def.co); } -static +/* 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); + pxdrfuncdecl( name,NULL ); + f_print( fout, "\n" ); + } + } + +} + + +static pstructdef(def) definition *def; { @@ -99,7 +181,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,19 +204,18 @@ 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; @@ -172,48 +253,110 @@ define_printed(stop, start) /* NOTREACHED */ } - static pprogramdef(def) definition *def; { version_list *vers; proc_list *proc; + int i; + char *ext; + + pargdef(def); puldefine(def->def_name, def->def.pr.prog_num); for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) { - puldefine(vers->vers_name, vers->vers_num); - for (proc = vers->procs; proc != NULL; proc = proc->next) { - if (!define_printed(proc, def->def.pr.versions)) { - puldefine(proc->proc_name, proc->proc_num); - } - pprocdef(proc, vers); + if (tblflag) { + f_print(fout, "extern struct rpcgen_table %s_%s_table[];\n", + locase(def->def_name), vers->vers_num); + f_print(fout, "extern %s_%s_nproc;\n", + locase(def->def_name), vers->vers_num); } + puldefine(vers->vers_name, vers->vers_num); + + /* + * Print out 3 definitions, one for ANSI-C, another for C++, + * a third for old style C + */ + + for(i=0;i<3;i++){ + if(i==0){ + f_print(fout,"\n#ifdef __cplusplus\n"); + ext="extern \"C\" "; + }else if ( i== 1){ + f_print(fout,"\n#elif __STDC__\n"); + ext="extern " ; + }else{ + f_print(fout,"\n#else /* Old Style C */ \n"); + ext="extern "; + } + + + for (proc = vers->procs; proc != NULL; proc = proc->next) { + if (!define_printed(proc, def->def.pr.versions)) { + puldefine(proc->proc_name, proc->proc_num); + } + f_print(fout,"%s",ext); + pprocdef(proc, vers, "CLIENT *", 0,i); + f_print(fout,"%s",ext); + pprocdef(proc, vers, "struct svc_req *", 1,i); + + } + + } + f_print(fout,"#endif /* Old Style C */ \n"); } } - -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 "); + + ptype( proc->res_prefix, proc->res_type, 1 ); + f_print( fout, "* " ); + if( server_p ) + pvname_svc(proc->proc_name, vp->vers_num); + else + pvname(proc->proc_name, vp->vers_num); + + /* + * mode 0 == cplusplus, mode 1 = ANSI-C, mode 2 = old style C + */ + if(mode == 0 || mode ==1) + parglist( proc, addargtype ); + else + f_print(fout, "();\n"); +} + + +/* print out argument list of procedure */ +static +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)); - } - pvname(proc->proc_name, vp->vers_num); - f_print(fout, "();\n"); + + f_print(fout, "%s);\n", addargtype); } static @@ -285,19 +428,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; @@ -347,11 +489,9 @@ pdeclaration(name, dec, tab) 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 59c86647b4e1..b42d6866f51d 100644 --- a/usr.bin/rpcgen/rpc_main.c +++ b/usr.bin/rpcgen/rpc_main.c @@ -1,115 +1,219 @@ -/* @(#)rpc_main.c 2.2 88/08/01 4.0 RPCSRC */ +/* $NetBSD: rpc_main.c,v 1.6 1995/06/11 21:49:56 pk Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. Users * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * + * program developed by the user or with the express written consent of + * Sun Microsystems, Inc. + * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * + * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. - * + * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. - * + * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. - * + * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 */ + #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.5 1994/01/20 18:21:56 jtc Exp $"; +static char sccsid[] = "@(#)rpc_main.c 1.30 89/03/30 (C) 1987 SMI"; +static char cvsid[] = "$Id: rpc_main.c,v 1.6 1995/06/11 21:49:56 pk Exp $"; #endif /* * rpc_main.c, Top level of the RPC protocol compiler. - * Copyright (C) 1987, Sun Microsystems, Inc. */ #include -#include +#include +#include +#ifdef __TURBOC__ +#define MAXPATHLEN 80 +#include +#include +#include +#else +#include #include -#include "rpc_util.h" +#endif +#include #include "rpc_parse.h" +#include "rpc_util.h" #include "rpc_scan.h" #define EXTEND 1 /* alias for TRUE */ +#define DONT_EXTEND 0 /* alias for FALSE */ + +#define SVR4_CPP "/usr/ccs/lib/cpp" +#define SUNOS_CPP "/lib/cpp" +static int cppDefined = 0; /* explicit path for C preprocessor */ struct commandline { - int cflag; - int hflag; - int lflag; - int sflag; - int mflag; - char *infile; - char *outfile; + int cflag; /* xdr C routines */ + int hflag; /* header file */ + int lflag; /* client side stubs */ + int mflag; /* server side stubs */ + int nflag; /* netid flag */ + int sflag; /* server stubs for the given transport */ + int tflag; /* dispatch Table file */ + int Ssflag; /* produce server sample code */ + int Scflag; /* produce client sample code */ + char *infile; /* input module name */ + char *outfile; /* output module name */ }; + static char *cmdname; -static char CPP[] = "/usr/bin/cpp"; + +static char *svcclosetime = "120"; +static char *CPP = "/usr/bin/cpp"; static char CPPFLAGS[] = "-C"; +static char pathbuf[MAXPATHLEN + 1]; static char *allv[] = { "rpcgen", "-s", "udp", "-s", "tcp", }; static int allc = sizeof(allv)/sizeof(allv[0]); +static char *allnv[] = { + "rpcgen", "-s", "netpath", +}; +static int allnc = sizeof(allnv)/sizeof(allnv[0]); + +#define ARGLISTLEN 20 +#define FIXEDARGS 2 + +static char *arglist[ARGLISTLEN]; +static int argcount = FIXEDARGS; + + +int nonfatalerrors; /* errors */ +int inetdflag/* = 1*/; /* Support for inetd */ /* is now the default */ +int pmflag; /* Support for port monitors */ +int logflag; /* Use syslog instead of fprintf for errors */ +int tblflag; /* Support for dispatch table file */ +int callerflag; /* Generate svc_caller() function */ + +#define INLINE 3 +/*length at which to start doing an inline */ + +int inline=INLINE; /* length at which to start doing an inline. 3 = default + if 0, no xdr_inline code */ + +int indefinitewait; /* If started by port monitors, hang till it wants */ +int exitnow; /* If started by port monitors, exit after the call */ +int timerflag; /* TRUE if !indefinite && !exitnow */ +int newstyle; /* newstyle of passing arguments (by value) */ +int Cflag = 0 ; /* ANSI C syntax */ +static int allfiles; /* generate all files */ +int tirpcflag = 0; /* generating code for tirpc, by default */ + +#ifdef __MSDOS__ +static char *dos_cppfile = NULL; +#endif + +static c_output __P((char *, char *, int, char *)); +static h_output __P((char *, char *, int, char *)); +static s_output __P((int, char **, char *, char *, int, char *, int, int)); +static l_output __P((char *, char *, int, char *)); +static t_output __P((char *, char *, int, char *)); +static svc_output __P((char *, char *, int, char *)); +static clnt_output __P((char *, char *, int, char *)); +static do_registers __P((int, char **)); +static void addarg __P((char *)); +static void putarg __P((int, char *)); +static void clear_args __P((void)); +static void checkfiles __P((char *, char *)); +static int parseargs __P((int, char **, struct commandline *)); +static usage __P((void)); +static options_usage __P((void)); -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(); + + if (cmd.cflag || cmd.hflag || cmd.lflag || cmd.tflag || cmd.sflag || + cmd.mflag || cmd.nflag || cmd.Ssflag || cmd.Scflag ) { + checkfiles(cmd.infile, cmd.outfile); } + else + checkfiles(cmd.infile,NULL); + if (cmd.cflag) { - c_output(cmd.infile, "-DRPC_XDR", !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 { + /* 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"); + } + if (allfiles) { + reinitialize(); + clnt_output(cmd.infile, "-DRPC_CLIENT", EXTEND, "_client.c"); + } } - exit(0); +#ifdef __MSDOS__ + if (dos_cppfile != NULL) { + (void) fclose(fin); + (void) unlink(dos_cppfile); + } +#endif + exit(nonfatalerrors); + /* NOTREACHED */ } /* - * strip path and add extension to filename + * add extension to filename */ static char * extendfile(path, ext) @@ -120,7 +224,7 @@ extendfile(path, ext) char *res; char *p; - if ((file = rindex(path, '/')) == NULL) + if ((file = strrchr(path, '/')) == NULL) file = path; else file++; @@ -129,7 +233,7 @@ extendfile(path, ext) if (res == NULL) { abort(); } - p = rindex(file, '.'); + p = strrchr(file, '.'); if (p == NULL) { p = file + strlen(file); } @@ -146,10 +250,12 @@ 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); @@ -162,6 +268,44 @@ 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" : infile; +#ifdef __MSDOS__ +#define DOSCPP "\\prog\\bc31\\bin\\cpp.exe" + { int retval; + char drive[MAXDRIVE], dir[MAXDIR], name[MAXFILE], ext[MAXEXT]; + char cppfile[MAXPATH]; + char *cpp; + + if ((cpp = searchpath("cpp.exe")) == NULL + && (cpp = getenv("RPCGENCPP")) == NULL) + cpp = DOSCPP; + + putarg(0, cpp); + putarg(1, "-P-"); + putarg(2, CPPFLAGS); + addarg(define); + addarg(infile); + addarg(NULL); + + retval = spawnvp(P_WAIT, arglist[0], arglist); + if (retval != 0) { + fprintf(stderr, "%s: C PreProcessor failed\n", cmdname); + crash(); + } + + fnsplit(infile, drive, dir, name, ext); + fnmerge(cppfile, drive, dir, name, ".i"); + + fin = fopen(cppfile, "r"); + if (fin == NULL) { + f_print(stderr, "%s: ", cmdname); + perror(cppfile); + crash(); + } + dos_cppfile = strdup(cppfile); + if (dos_cppfile == NULL) { + fprintf(stderr, "%s: out of memory\n", cmdname); + crash(); + } + } +#else (void) pipe(pd); switch (fork()) { case 0: + find_cpp(); + putarg(0, CPP); + putarg(1, CPPFLAGS); + addarg(define); + addarg(infile); + addarg((char *)NULL); (void) close(1); (void) dup2(pd[1], 1); (void) close(pd[0]); - execl(CPP, CPP, CPPFLAGS, define, infile, NULL); - perror("execl"); + execv(arglist[0], arglist); + perror("execv"); exit(1); case -1: perror("fork"); @@ -190,6 +380,7 @@ open_input(infile, define) } (void) close(pd[1]); fin = fdopen(pd[0], "r"); +#endif if (fin == NULL) { f_print(stderr, "%s: ", cmdname); perror(infilename); @@ -197,9 +388,47 @@ open_input(infile, define) } } +/* 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; +} + /* * Compile into an XDR routine output file */ + static c_output(infile, define, extend, outfile) char *infile; @@ -212,14 +441,17 @@ c_output(infile, define, extend, outfile) char *outfilename; long tell; + c_initialize(); open_input(infile, define); outfilename = extend ? extendfile(infile, outfile) : outfile; open_output(infile, outfilename); - f_print(fout, "#include \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 \n"); tell = ftell(fout); while (def = get_definition()) { emit(def); @@ -229,9 +461,56 @@ 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; @@ -242,24 +521,45 @@ h_output(infile, define, extend, outfile) definition *def; char *outfilename; long tell; + char *guard; + list *l; open_input(infile, define); outfilename = extend ? extendfile(infile, outfile) : outfile; open_output(infile, outfilename); + add_warning(); + guard = generate_guard( outfilename ? outfilename: infile ); + + f_print(fout,"#ifndef _%s\n#define _%s\n\n", guard, + guard); + + f_print(fout, "#include \n\n"); + 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); + } if (extend && tell == ftell(fout)) { (void) unlink(outfilename); + } else if (tblflag) { + f_print(fout, rpcgen_table_dcl); } + f_print(fout, "\n#endif /* !_%s */\n", guard); } /* * Compile into an RPC service */ static -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; @@ -267,22 +567,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 \n"); - f_print(fout, "#include \n"); + add_warning(); if (infile && (include = extendfile(infile, ".h"))) { f_print(fout, "#include \"%s\"\n", include); free(include); + } else + f_print(fout, "#include \n"); + + f_print(fout, "#include \n"); + f_print(fout, "#include /* getenv, exit */\n"); + if (Cflag) { + f_print (fout, + "#include /* for pmap_unset */\n"); + f_print (fout, "#include /* strcmp */ \n"); } - foundprogram = 0; + f_print(fout, "#include \n"); /*evas*/ + if (strcmp(svcclosetime, "-1") == 0) + indefinitewait = 1; + else if (strcmp(svcclosetime, "0") == 0) + exitnow = 1; + else if (inetdflag || pmflag) { + f_print(fout, "#include \n"); + timerflag = 1; + } + + if( !tirpcflag && inetdflag ) + f_print(fout, "#include /* TIOCNOTTY */\n"); + if( Cflag && (inetdflag || pmflag ) ) { + f_print(fout, "#ifdef __cplusplus\n"); + f_print(fout, "#include /* getdtablesize, open */\n"); + f_print(fout, "#endif /* __cplusplus */\n"); + + if( tirpcflag ) + f_print(fout, "#include /* setsid */\n"); + } + if( tirpcflag ) + f_print(fout, "#include \n"); + + f_print(fout, "#include \n"); + f_print(fout, "#include \n"); + if (inetdflag || !tirpcflag ) { + f_print(fout, "#include \n"); + f_print(fout, "#include \n"); + } + + if ( (netflag || pmflag) && tirpcflag ) { + f_print(fout, "#include \n"); + } + if (/*timerflag &&*/ tirpcflag) + f_print(fout, "#include /* rlimit */\n"); + if (logflag || inetdflag || pmflag) { + f_print(fout, "#ifdef SYSLOG\n"); + f_print(fout, "#include \n"); + f_print(fout, "#else\n"); + f_print(fout, "#define LOG_ERR 1\n"); + f_print(fout, "#define openlog(a, b, c)\n"); + f_print(fout, "#endif\n"); + } + + /* for ANSI-C */ + f_print(fout, "\n#ifdef __STDC__\n#define SIG_PF void(*)(int)\n#endif\n"); + + f_print(fout, "\n#ifdef DEBUG\n#define RPC_SVC_FG\n#endif\n"); + if (timerflag) + f_print(fout, "\n#define _RPCSVC_CLOSEDOWN %s\n", svcclosetime); while (def = get_definition()) { foundprogram |= (def->def_kind == DEF_PROGRAM); } @@ -290,16 +648,22 @@ 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); + if (callerflag) /*EVAS*/ + f_print(fout, "\nstatic SVCXPRT *caller;\n"); /*EVAS*/ + write_most(infile, netflag, nomain); + if (!nomain) { + if( !do_registers(argc, argv) ) { + if (outfilename) + (void) unlink(outfilename); + usage(); + } write_rest(); - write_programs("static"); } } +/* + * generate client side stubs + */ static l_output(infile, define, extend, outfile) char *infile; @@ -309,18 +673,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 \n"); + add_warning(); + if (Cflag) + f_print (fout, "#include /* for memset */\n"); if (infile && (include = extendfile(infile, ".h"))) { f_print(fout, "#include \"%s\"\n", include); free(include); - } - foundprogram = 0; + } else + f_print(fout, "#include \n"); while (def = get_definition()) { foundprogram |= (def->def_kind == DEF_PROGRAM); } @@ -332,33 +698,214 @@ l_output(infile, define, extend, outfile) } /* - * Perform registrations for service output + * generate the dispatch table */ static -do_registers(argc, argv) +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 \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 \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); + } +} + +/* + * Perform registrations for service output + * Return 0 if failed; 1 otherwise. + */ +static +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 0 + 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(); + } + } +#endif } /* * Parse command line arguments */ -static +static int parseargs(argc, argv, cmd) int argc; char *argv[]; struct commandline *cmd; - { int i; int j; @@ -371,15 +918,22 @@ 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; 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]; @@ -387,15 +941,74 @@ parseargs(argc, argv, cmd) for (j = 1; argv[i][j] != 0; j++) { c = argv[i][j]; switch (c) { + case 'A': + callerflag = 1; + break; + case 'a': + allfiles = 1; + break; case 'c': case 'h': case 'l': case 'm': + case 't': if (flag[c]) { return (0); } flag[c] = 1; break; + case 'S': + /* sample flag: Ss or Sc. + Ss means set flag['S']; + Sc means set flag['C']; */ + c = argv[i][++j]; /* get next char */ + if( c == 's' ) + c = 'S'; + else if( c == 'c' ) + c = 'C'; + else + return( 0 ); + + if (flag[c]) { + return (0); + } + flag[c] = 1; + break; + case 'C': /* ANSI C syntax */ + Cflag = 1; + break; + + case 'b': /* turn TIRPC flag off for + generating backward compatible + */ + tirpcflag = 0; + break; + + case 'I': + inetdflag = 1; + break; + case 'N': + newstyle = 1; + break; + case 'L': + logflag = 1; + break; + case 'K': + if (++i == argc) { + return (0); + } + svcclosetime = argv[i]; + goto nextarg; + case 'T': + tblflag = 1; + break; + case 'i' : + if (++i == argc) { + return (0); + } + inline = atoi(argv[i]); + goto nextarg; + case 'n': case 'o': case 's': if (argv[i][j - 1] != '-' || @@ -418,6 +1031,23 @@ parseargs(argc, argv, cmd) 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); @@ -427,18 +1057,92 @@ parseargs(argc, argv, cmd) ; } } + 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']; + + if( tirpcflag ) { + pmflag = inetdflag ? 0 : 1; /* pmflag or inetdflag is always TRUE */ + if( (inetdflag && cmd->nflag)) { /* netid not allowed with inetdflag */ + f_print(stderr, "Cannot use netid flag with inetd flag!\n"); + return (0); + } + } else { /* 4.1 mode */ + pmflag = 0; /* set pmflag only in tirpcmode */ + inetdflag = 1; /* inetdflag is TRUE by default */ + if( cmd->nflag ) { /* netid needs TIRPC */ + f_print( stderr, "Cannot use netid flag without TIRPC!\n"); + return( 0 ); + } + } + + if( newstyle && ( tblflag || cmd->tflag) ) { + f_print( stderr, "Cannot use table flags with newstyle!\n"); + return( 0 ); + } + + /* check no conflicts with file generation flags */ + nflags = cmd->cflag + cmd->hflag + cmd->lflag + cmd->mflag + + cmd->sflag + cmd->nflag + cmd->tflag + cmd->Ssflag + cmd->Scflag; + if (nflags == 0) { if (cmd->outfile != NULL || cmd->infile == NULL) { return (0); } } else if (nflags > 1) { + f_print( stderr, "Cannot have more than one file generation flag!\n"); return (0); } return (1); } + +static +usage() +{ + f_print(stderr, "usage: %s infile\n", cmdname); + f_print(stderr, "\t%s [-a][-b][-C][-Dname[=value]] -i size [-I [-K seconds]] [-A][-L][-M toolkit][-N][-T] infile\n", + cmdname); + f_print(stderr, "\t%s [-c | -h | -l | -m | -t | -Sc | -Ss] [-o outfile] [infile]\n", + cmdname); + f_print(stderr, "\t%s [-s nettype]* [-o outfile] [infile]\n", cmdname); + f_print(stderr, "\t%s [-n netid]* [-o outfile] [infile]\n", cmdname); + options_usage(); + exit(1); +} + +static +options_usage() +{ + f_print(stderr, "options:\n"); + f_print(stderr, "-A\t\tgenerate svc_caller() function\n"); + f_print(stderr, "-a\t\tgenerate all files, including samples\n"); + f_print(stderr, "-b\t\tbackward compatibility mode (generates code for SunOS 4.1)\n"); + f_print(stderr, "-c\t\tgenerate XDR routines\n"); + f_print(stderr, "-C\t\tANSI C mode\n"); + f_print(stderr, "-Dname[=value]\tdefine a symbol (same as #define)\n"); + f_print(stderr, "-h\t\tgenerate header file\n"); + f_print(stderr, "-i size\t\tsize at which to start generating inline code\n"); + f_print(stderr, "-I\t\tgenerate code for inetd support in server (for SunOS 4.1)\n"); + f_print(stderr, "-K seconds\tserver exits after K seconds of inactivity\n"); + f_print(stderr, "-l\t\tgenerate client side stubs\n"); + f_print(stderr, "-L\t\tserver errors will be printed to syslog\n"); + f_print(stderr, "-m\t\tgenerate server side stubs\n"); + f_print(stderr, "-n netid\tgenerate server code that supports named netid\n"); + f_print(stderr, "-N\t\tsupports multiple arguments and call-by-value\n"); + f_print(stderr, "-o outfile\tname of the output file\n"); + f_print(stderr, "-s nettype\tgenerate server code that supports named nettype\n"); + f_print(stderr, "-Sc\t\tgenerate sample client code that uses remote procedures\n"); + f_print(stderr, "-Ss\t\tgenerate sample server code that defines remote procedures\n"); + f_print(stderr, "-t\t\tgenerate RPC dispatch table\n"); + f_print(stderr, "-T\t\tgenerate code to support RPC dispatch tables\n"); + f_print(stderr, "-Y path\t\tdirectory name to find C preprocessor (cpp)\n"); + + exit(1); +} diff --git a/usr.bin/rpcgen/rpc_parse.c b/usr.bin/rpcgen/rpc_parse.c index b1ef10ce9e53..128d2c704639 100644 --- a/usr.bin/rpcgen/rpc_parse.c +++ b/usr.bin/rpcgen/rpc_parse.c @@ -1,35 +1,36 @@ -/* @(#)rpc_parse.c 2.1 88/08/01 4.0 RPCSRC */ +/* $NetBSD: rpc_parse.c,v 1.4 1995/06/11 21:49:58 pk Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. Users * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * + * program developed by the user or with the express written consent of + * Sun Microsystems, Inc. + * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * + * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. - * + * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. - * + * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. - * + * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 */ + #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.3 1993/08/01 18:09:19 mycroft Exp $"; +static char sccsid[] = "@(#)rpc_parse.c 1.8 89/02/22 (C) 1987 SMI"; #endif /* @@ -37,13 +38,25 @@ static char rcsid[] = "$Id: rpc_parse.c,v 1.3 1993/08/01 18:09:19 mycroft Exp $" * Copyright (C) 1987 Sun Microsystems, Inc. */ #include -#include "rpc_util.h" +#include "rpc/types.h" #include "rpc_scan.h" #include "rpc_parse.h" +#include "rpc_util.h" + +#define ARGNAME "arg" + +static isdefined __P((definition *)); +static def_struct __P((definition *)); +static def_program __P((definition *)); +static def_enum __P((definition *)); +static def_const __P((definition *)); +static def_union __P((definition *)); +static def_typedef __P((definition *)); +static get_declaration __P((declaration *, defkind)); +static get_prog_declaration __P((declaration *, defkind, int)); +static get_type __P((char **, char **, defkind)); +static unsigned_dec __P((char **)); -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 +89,6 @@ get_definition() break; case TOK_EOF: return (NULL); - break; default: error("definition keyword expected"); } @@ -92,7 +104,6 @@ isdefined(defp) STOREVAL(&defined, defp); } - static def_struct(defp) definition *defp; @@ -126,16 +137,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 +160,74 @@ 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 +237,7 @@ def_program(defp) *vtailp = NULL; } + static def_enum(defp) definition *defp; @@ -228,47 +286,124 @@ static def_union(defp) definition *defp; { - token tok; - declaration dec; - case_list *cases; - case_list **tailp; + token tok; + declaration dec; + case_list *cases,*tcase; + case_list **tailp; + int flag; - defp->def_kind = DEF_UNION; - scan(TOK_IDENT, &tok); - defp->def_name = tok.str; - scan(TOK_SWITCH, &tok); - scan(TOK_LPAREN, &tok); - get_declaration(&dec, DEF_UNION); - defp->def.un.enum_decl = dec; - tailp = &defp->def.un.cases; - scan(TOK_RPAREN, &tok); - scan(TOK_LBRACE, &tok); - scan(TOK_CASE, &tok); - while (tok.kind == TOK_CASE) { - scan(TOK_IDENT, &tok); - cases = ALLOC(case_list); - cases->case_name = tok.str; - scan(TOK_COLON, &tok); - get_declaration(&dec, DEF_UNION); - cases->case_decl = dec; - *tailp = cases; - tailp = &cases->next; - scan(TOK_SEMICOLON, &tok); - scan3(TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok); - } - *tailp = NULL; - if (tok.kind == TOK_DEFAULT) { - scan(TOK_COLON, &tok); - get_declaration(&dec, DEF_UNION); - defp->def.un.default_decl = ALLOC(declaration); - *defp->def.un.default_decl = dec; - scan(TOK_SEMICOLON, &tok); - scan(TOK_RBRACE, &tok); - } else { - defp->def.un.default_decl = NULL; - } + defp->def_kind = DEF_UNION; + scan(TOK_IDENT, &tok); + defp->def_name = tok.str; + scan(TOK_SWITCH, &tok); + scan(TOK_LPAREN, &tok); + get_declaration(&dec, DEF_UNION); + defp->def.un.enum_decl = dec; + tailp = &defp->def.un.cases; + scan(TOK_RPAREN, &tok); + scan(TOK_LBRACE, &tok); + scan(TOK_CASE, &tok); + while (tok.kind == TOK_CASE) { + scan2(TOK_IDENT, TOK_CHARCONST, &tok); + cases = ALLOC(case_list); + cases->case_name = tok.str; + scan(TOK_COLON, &tok); + /* now peek at next token */ + 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; + if (tok.kind == TOK_DEFAULT) { + scan(TOK_COLON, &tok); + get_declaration(&dec, DEF_UNION); + defp->def.un.default_decl = ALLOC(declaration); + *defp->def.un.default_decl = dec; + scan(TOK_SEMICOLON, &tok); + scan(TOK_RBRACE, &tok); + } else { + defp->def.un.default_decl = NULL; + } } +static char* reserved_words[] = { + "array", + "bytes", + "destroy", + "free", + "getpos", + "inline", + "pointer", + "reference", + "setpos", + "sizeof", + "union", + "vector", + NULL +}; + +static char* reserved_types[] = { + "opaque", + "string", + NULL +}; + +/* check that the given name is not one that would eventually result in + xdr routines that would conflict with internal XDR routines. */ +static 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 +414,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 +433,9 @@ 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; @@ -336,6 +474,74 @@ 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 = (char *)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) @@ -371,7 +577,7 @@ get_type(prefixp, typep, dkind) 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; @@ -389,7 +595,6 @@ get_type(prefixp, typep, dkind) } } - static unsigned_dec(typep) char **typep; diff --git a/usr.bin/rpcgen/rpc_parse.h b/usr.bin/rpcgen/rpc_parse.h index 2cb13a7ba037..faa651b78c85 100644 --- a/usr.bin/rpcgen/rpc_parse.h +++ b/usr.bin/rpcgen/rpc_parse.h @@ -1,38 +1,38 @@ +/* $NetBSD: rpc_parse.h,v 1.3 1995/06/11 21:50:00 pk Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. Users * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * + * program developed by the user or with the express written consent of + * Sun Microsystems, Inc. + * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * + * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. - * + * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. - * + * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. - * + * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 - * - * from: @(#)rpc_parse.h 1.3 87/03/09 (C) 1987 SMI - * $Id: rpc_parse.h,v 1.2 1993/08/01 18:09:25 mycroft Exp $ */ +/* @(#)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 +63,6 @@ struct typedef_def { }; typedef struct typedef_def typedef_def; - struct enumval_list { char *name; char *assignment; @@ -76,7 +75,6 @@ struct enum_def { }; typedef struct enum_def enum_def; - struct declaration { char *prefix; char *type; @@ -86,7 +84,6 @@ struct declaration { }; typedef struct declaration declaration; - struct decl_list { declaration decl; struct decl_list *next; @@ -98,9 +95,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 +110,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 +156,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 index f140137e9392..4100fcb68ece 100644 --- a/usr.bin/rpcgen/rpc_sample.c +++ b/usr.bin/rpcgen/rpc_sample.c @@ -1,3 +1,4 @@ +/* $NetBSD: rpc_sample.c,v 1.2 1995/06/11 21:50:01 pk Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape @@ -37,15 +38,18 @@ static char sccsid[] = "@(#)rpc_sample.c 1.1 90/08/30 (C) 1987 SMI"; * rpc_sample.c, Sample client-server code outputter for the RPC protocol compiler */ +#include #include #include #include "rpc_parse.h" #include "rpc_util.h" - static char RQSTP[] = "rqstp"; void printarglist(); +static write_sample_client __P((char *, version_list *)); +static write_sample_server __P((definition *)); +static return_type __P((proc_list *)); void write_sample_svc(def) @@ -201,13 +205,11 @@ write_sample_server(def) } } - - static return_type(plist) proc_list *plist; { - ptype( plist->res_prefix, plist->res_type, 1 ); + ptype( plist->res_prefix, plist->res_type, 1 ); } add_sample_msg() diff --git a/usr.bin/rpcgen/rpc_scan.c b/usr.bin/rpcgen/rpc_scan.c index dc440fed4721..b46327c5afe8 100644 --- a/usr.bin/rpcgen/rpc_scan.c +++ b/usr.bin/rpcgen/rpc_scan.c @@ -1,55 +1,67 @@ -/* @(#)rpc_scan.c 2.1 88/08/01 4.0 RPCSRC */ +/* $NetBSD: rpc_scan.c,v 1.4 1995/06/11 21:50:02 pk Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. Users * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * + * program developed by the user or with the express written consent of + * Sun Microsystems, Inc. + * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * + * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. - * + * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. - * + * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. - * + * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 */ + #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.3 1993/08/01 18:09:18 mycroft 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 +#include #include #include -#include +#include #include "rpc_scan.h" +#include "rpc_parse.h" #include "rpc_util.h" +static unget_token __P((token *tokp)); +static findstrconst __P((char **, char **)); +static findchrconst __P((char **, char **)); +static findconst __P((char **, char **)); +static findkind __P((char **, token *)); +static cppline __P((char *)); +static directive __P((char *)); +static printdirective __P((char *)); +static docppline __P((char *, int *, char **)); + #define startcomment(where) (where[0] == '/' && where[1] == '*') #define endcomment(where) (where[-1] == '*' && where[0] == '/') static int pushed = 0; /* is a token pushed */ static token lasttok; /* last token, if pushed */ -static int unget_token(), findstrconst(), findconst(), findkind(), cppline(), - directive(), printdirective(), docppline(); /* * scan expecting 1 given token */ @@ -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. */ @@ -185,10 +192,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 +268,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 +288,6 @@ get_token(tokp) findconst(&where, &tokp->str); break; - default: if (!(isalpha(*where) || *where == '_')) { char buf[100]; @@ -295,8 +307,6 @@ get_token(tokp) } } - - static unget_token(tokp) token *tokp; @@ -305,7 +315,6 @@ unget_token(tokp) pushed = 1; } - static findstrconst(str, val) char **str; @@ -329,6 +338,32 @@ findstrconst(str, val) *str = p; } +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; @@ -355,8 +390,6 @@ findconst(str, val) *str = p; } - - static token symbols[] = { {TOK_CONST, "const"}, {TOK_UNION, "union"}, @@ -382,13 +415,11 @@ static token symbols[] = { {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 3c7fbc492a53..4024090990d9 100644 --- a/usr.bin/rpcgen/rpc_scan.h +++ b/usr.bin/rpcgen/rpc_scan.h @@ -1,39 +1,38 @@ +/* $NetBSD: rpc_scan.h,v 1.3 1995/06/11 21:50:04 pk Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. Users * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * + * program developed by the user or with the express written consent of + * Sun Microsystems, Inc. + * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * + * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. - * + * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. - * + * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. - * + * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 - * - * 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.2 1993/08/01 18:09:26 mycroft Exp $ */ +/* @(#)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 +40,7 @@ */ enum tok_kind { TOK_IDENT, + TOK_CHARCONST, TOK_STRCONST, TOK_LPAREN, TOK_RPAREN, @@ -93,11 +93,14 @@ typedef struct token token; /* * routine interface */ -void scanprint(); -void scan(); -void scan2(); -void scan3(); -void scan_num(); -void peek(); -int peekscan(); -void get_token(); +void scan __P((tok_kind, token *)); +void scan2 __P((tok_kind, tok_kind, token *)); +void scan3 __P((tok_kind, tok_kind, tok_kind, token *)); +void scan_num __P((token *)); +void peek __P((token *)); +int peekscan __P((tok_kind, token *)); +void get_token __P((token *)); + +void expected1 __P((tok_kind)); +void expected2 __P((tok_kind, tok_kind)); +void expected3 __P((tok_kind, tok_kind, tok_kind)); diff --git a/usr.bin/rpcgen/rpc_svcout.c b/usr.bin/rpcgen/rpc_svcout.c index e75a4396c654..d771e2869226 100644 --- a/usr.bin/rpcgen/rpc_svcout.c +++ b/usr.bin/rpcgen/rpc_svcout.c @@ -1,43 +1,44 @@ -/* @(#)rpc_svcout.c 2.1 88/08/01 4.0 RPCSRC */ +/* $NetBSD: rpc_svcout.c,v 1.6 1995/06/11 21:50:05 pk Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. Users * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * + * program developed by the user or with the express written consent of + * Sun Microsystems, Inc. + * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * + * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. - * + * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. - * + * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. - * + * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 */ + #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.5 1995/03/06 04:59:27 cgd 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. */ +#include #include -#include +#include #include "rpc_parse.h" #include "rpc_util.h" @@ -47,97 +48,214 @@ static char ARG[] = "argument"; static char RESULT[] = "result"; static char ROUTINE[] = "local"; -static int write_program(), printerr(), printif(); +char _errbuf[256]; /* For all messages */ + +void internal_proctype __P((proc_list *)); +static write_real_program __P((definition *)); +static write_program __P((definition *, char *)); +static printerr __P((char *, char *)); +static printif __P((char *, char *, char *, char *)); +static write_inetmost __P((char *)); +static print_return __P((char *)); +static print_pmapunset __P((char *)); +static print_err_message __P((char *)); +static write_timeout_func __P((void)); +static write_pm_most __P((char *, int)); +static write_caller_func __P((void)); +static write_rpc_svc_fg __P((char *, char *)); +static 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, "*" ); +} + + /* * 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; +{ + if (inetdflag || pmflag) { + char* var_type; + var_type = (nomain? "extern" : "static"); + f_print(fout, "%s int _rpcpmstart;", var_type ); + f_print(fout, "\t\t/* Started by a port monitor ? */\n"); + f_print(fout, "%s int _rpcfdtype;", var_type ); + f_print(fout, "\t\t/* Whether Stream or Datagram ? */\n"); + if (timerflag) { + f_print(fout, "%s int _rpcsvcdirty;", var_type ); + f_print(fout, "\t/* Still serving ? */\n"); + } + write_svc_aux( nomain ); + } + /* write out dispatcher and stubs */ + write_programs( nomain? (char *)NULL : "static" ); + + if( nomain ) + return; + + f_print(fout, "\nmain()\n"); + f_print(fout, "{\n"); + if (inetdflag) { + write_inetmost(infile); /* Includes call to write_rpc_svc_fg() */ + } else { + if( tirpcflag ) { + if (netflag) { + f_print(fout, "\tregister SVCXPRT *%s;\n", TRANSP); + f_print(fout, "\tstruct netconfig *nconf = NULL;\n"); + } + f_print(fout, "\tpid_t pid;\n"); + f_print(fout, "\tint i;\n"); + f_print(fout, "\tchar mname[FMNAMESZ + 1];\n\n"); + write_pm_most(infile, netflag); + f_print(fout, "\telse {\n"); + write_rpc_svc_fg(infile, "\t\t"); + f_print(fout, "\t}\n"); + } else { + f_print(fout, "\tregister SVCXPRT *%s;\n", TRANSP); + f_print(fout, "\n"); + print_pmapunset("\t"); + } + } + + if (logflag && !inetdflag) { + open_log_file(infile, "\t"); + } +} + +/* + * write a registration for the given transport + */ +void +write_netid_register(transp) + char *transp; { list *l; definition *def; version_list *vp; + char *sp; + char tmpbuf[32]; - for (l = defined; l != NULL; l = l->next) { - def = (definition *) l->val; - if (def->def_kind == DEF_PROGRAM) { - for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { - f_print(fout, "\nstatic void "); - pvname(def->def_name, vp->vers_num); - f_print(fout, "();"); - } - } - } - f_print(fout, "\n\n"); - f_print(fout, "main()\n"); - f_print(fout, "{\n"); - f_print(fout, "\tSVCXPRT *%s;\n", TRANSP); + 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 */ 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);\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,16 +266,88 @@ 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"); + internal_proctype(proc); + f_print(fout, "\n_"); + pvname(proc->proc_name, vp->vers_num); + if( Cflag ) { + f_print(fout, "(" ); + /* arg name */ + if (proc->arg_num > 1) + f_print(fout, proc->args.argname); + else + ptype(proc->args.decls->decl.prefix, + proc->args.decls->decl.type, 0); + f_print(fout, " *argp, struct svc_req *%s)\n", + RQSTP); + } else { + f_print(fout, "(argp, %s)\n", RQSTP ); + /* arg name */ + if (proc->arg_num > 1) + f_print(fout, "\t%s *argp;\n", proc->args.argname); + else { + f_print(fout, "\t"); + ptype(proc->args.decls->decl.prefix, + proc->args.decls->decl.type, 0); + f_print(fout, " *argp;\n"); + } + f_print(fout, " struct svc_req *%s;\n", RQSTP); + } + + f_print(fout, "{\n"); + f_print(fout, "\treturn("); + if( Cflag ) + pvname_svc(proc->proc_name, vp->vers_num); + else + pvname(proc->proc_name, vp->vers_num); + f_print(fout, "("); + if (proc->arg_num < 2) { /* single argument */ + if (!streq( proc->args.decls->decl.type, "void")) + f_print(fout, "*argp, "); /* non-void */ + } else { + for (l = proc->args.decls; l != NULL; l = l->next) + f_print(fout, "argp->%s, ", l->decl.name); + } + f_print(fout, "%s));\n}\n", RQSTP); + } + } +} + +static write_program(def, storage) definition *def; char *storage; @@ -173,75 +363,136 @@ 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); - f_print(fout, "\n"); - f_print(fout, "\tswitch (%s->rq_proc) {\n", RQSTP); + if (Cflag) { + f_print(fout, "\txdrproc_t xdr_%s, xdr_%s;\n", ARG, RESULT); + f_print(fout, + "\tchar *(*%s)(char *, struct svc_req *);\n", + ROUTINE); + } else { + f_print(fout, "\tbool_t (*xdr_%s)(), (*xdr_%s)();\n", ARG, RESULT); + f_print(fout, "\tchar *(*%s)();\n", ROUTINE); + } + + f_print(fout, "\n"); + + if (callerflag) + f_print(fout, "\tcaller = transp;\n"); /*EVAS*/ + if (timerflag) + f_print(fout, "\t_rpcsvcdirty = 1;\n"); + f_print(fout, "\tswitch (%s->rq_proc) {\n", RQSTP); if (!nullproc(vp->procs)) { f_print(fout, "\tcase NULLPROC:\n"); - f_print(fout, "\t\t(void)svc_sendreply(%s, xdr_void, (char *)NULL);\n", TRANSP); - f_print(fout, "\t\treturn;\n\n"); + f_print(fout, + Cflag + ? "\t\t(void) svc_sendreply(%s, (xdrproc_t) xdr_void, (char *)NULL);\n" + : "\t\t(void) svc_sendreply(%s, xdr_void, (char *)NULL);\n", + TRANSP); + print_return("\t\t"); + f_print(fout, "\n"); } for (proc = vp->procs; proc != NULL; proc = proc->next) { f_print(fout, "\tcase %s:\n", proc->proc_name); - 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 ) + f_print(fout, + "\t\t%s = (char *(*)(char *, struct svc_req *)) ", + ROUTINE); + else + f_print(fout, "\t\t%s = (char *(*)()) ", ROUTINE); + + if (newstyle) { /* new style: calls internal routine */ + f_print(fout,"_"); + } + if( Cflag && !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, "\tmemset((char *)&%s, 0, sizeof(%s));\n", ARG, - ARG); - printif("getargs", TRANSP, "(caddr_t)&", 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); + if (Cflag) + f_print(fout, "\t%s = (*%s)((char *)&%s, %s);\n", + RESULT, ROUTINE, ARG, RQSTP); + else + f_print(fout, "\t%s = (*%s)(&%s, %s);\n", + RESULT, ROUTINE, ARG, RQSTP); f_print(fout, "\tif (%s != NULL && !svc_sendreply(%s, xdr_%s, %s)) {\n", RESULT, TRANSP, RESULT, RESULT); printerr("systemerr", TRANSP); f_print(fout, "\t}\n"); - printif("freeargs", TRANSP, "(caddr_t)&", 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_return("\t"); + f_print(fout, "}\n"); } } @@ -264,7 +515,6 @@ printif(proc, transp, prefix, arg) proc, transp, arg, prefix, arg); } - nullproc(proc) proc_list *proc; { @@ -275,3 +525,445 @@ 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) + f_print(fout, "%s_rpcsvcdirty = 0;\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(); + if (callerflag) /*EVAS*/ + write_caller_func(); /*EVAS*/ +} + +/* + * Write the _msgout function + */ + +write_msg_out() +{ + f_print(fout, "\n"); + f_print(fout, "static\n"); + if( !Cflag ) { + f_print(fout, "void _msgout(msg)\n"); + f_print(fout, "\tchar *msg;\n"); + } else { + f_print(fout, "void _msgout(char* msg)\n"); + } + f_print(fout, "{\n"); + f_print(fout, "#ifdef RPC_SVC_FG\n"); + if (inetdflag || pmflag) + f_print(fout, "\tif (_rpcpmstart)\n"); + f_print(fout, "\t\tsyslog(LOG_ERR, 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"); + f_print(fout, "closedown()\n"); + f_print(fout, "{\n"); + f_print(fout, "\tif (_rpcsvcdirty == 0) {\n"); + f_print(fout, "\t\textern fd_set svc_fdset;\n"); + f_print(fout, "\t\tstatic int size;\n"); + f_print(fout, "\t\tint i, openfd;\n"); + if (tirpcflag && pmflag) { + f_print(fout, "\t\tstruct t_info tinfo;\n\n"); + f_print(fout, "\t\tif (!t_getinfo(0, &tinfo) && (tinfo.servtype == T_CLTS))\n"); + } else { + f_print(fout, "\n\t\tif (_rpcfdtype == SOCK_DGRAM)\n"); + } + f_print(fout, "\t\t\texit(0);\n"); + f_print(fout, "\t\tif (size == 0) {\n"); + if( tirpcflag ) { + f_print(fout, "\t\t\tstruct rlimit rl;\n\n"); + f_print(fout, "\t\t\trl.rlim_max = 0;\n"); + f_print(fout, "\t\t\tgetrlimit(RLIMIT_NOFILE, &rl);\n"); + f_print(fout, "\t\t\tif ((size = rl.rlim_max) == 0)\n"); + f_print(fout, "\t\t\t\treturn;\n"); + } else { + f_print(fout, "\t\t\tsize = getdtablesize();\n"); + } + f_print(fout, "\t\t}\n"); + f_print(fout, "\t\tfor (i = 0, openfd = 0; i < size && openfd < 2; i++)\n"); + f_print(fout, "\t\t\tif (FD_ISSET(i, &svc_fdset))\n"); + f_print(fout, "\t\t\t\topenfd++;\n"); + f_print(fout, "\t\tif (openfd <= (_rpcpmstart?0:1))\n"); + f_print(fout, "\t\t\texit(0);\n"); + f_print(fout, "\t}\n"); + f_print(fout, "\t(void) alarm(_RPCSVC_CLOSEDOWN);\n"); + f_print(fout, "}\n"); +} + +static +write_caller_func() /*EVAS*/ +{ +#define P(s) f_print(fout, s); + +P("\n"); +P("char *svc_caller()\n"); +P("{\n"); +P(" struct sockaddr_in actual;\n"); +P(" struct hostent *hp;\n"); +P(" static struct in_addr prev;\n"); +P(" static char cname[128];\n\n"); + +P(" actual = *svc_getcaller(caller);\n\n"); + +P(" if (memcmp((char *)&actual.sin_addr, (char *)&prev,\n"); +P(" sizeof(struct in_addr)) == 0)\n"); +P(" return (cname);\n\n"); + +P(" prev = actual.sin_addr;\n\n"); + +P(" hp = gethostbyaddr((char *) &actual.sin_addr, sizeof(actual.sin_addr), AF_INET);\n"); +P(" if (hp == NULL) { /* dummy one up */\n"); +P(" extern char *inet_ntoa();\n"); +P(" strcpy(cname, inet_ntoa(actual.sin_addr));\n"); +P(" } else {\n"); +P(" strcpy(cname, hp->h_name);\n"); +P(" }\n\n"); + +P(" return (cname);\n"); +P("}\n"); + +#undef P +} + +/* + * 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"); + if (logflag) + open_log_file(infile, "\t\t"); + f_print(fout, "\t\tif ((netid = getenv(\"NLSPROVIDER\")) == NULL) {\n"); + sprintf(_errbuf, "cannot get transport name"); + print_err_message("\t\t\t"); + f_print(fout, "\t\t} else if ((nconf = getnetconfigent(netid)) == NULL) {\n"); + sprintf(_errbuf, "cannot get transport info"); + print_err_message("\t\t\t"); + f_print(fout, "\t\t}\n"); + /* + * A kludgy support for inetd services. Inetd only works with + * sockmod, and RPC works only with timod, hence all this jugglery + */ + f_print(fout, "\t\tif (strcmp(mname, \"sockmod\") == 0) {\n"); + f_print(fout, "\t\t\tif (ioctl(0, I_POP, 0) || ioctl(0, I_PUSH, \"timod\")) {\n"); + sprintf(_errbuf, "could not get the right module"); + print_err_message("\t\t\t\t"); + f_print(fout, "\t\t\t\texit(1);\n"); + f_print(fout, "\t\t\t}\n"); + f_print(fout, "\t\t}\n"); + if( timerflag ) + f_print(fout, "\t\tpmclose = (t_getstate(0) != T_DATAXFER);\n"); + f_print(fout, "\t\tif ((%s = svc_tli_create(0, nconf, NULL, 0, 0)) == NULL) {\n", + TRANSP); + sprintf(_errbuf, "cannot create server handle"); + print_err_message("\t\t\t"); + f_print(fout, "\t\t\texit(1);\n"); + f_print(fout, "\t\t}\n"); + f_print(fout, "\t\tif (nconf)\n"); + f_print(fout, "\t\t\tfreenetconfigent(nconf);\n"); + for (l = defined; l != NULL; l = l->next) { + def = (definition *) l->val; + if (def->def_kind != DEF_PROGRAM) { + continue; + } + for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { + f_print(fout, + "\t\tif (!svc_reg(%s, %s, %s, ", + TRANSP, def->def_name, vp->vers_name); + pvname(def->def_name, vp->vers_num); + f_print(fout, ", 0)) {\n"); + (void) sprintf(_errbuf, "unable to register (%s, %s).", + def->def_name, vp->vers_name); + print_err_message("\t\t\t"); + f_print(fout, "\t\t\texit(1);\n"); + f_print(fout, "\t\t}\n"); + } + } + if (timerflag) { + f_print(fout, "\t\tif (pmclose) {\n"); + f_print(fout, "\t\t\t(void) signal(SIGALRM, %s closedown);\n", + Cflag? "(SIG_PF)" : "(void(*)())" ); + f_print(fout, "\t\t\t(void) alarm(_RPCSVC_CLOSEDOWN);\n"); + f_print(fout, "\t\t}\n"); + } + f_print(fout, "\t\tsvc_run();\n"); + f_print(fout, "\t\texit(1);\n"); + f_print(fout, "\t\t/* NOTREACHED */\n"); + f_print(fout, "\t}\n"); +} + +/* + * Support for backgrounding the server if self started. + */ +static +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"); + } + if (inetdflag && streq(transp, "tcp")) { + f_print(fout, "%s\tif (_rpcpmstart)\n", sp); + + f_print(fout, "%s\t\t%s = svc%s_create(%s", + sp, TRANSP, "fd", inetdflag? "sock": "RPC_ANYSOCK"); + if (!isudp) + f_print(fout, ", 0, 0"); + f_print(fout, ");\n"); + + f_print(fout, "%s\telse\n", sp); + + f_print(fout, "%s\t\t%s = svc%s_create(%s", + sp, TRANSP, transp, inetdflag? "sock": "RPC_ANYSOCK"); + if (!isudp) + f_print(fout, ", 0, 0"); + f_print(fout, ");\n"); + + } else { + f_print(fout, "%s\t%s = svc%s_create(%s", + sp, TRANSP, transp, inetdflag? "sock": "RPC_ANYSOCK"); + if (!isudp) + f_print(fout, ", 0, 0"); + f_print(fout, ");\n"); + } + f_print(fout, "%s\tif (%s == NULL) {\n", sp, TRANSP); + (void) sprintf(_errbuf, "cannot create %s service.", transp); + (void) sprintf(tmpbuf, "%s\t\t", sp); + print_err_message(tmpbuf); + f_print(fout, "%s\t\texit(1);\n", sp); + f_print(fout, "%s\t}\n", sp); + + if (inetdflag) { + f_print(fout, "%s\tif (!_rpcpmstart)\n\t", sp); + f_print(fout, "%s\tproto = IPPROTO_%s;\n", + sp, isudp ? "UDP": "TCP"); + } + for (l = defined; l != NULL; l = l->next) { + def = (definition *) l->val; + if (def->def_kind != DEF_PROGRAM) { + continue; + } + for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { + f_print(fout, "%s\tif (!svc_register(%s, %s, %s, ", + sp, TRANSP, def->def_name, vp->vers_name); + pvname(def->def_name, vp->vers_num); + if (inetdflag) + f_print(fout, ", proto)) {\n"); + else + f_print(fout, ", IPPROTO_%s)) {\n", + isudp ? "UDP": "TCP"); + (void) sprintf(_errbuf, "unable to register (%s, %s, %s).", + def->def_name, vp->vers_name, transp); + print_err_message(tmpbuf); + f_print(fout, "%s\t\texit(1);\n", sp); + f_print(fout, "%s\t}\n", sp); + } + } + if (inetdflag) + f_print(fout, "\t}\n"); +} diff --git a/usr.bin/rpcgen/rpc_tblout.c b/usr.bin/rpcgen/rpc_tblout.c index 5dc8710135e3..b69072371dd3 100644 --- a/usr.bin/rpcgen/rpc_tblout.c +++ b/usr.bin/rpcgen/rpc_tblout.c @@ -1,3 +1,4 @@ +/* $NetBSD: rpc_tblout.c,v 1.2 1995/06/11 21:50:07 pk Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape @@ -35,6 +36,7 @@ static char sccsid[] = "@(#)rpc_tblout.c 1.4 89/02/22 (C) 1988 SMI"; /* * rpc_tblout.c, Dispatch table outputter for the RPC protocol compiler */ +#include #include #include #include "rpc_parse.h" @@ -53,9 +55,11 @@ 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 write_table __P((definition *)); +static printit __P((char *, char *)); + void write_tables() { diff --git a/usr.bin/rpcgen/rpc_util.c b/usr.bin/rpcgen/rpc_util.c index 07b819a26c5f..e1ad5ba42ef6 100644 --- a/usr.bin/rpcgen/rpc_util.c +++ b/usr.bin/rpcgen/rpc_util.c @@ -1,62 +1,66 @@ -/* @(#)rpc_util.c 2.1 88/08/01 4.0 RPCSRC */ +/* $NetBSD: rpc_util.c,v 1.5 1995/06/11 21:50:08 pk Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. Users * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * + * program developed by the user or with the express written consent of + * Sun Microsystems, Inc. + * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * + * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. - * + * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. - * + * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. - * + * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 */ + #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.4 1995/03/06 04:59:37 cgd 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. */ +#include #include +#include #include "rpc_scan.h" #include "rpc_parse.h" #include "rpc_util.h" +#define ARGEXT "argument" + +static void printwhere __P((void)); + 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 */ - -static int printwhere(); +list *defined; /* list of defined things */ /* * Reinitialize the world @@ -82,13 +86,14 @@ streq(a, b) /* * find a value in a list */ -char * +definition * findval(lst, val, cmp) list *lst; char *val; int (*cmp) (); { + for (; lst != NULL; lst = lst->next) { if ((*cmp) (lst->val, val)) { return (lst->val); @@ -103,11 +108,12 @@ findval(lst, val, cmp) void storeval(lstp, val) list **lstp; - char *val; + definition *val; { list **l; list *lst; + for (l = lstp; *l != NULL; l = (list **) & (*l)->next); lst = ALLOC(list); lst->val = val; @@ -115,7 +121,6 @@ storeval(lstp, val) *l = lst; } - static findit(def, type) definition *def; @@ -124,7 +129,6 @@ findit(def, type) return (streq(def->def_name, type)); } - static char * fixit(type, orig) char *type; @@ -186,7 +190,6 @@ ptype(prefix, type, follow) } } - static typedefed(def, type) definition *def; @@ -224,8 +227,7 @@ isvectordef(type, rel) } } - -static char * +char * locase(str) char *str; { @@ -240,6 +242,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,7 +258,6 @@ pvname(pname, vnum) f_print(fout, "%s_%s", locase(pname), vnum); } - /* * print a useful (?) error message, and then die */ @@ -277,7 +285,6 @@ crash() exit(1); } - void record_open(file) char *file; @@ -343,42 +350,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 +397,6 @@ toktostr(kind) return (sp->str); } - - static printbuf() { @@ -415,8 +419,7 @@ printbuf() } } - -static +static void printwhere() { int i; @@ -437,3 +440,65 @@ printwhere() } (void) fputc('\n', stderr); } + +char * +make_argname(pname, vname) + char *pname; + char *vname; +{ + char *name; + + name = (char *)malloc(strlen(pname) + strlen(vname) + strlen(ARGEXT) + 3); + if (!name) { + fprintf(stderr, "failed in malloc"); + exit(1); + } + sprintf(name, "%s_%s_%s", locase(pname), vname, ARGEXT); + return(name); +} + +bas_type *typ_list_h; +bas_type *typ_list_t; + +void +add_type(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 dfdb54985fe7..4c1de4e1ee40 100644 --- a/usr.bin/rpcgen/rpc_util.h +++ b/usr.bin/rpcgen/rpc_util.h @@ -1,54 +1,55 @@ +/* $NetBSD: rpc_util.h,v 1.3 1995/06/11 21:50:10 pk Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. Users * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * + * program developed by the user or with the express written consent of + * Sun Microsystems, Inc. + * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * + * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. - * + * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. - * + * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. - * + * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 - * - * 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.2 1993/08/01 18:09:24 mycroft Exp $ */ +/* @(#)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(); -#define alloc(size) malloc((unsigned)(size)) +#define alloc(size) (void *)malloc((unsigned)(size)) #define ALLOC(object) (object *) malloc(sizeof(object)) #define s_print (void) sprintf #define f_print (void) fprintf struct list { - char *val; + definition *val; struct list *next; }; typedef struct list list; +#define PUT 1 +#define GET 2 + /* * Global variables */ @@ -63,51 +64,94 @@ extern FILE *fin; extern list *defined; + +extern bas_type *typ_list_h; +extern bas_type *typ_list_t; + +/* + * All the option flags + */ +extern int inetdflag; +extern int pmflag; +extern int tblflag; +extern int logflag; +extern int newstyle; +extern int Cflag; /* C++ flag */ +extern int tirpcflag; /* flag for generating tirpc code */ +extern int inline; /* if this is 0, then do not generate inline code */ +extern int callerflag; + +/* + * Other flags related with inetd jumpstart. + */ +extern int indefinitewait; +extern int exitnow; +extern int timerflag; + +extern int nonfatalerrors; + /* * rpc_util routines */ void storeval(); #define STOREVAL(list,item) \ - storeval(list,(char *)item) + storeval(list,item) -char *findval(); +definition *findval(); #define FINDVAL(list,item,finder) \ - findval(list, (char *) item, finder) - -char *fixtype(); -char *stringfix(); -void pvname(); -void ptype(); -int isvectordef(); -int streq(); -void error(); -void expected1(); -void expected2(); -void expected3(); -void tabify(); -void record_open(); + findval(list, item, finder) +char *fixtype __P((char *)); +char *stringfix __P((char *)); +char *locase __P((char *)); +void pvname_svc __P((char *, char *)); +void pvname __P((char *, char *)); +void ptype __P((char *, char *, int)); +int isvectordef __P((char *, relation)); +int streq __P((char *, char *)); +void error __P((char *)); +void tabify __P((FILE *, int)); +void record_open __P((char *)); +bas_type *find_type __P((char *)); +char *make_argname __P((char *, char *)); /* * rpc_cout routines */ -void cprint(); -void emit(); +void emit __P((definition *)); /* * rpc_hout routines */ -void print_datadef(); +void print_datadef __P((definition *)); +void print_funcdef __P((definition *)); /* * rpc_svcout routines */ -void write_most(); -void write_register(); -void write_rest(); - +void write_most __P((char *, int, int)); +void write_rest __P((void)); +void write_programs __P((char *)); +void write_svc_aux __P((int)); +void write_inetd_register __P((char *)); +void write_netid_register __P((char *)); +void write_nettype_register __P((char *)); /* * rpc_clntout routines */ -void write_stubs(); +void write_stubs __P((void)); +void printarglist __P((proc_list *, char *, char *)); + + +/* + * rpc_tblout routines + */ +void write_tables __P((void)); + +/* + * rpc_sample routines + */ +void write_sample_svc __P((definition *)); +int write_sample_clnt __P((definition *)); +void write_sample_clnt_main __P((void)); diff --git a/usr.bin/rpcgen/rpcgen.1 b/usr.bin/rpcgen/rpcgen.1 index a8e014c3a389..bc4240ed0420 100644 --- a/usr.bin/rpcgen/rpcgen.1 +++ b/usr.bin/rpcgen/rpcgen.1 @@ -1,9 +1,8 @@ -.\" from: @(#)rpcgen.1 2.2 88/08/02 4.0 RPCSRC -.\" $Id: rpcgen.1,v 1.4 1993/08/01 07:29:24 mycroft Exp $ -.\" -.Dd January 18, 1988 +.\" $NetBSD: rpcgen.1,v 1.5 1995/06/11 21:50:11 pk Exp $ +.\" from: @(#)rpcgen.new.1 1.1 90/11/09 TIRPC 1.0; from 40.10 of 10/10/89 +.\" Copyright (c) 1988,1990 Sun Microsystems, Inc. - All Rights Reserved. +.Dd June 11, 1995 .Dt RPCGEN 1 -.Os .Sh NAME .Nm rpcgen .Nd RPC protocol compiler @@ -11,35 +10,46 @@ .Nm rpcgen .Ar infile .Nm rpcgen +.Op Fl D Op Ar name=value +.Op Fl A +.Op Fl M +.Op Fl T +.Op Fl K Ar secs +.Ar infile +.Nm rpcgen .Fl c Li | .Fl h Li | .Fl l Li | -.Fl m +.Fl m Li | +.Fl t Li | +.Fl S\&c Li | +.Fl S\&s Li | .Op Fl o Ar outfile .Op Ar infile .Nm rpcgen -.Fl s Ar transport +.Fl c Li | +.Ar nettype +.Op Fl o Ar outfile +.Op Ar infile +.Nm rpcgen +.Fl s Li | +.Ar netid .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 +protocol. +The input to +.Nm 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 +Language (Remote Procedure Call Language). .Nm rpcgen -is normally used as in the first synopsis where it takes an input file -and generates four output files. If the +is normally used as in the first synopsis where +it takes an input file and generates up to four output files. +If the .Ar infile is named .Pa proto.x , @@ -54,103 +64,379 @@ server-side stubs in .Pa proto_svc.c , and client-side stubs in .Pa proto_clnt.c . +With the +.Fl T +option, +it will also generate the +.Tn RPC +dispatch table in +.Pa proto_tbl.i . +With the +.Fl S\&c +option, +it will also generate sample code which would illustrate how to use the +remote procedures on the client side. This code would be created in +.Pa proto_client.c . +With the +.Fl S\&s +option, +it will also generate a sample server code which would illustrate how to write +the remote procedures. This code would be created in +.Pa proto_server.c . .Pp -The 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. +The server created can be started both by the port monitors +(for example, +.Em inetd +or +.Em listen ) +or by itself. +When it is started by a port monitor, +it creates servers only for the transport for which +the file descriptor 0 was passed. +The name of the transport must be specified +by setting up the environmental variable +.Ev PM_TRANSPORT . +When the server generated by +.Nm rpcgen +is executed, +it creates server handles for all the transports +specified in +.Ev NETPATH +environment variable, +or if it is unset, +it creates server handles for all the visible transports from +.Pa /etc/netconfig +file. +Note: +the transports are chosen at run time and not at compile time. +When the server is self-started, +it backgrounds itself by default. +A special define symbol +.Dv RPC_SVC_FG +can be used to run the server process in foreground. +.P +The second synopsis provides special features which allow +for the creation of more sophisticated +.Tn RPC +servers. +These features include support for user provided +.Li #defines +and +.Tn RPC +dispatch tables. +The entries in the +.Tn RPC +dispatch table contain: .Pp -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 +.Bl -inset -offset indent -compact +.It + +pointers to the service routine corresponding to that procedure, +.It + +a pointer to the input and output arguments, +.It + +the size of these routines +.El +.Pp +A server can use the dispatch table to check authorization +and then to execute the service routine; +a client library may use it to deal with the details of storage +management and +.Tn XDR +data conversion. +.Pp +The other three synopses shown above are used when +one does not want to generate all the output files, +but only a particular one. +Some examples of their usage is described in the +EXAMPLE +section below. +When .Nm rpcgen -input file. For each type of output file, +is executed with the +.Fl s +option, +it creates servers for that particular class of transports. +When +executed with the +.Fl n +option, +it creates a server for the transport specified by +.Em netid . +If +.Ar infile +is not specified, .Nm rpcgen -defines a special -.Xr cpp -symbol for use by the +accepts the standard input. +.Pp +The C preprocessor, +.Xr cpp 1 +is run on the input file before it is actually interpreted by +.Nm rpcgen +For each type of output file, +.Nm rpcgen +defines a special preprocessor symbol for use by the .Nm rpcgen programmer: .Pp -.Bl -tag -width RPC_CLNT -compact -.It Dv RPC_HDR +.PD 0 +.TP 12 +.Dv RPC_HDR defined when compiling into header files -.It Dv RPC_XDR +.TP +.Dv RPC_XDR defined when compiling into .Tn XDR routines -.It Dv RPC_SVC +.TP +.Dv RPC_SVC defined when compiling into server-side stubs -.It Dv RPC_CLNT +.TP +.Dv RPC_CLNT defined when compiling into client-side stubs -.El +.TP +.Dv RPC_TBL +defined when compiling into +.Tn RPC +dispatch tables +.PD .Pp -In addition, -.Nm rpcgen -does a little preprocessing of its own. Any line beginning with +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, +is passed directly into the output file, +uninterpreted by .Nm rpcgen -will assume that there exists a routine with the name -.Tn xdr_ -prepended to the name of the undefined type. +.Pp +For every data type referred to in +.Ar infile +.Nm rpcgen +assumes that there exists a +routine with the string +.Dq xdr_ +prepended to the name of the data type. +If this routine does not exist in the +.Tn RPC/XDR +library, it must be provided. +Providing an undefined data type +allows customization of +.Tn XDR +routines. .Sh OPTIONS .Bl -tag -width indent +.It Fl a +Generate all the files including sample code for client and server side. +.It Fl b +This generates code for the +.Tn SunOS4.1 +style of rpc. This is the default. .It Fl c Compile into .Tn XDR routines. +.It Fl C +Generate code in ANSI C. This option also generates code that could be +compiled with the C++ compiler. +.It Fl D Ar name Ns Op Ar =value +Define a symbol +.Dv name . +Equivalent to the +.Dv #define +directive in the source. +If no +.Dv value +is given, +.Dv value +is defined as 1. +This option may be specified more than once. .It Fl h Compile into C data-definitions (a header file). +The +.Fl T +option can be used in conjunction to produce a +header file which supports +.Tn RPC +dispatch tables. +.It Fl K Ar secs +By default, services created using +.Nm rpcgen +wait 120 seconds +after servicing a request before exiting. +That interval can be changed using the +.Fl K +flag. +To create a server that exits immediately upon servicing a request, +.Dq Fl K No 0 +can be used. +To create a server that never exits, the appropriate argument is +.Dq Fl K No -1 . +.IP +When monitoring for a server, +some port monitors, like the +.Tn SVR4 +utility +.Xr listen 1 , +.Em always +spawn a new process in response to a service request. +If it is known that a server will be used with such a monitor, the +server should exit immediately on completion. +For such servers, +.Nm rpcgen +should be used with +.Dq Fl K No -1 . .It Fl l Compile into client-side stubs. .It Fl m -Compile into server-side stubs, but do not generate a +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 +routine. +This option is useful for doing callback-routines +and for users who need to write their own .Fn main routine to do initialization. +.It Fl n Ar netid +Compile into server-side stubs for the transport +specified by +.Ar netid. +There should be an entry for +.Ar netid +in the +netconfig database. +This option may be specified more than once, +so as to compile a server that serves multiple transports. +.It Fl N +Use the newstyle of rpcgen. This allows procedures to have multiple arguments. +It also uses the style of parameter passing that closely resembles C. So, when +passing an argument to a remote procedure you do not have to pass a pointer to +the argument but the argument itself. This behaviour is different from the oldstyle +of rpcgen generated code. The newstyle is not the default case because of +backward compatibility. .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 +Specify the name of the output file. +If none is specified, +standard output is used +.Po +.Fl c Fl h Fl l +.Fl m Fl n Fl s +modes only +.Pc +.It Fl s Ar nettype +Compile into server-side stubs for all the +transports belonging to the class +.Ar nettype . +The supported classes are +.Em netpath, +.Em visible, +.Em circuit_n, +.Em circuit_v, +.Em datagram_n, +.Em datagram_v, +.Em tcp, and -.Fl s -modes only). -.It Fl s Ar transport -Compile into server-side stubs, using the the given transport. The -supported transports are -.Tn udp +.Em udp +[see +.Xr rpc 3 +for the meanings associated with these classes. Note: +.Bx +currently supports only the +.Em tcp and -.Tn tcp . -This option may be invoked more than once so as to compile a server -that serves multiple transports. +.Em udp +classes]. +This option may be specified more than once. +Note: +the transports are chosen at run time and not at compile time. +.It Fl S\&c +Generate sample code to show the use of remote procedure and how to bind +to the server before calling the client side stubs generated by rpcgen. +.It Fl S\&s +Generate skeleton code for the remote procedures on the server side. You would need +to fill in the actual code for the remote procedures. +.It Fl t +Compile into +.Tn RPC +dispatch table. +.It Fl T +Generate the code to support +.Tn RPC +dispatch tables. .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 +.Pp +The options +.Fl c , +.Fl h , +.Fl l , +.Fl m , +.Fl s , +and +.Fl t +are used exclusively to generate a particular type of file, +while the options +.Fl D +and +.Fl T +are global and can be used with the other options. +.Sh NOTES +The +.Tn RPC +Language does not support nesting of structures. +As a work-around, +structures can be declared at the top-level, +and their name used inside other structures in order to achieve the same effect. .Pp -Name clashes can occur when using program definitions, since the -apparent scoping does not really apply. Most of these can be avoided -by giving unique names for programs, versions, procedures and types. +Name clashes can occur when using program definitions, +since the apparent scoping does not really apply. +Most of these can be avoided by giving +unique names for programs, +versions, +procedures and types. +.Pp +The server code generated with +.Fl n +option refers to the transport indicated by +.Em netid +and hence is very site specific. +.Sh EXAMPLE +.Pp +The command +.Pp +.Bd -literal -offset indent +$ rpcgen -T prot.x +.Ed +.Pp +generates the five files: +.Pa prot.h , +.Pa prot_clnt.c , +.Pa prot_svc.c , +.Pa prot_xdr.c +and +.Pa prot_tbl.i . +.Pp +The following example sends the C data-definitions (header file) +to standard output. +.Pp +.Bd -literal -offset indent +$ rpcgen -h prot.x +.Ed +.Pp +To send the test version of the +.Dv -DTEST , +server side stubs for +all the transport belonging to the class +.Em datagram_n +to standard output, use: +.Pp +.Bd -literal -offset indent +$ rpcgen -s datagram_n -DTEST prot.x +.Ed +.Pp +To create the server side stubs for the transport indicated by +.Em netid +.Em tcp , +use: +.Pp +.Bd -literal -offset indent +$ rpcgen -n tcp -o prot_svc.c prot.x +.Ed +.Sh SEE ALSO +.Xr cpp 1