Subversion Repositories DevTools

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
227 dpurdie 1
/*
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.
9
 *
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.
13
 *
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.
17
 *
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.
21
 *
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.
25
 *
26
 * Sun Microsystems, Inc.
27
 * 2550 Garcia Avenue
28
 * Mountain View, California  94043
29
 */
30
 
31
#ifndef lint
32
 static char sccsid[] = "@(#)rpc_svcout.c 1.29 89/03/30 (C) 1987 SMI";
33
#endif
34
 
35
/*
36
 * rpc_svcout.c, Server-skeleton outputter for the RPC protocol compiler
37
 */
38
#include <stdio.h>
39
#include <string.h>
40
#include "rpc_parse.h"
41
#include "rpc_util.h"
42
 
43
static char RQSTP[] = "rqstp";
44
static char TRANSP[] = "transp";
45
static char ARG[] = "argument";
46
static char RESULT[] = "result";
47
static char ROUTINE[] = "local";
48
 
49
#if defined(PATCHED)
50
extern char *embeddedname;
51
extern int embeddedflag;
52
#endif
53
 
54
char _errbuf[256];	/* For all messages */
55
 
56
void internal_proctype();
57
 
58
static
59
p_xdrfunc( rname, typename )
60
	char* rname;
61
	char* typename;
62
{
63
	if( Cflag )
64
		f_print(fout, "\t\txdr_%s = (xdrproc_t) xdr_%s;\n", rname, 
65
			stringfix(typename) );
66
	else
67
		f_print(fout, "\t\txdr_%s = xdr_%s;\n", rname, stringfix(typename) );
68
}    
69
 
70
void
71
internal_proctype(plist)
72
	proc_list *plist;
73
{
74
	f_print(fout, "static ");
75
	ptype( plist->res_prefix, plist->res_type, 1 );
76
	f_print( fout, "*" );
77
}
78
 
79
 
80
/*
81
 * write most of the service, that is, everything but the registrations. 
82
 */
83
void
84
write_most(infile, netflag, nomain)
85
	char *infile;		/* our name */
86
	int netflag;
87
        int nomain;
88
{
89
	if (inetdflag || pmflag) {
90
	        char* var_type;
91
		var_type = (nomain? "extern" : "static");
92
		f_print(fout, "%s int _rpcpmstart;", var_type );
93
		f_print(fout, "\t\t/* Started by a port monitor ? */\n"); 
94
		f_print(fout, "%s int _rpcfdtype;", var_type );
95
		f_print(fout, "\t\t/* Whether Stream or Datagram ? */\n");
96
		if (timerflag) {
97
			f_print(fout, "%s int _rpcsvcdirty;", var_type );
98
			f_print(fout, "\t/* Still serving ? */\n");
99
		}
100
		write_svc_aux( nomain );
101
	}
102
	/* write out dispatcher and stubs */
103
	write_programs( nomain? (char *)NULL : "static" );
104
 
105
        if( nomain ) 
106
	  return;
107
 
108
	f_print(fout, "\n");
109
#if defined(PATCHED)
110
	if (!embeddedname)
111
	{
112
		f_print(stderr, "Embedded name not supplied\n");
113
		crash();
114
	}
115
	f_print(fout, "#if defined(EMBEDDED) || defined(WIN32)\n");
116
	f_print(fout, "%s()\n", embeddedname );
117
	f_print(fout, "#else\n");
118
#endif
119
	f_print(fout, "main()\n");
120
#if defined(PATCHED)
121
	f_print(fout, "#endif\n");
122
#endif
123
 
124
	f_print(fout, "{\n");
125
	if (inetdflag) {
126
		write_inetmost(infile); /* Includes call to write_rpc_svc_fg() */
127
	} else {
128
	  if( tirpcflag ) {
129
		if (netflag) {
130
			f_print(fout, "\tregister SVCXPRT *%s;\n", TRANSP);
131
			f_print(fout, "\tstruct netconfig *nconf = NULL;\n");
132
		}
133
		f_print(fout, "\tpid_t pid;\n");
134
		f_print(fout, "\tint i;\n");
135
		f_print(fout, "\tchar mname[FMNAMESZ + 1];\n\n");
136
		write_pm_most(infile, netflag);
137
		f_print(fout, "\telse {\n");
138
		write_rpc_svc_fg(infile, "\t\t");
139
		f_print(fout, "\t}\n");
140
	      } else {
141
		f_print(fout, "\tregister SVCXPRT *%s;\n", TRANSP);
142
		f_print(fout, "\n");
143
		print_pmapunset("\t");
144
	      }
145
	}
146
 
147
	if (logflag && !inetdflag) {
148
		open_log_file(infile, "\t");
149
	}
150
}
151
 
152
/*
153
 * write a registration for the given transport 
154
 */
155
void
156
write_netid_register(transp)
157
	char *transp;
