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
[] = {
94 static char pathbuf
[MAXPATHLEN
+ 1];
95 static char *allv
[] = {
96 "rpcgen", "-s", "udp", "-s", "tcp",
98 static int allc
= sizeof (allv
)/sizeof (allv
[0]);
99 static char *allnv
[] = {
100 "rpcgen", "-s", "netpath",
102 static int allnc
= sizeof (allnv
)/sizeof (allnv
[0]);
105 * machinations for handling expanding argument list
107 static void addarg(char *); /* add another argument to the list */
108 static void putarg(int, char *); /* put argument at specified location */
109 static void clear_args(void); /* clear argument list */
110 static void checkfiles(char *, char *); /* check if out file already exists */
113 #define ARGLISTLEN 20
116 static char *arglist
[ARGLISTLEN
];
117 static int argcount
= FIXEDARGS
;
120 int nonfatalerrors
; /* errors */
121 int inetdflag
; /* Support for inetd is now the default */
122 int pmflag
; /* Support for port monitors */
123 int logflag
; /* Use syslog instead of fprintf for errors */
124 int tblflag
; /* Support for dispatch table file */
125 int mtflag
= 0; /* Support for MT */
126 int mtauto
= 0; /* Enable automatic mode */
127 int rflag
= 1; /* Eliminate tail recursion from structures */
129 /* length at which to start doing an inline */
131 int inlinelen
= INLINE
;
133 * Length at which to start doing an inline. INLINE = default
134 * if 0, no xdr_inline code
137 int indefinitewait
; /* If started by port monitors, hang till it wants */
138 int exitnow
; /* If started by port monitors, exit after the call */
139 int timerflag
; /* TRUE if !indefinite && !exitnow */
140 int newstyle
; /* newstyle of passing arguments (by value) */
141 int Cflag
= 0; /* ANSI C syntax */
142 int CCflag
= 0; /* C++ files */
143 static int allfiles
; /* generate all files */
144 int tirpcflag
= 1; /* generating code for tirpc, by default */
145 xdrfunc
*xdrfunc_head
= NULL
; /* xdr function list */
146 xdrfunc
*xdrfunc_tail
= NULL
; /* xdr function list */
151 main(int argc
, char *argv
[])
153 struct commandline cmd
;
155 (void) memset(&cmd
, 0, sizeof (struct commandline
));
157 if (!parseargs(argc
, argv
, &cmd
))
160 * Only the client and server side stubs are likely to be customized,
161 * so in that case only, check if the outfile exists, and if so,
162 * print an error message and exit.
164 if (cmd
.Ssflag
|| cmd
.Scflag
|| cmd
.makefileflag
)
165 checkfiles(cmd
.infile
, cmd
.outfile
);
167 checkfiles(cmd
.infile
, NULL
);
170 c_output(cmd
.infile
, "-DRPC_XDR", DONT_EXTEND
, cmd
.outfile
);
171 } else if (cmd
.hflag
) {
172 h_output(cmd
.infile
, "-DRPC_HDR", DONT_EXTEND
, cmd
.outfile
);
173 } else if (cmd
.lflag
) {
174 l_output(cmd
.infile
, "-DRPC_CLNT", DONT_EXTEND
, cmd
.outfile
);
175 } else if (cmd
.sflag
|| cmd
.mflag
|| (cmd
.nflag
)) {
176 s_output(argc
, argv
, cmd
.infile
, "-DRPC_SVC", DONT_EXTEND
,
177 cmd
.outfile
, cmd
.mflag
, cmd
.nflag
);
178 } else if (cmd
.tflag
) {
179 t_output(cmd
.infile
, "-DRPC_TBL", DONT_EXTEND
, cmd
.outfile
);
180 } else if (cmd
.Ssflag
) {
181 svc_output(cmd
.infile
, "-DRPC_SERVER", DONT_EXTEND
,
183 } else if (cmd
.Scflag
) {
184 clnt_output(cmd
.infile
, "-DRPC_CLIENT", DONT_EXTEND
,
186 } else if (cmd
.makefileflag
) {
189 /* the rescans are required, since cpp may effect input */
190 c_output(cmd
.infile
, "-DRPC_XDR", EXTEND
, "_xdr.c");
192 h_output(cmd
.infile
, "-DRPC_HDR", EXTEND
, ".h");
194 l_output(cmd
.infile
, "-DRPC_CLNT", EXTEND
, "_clnt.c");
196 if (inetdflag
|| !tirpcflag
)
197 s_output(allc
, allv
, cmd
.infile
, "-DRPC_SVC", EXTEND
,
198 "_svc.c", cmd
.mflag
, cmd
.nflag
);
200 s_output(allnc
, allnv
, cmd
.infile
, "-DRPC_SVC",
201 EXTEND
, "_svc.c", cmd
.mflag
, cmd
.nflag
);
204 t_output(cmd
.infile
, "-DRPC_TBL", EXTEND
, "_tbl.i");
209 svc_output(cmd
.infile
, "-DRPC_SERVER", EXTEND
,
212 clnt_output(cmd
.infile
, "-DRPC_CLIENT", EXTEND
,
216 if (allfiles
|| (cmd
.makefileflag
== 1)) {
222 return (nonfatalerrors
);
227 * add extension to filename
230 extendfile(char *file
, char *ext
)
235 res
= malloc(strlen(file
) + strlen(ext
) + 1);
238 p
= strrchr(file
, '.');
240 p
= file
+ strlen(file
);
241 (void) strcpy(res
, file
);
242 (void) strcpy(res
+ (p
- file
), ext
);
247 * Open output file with given extension
250 open_output(char *infile
, char *outfile
)
253 if (outfile
== NULL
) {
258 if (infile
!= NULL
&& streq(outfile
, infile
)) {
260 "%s: %s already exists. No output generated.\n",
264 fout
= fopen(outfile
, "w");
266 f_print(stderr
, "%s: unable to open ", cmdname
);
270 record_open(outfile
);
277 f_print(fout
, "/*\n");
278 f_print(fout
, " * Please do not edit this file.\n");
279 f_print(fout
, " * It was generated using rpcgen.\n");
280 f_print(fout
, " */\n\n");
283 /* clear list of arguments */
289 for (i
= FIXEDARGS
; i
< ARGLISTLEN
; i
++)
291 argcount
= FIXEDARGS
;
294 /* make sure that a CPP exists */
300 if (stat(CPP
, &buf
) < 0) { /* SVR4 or explicit cpp does not exist */
302 (void) fprintf(stderr
,
303 "cannot find C preprocessor: %s \n", CPP
);
305 } else { /* try the other one */
307 if (stat(CPP
, &buf
) < 0) { /* can't find any cpp */
308 (void) fprintf(stderr
,
309 "cannot find any C preprocessor (cpp)\n");
317 * Open input file with given define for C-preprocessor
320 open_input(char *infile
, char *define
)
325 infilename
= (infile
== NULL
) ? "<stdin>" : infile
;
327 switch (childpid
= fork()) {
331 for (i
= 0; CPPFLAGS
[i
] != NULL
; i
++)
338 (void) dup2(pd
[1], 1);
340 (void) execv(arglist
[0], arglist
);
349 fin
= fdopen(pd
[0], "r");
351 f_print(stderr
, "%s: ", cmdname
);
357 /* valid tirpc nettypes */
358 static char *valid_ti_nettypes
[] = {
371 /* valid inetd nettypes */
372 static char *valid_i_nettypes
[] = {
379 check_nettype(char *name
, char *list_to_check
[])
382 for (i
= 0; list_to_check
[i
] != NULL
; i
++) {
383 if (strcmp(name
, list_to_check
[i
]) == 0) {
387 f_print(stderr
, "illegal nettype :\'%s\'\n", name
);
392 file_name(char *file
, char *ext
)
395 temp
= extendfile(file
, ext
);
397 if (access(temp
, F_OK
) != -1)
400 return ((char *)" ");
405 c_output(char *infile
, char *define
, int extend
, char *outfile
)
413 open_input(infile
, define
);
414 outfilename
= extend
? extendfile(infile
, outfile
) : outfile
;
415 open_output(infile
, outfilename
);
417 if (infile
&& (include
= extendfile(infile
, ".h"))) {
418 f_print(fout
, "#include \"%s\"\n", include
);
420 /* .h file already contains rpc/rpc.h */
422 f_print(fout
, "#include <rpc/rpc.h>\n");
424 * Include stdlib.h to support mem_alloc calls.
426 f_print(fout
, "\n#ifndef _KERNEL\n");
427 f_print(fout
, "#include <stdlib.h>\n");
428 f_print(fout
, "#endif /* !_KERNEL */\n\n");
430 while (def
= get_definition()) {
433 if (extend
&& tell
== ftell(fout
)) {
434 (void) unlink(outfilename
);
443 * add all the starting basic types.
444 * We may need to add some derived types
445 * if we need to generate INLINE macros.
446 * These types are defined in rpc/types.h
450 add_type(1, "short");
452 add_type(1, "u_int");
453 add_type(1, "u_long");
454 add_type(1, "u_short");
455 add_type(1, "rpcprog_t");
456 add_type(1, "rpcvers_t");
457 add_type(1, "rpcproc_t");
458 add_type(1, "rpcprot_t");
459 add_type(1, "rpcport_t");
462 char rpcgen_table_dcl1
[] = "struct rpcgen_table {\n";
464 char rpcgen_table_dcl2
[] = "\txdrproc_t\txdr_arg;\n"
465 "\tunsigned\tlen_arg;\n"
466 "\txdrproc_t\txdr_res;\n"
467 "\tunsigned\tlen_res;\n"
470 char rpcgen_table_proc
[] = "\tvoid\t*(*proc)();\n";
472 char rpcgen_table_proc_b
[] = "\tchar\t*(*proc)();\n";
476 generate_guard(char *pathname
)
478 char *filename
, *guard
, *tmp
;
480 filename
= strrchr(pathname
, '/'); /* find last component */
481 filename
= ((filename
== 0) ? pathname
: filename
+1);
482 guard
= extendfile(filename
, "_H_RPCGEN");
485 * Guard must be an ANSI C identifier composed of
486 * upper case letters, digits, or '_'.
487 * Convert invalid characters to '_'.
489 for (tmp
= guard
; *tmp
; tmp
++) {
490 if (!isalpha(*tmp
) && !isdigit(*tmp
)) {
495 *tmp
= toupper(*tmp
);
499 * The first character must be a letter; the underscore '_'
500 * counts as a letter.
502 if (!isalpha(guard
[0]))
509 * Compile into an XDR header file
514 h_output(char *infile
, char *define
, int extend
, char *outfile
)
524 open_input(infile
, define
);
525 outfilename
= extend
? extendfile(infile
, outfile
) : outfile
;
526 open_output(infile
, outfilename
);
528 if (outfilename
|| infile
)
529 guard
= generate_guard(outfilename
? outfilename
: infile
);
533 f_print(fout
, "#ifndef _%s\n#define _%s\n\n", guard
, guard
);
535 f_print(fout
, "#include <rpc/rpc.h>\n");
538 f_print(fout
, "#ifndef _KERNEL\n");
539 f_print(fout
, "#include <synch.h>\n");
540 f_print(fout
, "#include <thread.h>\n");
541 f_print(fout
, "#endif /* !_KERNEL */\n");
544 /* put the C++ support */
545 if (Cflag
&& !CCflag
) {
546 f_print(fout
, "\n#ifdef __cplusplus\n");
547 f_print(fout
, "extern \"C\" {\n");
548 f_print(fout
, "#endif\n\n");
551 /* put in a typedef for quadprecision. Only with Cflag */
554 * declaration of struct rpcgen_table must go before
555 * the definition of arrays like *_1_table[]
558 f_print(fout
, rpcgen_table_dcl1
);
560 f_print(fout
, rpcgen_table_proc
);
562 f_print(fout
, rpcgen_table_proc_b
);
563 f_print(fout
, rpcgen_table_dcl2
);
568 /* print data definitions */
569 while (def
= get_definition())
573 * print function declarations.
574 * Do this after data definitions because they might be used as
575 * arguments for functions
577 for (l
= defined
; l
!= NULL
; l
= l
->next
)
578 print_funcdef(l
->val
);
579 /* Now print all xdr func declarations */
580 if (xdrfunc_head
!= NULL
) {
581 f_print(fout
, "\n/* the xdr functions */\n");
584 f_print(fout
, "\n#ifdef __cplusplus\n");
585 f_print(fout
, "extern \"C\" {\n");
586 f_print(fout
, "#endif\n");
590 xdrfuncp
= xdrfunc_head
;
591 while (xdrfuncp
!= NULL
) {
592 print_xdr_func_def(xdrfuncp
->name
,
593 xdrfuncp
->pointerp
, 2);
594 xdrfuncp
= xdrfuncp
->next
;
597 for (i
= 1; i
< 3; i
++) {
600 "\n#if defined(__STDC__) || defined(__cplusplus)\n");
602 f_print(fout
, "\n#else /* K&R C */\n");
604 xdrfuncp
= xdrfunc_head
;
605 while (xdrfuncp
!= NULL
) {
606 print_xdr_func_def(xdrfuncp
->name
,
607 xdrfuncp
->pointerp
, i
);
608 xdrfuncp
= xdrfuncp
->next
;
611 f_print(fout
, "\n#endif /* K&R C */\n");
615 if (extend
&& tell
== ftell(fout
)) {
616 (void) unlink(outfilename
);
620 f_print(fout
, "\n#ifdef __cplusplus\n");
621 f_print(fout
, "}\n");
622 f_print(fout
, "#endif\n");
625 f_print(fout
, "\n#endif /* !_%s */\n", guard
);
629 * Compile into an RPC service
632 s_output(int argc
, char *argv
[], char *infile
, char *define
, int extend
,
633 char *outfile
, int nomain
, int netflag
)
637 int foundprogram
= 0;
640 open_input(infile
, define
);
641 outfilename
= extend
? extendfile(infile
, outfile
) : outfile
;
642 open_output(infile
, outfilename
);
644 if (infile
&& (include
= extendfile(infile
, ".h"))) {
645 f_print(fout
, "#include \"%s\"\n", include
);
648 f_print(fout
, "#include <rpc/rpc.h>\n");
650 f_print(fout
, "#include <stdio.h>\n");
651 f_print(fout
, "#include <stdlib.h> /* getenv, exit */\n");
652 f_print(fout
, "#include <signal.h>\n");
656 "#include <rpc/pmap_clnt.h> /* for pmap_unset */\n");
657 f_print(fout
, "#include <string.h> /* strcmp */\n");
659 if (strcmp(svcclosetime
, "-1") == 0)
661 else if (strcmp(svcclosetime
, "0") == 0)
663 else if (inetdflag
|| pmflag
)
666 if (!tirpcflag
&& inetdflag
)
667 f_print(fout
, "#include <sys/termios.h> /* TIOCNOTTY */\n");
668 if (Cflag
&& (inetdflag
|| pmflag
))
670 f_print(fout
, "#include <unistd.h> /* setsid */\n");
672 f_print(fout
, "#include <sys/types.h>\n");
674 f_print(fout
, "#include <memory.h>\n");
675 f_print(fout
, "#include <stropts.h>\n");
676 if (inetdflag
|| !tirpcflag
) {
677 f_print(fout
, "#include <sys/socket.h>\n");
678 f_print(fout
, "#include <netinet/in.h>\n");
679 f_print(fout
, "#include <rpc/svc_soc.h>\n");
682 if ((netflag
|| pmflag
) && tirpcflag
&& !nomain
)
683 f_print(fout
, "#include <netconfig.h>\n");
685 f_print(fout
, "#include <sys/resource.h> /* rlimit */\n");
686 if (logflag
|| inetdflag
|| pmflag
)
687 f_print(fout
, "#include <syslog.h>\n");
692 "\n#ifndef SIG_PF\n#define SIG_PF void(*)\
695 f_print(fout
, "\n#ifdef DEBUG\n#define RPC_SVC_FG\n#endif\n");
697 f_print(fout
, "\n#define _RPCSVC_CLOSEDOWN %s\n",
699 while (def
= get_definition())
700 foundprogram
|= (def
->def_kind
== DEF_PROGRAM
);
701 if (extend
&& !foundprogram
) {
702 (void) unlink(outfilename
);
705 write_most(infile
, netflag
, nomain
);
707 if (!do_registers(argc
, argv
)) {
709 (void) unlink(outfilename
);
717 * generate client side stubs
720 l_output(char *infile
, char *define
, int extend
, char *outfile
)
724 int foundprogram
= 0;
727 open_input(infile
, define
);
728 outfilename
= extend
? extendfile(infile
, outfile
) : outfile
;
729 open_output(infile
, outfilename
);
732 f_print(fout
, "#include <memory.h> /* for memset */\n");
733 if (infile
&& (include
= extendfile(infile
, ".h"))) {
734 f_print(fout
, "#include \"%s\"\n", include
);
737 f_print(fout
, "#include <rpc/rpc.h>\n");
739 f_print(fout
, "#ifndef _KERNEL\n");
740 f_print(fout
, "#include <stdio.h>\n");
741 f_print(fout
, "#include <stdlib.h> /* getenv, exit */\n");
742 f_print(fout
, "#endif /* !_KERNEL */\n");
744 while (def
= get_definition())
745 foundprogram
|= (def
->def_kind
== DEF_PROGRAM
);
746 if (extend
&& !foundprogram
) {
747 (void) unlink(outfilename
);
754 * generate the dispatch table
757 t_output(char *infile
, char *define
, int extend
, char *outfile
)
760 int foundprogram
= 0;
763 open_input(infile
, define
);
764 outfilename
= extend
? extendfile(infile
, outfile
) : outfile
;
765 open_output(infile
, outfilename
);
767 while (def
= get_definition()) {
768 foundprogram
|= (def
->def_kind
== DEF_PROGRAM
);
770 if (extend
&& !foundprogram
) {
771 (void) unlink(outfilename
);
777 /* sample routine for the server template */
779 svc_output(char *infile
, char *define
, int extend
, char *outfile
)
785 open_input(infile
, define
);
786 outfilename
= extend
? extendfile(infile
, outfile
) : outfile
;
787 checkfiles(infile
, outfilename
);
789 * Check if outfile already exists.
790 * if so, print an error message and exit
792 open_output(infile
, outfilename
);
795 if (infile
&& (include
= extendfile(infile
, ".h"))) {
796 f_print(fout
, "#include \"%s\"\n", include
);
799 f_print(fout
, "#include <rpc/rpc.h>\n");
802 f_print(fout
, "#include <stdio.h>\n");
803 f_print(fout
, "#include <stdlib.h> /* getenv, exit */\n");
804 f_print(fout
, "#include <signal.h>\n");
807 while (def
= get_definition())
808 write_sample_svc(def
);
809 if (extend
&& tell
== ftell(fout
))
810 (void) unlink(outfilename
);
813 /* sample main routine for client */
815 clnt_output(char *infile
, char *define
, int extend
, char *outfile
)
823 open_input(infile
, define
);
824 outfilename
= extend
? extendfile(infile
, outfile
) : outfile
;
825 checkfiles(infile
, outfilename
);
827 * Check if outfile already exists.
828 * if so, print an error message and exit
831 open_output(infile
, outfilename
);
833 if (infile
&& (include
= extendfile(infile
, ".h"))) {
834 f_print(fout
, "#include \"%s\"\n", include
);
837 f_print(fout
, "#include <rpc/rpc.h>\n");
839 f_print(fout
, "#include <stdio.h>\n");
840 f_print(fout
, "#include <stdlib.h> /* getenv, exit */\n");
843 while (def
= get_definition())
844 has_program
+= write_sample_clnt(def
);
847 write_sample_clnt_main();
849 if (extend
&& tell
== ftell(fout
))
850 (void) unlink(outfilename
);
855 mkfile_output(struct commandline
*cmd
)
857 char *mkfilename
, *clientname
, *clntname
, *xdrname
, *hdrname
;
858 char *servername
, *svcname
, *servprogname
, *clntprogname
;
861 svcname
= file_name(cmd
->infile
, "_svc.c");
862 clntname
= file_name(cmd
->infile
, "_clnt.c");
863 xdrname
= file_name(cmd
->infile
, "_xdr.c");
864 hdrname
= file_name(cmd
->infile
, ".h");
868 servername
= extendfile(cmd
->infile
, "_server.c");
869 clientname
= extendfile(cmd
->infile
, "_client.c");
874 servprogname
= extendfile(cmd
->infile
, "_server");
875 clntprogname
= extendfile(cmd
->infile
, "_client");
878 mkfilename
= malloc(strlen("makefile.") +
879 strlen(cmd
->infile
) + 1);
880 if (mkfilename
== NULL
) {
881 f_print(stderr
, "Out of memory!\n");
884 temp
= (char *)rindex(cmd
->infile
, '.');
885 (void) strcpy(mkfilename
, "makefile.");
886 (void) strncat(mkfilename
, cmd
->infile
,
887 (temp
- cmd
->infile
));
889 mkfilename
= cmd
->outfile
;
892 checkfiles(NULL
, mkfilename
);
893 open_output(NULL
, mkfilename
);
895 f_print(fout
, "\n# This is a template makefile generated\
898 f_print(fout
, "\n# Parameters \n\n");
900 f_print(fout
, "CLIENT = %s\nSERVER = %s\n\n",
901 clntprogname
, servprogname
);
902 f_print(fout
, "SOURCES_CLNT.c = \nSOURCES_CLNT.h = \n");
903 f_print(fout
, "SOURCES_SVC.c = \nSOURCES_SVC.h = \n");
904 f_print(fout
, "SOURCES.x = %s\n\n", cmd
->infile
);
905 f_print(fout
, "TARGETS_SVC.c = %s %s %s \n",
906 svcname
, servername
, xdrname
);
907 f_print(fout
, "TARGETS_CLNT.c = %s %s %s \n",
908 clntname
, clientname
, xdrname
);
909 f_print(fout
, "TARGETS = %s %s %s %s %s %s\n\n",
910 hdrname
, xdrname
, clntname
,
911 svcname
, clientname
, servername
);
913 f_print(fout
, "OBJECTS_CLNT = $(SOURCES_CLNT.c:%%.c=%%.o) "
914 "$(TARGETS_CLNT.c:%%.c=%%.o) ");
916 f_print(fout
, "\nOBJECTS_SVC = $(SOURCES_SVC.c:%%.c=%%.o) "
917 "$(TARGETS_SVC.c:%%.c=%%.o) ");
920 f_print(fout
, "\n# Compiler flags \n");
921 f_print(fout
, "\nCFLAGS += -g \n");
922 f_print(fout
, "RPCGENFLAGS = \n");
924 f_print(fout
, "\n# Targets \n\n");
926 f_print(fout
, "all : $(CLIENT) $(SERVER)\n\n");
927 f_print(fout
, "$(TARGETS) : $(SOURCES.x) \n");
928 f_print(fout
, "\trpcgen $(RPCGENFLAGS) $(SOURCES.x)\n\n");
929 f_print(fout
, "$(OBJECTS_CLNT) : $(SOURCES_CLNT.c) $(SOURCES_CLNT.h) \
930 $(TARGETS_CLNT.c) \n\n");
932 f_print(fout
, "$(OBJECTS_SVC) : $(SOURCES_SVC.c) $(SOURCES_SVC.h) \
933 $(TARGETS_SVC.c) \n\n");
934 f_print(fout
, "$(CLIENT) : $(OBJECTS_CLNT) \n");
935 f_print(fout
, "\t$(LINK.c) -o $(CLIENT) $(OBJECTS_CLNT) \
937 f_print(fout
, "$(SERVER) : $(OBJECTS_SVC) \n");
938 f_print(fout
, "\t$(LINK.c) -o $(SERVER) $(OBJECTS_SVC) $(LDLIBS)\n\n ");
939 f_print(fout
, "clean:\n\t $(RM) core $(TARGETS) $(OBJECTS_CLNT) \
940 $(OBJECTS_SVC) $(CLIENT) $(SERVER)\n\n");
945 * Perform registrations for service output
946 * Return 0 if failed; 1 otherwise.
949 do_registers(int argc
, char *argv
[])
953 if (inetdflag
|| !tirpcflag
) {
954 for (i
= 1; i
< argc
; i
++) {
955 if (streq(argv
[i
], "-s")) {
956 if (!check_nettype(argv
[i
+ 1],
959 write_inetd_register(argv
[i
+ 1]);
964 for (i
= 1; i
< argc
; i
++)
965 if (streq(argv
[i
], "-s")) {
966 if (!check_nettype(argv
[i
+ 1],
969 write_nettype_register(argv
[i
+ 1]);
971 } else if (streq(argv
[i
], "-n")) {
972 write_netid_register(argv
[i
+ 1]);
980 * Add another argument to the arg list
985 if (argcount
>= ARGLISTLEN
) {
986 f_print(stderr
, "rpcgen: too many defines\n");
990 arglist
[argcount
++] = cp
;
994 putarg(int where
, char *cp
)
996 if (where
>= ARGLISTLEN
) {
997 f_print(stderr
, "rpcgen: arglist coding error\n");
1001 arglist
[where
] = cp
;
1005 * if input file is stdin and an output file is specified then complain
1006 * if the file already exists. Otherwise the file may get overwritten
1007 * If input file does not exist, exit with an error
1010 checkfiles(char *infile
, char *outfile
)
1014 if (infile
) { /* infile ! = NULL */
1015 if (stat(infile
, &buf
) < 0) {
1021 if (stat(outfile
, &buf
) < 0)
1022 return; /* file does not exist */
1024 "file '%s' already exists and may be overwritten\n",
1031 * Parse command line arguments
1034 parseargs(int argc
, char *argv
[], struct commandline
*cmd
)
1039 char flag
[(1 << 8 * sizeof (char))];
1043 cmd
->infile
= cmd
->outfile
= NULL
;
1059 for (i
= 1; i
< argc
; i
++) {
1060 if (argv
[i
][0] != '-') {
1063 "Cannot specify more than one input file.\n");
1067 cmd
->infile
= argv
[i
];
1069 for (j
= 1; argv
[i
][j
] != 0; j
++) {
1086 * sample flag: Ss or Sc.
1087 * Ss means set flag['S'];
1088 * Sc means set flag['C'];
1089 * Sm means set flag['M'];
1091 ch
= argv
[i
][++j
]; /* get next char */
1105 case 'C': /* ANSI C syntax */
1107 ch
= argv
[i
][j
+1]; /* get next char */
1115 * Turn TIRPC flag off for
1116 * generating backward compatible
1134 svcclosetime
= argv
[i
];
1148 inlinelen
= atoi(argv
[i
]);
1153 if (argv
[i
][j
- 1] != '-' ||
1154 argv
[i
][j
+ 1] != 0)
1162 cmd
->outfile
= argv
[i
];
1166 if (argv
[i
][j
- 1] != '-')
1168 (void) addarg(argv
[i
]);
1176 (void) strcpy(pathbuf
, argv
[i
]);
1177 (void) strcat(pathbuf
, "/cpp");
1193 cmd
->cflag
= flag
['c'];
1194 cmd
->hflag
= flag
['h'];
1195 cmd
->lflag
= flag
['l'];
1196 cmd
->mflag
= flag
['m'];
1197 cmd
->nflag
= flag
['n'];
1198 cmd
->sflag
= flag
['s'];
1199 cmd
->tflag
= flag
['t'];
1200 cmd
->Ssflag
= flag
['S'];
1201 cmd
->Scflag
= flag
['C'];
1202 cmd
->makefileflag
= flag
['M'];
1207 "Cannot use -I flag without -b flag.\n");
1211 } else { /* 4.1 mode */
1212 pmflag
= 0; /* set pmflag only in tirpcmode */
1213 inetdflag
= 1; /* inetdflag is TRUE by default */
1214 if (cmd
->nflag
) { /* netid needs TIRPC */
1216 "Cannot use netid flag without TIRPC.\n");
1221 if (newstyle
&& (tblflag
|| cmd
->tflag
)) {
1222 f_print(stderr
, "Cannot use table flags with newstyle.\n");
1226 /* check no conflicts with file generation flags */
1227 nflags
= cmd
->cflag
+ cmd
->hflag
+ cmd
->lflag
+ cmd
->mflag
+
1228 cmd
->sflag
+ cmd
->nflag
+ cmd
->tflag
+ cmd
->Ssflag
+
1229 cmd
->Scflag
+ cmd
->makefileflag
;
1232 if (cmd
->outfile
!= NULL
|| cmd
->infile
== NULL
)
1234 } else if (cmd
->infile
== NULL
&&
1235 (cmd
->Ssflag
|| cmd
->Scflag
|| cmd
->makefileflag
)) {
1236 f_print(stderr
, "\"infile\" is required for template"
1237 " generation flags.\n");
1242 "Cannot have more than one file generation flag.\n");
1251 f_print(stderr
, "%s (%d.%d)\n", cmdname
, RPCGEN_MAJOR
, RPCGEN_MINOR
);
1252 f_print(stderr
, "usage: %s infile\n", cmdname
);
1253 f_print(stderr
, "\t%s [-abCLNTMA] [-Dname[=value]] [-i size]"
1254 " [-I [-K seconds]] [-Y path] infile\n", cmdname
);
1255 f_print(stderr
, "\t%s [-c | -h | -l | -m | -t | -Sc | -Ss | -Sm]"
1256 " [-o outfile] [infile]\n", cmdname
);
1257 f_print(stderr
, "\t%s [-s nettype]* [-o outfile] [infile]\n", cmdname
);
1258 f_print(stderr
, "\t%s [-n netid]* [-o outfile] [infile]\n", cmdname
);
1266 f_print(stderr
, "%s %d.%d\n", cmdname
, RPCGEN_MAJOR
, RPCGEN_MINOR
);
1274 f_print(stderr
, "options:\n");
1275 f_print(stderr
, "-a\t\tgenerate all files, including samples\n");
1276 f_print(stderr
, "-A\t\tgenerate code to enable automatic MT mode\n");
1277 f_print(stderr
, "-b\t\tbackward compatibility mode (generates code"
1278 " for SunOS 4.X)\n");
1279 f_print(stderr
, "-c\t\tgenerate XDR routines\n");
1280 f_print(stderr
, "-C\t\tANSI C mode\n");
1281 f_print(stderr
, "-Dname[=value]\tdefine a symbol (same as #define)\n");
1282 f_print(stderr
, "-h\t\tgenerate header file\n");
1283 f_print(stderr
, "-i size\t\tsize at which to start generating"
1285 f_print(stderr
, "-I\t\tgenerate code for inetd support in server"
1286 " (for SunOS 4.X)\n");
1287 f_print(stderr
, "-K seconds\tserver exits after K seconds of"
1289 f_print(stderr
, "-l\t\tgenerate client side stubs\n");
1290 f_print(stderr
, "-L\t\tserver errors will be printed to syslog\n");
1291 f_print(stderr
, "-m\t\tgenerate server side stubs\n");
1292 f_print(stderr
, "-M\t\tgenerate MT-safe code\n");
1293 f_print(stderr
, "-n netid\tgenerate server code that supports"
1295 f_print(stderr
, "-N\t\tsupports multiple arguments and"
1296 " call-by-value\n");
1297 f_print(stderr
, "-o outfile\tname of the output file\n");
1298 f_print(stderr
, "-s nettype\tgenerate server code that supports named"
1300 f_print(stderr
, "-Sc\t\tgenerate sample client code that uses remote"
1302 f_print(stderr
, "-Ss\t\tgenerate sample server code that defines"
1303 " remote procedures\n");
1304 f_print(stderr
, "-Sm \t\tgenerate makefile template \n");
1306 f_print(stderr
, "-t\t\tgenerate RPC dispatch table\n");
1307 f_print(stderr
, "-T\t\tgenerate code to support RPC dispatch tables\n");
1308 f_print(stderr
, "-v\t\tprint version information and exit\n");
1309 f_print(stderr
, "-Y path\t\tpath where cpp is found\n");