rpc_svcout.c revision 149709
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 149709 2005-09-02 10:23:26Z stefanf $");
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
5099979Salfredextern int tirpc_socket;
5199979Salfred
521897Swollmanstatic char RQSTP[] = "rqstp";
531897Swollmanstatic char TRANSP[] = "transp";
541897Swollmanstatic char ARG[] = "argument";
551897Swollmanstatic char RESULT[] = "result";
561897Swollmanstatic char ROUTINE[] = "local";
5712798Swpaulstatic char RETVAL[] = "retval";
581897Swollman
5912798Swpaulchar _errbuf[256];	/* For all messages */
6012798Swpaul
6192921Simpvoid internal_proctype( proc_list * );
6292921Simpstatic void write_real_program( definition * );
6392921Simpstatic void write_program( definition *, char * );
6492921Simpstatic void printerr( char *, char * );
6592921Simpstatic void printif( char *, char *, char *, char * );
6692921Simpstatic void write_inetmost( char * );
6792921Simpstatic void print_return( char * );
6892921Simpstatic void print_pmapunset( char * );
6992921Simpstatic void print_err_message( char * );
7092921Simpstatic void write_timeout_func( void );
7192921Simpstatic void write_pm_most( char *, int );
7292921Simpstatic void write_rpc_svc_fg( char *, char * );
7392921Simpstatic void open_log_file( char *, char * );
7492921Simpstatic void write_msg_out( void );
7592921Simpint nullproc( proc_list * );
7612798Swpaul
7712798Swpaul
7817142Sjkhstatic void
7912798Swpaulp_xdrfunc(rname, typename)
8012798Swpaulchar* rname;
8112798Swpaulchar* typename;
8212798Swpaul{
83149709Sstefanf	f_print(fout, "\t\txdr_%s = (xdrproc_t) xdr_%s;\n",
84149709Sstefanf	    rname, stringfix(typename));
8512798Swpaul}
8612798Swpaul
8712798Swpaulvoid
8812798Swpaulinternal_proctype(plist)
8912798Swpaul	proc_list *plist;
9012798Swpaul{
9112798Swpaul	f_print(fout, "static ");
9212798Swpaul	ptype(plist->res_prefix, plist->res_type, 1);
9312798Swpaul	f_print(fout, "*");
9412798Swpaul}
9512798Swpaul
9612798Swpaul
971897Swollman/*
988874Srgrimes * write most of the service, that is, everything but the registrations.
991897Swollman */
1001897Swollmanvoid
10112798Swpaulwrite_most(infile, netflag, nomain)
10212798Swpaul	char *infile;		/* our name */
10312798Swpaul	int netflag;
10412798Swpaul	int nomain;
1051897Swollman{
10612798Swpaul	if (inetdflag || pmflag) {
10712798Swpaul		char* var_type;
10812798Swpaul		var_type = (nomain? "extern" : "static");
10912798Swpaul		f_print(fout, "%s int _rpcpmstart;", var_type);
11012798Swpaul		f_print(fout, "\t\t/* Started by a port monitor ? */\n");
11199979Salfred		if (!tirpcflag || tirpc_socket) {
11212798Swpaul			f_print(fout, "%s int _rpcfdtype;", var_type);
11312798Swpaul			f_print(fout, "\n\t\t /* Whether Stream or \
11412798SwpaulDatagram ? */\n");
11512798Swpaul		}
1161897Swollman
11712798Swpaul		if (timerflag) {
11812798Swpaul			f_print(fout, "	/* States a server can be in \
11912798Swpaulwrt request */\n\n");
12012798Swpaul			f_print(fout, "#define\t_IDLE 0\n");
12112798Swpaul			f_print(fout, "#define\t_SERVED 1\n");
12212798Swpaul			f_print(fout, "#define\t_SERVING 2\n\n");
12312798Swpaul			f_print(fout, "static int _rpcsvcstate = _IDLE;");
12412798Swpaul			f_print(fout, "\t /* Set when a request is \
12512798Swpaulserviced */\n");
12612798Swpaul
12712798Swpaul			if (mtflag) {
12812798Swpaul				f_print(fout, "mutex_t _svcstate_lock;");
12912798Swpaul				f_print(fout, "\t\t\t/* Mutex lock for variable _rpcsvcstate */\n");
13012798Swpaul
1311897Swollman			}
13212798Swpaul
1331897Swollman		}
13412798Swpaul
13512798Swpaul		write_svc_aux(nomain);
1361897Swollman	}
13712798Swpaul	/* write out dispatcher and stubs */
13812798Swpaul	write_programs(nomain? (char *)NULL : "static");
13912798Swpaul
14012798Swpaul	if (nomain)
14112798Swpaul		return;
14212798Swpaul
14399979Salfred	f_print(fout, "\nint\n");
14499979Salfred	f_print(fout, "main()\n");
1451897Swollman	f_print(fout, "{\n");
146109363Smbr		if (tirpcflag) {
147109363Smbr			if (!inetdflag)
148109363Smbr				f_print(fout, "\t");
149109363Smbr			f_print(fout, "\tint maxrec = RPC_MAXDATASIZE;\n");
150109363Smbr		}
15112798Swpaul	if (inetdflag) {
15212798Swpaul		write_inetmost(infile);
15312798Swpaul		/* Includes call to write_rpc_svc_fg() */
15412798Swpaul	} else {
15512798Swpaul		if (tirpcflag) {
15612798Swpaul			if (netflag) {
15712798Swpaul				f_print(fout,
15812798Swpaul					"\tregister SVCXPRT *%s;\n", TRANSP);
15912798Swpaul				f_print(fout,
16012798Swpaul					"\tstruct netconfig *nconf = NULL;\n");
16112798Swpaul			}
16212798Swpaul			f_print(fout, "\tpid_t pid;\n");
16312798Swpaul			f_print(fout, "\tint i;\n");
16499979Salfred			if (pmflag) {
16599979Salfred				if (tirpc_socket) {
16699979Salfred					f_print(fout, "\tstruct sockaddr_storage saddr;\n");
16799979Salfred					f_print(fout, "\tint asize = sizeof (saddr);\n\n");
16899979Salfred				} else
16999979Salfred					f_print(fout, "\tchar mname[FMNAMESZ + 1];\n\n");
17099979Salfred			}
17112798Swpaul
17212798Swpaul			if (mtflag & timerflag)
17312798Swpaul				f_print(fout, "\tmutex_init(&_svcstate_lock, USYNC_THREAD, NULL);\n");
17499979Salfred			if (pmflag) {
17599979Salfred				write_pm_most(infile, netflag);
17699979Salfred				f_print(fout, "\telse {\n");
17799979Salfred				write_rpc_svc_fg(infile, "\t\t");
17899979Salfred				f_print(fout, "\t}\n");
179100441Scharnier			} else
18099979Salfred				write_rpc_svc_fg(infile, "\t\t");
18112798Swpaul
18212798Swpaul		} else {
18312798Swpaul			f_print(fout, "\tregister SVCXPRT *%s;\n", TRANSP);
18412798Swpaul			f_print(fout, "\n");
18512798Swpaul			print_pmapunset("\t");
18612798Swpaul		}
18712798Swpaul	}
18812798Swpaul
18912798Swpaul	if (logflag && !inetdflag) {
19012798Swpaul		open_log_file(infile, "\t");
19112798Swpaul	}
19212798Swpaul}
19312798Swpaul
19412798Swpaul/*
19512798Swpaul * write a registration for the given transport
19612798Swpaul */
19712798Swpaulvoid
19812798Swpaulwrite_netid_register(transp)
19912798Swpaul	char *transp;
20012798Swpaul{
20112798Swpaul	list *l;
20212798Swpaul	definition *def;
20312798Swpaul	version_list *vp;
20412798Swpaul	char *sp;
20512798Swpaul	char tmpbuf[32];
20612798Swpaul
20712798Swpaul	sp = "";
2081897Swollman	f_print(fout, "\n");
20912798Swpaul	f_print(fout, "%s\tnconf = getnetconfigent(\"%s\");\n", sp, transp);
21012798Swpaul	f_print(fout, "%s\tif (nconf == NULL) {\n", sp);
21112798Swpaul	(void) sprintf(_errbuf, "cannot find %s netid.", transp);
21212798Swpaul	sprintf(tmpbuf, "%s\t\t", sp);
21312798Swpaul	print_err_message(tmpbuf);
21412798Swpaul	f_print(fout, "%s\t\texit(1);\n", sp);
21512798Swpaul	f_print(fout, "%s\t}\n", sp);
216109363Smbr	if (tirpcflag) {
217109363Smbr		f_print(fout, "%s\t%s = svc_tli_create(RPC_ANYFD, ",
218109363Smbr		    sp, TRANSP);
219109363Smbr		f_print(fout,"nconf, 0, RPC_MAXDATASIZE, RPC_MAXDATASIZE);\n");
220109363Smbr	} else {
221109363Smbr		f_print(fout,
222109363Smbr		    "%s\t%s = svc_tli_create(RPC_ANYFD, nconf, 0, 0, 0);\n",
223109363Smbr		    sp, TRANSP);
224109363Smbr	}
22512798Swpaul	f_print(fout, "%s\tif (%s == NULL) {\n", sp, TRANSP);
22612798Swpaul	(void) sprintf(_errbuf, "cannot create %s service.", transp);
22712798Swpaul	print_err_message(tmpbuf);
22812798Swpaul	f_print(fout, "%s\t\texit(1);\n", sp);
22912798Swpaul	f_print(fout, "%s\t}\n", sp);
23012798Swpaul
2311897Swollman	for (l = defined; l != NULL; l = l->next) {
2321897Swollman		def = (definition *) l->val;
2331897Swollman		if (def->def_kind != DEF_PROGRAM) {
2341897Swollman			continue;
2351897Swollman		}
2361897Swollman		for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
23712798Swpaul			f_print(fout,
23812798Swpaul				"%s\t(void) rpcb_unset(%s, %s, nconf);\n",
23912798Swpaul				sp, def->def_name, vp->vers_name);
24012798Swpaul			f_print(fout,
24112798Swpaul				"%s\tif (!svc_reg(%s, %s, %s, ",
24212798Swpaul				sp, TRANSP, def->def_name, vp->vers_name);
24312798Swpaul			pvname(def->def_name, vp->vers_num);
24412798Swpaul			f_print(fout, ", nconf)) {\n");
24512798Swpaul			(void) sprintf(_errbuf,
24612798Swpaul				"unable to register (%s, %s, %s).",
24712798Swpaul				def->def_name, vp->vers_name, transp);
24812798Swpaul			print_err_message(tmpbuf);
24912798Swpaul			f_print(fout, "%s\t\texit(1);\n", sp);
25012798Swpaul			f_print(fout, "%s\t}\n", sp);
2511897Swollman		}
2521897Swollman	}
25312798Swpaul	f_print(fout, "%s\tfreenetconfigent(nconf);\n", sp);
2541897Swollman}
2551897Swollman
2561897Swollman/*
25712798Swpaul * write a registration for the given transport for TLI
2581897Swollman */
2591897Swollmanvoid
26012798Swpaulwrite_nettype_register(transp)
2611897Swollman	char *transp;
2621897Swollman{
2631897Swollman	list *l;
2641897Swollman	definition *def;
2651897Swollman	version_list *vp;
2661897Swollman
2671897Swollman	for (l = defined; l != NULL; l = l->next) {
2681897Swollman		def = (definition *) l->val;
2691897Swollman		if (def->def_kind != DEF_PROGRAM) {
2701897Swollman			continue;
2711897Swollman		}
272109363Smbr		if (tirpcflag) {
273109363Smbr			f_print(fout,
274109363Smbr			"\trpc_control(RPC_SVC_CONNMAXREC_SET, &maxrec);\n");
275109363Smbr		}
2761897Swollman		for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
27712798Swpaul			f_print(fout, "\tif (!svc_create(");
2781897Swollman			pvname(def->def_name, vp->vers_num);
27912798Swpaul			f_print(fout, ", %s, %s, \"%s\")) {\n",
2801897Swollman				def->def_name, vp->vers_name, transp);
28112798Swpaul			(void) sprintf(_errbuf,
28212798Swpaul				"unable to create (%s, %s) for %s.",
28312798Swpaul					def->def_name, vp->vers_name, transp);
28412798Swpaul			print_err_message("\t\t");
2851897Swollman			f_print(fout, "\t\texit(1);\n");
2861897Swollman			f_print(fout, "\t}\n");
2871897Swollman		}
2881897Swollman	}
2891897Swollman}
2901897Swollman
2911897Swollman/*
2928874Srgrimes * write the rest of the service
2931897Swollman */
2941897Swollmanvoid
2951897Swollmanwrite_rest()
2961897Swollman{
29712798Swpaul	f_print(fout, "\n");
29812798Swpaul	if (inetdflag) {
29912798Swpaul		f_print(fout, "\tif (%s == (SVCXPRT *)NULL) {\n", TRANSP);
30012798Swpaul		(void) sprintf(_errbuf, "could not create a handle");
30112798Swpaul		print_err_message("\t\t");
30212798Swpaul		f_print(fout, "\t\texit(1);\n");
30312798Swpaul		f_print(fout, "\t}\n");
30412798Swpaul		if (timerflag) {
30512798Swpaul			f_print(fout, "\tif (_rpcpmstart) {\n");
30612798Swpaul			f_print(fout,
307149709Sstefanf				"\t\t(void) signal(SIGALRM, closedown);\n");
30812798Swpaul			f_print(fout, "\t\t(void) \
30912798Swpaulalarm(_RPCSVC_CLOSEDOWN/2);\n");
31012798Swpaul			f_print(fout, "\t}\n");
31112798Swpaul		}
31212798Swpaul	}
3131897Swollman	f_print(fout, "\tsvc_run();\n");
31412798Swpaul	(void) sprintf(_errbuf, "svc_run returned");
31512798Swpaul	print_err_message("\t");
3161897Swollman	f_print(fout, "\texit(1);\n");
31712798Swpaul	f_print(fout, "\t/* NOTREACHED */\n");
3181897Swollman	f_print(fout, "}\n");
3191897Swollman}
3201897Swollman
3211897Swollmanvoid
3221897Swollmanwrite_programs(storage)
3231897Swollman	char *storage;
3241897Swollman{
3251897Swollman	list *l;
3261897Swollman	definition *def;
3271897Swollman
32812798Swpaul	/* write out stubs for procedure  definitions */
3291897Swollman	for (l = defined; l != NULL; l = l->next) {
3301897Swollman		def = (definition *) l->val;
3311897Swollman		if (def->def_kind == DEF_PROGRAM) {
33212798Swpaul			write_real_program(def);
33312798Swpaul		}
33412798Swpaul	}
33512798Swpaul
33612798Swpaul	/* write out dispatcher for each program */
33712798Swpaul	for (l = defined; l != NULL; l = l->next) {
33812798Swpaul		def = (definition *) l->val;
33912798Swpaul		if (def->def_kind == DEF_PROGRAM) {
3401897Swollman			write_program(def, storage);
3411897Swollman		}
3421897Swollman	}
34312798Swpaul
34412798Swpaul
3451897Swollman}
3461897Swollman
34712798Swpaul/*
34812798Swpaul * write out definition of internal function (e.g. _printmsg_1(...))
34912798Swpaul *  which calls server's defintion of actual function (e.g. printmsg_1(...)).
35012798Swpaul *  Unpacks single user argument of printmsg_1 to call-by-value format
35112798Swpaul *  expected by printmsg_1.
35212798Swpaul */
35317142Sjkhstatic void
35412798Swpaulwrite_real_program(def)
35512798Swpaul	definition *def;
35612798Swpaul{
35712798Swpaul	version_list *vp;
35812798Swpaul	proc_list *proc;
35912798Swpaul	decl_list *l;
3601897Swollman
36112798Swpaul	if (!newstyle) return;  /* not needed for old style */
36212798Swpaul	for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
36312798Swpaul		for (proc = vp->procs; proc != NULL; proc = proc->next) {
36412798Swpaul			f_print(fout, "\n");
36512798Swpaul			if (!mtflag)
36612798Swpaul				internal_proctype(proc);
36712798Swpaul			else
36812798Swpaul				f_print(fout, "int");
36912798Swpaul			f_print(fout, "\n_");
37012798Swpaul			pvname(proc->proc_name, vp->vers_num);
371149709Sstefanf			f_print(fout, "(");
372149709Sstefanf			/* arg name */
373149709Sstefanf			if (proc->arg_num > 1)
374149709Sstefanf				f_print(fout, proc->args.argname);
375149709Sstefanf			else
376149709Sstefanf				ptype(proc->args.decls->decl.prefix,
377149709Sstefanf				      proc->args.decls->decl.type, 0);
378149709Sstefanf			if (mtflag) {
379149709Sstefanf				f_print(fout, " *argp, void *%s, struct svc_req *%s)\n",
380149709Sstefanf					RESULT, RQSTP);
38112798Swpaul
38212798Swpaul
38312798Swpaul			}
384149709Sstefanf			else
385149709Sstefanf				f_print(fout, " *argp, struct svc_req *%s)\n",
386149709Sstefanf					RQSTP);
38712798Swpaul
38812798Swpaul			f_print(fout, "{\n");
38912798Swpaul			f_print(fout, "\treturn (");
390149709Sstefanf			pvname_svc(proc->proc_name, vp->vers_num);
39112798Swpaul			f_print(fout, "(");
39212798Swpaul			if (proc->arg_num < 2) { /* single argument */
39312798Swpaul				if (!streq(proc->args.decls->decl.type, "void"))
39412798Swpaul					f_print(fout, "*argp, "); /* non-void */
39512798Swpaul			} else {
39612798Swpaul				for (l = proc->args.decls;  l != NULL;
39712798Swpaul				     l = l->next)
39812798Swpaul					f_print(fout, "argp->%s, ",
39912798Swpaul						l->decl.name);
40012798Swpaul			}
40112798Swpaul			if (mtflag)
40212798Swpaul				f_print(fout, "%s, ",RESULT);
40312798Swpaul			f_print(fout, "%s));\n}\n", RQSTP);
40412798Swpaul		}
40512798Swpaul	}
40612798Swpaul}
40712798Swpaul
40817142Sjkhstatic void
4091897Swollmanwrite_program(def, storage)
4101897Swollman	definition *def;
4111897Swollman	char *storage;
4121897Swollman{
4131897Swollman	version_list *vp;
4141897Swollman	proc_list *proc;
4151897Swollman	int filled;
4161897Swollman
4171897Swollman	for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
4181897Swollman		f_print(fout, "\n");
4191897Swollman		if (storage != NULL) {
4201897Swollman			f_print(fout, "%s ", storage);
4211897Swollman		}
4221897Swollman		f_print(fout, "void\n");
4231897Swollman		pvname(def->def_name, vp->vers_num);
42412798Swpaul
425149709Sstefanf		f_print(fout, "(struct svc_req *%s, ", RQSTP);
426149709Sstefanf		f_print(fout, "register SVCXPRT *%s)\n", TRANSP);
4271897Swollman		f_print(fout, "{\n");
4281897Swollman
4291897Swollman		filled = 0;
4301897Swollman		f_print(fout, "\tunion {\n");
4311897Swollman		for (proc = vp->procs; proc != NULL; proc = proc->next) {
43212798Swpaul			if (proc->arg_num < 2) { /* single argument */
43312798Swpaul				if (streq(proc->args.decls->decl.type,
43412798Swpaul					  "void")) {
43512798Swpaul					continue;
43612798Swpaul				}
43712798Swpaul				filled = 1;
43812798Swpaul				f_print(fout, "\t\t");
43912798Swpaul				ptype(proc->args.decls->decl.prefix,
44012798Swpaul				      proc->args.decls->decl.type, 0);
44112798Swpaul				pvname(proc->proc_name, vp->vers_num);
44212798Swpaul				f_print(fout, "_arg;\n");
44312798Swpaul
44412798Swpaul			} else {
44512798Swpaul				filled = 1;
44612798Swpaul				f_print(fout, "\t\t%s", proc->args.argname);
44712798Swpaul				f_print(fout, " ");
44812798Swpaul				pvname(proc->proc_name, vp->vers_num);
44912798Swpaul				f_print(fout, "_arg;\n");
4501897Swollman			}
4511897Swollman		}
4521897Swollman		if (!filled) {
4531897Swollman			f_print(fout, "\t\tint fill;\n");
4541897Swollman		}
4551897Swollman		f_print(fout, "\t} %s;\n", ARG);
45612798Swpaul
45712798Swpaul		if (mtflag) {
45812798Swpaul			f_print(fout, "\tunion {\n");
45912798Swpaul			for (proc = vp->procs; proc != NULL; proc = proc->next) {
46012798Swpaul				f_print(fout, "\t\t");
46112798Swpaul				ptype(proc->res_prefix, proc->res_type, 0);
46212798Swpaul				pvname(proc->proc_name, vp->vers_num);
46312798Swpaul				f_print(fout, "_res;\n");
46412798Swpaul			}
46512798Swpaul			f_print(fout, "\t} %s;\n", RESULT);
46612798Swpaul			f_print(fout, "\tbool_t %s;\n", RETVAL);
46712798Swpaul
468100441Scharnier		} else
46912798Swpaul			f_print(fout, "\tchar *%s;\n", RESULT);
47012798Swpaul
471149709Sstefanf		f_print(fout, "\txdrproc_t xdr_%s, xdr_%s;\n", ARG, RESULT);
472149709Sstefanf		if (mtflag)
47312798Swpaul			f_print(fout,
474149709Sstefanf				"\tbool_t (*%s)(char *, void *, struct svc_req *);\n",
475149709Sstefanf				ROUTINE);
476149709Sstefanf		else
477149709Sstefanf			f_print(fout,
478149709Sstefanf				"\tchar *(*%s)(char *, struct svc_req *);\n",
479149709Sstefanf				ROUTINE);
4801897Swollman		f_print(fout, "\n");
48112798Swpaul
48212798Swpaul		if (timerflag) {
48312798Swpaul			if (mtflag)
48412798Swpaul				f_print(fout, "\tmutex_lock(&_svcstate_lock);\n");
48512798Swpaul
48612798Swpaul			f_print(fout, "\t_rpcsvcstate = _SERVING;\n");
48712798Swpaul			if (mtflag)
48812798Swpaul				f_print(fout, "\tmutex_unlock(&_svcstate_lock);\n");
48912798Swpaul		}
49012798Swpaul
4911897Swollman		f_print(fout, "\tswitch (%s->rq_proc) {\n", RQSTP);
4921897Swollman		if (!nullproc(vp->procs)) {
4931897Swollman			f_print(fout, "\tcase NULLPROC:\n");
49412798Swpaul			f_print(fout,
495149709Sstefanf				"\t\t(void) svc_sendreply(%s,\n\t\t\t"
496149709Sstefanf				"(xdrproc_t) xdr_void, (char *)NULL);\n",
49712798Swpaul				TRANSP);
49812798Swpaul			print_return("\t\t");
49912798Swpaul			f_print(fout, "\n");
5001897Swollman		}
5011897Swollman		for (proc = vp->procs; proc != NULL; proc = proc->next) {
5021897Swollman			f_print(fout, "\tcase %s:\n", proc->proc_name);
50312798Swpaul			if (proc->arg_num < 2) { /* single argument */
50412798Swpaul				p_xdrfunc(ARG, proc->args.decls->decl.type);
50512798Swpaul			} else {
50612798Swpaul				p_xdrfunc(ARG, proc->args.argname);
50712798Swpaul			}
50812798Swpaul			p_xdrfunc(RESULT, proc->res_type);
50912798Swpaul
510149709Sstefanf			if (mtflag)
511149709Sstefanf				f_print(fout,
512149709Sstefanf					"\t\t%s = (bool_t (*) (char *,  void *,  struct svc_req *))",
513149709Sstefanf					ROUTINE);
51412798Swpaul			else
515149709Sstefanf				f_print(fout,
516149709Sstefanf					"\t\t%s = (char *(*)(char *, struct svc_req *)) ",
517149709Sstefanf					ROUTINE);
51812798Swpaul			if (newstyle) { /* new style: calls internal routine */
51912798Swpaul				f_print(fout, "_");
52012798Swpaul			}
521149709Sstefanf			if (!newstyle)
52212798Swpaul				pvname_svc(proc->proc_name, vp->vers_num);
52312798Swpaul			else
52412798Swpaul				pvname(proc->proc_name, vp->vers_num);
5251897Swollman			f_print(fout, ";\n");
5261897Swollman			f_print(fout, "\t\tbreak;\n\n");
5271897Swollman		}
5281897Swollman		f_print(fout, "\tdefault:\n");
5291897Swollman		printerr("noproc", TRANSP);
53012798Swpaul		print_return("\t\t");
5311897Swollman		f_print(fout, "\t}\n");
5321897Swollman
53312798Swpaul		f_print(fout,
53412798Swpaul			"\t(void) memset((char *)&%s, 0, sizeof (%s));\n",
53512798Swpaul			ARG, ARG);
536149709Sstefanf		printif("getargs", TRANSP, "(caddr_t) &", ARG);
5371897Swollman		printerr("decode", TRANSP);
53812798Swpaul		print_return("\t\t");
5391897Swollman		f_print(fout, "\t}\n");
5401897Swollman
541100441Scharnier		if (!mtflag)
542149709Sstefanf			f_print(fout, "\t%s = (*%s)((char *)&%s, %s);\n",
543149709Sstefanf				RESULT, ROUTINE, ARG, RQSTP);
54412798Swpaul		else
545149709Sstefanf			f_print(fout, "\t%s = (bool_t) (*%s)((char *)&%s, (void *)&%s, %s);\n",
546149709Sstefanf				RETVAL, ROUTINE, ARG, RESULT, RQSTP);
54712798Swpaul
54812798Swpaul
54912798Swpaul		if (mtflag)
55012798Swpaul			f_print(fout,
55112798Swpaul				"\tif (%s > 0 && !svc_sendreply(%s, xdr_%s, (char *)&%s)) {\n",
55212798Swpaul				RETVAL, TRANSP, RESULT, RESULT);
55312798Swpaul		else
55412798Swpaul			f_print(fout,
55512798Swpaul				"\tif (%s != NULL && !svc_sendreply(%s, xdr_%s, %s)) {\n",
55612798Swpaul				RESULT, TRANSP, RESULT, RESULT);
55712798Swpaul
5581897Swollman		printerr("systemerr", TRANSP);
5591897Swollman		f_print(fout, "\t}\n");
5601897Swollman
561149709Sstefanf		printif("freeargs", TRANSP, "(caddr_t) &", ARG);
56212798Swpaul		(void) sprintf(_errbuf, "unable to free arguments");
56312798Swpaul		print_err_message("\t\t");
5641897Swollman		f_print(fout, "\t\texit(1);\n");
5651897Swollman		f_print(fout, "\t}\n");
56612798Swpaul		/* print out free routine */
56712798Swpaul		if (mtflag) {
56812798Swpaul			f_print(fout,"\tif (!");
56912798Swpaul			pvname(def->def_name, vp->vers_num);
57012798Swpaul			f_print(fout,"_freeresult(%s, xdr_%s, (caddr_t) &%s))\n",
57112798Swpaul				TRANSP, RESULT, RESULT);
57212798Swpaul			(void) sprintf(_errbuf, "unable to free results");
57312798Swpaul			print_err_message("\t\t");
57412798Swpaul			f_print(fout, "\n");
57512798Swpaul		};
57612798Swpaul		print_return("\t");
57712798Swpaul		f_print(fout, "}\n");
5781897Swollman	}
5791897Swollman}
5801897Swollman
58117142Sjkhstatic void
5821897Swollmanprinterr(err, transp)
5831897Swollman	char *err;
5841897Swollman	char *transp;
5851897Swollman{
5861897Swollman	f_print(fout, "\t\tsvcerr_%s(%s);\n", err, transp);
5871897Swollman}
5881897Swollman
58917142Sjkhstatic void
5901897Swollmanprintif(proc, transp, prefix, arg)
5911897Swollman	char *proc;
5921897Swollman	char *transp;
5931897Swollman	char *prefix;
5941897Swollman	char *arg;
5951897Swollman{
59674462Salfred	f_print(fout, "\tif (!svc_%s(%s, xdr_%s, (char *)%s%s)) {\n",
5971897Swollman		proc, transp, arg, prefix, arg);
5981897Swollman}
5991897Swollman
60017142Sjkhint
6011897Swollmannullproc(proc)
6021897Swollman	proc_list *proc;
6031897Swollman{
6041897Swollman	for (; proc != NULL; proc = proc->next) {
6051897Swollman		if (streq(proc->proc_num, "0")) {
6061897Swollman			return (1);
6071897Swollman		}
6081897Swollman	}
6091897Swollman	return (0);
6101897Swollman}
61112798Swpaul
61217142Sjkhstatic void
61312798Swpaulwrite_inetmost(infile)
61412798Swpaul	char *infile;
61512798Swpaul{
61612798Swpaul	f_print(fout, "\tregister SVCXPRT *%s;\n", TRANSP);
61712798Swpaul	f_print(fout, "\tint sock;\n");
61812798Swpaul	f_print(fout, "\tint proto;\n");
61912798Swpaul	f_print(fout, "\tstruct sockaddr_in saddr;\n");
62012798Swpaul	f_print(fout, "\tint asize = sizeof (saddr);\n");
62112798Swpaul	f_print(fout, "\n");
62212798Swpaul	f_print(fout,
62312798Swpaul	"\tif (getsockname(0, (struct sockaddr *)&saddr, &asize) == 0) {\n");
62412798Swpaul	f_print(fout, "\t\tint ssize = sizeof (int);\n\n");
62512798Swpaul	f_print(fout, "\t\tif (saddr.sin_family != AF_INET)\n");
62612798Swpaul	f_print(fout, "\t\t\texit(1);\n");
62712798Swpaul	f_print(fout, "\t\tif (getsockopt(0, SOL_SOCKET, SO_TYPE,\n");
62812798Swpaul	f_print(fout, "\t\t\t\t(char *)&_rpcfdtype, &ssize) == -1)\n");
62912798Swpaul	f_print(fout, "\t\t\texit(1);\n");
63012798Swpaul	f_print(fout, "\t\tsock = 0;\n");
63112798Swpaul	f_print(fout, "\t\t_rpcpmstart = 1;\n");
63212798Swpaul	f_print(fout, "\t\tproto = 0;\n");
63312798Swpaul	open_log_file(infile, "\t\t");
63412798Swpaul	f_print(fout, "\t} else {\n");
63512798Swpaul	write_rpc_svc_fg(infile, "\t\t");
63612798Swpaul	f_print(fout, "\t\tsock = RPC_ANYSOCK;\n");
63712798Swpaul	print_pmapunset("\t\t");
63812798Swpaul	f_print(fout, "\t}\n");
63912798Swpaul}
64012798Swpaul
64117142Sjkhstatic void
64212798Swpaulprint_return(space)
64312798Swpaul	char *space;
64412798Swpaul{
64512798Swpaul	if (exitnow)
64612798Swpaul		f_print(fout, "%sexit(0);\n", space);
64712798Swpaul	else {
64812798Swpaul		if (timerflag) {
64912798Swpaul			if (mtflag)
65012798Swpaul				f_print(fout, "%smutex_lock(&_svcstate_lock);\n", space);
65112798Swpaul				f_print(fout, "%s_rpcsvcstate = _SERVED;\n", space);
65212798Swpaul			if (mtflag)
65312798Swpaul				f_print(fout, "%smutex_unlock(&_svcstate_lock);\n", space);
65412798Swpaul		}
65512798Swpaul		f_print(fout, "%sreturn;\n", space);
65612798Swpaul	}
65712798Swpaul}
65812798Swpaul
65917142Sjkhstatic void
66012798Swpaulprint_pmapunset(space)
66112798Swpaul	char *space;
66212798Swpaul{
66312798Swpaul	list *l;
66412798Swpaul	definition *def;
66512798Swpaul	version_list *vp;
66612798Swpaul
66712798Swpaul	for (l = defined; l != NULL; l = l->next) {
66812798Swpaul		def = (definition *) l->val;
66912798Swpaul		if (def->def_kind == DEF_PROGRAM) {
67012798Swpaul			for (vp = def->def.pr.versions; vp != NULL;
67112798Swpaul					vp = vp->next) {
67212798Swpaul				f_print(fout, "%s(void) pmap_unset(%s, %s);\n",
67312798Swpaul					space, def->def_name, vp->vers_name);
67412798Swpaul			}
67512798Swpaul		}
67612798Swpaul	}
67712798Swpaul}
67812798Swpaul
67917142Sjkhstatic void
68012798Swpaulprint_err_message(space)
68112798Swpaul	char *space;
68212798Swpaul{
68312798Swpaul	if (logflag)
68412798Swpaul		f_print(fout, "%ssyslog(LOG_ERR, \"%s\");\n", space, _errbuf);
68512798Swpaul	else if (inetdflag || pmflag)
68612798Swpaul		f_print(fout, "%s_msgout(\"%s\");\n", space, _errbuf);
68712798Swpaul	else
68812798Swpaul		f_print(fout, "%sfprintf(stderr, \"%s\");\n", space, _errbuf);
68912798Swpaul}
69012798Swpaul
69112798Swpaul/*
69212798Swpaul * Write the server auxiliary function (_msgout, timeout)
69312798Swpaul */
69412798Swpaulvoid
69512798Swpaulwrite_svc_aux(nomain)
69612798Swpaul	int nomain;
69712798Swpaul{
69812798Swpaul	if (!logflag)
69912798Swpaul		write_msg_out();
70012798Swpaul	if (!nomain)
70112798Swpaul		write_timeout_func();
70212798Swpaul}
70312798Swpaul
70412798Swpaul/*
70512798Swpaul * Write the _msgout function
70612798Swpaul */
70712798Swpaul
70817142Sjkhstatic void
70917142Sjkhwrite_msg_out(void)
71012798Swpaul{
71112798Swpaul	f_print(fout, "\n");
71212798Swpaul/*
71312798Swpaul * Avoid making _msgout() static -- it's useful to have it visible
71412798Swpaul * in the toplevel RPC server code.
71512798Swpaul */
71612798Swpaul	f_print(fout, "static\n");
717149709Sstefanf	f_print(fout, "void _msgout(const char* msg)\n");
71812798Swpaul	f_print(fout, "{\n");
71912798Swpaul	f_print(fout, "#ifdef RPC_SVC_FG\n");
72012798Swpaul	if (inetdflag || pmflag)
72112798Swpaul		f_print(fout, "\tif (_rpcpmstart)\n");
72279295Skris	f_print(fout, "\t\tsyslog(LOG_ERR, \"%%s\", msg);\n");
72312798Swpaul	f_print(fout, "\telse\n");
72412798Swpaul	f_print(fout,
72512798Swpaul		"\t\t(void) fprintf(stderr, \"%%s\\n\", msg);\n");
72612798Swpaul	f_print(fout, "#else\n");
72779295Skris	f_print(fout, "\tsyslog(LOG_ERR, \"%%s\", msg);\n");
72812798Swpaul	f_print(fout, "#endif\n");
72912798Swpaul	f_print(fout, "}\n");
73012798Swpaul}
73112798Swpaul
73212798Swpaul/*
73312798Swpaul * Write the timeout function
73412798Swpaul */
73517142Sjkhstatic void
73617142Sjkhwrite_timeout_func(void)
73712798Swpaul{
73812798Swpaul	if (!timerflag)
73912798Swpaul		return;
74012798Swpaul
74112798Swpaul	f_print(fout, "\n");
74212798Swpaul	f_print(fout, "static void\n");
743149709Sstefanf	f_print(fout, "closedown(int sig)\n");
74412798Swpaul	f_print(fout, "{\n");
74512798Swpaul	if (mtflag)
74612798Swpaul		f_print(fout, "\tmutex_lock(&_svcstate_lock);\n");
74712798Swpaul	f_print(fout, "\tif (_rpcsvcstate == _IDLE) {\n");
74812798Swpaul	f_print(fout, "\t\textern fd_set svc_fdset;\n");
74912798Swpaul	f_print(fout, "\t\tstatic int size;\n");
75012798Swpaul	f_print(fout, "\t\tint i, openfd;\n");
75112798Swpaul	if (tirpcflag && pmflag) {
75212798Swpaul		f_print(fout, "\t\tstruct t_info tinfo;\n\n");
75312798Swpaul		f_print(fout,
75412798Swpaul			"\t\tif (!t_getinfo(0, &tinfo) && (tinfo.servtype == T_CLTS))\n");
75512798Swpaul	} else {
75612798Swpaul		f_print(fout, "\n\t\tif (_rpcfdtype == SOCK_DGRAM)\n");
75712798Swpaul	}
75812798Swpaul	f_print(fout, "\t\t\texit(0);\n");
75912798Swpaul	f_print(fout, "\t\tif (size == 0) {\n");
76012798Swpaul	if (tirpcflag) {
76112798Swpaul		f_print(fout, "\t\t\tstruct rlimit rl;\n\n");
76212798Swpaul		f_print(fout, "\t\t\trl.rlim_max = 0;\n");
76312798Swpaul		f_print(fout, "\t\t\tgetrlimit(RLIMIT_NOFILE, &rl);\n");
76412798Swpaul		f_print(fout, "\t\t\tif ((size = rl.rlim_max) == 0) {\n");
76512798Swpaul
76612798Swpaul		if (mtflag)
76712798Swpaul			f_print(fout, "\t\t\t\tmutex_unlock(&_svcstate_lock);\n");
76812798Swpaul
76912798Swpaul		f_print(fout, "\t\t\t\treturn;\n\t\t\t}\n");
77012798Swpaul	} else {
77112798Swpaul		f_print(fout, "\t\t\tsize = getdtablesize();\n");
77212798Swpaul	}
77312798Swpaul	f_print(fout, "\t\t}\n");
77412798Swpaul	f_print(fout,
77512798Swpaul		"\t\tfor (i = 0, openfd = 0; i < size && openfd < 2; i++)\n");
77612798Swpaul	f_print(fout, "\t\t\tif (FD_ISSET(i, &svc_fdset))\n");
77712798Swpaul	f_print(fout, "\t\t\t\topenfd++;\n");
77812798Swpaul	f_print(fout, "\t\tif (openfd <= 1)\n");
77912798Swpaul	f_print(fout, "\t\t\texit(0);\n");
78012798Swpaul	f_print(fout, "\t}\n");
78112798Swpaul	f_print(fout, "\tif (_rpcsvcstate == _SERVED)\n");
78212798Swpaul	f_print(fout, "\t\t_rpcsvcstate = _IDLE;\n\n");
78312798Swpaul	if (mtflag)
78412798Swpaul		f_print(fout, "\tmutex_unlock(&_svcstate_lock);\n");
78512798Swpaul
786149709Sstefanf	f_print(fout, "\t(void) signal(SIGALRM, closedown);\n");
78712798Swpaul	f_print(fout, "\t(void) alarm(_RPCSVC_CLOSEDOWN/2);\n");
78812798Swpaul	f_print(fout, "}\n");
78912798Swpaul
79012798Swpaul}
79112798Swpaul
79212798Swpaul/*
79312798Swpaul * Write the most of port monitor support
79412798Swpaul */
79517142Sjkhstatic void
79612798Swpaulwrite_pm_most(infile, netflag)
79712798Swpaul	char *infile;
79812798Swpaul	int netflag;
79912798Swpaul{
80012798Swpaul	list *l;
80112798Swpaul	definition *def;
80212798Swpaul	version_list *vp;
80312798Swpaul
80499979Salfred	if (tirpc_socket) {
80599979Salfred		f_print(fout,
80699979Salfred		"\tif (getsockname(0, (struct sockaddr *)&saddr, &asize) == 0) {\n");
80799979Salfred		f_print(fout, "\t\tint ssize = sizeof (int);\n");
80899979Salfred	} else {
80999979Salfred		f_print(fout, "\tif (!ioctl(0, I_LOOK, mname) &&\n");
81099979Salfred		f_print(fout, "\t\t(!strcmp(mname, \"sockmod\") ||");
81199979Salfred		f_print(fout, " !strcmp(mname, \"timod\"))) {\n");
81299979Salfred	}
81312798Swpaul	f_print(fout, " !strcmp(mname, \"timod\"))) {\n");
81412798Swpaul	f_print(fout, "\t\tchar *netid;\n");
81512798Swpaul	if (!netflag) {	/* Not included by -n option */
81612798Swpaul		f_print(fout, "\t\tstruct netconfig *nconf = NULL;\n");
81712798Swpaul		f_print(fout, "\t\tSVCXPRT *%s;\n", TRANSP);
81812798Swpaul	}
81912798Swpaul	if (timerflag)
82012798Swpaul		f_print(fout, "\t\tint pmclose;\n");
82112798Swpaul/*
82212798Swpaul *  Not necessary, defined in /usr/include/stdlib
82312798Swpaul *  f_print(fout, "\t\textern char *getenv();\n");
82412798Swpaul */
82512798Swpaul	f_print(fout, "\n");
82699979Salfred	if (tirpc_socket) {
82799979Salfred		f_print(fout, "\t\tif (saddr.ss_family != AF_INET &&\n");
82899979Salfred		f_print(fout, "\t\t    saddr.ss_family != AF_INET6)\n");
82999979Salfred		f_print(fout, "\t\t\texit(1);\n");
83099979Salfred		f_print(fout, "\t\tif (getsockopt(0, SOL_SOCKET, SO_TYPE,\n");
83199979Salfred		f_print(fout, "\t\t\t\t(char *)&_rpcfdtype, &ssize) == -1)\n");
83299979Salfred		f_print(fout, "\t\t\texit(1);\n");
83399979Salfred	}
83412798Swpaul	f_print(fout, "\t\t_rpcpmstart = 1;\n");
83512798Swpaul	open_log_file(infile, "\t\t");
83612798Swpaul	f_print(fout, "\n\t\tif ((netid = \
83712798Swpaulgetenv(\"NLSPROVIDER\")) == NULL) {\n");
83812798Swpaul
83912798Swpaul	if (timerflag) {
84012798Swpaul		f_print(fout, "\t\t/* started from inetd */\n");
84112798Swpaul		f_print(fout, "\t\t\tpmclose = 1;\n");
84212798Swpaul	}
84312798Swpaul	f_print(fout,
84412798Swpaul		"\t\t} else {\n");
84512798Swpaul	f_print(fout, "\t\t\tif ((nconf = getnetconfigent(netid)) == NULL)\n");
84612798Swpaul	sprintf(_errbuf, "cannot get transport info");
84712798Swpaul	print_err_message("\t\t\t\t");
84899979Salfred       if (timerflag) {
84999979Salfred		if (tirpc_socket)
85099979Salfred			f_print(fout, "\n\t\t\tpmclose = 1;\t/* XXX */\n");
85199979Salfred		else
85299979Salfred			f_print(fout,
85399979Salfred			    "\n\t\t\tpmclose = (t_getstate(0) != T_DATAXFER);\n");
85499979Salfred	}
85512798Swpaul	f_print(fout, "\t\t}\n");
85612798Swpaul	/*
85712798Swpaul	 * A kludgy support for inetd services. Inetd only works with
85812798Swpaul	 * sockmod, and RPC works only with timod, hence all this jugglery
85912798Swpaul	 */
86099979Salfred	if (!tirpc_socket) {
86199979Salfred		f_print(fout, "\t\tif (strcmp(mname, \"sockmod\") == 0) {\n");
86299979Salfred		f_print(fout, "\t\t\tif (ioctl(0, I_POP, 0) || ");
86399979Salfred		f_print(fout, "ioctl(0, I_PUSH, \"timod\")) {\n");
86499979Salfred		sprintf(_errbuf, "could not get the right module");
86599979Salfred		print_err_message("\t\t\t\t");
86699979Salfred		f_print(fout, "\t\t\t\texit(1);\n");
86799979Salfred		f_print(fout, "\t\t\t}\n");
86899979Salfred		f_print(fout, "\t\t}\n");
86999979Salfred	}
870109363Smbr	if (tirpcflag) {
871109363Smbr		f_print(fout,
872109363Smbr		"\t\tif ((%s = svc_tli_create(0, nconf, NULL, \
873109363Smbr		RPC_MAXDATASIZE, RPC_MAXDATASIZE)) \
874109363Smbr		== NULL) {\n",
87512798Swpaul		TRANSP);
876109363Smbr	} else {
877109363Smbr		f_print(fout,
878109363Smbr		    "\t\tif ((%s = svc_tli_create(0, nconf, NULL, 0, 0)) \
879109363Smbr		    == NULL) {\n",
880109363Smbr                    TRANSP);
881109363Smbr	}
88212798Swpaul	sprintf(_errbuf, "cannot create server handle");
88312798Swpaul	print_err_message("\t\t\t");
88412798Swpaul	f_print(fout, "\t\t\texit(1);\n");
88512798Swpaul	f_print(fout, "\t\t}\n");
88612798Swpaul	f_print(fout, "\t\tif (nconf)\n");
88712798Swpaul	f_print(fout, "\t\t\tfreenetconfigent(nconf);\n");
88812798Swpaul	for (l = defined; l != NULL; l = l->next) {
88912798Swpaul		def = (definition *) l->val;
89012798Swpaul		if (def->def_kind != DEF_PROGRAM) {
89112798Swpaul			continue;
89212798Swpaul		}
89312798Swpaul		for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
89412798Swpaul			f_print(fout,
89512798Swpaul				"\t\tif (!svc_reg(%s, %s, %s, ",
89612798Swpaul				TRANSP, def->def_name, vp->vers_name);
89712798Swpaul			pvname(def->def_name, vp->vers_num);
89812798Swpaul			f_print(fout, ", 0)) {\n");
89912798Swpaul			(void) sprintf(_errbuf, "unable to register (%s, %s).",
90012798Swpaul					def->def_name, vp->vers_name);
90112798Swpaul			print_err_message("\t\t\t");
90212798Swpaul			f_print(fout, "\t\t\texit(1);\n");
90312798Swpaul			f_print(fout, "\t\t}\n");
90412798Swpaul		}
90512798Swpaul	}
90612798Swpaul	if (timerflag) {
90712798Swpaul		f_print(fout, "\t\tif (pmclose) {\n");
908149709Sstefanf		f_print(fout, "\t\t\t(void) signal(SIGALRM, closedown);\n");
90912798Swpaul		f_print(fout, "\t\t\t(void) alarm(_RPCSVC_CLOSEDOWN/2);\n");
91012798Swpaul		f_print(fout, "\t\t}\n");
91112798Swpaul	}
91212798Swpaul	f_print(fout, "\t\tsvc_run();\n");
91312798Swpaul	f_print(fout, "\t\texit(1);\n");
91412798Swpaul	f_print(fout, "\t\t/* NOTREACHED */\n");
91512798Swpaul	f_print(fout, "\t}");
91612798Swpaul}
91712798Swpaul
91812798Swpaul/*
91912798Swpaul * Support for backgrounding the server if self started.
92012798Swpaul */
92117142Sjkhstatic void
92212798Swpaulwrite_rpc_svc_fg(infile, sp)
92312798Swpaul	char *infile;
92412798Swpaul	char *sp;
92512798Swpaul{
92612798Swpaul	f_print(fout, "#ifndef RPC_SVC_FG\n");
92712798Swpaul	f_print(fout, "%sint size;\n", sp);
92812798Swpaul	if (tirpcflag)
92912798Swpaul		f_print(fout, "%sstruct rlimit rl;\n", sp);
93012798Swpaul	if (inetdflag)
93112798Swpaul		f_print(fout, "%sint pid, i;\n\n", sp);
93212798Swpaul	f_print(fout, "%spid = fork();\n", sp);
93312798Swpaul	f_print(fout, "%sif (pid < 0) {\n", sp);
93412798Swpaul	f_print(fout, "%s\tperror(\"cannot fork\");\n", sp);
93512798Swpaul	f_print(fout, "%s\texit(1);\n", sp);
93612798Swpaul	f_print(fout, "%s}\n", sp);
93712798Swpaul	f_print(fout, "%sif (pid)\n", sp);
93812798Swpaul	f_print(fout, "%s\texit(0);\n", sp);
93912798Swpaul	/* get number of file descriptors */
94012798Swpaul	if (tirpcflag) {
94112798Swpaul		f_print(fout, "%srl.rlim_max = 0;\n", sp);
94212798Swpaul		f_print(fout, "%sgetrlimit(RLIMIT_NOFILE, &rl);\n", sp);
94312798Swpaul		f_print(fout, "%sif ((size = rl.rlim_max) == 0)\n", sp);
94412798Swpaul		f_print(fout, "%s\texit(1);\n", sp);
94512798Swpaul	} else {
94612798Swpaul		f_print(fout, "%ssize = getdtablesize();\n", sp);
94712798Swpaul	}
94812798Swpaul
94912798Swpaul	f_print(fout, "%sfor (i = 0; i < size; i++)\n", sp);
95012798Swpaul	f_print(fout, "%s\t(void) close(i);\n", sp);
95112798Swpaul	/* Redirect stderr and stdout to console */
95212798Swpaul	f_print(fout, "%si = open(\"/dev/console\", 2);\n", sp);
95312798Swpaul	f_print(fout, "%s(void) dup2(i, 1);\n", sp);
95412798Swpaul	f_print(fout, "%s(void) dup2(i, 2);\n", sp);
95512798Swpaul	/* This removes control of the controlling terminal */
95612798Swpaul	if (tirpcflag)
95712798Swpaul		f_print(fout, "%ssetsid();\n", sp);
95812798Swpaul	else {
95912798Swpaul		f_print(fout, "%si = open(\"/dev/tty\", 2);\n", sp);
96012798Swpaul		f_print(fout, "%sif (i >= 0) {\n", sp);
96112798Swpaul		f_print(fout,
96212798Swpaul			"%s\t(void) ioctl(i, TIOCNOTTY, (char *)NULL);\n", sp);
96312798Swpaul		f_print(fout, "%s\t(void) close(i);\n", sp);
96412798Swpaul		f_print(fout, "%s}\n", sp);
96512798Swpaul	}
96612798Swpaul	if (!logflag)
96712798Swpaul		open_log_file(infile, sp);
96812798Swpaul	f_print(fout, "#endif\n");
96912798Swpaul	if (logflag)
97012798Swpaul		open_log_file(infile, sp);
97112798Swpaul}
97212798Swpaul
97317142Sjkhstatic void
97412798Swpaulopen_log_file(infile, sp)
97512798Swpaul	char *infile;
97612798Swpaul	char *sp;
97712798Swpaul{
97812798Swpaul	char *s;
97912798Swpaul
98012798Swpaul	s = strrchr(infile, '.');
98112798Swpaul	if (s)
98212798Swpaul		*s = '\0';
98312798Swpaul	f_print(fout, "%sopenlog(\"%s\", LOG_PID, LOG_DAEMON);\n", sp, infile);
98412798Swpaul	if (s)
98512798Swpaul		*s = '.';
98612798Swpaul}
98712798Swpaul
98812798Swpaul
98912798Swpaul
99012798Swpaul
99112798Swpaul/*
99212798Swpaul * write a registration for the given transport for Inetd
99312798Swpaul */
99412798Swpaulvoid
99512798Swpaulwrite_inetd_register(transp)
99612798Swpaul	char *transp;
99712798Swpaul{
99812798Swpaul	list *l;
99912798Swpaul	definition *def;
100012798Swpaul	version_list *vp;
100112798Swpaul	char *sp;
100212798Swpaul	int isudp;
100312798Swpaul	char tmpbuf[32];
100412798Swpaul
100512798Swpaul	if (inetdflag)
100612798Swpaul		sp = "\t";
100712798Swpaul	else
100812798Swpaul		sp = "";
100912798Swpaul	if (streq(transp, "udp"))
101012798Swpaul		isudp = 1;
101112798Swpaul	else
101212798Swpaul		isudp = 0;
101312798Swpaul	f_print(fout, "\n");
101412798Swpaul	if (inetdflag) {
101512798Swpaul		f_print(fout,
101612798Swpaul			"\tif ((_rpcfdtype == 0) || (_rpcfdtype == %s)) {\n",
101712798Swpaul			isudp ? "SOCK_DGRAM" : "SOCK_STREAM");
101812798Swpaul	}
1019109363Smbr	if (tirpcflag)
1020109363Smbr		f_print(fout, "\t\trpc_control(RPC_SVC_CONNMAXREC_SET, &maxrec);\n");
102112798Swpaul	f_print(fout, "%s\t%s = svc%s_create(%s",
102212798Swpaul		sp, TRANSP, transp, inetdflag? "sock": "RPC_ANYSOCK");
102312798Swpaul	if (!isudp)
102412798Swpaul		f_print(fout, ", 0, 0");
102512798Swpaul	f_print(fout, ");\n");
102612798Swpaul	f_print(fout, "%s\tif (%s == NULL) {\n", sp, TRANSP);
102712798Swpaul	(void) sprintf(_errbuf, "cannot create %s service.", transp);
102812798Swpaul	(void) sprintf(tmpbuf, "%s\t\t", sp);
102912798Swpaul	print_err_message(tmpbuf);
103012798Swpaul	f_print(fout, "%s\t\texit(1);\n", sp);
103112798Swpaul	f_print(fout, "%s\t}\n", sp);
103212798Swpaul
103312798Swpaul	if (inetdflag) {
103412798Swpaul		f_print(fout, "%s\tif (!_rpcpmstart)\n\t", sp);
103512798Swpaul		f_print(fout, "%s\tproto = IPPROTO_%s;\n",
103612798Swpaul				sp, isudp ? "UDP": "TCP");
103712798Swpaul	}
103812798Swpaul	for (l = defined; l != NULL; l = l->next) {
103912798Swpaul		def = (definition *) l->val;
104012798Swpaul		if (def->def_kind != DEF_PROGRAM) {
104112798Swpaul			continue;
104212798Swpaul		}
104312798Swpaul		for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
104412798Swpaul			f_print(fout, "%s\tif (!svc_register(%s, %s, %s, ",
104512798Swpaul				sp, TRANSP, def->def_name, vp->vers_name);
104612798Swpaul			pvname(def->def_name, vp->vers_num);
104712798Swpaul			if (inetdflag)
104812798Swpaul				f_print(fout, ", proto)) {\n");
104912798Swpaul			else
105012798Swpaul				f_print(fout, ", IPPROTO_%s)) {\n",
105112798Swpaul					isudp ? "UDP": "TCP");
105212798Swpaul			(void) sprintf(_errbuf,
105312798Swpaul				"unable to register (%s, %s, %s).",
105412798Swpaul				def->def_name, vp->vers_name, transp);
105512798Swpaul			print_err_message(tmpbuf);
105612798Swpaul			f_print(fout, "%s\t\texit(1);\n", sp);
105712798Swpaul			f_print(fout, "%s\t}\n", sp);
105812798Swpaul		}
105912798Swpaul	}
106012798Swpaul	if (inetdflag)
106112798Swpaul		f_print(fout, "\t}\n");
106212798Swpaul}
1063