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