home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-04-24 | 96.8 KB | 3,231 lines |
- Newsgroups: comp.sources.unix
- From: mnl@dtro.e-technik.th-darmstadt.de (Michael Lipp)
- Subject: v26i181: mnl-rpc++-2.3.1 - a C++ interface to Sun RPC, Part01/03
- Sender: unix-sources-moderator@vix.com
- Approved: paul@vix.com
-
- Submitted-By: mnl@dtro.e-technik.th-darmstadt.de (Michael Lipp)
- Posting-Number: Volume 26, Issue 181
- Archive-Name: mnl-rpc++-2.3.1/part01
-
- This package contains the sources for a C++ interface to Sun RPCs.
-
- As far as I remember, I got the original sources of the rpc++-library from
- some newsgroup, though I don't remember which one. I liked the basic idea
- but disliked several aspects of the interface details. So I adapted it to my
- likes. I intended some minor changes but soon found myself renaming classes,
- changing method parameters, introducing new classes, etc. The result is by
- no way compatible with the original version. It is, I hope, nevertheless
- useful.
-
- This current version (2.3.1) of the rpc++ library updates the version 2.1
- posted in March 1991. It is the reaction to gcc-2.2 that finally allows a
- sufficiently reliable use of templates (almost, see Installation in
- rpc++.texi)
-
- mnl@dtro.e-technik.th-darmstadt.de (Michael Lipp)
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 1 (of 3)."
- # Contents: .cvsignore MANIFEST Makefile Proj.make README README-2.3
- # README-2.3.1 README.ORIG StdHdrs StdHdrs/Makefile StdHdrs/README
- # StdHdrs/rpc StdHdrs/rpc/auth.h StdHdrs/rpc/c_types.h
- # StdHdrs/rpc/pmap_clnt.h callback.cc example example/.cvsignore
- # example/Makefile example/calcsvc.cc example/calcsvc.h
- # example/client.cc example/server.cc gcc-2.2.fix gcc-2.3.3.fix
- # request.cc rpc++ rpc++/request.h rpc++/service.h rpc++/stub.h
- # rpc++/xdr++.h service.cc stub.cc version.h xdr++.cc
- # Wrapped by vixie@gw.home.vix.com on Sun Apr 25 00:49:46 1993
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f '.cvsignore' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'.cvsignore'\"
- else
- echo shar: Extracting \"'.cvsignore'\" \(192 characters\)
- sed "s/^X//" >'.cvsignore' <<'END_OF_FILE'
- X.dependencies
- rpc++.log
- rpc++.dvi
- rpc++.aux
- rpc++.toc
- rpc++.cp
- rpc++.fn
- rpc++.vr
- rpc++.tp
- rpc++.ky
- rpc++.pg
- rpc++.info
- X.isp_english
- rpc++.cps
- rpc++.fns
- rpc++.kys
- rpc++.pgs
- rpc++.tps
- rpc++.vrs
- END_OF_FILE
- if test 192 -ne `wc -c <'.cvsignore'`; then
- echo shar: \"'.cvsignore'\" unpacked with wrong size!
- fi
- # end of '.cvsignore'
- fi
- if test -f 'MANIFEST' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'MANIFEST'\"
- else
- echo shar: Extracting \"'MANIFEST'\" \(1385 characters\)
- sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
- X File Name Archive # Description
- X-----------------------------------------------------------
- X .cvsignore 1
- X COPYING 2
- X MANIFEST 1 This shipping list
- X Makefile 1
- X Proj.make 1
- X README 1
- X README-2.3 1
- X README-2.3.1 1
- X README.ORIG 1
- X StdHdrs 1
- X StdHdrs/Makefile 1
- X StdHdrs/README 1
- X StdHdrs/rpc 1
- X StdHdrs/rpc/auth.h 1
- X StdHdrs/rpc/c_types.h 1
- X StdHdrs/rpc/clnt.h 2
- X StdHdrs/rpc/pmap_clnt.h 1
- X StdHdrs/rpc/svc.h 2
- X StdHdrs/rpc/xdr.h 2
- X callback.cc 1
- X example 1
- X example/.cvsignore 1
- X example/Makefile 1
- X example/calcsvc.cc 1
- X example/calcsvc.h 1
- X example/client.cc 1
- X example/server.cc 1
- X gcc-2.2.fix 1
- X gcc-2.3.3.fix 1
- X request.cc 1
- X rpc++ 1
- X rpc++.texi 3
- X rpc++/callback.h 2
- X rpc++/request.h 1
- X rpc++/service.h 1
- X rpc++/stub.h 1
- X rpc++/xdr++.h 1
- X service.cc 1
- X stub.cc 1
- X version.h 1
- X xdr++.cc 1
- END_OF_FILE
- if test 1385 -ne `wc -c <'MANIFEST'`; then
- echo shar: \"'MANIFEST'\" unpacked with wrong size!
- fi
- # end of 'MANIFEST'
- fi
- if test -f 'Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Makefile'\"
- else
- echo shar: Extracting \"'Makefile'\" \(1446 characters\)
- sed "s/^X//" >'Makefile' <<'END_OF_FILE'
- TOP = .
- SUBDIRS = StdHdrs example
- X
- INSTROOT = ../..
- X
- CC = gcc
- CPPFLAGS = -I.
- CFLAGS = -ggdb
- C++FLAGS = $(CFLAGS)
- X
- LIBHDRS = rpc++/xdr++.h rpc++/request.h rpc++/service.h rpc++/stub.h \
- X rpc++/callback.h version.h
- LIBSRCS = xdr++.cc service.cc stub.cc request.cc callback.cc
- X
- LIBOBJS = $(LIBSRCS:%.cc=%.o) $(GENSRCS:%.cc=%.o)
- X
- all:: librpc++.a
- X
- subdirs.all:: librpc++.a
- X
- librpc++.a: $(LIBOBJS)
- X rm -f $@
- X ar cq $@ $(LIBOBJS)
- X if [ -x /bin/ranlib -o -x /usr/bin/ranlib ]; then ranlib $@; fi
- X
- install:: librpc++.a
- X install -d $(INSTROOT)/lib
- X if cmp -s librpc++.a $(INSTROOT)/lib/librpc++.a; then : ; \
- X else rm -f $(INSTROOT)/lib/librpc++.a; \
- X cp -p librpc++.a $(INSTROOT)/lib; \
- X chmod 444 $(INSTROOT)/lib/librpc++.a; \
- X for f in rpc++/*.h; do \
- X rm -f $(INSTROOT)/include/$$f; done; fi
- X install -d $(INSTROOT)/include/rpc++
- X for f in rpc++/*.h; do \
- X cmp -s $$f $(INSTROOT)/include/$$f \
- X || install -c -m 444 $$f $(INSTROOT)/include/rpc++; done
- X
- DISTLIST = Makefile README.ORIG README COPYING Proj.make rpc++.texi \
- X gcc-2.2.2.fix $(LIBHDRS) $(LIBSRCS) README-2.3
- X
- clean::
- X rm -f $(CLEANWILDCARDS) librpc++.a
- X
- include .dependencies
- X
- X.dependencies: $(LIBHDRS) $(LIBSRCS)
- X gcc -M $(CPPFLAGS) $(LIBSRCS) > .dependencies
- X
- distlist::
- X @for f in *.[ch] *.cc; do \
- X if expr " $(DISTLIST) " : ".* $$f " >/dev/null; then : ; \
- X else echo 1>&2 "Warning: c- or h-file \"$$f\" not in DISTLIST"; fi; \
- X done
- X
- include $(TOP)/Proj.make
- END_OF_FILE
- if test 1446 -ne `wc -c <'Makefile'`; then
- echo shar: \"'Makefile'\" unpacked with wrong size!
- fi
- # end of 'Makefile'
- fi
- if test -f 'Proj.make' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Proj.make'\"
- else
- echo shar: Extracting \"'Proj.make'\" \(1450 characters\)
- sed "s/^X//" >'Proj.make' <<'END_OF_FILE'
- X# These are included in every Makefile in the project
- X
- CWDPATH = .
- CLEANWILDCARDS = core *~ *.o
- VERYCLEANWILDCARDS = core *~ *.o
- TEXCLEANWILDCARD = *~ *.aux *.log *.bbl *.blg *.toc *.idx *.ind
- TEXVERYCLEANWILDCARD = $(TEXCLEANWILDCARD) *.dvi
- ifndef SUBDIRS
- SUBDIRS =
- endif
- X
- X# Doing all always means doing the subdirs.
- X# Make subdirs.all a target to allow forced processing
- ifneq ("$(SUBDIRS)", "")
- ifneq ("$(SUBDIRSALL)", "NO")
- all:: subdirs.all
- endif
- X
- subdirs.all::
- X @for d in $(SUBDIRS); do \
- X (cd $$d; \
- X smflags=$(SUBMFLAGS); \
- X echo "Making all in $$d with flags: $$smflags ..." ; \
- X echo "cd `pwd`"; \
- X $(MAKE) $$smflags all); done; \
- X echo "cd `pwd`"
- else
- all::;
- endif
- X
- ifneq ("$(SUBDIRS)", "")
- clean:: subdirs.clean
- X
- subdirs.clean::
- X @for d in $(SUBDIRS); do \
- X echo "Cleaning all in $$d..." ; \
- X (cd $$d; $(MAKE) clean); done
- else
- clean::;
- endif
- X
- ifneq ("$(SUBDIRS)", "")
- veryclean:: subdirs.veryclean
- X
- subdirs.veryclean::
- X @for d in $(SUBDIRS); do \
- X echo "Verycleaning all in $$d..." ; \
- X (cd $$d; $(MAKE) veryclean); done
- else
- veryclean::;
- endif
- X
- X# dist.list prints a list of files to be included in the distribution
- distlist::
- ifneq ("$(DISTLIST)", "")
- X @for f in $(DISTLIST); do \
- X echo $(CWDPATH)/$$f; done
- endif
- ifneq ("$(SUBDIRS)", "")
- ifneq ("$(SUBDIRSDIST)", "NO")
- X @for d in $(SUBDIRS); do \
- X (cd $$d; $(MAKE) distlist CWDPATH=$(CWDPATH)/$$d); done
- endif
- endif
- ifeq ("$(DISTLIST)$(SUBDIRS)","")
- X
- endif
- X
- END_OF_FILE
- if test 1450 -ne `wc -c <'Proj.make'`; then
- echo shar: \"'Proj.make'\" unpacked with wrong size!
- fi
- # end of 'Proj.make'
- fi
- if test -f 'README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README'\"
- else
- echo shar: Extracting \"'README'\" \(805 characters\)
- sed "s/^X//" >'README' <<'END_OF_FILE'
- This directory contains the sources for a C++ interface to Sun RPCs.
- X
- As far as I remember, I got the original sources of the rpc++-library
- from some newsgroup, though I don't remember which one. I liked the
- basic idea but disliked several aspects of the interface details. So I
- adapted it to my likes. I intended some minor changes but soon found
- myself renaming classes, changing method parameters, introducing new
- classes, etc. The result is by no way compatible with the original
- version. It is, I hope, nevertheless useful.
- X
- The current version 2.2 of the rpc++ library updates the version 2.1
- posted in March 1991. It is the reaction to gcc-2.2 that finally
- allows a sufficiently reliable use of templates (almost, see
- Installation in rpc++.texi)
- X
- Michael Lipp
- X
- X<mnl@dtro.e-technik.th-darmstadt.de>
- END_OF_FILE
- if test 805 -ne `wc -c <'README'`; then
- echo shar: \"'README'\" unpacked with wrong size!
- fi
- # end of 'README'
- fi
- if test -f 'README-2.3' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README-2.3'\"
- else
- echo shar: Extracting \"'README-2.3'\" \(747 characters\)
- sed "s/^X//" >'README-2.3' <<'END_OF_FILE'
- Version 2.3 fixes some bugs and adds a few methods that have shown to be
- needed for a complex application. The methods are:
- X
- RpcService::ReserveService
- X Allocates an unused service number at runtime.
- X
- RpcService::Unregister
- X Unregisters (i.e., provides no longer) a service.
- X
- RpcService::Provide (timeval&)
- X Previously only available without argument. Provides services for
- X a limited time or until a request has been handled.
- X
- RpcStub::ReCall
- X May be used from within an error handle to repeat a call after the cause
- X of its failure has been fixed.
- X
- StdHdrs/rpc contains a new version of xdr.h with better (more precise)
- function prototypes contributed by Doug Moore (dougm@cs.rice.edu).
- X
- Michael Lipp
- X
- X<mnl@dtro.e-technik.th-darmstadt.de>
- END_OF_FILE
- if test 747 -ne `wc -c <'README-2.3'`; then
- echo shar: \"'README-2.3'\" unpacked with wrong size!
- fi
- # end of 'README-2.3'
- fi
- if test -f 'README-2.3.1' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README-2.3.1'\"
- else
- echo shar: Extracting \"'README-2.3.1'\" \(725 characters\)
- sed "s/^X//" >'README-2.3.1' <<'END_OF_FILE'
- Version 2.3.1 fixes some warnings and ANSI C++ violations discovered
- by gcc-2.3.3 and clarifies include statements as suggested by Doug
- Moore (dougm@cs.rice.edu). It also includes the gcc-2.3.3 version of
- the gcc-2.2 patch. It's a pity that you still need to patch gcc in
- order to compile rpc++. I have re-sent the bug report and someone
- from cygnus replied that things should be fixed in the next gcc
- release.
- X
- Interactive Unix is no longer supported, simply because I replaced it
- with Linux on my 386-box (clearer, faster, cheaper). rpc++ compiles
- under Linux "out of the box" with the 4.2 development environment
- X(after you have patched and recompiled gcc, of course).
- X
- Michael Lipp
- X
- X<mnl@dtro.e-technik.th-darmstadt.de>
- END_OF_FILE
- if test 725 -ne `wc -c <'README-2.3.1'`; then
- echo shar: \"'README-2.3.1'\" unpacked with wrong size!
- fi
- # end of 'README-2.3.1'
- fi
- if test -f 'README.ORIG' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README.ORIG'\"
- else
- echo shar: Extracting \"'README.ORIG'\" \(280 characters\)
- sed "s/^X//" >'README.ORIG' <<'END_OF_FILE'
- This directory contains a collection of classes that provide an
- interface to SUN's RPCs. I dubbed the collection the rpc++-library. It
- has been tested with gcc-1.40 on a SparcStation running SunOS 4.0.
- X
- There is no documentation. Look at the example in ./example.
- X
- Peter Berens
- X
- X
- END_OF_FILE
- if test 280 -ne `wc -c <'README.ORIG'`; then
- echo shar: \"'README.ORIG'\" unpacked with wrong size!
- fi
- # end of 'README.ORIG'
- fi
- if test ! -d 'StdHdrs' ; then
- echo shar: Creating directory \"'StdHdrs'\"
- mkdir 'StdHdrs'
- fi
- if test -f 'StdHdrs/Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'StdHdrs/Makefile'\"
- else
- echo shar: Extracting \"'StdHdrs/Makefile'\" \(171 characters\)
- sed "s/^X//" >'StdHdrs/Makefile' <<'END_OF_FILE'
- TOP = ..
- SUBDIRS = rpc
- SUBDIRSALL = NO
- SUBDIRSDIST = NO
- X
- all::
- X
- clean::
- X rm -f $(CLEANWILDCARDS)
- X
- DISTLIST = Makefile README $(wildcard rpc/*.h)
- X
- include $(TOP)/Proj.make
- END_OF_FILE
- if test 171 -ne `wc -c <'StdHdrs/Makefile'`; then
- echo shar: \"'StdHdrs/Makefile'\" unpacked with wrong size!
- fi
- # end of 'StdHdrs/Makefile'
- fi
- if test -f 'StdHdrs/README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'StdHdrs/README'\"
- else
- echo shar: Extracting \"'StdHdrs/README'\" \(177 characters\)
- sed "s/^X//" >'StdHdrs/README' <<'END_OF_FILE'
- This directory contains some of Sun's rpc headers that have been fixed
- X(though not thoroughly) to work with ANSI C and C++. I have installed
- them in my standard C include path.
- END_OF_FILE
- if test 177 -ne `wc -c <'StdHdrs/README'`; then
- echo shar: \"'StdHdrs/README'\" unpacked with wrong size!
- fi
- # end of 'StdHdrs/README'
- fi
- if test ! -d 'StdHdrs/rpc' ; then
- echo shar: Creating directory \"'StdHdrs/rpc'\"
- mkdir 'StdHdrs/rpc'
- fi
- if test -f 'StdHdrs/rpc/auth.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'StdHdrs/rpc/auth.h'\"
- else
- echo shar: Extracting \"'StdHdrs/rpc/auth.h'\" \(4903 characters\)
- sed "s/^X//" >'StdHdrs/rpc/auth.h' <<'END_OF_FILE'
- X/* @(#)auth.h 2.3 88/08/07 4.0 RPCSRC; from 1.17 88/02/08 SMI */
- X/*
- X * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- X * unrestricted use provided that this legend is included on all tape
- X * media and as a part of the software program in whole or part. Users
- X * may copy or modify Sun RPC without charge, but are not authorized
- X * to license or distribute it to anyone else except as part of a product or
- X * program developed by the user.
- X *
- X * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- X * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- X * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- X *
- X * Sun RPC is provided with no support and without any obligation on the
- X * part of Sun Microsystems, Inc. to assist in its use, correction,
- X * modification or enhancement.
- X *
- X * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- X * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- X * OR ANY PART THEREOF.
- X *
- X * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- X * or profits or other special, indirect and consequential damages, even if
- X * Sun has been advised of the possibility of such damages.
- X *
- X * Sun Microsystems, Inc.
- X * 2550 Garcia Avenue
- X * Mountain View, California 94043
- X */
- X
- X/*
- X * auth.h, Authentication interface.
- X *
- X * Copyright (C) 1984, Sun Microsystems, Inc.
- X *
- X * The data structures are completely opaque to the client. The client
- X * is required to pass a AUTH * to routines that create rpc
- X * "sessions".
- X */
- X
- X
- X#ifndef _rpc_auth_h
- X#define _rpc_auth_h
- X
- X#define MAX_AUTH_BYTES 400
- X#define MAXNETNAMELEN 255 /* maximum length of network user's name */
- X
- X/*
- X * Status returned from authentication check
- X */
- enum auth_stat {
- X AUTH_OK=0,
- X /*
- X * failed at remote end
- X */
- X AUTH_BADCRED=1, /* bogus credentials (seal broken) */
- X AUTH_REJECTEDCRED=2, /* client should begin new session */
- X AUTH_BADVERF=3, /* bogus verifier (seal broken) */
- X AUTH_REJECTEDVERF=4, /* verifier expired or was replayed */
- X AUTH_TOOWEAK=5, /* rejected due to security reasons */
- X /*
- X * failed locally
- X */
- X AUTH_INVALIDRESP=6, /* bogus response verifier */
- X AUTH_FAILED=7 /* some unknown reason */
- X};
- X
- X#if (__mc68000__ || __sparc__ || __vax__ || __i386__)
- typedef u_long u_int32; /* 32-bit unsigned integers */
- X#endif
- X
- union des_block {
- X struct {
- X u_int32 high;
- X u_int32 low;
- X } key;
- X char c[8];
- X};
- typedef union des_block des_block;
- extern bool_t xdr_des_block();
- X
- X/*
- X * Authentication info. Opaque to client.
- X */
- struct opaque_auth {
- X enum_t oa_flavor; /* flavor of auth */
- X caddr_t oa_base; /* address of more auth stuff */
- X u_int oa_length; /* not to exceed MAX_AUTH_BYTES */
- X};
- X
- X
- X/*
- X * Auth handle, interface to client side authenticators.
- X */
- typedef struct {
- X struct opaque_auth ah_cred;
- X struct opaque_auth ah_verf;
- X union des_block ah_key;
- X struct auth_ops {
- X void (*ah_nextverf)();
- X int (*ah_marshal)(); /* nextverf & serialize */
- X int (*ah_validate)(); /* validate varifier */
- X int (*ah_refresh)(); /* refresh credentials */
- X void (*ah_destroy)(); /* destroy this structure */
- X } *ah_ops;
- X caddr_t ah_private;
- X} AUTH;
- X
- X
- X/*
- X * Authentication ops.
- X * The ops and the auth handle provide the interface to the authenticators.
- X *
- X * AUTH *auth;
- X * XDR *xdrs;
- X * struct opaque_auth verf;
- X */
- X#define AUTH_NEXTVERF(auth) \
- X ((*((auth)->ah_ops->ah_nextverf))(auth))
- X#define auth_nextverf(auth) \
- X ((*((auth)->ah_ops->ah_nextverf))(auth))
- X
- X#define AUTH_MARSHALL(auth, xdrs) \
- X ((*((auth)->ah_ops->ah_marshal))(auth, xdrs))
- X#define auth_marshall(auth, xdrs) \
- X ((*((auth)->ah_ops->ah_marshal))(auth, xdrs))
- X
- X#define AUTH_VALIDATE(auth, verfp) \
- X ((*((auth)->ah_ops->ah_validate))((auth), verfp))
- X#define auth_validate(auth, verfp) \
- X ((*((auth)->ah_ops->ah_validate))((auth), verfp))
- X
- X#define AUTH_REFRESH(auth) \
- X ((*((auth)->ah_ops->ah_refresh))(auth))
- X#define auth_refresh(auth) \
- X ((*((auth)->ah_ops->ah_refresh))(auth))
- X
- X#define AUTH_DESTROY(auth) \
- X ((*((auth)->ah_ops->ah_destroy))(auth))
- X#define auth_destroy(auth) \
- X ((*((auth)->ah_ops->ah_destroy))(auth))
- X
- X
- extern struct opaque_auth _null_auth;
- X
- X
- X/*
- X * These are the various implementations of client side authenticators.
- X */
- X
- X/*
- X * Unix style authentication
- X * AUTH *authunix_create(machname, uid, gid, len, aup_gids)
- X * char *machname;
- X * int uid;
- X * int gid;
- X * int len;
- X * int *aup_gids;
- X */
- extern AUTH *authunix_create();
- extern AUTH *authunix_create_default(); /* takes no parameters */
- extern AUTH *authnone_create(); /* takes no parameters */
- extern AUTH *authdes_create();
- X
- X#define AUTH_NONE 0 /* no authentication */
- X#define AUTH_NULL 0 /* backward compatibility */
- X#define AUTH_UNIX 1 /* unix style (uid, gids) */
- X#define AUTH_SHORT 2 /* short hand unix style */
- X#define AUTH_DES 3 /* des style (encrypted timestamps) */
- X
- X#endif /*!_rpc_auth_h*/
- END_OF_FILE
- if test 4903 -ne `wc -c <'StdHdrs/rpc/auth.h'`; then
- echo shar: \"'StdHdrs/rpc/auth.h'\" unpacked with wrong size!
- fi
- # end of 'StdHdrs/rpc/auth.h'
- fi
- if test -f 'StdHdrs/rpc/c_types.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'StdHdrs/rpc/c_types.h'\"
- else
- echo shar: Extracting \"'StdHdrs/rpc/c_types.h'\" \(2286 characters\)
- sed "s/^X//" >'StdHdrs/rpc/c_types.h' <<'END_OF_FILE'
- X#ifndef _rpc_c_types_h_
- X#define _rpc_c_types_h_
- X
- X#if defined(__cplusplus)
- X /*
- X * Definitions for C++ 2.0 and later require extern "C" { decl; }
- X */
- X# define EXTERN_FUNCTION( rtn, args ) extern "C" { rtn args; }
- X# define FUN_ARGS( args ) args
- X# define STRUCT_TAG( tag_name ) /* the tag disappears */
- X# define ENUM_BITFIELD( enum_type ) unsigned
- X# define ENUM_TYPE( enum_sp, enum_ty ) enum_ty
- X
- X#if defined(__STDC__) || defined(__cplusplus) || defined(c_plusplus)
- X# define NAME_CONFLICT( name ) _##name
- X#else
- X# define NAME_CONFLICT( name ) _/**/name
- X#endif
- X
- X# define DOTDOTDOT ...
- X# define _VOID_ /* anachronism */
- X# define CONST const
- X
- X/*
- X * This is not necessary for 2.0 since 2.0 has corrected the void (*) () problem
- X */
- typedef void (*_PFV_)();
- typedef int (*_PFI_)();
- X
- X#elif defined(c_plusplus)
- X /*
- X * Definitions for C++ 1.2
- X */
- X# define EXTERN_FUNCTION( rtn, args ) rtn args
- X# define FUN_ARGS( args ) args
- X# define STRUCT_TAG( tag_name ) /* the tag disappears */
- X# define ENUM_BITFIELD( enum_type ) unsigned
- X# define ENUM_TYPE( enum_sp, enum_ty ) enum_ty
- X# define NAME_CONFLICT( name ) _/**/name
- X# define DOTDOTDOT ...
- X# define _VOID_ /* anachronism */
- X# define CONST const
- X
- typedef void (*_PFV_)();
- typedef int (*_PFI_)();
- X
- X#elif defined(__STDC__)
- X /*
- X * Definitions for ANSI C
- X */
- X# define EXTERN_FUNCTION( rtn, args ) rtn args
- X# define FUN_ARGS( args ) args
- X# define STRUCT_TAG( tag_name ) tag_name
- X# define ENUM_BITFIELD( enum_type ) unsigned
- X# define ENUM_TYPE( enum_sp, enum_ty ) enum_sp enum_ty
- X# define NAME_CONFLICT( name ) name
- X# define DOTDOTDOT ...
- X# define _VOID_ void
- X# define CONST
- X
- X#else
- X /*
- X * Definitions for Sun/K&R C -- ignore function prototypes,
- X * but preserve tag names and enum bitfield declarations.
- X */
- X# define EXTERN_FUNCTION( rtn, args ) rtn()
- X# define FUN_ARGS( args ) ()
- X# define STRUCT_TAG( tag_name ) tag_name
- X# define ENUM_BITFIELD( enum_type ) enum_type
- X# define ENUM_TYPE( enum_sp, enum_ty ) enum_sp enum_ty
- X# define NAME_CONFLICT( name ) name
- X# define DOTDOTDOT
- X# define _VOID_
- X /* VOID is only used where it disappears anyway */
- X# define CONST
- X
- X#endif /* Which type of C/C++ compiler are we using? */
- X
- X#endif
- END_OF_FILE
- if test 2286 -ne `wc -c <'StdHdrs/rpc/c_types.h'`; then
- echo shar: \"'StdHdrs/rpc/c_types.h'\" unpacked with wrong size!
- fi
- # end of 'StdHdrs/rpc/c_types.h'
- fi
- if test -f 'StdHdrs/rpc/pmap_clnt.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'StdHdrs/rpc/pmap_clnt.h'\"
- else
- echo shar: Extracting \"'StdHdrs/rpc/pmap_clnt.h'\" \(3166 characters\)
- sed "s/^X//" >'StdHdrs/rpc/pmap_clnt.h' <<'END_OF_FILE'
- X/* @(#)pmap_clnt.h 2.1 88/07/29 4.0 RPCSRC; from 1.11 88/02/08 SMI */
- X/*
- X * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- X * unrestricted use provided that this legend is included on all tape
- X * media and as a part of the software program in whole or part. Users
- X * may copy or modify Sun RPC without charge, but are not authorized
- X * to license or distribute it to anyone else except as part of a product or
- X * program developed by the user.
- X *
- X * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- X * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- X * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- X *
- X * Sun RPC is provided with no support and without any obligation on the
- X * part of Sun Microsystems, Inc. to assist in its use, correction,
- X * modification or enhancement.
- X *
- X * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- X * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- X * OR ANY PART THEREOF.
- X *
- X * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- X * or profits or other special, indirect and consequential damages, even if
- X * Sun has been advised of the possibility of such damages.
- X *
- X * Sun Microsystems, Inc.
- X * 2550 Garcia Avenue
- X * Mountain View, California 94043
- X */
- X
- X/*
- X * pmap_clnt.h
- X * Supplies C routines to get to portmap services.
- X *
- X * Copyright (C) 1984, Sun Microsystems, Inc.
- X */
- X
- X/*
- X * Usage:
- X * success = pmap_set(program, version, protocol, port);
- X * success = pmap_unset(program, version);
- X * port = pmap_getport(address, program, version, protocol);
- X * head = pmap_getmaps(address);
- X * clnt_stat = pmap_rmtcall(address, program, version, procedure,
- X * xdrargs, argsp, xdrres, resp, tout, port_ptr)
- X * (works for udp only.)
- X * clnt_stat = clnt_broadcast(program, version, procedure,
- X * xdrargs, argsp, xdrres, resp, eachresult)
- X * (like pmap_rmtcall, except the call is broadcasted to all
- X * locally connected nets. For each valid response received,
- X * the procedure eachresult is called. Its form is:
- X * done = eachresult(resp, raddr)
- X * bool_t done;
- X * caddr_t resp;
- X * struct sockaddr_in raddr;
- X * where resp points to the results of the call and raddr is the
- X * address if the responder to the broadcast.
- X */
- X
- X#ifndef _rpc_pmap_clnt_h
- X#define _rpc_pmap_clnt_h
- X
- X#include <rpc/c_types.h>
- X
- XEXTERN_FUNCTION(bool_t pmap_set, (u_long prognum, u_long versnum,
- X int protocol, u_short port));
- XEXTERN_FUNCTION(bool_t pmap_unset, (u_long prognum, u_long versnum));
- XEXTERN_FUNCTION(struct pmaplist *pmap_getmaps, (struct sockaddr_in *addr));
- XEXTERN_FUNCTION(enum clnt_stat pmap_rmtcall, (struct sockaddr_in *addr,
- X u_long prognum, u_long versnum,
- X u_long procnum,
- X char *in, char *out,
- X xdrproc_t inproc,
- X xdrproc_t outproc,
- X struct timeval timeout,
- X u_long *portp));
- XEXTERN_FUNCTION(enum clnt_stat clnt_broadcast, ());
- XEXTERN_FUNCTION(u_short pmap_getport, (struct sockaddr_in *addr,
- X u_long prognum, u_long versnum,
- X u_long protocol));
- X
- X#endif /*!_rpc_pmap_clnt_h*/
- END_OF_FILE
- if test 3166 -ne `wc -c <'StdHdrs/rpc/pmap_clnt.h'`; then
- echo shar: \"'StdHdrs/rpc/pmap_clnt.h'\" unpacked with wrong size!
- fi
- # end of 'StdHdrs/rpc/pmap_clnt.h'
- fi
- if test -f 'callback.cc' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'callback.cc'\"
- else
- echo shar: Extracting \"'callback.cc'\" \(1312 characters\)
- sed "s/^X//" >'callback.cc' <<'END_OF_FILE'
- X// -*- c++ -*-
- X/*
- Copyright (C) 1991 Peter Bersen
- X
- This file is part of the rpc++ Library. This library is free
- software; you can redistribute it and/or modify it under the terms of
- the GNU Library General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your
- option) any later version. This library is distributed in the hope
- that it will be useful, but WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE. See the GNU Library General Public License for more details.
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free Software
- XFoundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- X
- Modified and partially rewritten March 1992 by Michael N. Lipp,
- mnl@dtro.e-technik.th-darmstadt.de. The original copyright terms and
- conditions apply without change to any modified or new parts.
- X*/
- X
- static char _rpcpp_callback_cc_[]
- X= "callback.cc,v 2.2 1992/06/15 19:12:37 mnl Exp";
- X
- X// callback.cc,v
- X// Revision 2.2 1992/06/15 19:12:37 mnl
- X// Fixed a few bugs, clarified interface.
- X//
- X// Revision 2.1.1.1 1992/03/08 13:28:42 mnl
- X// Initial mnl version.
- X//
- X
- X#ifdef __GNUG__
- X#pragma implementation
- X#endif
- X
- X#include "rpc++/callback.h"
- X
- END_OF_FILE
- if test 1312 -ne `wc -c <'callback.cc'`; then
- echo shar: \"'callback.cc'\" unpacked with wrong size!
- fi
- # end of 'callback.cc'
- fi
- if test ! -d 'example' ; then
- echo shar: Creating directory \"'example'\"
- mkdir 'example'
- fi
- if test -f 'example/.cvsignore' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'example/.cvsignore'\"
- else
- echo shar: Extracting \"'example/.cvsignore'\" \(28 characters\)
- sed "s/^X//" >'example/.cvsignore' <<'END_OF_FILE'
- X.dependencies
- server
- client
- END_OF_FILE
- if test 28 -ne `wc -c <'example/.cvsignore'`; then
- echo shar: \"'example/.cvsignore'\" unpacked with wrong size!
- fi
- # end of 'example/.cvsignore'
- fi
- if test -f 'example/Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'example/Makefile'\"
- else
- echo shar: Extracting \"'example/Makefile'\" \(874 characters\)
- sed "s/^X//" >'example/Makefile' <<'END_OF_FILE'
- TOP = ..
- SUBDIRS =
- X
- CC = gcc
- CPPFLAGS = -I..
- CFLAGS = -ggdb
- C++FLAGS = $(CFLAGS)
- X# for Linux:
- LOADLIBES = -L.. -lrpc++ -nojump -lg++
- X# for SunOS:
- X#LOADLIBES = -L.. -lrpc++ -lg++
- X# for ISC 2.2:
- X#LOADLIBES = -L.. -lrpc++ -lrpclib -lmisc -lg++ -linet -liberty
- X
- X
- HDRS = calcsvc.h
- SRCS = server.cc client.cc calcsvc.cc
- X
- all:: server client
- X
- server: server.o calcsvc.o
- X $(CC) -o $@ server.o calcsvc.o $(LOADLIBES)
- X
- client: client.o calcsvc.o
- X $(CC) -o $@ client.o calcsvc.o $(LOADLIBES)
- X
- DISTLIST = Makefile $(HDRS) $(SRCS)
- X
- clean::
- X rm -f $(CLEANWILDCARDS) server client
- X
- include .dependencies
- X
- X.dependencies: $(HDRS) $(SRCS)
- X gcc -M $(CPPFLAGS) $(SRCS) > .dependencies
- X
- distlist::
- X @for f in *.[ch] *.cc; do \
- X if expr " $(DISTLIST) " : ".* $$f " >/dev/null; then : ; \
- X else echo 1>&2 "Warning: c- or h-file \"$$f\" not in DISTLIST"; fi; \
- X done
- X
- include $(TOP)/Proj.make
- END_OF_FILE
- if test 874 -ne `wc -c <'example/Makefile'`; then
- echo shar: \"'example/Makefile'\" unpacked with wrong size!
- fi
- # end of 'example/Makefile'
- fi
- if test -f 'example/calcsvc.cc' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'example/calcsvc.cc'\"
- else
- echo shar: Extracting \"'example/calcsvc.cc'\" \(1107 characters\)
- sed "s/^X//" >'example/calcsvc.cc' <<'END_OF_FILE'
- X// -*- c++ -*-
- static char _calcsvc_cc_[]
- X= "calcsvc.cc,v 2.3 1992/06/15 19:13:13 mnl Exp";
- X
- X// calcsvc.cc,v
- X// Revision 2.3 1992/06/15 19:13:13 mnl
- X// Fixed a few bugs, clarified interface.
- X//
- X// Revision 2.2 1992/06/13 14:27:28 mnl
- X// Adapted to (patched) gcc-2.2. Fixed several bugs.
- X//
- X// Revision 2.1.1.1 1992/03/08 13:28:45 mnl
- X// Initial mnl version.
- X//
- X
- X#include <stream.h>
- X#include "calcsvc.h"
- X
- XXdrInfo& Xmyint = Xdr::Xint;
- X
- RpcRequest CalcRequests::Add (1, &Xmyint, &Xdr::Xint, &Xdr::Xint);
- RpcRequest CalcRequests::Sub (2, &Xdr::Xint, &Xdr::Xint, &Xdr::Xint);
- RpcRequest CalcRequests::Times (3, &Xdr::Xint, &Xdr::Xint, &Xdr::Xint);
- RpcRequest CalcRequests::Div (4, &Xdr::Xint, &Xdr::Xint, &Xdr::Xint);
- RpcRequest CalcRequests::Inc (5, &Xdr::Xint, &Xdr::Xint);
- RpcRequest CalcRequests::IToA (6, &Xdr::Xwrapstring, &Xdr::Xint);
- RpcRequest CalcRequests::Reset (7, &Xdr::Xvoid);
- RpcRequest CalcRequests::Sleep (8, &Xdr::Xnull, &Xdr::Xint, RpcRequest::async);
- RpcRequest CalcRequests::Msg (9, &Xdr::Xvoid, &Xdr::Xwrapstring);
- RpcRequest CalcRequests::Invalid (100, &Xdr::Xvoid, &Xdr::Xvoid);
- END_OF_FILE
- if test 1107 -ne `wc -c <'example/calcsvc.cc'`; then
- echo shar: \"'example/calcsvc.cc'\" unpacked with wrong size!
- fi
- # end of 'example/calcsvc.cc'
- fi
- if test -f 'example/calcsvc.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'example/calcsvc.h'\"
- else
- echo shar: Extracting \"'example/calcsvc.h'\" \(751 characters\)
- sed "s/^X//" >'example/calcsvc.h' <<'END_OF_FILE'
- X// -*- c++ -*-
- X#ifndef _CALCSERVICE_H_
- X#define _CALCSERVICE_H_
- static char _calcsvc_h_[]
- X= "calcsvc.h,v 2.3 1992/06/15 19:13:15 mnl Exp";
- X
- X// calcsvc.h,v
- X// Revision 2.3 1992/06/15 19:13:15 mnl
- X// Fixed a few bugs, clarified interface.
- X//
- X
- X#ifdef __GNUG__
- X#pragma interface
- X#endif
- X
- X#include "rpc++/request.h"
- X
- X#define CALCSVC 0x20100001
- X
- struct CalcRequests
- X{
- X static RpcRequest Add;
- X static RpcRequest Sub;
- X static RpcRequest Times;
- X static RpcRequest Div;
- X static RpcRequest Inc;
- X static RpcRequest IToA;
- X static RpcRequest Reset; // for testing proc without args
- X static RpcRequest Sleep; // for testing async
- X static RpcRequest Msg; // for testing string passing
- X static RpcRequest Invalid; // for testing error handling
- X};
- X
- X#endif
- END_OF_FILE
- if test 751 -ne `wc -c <'example/calcsvc.h'`; then
- echo shar: \"'example/calcsvc.h'\" unpacked with wrong size!
- fi
- # end of 'example/calcsvc.h'
- fi
- if test -f 'example/client.cc' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'example/client.cc'\"
- else
- echo shar: Extracting \"'example/client.cc'\" \(1635 characters\)
- sed "s/^X//" >'example/client.cc' <<'END_OF_FILE'
- X// -*- c++ -*-
- static char _client_cc_[]
- X= "client.cc,v 2.3 1992/06/15 19:13:17 mnl Exp";
- X
- X// client.cc,v
- X// Revision 2.3 1992/06/15 19:13:17 mnl
- X// Fixed a few bugs, clarified interface.
- X//
- X// Revision 2.2 1992/06/13 14:27:32 mnl
- X// Adapted to (patched) gcc-2.2. Fixed several bugs.
- X//
- X// Revision 2.1.1.1 1992/03/08 13:28:45 mnl
- X// Initial mnl version.
- X//
- X
- X#include <stream.h>
- X#include "rpc++/stub.h"
- X
- X#include "calcsvc.h"
- X
- class CalcStub : public RpcStub
- X{
- public:
- X inline CalcStub (u_long prognum, u_long versnum,
- X char* hostname = "localhost",
- X timeval timeout = defaultTimeout, bool connect = TRUE)
- X : RpcStub (prognum, versnum, hostname, timeout, connect) {}
- X
- X inline void Reset ()
- X { Call (CalcRequests::Reset); }
- X inline int Inc (int i)
- X { return *(int*)Call (CalcRequests::Inc, &i); }
- X inline char* IToA (int i)
- X { return *(char**)Call (CalcRequests::IToA, &i); }
- X inline int Add (int s1, int s2)
- X { return *(int*)Call (CalcRequests::Add, &s1, &s2); }
- X
- X inline void Msg (char* msg)
- X { Call (CalcRequests::Msg, &msg); }
- X inline void Sleep (int secs)
- X { Call (CalcRequests::Sleep, &secs); }
- X};
- X
- main (int argc, char* argv[])
- X{
- X char* server = argv[1];
- X
- X CalcStub svc (CALCSVC, 1, server);
- X svc.Reset ();
- X svc.Msg ("Hello server.\n");
- X int i = 0, o;
- X while (i < 10)
- X {
- X o = svc.Inc (i);
- X cout << svc.IToA (o) << '\n';
- X i = o;
- X }
- X i = svc.Add (12, 23);
- X cout << "add (" << 12 << ", " << 23 << ") = " << i << endl;
- X cout << "Calling Sleep (5) asynchronously.\n";
- X svc.Sleep (5);
- X cout << "Sleep call completed.\n";
- X svc.Call (CalcRequests::Invalid);
- X}
- END_OF_FILE
- if test 1635 -ne `wc -c <'example/client.cc'`; then
- echo shar: \"'example/client.cc'\" unpacked with wrong size!
- fi
- # end of 'example/client.cc'
- fi
- if test -f 'example/server.cc' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'example/server.cc'\"
- else
- echo shar: Extracting \"'example/server.cc'\" \(2434 characters\)
- sed "s/^X//" >'example/server.cc' <<'END_OF_FILE'
- X// -*- c++ -*-
- static char _server_cc_[]
- X= "server.cc,v 2.3 1992/06/15 19:13:18 mnl Exp";
- X
- X// server.cc,v
- X// Revision 2.3 1992/06/15 19:13:18 mnl
- X// Fixed a few bugs, clarified interface.
- X//
- X// Revision 2.2 1992/06/13 14:27:33 mnl
- X// Adapted to (patched) gcc-2.2. Fixed several bugs.
- X//
- X// Revision 2.1.1.1 1992/03/08 13:28:45 mnl
- X// Initial mnl version.
- X//
- X
- X#include <unistd.h>
- X#include <stream.h>
- X#include <string.h>
- X#include <malloc.h>
- X
- X#include "rpc++/service.h"
- X#include "calcsvc.h"
- X
- class Calc
- X{
- public:
- X void* Add (void*, void*);
- X void* Sub (void*, void*);
- X void* Times (void*, void*);
- X void* Div (void*, void*);
- X void* Inc (void*);
- X void* IToA (void**);
- X void Reset (RpcService*);
- X};
- X
- void* Calc::Add (void* in1, void* in2)
- X{
- X static int res;
- X res = *(int*)in1 + *(int*)in2;
- X return &res;
- X}
- X
- void* Calc::Sub (void* in1, void* in2)
- X{
- X static int res;
- X res = *(int*)in1 - *(int*)in2;
- X return &res;
- X}
- X
- void* Calc::Times (void* in1, void* in2)
- X{
- X static int res;
- X res = *(int*)in1 * *(int*)in2;
- X return &res;
- X}
- X
- void* Calc::Div (void* in1, void* in2)
- X{
- X static int res;
- X res = *(int*)in1 / *(int*)in2;
- X return &res;
- X}
- X
- void* Calc::Inc (void* in)
- X{
- X static int res;
- X res = *(int*)in + 1;
- X return &res;
- X}
- X
- void* Calc::IToA (void** in)
- X{
- X static char *s = 0;
- X delete s;
- X char *t = form ("%d", *(int*)in[0]);
- X s = new char[strlen (t) + 1];
- X strcpy (s, t);
- X return &s;
- X}
- X
- void Calc::Reset (RpcService* svc)
- X{
- X cout << "Received reset from " << svc->CallerName () << ".\n";
- X}
- X
- void printMessage (void* in)
- X{
- X cout << *(char**)in;
- X}
- X
- void doSleep (void* in)
- X{
- X cout << form ("Sleeping %d secs.\n", *(int*)in);
- X sleep (*(int*)in);
- X cout << "Woke up.\n";
- X}
- X
- main ()
- X{
- X RpcService svc (CALCSVC, 1);
- X Calc calc;
- X svc.Register (CalcRequests::Add, RpcMethodCall<Calc> (&calc, &calc.Add));
- X svc.Register (CalcRequests::Sub, RpcMethodCall<Calc> (&calc, &calc.Sub));
- X svc.Register (CalcRequests::Times, RpcMethodCall<Calc> (&calc, &calc.Times));
- X svc.Register (CalcRequests::Div, RpcMethodCall<Calc> (&calc, &calc.Div));
- X svc.Register (CalcRequests::Inc, RpcMethodCall<Calc> (&calc, &calc.Inc));
- X svc.Register (CalcRequests::IToA,RpcMethodCall<Calc>(&calc, &calc.IToA));
- X svc.Register (CalcRequests::Reset, RpcMethodCall<Calc> (&calc, &calc.Reset));
- X svc.Register (CalcRequests::Msg, RpcCallback (printMessage));
- X svc.Register (CalcRequests::Sleep, RpcCallback (doSleep));
- X svc.Provide ();
- X}
- END_OF_FILE
- if test 2434 -ne `wc -c <'example/server.cc'`; then
- echo shar: \"'example/server.cc'\" unpacked with wrong size!
- fi
- # end of 'example/server.cc'
- fi
- if test -f 'gcc-2.2.fix' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'gcc-2.2.fix'\"
- else
- echo shar: Extracting \"'gcc-2.2.fix'\" \(8606 characters\)
- sed "s/^X//" >'gcc-2.2.fix' <<'END_OF_FILE'
- To: bug-g++@prep.ai.mit.edu
- Subject: gcc-2.2 loops with template-local typedefs (bug&patch)
- BCC: mnl,ulf
- X--text follows this line--
- Hi,
- X
- trying to translate the following fragment on a Sparc running SunOs 4.1.2
- with gcc-2.2 results in gcc infinitly looping.
- X
- X---------------------------------------------------------------------------
- X// -*- c++ -*-
- X
- class AnyRpcCallback
- X{
- protected:
- X
- public:
- X inline virtual ~AnyRpcCallback () {}
- X inline virtual void Do (void* in, void* out) = 0;
- X};
- X
- template<class T> class RpcCallback : public AnyRpcCallback
- X{
- X typedef void (T::*Method)(void*, void*);
- X typedef void (T::*MethodN)(void*, void**);
- X typedef void (T::*Method1)(void*, void*);
- X typedef void (T::*Method2)(void*, void*, void*);
- X
- private:
- X T* object;
- X void (T::*method)(void*, void*);
- X
- public:
- X inline RpcCallback (T* o, void* m)
- X { object = o; method = m; }
- X inline void Do (void* in, void* out)
- X { (object->*method)(in, out); }
- X};
- X
- class Test
- X{
- public:
- X void m (void*, void*);
- X};
- X
- main ()
- X{
- X Test o;
- X AnyRpcCallback* cb = new RpcCallback<Test> (&o, &Test::m);
- X}
- X---------------------------------------------------------------------------
- X
- PLEASE NOTE that you will get another loop due to a bug that I have
- reported together with a patch earlier (it's appended to this mail).
- So you won't be able to reproduce the bug reported in this mail unless
- you have my previous patch applied. I am, however, definitely sure
- X(and the explanation below will confirm it) that the bug reported in
- this mail is *NOT* caused by my patch!
- X
- The problem is, that the "chain" field of the tree-nodes used by gcc
- for its internal representation is used for various purposes, and in
- the case of this template-local typedef, someone lost track of its usage.
- X
- After parsing, the TYPE_DECL-node created for the typedef is appended
- to the scope via "pushlevel". Types in the current scope are linked
- using the "chain" field. At the same time, however, all components of
- the template are linked together during parsing using the same "chain"
- field. Parsing the second typedef, "pushlevel" makes the first typedef
- a successor of the second typedef and the subsequent catenation of
- components makes the second typedef a successor of the first typedef
- thus creating a loop.
- X
- The resulting list of all components is used in routine
- X"finish_struct".
- X
- I think the most proper approach would be to use TREE_LIST nodes in
- the list of components as indirect references to the typedef-nodes.
- This is easy to achieve, it is, however, very hard to modify
- finish_struct in a way that it handles these indirection properly.
- Actually, I gave up when I tried to understand & modify the routine
- that removes the duplicate declarations from the list of components.
- X
- There are two easier approaches: (1) Don't include typedefs in the
- list of components, (2) use copies of the typedef-node which have an
- unused chain field. The first approach assumes that finish_struct
- doesn't do anything with typedefs, so it wouldn't be important if they
- are missing from the list of components. If this is the case, however,
- it can't hurt to use copies of the typedef-nodes (copies of the
- originals that are linked in the scope-list), so the second approach
- is safer. It can only fail if finish_struct modifies the typedef-nodes
- and this modification is significant for the typedef-nodes in the
- scope-list (which are, of course, not modified. Only the copies are).
- X
- So I think the patch is pretty safe. It fixes the problem and doesn't
- seem to introduce new ones. I'm aware that typedefs that are local to
- templates stretch language features to the limits, but it makes my
- C++ interface to RPCs real nice (I'll post it one of these days).
- X
- Michael
- X
- X*** .orig/cp-parse.y Mon Jun 15 17:08:58 1992
- X--- cp-parse.y Mon Jun 15 19:13:15 1992
- X***************
- X*** 2211,2217 ****
- X if (TREE_CODE (t) == ENUMERAL_TYPE && TREE_NONLOCAL_FLAG (t))
- X $$ = grok_enum_decls (t, $2);
- X else
- X! $$ = $2;
- X }
- X end_exception_decls ();
- X }
- X--- 2211,2233 ----
- X if (TREE_CODE (t) == ENUMERAL_TYPE && TREE_NONLOCAL_FLAG (t))
- X $$ = grok_enum_decls (t, $2);
- X else
- X! {
- X! /* if a component is a typedef, it is inserted
- X! in the list of nodes that make up the valid
- X! types in the scope. Thus its chain field is
- X! used and can't be used a second time for linking
- X! the components of the struct. So, we make a copy
- X! here. This apparently works. The proper thing
- X! to do, however, would be to use a TREE_LIST
- X! node to reference the typedef. I tried to rewrite
- X! finish_struct accordingly (i.e., ``dereference''
- X! components TREE_LIST before use, but I gave up.
- X! mnl@dtro.e-technik.th-darmstadt.de */
- X! if (TREE_CODE ($2) == TYPE_DECL)
- X! $$ = copy_node ($2);
- X! else
- X! $$ = $2;
- X! }
- X }
- X end_exception_decls ();
- X }
- X
- X===========================================================================
- The previous bug:
- X---------------------------------------------------------------------------
- Return-Path: <mnl>
- Date: Wed, 10 Jun 92 19:31:13 +0200
- XFrom: "Michael N. Lipp" <mnl>
- To: bug-g++@prep.ai.mit.edu
- Subject: gcc-2.2 bug&patch: typedef in template
- X
- Hi,
- X
- gcc-2.2 on a sparc running SunOS 4.1.2 enters an infinite loop when
- compiling this:
- X
- X-----------------------------------------------------------------------------
- X// -*- c++ -*-
- X
- class AnyRpcCallback
- X{
- protected:
- X
- public:
- X inline virtual ~AnyRpcCallback () {}
- X inline virtual void Do (void* in, void* out) = 0;
- X};
- X
- template<class T> class RpcCallback : public AnyRpcCallback
- X{
- X typedef void (T::*Method)(void*, void*);
- X
- private:
- X T* object;
- X void (T::*method)(void*, void*);
- X
- public:
- X inline RpcCallback (T* o, void* m)
- X { object = o; method = m; }
- X inline void Do (void* in, void* out)
- X { (object->*method)(in, out); }
- X};
- X
- class Test
- X{
- public:
- X void m (void*, void*);
- X};
- X
- main ()
- X{
- X Test o;
- X AnyRpcCallback* cb = new RpcCallback<Test> (&o, &Test::m);
- X}
- X-----------------------------------------------------------------------------
- X
- This is quite an improvement over gcc-2.1 which dumped core with this
- source.
- X
- I tracked the cause down: grokdeclarator does a pushlevel(0), then
- calls start_decl, which in turn calls grokdeclarator again which does
- a poplevel_class. This poplevel_class pops the level pushed by
- pushlevel(0) and so the poplevel performed by grokdeclarator to match
- its pushlevel(0) pops quite a different level! This can easily be
- observed by compiling cp-decl.c with -DDEBUG_CP_BINDING_LEVELS.
- X
- Here is a patch that fixes the bug. I don't think it hits the real
- cause of this problem, but it works.
- X
- X*** .orig/cp-decl.c Wed Jun 10 14:06:26 1992
- X--- cp-decl.c Wed Jun 10 15:20:38 1992
- X***************
- X*** 6874,6882 ****
- X--- 6874,6889 ----
- X tree loc_typedecl;
- X register int i = sizeof (struct lang_decl_flags) / sizeof (int);
- X register int *pi;
- X+ struct binding_level *local_binding_level;
- X
- X /* keep `grokdeclarator' from thinking we are in PARM context. */
- X pushlevel (0);
- X+ /* poplevel_class may be called by grokdeclarator which is called in
- X+ start_decl which is called below. In this case, our pushed level
- X+ may vanish and poplevel mustn't be called. So remember what we
- X+ have pushed and pop only if that is matched by
- X+ current_binding_level later. mnl@dtro.e-technik.th-darmstadt.de */
- X+ local_binding_level = current_binding_level;
- X loc_typedecl = start_decl (declarator, declspecs, initialized, NULL_TREE);
- X
- X pi = (int *) permalloc (sizeof (struct lang_decl_flags));
- X***************
- X*** 6883,6889 ****
- X while (i > 0)
- X pi[--i] = 0;
- X DECL_LANG_SPECIFIC (loc_typedecl) = (struct lang_decl *) pi;
- X! poplevel (0, 0, 0);
- X
- X #if 0
- X if (TREE_CODE (TREE_TYPE (loc_typedecl)) == ENUMERAL_TYPE)
- X--- 6890,6897 ----
- X while (i > 0)
- X pi[--i] = 0;
- X DECL_LANG_SPECIFIC (loc_typedecl) = (struct lang_decl *) pi;
- X! if (current_binding_level == local_binding_level)
- X! poplevel (0, 0, 0);
- X
- X #if 0
- X if (TREE_CODE (TREE_TYPE (loc_typedecl)) == ENUMERAL_TYPE)
- X
- Michael
- X
- X-----------------,------------------------------,------------------------------
- Michael N. Lipp ! Institut fuer Datentechnik ! Phone: 49-6151-163776
- X ! Merckstr. 25 ,----------' Fax: 49-6151-164976
- X ! D-6100 Darmstadt ! E-Mail:
- X ! (Germany) ! mnl@dtro.e-technik.th-darmstadt.de
- X-----------------'-------------------'-----------------------------------------
- X
- END_OF_FILE
- if test 8606 -ne `wc -c <'gcc-2.2.fix'`; then
- echo shar: \"'gcc-2.2.fix'\" unpacked with wrong size!
- fi
- # end of 'gcc-2.2.fix'
- fi
- if test -f 'gcc-2.3.3.fix' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'gcc-2.3.3.fix'\"
- else
- echo shar: Extracting \"'gcc-2.3.3.fix'\" \(7716 characters\)
- sed "s/^X//" >'gcc-2.3.3.fix' <<'END_OF_FILE'
- There are two bugs in gcc-2.3.3 that I have reported together with
- fixes for gcc-2.2.2 previously. The first bug is commented now (but
- not fixed), the second isn't fixed either (I can understand that. It
- is hard to do it properly). I'm repeating the bug report below
- together with new context diffs. Please note that I have not
- re-debugged, I have simply found that the same patches make things
- work. So maybe the comments are out of date.
- X
- Bug1:
- X
- Compiling this
- X--------------------------------------------------
- X// -*- c++ -*-
- X
- class AnyRpcCallback
- X{
- protected:
- X
- public:
- X inline virtual ~AnyRpcCallback () {}
- X inline virtual void Do (void* in, void* out) = 0;
- X};
- X
- template<class T> class RpcCallback : public AnyRpcCallback
- X{
- X typedef void (T::*Method)(void*, void*);
- X
- private:
- X T* object;
- X void (T::*method)(void*, void*);
- X
- public:
- X inline RpcCallback (T* o, void* m)
- X { object = o; method = m; }
- X inline void Do (void* in, void* out)
- X { (object->*method)(in, out); }
- X};
- X
- class Test
- X{
- public:
- X void m (void*, void*);
- X};
- X
- void Test::m (void*, void*)
- X{
- X}
- X
- main ()
- X{
- X Test o;
- X AnyRpcCallback* cb = new RpcCallback<Test> (&o, &Test::m);
- X}
- X--------------------------------------------------
- results in cc1plus looping infinitely.
- X
- I tracked the cause down: grokdeclarator does a pushlevel(0), then
- calls start_decl, which in turn calls grokdeclarator again which does
- a poplevel_class. This poplevel_class pops the level pushed by
- pushlevel(0) and so the poplevel performed by grokdeclarator to match
- its pushlevel(0) pops quite a different level! This can easily be
- observed by compiling cp-decl.c with -DDEBUG_CP_BINDING_LEVELS.
- X
- In gcc-2.3.3 the problem seems to be known as it is commented.
- X
- Here is a patch that fixes the bug. I don't think it hits the real
- cause of this problem, but it works.
- X
- X*** cp-decl.c.orig Sat Jan 2 15:04:20 1993
- X--- cp-decl.c Sat Jan 2 15:06:18 1993
- X***************
- X*** 7245,7253 ****
- X--- 7245,7260 ----
- X tree loc_typedecl;
- X register int i = sizeof (struct lang_decl_flags) / sizeof (int);
- X register int *pi;
- X+ struct binding_level *local_binding_level;
- X
- X /* keep `grokdeclarator' from thinking we are in PARM context. */
- X pushlevel (0);
- X+ /* poplevel_class may be called by grokdeclarator which is called in
- X+ start_decl which is called below. In this case, our pushed level
- X+ may vanish and poplevel mustn't be called. So remember what we
- X+ have pushed and pop only if that is matched by
- X+ current_binding_level later. mnl@dtro.e-technik.th-darmstadt.de */
- X+ local_binding_level = current_binding_level;
- X loc_typedecl = start_decl (declarator, declspecs, initialized, NULL_TREE);
- X
- X pi = (int *) permalloc (sizeof (struct lang_decl_flags));
- X***************
- X*** 7256,7262 ****
- X DECL_LANG_SPECIFIC (loc_typedecl) = (struct lang_decl *) pi;
- X /* This poplevel conflicts with the popclass over in
- X grokdeclarator. See ``This popclass conflicts'' */
- X! poplevel (0, 0, 0);
- X
- X #if 0
- X if (TREE_CODE (TREE_TYPE (loc_typedecl)) == ENUMERAL_TYPE)
- X--- 7263,7270 ----
- X DECL_LANG_SPECIFIC (loc_typedecl) = (struct lang_decl *) pi;
- X /* This poplevel conflicts with the popclass over in
- X grokdeclarator. See ``This popclass conflicts'' */
- X! if (current_binding_level == local_binding_level)
- X! poplevel (0, 0, 0);
- X
- X #if 0
- X if (TREE_CODE (TREE_TYPE (loc_typedecl)) == ENUMERAL_TYPE)
- X
- Bug2:
- X
- Compiling this
- X--------------------------------------------------
- X// -*- c++ -*-
- X
- class AnyRpcCallback
- X{
- protected:
- X
- public:
- X inline virtual ~AnyRpcCallback () {}
- X inline virtual void Do (void* in, void* out) = 0;
- X};
- X
- template<class T> class RpcCallback : public AnyRpcCallback
- X{
- X typedef void (T::*Method)(void*, void*);
- X typedef void (T::*MethodN)(void*, void**);
- X typedef void (T::*Method1)(void*, void*);
- X typedef void (T::*Method2)(void*, void*, void*);
- X
- private:
- X T* object;
- X void (T::*method)(void*, void*);
- X
- public:
- X inline RpcCallback (T* o, void* m)
- X { object = o; method = m; }
- X inline void Do (void* in, void* out)
- X { (object->*method)(in, out); }
- X};
- X
- class Test
- X{
- public:
- X void m (void*, void*);
- X};
- X
- main ()
- X{
- X Test o;
- X AnyRpcCallback* cb = new RpcCallback<Test> (&o, &Test::m);
- X}
- X--------------------------------------------------
- results in cc1plus looping infinitely.
- X
- The problem is that the "chain" field of the tree-nodes used by gcc
- for its internal representation is used for various purposes, and in
- the case of this template-local typedef, someone lost track of its usage.
- X
- After parsing, the TYPE_DECL-node created for the typedef is appended
- to the scope via "pushlevel". Types in the current scope are linked
- using the "chain" field. At the same time, however, all components of
- the template are linked together during parsing using the same "chain"
- field. Parsing the second typedef, "pushlevel" makes the first typedef
- a successor of the second typedef and the subsequent catenation of
- components makes the second typedef a successor of the first typedef
- thus creating a loop.
- X
- The resulting list of all components is used in routine
- X"finish_struct".
- X
- I think the most proper approach would be to use TREE_LIST nodes in
- the list of components as indirect references to the typedef-nodes.
- This is easy to achieve, it is, however, very hard to modify
- finish_struct in a way that it handles these indirection properly.
- Actually, I gave up when I tried to understand & modify the routine
- that removes the duplicate declarations from the list of components.
- X
- There are two easier approaches: (1) Don't include typedefs in the
- list of components, (2) use copies of the typedef-node which have an
- unused chain field. The first approach assumes that finish_struct
- doesn't do anything with typedefs, so it wouldn't be important if they
- are missing from the list of components. If this is the case, however,
- it can't hurt to use copies of the typedef-nodes (copies of the
- originals that are linked in the scope-list), so the second approach
- is safer. It can only fail if finish_struct modifies the typedef-nodes
- and this modification is significant for the typedef-nodes in the
- scope-list (which are, of course, not modified. Only the copies are).
- X
- So I think the patch is pretty safe. It fixes the problem and doesn't
- seem to introduce new ones. I'm aware that typedefs that are local to
- templates stretch language features to the limits, but it makes my
- C++ interface to RPCs real nice.
- X
- X*** cp-parse.y.orig Sat Jan 2 15:17:13 1993
- X--- cp-parse.y Sat Jan 2 15:18:13 1993
- X***************
- X*** 2335,2341 ****
- X if (TREE_CODE (t) == ENUMERAL_TYPE && TREE_NONLOCAL_FLAG (t))
- X $$ = grok_enum_decls (t, $2);
- X else
- X! $$ = $2;
- X }
- X end_exception_decls ();
- X }
- X--- 2335,2357 ----
- X if (TREE_CODE (t) == ENUMERAL_TYPE && TREE_NONLOCAL_FLAG (t))
- X $$ = grok_enum_decls (t, $2);
- X else
- X! {
- X! /* if a component is a typedef, it is inserted
- X! in the list of nodes that make up the valid
- X! types in the scope. Thus its chain field is
- X! used and can't be used a second time for linking
- X! the components of the struct. So, we make a copy
- X! here. This apparently works. The proper thing
- X! to do, however, would be to use a TREE_LIST
- X! node to reference the typedef. I tried to rewrite
- X! finish_struct accordingly (i.e., ``dereference''
- X! components TREE_LIST before use, but I gave up.
- X! mnl@dtro.e-technik.th-darmstadt.de */
- X! if (TREE_CODE ($2) == TYPE_DECL)
- X! $$ = copy_node ($2);
- X! else
- X! $$ = $2;
- X! }
- X }
- X end_exception_decls ();
- X }
- END_OF_FILE
- if test 7716 -ne `wc -c <'gcc-2.3.3.fix'`; then
- echo shar: \"'gcc-2.3.3.fix'\" unpacked with wrong size!
- fi
- # end of 'gcc-2.3.3.fix'
- fi
- if test -f 'request.cc' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'request.cc'\"
- else
- echo shar: Extracting \"'request.cc'\" \(4750 characters\)
- sed "s/^X//" >'request.cc' <<'END_OF_FILE'
- X// -*- c++ -*-
- X/*
- Copyright (C) 1991 Peter Bersen
- X
- This file is part of the rpc++ Library. This library is free
- software; you can redistribute it and/or modify it under the terms of
- the GNU Library General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your
- option) any later version. This library is distributed in the hope
- that it will be useful, but WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE. See the GNU Library General Public License for more details.
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free Software
- XFoundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- X
- Modified and partially rewritten March 1992 by Michael N. Lipp,
- mnl@dtro.e-technik.th-darmstadt.de. The original copyright terms and
- conditions apply without change to any modified or new parts.
- X*/
- X
- static char _rpcpp_request_cc_[]
- X= "request.cc,v 2.4 1992/08/08 13:11:40 mnl Exp";
- X
- X// request.cc,v
- X// Revision 2.4 1992/08/08 13:11:40 mnl
- X// RpcRequest(const RpcRequest&) added, 'cause RpcRequest has pointers
- X// to heap.
- X//
- X// Revision 2.3 1992/06/15 19:12:39 mnl
- X// Fixed a few bugs, clarified interface.
- X//
- X// Revision 2.2 1992/06/13 14:27:01 mnl
- X// Adapted to (patched) gcc-2.2. Fixed several bugs.
- X//
- X// Revision 2.1.1.1 1992/03/08 13:28:42 mnl
- X// Initial mnl version.
- X//
- X
- X#ifdef __GNUG__
- X#pragma implementation
- X#endif
- X
- X#include "rpc++/request.h"
- X
- X#include <assert.h>
- X
- void RpcRequest::init (u_long req, int pars, int parsz,
- X const XdrInfo* out, const XdrInfo** in, int rt)
- X{
- X params = pars;
- X parmsz = parsz;
- X reqnum = req;
- X ininfo = in;
- X ininfo[params] = (XdrInfo*)0;
- X outinfo = out;
- X reqtype = rt;
- X assert (rt == normal || outinfo->Proc () == 0);
- X}
- X
- RpcRequest::RpcRequest (const RpcRequest& r)
- X{
- X params = r.params;
- X parmsz = r.parmsz;
- X reqnum = r.reqnum;
- X ininfo = new XdrInfo*[params + 1];
- X memcpy (ininfo, r.ininfo, (params + 1) * sizeof (XdrInfo*));
- X outinfo = r.outinfo;
- X reqtype = r.reqtype;
- X}
- X
- RpcRequest::RpcRequest(u_long req, const XdrInfo* out, int t)
- X{
- X init (req, 0, 0, out, new XdrInfo*[1], t);
- X}
- X
- RpcRequest::RpcRequest(u_long req, const XdrInfo* out, const XdrInfo* in,
- X int t)
- X{
- X const XdrInfo** a = new XdrInfo*[2];
- X a[0] = in;
- X init (req, 1, -1, out, a, t);
- X}
- X
- RpcRequest::RpcRequest(u_long req, const XdrInfo* out, const XdrInfo* in0,
- X const XdrInfo* in1, int t)
- X{
- X const XdrInfo** a = new XdrInfo*[3];
- X a[0] = in0;
- X a[1] = in1;
- X init (req, 2, -1, out, a, t);
- X}
- X
- RpcRequest::RpcRequest(u_long req, const XdrInfo* out, const XdrInfo* in0,
- X const XdrInfo* in1, const XdrInfo* in2, int t)
- X{
- X const XdrInfo** a = new XdrInfo*[4];
- X a[0] = in0;
- X a[1] = in1;
- X a[2] = in2;
- X init (req, 3, -1, out, a, t);
- X}
- X
- RpcRequest::RpcRequest(u_long req, const XdrInfo* out, const XdrInfo* in0,
- X const XdrInfo* in1, const XdrInfo* in2,
- X const XdrInfo* in3, int t)
- X{
- X const XdrInfo** a = new XdrInfo*[5];
- X a[0] = in0;
- X a[1] = in1;
- X a[2] = in2;
- X a[3] = in3;
- X init (req, 4, -1, out, a, t);
- X}
- X
- RpcRequest::RpcRequest(u_long req, const XdrInfo* out, const XdrInfo* in0,
- X const XdrInfo* in1, const XdrInfo* in2,
- X const XdrInfo* in3, const XdrInfo* in4, int t)
- X{
- X const XdrInfo** a = new XdrInfo*[6];
- X a[0] = in0;
- X a[1] = in1;
- X a[2] = in2;
- X a[3] = in3;
- X a[4] = in4;
- X init (req, 5, -1, out, a, t);
- X}
- X
- RpcRequest::RpcRequest(u_long req, const XdrInfo* out, const XdrInfo* in0,
- X const XdrInfo* in1, const XdrInfo* in2,
- X const XdrInfo* in3, const XdrInfo* in4,
- X const XdrInfo* in5, int t)
- X{
- X const XdrInfo** a = new XdrInfo*[7];
- X a[0] = in0;
- X a[1] = in1;
- X a[2] = in2;
- X a[3] = in3;
- X a[4] = in4;
- X a[5] = in5;
- X init (req, 6, -1, out, a, t);
- X}
- X
- RpcRequest::RpcRequest(u_long req, const XdrInfo* out, const XdrInfo* in0,
- X const XdrInfo* in1, const XdrInfo* in2,
- X const XdrInfo* in3, const XdrInfo* in4,
- X const XdrInfo* in5, const XdrInfo *in6, int t)
- X{
- X const XdrInfo** a = new XdrInfo*[8];
- X a[0] = in0;
- X a[1] = in1;
- X a[2] = in2;
- X a[3] = in3;
- X a[4] = in4;
- X a[5] = in5;
- X a[6] = in6;
- X init (req, 7, -1, out, a, t);
- X}
- X
- RpcRequest::RpcRequest(u_long req, const XdrInfo* out, const XdrInfo** ins,
- X int t)
- X{
- X int pars = 0;
- X for (XdrInfo** p = ins; *p; p++)
- X pars += 1;
- X const XdrInfo** a = new XdrInfo* [pars + 1];
- X memcpy (a, ins, (pars + 1) * sizeof (XdrInfo*));
- X init (req, pars, -1, out, a, t);
- X}
- X
- int RpcRequest::ParamSize ()
- X{
- X if (parmsz < 0) // not yet calculated
- X {
- X parmsz = 0;
- X for (XdrInfo** ip = ininfo; *ip; ip++)
- X parmsz += (*ip)->Size ();
- X }
- X return parmsz;
- X}
- END_OF_FILE
- if test 4750 -ne `wc -c <'request.cc'`; then
- echo shar: \"'request.cc'\" unpacked with wrong size!
- fi
- # end of 'request.cc'
- fi
- if test ! -d 'rpc++' ; then
- echo shar: Creating directory \"'rpc++'\"
- mkdir 'rpc++'
- fi
- if test -f 'rpc++/request.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'rpc++/request.h'\"
- else
- echo shar: Extracting \"'rpc++/request.h'\" \(4511 characters\)
- sed "s/^X//" >'rpc++/request.h' <<'END_OF_FILE'
- X// -*- c++ -*-
- X/*
- Copyright (C) 1991 Peter Bersen
- X
- This file is part of the rpc++ Library. This library is free
- software; you can redistribute it and/or modify it under the terms of
- the GNU Library General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your
- option) any later version. This library is distributed in the hope
- that it will be useful, but WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE. See the GNU Library General Public License for more details.
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free Software
- XFoundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- X
- Modified and partially rewritten March 1992 by Michael N. Lipp,
- mnl@dtro.e-technik.th-darmstadt.de. The original copyright terms and
- conditions apply without change to any modified or new parts.
- X*/
- X
- X#ifndef _RPCREQUEST_H_
- X#define _RPCREQUEST_H_
- static char _rpcpp_request_h_[]
- X= "request.h,v 2.6 1993/01/20 15:00:49 mnl Exp";
- X
- X// request.h,v
- X// Revision 2.6 1993/01/20 15:00:49 mnl
- X// Updated for gcc-2.3.3.
- X//
- X// Revision 2.5 1992/12/06 18:58:12 mnl
- X// Fixed various bugs and added some Methods.
- X//
- X// Revision 2.4 1992/08/08 13:11:46 mnl
- X// RpcRequest(const RpcRequest&) added, 'cause RpcRequest has pointers
- X// to heap.
- X//
- X// Revision 2.3 1992/06/15 19:13:28 mnl
- X// Fixed a few bugs, clarified interface.
- X//
- X// Revision 2.2 1992/06/13 14:27:39 mnl
- X// Adapted to (patched) gcc-2.2. Fixed several bugs.
- X//
- X// Revision 2.1.1.1 1992/03/08 13:28:43 mnl
- X// Initial mnl version.
- X//
- X
- X#ifdef __GNUG__
- X#pragma interface
- X#endif
- X
- X#include "rpc++/xdr++.h"
- X#include <rpc/rpc.h>
- X
- X// RpcRequest is a class that specifies an individual request that is
- X// part of a service. Three parameters are required to specify a request:
- X// - the request number
- X// - the serializer (XdrInfo) for the input to the request
- X// - the serializer (XdrInfo) for the output from the request
- class RpcRequest
- X{
- private:
- X void init (u_long req, int pars, int parsz,
- X const XdrInfo* out, const XdrInfo** in, int rt);
- X
- public:
- X // Construct a new request from a request id, the information about
- X // the input data and the information about the output data.
- X // Note that requests that are registered for a service are stored
- X // in an array using the request id as the index, so keep indices
- X // small.
- X typedef enum { normal, batched, async } ReqType;
- X // No input arg:
- X RpcRequest (u_long req, const XdrInfo* out, int t = normal);
- X // One input arg:
- X RpcRequest (u_long req, const XdrInfo* out, const XdrInfo* in,
- X int t = normal);
- X // Two input args:
- X RpcRequest (u_long req, const XdrInfo* out, const XdrInfo*, const XdrInfo*,
- X int t = normal);
- X // ...
- X RpcRequest (u_long req, const XdrInfo* out, const XdrInfo*, const XdrInfo*,
- X const XdrInfo*, int t = normal);
- X RpcRequest (u_long req, const XdrInfo* out, const XdrInfo*, const XdrInfo*,
- X const XdrInfo*, const XdrInfo*, int t = normal);
- X RpcRequest (u_long req, const XdrInfo* out, const XdrInfo*, const XdrInfo*,
- X const XdrInfo*, const XdrInfo*, const XdrInfo*, int t = normal);
- X RpcRequest (u_long req, const XdrInfo* out, const XdrInfo*, const XdrInfo*,
- X const XdrInfo*, const XdrInfo*, const XdrInfo*, const XdrInfo*,
- X int t = normal);
- X RpcRequest (u_long req, const XdrInfo* out, const XdrInfo*, const XdrInfo*,
- X const XdrInfo*, const XdrInfo*, const XdrInfo*, const XdrInfo*,
- X const XdrInfo*, int t = normal);
- X // N input args, conversion routines given as a NULL terminated array
- X // of XdrInfo*:
- X RpcRequest (u_long req, const XdrInfo* out, const XdrInfo**, int t = normal);
- X // A copy
- X RpcRequest (const RpcRequest&);
- X ~RpcRequest ();
- X int RequestNumber () const;
- X const XdrInfo** InInfo ();
- X const XdrInfo* OutInfo ();
- X ReqType Type ();
- X int Params () const;
- X int ParamSize ();
- X
- protected:
- X int params;
- X int parmsz;
- X u_long reqnum;
- X const XdrInfo** ininfo;
- X const XdrInfo* outinfo;
- X ReqType reqtype;
- X};
- X
- inline RpcRequest::~RpcRequest ()
- X{ delete [] ininfo; }
- X
- inline int RpcRequest::Params () const
- X{ return params; }
- X
- inline int RpcRequest::RequestNumber () const
- X{ return reqnum; }
- X
- inline const XdrInfo** RpcRequest::InInfo ()
- X{ return ininfo; }
- X
- inline const XdrInfo* RpcRequest::OutInfo ()
- X{ return outinfo; }
- X
- inline RpcRequest::ReqType RpcRequest::Type ()
- X{ return reqtype; }
- X
- X#endif
- END_OF_FILE
- if test 4511 -ne `wc -c <'rpc++/request.h'`; then
- echo shar: \"'rpc++/request.h'\" unpacked with wrong size!
- fi
- # end of 'rpc++/request.h'
- fi
- if test -f 'rpc++/service.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'rpc++/service.h'\"
- else
- echo shar: Extracting \"'rpc++/service.h'\" \(4489 characters\)
- sed "s/^X//" >'rpc++/service.h' <<'END_OF_FILE'
- X// -*- c++ -*-
- X/*
- Copyright (C) 1991 Peter Bersen
- X
- This file is part of the rpc++ Library. This library is free
- software; you can redistribute it and/or modify it under the terms of
- the GNU Library General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your
- option) any later version. This library is distributed in the hope
- that it will be useful, but WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE. See the GNU Library General Public License for more details.
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free Software
- XFoundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- X
- Modified and partially rewritten March 1992 by Michael N. Lipp,
- mnl@dtro.e-technik.th-darmstadt.de. The original copyright terms and
- conditions apply without change to any modified or new parts.
- X*/
- X
- X#ifndef _RPCSERVICE_H_
- X#define _RPCSERVICE_H_
- static char _rpcpp_service_h_[]
- X= "service.h,v 2.5 1993/01/20 15:00:51 mnl Exp";
- X
- X// service.h,v
- X// Revision 2.5 1993/01/20 15:00:51 mnl
- X// Updated for gcc-2.3.3.
- X//
- X// Revision 2.4 1992/12/06 18:58:14 mnl
- X// Fixed various bugs and added some Methods.
- X//
- X// Revision 2.3 1992/06/15 19:13:30 mnl
- X// Fixed a few bugs, clarified interface.
- X//
- X// Revision 2.2 1992/06/13 14:27:41 mnl
- X// Adapted to (patched) gcc-2.2. Fixed several bugs.
- X//
- X// Revision 2.1.1.1 1992/03/08 13:28:43 mnl
- X// Initial mnl version.
- X//
- X
- X#ifdef __GNUG__
- X#pragma interface
- X#endif
- X
- X#undef TRUE
- X#undef FALSE
- X#include <bool.h>
- X#include "rpc++/request.h"
- X#include "rpc++/callback.h"
- X
- class RpcRegistered;
- X
- X//
- X// RpcService
- X//
- X
- class RpcService
- X{
- public:
- X typedef enum
- X { noError, reconstructionAttempt, cantCreateTCPService,
- X cantRegisterService, notRegistered, cantGetArgs,
- X invalidResult, cantSendReply, cantFreeArgs, selectError,
- X } errorCode;
- X
- X // Get state
- X inline virtual bool OK ()
- X { return errorState == noError; }
- X // Construct a service object for service prog, version vers
- X RpcService (u_long prog, u_long vers);
- X // Construct a transient service object for version vers
- X RpcService (u_long vers);
- X // Destruct the service
- X virtual ~RpcService ();
- X
- X // Get the program number (normally used after construction of transient)
- X u_long Program ();
- X virtual u_long ReserveService ();
- X
- X // Register an object and its method to be called on request
- X virtual void Register (const RpcRequest&, const AnyRpcCallback&);
- X virtual void Unregister (const RpcRequest&);
- X
- X // The link to RPC
- X virtual void Dispatch (svc_req* req, SVCXPRT* transp);
- X // Provide the service. Never returns.
- X void Provide ();
- X // Provide the service. Returns after timeout or call.
- X void Provide (timeval&);
- X
- X // Get caller. May be called during execution of a service routine.
- X inline struct sockaddr_in* Caller ()
- X { return svc_getcaller (xprt); }
- X const char* CallerName ();
- X // Reply before return
- X void Reply (void* res);
- X void Reply ();
- X // Quit provide loop
- X void Interrupt ();
- X
- private:
- X // Save the address of the one and only RpcService in the process.
- X // There may be only one RpcService, because we can register a program
- X // with svc_register (method RpcServiceCallback) but we can't make
- X // the svc function give an argument to this function when doing a
- X // callback, which means that we can't have it distinguish between
- X // various instances of RpcService.
- X static RpcService* me;
- X static inline void RpcServiceCallback (svc_req* req, SVCXPRT* transp)
- X { RpcService::me->Dispatch (req, transp); }
- X
- protected:
- X void init ();
- X void HandleError (errorCode e);
- X virtual void DoProvide (timeval*);
- X bool standalone;
- X errorCode errorState;
- X u_long prog;
- X u_long vers;
- X RpcRegistered** handlers;
- X int maxHandlerIndex;
- X static RpcRegistered* nopHandler;
- X SVCXPRT* xprt;
- X RpcRequest* rpcreq;
- X bool quitLoop;
- X char* inbuf;
- X int inmax;
- X bool haveReplied;
- X
- X // Default error handling prints a message and exit(2)s.
- X virtual void HandleError ();
- X};
- X
- inline void RpcService::HandleError (errorCode e)
- X{ errorState = e; HandleError (); }
- X
- inline u_long RpcService::Program ()
- X{ return prog; }
- X
- inline void RpcService::Reply ()
- X{ Reply (0); }
- X
- inline void RpcService::Interrupt ()
- X{ quitLoop = TRUE; }
- X
- inline void RpcService::Provide ()
- X{ DoProvide (0); }
- X
- inline void RpcService::Provide (timeval& t)
- X{ DoProvide (&t); }
- X
- X#endif
- END_OF_FILE
- if test 4489 -ne `wc -c <'rpc++/service.h'`; then
- echo shar: \"'rpc++/service.h'\" unpacked with wrong size!
- fi
- # end of 'rpc++/service.h'
- fi
- if test -f 'rpc++/stub.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'rpc++/stub.h'\"
- else
- echo shar: Extracting \"'rpc++/stub.h'\" \(4989 characters\)
- sed "s/^X//" >'rpc++/stub.h' <<'END_OF_FILE'
- X// -*- c++ -*-
- X/*
- Copyright (C) 1991 Peter Bersen
- X
- This file is part of the rpc++ Library. This library is free
- software; you can redistribute it and/or modify it under the terms of
- the GNU Library General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your
- option) any later version. This library is distributed in the hope
- that it will be useful, but WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE. See the GNU Library General Public License for more details.
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free Software
- XFoundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- X
- Modified and partially rewritten March 1992 by Michael N. Lipp,
- mnl@dtro.e-technik.th-darmstadt.de. The original copyright terms and
- conditions apply without change to any modified or new parts.
- X*/
- X
- X#ifndef _RPCSTUB_H_
- X#define _RPCSTUB_H_
- static char _rpcpp_stub_h_[]
- X= "stub.h,v 2.5 1992/12/06 18:58:15 mnl Exp";
- X
- X// stub.h,v
- X// Revision 2.5 1992/12/06 18:58:15 mnl
- X// Fixed various bugs and added some Methods.
- X//
- X// Revision 2.4 1992/08/08 13:23:18 mnl
- X// Space allocated for result turned out to be local to a CLIENT*, thus
- X// "res", "resmax" and "resproc" have been made member variables of
- X// RpcStub.
- X//
- X// Revision 2.3 1992/06/15 19:13:31 mnl
- X// Fixed a few bugs, clarified interface.
- X//
- X// Revision 2.2 1992/06/13 14:27:43 mnl
- X// Adapted to (patched) gcc-2.2. Fixed several bugs.
- X//
- X// Revision 2.1.1.1 1992/03/08 13:28:43 mnl
- X// Initial mnl version.
- X//
- X
- X#ifdef __GNUG__
- X#pragma interface
- X#endif
- X
- X#undef TRUE
- X#undef FALSE
- X#include <bool.h>
- X#include <String.h>
- X#include <sys/time.h>
- X#include "rpc++/request.h"
- X
- class RpcStub
- X{
- protected:
- X static timeval defaultTimeout;
- X
- public:
- X typedef enum
- X { noError, notConnected, cantCreate, cantCall,
- X } errorCode;
- X
- X // Construct a new stub
- X RpcStub (u_long prognum, u_long versnum,
- X char* hostname = "localhost",
- X timeval timeout = defaultTimeout, bool connect = TRUE);
- X RpcStub (u_long prognum, u_long versnum,
- X char* hostname = "localhost",
- X bool connect = TRUE, timeval timeout = defaultTimeout);
- X virtual ~RpcStub ();
- X
- X // Reconnect (in case of failure or delayed connection)
- X void Reconnect (bool handle_errors = TRUE);
- X
- X // Various inquiries
- X virtual bool OK ();
- X CLIENT* Service ();
- X
- X // Get/set timeout
- X timeval GetTimeout () const;
- X void SetTimeout (timeval& timo);
- X
- X // Make a call, either with or without an argument. If handle_errors
- X // is true, "Call" will call the error handler in case of an error.
- X // Else, it returns 0 as result and it is up to the client to handle
- X // the error.
- X // Call with one arg:
- X void* Call (RpcRequest&, bool handle_errors = TRUE);
- X // Call with two args:
- X void* Call (RpcRequest&, void* in, bool handle_errors = TRUE);
- X // ...
- X void* Call (RpcRequest& req, void*, void*, bool handle_errors = TRUE);
- X void* Call (RpcRequest& req, void*, void*, void*, bool handle_errors = TRUE);
- X void* Call (RpcRequest& req, void*, void*, void*, void*,
- X bool handle_errors = TRUE);
- X void* Call (RpcRequest& req, void*, void*, void*, void*, void*,
- X bool handle_errors = TRUE);
- X void* Call (RpcRequest& req, void*, void*, void*, void*, void*, void*,
- X bool handle_errors = TRUE);
- X void* Call (RpcRequest& req, void*, void*, void*, void*, void*, void*, void*,
- X bool handle_errors = TRUE);
- X // Call with N args:
- X void* Call (RpcRequest& req, void**, bool handle_errors = TRUE);
- X
- protected:
- X void* HandleError (errorCode e);
- X errorCode errorState;
- X u_long program;
- X u_long version;
- X String server;
- X timeval timeout;
- X CLIENT* svc;
- X void* res;
- X size_t resmax;
- X xdrproc_t resproc;
- X RpcRequest* curReq;
- X void** curArgs;
- X
- X void init (u_long prognum, u_long versnum,
- X char* hostname, timeval timeout, bool connect);
- X // Default error handling prints a message and exit(2)s.
- X virtual void* HandleError ();
- X void* DoCall (RpcRequest& req, void** args, bool handle_errors);
- X void* ReCall (bool);
- X};
- X
- inline RpcStub::RpcStub (u_long prognum, u_long versnum,
- X char* hostname, timeval timeout, bool connect)
- X{ init (prognum, versnum, hostname, timeout, connect); }
- X
- inline RpcStub::RpcStub (u_long prognum, u_long versnum,
- X char* hostname, bool connect, timeval timeout)
- X{ init (prognum, versnum, hostname, timeout, connect); }
- X
- inline virtual bool RpcStub::OK ()
- X{ return errorState == noError; }
- X
- inline CLIENT* RpcStub::Service ()
- X{ return svc; }
- X
- inline timeval RpcStub::GetTimeout () const
- X{ return timeout; }
- X
- inline void RpcStub::SetTimeout (timeval& tv)
- X{ clnt_control (svc, CLSET_TIMEOUT, &tv); timeout = tv; }
- X
- inline void* RpcStub::Call (RpcRequest& req, bool handle_errors = TRUE)
- X{ return Call (req, (void*)0, handle_errors); }
- X
- inline void* RpcStub::HandleError (errorCode e)
- X{ errorState = e; return HandleError (); }
- X
- X#endif
- END_OF_FILE
- if test 4989 -ne `wc -c <'rpc++/stub.h'`; then
- echo shar: \"'rpc++/stub.h'\" unpacked with wrong size!
- fi
- # end of 'rpc++/stub.h'
- fi
- if test -f 'rpc++/xdr++.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'rpc++/xdr++.h'\"
- else
- echo shar: Extracting \"'rpc++/xdr++.h'\" \(2585 characters\)
- sed "s/^X//" >'rpc++/xdr++.h' <<'END_OF_FILE'
- X// -*- c++ -*-
- X/*
- Copyright (C) 1991 Peter Bersen
- X
- This file is part of the rpc++ Library. This library is free
- software; you can redistribute it and/or modify it under the terms of
- the GNU Library General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your
- option) any later version. This library is distributed in the hope
- that it will be useful, but WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE. See the GNU Library General Public License for more details.
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free Software
- XFoundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- X
- Modified and partially rewritten March 1992 by Michael N. Lipp,
- mnl@dtro.e-technik.th-darmstadt.de. The original copyright terms and
- conditions apply without change to any modified or new parts.
- X*/
- X
- X#ifndef _XDRPLPL_H_
- X#define _XDRPLPL_H_
- static char _rpcpp_xdrpp_h_[]
- X= "xdr++.h,v 2.4 1993/01/20 15:00:52 mnl Exp";
- X
- X// xdr++.h,v
- X// Revision 2.4 1993/01/20 15:00:52 mnl
- X// Updated for gcc-2.3.3.
- X//
- X// Revision 2.3 1992/06/15 19:13:33 mnl
- X// Fixed a few bugs, clarified interface.
- X//
- X// Revision 2.2 1992/06/13 14:27:44 mnl
- X// Adapted to (patched) gcc-2.2. Fixed several bugs.
- X//
- X// Revision 2.1.1.1 1992/03/08 13:28:43 mnl
- X// Initial mnl version.
- X//
- X
- X#ifdef __GNUG__
- X#pragma interface
- X#endif
- X
- X/*
- X** Class XdrInfo describes serializers. It combines the xdrproc_t with the
- X** size info usually needed if you want to apply a serializer.
- X*/
- X
- X#include <rpc/types.h>
- X#include <rpc/xdr.h>
- X
- class XdrInfo
- X{
- protected:
- X xdrproc_t proc;
- X size_t size;
- public:
- X inline XdrInfo (xdrproc_t p, size_t s)
- X { proc = p; size = s; }
- X inline xdrproc_t Proc () const
- X { return proc; }
- X inline size_t Size () const
- X { return size; }
- X};
- X
- struct XdrSeqInfo
- X{
- X XdrInfo** infos;
- X void** data;
- X};
- X
- X/*
- X** Class Xdr provides a unique (C++-like) name scope for the predefined
- X** xdr routines by defining them as static members of type XdrInfo.
- X*/
- X
- class Xdr
- X{
- public:
- X static XdrInfo Xnull;
- X static XdrInfo Xchar;
- X static XdrInfo Xshort;
- X static XdrInfo Xint;
- X static XdrInfo Xlong;
- X static XdrInfo Xuchar;
- X static XdrInfo Xushort;
- X static XdrInfo Xuint;
- X static XdrInfo Xulong;
- X static XdrInfo Xfloat;
- X static XdrInfo Xdouble;
- X
- X static XdrInfo Xenum_t;
- X static XdrInfo Xbool_t;
- X static XdrInfo Xvoid;
- X
- X static XdrInfo Xwrapstring;
- X
- X static bool_t XdrParams (XDR* xdrs, XdrSeqInfo* xsi);
- X};
- X
- X#endif
- END_OF_FILE
- if test 2585 -ne `wc -c <'rpc++/xdr++.h'`; then
- echo shar: \"'rpc++/xdr++.h'\" unpacked with wrong size!
- fi
- # end of 'rpc++/xdr++.h'
- fi
- if test -f 'service.cc' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'service.cc'\"
- else
- echo shar: Extracting \"'service.cc'\" \(9174 characters\)
- sed "s/^X//" >'service.cc' <<'END_OF_FILE'
- X// -*- c++ -*-
- X/*
- Copyright (C) 1991 Peter Bersen
- X
- This file is part of the rpc++ Library. This library is free
- software; you can redistribute it and/or modify it under the terms of
- the GNU Library General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your
- option) any later version. This library is distributed in the hope
- that it will be useful, but WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE. See the GNU Library General Public License for more details.
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free Software
- XFoundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- X
- Modified and partially rewritten March 1992 by Michael N. Lipp,
- mnl@dtro.e-technik.th-darmstadt.de. The original copyright terms and
- conditions apply without change to any modified or new parts.
- X*/
- X
- static char _rpcpp_service_cc_[]
- X= "service.cc,v 2.5 1993/01/20 15:00:14 mnl Exp";
- X
- X// service.cc,v
- X// Revision 2.5 1993/01/20 15:00:14 mnl
- X// Updated for gcc-2.3.3.
- X//
- X// Revision 2.4 1992/12/06 18:57:53 mnl
- X// Fixed various bugs and added some Methods.
- X//
- X// Revision 2.3 1992/06/15 19:12:44 mnl
- X// Fixed a few bugs, clarified interface.
- X//
- X// Revision 2.2 1992/06/13 14:27:02 mnl
- X// Adapted to (patched) gcc-2.2. Fixed several bugs.
- X//
- X// Revision 2.1.1.1 1992/03/08 13:28:42 mnl
- X// Initial mnl version.
- X//
- X
- X#ifdef __GNUG__
- X#pragma implementation
- X#endif
- X
- X#include <assert.h>
- X#include <stream.h>
- X#include <memory.h>
- X#include <errno.h>
- X#include <stdlib.h>
- X#include <sys/types.h>
- X#include <sys/socket.h>
- X#include <netdb.h>
- X#include <rpc/rpc.h>
- X#include <rpc/svc.h>
- X#include <rpc/pmap_clnt.h>
- X#include "rpc++/service.h"
- X#include "rpc++/request.h"
- X
- extern "C" {
- X extern int getdtablesize();
- X}
- X
- X//
- X// RpcRegistered -- help class
- X//
- X
- class RpcRegistered
- X{
- public:
- X RpcRequest request;
- X AnyRpcCallback* callback;
- X
- X inline RpcRegistered (const RpcRequest& req, AnyRpcCallback* cb)
- X : request (req), callback (cb) { }
- X inline ~RpcRegistered ()
- X { delete callback; }
- X};
- X
- X//
- X// RpcService
- X//
- X
- RpcService* RpcService::me = 0;
- X// nopRequest is used as a dummy to mark reserved but not yet registered
- X// service slots. Just in case it gets called, there is really a nop.
- static void nop () {}
- static RpcCallback nopCb (nop);
- RpcRegistered* RpcService::nopHandler
- X = new RpcRegistered (RpcRequest (0, &Xdr::Xvoid), &nopCb);
- X
- RpcService::RpcService (u_long pnum, u_long vnum)
- X{
- X init ();
- X prog = pnum;
- X vers = vnum;
- X // find out if we have been started by inetd and set transp accoringly.
- X sockaddr_in sa;
- X int sasz = sizeof (sa);
- X // if started by inetd, stdin is a socket
- X standalone = (getsockname (0, (sockaddr*)&sa, &sasz) != 0);
- X if (standalone)
- X { // we are standalone
- X (void) pmap_unset(prog, vers);
- X xprt = svctcp_create(RPC_ANYSOCK, 0, 0);
- X }
- X else
- X { // inetd is our parent
- X xprt = svctcp_create(0, 0, 0);
- X }
- X if (xprt == NULL)
- X {
- X HandleError (cantCreateTCPService);
- X return;
- X }
- X if (!svc_register(xprt, prog, vers, RpcServiceCallback,
- X standalone ? IPPROTO_TCP : 0))
- X {
- X HandleError (cantRegisterService);
- X return;
- X }
- X}
- X
- RpcService::RpcService (u_long vnum)
- X{
- X init ();
- X vers = vnum;
- X prog = 0x40000000;
- X xprt = svctcp_create(RPC_ANYSOCK, 0, 0);
- X if (xprt == NULL)
- X {
- X HandleError (cantCreateTCPService);
- X return;
- X }
- X while (! pmap_set (prog, vers, IPPROTO_TCP, xprt->xp_port))
- X prog++;
- X if (!svc_register(xprt, prog, vers, RpcServiceCallback, IPPROTO_TCP))
- X {
- X HandleError (cantRegisterService);
- X return;
- X }
- X}
- X
- void RpcService::init ()
- X{
- X errorState = noError;
- X if (me)
- X {
- X HandleError (reconstructionAttempt);
- X return;
- X }
- X me = this;
- X handlers = 0;
- X maxHandlerIndex = -1;
- X inbuf = 0;
- X inmax = 0;
- X}
- X
- RpcService::~RpcService ()
- X{
- X if (standalone)
- X svc_unregister (prog, vers);
- X for (int i = 0; i <= maxHandlerIndex; i++)
- X if (handlers[i] != nopHandler)
- X delete handlers[i];
- X delete [] handlers;
- X delete [] inbuf;
- X me = 0;
- X}
- X
- void RpcService::HandleError ()
- X{
- X switch (errorState)
- X {
- X case reconstructionAttempt:
- X cerr << "rpc++: Attempt to construct another instance of RpcService.\n";
- X exit (1);
- X case cantCreateTCPService:
- X cerr << "rpc++: can't create tcp service.\n";
- X exit(1);
- X case cantRegisterService:
- X cerr << form ("rpc++: can't register (%d, %d, tcp).", prog, vers);
- X exit(1);
- X case cantSendReply:
- X cerr << "rpc++: can't reply to RPC call.\n";
- X break;
- X case invalidResult:
- X cerr << "rpc++: registered routine has return NULL pointer.\n";
- X abort ();
- X case notRegistered:
- X cerr << "rpc++: requested RPC routine not registered.\n";
- X break;
- X case cantGetArgs:
- X cerr << "rpc++: can't get procedure arguments.\n";
- X break;
- X case cantFreeArgs:
- X cerr << "rpc++: can't free XDR arguments.\n";
- X break;
- X }
- X errorState = noError;
- X}
- X
- void RpcService::Register (const RpcRequest& req, const AnyRpcCallback& cb)
- X{
- X assert (req.Params () == -1 || cb.Params () == -1
- X || req.Params () == cb.Params ());
- X AnyRpcCallback* cbp = cb.CopyToHeap ();
- X cbp->SetService (this);
- X if (req.RequestNumber () > maxHandlerIndex)
- X {
- X RpcRegistered** reg = new RpcRegistered*[req.RequestNumber () + 10];
- X memcpy (reg, handlers, (maxHandlerIndex + 1) * sizeof (RpcRegistered*));
- X memset (®[maxHandlerIndex + 1], 0,
- X (req.RequestNumber () + 10 - (maxHandlerIndex + 1))
- X * sizeof (RpcRegistered*));
- X delete handlers;
- X handlers = reg;
- X maxHandlerIndex = req.RequestNumber () + 10 - 1;
- X }
- X if (handlers[req.RequestNumber ()] != nopHandler)
- X delete handlers[req.RequestNumber ()];
- X handlers[req.RequestNumber ()] = new RpcRegistered (req, cbp);
- X}
- X
- void RpcService::Unregister (const RpcRequest& req)
- X{
- X if (req.RequestNumber () > maxHandlerIndex)
- X return;
- X if (handlers[req.RequestNumber ()] != nopHandler)
- X delete handlers[req.RequestNumber ()];
- X handlers[req.RequestNumber ()] = 0;
- X}
- X
- u_long RpcService::ReserveService ()
- X{
- X u_long svc = 0;
- X for (int req = 1; req <= maxHandlerIndex; req++)
- X {
- X if (handlers[req] == 0)
- X {
- X svc = req;
- X break;
- X }
- X }
- X if (svc == 0)
- X svc = maxHandlerIndex + 1;
- X handlers[svc] = nopHandler;
- X return svc;
- X}
- X
- void RpcService::Dispatch (svc_req* req, SVCXPRT* transp)
- X{
- X xprt = transp;
- X if (req->rq_proc == NULLPROC)
- X {
- X if (! svc_sendreply (xprt, xdr_void, 0))
- X {
- X svcerr_systemerr (xprt);
- X HandleError (cantSendReply);
- X }
- X return;
- X }
- X RpcRegistered* handler = ((req->rq_proc > maxHandlerIndex)
- X ? 0
- X : handlers[req->rq_proc]);
- X if (! handler)
- X {
- X svcerr_noproc (xprt);
- X HandleError (notRegistered);
- X return;
- X }
- X rpcreq = &handler->request;
- X
- X int insz = rpcreq->ParamSize ();
- X if (insz > inmax) // does in-data fit in available buffer?
- X { // if not, increase buffer space
- X delete [] inbuf;
- X inbuf = new char[inmax = insz];
- X }
- X void* dataps[rpcreq->Params ()];
- X void** dp = dataps;
- X *dp = inbuf;
- X for (XdrInfo** ip = rpcreq->InInfo(); *ip; ip++, dp++)
- X dp[1] = (char*)dp[0] + (*ip)->Size ();
- X
- X memset (inbuf, 0, insz);
- X XdrSeqInfo xsi = { rpcreq->InInfo (), dataps };
- X if (!svc_getargs (xprt, Xdr::XdrParams, &xsi))
- X {
- X if (rpcreq->Type () == RpcRequest::normal) // errors can be reported
- X svcerr_decode (xprt); // only if the client waits for a result
- X HandleError (cantGetArgs);
- X return;
- X }
- X haveReplied = FALSE;
- X void* res = handler->callback->Do (dataps);
- X if (! haveReplied)
- X Reply (res);
- X if (!svc_freeargs (xprt, Xdr::XdrParams, &xsi))
- X HandleError (cantFreeArgs);
- X xprt = 0;
- X}
- X
- void RpcService::Reply (void* res)
- X{
- X haveReplied = TRUE;
- X if (rpcreq->Type () == RpcRequest::normal) // i.e., result expected
- X {
- X xdrproc_t outproc = rpcreq->OutInfo()->Proc ();
- X if (outproc == (xdrproc_t)0)
- X {
- X cerr << "rpc++: RpcRequest has invalid xdrproc_t (0) in out-Info";
- X abort ();
- X }
- X if (res == 0 && outproc != (xdrproc_t)xdr_void)
- X {
- X svcerr_systemerr (xprt);
- X HandleError ();
- X }
- X else if (!svc_sendreply
- X (xprt, rpcreq->OutInfo()->Proc (), (caddr_t)res))
- X {
- X svcerr_systemerr (xprt);
- X HandleError (cantSendReply);
- X }
- X }
- X}
- X
- void RpcService::DoProvide (timeval* thisLong)
- X{
- X int dtbsz = getdtablesize();
- X fd_set readfds;
- X
- X quitLoop = FALSE;
- X while (! quitLoop)
- X {
- X readfds = svc_fdset;
- X switch(select (dtbsz, &readfds, 0, 0, thisLong))
- X {
- X case -1:
- X if (errno != EBADF)
- X continue;
- X cerr << "PRC++: select: " << sys_errlist[errno] << '\n';
- X return;
- X case 0:
- X if (thisLong == 0)
- X continue;
- X return;
- X default:
- X svc_getreqset (&readfds);
- X if (thisLong != 0)
- X return;
- X break;
- X }
- X }
- X}
- X
- const char* RpcService::CallerName ()
- X{
- X struct sockaddr_in *sa = Caller ();
- X struct hostent* he = gethostbyaddr ((const char*)&sa->sin_addr,
- X sizeof (sa->sin_addr),
- X sa->sin_family);
- X return he->h_name;
- X}
- END_OF_FILE
- if test 9174 -ne `wc -c <'service.cc'`; then
- echo shar: \"'service.cc'\" unpacked with wrong size!
- fi
- # end of 'service.cc'
- fi
- if test -f 'stub.cc' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'stub.cc'\"
- else
- echo shar: Extracting \"'stub.cc'\" \(6729 characters\)
- sed "s/^X//" >'stub.cc' <<'END_OF_FILE'
- X// -*- c++ -*-
- X/*
- Copyright (C) 1991 Peter Bersen
- X
- This file is part of the rpc++ Library. This library is free
- software; you can redistribute it and/or modify it under the terms of
- the GNU Library General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your
- option) any later version. This library is distributed in the hope
- that it will be useful, but WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE. See the GNU Library General Public License for more details.
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free Software
- XFoundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- X
- Modified and partially rewritten March 1992 by Michael N. Lipp,
- mnl@dtro.e-technik.th-darmstadt.de. The original copyright terms and
- conditions apply without change to any modified or new parts.
- X*/
- X
- static char _rpcpp_stub_cc_[]
- X= "stub.cc,v 2.5 1992/12/06 18:57:55 mnl Exp";
- X
- X// stub.cc,v
- X// Revision 2.5 1992/12/06 18:57:55 mnl
- X// Fixed various bugs and added some Methods.
- X//
- X// Revision 2.4 1992/08/08 13:23:13 mnl
- X// Space allocated for result turned out to be local to a CLIENT*, thus
- X// "res", "resmax" and "resproc" have been made member variables of
- X// RpcStub.
- X//
- X// Revision 2.3 1992/06/15 19:12:46 mnl
- X// Fixed a few bugs, clarified interface.
- X//
- X// Revision 2.2 1992/06/13 14:27:04 mnl
- X// Adapted to (patched) gcc-2.2. Fixed several bugs.
- X//
- X// Revision 2.1.1.1 1992/03/08 13:28:42 mnl
- X// Initial mnl version.
- X//
- X
- X#ifdef __GNUG__
- X#pragma implementation
- X#endif
- X
- X#include <stream.h>
- X#include <memory.h>
- X#include <assert.h>
- X#include "rpc++/stub.h"
- X
- timeval RpcStub::defaultTimeout = { 25, 0 };
- X
- void RpcStub::init (u_long prog, u_long vers,
- X char* srv, timeval timo, bool connect)
- X{
- X errorState = noError;
- X program = prog;
- X version = vers;
- X server = srv;
- X timeout = timo;
- X svc = 0;
- X res = 0;
- X resmax = 0;
- X resproc = 0;
- X if (connect)
- X Reconnect ();
- X else
- X errorState = notConnected;
- X}
- X
- RpcStub::~RpcStub ()
- X{
- X if (resproc) // "Call" has been called at least once,
- X clnt_freeres (svc, resproc, res); // free any data allocated by clnt_call
- X if (svc)
- X clnt_destroy (svc);
- X}
- X
- void* RpcStub::HandleError ()
- X{
- X switch (errorState)
- X {
- X case notConnected:
- X cerr << "rpc++: Stub has not been connected to server.\n";
- X case cantCreate:
- X cerr << clnt_spcreateerror ("rpc++") << '\n';
- X break;
- X case cantCall:
- X cerr << clnt_sperror (svc, "rpc++") << '\n';
- X exit (1);
- X }
- X return 0; // suppress compiler warning
- X}
- X
- void RpcStub::Reconnect (bool handle_errors)
- X{
- X if (resproc) // "Call" has been called
- X {
- X clnt_freeres (svc, resproc, res); // free data allocated by clnt_call
- X resproc = 0;
- X }
- X if (svc)
- X {
- X clnt_destroy (svc);
- X }
- X svc = clnt_create (server, program, version, "tcp"); // connect to client
- X if (svc == 0) // failed ?
- X {
- X if (handle_errors)
- X HandleError (cantCreate);
- X errorState = notConnected;
- X return;
- X }
- X clnt_control (svc, CLSET_TIMEOUT, &timeout);
- X errorState = noError;
- X}
- X
- void* RpcStub::Call (RpcRequest& req, void* in, bool handle_errors)
- X{
- X void* args[] = { in };
- X return DoCall (req, args, handle_errors);
- X}
- X
- void* RpcStub::Call (RpcRequest& req, void* in0, void* in1, bool handle_errors)
- X{
- X void* args[] = { in0, in1 };
- X return DoCall (req, args, handle_errors);
- X}
- X
- void* RpcStub::Call (RpcRequest& req, void* in0, void* in1, void* in2,
- X bool handle_errors)
- X{
- X void* args[] = { in0, in1, in2 };
- X return DoCall (req, args, handle_errors);
- X}
- X
- void* RpcStub::Call (RpcRequest& req, void* in0, void* in1, void* in2,
- X void* in3, bool handle_errors)
- X{
- X void* args[] = { in0, in1, in2, in3 };
- X return DoCall (req, args, handle_errors);
- X}
- X
- void* RpcStub::Call (RpcRequest& req, void* in0, void* in1, void* in2,
- X void* in3, void* in4, bool handle_errors)
- X{
- X void* args[] = { in0, in1, in2, in3, in4 };
- X return DoCall (req, args, handle_errors);
- X}
- X
- void* RpcStub::Call (RpcRequest& req, void* in0, void* in1, void* in2,
- X void* in3, void* in4, void* in5, bool handle_errors)
- X{
- X void* args[] = { in0, in1, in2, in3, in4, in5 };
- X return DoCall (req, args, handle_errors);
- X}
- X
- void* RpcStub::Call (RpcRequest& req, void* in0, void* in1, void* in2,
- X void* in3, void* in4, void* in5, void* in6,
- X bool handle_errors)
- X{
- X void* args[] = { in0, in1, in2, in3, in4, in5, in6 };
- X return DoCall (req, args, handle_errors);
- X}
- X
- void* RpcStub::Call (RpcRequest& req, void** ins, bool handle_errors)
- X{
- X return DoCall (req, ins, handle_errors);
- X}
- X
- void* RpcStub::DoCall (RpcRequest& req, void** args, bool handle_errors)
- X{
- X if (! OK () )
- X {
- X if (! handle_errors)
- X return 0;
- X return HandleError ();
- X }
- X if (resproc) // "Call" has been called previously,
- X clnt_freeres (svc, resproc, res); // free any data allocated by clnt_call
- X resproc = 0;
- X if (req.OutInfo()->Size () > resmax) // enough space for result?
- X {
- X delete res; // delete old result buffer
- X res = new char[resmax = req.OutInfo()->Size ()]; // get a new one
- X }
- X if (req.OutInfo()->Size () > 0 ) // preset result (everyone does it, why?)
- X memset (res, 0, req.OutInfo()->Size ());
- X
- X curReq = &req;
- X curArgs = args;
- X return ReCall (handle_errors);
- X}
- X
- void* RpcStub::ReCall (bool handle_errors)
- X{
- X static const timeval nullTimeout = { 0, 0 };
- X
- X if (resproc) // "ReCall" has been called before.
- X clnt_freeres (svc, resproc, res); // free any data allocated by clnt_call
- X resproc = curReq->OutInfo()->Proc (); // note current output deserializer
- X XdrSeqInfo xsi = { curReq->InInfo (), curArgs };
- X if (curReq->Type () == RpcRequest::normal)
- X {
- X if (clnt_call (svc, curReq->RequestNumber (), // do call
- X Xdr::XdrParams, &xsi,
- X curReq->OutInfo()->Proc (), res,
- X timeout) != RPC_SUCCESS)
- X {
- X if (! handle_errors)
- X return 0;
- X return HandleError (cantCall);
- X }
- X return res ? res : &nullTimeout; // if the return type is void,
- X // res may be 0 although the call succeeded. To simplify error
- X // checking if handle_errors is FALSE, we return a value != 0.
- X }
- X
- X // curReq->Type () is batched or async
- X enum clnt_stat callres;
- X callres = clnt_call (svc, curReq->RequestNumber (), // do call
- X Xdr::XdrParams, &xsi,
- X (curReq->Type () == RpcRequest::batched
- X ? (xdrproc_t)0 : xdr_void), res,
- X nullTimeout);
- X if (callres != RPC_SUCCESS && callres != RPC_TIMEDOUT)
- X {
- X if (! handle_errors)
- X return 0;
- X return HandleError (cantCall);
- X }
- X return res ? res : &nullTimeout;
- X}
- END_OF_FILE
- if test 6729 -ne `wc -c <'stub.cc'`; then
- echo shar: \"'stub.cc'\" unpacked with wrong size!
- fi
- # end of 'stub.cc'
- fi
- if test -f 'version.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'version.h'\"
- else
- echo shar: Extracting \"'version.h'\" \(134 characters\)
- sed "s/^X//" >'version.h' <<'END_OF_FILE'
- X// version.h,v 2.3 1992/12/06 18:57:57 mnl Exp
- X#ifndef _RPCPLPL_VERSION_H_
- static char* version = "rpc++-library, version 2.3"
- X#endif
- END_OF_FILE
- if test 134 -ne `wc -c <'version.h'`; then
- echo shar: \"'version.h'\" unpacked with wrong size!
- fi
- # end of 'version.h'
- fi
- if test -f 'xdr++.cc' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'xdr++.cc'\"
- else
- echo shar: Extracting \"'xdr++.cc'\" \(2541 characters\)
- sed "s/^X//" >'xdr++.cc' <<'END_OF_FILE'
- X// -*- c++ -*-
- X/*
- Copyright (C) 1991 Peter Bersen
- X
- This file is part of the rpc++ Library. This library is free
- software; you can redistribute it and/or modify it under the terms of
- the GNU Library General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your
- option) any later version. This library is distributed in the hope
- that it will be useful, but WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE. See the GNU Library General Public License for more details.
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free Software
- XFoundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- X
- Modified and partially rewritten March 1992 by Michael N. Lipp,
- mnl@dtro.e-technik.th-darmstadt.de. The original copyright terms and
- conditions apply without change to any modified or new parts.
- X*/
- X
- static char _rpcpp_xdrpp_cc_[]
- X= "xdr++.cc,v 2.3 1992/06/15 19:12:49 mnl Exp";
- X
- X// xdr++.cc,v
- X// Revision 2.3 1992/06/15 19:12:49 mnl
- X// Fixed a few bugs, clarified interface.
- X//
- X// Revision 2.2 1992/06/13 14:27:06 mnl
- X// Adapted to (patched) gcc-2.2. Fixed several bugs.
- X//
- X// Revision 2.1.1.1 1992/03/08 13:28:42 mnl
- X// Initial mnl version.
- X//
- X
- X#ifdef __GNUG__
- X#pragma implementation
- X#endif
- X
- X/*
- X** See Xdr.h.
- X*/
- X
- X#include "rpc++/xdr++.h"
- X
- XXdrInfo Xdr::Xnull ((xdrproc_t)0, 0);
- XXdrInfo Xdr::Xchar ((xdrproc_t)xdr_char, sizeof (char));
- XXdrInfo Xdr::Xshort ((xdrproc_t)xdr_short, sizeof (short));
- XXdrInfo Xdr::Xint ((xdrproc_t)xdr_int, sizeof (int));
- XXdrInfo Xdr::Xlong ((xdrproc_t)xdr_long, sizeof (long));
- XXdrInfo Xdr::Xuchar ((xdrproc_t)xdr_u_char, sizeof (u_char));
- XXdrInfo Xdr::Xushort ((xdrproc_t)xdr_u_short, sizeof (u_short));
- XXdrInfo Xdr::Xuint ((xdrproc_t)xdr_u_int, sizeof (u_int));
- XXdrInfo Xdr::Xulong ((xdrproc_t)xdr_u_long, sizeof (u_long));
- XXdrInfo Xdr::Xfloat ((xdrproc_t)xdr_float, sizeof (float));
- XXdrInfo Xdr::Xdouble ((xdrproc_t)xdr_double, sizeof (double));
- X
- XXdrInfo Xdr::Xenum_t ((xdrproc_t)xdr_enum, sizeof (enum_t));
- XXdrInfo Xdr::Xbool_t ((xdrproc_t)xdr_bool, sizeof (bool_t));
- XXdrInfo Xdr::Xvoid ((xdrproc_t)xdr_void, 0);
- XXdrInfo Xdr::Xwrapstring ((xdrproc_t)xdr_wrapstring, sizeof (char*));
- X
- bool_t Xdr::XdrParams (XDR* xdrs, XdrSeqInfo* xsi)
- X{
- X XdrInfo** infop = xsi->infos;
- X void** datap = xsi->data;
- X
- X while (*infop)
- X {
- X if (! (*infop->Proc ()) (xdrs, *datap))
- X return FALSE;
- X infop++, datap++;
- X }
- X return TRUE;
- X}
- END_OF_FILE
- if test 2541 -ne `wc -c <'xdr++.cc'`; then
- echo shar: \"'xdr++.cc'\" unpacked with wrong size!
- fi
- # end of 'xdr++.cc'
- fi
- echo shar: End of archive 1 \(of 3\).
- cp /dev/null ark1isdone
- MISSING=""
- for I in 1 2 3 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 3 archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-