The cirros image was rebuilt against the 3.13.0-83 kernel, drivers e1000e, igbvf...
[packages/trusty/cirros-testvm.git] / cirros-testvm / src-cirros / buildroot-2015.05 / package / libtirpc / 0004-Add-rpcgen-program-from-nfs-utils-sources.patch
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
5
6 Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
7 ---
8  Makefile.am          |    2 +-
9  configure.ac         |   14 +-
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
43
44 diff --git a/Makefile.am b/Makefile.am
45 index 9b812eb..6edf029 100644
46 --- a/Makefile.am
47 +++ b/Makefile.am
48 @@ -1,4 +1,4 @@
49 -SUBDIRS = src man doc
50 +SUBDIRS = src man doc rpcgen
51  ACLOCAL_AMFLAGS = -I m4
52  
53  noinst_HEADERS        = tirpc/reentrant.h \
54 diff --git a/configure.ac b/configure.ac
55 index 11df020..4110225 100644
56 --- a/configure.ac
57 +++ b/configure.ac
58 @@ -34,5 +34,17 @@ AC_CHECK_LIB([pthread], [pthread_create])
59  AC_CHECK_LIB([nsl], [yp_get_default_domain])
60  
61  
62 -AC_CONFIG_FILES([Makefile src/Makefile man/Makefile doc/Makefile])
63 +AM_CONDITIONAL(CROSS_COMPILING, test $cross_compiling = yes)
64 +
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)
68 +else
69 +   CC_FOR_BUILD=$CC
70 +fi
71 +AC_MSG_RESULT([$CC_FOR_BUILD])
72 +AC_SUBST(CC_FOR_BUILD)
73 +
74 +AC_CONFIG_FILES([Makefile src/Makefile man/Makefile doc/Makefile rpcgen/Makefile])
75 +
76  AC_OUTPUT(libtirpc.pc)
77 diff --git a/rpcgen/Makefile.am b/rpcgen/Makefile.am
78 new file mode 100644
79 index 0000000..2277b6f
80 --- /dev/null
81 +++ b/rpcgen/Makefile.am
82 @@ -0,0 +1,22 @@
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 $@
86 +
87 +bin_PROGRAMS = rpcgen
88 +
89 +rpcgen_SOURCES = \
90 +       rpc_clntout.c \
91 +       rpc_cout.c \
92 +       rpc_hout.c \
93 +       rpc_main.c \
94 +       rpc_parse.c \
95 +       rpc_sample.c \
96 +       rpc_scan.c \
97 +       rpc_svcout.c \
98 +       rpc_tblout.c \
99 +       rpc_util.c \
100 +       rpc_parse.h \
101 +       rpc_scan.h \
102 +       rpc_util.h
103 +
104 +dist_man1_MANS = rpcgen.1
105 diff --git a/rpcgen/rpc_clntout.c b/rpcgen/rpc_clntout.c
106 new file mode 100644
107 index 0000000..e2f4382
108 --- /dev/null
109 +++ b/rpcgen/rpc_clntout.c
110 @@ -0,0 +1,217 @@
111 +/*
112 + * Copyright (c) 2009, Sun Microsystems, Inc.
113 + * All rights reserved.
114 + *
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.
125 + *
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.
137 + */
138 +
139 +#if 0
140 +static char sccsid[] = "@(#)rpc_clntout.c 1.11 89/02/22 (C) 1987 SMI";
141 +#endif
142 +
143 +/*
144 + * rpc_clntout.c, Client-stub outputter for the RPC protocol compiler
145 + * Copyright (C) 1987, Sun Microsytsems, Inc.
146 + */
147 +#include <stdio.h>
148 +#include <string.h>
149 +#include <rpc/types.h>
150 +#include "rpc_parse.h"
151 +#include "rpc_util.h"
152 +#include "rpc_output.h"
153 +
154 +/* extern pdeclaration(); */
155 +/* void printarglist(); */
156 +
157 +#define DEFAULT_TIMEOUT 25     /* in seconds */
158 +static char RESULT[] = "clnt_res";
159 +
160 +static void    write_program(definition *def);
161 +static void    printbody(proc_list *proc);
162 +
163 +
164 +void
165 +write_stubs(void)
166 +{
167 +       list *l;
168 +       definition *def;
169 +
170 +       f_print(fout, 
171 +               "\n/* Default timeout can be changed using clnt_control() */\n");
172 +       f_print(fout, "static struct timeval TIMEOUT = { %d, 0 };\n",
173 +               DEFAULT_TIMEOUT);
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);
178 +               }
179 +       }
180 +}
181 +
182 +static void
183 +write_program(definition *def)
184 +{
185 +       version_list   *vp;
186 +       proc_list      *proc;
187 +
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");
196 +                       printbody(proc);
197 +                       f_print(fout, "}\n");
198 +               }
199 +       }
200 +}
201 +
202 +/*
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);
206 + */
207 +
208 +/* sample addargname = "clnt"; sample addargtype = "CLIENT * " */
209 +
210 +void
211 +printarglist(proc_list *proc, char *addargname, char *addargtype)
212 +{
213 +
214 +       decl_list      *l;
215 +
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);
221 +               } else {
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");
226 +               }
227 +       } else if (streq(proc->args.decls->decl.type, "void")) {
228 +               /* newstyle, 0 argument */
229 +               if (Cflag)
230 +                       f_print(fout, "(%s%s)\n", addargtype, addargname);
231 +               else
232 +                       f_print(fout, "(%s)\n", addargname);
233 +       } else {
234 +               /* new style, 1 or multiple arguments */
235 +               if (!Cflag) {
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");
242 +                       }
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, ", ");
247 +                       }
248 +                       f_print(fout, " %s%s)\n", addargtype, addargname);
249 +               }
250 +       }
251 +
252 +       if (!Cflag)
253 +               f_print(fout, "\t%s%s;\n", addargtype, addargname);
254 +}
255 +
256 +
257 +
258 +static char *
259 +ampr(char *type)
260 +{
261 +       if (isvectordef(type, REL_ALIAS)) {
262 +               return ("");
263 +       } else {
264 +               return ("&");
265 +       }
266 +}
267 +
268 +static void
269 +printbody(proc_list *proc)
270 +{
271 +       decl_list      *l;
272 +       bool_t          args2 = (proc->arg_num > 1);
273 +
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");
279 +       }
280 +       f_print(fout, "\tstatic ");
281 +       if (streq(proc->res_type, "void")) {
282 +               f_print(fout, "char ");
283 +       } else {
284 +               ptype(proc->res_prefix, proc->res_type, 0);
285 +       }
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 */
292 +               f_print(fout,
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",
295 +                       proc->proc_name,
296 +                       stringfix(proc->res_type), ampr(proc->res_type), RESULT);
297 +
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);
303 +               }
304 +               f_print(fout,
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 */
310 +               f_print(fout,
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",
313 +                       proc->proc_name,
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);
318 +       }
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);
324 +       } else {
325 +               f_print(fout, "\treturn (%s%s);\n", ampr(proc->res_type), RESULT);
326 +       }
327 +}
328 diff --git a/rpcgen/rpc_cout.c b/rpcgen/rpc_cout.c
329 new file mode 100644
330 index 0000000..a61214f
331 --- /dev/null
332 +++ b/rpcgen/rpc_cout.c
333 @@ -0,0 +1,706 @@
334 +/*
335 + * Copyright (c) 2009, Sun Microsystems, Inc.
336 + * All rights reserved.
337 + *
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.
348 + *
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.
360 + */
361 +
362 +#if 0
363 +static char sccsid[] = "@(#)rpc_cout.c 1.13 89/02/22 (C) 1987 SMI";
364 +#endif
365 +
366 +/*
367 + * rpc_cout.c, XDR routine outputter for the RPC protocol compiler 
368 + */
369 +#include <stdio.h>
370 +#include <string.h>
371 +#include <stdlib.h>
372 +#include <malloc.h>
373 +#include <ctype.h>
374 +#include "rpc_parse.h"
375 +#include "rpc_util.h"
376 +
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);
398 +
399 +/*
400 + * Emit the C-routine for the given definition 
401 + */
402 +void
403 +emit(definition *def)
404 +{
405 +       if (def->def_kind == DEF_CONST) {
406 +               return;
407 +       }
408 +       if (def->def_kind == DEF_PROGRAM) {
409 +               emit_program(def);
410 +               return;
411 +       }
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
416 +                * to xdr_foo */
417 +
418 +               if (strcmp(def->def.ty.old_type, def->def_name) == 0)
419 +                       return;
420 +       };
421 +
422 +       print_header(def);
423 +       switch (def->def_kind) {
424 +       case DEF_UNION:
425 +               emit_union(def);
426 +               break;
427 +       case DEF_ENUM:
428 +               emit_enum(def);
429 +               break;
430 +       case DEF_STRUCT:
431 +               emit_struct(def);
432 +               break;
433 +       case DEF_TYPEDEF:
434 +               emit_typedef(def);
435 +               break;
436 +       default:
437 +               break;
438 +       }
439 +       print_trailer();
440 +}
441 +
442 +static int
443 +findtype(definition *def, char *type)
444 +{
445 +
446 +       if (def->def_kind == DEF_PROGRAM || def->def_kind == DEF_CONST) {
447 +               return (0);
448 +       } else {
449 +               return (streq(def->def_name, type));
450 +       }
451 +}
452 +
453 +static int
454 +undefined(char *type)
455 +{
456 +       definition     *def;
457 +
458 +       def = (definition *) FINDVAL(defined, type, findtype);
459 +
460 +       return (def == NULL);
461 +}
462 +
463 +
464 +static void
465 +print_generic_header(char *procname, int pointerp)
466 +{
467 +       f_print(fout, "\n");
468 +       f_print(fout, "bool_t\n");
469 +       if (Cflag) {
470 +               f_print(fout, "xdr_%s(", procname);
471 +               f_print(fout, "XDR *xdrs, ");
472 +               f_print(fout, "%s ", procname);
473 +               if (pointerp)
474 +                       f_print(fout, "*");
475 +               f_print(fout, "objp)\n{\n\n");
476 +       } else {
477 +               f_print(fout, "xdr_%s(xdrs, objp)\n", procname);
478 +               f_print(fout, "\tXDR *xdrs;\n");
479 +               f_print(fout, "\t%s ", procname);
480 +               if (pointerp)
481 +                       f_print(fout, "*");
482 +               f_print(fout, "objp;\n{\n\n");
483 +       }
484 +}
485 +
486 +static void
487 +print_header(definition *def)
488 +{
489 +       print_generic_header(def->def_name,
490 +               def->def_kind != DEF_TYPEDEF ||
491 +               !isvectordef(def->def.ty.old_type, def->def.ty.rel));
492 +
493 +       /* Now add Inline support */
494 +
495 +
496 +       if (Inline == 0)
497 +               return;
498 +}
499 +
500 +static void
501 +print_prog_header(proc_list *plist)
502 +{
503 +       print_generic_header(plist->args.argname, 1);
504 +}
505 +
506 +static void
507 +print_trailer(void)
508 +{
509 +       f_print(fout, "\treturn (TRUE);\n");
510 +       f_print(fout, "}\n");
511 +}
512 +
513 +
514 +static void
515 +print_ifopen(int indent, char *name)
516 +{
517 +       tabify(fout, indent);
518 +       f_print(fout, " if (!xdr_%s(xdrs", name);
519 +}
520 +
521 +static void
522 +print_ifarg(char *arg)
523 +{
524 +       f_print(fout, ", %s", arg);
525 +}
526 +
527 +static void
528 +print_ifsizeof(char *prefix, char *type)
529 +{
530 +       if (streq(type, "bool")) {
531 +               f_print(fout, ", sizeof(bool_t), (xdrproc_t)xdr_bool");
532 +       } else {
533 +               f_print(fout, ", sizeof(");
534 +               if (undefined(type) && prefix) {
535 +                       f_print(fout, "%s ", prefix);
536 +               }
537 +               f_print(fout, "%s), (xdrproc_t)xdr_%s", type, type);
538 +       }
539 +}
540 +
541 +static void
542 +print_ifclose(int indent)
543 +{
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");
549 +}
550 +
551 +static void
552 +print_ifstat(int indent, char *prefix, char *type, relation rel,
553 +                       char *amax, char *objname, char *name)
554 +{
555 +       char *alt = NULL;
556 +
557 +       switch (rel) {
558 +       case REL_POINTER:
559 +               print_ifopen(indent, "pointer");
560 +               print_ifarg("(char **)");
561 +               f_print(fout, "%s", objname);
562 +               print_ifsizeof(prefix, type);
563 +               break;
564 +       case REL_VECTOR:
565 +               if (streq(type, "string")) {
566 +                       alt = "string";
567 +               } else if (streq(type, "opaque")) {
568 +                       alt = "opaque";
569 +               }
570 +               if (alt) {
571 +                       print_ifopen(indent, alt);
572 +                       print_ifarg(objname);
573 +               } else {
574 +                       print_ifopen(indent, "vector");
575 +                       print_ifarg("(char *)");
576 +                       f_print(fout, "%s", objname);
577 +               }
578 +               print_ifarg(amax);
579 +               if (!alt) {
580 +                       print_ifsizeof(prefix, type);
581 +               }
582 +               break;
583 +       case REL_ARRAY:
584 +               if (streq(type, "string")) {
585 +                       alt = "string";
586 +               } else if (streq(type, "opaque")) {
587 +                       alt = "bytes";
588 +               }
589 +               if (streq(type, "string")) {
590 +                       print_ifopen(indent, alt);
591 +                       print_ifarg(objname);
592 +               } else {
593 +                       if (alt) {
594 +                               print_ifopen(indent, alt);
595 +                       } else {
596 +                               print_ifopen(indent, "array");
597 +                       }
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);
603 +                       } else {
604 +                               f_print(fout, "&%s->%s_val, (u_int *)&%s->%s_len",
605 +                                       objname, name, objname, name);
606 +                       }
607 +               }
608 +               print_ifarg(amax);
609 +               if (!alt) {
610 +                       print_ifsizeof(prefix, type);
611 +               }
612 +               break;
613 +       case REL_ALIAS:
614 +               print_ifopen(indent, type);
615 +               print_ifarg(objname);
616 +               break;
617 +       }
618 +       print_ifclose(indent);
619 +}
620 +
621 +static void
622 +emit_enum(definition *def)
623 +{
624 +       print_ifopen(1, "enum");
625 +       print_ifarg("(enum_t *)objp");
626 +       print_ifclose(1);
627 +}
628 +
629 +static void
630 +emit_program(definition *def)
631 +{
632 +       decl_list      *dl;
633 +       version_list   *vlist;
634 +       proc_list      *plist;
635 +
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);
643 +                       print_trailer();
644 +               }
645 +}
646 +
647 +
648 +static void
649 +emit_union(definition *def)
650 +{
651 +  declaration *dflt;
652 +  case_list *cl;
653 +  declaration *cs;
654 +  char *object;
655 +  char *vecformat = "objp->%s_u.%s";
656 +  char *format = "&objp->%s_u.%s";
657 +
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) {
661 +
662 +    f_print(fout, "\tcase %s:\n", cl->case_name);
663 +    if(cl->contflag == 1)      /* a continued case statement */
664 +      continue;
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, 
671 +               cs->name);
672 +      } else {
673 +       s_print(object, format, def->def_name, 
674 +               cs->name);
675 +      }
676 +      print_ifstat(2, cs->prefix, cs->type, cs->rel, cs->array_max,
677 +                  object, cs->name);
678 +      free(object);
679 +    }
680 +    f_print(fout, "\t\tbreak;\n");
681 +  }
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, 
690 +               dflt->name);
691 +      } else {
692 +       s_print(object, format, def->def_name, 
693 +               dflt->name);
694 +      }
695 +
696 +      print_ifstat(2, dflt->prefix, dflt->type, dflt->rel,
697 +                  dflt->array_max, object, dflt->name);
698 +      free(object);
699 +      f_print(fout, "\t\tbreak;\n");
700 +    } else {
701 +      /* Avoid gcc warnings about `value not handled in switch' */
702 +      f_print(fout, "\tdefault:\n");
703 +      f_print(fout, "\t\tbreak;\n");
704 +    }
705 +  } else {
706 +    f_print(fout, "\tdefault:\n");
707 +    f_print(fout, "\t\treturn (FALSE);\n");
708 +  }
709 +
710 +  f_print(fout, "\t}\n");
711 +}
712 +
713 +static void
714 +emit_struct(definition *def)
715 +{
716 +       decl_list      *dl;
717 +       int             i, j, size, flag;
718 +       decl_list      *cur = NULL, *psav;
719 +       bas_type       *ptr;
720 +       char           *sizestr, *plus;
721 +       char            ptemp[256];
722 +       int             can_inline;
723 +       const char      *buf_declaration;
724 +
725 +
726 +       if (Inline == 0) {
727 +               for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
728 +                       print_stat(1, &dl->decl);
729 +       } else {
730 +               size = 0;
731 +               can_inline = 0;
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))) {
734 +
735 +                               if (dl->decl.rel == REL_ALIAS)
736 +                                       size += ptr->length;
737 +                               else {
738 +                                       can_inline = 1;
739 +                                       break;  /* can be inlined */
740 +                               };
741 +                       } else {
742 +                               if (size >= Inline) {
743 +                                       can_inline = 1;
744 +                                       break;  /* can be inlined */
745 +                               }
746 +                               size = 0;
747 +                       }
748 +               if (size > Inline)
749 +                       can_inline = 1;
750 +
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);
754 +                       return;
755 +               };
756 +
757 +
758 +
759 +
760 +               flag = PUT;
761 +               for (j = 0; j < 2; j++) {
762 +
763 +                       if (flag == PUT)
764 +                               f_print(fout, "\n\t if (xdrs->x_op == XDR_ENCODE) {\n");
765 +                       else
766 +                               f_print(fout, "\n \t return (TRUE);\n\t} else if (xdrs->x_op == XDR_DECODE) {\n");
767 +
768 +
769 +                       i = 0;
770 +                       size = 0;
771 +                       sizestr = NULL;
772 +                       buf_declaration = "int32_t *";
773 +                       for (dl = def->def.st.decls; dl != NULL; dl = dl->next) {       /* xxx */
774 +
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))) {
777 +                                       if (i == 0)
778 +                                               cur = dl;
779 +                                       i++;
780 +
781 +                                       if (dl->decl.rel == REL_ALIAS)
782 +                                               size += ptr->length;
783 +                                       else {
784 +                                               /* this is required to handle arrays */
785 +
786 +                                               if (sizestr == NULL)
787 +                                                       plus = " ";
788 +                                               else
789 +                                                       plus = "+";
790 +
791 +                                               if (ptr->length != 1)
792 +                                                       s_print(ptemp, " %s %s * %d", plus, dl->decl.array_max, ptr->length);
793 +                                               else
794 +                                                       s_print(ptemp, " %s %s ", plus, dl->decl.array_max);
795 +
796 +                                               /*now concatenate to sizestr !!!! */
797 +                                               if (sizestr == NULL)
798 +                                                       sizestr = strdup(ptemp);
799 +                                               else {
800 +                                                       sizestr = realloc(sizestr, strlen(sizestr) + strlen(ptemp) + 1);
801 +                                                       if (sizestr == NULL) {
802 +
803 +                                                               f_print(stderr, "Fatal error : no memory \n");
804 +                                                               crash();
805 +                                                       };
806 +                                                       sizestr = strcat(sizestr, ptemp);       /*build up length of array */
807 +
808 +                                               }
809 +                                       }
810 +
811 +                               } else {
812 +                                       if (i > 0)
813 +                                           {
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);
818 +                                                               cur = cur->next;
819 +                                                       }
820 +                                               } else {
821 +
822 +
823 +
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)
829 +                                                               f_print(fout,
830 +                                                                       "\t %sbuf = XDR_INLINE(xdrs,%s * BYTES_PER_XDR_UNIT);",
831 +                                                                       buf_declaration, sizestr);
832 +                                                       else
833 +                                                               f_print(fout,
834 +                                                                       "\t %sbuf = XDR_INLINE(xdrs,(%d + %s)* BYTES_PER_XDR_UNIT);",
835 +                                                                       buf_declaration, size, sizestr);
836 +                                                       buf_declaration = "";
837 +
838 +                                                       f_print(fout, "\n\t   if (buf == NULL) {\n");
839 +
840 +                                                       psav = cur;
841 +                                                       while (cur != dl) {
842 +                                                               print_stat(2, &cur->decl);
843 +                                                               cur = cur->next;
844 +                                                       }
845 +
846 +                                                       f_print(fout, "\n\t  }\n\t  else {\n");
847 +
848 +                                                       cur = psav;
849 +                                                       while (cur != dl) {
850 +                                                               emit_inline(&cur->decl, flag);
851 +                                                               cur = cur->next;
852 +                                                       }
853 +
854 +                                                       f_print(fout, "\t  }\n");
855 +                                               }
856 +                                           }
857 +                                       size = 0;
858 +                                       i = 0;
859 +                                       sizestr = NULL;
860 +                                       print_stat(1, &dl->decl);
861 +                               }
862 +
863 +                       }
864 +                       if (i > 0)
865 +                           {
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);
870 +                                               cur = cur->next;
871 +                                       }
872 +                               } else {
873 +
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)
879 +                                               f_print(fout,
880 +                                                       "\t\t%sbuf = XDR_INLINE(xdrs,%s * BYTES_PER_XDR_UNIT);",
881 +                                                       buf_declaration, sizestr);
882 +                                       else
883 +                                               f_print(fout,
884 +                                                       "\t\t%sbuf = XDR_INLINE(xdrs,(%d + %s)* BYTES_PER_XDR_UNIT);",
885 +                                                       buf_declaration, size, sizestr);
886 +                                       buf_declaration = "";
887 +
888 +                                       f_print(fout, "\n\t\tif (buf == NULL) {\n");
889 +
890 +                                       psav = cur;
891 +                                       while (cur != NULL) {
892 +                                               print_stat(2, &cur->decl);
893 +                                               cur = cur->next;
894 +                                       }
895 +                                       f_print(fout, "\n\t  }\n\t  else {\n");
896 +
897 +                                       cur = psav;
898 +                                       while (cur != dl) {
899 +                                               emit_inline(&cur->decl, flag);
900 +                                               cur = cur->next;
901 +                                       }
902 +
903 +                                       f_print(fout, "\t  }\n");
904 +
905 +                               }
906 +                           }
907 +                       flag = GET;
908 +               }
909 +               f_print(fout, "\t return(TRUE);\n\t}\n\n");
910 +
911 +               /* now take care of XDR_FREE case */
912 +
913 +               for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
914 +                       print_stat(1, &dl->decl);
915 +       }
916 +}
917
918 +
919 +
920 +
921 +static void
922 +emit_typedef(definition *def)
923 +{
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;
928 +
929 +
930 +         print_ifstat(1, prefix, type, rel, amax, "objp", def->def_name);
931 +}
932 +
933 +static void
934 +print_stat(int indent, declaration *dec)
935 +{
936 +       char *prefix = dec->prefix;
937 +       char *type = dec->type;
938 +       char *amax = dec->array_max;
939 +       relation rel = dec->rel;
940 +       char name[256];
941 +
942 +       if (isvectordef(type, rel)) {
943 +               s_print(name, "objp->%s", dec->name);
944 +       } else {
945 +               s_print(name, "&objp->%s", dec->name);
946 +       }
947 +       print_ifstat(indent, prefix, type, rel, amax, name, dec->name);
948 +}
949 +
950 +
951 +static void
952 +emit_inline(declaration *decl, int flag)
953 +{
954 +
955 +       /*check whether an array or not */
956 +
957 +       switch (decl->rel) {
958 +       case REL_ALIAS:
959 +               emit_single_in_line(decl, flag, REL_ALIAS);
960 +               break;
961 +       case REL_VECTOR:
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");
968 +               break;
969 +       default:
970 +               break;
971 +       }
972 +}
973 +
974 +static void
975 +emit_single_in_line(declaration *decl, int flag, relation rel)
976 +{
977 +       char *upp_case;
978 +       int freed=0;
979 +
980 +       if(flag == PUT)
981 +               f_print(fout,"\t\t (void) IXDR_PUT_");
982 +       else    
983 +               if(rel== REL_ALIAS)
984 +                       f_print(fout,"\t\t objp->%s = IXDR_GET_",decl->name);
985 +               else
986 +                       f_print(fout,"\t\t *genp++ = IXDR_GET_");
987 +
988 +       upp_case=upcase(decl->type);
989 +
990 +       /* hack  - XX */
991 +       if(strcmp(upp_case,"INT") == 0)
992 +       {
993 +               free(upp_case);
994 +               freed=1;
995 +               upp_case="INT32";
996 +       }
997 +
998 +       if(strcmp(upp_case,"U_INT") == 0)
999 +       {
1000 +               free(upp_case);
1001 +               freed=1;
1002 +               upp_case="U_INT32";
1003 +       }
1004 +
1005 +
1006 +       if(flag == PUT) 
1007 +               if(rel== REL_ALIAS)
1008 +                       f_print(fout,"%s(buf,objp->%s);\n",upp_case,decl->name);
1009 +               else
1010 +                       f_print(fout,"%s(buf,*genp++);\n",upp_case);
1011 +
1012 +       else
1013 +               f_print(fout,"%s(buf);\n",upp_case);
1014 +       if(!freed)
1015 +               free(upp_case);
1016 +
1017 +}
1018 +
1019 +
1020 +static char *
1021 +upcase(char *str)
1022 +{
1023 +       char           *ptr, *hptr;
1024 +
1025 +
1026 +       ptr = (char *) malloc(strlen(str)+1);
1027 +       if (ptr == (char *) NULL) {
1028 +               f_print(stderr, "malloc failed \n");
1029 +               exit(1);
1030 +       };
1031 +
1032 +       hptr = ptr;
1033 +       while (*str != '\0')
1034 +               *ptr++ = toupper(*str++);
1035 +
1036 +       *ptr = '\0';
1037 +       return (hptr);
1038 +
1039 +}
1040 diff --git a/rpcgen/rpc_hout.c b/rpcgen/rpc_hout.c
1041 new file mode 100644
1042 index 0000000..ea1cb24
1043 --- /dev/null
1044 +++ b/rpcgen/rpc_hout.c
1045 @@ -0,0 +1,490 @@
1046 +/*
1047 + * Copyright (c) 2009, Sun Microsystems, Inc.
1048 + * All rights reserved.
1049 + *
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.
1060 + *
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.
1072 + */
1073 +
1074 +#if 0
1075 +static char sccsid[] = "@(#)rpc_hout.c 1.12 89/02/22 (C) 1987 SMI";
1076 +#endif
1077 +
1078 +/*
1079 + * rpc_hout.c, Header file outputter for the RPC protocol compiler 
1080 + */
1081 +#include <stdio.h>
1082 +#include <ctype.h>
1083 +#include "rpc_parse.h"
1084 +#include "rpc_util.h"
1085 +#include "rpc_output.h"
1086 +
1087 +
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);
1103 +
1104 +/*
1105 + * Print the C-version of an xdr definition 
1106 + */
1107 +void
1108 +print_datadef(definition *def)
1109 +{
1110 +
1111 +       if (def->def_kind == DEF_PROGRAM )  /* handle data only */
1112 +               return;
1113 +
1114 +       if (def->def_kind != DEF_CONST) {
1115 +               f_print(fout, "\n");
1116 +       }
1117 +       switch (def->def_kind) {
1118 +       case DEF_STRUCT:
1119 +               pstructdef(def);
1120 +               break;
1121 +       case DEF_UNION:
1122 +               puniondef(def);
1123 +               break;
1124 +       case DEF_ENUM:
1125 +               penumdef(def);
1126 +               break;
1127 +       case DEF_TYPEDEF:
1128 +               ptypedef(def);
1129 +               break;
1130 +       case DEF_PROGRAM:
1131 +               pprogramdef(def);
1132 +               break;
1133 +       case DEF_CONST:
1134 +               pconstdef(def);
1135 +               break;
1136 +       }
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));
1141 +
1142 +       }
1143 +}
1144 +
1145 +
1146 +void
1147 +print_funcdef(definition *def)
1148 +{
1149 +       switch (def->def_kind) {
1150 +       case DEF_PROGRAM:
1151 +               f_print(fout, "\n");
1152 +               pprogramdef(def);
1153 +               break;
1154 +       default:
1155 +               break;
1156 +       }
1157 +}
1158 +
1159 +static void
1160 +pxdrfuncdecl(char *name, int pointerp)
1161 +{
1162 +       f_print(fout,
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 ? "*" : "",
1172 +       name);
1173 +}
1174 +
1175 +
1176 +static void
1177 +pconstdef(definition *def)
1178 +{
1179 +       pdefine(def->def_name, def->def.co);
1180 +}
1181 +
1182 +/* print out the definitions for the arguments of functions in the 
1183 +   header file 
1184 +*/
1185 +static  void
1186 +pargdef(definition *def)
1187 +{
1188 +       decl_list *l;
1189 +       version_list *vers;
1190 +       char *name;
1191 +       proc_list *plist;
1192 +
1193 +       
1194 +       for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) {
1195 +                       for(plist = vers->procs; plist != NULL; 
1196 +                           plist = plist->next) {
1197 +                               
1198 +                               if (!newstyle || plist->arg_num < 2) {
1199 +                                       continue; /* old style or single args */
1200 +                               }
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" );
1206 +                               }
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" );
1211 +                       }
1212 +               }
1213 +
1214 +}
1215 +
1216 +
1217 +static void
1218 +pstructdef(definition *def)
1219 +{
1220 +       decl_list *l;
1221 +       char *name = def->def_name;
1222 +
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");
1226 +       }
1227 +       f_print(fout, "};\n");
1228 +       f_print(fout, "typedef struct %s %s;\n", name, name);
1229 +}
1230 +
1231 +static void
1232 +puniondef(definition *def)
1233 +{
1234 +       case_list      *l;
1235 +       char           *name = def->def_name;
1236 +       declaration    *decl;
1237 +
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);
1242 +       } else {
1243 +               f_print(fout, "\t%s %s;\n", decl->type, decl->name);
1244 +       }
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");
1249 +       }
1250 +       decl = def->def.un.default_decl;
1251 +       if (decl && !streq(decl->type, "void")) {
1252 +               pdeclaration(name, decl, 2, ";\n");
1253 +       }
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);
1257 +}
1258 +
1259 +static void
1260 +pdefine(char *name, char *num)
1261 +{
1262 +       f_print(fout, "#define %s %s\n", name, num);
1263 +}
1264 +
1265 +static void
1266 +puldefine(char *name, char *num)
1267 +{
1268 +       f_print(fout, "#define %s ((u_int32_t)%s)\n", name, num);
1269 +}
1270 +
1271 +static int
1272 +define_printed(proc_list *stop, version_list *start)
1273 +{
1274 +       version_list *vers;
1275 +       proc_list *proc;
1276 +
1277 +       for (vers = start; vers != NULL; vers = vers->next) {
1278 +               for (proc = vers->procs; proc != NULL; proc = proc->next) {
1279 +                       if (proc == stop) {
1280 +                               return (0);
1281 +                       } else if (streq(proc->proc_name, stop->proc_name)) {
1282 +                               return (1);
1283 +                       }
1284 +               }
1285 +       }
1286 +       abort();
1287 +       /* NOTREACHED */
1288 +}
1289 +
1290 +static void
1291 +pprogramdef(definition *def)
1292 +{
1293 +       version_list   *vers;
1294 +       proc_list      *proc;
1295 +       int             i;
1296 +       char           *ext;
1297 +
1298 +       pargdef(def);
1299 +
1300 +       puldefine(def->def_name, def->def.pr.prog_num);
1301 +       for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) {
1302 +               if (tblflag) {
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);
1307 +               }
1308 +               puldefine(vers->vers_name, vers->vers_num);
1309 +
1310 +               /*
1311 +                * Print out 3 definitions, one for ANSI-C, another for C++,
1312 +                * a third for old style C
1313 +                */
1314 +
1315 +               for (i = 0; i < 3; i++) {
1316 +                       if (i == 0) {
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");
1321 +                               ext = "extern  ";
1322 +                       } else {
1323 +                               f_print(fout, "\n#else /* Old Style C */ \n");
1324 +                               ext = "extern  ";
1325 +                       }
1326 +
1327 +
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);
1331 +                               }
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);
1336 +
1337 +                       }
1338 +
1339 +               }
1340 +               f_print(fout, "#endif /* Old Style C */ \n");
1341 +       }
1342 +}
1343 +
1344 +static void
1345 +pprocdef(proc_list *proc, version_list *vp, char *addargtype,
1346 +                               int server_p, int mode)
1347 +{
1348 +       ptype(proc->res_prefix, proc->res_type, 1);
1349 +       f_print(fout, "* ");
1350 +       if (server_p)
1351 +               pvname_svc(proc->proc_name, vp->vers_num);
1352 +       else
1353 +               pvname(proc->proc_name, vp->vers_num);
1354 +
1355 +       /*
1356 +        * mode  0 == cplusplus, mode  1 = ANSI-C, mode 2 = old style C
1357 +        */
1358 +       if (mode == 0 || mode == 1)
1359 +               parglist(proc, addargtype);
1360 +       else
1361 +               f_print(fout, "();\n");
1362 +}
1363 +
1364 +
1365 +
1366 +/* print out argument list of procedure */
1367 +static void
1368 +parglist(proc_list *proc, char *addargtype)
1369 +{
1370 +       decl_list      *dl;
1371 +
1372 +       f_print(fout, "(");
1373 +
1374 +       if (proc->arg_num < 2 && newstyle &&
1375 +               streq(proc->args.decls->decl.type, "void")) {
1376 +               /* 0 argument in new style:  do nothing */
1377 +       } else {
1378 +               for (dl = proc->args.decls; dl != NULL; dl = dl->next) {
1379 +                       ptype(dl->decl.prefix, dl->decl.type, 1);
1380 +                       if (!newstyle)
1381 +                               f_print(fout, "*");     /* old style passes by reference */
1382 +
1383 +                       f_print(fout, ", ");
1384 +               }
1385 +       }
1386 +
1387 +       f_print(fout, "%s);\n", addargtype);
1388 +}
1389 +
1390 +static void
1391 +penumdef(definition *def)
1392 +{
1393 +       char *name = def->def_name;
1394 +       enumval_list *l;
1395 +       char *last = NULL;
1396 +       int count = 0;
1397 +
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;
1404 +                       count = 1;
1405 +               } else {
1406 +                       if (last == NULL) {
1407 +                               f_print(fout, " = %d", count++);
1408 +                       } else {
1409 +                               f_print(fout, " = %s + %d", last, count++);
1410 +                       }
1411 +               }
1412 +               f_print(fout, ",\n");
1413 +       }
1414 +       f_print(fout, "};\n");
1415 +       f_print(fout, "typedef enum %s %s;\n", name, name);
1416 +}
1417 +
1418 +static void
1419 +ptypedef(definition *def)
1420 +{
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;
1425 +
1426 +
1427 +       if (!streq(name, old)) {
1428 +               if (streq(old, "string")) {
1429 +                       old = "char";
1430 +                       rel = REL_POINTER;
1431 +               } else if (streq(old, "opaque")) {
1432 +                       old = "char";
1433 +               } else if (streq(old, "bool")) {
1434 +                       old = "bool_t";
1435 +               }
1436 +               if (undefined2(old, name) && def->def.ty.old_prefix) {
1437 +                       s_print(prefix, "%s ", def->def.ty.old_prefix);
1438 +               } else {
1439 +                       prefix[0] = 0;
1440 +               }
1441 +               f_print(fout, "typedef ");
1442 +               switch (rel) {
1443 +               case REL_ARRAY:
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);
1448 +                       break;
1449 +               case REL_POINTER:
1450 +                       f_print(fout, "%s%s *%s", prefix, old, name);
1451 +                       break;
1452 +               case REL_VECTOR:
1453 +                       f_print(fout, "%s%s %s[%s]", prefix, old, name,
1454 +                               def->def.ty.array_max);
1455 +                       break;
1456 +               case REL_ALIAS:
1457 +                       f_print(fout, "%s%s %s", prefix, old, name);
1458 +                       break;
1459 +               }
1460 +               f_print(fout, ";\n");
1461 +       }
1462 +}
1463 +
1464 +void
1465 +pdeclaration(char *name, declaration *dec, int tab, char *separator)
1466 +{
1467 +       char buf[8];    /* enough to hold "struct ", include NUL */
1468 +       char *prefix;
1469 +       char *type;
1470 +
1471 +       if (streq(dec->type, "void")) {
1472 +               return;
1473 +       }
1474 +       tabify(fout, tab);
1475 +       if (streq(dec->type, name) && !dec->prefix) {
1476 +               f_print(fout, "struct ");
1477 +       }
1478 +       if (streq(dec->type, "string")) {
1479 +               f_print(fout, "char *%s", dec->name);
1480 +       } else {
1481 +               prefix = "";
1482 +               if (streq(dec->type, "bool")) {
1483 +                       type = "bool_t";
1484 +               } else if (streq(dec->type, "opaque")) {
1485 +                       type = "char";
1486 +               } else {
1487 +                       if (dec->prefix) {
1488 +                               s_print(buf, "%s ", dec->prefix);
1489 +                               prefix = buf;
1490 +                       }
1491 +                       type = dec->type;
1492 +               }
1493 +               switch (dec->rel) {
1494 +               case REL_ALIAS:
1495 +                       f_print(fout, "%s%s %s", prefix, type, dec->name);
1496 +                       break;
1497 +               case REL_VECTOR:
1498 +                       f_print(fout, "%s%s %s[%s]", prefix, type, dec->name,
1499 +                               dec->array_max);
1500 +                       break;
1501 +               case REL_POINTER:
1502 +                       f_print(fout, "%s%s *%s", prefix, type, dec->name);
1503 +                       break;
1504 +               case REL_ARRAY:
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);
1512 +                       break;
1513 +               }
1514 +       }
1515 +       f_print(fout, separator );
1516 +}
1517 +
1518 +static int
1519 +undefined2(char *type, char *stop)
1520 +{
1521 +       list *l;
1522 +       definition *def;
1523 +
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)) {
1528 +                               return (1);
1529 +                       } else if (streq(def->def_name, type)) {
1530 +                               return (0);
1531 +                       }
1532 +               }
1533 +       }
1534 +       return (1);
1535 +}
1536 diff --git a/rpcgen/rpc_main.c b/rpcgen/rpc_main.c
1537 new file mode 100644
1538 index 0000000..28aa60c
1539 --- /dev/null
1540 +++ b/rpcgen/rpc_main.c
1541 @@ -0,0 +1,1067 @@
1542 +/*
1543 + * Copyright (c) 2009, Sun Microsystems, Inc.
1544 + * All rights reserved.
1545 + *
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.
1556 + *
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.
1568 + */
1569 +
1570 +#if 0
1571 +static char sccsid[] = "@(#)rpc_main.c 1.30 89/03/30 (C) 1987 SMI";
1572 +#endif
1573 +
1574 +/*
1575 + * rpc_main.c, Top level of the RPC protocol compiler. 
1576 + */
1577 +
1578 +#include <sys/types.h>
1579 +#include <sys/param.h>
1580 +#include <sys/file.h>
1581 +#include <sys/stat.h>
1582 +#include <stdio.h>
1583 +#include <string.h>
1584 +#include <stdlib.h>
1585 +#include <unistd.h>
1586 +#include <ctype.h>
1587 +#include <errno.h>
1588 +#include "rpc_parse.h"
1589 +#include "rpc_util.h"
1590 +#include "rpc_scan.h"
1591 +
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 */
1604 +};
1605 +
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);
1630 +
1631 +/*
1632 +extern void  write_sample_svc();
1633 +int write_sample_clnt();
1634 +void write_sample_clnt_main();
1635 +
1636 +static svc_output();
1637 + */
1638 +
1639 +#define EXTEND 1               /* alias for TRUE */
1640 +#define DONT_EXTEND    0               /* alias for FALSE */
1641 +
1642 +#define SVR4_CPP "/usr/ccs/lib/cpp"
1643 +#define SUNOS_CPP "/lib/cpp"
1644 +static int cppDefined = 0;          /* explicit path for C preprocessor */
1645 +
1646 +
1647 +static char *cmdname;
1648 +
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",
1655 +};
1656 +static int allc = sizeof(allv)/sizeof(allv[0]);
1657 +static char *allnv[] = {
1658 +       "rpcgen", "-s", "netpath",
1659 +};
1660 +static int allnc = sizeof(allnv)/sizeof(allnv[0]);
1661 +
1662 +/*
1663 + * machinations for handling expanding argument list
1664 + */
1665 +#if 0
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 */
1670 +#endif
1671 +
1672 +
1673 +
1674 +#define ARGLISTLEN     20
1675 +#define FIXEDARGS         2
1676 +
1677 +static char *arglist[ARGLISTLEN];
1678 +static int argcount = FIXEDARGS;
1679 +
1680 +
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 */
1686 +
1687 +/* length at which to start doing an inline */
1688 +#define INLINE 3
1689 +
1690 +int Inline = INLINE;   /* length at which to start doing an inline. 3 = default
1691 +                        * if 0, no xdr_inline code */
1692 +
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 */
1699 +#ifdef linux
1700 +int tirpcflag = 0;     /* no tirpc by default */
1701 +#else
1702 +int tirpcflag = 1;      /* generating code for tirpc, by default */
1703 +#endif
1704 +
1705 +int
1706 +main(int argc, char **argv)
1707 +{
1708 +       struct commandline cmd;
1709 +
1710 +       (void) memset((char *) &cmd, 0, sizeof(struct commandline));
1711 +       clear_args();
1712 +       if (!parseargs(argc, argv, &cmd))
1713 +               usage();
1714 +
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);
1718 +       } else
1719 +               checkfiles(cmd.infile, NULL);
1720 +
1721 +       if (cmd.cflag) {
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);
1736 +       } else {
1737 +               /* the rescans are required, since cpp may effect input */
1738 +               c_output(cmd.infile, "-DRPC_XDR", EXTEND, "_xdr.c");
1739 +               reinitialize();
1740 +               h_output(cmd.infile, "-DRPC_HDR", EXTEND, ".h");
1741 +               reinitialize();
1742 +               l_output(cmd.infile, "-DRPC_CLNT", EXTEND, "_clnt.c");
1743 +               reinitialize();
1744 +               if (inetdflag || !tirpcflag)
1745 +                       s_output(allc, allv, cmd.infile, "-DRPC_SVC", EXTEND,
1746 +                               "_svc.c", cmd.mflag, cmd.nflag);
1747 +               else
1748 +                       s_output(allnc, allnv, cmd.infile, "-DRPC_SVC",
1749 +                               EXTEND, "_svc.c", cmd.mflag, cmd.nflag);
1750 +               if (tblflag) {
1751 +                       reinitialize();
1752 +                       t_output(cmd.infile, "-DRPC_TBL", EXTEND, "_tbl.i");
1753 +               }
1754 +               if (allfiles) {
1755 +                       reinitialize();
1756 +                       svc_output(cmd.infile, "-DRPC_SERVER", EXTEND, "_server.c");
1757 +               }
1758 +               if (allfiles) {
1759 +                       reinitialize();
1760 +                       clnt_output(cmd.infile, "-DRPC_CLIENT", EXTEND, "_client.c");
1761 +               }
1762 +       }
1763 +       exit(nonfatalerrors);
1764 +       /* NOTREACHED */
1765 +}
1766 +
1767 +/*
1768 + * add extension to filename 
1769 + */
1770 +static char *
1771 +extendfile(char *file, char *ext)
1772 +{
1773 +       char *res;
1774 +       char *p;
1775 +
1776 +       res = alloc(strlen(file) + strlen(ext) + 1);
1777 +       if (res == NULL) {
1778 +               abort();
1779 +       }
1780 +       p = strrchr(file, '.');
1781 +       if (p == NULL) {
1782 +               p = file + strlen(file);
1783 +       }
1784 +       (void) strcpy(res, file);
1785 +       (void) strcpy(res + (p - file), ext);
1786 +       return (res);
1787 +}
1788 +
1789 +/*
1790 + * Open output file with given extension 
1791 + */
1792 +static void
1793 +open_output(char *infile, char *outfile)
1794 +{
1795 +
1796 +       if (outfile == NULL) {
1797 +               fout = stdout;
1798 +               return;
1799 +       }
1800 +
1801 +       if (infile != NULL && streq(outfile, infile)) {
1802 +               f_print(stderr, "%s: output would overwrite %s\n", cmdname,
1803 +                       infile);
1804 +               crash();
1805 +       }
1806 +       fout = fopen(outfile, "w");
1807 +       if (fout == NULL) {
1808 +               f_print(stderr, "%s: unable to open ", cmdname);
1809 +               perror(outfile);
1810 +               crash();
1811 +       }
1812 +       record_open(outfile);
1813 +
1814 +}
1815 +
1816 +static void
1817 +add_warning(void)
1818 +{
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");
1823 +}
1824 +
1825 +/* clear list of arguments */
1826 +static void
1827 +clear_args(void)
1828 +{
1829 +  int i;
1830 +  for( i=FIXEDARGS; i<ARGLISTLEN; i++ )
1831 +    arglist[i] = NULL;
1832 +  argcount = FIXEDARGS;
1833 +}
1834 +
1835 +/*
1836 + * Open input file with given define for C-preprocessor 
1837 + */
1838 +static void
1839 +open_input(char *infile, char *define)
1840 +{
1841 +       int pd[2];
1842 +
1843 +       infilename = (infile == NULL) ? "<stdin>" : infile;
1844 +       (void) pipe(pd);
1845 +       switch (fork()) {
1846 +       case 0:
1847 +               putarg(0, "cpp");
1848 +               putarg(1, CPPFLAGS);
1849 +               addarg(define);
1850 +               addarg(infile);
1851 +               addarg((char *)NULL);
1852 +               (void) close(1);
1853 +               (void) dup2(pd[1], 1);
1854 +               (void) close(pd[0]);
1855 +               if (cppDefined)
1856 +                       execv(CPP, arglist);
1857 +               else {
1858 +                       execvp("cpp", arglist);
1859 +                       if (errno == ENOENT)
1860 +                               execvp(SVR4_CPP, arglist);
1861 +                       if (errno == ENOENT)
1862 +                               execvp(SUNOS_CPP, arglist);
1863 +               }
1864 +               perror("execv");
1865 +               exit(1);
1866 +       case -1:
1867 +               perror("fork");
1868 +               exit(1);
1869 +       }
1870 +       (void) close(pd[1]);
1871 +       fin = fdopen(pd[0], "r");
1872 +       if (fin == NULL) {
1873 +               f_print(stderr, "%s: ", cmdname);
1874 +               perror(infilename);
1875 +               crash();
1876 +       }
1877 +}
1878 +
1879 +/* valid tirpc nettypes */
1880 +static char*   valid_ti_nettypes[] =
1881 +{
1882 +       "netpath",
1883 +       "visible",
1884 +       "circuit_v",
1885 +       "datagram_v",
1886 +       "circuit_n",
1887 +       "datagram_n",
1888 +       "udp",
1889 +       "tcp",
1890 +       "raw",
1891 +       NULL
1892 +};
1893 +
1894 +/* valid inetd nettypes */
1895 +static char* valid_i_nettypes[] =
1896 +{
1897 +       "udp",
1898 +       "tcp",
1899 +       NULL
1900 +};
1901 +
1902 +static int
1903 +check_nettype(char *name, char **list_to_check)
1904 +{
1905 +  int i;
1906 +  for( i = 0; list_to_check[i] != NULL; i++ ) {
1907 +         if( strcmp( name, list_to_check[i] ) == 0 ) {
1908 +           return 1;
1909 +         }
1910 +  }
1911 +  f_print( stderr, "illegal nettype :\'%s\'\n", name );
1912 +  return 0;
1913 +}
1914 +
1915 +/*
1916 + * Compile into an XDR routine output file
1917 + */
1918 +
1919 +static void
1920 +c_output(char *infile, char *define, int extend, char *outfile)
1921 +{
1922 +       definition *def;
1923 +       char *include;
1924 +       char *outfilename;
1925 +       long tell;
1926 +
1927 +       c_initialize();
1928 +       open_input(infile, define);     
1929 +       outfilename = extend ? extendfile(infile, outfile) : outfile;
1930 +       open_output(infile, outfilename);
1931 +       add_warning();
1932 +       if (infile && (include = extendfile(infile, ".h"))) {
1933 +               f_print(fout, "#include \"%s\"\n", include);
1934 +               free(include);
1935 +               /* .h file already contains rpc/rpc.h */
1936 +       } else
1937 +         f_print(fout, "#include <rpc/rpc.h>\n");
1938 +       tell = ftell(fout);
1939 +       while ((def = get_definition()) != NULL) {
1940 +               emit(def);
1941 +       }
1942 +       if (extend && tell == ftell(fout)) {
1943 +               (void) unlink(outfilename);
1944 +       }
1945 +}
1946 +
1947 +
1948 +static void
1949 +c_initialize(void)
1950 +{
1951 +
1952 +  /* add all the starting basic types */
1953 +
1954 +  add_type(1,"int");
1955 +  add_type(1,"int32_t");
1956 +  add_type(1,"short");
1957 +  add_type(1,"bool");
1958 +
1959 +  add_type(1,"u_int");
1960 +  add_type(1,"u_int32_t");
1961 +  add_type(1,"u_short");
1962 +
1963 +}
1964 +
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\
1971 +};\n";
1972 +
1973 +
1974 +static char *
1975 +generate_guard(char *pathname)
1976 +{
1977 +        char* filename, *guard, *tmp;
1978 +
1979 +       filename = strrchr(pathname, '/' );  /* find last component */
1980 +       filename = ((filename == 0) ? pathname : filename+1);
1981 +       guard = strdup(filename);
1982 +       /* convert to upper case */
1983 +       tmp = guard;
1984 +       while (*tmp) {
1985 +               if (islower(*tmp))
1986 +                       *tmp = toupper(*tmp);
1987 +               tmp++;
1988 +       }
1989 +               
1990 +       guard = extendfile(guard, "_H_RPCGEN");
1991 +       return( guard );
1992 +}
1993 +
1994 +/*
1995 + * Compile into an XDR header file
1996 + */
1997 +static void
1998 +h_output(char *infile, char *define, int extend, char *outfile)
1999 +{
2000 +       definition *def;
2001 +       char *outfilename;
2002 +       long tell;
2003 +       char *guard;
2004 +       list *l;
2005 +
2006 +       open_input(infile, define);
2007 +       outfilename =  extend ? extendfile(infile, outfile) : outfile;
2008 +       open_output(infile, outfilename);
2009 +       add_warning();
2010 +       guard = generate_guard(  outfilename ? outfilename: infile );
2011 +
2012 +       f_print(fout,"#ifndef _%s\n#define _%s\n\n", guard,
2013 +               guard);
2014 +
2015 +       f_print(fout, "#include <rpc/rpc.h>\n\n");
2016 +
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");
2029 +
2030 +       tell = ftell(fout);
2031 +       /* print data definitions */
2032 +       while ((def = get_definition()) != NULL) {
2033 +               print_datadef(def);
2034 +       }
2035 +
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);
2041 +       }
2042 +       if (extend && tell == ftell(fout)) {
2043 +               (void) unlink(outfilename);
2044 +       } else if (tblflag) {
2045 +               f_print(fout, rpcgen_table_dcl);
2046 +       }
2047 +       f_print(fout, "\n#endif /* !_%s */\n", guard);
2048 +}
2049 +
2050 +/*
2051 + * Compile into an RPC service
2052 + */
2053 +static void
2054 +s_output(int argc, char **argv, char *infile, char *define, int extend,
2055 +                       char *outfile, int nomain, int netflag)
2056 +{
2057 +       char *include;
2058 +       definition *def;
2059 +       int foundprogram = 0;
2060 +       char *outfilename;
2061 +
2062 +       open_input(infile, define);
2063 +       outfilename = extend ? extendfile(infile, outfile) : outfile;
2064 +       open_output(infile, outfilename);
2065 +       add_warning();
2066 +       if (infile && (include = extendfile(infile, ".h"))) {
2067 +               f_print(fout, "#include \"%s\"\n", include);
2068 +               free(include);
2069 +       } else
2070 +         f_print(fout, "#include <rpc/rpc.h>\n");
2071 +
2072 +       f_print(fout, "#include <stdio.h>\n");
2073 +       f_print(fout, "#include <stdlib.h>/* getenv, exit */\n"); 
2074 +       if (Cflag) {
2075 +               f_print (fout, "#include <rpc/pmap_clnt.h> /* for pmap_unset */\n");
2076 +               f_print (fout, "#include <string.h> /* strcmp */ \n"); 
2077 +       }
2078 +       if (strcmp(svcclosetime, "-1") == 0)
2079 +               indefinitewait = 1;
2080 +       else if (strcmp(svcclosetime, "0") == 0)
2081 +               exitnow = 1;
2082 +       else if (inetdflag || pmflag) {
2083 +               f_print(fout, "#include <signal.h>\n");
2084 +         timerflag = 1;
2085 +       }
2086 +
2087 +#ifndef linux
2088 +       if( !tirpcflag && inetdflag )
2089 +         f_print(fout, "#include <sys/ttycom.h>/* TIOCNOTTY */\n");
2090 +#else
2091 +       if( !tirpcflag )
2092 +         f_print(fout, "#include <sys/ioctl.h>/* TIOCNOTTY */\n");
2093 +#endif
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");
2098 +         
2099 +         if( tirpcflag )
2100 +           f_print(fout, "#include <unistd.h> /* setsid */\n");
2101 +       }
2102 +       if( tirpcflag )
2103 +         f_print(fout, "#include <sys/types.h>\n");
2104 +
2105 +       f_print(fout, "#include <memory.h>\n");
2106 +#ifndef linux
2107 +       f_print(fout, "#include <stropts.h>\n");
2108 +#endif
2109 +       if (inetdflag || !tirpcflag ) {
2110 +               f_print(fout, "#include <sys/socket.h>\n");
2111 +               f_print(fout, "#include <netinet/in.h>\n");
2112 +       } 
2113 +
2114 +       if ( (netflag || pmflag) && tirpcflag ) {
2115 +               f_print(fout, "#include <netconfig.h>\n");
2116 +       }
2117 +       if (/*timerflag &&*/ tirpcflag)
2118 +               f_print(fout, "#include <sys/resource.h> /* rlimit */\n");
2119 +       if (logflag || inetdflag || pmflag) {
2120 +#ifdef linux
2121 +               f_print(fout, "#include <syslog.h>\n");
2122 +#else
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");
2129 +#endif
2130 +       }
2131 +
2132 +       /* for ANSI-C */
2133 +       f_print(fout, "\n#ifdef __STDC__\n#define SIG_PF void(*)(int)\n#endif\n");
2134 +
2135 +       f_print(fout, "\n#ifdef DEBUG\n#define RPC_SVC_FG\n#endif\n");
2136 +       if (timerflag)
2137 +               f_print(fout, "\n#define _RPCSVC_CLOSEDOWN %s\n", svcclosetime);
2138 +       while ((def = get_definition()) != NULL) {
2139 +               foundprogram |= (def->def_kind == DEF_PROGRAM);
2140 +       }
2141 +       if (extend && !foundprogram) {
2142 +               (void) unlink(outfilename);
2143 +               return;
2144 +       }
2145 +       write_most(infile, netflag, nomain);
2146 +       if (!nomain) {
2147 +               if( !do_registers(argc, argv) ) {
2148 +                 if (outfilename)
2149 +                   (void) unlink(outfilename);
2150 +                 usage();
2151 +               }
2152 +               write_rest();
2153 +       }
2154 +}
2155 +
2156 +/*
2157 + * generate client side stubs
2158 + */
2159 +static void
2160 +l_output(char *infile, char *define, int extend, char *outfile)
2161 +{
2162 +       char *include;
2163 +       definition *def;
2164 +       int foundprogram = 0;
2165 +       char *outfilename;
2166 +
2167 +       open_input(infile, define);
2168 +       outfilename = extend ? extendfile(infile, outfile) : outfile;
2169 +       open_output(infile, outfilename);
2170 +       add_warning();
2171 +       if (Cflag)
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);
2175 +               free(include);
2176 +       } else
2177 +         f_print(fout, "#include <rpc/rpc.h>\n");
2178 +       while ((def = get_definition()) != NULL) {
2179 +               foundprogram |= (def->def_kind == DEF_PROGRAM);
2180 +       }
2181 +       if (extend && !foundprogram) {
2182 +               (void) unlink(outfilename);
2183 +               return;
2184 +       }
2185 +       write_stubs();
2186 +}
2187 +
2188 +/*
2189 + * generate the dispatch table
2190 + */
2191 +static void
2192 +t_output(char *infile, char *define, int extend, char *outfile)
2193 +{
2194 +       definition *def;
2195 +       int foundprogram = 0;
2196 +       char *outfilename;
2197 +
2198 +       open_input(infile, define);
2199 +       outfilename = extend ? extendfile(infile, outfile) : outfile;
2200 +       open_output(infile, outfilename);
2201 +       add_warning();
2202 +       while ((def = get_definition()) != NULL) {
2203 +               foundprogram |= (def->def_kind == DEF_PROGRAM);
2204 +       }
2205 +       if (extend && !foundprogram) {
2206 +               (void) unlink(outfilename);
2207 +               return;
2208 +       }
2209 +       write_tables();
2210 +}
2211 +
2212 +/* sample routine for the server template */
2213 +static  void
2214 +svc_output(char *infile, char *define, int extend, char *outfile)
2215 +{
2216 +  definition *def;
2217 +  char *include;
2218 +  char *outfilename;
2219 +  long tell;
2220 +  
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);
2226 +  add_sample_msg();
2227 +
2228 +  if (infile && (include = extendfile(infile, ".h"))) {
2229 +    f_print(fout, "#include \"%s\"\n", include);
2230 +    free(include);
2231 +  } else
2232 +    f_print(fout, "#include <rpc/rpc.h>\n");
2233 +
2234 +  tell = ftell(fout);
2235 +  while ((def = get_definition()) != NULL) {
2236 +         write_sample_svc(def);
2237 +  }
2238 +  if (extend && tell == ftell(fout)) {
2239 +         (void) unlink(outfilename);
2240 +  }
2241 +}
2242 +
2243 +
2244 +/* sample main routine for client */
2245 +static  void
2246 +clnt_output(char *infile, char *define, int extend, char *outfile)
2247 +{
2248 +       definition     *def;
2249 +       char           *include;
2250 +       char           *outfilename;
2251 +       long            tell;
2252 +       int             has_program = 0;
2253 +
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*/
2258 +
2259 +       open_output(infile, outfilename);
2260 +       add_sample_msg();
2261 +       if (infile && (include = extendfile(infile, ".h"))) {
2262 +               f_print(fout, "#include \"%s\"\n", include);
2263 +               free(include);
2264 +       } else
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);
2269 +       }
2270 +
2271 +       if (has_program)
2272 +               write_sample_clnt_main();
2273 +
2274 +       if (extend && tell == ftell(fout)) {
2275 +               (void) unlink(outfilename);
2276 +       }
2277 +}
2278 +
2279 +/*
2280 + * Perform registrations for service output 
2281 + * Return 0 if failed; 1 otherwise.
2282 + */
2283 +static int
2284 +do_registers(int argc, char **argv)
2285 +{
2286 +       int             i;
2287 +
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))
2292 +                                       return 0;
2293 +                               write_inetd_register(argv[i + 1]);
2294 +                               i++;
2295 +                       }
2296 +               }
2297 +       } else {
2298 +               for (i = 1; i < argc; i++)
2299 +                       if (streq(argv[i], "-s")) {
2300 +                               if (!check_nettype(argv[i + 1], valid_ti_nettypes))
2301 +                                       return 0;
2302 +                               write_nettype_register(argv[i + 1]);
2303 +                               i++;
2304 +                       } else if (streq(argv[i], "-n")) {
2305 +                               write_netid_register(argv[i + 1]);
2306 +                               i++;
2307 +                       }
2308 +       }
2309 +       return 1;
2310 +}
2311 +
2312 +/*
2313 + * Add another argument to the arg list
2314 + */
2315 +static void
2316 +addarg(char *cp)
2317 +{
2318 +       if (argcount >= ARGLISTLEN) {
2319 +               f_print(stderr, "rpcgen: too many defines\n");
2320 +               crash();
2321 +               /*NOTREACHED*/
2322 +       }
2323 +       arglist[argcount++] = cp;
2324 +
2325 +}
2326 +
2327 +static void
2328 +putarg(int where, char *cp)
2329 +{
2330 +       if (where >= ARGLISTLEN) {
2331 +               f_print(stderr, "rpcgen: arglist coding error\n");
2332 +               crash();
2333 +               /*NOTREACHED*/
2334 +       }
2335 +       arglist[where] = cp;
2336 +       
2337 +}
2338 +
2339 +/*
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 
2343 + */
2344 +
2345 +static void
2346 +checkfiles(char *infile, char *outfile) 
2347 +{
2348 +
2349 +  struct stat buf;
2350 +
2351 +  if(infile)                   /* infile ! = NULL */
2352 +    if(stat(infile,&buf) < 0)
2353 +      {
2354 +       perror(infile);
2355 +       crash();
2356 +      };
2357 +  if (outfile) {
2358 +    if (stat(outfile, &buf) < 0) 
2359 +      return;                  /* file does not exist */
2360 +    else {
2361 +      f_print(stderr, 
2362 +             "file '%s' already exists and may be overwritten\n", outfile);
2363 +      crash();
2364 +    }
2365 +  }
2366 +}
2367 +
2368 +/*
2369 + * Parse command line arguments 
2370 + */
2371 +static int
2372 +parseargs(int argc, char **argv, struct commandline *cmd)
2373 +{
2374 +       int i;
2375 +       int j;
2376 +       char c;
2377 +       char flag[(1 << 8 * sizeof(char))];
2378 +       int nflags;
2379 +
2380 +       cmdname = argv[0];
2381 +       cmd->infile = cmd->outfile = NULL;
2382 +       if (argc < 2) {
2383 +               return (0);
2384 +       }
2385 +       allfiles = 0;
2386 +       flag['c'] = 0;
2387 +       flag['h'] = 0;
2388 +       flag['l'] = 0;
2389 +       flag['m'] = 0;
2390 +       flag['o'] = 0;
2391 +       flag['s'] = 0;
2392 +       flag['n'] = 0;
2393 +       flag['t'] = 0;
2394 +       flag['S'] = 0;
2395 +       flag['C'] = 0;
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");
2400 +
2401 +                               return (0);
2402 +                       }
2403 +                       cmd->infile = argv[i];
2404 +               } else {
2405 +                       for (j = 1; argv[i][j] != 0; j++) {
2406 +                               c = argv[i][j];
2407 +                               switch (c) {
2408 +                               case 'a':
2409 +                                       allfiles = 1;
2410 +                                       break;
2411 +                               case 'c':
2412 +                               case 'h':
2413 +                               case 'l':
2414 +                               case 'm':
2415 +                               case 't':
2416 +                                       if (flag[(int) c]) {
2417 +                                               return (0);
2418 +                                       }
2419 +                                       flag[(int) c] = 1;
2420 +                                       break;
2421 +                               case 'S':  
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 */
2426 +                                       if( c == 's' )
2427 +                                         c = 'S';
2428 +                                       else if( c == 'c' )
2429 +                                         c = 'C';
2430 +                                       else
2431 +                                         return( 0 );
2432 +
2433 +                                       if (flag[(int) c]) {
2434 +                                               return (0);
2435 +                                       }
2436 +                                       flag[(int) c] = 1;
2437 +                                       break;
2438 +                               case 'C':  /* ANSI C syntax */
2439 +                                       Cflag = 1;
2440 +                                       break;
2441 +
2442 +                               case 'b':  /* turn TIRPC flag off for
2443 +                                           generating backward compatible
2444 +                                           */
2445 +                                       tirpcflag = 0;
2446 +                                       break;
2447 +
2448 +                               case 'I':
2449 +                                       inetdflag = 1;
2450 +                                       break;
2451 +                               case 'N':
2452 +                                       newstyle = 1;
2453 +                                       break;
2454 +                               case 'L':
2455 +                                       logflag = 1;
2456 +                                       break;
2457 +                               case 'K':
2458 +                                       if (++i == argc) {
2459 +                                               return (0);
2460 +                                       }
2461 +                                       svcclosetime = argv[i];
2462 +                                       goto nextarg;
2463 +                               case 'T':
2464 +                                       tblflag = 1;
2465 +                                       break;
2466 +                               case 'i' :
2467 +                                       if (++i == argc) {
2468 +                                               return (0);
2469 +                                       }
2470 +                                       Inline = atoi(argv[i]);
2471 +                                       goto nextarg;
2472 +                               case 'n':
2473 +                               case 'o':
2474 +                               case 's':
2475 +                                       if (argv[i][j - 1] != '-' || 
2476 +                                           argv[i][j + 1] != 0) {
2477 +                                               return (0);
2478 +                                       }
2479 +                                       flag[(int) c] = 1;
2480 +                                       if (++i == argc) {
2481 +                                               return (0);
2482 +                                       }
2483 +                                       if (c == 's') {
2484 +                                               if (!streq(argv[i], "udp") &&
2485 +                                                   !streq(argv[i], "tcp")) {
2486 +                                                       return (0);
2487 +                                               }
2488 +                                       } else if (c == 'o') {
2489 +                                               if (cmd->outfile) {
2490 +                                                       return (0);
2491 +                                               }
2492 +                                               cmd->outfile = argv[i];
2493 +                                       }
2494 +                                       goto nextarg;
2495 +                               case 'D':
2496 +                                       if (argv[i][j - 1] != '-') {
2497 +                                               return (0);
2498 +                                       }
2499 +                                       (void) addarg(argv[i]);
2500 +                                       goto nextarg;
2501 +                               case 'Y':
2502 +                                       if (++i == argc) {
2503 +                                               return (0);
2504 +                                       }
2505 +                                       (void) strcpy(pathbuf, argv[i]);
2506 +                                       (void) strcat(pathbuf, "/cpp");
2507 +                                       CPP = pathbuf;
2508 +                                       cppDefined = 1;
2509 +                                       goto nextarg;
2510 +
2511 +
2512 +
2513 +                               default:
2514 +                                       return (0);
2515 +                               }
2516 +                       }
2517 +       nextarg:
2518 +                       ;
2519 +               }
2520 +       }
2521 +
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'];
2531 +
2532 +       if( tirpcflag ) {
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");
2536 +           return (0);
2537 +         }
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");
2543 +           return( 0 );
2544 +         }
2545 +       }
2546 +
2547 +       if( newstyle && ( tblflag || cmd->tflag) ) {
2548 +         f_print( stderr, "Cannot use table flags with newstyle!\n");
2549 +         return( 0 );
2550 +       }
2551 +
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;
2555 +
2556 +       if (nflags == 0) {
2557 +               if (cmd->outfile != NULL || cmd->infile == NULL) {
2558 +                       return (0);
2559 +               }
2560 +       } else if (nflags > 1) {
2561 +               f_print( stderr, "Cannot have more than one file generation flag!\n");
2562 +               return (0);
2563 +       }
2564 +       return (1);
2565 +}
2566 +
2567 +static void
2568 +usage(void)
2569 +{
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",
2572 +                       cmdname);
2573 +       f_print(stderr, "\t%s [-c | -h | -l | -m | -t | -Sc | -Ss] [-o outfile] [infile]\n",
2574 +                       cmdname);
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);
2577 +       options_usage();
2578 +       exit(1);
2579 +}
2580 +
2581 +static void
2582 +options_usage(void)
2583 +{
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");
2606 +
2607 +       exit(1);
2608 +}
2609 diff --git a/rpcgen/rpc_output.h b/rpcgen/rpc_output.h
2610 new file mode 100644
2611 index 0000000..eb25a60
2612 --- /dev/null
2613 +++ b/rpcgen/rpc_output.h
2614 @@ -0,0 +1,16 @@
2615 +/*
2616 + * rpc_output.h
2617 + *
2618 + * Declarations for output functions
2619 + *
2620 + */
2621 +
2622 +#ifndef RPCGEN_NEW_OUTPUT_H
2623 +#define RPCGEN_NEW_OUTPUT_H
2624 +
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 *);
2629 +
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
2634 --- /dev/null
2635 +++ b/rpcgen/rpc_parse.c
2636 @@ -0,0 +1,609 @@
2637 +/*
2638 + * Copyright (c) 2009, Sun Microsystems, Inc.
2639 + * All rights reserved.
2640 + *
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.
2651 + *
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.
2663 + */
2664 +
2665 +#if 0
2666 +static char sccsid[] = "@(#)rpc_parse.c 1.8 89/02/22 (C) 1987 SMI";
2667 +#endif
2668 +
2669 +/*
2670 + * rpc_parse.c, Parser for the RPC protocol compiler 
2671 + * Copyright (C) 1987 Sun Microsystems, Inc.
2672 + */
2673 +#include <stdio.h>
2674 +#include <string.h>
2675 +#include "rpc/types.h"
2676 +#include "rpc_scan.h"
2677 +#include "rpc_parse.h"
2678 +#include "rpc_util.h"
2679 +
2680 +#define ARGNAME "arg"
2681 +
2682 +/*
2683 +extern char *make_argname();
2684 +extern char *strdup();
2685 + */
2686 +
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);
2699 +
2700 +/*
2701 + * return the next definition you see
2702 + */
2703 +definition *
2704 +get_definition(void)
2705 +{
2706 +       definition *defp;
2707 +       token tok;
2708 +
2709 +       defp = ALLOC(definition);
2710 +       get_token(&tok);
2711 +       switch (tok.kind) {
2712 +       case TOK_STRUCT:
2713 +               def_struct(defp);
2714 +               break;
2715 +       case TOK_UNION:
2716 +               def_union(defp);
2717 +               break;
2718 +       case TOK_TYPEDEF:
2719 +               def_typedef(defp);
2720 +               break;
2721 +       case TOK_ENUM:
2722 +               def_enum(defp);
2723 +               break;
2724 +       case TOK_PROGRAM:
2725 +               def_program(defp);
2726 +               break;
2727 +       case TOK_CONST:
2728 +               def_const(defp);
2729 +               break;
2730 +       case TOK_EOF:
2731 +               free(defp);
2732 +               return (NULL);
2733 +       default:
2734 +               error("definition keyword expected");
2735 +       }
2736 +       scan(TOK_SEMICOLON, &tok);
2737 +       isdefined(defp);
2738 +       return (defp);
2739 +}
2740 +
2741 +static void
2742 +isdefined(definition *defp)
2743 +{
2744 +       STOREVAL(&defined, defp);
2745 +}
2746 +
2747 +static void
2748 +def_struct(definition *defp)
2749 +{
2750 +       token tok;
2751 +       declaration dec;
2752 +       decl_list *decls;
2753 +       decl_list **tailp;
2754 +
2755 +       defp->def_kind = DEF_STRUCT;
2756 +
2757 +       scan(TOK_IDENT, &tok);
2758 +       defp->def_name = tok.str;
2759 +       scan(TOK_LBRACE, &tok);
2760 +       tailp = &defp->def.st.decls;
2761 +       do {
2762 +               get_declaration(&dec, DEF_STRUCT);
2763 +               decls = ALLOC(decl_list);
2764 +               decls->decl = dec;
2765 +               *tailp = decls;
2766 +               tailp = &decls->next;
2767 +               scan(TOK_SEMICOLON, &tok);
2768 +               peek(&tok);
2769 +       } while (tok.kind != TOK_RBRACE);
2770 +       get_token(&tok);
2771 +       *tailp = NULL;
2772 +}
2773 +
2774 +static void
2775 +def_program(definition *defp)
2776 +{
2777 +       token tok;
2778 +       declaration dec;
2779 +       decl_list *decls;
2780 +       decl_list **tailp;
2781 +       version_list *vlist;
2782 +       version_list **vtailp;
2783 +       proc_list *plist;
2784 +       proc_list **ptailp;
2785 +       int num_args;
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);
2794 +       do {
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;
2800 +               do {
2801 +                       /* get result type */
2802 +                       plist = ALLOC(proc_list);
2803 +                       get_type(&plist->res_prefix, &plist->res_type, 
2804 +                                DEF_PROGRAM);
2805 +                       if (streq(plist->res_type, "opaque")) {
2806 +                               error("illegal result type");
2807 +                       }
2808 +                       scan(TOK_IDENT, &tok);
2809 +                       plist->proc_name = tok.str;
2810 +                       scan(TOK_LPAREN, &tok);
2811 +                       /* get args - first one*/
2812 +                       num_args = 1;
2813 +                       isvoid = FALSE;
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
2817 +                        */
2818 +                       get_prog_declaration(&dec, DEF_PROGRAM, num_args);
2819 +                       if (streq(dec.type, "void"))
2820 +                         isvoid = TRUE;
2821 +                       decls = ALLOC(decl_list);
2822 +                       plist->args.decls = decls;
2823 +                       decls->decl = dec;
2824 +                       tailp = &decls->next;
2825 +                       /* get args */
2826 +                       while(peekscan(TOK_COMMA, &tok)) {
2827 +                         num_args++;
2828 +                         get_prog_declaration(&dec, DEF_STRUCT, 
2829 +                                              num_args);
2830 +                         decls = ALLOC(decl_list);
2831 +                         decls->decl = dec;
2832 +                         *tailp = decls;
2833 +                         if (streq(dec.type, "void"))
2834 +                           isvoid = TRUE;
2835 +                         tailp = &decls->next;
2836 +                       }
2837 +                       /* multiple arguments are only allowed in newstyle */
2838 +                       if( !newstyle && num_args > 1 ) {
2839 +                         error("only one argument is allowed" );
2840 +                       }
2841 +                       if (isvoid && num_args > 1) { 
2842 +                         error("illegal use of void in program definition");
2843 +                       }
2844 +                       *tailp = NULL;
2845 +                       scan(TOK_RPAREN, &tok);
2846 +                       scan(TOK_EQUAL, &tok);
2847 +                       scan_num(&tok);
2848 +                       scan(TOK_SEMICOLON, &tok);
2849 +                       plist->proc_num = tok.str;
2850 +                       plist->arg_num = num_args;
2851 +                       *ptailp = plist;
2852 +                       ptailp = &plist->next;
2853 +                       peek(&tok);
2854 +               } while (tok.kind != TOK_RBRACE);
2855 +               *ptailp = NULL;
2856 +               *vtailp = vlist;
2857 +               vtailp = &vlist->next;
2858 +               scan(TOK_RBRACE, &tok);
2859 +               scan(TOK_EQUAL, &tok);
2860 +               scan_num(&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,
2866 +                                                          vlist->vers_num); 
2867 +                       /* free the memory ??*/
2868 +               }
2869 +               scan(TOK_SEMICOLON, &tok);
2870 +               scan2(TOK_VERSION, TOK_RBRACE, &tok);
2871 +       } while (tok.kind == TOK_VERSION);
2872 +       scan(TOK_EQUAL, &tok);
2873 +       scan_num(&tok);
2874 +       defp->def.pr.prog_num = tok.str;
2875 +       *vtailp = NULL;
2876 +}
2877 +
2878 +
2879 +static void
2880 +def_enum(definition *defp)
2881 +{
2882 +       token tok;
2883 +       enumval_list *elist;
2884 +       enumval_list **tailp;
2885 +
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;
2891 +       do {
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) {
2898 +                       scan_num(&tok);
2899 +                       elist->assignment = tok.str;
2900 +                       scan2(TOK_COMMA, TOK_RBRACE, &tok);
2901 +               }
2902 +               *tailp = elist;
2903 +               tailp = &elist->next;
2904 +       } while (tok.kind != TOK_RBRACE);
2905 +       *tailp = NULL;
2906 +}
2907 +
2908 +static void
2909 +def_const(definition *defp)
2910 +{
2911 +       token tok;
2912 +
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;
2919 +}
2920 +
2921 +static void
2922 +def_union(definition *defp)
2923 +{
2924 +  token tok;
2925 +  declaration dec;
2926 +  case_list *cases;
2927 +  case_list **tailp;
2928 +
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))
2947 +      {
2948 +
2949 +       do 
2950 +         {
2951 +           scan2(TOK_IDENT, TOK_CHARCONST, &tok);
2952 +           cases->contflag=1;  /* continued case statement */
2953 +           *tailp = cases;
2954 +           tailp = &cases->next;
2955 +           cases = ALLOC(case_list);
2956 +           cases->case_name = tok.str;
2957 +           scan(TOK_COLON, &tok);
2958 +      
2959 +         }while(peekscan(TOK_CASE,&tok));
2960 +      }
2961 +
2962 +    get_declaration(&dec, DEF_UNION);
2963 +    cases->case_decl = dec;
2964 +    cases->contflag=0;         /* no continued case statement */
2965 +    *tailp = cases;
2966 +    tailp = &cases->next;
2967 +    scan(TOK_SEMICOLON, &tok);
2968 +
2969 +    scan3(TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok);
2970 +  }
2971 +  *tailp = NULL;
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);
2979 +  } else {
2980 +    defp->def.un.default_decl = NULL;
2981 +  }
2982 +}
2983 +
2984 +static char* reserved_words[] =
2985 +{
2986 +  "array",
2987 +  "bytes",
2988 +  "destroy",
2989 +  "free",
2990 +  "getpos",
2991 +  "inline",
2992 +  "pointer",
2993 +  "reference",
2994 +  "setpos",
2995 +  "sizeof",
2996 +  "union",
2997 +  "vector",
2998 +  NULL
2999 +  };
3000 +
3001 +static char* reserved_types[] =
3002 +{
3003 +  "opaque",
3004 +  "string",
3005 +  NULL
3006 +  };
3007 +
3008 +/* check that the given name is not one that would eventually result in
3009 +   xdr routines that would conflict with internal XDR routines. */
3010 +static void
3011 +check_type_name(char *name, int new_type)
3012 +{
3013 +  int i;
3014 +  char tmp[100];
3015 +
3016 +  for( i = 0; reserved_words[i] != NULL; i++ ) {
3017 +    if( strcmp( name, reserved_words[i] ) == 0 ) {
3018 +      sprintf(tmp, 
3019 +             "illegal (reserved) name :\'%s\' in type definition", name );
3020 +      error(tmp);
3021 +    }
3022 +  }
3023 +  if( new_type ) {
3024 +    for( i = 0; reserved_types[i] != NULL; i++ ) {
3025 +      if( strcmp( name, reserved_types[i] ) == 0 ) {
3026 +       sprintf(tmp, 
3027 +               "illegal (reserved) name :\'%s\' in type definition", name );
3028 +       error(tmp);
3029 +      }
3030 +    }
3031 +  }
3032 +}
3033 +
3034 +static void
3035 +def_typedef(definition *defp)
3036 +{
3037 +       declaration dec;
3038 +
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;
3047 +}
3048 +
3049 +static void
3050 +get_declaration(declaration *dec, defkind dkind)
3051 +{
3052 +       token tok;
3053 +
3054 +       get_type(&dec->prefix, &dec->type, dkind);
3055 +       dec->rel = REL_ALIAS;
3056 +       if (streq(dec->type, "void")) {
3057 +               return;
3058 +       }
3059 +
3060 +       check_type_name( dec->type, 0 );
3061 +
3062 +       scan2(TOK_STAR, TOK_IDENT, &tok);
3063 +       if (tok.kind == TOK_STAR) {
3064 +               dec->rel = REL_POINTER;
3065 +               scan(TOK_IDENT, &tok);
3066 +       }
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");
3071 +               }
3072 +               dec->rel = REL_VECTOR;
3073 +               scan_num(&tok);
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");
3079 +               }
3080 +               dec->rel = REL_ARRAY;
3081 +               if (peekscan(TOK_RANGLE, &tok)) {
3082 +                       dec->array_max = "~0";  /* unspecified size, use max */
3083 +               } else {
3084 +                       scan_num(&tok);
3085 +                       dec->array_max = tok.str;
3086 +                       scan(TOK_RANGLE, &tok);
3087 +               }
3088 +       }
3089 +       if (streq(dec->type, "opaque")) {
3090 +               if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR) {
3091 +                       error("array declaration expected");
3092 +               }
3093 +       } else if (streq(dec->type, "string")) {
3094 +               if (dec->rel != REL_ARRAY) {
3095 +                       error("variable-length array declaration expected");
3096 +               }
3097 +       }
3098 +}
3099 +
3100 +
3101 +static void
3102 +get_prog_declaration(declaration *dec, defkind dkind, int num)
3103 +{
3104 +       token tok;
3105 +       char name[10]; /* argument name */
3106 +
3107 +       if (dkind == DEF_PROGRAM) { 
3108 +         peek(&tok);
3109 +         if (tok.kind == TOK_RPAREN) { /* no arguments */
3110 +               dec->rel = REL_ALIAS;
3111 +               dec->type = "void";
3112 +               dec->prefix = NULL;
3113 +               dec->name = NULL;
3114 +               return;
3115 +             }
3116 +       }
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);
3121 +       else 
3122 +               sprintf(name, "%s%d", ARGNAME, num); /* default name of argument */
3123 +
3124 +       dec->name = (char *) strdup(name); 
3125 +       
3126 +       if (streq(dec->type, "void")) {
3127 +               return;
3128 +       }
3129 +
3130 +       if (streq(dec->type, "opaque")) {
3131 +               error("opaque -- illegal argument type");
3132 +       }
3133 +       if (peekscan(TOK_STAR, &tok)) { 
3134 +         if (streq(dec->type, "string")) {
3135 +           error("pointer to string not allowed in program arguments\n");
3136 +         }
3137 +               dec->rel = REL_POINTER;
3138 +               if (peekscan(TOK_IDENT, &tok))  /* optional name of argument */
3139 +                 dec->name = strdup(tok.str);
3140 +      }
3141 +         if (peekscan(TOK_LANGLE, &tok)) {
3142 +           if (!streq(dec->type, "string")) {
3143 +             error("arrays cannot be declared as arguments to procedures -- use typedef");
3144 +           }
3145 +               dec->rel = REL_ARRAY;
3146 +               if (peekscan(TOK_RANGLE, &tok)) {
3147 +                       dec->array_max = "~0";/* unspecified size, use max */
3148 +               } else {
3149 +                       scan_num(&tok);
3150 +                       dec->array_max = tok.str;
3151 +                       scan(TOK_RANGLE, &tok);
3152 +               }
3153 +       }
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<>
3158 +                                              */
3159 +                       dec->rel = REL_ARRAY;
3160 +                       dec->array_max = "~0";/* unspecified size, use max */
3161 +               }
3162 +       }
3163 +}
3164 +
3165 +
3166 +
3167 +static void
3168 +get_type(char **prefixp, char **typep, defkind dkind)
3169 +{
3170 +       token tok;
3171 +
3172 +       *prefixp = NULL;
3173 +       get_token(&tok);
3174 +       switch (tok.kind) {
3175 +       case TOK_IDENT:
3176 +               *typep = tok.str;
3177 +               break;
3178 +       case TOK_STRUCT:
3179 +       case TOK_ENUM:
3180 +       case TOK_UNION:
3181 +               *prefixp = tok.str;
3182 +               scan(TOK_IDENT, &tok);
3183 +               *typep = tok.str;
3184 +               break;
3185 +       case TOK_UNSIGNED:
3186 +               unsigned_dec(typep);
3187 +               break;
3188 +       case TOK_SHORT:
3189 +               *typep = "short";
3190 +               (void) peekscan(TOK_INT, &tok);
3191 +               break;
3192 +       case TOK_INT32:
3193 +               *typep = "int32_t";
3194 +               (void) peekscan(TOK_INT, &tok);
3195 +               break;
3196 +       case TOK_VOID:
3197 +               if (dkind != DEF_UNION && dkind != DEF_PROGRAM) {
3198 +                       error("voids allowed only inside union and program definitions with one argument");
3199 +               }
3200 +               *typep = tok.str;
3201 +               break;
3202 +       case TOK_STRING:
3203 +       case TOK_OPAQUE:
3204 +       case TOK_CHAR:
3205 +       case TOK_INT:
3206 +       case TOK_FLOAT:
3207 +       case TOK_DOUBLE:
3208 +       case TOK_BOOL:
3209 +               *typep = tok.str;
3210 +               break;
3211 +       default:
3212 +               error("expected type specifier");
3213 +       }
3214 +}
3215 +
3216 +static void
3217 +unsigned_dec(char **typep)
3218 +{
3219 +       token tok;
3220 +
3221 +       peek(&tok);
3222 +       switch (tok.kind) {
3223 +       case TOK_CHAR:
3224 +               get_token(&tok);
3225 +               *typep = "u_char";
3226 +               break;
3227 +       case TOK_SHORT:
3228 +               get_token(&tok);
3229 +               *typep = "u_short";
3230 +               (void) peekscan(TOK_INT, &tok);
3231 +               break;
3232 +       case TOK_INT32:
3233 +               get_token(&tok);
3234 +               *typep = "u_int32_";
3235 +               (void) peekscan(TOK_INT, &tok);
3236 +               break;
3237 +       case TOK_INT:
3238 +               get_token(&tok);
3239 +               *typep = "u_int";
3240 +               break;
3241 +       default:
3242 +               *typep = "u_int";
3243 +               break;
3244 +       }
3245 +}
3246 diff --git a/rpcgen/rpc_parse.h b/rpcgen/rpc_parse.h
3247 new file mode 100644
3248 index 0000000..2afae10
3249 --- /dev/null
3250 +++ b/rpcgen/rpc_parse.h
3251 @@ -0,0 +1,166 @@
3252 +/*
3253 + * Copyright (c) 2009, Sun Microsystems, Inc.
3254 + * All rights reserved.
3255 + *
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.
3266 + *
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.
3278 + */
3279 +
3280 +/*      @(#)rpc_parse.h  1.3  90/08/29  (C) 1987 SMI   */
3281 +
3282 +/*
3283 + * rpc_parse.h, Definitions for the RPCL parser 
3284 + */
3285 +
3286 +enum defkind {
3287 +       DEF_CONST,
3288 +       DEF_STRUCT,
3289 +       DEF_UNION,
3290 +       DEF_ENUM,
3291 +       DEF_TYPEDEF,
3292 +       DEF_PROGRAM
3293 +};
3294 +typedef enum defkind defkind;
3295 +
3296 +typedef char *const_def;
3297 +
3298 +enum relation {
3299 +       REL_VECTOR,     /* fixed length array */
3300 +       REL_ARRAY,      /* variable length array */
3301 +       REL_POINTER,    /* pointer */
3302 +       REL_ALIAS,      /* simple */
3303 +};
3304 +typedef enum relation relation;
3305 +
3306 +struct typedef_def {
3307 +       char *old_prefix;
3308 +       char *old_type;
3309 +       relation rel;
3310 +       char *array_max;
3311 +};
3312 +typedef struct typedef_def typedef_def;
3313 +
3314 +struct enumval_list {
3315 +       char *name;
3316 +       char *assignment;
3317 +       struct enumval_list *next;
3318 +};
3319 +typedef struct enumval_list enumval_list;
3320 +
3321 +struct enum_def {
3322 +       enumval_list *vals;
3323 +};
3324 +typedef struct enum_def enum_def;
3325 +
3326 +struct declaration {
3327 +       char *prefix;
3328 +       char *type;
3329 +       char *name;
3330 +       relation rel;
3331 +       char *array_max;
3332 +};
3333 +typedef struct declaration declaration;
3334 +
3335 +struct decl_list {
3336 +       declaration decl;
3337 +       struct decl_list *next;
3338 +};
3339 +typedef struct decl_list decl_list;
3340 +
3341 +struct struct_def {
3342 +       decl_list *decls;
3343 +};
3344 +typedef struct struct_def struct_def;
3345 +
3346 +struct case_list {
3347 +       char *case_name;
3348 +       int contflag;
3349 +       declaration case_decl;
3350 +       struct case_list *next;
3351 +};
3352 +typedef struct case_list case_list;
3353 +
3354 +struct union_def {
3355 +       declaration enum_decl;
3356 +       case_list *cases;
3357 +       declaration *default_decl;
3358 +};
3359 +typedef struct union_def union_def;
3360 +
3361 +struct arg_list {
3362 +       char *argname; /* name of struct for arg*/
3363 +       decl_list *decls;
3364 +};
3365 +       
3366 +typedef struct arg_list arg_list;
3367 +
3368 +struct proc_list {
3369 +       char *proc_name;
3370 +       char *proc_num;
3371 +       arg_list args;
3372 +       int arg_num;
3373 +       char *res_type;
3374 +       char *res_prefix;
3375 +       struct proc_list *next;
3376 +};
3377 +typedef struct proc_list proc_list;
3378 +
3379 +struct version_list {
3380 +       char *vers_name;
3381 +       char *vers_num;
3382 +       proc_list *procs;
3383 +       struct version_list *next;
3384 +};
3385 +typedef struct version_list version_list;
3386 +
3387 +struct program_def {
3388 +       char *prog_num;
3389 +       version_list *versions;
3390 +};
3391 +typedef struct program_def program_def;
3392 +
3393 +struct definition {
3394 +       char *def_name;
3395 +       defkind def_kind;
3396 +       union {
3397 +               const_def co;
3398 +               struct_def st;
3399 +               union_def un;
3400 +               enum_def en;
3401 +               typedef_def ty;
3402 +               program_def pr;
3403 +       } def;
3404 +};
3405 +typedef struct definition definition;
3406 +
3407 +definition *get_definition();
3408 +
3409 +
3410 +struct bas_type
3411 +{
3412 +  char *name;
3413 +  int length;
3414 +  struct bas_type *next;
3415 +};
3416 +
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
3421 --- /dev/null
3422 +++ b/rpcgen/rpc_sample.c
3423 @@ -0,0 +1,247 @@
3424 +/*
3425 + * Copyright (c) 2009, Sun Microsystems, Inc.
3426 + * All rights reserved.
3427 + *
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.
3438 + *
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.
3450 + */
3451 +
3452 +#if 0
3453 +static char sccsid[] = "@(#)rpc_sample.c  1.1  90/08/30  (C) 1987 SMI";
3454 +
3455 +#endif
3456 +
3457 +/*
3458 + * rpc_sample.c, Sample client-server code outputter for the RPC protocol compiler
3459 + */
3460 +
3461 +#include <stdio.h>
3462 +#include <string.h>
3463 +#include "rpc_parse.h"
3464 +#include "rpc_util.h"
3465 +
3466 +
3467 +static char RQSTP[] = "rqstp";
3468 +
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);
3472 +
3473 +void
3474 +write_sample_svc(definition *def)
3475 +{
3476 +       if (def->def_kind != DEF_PROGRAM)
3477 +               return;
3478 +       write_sample_server(def);
3479 +}
3480 +
3481 +
3482 +int
3483 +write_sample_clnt(definition *def)
3484 +{
3485 +       version_list   *vp;
3486 +       int             count = 0;
3487 +
3488 +       if (def->def_kind != DEF_PROGRAM)
3489 +               return (0);
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);
3493 +               ++count;
3494 +       }
3495 +       return (count);
3496 +}
3497 +
3498 +
3499 +static void
3500 +write_sample_client(char *program_name, version_list *vp)
3501 +{
3502 +       proc_list      *proc;
3503 +       int             i;
3504 +       decl_list      *l;
3505 +
3506 +       f_print(fout, "\n\nvoid\n");
3507 +       pvname(program_name, vp->vers_num);
3508 +       if (Cflag)
3509 +               f_print(fout, "( char* host )\n{\n");
3510 +       else
3511 +               f_print(fout, "(host)\nchar *host;\n{\n");
3512 +       f_print(fout, "\tCLIENT *clnt;\n");
3513 +
3514 +       i = 0;
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);
3524 +                       else
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" );*/
3537 +                       }
3538 +               }
3539 +       }
3540 +
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");
3547 +
3548 +       /* generate calls to procedures */
3549 +       i = 0;
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");
3562 +               } else {
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);
3567 +                       }
3568 +                       f_print(fout, "clnt);\n");
3569 +               }
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");
3573 +       }
3574 +
3575 +       f_print(fout, "\tclnt_destroy( clnt );\n");
3576 +       f_print(fout, "}\n");
3577 +}
3578 +
3579 +static void
3580 +write_sample_server(definition * def)
3581 +{
3582 +       version_list   *vp;
3583 +       proc_list      *proc;
3584 +
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");
3588 +                       /*                      if( Cflag )
3589 +                         f_print( fout, "extern \"C\"{\n");
3590 +*/
3591 +                       return_type(proc);
3592 +                       f_print(fout, "* \n");
3593 +                       if (Cflag)
3594 +                               pvname_svc(proc->proc_name, vp->vers_num);
3595 +                       else
3596 +                               pvname(proc->proc_name, vp->vers_num);
3597 +                       printarglist(proc, RQSTP, "struct svc_req *");
3598 +
3599 +                       f_print(fout, "{\n");
3600 +                       f_print(fout, "\n\tstatic ");
3601 +                       if (!streq(proc->res_type, "void"))
3602 +                               return_type(proc);
3603 +                       else
3604 +                               f_print(fout, "char*"); /* cannot have void type */
3605 +                       /* f_print(fout, " result;\n", proc->res_type); */
3606 +                       f_print(fout, " result;\n");
3607 +                       f_print(fout,
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");
3613 +                       /*                      if( Cflag)
3614 +                         f_print( fout, "};\n");
3615 +*/
3616 +
3617 +               }
3618 +       }
3619 +}
3620 +
3621 +
3622 +
3623 +static void
3624 +return_type(proc_list *plist)
3625 +{
3626 +       ptype( plist->res_prefix, plist->res_type, 1 );
3627 +}
3628 +
3629 +void
3630 +add_sample_msg(void)
3631 +{
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");
3637 +}
3638 +
3639 +void
3640 +write_sample_clnt_main(void)
3641 +{
3642 +  list *l;
3643 +  definition *def;
3644 +  version_list *vp;
3645 +
3646 +  f_print(fout, "\n\n" );
3647 +  if( Cflag )
3648 +    f_print(fout,"main( int argc, char* argv[] )\n{\n" );
3649 +  else
3650 +    f_print(fout, "main(argc, argv)\nint argc;\nchar *argv[];\n{\n" );
3651 +
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");
3657 +
3658 +  for (l = defined; l != NULL; l = l->next) {
3659 +               def = l->val;
3660 +               if (def->def_kind != DEF_PROGRAM) {
3661 +                       continue;
3662 +               }
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" );
3667 +                     }
3668 +               }
3669 +  f_print(fout, "}\n");
3670 +}
3671 diff --git a/rpcgen/rpc_scan.c b/rpcgen/rpc_scan.c
3672 new file mode 100644
3673 index 0000000..f58fa9f
3674 --- /dev/null
3675 +++ b/rpcgen/rpc_scan.c
3676 @@ -0,0 +1,474 @@
3677 +/*
3678 + * Copyright (c) 2009, Sun Microsystems, Inc.
3679 + * All rights reserved.
3680 + *
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.
3691 + *
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.
3703 + */
3704 +
3705 +#if 0
3706 +static char sccsid[] = "@(#)rpc_scan.c 1.11 89/02/22 (C) 1987 SMI";
3707 +#endif
3708 +
3709 +/*
3710 + * rpc_scan.c, Scanner for the RPC protocol compiler 
3711 + * Copyright (C) 1987, Sun Microsystems, Inc. 
3712 + */
3713 +#include <stdio.h>
3714 +#include <ctype.h>
3715 +#include <string.h>
3716 +#include "rpc_scan.h"
3717 +#include "rpc_parse.h"
3718 +#include "rpc_util.h"
3719 +
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);
3729 +
3730 +#define startcomment(where) (where[0] == '/' && where[1] == '*')
3731 +#define endcomment(where) (where[-1] == '*' && where[0] == '/')
3732 +
3733 +static int pushed = 0; /* is a token pushed */
3734 +static token lasttok;  /* last token, if pushed */
3735 +
3736 +/*
3737 + * scan expecting 1 given token 
3738 + */
3739 +void
3740 +scan(tok_kind expect, token *tokp)
3741 +{
3742 +       get_token(tokp);
3743 +       if (tokp->kind != expect) {
3744 +               expected1(expect);
3745 +       }
3746 +}
3747 +
3748 +/*
3749 + * scan expecting any of the 2 given tokens 
3750 + */
3751 +void
3752 +scan2(tok_kind expect1, tok_kind expect2, token *tokp)
3753 +{
3754 +       get_token(tokp);
3755 +       if (tokp->kind != expect1 && tokp->kind != expect2) {
3756 +               expected2(expect1, expect2);
3757 +       }
3758 +}
3759 +
3760 +/*
3761 + * scan expecting any of the 3 given token 
3762 + */
3763 +void
3764 +scan3(tok_kind expect1, tok_kind expect2, tok_kind expect3, token *tokp)
3765 +{
3766 +       get_token(tokp);
3767 +       if (tokp->kind != expect1 && tokp->kind != expect2
3768 +           && tokp->kind != expect3) {
3769 +               expected3(expect1, expect2, expect3);
3770 +       }
3771 +}
3772 +
3773 +/*
3774 + * scan expecting a constant, possibly symbolic 
3775 + */
3776 +void
3777 +scan_num(token *tokp)
3778 +{
3779 +       get_token(tokp);
3780 +       switch (tokp->kind) {
3781 +       case TOK_IDENT:
3782 +               break;
3783 +       default:
3784 +               error("constant or identifier expected");
3785 +       }
3786 +}
3787 +
3788 +/*
3789 + * Peek at the next token 
3790 + */
3791 +void
3792 +peek(token *tokp)
3793 +{
3794 +       get_token(tokp);
3795 +       unget_token(tokp);
3796 +}
3797 +
3798 +/*
3799 + * Peek at the next token and scan it if it matches what you expect 
3800 + */
3801 +int
3802 +peekscan(tok_kind expect, token *tokp)
3803 +{
3804 +       peek(tokp);
3805 +       if (tokp->kind == expect) {
3806 +               get_token(tokp);
3807 +               return (1);
3808 +       }
3809 +       return (0);
3810 +}
3811 +
3812 +/*
3813 + * Get the next token, printing out any directive that are encountered. 
3814 + */
3815 +void
3816 +get_token(token *tokp)
3817 +{
3818 +       int commenting;
3819 +
3820 +       if (pushed) {
3821 +               pushed = 0;
3822 +               *tokp = lasttok;
3823 +               return;
3824 +       }
3825 +       commenting = 0;
3826 +       for (;;) {
3827 +               if (*where == 0) {
3828 +                       for (;;) {
3829 +                               if (!fgets(curline, MAXLINESIZE, fin)) {
3830 +                                       tokp->kind = TOK_EOF;
3831 +                                       *where = 0;
3832 +                                       return;
3833 +                               }
3834 +                               linenum++;
3835 +                               if (commenting) {
3836 +                                       break;
3837 +                               } else if (cppline(curline)) {
3838 +                                       docppline(curline, &linenum, 
3839 +                                                 &infilename);
3840 +                               } else if (directive(curline)) {
3841 +                                       printdirective(curline);
3842 +                               } else {
3843 +                                       break;
3844 +                               }
3845 +                       }
3846 +                       where = curline;
3847 +               } else if (isspace(*where)) {
3848 +                       while (isspace(*where)) {
3849 +                               where++;        /* eat */
3850 +                       }
3851 +               } else if (commenting) {
3852 +                       for (where++; *where; where++) {
3853 +                               if (endcomment(where)) {
3854 +                                       where++;
3855 +                                       commenting--;
3856 +                                       break;
3857 +                               }
3858 +                       }
3859 +               } else if (startcomment(where)) {
3860 +                       where += 2;
3861 +                       commenting++;
3862 +               } else {
3863 +                       break;
3864 +               }
3865 +       }
3866 +
3867 +       /*
3868 +        * 'where' is not whitespace, comment or directive Must be a token! 
3869 +        */
3870 +       switch (*where) {
3871 +       case ':':
3872 +               tokp->kind = TOK_COLON;
3873 +               where++;
3874 +               break;
3875 +       case ';':
3876 +               tokp->kind = TOK_SEMICOLON;
3877 +               where++;
3878 +               break;
3879 +       case ',':
3880 +               tokp->kind = TOK_COMMA;
3881 +               where++;
3882 +               break;
3883 +       case '=':
3884 +               tokp->kind = TOK_EQUAL;
3885 +               where++;
3886 +               break;
3887 +       case '*':
3888 +               tokp->kind = TOK_STAR;
3889 +               where++;
3890 +               break;
3891 +       case '[':
3892 +               tokp->kind = TOK_LBRACKET;
3893 +               where++;
3894 +               break;
3895 +       case ']':
3896 +               tokp->kind = TOK_RBRACKET;
3897 +               where++;
3898 +               break;
3899 +       case '{':
3900 +               tokp->kind = TOK_LBRACE;
3901 +               where++;
3902 +               break;
3903 +       case '}':
3904 +               tokp->kind = TOK_RBRACE;
3905 +               where++;
3906 +               break;
3907 +       case '(':
3908 +               tokp->kind = TOK_LPAREN;
3909 +               where++;
3910 +               break;
3911 +       case ')':
3912 +               tokp->kind = TOK_RPAREN;
3913 +               where++;
3914 +               break;
3915 +       case '<':
3916 +               tokp->kind = TOK_LANGLE;
3917 +               where++;
3918 +               break;
3919 +       case '>':
3920 +               tokp->kind = TOK_RANGLE;
3921 +               where++;
3922 +               break;
3923 +
3924 +       case '"':
3925 +               tokp->kind = TOK_STRCONST;
3926 +               findstrconst(&where, &tokp->str);
3927 +               break;
3928 +       case '\'':
3929 +               tokp->kind = TOK_CHARCONST;
3930 +               findchrconst(&where, &tokp->str);
3931 +               break;
3932 +
3933 +       case '-':
3934 +       case '0':
3935 +       case '1':
3936 +       case '2':
3937 +       case '3':
3938 +       case '4':
3939 +       case '5':
3940 +       case '6':
3941 +       case '7':
3942 +       case '8':
3943 +       case '9':
3944 +               tokp->kind = TOK_IDENT;
3945 +               findconst(&where, &tokp->str);
3946 +               break;
3947 +
3948 +       default:
3949 +               if (!(isalpha(*where) || *where == '_')) {
3950 +                       char buf[100];
3951 +                       char *p;
3952 +
3953 +                       s_print(buf, "illegal character in file: ");
3954 +                       p = buf + strlen(buf);
3955 +                       if (isprint(*where)) {
3956 +                               s_print(p, "%c", *where);
3957 +                       } else {
3958 +                               s_print(p, "%d", *where);
3959 +                       }
3960 +                       error(buf);
3961 +               }
3962 +               findkind(&where, tokp);
3963 +               break;
3964 +       }
3965 +}
3966 +
3967 +static void
3968 +unget_token(token *tokp)
3969 +{
3970 +       lasttok = *tokp;
3971 +       pushed = 1;
3972 +}
3973 +
3974 +static void
3975 +findstrconst(char **str, char **val)
3976 +{
3977 +       char *p;
3978 +       int size;
3979 +
3980 +       p = *str;
3981 +       do {
3982 +               *p++;
3983 +       } while (*p && *p != '"');
3984 +       if (*p == 0) {
3985 +               error("unterminated string constant");
3986 +       }
3987 +       p++;
3988 +       size = p - *str;
3989 +       *val = alloc(size + 1);
3990 +       (void) strncpy(*val, *str, size);
3991 +       (*val)[size] = 0;
3992 +       *str = p;
3993 +}
3994 +
3995 +static void
3996 +findchrconst(char **str, char **val)
3997 +{
3998 +       char *p;
3999 +       int size;
4000 +
4001 +       p = *str;
4002 +       do {
4003 +               *p++;
4004 +       } while (*p && *p != '\'');
4005 +       if (*p == 0) {
4006 +               error("unterminated string constant");
4007 +       }
4008 +       p++;
4009 +       size = p - *str;
4010 +       if (size != 3) {
4011 +               error("empty char string");
4012 +       }
4013 +       *val = alloc(size + 1);
4014 +       (void) strncpy(*val, *str, size);
4015 +       (*val)[size] = 0;
4016 +       *str = p;
4017 +}
4018 +
4019 +static void
4020 +findconst(char **str, char **val)
4021 +{
4022 +       char *p;
4023 +       int size;
4024 +
4025 +       p = *str;
4026 +       if (*p == '0' && *(p + 1) == 'x') {
4027 +               p++;
4028 +               do {
4029 +                       p++;
4030 +               } while (isxdigit(*p));
4031 +       } else {
4032 +               do {
4033 +                       p++;
4034 +               } while (isdigit(*p));
4035 +       }
4036 +       size = p - *str;
4037 +       *val = alloc(size + 1);
4038 +       (void) strncpy(*val, *str, size);
4039 +       (*val)[size] = 0;
4040 +       *str = p;
4041 +}
4042 +
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"},
4056 +                         {TOK_INT, "int"},
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, "??????"},
4066 +};
4067 +
4068 +static void
4069 +findkind(char **mark, token *tokp)
4070 +{
4071 +       int len;
4072 +       token *s;
4073 +       char *str;
4074 +
4075 +       str = *mark;
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;
4083 +                               return;
4084 +                       }
4085 +               }
4086 +       }
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;
4093 +}
4094 +
4095 +static int
4096 +cppline(char *line)
4097 +{
4098 +       return (line == curline && *line == '#');
4099 +}
4100 +
4101 +static int
4102 +directive(char *line)
4103 +{
4104 +       return (line == curline && *line == '%');
4105 +}
4106 +
4107 +static void
4108 +printdirective(char *line)
4109 +{
4110 +       f_print(fout, "%s", line + 1);
4111 +}
4112 +
4113 +static void
4114 +docppline(char *line, int *lineno, char **fname)
4115 +{
4116 +       char *file;
4117 +       int num;
4118 +       char *p;
4119 +
4120 +       line++;
4121 +       while (isspace(*line)) {
4122 +               line++;
4123 +       }
4124 +       num = atoi(line);
4125 +       while (isdigit(*line)) {
4126 +               line++;
4127 +       }
4128 +       while (isspace(*line)) {
4129 +               line++;
4130 +       }
4131 +       if (*line != '"') {
4132 +               error("preprocessor error");
4133 +       }
4134 +       line++;
4135 +       p = file = alloc(strlen(line) + 1);
4136 +       while (*line && *line != '"') {
4137 +               *p++ = *line++;
4138 +       }
4139 +       if (*line == 0) {
4140 +               error("preprocessor error");
4141 +       }
4142 +       *p = 0;
4143 +       if (*file == 0) {
4144 +               *fname = NULL;
4145 +               free(file);
4146 +       } else {
4147 +               *fname = file;
4148 +       }
4149 +       *lineno = num - 1;
4150 +}
4151 diff --git a/rpcgen/rpc_scan.h b/rpcgen/rpc_scan.h
4152 new file mode 100644
4153 index 0000000..16f688c
4154 --- /dev/null
4155 +++ b/rpcgen/rpc_scan.h
4156 @@ -0,0 +1,103 @@
4157 +/*
4158 + * Copyright (c) 2009, Sun Microsystems, Inc.
4159 + * All rights reserved.
4160 + *
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.
4171 + *
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.
4183 + */
4184 +
4185 +/*      @(#)rpc_scan.h  1.3  90/08/29  (C) 1987 SMI   */
4186 +
4187 +/*
4188 + * rpc_scan.h, Definitions for the RPCL scanner 
4189 + */
4190 +
4191 +/*
4192 + * kinds of tokens 
4193 + */
4194 +enum tok_kind {
4195 +       TOK_IDENT,
4196 +       TOK_CHARCONST,
4197 +       TOK_STRCONST,
4198 +       TOK_LPAREN,
4199 +       TOK_RPAREN,
4200 +       TOK_LBRACE,
4201 +       TOK_RBRACE,
4202 +       TOK_LBRACKET,
4203 +       TOK_RBRACKET,
4204 +       TOK_LANGLE,
4205 +       TOK_RANGLE,
4206 +       TOK_STAR,
4207 +       TOK_COMMA,
4208 +       TOK_EQUAL,
4209 +       TOK_COLON,
4210 +       TOK_SEMICOLON,
4211 +       TOK_CONST,
4212 +       TOK_STRUCT,
4213 +       TOK_UNION,
4214 +       TOK_SWITCH,
4215 +       TOK_CASE,
4216 +       TOK_DEFAULT,
4217 +       TOK_ENUM,
4218 +       TOK_TYPEDEF,
4219 +       TOK_INT,
4220 +       TOK_SHORT,
4221 +       TOK_INT32,
4222 +       TOK_UNSIGNED,
4223 +       TOK_FLOAT,
4224 +       TOK_DOUBLE,
4225 +       TOK_OPAQUE,
4226 +       TOK_CHAR,
4227 +       TOK_STRING,
4228 +       TOK_BOOL,
4229 +       TOK_VOID,
4230 +       TOK_PROGRAM,
4231 +       TOK_VERSION,
4232 +       TOK_EOF
4233 +};
4234 +typedef enum tok_kind tok_kind;
4235 +
4236 +/*
4237 + * a token 
4238 + */
4239 +struct token {
4240 +       tok_kind kind;
4241 +       char *str;
4242 +};
4243 +typedef struct token token;
4244 +
4245 +
4246 +/*
4247 + * routine interface 
4248 + */
4249 +void            scan();
4250 +void            scan2();
4251 +void            scan3();
4252 +void            scan_num();
4253 +void            peek();
4254 +int             peekscan();
4255 +void            get_token();
4256 +void            expected1(tok_kind);
4257 +void            expected2(tok_kind, tok_kind);
4258 +void            expected3(tok_kind, tok_kind, tok_kind);
4259 +
4260 diff --git a/rpcgen/rpc_svcout.c b/rpcgen/rpc_svcout.c
4261 new file mode 100644
4262 index 0000000..284a529
4263 --- /dev/null
4264 +++ b/rpcgen/rpc_svcout.c
4265 @@ -0,0 +1,882 @@
4266 +/*
4267 + * Copyright (c) 2009, Sun Microsystems, Inc.
4268 + * All rights reserved.
4269 + *
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.
4280 + *
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.
4292 + */
4293 +
4294 +#if 0
4295 + static char sccsid[] = "@(#)rpc_svcout.c 1.29 89/03/30 (C) 1987 SMI";
4296 +#endif
4297 +
4298 +/*
4299 + * rpc_svcout.c, Server-skeleton outputter for the RPC protocol compiler
4300 + */
4301 +#include <stdio.h>
4302 +#include <string.h>
4303 +#include "rpc_parse.h"
4304 +#include "rpc_util.h"
4305 +#include "rpc_output.h"
4306 +
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);
4319 +
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";
4325 +
4326 +char _errbuf[256];     /* For all messages */
4327 +
4328 +static void
4329 +p_xdrfunc(char *rname, char *typename)
4330 +{
4331 +       if (Cflag)
4332 +               f_print(fout, "\t\txdr_%s = (xdrproc_t) xdr_%s;\n", rname,
4333 +                       stringfix(typename));
4334 +       else
4335 +               f_print(fout, "\t\txdr_%s = xdr_%s;\n", rname, stringfix(typename));
4336 +}
4337 +
4338 +void
4339 +internal_proctype(proc_list *plist)
4340 +{
4341 +       f_print(fout, "static ");
4342 +       ptype( plist->res_prefix, plist->res_type, 1 );
4343 +       f_print( fout, "*" );
4344 +}
4345 +
4346 +
4347 +/*
4348 + * write most of the service, that is, everything but the registrations. 
4349 + */
4350 +void
4351 +write_most(char *infile, int netflag, int nomain)
4352 +{
4353 +       if (inetdflag || pmflag) {
4354 +               char* var_type;
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");
4360 +               if (timerflag) {
4361 +                       f_print(fout, "%s int _rpcsvcdirty;", var_type );
4362 +                       f_print(fout, "\t/* Still serving ? */\n");
4363 +               }
4364 +               write_svc_aux( nomain );
4365 +       }
4366 +       /* write out dispatcher and stubs */
4367 +       write_programs( nomain? (char *)NULL : "static" );
4368 +
4369 +        if( nomain ) 
4370 +         return;
4371 +
4372 +       f_print(fout, "\nmain()\n");
4373 +       f_print(fout, "{\n");
4374 +       if (inetdflag) {
4375 +               write_inetmost(infile); /* Includes call to write_rpc_svc_fg() */
4376 +       } else {
4377 +         if( tirpcflag ) {
4378 +               if (netflag) {
4379 +                       f_print(fout, "\tregister SVCXPRT *%s;\n", TRANSP);
4380 +                       f_print(fout, "\tstruct netconfig *nconf = NULL;\n");
4381 +               }
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");
4389 +             } else {
4390 +               f_print(fout, "\tregister SVCXPRT *%s;\n", TRANSP);
4391 +               f_print(fout, "\n");
4392 +               print_pmapunset("\t");
4393 +             }
4394 +       }
4395 +
4396 +       if (logflag && !inetdflag) {
4397 +               open_log_file(infile, "\t");
4398 +       }
4399 +}
4400 +
4401 +/*
4402 + * write a registration for the given transport 
4403 + */
4404 +void
4405 +write_netid_register(char *transp)
4406 +{
4407 +       list *l;
4408 +       definition *def;
4409 +       version_list *vp;
4410 +       char *sp;
4411 +       char tmpbuf[32];
4412 +
4413 +       sp = "";
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",
4423 +                       sp, TRANSP);
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);
4429 +
4430 +       for (l = defined; l != NULL; l = l->next) {
4431 +               def = (definition *) l->val;
4432 +               if (def->def_kind != DEF_PROGRAM) {
4433 +                       continue;
4434 +               }
4435 +               for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
4436 +                       f_print(fout,
4437 +                               "%s\t(void) rpcb_unset(%s, %s, nconf);\n",
4438 +                               sp, def->def_name, vp->vers_name);
4439 +                       f_print(fout,
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);
4449 +               }
4450 +       }
4451 +       f_print(fout, "%s\tfreenetconfigent(nconf);\n", sp);
4452 +}
4453 +
4454 +/*
4455 + * write a registration for the given transport for TLI
4456 + */
4457 +void
4458 +write_nettype_register(char *transp)
4459 +{
4460 +       list *l;
4461 +       definition *def;
4462 +       version_list *vp;
4463 +
4464 +       for (l = defined; l != NULL; l = l->next) {
4465 +               def = (definition *) l->val;
4466 +               if (def->def_kind != DEF_PROGRAM) {
4467 +                       continue;
4468 +               }
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");
4480 +               }
4481 +       }
4482 +}
4483 +
4484 +/*
4485 + * write the rest of the service 
4486 + */
4487 +void
4488 +write_rest(void)
4489 +{
4490 +       f_print(fout, "\n");
4491 +       if (inetdflag) {
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");
4497 +               if (timerflag) {
4498 +                       f_print(fout, "\tif (_rpcpmstart) {\n");
4499 +                       f_print(fout, 
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");
4504 +               }
4505 +       }
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");
4512 +}
4513 +
4514 +void
4515 +write_programs(char *storage)
4516 +{
4517 +       list *l;
4518 +       definition *def;
4519 +
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);
4525 +               }
4526 +       }
4527 +
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);
4533 +               }
4534 +       }
4535 +
4536 +
4537 +}
4538 +
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. */
4543 +static void
4544 +write_real_program(definition *def)
4545 +{
4546 +       version_list *vp;
4547 +       proc_list *proc;
4548 +       decl_list *l;
4549 +
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);
4557 +                       if( Cflag ) {
4558 +                         f_print(fout, "(" );
4559 +                         /* arg name */
4560 +                         if (proc->arg_num > 1)
4561 +                           f_print(fout, proc->args.argname);
4562 +                         else
4563 +                           ptype(proc->args.decls->decl.prefix, 
4564 +                                 proc->args.decls->decl.type, 0);
4565 +                         f_print(fout, " *argp, struct svc_req *%s)\n", 
4566 +                                 RQSTP);
4567 +                       } else {
4568 +                         f_print(fout, "(argp, %s)\n", RQSTP );
4569 +                         /* arg name */
4570 +                         if (proc->arg_num > 1)
4571 +                           f_print(fout, "\t%s *argp;\n", proc->args.argname);
4572 +                         else {
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");
4577 +                         }
4578 +                         f_print(fout, "       struct svc_req *%s;\n", RQSTP);
4579 +                       }
4580 +
4581 +                       f_print(fout, "{\n");
4582 +                       f_print(fout, "\treturn(");
4583 +                       if( Cflag )
4584 +                         pvname_svc(proc->proc_name, vp->vers_num);
4585 +                       else
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 */
4591 +                       } else {
4592 +                         for (l = proc->args.decls;  l != NULL; l = l->next) 
4593 +                           f_print(fout, "argp->%s, ", l->decl.name);
4594 +                       }
4595 +                       f_print(fout, "%s));\n}\n", RQSTP);
4596 +               }               
4597 +       }
4598 +}
4599 +
4600 +static void
4601 +write_program(definition *def, char *storage)
4602 +{
4603 +       version_list *vp;
4604 +       proc_list *proc;
4605 +       int filled;
4606 +
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);
4611 +               }
4612 +               f_print(fout, "void\n");
4613 +               pvname(def->def_name, vp->vers_num);
4614 +
4615 +               if (Cflag) {
4616 +                  f_print(fout, "(struct svc_req *%s, ", RQSTP);
4617 +                  f_print(fout, "register SVCXPRT *%s)\n", TRANSP);
4618 +               } else {
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);
4622 +               }
4623 +
4624 +               f_print(fout, "{\n");
4625 +
4626 +               filled = 0;
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, 
4631 +                                         "void")) {
4632 +                                       continue;
4633 +                               }
4634 +                               filled = 1;
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");
4640 +
4641 +                       }
4642 +                       else {
4643 +                               filled = 1;
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");
4648 +                       }
4649 +               }
4650 +               if (!filled) {
4651 +                       f_print(fout, "\t\tint fill;\n");
4652 +               }
4653 +               f_print(fout, "\t} %s;\n", ARG);
4654 +               f_print(fout, "\tchar *%s;\n", RESULT);
4655 +
4656 +               if (Cflag) {
4657 +                   f_print(fout, "\txdrproc_t xdr_%s, xdr_%s;\n", ARG, RESULT);
4658 +                   f_print(fout,
4659 +                           "\tchar *(*%s)(char *, struct svc_req *);\n",
4660 +                           ROUTINE);
4661 +               } else {
4662 +                   f_print(fout, "\tbool_t (*xdr_%s)(), (*xdr_%s)();\n", ARG, RESULT);
4663 +                   f_print(fout, "\tchar *(*%s)();\n", ROUTINE);
4664 +               }
4665 +
4666 +               f_print(fout, "\n");
4667 +
4668 +               if (timerflag)
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");
4673 +                       f_print(fout,
4674 +                       "\t\t(void) svc_sendreply(%s, (xdrproc_t) xdr_void, (char *)NULL);\n",
4675 +                                       TRANSP);
4676 +                       print_return("\t\t");
4677 +                       f_print(fout, "\n");
4678 +               }
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);
4683 +                       } else {
4684 +                         p_xdrfunc( ARG, proc->args.argname);
4685 +                       }
4686 +                       p_xdrfunc( RESULT, proc->res_type);
4687 +                       if( Cflag )
4688 +                           f_print(fout,
4689 +                                   "\t\t%s = (char *(*)(char *, struct svc_req *)) ",
4690 +                                   ROUTINE);
4691 +                       else
4692 +                           f_print(fout, "\t\t%s = (char *(*)()) ", ROUTINE);
4693 +
4694 +                       if (newstyle) { /* new style: calls internal routine */
4695 +                               f_print(fout,"_");
4696 +                       }
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 */
4701 +#if 0
4702 +                       if( Cflag && !newstyle )
4703 +                         pvname_svc(proc->proc_name, vp->vers_num);
4704 +                       else
4705 +                         pvname(proc->proc_name, vp->vers_num);
4706 +#else
4707 +                       pvname_svc(proc->proc_name, vp->vers_num);
4708 +#endif
4709 +                       f_print(fout, ";\n");
4710 +                       f_print(fout, "\t\tbreak;\n\n");
4711 +               }
4712 +               f_print(fout, "\tdefault:\n");
4713 +               printerr("noproc", TRANSP);
4714 +               print_return("\t\t");
4715 +               f_print(fout, "\t}\n");
4716 +
4717 +               f_print(fout, "\t(void) memset((char *)&%s, 0, sizeof (%s));\n", ARG, ARG);
4718 +               if (Cflag)
4719 +                   printif("getargs", TRANSP, "(caddr_t) &", ARG);
4720 +               else
4721 +                   printif("getargs", TRANSP, "&", ARG);
4722 +               printerr("decode", TRANSP);
4723 +               print_return("\t\t");
4724 +               f_print(fout, "\t}\n");
4725 +
4726 +               if (Cflag)
4727 +                   f_print(fout, "\t%s = (*%s)((char *)&%s, %s);\n",
4728 +                           RESULT, ROUTINE, ARG, RQSTP);
4729 +               else
4730 +                   f_print(fout, "\t%s = (*%s)(&%s, %s);\n",
4731 +                           RESULT, ROUTINE, ARG, RQSTP);
4732 +               f_print(fout, 
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");
4738 +
4739 +               if (Cflag)
4740 +                   printif("freeargs", TRANSP, "(caddr_t) &", ARG);
4741 +               else
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");
4749 +       }
4750 +}
4751 +
4752 +static void
4753 +printerr(char *err, char *transp)
4754 +{
4755 +       f_print(fout, "\t\tsvcerr_%s(%s);\n", err, transp);
4756 +}
4757 +
4758 +static void
4759 +printif(char *proc, char *transp, char *prefix, char *arg)
4760 +{
4761 +       f_print(fout, "\tif (!svc_%s(%s, (xdrproc_t) xdr_%s, (caddr_t) %s%s)) {\n",
4762 +               proc, transp, arg, prefix, arg);
4763 +}
4764 +
4765 +int
4766 +nullproc(proc_list *proc)
4767 +{
4768 +       for (; proc != NULL; proc = proc->next) {
4769 +               if (streq(proc->proc_num, "0")) {
4770 +                       return (1);
4771 +               }
4772 +       }
4773 +       return (0);
4774 +}
4775 +
4776 +static void
4777 +write_inetmost(char *infile)
4778 +{
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");
4785 +       f_print(fout, 
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");
4802 +}
4803 +
4804 +static void
4805 +print_return(char *space)
4806 +{
4807 +       if (exitnow)
4808 +               f_print(fout, "%sexit(0);\n", space);
4809 +       else {
4810 +               if (timerflag)
4811 +                       f_print(fout, "%s_rpcsvcdirty = 0;\n", space);
4812 +               f_print(fout, "%sreturn;\n", space);
4813 +       }
4814 +}
4815 +
4816 +static void
4817 +print_pmapunset(char *space)
4818 +{
4819 +       list *l;
4820 +       definition *def;
4821 +       version_list *vp;
4822 +
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;
4827 +                                       vp = vp->next) {
4828 +                               f_print(fout, "%s(void) pmap_unset(%s, %s);\n",
4829 +                                       space, def->def_name, vp->vers_name);
4830 +                       }
4831 +               }
4832 +       }
4833 +}
4834 +
4835 +static void
4836 +print_err_message(char *space)
4837 +{
4838 +       if (logflag)
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);
4842 +       else
4843 +               f_print(fout, "%sfprintf(stderr, \"%s\");\n", space, _errbuf);
4844 +}
4845 +
4846 +/*
4847 + * Write the server auxiliary function ( _msgout, timeout)
4848 + */
4849 +void
4850 +write_svc_aux(int nomain)
4851 +{
4852 +       if (!logflag)
4853 +               write_msg_out();
4854 +       if( !nomain )
4855 +         write_timeout_func();
4856 +}
4857 +
4858 +/*
4859 + * Write the _msgout function
4860 + */
4861 +void
4862 +write_msg_out(void)
4863 +{
4864 +       f_print(fout, "\n");
4865 +       f_print(fout, "static\n");
4866 +       if( !Cflag ) {
4867 +         f_print(fout, "void _msgout(msg)\n");
4868 +         f_print(fout, "\tchar *msg;\n");
4869 +       } else {
4870 +         f_print(fout, "void _msgout(char* msg)\n");
4871 +       }
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");
4883 +}
4884 +
4885 +/*
4886 + * Write the timeout function
4887 + */
4888 +static void
4889 +write_timeout_func(void)
4890 +{
4891 +       if (!timerflag)
4892 +               return;
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");
4903 +       } else {
4904 +               f_print(fout, "\n\t\tif (_rpcfdtype == SOCK_DGRAM)\n");
4905 +       }
4906 +       f_print(fout, "\t\t\texit(0);\n");
4907 +       f_print(fout, "\t\tif (size == 0) {\n");
4908 +       if( tirpcflag ) {
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");
4914 +       } else {
4915 +         f_print(fout, "\t\t\tsize = getdtablesize();\n");
4916 +       }
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");
4926 +}
4927 +
4928 +/*
4929 + * Write the most of port monitor support
4930 + */
4931 +static void
4932 +write_pm_most(char *infile, int netflag)
4933 +{
4934 +       list *l;
4935 +       definition *def;
4936 +       version_list *vp;
4937 +
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);
4945 +       }
4946 +       if( timerflag )
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");
4952 +       if (logflag)
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");
4961 +       /*
4962 +        * A kludgy support for inetd services. Inetd only works with
4963 +        * sockmod, and RPC works only with timod, hence all this jugglery
4964 +        */
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");
4972 +       if( timerflag )
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",
4975 +                       TRANSP);
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) {
4985 +                       continue;
4986 +               }
4987 +               for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
4988 +                       f_print(fout,
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");
4998 +               }
4999 +       }
5000 +       if (timerflag) {
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");
5006 +       }
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");
5011 +}
5012 +
5013 +/*
5014 + * Support for backgrounding the server if self started.
5015 + */
5016 +static void
5017 +write_rpc_svc_fg(char *infile, char *sp)
5018 +{
5019 +       f_print(fout, "#ifndef RPC_SVC_FG\n");
5020 +       f_print(fout, "%sint size;\n", sp);
5021 +       if( tirpcflag )
5022 +               f_print(fout, "%sstruct rlimit rl;\n", sp);
5023 +       if (inetdflag)
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 */
5033 +       if( tirpcflag ) {
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);
5038 +       } else {
5039 +         f_print(fout, "%ssize = getdtablesize();\n", sp);
5040 +       }
5041 +
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 */
5049 +       if( tirpcflag )
5050 +         f_print(fout, "%ssetsid();\n", sp);
5051 +       else {
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);
5057 +       }
5058 +       if (!logflag)
5059 +               open_log_file(infile, sp);
5060 +       f_print(fout, "#endif\n");
5061 +       if (logflag)
5062 +               open_log_file(infile, sp);
5063 +}
5064 +
5065 +static void
5066 +open_log_file(char *infile, char *sp)
5067 +{
5068 +       char *s;
5069 +
5070 +       s = strrchr(infile, '.');
5071 +       if (s) 
5072 +               *s = '\0';
5073 +       f_print(fout,"%sopenlog(\"%s\", LOG_PID, LOG_DAEMON);\n", sp, infile);
5074 +       if (s)
5075 +               *s = '.';
5076 +}
5077 +
5078 +
5079 +
5080 +
5081 +/*
5082 + * write a registration for the given transport for Inetd
5083 + */
5084 +void
5085 +write_inetd_register(char *transp)
5086 +{
5087 +       list *l;
5088 +       definition *def;
5089 +       version_list *vp;
5090 +       char *sp;
5091 +       int isudp;
5092 +       char tmpbuf[32];
5093 +
5094 +       if (inetdflag)
5095 +               sp = "\t";
5096 +       else
5097 +               sp = "";
5098 +       if (streq(transp, "udp"))
5099 +               isudp = 1;
5100 +       else
5101 +               isudp = 0;
5102 +       f_print(fout, "\n");
5103 +       if (inetdflag) {
5104 +               f_print(fout, "\tif ((_rpcfdtype == 0) || (_rpcfdtype == %s)) {\n",
5105 +                               isudp ? "SOCK_DGRAM" : "SOCK_STREAM");
5106 +       }
5107 +       f_print(fout, "%s\t%s = svc%s_create(%s",
5108 +               sp, TRANSP, transp, inetdflag? "sock": "RPC_ANYSOCK");
5109 +       if (!isudp)
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);
5118 +
5119 +       if (inetdflag) {
5120 +               f_print(fout, "%s\tif (!_rpcpmstart)\n\t", sp);
5121 +               f_print(fout, "%s\tproto = IPPROTO_%s;\n",
5122 +                               sp, isudp ? "UDP": "TCP");
5123 +       }
5124 +       for (l = defined; l != NULL; l = l->next) {
5125 +               def = (definition *) l->val;
5126 +               if (def->def_kind != DEF_PROGRAM) {
5127 +                       continue;
5128 +               }
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);
5133 +                       if (inetdflag)
5134 +                               f_print(fout, ", proto)) {\n");
5135 +                       else 
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);
5143 +               }
5144 +       }
5145 +       if (inetdflag)
5146 +               f_print(fout, "\t}\n");
5147 +}
5148 diff --git a/rpcgen/rpc_tblout.c b/rpcgen/rpc_tblout.c
5149 new file mode 100644
5150 index 0000000..ae002f7
5151 --- /dev/null
5152 +++ b/rpcgen/rpc_tblout.c
5153 @@ -0,0 +1,165 @@
5154 +/*
5155 + * Copyright (c) 2009, Sun Microsystems, Inc.
5156 + * All rights reserved.
5157 + *
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.
5168 + *
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.
5180 + */
5181 +
5182 +#if 0
5183 +static char sccsid[] = "@(#)rpc_tblout.c 1.4 89/02/22 (C) 1988 SMI";
5184 +#endif
5185 +
5186 +/*
5187 + * rpc_tblout.c, Dispatch table outputter for the RPC protocol compiler
5188 + */
5189 +#include <stdio.h>
5190 +#include <string.h>
5191 +#include "rpc_parse.h"
5192 +#include "rpc_util.h"
5193 +#include "rpc_output.h"
5194 +
5195 +static void    write_table(definition *def);
5196 +static void    printit(char *prefix, char *type);
5197 +
5198 +#define TABSIZE                8
5199 +#define TABCOUNT       5
5200 +#define TABSTOP                (TABSIZE*TABCOUNT)
5201 +
5202 +static char tabstr[TABCOUNT+1] = "\t\t\t\t\t";
5203 +
5204 +static char tbl_hdr[] = "struct rpcgen_table %s_table[] = {\n";
5205 +static char tbl_end[] = "};\n";
5206 +
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";
5210 +
5211 +
5212 +static char tbl_nproc[] = "int %s_nproc =\n\tsizeof(%s_table)/sizeof(%s_table[0]);\n\n";
5213 +
5214 +void
5215 +write_tables(void)
5216 +{
5217 +       list *l;
5218 +       definition *def;
5219 +
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) {
5224 +                       write_table(def);
5225 +               }
5226 +       }
5227 +}
5228 +
5229 +static void
5230 +write_table(definition *def)
5231 +{
5232 +       version_list *vp;
5233 +       proc_list *proc;
5234 +       int current;
5235 +       int expected;
5236 +       char progvers[100];
5237 +       int warning;
5238 +
5239 +       for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
5240 +               warning = 0;
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);
5245 +
5246 +               if (nullproc(vp->procs)) {
5247 +                       expected = 0;
5248 +               } else {
5249 +                       expected = 1;
5250 +                       f_print(fout, null_entry);
5251 +               }
5252 +               for (proc = vp->procs; proc != NULL; proc = proc->next) {
5253 +                       current = atoi(proc->proc_num);
5254 +                       if (current != expected++) {
5255 +                               f_print(fout,
5256 +                       "\n/*\n * WARNING: table out of order\n */\n");
5257 +                               if (warning == 0) {
5258 +                                       f_print(stderr,
5259 +                                   "WARNING %s table is out of order\n",
5260 +                                           progvers);
5261 +                                       warning = 1;
5262 +                                       nonfatalerrors = 1;
5263 +                               }
5264 +                               expected = current + 1;
5265 +                       }
5266 +                       f_print(fout, "\n\t(char *(*)())RPCGEN_ACTION(");
5267 +
5268 +                       /* routine to invoke */
5269 +                       if( Cflag && !newstyle )
5270 +                         pvname_svc(proc->proc_name, vp->vers_num);
5271 +                       else {
5272 +                         if( newstyle )
5273 +                           f_print( fout, "_");   /* calls internal func */
5274 +                         pvname(proc->proc_name, vp->vers_num);
5275 +                       }
5276 +                       f_print(fout, "),\n");
5277 +
5278 +                       /* argument info */
5279 +                       if( proc->arg_num > 1 )
5280 +                         printit((char*) NULL, proc->args.argname );
5281 +                       else  
5282 +                         /* do we have to do something special for newstyle */
5283 +                         printit( proc->args.decls->decl.prefix,
5284 +                                 proc->args.decls->decl.type );
5285 +                       /* result info */
5286 +                       printit(proc->res_prefix, proc->res_type);
5287 +               }
5288 +
5289 +               /* print the table trailer */
5290 +               f_print(fout, tbl_end);
5291 +               f_print(fout, tbl_nproc, progvers, progvers, progvers);
5292 +       }
5293 +}
5294 +
5295 +static void
5296 +printit(char *prefix, char *type)
5297 +{
5298 +       int len;
5299 +       int tabs;
5300 +
5301 +
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]);
5308 +
5309 +       if (streq(type, "void")) {
5310 +               f_print(fout, "0");
5311 +       } else {
5312 +               f_print(fout, "sizeof ( ");
5313 +               /* XXX: should "follow" be 1 ??? */
5314 +               ptype(prefix, type, 0);
5315 +               f_print(fout, ")");
5316 +       }
5317 +       f_print(fout, ",\n");
5318 +}
5319 diff --git a/rpcgen/rpc_util.c b/rpcgen/rpc_util.c
5320 new file mode 100644
5321 index 0000000..b67be57
5322 --- /dev/null
5323 +++ b/rpcgen/rpc_util.c
5324 @@ -0,0 +1,479 @@
5325 +/*
5326 + * Copyright (c) 2009, Sun Microsystems, Inc.
5327 + * All rights reserved.
5328 + *
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.
5339 + *
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.
5351 + */
5352 +
5353 +#if 0
5354 +static char sccsid[] = "@(#)rpc_util.c 1.11 89/02/22 (C) 1987 SMI";
5355 +#endif
5356 +
5357 +/*
5358 + * rpc_util.c, Utility routines for the RPC protocol compiler 
5359 + */
5360 +#include <stdio.h>
5361 +#include <memory.h>
5362 +#include <ctype.h>
5363 +#include <unistd.h>
5364 +#include "rpc_scan.h"
5365 +#include "rpc_parse.h"
5366 +#include "rpc_util.h"
5367 +
5368 +static void    printwhere(void);
5369 +
5370 +
5371 +#define ARGEXT "argument"
5372 +
5373 +char curline[MAXLINESIZE];     /* current read line */
5374 +char *where = curline;         /* current point in line */
5375 +int linenum = 0;               /* current line number */
5376 +
5377 +char *infilename;              /* input filename */
5378 +
5379 +#define NFILES 7
5380 +char *outfiles[NFILES];                /* output file names */
5381 +int nfiles;
5382 +
5383 +FILE *fout;                    /* file pointer of current output */
5384 +FILE *fin;                     /* file pointer of current input */
5385 +
5386 +list *defined;                 /* list of defined things */
5387 +
5388 +/*
5389 + * Reinitialize the world 
5390 + */
5391 +void
5392 +reinitialize(void)
5393 +{
5394 +       memset(curline, 0, MAXLINESIZE);
5395 +       where = curline;
5396 +       linenum = 0;
5397 +       defined = NULL;
5398 +}
5399 +
5400 +/*
5401 + * string equality 
5402 + */
5403 +int
5404 +streq(char *a, char *b)
5405 +{
5406 +       return (strcmp(a, b) == 0);
5407 +}
5408 +
5409 +/*
5410 + * find a value in a list 
5411 + */
5412 +definition *
5413 +findval(list *lst, char *val, int (*cmp)(definition *, char *))
5414 +{
5415 +         
5416 +       for (; lst != NULL; lst = lst->next) {
5417 +               if ((*cmp) (lst->val, val)) {
5418 +                       return (lst->val);
5419 +               }
5420 +       }
5421 +       return (NULL);
5422 +}
5423 +
5424 +/*
5425 + * store a value in a list 
5426 + */
5427 +void
5428 +storeval(lstp, val)
5429 +       list **lstp;
5430 +       definition *val;
5431 +{
5432 +       list **l;
5433 +       list *lst;
5434 +
5435 +       
5436 +       for (l = lstp; *l != NULL; l = (list **) & (*l)->next);
5437 +       lst = ALLOC(list);
5438 +       lst->val = val;
5439 +       lst->next = NULL;
5440 +       *l = lst;
5441 +}
5442 +
5443 +static int
5444 +findit(definition *def, char *type)
5445 +{
5446 +       return (streq(def->def_name, type));
5447 +}
5448 +
5449 +static char *
5450 +fixit(char *type, char *orig)
5451 +{
5452 +       definition *def;
5453 +
5454 +       def = (definition *) FINDVAL(defined, type, findit);
5455 +       if (def == NULL || def->def_kind != DEF_TYPEDEF) {
5456 +               return (orig);
5457 +       }
5458 +       switch (def->def.ty.rel) {
5459 +       case REL_VECTOR:
5460 +               return (def->def.ty.old_type);
5461 +       case REL_ALIAS:
5462 +               return (fixit(def->def.ty.old_type, orig));
5463 +       default:
5464 +               return (orig);
5465 +       }
5466 +}
5467 +
5468 +char *
5469 +fixtype(char *type)
5470 +{
5471 +       return (fixit(type, type));
5472 +}
5473 +
5474 +char *
5475 +stringfix(char *type)
5476 +{
5477 +       if (streq(type, "string")) {
5478 +               return ("wrapstring");
5479 +       } else {
5480 +               return (type);
5481 +       }
5482 +}
5483 +
5484 +void
5485 +ptype(char *prefix, char *type, int follow)
5486 +{
5487 +       if (prefix != NULL) {
5488 +               if (streq(prefix, "enum")) {
5489 +                       f_print(fout, "enum ");
5490 +               } else {
5491 +                       f_print(fout, "struct ");
5492 +               }
5493 +       }
5494 +       if (streq(type, "bool")) {
5495 +               f_print(fout, "bool_t ");
5496 +       } else if (streq(type, "string")) {
5497 +               f_print(fout, "char *");
5498 +       } else {
5499 +               f_print(fout, "%s ", follow ? fixtype(type) : type);
5500 +       }
5501 +}
5502 +
5503 +static int
5504 +typedefed(definition *def, char *type)
5505 +{
5506 +       if (def->def_kind != DEF_TYPEDEF || def->def.ty.old_prefix != NULL) {
5507 +               return (0);
5508 +       } else {
5509 +               return (streq(def->def_name, type));
5510 +       }
5511 +}
5512 +
5513 +int
5514 +isvectordef(char *type, relation rel)
5515 +{
5516 +       definition *def;
5517 +
5518 +       for (;;) {
5519 +               switch (rel) {
5520 +               case REL_VECTOR:
5521 +                       return (!streq(type, "string"));
5522 +               case REL_ARRAY:
5523 +                       return (0);
5524 +               case REL_POINTER:
5525 +                       return (0);
5526 +               case REL_ALIAS:
5527 +                       def = (definition *) FINDVAL(defined, type, typedefed);
5528 +                       if (def == NULL) {
5529 +                               return (0);
5530 +                       }
5531 +                       type = def->def.ty.old_type;
5532 +                       rel = def->def.ty.rel;
5533 +               }
5534 +       }
5535 +}
5536 +
5537 +char *
5538 +locase(char *str)
5539 +{
5540 +       char c;
5541 +       static char buf[100];
5542 +       char *p = buf;
5543 +
5544 +       while ((c = *str++) != '\0') {
5545 +               *p++ = (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c;
5546 +       }
5547 +       *p = 0;
5548 +       return (buf);
5549 +}
5550 +
5551 +void
5552 +pvname_svc(char *pname, char *vnum)
5553 +{
5554 +       f_print(fout, "%s_%s_svc", locase(pname), vnum);
5555 +}
5556 +
5557 +void
5558 +pvname(char *pname, char *vnum)
5559 +{
5560 +       f_print(fout, "%s_%s", locase(pname), vnum);
5561 +}
5562 +
5563 +/*
5564 + * print a useful (?) error message, and then die 
5565 + */
5566 +void
5567 +error(char *msg)
5568 +{
5569 +       printwhere();
5570 +       f_print(stderr, "%s, line %d: ", infilename, linenum);
5571 +       f_print(stderr, "%s\n", msg);
5572 +       crash();
5573 +}
5574 +
5575 +/*
5576 + * Something went wrong, unlink any files that we may have created and then
5577 + * die. 
5578 + */
5579 +void
5580 +crash(void)
5581 +{
5582 +       int i;
5583 +
5584 +       for (i = 0; i < nfiles; i++) {
5585 +               (void) unlink(outfiles[i]);
5586 +       }
5587 +       exit(1);
5588 +}
5589 +
5590 +void
5591 +record_open(char *file)
5592 +{
5593 +       if (nfiles < NFILES) {
5594 +               outfiles[nfiles++] = file;
5595 +       } else {
5596 +               f_print(stderr, "too many files!\n");
5597 +               crash();
5598 +       }
5599 +}
5600 +
5601 +static char expectbuf[100];
5602 +static char *toktostr();
5603 +
5604 +/*
5605 + * error, token encountered was not the expected one 
5606 + */
5607 +void
5608 +expected1(exp1)
5609 +       tok_kind exp1;
5610 +{
5611 +       s_print(expectbuf, "expected '%s'",
5612 +               toktostr(exp1));
5613 +       error(expectbuf);
5614 +}
5615 +
5616 +/*
5617 + * error, token encountered was not one of two expected ones 
5618 + */
5619 +void
5620 +expected2(exp1, exp2)
5621 +       tok_kind exp1, exp2;
5622 +{
5623 +       s_print(expectbuf, "expected '%s' or '%s'",
5624 +               toktostr(exp1),
5625 +               toktostr(exp2));
5626 +       error(expectbuf);
5627 +}
5628 +
5629 +/*
5630 + * error, token encountered was not one of 3 expected ones 
5631 + */
5632 +void
5633 +expected3(exp1, exp2, exp3)
5634 +       tok_kind exp1, exp2, exp3;
5635 +{
5636 +       s_print(expectbuf, "expected '%s', '%s' or '%s'",
5637 +               toktostr(exp1),
5638 +               toktostr(exp2),
5639 +               toktostr(exp3));
5640 +       error(expectbuf);
5641 +}
5642 +
5643 +void
5644 +tabify(f, tab)
5645 +       FILE *f;
5646 +       int tab;
5647 +{
5648 +       while (tab--) {
5649 +               (void) fputc('\t', f);
5650 +       }
5651 +}
5652 +
5653 +
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, "]"},
5663 +                            {TOK_STAR, "*"},
5664 +                            {TOK_COMMA, ","},
5665 +                            {TOK_EQUAL, "="},
5666 +                            {TOK_COLON, ":"},
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"},
5675 +                            {TOK_INT, "int"},
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, "??????"}
5689 +};
5690 +
5691 +static char *
5692 +toktostr(kind)
5693 +       tok_kind kind;
5694 +{
5695 +       token *sp;
5696 +
5697 +       for (sp = tokstrings; sp->kind != TOK_EOF && sp->kind != kind; sp++);
5698 +       return (sp->str);
5699 +}
5700 +
5701 +static void
5702 +printbuf(void)
5703 +{
5704 +       char c;
5705 +       int i;
5706 +       int cnt;
5707 +
5708 +#      define TABSIZE 4
5709 +
5710 +       for (i = 0; (c = curline[i]) != '\0'; i++) {
5711 +               if (c == '\t') {
5712 +                       cnt = 8 - (i % TABSIZE);
5713 +                       c = ' ';
5714 +               } else {
5715 +                       cnt = 1;
5716 +               }
5717 +               while (cnt--) {
5718 +                       (void) fputc(c, stderr);
5719 +               }
5720 +       }
5721 +}
5722 +
5723 +static void
5724 +printwhere(void)
5725 +{
5726 +       int i;
5727 +       char c;
5728 +       int cnt;
5729 +
5730 +       printbuf();
5731 +       for (i = 0; i < where - curline; i++) {
5732 +               c = curline[i];
5733 +               if (c == '\t') {
5734 +                       cnt = 8 - (i % TABSIZE);
5735 +               } else {
5736 +                       cnt = 1;
5737 +               }
5738 +               while (cnt--) {
5739 +                       (void) fputc('^', stderr);
5740 +               }
5741 +       }
5742 +       (void) fputc('\n', stderr);
5743 +}
5744 +
5745 +char * 
5746 +make_argname(char *pname, char *vname) 
5747 +{
5748 +       char *name;
5749 +       
5750 +       name = malloc(strlen(pname) + strlen(vname) + strlen(ARGEXT) + 3);
5751 +       if (!name) {
5752 +               fprintf(stderr, "failed in malloc");
5753 +               exit(1);
5754 +       }
5755 +       sprintf(name, "%s_%s_%s", locase(pname), vname, ARGEXT);
5756 +       return(name);
5757 +}
5758 +
5759 +bas_type *typ_list_h;
5760 +bas_type *typ_list_t;
5761 +
5762 +void
5763 +add_type(int len, char *type)
5764 +{
5765 +       bas_type       *ptr;
5766 +
5767 +
5768 +       if ((ptr = (bas_type *) malloc(sizeof(bas_type))) == (bas_type *) NULL) {
5769 +               fprintf(stderr, "failed in malloc");
5770 +               exit(1);
5771 +       }
5772 +       ptr->name = type;
5773 +       ptr->length = len;
5774 +       ptr->next = NULL;
5775 +       if (typ_list_t == NULL) {
5776 +
5777 +               typ_list_t = ptr;
5778 +               typ_list_h = ptr;
5779 +       } else {
5780 +
5781 +               typ_list_t->next = ptr;
5782 +               typ_list_t = ptr;
5783 +       }
5784 +}
5785 +
5786 +
5787 +bas_type *
5788 +find_type(char *type)
5789 +{
5790 +       bas_type       *ptr;
5791 +
5792 +       ptr = typ_list_h;
5793 +
5794 +
5795 +       while (ptr != NULL) {
5796 +               if (strcmp(ptr->name, type) == 0)
5797 +                       return (ptr);
5798 +               else
5799 +                       ptr = ptr->next;
5800 +       };
5801 +       return (NULL);
5802 +}
5803 +
5804 diff --git a/rpcgen/rpc_util.h b/rpcgen/rpc_util.h
5805 new file mode 100644
5806 index 0000000..fa115be
5807 --- /dev/null
5808 +++ b/rpcgen/rpc_util.h
5809 @@ -0,0 +1,166 @@
5810 +/*
5811 + * Copyright (c) 2009, Sun Microsystems, Inc.
5812 + * All rights reserved.
5813 + *
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.
5824 + *
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.
5836 + */
5837 +
5838 +/*      @(#)rpc_util.h  1.5  90/08/29  (C) 1987 SMI   */
5839 +
5840 +/*
5841 + * rpc_util.h, Useful definitions for the RPC protocol compiler 
5842 + */
5843 +
5844 +#include <stdlib.h>
5845 +
5846 +#define alloc(size)            malloc((unsigned)(size))
5847 +#define ALLOC(object)   (object *) malloc(sizeof(object))
5848 +
5849 +#define s_print        (void) sprintf
5850 +#define f_print (void) fprintf
5851 +
5852 +struct list {
5853 +       definition *val;
5854 +       struct list *next;
5855 +};
5856 +typedef struct list list;
5857 +
5858 +#define PUT 1
5859 +#define GET 2
5860 +
5861 +/*
5862 + * Global variables 
5863 + */
5864 +#define MAXLINESIZE 1024
5865 +extern char curline[MAXLINESIZE];
5866 +extern char *where;
5867 +extern int linenum;
5868 +
5869 +extern char *infilename;
5870 +extern FILE *fout;
5871 +extern FILE *fin;
5872 +
5873 +extern list *defined;
5874 +
5875 +
5876 +extern bas_type *typ_list_h;
5877 +extern bas_type *typ_list_t;
5878 +
5879 +/*
5880 + * All the option flags
5881 + */
5882 +extern int inetdflag;
5883 +extern int pmflag;   
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 */
5890 +
5891 +/*
5892 + * Other flags related with inetd jumpstart.
5893 + */
5894 +extern int indefinitewait;
5895 +extern int exitnow;
5896 +extern int timerflag;
5897 +
5898 +extern int nonfatalerrors;
5899 +
5900 +/*
5901 + * rpc_util routines 
5902 + */
5903 +void storeval();
5904 +
5905 +#define STOREVAL(list,item)    \
5906 +       storeval(list,item)
5907 +
5908 +definition *findval();
5909 +
5910 +#define FINDVAL(list,item,finder) \
5911 +       findval(list, item, finder)
5912 +
5913 +
5914 +/*
5915 + * rpc_cout routines
5916 + */
5917 +void            cprint(void);
5918 +void            emit(definition *);
5919 +
5920 +/*
5921 + * rpc_hout routines
5922 + */
5923 +void            print_datadef(definition *);
5924 +void            print_funcdef(definition *);
5925 +
5926 +/*
5927 + * rpc_svcout routines
5928 + */
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);
5937 +
5938 +/*
5939 + * rpc_clntout routines
5940 + */
5941 +void            write_stubs(void);
5942 +void           printarglist(proc_list *, char *, char *);
5943 +
5944 +/*
5945 + * rpc_tblout routines
5946 + */
5947 +void            write_tables(void);
5948 +
5949 +/*
5950 + * rpc_util
5951 + */
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);
5958 +void           crash(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);
5968 +
5969 +/*
5970 + * rpc_sample
5971 + */
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
5979 --- /dev/null
5980 +++ b/rpcgen/rpcgen.1
5981 @@ -0,0 +1,521 @@
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.
5985 +.Dd March 28, 1993
5986 +.Dt RPCGEN 1
5987 +.Os
5988 +.Sh NAME
5989 +.Nm rpcgen
5990 +.Nd an RPC protocol compiler
5991 +.Sh SYNOPSIS
5992 +.Nm
5993 +.Ar infile
5994 +.Nm
5995 +.Op Fl a
5996 +.Op Fl b
5997 +.Op Fl C
5998 +.Oo
5999 +.Fl D Ns Ar name Ns Op Ar =value
6000 +.Oc
6001 +.Op Fl i Ar size
6002 +.Op Fl I Op Fl K Ar seconds
6003 +.Op Fl L
6004 +.Op Fl M
6005 +.Op Fl N
6006 +.Op Fl T
6007 +.Op Fl Y Ar pathname
6008 +.Ar infile
6009 +.Nm
6010 +.Oo
6011 +.Fl c |
6012 +.Fl h |
6013 +.Fl l |
6014 +.Fl m |
6015 +.Fl t |
6016 +.Fl \&Sc |
6017 +.Fl \&Ss |
6018 +.Fl \&Sm
6019 +.Oc
6020 +.Op Fl o Ar outfile
6021 +.Op Ar infile
6022 +.Nm
6023 +.Op Fl s Ar nettype
6024 +.Op Fl o Ar outfile
6025 +.Op Ar infile
6026 +.Nm
6027 +.Op Fl n Ar netid
6028 +.Op Fl o Ar outfile
6029 +.Op Ar infile
6030 +.\" .SH AVAILABILITY
6031 +.\" .LP
6032 +.\" SUNWcsu
6033 +.Sh DESCRIPTION
6034 +The
6035 +.Nm
6036 +utility is a tool that generates C code to implement an
6037 +.Tn RPC
6038 +protocol.
6039 +The input to
6040 +.Nm
6041 +is a language similar to C known as
6042 +.Tn RPC
6043 +Language (Remote Procedure Call Language).
6044 +.Pp
6045 +The
6046 +.Nm
6047 +utility is normally used as in the first synopsis where
6048 +it takes an input file and generates three output files.
6049 +If the
6050 +.Ar infile
6051 +is named
6052 +.Pa proto.x ,
6053 +then
6054 +.Nm
6055 +generates a header in
6056 +.Pa proto.h ,
6057 +XDR routines in
6058 +.Pa proto_xdr.c ,
6059 +server-side stubs in
6060 +.Pa proto_svc.c ,
6061 +and client-side stubs in
6062 +.Pa proto_clnt.c .
6063 +With the
6064 +.Fl T
6065 +option,
6066 +it also generates the
6067 +.Tn RPC
6068 +dispatch table in
6069 +.Pa proto_tbl.i .
6070 +.Pp
6071 +The
6072 +.Nm
6073 +utility can also generate sample client and server files
6074 +that can be customized to suit a particular application.
6075 +The
6076 +.Fl \&Sc ,
6077 +.Fl \&Ss
6078 +and
6079 +.Fl \&Sm
6080 +options generate sample client, server and makefile, respectively.
6081 +The
6082 +.Fl a
6083 +option generates all files, including sample files.
6084 +If the
6085 +.Ar infile
6086 +is
6087 +.Pa proto.x ,
6088 +then the client side sample file is written to
6089 +.Pa proto_client.c ,
6090 +the server side sample file to
6091 +.Pa proto_server.c
6092 +and the sample makefile to
6093 +.Pa makefile.proto .
6094 +.Pp
6095 +The server created can be started both by the port monitors
6096 +(for example,
6097 +.Xr inetd 8 )
6098 +or by itself.
6099 +When it is started by a port monitor,
6100 +it creates servers only for the transport for which
6101 +the file descriptor
6102 +.Em 0
6103 +was passed.
6104 +The name of the transport must be specified
6105 +by setting up the environment variable
6106 +.Ev PM_TRANSPORT .
6107 +When the server generated by
6108 +.Nm
6109 +is executed,
6110 +it creates server handles for all the transports
6111 +specified in
6112 +.Ev NETPATH
6113 +environment variable,
6114 +or if it is unset,
6115 +it creates server handles for all the visible transports from
6116 +.Pa /etc/netconfig
6117 +file.
6118 +Note:
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
6123 +.Em RPC_SVC_FG
6124 +can be used to run the server process in foreground.
6125 +.Pp
6126 +The second synopsis provides special features which allow
6127 +for the creation of more sophisticated
6128 +.Tn RPC
6129 +servers.
6130 +These features include support for user provided
6131 +.Em #defines
6132 +and
6133 +.Tn RPC
6134 +dispatch tables.
6135 +The entries in the
6136 +.Tn RPC
6137 +dispatch table contain:
6138 +.Bl -bullet -offset indent -compact
6139 +.It
6140 +pointers to the service routine corresponding to that procedure,
6141 +.It
6142 +a pointer to the input and output arguments,
6143 +.It
6144 +the size of these routines.
6145 +.El
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.
6150 +.Pp
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.
6154 +See the
6155 +.Sx EXAMPLES
6156 +section below for examples of
6157 +.Nm
6158 +usage.
6159 +When
6160 +.Nm
6161 +is executed with the
6162 +.Fl s
6163 +option,
6164 +it creates servers for that particular class of transports.
6165 +When
6166 +executed with the
6167 +.Fl n
6168 +option,
6169 +it creates a server for the transport specified by
6170 +.Ar netid .
6171 +If
6172 +.Ar infile
6173 +is not specified,
6174 +.Nm
6175 +accepts the standard input.
6176 +.Pp
6177 +The C preprocessor,
6178 +.Em cc -E
6179 +is run on the input file before it is actually interpreted by
6180 +.Nm .
6181 +For each type of output file,
6182 +.Nm
6183 +defines a special preprocessor symbol for use by the
6184 +.Nm
6185 +programmer:
6186 +.Bl -tag -width indent
6187 +.It RPC_HDR
6188 +defined when compiling into headers
6189 +.It RPC_XDR
6190 +defined when compiling into XDR routines
6191 +.It RPC_SVC
6192 +defined when compiling into server-side stubs
6193 +.It RPC_CLNT
6194 +defined when compiling into client-side stubs
6195 +.It RPC_TBL
6196 +defined when compiling into RPC dispatch tables
6197 +.El
6198 +.Pp
6199 +Any line beginning with
6200 +.Dq %
6201 +is passed directly into the output file,
6202 +uninterpreted by
6203 +.Nm .
6204 +To specify the path name of the C preprocessor use
6205 +.Fl Y
6206 +flag.
6207 +.Pp
6208 +For every data type referred to in
6209 +.Ar infile ,
6210 +.Nm
6211 +assumes that there exists a
6212 +routine with the string
6213 +.Em xdr_
6214 +prepended to the name of the data type.
6215 +If this routine does not exist in the
6216 +.Tn RPC/XDR
6217 +library, it must be provided.
6218 +Providing an undefined data type
6219 +allows customization of
6220 +.Xr xdr 3
6221 +routines.
6222 +.Sh OPTIONS
6223 +The following options are available:
6224 +.Bl -tag -width indent
6225 +.It Fl a
6226 +Generate all files, including sample files.
6227 +.It Fl b
6228 +Backward compatibility mode.
6229 +Generate transport specific
6230 +.Tn RPC
6231 +code for older versions
6232 +of the operating system.
6233 +.Pp
6234 +Note: in
6235 +.Fx ,
6236 +this compatibility flag is turned on by
6237 +default since
6238 +.Fx
6239 +supports only the older
6240 +.Tn ONC RPC
6241 +library.
6242 +.It Fl c
6243 +Compile into
6244 +.Tn XDR
6245 +routines.
6246 +.It Fl C
6247 +Generate header and stub files which can be used with
6248 +.Tn ANSI
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
6254 +Define a symbol
6255 +.Ar name .
6256 +Equivalent to the
6257 +.Em #define
6258 +directive in the source.
6259 +If no
6260 +.Ar value
6261 +is given,
6262 +.Ar value
6263 +is defined as
6264 +.Em 1 .
6265 +This option may be specified more than once.
6266 +.It Fl h
6267 +Compile into C data-definitions (a header).
6268 +.Fl T
6269 +option can be used in conjunction to produce a
6270 +header which supports
6271 +.Tn RPC
6272 +dispatch tables.
6273 +.It Fl i Ar size
6274 +Size at which to start generating inline code.
6275 +This option is useful for optimization.
6276 +The default size is 5.
6277 +.Pp
6278 +Note: in order to provide backwards compatibility with the older
6279 +.Nm
6280 +on the
6281 +.Fx
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.
6285 +.It Fl I
6286 +Compile support for
6287 +.Xr inetd 8
6288 +in the server side stubs.
6289 +Such servers can be self-started or can be started by
6290 +.Nm inetd .
6291 +When the server is self-started, it backgrounds itself by default.
6292 +A special define symbol
6293 +.Em RPC_SVC_FG
6294 +can be used to run the
6295 +server process in foreground, or the user may simply compile without
6296 +the
6297 +.Fl I
6298 +option.
6299 +.Pp
6300 +If there are no pending client requests, the
6301 +.Nm inetd
6302 +servers exit after 120 seconds (default).
6303 +The default can be changed with the
6304 +.Fl K
6305 +option.
6306 +All the error messages for
6307 +.Nm inetd
6308 +servers
6309 +are always logged with
6310 +.Xr syslog 3 .
6311 +.\" .IP
6312 +.\" Note:
6313 +.\" this option is supported for backward compatibility only.
6314 +.\" By default,
6315 +.\" .B rpcgen
6316 +.\" generates servers that can be invoked through portmonitors.
6317 +.Pp
6318 +.It Fl K Ar seconds
6319 +By default, services created using
6320 +.Nm
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
6325 +.Fl K
6326 +flag.
6327 +To create a server that exits immediately upon servicing a request,
6328 +use
6329 +.Fl K Ar 0 .
6330 +To create a server that never exits, the appropriate argument is
6331 +.Fl k Ar -1 .
6332 +.Pp
6333 +When monitoring for a server,
6334 +some portmonitors
6335 +.Em always
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.
6339 +For such servers,
6340 +.Nm
6341 +should be used with
6342 +.Fl K Ar 0 .
6343 +.It Fl l
6344 +Compile into client-side stubs.
6345 +.It Fl L
6346 +When the servers are started in foreground, use
6347 +.Xr syslog 3
6348 +to log the server errors instead of printing them on the standard
6349 +error.
6350 +.It Fl m
6351 +Compile into server-side stubs,
6352 +but do not generate a
6353 +.Qq main
6354 +routine.
6355 +This option is useful for doing callback-routines
6356 +and for users who need to write their own
6357 +.Qq main
6358 +routine to do initialization.
6359 +.It Fl M
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.
6364 +However, the
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.
6368 +.It Fl N
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
6374 +.Nm
6375 +generated code.
6376 +To maintain backward compatibility,
6377 +this option is not the default.
6378 +.It Fl n Ar netid
6379 +Compile into server-side stubs for the transport
6380 +specified by
6381 +.Ar netid .
6382 +There should be an entry for
6383 +.Ar netid
6384 +in the
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
6392 +(
6393 +.Fl c ,
6394 +.Fl h ,
6395 +.Fl l ,
6396 +.Fl m ,
6397 +.Fl n ,
6398 +.Fl s ,
6399 +.Fl \&Sc ,
6400 +.Fl \&Sm ,
6401 +.Fl \&Ss ,
6402 +and
6403 +.Fl t
6404 +modes only).
6405 +.It Fl s Ar nettype
6406 +Compile into server-side stubs for all the
6407 +transports belonging to the class
6408 +.Ar nettype .
6409 +The supported classes are
6410 +.Em netpath ,
6411 +.Em visible ,
6412 +.Em circuit_n ,
6413 +.Em circuit_v ,
6414 +.Em datagram_n ,
6415 +.Em datagram_v ,
6416 +.Em tcp ,
6417 +and
6418 +.Em udp
6419 +(see
6420 +.Xr rpc 3
6421 +for the meanings associated with these classes).
6422 +This option may be specified more than once.
6423 +Note:
6424 +the transports are chosen at run time and not at compile time.
6425 +.It Fl \&Sc
6426 +Generate sample client code that uses remote procedure calls.
6427 +.It Fl \&Sm
6428 +Generate a sample
6429 +.Pa Makefile
6430 +which can be used for compiling the application.
6431 +.It Fl \&Ss
6432 +Generate sample server code that uses remote procedure calls.
6433 +.It Fl t
6434 +Compile into
6435 +.Tn RPC
6436 +dispatch table.
6437 +.It Fl T
6438 +Generate the code to support
6439 +.Tn RPC
6440 +dispatch tables.
6441 +.Pp
6442 +The options
6443 +.Fl c ,
6444 +.Fl h ,
6445 +.Fl l ,
6446 +.Fl m ,
6447 +.Fl s ,
6448 +.Fl \&Sc ,
6449 +.Fl \&Sm ,
6450 +.Fl \&Ss ,
6451 +and
6452 +.Fl t
6453 +are used exclusively to generate a particular type of file,
6454 +while the options
6455 +.Fl D
6456 +and
6457 +.Fl T
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
6461 +.Nm
6462 +will start looking for the C-preprocessor.
6463 +.El
6464 +.Sh EXAMPLES
6465 +The following example:
6466 +.Dl example% rpcgen -T prot.x
6467 +.Pp
6468 +generates all the five files:
6469 +.Pa prot.h ,
6470 +.Pa prot_clnt.c ,
6471 +.Pa prot_svc.c ,
6472 +.Pa prot_xdr.c
6473 +and
6474 +.Pa prot_tbl.i .
6475 +.Pp
6476 +The following example sends the C data-definitions (header)
6477 +to the standard output.
6478 +.Dl example% rpcgen -h prot.x
6479 +.Pp
6480 +To send the test version of the
6481 +.Fl D Ns Ar TEST ,
6482 +server side stubs for
6483 +all the transport belonging to the class
6484 +.Ar datagram_n
6485 +to standard output, use:
6486 +.Dl example% rpcgen -s datagram_n -DTEST prot.x
6487 +.Pp
6488 +To create the server side stubs for the transport indicated
6489 +by
6490 +.Ar netid
6491 +tcp,
6492 +use:
6493 +.Dl example% rpcgen -n tcp -o prot_svc.c prot.x
6494 +.Sh SEE ALSO
6495 +.Xr cc 1 ,
6496 +.Xr rpc 3 ,
6497 +.Xr syslog 3 ,
6498 +.Xr inetd 8
6499 +.\" .BR rpc_svc_calls (3)
6500 +.Rs
6501 +.%T The rpcgen chapter in the NETP manual
6502 +.Re
6503 -- 
6504 2.0.0
6505