home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / N / TCPIP / NETKIT-B.05 / NETKIT-B / NetKit-B-0.05 / rpcgen.new / rpc_svcout.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-19  |  24.5 KB  |  922 lines

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