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