1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 * 22 * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 26 /* All Rights Reserved */ 27 /* 28 * University Copyright- Copyright (c) 1982, 1986, 1988 29 * The Regents of the University of California 30 * All Rights Reserved 31 * 32 * University Acknowledgment- Portions of this document are derived from 33 * software developed by the University of California, Berkeley, and its 34 * contributors. 35 */ 36 37 #pragma ident "%Z%%M% %I% %E% SMI" 38 39 /* 40 * rpc_svcout.c, Server-skeleton outputter for the RPC protocol compiler 41 */ 42 #include <stdio.h> 43 #include <string.h> 44 #include "rpc_parse.h" 45 #include "rpc_util.h" 46 47 static char RQSTP[] = "rqstp"; 48 static char TRANSP[] = "transp"; 49 static char ARG[] = "argument"; 50 static char RESULT[] = "result"; 51 static char ROUTINE[] = "local"; 52 static char ONEWAY_ROUTINE[] = "oneway_local"; 53 static char RETVAL[] = "retval"; 54 55 char _errbuf[256]; /* For all messages */ 56 57 void internal_proctype(); 58 59 static 60 p_xdrfunc(rname, typename) 61 char *rname; 62 char *typename; 63 { 64 if (Cflag) 65 f_print(fout, "\t\t_xdr_%s = (xdrproc_t) xdr_%s;\n", 66 rname, stringfix(typename)); 67 else 68 f_print(fout, "\t\t_xdr_%s = xdr_%s;\n", 69 rname, stringfix(typename)); 70 } 71 72 void 73 internal_proctype(plist) 74 proc_list *plist; 75 { 76 f_print(fout, "static "); 77 ptype(plist->res_prefix, plist->res_type, 1); 78 f_print(fout, "*"); 79 } 80 81 82 static void 83 write_mtauto() 84 { 85 f_print(fout, "\tif (!rpc_control(RPC_SVC_MTMODE_SET, &mode)) {\n"); 86 f_print(fout, "\t\t_msgout(\"%s\");\n", 87 "unable to set automatic MT mode."); 88 f_print(fout, "\t\texit(1);\n\t}\n"); 89 } 90 91 /* 92 * write most of the service, that is, everything but the registrations. 93 */ 94 void 95 write_most(infile, netflag, nomain) 96 char *infile; /* our name */ 97 int netflag; 98 int nomain; 99 { 100 if (inetdflag || pmflag) { 101 char *var_type; 102 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 if (!tirpcflag) { 106 f_print(fout, "%s int _rpcfdtype;", var_type); 107 f_print(fout, 108 "\n\t\t /* Whether Stream or Datagram ? */\n"); 109 } 110 111 if (timerflag) { 112 f_print(fout, 113 "\n/* States a server can be in wrt request */\n\n"); 114 f_print(fout, "#define\t_IDLE 0\n"); 115 f_print(fout, "#define\t_SERVED 1\n\n"); 116 f_print(fout, "static int _rpcsvcstate = _IDLE;"); 117 f_print(fout, 118 "\t/* Set when a request is serviced */\n"); 119 f_print(fout, "static int _rpcsvccount = 0;"); 120 f_print(fout, 121 "\t\t/* Number of requests being serviced */\n"); 122 123 if (mtflag) { 124 f_print(fout, "mutex_t _svcstate_lock;"); 125 f_print(fout, 126 "\t\t\t/* lock for _rpcsvcstate, _rpcsvccount */\n"); 127 128 } 129 } 130 131 write_svc_aux(nomain); 132 } 133 /* write out dispatcher and stubs */ 134 write_programs(nomain? (char *)NULL : "static"); 135 136 if (nomain) 137 return; 138 139 f_print(fout, "\nmain()\n"); 140 f_print(fout, "{\n"); 141 if (inetdflag) { 142 write_inetmost(infile); 143 /* Includes call to write_rpc_svc_fg() */ 144 } else { 145 if (tirpcflag) { 146 if (netflag) { 147 f_print(fout, 148 "\tregister SVCXPRT *%s;\n", TRANSP); 149 f_print(fout, 150 "\tstruct netconfig *nconf = NULL;\n"); 151 } 152 f_print(fout, "\tpid_t pid;\n"); 153 f_print(fout, "\tint i;\n"); 154 if (mtauto) { 155 f_print(fout, 156 "\tint mode = RPC_SVC_MT_AUTO;\n\n"); 157 write_mtauto(); 158 } else 159 f_print(fout, "\n"); 160 161 if (mtflag & timerflag) 162 f_print(fout, 163 "\tmutex_init(&_svcstate_lock, USYNC_THREAD, NULL);\n"); 164 165 write_pm_most(infile, netflag); 166 f_print(fout, "\telse {\n"); 167 write_rpc_svc_fg(infile, "\t\t"); 168 f_print(fout, "\t}\n"); 169 } else { 170 f_print(fout, "\tregister SVCXPRT *%s;\n", TRANSP); 171 f_print(fout, "\n"); 172 print_pmapunset("\t"); 173 } 174 } 175 176 if (logflag && !inetdflag) { 177 open_log_file(infile, "\t"); 178 } 179 } 180 181 /* 182 * write a registration for the given transport 183 */ 184 void 185 write_netid_register(transp) 186 char *transp; 187 { 188 list *l; 189 definition *def; 190 version_list *vp; 191 char *sp; 192 char tmpbuf[32]; 193 194 sp = ""; 195 f_print(fout, "\n"); 196 f_print(fout, "%s\tnconf = getnetconfigent(\"%s\");\n", sp, transp); 197 f_print(fout, "%s\tif (nconf == NULL) {\n", sp); 198 (void) sprintf(_errbuf, "cannot find %s netid.", transp); 199 sprintf(tmpbuf, "%s\t\t", sp); 200 print_err_message(tmpbuf); 201 f_print(fout, "%s\t\texit(1);\n", sp); 202 f_print(fout, "%s\t}\n", sp); 203 f_print(fout, "%s\t%s = svc_tli_create(RPC_ANYFD, nconf, 0, 0, 0);\n", 204 sp, TRANSP, transp); 205 f_print(fout, "%s\tif (%s == NULL) {\n", sp, TRANSP); 206 (void) sprintf(_errbuf, "cannot create %s service.", transp); 207 print_err_message(tmpbuf); 208 f_print(fout, "%s\t\texit(1);\n", sp); 209 f_print(fout, "%s\t}\n", sp); 210 211 for (l = defined; l != NULL; l = l->next) { 212 def = (definition *) l->val; 213 if (def->def_kind != DEF_PROGRAM) { 214 continue; 215 } 216 for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { 217 f_print(fout, 218 "%s\t(void) rpcb_unset(%s, %s, nconf);\n", 219 sp, def->def_name, vp->vers_name); 220 f_print(fout, 221 "%s\tif (!svc_reg(%s, %s, %s, ", 222 sp, TRANSP, def->def_name, vp->vers_name); 223 pvname(def->def_name, vp->vers_num); 224 f_print(fout, ", nconf)) {\n"); 225 (void) sprintf(_errbuf, 226 "unable to register (%s, %s, %s).", 227 def->def_name, vp->vers_name, transp); 228 print_err_message(tmpbuf); 229 f_print(fout, "%s\t\texit(1);\n", sp); 230 f_print(fout, "%s\t}\n", sp); 231 } 232 } 233 f_print(fout, "%s\tfreenetconfigent(nconf);\n", sp); 234 } 235 236 /* 237 * write a registration for the given transport for TLI 238 */ 239 void 240 write_nettype_register(transp) 241 char *transp; 242 { 243 list *l; 244 definition *def; 245 version_list *vp; 246 247 for (l = defined; l != NULL; l = l->next) { 248 def = (definition *) l->val; 249 if (def->def_kind != DEF_PROGRAM) { 250 continue; 251 } 252 for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { 253 f_print(fout, "\tif (!svc_create("); 254 pvname(def->def_name, vp->vers_num); 255 f_print(fout, ", %s, %s, \"%s\")) {\n", 256 def->def_name, vp->vers_name, transp); 257 (void) sprintf(_errbuf, 258 "unable to create (%s, %s) for %s.", 259 def->def_name, vp->vers_name, transp); 260 print_err_message("\t\t"); 261 f_print(fout, "\t\texit(1);\n"); 262 f_print(fout, "\t}\n"); 263 } 264 } 265 } 266 267 /* 268 * write the rest of the service 269 */ 270 void 271 write_rest() 272 { 273 f_print(fout, "\n"); 274 if (inetdflag) { 275 f_print(fout, "\tif (%s == (SVCXPRT *)NULL) {\n", TRANSP); 276 (void) sprintf(_errbuf, "could not create a handle"); 277 print_err_message("\t\t"); 278 f_print(fout, "\t\texit(1);\n"); 279 f_print(fout, "\t}\n"); 280 if (timerflag) { 281 f_print(fout, "\tif (_rpcpmstart) {\n"); 282 if (mtflag) { 283 f_print(fout, 284 "\t\tif (thr_create(NULL, 0, closedown, NULL, 0, NULL) != 0) {\n"); 285 f_print(fout, 286 "\t\t\t_msgout(\"cannot create closedown thread\");\n"); 287 f_print(fout, "\t\t\texit(1);\n"); 288 f_print(fout, "\t\t}\n"); 289 f_print(fout, "\t}\n"); 290 } else { 291 f_print(fout, 292 "\t\t(void) signal(SIGALRM, %s closedown);\n", 293 Cflag? "(SIG_PF)":"(void(*)())"); 294 f_print(fout, 295 "\t\t(void) alarm(_RPCSVC_CLOSEDOWN/2);\n"); 296 f_print(fout, "\t}\n"); 297 } 298 } 299 } 300 f_print(fout, "\tsvc_run();\n"); 301 (void) sprintf(_errbuf, "svc_run returned"); 302 print_err_message("\t"); 303 f_print(fout, "\texit(1);\n"); 304 f_print(fout, "\t/* NOTREACHED */\n"); 305 f_print(fout, "}\n"); 306 } 307 308 void 309 write_programs(storage) 310 char *storage; 311 { 312 list *l; 313 definition *def; 314 315 /* write out stubs for procedure definitions */ 316 for (l = defined; l != NULL; l = l->next) { 317 def = (definition *) l->val; 318 if (def->def_kind == DEF_PROGRAM) { 319 write_real_program(def); 320 } 321 } 322 323 /* write out dispatcher for each program */ 324 for (l = defined; l != NULL; l = l->next) { 325 def = (definition *) l->val; 326 if (def->def_kind == DEF_PROGRAM) { 327 write_program(def, storage); 328 } 329 } 330 331 332 } 333 334 /* 335 * write out definition of internal function (e.g. _printmsg_1(...)) 336 * which calls server's defintion of actual function (e.g. printmsg_1(...)). 337 * Unpacks single user argument of printmsg_1 to call-by-value format 338 * expected by printmsg_1. 339 */ 340 static 341 write_real_program(def) 342 definition *def; 343 { 344 version_list *vp; 345 proc_list *proc; 346 decl_list *l; 347 348 if (!newstyle) 349 return; /* not needed for old style */ 350 for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { 351 for (proc = vp->procs; proc != NULL; proc = proc->next) { 352 int oneway = streq(proc->res_type, "oneway"); 353 354 f_print(fout, "\n"); 355 if (!mtflag) 356 internal_proctype(proc); 357 else 358 f_print(fout, "int"); 359 f_print(fout, "\n_"); 360 pvname(proc->proc_name, vp->vers_num); 361 if (Cflag) { 362 f_print(fout, "("); 363 /* arg name */ 364 if (proc->arg_num > 1) 365 f_print(fout, proc->args.argname); 366 else 367 ptype(proc->args.decls->decl.prefix, 368 proc->args.decls->decl.type, 0); 369 if (mtflag) { 370 f_print(fout, " *argp, "); 371 ptype(proc->res_prefix, 372 proc->res_type, 1); 373 f_print(fout, 374 "*%s, struct svc_req *%s)\n", 375 RESULT, RQSTP); 376 } 377 else 378 f_print(fout, 379 " *argp, struct svc_req *%s)\n", 380 RQSTP); 381 382 } else { 383 if (mtflag) 384 f_print(fout, "(argp, %s, %s)\n", 385 RESULT, RQSTP); 386 else 387 f_print(fout, "(argp, %s)\n", RQSTP); 388 /* arg name */ 389 if (proc->arg_num > 1) 390 f_print(fout, "\t%s *argp;\n", 391 proc->args.argname); 392 else { 393 f_print(fout, "\t"); 394 ptype(proc->args.decls->decl.prefix, 395 proc->args.decls->decl.type, 0); 396 f_print(fout, " *argp;\n"); 397 } 398 if (mtflag) 399 f_print(fout, "\tvoid *%s;\n", RESULT); 400 f_print(fout, "\tstruct svc_req *%s;\n", RQSTP); 401 } 402 403 f_print(fout, "{\n"); 404 f_print(fout, "\treturn ("); 405 /* for mtflag, arguments are different */ 406 if (Cflag || mtflag) 407 pvname_svc(proc->proc_name, vp->vers_num); 408 else 409 pvname(proc->proc_name, vp->vers_num); 410 f_print(fout, "("); 411 if (proc->arg_num < 2) { /* single argument */ 412 if (!streq(proc->args.decls->decl.type, "void")) 413 f_print(fout, "*argp, "); /* non-void */ 414 } else { 415 for (l = proc->args.decls; l != NULL; 416 l = l->next) 417 f_print(fout, "argp->%s, ", 418 l->decl.name); 419 } 420 if (mtflag && !oneway) 421 f_print(fout, "%s, ", RESULT); 422 f_print(fout, "%s));\n}\n", RQSTP); 423 } 424 } 425 } 426 427 static 428 write_program(def, storage) 429 definition *def; 430 char *storage; 431 { 432 version_list *vp; 433 proc_list *proc; 434 int filled; 435 436 for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { 437 f_print(fout, "\n"); 438 if (storage != NULL) { 439 f_print(fout, "%s ", storage); 440 } 441 f_print(fout, "void\n"); 442 pvname(def->def_name, vp->vers_num); 443 444 if (Cflag) { 445 f_print(fout, "(struct svc_req *%s, ", RQSTP); 446 f_print(fout, "register SVCXPRT *%s)\n", TRANSP); 447 } else { 448 f_print(fout, "(%s, %s)\n", RQSTP, TRANSP); 449 f_print(fout, " struct svc_req *%s;\n", RQSTP); 450 f_print(fout, " register SVCXPRT *%s;\n", TRANSP); 451 } 452 453 f_print(fout, "{\n"); 454 455 filled = 0; 456 f_print(fout, "\tunion {\n"); 457 for (proc = vp->procs; proc != NULL; proc = proc->next) { 458 if (proc->arg_num < 2) { /* single argument */ 459 if (streq(proc->args.decls->decl.type, 460 "void")) { 461 continue; 462 } 463 filled = 1; 464 f_print(fout, "\t\t"); 465 ptype(proc->args.decls->decl.prefix, 466 proc->args.decls->decl.type, 0); 467 pvname(proc->proc_name, vp->vers_num); 468 f_print(fout, "_arg;\n"); 469 470 } else { 471 filled = 1; 472 f_print(fout, "\t\t%s", proc->args.argname); 473 f_print(fout, " "); 474 pvname(proc->proc_name, vp->vers_num); 475 f_print(fout, "_arg;\n"); 476 } 477 } 478 if (!filled) { 479 f_print(fout, "\t\tint fill;\n"); 480 } 481 f_print(fout, "\t} %s;\n", ARG); 482 483 if (mtflag) { 484 filled = 0; 485 f_print(fout, "\tunion {\n"); 486 for (proc = vp->procs; proc != NULL; 487 proc = proc->next) { 488 if (streq(proc->res_type, "void") || 489 streq(proc->res_type, "oneway")) 490 continue; 491 filled = 1; 492 f_print(fout, "\t\t"); 493 ptype(proc->res_prefix, proc->res_type, 0); 494 pvname(proc->proc_name, vp->vers_num); 495 f_print(fout, "_res;\n"); 496 } 497 if (!filled) 498 f_print(fout, "\t\tint fill;\n"); 499 f_print(fout, "\t} %s;\n", RESULT); 500 f_print(fout, "\tbool_t %s;\n", RETVAL); 501 502 } else 503 f_print(fout, "\tchar *%s;\n", RESULT); 504 505 if (Cflag) { 506 f_print(fout, "\txdrproc_t _xdr_%s, _xdr_%s;\n", 507 ARG, RESULT); 508 if (mtflag) 509 f_print(fout, 510 "\tbool_t (*%s)(char *, void *, struct svc_req *);\n", 511 ROUTINE); 512 else 513 f_print(fout, 514 "\tchar *(*%s)(char *, struct svc_req *);\n", 515 ROUTINE); 516 } else { 517 f_print(fout, 518 "\tbool_t (*_xdr_%s)(), (*_xdr_%s)();\n", 519 ARG, RESULT); 520 if (mtflag) 521 f_print(fout, "\tbool_t (*%s)();\n", ROUTINE); 522 else 523 f_print(fout, "\tchar *(*%s)();\n", ROUTINE); 524 } 525 f_print(fout, "\n"); 526 527 if (timerflag) { 528 if (mtflag) 529 f_print(fout, 530 "\tmutex_lock(&_svcstate_lock);\n"); 531 532 f_print(fout, "\t_rpcsvccount++;\n"); 533 if (mtflag) 534 f_print(fout, 535 "\tmutex_unlock(&_svcstate_lock);\n"); 536 } 537 538 f_print(fout, "\tswitch (%s->rq_proc) {\n", RQSTP); 539 if (!nullproc(vp->procs)) { 540 f_print(fout, "\tcase NULLPROC:\n"); 541 f_print(fout, 542 Cflag ? 543 "\t\t(void) svc_sendreply(%s,\n\t\t\t(xdrproc_t) xdr_void, (char *)NULL);\n" : 544 "\t\t(void) svc_sendreply(%s, xdr_void,\n\t\t\t(char *)NULL);\n", 545 TRANSP); 546 print_return("\t\t"); 547 f_print(fout, "\n"); 548 } 549 for (proc = vp->procs; proc != NULL; proc = proc->next) { 550 f_print(fout, "\tcase %s:\n", proc->proc_name); 551 if (proc->arg_num < 2) { /* single argument */ 552 p_xdrfunc(ARG, proc->args.decls->decl.type); 553 } else { 554 p_xdrfunc(ARG, proc->args.argname); 555 } 556 557 if (streq(proc->res_type, "oneway")) { 558 /* One-way call */ 559 f_print(fout, "\t\t_xdr_%s = NULL;\n", RESULT); 560 } else { 561 p_xdrfunc(RESULT, proc->res_type); 562 } 563 if (Cflag) { 564 if (mtflag) { 565 f_print(fout, 566 "\t\t%s = (bool_t (*) (char *, " 567 "void *, struct svc_req *))", 568 ROUTINE); 569 } else { 570 f_print(fout, 571 "\t\t%s = (char *(*)(char *, " 572 "struct svc_req *)) ", 573 ROUTINE); 574 } 575 } else { 576 if (mtflag) { 577 f_print(fout, 578 "\t\t%s = (bool_t (*)()) ", 579 ROUTINE); 580 } else { 581 f_print(fout, "\t\t%s = (char *(*)()) ", 582 ROUTINE); 583 } 584 } 585 586 if (newstyle) { /* new style: calls internal routine */ 587 f_print(fout, "_"); 588 } 589 if ((Cflag || mtflag) && !newstyle) 590 pvname_svc(proc->proc_name, vp->vers_num); 591 else 592 pvname(proc->proc_name, vp->vers_num); 593 f_print(fout, ";\n"); 594 f_print(fout, "\t\tbreak;\n\n"); 595 } 596 f_print(fout, "\tdefault:\n"); 597 printerr("noproc", TRANSP); 598 print_return("\t\t"); 599 f_print(fout, "\t}\n"); 600 601 f_print(fout, 602 "\t(void) memset((char *)&%s, 0, sizeof (%s));\n", 603 ARG, ARG); 604 printif("getargs", TRANSP, "(caddr_t) &", ARG); 605 printerr("decode", TRANSP); 606 print_return("\t\t"); 607 f_print(fout, "\t}\n"); 608 609 if (!mtflag) 610 if (Cflag) 611 f_print(fout, 612 "\t%s = (*%s)((char *)&%s, %s);\n", 613 RESULT, ROUTINE, ARG, RQSTP); 614 else 615 f_print(fout, "\t%s = (*%s)(&%s, %s);\n", 616 RESULT, ROUTINE, ARG, RQSTP); 617 else 618 if (Cflag) 619 f_print(fout, 620 "\t%s = (bool_t) (*%s)((char *)&%s, (void *)&%s, %s);\n", 621 RETVAL, ROUTINE, ARG, RESULT, RQSTP); 622 else 623 f_print(fout, 624 "\t%s = (bool_t) (*%s)(&%s, &%s, %s);\n", 625 RETVAL, ROUTINE, ARG, RESULT, RQSTP); 626 627 628 629 630 if (mtflag) 631 f_print(fout, 632 "\tif (_xdr_%s && %s > 0 && !svc_sendreply(%s, _xdr_%s, (char *)&%s)) {\n", 633 RESULT, RETVAL, TRANSP, RESULT, RESULT); 634 else 635 f_print(fout, 636 "\tif (_xdr_%s && %s != NULL && !svc_sendreply(%s, _xdr_%s, %s)) {\n", 637 RESULT, RESULT, TRANSP, RESULT, RESULT); 638 639 printerr("systemerr", TRANSP); 640 f_print(fout, "\t}\n"); 641 642 printif("freeargs", TRANSP, "(caddr_t) &", ARG); 643 (void) sprintf(_errbuf, "unable to free arguments"); 644 print_err_message("\t\t"); 645 f_print(fout, "\t\texit(1);\n"); 646 f_print(fout, "\t}\n"); 647 /* print out free routine */ 648 if (mtflag) { 649 f_print(fout, "\tif (_xdr_%s != NULL) {\n", RESULT); 650 f_print(fout, "\t\tif (!"); 651 652 pvname(def->def_name, vp->vers_num); 653 f_print(fout, 654 "_freeresult(%s, _xdr_%s, (caddr_t) &%s))\n", 655 TRANSP, RESULT, RESULT); 656 (void) sprintf(_errbuf, "unable to free results"); 657 print_err_message("\t\t\t"); 658 f_print(fout, "\n"); 659 f_print(fout, "\t}\n"); 660 }; 661 print_return("\t"); 662 f_print(fout, "}\n"); 663 } 664 } 665 666 static 667 printerr(err, transp) 668 char *err; 669 char *transp; 670 { 671 f_print(fout, "\t\tsvcerr_%s(%s);\n", err, transp); 672 } 673 674 static 675 printif(proc, transp, prefix, arg) 676 char *proc; 677 char *transp; 678 char *prefix; 679 char *arg; 680 { 681 f_print(fout, "\tif (!svc_%s(%s, _xdr_%s, %s%s)) {\n", 682 proc, transp, arg, prefix, arg); 683 } 684 685 nullproc(proc) 686 proc_list *proc; 687 { 688 for (; proc != NULL; proc = proc->next) { 689 if (streq(proc->proc_num, "0")) { 690 return (1); 691 } 692 } 693 return (0); 694 } 695 696 static 697 write_inetmost(infile) 698 char *infile; 699 { 700 f_print(fout, "\tregister SVCXPRT *%s;\n", TRANSP); 701 f_print(fout, "\tint sock;\n"); 702 f_print(fout, "\tint proto;\n"); 703 f_print(fout, "\tstruct sockaddr_in saddr;\n"); 704 f_print(fout, "\tint asize = sizeof (saddr);\n"); 705 f_print(fout, "\n"); 706 f_print(fout, 707 "\tif (getsockname(0, (struct sockaddr *)&saddr, &asize) == 0) {\n"); 708 f_print(fout, "\t\tint ssize = sizeof (int);\n\n"); 709 f_print(fout, "\t\tif (saddr.sin_family != AF_INET)\n"); 710 f_print(fout, "\t\t\texit(1);\n"); 711 f_print(fout, "\t\tif (getsockopt(0, SOL_SOCKET, SO_TYPE,\n"); 712 f_print(fout, "\t\t\t\t(char *)&_rpcfdtype, &ssize) == -1)\n"); 713 f_print(fout, "\t\t\texit(1);\n"); 714 f_print(fout, "\t\tsock = 0;\n"); 715 f_print(fout, "\t\t_rpcpmstart = 1;\n"); 716 f_print(fout, "\t\tproto = 0;\n"); 717 open_log_file(infile, "\t\t"); 718 f_print(fout, "\t} else {\n"); 719 write_rpc_svc_fg(infile, "\t\t"); 720 f_print(fout, "\t\tsock = RPC_ANYSOCK;\n"); 721 print_pmapunset("\t\t"); 722 f_print(fout, "\t}\n"); 723 } 724 725 static 726 print_return(space) 727 char *space; 728 { 729 if (exitnow) 730 f_print(fout, "%sexit(0);\n", space); 731 else { 732 if (timerflag) { 733 if (mtflag) 734 f_print(fout, 735 "%smutex_lock(&_svcstate_lock);\n", 736 space); 737 f_print(fout, "%s_rpcsvccount--;\n", space); 738 f_print(fout, "%s_rpcsvcstate = _SERVED;\n", space); 739 if (mtflag) 740 f_print(fout, 741 "%smutex_unlock(&_svcstate_lock);\n", 742 space); 743 } 744 f_print(fout, "%sreturn;\n", space); 745 } 746 } 747 748 static 749 print_pmapunset(space) 750 char *space; 751 { 752 list *l; 753 definition *def; 754 version_list *vp; 755 756 for (l = defined; l != NULL; l = l->next) { 757 def = (definition *) l->val; 758 if (def->def_kind == DEF_PROGRAM) { 759 for (vp = def->def.pr.versions; vp != NULL; 760 vp = vp->next) { 761 f_print(fout, "%s(void) pmap_unset(%s, %s);\n", 762 space, def->def_name, vp->vers_name); 763 } 764 } 765 } 766 } 767 768 static 769 print_err_message(space) 770 char *space; 771 { 772 if (logflag) 773 f_print(fout, "%ssyslog(LOG_ERR, \"%%s\", \"%s\");\n", space, 774 _errbuf); 775 else if (inetdflag || pmflag) 776 f_print(fout, "%s_msgout(\"%s\");\n", space, _errbuf); 777 else 778 f_print(fout, "%sfprintf(stderr, \"%%s\", \"%s\");\n", space, 779 _errbuf); 780 } 781 782 /* 783 * Write the server auxiliary function (_msgout, timeout) 784 */ 785 void 786 write_svc_aux(nomain) 787 int nomain; 788 { 789 if (!logflag) 790 write_msg_out(); 791 if (!nomain) 792 write_timeout_func(); 793 } 794 795 /* 796 * Write the _msgout function 797 */ 798 799 write_msg_out() 800 { 801 f_print(fout, "\n"); 802 f_print(fout, "static\n"); 803 if (!Cflag) { 804 f_print(fout, "void _msgout(msg)\n"); 805 f_print(fout, "\tchar *msg;\n"); 806 } else { 807 f_print(fout, "void _msgout(char* msg)\n"); 808 } 809 f_print(fout, "{\n"); 810 f_print(fout, "#ifdef RPC_SVC_FG\n"); 811 if (inetdflag || pmflag) 812 f_print(fout, "\tif (_rpcpmstart)\n"); 813 f_print(fout, "\t\tsyslog(LOG_ERR, \"%%s\", msg);\n"); 814 f_print(fout, "\telse\n"); 815 f_print(fout, 816 "\t\t(void) fprintf(stderr, \"%%s\\n\", msg);\n"); 817 f_print(fout, "#else\n"); 818 f_print(fout, "\tsyslog(LOG_ERR, \"%%s\", msg);\n"); 819 f_print(fout, "#endif\n"); 820 f_print(fout, "}\n"); 821 } 822 823 /* 824 * Write the timeout function 825 */ 826 static 827 write_timeout_func() 828 { 829 if (!timerflag) 830 return; 831 832 f_print(fout, "\n"); 833 if (mtflag) { 834 f_print(fout, "/*ARGSUSED*/\n"); 835 f_print(fout, "static void *\n"); 836 if (!Cflag) { 837 f_print(fout, "closedown(arg)\n"); 838 f_print(fout, "\tvoid *arg;\n"); 839 } else 840 f_print(fout, "closedown(void *arg)\n"); 841 f_print(fout, "{\n"); 842 f_print(fout, "\t/*CONSTCOND*/\n"); 843 f_print(fout, "\twhile (1) {\n"); 844 f_print(fout, "\t\t(void) sleep(_RPCSVC_CLOSEDOWN/2);\n\n"); 845 f_print(fout, 846 "\t\tif (mutex_trylock(&_svcstate_lock) != 0)\n"); 847 f_print(fout, "\t\t\tcontinue;\n\n"); 848 f_print(fout, 849 "\t\tif (_rpcsvcstate == _IDLE && _rpcsvccount == 0) {\n"); 850 if (tirpcflag) { 851 f_print(fout, "\t\t\tint size;\n"); 852 } else { 853 f_print(fout, "\t\t\textern fd_set svc_fdset;\n"); 854 f_print(fout, "\t\t\tstatic int size;\n"); 855 } 856 f_print(fout, "\t\t\tint i, openfd = 0;\n\n"); 857 if (tirpcflag) { 858 f_print(fout, "\t\t\tsize = svc_max_pollfd;\n"); 859 } else { 860 f_print(fout, "\t\t\tif (size == 0) {\n"); 861 f_print(fout, "\t\t\t\tsize = getdtablesize();\n"); 862 f_print(fout, "\t\t\t}\n"); 863 } 864 f_print(fout, 865 "\t\t\tfor (i = 0; i < size && openfd < 2; i++)\n"); 866 if (tirpcflag) { 867 f_print(fout, "\t\t\t\tif (svc_pollfd[i].fd >= 0)\n"); 868 } else { 869 f_print(fout, "\t\t\t\tif (FD_ISSET(i, &svc_fdset))\n"); 870 } 871 f_print(fout, "\t\t\t\t\topenfd++;\n"); 872 f_print(fout, "\t\t\tif (openfd <= 1)\n"); 873 f_print(fout, "\t\t\t\texit(0);\n"); 874 f_print(fout, "\t\t} else\n"); 875 f_print(fout, "\t\t\t_rpcsvcstate = _IDLE;\n\n"); 876 f_print(fout, "\t\tmutex_unlock(&_svcstate_lock);\n"); 877 f_print(fout, "\t}\n"); 878 f_print(fout, "}\n"); 879 return; 880 } 881 882 f_print(fout, "static void\n"); 883 if (!Cflag) { 884 f_print(fout, "closedown(sig)\n"); 885 f_print(fout, "\tint sig;\n"); 886 } else 887 f_print(fout, "closedown(int sig)\n"); 888 f_print(fout, "{\n"); 889 f_print(fout, "\tif (_rpcsvcstate == _IDLE && _rpcsvccount == 0) {\n"); 890 if (tirpcflag) { 891 f_print(fout, "\t\tint size;\n"); 892 } else { 893 f_print(fout, "\t\textern fd_set svc_fdset;\n"); 894 f_print(fout, "\t\tstatic int size;\n"); 895 } 896 f_print(fout, "\t\tint i, openfd = 0;\n\n"); 897 if (tirpcflag) { 898 f_print(fout, "\t\tsize = svc_max_pollfd;\n"); 899 } else { 900 f_print(fout, "\t\tif (size == 0) {\n"); 901 f_print(fout, "\t\t\tsize = getdtablesize();\n"); 902 f_print(fout, "\t\t}\n"); 903 } 904 f_print(fout, 905 "\t\tfor (i = 0; i < size && openfd < 2; i++)\n"); 906 if (tirpcflag) { 907 f_print(fout, "\t\t\tif (svc_pollfd[i].fd >= 0)\n"); 908 } else { 909 f_print(fout, "\t\t\tif (FD_ISSET(i, &svc_fdset))\n"); 910 } 911 f_print(fout, "\t\t\t\topenfd++;\n"); 912 f_print(fout, "\t\tif (openfd <= 1)\n"); 913 f_print(fout, "\t\t\texit(0);\n"); 914 f_print(fout, "\t} else\n"); 915 f_print(fout, "\t\t_rpcsvcstate = _IDLE;\n\n"); 916 917 f_print(fout, "\t(void) signal(SIGALRM, %s closedown);\n", 918 Cflag? "(SIG_PF)" : "(void(*)())"); 919 f_print(fout, "\t(void) alarm(_RPCSVC_CLOSEDOWN/2);\n"); 920 f_print(fout, "}\n"); 921 } 922 923 /* 924 * Write the most of port monitor support 925 */ 926 static 927 write_pm_most(infile, netflag) 928 char *infile; 929 int netflag; 930 { 931 list *l; 932 definition *def; 933 version_list *vp; 934 935 f_print(fout, "\t(void) sigset(SIGPIPE, SIG_IGN);\n\n"); 936 f_print(fout, "\t/*\n"); 937 f_print(fout, "\t * If stdin looks like a TLI endpoint, we assume\n"); 938 f_print(fout, "\t * that we were started by a port monitor. If\n"); 939 f_print(fout, "\t * t_getstate fails with TBADF, this is not a\n"); 940 f_print(fout, "\t * TLI endpoint.\n"); 941 f_print(fout, "\t */\n"); 942 f_print(fout, "\tif (t_getstate(0) != -1 || t_errno != TBADF) {\n"); 943 f_print(fout, "\t\tchar *netid;\n"); 944 if (!netflag) { /* Not included by -n option */ 945 f_print(fout, "\t\tstruct netconfig *nconf = NULL;\n"); 946 f_print(fout, "\t\tSVCXPRT *%s;\n", TRANSP); 947 } 948 if (timerflag) 949 f_print(fout, "\t\tint pmclose;\n"); 950 /* 951 * Not necessary, defined in /usr/include/stdlib 952 * f_print(fout, "\t\textern char *getenv();\n"); 953 */ 954 f_print(fout, "\n"); 955 f_print(fout, "\t\t_rpcpmstart = 1;\n"); 956 open_log_file(infile, "\t\t"); 957 f_print(fout, 958 "\n\t\tif ((netid = getenv(\"NLSPROVIDER\")) == NULL) {\n"); 959 960 if (timerflag) { 961 f_print(fout, "\t\t/* started from inetd */\n"); 962 f_print(fout, "\t\t\tpmclose = 1;\n"); 963 } 964 f_print(fout, 965 "\t\t} else {\n"); 966 f_print(fout, "\t\t\tif ((nconf = getnetconfigent(netid)) == NULL)\n"); 967 sprintf(_errbuf, "cannot get transport info"); 968 print_err_message("\t\t\t\t"); 969 if (timerflag) 970 f_print(fout, 971 "\n\t\t\tpmclose = (t_getstate(0) != T_DATAXFER);\n"); 972 f_print(fout, "\t\t}\n"); 973 f_print(fout, 974 "\t\tif ((%s = svc_tli_create(0, nconf, NULL, 0, 0)) == NULL) {\n", 975 TRANSP); 976 sprintf(_errbuf, "cannot create server handle"); 977 print_err_message("\t\t\t"); 978 f_print(fout, "\t\t\texit(1);\n"); 979 f_print(fout, "\t\t}\n"); 980 f_print(fout, "\t\tif (nconf)\n"); 981 f_print(fout, "\t\t\tfreenetconfigent(nconf);\n"); 982 for (l = defined; l != NULL; l = l->next) { 983 def = (definition *) l->val; 984 if (def->def_kind != DEF_PROGRAM) { 985 continue; 986 } 987 for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { 988 f_print(fout, 989 "\t\tif (!svc_reg(%s, %s, %s, ", 990 TRANSP, def->def_name, vp->vers_name); 991 pvname(def->def_name, vp->vers_num); 992 f_print(fout, ", 0)) {\n"); 993 (void) sprintf(_errbuf, "unable to register (%s, %s).", 994 def->def_name, vp->vers_name); 995 print_err_message("\t\t\t"); 996 f_print(fout, "\t\t\texit(1);\n"); 997 f_print(fout, "\t\t}\n"); 998 } 999 } 1000 if (timerflag) { 1001 f_print(fout, "\t\tif (pmclose) {\n"); 1002 if (mtflag) { 1003 f_print(fout, 1004 "\t\t\tif (thr_create(NULL, 0, closedown, NULL,\n\t\t\t\t\t0, NULL) != 0) {\n"); 1005 f_print(fout, 1006 "\t\t\t\t_msgout(\"cannot create closedown thread\");\n"); 1007 f_print(fout, "\t\t\t\texit(1);\n"); 1008 f_print(fout, "\t\t\t}\n"); 1009 } else { 1010 f_print(fout, 1011 "\t\t\t(void) signal(SIGALRM, %s closedown);\n", 1012 Cflag? "(SIG_PF)" : "(void(*)())"); 1013 f_print(fout, 1014 "\t\t\t(void) alarm(_RPCSVC_CLOSEDOWN/2);\n"); 1015 } 1016 f_print(fout, "\t\t}\n"); 1017 } 1018 f_print(fout, "\t\tsvc_run();\n"); 1019 f_print(fout, "\t\texit(1);\n"); 1020 f_print(fout, "\t\t/* NOTREACHED */\n"); 1021 f_print(fout, "\t}"); 1022 } 1023 1024 /* 1025 * Support for backgrounding the server if self started. 1026 */ 1027 static 1028 write_rpc_svc_fg(infile, sp) 1029 char *infile; 1030 char *sp; 1031 { 1032 f_print(fout, "#ifndef RPC_SVC_FG\n"); 1033 f_print(fout, "#pragma weak closefrom\n"); 1034 f_print(fout, "%sextern void closefrom();\n", sp); 1035 f_print(fout, "%sint size;\n", sp); 1036 if (tirpcflag) 1037 f_print(fout, "%sstruct rlimit rl;\n", sp); 1038 if (inetdflag) 1039 f_print(fout, "%sint pid, i;\n\n", sp); 1040 f_print(fout, "%spid = fork();\n", sp); 1041 f_print(fout, "%sif (pid < 0) {\n", sp); 1042 f_print(fout, "%s\tperror(\"cannot fork\");\n", sp); 1043 f_print(fout, "%s\texit(1);\n", sp); 1044 f_print(fout, "%s}\n", sp); 1045 f_print(fout, "%sif (pid)\n", sp); 1046 f_print(fout, "%s\texit(0);\n", sp); 1047 /* close all file descriptors */ 1048 if (tirpcflag) { 1049 f_print(fout, "%sif (closefrom != NULL)\n", sp); 1050 f_print(fout, "%s\tclosefrom(0);\n", sp); 1051 f_print(fout, "%selse {\n", sp); 1052 f_print(fout, "%s\trl.rlim_max = 0;\n", sp); 1053 f_print(fout, "%s\tgetrlimit(RLIMIT_NOFILE, &rl);\n", sp); 1054 f_print(fout, "%s\tif ((size = rl.rlim_max) == 0)\n", sp); 1055 f_print(fout, "%s\t\texit(1);\n", sp); 1056 f_print(fout, "%s\tfor (i = 0; i < size; i++)\n", sp); 1057 f_print(fout, "%s\t\t(void) close(i);\n", sp); 1058 f_print(fout, "%s}\n", sp); 1059 } else { 1060 f_print(fout, "%s\tsize = getdtablesize();\n", sp); 1061 f_print(fout, "%s\tfor (i = 0; i < size; i++)\n", sp); 1062 f_print(fout, "%s\t\t(void) close(i);\n", sp); 1063 } 1064 /* Redirect stderr and stdout to /dev/null */ 1065 f_print(fout, "%si = open(\"/dev/null\", 2);\n", sp); 1066 f_print(fout, "%s(void) dup2(i, 1);\n", sp); 1067 f_print(fout, "%s(void) dup2(i, 2);\n", sp); 1068 /* This removes control of the controlling terminal */ 1069 if (tirpcflag) 1070 f_print(fout, "%ssetsid();\n", sp); 1071 else { 1072 f_print(fout, "%si = open(\"/dev/tty\", 2);\n", sp); 1073 f_print(fout, "%sif (i >= 0) {\n", sp); 1074 f_print(fout, 1075 "%s\t(void) ioctl(i, TIOCNOTTY, (char *)NULL);\n", sp); 1076 f_print(fout, "%s\t(void) close(i);\n", sp); 1077 f_print(fout, "%s}\n", sp); 1078 } 1079 if (!logflag) 1080 open_log_file(infile, sp); 1081 f_print(fout, "#endif\n"); 1082 if (logflag) 1083 open_log_file(infile, sp); 1084 } 1085 1086 static 1087 open_log_file(infile, sp) 1088 char *infile; 1089 char *sp; 1090 { 1091 char *s; 1092 1093 s = strrchr(infile, '.'); 1094 if (s) 1095 *s = '\0'; 1096 f_print(fout, "%sopenlog(\"%s\", LOG_PID, LOG_DAEMON);\n", sp, infile); 1097 if (s) 1098 *s = '.'; 1099 } 1100 1101 1102 1103 1104 /* 1105 * write a registration for the given transport for Inetd 1106 */ 1107 void 1108 write_inetd_register(transp) 1109 char *transp; 1110 { 1111 list *l; 1112 definition *def; 1113 version_list *vp; 1114 char *sp; 1115 int isudp; 1116 char tmpbuf[32]; 1117 1118 if (inetdflag) 1119 sp = "\t"; 1120 else 1121 sp = ""; 1122 if (streq(transp, "udp")) 1123 isudp = 1; 1124 else 1125 isudp = 0; 1126 f_print(fout, "\n"); 1127 if (inetdflag) { 1128 f_print(fout, 1129 "\tif ((_rpcfdtype == 0) || (_rpcfdtype == %s)) {\n", 1130 isudp ? "SOCK_DGRAM" : "SOCK_STREAM"); 1131 } 1132 f_print(fout, "%s\t%s = svc%s_create(%s", 1133 sp, TRANSP, transp, inetdflag? "sock": "RPC_ANYSOCK"); 1134 if (!isudp) 1135 f_print(fout, ", 0, 0"); 1136 f_print(fout, ");\n"); 1137 f_print(fout, "%s\tif (%s == NULL) {\n", sp, TRANSP); 1138 (void) sprintf(_errbuf, "cannot create %s service.", transp); 1139 (void) sprintf(tmpbuf, "%s\t\t", sp); 1140 print_err_message(tmpbuf); 1141 f_print(fout, "%s\t\texit(1);\n", sp); 1142 f_print(fout, "%s\t}\n", sp); 1143 1144 if (inetdflag) { 1145 f_print(fout, "%s\tif (!_rpcpmstart)\n\t", sp); 1146 f_print(fout, "%s\tproto = IPPROTO_%s;\n", 1147 sp, isudp ? "UDP": "TCP"); 1148 } 1149 for (l = defined; l != NULL; l = l->next) { 1150 def = (definition *) l->val; 1151 if (def->def_kind != DEF_PROGRAM) { 1152 continue; 1153 } 1154 for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { 1155 f_print(fout, "%s\tif (!svc_register(%s, %s, %s, ", 1156 sp, TRANSP, def->def_name, vp->vers_name); 1157 pvname(def->def_name, vp->vers_num); 1158 if (inetdflag) 1159 f_print(fout, ", proto)) {\n"); 1160 else 1161 f_print(fout, ", IPPROTO_%s)) {\n", 1162 isudp ? "UDP": "TCP"); 1163 (void) sprintf(_errbuf, 1164 "unable to register (%s, %s, %s).", 1165 def->def_name, vp->vers_name, transp); 1166 print_err_message(tmpbuf); 1167 f_print(fout, "%s\t\texit(1);\n", sp); 1168 f_print(fout, "%s\t}\n", sp); 1169 } 1170 } 1171 if (inetdflag) 1172 f_print(fout, "\t}\n"); 1173 } 1174