158
{
159
	list *l;
160
	definition *def;
161
	version_list *vp;
162
	char *sp;
163
	char tmpbuf[32];
164
 
165
	sp = "";
166
	f_print(fout, "\n");
167
	f_print(fout, "%s\tnconf = getnetconfigent(\"%s\");\n", sp, transp);
168
	f_print(fout, "%s\tif (nconf == NULL) {\n", sp);
169
	(void) sprintf(_errbuf, "cannot find %s netid.", transp);
170
	sprintf(tmpbuf, "%s\t\t", sp);
171
	print_err_message(tmpbuf);
172
	f_print(fout, "%s\t\texit(1);\n", sp);
173
	f_print(fout, "%s\t}\n", sp);
174
	f_print(fout, "%s\t%s = svc_tli_create(RPC_ANYFD, nconf, 0, 0, 0);\n",
175
			sp, TRANSP, transp);
176
	f_print(fout, "%s\tif (%s == NULL) {\n", sp, TRANSP);
177
	(void) sprintf(_errbuf, "cannot create %s service.", transp);
178
	print_err_message(tmpbuf);
179
	f_print(fout, "%s\t\texit(1);\n", sp);
180
	f_print(fout, "%s\t}\n", sp);
181
 
182
	for (l = defined; l != NULL; l = l->next) {
183
		def = (definition *) l->val;
184
		if (def->def_kind != DEF_PROGRAM) {
185
			continue;
186
		}
187
		for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
188
			f_print(fout,
189
				"%s\t(void) rpcb_unset(%s, %s, nconf);\n",
190
				sp, def->def_name, vp->vers_name);
191
			f_print(fout,
192
				"%s\tif (!svc_reg(%s, %s, %s, ",
193
				sp, TRANSP, def->def_name, vp->vers_name);
194
			pvname(def->def_name, vp->vers_num);
195
			f_print(fout, ", nconf)) {\n");
196
			(void) sprintf(_errbuf, "unable to register (%s, %s, %s).",
197
					def->def_name, vp->vers_name, transp);
198
			print_err_message(tmpbuf);
199
			f_print(fout, "%s\t\texit(1);\n", sp);
200
			f_print(fout, "%s\t}\n", sp);
201
		}
202
	}
203
	f_print(fout, "%s\tfreenetconfigent(nconf);\n", sp);
204
}
205
 
206
/*
207
 * write a registration for the given transport for TLI
208
 */
209
void
210
write_nettype_register(transp)
211
	char *transp;
212
{
213
	list *l;
214
	definition *def;
215
	version_list *vp;
216
 
217
	for (l = defined; l != NULL; l = l->next) {
218
		def = (definition *) l->val;
219
		if (def->def_kind != DEF_PROGRAM) {
220
			continue;
221
		}
222
		for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
223
			f_print(fout, "\tif (!svc_create(");
224
			pvname(def->def_name, vp->vers_num);
225
			f_print(fout, ", %s, %s, \"%s\")) {\n ",
226
				def->def_name, vp->vers_name, transp);
227
			(void) sprintf(_errbuf,
228
				"unable to create (%s, %s) for %s.",
229
					def->def_name, vp->vers_name, transp);
230
			print_err_message("\t\t");
231
			f_print(fout, "\t\texit(1);\n");
232
			f_print(fout, "\t}\n");
233
		}
234
	}
235
}
236
 
237
/*
238
 * write the rest of the service 
239
 */
240
void
241
write_rest()
242
{
243
	f_print(fout, "\n");
244
	if (inetdflag) {
245
		f_print(fout, "\tif (%s == (SVCXPRT *)NULL) {\n", TRANSP);
246
		(void) sprintf(_errbuf, "could not create a handle");
247
		print_err_message("\t\t");
248
		f_print(fout, "\t\texit(1);\n");
249
		f_print(fout, "\t}\n");
250
		if (timerflag) {
251
			f_print(fout, "\tif (_rpcpmstart) {\n");
252
			f_print(fout, 
253
				"\t\t(void) signal(SIGALRM, %s closedown);\n",
254
				Cflag? "(SIG_PF)" : "(void(*)())" );
255
			f_print(fout, "\t\t(void) alarm(_RPCSVC_CLOSEDOWN);\n");
256
			f_print(fout, "\t}\n");
257
		}
258
	}
259
	f_print(fout, "\tsvc_run();\n");
260
	(void) sprintf(_errbuf, "svc_run returned");
261
	print_err_message("\t");
262
#if defined(PATCHED)
263
        f_print(fout, "#if defined(EMBEDDED) || defined(WIN32)\n");
264
	f_print(fout, "\treturn(3);\n");
265
	f_print(fout, "#else\n");
266
#endif
267
	f_print(fout, "\texit(1);\n");
268
	f_print(fout, "\t/* NOTREACHED */\n");
269
#if defined(PATCHED)
270
	f_print(fout, "#endif\n");
271
#endif
272
	f_print(fout, "}\n");
273
}
274
 
275
void
276
write_programs(storage)
277
	char *storage;
