xref: /onnv-gate/usr/src/cmd/rpcgen/rpc_svcout.c (revision 10133:5ca4202029f8)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
59497SJordan.Brown@Sun.COM  * Common Development and Distribution License (the "License").
69497SJordan.Brown@Sun.COM  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
20132Srobinson  */
21132Srobinson 
22132Srobinson /*
239497SJordan.Brown@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
270Sstevel@tonic-gate /* All Rights Reserved */
280Sstevel@tonic-gate /*
290Sstevel@tonic-gate  * University Copyright- Copyright (c) 1982, 1986, 1988
300Sstevel@tonic-gate  * The Regents of the University of California
310Sstevel@tonic-gate  * All Rights Reserved
320Sstevel@tonic-gate  *
330Sstevel@tonic-gate  * University Acknowledgment- Portions of this document are derived from
340Sstevel@tonic-gate  * software developed by the University of California, Berkeley, and its
350Sstevel@tonic-gate  * contributors.
360Sstevel@tonic-gate  */
370Sstevel@tonic-gate 
380Sstevel@tonic-gate /*
390Sstevel@tonic-gate  * rpc_svcout.c, Server-skeleton outputter for the RPC protocol compiler
400Sstevel@tonic-gate  */
410Sstevel@tonic-gate #include <stdio.h>
420Sstevel@tonic-gate #include <string.h>
43*10133SJordan.Brown@Sun.COM #include <stdarg.h>
440Sstevel@tonic-gate #include "rpc_parse.h"
450Sstevel@tonic-gate #include "rpc_util.h"
460Sstevel@tonic-gate 
47132Srobinson extern int nullproc(proc_list *);
48132Srobinson 
490Sstevel@tonic-gate static char RQSTP[] = "rqstp";
500Sstevel@tonic-gate static char TRANSP[] = "transp";
510Sstevel@tonic-gate static char ARG[] = "argument";
520Sstevel@tonic-gate static char RESULT[] = "result";
530Sstevel@tonic-gate static char ROUTINE[] = "local";
540Sstevel@tonic-gate static char RETVAL[] = "retval";
550Sstevel@tonic-gate 
56132Srobinson #define	ERRBUFLEN	256
570Sstevel@tonic-gate 
58132Srobinson static void internal_proctype(proc_list *);
59132Srobinson static void write_real_program(definition *);
60132Srobinson static void write_programs(char *);
61132Srobinson static void write_program(definition *, char *);
62132Srobinson static void printerr(char *, char *);
63132Srobinson static void write_svc_aux(int);
64132Srobinson static void printif(char *, char *, char *, char *);
65132Srobinson static void write_inetmost(char *);
66132Srobinson static void print_return(char *);
67132Srobinson static void print_pmapunset(char *);
68*10133SJordan.Brown@Sun.COM static void print_err_message(const char *, const char *, ...);
69132Srobinson static void write_msg_out(void);
70132Srobinson static void write_timeout_func(void);
71132Srobinson static void write_pm_most(char *, int);
72132Srobinson static void write_rpc_svc_fg(char *, char *);
73132Srobinson static void open_log_file(char *, char *);
74132Srobinson 
75132Srobinson static void
p_xdrfunc(char * rname,char * typename)76132Srobinson p_xdrfunc(char *rname, char *typename)
770Sstevel@tonic-gate {
78*10133SJordan.Brown@Sun.COM 	if (Cflag) {
79*10133SJordan.Brown@Sun.COM 		f_print(fout, "\t\t_xdr_%s = (xdrproc_t)\n", rname);
80*10133SJordan.Brown@Sun.COM 		f_print(fout, "\t\t    xdr_%s;\n", stringfix(typename));
81*10133SJordan.Brown@Sun.COM 	} else {
820Sstevel@tonic-gate 		f_print(fout, "\t\t_xdr_%s = xdr_%s;\n",
839497SJordan.Brown@Sun.COM 		    rname, stringfix(typename));
84*10133SJordan.Brown@Sun.COM 	}
850Sstevel@tonic-gate }
860Sstevel@tonic-gate 
87132Srobinson static void
internal_proctype(proc_list * plist)88132Srobinson internal_proctype(proc_list *plist)
890Sstevel@tonic-gate {
900Sstevel@tonic-gate 	f_print(fout, "static ");
910Sstevel@tonic-gate 	ptype(plist->res_prefix, plist->res_type, 1);
920Sstevel@tonic-gate 	f_print(fout, "*");
930Sstevel@tonic-gate }
940Sstevel@tonic-gate 
950Sstevel@tonic-gate 
960Sstevel@tonic-gate static void
write_mtauto(void)97132Srobinson write_mtauto(void)
980Sstevel@tonic-gate {
990Sstevel@tonic-gate 	f_print(fout, "\tif (!rpc_control(RPC_SVC_MTMODE_SET, &mode)) {\n");
100*10133SJordan.Brown@Sun.COM 	print_err_message("\t\t", "unable to set automatic MT mode.");
1010Sstevel@tonic-gate 	f_print(fout, "\t\texit(1);\n\t}\n");
1020Sstevel@tonic-gate }
1030Sstevel@tonic-gate 
1040Sstevel@tonic-gate /*
1050Sstevel@tonic-gate  * write most of the service, that is, everything but the registrations.
1060Sstevel@tonic-gate  */
1070Sstevel@tonic-gate void
write_most(char * infile,int netflag,int nomain)108132Srobinson write_most(char *infile, int netflag, int nomain)
1090Sstevel@tonic-gate {
1100Sstevel@tonic-gate 	if (inetdflag || pmflag) {
1110Sstevel@tonic-gate 		char *var_type;
1120Sstevel@tonic-gate 		var_type = (nomain? "extern" : "static");
1130Sstevel@tonic-gate 		f_print(fout, "%s int _rpcpmstart;", var_type);
1140Sstevel@tonic-gate 		f_print(fout, "\t\t/* Started by a port monitor ? */\n");
1150Sstevel@tonic-gate 		if (!tirpcflag) {
1160Sstevel@tonic-gate 			f_print(fout, "%s int _rpcfdtype;", var_type);
1170Sstevel@tonic-gate 			f_print(fout,
118*10133SJordan.Brown@Sun.COM 			    "\t\t /* Whether Stream or Datagram ? */\n");
1190Sstevel@tonic-gate 		}
1200Sstevel@tonic-gate 
1210Sstevel@tonic-gate 		if (timerflag) {
1220Sstevel@tonic-gate 			f_print(fout,
1230Sstevel@tonic-gate "\n/* States a server can be in wrt request */\n\n");
1240Sstevel@tonic-gate 			f_print(fout, "#define\t_IDLE 0\n");
1250Sstevel@tonic-gate 			f_print(fout, "#define\t_SERVED 1\n\n");
126*10133SJordan.Brown@Sun.COM 			if (nomain) {
127*10133SJordan.Brown@Sun.COM 				f_print(fout,
128*10133SJordan.Brown@Sun.COM 				    "/* LINTED static unused if no main */\n");
129*10133SJordan.Brown@Sun.COM 			}
130*10133SJordan.Brown@Sun.COM 			f_print(fout,
131*10133SJordan.Brown@Sun.COM 			    "static int _rpcsvcstate = _IDLE;");
1320Sstevel@tonic-gate 			f_print(fout,
1330Sstevel@tonic-gate "\t/* Set when a request is serviced */\n");
1340Sstevel@tonic-gate 			f_print(fout, "static int _rpcsvccount = 0;");
1350Sstevel@tonic-gate 			f_print(fout,
1360Sstevel@tonic-gate "\t\t/* Number of requests being serviced */\n");
1370Sstevel@tonic-gate 
1380Sstevel@tonic-gate 			if (mtflag) {
1390Sstevel@tonic-gate 				f_print(fout, "mutex_t _svcstate_lock;");
1400Sstevel@tonic-gate 				f_print(fout,
141*10133SJordan.Brown@Sun.COM "\t\t/* lock for _rpcsvcstate, _rpcsvccount */\n");
1420Sstevel@tonic-gate 
1430Sstevel@tonic-gate 			}
1440Sstevel@tonic-gate 		}
1450Sstevel@tonic-gate 
1460Sstevel@tonic-gate 		write_svc_aux(nomain);
1470Sstevel@tonic-gate 	}
1480Sstevel@tonic-gate 	/* write out dispatcher and stubs */
149132Srobinson 	write_programs(nomain ? NULL : "static");
1500Sstevel@tonic-gate 
1510Sstevel@tonic-gate 	if (nomain)
1520Sstevel@tonic-gate 		return;
1530Sstevel@tonic-gate 
154132Srobinson 	f_print(fout, "\nint\nmain()\n");
1550Sstevel@tonic-gate 	f_print(fout, "{\n");
1560Sstevel@tonic-gate 	if (inetdflag) {
1570Sstevel@tonic-gate 		write_inetmost(infile);
1580Sstevel@tonic-gate 		/* Includes call to write_rpc_svc_fg() */
1590Sstevel@tonic-gate 	} else {
1600Sstevel@tonic-gate 		if (tirpcflag) {
1610Sstevel@tonic-gate 			if (netflag) {
1620Sstevel@tonic-gate 				f_print(fout,
1639497SJordan.Brown@Sun.COM 				    "\tregister SVCXPRT *%s;\n", TRANSP);
1640Sstevel@tonic-gate 				f_print(fout,
1659497SJordan.Brown@Sun.COM 				    "\tstruct netconfig *nconf = NULL;\n");
1660Sstevel@tonic-gate 			}
1670Sstevel@tonic-gate 			f_print(fout, "\tpid_t pid;\n");
1680Sstevel@tonic-gate 			f_print(fout, "\tint i;\n");
1690Sstevel@tonic-gate 			if (mtauto) {
1700Sstevel@tonic-gate 				f_print(fout,
1719497SJordan.Brown@Sun.COM 				    "\tint mode = RPC_SVC_MT_AUTO;\n\n");
1720Sstevel@tonic-gate 				write_mtauto();
1730Sstevel@tonic-gate 			} else
1740Sstevel@tonic-gate 				f_print(fout, "\n");
1750Sstevel@tonic-gate 
1760Sstevel@tonic-gate 			if (mtflag & timerflag)
1770Sstevel@tonic-gate 				f_print(fout,
1780Sstevel@tonic-gate "\tmutex_init(&_svcstate_lock, USYNC_THREAD, NULL);\n");
1790Sstevel@tonic-gate 
1800Sstevel@tonic-gate 			write_pm_most(infile, netflag);
1810Sstevel@tonic-gate 			f_print(fout, "\telse {\n");
1820Sstevel@tonic-gate 			write_rpc_svc_fg(infile, "\t\t");
1830Sstevel@tonic-gate 			f_print(fout, "\t}\n");
1840Sstevel@tonic-gate 		} else {
1850Sstevel@tonic-gate 			f_print(fout, "\tregister SVCXPRT *%s;\n", TRANSP);
1860Sstevel@tonic-gate 			f_print(fout, "\n");
1870Sstevel@tonic-gate 			print_pmapunset("\t");
1880Sstevel@tonic-gate 		}
1890Sstevel@tonic-gate 	}
1900Sstevel@tonic-gate 
1910Sstevel@tonic-gate 	if (logflag && !inetdflag) {
1920Sstevel@tonic-gate 		open_log_file(infile, "\t");
1930Sstevel@tonic-gate 	}
1940Sstevel@tonic-gate }
1950Sstevel@tonic-gate 
1960Sstevel@tonic-gate /*
1970Sstevel@tonic-gate  * write a registration for the given transport
1980Sstevel@tonic-gate  */
1990Sstevel@tonic-gate void
write_netid_register(char * transp)200132Srobinson write_netid_register(char *transp)
2010Sstevel@tonic-gate {
2020Sstevel@tonic-gate 	list *l;
2030Sstevel@tonic-gate 	definition *def;
2040Sstevel@tonic-gate 	version_list *vp;
2050Sstevel@tonic-gate 	char *sp;
2060Sstevel@tonic-gate 	char tmpbuf[32];
2070Sstevel@tonic-gate 
2080Sstevel@tonic-gate 	sp = "";
2090Sstevel@tonic-gate 	f_print(fout, "\n");
2100Sstevel@tonic-gate 	f_print(fout, "%s\tnconf = getnetconfigent(\"%s\");\n", sp, transp);
2110Sstevel@tonic-gate 	f_print(fout, "%s\tif (nconf == NULL) {\n", sp);
212132Srobinson 	(void) snprintf(tmpbuf, sizeof (tmpbuf), "%s\t\t", sp);
213*10133SJordan.Brown@Sun.COM 	print_err_message(tmpbuf, "cannot find %s netid.", transp);
2140Sstevel@tonic-gate 	f_print(fout, "%s\t\texit(1);\n", sp);
2150Sstevel@tonic-gate 	f_print(fout, "%s\t}\n", sp);
2160Sstevel@tonic-gate 	f_print(fout, "%s\t%s = svc_tli_create(RPC_ANYFD, nconf, 0, 0, 0);\n",
2179497SJordan.Brown@Sun.COM 	    sp, TRANSP);
2180Sstevel@tonic-gate 	f_print(fout, "%s\tif (%s == NULL) {\n", sp, TRANSP);
219*10133SJordan.Brown@Sun.COM 	print_err_message(tmpbuf, "cannot create %s service.", transp);
2200Sstevel@tonic-gate 	f_print(fout, "%s\t\texit(1);\n", sp);
2210Sstevel@tonic-gate 	f_print(fout, "%s\t}\n", sp);
2220Sstevel@tonic-gate 
2230Sstevel@tonic-gate 	for (l = defined; l != NULL; l = l->next) {
2240Sstevel@tonic-gate 		def = (definition *) l->val;
2250Sstevel@tonic-gate 		if (def->def_kind != DEF_PROGRAM) {
2260Sstevel@tonic-gate 			continue;
2270Sstevel@tonic-gate 		}
2280Sstevel@tonic-gate 		for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
2290Sstevel@tonic-gate 			f_print(fout,
2309497SJordan.Brown@Sun.COM 			    "%s\t(void) rpcb_unset(%s, %s, nconf);\n",
2319497SJordan.Brown@Sun.COM 			    sp, def->def_name, vp->vers_name);
2320Sstevel@tonic-gate 			f_print(fout,
2339497SJordan.Brown@Sun.COM 			    "%s\tif (!svc_reg(%s, %s, %s, ",
2349497SJordan.Brown@Sun.COM 			    sp, TRANSP, def->def_name, vp->vers_name);
2350Sstevel@tonic-gate 			pvname(def->def_name, vp->vers_num);
2360Sstevel@tonic-gate 			f_print(fout, ", nconf)) {\n");
237*10133SJordan.Brown@Sun.COM 			print_err_message(tmpbuf,
2389497SJordan.Brown@Sun.COM 			    "unable to register (%s, %s, %s).",
2399497SJordan.Brown@Sun.COM 			    def->def_name, vp->vers_name, transp);
2400Sstevel@tonic-gate 			f_print(fout, "%s\t\texit(1);\n", sp);
2410Sstevel@tonic-gate 			f_print(fout, "%s\t}\n", sp);
2420Sstevel@tonic-gate 		}
2430Sstevel@tonic-gate 	}
2440Sstevel@tonic-gate 	f_print(fout, "%s\tfreenetconfigent(nconf);\n", sp);
2450Sstevel@tonic-gate }
2460Sstevel@tonic-gate 
2470Sstevel@tonic-gate /*
2480Sstevel@tonic-gate  * write a registration for the given transport for TLI
2490Sstevel@tonic-gate  */
2500Sstevel@tonic-gate void
write_nettype_register(char * transp)251132Srobinson write_nettype_register(char *transp)
2520Sstevel@tonic-gate {
2530Sstevel@tonic-gate 	list *l;
2540Sstevel@tonic-gate 	definition *def;
2550Sstevel@tonic-gate 	version_list *vp;
2560Sstevel@tonic-gate 
2570Sstevel@tonic-gate 	for (l = defined; l != NULL; l = l->next) {
2580Sstevel@tonic-gate 		def = (definition *) l->val;
2590Sstevel@tonic-gate 		if (def->def_kind != DEF_PROGRAM) {
2600Sstevel@tonic-gate 			continue;
2610Sstevel@tonic-gate 		}
2620Sstevel@tonic-gate 		for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
263*10133SJordan.Brown@Sun.COM 			f_print(fout, "\tif (!svc_create(\n");
264*10133SJordan.Brown@Sun.COM 			f_print(fout, "\t    ");
2650Sstevel@tonic-gate 			pvname(def->def_name, vp->vers_num);
266*10133SJordan.Brown@Sun.COM 			f_print(fout, ", %s, %s,\n",
267*10133SJordan.Brown@Sun.COM 			    def->def_name, vp->vers_name);
268*10133SJordan.Brown@Sun.COM 			f_print(fout, "\t    \"%s\")) {\n", transp);
269*10133SJordan.Brown@Sun.COM 			print_err_message("\t\t",
2709497SJordan.Brown@Sun.COM 			    "unable to create (%s, %s) for %s.",
2719497SJordan.Brown@Sun.COM 			    def->def_name, vp->vers_name, transp);
2720Sstevel@tonic-gate 			f_print(fout, "\t\texit(1);\n");
2730Sstevel@tonic-gate 			f_print(fout, "\t}\n");
2740Sstevel@tonic-gate 		}
2750Sstevel@tonic-gate 	}
2760Sstevel@tonic-gate }
2770Sstevel@tonic-gate 
2780Sstevel@tonic-gate /*
2790Sstevel@tonic-gate  * write the rest of the service
2800Sstevel@tonic-gate  */
2810Sstevel@tonic-gate void
write_rest(void)282132Srobinson write_rest(void)
2830Sstevel@tonic-gate {
2840Sstevel@tonic-gate 	f_print(fout, "\n");
2850Sstevel@tonic-gate 	if (inetdflag) {
2860Sstevel@tonic-gate 		f_print(fout, "\tif (%s == (SVCXPRT *)NULL) {\n", TRANSP);
287*10133SJordan.Brown@Sun.COM 		print_err_message("\t\t", "could not create a handle");
2880Sstevel@tonic-gate 		f_print(fout, "\t\texit(1);\n");
2890Sstevel@tonic-gate 		f_print(fout, "\t}\n");
2900Sstevel@tonic-gate 		if (timerflag) {
2910Sstevel@tonic-gate 			f_print(fout, "\tif (_rpcpmstart) {\n");
2920Sstevel@tonic-gate 			if (mtflag) {
2930Sstevel@tonic-gate 				f_print(fout,
2940Sstevel@tonic-gate "\t\tif (thr_create(NULL, 0, closedown, NULL, 0, NULL) != 0) {\n");
295*10133SJordan.Brown@Sun.COM 				print_err_message("\t\t\t",
296*10133SJordan.Brown@Sun.COM 				    "cannot create closedown thread");
2970Sstevel@tonic-gate 				f_print(fout, "\t\t\texit(1);\n");
2980Sstevel@tonic-gate 				f_print(fout, "\t\t}\n");
2990Sstevel@tonic-gate 				f_print(fout, "\t}\n");
3000Sstevel@tonic-gate 			} else {
3010Sstevel@tonic-gate 				f_print(fout,
3020Sstevel@tonic-gate 				"\t\t(void) signal(SIGALRM, %s closedown);\n",
3039497SJordan.Brown@Sun.COM 				    Cflag? "(SIG_PF)":"(void(*)())");
3040Sstevel@tonic-gate 				f_print(fout,
3050Sstevel@tonic-gate "\t\t(void) alarm(_RPCSVC_CLOSEDOWN/2);\n");
3060Sstevel@tonic-gate 				f_print(fout, "\t}\n");
3070Sstevel@tonic-gate 			}
3080Sstevel@tonic-gate 		}
3090Sstevel@tonic-gate 	}
3100Sstevel@tonic-gate 	f_print(fout, "\tsvc_run();\n");
311*10133SJordan.Brown@Sun.COM 	print_err_message("\t", "svc_run returned");
3120Sstevel@tonic-gate 	f_print(fout, "\texit(1);\n");
3130Sstevel@tonic-gate 	f_print(fout, "\t/* NOTREACHED */\n");
3140Sstevel@tonic-gate 	f_print(fout, "}\n");
3150Sstevel@tonic-gate }
3160Sstevel@tonic-gate 
317132Srobinson static void
write_programs(char * storage)318132Srobinson write_programs(char *storage)
3190Sstevel@tonic-gate {
3200Sstevel@tonic-gate 	list *l;
3210Sstevel@tonic-gate 	definition *def;
3220Sstevel@tonic-gate 
3230Sstevel@tonic-gate 	/* write out stubs for procedure  definitions */
3240Sstevel@tonic-gate 	for (l = defined; l != NULL; l = l->next) {
3250Sstevel@tonic-gate 		def = (definition *) l->val;
326132Srobinson 		if (def->def_kind == DEF_PROGRAM)
3270Sstevel@tonic-gate 			write_real_program(def);
3280Sstevel@tonic-gate 	}
3290Sstevel@tonic-gate 
3300Sstevel@tonic-gate 	/* write out dispatcher for each program */
3310Sstevel@tonic-gate 	for (l = defined; l != NULL; l = l->next) {
3320Sstevel@tonic-gate 		def = (definition *) l->val;
333132Srobinson 		if (def->def_kind == DEF_PROGRAM)
3340Sstevel@tonic-gate 			write_program(def, storage);
3350Sstevel@tonic-gate 	}
3360Sstevel@tonic-gate 
3370Sstevel@tonic-gate 
3380Sstevel@tonic-gate }
3390Sstevel@tonic-gate 
3400Sstevel@tonic-gate /*
3410Sstevel@tonic-gate  * write out definition of internal function (e.g. _printmsg_1(...))
3420Sstevel@tonic-gate  *  which calls server's defintion of actual function (e.g. printmsg_1(...)).
3430Sstevel@tonic-gate  *  Unpacks single user argument of printmsg_1 to call-by-value format
3440Sstevel@tonic-gate  *  expected by printmsg_1.
3450Sstevel@tonic-gate  */
346132Srobinson static void
write_real_program(definition * def)347132Srobinson write_real_program(definition *def)
3480Sstevel@tonic-gate {
3490Sstevel@tonic-gate 	version_list *vp;
3500Sstevel@tonic-gate 	proc_list *proc;
3510Sstevel@tonic-gate 	decl_list *l;
3520Sstevel@tonic-gate 
3530Sstevel@tonic-gate 	if (!newstyle)
3540Sstevel@tonic-gate 		return;  /* not needed for old style */
3550Sstevel@tonic-gate 	for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
3560Sstevel@tonic-gate 		for (proc = vp->procs; proc != NULL; proc = proc->next) {
3570Sstevel@tonic-gate 			int oneway = streq(proc->res_type, "oneway");
3580Sstevel@tonic-gate 
3590Sstevel@tonic-gate 			f_print(fout, "\n");
360*10133SJordan.Brown@Sun.COM 			if (proc->arg_num < 2 &&
361*10133SJordan.Brown@Sun.COM 			    streq(proc->args.decls->decl.type, "void")) {
362*10133SJordan.Brown@Sun.COM 				f_print(fout, "/* ARGSUSED */\n");
363*10133SJordan.Brown@Sun.COM 			}
3640Sstevel@tonic-gate 			if (!mtflag)
3650Sstevel@tonic-gate 				internal_proctype(proc);
3660Sstevel@tonic-gate 			else
3670Sstevel@tonic-gate 				f_print(fout, "int");
3680Sstevel@tonic-gate 			f_print(fout, "\n_");
3690Sstevel@tonic-gate 			pvname(proc->proc_name, vp->vers_num);
3700Sstevel@tonic-gate 			if (Cflag) {
371*10133SJordan.Brown@Sun.COM 				f_print(fout, "(\n");
372*10133SJordan.Brown@Sun.COM 				f_print(fout, "    ");
3730Sstevel@tonic-gate 				/* arg name */
3740Sstevel@tonic-gate 				if (proc->arg_num > 1)
375132Srobinson 					/* LINTED variable format */
3760Sstevel@tonic-gate 					f_print(fout, proc->args.argname);
3770Sstevel@tonic-gate 				else
3780Sstevel@tonic-gate 					ptype(proc->args.decls->decl.prefix,
3799497SJordan.Brown@Sun.COM 					    proc->args.decls->decl.type, 0);
380*10133SJordan.Brown@Sun.COM 				f_print(fout, " *argp,\n");
3810Sstevel@tonic-gate 				if (mtflag) {
382*10133SJordan.Brown@Sun.COM 					f_print(fout, "    ");
3830Sstevel@tonic-gate 					ptype(proc->res_prefix,
3849497SJordan.Brown@Sun.COM 					    proc->res_type, 1);
385*10133SJordan.Brown@Sun.COM 					f_print(fout, "*%s,\n", RESULT);
3860Sstevel@tonic-gate 				}
387*10133SJordan.Brown@Sun.COM 				f_print(fout, "    struct svc_req *%s)\n",
388*10133SJordan.Brown@Sun.COM 				    RQSTP);
3890Sstevel@tonic-gate 
3900Sstevel@tonic-gate 			} else {
3910Sstevel@tonic-gate 				if (mtflag)
3920Sstevel@tonic-gate 					f_print(fout, "(argp, %s, %s)\n",
3939497SJordan.Brown@Sun.COM 					    RESULT, RQSTP);
3940Sstevel@tonic-gate 				else
3950Sstevel@tonic-gate 					f_print(fout, "(argp, %s)\n", RQSTP);
3960Sstevel@tonic-gate 				/* arg name */
3970Sstevel@tonic-gate 				if (proc->arg_num > 1)
3980Sstevel@tonic-gate 					f_print(fout, "\t%s *argp;\n",
3999497SJordan.Brown@Sun.COM 					    proc->args.argname);
4000Sstevel@tonic-gate 				else {
4010Sstevel@tonic-gate 					f_print(fout, "\t");
4020Sstevel@tonic-gate 					ptype(proc->args.decls->decl.prefix,
4039497SJordan.Brown@Sun.COM 					    proc->args.decls->decl.type, 0);
4040Sstevel@tonic-gate 					f_print(fout, " *argp;\n");
4050Sstevel@tonic-gate 				}
4060Sstevel@tonic-gate 				if (mtflag)
4070Sstevel@tonic-gate 					f_print(fout, "\tvoid *%s;\n", RESULT);
4080Sstevel@tonic-gate 				f_print(fout, "\tstruct svc_req *%s;\n", RQSTP);
4090Sstevel@tonic-gate 			}
4100Sstevel@tonic-gate 
4110Sstevel@tonic-gate 			f_print(fout, "{\n");
4120Sstevel@tonic-gate 			f_print(fout, "\treturn (");
4130Sstevel@tonic-gate 			/* for mtflag, arguments are different */
4140Sstevel@tonic-gate 			if (Cflag || mtflag)
4150Sstevel@tonic-gate 				pvname_svc(proc->proc_name, vp->vers_num);
4160Sstevel@tonic-gate 			else
4170Sstevel@tonic-gate 				pvname(proc->proc_name, vp->vers_num);
4180Sstevel@tonic-gate 			f_print(fout, "(");
4190Sstevel@tonic-gate 			if (proc->arg_num < 2) { /* single argument */
420*10133SJordan.Brown@Sun.COM 				/* only print if non-void */
4210Sstevel@tonic-gate 				if (!streq(proc->args.decls->decl.type, "void"))
422*10133SJordan.Brown@Sun.COM 					f_print(fout, "*argp, ");
4230Sstevel@tonic-gate 			} else {
424*10133SJordan.Brown@Sun.COM 				f_print(fout, "\n");
4250Sstevel@tonic-gate 				for (l = proc->args.decls;  l != NULL;
4269497SJordan.Brown@Sun.COM 				    l = l->next)
427*10133SJordan.Brown@Sun.COM 					f_print(fout, "\t    argp->%s,\n",
4289497SJordan.Brown@Sun.COM 					    l->decl.name);
429*10133SJordan.Brown@Sun.COM 				f_print(fout, "\t    ");
4300Sstevel@tonic-gate 			}
4310Sstevel@tonic-gate 			if (mtflag && !oneway)
4320Sstevel@tonic-gate 				f_print(fout, "%s, ", RESULT);
4330Sstevel@tonic-gate 			f_print(fout, "%s));\n}\n", RQSTP);
4340Sstevel@tonic-gate 		}
4350Sstevel@tonic-gate 	}
4360Sstevel@tonic-gate }
4370Sstevel@tonic-gate 
438132Srobinson static void
write_program(definition * def,char * storage)439132Srobinson write_program(definition *def, char *storage)
4400Sstevel@tonic-gate {
4410Sstevel@tonic-gate 	version_list *vp;
4420Sstevel@tonic-gate 	proc_list *proc;
4430Sstevel@tonic-gate 	int filled;
4440Sstevel@tonic-gate 
4450Sstevel@tonic-gate 	for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
4460Sstevel@tonic-gate 		f_print(fout, "\n");
4470Sstevel@tonic-gate 		if (storage != NULL) {
4480Sstevel@tonic-gate 			f_print(fout, "%s ", storage);
4490Sstevel@tonic-gate 		}
4500Sstevel@tonic-gate 		f_print(fout, "void\n");
4510Sstevel@tonic-gate 		pvname(def->def_name, vp->vers_num);
4520Sstevel@tonic-gate 
4530Sstevel@tonic-gate 		if (Cflag) {
4540Sstevel@tonic-gate 			f_print(fout, "(struct svc_req *%s, ", RQSTP);
4550Sstevel@tonic-gate 			f_print(fout, "register SVCXPRT *%s)\n", TRANSP);
4560Sstevel@tonic-gate 		} else {
4570Sstevel@tonic-gate 			f_print(fout, "(%s, %s)\n", RQSTP, TRANSP);
4580Sstevel@tonic-gate 			f_print(fout, "	struct svc_req *%s;\n", RQSTP);
4590Sstevel@tonic-gate 			f_print(fout, "	register SVCXPRT *%s;\n", TRANSP);
4600Sstevel@tonic-gate 		}
4610Sstevel@tonic-gate 
4620Sstevel@tonic-gate 		f_print(fout, "{\n");
4630Sstevel@tonic-gate 
4640Sstevel@tonic-gate 		filled = 0;
4650Sstevel@tonic-gate 		f_print(fout, "\tunion {\n");
4660Sstevel@tonic-gate 		for (proc = vp->procs; proc != NULL; proc = proc->next) {
4670Sstevel@tonic-gate 			if (proc->arg_num < 2) { /* single argument */
4680Sstevel@tonic-gate 				if (streq(proc->args.decls->decl.type,
4699497SJordan.Brown@Sun.COM 				    "void")) {
4700Sstevel@tonic-gate 					continue;
4710Sstevel@tonic-gate 				}
4720Sstevel@tonic-gate 				filled = 1;
4730Sstevel@tonic-gate 				f_print(fout, "\t\t");
4740Sstevel@tonic-gate 				ptype(proc->args.decls->decl.prefix,
4759497SJordan.Brown@Sun.COM 				    proc->args.decls->decl.type, 0);
4760Sstevel@tonic-gate 				pvname(proc->proc_name, vp->vers_num);
4770Sstevel@tonic-gate 				f_print(fout, "_arg;\n");
4780Sstevel@tonic-gate 
4790Sstevel@tonic-gate 			} else {
4800Sstevel@tonic-gate 				filled = 1;
4810Sstevel@tonic-gate 				f_print(fout, "\t\t%s", proc->args.argname);
4820Sstevel@tonic-gate 				f_print(fout, " ");
4830Sstevel@tonic-gate 				pvname(proc->proc_name, vp->vers_num);
4840Sstevel@tonic-gate 				f_print(fout, "_arg;\n");
4850Sstevel@tonic-gate 			}
4860Sstevel@tonic-gate 		}
4870Sstevel@tonic-gate 		if (!filled) {
4880Sstevel@tonic-gate 			f_print(fout, "\t\tint fill;\n");
4890Sstevel@tonic-gate 		}
4900Sstevel@tonic-gate 		f_print(fout, "\t} %s;\n", ARG);
4910Sstevel@tonic-gate 
4920Sstevel@tonic-gate 		if (mtflag) {
4930Sstevel@tonic-gate 			filled = 0;
4940Sstevel@tonic-gate 			f_print(fout, "\tunion {\n");
4950Sstevel@tonic-gate 			for (proc = vp->procs; proc != NULL;
4969497SJordan.Brown@Sun.COM 			    proc = proc->next) {
4970Sstevel@tonic-gate 				if (streq(proc->res_type, "void") ||
4980Sstevel@tonic-gate 				    streq(proc->res_type, "oneway"))
4990Sstevel@tonic-gate 					continue;
5000Sstevel@tonic-gate 				filled = 1;
5010Sstevel@tonic-gate 				f_print(fout, "\t\t");
5020Sstevel@tonic-gate 				ptype(proc->res_prefix, proc->res_type, 0);
5030Sstevel@tonic-gate 				pvname(proc->proc_name, vp->vers_num);
5040Sstevel@tonic-gate 				f_print(fout, "_res;\n");
5050Sstevel@tonic-gate 			}
5060Sstevel@tonic-gate 			if (!filled)
5070Sstevel@tonic-gate 				f_print(fout, "\t\tint fill;\n");
5080Sstevel@tonic-gate 			f_print(fout, "\t} %s;\n", RESULT);
5090Sstevel@tonic-gate 			f_print(fout, "\tbool_t %s;\n", RETVAL);
5100Sstevel@tonic-gate 
5110Sstevel@tonic-gate 		} else
5120Sstevel@tonic-gate 			f_print(fout, "\tchar *%s;\n", RESULT);
5130Sstevel@tonic-gate 
5140Sstevel@tonic-gate 		if (Cflag) {
5150Sstevel@tonic-gate 			f_print(fout, "\txdrproc_t _xdr_%s, _xdr_%s;\n",
5169497SJordan.Brown@Sun.COM 			    ARG, RESULT);
5170Sstevel@tonic-gate 			if (mtflag)
5180Sstevel@tonic-gate 				f_print(fout,
5190Sstevel@tonic-gate "\tbool_t (*%s)(char *, void *, struct svc_req *);\n",
5209497SJordan.Brown@Sun.COM 				    ROUTINE);
5210Sstevel@tonic-gate 			else
5220Sstevel@tonic-gate 				f_print(fout,
5230Sstevel@tonic-gate "\tchar *(*%s)(char *, struct svc_req *);\n",
5249497SJordan.Brown@Sun.COM 				    ROUTINE);
5250Sstevel@tonic-gate 		} else {
5260Sstevel@tonic-gate 			f_print(fout,
5279497SJordan.Brown@Sun.COM 			    "\tbool_t (*_xdr_%s)(), (*_xdr_%s)();\n",
5289497SJordan.Brown@Sun.COM 			    ARG, RESULT);
5290Sstevel@tonic-gate 			if (mtflag)
5300Sstevel@tonic-gate 				f_print(fout, "\tbool_t (*%s)();\n", ROUTINE);
5310Sstevel@tonic-gate 			else
5320Sstevel@tonic-gate 				f_print(fout, "\tchar *(*%s)();\n", ROUTINE);
5330Sstevel@tonic-gate 		}
5340Sstevel@tonic-gate 		f_print(fout, "\n");
5350Sstevel@tonic-gate 
5360Sstevel@tonic-gate 		if (timerflag) {
5370Sstevel@tonic-gate 			if (mtflag)
5380Sstevel@tonic-gate 				f_print(fout,
539*10133SJordan.Brown@Sun.COM "\t(void) mutex_lock(&_svcstate_lock);\n");
5400Sstevel@tonic-gate 
5410Sstevel@tonic-gate 			f_print(fout, "\t_rpcsvccount++;\n");
5420Sstevel@tonic-gate 			if (mtflag)
5430Sstevel@tonic-gate 				f_print(fout,
544*10133SJordan.Brown@Sun.COM "\t(void) mutex_unlock(&_svcstate_lock);\n");
5450Sstevel@tonic-gate 		}
5460Sstevel@tonic-gate 
5470Sstevel@tonic-gate 		f_print(fout, "\tswitch (%s->rq_proc) {\n", RQSTP);
5480Sstevel@tonic-gate 		if (!nullproc(vp->procs)) {
5490Sstevel@tonic-gate 			f_print(fout, "\tcase NULLPROC:\n");
5500Sstevel@tonic-gate 			f_print(fout,
5510Sstevel@tonic-gate 			    Cflag ?
552*10133SJordan.Brown@Sun.COM "\t\t(void) svc_sendreply(%s,\n\t\t    (xdrproc_t)xdr_void, NULL);\n" :
553132Srobinson "\t\t(void) svc_sendreply(%s, xdr_void,\n\t\t\tNULL);\n",
5549497SJordan.Brown@Sun.COM 			    TRANSP);
5550Sstevel@tonic-gate 			print_return("\t\t");
5560Sstevel@tonic-gate 			f_print(fout, "\n");
5570Sstevel@tonic-gate 		}
5580Sstevel@tonic-gate 		for (proc = vp->procs; proc != NULL; proc = proc->next) {
5590Sstevel@tonic-gate 			f_print(fout, "\tcase %s:\n", proc->proc_name);
5600Sstevel@tonic-gate 			if (proc->arg_num < 2) { /* single argument */
5610Sstevel@tonic-gate 				p_xdrfunc(ARG, proc->args.decls->decl.type);
5620Sstevel@tonic-gate 			} else {
5630Sstevel@tonic-gate 				p_xdrfunc(ARG, proc->args.argname);
5640Sstevel@tonic-gate 			}
5650Sstevel@tonic-gate 
5660Sstevel@tonic-gate 			if (streq(proc->res_type, "oneway")) {
5670Sstevel@tonic-gate 				/* One-way call */
5680Sstevel@tonic-gate 				f_print(fout, "\t\t_xdr_%s = NULL;\n", RESULT);
5690Sstevel@tonic-gate 			} else {
5700Sstevel@tonic-gate 				p_xdrfunc(RESULT, proc->res_type);
5710Sstevel@tonic-gate 			}
5720Sstevel@tonic-gate 			if (Cflag) {
5730Sstevel@tonic-gate 				if (mtflag) {
5740Sstevel@tonic-gate 					f_print(fout,
5750Sstevel@tonic-gate 					    "\t\t%s = (bool_t (*) (char *,  "
5760Sstevel@tonic-gate 					    "void *,  struct svc_req *))",
5770Sstevel@tonic-gate 					    ROUTINE);
5780Sstevel@tonic-gate 				} else {
5790Sstevel@tonic-gate 					f_print(fout,
5800Sstevel@tonic-gate 					    "\t\t%s = (char *(*)(char *, "
581*10133SJordan.Brown@Sun.COM 					    "struct svc_req *))",
5820Sstevel@tonic-gate 					    ROUTINE);
5830Sstevel@tonic-gate 				}
5840Sstevel@tonic-gate 			} else {
5850Sstevel@tonic-gate 				if (mtflag) {
5860Sstevel@tonic-gate 					f_print(fout,
587*10133SJordan.Brown@Sun.COM 					    "\t\t%s = (bool_t (*)())",
5880Sstevel@tonic-gate 					    ROUTINE);
5890Sstevel@tonic-gate 				} else {
590*10133SJordan.Brown@Sun.COM 					f_print(fout, "\t\t%s = (char *(*)())",
5910Sstevel@tonic-gate 					    ROUTINE);
5920Sstevel@tonic-gate 				}
5930Sstevel@tonic-gate 			}
5940Sstevel@tonic-gate 
595*10133SJordan.Brown@Sun.COM 			f_print(fout, "\n\t\t    ");
5960Sstevel@tonic-gate 			if (newstyle) { /* new style: calls internal routine */
5970Sstevel@tonic-gate 				f_print(fout, "_");
5980Sstevel@tonic-gate 			}
5990Sstevel@tonic-gate 			if ((Cflag || mtflag) && !newstyle)
6000Sstevel@tonic-gate 				pvname_svc(proc->proc_name, vp->vers_num);
6010Sstevel@tonic-gate 			else
6020Sstevel@tonic-gate 				pvname(proc->proc_name, vp->vers_num);
6030Sstevel@tonic-gate 			f_print(fout, ";\n");
6040Sstevel@tonic-gate 			f_print(fout, "\t\tbreak;\n\n");
6050Sstevel@tonic-gate 		}
6060Sstevel@tonic-gate 		f_print(fout, "\tdefault:\n");
6070Sstevel@tonic-gate 		printerr("noproc", TRANSP);
6080Sstevel@tonic-gate 		print_return("\t\t");
6090Sstevel@tonic-gate 		f_print(fout, "\t}\n");
6100Sstevel@tonic-gate 
6110Sstevel@tonic-gate 		f_print(fout,
6129497SJordan.Brown@Sun.COM 		    "\t(void) memset((char *)&%s, 0, sizeof (%s));\n",
6139497SJordan.Brown@Sun.COM 		    ARG, ARG);
614132Srobinson 		printif("getargs", TRANSP, "(caddr_t)&", ARG);
6150Sstevel@tonic-gate 		printerr("decode", TRANSP);
6160Sstevel@tonic-gate 		print_return("\t\t");
6170Sstevel@tonic-gate 		f_print(fout, "\t}\n");
6180Sstevel@tonic-gate 
6190Sstevel@tonic-gate 		if (!mtflag)
6200Sstevel@tonic-gate 			if (Cflag)
6210Sstevel@tonic-gate 				f_print(fout,
6229497SJordan.Brown@Sun.COM 				    "\t%s = (*%s)((char *)&%s, %s);\n",
6239497SJordan.Brown@Sun.COM 				    RESULT, ROUTINE, ARG, RQSTP);
6240Sstevel@tonic-gate 			else
6250Sstevel@tonic-gate 				f_print(fout, "\t%s = (*%s)(&%s, %s);\n",
6269497SJordan.Brown@Sun.COM 				    RESULT, ROUTINE, ARG, RQSTP);
6270Sstevel@tonic-gate 		else
6280Sstevel@tonic-gate 			if (Cflag)
6290Sstevel@tonic-gate 				f_print(fout,
630132Srobinson "\t%s = (bool_t)(*%s)((char *)&%s, (void *)&%s, %s);\n",
6319497SJordan.Brown@Sun.COM 				    RETVAL, ROUTINE, ARG, RESULT, RQSTP);
6320Sstevel@tonic-gate 			else
6330Sstevel@tonic-gate 				f_print(fout,
634132Srobinson "\t%s = (bool_t)(*%s)(&%s, &%s, %s);\n",
6359497SJordan.Brown@Sun.COM 				    RETVAL, ROUTINE, ARG, RESULT, RQSTP);
6360Sstevel@tonic-gate 
6370Sstevel@tonic-gate 
6380Sstevel@tonic-gate 
6390Sstevel@tonic-gate 
6400Sstevel@tonic-gate 		if (mtflag)
6410Sstevel@tonic-gate 			f_print(fout,
642*10133SJordan.Brown@Sun.COM "\tif (_xdr_%s && %s > 0 &&\n"
643*10133SJordan.Brown@Sun.COM "\t    !svc_sendreply(%s, _xdr_%s, (char *)&%s)) {\n",
6449497SJordan.Brown@Sun.COM 			    RESULT, RETVAL, TRANSP, RESULT, RESULT);
6450Sstevel@tonic-gate 		else
6460Sstevel@tonic-gate 			f_print(fout,
647*10133SJordan.Brown@Sun.COM "\tif (_xdr_%s && %s != NULL &&\n"
648*10133SJordan.Brown@Sun.COM "\t    !svc_sendreply(%s, _xdr_%s, %s)) {\n",
6499497SJordan.Brown@Sun.COM 			    RESULT, RESULT, TRANSP, RESULT, RESULT);
6500Sstevel@tonic-gate 
6510Sstevel@tonic-gate 		printerr("systemerr", TRANSP);
6520Sstevel@tonic-gate 		f_print(fout, "\t}\n");
6530Sstevel@tonic-gate 
654132Srobinson 		printif("freeargs", TRANSP, "(caddr_t)&", ARG);
655*10133SJordan.Brown@Sun.COM 		print_err_message("\t\t", "unable to free arguments");
6560Sstevel@tonic-gate 		f_print(fout, "\t\texit(1);\n");
6570Sstevel@tonic-gate 		f_print(fout, "\t}\n");
6580Sstevel@tonic-gate 		/* print out free routine */
6590Sstevel@tonic-gate 		if (mtflag) {
6600Sstevel@tonic-gate 			f_print(fout, "\tif (_xdr_%s != NULL) {\n", RESULT);
6610Sstevel@tonic-gate 			f_print(fout, "\t\tif (!");
6620Sstevel@tonic-gate 
6630Sstevel@tonic-gate 			pvname(def->def_name, vp->vers_num);
664*10133SJordan.Brown@Sun.COM 			f_print(fout, "_freeresult(%s, _xdr_%s,\n",
665*10133SJordan.Brown@Sun.COM 			    TRANSP, RESULT);
666*10133SJordan.Brown@Sun.COM 			f_print(fout, "\t\t    (caddr_t)&%s))\n",
667*10133SJordan.Brown@Sun.COM 			    RESULT);
668*10133SJordan.Brown@Sun.COM 			print_err_message("\t\t\t", "unable to free results");
6690Sstevel@tonic-gate 			f_print(fout, "\n");
6700Sstevel@tonic-gate 			f_print(fout, "\t}\n");
6710Sstevel@tonic-gate 		};
6720Sstevel@tonic-gate 		print_return("\t");
6730Sstevel@tonic-gate 		f_print(fout, "}\n");
6740Sstevel@tonic-gate 	}
6750Sstevel@tonic-gate }
6760Sstevel@tonic-gate 
677132Srobinson static void
printerr(char * err,char * transp)678132Srobinson printerr(char *err, char *transp)
6790Sstevel@tonic-gate {
6800Sstevel@tonic-gate 	f_print(fout, "\t\tsvcerr_%s(%s);\n", err, transp);
6810Sstevel@tonic-gate }
6820Sstevel@tonic-gate 
683132Srobinson static void
printif(char * proc,char * transp,char * prefix,char * arg)684132Srobinson printif(char *proc, char *transp, char *prefix, char *arg)
6850Sstevel@tonic-gate {
6860Sstevel@tonic-gate 	f_print(fout, "\tif (!svc_%s(%s, _xdr_%s, %s%s)) {\n",
6879497SJordan.Brown@Sun.COM 	    proc, transp, arg, prefix, arg);
6880Sstevel@tonic-gate }
6890Sstevel@tonic-gate 
690132Srobinson int
nullproc(proc_list * proc)691132Srobinson nullproc(proc_list *proc)
6920Sstevel@tonic-gate {
6930Sstevel@tonic-gate 	for (; proc != NULL; proc = proc->next) {
694132Srobinson 		if (streq(proc->proc_num, "0"))
6950Sstevel@tonic-gate 			return (1);
6960Sstevel@tonic-gate 	}
6970Sstevel@tonic-gate 	return (0);
6980Sstevel@tonic-gate }
6990Sstevel@tonic-gate 
700132Srobinson static void
write_inetmost(char * infile)701132Srobinson write_inetmost(char *infile)
7020Sstevel@tonic-gate {
7030Sstevel@tonic-gate 	f_print(fout, "\tregister SVCXPRT *%s;\n", TRANSP);
7040Sstevel@tonic-gate 	f_print(fout, "\tint sock;\n");
7050Sstevel@tonic-gate 	f_print(fout, "\tint proto;\n");
7060Sstevel@tonic-gate 	f_print(fout, "\tstruct sockaddr_in saddr;\n");
7070Sstevel@tonic-gate 	f_print(fout, "\tint asize = sizeof (saddr);\n");
7080Sstevel@tonic-gate 	f_print(fout, "\n");
7090Sstevel@tonic-gate 	f_print(fout,
7100Sstevel@tonic-gate 	"\tif (getsockname(0, (struct sockaddr *)&saddr, &asize) == 0) {\n");
7110Sstevel@tonic-gate 	f_print(fout, "\t\tint ssize = sizeof (int);\n\n");
7120Sstevel@tonic-gate 	f_print(fout, "\t\tif (saddr.sin_family != AF_INET)\n");
7130Sstevel@tonic-gate 	f_print(fout, "\t\t\texit(1);\n");
7140Sstevel@tonic-gate 	f_print(fout, "\t\tif (getsockopt(0, SOL_SOCKET, SO_TYPE,\n");
715*10133SJordan.Brown@Sun.COM 	f_print(fout, "\t\t    (char *)&_rpcfdtype, &ssize) == -1)\n");
7160Sstevel@tonic-gate 	f_print(fout, "\t\t\texit(1);\n");
7170Sstevel@tonic-gate 	f_print(fout, "\t\tsock = 0;\n");
7180Sstevel@tonic-gate 	f_print(fout, "\t\t_rpcpmstart = 1;\n");
7190Sstevel@tonic-gate 	f_print(fout, "\t\tproto = 0;\n");
7200Sstevel@tonic-gate 	open_log_file(infile, "\t\t");
7210Sstevel@tonic-gate 	f_print(fout, "\t} else {\n");
7220Sstevel@tonic-gate 	write_rpc_svc_fg(infile, "\t\t");
7230Sstevel@tonic-gate 	f_print(fout, "\t\tsock = RPC_ANYSOCK;\n");
7240Sstevel@tonic-gate 	print_pmapunset("\t\t");
7250Sstevel@tonic-gate 	f_print(fout, "\t}\n");
7260Sstevel@tonic-gate }
7270Sstevel@tonic-gate 
728132Srobinson static void
print_return(char * space)729132Srobinson print_return(char *space)
7300Sstevel@tonic-gate {
731132Srobinson 	if (exitnow) {
7320Sstevel@tonic-gate 		f_print(fout, "%sexit(0);\n", space);
733132Srobinson 		return;
734132Srobinson 	}
735132Srobinson 	if (timerflag) {
736*10133SJordan.Brown@Sun.COM 		if (mtflag) {
737*10133SJordan.Brown@Sun.COM 			f_print(fout,
738*10133SJordan.Brown@Sun.COM 			    "%s(void) mutex_lock(&_svcstate_lock);\n",
7399497SJordan.Brown@Sun.COM 			    space);
740*10133SJordan.Brown@Sun.COM 		}
741132Srobinson 		f_print(fout, "%s_rpcsvccount--;\n", space);
742132Srobinson 		f_print(fout, "%s_rpcsvcstate = _SERVED;\n", space);
743*10133SJordan.Brown@Sun.COM 		if (mtflag) {
744*10133SJordan.Brown@Sun.COM 			f_print(fout,
745*10133SJordan.Brown@Sun.COM 			    "%s(void) mutex_unlock(&_svcstate_lock);\n",
7469497SJordan.Brown@Sun.COM 			    space);
747*10133SJordan.Brown@Sun.COM 		}
7480Sstevel@tonic-gate 	}
749*10133SJordan.Brown@Sun.COM 	f_print(fout, "%sreturn; /* CSTYLED */\n", space);
7500Sstevel@tonic-gate }
7510Sstevel@tonic-gate 
752132Srobinson static void
print_pmapunset(char * space)753132Srobinson print_pmapunset(char *space)
7540Sstevel@tonic-gate {
7550Sstevel@tonic-gate 	list *l;
7560Sstevel@tonic-gate 	definition *def;
7570Sstevel@tonic-gate 	version_list *vp;
7580Sstevel@tonic-gate 
7590Sstevel@tonic-gate 	for (l = defined; l != NULL; l = l->next) {
760132Srobinson 		def = (definition *)l->val;
7610Sstevel@tonic-gate 		if (def->def_kind == DEF_PROGRAM) {
7620Sstevel@tonic-gate 			for (vp = def->def.pr.versions; vp != NULL;
7639497SJordan.Brown@Sun.COM 			    vp = vp->next) {
7640Sstevel@tonic-gate 				f_print(fout, "%s(void) pmap_unset(%s, %s);\n",
7659497SJordan.Brown@Sun.COM 				    space, def->def_name, vp->vers_name);
7660Sstevel@tonic-gate 			}
7670Sstevel@tonic-gate 		}
7680Sstevel@tonic-gate 	}
7690Sstevel@tonic-gate }
7700Sstevel@tonic-gate 
771132Srobinson static void
print_err_message(const char * space,const char * fmt,...)772*10133SJordan.Brown@Sun.COM print_err_message(const char *space, const char *fmt, ...)
7730Sstevel@tonic-gate {
774*10133SJordan.Brown@Sun.COM 	char errbuf[ERRBUFLEN];
775*10133SJordan.Brown@Sun.COM 	va_list va;
776*10133SJordan.Brown@Sun.COM 
777*10133SJordan.Brown@Sun.COM 	va_start(va, fmt);
778*10133SJordan.Brown@Sun.COM 	(void) vsnprintf(errbuf, sizeof (errbuf), fmt, va);
779*10133SJordan.Brown@Sun.COM 	va_end(va);
780*10133SJordan.Brown@Sun.COM 
7810Sstevel@tonic-gate 	if (logflag)
782*10133SJordan.Brown@Sun.COM 		f_print(fout, "%ssyslog(LOG_ERR, \"%%s\",\n", space);
7830Sstevel@tonic-gate 	else if (inetdflag || pmflag)
784*10133SJordan.Brown@Sun.COM 		f_print(fout, "%sRPC_MSGOUT(\"%%s\",\n", space);
7850Sstevel@tonic-gate 	else
786*10133SJordan.Brown@Sun.COM 		f_print(fout, "%sfprintf(stderr, \"%%s\",\n", space);
787*10133SJordan.Brown@Sun.COM 	f_print(fout, "%s    \"%s\");\n", space, errbuf);
7880Sstevel@tonic-gate }
7890Sstevel@tonic-gate 
7900Sstevel@tonic-gate /*
791*10133SJordan.Brown@Sun.COM  * Write the server auxiliary function (RPC_MSGOUT, timeout)
7920Sstevel@tonic-gate  */
793132Srobinson static void
write_svc_aux(int nomain)794132Srobinson write_svc_aux(int nomain)
7950Sstevel@tonic-gate {
7960Sstevel@tonic-gate 	if (!logflag)
7970Sstevel@tonic-gate 		write_msg_out();
7980Sstevel@tonic-gate 	if (!nomain)
7990Sstevel@tonic-gate 		write_timeout_func();
8000Sstevel@tonic-gate }
8010Sstevel@tonic-gate 
8020Sstevel@tonic-gate /*
803*10133SJordan.Brown@Sun.COM  * Write the RPC_MSGOUT function
804*10133SJordan.Brown@Sun.COM  *
805*10133SJordan.Brown@Sun.COM  * Note that while we define RPC_MSGOUT to be printf-like, all existing
806*10133SJordan.Brown@Sun.COM  * calls are of the form "%s","<msg>" and this implementation assumes that
807*10133SJordan.Brown@Sun.COM  * trivial case.  If in the future it's desirable to generate richer calls
808*10133SJordan.Brown@Sun.COM  * this implementation can change to match.  This way we don't (yet) have
809*10133SJordan.Brown@Sun.COM  * to introduce varargs into the generated code.
8100Sstevel@tonic-gate  */
811132Srobinson static void
write_msg_out(void)812132Srobinson write_msg_out(void)
8130Sstevel@tonic-gate {
8140Sstevel@tonic-gate 	f_print(fout, "\n");
815*10133SJordan.Brown@Sun.COM 	f_print(fout, "#if\tdefined(RPC_MSGOUT)\n");
816*10133SJordan.Brown@Sun.COM 	if (!Cflag) {
817*10133SJordan.Brown@Sun.COM 		f_print(fout, "extern void RPC_MSGOUT();\n");
818*10133SJordan.Brown@Sun.COM 	} else {
819*10133SJordan.Brown@Sun.COM 		f_print(fout, "extern void RPC_MSGOUT(const char *, ...);\n");
820*10133SJordan.Brown@Sun.COM 	}
821*10133SJordan.Brown@Sun.COM 	f_print(fout, "#else\t/* defined(RPC_MSGOUT) */\n");
822132Srobinson 	f_print(fout, "static ");
8230Sstevel@tonic-gate 	if (!Cflag) {
824*10133SJordan.Brown@Sun.COM 		f_print(fout, "void\nRPC_MSGOUT(fmt, msg)\n");
825*10133SJordan.Brown@Sun.COM 		f_print(fout, "\tchar *fmt;\n");
8260Sstevel@tonic-gate 		f_print(fout, "\tchar *msg;\n");
8270Sstevel@tonic-gate 	} else {
828*10133SJordan.Brown@Sun.COM 		f_print(fout, "void\nRPC_MSGOUT(const char *fmt, char *msg)\n");
8290Sstevel@tonic-gate 	}
8300Sstevel@tonic-gate 	f_print(fout, "{\n");
8310Sstevel@tonic-gate 	f_print(fout, "#ifdef RPC_SVC_FG\n");
8320Sstevel@tonic-gate 	if (inetdflag || pmflag)
8330Sstevel@tonic-gate 		f_print(fout, "\tif (_rpcpmstart)\n");
834*10133SJordan.Brown@Sun.COM 	f_print(fout, "\t\tsyslog(LOG_ERR, fmt, msg);\n");
835*10133SJordan.Brown@Sun.COM 	f_print(fout, "\telse {\n");
836*10133SJordan.Brown@Sun.COM 	f_print(fout, "\t\t(void) fprintf(stderr, fmt, msg);\n");
837*10133SJordan.Brown@Sun.COM 	f_print(fout, "\t\t(void) putc('\\n', stderr);\n");
838*10133SJordan.Brown@Sun.COM 	f_print(fout, "\t}\n");
8390Sstevel@tonic-gate 	f_print(fout, "#else\n");
840*10133SJordan.Brown@Sun.COM 	f_print(fout, "\tsyslog(LOG_ERR, fmt, msg);\n");
8410Sstevel@tonic-gate 	f_print(fout, "#endif\n");
8420Sstevel@tonic-gate 	f_print(fout, "}\n");
843*10133SJordan.Brown@Sun.COM 	f_print(fout, "#endif\t/* defined(RPC_MSGOUT) */\n");
8440Sstevel@tonic-gate }
8450Sstevel@tonic-gate 
8460Sstevel@tonic-gate /*
8470Sstevel@tonic-gate  * Write the timeout function
8480Sstevel@tonic-gate  */
849132Srobinson static void
write_timeout_func(void)850132Srobinson write_timeout_func(void)
8510Sstevel@tonic-gate {
8520Sstevel@tonic-gate 	if (!timerflag)
8530Sstevel@tonic-gate 		return;
8540Sstevel@tonic-gate 
8550Sstevel@tonic-gate 	f_print(fout, "\n");
8560Sstevel@tonic-gate 	if (mtflag) {
8570Sstevel@tonic-gate 		f_print(fout, "/*ARGSUSED*/\n");
8580Sstevel@tonic-gate 		f_print(fout, "static void *\n");
8590Sstevel@tonic-gate 		if (!Cflag) {
8600Sstevel@tonic-gate 			f_print(fout, "closedown(arg)\n");
8610Sstevel@tonic-gate 			f_print(fout, "\tvoid *arg;\n");
8620Sstevel@tonic-gate 		} else
8630Sstevel@tonic-gate 			f_print(fout, "closedown(void *arg)\n");
8640Sstevel@tonic-gate 		f_print(fout, "{\n");
8650Sstevel@tonic-gate 		f_print(fout, "\t/*CONSTCOND*/\n");
8660Sstevel@tonic-gate 		f_print(fout, "\twhile (1) {\n");
8670Sstevel@tonic-gate 		f_print(fout, "\t\t(void) sleep(_RPCSVC_CLOSEDOWN/2);\n\n");
8680Sstevel@tonic-gate 		f_print(fout,
8690Sstevel@tonic-gate "\t\tif (mutex_trylock(&_svcstate_lock) != 0)\n");
8700Sstevel@tonic-gate 		f_print(fout, "\t\t\tcontinue;\n\n");
8710Sstevel@tonic-gate 		f_print(fout,
8720Sstevel@tonic-gate "\t\tif (_rpcsvcstate == _IDLE && _rpcsvccount == 0) {\n");
8730Sstevel@tonic-gate 		if (tirpcflag) {
8740Sstevel@tonic-gate 			f_print(fout, "\t\t\tint size;\n");
8750Sstevel@tonic-gate 		} else {
8760Sstevel@tonic-gate 			f_print(fout, "\t\t\textern fd_set svc_fdset;\n");
8770Sstevel@tonic-gate 			f_print(fout, "\t\t\tstatic int size;\n");
8780Sstevel@tonic-gate 		}
8790Sstevel@tonic-gate 		f_print(fout, "\t\t\tint i, openfd = 0;\n\n");
8800Sstevel@tonic-gate 		if (tirpcflag) {
8810Sstevel@tonic-gate 			f_print(fout, "\t\t\tsize = svc_max_pollfd;\n");
8820Sstevel@tonic-gate 		} else {
8830Sstevel@tonic-gate 			f_print(fout, "\t\t\tif (size == 0) {\n");
8840Sstevel@tonic-gate 			f_print(fout, "\t\t\t\tsize = getdtablesize();\n");
8850Sstevel@tonic-gate 			f_print(fout, "\t\t\t}\n");
8860Sstevel@tonic-gate 		}
8870Sstevel@tonic-gate 		f_print(fout,
8880Sstevel@tonic-gate "\t\t\tfor (i = 0; i < size && openfd < 2; i++)\n");
8890Sstevel@tonic-gate 		if (tirpcflag) {
8900Sstevel@tonic-gate 			f_print(fout, "\t\t\t\tif (svc_pollfd[i].fd >= 0)\n");
8910Sstevel@tonic-gate 		} else {
8920Sstevel@tonic-gate 			f_print(fout, "\t\t\t\tif (FD_ISSET(i, &svc_fdset))\n");
8930Sstevel@tonic-gate 		}
8940Sstevel@tonic-gate 		f_print(fout, "\t\t\t\t\topenfd++;\n");
8950Sstevel@tonic-gate 		f_print(fout, "\t\t\tif (openfd <= 1)\n");
8960Sstevel@tonic-gate 		f_print(fout, "\t\t\t\texit(0);\n");
8970Sstevel@tonic-gate 		f_print(fout, "\t\t} else\n");
8980Sstevel@tonic-gate 		f_print(fout, "\t\t\t_rpcsvcstate = _IDLE;\n\n");
899*10133SJordan.Brown@Sun.COM 		f_print(fout, "\t\t(void) mutex_unlock(&_svcstate_lock);\n");
9000Sstevel@tonic-gate 		f_print(fout, "\t}\n");
9010Sstevel@tonic-gate 		f_print(fout, "}\n");
9020Sstevel@tonic-gate 		return;
9030Sstevel@tonic-gate 	}
9040Sstevel@tonic-gate 
9050Sstevel@tonic-gate 	f_print(fout, "static void\n");
9060Sstevel@tonic-gate 	if (!Cflag) {
9070Sstevel@tonic-gate 		f_print(fout, "closedown(sig)\n");
9080Sstevel@tonic-gate 		f_print(fout, "\tint sig;\n");
9090Sstevel@tonic-gate 	} else
9100Sstevel@tonic-gate 		f_print(fout, "closedown(int sig)\n");
9110Sstevel@tonic-gate 	f_print(fout, "{\n");
9120Sstevel@tonic-gate 	f_print(fout, "\tif (_rpcsvcstate == _IDLE && _rpcsvccount == 0) {\n");
9130Sstevel@tonic-gate 	if (tirpcflag) {
9140Sstevel@tonic-gate 		f_print(fout, "\t\tint size;\n");
9150Sstevel@tonic-gate 	} else {
9160Sstevel@tonic-gate 		f_print(fout, "\t\textern fd_set svc_fdset;\n");
9170Sstevel@tonic-gate 		f_print(fout, "\t\tstatic int size;\n");
9180Sstevel@tonic-gate 	}
9190Sstevel@tonic-gate 	f_print(fout, "\t\tint i, openfd = 0;\n\n");
9200Sstevel@tonic-gate 	if (tirpcflag) {
9210Sstevel@tonic-gate 		f_print(fout, "\t\tsize = svc_max_pollfd;\n");
9220Sstevel@tonic-gate 	} else {
9230Sstevel@tonic-gate 		f_print(fout, "\t\tif (size == 0) {\n");
9240Sstevel@tonic-gate 		f_print(fout, "\t\t\tsize = getdtablesize();\n");
9250Sstevel@tonic-gate 		f_print(fout, "\t\t}\n");
9260Sstevel@tonic-gate 	}
9270Sstevel@tonic-gate 	f_print(fout,
9289497SJordan.Brown@Sun.COM 	    "\t\tfor (i = 0; i < size && openfd < 2; i++)\n");
9290Sstevel@tonic-gate 	if (tirpcflag) {
9300Sstevel@tonic-gate 		f_print(fout, "\t\t\tif (svc_pollfd[i].fd >= 0)\n");
9310Sstevel@tonic-gate 	} else {
9320Sstevel@tonic-gate 		f_print(fout, "\t\t\tif (FD_ISSET(i, &svc_fdset))\n");
9330Sstevel@tonic-gate 	}
9340Sstevel@tonic-gate 	f_print(fout, "\t\t\t\topenfd++;\n");
9350Sstevel@tonic-gate 	f_print(fout, "\t\tif (openfd <= 1)\n");
9360Sstevel@tonic-gate 	f_print(fout, "\t\t\texit(0);\n");
9370Sstevel@tonic-gate 	f_print(fout, "\t} else\n");
9380Sstevel@tonic-gate 	f_print(fout, "\t\t_rpcsvcstate = _IDLE;\n\n");
9390Sstevel@tonic-gate 
9400Sstevel@tonic-gate 	f_print(fout, "\t(void) signal(SIGALRM, %s closedown);\n",
9419497SJordan.Brown@Sun.COM 	    Cflag? "(SIG_PF)" : "(void(*)())");
9420Sstevel@tonic-gate 	f_print(fout, "\t(void) alarm(_RPCSVC_CLOSEDOWN/2);\n");
9430Sstevel@tonic-gate 	f_print(fout, "}\n");
9440Sstevel@tonic-gate }
9450Sstevel@tonic-gate 
9460Sstevel@tonic-gate /*
9470Sstevel@tonic-gate  * Write the most of port monitor support
9480Sstevel@tonic-gate  */
949132Srobinson static void
write_pm_most(char * infile,int netflag)950132Srobinson write_pm_most(char *infile, int netflag)
9510Sstevel@tonic-gate {
9520Sstevel@tonic-gate 	list *l;
9530Sstevel@tonic-gate 	definition *def;
9540Sstevel@tonic-gate 	version_list *vp;
9550Sstevel@tonic-gate 
9560Sstevel@tonic-gate 	f_print(fout, "\t(void) sigset(SIGPIPE, SIG_IGN);\n\n");
9570Sstevel@tonic-gate 	f_print(fout, "\t/*\n");
9580Sstevel@tonic-gate 	f_print(fout, "\t * If stdin looks like a TLI endpoint, we assume\n");
9590Sstevel@tonic-gate 	f_print(fout, "\t * that we were started by a port monitor. If\n");
9600Sstevel@tonic-gate 	f_print(fout, "\t * t_getstate fails with TBADF, this is not a\n");
9610Sstevel@tonic-gate 	f_print(fout, "\t * TLI endpoint.\n");
9620Sstevel@tonic-gate 	f_print(fout, "\t */\n");
9630Sstevel@tonic-gate 	f_print(fout, "\tif (t_getstate(0) != -1 || t_errno != TBADF) {\n");
9640Sstevel@tonic-gate 	f_print(fout, "\t\tchar *netid;\n");
9650Sstevel@tonic-gate 	if (!netflag) {	/* Not included by -n option */
9660Sstevel@tonic-gate 		f_print(fout, "\t\tstruct netconfig *nconf = NULL;\n");
9670Sstevel@tonic-gate 		f_print(fout, "\t\tSVCXPRT *%s;\n", TRANSP);
9680Sstevel@tonic-gate 	}
9690Sstevel@tonic-gate 	if (timerflag)
9700Sstevel@tonic-gate 		f_print(fout, "\t\tint pmclose;\n");
9710Sstevel@tonic-gate /*
9720Sstevel@tonic-gate  *  Not necessary, defined in /usr/include/stdlib
9730Sstevel@tonic-gate  *  f_print(fout, "\t\textern char *getenv();\n");
9740Sstevel@tonic-gate  */
9750Sstevel@tonic-gate 	f_print(fout, "\n");
9760Sstevel@tonic-gate 	f_print(fout, "\t\t_rpcpmstart = 1;\n");
9770Sstevel@tonic-gate 	open_log_file(infile, "\t\t");
9780Sstevel@tonic-gate 	f_print(fout,
9790Sstevel@tonic-gate "\n\t\tif ((netid = getenv(\"NLSPROVIDER\")) == NULL) {\n");
9800Sstevel@tonic-gate 
9810Sstevel@tonic-gate 	if (timerflag) {
9820Sstevel@tonic-gate 		f_print(fout, "\t\t/* started from inetd */\n");
9830Sstevel@tonic-gate 		f_print(fout, "\t\t\tpmclose = 1;\n");
9840Sstevel@tonic-gate 	}
985132Srobinson 	f_print(fout, "\t\t} else {\n");
9860Sstevel@tonic-gate 	f_print(fout, "\t\t\tif ((nconf = getnetconfigent(netid)) == NULL)\n");
987*10133SJordan.Brown@Sun.COM 	print_err_message("\t\t\t\t", "cannot get transport info");
9880Sstevel@tonic-gate 	if (timerflag)
9890Sstevel@tonic-gate 		f_print(fout,
9909497SJordan.Brown@Sun.COM 		    "\n\t\t\tpmclose = (t_getstate(0) != T_DATAXFER);\n");
9910Sstevel@tonic-gate 	f_print(fout, "\t\t}\n");
9920Sstevel@tonic-gate 	f_print(fout,
9930Sstevel@tonic-gate "\t\tif ((%s = svc_tli_create(0, nconf, NULL, 0, 0)) == NULL) {\n",
9949497SJordan.Brown@Sun.COM 	    TRANSP);
995*10133SJordan.Brown@Sun.COM 	print_err_message("\t\t\t", "cannot create server handle");
9960Sstevel@tonic-gate 	f_print(fout, "\t\t\texit(1);\n");
9970Sstevel@tonic-gate 	f_print(fout, "\t\t}\n");
9980Sstevel@tonic-gate 	f_print(fout, "\t\tif (nconf)\n");
9990Sstevel@tonic-gate 	f_print(fout, "\t\t\tfreenetconfigent(nconf);\n");
10000Sstevel@tonic-gate 	for (l = defined; l != NULL; l = l->next) {
10010Sstevel@tonic-gate 		def = (definition *) l->val;
10020Sstevel@tonic-gate 		if (def->def_kind != DEF_PROGRAM) {
10030Sstevel@tonic-gate 			continue;
10040Sstevel@tonic-gate 		}
10050Sstevel@tonic-gate 		for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
10060Sstevel@tonic-gate 			f_print(fout,
1007*10133SJordan.Brown@Sun.COM 			    "\t\tif (!svc_reg(%s, %s, %s,\n",
10089497SJordan.Brown@Sun.COM 			    TRANSP, def->def_name, vp->vers_name);
1009*10133SJordan.Brown@Sun.COM 			f_print(fout, "\t\t    ");
10100Sstevel@tonic-gate 			pvname(def->def_name, vp->vers_num);
10110Sstevel@tonic-gate 			f_print(fout, ", 0)) {\n");
1012*10133SJordan.Brown@Sun.COM 			print_err_message("\t\t\t",
10139497SJordan.Brown@Sun.COM 			    "unable to register (%s, %s).",
10149497SJordan.Brown@Sun.COM 			    def->def_name, vp->vers_name);
10150Sstevel@tonic-gate 			f_print(fout, "\t\t\texit(1);\n");
10160Sstevel@tonic-gate 			f_print(fout, "\t\t}\n");
10170Sstevel@tonic-gate 		}
10180Sstevel@tonic-gate 	}
10190Sstevel@tonic-gate 	if (timerflag) {
10200Sstevel@tonic-gate 		f_print(fout, "\t\tif (pmclose) {\n");
10210Sstevel@tonic-gate 		if (mtflag) {
10220Sstevel@tonic-gate 			f_print(fout,
1023*10133SJordan.Brown@Sun.COM "\t\t\tif (thr_create(NULL, 0, closedown, NULL,\n\t\t\t    0, NULL) != 0) {\n");
1024*10133SJordan.Brown@Sun.COM 			print_err_message("\t\t\t\t",
1025*10133SJordan.Brown@Sun.COM 			    "cannot create closedown thread");
10260Sstevel@tonic-gate 			f_print(fout, "\t\t\t\texit(1);\n");
10270Sstevel@tonic-gate 			f_print(fout, "\t\t\t}\n");
10280Sstevel@tonic-gate 		} else {
10290Sstevel@tonic-gate 			f_print(fout,
10300Sstevel@tonic-gate "\t\t\t(void) signal(SIGALRM, %s closedown);\n",
10319497SJordan.Brown@Sun.COM 			    Cflag? "(SIG_PF)" : "(void(*)())");
10320Sstevel@tonic-gate 			f_print(fout,
10330Sstevel@tonic-gate "\t\t\t(void) alarm(_RPCSVC_CLOSEDOWN/2);\n");
10340Sstevel@tonic-gate 		}
10350Sstevel@tonic-gate 		f_print(fout, "\t\t}\n");
10360Sstevel@tonic-gate 	}
10370Sstevel@tonic-gate 	f_print(fout, "\t\tsvc_run();\n");
10380Sstevel@tonic-gate 	f_print(fout, "\t\texit(1);\n");
10390Sstevel@tonic-gate 	f_print(fout, "\t\t/* NOTREACHED */\n");
10400Sstevel@tonic-gate 	f_print(fout, "\t}");
10410Sstevel@tonic-gate }
10420Sstevel@tonic-gate 
10430Sstevel@tonic-gate /*
10440Sstevel@tonic-gate  * Support for backgrounding the server if self started.
10450Sstevel@tonic-gate  */
1046132Srobinson static void
write_rpc_svc_fg(char * infile,char * sp)1047132Srobinson write_rpc_svc_fg(char *infile, char *sp)
10480Sstevel@tonic-gate {
10490Sstevel@tonic-gate 	f_print(fout, "#ifndef RPC_SVC_FG\n");
10500Sstevel@tonic-gate 	f_print(fout, "#pragma weak closefrom\n");
10510Sstevel@tonic-gate 	f_print(fout, "%sextern void closefrom();\n", sp);
10520Sstevel@tonic-gate 	f_print(fout, "%sint size;\n", sp);
10530Sstevel@tonic-gate 	if (tirpcflag)
10540Sstevel@tonic-gate 		f_print(fout, "%sstruct rlimit rl;\n", sp);
10550Sstevel@tonic-gate 	if (inetdflag)
10560Sstevel@tonic-gate 		f_print(fout, "%sint pid, i;\n\n", sp);
10570Sstevel@tonic-gate 	f_print(fout, "%spid = fork();\n", sp);
10580Sstevel@tonic-gate 	f_print(fout, "%sif (pid < 0) {\n", sp);
10590Sstevel@tonic-gate 	f_print(fout, "%s\tperror(\"cannot fork\");\n", sp);
10600Sstevel@tonic-gate 	f_print(fout, "%s\texit(1);\n", sp);
10610Sstevel@tonic-gate 	f_print(fout, "%s}\n", sp);
10620Sstevel@tonic-gate 	f_print(fout, "%sif (pid)\n", sp);
10630Sstevel@tonic-gate 	f_print(fout, "%s\texit(0);\n", sp);
10640Sstevel@tonic-gate 	/* close all file descriptors */
10650Sstevel@tonic-gate 	if (tirpcflag) {
10660Sstevel@tonic-gate 		f_print(fout, "%sif (closefrom != NULL)\n", sp);
10670Sstevel@tonic-gate 		f_print(fout, "%s\tclosefrom(0);\n", sp);
10680Sstevel@tonic-gate 		f_print(fout, "%selse {\n", sp);
10690Sstevel@tonic-gate 		f_print(fout, "%s\trl.rlim_max = 0;\n", sp);
10700Sstevel@tonic-gate 		f_print(fout, "%s\tgetrlimit(RLIMIT_NOFILE, &rl);\n", sp);
10710Sstevel@tonic-gate 		f_print(fout, "%s\tif ((size = rl.rlim_max) == 0)\n", sp);
10720Sstevel@tonic-gate 		f_print(fout, "%s\t\texit(1);\n", sp);
10730Sstevel@tonic-gate 		f_print(fout, "%s\tfor (i = 0; i < size; i++)\n", sp);
10740Sstevel@tonic-gate 		f_print(fout, "%s\t\t(void) close(i);\n", sp);
10750Sstevel@tonic-gate 		f_print(fout, "%s}\n", sp);
10760Sstevel@tonic-gate 	} else {
10770Sstevel@tonic-gate 		f_print(fout, "%s\tsize = getdtablesize();\n", sp);
10780Sstevel@tonic-gate 		f_print(fout, "%s\tfor (i = 0; i < size; i++)\n", sp);
10790Sstevel@tonic-gate 		f_print(fout, "%s\t\t(void) close(i);\n", sp);
10800Sstevel@tonic-gate 	}
10810Sstevel@tonic-gate 	/* Redirect stderr and stdout to /dev/null */
10820Sstevel@tonic-gate 	f_print(fout, "%si = open(\"/dev/null\", 2);\n", sp);
10830Sstevel@tonic-gate 	f_print(fout, "%s(void) dup2(i, 1);\n", sp);
10840Sstevel@tonic-gate 	f_print(fout, "%s(void) dup2(i, 2);\n", sp);
10850Sstevel@tonic-gate 	/* This removes control of the controlling terminal */
10860Sstevel@tonic-gate 	if (tirpcflag)
10870Sstevel@tonic-gate 		f_print(fout, "%ssetsid();\n", sp);
10880Sstevel@tonic-gate 	else {
10890Sstevel@tonic-gate 		f_print(fout, "%si = open(\"/dev/tty\", 2);\n", sp);
10900Sstevel@tonic-gate 		f_print(fout, "%sif (i >= 0) {\n", sp);
10910Sstevel@tonic-gate 		f_print(fout,
10929497SJordan.Brown@Sun.COM 		    "%s\t(void) ioctl(i, TIOCNOTTY, (char *)NULL);\n", sp);
10930Sstevel@tonic-gate 		f_print(fout, "%s\t(void) close(i);\n", sp);
10940Sstevel@tonic-gate 		f_print(fout, "%s}\n", sp);
10950Sstevel@tonic-gate 	}
10960Sstevel@tonic-gate 	if (!logflag)
10970Sstevel@tonic-gate 		open_log_file(infile, sp);
10980Sstevel@tonic-gate 	f_print(fout, "#endif\n");
10990Sstevel@tonic-gate 	if (logflag)
11000Sstevel@tonic-gate 		open_log_file(infile, sp);
11010Sstevel@tonic-gate }
11020Sstevel@tonic-gate 
1103132Srobinson static void
open_log_file(char * infile,char * sp)1104132Srobinson open_log_file(char *infile, char *sp)
11050Sstevel@tonic-gate {
11060Sstevel@tonic-gate 	char *s;
11070Sstevel@tonic-gate 
11080Sstevel@tonic-gate 	s = strrchr(infile, '.');
11090Sstevel@tonic-gate 	if (s)
11100Sstevel@tonic-gate 		*s = '\0';
11110Sstevel@tonic-gate 	f_print(fout, "%sopenlog(\"%s\", LOG_PID, LOG_DAEMON);\n", sp, infile);
11120Sstevel@tonic-gate 	if (s)
11130Sstevel@tonic-gate 		*s = '.';
11140Sstevel@tonic-gate }
11150Sstevel@tonic-gate 
11160Sstevel@tonic-gate /*
11170Sstevel@tonic-gate  * write a registration for the given transport for Inetd
11180Sstevel@tonic-gate  */
11190Sstevel@tonic-gate void
write_inetd_register(char * transp)1120132Srobinson write_inetd_register(char *transp)
11210Sstevel@tonic-gate {
11220Sstevel@tonic-gate 	list *l;
11230Sstevel@tonic-gate 	definition *def;
11240Sstevel@tonic-gate 	version_list *vp;
11250Sstevel@tonic-gate 	char *sp;
11260Sstevel@tonic-gate 	int isudp;
11270Sstevel@tonic-gate 	char tmpbuf[32];
11280Sstevel@tonic-gate 
11290Sstevel@tonic-gate 	if (inetdflag)
11300Sstevel@tonic-gate 		sp = "\t";
11310Sstevel@tonic-gate 	else
11320Sstevel@tonic-gate 		sp = "";
11330Sstevel@tonic-gate 	if (streq(transp, "udp"))
11340Sstevel@tonic-gate 		isudp = 1;
11350Sstevel@tonic-gate 	else
11360Sstevel@tonic-gate 		isudp = 0;
11370Sstevel@tonic-gate 	f_print(fout, "\n");
11380Sstevel@tonic-gate 	if (inetdflag) {
11390Sstevel@tonic-gate 		f_print(fout,
11409497SJordan.Brown@Sun.COM 		    "\tif ((_rpcfdtype == 0) || (_rpcfdtype == %s)) {\n",
11419497SJordan.Brown@Sun.COM 		    isudp ? "SOCK_DGRAM" : "SOCK_STREAM");
11420Sstevel@tonic-gate 	}
11430Sstevel@tonic-gate 	f_print(fout, "%s\t%s = svc%s_create(%s",
11449497SJordan.Brown@Sun.COM 	    sp, TRANSP, transp, inetdflag? "sock": "RPC_ANYSOCK");
11450Sstevel@tonic-gate 	if (!isudp)
11460Sstevel@tonic-gate 		f_print(fout, ", 0, 0");
11470Sstevel@tonic-gate 	f_print(fout, ");\n");
11480Sstevel@tonic-gate 	f_print(fout, "%s\tif (%s == NULL) {\n", sp, TRANSP);
1149132Srobinson 	(void) snprintf(tmpbuf, sizeof (tmpbuf), "%s\t\t", sp);
1150*10133SJordan.Brown@Sun.COM 	print_err_message(tmpbuf, "cannot create %s service.", transp);
11510Sstevel@tonic-gate 	f_print(fout, "%s\t\texit(1);\n", sp);
11520Sstevel@tonic-gate 	f_print(fout, "%s\t}\n", sp);
11530Sstevel@tonic-gate 
11540Sstevel@tonic-gate 	if (inetdflag) {
11550Sstevel@tonic-gate 		f_print(fout, "%s\tif (!_rpcpmstart)\n\t", sp);
11560Sstevel@tonic-gate 		f_print(fout, "%s\tproto = IPPROTO_%s;\n",
11579497SJordan.Brown@Sun.COM 		    sp, isudp ? "UDP": "TCP");
11580Sstevel@tonic-gate 	}
11590Sstevel@tonic-gate 	for (l = defined; l != NULL; l = l->next) {
11600Sstevel@tonic-gate 		def = (definition *) l->val;
1161132Srobinson 		if (def->def_kind != DEF_PROGRAM)
11620Sstevel@tonic-gate 			continue;
11630Sstevel@tonic-gate 		for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
1164*10133SJordan.Brown@Sun.COM 			f_print(fout, "%s\tif (!svc_register(%s, %s, %s,\n",
11659497SJordan.Brown@Sun.COM 			    sp, TRANSP, def->def_name, vp->vers_name);
1166*10133SJordan.Brown@Sun.COM 			f_print(fout, "%s\t    ", sp);
11670Sstevel@tonic-gate 			pvname(def->def_name, vp->vers_num);
11680Sstevel@tonic-gate 			if (inetdflag)
11690Sstevel@tonic-gate 				f_print(fout, ", proto)) {\n");
11700Sstevel@tonic-gate 			else
11710Sstevel@tonic-gate 				f_print(fout, ", IPPROTO_%s)) {\n",
11729497SJordan.Brown@Sun.COM 				    isudp ? "UDP": "TCP");
1173*10133SJordan.Brown@Sun.COM 			print_err_message(tmpbuf,
11749497SJordan.Brown@Sun.COM 			    "unable to register (%s, %s, %s).",
11759497SJordan.Brown@Sun.COM 			    def->def_name, vp->vers_name, transp);
11760Sstevel@tonic-gate 			f_print(fout, "%s\t\texit(1);\n", sp);
11770Sstevel@tonic-gate 			f_print(fout, "%s\t}\n", sp);
11780Sstevel@tonic-gate 		}
11790Sstevel@tonic-gate 	}
11800Sstevel@tonic-gate 	if (inetdflag)
11810Sstevel@tonic-gate 		f_print(fout, "\t}\n");
11820Sstevel@tonic-gate }
1183