Annotation of src/usr.bin/rpcgen/rpc_main.c, Revision 1.11
1.11 ! deraadt 1: /* $OpenBSD: rpc_main.c,v 1.9 2001/11/24 19:17:47 deraadt Exp $ */
! 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";
! 35: static char cvsid[] = "$OpenBSD: rpc_main.c,v 1.9 2001/11/24 19:17:47 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.1 deraadt 44: #include <stdio.h>
45: #include <stdlib.h>
46: #include <string.h>
47: #include <sys/types.h>
48: #ifdef __TURBOC__
49: #define MAXPATHLEN 80
50: #include <process.h>
51: #include <dir.h>
52: #else
53: #include <sys/param.h>
54: #include <sys/file.h>
55: #endif
56: #include <sys/stat.h>
57: #include "rpc_parse.h"
58: #include "rpc_util.h"
59: #include "rpc_scan.h"
60:
61: #define EXTEND 1 /* alias for TRUE */
1.11 ! deraadt 62: #define DONT_EXTEND 0 /* alias for FALSE */
1.1 deraadt 63:
64: #define SVR4_CPP "/usr/ccs/lib/cpp"
65: #define SUNOS_CPP "/lib/cpp"
1.11 ! deraadt 66: static int cppDefined = 0; /* explicit path for C preprocessor */
1.1 deraadt 67:
68: struct commandline {
1.11 ! deraadt 69: int cflag; /* xdr C routines */
! 70: int hflag; /* header file */
! 71: int lflag; /* client side stubs */
! 72: int mflag; /* server side stubs */
! 73: int nflag; /* netid flag */
! 74: int sflag; /* server stubs for the given transport */
! 75: int tflag; /* dispatch Table file */
! 76: int Ssflag; /* produce server sample code */
! 77: int Scflag; /* produce client sample code */
! 78: char *infile; /* input module name */
! 79: char *outfile;/* output module name */
1.1 deraadt 80: };
81:
1.11 ! deraadt 82: static char *cmdname;
1.1 deraadt 83:
1.11 ! deraadt 84: static char *svcclosetime = "120";
! 85: static char *CPP = "/usr/bin/cpp";
! 86: static char CPPFLAGS[] = "-C";
! 87: static char pathbuf[MAXPATHLEN];
! 88: static char *allv[] = {
1.1 deraadt 89: "rpcgen", "-s", "udp", "-s", "tcp",
90: };
1.11 ! deraadt 91: static int allc = sizeof(allv) / sizeof(allv[0]);
! 92: static char *allnv[] = {
1.1 deraadt 93: "rpcgen", "-s", "netpath",
94: };
1.11 ! deraadt 95: static int allnc = sizeof(allnv) / sizeof(allnv[0]);
1.1 deraadt 96:
97: #define ARGLISTLEN 20
98: #define FIXEDARGS 2
99:
1.11 ! deraadt 100: static char *arglist[ARGLISTLEN];
! 101: static int argcount = FIXEDARGS;
1.1 deraadt 102:
103:
1.11 ! deraadt 104: int nonfatalerrors; /* errors */
! 105: int inetdflag /* = 1 */ ; /* Support for inetd *//* is now the
! 106: * default */
! 107: int pmflag; /* Support for port monitors */
! 108: int logflag; /* Use syslog instead of fprintf for errors */
! 109: int tblflag; /* Support for dispatch table file */
! 110: int callerflag; /* Generate svc_caller() function */
1.1 deraadt 111:
112: #define INLINE 3
1.11 ! deraadt 113: /* length at which to start doing an inline */
1.1 deraadt 114:
1.11 ! deraadt 115: int doinline = INLINE; /* length at which to start doing an
! 116: * inline. 3 = default if 0, no
! 117: * xdr_inline code */
! 118:
! 119: int indefinitewait; /* If started by port monitors, hang till it
! 120: * wants */
! 121: int exitnow; /* If started by port monitors, exit after
! 122: * the call */
! 123: int timerflag; /* TRUE if !indefinite && !exitnow */
! 124: int newstyle; /* newstyle of passing arguments (by value) */
! 125: int Cflag = 0; /* ANSI C syntax */
! 126: static int allfiles; /* generate all files */
! 127: int tirpcflag = 0; /* generating code for tirpc, by default */
1.1 deraadt 128:
129: #ifdef __MSDOS__
1.11 ! deraadt 130: static char *dos_cppfile = NULL;
1.1 deraadt 131: #endif
132:
1.7 deraadt 133: static c_output __P((char *, char *, int, char *));
134: static h_output __P((char *, char *, int, char *));
135: static s_output __P((int, char **, char *, char *, int, char *, int, int));
136: static l_output __P((char *, char *, int, char *));
137: static t_output __P((char *, char *, int, char *));
138: static svc_output __P((char *, char *, int, char *));
139: static clnt_output __P((char *, char *, int, char *));
140: static do_registers __P((int, char **));
1.1 deraadt 141: static void addarg __P((char *));
142: static void putarg __P((int, char *));
1.7 deraadt 143: static void clear_args __P((void));
1.1 deraadt 144: static void checkfiles __P((char *, char *));
1.7 deraadt 145: static int parseargs __P((int, char **, struct commandline *));
1.11 ! deraadt 146: static usage __P((void));
1.7 deraadt 147:
1.1 deraadt 148:
1.11 ! deraadt 149: int
1.1 deraadt 150: main(argc, argv)
151: int argc;
152: char *argv[];
153: {
154: struct commandline cmd;
155:
1.11 ! deraadt 156: (void) memset((char *) &cmd, 0, sizeof(struct commandline));
1.1 deraadt 157: clear_args();
158: if (!parseargs(argc, argv, &cmd))
159: usage();
160:
1.11 ! deraadt 161: if (cmd.cflag || cmd.hflag || cmd.lflag || cmd.tflag || cmd.sflag ||
! 162: cmd.mflag || cmd.nflag || cmd.Ssflag || cmd.Scflag) {
! 163: checkfiles(cmd.infile, cmd.outfile);
! 164: } else
! 165: checkfiles(cmd.infile, NULL);
1.1 deraadt 166:
167: if (cmd.cflag) {
168: c_output(cmd.infile, "-DRPC_XDR", DONT_EXTEND, cmd.outfile);
169: } else if (cmd.hflag) {
170: h_output(cmd.infile, "-DRPC_HDR", DONT_EXTEND, cmd.outfile);
171: } else if (cmd.lflag) {
172: l_output(cmd.infile, "-DRPC_CLNT", DONT_EXTEND, cmd.outfile);
173: } else if (cmd.sflag || cmd.mflag || (cmd.nflag)) {
1.11 ! deraadt 174: s_output(argc, argv, cmd.infile, "-DRPC_SVC", DONT_EXTEND,
1.1 deraadt 175: cmd.outfile, cmd.mflag, cmd.nflag);
176: } else if (cmd.tflag) {
177: t_output(cmd.infile, "-DRPC_TBL", DONT_EXTEND, cmd.outfile);
1.11 ! deraadt 178: } else if (cmd.Ssflag) {
! 179: svc_output(cmd.infile, "-DRPC_SERVER", DONT_EXTEND, cmd.outfile);
1.1 deraadt 180: } else if (cmd.Scflag) {
1.11 ! deraadt 181: clnt_output(cmd.infile, "-DRPC_CLIENT", DONT_EXTEND, cmd.outfile);
1.1 deraadt 182: } else {
183: /* the rescans are required, since cpp may effect input */
184: c_output(cmd.infile, "-DRPC_XDR", EXTEND, "_xdr.c");
185: reinitialize();
186: h_output(cmd.infile, "-DRPC_HDR", EXTEND, ".h");
187: reinitialize();
188: l_output(cmd.infile, "-DRPC_CLNT", EXTEND, "_clnt.c");
189: reinitialize();
1.11 ! deraadt 190: if (inetdflag || !tirpcflag)
! 191: s_output(allc, allv, cmd.infile, "-DRPC_SVC", EXTEND,
! 192: "_svc.c", cmd.mflag, cmd.nflag);
1.1 deraadt 193: else
1.11 ! deraadt 194: s_output(allnc, allnv, cmd.infile, "-DRPC_SVC",
! 195: EXTEND, "_svc.c", cmd.mflag, cmd.nflag);
1.1 deraadt 196: if (tblflag) {
197: reinitialize();
198: t_output(cmd.infile, "-DRPC_TBL", EXTEND, "_tbl.i");
199: }
200: if (allfiles) {
1.11 ! deraadt 201: reinitialize();
! 202: svc_output(cmd.infile, "-DRPC_SERVER", EXTEND, "_server.c");
1.1 deraadt 203: }
204: if (allfiles) {
1.11 ! deraadt 205: reinitialize();
! 206: clnt_output(cmd.infile, "-DRPC_CLIENT", EXTEND, "_client.c");
! 207: }
1.1 deraadt 208: }
209: #ifdef __MSDOS__
210: if (dos_cppfile != NULL) {
211: (void) fclose(fin);
212: (void) unlink(dos_cppfile);
213: }
214: #endif
215: exit(nonfatalerrors);
216: /* NOTREACHED */
217: }
218:
219: /*
1.11 ! deraadt 220: * add extension to filename
1.1 deraadt 221: */
222: static char *
223: extendfile(path, ext)
224: char *path;
225: char *ext;
226: {
227: char *file;
228: char *res;
229: char *p;
230:
231: if ((file = strrchr(path, '/')) == NULL)
232: file = path;
233: else
234: file++;
235:
236: res = alloc(strlen(file) + strlen(ext) + 1);
1.11 ! deraadt 237: if (res == NULL)
1.1 deraadt 238: abort();
239: p = strrchr(file, '.');
1.11 ! deraadt 240: if (p == NULL)
1.1 deraadt 241: p = file + strlen(file);
242: (void) strcpy(res, file);
243: (void) strcpy(res + (p - file), ext);
244: return (res);
245: }
246:
247: /*
1.11 ! deraadt 248: * Open output file with given extension
1.1 deraadt 249: */
1.11 ! deraadt 250: static void
1.1 deraadt 251: open_output(infile, outfile)
252: char *infile;
253: char *outfile;
254: {
255:
256: if (outfile == NULL) {
257: fout = stdout;
258: return;
259: }
260: if (infile != NULL && streq(outfile, infile)) {
261: f_print(stderr, "%s: output would overwrite %s\n", cmdname,
1.11 ! deraadt 262: infile);
1.1 deraadt 263: crash();
264: }
265: fout = fopen(outfile, "w");
266: if (fout == NULL) {
267: f_print(stderr, "%s: unable to open ", cmdname);
268: perror(outfile);
269: crash();
270: }
271: record_open(outfile);
272:
273: }
274:
1.7 deraadt 275: static
1.1 deraadt 276: add_warning()
277: {
278: f_print(fout, "/*\n");
279: f_print(fout, " * Please do not edit this file.\n");
280: f_print(fout, " * It was generated using rpcgen.\n");
281: f_print(fout, " */\n\n");
282: }
283:
284: /* clear list of arguments */
1.11 ! deraadt 285: static void
! 286: clear_args()
1.1 deraadt 287: {
1.11 ! deraadt 288: int i;
! 289: for (i = FIXEDARGS; i < ARGLISTLEN; i++)
! 290: arglist[i] = NULL;
! 291: argcount = FIXEDARGS;
1.1 deraadt 292: }
293:
294: /* make sure that a CPP exists */
1.11 ! deraadt 295: static void
! 296: find_cpp()
1.1 deraadt 297: {
1.11 ! deraadt 298: struct stat buf;
1.1 deraadt 299:
1.11 ! deraadt 300: /* SVR4 or explicit cpp does not exist */
! 301: if (stat(CPP, &buf) < 0) {
! 302: if (cppDefined) {
! 303: fprintf(stderr, "cannot find C preprocessor: %s \n", CPP);
! 304: crash();
! 305: } else {
! 306: /* try the other one */
! 307: CPP = SUNOS_CPP;
! 308: if (stat(CPP, &buf) < 0) { /* can't find any cpp */
! 309: fprintf(stderr,
! 310: "cannot find any C preprocessor: %s\n", CPP);
! 311: crash();
! 312: }
! 313: }
! 314: }
1.1 deraadt 315: }
316:
317: /*
1.11 ! deraadt 318: * Open input file with given define for C-preprocessor
1.1 deraadt 319: */
1.7 deraadt 320: static
1.1 deraadt 321: open_input(infile, define)
1.11 ! deraadt 322: char *infile;
! 323: char *define;
1.1 deraadt 324: {
1.11 ! deraadt 325: int pd[2];
1.1 deraadt 326:
327: infilename = (infile == NULL) ? "<stdin>" : infile;
328: #ifdef __MSDOS__
329: #define DOSCPP "\\prog\\bc31\\bin\\cpp.exe"
1.11 ! deraadt 330: {
! 331: int retval;
! 332: char drive[MAXDRIVE], dir[MAXDIR], name[MAXFILE],
! 333: ext[MAXEXT];
! 334: char cppfile[MAXPATH];
! 335: char *cpp;
! 336:
! 337: if ((cpp = searchpath("cpp.exe")) == NULL &&
! 338: (cpp = getenv("RPCGENCPP")) == NULL)
! 339: cpp = DOSCPP;
! 340:
! 341: putarg(0, cpp);
! 342: putarg(1, "-P-");
! 343: putarg(2, CPPFLAGS);
! 344: addarg(define);
! 345: addarg(infile);
! 346: addarg(NULL);
1.1 deraadt 347:
1.11 ! deraadt 348: retval = spawnvp(P_WAIT, arglist[0], arglist);
! 349: if (retval != 0) {
! 350: fprintf(stderr, "%s: C PreProcessor failed\n", cmdname);
! 351: crash();
! 352: }
! 353: fnsplit(infile, drive, dir, name, ext);
! 354: fnmerge(cppfile, drive, dir, name, ".i");
1.1 deraadt 355:
1.11 ! deraadt 356: fin = fopen(cppfile, "r");
! 357: if (fin == NULL) {
! 358: f_print(stderr, "%s: ", cmdname);
! 359: perror(cppfile);
! 360: crash();
! 361: }
! 362: dos_cppfile = strdup(cppfile);
! 363: if (dos_cppfile == NULL) {
! 364: fprintf(stderr, "%s: out of memory\n", cmdname);
! 365: crash();
! 366: }
1.1 deraadt 367: }
368: #else
369: (void) pipe(pd);
370: switch (fork()) {
371: case 0:
372: find_cpp();
373: putarg(0, CPP);
374: putarg(1, CPPFLAGS);
375: addarg(define);
376: addarg(infile);
1.11 ! deraadt 377: addarg((char *) NULL);
1.1 deraadt 378: (void) close(1);
379: (void) dup2(pd[1], 1);
380: (void) close(pd[0]);
381: execv(arglist[0], arglist);
382: perror("execv");
383: exit(1);
384: case -1:
385: perror("fork");
386: exit(1);
387: }
388: (void) close(pd[1]);
389: fin = fdopen(pd[0], "r");
390: #endif
391: if (fin == NULL) {
392: f_print(stderr, "%s: ", cmdname);
393: perror(infilename);
394: crash();
395: }
396: }
397:
398: /* valid tirpc nettypes */
1.11 ! deraadt 399: static char *valid_ti_nettypes[] = {
! 400: "netpath",
! 401: "visible",
! 402: "circuit_v",
! 403: "datagram_v",
! 404: "circuit_n",
! 405: "datagram_n",
! 406: "udp",
! 407: "tcp",
! 408: "raw",
! 409: NULL
! 410: };
1.1 deraadt 411:
412: /* valid inetd nettypes */
1.11 ! deraadt 413: static char *valid_i_nettypes[] = {
! 414: "udp",
! 415: "tcp",
! 416: NULL
1.1 deraadt 417: };
418:
1.11 ! deraadt 419: static int
! 420: check_nettype(name, list_to_check)
! 421: char *name;
! 422: char *list_to_check[];
! 423: {
! 424: int i;
! 425: for (i = 0; list_to_check[i] != NULL; i++) {
! 426: if (strcmp(name, list_to_check[i]) == 0)
! 427: return 1;
! 428: }
! 429: f_print(stderr, "illegal nettype :\'%s\'\n", name);
! 430: return 0;
1.1 deraadt 431: }
432:
433: /*
434: * Compile into an XDR routine output file
435: */
436:
1.7 deraadt 437: static
1.1 deraadt 438: c_output(infile, define, extend, outfile)
1.11 ! deraadt 439: char *infile;
! 440: char *define;
! 441: int extend;
! 442: char *outfile;
! 443: {
! 444: definition *def;
! 445: char *include;
! 446: char *outfilename;
! 447: long tell;
1.1 deraadt 448:
449: c_initialize();
1.11 ! deraadt 450: open_input(infile, define);
1.1 deraadt 451: outfilename = extend ? extendfile(infile, outfile) : outfile;
452: open_output(infile, outfilename);
453: add_warning();
454: if (infile && (include = extendfile(infile, ".h"))) {
455: f_print(fout, "#include \"%s\"\n", include);
456: free(include);
457: /* .h file already contains rpc/rpc.h */
458: } else
1.11 ! deraadt 459: f_print(fout, "#include <rpc/rpc.h>\n");
1.1 deraadt 460: tell = ftell(fout);
461: while (def = get_definition()) {
462: emit(def);
463: }
464: if (extend && tell == ftell(fout)) {
465: (void) unlink(outfilename);
466: }
467: }
468:
469:
470: c_initialize()
471: {
472:
1.11 ! deraadt 473: /* add all the starting basic types */
1.1 deraadt 474:
1.11 ! deraadt 475: add_type(1, "int");
! 476: add_type(1, "long");
! 477: add_type(1, "short");
! 478: add_type(1, "bool");
1.1 deraadt 479:
1.11 ! deraadt 480: add_type(1, "u_int");
! 481: add_type(1, "u_long");
! 482: add_type(1, "u_short");
1.1 deraadt 483:
484: }
485:
1.11 ! deraadt 486: char rpcgen_table_dcl[] = "struct rpcgen_table {\n\
1.1 deraadt 487: char *(*proc)();\n\
488: xdrproc_t xdr_arg;\n\
489: unsigned len_arg;\n\
490: xdrproc_t xdr_res;\n\
491: unsigned len_res;\n\
492: };\n";
493:
494:
1.11 ! deraadt 495: char *
! 496: generate_guard(pathname)
! 497: char *pathname;
1.1 deraadt 498: {
1.11 ! deraadt 499: char *filename, *guard, *tmp;
1.1 deraadt 500:
1.11 ! deraadt 501: filename = strrchr(pathname, '/'); /* find last component */
! 502: filename = ((filename == 0) ? pathname : filename + 1);
1.1 deraadt 503: guard = strdup(filename);
504: /* convert to upper case */
505: tmp = guard;
506: while (*tmp) {
507: if (islower(*tmp))
508: *tmp = toupper(*tmp);
509: tmp++;
510: }
1.11 ! deraadt 511:
1.1 deraadt 512: guard = extendfile(guard, "_H_RPCGEN");
1.11 ! deraadt 513: return (guard);
1.1 deraadt 514: }
515:
516: /*
517: * Compile into an XDR header file
518: */
519:
1.7 deraadt 520: static
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.11 ! deraadt 539: f_print(fout, "#ifndef _%s\n#define _%s\n\n", guard,
1.1 deraadt 540: guard);
541:
1.2 niklas 542: f_print(fout, "#define RPCGEN_VERSION\t%s\n\n", RPCGEN_VERSION);
1.1 deraadt 543: f_print(fout, "#include <rpc/rpc.h>\n\n");
544:
545: tell = ftell(fout);
546: /* print data definitions */
547: while (def = get_definition()) {
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) {
561: f_print(fout, rpcgen_table_dcl);
562: }
563: f_print(fout, "\n#endif /* !_%s */\n", guard);
564: }
565:
566: /*
567: * Compile into an RPC service
568: */
1.7 deraadt 569: static
1.1 deraadt 570: s_output(argc, argv, infile, define, extend, outfile, nomain, netflag)
1.11 ! deraadt 571: int argc;
! 572: char *argv[];
! 573: char *infile;
! 574: char *define;
! 575: int extend;
! 576: char *outfile;
! 577: int nomain;
! 578: int netflag;
! 579: {
! 580: char *include;
! 581: definition *def;
! 582: int foundprogram = 0;
! 583: char *outfilename;
1.1 deraadt 584:
585: open_input(infile, define);
586: outfilename = extend ? extendfile(infile, outfile) : outfile;
587: open_output(infile, outfilename);
588: add_warning();
589: if (infile && (include = extendfile(infile, ".h"))) {
590: f_print(fout, "#include \"%s\"\n", include);
591: free(include);
592: } else
1.11 ! deraadt 593: f_print(fout, "#include <rpc/rpc.h>\n");
1.1 deraadt 594:
595: f_print(fout, "#include <stdio.h>\n");
1.11 ! deraadt 596: f_print(fout, "#include <stdlib.h>/* getenv, exit */\n");
1.1 deraadt 597: if (Cflag) {
1.11 ! deraadt 598: f_print(fout,
1.1 deraadt 599: "#include <rpc/pmap_clnt.h> /* for pmap_unset */\n");
1.11 ! deraadt 600: f_print(fout, "#include <string.h> /* strcmp */ \n");
1.1 deraadt 601: }
1.11 ! deraadt 602: f_print(fout, "#include <netdb.h>\n"); /* evas */
1.1 deraadt 603: if (strcmp(svcclosetime, "-1") == 0)
604: indefinitewait = 1;
605: else if (strcmp(svcclosetime, "0") == 0)
606: exitnow = 1;
607: else if (inetdflag || pmflag) {
608: f_print(fout, "#include <signal.h>\n");
1.11 ! deraadt 609: timerflag = 1;
1.1 deraadt 610: }
1.11 ! deraadt 611: if (!tirpcflag && inetdflag)
! 612: f_print(fout, "#include <sys/ttycom.h>/* TIOCNOTTY */\n");
! 613: if (Cflag && (inetdflag || pmflag)) {
! 614: f_print(fout, "#ifdef __cplusplus\n");
! 615: f_print(fout, "#include <sysent.h> /* getdtablesize, open */\n");
! 616: f_print(fout, "#endif /* __cplusplus */\n");
1.1 deraadt 617:
1.11 ! deraadt 618: if (tirpcflag)
! 619: f_print(fout, "#include <unistd.h> /* setsid */\n");
1.1 deraadt 620: }
1.11 ! deraadt 621: if (tirpcflag)
! 622: f_print(fout, "#include <sys/types.h>\n");
1.1 deraadt 623:
624: f_print(fout, "#include <memory.h>\n");
625: if (tirpcflag)
626: f_print(fout, "#include <stropts.h>\n");
627:
1.11 ! deraadt 628: if (inetdflag || !tirpcflag) {
1.1 deraadt 629: f_print(fout, "#include <sys/socket.h>\n");
630: f_print(fout, "#include <netinet/in.h>\n");
1.11 ! deraadt 631: }
! 632: if ((netflag || pmflag) && tirpcflag) {
1.1 deraadt 633: f_print(fout, "#include <netconfig.h>\n");
634: }
1.11 ! deraadt 635: if ( /* timerflag && */ tirpcflag)
1.1 deraadt 636: f_print(fout, "#include <sys/resource.h> /* rlimit */\n");
637: if (logflag || inetdflag || pmflag) {
638: f_print(fout, "#include <syslog.h>\n");
1.8 deraadt 639: f_print(fout, "#include <errno.h>\n");
1.1 deraadt 640: }
641: /* for ANSI-C */
642: f_print(fout, "\n#ifdef __STDC__\n#define SIG_PF void(*)(int)\n#endif\n");
643:
644: f_print(fout, "\n#ifdef DEBUG\n#define RPC_SVC_FG\n#endif\n");
645: if (timerflag)
646: f_print(fout, "\n#define _RPCSVC_CLOSEDOWN %s\n", svcclosetime);
647: while (def = get_definition()) {
648: foundprogram |= (def->def_kind == DEF_PROGRAM);
649: }
650: if (extend && !foundprogram) {
651: (void) unlink(outfilename);
652: return;
653: }
1.11 ! deraadt 654: if (callerflag) /* EVAS */
! 655: f_print(fout, "\nstatic SVCXPRT *caller;\n"); /* EVAS */
1.1 deraadt 656: write_most(infile, netflag, nomain);
657: if (!nomain) {
1.11 ! deraadt 658: if (!do_registers(argc, argv)) {
! 659: if (outfilename)
! 660: (void) unlink(outfilename);
! 661: usage();
1.1 deraadt 662: }
663: write_rest();
664: }
665: }
666:
667: /*
668: * generate client side stubs
669: */
1.7 deraadt 670: static
1.1 deraadt 671: l_output(infile, define, extend, outfile)
1.11 ! deraadt 672: char *infile;
! 673: char *define;
! 674: int extend;
! 675: char *outfile;
! 676: {
! 677: char *include;
! 678: definition *def;
! 679: int foundprogram = 0;
! 680: char *outfilename;
1.1 deraadt 681:
682: open_input(infile, define);
683: outfilename = extend ? extendfile(infile, outfile) : outfile;
684: open_output(infile, outfilename);
685: add_warning();
686: if (Cflag)
1.11 ! deraadt 687: f_print(fout, "#include <memory.h> /* for memset */\n");
1.1 deraadt 688: if (infile && (include = extendfile(infile, ".h"))) {
689: f_print(fout, "#include \"%s\"\n", include);
690: free(include);
691: } else
1.11 ! deraadt 692: f_print(fout, "#include <rpc/rpc.h>\n");
! 693: while (def = get_definition())
1.1 deraadt 694: foundprogram |= (def->def_kind == DEF_PROGRAM);
1.11 ! deraadt 695:
1.1 deraadt 696: if (extend && !foundprogram) {
697: (void) unlink(outfilename);
698: return;
699: }
700: write_stubs();
701: }
702:
703: /*
704: * generate the dispatch table
705: */
1.7 deraadt 706: static
1.1 deraadt 707: t_output(infile, define, extend, outfile)
1.11 ! deraadt 708: char *infile;
! 709: char *define;
! 710: int extend;
! 711: char *outfile;
! 712: {
! 713: definition *def;
! 714: int foundprogram = 0;
! 715: char *outfilename;
1.1 deraadt 716:
717: open_input(infile, define);
718: outfilename = extend ? extendfile(infile, outfile) : outfile;
719: open_output(infile, outfilename);
720: add_warning();
1.11 ! deraadt 721: while (def = get_definition())
1.1 deraadt 722: foundprogram |= (def->def_kind == DEF_PROGRAM);
1.11 ! deraadt 723:
1.1 deraadt 724: if (extend && !foundprogram) {
725: (void) unlink(outfilename);
726: return;
727: }
728: write_tables();
729: }
730:
731: /* sample routine for the server template */
1.11 ! deraadt 732: static
1.1 deraadt 733: svc_output(infile, define, extend, outfile)
1.11 ! deraadt 734: char *infile;
! 735: char *define;
! 736: int extend;
! 737: char *outfile;
! 738: {
! 739: definition *def;
! 740: char *include;
! 741: char *outfilename;
! 742: long tell;
! 743:
! 744: open_input(infile, define);
! 745: outfilename = extend ? extendfile(infile, outfile) : outfile;
! 746: checkfiles(infile, outfilename); /* check if outfile already
! 747: * exists. if so, print an
! 748: * error message and exit */
! 749: open_output(infile, outfilename);
! 750: add_sample_msg();
! 751:
! 752: if (infile && (include = extendfile(infile, ".h"))) {
! 753: f_print(fout, "#include \"%s\"\n", include);
! 754: free(include);
! 755: } else
! 756: f_print(fout, "#include <rpc/rpc.h>\n");
! 757:
! 758: tell = ftell(fout);
! 759: while (def = get_definition())
! 760: write_sample_svc(def);
! 761:
! 762: if (extend && tell == ftell(fout))
! 763: (void) unlink(outfilename);
1.1 deraadt 764: }
765:
766:
767: /* sample main routine for client */
1.11 ! deraadt 768: static
1.1 deraadt 769: clnt_output(infile, define, extend, outfile)
1.11 ! deraadt 770: char *infile;
! 771: char *define;
! 772: int extend;
! 773: char *outfile;
! 774: {
! 775: definition *def;
! 776: char *include, *outfilename;
! 777: long tell;
! 778: int has_program = 0;
! 779:
! 780: open_input(infile, define);
! 781: outfilename = extend ? extendfile(infile, outfile) : outfile;
! 782:
! 783: /*
! 784: * check if outfile already exists. if so,
! 785: * print an error message and exit
! 786: */
! 787: checkfiles(infile, outfilename);
! 788:
! 789: open_output(infile, outfilename);
! 790: add_sample_msg();
! 791: if (infile && (include = extendfile(infile, ".h"))) {
! 792: f_print(fout, "#include \"%s\"\n", include);
! 793: free(include);
! 794: } else
! 795: f_print(fout, "#include <rpc/rpc.h>\n");
! 796: tell = ftell(fout);
! 797: while (def = get_definition())
! 798: has_program += write_sample_clnt(def);
! 799:
! 800: if (has_program)
! 801: write_sample_clnt_main();
! 802:
! 803: if (extend && tell == ftell(fout))
! 804: (void) unlink(outfilename);
1.1 deraadt 805: }
806:
807: /*
1.11 ! deraadt 808: * Perform registrations for service output
1.1 deraadt 809: * Return 0 if failed; 1 otherwise.
810: */
1.7 deraadt 811: static
1.11 ! deraadt 812: int
! 813: do_registers(argc, argv)
! 814: int argc;
! 815: char *argv[];
1.1 deraadt 816: {
1.11 ! deraadt 817: int i;
1.1 deraadt 818:
1.11 ! deraadt 819: if (inetdflag || !tirpcflag) {
1.1 deraadt 820: for (i = 1; i < argc; i++) {
821: if (streq(argv[i], "-s")) {
1.11 ! deraadt 822: if (!check_nettype(argv[i + 1], valid_i_nettypes))
! 823: return 0;
1.1 deraadt 824: write_inetd_register(argv[i + 1]);
825: i++;
826: }
827: }
828: } else {
829: for (i = 1; i < argc; i++)
1.11 ! deraadt 830: if (streq(argv[i], "-s")) {
! 831: if (!check_nettype(argv[i + 1], valid_ti_nettypes))
! 832: return 0;
1.1 deraadt 833: write_nettype_register(argv[i + 1]);
834: i++;
835: } else if (streq(argv[i], "-n")) {
836: write_netid_register(argv[i + 1]);
837: i++;
838: }
839: }
840: return 1;
841: }
842:
843: /*
844: * Add another argument to the arg list
845: */
846: static void
847: addarg(cp)
1.11 ! deraadt 848: char *cp;
1.1 deraadt 849: {
850: if (argcount >= ARGLISTLEN) {
851: f_print(stderr, "rpcgen: too many defines\n");
852: crash();
1.11 ! deraadt 853: /* NOTREACHED */
1.1 deraadt 854: }
855: arglist[argcount++] = cp;
856:
857: }
858:
859: static void
860: putarg(where, cp)
1.11 ! deraadt 861: char *cp;
! 862: int where;
1.1 deraadt 863: {
864: if (where >= ARGLISTLEN) {
865: f_print(stderr, "rpcgen: arglist coding error\n");
866: crash();
1.11 ! deraadt 867: /* NOTREACHED */
1.1 deraadt 868: }
869: arglist[where] = cp;
870: }
871:
872: /*
873: * if input file is stdin and an output file is specified then complain
874: * if the file already exists. Otherwise the file may get overwritten
1.11 ! deraadt 875: * If input file does not exist, exit with an error
1.1 deraadt 876: */
877: static void
1.11 ! deraadt 878: checkfiles(infile, outfile)
! 879: char *infile;
! 880: char *outfile;
1.1 deraadt 881: {
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 {
! 895: f_print(stderr,
! 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.11 ! deraadt 935: f_print(stderr,
! 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.11 ! deraadt 955: if (flag[c])
1.1 deraadt 956: return (0);
957: flag[c] = 1;
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.11 ! deraadt 973: if (flag[c])
1.1 deraadt 974: return (0);
975: flag[c] = 1;
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);
1017: flag[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 */
! 1068: f_print(stderr, "Cannot use netid flag with inetd flag!\n");
! 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 */
! 1077: f_print(stderr, "Cannot use netid flag without TIRPC!\n");
! 1078: return (0);
! 1079: }
1.1 deraadt 1080: }
1081:
1.11 ! deraadt 1082: if (newstyle && (tblflag || cmd->tflag)) {
! 1083: f_print(stderr, "Cannot use table flags with newstyle!\n");
! 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.11 ! deraadt 1094: f_print(stderr, "Cannot have more than one file generation flag!\n");
1.1 deraadt 1095: return (0);
1096: }
1097: return (1);
1098: }
1099:
1.7 deraadt 1100: static
1.1 deraadt 1101: usage()
1102: {
1.11 ! deraadt 1103: f_print(stderr, "usage: %s [-abACILNT] [-Dname[=value]] [-i lines] "
! 1104: "[-K seconds] infile\n", cmdname);
! 1105: f_print(stderr, " %s [-c | -h | -l | -m | -t | -Sc | -Ss] "
! 1106: "[-o outfile] [infile]\n", cmdname);
! 1107: f_print(stderr, " %s [-s nettype]* [-o outfile] [infile]\n", cmdname);
1.1 deraadt 1108: exit(1);
1109: }