278
{
279
	list *l;
280
	definition *def;
281
 
282
	/* write out stubs for procedure  definitions */
283
	for (l = defined; l != NULL; l = l->next) {
284
		def = (definition *) l->val;
285
		if (def->def_kind == DEF_PROGRAM) {
286
			write_real_program(def);
287
		}
288
	}
289
 
290
	/* write out dispatcher for each program */
291
	for (l = defined; l != NULL; l = l->next) {
292
		def = (definition *) l->val;
293
		if (def->def_kind == DEF_PROGRAM) {
294
			write_program(def, storage);
295
		}
296
	}
297
 
298
 
299
}
300
 
301
/* write out definition of internal function (e.g. _printmsg_1(...))
302
   which calls server's defintion of actual function (e.g. printmsg_1(...)).
303
   Unpacks single user argument of printmsg_1 to call-by-value format
304
   expected by printmsg_1. */
305
static
306
write_real_program(def)
307
	definition *def;
308
{
309
	version_list *vp;
310
	proc_list *proc;
311
	decl_list *l;
312
 
313
	if( !newstyle ) return;  /* not needed for old style */
314
	for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
315
		for (proc = vp->procs; proc != NULL; proc = proc->next) {
316
			f_print(fout, "\n");
317
			internal_proctype(proc);
318
			f_print(fout, "\n_");
319
			pvname(proc->proc_name, vp->vers_num);
320
			if( Cflag ) {
321
			  f_print(fout, "(" );
322
			  /* arg name */
323
			  if (proc->arg_num > 1)
324
			    f_print(fout, proc->args.argname);
325
			  else
326
			    ptype(proc->args.decls->decl.prefix, 
327
				  proc->args.decls->decl.type, 0);
328
			  f_print(fout, " *argp, struct svc_req *%s)\n", 
329
				  RQSTP);
330
			} else {
331
			  f_print(fout, "(argp, %s)\n", RQSTP );
332
			  /* arg name */
333
			  if (proc->arg_num > 1)
334
			    f_print(fout, "\t%s *argp;\n", proc->args.argname);
335
			  else {
336
			    f_print(fout, "\t");
337
			    ptype(proc->args.decls->decl.prefix, 
338
				  proc->args.decls->decl.type, 0);
339
			    f_print(fout, " *argp;\n");
340
			  }
341
			  f_print(fout, "	struct svc_req *%s;\n", RQSTP);
342
			}
343
 
344
			f_print(fout, "{\n");
345
			f_print(fout, "\treturn(");
346
			if( Cflag )
347
			  pvname_svc(proc->proc_name, vp->vers_num);
348
			else
349
			  pvname(proc->proc_name, vp->vers_num);
350
			f_print(fout, "(");
351
			if (proc->arg_num < 2) { /* single argument */
352
			  if (!streq( proc->args.decls->decl.type, "void"))
353
			    f_print(fout, "*argp, ");  /* non-void */
354
			} else {
355
			  for (l = proc->args.decls;  l != NULL; l = l->next) 
356
			    f_print(fout, "argp->%s, ", l->decl.name);
357
			}
358
			f_print(fout, "%s));\n}\n", RQSTP);
359
		} 		
360
	}
361
}
362
 
363
static 
364
write_program(def, storage)
365
	definition *def;
366
	char *storage;
