home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / unix / volume26 / mnlrpc23 / part01 < prev    next >
Encoding:
Text File  |  1993-04-24  |  96.8 KB  |  3,231 lines

  1. Newsgroups: comp.sources.unix
  2. From: mnl@dtro.e-technik.th-darmstadt.de (Michael Lipp)
  3. Subject: v26i181: mnl-rpc++-2.3.1 - a C++ interface to Sun RPC, Part01/03
  4. Sender: unix-sources-moderator@vix.com
  5. Approved: paul@vix.com
  6.  
  7. Submitted-By: mnl@dtro.e-technik.th-darmstadt.de (Michael Lipp)
  8. Posting-Number: Volume 26, Issue 181
  9. Archive-Name: mnl-rpc++-2.3.1/part01
  10.  
  11. This package contains the sources for a C++ interface to Sun RPCs.
  12.  
  13. As far as I remember, I got the original sources of the rpc++-library from
  14. some newsgroup, though I don't remember which one. I liked the basic idea
  15. but disliked several aspects of the interface details. So I adapted it to my
  16. likes. I intended some minor changes but soon found myself renaming classes,
  17. changing method parameters, introducing new classes, etc. The result is by
  18. no way compatible with the original version. It is, I hope, nevertheless
  19. useful.
  20.  
  21. This current version (2.3.1) of the rpc++ library updates the version 2.1
  22. posted in March 1991. It is the reaction to gcc-2.2 that finally allows a
  23. sufficiently reliable use of templates (almost, see Installation in
  24. rpc++.texi)
  25.  
  26.     mnl@dtro.e-technik.th-darmstadt.de (Michael Lipp)
  27.  
  28. #! /bin/sh
  29. # This is a shell archive.  Remove anything before this line, then unpack
  30. # it by saving it into a file and typing "sh file".  To overwrite existing
  31. # files, type "sh file -c".  You can also feed this as standard input via
  32. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  33. # will see the following message at the end:
  34. #        "End of archive 1 (of 3)."
  35. # Contents:  .cvsignore MANIFEST Makefile Proj.make README README-2.3
  36. #   README-2.3.1 README.ORIG StdHdrs StdHdrs/Makefile StdHdrs/README
  37. #   StdHdrs/rpc StdHdrs/rpc/auth.h StdHdrs/rpc/c_types.h
  38. #   StdHdrs/rpc/pmap_clnt.h callback.cc example example/.cvsignore
  39. #   example/Makefile example/calcsvc.cc example/calcsvc.h
  40. #   example/client.cc example/server.cc gcc-2.2.fix gcc-2.3.3.fix
  41. #   request.cc rpc++ rpc++/request.h rpc++/service.h rpc++/stub.h
  42. #   rpc++/xdr++.h service.cc stub.cc version.h xdr++.cc
  43. # Wrapped by vixie@gw.home.vix.com on Sun Apr 25 00:49:46 1993
  44. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  45. if test -f '.cvsignore' -a "${1}" != "-c" ; then 
  46.   echo shar: Will not clobber existing file \"'.cvsignore'\"
  47. else
  48. echo shar: Extracting \"'.cvsignore'\" \(192 characters\)
  49. sed "s/^X//" >'.cvsignore' <<'END_OF_FILE'
  50. X.dependencies
  51. rpc++.log
  52. rpc++.dvi
  53. rpc++.aux
  54. rpc++.toc
  55. rpc++.cp
  56. rpc++.fn
  57. rpc++.vr
  58. rpc++.tp
  59. rpc++.ky
  60. rpc++.pg
  61. rpc++.info
  62. X.isp_english
  63. rpc++.cps
  64. rpc++.fns
  65. rpc++.kys
  66. rpc++.pgs
  67. rpc++.tps
  68. rpc++.vrs
  69. END_OF_FILE
  70. if test 192 -ne `wc -c <'.cvsignore'`; then
  71.     echo shar: \"'.cvsignore'\" unpacked with wrong size!
  72. fi
  73. # end of '.cvsignore'
  74. fi
  75. if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  76.   echo shar: Will not clobber existing file \"'MANIFEST'\"
  77. else
  78. echo shar: Extracting \"'MANIFEST'\" \(1385 characters\)
  79. sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
  80. X   File Name        Archive #    Description
  81. X-----------------------------------------------------------
  82. X .cvsignore                 1    
  83. X COPYING                    2    
  84. X MANIFEST                   1    This shipping list
  85. X Makefile                   1    
  86. X Proj.make                  1    
  87. X README                     1    
  88. X README-2.3                 1    
  89. X README-2.3.1               1    
  90. X README.ORIG                1    
  91. X StdHdrs                    1    
  92. X StdHdrs/Makefile           1    
  93. X StdHdrs/README             1    
  94. X StdHdrs/rpc                1    
  95. X StdHdrs/rpc/auth.h         1    
  96. X StdHdrs/rpc/c_types.h      1    
  97. X StdHdrs/rpc/clnt.h         2    
  98. X StdHdrs/rpc/pmap_clnt.h    1    
  99. X StdHdrs/rpc/svc.h          2    
  100. X StdHdrs/rpc/xdr.h          2    
  101. X callback.cc                1    
  102. X example                    1    
  103. X example/.cvsignore         1    
  104. X example/Makefile           1    
  105. X example/calcsvc.cc         1    
  106. X example/calcsvc.h          1    
  107. X example/client.cc          1    
  108. X example/server.cc          1    
  109. X gcc-2.2.fix                1    
  110. X gcc-2.3.3.fix              1    
  111. X request.cc                 1    
  112. X rpc++                      1    
  113. X rpc++.texi                 3    
  114. X rpc++/callback.h           2    
  115. X rpc++/request.h            1    
  116. X rpc++/service.h            1    
  117. X rpc++/stub.h               1    
  118. X rpc++/xdr++.h              1    
  119. X service.cc                 1    
  120. X stub.cc                    1    
  121. X version.h                  1    
  122. X xdr++.cc                   1    
  123. END_OF_FILE
  124. if test 1385 -ne `wc -c <'MANIFEST'`; then
  125.     echo shar: \"'MANIFEST'\" unpacked with wrong size!
  126. fi
  127. # end of 'MANIFEST'
  128. fi
  129. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  130.   echo shar: Will not clobber existing file \"'Makefile'\"
  131. else
  132. echo shar: Extracting \"'Makefile'\" \(1446 characters\)
  133. sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  134. TOP = .
  135. SUBDIRS = StdHdrs example
  136. X
  137. INSTROOT = ../..
  138. X
  139. CC = gcc
  140. CPPFLAGS = -I.
  141. CFLAGS = -ggdb
  142. C++FLAGS = $(CFLAGS)
  143. X
  144. LIBHDRS = rpc++/xdr++.h rpc++/request.h rpc++/service.h rpc++/stub.h \
  145. X      rpc++/callback.h version.h
  146. LIBSRCS = xdr++.cc service.cc stub.cc request.cc callback.cc
  147. X
  148. LIBOBJS = $(LIBSRCS:%.cc=%.o) $(GENSRCS:%.cc=%.o)
  149. X
  150. all:: librpc++.a
  151. X
  152. subdirs.all:: librpc++.a
  153. X
  154. librpc++.a: $(LIBOBJS)
  155. X    rm -f $@
  156. X    ar cq $@ $(LIBOBJS)
  157. X    if [ -x /bin/ranlib -o -x /usr/bin/ranlib ]; then ranlib $@; fi
  158. X
  159. install:: librpc++.a
  160. X    install -d $(INSTROOT)/lib
  161. X    if cmp -s librpc++.a $(INSTROOT)/lib/librpc++.a; then : ; \
  162. X    else rm -f $(INSTROOT)/lib/librpc++.a; \
  163. X      cp -p librpc++.a $(INSTROOT)/lib; \
  164. X      chmod 444 $(INSTROOT)/lib/librpc++.a; \
  165. X      for f in rpc++/*.h; do \
  166. X        rm -f $(INSTROOT)/include/$$f; done; fi
  167. X    install -d $(INSTROOT)/include/rpc++
  168. X    for f in rpc++/*.h; do \
  169. X      cmp -s $$f $(INSTROOT)/include/$$f \
  170. X      || install -c -m 444 $$f $(INSTROOT)/include/rpc++; done
  171. X
  172. DISTLIST = Makefile README.ORIG README COPYING Proj.make rpc++.texi \
  173. X       gcc-2.2.2.fix $(LIBHDRS) $(LIBSRCS) README-2.3
  174. X
  175. clean::
  176. X    rm -f $(CLEANWILDCARDS) librpc++.a
  177. X
  178. include .dependencies
  179. X
  180. X.dependencies: $(LIBHDRS) $(LIBSRCS)
  181. X    gcc -M $(CPPFLAGS) $(LIBSRCS) > .dependencies
  182. X
  183. distlist::
  184. X    @for f in *.[ch] *.cc; do \
  185. X      if expr " $(DISTLIST) " : ".* $$f " >/dev/null; then : ; \
  186. X      else echo 1>&2 "Warning: c- or h-file \"$$f\" not in DISTLIST"; fi; \
  187. X    done
  188. X
  189. include $(TOP)/Proj.make
  190. END_OF_FILE
  191. if test 1446 -ne `wc -c <'Makefile'`; then
  192.     echo shar: \"'Makefile'\" unpacked with wrong size!
  193. fi
  194. # end of 'Makefile'
  195. fi
  196. if test -f 'Proj.make' -a "${1}" != "-c" ; then 
  197.   echo shar: Will not clobber existing file \"'Proj.make'\"
  198. else
  199. echo shar: Extracting \"'Proj.make'\" \(1450 characters\)
  200. sed "s/^X//" >'Proj.make' <<'END_OF_FILE'
  201. X# These are included in every Makefile in the project
  202. X
  203. CWDPATH = .
  204. CLEANWILDCARDS = core *~ *.o
  205. VERYCLEANWILDCARDS = core *~ *.o
  206. TEXCLEANWILDCARD = *~ *.aux *.log *.bbl *.blg *.toc *.idx *.ind
  207. TEXVERYCLEANWILDCARD = $(TEXCLEANWILDCARD) *.dvi
  208. ifndef SUBDIRS
  209. SUBDIRS =
  210. endif
  211. X
  212. X# Doing all always means doing the subdirs.
  213. X# Make subdirs.all a target to allow forced processing
  214. ifneq ("$(SUBDIRS)", "")
  215. ifneq ("$(SUBDIRSALL)", "NO")
  216. all:: subdirs.all
  217. endif
  218. X
  219. subdirs.all::
  220. X    @for d in $(SUBDIRS); do \
  221. X      (cd $$d; \
  222. X       smflags=$(SUBMFLAGS); \
  223. X       echo "Making all in $$d with flags: $$smflags ..." ; \
  224. X       echo "cd `pwd`"; \
  225. X       $(MAKE) $$smflags all); done; \
  226. X    echo "cd `pwd`"
  227. else
  228. all::;
  229. endif
  230. X
  231. ifneq ("$(SUBDIRS)", "")
  232. clean:: subdirs.clean
  233. X
  234. subdirs.clean::
  235. X    @for d in $(SUBDIRS); do \
  236. X      echo "Cleaning all in $$d..." ; \
  237. X      (cd $$d; $(MAKE) clean); done
  238. else
  239. clean::;
  240. endif
  241. X
  242. ifneq ("$(SUBDIRS)", "")
  243. veryclean:: subdirs.veryclean
  244. X
  245. subdirs.veryclean::
  246. X    @for d in $(SUBDIRS); do \
  247. X      echo "Verycleaning all in $$d..." ; \
  248. X      (cd $$d; $(MAKE) veryclean); done
  249. else
  250. veryclean::;
  251. endif
  252. X
  253. X# dist.list prints a list of files to be included in the distribution
  254. distlist::
  255. ifneq ("$(DISTLIST)", "")
  256. X    @for f in $(DISTLIST); do \
  257. X      echo $(CWDPATH)/$$f; done
  258. endif
  259. ifneq ("$(SUBDIRS)", "")
  260. ifneq ("$(SUBDIRSDIST)", "NO")
  261. X    @for d in $(SUBDIRS); do \
  262. X      (cd $$d; $(MAKE) distlist CWDPATH=$(CWDPATH)/$$d); done
  263. endif
  264. endif
  265. ifeq ("$(DISTLIST)$(SUBDIRS)","")
  266. X    
  267. endif
  268. X
  269. END_OF_FILE
  270. if test 1450 -ne `wc -c <'Proj.make'`; then
  271.     echo shar: \"'Proj.make'\" unpacked with wrong size!
  272. fi
  273. # end of 'Proj.make'
  274. fi
  275. if test -f 'README' -a "${1}" != "-c" ; then 
  276.   echo shar: Will not clobber existing file \"'README'\"
  277. else
  278. echo shar: Extracting \"'README'\" \(805 characters\)
  279. sed "s/^X//" >'README' <<'END_OF_FILE'
  280. This directory contains the sources for a C++ interface to Sun RPCs.
  281. X
  282. As far as I remember, I got the original sources of the rpc++-library
  283. from some newsgroup, though I don't remember which one. I liked the
  284. basic idea but disliked several aspects of the interface details. So I
  285. adapted it to my likes. I intended some minor changes but soon found
  286. myself renaming classes, changing method parameters, introducing new
  287. classes, etc. The result is by no way compatible with the original
  288. version. It is, I hope, nevertheless useful.
  289. X
  290. The current version 2.2 of the rpc++ library updates the version 2.1
  291. posted in March 1991. It is the reaction to gcc-2.2 that finally
  292. allows a sufficiently reliable use of templates (almost, see
  293. Installation in rpc++.texi)
  294. X
  295. Michael Lipp
  296. X
  297. X<mnl@dtro.e-technik.th-darmstadt.de>
  298. END_OF_FILE
  299. if test 805 -ne `wc -c <'README'`; then
  300.     echo shar: \"'README'\" unpacked with wrong size!
  301. fi
  302. # end of 'README'
  303. fi
  304. if test -f 'README-2.3' -a "${1}" != "-c" ; then 
  305.   echo shar: Will not clobber existing file \"'README-2.3'\"
  306. else
  307. echo shar: Extracting \"'README-2.3'\" \(747 characters\)
  308. sed "s/^X//" >'README-2.3' <<'END_OF_FILE'
  309. Version 2.3 fixes some bugs and adds a few methods that have shown to be
  310. needed for a complex application. The methods are:
  311. X
  312. RpcService::ReserveService
  313. X  Allocates an unused service number at runtime.
  314. X
  315. RpcService::Unregister
  316. X  Unregisters (i.e., provides no longer) a service.
  317. X
  318. RpcService::Provide (timeval&)
  319. X  Previously only available without argument. Provides services for
  320. X  a limited time or until a request has been handled.
  321. X
  322. RpcStub::ReCall
  323. X  May be used from within an error handle to repeat a call after the cause
  324. X  of its failure has been fixed.
  325. X
  326. StdHdrs/rpc contains a new version of xdr.h with better (more precise)
  327. function prototypes contributed by Doug Moore (dougm@cs.rice.edu).
  328. X
  329. Michael Lipp
  330. X
  331. X<mnl@dtro.e-technik.th-darmstadt.de>
  332. END_OF_FILE
  333. if test 747 -ne `wc -c <'README-2.3'`; then
  334.     echo shar: \"'README-2.3'\" unpacked with wrong size!
  335. fi
  336. # end of 'README-2.3'
  337. fi
  338. if test -f 'README-2.3.1' -a "${1}" != "-c" ; then 
  339.   echo shar: Will not clobber existing file \"'README-2.3.1'\"
  340. else
  341. echo shar: Extracting \"'README-2.3.1'\" \(725 characters\)
  342. sed "s/^X//" >'README-2.3.1' <<'END_OF_FILE'
  343. Version 2.3.1 fixes some warnings and ANSI C++ violations discovered
  344. by gcc-2.3.3 and clarifies include statements as suggested by Doug
  345. Moore (dougm@cs.rice.edu). It also includes the gcc-2.3.3 version of
  346. the gcc-2.2 patch. It's a pity that you still need to patch gcc in
  347. order to compile rpc++.  I have re-sent the bug report and someone
  348. from cygnus replied that things should be fixed in the next gcc
  349. release.
  350. X
  351. Interactive Unix is no longer supported, simply because I replaced it
  352. with Linux on my 386-box (clearer, faster, cheaper). rpc++ compiles
  353. under Linux "out of the box" with the 4.2 development environment
  354. X(after you have patched and recompiled gcc, of course).
  355. X
  356. Michael Lipp
  357. X
  358. X<mnl@dtro.e-technik.th-darmstadt.de>
  359. END_OF_FILE
  360. if test 725 -ne `wc -c <'README-2.3.1'`; then
  361.     echo shar: \"'README-2.3.1'\" unpacked with wrong size!
  362. fi
  363. # end of 'README-2.3.1'
  364. fi
  365. if test -f 'README.ORIG' -a "${1}" != "-c" ; then 
  366.   echo shar: Will not clobber existing file \"'README.ORIG'\"
  367. else
  368. echo shar: Extracting \"'README.ORIG'\" \(280 characters\)
  369. sed "s/^X//" >'README.ORIG' <<'END_OF_FILE'
  370. This directory contains a collection of classes that provide an
  371. interface to SUN's RPCs. I dubbed the collection the rpc++-library. It
  372. has been tested with gcc-1.40 on a SparcStation running SunOS 4.0.
  373. X
  374. There is no documentation. Look at the example in ./example.
  375. X
  376. Peter Berens
  377. X
  378. X
  379. END_OF_FILE
  380. if test 280 -ne `wc -c <'README.ORIG'`; then
  381.     echo shar: \"'README.ORIG'\" unpacked with wrong size!
  382. fi
  383. # end of 'README.ORIG'
  384. fi
  385. if test ! -d 'StdHdrs' ; then
  386.     echo shar: Creating directory \"'StdHdrs'\"
  387.     mkdir 'StdHdrs'
  388. fi
  389. if test -f 'StdHdrs/Makefile' -a "${1}" != "-c" ; then 
  390.   echo shar: Will not clobber existing file \"'StdHdrs/Makefile'\"
  391. else
  392. echo shar: Extracting \"'StdHdrs/Makefile'\" \(171 characters\)
  393. sed "s/^X//" >'StdHdrs/Makefile' <<'END_OF_FILE'
  394. TOP = ..
  395. SUBDIRS = rpc
  396. SUBDIRSALL = NO
  397. SUBDIRSDIST = NO
  398. X
  399. all::
  400. X
  401. clean::
  402. X    rm -f $(CLEANWILDCARDS)
  403. X
  404. DISTLIST = Makefile README $(wildcard rpc/*.h)
  405. X
  406. include $(TOP)/Proj.make
  407. END_OF_FILE
  408. if test 171 -ne `wc -c <'StdHdrs/Makefile'`; then
  409.     echo shar: \"'StdHdrs/Makefile'\" unpacked with wrong size!
  410. fi
  411. # end of 'StdHdrs/Makefile'
  412. fi
  413. if test -f 'StdHdrs/README' -a "${1}" != "-c" ; then 
  414.   echo shar: Will not clobber existing file \"'StdHdrs/README'\"
  415. else
  416. echo shar: Extracting \"'StdHdrs/README'\" \(177 characters\)
  417. sed "s/^X//" >'StdHdrs/README' <<'END_OF_FILE'
  418. This directory contains some of Sun's rpc headers that have been fixed
  419. X(though not thoroughly) to work with ANSI C and C++. I have installed
  420. them in my standard C include path.
  421. END_OF_FILE
  422. if test 177 -ne `wc -c <'StdHdrs/README'`; then
  423.     echo shar: \"'StdHdrs/README'\" unpacked with wrong size!
  424. fi
  425. # end of 'StdHdrs/README'
  426. fi
  427. if test ! -d 'StdHdrs/rpc' ; then
  428.     echo shar: Creating directory \"'StdHdrs/rpc'\"
  429.     mkdir 'StdHdrs/rpc'
  430. fi
  431. if test -f 'StdHdrs/rpc/auth.h' -a "${1}" != "-c" ; then 
  432.   echo shar: Will not clobber existing file \"'StdHdrs/rpc/auth.h'\"
  433. else
  434. echo shar: Extracting \"'StdHdrs/rpc/auth.h'\" \(4903 characters\)
  435. sed "s/^X//" >'StdHdrs/rpc/auth.h' <<'END_OF_FILE'
  436. X/* @(#)auth.h    2.3 88/08/07 4.0 RPCSRC; from 1.17 88/02/08 SMI */
  437. X/*
  438. X * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  439. X * unrestricted use provided that this legend is included on all tape
  440. X * media and as a part of the software program in whole or part.  Users
  441. X * may copy or modify Sun RPC without charge, but are not authorized
  442. X * to license or distribute it to anyone else except as part of a product or
  443. X * program developed by the user.
  444. X * 
  445. X * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  446. X * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  447. X * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  448. X * 
  449. X * Sun RPC is provided with no support and without any obligation on the
  450. X * part of Sun Microsystems, Inc. to assist in its use, correction,
  451. X * modification or enhancement.
  452. X * 
  453. X * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  454. X * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  455. X * OR ANY PART THEREOF.
  456. X * 
  457. X * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  458. X * or profits or other special, indirect and consequential damages, even if
  459. X * Sun has been advised of the possibility of such damages.
  460. X * 
  461. X * Sun Microsystems, Inc.
  462. X * 2550 Garcia Avenue
  463. X * Mountain View, California  94043
  464. X */
  465. X
  466. X/*
  467. X * auth.h, Authentication interface.
  468. X *
  469. X * Copyright (C) 1984, Sun Microsystems, Inc.
  470. X *
  471. X * The data structures are completely opaque to the client.  The client
  472. X * is required to pass a AUTH * to routines that create rpc
  473. X * "sessions".
  474. X */
  475. X
  476. X
  477. X#ifndef _rpc_auth_h
  478. X#define    _rpc_auth_h
  479. X
  480. X#define    MAX_AUTH_BYTES    400
  481. X#define    MAXNETNAMELEN    255    /* maximum length of network user's name */
  482. X
  483. X/*
  484. X * Status returned from authentication check
  485. X */
  486. enum auth_stat {
  487. X    AUTH_OK=0,
  488. X    /*
  489. X     * failed at remote end
  490. X     */
  491. X    AUTH_BADCRED=1,            /* bogus credentials (seal broken) */
  492. X    AUTH_REJECTEDCRED=2,        /* client should begin new session */
  493. X    AUTH_BADVERF=3,            /* bogus verifier (seal broken) */
  494. X    AUTH_REJECTEDVERF=4,        /* verifier expired or was replayed */
  495. X    AUTH_TOOWEAK=5,            /* rejected due to security reasons */
  496. X    /*
  497. X     * failed locally
  498. X    */
  499. X    AUTH_INVALIDRESP=6,        /* bogus response verifier */
  500. X    AUTH_FAILED=7            /* some unknown reason */
  501. X};
  502. X
  503. X#if (__mc68000__ || __sparc__ || __vax__ || __i386__)
  504. typedef u_long u_int32;    /* 32-bit unsigned integers */
  505. X#endif
  506. X
  507. union des_block {
  508. X    struct {
  509. X        u_int32 high;
  510. X        u_int32 low;
  511. X    } key;
  512. X    char c[8];
  513. X};
  514. typedef union des_block des_block;
  515. extern bool_t xdr_des_block();
  516. X
  517. X/*
  518. X * Authentication info.  Opaque to client.
  519. X */
  520. struct opaque_auth {
  521. X    enum_t    oa_flavor;        /* flavor of auth */
  522. X    caddr_t    oa_base;        /* address of more auth stuff */
  523. X    u_int    oa_length;        /* not to exceed MAX_AUTH_BYTES */
  524. X};
  525. X
  526. X
  527. X/*
  528. X * Auth handle, interface to client side authenticators.
  529. X */
  530. typedef struct {
  531. X    struct    opaque_auth    ah_cred;
  532. X    struct    opaque_auth    ah_verf;
  533. X    union    des_block    ah_key;
  534. X    struct auth_ops {
  535. X        void    (*ah_nextverf)();
  536. X        int    (*ah_marshal)();    /* nextverf & serialize */
  537. X        int    (*ah_validate)();    /* validate varifier */
  538. X        int    (*ah_refresh)();    /* refresh credentials */
  539. X        void    (*ah_destroy)();    /* destroy this structure */
  540. X    } *ah_ops;
  541. X    caddr_t ah_private;
  542. X} AUTH;
  543. X
  544. X
  545. X/*
  546. X * Authentication ops.
  547. X * The ops and the auth handle provide the interface to the authenticators.
  548. X *
  549. X * AUTH    *auth;
  550. X * XDR    *xdrs;
  551. X * struct opaque_auth verf;
  552. X */
  553. X#define AUTH_NEXTVERF(auth)        \
  554. X        ((*((auth)->ah_ops->ah_nextverf))(auth))
  555. X#define auth_nextverf(auth)        \
  556. X        ((*((auth)->ah_ops->ah_nextverf))(auth))
  557. X
  558. X#define AUTH_MARSHALL(auth, xdrs)    \
  559. X        ((*((auth)->ah_ops->ah_marshal))(auth, xdrs))
  560. X#define auth_marshall(auth, xdrs)    \
  561. X        ((*((auth)->ah_ops->ah_marshal))(auth, xdrs))
  562. X
  563. X#define AUTH_VALIDATE(auth, verfp)    \
  564. X        ((*((auth)->ah_ops->ah_validate))((auth), verfp))
  565. X#define auth_validate(auth, verfp)    \
  566. X        ((*((auth)->ah_ops->ah_validate))((auth), verfp))
  567. X
  568. X#define AUTH_REFRESH(auth)        \
  569. X        ((*((auth)->ah_ops->ah_refresh))(auth))
  570. X#define auth_refresh(auth)        \
  571. X        ((*((auth)->ah_ops->ah_refresh))(auth))
  572. X
  573. X#define AUTH_DESTROY(auth)        \
  574. X        ((*((auth)->ah_ops->ah_destroy))(auth))
  575. X#define auth_destroy(auth)        \
  576. X        ((*((auth)->ah_ops->ah_destroy))(auth))
  577. X
  578. X
  579. extern struct opaque_auth _null_auth;
  580. X
  581. X
  582. X/*
  583. X * These are the various implementations of client side authenticators.
  584. X */
  585. X
  586. X/*
  587. X * Unix style authentication
  588. X * AUTH *authunix_create(machname, uid, gid, len, aup_gids)
  589. X *    char *machname;
  590. X *    int uid;
  591. X *    int gid;
  592. X *    int len;
  593. X *    int *aup_gids;
  594. X */
  595. extern AUTH *authunix_create();
  596. extern AUTH *authunix_create_default();    /* takes no parameters */
  597. extern AUTH *authnone_create();        /* takes no parameters */
  598. extern AUTH *authdes_create();
  599. X
  600. X#define AUTH_NONE    0        /* no authentication */
  601. X#define    AUTH_NULL    0        /* backward compatibility */
  602. X#define    AUTH_UNIX    1        /* unix style (uid, gids) */
  603. X#define    AUTH_SHORT    2        /* short hand unix style */
  604. X#define    AUTH_DES    3        /* des style (encrypted timestamps) */
  605. X
  606. X#endif /*!_rpc_auth_h*/
  607. END_OF_FILE
  608. if test 4903 -ne `wc -c <'StdHdrs/rpc/auth.h'`; then
  609.     echo shar: \"'StdHdrs/rpc/auth.h'\" unpacked with wrong size!
  610. fi
  611. # end of 'StdHdrs/rpc/auth.h'
  612. fi
  613. if test -f 'StdHdrs/rpc/c_types.h' -a "${1}" != "-c" ; then 
  614.   echo shar: Will not clobber existing file \"'StdHdrs/rpc/c_types.h'\"
  615. else
  616. echo shar: Extracting \"'StdHdrs/rpc/c_types.h'\" \(2286 characters\)
  617. sed "s/^X//" >'StdHdrs/rpc/c_types.h' <<'END_OF_FILE'
  618. X#ifndef _rpc_c_types_h_
  619. X#define _rpc_c_types_h_
  620. X
  621. X#if defined(__cplusplus)
  622. X    /*
  623. X     * Definitions for C++ 2.0 and later require extern "C" { decl; }
  624. X     */
  625. X#   define EXTERN_FUNCTION( rtn, args ) extern "C" { rtn args; }
  626. X#   define FUN_ARGS( args ) args
  627. X#   define STRUCT_TAG( tag_name ) /* the tag disappears */
  628. X#   define ENUM_BITFIELD( enum_type ) unsigned
  629. X#   define ENUM_TYPE( enum_sp, enum_ty ) enum_ty
  630. X
  631. X#if defined(__STDC__) || defined(__cplusplus) || defined(c_plusplus)
  632. X#   define NAME_CONFLICT( name ) _##name
  633. X#else
  634. X#   define NAME_CONFLICT( name ) _/**/name
  635. X#endif
  636. X
  637. X#   define DOTDOTDOT ...
  638. X#   define _VOID_ /* anachronism */
  639. X#   define CONST const
  640. X
  641. X/*
  642. X * This is not necessary for 2.0 since 2.0 has corrected the void (*) () problem
  643. X */
  644. typedef void (*_PFV_)();
  645. typedef int (*_PFI_)();
  646. X
  647. X#elif defined(c_plusplus)
  648. X    /*
  649. X     * Definitions for C++ 1.2
  650. X     */
  651. X#   define EXTERN_FUNCTION( rtn, args ) rtn args
  652. X#   define FUN_ARGS( args ) args
  653. X#   define STRUCT_TAG( tag_name )  /* the tag disappears */
  654. X#   define ENUM_BITFIELD( enum_type ) unsigned
  655. X#   define ENUM_TYPE( enum_sp, enum_ty ) enum_ty
  656. X#   define NAME_CONFLICT( name ) _/**/name
  657. X#   define DOTDOTDOT ...
  658. X#   define _VOID_ /* anachronism */
  659. X#   define CONST const 
  660. X
  661. typedef void (*_PFV_)();
  662. typedef int (*_PFI_)();
  663. X
  664. X#elif defined(__STDC__)
  665. X    /*
  666. X     * Definitions for ANSI C
  667. X     */
  668. X#   define EXTERN_FUNCTION( rtn, args ) rtn args
  669. X#   define FUN_ARGS( args ) args
  670. X#   define STRUCT_TAG( tag_name ) tag_name
  671. X#   define ENUM_BITFIELD( enum_type ) unsigned
  672. X#   define ENUM_TYPE( enum_sp, enum_ty ) enum_sp enum_ty
  673. X#   define NAME_CONFLICT( name ) name
  674. X#   define DOTDOTDOT ...
  675. X#   define _VOID_ void
  676. X#   define CONST   
  677. X
  678. X#else
  679. X    /*
  680. X     * Definitions for Sun/K&R C -- ignore function prototypes,
  681. X     * but preserve tag names and enum bitfield declarations.
  682. X     */
  683. X#   define EXTERN_FUNCTION( rtn, args ) rtn()
  684. X#   define FUN_ARGS( args ) ()
  685. X#   define STRUCT_TAG( tag_name ) tag_name
  686. X#   define ENUM_BITFIELD( enum_type ) enum_type
  687. X#   define ENUM_TYPE( enum_sp, enum_ty ) enum_sp enum_ty
  688. X#   define NAME_CONFLICT( name ) name
  689. X#   define DOTDOTDOT
  690. X#   define _VOID_
  691. X    /* VOID is only used where it disappears anyway */
  692. X#   define CONST   
  693. X
  694. X#endif /* Which type of C/C++ compiler are we using? */
  695. X
  696. X#endif
  697. END_OF_FILE
  698. if test 2286 -ne `wc -c <'StdHdrs/rpc/c_types.h'`; then
  699.     echo shar: \"'StdHdrs/rpc/c_types.h'\" unpacked with wrong size!
  700. fi
  701. # end of 'StdHdrs/rpc/c_types.h'
  702. fi
  703. if test -f 'StdHdrs/rpc/pmap_clnt.h' -a "${1}" != "-c" ; then 
  704.   echo shar: Will not clobber existing file \"'StdHdrs/rpc/pmap_clnt.h'\"
  705. else
  706. echo shar: Extracting \"'StdHdrs/rpc/pmap_clnt.h'\" \(3166 characters\)
  707. sed "s/^X//" >'StdHdrs/rpc/pmap_clnt.h' <<'END_OF_FILE'
  708. X/* @(#)pmap_clnt.h    2.1 88/07/29 4.0 RPCSRC; from 1.11 88/02/08 SMI */
  709. X/*
  710. X * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  711. X * unrestricted use provided that this legend is included on all tape
  712. X * media and as a part of the software program in whole or part.  Users
  713. X * may copy or modify Sun RPC without charge, but are not authorized
  714. X * to license or distribute it to anyone else except as part of a product or
  715. X * program developed by the user.
  716. X * 
  717. X * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  718. X * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  719. X * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  720. X * 
  721. X * Sun RPC is provided with no support and without any obligation on the
  722. X * part of Sun Microsystems, Inc. to assist in its use, correction,
  723. X * modification or enhancement.
  724. X * 
  725. X * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  726. X * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  727. X * OR ANY PART THEREOF.
  728. X * 
  729. X * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  730. X * or profits or other special, indirect and consequential damages, even if
  731. X * Sun has been advised of the possibility of such damages.
  732. X * 
  733. X * Sun Microsystems, Inc.
  734. X * 2550 Garcia Avenue
  735. X * Mountain View, California  94043
  736. X */
  737. X
  738. X/*
  739. X * pmap_clnt.h
  740. X * Supplies C routines to get to portmap services.
  741. X *
  742. X * Copyright (C) 1984, Sun Microsystems, Inc.
  743. X */
  744. X
  745. X/*
  746. X * Usage:
  747. X *    success = pmap_set(program, version, protocol, port);
  748. X *    success = pmap_unset(program, version);
  749. X *    port = pmap_getport(address, program, version, protocol);
  750. X *    head = pmap_getmaps(address);
  751. X *    clnt_stat = pmap_rmtcall(address, program, version, procedure,
  752. X *        xdrargs, argsp, xdrres, resp, tout, port_ptr)
  753. X *        (works for udp only.) 
  754. X *     clnt_stat = clnt_broadcast(program, version, procedure,
  755. X *        xdrargs, argsp,    xdrres, resp, eachresult)
  756. X *        (like pmap_rmtcall, except the call is broadcasted to all
  757. X *        locally connected nets.  For each valid response received,
  758. X *        the procedure eachresult is called.  Its form is:
  759. X *    done = eachresult(resp, raddr)
  760. X *        bool_t done;
  761. X *        caddr_t resp;
  762. X *        struct sockaddr_in raddr;
  763. X *        where resp points to the results of the call and raddr is the
  764. X *        address if the responder to the broadcast.
  765. X */
  766. X
  767. X#ifndef _rpc_pmap_clnt_h
  768. X#define    _rpc_pmap_clnt_h
  769. X
  770. X#include <rpc/c_types.h>
  771. X
  772. XEXTERN_FUNCTION(bool_t        pmap_set, (u_long prognum, u_long versnum, 
  773. X                       int protocol, u_short port));
  774. XEXTERN_FUNCTION(bool_t        pmap_unset, (u_long prognum, u_long versnum));
  775. XEXTERN_FUNCTION(struct pmaplist    *pmap_getmaps, (struct sockaddr_in *addr));
  776. XEXTERN_FUNCTION(enum clnt_stat pmap_rmtcall, (struct sockaddr_in *addr,
  777. X                          u_long prognum, u_long versnum,
  778. X                          u_long procnum,
  779. X                          char *in, char *out,
  780. X                          xdrproc_t inproc, 
  781. X                          xdrproc_t outproc,
  782. X                          struct timeval timeout,
  783. X                          u_long *portp));
  784. XEXTERN_FUNCTION(enum clnt_stat        clnt_broadcast, ());
  785. XEXTERN_FUNCTION(u_short        pmap_getport, (struct sockaddr_in *addr,
  786. X                           u_long prognum, u_long versnum,
  787. X                           u_long protocol));
  788. X
  789. X#endif /*!_rpc_pmap_clnt_h*/
  790. END_OF_FILE
  791. if test 3166 -ne `wc -c <'StdHdrs/rpc/pmap_clnt.h'`; then
  792.     echo shar: \"'StdHdrs/rpc/pmap_clnt.h'\" unpacked with wrong size!
  793. fi
  794. # end of 'StdHdrs/rpc/pmap_clnt.h'
  795. fi
  796. if test -f 'callback.cc' -a "${1}" != "-c" ; then 
  797.   echo shar: Will not clobber existing file \"'callback.cc'\"
  798. else
  799. echo shar: Extracting \"'callback.cc'\" \(1312 characters\)
  800. sed "s/^X//" >'callback.cc' <<'END_OF_FILE'
  801. X// -*- c++ -*-
  802. X/* 
  803. Copyright (C) 1991 Peter Bersen
  804. X
  805. This file is part of the rpc++ Library.  This library is free
  806. software; you can redistribute it and/or modify it under the terms of
  807. the GNU Library General Public License as published by the Free
  808. Software Foundation; either version 2 of the License, or (at your
  809. option) any later version.  This library is distributed in the hope
  810. that it will be useful, but WITHOUT ANY WARRANTY; without even the
  811. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  812. PURPOSE.  See the GNU Library General Public License for more details.
  813. You should have received a copy of the GNU Library General Public
  814. License along with this library; if not, write to the Free Software
  815. XFoundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  816. X
  817. Modified and partially rewritten March 1992 by Michael N. Lipp,
  818. mnl@dtro.e-technik.th-darmstadt.de. The original copyright terms and
  819. conditions apply without change to any modified or new parts.
  820. X*/
  821. X
  822. static char _rpcpp_callback_cc_[]
  823. X= "callback.cc,v 2.2 1992/06/15 19:12:37 mnl Exp";
  824. X
  825. X// callback.cc,v
  826. X// Revision 2.2  1992/06/15  19:12:37  mnl
  827. X// Fixed a few bugs, clarified interface.
  828. X//
  829. X// Revision 2.1.1.1  1992/03/08  13:28:42  mnl
  830. X// Initial mnl version.
  831. X//
  832. X
  833. X#ifdef __GNUG__
  834. X#pragma implementation
  835. X#endif
  836. X
  837. X#include "rpc++/callback.h"
  838. X
  839. END_OF_FILE
  840. if test 1312 -ne `wc -c <'callback.cc'`; then
  841.     echo shar: \"'callback.cc'\" unpacked with wrong size!
  842. fi
  843. # end of 'callback.cc'
  844. fi
  845. if test ! -d 'example' ; then
  846.     echo shar: Creating directory \"'example'\"
  847.     mkdir 'example'
  848. fi
  849. if test -f 'example/.cvsignore' -a "${1}" != "-c" ; then 
  850.   echo shar: Will not clobber existing file \"'example/.cvsignore'\"
  851. else
  852. echo shar: Extracting \"'example/.cvsignore'\" \(28 characters\)
  853. sed "s/^X//" >'example/.cvsignore' <<'END_OF_FILE'
  854. X.dependencies
  855. server
  856. client
  857. END_OF_FILE
  858. if test 28 -ne `wc -c <'example/.cvsignore'`; then
  859.     echo shar: \"'example/.cvsignore'\" unpacked with wrong size!
  860. fi
  861. # end of 'example/.cvsignore'
  862. fi
  863. if test -f 'example/Makefile' -a "${1}" != "-c" ; then 
  864.   echo shar: Will not clobber existing file \"'example/Makefile'\"
  865. else
  866. echo shar: Extracting \"'example/Makefile'\" \(874 characters\)
  867. sed "s/^X//" >'example/Makefile' <<'END_OF_FILE'
  868. TOP = ..
  869. SUBDIRS = 
  870. X
  871. CC = gcc
  872. CPPFLAGS = -I..
  873. CFLAGS = -ggdb
  874. C++FLAGS = $(CFLAGS)
  875. X# for Linux:
  876. LOADLIBES = -L.. -lrpc++ -nojump -lg++
  877. X# for SunOS:
  878. X#LOADLIBES = -L.. -lrpc++ -lg++
  879. X# for ISC 2.2:
  880. X#LOADLIBES = -L.. -lrpc++ -lrpclib -lmisc -lg++ -linet -liberty
  881. X
  882. X
  883. HDRS = calcsvc.h
  884. SRCS = server.cc client.cc calcsvc.cc
  885. X
  886. all:: server client
  887. X
  888. server: server.o calcsvc.o
  889. X    $(CC) -o $@ server.o calcsvc.o $(LOADLIBES)
  890. X
  891. client: client.o calcsvc.o
  892. X    $(CC) -o $@ client.o calcsvc.o $(LOADLIBES)
  893. X
  894. DISTLIST = Makefile $(HDRS) $(SRCS)
  895. X
  896. clean::
  897. X    rm -f $(CLEANWILDCARDS) server client
  898. X
  899. include .dependencies
  900. X
  901. X.dependencies: $(HDRS) $(SRCS)
  902. X    gcc -M $(CPPFLAGS) $(SRCS) > .dependencies
  903. X
  904. distlist::
  905. X    @for f in *.[ch] *.cc; do \
  906. X      if expr " $(DISTLIST) " : ".* $$f " >/dev/null; then : ; \
  907. X      else echo 1>&2 "Warning: c- or h-file \"$$f\" not in DISTLIST"; fi; \
  908. X    done
  909. X
  910. include $(TOP)/Proj.make
  911. END_OF_FILE
  912. if test 874 -ne `wc -c <'example/Makefile'`; then
  913.     echo shar: \"'example/Makefile'\" unpacked with wrong size!
  914. fi
  915. # end of 'example/Makefile'
  916. fi
  917. if test -f 'example/calcsvc.cc' -a "${1}" != "-c" ; then 
  918.   echo shar: Will not clobber existing file \"'example/calcsvc.cc'\"
  919. else
  920. echo shar: Extracting \"'example/calcsvc.cc'\" \(1107 characters\)
  921. sed "s/^X//" >'example/calcsvc.cc' <<'END_OF_FILE'
  922. X// -*- c++ -*-
  923. static char _calcsvc_cc_[]
  924. X= "calcsvc.cc,v 2.3 1992/06/15 19:13:13 mnl Exp";
  925. X
  926. X// calcsvc.cc,v
  927. X// Revision 2.3  1992/06/15  19:13:13  mnl
  928. X// Fixed a few bugs, clarified interface.
  929. X//
  930. X// Revision 2.2  1992/06/13  14:27:28  mnl
  931. X// Adapted to (patched) gcc-2.2. Fixed several bugs.
  932. X//
  933. X// Revision 2.1.1.1  1992/03/08  13:28:45  mnl
  934. X// Initial mnl version.
  935. X//
  936. X
  937. X#include <stream.h>
  938. X#include "calcsvc.h"
  939. X
  940. XXdrInfo& Xmyint = Xdr::Xint;
  941. X
  942. RpcRequest CalcRequests::Add (1, &Xmyint, &Xdr::Xint, &Xdr::Xint);
  943. RpcRequest CalcRequests::Sub (2, &Xdr::Xint, &Xdr::Xint, &Xdr::Xint);
  944. RpcRequest CalcRequests::Times (3, &Xdr::Xint, &Xdr::Xint, &Xdr::Xint);
  945. RpcRequest CalcRequests::Div (4, &Xdr::Xint, &Xdr::Xint, &Xdr::Xint);
  946. RpcRequest CalcRequests::Inc (5, &Xdr::Xint, &Xdr::Xint);
  947. RpcRequest CalcRequests::IToA (6, &Xdr::Xwrapstring, &Xdr::Xint);
  948. RpcRequest CalcRequests::Reset (7, &Xdr::Xvoid);
  949. RpcRequest CalcRequests::Sleep (8, &Xdr::Xnull, &Xdr::Xint, RpcRequest::async);
  950. RpcRequest CalcRequests::Msg (9, &Xdr::Xvoid, &Xdr::Xwrapstring);
  951. RpcRequest CalcRequests::Invalid (100, &Xdr::Xvoid, &Xdr::Xvoid);
  952. END_OF_FILE
  953. if test 1107 -ne `wc -c <'example/calcsvc.cc'`; then
  954.     echo shar: \"'example/calcsvc.cc'\" unpacked with wrong size!
  955. fi
  956. # end of 'example/calcsvc.cc'
  957. fi
  958. if test -f 'example/calcsvc.h' -a "${1}" != "-c" ; then 
  959.   echo shar: Will not clobber existing file \"'example/calcsvc.h'\"
  960. else
  961. echo shar: Extracting \"'example/calcsvc.h'\" \(751 characters\)
  962. sed "s/^X//" >'example/calcsvc.h' <<'END_OF_FILE'
  963. X// -*- c++ -*-
  964. X#ifndef _CALCSERVICE_H_
  965. X#define _CALCSERVICE_H_
  966. static char _calcsvc_h_[]
  967. X= "calcsvc.h,v 2.3 1992/06/15 19:13:15 mnl Exp";
  968. X
  969. X// calcsvc.h,v
  970. X// Revision 2.3  1992/06/15  19:13:15  mnl
  971. X// Fixed a few bugs, clarified interface.
  972. X//
  973. X
  974. X#ifdef __GNUG__
  975. X#pragma interface
  976. X#endif
  977. X
  978. X#include "rpc++/request.h"
  979. X
  980. X#define CALCSVC 0x20100001
  981. X
  982. struct CalcRequests
  983. X{
  984. X  static RpcRequest Add;
  985. X  static RpcRequest Sub;
  986. X  static RpcRequest Times;
  987. X  static RpcRequest Div;
  988. X  static RpcRequest Inc;
  989. X  static RpcRequest IToA;
  990. X  static RpcRequest Reset; // for testing proc without args
  991. X  static RpcRequest Sleep; // for testing async
  992. X  static RpcRequest Msg;   // for testing string passing
  993. X  static RpcRequest Invalid; // for testing error handling
  994. X};
  995. X
  996. X#endif
  997. END_OF_FILE
  998. if test 751 -ne `wc -c <'example/calcsvc.h'`; then
  999.     echo shar: \"'example/calcsvc.h'\" unpacked with wrong size!
  1000. fi
  1001. # end of 'example/calcsvc.h'
  1002. fi
  1003. if test -f 'example/client.cc' -a "${1}" != "-c" ; then 
  1004.   echo shar: Will not clobber existing file \"'example/client.cc'\"
  1005. else
  1006. echo shar: Extracting \"'example/client.cc'\" \(1635 characters\)
  1007. sed "s/^X//" >'example/client.cc' <<'END_OF_FILE'
  1008. X// -*- c++ -*-
  1009. static char _client_cc_[]
  1010. X= "client.cc,v 2.3 1992/06/15 19:13:17 mnl Exp";
  1011. X
  1012. X// client.cc,v
  1013. X// Revision 2.3  1992/06/15  19:13:17  mnl
  1014. X// Fixed a few bugs, clarified interface.
  1015. X//
  1016. X// Revision 2.2  1992/06/13  14:27:32  mnl
  1017. X// Adapted to (patched) gcc-2.2. Fixed several bugs.
  1018. X//
  1019. X// Revision 2.1.1.1  1992/03/08  13:28:45  mnl
  1020. X// Initial mnl version.
  1021. X//
  1022. X
  1023. X#include <stream.h>
  1024. X#include "rpc++/stub.h"
  1025. X
  1026. X#include "calcsvc.h"
  1027. X
  1028. class CalcStub : public RpcStub
  1029. X{
  1030. public:
  1031. X  inline CalcStub (u_long prognum, u_long versnum,
  1032. X           char* hostname = "localhost",
  1033. X           timeval timeout = defaultTimeout, bool connect = TRUE)
  1034. X    : RpcStub (prognum, versnum, hostname, timeout, connect) {}
  1035. X
  1036. X  inline void Reset ()
  1037. X    { Call (CalcRequests::Reset); }
  1038. X  inline int Inc (int i)
  1039. X    { return *(int*)Call (CalcRequests::Inc, &i); }
  1040. X  inline char* IToA (int i)
  1041. X    { return *(char**)Call (CalcRequests::IToA, &i); }
  1042. X  inline int Add (int s1, int s2)
  1043. X    { return *(int*)Call (CalcRequests::Add, &s1, &s2); }
  1044. X
  1045. X  inline void Msg (char* msg)
  1046. X    { Call (CalcRequests::Msg, &msg); }
  1047. X  inline void Sleep (int secs)
  1048. X    { Call (CalcRequests::Sleep, &secs); }
  1049. X};
  1050. X
  1051. main (int argc, char* argv[])
  1052. X{
  1053. X  char* server = argv[1];
  1054. X
  1055. X  CalcStub svc (CALCSVC, 1, server);
  1056. X  svc.Reset ();
  1057. X  svc.Msg ("Hello server.\n");
  1058. X  int i = 0, o;
  1059. X  while (i < 10)
  1060. X    {
  1061. X      o = svc.Inc (i);
  1062. X      cout << svc.IToA (o) << '\n';
  1063. X      i = o;
  1064. X    }
  1065. X  i = svc.Add (12, 23);
  1066. X  cout << "add (" << 12 << ", " << 23 << ") = " << i << endl;
  1067. X  cout << "Calling Sleep (5) asynchronously.\n";
  1068. X  svc.Sleep (5);
  1069. X  cout << "Sleep call completed.\n";
  1070. X  svc.Call (CalcRequests::Invalid);
  1071. X}
  1072. END_OF_FILE
  1073. if test 1635 -ne `wc -c <'example/client.cc'`; then
  1074.     echo shar: \"'example/client.cc'\" unpacked with wrong size!
  1075. fi
  1076. # end of 'example/client.cc'
  1077. fi
  1078. if test -f 'example/server.cc' -a "${1}" != "-c" ; then 
  1079.   echo shar: Will not clobber existing file \"'example/server.cc'\"
  1080. else
  1081. echo shar: Extracting \"'example/server.cc'\" \(2434 characters\)
  1082. sed "s/^X//" >'example/server.cc' <<'END_OF_FILE'
  1083. X// -*- c++ -*-
  1084. static char _server_cc_[]
  1085. X= "server.cc,v 2.3 1992/06/15 19:13:18 mnl Exp";
  1086. X
  1087. X// server.cc,v
  1088. X// Revision 2.3  1992/06/15  19:13:18  mnl
  1089. X// Fixed a few bugs, clarified interface.
  1090. X//
  1091. X// Revision 2.2  1992/06/13  14:27:33  mnl
  1092. X// Adapted to (patched) gcc-2.2. Fixed several bugs.
  1093. X//
  1094. X// Revision 2.1.1.1  1992/03/08  13:28:45  mnl
  1095. X// Initial mnl version.
  1096. X//
  1097. X
  1098. X#include <unistd.h>
  1099. X#include <stream.h>
  1100. X#include <string.h>
  1101. X#include <malloc.h>
  1102. X
  1103. X#include "rpc++/service.h"
  1104. X#include "calcsvc.h"
  1105. X
  1106. class Calc
  1107. X{
  1108. public:
  1109. X  void* Add (void*, void*);
  1110. X  void* Sub (void*, void*);
  1111. X  void* Times (void*, void*);
  1112. X  void* Div (void*, void*);
  1113. X  void* Inc (void*);
  1114. X  void* IToA (void**);
  1115. X  void Reset (RpcService*);
  1116. X};
  1117. X
  1118. void* Calc::Add (void* in1, void* in2)
  1119. X{
  1120. X  static int res;
  1121. X  res = *(int*)in1 + *(int*)in2;
  1122. X  return &res;
  1123. X}
  1124. X
  1125. void* Calc::Sub (void* in1, void* in2)
  1126. X{
  1127. X  static int res;
  1128. X  res = *(int*)in1 - *(int*)in2;
  1129. X  return &res;
  1130. X}
  1131. X
  1132. void* Calc::Times (void* in1, void* in2)
  1133. X{
  1134. X  static int res;
  1135. X  res = *(int*)in1 * *(int*)in2;
  1136. X  return &res;
  1137. X}
  1138. X
  1139. void* Calc::Div (void* in1, void* in2)
  1140. X{
  1141. X  static int res;
  1142. X  res = *(int*)in1 / *(int*)in2;
  1143. X  return &res;
  1144. X}
  1145. X
  1146. void* Calc::Inc (void* in)
  1147. X{
  1148. X  static int res;
  1149. X  res = *(int*)in + 1;
  1150. X  return &res;
  1151. X}
  1152. X
  1153. void* Calc::IToA (void** in)
  1154. X{
  1155. X  static char *s = 0;
  1156. X  delete s;
  1157. X  char *t = form ("%d", *(int*)in[0]);
  1158. X  s = new char[strlen (t) + 1];
  1159. X  strcpy (s, t);
  1160. X  return &s;
  1161. X}
  1162. X
  1163. void Calc::Reset (RpcService* svc)
  1164. X{
  1165. X  cout << "Received reset from " << svc->CallerName () << ".\n";
  1166. X}
  1167. X
  1168. void printMessage (void* in)
  1169. X{
  1170. X  cout << *(char**)in;
  1171. X}
  1172. X
  1173. void doSleep (void* in)
  1174. X{
  1175. X  cout << form ("Sleeping %d secs.\n", *(int*)in);
  1176. X  sleep (*(int*)in);
  1177. X  cout << "Woke up.\n";
  1178. X}
  1179. X
  1180. main ()
  1181. X{
  1182. X  RpcService svc (CALCSVC, 1);
  1183. X  Calc calc;
  1184. X  svc.Register (CalcRequests::Add, RpcMethodCall<Calc> (&calc, &calc.Add));
  1185. X  svc.Register (CalcRequests::Sub, RpcMethodCall<Calc> (&calc, &calc.Sub));
  1186. X  svc.Register (CalcRequests::Times, RpcMethodCall<Calc> (&calc, &calc.Times));
  1187. X  svc.Register (CalcRequests::Div, RpcMethodCall<Calc> (&calc, &calc.Div));
  1188. X  svc.Register (CalcRequests::Inc, RpcMethodCall<Calc> (&calc, &calc.Inc));
  1189. X  svc.Register (CalcRequests::IToA,RpcMethodCall<Calc>(&calc, &calc.IToA));
  1190. X  svc.Register (CalcRequests::Reset, RpcMethodCall<Calc> (&calc, &calc.Reset));
  1191. X  svc.Register (CalcRequests::Msg, RpcCallback (printMessage));
  1192. X  svc.Register (CalcRequests::Sleep, RpcCallback (doSleep));
  1193. X  svc.Provide ();
  1194. X}
  1195. END_OF_FILE
  1196. if test 2434 -ne `wc -c <'example/server.cc'`; then
  1197.     echo shar: \"'example/server.cc'\" unpacked with wrong size!
  1198. fi
  1199. # end of 'example/server.cc'
  1200. fi
  1201. if test -f 'gcc-2.2.fix' -a "${1}" != "-c" ; then 
  1202.   echo shar: Will not clobber existing file \"'gcc-2.2.fix'\"
  1203. else
  1204. echo shar: Extracting \"'gcc-2.2.fix'\" \(8606 characters\)
  1205. sed "s/^X//" >'gcc-2.2.fix' <<'END_OF_FILE'
  1206. To: bug-g++@prep.ai.mit.edu
  1207. Subject: gcc-2.2 loops with template-local typedefs (bug&patch)
  1208. BCC: mnl,ulf
  1209. X--text follows this line--
  1210. Hi,
  1211. X
  1212. trying to translate the following fragment on a Sparc running SunOs 4.1.2
  1213. with gcc-2.2 results in gcc infinitly looping.
  1214. X
  1215. X---------------------------------------------------------------------------
  1216. X// -*- c++ -*-
  1217. X
  1218. class AnyRpcCallback
  1219. X{
  1220. protected:
  1221. X
  1222. public:
  1223. X  inline virtual ~AnyRpcCallback () {}
  1224. X  inline virtual void Do (void* in, void* out) = 0;
  1225. X};
  1226. X
  1227. template<class T> class RpcCallback : public AnyRpcCallback
  1228. X{
  1229. X  typedef void (T::*Method)(void*, void*);
  1230. X  typedef void (T::*MethodN)(void*, void**);
  1231. X  typedef void (T::*Method1)(void*, void*);
  1232. X  typedef void (T::*Method2)(void*, void*, void*);
  1233. X
  1234. private:
  1235. X  T* object;
  1236. X  void (T::*method)(void*, void*);
  1237. X
  1238. public:
  1239. X  inline RpcCallback (T* o, void* m)
  1240. X    { object = o; method = m; }
  1241. X  inline void Do (void* in, void* out)
  1242. X    { (object->*method)(in, out); }
  1243. X};
  1244. X
  1245. class Test
  1246. X{
  1247. public:
  1248. X  void m (void*, void*);
  1249. X};
  1250. X
  1251. main ()
  1252. X{
  1253. X  Test o;
  1254. X  AnyRpcCallback* cb = new RpcCallback<Test> (&o, &Test::m);
  1255. X}
  1256. X---------------------------------------------------------------------------
  1257. X
  1258. PLEASE NOTE that you will get another loop due to a bug that I have
  1259. reported together with a patch earlier (it's appended to this mail).
  1260. So you won't be able to reproduce the bug reported in this mail unless
  1261. you have my previous patch applied. I am, however, definitely sure
  1262. X(and the explanation below will confirm it) that the bug reported in
  1263. this mail is *NOT* caused by my patch!
  1264. X
  1265. The problem is, that the "chain" field of the tree-nodes used by gcc
  1266. for its internal representation is used for various purposes, and in
  1267. the case of this template-local typedef, someone lost track of its usage.
  1268. X
  1269. After parsing, the TYPE_DECL-node created for the typedef is appended
  1270. to the scope via "pushlevel". Types in the current scope are linked
  1271. using the "chain" field. At the same time, however, all components of
  1272. the template are linked together during parsing using the same "chain"
  1273. field. Parsing the second typedef, "pushlevel" makes the first typedef
  1274. a successor of the second typedef and the subsequent catenation of
  1275. components makes the second typedef a successor of the first typedef
  1276. thus creating a loop.
  1277. X
  1278. The resulting list of all components is used in routine
  1279. X"finish_struct".
  1280. X
  1281. I think the most proper approach would be to use TREE_LIST nodes in
  1282. the list of components as indirect references to the typedef-nodes.
  1283. This is easy to achieve, it is, however, very hard to modify
  1284. finish_struct in a way that it handles these indirection properly.
  1285. Actually, I gave up when I tried to understand & modify the routine
  1286. that removes the duplicate declarations from the list of components.
  1287. X
  1288. There are two easier approaches: (1) Don't include typedefs in the
  1289. list of components, (2) use copies of the typedef-node which have an
  1290. unused chain field. The first approach assumes that finish_struct
  1291. doesn't do anything with typedefs, so it wouldn't be important if they
  1292. are missing from the list of components. If this is the case, however,
  1293. it can't hurt to use copies of the typedef-nodes (copies of the
  1294. originals that are linked in the scope-list), so the second approach
  1295. is safer. It can only fail if finish_struct modifies the typedef-nodes
  1296. and this modification is significant for the typedef-nodes in the
  1297. scope-list (which are, of course, not modified. Only the copies are).
  1298. X
  1299. So I think the patch is pretty safe. It fixes the problem and doesn't
  1300. seem to introduce new ones. I'm aware that typedefs that are local to
  1301. templates stretch language features to the limits, but it makes my
  1302. C++ interface to RPCs real nice (I'll post it one of these days).
  1303. X
  1304. Michael
  1305. X
  1306. X*** .orig/cp-parse.y    Mon Jun 15 17:08:58 1992
  1307. X--- cp-parse.y    Mon Jun 15 19:13:15 1992
  1308. X***************
  1309. X*** 2211,2217 ****
  1310. X                if (TREE_CODE (t) == ENUMERAL_TYPE && TREE_NONLOCAL_FLAG (t))
  1311. X              $$ = grok_enum_decls (t, $2);
  1312. X                else
  1313. X!             $$ = $2;
  1314. X              }
  1315. X            end_exception_decls ();
  1316. X          }
  1317. X--- 2211,2233 ----
  1318. X                if (TREE_CODE (t) == ENUMERAL_TYPE && TREE_NONLOCAL_FLAG (t))
  1319. X              $$ = grok_enum_decls (t, $2);
  1320. X                else
  1321. X!             {
  1322. X!               /* if a component is a typedef, it is inserted
  1323. X!                  in the list of nodes that make up the valid
  1324. X!                  types in the scope. Thus its chain field is
  1325. X!                  used and can't be used a second time for linking
  1326. X!                  the components of the struct. So, we make a copy
  1327. X!                  here. This apparently works. The proper thing
  1328. X!                  to do, however, would be to use a TREE_LIST
  1329. X!                  node to reference the typedef. I tried to rewrite
  1330. X!                  finish_struct accordingly (i.e., ``dereference''
  1331. X!                  components TREE_LIST before use, but I gave up.
  1332. X!                  mnl@dtro.e-technik.th-darmstadt.de */
  1333. X!               if (TREE_CODE ($2) == TYPE_DECL)
  1334. X!                 $$ = copy_node ($2);
  1335. X!               else
  1336. X!                 $$ = $2;
  1337. X!             }
  1338. X              }
  1339. X            end_exception_decls ();
  1340. X          }
  1341. X
  1342. X===========================================================================
  1343. The previous bug:
  1344. X---------------------------------------------------------------------------
  1345. Return-Path: <mnl>
  1346. Date: Wed, 10 Jun 92 19:31:13 +0200
  1347. XFrom: "Michael N. Lipp" <mnl>
  1348. To: bug-g++@prep.ai.mit.edu
  1349. Subject: gcc-2.2 bug&patch: typedef in template
  1350. X
  1351. Hi,
  1352. X
  1353. gcc-2.2 on a sparc running SunOS 4.1.2 enters an infinite loop when
  1354. compiling this:
  1355. X
  1356. X-----------------------------------------------------------------------------
  1357. X// -*- c++ -*-
  1358. X
  1359. class AnyRpcCallback
  1360. X{
  1361. protected:
  1362. X
  1363. public:
  1364. X  inline virtual ~AnyRpcCallback () {}
  1365. X  inline virtual void Do (void* in, void* out) = 0;
  1366. X};
  1367. X
  1368. template<class T> class RpcCallback : public AnyRpcCallback
  1369. X{
  1370. X  typedef void (T::*Method)(void*, void*);
  1371. X
  1372. private:
  1373. X  T* object;
  1374. X  void (T::*method)(void*, void*);
  1375. X
  1376. public:
  1377. X  inline RpcCallback (T* o, void* m)
  1378. X    { object = o; method = m; }
  1379. X  inline void Do (void* in, void* out)
  1380. X    { (object->*method)(in, out); }
  1381. X};
  1382. X
  1383. class Test
  1384. X{
  1385. public:
  1386. X  void m (void*, void*);
  1387. X};
  1388. X
  1389. main ()
  1390. X{
  1391. X  Test o;
  1392. X  AnyRpcCallback* cb = new RpcCallback<Test> (&o, &Test::m);
  1393. X}
  1394. X-----------------------------------------------------------------------------
  1395. X
  1396. This is quite an improvement over gcc-2.1 which dumped core with this
  1397. source.
  1398. X
  1399. I tracked the cause down: grokdeclarator does a pushlevel(0), then
  1400. calls start_decl, which in turn calls grokdeclarator again which does
  1401. a poplevel_class. This poplevel_class pops the level pushed by
  1402. pushlevel(0) and so the poplevel performed by grokdeclarator to match
  1403. its pushlevel(0) pops quite a different level! This can easily be
  1404. observed by compiling cp-decl.c with -DDEBUG_CP_BINDING_LEVELS.
  1405. X
  1406. Here is a patch that fixes the bug. I don't think it hits the real
  1407. cause of this problem, but it works.
  1408. X
  1409. X*** .orig/cp-decl.c    Wed Jun 10 14:06:26 1992
  1410. X--- cp-decl.c    Wed Jun 10 15:20:38 1992
  1411. X***************
  1412. X*** 6874,6882 ****
  1413. X--- 6874,6889 ----
  1414. X        tree loc_typedecl;
  1415. X        register int i = sizeof (struct lang_decl_flags) / sizeof (int);
  1416. X        register int *pi;
  1417. X+       struct binding_level *local_binding_level;
  1418. X  
  1419. X        /* keep `grokdeclarator' from thinking we are in PARM context.  */
  1420. X        pushlevel (0);
  1421. X+       /* poplevel_class may be called by grokdeclarator which is called in
  1422. X+          start_decl which is called below. In this case, our pushed level
  1423. X+          may vanish and poplevel mustn't be called. So remember what we
  1424. X+          have pushed and pop only if that is matched by 
  1425. X+          current_binding_level later. mnl@dtro.e-technik.th-darmstadt.de */
  1426. X+       local_binding_level = current_binding_level;
  1427. X        loc_typedecl = start_decl (declarator, declspecs, initialized, NULL_TREE);
  1428. X  
  1429. X        pi = (int *) permalloc (sizeof (struct lang_decl_flags));
  1430. X***************
  1431. X*** 6883,6889 ****
  1432. X        while (i > 0)
  1433. X          pi[--i] = 0;
  1434. X        DECL_LANG_SPECIFIC (loc_typedecl) = (struct lang_decl *) pi;
  1435. X!       poplevel (0, 0, 0);
  1436. X  
  1437. X  #if 0
  1438. X        if (TREE_CODE (TREE_TYPE (loc_typedecl)) == ENUMERAL_TYPE)
  1439. X--- 6890,6897 ----
  1440. X        while (i > 0)
  1441. X          pi[--i] = 0;
  1442. X        DECL_LANG_SPECIFIC (loc_typedecl) = (struct lang_decl *) pi;
  1443. X!       if (current_binding_level == local_binding_level)
  1444. X!         poplevel (0, 0, 0);
  1445. X  
  1446. X  #if 0
  1447. X        if (TREE_CODE (TREE_TYPE (loc_typedecl)) == ENUMERAL_TYPE)
  1448. X
  1449. Michael
  1450. X
  1451. X-----------------,------------------------------,------------------------------
  1452. Michael N. Lipp  !  Institut fuer Datentechnik  !  Phone: 49-6151-163776
  1453. X                 !  Merckstr. 25     ,----------'  Fax:   49-6151-164976
  1454. X                 !  D-6100 Darmstadt ! E-Mail:
  1455. X                 !  (Germany)        !     mnl@dtro.e-technik.th-darmstadt.de
  1456. X-----------------'-------------------'-----------------------------------------
  1457. X
  1458. END_OF_FILE
  1459. if test 8606 -ne `wc -c <'gcc-2.2.fix'`; then
  1460.     echo shar: \"'gcc-2.2.fix'\" unpacked with wrong size!
  1461. fi
  1462. # end of 'gcc-2.2.fix'
  1463. fi
  1464. if test -f 'gcc-2.3.3.fix' -a "${1}" != "-c" ; then 
  1465.   echo shar: Will not clobber existing file \"'gcc-2.3.3.fix'\"
  1466. else
  1467. echo shar: Extracting \"'gcc-2.3.3.fix'\" \(7716 characters\)
  1468. sed "s/^X//" >'gcc-2.3.3.fix' <<'END_OF_FILE'
  1469. There are two bugs in gcc-2.3.3 that I have reported together with
  1470. fixes for gcc-2.2.2 previously.  The first bug is commented now (but
  1471. not fixed), the second isn't fixed either (I can understand that.  It
  1472. is hard to do it properly).  I'm repeating the bug report below
  1473. together with new context diffs.  Please note that I have not
  1474. re-debugged, I have simply found that the same patches make things
  1475. work.  So maybe the comments are out of date.
  1476. X
  1477. Bug1:
  1478. X
  1479. Compiling this
  1480. X--------------------------------------------------
  1481. X// -*- c++ -*-
  1482. X
  1483. class AnyRpcCallback
  1484. X{
  1485. protected:
  1486. X
  1487. public:
  1488. X  inline virtual ~AnyRpcCallback () {}
  1489. X  inline virtual void Do (void* in, void* out) = 0;
  1490. X};
  1491. X
  1492. template<class T> class RpcCallback : public AnyRpcCallback
  1493. X{
  1494. X  typedef void (T::*Method)(void*, void*);
  1495. X
  1496. private:
  1497. X  T* object;
  1498. X  void (T::*method)(void*, void*);
  1499. X
  1500. public:
  1501. X  inline RpcCallback (T* o, void* m)
  1502. X    { object = o; method = m; }
  1503. X  inline void Do (void* in, void* out)
  1504. X    { (object->*method)(in, out); }
  1505. X};
  1506. X
  1507. class Test
  1508. X{
  1509. public:
  1510. X  void m (void*, void*);
  1511. X};
  1512. X
  1513. void Test::m (void*, void*)
  1514. X{
  1515. X}
  1516. X
  1517. main ()
  1518. X{
  1519. X  Test o;
  1520. X  AnyRpcCallback* cb = new RpcCallback<Test> (&o, &Test::m);
  1521. X}
  1522. X--------------------------------------------------
  1523. results in cc1plus looping infinitely.
  1524. X
  1525. I tracked the cause down: grokdeclarator does a pushlevel(0), then
  1526. calls start_decl, which in turn calls grokdeclarator again which does
  1527. a poplevel_class. This poplevel_class pops the level pushed by
  1528. pushlevel(0) and so the poplevel performed by grokdeclarator to match
  1529. its pushlevel(0) pops quite a different level! This can easily be
  1530. observed by compiling cp-decl.c with -DDEBUG_CP_BINDING_LEVELS.
  1531. X
  1532. In gcc-2.3.3 the problem seems to be known as it is commented.
  1533. X
  1534. Here is a patch that fixes the bug. I don't think it hits the real
  1535. cause of this problem, but it works.
  1536. X
  1537. X*** cp-decl.c.orig    Sat Jan  2 15:04:20 1993
  1538. X--- cp-decl.c    Sat Jan  2 15:06:18 1993
  1539. X***************
  1540. X*** 7245,7253 ****
  1541. X--- 7245,7260 ----
  1542. X        tree loc_typedecl;
  1543. X        register int i = sizeof (struct lang_decl_flags) / sizeof (int);
  1544. X        register int *pi;
  1545. X+        struct binding_level *local_binding_level;
  1546. X  
  1547. X        /* keep `grokdeclarator' from thinking we are in PARM context.  */
  1548. X        pushlevel (0);
  1549. X+        /* poplevel_class may be called by grokdeclarator which is called in
  1550. X+           start_decl which is called below. In this case, our pushed level
  1551. X+           may vanish and poplevel mustn't be called. So remember what we
  1552. X+           have pushed and pop only if that is matched by 
  1553. X+           current_binding_level later. mnl@dtro.e-technik.th-darmstadt.de */
  1554. X+        local_binding_level = current_binding_level;
  1555. X        loc_typedecl = start_decl (declarator, declspecs, initialized, NULL_TREE);
  1556. X  
  1557. X        pi = (int *) permalloc (sizeof (struct lang_decl_flags));
  1558. X***************
  1559. X*** 7256,7262 ****
  1560. X        DECL_LANG_SPECIFIC (loc_typedecl) = (struct lang_decl *) pi;
  1561. X        /* This poplevel conflicts with the popclass over in
  1562. X           grokdeclarator.  See ``This popclass conflicts'' */
  1563. X!       poplevel (0, 0, 0);
  1564. X  
  1565. X  #if 0
  1566. X        if (TREE_CODE (TREE_TYPE (loc_typedecl)) == ENUMERAL_TYPE)
  1567. X--- 7263,7270 ----
  1568. X        DECL_LANG_SPECIFIC (loc_typedecl) = (struct lang_decl *) pi;
  1569. X        /* This poplevel conflicts with the popclass over in
  1570. X           grokdeclarator.  See ``This popclass conflicts'' */
  1571. X!        if (current_binding_level == local_binding_level)
  1572. X!         poplevel (0, 0, 0);
  1573. X  
  1574. X  #if 0
  1575. X        if (TREE_CODE (TREE_TYPE (loc_typedecl)) == ENUMERAL_TYPE)
  1576. X
  1577. Bug2:
  1578. X
  1579. Compiling this
  1580. X--------------------------------------------------
  1581. X// -*- c++ -*-
  1582. X
  1583. class AnyRpcCallback
  1584. X{
  1585. protected:
  1586. X
  1587. public:
  1588. X  inline virtual ~AnyRpcCallback () {}
  1589. X  inline virtual void Do (void* in, void* out) = 0;
  1590. X};
  1591. X
  1592. template<class T> class RpcCallback : public AnyRpcCallback
  1593. X{
  1594. X  typedef void (T::*Method)(void*, void*);
  1595. X  typedef void (T::*MethodN)(void*, void**);
  1596. X  typedef void (T::*Method1)(void*, void*);
  1597. X  typedef void (T::*Method2)(void*, void*, void*);
  1598. X
  1599. private:
  1600. X  T* object;
  1601. X  void (T::*method)(void*, void*);
  1602. X
  1603. public:
  1604. X  inline RpcCallback (T* o, void* m)
  1605. X    { object = o; method = m; }
  1606. X  inline void Do (void* in, void* out)
  1607. X    { (object->*method)(in, out); }
  1608. X};
  1609. X
  1610. class Test
  1611. X{
  1612. public:
  1613. X  void m (void*, void*);
  1614. X};
  1615. X
  1616. main ()
  1617. X{
  1618. X  Test o;
  1619. X  AnyRpcCallback* cb = new RpcCallback<Test> (&o, &Test::m);
  1620. X}
  1621. X--------------------------------------------------
  1622. results in cc1plus looping infinitely.
  1623. X
  1624. The problem is that the "chain" field of the tree-nodes used by gcc
  1625. for its internal representation is used for various purposes, and in
  1626. the case of this template-local typedef, someone lost track of its usage.
  1627. X
  1628. After parsing, the TYPE_DECL-node created for the typedef is appended
  1629. to the scope via "pushlevel". Types in the current scope are linked
  1630. using the "chain" field. At the same time, however, all components of
  1631. the template are linked together during parsing using the same "chain"
  1632. field. Parsing the second typedef, "pushlevel" makes the first typedef
  1633. a successor of the second typedef and the subsequent catenation of
  1634. components makes the second typedef a successor of the first typedef
  1635. thus creating a loop.
  1636. X
  1637. The resulting list of all components is used in routine
  1638. X"finish_struct".
  1639. X
  1640. I think the most proper approach would be to use TREE_LIST nodes in
  1641. the list of components as indirect references to the typedef-nodes.
  1642. This is easy to achieve, it is, however, very hard to modify
  1643. finish_struct in a way that it handles these indirection properly.
  1644. Actually, I gave up when I tried to understand & modify the routine
  1645. that removes the duplicate declarations from the list of components.
  1646. X
  1647. There are two easier approaches: (1) Don't include typedefs in the
  1648. list of components, (2) use copies of the typedef-node which have an
  1649. unused chain field. The first approach assumes that finish_struct
  1650. doesn't do anything with typedefs, so it wouldn't be important if they
  1651. are missing from the list of components. If this is the case, however,
  1652. it can't hurt to use copies of the typedef-nodes (copies of the
  1653. originals that are linked in the scope-list), so the second approach
  1654. is safer. It can only fail if finish_struct modifies the typedef-nodes
  1655. and this modification is significant for the typedef-nodes in the
  1656. scope-list (which are, of course, not modified. Only the copies are).
  1657. X
  1658. So I think the patch is pretty safe. It fixes the problem and doesn't
  1659. seem to introduce new ones. I'm aware that typedefs that are local to
  1660. templates stretch language features to the limits, but it makes my
  1661. C++ interface to RPCs real nice.
  1662. X
  1663. X*** cp-parse.y.orig    Sat Jan  2 15:17:13 1993
  1664. X--- cp-parse.y    Sat Jan  2 15:18:13 1993
  1665. X***************
  1666. X*** 2335,2341 ****
  1667. X                if (TREE_CODE (t) == ENUMERAL_TYPE && TREE_NONLOCAL_FLAG (t))
  1668. X              $$ = grok_enum_decls (t, $2);
  1669. X                else
  1670. X!             $$ = $2;
  1671. X              }
  1672. X            end_exception_decls ();
  1673. X          }
  1674. X--- 2335,2357 ----
  1675. X                if (TREE_CODE (t) == ENUMERAL_TYPE && TREE_NONLOCAL_FLAG (t))
  1676. X              $$ = grok_enum_decls (t, $2);
  1677. X                else
  1678. X!             {
  1679. X!                /* if a component is a typedef, it is inserted
  1680. X!                   in the list of nodes that make up the valid
  1681. X!                   types in the scope. Thus its chain field is
  1682. X!                   used and can't be used a second time for linking
  1683. X!                   the components of the struct. So, we make a copy
  1684. X!                   here. This apparently works. The proper thing
  1685. X!                   to do, however, would be to use a TREE_LIST
  1686. X!                   node to reference the typedef. I tried to rewrite
  1687. X!                   finish_struct accordingly (i.e., ``dereference''
  1688. X!                   components TREE_LIST before use, but I gave up.
  1689. X!                   mnl@dtro.e-technik.th-darmstadt.de */
  1690. X!                if (TREE_CODE ($2) == TYPE_DECL)
  1691. X!                  $$ = copy_node ($2);
  1692. X!                else
  1693. X!                 $$ = $2;
  1694. X!             }
  1695. X              }
  1696. X            end_exception_decls ();
  1697. X          }
  1698. END_OF_FILE
  1699. if test 7716 -ne `wc -c <'gcc-2.3.3.fix'`; then
  1700.     echo shar: \"'gcc-2.3.3.fix'\" unpacked with wrong size!
  1701. fi
  1702. # end of 'gcc-2.3.3.fix'
  1703. fi
  1704. if test -f 'request.cc' -a "${1}" != "-c" ; then 
  1705.   echo shar: Will not clobber existing file \"'request.cc'\"
  1706. else
  1707. echo shar: Extracting \"'request.cc'\" \(4750 characters\)
  1708. sed "s/^X//" >'request.cc' <<'END_OF_FILE'
  1709. X// -*- c++ -*-
  1710. X/* 
  1711. Copyright (C) 1991 Peter Bersen
  1712. X
  1713. This file is part of the rpc++ Library.  This library is free
  1714. software; you can redistribute it and/or modify it under the terms of
  1715. the GNU Library General Public License as published by the Free
  1716. Software Foundation; either version 2 of the License, or (at your
  1717. option) any later version.  This library is distributed in the hope
  1718. that it will be useful, but WITHOUT ANY WARRANTY; without even the
  1719. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  1720. PURPOSE.  See the GNU Library General Public License for more details.
  1721. You should have received a copy of the GNU Library General Public
  1722. License along with this library; if not, write to the Free Software
  1723. XFoundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  1724. X
  1725. Modified and partially rewritten March 1992 by Michael N. Lipp,
  1726. mnl@dtro.e-technik.th-darmstadt.de. The original copyright terms and
  1727. conditions apply without change to any modified or new parts.
  1728. X*/
  1729. X
  1730. static char _rpcpp_request_cc_[]
  1731. X= "request.cc,v 2.4 1992/08/08 13:11:40 mnl Exp";
  1732. X
  1733. X// request.cc,v
  1734. X// Revision 2.4  1992/08/08  13:11:40  mnl
  1735. X// RpcRequest(const RpcRequest&) added, 'cause RpcRequest has pointers
  1736. X// to heap.
  1737. X//
  1738. X// Revision 2.3  1992/06/15  19:12:39  mnl
  1739. X// Fixed a few bugs, clarified interface.
  1740. X//
  1741. X// Revision 2.2  1992/06/13  14:27:01  mnl
  1742. X// Adapted to (patched) gcc-2.2. Fixed several bugs.
  1743. X//
  1744. X// Revision 2.1.1.1  1992/03/08  13:28:42  mnl
  1745. X// Initial mnl version.
  1746. X//
  1747. X
  1748. X#ifdef __GNUG__
  1749. X#pragma implementation
  1750. X#endif
  1751. X
  1752. X#include "rpc++/request.h"
  1753. X
  1754. X#include <assert.h>
  1755. X
  1756. void RpcRequest::init (u_long req, int pars, int parsz,
  1757. X               const XdrInfo* out, const XdrInfo** in, int rt)
  1758. X{
  1759. X  params = pars;
  1760. X  parmsz = parsz;
  1761. X  reqnum = req;
  1762. X  ininfo = in;
  1763. X  ininfo[params] = (XdrInfo*)0;
  1764. X  outinfo = out;
  1765. X  reqtype = rt;
  1766. X  assert (rt == normal || outinfo->Proc () == 0);
  1767. X}
  1768. X
  1769. RpcRequest::RpcRequest (const RpcRequest& r)
  1770. X{
  1771. X  params = r.params;
  1772. X  parmsz = r.parmsz;
  1773. X  reqnum = r.reqnum;
  1774. X  ininfo = new XdrInfo*[params + 1];
  1775. X  memcpy (ininfo, r.ininfo, (params + 1) * sizeof (XdrInfo*));
  1776. X  outinfo = r.outinfo;
  1777. X  reqtype = r.reqtype;
  1778. X}
  1779. X  
  1780. RpcRequest::RpcRequest(u_long req, const XdrInfo* out, int t)
  1781. X{
  1782. X  init (req, 0, 0, out, new XdrInfo*[1], t);
  1783. X}
  1784. X
  1785. RpcRequest::RpcRequest(u_long req, const XdrInfo* out, const XdrInfo* in,
  1786. X               int t)
  1787. X{
  1788. X  const XdrInfo** a = new XdrInfo*[2];
  1789. X  a[0] = in;
  1790. X  init (req, 1, -1, out, a, t);
  1791. X}
  1792. X
  1793. RpcRequest::RpcRequest(u_long req, const XdrInfo* out, const XdrInfo* in0,
  1794. X               const XdrInfo* in1, int t)
  1795. X{
  1796. X  const XdrInfo** a = new XdrInfo*[3];
  1797. X  a[0] = in0;
  1798. X  a[1] = in1;
  1799. X  init (req, 2, -1, out, a, t);
  1800. X}
  1801. X
  1802. RpcRequest::RpcRequest(u_long req, const XdrInfo* out, const XdrInfo* in0,
  1803. X               const XdrInfo* in1, const XdrInfo* in2, int t)
  1804. X{
  1805. X  const XdrInfo** a = new XdrInfo*[4];
  1806. X  a[0] = in0;
  1807. X  a[1] = in1;
  1808. X  a[2] = in2;
  1809. X  init (req, 3, -1, out, a, t);
  1810. X}
  1811. X
  1812. RpcRequest::RpcRequest(u_long req, const XdrInfo* out, const XdrInfo* in0,
  1813. X               const XdrInfo* in1, const XdrInfo* in2,
  1814. X               const XdrInfo* in3, int t)
  1815. X{
  1816. X  const XdrInfo** a = new XdrInfo*[5];
  1817. X  a[0] = in0;
  1818. X  a[1] = in1;
  1819. X  a[2] = in2;
  1820. X  a[3] = in3;
  1821. X  init (req, 4, -1, out, a, t);
  1822. X}
  1823. X
  1824. RpcRequest::RpcRequest(u_long req, const XdrInfo* out, const XdrInfo* in0,
  1825. X               const XdrInfo* in1, const XdrInfo* in2,
  1826. X               const XdrInfo* in3, const XdrInfo* in4, int t)
  1827. X{
  1828. X  const XdrInfo** a = new XdrInfo*[6];
  1829. X  a[0] = in0;
  1830. X  a[1] = in1;
  1831. X  a[2] = in2;
  1832. X  a[3] = in3;
  1833. X  a[4] = in4;
  1834. X  init (req, 5, -1, out, a, t);
  1835. X}
  1836. X
  1837. RpcRequest::RpcRequest(u_long req, const XdrInfo* out, const XdrInfo* in0,
  1838. X               const XdrInfo* in1, const XdrInfo* in2,
  1839. X               const XdrInfo* in3, const XdrInfo* in4,
  1840. X               const XdrInfo* in5, int t)
  1841. X{
  1842. X  const XdrInfo** a = new XdrInfo*[7];
  1843. X  a[0] = in0;
  1844. X  a[1] = in1;
  1845. X  a[2] = in2;
  1846. X  a[3] = in3;
  1847. X  a[4] = in4;
  1848. X  a[5] = in5;
  1849. X  init (req, 6, -1, out, a, t);
  1850. X}
  1851. X
  1852. RpcRequest::RpcRequest(u_long req, const XdrInfo* out, const XdrInfo* in0,
  1853. X               const XdrInfo* in1, const XdrInfo* in2,
  1854. X               const XdrInfo* in3, const XdrInfo* in4,
  1855. X               const XdrInfo* in5, const XdrInfo *in6, int t)
  1856. X{
  1857. X  const XdrInfo** a = new XdrInfo*[8];
  1858. X  a[0] = in0;
  1859. X  a[1] = in1;
  1860. X  a[2] = in2;
  1861. X  a[3] = in3;
  1862. X  a[4] = in4;
  1863. X  a[5] = in5;
  1864. X  a[6] = in6;
  1865. X  init (req, 7, -1, out, a, t);
  1866. X}
  1867. X
  1868. RpcRequest::RpcRequest(u_long req, const XdrInfo* out, const XdrInfo** ins,
  1869. X               int t)
  1870. X{
  1871. X  int pars = 0;
  1872. X  for (XdrInfo** p = ins; *p; p++)
  1873. X    pars += 1;
  1874. X  const XdrInfo** a = new XdrInfo* [pars + 1];
  1875. X  memcpy (a, ins, (pars + 1) * sizeof (XdrInfo*));
  1876. X  init (req, pars, -1, out, a, t);
  1877. X}
  1878. X
  1879. int RpcRequest::ParamSize ()
  1880. X{
  1881. X  if (parmsz < 0) // not yet calculated
  1882. X    {
  1883. X      parmsz = 0;
  1884. X      for (XdrInfo** ip = ininfo; *ip; ip++)
  1885. X    parmsz += (*ip)->Size ();
  1886. X    }
  1887. X  return parmsz;
  1888. X}
  1889. END_OF_FILE
  1890. if test 4750 -ne `wc -c <'request.cc'`; then
  1891.     echo shar: \"'request.cc'\" unpacked with wrong size!
  1892. fi
  1893. # end of 'request.cc'
  1894. fi
  1895. if test ! -d 'rpc++' ; then
  1896.     echo shar: Creating directory \"'rpc++'\"
  1897.     mkdir 'rpc++'
  1898. fi
  1899. if test -f 'rpc++/request.h' -a "${1}" != "-c" ; then 
  1900.   echo shar: Will not clobber existing file \"'rpc++/request.h'\"
  1901. else
  1902. echo shar: Extracting \"'rpc++/request.h'\" \(4511 characters\)
  1903. sed "s/^X//" >'rpc++/request.h' <<'END_OF_FILE'
  1904. X// -*- c++ -*-
  1905. X/* 
  1906. Copyright (C) 1991 Peter Bersen
  1907. X
  1908. This file is part of the rpc++ Library.  This library is free
  1909. software; you can redistribute it and/or modify it under the terms of
  1910. the GNU Library General Public License as published by the Free
  1911. Software Foundation; either version 2 of the License, or (at your
  1912. option) any later version.  This library is distributed in the hope
  1913. that it will be useful, but WITHOUT ANY WARRANTY; without even the
  1914. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  1915. PURPOSE.  See the GNU Library General Public License for more details.
  1916. You should have received a copy of the GNU Library General Public
  1917. License along with this library; if not, write to the Free Software
  1918. XFoundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  1919. X
  1920. Modified and partially rewritten March 1992 by Michael N. Lipp,
  1921. mnl@dtro.e-technik.th-darmstadt.de. The original copyright terms and
  1922. conditions apply without change to any modified or new parts.
  1923. X*/
  1924. X
  1925. X#ifndef _RPCREQUEST_H_
  1926. X#define _RPCREQUEST_H_
  1927. static char _rpcpp_request_h_[]
  1928. X= "request.h,v 2.6 1993/01/20 15:00:49 mnl Exp";
  1929. X
  1930. X// request.h,v
  1931. X// Revision 2.6  1993/01/20  15:00:49  mnl
  1932. X// Updated for gcc-2.3.3.
  1933. X//
  1934. X// Revision 2.5  1992/12/06  18:58:12  mnl
  1935. X// Fixed various bugs and added some Methods.
  1936. X//
  1937. X// Revision 2.4  1992/08/08  13:11:46  mnl
  1938. X// RpcRequest(const RpcRequest&) added, 'cause RpcRequest has pointers
  1939. X// to heap.
  1940. X//
  1941. X// Revision 2.3  1992/06/15  19:13:28  mnl
  1942. X// Fixed a few bugs, clarified interface.
  1943. X//
  1944. X// Revision 2.2  1992/06/13  14:27:39  mnl
  1945. X// Adapted to (patched) gcc-2.2. Fixed several bugs.
  1946. X//
  1947. X// Revision 2.1.1.1  1992/03/08  13:28:43  mnl
  1948. X// Initial mnl version.
  1949. X//
  1950. X
  1951. X#ifdef __GNUG__
  1952. X#pragma interface
  1953. X#endif
  1954. X
  1955. X#include "rpc++/xdr++.h"
  1956. X#include <rpc/rpc.h>
  1957. X
  1958. X// RpcRequest is a class that specifies an individual request that is
  1959. X// part of a service. Three parameters are required to specify a request:
  1960. X//  - the request number
  1961. X//  - the serializer (XdrInfo) for the input to the request
  1962. X//  - the serializer (XdrInfo) for the output from the request
  1963. class RpcRequest
  1964. X{
  1965. private:
  1966. X  void init (u_long req, int pars, int parsz,
  1967. X         const XdrInfo* out, const XdrInfo** in, int rt);
  1968. X
  1969. public:
  1970. X  // Construct a new request from a request id, the information about
  1971. X  // the input data and the information about the output data.
  1972. X  // Note that requests that are registered for a service are stored
  1973. X  // in an array using the request id as the index, so keep indices
  1974. X  // small.
  1975. X  typedef enum { normal, batched, async } ReqType;
  1976. X  // No input arg:
  1977. X  RpcRequest (u_long req, const XdrInfo* out, int t = normal);
  1978. X  // One input arg:
  1979. X  RpcRequest (u_long req, const XdrInfo* out, const XdrInfo* in,
  1980. X          int t = normal);
  1981. X  // Two input args:
  1982. X  RpcRequest (u_long req, const XdrInfo* out, const XdrInfo*, const XdrInfo*,
  1983. X          int t = normal);
  1984. X  // ...
  1985. X  RpcRequest (u_long req, const XdrInfo* out, const XdrInfo*, const XdrInfo*,
  1986. X          const XdrInfo*, int t = normal);
  1987. X  RpcRequest (u_long req, const XdrInfo* out, const XdrInfo*, const XdrInfo*,
  1988. X          const XdrInfo*, const XdrInfo*, int t = normal);
  1989. X  RpcRequest (u_long req, const XdrInfo* out, const XdrInfo*, const XdrInfo*,
  1990. X          const XdrInfo*, const XdrInfo*, const XdrInfo*, int t = normal);
  1991. X  RpcRequest (u_long req, const XdrInfo* out, const XdrInfo*, const XdrInfo*,
  1992. X          const XdrInfo*, const XdrInfo*, const XdrInfo*, const XdrInfo*,
  1993. X          int t = normal);
  1994. X  RpcRequest (u_long req, const XdrInfo* out, const XdrInfo*, const XdrInfo*,
  1995. X          const XdrInfo*, const XdrInfo*, const XdrInfo*, const XdrInfo*,
  1996. X          const XdrInfo*, int t = normal);
  1997. X  // N input args, conversion routines given as a NULL terminated array
  1998. X  // of XdrInfo*:
  1999. X  RpcRequest (u_long req, const XdrInfo* out, const XdrInfo**, int t = normal);
  2000. X  // A copy
  2001. X  RpcRequest (const RpcRequest&);
  2002. X  ~RpcRequest ();
  2003. X  int RequestNumber () const;
  2004. X  const XdrInfo** InInfo ();
  2005. X  const XdrInfo* OutInfo ();
  2006. X  ReqType Type ();
  2007. X  int Params () const;
  2008. X  int ParamSize ();
  2009. X
  2010. protected:
  2011. X  int params;
  2012. X  int parmsz;
  2013. X  u_long reqnum;
  2014. X  const XdrInfo** ininfo;
  2015. X  const XdrInfo* outinfo;
  2016. X  ReqType reqtype;
  2017. X};
  2018. X
  2019. inline RpcRequest::~RpcRequest ()
  2020. X{ delete [] ininfo; }
  2021. X
  2022. inline int RpcRequest::Params () const
  2023. X{ return params; }
  2024. X
  2025. inline int RpcRequest::RequestNumber () const
  2026. X{ return reqnum; }
  2027. X
  2028. inline const XdrInfo** RpcRequest::InInfo ()
  2029. X{ return ininfo; }
  2030. X
  2031. inline const XdrInfo* RpcRequest::OutInfo ()
  2032. X{ return outinfo; }
  2033. X
  2034. inline RpcRequest::ReqType RpcRequest::Type ()
  2035. X{ return reqtype; }
  2036. X
  2037. X#endif
  2038. END_OF_FILE
  2039. if test 4511 -ne `wc -c <'rpc++/request.h'`; then
  2040.     echo shar: \"'rpc++/request.h'\" unpacked with wrong size!
  2041. fi
  2042. # end of 'rpc++/request.h'
  2043. fi
  2044. if test -f 'rpc++/service.h' -a "${1}" != "-c" ; then 
  2045.   echo shar: Will not clobber existing file \"'rpc++/service.h'\"
  2046. else
  2047. echo shar: Extracting \"'rpc++/service.h'\" \(4489 characters\)
  2048. sed "s/^X//" >'rpc++/service.h' <<'END_OF_FILE'
  2049. X// -*- c++ -*-
  2050. X/* 
  2051. Copyright (C) 1991 Peter Bersen
  2052. X
  2053. This file is part of the rpc++ Library.  This library is free
  2054. software; you can redistribute it and/or modify it under the terms of
  2055. the GNU Library General Public License as published by the Free
  2056. Software Foundation; either version 2 of the License, or (at your
  2057. option) any later version.  This library is distributed in the hope
  2058. that it will be useful, but WITHOUT ANY WARRANTY; without even the
  2059. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  2060. PURPOSE.  See the GNU Library General Public License for more details.
  2061. You should have received a copy of the GNU Library General Public
  2062. License along with this library; if not, write to the Free Software
  2063. XFoundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  2064. X
  2065. Modified and partially rewritten March 1992 by Michael N. Lipp,
  2066. mnl@dtro.e-technik.th-darmstadt.de. The original copyright terms and
  2067. conditions apply without change to any modified or new parts.
  2068. X*/
  2069. X
  2070. X#ifndef _RPCSERVICE_H_
  2071. X#define _RPCSERVICE_H_
  2072. static char _rpcpp_service_h_[]
  2073. X= "service.h,v 2.5 1993/01/20 15:00:51 mnl Exp";
  2074. X
  2075. X// service.h,v
  2076. X// Revision 2.5  1993/01/20  15:00:51  mnl
  2077. X// Updated for gcc-2.3.3.
  2078. X//
  2079. X// Revision 2.4  1992/12/06  18:58:14  mnl
  2080. X// Fixed various bugs and added some Methods.
  2081. X//
  2082. X// Revision 2.3  1992/06/15  19:13:30  mnl
  2083. X// Fixed a few bugs, clarified interface.
  2084. X//
  2085. X// Revision 2.2  1992/06/13  14:27:41  mnl
  2086. X// Adapted to (patched) gcc-2.2. Fixed several bugs.
  2087. X//
  2088. X// Revision 2.1.1.1  1992/03/08  13:28:43  mnl
  2089. X// Initial mnl version.
  2090. X//
  2091. X
  2092. X#ifdef __GNUG__
  2093. X#pragma interface
  2094. X#endif
  2095. X
  2096. X#undef TRUE
  2097. X#undef FALSE
  2098. X#include <bool.h>
  2099. X#include "rpc++/request.h"
  2100. X#include "rpc++/callback.h"
  2101. X
  2102. class RpcRegistered;
  2103. X
  2104. X//
  2105. X// RpcService
  2106. X//
  2107. X
  2108. class RpcService
  2109. X{
  2110. public:
  2111. X  typedef enum
  2112. X    { noError, reconstructionAttempt, cantCreateTCPService,
  2113. X      cantRegisterService, notRegistered, cantGetArgs,
  2114. X      invalidResult, cantSendReply, cantFreeArgs, selectError,
  2115. X    } errorCode;
  2116. X
  2117. X  // Get state
  2118. X  inline virtual bool OK ()
  2119. X    { return errorState == noError; }
  2120. X  // Construct a service object for service prog, version vers
  2121. X  RpcService (u_long prog, u_long vers);
  2122. X  // Construct a transient service object for version vers
  2123. X  RpcService (u_long vers);
  2124. X  // Destruct the service
  2125. X  virtual ~RpcService ();
  2126. X
  2127. X  // Get the program number (normally used after construction of transient)
  2128. X  u_long Program ();
  2129. X  virtual u_long ReserveService ();
  2130. X  
  2131. X  // Register an object and its method to be called on request
  2132. X  virtual void Register (const RpcRequest&, const AnyRpcCallback&);
  2133. X  virtual void Unregister (const RpcRequest&);
  2134. X
  2135. X  // The link to RPC
  2136. X  virtual void Dispatch (svc_req* req, SVCXPRT* transp);
  2137. X  // Provide the service. Never returns.
  2138. X  void Provide ();
  2139. X  // Provide the service. Returns after timeout or call.
  2140. X  void Provide (timeval&);
  2141. X
  2142. X  // Get caller. May be called during execution of a service routine.
  2143. X  inline struct sockaddr_in* Caller ()
  2144. X    { return svc_getcaller (xprt); }
  2145. X  const char* CallerName ();
  2146. X  // Reply before return
  2147. X  void Reply (void* res);
  2148. X  void Reply ();
  2149. X  // Quit provide loop
  2150. X  void Interrupt ();
  2151. X
  2152. private:
  2153. X  // Save the address of the one and only RpcService in the process.
  2154. X  // There may be only one RpcService, because we can register a program
  2155. X  // with svc_register (method RpcServiceCallback) but we can't make
  2156. X  // the svc function give an argument to this function when doing a
  2157. X  // callback, which means that we can't have it distinguish between
  2158. X  // various instances of RpcService.
  2159. X  static RpcService* me;
  2160. X  static inline void RpcServiceCallback (svc_req* req, SVCXPRT* transp)
  2161. X    { RpcService::me->Dispatch (req, transp); }
  2162. X
  2163. protected:
  2164. X  void init ();
  2165. X  void HandleError (errorCode e);
  2166. X  virtual void DoProvide (timeval*);
  2167. X  bool standalone;
  2168. X  errorCode errorState;
  2169. X  u_long prog;
  2170. X  u_long vers;
  2171. X  RpcRegistered** handlers;
  2172. X  int maxHandlerIndex;
  2173. X  static RpcRegistered* nopHandler;
  2174. X  SVCXPRT* xprt;
  2175. X  RpcRequest* rpcreq;
  2176. X  bool quitLoop;
  2177. X  char* inbuf;
  2178. X  int inmax;
  2179. X  bool haveReplied;
  2180. X
  2181. X  // Default error handling prints a message and exit(2)s.
  2182. X  virtual void HandleError ();
  2183. X};
  2184. X
  2185. inline void RpcService::HandleError (errorCode e)
  2186. X{ errorState = e; HandleError (); }
  2187. X
  2188. inline u_long RpcService::Program ()
  2189. X{ return prog; }
  2190. X
  2191. inline void RpcService::Reply ()
  2192. X{ Reply (0); }
  2193. X
  2194. inline void RpcService::Interrupt ()
  2195. X{ quitLoop = TRUE; }
  2196. X
  2197. inline void RpcService::Provide ()
  2198. X{ DoProvide (0); }
  2199. X
  2200. inline void RpcService::Provide (timeval& t)
  2201. X{ DoProvide (&t); }
  2202. X
  2203. X#endif
  2204. END_OF_FILE
  2205. if test 4489 -ne `wc -c <'rpc++/service.h'`; then
  2206.     echo shar: \"'rpc++/service.h'\" unpacked with wrong size!
  2207. fi
  2208. # end of 'rpc++/service.h'
  2209. fi
  2210. if test -f 'rpc++/stub.h' -a "${1}" != "-c" ; then 
  2211.   echo shar: Will not clobber existing file \"'rpc++/stub.h'\"
  2212. else
  2213. echo shar: Extracting \"'rpc++/stub.h'\" \(4989 characters\)
  2214. sed "s/^X//" >'rpc++/stub.h' <<'END_OF_FILE'
  2215. X// -*- c++ -*-
  2216. X/* 
  2217. Copyright (C) 1991 Peter Bersen
  2218. X
  2219. This file is part of the rpc++ Library.  This library is free
  2220. software; you can redistribute it and/or modify it under the terms of
  2221. the GNU Library General Public License as published by the Free
  2222. Software Foundation; either version 2 of the License, or (at your
  2223. option) any later version.  This library is distributed in the hope
  2224. that it will be useful, but WITHOUT ANY WARRANTY; without even the
  2225. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  2226. PURPOSE.  See the GNU Library General Public License for more details.
  2227. You should have received a copy of the GNU Library General Public
  2228. License along with this library; if not, write to the Free Software
  2229. XFoundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  2230. X
  2231. Modified and partially rewritten March 1992 by Michael N. Lipp,
  2232. mnl@dtro.e-technik.th-darmstadt.de. The original copyright terms and
  2233. conditions apply without change to any modified or new parts.
  2234. X*/
  2235. X
  2236. X#ifndef _RPCSTUB_H_
  2237. X#define _RPCSTUB_H_
  2238. static char _rpcpp_stub_h_[]
  2239. X= "stub.h,v 2.5 1992/12/06 18:58:15 mnl Exp";
  2240. X
  2241. X// stub.h,v
  2242. X// Revision 2.5  1992/12/06  18:58:15  mnl
  2243. X// Fixed various bugs and added some Methods.
  2244. X//
  2245. X// Revision 2.4  1992/08/08  13:23:18  mnl
  2246. X// Space allocated for result turned out to be local to a CLIENT*, thus
  2247. X// "res", "resmax" and "resproc" have been made member variables of
  2248. X// RpcStub.
  2249. X//
  2250. X// Revision 2.3  1992/06/15  19:13:31  mnl
  2251. X// Fixed a few bugs, clarified interface.
  2252. X//
  2253. X// Revision 2.2  1992/06/13  14:27:43  mnl
  2254. X// Adapted to (patched) gcc-2.2. Fixed several bugs.
  2255. X//
  2256. X// Revision 2.1.1.1  1992/03/08  13:28:43  mnl
  2257. X// Initial mnl version.
  2258. X//
  2259. X
  2260. X#ifdef __GNUG__
  2261. X#pragma interface
  2262. X#endif
  2263. X
  2264. X#undef TRUE
  2265. X#undef FALSE
  2266. X#include <bool.h>
  2267. X#include <String.h>
  2268. X#include <sys/time.h>
  2269. X#include "rpc++/request.h"
  2270. X
  2271. class RpcStub 
  2272. X{
  2273. protected:
  2274. X  static timeval defaultTimeout;
  2275. X
  2276. public:
  2277. X  typedef enum
  2278. X    { noError, notConnected, cantCreate, cantCall,
  2279. X    } errorCode;
  2280. X
  2281. X  // Construct a new stub
  2282. X  RpcStub (u_long prognum, u_long versnum,
  2283. X       char* hostname = "localhost",
  2284. X       timeval timeout = defaultTimeout, bool connect = TRUE);
  2285. X  RpcStub (u_long prognum, u_long versnum,
  2286. X       char* hostname = "localhost",
  2287. X       bool connect = TRUE, timeval timeout = defaultTimeout);
  2288. X  virtual ~RpcStub ();
  2289. X
  2290. X  // Reconnect (in case of failure or delayed connection)
  2291. X  void Reconnect (bool handle_errors = TRUE);
  2292. X
  2293. X  // Various inquiries
  2294. X  virtual bool OK ();
  2295. X  CLIENT* Service ();
  2296. X
  2297. X  // Get/set timeout
  2298. X  timeval GetTimeout () const;
  2299. X  void SetTimeout (timeval& timo);
  2300. X
  2301. X  // Make a call, either with or without an argument. If handle_errors
  2302. X  // is true, "Call" will call the error handler in case of an error.
  2303. X  // Else, it returns 0 as result and it is up to the client to handle
  2304. X  // the error.
  2305. X  // Call with one arg:
  2306. X  void* Call (RpcRequest&, bool handle_errors = TRUE);
  2307. X  // Call with two args:
  2308. X  void* Call (RpcRequest&, void* in, bool handle_errors = TRUE);
  2309. X  // ...
  2310. X  void* Call (RpcRequest& req, void*, void*, bool handle_errors = TRUE);
  2311. X  void* Call (RpcRequest& req, void*, void*, void*, bool handle_errors = TRUE);
  2312. X  void* Call (RpcRequest& req, void*, void*, void*, void*,
  2313. X          bool handle_errors = TRUE);
  2314. X  void* Call (RpcRequest& req, void*, void*, void*, void*, void*,
  2315. X          bool handle_errors = TRUE);
  2316. X  void* Call (RpcRequest& req, void*, void*, void*, void*, void*, void*,
  2317. X          bool handle_errors = TRUE);
  2318. X  void* Call (RpcRequest& req, void*, void*, void*, void*, void*, void*, void*,
  2319. X          bool handle_errors = TRUE);
  2320. X  // Call with N args:
  2321. X  void* Call (RpcRequest& req, void**, bool handle_errors = TRUE);
  2322. X
  2323. protected:
  2324. X  void* HandleError (errorCode e);
  2325. X  errorCode errorState;
  2326. X  u_long program;
  2327. X  u_long version;
  2328. X  String server;
  2329. X  timeval timeout;
  2330. X  CLIENT* svc;
  2331. X  void* res;
  2332. X  size_t resmax;
  2333. X  xdrproc_t resproc;
  2334. X  RpcRequest* curReq;
  2335. X  void** curArgs;
  2336. X
  2337. X  void init (u_long prognum, u_long versnum,
  2338. X         char* hostname, timeval timeout, bool connect);
  2339. X  // Default error handling prints a message and exit(2)s.
  2340. X  virtual void* HandleError ();
  2341. X  void* DoCall (RpcRequest& req, void** args, bool handle_errors);
  2342. X  void* ReCall (bool);
  2343. X};
  2344. X
  2345. inline RpcStub::RpcStub (u_long prognum, u_long versnum,
  2346. X             char* hostname, timeval timeout, bool connect)
  2347. X{ init (prognum, versnum, hostname, timeout, connect); }
  2348. X
  2349. inline RpcStub::RpcStub (u_long prognum, u_long versnum,
  2350. X             char* hostname, bool connect, timeval timeout)
  2351. X{ init (prognum, versnum, hostname, timeout, connect); }
  2352. X
  2353. inline virtual bool RpcStub::OK ()
  2354. X{ return errorState == noError; }
  2355. X
  2356. inline CLIENT* RpcStub::Service ()
  2357. X{ return svc; }
  2358. X
  2359. inline timeval RpcStub::GetTimeout () const
  2360. X{ return timeout; }
  2361. X
  2362. inline void RpcStub::SetTimeout (timeval& tv)
  2363. X{ clnt_control (svc, CLSET_TIMEOUT, &tv); timeout = tv; }
  2364. X
  2365. inline void* RpcStub::Call (RpcRequest& req, bool handle_errors = TRUE)
  2366. X{ return Call (req, (void*)0, handle_errors); }
  2367. X
  2368. inline void* RpcStub::HandleError (errorCode e)
  2369. X{ errorState = e; return HandleError (); }
  2370. X
  2371. X#endif
  2372. END_OF_FILE
  2373. if test 4989 -ne `wc -c <'rpc++/stub.h'`; then
  2374.     echo shar: \"'rpc++/stub.h'\" unpacked with wrong size!
  2375. fi
  2376. # end of 'rpc++/stub.h'
  2377. fi
  2378. if test -f 'rpc++/xdr++.h' -a "${1}" != "-c" ; then 
  2379.   echo shar: Will not clobber existing file \"'rpc++/xdr++.h'\"
  2380. else
  2381. echo shar: Extracting \"'rpc++/xdr++.h'\" \(2585 characters\)
  2382. sed "s/^X//" >'rpc++/xdr++.h' <<'END_OF_FILE'
  2383. X// -*- c++ -*-
  2384. X/* 
  2385. Copyright (C) 1991 Peter Bersen
  2386. X
  2387. This file is part of the rpc++ Library.  This library is free
  2388. software; you can redistribute it and/or modify it under the terms of
  2389. the GNU Library General Public License as published by the Free
  2390. Software Foundation; either version 2 of the License, or (at your
  2391. option) any later version.  This library is distributed in the hope
  2392. that it will be useful, but WITHOUT ANY WARRANTY; without even the
  2393. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  2394. PURPOSE.  See the GNU Library General Public License for more details.
  2395. You should have received a copy of the GNU Library General Public
  2396. License along with this library; if not, write to the Free Software
  2397. XFoundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  2398. X
  2399. Modified and partially rewritten March 1992 by Michael N. Lipp,
  2400. mnl@dtro.e-technik.th-darmstadt.de. The original copyright terms and
  2401. conditions apply without change to any modified or new parts.
  2402. X*/
  2403. X
  2404. X#ifndef _XDRPLPL_H_
  2405. X#define _XDRPLPL_H_
  2406. static char _rpcpp_xdrpp_h_[]
  2407. X= "xdr++.h,v 2.4 1993/01/20 15:00:52 mnl Exp";
  2408. X
  2409. X// xdr++.h,v
  2410. X// Revision 2.4  1993/01/20  15:00:52  mnl
  2411. X// Updated for gcc-2.3.3.
  2412. X//
  2413. X// Revision 2.3  1992/06/15  19:13:33  mnl
  2414. X// Fixed a few bugs, clarified interface.
  2415. X//
  2416. X// Revision 2.2  1992/06/13  14:27:44  mnl
  2417. X// Adapted to (patched) gcc-2.2. Fixed several bugs.
  2418. X//
  2419. X// Revision 2.1.1.1  1992/03/08  13:28:43  mnl
  2420. X// Initial mnl version.
  2421. X//
  2422. X
  2423. X#ifdef __GNUG__
  2424. X#pragma interface
  2425. X#endif
  2426. X
  2427. X/*
  2428. X** Class XdrInfo describes serializers. It combines the xdrproc_t with the
  2429. X** size info usually needed if you want to apply a serializer.
  2430. X*/
  2431. X
  2432. X#include <rpc/types.h>
  2433. X#include <rpc/xdr.h>
  2434. X
  2435. class XdrInfo
  2436. X{
  2437. protected:
  2438. X  xdrproc_t proc;
  2439. X  size_t size;
  2440. public:
  2441. X  inline XdrInfo (xdrproc_t p, size_t s)
  2442. X    { proc = p; size = s; }
  2443. X  inline xdrproc_t Proc () const
  2444. X    { return proc; }
  2445. X  inline size_t Size () const
  2446. X    { return size; }
  2447. X};
  2448. X
  2449. struct XdrSeqInfo
  2450. X{
  2451. X  XdrInfo** infos;
  2452. X  void** data;
  2453. X};
  2454. X
  2455. X/*
  2456. X** Class Xdr provides a unique (C++-like) name scope for the predefined
  2457. X** xdr routines by defining them as static members of type XdrInfo.
  2458. X*/
  2459. X
  2460. class Xdr
  2461. X{
  2462. public:
  2463. X  static XdrInfo Xnull;
  2464. X  static XdrInfo Xchar;
  2465. X  static XdrInfo Xshort;
  2466. X  static XdrInfo Xint;
  2467. X  static XdrInfo Xlong;
  2468. X  static XdrInfo Xuchar;
  2469. X  static XdrInfo Xushort;
  2470. X  static XdrInfo Xuint;
  2471. X  static XdrInfo Xulong;
  2472. X  static XdrInfo Xfloat;
  2473. X  static XdrInfo Xdouble;
  2474. X
  2475. X  static XdrInfo Xenum_t;
  2476. X  static XdrInfo Xbool_t;
  2477. X  static XdrInfo Xvoid;
  2478. X
  2479. X  static XdrInfo Xwrapstring;
  2480. X
  2481. X  static bool_t XdrParams (XDR* xdrs, XdrSeqInfo* xsi);
  2482. X};
  2483. X
  2484. X#endif
  2485. END_OF_FILE
  2486. if test 2585 -ne `wc -c <'rpc++/xdr++.h'`; then
  2487.     echo shar: \"'rpc++/xdr++.h'\" unpacked with wrong size!
  2488. fi
  2489. # end of 'rpc++/xdr++.h'
  2490. fi
  2491. if test -f 'service.cc' -a "${1}" != "-c" ; then 
  2492.   echo shar: Will not clobber existing file \"'service.cc'\"
  2493. else
  2494. echo shar: Extracting \"'service.cc'\" \(9174 characters\)
  2495. sed "s/^X//" >'service.cc' <<'END_OF_FILE'
  2496. X// -*- c++ -*-
  2497. X/* 
  2498. Copyright (C) 1991 Peter Bersen
  2499. X
  2500. This file is part of the rpc++ Library.  This library is free
  2501. software; you can redistribute it and/or modify it under the terms of
  2502. the GNU Library General Public License as published by the Free
  2503. Software Foundation; either version 2 of the License, or (at your
  2504. option) any later version.  This library is distributed in the hope
  2505. that it will be useful, but WITHOUT ANY WARRANTY; without even the
  2506. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  2507. PURPOSE.  See the GNU Library General Public License for more details.
  2508. You should have received a copy of the GNU Library General Public
  2509. License along with this library; if not, write to the Free Software
  2510. XFoundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  2511. X
  2512. Modified and partially rewritten March 1992 by Michael N. Lipp,
  2513. mnl@dtro.e-technik.th-darmstadt.de. The original copyright terms and
  2514. conditions apply without change to any modified or new parts.
  2515. X*/
  2516. X
  2517. static char _rpcpp_service_cc_[]
  2518. X= "service.cc,v 2.5 1993/01/20 15:00:14 mnl Exp";
  2519. X
  2520. X// service.cc,v
  2521. X// Revision 2.5  1993/01/20  15:00:14  mnl
  2522. X// Updated for gcc-2.3.3.
  2523. X//
  2524. X// Revision 2.4  1992/12/06  18:57:53  mnl
  2525. X// Fixed various bugs and added some Methods.
  2526. X//
  2527. X// Revision 2.3  1992/06/15  19:12:44  mnl
  2528. X// Fixed a few bugs, clarified interface.
  2529. X//
  2530. X// Revision 2.2  1992/06/13  14:27:02  mnl
  2531. X// Adapted to (patched) gcc-2.2. Fixed several bugs.
  2532. X//
  2533. X// Revision 2.1.1.1  1992/03/08  13:28:42  mnl
  2534. X// Initial mnl version.
  2535. X//
  2536. X
  2537. X#ifdef __GNUG__
  2538. X#pragma implementation
  2539. X#endif
  2540. X
  2541. X#include <assert.h>
  2542. X#include <stream.h>
  2543. X#include <memory.h>
  2544. X#include <errno.h>
  2545. X#include <stdlib.h>
  2546. X#include <sys/types.h>
  2547. X#include <sys/socket.h>
  2548. X#include <netdb.h>
  2549. X#include <rpc/rpc.h>
  2550. X#include <rpc/svc.h>
  2551. X#include <rpc/pmap_clnt.h>
  2552. X#include "rpc++/service.h"
  2553. X#include "rpc++/request.h"
  2554. X
  2555. extern "C" {
  2556. X  extern int getdtablesize();
  2557. X}
  2558. X
  2559. X//
  2560. X// RpcRegistered -- help class
  2561. X//
  2562. X
  2563. class RpcRegistered
  2564. X{
  2565. public:
  2566. X  RpcRequest request;
  2567. X  AnyRpcCallback* callback;
  2568. X
  2569. X  inline RpcRegistered (const RpcRequest& req, AnyRpcCallback* cb)
  2570. X    : request (req), callback (cb) { }
  2571. X  inline ~RpcRegistered ()
  2572. X    { delete callback; }
  2573. X};
  2574. X
  2575. X//
  2576. X// RpcService
  2577. X//
  2578. X
  2579. RpcService* RpcService::me = 0;
  2580. X// nopRequest is used as a dummy to mark reserved but not yet registered
  2581. X// service slots. Just in case it gets called, there is really a nop.
  2582. static void nop () {}
  2583. static RpcCallback nopCb (nop);
  2584. RpcRegistered* RpcService::nopHandler
  2585. X = new RpcRegistered (RpcRequest (0, &Xdr::Xvoid), &nopCb);
  2586. X
  2587. RpcService::RpcService (u_long pnum, u_long vnum)
  2588. X{
  2589. X  init ();
  2590. X  prog = pnum;
  2591. X  vers = vnum;
  2592. X  // find out if we have been started by inetd and set transp accoringly.
  2593. X  sockaddr_in sa;
  2594. X  int sasz = sizeof (sa);
  2595. X  // if started by inetd, stdin is a socket
  2596. X  standalone = (getsockname (0, (sockaddr*)&sa, &sasz) != 0);
  2597. X  if (standalone)
  2598. X    { // we are standalone
  2599. X      (void) pmap_unset(prog, vers);
  2600. X      xprt = svctcp_create(RPC_ANYSOCK, 0, 0);
  2601. X    }
  2602. X  else
  2603. X    { // inetd is our parent
  2604. X      xprt = svctcp_create(0, 0, 0);
  2605. X    }
  2606. X  if (xprt == NULL)
  2607. X    {
  2608. X      HandleError (cantCreateTCPService);
  2609. X      return;
  2610. X    }
  2611. X  if (!svc_register(xprt, prog, vers, RpcServiceCallback,
  2612. X            standalone ? IPPROTO_TCP : 0))
  2613. X    {
  2614. X      HandleError (cantRegisterService);
  2615. X      return;
  2616. X    }
  2617. X}
  2618. X
  2619. RpcService::RpcService (u_long vnum)
  2620. X{
  2621. X  init ();
  2622. X  vers = vnum;
  2623. X  prog = 0x40000000;
  2624. X  xprt = svctcp_create(RPC_ANYSOCK, 0, 0);
  2625. X  if (xprt == NULL)
  2626. X    {
  2627. X      HandleError (cantCreateTCPService);
  2628. X      return;
  2629. X    }
  2630. X  while (! pmap_set (prog, vers, IPPROTO_TCP, xprt->xp_port))
  2631. X    prog++;
  2632. X  if (!svc_register(xprt, prog, vers, RpcServiceCallback, IPPROTO_TCP))
  2633. X    {
  2634. X      HandleError (cantRegisterService);
  2635. X      return;
  2636. X    }
  2637. X}
  2638. X
  2639. void RpcService::init ()
  2640. X{
  2641. X  errorState = noError;
  2642. X  if (me)
  2643. X    {
  2644. X      HandleError (reconstructionAttempt);
  2645. X      return;
  2646. X    }
  2647. X  me = this;
  2648. X  handlers = 0;
  2649. X  maxHandlerIndex = -1;
  2650. X  inbuf = 0;
  2651. X  inmax = 0;
  2652. X}
  2653. X
  2654. RpcService::~RpcService ()
  2655. X{
  2656. X  if (standalone)
  2657. X    svc_unregister (prog, vers);
  2658. X  for (int i = 0; i <= maxHandlerIndex; i++)
  2659. X    if (handlers[i] != nopHandler)
  2660. X      delete handlers[i];
  2661. X  delete [] handlers;
  2662. X  delete [] inbuf;
  2663. X  me = 0;
  2664. X}
  2665. X
  2666. void RpcService::HandleError ()
  2667. X{
  2668. X  switch (errorState)
  2669. X    {
  2670. X    case reconstructionAttempt:
  2671. X      cerr << "rpc++: Attempt to construct another instance of RpcService.\n";
  2672. X      exit (1);
  2673. X    case cantCreateTCPService:
  2674. X      cerr << "rpc++: can't create tcp service.\n";
  2675. X      exit(1);
  2676. X    case cantRegisterService:
  2677. X      cerr << form ("rpc++: can't register (%d, %d, tcp).", prog, vers);
  2678. X      exit(1);
  2679. X    case cantSendReply:
  2680. X      cerr << "rpc++: can't reply to RPC call.\n";
  2681. X      break;
  2682. X    case invalidResult:
  2683. X      cerr << "rpc++: registered routine has return NULL pointer.\n";
  2684. X      abort ();
  2685. X    case notRegistered:
  2686. X      cerr << "rpc++: requested RPC routine not registered.\n";
  2687. X      break;
  2688. X    case cantGetArgs:
  2689. X      cerr << "rpc++: can't get procedure arguments.\n";
  2690. X      break;
  2691. X    case cantFreeArgs:
  2692. X      cerr << "rpc++: can't free XDR arguments.\n";
  2693. X      break;
  2694. X    }
  2695. X  errorState = noError;
  2696. X}
  2697. X
  2698. void RpcService::Register (const RpcRequest& req, const AnyRpcCallback& cb)
  2699. X{
  2700. X  assert (req.Params () == -1 || cb.Params () == -1
  2701. X      || req.Params () == cb.Params ());
  2702. X  AnyRpcCallback* cbp = cb.CopyToHeap ();
  2703. X  cbp->SetService (this);
  2704. X  if (req.RequestNumber () > maxHandlerIndex)
  2705. X    {
  2706. X      RpcRegistered** reg = new RpcRegistered*[req.RequestNumber () + 10];
  2707. X      memcpy (reg, handlers, (maxHandlerIndex + 1) * sizeof (RpcRegistered*));
  2708. X      memset (®[maxHandlerIndex + 1], 0,
  2709. X          (req.RequestNumber () + 10 - (maxHandlerIndex + 1))
  2710. X          * sizeof (RpcRegistered*));
  2711. X      delete handlers;
  2712. X      handlers = reg;
  2713. X      maxHandlerIndex = req.RequestNumber () + 10 - 1;
  2714. X    }
  2715. X  if (handlers[req.RequestNumber ()] != nopHandler)
  2716. X    delete handlers[req.RequestNumber ()];
  2717. X  handlers[req.RequestNumber ()] = new RpcRegistered (req, cbp);
  2718. X}
  2719. X
  2720. void RpcService::Unregister (const RpcRequest& req)
  2721. X{
  2722. X  if (req.RequestNumber () > maxHandlerIndex)
  2723. X    return;
  2724. X  if (handlers[req.RequestNumber ()] != nopHandler)
  2725. X    delete handlers[req.RequestNumber ()];
  2726. X  handlers[req.RequestNumber ()] = 0;
  2727. X}
  2728. X
  2729. u_long RpcService::ReserveService ()
  2730. X{
  2731. X  u_long svc = 0;
  2732. X  for (int req = 1; req <= maxHandlerIndex; req++)
  2733. X    {
  2734. X      if (handlers[req] == 0)
  2735. X    {
  2736. X      svc = req;
  2737. X      break;
  2738. X    }
  2739. X    }
  2740. X  if (svc == 0)
  2741. X    svc = maxHandlerIndex + 1;
  2742. X  handlers[svc] = nopHandler;
  2743. X  return svc;
  2744. X}
  2745. X
  2746. void RpcService::Dispatch (svc_req* req, SVCXPRT* transp)
  2747. X{
  2748. X  xprt = transp;
  2749. X  if (req->rq_proc == NULLPROC)
  2750. X    {
  2751. X      if (! svc_sendreply (xprt, xdr_void, 0))
  2752. X    {
  2753. X      svcerr_systemerr (xprt);
  2754. X      HandleError (cantSendReply);
  2755. X    }
  2756. X      return;
  2757. X    }
  2758. X  RpcRegistered* handler = ((req->rq_proc > maxHandlerIndex)
  2759. X                ? 0
  2760. X                : handlers[req->rq_proc]);
  2761. X  if (! handler)
  2762. X    {
  2763. X      svcerr_noproc (xprt);
  2764. X      HandleError (notRegistered);
  2765. X      return;
  2766. X    }
  2767. X  rpcreq = &handler->request;
  2768. X
  2769. X  int insz = rpcreq->ParamSize ();
  2770. X  if (insz > inmax) // does in-data fit in available buffer?
  2771. X    { // if not, increase buffer space
  2772. X      delete [] inbuf;
  2773. X      inbuf = new char[inmax = insz];
  2774. X    }
  2775. X  void* dataps[rpcreq->Params ()];
  2776. X  void** dp = dataps;
  2777. X  *dp = inbuf;
  2778. X  for (XdrInfo** ip = rpcreq->InInfo(); *ip; ip++, dp++)
  2779. X    dp[1] = (char*)dp[0] + (*ip)->Size ();
  2780. X
  2781. X  memset (inbuf, 0, insz);
  2782. X  XdrSeqInfo xsi = { rpcreq->InInfo (), dataps };
  2783. X  if (!svc_getargs (xprt, Xdr::XdrParams, &xsi))
  2784. X    {
  2785. X      if (rpcreq->Type () == RpcRequest::normal) // errors can be reported
  2786. X    svcerr_decode (xprt);   // only if the client waits for a result
  2787. X      HandleError (cantGetArgs);
  2788. X      return;
  2789. X    }
  2790. X  haveReplied = FALSE;
  2791. X  void* res = handler->callback->Do (dataps);
  2792. X  if (! haveReplied)
  2793. X    Reply (res);
  2794. X  if (!svc_freeargs (xprt, Xdr::XdrParams, &xsi))
  2795. X    HandleError (cantFreeArgs);
  2796. X  xprt = 0;
  2797. X}
  2798. X
  2799. void RpcService::Reply (void* res)
  2800. X{
  2801. X  haveReplied = TRUE;
  2802. X  if (rpcreq->Type () == RpcRequest::normal) // i.e., result expected
  2803. X    {
  2804. X      xdrproc_t outproc = rpcreq->OutInfo()->Proc ();
  2805. X      if (outproc == (xdrproc_t)0)
  2806. X    {
  2807. X      cerr << "rpc++: RpcRequest has invalid xdrproc_t (0) in out-Info";
  2808. X      abort ();
  2809. X    }
  2810. X      if (res == 0 && outproc != (xdrproc_t)xdr_void)
  2811. X    {
  2812. X      svcerr_systemerr (xprt);
  2813. X      HandleError ();
  2814. X    }
  2815. X      else if (!svc_sendreply
  2816. X           (xprt, rpcreq->OutInfo()->Proc (), (caddr_t)res))
  2817. X    {
  2818. X      svcerr_systemerr (xprt);
  2819. X      HandleError (cantSendReply);
  2820. X    }
  2821. X    }
  2822. X}
  2823. X
  2824. void RpcService::DoProvide (timeval* thisLong)
  2825. X{
  2826. X  int dtbsz = getdtablesize();
  2827. X  fd_set readfds;
  2828. X
  2829. X  quitLoop = FALSE;
  2830. X  while (! quitLoop)
  2831. X    {
  2832. X      readfds = svc_fdset;
  2833. X      switch(select (dtbsz, &readfds, 0, 0, thisLong))
  2834. X    {
  2835. X    case -1:
  2836. X      if (errno != EBADF)
  2837. X        continue;
  2838. X      cerr << "PRC++: select: " << sys_errlist[errno] << '\n';
  2839. X      return;
  2840. X    case 0:
  2841. X      if (thisLong == 0)
  2842. X        continue;
  2843. X      return;
  2844. X    default:
  2845. X      svc_getreqset (&readfds);
  2846. X      if (thisLong != 0)
  2847. X        return;
  2848. X      break;
  2849. X    }
  2850. X    }
  2851. X}
  2852. X
  2853. const char* RpcService::CallerName ()
  2854. X{
  2855. X  struct sockaddr_in *sa = Caller ();
  2856. X  struct hostent* he = gethostbyaddr ((const char*)&sa->sin_addr,
  2857. X                      sizeof (sa->sin_addr),
  2858. X                      sa->sin_family);
  2859. X  return he->h_name;
  2860. X}
  2861. END_OF_FILE
  2862. if test 9174 -ne `wc -c <'service.cc'`; then
  2863.     echo shar: \"'service.cc'\" unpacked with wrong size!
  2864. fi
  2865. # end of 'service.cc'
  2866. fi
  2867. if test -f 'stub.cc' -a "${1}" != "-c" ; then 
  2868.   echo shar: Will not clobber existing file \"'stub.cc'\"
  2869. else
  2870. echo shar: Extracting \"'stub.cc'\" \(6729 characters\)
  2871. sed "s/^X//" >'stub.cc' <<'END_OF_FILE'
  2872. X// -*- c++ -*-
  2873. X/* 
  2874. Copyright (C) 1991 Peter Bersen
  2875. X
  2876. This file is part of the rpc++ Library.  This library is free
  2877. software; you can redistribute it and/or modify it under the terms of
  2878. the GNU Library General Public License as published by the Free
  2879. Software Foundation; either version 2 of the License, or (at your
  2880. option) any later version.  This library is distributed in the hope
  2881. that it will be useful, but WITHOUT ANY WARRANTY; without even the
  2882. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  2883. PURPOSE.  See the GNU Library General Public License for more details.
  2884. You should have received a copy of the GNU Library General Public
  2885. License along with this library; if not, write to the Free Software
  2886. XFoundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  2887. X
  2888. Modified and partially rewritten March 1992 by Michael N. Lipp,
  2889. mnl@dtro.e-technik.th-darmstadt.de. The original copyright terms and
  2890. conditions apply without change to any modified or new parts.
  2891. X*/
  2892. X
  2893. static char _rpcpp_stub_cc_[]
  2894. X= "stub.cc,v 2.5 1992/12/06 18:57:55 mnl Exp";
  2895. X
  2896. X// stub.cc,v
  2897. X// Revision 2.5  1992/12/06  18:57:55  mnl
  2898. X// Fixed various bugs and added some Methods.
  2899. X//
  2900. X// Revision 2.4  1992/08/08  13:23:13  mnl
  2901. X// Space allocated for result turned out to be local to a CLIENT*, thus
  2902. X// "res", "resmax" and "resproc" have been made member variables of
  2903. X// RpcStub.
  2904. X//
  2905. X// Revision 2.3  1992/06/15  19:12:46  mnl
  2906. X// Fixed a few bugs, clarified interface.
  2907. X//
  2908. X// Revision 2.2  1992/06/13  14:27:04  mnl
  2909. X// Adapted to (patched) gcc-2.2. Fixed several bugs.
  2910. X//
  2911. X// Revision 2.1.1.1  1992/03/08  13:28:42  mnl
  2912. X// Initial mnl version.
  2913. X//
  2914. X
  2915. X#ifdef __GNUG__
  2916. X#pragma implementation
  2917. X#endif
  2918. X
  2919. X#include <stream.h>
  2920. X#include <memory.h>
  2921. X#include <assert.h>
  2922. X#include "rpc++/stub.h"
  2923. X
  2924. timeval RpcStub::defaultTimeout = { 25, 0 };
  2925. X
  2926. void RpcStub::init (u_long prog, u_long vers,
  2927. X           char* srv, timeval timo, bool connect)
  2928. X{
  2929. X  errorState = noError;
  2930. X  program = prog;
  2931. X  version = vers;
  2932. X  server = srv;
  2933. X  timeout = timo;
  2934. X  svc = 0;
  2935. X  res = 0;
  2936. X  resmax = 0;
  2937. X  resproc = 0;
  2938. X  if (connect)
  2939. X    Reconnect ();
  2940. X  else
  2941. X    errorState = notConnected;
  2942. X}
  2943. X
  2944. RpcStub::~RpcStub ()
  2945. X{
  2946. X  if (resproc) // "Call" has been called at least once,
  2947. X    clnt_freeres (svc, resproc, res); // free any data allocated by clnt_call
  2948. X  if (svc)
  2949. X    clnt_destroy (svc);
  2950. X}
  2951. X
  2952. void* RpcStub::HandleError ()
  2953. X{
  2954. X  switch (errorState)
  2955. X    {
  2956. X    case notConnected:
  2957. X      cerr << "rpc++: Stub has not been connected to server.\n";
  2958. X    case cantCreate:
  2959. X      cerr << clnt_spcreateerror ("rpc++") << '\n';
  2960. X      break;
  2961. X    case cantCall:
  2962. X      cerr << clnt_sperror (svc, "rpc++") << '\n';
  2963. X      exit (1);
  2964. X    }
  2965. X  return 0; // suppress compiler warning
  2966. X}
  2967. X
  2968. void RpcStub::Reconnect (bool handle_errors)
  2969. X{
  2970. X  if (resproc) // "Call" has been called
  2971. X    {
  2972. X      clnt_freeres (svc, resproc, res); // free data allocated by clnt_call
  2973. X      resproc = 0;
  2974. X    }
  2975. X  if (svc)
  2976. X    {
  2977. X      clnt_destroy (svc);
  2978. X    }
  2979. X  svc = clnt_create (server, program, version, "tcp"); // connect to client
  2980. X  if (svc == 0) // failed ?
  2981. X    {
  2982. X      if (handle_errors)
  2983. X    HandleError (cantCreate);
  2984. X      errorState = notConnected;
  2985. X      return;
  2986. X    }
  2987. X  clnt_control (svc, CLSET_TIMEOUT, &timeout);
  2988. X  errorState = noError;
  2989. X}
  2990. X
  2991. void* RpcStub::Call (RpcRequest& req, void* in, bool handle_errors)
  2992. X{
  2993. X  void* args[] = { in };
  2994. X  return DoCall (req, args, handle_errors);
  2995. X}
  2996. X
  2997. void* RpcStub::Call (RpcRequest& req, void* in0, void* in1, bool handle_errors)
  2998. X{
  2999. X  void* args[] = { in0, in1 };
  3000. X  return DoCall (req, args, handle_errors);
  3001. X}
  3002. X
  3003. void* RpcStub::Call (RpcRequest& req, void* in0, void* in1, void* in2,
  3004. X             bool handle_errors)
  3005. X{
  3006. X  void* args[] = { in0, in1, in2 };
  3007. X  return DoCall (req, args, handle_errors);
  3008. X}
  3009. X
  3010. void* RpcStub::Call (RpcRequest& req, void* in0, void* in1, void* in2,
  3011. X             void* in3, bool handle_errors)
  3012. X{
  3013. X  void* args[] = { in0, in1, in2, in3 };
  3014. X  return DoCall (req, args, handle_errors);
  3015. X}
  3016. X
  3017. void* RpcStub::Call (RpcRequest& req, void* in0, void* in1, void* in2,
  3018. X             void* in3, void* in4, bool handle_errors)
  3019. X{
  3020. X  void* args[] = { in0, in1, in2, in3, in4 };
  3021. X  return DoCall (req, args, handle_errors);
  3022. X}
  3023. X
  3024. void* RpcStub::Call (RpcRequest& req, void* in0, void* in1, void* in2,
  3025. X             void* in3, void* in4, void* in5, bool handle_errors)
  3026. X{
  3027. X  void* args[] = { in0, in1, in2, in3, in4, in5 };
  3028. X  return DoCall (req, args, handle_errors);
  3029. X}
  3030. X
  3031. void* RpcStub::Call (RpcRequest& req, void* in0, void* in1, void* in2,
  3032. X             void* in3, void* in4, void* in5, void* in6,
  3033. X             bool handle_errors)
  3034. X{
  3035. X  void* args[] = { in0, in1, in2, in3, in4, in5, in6 };
  3036. X  return DoCall (req, args, handle_errors);
  3037. X}
  3038. X
  3039. void* RpcStub::Call (RpcRequest& req, void** ins, bool handle_errors)
  3040. X{
  3041. X  return DoCall (req, ins, handle_errors);
  3042. X}
  3043. X
  3044. void* RpcStub::DoCall (RpcRequest& req, void** args, bool handle_errors)
  3045. X{
  3046. X  if (! OK () )
  3047. X    {
  3048. X      if (! handle_errors)
  3049. X    return 0;
  3050. X      return HandleError ();
  3051. X    }
  3052. X  if (resproc) // "Call" has been called previously,
  3053. X    clnt_freeres (svc, resproc, res); // free any data allocated by clnt_call
  3054. X  resproc = 0;
  3055. X  if (req.OutInfo()->Size () > resmax) // enough space for result?
  3056. X    {
  3057. X      delete res; // delete old result buffer
  3058. X      res = new char[resmax = req.OutInfo()->Size ()]; // get a new one
  3059. X    }
  3060. X  if (req.OutInfo()->Size () > 0 ) // preset result (everyone does it, why?)
  3061. X    memset (res, 0, req.OutInfo()->Size ());
  3062. X
  3063. X  curReq = &req;
  3064. X  curArgs = args;
  3065. X  return ReCall (handle_errors);
  3066. X}
  3067. X
  3068. void* RpcStub::ReCall (bool handle_errors)
  3069. X{
  3070. X  static const timeval nullTimeout = { 0, 0 };
  3071. X
  3072. X  if (resproc) // "ReCall" has been called before.
  3073. X    clnt_freeres (svc, resproc, res); // free any data allocated by clnt_call
  3074. X  resproc = curReq->OutInfo()->Proc (); // note current output deserializer
  3075. X  XdrSeqInfo xsi = { curReq->InInfo (), curArgs };
  3076. X  if (curReq->Type () == RpcRequest::normal)
  3077. X    {
  3078. X      if (clnt_call (svc, curReq->RequestNumber (), // do call
  3079. X             Xdr::XdrParams, &xsi,
  3080. X             curReq->OutInfo()->Proc (), res,
  3081. X             timeout) != RPC_SUCCESS)
  3082. X    {
  3083. X      if (! handle_errors)
  3084. X        return 0;
  3085. X      return HandleError (cantCall);
  3086. X    }
  3087. X      return res ? res : &nullTimeout; // if the return type is void,
  3088. X      // res may be 0 although the call succeeded. To simplify error
  3089. X      // checking if handle_errors is FALSE, we return a value != 0.
  3090. X    }
  3091. X
  3092. X  // curReq->Type () is batched or async
  3093. X  enum clnt_stat callres;
  3094. X  callres = clnt_call (svc, curReq->RequestNumber (), // do call
  3095. X               Xdr::XdrParams, &xsi,
  3096. X               (curReq->Type () == RpcRequest::batched
  3097. X                ? (xdrproc_t)0 : xdr_void), res,
  3098. X               nullTimeout);
  3099. X  if (callres != RPC_SUCCESS && callres != RPC_TIMEDOUT)
  3100. X    {
  3101. X      if (! handle_errors)
  3102. X    return 0;
  3103. X      return HandleError (cantCall);
  3104. X    }
  3105. X  return res ? res : &nullTimeout;
  3106. X}
  3107. END_OF_FILE
  3108. if test 6729 -ne `wc -c <'stub.cc'`; then
  3109.     echo shar: \"'stub.cc'\" unpacked with wrong size!
  3110. fi
  3111. # end of 'stub.cc'
  3112. fi
  3113. if test -f 'version.h' -a "${1}" != "-c" ; then 
  3114.   echo shar: Will not clobber existing file \"'version.h'\"
  3115. else
  3116. echo shar: Extracting \"'version.h'\" \(134 characters\)
  3117. sed "s/^X//" >'version.h' <<'END_OF_FILE'
  3118. X// version.h,v 2.3 1992/12/06 18:57:57 mnl Exp
  3119. X#ifndef _RPCPLPL_VERSION_H_
  3120. static char* version = "rpc++-library, version 2.3"
  3121. X#endif
  3122. END_OF_FILE
  3123. if test 134 -ne `wc -c <'version.h'`; then
  3124.     echo shar: \"'version.h'\" unpacked with wrong size!
  3125. fi
  3126. # end of 'version.h'
  3127. fi
  3128. if test -f 'xdr++.cc' -a "${1}" != "-c" ; then 
  3129.   echo shar: Will not clobber existing file \"'xdr++.cc'\"
  3130. else
  3131. echo shar: Extracting \"'xdr++.cc'\" \(2541 characters\)
  3132. sed "s/^X//" >'xdr++.cc' <<'END_OF_FILE'
  3133. X// -*- c++ -*-
  3134. X/* 
  3135. Copyright (C) 1991 Peter Bersen
  3136. X
  3137. This file is part of the rpc++ Library.  This library is free
  3138. software; you can redistribute it and/or modify it under the terms of
  3139. the GNU Library General Public License as published by the Free
  3140. Software Foundation; either version 2 of the License, or (at your
  3141. option) any later version.  This library is distributed in the hope
  3142. that it will be useful, but WITHOUT ANY WARRANTY; without even the
  3143. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  3144. PURPOSE.  See the GNU Library General Public License for more details.
  3145. You should have received a copy of the GNU Library General Public
  3146. License along with this library; if not, write to the Free Software
  3147. XFoundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  3148. X
  3149. Modified and partially rewritten March 1992 by Michael N. Lipp,
  3150. mnl@dtro.e-technik.th-darmstadt.de. The original copyright terms and
  3151. conditions apply without change to any modified or new parts.
  3152. X*/
  3153. X
  3154. static char _rpcpp_xdrpp_cc_[]
  3155. X= "xdr++.cc,v 2.3 1992/06/15 19:12:49 mnl Exp";
  3156. X
  3157. X// xdr++.cc,v
  3158. X// Revision 2.3  1992/06/15  19:12:49  mnl
  3159. X// Fixed a few bugs, clarified interface.
  3160. X//
  3161. X// Revision 2.2  1992/06/13  14:27:06  mnl
  3162. X// Adapted to (patched) gcc-2.2. Fixed several bugs.
  3163. X//
  3164. X// Revision 2.1.1.1  1992/03/08  13:28:42  mnl
  3165. X// Initial mnl version.
  3166. X//
  3167. X
  3168. X#ifdef __GNUG__
  3169. X#pragma implementation
  3170. X#endif
  3171. X
  3172. X/*
  3173. X** See Xdr.h.
  3174. X*/
  3175. X
  3176. X#include "rpc++/xdr++.h"
  3177. X
  3178. XXdrInfo Xdr::Xnull ((xdrproc_t)0, 0);
  3179. XXdrInfo Xdr::Xchar ((xdrproc_t)xdr_char, sizeof (char));
  3180. XXdrInfo Xdr::Xshort ((xdrproc_t)xdr_short, sizeof (short));
  3181. XXdrInfo Xdr::Xint ((xdrproc_t)xdr_int, sizeof (int));
  3182. XXdrInfo Xdr::Xlong ((xdrproc_t)xdr_long, sizeof (long));
  3183. XXdrInfo Xdr::Xuchar ((xdrproc_t)xdr_u_char, sizeof (u_char));
  3184. XXdrInfo Xdr::Xushort ((xdrproc_t)xdr_u_short, sizeof (u_short));
  3185. XXdrInfo Xdr::Xuint ((xdrproc_t)xdr_u_int, sizeof (u_int));
  3186. XXdrInfo Xdr::Xulong ((xdrproc_t)xdr_u_long, sizeof (u_long));
  3187. XXdrInfo Xdr::Xfloat ((xdrproc_t)xdr_float, sizeof (float));
  3188. XXdrInfo Xdr::Xdouble ((xdrproc_t)xdr_double, sizeof (double));
  3189. X
  3190. XXdrInfo Xdr::Xenum_t ((xdrproc_t)xdr_enum, sizeof (enum_t));
  3191. XXdrInfo Xdr::Xbool_t ((xdrproc_t)xdr_bool, sizeof (bool_t));
  3192. XXdrInfo Xdr::Xvoid ((xdrproc_t)xdr_void, 0);
  3193. XXdrInfo Xdr::Xwrapstring ((xdrproc_t)xdr_wrapstring, sizeof (char*));
  3194. X
  3195. bool_t Xdr::XdrParams (XDR* xdrs, XdrSeqInfo* xsi)
  3196. X{
  3197. X  XdrInfo** infop = xsi->infos;
  3198. X  void** datap = xsi->data;
  3199. X
  3200. X  while (*infop)
  3201. X    {
  3202. X      if (! (*infop->Proc ()) (xdrs, *datap))
  3203. X    return FALSE;
  3204. X      infop++, datap++;
  3205. X    }
  3206. X  return TRUE;
  3207. X}
  3208. END_OF_FILE
  3209. if test 2541 -ne `wc -c <'xdr++.cc'`; then
  3210.     echo shar: \"'xdr++.cc'\" unpacked with wrong size!
  3211. fi
  3212. # end of 'xdr++.cc'
  3213. fi
  3214. echo shar: End of archive 1 \(of 3\).
  3215. cp /dev/null ark1isdone
  3216. MISSING=""
  3217. for I in 1 2 3 ; do
  3218.     if test ! -f ark${I}isdone ; then
  3219.     MISSING="${MISSING} ${I}"
  3220.     fi
  3221. done
  3222. if test "${MISSING}" = "" ; then
  3223.     echo You have unpacked all 3 archives.
  3224.     rm -f ark[1-9]isdone
  3225. else
  3226.     echo You still need to unpack the following archives:
  3227.     echo "        " ${MISSING}
  3228. fi
  3229. ##  End of shell archive.
  3230. exit 0
  3231.