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