367
{
368
	version_list *vp;
369
	proc_list *proc;
370
	int filled;
371
 
372
	for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
373
		f_print(fout, "\n");
374
		if (storage != NULL) {
375
			f_print(fout, "%s ", storage);
376
		}
377
		f_print(fout, "void\n");
378
		pvname(def->def_name, vp->vers_num);
379
 
380
		if (Cflag) {
381
		   f_print(fout, "(struct svc_req *%s, ", RQSTP);
382
		   f_print(fout, "register SVCXPRT *%s)\n", TRANSP);
383
		} else {
384
		   f_print(fout, "(%s, %s)\n", RQSTP, TRANSP);
385
		   f_print(fout, "	struct svc_req *%s;\n", RQSTP);
386
		   f_print(fout, "	register SVCXPRT *%s;\n", TRANSP);
387
		}
388
 
389
		f_print(fout, "{\n");
390
 
391
		filled = 0;
392
		f_print(fout, "\tunion {\n");
393
		for (proc = vp->procs; proc != NULL; proc = proc->next) {
394
			if (proc->arg_num < 2) { /* single argument */
395
				if (streq(proc->args.decls->decl.type, 
396
					  "void")) {
397
					continue;
398
				}
399
				filled = 1;
400
				f_print(fout, "\t\t");
401
				ptype(proc->args.decls->decl.prefix, 
402
				      proc->args.decls->decl.type, 0);
403
				pvname(proc->proc_name, vp->vers_num);
404
				f_print(fout, "_arg;\n");
405
 
406
			}
407
			else {
408
				filled = 1;
409
				f_print(fout, "\t\t%s", proc->args.argname);
410
				f_print(fout, " ");
411
				pvname(proc->proc_name, vp->vers_num);
412
				f_print(fout, "_arg;\n");
413
			}
414
		}
415
		if (!filled) {
416
			f_print(fout, "\t\tint fill;\n");
417
		}
418
		f_print(fout, "\t} %s;\n", ARG);
419
		f_print(fout, "\tchar *%s;\n", RESULT);
420
 
421
		if (Cflag) {
422
		    f_print(fout, "\txdrproc_t xdr_%s, xdr_%s;\n", ARG, RESULT);
423
		    f_print(fout,
424
			    "\tchar *(*%s)(char *, struct svc_req *);\n",
425
			    ROUTINE);
426
		} else {
427
		    f_print(fout, "\tbool_t (*xdr_%s)(), (*xdr_%s)();\n", ARG, RESULT);
428
		    f_print(fout, "\tchar *(*%s)();\n", ROUTINE);
429
		}
430
 
431
		f_print(fout, "\n");
432
 
433
		if (timerflag)
434
			f_print(fout, "\t_rpcsvcdirty = 1;\n");
435
		f_print(fout, "\tswitch (%s->rq_proc) {\n", RQSTP);
436
		if (!nullproc(vp->procs)) {
437
			f_print(fout, "\tcase NULLPROC:\n");
438
			f_print(fout,
439
			Cflag
440
			? "\t\t(void) svc_sendreply(%s, (xdrproc_t) xdr_void, (char *)NULL);\n"
441
			: "\t\t(void) svc_sendreply(%s, xdr_void, (char *)NULL);\n",
442
					TRANSP);
443
			print_return("\t\t");
444
			f_print(fout, "\n");
445
		}
446
		for (proc = vp->procs; proc != NULL; proc = proc->next) {
447
			f_print(fout, "\tcase %s:\n", proc->proc_name);
448
			if (proc->arg_num < 2) { /* single argument */
449
			  p_xdrfunc( ARG, proc->args.decls->decl.type);
450
			} else {
451
			  p_xdrfunc( ARG, proc->args.argname);
452
			}
453
			p_xdrfunc( RESULT, proc->res_type);
454
			if( Cflag )
455
			    f_print(fout,
456
				    "\t\t%s = (char *(*)(char *, struct svc_req *)) ",
457
				    ROUTINE);
458
			else
459
			    f_print(fout, "\t\t%s = (char *(*)()) ", ROUTINE);
460
 
461
			if (newstyle) { /* new style: calls internal routine */
462
				f_print(fout,"_");
463
			}
464
			if( Cflag && !newstyle )
465
			  pvname_svc(proc->proc_name, vp->vers_num);
466
			else
467
			  pvname(proc->proc_name, vp->vers_num);
468
			f_print(fout, ";\n");
469
			f_print(fout, "\t\tbreak;\n\n");
470
		}
471
		f_print(fout, "\tdefault:\n");
472
		printerr("noproc", TRANSP);
473
		print_return("\t\t");
474
		f_print(fout, "\t}\n");
475
 
476
		f_print(fout, "\t(void) memset((char *)&%s, 0, sizeof (%s));\n", ARG, ARG);
477
		if (Cflag)
478
		    printif("getargs", TRANSP, "(caddr_t) &", ARG);
479
		else
480
		    printif("getargs", TRANSP, "&", ARG);
481
		printerr("decode", TRANSP);
482
		print_return("\t\t");
483
		f_print(fout, "\t}\n");
484
 
485
		if (Cflag)
486
		    f_print(fout, "\t%s = (*%s)((char *)&%s, %s);\n",
487
			    RESULT, ROUTINE, ARG, RQSTP);
488
		else
489
		    f_print(fout, "\t%s = (*%s)(&%s, %s);\n",
490
			    RESULT, ROUTINE, ARG, RQSTP);
491
		f_print(fout, 
492
			"\tif (%s != NULL && !svc_sendreply(%s, xdr_%s, %s)) {\n",
493
			RESULT, TRANSP, RESULT, RESULT);
494
		printerr("systemerr", TRANSP);
495
		f_print(fout, "\t}\n");
496
 
497
		if (Cflag)
498
		    printif("freeargs", TRANSP, "(caddr_t) &", ARG);
499
		else
500
		    printif("freeargs", TRANSP, "&", ARG);
501
		(void) sprintf(_errbuf, "unable to free arguments");
502
		print_err_message("\t\t");
503
#if defined(PATCHED)
504
		f_print(fout, "#if defined(EMBEDDED) || defined(WIN32)\n");
505
		print_return("\t\t");
506
		f_print(fout, "#else\n");
507
#endif
508
		f_print(fout, "\t\texit(1);\n");
509
#if defined(PATCHED)
510
		f_print(fout, "#endif\n");
511
#endif
512
		f_print(fout, "\t}\n");
513
		print_return("\t");
514
		f_print(fout, "}\n");
515
	}
516
}
517
 
518
static
519
printerr(err, transp)
520
	char *err;
