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