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