521
	char *transp;
522
{
523
	f_print(fout, "\t\tsvcerr_%s(%s);\n", err, transp);
524
}
525
 
526
static
527
printif(proc, transp, prefix, arg)
528
	char *proc;
529
	char *transp;
530
	char *prefix;
531
	char *arg;
532
{
533
	f_print(fout, "\tif (!svc_%s(%s, xdr_%s, %s%s)) {\n",
534
		proc, transp, arg, prefix, arg);
535
}
536
 
537
nullproc(proc)
538
	proc_list *proc;
539
{
540
	for (; proc != NULL; proc = proc->next) {
541
		if (streq(proc->proc_num, "0")) {
542
			return (1);
543
		}
544
	}
545
	return (0);
546
}
547
 
548
static
549
write_inetmost(infile)
550
	char *infile;
551
{
552
	f_print(fout, "\tregister SVCXPRT *%s;\n", TRANSP);
553
	f_print(fout, "\tint sock;\n");
554
	f_print(fout, "\tint proto;\n");
555
	f_print(fout, "\tstruct sockaddr_in saddr;\n");
556
	f_print(fout, "\tint asize = sizeof (saddr);\n");
557
	f_print(fout, "\n");
558
	f_print(fout, 
559
	"\tif (getsockname(0, (struct sockaddr *)&saddr, &asize) == 0) {\n");
560
	f_print(fout, "\t\tint ssize = sizeof (int);\n\n");
561
	f_print(fout, "\t\tif (saddr.sin_family != AF_INET)\n");
562
	f_print(fout, "\t\t\texit(1);\n");
563
	f_print(fout, "\t\tif (getsockopt(0, SOL_SOCKET, SO_TYPE,\n");
564
	f_print(fout, "\t\t\t\t(char *)&_rpcfdtype, &ssize) == -1)\n");
565
	f_print(fout, "\t\t\texit(1);\n");
566
	f_print(fout, "\t\tsock = 0;\n");
567
	f_print(fout, "\t\t_rpcpmstart = 1;\n");
568
	f_print(fout, "\t\tproto = 0;\n");
569
	open_log_file(infile, "\t\t");
570
	f_print(fout, "\t} else {\n");
571
	write_rpc_svc_fg(infile, "\t\t");
572
	f_print(fout, "\t\tsock = RPC_ANYSOCK;\n");
573
	print_pmapunset("\t\t");
574
	f_print(fout, "\t}\n");
575
}
576
 
577
static
578
print_return(space)
579
	char *space;
580
{
581
	if (exitnow)
582
		f_print(fout, "%sexit(0);\n", space);
583
	else {
584
		if (timerflag)
585
			f_print(fout, "%s_rpcsvcdirty = 0;\n", space);
586
		f_print(fout, "%sreturn;\n", space);
587
	}
588
}
589
 
590
static
591
print_pmapunset(space)
592
	char *space;
593
{
594
	list *l;
595
	definition *def;
596
	version_list *vp;
597
 
598
	for (l = defined; l != NULL; l = l->next) {
599
		def = (definition *) l->val;
600
		if (def->def_kind == DEF_PROGRAM) {
601
			for (vp = def->def.pr.versions; vp != NULL;
602
					vp = vp->next) {
603
				f_print(fout, "%s(void) pmap_unset(%s, %s);\n",
604
					space, def->def_name, vp->vers_name);
605
			}
606
		}
607
	}
608
}
609
 
610
static
611
print_err_message(space)
612
	char *space;
613
{
614
#if defined(PATCHED)
615
	f_print(fout, "#if defined(EMBEDDED)\n");
616
	f_print(fout, "#if defined(DEBUG)\n");
617
	f_print(fout, "%srpc_msgout(\"%s\");\n", space, _errbuf);
618
	f_print(fout, "#endif\n");
619
	f_print(fout, "#else\n");
620
#endif
621
	if (logflag)
622
		f_print(fout, "%ssyslog(LOG_ERR, \"%s\");\n", space, _errbuf);
623
	else if (inetdflag || pmflag)
624
		f_print(fout, "%s_msgout(\"%s\");\n", space, _errbuf);
625
	else
626
		f_print(fout, "%sfprintf(stderr, \"%s\");\n", space, _errbuf);
627
#if defined(PATCHED)
628
	f_print(fout, "#endif\n");
629
#endif
630
}
631
 
632
/*
633
 * Write the server auxiliary function ( _msgout, timeout)
634
 */
635
void
636
write_svc_aux( nomain )
637
     int nomain;
638
{
639
#if defined(PATCHED)
640
	if (!embeddedflag && !logflag)
641
#else
642
	if (!logflag)
643
#endif
644
		write_msg_out();
645
	if (!nomain)
646
		write_timeout_func();
647
}
648
 
649
/*
650
 * Write the _msgout function
651
 */
652
 
