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