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