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