653
write_msg_out()
654
{
655
	f_print(fout, "\n");
656
	f_print(fout, "static\n");
657
	if( !Cflag ) {
658
	  f_print(fout, "void _msgout(msg)\n");
659
	  f_print(fout, "\tchar *msg;\n");
660
	} else {
661
	  f_print(fout, "void _msgout(char* msg)\n");
662
	}
663
	f_print(fout, "{\n");
664
	f_print(fout, "#ifdef RPC_SVC_FG\n");
665
	if (inetdflag || pmflag)
666
		f_print(fout, "\tif (_rpcpmstart)\n");
667
	f_print(fout, "\t\tsyslog(LOG_ERR, msg);\n");
668
	f_print(fout, "\telse\n");
669
	f_print(fout, "\t\t(void) fprintf(stderr, \"%%s\\n\", msg);\n");
670
	f_print(fout, "#else\n");
671
	f_print(fout, "\tsyslog(LOG_ERR, msg);\n");
672
	f_print(fout, "#endif\n");
673
	f_print(fout, "}\n");
674
}
675
 
676
/*
677
 * Write the timeout function
678
 */
679
static
680
write_timeout_func()
681
{
682
	if (!timerflag)
683
		return;
684
	f_print(fout, "\n");
685
	f_print(fout, "static void\n");
686
	f_print(fout, "closedown()\n");
687
	f_print(fout, "{\n");
688
	f_print(fout, "\tif (_rpcsvcdirty == 0) {\n");
689
	f_print(fout, "\t\textern fd_set svc_fdset;\n");
690
	f_print(fout, "\t\tstatic int size;\n");
691
	f_print(fout, "\t\tint i, openfd;\n");
692
	if (tirpcflag && pmflag) {
693
		f_print(fout, "\t\tstruct t_info tinfo;\n\n");
694
		f_print(fout, "\t\tif (!t_getinfo(0, &tinfo) && (tinfo.servtype == T_CLTS))\n");
695
	} else {
696
		f_print(fout, "\n\t\tif (_rpcfdtype == SOCK_DGRAM)\n");
697
	}
698
	f_print(fout, "\t\t\texit(0);\n");
699
	f_print(fout, "\t\tif (size == 0) {\n");
700
	if( tirpcflag ) {
701
	  f_print(fout, "\t\t\tstruct rlimit rl;\n\n");
702
	  f_print(fout, "\t\t\trl.rlim_max = 0;\n");
703
	  f_print(fout, "\t\t\tgetrlimit(RLIMIT_NOFILE, &rl);\n");
704
	  f_print(fout, "\t\t\tif ((size = rl.rlim_max) == 0)\n");
705
	  f_print(fout, "\t\t\t\treturn;\n");
706
	} else {
707
	  f_print(fout, "\t\t\tsize = getdtablesize();\n");
708
	}
709
	f_print(fout, "\t\t}\n");
710
	f_print(fout, "\t\tfor (i = 0, openfd = 0; i < size && openfd < 2; i++)\n");
711
	f_print(fout, "\t\t\tif (FD_ISSET(i, &svc_fdset))\n");
712
	f_print(fout, "\t\t\t\topenfd++;\n");
713
	f_print(fout, "\t\tif (openfd <= 1)\n");
714
	f_print(fout, "\t\t\texit(0);\n");
715
	f_print(fout, "\t}\n");
716
	f_print(fout, "\t(void) alarm(_RPCSVC_CLOSEDOWN);\n");
717
	f_print(fout, "}\n");
718
}
719
 
720
/*
721
 * Write the most of port monitor support
722
 */
723
static
724
write_pm_most(infile, netflag)
725
	char *infile;
726
	int netflag;
