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