1 From c4c4550dafabda05d78ca4aa9969db8a4f70affe Mon Sep 17 00:00:00 2001
2 From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
3 Date: Sat, 10 Nov 2012 16:21:01 +0100
4 Subject: [PATCH] Add rpcgen program from nfs-utils sources
6 Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
10 rpcgen/Makefile.am | 22 ++
11 rpcgen/rpc_clntout.c | 217 ++++++++++
12 rpcgen/rpc_cout.c | 706 +++++++++++++++++++++++++++++++++
13 rpcgen/rpc_hout.c | 490 +++++++++++++++++++++++
14 rpcgen/rpc_main.c | 1067 ++++++++++++++++++++++++++++++++++++++++++++++++++
15 rpcgen/rpc_output.h | 16 +
16 rpcgen/rpc_parse.c | 609 ++++++++++++++++++++++++++++
17 rpcgen/rpc_parse.h | 166 ++++++++
18 rpcgen/rpc_sample.c | 247 ++++++++++++
19 rpcgen/rpc_scan.c | 474 ++++++++++++++++++++++
20 rpcgen/rpc_scan.h | 103 +++++
21 rpcgen/rpc_svcout.c | 882 +++++++++++++++++++++++++++++++++++++++++
22 rpcgen/rpc_tblout.c | 165 ++++++++
23 rpcgen/rpc_util.c | 479 ++++++++++++++++++++++
24 rpcgen/rpc_util.h | 166 ++++++++
25 rpcgen/rpcgen.1 | 521 ++++++++++++++++++++++++
26 18 files changed, 6344 insertions(+), 2 deletions(-)
27 create mode 100644 rpcgen/Makefile.am
28 create mode 100644 rpcgen/rpc_clntout.c
29 create mode 100644 rpcgen/rpc_cout.c
30 create mode 100644 rpcgen/rpc_hout.c
31 create mode 100644 rpcgen/rpc_main.c
32 create mode 100644 rpcgen/rpc_output.h
33 create mode 100644 rpcgen/rpc_parse.c
34 create mode 100644 rpcgen/rpc_parse.h
35 create mode 100644 rpcgen/rpc_sample.c
36 create mode 100644 rpcgen/rpc_scan.c
37 create mode 100644 rpcgen/rpc_scan.h
38 create mode 100644 rpcgen/rpc_svcout.c
39 create mode 100644 rpcgen/rpc_tblout.c
40 create mode 100644 rpcgen/rpc_util.c
41 create mode 100644 rpcgen/rpc_util.h
42 create mode 100644 rpcgen/rpcgen.1
44 diff --git a/Makefile.am b/Makefile.am
45 index 9b812eb..6edf029 100644
49 -SUBDIRS = src man doc
50 +SUBDIRS = src man doc rpcgen
51 ACLOCAL_AMFLAGS = -I m4
53 noinst_HEADERS = tirpc/reentrant.h \
54 diff --git a/configure.ac b/configure.ac
55 index 11df020..4110225 100644
58 @@ -34,5 +34,17 @@ AC_CHECK_LIB([pthread], [pthread_create])
59 AC_CHECK_LIB([nsl], [yp_get_default_domain])
62 -AC_CONFIG_FILES([Makefile src/Makefile man/Makefile doc/Makefile])
63 +AM_CONDITIONAL(CROSS_COMPILING, test $cross_compiling = yes)
65 +AC_MSG_CHECKING([for a C compiler for build tools])
66 +if test $cross_compiling = yes; then
67 + AC_CHECK_PROGS(CC_FOR_BUILD, gcc cc)
71 +AC_MSG_RESULT([$CC_FOR_BUILD])
72 +AC_SUBST(CC_FOR_BUILD)
74 +AC_CONFIG_FILES([Makefile src/Makefile man/Makefile doc/Makefile rpcgen/Makefile])
76 AC_OUTPUT(libtirpc.pc)
77 diff --git a/rpcgen/Makefile.am b/rpcgen/Makefile.am
79 index 0000000..2277b6f
81 +++ b/rpcgen/Makefile.am
83 +COMPILE = $(CC_FOR_BUILD) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
84 + $(CPPFLAGS_FOR_BUILD) $(AM_CFLAGS) $(CFLAGS_FOR_BUILD)
85 +LINK = $(CC_FOR_BUILD) $(AM_CFLAGS) $(CFLAGS_FOR_BUILD) $(AM_LDFLAGS) $(LDFLAGS_FOR_BUILD) -o $@
87 +bin_PROGRAMS = rpcgen
104 +dist_man1_MANS = rpcgen.1
105 diff --git a/rpcgen/rpc_clntout.c b/rpcgen/rpc_clntout.c
107 index 0000000..e2f4382
109 +++ b/rpcgen/rpc_clntout.c
112 + * Copyright (c) 2009, Sun Microsystems, Inc.
113 + * All rights reserved.
115 + * Redistribution and use in source and binary forms, with or without
116 + * modification, are permitted provided that the following conditions are met:
117 + * - Redistributions of source code must retain the above copyright notice,
118 + * this list of conditions and the following disclaimer.
119 + * - Redistributions in binary form must reproduce the above copyright notice,
120 + * this list of conditions and the following disclaimer in the documentation
121 + * and/or other materials provided with the distribution.
122 + * - Neither the name of Sun Microsystems, Inc. nor the names of its
123 + * contributors may be used to endorse or promote products derived
124 + * from this software without specific prior written permission.
126 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
127 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
128 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
129 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
130 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
131 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
132 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
133 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
134 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
135 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
136 + * POSSIBILITY OF SUCH DAMAGE.
140 +static char sccsid[] = "@(#)rpc_clntout.c 1.11 89/02/22 (C) 1987 SMI";
144 + * rpc_clntout.c, Client-stub outputter for the RPC protocol compiler
145 + * Copyright (C) 1987, Sun Microsytsems, Inc.
149 +#include <rpc/types.h>
150 +#include "rpc_parse.h"
151 +#include "rpc_util.h"
152 +#include "rpc_output.h"
154 +/* extern pdeclaration(); */
155 +/* void printarglist(); */
157 +#define DEFAULT_TIMEOUT 25 /* in seconds */
158 +static char RESULT[] = "clnt_res";
160 +static void write_program(definition *def);
161 +static void printbody(proc_list *proc);
171 + "\n/* Default timeout can be changed using clnt_control() */\n");
172 + f_print(fout, "static struct timeval TIMEOUT = { %d, 0 };\n",
174 + for (l = defined; l != NULL; l = l->next) {
175 + def = (definition *) l->val;
176 + if (def->def_kind == DEF_PROGRAM) {
177 + write_program(def);
183 +write_program(definition *def)
188 + for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
189 + for (proc = vp->procs; proc != NULL; proc = proc->next) {
190 + f_print(fout, "\n");
191 + ptype(proc->res_prefix, proc->res_type, 1);
192 + f_print(fout, "*\n");
193 + pvname(proc->proc_name, vp->vers_num);
194 + printarglist(proc, "clnt", "CLIENT *");
195 + f_print(fout, "{\n");
197 + f_print(fout, "}\n");
203 + * Writes out declarations of procedure's argument list.
204 + * In either ANSI C style, in one of old rpcgen style (pass by reference),
205 + * or new rpcgen style (multiple arguments, pass by value);
208 +/* sample addargname = "clnt"; sample addargtype = "CLIENT * " */
211 +printarglist(proc_list *proc, char *addargname, char *addargtype)
216 + if (!newstyle) { /* old style: always pass arg by reference */
217 + if (Cflag) { /* C++ style heading */
218 + f_print(fout, "(");
219 + ptype(proc->args.decls->decl.prefix, proc->args.decls->decl.type, 1);
220 + f_print(fout, "*argp, %s%s)\n", addargtype, addargname);
222 + f_print(fout, "(argp, %s)\n", addargname);
223 + f_print(fout, "\t");
224 + ptype(proc->args.decls->decl.prefix, proc->args.decls->decl.type, 1);
225 + f_print(fout, "*argp;\n");
227 + } else if (streq(proc->args.decls->decl.type, "void")) {
228 + /* newstyle, 0 argument */
230 + f_print(fout, "(%s%s)\n", addargtype, addargname);
232 + f_print(fout, "(%s)\n", addargname);
234 + /* new style, 1 or multiple arguments */
236 + f_print(fout, "(");
237 + for (l = proc->args.decls; l != NULL; l = l->next)
238 + f_print(fout, "%s, ", l->decl.name);
239 + f_print(fout, "%s)\n", addargname);
240 + for (l = proc->args.decls; l != NULL; l = l->next) {
241 + pdeclaration(proc->args.argname, &l->decl, 1, ";\n");
243 + } else { /* C++ style header */
244 + f_print(fout, "(");
245 + for (l = proc->args.decls; l != NULL; l = l->next) {
246 + pdeclaration(proc->args.argname, &l->decl, 0, ", ");
248 + f_print(fout, " %s%s)\n", addargtype, addargname);
253 + f_print(fout, "\t%s%s;\n", addargtype, addargname);
261 + if (isvectordef(type, REL_ALIAS)) {
269 +printbody(proc_list *proc)
272 + bool_t args2 = (proc->arg_num > 1);
274 + /* For new style with multiple arguments, need a structure in which
275 + * to stuff the arguments. */
276 + if (newstyle && args2) {
277 + f_print(fout, "\t%s", proc->args.argname);
278 + f_print(fout, " arg;\n");
280 + f_print(fout, "\tstatic ");
281 + if (streq(proc->res_type, "void")) {
282 + f_print(fout, "char ");
284 + ptype(proc->res_prefix, proc->res_type, 0);
286 + f_print(fout, "%s;\n", RESULT);
287 + f_print(fout, "\n");
288 + f_print(fout, "\tmemset((char *)%s%s, 0, sizeof(%s));\n",
289 + ampr(proc->res_type), RESULT, RESULT);
290 + if (newstyle && !args2 && (streq(proc->args.decls->decl.type, "void"))) {
291 + /* newstyle, 0 arguments */
293 + "\tif (clnt_call(clnt, %s, (xdrproc_t) xdr_void, (caddr_t) NULL, "
294 + "(xdrproc_t) xdr_%s, (caddr_t) %s%s, TIMEOUT) != RPC_SUCCESS) {\n",
296 + stringfix(proc->res_type), ampr(proc->res_type), RESULT);
298 + } else if (newstyle && args2) {
299 + /* newstyle, multiple arguments: stuff arguments into structure */
300 + for (l = proc->args.decls; l != NULL; l = l->next) {
301 + f_print(fout, "\targ.%s = %s;\n",
302 + l->decl.name, l->decl.name);
305 + "\tif (clnt_call(clnt, %s, (xdrproc_t) xdr_%s, (caddr_t) &arg, "
306 + "(xdrproc_t) xdr_%s, (caddr_t) %s%s, TIMEOUT) != RPC_SUCCESS) {\n",
307 + proc->proc_name, proc->args.argname,
308 + stringfix(proc->res_type), ampr(proc->res_type), RESULT);
309 + } else { /* single argument, new or old style */
311 + "\tif (clnt_call(clnt, %s, (xdrproc_t) xdr_%s, "
312 + "(caddr_t) %s%s, (xdrproc_t) xdr_%s, (caddr_t) %s%s, TIMEOUT) != RPC_SUCCESS) {\n",
314 + stringfix(proc->args.decls->decl.type),
315 + (newstyle ? "&" : ""),
316 + (newstyle ? proc->args.decls->decl.name : "argp"),
317 + stringfix(proc->res_type), ampr(proc->res_type), RESULT);
319 + f_print(fout, "\t\treturn (NULL);\n");
320 + f_print(fout, "\t}\n");
321 + if (streq(proc->res_type, "void")) {
322 + f_print(fout, "\treturn ((void *)%s%s);\n",
323 + ampr(proc->res_type), RESULT);
325 + f_print(fout, "\treturn (%s%s);\n", ampr(proc->res_type), RESULT);
328 diff --git a/rpcgen/rpc_cout.c b/rpcgen/rpc_cout.c
330 index 0000000..a61214f
332 +++ b/rpcgen/rpc_cout.c
335 + * Copyright (c) 2009, Sun Microsystems, Inc.
336 + * All rights reserved.
338 + * Redistribution and use in source and binary forms, with or without
339 + * modification, are permitted provided that the following conditions are met:
340 + * - Redistributions of source code must retain the above copyright notice,
341 + * this list of conditions and the following disclaimer.
342 + * - Redistributions in binary form must reproduce the above copyright notice,
343 + * this list of conditions and the following disclaimer in the documentation
344 + * and/or other materials provided with the distribution.
345 + * - Neither the name of Sun Microsystems, Inc. nor the names of its
346 + * contributors may be used to endorse or promote products derived
347 + * from this software without specific prior written permission.
349 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
350 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
351 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
352 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
353 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
354 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
355 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
356 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
357 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
358 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
359 + * POSSIBILITY OF SUCH DAMAGE.
363 +static char sccsid[] = "@(#)rpc_cout.c 1.13 89/02/22 (C) 1987 SMI";
367 + * rpc_cout.c, XDR routine outputter for the RPC protocol compiler
374 +#include "rpc_parse.h"
375 +#include "rpc_util.h"
377 +static int findtype(definition *def, char *type);
378 +static int undefined(char *type);
379 +static void print_generic_header(char *procname, int pointerp);
380 +static void print_header(definition *def);
381 +static void print_prog_header(proc_list *plist);
382 +static void print_trailer(void);
383 +static void print_ifopen(int indent, char *name);
384 +static void print_ifarg(char *arg);
385 +static void print_ifsizeof(char *prefix, char *type);
386 +static void print_ifclose(int indent);
387 +static void print_ifstat(int indent, char *prefix, char *type, relation rel,
388 + char *amax, char *objname, char *name);
389 +static void emit_enum(definition *def);
390 +static void emit_program(definition *def);
391 +static void emit_union(definition *def);
392 +static void emit_struct(definition *def);
393 +static void emit_typedef(definition *def);
394 +static void print_stat(int indent, declaration *dec);
395 +static void emit_inline(declaration *decl, int flag);
396 +static void emit_single_in_line(declaration *decl, int flag, relation rel);
397 +static char * upcase(char *str);
400 + * Emit the C-routine for the given definition
403 +emit(definition *def)
405 + if (def->def_kind == DEF_CONST) {
408 + if (def->def_kind == DEF_PROGRAM) {
412 + if (def->def_kind == DEF_TYPEDEF) {
413 + /* now we need to handle declarations like
414 + * struct typedef foo foo;
415 + * since we dont want this to be expanded into 2 calls
418 + if (strcmp(def->def.ty.old_type, def->def_name) == 0)
423 + switch (def->def_kind) {
443 +findtype(definition *def, char *type)
446 + if (def->def_kind == DEF_PROGRAM || def->def_kind == DEF_CONST) {
449 + return (streq(def->def_name, type));
454 +undefined(char *type)
458 + def = (definition *) FINDVAL(defined, type, findtype);
460 + return (def == NULL);
465 +print_generic_header(char *procname, int pointerp)
467 + f_print(fout, "\n");
468 + f_print(fout, "bool_t\n");
470 + f_print(fout, "xdr_%s(", procname);
471 + f_print(fout, "XDR *xdrs, ");
472 + f_print(fout, "%s ", procname);
474 + f_print(fout, "*");
475 + f_print(fout, "objp)\n{\n\n");
477 + f_print(fout, "xdr_%s(xdrs, objp)\n", procname);
478 + f_print(fout, "\tXDR *xdrs;\n");
479 + f_print(fout, "\t%s ", procname);
481 + f_print(fout, "*");
482 + f_print(fout, "objp;\n{\n\n");
487 +print_header(definition *def)
489 + print_generic_header(def->def_name,
490 + def->def_kind != DEF_TYPEDEF ||
491 + !isvectordef(def->def.ty.old_type, def->def.ty.rel));
493 + /* Now add Inline support */
501 +print_prog_header(proc_list *plist)
503 + print_generic_header(plist->args.argname, 1);
509 + f_print(fout, "\treturn (TRUE);\n");
510 + f_print(fout, "}\n");
515 +print_ifopen(int indent, char *name)
517 + tabify(fout, indent);
518 + f_print(fout, " if (!xdr_%s(xdrs", name);
522 +print_ifarg(char *arg)
524 + f_print(fout, ", %s", arg);
528 +print_ifsizeof(char *prefix, char *type)
530 + if (streq(type, "bool")) {
531 + f_print(fout, ", sizeof(bool_t), (xdrproc_t)xdr_bool");
533 + f_print(fout, ", sizeof(");
534 + if (undefined(type) && prefix) {
535 + f_print(fout, "%s ", prefix);
537 + f_print(fout, "%s), (xdrproc_t)xdr_%s", type, type);
542 +print_ifclose(int indent)
544 + f_print(fout, ")) {\n");
545 + tabify(fout, indent);
546 + f_print(fout, "\t return (FALSE);\n");
547 + tabify(fout, indent);
548 + f_print(fout, " }\n");
552 +print_ifstat(int indent, char *prefix, char *type, relation rel,
553 + char *amax, char *objname, char *name)
559 + print_ifopen(indent, "pointer");
560 + print_ifarg("(char **)");
561 + f_print(fout, "%s", objname);
562 + print_ifsizeof(prefix, type);
565 + if (streq(type, "string")) {
567 + } else if (streq(type, "opaque")) {
571 + print_ifopen(indent, alt);
572 + print_ifarg(objname);
574 + print_ifopen(indent, "vector");
575 + print_ifarg("(char *)");
576 + f_print(fout, "%s", objname);
580 + print_ifsizeof(prefix, type);
584 + if (streq(type, "string")) {
586 + } else if (streq(type, "opaque")) {
589 + if (streq(type, "string")) {
590 + print_ifopen(indent, alt);
591 + print_ifarg(objname);
594 + print_ifopen(indent, alt);
596 + print_ifopen(indent, "array");
598 + /* The (void*) avoids a gcc-4.1 warning */
599 + print_ifarg("(char **)(void*)");
600 + if (*objname == '&') {
601 + f_print(fout, "%s.%s_val, (u_int *)%s.%s_len",
602 + objname, name, objname, name);
604 + f_print(fout, "&%s->%s_val, (u_int *)&%s->%s_len",
605 + objname, name, objname, name);
610 + print_ifsizeof(prefix, type);
614 + print_ifopen(indent, type);
615 + print_ifarg(objname);
618 + print_ifclose(indent);
622 +emit_enum(definition *def)
624 + print_ifopen(1, "enum");
625 + print_ifarg("(enum_t *)objp");
630 +emit_program(definition *def)
633 + version_list *vlist;
636 + for (vlist = def->def.pr.versions; vlist != NULL; vlist = vlist->next)
637 + for (plist = vlist->procs; plist != NULL; plist = plist->next) {
638 + if (!newstyle || plist->arg_num < 2)
639 + continue;/* old style, or single argument */
640 + print_prog_header(plist);
641 + for (dl = plist->args.decls; dl != NULL; dl = dl->next)
642 + print_stat(1, &dl->decl);
649 +emit_union(definition *def)
655 + char *vecformat = "objp->%s_u.%s";
656 + char *format = "&objp->%s_u.%s";
658 + print_stat(1,&def->def.un.enum_decl);
659 + f_print(fout, "\tswitch (objp->%s) {\n", def->def.un.enum_decl.name);
660 + for (cl = def->def.un.cases; cl != NULL; cl = cl->next) {
662 + f_print(fout, "\tcase %s:\n", cl->case_name);
663 + if(cl->contflag == 1) /* a continued case statement */
665 + cs = &cl->case_decl;
666 + if (!streq(cs->type, "void")) {
667 + object = alloc(strlen(def->def_name) + strlen(format) +
668 + strlen(cs->name) + 1);
669 + if (isvectordef (cs->type, cs->rel)) {
670 + s_print(object, vecformat, def->def_name,
673 + s_print(object, format, def->def_name,
676 + print_ifstat(2, cs->prefix, cs->type, cs->rel, cs->array_max,
680 + f_print(fout, "\t\tbreak;\n");
682 + dflt = def->def.un.default_decl;
683 + if (dflt != NULL) {
684 + if (!streq(dflt->type, "void")) {
685 + f_print(fout, "\tdefault:\n");
686 + object = alloc(strlen(def->def_name) + strlen(format) +
687 + strlen(dflt->name) + 1);
688 + if (isvectordef (dflt->type, dflt->rel)) {
689 + s_print(object, vecformat, def->def_name,
692 + s_print(object, format, def->def_name,
696 + print_ifstat(2, dflt->prefix, dflt->type, dflt->rel,
697 + dflt->array_max, object, dflt->name);
699 + f_print(fout, "\t\tbreak;\n");
701 + /* Avoid gcc warnings about `value not handled in switch' */
702 + f_print(fout, "\tdefault:\n");
703 + f_print(fout, "\t\tbreak;\n");
706 + f_print(fout, "\tdefault:\n");
707 + f_print(fout, "\t\treturn (FALSE);\n");
710 + f_print(fout, "\t}\n");
714 +emit_struct(definition *def)
717 + int i, j, size, flag;
718 + decl_list *cur = NULL, *psav;
720 + char *sizestr, *plus;
723 + const char *buf_declaration;
727 + for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
728 + print_stat(1, &dl->decl);
732 + for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
733 + if ((dl->decl.prefix == NULL) && ((ptr = find_type(dl->decl.type)) != NULL) && ((dl->decl.rel == REL_ALIAS) || (dl->decl.rel == REL_VECTOR))) {
735 + if (dl->decl.rel == REL_ALIAS)
736 + size += ptr->length;
739 + break; /* can be inlined */
742 + if (size >= Inline) {
744 + break; /* can be inlined */
751 + if (can_inline == 0) { /* can not inline, drop back to old mode */
752 + for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
753 + print_stat(1, &dl->decl);
761 + for (j = 0; j < 2; j++) {
764 + f_print(fout, "\n\t if (xdrs->x_op == XDR_ENCODE) {\n");
766 + f_print(fout, "\n \t return (TRUE);\n\t} else if (xdrs->x_op == XDR_DECODE) {\n");
772 + buf_declaration = "int32_t *";
773 + for (dl = def->def.st.decls; dl != NULL; dl = dl->next) { /* xxx */
775 + /* now walk down the list and check for basic types */
776 + if ((dl->decl.prefix == NULL) && ((ptr = find_type(dl->decl.type)) != NULL) && ((dl->decl.rel == REL_ALIAS) || (dl->decl.rel == REL_VECTOR))) {
781 + if (dl->decl.rel == REL_ALIAS)
782 + size += ptr->length;
784 + /* this is required to handle arrays */
786 + if (sizestr == NULL)
791 + if (ptr->length != 1)
792 + s_print(ptemp, " %s %s * %d", plus, dl->decl.array_max, ptr->length);
794 + s_print(ptemp, " %s %s ", plus, dl->decl.array_max);
796 + /*now concatenate to sizestr !!!! */
797 + if (sizestr == NULL)
798 + sizestr = strdup(ptemp);
800 + sizestr = realloc(sizestr, strlen(sizestr) + strlen(ptemp) + 1);
801 + if (sizestr == NULL) {
803 + f_print(stderr, "Fatal error : no memory \n");
806 + sizestr = strcat(sizestr, ptemp); /*build up length of array */
814 + if (sizestr == NULL && size < Inline) {
815 + /* don't expand into inline code if size < inline */
816 + while (cur != dl) {
817 + print_stat(1, &cur->decl);
824 + /* were already looking at a xdr_inlineable structure */
825 + if (sizestr == NULL)
826 + f_print(fout, "\t %sbuf = XDR_INLINE(xdrs,%d * BYTES_PER_XDR_UNIT);",
827 + buf_declaration, size);
828 + else if (size == 0)
830 + "\t %sbuf = XDR_INLINE(xdrs,%s * BYTES_PER_XDR_UNIT);",
831 + buf_declaration, sizestr);
834 + "\t %sbuf = XDR_INLINE(xdrs,(%d + %s)* BYTES_PER_XDR_UNIT);",
835 + buf_declaration, size, sizestr);
836 + buf_declaration = "";
838 + f_print(fout, "\n\t if (buf == NULL) {\n");
841 + while (cur != dl) {
842 + print_stat(2, &cur->decl);
846 + f_print(fout, "\n\t }\n\t else {\n");
849 + while (cur != dl) {
850 + emit_inline(&cur->decl, flag);
854 + f_print(fout, "\t }\n");
860 + print_stat(1, &dl->decl);
866 + if (sizestr == NULL && size < Inline) {
867 + /* don't expand into inline code if size < inline */
868 + while (cur != dl) {
869 + print_stat(1, &cur->decl);
874 + /* were already looking at a xdr_inlineable structure */
875 + if (sizestr == NULL)
876 + f_print(fout, "\t\t%sbuf = XDR_INLINE(xdrs,%d * BYTES_PER_XDR_UNIT);",
877 + buf_declaration, size);
878 + else if (size == 0)
880 + "\t\t%sbuf = XDR_INLINE(xdrs,%s * BYTES_PER_XDR_UNIT);",
881 + buf_declaration, sizestr);
884 + "\t\t%sbuf = XDR_INLINE(xdrs,(%d + %s)* BYTES_PER_XDR_UNIT);",
885 + buf_declaration, size, sizestr);
886 + buf_declaration = "";
888 + f_print(fout, "\n\t\tif (buf == NULL) {\n");
891 + while (cur != NULL) {
892 + print_stat(2, &cur->decl);
895 + f_print(fout, "\n\t }\n\t else {\n");
898 + while (cur != dl) {
899 + emit_inline(&cur->decl, flag);
903 + f_print(fout, "\t }\n");
909 + f_print(fout, "\t return(TRUE);\n\t}\n\n");
911 + /* now take care of XDR_FREE case */
913 + for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
914 + print_stat(1, &dl->decl);
922 +emit_typedef(definition *def)
924 + char *prefix = def->def.ty.old_prefix;
925 + char *type = def->def.ty.old_type;
926 + char *amax = def->def.ty.array_max;
927 + relation rel = def->def.ty.rel;
930 + print_ifstat(1, prefix, type, rel, amax, "objp", def->def_name);
934 +print_stat(int indent, declaration *dec)
936 + char *prefix = dec->prefix;
937 + char *type = dec->type;
938 + char *amax = dec->array_max;
939 + relation rel = dec->rel;
942 + if (isvectordef(type, rel)) {
943 + s_print(name, "objp->%s", dec->name);
945 + s_print(name, "&objp->%s", dec->name);
947 + print_ifstat(indent, prefix, type, rel, amax, name, dec->name);
952 +emit_inline(declaration *decl, int flag)
955 + /*check whether an array or not */
957 + switch (decl->rel) {
959 + emit_single_in_line(decl, flag, REL_ALIAS);
962 + f_print(fout, "\t\t{ register %s *genp; \n", decl->type);
963 + f_print(fout, "\t\t int i;\n");
964 + f_print(fout, "\t\t for ( i = 0,genp=objp->%s;\n \t\t\ti < %s; i++){\n\t\t",
965 + decl->name, decl->array_max);
966 + emit_single_in_line(decl, flag, REL_VECTOR);
967 + f_print(fout, "\t\t }\n\t\t };\n");
975 +emit_single_in_line(declaration *decl, int flag, relation rel)
981 + f_print(fout,"\t\t (void) IXDR_PUT_");
983 + if(rel== REL_ALIAS)
984 + f_print(fout,"\t\t objp->%s = IXDR_GET_",decl->name);
986 + f_print(fout,"\t\t *genp++ = IXDR_GET_");
988 + upp_case=upcase(decl->type);
991 + if(strcmp(upp_case,"INT") == 0)
998 + if(strcmp(upp_case,"U_INT") == 0)
1002 + upp_case="U_INT32";
1007 + if(rel== REL_ALIAS)
1008 + f_print(fout,"%s(buf,objp->%s);\n",upp_case,decl->name);
1010 + f_print(fout,"%s(buf,*genp++);\n",upp_case);
1013 + f_print(fout,"%s(buf);\n",upp_case);
1026 + ptr = (char *) malloc(strlen(str)+1);
1027 + if (ptr == (char *) NULL) {
1028 + f_print(stderr, "malloc failed \n");
1033 + while (*str != '\0')
1034 + *ptr++ = toupper(*str++);
1040 diff --git a/rpcgen/rpc_hout.c b/rpcgen/rpc_hout.c
1041 new file mode 100644
1042 index 0000000..ea1cb24
1044 +++ b/rpcgen/rpc_hout.c
1047 + * Copyright (c) 2009, Sun Microsystems, Inc.
1048 + * All rights reserved.
1050 + * Redistribution and use in source and binary forms, with or without
1051 + * modification, are permitted provided that the following conditions are met:
1052 + * - Redistributions of source code must retain the above copyright notice,
1053 + * this list of conditions and the following disclaimer.
1054 + * - Redistributions in binary form must reproduce the above copyright notice,
1055 + * this list of conditions and the following disclaimer in the documentation
1056 + * and/or other materials provided with the distribution.
1057 + * - Neither the name of Sun Microsystems, Inc. nor the names of its
1058 + * contributors may be used to endorse or promote products derived
1059 + * from this software without specific prior written permission.
1061 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1062 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1063 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1064 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
1065 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1066 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1067 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1068 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
1069 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1070 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
1071 + * POSSIBILITY OF SUCH DAMAGE.
1075 +static char sccsid[] = "@(#)rpc_hout.c 1.12 89/02/22 (C) 1987 SMI";
1079 + * rpc_hout.c, Header file outputter for the RPC protocol compiler
1083 +#include "rpc_parse.h"
1084 +#include "rpc_util.h"
1085 +#include "rpc_output.h"
1088 +static int undefined2(char *type, char *stop);
1089 +static void pxdrfuncdecl(char *name, int pointerp);
1090 +static void pconstdef(definition *def);
1091 +static void pargdef(definition *def);
1092 +static void pstructdef(definition *def);
1093 +static void puniondef(definition *def);
1094 +static void pdefine(char *name, char *num);
1095 +static void puldefine(char *name, char *num);
1096 +static int define_printed(proc_list *stop, version_list *start);
1097 +static void pprogramdef(definition *def);
1098 +static void pprocdef(proc_list *proc, version_list *vp,
1099 + char *addargtype, int server_p, int mode);
1100 +static void parglist(proc_list *proc, char *addargtype);
1101 +static void penumdef(definition *def);
1102 +static void ptypedef(definition *def);
1105 + * Print the C-version of an xdr definition
1108 +print_datadef(definition *def)
1111 + if (def->def_kind == DEF_PROGRAM ) /* handle data only */
1114 + if (def->def_kind != DEF_CONST) {
1115 + f_print(fout, "\n");
1117 + switch (def->def_kind) {
1137 + if (def->def_kind != DEF_PROGRAM && def->def_kind != DEF_CONST) {
1138 + pxdrfuncdecl( def->def_name,
1139 + def->def_kind != DEF_TYPEDEF ||
1140 + !isvectordef(def->def.ty.old_type, def->def.ty.rel));
1147 +print_funcdef(definition *def)
1149 + switch (def->def_kind) {
1151 + f_print(fout, "\n");
1160 +pxdrfuncdecl(char *name, int pointerp)
1163 + "#ifdef __cplusplus \n"
1164 + "extern \"C\" bool_t xdr_%s(XDR *, %s%s);\n"
1165 + "#elif __STDC__ \n"
1166 + "extern bool_t xdr_%s(XDR *, %s%s);\n"
1167 + "#else /* Old Style C */ \n"
1168 + "bool_t xdr_%s();\n"
1169 + "#endif /* Old Style C */ \n\n",
1170 + name, name, pointerp ? "*" : "",
1171 + name, name, pointerp ? "*" : "",
1177 +pconstdef(definition *def)
1179 + pdefine(def->def_name, def->def.co);
1182 +/* print out the definitions for the arguments of functions in the
1186 +pargdef(definition *def)
1189 + version_list *vers;
1194 + for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) {
1195 + for(plist = vers->procs; plist != NULL;
1196 + plist = plist->next) {
1198 + if (!newstyle || plist->arg_num < 2) {
1199 + continue; /* old style or single args */
1201 + name = plist->args.argname;
1202 + f_print(fout, "struct %s {\n", name);
1203 + for (l = plist->args.decls;
1204 + l != NULL; l = l->next) {
1205 + pdeclaration(name, &l->decl, 1, ";\n" );
1207 + f_print(fout, "};\n");
1208 + f_print(fout, "typedef struct %s %s;\n", name, name);
1209 + pxdrfuncdecl(name, 0);
1210 + f_print( fout, "\n" );
1218 +pstructdef(definition *def)
1221 + char *name = def->def_name;
1223 + f_print(fout, "struct %s {\n", name);
1224 + for (l = def->def.st.decls; l != NULL; l = l->next) {
1225 + pdeclaration(name, &l->decl, 1, ";\n");
1227 + f_print(fout, "};\n");
1228 + f_print(fout, "typedef struct %s %s;\n", name, name);
1232 +puniondef(definition *def)
1235 + char *name = def->def_name;
1236 + declaration *decl;
1238 + f_print(fout, "struct %s {\n", name);
1239 + decl = &def->def.un.enum_decl;
1240 + if (streq(decl->type, "bool")) {
1241 + f_print(fout, "\tbool_t %s;\n", decl->name);
1243 + f_print(fout, "\t%s %s;\n", decl->type, decl->name);
1245 + f_print(fout, "\tunion {\n");
1246 + for (l = def->def.un.cases; l != NULL; l = l->next) {
1247 + if (l->contflag == 0)
1248 + pdeclaration(name, &l->case_decl, 2, ";\n");
1250 + decl = def->def.un.default_decl;
1251 + if (decl && !streq(decl->type, "void")) {
1252 + pdeclaration(name, decl, 2, ";\n");
1254 + f_print(fout, "\t} %s_u;\n", name);
1255 + f_print(fout, "};\n");
1256 + f_print(fout, "typedef struct %s %s;\n", name, name);
1260 +pdefine(char *name, char *num)
1262 + f_print(fout, "#define %s %s\n", name, num);
1266 +puldefine(char *name, char *num)
1268 + f_print(fout, "#define %s ((u_int32_t)%s)\n", name, num);
1272 +define_printed(proc_list *stop, version_list *start)
1274 + version_list *vers;
1277 + for (vers = start; vers != NULL; vers = vers->next) {
1278 + for (proc = vers->procs; proc != NULL; proc = proc->next) {
1279 + if (proc == stop) {
1281 + } else if (streq(proc->proc_name, stop->proc_name)) {
1291 +pprogramdef(definition *def)
1293 + version_list *vers;
1300 + puldefine(def->def_name, def->def.pr.prog_num);
1301 + for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) {
1303 + f_print(fout, "extern struct rpcgen_table %s_%s_table[];\n",
1304 + locase(def->def_name), vers->vers_num);
1305 + f_print(fout, "extern %s_%s_nproc;\n",
1306 + locase(def->def_name), vers->vers_num);
1308 + puldefine(vers->vers_name, vers->vers_num);
1311 + * Print out 3 definitions, one for ANSI-C, another for C++,
1312 + * a third for old style C
1315 + for (i = 0; i < 3; i++) {
1317 + f_print(fout, "\n#ifdef __cplusplus\n");
1318 + ext = "extern \"C\" ";
1319 + } else if (i == 1) {
1320 + f_print(fout, "\n#elif __STDC__\n");
1323 + f_print(fout, "\n#else /* Old Style C */ \n");
1328 + for (proc = vers->procs; proc != NULL; proc = proc->next) {
1329 + if (!define_printed(proc, def->def.pr.versions)) {
1330 + puldefine(proc->proc_name, proc->proc_num);
1332 + f_print(fout, "%s", ext);
1333 + pprocdef(proc, vers, "CLIENT *", 0, i);
1334 + f_print(fout, "%s", ext);
1335 + pprocdef(proc, vers, "struct svc_req *", 1, i);
1340 + f_print(fout, "#endif /* Old Style C */ \n");
1345 +pprocdef(proc_list *proc, version_list *vp, char *addargtype,
1346 + int server_p, int mode)
1348 + ptype(proc->res_prefix, proc->res_type, 1);
1349 + f_print(fout, "* ");
1351 + pvname_svc(proc->proc_name, vp->vers_num);
1353 + pvname(proc->proc_name, vp->vers_num);
1356 + * mode 0 == cplusplus, mode 1 = ANSI-C, mode 2 = old style C
1358 + if (mode == 0 || mode == 1)
1359 + parglist(proc, addargtype);
1361 + f_print(fout, "();\n");
1366 +/* print out argument list of procedure */
1368 +parglist(proc_list *proc, char *addargtype)
1372 + f_print(fout, "(");
1374 + if (proc->arg_num < 2 && newstyle &&
1375 + streq(proc->args.decls->decl.type, "void")) {
1376 + /* 0 argument in new style: do nothing */
1378 + for (dl = proc->args.decls; dl != NULL; dl = dl->next) {
1379 + ptype(dl->decl.prefix, dl->decl.type, 1);
1381 + f_print(fout, "*"); /* old style passes by reference */
1383 + f_print(fout, ", ");
1387 + f_print(fout, "%s);\n", addargtype);
1391 +penumdef(definition *def)
1393 + char *name = def->def_name;
1395 + char *last = NULL;
1398 + f_print(fout, "enum %s {\n", name);
1399 + for (l = def->def.en.vals; l != NULL; l = l->next) {
1400 + f_print(fout, "\t%s", l->name);
1401 + if (l->assignment) {
1402 + f_print(fout, " = %s", l->assignment);
1403 + last = l->assignment;
1406 + if (last == NULL) {
1407 + f_print(fout, " = %d", count++);
1409 + f_print(fout, " = %s + %d", last, count++);
1412 + f_print(fout, ",\n");
1414 + f_print(fout, "};\n");
1415 + f_print(fout, "typedef enum %s %s;\n", name, name);
1419 +ptypedef(definition *def)
1421 + char *name = def->def_name;
1422 + char *old = def->def.ty.old_type;
1423 + char prefix[8]; /* enough to contain "struct ", including NUL */
1424 + relation rel = def->def.ty.rel;
1427 + if (!streq(name, old)) {
1428 + if (streq(old, "string")) {
1430 + rel = REL_POINTER;
1431 + } else if (streq(old, "opaque")) {
1433 + } else if (streq(old, "bool")) {
1436 + if (undefined2(old, name) && def->def.ty.old_prefix) {
1437 + s_print(prefix, "%s ", def->def.ty.old_prefix);
1441 + f_print(fout, "typedef ");
1444 + f_print(fout, "struct {\n");
1445 + f_print(fout, "\tu_int %s_len;\n", name);
1446 + f_print(fout, "\t%s%s *%s_val;\n", prefix, old, name);
1447 + f_print(fout, "} %s", name);
1450 + f_print(fout, "%s%s *%s", prefix, old, name);
1453 + f_print(fout, "%s%s %s[%s]", prefix, old, name,
1454 + def->def.ty.array_max);
1457 + f_print(fout, "%s%s %s", prefix, old, name);
1460 + f_print(fout, ";\n");
1465 +pdeclaration(char *name, declaration *dec, int tab, char *separator)
1467 + char buf[8]; /* enough to hold "struct ", include NUL */
1471 + if (streq(dec->type, "void")) {
1474 + tabify(fout, tab);
1475 + if (streq(dec->type, name) && !dec->prefix) {
1476 + f_print(fout, "struct ");
1478 + if (streq(dec->type, "string")) {
1479 + f_print(fout, "char *%s", dec->name);
1482 + if (streq(dec->type, "bool")) {
1484 + } else if (streq(dec->type, "opaque")) {
1487 + if (dec->prefix) {
1488 + s_print(buf, "%s ", dec->prefix);
1493 + switch (dec->rel) {
1495 + f_print(fout, "%s%s %s", prefix, type, dec->name);
1498 + f_print(fout, "%s%s %s[%s]", prefix, type, dec->name,
1502 + f_print(fout, "%s%s *%s", prefix, type, dec->name);
1505 + f_print(fout, "struct {\n");
1506 + tabify(fout, tab);
1507 + f_print(fout, "\tu_int %s_len;\n", dec->name);
1508 + tabify(fout, tab);
1509 + f_print(fout, "\t%s%s *%s_val;\n", prefix, type, dec->name);
1510 + tabify(fout, tab);
1511 + f_print(fout, "} %s", dec->name);
1515 + f_print(fout, separator );
1519 +undefined2(char *type, char *stop)
1524 + for (l = defined; l != NULL; l = l->next) {
1525 + def = (definition *) l->val;
1526 + if (def->def_kind != DEF_PROGRAM) {
1527 + if (streq(def->def_name, stop)) {
1529 + } else if (streq(def->def_name, type)) {
1536 diff --git a/rpcgen/rpc_main.c b/rpcgen/rpc_main.c
1537 new file mode 100644
1538 index 0000000..28aa60c
1540 +++ b/rpcgen/rpc_main.c
1543 + * Copyright (c) 2009, Sun Microsystems, Inc.
1544 + * All rights reserved.
1546 + * Redistribution and use in source and binary forms, with or without
1547 + * modification, are permitted provided that the following conditions are met:
1548 + * - Redistributions of source code must retain the above copyright notice,
1549 + * this list of conditions and the following disclaimer.
1550 + * - Redistributions in binary form must reproduce the above copyright notice,
1551 + * this list of conditions and the following disclaimer in the documentation
1552 + * and/or other materials provided with the distribution.
1553 + * - Neither the name of Sun Microsystems, Inc. nor the names of its
1554 + * contributors may be used to endorse or promote products derived
1555 + * from this software without specific prior written permission.
1557 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1558 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1559 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1560 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
1561 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1562 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1563 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1564 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
1565 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1566 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
1567 + * POSSIBILITY OF SUCH DAMAGE.
1571 +static char sccsid[] = "@(#)rpc_main.c 1.30 89/03/30 (C) 1987 SMI";
1575 + * rpc_main.c, Top level of the RPC protocol compiler.
1578 +#include <sys/types.h>
1579 +#include <sys/param.h>
1580 +#include <sys/file.h>
1581 +#include <sys/stat.h>
1583 +#include <string.h>
1584 +#include <stdlib.h>
1585 +#include <unistd.h>
1588 +#include "rpc_parse.h"
1589 +#include "rpc_util.h"
1590 +#include "rpc_scan.h"
1592 +struct commandline {
1593 + int cflag; /* xdr C routines */
1594 + int hflag; /* header file */
1595 + int lflag; /* client side stubs */
1596 + int mflag; /* server side stubs */
1597 + int nflag; /* netid flag */
1598 + int sflag; /* server stubs for the given transport */
1599 + int tflag; /* dispatch Table file */
1600 + int Ssflag; /* produce server sample code */
1601 + int Scflag; /* produce client sample code */
1602 + char *infile; /* input module name */
1603 + char *outfile; /* output module name */
1606 +static char * extendfile(char *file, char *ext);
1607 +static void open_output(char *infile, char *outfile);
1608 +static void add_warning(void);
1609 +static void clear_args(void);
1610 +static void open_input(char *infile, char *define);
1611 +static int check_nettype(char *name, char **list_to_check);
1612 +static void c_output(char *infile, char *define, int extend, char *outfile);
1613 +static void c_initialize(void);
1614 +static char * generate_guard(char *pathname);
1615 +static void h_output(char *infile, char *define, int extend, char *outfile);
1616 +static void s_output(int argc, char **argv, char *infile,
1617 + char *define, int extend, char *outfile,
1618 + int nomain, int netflag);
1619 +static void l_output(char *infile, char *define, int extend, char *outfile);
1620 +static void t_output(char *infile, char *define, int extend, char *outfile);
1621 +static void svc_output(char *, char *, int, char *);
1622 +static void clnt_output(char *, char *, int, char *);
1623 +static int do_registers(int argc, char **argv);
1624 +static void addarg(char *cp);
1625 +static void putarg(int where, char *cp);
1626 +static void checkfiles(char *infile, char *outfile);
1627 +static int parseargs(int argc, char **argv, struct commandline *cmd);
1628 +static void usage(void);
1629 +static void options_usage(void);
1632 +extern void write_sample_svc();
1633 +int write_sample_clnt();
1634 +void write_sample_clnt_main();
1636 +static svc_output();
1639 +#define EXTEND 1 /* alias for TRUE */
1640 +#define DONT_EXTEND 0 /* alias for FALSE */
1642 +#define SVR4_CPP "/usr/ccs/lib/cpp"
1643 +#define SUNOS_CPP "/lib/cpp"
1644 +static int cppDefined = 0; /* explicit path for C preprocessor */
1647 +static char *cmdname;
1649 +static char *svcclosetime = "120";
1650 +static char *CPP = SVR4_CPP;
1651 +static char CPPFLAGS[] = "-C";
1652 +static char pathbuf[MAXPATHLEN + 1];
1653 +static char *allv[] = {
1654 + "rpcgen", "-s", "udp", "-s", "tcp",
1656 +static int allc = sizeof(allv)/sizeof(allv[0]);
1657 +static char *allnv[] = {
1658 + "rpcgen", "-s", "netpath",
1660 +static int allnc = sizeof(allnv)/sizeof(allnv[0]);
1663 + * machinations for handling expanding argument list
1666 +static void addarg(); /* add another argument to the list */
1667 +static void putarg(); /* put argument at specified location */
1668 +static void clear_args(); /* clear argument list */
1669 +static void checkfiles(); /* check if out file already exists */
1674 +#define ARGLISTLEN 20
1675 +#define FIXEDARGS 2
1677 +static char *arglist[ARGLISTLEN];
1678 +static int argcount = FIXEDARGS;
1681 +int nonfatalerrors; /* errors */
1682 +int inetdflag/* = 1*/; /* Support for inetd */ /* is now the default */
1683 +int pmflag; /* Support for port monitors */
1684 +int logflag; /* Use syslog instead of fprintf for errors */
1685 +int tblflag; /* Support for dispatch table file */
1687 +/* length at which to start doing an inline */
1690 +int Inline = INLINE; /* length at which to start doing an inline. 3 = default
1691 + * if 0, no xdr_inline code */
1693 +int indefinitewait; /* If started by port monitors, hang till it wants */
1694 +int exitnow; /* If started by port monitors, exit after the call */
1695 +int timerflag; /* TRUE if !indefinite && !exitnow */
1696 +int newstyle; /* newstyle of passing arguments (by value) */
1697 +int Cflag = 0 ; /* ANSI C syntax */
1698 +static int allfiles; /* generate all files */
1700 +int tirpcflag = 0; /* no tirpc by default */
1702 +int tirpcflag = 1; /* generating code for tirpc, by default */
1706 +main(int argc, char **argv)
1708 + struct commandline cmd;
1710 + (void) memset((char *) &cmd, 0, sizeof(struct commandline));
1712 + if (!parseargs(argc, argv, &cmd))
1715 + if (cmd.cflag || cmd.hflag || cmd.lflag || cmd.tflag || cmd.sflag ||
1716 + cmd.mflag || cmd.nflag || cmd.Ssflag || cmd.Scflag) {
1717 + checkfiles(cmd.infile, cmd.outfile);
1719 + checkfiles(cmd.infile, NULL);
1722 + c_output(cmd.infile, "-DRPC_XDR", DONT_EXTEND, cmd.outfile);
1723 + } else if (cmd.hflag) {
1724 + h_output(cmd.infile, "-DRPC_HDR", DONT_EXTEND, cmd.outfile);
1725 + } else if (cmd.lflag) {
1726 + l_output(cmd.infile, "-DRPC_CLNT", DONT_EXTEND, cmd.outfile);
1727 + } else if (cmd.sflag || cmd.mflag || (cmd.nflag)) {
1728 + s_output(argc, argv, cmd.infile, "-DRPC_SVC", DONT_EXTEND,
1729 + cmd.outfile, cmd.mflag, cmd.nflag);
1730 + } else if (cmd.tflag) {
1731 + t_output(cmd.infile, "-DRPC_TBL", DONT_EXTEND, cmd.outfile);
1732 + } else if (cmd.Ssflag) {
1733 + svc_output(cmd.infile, "-DRPC_SERVER", DONT_EXTEND, cmd.outfile);
1734 + } else if (cmd.Scflag) {
1735 + clnt_output(cmd.infile, "-DRPC_CLIENT", DONT_EXTEND, cmd.outfile);
1737 + /* the rescans are required, since cpp may effect input */
1738 + c_output(cmd.infile, "-DRPC_XDR", EXTEND, "_xdr.c");
1740 + h_output(cmd.infile, "-DRPC_HDR", EXTEND, ".h");
1742 + l_output(cmd.infile, "-DRPC_CLNT", EXTEND, "_clnt.c");
1744 + if (inetdflag || !tirpcflag)
1745 + s_output(allc, allv, cmd.infile, "-DRPC_SVC", EXTEND,
1746 + "_svc.c", cmd.mflag, cmd.nflag);
1748 + s_output(allnc, allnv, cmd.infile, "-DRPC_SVC",
1749 + EXTEND, "_svc.c", cmd.mflag, cmd.nflag);
1752 + t_output(cmd.infile, "-DRPC_TBL", EXTEND, "_tbl.i");
1756 + svc_output(cmd.infile, "-DRPC_SERVER", EXTEND, "_server.c");
1760 + clnt_output(cmd.infile, "-DRPC_CLIENT", EXTEND, "_client.c");
1763 + exit(nonfatalerrors);
1768 + * add extension to filename
1771 +extendfile(char *file, char *ext)
1776 + res = alloc(strlen(file) + strlen(ext) + 1);
1777 + if (res == NULL) {
1780 + p = strrchr(file, '.');
1782 + p = file + strlen(file);
1784 + (void) strcpy(res, file);
1785 + (void) strcpy(res + (p - file), ext);
1790 + * Open output file with given extension
1793 +open_output(char *infile, char *outfile)
1796 + if (outfile == NULL) {
1801 + if (infile != NULL && streq(outfile, infile)) {
1802 + f_print(stderr, "%s: output would overwrite %s\n", cmdname,
1806 + fout = fopen(outfile, "w");
1807 + if (fout == NULL) {
1808 + f_print(stderr, "%s: unable to open ", cmdname);
1812 + record_open(outfile);
1819 + f_print(fout, "/*\n");
1820 + f_print(fout, " * Please do not edit this file.\n");
1821 + f_print(fout, " * It was generated using rpcgen.\n");
1822 + f_print(fout, " */\n\n");
1825 +/* clear list of arguments */
1830 + for( i=FIXEDARGS; i<ARGLISTLEN; i++ )
1831 + arglist[i] = NULL;
1832 + argcount = FIXEDARGS;
1836 + * Open input file with given define for C-preprocessor
1839 +open_input(char *infile, char *define)
1843 + infilename = (infile == NULL) ? "<stdin>" : infile;
1848 + putarg(1, CPPFLAGS);
1851 + addarg((char *)NULL);
1853 + (void) dup2(pd[1], 1);
1854 + (void) close(pd[0]);
1856 + execv(CPP, arglist);
1858 + execvp("cpp", arglist);
1859 + if (errno == ENOENT)
1860 + execvp(SVR4_CPP, arglist);
1861 + if (errno == ENOENT)
1862 + execvp(SUNOS_CPP, arglist);
1870 + (void) close(pd[1]);
1871 + fin = fdopen(pd[0], "r");
1872 + if (fin == NULL) {
1873 + f_print(stderr, "%s: ", cmdname);
1874 + perror(infilename);
1879 +/* valid tirpc nettypes */
1880 +static char* valid_ti_nettypes[] =
1894 +/* valid inetd nettypes */
1895 +static char* valid_i_nettypes[] =
1903 +check_nettype(char *name, char **list_to_check)
1906 + for( i = 0; list_to_check[i] != NULL; i++ ) {
1907 + if( strcmp( name, list_to_check[i] ) == 0 ) {
1911 + f_print( stderr, "illegal nettype :\'%s\'\n", name );
1916 + * Compile into an XDR routine output file
1920 +c_output(char *infile, char *define, int extend, char *outfile)
1924 + char *outfilename;
1928 + open_input(infile, define);
1929 + outfilename = extend ? extendfile(infile, outfile) : outfile;
1930 + open_output(infile, outfilename);
1932 + if (infile && (include = extendfile(infile, ".h"))) {
1933 + f_print(fout, "#include \"%s\"\n", include);
1935 + /* .h file already contains rpc/rpc.h */
1937 + f_print(fout, "#include <rpc/rpc.h>\n");
1938 + tell = ftell(fout);
1939 + while ((def = get_definition()) != NULL) {
1942 + if (extend && tell == ftell(fout)) {
1943 + (void) unlink(outfilename);
1952 + /* add all the starting basic types */
1954 + add_type(1,"int");
1955 + add_type(1,"int32_t");
1956 + add_type(1,"short");
1957 + add_type(1,"bool");
1959 + add_type(1,"u_int");
1960 + add_type(1,"u_int32_t");
1961 + add_type(1,"u_short");
1965 +char rpcgen_table_dcl[] = "struct rpcgen_table {\n\
1966 + char *(*proc)();\n\
1967 + xdrproc_t xdr_arg;\n\
1968 + unsigned len_arg;\n\
1969 + xdrproc_t xdr_res;\n\
1970 + unsigned len_res;\n\
1975 +generate_guard(char *pathname)
1977 + char* filename, *guard, *tmp;
1979 + filename = strrchr(pathname, '/' ); /* find last component */
1980 + filename = ((filename == 0) ? pathname : filename+1);
1981 + guard = strdup(filename);
1982 + /* convert to upper case */
1985 + if (islower(*tmp))
1986 + *tmp = toupper(*tmp);
1990 + guard = extendfile(guard, "_H_RPCGEN");
1995 + * Compile into an XDR header file
1998 +h_output(char *infile, char *define, int extend, char *outfile)
2001 + char *outfilename;
2006 + open_input(infile, define);
2007 + outfilename = extend ? extendfile(infile, outfile) : outfile;
2008 + open_output(infile, outfilename);
2010 + guard = generate_guard( outfilename ? outfilename: infile );
2012 + f_print(fout,"#ifndef _%s\n#define _%s\n\n", guard,
2015 + f_print(fout, "#include <rpc/rpc.h>\n\n");
2017 + f_print(fout, "#ifndef IXDR_GET_INT32\n");
2018 + f_print(fout, "#define IXDR_GET_INT32(buf) IXDR_GET_LONG((buf))\n");
2019 + f_print(fout, "#endif\n");
2020 + f_print(fout, "#ifndef IXDR_PUT_INT32\n");
2021 + f_print(fout, "#define IXDR_PUT_INT32(buf, v) IXDR_PUT_LONG((buf), (v))\n");
2022 + f_print(fout, "#endif\n");
2023 + f_print(fout, "#ifndef IXDR_GET_U_INT32\n");
2024 + f_print(fout, "#define IXDR_GET_U_INT32(buf) IXDR_GET_U_LONG((buf))\n");
2025 + f_print(fout, "#endif\n");
2026 + f_print(fout, "#ifndef IXDR_PUT_U_INT32\n");
2027 + f_print(fout, "#define IXDR_PUT_U_INT32(buf, v) IXDR_PUT_U_LONG((buf), (v))\n");
2028 + f_print(fout, "#endif\n");
2030 + tell = ftell(fout);
2031 + /* print data definitions */
2032 + while ((def = get_definition()) != NULL) {
2033 + print_datadef(def);
2036 + /* print function declarations.
2037 + Do this after data definitions because they might be used as
2038 + arguments for functions */
2039 + for (l = defined; l != NULL; l = l->next) {
2040 + print_funcdef(l->val);
2042 + if (extend && tell == ftell(fout)) {
2043 + (void) unlink(outfilename);
2044 + } else if (tblflag) {
2045 + f_print(fout, rpcgen_table_dcl);
2047 + f_print(fout, "\n#endif /* !_%s */\n", guard);
2051 + * Compile into an RPC service
2054 +s_output(int argc, char **argv, char *infile, char *define, int extend,
2055 + char *outfile, int nomain, int netflag)
2059 + int foundprogram = 0;
2060 + char *outfilename;
2062 + open_input(infile, define);
2063 + outfilename = extend ? extendfile(infile, outfile) : outfile;
2064 + open_output(infile, outfilename);
2066 + if (infile && (include = extendfile(infile, ".h"))) {
2067 + f_print(fout, "#include \"%s\"\n", include);
2070 + f_print(fout, "#include <rpc/rpc.h>\n");
2072 + f_print(fout, "#include <stdio.h>\n");
2073 + f_print(fout, "#include <stdlib.h>/* getenv, exit */\n");
2075 + f_print (fout, "#include <rpc/pmap_clnt.h> /* for pmap_unset */\n");
2076 + f_print (fout, "#include <string.h> /* strcmp */ \n");
2078 + if (strcmp(svcclosetime, "-1") == 0)
2079 + indefinitewait = 1;
2080 + else if (strcmp(svcclosetime, "0") == 0)
2082 + else if (inetdflag || pmflag) {
2083 + f_print(fout, "#include <signal.h>\n");
2088 + if( !tirpcflag && inetdflag )
2089 + f_print(fout, "#include <sys/ttycom.h>/* TIOCNOTTY */\n");
2092 + f_print(fout, "#include <sys/ioctl.h>/* TIOCNOTTY */\n");
2094 + if( Cflag && (inetdflag || pmflag ) ) {
2095 + f_print(fout, "#ifdef __cplusplus\n");
2096 + f_print(fout, "#include <sysent.h> /* getdtablesize, open */\n");
2097 + f_print(fout, "#endif /* __cplusplus */\n");
2100 + f_print(fout, "#include <unistd.h> /* setsid */\n");
2103 + f_print(fout, "#include <sys/types.h>\n");
2105 + f_print(fout, "#include <memory.h>\n");
2107 + f_print(fout, "#include <stropts.h>\n");
2109 + if (inetdflag || !tirpcflag ) {
2110 + f_print(fout, "#include <sys/socket.h>\n");
2111 + f_print(fout, "#include <netinet/in.h>\n");
2114 + if ( (netflag || pmflag) && tirpcflag ) {
2115 + f_print(fout, "#include <netconfig.h>\n");
2117 + if (/*timerflag &&*/ tirpcflag)
2118 + f_print(fout, "#include <sys/resource.h> /* rlimit */\n");
2119 + if (logflag || inetdflag || pmflag) {
2121 + f_print(fout, "#include <syslog.h>\n");
2123 + f_print(fout, "#ifdef SYSLOG\n");
2124 + f_print(fout, "#include <syslog.h>\n");
2125 + f_print(fout, "#else\n");
2126 + f_print(fout, "#define LOG_ERR 1\n");
2127 + f_print(fout, "#define openlog(a, b, c)\n");
2128 + f_print(fout, "#endif\n");
2133 + f_print(fout, "\n#ifdef __STDC__\n#define SIG_PF void(*)(int)\n#endif\n");
2135 + f_print(fout, "\n#ifdef DEBUG\n#define RPC_SVC_FG\n#endif\n");
2137 + f_print(fout, "\n#define _RPCSVC_CLOSEDOWN %s\n", svcclosetime);
2138 + while ((def = get_definition()) != NULL) {
2139 + foundprogram |= (def->def_kind == DEF_PROGRAM);
2141 + if (extend && !foundprogram) {
2142 + (void) unlink(outfilename);
2145 + write_most(infile, netflag, nomain);
2147 + if( !do_registers(argc, argv) ) {
2149 + (void) unlink(outfilename);
2157 + * generate client side stubs
2160 +l_output(char *infile, char *define, int extend, char *outfile)
2164 + int foundprogram = 0;
2165 + char *outfilename;
2167 + open_input(infile, define);
2168 + outfilename = extend ? extendfile(infile, outfile) : outfile;
2169 + open_output(infile, outfilename);
2172 + f_print (fout, "#include <memory.h> /* for memset */\n");
2173 + if (infile && (include = extendfile(infile, ".h"))) {
2174 + f_print(fout, "#include \"%s\"\n", include);
2177 + f_print(fout, "#include <rpc/rpc.h>\n");
2178 + while ((def = get_definition()) != NULL) {
2179 + foundprogram |= (def->def_kind == DEF_PROGRAM);
2181 + if (extend && !foundprogram) {
2182 + (void) unlink(outfilename);
2189 + * generate the dispatch table
2192 +t_output(char *infile, char *define, int extend, char *outfile)
2195 + int foundprogram = 0;
2196 + char *outfilename;
2198 + open_input(infile, define);
2199 + outfilename = extend ? extendfile(infile, outfile) : outfile;
2200 + open_output(infile, outfilename);
2202 + while ((def = get_definition()) != NULL) {
2203 + foundprogram |= (def->def_kind == DEF_PROGRAM);
2205 + if (extend && !foundprogram) {
2206 + (void) unlink(outfilename);
2212 +/* sample routine for the server template */
2214 +svc_output(char *infile, char *define, int extend, char *outfile)
2218 + char *outfilename;
2221 + open_input(infile, define);
2222 + outfilename = extend ? extendfile(infile, outfile) : outfile;
2223 + checkfiles(infile,outfilename); /*check if outfile already exists.
2224 + if so, print an error message and exit*/
2225 + open_output(infile, outfilename);
2228 + if (infile && (include = extendfile(infile, ".h"))) {
2229 + f_print(fout, "#include \"%s\"\n", include);
2232 + f_print(fout, "#include <rpc/rpc.h>\n");
2234 + tell = ftell(fout);
2235 + while ((def = get_definition()) != NULL) {
2236 + write_sample_svc(def);
2238 + if (extend && tell == ftell(fout)) {
2239 + (void) unlink(outfilename);
2244 +/* sample main routine for client */
2246 +clnt_output(char *infile, char *define, int extend, char *outfile)
2250 + char *outfilename;
2252 + int has_program = 0;
2254 + open_input(infile, define);
2255 + outfilename = extend ? extendfile(infile, outfile) : outfile;
2256 + checkfiles(infile, outfilename); /*check if outfile already exists.
2257 + if so, print an error message and exit*/
2259 + open_output(infile, outfilename);
2261 + if (infile && (include = extendfile(infile, ".h"))) {
2262 + f_print(fout, "#include \"%s\"\n", include);
2265 + f_print(fout, "#include <rpc/rpc.h>\n");
2266 + tell = ftell(fout);
2267 + while ((def = get_definition()) != NULL) {
2268 + has_program += write_sample_clnt(def);
2272 + write_sample_clnt_main();
2274 + if (extend && tell == ftell(fout)) {
2275 + (void) unlink(outfilename);
2280 + * Perform registrations for service output
2281 + * Return 0 if failed; 1 otherwise.
2284 +do_registers(int argc, char **argv)
2288 + if (inetdflag || !tirpcflag) {
2289 + for (i = 1; i < argc; i++) {
2290 + if (streq(argv[i], "-s")) {
2291 + if (!check_nettype(argv[i + 1], valid_i_nettypes))
2293 + write_inetd_register(argv[i + 1]);
2298 + for (i = 1; i < argc; i++)
2299 + if (streq(argv[i], "-s")) {
2300 + if (!check_nettype(argv[i + 1], valid_ti_nettypes))
2302 + write_nettype_register(argv[i + 1]);
2304 + } else if (streq(argv[i], "-n")) {
2305 + write_netid_register(argv[i + 1]);
2313 + * Add another argument to the arg list
2318 + if (argcount >= ARGLISTLEN) {
2319 + f_print(stderr, "rpcgen: too many defines\n");
2323 + arglist[argcount++] = cp;
2328 +putarg(int where, char *cp)
2330 + if (where >= ARGLISTLEN) {
2331 + f_print(stderr, "rpcgen: arglist coding error\n");
2335 + arglist[where] = cp;
2340 + * if input file is stdin and an output file is specified then complain
2341 + * if the file already exists. Otherwise the file may get overwritten
2342 + * If input file does not exist, exit with an error
2346 +checkfiles(char *infile, char *outfile)
2351 + if(infile) /* infile ! = NULL */
2352 + if(stat(infile,&buf) < 0)
2358 + if (stat(outfile, &buf) < 0)
2359 + return; /* file does not exist */
2362 + "file '%s' already exists and may be overwritten\n", outfile);
2369 + * Parse command line arguments
2372 +parseargs(int argc, char **argv, struct commandline *cmd)
2377 + char flag[(1 << 8 * sizeof(char))];
2380 + cmdname = argv[0];
2381 + cmd->infile = cmd->outfile = NULL;
2396 + for (i = 1; i < argc; i++) {
2397 + if (argv[i][0] != '-') {
2398 + if (cmd->infile) {
2399 + f_print( stderr, "Cannot specify more than one input file!\n");
2403 + cmd->infile = argv[i];
2405 + for (j = 1; argv[i][j] != 0; j++) {
2416 + if (flag[(int) c]) {
2419 + flag[(int) c] = 1;
2422 + /* sample flag: Ss or Sc.
2423 + Ss means set flag['S'];
2424 + Sc means set flag['C']; */
2425 + c = argv[i][++j]; /* get next char */
2428 + else if( c == 'c' )
2433 + if (flag[(int) c]) {
2436 + flag[(int) c] = 1;
2438 + case 'C': /* ANSI C syntax */
2442 + case 'b': /* turn TIRPC flag off for
2443 + generating backward compatible
2458 + if (++i == argc) {
2461 + svcclosetime = argv[i];
2467 + if (++i == argc) {
2470 + Inline = atoi(argv[i]);
2475 + if (argv[i][j - 1] != '-' ||
2476 + argv[i][j + 1] != 0) {
2479 + flag[(int) c] = 1;
2480 + if (++i == argc) {
2484 + if (!streq(argv[i], "udp") &&
2485 + !streq(argv[i], "tcp")) {
2488 + } else if (c == 'o') {
2489 + if (cmd->outfile) {
2492 + cmd->outfile = argv[i];
2496 + if (argv[i][j - 1] != '-') {
2499 + (void) addarg(argv[i]);
2502 + if (++i == argc) {
2505 + (void) strcpy(pathbuf, argv[i]);
2506 + (void) strcat(pathbuf, "/cpp");
2522 + cmd->cflag = flag['c'];
2523 + cmd->hflag = flag['h'];
2524 + cmd->lflag = flag['l'];
2525 + cmd->mflag = flag['m'];
2526 + cmd->nflag = flag['n'];
2527 + cmd->sflag = flag['s'];
2528 + cmd->tflag = flag['t'];
2529 + cmd->Ssflag = flag['S'];
2530 + cmd->Scflag = flag['C'];
2533 + pmflag = inetdflag ? 0 : 1; /* pmflag or inetdflag is always TRUE */
2534 + if( (inetdflag && cmd->nflag)) { /* netid not allowed with inetdflag */
2535 + f_print(stderr, "Cannot use netid flag with inetd flag!\n");
2538 + } else { /* 4.1 mode */
2539 + pmflag = 0; /* set pmflag only in tirpcmode */
2540 + inetdflag = 1; /* inetdflag is TRUE by default */
2541 + if( cmd->nflag ) { /* netid needs TIRPC */
2542 + f_print( stderr, "Cannot use netid flag without TIRPC!\n");
2547 + if( newstyle && ( tblflag || cmd->tflag) ) {
2548 + f_print( stderr, "Cannot use table flags with newstyle!\n");
2552 + /* check no conflicts with file generation flags */
2553 + nflags = cmd->cflag + cmd->hflag + cmd->lflag + cmd->mflag +
2554 + cmd->sflag + cmd->nflag + cmd->tflag + cmd->Ssflag + cmd->Scflag;
2556 + if (nflags == 0) {
2557 + if (cmd->outfile != NULL || cmd->infile == NULL) {
2560 + } else if (nflags > 1) {
2561 + f_print( stderr, "Cannot have more than one file generation flag!\n");
2570 + f_print(stderr, "usage: %s infile\n", cmdname);
2571 + f_print(stderr, "\t%s [-a][-b][-C][-Dname[=value]] -i size [-I [-K seconds]] [-L][-N][-T] infile\n",
2573 + f_print(stderr, "\t%s [-c | -h | -l | -m | -t | -Sc | -Ss] [-o outfile] [infile]\n",
2575 + f_print(stderr, "\t%s [-s nettype]* [-o outfile] [infile]\n", cmdname);
2576 + f_print(stderr, "\t%s [-n netid]* [-o outfile] [infile]\n", cmdname);
2582 +options_usage(void)
2584 + f_print(stderr, "options:\n");
2585 + f_print(stderr, "-a\t\tgenerate all files, including samples\n");
2586 + f_print(stderr, "-b\t\tbackward compatibility mode (generates code for SunOS 4.1)\n");
2587 + f_print(stderr, "-c\t\tgenerate XDR routines\n");
2588 + f_print(stderr, "-C\t\tANSI C mode\n");
2589 + f_print(stderr, "-Dname[=value]\tdefine a symbol (same as #define)\n");
2590 + f_print(stderr, "-h\t\tgenerate header file\n");
2591 + f_print(stderr, "-i size\t\tsize at which to start generating inline code\n");
2592 + f_print(stderr, "-I\t\tgenerate code for inetd support in server (for SunOS 4.1)\n");
2593 + f_print(stderr, "-K seconds\tserver exits after K seconds of inactivity\n");
2594 + f_print(stderr, "-l\t\tgenerate client side stubs\n");
2595 + f_print(stderr, "-L\t\tserver errors will be printed to syslog\n");
2596 + f_print(stderr, "-m\t\tgenerate server side stubs\n");
2597 + f_print(stderr, "-n netid\tgenerate server code that supports named netid\n");
2598 + f_print(stderr, "-N\t\tsupports multiple arguments and call-by-value\n");
2599 + f_print(stderr, "-o outfile\tname of the output file\n");
2600 + f_print(stderr, "-s nettype\tgenerate server code that supports named nettype\n");
2601 + f_print(stderr, "-Sc\t\tgenerate sample client code that uses remote procedures\n");
2602 + f_print(stderr, "-Ss\t\tgenerate sample server code that defines remote procedures\n");
2603 + f_print(stderr, "-t\t\tgenerate RPC dispatch table\n");
2604 + f_print(stderr, "-T\t\tgenerate code to support RPC dispatch tables\n");
2605 + f_print(stderr, "-Y path\t\tdirectory name to find C preprocessor (cpp)\n");
2609 diff --git a/rpcgen/rpc_output.h b/rpcgen/rpc_output.h
2610 new file mode 100644
2611 index 0000000..eb25a60
2613 +++ b/rpcgen/rpc_output.h
2618 + * Declarations for output functions
2622 +#ifndef RPCGEN_NEW_OUTPUT_H
2623 +#define RPCGEN_NEW_OUTPUT_H
2625 +void write_msg_out(void);
2626 +int nullproc(proc_list *);
2627 +void printarglist(proc_list *, char *, char *);
2628 +void pdeclaration(char *, declaration *, int, char *);
2630 +#endif /* RPCGEN_NEW_OUTPUT_H */
2631 diff --git a/rpcgen/rpc_parse.c b/rpcgen/rpc_parse.c
2632 new file mode 100644
2633 index 0000000..b53a553
2635 +++ b/rpcgen/rpc_parse.c
2638 + * Copyright (c) 2009, Sun Microsystems, Inc.
2639 + * All rights reserved.
2641 + * Redistribution and use in source and binary forms, with or without
2642 + * modification, are permitted provided that the following conditions are met:
2643 + * - Redistributions of source code must retain the above copyright notice,
2644 + * this list of conditions and the following disclaimer.
2645 + * - Redistributions in binary form must reproduce the above copyright notice,
2646 + * this list of conditions and the following disclaimer in the documentation
2647 + * and/or other materials provided with the distribution.
2648 + * - Neither the name of Sun Microsystems, Inc. nor the names of its
2649 + * contributors may be used to endorse or promote products derived
2650 + * from this software without specific prior written permission.
2652 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2653 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2654 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2655 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
2656 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2657 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2658 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2659 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2660 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2661 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2662 + * POSSIBILITY OF SUCH DAMAGE.
2666 +static char sccsid[] = "@(#)rpc_parse.c 1.8 89/02/22 (C) 1987 SMI";
2670 + * rpc_parse.c, Parser for the RPC protocol compiler
2671 + * Copyright (C) 1987 Sun Microsystems, Inc.
2674 +#include <string.h>
2675 +#include "rpc/types.h"
2676 +#include "rpc_scan.h"
2677 +#include "rpc_parse.h"
2678 +#include "rpc_util.h"
2680 +#define ARGNAME "arg"
2683 +extern char *make_argname();
2684 +extern char *strdup();
2687 +static void isdefined(definition *defp);
2688 +static void def_struct(definition *defp);
2689 +static void def_program(definition *defp);
2690 +static void def_enum(definition *defp);
2691 +static void def_const(definition *defp);
2692 +static void def_union(definition *defp);
2693 +static void check_type_name(char *name, int new_type);
2694 +static void def_typedef(definition *defp);
2695 +static void get_declaration(declaration *dec, defkind dkind);
2696 +static void get_prog_declaration(declaration *dec, defkind dkind, int num);
2697 +static void get_type(char **prefixp, char **typep, defkind dkind);
2698 +static void unsigned_dec(char **typep);
2701 + * return the next definition you see
2704 +get_definition(void)
2709 + defp = ALLOC(definition);
2711 + switch (tok.kind) {
2719 + def_typedef(defp);
2725 + def_program(defp);
2734 + error("definition keyword expected");
2736 + scan(TOK_SEMICOLON, &tok);
2742 +isdefined(definition *defp)
2744 + STOREVAL(&defined, defp);
2748 +def_struct(definition *defp)
2753 + decl_list **tailp;
2755 + defp->def_kind = DEF_STRUCT;
2757 + scan(TOK_IDENT, &tok);
2758 + defp->def_name = tok.str;
2759 + scan(TOK_LBRACE, &tok);
2760 + tailp = &defp->def.st.decls;
2762 + get_declaration(&dec, DEF_STRUCT);
2763 + decls = ALLOC(decl_list);
2764 + decls->decl = dec;
2766 + tailp = &decls->next;
2767 + scan(TOK_SEMICOLON, &tok);
2769 + } while (tok.kind != TOK_RBRACE);
2775 +def_program(definition *defp)
2780 + decl_list **tailp;
2781 + version_list *vlist;
2782 + version_list **vtailp;
2784 + proc_list **ptailp;
2786 + bool_t isvoid = FALSE; /* whether first argument is void */
2787 + defp->def_kind = DEF_PROGRAM;
2788 + scan(TOK_IDENT, &tok);
2789 + defp->def_name = tok.str;
2790 + scan(TOK_LBRACE, &tok);
2791 + vtailp = &defp->def.pr.versions;
2792 + tailp = &defp->def.st.decls;
2793 + scan(TOK_VERSION, &tok);
2795 + scan(TOK_IDENT, &tok);
2796 + vlist = ALLOC(version_list);
2797 + vlist->vers_name = tok.str;
2798 + scan(TOK_LBRACE, &tok);
2799 + ptailp = &vlist->procs;
2801 + /* get result type */
2802 + plist = ALLOC(proc_list);
2803 + get_type(&plist->res_prefix, &plist->res_type,
2805 + if (streq(plist->res_type, "opaque")) {
2806 + error("illegal result type");
2808 + scan(TOK_IDENT, &tok);
2809 + plist->proc_name = tok.str;
2810 + scan(TOK_LPAREN, &tok);
2811 + /* get args - first one*/
2814 + /* type of DEF_PROGRAM in the first
2815 + * get_prog_declaration and DEF_STURCT in the next
2816 + * allows void as argument if it is the only argument
2818 + get_prog_declaration(&dec, DEF_PROGRAM, num_args);
2819 + if (streq(dec.type, "void"))
2821 + decls = ALLOC(decl_list);
2822 + plist->args.decls = decls;
2823 + decls->decl = dec;
2824 + tailp = &decls->next;
2826 + while(peekscan(TOK_COMMA, &tok)) {
2828 + get_prog_declaration(&dec, DEF_STRUCT,
2830 + decls = ALLOC(decl_list);
2831 + decls->decl = dec;
2833 + if (streq(dec.type, "void"))
2835 + tailp = &decls->next;
2837 + /* multiple arguments are only allowed in newstyle */
2838 + if( !newstyle && num_args > 1 ) {
2839 + error("only one argument is allowed" );
2841 + if (isvoid && num_args > 1) {
2842 + error("illegal use of void in program definition");
2845 + scan(TOK_RPAREN, &tok);
2846 + scan(TOK_EQUAL, &tok);
2848 + scan(TOK_SEMICOLON, &tok);
2849 + plist->proc_num = tok.str;
2850 + plist->arg_num = num_args;
2852 + ptailp = &plist->next;
2854 + } while (tok.kind != TOK_RBRACE);
2857 + vtailp = &vlist->next;
2858 + scan(TOK_RBRACE, &tok);
2859 + scan(TOK_EQUAL, &tok);
2861 + vlist->vers_num = tok.str;
2862 + /* make the argument structure name for each arg*/
2863 + for(plist = vlist->procs; plist != NULL;
2864 + plist = plist->next) {
2865 + plist->args.argname = make_argname(plist->proc_name,
2867 + /* free the memory ??*/
2869 + scan(TOK_SEMICOLON, &tok);
2870 + scan2(TOK_VERSION, TOK_RBRACE, &tok);
2871 + } while (tok.kind == TOK_VERSION);
2872 + scan(TOK_EQUAL, &tok);
2874 + defp->def.pr.prog_num = tok.str;
2880 +def_enum(definition *defp)
2883 + enumval_list *elist;
2884 + enumval_list **tailp;
2886 + defp->def_kind = DEF_ENUM;
2887 + scan(TOK_IDENT, &tok);
2888 + defp->def_name = tok.str;
2889 + scan(TOK_LBRACE, &tok);
2890 + tailp = &defp->def.en.vals;
2892 + scan(TOK_IDENT, &tok);
2893 + elist = ALLOC(enumval_list);
2894 + elist->name = tok.str;
2895 + elist->assignment = NULL;
2896 + scan3(TOK_COMMA, TOK_RBRACE, TOK_EQUAL, &tok);
2897 + if (tok.kind == TOK_EQUAL) {
2899 + elist->assignment = tok.str;
2900 + scan2(TOK_COMMA, TOK_RBRACE, &tok);
2903 + tailp = &elist->next;
2904 + } while (tok.kind != TOK_RBRACE);
2909 +def_const(definition *defp)
2913 + defp->def_kind = DEF_CONST;
2914 + scan(TOK_IDENT, &tok);
2915 + defp->def_name = tok.str;
2916 + scan(TOK_EQUAL, &tok);
2917 + scan2(TOK_IDENT, TOK_STRCONST, &tok);
2918 + defp->def.co = tok.str;
2922 +def_union(definition *defp)
2927 + case_list **tailp;
2929 + defp->def_kind = DEF_UNION;
2930 + scan(TOK_IDENT, &tok);
2931 + defp->def_name = tok.str;
2932 + scan(TOK_SWITCH, &tok);
2933 + scan(TOK_LPAREN, &tok);
2934 + get_declaration(&dec, DEF_UNION);
2935 + defp->def.un.enum_decl = dec;
2936 + tailp = &defp->def.un.cases;
2937 + scan(TOK_RPAREN, &tok);
2938 + scan(TOK_LBRACE, &tok);
2939 + scan(TOK_CASE, &tok);
2940 + while (tok.kind == TOK_CASE) {
2941 + scan2(TOK_IDENT, TOK_CHARCONST, &tok);
2942 + cases = ALLOC(case_list);
2943 + cases->case_name = tok.str;
2944 + scan(TOK_COLON, &tok);
2945 + /* now peek at next token */
2946 + if(peekscan(TOK_CASE,&tok))
2951 + scan2(TOK_IDENT, TOK_CHARCONST, &tok);
2952 + cases->contflag=1; /* continued case statement */
2954 + tailp = &cases->next;
2955 + cases = ALLOC(case_list);
2956 + cases->case_name = tok.str;
2957 + scan(TOK_COLON, &tok);
2959 + }while(peekscan(TOK_CASE,&tok));
2962 + get_declaration(&dec, DEF_UNION);
2963 + cases->case_decl = dec;
2964 + cases->contflag=0; /* no continued case statement */
2966 + tailp = &cases->next;
2967 + scan(TOK_SEMICOLON, &tok);
2969 + scan3(TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok);
2972 + if (tok.kind == TOK_DEFAULT) {
2973 + scan(TOK_COLON, &tok);
2974 + get_declaration(&dec, DEF_UNION);
2975 + defp->def.un.default_decl = ALLOC(declaration);
2976 + *defp->def.un.default_decl = dec;
2977 + scan(TOK_SEMICOLON, &tok);
2978 + scan(TOK_RBRACE, &tok);
2980 + defp->def.un.default_decl = NULL;
2984 +static char* reserved_words[] =
3001 +static char* reserved_types[] =
3008 +/* check that the given name is not one that would eventually result in
3009 + xdr routines that would conflict with internal XDR routines. */
3011 +check_type_name(char *name, int new_type)
3016 + for( i = 0; reserved_words[i] != NULL; i++ ) {
3017 + if( strcmp( name, reserved_words[i] ) == 0 ) {
3019 + "illegal (reserved) name :\'%s\' in type definition", name );
3024 + for( i = 0; reserved_types[i] != NULL; i++ ) {
3025 + if( strcmp( name, reserved_types[i] ) == 0 ) {
3027 + "illegal (reserved) name :\'%s\' in type definition", name );
3035 +def_typedef(definition *defp)
3039 + defp->def_kind = DEF_TYPEDEF;
3040 + get_declaration(&dec, DEF_TYPEDEF);
3041 + defp->def_name = dec.name;
3042 + check_type_name( dec.name, 1 );
3043 + defp->def.ty.old_prefix = dec.prefix;
3044 + defp->def.ty.old_type = dec.type;
3045 + defp->def.ty.rel = dec.rel;
3046 + defp->def.ty.array_max = dec.array_max;
3050 +get_declaration(declaration *dec, defkind dkind)
3054 + get_type(&dec->prefix, &dec->type, dkind);
3055 + dec->rel = REL_ALIAS;
3056 + if (streq(dec->type, "void")) {
3060 + check_type_name( dec->type, 0 );
3062 + scan2(TOK_STAR, TOK_IDENT, &tok);
3063 + if (tok.kind == TOK_STAR) {
3064 + dec->rel = REL_POINTER;
3065 + scan(TOK_IDENT, &tok);
3067 + dec->name = tok.str;
3068 + if (peekscan(TOK_LBRACKET, &tok)) {
3069 + if (dec->rel == REL_POINTER) {
3070 + error("no array-of-pointer declarations -- use typedef");
3072 + dec->rel = REL_VECTOR;
3074 + dec->array_max = tok.str;
3075 + scan(TOK_RBRACKET, &tok);
3076 + } else if (peekscan(TOK_LANGLE, &tok)) {
3077 + if (dec->rel == REL_POINTER) {
3078 + error("no array-of-pointer declarations -- use typedef");
3080 + dec->rel = REL_ARRAY;
3081 + if (peekscan(TOK_RANGLE, &tok)) {
3082 + dec->array_max = "~0"; /* unspecified size, use max */
3085 + dec->array_max = tok.str;
3086 + scan(TOK_RANGLE, &tok);
3089 + if (streq(dec->type, "opaque")) {
3090 + if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR) {
3091 + error("array declaration expected");
3093 + } else if (streq(dec->type, "string")) {
3094 + if (dec->rel != REL_ARRAY) {
3095 + error("variable-length array declaration expected");
3102 +get_prog_declaration(declaration *dec, defkind dkind, int num)
3105 + char name[10]; /* argument name */
3107 + if (dkind == DEF_PROGRAM) {
3109 + if (tok.kind == TOK_RPAREN) { /* no arguments */
3110 + dec->rel = REL_ALIAS;
3111 + dec->type = "void";
3112 + dec->prefix = NULL;
3117 + get_type(&dec->prefix, &dec->type, dkind);
3118 + dec->rel = REL_ALIAS;
3119 + if (peekscan(TOK_IDENT, &tok)) /* optional name of argument */
3120 + strcpy(name, tok.str);
3122 + sprintf(name, "%s%d", ARGNAME, num); /* default name of argument */
3124 + dec->name = (char *) strdup(name);
3126 + if (streq(dec->type, "void")) {
3130 + if (streq(dec->type, "opaque")) {
3131 + error("opaque -- illegal argument type");
3133 + if (peekscan(TOK_STAR, &tok)) {
3134 + if (streq(dec->type, "string")) {
3135 + error("pointer to string not allowed in program arguments\n");
3137 + dec->rel = REL_POINTER;
3138 + if (peekscan(TOK_IDENT, &tok)) /* optional name of argument */
3139 + dec->name = strdup(tok.str);
3141 + if (peekscan(TOK_LANGLE, &tok)) {
3142 + if (!streq(dec->type, "string")) {
3143 + error("arrays cannot be declared as arguments to procedures -- use typedef");
3145 + dec->rel = REL_ARRAY;
3146 + if (peekscan(TOK_RANGLE, &tok)) {
3147 + dec->array_max = "~0";/* unspecified size, use max */
3150 + dec->array_max = tok.str;
3151 + scan(TOK_RANGLE, &tok);
3154 + if (streq(dec->type, "string")) {
3155 + if (dec->rel != REL_ARRAY) { /* .x specifies just string as
3156 + * type of argument
3157 + * - make it string<>
3159 + dec->rel = REL_ARRAY;
3160 + dec->array_max = "~0";/* unspecified size, use max */
3168 +get_type(char **prefixp, char **typep, defkind dkind)
3174 + switch (tok.kind) {
3181 + *prefixp = tok.str;
3182 + scan(TOK_IDENT, &tok);
3185 + case TOK_UNSIGNED:
3186 + unsigned_dec(typep);
3190 + (void) peekscan(TOK_INT, &tok);
3193 + *typep = "int32_t";
3194 + (void) peekscan(TOK_INT, &tok);
3197 + if (dkind != DEF_UNION && dkind != DEF_PROGRAM) {
3198 + error("voids allowed only inside union and program definitions with one argument");
3212 + error("expected type specifier");
3217 +unsigned_dec(char **typep)
3222 + switch (tok.kind) {
3225 + *typep = "u_char";
3229 + *typep = "u_short";
3230 + (void) peekscan(TOK_INT, &tok);
3234 + *typep = "u_int32_";
3235 + (void) peekscan(TOK_INT, &tok);
3246 diff --git a/rpcgen/rpc_parse.h b/rpcgen/rpc_parse.h
3247 new file mode 100644
3248 index 0000000..2afae10
3250 +++ b/rpcgen/rpc_parse.h
3253 + * Copyright (c) 2009, Sun Microsystems, Inc.
3254 + * All rights reserved.
3256 + * Redistribution and use in source and binary forms, with or without
3257 + * modification, are permitted provided that the following conditions are met:
3258 + * - Redistributions of source code must retain the above copyright notice,
3259 + * this list of conditions and the following disclaimer.
3260 + * - Redistributions in binary form must reproduce the above copyright notice,
3261 + * this list of conditions and the following disclaimer in the documentation
3262 + * and/or other materials provided with the distribution.
3263 + * - Neither the name of Sun Microsystems, Inc. nor the names of its
3264 + * contributors may be used to endorse or promote products derived
3265 + * from this software without specific prior written permission.
3267 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
3268 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
3269 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
3270 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
3271 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
3272 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
3273 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
3274 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
3275 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
3276 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3277 + * POSSIBILITY OF SUCH DAMAGE.
3280 +/* @(#)rpc_parse.h 1.3 90/08/29 (C) 1987 SMI */
3283 + * rpc_parse.h, Definitions for the RPCL parser
3294 +typedef enum defkind defkind;
3296 +typedef char *const_def;
3299 + REL_VECTOR, /* fixed length array */
3300 + REL_ARRAY, /* variable length array */
3301 + REL_POINTER, /* pointer */
3302 + REL_ALIAS, /* simple */
3304 +typedef enum relation relation;
3306 +struct typedef_def {
3312 +typedef struct typedef_def typedef_def;
3314 +struct enumval_list {
3317 + struct enumval_list *next;
3319 +typedef struct enumval_list enumval_list;
3322 + enumval_list *vals;
3324 +typedef struct enum_def enum_def;
3326 +struct declaration {
3333 +typedef struct declaration declaration;
3337 + struct decl_list *next;
3339 +typedef struct decl_list decl_list;
3341 +struct struct_def {
3344 +typedef struct struct_def struct_def;
3349 + declaration case_decl;
3350 + struct case_list *next;
3352 +typedef struct case_list case_list;
3355 + declaration enum_decl;
3357 + declaration *default_decl;
3359 +typedef struct union_def union_def;
3362 + char *argname; /* name of struct for arg*/
3366 +typedef struct arg_list arg_list;
3375 + struct proc_list *next;
3377 +typedef struct proc_list proc_list;
3379 +struct version_list {
3383 + struct version_list *next;
3385 +typedef struct version_list version_list;
3387 +struct program_def {
3389 + version_list *versions;
3391 +typedef struct program_def program_def;
3393 +struct definition {
3405 +typedef struct definition definition;
3407 +definition *get_definition();
3414 + struct bas_type *next;
3417 +typedef struct bas_type bas_type;
3418 diff --git a/rpcgen/rpc_sample.c b/rpcgen/rpc_sample.c
3419 new file mode 100644
3420 index 0000000..2b5c81b
3422 +++ b/rpcgen/rpc_sample.c
3425 + * Copyright (c) 2009, Sun Microsystems, Inc.
3426 + * All rights reserved.
3428 + * Redistribution and use in source and binary forms, with or without
3429 + * modification, are permitted provided that the following conditions are met:
3430 + * - Redistributions of source code must retain the above copyright notice,
3431 + * this list of conditions and the following disclaimer.
3432 + * - Redistributions in binary form must reproduce the above copyright notice,
3433 + * this list of conditions and the following disclaimer in the documentation
3434 + * and/or other materials provided with the distribution.
3435 + * - Neither the name of Sun Microsystems, Inc. nor the names of its
3436 + * contributors may be used to endorse or promote products derived
3437 + * from this software without specific prior written permission.
3439 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
3440 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
3441 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
3442 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
3443 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
3444 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
3445 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
3446 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
3447 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
3448 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3449 + * POSSIBILITY OF SUCH DAMAGE.
3453 +static char sccsid[] = "@(#)rpc_sample.c 1.1 90/08/30 (C) 1987 SMI";
3458 + * rpc_sample.c, Sample client-server code outputter for the RPC protocol compiler
3462 +#include <string.h>
3463 +#include "rpc_parse.h"
3464 +#include "rpc_util.h"
3467 +static char RQSTP[] = "rqstp";
3469 +static void write_sample_client(char *program_name, version_list *vp);
3470 +static void write_sample_server(definition * def);
3471 +static void return_type(proc_list *plist);
3474 +write_sample_svc(definition *def)
3476 + if (def->def_kind != DEF_PROGRAM)
3478 + write_sample_server(def);
3483 +write_sample_clnt(definition *def)
3488 + if (def->def_kind != DEF_PROGRAM)
3490 + /* generate sample code for each version */
3491 + for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
3492 + write_sample_client(def->def_name, vp);
3500 +write_sample_client(char *program_name, version_list *vp)
3506 + f_print(fout, "\n\nvoid\n");
3507 + pvname(program_name, vp->vers_num);
3509 + f_print(fout, "( char* host )\n{\n");
3511 + f_print(fout, "(host)\nchar *host;\n{\n");
3512 + f_print(fout, "\tCLIENT *clnt;\n");
3515 + for (proc = vp->procs; proc != NULL; proc = proc->next) {
3516 + f_print(fout, "\t");
3517 + ptype(proc->res_prefix, proc->res_type, 1);
3518 + f_print(fout, " *result_%d;\n", ++i);
3519 + /* print out declarations for arguments */
3520 + if (proc->arg_num < 2 && !newstyle) {
3521 + f_print(fout, "\t");
3522 + if (!streq(proc->args.decls->decl.type, "void"))
3523 + ptype(proc->args.decls->decl.prefix, proc->args.decls->decl.type, 1);
3525 + f_print(fout, "char* "); /* cannot have "void" type */
3526 + f_print(fout, " ");
3527 + pvname(proc->proc_name, vp->vers_num);
3528 + f_print(fout, "_arg;\n");
3529 + } else if (!streq(proc->args.decls->decl.type, "void")) {
3530 + for (l = proc->args.decls; l != NULL; l = l->next) {
3531 + f_print(fout, "\t");
3532 + ptype(l->decl.prefix, l->decl.type, 1);
3533 + f_print(fout, " ");
3534 + pvname(proc->proc_name, vp->vers_num);
3535 + f_print(fout, "_%s;\n", l->decl.name);
3536 + /* pdeclaration(proc->args.argname, &l->decl, 1, ";\n" );*/
3541 + /* generate creation of client handle */
3542 + f_print(fout, "\tclnt = clnt_create(host, %s, %s, \"%s\");\n",
3543 + program_name, vp->vers_name, tirpcflag ? "netpath" : "udp");
3544 + f_print(fout, "\tif (clnt == NULL) {\n");
3545 + f_print(fout, "\t\tclnt_pcreateerror(host);\n");
3546 + f_print(fout, "\t\texit(1);\n\t}\n");
3548 + /* generate calls to procedures */
3550 + for (proc = vp->procs; proc != NULL; proc = proc->next) {
3551 + f_print(fout, "\tresult_%d = ", ++i);
3552 + pvname(proc->proc_name, vp->vers_num);
3553 + if (proc->arg_num < 2 && !newstyle) {
3554 + f_print(fout, "(");
3555 + if (streq(proc->args.decls->decl.type, "void")) /* cast to void* */
3556 + f_print(fout, "(void*)");
3557 + f_print(fout, "&");
3558 + pvname(proc->proc_name, vp->vers_num);
3559 + f_print(fout, "_arg, clnt);\n");
3560 + } else if (streq(proc->args.decls->decl.type, "void")) {
3561 + f_print(fout, "(clnt);\n");
3563 + f_print(fout, "(");
3564 + for (l = proc->args.decls; l != NULL; l = l->next) {
3565 + pvname(proc->proc_name, vp->vers_num);
3566 + f_print(fout, "_%s, ", l->decl.name);
3568 + f_print(fout, "clnt);\n");
3570 + f_print(fout, "\tif (result_%d == NULL) {\n", i);
3571 + f_print(fout, "\t\tclnt_perror(clnt, \"call failed:\");\n");
3572 + f_print(fout, "\t}\n");
3575 + f_print(fout, "\tclnt_destroy( clnt );\n");
3576 + f_print(fout, "}\n");
3580 +write_sample_server(definition * def)
3585 + for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
3586 + for (proc = vp->procs; proc != NULL; proc = proc->next) {
3587 + f_print(fout, "\n");
3589 + f_print( fout, "extern \"C\"{\n");
3591 + return_type(proc);
3592 + f_print(fout, "* \n");
3594 + pvname_svc(proc->proc_name, vp->vers_num);
3596 + pvname(proc->proc_name, vp->vers_num);
3597 + printarglist(proc, RQSTP, "struct svc_req *");
3599 + f_print(fout, "{\n");
3600 + f_print(fout, "\n\tstatic ");
3601 + if (!streq(proc->res_type, "void"))
3602 + return_type(proc);
3604 + f_print(fout, "char*"); /* cannot have void type */
3605 + /* f_print(fout, " result;\n", proc->res_type); */
3606 + f_print(fout, " result;\n");
3608 + "\n\t/*\n\t * insert server code here\n\t */\n\n");
3609 + if (!streq(proc->res_type, "void"))
3610 + f_print(fout, "\treturn(&result);\n}\n");
3611 + else /* cast back to void * */
3612 + f_print(fout, "\treturn((void*) &result);\n}\n");
3614 + f_print( fout, "};\n");
3624 +return_type(proc_list *plist)
3626 + ptype( plist->res_prefix, plist->res_type, 1 );
3630 +add_sample_msg(void)
3632 + f_print(fout, "/*\n");
3633 + f_print(fout, " * This is sample code generated by rpcgen.\n");
3634 + f_print(fout, " * These are only templates and you can use them\n");
3635 + f_print(fout, " * as a guideline for developing your own functions.\n");
3636 + f_print(fout, " */\n\n");
3640 +write_sample_clnt_main(void)
3646 + f_print(fout, "\n\n" );
3648 + f_print(fout,"main( int argc, char* argv[] )\n{\n" );
3650 + f_print(fout, "main(argc, argv)\nint argc;\nchar *argv[];\n{\n" );
3652 + f_print(fout, "\tchar *host;");
3653 + f_print(fout, "\n\n\tif(argc < 2) {");
3654 + f_print(fout, "\n\t\tprintf(\"usage: %%s server_host\\n\", argv[0]);\n" );
3655 + f_print(fout, "\t\texit(1);\n\t}");
3656 + f_print(fout, "\n\thost = argv[1];\n");
3658 + for (l = defined; l != NULL; l = l->next) {
3660 + if (def->def_kind != DEF_PROGRAM) {
3663 + for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
3664 + f_print( fout, "\t" );
3665 + pvname(def->def_name, vp->vers_num);
3666 + f_print( fout, "( host );\n" );
3669 + f_print(fout, "}\n");
3671 diff --git a/rpcgen/rpc_scan.c b/rpcgen/rpc_scan.c
3672 new file mode 100644
3673 index 0000000..f58fa9f
3675 +++ b/rpcgen/rpc_scan.c
3678 + * Copyright (c) 2009, Sun Microsystems, Inc.
3679 + * All rights reserved.
3681 + * Redistribution and use in source and binary forms, with or without
3682 + * modification, are permitted provided that the following conditions are met:
3683 + * - Redistributions of source code must retain the above copyright notice,
3684 + * this list of conditions and the following disclaimer.
3685 + * - Redistributions in binary form must reproduce the above copyright notice,
3686 + * this list of conditions and the following disclaimer in the documentation
3687 + * and/or other materials provided with the distribution.
3688 + * - Neither the name of Sun Microsystems, Inc. nor the names of its
3689 + * contributors may be used to endorse or promote products derived
3690 + * from this software without specific prior written permission.
3692 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
3693 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
3694 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
3695 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
3696 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
3697 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
3698 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
3699 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
3700 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
3701 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3702 + * POSSIBILITY OF SUCH DAMAGE.
3706 +static char sccsid[] = "@(#)rpc_scan.c 1.11 89/02/22 (C) 1987 SMI";
3710 + * rpc_scan.c, Scanner for the RPC protocol compiler
3711 + * Copyright (C) 1987, Sun Microsystems, Inc.
3715 +#include <string.h>
3716 +#include "rpc_scan.h"
3717 +#include "rpc_parse.h"
3718 +#include "rpc_util.h"
3720 +static void unget_token(token *tokp);
3721 +static void findstrconst(char **str, char **val);
3722 +static void findchrconst(char **str, char **val);
3723 +static void findconst(char **str, char **val);
3724 +static void findkind(char **mark, token *tokp);
3725 +static int cppline(char *line);
3726 +static int directive(char *line);
3727 +static void printdirective(char *line);
3728 +static void docppline(char *line, int *lineno, char **fname);
3730 +#define startcomment(where) (where[0] == '/' && where[1] == '*')
3731 +#define endcomment(where) (where[-1] == '*' && where[0] == '/')
3733 +static int pushed = 0; /* is a token pushed */
3734 +static token lasttok; /* last token, if pushed */
3737 + * scan expecting 1 given token
3740 +scan(tok_kind expect, token *tokp)
3743 + if (tokp->kind != expect) {
3744 + expected1(expect);
3749 + * scan expecting any of the 2 given tokens
3752 +scan2(tok_kind expect1, tok_kind expect2, token *tokp)
3755 + if (tokp->kind != expect1 && tokp->kind != expect2) {
3756 + expected2(expect1, expect2);
3761 + * scan expecting any of the 3 given token
3764 +scan3(tok_kind expect1, tok_kind expect2, tok_kind expect3, token *tokp)
3767 + if (tokp->kind != expect1 && tokp->kind != expect2
3768 + && tokp->kind != expect3) {
3769 + expected3(expect1, expect2, expect3);
3774 + * scan expecting a constant, possibly symbolic
3777 +scan_num(token *tokp)
3780 + switch (tokp->kind) {
3784 + error("constant or identifier expected");
3789 + * Peek at the next token
3795 + unget_token(tokp);
3799 + * Peek at the next token and scan it if it matches what you expect
3802 +peekscan(tok_kind expect, token *tokp)
3805 + if (tokp->kind == expect) {
3813 + * Get the next token, printing out any directive that are encountered.
3816 +get_token(token *tokp)
3827 + if (*where == 0) {
3829 + if (!fgets(curline, MAXLINESIZE, fin)) {
3830 + tokp->kind = TOK_EOF;
3837 + } else if (cppline(curline)) {
3838 + docppline(curline, &linenum,
3840 + } else if (directive(curline)) {
3841 + printdirective(curline);
3847 + } else if (isspace(*where)) {
3848 + while (isspace(*where)) {
3849 + where++; /* eat */
3851 + } else if (commenting) {
3852 + for (where++; *where; where++) {
3853 + if (endcomment(where)) {
3859 + } else if (startcomment(where)) {
3868 + * 'where' is not whitespace, comment or directive Must be a token!
3872 + tokp->kind = TOK_COLON;
3876 + tokp->kind = TOK_SEMICOLON;
3880 + tokp->kind = TOK_COMMA;
3884 + tokp->kind = TOK_EQUAL;
3888 + tokp->kind = TOK_STAR;
3892 + tokp->kind = TOK_LBRACKET;
3896 + tokp->kind = TOK_RBRACKET;
3900 + tokp->kind = TOK_LBRACE;
3904 + tokp->kind = TOK_RBRACE;
3908 + tokp->kind = TOK_LPAREN;
3912 + tokp->kind = TOK_RPAREN;
3916 + tokp->kind = TOK_LANGLE;
3920 + tokp->kind = TOK_RANGLE;
3925 + tokp->kind = TOK_STRCONST;
3926 + findstrconst(&where, &tokp->str);
3929 + tokp->kind = TOK_CHARCONST;
3930 + findchrconst(&where, &tokp->str);
3944 + tokp->kind = TOK_IDENT;
3945 + findconst(&where, &tokp->str);
3949 + if (!(isalpha(*where) || *where == '_')) {
3953 + s_print(buf, "illegal character in file: ");
3954 + p = buf + strlen(buf);
3955 + if (isprint(*where)) {
3956 + s_print(p, "%c", *where);
3958 + s_print(p, "%d", *where);
3962 + findkind(&where, tokp);
3968 +unget_token(token *tokp)
3975 +findstrconst(char **str, char **val)
3983 + } while (*p && *p != '"');
3985 + error("unterminated string constant");
3989 + *val = alloc(size + 1);
3990 + (void) strncpy(*val, *str, size);
3996 +findchrconst(char **str, char **val)
4004 + } while (*p && *p != '\'');
4006 + error("unterminated string constant");
4011 + error("empty char string");
4013 + *val = alloc(size + 1);
4014 + (void) strncpy(*val, *str, size);
4020 +findconst(char **str, char **val)
4026 + if (*p == '0' && *(p + 1) == 'x') {
4030 + } while (isxdigit(*p));
4034 + } while (isdigit(*p));
4037 + *val = alloc(size + 1);
4038 + (void) strncpy(*val, *str, size);
4043 +static token symbols[] = {
4044 + {TOK_CONST, "const"},
4045 + {TOK_UNION, "union"},
4046 + {TOK_SWITCH, "switch"},
4047 + {TOK_CASE, "case"},
4048 + {TOK_DEFAULT, "default"},
4049 + {TOK_STRUCT, "struct"},
4050 + {TOK_TYPEDEF, "typedef"},
4051 + {TOK_ENUM, "enum"},
4052 + {TOK_OPAQUE, "opaque"},
4053 + {TOK_BOOL, "bool"},
4054 + {TOK_VOID, "void"},
4055 + {TOK_CHAR, "char"},
4057 + {TOK_UNSIGNED, "unsigned"},
4058 + {TOK_SHORT, "short"},
4059 + {TOK_INT32, "int32"},
4060 + {TOK_FLOAT, "float"},
4061 + {TOK_DOUBLE, "double"},
4062 + {TOK_STRING, "string"},
4063 + {TOK_PROGRAM, "program"},
4064 + {TOK_VERSION, "version"},
4065 + {TOK_EOF, "??????"},
4069 +findkind(char **mark, token *tokp)
4076 + for (s = symbols; s->kind != TOK_EOF; s++) {
4077 + len = strlen(s->str);
4078 + if (strncmp(str, s->str, len) == 0) {
4079 + if (!isalnum(str[len]) && str[len] != '_') {
4080 + tokp->kind = s->kind;
4081 + tokp->str = s->str;
4082 + *mark = str + len;
4087 + tokp->kind = TOK_IDENT;
4088 + for (len = 0; isalnum(str[len]) || str[len] == '_'; len++);
4089 + tokp->str = alloc(len + 1);
4090 + (void) strncpy(tokp->str, str, len);
4091 + tokp->str[len] = 0;
4092 + *mark = str + len;
4096 +cppline(char *line)
4098 + return (line == curline && *line == '#');
4102 +directive(char *line)
4104 + return (line == curline && *line == '%');
4108 +printdirective(char *line)
4110 + f_print(fout, "%s", line + 1);
4114 +docppline(char *line, int *lineno, char **fname)
4121 + while (isspace(*line)) {
4125 + while (isdigit(*line)) {
4128 + while (isspace(*line)) {
4131 + if (*line != '"') {
4132 + error("preprocessor error");
4135 + p = file = alloc(strlen(line) + 1);
4136 + while (*line && *line != '"') {
4140 + error("preprocessor error");
4149 + *lineno = num - 1;
4151 diff --git a/rpcgen/rpc_scan.h b/rpcgen/rpc_scan.h
4152 new file mode 100644
4153 index 0000000..16f688c
4155 +++ b/rpcgen/rpc_scan.h
4158 + * Copyright (c) 2009, Sun Microsystems, Inc.
4159 + * All rights reserved.
4161 + * Redistribution and use in source and binary forms, with or without
4162 + * modification, are permitted provided that the following conditions are met:
4163 + * - Redistributions of source code must retain the above copyright notice,
4164 + * this list of conditions and the following disclaimer.
4165 + * - Redistributions in binary form must reproduce the above copyright notice,
4166 + * this list of conditions and the following disclaimer in the documentation
4167 + * and/or other materials provided with the distribution.
4168 + * - Neither the name of Sun Microsystems, Inc. nor the names of its
4169 + * contributors may be used to endorse or promote products derived
4170 + * from this software without specific prior written permission.
4172 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
4173 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4174 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4175 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
4176 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
4177 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
4178 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
4179 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
4180 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
4181 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
4182 + * POSSIBILITY OF SUCH DAMAGE.
4185 +/* @(#)rpc_scan.h 1.3 90/08/29 (C) 1987 SMI */
4188 + * rpc_scan.h, Definitions for the RPCL scanner
4234 +typedef enum tok_kind tok_kind;
4243 +typedef struct token token;
4247 + * routine interface
4256 +void expected1(tok_kind);
4257 +void expected2(tok_kind, tok_kind);
4258 +void expected3(tok_kind, tok_kind, tok_kind);
4260 diff --git a/rpcgen/rpc_svcout.c b/rpcgen/rpc_svcout.c
4261 new file mode 100644
4262 index 0000000..284a529
4264 +++ b/rpcgen/rpc_svcout.c
4267 + * Copyright (c) 2009, Sun Microsystems, Inc.
4268 + * All rights reserved.
4270 + * Redistribution and use in source and binary forms, with or without
4271 + * modification, are permitted provided that the following conditions are met:
4272 + * - Redistributions of source code must retain the above copyright notice,
4273 + * this list of conditions and the following disclaimer.
4274 + * - Redistributions in binary form must reproduce the above copyright notice,
4275 + * this list of conditions and the following disclaimer in the documentation
4276 + * and/or other materials provided with the distribution.
4277 + * - Neither the name of Sun Microsystems, Inc. nor the names of its
4278 + * contributors may be used to endorse or promote products derived
4279 + * from this software without specific prior written permission.
4281 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
4282 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4283 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4284 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
4285 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
4286 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
4287 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
4288 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
4289 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
4290 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
4291 + * POSSIBILITY OF SUCH DAMAGE.
4295 + static char sccsid[] = "@(#)rpc_svcout.c 1.29 89/03/30 (C) 1987 SMI";
4299 + * rpc_svcout.c, Server-skeleton outputter for the RPC protocol compiler
4302 +#include <string.h>
4303 +#include "rpc_parse.h"
4304 +#include "rpc_util.h"
4305 +#include "rpc_output.h"
4307 +static void write_real_program(definition *def);
4308 +static void write_program(definition *def, char *storage);
4309 +static void printerr(char *err, char *transp);
4310 +static void printif(char *proc, char *transp, char *prefix, char *arg);
4311 +static void write_inetmost(char *infile);
4312 +static void print_return(char *space);
4313 +static void print_pmapunset(char *space);
4314 +static void print_err_message(char *space);
4315 +static void write_timeout_func(void);
4316 +static void write_pm_most(char *infile, int netflag);
4317 +static void write_rpc_svc_fg(char *infile, char *sp);
4318 +static void open_log_file(char *infile, char *sp);
4320 +static char RQSTP[] = "rqstp";
4321 +static char TRANSP[] = "transp";
4322 +static char ARG[] = "argument";
4323 +static char RESULT[] = "result";
4324 +static char ROUTINE[] = "local";
4326 +char _errbuf[256]; /* For all messages */
4329 +p_xdrfunc(char *rname, char *typename)
4332 + f_print(fout, "\t\txdr_%s = (xdrproc_t) xdr_%s;\n", rname,
4333 + stringfix(typename));
4335 + f_print(fout, "\t\txdr_%s = xdr_%s;\n", rname, stringfix(typename));
4339 +internal_proctype(proc_list *plist)
4341 + f_print(fout, "static ");
4342 + ptype( plist->res_prefix, plist->res_type, 1 );
4343 + f_print( fout, "*" );
4348 + * write most of the service, that is, everything but the registrations.
4351 +write_most(char *infile, int netflag, int nomain)
4353 + if (inetdflag || pmflag) {
4355 + var_type = (nomain? "extern" : "static");
4356 + f_print(fout, "%s int _rpcpmstart;", var_type );
4357 + f_print(fout, "\t\t/* Started by a port monitor ? */\n");
4358 + f_print(fout, "%s int _rpcfdtype;", var_type );
4359 + f_print(fout, "\t\t/* Whether Stream or Datagram ? */\n");
4361 + f_print(fout, "%s int _rpcsvcdirty;", var_type );
4362 + f_print(fout, "\t/* Still serving ? */\n");
4364 + write_svc_aux( nomain );
4366 + /* write out dispatcher and stubs */
4367 + write_programs( nomain? (char *)NULL : "static" );
4372 + f_print(fout, "\nmain()\n");
4373 + f_print(fout, "{\n");
4375 + write_inetmost(infile); /* Includes call to write_rpc_svc_fg() */
4379 + f_print(fout, "\tregister SVCXPRT *%s;\n", TRANSP);
4380 + f_print(fout, "\tstruct netconfig *nconf = NULL;\n");
4382 + f_print(fout, "\tpid_t pid;\n");
4383 + f_print(fout, "\tint i;\n");
4384 + f_print(fout, "\tchar mname[FMNAMESZ + 1];\n\n");
4385 + write_pm_most(infile, netflag);
4386 + f_print(fout, "\telse {\n");
4387 + write_rpc_svc_fg(infile, "\t\t");
4388 + f_print(fout, "\t}\n");
4390 + f_print(fout, "\tregister SVCXPRT *%s;\n", TRANSP);
4391 + f_print(fout, "\n");
4392 + print_pmapunset("\t");
4396 + if (logflag && !inetdflag) {
4397 + open_log_file(infile, "\t");
4402 + * write a registration for the given transport
4405 +write_netid_register(char *transp)
4414 + f_print(fout, "\n");
4415 + f_print(fout, "%s\tnconf = getnetconfigent(\"%s\");\n", sp, transp);
4416 + f_print(fout, "%s\tif (nconf == NULL) {\n", sp);
4417 + (void) sprintf(_errbuf, "cannot find %s netid.", transp);
4418 + sprintf(tmpbuf, "%s\t\t", sp);
4419 + print_err_message(tmpbuf);
4420 + f_print(fout, "%s\t\texit(1);\n", sp);
4421 + f_print(fout, "%s\t}\n", sp);
4422 + f_print(fout, "%s\t%s = svc_tli_create(RPC_ANYFD, nconf, 0, 0, 0);\n",
4424 + f_print(fout, "%s\tif (%s == NULL) {\n", sp, TRANSP);
4425 + (void) sprintf(_errbuf, "cannot create %s service.", transp);
4426 + print_err_message(tmpbuf);
4427 + f_print(fout, "%s\t\texit(1);\n", sp);
4428 + f_print(fout, "%s\t}\n", sp);
4430 + for (l = defined; l != NULL; l = l->next) {
4431 + def = (definition *) l->val;
4432 + if (def->def_kind != DEF_PROGRAM) {
4435 + for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
4437 + "%s\t(void) rpcb_unset(%s, %s, nconf);\n",
4438 + sp, def->def_name, vp->vers_name);
4440 + "%s\tif (!svc_reg(%s, %s, %s, ",
4441 + sp, TRANSP, def->def_name, vp->vers_name);
4442 + pvname(def->def_name, vp->vers_num);
4443 + f_print(fout, ", nconf)) {\n");
4444 + (void) sprintf(_errbuf, "unable to register (%s, %s, %s).",
4445 + def->def_name, vp->vers_name, transp);
4446 + print_err_message(tmpbuf);
4447 + f_print(fout, "%s\t\texit(1);\n", sp);
4448 + f_print(fout, "%s\t}\n", sp);
4451 + f_print(fout, "%s\tfreenetconfigent(nconf);\n", sp);
4455 + * write a registration for the given transport for TLI
4458 +write_nettype_register(char *transp)
4464 + for (l = defined; l != NULL; l = l->next) {
4465 + def = (definition *) l->val;
4466 + if (def->def_kind != DEF_PROGRAM) {
4469 + for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
4470 + f_print(fout, "\tif (!svc_create(");
4471 + pvname(def->def_name, vp->vers_num);
4472 + f_print(fout, ", %s, %s, \"%s\")) {\n ",
4473 + def->def_name, vp->vers_name, transp);
4474 + (void) sprintf(_errbuf,
4475 + "unable to create (%s, %s) for %s.",
4476 + def->def_name, vp->vers_name, transp);
4477 + print_err_message("\t\t");
4478 + f_print(fout, "\t\texit(1);\n");
4479 + f_print(fout, "\t}\n");
4485 + * write the rest of the service
4490 + f_print(fout, "\n");
4492 + f_print(fout, "\tif (%s == (SVCXPRT *)NULL) {\n", TRANSP);
4493 + (void) sprintf(_errbuf, "could not create a handle");
4494 + print_err_message("\t\t");
4495 + f_print(fout, "\t\texit(1);\n");
4496 + f_print(fout, "\t}\n");
4498 + f_print(fout, "\tif (_rpcpmstart) {\n");
4500 + "\t\t(void) signal(SIGALRM, %s closedown);\n",
4501 + Cflag? "(SIG_PF)" : "(void(*)())" );
4502 + f_print(fout, "\t\t(void) alarm(_RPCSVC_CLOSEDOWN);\n");
4503 + f_print(fout, "\t}\n");
4506 + f_print(fout, "\tsvc_run();\n");
4507 + (void) sprintf(_errbuf, "svc_run returned");
4508 + print_err_message("\t");
4509 + f_print(fout, "\texit(1);\n");
4510 + f_print(fout, "\t/* NOTREACHED */\n");
4511 + f_print(fout, "}\n");
4515 +write_programs(char *storage)
4520 + /* write out stubs for procedure definitions */
4521 + for (l = defined; l != NULL; l = l->next) {
4522 + def = (definition *) l->val;
4523 + if (def->def_kind == DEF_PROGRAM) {
4524 + write_real_program(def);
4528 + /* write out dispatcher for each program */
4529 + for (l = defined; l != NULL; l = l->next) {
4530 + def = (definition *) l->val;
4531 + if (def->def_kind == DEF_PROGRAM) {
4532 + write_program(def, storage);
4539 +/* write out definition of internal function (e.g. _printmsg_1(...))
4540 + which calls server's defintion of actual function (e.g. printmsg_1(...)).
4541 + Unpacks single user argument of printmsg_1 to call-by-value format
4542 + expected by printmsg_1. */
4544 +write_real_program(definition *def)
4550 + if( !newstyle ) return; /* not needed for old style */
4551 + for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
4552 + for (proc = vp->procs; proc != NULL; proc = proc->next) {
4553 + f_print(fout, "\n");
4554 + internal_proctype(proc);
4555 + f_print(fout, "\n_");
4556 + pvname(proc->proc_name, vp->vers_num);
4558 + f_print(fout, "(" );
4560 + if (proc->arg_num > 1)
4561 + f_print(fout, proc->args.argname);
4563 + ptype(proc->args.decls->decl.prefix,
4564 + proc->args.decls->decl.type, 0);
4565 + f_print(fout, " *argp, struct svc_req *%s)\n",
4568 + f_print(fout, "(argp, %s)\n", RQSTP );
4570 + if (proc->arg_num > 1)
4571 + f_print(fout, "\t%s *argp;\n", proc->args.argname);
4573 + f_print(fout, "\t");
4574 + ptype(proc->args.decls->decl.prefix,
4575 + proc->args.decls->decl.type, 0);
4576 + f_print(fout, " *argp;\n");
4578 + f_print(fout, " struct svc_req *%s;\n", RQSTP);
4581 + f_print(fout, "{\n");
4582 + f_print(fout, "\treturn(");
4584 + pvname_svc(proc->proc_name, vp->vers_num);
4586 + pvname(proc->proc_name, vp->vers_num);
4587 + f_print(fout, "(");
4588 + if (proc->arg_num < 2) { /* single argument */
4589 + if (!streq( proc->args.decls->decl.type, "void"))
4590 + f_print(fout, "*argp, "); /* non-void */
4592 + for (l = proc->args.decls; l != NULL; l = l->next)
4593 + f_print(fout, "argp->%s, ", l->decl.name);
4595 + f_print(fout, "%s));\n}\n", RQSTP);
4601 +write_program(definition *def, char *storage)
4607 + for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
4608 + f_print(fout, "\n");
4609 + if (storage != NULL) {
4610 + f_print(fout, "%s ", storage);
4612 + f_print(fout, "void\n");
4613 + pvname(def->def_name, vp->vers_num);
4616 + f_print(fout, "(struct svc_req *%s, ", RQSTP);
4617 + f_print(fout, "register SVCXPRT *%s)\n", TRANSP);
4619 + f_print(fout, "(%s, %s)\n", RQSTP, TRANSP);
4620 + f_print(fout, " struct svc_req *%s;\n", RQSTP);
4621 + f_print(fout, " register SVCXPRT *%s;\n", TRANSP);
4624 + f_print(fout, "{\n");
4627 + f_print(fout, "\tunion {\n");
4628 + for (proc = vp->procs; proc != NULL; proc = proc->next) {
4629 + if (proc->arg_num < 2) { /* single argument */
4630 + if (streq(proc->args.decls->decl.type,
4635 + f_print(fout, "\t\t");
4636 + ptype(proc->args.decls->decl.prefix,
4637 + proc->args.decls->decl.type, 0);
4638 + pvname(proc->proc_name, vp->vers_num);
4639 + f_print(fout, "_arg;\n");
4644 + f_print(fout, "\t\t%s", proc->args.argname);
4645 + f_print(fout, " ");
4646 + pvname(proc->proc_name, vp->vers_num);
4647 + f_print(fout, "_arg;\n");
4651 + f_print(fout, "\t\tint fill;\n");
4653 + f_print(fout, "\t} %s;\n", ARG);
4654 + f_print(fout, "\tchar *%s;\n", RESULT);
4657 + f_print(fout, "\txdrproc_t xdr_%s, xdr_%s;\n", ARG, RESULT);
4659 + "\tchar *(*%s)(char *, struct svc_req *);\n",
4662 + f_print(fout, "\tbool_t (*xdr_%s)(), (*xdr_%s)();\n", ARG, RESULT);
4663 + f_print(fout, "\tchar *(*%s)();\n", ROUTINE);
4666 + f_print(fout, "\n");
4669 + f_print(fout, "\t_rpcsvcdirty = 1;\n");
4670 + f_print(fout, "\tswitch (%s->rq_proc) {\n", RQSTP);
4671 + if (!nullproc(vp->procs)) {
4672 + f_print(fout, "\tcase NULLPROC:\n");
4674 + "\t\t(void) svc_sendreply(%s, (xdrproc_t) xdr_void, (char *)NULL);\n",
4676 + print_return("\t\t");
4677 + f_print(fout, "\n");
4679 + for (proc = vp->procs; proc != NULL; proc = proc->next) {
4680 + f_print(fout, "\tcase %s:\n", proc->proc_name);
4681 + if (proc->arg_num < 2) { /* single argument */
4682 + p_xdrfunc( ARG, proc->args.decls->decl.type);
4684 + p_xdrfunc( ARG, proc->args.argname);
4686 + p_xdrfunc( RESULT, proc->res_type);
4689 + "\t\t%s = (char *(*)(char *, struct svc_req *)) ",
4692 + f_print(fout, "\t\t%s = (char *(*)()) ", ROUTINE);
4694 + if (newstyle) { /* new style: calls internal routine */
4695 + f_print(fout,"_");
4697 + /* Not sure about the following...
4698 + * rpc_hout always generates foobar_1_svc for
4699 + * the service procedure, so why should we use
4700 + * foobar_1 here?! --okir */
4702 + if( Cflag && !newstyle )
4703 + pvname_svc(proc->proc_name, vp->vers_num);
4705 + pvname(proc->proc_name, vp->vers_num);
4707 + pvname_svc(proc->proc_name, vp->vers_num);
4709 + f_print(fout, ";\n");
4710 + f_print(fout, "\t\tbreak;\n\n");
4712 + f_print(fout, "\tdefault:\n");
4713 + printerr("noproc", TRANSP);
4714 + print_return("\t\t");
4715 + f_print(fout, "\t}\n");
4717 + f_print(fout, "\t(void) memset((char *)&%s, 0, sizeof (%s));\n", ARG, ARG);
4719 + printif("getargs", TRANSP, "(caddr_t) &", ARG);
4721 + printif("getargs", TRANSP, "&", ARG);
4722 + printerr("decode", TRANSP);
4723 + print_return("\t\t");
4724 + f_print(fout, "\t}\n");
4727 + f_print(fout, "\t%s = (*%s)((char *)&%s, %s);\n",
4728 + RESULT, ROUTINE, ARG, RQSTP);
4730 + f_print(fout, "\t%s = (*%s)(&%s, %s);\n",
4731 + RESULT, ROUTINE, ARG, RQSTP);
4733 + "\tif (%s != NULL && !svc_sendreply(%s, "
4734 + "(xdrproc_t) xdr_%s, %s)) {\n",
4735 + RESULT, TRANSP, RESULT, RESULT);
4736 + printerr("systemerr", TRANSP);
4737 + f_print(fout, "\t}\n");
4740 + printif("freeargs", TRANSP, "(caddr_t) &", ARG);
4742 + printif("freeargs", TRANSP, "&", ARG);
4743 + (void) sprintf(_errbuf, "unable to free arguments");
4744 + print_err_message("\t\t");
4745 + f_print(fout, "\t\texit(1);\n");
4746 + f_print(fout, "\t}\n");
4747 + print_return("\t");
4748 + f_print(fout, "}\n");
4753 +printerr(char *err, char *transp)
4755 + f_print(fout, "\t\tsvcerr_%s(%s);\n", err, transp);
4759 +printif(char *proc, char *transp, char *prefix, char *arg)
4761 + f_print(fout, "\tif (!svc_%s(%s, (xdrproc_t) xdr_%s, (caddr_t) %s%s)) {\n",
4762 + proc, transp, arg, prefix, arg);
4766 +nullproc(proc_list *proc)
4768 + for (; proc != NULL; proc = proc->next) {
4769 + if (streq(proc->proc_num, "0")) {
4777 +write_inetmost(char *infile)
4779 + f_print(fout, "\tregister SVCXPRT *%s;\n", TRANSP);
4780 + f_print(fout, "\tint sock;\n");
4781 + f_print(fout, "\tint proto;\n");
4782 + f_print(fout, "\tstruct sockaddr_in saddr;\n");
4783 + f_print(fout, "\tint asize = sizeof (saddr);\n");
4784 + f_print(fout, "\n");
4786 + "\tif (getsockname(0, (struct sockaddr *)&saddr, &asize) == 0) {\n");
4787 + f_print(fout, "\t\tint ssize = sizeof (int);\n\n");
4788 + f_print(fout, "\t\tif (saddr.sin_family != AF_INET)\n");
4789 + f_print(fout, "\t\t\texit(1);\n");
4790 + f_print(fout, "\t\tif (getsockopt(0, SOL_SOCKET, SO_TYPE,\n");
4791 + f_print(fout, "\t\t\t\t(char *)&_rpcfdtype, &ssize) == -1)\n");
4792 + f_print(fout, "\t\t\texit(1);\n");
4793 + f_print(fout, "\t\tsock = 0;\n");
4794 + f_print(fout, "\t\t_rpcpmstart = 1;\n");
4795 + f_print(fout, "\t\tproto = 0;\n");
4796 + open_log_file(infile, "\t\t");
4797 + f_print(fout, "\t} else {\n");
4798 + write_rpc_svc_fg(infile, "\t\t");
4799 + f_print(fout, "\t\tsock = RPC_ANYSOCK;\n");
4800 + print_pmapunset("\t\t");
4801 + f_print(fout, "\t}\n");
4805 +print_return(char *space)
4808 + f_print(fout, "%sexit(0);\n", space);
4811 + f_print(fout, "%s_rpcsvcdirty = 0;\n", space);
4812 + f_print(fout, "%sreturn;\n", space);
4817 +print_pmapunset(char *space)
4823 + for (l = defined; l != NULL; l = l->next) {
4824 + def = (definition *) l->val;
4825 + if (def->def_kind == DEF_PROGRAM) {
4826 + for (vp = def->def.pr.versions; vp != NULL;
4828 + f_print(fout, "%s(void) pmap_unset(%s, %s);\n",
4829 + space, def->def_name, vp->vers_name);
4836 +print_err_message(char *space)
4839 + f_print(fout, "%ssyslog(LOG_ERR, \"%s\");\n", space, _errbuf);
4840 + else if (inetdflag || pmflag)
4841 + f_print(fout, "%s_msgout(\"%s\");\n", space, _errbuf);
4843 + f_print(fout, "%sfprintf(stderr, \"%s\");\n", space, _errbuf);
4847 + * Write the server auxiliary function ( _msgout, timeout)
4850 +write_svc_aux(int nomain)
4855 + write_timeout_func();
4859 + * Write the _msgout function
4862 +write_msg_out(void)
4864 + f_print(fout, "\n");
4865 + f_print(fout, "static\n");
4867 + f_print(fout, "void _msgout(msg)\n");
4868 + f_print(fout, "\tchar *msg;\n");
4870 + f_print(fout, "void _msgout(char* msg)\n");
4872 + f_print(fout, "{\n");
4873 + f_print(fout, "#ifdef RPC_SVC_FG\n");
4874 + if (inetdflag || pmflag)
4875 + f_print(fout, "\tif (_rpcpmstart)\n");
4876 + f_print(fout, "\t\tsyslog(LOG_ERR, \"%%s\", msg);\n");
4877 + f_print(fout, "\telse\n");
4878 + f_print(fout, "\t\t(void) fprintf(stderr, \"%%s\\n\", msg);\n");
4879 + f_print(fout, "#else\n");
4880 + f_print(fout, "\tsyslog(LOG_ERR, \"%%s\", msg);\n");
4881 + f_print(fout, "#endif\n");
4882 + f_print(fout, "}\n");
4886 + * Write the timeout function
4889 +write_timeout_func(void)
4893 + f_print(fout, "\n");
4894 + f_print(fout, "static void\n");
4895 + f_print(fout, "closedown()\n");
4896 + f_print(fout, "{\n");
4897 + f_print(fout, "\tif (_rpcsvcdirty == 0) {\n");
4898 + f_print(fout, "\t\tstatic int size;\n");
4899 + f_print(fout, "\t\tint i, openfd;\n");
4900 + if (tirpcflag && pmflag) {
4901 + f_print(fout, "\t\tstruct t_info tinfo;\n\n");
4902 + f_print(fout, "\t\tif (!t_getinfo(0, &tinfo) && (tinfo.servtype == T_CLTS))\n");
4904 + f_print(fout, "\n\t\tif (_rpcfdtype == SOCK_DGRAM)\n");
4906 + f_print(fout, "\t\t\texit(0);\n");
4907 + f_print(fout, "\t\tif (size == 0) {\n");
4909 + f_print(fout, "\t\t\tstruct rlimit rl;\n\n");
4910 + f_print(fout, "\t\t\trl.rlim_max = 0;\n");
4911 + f_print(fout, "\t\t\tgetrlimit(RLIMIT_NOFILE, &rl);\n");
4912 + f_print(fout, "\t\t\tif ((size = rl.rlim_max) == 0)\n");
4913 + f_print(fout, "\t\t\t\treturn;\n");
4915 + f_print(fout, "\t\t\tsize = getdtablesize();\n");
4917 + f_print(fout, "\t\t}\n");
4918 + f_print(fout, "\t\tfor (i = 0, openfd = 0; i < size && openfd < 2; i++)\n");
4919 + f_print(fout, "\t\t\tif (FD_ISSET(i, &svc_fdset))\n");
4920 + f_print(fout, "\t\t\t\topenfd++;\n");
4921 + f_print(fout, "\t\tif (openfd <= 1)\n");
4922 + f_print(fout, "\t\t\texit(0);\n");
4923 + f_print(fout, "\t}\n");
4924 + f_print(fout, "\t(void) alarm(_RPCSVC_CLOSEDOWN);\n");
4925 + f_print(fout, "}\n");
4929 + * Write the most of port monitor support
4932 +write_pm_most(char *infile, int netflag)
4938 + f_print(fout, "\tif (!ioctl(0, I_LOOK, mname) &&\n");
4939 + f_print(fout, "\t\t(!strcmp(mname, \"sockmod\") ||");
4940 + f_print(fout, " !strcmp(mname, \"timod\"))) {\n");
4941 + f_print(fout, "\t\tchar *netid;\n");
4942 + if (!netflag) { /* Not included by -n option */
4943 + f_print(fout, "\t\tstruct netconfig *nconf = NULL;\n");
4944 + f_print(fout, "\t\tSVCXPRT *%s;\n", TRANSP);
4947 + f_print(fout, "\t\tint pmclose;\n");
4948 +/* not necessary, defined in /usr/include/stdlib */
4949 +/* f_print(fout, "\t\textern char *getenv();\n");*/
4950 + f_print(fout, "\n");
4951 + f_print(fout, "\t\t_rpcpmstart = 1;\n");
4953 + open_log_file(infile, "\t\t");
4954 + f_print(fout, "\t\tif ((netid = getenv(\"NLSPROVIDER\")) == NULL) {\n");
4955 + sprintf(_errbuf, "cannot get transport name");
4956 + print_err_message("\t\t\t");
4957 + f_print(fout, "\t\t} else if ((nconf = getnetconfigent(netid)) == NULL) {\n");
4958 + sprintf(_errbuf, "cannot get transport info");
4959 + print_err_message("\t\t\t");
4960 + f_print(fout, "\t\t}\n");
4962 + * A kludgy support for inetd services. Inetd only works with
4963 + * sockmod, and RPC works only with timod, hence all this jugglery
4965 + f_print(fout, "\t\tif (strcmp(mname, \"sockmod\") == 0) {\n");
4966 + f_print(fout, "\t\t\tif (ioctl(0, I_POP, 0) || ioctl(0, I_PUSH, \"timod\")) {\n");
4967 + sprintf(_errbuf, "could not get the right module");
4968 + print_err_message("\t\t\t\t");
4969 + f_print(fout, "\t\t\t\texit(1);\n");
4970 + f_print(fout, "\t\t\t}\n");
4971 + f_print(fout, "\t\t}\n");
4973 + f_print(fout, "\t\tpmclose = (t_getstate(0) != T_DATAXFER);\n");
4974 + f_print(fout, "\t\tif ((%s = svc_tli_create(0, nconf, NULL, 0, 0)) == NULL) {\n",
4976 + sprintf(_errbuf, "cannot create server handle");
4977 + print_err_message("\t\t\t");
4978 + f_print(fout, "\t\t\texit(1);\n");
4979 + f_print(fout, "\t\t}\n");
4980 + f_print(fout, "\t\tif (nconf)\n");
4981 + f_print(fout, "\t\t\tfreenetconfigent(nconf);\n");
4982 + for (l = defined; l != NULL; l = l->next) {
4983 + def = (definition *) l->val;
4984 + if (def->def_kind != DEF_PROGRAM) {
4987 + for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
4989 + "\t\tif (!svc_reg(%s, %s, %s, ",
4990 + TRANSP, def->def_name, vp->vers_name);
4991 + pvname(def->def_name, vp->vers_num);
4992 + f_print(fout, ", 0)) {\n");
4993 + (void) sprintf(_errbuf, "unable to register (%s, %s).",
4994 + def->def_name, vp->vers_name);
4995 + print_err_message("\t\t\t");
4996 + f_print(fout, "\t\t\texit(1);\n");
4997 + f_print(fout, "\t\t}\n");
5001 + f_print(fout, "\t\tif (pmclose) {\n");
5002 + f_print(fout, "\t\t\t(void) signal(SIGALRM, %s closedown);\n",
5003 + Cflag? "(SIG_PF)" : "(void(*)())" );
5004 + f_print(fout, "\t\t\t(void) alarm(_RPCSVC_CLOSEDOWN);\n");
5005 + f_print(fout, "\t\t}\n");
5007 + f_print(fout, "\t\tsvc_run();\n");
5008 + f_print(fout, "\t\texit(1);\n");
5009 + f_print(fout, "\t\t/* NOTREACHED */\n");
5010 + f_print(fout, "\t}\n");
5014 + * Support for backgrounding the server if self started.
5017 +write_rpc_svc_fg(char *infile, char *sp)
5019 + f_print(fout, "#ifndef RPC_SVC_FG\n");
5020 + f_print(fout, "%sint size;\n", sp);
5022 + f_print(fout, "%sstruct rlimit rl;\n", sp);
5024 + f_print(fout, "%sint pid, i;\n\n", sp);
5025 + f_print(fout, "%spid = fork();\n", sp);
5026 + f_print(fout, "%sif (pid < 0) {\n", sp);
5027 + f_print(fout, "%s\tperror(\"cannot fork\");\n", sp);
5028 + f_print(fout, "%s\texit(1);\n", sp);
5029 + f_print(fout, "%s}\n", sp);
5030 + f_print(fout, "%sif (pid)\n", sp);
5031 + f_print(fout, "%s\texit(0);\n", sp);
5032 + /* get number of file descriptors */
5034 + f_print(fout, "%srl.rlim_max = 0;\n", sp);
5035 + f_print(fout, "%sgetrlimit(RLIMIT_NOFILE, &rl);\n", sp);
5036 + f_print(fout, "%sif ((size = rl.rlim_max) == 0)\n", sp);
5037 + f_print(fout, "%s\texit(1);\n", sp);
5039 + f_print(fout, "%ssize = getdtablesize();\n", sp);
5042 + f_print(fout, "%sfor (i = 0; i < size; i++)\n", sp);
5043 + f_print(fout, "%s\t(void) close(i);\n", sp);
5044 + /* Redirect stderr and stdout to console */
5045 + f_print(fout, "%si = open(\"/dev/console\", 2);\n", sp);
5046 + f_print(fout, "%s(void) dup2(i, 1);\n", sp);
5047 + f_print(fout, "%s(void) dup2(i, 2);\n", sp);
5048 + /* This removes control of the controlling terminal */
5050 + f_print(fout, "%ssetsid();\n", sp);
5052 + f_print(fout, "%si = open(\"/dev/tty\", 2);\n", sp);
5053 + f_print(fout, "%sif (i >= 0) {\n", sp);
5054 + f_print(fout, "%s\t(void) ioctl(i, TIOCNOTTY, (char *)NULL);\n", sp);;
5055 + f_print(fout, "%s\t(void) close(i);\n", sp);
5056 + f_print(fout, "%s}\n", sp);
5059 + open_log_file(infile, sp);
5060 + f_print(fout, "#endif\n");
5062 + open_log_file(infile, sp);
5066 +open_log_file(char *infile, char *sp)
5070 + s = strrchr(infile, '.');
5073 + f_print(fout,"%sopenlog(\"%s\", LOG_PID, LOG_DAEMON);\n", sp, infile);
5082 + * write a registration for the given transport for Inetd
5085 +write_inetd_register(char *transp)
5098 + if (streq(transp, "udp"))
5102 + f_print(fout, "\n");
5104 + f_print(fout, "\tif ((_rpcfdtype == 0) || (_rpcfdtype == %s)) {\n",
5105 + isudp ? "SOCK_DGRAM" : "SOCK_STREAM");
5107 + f_print(fout, "%s\t%s = svc%s_create(%s",
5108 + sp, TRANSP, transp, inetdflag? "sock": "RPC_ANYSOCK");
5110 + f_print(fout, ", 0, 0");
5111 + f_print(fout, ");\n");
5112 + f_print(fout, "%s\tif (%s == NULL) {\n", sp, TRANSP);
5113 + (void) sprintf(_errbuf, "cannot create %s service.", transp);
5114 + (void) sprintf(tmpbuf, "%s\t\t", sp);
5115 + print_err_message(tmpbuf);
5116 + f_print(fout, "%s\t\texit(1);\n", sp);
5117 + f_print(fout, "%s\t}\n", sp);
5120 + f_print(fout, "%s\tif (!_rpcpmstart)\n\t", sp);
5121 + f_print(fout, "%s\tproto = IPPROTO_%s;\n",
5122 + sp, isudp ? "UDP": "TCP");
5124 + for (l = defined; l != NULL; l = l->next) {
5125 + def = (definition *) l->val;
5126 + if (def->def_kind != DEF_PROGRAM) {
5129 + for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
5130 + f_print(fout, "%s\tif (!svc_register(%s, %s, %s, ",
5131 + sp, TRANSP, def->def_name, vp->vers_name);
5132 + pvname(def->def_name, vp->vers_num);
5134 + f_print(fout, ", proto)) {\n");
5136 + f_print(fout, ", IPPROTO_%s)) {\n",
5137 + isudp ? "UDP": "TCP");
5138 + (void) sprintf(_errbuf, "unable to register (%s, %s, %s).",
5139 + def->def_name, vp->vers_name, transp);
5140 + print_err_message(tmpbuf);
5141 + f_print(fout, "%s\t\texit(1);\n", sp);
5142 + f_print(fout, "%s\t}\n", sp);
5146 + f_print(fout, "\t}\n");
5148 diff --git a/rpcgen/rpc_tblout.c b/rpcgen/rpc_tblout.c
5149 new file mode 100644
5150 index 0000000..ae002f7
5152 +++ b/rpcgen/rpc_tblout.c
5155 + * Copyright (c) 2009, Sun Microsystems, Inc.
5156 + * All rights reserved.
5158 + * Redistribution and use in source and binary forms, with or without
5159 + * modification, are permitted provided that the following conditions are met:
5160 + * - Redistributions of source code must retain the above copyright notice,
5161 + * this list of conditions and the following disclaimer.
5162 + * - Redistributions in binary form must reproduce the above copyright notice,
5163 + * this list of conditions and the following disclaimer in the documentation
5164 + * and/or other materials provided with the distribution.
5165 + * - Neither the name of Sun Microsystems, Inc. nor the names of its
5166 + * contributors may be used to endorse or promote products derived
5167 + * from this software without specific prior written permission.
5169 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
5170 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
5171 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
5172 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
5173 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
5174 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
5175 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
5176 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
5177 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
5178 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
5179 + * POSSIBILITY OF SUCH DAMAGE.
5183 +static char sccsid[] = "@(#)rpc_tblout.c 1.4 89/02/22 (C) 1988 SMI";
5187 + * rpc_tblout.c, Dispatch table outputter for the RPC protocol compiler
5190 +#include <string.h>
5191 +#include "rpc_parse.h"
5192 +#include "rpc_util.h"
5193 +#include "rpc_output.h"
5195 +static void write_table(definition *def);
5196 +static void printit(char *prefix, char *type);
5200 +#define TABSTOP (TABSIZE*TABCOUNT)
5202 +static char tabstr[TABCOUNT+1] = "\t\t\t\t\t";
5204 +static char tbl_hdr[] = "struct rpcgen_table %s_table[] = {\n";
5205 +static char tbl_end[] = "};\n";
5207 +static char null_entry[] = "\n\t(char *(*)())0,\n\
5208 + \t(xdrproc_t) xdr_void,\t\t\t0,\n\
5209 + \t(xdrproc_t) xdr_void,\t\t\t0,\n";
5212 +static char tbl_nproc[] = "int %s_nproc =\n\tsizeof(%s_table)/sizeof(%s_table[0]);\n\n";
5220 + f_print(fout, "\n");
5221 + for (l = defined; l != NULL; l = l->next) {
5222 + def = (definition *) l->val;
5223 + if (def->def_kind == DEF_PROGRAM) {
5230 +write_table(definition *def)
5236 + char progvers[100];
5239 + for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
5241 + s_print(progvers, "%s_%s",
5242 + locase(def->def_name), vp->vers_num);
5243 + /* print the table header */
5244 + f_print(fout, tbl_hdr, progvers);
5246 + if (nullproc(vp->procs)) {
5250 + f_print(fout, null_entry);
5252 + for (proc = vp->procs; proc != NULL; proc = proc->next) {
5253 + current = atoi(proc->proc_num);
5254 + if (current != expected++) {
5256 + "\n/*\n * WARNING: table out of order\n */\n");
5257 + if (warning == 0) {
5259 + "WARNING %s table is out of order\n",
5262 + nonfatalerrors = 1;
5264 + expected = current + 1;
5266 + f_print(fout, "\n\t(char *(*)())RPCGEN_ACTION(");
5268 + /* routine to invoke */
5269 + if( Cflag && !newstyle )
5270 + pvname_svc(proc->proc_name, vp->vers_num);
5273 + f_print( fout, "_"); /* calls internal func */
5274 + pvname(proc->proc_name, vp->vers_num);
5276 + f_print(fout, "),\n");
5278 + /* argument info */
5279 + if( proc->arg_num > 1 )
5280 + printit((char*) NULL, proc->args.argname );
5282 + /* do we have to do something special for newstyle */
5283 + printit( proc->args.decls->decl.prefix,
5284 + proc->args.decls->decl.type );
5286 + printit(proc->res_prefix, proc->res_type);
5289 + /* print the table trailer */
5290 + f_print(fout, tbl_end);
5291 + f_print(fout, tbl_nproc, progvers, progvers, progvers);
5296 +printit(char *prefix, char *type)
5302 + len = fprintf(fout, "\txdr_%s,", stringfix(type));
5303 + /* account for leading tab expansion */
5304 + len += TABSIZE - 1;
5305 + /* round up to tabs required */
5306 + tabs = (TABSTOP - len + TABSIZE - 1)/TABSIZE;
5307 + f_print(fout, "%s", &tabstr[TABCOUNT-tabs]);
5309 + if (streq(type, "void")) {
5310 + f_print(fout, "0");
5312 + f_print(fout, "sizeof ( ");
5313 + /* XXX: should "follow" be 1 ??? */
5314 + ptype(prefix, type, 0);
5315 + f_print(fout, ")");
5317 + f_print(fout, ",\n");
5319 diff --git a/rpcgen/rpc_util.c b/rpcgen/rpc_util.c
5320 new file mode 100644
5321 index 0000000..b67be57
5323 +++ b/rpcgen/rpc_util.c
5326 + * Copyright (c) 2009, Sun Microsystems, Inc.
5327 + * All rights reserved.
5329 + * Redistribution and use in source and binary forms, with or without
5330 + * modification, are permitted provided that the following conditions are met:
5331 + * - Redistributions of source code must retain the above copyright notice,
5332 + * this list of conditions and the following disclaimer.
5333 + * - Redistributions in binary form must reproduce the above copyright notice,
5334 + * this list of conditions and the following disclaimer in the documentation
5335 + * and/or other materials provided with the distribution.
5336 + * - Neither the name of Sun Microsystems, Inc. nor the names of its
5337 + * contributors may be used to endorse or promote products derived
5338 + * from this software without specific prior written permission.
5340 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
5341 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
5342 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
5343 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
5344 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
5345 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
5346 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
5347 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
5348 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
5349 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
5350 + * POSSIBILITY OF SUCH DAMAGE.
5354 +static char sccsid[] = "@(#)rpc_util.c 1.11 89/02/22 (C) 1987 SMI";
5358 + * rpc_util.c, Utility routines for the RPC protocol compiler
5361 +#include <memory.h>
5363 +#include <unistd.h>
5364 +#include "rpc_scan.h"
5365 +#include "rpc_parse.h"
5366 +#include "rpc_util.h"
5368 +static void printwhere(void);
5371 +#define ARGEXT "argument"
5373 +char curline[MAXLINESIZE]; /* current read line */
5374 +char *where = curline; /* current point in line */
5375 +int linenum = 0; /* current line number */
5377 +char *infilename; /* input filename */
5380 +char *outfiles[NFILES]; /* output file names */
5383 +FILE *fout; /* file pointer of current output */
5384 +FILE *fin; /* file pointer of current input */
5386 +list *defined; /* list of defined things */
5389 + * Reinitialize the world
5394 + memset(curline, 0, MAXLINESIZE);
5404 +streq(char *a, char *b)
5406 + return (strcmp(a, b) == 0);
5410 + * find a value in a list
5413 +findval(list *lst, char *val, int (*cmp)(definition *, char *))
5416 + for (; lst != NULL; lst = lst->next) {
5417 + if ((*cmp) (lst->val, val)) {
5418 + return (lst->val);
5425 + * store a value in a list
5428 +storeval(lstp, val)
5436 + for (l = lstp; *l != NULL; l = (list **) & (*l)->next);
5437 + lst = ALLOC(list);
5444 +findit(definition *def, char *type)
5446 + return (streq(def->def_name, type));
5450 +fixit(char *type, char *orig)
5454 + def = (definition *) FINDVAL(defined, type, findit);
5455 + if (def == NULL || def->def_kind != DEF_TYPEDEF) {
5458 + switch (def->def.ty.rel) {
5460 + return (def->def.ty.old_type);
5462 + return (fixit(def->def.ty.old_type, orig));
5469 +fixtype(char *type)
5471 + return (fixit(type, type));
5475 +stringfix(char *type)
5477 + if (streq(type, "string")) {
5478 + return ("wrapstring");
5485 +ptype(char *prefix, char *type, int follow)
5487 + if (prefix != NULL) {
5488 + if (streq(prefix, "enum")) {
5489 + f_print(fout, "enum ");
5491 + f_print(fout, "struct ");
5494 + if (streq(type, "bool")) {
5495 + f_print(fout, "bool_t ");
5496 + } else if (streq(type, "string")) {
5497 + f_print(fout, "char *");
5499 + f_print(fout, "%s ", follow ? fixtype(type) : type);
5504 +typedefed(definition *def, char *type)
5506 + if (def->def_kind != DEF_TYPEDEF || def->def.ty.old_prefix != NULL) {
5509 + return (streq(def->def_name, type));
5514 +isvectordef(char *type, relation rel)
5521 + return (!streq(type, "string"));
5527 + def = (definition *) FINDVAL(defined, type, typedefed);
5528 + if (def == NULL) {
5531 + type = def->def.ty.old_type;
5532 + rel = def->def.ty.rel;
5541 + static char buf[100];
5544 + while ((c = *str++) != '\0') {
5545 + *p++ = (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c;
5552 +pvname_svc(char *pname, char *vnum)
5554 + f_print(fout, "%s_%s_svc", locase(pname), vnum);
5558 +pvname(char *pname, char *vnum)
5560 + f_print(fout, "%s_%s", locase(pname), vnum);
5564 + * print a useful (?) error message, and then die
5570 + f_print(stderr, "%s, line %d: ", infilename, linenum);
5571 + f_print(stderr, "%s\n", msg);
5576 + * Something went wrong, unlink any files that we may have created and then
5584 + for (i = 0; i < nfiles; i++) {
5585 + (void) unlink(outfiles[i]);
5591 +record_open(char *file)
5593 + if (nfiles < NFILES) {
5594 + outfiles[nfiles++] = file;
5596 + f_print(stderr, "too many files!\n");
5601 +static char expectbuf[100];
5602 +static char *toktostr();
5605 + * error, token encountered was not the expected one
5611 + s_print(expectbuf, "expected '%s'",
5617 + * error, token encountered was not one of two expected ones
5620 +expected2(exp1, exp2)
5621 + tok_kind exp1, exp2;
5623 + s_print(expectbuf, "expected '%s' or '%s'",
5630 + * error, token encountered was not one of 3 expected ones
5633 +expected3(exp1, exp2, exp3)
5634 + tok_kind exp1, exp2, exp3;
5636 + s_print(expectbuf, "expected '%s', '%s' or '%s'",
5649 + (void) fputc('\t', f);
5654 +static token tokstrings[] = {
5655 + {TOK_IDENT, "identifier"},
5656 + {TOK_CONST, "const"},
5657 + {TOK_RPAREN, ")"},
5658 + {TOK_LPAREN, "("},
5659 + {TOK_RBRACE, "}"},
5660 + {TOK_LBRACE, "{"},
5661 + {TOK_LBRACKET, "["},
5662 + {TOK_RBRACKET, "]"},
5667 + {TOK_SEMICOLON, ";"},
5668 + {TOK_UNION, "union"},
5669 + {TOK_STRUCT, "struct"},
5670 + {TOK_SWITCH, "switch"},
5671 + {TOK_CASE, "case"},
5672 + {TOK_DEFAULT, "default"},
5673 + {TOK_ENUM, "enum"},
5674 + {TOK_TYPEDEF, "typedef"},
5676 + {TOK_SHORT, "short"},
5677 + {TOK_INT32, "int32"},
5678 + {TOK_UNSIGNED, "unsigned"},
5679 + {TOK_DOUBLE, "double"},
5680 + {TOK_FLOAT, "float"},
5681 + {TOK_CHAR, "char"},
5682 + {TOK_STRING, "string"},
5683 + {TOK_OPAQUE, "opaque"},
5684 + {TOK_BOOL, "bool"},
5685 + {TOK_VOID, "void"},
5686 + {TOK_PROGRAM, "program"},
5687 + {TOK_VERSION, "version"},
5688 + {TOK_EOF, "??????"}
5697 + for (sp = tokstrings; sp->kind != TOK_EOF && sp->kind != kind; sp++);
5710 + for (i = 0; (c = curline[i]) != '\0'; i++) {
5712 + cnt = 8 - (i % TABSIZE);
5718 + (void) fputc(c, stderr);
5731 + for (i = 0; i < where - curline; i++) {
5734 + cnt = 8 - (i % TABSIZE);
5739 + (void) fputc('^', stderr);
5742 + (void) fputc('\n', stderr);
5746 +make_argname(char *pname, char *vname)
5750 + name = malloc(strlen(pname) + strlen(vname) + strlen(ARGEXT) + 3);
5752 + fprintf(stderr, "failed in malloc");
5755 + sprintf(name, "%s_%s_%s", locase(pname), vname, ARGEXT);
5759 +bas_type *typ_list_h;
5760 +bas_type *typ_list_t;
5763 +add_type(int len, char *type)
5768 + if ((ptr = (bas_type *) malloc(sizeof(bas_type))) == (bas_type *) NULL) {
5769 + fprintf(stderr, "failed in malloc");
5773 + ptr->length = len;
5775 + if (typ_list_t == NULL) {
5781 + typ_list_t->next = ptr;
5788 +find_type(char *type)
5795 + while (ptr != NULL) {
5796 + if (strcmp(ptr->name, type) == 0)
5804 diff --git a/rpcgen/rpc_util.h b/rpcgen/rpc_util.h
5805 new file mode 100644
5806 index 0000000..fa115be
5808 +++ b/rpcgen/rpc_util.h
5811 + * Copyright (c) 2009, Sun Microsystems, Inc.
5812 + * All rights reserved.
5814 + * Redistribution and use in source and binary forms, with or without
5815 + * modification, are permitted provided that the following conditions are met:
5816 + * - Redistributions of source code must retain the above copyright notice,
5817 + * this list of conditions and the following disclaimer.
5818 + * - Redistributions in binary form must reproduce the above copyright notice,
5819 + * this list of conditions and the following disclaimer in the documentation
5820 + * and/or other materials provided with the distribution.
5821 + * - Neither the name of Sun Microsystems, Inc. nor the names of its
5822 + * contributors may be used to endorse or promote products derived
5823 + * from this software without specific prior written permission.
5825 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
5826 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
5827 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
5828 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
5829 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
5830 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
5831 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
5832 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
5833 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
5834 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
5835 + * POSSIBILITY OF SUCH DAMAGE.
5838 +/* @(#)rpc_util.h 1.5 90/08/29 (C) 1987 SMI */
5841 + * rpc_util.h, Useful definitions for the RPC protocol compiler
5844 +#include <stdlib.h>
5846 +#define alloc(size) malloc((unsigned)(size))
5847 +#define ALLOC(object) (object *) malloc(sizeof(object))
5849 +#define s_print (void) sprintf
5850 +#define f_print (void) fprintf
5854 + struct list *next;
5856 +typedef struct list list;
5862 + * Global variables
5864 +#define MAXLINESIZE 1024
5865 +extern char curline[MAXLINESIZE];
5866 +extern char *where;
5867 +extern int linenum;
5869 +extern char *infilename;
5873 +extern list *defined;
5876 +extern bas_type *typ_list_h;
5877 +extern bas_type *typ_list_t;
5880 + * All the option flags
5882 +extern int inetdflag;
5884 +extern int tblflag;
5885 +extern int logflag;
5886 +extern int newstyle;
5887 +extern int Cflag; /* C++ flag */
5888 +extern int tirpcflag; /* flag for generating tirpc code */
5889 +extern int Inline; /* if this is 0, then do not generate inline code */
5892 + * Other flags related with inetd jumpstart.
5894 +extern int indefinitewait;
5895 +extern int exitnow;
5896 +extern int timerflag;
5898 +extern int nonfatalerrors;
5901 + * rpc_util routines
5905 +#define STOREVAL(list,item) \
5906 + storeval(list,item)
5908 +definition *findval();
5910 +#define FINDVAL(list,item,finder) \
5911 + findval(list, item, finder)
5915 + * rpc_cout routines
5918 +void emit(definition *);
5921 + * rpc_hout routines
5923 +void print_datadef(definition *);
5924 +void print_funcdef(definition *);
5927 + * rpc_svcout routines
5929 +void write_most(char *, int, int);
5930 +void write_register(void);
5931 +void write_netid_register(char *);
5932 +void write_nettype_register(char *);
5933 +void write_inetd_register(char *);
5934 +void write_rest(void);
5935 +void write_programs(char *);
5936 +void write_svc_aux(int);
5939 + * rpc_clntout routines
5941 +void write_stubs(void);
5942 +void printarglist(proc_list *, char *, char *);
5945 + * rpc_tblout routines
5947 +void write_tables(void);
5952 +void pvname_svc(char *, char *);
5953 +void pvname(char *, char *);
5954 +void ptype(char *, char *, int);
5955 +char * make_argname(char *, char *);
5956 +void add_type(int, char *);
5957 +void reinitialize(void);
5959 +void error(char *);
5960 +char *fixtype(char *);
5961 +char *stringfix(char *);
5962 +char *locase(char *);
5963 +int isvectordef(char *, relation);
5964 +int streq(char *, char *);
5965 +void tabify(FILE *, int);
5966 +void record_open(char *);
5967 +bas_type *find_type(char *type);
5972 +void write_sample_svc(definition *);
5973 +int write_sample_clnt(definition *);
5974 +void write_sample_clnt_main(void);
5975 +void add_sample_msg(void);
5976 diff --git a/rpcgen/rpcgen.1 b/rpcgen/rpcgen.1
5977 new file mode 100644
5978 index 0000000..89df7ed
5980 +++ b/rpcgen/rpcgen.1
5982 +.\" @(#)rpcgen.1 1.35 93/06/02 SMI
5983 +.\" $FreeBSD: src/usr.bin/rpcgen/rpcgen.1,v 1.12.2.4 2002/06/21 15:28:50 charnier Exp $
5984 +.\" Copyright 1985-1993 Sun Microsystems, Inc.
5990 +.Nd an RPC protocol compiler
5999 +.Fl D Ns Ar name Ns Op Ar =value
6002 +.Op Fl I Op Fl K Ar seconds
6007 +.Op Fl Y Ar pathname
6020 +.Op Fl o Ar outfile
6023 +.Op Fl s Ar nettype
6024 +.Op Fl o Ar outfile
6028 +.Op Fl o Ar outfile
6030 +.\" .SH AVAILABILITY
6036 +utility is a tool that generates C code to implement an
6041 +is a language similar to C known as
6043 +Language (Remote Procedure Call Language).
6047 +utility is normally used as in the first synopsis where
6048 +it takes an input file and generates three output files.
6055 +generates a header in
6059 +server-side stubs in
6061 +and client-side stubs in
6066 +it also generates the
6073 +utility can also generate sample client and server files
6074 +that can be customized to suit a particular application.
6080 +options generate sample client, server and makefile, respectively.
6083 +option generates all files, including sample files.
6088 +then the client side sample file is written to
6089 +.Pa proto_client.c ,
6090 +the server side sample file to
6092 +and the sample makefile to
6093 +.Pa makefile.proto .
6095 +The server created can be started both by the port monitors
6099 +When it is started by a port monitor,
6100 +it creates servers only for the transport for which
6101 +the file descriptor
6104 +The name of the transport must be specified
6105 +by setting up the environment variable
6107 +When the server generated by
6110 +it creates server handles for all the transports
6113 +environment variable,
6115 +it creates server handles for all the visible transports from
6119 +the transports are chosen at run time and not at compile time.
6120 +When the server is self-started,
6121 +it backgrounds itself by default.
6122 +A special define symbol
6124 +can be used to run the server process in foreground.
6126 +The second synopsis provides special features which allow
6127 +for the creation of more sophisticated
6130 +These features include support for user provided
6137 +dispatch table contain:
6138 +.Bl -bullet -offset indent -compact
6140 +pointers to the service routine corresponding to that procedure,
6142 +a pointer to the input and output arguments,
6144 +the size of these routines.
6146 +A server can use the dispatch table to check authorization
6147 +and then to execute the service routine;
6148 +a client library may use it to deal with the details of storage
6149 +management and XDR data conversion.
6151 +The other three synopses shown above are used when
6152 +one does not want to generate all the output files,
6153 +but only a particular one.
6156 +section below for examples of
6161 +is executed with the
6164 +it creates servers for that particular class of transports.
6169 +it creates a server for the transport specified by
6175 +accepts the standard input.
6177 +The C preprocessor,
6179 +is run on the input file before it is actually interpreted by
6181 +For each type of output file,
6183 +defines a special preprocessor symbol for use by the
6186 +.Bl -tag -width indent
6188 +defined when compiling into headers
6190 +defined when compiling into XDR routines
6192 +defined when compiling into server-side stubs
6194 +defined when compiling into client-side stubs
6196 +defined when compiling into RPC dispatch tables
6199 +Any line beginning with
6201 +is passed directly into the output file,
6204 +To specify the path name of the C preprocessor use
6208 +For every data type referred to in
6211 +assumes that there exists a
6212 +routine with the string
6214 +prepended to the name of the data type.
6215 +If this routine does not exist in the
6217 +library, it must be provided.
6218 +Providing an undefined data type
6219 +allows customization of
6223 +The following options are available:
6224 +.Bl -tag -width indent
6226 +Generate all files, including sample files.
6228 +Backward compatibility mode.
6229 +Generate transport specific
6231 +code for older versions
6232 +of the operating system.
6236 +this compatibility flag is turned on by
6239 +supports only the older
6247 +Generate header and stub files which can be used with
6249 +C compilers. Headers generated with this flag can also be
6250 +used with C++ programs.
6251 +.It Fl D Ns Ar name
6252 +.It Fl D Ns Ar name=value
6253 +.\".It Fl D Ns Ar name Ns Op Ar =value
6258 +directive in the source.
6265 +This option may be specified more than once.
6267 +Compile into C data-definitions (a header).
6269 +option can be used in conjunction to produce a
6270 +header which supports
6274 +Size at which to start generating inline code.
6275 +This option is useful for optimization.
6276 +The default size is 5.
6278 +Note: in order to provide backwards compatibility with the older
6282 +platform, the default is actually 0 (which means
6283 +that inline code generation is disabled by default). You must specify
6284 +a non-zero value explicitly to override this default.
6286 +Compile support for
6288 +in the server side stubs.
6289 +Such servers can be self-started or can be started by
6291 +When the server is self-started, it backgrounds itself by default.
6292 +A special define symbol
6294 +can be used to run the
6295 +server process in foreground, or the user may simply compile without
6300 +If there are no pending client requests, the
6302 +servers exit after 120 seconds (default).
6303 +The default can be changed with the
6306 +All the error messages for
6309 +are always logged with
6313 +.\" this option is supported for backward compatibility only.
6316 +.\" generates servers that can be invoked through portmonitors.
6318 +.It Fl K Ar seconds
6319 +By default, services created using
6321 +and invoked through
6322 +port monitors wait 120 seconds
6323 +after servicing a request before exiting.
6324 +That interval can be changed using the
6327 +To create a server that exits immediately upon servicing a request,
6330 +To create a server that never exits, the appropriate argument is
6333 +When monitoring for a server,
6336 +spawn a new process in response to a service request.
6337 +If it is known that a server will be used with such a monitor, the
6338 +server should exit immediately on completion.
6341 +should be used with
6344 +Compile into client-side stubs.
6346 +When the servers are started in foreground, use
6348 +to log the server errors instead of printing them on the standard
6351 +Compile into server-side stubs,
6352 +but do not generate a
6355 +This option is useful for doing callback-routines
6356 +and for users who need to write their own
6358 +routine to do initialization.
6360 +Generate multithread-safe stubs for passing arguments and results between
6361 +rpcgen generated code and user written code.
6362 +This option is useful
6363 +for users who want to use threads in their code.
6365 +.Xr rpc_svc_calls 3
6366 +functions are not yet MT-safe, which means that rpcgen generated server-side
6367 +code will not be MT-safe.
6369 +This option allows procedures to have multiple arguments.
6370 +It also uses the style of parameter passing that closely resembles C.
6371 +So, when passing an argument to a remote procedure, you do not have to
6372 +pass a pointer to the argument, but can pass the argument itself.
6373 +This behavior is different from the old style of
6376 +To maintain backward compatibility,
6377 +this option is not the default.
6379 +Compile into server-side stubs for the transport
6382 +There should be an entry for
6385 +netconfig database.
6386 +This option may be specified more than once,
6387 +so as to compile a server that serves multiple transports.
6388 +.It Fl o Ar outfile
6389 +Specify the name of the output file.
6390 +If none is specified,
6391 +standard output is used
6405 +.It Fl s Ar nettype
6406 +Compile into server-side stubs for all the
6407 +transports belonging to the class
6409 +The supported classes are
6421 +for the meanings associated with these classes).
6422 +This option may be specified more than once.
6424 +the transports are chosen at run time and not at compile time.
6426 +Generate sample client code that uses remote procedure calls.
6430 +which can be used for compiling the application.
6432 +Generate sample server code that uses remote procedure calls.
6438 +Generate the code to support
6453 +are used exclusively to generate a particular type of file,
6458 +are global and can be used with the other options.
6459 +.It Fl Y Ar pathname
6460 +Give the name of the directory where
6462 +will start looking for the C-preprocessor.
6465 +The following example:
6466 +.Dl example% rpcgen -T prot.x
6468 +generates all the five files:
6476 +The following example sends the C data-definitions (header)
6477 +to the standard output.
6478 +.Dl example% rpcgen -h prot.x
6480 +To send the test version of the
6482 +server side stubs for
6483 +all the transport belonging to the class
6485 +to standard output, use:
6486 +.Dl example% rpcgen -s datagram_n -DTEST prot.x
6488 +To create the server side stubs for the transport indicated
6493 +.Dl example% rpcgen -n tcp -o prot_svc.c prot.x
6499 +.\" .BR rpc_svc_calls (3)
6501 +.%T The rpcgen chapter in the NETP manual