727
{
728
	list *l;
729
	definition *def;
730
	version_list *vp;
731
 
732
	f_print(fout, "\tif (!ioctl(0, I_LOOK, mname) &&\n");
733
	f_print(fout, "\t\t(!strcmp(mname, \"sockmod\") ||");
734
	f_print(fout, " !strcmp(mname, \"timod\"))) {\n");
735
	f_print(fout, "\t\tchar *netid;\n");
736
	if (!netflag) {	/* Not included by -n option */
737
		f_print(fout, "\t\tstruct netconfig *nconf = NULL;\n");
738
		f_print(fout, "\t\tSVCXPRT *%s;\n", TRANSP);
739
	}
740
	if( timerflag )
741
	  f_print(fout, "\t\tint pmclose;\n");
742
/* not necessary, defined in /usr/include/stdlib */
743
/*	f_print(fout, "\t\textern char *getenv();\n");*/
744
	f_print(fout, "\n");
745
	f_print(fout, "\t\t_rpcpmstart = 1;\n");
746
	if (logflag)
747
		open_log_file(infile, "\t\t");
748
	f_print(fout, "\t\tif ((netid = getenv(\"NLSPROVIDER\")) == NULL) {\n");
749
	sprintf(_errbuf, "cannot get transport name");
750
	print_err_message("\t\t\t");
751
	f_print(fout, "\t\t} else if ((nconf = getnetconfigent(netid)) == NULL) {\n");
752
	sprintf(_errbuf, "cannot get transport info");
753
	print_err_message("\t\t\t");
754
	f_print(fout, "\t\t}\n");
755
	/*
756
	 * A kludgy support for inetd services. Inetd only works with
757
	 * sockmod, and RPC works only with timod, hence all this jugglery
758
	 */
759
	f_print(fout, "\t\tif (strcmp(mname, \"sockmod\") == 0) {\n");
760
	f_print(fout, "\t\t\tif (ioctl(0, I_POP, 0) || ioctl(0, I_PUSH, \"timod\")) {\n");
761
	sprintf(_errbuf, "could not get the right module");
762
	print_err_message("\t\t\t\t");
763
	f_print(fout, "\t\t\t\texit(1);\n");
764
	f_print(fout, "\t\t\t}\n");
765
	f_print(fout, "\t\t}\n");
766
	if( timerflag )
767
	  f_print(fout, "\t\tpmclose = (t_getstate(0) != T_DATAXFER);\n");
768
	f_print(fout, "\t\tif ((%s = svc_tli_create(0, nconf, NULL, 0, 0)) == NULL) {\n",
769
			TRANSP);
770
	sprintf(_errbuf, "cannot create server handle");
771
	print_err_message("\t\t\t");
772
	f_print(fout, "\t\t\texit(1);\n");
773
	f_print(fout, "\t\t}\n");
774
	f_print(fout, "\t\tif (nconf)\n");
775
	f_print(fout, "\t\t\tfreenetconfigent(nconf);\n");
776
	for (l = defined; l != NULL; l = l->next) {
777
		def = (definition *) l->val;
778
		if (def->def_kind != DEF_PROGRAM) {
779
			continue;
780
		}
781
		for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
782
			f_print(fout,
783
				"\t\tif (!svc_reg(%s, %s, %s, ",
784
				TRANSP, def->def_name, vp->vers_name);
785
			pvname(def->def_name, vp->vers_num);
786
			f_print(fout, ", 0)) {\n");
787
			(void) sprintf(_errbuf, "unable to register (%s, %s).",
788
					def->def_name, vp->vers_name);
789
			print_err_message("\t\t\t");
790
			f_print(fout, "\t\t\texit(1);\n");
791
			f_print(fout, "\t\t}\n");
792
		}
793
	}
794
	if (timerflag) {
795
		f_print(fout, "\t\tif (pmclose) {\n");
796
		f_print(fout, "\t\t\t(void) signal(SIGALRM, %s closedown);\n",
797
				Cflag? "(SIG_PF)" : "(void(*)())" );
798
		f_print(fout, "\t\t\t(void) alarm(_RPCSVC_CLOSEDOWN);\n");
799
		f_print(fout, "\t\t}\n");
800
	}
801
	f_print(fout, "\t\tsvc_run();\n");
802
	f_print(fout, "\t\texit(1);\n");
803
	f_print(fout, "\t\t/* NOTREACHED */\n");
804
	f_print(fout, "\t}\n");
805
}
806
 
807
/*
808
 * Support for backgrounding the server if self started.
809
 */
810
static
811
write_rpc_svc_fg(infile, sp)
812
	char *infile;
813
	char *sp;
814
{
815
	f_print(fout, "#ifndef RPC_SVC_FG\n");
816
	f_print(fout, "%sint size;\n", sp);
817
	if( tirpcflag )
818
	        f_print(fout, "%sstruct rlimit rl;\n", sp);
819
	if (inetdflag)
820
		f_print(fout, "%sint pid, i;\n\n", sp);
821
	f_print(fout, "%spid = fork();\n", sp);
822
	f_print(fout, "%sif (pid < 0) {\n", sp);
823
	f_print(fout, "%s\tperror(\"cannot fork\");\n", sp);
824
	f_print(fout, "%s\texit(1);\n", sp);
825
	f_print(fout, "%s}\n", sp);
826
	f_print(fout, "%sif (pid)\n", sp);
827
	f_print(fout, "%s\texit(0);\n", sp);
828
	/* get number of file descriptors */
829
	if( tirpcflag ) {
830
	  f_print(fout, "%srl.rlim_max = 0;\n", sp);
831
	  f_print(fout, "%sgetrlimit(RLIMIT_NOFILE, &rl);\n", sp);
832
	  f_print(fout, "%sif ((size = rl.rlim_max) == 0)\n", sp);
833
	  f_print(fout, "%s\texit(1);\n", sp);
834
	} else {
835
	  f_print(fout, "%ssize = getdtablesize();\n", sp);
836
	}
837
 
838
	f_print(fout, "%sfor (i = 0; i < size; i++)\n", sp);
839
	f_print(fout, "%s\t(void) close(i);\n", sp);
840
	/* Redirect stderr and stdout to console */
841
	f_print(fout, "%si = open(\"/dev/console\", 2);\n", sp);
842
	f_print(fout, "%s(void) dup2(i, 1);\n", sp);
843
	f_print(fout, "%s(void) dup2(i, 2);\n", sp);
844
	/* This removes control of the controlling terminal */
845
	if( tirpcflag )
846
	  f_print(fout, "%ssetsid();\n", sp);
847
	else {
848
	  f_print(fout, "%si = open(\"/dev/tty\", 2);\n", sp);
849
	  f_print(fout, "%sif (i >= 0) {\n", sp);
850
	  f_print(fout, "%s\t(void) ioctl(i, TIOCNOTTY, (char *)NULL);\n", sp);;
851
	  f_print(fout, "%s\t(void) close(i);\n", sp);
852
	  f_print(fout, "%s}\n", sp);
853
	}
854
	if (!logflag)
855
		open_log_file(infile, sp);
856
	f_print(fout, "#endif\n");
857
	if (logflag)
858
		open_log_file(infile, sp);
859
}
860
 
