Annotation of src/usr.bin/rpcgen/rpc_main.c, Revision 1.32
1.32 ! deraadt 1: /* $OpenBSD: rpc_main.c,v 1.31 2015/10/10 20:57:00 deraadt Exp $ */
1.11 deraadt 2: /* $NetBSD: rpc_main.c,v 1.9 1996/02/19 11:12:43 pk Exp $ */
1.25 millert 3:
1.1 deraadt 4: /*
1.25 millert 5: * Copyright (c) 2010, Oracle America, Inc.
1.1 deraadt 6: *
1.25 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.25 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.25 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: /*
1.11 deraadt 36: * rpc_main.c, Top level of the RPC protocol compiler.
1.1 deraadt 37: */
38:
1.11 deraadt 39: #define RPCGEN_VERSION "199506"/* This program's version (year & month) */
1.2 niklas 40:
1.15 deraadt 41: #include <sys/types.h>
42: #include <sys/file.h>
1.1 deraadt 43: #include <stdio.h>
44: #include <stdlib.h>
45: #include <string.h>
1.15 deraadt 46: #include <unistd.h>
1.29 deraadt 47: #include <limits.h>
1.15 deraadt 48: #include <ctype.h>
1.1 deraadt 49: #include <sys/stat.h>
50: #include "rpc_parse.h"
51: #include "rpc_util.h"
52: #include "rpc_scan.h"
53:
54: #define EXTEND 1 /* alias for TRUE */
1.11 deraadt 55: #define DONT_EXTEND 0 /* alias for FALSE */
1.1 deraadt 56:
57: #define SVR4_CPP "/usr/ccs/lib/cpp"
58: #define SUNOS_CPP "/lib/cpp"
1.11 deraadt 59: static int cppDefined = 0; /* explicit path for C preprocessor */
1.1 deraadt 60:
61: struct commandline {
1.11 deraadt 62: int cflag; /* xdr C routines */
63: int hflag; /* header file */
64: int lflag; /* client side stubs */
65: int mflag; /* server side stubs */
66: int nflag; /* netid flag */
67: int sflag; /* server stubs for the given transport */
68: int tflag; /* dispatch Table file */
69: int Ssflag; /* produce server sample code */
70: int Scflag; /* produce client sample code */
71: char *infile; /* input module name */
72: char *outfile;/* output module name */
1.1 deraadt 73: };
74:
1.11 deraadt 75: static char *cmdname;
1.1 deraadt 76:
1.11 deraadt 77: static char *svcclosetime = "120";
78: static char *CPP = "/usr/bin/cpp";
79: static char CPPFLAGS[] = "-C";
1.29 deraadt 80: static char pathbuf[PATH_MAX];
1.11 deraadt 81: static char *allv[] = {
1.1 deraadt 82: "rpcgen", "-s", "udp", "-s", "tcp",
83: };
1.11 deraadt 84: static int allc = sizeof(allv) / sizeof(allv[0]);
85: static char *allnv[] = {
1.1 deraadt 86: "rpcgen", "-s", "netpath",
87: };
1.11 deraadt 88: static int allnc = sizeof(allnv) / sizeof(allnv[0]);
1.1 deraadt 89:
90: #define ARGLISTLEN 20
91: #define FIXEDARGS 2
92:
1.11 deraadt 93: static char *arglist[ARGLISTLEN];
94: static int argcount = FIXEDARGS;
1.1 deraadt 95:
96:
1.11 deraadt 97: int nonfatalerrors; /* errors */
98: int inetdflag /* = 1 */ ; /* Support for inetd *//* is now the
99: * default */
100: int pmflag; /* Support for port monitors */
101: int logflag; /* Use syslog instead of fprintf for errors */
102: int tblflag; /* Support for dispatch table file */
103: int callerflag; /* Generate svc_caller() function */
1.1 deraadt 104:
105: #define INLINE 3
1.11 deraadt 106: /* length at which to start doing an inline */
1.1 deraadt 107:
1.11 deraadt 108: int doinline = INLINE; /* length at which to start doing an
109: * inline. 3 = default if 0, no
110: * xdr_inline code */
111:
112: int indefinitewait; /* If started by port monitors, hang till it
113: * wants */
114: int exitnow; /* If started by port monitors, exit after
115: * the call */
116: int timerflag; /* TRUE if !indefinite && !exitnow */
117: int newstyle; /* newstyle of passing arguments (by value) */
118: int Cflag = 0; /* ANSI C syntax */
119: static int allfiles; /* generate all files */
120: int tirpcflag = 0; /* generating code for tirpc, by default */
1.1 deraadt 121:
1.15 deraadt 122: static void c_output(char *, char *, int, char *);
123: static void h_output(char *, char *, int, char *);
124: static void s_output(int, char **, char *, char *, int, char *, int, int);
125: static void l_output(char *, char *, int, char *);
126: static void t_output(char *, char *, int, char *);
127: static void svc_output(char *, char *, int, char *);
128: static void clnt_output(char *, char *, int, char *);
129: static int do_registers(int, char **);
1.12 millert 130: static void addarg(char *);
131: static void putarg(int, char *);
132: static void clear_args(void);
133: static void checkfiles(char *, char *);
134: static int parseargs(int, char **, struct commandline *);
1.15 deraadt 135: static void usage(void);
136: void c_initialize(void);
1.1 deraadt 137:
1.11 deraadt 138: int
1.19 deraadt 139: main(int argc, char *argv[])
1.1 deraadt 140: {
141: struct commandline cmd;
1.31 deraadt 142:
1.32 ! deraadt 143: if (pledge("stdio rpath wpath cpath proc exec", NULL) == -1) {
1.31 deraadt 144: perror("pledge");
1.32 ! deraadt 145: exit(1);
! 146: }
1.1 deraadt 147:
1.11 deraadt 148: (void) memset((char *) &cmd, 0, sizeof(struct commandline));
1.1 deraadt 149: clear_args();
150: if (!parseargs(argc, argv, &cmd))
151: usage();
152:
1.11 deraadt 153: if (cmd.cflag || cmd.hflag || cmd.lflag || cmd.tflag || cmd.sflag ||
154: cmd.mflag || cmd.nflag || cmd.Ssflag || cmd.Scflag) {
155: checkfiles(cmd.infile, cmd.outfile);
156: } else
157: checkfiles(cmd.infile, NULL);
1.1 deraadt 158:
159: if (cmd.cflag) {
160: c_output(cmd.infile, "-DRPC_XDR", DONT_EXTEND, cmd.outfile);
161: } else if (cmd.hflag) {
162: h_output(cmd.infile, "-DRPC_HDR", DONT_EXTEND, cmd.outfile);
163: } else if (cmd.lflag) {
164: l_output(cmd.infile, "-DRPC_CLNT", DONT_EXTEND, cmd.outfile);
165: } else if (cmd.sflag || cmd.mflag || (cmd.nflag)) {
1.11 deraadt 166: s_output(argc, argv, cmd.infile, "-DRPC_SVC", DONT_EXTEND,
1.1 deraadt 167: cmd.outfile, cmd.mflag, cmd.nflag);
168: } else if (cmd.tflag) {
169: t_output(cmd.infile, "-DRPC_TBL", DONT_EXTEND, cmd.outfile);
1.11 deraadt 170: } else if (cmd.Ssflag) {
171: svc_output(cmd.infile, "-DRPC_SERVER", DONT_EXTEND, cmd.outfile);
1.1 deraadt 172: } else if (cmd.Scflag) {
1.11 deraadt 173: clnt_output(cmd.infile, "-DRPC_CLIENT", DONT_EXTEND, cmd.outfile);
1.1 deraadt 174: } else {
175: /* the rescans are required, since cpp may effect input */
176: c_output(cmd.infile, "-DRPC_XDR", EXTEND, "_xdr.c");
177: reinitialize();
178: h_output(cmd.infile, "-DRPC_HDR", EXTEND, ".h");
179: reinitialize();
180: l_output(cmd.infile, "-DRPC_CLNT", EXTEND, "_clnt.c");
181: reinitialize();
1.11 deraadt 182: if (inetdflag || !tirpcflag)
183: s_output(allc, allv, cmd.infile, "-DRPC_SVC", EXTEND,
184: "_svc.c", cmd.mflag, cmd.nflag);
1.1 deraadt 185: else
1.11 deraadt 186: s_output(allnc, allnv, cmd.infile, "-DRPC_SVC",
187: EXTEND, "_svc.c", cmd.mflag, cmd.nflag);
1.1 deraadt 188: if (tblflag) {
189: reinitialize();
190: t_output(cmd.infile, "-DRPC_TBL", EXTEND, "_tbl.i");
191: }
192: if (allfiles) {
1.11 deraadt 193: reinitialize();
194: svc_output(cmd.infile, "-DRPC_SERVER", EXTEND, "_server.c");
1.1 deraadt 195: }
196: if (allfiles) {
1.11 deraadt 197: reinitialize();
198: clnt_output(cmd.infile, "-DRPC_CLIENT", EXTEND, "_client.c");
199: }
1.1 deraadt 200: }
201: exit(nonfatalerrors);
202: /* NOTREACHED */
203: }
204:
205: /*
1.11 deraadt 206: * add extension to filename
1.1 deraadt 207: */
208: static char *
1.19 deraadt 209: extendfile(char *path, char *ext)
1.1 deraadt 210: {
211: char *file;
212: char *res;
213: char *p;
1.18 deraadt 214: size_t len;
1.1 deraadt 215:
216: if ((file = strrchr(path, '/')) == NULL)
217: file = path;
218: else
219: file++;
220:
1.18 deraadt 221: len = strlen(file) + strlen(ext) + 1;
1.30 deraadt 222: res = malloc(len);
1.15 deraadt 223: if (res == NULL) {
224: fprintf(stderr, "could not allocate memory\n");
225: exit(1);
226: }
1.1 deraadt 227: p = strrchr(file, '.');
1.11 deraadt 228: if (p == NULL)
1.1 deraadt 229: p = file + strlen(file);
1.18 deraadt 230: (void) strlcpy(res, file, len);
231: (void) strlcpy(res + (p - file), ext, len - (p - file));
1.1 deraadt 232: return (res);
233: }
234:
235: /*
1.11 deraadt 236: * Open output file with given extension
1.1 deraadt 237: */
1.11 deraadt 238: static void
1.19 deraadt 239: open_output(char *infile, char *outfile)
1.1 deraadt 240: {
241:
242: if (outfile == NULL) {
243: fout = stdout;
244: return;
245: }
246: if (infile != NULL && streq(outfile, infile)) {
1.14 deraadt 247: fprintf(stderr, "%s: output would overwrite %s\n", cmdname,
1.11 deraadt 248: infile);
1.1 deraadt 249: crash();
250: }
251: fout = fopen(outfile, "w");
252: if (fout == NULL) {
1.14 deraadt 253: fprintf(stderr, "%s: unable to open ", cmdname);
1.1 deraadt 254: perror(outfile);
255: crash();
256: }
257: record_open(outfile);
258:
259: }
260:
1.15 deraadt 261: static void
1.19 deraadt 262: add_warning(void)
1.1 deraadt 263: {
1.14 deraadt 264: fprintf(fout, "/*\n");
265: fprintf(fout, " * Please do not edit this file.\n");
266: fprintf(fout, " * It was generated using rpcgen.\n");
267: fprintf(fout, " */\n\n");
1.1 deraadt 268: }
269:
270: /* clear list of arguments */
1.15 deraadt 271: static void
1.19 deraadt 272: clear_args(void)
1.1 deraadt 273: {
1.11 deraadt 274: int i;
275: for (i = FIXEDARGS; i < ARGLISTLEN; i++)
276: arglist[i] = NULL;
277: argcount = FIXEDARGS;
1.1 deraadt 278: }
279:
280: /* make sure that a CPP exists */
1.15 deraadt 281: static void
1.19 deraadt 282: find_cpp(void)
1.1 deraadt 283: {
1.11 deraadt 284: struct stat buf;
1.1 deraadt 285:
1.11 deraadt 286: /* SVR4 or explicit cpp does not exist */
287: if (stat(CPP, &buf) < 0) {
288: if (cppDefined) {
289: fprintf(stderr, "cannot find C preprocessor: %s \n", CPP);
290: crash();
291: } else {
292: /* try the other one */
293: CPP = SUNOS_CPP;
294: if (stat(CPP, &buf) < 0) { /* can't find any cpp */
295: fprintf(stderr,
296: "cannot find any C preprocessor: %s\n", CPP);
297: crash();
298: }
299: }
300: }
1.1 deraadt 301: }
302:
303: /*
1.11 deraadt 304: * Open input file with given define for C-preprocessor
1.1 deraadt 305: */
1.15 deraadt 306: static void
1.19 deraadt 307: open_input(char *infile, char *define)
1.1 deraadt 308: {
1.11 deraadt 309: int pd[2];
1.1 deraadt 310:
311: infilename = (infile == NULL) ? "<stdin>" : infile;
312: (void) pipe(pd);
313: switch (fork()) {
314: case 0:
315: find_cpp();
316: putarg(0, CPP);
317: putarg(1, CPPFLAGS);
318: addarg(define);
319: addarg(infile);
1.11 deraadt 320: addarg((char *) NULL);
1.1 deraadt 321: (void) close(1);
322: (void) dup2(pd[1], 1);
323: (void) close(pd[0]);
324: execv(arglist[0], arglist);
325: perror("execv");
326: exit(1);
327: case -1:
328: perror("fork");
329: exit(1);
330: }
331: (void) close(pd[1]);
332: fin = fdopen(pd[0], "r");
333: if (fin == NULL) {
1.14 deraadt 334: fprintf(stderr, "%s: ", cmdname);
1.1 deraadt 335: perror(infilename);
336: crash();
337: }
338: }
339:
340: /* valid tirpc nettypes */
1.11 deraadt 341: static char *valid_ti_nettypes[] = {
342: "netpath",
343: "visible",
344: "circuit_v",
345: "datagram_v",
346: "circuit_n",
347: "datagram_n",
348: "udp",
349: "tcp",
350: "raw",
351: NULL
352: };
1.1 deraadt 353:
354: /* valid inetd nettypes */
1.11 deraadt 355: static char *valid_i_nettypes[] = {
356: "udp",
357: "tcp",
358: NULL
1.1 deraadt 359: };
360:
1.15 deraadt 361: static int
1.19 deraadt 362: check_nettype(char *name, char *list_to_check[])
1.11 deraadt 363: {
364: int i;
365: for (i = 0; list_to_check[i] != NULL; i++) {
366: if (strcmp(name, list_to_check[i]) == 0)
367: return 1;
368: }
1.14 deraadt 369: fprintf(stderr, "illegal nettype :\'%s\'\n", name);
1.11 deraadt 370: return 0;
1.1 deraadt 371: }
372:
373: /*
374: * Compile into an XDR routine output file
375: */
376:
1.15 deraadt 377: static void
1.1 deraadt 378: c_output(infile, define, extend, outfile)
1.11 deraadt 379: char *infile;
380: char *define;
381: int extend;
382: char *outfile;
383: {
384: definition *def;
385: char *include;
386: char *outfilename;
387: long tell;
1.1 deraadt 388:
389: c_initialize();
1.11 deraadt 390: open_input(infile, define);
1.1 deraadt 391: outfilename = extend ? extendfile(infile, outfile) : outfile;
392: open_output(infile, outfilename);
393: add_warning();
394: if (infile && (include = extendfile(infile, ".h"))) {
1.14 deraadt 395: fprintf(fout, "#include \"%s\"\n", include);
1.1 deraadt 396: free(include);
397: /* .h file already contains rpc/rpc.h */
398: } else
1.14 deraadt 399: fprintf(fout, "#include <rpc/rpc.h>\n");
1.1 deraadt 400: tell = ftell(fout);
1.15 deraadt 401: while ((def = get_definition())) {
1.1 deraadt 402: emit(def);
403: }
404: if (extend && tell == ftell(fout)) {
405: (void) unlink(outfilename);
406: }
407: }
408:
409:
1.15 deraadt 410: void
411: c_initialize(void)
1.1 deraadt 412: {
413:
1.11 deraadt 414: /* add all the starting basic types */
1.1 deraadt 415:
1.11 deraadt 416: add_type(1, "int");
417: add_type(1, "long");
418: add_type(1, "short");
419: add_type(1, "bool");
1.1 deraadt 420:
1.11 deraadt 421: add_type(1, "u_int");
422: add_type(1, "u_long");
423: add_type(1, "u_short");
1.1 deraadt 424:
425: }
426:
1.26 guenther 427: static const char rpcgen_table_dcl[] = "struct rpcgen_table {\n\
1.1 deraadt 428: char *(*proc)();\n\
429: xdrproc_t xdr_arg;\n\
1.13 deraadt 430: unsigned int len_arg;\n\
1.1 deraadt 431: xdrproc_t xdr_res;\n\
1.13 deraadt 432: unsigned int len_res;\n\
1.1 deraadt 433: };\n";
434:
435:
1.19 deraadt 436: static char *
437: generate_guard(char *pathname)
1.1 deraadt 438: {
1.21 dhill 439: char *filename, *guard, *tmp, *tmp2;
1.1 deraadt 440:
1.11 deraadt 441: filename = strrchr(pathname, '/'); /* find last component */
442: filename = ((filename == 0) ? pathname : filename + 1);
1.1 deraadt 443: guard = strdup(filename);
1.15 deraadt 444: if (guard == NULL) {
445: fprintf(stderr, "out of memory while processing %s\n", filename);
446: crash();
447: }
448:
1.1 deraadt 449: /* convert to upper case */
450: tmp = guard;
451: while (*tmp) {
1.27 deraadt 452: if (islower((unsigned char)*tmp))
453: *tmp = toupper((unsigned char)*tmp);
1.1 deraadt 454: tmp++;
455: }
1.11 deraadt 456:
1.21 dhill 457: tmp2 = extendfile(guard, "_H_RPCGEN");
458: free(guard);
459: guard = tmp2;
460:
1.11 deraadt 461: return (guard);
1.1 deraadt 462: }
463:
464: /*
465: * Compile into an XDR header file
466: */
467:
1.15 deraadt 468: static void
1.1 deraadt 469: h_output(infile, define, extend, outfile)
1.11 deraadt 470: char *infile;
471: char *define;
472: int extend;
473: char *outfile;
474: {
475: definition *def;
476: char *outfilename;
477: long tell;
478: char *guard;
479: list *l;
1.1 deraadt 480:
481: open_input(infile, define);
1.11 deraadt 482: outfilename = extend ? extendfile(infile, outfile) : outfile;
1.1 deraadt 483: open_output(infile, outfilename);
484: add_warning();
1.11 deraadt 485: guard = generate_guard(outfilename ? outfilename : infile);
1.1 deraadt 486:
1.14 deraadt 487: fprintf(fout, "#ifndef _%s\n#define _%s\n\n", guard,
1.1 deraadt 488: guard);
489:
1.14 deraadt 490: fprintf(fout, "#define RPCGEN_VERSION\t%s\n\n", RPCGEN_VERSION);
491: fprintf(fout, "#include <rpc/rpc.h>\n\n");
1.1 deraadt 492:
493: tell = ftell(fout);
494: /* print data definitions */
1.15 deraadt 495: while ((def = get_definition())) {
1.1 deraadt 496: print_datadef(def);
497: }
498:
1.11 deraadt 499: /*
500: * print function declarations. Do this after data definitions
501: * because they might be used as arguments for functions
502: */
1.1 deraadt 503: for (l = defined; l != NULL; l = l->next) {
504: print_funcdef(l->val);
505: }
506: if (extend && tell == ftell(fout)) {
507: (void) unlink(outfilename);
508: } else if (tblflag) {
1.14 deraadt 509: fprintf(fout, rpcgen_table_dcl);
1.1 deraadt 510: }
1.14 deraadt 511: fprintf(fout, "\n#endif /* !_%s */\n", guard);
1.21 dhill 512:
513: free(guard);
1.1 deraadt 514: }
515:
516: /*
517: * Compile into an RPC service
518: */
1.15 deraadt 519: static void
1.1 deraadt 520: s_output(argc, argv, infile, define, extend, outfile, nomain, netflag)
1.11 deraadt 521: int argc;
522: char *argv[];
523: char *infile;
524: char *define;
525: int extend;
526: char *outfile;
527: int nomain;
528: int netflag;
529: {
530: char *include;
531: definition *def;
532: int foundprogram = 0;
533: char *outfilename;
1.1 deraadt 534:
535: open_input(infile, define);
536: outfilename = extend ? extendfile(infile, outfile) : outfile;
537: open_output(infile, outfilename);
538: add_warning();
539: if (infile && (include = extendfile(infile, ".h"))) {
1.14 deraadt 540: fprintf(fout, "#include \"%s\"\n", include);
1.1 deraadt 541: free(include);
542: } else
1.14 deraadt 543: fprintf(fout, "#include <rpc/rpc.h>\n");
1.1 deraadt 544:
1.23 weingart 545: fprintf(fout, "#include <unistd.h>\n");
1.14 deraadt 546: fprintf(fout, "#include <stdio.h>\n");
547: fprintf(fout, "#include <stdlib.h>/* getenv, exit */\n");
1.1 deraadt 548: if (Cflag) {
1.14 deraadt 549: fprintf(fout,
1.1 deraadt 550: "#include <rpc/pmap_clnt.h> /* for pmap_unset */\n");
1.14 deraadt 551: fprintf(fout, "#include <string.h> /* strcmp */ \n");
1.1 deraadt 552: }
1.14 deraadt 553: fprintf(fout, "#include <netdb.h>\n"); /* evas */
1.1 deraadt 554: if (strcmp(svcclosetime, "-1") == 0)
555: indefinitewait = 1;
556: else if (strcmp(svcclosetime, "0") == 0)
557: exitnow = 1;
558: else if (inetdflag || pmflag) {
1.14 deraadt 559: fprintf(fout, "#include <signal.h>\n");
1.11 deraadt 560: timerflag = 1;
1.1 deraadt 561: }
1.11 deraadt 562: if (!tirpcflag && inetdflag)
1.14 deraadt 563: fprintf(fout, "#include <sys/ttycom.h>/* TIOCNOTTY */\n");
1.11 deraadt 564: if (Cflag && (inetdflag || pmflag)) {
1.14 deraadt 565: fprintf(fout, "#ifdef __cplusplus\n");
566: fprintf(fout, "#include <sysent.h> /* getdtablesize, open */\n");
567: fprintf(fout, "#endif /* __cplusplus */\n");
1.1 deraadt 568:
1.11 deraadt 569: if (tirpcflag)
1.14 deraadt 570: fprintf(fout, "#include <unistd.h> /* setsid */\n");
1.1 deraadt 571: }
1.11 deraadt 572: if (tirpcflag)
1.14 deraadt 573: fprintf(fout, "#include <sys/types.h>\n");
1.1 deraadt 574:
1.14 deraadt 575: fprintf(fout, "#include <memory.h>\n");
1.1 deraadt 576: if (tirpcflag)
1.14 deraadt 577: fprintf(fout, "#include <stropts.h>\n");
1.1 deraadt 578:
1.11 deraadt 579: if (inetdflag || !tirpcflag) {
1.14 deraadt 580: fprintf(fout, "#include <sys/socket.h>\n");
581: fprintf(fout, "#include <netinet/in.h>\n");
1.11 deraadt 582: }
583: if ((netflag || pmflag) && tirpcflag) {
1.14 deraadt 584: fprintf(fout, "#include <netconfig.h>\n");
1.1 deraadt 585: }
1.15 deraadt 586: if (/* timerflag && */ tirpcflag)
1.14 deraadt 587: fprintf(fout, "#include <sys/resource.h> /* rlimit */\n");
1.1 deraadt 588: if (logflag || inetdflag || pmflag) {
1.14 deraadt 589: fprintf(fout, "#include <syslog.h>\n");
590: fprintf(fout, "#include <errno.h>\n");
1.1 deraadt 591: }
592: /* for ANSI-C */
1.14 deraadt 593: fprintf(fout, "\n#ifdef __STDC__\n#define SIG_PF void(*)(int)\n#endif\n");
1.1 deraadt 594:
1.14 deraadt 595: fprintf(fout, "\n#ifdef DEBUG\n#define RPC_SVC_FG\n#endif\n");
1.1 deraadt 596: if (timerflag)
1.14 deraadt 597: fprintf(fout, "\n#define _RPCSVC_CLOSEDOWN %s\n", svcclosetime);
1.15 deraadt 598: while ((def = get_definition())) {
1.1 deraadt 599: foundprogram |= (def->def_kind == DEF_PROGRAM);
600: }
601: if (extend && !foundprogram) {
602: (void) unlink(outfilename);
603: return;
604: }
1.11 deraadt 605: if (callerflag) /* EVAS */
1.14 deraadt 606: fprintf(fout, "\nstatic SVCXPRT *caller;\n"); /* EVAS */
1.1 deraadt 607: write_most(infile, netflag, nomain);
608: if (!nomain) {
1.11 deraadt 609: if (!do_registers(argc, argv)) {
610: if (outfilename)
611: (void) unlink(outfilename);
612: usage();
1.1 deraadt 613: }
614: write_rest();
615: }
616: }
617:
618: /*
619: * generate client side stubs
620: */
1.15 deraadt 621: static void
1.1 deraadt 622: l_output(infile, define, extend, outfile)
1.11 deraadt 623: char *infile;
624: char *define;
625: int extend;
626: char *outfile;
627: {
628: char *include;
629: definition *def;
630: int foundprogram = 0;
631: char *outfilename;
1.1 deraadt 632:
633: open_input(infile, define);
634: outfilename = extend ? extendfile(infile, outfile) : outfile;
635: open_output(infile, outfilename);
636: add_warning();
637: if (Cflag)
1.14 deraadt 638: fprintf(fout, "#include <memory.h> /* for memset */\n");
1.1 deraadt 639: if (infile && (include = extendfile(infile, ".h"))) {
1.14 deraadt 640: fprintf(fout, "#include \"%s\"\n", include);
1.1 deraadt 641: free(include);
642: } else
1.14 deraadt 643: fprintf(fout, "#include <rpc/rpc.h>\n");
1.15 deraadt 644: while ((def = get_definition()))
1.1 deraadt 645: foundprogram |= (def->def_kind == DEF_PROGRAM);
1.11 deraadt 646:
1.1 deraadt 647: if (extend && !foundprogram) {
648: (void) unlink(outfilename);
649: return;
650: }
651: write_stubs();
652: }
653:
654: /*
655: * generate the dispatch table
656: */
1.15 deraadt 657: static void
1.1 deraadt 658: t_output(infile, define, extend, outfile)
1.11 deraadt 659: char *infile;
660: char *define;
661: int extend;
662: char *outfile;
663: {
664: definition *def;
665: int foundprogram = 0;
666: char *outfilename;
1.1 deraadt 667:
668: open_input(infile, define);
669: outfilename = extend ? extendfile(infile, outfile) : outfile;
670: open_output(infile, outfilename);
671: add_warning();
1.15 deraadt 672: while ((def = get_definition()))
1.1 deraadt 673: foundprogram |= (def->def_kind == DEF_PROGRAM);
1.11 deraadt 674:
1.1 deraadt 675: if (extend && !foundprogram) {
676: (void) unlink(outfilename);
677: return;
678: }
679: write_tables();
680: }
681:
682: /* sample routine for the server template */
1.15 deraadt 683: static void
1.1 deraadt 684: svc_output(infile, define, extend, outfile)
1.11 deraadt 685: char *infile;
686: char *define;
687: int extend;
688: char *outfile;
689: {
690: definition *def;
691: char *include;
692: char *outfilename;
693: long tell;
694:
695: open_input(infile, define);
696: outfilename = extend ? extendfile(infile, outfile) : outfile;
697: checkfiles(infile, outfilename); /* check if outfile already
698: * exists. if so, print an
699: * error message and exit */
700: open_output(infile, outfilename);
701: add_sample_msg();
702:
703: if (infile && (include = extendfile(infile, ".h"))) {
1.14 deraadt 704: fprintf(fout, "#include \"%s\"\n", include);
1.11 deraadt 705: free(include);
706: } else
1.14 deraadt 707: fprintf(fout, "#include <rpc/rpc.h>\n");
1.11 deraadt 708:
709: tell = ftell(fout);
1.15 deraadt 710: while ((def = get_definition()))
1.11 deraadt 711: write_sample_svc(def);
712:
713: if (extend && tell == ftell(fout))
714: (void) unlink(outfilename);
1.1 deraadt 715: }
716:
717:
718: /* sample main routine for client */
1.15 deraadt 719: static void
1.1 deraadt 720: clnt_output(infile, define, extend, outfile)
1.11 deraadt 721: char *infile;
722: char *define;
723: int extend;
724: char *outfile;
725: {
726: definition *def;
727: char *include, *outfilename;
728: long tell;
729: int has_program = 0;
730:
731: open_input(infile, define);
732: outfilename = extend ? extendfile(infile, outfile) : outfile;
733:
734: /*
735: * check if outfile already exists. if so,
736: * print an error message and exit
737: */
738: checkfiles(infile, outfilename);
739:
740: open_output(infile, outfilename);
741: add_sample_msg();
742: if (infile && (include = extendfile(infile, ".h"))) {
1.14 deraadt 743: fprintf(fout, "#include \"%s\"\n", include);
1.11 deraadt 744: free(include);
745: } else
1.14 deraadt 746: fprintf(fout, "#include <rpc/rpc.h>\n");
1.11 deraadt 747: tell = ftell(fout);
1.15 deraadt 748: while ((def = get_definition()))
1.11 deraadt 749: has_program += write_sample_clnt(def);
750:
751: if (has_program)
752: write_sample_clnt_main();
753:
754: if (extend && tell == ftell(fout))
755: (void) unlink(outfilename);
1.1 deraadt 756: }
757:
758: /*
1.11 deraadt 759: * Perform registrations for service output
1.1 deraadt 760: * Return 0 if failed; 1 otherwise.
761: */
1.15 deraadt 762: static int
1.11 deraadt 763: do_registers(argc, argv)
764: int argc;
765: char *argv[];
1.1 deraadt 766: {
1.11 deraadt 767: int i;
1.1 deraadt 768:
1.11 deraadt 769: if (inetdflag || !tirpcflag) {
1.1 deraadt 770: for (i = 1; i < argc; i++) {
771: if (streq(argv[i], "-s")) {
1.11 deraadt 772: if (!check_nettype(argv[i + 1], valid_i_nettypes))
773: return 0;
1.1 deraadt 774: write_inetd_register(argv[i + 1]);
775: i++;
776: }
777: }
778: } else {
779: for (i = 1; i < argc; i++)
1.11 deraadt 780: if (streq(argv[i], "-s")) {
781: if (!check_nettype(argv[i + 1], valid_ti_nettypes))
782: return 0;
1.1 deraadt 783: write_nettype_register(argv[i + 1]);
784: i++;
785: } else if (streq(argv[i], "-n")) {
786: write_netid_register(argv[i + 1]);
787: i++;
788: }
789: }
790: return 1;
791: }
792:
793: /*
794: * Add another argument to the arg list
795: */
796: static void
797: addarg(cp)
1.11 deraadt 798: char *cp;
1.1 deraadt 799: {
800: if (argcount >= ARGLISTLEN) {
1.14 deraadt 801: fprintf(stderr, "rpcgen: too many defines\n");
1.1 deraadt 802: crash();
1.11 deraadt 803: /* NOTREACHED */
1.1 deraadt 804: }
805: arglist[argcount++] = cp;
806:
807: }
808:
809: static void
810: putarg(where, cp)
1.11 deraadt 811: char *cp;
812: int where;
1.1 deraadt 813: {
814: if (where >= ARGLISTLEN) {
1.14 deraadt 815: fprintf(stderr, "rpcgen: arglist coding error\n");
1.1 deraadt 816: crash();
1.11 deraadt 817: /* NOTREACHED */
1.1 deraadt 818: }
819: arglist[where] = cp;
820: }
821:
822: /*
823: * if input file is stdin and an output file is specified then complain
824: * if the file already exists. Otherwise the file may get overwritten
1.11 deraadt 825: * If input file does not exist, exit with an error
1.1 deraadt 826: */
827: static void
1.11 deraadt 828: checkfiles(infile, outfile)
829: char *infile;
830: char *outfile;
1.1 deraadt 831: {
1.11 deraadt 832: struct stat buf;
833:
834: if (infile) /* infile ! = NULL */
835: if (stat(infile, &buf) < 0) {
836: perror(infile);
837: crash();
838: }
1.1 deraadt 839: #if 0
1.11 deraadt 840: if (outfile) {
841: if (stat(outfile, &buf) < 0)
842: return; /* file does not exist */
843: else {
1.14 deraadt 844: fprintf(stderr,
1.11 deraadt 845: "file '%s' already exists and may be overwritten\n",
846: outfile);
847: crash();
848: }
849: }
1.1 deraadt 850: #endif
851: }
852:
853: /*
1.11 deraadt 854: * Parse command line arguments
1.1 deraadt 855: */
856: static int
857: parseargs(argc, argv, cmd)
858: int argc;
859: char *argv[];
860: struct commandline *cmd;
861: {
1.11 deraadt 862: int i, j, nflags;
863: char c, flag[(1 << 8 * sizeof(char))];
1.1 deraadt 864:
865: cmdname = argv[0];
866: cmd->infile = cmd->outfile = NULL;
1.11 deraadt 867: if (argc < 2)
1.1 deraadt 868: return (0);
1.11 deraadt 869:
1.1 deraadt 870: allfiles = 0;
871: flag['c'] = 0;
872: flag['h'] = 0;
873: flag['l'] = 0;
874: flag['m'] = 0;
875: flag['o'] = 0;
876: flag['s'] = 0;
877: flag['n'] = 0;
878: flag['t'] = 0;
879: flag['S'] = 0;
880: flag['C'] = 0;
881: for (i = 1; i < argc; i++) {
882: if (argv[i][0] != '-') {
883: if (cmd->infile) {
1.14 deraadt 884: fprintf(stderr,
1.11 deraadt 885: "Cannot specify more than one input file!\n");
1.1 deraadt 886: return (0);
887: }
888: cmd->infile = argv[i];
889: } else {
890: for (j = 1; argv[i][j] != 0; j++) {
891: c = argv[i][j];
892: switch (c) {
893: case 'A':
894: callerflag = 1;
895: break;
896: case 'a':
897: allfiles = 1;
898: break;
899: case 'c':
900: case 'h':
901: case 'l':
902: case 'm':
903: case 't':
1.15 deraadt 904: if (flag[(unsigned char)c])
1.1 deraadt 905: return (0);
1.15 deraadt 906: flag[(unsigned char)c] = 1;
1.1 deraadt 907: break;
1.11 deraadt 908: case 'S':
909: /*
910: * sample flag: Ss or Sc. Ss means
911: * set flag['S']; Sc means set
912: * flag['C'];
913: */
914: c = argv[i][++j]; /* get next char */
915: if (c == 's')
916: c = 'S';
917: else if (c == 'c')
918: c = 'C';
1.1 deraadt 919: else
1.11 deraadt 920: return (0);
1.1 deraadt 921:
1.15 deraadt 922: if (flag[(unsigned char)c])
1.1 deraadt 923: return (0);
1.15 deraadt 924: flag[(unsigned char)c] = 1;
1.1 deraadt 925: break;
1.11 deraadt 926: case 'C': /* ANSI C syntax */
1.1 deraadt 927: Cflag = 1;
928: break;
929:
1.11 deraadt 930: case 'b':
931: /*
932: * turn TIRPC flag off for
933: * generating backward compatible
934: */
1.1 deraadt 935: tirpcflag = 0;
936: break;
937:
938: case 'I':
939: inetdflag = 1;
940: break;
941: case 'N':
942: newstyle = 1;
943: break;
944: case 'L':
945: logflag = 1;
946: break;
947: case 'K':
1.11 deraadt 948: if (++i == argc)
1.1 deraadt 949: return (0);
950: svcclosetime = argv[i];
951: goto nextarg;
952: case 'T':
953: tblflag = 1;
954: break;
1.11 deraadt 955: case 'i':
956: if (++i == argc)
1.1 deraadt 957: return (0);
1.3 deraadt 958: doinline = atoi(argv[i]);
1.1 deraadt 959: goto nextarg;
960: case 'n':
961: case 'o':
962: case 's':
1.11 deraadt 963: if (argv[i][j - 1] != '-' ||
964: argv[i][j + 1] != 0)
1.1 deraadt 965: return (0);
1.15 deraadt 966: flag[(unsigned char)c] = 1;
1.11 deraadt 967: if (++i == argc)
1.1 deraadt 968: return (0);
969: if (c == 's') {
970: if (!streq(argv[i], "udp") &&
1.11 deraadt 971: !streq(argv[i], "tcp"))
1.1 deraadt 972: return (0);
973: } else if (c == 'o') {
1.11 deraadt 974: if (cmd->outfile)
1.1 deraadt 975: return (0);
976: cmd->outfile = argv[i];
977: }
978: goto nextarg;
979: case 'D':
1.11 deraadt 980: if (argv[i][j - 1] != '-')
1.1 deraadt 981: return (0);
982: (void) addarg(argv[i]);
983: goto nextarg;
984: case 'Y':
1.11 deraadt 985: if (++i == argc)
1.1 deraadt 986: return (0);
1.4 deraadt 987: if (snprintf(pathbuf, sizeof pathbuf,
988: "%s/cpp", argv[i]) >= sizeof pathbuf)
989: usage();
1.1 deraadt 990: CPP = pathbuf;
991: cppDefined = 1;
992: goto nextarg;
993: default:
994: return (0);
995: }
996: }
997: nextarg:
998: ;
999: }
1000: }
1001:
1002: cmd->cflag = flag['c'];
1003: cmd->hflag = flag['h'];
1004: cmd->lflag = flag['l'];
1005: cmd->mflag = flag['m'];
1006: cmd->nflag = flag['n'];
1007: cmd->sflag = flag['s'];
1008: cmd->tflag = flag['t'];
1009: cmd->Ssflag = flag['S'];
1010: cmd->Scflag = flag['C'];
1011:
1.11 deraadt 1012: if (tirpcflag) {
1013: pmflag = inetdflag ? 0 : 1; /* pmflag or inetdflag is
1014: * always TRUE */
1015: if (inetdflag && cmd->nflag) {
1016: /* netid not allowed with inetdflag */
1.14 deraadt 1017: fprintf(stderr, "Cannot use netid flag with inetd flag!\n");
1.11 deraadt 1018: return (0);
1019: }
1020: } else {
1021: /* 4.1 mode */
1022: pmflag = 0; /* set pmflag only in tirpcmode */
1023: inetdflag = 1; /* inetdflag is TRUE by default */
1024: if (cmd->nflag) {
1025: /* netid needs TIRPC */
1.14 deraadt 1026: fprintf(stderr, "Cannot use netid flag without TIRPC!\n");
1.11 deraadt 1027: return (0);
1028: }
1.1 deraadt 1029: }
1030:
1.11 deraadt 1031: if (newstyle && (tblflag || cmd->tflag)) {
1.14 deraadt 1032: fprintf(stderr, "Cannot use table flags with newstyle!\n");
1.11 deraadt 1033: return (0);
1034: }
1.1 deraadt 1035: /* check no conflicts with file generation flags */
1036: nflags = cmd->cflag + cmd->hflag + cmd->lflag + cmd->mflag +
1.11 deraadt 1037: cmd->sflag + cmd->nflag + cmd->tflag + cmd->Ssflag + cmd->Scflag;
1.1 deraadt 1038:
1039: if (nflags == 0) {
1.11 deraadt 1040: if (cmd->outfile != NULL || cmd->infile == NULL)
1.1 deraadt 1041: return (0);
1042: } else if (nflags > 1) {
1.14 deraadt 1043: fprintf(stderr, "Cannot have more than one file generation flag!\n");
1.1 deraadt 1044: return (0);
1045: }
1046: return (1);
1047: }
1048:
1.15 deraadt 1049: static void
1050: usage(void)
1.1 deraadt 1051: {
1.14 deraadt 1052: fprintf(stderr, "usage: %s [-abACILNT] [-Dname[=value]] [-i lines] "
1.11 deraadt 1053: "[-K seconds] infile\n", cmdname);
1.14 deraadt 1054: fprintf(stderr, " %s [-c | -h | -l | -m | -t | -Sc | -Ss] "
1.11 deraadt 1055: "[-o outfile] [infile]\n", cmdname);
1.14 deraadt 1056: fprintf(stderr, " %s [-s nettype]* [-o outfile] [infile]\n", cmdname);
1.1 deraadt 1057: exit(1);
1058: }