1 /* @(#)rpc_main.c 1.4 87/11/30 3.9 RPCSRC */
3 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
4 * unrestricted use provided that this legend is included on all tape
5 * media and as a part of the software program in whole or part. Users
6 * may copy or modify Sun RPC without charge, but are not authorized
7 * to license or distribute it to anyone else except as part of a product or
8 * program developed by the user.
10 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
11 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
12 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
14 * Sun RPC is provided with no support and without any obligation on the
15 * part of Sun Microsystems, Inc. to assist in its use, correction,
16 * modification or enhancement.
18 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
19 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
20 * OR ANY PART THEREOF.
22 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
23 * or profits or other special, indirect and consequential damages, even if
24 * Sun has been advised of the possibility of such damages.
26 * Sun Microsystems, Inc.
28 * Mountain View, California 94043
32 * rpc_main.c, Top level of the RPC protocol compiler.
33 * Copyright (C) 1987, Sun Microsystems, Inc.
36 #include <afsconfig.h>
37 #include <afs/param.h>
45 #include "rpc_parse.h"
48 #define EXTEND 1 /* alias for TRUE */
68 #define MAXCPPARGS 256 /* maximum number of arguments to cpp */
71 static char *IncludeDir
[MAXCPPARGS
];
73 char *OutFileFlag
= "";
75 char Sflag
= 0, Cflag
= 0, hflag
= 0, cflag
= 0, kflag
= 0, uflag
= 0;
76 char ansic_flag
= 0; /* If set, build ANSI C style prototypes */
77 char brief_flag
= 0; /* If set, shorten names */
78 char zflag
= 0; /* If set, abort server stub if rpc call returns non-zero */
79 char xflag
= 0; /* if set, add stats code to stubs */
80 char yflag
= 0; /* if set, only emit function name arrays to xdr file */
82 static int pclose_fin
= 0;
85 static char *CPP
= PATH_CPP
;
88 static char *CPP
= "cl /EP /C /nologo";
90 static char *CPP
= "/lib/cpp";
95 * Running "cpp" directly on DEC OSF/1 does not define anything; the "cc"
96 * driver is responsible. To compensate (and allow for other definitions
97 * which should always be passed to "cpp"), place definitions which whould
98 * always be passed to "rxgen" in this string.
100 static char *CPPFLAGS
= "-C"
111 #include "AFS_component_version_number.c"
113 /* static prototypes */
114 static char *extendfile(char *file
, char *ext
);
115 static void open_output(char *infile
, char *outfile
);
116 static void open_input(char *infile
, char *define
);
117 static void c_output(char *infile
, char *define
, int extend
, char *outfile
,
119 static void h_output(char *infile
, char *define
, int extend
, char *outfile
,
121 static int parseargs(int argc
, char *argv
[], struct commandline
*cmd
);
122 static void C_output(char *infile
, char *define
, int extend
, char *outfile
,
124 static void S_output(char *infile
, char *define
, int extend
, char *outfile
,
126 static char *uppercase(char *str
);
129 main(int argc
, char *argv
[])
131 struct commandline cmd
;
134 ep
= getenv("RXGEN_CPPCMD");
139 * The following signal action for AIX is necessary so that in case of a
140 * crash (i.e. core is generated) we can include the user's data section
141 * in the core dump. Unfortunately, by default, only a partial core is
142 * generated which, in many cases, isn't too useful.
144 struct sigaction nsa
;
146 sigemptyset(&nsa
.sa_mask
);
147 nsa
.sa_handler
= SIG_DFL
;
148 nsa
.sa_flags
= SA_FULLDUMP
;
149 sigaction(SIGSEGV
, &nsa
, NULL
);
152 if (!parseargs(argc
, argv
, &cmd
)) {
153 f_print(stderr
, "usage: %s infile\n", cmdname
);
155 " %s [-c | -h | -C | -S | -r | -b | -k | -p | -d | -z | -u] [-Pprefix] [-Idir] [-o outfile] [infile]\n",
157 f_print(stderr
, " %s [-o outfile] [infile]\n",
161 OutFileFlag
= cmd
.outfile
;
163 strcpy(OutFile
, cmd
.outfile
);
166 c_output(cmd
.infile
, "-DRPC_XDR", !EXTEND
, cmd
.outfile
, 0);
167 } else if (cmd
.hflag
) {
168 h_output(cmd
.infile
, "-DRPC_HDR", !EXTEND
, cmd
.outfile
, 0);
169 } else if (cmd
.Cflag
) {
171 C_output(cmd
.infile
, "-DRPC_CLIENT", !EXTEND
, cmd
.outfile
, 1);
172 } else if (cmd
.Sflag
) {
174 S_output(cmd
.infile
, "-DRPC_SERVER", !EXTEND
, cmd
.outfile
, 1);
176 if (OutFileFlag
&& (strrchr(OutFile
, '.') == NULL
))
177 strcat(OutFile
, ".");
179 C_output((OutFileFlag
? OutFile
: cmd
.infile
), "-DRPC_CLIENT",
182 S_output((OutFileFlag
? OutFile
: cmd
.infile
), "-DRPC_SERVER",
187 c_output((OutFileFlag
? OutFile
: cmd
.infile
), "-DRPC_XDR",
188 EXTEND
, ".xdr.c", 0);
190 h_output((OutFileFlag
? OutFile
: cmd
.infile
), "-DRPC_HDR",
193 C_output((OutFileFlag
? OutFile
: cmd
.infile
), "-DRPC_CLIENT",
196 S_output((OutFileFlag
? OutFile
: cmd
.infile
), "-DRPC_SERVER",
201 if (fin
&& pclose_fin
) {
202 /* the cpp command we called returned a non-zero exit status */
211 * add extension to filename
214 extendfile(char *file
, char *ext
)
220 res
= alloc(strlen(file
) + strlen(ext
) + 1);
224 p
= (char *)strrchr(file
, '.');
226 p
= file
+ strlen(file
);
228 sname
= (char *)strrchr(file
, '/');
234 strcpy(res
+ (p
- sname
), ext
);
239 * Open output file with given extension
242 open_output(char *infile
, char *outfile
)
244 if (outfile
== NULL
) {
248 if (infile
!= NULL
&& streq(outfile
, infile
)) {
249 f_print(stderr
, "%s: output would overwrite %s\n", cmdname
, infile
);
252 fout
= fopen(outfile
, "w");
254 f_print(stderr
, "%s: unable to open ", cmdname
);
258 record_open(outfile
);
262 * Open input file with given define for C-preprocessor
265 open_input(char *infile
, char *define
)
271 infilename
= (infile
== NULL
) ? "<stdin>" : infile
;
272 l
= strlen(CPP
) + strlen(CPPFLAGS
) + strlen(define
) + 3;
273 for (i
= 0; i
< nincludes
; i
++)
274 l
+= strlen(IncludeDir
[i
]) + 1;
275 l
+= strlen(infile
) + 1;
276 cpp_cmdline
= malloc(l
);
278 perror("Unable to allocate space for cpp command line");
282 sprintf(cpp_cmdline
, "%s %s %s", CPP
, CPPFLAGS
, define
);
283 l
= strlen(cpp_cmdline
);
284 for (i
= 0; i
< nincludes
; i
++) {
285 cpp_cmdline
[l
++] = ' ';
286 strcpy(cpp_cmdline
+ l
, IncludeDir
[i
]);
287 l
+= strlen(IncludeDir
[i
]);
289 cpp_cmdline
[l
++] = ' ';
290 strcpy(cpp_cmdline
+ l
, infile
);
292 fin
= popen(cpp_cmdline
, "r");
298 if (infile
== NULL
) {
302 fin
= fopen(infile
, "r");
305 f_print(stderr
, "%s: ", cmdname
);
312 * Compile into an XDR routine output file
315 c_output(char *infile
, char *define
, int extend
, char *outfile
, int append
)
322 char *currfile
= (OutFileFlag
? OutFile
: infile
);
325 open_input(infile
, define
);
327 memset(fullname
, 0, sizeof(fullname
));
329 strcpy(fullname
, prefix
);
330 strcat(fullname
, infile
);
332 strcpy(fullname
, infile
);
333 outfilename
= extend
? extendfile(fullname
, outfile
) : outfile
;
334 open_output(infile
, outfilename
);
335 f_print(fout
, "/* Machine generated file -- Do NOT edit */\n\n");
338 f_print(fout
, "#include \"afsconfig.h\"\n");
339 f_print(fout
, "#include \"afs/param.h\"\n");
341 f_print(fout
, "#include <afsconfig.h>\n");
342 f_print(fout
, "#include <afs/param.h>\n");
343 f_print(fout
, "#include <roken.h>\n");
345 f_print(fout
, "#ifdef AFS_NT40_ENV\n");
346 f_print(fout
, "#define AFS_RXGEN_EXPORT __declspec(dllexport)\n");
347 f_print(fout
, "#endif /* AFS_NT40_ENV */\n");
349 if (currfile
&& (include
= extendfile(currfile
, ".h"))) {
351 f_print(fout
, "#include \"%s\"\n\n", include
);
353 f_print(fout
, "#include \"%s\"\n\n", include
);
356 /* In case we can't include the interface's own header file... */
358 f_print(fout
, "#include \"h/types.h\"\n");
359 f_print(fout
, "#include \"h/socket.h\"\n");
360 f_print(fout
, "#include \"h/file.h\"\n");
361 f_print(fout
, "#include \"h/stat.h\"\n");
362 f_print(fout
, "#include \"netinet/in.h\"\n");
363 f_print(fout
, "#include \"h/time.h\"\n");
364 f_print(fout
, "#include \"rx/xdr.h\"\n");
365 f_print(fout
, "#include \"afs/rxgen_consts.h\"\n");
367 f_print(fout
, "#include <rx/xdr.h>\n");
372 while ((def
= get_definition())) {
374 if ((!IsRxgenDefinition(def
)) && def
->def_kind
!= DEF_CUSTOMIZED
)
380 * Print out array containing list of all functions in the interface
385 for (j
= 0; j
<= PackageIndex
; j
++) {
386 f_print(fout
, "AFS_RXGEN_EXPORT\n");
387 f_print(fout
, "const char *%sfunction_names[] = {\n",
390 for (i
= 0; i
< no_of_stat_funcs_header
[j
]; i
++) {
392 f_print(fout
, "\t\"%s\"", function_list
[j
][i
]);
394 f_print(fout
, ",\n\t\"%s\"", function_list
[j
][i
]);
399 f_print(fout
, "\n};\n");
401 er_Proc_CodeGeneration();
404 if (extend
&& tell
== ftell(fout
)) {
405 (void)unlink(outfilename
);
411 * Compile into an XDR header file
414 h_output(char *infile
, char *define
, int extend
, char *outfile
, int append
)
419 char fullname
[1024], *p
;
421 open_input(infile
, define
);
423 memset(fullname
, 0, sizeof(fullname
));
425 strcpy(fullname
, prefix
);
426 strcat(fullname
, infile
);
428 strcpy(fullname
, infile
);
429 outfilename
= extend
? extendfile(fullname
, outfile
) : outfile
;
430 open_output(infile
, outfilename
);
431 strcpy(fullname
, outfilename
);
432 if ((p
= strchr(fullname
, '.')))
434 f_print(fout
, "/* Machine generated file -- Do NOT edit */\n\n");
435 f_print(fout
, "#ifndef _RXGEN_%s_\n", uppercase(fullname
));
436 f_print(fout
, "#define _RXGEN_%s_\n\n", uppercase(fullname
));
437 f_print(fout
, "#ifdef KERNEL\n");
439 "/* The following 'ifndefs' are not a good solution to the vendor's omission of surrounding all system includes with 'ifndef's since it requires that this file is included after the system includes...*/\n");
440 f_print(fout
, "#include <afsconfig.h>\n");
441 f_print(fout
, "#include \"afs/param.h\"\n");
442 f_print(fout
, "#ifdef UKERNEL\n");
443 f_print(fout
, "#include \"afs/sysincludes.h\"\n");
444 f_print(fout
, "#include \"rx/xdr.h\"\n");
445 f_print(fout
, "#include \"rx/rx.h\"\n");
447 f_print(fout
, "#include \"rx/rx_globals.h\"\n");
450 f_print(fout
, "#include \"rx/rx_opaque.h\"\n");
452 f_print(fout
, "#else /* UKERNEL */\n");
453 f_print(fout
, "#include \"h/types.h\"\n");
454 f_print(fout
, "#ifndef SOCK_DGRAM /* XXXXX */\n");
455 f_print(fout
, "#include \"h/socket.h\"\n");
456 f_print(fout
, "#endif\n");
457 f_print(fout
, "#ifndef DTYPE_SOCKET /* XXXXX */\n");
458 f_print(fout
, "#ifndef AFS_LINUX22_ENV\n");
459 f_print(fout
, "#include \"h/file.h\"\n");
460 f_print(fout
, "#endif\n");
461 f_print(fout
, "#endif\n");
462 f_print(fout
, "#ifndef S_IFMT /* XXXXX */\n");
463 f_print(fout
, "#include \"h/stat.h\"\n");
464 f_print(fout
, "#endif\n");
465 f_print(fout
, "#if defined (AFS_OBSD_ENV) && !defined (MLEN)\n");
466 f_print(fout
, "#include \"sys/mbuf.h\"\n");
467 f_print(fout
, "#endif\n");
468 f_print(fout
, "#ifndef IPPROTO_UDP /* XXXXX */\n");
469 f_print(fout
, "#include \"netinet/in.h\"\n");
470 f_print(fout
, "#endif\n");
471 f_print(fout
, "#ifndef DST_USA /* XXXXX */\n");
472 f_print(fout
, "#include \"h/time.h\"\n");
473 f_print(fout
, "#endif\n");
474 f_print(fout
, "#ifndef AFS_LINUX22_ENV\n");
475 f_print(fout
, "#include \"rpc/types.h\"\n");
476 f_print(fout
, "#endif /* AFS_LINUX22_ENV */\n");
477 f_print(fout
, "#ifndef XDR_GETLONG /* XXXXX */\n");
478 f_print(fout
, "#ifdef AFS_LINUX22_ENV\n");
479 f_print(fout
, "#ifndef quad_t\n");
480 f_print(fout
, "#define quad_t __quad_t\n");
481 f_print(fout
, "#define u_quad_t __u_quad_t\n");
482 f_print(fout
, "#endif\n");
483 f_print(fout
, "#endif\n");
484 f_print(fout
, "#include \"rx/xdr.h\"\n");
485 f_print(fout
, "#endif /* XDR_GETLONG */\n");
486 f_print(fout
, "#endif /* UKERNEL */\n");
487 f_print(fout
, "#include \"afs/rxgen_consts.h\"\n");
488 f_print(fout
, "#include \"afs_osi.h\"\n");
489 f_print(fout
, "#include \"rx/rx.h\"\n");
491 f_print(fout
, "#include \"rx/rx_globals.h\"\n");
494 f_print(fout
, "#include \"rx/rx_opaque.h\"\n");
496 f_print(fout
, "#else /* KERNEL */\n");
497 f_print(fout
, "#include <afs/param.h>\n");
498 f_print(fout
, "#include <afs/stds.h>\n");
499 f_print(fout
, "#include <sys/types.h>\n");
500 f_print(fout
, "#include <rx/xdr.h>\n");
501 f_print(fout
, "#include <rx/rx.h>\n");
503 f_print(fout
, "#include <rx/rx_globals.h>\n");
506 f_print(fout
, "#include <rx/rx_opaque.h>\n");
508 f_print(fout
, "#include <afs/rxgen_consts.h>\n");
510 f_print(fout
, "#include <ubik.h>\n");
511 f_print(fout
, "#endif /* KERNEL */\n\n");
512 f_print(fout
, "#ifdef AFS_NT40_ENV\n");
513 f_print(fout
, "#ifndef AFS_RXGEN_EXPORT\n");
514 f_print(fout
, "#define AFS_RXGEN_EXPORT __declspec(dllimport)\n");
515 f_print(fout
, "#endif /* AFS_RXGEN_EXPORT */\n");
516 f_print(fout
, "#else /* AFS_NT40_ENV */\n");
517 f_print(fout
, "#define AFS_RXGEN_EXPORT\n");
518 f_print(fout
, "#endif /* AFS_NT40_ENV */\n\n");
520 while ((def
= get_definition())) {
523 h_Proc_CodeGeneration();
526 f_print(fout
, "#endif /* _RXGEN_%s_ */\n", uppercase(fullname
));
527 if (extend
&& tell
== ftell(fout
)) {
528 (void)unlink(outfilename
);
533 C_output(char *infile
, char *define
, int extend
, char *outfile
, int append
)
539 char *currfile
= (OutFileFlag
? OutFile
: infile
);
542 open_input(infile
, define
);
543 memset(fullname
, 0, sizeof(fullname
));
545 strcpy(fullname
, prefix
);
546 strcat(fullname
, infile
);
548 strcpy(fullname
, infile
);
549 outfilename
= extend
? extendfile(fullname
, outfile
) : outfile
;
550 open_output(infile
, outfilename
);
551 f_print(fout
, "/* Machine generated file -- Do NOT edit */\n\n");
552 if (currfile
&& (include
= extendfile(currfile
, ".h"))) {
554 f_print(fout
, "#include \"%s\"\n\n", include
);
556 f_print(fout
, "#include <afsconfig.h>\n");
557 f_print(fout
, "#include <afs/param.h>\n");
558 f_print(fout
, "#include <roken.h>\n");
559 f_print(fout
, "#include <afs/opr.h>\n");
560 f_print(fout
, "#ifdef AFS_PTHREAD_ENV\n");
561 f_print(fout
, "# include <opr/lock.h>\n");
562 f_print(fout
, "#endif\n");
563 f_print(fout
, "#include \"%s\"\n\n", include
);
568 f_print(fout
, "#include \"h/types.h\"\n");
569 f_print(fout
, "#include \"h/socket.h\"\n");
570 f_print(fout
, "#include \"h/file.h\"\n");
571 f_print(fout
, "#include \"h/stat.h\"\n");
572 f_print(fout
, "#include \"netinet/in.h\"\n");
573 f_print(fout
, "#include \"h/time.h\"\n");
574 f_print(fout
, "#include \"rpc/types.h\"\n");
575 f_print(fout
, "#include \"rx/xdr.h\"\n");
576 f_print(fout
, "#include \"afs/rxgen_consts.h\"\n");
577 f_print(fout
, "#include \"afs/afs_osi.h\"\n");
578 f_print(fout
, "#include \"rx/rx.h\"\n");
580 f_print(fout
, "#include \"rx/rx_globals.h\"\n");
583 f_print(fout
, "#include \"rx/rx_opaque.h\"\n");
586 f_print(fout
, "#include <sys/types.h>\n");
587 f_print(fout
, "#include <rx/xdr.h>\n");
588 f_print(fout
, "#include <rx/rx.h>\n");
590 f_print(fout
, "#include <rx/rx_globals.h>\n");
593 f_print(fout
, "#include <rx/rx_opaque.h\"\n");
595 f_print(fout
, "#include <afs/rxgen_consts.h>\n");
600 while (get_definition())
602 if (extend
&& tell
== ftell(fout
)) {
603 (void)unlink(outfilename
);
610 S_output(char *infile
, char *define
, int extend
, char *outfile
, int append
)
617 char *currfile
= (OutFileFlag
? OutFile
: infile
);
620 open_input(infile
, define
);
621 memset(fullname
, 0, sizeof(fullname
));
623 strcpy(fullname
, prefix
);
624 strcat(fullname
, infile
);
626 strcpy(fullname
, infile
);
627 outfilename
= extend
? extendfile(fullname
, outfile
) : outfile
;
628 open_output(infile
, outfilename
);
629 f_print(fout
, "/* Machine generated file -- Do NOT edit */\n\n");
630 if (currfile
&& (include
= extendfile(currfile
, ".h"))) {
632 f_print(fout
, "#include \"%s\"\n", include
);
634 f_print(fout
, "#include <afsconfig.h>\n");
635 f_print(fout
, "#include <afs/param.h>\n");
636 f_print(fout
, "#include <roken.h>\n");
637 f_print(fout
, "#include \"%s\"\n\n", include
);
642 f_print(fout
, "#include \"h/types.h\"\n");
643 f_print(fout
, "#include \"h/socket.h\"\n");
644 f_print(fout
, "#include \"h/file.h\"\n");
645 f_print(fout
, "#include \"h/stat.h\"\n");
646 f_print(fout
, "#include \"netinet/in.h\"\n");
647 f_print(fout
, "#include \"h/time.h\"\n");
648 f_print(fout
, "#include \"rpc/types.h\"\n");
649 f_print(fout
, "#include \"rx/xdr.h\"\n");
650 f_print(fout
, "#include \"afs/rxgen_consts.h\"\n");
651 f_print(fout
, "#include \"afs/afs_osi.h\"\n");
652 f_print(fout
, "#include \"rx/rx.h\"\n");
654 f_print(fout
, "#include \"rx/rx_globals.h\"\n");
657 f_print(fout
, "#include \"rx/rx_opaque.h\"\n");
660 f_print(fout
, "#include <sys/types.h>\n");
661 f_print(fout
, "#include <rx/xdr.h>\n");
662 f_print(fout
, "#include <rx/rx.h>\n");
664 f_print(fout
, "#include <rx/rx_globals.h>\n");
667 f_print(fout
, "#include <rx/rx_opaque.h>\n");
669 f_print(fout
, "#include <afs/rxgen_consts.h>\n");
675 while ((def
= get_definition())) {
680 er_Proc_CodeGeneration();
682 if (extend
&& tell
== ftell(fout
)) {
683 (void)unlink(outfilename
);
691 static char max_size
[100];
693 int len
= (int)strlen(str
);
695 for (pnt
= max_size
; len
> 0; len
--, str
++) {
696 *pnt
++ = (islower(*str
) ? toupper(*str
) : *str
);
703 * Parse command line arguments
706 parseargs(int argc
, char *argv
[], struct commandline
*cmd
)
711 char flag
[(1 << (8 * sizeof(char)))];
715 cmd
->infile
= cmd
->outfile
= NULL
;
719 memset(flag
, 0, sizeof(flag
));
721 for (i
= 1; i
< argc
; i
++) {
722 if (argv
[i
][0] != '-') {
726 cmd
->infile
= argv
[i
];
728 for (j
= 1; argv
[i
][j
] != 0; j
++) {
751 if (argv
[i
][j
- 1] != '-' || argv
[i
][j
+ 1] != 0) {
761 cmd
->outfile
= argv
[i
];
764 if (argv
[i
][j
- 1] != '-')
766 prefix
= &argv
[i
][j
+ 1];
769 if (nincludes
>= MAXCPPARGS
) {
770 f_print(stderr
, "Too many -I arguments\n");
773 if (argv
[i
][j
- 1] != '-')
775 IncludeDir
[nincludes
++] = &argv
[i
][j
- 1];
785 cmd
->ansic_flag
= ansic_flag
= flag
['A'];
786 cmd
->brief_flag
= brief_flag
= flag
['b'];
787 cmd
->cflag
= cflag
= flag
['c'];
788 cmd
->hflag
= hflag
= flag
['h'];
789 cmd
->xflag
= xflag
= flag
['x'];
790 cmd
->yflag
= yflag
= flag
['y'];
791 cmd
->Cflag
= Cflag
= flag
['C'];
792 cmd
->Sflag
= Sflag
= flag
['S'];
793 cmd
->rflag
= flag
['r'];
794 cmd
->uflag
= uflag
= flag
['u'];
795 cmd
->kflag
= kflag
= flag
['k'];
796 cmd
->pflag
= flag
['p'];
797 cmd
->dflag
= debug
= flag
['d'];
802 cmd
->cflag
+ cmd
->hflag
+ cmd
->Cflag
+ cmd
->Sflag
+ cmd
->rflag
;
804 if (cmd
->outfile
!= NULL
|| cmd
->infile
== NULL
) {
807 } else if (nflags
> 1) {