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