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