Add xdr_quad_t and xdr_u_quad_t aliases.
[kopensolaris-gnu/glibc.git] / sunrpc / rpc_svcout.c
1 /*
2  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
3  * unrestricted use provided that this legend is included on all tape
4  * media and as a part of the software program in whole or part.  Users
5  * may copy or modify Sun RPC without charge, but are not authorized
6  * to license or distribute it to anyone else except as part of a product or
7  * program developed by the user or with the express written consent of
8  * Sun Microsystems, Inc.
9  *
10  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
11  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
12  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
13  *
14  * Sun RPC is provided with no support and without any obligation on the
15  * part of Sun Microsystems, Inc. to assist in its use, correction,
16  * modification or enhancement.
17  *
18  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
19  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
20  * OR ANY PART THEREOF.
21  *
22  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
23  * or profits or other special, indirect and consequential damages, even if
24  * Sun has been advised of the possibility of such damages.
25  *
26  * Sun Microsystems, Inc.
27  * 2550 Garcia Avenue
28  * Mountain View, California  94043
29  */
30
31 /*
32  * From: @(#)rpc_svcout.c 1.29 89/03/30 (C) 1987 SMI
33  */
34 char svcout_rcsid[] =
35   "$Id$";
36
37 /*
38  * rpc_svcout.c, Server-skeleton outputter for the RPC protocol compiler
39  */
40 #include <stdio.h>
41 #include <string.h>
42 #include "rpc_parse.h"
43 #include "rpc_util.h"
44 #include "proto.h"
45
46 static const char RQSTP[] = "rqstp";
47 static const char TRANSP[] = "transp";
48 static const char ARG[] = "argument";
49 static const char RESULT[] = "result";
50 static const char ROUTINE[] = "local";
51 static char RETVAL[] = "retval";
52
53 char _errbuf[256];              /* For all messages */
54
55 static void internal_proctype (const proc_list * plist);
56 static void p_xdrfunc (const char *rname, const char *typename);
57 static void write_real_program (const definition * def);
58 static void write_program (const definition * def, const char *storage);
59 static void printerr (const char *err, const char *transp);
60 static void printif (const char *proc, const char *transp, const char *arg);
61 static void write_inetmost (const char *infile);
62 static void print_return (const char *space);
63 static void print_pmapunset (const char *space);
64 static void print_err_message (const char *space);
65 static void write_timeout_func (void);
66 static void write_pm_most (const char *infile, int netflag);
67 static void write_rpc_svc_fg (const char *infile, const char *sp);
68 static void open_log_file (const char *infile, const char *sp);
69
70 static void
71 p_xdrfunc (const char *rname, const char *typename)
72 {
73   if (Cflag)
74     f_print (fout, "\t\t_xdr_%s = (xdrproc_t) xdr_%s;\n", rname,
75              stringfix (typename));
76   else
77     f_print (fout, "\t\t_xdr_%s = xdr_%s;\n", rname, stringfix (typename));
78 }
79
80 void
81 internal_proctype (const proc_list * plist)
82 {
83   f_print (fout, "static ");
84   ptype (plist->res_prefix, plist->res_type, 1);
85   f_print (fout, "*");
86 }
87
88
89 /*
90  * write most of the service, that is, everything but the registrations.
91  */
92 void
93 write_most (const char *infile /* our name */ , int netflag, int nomain)
94 {
95   if (inetdflag || pmflag)
96     {
97       const char *var_type;
98 #ifdef __GNU_LIBRARY__
99       /* WHY? */
100       var_type = (nomain ? "extern" : "");
101 #else
102       var_type = (nomain ? "extern" : "static");
103 #endif
104       f_print (fout, "%s int _rpcpmstart;", var_type);
105       f_print (fout, "\t\t/* Started by a port monitor ? */\n");
106       if (!tirpcflag)
107         {
108           f_print (fout, "%s int _rpcfdtype;", var_type);
109           f_print (fout, "\t\t/* Whether Stream or Datagram ? */\n");
110         }
111       if (timerflag)
112         {
113 #if 0
114           f_print (fout, "%s int _rpcsvcdirty;", var_type);
115           f_print (fout, "\t/* Still serving ? */\n");
116 #else
117           f_print(fout, " /* States a server can be in wrt request */\n\n");
118           f_print(fout, "#define\t_IDLE 0\n");
119           f_print(fout, "#define\t_SERVED 1\n");
120           f_print(fout, "#define\t_SERVING 2\n\n");
121           f_print(fout, "static int _rpcsvcstate = _IDLE;");
122           f_print(fout, "\t /* Set when a request is serviced */\n");
123
124           if (mtflag)
125             {
126               f_print (fout, "mutex_t _svcstate_lock;");
127               f_print (fout,
128                        "\t\t\t/* Mutex lock for variable_rpcsvcstate */\n");
129             }
130 #endif
131         }
132       write_svc_aux (nomain);
133     }
134   /* write out dispatcher and stubs */
135   write_programs (nomain ? NULL : "static");
136
137   if (nomain)
138     return;
139
140 #ifdef __GNU_LIBRARY__
141   if (Cflag)
142     f_print (fout, "\nint\nmain (int argc, char **argv)\n");
143   else
144     {
145       f_print (fout, "\nint\nmain (argc, argv)\n");
146       f_print (fout, "\tint argc;\n");
147       f_print (fout, "\tchar **argv;\n");
148     }
149 #else
150   f_print (fout, "\nmain()\n");
151 #endif
152   f_print (fout, "{\n");
153   if (inetdflag)
154     {
155       write_inetmost (infile);  /* Includes call to write_rpc_svc_fg() */
156     }
157   else
158     {
159       if (tirpcflag)
160         {
161           if (netflag)
162             {
163               f_print (fout, "\tregister SVCXPRT *%s;\n", TRANSP);
164               f_print (fout, "\tstruct netconfig *nconf = NULL;\n");
165             }
166           f_print (fout, "\tpid_t pid;\n");
167           f_print (fout, "\tint i;\n");
168           f_print (fout, "\tchar mname[FMNAMESZ + 1];\n\n");
169
170           if (mtflag & timerflag)
171             f_print (fout,
172                      "\tmutex_init (&_svcstate_lock, USYNC_THREAD, NULL);\n");
173
174           write_pm_most (infile, netflag);
175           f_print (fout, "\telse {\n");
176           write_rpc_svc_fg (infile, "\t\t");
177           f_print (fout, "\t}\n");
178         }
179       else
180         {
181           f_print (fout, "\tregister SVCXPRT *%s;\n", TRANSP);
182           f_print (fout, "\n");
183           print_pmapunset ("\t");
184         }
185     }
186
187   if (logflag && !inetdflag)
188     {
189       open_log_file (infile, "\t");
190     }
191 }
192
193 /*
194  * write a registration for the given transport
195  */
196 void
197 write_netid_register (const char *transp)
198 {
199   list *l;
200   definition *def;
201   version_list *vp;
202   const char *sp;
203   char tmpbuf[32];
204
205   sp = "";
206   f_print (fout, "\n");
207   f_print (fout, "%s\tnconf = getnetconfigent (\"%s\");\n", sp, transp);
208   f_print (fout, "%s\tif (nconf == NULL) {\n", sp);
209   (void) sprintf (_errbuf, "cannot find %s netid.", transp);
210   sprintf (tmpbuf, "%s\t\t", sp);
211   print_err_message (tmpbuf);
212   f_print (fout, "%s\t\texit (1);\n", sp);
213   f_print (fout, "%s\t}\n", sp);
214   f_print (fout, "%s\t%s = svc_tli_create (RPC_ANYFD, nconf, 0, 0, 0);\n",
215            sp, TRANSP /*, transp *//* ?!?... */ );
216   f_print (fout, "%s\tif (%s == NULL) {\n", sp, TRANSP);
217   sprintf (_errbuf, "cannot create %s service.", transp);
218   print_err_message (tmpbuf);
219   f_print (fout, "%s\t\texit (1);\n", sp);
220   f_print (fout, "%s\t}\n", sp);
221
222   for (l = defined; l != NULL; l = l->next)
223     {
224       def = (definition *) l->val;
225       if (def->def_kind != DEF_PROGRAM)
226         {
227           continue;
228         }
229       for (vp = def->def.pr.versions; vp != NULL; vp = vp->next)
230         {
231           f_print (fout, "%s\t(void) rpcb_unset (%s, %s, nconf);\n",
232                    sp, def->def_name, vp->vers_name);
233           f_print (fout, "%s\tif (!svc_reg (%s, %s, %s, ",
234                    sp, TRANSP, def->def_name, vp->vers_name);
235           pvname (def->def_name, vp->vers_num);
236           f_print (fout, ", nconf)) {\n");
237           (void) sprintf (_errbuf, "unable to register (%s, %s, %s).",
238                           def->def_name, vp->vers_name, transp);
239           print_err_message (tmpbuf);
240           f_print (fout, "%s\t\texit (1);\n", sp);
241           f_print (fout, "%s\t}\n", sp);
242         }
243     }
244   f_print (fout, "%s\tfreenetconfigent (nconf);\n", sp);
245 }
246
247 /*
248  * write a registration for the given transport for TLI
249  */
250 void
251 write_nettype_register (const char *transp)
252 {
253   list *l;
254   definition *def;
255   version_list *vp;
256
257   for (l = defined; l != NULL; l = l->next)
258     {
259       def = (definition *) l->val;
260       if (def->def_kind != DEF_PROGRAM)
261         {
262           continue;
263         }
264       for (vp = def->def.pr.versions; vp != NULL; vp = vp->next)
265         {
266           f_print (fout, "\tif (!svc_create (");
267           pvname (def->def_name, vp->vers_num);
268           f_print (fout, ", %s, %s, \"%s\")) {\n ",
269                    def->def_name, vp->vers_name, transp);
270           (void) sprintf (_errbuf,
271                           "unable to create (%s, %s) for %s.",
272                           def->def_name, vp->vers_name, transp);
273           print_err_message ("\t\t");
274           f_print (fout, "\t\texit (1);\n");
275           f_print (fout, "\t}\n");
276         }
277     }
278 }
279
280 /*
281  * write the rest of the service
282  */
283 void
284 write_rest (void)
285 {
286   f_print (fout, "\n");
287   if (inetdflag)
288     {
289       f_print (fout, "\tif (%s == (SVCXPRT *)NULL) {\n", TRANSP);
290       (void) sprintf (_errbuf, "could not create a handle");
291       print_err_message ("\t\t");
292       f_print (fout, "\t\texit (1);\n");
293       f_print (fout, "\t}\n");
294       if (timerflag)
295         {
296           f_print (fout, "\tif (_rpcpmstart) {\n");
297           f_print (fout,
298                    "\t\t(void) signal (SIGALRM, %s closedown);\n",
299                    Cflag ? "(SIG_PF)" : "(void(*)())");
300           f_print (fout, "\t\t(void) alarm (_RPCSVC_CLOSEDOWN);\n");
301           f_print (fout, "\t}\n");
302         }
303     }
304   f_print (fout, "\tsvc_run ();\n");
305   (void) sprintf (_errbuf, "svc_run returned");
306   print_err_message ("\t");
307   f_print (fout, "\texit (1);\n");
308   f_print (fout, "\t/* NOTREACHED */\n");
309   f_print (fout, "}\n");
310 }
311
312 void
313 write_programs (const char *storage)
314 {
315   list *l;
316   definition *def;
317
318   /* write out stubs for procedure  definitions */
319   for (l = defined; l != NULL; l = l->next)
320     {
321       def = (definition *) l->val;
322       if (def->def_kind == DEF_PROGRAM)
323         {
324           write_real_program (def);
325         }
326     }
327
328   /* write out dispatcher for each program */
329   for (l = defined; l != NULL; l = l->next)
330     {
331       def = (definition *) l->val;
332       if (def->def_kind == DEF_PROGRAM)
333         {
334           write_program (def, storage);
335         }
336     }
337 }
338
339 /* write out definition of internal function (e.g. _printmsg_1(...))
340    which calls server's defintion of actual function (e.g. printmsg_1(...)).
341    Unpacks single user argument of printmsg_1 to call-by-value format
342    expected by printmsg_1. */
343 static void
344 write_real_program (const definition * def)
345 {
346   version_list *vp;
347   proc_list *proc;
348   decl_list *l;
349
350   if (!newstyle)
351     return;                     /* not needed for old style */
352   for (vp = def->def.pr.versions; vp != NULL; vp = vp->next)
353     {
354       for (proc = vp->procs; proc != NULL; proc = proc->next)
355         {
356           fprintf (fout, "\n");
357           if (!mtflag)
358             internal_proctype (proc);
359           else
360             f_print (fout, "int");
361           f_print (fout, "\n_");
362           pvname (proc->proc_name, vp->vers_num);
363           if (Cflag)
364             {
365               f_print (fout, " (");
366               /* arg name */
367               if (proc->arg_num > 1)
368                 f_print (fout, proc->args.argname);
369               else
370                 ptype (proc->args.decls->decl.prefix,
371                        proc->args.decls->decl.type, 0);
372               if (mtflag)
373                 {
374                   f_print(fout, " *argp, void *%s, struct svc_req *%s)\n",
375                           RESULT, RQSTP);
376                 }
377               else
378                 f_print (fout, " *argp, struct svc_req *%s)\n",
379                          RQSTP);
380             }
381           else
382             {
383               if (mtflag)
384                 f_print(fout, " (argp, %s, %s)\n", RESULT, RQSTP);
385               else
386                 f_print (fout, " (argp, %s)\n", RQSTP);
387               /* arg name */
388               if (proc->arg_num > 1)
389                 f_print (fout, "\t%s *argp;\n", proc->args.argname);
390               else
391                 {
392                   f_print (fout, "\t");
393                   ptype (proc->args.decls->decl.prefix,
394                          proc->args.decls->decl.type, 0);
395                   f_print (fout, " *argp;\n");
396                 }
397               f_print (fout, "  struct svc_req *%s;\n", RQSTP);
398             }
399
400           f_print (fout, "{\n");
401           f_print (fout, "\treturn (");
402           if (Cflag || mtflag)
403             pvname_svc (proc->proc_name, vp->vers_num);
404           else
405             pvname (proc->proc_name, vp->vers_num);
406           f_print (fout, "(");
407           if (proc->arg_num < 2)
408             {                   /* single argument */
409               if (!streq (proc->args.decls->decl.type, "void"))
410                 f_print (fout, "*argp, ");      /* non-void */
411             }
412           else
413             {
414               for (l = proc->args.decls; l != NULL; l = l->next)
415                 f_print (fout, "argp->%s, ", l->decl.name);
416             }
417           if (mtflag)
418             f_print (fout, "%s, ", RESULT);
419           f_print (fout, "%s));\n}\n", RQSTP);
420         }
421     }
422 }
423
424 static void
425 write_program (const definition * def, const char *storage)
426 {
427   version_list *vp;
428   proc_list *proc;
429   int filled;
430
431   for (vp = def->def.pr.versions; vp != NULL; vp = vp->next)
432     {
433       f_print (fout, "\n");
434       if (storage != NULL)
435         {
436           f_print (fout, "%s ", storage);
437         }
438       f_print (fout, "void\n");
439       pvname (def->def_name, vp->vers_num);
440
441       if (Cflag)
442         {
443           f_print (fout, "(struct svc_req *%s, ", RQSTP);
444           f_print (fout, "register SVCXPRT *%s)\n", TRANSP);
445         }
446       else
447         {
448           f_print (fout, "(%s, %s)\n", RQSTP, TRANSP);
449           f_print (fout, "      struct svc_req *%s;\n", RQSTP);
450           f_print (fout, "      register SVCXPRT *%s;\n", TRANSP);
451         }
452
453       f_print (fout, "{\n");
454
455       filled = 0;
456       f_print (fout, "\tunion {\n");
457       for (proc = vp->procs; proc != NULL; proc = proc->next)
458         {
459           if (proc->arg_num < 2)
460             {                   /* single argument */
461               if (streq (proc->args.decls->decl.type,
462                          "void"))
463                 {
464                   continue;
465                 }
466               filled = 1;
467               f_print (fout, "\t\t");
468               ptype (proc->args.decls->decl.prefix,
469                      proc->args.decls->decl.type, 0);
470               pvname (proc->proc_name, vp->vers_num);
471               f_print (fout, "_arg;\n");
472
473             }
474           else
475             {
476               filled = 1;
477               f_print (fout, "\t\t%s", proc->args.argname);
478               f_print (fout, " ");
479               pvname (proc->proc_name, vp->vers_num);
480               f_print (fout, "_arg;\n");
481             }
482         }
483       if (!filled)
484         {
485           f_print (fout, "\t\tint fill;\n");
486         }
487       f_print (fout, "\t} %s;\n", ARG);
488       if (mtflag)
489         {
490           f_print(fout, "\tunion {\n");
491           for (proc = vp->procs; proc != NULL; proc = proc->next)
492             if (!streq (proc->res_type, "void"))
493               {
494                 f_print(fout, "\t\t");
495                 ptype(proc->res_prefix, proc->res_type, 0);
496                 pvname(proc->proc_name, vp->vers_num);
497                 f_print(fout, "_res;\n");
498               }
499           f_print(fout, "\t} %s;\n", RESULT);
500           f_print(fout, "\tbool_t %s;\n", RETVAL);
501
502         } else
503           f_print (fout, "\tchar *%s;\n", RESULT);
504
505       if (Cflag)
506         {
507           f_print (fout, "\txdrproc_t _xdr_%s, _xdr_%s;\n", ARG, RESULT);
508           if (mtflag)
509             f_print(fout,
510                     "\tbool_t (*%s)(char *, void *, struct svc_req *);\n",
511                     ROUTINE);
512           else
513             f_print (fout, "\tchar *(*%s)(char *, struct svc_req *);\n",
514                      ROUTINE);
515         }
516       else
517         {
518           f_print (fout, "\tbool_t (*_xdr_%s)(), (*_xdr_%s)();\n", ARG, RESULT);
519           if (mtflag)
520             f_print(fout, "\tbool_t (*%s)();\n", ROUTINE);
521           else
522             f_print (fout, "\tchar *(*%s)();\n", ROUTINE);
523         }
524       f_print (fout, "\n");
525
526       if (timerflag)
527 #if 0
528         f_print (fout, "\t_rpcsvcdirty = 1;\n");
529 #else
530       {
531         if (mtflag)
532           f_print(fout, "\tmutex_lock(&_svcstate_lock);\n");
533         f_print(fout, "\t_rpcsvcstate = _SERVING;\n");
534         if (mtflag)
535           f_print(fout, "\tmutex_unlock(&_svcstate_lock);\n");
536       }
537 #endif
538
539       f_print (fout, "\tswitch (%s->rq_proc) {\n", RQSTP);
540       if (!nullproc (vp->procs))
541         {
542           f_print (fout, "\tcase NULLPROC:\n");
543           f_print (fout,
544                    "\t\t(void) svc_sendreply (%s, (xdrproc_t) xdr_void, (char *)NULL);\n",
545                    TRANSP);
546           print_return ("\t\t");
547           f_print (fout, "\n");
548         }
549       for (proc = vp->procs; proc != NULL; proc = proc->next)
550         {
551           f_print (fout, "\tcase %s:\n", proc->proc_name);
552           if (proc->arg_num < 2)
553             {                   /* single argument */
554               p_xdrfunc (ARG, proc->args.decls->decl.type);
555             }
556           else
557             {
558               p_xdrfunc (ARG, proc->args.argname);
559             }
560           p_xdrfunc (RESULT, proc->res_type);
561           if (Cflag)
562             {
563               if (mtflag)
564                 f_print(fout,
565                         "\t\t%s = (bool_t (*) (char *, void *,  struct svc_req *))",
566                         ROUTINE);
567               else
568                 f_print (fout,
569                          "\t\t%s = (char *(*)(char *, struct svc_req *)) ",
570                          ROUTINE);
571             }
572           else
573             if (mtflag)
574               f_print(fout, "\t\t%s = (bool_t (*)()) ", ROUTINE);
575             else
576               f_print (fout, "\t\t%s = (char *(*)()) ", ROUTINE);
577
578           if (newstyle)
579             {                   /* new style: calls internal routine */
580               f_print (fout, "_");
581             }
582           if ((Cflag || mtflag) && !newstyle)
583             pvname_svc (proc->proc_name, vp->vers_num);
584           else
585             pvname (proc->proc_name, vp->vers_num);
586           f_print (fout, ";\n");
587           f_print (fout, "\t\tbreak;\n\n");
588         }
589       f_print (fout, "\tdefault:\n");
590       printerr ("noproc", TRANSP);
591       print_return ("\t\t");
592       f_print (fout, "\t}\n");
593
594       f_print (fout, "\tmemset ((char *)&%s, 0, sizeof (%s));\n", ARG, ARG);
595       printif ("getargs", TRANSP, ARG);
596       printerr ("decode", TRANSP);
597       print_return ("\t\t");
598       f_print (fout, "\t}\n");
599
600       if (!mtflag)
601         {
602           if (Cflag)
603             f_print (fout, "\t%s = (*%s)((char *)&%s, %s);\n",
604                      RESULT, ROUTINE, ARG, RQSTP);
605           else
606             f_print (fout, "\t%s = (*%s)(&%s, %s);\n",
607                      RESULT, ROUTINE, ARG, RQSTP);
608         }
609       else
610         if (Cflag)
611           f_print(fout, "\t%s = (bool_t) (*%s)((char *)&%s, (void *)&%s, %s);\n",
612                   RETVAL, ROUTINE, ARG, RESULT, RQSTP);
613         else
614           f_print(fout, "\t%s = (bool_t) (*%s)(&%s, &%s, %s);\n",
615                   RETVAL, ROUTINE, ARG, RESULT, RQSTP);
616       if (mtflag)
617         f_print(fout,
618                 "\tif (%s > 0 && !svc_sendreply(%s, (xdrproc_t) _xdr_%s, (char *)&%s)) {\n",
619                 RETVAL, TRANSP, RESULT, RESULT);
620       else
621         f_print(fout,
622                 "\tif (%s != NULL && !svc_sendreply(%s, (xdrproc_t) _xdr_%s, %s)) {\n",
623                 RESULT, TRANSP, RESULT, RESULT);
624
625       printerr ("systemerr", TRANSP);
626       f_print (fout, "\t}\n");
627
628       printif ("freeargs", TRANSP, ARG);
629
630       sprintf (_errbuf, "unable to free arguments");
631       print_err_message ("\t\t");
632       f_print (fout, "\t\texit (1);\n");
633       f_print (fout, "\t}\n");
634       /* print out free routine */
635       if (mtflag)
636         {
637           f_print(fout,"\tif (!");
638           pvname(def->def_name, vp->vers_num);
639           f_print(fout,"_freeresult (%s, _xdr_%s, (caddr_t) &%s))\n",
640                   TRANSP, RESULT, RESULT);
641           (void) sprintf(_errbuf, "unable to free results");
642           print_err_message("\t\t");
643           f_print(fout, "\n");
644         }
645       print_return ("\t");
646       f_print (fout, "}\n");
647     }
648 }
649
650 static void
651 printerr (const char *err, const char *transp)
652 {
653   f_print (fout, "\t\tsvcerr_%s (%s);\n", err, transp);
654 }
655
656 static void
657 printif (const char *proc, const char *transp, const char *arg)
658 {
659   f_print (fout, "\tif (!svc_%s (%s, (xdrproc_t) _xdr_%s, (caddr_t) &%s)) {\n",
660            proc, transp, arg, arg);
661 }
662
663 int
664 nullproc (const proc_list * proc)
665 {
666   for (; proc != NULL; proc = proc->next)
667     {
668       if (streq (proc->proc_num, "0"))
669         {
670           return 1;
671         }
672     }
673   return 0;
674 }
675
676 static void
677 write_inetmost (const char *infile)
678 {
679   f_print (fout, "\tregister SVCXPRT *%s;\n", TRANSP);
680   f_print (fout, "\tint sock;\n");
681   f_print (fout, "\tint proto;\n");
682   f_print (fout, "\tstruct sockaddr_in saddr;\n");
683   f_print (fout, "\tint asize = sizeof (saddr);\n");
684   f_print (fout, "\n");
685   f_print (fout,
686        "\tif (getsockname (0, (struct sockaddr *)&saddr, &asize) == 0) {\n");
687   f_print (fout, "\t\tint ssize = sizeof (int);\n\n");
688   f_print (fout, "\t\tif (saddr.sin_family != AF_INET)\n");
689   f_print (fout, "\t\t\texit (1);\n");
690   f_print (fout, "\t\tif (getsockopt (0, SOL_SOCKET, SO_TYPE,\n");
691   f_print (fout, "\t\t\t\t(char *)&_rpcfdtype, &ssize) == -1)\n");
692   f_print (fout, "\t\t\texit (1);\n");
693   f_print (fout, "\t\tsock = 0;\n");
694   f_print (fout, "\t\t_rpcpmstart = 1;\n");
695   f_print (fout, "\t\tproto = 0;\n");
696   open_log_file (infile, "\t\t");
697   f_print (fout, "\t} else {\n");
698   write_rpc_svc_fg (infile, "\t\t");
699   f_print (fout, "\t\tsock = RPC_ANYSOCK;\n");
700   print_pmapunset ("\t\t");
701   f_print (fout, "\t}\n");
702 }
703
704 static void
705 print_return (const char *space)
706 {
707   if (exitnow)
708     f_print (fout, "%sexit (0);\n", space);
709   else
710     {
711       if (timerflag)
712         {
713 #if 0
714           f_print (fout, "%s_rpcsvcdirty = 0;\n", space);
715 #else
716           if (mtflag)
717             f_print(fout, "%smutex_lock(&_svcstate_lock);\n", space);
718           f_print(fout, "%s_rpcsvcstate = _SERVED;\n", space);
719           if (mtflag)
720             f_print(fout, "%smutex_unlock(&_svcstate_lock);\n", space);
721 #endif
722         }
723       f_print (fout, "%sreturn;\n", space);
724     }
725 }
726
727 static void
728 print_pmapunset (const char *space)
729 {
730   list *l;
731   definition *def;
732   version_list *vp;
733
734   for (l = defined; l != NULL; l = l->next)
735     {
736       def = (definition *) l->val;
737       if (def->def_kind == DEF_PROGRAM)
738         {
739           for (vp = def->def.pr.versions; vp != NULL;
740                vp = vp->next)
741             {
742               f_print (fout, "%spmap_unset (%s, %s);\n",
743                        space, def->def_name, vp->vers_name);
744             }
745         }
746     }
747 }
748
749 static void
750 print_err_message (const char *space)
751 {
752   if (logflag)
753     f_print (fout, "%ssyslog (LOG_ERR, \"%%s\", \"%s\");\n", space, _errbuf);
754   else if (inetdflag || pmflag)
755     f_print (fout, "%s_msgout (\"%s\");\n", space, _errbuf);
756   else
757     f_print (fout, "%sfprintf (stderr, \"%%s\", \"%s\");\n", space, _errbuf);
758 }
759
760 /*
761  * Write the server auxiliary function ( _msgout, timeout)
762  */
763 void
764 write_svc_aux (int nomain)
765 {
766   if (!logflag)
767     write_msg_out ();
768   if (!nomain)
769     write_timeout_func ();
770 }
771
772 /*
773  * Write the _msgout function
774  */
775
776 void
777 write_msg_out (void)
778 {
779   f_print (fout, "\n");
780   f_print (fout, "static\n");
781   if (!Cflag)
782     {
783       f_print (fout, "void _msgout (msg)\n");
784       f_print (fout, "\tchar *msg;\n");
785     }
786   else
787     {
788       f_print (fout, "void _msgout (char* msg)\n");
789     }
790   f_print (fout, "{\n");
791   f_print (fout, "#ifdef RPC_SVC_FG\n");
792   if (inetdflag || pmflag)
793     f_print (fout, "\tif (_rpcpmstart)\n");
794   f_print (fout, "\t\tsyslog (LOG_ERR, \"%%s\", msg);\n");
795   f_print (fout, "\telse\n");
796   f_print (fout, "\t\tfprintf (stderr, \"%%s\\n\", msg);\n");
797   f_print (fout, "#else\n");
798   f_print (fout, "\tsyslog (LOG_ERR, \"%%s\", msg);\n");
799   f_print (fout, "#endif\n");
800   f_print (fout, "}\n");
801 }
802
803 /*
804  * Write the timeout function
805  */
806 static void
807 write_timeout_func (void)
808 {
809   if (!timerflag)
810     return;
811   f_print (fout, "\n");
812   f_print (fout, "static void\n");
813   if (Cflag)
814     f_print (fout, "closedown (int sig)\n");
815   else
816     f_print (fout, "closedown (sig)\n\tint sig;\n");
817   f_print (fout, "{\n");
818
819 #if defined (__GNU_LIBRARY__) && 0
820   f_print (fout, "\t(void) signal (sig, %s closedown);\n",
821            Cflag ? "(SIG_PF)" : "(void(*)())");
822 #endif
823   if (mtflag)
824     f_print(fout, "\tmutex_lock(&_svcstate_lock);\n");
825 #if 0
826   f_print (fout, "\tif (_rpcsvcdirty == 0) {\n");
827 #else
828   f_print(fout, "\tif (_rpcsvcstate == _IDLE) {\n");
829 #endif
830   f_print (fout, "\t\textern fd_set svc_fdset;\n");
831   f_print (fout, "\t\tstatic int size;\n");
832   f_print (fout, "\t\tint i, openfd;\n");
833   if (tirpcflag && pmflag)
834     {
835       f_print (fout, "\t\tstruct t_info tinfo;\n\n");
836       f_print (fout, "\t\tif (!t_getinfo(0, &tinfo) && (tinfo.servtype == T_CLTS))\n");
837     }
838   else
839     {
840       f_print (fout, "\n\t\tif (_rpcfdtype == SOCK_DGRAM)\n");
841     }
842   f_print (fout, "\t\t\texit (0);\n");
843   f_print (fout, "\t\tif (size == 0) {\n");
844   if (tirpcflag)
845     {
846       f_print (fout, "\t\t\tstruct rlimit rl;\n\n");
847       f_print (fout, "\t\t\trl.rlim_max = 0;\n");
848       f_print (fout, "\t\t\tgetrlimit(RLIMIT_NOFILE, &rl);\n");
849       f_print (fout, "\t\t\tif ((size = rl.rlim_max) == 0) {\n");
850       if (mtflag)
851         f_print(fout, "\t\t\t\tmutex_unlock(&_svcstate_lock);\n");
852        f_print (fout, "\t\t\t\treturn;\n\t\t\t}\n");
853     }
854   else
855     {
856       f_print (fout, "\t\t\tsize = getdtablesize();\n");
857     }
858   f_print (fout, "\t\t}\n");
859   f_print (fout, "\t\tfor (i = 0, openfd = 0; i < size && openfd < 2; i++)\n");
860   f_print (fout, "\t\t\tif (FD_ISSET(i, &svc_fdset))\n");
861   f_print (fout, "\t\t\t\topenfd++;\n");
862   f_print (fout, "\t\tif (openfd <= 1)\n");
863   f_print (fout, "\t\t\texit (0);\n");
864   f_print (fout, "\t}\n");
865   f_print(fout, "\tif (_rpcsvcstate == _SERVED)\n");
866   f_print(fout, "\t\t_rpcsvcstate = _IDLE;\n\n");
867   if (mtflag)
868     f_print(fout, "\tmutex_unlock(&_svcstate_lock);\n");
869   f_print(fout, "\t(void) signal(SIGALRM, %s closedown);\n",
870           Cflag? "(SIG_PF)" : "(void(*)())");
871   f_print (fout, "\talarm (_RPCSVC_CLOSEDOWN);\n");
872   f_print (fout, "}\n");
873 }
874
875 /*
876  * Write the most of port monitor support
877  */
878 static void
879 write_pm_most (const char *infile, int netflag)
880 {
881   list *l;
882   definition *def;
883   version_list *vp;
884
885   f_print (fout, "\tif (!ioctl(0, I_LOOK, mname) &&\n");
886   f_print (fout, "\t\t(!strcmp(mname, \"sockmod\") ||");
887   f_print (fout, " !strcmp(mname, \"timod\"))) {\n");
888   f_print (fout, "\t\tchar *netid;\n");
889   if (!netflag)
890     {                           /* Not included by -n option */
891       f_print (fout, "\t\tstruct netconfig *nconf = NULL;\n");
892       f_print (fout, "\t\tSVCXPRT *%s;\n", TRANSP);
893     }
894   if (timerflag)
895     f_print (fout, "\t\tint pmclose;\n");
896 /* not necessary, defined in /usr/include/stdlib */
897 /*      f_print(fout, "\t\textern char *getenv();\n"); */
898   f_print (fout, "\n");
899   f_print (fout, "\t\t_rpcpmstart = 1;\n");
900   if (logflag)
901     open_log_file (infile, "\t\t");
902   f_print (fout, "\t\tif ((netid = getenv(\"NLSPROVIDER\")) == NULL) {\n");
903   sprintf (_errbuf, "cannot get transport name");
904   print_err_message ("\t\t\t");
905   f_print (fout, "\t\t} else if ((nconf = getnetconfigent(netid)) == NULL) {\n");
906   sprintf (_errbuf, "cannot get transport info");
907   print_err_message ("\t\t\t");
908   f_print (fout, "\t\t}\n");
909   /*
910    * A kludgy support for inetd services. Inetd only works with
911    * sockmod, and RPC works only with timod, hence all this jugglery
912    */
913   f_print (fout, "\t\tif (strcmp(mname, \"sockmod\") == 0) {\n");
914   f_print (fout, "\t\t\tif (ioctl(0, I_POP, 0) || ioctl(0, I_PUSH, \"timod\")) {\n");
915   sprintf (_errbuf, "could not get the right module");
916   print_err_message ("\t\t\t\t");
917   f_print (fout, "\t\t\t\texit(1);\n");
918   f_print (fout, "\t\t\t}\n");
919   f_print (fout, "\t\t}\n");
920   if (timerflag)
921     f_print (fout, "\t\tpmclose = (t_getstate(0) != T_DATAXFER);\n");
922   f_print (fout, "\t\tif ((%s = svc_tli_create(0, nconf, NULL, 0, 0)) == NULL) {\n",
923            TRANSP);
924   sprintf (_errbuf, "cannot create server handle");
925   print_err_message ("\t\t\t");
926   f_print (fout, "\t\t\texit(1);\n");
927   f_print (fout, "\t\t}\n");
928   f_print (fout, "\t\tif (nconf)\n");
929   f_print (fout, "\t\t\tfreenetconfigent(nconf);\n");
930   for (l = defined; l != NULL; l = l->next)
931     {
932       def = (definition *) l->val;
933       if (def->def_kind != DEF_PROGRAM)
934         {
935           continue;
936         }
937       for (vp = def->def.pr.versions; vp != NULL; vp = vp->next)
938         {
939           f_print (fout,
940                    "\t\tif (!svc_reg(%s, %s, %s, ",
941                    TRANSP, def->def_name, vp->vers_name);
942           pvname (def->def_name, vp->vers_num);
943           f_print (fout, ", 0)) {\n");
944           (void) sprintf (_errbuf, "unable to register (%s, %s).",
945                           def->def_name, vp->vers_name);
946           print_err_message ("\t\t\t");
947           f_print (fout, "\t\t\texit(1);\n");
948           f_print (fout, "\t\t}\n");
949         }
950     }
951   if (timerflag)
952     {
953       f_print (fout, "\t\tif (pmclose) {\n");
954       f_print (fout, "\t\t\t(void) signal(SIGALRM, %s closedown);\n",
955                Cflag ? "(SIG_PF)" : "(void(*)())");
956       f_print (fout, "\t\t\t(void) alarm(_RPCSVC_CLOSEDOWN);\n");
957       f_print (fout, "\t\t}\n");
958     }
959   f_print (fout, "\t\tsvc_run();\n");
960   f_print (fout, "\t\texit(1);\n");
961   f_print (fout, "\t\t/* NOTREACHED */\n");
962   f_print (fout, "\t}\n");
963 }
964
965 /*
966  * Support for backgrounding the server if self started.
967  */
968 static void
969 write_rpc_svc_fg (const char *infile, const char *sp)
970 {
971   f_print (fout, "#ifndef RPC_SVC_FG\n");
972   f_print (fout, "%sint size;\n", sp);
973   if (tirpcflag)
974     f_print (fout, "%sstruct rlimit rl;\n", sp);
975   if (inetdflag)
976     f_print (fout, "%sint pid, i;\n\n", sp);
977   f_print (fout, "%spid = fork();\n", sp);
978   f_print (fout, "%sif (pid < 0) {\n", sp);
979   f_print (fout, "%s\tperror(\"cannot fork\");\n", sp);
980   f_print (fout, "%s\texit(1);\n", sp);
981   f_print (fout, "%s}\n", sp);
982   f_print (fout, "%sif (pid)\n", sp);
983   f_print (fout, "%s\texit(0);\n", sp);
984   /* get number of file descriptors */
985   if (tirpcflag)
986     {
987       f_print (fout, "%srl.rlim_max = 0;\n", sp);
988       f_print (fout, "%sgetrlimit(RLIMIT_NOFILE, &rl);\n", sp);
989       f_print (fout, "%sif ((size = rl.rlim_max) == 0)\n", sp);
990       f_print (fout, "%s\texit(1);\n", sp);
991     }
992   else
993     {
994       f_print (fout, "%ssize = getdtablesize();\n", sp);
995     }
996
997   f_print (fout, "%sfor (i = 0; i < size; i++)\n", sp);
998   f_print (fout, "%s\t(void) close(i);\n", sp);
999   /* Redirect stderr and stdout to console */
1000   f_print (fout, "%si = open(\"/dev/console\", 2);\n", sp);
1001   f_print (fout, "%s(void) dup2(i, 1);\n", sp);
1002   f_print (fout, "%s(void) dup2(i, 2);\n", sp);
1003   /* This removes control of the controlling terminal */
1004   if (tirpcflag)
1005     f_print (fout, "%ssetsid();\n", sp);
1006   else
1007     {
1008       f_print (fout, "%si = open(\"/dev/tty\", 2);\n", sp);
1009       f_print (fout, "%sif (i >= 0) {\n", sp);
1010       f_print (fout, "%s\t(void) ioctl(i, TIOCNOTTY, (char *)NULL);\n", sp);;
1011       f_print (fout, "%s\t(void) close(i);\n", sp);
1012       f_print (fout, "%s}\n", sp);
1013     }
1014   if (!logflag)
1015     open_log_file (infile, sp);
1016   f_print (fout, "#endif\n");
1017   if (logflag)
1018     open_log_file (infile, sp);
1019 }
1020
1021 static void
1022 open_log_file (const char *infile, const char *sp)
1023 {
1024   char *s;
1025
1026   s = strrchr (infile, '.');
1027   if (s)
1028     *s = '\0';
1029   f_print (fout, "%sopenlog(\"%s\", LOG_PID, LOG_DAEMON);\n", sp, infile);
1030   if (s)
1031     *s = '.';
1032 }
1033
1034 /*
1035  * write a registration for the given transport for Inetd
1036  */
1037 void
1038 write_inetd_register (const char *transp)
1039 {
1040   list *l;
1041   definition *def;
1042   version_list *vp;
1043   const char *sp;
1044   int isudp;
1045   char tmpbuf[32];
1046
1047   if (inetdflag)
1048     sp = "\t";
1049   else
1050     sp = "";
1051   if (streq (transp, "udp") || streq (transp, "udp6"))
1052     isudp = 1;
1053   else
1054     isudp = 0;
1055   f_print (fout, "\n");
1056   if (inetdflag)
1057     {
1058       f_print (fout, "\tif ((_rpcfdtype == 0) || (_rpcfdtype == %s)) {\n",
1059                isudp ? "SOCK_DGRAM" : "SOCK_STREAM");
1060     }
1061   f_print (fout, "%s\t%s = svc%s_create(%s",
1062            sp, TRANSP, transp, inetdflag ? "sock" : "RPC_ANYSOCK");
1063   if (!isudp)
1064     f_print (fout, ", 0, 0");
1065   f_print (fout, ");\n");
1066   f_print (fout, "%s\tif (%s == NULL) {\n", sp, TRANSP);
1067   (void) sprintf (_errbuf, "cannot create %s service.", transp);
1068   (void) sprintf (tmpbuf, "%s\t\t", sp);
1069   print_err_message (tmpbuf);
1070   f_print (fout, "%s\t\texit(1);\n", sp);
1071   f_print (fout, "%s\t}\n", sp);
1072
1073   if (inetdflag)
1074     {
1075       f_print (fout, "%s\tif (!_rpcpmstart)\n\t", sp);
1076       f_print (fout, "%s\tproto = IPPROTO_%s;\n",
1077                sp, isudp ? "UDP" : "TCP");
1078     }
1079   for (l = defined; l != NULL; l = l->next)
1080     {
1081       def = (definition *) l->val;
1082       if (def->def_kind != DEF_PROGRAM)
1083         {
1084           continue;
1085         }
1086       for (vp = def->def.pr.versions; vp != NULL; vp = vp->next)
1087         {
1088           f_print (fout, "%s\tif (!svc_register(%s, %s, %s, ",
1089                    sp, TRANSP, def->def_name, vp->vers_name);
1090           pvname (def->def_name, vp->vers_num);
1091           if (inetdflag)
1092             f_print (fout, ", proto)) {\n");
1093           else
1094             f_print (fout, ", IPPROTO_%s)) {\n",
1095                      isudp ? "UDP" : "TCP");
1096           (void) sprintf (_errbuf, "unable to register (%s, %s, %s).",
1097                           def->def_name, vp->vers_name, transp);
1098           print_err_message (tmpbuf);
1099           f_print (fout, "%s\t\texit(1);\n", sp);
1100           f_print (fout, "%s\t}\n", sp);
1101         }
1102     }
1103   if (inetdflag)
1104     f_print (fout, "\t}\n");
1105 }