diff options
author | Ulrich Drepper <drepper@redhat.com> | 1996-10-17 01:51:38 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 1996-10-17 01:51:38 +0000 |
commit | 0d204b0a522b9fef2168e1808a0566c9209d0893 (patch) | |
tree | 70ea6e1aec8f2cc5ab9b53f4ef15f24a9503fd5a /sunrpc/rpc_main.c | |
parent | b207ff4bd88564215ef7c68e61ec46aa4cb461c1 (diff) | |
download | glibc-0d204b0a522b9fef2168e1808a0566c9209d0893.zip glibc-0d204b0a522b9fef2168e1808a0566c9209d0893.tar.gz glibc-0d204b0a522b9fef2168e1808a0566c9209d0893.tar.bz2 |
update from main archive 961016cvs/libc-961019cvs/libc-961018cvs/libc-961017
Thu Oct 17 01:55:34 1996 Ulrich Drepper <drepper@cygnus.com>
* sunrpc/Makefile ($(objpfx)rpcsvc/%.h, $(objpfx)x%.c): Write
output to $@T and move to $@ later since the new rpcgen will not
overwrite existing files.
* po/Makefile (libc.pot): Fix typo.
Sun Oct 13 20:52:07 1996 Thorsten Kukuk <kukuk@weber.uni-paderborn.de>
Update rpcgen program to TI-rpc code.
* sunrpc/Makefile (rpcgen-objs): Add rpc_tblout.o and rpc_sample.o.
(distribute): Add proto.h.
* sunrpc/proto.h: New file. Prototypes for all the RPC functions.
* sunrpc/rpc_clntout.c: Change to allow generation of ISO C code.
* sunrpc/rpc_cout.c: Likewise.
* sunrpc/rpc_hout.c: Likewise.
* sunrpc/rpc_main.c: Likewise.
* sunrpc/rpc_parse.c: Likewise.
* sunrpc/rpc_parse.h: Likewise.
* sunrpc/rpc_scan.c: Likewise.
* sunrpc/rpc_scan.h: Likewise.
* sunrpc/rpc_svcout.c: Likewise.
* sunrpc/rpc_util.c: Likewise.
* sunrpc/rpc_util.h: Likewise.
* sunrpc/rpc_tblout.c: New file.
* sunrpc/rpc_sample.c: Likewise.
Thu Oct 17 00:26:20 1996 NIIBE Yutaka <gniibe@mri.co.jp>
* sysdeps/unix/opendir.c: Add semicolon for consistency.
Wed Oct 16 12:26:53 1996 Sven Verdoolaege <skimo@breughel.ufsia.ac.be>
* locale/progams/localedef.c (main): Test with -1 to find out
whether read failed.
Wed Oct 16 14:54:59 1996 Ulrich Drepper <drepper@cygnus.com>
* sysdeps/unix/sysv/linux/i386/clone.S: Use JUMPTARGET and
PSEUDO_END macro.
Tue Oct 15 21:27:42 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* sysdeps/unix/sysv/linux/m68k/sigcontext.h: Removed.
Tue Oct 15 15:52:29 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* sysdeps/unix/sysv/linux/m68k/clone.S: Add CALL_MCOUNT.
* sysdeps/unix/sysv/linux/m68k/mmap.S: Likewise.
* sysdeps/unix/sysv/linux/m68k/sigreturn.S: Likewise.
* sysdeps/unix/sysv/linux/m68k/socket.S: Likewise.
* sysdeps/unix/sysv/linux/m68k/sysdep.S (__errno_location):
Likewise.
* sysdeps/unix/sysv/linux/m68k/syscall.S: Likewise.
Correct generation of system call.
Tue Oct 15 15:13:16 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* Makerules (sysd-Makefile): Fix command so that it works in the
subdirectories.
(BUILD_CFLAGS): Change back using $(..) instead of
$(common-objpfx), the latter fails in the toplevel directory when
$(objdir) is relative.
(common-objdir-compile): Run compiler in $(objdir).
* sysdeps/posix/Makefile (mk-stdiolim): Likewise.
Tue Oct 15 23:39:48 1996 Ulrich Drepper <drepper@cygnus.com>
* string/string.h [__USE_SVID]: Add prototype for swab.
* time/sys/time.h [__USE_BSD]: Add prototype for ualarm.
Reported by Andreas Jaeger.
The available nlist implementation is not generally usable.
Especially on the currently supported ELF systems the nlist
function comes with the libelf.
* misc/Makefile (headers): Remove nlist.h.
(routines): Remove nlist.
* Makefile ($(objpfx)version-info.h): Include information about
system the libc is built on in version-info.h file.
* po/Makefile (distribute): Add header.pot.
Tue Oct 15 16:34:15 1996 Andreas Jaeger <aj@arthur.pfalz.de>
* sysdeps/unix/sysv/linux/sleep.c: Include file with prototype.
* sysdeps/unix/sysv/linux/reboot.c: Likewise.
* misc/error.c: Likewise.
Tue Oct 15 22:41:27 1996 Ulrich Drepper <drepper@cygnus.com>
* sysdeps/unix/sysv/linux/syscalls.list: Add {get,set}resuid.
Tue Oct 15 08:06:02 1996 Andreas Jaeger <aj@arthur.pfalz.de>
* crypt/Makefiel (rpath-link): Extend search path to current directory.
Fri Oct 11 09:18:06 1996 Sven Verdoolaege <skimo@breughel.ufsia.ac.be>
* sysdeps/i386/i586/strlen.S: Correct handling of prolog for
aligning pointer.
Tue Oct 15 02:13:21 1996 Ulrich Drepper <drepper@cygnus.com>
* stdio-common/vfprintf.c: Don't declare __flockfile as weak.
* crypt/md5-crypt.c (md5_crypt_r): Add cast to prevent warning.
Sun Oct 13 19:16:10 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* sysdeps/unix/sysv/linux/m68k/sysdep.h (POUND): Macro removed,
replaced by `&'.
(PSEUDO_END): Provide definition to use .size directive.
(PSEUDO): Don't interpret negative return values less than -128 as
syscall error.
* sysdeps/unix/sysv/linux/m68k/syscall.S (syscall): Likewise.
* sysdeps/m68k/bsd-_setjmp.S: Use PSEUDO_END macro to provide
.size directive.
* sysdeps/m68k/bsd-setjmp.S: Likewise.
* sysdeps/unix/sysv/linux/m68k/clone.S: Likewise.
* sysdeps/unix/sysv/linux/m68k/mmap.S: Likewise.
* sysdeps/unix/sysv/linux/m68k/sigreturn.S: Likewise.
* sysdeps/unix/sysv/linux/m68k/socket.S: Likewise.
* sysdeps/unix/sysv/linux/m68k/syscall.S: Likewise.
* sysdeps/unix/sysv/linux/m68k/sysdep.S: Use PSEUDO_END instead of
explicit .size directive.
* libio/iogets.c: Warn when gets is used.
cd * time/strptime.c: Recognize %s, %u, %g, and %G format.
Diffstat (limited to 'sunrpc/rpc_main.c')
-rw-r--r-- | sunrpc/rpc_main.c | 930 |
1 files changed, 800 insertions, 130 deletions
diff --git a/sunrpc/rpc_main.c b/sunrpc/rpc_main.c index 053b301..c6fbad1 100644 --- a/sunrpc/rpc_main.c +++ b/sunrpc/rpc_main.c @@ -1,11 +1,11 @@ -/* @(#)rpc_main.c 2.2 88/08/01 4.0 RPCSRC */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. Users * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or - * program developed by the user. + * program developed by the user or with the express written consent of + * Sun Microsystems, Inc. * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR @@ -27,101 +27,223 @@ * 2550 Garcia Avenue * Mountain View, California 94043 */ -#ifndef lint -static char sccsid[] = "@(#)rpc_main.c 1.7 87/06/24 (C) 1987 SMI"; -#endif + +/* + * From @(#)rpc_main.c 1.30 89/03/30 (C) 1987 SMI; + */ +char main_rcsid[] = + "$Id$"; /* * rpc_main.c, Top level of the RPC protocol compiler. - * Copyright (C) 1987, Sun Microsystems, Inc. */ #include <stdio.h> -#include <strings.h> +#include <string.h> +#include <unistd.h> +#include <ctype.h> +#include <sys/types.h> +#include <sys/param.h> #include <sys/file.h> -#include "rpc_util.h" +#include <sys/stat.h> #include "rpc_parse.h" +#include "rpc_util.h" #include "rpc_scan.h" +#include "proto.h" + #define EXTEND 1 /* alias for TRUE */ +#define DONT_EXTEND 0 /* alias for FALSE */ + +#define SVR4_CPP "/usr/ccs/lib/cpp" +#define SUNOS_CPP "/lib/cpp" +static int cppDefined = 0; /* explicit path for C preprocessor */ struct commandline { - int cflag; - int hflag; - int lflag; - int sflag; - int mflag; - char *infile; - char *outfile; + int cflag; /* xdr C routines */ + int hflag; /* header file */ + int lflag; /* client side stubs */ + int mflag; /* server side stubs */ + int nflag; /* netid flag */ + int sflag; /* server stubs for the given transport */ + int tflag; /* dispatch Table file */ + int Ssflag; /* produce server sample code */ + int Scflag; /* produce client sample code */ + const char *infile; /* input module name */ + const char *outfile; /* output module name */ }; -static char *cmdname; -static char CPP[] = "/lib/cpp"; + +static const char *cmdname; + +static const char *svcclosetime = "120"; +static const char *CPP = SVR4_CPP; static char CPPFLAGS[] = "-C"; -static char *allv[] = { +static char pathbuf[MAXPATHLEN + 1]; +static const char *allv[] = { "rpcgen", "-s", "udp", "-s", "tcp", }; static int allc = sizeof(allv)/sizeof(allv[0]); +static const char *allnv[] = { + "rpcgen", "-s", "netpath", +}; +static int allnc = sizeof(allnv)/sizeof(allnv[0]); + +/* + * machinations for handling expanding argument list + */ +static void addarg(const char *); /* add another argument to the list */ +static void putarg(int, const char *); /* put argument at specified location */ +static void clear_args(void); /* clear argument list */ +static void checkfiles(const char *, const char *); + /* check if out file already exists */ + +static void clear_args(void); +static char *extendfile(const char *file, const char *ext); +static void open_output(const char *infile, const char *outfile); +static void add_warning(void); +static void clear_args(void); +static void find_cpp(void); +static void open_input(const char *infile, const char *define); +static int check_nettype(const char *name, const char *list_to_check[]); +static void c_output(const char *infile, const char *define, + int extend, const char *outfile); +static void h_output(const char *infile, const char *define, + int extend, const char *outfile); +static void s_output(int argc, const char *argv[], const char *infile, + const char *define, int extend, + const char *outfile, int nomain, int netflag); +static void l_output(const char *infile, const char *define, + int extend, const char *outfile); +static void t_output(const char *infile, const char *define, + int extend, const char *outfile); +static void svc_output(const char *infile, const char *define, + int extend, const char *outfile); +static void clnt_output(const char *infile, const char *define, + int extend, const char *outfile); +static int do_registers(int argc, const char *argv[]); +static void addarg(const char *cp); +static void putarg(int whereto, const char *cp); +static void checkfiles(const char *infile, const char *outfile); +static int parseargs(int argc, const char *argv[], struct commandline *cmd); +static void usage(void); +static void options_usage(void); +static void c_initialize(void); +static char *generate_guard(const char *pathname); + + +#define ARGLISTLEN 20 +#define FIXEDARGS 2 + +static const char *arglist[ARGLISTLEN]; +static int argcount = FIXEDARGS; + + +int nonfatalerrors; /* errors */ +int inetdflag/* = 1*/; /* Support for inetd */ /* is now the default */ +int pmflag; /* Support for port monitors */ +int logflag; /* Use syslog instead of fprintf for errors */ +int tblflag; /* Support for dispatch table file */ -main(argc, argv) - int argc; - char *argv[]; +#define INLINE 3 +/*length at which to start doing an inline */ +int inlineflag=INLINE; /* length at which to start doing an inline. 3 = default + if 0, no xdr_inline code */ + +int indefinitewait; /* If started by port monitors, hang till it wants */ +int exitnow; /* If started by port monitors, exit after the call */ +int timerflag; /* TRUE if !indefinite && !exitnow */ +int newstyle; /* newstyle of passing arguments (by value) */ +#ifdef __GNU_LIBRARY__ +int Cflag = 1 ; /* ANSI C syntax */ +#else +int Cflag = 0 ; /* ANSI C syntax */ +#endif +static int allfiles; /* generate all files */ +#ifdef __GNU_LIBRARY__ +int tirpcflag = 0; /* generating code for tirpc, by default */ +#else +int tirpcflag = 1; /* generating code for tirpc, by default */ +#endif + +int +main(int argc, const char *argv[]) { struct commandline cmd; - /* Use the libc message catalog for translations. */ - textdomain (_libc_intl_domainname); + (void) memset((char *)&cmd, 0, sizeof (struct commandline)); + clear_args(); + if (!parseargs(argc, argv, &cmd)) + usage(); - if (!parseargs(argc, argv, &cmd)) { - f_print(stderr, - _("usage: %s infile\n"), cmdname); - f_print(stderr, - _(" %s [-c | -h | -l | -m] [-o outfile] [infile]\n"), - cmdname); - f_print(stderr, - _(" %s [-s udp|tcp]* [-o outfile] [infile]\n"), - cmdname); - exit(1); + if (cmd.cflag || cmd.hflag || cmd.lflag || cmd.tflag || cmd.sflag || + cmd.mflag || cmd.nflag || cmd.Ssflag || cmd.Scflag ) { + checkfiles(cmd.infile, cmd.outfile); } + else + checkfiles(cmd.infile,NULL); + if (cmd.cflag) { - c_output(cmd.infile, "-DRPC_XDR", !EXTEND, cmd.outfile); + c_output(cmd.infile, "-DRPC_XDR", DONT_EXTEND, cmd.outfile); } else if (cmd.hflag) { - h_output(cmd.infile, "-DRPC_HDR", !EXTEND, cmd.outfile); + h_output(cmd.infile, "-DRPC_HDR", DONT_EXTEND, cmd.outfile); } else if (cmd.lflag) { - l_output(cmd.infile, "-DRPC_CLNT", !EXTEND, cmd.outfile); - } else if (cmd.sflag || cmd.mflag) { - s_output(argc, argv, cmd.infile, "-DRPC_SVC", !EXTEND, - cmd.outfile, cmd.mflag); + l_output(cmd.infile, "-DRPC_CLNT", DONT_EXTEND, cmd.outfile); + } else if (cmd.sflag || cmd.mflag || (cmd.nflag)) { + s_output(argc, argv, cmd.infile, "-DRPC_SVC", DONT_EXTEND, + cmd.outfile, cmd.mflag, cmd.nflag); + } else if (cmd.tflag) { + t_output(cmd.infile, "-DRPC_TBL", DONT_EXTEND, cmd.outfile); + } else if (cmd.Ssflag) { + svc_output(cmd.infile, "-DRPC_SERVER", DONT_EXTEND, cmd.outfile); + } else if (cmd.Scflag) { + clnt_output(cmd.infile, "-DRPC_CLIENT", DONT_EXTEND, cmd.outfile); } else { + /* the rescans are required, since cpp may effect input */ c_output(cmd.infile, "-DRPC_XDR", EXTEND, "_xdr.c"); reinitialize(); h_output(cmd.infile, "-DRPC_HDR", EXTEND, ".h"); reinitialize(); l_output(cmd.infile, "-DRPC_CLNT", EXTEND, "_clnt.c"); reinitialize(); - s_output(allc, allv, cmd.infile, "-DRPC_SVC", EXTEND, - "_svc.c", cmd.mflag); + if (inetdflag || !tirpcflag ) + s_output(allc, allv, cmd.infile, "-DRPC_SVC", EXTEND, + "_svc.c", cmd.mflag, cmd.nflag); + else + s_output(allnc, allnv, cmd.infile, "-DRPC_SVC", + EXTEND, "_svc.c", cmd.mflag, cmd.nflag); + if (tblflag) { + reinitialize(); + t_output(cmd.infile, "-DRPC_TBL", EXTEND, "_tbl.i"); + } + if (allfiles) { + reinitialize(); + svc_output(cmd.infile, "-DRPC_SERVER", EXTEND, "_server.c"); + } + if (allfiles) { + reinitialize(); + clnt_output(cmd.infile, "-DRPC_CLIENT", EXTEND, "_client.c"); + } } - exit(0); + exit(nonfatalerrors); + /* NOTREACHED */ } /* * add extension to filename */ static char * -extendfile(file, ext) - char *file; - char *ext; +extendfile(const char *file, const char *ext) { char *res; - char *p; + const char *p; res = alloc(strlen(file) + strlen(ext) + 1); if (res == NULL) { abort(); } - p = rindex(file, '.'); + p = strrchr(file, '.'); if (p == NULL) { p = file + strlen(file); } @@ -133,36 +255,78 @@ extendfile(file, ext) /* * Open output file with given extension */ -static -open_output(infile, outfile) - char *infile; - char *outfile; +static void +open_output(const char *infile, const char *outfile) { + if (outfile == NULL) { fout = stdout; return; } + if (infile != NULL && streq(outfile, infile)) { - f_print(stderr, _("%s: output would overwrite %s\n"), cmdname, + f_print(stderr, "%s: output would overwrite %s\n", cmdname, infile); crash(); } fout = fopen(outfile, "w"); if (fout == NULL) { - f_print(stderr, _("%s: unable to open "), cmdname); + f_print(stderr, "%s: unable to open ", cmdname); perror(outfile); crash(); } record_open(outfile); } +static void +add_warning(void) +{ + f_print(fout, "/*\n"); + f_print(fout, " * Please do not edit this file.\n"); + f_print(fout, " * It was generated using rpcgen.\n"); + f_print(fout, " */\n\n"); +} + +static void +add_stdheaders(void) +{ + f_print(fout, "#include <rpc/types.h>\n"); + f_print(fout, "#include <rpc/xdr.h>\n\n"); +} + +/* clear list of arguments */ +static void clear_args(void) +{ + int i; + for( i=FIXEDARGS; i<ARGLISTLEN; i++ ) + arglist[i] = NULL; + argcount = FIXEDARGS; +} + +/* make sure that a CPP exists */ +static void find_cpp(void) +{ + struct stat buf; + + if (stat(CPP, &buf) < 0 ) { /* SVR4 or explicit cpp does not exist */ + if (cppDefined) { + fprintf( stderr, "cannot find C preprocessor: %s \n", CPP ); + crash(); + } else { /* try the other one */ + CPP = SUNOS_CPP; + if( stat( CPP, &buf ) < 0 ) { /* can't find any cpp */ + fprintf( stderr, "cannot find any C preprocessor (cpp)\n" ); + crash(); + } + } + } +} + /* * Open input file with given define for C-preprocessor */ -static -open_input(infile, define) - char *infile; - char *define; +static void +open_input(const char *infile, const char *define) { int pd[2]; @@ -170,11 +334,17 @@ open_input(infile, define) (void) pipe(pd); switch (fork()) { case 0: + find_cpp(); + putarg(0, CPP); + putarg(1, CPPFLAGS); + addarg(define); + addarg(infile); + addarg((char *)NULL); (void) close(1); (void) dup2(pd[1], 1); (void) close(pd[0]); - execl(CPP, CPP, CPPFLAGS, define, infile, NULL); - perror("execl"); + execv(arglist[0], (char **)arglist); + perror("execv"); exit(1); case -1: perror("fork"); @@ -189,31 +359,67 @@ open_input(infile, define) } } +/* valid tirpc nettypes */ +static const char *valid_ti_nettypes[] = +{ + "netpath", + "visible", + "circuit_v", + "datagram_v", + "circuit_n", + "datagram_n", + "udp", + "tcp", + "raw", + NULL + }; + +/* valid inetd nettypes */ +static const char *valid_i_nettypes[] = +{ + "udp", + "tcp", + NULL +}; + +static int check_nettype(const char *name, const char *list_to_check[]) { + int i; + for( i = 0; list_to_check[i] != NULL; i++ ) { + if( strcmp( name, list_to_check[i] ) == 0 ) { + return 1; + } + } + f_print( stderr, "illegal nettype :\'%s\'\n", name ); + return 0; +} + /* * Compile into an XDR routine output file */ -static -c_output(infile, define, extend, outfile) - char *infile; - char *define; - int extend; - char *outfile; + +static void +c_output(const char *infile, const char *define, int extend, + const char *outfile) { definition *def; char *include; - char *outfilename; + const char *outfilename; long tell; + c_initialize(); open_input(infile, define); outfilename = extend ? extendfile(infile, outfile) : outfile; open_output(infile, outfilename); - f_print(fout, "#include <rpc/rpc.h>\n"); + add_warning(); + add_stdheaders(); if (infile && (include = extendfile(infile, ".h"))) { f_print(fout, "#include \"%s\"\n", include); free(include); - } + /* .h file already contains rpc/rpc.h */ + } else + f_print(fout, "#include <rpc/rpc.h>\n"); tell = ftell(fout); - while (def = get_definition()) { + while ((def = get_definition())!=NULL) { emit(def); } if (extend && tell == ftell(fout)) { @@ -221,99 +427,236 @@ c_output(infile, define, extend, outfile) } } +void +c_initialize(void) +{ + + /* add all the starting basic types */ + + add_type(1,"int"); + add_type(1,"long"); + add_type(1,"short"); + add_type(1,"bool"); + + add_type(1,"u_int"); + add_type(1,"u_long"); + add_type(1,"u_short"); + +} + +char rpcgen_table_dcl[] = "struct rpcgen_table {\n\ + char *(*proc)();\n\ + xdrproc_t xdr_arg;\n\ + unsigned len_arg;\n\ + xdrproc_t xdr_res;\n\ + unsigned len_res;\n\ +};\n"; + + +static char *generate_guard(const char *pathname) { + const char *filename; + char *guard, *tmp; + + filename = strrchr(pathname, '/' ); /* find last component */ + filename = ((filename == NULL) ? pathname : filename+1); + guard = strdup(filename); + /* convert to upper case */ + tmp = guard; + while (*tmp) { + if (islower(*tmp)) + *tmp = toupper(*tmp); + tmp++; + } + + guard = extendfile(guard, "_H_RPCGEN"); + return guard; +} + /* * Compile into an XDR header file */ -static -h_output(infile, define, extend, outfile) - char *infile; - char *define; - int extend; - char *outfile; + + +static void +h_output(const char *infile, const char *define, int extend, + const char *outfile) { definition *def; - char *outfilename; + const char *ifilename; + const char *outfilename; long tell; + char *guard; + list *l; open_input(infile, define); outfilename = extend ? extendfile(infile, outfile) : outfile; open_output(infile, outfilename); + add_warning(); + ifilename = (infile == NULL) ? "STDIN" : infile; + guard = generate_guard( outfilename ? outfilename: ifilename ); + + f_print(fout,"#ifndef _%s\n#define _%s\n\n", guard, + guard); + + f_print(fout, "#include <rpc/rpc.h>\n\n"); + tell = ftell(fout); - while (def = get_definition()) { + /* print data definitions */ + while ((def = get_definition())!=NULL) { print_datadef(def); } + + /* print function declarations. + Do this after data definitions because they might be used as + arguments for functions */ + for (l = defined; l != NULL; l = l->next) { + print_funcdef(l->val); + } if (extend && tell == ftell(fout)) { (void) unlink(outfilename); + } else if (tblflag) { + f_print(fout, rpcgen_table_dcl); } + f_print(fout, "\n#endif /* !_%s */\n", guard); } /* * Compile into an RPC service */ -static -s_output(argc, argv, infile, define, extend, outfile, nomain) - int argc; - char *argv[]; - char *infile; - char *define; - int extend; - char *outfile; - int nomain; +static void +s_output(int argc, const char *argv[], const char *infile, const char *define, + int extend, const char *outfile, int nomain, int netflag) { char *include; definition *def; - int foundprogram; - char *outfilename; + int foundprogram = 0; + const char *outfilename; open_input(infile, define); outfilename = extend ? extendfile(infile, outfile) : outfile; open_output(infile, outfilename); - f_print(fout, "#include <stdio.h>\n"); - f_print(fout, "#include <rpc/rpc.h>\n"); + add_warning(); if (infile && (include = extendfile(infile, ".h"))) { f_print(fout, "#include \"%s\"\n", include); free(include); + } else + f_print(fout, "#include <rpc/rpc.h>\n"); + + f_print(fout, "#include <stdio.h>\n"); + f_print(fout, "#include <stdlib.h>/* getenv, exit */\n"); + if (Cflag) { + f_print (fout, "#include <rpc/pmap_clnt.h> /* for pmap_unset */\n"); + f_print (fout, "#include <string.h> /* strcmp */ \n"); + } + if (strcmp(svcclosetime, "-1") == 0) + indefinitewait = 1; + else if (strcmp(svcclosetime, "0") == 0) + exitnow = 1; + else if (inetdflag || pmflag) { + f_print(fout, "#include <signal.h>\n"); + timerflag = 1; + } + + if( !tirpcflag && inetdflag ) +#ifdef __GNU_LIBRARY__ + f_print(fout, "#include <sys/ioctl.h> /* ioctl, TIOCNOTTY */\n"); +#else + f_print(fout, "#include <sys/ttycom.h>/* TIOCNOTTY */\n"); +#endif + if( Cflag && (inetdflag || pmflag ) ) { +#ifdef __GNU_LIBRARY__ + f_print(fout, "#include <sys/types.h> /* open */\n"); + f_print(fout, "#include <sys/stat.h> /* open */\n"); + f_print(fout, "#include <fcntl.h> /* open */\n"); + f_print(fout, "#include <unistd.h> /* getdtablesize */\n"); +#else + f_print(fout, "#ifdef __cplusplus\n"); + f_print(fout, "#include <sysent.h> /* getdtablesize, open */\n"); + f_print(fout, "#endif /* __cplusplus */\n"); +#endif + if( tirpcflag ) + f_print(fout, "#include <unistd.h> /* setsid */\n"); + } + if( tirpcflag ) + f_print(fout, "#include <sys/types.h>\n"); + + f_print(fout, "#include <memory.h>\n"); +#ifndef __GNU_LIBRARY__ + f_print(fout, "#include <stropts.h>\n"); +#endif + if (inetdflag || !tirpcflag ) { + f_print(fout, "#include <sys/socket.h>\n"); + f_print(fout, "#include <netinet/in.h>\n"); + } + + if ( (netflag || pmflag) && tirpcflag ) { + f_print(fout, "#include <netconfig.h>\n"); + } + if (/*timerflag &&*/ tirpcflag) + f_print(fout, "#include <sys/resource.h> /* rlimit */\n"); + if (logflag || inetdflag || pmflag) { +#ifdef __GNU_LIBRARY__ + f_print(fout, "#include <syslog.h>\n"); +#else + f_print(fout, "#ifdef SYSLOG\n"); + f_print(fout, "#include <syslog.h>\n"); + f_print(fout, "#else\n"); + f_print(fout, "#define LOG_ERR 1\n"); + f_print(fout, "#define openlog(a, b, c)\n"); + f_print(fout, "#endif\n"); +#endif } - foundprogram = 0; - while (def = get_definition()) { + + /* for ANSI-C */ + f_print(fout, "\n#ifdef __STDC__\n#define SIG_PF void(*)(int)\n#endif\n"); + +#ifndef __GNU_LIBRARY__ + f_print(fout, "\n#ifdef DEBUG\n#define RPC_SVC_FG\n#endif\n"); +#endif + if (timerflag) + f_print(fout, "\n#define _RPCSVC_CLOSEDOWN %s\n", svcclosetime); + while ((def = get_definition())!=NULL) { foundprogram |= (def->def_kind == DEF_PROGRAM); } if (extend && !foundprogram) { (void) unlink(outfilename); return; } - if (nomain) { - write_programs((char *)NULL); - } else { - write_most(); - do_registers(argc, argv); + write_most(infile, netflag, nomain); + if (!nomain) { + if( !do_registers(argc, argv) ) { + if (outfilename) + (void) unlink(outfilename); + usage(); + } write_rest(); - write_programs("static"); } } -static -l_output(infile, define, extend, outfile) - char *infile; - char *define; - int extend; - char *outfile; +/* + * generate client side stubs + */ +static void +l_output(const char *infile, const char *define, int extend, + const char *outfile) { char *include; definition *def; - int foundprogram; - char *outfilename; + int foundprogram = 0; + const char *outfilename; open_input(infile, define); outfilename = extend ? extendfile(infile, outfile) : outfile; open_output(infile, outfilename); - f_print(fout, "#include <rpc/rpc.h>\n"); + add_warning(); + if (Cflag) + f_print (fout, "#include <memory.h> /* for memset */\n"); if (infile && (include = extendfile(infile, ".h"))) { f_print(fout, "#include \"%s\"\n", include); free(include); - } - foundprogram = 0; - while (def = get_definition()) { + } else + f_print(fout, "#include <rpc/rpc.h>\n"); + while ((def = get_definition())!=NULL) { foundprogram |= (def->def_kind == DEF_PROGRAM); } if (extend && !foundprogram) { @@ -324,37 +667,195 @@ l_output(infile, define, extend, outfile) } /* - * Perform registrations for service output + * generate the dispatch table */ -static -do_registers(argc, argv) - int argc; - char *argv[]; +static void +t_output(const char *infile, const char *define, int extend, + const char *outfile) +{ + definition *def; + int foundprogram = 0; + const char *outfilename; + + open_input(infile, define); + outfilename = extend ? extendfile(infile, outfile) : outfile; + open_output(infile, outfilename); + add_warning(); + while ((def = get_definition())!=NULL) { + foundprogram |= (def->def_kind == DEF_PROGRAM); + } + if (extend && !foundprogram) { + (void) unlink(outfilename); + return; + } + write_tables(); +} + +/* sample routine for the server template */ +static void +svc_output(const char *infile, const char *define, int extend, + const char *outfile) +{ + definition *def; + char *include; + const char *outfilename; + long tell; + + open_input(infile, define); + outfilename = extend ? extendfile(infile, outfile) : outfile; + checkfiles(infile,outfilename); /*check if outfile already exists. + if so, print an error message and exit*/ + open_output(infile, outfilename); + add_sample_msg(); + + if (infile && (include = extendfile(infile, ".h"))) { + f_print(fout, "#include \"%s\"\n", include); + free(include); + } else + f_print(fout, "#include <rpc/rpc.h>\n"); + + tell = ftell(fout); + while ((def = get_definition())!=NULL) { + write_sample_svc(def); + } + if (extend && tell == ftell(fout)) { + (void) unlink(outfilename); + } +} + + +/* sample main routine for client */ +static void +clnt_output(const char *infile, const char *define, int extend, + const char *outfile) +{ + definition *def; + char *include; + const char *outfilename; + long tell; + int has_program = 0; + open_input(infile, define); + outfilename = extend ? extendfile(infile, outfile) : outfile; + checkfiles(infile,outfilename); /*check if outfile already exists. + if so, print an error message and exit*/ + + open_output(infile, outfilename); + add_sample_msg(); + if (infile && (include = extendfile(infile, ".h"))) { + f_print(fout, "#include \"%s\"\n", include); + free(include); + } else + f_print(fout, "#include <rpc/rpc.h>\n"); + tell = ftell(fout); + while ((def = get_definition())!=NULL) { + has_program += write_sample_clnt(def); + } + + if( has_program ) + write_sample_clnt_main(); + + if (extend && tell == ftell(fout)) { + (void) unlink(outfilename); + } +} + +/* + * Perform registrations for service output + * Return 0 if failed; 1 otherwise. + */ +static int do_registers(int argc, const char *argv[]) { int i; - for (i = 1; i < argc; i++) { - if (streq(argv[i], "-s")) { - write_register(argv[i + 1]); - i++; + if ( inetdflag || !tirpcflag) { + for (i = 1; i < argc; i++) { + if (streq(argv[i], "-s")) { + if(!check_nettype( argv[i + 1], valid_i_nettypes )) + return 0; + write_inetd_register(argv[i + 1]); + i++; + } } + } else { + for (i = 1; i < argc; i++) + if (streq(argv[i], "-s")) { + if(!check_nettype( argv[i + 1], valid_ti_nettypes )) + return 0; + write_nettype_register(argv[i + 1]); + i++; + } else if (streq(argv[i], "-n")) { + write_netid_register(argv[i + 1]); + i++; + } } + return 1; } /* - * Parse command line arguments + * Add another argument to the arg list */ -static -parseargs(argc, argv, cmd) - int argc; - char *argv[]; - struct commandline *cmd; +static void +addarg(const char *cp) +{ + if (argcount >= ARGLISTLEN) { + f_print(stderr, "rpcgen: too many defines\n"); + crash(); + /*NOTREACHED*/ + } + arglist[argcount++] = cp; + +} + +static void +putarg(int whereto, const char *cp) +{ + if (whereto >= ARGLISTLEN) { + f_print(stderr, "rpcgen: arglist coding error\n"); + crash(); + /*NOTREACHED*/ + } + arglist[whereto] = cp; +} +/* + * if input file is stdin and an output file is specified then complain + * if the file already exists. Otherwise the file may get overwritten + * If input file does not exist, exit with an error + */ + +static void +checkfiles(const char *infile, const char *outfile) +{ + + struct stat buf; + + if(infile) /* infile ! = NULL */ + if(stat(infile,&buf) < 0) + { + perror(infile); + crash(); + }; + if (outfile) { + if (stat(outfile, &buf) < 0) + return; /* file does not exist */ + else { + f_print(stderr, + "file '%s' already exists and may be overwritten\n", outfile); + crash(); + } + } +} + +/* + * Parse command line arguments + */ +static int +parseargs(int argc, const char *argv[], struct commandline *cmd) { int i; int j; - char c; + int c; char flag[(1 << 8 * sizeof(char))]; int nflags; @@ -363,15 +864,22 @@ parseargs(argc, argv, cmd) if (argc < 2) { return (0); } + allfiles = 0; flag['c'] = 0; flag['h'] = 0; - flag['s'] = 0; - flag['o'] = 0; flag['l'] = 0; flag['m'] = 0; + flag['o'] = 0; + flag['s'] = 0; + flag['n'] = 0; + flag['t'] = 0; + flag['S'] = 0; + flag['C'] = 0; for (i = 1; i < argc; i++) { if (argv[i][0] != '-') { if (cmd->infile) { + f_print( stderr, "Cannot specify more than one input file!\n"); + return (0); } cmd->infile = argv[i]; @@ -379,15 +887,85 @@ parseargs(argc, argv, cmd) for (j = 1; argv[i][j] != 0; j++) { c = argv[i][j]; switch (c) { + case 'a': + allfiles = 1; + break; case 'c': case 'h': case 'l': case 'm': + case 't': if (flag[c]) { return (0); } flag[c] = 1; break; + case 'S': + /* sample flag: Ss or Sc. + Ss means set flag['S']; + Sc means set flag['C']; */ + c = argv[i][++j]; /* get next char */ + if( c == 's' ) + c = 'S'; + else if( c == 'c' ) + c = 'C'; + else + return( 0 ); + + if (flag[c]) { + return (0); + } + flag[c] = 1; + break; + case 'C': /* ANSI C syntax */ + Cflag = 1; + break; + +#ifdef __GNU_LIBRARY__ + case 'k': /* K&R C syntax */ + Cflag = 0; + break; + +#endif + case 'b': /* turn TIRPC flag off for + generating backward compatible + */ + tirpcflag = 0; + break; + +#ifdef __GNU_LIBRARY__ + case '5': /* turn TIRPC flag on for + generating SysVr4 compatible + */ + tirpcflag = 1; + break; + +#endif + case 'I': + inetdflag = 1; + break; + case 'N': + newstyle = 1; + break; + case 'L': + logflag = 1; + break; + case 'K': + if (++i == argc) { + return (0); + } + svcclosetime = argv[i]; + goto nextarg; + case 'T': + tblflag = 1; + break; + case 'i' : + if (++i == argc) { + return (0); + } + inlineflag = atoi(argv[i]); + goto nextarg; + case 'n': case 'o': case 's': if (argv[i][j - 1] != '-' || @@ -410,6 +988,23 @@ parseargs(argc, argv, cmd) cmd->outfile = argv[i]; } goto nextarg; + case 'D': + if (argv[i][j - 1] != '-') { + return (0); + } + (void) addarg(argv[i]); + goto nextarg; + case 'Y': + if (++i == argc) { + return (0); + } + (void) strcpy(pathbuf, argv[i]); + (void) strcat(pathbuf, "/cpp"); + CPP = pathbuf; + cppDefined = 1; + goto nextarg; + + default: return (0); @@ -419,18 +1014,93 @@ parseargs(argc, argv, cmd) ; } } + cmd->cflag = flag['c']; cmd->hflag = flag['h']; - cmd->sflag = flag['s']; cmd->lflag = flag['l']; cmd->mflag = flag['m']; - nflags = cmd->cflag + cmd->hflag + cmd->sflag + cmd->lflag + cmd->mflag; + cmd->nflag = flag['n']; + cmd->sflag = flag['s']; + cmd->tflag = flag['t']; + cmd->Ssflag = flag['S']; + cmd->Scflag = flag['C']; + + if( tirpcflag ) { + pmflag = inetdflag ? 0 : 1; /* pmflag or inetdflag is always TRUE */ + if( (inetdflag && cmd->nflag)) { /* netid not allowed with inetdflag */ + f_print(stderr, "Cannot use netid flag with inetd flag!\n"); + return (0); + } + } else { /* 4.1 mode */ + pmflag = 0; /* set pmflag only in tirpcmode */ +#ifndef __GNU_LIBRARY__ + inetdflag = 1; /* inetdflag is TRUE by default */ +#endif + if( cmd->nflag ) { /* netid needs TIRPC */ + f_print( stderr, "Cannot use netid flag without TIRPC!\n"); + return( 0 ); + } + } + + if( newstyle && ( tblflag || cmd->tflag) ) { + f_print( stderr, "Cannot use table flags with newstyle!\n"); + return( 0 ); + } + + /* check no conflicts with file generation flags */ + nflags = cmd->cflag + cmd->hflag + cmd->lflag + cmd->mflag + + cmd->sflag + cmd->nflag + cmd->tflag + cmd->Ssflag + cmd->Scflag; + if (nflags == 0) { if (cmd->outfile != NULL || cmd->infile == NULL) { return (0); } } else if (nflags > 1) { + f_print( stderr, "Cannot have more than one file generation flag!\n"); return (0); } return (1); } + +static void +usage(void) +{ + f_print(stderr, "usage: %s infile\n", cmdname); + f_print(stderr, "\t%s [-a][-b][-C][-Dname[=value]] -i size [-I [-K seconds]] [-L][-N][-T] infile\n", + cmdname); + f_print(stderr, "\t%s [-c | -h | -l | -m | -t | -Sc | -Ss] [-o outfile] [infile]\n", + cmdname); + f_print(stderr, "\t%s [-s nettype]* [-o outfile] [infile]\n", cmdname); + f_print(stderr, "\t%s [-n netid]* [-o outfile] [infile]\n", cmdname); + options_usage(); + exit(1); +} + +static void +options_usage(void) +{ + f_print(stderr, "options:\n"); + f_print(stderr, "-a\t\tgenerate all files, including samples\n"); + f_print(stderr, "-b\t\tbackward compatibility mode (generates code for SunOS 4.1)\n"); + f_print(stderr, "-c\t\tgenerate XDR routines\n"); + f_print(stderr, "-C\t\tANSI C mode\n"); + f_print(stderr, "-Dname[=value]\tdefine a symbol (same as #define)\n"); + f_print(stderr, "-h\t\tgenerate header file\n"); + f_print(stderr, "-i size\t\tsize at which to start generating inline code\n"); + f_print(stderr, "-I\t\tgenerate code for inetd support in server (for SunOS 4.1)\n"); + f_print(stderr, "-K seconds\tserver exits after K seconds of inactivity\n"); + f_print(stderr, "-l\t\tgenerate client side stubs\n"); + f_print(stderr, "-L\t\tserver errors will be printed to syslog\n"); + f_print(stderr, "-m\t\tgenerate server side stubs\n"); + f_print(stderr, "-n netid\tgenerate server code that supports named netid\n"); + f_print(stderr, "-N\t\tsupports multiple arguments and call-by-value\n"); + f_print(stderr, "-o outfile\tname of the output file\n"); + f_print(stderr, "-s nettype\tgenerate server code that supports named nettype\n"); + f_print(stderr, "-Sc\t\tgenerate sample client code that uses remote procedures\n"); + f_print(stderr, "-Ss\t\tgenerate sample server code that defines remote procedures\n"); + f_print(stderr, "-t\t\tgenerate RPC dispatch table\n"); + f_print(stderr, "-T\t\tgenerate code to support RPC dispatch tables\n"); + f_print(stderr, "-Y path\t\tdirectory name to find C preprocessor (cpp)\n"); + + exit(1); +} |