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