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$");
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) {
119171932Sdelphij				f_print(fout, "pthread_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 */
129170825Sse	write_programs((char *)NULL);
13012798Swpaul
13112798Swpaul	if (nomain)
13212798Swpaul		return;
13312798Swpaul
13499979Salfred	f_print(fout, "\nint\n");
13599979Salfred	f_print(fout, "main()\n");
1361897Swollman	f_print(fout, "{\n");
13712798Swpaul	if (inetdflag) {
13812798Swpaul		write_inetmost(infile);
13912798Swpaul		/* Includes call to write_rpc_svc_fg() */
14012798Swpaul	} else {
14112798Swpaul		if (tirpcflag) {
14212798Swpaul			if (netflag) {
14312798Swpaul				f_print(fout,
14412798Swpaul					"\tregister SVCXPRT *%s;\n", TRANSP);
14512798Swpaul				f_print(fout,
14612798Swpaul					"\tstruct netconfig *nconf = NULL;\n");
14712798Swpaul			}
14812798Swpaul			f_print(fout, "\tpid_t pid;\n");
14912798Swpaul			f_print(fout, "\tint i;\n");
15099979Salfred			if (pmflag) {
15199979Salfred				if (tirpc_socket) {
15299979Salfred					f_print(fout, "\tstruct sockaddr_storage saddr;\n");
153149733Sstefanf					f_print(fout, "\tsocklen_t asize = sizeof (saddr);\n\n");
15499979Salfred				} else
15599979Salfred					f_print(fout, "\tchar mname[FMNAMESZ + 1];\n\n");
15699979Salfred			}
15712798Swpaul
15812798Swpaul			if (mtflag & timerflag)
15912798Swpaul				f_print(fout, "\tmutex_init(&_svcstate_lock, USYNC_THREAD, NULL);\n");
16099979Salfred			if (pmflag) {
16199979Salfred				write_pm_most(infile, netflag);
16299979Salfred				f_print(fout, "\telse {\n");
16399979Salfred				write_rpc_svc_fg(infile, "\t\t");
16499979Salfred				f_print(fout, "\t}\n");
165100441Scharnier			} else
16699979Salfred				write_rpc_svc_fg(infile, "\t\t");
16712798Swpaul
16812798Swpaul		} else {
16912798Swpaul			f_print(fout, "\tregister SVCXPRT *%s;\n", TRANSP);
17012798Swpaul			f_print(fout, "\n");
17112798Swpaul			print_pmapunset("\t");
17212798Swpaul		}
17312798Swpaul	}
17412798Swpaul
17512798Swpaul	if (logflag && !inetdflag) {
17612798Swpaul		open_log_file(infile, "\t");
17712798Swpaul	}
17812798Swpaul}
17912798Swpaul
18012798Swpaul/*
18112798Swpaul * write a registration for the given transport
18212798Swpaul */
18312798Swpaulvoid
184152398Sdwmalonewrite_netid_register(const char *transp)
18512798Swpaul{
18612798Swpaul	list *l;
18712798Swpaul	definition *def;
18812798Swpaul	version_list *vp;
189152398Sdwmalone	const char *sp;
19012798Swpaul	char tmpbuf[32];
19112798Swpaul
19212798Swpaul	sp = "";
1931897Swollman	f_print(fout, "\n");
19412798Swpaul	f_print(fout, "%s\tnconf = getnetconfigent(\"%s\");\n", sp, transp);
19512798Swpaul	f_print(fout, "%s\tif (nconf == NULL) {\n", sp);
19612798Swpaul	(void) sprintf(_errbuf, "cannot find %s netid.", transp);
19712798Swpaul	sprintf(tmpbuf, "%s\t\t", sp);
19812798Swpaul	print_err_message(tmpbuf);
19912798Swpaul	f_print(fout, "%s\t\texit(1);\n", sp);
20012798Swpaul	f_print(fout, "%s\t}\n", sp);
201109363Smbr	if (tirpcflag) {
202109363Smbr		f_print(fout, "%s\t%s = svc_tli_create(RPC_ANYFD, ",
203109363Smbr		    sp, TRANSP);
204109363Smbr		f_print(fout,"nconf, 0, RPC_MAXDATASIZE, RPC_MAXDATASIZE);\n");
205109363Smbr	} else {
206109363Smbr		f_print(fout,
207109363Smbr		    "%s\t%s = svc_tli_create(RPC_ANYFD, nconf, 0, 0, 0);\n",
208109363Smbr		    sp, TRANSP);
209109363Smbr	}
21012798Swpaul	f_print(fout, "%s\tif (%s == NULL) {\n", sp, TRANSP);
21112798Swpaul	(void) sprintf(_errbuf, "cannot create %s service.", transp);
21212798Swpaul	print_err_message(tmpbuf);
21312798Swpaul	f_print(fout, "%s\t\texit(1);\n", sp);
21412798Swpaul	f_print(fout, "%s\t}\n", sp);
21512798Swpaul
2161897Swollman	for (l = defined; l != NULL; l = l->next) {
2171897Swollman		def = (definition *) l->val;
2181897Swollman		if (def->def_kind != DEF_PROGRAM) {
2191897Swollman			continue;
2201897Swollman		}
2211897Swollman		for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
22212798Swpaul			f_print(fout,
22312798Swpaul				"%s\t(void) rpcb_unset(%s, %s, nconf);\n",
22412798Swpaul				sp, def->def_name, vp->vers_name);
22512798Swpaul			f_print(fout,
22612798Swpaul				"%s\tif (!svc_reg(%s, %s, %s, ",
22712798Swpaul				sp, TRANSP, def->def_name, vp->vers_name);
22812798Swpaul			pvname(def->def_name, vp->vers_num);
22912798Swpaul			f_print(fout, ", nconf)) {\n");
23012798Swpaul			(void) sprintf(_errbuf,
23112798Swpaul				"unable to register (%s, %s, %s).",
23212798Swpaul				def->def_name, vp->vers_name, transp);
23312798Swpaul			print_err_message(tmpbuf);
23412798Swpaul			f_print(fout, "%s\t\texit(1);\n", sp);
23512798Swpaul			f_print(fout, "%s\t}\n", sp);
2361897Swollman		}
2371897Swollman	}
23812798Swpaul	f_print(fout, "%s\tfreenetconfigent(nconf);\n", sp);
2391897Swollman}
2401897Swollman
2411897Swollman/*
24212798Swpaul * write a registration for the given transport for TLI
2431897Swollman */
2441897Swollmanvoid
245152398Sdwmalonewrite_nettype_register(const char *transp)
2461897Swollman{
2471897Swollman	list *l;
2481897Swollman	definition *def;
2491897Swollman	version_list *vp;
2501897Swollman
2511897Swollman	for (l = defined; l != NULL; l = l->next) {
2521897Swollman		def = (definition *) l->val;
2531897Swollman		if (def->def_kind != DEF_PROGRAM) {
2541897Swollman			continue;
2551897Swollman		}
2561897Swollman		for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
25712798Swpaul			f_print(fout, "\tif (!svc_create(");
2581897Swollman			pvname(def->def_name, vp->vers_num);
25912798Swpaul			f_print(fout, ", %s, %s, \"%s\")) {\n",
2601897Swollman				def->def_name, vp->vers_name, transp);
26112798Swpaul			(void) sprintf(_errbuf,
26212798Swpaul				"unable to create (%s, %s) for %s.",
26312798Swpaul					def->def_name, vp->vers_name, transp);
26412798Swpaul			print_err_message("\t\t");
2651897Swollman			f_print(fout, "\t\texit(1);\n");
2661897Swollman			f_print(fout, "\t}\n");
2671897Swollman		}
2681897Swollman	}
2691897Swollman}
2701897Swollman
2711897Swollman/*
2728874Srgrimes * write the rest of the service
2731897Swollman */
2741897Swollmanvoid
275152398Sdwmalonewrite_rest(void)
2761897Swollman{
27712798Swpaul	f_print(fout, "\n");
27812798Swpaul	if (inetdflag) {
27912798Swpaul		f_print(fout, "\tif (%s == (SVCXPRT *)NULL) {\n", TRANSP);
28012798Swpaul		(void) sprintf(_errbuf, "could not create a handle");
28112798Swpaul		print_err_message("\t\t");
28212798Swpaul		f_print(fout, "\t\texit(1);\n");
28312798Swpaul		f_print(fout, "\t}\n");
28412798Swpaul		if (timerflag) {
28512798Swpaul			f_print(fout, "\tif (_rpcpmstart) {\n");
28612798Swpaul			f_print(fout,
287149709Sstefanf				"\t\t(void) signal(SIGALRM, closedown);\n");
28812798Swpaul			f_print(fout, "\t\t(void) \
28912798Swpaulalarm(_RPCSVC_CLOSEDOWN/2);\n");
29012798Swpaul			f_print(fout, "\t}\n");
29112798Swpaul		}
29212798Swpaul	}
2931897Swollman	f_print(fout, "\tsvc_run();\n");
29412798Swpaul	(void) sprintf(_errbuf, "svc_run returned");
29512798Swpaul	print_err_message("\t");
2961897Swollman	f_print(fout, "\texit(1);\n");
29712798Swpaul	f_print(fout, "\t/* NOTREACHED */\n");
2981897Swollman	f_print(fout, "}\n");
2991897Swollman}
3001897Swollman
3011897Swollmanvoid
302152398Sdwmalonewrite_programs(const char *storage)
3031897Swollman{
3041897Swollman	list *l;
3051897Swollman	definition *def;
3061897Swollman
30712798Swpaul	/* write out stubs for procedure  definitions */
3081897Swollman	for (l = defined; l != NULL; l = l->next) {
3091897Swollman		def = (definition *) l->val;
3101897Swollman		if (def->def_kind == DEF_PROGRAM) {
31112798Swpaul			write_real_program(def);
31212798Swpaul		}
31312798Swpaul	}
31412798Swpaul
31512798Swpaul	/* write out dispatcher for each program */
31612798Swpaul	for (l = defined; l != NULL; l = l->next) {
31712798Swpaul		def = (definition *) l->val;
31812798Swpaul		if (def->def_kind == DEF_PROGRAM) {
3191897Swollman			write_program(def, storage);
3201897Swollman		}
3211897Swollman	}
32212798Swpaul
32312798Swpaul
3241897Swollman}
3251897Swollman
32612798Swpaul/*
32712798Swpaul * write out definition of internal function (e.g. _printmsg_1(...))
32812798Swpaul *  which calls server's defintion of actual function (e.g. printmsg_1(...)).
32912798Swpaul *  Unpacks single user argument of printmsg_1 to call-by-value format
33012798Swpaul *  expected by printmsg_1.
33112798Swpaul */
33217142Sjkhstatic void
333152398Sdwmalonewrite_real_program(definition *def)
33412798Swpaul{
33512798Swpaul	version_list *vp;
33612798Swpaul	proc_list *proc;
33712798Swpaul	decl_list *l;
3381897Swollman
33912798Swpaul	if (!newstyle) return;  /* not needed for old style */
34012798Swpaul	for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
34112798Swpaul		for (proc = vp->procs; proc != NULL; proc = proc->next) {
34212798Swpaul			f_print(fout, "\n");
34312798Swpaul			if (!mtflag)
34412798Swpaul				internal_proctype(proc);
34512798Swpaul			else
34612798Swpaul				f_print(fout, "int");
34712798Swpaul			f_print(fout, "\n_");
34812798Swpaul			pvname(proc->proc_name, vp->vers_num);
349149709Sstefanf			f_print(fout, "(");
350149709Sstefanf			/* arg name */
351149709Sstefanf			if (proc->arg_num > 1)
352222080Sbenl				fputs(proc->args.argname, fout);
353149709Sstefanf			else
354149709Sstefanf				ptype(proc->args.decls->decl.prefix,
355149709Sstefanf				      proc->args.decls->decl.type, 0);
356149709Sstefanf			if (mtflag) {
357149709Sstefanf				f_print(fout, " *argp, void *%s, struct svc_req *%s)\n",
358149709Sstefanf					RESULT, RQSTP);
35912798Swpaul
36012798Swpaul
36112798Swpaul			}
362149709Sstefanf			else
363149709Sstefanf				f_print(fout, " *argp, struct svc_req *%s)\n",
364149709Sstefanf					RQSTP);
36512798Swpaul
36612798Swpaul			f_print(fout, "{\n");
36712798Swpaul			f_print(fout, "\treturn (");
368149709Sstefanf			pvname_svc(proc->proc_name, vp->vers_num);
36912798Swpaul			f_print(fout, "(");
37012798Swpaul			if (proc->arg_num < 2) { /* single argument */
37112798Swpaul				if (!streq(proc->args.decls->decl.type, "void"))
37212798Swpaul					f_print(fout, "*argp, "); /* non-void */
37312798Swpaul			} else {
37412798Swpaul				for (l = proc->args.decls;  l != NULL;
37512798Swpaul				     l = l->next)
37612798Swpaul					f_print(fout, "argp->%s, ",
37712798Swpaul						l->decl.name);
37812798Swpaul			}
37912798Swpaul			if (mtflag)
38012798Swpaul				f_print(fout, "%s, ",RESULT);
38112798Swpaul			f_print(fout, "%s));\n}\n", RQSTP);
38212798Swpaul		}
38312798Swpaul	}
38412798Swpaul}
38512798Swpaul
38617142Sjkhstatic void
387152398Sdwmalonewrite_program(definition *def, const char *storage)
3881897Swollman{
3891897Swollman	version_list *vp;
3901897Swollman	proc_list *proc;
3911897Swollman	int filled;
3921897Swollman
3931897Swollman	for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
3941897Swollman		f_print(fout, "\n");
3951897Swollman		if (storage != NULL) {
3961897Swollman			f_print(fout, "%s ", storage);
3971897Swollman		}
3981897Swollman		f_print(fout, "void\n");
3991897Swollman		pvname(def->def_name, vp->vers_num);
40012798Swpaul
401149709Sstefanf		f_print(fout, "(struct svc_req *%s, ", RQSTP);
402149710Sstefanf		f_print(fout, "SVCXPRT *%s)\n", TRANSP);
4031897Swollman		f_print(fout, "{\n");
4041897Swollman
4051897Swollman		filled = 0;
4061897Swollman		f_print(fout, "\tunion {\n");
4071897Swollman		for (proc = vp->procs; proc != NULL; proc = proc->next) {
40812798Swpaul			if (proc->arg_num < 2) { /* single argument */
40912798Swpaul				if (streq(proc->args.decls->decl.type,
41012798Swpaul					  "void")) {
41112798Swpaul					continue;
41212798Swpaul				}
41312798Swpaul				filled = 1;
41412798Swpaul				f_print(fout, "\t\t");
41512798Swpaul				ptype(proc->args.decls->decl.prefix,
41612798Swpaul				      proc->args.decls->decl.type, 0);
41712798Swpaul				pvname(proc->proc_name, vp->vers_num);
41812798Swpaul				f_print(fout, "_arg;\n");
41912798Swpaul
42012798Swpaul			} else {
42112798Swpaul				filled = 1;
42212798Swpaul				f_print(fout, "\t\t%s", proc->args.argname);
42312798Swpaul				f_print(fout, " ");
42412798Swpaul				pvname(proc->proc_name, vp->vers_num);
42512798Swpaul				f_print(fout, "_arg;\n");
4261897Swollman			}
4271897Swollman		}
4281897Swollman		if (!filled) {
4291897Swollman			f_print(fout, "\t\tint fill;\n");
4301897Swollman		}
4311897Swollman		f_print(fout, "\t} %s;\n", ARG);
43212798Swpaul
43312798Swpaul		if (mtflag) {
43412798Swpaul			f_print(fout, "\tunion {\n");
43512798Swpaul			for (proc = vp->procs; proc != NULL; proc = proc->next) {
436181630Sdfr				if (streq(proc->res_type, "void")) {
437181630Sdfr					continue;
438181630Sdfr				}
43912798Swpaul				f_print(fout, "\t\t");
44012798Swpaul				ptype(proc->res_prefix, proc->res_type, 0);
44112798Swpaul				pvname(proc->proc_name, vp->vers_num);
44212798Swpaul				f_print(fout, "_res;\n");
44312798Swpaul			}
44412798Swpaul			f_print(fout, "\t} %s;\n", RESULT);
44512798Swpaul			f_print(fout, "\tbool_t %s;\n", RETVAL);
44612798Swpaul
447100441Scharnier		} else
44812798Swpaul			f_print(fout, "\tchar *%s;\n", RESULT);
44912798Swpaul
450149709Sstefanf		f_print(fout, "\txdrproc_t xdr_%s, xdr_%s;\n", ARG, RESULT);
451149709Sstefanf		if (mtflag)
45212798Swpaul			f_print(fout,
453149709Sstefanf				"\tbool_t (*%s)(char *, void *, struct svc_req *);\n",
454149709Sstefanf				ROUTINE);
455149709Sstefanf		else
456149709Sstefanf			f_print(fout,
457149709Sstefanf				"\tchar *(*%s)(char *, struct svc_req *);\n",
458149709Sstefanf				ROUTINE);
4591897Swollman		f_print(fout, "\n");
46012798Swpaul
46112798Swpaul		if (timerflag) {
46212798Swpaul			if (mtflag)
463171932Sdelphij				f_print(fout, "\tpthread_mutex_lock(&_svcstate_lock);\n");
46412798Swpaul
46512798Swpaul			f_print(fout, "\t_rpcsvcstate = _SERVING;\n");
46612798Swpaul			if (mtflag)
467171932Sdelphij				f_print(fout, "\tpthread_mutex_unlock(&_svcstate_lock);\n");
46812798Swpaul		}
46912798Swpaul
4701897Swollman		f_print(fout, "\tswitch (%s->rq_proc) {\n", RQSTP);
4711897Swollman		if (!nullproc(vp->procs)) {
4721897Swollman			f_print(fout, "\tcase NULLPROC:\n");
47312798Swpaul			f_print(fout,
474149709Sstefanf				"\t\t(void) svc_sendreply(%s,\n\t\t\t"
475149709Sstefanf				"(xdrproc_t) xdr_void, (char *)NULL);\n",
47612798Swpaul				TRANSP);
47712798Swpaul			print_return("\t\t");
47812798Swpaul			f_print(fout, "\n");
4791897Swollman		}
4801897Swollman		for (proc = vp->procs; proc != NULL; proc = proc->next) {
4811897Swollman			f_print(fout, "\tcase %s:\n", proc->proc_name);
48212798Swpaul			if (proc->arg_num < 2) { /* single argument */
48312798Swpaul				p_xdrfunc(ARG, proc->args.decls->decl.type);
48412798Swpaul			} else {
48512798Swpaul				p_xdrfunc(ARG, proc->args.argname);
48612798Swpaul			}
48712798Swpaul			p_xdrfunc(RESULT, proc->res_type);
48812798Swpaul
489149709Sstefanf			if (mtflag)
490149709Sstefanf				f_print(fout,
491149709Sstefanf					"\t\t%s = (bool_t (*) (char *,  void *,  struct svc_req *))",
492149709Sstefanf					ROUTINE);
49312798Swpaul			else
494149709Sstefanf				f_print(fout,
495149709Sstefanf					"\t\t%s = (char *(*)(char *, struct svc_req *)) ",
496149709Sstefanf					ROUTINE);
49712798Swpaul			if (newstyle) { /* new style: calls internal routine */
49812798Swpaul				f_print(fout, "_");
49912798Swpaul			}
500149709Sstefanf			if (!newstyle)
50112798Swpaul				pvname_svc(proc->proc_name, vp->vers_num);
50212798Swpaul			else
50312798Swpaul				pvname(proc->proc_name, vp->vers_num);
5041897Swollman			f_print(fout, ";\n");
5051897Swollman			f_print(fout, "\t\tbreak;\n\n");
5061897Swollman		}
5071897Swollman		f_print(fout, "\tdefault:\n");
5081897Swollman		printerr("noproc", TRANSP);
50912798Swpaul		print_return("\t\t");
5101897Swollman		f_print(fout, "\t}\n");
5111897Swollman
51212798Swpaul		f_print(fout,
51312798Swpaul			"\t(void) memset((char *)&%s, 0, sizeof (%s));\n",
51412798Swpaul			ARG, ARG);
515149709Sstefanf		printif("getargs", TRANSP, "(caddr_t) &", ARG);
5161897Swollman		printerr("decode", TRANSP);
51712798Swpaul		print_return("\t\t");
5181897Swollman		f_print(fout, "\t}\n");
5191897Swollman
520100441Scharnier		if (!mtflag)
521149709Sstefanf			f_print(fout, "\t%s = (*%s)((char *)&%s, %s);\n",
522149709Sstefanf				RESULT, ROUTINE, ARG, RQSTP);
52312798Swpaul		else
524149709Sstefanf			f_print(fout, "\t%s = (bool_t) (*%s)((char *)&%s, (void *)&%s, %s);\n",
525149709Sstefanf				RETVAL, ROUTINE, ARG, RESULT, RQSTP);
52612798Swpaul
52712798Swpaul
52812798Swpaul		if (mtflag)
52912798Swpaul			f_print(fout,
53012798Swpaul				"\tif (%s > 0 && !svc_sendreply(%s, xdr_%s, (char *)&%s)) {\n",
53112798Swpaul				RETVAL, TRANSP, RESULT, RESULT);
53212798Swpaul		else
53312798Swpaul			f_print(fout,
53412798Swpaul				"\tif (%s != NULL && !svc_sendreply(%s, xdr_%s, %s)) {\n",
53512798Swpaul				RESULT, TRANSP, RESULT, RESULT);
53612798Swpaul
5371897Swollman		printerr("systemerr", TRANSP);
5381897Swollman		f_print(fout, "\t}\n");
5391897Swollman
540149709Sstefanf		printif("freeargs", TRANSP, "(caddr_t) &", ARG);
54112798Swpaul		(void) sprintf(_errbuf, "unable to free arguments");
54212798Swpaul		print_err_message("\t\t");
5431897Swollman		f_print(fout, "\t\texit(1);\n");
5441897Swollman		f_print(fout, "\t}\n");
54512798Swpaul		/* print out free routine */
54612798Swpaul		if (mtflag) {
54712798Swpaul			f_print(fout,"\tif (!");
54812798Swpaul			pvname(def->def_name, vp->vers_num);
54912798Swpaul			f_print(fout,"_freeresult(%s, xdr_%s, (caddr_t) &%s))\n",
55012798Swpaul				TRANSP, RESULT, RESULT);
55112798Swpaul			(void) sprintf(_errbuf, "unable to free results");
55212798Swpaul			print_err_message("\t\t");
55312798Swpaul			f_print(fout, "\n");
55412798Swpaul		};
55512798Swpaul		print_return("\t");
55612798Swpaul		f_print(fout, "}\n");
5571897Swollman	}
5581897Swollman}
5591897Swollman
56017142Sjkhstatic void
561152398Sdwmaloneprinterr(const char *err, const char *transp)
5621897Swollman{
5631897Swollman	f_print(fout, "\t\tsvcerr_%s(%s);\n", err, transp);
5641897Swollman}
5651897Swollman
56617142Sjkhstatic void
567152398Sdwmaloneprintif(const char *proc, const char *transp, const char *prefix,
568152398Sdwmalone    const char *arg)
5691897Swollman{
57074462Salfred	f_print(fout, "\tif (!svc_%s(%s, xdr_%s, (char *)%s%s)) {\n",
5711897Swollman		proc, transp, arg, prefix, arg);
5721897Swollman}
5731897Swollman
57417142Sjkhint
575152398Sdwmalonenullproc(proc_list *proc)
5761897Swollman{
5771897Swollman	for (; proc != NULL; proc = proc->next) {
5781897Swollman		if (streq(proc->proc_num, "0")) {
5791897Swollman			return (1);
5801897Swollman		}
5811897Swollman	}
5821897Swollman	return (0);
5831897Swollman}
58412798Swpaul
58517142Sjkhstatic void
586152398Sdwmalonewrite_inetmost(const char *infile)
58712798Swpaul{
58812798Swpaul	f_print(fout, "\tregister SVCXPRT *%s;\n", TRANSP);
58912798Swpaul	f_print(fout, "\tint sock;\n");
59012798Swpaul	f_print(fout, "\tint proto;\n");
59112798Swpaul	f_print(fout, "\tstruct sockaddr_in saddr;\n");
592149733Sstefanf	f_print(fout, "\tsocklen_t asize = sizeof (saddr);\n");
59312798Swpaul	f_print(fout, "\n");
59412798Swpaul	f_print(fout,
59512798Swpaul	"\tif (getsockname(0, (struct sockaddr *)&saddr, &asize) == 0) {\n");
596149733Sstefanf	f_print(fout, "\t\tsocklen_t ssize = sizeof (int);\n\n");
59712798Swpaul	f_print(fout, "\t\tif (saddr.sin_family != AF_INET)\n");
59812798Swpaul	f_print(fout, "\t\t\texit(1);\n");
59912798Swpaul	f_print(fout, "\t\tif (getsockopt(0, SOL_SOCKET, SO_TYPE,\n");
60012798Swpaul	f_print(fout, "\t\t\t\t(char *)&_rpcfdtype, &ssize) == -1)\n");
60112798Swpaul	f_print(fout, "\t\t\texit(1);\n");
60212798Swpaul	f_print(fout, "\t\tsock = 0;\n");
60312798Swpaul	f_print(fout, "\t\t_rpcpmstart = 1;\n");
60412798Swpaul	f_print(fout, "\t\tproto = 0;\n");
60512798Swpaul	open_log_file(infile, "\t\t");
60612798Swpaul	f_print(fout, "\t} else {\n");
60712798Swpaul	write_rpc_svc_fg(infile, "\t\t");
60812798Swpaul	f_print(fout, "\t\tsock = RPC_ANYSOCK;\n");
60912798Swpaul	print_pmapunset("\t\t");
61012798Swpaul	f_print(fout, "\t}\n");
61112798Swpaul}
61212798Swpaul
61317142Sjkhstatic void
614152398Sdwmaloneprint_return(const char *space)
61512798Swpaul{
61612798Swpaul	if (exitnow)
61712798Swpaul		f_print(fout, "%sexit(0);\n", space);
61812798Swpaul	else {
61912798Swpaul		if (timerflag) {
62012798Swpaul			if (mtflag)
621171932Sdelphij				f_print(fout, "%spthread_mutex_lock(&_svcstate_lock);\n", space);
62212798Swpaul				f_print(fout, "%s_rpcsvcstate = _SERVED;\n", space);
62312798Swpaul			if (mtflag)
624171932Sdelphij				f_print(fout, "%spthread_mutex_unlock(&_svcstate_lock);\n", space);
62512798Swpaul		}
62612798Swpaul		f_print(fout, "%sreturn;\n", space);
62712798Swpaul	}
62812798Swpaul}
62912798Swpaul
63017142Sjkhstatic void
631152398Sdwmaloneprint_pmapunset(const char *space)
63212798Swpaul{
63312798Swpaul	list *l;
63412798Swpaul	definition *def;
63512798Swpaul	version_list *vp;
63612798Swpaul
63712798Swpaul	for (l = defined; l != NULL; l = l->next) {
63812798Swpaul		def = (definition *) l->val;
63912798Swpaul		if (def->def_kind == DEF_PROGRAM) {
64012798Swpaul			for (vp = def->def.pr.versions; vp != NULL;
64112798Swpaul					vp = vp->next) {
64212798Swpaul				f_print(fout, "%s(void) pmap_unset(%s, %s);\n",
64312798Swpaul					space, def->def_name, vp->vers_name);
64412798Swpaul			}
64512798Swpaul		}
64612798Swpaul	}
64712798Swpaul}
64812798Swpaul
64917142Sjkhstatic void
650152398Sdwmaloneprint_err_message(const char *space)
65112798Swpaul{
65212798Swpaul	if (logflag)
65312798Swpaul		f_print(fout, "%ssyslog(LOG_ERR, \"%s\");\n", space, _errbuf);
65412798Swpaul	else if (inetdflag || pmflag)
65512798Swpaul		f_print(fout, "%s_msgout(\"%s\");\n", space, _errbuf);
65612798Swpaul	else
65712798Swpaul		f_print(fout, "%sfprintf(stderr, \"%s\");\n", space, _errbuf);
65812798Swpaul}
65912798Swpaul
66012798Swpaul/*
66112798Swpaul * Write the server auxiliary function (_msgout, timeout)
66212798Swpaul */
66312798Swpaulvoid
664152398Sdwmalonewrite_svc_aux(int nomain)
66512798Swpaul{
66612798Swpaul	if (!logflag)
66712798Swpaul		write_msg_out();
66812798Swpaul	if (!nomain)
66912798Swpaul		write_timeout_func();
67012798Swpaul}
67112798Swpaul
67212798Swpaul/*
67312798Swpaul * Write the _msgout function
67412798Swpaul */
67512798Swpaul
67617142Sjkhstatic void
67717142Sjkhwrite_msg_out(void)
67812798Swpaul{
67912798Swpaul	f_print(fout, "\n");
68012798Swpaul/*
68112798Swpaul * Avoid making _msgout() static -- it's useful to have it visible
68212798Swpaul * in the toplevel RPC server code.
68312798Swpaul */
68412798Swpaul	f_print(fout, "static\n");
685149709Sstefanf	f_print(fout, "void _msgout(const char* msg)\n");
68612798Swpaul	f_print(fout, "{\n");
68712798Swpaul	f_print(fout, "#ifdef RPC_SVC_FG\n");
68812798Swpaul	if (inetdflag || pmflag)
68912798Swpaul		f_print(fout, "\tif (_rpcpmstart)\n");
69079295Skris	f_print(fout, "\t\tsyslog(LOG_ERR, \"%%s\", msg);\n");
69112798Swpaul	f_print(fout, "\telse\n");
69212798Swpaul	f_print(fout,
69312798Swpaul		"\t\t(void) fprintf(stderr, \"%%s\\n\", msg);\n");
69412798Swpaul	f_print(fout, "#else\n");
69579295Skris	f_print(fout, "\tsyslog(LOG_ERR, \"%%s\", msg);\n");
69612798Swpaul	f_print(fout, "#endif\n");
69712798Swpaul	f_print(fout, "}\n");
69812798Swpaul}
69912798Swpaul
70012798Swpaul/*
70112798Swpaul * Write the timeout function
70212798Swpaul */
70317142Sjkhstatic void
70417142Sjkhwrite_timeout_func(void)
70512798Swpaul{
70612798Swpaul	if (!timerflag)
70712798Swpaul		return;
70812798Swpaul
70912798Swpaul	f_print(fout, "\n");
71012798Swpaul	f_print(fout, "static void\n");
711149709Sstefanf	f_print(fout, "closedown(int sig)\n");
71212798Swpaul	f_print(fout, "{\n");
71312798Swpaul	if (mtflag)
714171932Sdelphij		f_print(fout, "\tpthread_mutex_lock(&_svcstate_lock);\n");
71512798Swpaul	f_print(fout, "\tif (_rpcsvcstate == _IDLE) {\n");
71612798Swpaul	f_print(fout, "\t\textern fd_set svc_fdset;\n");
71712798Swpaul	f_print(fout, "\t\tstatic int size;\n");
71812798Swpaul	f_print(fout, "\t\tint i, openfd;\n");
71912798Swpaul	if (tirpcflag && pmflag) {
72012798Swpaul		f_print(fout, "\t\tstruct t_info tinfo;\n\n");
72112798Swpaul		f_print(fout,
72212798Swpaul			"\t\tif (!t_getinfo(0, &tinfo) && (tinfo.servtype == T_CLTS))\n");
72312798Swpaul	} else {
72412798Swpaul		f_print(fout, "\n\t\tif (_rpcfdtype == SOCK_DGRAM)\n");
72512798Swpaul	}
72612798Swpaul	f_print(fout, "\t\t\texit(0);\n");
72712798Swpaul	f_print(fout, "\t\tif (size == 0) {\n");
72812798Swpaul	if (tirpcflag) {
72912798Swpaul		f_print(fout, "\t\t\tstruct rlimit rl;\n\n");
73012798Swpaul		f_print(fout, "\t\t\trl.rlim_max = 0;\n");
73112798Swpaul		f_print(fout, "\t\t\tgetrlimit(RLIMIT_NOFILE, &rl);\n");
73212798Swpaul		f_print(fout, "\t\t\tif ((size = rl.rlim_max) == 0) {\n");
73312798Swpaul
73412798Swpaul		if (mtflag)
735171932Sdelphij			f_print(fout, "\t\t\t\tpthread_mutex_unlock(&_svcstate_lock);\n");
73612798Swpaul
73712798Swpaul		f_print(fout, "\t\t\t\treturn;\n\t\t\t}\n");
73812798Swpaul	} else {
73912798Swpaul		f_print(fout, "\t\t\tsize = getdtablesize();\n");
74012798Swpaul	}
74112798Swpaul	f_print(fout, "\t\t}\n");
74212798Swpaul	f_print(fout,
74312798Swpaul		"\t\tfor (i = 0, openfd = 0; i < size && openfd < 2; i++)\n");
74412798Swpaul	f_print(fout, "\t\t\tif (FD_ISSET(i, &svc_fdset))\n");
74512798Swpaul	f_print(fout, "\t\t\t\topenfd++;\n");
74612798Swpaul	f_print(fout, "\t\tif (openfd <= 1)\n");
74712798Swpaul	f_print(fout, "\t\t\texit(0);\n");
74812798Swpaul	f_print(fout, "\t}\n");
74912798Swpaul	f_print(fout, "\tif (_rpcsvcstate == _SERVED)\n");
75012798Swpaul	f_print(fout, "\t\t_rpcsvcstate = _IDLE;\n\n");
75112798Swpaul	if (mtflag)
752171932Sdelphij		f_print(fout, "\tpthread_mutex_unlock(&_svcstate_lock);\n");
75312798Swpaul
754149709Sstefanf	f_print(fout, "\t(void) signal(SIGALRM, closedown);\n");
75512798Swpaul	f_print(fout, "\t(void) alarm(_RPCSVC_CLOSEDOWN/2);\n");
75612798Swpaul	f_print(fout, "}\n");
75712798Swpaul
75812798Swpaul}
75912798Swpaul
76012798Swpaul/*
76112798Swpaul * Write the most of port monitor support
76212798Swpaul */
76317142Sjkhstatic void
764152398Sdwmalonewrite_pm_most(const char *infile, int netflag)
76512798Swpaul{
76612798Swpaul	list *l;
76712798Swpaul	definition *def;
76812798Swpaul	version_list *vp;
76912798Swpaul
77099979Salfred	if (tirpc_socket) {
77199979Salfred		f_print(fout,
77299979Salfred		"\tif (getsockname(0, (struct sockaddr *)&saddr, &asize) == 0) {\n");
773149733Sstefanf		f_print(fout, "\t\tsocklen_t ssize = sizeof (int);\n");
77499979Salfred	} else {
77599979Salfred		f_print(fout, "\tif (!ioctl(0, I_LOOK, mname) &&\n");
77699979Salfred		f_print(fout, "\t\t(!strcmp(mname, \"sockmod\") ||");
77799979Salfred		f_print(fout, " !strcmp(mname, \"timod\"))) {\n");
77899979Salfred	}
77912798Swpaul	f_print(fout, "\t\tchar *netid;\n");
78012798Swpaul	if (!netflag) {	/* Not included by -n option */
78112798Swpaul		f_print(fout, "\t\tstruct netconfig *nconf = NULL;\n");
78212798Swpaul		f_print(fout, "\t\tSVCXPRT *%s;\n", TRANSP);
78312798Swpaul	}
78412798Swpaul	if (timerflag)
78512798Swpaul		f_print(fout, "\t\tint pmclose;\n");
78612798Swpaul/*
78712798Swpaul *  Not necessary, defined in /usr/include/stdlib
78812798Swpaul *  f_print(fout, "\t\textern char *getenv();\n");
78912798Swpaul */
79012798Swpaul	f_print(fout, "\n");
79199979Salfred	if (tirpc_socket) {
79299979Salfred		f_print(fout, "\t\tif (saddr.ss_family != AF_INET &&\n");
79399979Salfred		f_print(fout, "\t\t    saddr.ss_family != AF_INET6)\n");
79499979Salfred		f_print(fout, "\t\t\texit(1);\n");
79599979Salfred		f_print(fout, "\t\tif (getsockopt(0, SOL_SOCKET, SO_TYPE,\n");
79699979Salfred		f_print(fout, "\t\t\t\t(char *)&_rpcfdtype, &ssize) == -1)\n");
79799979Salfred		f_print(fout, "\t\t\texit(1);\n");
79899979Salfred	}
79912798Swpaul	f_print(fout, "\t\t_rpcpmstart = 1;\n");
80012798Swpaul	open_log_file(infile, "\t\t");
80112798Swpaul	f_print(fout, "\n\t\tif ((netid = \
80212798Swpaulgetenv(\"NLSPROVIDER\")) == NULL) {\n");
80312798Swpaul
80412798Swpaul	if (timerflag) {
80512798Swpaul		f_print(fout, "\t\t/* started from inetd */\n");
80612798Swpaul		f_print(fout, "\t\t\tpmclose = 1;\n");
80712798Swpaul	}
80812798Swpaul	f_print(fout,
80912798Swpaul		"\t\t} else {\n");
81012798Swpaul	f_print(fout, "\t\t\tif ((nconf = getnetconfigent(netid)) == NULL)\n");
81112798Swpaul	sprintf(_errbuf, "cannot get transport info");
81212798Swpaul	print_err_message("\t\t\t\t");
81399979Salfred       if (timerflag) {
81499979Salfred		if (tirpc_socket)
81599979Salfred			f_print(fout, "\n\t\t\tpmclose = 1;\t/* XXX */\n");
81699979Salfred		else
81799979Salfred			f_print(fout,
81899979Salfred			    "\n\t\t\tpmclose = (t_getstate(0) != T_DATAXFER);\n");
81999979Salfred	}
82012798Swpaul	f_print(fout, "\t\t}\n");
82112798Swpaul	/*
82212798Swpaul	 * A kludgy support for inetd services. Inetd only works with
82312798Swpaul	 * sockmod, and RPC works only with timod, hence all this jugglery
82412798Swpaul	 */
82599979Salfred	if (!tirpc_socket) {
82699979Salfred		f_print(fout, "\t\tif (strcmp(mname, \"sockmod\") == 0) {\n");
82799979Salfred		f_print(fout, "\t\t\tif (ioctl(0, I_POP, 0) || ");
82899979Salfred		f_print(fout, "ioctl(0, I_PUSH, \"timod\")) {\n");
82999979Salfred		sprintf(_errbuf, "could not get the right module");
83099979Salfred		print_err_message("\t\t\t\t");
83199979Salfred		f_print(fout, "\t\t\t\texit(1);\n");
83299979Salfred		f_print(fout, "\t\t\t}\n");
83399979Salfred		f_print(fout, "\t\t}\n");
83499979Salfred	}
835109363Smbr	if (tirpcflag) {
836109363Smbr		f_print(fout,
837109363Smbr		"\t\tif ((%s = svc_tli_create(0, nconf, NULL, \
838109363Smbr		RPC_MAXDATASIZE, RPC_MAXDATASIZE)) \
839109363Smbr		== NULL) {\n",
84012798Swpaul		TRANSP);
841109363Smbr	} else {
842109363Smbr		f_print(fout,
843109363Smbr		    "\t\tif ((%s = svc_tli_create(0, nconf, NULL, 0, 0)) \
844109363Smbr		    == NULL) {\n",
845109363Smbr                    TRANSP);
846109363Smbr	}
84712798Swpaul	sprintf(_errbuf, "cannot create server handle");
84812798Swpaul	print_err_message("\t\t\t");
84912798Swpaul	f_print(fout, "\t\t\texit(1);\n");
85012798Swpaul	f_print(fout, "\t\t}\n");
85112798Swpaul	f_print(fout, "\t\tif (nconf)\n");
85212798Swpaul	f_print(fout, "\t\t\tfreenetconfigent(nconf);\n");
85312798Swpaul	for (l = defined; l != NULL; l = l->next) {
85412798Swpaul		def = (definition *) l->val;
85512798Swpaul		if (def->def_kind != DEF_PROGRAM) {
85612798Swpaul			continue;
85712798Swpaul		}
85812798Swpaul		for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
85912798Swpaul			f_print(fout,
86012798Swpaul				"\t\tif (!svc_reg(%s, %s, %s, ",
86112798Swpaul				TRANSP, def->def_name, vp->vers_name);
86212798Swpaul			pvname(def->def_name, vp->vers_num);
86312798Swpaul			f_print(fout, ", 0)) {\n");
86412798Swpaul			(void) sprintf(_errbuf, "unable to register (%s, %s).",
86512798Swpaul					def->def_name, vp->vers_name);
86612798Swpaul			print_err_message("\t\t\t");
86712798Swpaul			f_print(fout, "\t\t\texit(1);\n");
86812798Swpaul			f_print(fout, "\t\t}\n");
86912798Swpaul		}
87012798Swpaul	}
87112798Swpaul	if (timerflag) {
87212798Swpaul		f_print(fout, "\t\tif (pmclose) {\n");
873149709Sstefanf		f_print(fout, "\t\t\t(void) signal(SIGALRM, closedown);\n");
87412798Swpaul		f_print(fout, "\t\t\t(void) alarm(_RPCSVC_CLOSEDOWN/2);\n");
87512798Swpaul		f_print(fout, "\t\t}\n");
87612798Swpaul	}
87712798Swpaul	f_print(fout, "\t\tsvc_run();\n");
87812798Swpaul	f_print(fout, "\t\texit(1);\n");
87912798Swpaul	f_print(fout, "\t\t/* NOTREACHED */\n");
88012798Swpaul	f_print(fout, "\t}");
88112798Swpaul}
88212798Swpaul
88312798Swpaul/*
88412798Swpaul * Support for backgrounding the server if self started.
88512798Swpaul */
88617142Sjkhstatic void
887152398Sdwmalonewrite_rpc_svc_fg(const char *infile, const char *sp)
88812798Swpaul{
88912798Swpaul	f_print(fout, "#ifndef RPC_SVC_FG\n");
89012798Swpaul	f_print(fout, "%sint size;\n", sp);
89112798Swpaul	if (tirpcflag)
89212798Swpaul		f_print(fout, "%sstruct rlimit rl;\n", sp);
89312798Swpaul	if (inetdflag)
89412798Swpaul		f_print(fout, "%sint pid, i;\n\n", sp);
89512798Swpaul	f_print(fout, "%spid = fork();\n", sp);
89612798Swpaul	f_print(fout, "%sif (pid < 0) {\n", sp);
89712798Swpaul	f_print(fout, "%s\tperror(\"cannot fork\");\n", sp);
89812798Swpaul	f_print(fout, "%s\texit(1);\n", sp);
89912798Swpaul	f_print(fout, "%s}\n", sp);
90012798Swpaul	f_print(fout, "%sif (pid)\n", sp);
90112798Swpaul	f_print(fout, "%s\texit(0);\n", sp);
90212798Swpaul	/* get number of file descriptors */
90312798Swpaul	if (tirpcflag) {
90412798Swpaul		f_print(fout, "%srl.rlim_max = 0;\n", sp);
90512798Swpaul		f_print(fout, "%sgetrlimit(RLIMIT_NOFILE, &rl);\n", sp);
90612798Swpaul		f_print(fout, "%sif ((size = rl.rlim_max) == 0)\n", sp);
90712798Swpaul		f_print(fout, "%s\texit(1);\n", sp);
90812798Swpaul	} else {
90912798Swpaul		f_print(fout, "%ssize = getdtablesize();\n", sp);
91012798Swpaul	}
91112798Swpaul
91212798Swpaul	f_print(fout, "%sfor (i = 0; i < size; i++)\n", sp);
91312798Swpaul	f_print(fout, "%s\t(void) close(i);\n", sp);
91412798Swpaul	/* Redirect stderr and stdout to console */
91512798Swpaul	f_print(fout, "%si = open(\"/dev/console\", 2);\n", sp);
91612798Swpaul	f_print(fout, "%s(void) dup2(i, 1);\n", sp);
91712798Swpaul	f_print(fout, "%s(void) dup2(i, 2);\n", sp);
91812798Swpaul	/* This removes control of the controlling terminal */
91912798Swpaul	if (tirpcflag)
92012798Swpaul		f_print(fout, "%ssetsid();\n", sp);
92112798Swpaul	else {
92212798Swpaul		f_print(fout, "%si = open(\"/dev/tty\", 2);\n", sp);
92312798Swpaul		f_print(fout, "%sif (i >= 0) {\n", sp);
92412798Swpaul		f_print(fout,
92512798Swpaul			"%s\t(void) ioctl(i, TIOCNOTTY, (char *)NULL);\n", sp);
92612798Swpaul		f_print(fout, "%s\t(void) close(i);\n", sp);
92712798Swpaul		f_print(fout, "%s}\n", sp);
92812798Swpaul	}
92912798Swpaul	if (!logflag)
93012798Swpaul		open_log_file(infile, sp);
93112798Swpaul	f_print(fout, "#endif\n");
93212798Swpaul	if (logflag)
93312798Swpaul		open_log_file(infile, sp);
93412798Swpaul}
93512798Swpaul
93617142Sjkhstatic void
937152398Sdwmaloneopen_log_file(const char *infile, const char *sp)
93812798Swpaul{
93912798Swpaul	char *s;
94012798Swpaul
94112798Swpaul	s = strrchr(infile, '.');
94212798Swpaul	if (s)
94312798Swpaul		*s = '\0';
94412798Swpaul	f_print(fout, "%sopenlog(\"%s\", LOG_PID, LOG_DAEMON);\n", sp, infile);
94512798Swpaul	if (s)
94612798Swpaul		*s = '.';
94712798Swpaul}
94812798Swpaul
94912798Swpaul
95012798Swpaul
95112798Swpaul
95212798Swpaul/*
95312798Swpaul * write a registration for the given transport for Inetd
95412798Swpaul */
95512798Swpaulvoid
956152398Sdwmalonewrite_inetd_register(const char *transp)
95712798Swpaul{
95812798Swpaul	list *l;
95912798Swpaul	definition *def;
96012798Swpaul	version_list *vp;
961152398Sdwmalone	const char *sp;
96212798Swpaul	int isudp;
96312798Swpaul	char tmpbuf[32];
96412798Swpaul
96512798Swpaul	if (inetdflag)
96612798Swpaul		sp = "\t";
96712798Swpaul	else
96812798Swpaul		sp = "";
96912798Swpaul	if (streq(transp, "udp"))
97012798Swpaul		isudp = 1;
97112798Swpaul	else
97212798Swpaul		isudp = 0;
97312798Swpaul	f_print(fout, "\n");
97412798Swpaul	if (inetdflag) {
97512798Swpaul		f_print(fout,
97612798Swpaul			"\tif ((_rpcfdtype == 0) || (_rpcfdtype == %s)) {\n",
97712798Swpaul			isudp ? "SOCK_DGRAM" : "SOCK_STREAM");
97812798Swpaul	}
97912798Swpaul	f_print(fout, "%s\t%s = svc%s_create(%s",
98012798Swpaul		sp, TRANSP, transp, inetdflag? "sock": "RPC_ANYSOCK");
98112798Swpaul	if (!isudp)
98212798Swpaul		f_print(fout, ", 0, 0");
98312798Swpaul	f_print(fout, ");\n");
98412798Swpaul	f_print(fout, "%s\tif (%s == NULL) {\n", sp, TRANSP);
98512798Swpaul	(void) sprintf(_errbuf, "cannot create %s service.", transp);
98612798Swpaul	(void) sprintf(tmpbuf, "%s\t\t", sp);
98712798Swpaul	print_err_message(tmpbuf);
98812798Swpaul	f_print(fout, "%s\t\texit(1);\n", sp);
98912798Swpaul	f_print(fout, "%s\t}\n", sp);
99012798Swpaul
99112798Swpaul	if (inetdflag) {
99212798Swpaul		f_print(fout, "%s\tif (!_rpcpmstart)\n\t", sp);
99312798Swpaul		f_print(fout, "%s\tproto = IPPROTO_%s;\n",
99412798Swpaul				sp, isudp ? "UDP": "TCP");
99512798Swpaul	}
99612798Swpaul	for (l = defined; l != NULL; l = l->next) {
99712798Swpaul		def = (definition *) l->val;
99812798Swpaul		if (def->def_kind != DEF_PROGRAM) {
99912798Swpaul			continue;
100012798Swpaul		}
100112798Swpaul		for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
100212798Swpaul			f_print(fout, "%s\tif (!svc_register(%s, %s, %s, ",
100312798Swpaul				sp, TRANSP, def->def_name, vp->vers_name);
100412798Swpaul			pvname(def->def_name, vp->vers_num);
100512798Swpaul			if (inetdflag)
100612798Swpaul				f_print(fout, ", proto)) {\n");
100712798Swpaul			else
100812798Swpaul				f_print(fout, ", IPPROTO_%s)) {\n",
100912798Swpaul					isudp ? "UDP": "TCP");
101012798Swpaul			(void) sprintf(_errbuf,
101112798Swpaul				"unable to register (%s, %s, %s).",
101212798Swpaul				def->def_name, vp->vers_name, transp);
101312798Swpaul			print_err_message(tmpbuf);
101412798Swpaul			f_print(fout, "%s\t\texit(1);\n", sp);
101512798Swpaul			f_print(fout, "%s\t}\n", sp);
101612798Swpaul		}
101712798Swpaul	}
101812798Swpaul	if (inetdflag)
101912798Swpaul		f_print(fout, "\t}\n");
102012798Swpaul}
1021