rpc_svcout.c revision 152398
11897Swollman/*
21897Swollman * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
31897Swollman * unrestricted use provided that this legend is included on all tape
41897Swollman * media and as a part of the software program in whole or part.  Users
51897Swollman * may copy or modify Sun RPC without charge, but are not authorized
61897Swollman * to license or distribute it to anyone else except as part of a product or
71897Swollman * program developed by the user.
8100441Scharnier *
91897Swollman * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
101897Swollman * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
111897Swollman * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
12100441Scharnier *
131897Swollman * Sun RPC is provided with no support and without any obligation on the
141897Swollman * part of Sun Microsystems, Inc. to assist in its use, correction,
151897Swollman * modification or enhancement.
16100441Scharnier *
171897Swollman * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
181897Swollman * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
191897Swollman * OR ANY PART THEREOF.
20100441Scharnier *
211897Swollman * In no event will Sun Microsystems, Inc. be liable for any lost revenue
221897Swollman * or profits or other special, indirect and consequential damages, even if
231897Swollman * Sun has been advised of the possibility of such damages.
24100441Scharnier *
251897Swollman * Sun Microsystems, Inc.
261897Swollman * 2550 Garcia Avenue
271897Swollman * Mountain View, California  94043
281897Swollman */
2912798Swpaul
30100441Scharnier#if 0
311897Swollman#ifndef lint
32146833Sstefanf#ident	"@(#)rpc_svcout.c	1.4	90/04/13 SMI"
3312798Swpaulstatic char sccsid[] = "@(#)rpc_svcout.c 1.29 89/03/30 (C) 1987 SMI";
341897Swollman#endif
3579880Skris#endif
361897Swollman
37100441Scharnier#include <sys/cdefs.h>
38100441Scharnier__FBSDID("$FreeBSD: head/usr.bin/rpcgen/rpc_svcout.c 152398 2005-11-13 21:17:24Z dwmalone $");
39100441Scharnier
401897Swollman/*
411897Swollman * rpc_svcout.c, Server-skeleton outputter for the RPC protocol compiler
4212798Swpaul * Copyright (C) 1987, Sun Microsystems, Inc.
431897Swollman */
441897Swollman#include <stdio.h>
4512798Swpaul#include <string.h>
461897Swollman#include "rpc_parse.h"
47149682Sstefanf#include "rpc_scan.h"
481897Swollman#include "rpc_util.h"
491897Swollman
501897Swollmanstatic char RQSTP[] = "rqstp";
511897Swollmanstatic char TRANSP[] = "transp";
521897Swollmanstatic char ARG[] = "argument";
531897Swollmanstatic char RESULT[] = "result";
541897Swollmanstatic char ROUTINE[] = "local";
5512798Swpaulstatic char RETVAL[] = "retval";
561897Swollman
5712798Swpaulchar _errbuf[256];	/* For all messages */
5812798Swpaul
5992921Simpvoid internal_proctype( proc_list * );
6092921Simpstatic void write_real_program( definition * );
61152398Sdwmalonestatic void write_program(definition *, const char *);
62152398Sdwmalonestatic void printerr(const char *, const char *);
63152398Sdwmalonestatic void printif(const char *, const char *, const char *, const char *);
64152398Sdwmalonestatic void write_inetmost(const char *);
65152398Sdwmalonestatic void print_return(const char *);
66152398Sdwmalonestatic void print_pmapunset(const char *);
67152398Sdwmalonestatic void print_err_message(const char *);
6892921Simpstatic void write_timeout_func( void );
69152398Sdwmalonestatic void write_pm_most(const char *, int);
70152398Sdwmalonestatic void write_rpc_svc_fg(const char *, const char *);
71152398Sdwmalonestatic void open_log_file(const char *, const char *);
7292921Simpstatic void write_msg_out( void );
7312798Swpaul
7412798Swpaul
7517142Sjkhstatic void
76152398Sdwmalonep_xdrfunc(const char *rname, const char *typename)
7712798Swpaul{
78149709Sstefanf	f_print(fout, "\t\txdr_%s = (xdrproc_t) xdr_%s;\n",
79149709Sstefanf	    rname, stringfix(typename));
8012798Swpaul}
8112798Swpaul
8212798Swpaulvoid
83152398Sdwmaloneinternal_proctype(proc_list *plist)
8412798Swpaul{
8512798Swpaul	f_print(fout, "static ");
8612798Swpaul	ptype(plist->res_prefix, plist->res_type, 1);
8712798Swpaul	f_print(fout, "*");
8812798Swpaul}
8912798Swpaul
9012798Swpaul
911897Swollman/*
928874Srgrimes * write most of the service, that is, everything but the registrations.
931897Swollman */
941897Swollmanvoid
95152398Sdwmalonewrite_most(const char *infile, int netflag, int nomain)
961897Swollman{
9712798Swpaul	if (inetdflag || pmflag) {
98152398Sdwmalone		const char *var_type;
9912798Swpaul		var_type = (nomain? "extern" : "static");
10012798Swpaul		f_print(fout, "%s int _rpcpmstart;", var_type);
10112798Swpaul		f_print(fout, "\t\t/* Started by a port monitor ? */\n");
10299979Salfred		if (!tirpcflag || tirpc_socket) {
10312798Swpaul			f_print(fout, "%s int _rpcfdtype;", var_type);
10412798Swpaul			f_print(fout, "\n\t\t /* Whether Stream or \
10512798SwpaulDatagram ? */\n");
10612798Swpaul		}
1071897Swollman
10812798Swpaul		if (timerflag) {
10912798Swpaul			f_print(fout, "	/* States a server can be in \
11012798Swpaulwrt request */\n\n");
11112798Swpaul			f_print(fout, "#define\t_IDLE 0\n");
11212798Swpaul			f_print(fout, "#define\t_SERVED 1\n");
11312798Swpaul			f_print(fout, "#define\t_SERVING 2\n\n");
11412798Swpaul			f_print(fout, "static int _rpcsvcstate = _IDLE;");
11512798Swpaul			f_print(fout, "\t /* Set when a request is \
11612798Swpaulserviced */\n");
11712798Swpaul
11812798Swpaul			if (mtflag) {
11912798Swpaul				f_print(fout, "mutex_t _svcstate_lock;");
12012798Swpaul				f_print(fout, "\t\t\t/* Mutex lock for variable _rpcsvcstate */\n");
12112798Swpaul
1221897Swollman			}
12312798Swpaul
1241897Swollman		}
12512798Swpaul
12612798Swpaul		write_svc_aux(nomain);
1271897Swollman	}
12812798Swpaul	/* write out dispatcher and stubs */
12912798Swpaul	write_programs(nomain? (char *)NULL : "static");
13012798Swpaul
13112798Swpaul	if (nomain)
13212798Swpaul		return;
13312798Swpaul
13499979Salfred	f_print(fout, "\nint\n");
13599979Salfred	f_print(fout, "main()\n");
1361897Swollman	f_print(fout, "{\n");
137109363Smbr		if (tirpcflag) {
138109363Smbr			if (!inetdflag)
139109363Smbr				f_print(fout, "\t");
140109363Smbr			f_print(fout, "\tint maxrec = RPC_MAXDATASIZE;\n");
141109363Smbr		}
14212798Swpaul	if (inetdflag) {
14312798Swpaul		write_inetmost(infile);
14412798Swpaul		/* Includes call to write_rpc_svc_fg() */
14512798Swpaul	} else {
14612798Swpaul		if (tirpcflag) {
14712798Swpaul			if (netflag) {
14812798Swpaul				f_print(fout,
14912798Swpaul					"\tregister SVCXPRT *%s;\n", TRANSP);
15012798Swpaul				f_print(fout,
15112798Swpaul					"\tstruct netconfig *nconf = NULL;\n");
15212798Swpaul			}
15312798Swpaul			f_print(fout, "\tpid_t pid;\n");
15412798Swpaul			f_print(fout, "\tint i;\n");
15599979Salfred			if (pmflag) {
15699979Salfred				if (tirpc_socket) {
15799979Salfred					f_print(fout, "\tstruct sockaddr_storage saddr;\n");
158149733Sstefanf					f_print(fout, "\tsocklen_t asize = sizeof (saddr);\n\n");
15999979Salfred				} else
16099979Salfred					f_print(fout, "\tchar mname[FMNAMESZ + 1];\n\n");
16199979Salfred			}
16212798Swpaul
16312798Swpaul			if (mtflag & timerflag)
16412798Swpaul				f_print(fout, "\tmutex_init(&_svcstate_lock, USYNC_THREAD, NULL);\n");
16599979Salfred			if (pmflag) {
16699979Salfred				write_pm_most(infile, netflag);
16799979Salfred				f_print(fout, "\telse {\n");
16899979Salfred				write_rpc_svc_fg(infile, "\t\t");
16999979Salfred				f_print(fout, "\t}\n");
170100441Scharnier			} else
17199979Salfred				write_rpc_svc_fg(infile, "\t\t");
17212798Swpaul
17312798Swpaul		} else {
17412798Swpaul			f_print(fout, "\tregister SVCXPRT *%s;\n", TRANSP);
17512798Swpaul			f_print(fout, "\n");
17612798Swpaul			print_pmapunset("\t");
17712798Swpaul		}
17812798Swpaul	}
17912798Swpaul
18012798Swpaul	if (logflag && !inetdflag) {
18112798Swpaul		open_log_file(infile, "\t");
18212798Swpaul	}
18312798Swpaul}
18412798Swpaul
18512798Swpaul/*
18612798Swpaul * write a registration for the given transport
18712798Swpaul */
18812798Swpaulvoid
189152398Sdwmalonewrite_netid_register(const char *transp)
19012798Swpaul{
19112798Swpaul	list *l;
19212798Swpaul	definition *def;
19312798Swpaul	version_list *vp;
194152398Sdwmalone	const char *sp;
19512798Swpaul	char tmpbuf[32];
19612798Swpaul
19712798Swpaul	sp = "";
1981897Swollman	f_print(fout, "\n");
19912798Swpaul	f_print(fout, "%s\tnconf = getnetconfigent(\"%s\");\n", sp, transp);
20012798Swpaul	f_print(fout, "%s\tif (nconf == NULL) {\n", sp);
20112798Swpaul	(void) sprintf(_errbuf, "cannot find %s netid.", transp);
20212798Swpaul	sprintf(tmpbuf, "%s\t\t", sp);
20312798Swpaul	print_err_message(tmpbuf);
20412798Swpaul	f_print(fout, "%s\t\texit(1);\n", sp);
20512798Swpaul	f_print(fout, "%s\t}\n", sp);
206109363Smbr	if (tirpcflag) {
207109363Smbr		f_print(fout, "%s\t%s = svc_tli_create(RPC_ANYFD, ",
208109363Smbr		    sp, TRANSP);
209109363Smbr		f_print(fout,"nconf, 0, RPC_MAXDATASIZE, RPC_MAXDATASIZE);\n");
210109363Smbr	} else {
211109363Smbr		f_print(fout,
212109363Smbr		    "%s\t%s = svc_tli_create(RPC_ANYFD, nconf, 0, 0, 0);\n",
213109363Smbr		    sp, TRANSP);
214109363Smbr	}
21512798Swpaul	f_print(fout, "%s\tif (%s == NULL) {\n", sp, TRANSP);
21612798Swpaul	(void) sprintf(_errbuf, "cannot create %s service.", transp);
21712798Swpaul	print_err_message(tmpbuf);
21812798Swpaul	f_print(fout, "%s\t\texit(1);\n", sp);
21912798Swpaul	f_print(fout, "%s\t}\n", sp);
22012798Swpaul
2211897Swollman	for (l = defined; l != NULL; l = l->next) {
2221897Swollman		def = (definition *) l->val;
2231897Swollman		if (def->def_kind != DEF_PROGRAM) {
2241897Swollman			continue;
2251897Swollman		}
2261897Swollman		for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
22712798Swpaul			f_print(fout,
22812798Swpaul				"%s\t(void) rpcb_unset(%s, %s, nconf);\n",
22912798Swpaul				sp, def->def_name, vp->vers_name);
23012798Swpaul			f_print(fout,
23112798Swpaul				"%s\tif (!svc_reg(%s, %s, %s, ",
23212798Swpaul				sp, TRANSP, def->def_name, vp->vers_name);
23312798Swpaul			pvname(def->def_name, vp->vers_num);
23412798Swpaul			f_print(fout, ", nconf)) {\n");
23512798Swpaul			(void) sprintf(_errbuf,
23612798Swpaul				"unable to register (%s, %s, %s).",
23712798Swpaul				def->def_name, vp->vers_name, transp);
23812798Swpaul			print_err_message(tmpbuf);
23912798Swpaul			f_print(fout, "%s\t\texit(1);\n", sp);
24012798Swpaul			f_print(fout, "%s\t}\n", sp);
2411897Swollman		}
2421897Swollman	}
24312798Swpaul	f_print(fout, "%s\tfreenetconfigent(nconf);\n", sp);
2441897Swollman}
2451897Swollman
2461897Swollman/*
24712798Swpaul * write a registration for the given transport for TLI
2481897Swollman */
2491897Swollmanvoid
250152398Sdwmalonewrite_nettype_register(const char *transp)
2511897Swollman{
2521897Swollman	list *l;
2531897Swollman	definition *def;
2541897Swollman	version_list *vp;
2551897Swollman
2561897Swollman	for (l = defined; l != NULL; l = l->next) {
2571897Swollman		def = (definition *) l->val;
2581897Swollman		if (def->def_kind != DEF_PROGRAM) {
2591897Swollman			continue;
2601897Swollman		}
261109363Smbr		if (tirpcflag) {
262109363Smbr			f_print(fout,
263109363Smbr			"\trpc_control(RPC_SVC_CONNMAXREC_SET, &maxrec);\n");
264109363Smbr		}
2651897Swollman		for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
26612798Swpaul			f_print(fout, "\tif (!svc_create(");
2671897Swollman			pvname(def->def_name, vp->vers_num);
26812798Swpaul			f_print(fout, ", %s, %s, \"%s\")) {\n",
2691897Swollman				def->def_name, vp->vers_name, transp);
27012798Swpaul			(void) sprintf(_errbuf,
27112798Swpaul				"unable to create (%s, %s) for %s.",
27212798Swpaul					def->def_name, vp->vers_name, transp);
27312798Swpaul			print_err_message("\t\t");
2741897Swollman			f_print(fout, "\t\texit(1);\n");
2751897Swollman			f_print(fout, "\t}\n");
2761897Swollman		}
2771897Swollman	}
2781897Swollman}
2791897Swollman
2801897Swollman/*
2818874Srgrimes * write the rest of the service
2821897Swollman */
2831897Swollmanvoid
284152398Sdwmalonewrite_rest(void)
2851897Swollman{
28612798Swpaul	f_print(fout, "\n");
28712798Swpaul	if (inetdflag) {
28812798Swpaul		f_print(fout, "\tif (%s == (SVCXPRT *)NULL) {\n", TRANSP);
28912798Swpaul		(void) sprintf(_errbuf, "could not create a handle");
29012798Swpaul		print_err_message("\t\t");
29112798Swpaul		f_print(fout, "\t\texit(1);\n");
29212798Swpaul		f_print(fout, "\t}\n");
29312798Swpaul		if (timerflag) {
29412798Swpaul			f_print(fout, "\tif (_rpcpmstart) {\n");
29512798Swpaul			f_print(fout,
296149709Sstefanf				"\t\t(void) signal(SIGALRM, closedown);\n");
29712798Swpaul			f_print(fout, "\t\t(void) \
29812798Swpaulalarm(_RPCSVC_CLOSEDOWN/2);\n");
29912798Swpaul			f_print(fout, "\t}\n");
30012798Swpaul		}
30112798Swpaul	}
3021897Swollman	f_print(fout, "\tsvc_run();\n");
30312798Swpaul	(void) sprintf(_errbuf, "svc_run returned");
30412798Swpaul	print_err_message("\t");
3051897Swollman	f_print(fout, "\texit(1);\n");
30612798Swpaul	f_print(fout, "\t/* NOTREACHED */\n");
3071897Swollman	f_print(fout, "}\n");
3081897Swollman}
3091897Swollman
3101897Swollmanvoid
311152398Sdwmalonewrite_programs(const char *storage)
3121897Swollman{
3131897Swollman	list *l;
3141897Swollman	definition *def;
3151897Swollman
31612798Swpaul	/* write out stubs for procedure  definitions */
3171897Swollman	for (l = defined; l != NULL; l = l->next) {
3181897Swollman		def = (definition *) l->val;
3191897Swollman		if (def->def_kind == DEF_PROGRAM) {
32012798Swpaul			write_real_program(def);
32112798Swpaul		}
32212798Swpaul	}
32312798Swpaul
32412798Swpaul	/* write out dispatcher for each program */
32512798Swpaul	for (l = defined; l != NULL; l = l->next) {
32612798Swpaul		def = (definition *) l->val;
32712798Swpaul		if (def->def_kind == DEF_PROGRAM) {
3281897Swollman			write_program(def, storage);
3291897Swollman		}
3301897Swollman	}
33112798Swpaul
33212798Swpaul
3331897Swollman}
3341897Swollman
33512798Swpaul/*
33612798Swpaul * write out definition of internal function (e.g. _printmsg_1(...))
33712798Swpaul *  which calls server's defintion of actual function (e.g. printmsg_1(...)).
33812798Swpaul *  Unpacks single user argument of printmsg_1 to call-by-value format
33912798Swpaul *  expected by printmsg_1.
34012798Swpaul */
34117142Sjkhstatic void
342152398Sdwmalonewrite_real_program(definition *def)
34312798Swpaul{
34412798Swpaul	version_list *vp;
34512798Swpaul	proc_list *proc;
34612798Swpaul	decl_list *l;
3471897Swollman
34812798Swpaul	if (!newstyle) return;  /* not needed for old style */
34912798Swpaul	for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
35012798Swpaul		for (proc = vp->procs; proc != NULL; proc = proc->next) {
35112798Swpaul			f_print(fout, "\n");
35212798Swpaul			if (!mtflag)
35312798Swpaul				internal_proctype(proc);
35412798Swpaul			else
35512798Swpaul				f_print(fout, "int");
35612798Swpaul			f_print(fout, "\n_");
35712798Swpaul			pvname(proc->proc_name, vp->vers_num);
358149709Sstefanf			f_print(fout, "(");
359149709Sstefanf			/* arg name */
360149709Sstefanf			if (proc->arg_num > 1)
361149709Sstefanf				f_print(fout, proc->args.argname);
362149709Sstefanf			else
363149709Sstefanf				ptype(proc->args.decls->decl.prefix,
364149709Sstefanf				      proc->args.decls->decl.type, 0);
365149709Sstefanf			if (mtflag) {
366149709Sstefanf				f_print(fout, " *argp, void *%s, struct svc_req *%s)\n",
367149709Sstefanf					RESULT, RQSTP);
36812798Swpaul
36912798Swpaul
37012798Swpaul			}
371149709Sstefanf			else
372149709Sstefanf				f_print(fout, " *argp, struct svc_req *%s)\n",
373149709Sstefanf					RQSTP);
37412798Swpaul
37512798Swpaul			f_print(fout, "{\n");
37612798Swpaul			f_print(fout, "\treturn (");
377149709Sstefanf			pvname_svc(proc->proc_name, vp->vers_num);
37812798Swpaul			f_print(fout, "(");
37912798Swpaul			if (proc->arg_num < 2) { /* single argument */
38012798Swpaul				if (!streq(proc->args.decls->decl.type, "void"))
38112798Swpaul					f_print(fout, "*argp, "); /* non-void */
38212798Swpaul			} else {
38312798Swpaul				for (l = proc->args.decls;  l != NULL;
38412798Swpaul				     l = l->next)
38512798Swpaul					f_print(fout, "argp->%s, ",
38612798Swpaul						l->decl.name);
38712798Swpaul			}
38812798Swpaul			if (mtflag)
38912798Swpaul				f_print(fout, "%s, ",RESULT);
39012798Swpaul			f_print(fout, "%s));\n}\n", RQSTP);
39112798Swpaul		}
39212798Swpaul	}
39312798Swpaul}
39412798Swpaul
39517142Sjkhstatic void
396152398Sdwmalonewrite_program(definition *def, const char *storage)
3971897Swollman{
3981897Swollman	version_list *vp;
3991897Swollman	proc_list *proc;
4001897Swollman	int filled;
4011897Swollman
4021897Swollman	for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
4031897Swollman		f_print(fout, "\n");
4041897Swollman		if (storage != NULL) {
4051897Swollman			f_print(fout, "%s ", storage);
4061897Swollman		}
4071897Swollman		f_print(fout, "void\n");
4081897Swollman		pvname(def->def_name, vp->vers_num);
40912798Swpaul
410149709Sstefanf		f_print(fout, "(struct svc_req *%s, ", RQSTP);
411149710Sstefanf		f_print(fout, "SVCXPRT *%s)\n", TRANSP);
4121897Swollman		f_print(fout, "{\n");
4131897Swollman
4141897Swollman		filled = 0;
4151897Swollman		f_print(fout, "\tunion {\n");
4161897Swollman		for (proc = vp->procs; proc != NULL; proc = proc->next) {
41712798Swpaul			if (proc->arg_num < 2) { /* single argument */
41812798Swpaul				if (streq(proc->args.decls->decl.type,
41912798Swpaul					  "void")) {
42012798Swpaul					continue;
42112798Swpaul				}
42212798Swpaul				filled = 1;
42312798Swpaul				f_print(fout, "\t\t");
42412798Swpaul				ptype(proc->args.decls->decl.prefix,
42512798Swpaul				      proc->args.decls->decl.type, 0);
42612798Swpaul				pvname(proc->proc_name, vp->vers_num);
42712798Swpaul				f_print(fout, "_arg;\n");
42812798Swpaul
42912798Swpaul			} else {
43012798Swpaul				filled = 1;
43112798Swpaul				f_print(fout, "\t\t%s", proc->args.argname);
43212798Swpaul				f_print(fout, " ");
43312798Swpaul				pvname(proc->proc_name, vp->vers_num);
43412798Swpaul				f_print(fout, "_arg;\n");
4351897Swollman			}
4361897Swollman		}
4371897Swollman		if (!filled) {
4381897Swollman			f_print(fout, "\t\tint fill;\n");
4391897Swollman		}
4401897Swollman		f_print(fout, "\t} %s;\n", ARG);
44112798Swpaul
44212798Swpaul		if (mtflag) {
44312798Swpaul			f_print(fout, "\tunion {\n");
44412798Swpaul			for (proc = vp->procs; proc != NULL; proc = proc->next) {
44512798Swpaul				f_print(fout, "\t\t");
44612798Swpaul				ptype(proc->res_prefix, proc->res_type, 0);
44712798Swpaul				pvname(proc->proc_name, vp->vers_num);
44812798Swpaul				f_print(fout, "_res;\n");
44912798Swpaul			}
45012798Swpaul			f_print(fout, "\t} %s;\n", RESULT);
45112798Swpaul			f_print(fout, "\tbool_t %s;\n", RETVAL);
45212798Swpaul
453100441Scharnier		} else
45412798Swpaul			f_print(fout, "\tchar *%s;\n", RESULT);
45512798Swpaul
456149709Sstefanf		f_print(fout, "\txdrproc_t xdr_%s, xdr_%s;\n", ARG, RESULT);
457149709Sstefanf		if (mtflag)
45812798Swpaul			f_print(fout,
459149709Sstefanf				"\tbool_t (*%s)(char *, void *, struct svc_req *);\n",
460149709Sstefanf				ROUTINE);
461149709Sstefanf		else
462149709Sstefanf			f_print(fout,
463149709Sstefanf				"\tchar *(*%s)(char *, struct svc_req *);\n",
464149709Sstefanf				ROUTINE);
4651897Swollman		f_print(fout, "\n");
46612798Swpaul
46712798Swpaul		if (timerflag) {
46812798Swpaul			if (mtflag)
46912798Swpaul				f_print(fout, "\tmutex_lock(&_svcstate_lock);\n");
47012798Swpaul
47112798Swpaul			f_print(fout, "\t_rpcsvcstate = _SERVING;\n");
47212798Swpaul			if (mtflag)
47312798Swpaul				f_print(fout, "\tmutex_unlock(&_svcstate_lock);\n");
47412798Swpaul		}
47512798Swpaul
4761897Swollman		f_print(fout, "\tswitch (%s->rq_proc) {\n", RQSTP);
4771897Swollman		if (!nullproc(vp->procs)) {
4781897Swollman			f_print(fout, "\tcase NULLPROC:\n");
47912798Swpaul			f_print(fout,
480149709Sstefanf				"\t\t(void) svc_sendreply(%s,\n\t\t\t"
481149709Sstefanf				"(xdrproc_t) xdr_void, (char *)NULL);\n",
48212798Swpaul				TRANSP);
48312798Swpaul			print_return("\t\t");
48412798Swpaul			f_print(fout, "\n");
4851897Swollman		}
4861897Swollman		for (proc = vp->procs; proc != NULL; proc = proc->next) {
4871897Swollman			f_print(fout, "\tcase %s:\n", proc->proc_name);
48812798Swpaul			if (proc->arg_num < 2) { /* single argument */
48912798Swpaul				p_xdrfunc(ARG, proc->args.decls->decl.type);
49012798Swpaul			} else {
49112798Swpaul				p_xdrfunc(ARG, proc->args.argname);
49212798Swpaul			}
49312798Swpaul			p_xdrfunc(RESULT, proc->res_type);
49412798Swpaul
495149709Sstefanf			if (mtflag)
496149709Sstefanf				f_print(fout,
497149709Sstefanf					"\t\t%s = (bool_t (*) (char *,  void *,  struct svc_req *))",
498149709Sstefanf					ROUTINE);
49912798Swpaul			else
500149709Sstefanf				f_print(fout,
501149709Sstefanf					"\t\t%s = (char *(*)(char *, struct svc_req *)) ",
502149709Sstefanf					ROUTINE);
50312798Swpaul			if (newstyle) { /* new style: calls internal routine */
50412798Swpaul				f_print(fout, "_");
50512798Swpaul			}
506149709Sstefanf			if (!newstyle)
50712798Swpaul				pvname_svc(proc->proc_name, vp->vers_num);
50812798Swpaul			else
50912798Swpaul				pvname(proc->proc_name, vp->vers_num);
5101897Swollman			f_print(fout, ";\n");
5111897Swollman			f_print(fout, "\t\tbreak;\n\n");
5121897Swollman		}
5131897Swollman		f_print(fout, "\tdefault:\n");
5141897Swollman		printerr("noproc", TRANSP);
51512798Swpaul		print_return("\t\t");
5161897Swollman		f_print(fout, "\t}\n");
5171897Swollman
51812798Swpaul		f_print(fout,
51912798Swpaul			"\t(void) memset((char *)&%s, 0, sizeof (%s));\n",
52012798Swpaul			ARG, ARG);
521149709Sstefanf		printif("getargs", TRANSP, "(caddr_t) &", ARG);
5221897Swollman		printerr("decode", TRANSP);
52312798Swpaul		print_return("\t\t");
5241897Swollman		f_print(fout, "\t}\n");
5251897Swollman
526100441Scharnier		if (!mtflag)
527149709Sstefanf			f_print(fout, "\t%s = (*%s)((char *)&%s, %s);\n",
528149709Sstefanf				RESULT, ROUTINE, ARG, RQSTP);
52912798Swpaul		else
530149709Sstefanf			f_print(fout, "\t%s = (bool_t) (*%s)((char *)&%s, (void *)&%s, %s);\n",
531149709Sstefanf				RETVAL, ROUTINE, ARG, RESULT, RQSTP);
53212798Swpaul
53312798Swpaul
53412798Swpaul		if (mtflag)
53512798Swpaul			f_print(fout,
53612798Swpaul				"\tif (%s > 0 && !svc_sendreply(%s, xdr_%s, (char *)&%s)) {\n",
53712798Swpaul				RETVAL, TRANSP, RESULT, RESULT);
53812798Swpaul		else
53912798Swpaul			f_print(fout,
54012798Swpaul				"\tif (%s != NULL && !svc_sendreply(%s, xdr_%s, %s)) {\n",
54112798Swpaul				RESULT, TRANSP, RESULT, RESULT);
54212798Swpaul
5431897Swollman		printerr("systemerr", TRANSP);
5441897Swollman		f_print(fout, "\t}\n");
5451897Swollman
546149709Sstefanf		printif("freeargs", TRANSP, "(caddr_t) &", ARG);
54712798Swpaul		(void) sprintf(_errbuf, "unable to free arguments");
54812798Swpaul		print_err_message("\t\t");
5491897Swollman		f_print(fout, "\t\texit(1);\n");
5501897Swollman		f_print(fout, "\t}\n");
55112798Swpaul		/* print out free routine */
55212798Swpaul		if (mtflag) {
55312798Swpaul			f_print(fout,"\tif (!");
55412798Swpaul			pvname(def->def_name, vp->vers_num);
55512798Swpaul			f_print(fout,"_freeresult(%s, xdr_%s, (caddr_t) &%s))\n",
55612798Swpaul				TRANSP, RESULT, RESULT);
55712798Swpaul			(void) sprintf(_errbuf, "unable to free results");
55812798Swpaul			print_err_message("\t\t");
55912798Swpaul			f_print(fout, "\n");
56012798Swpaul		};
56112798Swpaul		print_return("\t");
56212798Swpaul		f_print(fout, "}\n");
5631897Swollman	}
5641897Swollman}
5651897Swollman
56617142Sjkhstatic void
567152398Sdwmaloneprinterr(const char *err, const char *transp)
5681897Swollman{
5691897Swollman	f_print(fout, "\t\tsvcerr_%s(%s);\n", err, transp);
5701897Swollman}
5711897Swollman
57217142Sjkhstatic void
573152398Sdwmaloneprintif(const char *proc, const char *transp, const char *prefix,
574152398Sdwmalone    const char *arg)
5751897Swollman{
57674462Salfred	f_print(fout, "\tif (!svc_%s(%s, xdr_%s, (char *)%s%s)) {\n",
5771897Swollman		proc, transp, arg, prefix, arg);
5781897Swollman}
5791897Swollman
58017142Sjkhint
581152398Sdwmalonenullproc(proc_list *proc)
5821897Swollman{
5831897Swollman	for (; proc != NULL; proc = proc->next) {
5841897Swollman		if (streq(proc->proc_num, "0")) {
5851897Swollman			return (1);
5861897Swollman		}
5871897Swollman	}
5881897Swollman	return (0);
5891897Swollman}
59012798Swpaul
59117142Sjkhstatic void
592152398Sdwmalonewrite_inetmost(const char *infile)
59312798Swpaul{
59412798Swpaul	f_print(fout, "\tregister SVCXPRT *%s;\n", TRANSP);
59512798Swpaul	f_print(fout, "\tint sock;\n");
59612798Swpaul	f_print(fout, "\tint proto;\n");
59712798Swpaul	f_print(fout, "\tstruct sockaddr_in saddr;\n");
598149733Sstefanf	f_print(fout, "\tsocklen_t asize = sizeof (saddr);\n");
59912798Swpaul	f_print(fout, "\n");
60012798Swpaul	f_print(fout,
60112798Swpaul	"\tif (getsockname(0, (struct sockaddr *)&saddr, &asize) == 0) {\n");
602149733Sstefanf	f_print(fout, "\t\tsocklen_t ssize = sizeof (int);\n\n");
60312798Swpaul	f_print(fout, "\t\tif (saddr.sin_family != AF_INET)\n");
60412798Swpaul	f_print(fout, "\t\t\texit(1);\n");
60512798Swpaul	f_print(fout, "\t\tif (getsockopt(0, SOL_SOCKET, SO_TYPE,\n");
60612798Swpaul	f_print(fout, "\t\t\t\t(char *)&_rpcfdtype, &ssize) == -1)\n");
60712798Swpaul	f_print(fout, "\t\t\texit(1);\n");
60812798Swpaul	f_print(fout, "\t\tsock = 0;\n");
60912798Swpaul	f_print(fout, "\t\t_rpcpmstart = 1;\n");
61012798Swpaul	f_print(fout, "\t\tproto = 0;\n");
61112798Swpaul	open_log_file(infile, "\t\t");
61212798Swpaul	f_print(fout, "\t} else {\n");
61312798Swpaul	write_rpc_svc_fg(infile, "\t\t");
61412798Swpaul	f_print(fout, "\t\tsock = RPC_ANYSOCK;\n");
61512798Swpaul	print_pmapunset("\t\t");
61612798Swpaul	f_print(fout, "\t}\n");
61712798Swpaul}
61812798Swpaul
61917142Sjkhstatic void
620152398Sdwmaloneprint_return(const char *space)
62112798Swpaul{
62212798Swpaul	if (exitnow)
62312798Swpaul		f_print(fout, "%sexit(0);\n", space);
62412798Swpaul	else {
62512798Swpaul		if (timerflag) {
62612798Swpaul			if (mtflag)
62712798Swpaul				f_print(fout, "%smutex_lock(&_svcstate_lock);\n", space);
62812798Swpaul				f_print(fout, "%s_rpcsvcstate = _SERVED;\n", space);
62912798Swpaul			if (mtflag)
63012798Swpaul				f_print(fout, "%smutex_unlock(&_svcstate_lock);\n", space);
63112798Swpaul		}
63212798Swpaul		f_print(fout, "%sreturn;\n", space);
63312798Swpaul	}
63412798Swpaul}
63512798Swpaul
63617142Sjkhstatic void
637152398Sdwmaloneprint_pmapunset(const char *space)
63812798Swpaul{
63912798Swpaul	list *l;
64012798Swpaul	definition *def;
64112798Swpaul	version_list *vp;
64212798Swpaul
64312798Swpaul	for (l = defined; l != NULL; l = l->next) {
64412798Swpaul		def = (definition *) l->val;
64512798Swpaul		if (def->def_kind == DEF_PROGRAM) {
64612798Swpaul			for (vp = def->def.pr.versions; vp != NULL;
64712798Swpaul					vp = vp->next) {
64812798Swpaul				f_print(fout, "%s(void) pmap_unset(%s, %s);\n",
64912798Swpaul					space, def->def_name, vp->vers_name);
65012798Swpaul			}
65112798Swpaul		}
65212798Swpaul	}
65312798Swpaul}
65412798Swpaul
65517142Sjkhstatic void
656152398Sdwmaloneprint_err_message(const char *space)
65712798Swpaul{
65812798Swpaul	if (logflag)
65912798Swpaul		f_print(fout, "%ssyslog(LOG_ERR, \"%s\");\n", space, _errbuf);
66012798Swpaul	else if (inetdflag || pmflag)
66112798Swpaul		f_print(fout, "%s_msgout(\"%s\");\n", space, _errbuf);
66212798Swpaul	else
66312798Swpaul		f_print(fout, "%sfprintf(stderr, \"%s\");\n", space, _errbuf);
66412798Swpaul}
66512798Swpaul
66612798Swpaul/*
66712798Swpaul * Write the server auxiliary function (_msgout, timeout)
66812798Swpaul */
66912798Swpaulvoid
670152398Sdwmalonewrite_svc_aux(int nomain)
67112798Swpaul{
67212798Swpaul	if (!logflag)
67312798Swpaul		write_msg_out();
67412798Swpaul	if (!nomain)
67512798Swpaul		write_timeout_func();
67612798Swpaul}
67712798Swpaul
67812798Swpaul/*
67912798Swpaul * Write the _msgout function
68012798Swpaul */
68112798Swpaul
68217142Sjkhstatic void
68317142Sjkhwrite_msg_out(void)
68412798Swpaul{
68512798Swpaul	f_print(fout, "\n");
68612798Swpaul/*
68712798Swpaul * Avoid making _msgout() static -- it's useful to have it visible
68812798Swpaul * in the toplevel RPC server code.
68912798Swpaul */
69012798Swpaul	f_print(fout, "static\n");
691149709Sstefanf	f_print(fout, "void _msgout(const char* msg)\n");
69212798Swpaul	f_print(fout, "{\n");
69312798Swpaul	f_print(fout, "#ifdef RPC_SVC_FG\n");
69412798Swpaul	if (inetdflag || pmflag)
69512798Swpaul		f_print(fout, "\tif (_rpcpmstart)\n");
69679295Skris	f_print(fout, "\t\tsyslog(LOG_ERR, \"%%s\", msg);\n");
69712798Swpaul	f_print(fout, "\telse\n");
69812798Swpaul	f_print(fout,
69912798Swpaul		"\t\t(void) fprintf(stderr, \"%%s\\n\", msg);\n");
70012798Swpaul	f_print(fout, "#else\n");
70179295Skris	f_print(fout, "\tsyslog(LOG_ERR, \"%%s\", msg);\n");
70212798Swpaul	f_print(fout, "#endif\n");
70312798Swpaul	f_print(fout, "}\n");
70412798Swpaul}
70512798Swpaul
70612798Swpaul/*
70712798Swpaul * Write the timeout function
70812798Swpaul */
70917142Sjkhstatic void
71017142Sjkhwrite_timeout_func(void)
71112798Swpaul{
71212798Swpaul	if (!timerflag)
71312798Swpaul		return;
71412798Swpaul
71512798Swpaul	f_print(fout, "\n");
71612798Swpaul	f_print(fout, "static void\n");
717149709Sstefanf	f_print(fout, "closedown(int sig)\n");
71812798Swpaul	f_print(fout, "{\n");
71912798Swpaul	if (mtflag)
72012798Swpaul		f_print(fout, "\tmutex_lock(&_svcstate_lock);\n");
72112798Swpaul	f_print(fout, "\tif (_rpcsvcstate == _IDLE) {\n");
72212798Swpaul	f_print(fout, "\t\textern fd_set svc_fdset;\n");
72312798Swpaul	f_print(fout, "\t\tstatic int size;\n");
72412798Swpaul	f_print(fout, "\t\tint i, openfd;\n");
72512798Swpaul	if (tirpcflag && pmflag) {
72612798Swpaul		f_print(fout, "\t\tstruct t_info tinfo;\n\n");
72712798Swpaul		f_print(fout,
72812798Swpaul			"\t\tif (!t_getinfo(0, &tinfo) && (tinfo.servtype == T_CLTS))\n");
72912798Swpaul	} else {
73012798Swpaul		f_print(fout, "\n\t\tif (_rpcfdtype == SOCK_DGRAM)\n");
73112798Swpaul	}
73212798Swpaul	f_print(fout, "\t\t\texit(0);\n");
73312798Swpaul	f_print(fout, "\t\tif (size == 0) {\n");
73412798Swpaul	if (tirpcflag) {
73512798Swpaul		f_print(fout, "\t\t\tstruct rlimit rl;\n\n");
73612798Swpaul		f_print(fout, "\t\t\trl.rlim_max = 0;\n");
73712798Swpaul		f_print(fout, "\t\t\tgetrlimit(RLIMIT_NOFILE, &rl);\n");
73812798Swpaul		f_print(fout, "\t\t\tif ((size = rl.rlim_max) == 0) {\n");
73912798Swpaul
74012798Swpaul		if (mtflag)
74112798Swpaul			f_print(fout, "\t\t\t\tmutex_unlock(&_svcstate_lock);\n");
74212798Swpaul
74312798Swpaul		f_print(fout, "\t\t\t\treturn;\n\t\t\t}\n");
74412798Swpaul	} else {
74512798Swpaul		f_print(fout, "\t\t\tsize = getdtablesize();\n");
74612798Swpaul	}
74712798Swpaul	f_print(fout, "\t\t}\n");
74812798Swpaul	f_print(fout,
74912798Swpaul		"\t\tfor (i = 0, openfd = 0; i < size && openfd < 2; i++)\n");
75012798Swpaul	f_print(fout, "\t\t\tif (FD_ISSET(i, &svc_fdset))\n");
75112798Swpaul	f_print(fout, "\t\t\t\topenfd++;\n");
75212798Swpaul	f_print(fout, "\t\tif (openfd <= 1)\n");
75312798Swpaul	f_print(fout, "\t\t\texit(0);\n");
75412798Swpaul	f_print(fout, "\t}\n");
75512798Swpaul	f_print(fout, "\tif (_rpcsvcstate == _SERVED)\n");
75612798Swpaul	f_print(fout, "\t\t_rpcsvcstate = _IDLE;\n\n");
75712798Swpaul	if (mtflag)
75812798Swpaul		f_print(fout, "\tmutex_unlock(&_svcstate_lock);\n");
75912798Swpaul
760149709Sstefanf	f_print(fout, "\t(void) signal(SIGALRM, closedown);\n");
76112798Swpaul	f_print(fout, "\t(void) alarm(_RPCSVC_CLOSEDOWN/2);\n");
76212798Swpaul	f_print(fout, "}\n");
76312798Swpaul
76412798Swpaul}
76512798Swpaul
76612798Swpaul/*
76712798Swpaul * Write the most of port monitor support
76812798Swpaul */
76917142Sjkhstatic void
770152398Sdwmalonewrite_pm_most(const char *infile, int netflag)
77112798Swpaul{
77212798Swpaul	list *l;
77312798Swpaul	definition *def;
77412798Swpaul	version_list *vp;
77512798Swpaul
77699979Salfred	if (tirpc_socket) {
77799979Salfred		f_print(fout,
77899979Salfred		"\tif (getsockname(0, (struct sockaddr *)&saddr, &asize) == 0) {\n");
779149733Sstefanf		f_print(fout, "\t\tsocklen_t ssize = sizeof (int);\n");
78099979Salfred	} else {
78199979Salfred		f_print(fout, "\tif (!ioctl(0, I_LOOK, mname) &&\n");
78299979Salfred		f_print(fout, "\t\t(!strcmp(mname, \"sockmod\") ||");
78399979Salfred		f_print(fout, " !strcmp(mname, \"timod\"))) {\n");
78499979Salfred	}
78512798Swpaul	f_print(fout, "\t\tchar *netid;\n");
78612798Swpaul	if (!netflag) {	/* Not included by -n option */
78712798Swpaul		f_print(fout, "\t\tstruct netconfig *nconf = NULL;\n");
78812798Swpaul		f_print(fout, "\t\tSVCXPRT *%s;\n", TRANSP);
78912798Swpaul	}
79012798Swpaul	if (timerflag)
79112798Swpaul		f_print(fout, "\t\tint pmclose;\n");
79212798Swpaul/*
79312798Swpaul *  Not necessary, defined in /usr/include/stdlib
79412798Swpaul *  f_print(fout, "\t\textern char *getenv();\n");
79512798Swpaul */
79612798Swpaul	f_print(fout, "\n");
79799979Salfred	if (tirpc_socket) {
79899979Salfred		f_print(fout, "\t\tif (saddr.ss_family != AF_INET &&\n");
79999979Salfred		f_print(fout, "\t\t    saddr.ss_family != AF_INET6)\n");
80099979Salfred		f_print(fout, "\t\t\texit(1);\n");
80199979Salfred		f_print(fout, "\t\tif (getsockopt(0, SOL_SOCKET, SO_TYPE,\n");
80299979Salfred		f_print(fout, "\t\t\t\t(char *)&_rpcfdtype, &ssize) == -1)\n");
80399979Salfred		f_print(fout, "\t\t\texit(1);\n");
80499979Salfred	}
80512798Swpaul	f_print(fout, "\t\t_rpcpmstart = 1;\n");
80612798Swpaul	open_log_file(infile, "\t\t");
80712798Swpaul	f_print(fout, "\n\t\tif ((netid = \
80812798Swpaulgetenv(\"NLSPROVIDER\")) == NULL) {\n");
80912798Swpaul
81012798Swpaul	if (timerflag) {
81112798Swpaul		f_print(fout, "\t\t/* started from inetd */\n");
81212798Swpaul		f_print(fout, "\t\t\tpmclose = 1;\n");
81312798Swpaul	}
81412798Swpaul	f_print(fout,
81512798Swpaul		"\t\t} else {\n");
81612798Swpaul	f_print(fout, "\t\t\tif ((nconf = getnetconfigent(netid)) == NULL)\n");
81712798Swpaul	sprintf(_errbuf, "cannot get transport info");
81812798Swpaul	print_err_message("\t\t\t\t");
81999979Salfred       if (timerflag) {
82099979Salfred		if (tirpc_socket)
82199979Salfred			f_print(fout, "\n\t\t\tpmclose = 1;\t/* XXX */\n");
82299979Salfred		else
82399979Salfred			f_print(fout,
82499979Salfred			    "\n\t\t\tpmclose = (t_getstate(0) != T_DATAXFER);\n");
82599979Salfred	}
82612798Swpaul	f_print(fout, "\t\t}\n");
82712798Swpaul	/*
82812798Swpaul	 * A kludgy support for inetd services. Inetd only works with
82912798Swpaul	 * sockmod, and RPC works only with timod, hence all this jugglery
83012798Swpaul	 */
83199979Salfred	if (!tirpc_socket) {
83299979Salfred		f_print(fout, "\t\tif (strcmp(mname, \"sockmod\") == 0) {\n");
83399979Salfred		f_print(fout, "\t\t\tif (ioctl(0, I_POP, 0) || ");
83499979Salfred		f_print(fout, "ioctl(0, I_PUSH, \"timod\")) {\n");
83599979Salfred		sprintf(_errbuf, "could not get the right module");
83699979Salfred		print_err_message("\t\t\t\t");
83799979Salfred		f_print(fout, "\t\t\t\texit(1);\n");
83899979Salfred		f_print(fout, "\t\t\t}\n");
83999979Salfred		f_print(fout, "\t\t}\n");
84099979Salfred	}
841109363Smbr	if (tirpcflag) {
842109363Smbr		f_print(fout,
843109363Smbr		"\t\tif ((%s = svc_tli_create(0, nconf, NULL, \
844109363Smbr		RPC_MAXDATASIZE, RPC_MAXDATASIZE)) \
845109363Smbr		== NULL) {\n",
84612798Swpaul		TRANSP);
847109363Smbr	} else {
848109363Smbr		f_print(fout,
849109363Smbr		    "\t\tif ((%s = svc_tli_create(0, nconf, NULL, 0, 0)) \
850109363Smbr		    == NULL) {\n",
851109363Smbr                    TRANSP);
852109363Smbr	}
85312798Swpaul	sprintf(_errbuf, "cannot create server handle");
85412798Swpaul	print_err_message("\t\t\t");
85512798Swpaul	f_print(fout, "\t\t\texit(1);\n");
85612798Swpaul	f_print(fout, "\t\t}\n");
85712798Swpaul	f_print(fout, "\t\tif (nconf)\n");
85812798Swpaul	f_print(fout, "\t\t\tfreenetconfigent(nconf);\n");
85912798Swpaul	for (l = defined; l != NULL; l = l->next) {
86012798Swpaul		def = (definition *) l->val;
86112798Swpaul		if (def->def_kind != DEF_PROGRAM) {
86212798Swpaul			continue;
86312798Swpaul		}
86412798Swpaul		for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
86512798Swpaul			f_print(fout,
86612798Swpaul				"\t\tif (!svc_reg(%s, %s, %s, ",
86712798Swpaul				TRANSP, def->def_name, vp->vers_name);
86812798Swpaul			pvname(def->def_name, vp->vers_num);
86912798Swpaul			f_print(fout, ", 0)) {\n");
87012798Swpaul			(void) sprintf(_errbuf, "unable to register (%s, %s).",
87112798Swpaul					def->def_name, vp->vers_name);
87212798Swpaul			print_err_message("\t\t\t");
87312798Swpaul			f_print(fout, "\t\t\texit(1);\n");
87412798Swpaul			f_print(fout, "\t\t}\n");
87512798Swpaul		}
87612798Swpaul	}
87712798Swpaul	if (timerflag) {
87812798Swpaul		f_print(fout, "\t\tif (pmclose) {\n");
879149709Sstefanf		f_print(fout, "\t\t\t(void) signal(SIGALRM, closedown);\n");
88012798Swpaul		f_print(fout, "\t\t\t(void) alarm(_RPCSVC_CLOSEDOWN/2);\n");
88112798Swpaul		f_print(fout, "\t\t}\n");
88212798Swpaul	}
88312798Swpaul	f_print(fout, "\t\tsvc_run();\n");
88412798Swpaul	f_print(fout, "\t\texit(1);\n");
88512798Swpaul	f_print(fout, "\t\t/* NOTREACHED */\n");
88612798Swpaul	f_print(fout, "\t}");
88712798Swpaul}
88812798Swpaul
88912798Swpaul/*
89012798Swpaul * Support for backgrounding the server if self started.
89112798Swpaul */
89217142Sjkhstatic void
893152398Sdwmalonewrite_rpc_svc_fg(const char *infile, const char *sp)
89412798Swpaul{
89512798Swpaul	f_print(fout, "#ifndef RPC_SVC_FG\n");
89612798Swpaul	f_print(fout, "%sint size;\n", sp);
89712798Swpaul	if (tirpcflag)
89812798Swpaul		f_print(fout, "%sstruct rlimit rl;\n", sp);
89912798Swpaul	if (inetdflag)
90012798Swpaul		f_print(fout, "%sint pid, i;\n\n", sp);
90112798Swpaul	f_print(fout, "%spid = fork();\n", sp);
90212798Swpaul	f_print(fout, "%sif (pid < 0) {\n", sp);
90312798Swpaul	f_print(fout, "%s\tperror(\"cannot fork\");\n", sp);
90412798Swpaul	f_print(fout, "%s\texit(1);\n", sp);
90512798Swpaul	f_print(fout, "%s}\n", sp);
90612798Swpaul	f_print(fout, "%sif (pid)\n", sp);
90712798Swpaul	f_print(fout, "%s\texit(0);\n", sp);
90812798Swpaul	/* get number of file descriptors */
90912798Swpaul	if (tirpcflag) {
91012798Swpaul		f_print(fout, "%srl.rlim_max = 0;\n", sp);
91112798Swpaul		f_print(fout, "%sgetrlimit(RLIMIT_NOFILE, &rl);\n", sp);
91212798Swpaul		f_print(fout, "%sif ((size = rl.rlim_max) == 0)\n", sp);
91312798Swpaul		f_print(fout, "%s\texit(1);\n", sp);
91412798Swpaul	} else {
91512798Swpaul		f_print(fout, "%ssize = getdtablesize();\n", sp);
91612798Swpaul	}
91712798Swpaul
91812798Swpaul	f_print(fout, "%sfor (i = 0; i < size; i++)\n", sp);
91912798Swpaul	f_print(fout, "%s\t(void) close(i);\n", sp);
92012798Swpaul	/* Redirect stderr and stdout to console */
92112798Swpaul	f_print(fout, "%si = open(\"/dev/console\", 2);\n", sp);
92212798Swpaul	f_print(fout, "%s(void) dup2(i, 1);\n", sp);
92312798Swpaul	f_print(fout, "%s(void) dup2(i, 2);\n", sp);
92412798Swpaul	/* This removes control of the controlling terminal */
92512798Swpaul	if (tirpcflag)
92612798Swpaul		f_print(fout, "%ssetsid();\n", sp);
92712798Swpaul	else {
92812798Swpaul		f_print(fout, "%si = open(\"/dev/tty\", 2);\n", sp);
92912798Swpaul		f_print(fout, "%sif (i >= 0) {\n", sp);
93012798Swpaul		f_print(fout,
93112798Swpaul			"%s\t(void) ioctl(i, TIOCNOTTY, (char *)NULL);\n", sp);
93212798Swpaul		f_print(fout, "%s\t(void) close(i);\n", sp);
93312798Swpaul		f_print(fout, "%s}\n", sp);
93412798Swpaul	}
93512798Swpaul	if (!logflag)
93612798Swpaul		open_log_file(infile, sp);
93712798Swpaul	f_print(fout, "#endif\n");
93812798Swpaul	if (logflag)
93912798Swpaul		open_log_file(infile, sp);
94012798Swpaul}
94112798Swpaul
94217142Sjkhstatic void
943152398Sdwmaloneopen_log_file(const char *infile, const char *sp)
94412798Swpaul{
94512798Swpaul	char *s;
94612798Swpaul
94712798Swpaul	s = strrchr(infile, '.');
94812798Swpaul	if (s)
94912798Swpaul		*s = '\0';
95012798Swpaul	f_print(fout, "%sopenlog(\"%s\", LOG_PID, LOG_DAEMON);\n", sp, infile);
95112798Swpaul	if (s)
95212798Swpaul		*s = '.';
95312798Swpaul}
95412798Swpaul
95512798Swpaul
95612798Swpaul
95712798Swpaul
95812798Swpaul/*
95912798Swpaul * write a registration for the given transport for Inetd
96012798Swpaul */
96112798Swpaulvoid
962152398Sdwmalonewrite_inetd_register(const char *transp)
96312798Swpaul{
96412798Swpaul	list *l;
96512798Swpaul	definition *def;
96612798Swpaul	version_list *vp;
967152398Sdwmalone	const char *sp;
96812798Swpaul	int isudp;
96912798Swpaul	char tmpbuf[32];
97012798Swpaul
97112798Swpaul	if (inetdflag)
97212798Swpaul		sp = "\t";
97312798Swpaul	else
97412798Swpaul		sp = "";
97512798Swpaul	if (streq(transp, "udp"))
97612798Swpaul		isudp = 1;
97712798Swpaul	else
97812798Swpaul		isudp = 0;
97912798Swpaul	f_print(fout, "\n");
98012798Swpaul	if (inetdflag) {
98112798Swpaul		f_print(fout,
98212798Swpaul			"\tif ((_rpcfdtype == 0) || (_rpcfdtype == %s)) {\n",
98312798Swpaul			isudp ? "SOCK_DGRAM" : "SOCK_STREAM");
98412798Swpaul	}
985109363Smbr	if (tirpcflag)
986109363Smbr		f_print(fout, "\t\trpc_control(RPC_SVC_CONNMAXREC_SET, &maxrec);\n");
98712798Swpaul	f_print(fout, "%s\t%s = svc%s_create(%s",
98812798Swpaul		sp, TRANSP, transp, inetdflag? "sock": "RPC_ANYSOCK");
98912798Swpaul	if (!isudp)
99012798Swpaul		f_print(fout, ", 0, 0");
99112798Swpaul	f_print(fout, ");\n");
99212798Swpaul	f_print(fout, "%s\tif (%s == NULL) {\n", sp, TRANSP);
99312798Swpaul	(void) sprintf(_errbuf, "cannot create %s service.", transp);
99412798Swpaul	(void) sprintf(tmpbuf, "%s\t\t", sp);
99512798Swpaul	print_err_message(tmpbuf);
99612798Swpaul	f_print(fout, "%s\t\texit(1);\n", sp);
99712798Swpaul	f_print(fout, "%s\t}\n", sp);
99812798Swpaul
99912798Swpaul	if (inetdflag) {
100012798Swpaul		f_print(fout, "%s\tif (!_rpcpmstart)\n\t", sp);
100112798Swpaul		f_print(fout, "%s\tproto = IPPROTO_%s;\n",
100212798Swpaul				sp, isudp ? "UDP": "TCP");
100312798Swpaul	}
100412798Swpaul	for (l = defined; l != NULL; l = l->next) {
100512798Swpaul		def = (definition *) l->val;
100612798Swpaul		if (def->def_kind != DEF_PROGRAM) {
100712798Swpaul			continue;
100812798Swpaul		}
100912798Swpaul		for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
101012798Swpaul			f_print(fout, "%s\tif (!svc_register(%s, %s, %s, ",
101112798Swpaul				sp, TRANSP, def->def_name, vp->vers_name);
101212798Swpaul			pvname(def->def_name, vp->vers_num);
101312798Swpaul			if (inetdflag)
101412798Swpaul				f_print(fout, ", proto)) {\n");
101512798Swpaul			else
101612798Swpaul				f_print(fout, ", IPPROTO_%s)) {\n",
101712798Swpaul					isudp ? "UDP": "TCP");
101812798Swpaul			(void) sprintf(_errbuf,
101912798Swpaul				"unable to register (%s, %s, %s).",
102012798Swpaul				def->def_name, vp->vers_name, transp);
102112798Swpaul			print_err_message(tmpbuf);
102212798Swpaul			f_print(fout, "%s\t\texit(1);\n", sp);
102312798Swpaul			f_print(fout, "%s\t}\n", sp);
102412798Swpaul		}
102512798Swpaul	}
102612798Swpaul	if (inetdflag)
102712798Swpaul		f_print(fout, "\t}\n");
102812798Swpaul}
1029