4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
26 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
27 /* All Rights Reserved */
29 * University Copyright- Copyright (c) 1982, 1986, 1988
30 * The Regents of the University of California
33 * University Acknowledgment- Portions of this document are derived from
34 * software developed by the University of California, Berkeley, and its
39 * rpc_main.c, Top level of the RPC protocol compiler.
48 #include <sys/types.h>
49 #include <sys/param.h>
52 #include "rpc_parse.h"
57 extern void write_sample_svc(definition
*);
58 extern int write_sample_clnt(definition
*);
59 extern void write_sample_clnt_main(void);
60 extern void reinitialize(void);
61 extern void crash(void);
62 extern void add_type(int, char *);
63 extern void add_sample_msg(void);
65 static void svc_output(char *, char *, int, char *);
66 static void clnt_output(char *, char *, int, char *);
67 static void c_output(char *, char *, int, char *);
68 static void mkfile_output(struct commandline
*);
69 static void c_initialize(void);
70 static void h_output(char *, char *, int, char *);
71 static void s_output(int, char *[], char *, char *, int, char *, int, int);
72 static void l_output(char *, char *, int, char *);
73 static void t_output(char *, char *, int, char *);
74 static int do_registers(int, char *[]);
75 static uint_t
parseargs(int, char *[], struct commandline
*);
76 static void usage(void);
77 static void version_info(void);
78 static void options_usage(void);
80 #define EXTEND 1 /* alias for TRUE */
81 #define DONT_EXTEND 0 /* alias for FALSE */
83 #define SUNOS_CPP "/opt/gcc/4.4.4/bin/cpp"
84 static int cppDefined
= 0; /* explicit path for C preprocessor */
89 static char *svcclosetime
= "120";
90 static char *CPP
= SUNOS_CPP
;
91 static char CPPFLAGS
[] = "-C";
92 static char pathbuf
[MAXPATHLEN
+ 1];
93 static char *allv
[] = {
94 "rpcgen", "-s", "udp", "-s", "tcp",
96 static int allc
= sizeof (allv
)/sizeof (allv
[0]);
97 static char *allnv
[] = {
98 "rpcgen", "-s", "netpath",
100 static int allnc
= sizeof (allnv
)/sizeof (allnv
[0]);
103 * machinations for handling expanding argument list
105 static void addarg(char *); /* add another argument to the list */
106 static void putarg(int, char *); /* put argument at specified location */
107 static void clear_args(void); /* clear argument list */
108 static void checkfiles(char *, char *); /* check if out file already exists */
111 #define ARGLISTLEN 20
114 static char *arglist
[ARGLISTLEN
];
115 static int argcount
= FIXEDARGS
;
118 int nonfatalerrors
; /* errors */
119 int inetdflag
; /* Support for inetd is now the default */
120 int pmflag
; /* Support for port monitors */
121 int logflag
; /* Use syslog instead of fprintf for errors */
122 int tblflag
; /* Support for dispatch table file */
123 int mtflag
= 0; /* Support for MT */
124 int mtauto
= 0; /* Enable automatic mode */
125 int rflag
= 1; /* Eliminate tail recursion from structures */
127 /* length at which to start doing an inline */
129 int inlinelen
= INLINE
;
131 * Length at which to start doing an inline. INLINE = default
132 * if 0, no xdr_inline code
135 int indefinitewait
; /* If started by port monitors, hang till it wants */
136 int exitnow
; /* If started by port monitors, exit after the call */
137 int timerflag
; /* TRUE if !indefinite && !exitnow */
138 int newstyle
; /* newstyle of passing arguments (by value) */
139 int Cflag
= 0; /* ANSI C syntax */
140 int CCflag
= 0; /* C++ files */
141 static int allfiles
; /* generate all files */
142 int tirpcflag
= 1; /* generating code for tirpc, by default */
143 xdrfunc
*xdrfunc_head
= NULL
; /* xdr function list */
144 xdrfunc
*xdrfunc_tail
= NULL
; /* xdr function list */
149 main(int argc
, char *argv
[])
151 struct commandline cmd
;
153 (void) memset(&cmd
, 0, sizeof (struct commandline
));
155 if (!parseargs(argc
, argv
, &cmd
))
158 * Only the client and server side stubs are likely to be customized,
159 * so in that case only, check if the outfile exists, and if so,
160 * print an error message and exit.
162 if (cmd
.Ssflag
|| cmd
.Scflag
|| cmd
.makefileflag
)
163 checkfiles(cmd
.infile
, cmd
.outfile
);
165 checkfiles(cmd
.infile
, NULL
);
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
)) {
174 s_output(argc
, argv
, cmd
.infile
, "-DRPC_SVC", DONT_EXTEND
,
175 cmd
.outfile
, cmd
.mflag
, cmd
.nflag
);
176 } else if (cmd
.tflag
) {
177 t_output(cmd
.infile
, "-DRPC_TBL", DONT_EXTEND
, cmd
.outfile
);
178 } else if (cmd
.Ssflag
) {
179 svc_output(cmd
.infile
, "-DRPC_SERVER", DONT_EXTEND
,
181 } else if (cmd
.Scflag
) {
182 clnt_output(cmd
.infile
, "-DRPC_CLIENT", DONT_EXTEND
,
184 } else if (cmd
.makefileflag
) {
187 /* the rescans are required, since cpp may effect input */
188 c_output(cmd
.infile
, "-DRPC_XDR", EXTEND
, "_xdr.c");
190 h_output(cmd
.infile
, "-DRPC_HDR", EXTEND
, ".h");
192 l_output(cmd
.infile
, "-DRPC_CLNT", EXTEND
, "_clnt.c");
194 if (inetdflag
|| !tirpcflag
)
195 s_output(allc
, allv
, cmd
.infile
, "-DRPC_SVC", EXTEND
,
196 "_svc.c", cmd
.mflag
, cmd
.nflag
);
198 s_output(allnc
, allnv
, cmd
.infile
, "-DRPC_SVC",
199 EXTEND
, "_svc.c", cmd
.mflag
, cmd
.nflag
);
202 t_output(cmd
.infile
, "-DRPC_TBL", EXTEND
, "_tbl.i");
207 svc_output(cmd
.infile
, "-DRPC_SERVER", EXTEND
,
210 clnt_output(cmd
.infile
, "-DRPC_CLIENT", EXTEND
,
214 if (allfiles
|| (cmd
.makefileflag
== 1)) {
220 return (nonfatalerrors
);
225 * add extension to filename
228 extendfile(char *file
, char *ext
)
233 res
= malloc(strlen(file
) + strlen(ext
) + 1);
236 p
= strrchr(file
, '.');
238 p
= file
+ strlen(file
);
239 (void) strcpy(res
, file
);
240 (void) strcpy(res
+ (p
- file
), ext
);
245 * Open output file with given extension
248 open_output(char *infile
, char *outfile
)
251 if (outfile
== NULL
) {
256 if (infile
!= NULL
&& streq(outfile
, infile
)) {
258 "%s: %s already exists. No output generated.\n",
262 fout
= fopen(outfile
, "w");
264 f_print(stderr
, "%s: unable to open ", cmdname
);
268 record_open(outfile
);
275 f_print(fout
, "/*\n");
276 f_print(fout
, " * Please do not edit this file.\n");
277 f_print(fout
, " * It was generated using rpcgen.\n");
278 f_print(fout
, " */\n\n");
281 /* clear list of arguments */
287 for (i
= FIXEDARGS
; i
< ARGLISTLEN
; i
++)
289 argcount
= FIXEDARGS
;
292 /* make sure that a CPP exists */
298 if (stat(CPP
, &buf
) < 0) { /* SVR4 or explicit cpp does not exist */
300 (void) fprintf(stderr
,
301 "cannot find C preprocessor: %s \n", CPP
);
303 } else { /* try the other one */
305 if (stat(CPP
, &buf
) < 0) { /* can't find any cpp */
306 (void) fprintf(stderr
,
307 "cannot find any C preprocessor (cpp)\n");
315 * Open input file with given define for C-preprocessor
318 open_input(char *infile
, char *define
)
322 infilename
= (infile
== NULL
) ? "<stdin>" : infile
;
324 switch (childpid
= fork()) {
334 (void) dup2(pd
[1], 1);
336 (void) execv(arglist
[0], arglist
);
345 fin
= fdopen(pd
[0], "r");
347 f_print(stderr
, "%s: ", cmdname
);
353 /* valid tirpc nettypes */
354 static char *valid_ti_nettypes
[] = {
367 /* valid inetd nettypes */
368 static char *valid_i_nettypes
[] = {
375 check_nettype(char *name
, char *list_to_check
[])
378 for (i
= 0; list_to_check
[i
] != NULL
; i
++) {
379 if (strcmp(name
, list_to_check
[i
]) == 0) {
383 f_print(stderr
, "illegal nettype :\'%s\'\n", name
);
388 file_name(char *file
, char *ext
)
391 temp
= extendfile(file
, ext
);
393 if (access(temp
, F_OK
) != -1)
396 return ((char *)" ");
401 c_output(char *infile
, char *define
, int extend
, char *outfile
)
409 open_input(infile
, define
);
410 outfilename
= extend
? extendfile(infile
, outfile
) : outfile
;
411 open_output(infile
, outfilename
);
413 if (infile
&& (include
= extendfile(infile
, ".h"))) {
414 f_print(fout
, "#include \"%s\"\n", include
);
416 /* .h file already contains rpc/rpc.h */
418 f_print(fout
, "#include <rpc/rpc.h>\n");
420 * Include stdlib.h to support mem_alloc calls.
422 f_print(fout
, "\n#ifndef _KERNEL\n");
423 f_print(fout
, "#include <stdlib.h>\n");
424 f_print(fout
, "#endif /* !_KERNEL */\n\n");
426 while (def
= get_definition()) {
429 if (extend
&& tell
== ftell(fout
)) {
430 (void) unlink(outfilename
);
439 * add all the starting basic types.
440 * We may need to add some derived types
441 * if we need to generate INLINE macros.
442 * These types are defined in rpc/types.h
446 add_type(1, "short");
448 add_type(1, "u_int");
449 add_type(1, "u_long");
450 add_type(1, "u_short");
451 add_type(1, "rpcprog_t");
452 add_type(1, "rpcvers_t");
453 add_type(1, "rpcproc_t");
454 add_type(1, "rpcprot_t");
455 add_type(1, "rpcport_t");
458 char rpcgen_table_dcl1
[] = "struct rpcgen_table {\n";
460 char rpcgen_table_dcl2
[] = "\txdrproc_t\txdr_arg;\n"
461 "\tunsigned\tlen_arg;\n"
462 "\txdrproc_t\txdr_res;\n"
463 "\tunsigned\tlen_res;\n"
466 char rpcgen_table_proc
[] = "\tvoid\t*(*proc)();\n";
468 char rpcgen_table_proc_b
[] = "\tchar\t*(*proc)();\n";
472 generate_guard(char *pathname
)
474 char *filename
, *guard
, *tmp
;
476 filename
= strrchr(pathname
, '/'); /* find last component */
477 filename
= ((filename
== 0) ? pathname
: filename
+1);
478 guard
= extendfile(filename
, "_H_RPCGEN");
481 * Guard must be an ANSI C identifier composed of
482 * upper case letters, digits, or '_'.
483 * Convert invalid characters to '_'.
485 for (tmp
= guard
; *tmp
; tmp
++) {
486 if (!isalpha(*tmp
) && !isdigit(*tmp
)) {
491 *tmp
= toupper(*tmp
);
495 * The first character must be a letter; the underscore '_'
496 * counts as a letter.
498 if (!isalpha(guard
[0]))
505 * Compile into an XDR header file
510 h_output(char *infile
, char *define
, int extend
, char *outfile
)
520 open_input(infile
, define
);
521 outfilename
= extend
? extendfile(infile
, outfile
) : outfile
;
522 open_output(infile
, outfilename
);
524 if (outfilename
|| infile
)
525 guard
= generate_guard(outfilename
? outfilename
: infile
);
529 f_print(fout
, "#ifndef _%s\n#define _%s\n\n", guard
, guard
);
531 f_print(fout
, "#include <rpc/rpc.h>\n");
534 f_print(fout
, "#ifndef _KERNEL\n");
535 f_print(fout
, "#include <synch.h>\n");
536 f_print(fout
, "#include <thread.h>\n");
537 f_print(fout
, "#endif /* !_KERNEL */\n");
540 /* put the C++ support */
541 if (Cflag
&& !CCflag
) {
542 f_print(fout
, "\n#ifdef __cplusplus\n");
543 f_print(fout
, "extern \"C\" {\n");
544 f_print(fout
, "#endif\n\n");
547 /* put in a typedef for quadprecision. Only with Cflag */
550 * declaration of struct rpcgen_table must go before
551 * the definition of arrays like *_1_table[]
554 f_print(fout
, rpcgen_table_dcl1
);
556 f_print(fout
, rpcgen_table_proc
);
558 f_print(fout
, rpcgen_table_proc_b
);
559 f_print(fout
, rpcgen_table_dcl2
);
564 /* print data definitions */
565 while (def
= get_definition())
569 * print function declarations.
570 * Do this after data definitions because they might be used as
571 * arguments for functions
573 for (l
= defined
; l
!= NULL
; l
= l
->next
)
574 print_funcdef(l
->val
);
575 /* Now print all xdr func declarations */
576 if (xdrfunc_head
!= NULL
) {
577 f_print(fout
, "\n/* the xdr functions */\n");
580 f_print(fout
, "\n#ifdef __cplusplus\n");
581 f_print(fout
, "extern \"C\" {\n");
582 f_print(fout
, "#endif\n");
586 xdrfuncp
= xdrfunc_head
;
587 while (xdrfuncp
!= NULL
) {
588 print_xdr_func_def(xdrfuncp
->name
,
589 xdrfuncp
->pointerp
, 2);
590 xdrfuncp
= xdrfuncp
->next
;
593 for (i
= 1; i
< 3; i
++) {
596 "\n#if defined(__STDC__) || defined(__cplusplus)\n");
598 f_print(fout
, "\n#else /* K&R C */\n");
600 xdrfuncp
= xdrfunc_head
;
601 while (xdrfuncp
!= NULL
) {
602 print_xdr_func_def(xdrfuncp
->name
,
603 xdrfuncp
->pointerp
, i
);
604 xdrfuncp
= xdrfuncp
->next
;
607 f_print(fout
, "\n#endif /* K&R C */\n");
611 if (extend
&& tell
== ftell(fout
)) {
612 (void) unlink(outfilename
);
616 f_print(fout
, "\n#ifdef __cplusplus\n");
617 f_print(fout
, "}\n");
618 f_print(fout
, "#endif\n");
621 f_print(fout
, "\n#endif /* !_%s */\n", guard
);
625 * Compile into an RPC service
628 s_output(int argc
, char *argv
[], char *infile
, char *define
, int extend
,
629 char *outfile
, int nomain
, int netflag
)
633 int foundprogram
= 0;
636 open_input(infile
, define
);
637 outfilename
= extend
? extendfile(infile
, outfile
) : outfile
;
638 open_output(infile
, outfilename
);
640 if (infile
&& (include
= extendfile(infile
, ".h"))) {
641 f_print(fout
, "#include \"%s\"\n", include
);
644 f_print(fout
, "#include <rpc/rpc.h>\n");
646 f_print(fout
, "#include <stdio.h>\n");
647 f_print(fout
, "#include <stdlib.h> /* getenv, exit */\n");
648 f_print(fout
, "#include <signal.h>\n");
652 "#include <rpc/pmap_clnt.h> /* for pmap_unset */\n");
653 f_print(fout
, "#include <string.h> /* strcmp */\n");
655 if (strcmp(svcclosetime
, "-1") == 0)
657 else if (strcmp(svcclosetime
, "0") == 0)
659 else if (inetdflag
|| pmflag
)
662 if (!tirpcflag
&& inetdflag
)
663 f_print(fout
, "#include <sys/termios.h> /* TIOCNOTTY */\n");
664 if (Cflag
&& (inetdflag
|| pmflag
))
666 f_print(fout
, "#include <unistd.h> /* setsid */\n");
668 f_print(fout
, "#include <sys/types.h>\n");
670 f_print(fout
, "#include <memory.h>\n");
671 f_print(fout
, "#include <stropts.h>\n");
672 if (inetdflag
|| !tirpcflag
) {
673 f_print(fout
, "#include <sys/socket.h>\n");
674 f_print(fout
, "#include <netinet/in.h>\n");
675 f_print(fout
, "#include <rpc/svc_soc.h>\n");
678 if ((netflag
|| pmflag
) && tirpcflag
&& !nomain
)
679 f_print(fout
, "#include <netconfig.h>\n");
681 f_print(fout
, "#include <sys/resource.h> /* rlimit */\n");
682 if (logflag
|| inetdflag
|| pmflag
)
683 f_print(fout
, "#include <syslog.h>\n");
688 "\n#ifndef SIG_PF\n#define SIG_PF void(*)\
691 f_print(fout
, "\n#ifdef DEBUG\n#define RPC_SVC_FG\n#endif\n");
693 f_print(fout
, "\n#define _RPCSVC_CLOSEDOWN %s\n",
695 while (def
= get_definition())
696 foundprogram
|= (def
->def_kind
== DEF_PROGRAM
);
697 if (extend
&& !foundprogram
) {
698 (void) unlink(outfilename
);
701 write_most(infile
, netflag
, nomain
);
703 if (!do_registers(argc
, argv
)) {
705 (void) unlink(outfilename
);
713 * generate client side stubs
716 l_output(char *infile
, char *define
, int extend
, char *outfile
)
720 int foundprogram
= 0;
723 open_input(infile
, define
);
724 outfilename
= extend
? extendfile(infile
, outfile
) : outfile
;
725 open_output(infile
, outfilename
);
728 f_print(fout
, "#include <memory.h> /* for memset */\n");
729 if (infile
&& (include
= extendfile(infile
, ".h"))) {
730 f_print(fout
, "#include \"%s\"\n", include
);
733 f_print(fout
, "#include <rpc/rpc.h>\n");
735 f_print(fout
, "#ifndef _KERNEL\n");
736 f_print(fout
, "#include <stdio.h>\n");
737 f_print(fout
, "#include <stdlib.h> /* getenv, exit */\n");
738 f_print(fout
, "#endif /* !_KERNEL */\n");
740 while (def
= get_definition())
741 foundprogram
|= (def
->def_kind
== DEF_PROGRAM
);
742 if (extend
&& !foundprogram
) {
743 (void) unlink(outfilename
);
750 * generate the dispatch table
753 t_output(char *infile
, char *define
, int extend
, char *outfile
)
756 int foundprogram
= 0;
759 open_input(infile
, define
);
760 outfilename
= extend
? extendfile(infile
, outfile
) : outfile
;
761 open_output(infile
, outfilename
);
763 while (def
= get_definition()) {
764 foundprogram
|= (def
->def_kind
== DEF_PROGRAM
);
766 if (extend
&& !foundprogram
) {
767 (void) unlink(outfilename
);
773 /* sample routine for the server template */
775 svc_output(char *infile
, char *define
, int extend
, char *outfile
)
781 open_input(infile
, define
);
782 outfilename
= extend
? extendfile(infile
, outfile
) : outfile
;
783 checkfiles(infile
, outfilename
);
785 * Check if outfile already exists.
786 * if so, print an error message and exit
788 open_output(infile
, outfilename
);
791 if (infile
&& (include
= extendfile(infile
, ".h"))) {
792 f_print(fout
, "#include \"%s\"\n", include
);
795 f_print(fout
, "#include <rpc/rpc.h>\n");
798 f_print(fout
, "#include <stdio.h>\n");
799 f_print(fout
, "#include <stdlib.h> /* getenv, exit */\n");
800 f_print(fout
, "#include <signal.h>\n");
803 while (def
= get_definition())
804 write_sample_svc(def
);
805 if (extend
&& tell
== ftell(fout
))
806 (void) unlink(outfilename
);
809 /* sample main routine for client */
811 clnt_output(char *infile
, char *define
, int extend
, char *outfile
)
819 open_input(infile
, define
);
820 outfilename
= extend
? extendfile(infile
, outfile
) : outfile
;
821 checkfiles(infile
, outfilename
);
823 * Check if outfile already exists.
824 * if so, print an error message and exit
827 open_output(infile
, outfilename
);
829 if (infile
&& (include
= extendfile(infile
, ".h"))) {
830 f_print(fout
, "#include \"%s\"\n", include
);
833 f_print(fout
, "#include <rpc/rpc.h>\n");
835 f_print(fout
, "#include <stdio.h>\n");
836 f_print(fout
, "#include <stdlib.h> /* getenv, exit */\n");
839 while (def
= get_definition())
840 has_program
+= write_sample_clnt(def
);
843 write_sample_clnt_main();
845 if (extend
&& tell
== ftell(fout
))
846 (void) unlink(outfilename
);
851 mkfile_output(struct commandline
*cmd
)
853 char *mkfilename
, *clientname
, *clntname
, *xdrname
, *hdrname
;
854 char *servername
, *svcname
, *servprogname
, *clntprogname
;
857 svcname
= file_name(cmd
->infile
, "_svc.c");
858 clntname
= file_name(cmd
->infile
, "_clnt.c");
859 xdrname
= file_name(cmd
->infile
, "_xdr.c");
860 hdrname
= file_name(cmd
->infile
, ".h");
864 servername
= extendfile(cmd
->infile
, "_server.c");
865 clientname
= extendfile(cmd
->infile
, "_client.c");
870 servprogname
= extendfile(cmd
->infile
, "_server");
871 clntprogname
= extendfile(cmd
->infile
, "_client");
874 mkfilename
= malloc(strlen("makefile.") +
875 strlen(cmd
->infile
) + 1);
876 if (mkfilename
== NULL
) {
877 f_print(stderr
, "Out of memory!\n");
880 temp
= (char *)rindex(cmd
->infile
, '.');
881 (void) strcpy(mkfilename
, "makefile.");
882 (void) strncat(mkfilename
, cmd
->infile
,
883 (temp
- cmd
->infile
));
885 mkfilename
= cmd
->outfile
;
888 checkfiles(NULL
, mkfilename
);
889 open_output(NULL
, mkfilename
);
891 f_print(fout
, "\n# This is a template makefile generated\
894 f_print(fout
, "\n# Parameters \n\n");
896 f_print(fout
, "CLIENT = %s\nSERVER = %s\n\n",
897 clntprogname
, servprogname
);
898 f_print(fout
, "SOURCES_CLNT.c = \nSOURCES_CLNT.h = \n");
899 f_print(fout
, "SOURCES_SVC.c = \nSOURCES_SVC.h = \n");
900 f_print(fout
, "SOURCES.x = %s\n\n", cmd
->infile
);
901 f_print(fout
, "TARGETS_SVC.c = %s %s %s \n",
902 svcname
, servername
, xdrname
);
903 f_print(fout
, "TARGETS_CLNT.c = %s %s %s \n",
904 clntname
, clientname
, xdrname
);
905 f_print(fout
, "TARGETS = %s %s %s %s %s %s\n\n",
906 hdrname
, xdrname
, clntname
,
907 svcname
, clientname
, servername
);
909 f_print(fout
, "OBJECTS_CLNT = $(SOURCES_CLNT.c:%%.c=%%.o) "
910 "$(TARGETS_CLNT.c:%%.c=%%.o) ");
912 f_print(fout
, "\nOBJECTS_SVC = $(SOURCES_SVC.c:%%.c=%%.o) "
913 "$(TARGETS_SVC.c:%%.c=%%.o) ");
916 f_print(fout
, "\n# Compiler flags \n");
917 f_print(fout
, "\nCFLAGS += -g \n");
918 f_print(fout
, "RPCGENFLAGS = \n");
920 f_print(fout
, "\n# Targets \n\n");
922 f_print(fout
, "all : $(CLIENT) $(SERVER)\n\n");
923 f_print(fout
, "$(TARGETS) : $(SOURCES.x) \n");
924 f_print(fout
, "\trpcgen $(RPCGENFLAGS) $(SOURCES.x)\n\n");
925 f_print(fout
, "$(OBJECTS_CLNT) : $(SOURCES_CLNT.c) $(SOURCES_CLNT.h) \
926 $(TARGETS_CLNT.c) \n\n");
928 f_print(fout
, "$(OBJECTS_SVC) : $(SOURCES_SVC.c) $(SOURCES_SVC.h) \
929 $(TARGETS_SVC.c) \n\n");
930 f_print(fout
, "$(CLIENT) : $(OBJECTS_CLNT) \n");
931 f_print(fout
, "\t$(LINK.c) -o $(CLIENT) $(OBJECTS_CLNT) \
933 f_print(fout
, "$(SERVER) : $(OBJECTS_SVC) \n");
934 f_print(fout
, "\t$(LINK.c) -o $(SERVER) $(OBJECTS_SVC) $(LDLIBS)\n\n ");
935 f_print(fout
, "clean:\n\t $(RM) core $(TARGETS) $(OBJECTS_CLNT) \
936 $(OBJECTS_SVC) $(CLIENT) $(SERVER)\n\n");
941 * Perform registrations for service output
942 * Return 0 if failed; 1 otherwise.
945 do_registers(int argc
, char *argv
[])
949 if (inetdflag
|| !tirpcflag
) {
950 for (i
= 1; i
< argc
; i
++) {
951 if (streq(argv
[i
], "-s")) {
952 if (!check_nettype(argv
[i
+ 1],
955 write_inetd_register(argv
[i
+ 1]);
960 for (i
= 1; i
< argc
; i
++)
961 if (streq(argv
[i
], "-s")) {
962 if (!check_nettype(argv
[i
+ 1],
965 write_nettype_register(argv
[i
+ 1]);
967 } else if (streq(argv
[i
], "-n")) {
968 write_netid_register(argv
[i
+ 1]);
976 * Add another argument to the arg list
981 if (argcount
>= ARGLISTLEN
) {
982 f_print(stderr
, "rpcgen: too many defines\n");
986 arglist
[argcount
++] = cp
;
990 putarg(int where
, char *cp
)
992 if (where
>= ARGLISTLEN
) {
993 f_print(stderr
, "rpcgen: arglist coding error\n");
1001 * if input file is stdin and an output file is specified then complain
1002 * if the file already exists. Otherwise the file may get overwritten
1003 * If input file does not exist, exit with an error
1006 checkfiles(char *infile
, char *outfile
)
1010 if (infile
) { /* infile ! = NULL */
1011 if (stat(infile
, &buf
) < 0) {
1017 if (stat(outfile
, &buf
) < 0)
1018 return; /* file does not exist */
1020 "file '%s' already exists and may be overwritten\n",
1027 * Parse command line arguments
1030 parseargs(int argc
, char *argv
[], struct commandline
*cmd
)
1035 char flag
[(1 << 8 * sizeof (char))];
1039 cmd
->infile
= cmd
->outfile
= NULL
;
1055 for (i
= 1; i
< argc
; i
++) {
1056 if (argv
[i
][0] != '-') {
1059 "Cannot specify more than one input file.\n");
1063 cmd
->infile
= argv
[i
];
1065 for (j
= 1; argv
[i
][j
] != 0; j
++) {
1082 * sample flag: Ss or Sc.
1083 * Ss means set flag['S'];
1084 * Sc means set flag['C'];
1085 * Sm means set flag['M'];
1087 ch
= argv
[i
][++j
]; /* get next char */
1101 case 'C': /* ANSI C syntax */
1103 ch
= argv
[i
][j
+1]; /* get next char */
1111 * Turn TIRPC flag off for
1112 * generating backward compatible
1130 svcclosetime
= argv
[i
];
1144 inlinelen
= atoi(argv
[i
]);
1149 if (argv
[i
][j
- 1] != '-' ||
1150 argv
[i
][j
+ 1] != 0)
1158 cmd
->outfile
= argv
[i
];
1162 if (argv
[i
][j
- 1] != '-')
1164 (void) addarg(argv
[i
]);
1172 (void) strcpy(pathbuf
, argv
[i
]);
1173 (void) strcat(pathbuf
, "/cpp");
1189 cmd
->cflag
= flag
['c'];
1190 cmd
->hflag
= flag
['h'];
1191 cmd
->lflag
= flag
['l'];
1192 cmd
->mflag
= flag
['m'];
1193 cmd
->nflag
= flag
['n'];
1194 cmd
->sflag
= flag
['s'];
1195 cmd
->tflag
= flag
['t'];
1196 cmd
->Ssflag
= flag
['S'];
1197 cmd
->Scflag
= flag
['C'];
1198 cmd
->makefileflag
= flag
['M'];
1203 "Cannot use -I flag without -b flag.\n");
1207 } else { /* 4.1 mode */
1208 pmflag
= 0; /* set pmflag only in tirpcmode */
1209 inetdflag
= 1; /* inetdflag is TRUE by default */
1210 if (cmd
->nflag
) { /* netid needs TIRPC */
1212 "Cannot use netid flag without TIRPC.\n");
1217 if (newstyle
&& (tblflag
|| cmd
->tflag
)) {
1218 f_print(stderr
, "Cannot use table flags with newstyle.\n");
1222 /* check no conflicts with file generation flags */
1223 nflags
= cmd
->cflag
+ cmd
->hflag
+ cmd
->lflag
+ cmd
->mflag
+
1224 cmd
->sflag
+ cmd
->nflag
+ cmd
->tflag
+ cmd
->Ssflag
+
1225 cmd
->Scflag
+ cmd
->makefileflag
;
1228 if (cmd
->outfile
!= NULL
|| cmd
->infile
== NULL
)
1230 } else if (cmd
->infile
== NULL
&&
1231 (cmd
->Ssflag
|| cmd
->Scflag
|| cmd
->makefileflag
)) {
1232 f_print(stderr
, "\"infile\" is required for template"
1233 " generation flags.\n");
1238 "Cannot have more than one file generation flag.\n");
1247 f_print(stderr
, "%s (%d.%d)\n", cmdname
, RPCGEN_MAJOR
, RPCGEN_MINOR
);
1248 f_print(stderr
, "usage: %s infile\n", cmdname
);
1249 f_print(stderr
, "\t%s [-abCLNTMA] [-Dname[=value]] [-i size]"
1250 " [-I [-K seconds]] [-Y path] infile\n", cmdname
);
1251 f_print(stderr
, "\t%s [-c | -h | -l | -m | -t | -Sc | -Ss | -Sm]"
1252 " [-o outfile] [infile]\n", cmdname
);
1253 f_print(stderr
, "\t%s [-s nettype]* [-o outfile] [infile]\n", cmdname
);
1254 f_print(stderr
, "\t%s [-n netid]* [-o outfile] [infile]\n", cmdname
);
1262 f_print(stderr
, "%s %d.%d\n", cmdname
, RPCGEN_MAJOR
, RPCGEN_MINOR
);
1270 f_print(stderr
, "options:\n");
1271 f_print(stderr
, "-a\t\tgenerate all files, including samples\n");
1272 f_print(stderr
, "-A\t\tgenerate code to enable automatic MT mode\n");
1273 f_print(stderr
, "-b\t\tbackward compatibility mode (generates code"
1274 " for SunOS 4.X)\n");
1275 f_print(stderr
, "-c\t\tgenerate XDR routines\n");
1276 f_print(stderr
, "-C\t\tANSI C mode\n");
1277 f_print(stderr
, "-Dname[=value]\tdefine a symbol (same as #define)\n");
1278 f_print(stderr
, "-h\t\tgenerate header file\n");
1279 f_print(stderr
, "-i size\t\tsize at which to start generating"
1281 f_print(stderr
, "-I\t\tgenerate code for inetd support in server"
1282 " (for SunOS 4.X)\n");
1283 f_print(stderr
, "-K seconds\tserver exits after K seconds of"
1285 f_print(stderr
, "-l\t\tgenerate client side stubs\n");
1286 f_print(stderr
, "-L\t\tserver errors will be printed to syslog\n");
1287 f_print(stderr
, "-m\t\tgenerate server side stubs\n");
1288 f_print(stderr
, "-M\t\tgenerate MT-safe code\n");
1289 f_print(stderr
, "-n netid\tgenerate server code that supports"
1291 f_print(stderr
, "-N\t\tsupports multiple arguments and"
1292 " call-by-value\n");
1293 f_print(stderr
, "-o outfile\tname of the output file\n");
1294 f_print(stderr
, "-s nettype\tgenerate server code that supports named"
1296 f_print(stderr
, "-Sc\t\tgenerate sample client code that uses remote"
1298 f_print(stderr
, "-Ss\t\tgenerate sample server code that defines"
1299 " remote procedures\n");
1300 f_print(stderr
, "-Sm \t\tgenerate makefile template \n");
1302 f_print(stderr
, "-t\t\tgenerate RPC dispatch table\n");
1303 f_print(stderr
, "-T\t\tgenerate code to support RPC dispatch tables\n");
1304 f_print(stderr
, "-v\t\tprint version information and exit\n");
1305 f_print(stderr
, "-Y path\t\tpath where cpp is found\n");