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