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