861
static
862
open_log_file(infile, sp)
863
	char *infile;
864
	char *sp;
865
{
866
	char *s;
867
 
868
	s = strrchr(infile, '.');
869
	if (s) 
870
		*s = '\0';
871
	f_print(fout,"%sopenlog(\"%s\", LOG_PID, LOG_DAEMON);\n", sp, infile);
872
	if (s)
873
		*s = '.';
874
}
875
 
876
 
877
 
878
 
879
/*
880
 * write a registration for the given transport for Inetd
881
 */
882
void
883
write_inetd_register(transp)
884
	char *transp;
885
{
886
	list *l;
887
	definition *def;
888
	version_list *vp;
889
	char *sp;
890
	int isudp;
891
	char tmpbuf[32];
892
 
893
	if (inetdflag)
894
		sp = "\t";
895
	else
896
		sp = "";
897
	if (streq(transp, "udp"))
898
		isudp = 1;
899
	else
900
		isudp = 0;
901
	f_print(fout, "\n");
902
	if (inetdflag) {
903
		f_print(fout, "\tif ((_rpcfdtype == 0) || (_rpcfdtype == %s)) {\n",
904
				isudp ? "SOCK_DGRAM" : "SOCK_STREAM");
905
	}
906
	f_print(fout, "%s\t%s = svc%s_create(%s",
907
		sp, TRANSP, transp, inetdflag? "sock": "RPC_ANYSOCK");
908
	if (!isudp)
909
		f_print(fout, ", 0, 0");
910
	f_print(fout, ");\n");
911
	f_print(fout, "%s\tif (%s == NULL) {\n", sp, TRANSP);
912
	(void) sprintf(_errbuf, "cannot create %s service.", transp);
913
	(void) sprintf(tmpbuf, "%s\t\t", sp);
914
	print_err_message(tmpbuf);
915
#if defined(PATCHED)
916
	f_print(fout, "#if defined(EMBEDDED) || defined(WIN32)\n");
917
	f_print(fout, "%s\t\treturn(1);\n", sp);
918
	f_print(fout, "#else\n");
919
#endif
920
	f_print(fout, "%s\t\texit(1);\n", sp);
921
#if defined(PATCHED)
922
	f_print(fout, "#endif\n");
923
#endif
924
	f_print(fout, "%s\t}\n", sp);
925
 
926
	if (inetdflag) {
927
		f_print(fout, "%s\tif (!_rpcpmstart)\n\t", sp);
928
		f_print(fout, "%s\tproto = IPPROTO_%s;\n",
929
				sp, isudp ? "UDP": "TCP");
930
	}
931
	for (l = defined; l != NULL; l = l->next) {
932
		def = (definition *) l->val;
933
		if (def->def_kind != DEF_PROGRAM) {
934
			continue;
935
		}
936
		for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
937
			f_print(fout, "%s\tif (!svc_register(%s, %s, %s, ",
938
				sp, TRANSP, def->def_name, vp->vers_name);
939
			pvname(def->def_name, vp->vers_num);
940
			if (inetdflag)
941
				f_print(fout, ", proto)) {\n");
942
			else 
943
				f_print(fout, ", IPPROTO_%s)) {\n",
944
					isudp ? "UDP": "TCP");
945
			(void) sprintf(_errbuf, "unable to register (%s, %s, %s).",
946
					def->def_name, vp->vers_name, transp);
947
			print_err_message(tmpbuf);
948
#if defined(PATCHED)
949
			f_print(fout, "#if defined(EMBEDDED) || defined(WIN32)\n");
950
			f_print(fout, "%s\t\treturn(2);\n", sp);
951
			f_print(fout, "#else\n");
952
#endif
953
			f_print(fout, "%s\t\texit(1);\n", sp);
954
#if defined(PATCHED)
955
			f_print(fout, "#endif\n");
956
#endif
957
			f_print(fout, "%s\t}\n", sp);
958
		}
959
	}
960
	if (inetdflag)
961
		f_print(fout, "\t}\n");
962
}