2 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
3 * unrestricted use provided that this legend is included on all tape
4 * media and as a part of the software program in whole or part. Users
5 * may copy or modify Sun RPC without charge, but are not authorized
6 * to license or distribute it to anyone else except as part of a product or
7 * program developed by the user or with the express written consent of
8 * Sun Microsystems, Inc.
10 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
11 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
12 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
14 * Sun RPC is provided with no support and without any obligation on the
15 * part of Sun Microsystems, Inc. to assist in its use, correction,
16 * modification or enhancement.
18 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
19 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
20 * OR ANY PART THEREOF.
22 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
23 * or profits or other special, indirect and consequential damages, even if
24 * Sun has been advised of the possibility of such damages.
26 * Sun Microsystems, Inc.
28 * Mountain View, California 94043
32 * From: @(#)rpc_svcout.c 1.29 89/03/30 (C) 1987 SMI
38 * rpc_svcout.c, Server-skeleton outputter for the RPC protocol compiler
42 #include "rpc_parse.h"
46 static char RQSTP
[] = "rqstp";
47 static char TRANSP
[] = "transp";
48 static char ARG
[] = "argument";
49 static char RESULT
[] = "result";
50 static char ROUTINE
[] = "local";
52 char _errbuf
[256]; /* For all messages */
54 static void internal_proctype(proc_list
*plist
);
55 static void p_xdrfunc(const char *rname
, const char *typename
);
56 static void write_real_program(definition
*def
);
57 static void write_program(definition
*def
, const char *storage
);
58 static void printerr(const char *err
, const char *transp
);
59 static void printif(const char *proc
, const char *transp
,
60 const char *prefix
, const char *arg
);
61 static void write_inetmost(const char *infile
);
62 static void print_return(const char *space
);
63 static void print_pmapunset(const char *space
);
64 static void print_err_message(const char *space
);
65 static void write_timeout_func(void);
66 static void write_pm_most(const char *infile
, int netflag
);
67 static void write_rpc_svc_fg(const char *infile
, const char *sp
);
68 static void open_log_file(const char *infile
, const char *sp
);
71 p_xdrfunc(const char *rname
, const char *typename
)
74 f_print(fout
, "\t\txdr_%s = (xdrproc_t) xdr_%s;\n", rname
,
75 stringfix(typename
) );
77 f_print(fout
, "\t\txdr_%s = xdr_%s;\n", rname
, stringfix(typename
) );
81 internal_proctype(proc_list
*plist
)
83 f_print(fout
, "static ");
84 ptype( plist
->res_prefix
, plist
->res_type
, 1 );
90 * write most of the service, that is, everything but the registrations.
93 write_most(const char *infile
/* our name */, int netflag
, int nomain
)
95 if (inetdflag
|| pmflag
) {
97 #ifdef __GNU_LIBRARY__
99 var_type
= (nomain
? "extern" : "");
101 var_type
= (nomain
? "extern" : "static");
103 f_print(fout
, "%s int _rpcpmstart;", var_type
);
104 f_print(fout
, "\t\t/* Started by a port monitor ? */\n");
105 f_print(fout
, "%s int _rpcfdtype;", var_type
);
106 f_print(fout
, "\t\t/* Whether Stream or Datagram ? */\n");
108 f_print(fout
, "%s int _rpcsvcdirty;", var_type
);
109 f_print(fout
, "\t/* Still serving ? */\n");
111 write_svc_aux( nomain
);
113 /* write out dispatcher and stubs */
114 write_programs(nomain
? NULL
: "static");
119 #ifdef __GNU_LIBRARY__
121 f_print(fout
, "\nint\nmain(int argc, char **argv)\n");
123 f_print(fout
, "\nint\nmain(argc, argv)\n");
124 f_print(fout
, "\tint argc;\n");
125 f_print(fout
, "\tchar **argv;\n");
128 f_print(fout
, "\nmain()\n");
130 f_print(fout
, "{\n");
132 write_inetmost(infile
); /* Includes call to write_rpc_svc_fg() */
136 f_print(fout
, "\tregister SVCXPRT *%s;\n", TRANSP
);
137 f_print(fout
, "\tstruct netconfig *nconf = NULL;\n");
139 f_print(fout
, "\tpid_t pid;\n");
140 f_print(fout
, "\tint i;\n");
141 f_print(fout
, "\tchar mname[FMNAMESZ + 1];\n\n");
142 write_pm_most(infile
, netflag
);
143 f_print(fout
, "\telse {\n");
144 write_rpc_svc_fg(infile
, "\t\t");
145 f_print(fout
, "\t}\n");
147 f_print(fout
, "\tregister SVCXPRT *%s;\n", TRANSP
);
149 print_pmapunset("\t");
153 if (logflag
&& !inetdflag
) {
154 open_log_file(infile
, "\t");
159 * write a registration for the given transport
162 write_netid_register(const char *transp
)
172 f_print(fout
, "%s\tnconf = getnetconfigent(\"%s\");\n", sp
, transp
);
173 f_print(fout
, "%s\tif (nconf == NULL) {\n", sp
);
174 (void) sprintf(_errbuf
, "cannot find %s netid.", transp
);
175 sprintf(tmpbuf
, "%s\t\t", sp
);
176 print_err_message(tmpbuf
);
177 f_print(fout
, "%s\t\texit(1);\n", sp
);
178 f_print(fout
, "%s\t}\n", sp
);
179 f_print(fout
, "%s\t%s = svc_tli_create(RPC_ANYFD, nconf, 0, 0, 0);\n",
180 sp
, TRANSP
/*, transp*/ /* ?!?... */ );
181 f_print(fout
, "%s\tif (%s == NULL) {\n", sp
, TRANSP
);
182 (void) sprintf(_errbuf
, "cannot create %s service.", transp
);
183 print_err_message(tmpbuf
);
184 f_print(fout
, "%s\t\texit(1);\n", sp
);
185 f_print(fout
, "%s\t}\n", sp
);
187 for (l
= defined
; l
!= NULL
; l
= l
->next
) {
188 def
= (definition
*) l
->val
;
189 if (def
->def_kind
!= DEF_PROGRAM
) {
192 for (vp
= def
->def
.pr
.versions
; vp
!= NULL
; vp
= vp
->next
) {
194 "%s\t(void) rpcb_unset(%s, %s, nconf);\n",
195 sp
, def
->def_name
, vp
->vers_name
);
197 "%s\tif (!svc_reg(%s, %s, %s, ",
198 sp
, TRANSP
, def
->def_name
, vp
->vers_name
);
199 pvname(def
->def_name
, vp
->vers_num
);
200 f_print(fout
, ", nconf)) {\n");
201 (void) sprintf(_errbuf
, "unable to register (%s, %s, %s).",
202 def
->def_name
, vp
->vers_name
, transp
);
203 print_err_message(tmpbuf
);
204 f_print(fout
, "%s\t\texit(1);\n", sp
);
205 f_print(fout
, "%s\t}\n", sp
);
208 f_print(fout
, "%s\tfreenetconfigent(nconf);\n", sp
);
212 * write a registration for the given transport for TLI
215 write_nettype_register(const char *transp
)
221 for (l
= defined
; l
!= NULL
; l
= l
->next
) {
222 def
= (definition
*) l
->val
;
223 if (def
->def_kind
!= DEF_PROGRAM
) {
226 for (vp
= def
->def
.pr
.versions
; vp
!= NULL
; vp
= vp
->next
) {
227 f_print(fout
, "\tif (!svc_create(");
228 pvname(def
->def_name
, vp
->vers_num
);
229 f_print(fout
, ", %s, %s, \"%s\")) {\n ",
230 def
->def_name
, vp
->vers_name
, transp
);
231 (void) sprintf(_errbuf
,
232 "unable to create (%s, %s) for %s.",
233 def
->def_name
, vp
->vers_name
, transp
);
234 print_err_message("\t\t");
235 f_print(fout
, "\t\texit(1);\n");
236 f_print(fout
, "\t}\n");
242 * write the rest of the service
249 f_print(fout
, "\tif (%s == (SVCXPRT *)NULL) {\n", TRANSP
);
250 (void) sprintf(_errbuf
, "could not create a handle");
251 print_err_message("\t\t");
252 f_print(fout
, "\t\texit(1);\n");
253 f_print(fout
, "\t}\n");
255 f_print(fout
, "\tif (_rpcpmstart) {\n");
257 "\t\t(void) signal(SIGALRM, %s closedown);\n",
258 Cflag
? "(SIG_PF)" : "(void(*)())" );
259 f_print(fout
, "\t\t(void) alarm(_RPCSVC_CLOSEDOWN);\n");
260 f_print(fout
, "\t}\n");
263 f_print(fout
, "\tsvc_run();\n");
264 (void) sprintf(_errbuf
, "svc_run returned");
265 print_err_message("\t");
266 f_print(fout
, "\texit(1);\n");
267 f_print(fout
, "\t/* NOTREACHED */\n");
268 f_print(fout
, "}\n");
272 write_programs(const char *storage
)
277 /* write out stubs for procedure definitions */
278 for (l
= defined
; l
!= NULL
; l
= l
->next
) {
279 def
= (definition
*) l
->val
;
280 if (def
->def_kind
== DEF_PROGRAM
) {
281 write_real_program(def
);
285 /* write out dispatcher for each program */
286 for (l
= defined
; l
!= NULL
; l
= l
->next
) {
287 def
= (definition
*) l
->val
;
288 if (def
->def_kind
== DEF_PROGRAM
) {
289 write_program(def
, storage
);
296 /* write out definition of internal function (e.g. _printmsg_1(...))
297 which calls server's defintion of actual function (e.g. printmsg_1(...)).
298 Unpacks single user argument of printmsg_1 to call-by-value format
299 expected by printmsg_1. */
301 write_real_program(definition
*def
)
307 if( !newstyle
) return; /* not needed for old style */
308 for (vp
= def
->def
.pr
.versions
; vp
!= NULL
; vp
= vp
->next
) {
309 for (proc
= vp
->procs
; proc
!= NULL
; proc
= proc
->next
) {
311 internal_proctype(proc
);
312 f_print(fout
, "\n_");
313 pvname(proc
->proc_name
, vp
->vers_num
);
317 if (proc
->arg_num
> 1)
318 f_print(fout
, proc
->args
.argname
);
320 ptype(proc
->args
.decls
->decl
.prefix
,
321 proc
->args
.decls
->decl
.type
, 0);
322 f_print(fout
, " *argp, struct svc_req *%s)\n",
325 f_print(fout
, "(argp, %s)\n", RQSTP
);
327 if (proc
->arg_num
> 1)
328 f_print(fout
, "\t%s *argp;\n", proc
->args
.argname
);
331 ptype(proc
->args
.decls
->decl
.prefix
,
332 proc
->args
.decls
->decl
.type
, 0);
333 f_print(fout
, " *argp;\n");
335 f_print(fout
, " struct svc_req *%s;\n", RQSTP
);
338 f_print(fout
, "{\n");
339 f_print(fout
, "\treturn(");
341 pvname_svc(proc
->proc_name
, vp
->vers_num
);
343 pvname(proc
->proc_name
, vp
->vers_num
);
345 if (proc
->arg_num
< 2) { /* single argument */
346 if (!streq( proc
->args
.decls
->decl
.type
, "void"))
347 f_print(fout
, "*argp, "); /* non-void */
349 for (l
= proc
->args
.decls
; l
!= NULL
; l
= l
->next
)
350 f_print(fout
, "argp->%s, ", l
->decl
.name
);
352 f_print(fout
, "%s));\n}\n", RQSTP
);
358 write_program(definition
*def
, const char *storage
)
364 for (vp
= def
->def
.pr
.versions
; vp
!= NULL
; vp
= vp
->next
) {
366 if (storage
!= NULL
) {
367 f_print(fout
, "%s ", storage
);
369 f_print(fout
, "void\n");
370 pvname(def
->def_name
, vp
->vers_num
);
373 f_print(fout
, "(struct svc_req *%s, ", RQSTP
);
374 f_print(fout
, "register SVCXPRT *%s)\n", TRANSP
);
376 f_print(fout
, "(%s, %s)\n", RQSTP
, TRANSP
);
377 f_print(fout
, " struct svc_req *%s;\n", RQSTP
);
378 f_print(fout
, " register SVCXPRT *%s;\n", TRANSP
);
381 f_print(fout
, "{\n");
384 f_print(fout
, "\tunion {\n");
385 for (proc
= vp
->procs
; proc
!= NULL
; proc
= proc
->next
) {
386 if (proc
->arg_num
< 2) { /* single argument */
387 if (streq(proc
->args
.decls
->decl
.type
,
392 f_print(fout
, "\t\t");
393 ptype(proc
->args
.decls
->decl
.prefix
,
394 proc
->args
.decls
->decl
.type
, 0);
395 pvname(proc
->proc_name
, vp
->vers_num
);
396 f_print(fout
, "_arg;\n");
401 f_print(fout
, "\t\t%s", proc
->args
.argname
);
403 pvname(proc
->proc_name
, vp
->vers_num
);
404 f_print(fout
, "_arg;\n");
408 f_print(fout
, "\t\tint fill;\n");
410 f_print(fout
, "\t} %s;\n", ARG
);
411 f_print(fout
, "\tchar *%s;\n", RESULT
);
414 f_print(fout
, "\txdrproc_t xdr_%s, xdr_%s;\n", ARG
, RESULT
);
416 "\tchar *(*%s)(char *, struct svc_req *);\n",
419 f_print(fout
, "\tbool_t (*xdr_%s)(), (*xdr_%s)();\n", ARG
, RESULT
);
420 f_print(fout
, "\tchar *(*%s)();\n", ROUTINE
);
426 f_print(fout
, "\t_rpcsvcdirty = 1;\n");
427 f_print(fout
, "\tswitch (%s->rq_proc) {\n", RQSTP
);
428 if (!nullproc(vp
->procs
)) {
429 f_print(fout
, "\tcase NULLPROC:\n");
432 ? "\t\t(void) svc_sendreply(%s, (xdrproc_t) xdr_void, (char *)NULL);\n"
433 : "\t\t(void) svc_sendreply(%s, xdr_void, (char *)NULL);\n",
435 print_return("\t\t");
438 for (proc
= vp
->procs
; proc
!= NULL
; proc
= proc
->next
) {
439 f_print(fout
, "\tcase %s:\n", proc
->proc_name
);
440 if (proc
->arg_num
< 2) { /* single argument */
441 p_xdrfunc( ARG
, proc
->args
.decls
->decl
.type
);
443 p_xdrfunc( ARG
, proc
->args
.argname
);
445 p_xdrfunc( RESULT
, proc
->res_type
);
448 "\t\t%s = (char *(*)(char *, struct svc_req *)) ",
451 f_print(fout
, "\t\t%s = (char *(*)()) ", ROUTINE
);
453 if (newstyle
) { /* new style: calls internal routine */
456 if( Cflag
&& !newstyle
)
457 pvname_svc(proc
->proc_name
, vp
->vers_num
);
459 pvname(proc
->proc_name
, vp
->vers_num
);
460 f_print(fout
, ";\n");
461 f_print(fout
, "\t\tbreak;\n\n");
463 f_print(fout
, "\tdefault:\n");
464 printerr("noproc", TRANSP
);
465 print_return("\t\t");
466 f_print(fout
, "\t}\n");
468 f_print(fout
, "\t(void) memset((char *)&%s, 0, sizeof (%s));\n", ARG
, ARG
);
470 printif("getargs", TRANSP
, "(caddr_t) &", ARG
);
472 printif("getargs", TRANSP
, "&", ARG
);
473 printerr("decode", TRANSP
);
474 print_return("\t\t");
475 f_print(fout
, "\t}\n");
478 f_print(fout
, "\t%s = (*%s)((char *)&%s, %s);\n",
479 RESULT
, ROUTINE
, ARG
, RQSTP
);
481 f_print(fout
, "\t%s = (*%s)(&%s, %s);\n",
482 RESULT
, ROUTINE
, ARG
, RQSTP
);
484 "\tif (%s != NULL && !svc_sendreply(%s, xdr_%s, %s)) {\n",
485 RESULT
, TRANSP
, RESULT
, RESULT
);
486 printerr("systemerr", TRANSP
);
487 f_print(fout
, "\t}\n");
490 printif("freeargs", TRANSP
, "(caddr_t) &", ARG
);
492 printif("freeargs", TRANSP
, "&", ARG
);
493 (void) sprintf(_errbuf
, "unable to free arguments");
494 print_err_message("\t\t");
495 f_print(fout
, "\t\texit(1);\n");
496 f_print(fout
, "\t}\n");
498 f_print(fout
, "}\n");
503 printerr(const char *err
, const char *transp
)
505 f_print(fout
, "\t\tsvcerr_%s(%s);\n", err
, transp
);
509 printif(const char *proc
, const char *transp
, const char *prefix
,
512 f_print(fout
, "\tif (!svc_%s(%s, xdr_%s, %s%s)) {\n",
513 proc
, transp
, arg
, prefix
, arg
);
517 nullproc(proc_list
*proc
)
519 for (; proc
!= NULL
; proc
= proc
->next
) {
520 if (streq(proc
->proc_num
, "0")) {
528 write_inetmost(const char *infile
)
530 f_print(fout
, "\tregister SVCXPRT *%s;\n", TRANSP
);
531 f_print(fout
, "\tint sock;\n");
532 f_print(fout
, "\tint proto;\n");
533 f_print(fout
, "\tstruct sockaddr_in saddr;\n");
534 f_print(fout
, "\tint asize = sizeof (saddr);\n");
537 "\tif (getsockname(0, (struct sockaddr *)&saddr, &asize) == 0) {\n");
538 f_print(fout
, "\t\tint ssize = sizeof (int);\n\n");
539 f_print(fout
, "\t\tif (saddr.sin_family != AF_INET)\n");
540 f_print(fout
, "\t\t\texit(1);\n");
541 f_print(fout
, "\t\tif (getsockopt(0, SOL_SOCKET, SO_TYPE,\n");
542 f_print(fout
, "\t\t\t\t(char *)&_rpcfdtype, &ssize) == -1)\n");
543 f_print(fout
, "\t\t\texit(1);\n");
544 f_print(fout
, "\t\tsock = 0;\n");
545 f_print(fout
, "\t\t_rpcpmstart = 1;\n");
546 f_print(fout
, "\t\tproto = 0;\n");
547 open_log_file(infile
, "\t\t");
548 f_print(fout
, "\t} else {\n");
549 write_rpc_svc_fg(infile
, "\t\t");
550 f_print(fout
, "\t\tsock = RPC_ANYSOCK;\n");
551 print_pmapunset("\t\t");
552 f_print(fout
, "\t}\n");
556 print_return(const char *space
)
559 f_print(fout
, "%sexit(0);\n", space
);
562 f_print(fout
, "%s_rpcsvcdirty = 0;\n", space
);
563 f_print(fout
, "%sreturn;\n", space
);
568 print_pmapunset(const char *space
)
574 for (l
= defined
; l
!= NULL
; l
= l
->next
) {
575 def
= (definition
*) l
->val
;
576 if (def
->def_kind
== DEF_PROGRAM
) {
577 for (vp
= def
->def
.pr
.versions
; vp
!= NULL
;
579 f_print(fout
, "%s(void) pmap_unset(%s, %s);\n",
580 space
, def
->def_name
, vp
->vers_name
);
587 print_err_message(const char *space
)
590 f_print(fout
, "%ssyslog(LOG_ERR, \"%s\");\n", space
, _errbuf
);
591 else if (inetdflag
|| pmflag
)
592 f_print(fout
, "%s_msgout(\"%s\");\n", space
, _errbuf
);
594 f_print(fout
, "%sfprintf(stderr, \"%s\");\n", space
, _errbuf
);
598 * Write the server auxiliary function ( _msgout, timeout)
601 write_svc_aux(int nomain
)
606 write_timeout_func();
610 * Write the _msgout function
617 f_print(fout
, "static\n");
619 f_print(fout
, "void _msgout(msg)\n");
620 f_print(fout
, "\tchar *msg;\n");
622 f_print(fout
, "void _msgout(char* msg)\n");
624 f_print(fout
, "{\n");
625 f_print(fout
, "#ifdef RPC_SVC_FG\n");
626 if (inetdflag
|| pmflag
)
627 f_print(fout
, "\tif (_rpcpmstart)\n");
628 f_print(fout
, "\t\tsyslog(LOG_ERR, msg);\n");
629 f_print(fout
, "\telse\n");
630 f_print(fout
, "\t\t(void) fprintf(stderr, \"%%s\\n\", msg);\n");
631 f_print(fout
, "#else\n");
632 f_print(fout
, "\tsyslog(LOG_ERR, msg);\n");
633 f_print(fout
, "#endif\n");
634 f_print(fout
, "}\n");
638 * Write the timeout function
641 write_timeout_func(void)
646 f_print(fout
, "static void\n");
647 #ifdef __GNU_LIBRARY__
649 f_print(fout
, "closedown(int sig)\n");
651 f_print(fout
, "closedown(sig)\n\tint sig;\n");
653 f_print(fout
, "closedown()\n");
655 f_print(fout
, "{\n");
656 #ifdef __GNU_LIBRARY__
657 f_print(fout
, "\t(void) signal(sig, %s closedown);\n",
658 Cflag
? "(SIG_PF)" : "(void(*)())" );
660 f_print(fout
, "\tif (_rpcsvcdirty == 0) {\n");
661 f_print(fout
, "\t\textern fd_set svc_fdset;\n");
662 f_print(fout
, "\t\tstatic int size;\n");
663 f_print(fout
, "\t\tint i, openfd;\n");
664 if (tirpcflag
&& pmflag
) {
665 f_print(fout
, "\t\tstruct t_info tinfo;\n\n");
666 f_print(fout
, "\t\tif (!t_getinfo(0, &tinfo) && (tinfo.servtype == T_CLTS))\n");
668 f_print(fout
, "\n\t\tif (_rpcfdtype == SOCK_DGRAM)\n");
670 f_print(fout
, "\t\t\texit(0);\n");
671 f_print(fout
, "\t\tif (size == 0) {\n");
673 f_print(fout
, "\t\t\tstruct rlimit rl;\n\n");
674 f_print(fout
, "\t\t\trl.rlim_max = 0;\n");
675 f_print(fout
, "\t\t\tgetrlimit(RLIMIT_NOFILE, &rl);\n");
676 f_print(fout
, "\t\t\tif ((size = rl.rlim_max) == 0)\n");
677 f_print(fout
, "\t\t\t\treturn;\n");
679 f_print(fout
, "\t\t\tsize = getdtablesize();\n");
681 f_print(fout
, "\t\t}\n");
682 f_print(fout
, "\t\tfor (i = 0, openfd = 0; i < size && openfd < 2; i++)\n");
683 f_print(fout
, "\t\t\tif (FD_ISSET(i, &svc_fdset))\n");
684 f_print(fout
, "\t\t\t\topenfd++;\n");
685 f_print(fout
, "\t\tif (openfd <= 1)\n");
686 f_print(fout
, "\t\t\texit(0);\n");
687 f_print(fout
, "\t}\n");
688 f_print(fout
, "\t(void) alarm(_RPCSVC_CLOSEDOWN);\n");
689 f_print(fout
, "}\n");
693 * Write the most of port monitor support
696 write_pm_most(const char *infile
, int netflag
)
702 f_print(fout
, "\tif (!ioctl(0, I_LOOK, mname) &&\n");
703 f_print(fout
, "\t\t(!strcmp(mname, \"sockmod\") ||");
704 f_print(fout
, " !strcmp(mname, \"timod\"))) {\n");
705 f_print(fout
, "\t\tchar *netid;\n");
706 if (!netflag
) { /* Not included by -n option */
707 f_print(fout
, "\t\tstruct netconfig *nconf = NULL;\n");
708 f_print(fout
, "\t\tSVCXPRT *%s;\n", TRANSP
);
711 f_print(fout
, "\t\tint pmclose;\n");
712 /* not necessary, defined in /usr/include/stdlib */
713 /* f_print(fout, "\t\textern char *getenv();\n");*/
715 f_print(fout
, "\t\t_rpcpmstart = 1;\n");
717 open_log_file(infile
, "\t\t");
718 f_print(fout
, "\t\tif ((netid = getenv(\"NLSPROVIDER\")) == NULL) {\n");
719 sprintf(_errbuf
, "cannot get transport name");
720 print_err_message("\t\t\t");
721 f_print(fout
, "\t\t} else if ((nconf = getnetconfigent(netid)) == NULL) {\n");
722 sprintf(_errbuf
, "cannot get transport info");
723 print_err_message("\t\t\t");
724 f_print(fout
, "\t\t}\n");
726 * A kludgy support for inetd services. Inetd only works with
727 * sockmod, and RPC works only with timod, hence all this jugglery
729 f_print(fout
, "\t\tif (strcmp(mname, \"sockmod\") == 0) {\n");
730 f_print(fout
, "\t\t\tif (ioctl(0, I_POP, 0) || ioctl(0, I_PUSH, \"timod\")) {\n");
731 sprintf(_errbuf
, "could not get the right module");
732 print_err_message("\t\t\t\t");
733 f_print(fout
, "\t\t\t\texit(1);\n");
734 f_print(fout
, "\t\t\t}\n");
735 f_print(fout
, "\t\t}\n");
737 f_print(fout
, "\t\tpmclose = (t_getstate(0) != T_DATAXFER);\n");
738 f_print(fout
, "\t\tif ((%s = svc_tli_create(0, nconf, NULL, 0, 0)) == NULL) {\n",
740 sprintf(_errbuf
, "cannot create server handle");
741 print_err_message("\t\t\t");
742 f_print(fout
, "\t\t\texit(1);\n");
743 f_print(fout
, "\t\t}\n");
744 f_print(fout
, "\t\tif (nconf)\n");
745 f_print(fout
, "\t\t\tfreenetconfigent(nconf);\n");
746 for (l
= defined
; l
!= NULL
; l
= l
->next
) {
747 def
= (definition
*) l
->val
;
748 if (def
->def_kind
!= DEF_PROGRAM
) {
751 for (vp
= def
->def
.pr
.versions
; vp
!= NULL
; vp
= vp
->next
) {
753 "\t\tif (!svc_reg(%s, %s, %s, ",
754 TRANSP
, def
->def_name
, vp
->vers_name
);
755 pvname(def
->def_name
, vp
->vers_num
);
756 f_print(fout
, ", 0)) {\n");
757 (void) sprintf(_errbuf
, "unable to register (%s, %s).",
758 def
->def_name
, vp
->vers_name
);
759 print_err_message("\t\t\t");
760 f_print(fout
, "\t\t\texit(1);\n");
761 f_print(fout
, "\t\t}\n");
765 f_print(fout
, "\t\tif (pmclose) {\n");
766 f_print(fout
, "\t\t\t(void) signal(SIGALRM, %s closedown);\n",
767 Cflag
? "(SIG_PF)" : "(void(*)())" );
768 f_print(fout
, "\t\t\t(void) alarm(_RPCSVC_CLOSEDOWN);\n");
769 f_print(fout
, "\t\t}\n");
771 f_print(fout
, "\t\tsvc_run();\n");
772 f_print(fout
, "\t\texit(1);\n");
773 f_print(fout
, "\t\t/* NOTREACHED */\n");
774 f_print(fout
, "\t}\n");
778 * Support for backgrounding the server if self started.
781 write_rpc_svc_fg(const char *infile
, const char *sp
)
783 f_print(fout
, "#ifndef RPC_SVC_FG\n");
784 f_print(fout
, "%sint size;\n", sp
);
786 f_print(fout
, "%sstruct rlimit rl;\n", sp
);
788 f_print(fout
, "%sint pid, i;\n\n", sp
);
789 f_print(fout
, "%spid = fork();\n", sp
);
790 f_print(fout
, "%sif (pid < 0) {\n", sp
);
791 f_print(fout
, "%s\tperror(\"cannot fork\");\n", sp
);
792 f_print(fout
, "%s\texit(1);\n", sp
);
793 f_print(fout
, "%s}\n", sp
);
794 f_print(fout
, "%sif (pid)\n", sp
);
795 f_print(fout
, "%s\texit(0);\n", sp
);
796 /* get number of file descriptors */
798 f_print(fout
, "%srl.rlim_max = 0;\n", sp
);
799 f_print(fout
, "%sgetrlimit(RLIMIT_NOFILE, &rl);\n", sp
);
800 f_print(fout
, "%sif ((size = rl.rlim_max) == 0)\n", sp
);
801 f_print(fout
, "%s\texit(1);\n", sp
);
803 f_print(fout
, "%ssize = getdtablesize();\n", sp
);
806 f_print(fout
, "%sfor (i = 0; i < size; i++)\n", sp
);
807 f_print(fout
, "%s\t(void) close(i);\n", sp
);
808 /* Redirect stderr and stdout to console */
809 f_print(fout
, "%si = open(\"/dev/console\", 2);\n", sp
);
810 f_print(fout
, "%s(void) dup2(i, 1);\n", sp
);
811 f_print(fout
, "%s(void) dup2(i, 2);\n", sp
);
812 /* This removes control of the controlling terminal */
814 f_print(fout
, "%ssetsid();\n", sp
);
816 f_print(fout
, "%si = open(\"/dev/tty\", 2);\n", sp
);
817 f_print(fout
, "%sif (i >= 0) {\n", sp
);
818 f_print(fout
, "%s\t(void) ioctl(i, TIOCNOTTY, (char *)NULL);\n", sp
);;
819 f_print(fout
, "%s\t(void) close(i);\n", sp
);
820 f_print(fout
, "%s}\n", sp
);
823 open_log_file(infile
, sp
);
824 f_print(fout
, "#endif\n");
826 open_log_file(infile
, sp
);
830 open_log_file(const char *infile
, const char *sp
)
834 s
= strrchr(infile
, '.');
837 f_print(fout
,"%sopenlog(\"%s\", LOG_PID, LOG_DAEMON);\n", sp
, infile
);
846 * write a registration for the given transport for Inetd
849 write_inetd_register(const char *transp
)
862 if (streq(transp
, "udp"))
868 f_print(fout
, "\tif ((_rpcfdtype == 0) || (_rpcfdtype == %s)) {\n",
869 isudp
? "SOCK_DGRAM" : "SOCK_STREAM");
871 f_print(fout
, "%s\t%s = svc%s_create(%s",
872 sp
, TRANSP
, transp
, inetdflag
? "sock": "RPC_ANYSOCK");
874 f_print(fout
, ", 0, 0");
875 f_print(fout
, ");\n");
876 f_print(fout
, "%s\tif (%s == NULL) {\n", sp
, TRANSP
);
877 (void) sprintf(_errbuf
, "cannot create %s service.", transp
);
878 (void) sprintf(tmpbuf
, "%s\t\t", sp
);
879 print_err_message(tmpbuf
);
880 f_print(fout
, "%s\t\texit(1);\n", sp
);
881 f_print(fout
, "%s\t}\n", sp
);
884 f_print(fout
, "%s\tif (!_rpcpmstart)\n\t", sp
);
885 f_print(fout
, "%s\tproto = IPPROTO_%s;\n",
886 sp
, isudp
? "UDP": "TCP");
888 for (l
= defined
; l
!= NULL
; l
= l
->next
) {
889 def
= (definition
*) l
->val
;
890 if (def
->def_kind
!= DEF_PROGRAM
) {
893 for (vp
= def
->def
.pr
.versions
; vp
!= NULL
; vp
= vp
->next
) {
894 f_print(fout
, "%s\tif (!svc_register(%s, %s, %s, ",
895 sp
, TRANSP
, def
->def_name
, vp
->vers_name
);
896 pvname(def
->def_name
, vp
->vers_num
);
898 f_print(fout
, ", proto)) {\n");
900 f_print(fout
, ", IPPROTO_%s)) {\n",
901 isudp
? "UDP": "TCP");
902 (void) sprintf(_errbuf
, "unable to register (%s, %s, %s).",
903 def
->def_name
, vp
->vers_name
, transp
);
904 print_err_message(tmpbuf
);
905 f_print(fout
, "%s\t\texit(1);\n", sp
);
906 f_print(fout
, "%s\t}\n", sp
);
910 f_print(fout
, "\t}\n");