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