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