remotetea-1.0.7/0000755005374700003410000000000010736716050014625 5ustar piccainstrumentationremotetea-1.0.7/.classpath0000644005374700003410000000052710736703100016604 0ustar piccainstrumentation remotetea-1.0.7/.project0000644005374700003410000000056007716676410016306 0ustar piccainstrumentation remotetea org.eclipse.jdt.core.javabuilder org.eclipse.jdt.core.javanature remotetea-1.0.7/COPYING.LIB0000644005374700003410000006125107716634456016307 0ustar piccainstrumentation GNU LIBRARY GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the library GPL. It is numbered 2 because it goes with version 2 of the ordinary GPL.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Library General Public License, applies to some specially designated Free Software Foundation software, and to any other libraries whose authors decide to use it. You can use it for your libraries, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library, or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link a program with the library, you must provide complete object files to the recipients so that they can relink them with the library, after making changes to the library and recompiling it. And you must show them these terms so they know their rights. Our method of protecting your rights has two steps: (1) copyright the library, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the library. Also, for each distributor's protection, we want to make certain that everyone understands that there is no warranty for this free library. If the library is modified by someone else and passed on, we want its recipients to know that what they have is not the original version, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that companies distributing free software will individually obtain patent licenses, thus in effect transforming the program into proprietary software. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License, which was designed for utility programs. This license, the GNU Library General Public License, applies to certain designated libraries. This license is quite different from the ordinary one; be sure to read it in full, and don't assume that anything in it is the same as in the ordinary license. The reason we have a separate public license for some libraries is that they blur the distinction we usually make between modifying or adding to a program and simply using it. Linking a program with a library, without changing the library, is in some sense simply using the library, and is analogous to running a utility program or application program. However, in a textual and legal sense, the linked executable is a combined work, a derivative of the original library, and the ordinary General Public License treats it as such. Because of this blurred distinction, using the ordinary General Public License for libraries did not effectively promote software sharing, because most developers did not use the libraries. We concluded that weaker conditions might promote sharing better. However, unrestricted linking of non-free programs would deprive the users of those programs of all benefit from the free status of the libraries themselves. This Library General Public License is intended to permit developers of non-free programs to use free libraries, while preserving your freedom as a user of such programs to change the free libraries that are incorporated in them. (We have not seen how to achieve this as regards changes in header files, but we have achieved it as regards changes in the actual functions of the Library.) The hope is that this will lead to faster development of free libraries. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, while the latter only works together with the library. Note that it is possible for a library to be covered by the ordinary General Public License rather than by this special one. GNU LIBRARY GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Library General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also compile or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. c) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. d) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Library General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! remotetea-1.0.7/changelog.html0000644005374700003410000007734410736715740017466 0ustar piccainstrumentation Change Log of the Remote Tea Package

CVS info: $Revision: 1.7 $ $Date: 2008/01/02 15:12:47 $ $State: Exp $ $Locker: $

Change Log Remote Tea

Remote Tea Project Home Page on SourceForge.

Version 1.0.7:

You already guessed it: minor update/maintenance release.

  • Fixed inheriting character encoding from TCP-based listening server transport to the child TCP-based server connection transports.
  • Fixed/corrected behavior when registering server transports: an ONC/RPC exception with the reason OncRpcException.RPC_CANNOTREGISTER will now be thrown if the local portmapper denies port registration.

Version 1.0.6:

This is again a minor update/maintenance release.

  • Fixed encapsulation of properties when generating beans.
  • Fixed miscalculation of remaining timeout, which could case infinite timeouts.

Version 1.0.5:

This is a minor update/maintenance release.

  • Fixed a code generation error in jrpcgen which cause the protocol compiler to emit ONC/RPC server code that did not properly returned errors for unsupported programs.
  • Added new jrpcgen-test target to Ant build file so that the jrpcgen protocol compiler can be more easily tested on the example files.
  • Fixed build.xml Ant script to include also exactly this build file in the source code zip which gets uploaded to Source Forge.

Version 1.0.4:

It has been a long time since the previous release ... but yes, I finally managed to pick up the patches sent and rolled them into the new release. Many things changed in the meantime so I'm glad I got this release out of the door at all. My new employer throws all kind of really interesting tasks at me, so RemoteTea is now a really low profile project to me. If volunteers will step forward to maintain RemoteTea I would be glad to welcome them aboard the RemoteTea project.

  • Added a new option -bean to jrpcgen for generating accessors (setters and getters) for all elements in a structure. Option -bean also implies -ser. This feature bases on a patch from Ralph Neff.
  • jrpcgen now also accepts .x files without a program section. In this case no stub classes are generated, but Java source code files for all structures, enums, et cetera are still generated. This feature bases on a patch from Bialas Krzysztof.
  • Updated to new CPU runtime, see also the CUP LALR Parser Generator in Java Version 11 at TU Munich.
  • Incorporated patches for: compile target in Ant build file, include Ant task in jrpcgen.jar.
  • Thank you all who sent in patches!

Version 1.0.3:

This release marks my movement from the website of the good old Chair of Process Control Engineering to Sourceforge. Since Remote Tea has now quite some users, it was time to put the project on its own feet. Let's see where this will lead to.

  • With my transition from JBuilder to Eclipse a little bit of rearrangement of a few files was necessary. In particular, the old JBuilder project files are gone down the bit bucket, so say hello to the new Eclipse project files. With the switch to Eclipse we now have a free IDE for a free ONC/RPC package – and if you use ClassPath and an appropriate VM, then the whole thing is free.
  • Updated documentation – but you will probably already have noticed that from the new style of this and the other HTML files.
  • Yet another small correction to jrpcgen: it does not emit unnecessary import statements anymore. This silences especially the Eclipse IDE, but also other smart asses.
  • It is now possible to optionally control the character encoding used when (de-)serializing strings. The OncRpcClient class now has a pair of accessors setCharacterEncoding(encoding) and getCharacterEncoding(). Similiar, OncRpcServerStub gives control over character encoding on the server side.

Version 1.0.2:

  • Fixed a bug in jrpcgen, which caused the automatically generated constructor in server stubs, which accepts a port number, to ignore this port number.
  • Also squashed a bug which caused problems when definitions from enumerations where used as program numbers.
  • Small todo work done, so that jrpcgen now emits more useful information in the javadoc tags for remote procedure parameters and results.
  • Removed old and useless code from jrpcgen that has alread been commented out for quite some time.
  • Added new parameter -withcallinfo to jrpcgen. When specified on the command line, jrpcgen emits server method stubs which contain always as their first parameter an additional parameter holding information about the remote call itself. This can be used, for instance, for authentication purposes, et cetera. The parameter is always named call$ and of type OncRpcCallInformation.
  • Added new parameter -noclamp to jrpcgen. When -noclamp is specified on the command line, jrpcgen emits client method stubs which use the version number specified when creating the client object at runtime. When this option is not given, jrpcgen defaults to the current behavior and uses the version number as specified in the x-file.

Version 1.0.1:

  • Fixed a bug in jrpcgen, which emitted wrong stub code when a remote function contained more than one parameter: in this case, enumerations were not properly coerced to integers (thanks to Michael Smith for pointing this out and at the same time supplying the patch).
  • Fixed another bug in jrpcgen, which resulted in some (enumeration) constants not being dumped.

Version 1.0.0:

  • Tired of all the pre-1.0 releases in the past two years, I finally decided to go straight to the official 1.0 release. The past releases were primarily aiming at feature completeness to some degree, while the real basic parts were quite stable (with few improvements and bug fixes) over time. So, ... we have reached 1.0! ...and will probably soon get to 1.0.x, sigh.
  • For XDR structs with tail references to themselves, jrpcgen now emits serialization and deserialization code which uses an iteration loop instead of tail recursion. The benefit of this is that the call stack usage is considerably reduced. Of course, this optimization can only be applied if the reference to the same type is the last element of the structure.
  • Corrected a race condition, which sometimes caused the listening TCP thread in ONC/RPC servers to die with NullPointerExceptions. Many thanks to Michael Smith for hunting down this one. Classes concerned are OncRpcTcpConnectionServerTransport, OncRpcTcpServerTransport and OncRpcUdpServerTransport.
  • jrpcgen now exits the VM with a non-zero return code in case it was called through its static main and jrpcgen stumbled on an error. This allows jrpcgen to be used in classic make projects. The Apache Ant is not affected by this behavior.
  • Added an additional constructor to the classes OncRpcTcpServerTransport and OncRpcUdpServerTransport. It accepts now a local binding address. The server socket is then bound only to this/these local address(es). In addition, jrpcgen now emits source code for server stubs with an additional constructor which accepts the additional binding address.

Version 0.95.2:

  • Small change in OncRpcTcpSocketHelper.connect() to accept a negative timeout that signals to use the particular implementation-specific timeout value.
  • Added new constructor to OncRpcTcpClient, which accepts a timeout parameter (in milliseconds) as its last argument. This constructor can be used to limit the connection attempt period and finally makes the timeout functionality available which has been implemented in the 0.95.1 release. It is important to note that the timeout specified as the parameter to the constructor does not apply to later ONC/RPC calls. These are controlled as usual through the existing timeout-related accessors.
  • Made OncRpcPortmapClient a stand-alone class, which is not derived from OncRpcUdpClient any more. This now allows applications to contact the portmapper either using UDP/IP or TCP/IP (HTTP not yet supported).
  • Bumped up the versioning information in OncRpcConstants (I had forgotten to do so for the previous releases...).

Version 0.95.1:

After a long time (and a Ph.D. thesis on metamodelling for communication in operational process control engineering now written and on its way) I've finally managed to get a new RemoteTea release out of the door.

  • Implemented timeout-controlled connects for TCP-based ONC/RPC clients. The whole thing is a little bit tricky in view of pre-1.4 JREs. However, I definitely want to support JDK 1.2 and 1.3 (so much for write once, forget everywhere).

    The socket helper object features a connect method which can execute timeout-controlled connection establishment. In case the current VM Remote Tea is running on does not provide a proper implementation, Remote Tea resorts to the following algorithm:

    • The connect method creates a new thread which in turn tries to connect to the given port at the given host (an instance of the local class Connectiator is responsible for this).
    • The original thread initiating the Connectiator thread now waits for it to finish, but no longer than the timeout specified in the call to the connect method. In case the Connectiator does not succeed within the timeout period, an IOException is thrown by the connect method.
    • The Connectiator object will signal itself in case it succeeded, but also if it failed. Its getIOException method then either returns null or an IOException.
  • Fixed deserializing bug in XdrDecodingStream.xdrDecodeLong(), where unwanted sign extension messed up 64 bit wide integers (XDR hypers).
  • Fixed a long-standing feature in XdrTcpDecodingStream.fill(), which caused invalid header decoding if the fragment length was larger than 227.
  • Fixed sanity checks for those ONC/RPC partners sending empty XDR fragments as last fragments of XDR records – a trailing last XDR fragment that carries no data is now accepted. The fix concerns the class XdrTcpDecodingStream semantics of the fill method were slightly changed to return also in case of empty trailing record (lastFragment attribute must be true). All methods directly calling fill have been adapted (at least I hope so).
  • Improved handling of wrong or mismatching ONC/RPC messages for UDP-based ONC/RPC clients. They do not emit new calls any more when receiving replies from wrong sources and keep quiet instead until the timeout expires (as per current timeout strategy).
  • Fixed some buffer offset bugs (forgot to take care of CRLF at one place) in XdrHttpDecodingStream, for which patches were kindly offered by the austrian internet chamoises.
  • Added Ant task for jrpcgen as org.acplt.oncrpc.ant.JrpcgenTask, kindly provided by Jean-Francois Daune. This also involved some small changes to jrpcgen in order to make it available as a task.

Version 0.94.2:

  • Fixed bug in jrpcgen, which caused a crash when hashing a union's structure (needed to create serial version UIDs) and the union contained a non-empty default arm. Also added appropriate test case to demo.x.

Version 0.94.1:

  • Added two new code generation options to jrpcgen:
    • -ser: tag classes generated for XDR structs, XDR unions and XDR typedefs as serializable. Also automatically generates serialVersionUID using the SHA-1 algorithm. (My thanks to the GNU classpath project for providing the SHA-1 algorithm, please see Jrpcgen.SHA.java for license details).
    • -initstrings: automatically initialize all Strings as empty strings (""). Note that this may lead to lazy programming; better make explicitly sure that every member of a struct gets initialized properly before encoding the struct.

Version 0.93.1:

  • Once more fixed support for JDK 1.1 for Java-based ONC/RPC servers: the old code still used a LinkedList, which is only available since JDK 1.2. So I added a minimalist double linked list local class (it's in OncRpcTcpServerTransport.TransportList).
  • Worked around some broken JDKs 1.1 (especially on AIX, but I have also heard of problems on Linux), which have broken InetAddress.getLocalHost. The code now uses InetAdress.getByName("127.0.0.1"). Yeah, write once, does not work anywhere.
  • Added overloaded client.call method which expects an additional (procedure/protocol) version number as its second argument. This method is necessary so several versions can coexists peacefully in one client and can be called simultaneously. As before, if you do not specify a version in the call to client.call the default version is used as specified in the constructor. Please note that OncRpcClient-derived classes must now implement the overloaded call method expecting four parameters: procedure number, version number, parameters, and result (this only applies to those who want to implement their own ONC/RPC clients for different transports than those already provided).
  • Added support for multiple parameters in procedure declarations within x-files, to be more in sync with newer rpcgen releases. In addition, jrpcgen now also accept named parameters in remote procedure declarations. Both enhancements caused quite some changes in the code emitting parts of jrpcgen: local wrapper classes are used to serialize and deserialize multiple parameters.

Version 0.92.1:

  • Support for batched ONC/RPC calls when using TCP-based transports: see OncRpcTcpClient.batchCall() for more information.
  • Added support for handling multiple ONC/RPC programs and/or versions through the same server transport.
  • jrpcgen now emits a second constructor expecting the port number to bind transports to as its solely parameter. This allows server writers to bind their servers to well-known ports.
  • Added a jportmap and an embedded portmap service class. It can be used by standalone applications which should also be useable if the user has not installed a portmap service. I must have been bored or insane. Or both.
  • Made several OncRpcServerStub methods public (instead of protected), to give derived server classes more control over the way they spin up and down.

Version 0.91.2:

  • Ashes on my head for releasing 0.91.1 with a really dumb bug related to JDK 1.1 backwards compatibility which broke JDK2 compatibility completely. When using reflection one can not call the superclass' methods for obvious reasons, so an endless recursion occured in OncRpcTcpSocket. So much for almost not testing the release. To fix this stupid design bug the classes OncRpcTcpSocket and OncRpcUdpSocket were moved to OncRpcTcpSocketHelper and OncRpcUdpSocketHelper. They now merely support Socket and DatagramSocket instead of inheriting from them. This avoids the endless reflection method invocation loop, but is still cheaper in terms of method invocation performance than a wrapper class.
  • Fixed missing JDK 1.1 compatibility for the server classes.

Version 0.91.1:

  • Fixed a deserialization bug with AUTH_NONE on the server side in OncRpcServerAuth.xdrNew when recycling the AUTH_NONE handler singleton.
  • Removed automatic startup from the constructor of jrpcgen generated server stubs. The constructor of a server stub class now only creates the transport objects and sets the public transports field within class OncRpcServerStub. Registering with the portmapper as well as dispatching calls is now done within the run() method (note: without any parameters). You need to change your code accordingly by inserting a call to run(), otherwise the server will not start.
        MyServer myserver = new MyServer();
        myserver.run();
      
  • Preparations for cvs check-in: in order to handle individual Java projects in form of cvs submodules within the toplevel cvs module java, some files were moved. The JBuilder project files have been moved to the projects/ subdirectory.
  • Fixed problem with jrpcgen emitting constants which depend on other constants in wrong order. Constants which are needed by other constant definitions are now emitted first. In case an enumeration element depends on a global constant (or for some reason on another enumeration element), then the enclosure is taken into account too. The demo.x example now tests some pathological cases.
  • Added backward support for JDK 1.1. While I'm not very proud of it, many people requested this as quite some companies use the bug-ridden MS InternetExploder with its very own JVM. Changes include using addElement instead of add when adding objects to a Vector.
  • Moved the readme documentation into its own directory readme-first/ which should be more obvious to first-time users of the RemoteTea source code and does not clobber the projects/ directory any more.
  • Fixed NullPointerException in OncRpcTcpClient and OncRpcUdpClient when checking for rejected credentials – and I thought Java had no pointers.
  • jrpcgen: support for short form unsigned in addition to unsigned int (compatibility with rpcgen). Handling of octal numbers added (okay, it is still a valid number format). Fixed bug in the code generation of desciminated unions using booleans. Support for more than one program definition within the same x-file. In this case the source code files generated for the client and server stubs are named <x-filename><program-id>Client.java and <x-filename><program-id>Server.java, respectively.
  • First rough cut for tunneling ONC/RPC client calls through HTTP connections. On the other end, you will need the Tea Tunnel Apache DSO module, which untunnels calls and forwards them to the appropriate ONC/RPC server using direct TCP/IP or UDP/IP connections (or non-connections in the case of UDP/IP).
  • Added new package org.acplt.oncrpc.web containing helper classes for HTTP client connections (HttpClientConnection), and base64 encoding and decoding (Base64), as well as some other stuff.
  • Added new class OncRpcHttpClient, which stands in the tradition of OncRpcClient and implements sending ONC/RPC calls through HTTP tunnels. Also added XdrHttpDecodingStream, which can pull base64 encoded data from a web server and provide the decoded data through the usual decoding XDR stream interface.

Version 0.90.1:

  • Fixed XdrEncodingStream.xdrEncodeByteFixedVector() which falsely encoded length information about the following array of characters. I should take more care when doing Italian code recycling using copy & pasta...
  • Fixed bug in OncRpcTcpClient.call() which caused XDR buffer underflows when receiving the next reply after the previous reply has been rejected by an ONC/RPC server.
  • Updated package.html for package org.acplt.oncrpc to put it in sync with (de-) serializing fixed-size vectors and dynamic and fixed vectors of characters.
  • Added AUTH_UNIX authentication. For this to achieve quite some additions and changes were necessary – luckily, old applications will not be broken, as the changes are deep within the RemoteTea package:
    • See OncRpcClient for a description about how to use authentication with ONC/RPC clients.
    • For handling of client-side authentication issues, the classes OncRpcClientAuth, OncRpcClientAuthNone and OncRpcClientAuthUnix were added.
    • The ONC/RPC call and reply message classes OncRpcReplyMessage and OncRpcCallMessage are now both abstract. This was necessary because ONC/RPC protocol issues make it necessary to handle authentication through so-called authentication protocol handling objects different on the client side than on the server side. Additional classes now handle sending calls and receiving replies on the client side (OncRpcClientCallMessage and OncRpcClientReplyMessage respectively), as well as on the server side (OncRpcServerCallMessage and OncRpcServerReplyMessage). According to their needs, these new classes only declare those encoding and decoding methods which are really needed. In consequence, the base class OncRpcCallMessage has lost its XdrAble interface completely.
    • Added authentication handling and credential refreshing to OncRpcUdpClient and OncRpcTcpClient, as well as to the base class OncRpcClient.
    • Added authentication protocol handling to ONC/RPC transports. If servers want to take advantage of authentication, they need to look at the callMessage.auth attribute of the OncRpcCallInformation delivered with each incomming ONC/RPC call. See tests.org.acplt.oncrpc.ServerTest.java for an example.
    Please note that AUTH_DES is still not supported, as this needs quite some things to be done and I don't have full information about the AUTH_DES protocol.
  • Added new classes XdrBufferEncodingStream and XdrBufferDecodingStream for encoding and decoding XDR data from and to a fixed-size buffer. These classes comes in handy when dealing with shorthand credentials.
  • Added class XdrDynamicOpaque to handle variable-sized vectors of bytes.
  • Moved the jrpcgen package to org.acplt.oncrpc.apps.jrpcgen, because it's an application belonging very tight to ONC/RPC.
  • Added new OncRpcConstants.REMOTETEA_VERSION_PREVERSION, which indicates preversions if not zero.

Version 0.86.1:

  • As Sun's rpcgen encodes char<> as a series of characters, each one sitting happily in its very own XDR int (that is, four bytes), the two methods XdrDecodingStream.xdrDecodeBytes() and XdrEncodingStream.xdrEncodeBytes() were renamed to XdrDecodingStream.xdrDecodeByteVector() and XdrEncodingStream.xdrEncodeByteVector() as well as their semantics changed accordingly.
  • Added methods XdrDecodingStream.xdrDecodeDynamicOpaque(), XdrEncodingStream.xdrEncodeDynamicOpaque(), XdrDecodingStream.xdrDecodeByteFixedVector() and XdrEncodingStream.xdrEncodeByteFixedVector().
  • Fixed jrpcgen accordingly, so it generates proper code for arrays of bytes and opaque data types accordingly.
  • Made all non-abstract encoding and decoding methods in XdrDecodingStream and XdrEncodingStream finally final. Maybe this helps Java compilers improve code speed. Maybe.
  • Fixed jrpcgen code generation error when the size of an array was specified using a constant identifier. Now jrpcgen properly references the constant from the x-file's main class.
  • Fixed some documentation errors for XdrDecodingStream and XdrEncodingStream.

Version 0.85.1:

  • Added new method readBuffer() to class XdrTcpDecodingStream. This fixes problems when reading from a TCP/IP stream and not all bytes wanted are immediately available, thus stream.read() returning not all bytes at once (shame on me for not reading the java.io documentation attentive enough).

Version 0.84.1:

  • Added control over the retransmission strategy used by UDP/IP-based ONC/RPC clients. The default strategy is now not to resend lost ONC/RPC calls (retransmission timeout is set to the overall timeout). Either a fixed retransmission timeout can be choosen, where lost calls are resend every <retransmission timeout> milliseconds, or an exponential back-off alogorithm. The exponential scheme starts with the retransmission timeout and doubles it every time a call is lost, until the overall timeout is reached.
  • Added two more constructors to ONC/RPC clients generated by jrpcgen from x-files. These constructors now also accept the remote program number, so application writers gain full control.

Version 0.83.1:

  • Fixed support for indirection in decriminated unions. Also cleaned up some minor things related to constants and enumerations. Thanks to Ulrik Sandberg for throwing all kinds of vicious x-files at jrpcgen.

Version 0.82.1:

  • Added support for indirection in x-files, also called optional data in ONC/RPC babble. Also added a new test case to the demo.x file.

Version 0.81.1:

  • Added broadcasting of ONC/RPC calls to UDP/IP-based ONC/RPC clients through the new broadcastCall of method in class OncRpcUdpClient.
  • Added helper methods for encoding and decoding fixed-size vectors for various base data types.
  • Added a description about mapping rpcgen (RFC 1832) data types to Java data type.
  • Added an RPC protocol compiler named jrpcgen. Sun's documentation on the rpcgen syntax and grammar is rather thin and sometimes inaccurate. As always, I had to resort to RTSL (Read The Source, Luke!) to find out what syntax and grammar rpcgen does in fact use. Please give it a try and report problems. Note that there is no preprocessor step.

Version 0.80.2:

  • Fixed a buffer underflow exception in XdrUdpDecodingStream in methods xdrDecodeOpaque(int) and xdrDecodeOpaque(byte[],int,int). This cures the bug where a XDR string being the last piece of information in a RPC call or reply could not be read successfully.
  • Added org.acplt.oncrpc.OncRpcConstants, which contains versioning information.

Version 0.80.1:

  • Separated the ONC/RPC package under the name Remote Tea from the ACPLTea package. As the ONC/RPC implementation is pretty functional the version number was changed to reflect this.
  • Added XDR primitive and serializable data types for strings, floats, etc.

Version 0.35.1 and before:

  • Graciously hidden in the mist of history (probably also in the midst of history). The Remote Tea package was then only available together with the ACPLTea package, but not separate.
remotetea-1.0.7/docstyle.css0000644005374700003410000000301607716634572017201 0ustar piccainstrumentation/* * docstyle.css -- Contains the styling definition for the HTML documentation. * * $Revision: 1.1 $ */ body { font-family: verdana, arial, helvetica, sans-serif; font-size: 90%; color: #000000; background: #FFFFFF; } a:link { color: #0000CC; } a:visited { color: #000080; } a:active { color: #CC0000; } code { font-family: courier, fixed; font-size: 110%; } span.product { font-style: italic; } sup { font-size: 60%; } span.arg { font-style: italic; font-weight: bold; } h1 { font-size: 250%; font-weight: bold; color: #000080; } h2 { font-size: 140%; font-weight: bold; color: #000080; margin: 4ex 0 2ex 0; padding: 0px 0px 3px 10px; width: 15em; border-bottom-style: dotted; border-bottom-width: 2px; border-bottom-color: #AAAAAA; } p.important { font-weight: bold; color: #CC0000; margin: 0ex 0em 0ex 2em; } p { line-height: 1.3; margin: 0 0 0 2em; } p + p { text-indent: 2em; } p.revision { font-size: 80%; text-indent: 0em; margin: 0 0 -2ex 0; text-indent: 0em; } /* Use french quotes */ q { quotes: "\00AB" "\00BB"; } /* External links are shown differently from internal links */ a.ext:before { content: "\00BB"; font-weight: bold; } a.ext:after { content: ""; } /* bulleted lists */ ul { list-style-type: square; color: #000080; } li { margin-left: .5em; } li + li { margin-top: .5ex; } li > span { color: #000000; } div.annotation { font-size: 90%; font-style: italic; margin: .25ex 1em 0ex 2em; } /* End of docstyle.css */ remotetea-1.0.7/readme.html0000644005374700003410000000706007716653520016761 0ustar piccainstrumentation Remote Tea ONC/RPC Java Library

CVS info: $Revision: 1.1 $ $Date: 2003/08/14 11:33:03 $ $State: Exp $ $Locker: $

README

The whole release shebang is summarized in our Change Log.

As always, the most current information about the Remote Tea Java Library, as well as updates, can be found on the web at the Remote Tea ONC/RPC Home Page.

Licensing

The Remote Tea Java Library is licensed under the terms of the GNU Library General Public License (LGPL).

Rationale: while the LGPL does not restrict the use of my packages even in commercial applications, I am ensuring this way that modifications to the source code must be given back to the comunity. If you use my packages in commercial applications, you must either include the source code of the Remote Tea ONC/RPC Java Library or provide the source code to your customers on request. The details can be found in the LGPL terms.

Project Structure

The directory structure is as follows. Due to the transition to the Eclipse IDE and Ant not everything is currently in place and perfect shape.

  • javadoc/: Remote Tea ONC/RPC documentation
  • src/: source code of the Remote Tea ONC/RPC Java Library.
    • src/org/acplt/oncrpc contains the source code of the various packages.
    • src/org/acplt/oncrpc/apps contains applications, in this case only the jrpcgen rpc protocol compiler in the jrpcgen/ subdirectory.
    • src/tests contains test code.
    • src/tests/org/acplt/oncrpc/jrpcgen contains an example of how to use the jrpcgen rpc protocol compiler. To generate source code from the x-file, run:
        java -jar jrpcgen.jar -p tests.org.acplt.oncrpc.jrpcgen -nobackup demo.x
          
  • classes/: will receive the compiled Java bytecode. After running the Ant build.xml makefile with target jar, this directory will also contain two jar files called classes/oncrpc.jar and classes/jrpcgen.jar.

The Remote Tea ONC/RPC Java package is currently being developed and tested using Eclipse on a JDK 1.4.2 (Windows).

Those who like to compile the sources by themselves might want to use either the Eclipse .project file or the Ant makefile build.xml (this is not really functional yet), both are located in the root directory of this package.

Who's to blame

The Remote Tea Java Package has been written by Harald Albrecht (harald@plt.rwth-aachen.de).
© 1999, 2003 Chair of Process Control Engineering,
Aachen University of Technology,
52064 Aachen, Germany

remotetea-1.0.7/src/0000755005374700003410000000000010736702150015410 5ustar piccainstrumentationremotetea-1.0.7/src/org/0000755005374700003410000000000010736702150016177 5ustar piccainstrumentationremotetea-1.0.7/src/org/acplt/0000755005374700003410000000000010736702150017302 5ustar piccainstrumentationremotetea-1.0.7/src/org/acplt/oncrpc/0000755005374700003410000000000010736702150020566 5ustar piccainstrumentationremotetea-1.0.7/src/org/acplt/oncrpc/ant/0000755005374700003410000000000010736702150021350 5ustar piccainstrumentationremotetea-1.0.7/src/org/acplt/oncrpc/ant/JrpcgenTask.java0000644005374700003410000001405207716637206024445 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/ant/JrpcgenTask.java,v 1.3 2003/08/14 09:47:17 haraldalbrecht Exp $ * * Copyright (c) 2001 * Daune Consult SPRL * Rue du monument, 1 * 6530 Thirimont (Belgium) * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc.ant; import java.io.File; import java.io.IOException; import org.acplt.oncrpc.apps.jrpcgen.jrpcgen; import org.apache.tools.ant.BuildException; /** * Ant task to run the ONC/RPC '.x' file compiler provided in the Remote Tea * library: jrpcgen. * *

The Remote Tea library is a complete open source implementation of * the ONC/RPC standard, developped by the Chair of Process Control * Engineering of University of Aachen, Germany. *

Remote Tea can be found at * * http://www.plt.rwth-aachen.de/ks/english/remotetea.html. * *

The task attributes are: *

    *
  • srcfile : '.x' file to compile (mandatory)
  • *
  • destdir : directory where generated files need to be placed * (mandatory). If a 'package' directive is used, * do not add the package directories to destDir * (it is done automatically by the task)
  • *
  • package : package name to be used for generated files (optional)
  • *
  • createdir : indicates whether jrpcgen must create destdir if it does * not exist (optional). Defaults to no.
  • *
  • verbose : indicates whether jrpcgen must be verbose (optional). * Defaults to no.
  • *
  • debug : indicates whether jrpcgen must trace debug information * (optional). Defaults to no.
  • *
  • backup : indicates whether jrpcgen must backup files (optional). * Defaults to no.
  • *
* * @author Jean-Francois Daune */ public class JrpcgenTask extends org.apache.tools.ant.Task { public void setSrcfile(java.io.File srcFile) { this.srcFile = srcFile; } public void setDestdir(java.io.File destDir) { this.destDir = destDir; } public void setPackage(java.lang.String packageName) { this.packageName = packageName; } public void setCreatedir(boolean createDir) { this.createDir = createDir; } public void setDebug(boolean debug) { this.debug = debug; } public void setVerbose(boolean verbose) { this.verbose = verbose; } public void setBackup(boolean backup) { this.backup = backup; } public void execute() throws BuildException { checkAttributes(); try { System.out.println("Compiling " + srcFile.getCanonicalPath()); } catch (IOException ex) { } if(packageName != null) { jrpcgen.packageName = packageName; try { // Add the package name to destination dir destDir = new File( destDir.getCanonicalPath() + File.separator + packageName.replace('.', File.separatorChar)); } catch (IOException ex) { throw new BuildException(ex); // should never occur } } if (createDir) { // Create the destination dir if it does not exist try { if (!destDir.exists()) { boolean dirsCreated = destDir.mkdirs(); if (!dirsCreated) { throw new BuildException("Could not create destination dir" ); } } } catch (SecurityException ex) { throw new BuildException(ex); } } if (debug) dumpState(); jrpcgen.debug = debug; jrpcgen.verbose = verbose; jrpcgen.noBackups = (!backup); jrpcgen.destinationDir = destDir; jrpcgen.xFile = srcFile; try { jrpcgen.doParse(); } catch (Throwable t) { throw new BuildException(t); } } private void checkAttributes() throws BuildException { if(srcFile == null) throw new BuildException("srcfile has not been set"); if(destDir == null) throw new BuildException("destdir has not been set"); try { if(!srcFile.isFile()) throw new BuildException("problem reading srcdir"); if(!destDir.isDirectory()) throw new BuildException("problem accessing srcdir"); } catch(SecurityException ex) { throw new BuildException(ex); } } private void dumpState() { System.out.println(srcFile); System.out.println(destDir); System.out.println(packageName); System.out.println(backup); System.out.println(debug); System.out.println(verbose); System.out.println(createDir); } private java.io.File srcFile; private java.io.File destDir; private String packageName; /** * Task attribute "debug". */ private boolean debug = false; private boolean verbose = false; private boolean backup = false; private boolean createDir = false; }remotetea-1.0.7/src/org/acplt/oncrpc/apps/0000755005374700003410000000000010736702150021531 5ustar piccainstrumentationremotetea-1.0.7/src/org/acplt/oncrpc/apps/jportmap/0000755005374700003410000000000010736702150023365 5ustar piccainstrumentationremotetea-1.0.7/src/org/acplt/oncrpc/apps/jportmap/OncRpcEmbeddedPortmap.java0000644005374700003410000002404207716622550030404 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/apps/jportmap/OncRpcEmbeddedPortmap.java,v 1.2 2003/08/14 08:00:08 haraldalbrecht Exp $ * * Copyright (c) 2001 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc.apps.jportmap; import java.io.IOException; import java.net.InetAddress; import org.acplt.oncrpc.*; import org.acplt.oncrpc.server.*; /** * The class OncRpcEmbeddedPortmap provides an embeddable * portmap service, which is automatically started in its own thread if * the (operating) system does not already provide the portmap service. * If an embedded portmap service is started it will stop only after the * last ONC/RPC program has been deregistered. * * @version $Revision: 1.2 $ $Date: 2003/08/14 08:00:08 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class OncRpcEmbeddedPortmap { /** * Constructs an embeddable portmap service of class * OncRpcEmbeddedPortmap and starts the service if no * other (external) portmap service is available. This constructor is * the same as OncRpcEmbeddedPortmap calling with a * timeout of 3 seconds. * *

The constructor starts the portmap service in its own thread and * then returns. * * @see OncRpcEmbeddedPortmap#embeddedPortmapInUse */ public OncRpcEmbeddedPortmap() throws OncRpcException, IOException { this(3000); } /** * Constructs an embeddable portmap service of class * OncRpcEmbeddedPortmap and starts the service if no * other (external) portmap service is available. * *

The constructor starts the portmap service in its own thread and * then returns. * * @param checkTimeout timeout in milliseconds to wait before assuming * that no portmap service is currently available. * * @see OncRpcEmbeddedPortmap#embeddedPortmapInUse */ public OncRpcEmbeddedPortmap(int checkTimeout) throws OncRpcException, IOException { if ( !isPortmapRunning(checkTimeout) ) { embeddedPortmap = new embeddedjportmap(); embeddedPortmapThread = new OncRpcEmbeddedPortmapThread(embeddedPortmap); embeddedPortmap.serviceThread = embeddedPortmapThread; // Do not make portmap thread a daemon, otherwise it would be // simply terminated when an application using it finishes. // embeddedPortmapThread.setDaemon(true); embeddedPortmapThread.start(); } } /** * Indicates whether a portmap service (regardless whether it's supplied * by the operating system or an embedded portmap service) is currently * running. This method will check for 3 seconds for an answer from a * portmap before assuming that no one exists. * * @return true, if a portmap service (either external or * embedded) is running and can be contacted. */ public static boolean isPortmapRunning() { return isPortmapRunning(3000); } /** * Indicates whether a portmap service (regardless whether it's supplied * by the operating system or an embedded portmap service) is currently * running. * * @param checkTimeout timeout in milliseconds to wait before assuming * that no portmap service is currently available. * * @return true, if a portmap service (either external or * embedded) is running and can be contacted. */ public static boolean isPortmapRunning(int checkTimeout) { boolean available = false; try { OncRpcPortmapClient portmap = new OncRpcPortmapClient(InetAddress.getByName("127.0.0.1")); portmap.getOncRpcClient().setTimeout(checkTimeout); portmap.ping(); available = true; } catch ( OncRpcException e ) { } catch ( IOException e ) { } return available; } /** * Indicates whether the embedded portmap service is in use. * * @return true, if embedded portmap service is currently * used. */ public boolean embeddedPortmapInUse() { return embeddedPortmapThread != null; } /** * Returns the thread object running the embedded portmap service. * * @return Thread object or null if no embedded portmap * service has been started. */ public Thread getEmbeddedPortmapServiceThread() { return embeddedPortmapThread; } /** * Returns object implementing the embedded portmap service. * * @return Embedded portmap object or null if no * embedded portmap service has been started. */ public jportmap getEmbeddedPortmap() { return embeddedPortmap; } /** * Stop the embedded portmap service if it is running. Normaly you should * not use this method except you need to force the embedded portmap * service to terminate. Under normal conditions the thread responsible * for the embedded portmap service will terminate automatically after the * last ONC/RPC program has been deregistered. * *

This method * just signals the portmap thread to stop processing ONC/RPC portmap * calls and to terminate itself after it has cleaned up after itself. */ public void shutdown() { OncRpcServerStub portmap = embeddedPortmap; if ( portmap != null ) { portmap.stopRpcProcessing(); } } /** * Portmap object acting as embedded portmap service or null * if no embedded portmap service is necessary because the operating * system already supplies one or another portmapper is already running. */ protected embeddedjportmap embeddedPortmap; /** * References thread object running the embedded portmap service. */ protected Thread embeddedPortmapThread; /** * Extend the portmap service so that it automatically takes itself out * of service when the last ONC/RPC programs is deregistered. */ class embeddedjportmap extends jportmap { /** * Creates a new instance of an embeddable portmap service. */ public embeddedjportmap() throws IOException, OncRpcException { } /** * Thread running the embedded portmap service. */ protected Thread serviceThread; /** * Deregister all port settings for a particular (program, version) for * all transports (TCP, UDP, ...). This method basically falls back to * the implementation provided by the jrpcgen superclass, * but checks whether there are other ONC/RPC programs registered. If * not, it signals itself to shut down the portmap service. * * @param params (program, version) to deregister. The protocol and port * fields are not used. * * @return true if deregistration succeeded. */ XdrBoolean unsetPort(OncRpcServerIdent params) { XdrBoolean ok = super.unsetPort(params); if ( ok.booleanValue() ) { // // Check for registered programs other than PMAP_PROGRAM. // boolean onlyPmap = true; int size = servers.size(); for ( int idx = 0; idx < size; ++idx ) { if ( ((OncRpcServerIdent)servers.elementAt(idx)).program != PMAP_PROGRAM ) { onlyPmap = false; break; } } // // If only portmap-related entries are left, then shut down this // portmap service. // if ( onlyPmap && (serviceThread != null) ) { stopRpcProcessing(); } } return ok; } } /** * The class OncRpcEmbeddedPortmapThread implements a thread * which will run an embedded portmap service. */ class OncRpcEmbeddedPortmapThread extends Thread { /** * Construct a new embedded portmap service thread and associate * it with the portmap object to be used as the service. The service * is not started yet. */ public OncRpcEmbeddedPortmapThread(embeddedjportmap portmap) { super("embedded portmap service thread"); this.portmap = portmap; } /** * Run the embedded portmap service thread, starting dispatching * of all portmap transports until we get the signal to shut down. */ public void run() { try { portmap.run(portmap.transports); } catch ( Exception e ) { } portmap.close(portmap.transports); portmap.serviceThread = null; } /** * The embedded portmap service object this thread belongs to. The * service object implements the ONC/RPC dispatcher and the individual * remote procedures for a portmapper). */ private embeddedjportmap portmap; } } // End of OncRpcEmbeddedPortmap.java remotetea-1.0.7/src/org/acplt/oncrpc/apps/jportmap/jportmap.java0000644005374700003410000003557607716652732026122 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/apps/jportmap/jportmap.java,v 1.2 2003/08/14 11:26:50 haraldalbrecht Exp $ * * Copyright (c) 2001 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc.apps.jportmap; import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Vector; import org.acplt.oncrpc.*; import org.acplt.oncrpc.server.*; /** * The class jportmap implements a Java-based ONC/RPC port mapper, * speaking the widely deployed protocol version 2. * *

This class can be either used stand-alone (a static main is * provided for this purpose) or as part of an application. In this case you * should check first for another portmap already running before starting your * own one. * * @version $Revision: 1.2 $ $Date: 2003/08/14 11:26:50 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class jportmap extends OncRpcServerStub implements OncRpcDispatchable { /** * Create a new portmap instance, create the transport registration * information and UDP and TCP-based transports, which will be bound * later to port 111. The constructor does not start the dispatcher loop. */ public jportmap() throws OncRpcException, IOException { // // We only need to register one {progam, version}. // info = new OncRpcServerTransportRegistrationInfo [] { new OncRpcServerTransportRegistrationInfo(PMAP_PROGRAM, PMAP_VERSION) }; // // We support both UDP and TCP-based transports for ONC/RPC portmap // calls, and these transports are bound to the well-known port 111. // transports = new OncRpcServerTransport [] { new OncRpcUdpServerTransport(this, PMAP_PORT, info, 32768), new OncRpcTcpServerTransport(this, PMAP_PORT, info, 32768) }; // // Finally, we add ourself to the list of registered ONC/RPC servers. // This is just a convenience. // servers.addElement(new OncRpcServerIdent( PMAP_PROGRAM, PMAP_VERSION, OncRpcProtocols.ONCRPC_TCP, PMAP_PORT)); servers.addElement(new OncRpcServerIdent( PMAP_PROGRAM, PMAP_VERSION, OncRpcProtocols.ONCRPC_UDP, PMAP_PORT)); // // Determine all local IP addresses assigned to this host. // Once again, take care of broken JDKs, which can not handle // InetAdress.getLocalHost() properly. Sigh. // try { InetAddress loopback = InetAddress.getByName("127.0.0.1"); InetAddress [] addrs = InetAddress.getAllByName("127.0.0.1"); // // Check whether the loopback address is already included in // the address list for this host. If not, add it to the list. // boolean loopbackIncluded = false; for ( int idx = 0; idx < addrs.length; ++idx ) { if ( addrs[idx].equals(loopback) ) { loopbackIncluded = true; break; } } if ( loopbackIncluded ) { locals = addrs; } else { locals = new InetAddress[addrs.length + 1]; locals[0] = loopback; System.arraycopy(addrs, 0, locals, 1, addrs.length); } } catch ( UnknownHostException e ) { // // Trouble getting all addresses for this host (which might // have been caused by some dumb security manager -- yeah, as // if managers were not dumb by definition), so fall back to // allowing only the loopback address. // locals = new InetAddress[1]; locals[0] = InetAddress.getByName("127.0.0.1"); } } /** * Lookup port for (program, version, protocol). If no suitable * registration entry if found and an entry with another version, but the * same program and version number is found, this is returned instead. * This is compatible with the way Sun's portmap implementation works. * * @param params server identification (program, version, protocol) to * look up. The port field is not used. * * @return port number where server listens for incomming ONC/RPC calls, * or 0, if no server is registered for (program, protocol). */ OncRpcGetPortResult getPort(OncRpcServerIdent params) { OncRpcServerIdent ident = null; OncRpcGetPortResult result = new OncRpcGetPortResult(); int size = servers.size(); for ( int idx = 0; idx < size; ++idx ) { OncRpcServerIdent svr = (OncRpcServerIdent) servers.get(idx); if ( (svr.program == params.program) && (svr.protocol == params.protocol) ) { // // (program, protocol) already matches. If it has the same // version, then we're done. Otherwise we remember this // entry for possible later usage and search further through // the list. // if ( svr.version == params.version ) { result.port = svr.port; return result; } ident = svr; } } // // Return port of "best" match, if one was found at all, otherwise // just return 0, which indicates an invalid UDP/TCP port. // if ( ident == null ) { result.port = 0; } else { result.port = ident.port; } return result; } /** * Register a port number for a particular (program, version, protocol). * Note that a caller can not register the same (program, version, * protocol) for another port. In this case we return false. Thus, a * caller first needs to deregister any old entries which it whishes to * update. Always add new registration entries to the end of the list * (vector). * * @param params (program, version, protocol, port) to register. * * @return true if registration succeeded. */ XdrBoolean setPort(OncRpcServerIdent params) { if ( params.program != PMAP_PROGRAM ) { // // Only accept registration attempts for anything other than // the portmapper. We do not want clients to play tricks on us. // int size = servers.size(); for ( int idx = 0; idx < size; ++idx ) { OncRpcServerIdent svr = (OncRpcServerIdent) servers.get(idx); if ( (svr.program == params.program) && (svr.version == params.version) && (svr.protocol == params.protocol) ) { // // In case (program, version, protocol) is already // registered only accept, if the port stays the same. // This will silently accept double registrations (i.e., // due to duplicated UDP calls). // return new XdrBoolean(svr.port == params.port); } } // // Add new registration entry to end of the list. // servers.addElement(params); return new XdrBoolean(true); } return new XdrBoolean(false); } /** * Deregister all port settings for a particular (program, version) for * all transports (TCP, UDP, ...). While these are strange semantics, * they are compatible with Sun's portmap implementation. * * @param params (program, version) to deregister. The protocol and port * fields are not used. * * @return true if deregistration succeeded. */ XdrBoolean unsetPort(OncRpcServerIdent params) { boolean ok = false; if ( params.program != PMAP_PROGRAM ) { // // Only allow clients to deregister ONC/RPC servers other than // the portmap entries. // int size = servers.size(); for ( int idx = size - 1; idx >= 0; --idx ) { OncRpcServerIdent svr = (OncRpcServerIdent) servers.get(idx); if ( (svr.program == params.program) && (svr.version == params.version) ) { servers.removeElementAt(idx); ok = true; } } } return new XdrBoolean(ok); } /** * Return list of registered ONC/RPC servers. * * @return list of ONC/RPC server descriptions (program, version, * protocol, port). */ OncRpcDumpResult listServers() { OncRpcDumpResult result = new OncRpcDumpResult(); result.servers = servers; return result; } /** * Checks whether the address given belongs to one of the local * addresses of this host. * * @param addr IP address to check. * * @return true if address specified belongs to one of the * local addresses of this host. */ boolean isLocalAddress(InetAddress addr) { int size = locals.length; for ( int idx = 0; idx < size; ++idx ) { if ( addr.equals(locals[idx]) ) { return true; } } return false; } /** * Dispatch incomming ONC/RPC calls to the individual handler functions. * The CALLIT method is currently unimplemented. * * @param call The ONC/RPC call, with references to the transport and * XDR streams to use for retrieving parameters and sending replies. * @param program the portmap's program number, 100000 * @param version the portmap's protocol version, 2 * @param procedure the procedure to call. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void dispatchOncRpcCall(OncRpcCallInformation call, int program, int version, int procedure) throws OncRpcException, IOException { // // Make sure it's the right program and version that we can handle. // (defensive programming) // if ( program == PMAP_PROGRAM ) { if ( version == PMAP_VERSION ) { switch ( procedure ) { case 0: { // handle NULL call. call.retrieveCall(XdrVoid.XDR_VOID); call.reply(XdrVoid.XDR_VOID); break; } case OncRpcPortmapServices.PMAP_GETPORT: { // handle port query OncRpcServerIdent params = new OncRpcServerIdent(); call.retrieveCall(params); OncRpcGetPortResult result = getPort(params); call.reply(result); break; } case OncRpcPortmapServices.PMAP_SET: { // handle port registration // // ensure that no remote client tries to register // OncRpcServerIdent params = new OncRpcServerIdent(); call.retrieveCall(params); XdrBoolean result; if ( isLocalAddress(call.peerAddress) ) { result = setPort(params); } else { result = new XdrBoolean(false); } call.reply(result); break; } case OncRpcPortmapServices.PMAP_UNSET: { // handle port deregistration OncRpcServerIdent params = new OncRpcServerIdent(); call.retrieveCall(params); XdrBoolean result; if ( isLocalAddress(call.peerAddress) ) { result = unsetPort(params); } else { result = new XdrBoolean(false); } call.reply(result); break; } case OncRpcPortmapServices.PMAP_DUMP: { // list all registrations call.retrieveCall(XdrVoid.XDR_VOID); OncRpcDumpResult result = listServers(); call.reply(result); break; } default: // unknown/unimplemented procedure call.failProcedureUnavailable(); } } else { call.failProgramMismatch(PMAP_VERSION, PMAP_VERSION); } } else { call.failProgramUnavailable(); } } /** * List of IP addresses assigned to this host. Will be filled later * by constructor. */ public InetAddress [] locals = null; /** * The list of registrated servers. */ public Vector servers = new Vector(); /** * Create an instance of an ONC/RPC portmapper and run it. As we have * to bootstrap the ONC/RPC port information chain, we do not use the * usual overloaded run() method without any parameters, * but instead supply it the transports to handle. Registration and * deregistration is not necessary and not possible. */ public static void main(String[] args) { try { jportmap pmap = new jportmap(); pmap.run(pmap.transports); pmap.close(pmap.transports); } catch ( OncRpcException e ) { e.printStackTrace(System.out); } catch ( IOException e ) { e.printStackTrace(System.out); } } /** * Well-known port where the portmap process can be found on Internet hosts. */ public static final int PMAP_PORT = 111; /** * Program number of the portmapper as defined in RFC 1832. */ public static final int PMAP_PROGRAM = 100000; /** * Program version number of the portmapper as defined in RFC 1832. */ public static final int PMAP_VERSION = 2; } // End of jportmap.java remotetea-1.0.7/src/org/acplt/oncrpc/apps/jportmap/package.html0000644005374700003410000000341310627063130025644 0ustar piccainstrumentation ONC/RPC for Java package Java-based portmap

This package implements a Java-based ONC/RPC portmap compatible with Sun's portmap, protocol version 2.

In case you really do not want to use a native portmap designed for your particular operating system, you can use jportmap as a substitute (nod, nod...). I must be (beep) writing a Java-based portmap.

There is also an embeddable portmap service available as class OncRpcEmbeddedPortmap. This can be used to make sure that a portmap service is always available, even if the operating system does not provide one or it is not installed or not enabled.

This package is part of the Remote Tea Java ONC/RPC Library package.

(c) 2001, 2006 Harald Albrecht.
(c) 2001 Lehrstuhl für Prozeßleittechnik, Aachen University of Technology, Germany.

This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details.

You should have received a copy of the GNU Library General Public License along with this program (see the file COPYING.LIB for more details); if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. remotetea-1.0.7/src/org/acplt/oncrpc/apps/jrpcgen/0000755005374700003410000000000010736702150023161 5ustar piccainstrumentationremotetea-1.0.7/src/org/acplt/oncrpc/apps/jrpcgen/cup_runtime/0000755005374700003410000000000010736702150025513 5ustar piccainstrumentationremotetea-1.0.7/src/org/acplt/oncrpc/apps/jrpcgen/cup_runtime/Scanner.java0000644005374700003410000000156710335177070027762 0ustar piccainstrumentationpackage org.acplt.oncrpc.apps.jrpcgen.cup_runtime; /** * Defines the Scanner interface, which CUP uses in the default * implementation of lr_parser.scan(). Integration * of scanners implementing Scanner is facilitated. * * @version last updated 23-Jul-1999 * @author David MacMahon */ /* ************************************************* Interface Scanner Declares the next_token() method that should be implemented by scanners. This method is typically called by lr_parser.scan(). End-of-file can be indicated either by returning new Symbol(lr_parser.EOF_sym()) or null. ***************************************************/ public interface Scanner { /** Return the next token, or null on end-of-file. */ public Symbol next_token() throws java.lang.Exception; } remotetea-1.0.7/src/org/acplt/oncrpc/apps/jrpcgen/cup_runtime/Symbol.java0000644005374700003410000000517610335177070027636 0ustar piccainstrumentationpackage org.acplt.oncrpc.apps.jrpcgen.cup_runtime; /** * Defines the Symbol class, which is used to represent all terminals * and nonterminals while parsing. The lexer should pass CUP Symbols * and CUP returns a Symbol. * * @version last updated: 7/3/96 * @author Frank Flannery */ /* **************************************************************** Class Symbol what the parser expects to receive from the lexer. the token is identified as follows: sym: the symbol type parse_state: the parse state. value: is the lexical value of type Object left : is the left position in the original input file right: is the right position in the original input file ******************************************************************/ public class Symbol { /******************************* Constructor for l,r values *******************************/ public Symbol(int id, int l, int r, Object o) { this(id); left = l; right = r; value = o; } /******************************* Constructor for no l,r values ********************************/ public Symbol(int id, Object o) { this(id, -1, -1, o); } /***************************** Constructor for no value ***************************/ public Symbol(int id, int l, int r) { this(id, l, r, null); } /*********************************** Constructor for no value or l,r ***********************************/ public Symbol(int sym_num) { this(sym_num, -1); left = -1; right = -1; value = null; } /*********************************** Constructor to give a start state ***********************************/ Symbol(int sym_num, int state) { sym = sym_num; parse_state = state; } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** The symbol number of the terminal or non terminal being represented */ public int sym; /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** The parse state to be recorded on the parse stack with this symbol. * This field is for the convenience of the parser and shouldn't be * modified except by the parser. */ public int parse_state; /** This allows us to catch some errors caused by scanners recycling * symbols. For the use of the parser only. [CSA, 23-Jul-1999] */ boolean used_by_parser = false; /******************************* The data passed to parser *******************************/ public int left, right; public Object value; /***************************** Printing this token out. (Override for pretty-print). ****************************/ public String toString() { return "#"+sym; } } remotetea-1.0.7/src/org/acplt/oncrpc/apps/jrpcgen/cup_runtime/lr_parser.java0000644005374700003410000012613210335177070030356 0ustar piccainstrumentation package org.acplt.oncrpc.apps.jrpcgen.cup_runtime; import java.util.Stack; /** This class implements a skeleton table driven LR parser. In general, * LR parsers are a form of bottom up shift-reduce parsers. Shift-reduce * parsers act by shifting input onto a parse stack until the Symbols * matching the right hand side of a production appear on the top of the * stack. Once this occurs, a reduce is performed. This involves removing * the Symbols corresponding to the right hand side of the production * (the so called "handle") and replacing them with the non-terminal from * the left hand side of the production.

* * To control the decision of whether to shift or reduce at any given point, * the parser uses a state machine (the "viable prefix recognition machine" * built by the parser generator). The current state of the machine is placed * on top of the parse stack (stored as part of a Symbol object representing * a terminal or non terminal). The parse action table is consulted * (using the current state and the current lookahead Symbol as indexes) to * determine whether to shift or to reduce. When the parser shifts, it * changes to a new state by pushing a new Symbol (containing a new state) * onto the stack. When the parser reduces, it pops the handle (right hand * side of a production) off the stack. This leaves the parser in the state * it was in before any of those Symbols were matched. Next the reduce-goto * table is consulted (using the new state and current lookahead Symbol as * indexes) to determine a new state to go to. The parser then shifts to * this goto state by pushing the left hand side Symbol of the production * (also containing the new state) onto the stack.

* * This class actually provides four LR parsers. The methods parse() and * debug_parse() provide two versions of the main parser (the only difference * being that debug_parse() emits debugging trace messages as it parses). * In addition to these main parsers, the error recovery mechanism uses two * more. One of these is used to simulate "parsing ahead" in the input * without carrying out actions (to verify that a potential error recovery * has worked), and the other is used to parse through buffered "parse ahead" * input in order to execute all actions and re-synchronize the actual parser * configuration.

* * This is an abstract class which is normally filled out by a subclass * generated by the JavaCup parser generator. In addition to supplying * the actual parse tables, generated code also supplies methods which * invoke various pieces of user supplied code, provide access to certain * special Symbols (e.g., EOF and error), etc. Specifically, the following * abstract methods are normally supplied by generated code: *

*
short[][] production_table() *
Provides a reference to the production table (indicating the index of * the left hand side non terminal and the length of the right hand side * for each production in the grammar). *
short[][] action_table() *
Provides a reference to the parse action table. *
short[][] reduce_table() *
Provides a reference to the reduce-goto table. *
int start_state() *
Indicates the index of the start state. *
int start_production() *
Indicates the index of the starting production. *
int EOF_sym() *
Indicates the index of the EOF Symbol. *
int error_sym() *
Indicates the index of the error Symbol. *
Symbol do_action() *
Executes a piece of user supplied action code. This always comes at * the point of a reduce in the parse, so this code also allocates and * fills in the left hand side non terminal Symbol object that is to be * pushed onto the stack for the reduce. *
void init_actions() *
Code to initialize a special object that encapsulates user supplied * actions (this object is used by do_action() to actually carry out the * actions). *
* * In addition to these routines that must be supplied by the * generated subclass there are also a series of routines that may * be supplied. These include: *
*
Symbol scan() *
Used to get the next input Symbol from the scanner. *
Scanner getScanner() *
Used to provide a scanner for the default implementation of * scan(). *
int error_sync_size() *
This determines how many Symbols past the point of an error * must be parsed without error in order to consider a recovery to * be valid. This defaults to 3. Values less than 2 are not * recommended. *
void report_error(String message, Object info) *
This method is called to report an error. The default implementation * simply prints a message to System.err and where the error occurred. * This method is often replaced in order to provide a more sophisticated * error reporting mechanism. *
void report_fatal_error(String message, Object info) *
This method is called when a fatal error that cannot be recovered from * is encountered. In the default implementation, it calls * report_error() to emit a message, then throws an exception. *
void syntax_error(Symbol cur_token) *
This method is called as soon as syntax error is detected (but * before recovery is attempted). In the default implementation it * invokes: report_error("Syntax error", null); *
void unrecovered_syntax_error(Symbol cur_token) *
This method is called if syntax error recovery fails. In the default * implementation it invokes:
* report_fatal_error("Couldn't repair and continue parse", null); *
* * @see java_cup.runtime.Symbol * @see java_cup.runtime.Symbol * @see java_cup.runtime.virtual_parse_stack * @version last updated: 7/3/96 * @author Frank Flannery */ public abstract class lr_parser { /*-----------------------------------------------------------*/ /*--- Constructor(s) ----------------------------------------*/ /*-----------------------------------------------------------*/ /** Simple constructor. */ public lr_parser() { /* nothing to do here */ } /** Constructor that sets the default scanner. [CSA/davidm] */ public lr_parser(Scanner s) { this(); /* in case default constructor someday does something */ setScanner(s); } /*-----------------------------------------------------------*/ /*--- (Access to) Static (Class) Variables ------------------*/ /*-----------------------------------------------------------*/ /** The default number of Symbols after an error we much match to consider * it recovered from. */ protected final static int _error_sync_size = 3; /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** The number of Symbols after an error we much match to consider it * recovered from. */ protected int error_sync_size() {return _error_sync_size; } /*-----------------------------------------------------------*/ /*--- (Access to) Instance Variables ------------------------*/ /*-----------------------------------------------------------*/ /** Table of production information (supplied by generated subclass). * This table contains one entry per production and is indexed by * the negative-encoded values (reduce actions) in the action_table. * Each entry has two parts, the index of the non-terminal on the * left hand side of the production, and the number of Symbols * on the right hand side. */ public abstract short[][] production_table(); /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** The action table (supplied by generated subclass). This table is * indexed by state and terminal number indicating what action is to * be taken when the parser is in the given state (i.e., the given state * is on top of the stack) and the given terminal is next on the input. * States are indexed using the first dimension, however, the entries for * a given state are compacted and stored in adjacent index, value pairs * which are searched for rather than accessed directly (see get_action()). * The actions stored in the table will be either shifts, reduces, or * errors. Shifts are encoded as positive values (one greater than the * state shifted to). Reduces are encoded as negative values (one less * than the production reduced by). Error entries are denoted by zero. * * @see java_cup.runtime.lr_parser#get_action */ public abstract short[][] action_table(); /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** The reduce-goto table (supplied by generated subclass). This * table is indexed by state and non-terminal number and contains * state numbers. States are indexed using the first dimension, however, * the entries for a given state are compacted and stored in adjacent * index, value pairs which are searched for rather than accessed * directly (see get_reduce()). When a reduce occurs, the handle * (corresponding to the RHS of the matched production) is popped off * the stack. The new top of stack indicates a state. This table is * then indexed by that state and the LHS of the reducing production to * indicate where to "shift" to. * * @see java_cup.runtime.lr_parser#get_reduce */ public abstract short[][] reduce_table(); /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** The index of the start state (supplied by generated subclass). */ public abstract int start_state(); /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** The index of the start production (supplied by generated subclass). */ public abstract int start_production(); /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** The index of the end of file terminal Symbol (supplied by generated * subclass). */ public abstract int EOF_sym(); /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** The index of the special error Symbol (supplied by generated subclass). */ public abstract int error_sym(); /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Internal flag to indicate when parser should quit. */ protected boolean _done_parsing = false; /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** This method is called to indicate that the parser should quit. This is * normally called by an accept action, but can be used to cancel parsing * early in other circumstances if desired. */ public void done_parsing() { _done_parsing = true; } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /* Global parse state shared by parse(), error recovery, and * debugging routines */ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Indication of the index for top of stack (for use by actions). */ protected int tos; /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** The current lookahead Symbol. */ protected Symbol cur_token; /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** The parse stack itself. */ protected Stack stack = new Stack(); /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Direct reference to the production table. */ protected short[][] production_tab; /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Direct reference to the action table. */ protected short[][] action_tab; /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Direct reference to the reduce-goto table. */ protected short[][] reduce_tab; /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** This is the scanner object used by the default implementation * of scan() to get Symbols. To avoid name conflicts with existing * code, this field is private. [CSA/davidm] */ private Scanner _scanner; /** * Simple accessor method to set the default scanner. */ public void setScanner(Scanner s) { _scanner = s; } /** * Simple accessor method to get the default scanner. */ public Scanner getScanner() { return _scanner; } /*-----------------------------------------------------------*/ /*--- General Methods ---------------------------------------*/ /*-----------------------------------------------------------*/ /** Perform a bit of user supplied action code (supplied by generated * subclass). Actions are indexed by an internal action number assigned * at parser generation time. * * @param act_num the internal index of the action to be performed. * @param parser the parser object we are acting for. * @param stack the parse stack of that object. * @param top the index of the top element of the parse stack. */ public abstract Symbol do_action( int act_num, lr_parser parser, Stack stack, int top) throws java.lang.Exception; /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** User code for initialization inside the parser. Typically this * initializes the scanner. This is called before the parser requests * the first Symbol. Here this is just a placeholder for subclasses that * might need this and we perform no action. This method is normally * overridden by the generated code using this contents of the "init with" * clause as its body. */ public void user_init() throws java.lang.Exception { } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Initialize the action object. This is called before the parser does * any parse actions. This is filled in by generated code to create * an object that encapsulates all action code. */ protected abstract void init_actions() throws java.lang.Exception; /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Get the next Symbol from the input (supplied by generated subclass). * Once end of file has been reached, all subsequent calls to scan * should return an EOF Symbol (which is Symbol number 0). By default * this method returns getScanner().next_token(); this implementation * can be overriden by the generated parser using the code declared in * the "scan with" clause. Do not recycle objects; every call to * scan() should return a fresh object. */ public Symbol scan() throws java.lang.Exception { Symbol sym = getScanner().next_token(); return (sym!=null) ? sym : new Symbol(EOF_sym()); } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Report a fatal error. This method takes a message string and an * additional object (to be used by specializations implemented in * subclasses). Here in the base class a very simple implementation * is provided which reports the error then throws an exception. * * @param message an error message. * @param info an extra object reserved for use by specialized subclasses. */ public void report_fatal_error( String message, Object info) throws java.lang.Exception { /* stop parsing (not really necessary since we throw an exception, but) */ done_parsing(); /* use the normal error message reporting to put out the message */ report_error(message, info); /* throw an exception */ throw new Exception("Can't recover from previous error(s)"); } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Report a non fatal error (or warning). This method takes a message * string and an additional object (to be used by specializations * implemented in subclasses). Here in the base class a very simple * implementation is provided which simply prints the message to * System.err. * * @param message an error message. * @param info an extra object reserved for use by specialized subclasses. */ public void report_error(String message, Object info) { System.err.print(message); if (info instanceof Symbol) if (((Symbol)info).left != -1) System.err.println(" at character " + ((Symbol)info).left + " of input"); else System.err.println(""); else System.err.println(""); } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** This method is called when a syntax error has been detected and recovery * is about to be invoked. Here in the base class we just emit a * "Syntax error" error message. * * @param cur_token the current lookahead Symbol. */ public void syntax_error(Symbol cur_token) { report_error("Syntax error", cur_token); } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** This method is called if it is determined that syntax error recovery * has been unsuccessful. Here in the base class we report a fatal error. * * @param cur_token the current lookahead Symbol. */ public void unrecovered_syntax_error(Symbol cur_token) throws java.lang.Exception { report_fatal_error("Couldn't repair and continue parse", cur_token); } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Fetch an action from the action table. The table is broken up into * rows, one per state (rows are indexed directly by state number). * Within each row, a list of index, value pairs are given (as sequential * entries in the table), and the list is terminated by a default entry * (denoted with a Symbol index of -1). To find the proper entry in a row * we do a linear or binary search (depending on the size of the row). * * @param state the state index of the action being accessed. * @param sym the Symbol index of the action being accessed. */ protected final short get_action(int state, int sym) { short tag; int first, last, probe; short[] row = action_tab[state]; /* linear search if we are < 10 entries */ if (row.length < 20) for (probe = 0; probe < row.length; probe++) { /* is this entry labeled with our Symbol or the default? */ tag = row[probe++]; if (tag == sym || tag == -1) { /* return the next entry */ return row[probe]; } } /* otherwise binary search */ else { first = 0; last = (row.length-1)/2 - 1; /* leave out trailing default entry */ while (first <= last) { probe = (first+last)/2; if (sym == row[probe*2]) return row[probe*2+1]; else if (sym > row[probe*2]) first = probe+1; else last = probe-1; } /* not found, use the default at the end */ return row[row.length-1]; } /* shouldn't happened, but if we run off the end we return the default (error == 0) */ return 0; } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Fetch a state from the reduce-goto table. The table is broken up into * rows, one per state (rows are indexed directly by state number). * Within each row, a list of index, value pairs are given (as sequential * entries in the table), and the list is terminated by a default entry * (denoted with a Symbol index of -1). To find the proper entry in a row * we do a linear search. * * @param state the state index of the entry being accessed. * @param sym the Symbol index of the entry being accessed. */ protected final short get_reduce(int state, int sym) { short tag; short[] row = reduce_tab[state]; /* if we have a null row we go with the default */ if (row == null) return -1; for (int probe = 0; probe < row.length; probe++) { /* is this entry labeled with our Symbol or the default? */ tag = row[probe++]; if (tag == sym || tag == -1) { /* return the next entry */ return row[probe]; } } /* if we run off the end we return the default (error == -1) */ return -1; } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** This method provides the main parsing routine. It returns only when * done_parsing() has been called (typically because the parser has * accepted, or a fatal error has been reported). See the header * documentation for the class regarding how shift/reduce parsers operate * and how the various tables are used. */ public Symbol parse() throws java.lang.Exception { /* the current action code */ int act; /* the Symbol/stack element returned by a reduce */ Symbol lhs_sym = null; /* information about production being reduced with */ short handle_size, lhs_sym_num; /* set up direct reference to tables to drive the parser */ production_tab = production_table(); action_tab = action_table(); reduce_tab = reduce_table(); /* initialize the action encapsulation object */ init_actions(); /* do user initialization */ user_init(); /* get the first token */ cur_token = scan(); /* push dummy Symbol with start state to get us underway */ stack.removeAllElements(); stack.push(new Symbol(0, start_state())); tos = 0; /* continue until we are told to stop */ for (_done_parsing = false; !_done_parsing; ) { /* Check current token for freshness. */ if (cur_token.used_by_parser) throw new Error("Symbol recycling detected (fix your scanner)."); /* current state is always on the top of the stack */ /* look up action out of the current state with the current input */ act = get_action(((Symbol)stack.peek()).parse_state, cur_token.sym); /* decode the action -- > 0 encodes shift */ if (act > 0) { /* shift to the encoded state by pushing it on the stack */ cur_token.parse_state = act-1; cur_token.used_by_parser = true; stack.push(cur_token); tos++; /* advance to the next Symbol */ cur_token = scan(); } /* if its less than zero, then it encodes a reduce action */ else if (act < 0) { /* perform the action for the reduce */ lhs_sym = do_action((-act)-1, this, stack, tos); /* look up information about the production */ lhs_sym_num = production_tab[(-act)-1][0]; handle_size = production_tab[(-act)-1][1]; /* pop the handle off the stack */ for (int i = 0; i < handle_size; i++) { stack.pop(); tos--; } /* look up the state to go to from the one popped back to */ act = get_reduce(((Symbol)stack.peek()).parse_state, lhs_sym_num); /* shift to that state */ lhs_sym.parse_state = act; lhs_sym.used_by_parser = true; stack.push(lhs_sym); tos++; } /* finally if the entry is zero, we have an error */ else if (act == 0) { /* call user syntax error reporting routine */ syntax_error(cur_token); /* try to error recover */ if (!error_recovery(false)) { /* if that fails give up with a fatal syntax error */ unrecovered_syntax_error(cur_token); /* just in case that wasn't fatal enough, end parse */ done_parsing(); } else { lhs_sym = (Symbol)stack.peek(); } } } return lhs_sym; } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Write a debugging message to System.err for the debugging version * of the parser. * * @param mess the text of the debugging message. */ public void debug_message(String mess) { System.err.println(mess); } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Dump the parse stack for debugging purposes. */ public void dump_stack() { if (stack == null) { debug_message("# Stack dump requested, but stack is null"); return; } debug_message("============ Parse Stack Dump ============"); /* dump the stack */ for (int i=0; i"); if ((i%3)==2 || (i==(stack.size()-1))) { debug_message(sb.toString()); sb = new StringBuffer(" "); } } } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Perform a parse with debugging output. This does exactly the * same things as parse(), except that it calls debug_shift() and * debug_reduce() when shift and reduce moves are taken by the parser * and produces various other debugging messages. */ public Symbol debug_parse() throws java.lang.Exception { /* the current action code */ int act; /* the Symbol/stack element returned by a reduce */ Symbol lhs_sym = null; /* information about production being reduced with */ short handle_size, lhs_sym_num; /* set up direct reference to tables to drive the parser */ production_tab = production_table(); action_tab = action_table(); reduce_tab = reduce_table(); debug_message("# Initializing parser"); /* initialize the action encapsulation object */ init_actions(); /* do user initialization */ user_init(); /* the current Symbol */ cur_token = scan(); debug_message("# Current Symbol is #" + cur_token.sym); /* push dummy Symbol with start state to get us underway */ stack.removeAllElements(); stack.push(new Symbol(0, start_state())); tos = 0; /* continue until we are told to stop */ for (_done_parsing = false; !_done_parsing; ) { /* Check current token for freshness. */ if (cur_token.used_by_parser) throw new Error("Symbol recycling detected (fix your scanner)."); /* current state is always on the top of the stack */ //debug_stack(); /* look up action out of the current state with the current input */ act = get_action(((Symbol)stack.peek()).parse_state, cur_token.sym); /* decode the action -- > 0 encodes shift */ if (act > 0) { /* shift to the encoded state by pushing it on the stack */ cur_token.parse_state = act-1; cur_token.used_by_parser = true; debug_shift(cur_token); stack.push(cur_token); tos++; /* advance to the next Symbol */ cur_token = scan(); debug_message("# Current token is " + cur_token); } /* if its less than zero, then it encodes a reduce action */ else if (act < 0) { /* perform the action for the reduce */ lhs_sym = do_action((-act)-1, this, stack, tos); /* look up information about the production */ lhs_sym_num = production_tab[(-act)-1][0]; handle_size = production_tab[(-act)-1][1]; debug_reduce((-act)-1, lhs_sym_num, handle_size); /* pop the handle off the stack */ for (int i = 0; i < handle_size; i++) { stack.pop(); tos--; } /* look up the state to go to from the one popped back to */ act = get_reduce(((Symbol)stack.peek()).parse_state, lhs_sym_num); debug_message("# Reduce rule: top state " + ((Symbol)stack.peek()).parse_state + ", lhs sym " + lhs_sym_num + " -> state " + act); /* shift to that state */ lhs_sym.parse_state = act; lhs_sym.used_by_parser = true; stack.push(lhs_sym); tos++; debug_message("# Goto state #" + act); } /* finally if the entry is zero, we have an error */ else if (act == 0) { /* call user syntax error reporting routine */ syntax_error(cur_token); /* try to error recover */ if (!error_recovery(true)) { /* if that fails give up with a fatal syntax error */ unrecovered_syntax_error(cur_token); /* just in case that wasn't fatal enough, end parse */ done_parsing(); } else { lhs_sym = (Symbol)stack.peek(); } } } return lhs_sym; } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /* Error recovery code */ /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Attempt to recover from a syntax error. This returns false if recovery * fails, true if it succeeds. Recovery happens in 4 steps. First we * pop the parse stack down to a point at which we have a shift out * of the top-most state on the error Symbol. This represents the * initial error recovery configuration. If no such configuration is * found, then we fail. Next a small number of "lookahead" or "parse * ahead" Symbols are read into a buffer. The size of this buffer is * determined by error_sync_size() and determines how many Symbols beyond * the error must be matched to consider the recovery a success. Next, * we begin to discard Symbols in attempt to get past the point of error * to a point where we can continue parsing. After each Symbol, we attempt * to "parse ahead" though the buffered lookahead Symbols. The "parse ahead" * process simulates that actual parse, but does not modify the real * parser's configuration, nor execute any actions. If we can parse all * the stored Symbols without error, then the recovery is considered a * success. Once a successful recovery point is determined, we do an * actual parse over the stored input -- modifying the real parse * configuration and executing all actions. Finally, we return the the * normal parser to continue with the overall parse. * * @param debug should we produce debugging messages as we parse. */ protected boolean error_recovery(boolean debug) throws java.lang.Exception { if (debug) debug_message("# Attempting error recovery"); /* first pop the stack back into a state that can shift on error and do that shift (if that fails, we fail) */ if (!find_recovery_config(debug)) { if (debug) debug_message("# Error recovery fails"); return false; } /* read ahead to create lookahead we can parse multiple times */ read_lookahead(); /* repeatedly try to parse forward until we make it the required dist */ for (;;) { /* try to parse forward, if it makes it, bail out of loop */ if (debug) debug_message("# Trying to parse ahead"); if (try_parse_ahead(debug)) { break; } /* if we are now at EOF, we have failed */ if (lookahead[0].sym == EOF_sym()) { if (debug) debug_message("# Error recovery fails at EOF"); return false; } /* otherwise, we consume another Symbol and try again */ // BUG FIX by Bruce Hutton // Computer Science Department, University of Auckland, // Auckland, New Zealand. // It is the first token that is being consumed, not the one // we were up to parsing if (debug) debug_message("# Consuming Symbol #" + lookahead[ 0 ].sym); restart_lookahead(); } /* we have consumed to a point where we can parse forward */ if (debug) debug_message("# Parse-ahead ok, going back to normal parse"); /* do the real parse (including actions) across the lookahead */ parse_lookahead(debug); /* we have success */ return true; } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Determine if we can shift under the special error Symbol out of the * state currently on the top of the (real) parse stack. */ protected boolean shift_under_error() { /* is there a shift under error Symbol */ return get_action(((Symbol)stack.peek()).parse_state, error_sym()) > 0; } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Put the (real) parse stack into error recovery configuration by * popping the stack down to a state that can shift on the special * error Symbol, then doing the shift. If no suitable state exists on * the stack we return false * * @param debug should we produce debugging messages as we parse. */ protected boolean find_recovery_config(boolean debug) { Symbol error_token; int act; if (debug) debug_message("# Finding recovery state on stack"); /* Remember the right-position of the top symbol on the stack */ int right_pos = ((Symbol)stack.peek()).right; int left_pos = ((Symbol)stack.peek()).left; /* pop down until we can shift under error Symbol */ while (!shift_under_error()) { /* pop the stack */ if (debug) debug_message("# Pop stack by one, state was # " + ((Symbol)stack.peek()).parse_state); left_pos = ((Symbol)stack.pop()).left; tos--; /* if we have hit bottom, we fail */ if (stack.empty()) { if (debug) debug_message("# No recovery state found on stack"); return false; } } /* state on top of the stack can shift under error, find the shift */ act = get_action(((Symbol)stack.peek()).parse_state, error_sym()); if (debug) { debug_message("# Recover state found (#" + ((Symbol)stack.peek()).parse_state + ")"); debug_message("# Shifting on error to state #" + (act-1)); } /* build and shift a special error Symbol */ error_token = new Symbol(error_sym(), left_pos, right_pos); error_token.parse_state = act-1; error_token.used_by_parser = true; stack.push(error_token); tos++; return true; } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Lookahead Symbols used for attempting error recovery "parse aheads". */ protected Symbol lookahead[]; /** Position in lookahead input buffer used for "parse ahead". */ protected int lookahead_pos; /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Read from input to establish our buffer of "parse ahead" lookahead * Symbols. */ protected void read_lookahead() throws java.lang.Exception { /* create the lookahead array */ lookahead = new Symbol[error_sync_size()]; /* fill in the array */ for (int i = 0; i < error_sync_size(); i++) { lookahead[i] = cur_token; cur_token = scan(); } /* start at the beginning */ lookahead_pos = 0; } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Return the current lookahead in our error "parse ahead" buffer. */ protected Symbol cur_err_token() { return lookahead[lookahead_pos]; } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Advance to next "parse ahead" input Symbol. Return true if we have * input to advance to, false otherwise. */ protected boolean advance_lookahead() { /* advance the input location */ lookahead_pos++; /* return true if we didn't go off the end */ return lookahead_pos < error_sync_size(); } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Reset the parse ahead input to one Symbol past where we started error * recovery (this consumes one new Symbol from the real input). */ protected void restart_lookahead() throws java.lang.Exception { /* move all the existing input over */ for (int i = 1; i < error_sync_size(); i++) lookahead[i-1] = lookahead[i]; /* read a new Symbol into the last spot */ // BUG Fix by Bruce Hutton // Computer Science Department, University of Auckland, // Auckland, New Zealand. [applied 5-sep-1999 by csa] // The following two lines were out of order!! lookahead[error_sync_size()-1] = cur_token; cur_token = scan(); /* reset our internal position marker */ lookahead_pos = 0; } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Do a simulated parse forward (a "parse ahead") from the current * stack configuration using stored lookahead input and a virtual parse * stack. Return true if we make it all the way through the stored * lookahead input without error. This basically simulates the action of * parse() using only our saved "parse ahead" input, and not executing any * actions. * * @param debug should we produce debugging messages as we parse. */ protected boolean try_parse_ahead(boolean debug) throws java.lang.Exception { int act; short lhs, rhs_size; /* create a virtual stack from the real parse stack */ virtual_parse_stack vstack = new virtual_parse_stack(stack); /* parse until we fail or get past the lookahead input */ for (;;) { /* look up the action from the current state (on top of stack) */ act = get_action(vstack.top(), cur_err_token().sym); /* if its an error, we fail */ if (act == 0) return false; /* > 0 encodes a shift */ if (act > 0) { /* push the new state on the stack */ vstack.push(act-1); if (debug) debug_message("# Parse-ahead shifts Symbol #" + cur_err_token().sym + " into state #" + (act-1)); /* advance simulated input, if we run off the end, we are done */ if (!advance_lookahead()) return true; } /* < 0 encodes a reduce */ else { /* if this is a reduce with the start production we are done */ if ((-act)-1 == start_production()) { if (debug) debug_message("# Parse-ahead accepts"); return true; } /* get the lhs Symbol and the rhs size */ lhs = production_tab[(-act)-1][0]; rhs_size = production_tab[(-act)-1][1]; /* pop handle off the stack */ for (int i = 0; i < rhs_size; i++) vstack.pop(); if (debug) debug_message("# Parse-ahead reduces: handle size = " + rhs_size + " lhs = #" + lhs + " from state #" + vstack.top()); /* look up goto and push it onto the stack */ vstack.push(get_reduce(vstack.top(), lhs)); if (debug) debug_message("# Goto state #" + vstack.top()); } } } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Parse forward using stored lookahead Symbols. In this case we have * already verified that parsing will make it through the stored lookahead * Symbols and we are now getting back to the point at which we can hand * control back to the normal parser. Consequently, this version of the * parser performs all actions and modifies the real parse configuration. * This returns once we have consumed all the stored input or we accept. * * @param debug should we produce debugging messages as we parse. */ protected void parse_lookahead(boolean debug) throws java.lang.Exception { /* the current action code */ int act; /* the Symbol/stack element returned by a reduce */ Symbol lhs_sym = null; /* information about production being reduced with */ short handle_size, lhs_sym_num; /* restart the saved input at the beginning */ lookahead_pos = 0; if (debug) { debug_message("# Reparsing saved input with actions"); debug_message("# Current Symbol is #" + cur_err_token().sym); debug_message("# Current state is #" + ((Symbol)stack.peek()).parse_state); } /* continue until we accept or have read all lookahead input */ while(!_done_parsing) { /* current state is always on the top of the stack */ /* look up action out of the current state with the current input */ act = get_action(((Symbol)stack.peek()).parse_state, cur_err_token().sym); /* decode the action -- > 0 encodes shift */ if (act > 0) { /* shift to the encoded state by pushing it on the stack */ cur_err_token().parse_state = act-1; cur_err_token().used_by_parser = true; if (debug) debug_shift(cur_err_token()); stack.push(cur_err_token()); tos++; /* advance to the next Symbol, if there is none, we are done */ if (!advance_lookahead()) { if (debug) debug_message("# Completed reparse"); /* scan next Symbol so we can continue parse */ // BUGFIX by Chris Harris : // correct a one-off error by commenting out // this next line. /*cur_token = scan();*/ /* go back to normal parser */ return; } if (debug) debug_message("# Current Symbol is #" + cur_err_token().sym); } /* if its less than zero, then it encodes a reduce action */ else if (act < 0) { /* perform the action for the reduce */ lhs_sym = do_action((-act)-1, this, stack, tos); /* look up information about the production */ lhs_sym_num = production_tab[(-act)-1][0]; handle_size = production_tab[(-act)-1][1]; if (debug) debug_reduce((-act)-1, lhs_sym_num, handle_size); /* pop the handle off the stack */ for (int i = 0; i < handle_size; i++) { stack.pop(); tos--; } /* look up the state to go to from the one popped back to */ act = get_reduce(((Symbol)stack.peek()).parse_state, lhs_sym_num); /* shift to that state */ lhs_sym.parse_state = act; lhs_sym.used_by_parser = true; stack.push(lhs_sym); tos++; if (debug) debug_message("# Goto state #" + act); } /* finally if the entry is zero, we have an error (shouldn't happen here, but...)*/ else if (act == 0) { report_fatal_error("Syntax error", lhs_sym); return; } } } /*-----------------------------------------------------------*/ /** Utility function: unpacks parse tables from strings */ protected static short[][] unpackFromStrings(String[] sa) { // Concatanate initialization strings. StringBuffer sb = new StringBuffer(sa[0]); for (int i=1; i= real_stack.size()) return; /* get a copy of the first Symbol we have not transfered */ stack_sym = (Symbol)real_stack.elementAt(real_stack.size()-1-real_next); /* record the transfer */ real_next++; /* put the state number from the Symbol onto the virtual stack */ vstack.push(new Integer(stack_sym.parse_state)); } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Indicate whether the stack is empty. */ public boolean empty() { /* if vstack is empty then we were unable to transfer onto it and the whole thing is empty. */ return vstack.empty(); } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Return value on the top of the stack (without popping it). */ public int top() throws java.lang.Exception { if (vstack.empty()) throw new Exception( "Internal parser error: top() called on empty virtual stack"); return ((Integer)vstack.peek()).intValue(); } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Pop the stack. */ public void pop() throws java.lang.Exception { if (vstack.empty()) throw new Exception( "Internal parser error: pop from empty virtual stack"); /* pop it */ vstack.pop(); /* if we are now empty transfer an element (if there is one) */ if (vstack.empty()) get_from_real(); } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Push a state number onto the stack. */ public void push(int state_num) { vstack.push(new Integer(state_num)); } /*-----------------------------------------------------------*/ } remotetea-1.0.7/src/org/acplt/oncrpc/apps/jrpcgen/JrpcgenConst.java0000644005374700003410000001276407716406402026442 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/apps/jrpcgen/JrpcgenConst.java,v 1.1.1.1 2003/08/13 12:03:45 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc.apps.jrpcgen; /** * The JrpcgenConst class represents a single constant defined * in an rpcgen "x"-file. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:45 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class JrpcgenConst { /** * Constant identifier. */ public String identifier; /** * Contains value (or identifier refering to another constant) of constant. */ public String value; /** * Specifies the enclosure (scope) within the identifier must be * addressed for a constant defined by an enumumeration. */ public String enclosure; /** * Returns value as integer literal (and thus resolving identifiers * recursively, if necessary). This is only possible for simple * subsitutions, that is A is defined as B, B as C, and C as 42, thus * A is eventually defined as 42. * *

This simple kind of resolving is necessary when defining a particular * version of an ONC/RPC protocol. We need to be able to resolve the * version to an integer literal because we need to append the version * number to any remote procedure defined to avoid identifier clashes if * the same remote procedure is defined for several versions. * * @return integer literal as String or null, * if the identifier could not be resolved to an integer literal. */ public String resolveValue() { if ( value.length() > 0 ) { // // If the value is an integer literal, then we just have to // return it. That's it. // if ( Character.isDigit(value.charAt(0)) || (value.charAt(0) == '-') ) { return value; } // // It's an identifier, which we now have to resolve. First, // look it up in the list of global identifiers. Then recursively // resolve the value. // Object id = jrpcgen.globalIdentifiers.get(identifier); if ( (id != null) && (id instanceof JrpcgenConst) ) { return ((JrpcgenConst) id).resolveValue(); } } return null; } /** * Constructs a JrpcgenConst and sets the identifier and * the associated value. * * @param identifier Constant identifier to define. * @param value Value assigned to constant. */ public JrpcgenConst(String identifier, String value) { this(identifier, value, null); } /** * Constructs a JrpcgenConst and sets the identifier and * the associated value of an enumeration etc. * * @param identifier Constant identifier to define. * @param value Value assigned to constant. * @param enclosure Name of enclosing enumeration, etc. */ public JrpcgenConst(String identifier, String value, String enclosure) { this.identifier = identifier; this.value = value; this.enclosure = enclosure; } /** * Returns the identifier this constant depends on or null, * if no dependency exists. * * @return dependency identifier or null. */ public String getDependencyIdentifier() { int len = value.length(); int idx = 0; char c; // // Check to see if it's an identifier and search for its end. // This is necessary as elements of an enumeration might have // "+x" appended, where x is an integer literal. // while ( idx < len ) { c = value.charAt(idx++); if ( !( ((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z')) || (c == '_') || ((c >= '0') && (c <= '9') && (idx > 0)) ) ) { --idx; // back up to the char not belonging to the identifier. break; } } if ( idx > 0 ) { return value.substring(0, idx); } return null; } /** * Dumps the constant as well as its value to System.out. */ public void dump() { System.out.println(identifier + " = " + value); } /** * Flag indicating whether this constant and its dependencies should be * traversed any more. */ public boolean dontTraverseAnyMore = false; } // End of JrpcgenConst.java remotetea-1.0.7/src/org/acplt/oncrpc/apps/jrpcgen/JrpcgenDeclaration.java0000644005374700003410000001106607716623542027601 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/apps/jrpcgen/JrpcgenDeclaration.java,v 1.2 2003/08/14 08:08:34 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc.apps.jrpcgen; /** * The JrpcgenDeclaration class represents a single declaration * from an rpcgen "x"-file. * * @version $Revision: 1.2 $ $Date: 2003/08/14 08:08:34 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class JrpcgenDeclaration implements Cloneable { /** * Identifier. */ public String identifier; /** * Type specifier. */ public String type; /** * Kind of declaration (scalar, fixed size vector, dynamic vector). * * @see JrpcgenDeclaration#SCALAR * @see JrpcgenDeclaration#FIXEDVECTOR * @see JrpcgenDeclaration#DYNAMICVECTOR * @see JrpcgenDeclaration#INDIRECTION */ public int kind; /** * Fixed size or upper limit for size of vector. */ public String size; /** * Indicates that a scalar is declared. */ public static final int SCALAR = 0; /** * Indicates that a vector (an array) with fixed size is declared. */ public static final int FIXEDVECTOR = 1; /** * Indicates that a vector (an array) with dynamic (or unknown) size * is declared. */ public static final int DYNAMICVECTOR = 2; /** * Indicates that an indirection (reference, pointer, whatever you like * to call it nowadays) is declared. */ public static final int INDIRECTION = 3; /** * Returns the identifier. */ public String toString() { return identifier; } /** * Constructs a JrpcgenDeclaration and sets the identifier * and its data type. The {@link JrpcgenDeclaration#kind} of the * declaration is assumed to be {@link JrpcgenDeclaration#SCALAR}. * * @param identifier Identifier to be declared. * @param type Data type the identifier is declared of. */ public JrpcgenDeclaration(String identifier, String type) { this.identifier = identifier; this.type = type; this.kind = SCALAR; } /** * Constructs a JrpcgenDeclaration and sets the identifier, * its data type, kind and size of vector. This constructur is typically * used when declaring either fixed-size or dynamic arrays. * * @param identifier Identifier to be declared. * @param type Data type the identifier is declared of. * @param kind Kind of declaration (scalar, vector, indirection). * @param size Size of array (if fixed-sized, otherwise null). */ public JrpcgenDeclaration(String identifier, String type, int kind, String size) { this.identifier = identifier; this.type = type; this.kind = kind; this.size = size; } /** * Dumps the declaration to System.out. */ public void dump() { System.out.print(type); System.out.print(kind == JrpcgenDeclaration.INDIRECTION ? " *" : " "); System.out.print(identifier); switch ( kind ) { case JrpcgenDeclaration.FIXEDVECTOR: System.out.print("[" + size + "]"); break; case JrpcgenDeclaration.DYNAMICVECTOR: if ( size != null ) { System.out.print("<" + size + ">"); } else { System.out.print("<>"); } break; } System.out.println(); } /** * Clones declaration object. */ public Object clone() throws CloneNotSupportedException { return super.clone(); } } // End of JrpcgenDeclaration.javaremotetea-1.0.7/src/org/acplt/oncrpc/apps/jrpcgen/JrpcgenEnum.java0000644005374700003410000000526307716406402026254 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/apps/jrpcgen/JrpcgenEnum.java,v 1.1.1.1 2003/08/13 12:03:45 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc.apps.jrpcgen; import java.util.Vector; /** * The JrpcgenEnum class represents a single enumeration * from an rpcgen "x"-file. It is a "container" for the elements (constants) * belonging to this enumeration. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:45 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class JrpcgenEnum { /** * Enumeration identifier. */ public String identifier; /** * Contains enumeration elements as well as their values. The elements * are of class {@link JrpcgenConst}. */ public Vector enums; /** * Returns the fully qualified identifier. * * return fully qualified identifier. */ public String toString() { return identifier; } /** * Constructs a JrpcgenEnum and sets the identifier and all * its enumeration elements. * * @param identifier Identifier to be declared. * @param enums Vector of enumeration elements of class {@link JrpcgenConst}. */ public JrpcgenEnum(String identifier, Vector enums) { this.identifier = identifier; this.enums = enums; } /** * Dumps the enumeration together with its elements to * System.out. */ public void dump() { System.out.println("ENUM " + identifier); int size = enums.size(); for ( int idx = 0; idx < size; ++idx ) { JrpcgenConst c = (JrpcgenConst) enums.elementAt(idx); System.out.print(" "); c.dump(); } System.out.println(); } } // End of JrpcgenEnum.java remotetea-1.0.7/src/org/acplt/oncrpc/apps/jrpcgen/JrpcgenParamInfo.java0000644005374700003410000000347307716623670027235 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/apps/jrpcgen/JrpcgenParamInfo.java,v 1.2 2003/08/14 08:09:59 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc.apps.jrpcgen; /** * The JrpcgenParamInfo class contains information about the * data type of a procedure's parameter, as well as the parameter's optional * name. * * @version $Revision: 1.2 $ $Date: 2003/08/14 08:09:59 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ class JrpcgenParamInfo { /** * */ public String parameterType; /** * */ public String parameterName; /** * Constructs a new JrpcgenParamInfo object containing * information about ... * */ public JrpcgenParamInfo(String parameterType, String parameterName) { this.parameterType = parameterType; this.parameterName = parameterName; } } // End of JrpcgenParamInfo.javaremotetea-1.0.7/src/org/acplt/oncrpc/apps/jrpcgen/JrpcgenParser.cup0000644005374700003410000006612110335177470026453 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/apps/jrpcgen/JrpcgenParser.cup,v 1.2 2005/11/11 21:29:44 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * To compile into java code use: * java java_cup.Main -interface \ * -runtime org.acplt.oncrpc.apps.jrpcgen.cup_runtime \ * -symbols JrpcgenSymbols -parser JrpcgenParser < JrpcgenParser.cup */ package org.acplt.oncrpc.apps.jrpcgen; import org.acplt.oncrpc.apps.jrpcgen.cup_runtime.*; import java.util.Vector; // // We need to set up some code within the parser class... // parser code {: public void report_error(String message, Object info) { StringBuffer msg = new StringBuffer("jrpcgen: error"); if (info instanceof Symbol) { Symbol s = (Symbol) info; msg.append(" in line "); msg.append(s.left); } msg.append(": "); msg.append(message); System.out.println(msg); throw(new JrpcgenParserException()); } public void report_error(String message, int line) { StringBuffer msg = new StringBuffer("jrpcgen: error in line "); msg.append(line); msg.append(": "); msg.append(message); System.out.println(msg); throw(new JrpcgenParserException()); } public void syntax_error(Symbol cur_token) { StringBuffer msg = new StringBuffer("jrpcgen: syntax error in line "); msg.append(cur_token.left); System.out.println(msg); throw(new JrpcgenParserException()); } public void report_fatal_error(String message, Object info) { report_error(message, info); throw(new RuntimeException("Fatal Syntax Error")); } :}; // // As per convention, we use all uppercase letters for TERMINALs. // Notes: // - we do not define the terminals U_SHORT etc. but instead map these // terminals in the scanner to the corresponding signed base data type. // terminal SEMICOLON; // ";" terminal COMMA; // "," terminal COLON; // ":" terminal EQUAL; // "=" terminal STAR; // "*" terminal LPAREN, RPAREN; // "(" ")" terminal LBRACE, RBRACE; // "{" "}" terminal LBRACKET, RBRACKET; // "[" "]" terminal LANGLE, RANGLE; // "<" ">" terminal PROGRAM; // "PROGRAM" "program" terminal VERSION; // "VERSION" "version" terminal CONST; // "const" terminal TYPEDEF; // "typedef" terminal SWITCH; // "switch" terminal CASE; // "case" terminal DEFAULT; // "default" terminal VOID; // "void" terminal CHAR; // "char" terminal SHORT; // "short" terminal INT; // "int" terminal LONG; // "long" terminal HYPER; // "hyper" terminal FLOAT; // "float" terminal DOUBLE; // "double" terminal QUADRUPLE; // "quadruple" terminal BOOL; // "bool" terminal ENUM; // "enum" terminal OPAQUE; // "opaque" terminal STRING; // "string" terminal STRUCT; // "struct" terminal UNION; // "union" terminal UNSIGNED; // "unsigned" terminal String INTEGER_LITERAL; // yes, that's right. terminal String IDENTIFIER; non terminal compilation_unit; non terminal definitions_opt, definitions, definition; non terminal constant_def; non terminal enum_def; non terminal Vector enum_elements; non terminal JrpcgenConst enum_element; non terminal struct_def; non terminal union_def; non terminal Vector union_cases; non terminal JrpcgenUnionArm union_case; non terminal typedef_def; non terminal Vector program_defs; non terminal program_defs_opt; non terminal JrpcgenProgramInfo program_def; non terminal Vector version_defs; non terminal JrpcgenVersionInfo version_def; non terminal Vector procedure_defs; non terminal JrpcgenProcedureInfo procedure_def; non terminal Vector argument_list; non terminal Vector argument_list_no_void; non terminal String type_specifier_incl_specials; non terminal String type_specifier_incl_string; non terminal String type_specifier; non terminal Vector declarations; non terminal JrpcgenDeclaration declaration; non terminal String int_types; non terminal String value; start with compilation_unit; // // A ".x" file consists of zero or more definitions (typedef, struct, union, // enum, const) followed by exactly one program definition. // // After the compilation unit has been parsed, the jrpcgen class will contain // all necessary information in its static variable members to generate the // various source code files. // // ** SF patch #1159721: add possibility to generate from .x file without program def ** compilation_unit ::= definitions_opt program_defs_opt ; program_defs_opt ::= /* empty */ {: jrpcgen.programInfos = new Vector(); :} | program_defs:progDefs {: jrpcgen.programInfos = progDefs; :} ; program_defs ::= program_def:progDef {: RESULT = new Vector(); RESULT.addElement(progDef); :} | program_defs:progDefs program_def:progDef {: progDefs.addElement(progDef); RESULT = progDefs; :} ; definitions_opt ::= /* empty */ | definitions ; definitions ::= definition | definitions definition ; // // A single definition can be either a typedef, struct, union, enum or const // definition. // definition ::= constant_def | enum_def | struct_def | union_def | typedef_def ; // // A constant definition assigns either an integer literal or an identifier // to a (constant) identifier: // - add constant identifier to global identifier list and remember the // "value" of the constant (either an integer literal or another // identifier). // constant_def ::= CONST IDENTIFIER:id EQUAL value:value SEMICOLON {: JrpcgenConst type = new JrpcgenConst(id, value, jrpcgen.baseClassname); if ( jrpcgen.globalIdentifiers.put(id, type) != null ) { parser.report_error("const identifier \"" + id + "\" already defined", idleft); } if ( jrpcgen.debug ) { System.out.print("CONST "); type.dump(); System.out.println(); } :} ; // // Parse an enumeration: // - add enumeration identifier to global identifier list and remember // which enumerated elements belong to the enumeration. // - add the individual enumerated elements to the global identifier list. // enum_def ::= ENUM IDENTIFIER:id LBRACE enum_elements:elements RBRACE SEMICOLON {: // // Fix up enclosure of enumeration elements, so we can later // use a full qualified identifier. // int size = elements.size(); for ( int idx = 0; idx < size; ++idx ) { JrpcgenConst c = (JrpcgenConst) elements.elementAt(idx); c.enclosure = id; } JrpcgenEnum type = new JrpcgenEnum(id, elements); if ( jrpcgen.globalIdentifiers.put(id, type) != null ) { parser.report_error("enum identifier \"" + id + "\" already defined", idleft); } if ( jrpcgen.debug ) { type.dump(); } :} ; enum_elements ::= enum_element:el {: // // If no specific value has been assigned to this element of // an enumeration, assign zero by default. // if ( el.value == null ) { el.value = "0"; } RESULT = new Vector(); RESULT.addElement(el); :} | enum_elements:elements COMMA enum_element:el {: // // If no specific value has been assigned to this element of // an enumeration, increment value of previous element and // assign the new value to this element. BTW -- we let the // Java compiler do the calculation, so references to // other constants by name are valid. // if ( el.value == null ) { el.value = ((JrpcgenConst)elements.elementAt(elements.size() - 1)).value + "+1"; } elements.addElement(el); RESULT = elements; :} ; enum_element ::= IDENTIFIER:id {: // // We don't know yet the value, so we don't specify one. The // value will be fixed up when the production for the complete // enumeration triggers. // RESULT = new JrpcgenConst(id, null); if ( jrpcgen.globalIdentifiers.put(id, RESULT) != null ) { parser.report_error("identifier \"" + id + "\" already defined", idleft); } :} | IDENTIFIER:id EQUAL value:val {: RESULT = new JrpcgenConst(id, val); if ( jrpcgen.globalIdentifiers.put(id, RESULT) != null ) { parser.report_error("identifier \"" + id + "\" already defined", idleft); } :} ; // // Parse a structure: // - add structure identifier to global list of identifiers. // struct_def ::= STRUCT IDENTIFIER:id LBRACE declarations:elements RBRACE SEMICOLON {: JrpcgenStruct strct = new JrpcgenStruct(id, elements); if ( jrpcgen.globalIdentifiers.put(id, strct) != null ) { parser.report_error("struct identifier \"" + id + "\" already defined", idleft); } if ( jrpcgen.debug ) { strct.dump(); } :} ; // // Parse a union: // - add union identifier to global list of identifiers. // Note that this grammar is more liberal with respect to the "default" // arm: it can appear anywhere within the union and need not to be the // last arm. This makes the grammar more straight then Sun's rpcgen. // union_def ::= UNION IDENTIFIER:id SWITCH LPAREN declaration:descrim RPAREN LBRACE union_cases:elements RBRACE SEMICOLON {: JrpcgenUnion uni = new JrpcgenUnion(id, descrim, elements); if ( jrpcgen.globalIdentifiers.put(id, uni) != null ) { parser.report_error("union identifier \"" + id + "\" already defined", idleft); } if ( jrpcgen.debug ) { uni.dump(); } :} ; union_cases ::= union_case:arm {: RESULT = new Vector(); RESULT.addElement(arm); :} | union_cases:arms union_case:arm {: arms.addElement(arm); RESULT = arms; :} ; union_case ::= CASE value:val COLON {: RESULT = new JrpcgenUnionArm(val, null); :} | CASE value:val COLON declaration:element SEMICOLON {: RESULT = new JrpcgenUnionArm(val, element); :} | DEFAULT COLON declaration:element SEMICOLON {: RESULT = new JrpcgenUnionArm(null, element); :} ; // // New type definition. // typedef_def ::= TYPEDEF declaration:decl SEMICOLON {: if ( jrpcgen.globalIdentifiers.put(decl.identifier, decl) != null ) { parser.report_error("typedef identifier \"" + decl.identifier + "\" already defined", declleft); } if ( jrpcgen.debug ) { System.out.print("TYPEDEF "); decl.dump(); } :} ; // // Parse a program definition: // - add program identifier to global list of identifiers. // - remember the individual versions of this program. // program_def ::= PROGRAM IDENTIFIER:progId LBRACE version_defs:versions RBRACE EQUAL value:progNumber SEMICOLON {: JrpcgenConst prog = new JrpcgenConst(progId, progNumber, jrpcgen.baseClassname); RESULT = new JrpcgenProgramInfo(progId, progNumber, versions); if ( jrpcgen.globalIdentifiers.put(progId, prog) != null ) { parser.report_error("program identifier \"" + progId + "\" already defined", progIdleft); } if ( jrpcgen.debug ) { System.out.println("PROGRAM " + progId + " = " + progNumber); } :} ; // // Parse a version definition: // - add version identifier to global list of identifiers. // - remember the procedures defined for this program version. // version_defs ::= version_def:version {: RESULT = new Vector(); RESULT.addElement(version); :} | version_defs:versions version_def:version {: versions.addElement(version); RESULT = versions; :} ; version_def ::= VERSION IDENTIFIER:versId LBRACE procedure_defs:procs RBRACE EQUAL value:versNumber SEMICOLON {: JrpcgenConst vers = new JrpcgenConst(versId, versNumber, jrpcgen.baseClassname); RESULT = new JrpcgenVersionInfo(versId, versNumber, procs); if ( jrpcgen.globalIdentifiers.put(versId, vers) != null ) { parser.report_error("version identifier \"" + versId + "\" already defined", versIdleft); } versNumber = vers.resolveValue(); if ( versNumber == null ) { parser.report_error("Can not resolve version identifier \"" + versId + "\" to integer literal", versNumberleft); } // // We also need to fix up the procedure identifiers by appending // the version number. // int size = procs.size(); for ( int idx = 0; idx < size; ++idx ) { JrpcgenProcedureInfo procInfo = (JrpcgenProcedureInfo) procs.elementAt(idx); procInfo.procedureId += "_" + versNumber; JrpcgenConst proc = new JrpcgenConst(procInfo.procedureId, procInfo.procedureNumber, jrpcgen.baseClassname); if ( jrpcgen.globalIdentifiers.put(procInfo.procedureId, proc) != null ) { // FIXME line number parser.report_error("procedure identifier \"" + procInfo.procedureId + "\" already defined", 0); } } if ( jrpcgen.debug ) { System.out.println("VERSION " + versId + " = " + versNumber); for ( int idx = 0; idx < size; ++idx ) { JrpcgenProcedureInfo procInfo = (JrpcgenProcedureInfo) procs.elementAt(idx); System.out.print("PROCEDURE " + procInfo.resultType + " " + procInfo.procedureId + "("); if ( procInfo.parameters == null ) { System.out.print("void"); } else { for ( int pidx = 0; pidx < procInfo.parameters.size(); ++pidx ) { JrpcgenParamInfo paramInfo = (JrpcgenParamInfo) procInfo.parameters.elementAt(pidx); if ( pidx > 0 ) { System.out.print(","); } System.out.print(paramInfo.parameterType); if ( paramInfo.parameterName != null ) { System.out.print(" " + paramInfo.parameterName); } } } System.out.println(") = " + procInfo.procedureNumber); } } :} ; procedure_defs ::= procedure_def:proc {: RESULT = new Vector(); RESULT.addElement(proc); :} | procedure_defs:procs procedure_def:proc {: procs.addElement(proc); RESULT = procs; :} ; // // A procedure definition consists of the return type, the procedure identifier, // one parameter type and the procedure number to assign. Nothing more. // // Please note that RFC 1832 is fishy: it talks about multiple parameters // separated by commas, but at least rpcgen for ONC/RPC protocol version 2 // does only support a single parameter. Also, it forgets about "void" // being valid and opaque being invalid -- see Sun's rpcgen source. Sigh. // // Due to "popular request" (SPQR, anyone?!) the grammar has been updated // to cope with multiple parameters. // procedure_def ::= type_specifier_incl_specials:resultType IDENTIFIER:procId LPAREN argument_list:args RPAREN EQUAL value:procNumber SEMICOLON {: RESULT = new JrpcgenProcedureInfo(procId, procNumber, resultType, args); // // NOTE: we can not add the identifier for the procedure number // to the list of global identifiers yet, as we do not know the // version number. This has to be fixed after the embracing // version definition was parsed in toto. // :} ; // // We either accept only one "void" argument, indicating that there are // no arguments to a particular remote procedure at all, or a list of // arguments, either named or unnamed. // argument_list ::= VOID {: RESULT = null; // special case, allows fast tests :} | argument_list_no_void:args {: RESULT = args; // just pass through int size = RESULT.size(); // // All arguments, which are unnamed so far will now get // default names. // for ( int idx = 0; idx < size; ++idx ) { JrpcgenParamInfo paraminfo = (JrpcgenParamInfo) RESULT.elementAt(idx); if ( paraminfo.parameterName == null ) { paraminfo.parameterName = "arg" + (idx + 1); } } :} ; // // Accept a list of arguments, either named or unnamed. // argument_list_no_void ::= type_specifier_incl_string:paramType {: RESULT = new Vector(); RESULT.addElement(new JrpcgenParamInfo(paramType, null)); :} | type_specifier_incl_string:paramType IDENTIFIER:paramName {: RESULT = new Vector(); RESULT.addElement(new JrpcgenParamInfo(paramType, paramName)); :} | argument_list:args COMMA type_specifier_incl_string:paramType {: RESULT = args; RESULT.addElement(new JrpcgenParamInfo(paramType, null)); :} | argument_list:args COMMA type_specifier_incl_string:paramType IDENTIFIER:paramName {: RESULT = args; RESULT.addElement(new JrpcgenParamInfo(paramType, paramName)); :} ; type_specifier_incl_specials ::= VOID {: RESULT = "void"; :} | type_specifier_incl_string:type {: RESULT = type; :} ; type_specifier_incl_string ::= STRING {: RESULT = "String"; :} | type_specifier:type {: RESULT = type; :} ; // // A type specifier can be either a base type ("builtin" type), an // enumeration type, structure, union or typedef'd type. The "string" // type specifier is insane, as it does not accept size specification. // Somehow the whole x-file grammar is brain-damaged: it was never // carefully designed but instead grew like the pest. // type_specifier ::= IDENTIFIER:id {: RESULT = id; :} | BOOL {: RESULT = "boolean"; :} | // As the Java language and the [Jk...]VM can only handle signed // integers of various sizes, we ignore the UNSIGNED token completely. UNSIGNED int_types:type {: RESULT = type; :} | int_types:type {: RESULT = type; :} | // Per default unsigned without any following type maps to "int" UNSIGNED {: RESULT = "int"; :} | FLOAT {: RESULT = "float"; :} | DOUBLE {: RESULT = "double"; :} | QUADRUPLE // FIXME! {: RESULT = "double"; :} | ENUM IDENTIFIER:id {: RESULT = id; :} | STRUCT IDENTIFIER:id {: RESULT = id; :} | UNION IDENTIFIER:id {: RESULT = id; :} ; // // // declarations ::= declaration:decl SEMICOLON {: RESULT = new Vector(); RESULT.addElement(decl); :} | declarations:decls declaration:decl SEMICOLON {: decls.addElement(decl); RESULT = decls; :} ; declaration ::= OPAQUE IDENTIFIER:id LBRACKET value:size RBRACKET {: // Note: we use the pseudo-type "opaque" here to distinguish // real byte arrays from fake byte (char) arrays. RESULT = new JrpcgenDeclaration( id, "opaque", JrpcgenDeclaration.FIXEDVECTOR, size); :} | OPAQUE IDENTIFIER:id LANGLE value:size RANGLE {: // Note: we use the pseudo-type "opaque" here to distinguish // real byte arrays from fake byte (char) arrays. RESULT = new JrpcgenDeclaration( id, "opaque", JrpcgenDeclaration.DYNAMICVECTOR, size); :} | OPAQUE IDENTIFIER:id LANGLE RANGLE {: // Note: we use the pseudo-type "opaque" here to distinguish // real byte arrays from fake byte (char) arrays. RESULT = new JrpcgenDeclaration( id, "opaque", JrpcgenDeclaration.DYNAMICVECTOR, null); :} | STRING IDENTIFIER:id LANGLE value:size RANGLE {: RESULT = new JrpcgenDeclaration( id, "String", JrpcgenDeclaration.DYNAMICVECTOR, size); :} | STRING IDENTIFIER:id LANGLE RANGLE {: RESULT = new JrpcgenDeclaration( id, "String", JrpcgenDeclaration.DYNAMICVECTOR, null); :} | type_specifier:type IDENTIFIER:id {: RESULT = new JrpcgenDeclaration(id, type); :} | type_specifier:type IDENTIFIER:id LBRACKET value:size RBRACKET {: RESULT = new JrpcgenDeclaration( id, type, JrpcgenDeclaration.FIXEDVECTOR, size); :} | type_specifier:type IDENTIFIER:id LANGLE value:size RANGLE {: RESULT = new JrpcgenDeclaration( id, type, JrpcgenDeclaration.DYNAMICVECTOR, size); :} | type_specifier:type IDENTIFIER:id LANGLE RANGLE {: RESULT = new JrpcgenDeclaration( id, type, JrpcgenDeclaration.DYNAMICVECTOR, null); :} | type_specifier:type STAR IDENTIFIER:id {: RESULT = new JrpcgenDeclaration( id, type, JrpcgenDeclaration.INDIRECTION, null); :} | VOID {: RESULT = new JrpcgenDeclaration(null, "void"); :} ; // // There are quite some integer types defined in RFC 1832, with additional // types used by Sun's rpcgen. // int_types ::= SHORT INT {: RESULT = "short"; :} | SHORT {: RESULT = "short"; :} | // // Note that we try to retain compatibility to most C compilers by // mapping a "C char" to a "Java byte". // CHAR {: RESULT = "byte"; :} | INT {: RESULT = "int"; :} | LONG INT {: RESULT = "int"; :} | LONG {: RESULT = "int"; :} | HYPER {: RESULT = "long"; :} | HYPER INT {: RESULT = "long"; :} ; // // "Values" can be either integer literals or identifiers, which then can // be (hopefully) resolved to an integer literal. // value ::= INTEGER_LITERAL:lit {: RESULT = lit; :} | IDENTIFIER:id {: RESULT = id; :} ; /* End of file JrpcgenParser.cup */ remotetea-1.0.7/src/org/acplt/oncrpc/apps/jrpcgen/JrpcgenParser.java0000644005374700003410000034134210335177600026601 0ustar piccainstrumentation //---------------------------------------------------- // The following code was generated by CUP v0.10k TUM Edition 20050516 // Fri Nov 11 20:53:50 CET 2005 //---------------------------------------------------- package org.acplt.oncrpc.apps.jrpcgen; import org.acplt.oncrpc.apps.jrpcgen.cup_runtime.*; import java.util.Vector; /** CUP v0.10k TUM Edition 20050516 generated parser. * @version Fri Nov 11 20:53:50 CET 2005 */ public class JrpcgenParser extends org.acplt.oncrpc.apps.jrpcgen.cup_runtime.lr_parser { /** Default constructor. */ public JrpcgenParser() {super();} /** Constructor which sets the default scanner. */ public JrpcgenParser(org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Scanner s) {super(s);} /** Production table. */ protected static final short _production_table[][] = unpackFromStrings(new String[] { "\000\120\000\002\002\004\000\002\003\004\000\002\021" + "\002\000\002\021\003\000\002\020\003\000\002\020\004" + "\000\002\004\002\000\002\004\003\000\002\005\003\000" + "\002\005\004\000\002\006\003\000\002\006\003\000\002" + "\006\003\000\002\006\003\000\002\006\003\000\002\007" + "\007\000\002\010\010\000\002\011\003\000\002\011\005" + "\000\002\012\003\000\002\012\005\000\002\013\010\000" + "\002\014\014\000\002\015\003\000\002\015\004\000\002" + "\016\005\000\002\016\007\000\002\016\006\000\002\017" + "\005\000\002\022\012\000\002\023\003\000\002\023\004" + "\000\002\024\012\000\002\025\003\000\002\025\004\000" + "\002\026\012\000\002\027\003\000\002\027\003\000\002" + "\030\003\000\002\030\004\000\002\030\005\000\002\030" + "\006\000\002\031\003\000\002\031\003\000\002\032\003" + "\000\002\032\003\000\002\033\003\000\002\033\003\000" + "\002\033\004\000\002\033\003\000\002\033\003\000\002" + "\033\003\000\002\033\003\000\002\033\003\000\002\033" + "\004\000\002\033\004\000\002\033\004\000\002\034\004" + "\000\002\034\005\000\002\035\007\000\002\035\007\000" + "\002\035\006\000\002\035\007\000\002\035\006\000\002" + "\035\004\000\002\035\007\000\002\035\007\000\002\035" + "\006\000\002\035\005\000\002\035\003\000\002\036\004" + "\000\002\036\003\000\002\036\003\000\002\036\003\000" + "\002\036\004\000\002\036\003\000\002\036\003\000\002" + "\036\004\000\002\037\003\000\002\037\003" }); /** Access to production table. */ public short[][] production_table() {return _production_table;} /** Parse-action table. */ protected static final short[][] _action_table = unpackFromStrings(new String[] { "\000\235\000\020\002\ufffb\021\ufffb\023\021\024\014\042" + "\004\045\011\046\007\001\002\000\004\051\225\001\002" + "\000\020\002\ufff5\021\ufff5\023\ufff5\024\ufff5\042\ufff5\045" + "\ufff5\046\ufff5\001\002\000\020\002\ufff9\021\ufff9\023\ufff9" + "\024\ufff9\042\ufff9\045\ufff9\046\ufff9\001\002\000\004\051" + "\201\001\002\000\020\002\ufff7\021\ufff7\023\ufff7\024\ufff7" + "\042\ufff7\045\ufff7\046\ufff7\001\002\000\004\051\170\001" + "\002\000\020\002\ufff3\021\ufff3\023\ufff3\024\ufff3\042\ufff3" + "\045\ufff3\046\ufff3\001\002\000\020\002\ufff6\021\ufff6\023" + "\ufff6\024\ufff6\042\ufff6\045\ufff6\046\ufff6\001\002\000\044" + "\030\137\031\056\032\072\033\055\034\052\035\065\036" + "\062\037\077\040\073\041\074\042\067\043\136\044\135" + "\045\054\046\066\047\060\051\057\001\002\000\020\002" + "\ufff4\021\ufff4\023\ufff4\024\ufff4\042\ufff4\045\ufff4\046\ufff4" + "\001\002\000\006\002\uffff\021\035\001\002\000\020\002" + "\ufffa\021\ufffa\023\021\024\014\042\004\045\011\046\007" + "\001\002\000\004\002\030\001\002\000\004\051\022\001" + "\002\000\004\007\023\001\002\000\006\050\024\051\025" + "\001\002\000\016\004\uffb3\005\uffb3\006\uffb3\014\uffb3\016" + "\uffb3\020\uffb3\001\002\000\016\004\uffb2\005\uffb2\006\uffb2" + "\014\uffb2\016\uffb2\020\uffb2\001\002\000\004\004\027\001" + "\002\000\020\002\ufff2\021\ufff2\023\ufff2\024\ufff2\042\ufff2" + "\045\ufff2\046\ufff2\001\002\000\004\002\001\001\002\000" + "\020\002\ufff8\021\ufff8\023\ufff8\024\ufff8\042\ufff8\045\ufff8" + "\046\ufff8\001\002\000\006\002\ufffe\021\035\001\002\000" + "\006\002\ufffd\021\ufffd\001\002\000\004\002\000\001\002" + "\000\004\051\036\001\002\000\004\013\037\001\002\000" + "\004\022\041\001\002\000\006\014\uffe3\022\uffe3\001\002" + "\000\004\051\050\001\002\000\006\014\044\022\041\001" + "\002\000\006\014\uffe2\022\uffe2\001\002\000\004\007\045" + "\001\002\000\006\050\024\051\025\001\002\000\004\004" + "\047\001\002\000\006\002\uffe4\021\uffe4\001\002\000\004" + "\013\051\001\002\000\042\030\075\031\056\032\072\033" + "\055\034\052\035\065\036\062\037\077\040\073\041\074" + "\042\067\044\061\045\054\046\066\047\060\051\057\001" + "\002\000\014\005\uffb6\010\uffb6\012\uffb6\033\131\051\uffb6" + "\001\002\000\010\005\uffd4\012\uffd4\051\uffd4\001\002\000" + "\004\051\130\001\002\000\012\005\uffb8\010\uffb8\012\uffb8" + "\051\uffb8\001\002\000\012\005\uffb9\010\uffb9\012\uffb9\051" + "\uffb9\001\002\000\012\005\uffd3\010\uffd3\012\uffd3\051\uffd3" + "\001\002\000\024\005\uffcf\010\uffcf\012\uffcf\031\056\032" + "\072\033\055\034\052\035\065\051\uffcf\001\002\000\010" + "\005\uffd5\012\uffd5\051\uffd5\001\002\000\012\005\uffce\010" + "\uffce\012\uffce\051\uffce\001\002\000\044\014\122\030\075" + "\031\056\032\072\033\055\034\052\035\065\036\062\037" + "\077\040\073\041\074\042\067\044\061\045\054\046\066" + "\047\060\051\057\001\002\000\044\014\uffe0\030\uffe0\031" + "\uffe0\032\uffe0\033\uffe0\034\uffe0\035\uffe0\036\uffe0\037\uffe0" + "\040\uffe0\041\uffe0\042\uffe0\044\uffe0\045\uffe0\046\uffe0\047" + "\uffe0\051\uffe0\001\002\000\014\005\uffb5\010\uffb5\012\uffb5" + "\033\121\051\uffb5\001\002\000\004\051\120\001\002\000" + "\004\051\117\001\002\000\004\051\uffd6\001\002\000\004" + "\051\101\001\002\000\014\005\uffba\010\uffba\012\uffba\033" + "\100\051\uffba\001\002\000\012\005\uffcc\010\uffcc\012\uffcc" + "\051\uffcc\001\002\000\012\005\uffd2\010\uffd2\012\uffd2\051" + "\uffd2\001\002\000\004\051\uffd7\001\002\000\012\005\uffd0" + "\010\uffd0\012\uffd0\051\uffd0\001\002\000\012\005\uffcd\010" + "\uffcd\012\uffcd\051\uffcd\001\002\000\012\005\uffbb\010\uffbb" + "\012\uffbb\051\uffbb\001\002\000\004\011\102\001\002\000" + "\042\030\105\031\056\032\072\033\055\034\052\035\065" + "\036\062\037\077\040\073\041\074\042\067\044\061\045" + "\054\046\066\047\060\051\057\001\002\000\010\005\uffdb" + "\012\uffdb\051\116\001\002\000\006\005\uffdc\012\uffdc\001" + "\002\000\006\005\uffdd\012\uffdd\001\002\000\006\005\107" + "\012\110\001\002\000\040\031\056\032\072\033\055\034" + "\052\035\065\036\062\037\077\040\073\041\074\042\067" + "\044\061\045\054\046\066\047\060\051\057\001\002\000" + "\004\007\111\001\002\000\006\050\024\051\025\001\002" + "\000\004\004\113\001\002\000\044\014\uffde\030\uffde\031" + "\uffde\032\uffde\033\uffde\034\uffde\035\uffde\036\uffde\037\uffde" + "\040\uffde\041\uffde\042\uffde\044\uffde\045\uffde\046\uffde\047" + "\uffde\051\uffde\001\002\000\010\005\uffd9\012\uffd9\051\115" + "\001\002\000\006\005\uffd8\012\uffd8\001\002\000\006\005" + "\uffda\012\uffda\001\002\000\012\005\uffcb\010\uffcb\012\uffcb" + "\051\uffcb\001\002\000\012\005\uffc9\010\uffc9\012\uffc9\051" + "\uffc9\001\002\000\012\005\uffb4\010\uffb4\012\uffb4\051\uffb4" + "\001\002\000\004\007\124\001\002\000\044\014\uffdf\030" + "\uffdf\031\uffdf\032\uffdf\033\uffdf\034\uffdf\035\uffdf\036\uffdf" + "\037\uffdf\040\uffdf\041\uffdf\042\uffdf\044\uffdf\045\uffdf\046" + "\uffdf\047\uffdf\051\uffdf\001\002\000\006\050\024\051\025" + "\001\002\000\004\004\126\001\002\000\006\014\uffe1\022" + "\uffe1\001\002\000\012\005\uffd1\010\uffd1\012\uffd1\051\uffd1" + "\001\002\000\012\005\uffca\010\uffca\012\uffca\051\uffca\001" + "\002\000\012\005\uffb7\010\uffb7\012\uffb7\051\uffb7\001\002" + "\000\006\002\ufffc\021\ufffc\001\002\000\004\004\167\001" + "\002\000\006\010\155\051\156\001\002\000\004\051\150" + "\001\002\000\004\051\140\001\002\000\006\004\uffbc\012" + "\uffbc\001\002\000\006\015\142\017\141\001\002\000\010" + "\020\145\050\024\051\025\001\002\000\006\050\024\051" + "\025\001\002\000\004\016\144\001\002\000\006\004\uffc6" + "\012\uffc6\001\002\000\006\004\uffc4\012\uffc4\001\002\000" + "\004\020\147\001\002\000\006\004\uffc5\012\uffc5\001\002" + "\000\004\017\151\001\002\000\010\020\152\050\024\051" + "\025\001\002\000\006\004\uffc2\012\uffc2\001\002\000\004" + "\020\154\001\002\000\006\004\uffc3\012\uffc3\001\002\000" + "\004\051\166\001\002\000\012\004\uffc1\012\uffc1\015\160" + "\017\157\001\002\000\010\020\163\050\024\051\025\001" + "\002\000\006\050\024\051\025\001\002\000\004\016\162" + "\001\002\000\006\004\uffc0\012\uffc0\001\002\000\006\004" + "\uffbe\012\uffbe\001\002\000\004\020\165\001\002\000\006" + "\004\uffbf\012\uffbf\001\002\000\006\004\uffbd\012\uffbd\001" + "\002\000\020\002\uffe5\021\uffe5\023\uffe5\024\uffe5\042\uffe5" + "\045\uffe5\046\uffe5\001\002\000\004\013\171\001\002\000" + "\044\030\137\031\056\032\072\033\055\034\052\035\065" + "\036\062\037\077\040\073\041\074\042\067\043\136\044" + "\135\045\054\046\066\047\060\051\057\001\002\000\004" + "\004\200\001\002\000\046\014\175\030\137\031\056\032" + "\072\033\055\034\052\035\065\036\062\037\077\040\073" + "\041\074\042\067\043\136\044\135\045\054\046\066\047" + "\060\051\057\001\002\000\004\004\177\001\002\000\004" + "\004\176\001\002\000\020\002\uffec\021\uffec\023\uffec\024" + "\uffec\042\uffec\045\uffec\046\uffec\001\002\000\046\014\uffc7" + "\030\uffc7\031\uffc7\032\uffc7\033\uffc7\034\uffc7\035\uffc7\036" + "\uffc7\037\uffc7\040\uffc7\041\uffc7\042\uffc7\043\uffc7\044\uffc7" + "\045\uffc7\046\uffc7\047\uffc7\051\uffc7\001\002\000\046\014" + "\uffc8\030\uffc8\031\uffc8\032\uffc8\033\uffc8\034\uffc8\035\uffc8" + "\036\uffc8\037\uffc8\040\uffc8\041\uffc8\042\uffc8\043\uffc8\044" + "\uffc8\045\uffc8\046\uffc8\047\uffc8\051\uffc8\001\002\000\004" + "\025\202\001\002\000\004\011\203\001\002\000\044\030" + "\137\031\056\032\072\033\055\034\052\035\065\036\062" + "\037\077\040\073\041\074\042\067\043\136\044\135\045" + "\054\046\066\047\060\051\057\001\002\000\004\012\205" + "\001\002\000\004\013\206\001\002\000\006\026\212\027" + "\207\001\002\000\004\006\222\001\002\000\010\014\uffea" + "\026\uffea\027\uffea\001\002\000\010\014\220\026\212\027" + "\207\001\002\000\006\050\024\051\025\001\002\000\004" + "\006\214\001\002\000\052\014\uffe8\026\uffe8\027\uffe8\030" + "\137\031\056\032\072\033\055\034\052\035\065\036\062" + "\037\077\040\073\041\074\042\067\043\136\044\135\045" + "\054\046\066\047\060\051\057\001\002\000\004\004\216" + "\001\002\000\010\014\uffe7\026\uffe7\027\uffe7\001\002\000" + "\010\014\uffe9\026\uffe9\027\uffe9\001\002\000\004\004\221" + "\001\002\000\020\002\uffeb\021\uffeb\023\uffeb\024\uffeb\042" + "\uffeb\045\uffeb\046\uffeb\001\002\000\044\030\137\031\056" + "\032\072\033\055\034\052\035\065\036\062\037\077\040" + "\073\041\074\042\067\043\136\044\135\045\054\046\066" + "\047\060\051\057\001\002\000\004\004\224\001\002\000" + "\010\014\uffe6\026\uffe6\027\uffe6\001\002\000\004\013\226" + "\001\002\000\004\051\231\001\002\000\006\005\ufff0\014" + "\ufff0\001\002\000\006\005\234\014\235\001\002\000\010" + "\005\uffee\007\232\014\uffee\001\002\000\006\050\024\051" + "\025\001\002\000\006\005\uffed\014\uffed\001\002\000\004" + "\051\231\001\002\000\004\004\236\001\002\000\020\002" + "\ufff1\021\ufff1\023\ufff1\024\ufff1\042\ufff1\045\ufff1\046\ufff1" + "\001\002\000\006\005\uffef\014\uffef\001\002" }); /** Access to parse-action table. */ public short[][] action_table() {return _action_table;} /** reduce_goto table. */ protected static final short[][] _reduce_table = unpackFromStrings(new String[] { "\000\235\000\024\003\017\004\015\005\016\006\005\007" + "\007\010\012\013\004\014\014\017\011\001\001\000\002" + "\001\001\000\002\001\001\000\002\001\001\000\002\001" + "\001\000\002\001\001\000\002\001\001\000\002\001\001" + "\000\002\001\001\000\010\033\133\035\132\036\075\001" + "\001\000\002\001\001\000\010\020\031\021\033\022\032" + "\001\001\000\016\006\030\007\007\010\012\013\004\014" + "\014\017\011\001\001\000\002\001\001\000\002\001\001" + "\000\002\001\001\000\004\037\025\001\001\000\002\001" + "\001\000\002\001\001\000\002\001\001\000\002\001\001" + "\000\002\001\001\000\002\001\001\000\004\022\131\001" + "\001\000\002\001\001\000\002\001\001\000\002\001\001" + "\000\002\001\001\000\006\023\041\024\037\001\001\000" + "\002\001\001\000\002\001\001\000\004\024\042\001\001" + "\000\002\001\001\000\002\001\001\000\004\037\045\001" + "\001\000\002\001\001\000\002\001\001\000\002\001\001" + "\000\016\025\062\026\063\031\070\032\067\033\052\036" + "\075\001\001\000\002\001\001\000\002\001\001\000\002" + "\001\001\000\002\001\001\000\002\001\001\000\002\001" + "\001\000\004\036\126\001\001\000\002\001\001\000\002" + "\001\001\000\014\026\122\031\070\032\067\033\052\036" + "\075\001\001\000\002\001\001\000\002\001\001\000\002" + "\001\001\000\002\001\001\000\002\001\001\000\002\001" + "\001\000\002\001\001\000\002\001\001\000\002\001\001" + "\000\002\001\001\000\002\001\001\000\002\001\001\000" + "\002\001\001\000\002\001\001\000\014\027\105\030\103" + "\032\102\033\052\036\075\001\001\000\002\001\001\000" + "\002\001\001\000\002\001\001\000\002\001\001\000\010" + "\032\113\033\052\036\075\001\001\000\002\001\001\000" + "\004\037\111\001\001\000\002\001\001\000\002\001\001" + "\000\002\001\001\000\002\001\001\000\002\001\001\000" + "\002\001\001\000\002\001\001\000\002\001\001\000\002" + "\001\001\000\002\001\001\000\004\037\124\001\001\000" + "\002\001\001\000\002\001\001\000\002\001\001\000\002" + "\001\001\000\002\001\001\000\002\001\001\000\002\001" + "\001\000\002\001\001\000\002\001\001\000\002\001\001" + "\000\002\001\001\000\002\001\001\000\004\037\145\001" + "\001\000\004\037\142\001\001\000\002\001\001\000\002" + "\001\001\000\002\001\001\000\002\001\001\000\002\001" + "\001\000\002\001\001\000\004\037\152\001\001\000\002" + "\001\001\000\002\001\001\000\002\001\001\000\002\001" + "\001\000\002\001\001\000\004\037\163\001\001\000\004" + "\037\160\001\001\000\002\001\001\000\002\001\001\000" + "\002\001\001\000\002\001\001\000\002\001\001\000\002" + "\001\001\000\002\001\001\000\002\001\001\000\012\033" + "\133\034\172\035\171\036\075\001\001\000\002\001\001" + "\000\010\033\133\035\173\036\075\001\001\000\002\001" + "\001\000\002\001\001\000\002\001\001\000\002\001\001" + "\000\002\001\001\000\002\001\001\000\002\001\001\000" + "\010\033\133\035\203\036\075\001\001\000\002\001\001" + "\000\002\001\001\000\006\015\210\016\207\001\001\000" + "\002\001\001\000\002\001\001\000\004\016\216\001\001" + "\000\004\037\212\001\001\000\002\001\001\000\010\033" + "\133\035\214\036\075\001\001\000\002\001\001\000\002" + "\001\001\000\002\001\001\000\002\001\001\000\002\001" + "\001\000\010\033\133\035\222\036\075\001\001\000\002" + "\001\001\000\002\001\001\000\002\001\001\000\006\011" + "\227\012\226\001\001\000\002\001\001\000\002\001\001" + "\000\002\001\001\000\004\037\232\001\001\000\002\001" + "\001\000\004\012\236\001\001\000\002\001\001\000\002" + "\001\001\000\002\001\001" }); /** Access to reduce_goto table. */ public short[][] reduce_table() {return _reduce_table;} /** Instance of action encapsulation class. */ protected CUP$JrpcgenParser$actions action_obj; /** Action encapsulation object initializer. */ protected void init_actions() { action_obj = new CUP$JrpcgenParser$actions(this); } /** Invoke a user supplied parse action. */ public org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol do_action( int act_num, org.acplt.oncrpc.apps.jrpcgen.cup_runtime.lr_parser parser, java.util.Stack stack, int top) throws java.lang.Exception { /* call code in generated class */ return action_obj.CUP$JrpcgenParser$do_action(act_num, parser, stack, top); } /** Indicates start state. */ public int start_state() {return 0;} /** Indicates start production. */ public int start_production() {return 0;} /** EOF Symbol index. */ public int EOF_sym() {return 0;} /** error Symbol index. */ public int error_sym() {return 1;} public void report_error(String message, Object info) { StringBuffer msg = new StringBuffer("jrpcgen: error"); if (info instanceof Symbol) { Symbol s = (Symbol) info; msg.append(" in line "); msg.append(s.left); } msg.append(": "); msg.append(message); System.out.println(msg); throw(new JrpcgenParserException()); } public void report_error(String message, int line) { StringBuffer msg = new StringBuffer("jrpcgen: error in line "); msg.append(line); msg.append(": "); msg.append(message); System.out.println(msg); throw(new JrpcgenParserException()); } public void syntax_error(Symbol cur_token) { StringBuffer msg = new StringBuffer("jrpcgen: syntax error in line "); msg.append(cur_token.left); System.out.println(msg); throw(new JrpcgenParserException()); } public void report_fatal_error(String message, Object info) { report_error(message, info); throw(new RuntimeException("Fatal Syntax Error")); } } /** Cup generated class to encapsulate user supplied action code.*/ class CUP$JrpcgenParser$actions { private final JrpcgenParser parser; /** Constructor */ CUP$JrpcgenParser$actions(JrpcgenParser parser) { this.parser = parser; } /** Method with the actual generated action code. */ public final org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol CUP$JrpcgenParser$do_action( int CUP$JrpcgenParser$act_num, org.acplt.oncrpc.apps.jrpcgen.cup_runtime.lr_parser CUP$JrpcgenParser$parser, java.util.Stack CUP$JrpcgenParser$stack, int CUP$JrpcgenParser$top) throws java.lang.Exception { /* Symbol object for return from actions */ org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol CUP$JrpcgenParser$result; /* select the action based on the action number */ switch (CUP$JrpcgenParser$act_num) { /*. . . . . . . . . . . . . . . . . . . .*/ case 79: // value ::= IDENTIFIER { String RESULT = null; int idleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left; int idright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right; String id = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).value; RESULT = id; CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(29/*value*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 78: // value ::= INTEGER_LITERAL { String RESULT = null; int litleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left; int litright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right; String lit = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).value; RESULT = lit; CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(29/*value*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 77: // int_types ::= HYPER INT { String RESULT = null; RESULT = "long"; CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(28/*int_types*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 76: // int_types ::= HYPER { String RESULT = null; RESULT = "long"; CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(28/*int_types*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 75: // int_types ::= LONG { String RESULT = null; RESULT = "int"; CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(28/*int_types*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 74: // int_types ::= LONG INT { String RESULT = null; RESULT = "int"; CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(28/*int_types*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 73: // int_types ::= INT { String RESULT = null; RESULT = "int"; CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(28/*int_types*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 72: // int_types ::= CHAR { String RESULT = null; RESULT = "byte"; CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(28/*int_types*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 71: // int_types ::= SHORT { String RESULT = null; RESULT = "short"; CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(28/*int_types*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 70: // int_types ::= SHORT INT { String RESULT = null; RESULT = "short"; CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(28/*int_types*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 69: // declaration ::= VOID { JrpcgenDeclaration RESULT = null; RESULT = new JrpcgenDeclaration(null, "void"); CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(27/*declaration*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 68: // declaration ::= type_specifier STAR IDENTIFIER { JrpcgenDeclaration RESULT = null; int typeleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-2)).left; int typeright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-2)).right; String type = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-2)).value; int idleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left; int idright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right; String id = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).value; RESULT = new JrpcgenDeclaration( id, type, JrpcgenDeclaration.INDIRECTION, null); CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(27/*declaration*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-2)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 67: // declaration ::= type_specifier IDENTIFIER LANGLE RANGLE { JrpcgenDeclaration RESULT = null; int typeleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-3)).left; int typeright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-3)).right; String type = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-3)).value; int idleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-2)).left; int idright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-2)).right; String id = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-2)).value; RESULT = new JrpcgenDeclaration( id, type, JrpcgenDeclaration.DYNAMICVECTOR, null); CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(27/*declaration*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-3)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 66: // declaration ::= type_specifier IDENTIFIER LANGLE value RANGLE { JrpcgenDeclaration RESULT = null; int typeleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-4)).left; int typeright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-4)).right; String type = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-4)).value; int idleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-3)).left; int idright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-3)).right; String id = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-3)).value; int sizeleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).left; int sizeright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).right; String size = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).value; RESULT = new JrpcgenDeclaration( id, type, JrpcgenDeclaration.DYNAMICVECTOR, size); CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(27/*declaration*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-4)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 65: // declaration ::= type_specifier IDENTIFIER LBRACKET value RBRACKET { JrpcgenDeclaration RESULT = null; int typeleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-4)).left; int typeright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-4)).right; String type = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-4)).value; int idleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-3)).left; int idright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-3)).right; String id = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-3)).value; int sizeleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).left; int sizeright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).right; String size = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).value; RESULT = new JrpcgenDeclaration( id, type, JrpcgenDeclaration.FIXEDVECTOR, size); CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(27/*declaration*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-4)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 64: // declaration ::= type_specifier IDENTIFIER { JrpcgenDeclaration RESULT = null; int typeleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).left; int typeright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).right; String type = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).value; int idleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left; int idright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right; String id = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).value; RESULT = new JrpcgenDeclaration(id, type); CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(27/*declaration*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 63: // declaration ::= STRING IDENTIFIER LANGLE RANGLE { JrpcgenDeclaration RESULT = null; int idleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-2)).left; int idright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-2)).right; String id = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-2)).value; RESULT = new JrpcgenDeclaration( id, "String", JrpcgenDeclaration.DYNAMICVECTOR, null); CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(27/*declaration*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-3)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 62: // declaration ::= STRING IDENTIFIER LANGLE value RANGLE { JrpcgenDeclaration RESULT = null; int idleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-3)).left; int idright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-3)).right; String id = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-3)).value; int sizeleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).left; int sizeright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).right; String size = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).value; RESULT = new JrpcgenDeclaration( id, "String", JrpcgenDeclaration.DYNAMICVECTOR, size); CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(27/*declaration*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-4)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 61: // declaration ::= OPAQUE IDENTIFIER LANGLE RANGLE { JrpcgenDeclaration RESULT = null; int idleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-2)).left; int idright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-2)).right; String id = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-2)).value; // Note: we use the pseudo-type "opaque" here to distinguish // real byte arrays from fake byte (char) arrays. RESULT = new JrpcgenDeclaration( id, "opaque", JrpcgenDeclaration.DYNAMICVECTOR, null); CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(27/*declaration*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-3)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 60: // declaration ::= OPAQUE IDENTIFIER LANGLE value RANGLE { JrpcgenDeclaration RESULT = null; int idleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-3)).left; int idright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-3)).right; String id = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-3)).value; int sizeleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).left; int sizeright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).right; String size = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).value; // Note: we use the pseudo-type "opaque" here to distinguish // real byte arrays from fake byte (char) arrays. RESULT = new JrpcgenDeclaration( id, "opaque", JrpcgenDeclaration.DYNAMICVECTOR, size); CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(27/*declaration*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-4)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 59: // declaration ::= OPAQUE IDENTIFIER LBRACKET value RBRACKET { JrpcgenDeclaration RESULT = null; int idleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-3)).left; int idright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-3)).right; String id = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-3)).value; int sizeleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).left; int sizeright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).right; String size = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).value; // Note: we use the pseudo-type "opaque" here to distinguish // real byte arrays from fake byte (char) arrays. RESULT = new JrpcgenDeclaration( id, "opaque", JrpcgenDeclaration.FIXEDVECTOR, size); CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(27/*declaration*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-4)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 58: // declarations ::= declarations declaration SEMICOLON { Vector RESULT = null; int declsleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-2)).left; int declsright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-2)).right; Vector decls = (Vector)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-2)).value; int declleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).left; int declright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).right; JrpcgenDeclaration decl = (JrpcgenDeclaration)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).value; decls.addElement(decl); RESULT = decls; CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(26/*declarations*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-2)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 57: // declarations ::= declaration SEMICOLON { Vector RESULT = null; int declleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).left; int declright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).right; JrpcgenDeclaration decl = (JrpcgenDeclaration)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).value; RESULT = new Vector(); RESULT.addElement(decl); CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(26/*declarations*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 56: // type_specifier ::= UNION IDENTIFIER { String RESULT = null; int idleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left; int idright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right; String id = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).value; RESULT = id; CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(25/*type_specifier*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 55: // type_specifier ::= STRUCT IDENTIFIER { String RESULT = null; int idleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left; int idright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right; String id = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).value; RESULT = id; CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(25/*type_specifier*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 54: // type_specifier ::= ENUM IDENTIFIER { String RESULT = null; int idleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left; int idright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right; String id = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).value; RESULT = id; CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(25/*type_specifier*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 53: // type_specifier ::= QUADRUPLE { String RESULT = null; RESULT = "double"; CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(25/*type_specifier*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 52: // type_specifier ::= DOUBLE { String RESULT = null; RESULT = "double"; CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(25/*type_specifier*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 51: // type_specifier ::= FLOAT { String RESULT = null; RESULT = "float"; CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(25/*type_specifier*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 50: // type_specifier ::= UNSIGNED { String RESULT = null; RESULT = "int"; CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(25/*type_specifier*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 49: // type_specifier ::= int_types { String RESULT = null; int typeleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left; int typeright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right; String type = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).value; RESULT = type; CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(25/*type_specifier*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 48: // type_specifier ::= UNSIGNED int_types { String RESULT = null; int typeleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left; int typeright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right; String type = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).value; RESULT = type; CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(25/*type_specifier*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 47: // type_specifier ::= BOOL { String RESULT = null; RESULT = "boolean"; CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(25/*type_specifier*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 46: // type_specifier ::= IDENTIFIER { String RESULT = null; int idleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left; int idright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right; String id = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).value; RESULT = id; CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(25/*type_specifier*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 45: // type_specifier_incl_string ::= type_specifier { String RESULT = null; int typeleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left; int typeright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right; String type = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).value; RESULT = type; CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(24/*type_specifier_incl_string*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 44: // type_specifier_incl_string ::= STRING { String RESULT = null; RESULT = "String"; CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(24/*type_specifier_incl_string*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 43: // type_specifier_incl_specials ::= type_specifier_incl_string { String RESULT = null; int typeleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left; int typeright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right; String type = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).value; RESULT = type; CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(23/*type_specifier_incl_specials*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 42: // type_specifier_incl_specials ::= VOID { String RESULT = null; RESULT = "void"; CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(23/*type_specifier_incl_specials*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 41: // argument_list_no_void ::= argument_list COMMA type_specifier_incl_string IDENTIFIER { Vector RESULT = null; int argsleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-3)).left; int argsright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-3)).right; Vector args = (Vector)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-3)).value; int paramTypeleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).left; int paramTyperight = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).right; String paramType = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).value; int paramNameleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left; int paramNameright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right; String paramName = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).value; RESULT = args; RESULT.addElement(new JrpcgenParamInfo(paramType, paramName)); CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(22/*argument_list_no_void*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-3)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 40: // argument_list_no_void ::= argument_list COMMA type_specifier_incl_string { Vector RESULT = null; int argsleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-2)).left; int argsright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-2)).right; Vector args = (Vector)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-2)).value; int paramTypeleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left; int paramTyperight = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right; String paramType = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).value; RESULT = args; RESULT.addElement(new JrpcgenParamInfo(paramType, null)); CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(22/*argument_list_no_void*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-2)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 39: // argument_list_no_void ::= type_specifier_incl_string IDENTIFIER { Vector RESULT = null; int paramTypeleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).left; int paramTyperight = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).right; String paramType = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).value; int paramNameleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left; int paramNameright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right; String paramName = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).value; RESULT = new Vector(); RESULT.addElement(new JrpcgenParamInfo(paramType, paramName)); CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(22/*argument_list_no_void*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 38: // argument_list_no_void ::= type_specifier_incl_string { Vector RESULT = null; int paramTypeleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left; int paramTyperight = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right; String paramType = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).value; RESULT = new Vector(); RESULT.addElement(new JrpcgenParamInfo(paramType, null)); CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(22/*argument_list_no_void*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 37: // argument_list ::= argument_list_no_void { Vector RESULT = null; int argsleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left; int argsright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right; Vector args = (Vector)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).value; RESULT = args; // just pass through int size = RESULT.size(); // // All arguments, which are unnamed so far will now get // default names. // for ( int idx = 0; idx < size; ++idx ) { JrpcgenParamInfo paraminfo = (JrpcgenParamInfo) RESULT.elementAt(idx); if ( paraminfo.parameterName == null ) { paraminfo.parameterName = "arg" + (idx + 1); } } CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(21/*argument_list*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 36: // argument_list ::= VOID { Vector RESULT = null; RESULT = null; // special case, allows fast tests CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(21/*argument_list*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 35: // procedure_def ::= type_specifier_incl_specials IDENTIFIER LPAREN argument_list RPAREN EQUAL value SEMICOLON { JrpcgenProcedureInfo RESULT = null; int resultTypeleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-7)).left; int resultTyperight = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-7)).right; String resultType = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-7)).value; int procIdleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-6)).left; int procIdright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-6)).right; String procId = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-6)).value; int argsleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-4)).left; int argsright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-4)).right; Vector args = (Vector)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-4)).value; int procNumberleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).left; int procNumberright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).right; String procNumber = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).value; RESULT = new JrpcgenProcedureInfo(procId, procNumber, resultType, args); // // NOTE: we can not add the identifier for the procedure number // to the list of global identifiers yet, as we do not know the // version number. This has to be fixed after the embracing // version definition was parsed in toto. // CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(20/*procedure_def*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-7)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 34: // procedure_defs ::= procedure_defs procedure_def { Vector RESULT = null; int procsleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).left; int procsright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).right; Vector procs = (Vector)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).value; int procleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left; int procright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right; JrpcgenProcedureInfo proc = (JrpcgenProcedureInfo)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).value; procs.addElement(proc); RESULT = procs; CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(19/*procedure_defs*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 33: // procedure_defs ::= procedure_def { Vector RESULT = null; int procleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left; int procright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right; JrpcgenProcedureInfo proc = (JrpcgenProcedureInfo)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).value; RESULT = new Vector(); RESULT.addElement(proc); CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(19/*procedure_defs*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 32: // version_def ::= VERSION IDENTIFIER LBRACE procedure_defs RBRACE EQUAL value SEMICOLON { JrpcgenVersionInfo RESULT = null; int versIdleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-6)).left; int versIdright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-6)).right; String versId = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-6)).value; int procsleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-4)).left; int procsright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-4)).right; Vector procs = (Vector)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-4)).value; int versNumberleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).left; int versNumberright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).right; String versNumber = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).value; JrpcgenConst vers = new JrpcgenConst(versId, versNumber, jrpcgen.baseClassname); RESULT = new JrpcgenVersionInfo(versId, versNumber, procs); if ( jrpcgen.globalIdentifiers.put(versId, vers) != null ) { parser.report_error("version identifier \"" + versId + "\" already defined", versIdleft); } versNumber = vers.resolveValue(); if ( versNumber == null ) { parser.report_error("Can not resolve version identifier \"" + versId + "\" to integer literal", versNumberleft); } // // We also need to fix up the procedure identifiers by appending // the version number. // int size = procs.size(); for ( int idx = 0; idx < size; ++idx ) { JrpcgenProcedureInfo procInfo = (JrpcgenProcedureInfo) procs.elementAt(idx); procInfo.procedureId += "_" + versNumber; JrpcgenConst proc = new JrpcgenConst(procInfo.procedureId, procInfo.procedureNumber, jrpcgen.baseClassname); if ( jrpcgen.globalIdentifiers.put(procInfo.procedureId, proc) != null ) { // FIXME line number parser.report_error("procedure identifier \"" + procInfo.procedureId + "\" already defined", 0); } } if ( jrpcgen.debug ) { System.out.println("VERSION " + versId + " = " + versNumber); for ( int idx = 0; idx < size; ++idx ) { JrpcgenProcedureInfo procInfo = (JrpcgenProcedureInfo) procs.elementAt(idx); System.out.print("PROCEDURE " + procInfo.resultType + " " + procInfo.procedureId + "("); if ( procInfo.parameters == null ) { System.out.print("void"); } else { for ( int pidx = 0; pidx < procInfo.parameters.size(); ++pidx ) { JrpcgenParamInfo paramInfo = (JrpcgenParamInfo) procInfo.parameters.elementAt(pidx); if ( pidx > 0 ) { System.out.print(","); } System.out.print(paramInfo.parameterType); if ( paramInfo.parameterName != null ) { System.out.print(" " + paramInfo.parameterName); } } } System.out.println(") = " + procInfo.procedureNumber); } } CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(18/*version_def*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-7)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 31: // version_defs ::= version_defs version_def { Vector RESULT = null; int versionsleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).left; int versionsright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).right; Vector versions = (Vector)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).value; int versionleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left; int versionright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right; JrpcgenVersionInfo version = (JrpcgenVersionInfo)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).value; versions.addElement(version); RESULT = versions; CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(17/*version_defs*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 30: // version_defs ::= version_def { Vector RESULT = null; int versionleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left; int versionright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right; JrpcgenVersionInfo version = (JrpcgenVersionInfo)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).value; RESULT = new Vector(); RESULT.addElement(version); CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(17/*version_defs*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 29: // program_def ::= PROGRAM IDENTIFIER LBRACE version_defs RBRACE EQUAL value SEMICOLON { JrpcgenProgramInfo RESULT = null; int progIdleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-6)).left; int progIdright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-6)).right; String progId = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-6)).value; int versionsleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-4)).left; int versionsright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-4)).right; Vector versions = (Vector)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-4)).value; int progNumberleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).left; int progNumberright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).right; String progNumber = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).value; JrpcgenConst prog = new JrpcgenConst(progId, progNumber, jrpcgen.baseClassname); RESULT = new JrpcgenProgramInfo(progId, progNumber, versions); if ( jrpcgen.globalIdentifiers.put(progId, prog) != null ) { parser.report_error("program identifier \"" + progId + "\" already defined", progIdleft); } if ( jrpcgen.debug ) { System.out.println("PROGRAM " + progId + " = " + progNumber); } CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(16/*program_def*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-7)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 28: // typedef_def ::= TYPEDEF declaration SEMICOLON { Object RESULT = null; int declleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).left; int declright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).right; JrpcgenDeclaration decl = (JrpcgenDeclaration)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).value; if ( jrpcgen.globalIdentifiers.put(decl.identifier, decl) != null ) { parser.report_error("typedef identifier \"" + decl.identifier + "\" already defined", declleft); } if ( jrpcgen.debug ) { System.out.print("TYPEDEF "); decl.dump(); } CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(13/*typedef_def*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-2)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 27: // union_case ::= DEFAULT COLON declaration SEMICOLON { JrpcgenUnionArm RESULT = null; int elementleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).left; int elementright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).right; JrpcgenDeclaration element = (JrpcgenDeclaration)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).value; RESULT = new JrpcgenUnionArm(null, element); CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(12/*union_case*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-3)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 26: // union_case ::= CASE value COLON declaration SEMICOLON { JrpcgenUnionArm RESULT = null; int valleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-3)).left; int valright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-3)).right; String val = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-3)).value; int elementleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).left; int elementright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).right; JrpcgenDeclaration element = (JrpcgenDeclaration)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).value; RESULT = new JrpcgenUnionArm(val, element); CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(12/*union_case*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-4)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 25: // union_case ::= CASE value COLON { JrpcgenUnionArm RESULT = null; int valleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).left; int valright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).right; String val = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).value; RESULT = new JrpcgenUnionArm(val, null); CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(12/*union_case*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-2)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 24: // union_cases ::= union_cases union_case { Vector RESULT = null; int armsleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).left; int armsright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).right; Vector arms = (Vector)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).value; int armleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left; int armright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right; JrpcgenUnionArm arm = (JrpcgenUnionArm)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).value; arms.addElement(arm); RESULT = arms; CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(11/*union_cases*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 23: // union_cases ::= union_case { Vector RESULT = null; int armleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left; int armright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right; JrpcgenUnionArm arm = (JrpcgenUnionArm)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).value; RESULT = new Vector(); RESULT.addElement(arm); CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(11/*union_cases*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 22: // union_def ::= UNION IDENTIFIER SWITCH LPAREN declaration RPAREN LBRACE union_cases RBRACE SEMICOLON { Object RESULT = null; int idleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-8)).left; int idright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-8)).right; String id = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-8)).value; int descrimleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-5)).left; int descrimright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-5)).right; JrpcgenDeclaration descrim = (JrpcgenDeclaration)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-5)).value; int elementsleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-2)).left; int elementsright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-2)).right; Vector elements = (Vector)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-2)).value; JrpcgenUnion uni = new JrpcgenUnion(id, descrim, elements); if ( jrpcgen.globalIdentifiers.put(id, uni) != null ) { parser.report_error("union identifier \"" + id + "\" already defined", idleft); } if ( jrpcgen.debug ) { uni.dump(); } CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(10/*union_def*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-9)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 21: // struct_def ::= STRUCT IDENTIFIER LBRACE declarations RBRACE SEMICOLON { Object RESULT = null; int idleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-4)).left; int idright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-4)).right; String id = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-4)).value; int elementsleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-2)).left; int elementsright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-2)).right; Vector elements = (Vector)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-2)).value; JrpcgenStruct strct = new JrpcgenStruct(id, elements); if ( jrpcgen.globalIdentifiers.put(id, strct) != null ) { parser.report_error("struct identifier \"" + id + "\" already defined", idleft); } if ( jrpcgen.debug ) { strct.dump(); } CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(9/*struct_def*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-5)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 20: // enum_element ::= IDENTIFIER EQUAL value { JrpcgenConst RESULT = null; int idleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-2)).left; int idright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-2)).right; String id = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-2)).value; int valleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left; int valright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right; String val = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).value; RESULT = new JrpcgenConst(id, val); if ( jrpcgen.globalIdentifiers.put(id, RESULT) != null ) { parser.report_error("identifier \"" + id + "\" already defined", idleft); } CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(8/*enum_element*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-2)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 19: // enum_element ::= IDENTIFIER { JrpcgenConst RESULT = null; int idleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left; int idright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right; String id = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).value; // // We don't know yet the value, so we don't specify one. The // value will be fixed up when the production for the complete // enumeration triggers. // RESULT = new JrpcgenConst(id, null); if ( jrpcgen.globalIdentifiers.put(id, RESULT) != null ) { parser.report_error("identifier \"" + id + "\" already defined", idleft); } CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(8/*enum_element*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 18: // enum_elements ::= enum_elements COMMA enum_element { Vector RESULT = null; int elementsleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-2)).left; int elementsright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-2)).right; Vector elements = (Vector)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-2)).value; int elleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left; int elright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right; JrpcgenConst el = (JrpcgenConst)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).value; // // If no specific value has been assigned to this element of // an enumeration, increment value of previous element and // assign the new value to this element. BTW -- we let the // Java compiler do the calculation, so references to // other constants by name are valid. // if ( el.value == null ) { el.value = ((JrpcgenConst)elements.elementAt(elements.size() - 1)).value + "+1"; } elements.addElement(el); RESULT = elements; CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(7/*enum_elements*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-2)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 17: // enum_elements ::= enum_element { Vector RESULT = null; int elleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left; int elright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right; JrpcgenConst el = (JrpcgenConst)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).value; // // If no specific value has been assigned to this element of // an enumeration, assign zero by default. // if ( el.value == null ) { el.value = "0"; } RESULT = new Vector(); RESULT.addElement(el); CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(7/*enum_elements*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 16: // enum_def ::= ENUM IDENTIFIER LBRACE enum_elements RBRACE SEMICOLON { Object RESULT = null; int idleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-4)).left; int idright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-4)).right; String id = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-4)).value; int elementsleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-2)).left; int elementsright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-2)).right; Vector elements = (Vector)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-2)).value; // // Fix up enclosure of enumeration elements, so we can later // use a full qualified identifier. // int size = elements.size(); for ( int idx = 0; idx < size; ++idx ) { JrpcgenConst c = (JrpcgenConst) elements.elementAt(idx); c.enclosure = id; } JrpcgenEnum type = new JrpcgenEnum(id, elements); if ( jrpcgen.globalIdentifiers.put(id, type) != null ) { parser.report_error("enum identifier \"" + id + "\" already defined", idleft); } if ( jrpcgen.debug ) { type.dump(); } CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(6/*enum_def*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-5)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 15: // constant_def ::= CONST IDENTIFIER EQUAL value SEMICOLON { Object RESULT = null; int idleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-3)).left; int idright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-3)).right; String id = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-3)).value; int valueleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).left; int valueright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).right; String value = (String)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).value; JrpcgenConst type = new JrpcgenConst(id, value, jrpcgen.baseClassname); if ( jrpcgen.globalIdentifiers.put(id, type) != null ) { parser.report_error("const identifier \"" + id + "\" already defined", idleft); } if ( jrpcgen.debug ) { System.out.print("CONST "); type.dump(); System.out.println(); } CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(5/*constant_def*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-4)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 14: // definition ::= typedef_def { Object RESULT = null; CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(4/*definition*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 13: // definition ::= union_def { Object RESULT = null; CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(4/*definition*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 12: // definition ::= struct_def { Object RESULT = null; CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(4/*definition*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 11: // definition ::= enum_def { Object RESULT = null; CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(4/*definition*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 10: // definition ::= constant_def { Object RESULT = null; CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(4/*definition*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 9: // definitions ::= definitions definition { Object RESULT = null; CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(3/*definitions*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 8: // definitions ::= definition { Object RESULT = null; CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(3/*definitions*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 7: // definitions_opt ::= definitions { Object RESULT = null; CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(2/*definitions_opt*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 6: // definitions_opt ::= { Object RESULT = null; CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(2/*definitions_opt*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 5: // program_defs ::= program_defs program_def { Vector RESULT = null; int progDefsleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).left; int progDefsright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).right; Vector progDefs = (Vector)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).value; int progDefleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left; int progDefright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right; JrpcgenProgramInfo progDef = (JrpcgenProgramInfo)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).value; progDefs.addElement(progDef); RESULT = progDefs; CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(14/*program_defs*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 4: // program_defs ::= program_def { Vector RESULT = null; int progDefleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left; int progDefright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right; JrpcgenProgramInfo progDef = (JrpcgenProgramInfo)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).value; RESULT = new Vector(); RESULT.addElement(progDef); CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(14/*program_defs*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 3: // program_defs_opt ::= program_defs { Object RESULT = null; int progDefsleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left; int progDefsright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right; Vector progDefs = (Vector)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).value; jrpcgen.programInfos = progDefs; CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(15/*program_defs_opt*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 2: // program_defs_opt ::= { Object RESULT = null; jrpcgen.programInfos = new Vector(); CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(15/*program_defs_opt*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 1: // compilation_unit ::= definitions_opt program_defs_opt { Object RESULT = null; CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(1/*compilation_unit*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } return CUP$JrpcgenParser$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 0: // $START ::= compilation_unit EOF { Object RESULT = null; int start_valleft = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).left; int start_valright = ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).right; Object start_val = (Object)((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol) CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).value; RESULT = start_val; CUP$JrpcgenParser$result = new org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol(0/*$START*/, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-1)).left, ((org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol)CUP$JrpcgenParser$stack.elementAt(CUP$JrpcgenParser$top-0)).right, RESULT); } /* ACCEPT */ CUP$JrpcgenParser$parser.done_parsing(); return CUP$JrpcgenParser$result; /* . . . . . .*/ default: throw new Exception( "Invalid action number found in internal parse table"); } } } remotetea-1.0.7/src/org/acplt/oncrpc/apps/jrpcgen/JrpcgenParserException.java0000644005374700003410000000312007716406402030451 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/apps/jrpcgen/JrpcgenParserException.java,v 1.1.1.1 2003/08/13 12:03:46 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc.apps.jrpcgen; /** * The JrpcgenParserException class represents a parser * exception indicating to abort parsing the x-file. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:46 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ class JrpcgenParserException extends RuntimeException { /** * Constructs a JrpcgenParserException with no detail message. */ public JrpcgenParserException() { super(); } } // End of JrpcgenParserException.java remotetea-1.0.7/src/org/acplt/oncrpc/apps/jrpcgen/JrpcgenProcedureInfo.java0000644005374700003410000000570407716652732030125 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/apps/jrpcgen/JrpcgenProcedureInfo.java,v 1.3 2003/08/14 11:26:50 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc.apps.jrpcgen; import java.util.Vector; /** * The JrpcgenProcedureInfo class contains information about a * specific version of an ONC/RPC program as defined in an rpcgen "x"-file. * * @version $Revision: 1.3 $ $Date: 2003/08/14 11:26:50 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ class JrpcgenProcedureInfo { /** * Procedure number assigned to the procedure of a particular verions of * an ONC/RPC program. This attribute contains either an integer literal * or an identifier (which must resolve to an integer). */ public String procedureNumber; /** * Identifier assigned to the procedure number of an a particular * procedure of a particular version of an ONC/RPC program. */ public String procedureId; /** * Type specifier of the result returned by the remote procedure. */ public String resultType; /** * Parameter(s) to the remote procedure. */ public Vector parameters; /** * Constructs a new JrpcgenProcedureInfo object containing * information about a programs' version and a set of procedures * defined by this program version. * * @param procedureId Identifier assigned to the procedure of a particular * version of an ONC/RPC program. * @param procedureNumber Procedure number assigned to remote procedure. * @param resultType Type specifier of result returned by remote procedure. * @param parameters Type specifier of parameter to the remote procedure. */ public JrpcgenProcedureInfo(String procedureId, String procedureNumber, String resultType, Vector parameters) { this.procedureId = procedureId; this.procedureNumber = procedureNumber; this.resultType = resultType; this.parameters = parameters; } } // End of JrpcgenProcedureInfo.javaremotetea-1.0.7/src/org/acplt/oncrpc/apps/jrpcgen/JrpcgenProgramInfo.java0000644005374700003410000000640307716406402027570 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/apps/jrpcgen/JrpcgenProgramInfo.java,v 1.1.1.1 2003/08/13 12:03:46 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc.apps.jrpcgen; import java.util.Vector; import java.io.PrintWriter; /** * The JrpcgenProgramInfo class contains information about a * single ONC/RPC program as defined in an rpcgen "x"-file. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:46 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ class JrpcgenProgramInfo { /** * Program number assigned to an ONC/RPC program. This attribute contains * either an integer literal or an identifier (which must resolve to an * integer). */ public String programNumber; /** * Identifier assigned to the program number of an ONC/RPC program. */ public String programId; /** * Set of versions specified for a particular ONC/RPC program. * The elements in the set are of class {@link JrpcgenVersionInfo}. */ public Vector versions; /** * Construct a new JrpcgenProgramInfo object containing the * programs's identifier and number, as well as the versions defined * for this particular ONC/RPC program. * * @param programId Identifier defined for this ONC/RPC program. * @param programNumber Program number assigned to this ONC/RPC program. * @param versions Vector of versions defined for this ONC/RPC program. */ public JrpcgenProgramInfo(String programId, String programNumber, Vector versions) { this.programId = programId; this.programNumber = programNumber; this.versions = versions; } /** * Generates source code to define all constants belonging to this * program. * * @param out PrintWriter to send source code to. */ public void dumpConstants(PrintWriter out) { out.println(" /* ONC/RPC program number definition */"); out.println(" public final static int " + programId + " = " + programNumber + ";"); int size = versions.size(); for ( int idx = 0; idx < size; ++idx ) { JrpcgenVersionInfo version = (JrpcgenVersionInfo) versions.elementAt(idx); version.dumpConstants(out); } } } // End of JrpcgenProgramInfo.java remotetea-1.0.7/src/org/acplt/oncrpc/apps/jrpcgen/JrpcgenSHA.java0000644005374700003410000002012407716406404025756 0ustar piccainstrumentation/* SHA.java -- Class implementing the SHA-1 algorithm as specified in [1]. Copyright (C) 1999, 2000 Free Software Foundation, Inc. This file is part of GNU Classpath. GNU Classpath is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GNU Classpath is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Classpath; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. As a special exception, if you link this library with other files to produce an executable, this library does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ /* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/apps/jrpcgen/JrpcgenSHA.java,v 1.1.1.1 2003/08/13 12:03:47 haraldalbrecht Exp $ * * The original file gnu.java.security.provider.SHA.java has been * renamed to reflect the many chances made to it. While the processing * kernel has not been changed, the overall interface has. Especially * some methods have been added which can hash several kinds of data * types, as needed by the jrpcgen protocol compiler. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:47 $ $State: Exp $ $Locker: $ * @author GNU Classpath */ package org.acplt.oncrpc.apps.jrpcgen; /** * This class implements the SHA-1 algorithm as described in * "Federal Information Processing Standards Publication 180-1: * Specifications for the Secure Hash Standard. April 17, 1995." */ public class JrpcgenSHA { /** * Create a new SHA-1 hashing object. */ public JrpcgenSHA() { reset(); } /** * Update the hash using a single byte (8 bits). * * @param b Byte to hash. */ public void update(byte b) { int i = (int)bytecount % 64; int shift = (3 - i % 4) * 8; int idx = i / 4; // if you could index ints, this would be: W[idx][shift/8] = b W[idx] = (W[idx] & ~(0xff << shift)) | ((b & 0xff) << shift); // if we've filled up a block, then process it if ( (++bytecount) % 64 == 0 ) { process(); } } /** * Update the hash using a short integer (16 bits). * * @param s Short integer to hash. */ public void update(short s) { update((byte) s); update((byte)(s >>> 8)); } /** * Update the hash using an integer (32 bits). * * @param i Integer to hash. */ public void update(int i) { update((byte) i); update((byte)(i >>> 8)); update((byte)(i >>> 16)); update((byte)(i >>> 24)); } /** * Update the hash using a string. * * @param s String to hash. */ public void update(String s) { int len = s.length(); for ( int idx = 0; idx < len; ++idx ) { update((short)s.charAt(idx)); } } /** * Reset the hashing engine to start hashing another set of innocent * bytes. */ public void reset() { bytecount = 0; // magic numbers from [1] p. 10. H0 = 0x67452301; H1 = 0xefcdab89; H2 = 0x98badcfe; H3 = 0x10325476; H4 = 0xc3d2e1f0; } /** * Retrieve the digest (that is, informally spoken, the "hash value"). * * @return digest as a series of 20 bytes (80 bits). */ public byte[] getDigest() { long bitcount = bytecount * 8; update((byte)0x80); // 10000000 in binary; the start of the padding // add the rest of the padding to fill this block out, but leave 8 // bytes to put in the original bytecount while ( (int)bytecount % 64 != 56 ) { update((byte)0); } // add the length of the original, unpadded block to the end of // the padding W[14] = (int)(bitcount >>> 32); W[15] = (int)bitcount; bytecount += 8; // digest the fully padded block process(); byte[] result = new byte[] { (byte)(H0 >>> 24), (byte)(H0 >>> 16), (byte)(H0 >>> 8), (byte) H0, (byte)(H1 >>> 24), (byte)(H1 >>> 16), (byte)(H1 >>> 8), (byte) H1, (byte)(H2 >>> 24), (byte)(H2 >>> 16), (byte)(H2 >>> 8), (byte) H2, (byte)(H3 >>> 24), (byte)(H3 >>> 16), (byte)(H3 >>> 8), (byte) H3, (byte)(H4 >>> 24), (byte)(H4 >>> 16), (byte)(H4 >>> 8), (byte) H4 }; reset(); return result; } /** * Return first 64 bits of hash digest for use as a serialization * UID, etc. * * @return hash digest with only 64 bit size. */ public long getHash() { byte [] hash = getDigest(); return ( ((long)hash[0]) & 0xFF) + ((((long)hash[1]) & 0xFF) << 8) + ((((long)hash[2]) & 0xFF) << 16) + ((((long)hash[3]) & 0xFF) << 24) + ((((long)hash[4]) & 0xFF) << 32) + ((((long)hash[5]) & 0xFF) << 40) + ((((long)hash[6]) & 0xFF) << 48) + ((((long)hash[7]) & 0xFF) << 56); } /** * Process a single block. This is pretty much copied verbatim from * "Federal Information Processing Standards Publication 180-1: * Specifications for the Secure Hash Standard. April 17, 1995.", * pp. 9, 10. */ private void process() { for ( int t = 16; t < 80; ++t ) { int Wt = W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16]; W[t] = Wt << 1 | Wt >>> 31; } int A = H0; int B = H1; int C = H2; int D = H3; int E = H4; for ( int t = 0; t < 20; ++t ) { int TEMP = (A << 5 | A >>> 27) // S^5(A) + ((B & C) | (~B & D)) // f_t(B,C,D) + E + W[t] + 0x5a827999; // K_t E = D; D = C; C = B << 30 | B >>> 2; // S^30(B) B = A; A = TEMP; } for ( int t = 20; t < 40; ++t ) { int TEMP = (A << 5 | A >>> 27) // S^5(A) + (B ^ C ^ D) // f_t(B,C,D) + E + W[t] + 0x6ed9eba1; // K_t E = D; D = C; C = B << 30 | B >>> 2; // S^30(B) B = A; A = TEMP; } for ( int t = 40; t < 60; ++t ) { int TEMP = (A << 5 | A >>> 27) // S^5(A) + (B & C | B & D | C & D) // f_t(B,C,D) + E + W[t] + 0x8f1bbcdc; // K_t E = D; D = C; C = B << 30 | B >>> 2; // S^30(B) B = A; A = TEMP; } for ( int t = 60; t < 80; ++t ) { int TEMP = (A << 5 | A >>> 27) // S^5(A) + (B ^ C ^ D) // f_t(B,C,D) + E + W[t] + 0xca62c1d6; // K_t E = D; D = C; C = B << 30 | B >>> 2; // S^30(B) B = A; A = TEMP; } H0 += A; H1 += B; H2 += C; H3 += D; H4 += E; // Reset W by clearing it. for ( int t = 0; t < 80; ++t ) { W[t] = 0; } } /** * Work buffer for calculating the hash. */ private final int W[] = new int[80]; private long bytecount; private int H0; private int H1; private int H2; private int H3; private int H4; } // End of JrpcgenSHA.java remotetea-1.0.7/src/org/acplt/oncrpc/apps/jrpcgen/JrpcgenScanner.flex0000644005374700003410000001361107716406404026754 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/apps/jrpcgen/JrpcgenScanner.flex,v 1.1.1.1 2003/08/13 12:03:47 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * To compile into java code use: * java -jar JFlex.jar JrpcgenScanner.flex */ package org.acplt.oncrpc.apps.jrpcgen; import org.acplt.oncrpc.apps.jrpcgen.cup_runtime.*; %% %class JrpcgenScanner %unicode // Do not use %cup directive here as this causes JFlex to create a parser // class which tries to always implement java_cup.runtime.Scanner... //%cup %implements org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Scanner %function next_token %type org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol %eofval{ return new Symbol(JrpcgenSymbols.EOF); %eofval} %eofclose %line %column %{ StringBuffer string = new StringBuffer(); private Symbol symbol(int type) { return new Symbol(type, yyline+1, yycolumn+1); } private Symbol symbol(int type, Object value) { return new Symbol(type, yyline+1, yycolumn+1, value); } /* assumes correct representation of a long value for specified radix in String s */ private long parseLong(String s, int radix) { int max = s.length(); long result = 0; long digit; for (int i = 0; i < max; i++) { digit = Character.digit(yy_buffer[i],radix); result*= radix; result+= digit; } return result; } %} // // Macros // LINE_TERMINATOR=\r|\n|\r\n INPUT_CHARACTER=[^\r\n] WHITE_SPACE={LINE_TERMINATOR}|[ \t\f] JAVA_COMMENT={MULTILINE_COMMENT}|{EOL_COMMENT} MULTILINE_COMMENT = "/*"{COMMENT_CONTENT}\*+"/" EOL_COMMENT="//".*{LINE_TERMINATOR} COMMENT_CONTENT=([^*]|\*+[^*/])* IDENTIFIER=[a-zA-Z_][a-zA-Z0-9_]* INTEGER_LITERAL = [1-9][0-9]*|"0x"[0-9A-Fa-f]+|0[0-7]+|0|-[1-9][0-9]* %% { // keywords "program" { return symbol(JrpcgenSymbols.PROGRAM); } "version" { return symbol(JrpcgenSymbols.VERSION); } "PROGRAM" { return symbol(JrpcgenSymbols.PROGRAM); } "VERSION" { return symbol(JrpcgenSymbols.VERSION); } "const" { return symbol(JrpcgenSymbols.CONST); } "typedef" { return symbol(JrpcgenSymbols.TYPEDEF); } "switch" { return symbol(JrpcgenSymbols.SWITCH); } "case" { return symbol(JrpcgenSymbols.CASE); } "default" { return symbol(JrpcgenSymbols.DEFAULT); } // data types "void" { return symbol(JrpcgenSymbols.VOID); } "char" { return symbol(JrpcgenSymbols.CHAR); } "short" { return symbol(JrpcgenSymbols.SHORT); } "u_short" { return symbol(JrpcgenSymbols.SHORT); } "int" { return symbol(JrpcgenSymbols.INT); } "u_int" { return symbol(JrpcgenSymbols.INT); } "long" { return symbol(JrpcgenSymbols.LONG); } "u_long" { return symbol(JrpcgenSymbols.LONG); } "hyper" { return symbol(JrpcgenSymbols.HYPER); } "float" { return symbol(JrpcgenSymbols.FLOAT); } "double" { return symbol(JrpcgenSymbols.DOUBLE); } "quadruple" { return symbol(JrpcgenSymbols.QUADRUPLE); } "bool" { return symbol(JrpcgenSymbols.BOOL); } "bool_t" { return symbol(JrpcgenSymbols.BOOL); } "enum" { return symbol(JrpcgenSymbols.ENUM); } "opaque" { return symbol(JrpcgenSymbols.OPAQUE); } "string" { return symbol(JrpcgenSymbols.STRING); } "struct" { return symbol(JrpcgenSymbols.STRUCT); } "union" { return symbol(JrpcgenSymbols.UNION); } // modifiers "unsigned" { return symbol(JrpcgenSymbols.UNSIGNED); } // separators ";" { return symbol(JrpcgenSymbols.SEMICOLON); } "," { return symbol(JrpcgenSymbols.COMMA); } ":" { return symbol(JrpcgenSymbols.COLON); } "=" { return symbol(JrpcgenSymbols.EQUAL); } "*" { return symbol(JrpcgenSymbols.STAR); } "(" { return symbol(JrpcgenSymbols.LPAREN); } ")" { return symbol(JrpcgenSymbols.RPAREN); } "{" { return symbol(JrpcgenSymbols.LBRACE); } "}" { return symbol(JrpcgenSymbols.RBRACE); } "[" { return symbol(JrpcgenSymbols.LBRACKET); } "]" { return symbol(JrpcgenSymbols.RBRACKET); } "<" { return symbol(JrpcgenSymbols.LANGLE); } ">" { return symbol(JrpcgenSymbols.RANGLE); } // integer literals {INTEGER_LITERAL} { return symbol(JrpcgenSymbols.INTEGER_LITERAL, yytext()); } // identifiers: simple return the identifier as the value of the symbol. {IDENTIFIER} { return symbol(JrpcgenSymbols.IDENTIFIER, yytext()); } // white space & comment handling {WHITE_SPACE} { /* ignore */ } {JAVA_COMMENT} { /* ignore */ } } . | \n { throw new Error("Illegal character \"" + yytext() + "\""); } /* End of file JrpcgenScanner.flex */ remotetea-1.0.7/src/org/acplt/oncrpc/apps/jrpcgen/JrpcgenScanner.java0000644005374700003410000006111007716406404026734 0ustar piccainstrumentation/* The following code was generated by JFlex 1.2.2 on 20.10.00 09:36 */ /* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/apps/jrpcgen/JrpcgenScanner.java,v 1.1.1.1 2003/08/13 12:03:47 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * To compile into java code use: * java -jar JFlex.jar JrpcgenScanner.flex */ package org.acplt.oncrpc.apps.jrpcgen; import org.acplt.oncrpc.apps.jrpcgen.cup_runtime.*; /** * This class is a scanner generated by * JFlex 1.2.2 * on 20.10.00 09:36 from the specification file * file:/G:/JAVA/SRC/ORG/ACPLT/ONCRPC/APPS/JRPCGEN/JrpcgenScanner.flex */ class JrpcgenScanner implements org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Scanner { /** this character denotes the end of file */ final public static int YYEOF = -1; /** lexical states */ final public static int YYINITIAL = 0; /** * Translates characters to character classes */ final private static String yycmap_packed = "\11\0\1\3\1\2\1\0\1\3\1\1\22\0\1\3\7\0\1\63"+ "\1\64\1\5\1\0\1\60\1\14\1\0\1\4\1\7\7\13\2\10"+ "\1\61\1\57\1\71\1\62\1\72\2\0\1\34\3\12\1\37\1\12"+ "\1\33\1\6\1\41\3\6\1\35\1\42\1\32\1\30\1\6\1\31"+ "\1\40\2\6\1\36\4\6\1\67\1\0\1\70\1\0\1\54\1\0"+ "\1\21\1\55\1\43\1\46\1\24\1\47\1\20\1\51\1\26\2\6"+ "\1\53\1\22\1\27\1\17\1\15\1\56\1\16\1\25\1\44\1\52"+ "\1\23\1\50\1\11\1\45\1\6\1\65\1\0\1\66\uff82\0"; /** * Translates characters to character classes */ final private static char [] yycmap = yy_unpack_cmap(yycmap_packed); /** * Translates a state to a row index in the transition table */ final private static int yy_rowMap [] = { 0, 59, 118, 59, 177, 59, 236, 295, 354, 413, 472, 531, 590, 649, 708, 767, 826, 885, 944, 1003, 1062, 1121, 1180, 1239, 1298, 1357, 1416, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 1475, 1534, 1593, 1652, 1711, 1770, 1829, 1888, 1947, 2006, 2065, 2124, 2183, 2242, 2301, 2360, 2419, 2478, 2537, 2596, 2655, 2714, 2773, 2832, 2891, 2950, 3009, 3068, 1475, 3127, 1652, 3186, 3245, 3304, 3363, 3422, 3481, 3540, 3599, 236, 3658, 3717, 3776, 3835, 3894, 3953, 4012, 4071, 4130, 4189, 4248, 4307, 4366, 4425, 4484, 4543, 4602, 4661, 236, 4720, 236, 4779, 4838, 4897, 4956, 5015, 5074, 5133, 236, 236, 5192, 5251, 5310, 5369, 5428, 5487, 5546, 236, 5605, 5664, 5723, 5782, 5841, 5900, 5959, 6018, 236, 6077, 6136, 236, 6195, 6254, 6313, 236, 236, 6372, 236, 6431, 6490, 6549, 236, 6608, 236, 236, 236, 6667, 6726, 6785, 236, 6844, 6903, 236, 6962, 236, 236, 236, 236, 7021, 7080, 236, 7139, 236 }; /** * The packed transition table of the DFA */ final private static String yy_packed = "\1\2\1\3\2\4\1\5\1\6\1\7\1\10\1\11"+ "\2\7\1\11\1\12\1\13\1\7\1\14\3\7\1\15"+ "\1\16\1\17\1\20\1\7\1\21\5\7\1\22\4\7"+ "\1\23\1\24\1\7\1\25\1\26\1\7\1\27\1\30"+ "\1\31\1\7\1\32\1\33\1\34\1\35\1\36\1\37"+ "\1\40\1\41\1\42\1\43\1\44\1\45\1\46\1\47"+ "\75\0\1\4\74\0\1\50\1\51\73\0\6\7\1\0"+ "\42\7\23\0\1\52\1\0\1\53\1\0\1\52\66\0"+ "\2\11\2\0\1\11\67\0\1\11\2\0\1\11\65\0"+ "\6\7\1\0\1\7\1\54\40\7\22\0\6\7\1\0"+ "\1\55\41\7\22\0\6\7\1\0\2\7\1\56\4\7"+ "\1\57\32\7\22\0\6\7\1\0\12\7\1\60\27\7"+ "\22\0\6\7\1\0\27\7\1\61\3\7\1\62\1\63"+ "\5\7\22\0\6\7\1\0\12\7\1\64\27\7\22\0"+ "\6\7\1\0\14\7\1\65\25\7\22\0\6\7\1\0"+ "\22\7\1\66\17\7\22\0\6\7\1\0\2\7\1\67"+ "\1\7\1\70\27\7\1\71\5\7\22\0\6\7\1\0"+ "\30\7\1\72\11\7\22\0\6\7\1\0\2\7\1\73"+ "\4\7\1\74\32\7\22\0\6\7\1\0\36\7\1\75"+ "\3\7\22\0\6\7\1\0\30\7\1\76\11\7\22\0"+ "\6\7\1\0\12\7\1\77\24\7\1\100\2\7\22\0"+ "\6\7\1\0\2\7\1\101\37\7\22\0\6\7\1\0"+ "\2\7\1\102\37\7\22\0\6\7\1\0\35\7\1\103"+ "\4\7\14\0\1\50\1\104\1\4\70\50\5\51\1\105"+ "\65\51\7\0\1\52\3\0\1\52\66\0\2\106\1\0"+ "\2\106\5\0\1\106\2\0\1\106\7\0\1\106\2\0"+ "\1\106\3\0\1\106\2\0\2\106\5\0\1\106\23\0"+ "\6\7\1\0\2\7\1\107\37\7\22\0\6\7\1\0"+ "\4\7\1\110\35\7\22\0\6\7\1\0\11\7\1\111"+ "\30\7\22\0\6\7\1\0\1\7\1\112\40\7\22\0"+ "\6\7\1\0\35\7\1\113\4\7\22\0\6\7\1\0"+ "\1\7\1\114\40\7\22\0\6\7\1\0\11\7\1\115"+ "\30\7\22\0\6\7\1\0\2\7\1\116\37\7\22\0"+ "\6\7\1\0\27\7\1\117\12\7\22\0\6\7\1\0"+ "\15\7\1\120\24\7\22\0\6\7\1\0\14\7\1\121"+ "\25\7\22\0\6\7\1\0\12\7\1\122\27\7\22\0"+ "\6\7\1\0\10\7\1\123\31\7\22\0\6\7\1\0"+ "\4\7\1\124\35\7\22\0\6\7\1\0\1\125\41\7"+ "\22\0\6\7\1\0\35\7\1\126\4\7\22\0\6\7"+ "\1\0\32\7\1\127\7\7\22\0\6\7\1\0\2\7"+ "\1\130\37\7\22\0\6\7\1\0\1\131\41\7\22\0"+ "\6\7\1\0\10\7\1\132\1\133\30\7\22\0\6\7"+ "\1\0\10\7\1\134\1\20\24\7\1\31\3\7\22\0"+ "\6\7\1\0\12\7\1\135\27\7\22\0\6\7\1\0"+ "\2\7\1\136\37\7\22\0\6\7\1\0\4\7\1\137"+ "\35\7\14\0\4\51\1\4\1\105\65\51\6\0\6\7"+ "\1\0\3\7\1\140\36\7\22\0\6\7\1\0\41\7"+ "\1\141\22\0\6\7\1\0\31\7\1\142\10\7\22\0"+ "\6\7\1\0\10\7\1\143\31\7\22\0\6\7\1\0"+ "\5\7\1\144\34\7\22\0\6\7\1\0\11\7\1\145"+ "\23\7\1\146\4\7\22\0\6\7\1\0\27\7\1\147"+ "\12\7\22\0\6\7\1\0\1\7\1\150\40\7\22\0"+ "\6\7\1\0\16\7\1\151\23\7\22\0\6\7\1\0"+ "\23\7\1\152\16\7\22\0\6\7\1\0\10\7\1\153"+ "\31\7\22\0\6\7\1\0\7\7\1\154\32\7\22\0"+ "\6\7\1\0\1\7\1\155\40\7\22\0\6\7\1\0"+ "\7\7\1\156\32\7\22\0\6\7\1\0\40\7\1\157"+ "\1\7\22\0\6\7\1\0\4\7\1\160\35\7\22\0"+ "\6\7\1\0\4\7\1\161\35\7\22\0\6\7\1\0"+ "\7\7\1\162\32\7\22\0\6\7\1\0\11\7\1\163"+ "\30\7\22\0\6\7\1\0\2\7\1\164\37\7\22\0"+ "\6\7\1\0\34\7\1\63\5\7\22\0\6\7\1\0"+ "\3\7\1\165\36\7\22\0\6\7\1\0\36\7\1\166"+ "\3\7\22\0\6\7\1\0\31\7\1\167\10\7\22\0"+ "\6\7\1\0\1\7\1\170\40\7\22\0\6\7\1\0"+ "\35\7\1\171\4\7\22\0\6\7\1\0\11\7\1\172"+ "\30\7\22\0\6\7\1\0\12\7\1\173\27\7\22\0"+ "\6\7\1\0\26\7\1\174\13\7\22\0\6\7\1\0"+ "\26\7\1\175\13\7\22\0\6\7\1\0\27\7\1\176"+ "\12\7\22\0\6\7\1\0\14\7\1\177\25\7\22\0"+ "\6\7\1\0\24\7\1\200\15\7\22\0\6\7\1\0"+ "\27\7\1\201\12\7\22\0\6\7\1\0\31\7\1\202"+ "\10\7\22\0\6\7\1\0\36\7\1\203\3\7\22\0"+ "\6\7\1\0\35\7\1\204\4\7\22\0\6\7\1\0"+ "\27\7\1\205\12\7\22\0\6\7\1\0\1\7\1\206"+ "\40\7\22\0\6\7\1\0\3\7\1\207\36\7\22\0"+ "\6\7\1\0\12\7\1\210\27\7\22\0\6\7\1\0"+ "\37\7\1\211\2\7\22\0\6\7\1\0\1\7\1\212"+ "\40\7\22\0\6\7\1\0\4\7\1\213\35\7\22\0"+ "\6\7\1\0\7\7\1\214\32\7\22\0\6\7\1\0"+ "\2\7\1\215\37\7\22\0\6\7\1\0\3\7\1\216"+ "\36\7\22\0\6\7\1\0\27\7\1\217\12\7\22\0"+ "\6\7\1\0\34\7\1\220\5\7\22\0\6\7\1\0"+ "\17\7\1\221\22\7\22\0\6\7\1\0\15\7\1\222"+ "\24\7\22\0\6\7\1\0\7\7\1\223\32\7\22\0"+ "\6\7\1\0\7\7\1\224\32\7\22\0\6\7\1\0"+ "\36\7\1\225\3\7\22\0\6\7\1\0\12\7\1\226"+ "\27\7\22\0\6\7\1\0\27\7\1\227\12\7\22\0"+ "\6\7\1\0\35\7\1\230\4\7\22\0\6\7\1\0"+ "\5\7\1\231\34\7\22\0\6\7\1\0\12\7\1\232"+ "\27\7\22\0\6\7\1\0\20\7\1\231\21\7\22\0"+ "\6\7\1\0\25\7\1\232\14\7\22\0\6\7\1\0"+ "\32\7\1\233\7\7\22\0\6\7\1\0\27\7\1\234"+ "\12\7\22\0\6\7\1\0\7\7\1\235\32\7\22\0"+ "\6\7\1\0\1\236\41\7\22\0\6\7\1\0\31\7"+ "\1\237\10\7\22\0\6\7\1\0\36\7\1\240\3\7"+ "\22\0\6\7\1\0\7\7\1\241\32\7\14\0"; /** * The transition table of the DFA */ final private static int yytrans [] = yy_unpack(yy_packed); /* error codes */ final private static int YY_UNKNOWN_ERROR = 0; final private static int YY_ILLEGAL_STATE = 1; final private static int YY_NO_MATCH = 2; final private static int YY_PUSHBACK_2BIG = 3; /* error messages for the codes above */ final private static String YY_ERROR_MSG[] = { "Unkown internal scanner error", "Internal error: unknown state", "Error: could not match input", "Error: pushback value was too large" }; /** * YY_ATTRIBUTE[aState] contains the attributes of state aState */ private final static byte YY_ATTRIBUTE[] = { 0, 9, 1, 9, 1, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; /** the input device */ private java.io.Reader yy_reader; /** the current state of the DFA */ private int yy_state; /** the current lexical state */ private int yy_lexical_state = YYINITIAL; /** this buffer contains the current text to be matched and is the source of the yytext() string */ private char yy_buffer[] = new char[16384]; /** the textposition at the last accepting state */ private int yy_markedPos; /** the textposition at the last state to be included in yytext */ private int yy_pushbackPos; /** the current text position in the buffer */ private int yy_currentPos; /** startRead marks the beginning of the yytext() string in the buffer */ private int yy_startRead; /** endRead marks the last character in the buffer, that has been read from input */ private int yy_endRead; /** number of newlines encountered up to the start of the matched text */ private int yyline; /** the number of characters up to the start of the matched text */ private int yychar; /** * the number of characters from the last newline up to the start of the * matched text */ private int yycolumn; /** * yy_atBOL == true <=> the scanner is currently at the beginning of a line */ private boolean yy_atBOL; /** yy_atEOF == true <=> the scanner has returned a value for EOF */ private boolean yy_atEOF; /** denotes if the user-EOF-code has already been executed */ private boolean yy_eof_done; /* user code: */ StringBuffer string = new StringBuffer(); private Symbol symbol(int type) { return new Symbol(type, yyline+1, yycolumn+1); } private Symbol symbol(int type, Object value) { return new Symbol(type, yyline+1, yycolumn+1, value); } /* assumes correct representation of a long value for specified radix in String s */ private long parseLong(String s, int radix) { int max = s.length(); long result = 0; long digit; for (int i = 0; i < max; i++) { digit = Character.digit(yy_buffer[i],radix); result*= radix; result+= digit; } return result; } /** * Creates a new scanner * There is also a java.io.InputStream version of this constructor. * * @param in the java.io.Reader to read input from. */ JrpcgenScanner(java.io.Reader in) { this.yy_reader = in; } /** * Creates a new scanner. * There is also java.io.Reader version of this constructor. * * @param in the java.io.Inputstream to read input from. */ JrpcgenScanner(java.io.InputStream in) { this(new java.io.InputStreamReader(in)); } /** * Unpacks the compressed DFA transition table. * * @param packed the packed transition table * @return the unpacked transition table */ private static int [] yy_unpack(String packed) { int [] trans = new int[7198]; int i = 0; /* index in packed string */ int j = 0; /* index in unpacked array */ while (i < 1550) { int count = packed.charAt(i++); int value = packed.charAt(i++); value--; do trans[j++] = value; while (--count > 0); } return trans; } /** * Unpacks the compressed character translation table. * * @param packed the packed character translation table * @return the unpacked character translation table */ private static char [] yy_unpack_cmap(String packed) { char [] map = new char[0x10000]; int i = 0; /* index in packed string */ int j = 0; /* index in unpacked array */ while (i < 158) { int count = packed.charAt(i++); char value = packed.charAt(i++); do map[j++] = value; while (--count > 0); } return map; } /** * Gets the next input character. * * @return the next character of the input stream, EOF if the * end of the stream is reached. * @exception IOException if any I/O-Error occurs */ private int yy_advance() throws java.io.IOException { /* standard case */ if (yy_currentPos < yy_endRead) return yy_buffer[yy_currentPos++]; /* if the eof is reached, we don't need to work hard */ if (yy_atEOF) return YYEOF; /* otherwise: need to refill the buffer */ /* first: make room (if you can) */ if (yy_startRead > 0) { System.arraycopy(yy_buffer, yy_startRead, yy_buffer, 0, yy_endRead-yy_startRead); /* translate stored positions */ yy_endRead-= yy_startRead; yy_currentPos-= yy_startRead; yy_markedPos-= yy_startRead; yy_pushbackPos-= yy_startRead; yy_startRead = 0; } /* is the buffer big enough? */ if (yy_currentPos >= yy_buffer.length) { /* if not: blow it up */ char newBuffer[] = new char[yy_currentPos*2]; System.arraycopy(yy_buffer, 0, newBuffer, 0, yy_buffer.length); yy_buffer = newBuffer; } /* finally: fill the buffer with new input */ int numRead = yy_reader.read(yy_buffer, yy_endRead, yy_buffer.length-yy_endRead); if ( numRead == -1 ) return YYEOF; yy_endRead+= numRead; return yy_buffer[yy_currentPos++]; } /** * Closes the input stream. */ final public void yyclose() throws java.io.IOException { yy_atEOF = true; /* indicate end of file */ yy_endRead = yy_startRead; /* invalidate buffer */ yy_reader.close(); } /** * Returns the current lexical state. */ final public int yystate() { return yy_lexical_state; } /** * Enters a new lexical state * * @param newState the new lexical state */ final public void yybegin(int newState) { yy_lexical_state = newState; } /** * Returns the text matched by the current regular expression. */ final public String yytext() { return new String( yy_buffer, yy_startRead, yy_markedPos-yy_startRead ); } /** * Returns the length of the matched text region. */ final public int yylength() { return yy_markedPos-yy_startRead; } /** * Reports an error that occured while scanning. * * @param errorCode the code of the errormessage to display */ private void yy_ScanError(int errorCode) { try { System.out.println(YY_ERROR_MSG[errorCode]); } catch (ArrayIndexOutOfBoundsException e) { System.out.println(YY_ERROR_MSG[YY_UNKNOWN_ERROR]); } System.exit(1); } /** * Pushes the specified amount of characters back into the input stream. * * They will be read again by then next call of the scanning method * * @param number the number of characters to be read again. * This number must not be greater than yylength()! */ private void yypushback(int number) { if ( number > yylength() ) yy_ScanError(YY_PUSHBACK_2BIG); yy_markedPos -= number; } /** * Contains user EOF-code, which will be executed exactly once, * when the end of file is reached */ private void yy_do_eof() throws java.io.IOException { if (!yy_eof_done) { yy_eof_done = true; yyclose(); } } /** * Resumes scanning until the next regular expression is matched, * the end of input is encountered or an I/O-Error occurs. * * @return the next token * @exception IOException if any I/O-Error occurs */ public org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol next_token() throws java.io.IOException { int yy_input; int yy_action; while (true) { boolean yy_counted = false; for (yy_currentPos = yy_startRead; yy_currentPos < yy_markedPos; yy_currentPos++) { switch (yy_buffer[yy_currentPos]) { case '\r': yyline++; yycolumn = 0; yy_counted = true; break; case '\n': if (yy_counted) yy_counted = false; else { yyline++; yycolumn = 0; } break; default: yy_counted = false; yycolumn++; } } if (yy_counted) { if ( yy_advance() == '\n' ) yyline--; if ( !yy_atEOF ) yy_currentPos--; } yy_action = -1; yy_currentPos = yy_startRead = yy_markedPos; yy_state = yy_lexical_state; yy_forAction: { while (true) { yy_input = yy_advance(); if ( yy_input == YYEOF ) break yy_forAction; int yy_next = yytrans[ yy_rowMap[yy_state] + yycmap[yy_input] ]; if (yy_next == -1) break yy_forAction; yy_state = yy_next; int yy_attributes = YY_ATTRIBUTE[yy_state]; if ( (yy_attributes & 1) > 0 ) { yy_action = yy_state; yy_markedPos = yy_currentPos; if ( (yy_attributes & 8) > 0 ) break yy_forAction; } } } switch (yy_action) { case 160: { return symbol(JrpcgenSymbols.QUADRUPLE); } case 162: break; case 158: { return symbol(JrpcgenSymbols.UNSIGNED); } case 163: break; case 155: { return symbol(JrpcgenSymbols.DEFAULT); } case 164: break; case 154: { return symbol(JrpcgenSymbols.TYPEDEF); } case 165: break; case 153: { return symbol(JrpcgenSymbols.VERSION); } case 166: break; case 38: { return symbol(JrpcgenSymbols.RANGLE); } case 167: break; case 37: { return symbol(JrpcgenSymbols.LANGLE); } case 168: break; case 36: { return symbol(JrpcgenSymbols.RBRACKET); } case 169: break; case 35: { return symbol(JrpcgenSymbols.LBRACKET); } case 170: break; case 34: { return symbol(JrpcgenSymbols.RBRACE); } case 171: break; case 33: { return symbol(JrpcgenSymbols.LBRACE); } case 172: break; case 32: { return symbol(JrpcgenSymbols.RPAREN); } case 173: break; case 31: { return symbol(JrpcgenSymbols.LPAREN); } case 174: break; case 30: { return symbol(JrpcgenSymbols.EQUAL); } case 175: break; case 1: case 4: case 9: { throw new Error("Illegal character \"" + yytext() + "\""); } case 176: break; case 2: case 3: case 67: { /* ignore */ } case 177: break; case 5: { return symbol(JrpcgenSymbols.STAR); } case 178: break; case 27: { return symbol(JrpcgenSymbols.SEMICOLON); } case 179: break; case 28: { return symbol(JrpcgenSymbols.COMMA); } case 180: break; case 29: { return symbol(JrpcgenSymbols.COLON); } case 181: break; case 78: { return symbol(JrpcgenSymbols.INT); } case 182: break; case 97: { return symbol(JrpcgenSymbols.VOID); } case 183: break; case 99: { return symbol(JrpcgenSymbols.ENUM); } case 184: break; case 107: { return symbol(JrpcgenSymbols.CASE); } case 185: break; case 108: { return symbol(JrpcgenSymbols.CHAR); } case 186: break; case 116: { return symbol(JrpcgenSymbols.LONG); } case 187: break; case 117: case 150: { return symbol(JrpcgenSymbols.BOOL); } case 188: break; case 125: { return symbol(JrpcgenSymbols.SHORT); } case 189: break; case 128: { return symbol(JrpcgenSymbols.CONST); } case 190: break; case 132: { return symbol(JrpcgenSymbols.FLOAT); } case 191: break; case 133: { return symbol(JrpcgenSymbols.HYPER); } case 192: break; case 135: { return symbol(JrpcgenSymbols.UNION); } case 193: break; case 139: { return symbol(JrpcgenSymbols.OPAQUE); } case 194: break; case 141: { return symbol(JrpcgenSymbols.STRING); } case 195: break; case 142: { return symbol(JrpcgenSymbols.STRUCT); } case 196: break; case 143: { return symbol(JrpcgenSymbols.SWITCH); } case 197: break; case 147: { return symbol(JrpcgenSymbols.DOUBLE); } case 198: break; case 152: { return symbol(JrpcgenSymbols.PROGRAM); } case 199: break; case 6: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26: case 43: case 44: case 45: case 46: case 47: case 48: case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: case 58: case 59: case 60: case 61: case 62: case 63: case 64: case 65: case 66: case 70: case 71: case 72: case 73: case 74: case 75: case 76: case 77: case 79: case 80: case 81: case 82: case 83: case 84: case 85: case 86: case 87: case 88: case 89: case 90: case 91: case 92: case 93: case 94: case 95: case 96: case 98: case 100: case 101: case 102: case 103: case 104: case 105: case 106: case 109: case 110: case 111: case 112: case 113: case 114: case 115: case 118: case 119: case 120: case 121: case 122: case 123: case 124: case 126: case 127: case 129: case 130: case 131: case 134: case 136: case 137: case 138: case 140: case 144: case 145: case 146: case 148: case 149: case 151: case 156: case 157: case 159: { return symbol(JrpcgenSymbols.IDENTIFIER, yytext()); } case 200: break; case 7: case 8: case 41: case 69: { return symbol(JrpcgenSymbols.INTEGER_LITERAL, yytext()); } case 201: break; default: if (yy_input == YYEOF && yy_startRead == yy_currentPos) { yy_atEOF = true; yy_do_eof(); { return new Symbol(JrpcgenSymbols.EOF); } } else { yy_ScanError(YY_NO_MATCH); } } } } } remotetea-1.0.7/src/org/acplt/oncrpc/apps/jrpcgen/JrpcgenStruct.java0000644005374700003410000000513507716406404026634 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/apps/jrpcgen/JrpcgenStruct.java,v 1.1.1.1 2003/08/13 12:03:47 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc.apps.jrpcgen; import java.util.Vector; /** * The JrpcgenStruct class represents a single structure defined * in an rpcgen "x"-file. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:47 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class JrpcgenStruct { /** * Structure identifier. */ public String identifier; /** * Contains elements of structure. The elements are of class * {@link JrpcgenDeclaration}. */ public Vector elements; /** * Returns just the identifier. */ public String toString() { return identifier; } /** * Constructs a JrpcgenStruct and sets the identifier and all * its attribute elements. * * @param identifier Identifier to be declared. * @param elements Vector of atrribute elements of class * {@link JrpcgenDeclaration}. */ public JrpcgenStruct(String identifier, Vector elements) { this.identifier = identifier; this.elements = elements; } /** * Dumps the structure together with its attribute elements to * System.out. */ public void dump() { System.out.println("STRUCT " + identifier + ":"); int size = elements.size(); for ( int idx = 0; idx < size; ++idx ) { JrpcgenDeclaration d = (JrpcgenDeclaration) elements.elementAt(idx); System.out.print(" "); d.dump(); } System.out.println(); } } // End of JrpcgenStruct.javaremotetea-1.0.7/src/org/acplt/oncrpc/apps/jrpcgen/JrpcgenSymbols.java0000644005374700003410000000360010335177600026765 0ustar piccainstrumentation //---------------------------------------------------- // The following code was generated by CUP v0.10k TUM Edition 20050516 // Fri Nov 11 20:53:50 CET 2005 //---------------------------------------------------- package org.acplt.oncrpc.apps.jrpcgen; /** CUP generated interface containing symbol constants. */ public interface JrpcgenSymbols { /* terminals */ public static final int SHORT = 24; public static final int QUADRUPLE = 30; public static final int LBRACKET = 11; public static final int CONST = 17; public static final int CHAR = 23; public static final int CASE = 20; public static final int DOUBLE = 29; public static final int HYPER = 27; public static final int LPAREN = 7; public static final int INT = 25; public static final int STAR = 6; public static final int RPAREN = 8; public static final int SEMICOLON = 2; public static final int BOOL = 31; public static final int COMMA = 3; public static final int VERSION = 16; public static final int TYPEDEF = 18; public static final int EOF = 0; public static final int RBRACKET = 12; public static final int EQUAL = 5; public static final int error = 1; public static final int PROGRAM = 15; public static final int UNSIGNED = 37; public static final int VOID = 22; public static final int SWITCH = 19; public static final int COLON = 4; public static final int UNION = 36; public static final int LANGLE = 13; public static final int LBRACE = 9; public static final int OPAQUE = 33; public static final int ENUM = 32; public static final int DEFAULT = 21; public static final int FLOAT = 28; public static final int RANGLE = 14; public static final int RBRACE = 10; public static final int LONG = 26; public static final int STRING = 34; public static final int STRUCT = 35; public static final int IDENTIFIER = 39; public static final int INTEGER_LITERAL = 38; } remotetea-1.0.7/src/org/acplt/oncrpc/apps/jrpcgen/JrpcgenUnion.java0000644005374700003410000000613407716406404026440 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/apps/jrpcgen/JrpcgenUnion.java,v 1.1.1.1 2003/08/13 12:03:47 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc.apps.jrpcgen; import java.util.Vector; /** * The JrpcgenUnion class represents a single union defined * in an rpcgen "x"-file. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:47 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class JrpcgenUnion { /** * Union identifier. */ public String identifier; /** * {@link JrpcgenDeclaration} of descriminant element (containing its * identifier and data type). */ public JrpcgenDeclaration descriminant; /** * Contains arms of union. The arms are of class * {@link JrpcgenDeclaration}. The keys are the descriminant values. */ public Vector elements; /** * Returns just the identifier. */ public String toString() { return identifier; } /** * Constructs a JrpcgenUnion and sets the identifier, the * descrimant element as well as all attribute elements. * * @param identifier Identifier to be declared. * @param descriminant Descriminant element of class * {@link JrpcgenDeclaration}. * @param elements Vector of atrribute elements of class * {@link JrpcgenDeclaration}. */ public JrpcgenUnion(String identifier, JrpcgenDeclaration descriminant, Vector elements) { this.identifier = identifier; this.descriminant = descriminant; this.elements = elements; } /** * Dumps the union together with its attribute elements end the * descriminant to System.out. */ public void dump() { System.out.println("UNION " + identifier + ":"); System.out.println(" switch (" + descriminant.type + " " + descriminant.identifier + ")"); int size = elements.size(); for ( int idx = 0; idx < size; ++idx ) { JrpcgenUnionArm a = (JrpcgenUnionArm) elements.elementAt(idx); System.out.print(" "); a.dump(); } System.out.println(); } } // End of JrpcgenUnion.javaremotetea-1.0.7/src/org/acplt/oncrpc/apps/jrpcgen/JrpcgenUnionArm.java0000644005374700003410000000560407716623670027107 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/apps/jrpcgen/JrpcgenUnionArm.java,v 1.2 2003/08/14 08:09:59 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc.apps.jrpcgen; /** * The JrpcgenUnionArm class represents a single union arm defined * for a particular union in an rpcgen "x"-file. * * @version $Revision: 1.2 $ $Date: 2003/08/14 08:09:59 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class JrpcgenUnionArm { /** * Value for which the descriminated union arm is valid. */ public String value; /** * Attribute element of descriminated arm (of class * {@link JrpcgenDeclaration}). */ public JrpcgenDeclaration element; /** * Constructs a JrpcgenUnionArm and sets decrimated arm's * value and the associated attribute element. * * @param value Value for which descriminated arm is valid. * @param element Descriminated arm element of class * {@link JrpcgenDeclaration}. */ public JrpcgenUnionArm(String value, JrpcgenDeclaration element) { this.value = value; this.element = element; } /** * Dumps the union arm to System.out. */ public void dump() { if ( value == null ) { if ( element == null ) { System.out.println(" default: -"); } else if ( element.identifier != null ) { System.out.print(" default: "); element.dump(); } else { System.out.println(" default: void"); } } else { if ( element == null ) { System.out.println(" " + value + ": -"); } else if ( element.identifier != null ) { System.out.print(" " + value + ": "); element.dump(); } else { System.out.println(" " + value + ": void"); } } } } // End of JrpcgenUnionArm.javaremotetea-1.0.7/src/org/acplt/oncrpc/apps/jrpcgen/JrpcgenVersionInfo.java0000644005374700003410000000606607716406404027615 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/apps/jrpcgen/JrpcgenVersionInfo.java,v 1.1.1.1 2003/08/13 12:03:47 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc.apps.jrpcgen; import java.util.Vector; import java.io.PrintWriter; /** * The JrpcgenVersionInfo class contains information about a * specific version of an ONC/RPC program as defined in a rpcgen "x"-file. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:47 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ class JrpcgenVersionInfo { /** * Version number assigned to an ONC/RPC program. This attribute contains * either an integer literal or an identifier (which must resolve to an * integer). */ public String versionNumber; /** * Identifier assigned to the version number of an ONC/RPC program. */ public String versionId; /** * Set of procedures specified for a particular ONC/RPC program. * The elements in the set are of class {@link JrpcgenProcedureInfo}. */ public Vector procedures; /** * Constructs a new JrpcgenVersionInfo object containing * information about a programs' version and a set of procedures * defined by this program version. * * @param versionId Identifier defined for this version of a * particular ONC/RPC program. * @param versionNumber Version number. * @param procedures Vector of procedures defined for this ONC/RPC program. */ public JrpcgenVersionInfo(String versionId, String versionNumber, Vector procedures) { this.versionId = versionId; this.versionNumber = versionNumber; this.procedures = procedures; } /** * Generates source code to define the version constant belonging to this * program. * * @param out PrintWriter to send source code to. */ public void dumpConstants(PrintWriter out) { out.println(" /* ONC/RPC program version number definition */"); out.println(" public final static int " + versionId + " = " + versionNumber + ";"); } } // End of JrpcgenVersionInfo.javaremotetea-1.0.7/src/org/acplt/oncrpc/apps/jrpcgen/jrpcgen.java0000644005374700003410000031041710627062426025466 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/apps/jrpcgen/jrpcgen.java,v 1.6 2007/05/29 19:38:30 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ // // Personal note: this class probably suffers from a flashback on // procedural programming ... but where do we need to be today? // package org.acplt.oncrpc.apps.jrpcgen; import org.acplt.oncrpc.apps.jrpcgen.cup_runtime.Symbol; import java.io.*; import java.util.Hashtable; import java.util.Vector; import java.util.Enumeration; import java.util.Date; import java.text.SimpleDateFormat; /** * The class jrpcgen implements a Java-based rpcgen RPC protocol * compiler. jrpcgen is a Java-based tool that generates source code of Java * classes to implement an RPC protocol. The input to jrpcgen is a language * similiar to C (but more probably much more similiar to FORTRAN) known as * the RPC language (Remote Procedure Call Language). * * @version $Revision: 1.6 $ $Date: 2007/05/29 19:38:30 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class jrpcgen { /** * Print the help message describing the available command line options. */ public static void printHelp() { System.out.println("Usage: jrpcgen [-options] x-file"); System.out.println(); System.out.println("where options include:"); System.out.println(" -c specify class name of client proxy stub"); System.out.println(" -d

specify directory where to place generated source code files"); System.out.println(" -p specify package name for generated source code files"); System.out.println(" -s specify class name of server proxy stub"); System.out.println(" -ser tag generated XDR classes as serializable"); System.out.println(" -bean generate accessors for usage as bean, implies -ser"); System.out.println(" -noclamp do not clamp version number in client method stubs"); System.out.println(" -withcallinfo supply call information to server method stubs"); System.out.println(" -initstrings initialize all strings to be empty instead of null"); System.out.println(" -nobackup do not make backups of old source code files"); System.out.println(" -noclient do not create client proxy stub"); System.out.println(" -noserver do not create server proxy stub"); System.out.println(" -parseonly parse x-file only but do not create source code files"); System.out.println(" -verbose enable verbose output about what jrpcgen is doing"); System.out.println(" -version print jrpcgen version and exit"); System.out.println(" -debug enables printing of diagnostic messages"); System.out.println(" -? -help print this help message and exit"); System.out.println(" -- end options"); System.out.println(); } /** * Current version of jrpcgen. */ public static final String VERSION = "1.0.7"; /** * A remote procedure has no parameters and thus needs to use the * XDR void wrapper class as a dummy. */ public static final int PARAMS_VOID = 0; /** * A remote procedure expects only a single parameter, which is a * complex type (class). */ public static final int PARAMS_SINGLE = 1; /** * A remote procedure expects only a single parameter, which is of * a base type, like integer, boolean, string, et cetera. */ public static final int PARAMS_SINGLE_BASETYPE = 2; /** * A remote procedure expects more than one parameter and thus needs * an XDR wrapping class. */ public static final int PARAMS_MORE = 3; /** * String containing date/time when a jrpcgen run was started. This string * is used in the headers of the generated source code files. */ public static final String startDate = (new SimpleDateFormat()).format(new Date()); /** * Contains all global identifiers for type, structure and union specifiers * as well as for constants and enumeration members. This static attribute * is directly manipulated by the parser. */ public static Hashtable globalIdentifiers = new Hashtable(); /** * Disable automatic backup of old source code files, if true. */ public static boolean noBackups = false; /** * Holds information about the remote program defined in the jrpcgen * x-file. */ public static Vector programInfos = null; /** * Clamp version and program number in client method stubs to the * version and program number specified in the x-file. */ public static boolean clampProgAndVers = true; /** * Supply (additional) call information to server method stubs. */ public static boolean withCallInfo = false; /** * Enable diagnostic messages when parsing the x-file. */ public static boolean debug = false; /** * Verbosity flag. If true, then jrpcgen will report about * the steps it is taking when generating all the source code files. */ public static boolean verbose = false; /** * Parse x-file only but do not create source code files if set to * true. */ public static boolean parseOnly = false; /** * The x-file to parse (not: the X Files, the latter ones are something * completely different). */ public static File xFile = null; /** * Destination directory where to place the generated files. */ public static File destinationDir = new File("."); /** * Current FileWriter object receiving generated source code. */ public static Writer currentFileWriter = null; /** * Current PrintWriter object sitting on top of the * {@link #currentFileWriter} object receiving generated source code. */ public static PrintWriter currentPrintWriter = null; /** * Full name of the current source code file. */ public static String currentFilename = null; /** * Specifies package name for generated source code, if not * null. If null, then no package statement * is emitted. */ public static String packageName = null; /** * Name of class containing global constants. It is derived from the * filename with the extension (".x") and path removed. */ public static String baseClassname = null; /** * Do not generate source code for the client proxy stub if * true. */ public static boolean noClient = false; /** * Do not generate source code for the server proxy stub if * true. */ public static boolean noServer = false; /** * Name of class containing the ONC/RPC server stubs. */ public static String serverClass = null; /** * Name of class containing the ONC/RPC client stubs. */ public static String clientClass = null; /** * Enable tagging of XDR classes as being Serializable */ public static boolean makeSerializable = false; /** * Enable generation of accessors in order to use XDR classes as beans. */ public static boolean makeBean = false; /** * Enable automatic initialization of String with empty Strings * instead of null reference. */ public static boolean initStrings = false; /** * Creates a new source code file for a Java class based on its class * name. Same as {@link #createJavaSourceFile(String, boolean)} with * the emitImport parameter set to true. * * @param classname Name of Java class to generate. Must not contain * a file extension -- especially ".java" is invalid. When the source * code file is created, ".java" is appended automatically. * * @return PrintWriter to send source code to. */ public static PrintWriter createJavaSourceFile(String classname) { return createJavaSourceFile(classname, true); } /** * Creates a new source code file for a Java class based on its class * name. If an old version of the source file exists, it is renamed first. * The backup will have the same name as the original file with "~" * appended. * * @param classname Name of Java class to generate. Must not contain * a file extension -- especially ".java" is invalid. When the source * code file is created, ".java" is appended automatically. * @param emitImports if true, then import statements for * the remotetea ONC/RPC package and IOExceptions. * * @return PrintWriter to send source code to. */ public static PrintWriter createJavaSourceFile(String classname, boolean emitImports) { String filename = classname + ".java"; if ( debug ) { System.out.println("Generating source code for \"" + filename + "\" in \"" + destinationDir + "\""); } File file = new File(destinationDir, filename); // // If an old file of the same name already exists, then rename it // before creating the new file. // if ( file.exists() && !noBackups ) { if ( !file.isFile() ) { // // If the file to be created already exists and is not a // regular file, then bail out with an error. // System.err.println("error: source file \"" + filename + "\"already exists and is not a regular file"); System.exit(1); } File oldBackup = new File(destinationDir, filename + "~"); if ( oldBackup.isFile() ) { oldBackup.delete(); } else if ( oldBackup.exists() ) { System.err.println("error: backup source file \"" + filename + "~\" is not a regular file"); System.exit(1); } if ( !file.renameTo(new File(destinationDir, filename + "~")) ) { System.err.println("error: can not rename old source code file \"" + filename + "\""); System.exit(1); } if ( verbose ) { System.out.println("Saved old source code file as \"" + filename + "~\""); } } // // Now create a new source code file... // try { currentFileWriter = new FileWriter(file); } catch ( IOException e ) { System.err.println("error: can not create \"" + filename + "\": " + e.getLocalizedMessage()); System.exit(1); } if ( verbose ) { System.out.print("Creating source code file \"" + filename + "\"..."); } currentFilename = filename; PrintWriter out = new PrintWriter(currentFileWriter, true); currentPrintWriter = out; // // Create automatic header(s)... // Note that we always emit the import statements, regardless of // whether we're emitting a class file or an interface file consisting // of an enumeration. // out.println("/*"); out.println(" * Automatically generated by jrpcgen " + VERSION + " on " + startDate); out.println(" * jrpcgen is part of the \"Remote Tea\" ONC/RPC package for Java"); out.println(" * See http://remotetea.sourceforge.net for details"); out.println(" */"); // // Only generated package statement if a package name has been specified. // if ( (packageName != null) && (packageName.length() > 0) ) { out.println("package " + packageName + ";"); } if ( emitImports ) { out.println("import org.acplt.oncrpc.*;"); out.println("import java.io.IOException;"); out.println(); } return out; } /** * Create a new hash function object and initialize it using a class * and package name. * * @param classname Name of class. * * @return hash function object. */ public static JrpcgenSHA createSHA(String classname) { JrpcgenSHA hash = new JrpcgenSHA(); if ( (packageName != null) && (packageName.length() > 0) ) { hash.update(packageName + "." + classname); } else { hash.update(classname); } return hash; } /** * Closes the source code file previously opened with * createJavaSourceFile. This method writes a trailer * before closing the file. */ public static void closeJavaSourceFile() { // // Create automatic footer before closing the file. // currentPrintWriter.println("// End of " + currentFilename); if ( verbose ) { System.out.println(); } try { currentPrintWriter.close(); currentFileWriter.close(); } catch ( IOException e ) { System.err.println("Can not close source code file: " + e.getLocalizedMessage()); } } /** * Dump the value of a constant and optionally first dump all constants * it depends on. */ public static void dumpConstantAndDependency(PrintWriter out, JrpcgenConst c) { // // This simple test avoids endless recursions: we already dumped this // particular constant in some place, so we should not proceed. // if ( c.dontTraverseAnyMore ) { return; } // // Since we will dump the constant below, we already set the flag, // to avoid endless recursions. // c.dontTraverseAnyMore = true; String dependencyIdentifier = c.getDependencyIdentifier(); if ( dependencyIdentifier != null ) { // // There is a dependency, so try to resolve that first. In case // we depend on another identifier belonging to the same enclosure, // we dump this other identifier first. However, if the identifier // we depend on belongs to a different enclosure, then we must not // dump it: this will be the job of a later call when the proper // enclosure is in the works. // JrpcgenConst dc = (JrpcgenConst) globalIdentifiers.get(dependencyIdentifier); if ( dc != null ) { if ( !c.enclosure.equalsIgnoreCase(dc.enclosure) ) { // // In case we depend on a constant which belongs to a // different enclosure then also dump the enclosure (that // is, "enclosure.valueidentifier"). // // Note that this code depends on the "value" starts // with the identifier we depend on (which is currently // the case), so we just need to prepend the enclosure. // out.println(" public static final int " + c.identifier + " = " + dc.enclosure + "." + c.value + ";"); return; } // // Only dump the identifier we're dependent on, if it's in // the same enclosure. // dumpConstantAndDependency(out, dc); } } // // Just dump the plain value (without enclosure). // out.println(" public static final int " + c.identifier + " = " + c.value + ";"); } /** * Generate source code file containing all constants defined in the * x-file as well as all implicitely defined constants, like program, * version and procedure numbers, etc. This method creates a public * interface with the constants as public static final integers. */ public static void dumpConstants() { // // Create new source code file containing a Java interface representing // all XDR constants. // PrintWriter out = createJavaSourceFile(baseClassname, false); // // Spit out some description for javadoc & friends... // out.println("/**"); out.println(" * A collection of constants used by the \"" + baseClassname + "\" ONC/RPC program."); out.println(" */"); out.println("public interface " + baseClassname + " {"); Enumeration globals = globalIdentifiers.elements(); while ( globals.hasMoreElements() ) { Object o = globals.nextElement(); if ( o instanceof JrpcgenConst ) { JrpcgenConst c = (JrpcgenConst) o; // // Dump only such constants which belong to the global // constants enclosure. Ignore all other constants, as those // belong to other Java class enclosures. // if ( baseClassname.equals(c.enclosure) ) { dumpConstantAndDependency(out, c); } } } out.println("}"); closeJavaSourceFile(); } /** * Generate a source code file containing all elements of an enumeration * defined in a x-file. * * @param e {@link JrpcgenEnum Description} of XDR enumeration. */ public static void dumpEnum(JrpcgenEnum e) { // // Create new source code file containing a Java interface representing // the XDR enumeration. // PrintWriter out = createJavaSourceFile(e.identifier, false); // // Spit out some description for javadoc & friends... // out.println("/**"); out.println(" * Enumeration (collection of constants)."); out.println(" */"); out.println("public interface " + e.identifier + " {"); out.println(); Enumeration enums = e.enums.elements(); while ( enums.hasMoreElements() ) { JrpcgenConst c = (JrpcgenConst) enums.nextElement(); // // In case an element depends on a global constant, then // this constant will automatically be duplicated as part // of this enumeration. // dumpConstantAndDependency(out, c); } // // Close class... // out.println(); out.println("}"); closeJavaSourceFile(); } /** * Java base data types for which are XDR encoding and decoding helper * methods available. */ private static String [] baseTypes = { "void", "boolean", "byte", "short", "int", "long", "float", "double", "String" }; /** * Given a name of a data type return the name of the equivalent Java * data type (if it exists), otherwise return null. * * NOTE: "opaque" is considered like "byte" to be a base type... * FIXME: char/byte? * * @return Name of Java base data type or null if the * given data type is not equivalent to one of Java's base data * types. */ public static String xdrBaseType(String type) { int size = baseTypes.length; if ( "opaque".compareTo(type) == 0 ) { type = "byte"; } for ( int idx = 0; idx < size; ++idx ) { if ( baseTypes[idx].compareTo(type) == 0 ) { // // For base data types simply convert the first letter to // an upper case letter. // return "Xdr" + type.substring(0, 1).toUpperCase() + type.substring(1); } } return null; } /** * Return the en-/decoding syllable XXX appropriate for a base data * type including arrays of base data types. * * @param decl declaration of a member of RPC struct or union. * * @return null, if the declaration does not specify a base data * type. Otherwise a three-element String array, with [0] containing * the type syllable for base type (including arrays), [1] containing * parameter options when encoding (like maximum sizes, etc), and [2] * containing options for decoding. */ public static JrpcgenEnDecodingInfo baseEnDecodingSyllable(JrpcgenDeclaration decl) { String syllable = decl.type; boolean isBase = false; // // Check for Java base data types... if a match is found, then convert // the data type name, so that it becomes a valid syllable for use // with XDR en-/decoding functions xdrEncodingXXX() etc. // Example: "int" --> "Int" (because of xdrEncodingInt()) // NOTE: we consider "opaque" to be a base type here... // int size = baseTypes.length; String type = decl.type; if ( "opaque".compareTo(type) == 0 ) { type = "byte"; } for ( int idx = 0; idx < size; ++idx ) { if ( baseTypes[idx].compareTo(type) == 0 ) { // // For base data types simply convert the first letter to // an upper case letter. // isBase = true; syllable = syllable.substring(0, 1).toUpperCase() + syllable.substring(1); break; } } // // Handle special case of enumerations, which have to be represented // using ints in the Java language. // if ( !isBase ) { Object o = globalIdentifiers.get(decl.type); if ( o instanceof JrpcgenEnum ) { isBase = true; syllable = "Int"; } } // // In case we're dealing with an array, then add "Vector" to // the syllable to use the appropriate vector en-/decoding method // for base data types. // NOTE: unfortunately, strings do not adhere to this scheme, as // they are considered to be arrays of characters... what a silly // idea, as this makes a typedef necessary in case someone needs // an array of strings. // NOTE: also opaques break the scheme somehow, but the char=byte // versus opaque schisma anyhow drives me crazy... // if ( isBase ) { String encodingOpts = null; String decodingOpts = null; if ( (decl.kind == JrpcgenDeclaration.FIXEDVECTOR) || (decl.kind == JrpcgenDeclaration.DYNAMICVECTOR) ) { if ( "opaque".equals(decl.type) ) { if ( decl.kind == JrpcgenDeclaration.FIXEDVECTOR ) { syllable = "Opaque"; encodingOpts = checkForEnumValue(decl.size); decodingOpts = checkForEnumValue(decl.size); } else { syllable = "DynamicOpaque"; encodingOpts = null; decodingOpts = null; } } else if ( !"String".equals(decl.type) ) { if ( decl.kind == JrpcgenDeclaration.FIXEDVECTOR ) { syllable = syllable + "Fixed"; encodingOpts = checkForEnumValue(decl.size); decodingOpts = checkForEnumValue(decl.size); } syllable = syllable + "Vector"; } } JrpcgenEnDecodingInfo result = new JrpcgenEnDecodingInfo(syllable, encodingOpts, decodingOpts); return result; } return null; } /** * Return en- or decoding method appropriate for a struct or union member. */ public static String codingMethod(JrpcgenDeclaration decl, boolean encode) { return codingMethod(decl, encode, null); } /** * Return en- or decoding method appropriate for a struct or union member. * * @param decl declaration for which the en-/decoding Java source code be * returned. * @param encode true if encoding method should be returned, * false if decoding method is to be returned. * @param oref name of object reference or null if * "this" should be used instead. */ public static String codingMethod(JrpcgenDeclaration decl, boolean encode, String oref) { // // Skip entries for void arms etc... // if ( decl.identifier == null ) { return ""; } StringBuffer code = new StringBuffer(); JrpcgenEnDecodingInfo data = baseEnDecodingSyllable(decl); // // In case no type was specified for the outer element, assume no // name, otherwise convert into a suitable prefix for code generation // by appending a dot. // if ( oref == null ) { oref = ""; } else { oref = oref + "."; } if ( data != null ) { // // It's a base data type (including vectors). So we can use the // predefined en-/decoding methods: // - xdr.xdrEncodeXXX(value); // - value = xdr.xdrDecodeXXX(value); // if ( encode ) { code.append(" xdr.xdrEncode"); code.append(data.syllable); code.append("("); code.append(oref + decl.identifier); if ( data.encodingOptions != null ) { code.append(", "); code.append(data.encodingOptions); } code.append(");\n"); } else { code.append(" "); code.append(oref + decl.identifier); code.append(" = xdr.xdrDecode"); code.append(data.syllable); code.append("("); if ( data.decodingOptions != null ) { code.append(data.decodingOptions); } code.append(");\n"); } return code.toString(); } else { // // It's not a built-in base data type but instead something that // is represented by a class. // - foo.xdrEncode(xdr); // - foo = new FOO(); // foo.xdrDecode(xdr); // In case of arrays, this is going to be hairy... // if ( decl.kind == JrpcgenDeclaration.SCALAR ) { code.append(" "); if ( encode ) { code.append(oref + decl.identifier); code.append(".xdrEncode(xdr);\n"); } else { code.append(oref + decl.identifier); code.append(" = new "); code.append(decl.type); code.append("(xdr);\n"); } return code.toString(); // // It's not a built-in base data type but instead an indirection // (reference) to some instance (optional data). // } else if ( decl.kind == JrpcgenDeclaration.INDIRECTION ) { code.append(" "); if ( encode ) { code.append("if ( "); code.append(oref + decl.identifier); code.append(" != null ) { "); code.append("xdr.xdrEncodeBoolean(true); "); code.append(oref + decl.identifier); code.append(".xdrEncode(xdr);"); code.append(" } else { "); code.append("xdr.xdrEncodeBoolean(false);"); code.append(" };\n"); } else { code.append(oref + decl.identifier); code.append(" = xdr.xdrDecodeBoolean() ? new "); code.append(decl.type); code.append("(xdr) : null;\n"); } return code.toString(); } // // Array case... Urgh! // if ( encode ) { code.append(" { "); code.append("int $size = "); if ( decl.kind == JrpcgenDeclaration.DYNAMICVECTOR ) { // // Dynamic array size. So we need to use the current size // of the Java array. // code.append(oref + decl.identifier); code.append(".length"); } else { code.append(checkForEnumValue(decl.size)); } code.append("; "); if ( decl.kind == JrpcgenDeclaration.DYNAMICVECTOR ) { // // Dynamic array size. So we need to encode size information. // code.append("xdr.xdrEncodeInt($size); "); } // // Now encode all elements. // code.append("for ( int $idx = 0; $idx < $size; ++$idx ) { "); code.append(oref + decl.identifier); code.append("[$idx].xdrEncode(xdr); "); code.append("} }\n"); } else { code.append(" { "); code.append("int $size = "); if ( decl.kind == JrpcgenDeclaration.DYNAMICVECTOR ) { // // Dynamic array size. So we need to decode size information. // code.append("xdr.xdrDecodeInt()"); } else { code.append(checkForEnumValue(decl.size)); } code.append("; "); // // Now encode all elements. // code.append(oref + decl.identifier); code.append(" = new "); code.append(decl.type); code.append("[$size]; "); code.append("for ( int $idx = 0; $idx < $size; ++$idx ) { "); code.append(oref + decl.identifier); code.append("[$idx] = new "); code.append(decl.type); code.append("(xdr); "); code.append("} }\n"); } return code.toString(); } } /** * Checks whether a given data type identifier refers to an enumeration * type and then returns Java's int data type instead. In case of the * pseudo-type "opaque" return Java's byte data type. For all other * data types, the data type identifier is returned unaltered. * * @param dataType data type identifier to check. * * @return data type identifier. */ public static String checkForSpecials(String dataType) { if ( globalIdentifiers.get(dataType) instanceof JrpcgenEnum ) { return "int"; } else if ( "opaque".equals(dataType) ) { return "byte"; } return dataType; } /** * Checks whether a given value references an identifier and then * returns the qualified identifier (interface where the value is * defined in) or simply the value in case of an integer literal. * * @param value Either an identifier to resolve or an integer literal. * * @return Integer literal or qualified identifier. */ public static String checkForEnumValue(String value) { if ( value.length() > 0 ) { // // If the value is an integer literal, then we just have to // return it. That's it. // if ( Character.isDigit(value.charAt(0)) || (value.charAt(0) == '-') ) { return value; } // // It's an identifier: we now need to find out in which // enclosure it lives, so we can return a qualified identifier. // Object id = jrpcgen.globalIdentifiers.get(value); if ( (id != null) && (id instanceof JrpcgenConst) ) { JrpcgenConst c = (JrpcgenConst) id; if ( c.enclosure == null ) { return c.value; } return c.enclosure + "." + c.identifier; } } return value; } /** * Generate a source code file containing all elements of a struct * defined in a x-file. * * @param s {@link JrpcgenStruct Description} of XDR struct. */ public static void dumpStruct(JrpcgenStruct s) { // // Create new source code file containing a Java class representing // the XDR struct. // String access = " public "; // modify encapsulation with beans PrintWriter out = createJavaSourceFile(s.identifier); out.print("public class " + s.identifier + " implements XdrAble"); if ( makeSerializable ) { out.print(", java.io.Serializable"); } if ( makeBean ) { access = " protected "; } out.println(" {"); // // Generate declarations of all members of this XDR struct. This the // perfect place to also update the hash function using the elements // together with their type. // boolean useIteration = false; JrpcgenSHA hash = createSHA(s.identifier); Enumeration decls = s.elements.elements(); while ( decls.hasMoreElements() ) { JrpcgenDeclaration d = (JrpcgenDeclaration) decls.nextElement(); hash.update(d.type); hash.update(d.kind); hash.update(d.identifier); out.print(access + checkForSpecials(d.type) + " "); if ( ((d.kind == JrpcgenDeclaration.FIXEDVECTOR) || (d.kind == JrpcgenDeclaration.DYNAMICVECTOR)) && !d.type.equals("String") ) { out.print("[] "); } if ( initStrings && d.type.equals("String") ) { out.println(d.identifier + " = \"\"; "); } else { out.println(d.identifier + ";"); } // // If the last element in the XDR struct is a reference to // the type of the XDR struct (that is, a linked list), then // we can convert this tail recursion into an iteration, // avoiding deep recursions for large lists. // if ( !decls.hasMoreElements() && d.kind == JrpcgenDeclaration.INDIRECTION && d.type.equals(s.identifier) ) { useIteration = true; } } // // Generate serial version unique identifier // if ( makeSerializable ) { out.println(); out.println(" private static final long serialVersionUID = " + hash.getHash() + "L;"); if ( makeBean ) { // // Also generate accessors (getters and setters) so that // class can be used as a bean. // decls = s.elements.elements(); while ( decls.hasMoreElements() ) { out.println(); JrpcgenDeclaration d = (JrpcgenDeclaration) decls.nextElement(); String jbName = d.identifier.substring(0,1).toUpperCase() + d.identifier.substring(1); boolean isArray = (((d.kind == JrpcgenDeclaration.FIXEDVECTOR) || (d.kind == JrpcgenDeclaration.DYNAMICVECTOR)) && !d.type.equals("String") ); // // Generate the setter(s) // if ( isArray ) { out.println(" public void set" + jbName + "(" + checkForSpecials(d.type) + "[] x) { this." + d.identifier + " = x; }"); out.println(" public void set" + jbName + "(int index, " + checkForSpecials(d.type) + " x) { this." + d.identifier + "[index] = x; }"); } else { out.println(" public void set" + jbName + "(" + checkForSpecials(d.type) + " x) { this." + d.identifier + " = x; }"); } // // Generate the getter(s) // if ( isArray ) { out.println(" public " + checkForSpecials(d.type) + "[] get" + jbName + "() { return this." + d.identifier + "; }"); out.println(" public " + checkForSpecials(d.type) + " get" + jbName + "(int index) { return this." + d.identifier + "[index]; }"); } else { out.println(" public " + checkForSpecials(d.type) + " get" + jbName + "() { return this." + d.identifier + "; }"); } } } } // // Now generate code for encoding and decoding this class (structure). // out.println(); out.println(" public " + s.identifier + "() {"); out.println(" }"); out.println(); out.println(" public " + s.identifier + "(XdrDecodingStream xdr)"); out.println(" throws OncRpcException, IOException {"); out.println(" xdrDecode(xdr);"); out.println(" }"); out.println(); out.println(" public void xdrEncode(XdrEncodingStream xdr)"); out.println(" throws OncRpcException, IOException {"); decls = s.elements.elements(); if ( useIteration ) { out.println(" " + s.identifier + " $this = this;"); out.println(" do {"); JrpcgenDeclaration decl = null; // // when using the iteration loop for serializing emit code for // all but the tail element, which is the reference to our type. // for ( int size = s.elements.size(); size > 1; --size ) { decl = (JrpcgenDeclaration) decls.nextElement(); out.print(" " + codingMethod(decl, true, "$this")); } decl = (JrpcgenDeclaration) decls.nextElement(); out.println(" $this = $this." + decl.identifier + ";"); out.println(" xdr.xdrEncodeBoolean($this != null);"); out.println(" } while ( $this != null );"); } else { while ( decls.hasMoreElements() ) { out.print(codingMethod((JrpcgenDeclaration) decls.nextElement(), true)); } } out.println(" }"); out.println(); out.println(" public void xdrDecode(XdrDecodingStream xdr)"); out.println(" throws OncRpcException, IOException {"); decls = s.elements.elements(); if ( useIteration ) { out.println(" " + s.identifier + " $this = this;"); out.println(" " + s.identifier + " $next;"); out.println(" do {"); JrpcgenDeclaration decl = null; // // when using the iteration loop for serializing emit code for // all but the tail element, which is the reference to our type. // for ( int size = s.elements.size(); size > 1; --size ) { decl = (JrpcgenDeclaration) decls.nextElement(); out.print(" " + codingMethod(decl, false, "$this")); } decl = (JrpcgenDeclaration) decls.nextElement(); out.println(" $next = xdr.xdrDecodeBoolean() ? new " + s.identifier + "() : null;"); out.println(" $this." + decl.identifier + " = $next;"); out.println(" $this = $next;"); out.println(" } while ( $this != null );"); } else { while ( decls.hasMoreElements() ) { out.print(codingMethod((JrpcgenDeclaration) decls.nextElement(), false)); } } out.println(" }"); // // Close class... // out.println(); out.println("}"); closeJavaSourceFile(); } /** * Generate a source code file containing all elements of a union * defined in a x-file. * * @param u {@link JrpcgenUnion Description} of XDR union. */ public static void dumpUnion(JrpcgenUnion u) { // // Create new source code file containing a Java class representing // the XDR union. // PrintWriter out = createJavaSourceFile(u.identifier); out.print("public class " + u.identifier + " implements XdrAble"); if ( makeSerializable ) { out.print(", java.io.Serializable"); } out.println(" {"); // // Note that the descriminant can not be of an array type, string, etc. // so we don't have to handle all the special cases here. // out.println(" public " + checkForSpecials(u.descriminant.type) + " " + u.descriminant.identifier + ";"); boolean boolDescriminant = u.descriminant.type.equals("boolean"); JrpcgenSHA hash = createSHA(u.identifier); Enumeration arms = u.elements.elements(); while ( arms.hasMoreElements() ) { JrpcgenUnionArm a = (JrpcgenUnionArm) arms.nextElement(); // // Skip all arms which do not contain a variable but are // declared as "void" instead. Also skip all arms which are // mapped to another arm. // if ( (a.element == null) || (a.element.identifier == null) ) { continue; } // // In case we are working on the default arm and this arm // contains some variables, we hash the dummy descriminator // value "default". // if ( a.value != null ) { hash.update(a.value); } else { hash.update("default"); } hash.update(a.element.type); hash.update(a.element.kind); hash.update(a.element.identifier); out.print(" public " + checkForSpecials(a.element.type) + " "); if ( ((a.element.kind == JrpcgenDeclaration.FIXEDVECTOR) || (a.element.kind == JrpcgenDeclaration.DYNAMICVECTOR)) && !a.element.type.equals("String") ) { out.print("[] "); } out.println(a.element.identifier + ";"); } // // Generate serial version unique identifier // if ( makeSerializable ) { out.println(); out.println(" private static final long serialVersionUID = " + hash.getHash() + "L;"); } // // Now generate code for encoding and decoding this class (structure). // out.println(); out.println(" public " + u.identifier + "() {"); out.println(" }"); out.println(); out.println(" public " + u.identifier + "(XdrDecodingStream xdr)"); out.println(" throws OncRpcException, IOException {"); out.println(" xdrDecode(xdr);"); out.println(" }"); out.println(); out.println(" public void xdrEncode(XdrEncodingStream xdr)"); out.println(" throws OncRpcException, IOException {"); out.print(codingMethod(u.descriminant, true)); if ( !boolDescriminant ) { // // Produce code using an ordinary switch statement... // out.println(" switch ( " + u.descriminant.identifier + " ) {"); arms = u.elements.elements(); while ( arms.hasMoreElements() ) { JrpcgenUnionArm a = (JrpcgenUnionArm) arms.nextElement(); if ( a.value != null ) { out.println(" case " + checkForEnumValue(a.value) + ":"); } else { // // It's the default arm. // out.println(" default:"); } // // Only emit code if arm does not map to another arm. // if ( a.element != null ) { if ( a.element.identifier != null ) { // // Arm does not contain void, so we need to spit out // encoding instructions. // out.print(" "); out.print(codingMethod(a.element, true)); } out.println(" break;"); } } out.println(" }"); } else { // // boolean descriminant: here we can have at most two arms, guess // why. // boolean firstArm = true; arms = u.elements.elements(); while ( arms.hasMoreElements() ) { JrpcgenUnionArm a = (JrpcgenUnionArm) arms.nextElement(); if ( a.value == null ) { // // Skip default branch this time... // continue; } if ( a.element.identifier != null ) { // // Arm contains data, so we need to create encoding // instructions. // out.print(" "); if ( !firstArm ) { out.print("else "); } else { firstArm = false; } out.println("if ( " + u.descriminant.identifier + " == " + checkForEnumValue(a.value) + " ) {"); out.print(" "); out.print(codingMethod(a.element, true)); out.println(" }"); } } arms = u.elements.elements(); while ( arms.hasMoreElements() ) { JrpcgenUnionArm a = (JrpcgenUnionArm) arms.nextElement(); if ( (a.value == null) && (a.element.identifier != null) ) { out.print(" "); if ( !firstArm ) { out.print("else "); } out.println("{"); out.print(" "); out.print(codingMethod(a.element, true)); out.println(" }"); } } } out.println(" }"); out.println(); out.println(" public void xdrDecode(XdrDecodingStream xdr)"); out.println(" throws OncRpcException, IOException {"); out.print(codingMethod(u.descriminant, false)); if ( !boolDescriminant ) { // // Produce code using an ordinary switch statement... // out.println(" switch ( " + u.descriminant.identifier + " ) {"); arms = u.elements.elements(); while ( arms.hasMoreElements() ) { JrpcgenUnionArm a = (JrpcgenUnionArm) arms.nextElement(); if ( a.value != null ) { out.println(" case " + checkForEnumValue(a.value) + ":"); } else { // // It's the default arm. // out.println(" default:"); } // // Only emit code if arm does not map to another arm. // if ( a.element != null ) { if ( a.element.identifier != null ) { // // Arm does not contain void, so we need to spit out // encoding instructions. // out.print(" "); out.print(codingMethod(a.element, false)); } out.println(" break;"); } } out.println(" }"); } else { // // boolean descriminant: here we can have at most two arms, guess // why. // boolean firstArm = true; arms = u.elements.elements(); while ( arms.hasMoreElements() ) { JrpcgenUnionArm a = (JrpcgenUnionArm) arms.nextElement(); if ( a.value == null ) { // // Skip default branch this time... // continue; } if ( a.element.identifier != null ) { // // Arm contains data, so we need to create encoding // instructions. // out.print(" "); if ( !firstArm ) { out.print("else "); } else { firstArm = false; } out.println("if ( " + u.descriminant.identifier + " == " + checkForEnumValue(a.value) + " ) {"); out.print(" "); out.print(codingMethod(a.element, false)); out.println(" }"); } } arms = u.elements.elements(); while ( arms.hasMoreElements() ) { JrpcgenUnionArm a = (JrpcgenUnionArm) arms.nextElement(); if ( (a.value == null) && (a.element.identifier != null) ) { out.print(" "); if ( !firstArm ) { out.print("else "); } out.println("{"); out.print(" "); out.print(codingMethod(a.element, false)); out.println(" }"); } } } out.println(" }"); // // Close class... // out.println(); out.println("}"); closeJavaSourceFile(); } /** * Generate a source code file containing a wrapper class for a typedef * defined in a x-file. * * @param d {@link JrpcgenDeclaration Description} of XDR typedef. */ public static void dumpTypedef(JrpcgenDeclaration d) { // // Create new source code file containing a Java class representing // the XDR struct. // PrintWriter out = createJavaSourceFile(d.identifier); out.print("public class " + d.identifier + " implements XdrAble"); if ( makeSerializable ) { out.print(", java.io.Serializable"); } out.println(" {"); out.println(); String paramType = checkForSpecials(d.type); if ( ((d.kind == JrpcgenDeclaration.FIXEDVECTOR) || (d.kind == JrpcgenDeclaration.DYNAMICVECTOR)) && !d.type.equals("String") ) { paramType += " []"; } out.print(" public " + paramType + " value;"); out.println(); // // Generate serial version unique identifier // if ( makeSerializable ) { JrpcgenSHA hash = createSHA(d.identifier); hash.update(d.type); hash.update(d.kind); out.println(); out.println(" private static final long serialVersionUID = " + hash.getHash() + "L;"); } // // Now generate code for encoding and decoding this class (typedef). // JrpcgenDeclaration dstar = null; try { dstar = (JrpcgenDeclaration) d.clone(); } catch ( CloneNotSupportedException e ) { throw(new RuntimeException("fatal: can not clone JrpcgenDeclaration")); } dstar.identifier = "value"; out.println(); out.println(" public " + d.identifier + "() {"); out.println(" }"); out.println(); out.println(" public " + d.identifier + "(" + paramType + " value) {"); out.println(" this.value = value;"); out.println(" }"); out.println(); out.println(" public " + d.identifier + "(XdrDecodingStream xdr)"); out.println(" throws OncRpcException, IOException {"); out.println(" xdrDecode(xdr);"); out.println(" }"); out.println(); out.println(" public void xdrEncode(XdrEncodingStream xdr)"); out.println(" throws OncRpcException, IOException {"); out.print(codingMethod(dstar, true)); out.println(" }"); out.println(); out.println(" public void xdrDecode(XdrDecodingStream xdr)"); out.println(" throws OncRpcException, IOException {"); out.print(codingMethod(dstar, false)); out.println(" }"); // // Close class... // out.println(); out.println("}"); closeJavaSourceFile(); } /** * Generate source code files for all structures, unions and enumerations * as well as constants. All constants, which do not belong to enumerations, * are emitted to a single interface. */ public static void dumpClasses() { Enumeration globals = globalIdentifiers.elements(); while ( globals.hasMoreElements() ) { Object o = globals.nextElement(); if ( o instanceof JrpcgenEnum ) { dumpEnum((JrpcgenEnum) o); } else if ( o instanceof JrpcgenStruct ) { dumpStruct((JrpcgenStruct) o); } else if ( o instanceof JrpcgenUnion ) { dumpUnion((JrpcgenUnion) o); } else if ( o instanceof JrpcgenDeclaration ) { dumpTypedef((JrpcgenDeclaration) o); } } } /** * Generate source code for client-side stub methods for a particular * remote program version. The client-side stub methods take the * parameter(s) from the caller, encode them and throw them over to the * server. After receiving a reply, they will unpack and return it as * the outcome of the method call. * * @param out Printer writer to send source code to. * @param versionInfo Information about the remote program version for * which source code is to be generated. */ public static void dumpClientStubMethods(PrintWriter out, JrpcgenVersionInfo versionInfo) { int size = versionInfo.procedures.size(); for ( int idx = 0; idx < size; ++idx ) { JrpcgenProcedureInfo proc = (JrpcgenProcedureInfo) versionInfo.procedures.elementAt(idx); // // First spit out the stub method. While we don't need to // fiddle around with the data types of the method's // parameter(s) and result, we later have to care about // some primitive data types when serializing them. // String resultType = checkForSpecials(proc.resultType); out.println(" /**"); out.println(" * Call remote procedure " + proc.procedureId + "."); // // If there are no parameters, skip the parameter documentation // section, otherwise dump javadoc @param entries for every // parameter encountered. // if ( proc.parameters != null ) { Enumeration params = proc.parameters.elements(); while ( params.hasMoreElements() ) { JrpcgenParamInfo param = (JrpcgenParamInfo) params.nextElement(); out.println(" * @param " + param.parameterName + " parameter (of type " + param.parameterType + ") to the remote procedure call."); } } // // Only generate javadoc for result, when it is non-void. // if ( proc.resultType.compareTo("void") != 0 ) { out.println(" * @return Result from remote procedure call (of type " + proc.resultType + ")."); } out.println(" * @throws OncRpcException if an ONC/RPC error occurs."); out.println(" * @throws IOException if an I/O error occurs."); out.println(" */"); out.print (" public " + resultType + " " + proc.procedureId + "("); // // If the remote procedure does not have any parameters, then // parameters will be null. Otherwise it contains a vector with // information about the individual parameters, which we use // in order to generate the parameter list. Note that all // parameters are named at this point (they will either have a // user supplied name, or an automatically generated one). // int paramsKind; if ( proc.parameters != null ) { int psize = proc.parameters.size(); for ( int pidx = 0; pidx < psize; ++pidx ) { JrpcgenParamInfo paramInfo = (JrpcgenParamInfo) proc.parameters.elementAt(pidx); if ( pidx > 0 ) { out.print(", "); } out.print(checkForSpecials(paramInfo.parameterType)); out.print(" "); out.print(paramInfo.parameterName); } // // Now find out what kind of parameter(s) we have. In case // the remote procedure only expects a single parameter, check // whether it is a base type. In this case we later need to // wrap the single parameter. If the remote procedure expects // more than a single parameter, then we always need a // XDR wrapper. // if ( psize > 1 ) { paramsKind = PARAMS_MORE; } else { // // psize must be equal to one, otherwise proc.parameters // must have been null. // String firstParamType = ((JrpcgenParamInfo)proc.parameters.elementAt(0)) .parameterType; if ( xdrBaseType(checkForSpecials(firstParamType)) == null ) { // // No, it is not a base type, so we don't need one // of the special XDR wrapper classes. // paramsKind = PARAMS_SINGLE; } else { // // The single parameter to the remote procedure is // a base type, so we will later need a wrapper. // paramsKind = PARAMS_SINGLE_BASETYPE; } } } else { // // Remote procedure does not expect parameters at all. // paramsKind = PARAMS_VOID; } out.println(")"); out.println(" throws OncRpcException, IOException {"); // // Do generate code for wrapping parameters here, if necessary. // String xdrParamsName = null; // Name of variable representing XDR-able arguments switch ( paramsKind ) { case PARAMS_VOID: xdrParamsName = "args$"; out.println(" XdrVoid args$ = XdrVoid.XDR_VOID;"); break; case PARAMS_SINGLE: { JrpcgenParamInfo paramInfo = (JrpcgenParamInfo) proc.parameters.elementAt(0); xdrParamsName = paramInfo.parameterName; // // We do not need to emit an args$ declaration here, as we // can immediately make use of the one and only argument // the remote procedure expects. // break; } case PARAMS_SINGLE_BASETYPE: { JrpcgenParamInfo paramInfo = (JrpcgenParamInfo) proc.parameters.elementAt(0); xdrParamsName = "args$"; String xdrParamsType = xdrBaseType(checkForSpecials(paramInfo.parameterType)); out.println(" " + xdrParamsType + " args$ = new " + xdrParamsType + "(" + paramInfo.parameterName + ");"); break; } case PARAMS_MORE: xdrParamsName = "args$"; out.println(" class XdrAble$ implements XdrAble {"); int psize = proc.parameters.size(); for ( int pidx = 0; pidx < psize; ++pidx ) { JrpcgenParamInfo pinfo = (JrpcgenParamInfo) proc.parameters.elementAt(pidx); out.println(" public " + checkForSpecials(pinfo.parameterType) + " " + pinfo.parameterName + ";"); } out.println(" public void xdrEncode(XdrEncodingStream xdr)"); out.println(" throws OncRpcException, IOException {"); // // Emit serialization code for all parameters. // Note that not we do not need to deal with all kinds of // parameters here, as things like "int<5>" are invalid, // a typedef declaration is then necessary. // JrpcgenDeclaration decl = new JrpcgenDeclaration(null, null); for ( int pidx = 0; pidx < psize; ++pidx ) { JrpcgenParamInfo pinfo = (JrpcgenParamInfo) proc.parameters.elementAt(pidx); decl.kind = JrpcgenDeclaration.SCALAR; decl.identifier = pinfo.parameterName; decl.type = pinfo.parameterType; out.print(" "); out.print(codingMethod(decl, true)); } out.println(" }"); out.println(" public void xdrDecode(XdrDecodingStream xdr)"); out.println(" throws OncRpcException, IOException {"); out.println(" }"); out.println(" };"); out.println(" XdrAble$ args$ = new XdrAble$();"); for ( int pidx = 0; pidx < psize; ++pidx ) { JrpcgenParamInfo pinfo = (JrpcgenParamInfo) proc.parameters.elementAt(pidx); out.println(" args$." + pinfo.parameterName + " = " + pinfo.parameterName + ";"); } break; } // // Check the return data type of the result to be of one of // the base data types, like int, boolean, etc. In this case we // have to unwrap the result from one of the special XDR wrapper // classes and return the base data type instead. // String xdrResultType = xdrBaseType(resultType); // // Handle the result of the method: similiar to what we did // above. However, in all other cases we always need to // create a result object, regardless of whether we have to // deal with a basic data type (except void) or with some // "complex" data type. // if ( resultType.equals("void") ) { out.println(" XdrVoid result$ = XdrVoid.XDR_VOID;"); } else if ( xdrResultType != null ) { out.println(" " + xdrResultType + " result$ = new " + xdrResultType + "();"); } else { out.println(" " + resultType + " result$ = new " + resultType + "();"); } // // Now emit the real ONC/RPC call using the (optionally // wrapped) parameter and (optionally wrapped) result. // if ( clampProgAndVers ) { out.println(" client.call(" + baseClassname + "." + proc.procedureId + ", " + baseClassname + "." + versionInfo.versionId + ", " + xdrParamsName + ", result$);"); } else { out.println(" client.call(" + baseClassname + "." + proc.procedureId + ", client.getVersion(), " + xdrParamsName + ", result$);"); } // // In case of a wrapped result we need to return the value // of the wrapper, otherwise we can return the result // itself (which then is not a base data type). As a special // case, we can not return void values...anyone for a // language design with first class void objects?! // if ( xdrResultType != null ) { // // Data type of result is a Java base data type, so we need // to unwrap the XDR-able result -- if it's not a void, which // we do not need to return at all. // if ( !resultType.equals("void") ) { out.println(" return result$." + resultType.toLowerCase() + "Value();"); } } else { // // Data type of result is a complex type (class), so we // do not unwrap it but can return it immediately. // out.println(" return result$;"); } // // Close the stub method (just as a hint, as it is // getting rather difficult to see what code is produced // at this stage...) // out.println(" }"); out.println(); } } /** * Generate source code for the client stub proxy object. This client * stub proxy object is then used by client applications to make remote * procedure (aka method) calls to an ONC/RPC server. */ public static void dumpClient(JrpcgenProgramInfo programInfo) { // // When several versions of a program are defined, we search for the // latest and greatest one. This highest version number ist then // used to create the necessary OncRpcClient for // communication when the client proxy stub is constructed. // int version = Integer.parseInt( ((JrpcgenVersionInfo)programInfo.versions.elementAt(0)).versionNumber); int versionSize = programInfo.versions.size(); for ( int idx = 1; idx < versionSize; ++idx ) { int anotherVersion = Integer.parseInt( ((JrpcgenVersionInfo)programInfo.versions.elementAt(idx)).versionNumber); if ( anotherVersion > version ) { version = anotherVersion; } } // // Create new source code file containing a Java class representing // the XDR struct. // In case we have several programs defines, build the source code // file name from the program's name (this case is identified by a // null clientClass name). // String clientClass = jrpcgen.clientClass; if ( clientClass == null ) { clientClass = baseClassname + "_" + programInfo.programId + "_Client"; System.out.println("CLIENT: " + clientClass); } PrintWriter out = createJavaSourceFile(clientClass); out.println("import java.net.InetAddress;"); out.println(); out.println("/**"); out.println(" * The class " + clientClass + " implements the client stub proxy"); out.println(" * for the " + programInfo.programId + " remote program. It provides method stubs"); out.println(" * which, when called, in turn call the appropriate remote method (procedure)."); out.println(" */"); out.println("public class " + clientClass + " extends OncRpcClientStub {"); out.println(); // // Generate constructors... // out.println(" /**"); out.println(" * Constructs a " + clientClass + " client stub proxy object"); out.println(" * from which the " + programInfo.programId + " remote program can be accessed."); out.println(" * @param host Internet address of host where to contact the remote program."); out.println(" * @param protocol {@link org.acplt.oncrpc.OncRpcProtocols Protocol} to be"); out.println(" * used for ONC/RPC calls."); out.println(" * @throws OncRpcException if an ONC/RPC error occurs."); out.println(" * @throws IOException if an I/O error occurs."); out.println(" */"); out.println(" public " + clientClass + "(InetAddress host, int protocol)"); out.println(" throws OncRpcException, IOException {"); out.println(" super(host, " + baseClassname + "." + programInfo.programId + ", " + version + ", 0, protocol);"); out.println(" }"); out.println(); out.println(" /**"); out.println(" * Constructs a " + clientClass + " client stub proxy object"); out.println(" * from which the " + programInfo.programId + " remote program can be accessed."); out.println(" * @param host Internet address of host where to contact the remote program."); out.println(" * @param port Port number at host where the remote program can be reached."); out.println(" * @param protocol {@link org.acplt.oncrpc.OncRpcProtocols Protocol} to be"); out.println(" * used for ONC/RPC calls."); out.println(" * @throws OncRpcException if an ONC/RPC error occurs."); out.println(" * @throws IOException if an I/O error occurs."); out.println(" */"); out.println(" public " + clientClass + "(InetAddress host, int port, int protocol)"); out.println(" throws OncRpcException, IOException {"); out.println(" super(host, " + baseClassname + "." + programInfo.programId + ", " + version + ", port, protocol);"); out.println(" }"); out.println(); out.println(" /**"); out.println(" * Constructs a " + clientClass + " client stub proxy object"); out.println(" * from which the " + programInfo.programId + " remote program can be accessed."); out.println(" * @param client ONC/RPC client connection object implementing a particular"); out.println(" * protocol."); out.println(" * @throws OncRpcException if an ONC/RPC error occurs."); out.println(" * @throws IOException if an I/O error occurs."); out.println(" */"); out.println(" public " + clientClass + "(OncRpcClient client)"); out.println(" throws OncRpcException, IOException {"); out.println(" super(client);"); out.println(" }"); out.println(); out.println(" /**"); out.println(" * Constructs a " + clientClass + " client stub proxy object"); out.println(" * from which the " + programInfo.programId + " remote program can be accessed."); out.println(" * @param host Internet address of host where to contact the remote program."); out.println(" * @param program Remote program number."); out.println(" * @param version Remote program version number."); out.println(" * @param protocol {@link org.acplt.oncrpc.OncRpcProtocols Protocol} to be"); out.println(" * used for ONC/RPC calls."); out.println(" * @throws OncRpcException if an ONC/RPC error occurs."); out.println(" * @throws IOException if an I/O error occurs."); out.println(" */"); out.println(" public " + clientClass + "(InetAddress host, int program, int version, int protocol)"); out.println(" throws OncRpcException, IOException {"); out.println(" super(host, program, version, 0, protocol);"); out.println(" }"); out.println(); out.println(" /**"); out.println(" * Constructs a " + clientClass + " client stub proxy object"); out.println(" * from which the " + programInfo.programId + " remote program can be accessed."); out.println(" * @param host Internet address of host where to contact the remote program."); out.println(" * @param program Remote program number."); out.println(" * @param version Remote program version number."); out.println(" * @param port Port number at host where the remote program can be reached."); out.println(" * @param protocol {@link org.acplt.oncrpc.OncRpcProtocols Protocol} to be"); out.println(" * used for ONC/RPC calls."); out.println(" * @throws OncRpcException if an ONC/RPC error occurs."); out.println(" * @throws IOException if an I/O error occurs."); out.println(" */"); out.println(" public " + clientClass + "(InetAddress host, int program, int version, int port, int protocol)"); out.println(" throws OncRpcException, IOException {"); out.println(" super(host, program, version, port, protocol);"); out.println(" }"); out.println(); // // Generate method stubs... This is getting hairy in case someone // uses basic data types as parameters or the procedure's result. // In these cases we need to encapsulate these basic data types in // XDR-able data types. // for ( int versionIdx = 0; versionIdx < versionSize; ++versionIdx ) { JrpcgenVersionInfo versionInfo = (JrpcgenVersionInfo) programInfo.versions.elementAt(versionIdx); dumpClientStubMethods(out, versionInfo); } // // Close class...done! // out.println("}"); closeJavaSourceFile(); } /** * */ public static void dumpServerStubMethodCall(PrintWriter out, JrpcgenProcedureInfo proc) { // // Check for special return types, like enumerations, which we // map to their corresponding Java base data type. // String resultType = checkForSpecials(proc.resultType); // // If the remote procedure does not have any parameters, then // parameters will be null. Otherwise it contains a vector with // information about the individual parameters, which we use // in order to generate the parameter list. Note that all // parameters are named at this point (they will either have a // user supplied name, or an automatically generated one). // int paramsKind; if ( proc.parameters != null ) { int psize = proc.parameters.size(); // // Now find out what kind of parameter(s) we have. In case // the remote procedure only expects a single parameter, check // whether it is a base type. In this case we later need to // wrap the single parameter. If the remote procedure expects // more than a single parameter, then we always need a // XDR wrapper. // if ( psize > 1 ) { paramsKind = PARAMS_MORE; } else { // // psize must be equal to one, otherwise proc.parameters // must have been null. // String firstParamType = ((JrpcgenParamInfo)proc.parameters.elementAt(0)) .parameterType; if ( xdrBaseType(checkForSpecials(firstParamType)) == null ) { // // No, it is not a base type, so we don't need one // of the special XDR wrapper classes. // paramsKind = PARAMS_SINGLE; } else { // // The single parameter to the remote procedure is // a base type, so we will later need a wrapper. // paramsKind = PARAMS_SINGLE_BASETYPE; } } } else { // // Remote procedure does not expect parameters at all. // paramsKind = PARAMS_VOID; } // // Do generate code for unwrapping here, if necessary. // String params = ""; switch ( paramsKind ) { case PARAMS_VOID: // // Almost nothing to do here -- well, we need to retrieve nothing // so the RPC layer can do its book keeping. // out.println(" call.retrieveCall(XdrVoid.XDR_VOID);"); params = withCallInfo ? "call" : ""; break; case PARAMS_SINGLE: { // // Only a single parameter, which is in addition immediately // ready for serialization. // JrpcgenParamInfo paramInfo = (JrpcgenParamInfo) proc.parameters.elementAt(0); out.println(" " + paramInfo.parameterType + " args$ = new " + paramInfo.parameterType + "();"); out.println(" call.retrieveCall(args$);"); params = (withCallInfo ? "call, " : "") + "args$"; break; } case PARAMS_SINGLE_BASETYPE: { // // Only a single parameter, but we have to unwrap it first. // JrpcgenParamInfo paramInfo = (JrpcgenParamInfo) proc.parameters.elementAt(0); String paramsType = checkForSpecials(paramInfo.parameterType); String xdrParamsType = xdrBaseType(paramsType); out.println(" " + xdrParamsType + " args$ = new " + xdrParamsType + "();"); out.println(" call.retrieveCall(args$);"); params = (withCallInfo ? "call, " : "") + "args$." + paramsType.toLowerCase() + "Value()"; break; } case PARAMS_MORE: { // // // StringBuffer paramsBuff = new StringBuffer(); out.println(" class XdrAble$ implements XdrAble {"); int psize = proc.parameters.size(); for ( int pidx = 0; pidx < psize; ++pidx ) { JrpcgenParamInfo pinfo = (JrpcgenParamInfo) proc.parameters.elementAt(pidx); out.println(" public " + checkForSpecials(pinfo.parameterType) + " " + pinfo.parameterName + ";"); } out.println(" public void xdrEncode(XdrEncodingStream xdr)"); out.println(" throws OncRpcException, IOException {"); out.println(" }"); out.println(" public void xdrDecode(XdrDecodingStream xdr)"); out.println(" throws OncRpcException, IOException {"); // // Emit serialization code for all parameters. // Note that not we do not need to deal with all kinds of // parameters here, as things like "int<5>" are invalid, // a typedef declaration is then necessary. // JrpcgenDeclaration decl = new JrpcgenDeclaration(null, null); for ( int pidx = 0; pidx < psize; ++pidx ) { JrpcgenParamInfo pinfo = (JrpcgenParamInfo) proc.parameters.elementAt(pidx); decl.kind = JrpcgenDeclaration.SCALAR; decl.identifier = pinfo.parameterName; decl.type = pinfo.parameterType; out.print(" "); out.print(codingMethod(decl, false)); } out.println(" }"); out.println(" };"); out.println(" XdrAble$ args$ = new XdrAble$();"); out.println(" call.retrieveCall(args$);"); if ( withCallInfo ) { if ( psize > 0 ) { paramsBuff.append("call, "); } else { paramsBuff.append("call"); } } for ( int pidx = 0; pidx < psize; ++pidx ) { JrpcgenParamInfo pinfo = (JrpcgenParamInfo) proc.parameters.elementAt(pidx); if ( pidx > 0 ) { paramsBuff.append(", "); } paramsBuff.append("args$."); paramsBuff.append(pinfo.parameterName); } params = paramsBuff.toString(); break; } } // // Check the return data type of the result to be of one of // the base data types, like int, boolean, etc. In this case we // have to unwrap the result from one of the special XDR wrapper // classes and return the base data type instead. // String xdrResultType = xdrBaseType(resultType); if ( resultType.equals("void") ) { // // It's a remote procedure, so it does return simply nothing. // We use the singleton XDR_VOID to return a "nothing". // out.println(" " + proc.procedureId + "(" + params + ");"); out.println(" call.reply(XdrVoid.XDR_VOID);"); } else if ( xdrResultType != null ) { // // The return type is some Java base data type, so we need to // wrap the return value before we can serialize it. // out.println(" " + xdrResultType + " result$ = new " + xdrResultType + "(" + proc.procedureId + "(" + params + "));"); out.println(" call.reply(result$);"); } else { // // The return type is a complex type which supports XdrAble. // out.println(" " + resultType + " result$ = " + proc.procedureId + "(" + params + ");"); out.println(" call.reply(result$);"); } } /** * Generate public abstract method signatures for all remote procedure * calls. This ensures that they have to be implemented before any * derived server class gets usefull. */ public static void dumpServerStubMethods(PrintWriter out, JrpcgenVersionInfo versionInfo) { int procSize = versionInfo.procedures.size(); for ( int idx = 0; idx < procSize; ++idx ) { JrpcgenProcedureInfo proc = (JrpcgenProcedureInfo) versionInfo.procedures.elementAt(idx); // // Fold enumerations et cetera back to their Java base data types. // String resultType = checkForSpecials(proc.resultType); // // Now emit the method signature, checking each argument for // specials, like enumerations. Also take care of no parameters // at all... Fortunately, this is relatively easy as we do not // need to care about parameter wrapping/unwrapping here. // out.print(" public abstract " + resultType + " " + proc.procedureId + "("); if ( proc.parameters != null ) { if ( withCallInfo ) { out.print("OncRpcCallInformation call$, "); } int psize = proc.parameters.size(); for ( int pidx = 0; pidx < psize; ++pidx ) { JrpcgenParamInfo paramInfo = (JrpcgenParamInfo) proc.parameters.elementAt(pidx); if ( pidx > 0 ) { out.print(", "); } out.print(checkForSpecials(paramInfo.parameterType)); out.print(" "); out.print(paramInfo.parameterName); } } else if ( withCallInfo ) { out.print("OncRpcCallInformation call$"); } out.println(");"); out.println(); } } /** * */ public static void dumpServer(JrpcgenProgramInfo programInfo) { // // Create new source code file containing a Java class representing // the XDR struct. // In case we have several programs defines, build the source code // file name from the program's name (this case is identified by a // null clientClass name). // String serverClass = jrpcgen.serverClass; if ( serverClass == null ) { serverClass = baseClassname + "_" + programInfo.programId + "_ServerStub"; } PrintWriter out = createJavaSourceFile(serverClass); out.println("import java.net.InetAddress;"); out.println(); out.println("import org.acplt.oncrpc.server.*;"); out.println(); out.println("/**"); out.println(" */"); out.println("public abstract class " + serverClass + " extends OncRpcServerStub implements OncRpcDispatchable {"); out.println(); // // Generate constructor(s)... // out.println(" public " + serverClass + "()"); out.println(" throws OncRpcException, IOException {"); out.println(" this(0);"); out.println(" }"); out.println(); out.println(" public " + serverClass + "(int port)"); out.println(" throws OncRpcException, IOException {"); out.println(" this(null, port);"); out.println(" }"); out.println(); out.println(" public " + serverClass + "(InetAddress bindAddr, int port)"); out.println(" throws OncRpcException, IOException {"); // // For every version specified, create both UDP and TCP-based // transports. // out.println(" info = new OncRpcServerTransportRegistrationInfo [] {"); int versionSize = programInfo.versions.size(); for ( int versionIdx = 0; versionIdx < versionSize; ++versionIdx ) { JrpcgenVersionInfo versionInfo = (JrpcgenVersionInfo) programInfo.versions.elementAt(versionIdx); out.println(" new OncRpcServerTransportRegistrationInfo(" + baseClassname + "." + programInfo.programId + ", " + versionInfo.versionNumber + "),"); } out.println(" };"); out.println(" transports = new OncRpcServerTransport [] {"); out.println(" new OncRpcUdpServerTransport(this, bindAddr, port, info, 32768),"); out.println(" new OncRpcTcpServerTransport(this, bindAddr, port, info, 32768)"); out.println(" };"); // // Finish constructor method... // out.println(" }"); out.println(); // // Generate dispatcher code... // out.println(" public void dispatchOncRpcCall(OncRpcCallInformation call, int program, int version, int procedure)"); out.println(" throws OncRpcException, IOException {"); for ( int versionIdx = 0; versionIdx < versionSize; ++versionIdx ) { JrpcgenVersionInfo versionInfo = (JrpcgenVersionInfo) programInfo.versions.elementAt(versionIdx); out.print(versionIdx == 0 ? " " : " } else "); out.println("if ( version == " + versionInfo.versionNumber + " ) {"); int procSize = versionInfo.procedures.size(); out.println(" switch ( procedure ) {"); for ( int procIdx = 0; procIdx < procSize; ++procIdx ) { // // Emit case arms for every procedure defined. We have to // take care that the procedure number might be a constant // comming from an enumeration: in this case we need also to // dump the enclosure. // JrpcgenProcedureInfo procInfo = (JrpcgenProcedureInfo) versionInfo.procedures.elementAt(procIdx); out.println(" case " + checkForEnumValue(procInfo.procedureNumber) + ": {"); dumpServerStubMethodCall(out, procInfo); out.println(" break;"); out.println(" }"); } out.println(" default:"); out.println(" call.failProcedureUnavailable();"); out.println(" }"); } out.println(" } else {"); out.println(" call.failProgramUnavailable();"); out.println(" }"); out.println(" }"); out.println(); // // Generate the stub methods for all specified remote procedures. // for ( int versionIdx = 0; versionIdx < versionSize; ++versionIdx ) { JrpcgenVersionInfo versionInfo = (JrpcgenVersionInfo) programInfo.versions.elementAt(versionIdx); dumpServerStubMethods(out, versionInfo); } // // Close class...done! // out.println("}"); closeJavaSourceFile(); } /** * Create the source code files based on the parsed information from the * x-file. */ public static void dumpFiles() { dumpConstants(); dumpClasses(); for ( int i = 0; i < programInfos.size(); ++i ) { JrpcgenProgramInfo progInfo = (JrpcgenProgramInfo) programInfos.elementAt(i); if ( !noClient ) { dumpClient(progInfo); } if ( !noServer ) { dumpServer(progInfo); } } } /** * The main part of jrpcgen where all things start. */ public static void main(String[] args) { // // First parse the command line (options)... // int argc = args.length; int argIdx = 0; for ( ; argIdx < argc; ++argIdx ) { // // Check to see whether this is an option... // String arg = args[argIdx]; if ( (arg.length() > 0) && (arg.charAt(0) != '-') ) { break; } // // ...and which option is it? // if ( arg.equals("-d") ) { // -d if ( ++argIdx >= argc ) { System.out.println("jrpcgen: missing directory"); System.exit(1); } destinationDir = new File(args[argIdx]); } else if ( arg.equals("-package") || arg.equals("-p") ) { // -p if ( ++argIdx >= argc ) { System.out.println("jrpcgen: missing package name"); System.exit(1); } packageName = args[argIdx]; } else if ( arg.equals("-c") ) { // -c if ( ++argIdx >= argc ) { System.out.println("jrpcgen: missing client class name"); System.exit(1); } clientClass = args[argIdx]; } else if ( arg.equals("-s") ) { // -s if ( ++argIdx >= argc ) { System.out.println("jrpcgen: missing server class name"); System.exit(1); } serverClass = args[argIdx]; } else if ( arg.equals("-ser") ) { makeSerializable = true; } else if ( arg.equals("-bean") ) { makeSerializable = true; makeBean = true; } else if ( arg.equals("-initstrings") ) { initStrings = true; } else if ( arg.equals("-noclamp") ) { clampProgAndVers = false; } else if ( arg.equals("-withcallinfo") ) { withCallInfo = true; } else if ( arg.equals("-debug") ) { debug = true; } else if ( arg.equals("-nobackup") ) { noBackups = true; } else if ( arg.equals("-noclient") ) { noClient = true; } else if ( arg.equals("-noserver") ) { noServer = true; } else if ( arg.equals("-parseonly") ) { parseOnly = true; } else if ( arg.equals("-verbose") ) { verbose = true; } else if ( arg.equals("-version") ) { System.out.println("jrpcgen version \"" + VERSION + "\""); System.exit(1); } else if ( arg.equals("-help") || arg.equals("-?") ) { printHelp(); System.exit(1); } else if ( arg.equals("--") ) { // // End of options... // ++argIdx; break; } else { // // It's an unknown option! // System.out.println("Unrecognized option: " + arg); System.exit(1); } } // // Otherwise we regard the current command line argument to be the // name of the x-file to compile. Check, that there is exactly one // x-file specified. // if ( (argIdx >= argc) || (argIdx < argc - 1) ) { printHelp(); System.exit(1); } String xfilename = args[argIdx]; xFile = new File(".", xfilename); // // Try to parse the file and generate the different class source // code files... // try { doParse(); } catch ( Throwable t ) { System.out.println(t.getMessage()); // // Exit application with non-zero outcome, so in case jrpcgen is // used as part of, for instance, a make process, such tools can // detect that there was a problem. // System.exit(1); } } /** * The real parsing and code generation part. This has been factored out * of main() in order to make it available as an Ant task. */ public static void doParse() throws FileNotFoundException, Exception { // // Get the base name for the client and server classes, it is derived // from the filename. // if ( baseClassname == null ) { String name = xFile.getName(); int dotIdx = name.lastIndexOf('.'); if ( dotIdx < 0 ) { baseClassname = name; } else { baseClassname = name.substring(0, dotIdx); } } // // // FileInputStream in = null; try { in = new FileInputStream(xFile.getCanonicalPath()); } catch ( FileNotFoundException e ) { throw(new FileNotFoundException("jrpcgen: can not open source x-file \"" + xFile.getCanonicalPath() + "\"")); } JrpcgenScanner scanner = new JrpcgenScanner(in); JrpcgenParser parser = new JrpcgenParser(scanner); jrpcgen.globalIdentifiers.put("TRUE", new JrpcgenConst("TRUE", "true")); jrpcgen.globalIdentifiers.put("FALSE", new JrpcgenConst("FALSE", "false")); try { Symbol sym = parser.parse(); if ( !parseOnly ) { if ( programInfos.size() <= 1 ) { if ( clientClass == null ) { clientClass = baseClassname + "Client"; } if ( serverClass == null ) { serverClass = baseClassname + "ServerStub"; } } dumpFiles(); } } catch ( JrpcgenParserException pe ) { throw(new Exception("jrpcgen: compilation aborted (" + pe.getMessage() + ")")); } } } /** * The class JrpcgenEnDecodingInfo contains information which * is necessary to generate source code calling appropriate XDR encoding * and decoding methods. * * @version $Revision: 1.6 $ $Date: 2007/05/29 19:38:30 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ class JrpcgenEnDecodingInfo { /** * Construct a JrpcgenEnDecodingInfo object containing * information for generating source code for encoding and decoding * of XDR/Java base data types. * * @param syllable Syllable of encoding/decoding method. * @param encodingOptions Optional parameters necessary to encode * base data type. * @param decodingOptions Optional parameters necessary to decode * base data type. */ public JrpcgenEnDecodingInfo(String syllable, String encodingOptions, String decodingOptions) { this.syllable = syllable; this.encodingOptions = encodingOptions; this.decodingOptions = decodingOptions; } /** * (Type) syllable of the encoding or decoding method. The full name * of the encoding or decoding method is always in the form of * "xdrEncodeXXX(...)" or "xdrDecodeXXX(...)", where "XXX" is the * syllable contained in this attribute. */ public String syllable; /** * Optional parameters to use when encoding a base data type. This * typically includes the size parameter for encoding fixed-size * vectors/arrays. When this attribute is not null, then * these parameters need to be appended. The attribute never contains * a leading parameter separator (aka "comma"). */ public String encodingOptions; /** * Optional parameters to use when decoding a base data type. This * typically includes the size parameter for decoding fixed-size * vectors/arrays. When this attribute is not null, then * these parameters need to be appended. The attribute never contains * a leading parameter separator (aka "comma"). */ public String decodingOptions; } // End of file jrpcgen.java remotetea-1.0.7/src/org/acplt/oncrpc/apps/jrpcgen/package.html0000644005374700003410000001623110627063014025443 0ustar piccainstrumentation jrpcgen for ONC/RPC Java package jrpcgen for ONC/RPC Java package.

This package provides a Java-based rpcgen RPC protocol compiler called "jrpcgen". jrpcgen is a Java-based tool that generates source code of Java classes to implement an RPC protocol. The input to jrpcgen is a language similiar to C (but more probably much more similiar to FORTRAN) known as the RPC language (Remote Procedure Call Language). Because the files containing RPC language are typically tagged with ".x" they are called "x-files" throughout this documentation.

Usage:

jrpcgen [-options] x-file

where options include:

-c classname
Specify class name of client proxy stub.
-d directory
Specify directory where to place generated class source code files.
-p package name or -package package name
Specify package name for generated source code files.
-s classname
Specify class name of server proxy stub.
-ser
tag classes generated for XDR structs, XDR unions and XDR typedefs as serializable. Also automatically generates serialVersionUID using the SHA-1 algorithm.
-bean
generate accessors for usage as bean, implies -ser.
-noclamp
do not clamp version number in client method stubs.
-initstrings
automatically initialize all Strings as empty strings (""). Note that this may lead to lazy programming; better make explicitly sure that every member of a struct gets initialized properly before encoding the struct.
-nobackup
Do not make backups of old source code files for which new source code is generated.
-noclient
Do not create source code for the client proxy stub.
-noserver
Do not create source code for the server proxy stub.
-parseonly
Parse x-file only but do not generate source code files.
-verbose
Enable verbose output about what the jrpcgen compiler is doing.
-version
Print jrpcgen version.
-? or -help
Print this help.
--
End options.

Notes

To cite the man pages for rpcgen(1): The RPC Language does not support nesting of structures. As a work-around, structures can be declared at the top-level, and their name used inside other structures in order to achieve the same effect. Name clashes can occur when using program definitions, since the apparent scoping does not really apply. Most of these can be avoided by giving unique names for programs, versions, procedures, and types. And I thought that the RFC was written before rpcgen to reflect reality but not wishes for further development.

jrpcgen can process the same x-files as its SunOS4.1-based rpcgen counterpart. Or at least it should. The Java language as well as the Java environment cause some slight differences in the code generated with respect to the typical C code emitted by rpcgen. Please also refer to the demo.x example in tests.org.acplt.oncrpc.jrpcgen for the inner details.

However, jrpcgen currently does not support C preprocessor directives, as rpcgen does my running cpp first on the x-file. If you need to achieve the same effect, first run cpp by hand (pardon: makefile) and pipe the result into jrpcgen.

  • All global constants are put into one public interface with the same name as the x-file. Global constants are constants either defined using "const" or program and version constants. If a x-file named demo.x defines a constant FOO, then its Java counterpart will be accessible as demo.FOO.

  • All enumeration members of a particular enumeration are put into a public interface with the same name as the enumeration. For example: enum FOO { foo }; results in a public interface FOO with a public static final int foo. The enumeration members are accessed like FOO.foo. Within the generated Java code, wherever the enumeration type is used, a Java base data type of int is used instead to avoid cluttering the code.

  • For each typedef the jrpcgen protocol compiler emits a class source file of the same name. For instance, typedef string STRING<>; results in class STRING. Such classes always contain exactly one attribute named value. This attribute is of the same type as specified in the typedef, that is String (Java base type) in our case.

  • For each struct the protocol compiler also emits a class source file of the same name, containing the specified attributes.

  • The server stub code contains the dispatcher code and defines each remote procedure specified in the x-file as abstract. You need to supply your own implementation for each one of these stubs. Note that RPC base data types like int, u_long, etc. are mapped to their appropriate Java base type counterparts (int, int, in this example).

    By default, the server stub class is named after the x-file but with ServerStub appended. For example, if the x-file is named demo.x, then the server stub class is demoServerStub.

  • The client stub/proxy implements the remote procedures specified in the x-file as local methods which will call their remote counterpart on an ONC/RPC server.

    By default, the client stub class is named after the x-file but with Client appended. For example, if the x-file is named demo.x, then the client class is demoClient.

This package is part of the Remote Tea Java Library package.

(c) 1999, 2006 Harald Albrecht.
(c) 1999 Lehrstuhl für Prozeßleittechnik, Aachen University of Technology, Germany.

This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details.

You should have received a copy of the GNU Library General Public License along with this program (see the file COPYING.LIB for more details); if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. remotetea-1.0.7/src/org/acplt/oncrpc/server/0000755005374700003410000000000010736702150022074 5ustar piccainstrumentationremotetea-1.0.7/src/org/acplt/oncrpc/server/OncRpcCallInformation.java0000644005374700003410000004320707716652732027151 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/server/OncRpcCallInformation.java,v 1.3 2003/08/14 11:26:50 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc.server; import org.acplt.oncrpc.*; import java.io.IOException; import java.net.InetAddress; /** * Objects of class OncRpcCallInformation contain information * about individual ONC/RPC calls. They are given to ONC/RPC * {@link OncRpcDispatchable call dispatchers}, * so they can send back the reply to the appropriate caller, etc. Use only * this call info objects to retrieve call parameters and send back replies * as in the future UDP/IP-based transports may become multi-threaded handling. * The call info object is responsible to control access to the underlaying * transport, so never mess with the transport directly. * *

Note that this class provides two different patterns for accessing * parameters sent by clients within the ONC/RPC call and sending back replies. * *

    *
  1. The convenient high-level access: *
      *
    • Use {@link #retrieveCall(XdrAble)} to retrieve the parameters of * the call and deserialize it into a paramter object. *
    • Use {@link #reply(XdrAble)} to send back the reply by serializing * a reply/result object. Or use the failXXX methods to send back * an error indication instead. *
    * *
  2. The lower-level access, giving more control over how and when data * is deserialized and serialized: *
      *
    • Use {@link #getXdrDecodingStream} to get a reference to the XDR * stream from which you can deserialize the call's parameter. *
    • When you are finished deserializing, call {@link #endDecoding}. *
    • To send back the reply/result, call * {@link #beginEncoding(OncRpcServerReplyMessage)}. Using the XDR stream returned * by {@link #getXdrEncodingStream} serialize the reply/result. Finally finish * the serializing step by calling {@link #endEncoding}. *
    *
* * @see OncRpcDispatchable * * @version $Revision: 1.3 $ $Date: 2003/08/14 11:26:50 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class OncRpcCallInformation { /** * Create an OncRpcCallInformation object and associate it * with a ONC/RPC server transport. Typically, * OncRpcCallInformation objects are created by transports * once before handling incoming calls using the same call info object. * To support multithreaded handling of calls in the future (for UDP/IP), * the transport is already divided from the call info. * * @param transport ONC/RPC server transport. */ protected OncRpcCallInformation(OncRpcServerTransport transport) { this.transport = transport; } /** * Contains the call message header from ONC/RPC identifying this * particular call. */ public OncRpcServerCallMessage callMessage = new OncRpcServerCallMessage(); /** * Internet address of the peer from which we received an ONC/RPC call * or whom we intend to call. */ public InetAddress peerAddress = null; /** * Port number of the peer from which we received an ONC/RPC call or * whom we intend to call. */ public int peerPort = 0; /** * Associated transport from which we receive the ONC/RPC call parameters * and to which we serialize the ONC/RPC reply. Never mess with this * member or you might break all future extensions horribly -- but this * warning probably only stimulates you... */ protected OncRpcServerTransport transport; /** * Retrieves the parameters sent within an ONC/RPC call message. It also * makes sure that the deserialization process is properly finished after * the call parameters have been retrieved. * * @throws OncRpcException if an ONC/RPC exception occurs, like the data * could not be successfully deserialized. * @throws IOException if an I/O exception occurs, like transmission * failures over the network, etc. */ public void retrieveCall(XdrAble call) throws OncRpcException, IOException { transport.retrieveCall(call); } /** * Returns XDR stream which can be used for deserializing the parameters * of this ONC/RPC call. This method belongs to the lower-level access * pattern when handling ONC/RPC calls. * * @return Reference to decoding XDR stream. */ public XdrDecodingStream getXdrDecodingStream() { return transport.getXdrDecodingStream(); } /** * Finishes call parameter deserialization. Afterwards the XDR stream * returned by {@link #getXdrDecodingStream} must not be used any more. * This method belongs to the lower-level access pattern when handling * ONC/RPC calls. * * @throws OncRpcException if an ONC/RPC exception occurs, like the data * could not be successfully deserialized. * @throws IOException if an I/O exception occurs, like transmission * failures over the network, etc. */ public void endDecoding() throws OncRpcException, IOException { transport.endDecoding(); } /** * Begins the sending phase for ONC/RPC replies. After beginning sending * you can serialize the reply/result (but only if the call was accepted, see * {@link org.acplt.oncrpc.OncRpcReplyMessage} for details). The stream * to use for serialization can be obtained using * {@link #getXdrEncodingStream}. * This method belongs to the lower-level access pattern when handling * ONC/RPC calls. * * @param state ONC/RPC reply header indicating success or failure. * * @throws OncRpcException if an ONC/RPC exception occurs, like the data * could not be successfully serialized. * @throws IOException if an I/O exception occurs, like transmission * failures over the network, etc. */ public void beginEncoding(OncRpcServerReplyMessage state) throws OncRpcException, IOException { transport.beginEncoding(this, state); } /** * Begins the sending phase for accepted ONC/RPC replies. After beginning * sending you can serialize the result/reply. The stream * to use for serialization can be obtained using * {@link #getXdrEncodingStream}. * This method belongs to the lower-level access pattern when handling * ONC/RPC calls. * * @throws OncRpcException if an ONC/RPC exception occurs, like the data * could not be successfully serialized. * @throws IOException if an I/O exception occurs, like transmission * failures over the network, etc. */ public void beginEncoding() throws OncRpcException, IOException { transport.beginEncoding( this, new OncRpcServerReplyMessage( callMessage, OncRpcReplyStatus.ONCRPC_MSG_ACCEPTED, OncRpcAcceptStatus.ONCRPC_SUCCESS, OncRpcReplyMessage.UNUSED_PARAMETER, OncRpcReplyMessage.UNUSED_PARAMETER, OncRpcReplyMessage.UNUSED_PARAMETER, OncRpcReplyMessage.UNUSED_PARAMETER)); } /** * Returns XDR stream which can be used for eserializing the reply * to this ONC/RPC call. This method belongs to the lower-level access * pattern when handling ONC/RPC calls. * * @return Reference to enecoding XDR stream. */ public XdrEncodingStream getXdrEncodingStream() { return transport.getXdrEncodingStream(); } /** * Finishes encoding the reply to this ONC/RPC call. Afterwards you must * not use the XDR stream returned by {@link #getXdrEncodingStream} any * longer. * * @throws OncRpcException if an ONC/RPC exception occurs, like the data * could not be successfully serialized. * @throws IOException if an I/O exception occurs, like transmission * failures over the network, etc. */ public void endEncoding() throws OncRpcException, IOException { transport.endEncoding(); } /** * Send back an ONC/RPC reply to the caller who sent in this call. This is * a low-level function and typically should not be used by call * dispatchers. Instead use the other {@link #reply(XdrAble) reply method} * which just expects a serializable object to send back to the caller. * * @param state ONC/RPC reply message header indicating success or failure * and containing associated state information. * @param reply If not null, then this parameter references * the reply to be serialized after the reply message header. * * @throws OncRpcException if an ONC/RPC exception occurs, like the data * could not be successfully serialized. * @throws IOException if an I/O exception occurs, like transmission * failures over the network, etc. * * @see OncRpcReplyMessage * @see OncRpcDispatchable */ public void reply(OncRpcServerReplyMessage state, XdrAble reply) throws OncRpcException, IOException { transport.reply(this, state, reply); } /** * Send back an ONC/RPC reply to the caller who sent in this call. This * automatically sends an ONC/RPC reply header before the reply part, * indicating success within the header. * * @param reply Reply body the ONC/RPC reply message. * * @throws OncRpcException if an ONC/RPC exception occurs, like the data * could not be successfully serialized. * @throws IOException if an I/O exception occurs, like transmission * failures over the network, etc. */ public void reply(XdrAble reply) throws OncRpcException, IOException { reply(new OncRpcServerReplyMessage(callMessage, OncRpcReplyStatus.ONCRPC_MSG_ACCEPTED, OncRpcAcceptStatus.ONCRPC_SUCCESS, OncRpcReplyMessage.UNUSED_PARAMETER, OncRpcReplyMessage.UNUSED_PARAMETER, OncRpcReplyMessage.UNUSED_PARAMETER, OncRpcReplyMessage.UNUSED_PARAMETER), reply); } /** * Send back an ONC/RPC failure indication about invalid arguments to the * caller who sent in this call. * * @throws OncRpcException if an ONC/RPC exception occurs, like the data * could not be successfully serialized. * @throws IOException if an I/O exception occurs, like transmission * failures over the network, etc. */ public void failArgumentGarbage() throws OncRpcException, IOException { reply(new OncRpcServerReplyMessage( callMessage, OncRpcReplyStatus.ONCRPC_MSG_ACCEPTED, OncRpcAcceptStatus.ONCRPC_GARBAGE_ARGS, OncRpcReplyMessage.UNUSED_PARAMETER, OncRpcReplyMessage.UNUSED_PARAMETER, OncRpcReplyMessage.UNUSED_PARAMETER, OncRpcReplyMessage.UNUSED_PARAMETER), null); } /** * Send back an ONC/RPC failure indication about an unavailable procedure * call to the caller who sent in this call. * * @throws OncRpcException if an ONC/RPC exception occurs, like the data * could not be successfully serialized. * @throws IOException if an I/O exception occurs, like transmission * failures over the network, etc. */ public void failProcedureUnavailable() throws OncRpcException, IOException { reply(new OncRpcServerReplyMessage(callMessage, OncRpcReplyStatus.ONCRPC_MSG_ACCEPTED, OncRpcAcceptStatus.ONCRPC_PROC_UNAVAIL, OncRpcReplyMessage.UNUSED_PARAMETER, OncRpcReplyMessage.UNUSED_PARAMETER, OncRpcReplyMessage.UNUSED_PARAMETER, OncRpcReplyMessage.UNUSED_PARAMETER), null); } /** * Send back an ONC/RPC failure indication about an unavailable program * to the caller who sent in this call. * * @throws OncRpcException if an ONC/RPC exception occurs, like the data * could not be successfully serialized. * @throws IOException if an I/O exception occurs, like transmission * failures over the network, etc. */ public void failProgramUnavailable() throws OncRpcException, IOException { reply(new OncRpcServerReplyMessage(callMessage, OncRpcReplyStatus.ONCRPC_MSG_ACCEPTED, OncRpcAcceptStatus.ONCRPC_PROG_UNAVAIL, OncRpcReplyMessage.UNUSED_PARAMETER, OncRpcReplyMessage.UNUSED_PARAMETER, OncRpcReplyMessage.UNUSED_PARAMETER, OncRpcReplyMessage.UNUSED_PARAMETER), null); } /** * Send back an ONC/RPC failure indication about a program version mismatch * to the caller who sent in this call. * * @param lowVersion lowest supported program version. * @param highVersion highest supported program version. * * @throws OncRpcException if an ONC/RPC exception occurs, like the data * could not be successfully serialized. * @throws IOException if an I/O exception occurs, like transmission * failures over the network, etc. */ public void failProgramMismatch(int lowVersion, int highVersion) throws OncRpcException, IOException { reply(new OncRpcServerReplyMessage(callMessage, OncRpcReplyStatus.ONCRPC_MSG_ACCEPTED, OncRpcAcceptStatus.ONCRPC_PROG_MISMATCH, OncRpcReplyMessage.UNUSED_PARAMETER, lowVersion, highVersion, OncRpcReplyMessage.UNUSED_PARAMETER), null); } /** * Send back an ONC/RPC failure indication about a system error * to the caller who sent in this call. * * @throws OncRpcException if an ONC/RPC exception occurs, like the data * could not be successfully serialized. * @throws IOException if an I/O exception occurs, like transmission * failures over the network, etc. */ public void failSystemError() throws OncRpcException, IOException { reply(new OncRpcServerReplyMessage(callMessage, OncRpcReplyStatus.ONCRPC_MSG_ACCEPTED, OncRpcAcceptStatus.ONCRPC_SYSTEM_ERR, OncRpcReplyMessage.UNUSED_PARAMETER, OncRpcReplyMessage.UNUSED_PARAMETER, OncRpcReplyMessage.UNUSED_PARAMETER, OncRpcReplyMessage.UNUSED_PARAMETER), null); } /** * Send back an ONC/RPC failure indication about a ONC/RPC version mismatch * call to the caller who sent in this call. * * @throws OncRpcException if an ONC/RPC exception occurs, like the data * could not be successfully serialized. * @throws IOException if an I/O exception occurs, like transmission * failures over the network, etc. */ public void failOncRpcVersionMismatch() throws OncRpcException, IOException { reply(new OncRpcServerReplyMessage(callMessage, OncRpcReplyStatus.ONCRPC_MSG_DENIED, OncRpcReplyMessage.UNUSED_PARAMETER, OncRpcRejectStatus.ONCRPC_RPC_MISMATCH, OncRpcCallMessage.ONCRPC_VERSION, OncRpcCallMessage.ONCRPC_VERSION, OncRpcReplyMessage.UNUSED_PARAMETER), null); } /** * Send back an ONC/RPC failure indication about a failed authentication * to the caller who sent in this call. * * @param authStatus {@link OncRpcAuthStatus Reason} why authentication * failed. * * @throws OncRpcException if an ONC/RPC exception occurs, like the data * could not be successfully serialized. * @throws IOException if an I/O exception occurs, like transmission * failures over the network, etc. */ public void failAuthenticationFailed(int authStatus) throws OncRpcException, IOException { reply(new OncRpcServerReplyMessage(callMessage, OncRpcReplyStatus.ONCRPC_MSG_DENIED, OncRpcReplyMessage.UNUSED_PARAMETER, OncRpcRejectStatus.ONCRPC_AUTH_ERROR, OncRpcReplyMessage.UNUSED_PARAMETER, OncRpcReplyMessage.UNUSED_PARAMETER, authStatus), null); } } // End of OncRpcCallInformation.java remotetea-1.0.7/src/org/acplt/oncrpc/server/OncRpcDispatchable.java0000644005374700003410000001330007716406410026430 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/server/OncRpcDispatchable.java,v 1.1.1.1 2003/08/13 12:03:51 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc.server; import org.acplt.oncrpc.*; import java.io.IOException; /** * Tags classes as being able to dispatch and handle ONC/RPC requests from * clients. * *

This interface is used as follows for dispatching and handling ONC/RPC * calls: *

    *
  • First check which procedure the client intends to call. This information * is delivered through the procedure parameter. In case you * do not handle multiple programs within the same dispatcher, you can ignore * the program parameter as well as version. *
  • Retrieve appropriate parameters for this intended procedure using the * {@link OncRpcCallInformation#retrieveCall} method of the * {@link OncRpcCallInformation call} object also supplied to the dispatcher * through the call parameter. *
  • Do whatever you need to do for this ONC/RPC call and make up an * appropriate reply to be sent back to the client in the next step. *
  • Send back the reply by calling the {@link OncRpcCallInformation#reply} * method of the {@link OncRpcCallInformation call} object *
* *

Here's a simple example only showing how to handle the famous * procedure 0: this is the "ping" procedure which can be used * to test whether the server is still living. The example also shows how to * handle calls for procedures which are not implemented (not defined) by * calling {@link OncRpcCallInformation#failProcedureUnavailable}. * *

In case the dispatcher throws an exception, the affected ONC/RPC server * transport will send a system error indication {@link OncRpcCallInformation#failSystemError} to * the client. No error indication will be sent if the exception resulted from * an I/O problem. Note that if you do not explicitely send back a reply, no * reply is sent at all, making batched calls possible. * *

 * public void dispatchOncRpcCall(OncRpcCallInformation call,
 *                                int program, int version, int procedure)
 *        throws OncRpcException, IOException {
 *     switch ( procedure ) {
 *     case 0:
 *         XdrVoid v = new XdrVoid();
 *         call.retrieveCall(v);
 *         call.reply(v);
 *         break;
 *     default:
 *         call.failProcedureUnavailable();
 *     }
 * }
 * 
* * In addition, there are also lower-level methods available for retrieving * parameters and sending replies, in case you need to break up deserialization * and serialization into several steps. The following code snipped shows * how to use them. Here, the objects foo and bar * represents call parameter objects, while baz and blah * are used to sent back the reply data. * *
 * public void dispatchOncRpcCall(OncRpcCallInformation call,
 *                                int program, int version, int procedure)
 *        throws OncRpcException, IOException {
 *     switch ( procedure ) {
 *     case 42:
 *         // Retrieve call parameters.
 *         XdrDecodingStream decoder = call.getXdrDecodingStream();
 *         foo.xdrDecode(decoder);
 *         bar.xdrDecode(decoder);
 *         call.endDecoding();
 *         // Handle particular ONC/RPC call...
 *
 *         // Send back reply.
 *         call.beginEncoding();
 *         XdrEncodingStream encoder = call.getXdrEncodingStream();
 *         baz.xdrEncode(encoder);
 *         blah.xdrEncode(encoder);
 *         call.endEncoding();
 *         break;
 *     }
 * }
 * 
* * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:51 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public interface OncRpcDispatchable { /** * Dispatch (handle) an ONC/RPC request from a client. This interface has * some fairly deep semantics, so please read the description above for * how to use it properly. For background information about fairly deep * semantics, please also refer to Gigzales, J.: Semantics * considered harmful. Addison-Reilly, 1992, ISBN 0-542-10815-X. * *

See the introduction to this class for examples of how to use * this interface properly. * * @param call Information about the call to handle, like the caller's * Internet address, the ONC/RPC call header, etc. * @param program Program number requested by client. * @param version Version number requested. * @param procedure Procedure number requested. * * @see OncRpcCallInformation */ public void dispatchOncRpcCall(OncRpcCallInformation call, int program, int version, int procedure) throws OncRpcException, IOException; } // End of OncRpcDispatchable.java remotetea-1.0.7/src/org/acplt/oncrpc/server/OncRpcServerAcceptedCallMessage.java0000644005374700003410000001070607716623764031071 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/server/OncRpcServerAcceptedCallMessage.java,v 1.2 2003/08/14 08:10:59 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc.server; import org.acplt.oncrpc.*; /** * The OncRpcServerAcceptedCallMessage class represents (on the * sender's side) an accepted ONC/RPC call. In ONC/RPC babble, an "accepted" * call does not mean that it carries a result from the remote procedure * call, but rather that the call was accepted at the basic ONC/RPC level * and no authentification failure or else occured. * *

This ONC/RPC reply header class is only a convenience for server * implementors. * * @version $Revision: 1.2 $ $Date: 2003/08/14 08:10:59 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class OncRpcServerAcceptedCallMessage extends OncRpcServerReplyMessage { /** * Constructs an OncRpcServerAcceptedCallMessage object which * represents an accepted call, which was also successfully executed, * so the reply will contain information from the remote procedure call. * * @param call The call message header, which is used to construct the * matching reply message header from. */ public OncRpcServerAcceptedCallMessage(OncRpcServerCallMessage call) { super(call, OncRpcReplyStatus.ONCRPC_MSG_ACCEPTED, OncRpcAcceptStatus.ONCRPC_SUCCESS, OncRpcReplyMessage.UNUSED_PARAMETER, OncRpcReplyMessage.UNUSED_PARAMETER, OncRpcReplyMessage.UNUSED_PARAMETER, OncRpcAuthStatus.ONCRPC_AUTH_OK); } /** * Constructs an OncRpcAcceptedCallMessage object which * represents an accepted call, which was not necessarily successfully * carried out. The parameter acceptStatus will then * indicate the exact outcome of the ONC/RPC call. * * @param call The call message header, which is used to construct the * matching reply message header from. * @param acceptStatus The accept status of the call. This can be any * one of the constants defined in the {@link OncRpcAcceptStatus} * interface. */ public OncRpcServerAcceptedCallMessage(OncRpcServerCallMessage call, int acceptStatus) { super(call, OncRpcReplyStatus.ONCRPC_MSG_ACCEPTED, acceptStatus, OncRpcReplyMessage.UNUSED_PARAMETER, OncRpcReplyMessage.UNUSED_PARAMETER, OncRpcReplyMessage.UNUSED_PARAMETER, OncRpcAuthStatus.ONCRPC_AUTH_OK); } /** * Constructs an OncRpcAcceptedCallMessage object for an * accepted call with an unsupported version. The reply will contain * information about the lowest and highest supported version. * * @param call The call message header, which is used to construct the * matching reply message header from. * @param low Lowest program version supported by this ONC/RPC server. * @param high Highest program version supported by this ONC/RPC server. */ public OncRpcServerAcceptedCallMessage(OncRpcServerCallMessage call, int low, int high) { super(call, OncRpcReplyStatus.ONCRPC_MSG_ACCEPTED, OncRpcAcceptStatus.ONCRPC_PROG_MISMATCH, OncRpcReplyMessage.UNUSED_PARAMETER, low, high, OncRpcAuthStatus.ONCRPC_AUTH_OK); } } // End of OncRpcServerAcceptedCallMessage.java remotetea-1.0.7/src/org/acplt/oncrpc/server/OncRpcServerAuth.java0000644005374700003410000001163407716406410026145 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/server/OncRpcServerAuth.java,v 1.1.1.1 2003/08/13 12:03:51 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc.server; import org.acplt.oncrpc.*; import java.io.IOException; /** * The OncRpcServerAuth class is the base class and factory * for handling all protocol issues of ONC/RPC authentication on the server * side. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:51 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public abstract class OncRpcServerAuth { /** * Returns the type (flavor) of {@link OncRpcAuthType authentication} * used. * * @return Authentication type used by this authentication object. */ public abstract int getAuthenticationType(); /** * Restores (deserializes) an authentication object from an XDR stream. * * @param xdr XDR stream from which the authentication object is * restored. * @param recycle old authtentication object which is intended to be * reused in case it is of the same authentication type as the new * one just arriving from the XDR stream. * * @return Authentication information encapsulated in an object, whose class * is derived from OncRpcServerAuth. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public static final OncRpcServerAuth xdrNew(XdrDecodingStream xdr, OncRpcServerAuth recycle) throws OncRpcException, IOException { OncRpcServerAuth auth; // // In case we got an old authentication object and we are just about // to receive an authentication with the same type, we reuse the old // object. // int authType = xdr.xdrDecodeInt(); if ( (recycle != null) && (recycle.getAuthenticationType() == authType) ) { // // Simply recycle authentication object and pull its new state // of the XDR stream. // auth = recycle; auth.xdrDecodeCredVerf(xdr); } else { // // Create a new authentication object and pull its state off // the XDR stream. // switch ( authType ) { case OncRpcAuthType.ONCRPC_AUTH_NONE: auth = OncRpcServerAuthNone.AUTH_NONE; auth.xdrDecodeCredVerf(xdr); break; case OncRpcAuthType.ONCRPC_AUTH_SHORT: auth = new OncRpcServerAuthShort(xdr); break; case OncRpcAuthType.ONCRPC_AUTH_UNIX: auth = new OncRpcServerAuthUnix(xdr); break; default: // // In case of an unknown or unsupported type, throw an exception. // Note: using AUTH_REJECTEDCRED is in sync with the way Sun's // ONC/RPC implementation does it. But don't ask me why they do // it this way...! // throw(new OncRpcAuthenticationException( OncRpcAuthStatus.ONCRPC_AUTH_REJECTEDCRED)); } } return auth; } /** * Decodes -- that is: deserializes -- an ONC/RPC authentication object * (credential & verifier) on the server side. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public abstract void xdrDecodeCredVerf(XdrDecodingStream xdr) throws OncRpcException, IOException; /** * Encodes -- that is: serializes -- an ONC/RPC authentication object * (its verifier) on the server side. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public abstract void xdrEncodeVerf(XdrEncodingStream xdr) throws OncRpcException, IOException; } // End of OncRpcServerAuth.java remotetea-1.0.7/src/org/acplt/oncrpc/server/OncRpcServerAuthNone.java0000644005374700003410000000732407716406410026766 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/server/OncRpcServerAuthNone.java,v 1.1.1.1 2003/08/13 12:03:51 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc.server; import org.acplt.oncrpc.*; import java.io.IOException; /** * The OncRpcServerAuthNone class handles all protocol issues * of the ONC/RPC authentication AUTH_NONE on the server * side. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:51 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public final class OncRpcServerAuthNone extends OncRpcServerAuth { /** * Returns the type (flavor) of {@link OncRpcAuthType authentication} * used. * * @return Authentication type used by this authentication object. */ public final int getAuthenticationType() { return OncRpcAuthType.ONCRPC_AUTH_NONE; } /** * Decodes -- that is: deserializes -- an ONC/RPC authentication object * (credential & verifier) on the server side. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final void xdrDecodeCredVerf(XdrDecodingStream xdr) throws OncRpcException, IOException { // // As the authentication type has already been pulled off the XDR // stream, we only need to make sure that really no opaque data follows. // if ( xdr.xdrDecodeInt() != 0 ) { throw(new OncRpcAuthenticationException( OncRpcAuthStatus.ONCRPC_AUTH_BADCRED)); } // // We also need to decode the verifier. This must be of type // AUTH_NONE too. For some obscure historical reasons, we have to // deal with credentials and verifiers, although they belong together, // according to Sun's specification. // if ( (xdr.xdrDecodeInt() != OncRpcAuthType.ONCRPC_AUTH_NONE) || (xdr.xdrDecodeInt() != 0) ) { throw(new OncRpcAuthenticationException( OncRpcAuthStatus.ONCRPC_AUTH_BADVERF)); } } /** * Encodes -- that is: serializes -- an ONC/RPC authentication object * (its verifier) on the server side. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final void xdrEncodeVerf(XdrEncodingStream xdr) throws OncRpcException, IOException { // // Encode an AUTH_NONE verifier with zero length. // xdr.xdrEncodeInt(OncRpcAuthType.ONCRPC_AUTH_NONE); xdr.xdrEncodeInt(0); } /** * Singleton to use when an authentication object for AUTH_NONE * is needed. */ public static final OncRpcServerAuthNone AUTH_NONE = new OncRpcServerAuthNone(); } // End of OncRpcServerAuthNone.java remotetea-1.0.7/src/org/acplt/oncrpc/server/OncRpcServerAuthShort.java0000644005374700003410000001317007716406410027162 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/server/OncRpcServerAuthShort.java,v 1.1.1.1 2003/08/13 12:03:51 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc.server; import org.acplt.oncrpc.*; import java.io.IOException; /** * The OncRpcServerAuthShort class handles all protocol issues * of the ONC/RPC authentication AUTH_SHORT on the server * side. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:51 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public final class OncRpcServerAuthShort extends OncRpcServerAuth { /** * Constructs an OncRpcServerAuthShort object and pulls its * state off an XDR stream. * * @param xdr XDR stream to retrieve the object state from. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public OncRpcServerAuthShort(XdrDecodingStream xdr) throws OncRpcException, IOException { xdrDecodeCredVerf(xdr); } /** * Returns the type (flavor) of {@link OncRpcAuthType authentication} * used. * * @return Authentication type used by this authentication object. */ public final int getAuthenticationType() { return OncRpcAuthType.ONCRPC_AUTH_SHORT; } /** * Returns the shorthand credential sent by the caller. */ public final byte [] getShorthandCred() { return shorthandCred; } /** * Sets shorthand verifier to be sent back to the caller. The caller then * can use this shorthand verifier as the new credential with the next * ONC/RPC calls. If you don't set the verifier or set it to * null, then the verifier returned to the caller will be * of type AUTH_NONE. */ public final void setShorthandVerifier(byte [] shorthandVerf) { this.shorthandVerf = shorthandVerf; } /** * Returns the shorthand verifier to be sent back to the caller. */ public final byte [] getShorthandVerifier() { return shorthandVerf; } /** * Decodes -- that is: deserializes -- an ONC/RPC authentication object * (credential & verifier) on the server side. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final void xdrDecodeCredVerf(XdrDecodingStream xdr) throws OncRpcException, IOException { // // Reset the authentication object's state properly... // shorthandCred = null; shorthandVerf = null; // // Pull off the shorthand credential information (opaque date) of // the XDR stream... // shorthandCred = xdr.xdrDecodeDynamicOpaque(); if ( shorthandCred.length > OncRpcAuthConstants.ONCRPC_MAX_AUTH_BYTES ) { throw(new OncRpcAuthenticationException( OncRpcAuthStatus.ONCRPC_AUTH_BADCRED)); } // // We also need to decode the verifier. This must be of type // AUTH_NONE too. For some obscure historical reasons, we have to // deal with credentials and verifiers, although they belong together, // according to Sun's specification. // if ( (xdr.xdrDecodeInt() != OncRpcAuthType.ONCRPC_AUTH_NONE) || (xdr.xdrDecodeInt() != 0) ) { throw(new OncRpcAuthenticationException( OncRpcAuthStatus.ONCRPC_AUTH_BADVERF)); } } /** * Encodes -- that is: serializes -- an ONC/RPC authentication object * (its verifier) on the server side. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final void xdrEncodeVerf(XdrEncodingStream xdr) throws OncRpcException, IOException { if ( shorthandVerf != null ) { // // Encode AUTH_SHORT shorthand verifier (credential). // xdr.xdrEncodeInt(OncRpcAuthType.ONCRPC_AUTH_SHORT); xdr.xdrEncodeDynamicOpaque(shorthandVerf); } else { // // Encode an AUTH_NONE verifier with zero length, if no shorthand // verifier (credential) has been supplied by now. // xdr.xdrEncodeInt(OncRpcAuthType.ONCRPC_AUTH_NONE); xdr.xdrEncodeInt(0); } } /** * Contains the shorthand credential sent by the caller. */ private byte [] shorthandCred; /** * Contains the shorthand authentication verifier (credential) to return * to the caller to be used with the next ONC/RPC calls. */ private byte [] shorthandVerf; } // End of OncRpcServerAuthShort.java remotetea-1.0.7/src/org/acplt/oncrpc/server/OncRpcServerAuthUnix.java0000644005374700003410000001457607716406410027021 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/server/OncRpcServerAuthUnix.java,v 1.1.1.1 2003/08/13 12:03:51 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc.server; import org.acplt.oncrpc.*; import java.io.IOException; /** * The OncRpcServerAuthNone class handles all protocol issues * of the ONC/RPC authentication AUTH_UNIX on the server * side. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:51 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public final class OncRpcServerAuthUnix extends OncRpcServerAuth { /** * Contains timestamp as supplied through credential. */ public int stamp; /** * Contains the machine name of caller supplied through credential. */ public String machinename; /** * Contains the user ID of caller supplied through credential. */ public int uid; /** * Contains the group ID of caller supplied through credential. */ public int gid; /** * Contains a set of group IDs the caller belongs to, as supplied * through credential. */ public int [] gids; /** * Constructs an OncRpcServerAuthUnix object and pulls its * state off an XDR stream. * * @param xdr XDR stream to retrieve the object state from. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public OncRpcServerAuthUnix(XdrDecodingStream xdr) throws OncRpcException, IOException { xdrDecodeCredVerf(xdr); } /** * Returns the type (flavor) of {@link OncRpcAuthType authentication} * used. * * @return Authentication type used by this authentication object. */ public final int getAuthenticationType() { return OncRpcAuthType.ONCRPC_AUTH_UNIX; } /** * Sets shorthand verifier to be sent back to the caller. The caller then * can use this shorthand verifier as the new credential with the next * ONC/RPC calls to speed up things up (hopefully). */ public final void setShorthandVerifier(byte [] shorthandVerf) { this.shorthandVerf = shorthandVerf; } /** * Returns the shorthand verifier to be sent back to the caller. */ public final byte [] getShorthandVerifier() { return shorthandVerf; } /** * Decodes -- that is: deserializes -- an ONC/RPC authentication object * (credential & verifier) on the server side. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final void xdrDecodeCredVerf(XdrDecodingStream xdr) throws OncRpcException, IOException { // // Reset some part of the object's state... // shorthandVerf = null; // // Now pull off the object state of the XDR stream... // int realLen = xdr.xdrDecodeInt(); stamp = xdr.xdrDecodeInt(); machinename = xdr.xdrDecodeString(); uid = xdr.xdrDecodeInt(); gid = xdr.xdrDecodeInt(); gids = xdr.xdrDecodeIntVector(); // // Make sure that the indicated length of the opaque data is kosher. // If not, throw an exception, as there is something strange going on! // int len = 4 // length of stamp + ((machinename.length() + 7) & ~3) // len string incl. len + 4 // length of uid + 4 // length of gid + (gids.length * 4) + 4 // length of vector of gids incl. len ; if ( realLen != len ) { if ( realLen < len ) { throw(new OncRpcException(OncRpcException.RPC_BUFFERUNDERFLOW)); } else { throw(new OncRpcException(OncRpcException.RPC_AUTHERROR)); } } // // We also need to decode the verifier. This must be of type // AUTH_NONE too. For some obscure historical reasons, we have to // deal with credentials and verifiers, although they belong together, // according to Sun's specification. // if ( (xdr.xdrDecodeInt() != OncRpcAuthType.ONCRPC_AUTH_NONE) || (xdr.xdrDecodeInt() != 0) ) { throw(new OncRpcAuthenticationException( OncRpcAuthStatus.ONCRPC_AUTH_BADVERF)); } } /** * Encodes -- that is: serializes -- an ONC/RPC authentication object * (its verifier) on the server side. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final void xdrEncodeVerf(XdrEncodingStream xdr) throws OncRpcException, IOException { if ( shorthandVerf != null ) { // // Encode AUTH_SHORT shorthand verifier (credential). // xdr.xdrEncodeInt(OncRpcAuthType.ONCRPC_AUTH_SHORT); xdr.xdrEncodeDynamicOpaque(shorthandVerf); } else { // // Encode an AUTH_NONE verifier with zero length, if no shorthand // verifier (credential) has been supplied by now. // xdr.xdrEncodeInt(OncRpcAuthType.ONCRPC_AUTH_NONE); xdr.xdrEncodeInt(0); } } /** * Contains the shorthand authentication verifier (credential) to return * to the caller to be used with the next ONC/RPC calls. */ private byte [] shorthandVerf; } // End of OncRpcServerAuthUnix.java remotetea-1.0.7/src/org/acplt/oncrpc/server/OncRpcServerCallMessage.java0000644005374700003410000000742107716406410027423 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/server/OncRpcServerCallMessage.java,v 1.1.1.1 2003/08/13 12:03:51 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc.server; import org.acplt.oncrpc.*; import java.io.IOException; /** * The OncRpcServerCallMessage class represents an ONC/RPC * call message on the server side. For this reasons it just handles * decoding of call messages but can not do any encoding. This class is * also responsible for pulling off authentication information from the * wire and converting it into appropriate authentication protocol handling * objects. As with all good management, this class therefor delegates this * somehow unpleasant work to the server-side authentication protocol handling * classes. * * @see OncRpcServerAuth * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:51 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class OncRpcServerCallMessage extends OncRpcCallMessage { /** * Decodes -- that is: deserializes -- a ONC/RPC message header object * from a XDR stream according to RFC 1831. * * @param xdr A decoding XDR stream from which to receive all the mess. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException { messageId = xdr.xdrDecodeInt(); // // Make sure that we are really decoding an ONC/RPC message call // header. Otherwise, throw the appropriate OncRpcException exception. // messageType = xdr.xdrDecodeInt(); if ( messageType != OncRpcMessageType.ONCRPC_CALL ) { throw(new OncRpcException(OncRpcException.RPC_WRONGMESSAGE)); } // // Make sure that the other side is talking the right slang -- // we will only understand version 2 slang of ONC/RPC. // oncRpcVersion = xdr.xdrDecodeInt(); if ( oncRpcVersion != ONCRPC_VERSION ) { throw(new OncRpcException(OncRpcException.RPC_VERSMISMATCH)); } // // Now decode the remaining fields of the call header. // program = xdr.xdrDecodeInt(); version = xdr.xdrDecodeInt(); procedure = xdr.xdrDecodeInt(); // // Last comes the authentication data. Note that the "factory" hidden // within xdrNew() will graciously recycle any old authentication // protocol handling object if it is of the same authentication type // as the new one just coming in from the XDR wire. // auth = OncRpcServerAuth.xdrNew(xdr, auth); } /** * Contains the authentication protocol handling object retrieved together * with the call message itself. */ public OncRpcServerAuth auth; } // End of OncRpcServerCallMessage.java remotetea-1.0.7/src/org/acplt/oncrpc/server/OncRpcServerReplyMessage.java0000644005374700003410000001360307716406410027642 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/server/OncRpcServerReplyMessage.java,v 1.1.1.1 2003/08/13 12:03:51 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc.server; import org.acplt.oncrpc.*; import java.io.IOException; /** * The OncRpcReplyMessage class represents an ONC/RPC reply * message as defined by ONC/RPC in RFC 1831. Such messages are sent back by * ONC/RPC to servers to clients and contain (in case of real success) the * result of a remote procedure call. * *

This class and all its derived classes can be encoded only. They are * not able to encode themselves, because they are used solely on the * server side of an ONC/RPC connection. * *

The decision to define only one single class for the accepted and * rejected replies was driven by the motivation not to use polymorphism * and thus have to upcast and downcast references all the time. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:51 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class OncRpcServerReplyMessage extends OncRpcReplyMessage { /** * Initializes a new OncRpcReplyMessage object and initializes * its complete state from the given parameters. * *

Note that depending on the reply, acceptance and rejectance status * some parameters are unused and can be specified as * UNUSED_PARAMETER. * * @param call The ONC/RPC call this reply message corresponds to. * @param replyStatus The reply status (see {@link OncRpcReplyStatus}). * @param acceptStatus The acceptance state (see {@link OncRpcAcceptStatus}). * @param rejectStatus The rejectance state (see {@link OncRpcRejectStatus}). * @param lowVersion lowest supported version. * @param highVersion highest supported version. * @param authStatus The autentication state (see {@link OncRpcAuthStatus}). */ public OncRpcServerReplyMessage(OncRpcServerCallMessage call, int replyStatus, int acceptStatus, int rejectStatus, int lowVersion, int highVersion, int authStatus) { super(call, replyStatus, acceptStatus, rejectStatus, lowVersion, highVersion, authStatus); this.auth = call.auth; } /** * Encodes -- that is: serializes -- a ONC/RPC reply header object * into a XDR stream. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException { xdr.xdrEncodeInt(messageId); xdr.xdrEncodeInt(messageType); xdr.xdrEncodeInt(replyStatus); switch ( replyStatus ) { case OncRpcReplyStatus.ONCRPC_MSG_ACCEPTED: // // Encode the information returned for accepted message calls. // // First encode the authentification data. If someone has // nulled (nuked?) the authentication protocol handling object // from the call information object, then we can still fall back // to sending AUTH_NONE replies... // if ( auth != null ) { auth.xdrEncodeVerf(xdr); } else { xdr.xdrEncodeInt(OncRpcAuthType.ONCRPC_AUTH_NONE); xdr.xdrEncodeInt(0); } // // Even if the call was accepted by the server, it can still // indicate an error. Depending on the status of the accepted // call we have to send back an indication about the range of // versions we support of a particular program (server). // xdr.xdrEncodeInt(acceptStatus); switch ( acceptStatus ) { case OncRpcAcceptStatus.ONCRPC_PROG_MISMATCH: xdr.xdrEncodeInt(lowVersion); xdr.xdrEncodeInt(highVersion); break; default: // // Otherwise "open ended set of problem", like the author // of Sun's ONC/RPC source once wrote... // break; } break; case OncRpcReplyStatus.ONCRPC_MSG_DENIED: // // Encode the information returned for denied message calls. // xdr.xdrEncodeInt(rejectStatus); switch ( rejectStatus ) { case OncRpcRejectStatus.ONCRPC_RPC_MISMATCH: xdr.xdrEncodeInt(lowVersion); xdr.xdrEncodeInt(highVersion); break; case OncRpcRejectStatus.ONCRPC_AUTH_ERROR: xdr.xdrEncodeInt(authStatus); break; default: } break; } } /** * Contains the authentication protocol handling object. */ OncRpcServerAuth auth; } // End of OncRpcServerReplyMessage.java remotetea-1.0.7/src/org/acplt/oncrpc/server/OncRpcServerStub.java0000644005374700003410000001673207716673270026177 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/server/OncRpcServerStub.java,v 1.2 2003/08/14 13:47:04 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc.server; import org.acplt.oncrpc.*; import java.io.IOException; /** * The abstract OncRpcServerStub class is the base class to * build ONC/RPC-program specific servers upon. This class is typically * only used by jrpcgen generated servers, which provide a particular * set of remote procedures as defined in a x-file. * * @version $Revision: 1.2 $ $Date: 2003/08/14 13:47:04 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public abstract class OncRpcServerStub { /** * Array containing ONC/RPC server transport objects which describe what * transports an ONC/RPC server offers for handling ONC/RPC calls. */ public OncRpcServerTransport [] transports; /** * Array containing program and version numbers tuples this server is * willing to handle. */ public OncRpcServerTransportRegistrationInfo [] info; /** * Notification flag for signalling the server to stop processing * incomming remote procedure calls and to shut down. */ protected Object shutdownSignal = new Object(); /** * All inclusive convenience method: register server transports with * portmapper, then run the call dispatcher until the server is signalled * to shut down, and finally deregister the transports. * * @throws OncRpcException if the portmapper can not be contacted * successfully. * @throws IOException if a severe network I/O error occurs in the * server from which it can not recover (like severe exceptions thrown * when waiting for now connections on a server socket). */ public void run() throws OncRpcException, IOException { // // Ignore all problems during unregistration. // try { unregister(transports); } catch ( OncRpcException ore ) { } register(transports); run(transports); try { unregister(transports); } finally { close(transports); } } /** * Register a set of server transports with the local portmapper. * * @param transports Array of server transport objects to register, * which will later handle incomming remote procedure call requests. * * @throws OncRpcException if the portmapper could not be contacted * successfully. */ public void register(OncRpcServerTransport [] transports) throws OncRpcException { int size = transports.length; for ( int idx = 0; idx < size; ++idx ) { transports[idx].register(); } } /** * Process incomming remote procedure call requests from all specified * transports. To end processing and to shut the server down signal * the {@link #shutdownSignal} object. Note that the thread on which * run() is called will ignore any interruptions and * will silently swallow them. * * @param transports Array of server transport objects for which * processing of remote procedure call requests should be done. */ public void run(OncRpcServerTransport [] transports) { int size = transports.length; for ( int idx = 0; idx < size; ++idx ) { transports[idx].listen(); } // // Loop and wait for the shutdown flag to become signalled. If the // server's main thread gets interrupted it will not shut itself // down. It can only be stopped by signalling the shutdownSignal // object. // for ( ;; ) { synchronized ( shutdownSignal ) { try { shutdownSignal.wait(); break; } catch ( InterruptedException e ) { } } } } /** * Notify the RPC server to stop processing of remote procedure call * requests as soon as possible. Note that each transport has its own * thread, so processing will not stop before the transports have been * closed by calling the {@link #close} method of the server. */ public void stopRpcProcessing() { if ( shutdownSignal != null ) { synchronized ( shutdownSignal ) { shutdownSignal.notify(); } } } /** * Unregister a set of server transports from the local portmapper. * * @param transports Array of server transport objects to unregister. * * @throws OncRpcException with a reason of * {@link OncRpcException#RPC_FAILED OncRpcException.RPC_FAILED} if * the portmapper could not be contacted successfully. Note that * it is not considered an error to remove a non-existing entry from * the portmapper. */ public void unregister(OncRpcServerTransport [] transports) throws OncRpcException { int size = transports.length; for ( int idx = 0; idx < size; ++idx ) { transports[idx].unregister(); } } /** * Close all transports listed in a set of server transports. Only * by calling this method processing of remote procedure calls by * individual transports can be stopped. This is because every server * transport is handled by its own thread. * * @param transports Array of server transport objects to close. */ public void close(OncRpcServerTransport [] transports) { int size = transports.length; for ( int idx = 0; idx < size; ++idx ) { transports[idx].close(); } } /** * Set the character encoding for deserializing strings. * * @param characterEncoding the encoding to use for deserializing strings. * If null, the system's default encoding is to be used. */ public void setCharacterEncoding(String characterEncoding) { this.characterEncoding = characterEncoding; int size = transports.length; for ( int idx = 0; idx < size; ++idx ) { transports[idx].setCharacterEncoding(characterEncoding); } } /** * Get the character encoding for deserializing strings. * * @return the encoding currently used for deserializing strings. * If null, then the system's default encoding is used. */ public String getCharacterEncoding() { return characterEncoding; } /** * Encoding to use when deserializing strings or null if * the system's default encoding should be used. */ private String characterEncoding; } // End of OncRpcServerStub.javaremotetea-1.0.7/src/org/acplt/oncrpc/server/OncRpcServerTransport.java0000644005374700003410000003015107716673270027245 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/server/OncRpcServerTransport.java,v 1.3 2003/08/14 13:47:04 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc.server; import org.acplt.oncrpc.*; import java.io.IOException; import java.net.InetAddress; /** * Instances of class OncRpcServerTransport encapsulate XDR * streams of ONC/RPC servers. Using server transports, ONC/RPC calls are * received and the corresponding replies are later sent back after * handling. * *

Note that the server-specific dispatcher handling requests * (done through {@link OncRpcDispatchable} will only * directly deal with {@link OncRpcCallInformation} objects. These * call information objects reference OncRpcServerTransport object, but * the server programmer typically will never touch them, as the call * information object already contains all necessary information about * a call, so replies can be sent back (and this is definetely a sentence * containing too many words). * * @see OncRpcCallInformation * @see OncRpcDispatchable * * @version $Revision: 1.3 $ $Date: 2003/08/14 13:47:04 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public abstract class OncRpcServerTransport { /** * Create a new instance of a OncRpcServerTransport which * encapsulates XDR streams of an ONC/RPC server. Using a server transport, * ONC/RPC calls are received and the corresponding replies are sent back. * *

We do not create any XDR streams here, as it is the responsibility * of derived classes to create appropriate XDR stream objects for the * respective kind of transport mechanism used (like TCP/IP and UDP/IP). * * @param dispatcher Reference to interface of an object capable of * dispatching (handling) ONC/RPC calls. * @param port Number of port where the server will wait for incoming * calls. * @param info Array of program and version number tuples of the ONC/RPC * programs and versions handled by this transport. */ protected OncRpcServerTransport(OncRpcDispatchable dispatcher, int port, OncRpcServerTransportRegistrationInfo [] info) { this.dispatcher = dispatcher; this.port = port; this.info = info; } /** * Register the port where this server transport waits for incoming * requests with the ONC/RPC portmapper. * *

The contract of this method is, that derived classes implement * the appropriate communication with the portmapper, so the transport * is registered only for the protocol supported by a particular kind * of server transport. * * @throws OncRpcException if the portmapper could not be contacted * successfully. */ public abstract void register() throws OncRpcException; /** * Unregisters the port where this server transport waits for incoming * requests from the ONC/RPC portmapper. * *

Note that due to the way Sun decided to implement its ONC/RPC * portmapper process, deregistering one server transports causes all * entries for the same program and version to be removed, regardless * of the protocol (UDP/IP or TCP/IP) used. Sigh. * * @throws OncRpcException with a reason of * {@link OncRpcException#RPC_FAILED OncRpcException.RPC_FAILED} if * the portmapper could not be contacted successfully. Note that * it is not considered an error to remove a non-existing entry from * the portmapper. */ public void unregister() throws OncRpcException { try { OncRpcPortmapClient portmapper = new OncRpcPortmapClient(InetAddress.getByName("127.0.0.1")); int size = info.length; for ( int idx = 0; idx < size; ++idx ) { portmapper.unsetPort(info[idx].program, info[idx].version); } } catch ( IOException e ) { throw(new OncRpcException(OncRpcException.RPC_FAILED)); } } /** * Close the server transport and free any resources associated with it. * *

Note that the server transport is not deregistered. You'll * have to do it manually if you need to do so. The reason for this * behaviour is, that the portmapper removes all entries regardless of * the protocol (TCP/IP or UDP/IP) for a given ONC/RPC program number * and version. * *

Derived classes can choose between different behaviour for * shuting down the associated transport handler threads: *

    *
  • Close the transport immediately and let the threads stumble on the * closed network connection. *
  • Wait for handler threads to complete their current ONC/RPC request * (with timeout), then close connections and kill the threads. *
*/ public abstract void close(); /** * Creates a new thread and uses this thread to listen to incoming * ONC/RPC requests, then dispatches them and finally sends back the * appropriate reply messages. * *

Note that you have to supply an implementation for this abstract * method in derived classes. Your implementation needs to create a new * thread to wait for incoming requests. The method has to return * immediately for the calling thread. */ public abstract void listen(); /** * Returns port number of socket this server transport listens on for * incoming ONC/RPC calls. * * @return Port number of socket listening for incoming calls. */ public int getPort() { return port; } /** * Set the character encoding for (de-)serializing strings. * * @param characterEncoding the encoding to use for (de-)serializing strings. * If null, the system's default encoding is to be used. */ public abstract void setCharacterEncoding(String characterEncoding); /** * Get the character encoding for (de-)serializing strings. * * @return the encoding currently used for (de-)serializing strings. * If null, then the system's default encoding is used. */ public abstract String getCharacterEncoding(); /** * Retrieves the parameters sent within an ONC/RPC call message. It also * makes sure that the deserialization process is properly finished after * the call parameters have been retrieved. Under the hood this method * therefore calls {@link XdrDecodingStream#endDecoding} to free any * pending resources from the decoding stage. * * @throws OncRpcException if an ONC/RPC exception occurs, like the data * could not be successfully deserialized. * @throws IOException if an I/O exception occurs, like transmission * failures over the network, etc. */ protected abstract void retrieveCall(XdrAble call) throws OncRpcException, IOException; /** * Returns XDR stream which can be used for deserializing the parameters * of this ONC/RPC call. This method belongs to the lower-level access * pattern when handling ONC/RPC calls. * * @return Reference to decoding XDR stream. */ protected abstract XdrDecodingStream getXdrDecodingStream(); /** * Finishes call parameter deserialization. Afterwards the XDR stream * returned by {@link #getXdrDecodingStream} must not be used any more. * This method belongs to the lower-level access pattern when handling * ONC/RPC calls. * * @throws OncRpcException if an ONC/RPC exception occurs, like the data * could not be successfully deserialized. * @throws IOException if an I/O exception occurs, like transmission * failures over the network, etc. */ protected abstract void endDecoding() throws OncRpcException, IOException; /** * Returns XDR stream which can be used for eserializing the reply * to this ONC/RPC call. This method belongs to the lower-level access * pattern when handling ONC/RPC calls. * * @return Reference to enecoding XDR stream. */ protected abstract XdrEncodingStream getXdrEncodingStream(); /** * Begins the sending phase for ONC/RPC replies. * This method belongs to the lower-level access pattern when handling * ONC/RPC calls. * * @param callInfo Information about ONC/RPC call for which we are about * to send back the reply. * @param state ONC/RPC reply header indicating success or failure. * * @throws OncRpcException if an ONC/RPC exception occurs, like the data * could not be successfully serialized. * @throws IOException if an I/O exception occurs, like transmission */ protected abstract void beginEncoding(OncRpcCallInformation callInfo, OncRpcServerReplyMessage state) throws OncRpcException, IOException; /** * Finishes encoding the reply to this ONC/RPC call. Afterwards you must * not use the XDR stream returned by {@link #getXdrEncodingStream} any * longer. * * @throws OncRpcException if an ONC/RPC exception occurs, like the data * could not be successfully serialized. * @throws IOException if an I/O exception occurs, like transmission * failures over the network, etc. */ protected abstract void endEncoding() throws OncRpcException, IOException; /** * Send back an ONC/RPC reply to the original caller. This is rather a * low-level method, typically not used by applications. Dispatcher handling * ONC/RPC calls have to use the * {@link OncRpcCallInformation#reply(XdrAble)} method instead on the * call object supplied to the handler. * *

An appropriate implementation has to be provided in derived classes * as it is dependent on the type of transport (whether UDP/IP or TCP/IP) * used. * * @param callInfo information about the original call, which are necessary * to send back the reply to the appropriate caller. * @param state ONC/RPC reply message header indicating success or failure * and containing associated state information. * @param reply If not null, then this parameter references * the reply to be serialized after the reply message header. * * @throws OncRpcException if an ONC/RPC exception occurs, like the data * could not be successfully serialized. * @throws IOException if an I/O exception occurs, like transmission * failures over the network, etc. * * @see OncRpcCallInformation * @see OncRpcDispatchable */ protected abstract void reply(OncRpcCallInformation callInfo, OncRpcServerReplyMessage state, XdrAble reply) throws OncRpcException, IOException; /** * Reference to interface of an object capable of handling/dispatching * ONC/RPC requests. */ protected OncRpcDispatchable dispatcher; /** * Port number where we're listening for incoming ONC/RPC requests. */ protected int port; /** * Program and version number tuples handled by this server transport. */ protected OncRpcServerTransportRegistrationInfo [] info; } // End of OncRpcServerTransport.java remotetea-1.0.7/src/org/acplt/oncrpc/server/OncRpcServerTransportRegistrationInfo.java0000644005374700003410000000373407716406410032451 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/server/OncRpcServerTransportRegistrationInfo.java,v 1.1.1.1 2003/08/13 12:03:52 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000, 2001 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc.server; /** * The class OncRpcServerTransportRegistrationInfo holds * information about (possibly multiple) registration of server transports * for individual program and version numbers. * * @version $Revision: 1.1.1.1 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class OncRpcServerTransportRegistrationInfo { /** * @param program Number of ONC/RPC program handled by a server * transport. * @param version Version number of ONC/RPC program handled. */ public OncRpcServerTransportRegistrationInfo(int program, int version) { this.program = program; this.version = version; } /** * Number of ONC/RPC program handled. */ public int program; /** * Version number of ONC/RPC program handled. */ public int version; } // End of OncRpcServerTransportRegistrationInfo.java remotetea-1.0.7/src/org/acplt/oncrpc/server/OncRpcTcpConnectionServerTransport.java0000644005374700003410000005437610736716020031736 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/server/OncRpcTcpConnectionServerTransport.java,v 1.5 2008/01/02 15:13:35 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc.server; import org.acplt.oncrpc.*; import java.io.IOException; import java.net.Socket; /** * Instances of class OncRpcTcpServerTransport encapsulate * TCP/IP-based XDR streams of ONC/RPC servers. This server transport class * is responsible for receiving ONC/RPC calls over TCP/IP. * * @see OncRpcServerTransport * @see OncRpcTcpServerTransport * @see OncRpcUdpServerTransport * * @version $Revision: 1.5 $ $Date: 2008/01/02 15:13:35 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class OncRpcTcpConnectionServerTransport extends OncRpcServerTransport { /** * Create a new instance of a OncRpcTcpSConnectionerverTransport * which encapsulates TCP/IP-based XDR streams of an ONC/RPC server. This * particular server transport handles individual ONC/RPC connections over * TCP/IP. This constructor is a convenience constructor for those transports * handling only a single ONC/RPC program and version number. * * @param dispatcher Reference to interface of an object capable of * dispatching (handling) ONC/RPC calls. * @param socket TCP/IP-based socket of new connection. * @param program Number of ONC/RPC program handled by this server * transport. * @param version Version number of ONC/RPC program handled. * @param bufferSize Size of buffer used when receiving and sending * chunks of XDR fragments over TCP/IP. The fragments built up to * form ONC/RPC call and reply messages. * @param parent Parent server transport which created us. * @param transmissionTimeout Inherited transmission timeout. */ public OncRpcTcpConnectionServerTransport(OncRpcDispatchable dispatcher, Socket socket, int program, int version, int bufferSize, OncRpcTcpServerTransport parent, int transmissionTimeout) throws OncRpcException, IOException { this(dispatcher, socket, new OncRpcServerTransportRegistrationInfo[] { new OncRpcServerTransportRegistrationInfo(program, version) }, bufferSize, parent, transmissionTimeout); } /** * Create a new instance of a OncRpcTcpSConnectionerverTransport * which encapsulates TCP/IP-based XDR streams of an ONC/RPC server. This * particular server transport handles individual ONC/RPC connections over * TCP/IP. * * @param dispatcher Reference to interface of an object capable of * dispatching (handling) ONC/RPC calls. * @param socket TCP/IP-based socket of new connection. * @param info Array of program and version number tuples of the ONC/RPC * programs and versions handled by this transport. * @param bufferSize Size of buffer used when receiving and sending * chunks of XDR fragments over TCP/IP. The fragments built up to * form ONC/RPC call and reply messages. * @param parent Parent server transport which created us. * @param transmissionTimeout Inherited transmission timeout. */ public OncRpcTcpConnectionServerTransport(OncRpcDispatchable dispatcher, Socket socket, OncRpcServerTransportRegistrationInfo [] info, int bufferSize, OncRpcTcpServerTransport parent, int transmissionTimeout) throws OncRpcException, IOException { super(dispatcher, 0, info); this.parent = parent; this.transmissionTimeout = transmissionTimeout; // // Make sure the buffer is large enough and resize system buffers // accordingly, if possible. // if ( bufferSize < 1024 ) { bufferSize = 1024; } this.socket = socket; this.port = socket.getLocalPort(); socketHelper = new OncRpcTcpSocketHelper(socket); if ( socketHelper.getSendBufferSize() < bufferSize ) { socketHelper.setSendBufferSize(bufferSize); } if ( socketHelper.getReceiveBufferSize() < bufferSize ) { socketHelper.setReceiveBufferSize(bufferSize); } // // Create the necessary encoding and decoding streams, so we can // communicate at all. // sendingXdr = new XdrTcpEncodingStream(socket, bufferSize); receivingXdr = new XdrTcpDecodingStream(socket, bufferSize); // // Inherit the character encoding setting from the listening // transport (parent transport). // setCharacterEncoding(parent.getCharacterEncoding()); } /** * Close the server transport and free any resources associated with it. * *

Note that the server transport is not deregistered. You'll * have to do it manually if you need to do so. The reason for this * behaviour is, that the portmapper removes all entries regardless of * the protocol (TCP/IP or UDP/IP) for a given ONC/RPC program number * and version. * *

Calling this method on a OncRpcTcpServerTransport * results in the listening TCP network socket immediately being closed. * The handler thread will therefore either terminate directly or when * it tries to sent back replies. */ public void close() { if ( socket != null ) { // // Since there is a non-zero chance of getting race conditions, // we now first set the socket instance member to null, before // we close the corresponding socket. This avoids null-pointer // exceptions in the method which waits for new requests: it is // possible that this method is awakened because the socket has // been closed before we could set the socket instance member to // null. Many thanks to Michael Smith for tracking down this one. // Socket deadSocket = socket; socket = null; try { deadSocket.close(); } catch ( IOException e ) { } } if ( sendingXdr != null ) { XdrEncodingStream deadXdrStream = sendingXdr; sendingXdr = null; try { deadXdrStream.close(); } catch ( IOException e ) { } catch ( OncRpcException e ) { } } if ( receivingXdr != null ) { XdrDecodingStream deadXdrStream = receivingXdr; receivingXdr = null; try { deadXdrStream.close(); } catch ( IOException e ) { } catch ( OncRpcException e ) { } } if ( parent != null ) { parent.removeTransport(this); parent = null; } } /** * Finalize object by making sure that we're removed from the list * of open transports which our parent transport maintains. */ protected void finalize() { if ( parent != null ) { parent.removeTransport(this); } } /** * Do not call. * * @throws Error because this method must not be called for an * individual TCP/IP-based server transport. */ public void register() throws OncRpcException { throw(new Error("OncRpcTcpServerTransport.register() is abstract " +"and can not be called.")); } /** * Retrieves the parameters sent within an ONC/RPC call message. It also * makes sure that the deserialization process is properly finished after * the call parameters have been retrieved. Under the hood this method * therefore calls {@link XdrDecodingStream#endDecoding} to free any * pending resources from the decoding stage. * * @throws OncRpcException if an ONC/RPC exception occurs, like the data * could not be successfully deserialized. * @throws IOException if an I/O exception occurs, like transmission * failures over the network, etc. */ public void retrieveCall(XdrAble call) throws OncRpcException, IOException { call.xdrDecode(receivingXdr); if ( pendingDecoding ) { pendingDecoding = false; receivingXdr.endDecoding(); } } /** * Returns XDR stream which can be used for deserializing the parameters * of this ONC/RPC call. This method belongs to the lower-level access * pattern when handling ONC/RPC calls. * */ protected XdrDecodingStream getXdrDecodingStream() { return receivingXdr; } /** * Finishes call parameter deserialization. Afterwards the XDR stream * returned by {@link #getXdrDecodingStream} must not be used any more. * This method belongs to the lower-level access pattern when handling * ONC/RPC calls. * * @throws OncRpcException if an ONC/RPC exception occurs, like the data * could not be successfully deserialized. * @throws IOException if an I/O exception occurs, like transmission * failures over the network, etc. */ protected void endDecoding() throws OncRpcException, IOException { if ( pendingDecoding ) { pendingDecoding = false; receivingXdr.endDecoding(); } } /** * Returns XDR stream which can be used for eserializing the reply * to this ONC/RPC call. This method belongs to the lower-level access * pattern when handling ONC/RPC calls. * * @return Reference to enecoding XDR stream. */ protected XdrEncodingStream getXdrEncodingStream() { return sendingXdr; } /** * Begins the sending phase for ONC/RPC replies. * This method belongs to the lower-level access pattern when handling * ONC/RPC calls. * * @param callInfo Information about ONC/RPC call for which we are about * to send back the reply. * @param state ONC/RPC reply header indicating success or failure. * * @throws OncRpcException if an ONC/RPC exception occurs, like the data * could not be successfully serialized. * @throws IOException if an I/O exception occurs, like transmission */ protected void beginEncoding(OncRpcCallInformation callInfo, OncRpcServerReplyMessage state) throws OncRpcException, IOException { // // In case decoding has not been properly finished, do it now to // free up pending resources, etc. // if ( pendingDecoding ) { pendingDecoding = false; receivingXdr.endDecoding(); } // // Now start encoding using the reply message header first... // pendingEncoding = true; sendingXdr.beginEncoding(callInfo.peerAddress, callInfo.peerPort); state.xdrEncode(sendingXdr); } /** * Finishes encoding the reply to this ONC/RPC call. Afterwards you must * not use the XDR stream returned by {@link #getXdrEncodingStream} any * longer. * * @throws OncRpcException if an ONC/RPC exception occurs, like the data * could not be successfully serialized. * @throws IOException if an I/O exception occurs, like transmission * failures over the network, etc. */ protected void endEncoding() throws OncRpcException, IOException { // // Close the case. Finito. // sendingXdr.endEncoding(); pendingEncoding = false; } /** * Send back an ONC/RPC reply to the original caller. This is rather a * low-level method, typically not used by applications. Dispatcher handling * ONC/RPC calls have to use the * {@link OncRpcCallInformation#reply(XdrAble)} method instead on the * call object supplied to the handler. * * @param callInfo information about the original call, which are necessary * to send back the reply to the appropriate caller. * @param state ONC/RPC reply message header indicating success or failure * and containing associated state information. * @param reply If not null, then this parameter references * the reply to be serialized after the reply message header. * * @throws OncRpcException if an ONC/RPC exception occurs, like the data * could not be successfully serialized. * @throws IOException if an I/O exception occurs, like transmission * failures over the network, etc. * * @see OncRpcCallInformation * @see OncRpcDispatchable */ protected void reply(OncRpcCallInformation callInfo, OncRpcServerReplyMessage state, XdrAble reply) throws OncRpcException, IOException { beginEncoding(callInfo, state); if ( reply != null ) { reply.xdrEncode(sendingXdr); } endEncoding(); } /** * Creates a new thread and uses this thread to handle the new connection * to receive ONC/RPC requests, then dispatching them and finally sending * back reply messages. Control in the calling thread immediately * returns after the handler thread has been created. * *

Currently only one call after the other is dispatched, so no * multithreading is done when receiving multiple calls. Instead, later * calls have to wait for the current call to finish before they are * handled. */ public void listen() { Thread listener = new Thread("TCP server transport connection thread") { public void run() { _listen(); } }; listener.setDaemon(true); listener.start(); } /** * The real workhorse handling incoming requests, dispatching them and * sending back replies. */ private void _listen() { OncRpcCallInformation callInfo = new OncRpcCallInformation(this); for ( ;; ) { // // Start decoding the incomming call. This involves remembering // from whom we received the call so we can later send back the // appropriate reply message. // try { socket.setSoTimeout(0); pendingDecoding = true; receivingXdr.beginDecoding(); callInfo.peerAddress = receivingXdr.getSenderAddress(); callInfo.peerPort = receivingXdr.getSenderPort(); socket.setSoTimeout(transmissionTimeout); } catch ( IOException e ) { // // In case of I/O Exceptions (especially socket exceptions) // close the file and leave the stage. There's nothing we can // do anymore. // close(); return; } catch ( OncRpcException e ) { // // In case of ONC/RPC exceptions at this stage kill the // connection. // close(); return; } try { // // Pull off the ONC/RPC call header of the XDR stream. // callInfo.callMessage.xdrDecode(receivingXdr); } catch ( IOException e ) { // // In case of I/O Exceptions (especially socket exceptions) // close the file and leave the stage. There's nothing we can // do anymore. // close(); return; } catch ( OncRpcException e ) { // // In case of ONC/RPC exceptions at this stage we're silently // ignoring that there was some data coming in, as we're not // sure we got enough information to send a matching reply // message back to the caller. // if ( pendingDecoding ) { pendingDecoding = false; try { receivingXdr.endDecoding(); } catch ( IOException e2 ) { close(); return; } catch ( OncRpcException e2 ) { } } continue; } try { // // Let the dispatcher retrieve the call parameters, work on // it and send back the reply. // To make it once again clear: the dispatch called has to // pull off the parameters of the stream! // dispatcher.dispatchOncRpcCall(callInfo, callInfo.callMessage.program, callInfo.callMessage.version, callInfo.callMessage.procedure); } catch ( Exception e ) { // // In case of some other runtime exception, we report back to // the caller a system error. We can not do this if we don't // got the exception when serializing the reply, in this case // all we can do is to drop the connection. If a reply was not // yet started, we can safely send a system error reply. // if ( pendingEncoding ) { close(); // Drop the connection... return; // ...and kill the transport. } // // Looks safe, so we try to send back an error reply. // if ( pendingDecoding ) { pendingDecoding = false; try { receivingXdr.endDecoding(); } catch ( IOException e2 ) { close(); return; } catch ( OncRpcException e2 ) { } } // // Check for authentication exceptions, which are reported back // as is. Otherwise, just report a system error // -- very generic, indeed. // try { if ( e instanceof OncRpcAuthenticationException ) { callInfo.failAuthenticationFailed( ((OncRpcAuthenticationException) e).getAuthStatus()); } else { callInfo.failSystemError(); } } catch ( IOException e2 ) { close(); return; } catch ( OncRpcException e2 ) { } // // Phew. Done with the error reply. So let's wait for new // incoming ONC/RPC calls... // } } } /** * Set the character encoding for (de-)serializing strings. * * @param characterEncoding the encoding to use for (de-)serializing strings. * If null, the system's default encoding is to be used. */ public void setCharacterEncoding(String characterEncoding) { sendingXdr.setCharacterEncoding(characterEncoding); receivingXdr.setCharacterEncoding(characterEncoding); } /** * Get the character encoding for (de-)serializing strings. * * @return the encoding currently used for (de-)serializing strings. * If null, then the system's default encoding is used. */ public String getCharacterEncoding() { return sendingXdr.getCharacterEncoding(); } /** * TCP socket used for stream-based communication with ONC/RPC * clients. */ private Socket socket; /** * Socket helper object supplying missing methods for JDK 1.1 * backwards compatibility. So much for compile once, does not run * everywhere. */ private OncRpcTcpSocketHelper socketHelper; /** * XDR encoding stream used for sending replies via TCP/IP back to an * ONC/RPC client. */ private XdrTcpEncodingStream sendingXdr; /** * XDR decoding stream used when receiving requests via TCP/IP from * ONC/RPC clients. */ private XdrTcpDecodingStream receivingXdr; /** * Indicates that BeginDecoding has been called for the * receiving XDR stream, so that it should be closed later using * EndDecoding. */ private boolean pendingDecoding = false; /** * Indicates that BeginEncoding has been called for the * sending XDR stream, so in face of exceptions we can not send an * error reply to the client but only drop the connection. */ private boolean pendingEncoding = false; /** * Reference to the TCP/IP transport which created us to handle a * new ONC/RPC connection. */ private OncRpcTcpServerTransport parent; /** * Timeout during the phase where data is received within calls, or data is * sent within replies. */ protected int transmissionTimeout; } // End of OncRpcTcpConnectionServerTransport.java remotetea-1.0.7/src/org/acplt/oncrpc/server/OncRpcTcpServerTransport.java0000644005374700003410000005357410736716020027715 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/server/OncRpcTcpServerTransport.java,v 1.3 2008/01/02 15:13:35 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc.server; import org.acplt.oncrpc.*; import java.io.IOException; import java.net.Socket; import java.net.ServerSocket; import java.net.InetAddress; /** * Instances of class OncRpcTcpServerTransport encapsulate * TCP/IP-based XDR streams of ONC/RPC servers. This server transport class * is responsible for accepting new ONC/RPC connections over TCP/IP. * * @see OncRpcServerTransport * @see OncRpcTcpConnectionServerTransport * @see OncRpcUdpServerTransport * * @version $Revision: 1.3 $ $Date: 2008/01/02 15:13:35 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class OncRpcTcpServerTransport extends OncRpcServerTransport { /** * Create a new instance of a OncRpcTcpServerTransport which * encapsulates TCP/IP-based XDR streams of an ONC/RPC server. This * particular server transport only waits for incoming connection requests * and then creates {@link OncRpcTcpConnectionServerTransport} server transports * to handle individual connections. * This constructor is a convenience constructor for those transports * handling only a single ONC/RPC program and version number. * * @param dispatcher Reference to interface of an object capable of * dispatching (handling) ONC/RPC calls. * @param port Number of port where the server will wait for incoming * calls. * @param program Number of ONC/RPC program handled by this server * transport. * @param version Version number of ONC/RPC program handled. * @param bufferSize Size of buffer used when receiving and sending * chunks of XDR fragments over TCP/IP. The fragments built up to * form ONC/RPC call and reply messages. */ public OncRpcTcpServerTransport(OncRpcDispatchable dispatcher, int port, int program, int version, int bufferSize) throws OncRpcException, IOException { this(dispatcher, port, new OncRpcServerTransportRegistrationInfo[] { new OncRpcServerTransportRegistrationInfo(program, version) }, bufferSize); } /** * Create a new instance of a OncRpcTcpServerTransport which * encapsulates TCP/IP-based XDR streams of an ONC/RPC server. This * particular server transport only waits for incoming connection requests * and then creates {@link OncRpcTcpConnectionServerTransport} server transports * to handle individual connections. * * @param dispatcher Reference to interface of an object capable of * dispatching (handling) ONC/RPC calls. * @param port Number of port where the server will wait for incoming * calls. * @param info Array of program and version number tuples of the ONC/RPC * programs and versions handled by this transport. * @param bufferSize Size of buffer used when receiving and sending * chunks of XDR fragments over TCP/IP. The fragments built up to * form ONC/RPC call and reply messages. */ public OncRpcTcpServerTransport(OncRpcDispatchable dispatcher, int port, OncRpcServerTransportRegistrationInfo [] info, int bufferSize) throws OncRpcException, IOException { this(dispatcher, null, port, info, bufferSize); } /** * Create a new instance of a OncRpcTcpServerTransport which * encapsulates TCP/IP-based XDR streams of an ONC/RPC server. This * particular server transport only waits for incoming connection requests * and then creates {@link OncRpcTcpConnectionServerTransport} server transports * to handle individual connections. * * @param dispatcher Reference to interface of an object capable of * dispatching (handling) ONC/RPC calls. * @param bindAddr The local Internet Address the server will bind to. * @param port Number of port where the server will wait for incoming * calls. * @param info Array of program and version number tuples of the ONC/RPC * programs and versions handled by this transport. * @param bufferSize Size of buffer used when receiving and sending * chunks of XDR fragments over TCP/IP. The fragments built up to * form ONC/RPC call and reply messages. */ public OncRpcTcpServerTransport(OncRpcDispatchable dispatcher, InetAddress bindAddr, int port, OncRpcServerTransportRegistrationInfo [] info, int bufferSize) throws OncRpcException, IOException { super(dispatcher, port, info); // // Make sure the buffer is large enough and resize system buffers // accordingly, if possible. // if ( bufferSize < 1024 ) { bufferSize = 1024; } this.bufferSize = bufferSize; socket = new ServerSocket(port, 0, bindAddr); if ( port == 0 ) { this.port = socket.getLocalPort(); } } /** * Close the server transport and free any resources associated with it. * *

Note that the server transport is not deregistered. You'll * have to do it manually if you need to do so. The reason for this * behaviour is, that the portmapper removes all entries regardless of * the protocol (TCP/IP or UDP/IP) for a given ONC/RPC program number * and version. * *

Calling this method on a OncRpcTcpServerTransport * results in the listening TCP network socket immediately being closed. * In addition, all server transports handling the individual TCP/IP * connections will also be closed. The handler threads will therefore * either terminate directly or when they try to sent back replies. */ public void close() { if ( socket != null ) { // // Since there is a non-zero chance of getting race conditions, // we now first set the socket instance member to null, before // we close the corresponding socket. This avoids null-pointer // exceptions in the method which waits for connections: it is // possible that that method is awakened because the socket has // been closed before we could set the socket instance member to // null. Many thanks to Michael Smith for tracking down this one. // ServerSocket deadSocket = socket; socket = null; try { deadSocket.close(); } catch ( IOException e ) { } } // // Now close all per-connection transports currently open... // synchronized ( openTransports ) { while ( openTransports.size() > 0 ) { OncRpcTcpConnectionServerTransport transport = (OncRpcTcpConnectionServerTransport) openTransports.removeFirst(); transport.close(); } } } /** * Removes a TCP/IP server transport from the list of currently open * transports. * * @param transport Server transport to remove from the list of currently * open transports for this listening transport. */ protected void removeTransport(OncRpcTcpConnectionServerTransport transport) { synchronized ( openTransports ) { openTransports.remove((Object)transport); } } /** * Register the TCP/IP port where this server transport waits for incoming * requests with the ONC/RPC portmapper. * * @throws OncRpcException if the portmapper could not be contacted * successfully of if the portmapper rejected port registration(s). */ public void register() throws OncRpcException { try { OncRpcPortmapClient portmapper = new OncRpcPortmapClient(InetAddress.getByName("127.0.0.1")); int size = info.length; for ( int idx = 0; idx < size; ++idx ) { // // Try to register the port for our transport with the local ONC/RPC // portmapper. If this fails, bail out with an exception. // if ( !portmapper.setPort(info[idx].program, info[idx].version, OncRpcProtocols.ONCRPC_TCP, port) ) { throw(new OncRpcException(OncRpcException.RPC_CANNOTREGISTER)); } } } catch ( IOException e ) { throw(new OncRpcException(OncRpcException.RPC_FAILED)); } } /** * Do not call. * * @throws Error because this method must not be called for a listening * server transport. */ public void retrieveCall(XdrAble call) throws OncRpcException, IOException { throw(new Error("OncRpcTcpServerTransport.retrieveCall() is abstract " +"and can not be called.")); } /** * Do not call. * * @throws Error because this method must not be called for a listening * server transport. */ protected XdrDecodingStream getXdrDecodingStream() { throw(new Error("OncRpcTcpServerTransport.getXdrDecodingStream() is abstract " +"and can not be called.")); } /** * Do not call. * * @throws Error because this method must not be called for a listening * server transport. */ protected void endDecoding() throws OncRpcException, IOException { throw(new Error("OncRpcTcpServerTransport.endDecoding() is abstract " +"and can not be called.")); } /** * Do not call. * * @throws Error because this method must not be called for a listening * server transport. */ protected XdrEncodingStream getXdrEncodingStream() { throw(new Error("OncRpcTcpServerTransport.getXdrEncodingStream() is abstract " +"and can not be called.")); } /** * Do not call. * * @throws Error because this method must not be called for a listening * server transport. */ protected void beginEncoding(OncRpcCallInformation callInfo, OncRpcServerReplyMessage state) throws OncRpcException, IOException { throw(new Error("OncRpcTcpServerTransport.beginEncoding() is abstract " +"and can not be called.")); } /** * Do not call. * * @throws Error because this method must not be called for a listening * server transport. */ protected void endEncoding() throws OncRpcException, IOException { throw(new Error("OncRpcTcpServerTransport.endEncoding() is abstract " +"and can not be called.")); } /** * Do not call. * * @throws Error because this method must not be called for a listening * server transport. */ protected void reply(OncRpcCallInformation callInfo, OncRpcServerReplyMessage state, XdrAble reply) throws OncRpcException, IOException { throw(new Error("OncRpcTcpServerTransport.reply() is abstract " +"and can not be called.")); } /** * Creates a new thread and uses this thread to listen to incoming * ONC/RPC requests, then dispatches them and finally sends back the * appropriate reply messages. Control in the calling thread immediately * returns after the handler thread has been created. * *

For every incomming TCP/IP connection a handler thread is created * to handle ONC/RPC calls on this particular connection. */ public void listen() { // // Create a new (daemon) thread which will handle incoming connection // requests. // Thread listenThread = new Thread("TCP server transport listener thread") { public void run() { for ( ;; ) { try { // // Now wait for (new) connection requests to come in. // ServerSocket myServerSocket = socket; if ( myServerSocket == null ) { break; } Socket newSocket = myServerSocket.accept(); OncRpcTcpConnectionServerTransport transport = new OncRpcTcpConnectionServerTransport( dispatcher, newSocket, info, bufferSize, OncRpcTcpServerTransport.this, transmissionTimeout); synchronized ( openTransports ) { openTransports.add((Object)transport); } // // Let the newly created transport object handle this // connection. Note that it will create its own // thread for handling. // transport.listen(); } catch ( OncRpcException e ) { } catch ( IOException e ) { // // We are just ignoring most of the IOExceptions as // they might be thrown, for instance, if a client // attempts a connection and resets it before it is // pulled off by accept(). If the socket has been // gone away after an IOException this means that the // transport has been closed, so we end this thread // gracefully. // if ( socket == null ) { break; } } } } }; // // Now make the new handling thread a deamon and start it, so it // sits there waiting for incoming TCP/IP connection requests. // listenThread.setDaemon(true); listenThread.start(); } /** * Set the timeout used during transmission of data. If the flow of data * when sending calls or receiving replies blocks longer than the given * timeout, an exception is thrown. The timeout must be > 0. * * @param milliseconds Transmission timeout in milliseconds. */ public void setTransmissionTimeout(int milliseconds) { if ( milliseconds <= 0 ) { throw(new IllegalArgumentException("transmission timeout must be > 0")); } transmissionTimeout = milliseconds; } /** * Retrieve the current timeout used during transmission phases (call and * reply phases). * * @return Current transmission timeout. */ public int getTransmissionTimeout() { return transmissionTimeout; } /** * Set the character encoding for (de-)serializing strings. * * @param characterEncoding the encoding to use for (de-)serializing strings. * If null, the system's default encoding is to be used. */ public void setCharacterEncoding(String characterEncoding) { this.characterEncoding = characterEncoding; } /** * Get the character encoding for (de-)serializing strings. * * @return the encoding currently used for (de-)serializing strings. * If null, then the system's default encoding is used. */ public String getCharacterEncoding() { return characterEncoding; } /** * TCP socket used for stream-based communication with ONC/RPC * clients. */ private ServerSocket socket; /** * Size of send/receive buffers to use when encoding/decoding XDR data. */ private int bufferSize; /** * Collection containing currently open transports. */ private TransportList openTransports = new TransportList(); /** * Timeout during the phase where data is received within calls, or data is * sent within replies. */ protected int transmissionTimeout = 30000; /** * Encoding to use when deserializing strings or null if * the system's default encoding should be used. */ private String characterEncoding = null; /** * Minumum implementation of a double linked list which notices which * transports are currently open and have to be shut down when this * listening transport is shut down. The only reason why we have this * code here instead of using java.util.LinkedList is due to JDK 1.1 * compatibility. * *

Note that the methods are not synchronized as we leave this up * to the caller, who can thus optimize access during critical sections. */ private class TransportList { /** * Create a new instance of a list of open transports. */ public TransportList() { // // Link header node with itself, so it is its own successor // and predecessor. Using a header node excuses us from checking // for the special cases of first and last node (or both at // the same time). // head.next = head; head.prev = head; } /** * Add new transport to list of open transports. The new transport * is always added immediately after the head of the linked list. */ public void add(Object o) { Node node = new Node(o); node.next = head.next; head.next = node; node.prev = head; node.next.prev = node; ++size; } /** * Remove given transport from list of open transports. */ public boolean remove(Object o) { Node node = head.next; while ( node != head ) { if ( node.item == o ) { node.prev.next = node.next; node.next.prev = node.prev; --size; return true; } node = node.next; } return false; } /** * Removes and returns the first open transport from list. */ public Object removeFirst() { // // Do not remove the header node. // if ( size == 0 ) { throw(new java.util.NoSuchElementException()); } Node node = head.next; head.next = node.next; node.next.prev = head; --size; return node.item; } /** * Returns the number of (open) transports in this list. * * @return the number of (open) transports. */ public int size() { return size; } /** * Head node for list of open transports which does not represent * an open transport but instead excuses us of dealing with all * the special cases of real nodes at the begin or end of the list. */ private Node head = new Node(null); /** * Number of (real) open transports currently registered in this * list. */ private int size = 0; /** * Node class referencing an individual open transport and holding * references to the previous and next open transports. */ private class Node { /** * Create a new instance of a node object and let it reference * an open transport. The creator of this object is then * responsible for adding this node to the circular list itself. */ public Node(Object item) { this.item = item; } /** * Next item node (in other words: next open transport) * in the list. This will never be null for the * first item, but instead reference the last item. Thus, the * list is circular. */ Node next; /** * Previous item node (in other words: previous open transport) * in the list. This will never be null for the * last item, but instead reference the first item. Thus, the * list is circular. */ Node prev; /** * The item/object placed at this position in the list. This * currently always references an open transport. */ Object item; } } } // End of OncRpcTcpServerTransport.java remotetea-1.0.7/src/org/acplt/oncrpc/server/OncRpcUdpServerTransport.java0000644005374700003410000005503710736716020027713 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/server/OncRpcUdpServerTransport.java,v 1.4 2008/01/02 15:13:35 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc.server; import org.acplt.oncrpc.*; import java.io.IOException; import java.net.DatagramSocket; import java.net.InetAddress; /** * Instances of class OncRpcUdpServerTransport encapsulate * UDP/IP-based XDR streams of ONC/RPC servers. This server transport class * is responsible for receiving ONC/RPC calls over UDP/IP. * * @see OncRpcServerTransport * @see OncRpcTcpServerTransport * * @version $Revision: 1.4 $ $Date: 2008/01/02 15:13:35 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class OncRpcUdpServerTransport extends OncRpcServerTransport { /** * Create a new instance of a OncRpcUdpServerTransport which * encapsulates UDP/IP-based XDR streams of an ONC/RPC server. Using a * server transport, ONC/RPC calls are received and the corresponding * replies are sent back. * This constructor is a convenience constructor for those transports * handling only a single ONC/RPC program and version number. * * @param dispatcher Reference to interface of an object capable of * dispatching (handling) ONC/RPC calls. * @param port Number of port where the server will wait for incoming * calls. * @param program Number of ONC/RPC program handled by this server * transport. * @param version Version number of ONC/RPC program handled. * @param bufferSize Size of buffer for receiving and sending UDP/IP * datagrams containing ONC/RPC call and reply messages. */ public OncRpcUdpServerTransport(OncRpcDispatchable dispatcher, int port, int program, int version, int bufferSize) throws OncRpcException, IOException { this(dispatcher, port, new OncRpcServerTransportRegistrationInfo [] { new OncRpcServerTransportRegistrationInfo(program, version) }, bufferSize); } /** * Create a new instance of a OncRpcUdpServerTransport which * encapsulates UDP/IP-based XDR streams of an ONC/RPC server. Using a * server transport, ONC/RPC calls are received and the corresponding * replies are sent back. * This constructor is a convenience constructor for those transports * handling only a single ONC/RPC program and version number. * * @param dispatcher Reference to interface of an object capable of * dispatching (handling) ONC/RPC calls. * @param port Number of port where the server will wait for incoming * calls. * @param info Array of program and version number tuples of the ONC/RPC * programs and versions handled by this transport. * @param bufferSize Size of buffer for receiving and sending UDP/IP * datagrams containing ONC/RPC call and reply messages. */ public OncRpcUdpServerTransport(OncRpcDispatchable dispatcher, int port, OncRpcServerTransportRegistrationInfo [] info, int bufferSize) throws OncRpcException, IOException { this(dispatcher, null, port, info, bufferSize); } /** * Create a new instance of a OncRpcUdpServerTransport which * encapsulates UDP/IP-based XDR streams of an ONC/RPC server. Using a * server transport, ONC/RPC calls are received and the corresponding * replies are sent back. * This constructor is a convenience constructor for those transports * handling only a single ONC/RPC program and version number. * * @param dispatcher Reference to interface of an object capable of * dispatching (handling) ONC/RPC calls. * @param bindAddr The local Internet Address the server will bind to. * @param port Number of port where the server will wait for incoming * calls. * @param info Array of program and version number tuples of the ONC/RPC * programs and versions handled by this transport. * @param bufferSize Size of buffer for receiving and sending UDP/IP * datagrams containing ONC/RPC call and reply messages. */ public OncRpcUdpServerTransport(OncRpcDispatchable dispatcher, InetAddress bindAddr, int port, OncRpcServerTransportRegistrationInfo [] info, int bufferSize) throws OncRpcException, IOException { super(dispatcher, port, info); // // Make sure the buffer is large enough and resize system buffers // accordingly, if possible. // if ( bufferSize < 1024 ) { bufferSize = 1024; } socket = new DatagramSocket(port, bindAddr); socketHelper = new OncRpcUdpSocketHelper(socket); if ( port == 0 ) { this.port = socket.getLocalPort(); } if ( socketHelper.getSendBufferSize() < bufferSize ) { socketHelper.setSendBufferSize(bufferSize); } if ( socketHelper.getReceiveBufferSize() < bufferSize ) { socketHelper.setReceiveBufferSize(bufferSize); } // // Create the necessary encoding and decoding streams, so we can // communicate at all. // sendingXdr = new XdrUdpEncodingStream(socket, bufferSize); receivingXdr = new XdrUdpDecodingStream(socket, bufferSize); } /** * Close the server transport and free any resources associated with it. * *

Note that the server transport is not deregistered. You'll * have to do it manually if you need to do so. The reason for this * behaviour is, that the portmapper removes all entries regardless of * the protocol (TCP/IP or UDP/IP) for a given ONC/RPC program number * and version. * *

Calling this method on a OncRpcUdpServerTransport * results in the UDP network socket immediately being closed. The * handler thread will therefore either terminate directly or when it * tries to sent back a reply which it was about to handle at the time * the close method was called. */ public void close() { if ( socket != null ) { // // Since there is a non-zero chance of getting race conditions, // we now first set the socket instance member to null, before // we close the corresponding socket. This avoids null-pointer // exceptions in the method which waits for new requests: it is // possible that this method is awakened because the socket has // been closed before we could set the socket instance member to // null. Many thanks to Michael Smith for tracking down this one. // DatagramSocket deadSocket = socket; socket = null; deadSocket.close(); } if ( sendingXdr != null ) { XdrEncodingStream deadXdrStream = sendingXdr; sendingXdr = null; try { deadXdrStream.close(); } catch ( IOException e ) { } catch ( OncRpcException e ) { } } if ( receivingXdr != null ) { XdrDecodingStream deadXdrStream = receivingXdr; receivingXdr = null; try { deadXdrStream.close(); } catch ( IOException e ) { } catch ( OncRpcException e ) { } } } /** * Register the UDP/IP port where this server transport waits for incoming * requests with the ONC/RPC portmapper. * * @throws OncRpcException if the portmapper could not be contacted * successfully. */ public void register() throws OncRpcException { try { OncRpcPortmapClient portmapper = new OncRpcPortmapClient(InetAddress.getByName("127.0.0.1")); int size = info.length; for ( int idx = 0; idx < size; ++idx ) { // // Try to register the port for our transport with the local ONC/RPC // portmapper. If this fails, bail out with an exception. // if ( !portmapper.setPort(info[idx].program, info[idx].version, OncRpcProtocols.ONCRPC_UDP, port) ) { throw(new OncRpcException(OncRpcException.RPC_CANNOTREGISTER)); } } } catch ( IOException e ) { throw(new OncRpcException(OncRpcException.RPC_FAILED)); } } /** * Retrieves the parameters sent within an ONC/RPC call message. It also * makes sure that the deserialization process is properly finished after * the call parameters have been retrieved. Under the hood this method * therefore calls {@link XdrDecodingStream#endDecoding} to free any * pending resources from the decoding stage. * * @throws OncRpcException if an ONC/RPC exception occurs, like the data * could not be successfully deserialized. * @throws IOException if an I/O exception occurs, like transmission * failures over the network, etc. */ protected void retrieveCall(XdrAble call) throws OncRpcException, IOException { call.xdrDecode(receivingXdr); if ( pendingDecoding ) { pendingDecoding = false; receivingXdr.endDecoding(); } } /** * Returns XDR stream which can be used for deserializing the parameters * of this ONC/RPC call. This method belongs to the lower-level access * pattern when handling ONC/RPC calls. * * @return Reference to decoding XDR stream. */ protected XdrDecodingStream getXdrDecodingStream() { return receivingXdr; } /** * Finishes call parameter deserialization. Afterwards the XDR stream * returned by {@link #getXdrDecodingStream} must not be used any more. * This method belongs to the lower-level access pattern when handling * ONC/RPC calls. * * @throws OncRpcException if an ONC/RPC exception occurs, like the data * could not be successfully deserialized. * @throws IOException if an I/O exception occurs, like transmission * failures over the network, etc. */ protected void endDecoding() throws OncRpcException, IOException { if ( pendingDecoding ) { pendingDecoding = false; receivingXdr.endDecoding(); } } /** * Returns XDR stream which can be used for eserializing the reply * to this ONC/RPC call. This method belongs to the lower-level access * pattern when handling ONC/RPC calls. * * @return Reference to enecoding XDR stream. */ protected XdrEncodingStream getXdrEncodingStream() { return sendingXdr; } /** * Begins the sending phase for ONC/RPC replies. * This method belongs to the lower-level access pattern when handling * ONC/RPC calls. * * @param callInfo Information about ONC/RPC call for which we are about * to send back the reply. * @param state ONC/RPC reply header indicating success or failure. * * @throws OncRpcException if an ONC/RPC exception occurs, like the data * could not be successfully serialized. * @throws IOException if an I/O exception occurs, like transmission */ protected void beginEncoding(OncRpcCallInformation callInfo, OncRpcServerReplyMessage state) throws OncRpcException, IOException { // // In case decoding has not been properly finished, do it now to // free up pending resources, etc. // if ( pendingDecoding ) { pendingDecoding = false; receivingXdr.endDecoding(); } // // Now start encoding using the reply message header first... // sendingXdr.beginEncoding(callInfo.peerAddress, callInfo.peerPort); state.xdrEncode(sendingXdr); } /** * Finishes encoding the reply to this ONC/RPC call. Afterwards you must * not use the XDR stream returned by {@link #getXdrEncodingStream} any * longer. * * @throws OncRpcException if an ONC/RPC exception occurs, like the data * could not be successfully serialized. * @throws IOException if an I/O exception occurs, like transmission * failures over the network, etc. */ protected void endEncoding() throws OncRpcException, IOException { // // Close the case. Finito. // sendingXdr.endEncoding(); } /** * Send back an ONC/RPC reply to the original caller. This is rather a * low-level method, typically not used by applications. Dispatcher handling * ONC/RPC calls have to use the * {@link OncRpcCallInformation#reply(XdrAble)} method instead on the * call object supplied to the handler. * * @param callInfo information about the original call, which are necessary * to send back the reply to the appropriate caller. * @param state ONC/RPC reply message header indicating success or failure * and containing associated state information. * @param reply If not null, then this parameter references * the reply to be serialized after the reply message header. * * @throws OncRpcException if an ONC/RPC exception occurs, like the data * could not be successfully serialized. * @throws IOException if an I/O exception occurs, like transmission * failures over the network, etc. * * @see OncRpcCallInformation * @see OncRpcDispatchable */ protected void reply(OncRpcCallInformation callInfo, OncRpcServerReplyMessage state, XdrAble reply) throws OncRpcException, IOException { beginEncoding(callInfo, state); if ( reply != null ) { reply.xdrEncode(sendingXdr); } endEncoding(); } /** * Creates a new thread and uses this thread to listen to incoming * ONC/RPC requests, then dispatches them and finally sends back the * appropriate reply messages. Control in the calling thread immediately * returns after the handler thread has been created. * *

Currently only one call after the other is dispatched, so no * multithreading is done when receiving multiple calls. Instead, later * calls have to wait for the current call to finish before they are * handled. */ public void listen() { Thread listener = new Thread("UDP server transport listener thread") { public void run() { _listen(); } }; listener.setDaemon(true); listener.start(); } /** * The real workhorse handling incoming requests, dispatching them and * sending back replies. */ public void _listen() { OncRpcCallInformation callInfo = new OncRpcCallInformation(this); for ( ;; ) { // // Start decoding the incomming call. This involves remembering // from whom we received the call so we can later send back the // appropriate reply message. // Note that for UDP-based communication we don't need to deal // with timeouts. // try { pendingDecoding = true; receivingXdr.beginDecoding(); callInfo.peerAddress = receivingXdr.getSenderAddress(); callInfo.peerPort = receivingXdr.getSenderPort(); } catch ( IOException e ) { // // In case of I/O Exceptions (especially socket exceptions) // close the file and leave the stage. There's nothing we can // do anymore. // close(); return; } catch ( OncRpcException e ) { // // In case of ONC/RPC exceptions at this stage we're silently // ignoring that there was some data coming in... // continue; } try { // // Pull off the ONC/RPC call header of the XDR stream. // callInfo.callMessage.xdrDecode(receivingXdr); } catch ( IOException e ) { // // In case of I/O Exceptions (especially socket exceptions) // close the file and leave the stage. There's nothing we can // do anymore. // close(); return; } catch ( OncRpcException e ) { // // In case of ONC/RPC exceptions at this stage we're silently // ignoring that there was some data coming in, as we're not // sure we got enough information to send a matching reply // message back to the caller. // if ( pendingDecoding ) { pendingDecoding = false; try { receivingXdr.endDecoding(); } catch ( IOException e2 ) { close(); return; } catch ( OncRpcException e2 ) { } } continue; } try { // // Let the dispatcher retrieve the call parameters, work on // it and send back the reply. // To make it once again clear: the dispatch called has to // pull off the parameters of the stream! // dispatcher.dispatchOncRpcCall(callInfo, callInfo.callMessage.program, callInfo.callMessage.version, callInfo.callMessage.procedure); } catch ( Exception e ) { // // In case of some other runtime exception, we report back to // the caller a system error. // // In case of UDP-bases transports we can do so, because we // know that we can reset the buffer and serialize another // reply message even in case we caught some OncRpcException. // // Note that we "kill" the transport by closing it when we // got stuck with an I/O exception when trying to send back // an error reply. // if ( pendingDecoding ) { pendingDecoding = false; try { receivingXdr.endDecoding(); } catch ( IOException e2 ) { close(); return; } catch ( OncRpcException e2 ) { } } // // Check for authentication exceptions, which are reported back // as is. Otherwise, just report a system error // -- very generic, indeed. // try { if ( e instanceof OncRpcAuthenticationException ) { callInfo.failAuthenticationFailed( ((OncRpcAuthenticationException) e).getAuthStatus()); } else { callInfo.failSystemError(); } } catch ( IOException e2 ) { close(); return; } catch ( OncRpcException e2 ) { } // // Phew. Done with the error reply. So let's wait for new // incoming ONC/RPC calls... // } } } /** * Set the character encoding for (de-)serializing strings. * * @param characterEncoding the encoding to use for (de-)serializing strings. * If null, the system's default encoding is to be used. */ public void setCharacterEncoding(String characterEncoding) { sendingXdr.setCharacterEncoding(characterEncoding); receivingXdr.setCharacterEncoding(characterEncoding); } /** * Get the character encoding for (de-)serializing strings. * * @return the encoding currently used for (de-)serializing strings. * If null, then the system's default encoding is used. */ public String getCharacterEncoding() { return sendingXdr.getCharacterEncoding(); } /** * UDP socket used for datagram-based communication with ONC/RPC * clients. */ private DatagramSocket socket; /** * Socket helper object supplying missing methods for JDK 1.1 * backwards compatibility. So much for compile once, does not run * everywhere. */ private OncRpcUdpSocketHelper socketHelper; /** * XDR encoding stream used for sending replies via UDP/IP back to an * ONC/RPC client. */ private XdrUdpEncodingStream sendingXdr; /** * XDR decoding stream used when receiving requests via UDP/IP from * ONC/RPC clients. */ private XdrUdpDecodingStream receivingXdr; /** * Indicates that BeginDecoding has been called for the * receiving XDR stream, so that it should be closed later using * EndDecoding. */ private boolean pendingDecoding = false; } // End of OncRpcUdpServerTransport.java remotetea-1.0.7/src/org/acplt/oncrpc/server/package.html0000644005374700003410000002513710627063100024357 0ustar piccainstrumentation ONC/RPC Server for Java package ONC/RPC Server support package.

This package implements classes needed to write ONC/RPC servers according to Sun's ONC/RPC Remote Procedure Call specification (see RFC 1831, RFC 1832, RFC 1833).

Here is a short introduction to writing ONC/RPC servers. However, at the moment this might be not as convenient as you would like it to be, but rather low-level. Nevertheless, here are the basic steps to write a simple ONC/RPC server. Please also take a look at src/tests/org/acplt/oncrpc/ServerTest.java.

To implement an ONC/RPC server, you need to implement the OncRpcDispatchable interface. This requires implementing the dispatchOncRpcCall method, which handles incoming ONC/RPC calls. In the following code snippet we show how to handle the ping request (ONC/RPC procedure number 0):

public void dispatchOncRpcCall(OncRpcCallInformation call,
                               int program, int version, int procedure)
       throws OncRpcException, IOException {
    System.out.println("Incomming call for program "
                       + Integer.toHexString(program)
                       + "; version " + version
                       + "; procedure " + Integer.toHexString(procedure));
    switch ( procedure ) {
    //
    // Implement ping call...
    //
    case 0:
        call.retrieveCall(XdrVoid.XDR_VOID);
        call.reply(XdrVoid.XDR_VOID);
        break;
    //
    // For all unknown calls, send back an error reply.
    //
    default:
        call.failProcedureUnavailable();
    }
}

For every incoming ONC/RPC call, you'll receive some information about the call through the call parameter (of class OncRpcCallInformation). The call object is necessary to retrieve the parameters of the call as well as to sent back the reply. For the ping call (procedure number 0), the ONC/RPC dispatcher shown above simply retrieves the parameters using retrieveCall(XdrAble). Because the call expects no parameters, we supply the static void object XdrVoid.XDR_VOID to the retrieveCall method.

To send back the reply for the ping call, we use OncRpcCallInformation(XdrAble). Again, the caller does not expect any reply, so we specify the static void object XdrVoid.XDR_VOID once more. Then, we simply return and let the ONC/RPC magic sending back the reply.

In case we receive an ONC/RPC call for an unknown procedure (and / or version) we simply call the failProcedureUnavailable() method of the call object.

Now that we have solved the handling of ONC/RPC calls, we can now set up the stage, also known as an ONC/RPC server. To receive incoming calls, you first need to create so-called ONC/RPC server transports. In our example we will create one transport for each the UDP/IP and TCP/IP protocols. When creating a server transport, you need to specify in the call to the constructor:

  • the object which will handle incoming ONC/RPC calls,
  • the port number where to wait for incoming calls (if you do not need to listen at a specific port number, just specify 0, so the system will choose the next free port number for you),
  • the program number to handle through the transport,
  • the program's version number,
  • and finally an optional buffer size. This buffer size is especially important for UDP/IP-based transports, as they are only able to receive calls and send back replies not larger than the buffer size. For TCP/IP-based transport the buffer size only affects how efficient the network communication will be, for instance, how often the buffer needs to be flushed and data transmitted over the network. Especially with large calls or replies, larger buffer sizes can improve communication speed.
OncRpcUdpServerTransport udpTrans =
    new OncRpcUdpServerTransport(this, 55555, 0x49679, 1, 8192);
OncRpcTcpServerTransport tcpTrans =
    new OncRpcTcpServerTransport(this, 55555, 0x49679, 1, 8192);

When you're ready, you should first register your ONC/RPC server with the (local) portmapper by calling the register() method on all server transports you created during the previous step. Then start listening on these transports by calling their listen() methods.

udpTrans.register();
tcpTrans.register();

tcpTrans.listen();
udpTrans.listen();

System.out.println("Server started.");

Note that the listen() methods will create new threads, which then will be responsible for handling incoming ONC/RPC calls. Note that you may need to make your ONC/RPC dispatch handler (OncRpcDispatchable) synchronized if you can not handle simultaneous calls from multiple threads at the same time.

The tricky part is stopping the server somehow. Unfortunately, this is not an easy issue on Java platforms and up to you. For an example, look at the source of the src/tests/org/acplt/oncrpc/ServerTest.java example. Basically, this example uses the ONC/RPC call 42 to shut down a server.

After you have received the shutdown notification you can shut down the server transports (for instance) from your main thread using the close() method:

tcpTrans.unregister();
tcpTrans.close();

udpTrans.unregister();
udpTrans.close();

System.out.println("Server shut down.");

You should also deregister your server from the portmapper at the same time you're closing the transports. Note that the OncRpcTcpServerTransport.close() method also closes all currently open TCP/IP transports which have been created to handle individual TCP/IP connections from individual clients.

Now that's basically all you need to know to write ONC/RPC servers. However, if you plan to mess with authentication, read on...

ONC/RPC authentication on the server side is done within the call dispatcher. Before executing an ONC/RPC call, first check the authentication object for kosher information:

public void dispatchOncRpcCall(OncRpcCallInformation call,
                               int program, int version, int procedure)
       throws OncRpcException, IOException {
    switch ( call.callMessage.auth.getAuthenticationType() )
    case OncRpcAuthType.ONCRPC_AUTH_UNIX:
        ...
        break;
    case OncRpcAuthType.ONCRPC_AUTH_SHORT:
        ...
        break;
    case OncRpcAuthType.ONCRPC_AUTH_NONE:
    default:
        throw(new OncRpcAuthenticationException(
                      OncRpcAuthStatus.ONCRPC_AUTH_BADCRED));
    }

The example above is a very restrictive one in that it even forbids ONC/RPC clients to ping the server without proper authentication.

In a more elaborate example below you can see how to handle authentication of type AUTH_UNIX. It also shows how to use shorthand credentials, if you like.

public void dispatchOncRpcCall(OncRpcCallInformation call,
                               int program, int version, int procedure)
       throws OncRpcException, IOException {
    switch ( call.callMessage.auth.getAuthenticationType() )
    case OncRpcAuthType.ONCRPC_AUTH_UNIX:
        OncRpcServerAuthUnix auth = (OncRpcServerAuthUnix) call.callMessage.auth;
        if ( (auth.uid != 42)
             && (auth.gid != 815) ) {
            throw(new OncRpcAuthenticationException(
                          OncRpcAuthStatus.ONCRPC_AUTH_BADCRED));
        }
        //
        // Suggest shorthand authentication...
        //
        XdrBufferEncodingStream xdr = new XdrBufferEncodingStream(8);
        xdr.beginEncoding(null, 0);
        xdr.xdrEncodeInt(42);
        xdr.xdrEncodeInt(~42);
        xdr.endEncoding();
        //
        // ATTENTION: this will return the *whole* buffer created by the
        // constructor of XdrBufferEncodingStream(len) above. So make sure
        // that you really want to return the whole buffer!
        //
        auth.setShorthandVerifier(xdr.getXdrData());
        break;

    case OncRpcAuthType.ONCRPC_AUTH_SHORT:
        //
        // Check shorthand credentials.
        //
        OncRpcServerAuthShort auth = (OncRpcServerAuthShort) call.callMessage.auth;
        XdrBufferDecodingStream xdr =
            new XdrBufferDecodingStream(auth.getShorthandCred());
        xdr.beginDecoding();
        int credv1 = xdr.xdrDecodeInt();
        int credv2 = xdr.xdrDecodeInt();
        xdr.endDecoding();
        if ( credv1 != ~credv2 ) {
            throw(new OncRpcAuthenticationException(
                          OncRpcAuthStatus.ONCRPC_AUTH_REJECTEDCRED));
        }
        if ( (++shorthandCredCounter % 3) == 0 ) {
            throw(new OncRpcAuthenticationException(
                          OncRpcAuthStatus.ONCRPC_AUTH_REJECTEDCRED));
        }
        break;

    case OncRpcAuthType.ONCRPC_AUTH_NONE:
        if ( procedure != 0 ) {
            throw(new OncRpcAuthenticationException(
                          OncRpcAuthStatus.ONCRPC_AUTH_BADCRED));
        }

    default:
        throw(new OncRpcAuthenticationException(
                      OncRpcAuthStatus.ONCRPC_AUTH_BADCRED));
    }
    
    switch ( procedure ) {
        ...
    }
}

This package is part of the ACPLT/KS ACPLTea Java Library package.

(c) 1999, 2006 Harald Albrecht.
(c) 1999 Lehrstuhl für Prozeßleittechnik, Aachen University of Technology, Germany.

This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details.

You should have received a copy of the GNU Library General Public License along with this program (see the file COPYING.LIB for more details); if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. remotetea-1.0.7/src/org/acplt/oncrpc/web/0000755005374700003410000000000010736702150021343 5ustar piccainstrumentationremotetea-1.0.7/src/org/acplt/oncrpc/web/Base64.java0000644005374700003410000002076307716406400023245 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/web/Base64.java,v 1.1.1.1 2003/08/13 12:03:44 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc.web; /** * The abstract Base64 class provides static methods to convert * back and forth between binary and base64-encoded data. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:44 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public abstract class Base64 { /** * Converts binary data into base64 encoded data. * * @param binaryData Binary data to be encoded. * @param binaryOffset Offset into binaryData where to * the data to be encoded begins. * @param length Length of data to encode. * @param encodedData Buffer receiving base64 encoded data. * @param encodedOffset Offset into encodedData where the * store base64 encoded data. * * @return Length of encoded base64 data. */ public static int encode(byte [] binaryData, int binaryOffset, int length, byte [] encodedData, int encodedOffset) { // // Calculate length of encoded data including optional padding. // int encodedLength = ((length + 2) / 3) * 4; // // Now do the encoding, thus inflating every three bytes of binary // data to four ASCII characters. // int b1, b2, b3; int endPos = binaryOffset + length - 1 - 2; while ( binaryOffset <= endPos ) { b1 = binaryData[binaryOffset++]; b2 = binaryData[binaryOffset++]; b3 = binaryData[binaryOffset++]; encodedData[encodedOffset++] = encodingBase64Alephbeth[(b1 >>> 2) & 0x3F]; encodedData[encodedOffset++] = encodingBase64Alephbeth[((b1 << 4) & 0x30) | ((b2 >>> 4) & 0xF)]; encodedData[encodedOffset++] = encodingBase64Alephbeth[((b2 << 2) & 0x3C) | ((b3 >>> 6) & 0x03)]; encodedData[encodedOffset++] = encodingBase64Alephbeth[b3 & 0x3F]; } // // If one or two bytes are left (because we work on blocks of three // bytes), convert them too and apply padding. // endPos += 2; // now points to the last encodable byte if ( binaryOffset <= endPos ) { b1 = binaryData[binaryOffset++]; encodedData[encodedOffset++] = encodingBase64Alephbeth[(b1 >>> 2) & 0x3F]; if ( binaryOffset <= endPos ) { b2 = binaryData[binaryOffset++]; encodedData[encodedOffset++] = encodingBase64Alephbeth[((b1 << 4) & 0x30) | ((b2 >>> 4) & 0xF)]; encodedData[encodedOffset++] = encodingBase64Alephbeth[(b2 << 2) & 0x3C]; encodedData[encodedOffset] = '='; } else { encodedData[encodedOffset++] = encodingBase64Alephbeth[(b1 << 4) & 0x30]; encodedData[encodedOffset++] = '='; encodedData[encodedOffset] = '='; } } // // Finally return length of encoded data // return encodedLength; } /** * Converts base64 encoded data into binary data. * * @param encodedData Base64 encoded data. * @param encodedOffset Offset into encodedData where the * base64 encoded data starts. * @param length Length of encoded data. * @param binaryData Decoded (binary) data. * @param binaryOffset Offset into binaryData where to * store the decoded binary data. * * @return Length of decoded binary data. */ public static int decode(byte [] encodedData, int encodedOffset, int length, byte [] binaryData, int binaryOffset) { // // Determine the length of data to be decoded. Optional padding has // to be removed first (of course). // int endPos = encodedOffset + length - 1; while ( (endPos >= 0) && (encodedData[endPos] == '=') ) { --endPos; } // next line was: endPos - length / 4 + 1 int binaryLength = endPos - encodedOffset - length / 4 + 1; // // Now do the four-to-three entities/letters/bytes/whatever // conversion. We chew on as many four-letter groups as we can, // converting them into three byte groups. // byte b1, b2, b3, b4; int stopPos = endPos - 3; // now points to the last letter in the // last four-letter group while ( encodedOffset <= stopPos ) { b1 = decodingBase64Alephbeth[encodedData[encodedOffset++]]; b2 = decodingBase64Alephbeth[encodedData[encodedOffset++]]; b3 = decodingBase64Alephbeth[encodedData[encodedOffset++]]; b4 = decodingBase64Alephbeth[encodedData[encodedOffset++]]; binaryData[binaryOffset++] = (byte)(((b1 << 2) & 0xFF) | ((b2 >>> 4) & 0x03)); binaryData[binaryOffset++] = (byte)(((b2 << 4) & 0xFF) | ((b3 >>> 2) & 0x0F)); binaryData[binaryOffset++] = (byte)(((b3 << 6) & 0xFF) | (b4 & 0x3F)); } // // If one, two or three letters from the base64 encoded data are // left, convert them too. // Hack Note(tm): if the length of encoded data is not a multiple // of four, then padding must occur ('='). As the decoding alphabet // contains zeros everywhere with the exception of valid letters, // indexing into the mapping is just fine and reliefs us of the // pain to check everything and make thus makes the code better. // if ( encodedOffset <= endPos ) { b1 = decodingBase64Alephbeth[encodedData[encodedOffset++]]; b2 = decodingBase64Alephbeth[encodedData[encodedOffset++]]; binaryData[binaryOffset++] = (byte)(((b1 << 2) & 0xFF) | ((b2 >>> 4) & 0x03)); if ( encodedOffset <= endPos ) { b3 = decodingBase64Alephbeth[encodedData[encodedOffset]]; binaryData[binaryOffset++] = (byte)(((b2 << 4) & 0xFF) | ((b3 >>> 2) & 0x0F)); } } // // Okay. That's it for now. Just return the length of decoded data. // return binaryLength; } /** * Mapping from binary 0-63 to base64 alphabet according to RFC 2045. * (Yes, I do know that the Hebrew alphabet has only 22 letters.) */ private static final byte [] encodingBase64Alephbeth = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' }; /** * Mapping from base64 alphabet to binary 0-63. */ private static final byte [] decodingBase64Alephbeth; /** * The class initializer is responsible to set up the mapping from the * base64 alphabet (ASCII-based) to binary 0-63. */ static { decodingBase64Alephbeth = new byte[256]; for ( int i = 0; i < 64; ++i ) { decodingBase64Alephbeth[encodingBase64Alephbeth[i]] = (byte) i; } } } // End of Base64.java remotetea-1.0.7/src/org/acplt/oncrpc/web/HttpClientConnection.java0000644005374700003410000014702407716406402026321 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/web/HttpClientConnection.java,v 1.1.1.1 2003/08/13 12:03:45 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc.web; import java.io.IOException; import java.io.OutputStream; import java.io.BufferedOutputStream; import java.io.InputStream; import java.io.BufferedInputStream; import java.net.InetAddress; import java.net.Socket; import java.net.ProtocolException; import java.security.AccessController; import java.security.PrivilegedAction; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; import org.acplt.oncrpc.OncRpcConstants; /** * The class HttpClientConnection provides a simple HTTP/1.1 * compliant connection from a client to an HTTP server. This class does not * provide a full-blown HTTP connection, but it is rather optimized for what * ONC/RPC clients need in order to tunnel ONC remote procedure calls through * ordinary HTTP connections, thus penetrating firewalls. * *

A HttpClientConnection is not that clever as you would * first expect. Rather you have to do some things for yourself, like * reconnecting dropped connections, and so on. While this sometimes result * in more labour on the caller's shoulders, this keeps resource wasting at * a minimum, and gives you full control over redirections and other mess -- * you do want full control, right?. * *

For this reason, for instance, an HttpClientConnection * does not buffer the whole request before sending it to the server but * rather relies on the caller to supply the right content-length information. * This avoids unnecessary double buffering but instead creates the bas64 * encoded content on-the-fly. * *

Of course, this client connection object does not touch the content, * it just suplies the pipe to swallow the data. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:45 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class HttpClientConnection { /** * Default port where HTTP servers listen for incomming requests. This is * just a convenience definition to make the code more readable. */ public final static int HTTP_DEFAULTPORT = 80; /** * Constructs a new HttpClientConnection. The port used on * the HTTP server side is the default HTTP port, 80. * * @param hostname name (DNS name or IP dotted address) of host running * a HTTP server to which we want to connect to. */ public HttpClientConnection(String hostname) { this(hostname, HTTP_DEFAULTPORT); } /** * Constructs a new HttpClientConnection. * * @param hostname name (DNS name or IP dotted address) of host running * a HTTP server to which we should connect to. * @param port Port number where the HTTP server can be contacted. */ public HttpClientConnection(String hostname, int port) { this.hostname = hostname; this.port = port; // // The connection is closed, that is, dead. // mode = HTTP_DEAD; } /** * Closes the connection to the HTTP server and frees up some resources. * After calling close it is still possible to open a new * connection to the HTTP server once again. */ public void close() { if ( socket != null ) { // // Close the input and output streams, then close the // socket. Catch all exceptions when closing each object // individually, so we can clean up all three despite // them throwing nasty exceptions at us... // try { in.close(); } catch ( IOException e ) { } try { out.close(); } catch ( IOException e ) { } try { socket.close(); } catch ( IOException e ) { } socket = null; out = null; in = null; } mode = HTTP_DEAD; } /** * Starts a new HTTP "POST" request and sends all necessary HTTP header * fields. Next, the caller can send lots of content using the * {@link #writeContentBytes} method. Finally, to finish the request * he has to call the {@link #endPostRequest} method. * * @param path Path to server object which handles the POST request. * For instance, this can be a CGI script (although it better should * not be one, except in the case of FAST CGI). * @param mimeType MIME-classified type of content to be sent. * @param contentLength Length of content to be sent. If negative, the * length is not known in advance. In this case, keeping the connection * alive is not possible, so callers should avoid this situation, * if possible. * * @exception IOException if an I/O exception occurs when sending the * HTTP headers. In this case the connection is closed automatically * and the caller must not send any content. However, the caller * is free to give the request another try by calling * beginEncoding again, thus opening a new HTTP connection. */ public void beginPostRequest(String path, String mimeType, int contentLength) throws IOException { // // Make sure that the connection is open. This will also handle the // case that the HTTP server or proxy can not keep connections alive, // either because it can not per se or the client does not know the // requests's content length in advance (bad, bad, very bad!). // connect(); // // Remember how many content bytes we need to see before finishing // the request and then enter "sending" mode. // remainingContentLength = contentLength; mode = HTTP_SENDING; // // Set the socket timeout, so we don't hang around forever waiting // for an answer or to get rid of our content. // socket.setSoTimeout(timeout); // // Send method header and all the other useful headers. // if ( useProxy ) { writeln("POST http://" + hostname + path + " HTTP/1.1"); } else { writeln("POST " + path + " HTTP/1.1"); } // // Now send all the interesting headers... // This first involves indicating the host we intended to contact // while going through an HTTP proxy. Also send some interesting // agent information about us... // if ( !useProxy ) { writeln("Host: " + hostname); } writeln("User-Agent: " + userAgentId); // // Try to keep the connection alive. // if ( useProxy ) { writeln("Proxy-Connection: keep-alive"); } else { writeln("Connection: keep-alive"); } // // Ensure that proxies do not cache the POST request. On the other // side of the wire, the HTTP server -- respective the redirecting // CGI -- is responsible for returning appropriate cache control // headers. // writeln("Cache-Control: no-cache, no-store, private"); writeln("Pragma: no-cache"); // // Finish headers with a description of the content that will follow // within this POST request. If the exact content-length is not known // in advance we have to fall back to the old close-the-line principle. // // Note: this is currently not possible because Java does not allow // us to close only one side of the socket connection. Half-closes // have only been introduced lately with the JDK1.3 -- sloooooowly, // Sun is learning what is needed for an "Internet Platform". As if // that wasn't clear from the beginning... did no-one read the // BSD socket API for a start?! And what about Mr. Tanenbaum?! // writeln("Content-Type: " + mimeType); if ( contentLength > 0 ) { writeln("Content-Length: " + contentLength); } else { throw(new ProtocolException( "ONC/RPC HTTP-tunnel POST needs content length to keep the connection alive")); } // // Finish the header section of the HTTP request. This is marked // according to the HTTP specification by an empty line. The next // thing following is content... // writeln(""); // // Let the real content roll -- or were that the "good times?" // } /** * Send (part) of the content to the HTTP server. Note that the output * is done unbuffered, so callers should write their content in large * chunks to avoid the calling overhead for sending data. * * @param bytes The data. * @param offset Start offset in the data. * @param length Number of bytes to write. * * @exception RuntimeException if too much content was sent. * @exception IOException if an I/O error occurs. * @exception NullPointerException if bytes is * null. * @exception IndexOutOfBoundsException if offset is negative, * or length is negative, or offset + length is * greater than the length of the array bytes. */ public void writeContentBytes(byte [] bytes, int offset, int length) throws IOException { if ( mode != HTTP_SENDING ) { throw(new ProtocolException( "ONC/RPC HTTP tunnel not in sending mode")); } // // Check incomming parameters... // if ( bytes == null) { throw(new NullPointerException()); } else if ( (offset < 0) || (offset > bytes.length) || (length < 0) || ((offset + length) > bytes.length) || ((offset + length) < 0) ) { throw(new IndexOutOfBoundsException()); } else if ( length == 0 ) { return; } // // First check that not too much amount of content gets sent. // (Looks like this should be a code template for marketing!) // if ( remainingContentLength >= 0 ) { remainingContentLength -= length; if ( remainingContentLength < 0 ) { close(); throw(new ProtocolException( "ONC/RPC HTTP tunnel received too much content")); } } // // Whow! Finally write some bytes... In case we get an I/O error, // we terminate the connection and rethrow the I/O exception. // try { out.write(bytes, offset, length); } catch ( IOException e ) { close(); throw(e); } } /** * Ends the HTTP "POST" request. The next logical step for a caller is * then to call ... #FIXME */ public void endPostRequest() throws IOException { if ( remainingContentLength > 0 ) { // // As not all content has been sent, abort the connection the // hard way and throw an exception to notify the caller. // close(); throw(new ProtocolException( "ONC/RPC HTTP tunnel received not enough content")); } try { out.flush(); } catch ( IOException e ) { // // If flushing the connection results in an I/O exception, tear // down the connection before rethrowing the exception. This allows // the caller to reconnect and retry the POST. // close(); throw(e); } mode = HTTP_IDLE; } /** * Handle options sent by the HTTP server. * *

Currently the following options are handled by this class: *

    *
  • Content-Length -- length of content following the header section
  • *
  • Content-Type -- type of content sent
  • *
  • Proxy-Connection -- handle keep-alive request
  • *
  • Connection -- handle keep-alive request
  • *
  • Transfer-Encoding -- transfer encoding choosen by HTTP server
  • *
* * @param option Name of option sent by HTTP server. * @param value Value of option. */ protected void handleOption(String option, String value) { // FIXME System.out.println("OPTION: \"" + option + "\" = \"" + value + "\""); if ( "Content-Length".equalsIgnoreCase(option) ) { try { remainingContentLength = Integer.parseInt(value); } catch ( NumberFormatException e ) { } } else if ( "Content-Type".equalsIgnoreCase(option) ) { contentType = value; } else if ( "Proxy-Connection".equalsIgnoreCase(option) ) { if ( useProxy ) { keepAlive = "Keep-Alive".equalsIgnoreCase(value); } } else if ( "Connection".equalsIgnoreCase(option) ) { if ( !useProxy ) { keepAlive = "Keep-Alive".equalsIgnoreCase(value); } } else if ( "Transfer-Encoding".equalsIgnoreCase(option) ) { chunkedTransfer = "chunked".equalsIgnoreCase(value); } } /** * Read the HTTP headers sent by the servers and also parse them at the * same time. * * @return HTTP status code. */ private int readHeaders() throws IOException { // // Reset/init section. // keepAlive = false; remainingContentLength = 0; chunkedTransfer = false; remainingChunkLength = 0; contentType = null; // // Read response line, but handle the dreaded HTTP/1.1 100 Continue // server response. // String [] param; int httpStatus; for ( ;; ) { // // First, read in the response line, which contains the HTTP version // spoken by the server, the status code, and a reason phrase. // param = new String[1]; if ( !readHeaderLine(param) || !param[0].startsWith("HTTP/") ) { throw(new IOException("Invalid HTTP header")); } String header = param[0]; // // Retrieve the status code from the HTTP header line. This involves // finding the end of the HTTP/x.x string and skipping all spaces // until we reach the HTTP status code in the form of XYZ. // Yes, we are not interested in the HTTP protocol spoken by the server. // int index = 0; int len = header.length(); for ( ; (index < len) && (header.charAt(index) != ' ') ; ++index ) { // empty } for ( ; (index < len) && (header.charAt(index) == ' ') ; ++index ) { // empty } try { responseCode = 300; // #FIXME? httpStatus = Integer.parseInt(header.substring(index, index + 3)); responseCode = httpStatus; } catch ( NumberFormatException e ) { throw(new IOException("Invalid HTTP header")); } // // If it's not a "100 Continue", then we can proceed reading // header lines. Otherwise we expect to see another HTTP response // line. // if ( responseCode != 100 ) { break; } } // // Now parse the following options within the HTTP header. Every // non-empty line contains an HTTP option, which is handed over to // the handleOption method for implementation-specific behaviour. // param = new String[2]; for ( ;; ) { if ( readHeaderLine(param) ) { handleOption(param[0], param[1]); } else { // // End of HTTP header section reached, so leave the loop. // break; } } // // Some final sanity checks: if the server does not know how long // the content it sends is going to be, it sends a negative length. // In this case we can not keep the connection alive (and in fact // the server should not have been responded with such a header, but // we gracefully ignore this here). // if ( remainingContentLength <= 0 ) { keepAlive = false; remainingContentLength = -1; // means "don't know" } // // Done. Return the status of the HTTP request returned in this reply. // return httpStatus; } /** * Read in a header line coming over the HTTP connection from the server. * * @param keyvalue An array with room for either exactly one or two * strings, receiving the header option and optionally its value. If * only room for a single return string is supplied, then * readHeaderLine will only read in the header line (like * the first HTTP header) without separating the options's value from * its name. If a header option has no option, then null * is returned as the value string. * * @return false if the end of the headers has been reached. */ private boolean readHeaderLine(String [] keyvalue) throws IOException { int headerSize = headerLine.length; int index = 0; boolean option = keyvalue.length > 1; // // Now parse the next header line. // int ch; int nextch; int colon = -1; ReadLine: while ( (ch = in.read()) >= 0 ) { switch ( ch ) { // // For header options in form of key: value remember the position. // Note that the use the invariant that the index can not be // negative. So if the colon position is not negative, it has // already been set and we must not set it again, as, for instance, // the value of the option might also contains colons. // case ':': if ( colon < 0 ) { colon = index; } break; // // Replace HT with SP // case '\t': ch = ' '; break; // // Swallow CRLF. As we speak HTTP/1.1 (or at least we could), we // need to support header lines folded onto multiple lines. // case '\r': case '\n': // // Check for a continuation line, which is indicated by a // new line beginning with either a space or a horizontal tab. // in.mark(1); nextch = in.read(); if ( (ch == '\r') && (nextch == '\n') ) { // // Okay. This *is* a CRLF. Now let's look for a continuation // indication... // in.mark(1); nextch = in.read(); if ( (nextch != ' ') && (nextch != '\t') ) { // // Nope. This is the final line of a header line. So we need // to back up so the char can be read on the next round. // in.reset(); break ReadLine; } } else { in.reset(); } // // This is either crap or a continuation line, so we replace // the crap or the CRLF and the following SP or HT (in case of // a continuation line) with a single SP. // ch = ' '; break; } // // Add character to header line buffer, growing the buffer as // needed. // if ( index >= headerSize ) { char [] newHeaderLine = new char[headerSize * 2]; System.arraycopy(headerLine, 0, newHeaderLine, 0, headerSize); headerLine = newHeaderLine; headerSize *= 2; } headerLine[index++] = (char) ch; } // // End of headers reached (an empty line)? // if ( index == 0 ) { return false; } // // We are done. Return the header string, constructed from the buffer. // In case we're dealing with options which have values and parsing // is not disabled, we first separate the option and its value and // then return as two separate strings. // while ( (--index > 0) && (headerLine[index] <= ' ') ) { // empty } ++index; if ( option ) { if ( colon <= 0 ) { // // Only "option", but not "option: value" // keyvalue[0] = new String(headerLine, 0, index); keyvalue[1] = null; } else { keyvalue[0] = new String(headerLine, 0, colon); while ( (++colon < index) && (headerLine[colon] <= ' ') ) { // empty } keyvalue[1] = new String(headerLine, colon, index - colon); } } else { keyvalue[0] = new String(headerLine, 0, index); } return true; } /** * Read exactly one line, termined by CRLF or either CR or LF, and return * it. * * @return Line without the terminating CR, LF or CRLF. */ private String readLine() throws IOException { int headerSize = headerLine.length; int index = 0; // // Now parse the next header line. // int ch; int nextch; ReadLine: while ( (ch = in.read()) >= 0 ) { switch ( ch ) { // // Swallow CRLF. // case '\r': case '\n': in.mark(1); nextch = in.read(); if ( (ch == '\r') && (nextch == '\n') ) { // // Okay. This *is* a CRLF. // break ReadLine; } else { in.reset(); } // // This is either crap or a continuation line, so we replace // the crap or the CRLF and the following SP or HT (in case of // a continuation line) with a single SP. // ch = ' '; break; } // // Add character to header line buffer, growing the buffer as // needed. // if ( index >= headerSize ) { char [] newHeaderLine = new char[headerSize * 2]; System.arraycopy(headerLine, 0, newHeaderLine, 0, headerSize); headerLine = newHeaderLine; headerSize *= 2; } headerLine[index++] = (char) ch; } // // End of headers reached? // return new String(headerLine, 0, index); } /** * Begin receiving the content sent by the HTTP server. This * method blocks until at least the HTTP header section has been received * or until the connection times out. * * @return HTTP server response code (status code). */ public int beginDecoding() throws IOException { mode = HTTP_RECEIVING; finalChunkSeen = false; // // Now read the HTTP headers sent by the server. If the response code // is not okay, we end decoding immediately. This will either result // in the connection getting closed of the content skipped, if the // connection can be kept alive. // readHeaders(); switch ( responseCode ) { case 200: // // Accepted request... // break; default: // // All other response codes: not accepted! // endDecoding(); } return responseCode; } /** * Returns the content type (MIME type, charset, etc.). * * @return content type */ public String getContentType() { return contentType; } /** * Read content sent by the HTTP server. This method also handles the * HTTP/1.1 chunked transfer encoding if the HTTP server insisted on using * it. If only chunked transfer encoding has been introduced with the * first official 0.9 protocol version of HTTP, it would have made sending * ONC/RPC requests much easier, because we would not need to buffer the * while request before sending it just to know its exact length. * Unfortunately, chunking has only been introduced lately so we can not * expect servers and especially proxies to handle it. Sigh. * * @param buffer Buffer to receive the content sent by the HTTP server. * @param offset Start offset in the buffer. * @param length Number of bytes to receive. * * @exception ProtocolException if not enough content was available (the * caller attempted to read more data than available) or if we received * junk information violating the HTTP protocol specification. * @exception IOException if an I/O error occurs. * @exception NullPointerException if bytes is * null. * @exception IndexOutOfBoundsException if offset is negative, * or length is negative, or offset + length is * greater than the length of the array bytes. */ public int readContentBytes(byte [] buffer, int offset, int length) throws IOException { int bytesread; int total = 0; if ( mode != HTTP_RECEIVING ) { throw(new ProtocolException( "ONC/RPC HTTP tunnel not in receiving mode")); } // // Check incomming parameters... // if ( buffer == null ) { throw(new NullPointerException()); } else if ( (offset < 0) || (offset > buffer.length) || (length < 0) || ((offset + length) > buffer.length) || ((offset + length) < 0) ) { throw(new IndexOutOfBoundsException()); } else if ( length == 0 ) { return 0; } // // First check that there is still enough content to read. In case // the HTTP server did not indicate the content length, we return // as much as possible until we hit the "end of file". Note that // in case of chuncked transfers, we don't know the content length // in advance too, so we read 'til we drop. // // In contrast to Java's read() from the io package, we block until // we either got the specified amout of content or until we reach // eof. // if ( remainingContentLength >= 0 ) { // // Do not decrement remainingContentLength here to avoid getting // out of sync in case of exceptions... // if ( remainingContentLength < length ) { close(); throw(new ProtocolException( "ONC/RPC HTTP tunnel has not enough content available")); } } // // Whow! Finally read some bytes... In case we get an I/O error, // we terminate the connection and rethrow the I/O exception. // But beginning with HTTP/1.1 reading some bytes can actually be not // that easy as expected from earlier protocol versions, as we now // probably have to deal with transfer encodings. Currently, we only // support chunked transfers. // if ( chunkedTransfer ) { int toRead; // // Beginning with HTTP/1.1 we need to handle chunked transfers, // where the sender splits the content into chunks without telling // the receiver the overall total length, but only how long an // individual chunk is going to be. Advantage: the sender does not // need to buffer the content in order to find out the total length, // but can instead use a fixed-sized buffer and split the content // into appropriate-sized chunks. // try { for ( ;; ) { // // If the previous chunk has been completely read, we now // need to read in the length of the following chunk. If // we're currently in the middle of a chunk, we can skip // this step and immediately proceed to slurp chunk content. // if ( remainingChunkLength <= 0 ) { if ( finalChunkSeen ) { throw(new ProtocolException( "ONC/RPC HTTP tunnel has not enough content available")); } // // Next chunk or first chunk: // the length of the following chunk is encoded as // an hex integer followed by a line break. If we read // a zero length chunk, we've reached the end of the // road. This is only acceptable if no more data needs // to be read. // String hexLen = readLine(); // // This is ridiculous: parseInt does not like white // space, and Apache sends them after the chunk length // and before the line termination CRLF. So we need // to trim the string. // try { remainingChunkLength = Integer.parseInt(hexLen.trim(), 16); if ( remainingChunkLength < 0 ) { throw(new NumberFormatException("must not be negative")); } } catch ( NumberFormatException e ) { throw(new ProtocolException( "HTTP chunking transfer protocol violation: invalid chunk length \"" + hexLen + "\"")); } if ( remainingChunkLength == 0 ) { finalChunkSeen = true; //if ( length > 0 ) { // // If we got here, we reached the last chunk but // the caller wanted even more data. // // throw(new ProtocolException( // "ONC/RPC HTTP tunnel has not enough content available")); //} return total; } } // // Now read in as many data as the caller wants or as many // as the current chunk contains, whichever is less. Note // that the read method will only return *up to* the amount // of data specified, so it can perfectly return with less // data than expected if the I/O layer, and especially the // TCP stack decides to do so although there's still data // "in the pipe". To cope with this situation, we turn one // round after another as long as there is still data for // the current chunk outstanding. // while ( remainingChunkLength > 0 ) { toRead = length <= remainingChunkLength ? length : remainingChunkLength; bytesread = in.read(buffer, offset, toRead); if ( bytesread < 0 ) { throw(new ProtocolException( "ONC/RPC HTTP tunnel has not enough content available")); } offset += bytesread; total += bytesread; length -= bytesread; remainingChunkLength -= bytesread; if ( length <= 0 ) { // // In case we also reached the end of the current // chunk, swallow the CRLF terminating the chunk. // Otherwise we would get into trouble when the // next read expects to see a chunk length // indication. // if ( remainingChunkLength <= 0 ) { readLine(); } return total; } } // // Swallow trailing CRLF terminating each chunk of data, // then start over with the next chunk, because there is // still data to be read. // readLine(); } } catch ( IOException e ) { close(); throw(e); } } // // Handle protocol versions HTTP/0.9, HTTP/1.0, or non-chunked // transfers with HTTP/1.1. This is the simple case, where we only // slurp in bytes, bytes, bytes... // try { while ( length > 0 ) { bytesread = in.read(buffer, offset, length); if ( bytesread < 0 ) { // // In case we reach eof, the read() method will first // return all data up to eof, and then, on the next call, // -1 to indicate eof. We only can reach eof when the // server closed its sending side of the connection. When // we see an eof, we make sure that the caller did not // expected to get more data when we got. // if ( remainingContentLength >= 0 ) { throw(new ProtocolException( "ONC/RPC HTTP tunnel has not enough content available")); } break; } total += bytesread; offset += bytesread; length -= bytesread; } } catch ( IOException e ) { // // In case of I/O problems, and especially communication timeouts, // close the connection and rethrow the exception to notify the // caller. // close(); throw(e); } finally { // // Don't forget to update the counter bean heads... // if ( remainingContentLength >= 0 ) { remainingContentLength -= total; } } // // Phew! Done with the easy case, now return the amount of data // received from the HTTP server in this turn. // return total; } /** * Returns amount of content still available (to be read). This always * shows the remaining amount and is updated whenever content is read * using {@link #readContentBytes}. * * @return Amount of content available. */ public int getRemainingContentLength() { return remainingContentLength; } /** * *

This method silently discards any unread content, if the caller has * yet not read all content. */ public void endDecoding() throws IOException { // // Make sure that we slurp all data yet unread to keep keep-alive // connections alive (I love the English tongue... but maybe this is // just the result of my German tongue and syntax going crazy, so // Mark Twain was right. No, Mark Twain did not invent the scanner API!) // if ( chunkedTransfer ) { if ( keepAlive && !finalChunkSeen ) { // // Only makes sense if the connection can be kept alive, otherwise // we don't want to bother ourselves slurping junk data... // int chunkLength; long bytesSkipped; try { // // First, get rid of the current chunk, if there is any. // while ( remainingChunkLength > 0 ) { bytesSkipped = in.skip(remainingChunkLength); if ( bytesSkipped < 0 ) { throw(new IOException("Could not skip chunk")); } remainingChunkLength -= bytesSkipped; } // // Then dispose any other chunks... // String hexLen; while ( !finalChunkSeen ) { // // Read next chunk header, then flush chunk data, including // the CRLF terminating each chunk. // hexLen = readLine(); chunkLength = Integer.parseInt(hexLen, 16); if ( chunkLength < 0 ) { throw(new NumberFormatException("must not be negative")); } if ( chunkLength == 0 ) { break; } while ( chunkLength > 0 ) { bytesSkipped = in.skip(remainingChunkLength); if ( bytesSkipped < 0 ) { throw(new IOException("Could not skip chunk")); } chunkLength -= bytesSkipped; } readLine(); } } catch ( Exception e ) { // // Got in any trouble? Then kill the connection. // close(); } } } else if ( keepAlive ) { // // Skip remaining unread content, if the content length is known // in advance. Otherwise drop the connection. // if ( remainingContentLength > 0 ) { long bytesSkipped; while ( remainingContentLength > 0 ) { bytesSkipped = in.skip(remainingContentLength); if ( bytesSkipped < 0 ) { close(); break; } remainingContentLength -= bytesSkipped; } } else if ( remainingContentLength < 0 ) { close(); } } // // Indicate new mode, if the connection is still alive, or close it // if it can not kept alive. // if ( mode != HTTP_DEAD ) { if ( !keepAlive ) { close(); } else { mode = HTTP_IDLE; } } } /** * Set the timout for sending or receiving information to/from the HTTP * server. * * @param milliseconds Timeout in milliseconds. */ public void setTimeout(int milliseconds) { if ( milliseconds <= 0 ) { throw(new IllegalArgumentException("timeouts must be positive.")); } timeout = milliseconds; } /** * Retrieve the current timeout set for remote procedure calls. A timeout * of zero indicates batching calls (no reply message is expected). * * @return Current timeout. */ public int getTimeout() { return timeout; } /** * */ public int getResponseCode() { return responseCode; } /** * */ public boolean getKeepAlive() { return keepAlive; } /** * Connects to the HTTP server. In case an HTTP proxy has been configured, * this connects to the proxy instead. * *

If the connection is in keep-alive mode and already open, then the * connection is reused. * * @exception SecurityException if a security manager exists and its * checkConnect method does not allow the connect * operation. */ private void connect() throws IOException { // // Only connect, if we don't already have a socket at hand. Otherwise // we reuse the old connection, if that is okay. // if ( socket != null ) { if ( keepAlive ) { return; } close(); } // // Check that we are allowed to connect to the HTTP server. Note that // this is the barrier which keeps callers from connecting to anywhere // through a proxy server -- note that connection to the proxy is // always done as a privileged operation, so we must be cautious here. // SecurityManager security = System.getSecurityManager(); if ( security != null ) { security.checkConnect(hostname, port); } // // If we had already successfully contacted the proxy HTTP server // during the last request, we contact it once again. This way, we // don't need to go through all the system's property hasle, etc. // if ( cachedProxyHost != null ) { socket = new Socket(cachedProxyHost, cachedProxyPort); useProxy = true; } else { // // FIXME: support for non-proxied servers... // // // Check for proxy server. If one has configured, this is the // one to connect to. The proxy then will connect to the real // http server. // final String proxyHost = getProxyHost(); if ( proxyHost != null ) { final int proxyPort = getProxyPort(); try { AccessController.doPrivileged(new PrivilegedExceptionAction() { public Object run() throws IOException { socket = new Socket(proxyHost, proxyPort); useProxy = true; cachedProxyHost = proxyHost; cachedProxyPort = proxyPort; return null; // return value is not used by caller } } ); } catch ( PrivilegedActionException e ) { // // Okay, now we can really try to connect to the HTTP server. // useProxy = false; socket = new Socket(InetAddress.getByName(hostname), port); } } else { // // Okay, now we can really try to connect to the HTTP server. // useProxy = false; socket = new Socket(InetAddress.getByName(hostname), port); } } // // It might help to disable Nagle, so that packets are not delayed // after we've handed it over to the network stack before going to // the wire. // socket.setTcpNoDelay(true); // // Get all the streams we like to work with. We do buffer both the // input and output streams to make the whole thing perform better. // out = new BufferedOutputStream(socket.getOutputStream(), 4096); in = new BufferedInputStream(socket.getInputStream(), 4096); // // FIXME?? keepAlive = true; } /** * Writes an ASCII string to the HTTP server (this is buffered first). * * @param s String to write. */ private void write(String s) throws IOException { int slen = s.length(); int sindex = 0; int index; int blocklen = asciiBuffer.length; int len; while ( slen > 0 ) { len = slen > blocklen ? blocklen : slen; for ( index = 0; index < len; ++index ) { asciiBuffer[index] = (byte) s.charAt(sindex++); } slen -= len; out.write(asciiBuffer, 0, len); } } /** * Writes an ASCII string and appends a line termination in the form of * CR followed by LF. * * @param s String to write. */ private void writeln(String s) throws IOException { write(s); out.write(CRLF); } /** * Retrieves the host name where the HTTP proxy server resided from the * system properties. * * @return Name of proxy host or null if no proxy has been * configured. */ private String getProxyHost() { String proxyHost = (String) AccessController.doPrivileged( new GetPropertyPrivilegedAction("http.proxyHost")); if ( proxyHost == null ) { proxyHost = (String) AccessController.doPrivileged( new GetPropertyPrivilegedAction("proxyHost")); } return proxyHost; } /** * Retrieves the port number where the HTTP proxy server resides from * the system properties. If no port number has been configured for the * HTTP proxy, then the default http port number of 80 is returned. * * @return Port number of HTTP proxy server. */ private int getProxyPort() { String proxyPort = (String) AccessController.doPrivileged( new GetPropertyPrivilegedAction("http.proxyPort")); if ( proxyPort == null ) { proxyPort = (String) AccessController.doPrivileged( new GetPropertyPrivilegedAction("proxyPort")); } if ( proxyPort != null ) { // // If something has been specified as the proxy port system // property, try to convert this into a port number. If this // fails, return the default port number of an HTTP server. // try { return Integer.parseInt(proxyPort); } catch ( NumberFormatException e ) { } } return HTTP_DEFAULTPORT; } /** * Host name of HTTP server to contact in the form of * www.acplt.org. */ private String hostname; /** * Port number where to contact the HTTP server. This defaults to the * standard port where HTTP servers are expected: port 80. */ private int port = HTTP_DEFAULTPORT; /** * TCP/IP socket for communication with the HTTP server. */ private Socket socket; /** * Timeout (in milliseconds) for communication with an HTTP server. */ private int timeout = 30000; /** * */ private boolean keepAlive = true; /** * Indicates whether the HTTP server send its reply using the chunked * transfer encoding. */ private boolean chunkedTransfer; /** * Contains the amount of data still to be read for the current chunk. */ private int remainingChunkLength; /** * Indicates whether the end-of-chunks chunk has been read (whow, another * one for the Purlitzer price). */ private boolean finalChunkSeen; /** * Type of content sent by HTTP server. */ private String contentType; /** * Buffered output stream used for sending the HTTP headers. This stream * is not used to send content in an HTTP request. */ private OutputStream out; /** * */ private InputStream in; /** * Contains the HTTP response code from the last request sent to the * HTTP server. */ private int responseCode; /** * Buffer receiving ASCII characters from Unicode strings when sending * (header) strings to the HTTP server. */ private byte [] asciiBuffer = new byte[1024]; /** * Dynamically growing buffer used during header parsing. */ private char [] headerLine = new char[80]; /** * */ private String userAgentId = "Not Mozilla, but RemoteTea v" + OncRpcConstants.REMOTETEA_VERSION_STRING; /** * */ private final static int HTTP_DEAD = 0; private final static int HTTP_IDLE = 1; private final static int HTTP_SENDING = 2; private final static int HTTP_RECEIVING = 3; /** * Indicates sending/receiving mode of the HTTP connection. */ private int mode = HTTP_IDLE; /** * Indicates the amount of content data which still has to be sent or * received. */ private int remainingContentLength; /** * */ public final static byte [] CRLF = { 13, 10 }; /** * Indicates whether a proxy HTTP server needs to be contacted in order * to reach the real HTTP server. */ private boolean useProxy = false; /** * Address of proxy host to contact instead of real HTTP server. */ private String cachedProxyHost; /** * Port number of proxy HTTP server. */ private int cachedProxyPort; /** * */ class GetPropertyPrivilegedAction implements PrivilegedAction { /** * */ public GetPropertyPrivilegedAction(String property) { this.property = property; } /** * */ public GetPropertyPrivilegedAction(String property, String defaultValue) { this.property = property; this.defaultValue = defaultValue; } /** * */ public Object run() { return System.getProperty(property, defaultValue); } /** * The property to retrieve. */ private String property; /** * Default value or null. */ private String defaultValue; } } // End of HttpClientConnection.java remotetea-1.0.7/src/org/acplt/oncrpc/web/HttpTunnelConstants.java0000644005374700003410000000507407716406402026223 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/web/HttpTunnelConstants.java,v 1.1.1.1 2003/08/13 12:03:45 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc.web; /** * A collection of constants generally useful when working with HTTP * tunnels for the ONC/RPC protocol. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:45 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public interface HttpTunnelConstants { /** * Amount of octets (binary data) which can be encoded in a single * plain ASCII line. This amount must always be a multiple of * three. This is demanded by the base64 encoding scheme, which * encodes every three octets using four plain ASCII characters. */ public final static int BYTES_PER_LINE = 48; /** * Amount of plain ASCII characters per line for representing the encoded * octets. This amount is derived from the BYTES_PER_LINE * setting. */ public final static int ENCODED_BYTES_PER_LINE = (BYTES_PER_LINE / 3) * 4; /** * Amount of plain ASCII characters per line for representing the encoded * octets. This amount is derived from the BYTES_PER_LINE * setting and also accounts for the line termination (CRLF). */ public final static int ENCODED_BYTES_PER_LINE_CRLF = ENCODED_BYTES_PER_LINE + 2; /** * Amount of lines that should be processed at once using a buffer. */ public final static int LINES_PER_BLOCK = 100; /** * Protocol identifier of ONC/RPC HTTP tunnel. */ public final static String TUNNEL_PROTO_ID = "TEA/1.0"; } // End of HttpTunnelConstants.java remotetea-1.0.7/src/org/acplt/oncrpc/OncRpcAcceptStatus.java0000644005374700003410000000507407716406374025164 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/OncRpcAcceptStatus.java,v 1.1.1.1 2003/08/13 12:03:39 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; /** * A collection of constants used to identify the acceptance status of * ONC/RPC reply messages. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:39 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public interface OncRpcAcceptStatus { /** * The remote procedure was called and executed successfully. */ public static final int ONCRPC_SUCCESS = 0; /** * The program requested is not available. So the remote host * does not export this particular program and the ONC/RPC server * which you tried to send a RPC call message doesn't know of this * program either. */ public static final int ONCRPC_PROG_UNAVAIL = 1; /** * A program version number mismatch occured. The remote ONC/RPC * server does not support this particular version of the program. */ public static final int ONCRPC_PROG_MISMATCH = 2; /** * The procedure requested is not available. The remote ONC/RPC server * does not support this particular procedure. */ public static final int ONCRPC_PROC_UNAVAIL = 3; /** * The server could not decode the arguments sent within the ONC/RPC * call message. */ public static final int ONCRPC_GARBAGE_ARGS = 4; /** * The server encountered a system error and thus was not able to * process the procedure call. Causes might be memory shortage, * desinterest and sloth. */ public static final int ONCRPC_SYSTEM_ERR = 5; } // End of OncRpcAcceptStatus.java remotetea-1.0.7/src/org/acplt/oncrpc/OncRpcAuthConstants.java0000644005374700003410000000331307716406374025351 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/OncRpcAuthConstants.java,v 1.1.1.1 2003/08/13 12:03:40 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; /** * A collection of constants related to authentication and generally usefull * for ONC/RPC. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:40 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public interface OncRpcAuthConstants { /** * Maximum length of opaque authentication information. */ public static final int ONCRPC_MAX_AUTH_BYTES = 400; /** * Maximum length of machine name. */ public static final int ONCRPC_MAX_MACHINE_NAME = 255; /** * Maximum allowed number of groups. */ public static final int ONCRPC_MAX_GROUPS = 16; } // End of OncRpcAuthConstants.java remotetea-1.0.7/src/org/acplt/oncrpc/OncRpcAuthStatus.java0000644005374700003410000000516307716406374024665 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/OncRpcAuthStatus.java,v 1.1.1.1 2003/08/13 12:03:40 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; /** * A collection of constants used to identify the authentication status * (or any authentication errors) in ONC/RPC replies of the corresponding * ONC/RPC calls. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:40 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public interface OncRpcAuthStatus { /** * There is no authentication problem or error. */ public static final int ONCRPC_AUTH_OK = 0; /** * The ONC/RPC server detected a bad credential (that is, the seal was * broken). */ public static final int ONCRPC_AUTH_BADCRED = 1; /** * The ONC/RPC server has rejected the credential and forces the caller * to begin a new session. */ public static final int ONCRPC_AUTH_REJECTEDCRED = 2; /** * The ONC/RPC server detected a bad verifier (that is, the seal was * broken). */ public static final int ONCRPC_AUTH_BADVERF = 3; /** * The ONC/RPC server detected an expired verifier (which can also happen * if the verifier was replayed). */ public static final int ONCRPC_AUTH_REJECTEDVERF = 4; /** * The ONC/RPC server rejected the authentication for security reasons. */ public static final int ONCRPC_AUTH_TOOWEAK = 5; /** * The ONC/RPC client detected a bogus response verifier. */ public static final int ONCRPC_AUTH_INVALIDRESP = 6; /** * Authentication at the ONC/RPC client failed for an unknown reason. */ public static final int ONCRPC_AUTH_FAILED = 7; } // End of OncRpcAuthStatus.javaremotetea-1.0.7/src/org/acplt/oncrpc/OncRpcAuthType.java0000644005374700003410000000432707716406374024324 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/OncRpcAuthType.java,v 1.1.1.1 2003/08/13 12:03:40 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; /** * A collection of constants used to identify the authentication schemes * available for ONC/RPC. Please note that currently only * ONCRPC_AUTH_NONE is supported by this Java package. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:40 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public interface OncRpcAuthType { /** * No authentication scheme used for this remote procedure call. */ public static final int ONCRPC_AUTH_NONE = 0; /** * The so-called "Unix" authentication scheme is not supported. This one * only sends the users id as well as her/his group identifiers, so this * is simply far too weak to use in typical situations where * authentication is requested. */ public static final int ONCRPC_AUTH_UNIX = 1; /** * The so-called "short hand Unix style" is not supported. */ public static final int ONCRPC_AUTH_SHORT = 2; /** * The DES authentication scheme (using encrypted time stamps) is not * supported -- and besides, it's not a silver bullet either. */ public static final int ONCRPC_AUTH_DES = 3; } // End of OncRpcAuthType.java remotetea-1.0.7/src/org/acplt/oncrpc/OncRpcAuthenticationException.java0000644005374700003410000000475710335174250027410 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/OncRpcAuthenticationException.java,v 1.2 2005/11/11 21:01:44 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; /** * The class OncRpcAuthenticationException indicates an * authentication exception. * * @version $Revision: 1.2 $ $Date: 2005/11/11 21:01:44 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class OncRpcAuthenticationException extends OncRpcException { /** * Defines the serial version UID for OncRpcAuthenticationException. */ private static final long serialVersionUID = 7747394107888423440L; /** * Initializes an OncRpcAuthenticationException * with a detail of {@link OncRpcException#RPC_AUTHERROR} and * the specified {@link OncRpcAuthStatus authentication status} detail. * * @param authStatus The authentication status, which can be any one of * the {@link OncRpcAuthStatus OncRpcAuthStatus constants}. */ public OncRpcAuthenticationException(int authStatus) { super(RPC_AUTHERROR); authStatusDetail = authStatus; } /** * Returns the authentication status detail of this ONC/RPC exception * object. * * @return The authentication status of this OncRpcException. */ public int getAuthStatus() { return authStatusDetail; } /** * Specific authentication status detail (reason why this authentication * exception was thrown). * * @serial */ private int authStatusDetail; } // End of OncRpcAuthenticationException.java remotetea-1.0.7/src/org/acplt/oncrpc/OncRpcBroadcastAdapter.java0000644005374700003410000000355507716406374025766 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/OncRpcBroadcastAdapter.java,v 1.1.1.1 2003/08/13 12:03:40 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; /** * An abstract adapter class for * {@link OncRpcBroadcastListener receiving} * {@link OncRpcBroadcastEvent ONC/RPC broadcast reply events}. * The methods in this class are empty. This class exists as * convenience for creating listener objects. * * @see OncRpcUdpClient * @see OncRpcBroadcastAdapter * @see OncRpcBroadcastListener * @see OncRpcBroadcastEvent * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:40 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public abstract class OncRpcBroadcastAdapter implements OncRpcBroadcastListener { /** * Invoked when a reply to an ONC/RPC broadcast call is received. * * @see OncRpcBroadcastEvent */ public void replyReceived(OncRpcBroadcastEvent evt) { } } // End of OncRpcBroadcastAdapter.javaremotetea-1.0.7/src/org/acplt/oncrpc/OncRpcBroadcastEvent.java0000644005374700003410000000772610335176310025454 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/OncRpcBroadcastEvent.java,v 1.3 2005/11/11 21:19:20 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; import java.util.EventObject; import java.net.InetAddress; /** * The class OncRpcBroadcastEvent defines an event fired by * {@link OncRpcUdpClient ONC/RPC UDP/IP-based clients} whenever replies * to a * {@link OncRpcUdpClient#broadcastCall(int, XdrAble, XdrAble, OncRpcBroadcastListener) broadcast call} * are received. * * @see OncRpcBroadcastListener * @see OncRpcBroadcastAdapter * @see OncRpcUdpClient * * @version $Revision: 1.3 $ $Date: 2005/11/11 21:19:20 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class OncRpcBroadcastEvent extends EventObject { /** * Defines the serial version UID for OncRpcBroadcastEvent. */ private static final long serialVersionUID = 1604512454490873965L; /** * Creates a new KscPackageUpdateEvent object and * initializes its state. * * @param source The {@link OncRpcUdpClient ONC/RPC client object} which has * fired this event. * @param replyAddress Internetaddress of reply's origin. * @param procedureNumber Procedure number of ONC/RPC call. * @param params The ONC/RPC call resulting in this reply. * @param reply The ONC/RPC reply itself. */ public OncRpcBroadcastEvent(OncRpcUdpClient source, InetAddress replyAddress, int procedureNumber, XdrAble params, XdrAble reply) { super(source); this.replyAddress = replyAddress; this.procedureNumber = procedureNumber; this.params = params; this.reply = reply; } /** * Returns the address of the sender of the ONC/RPC reply message. * * @return address of sender of reply. */ public InetAddress getReplyAddress() { return replyAddress; } /** * Returns ONC/RPC reply message. * * @return reply message object. */ public XdrAble getReply() { return reply; } /** * Returns the number of the remote procedure called. * * @return procedure number. */ public int getProcedureNumber() { return procedureNumber; } /** * Returns the parameter message sent in a broadcast RPC. * * @return parameter message object. */ public XdrAble getParams() { return params; } /** * Contains the address of the sender of the ONC/RPC reply message. * * @serial */ private InetAddress replyAddress; /** * Contains the number of the remote procedure called. * * @serial */ private int procedureNumber; /** * Contains the parameters sent in the ONC/RPC broadcast call. * * @serial */ private XdrAble params; /** * Contains the reply from a remote ONC/RPC server, which answered * the broadcast call. * * @serial */ private XdrAble reply; } // End of OncRpcBroadcastEvent.java remotetea-1.0.7/src/org/acplt/oncrpc/OncRpcBroadcastListener.java0000644005374700003410000000371707716406374026173 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/OncRpcBroadcastListener.java,v 1.1.1.1 2003/08/13 12:03:40 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; /** * The listener class for {@link OncRpcBroadcastListener receiving} * {@link OncRpcBroadcastEvent ONC/RPC broadcast reply events}. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:40 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public interface OncRpcBroadcastListener { /** * Invoked when a reply to an ONC/RPC broadcast call is received. * *

Please note that you should not spend too much time when handling * broadcast events, otherwise you'll probably miss some of the incomming * replies. Because most operating systems will not buffer large amount * of incomming UDP/IP datagramms for a given socket, you will experience * packet drops when you stay too long in the processing stage. * * @see OncRpcBroadcastEvent */ public void replyReceived(OncRpcBroadcastEvent evt); } // End of OncRpcBroadcastListener.java remotetea-1.0.7/src/org/acplt/oncrpc/OncRpcCallMessage.java0000644005374700003410000000766007716622074024741 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/OncRpcCallMessage.java,v 1.2 2003/08/14 07:55:07 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; /** * The OncRpcCallMessage class represents a remote procedure call * message as defined by ONC/RPC in RFC 1831. Such messages are sent by ONC/RPC * clients to servers in order to request a remote procedure call. * *

Note that this is an abstract class. Because call message objects also * need to deal with authentication protocol issues, they need help of so-called * authentication protocol handling objects. These objects are of different * classes, depending on where they are used (either within the server or * the client). * *

Please also note that this class implements no encoding or decoding * functionality: it doesn't need them. Only derived classes will be able * to be encoded on the side of the client and decoded at the end of the * server. * * @version $Revision: 1.2 $ $Date: 2003/08/14 07:55:07 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public abstract class OncRpcCallMessage extends OncRpcMessage { /** * Protocol version used by this ONC/RPC Java implementation. The protocol * version 2 is defined in RFC 1831. */ public final static int ONCRPC_VERSION = 2; /** * Protocol version used by this ONC/RPC call message. */ public int oncRpcVersion; /** * Program number of this particular remote procedure call message. */ public int program; /** * Program version number of this particular remote procedure call message. */ public int version; /** * Number (identifier) of remote procedure to call. */ public int procedure; /** * Constructs and initialises a new ONC/RPC call message header. * * @param messageId An identifier choosen by an ONC/RPC client to uniquely * identify matching call and reply messages. * @param program Program number of the remote procedure to call. * @param version Program version number of the remote procedure to call. * @param procedure Procedure number (identifier) of the procedure to call. */ public OncRpcCallMessage(int messageId, int program, int version, int procedure) { super(messageId); messageType = OncRpcMessageType.ONCRPC_CALL; oncRpcVersion = ONCRPC_VERSION; this.program = program; this.version = version; this.procedure = procedure; } /** * Constructs a new (incompletely initialized) ONC/RPC call message header. * The messageType is set to * {@link OncRpcMessageType#ONCRPC_CALL} and the oncRpcVersion * is set to {@link #ONCRPC_VERSION}. */ public OncRpcCallMessage() { super(0); messageType = OncRpcMessageType.ONCRPC_CALL; oncRpcVersion = ONCRPC_VERSION; this.program = 0; this.version = 0; this.procedure = 0; } } // End of OncRpcCallMessage.java remotetea-1.0.7/src/org/acplt/oncrpc/OncRpcClient.java0000644005374700003410000005173507716673422024004 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/OncRpcClient.java,v 1.3 2003/08/14 13:48:33 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; import java.io.IOException; import java.net.InetAddress; /** * The abstract OncRpcClient class is the foundation for * protcol-specific ONC/RPC clients. It encapsulates protocol-independent * functionality, like port resolving, if no port was specified for the * ONC/RPC server to contact. This class also provides the method skeleton, * for instance for executing procedure calls. * *

In order to communicate with an ONC/RPC server, you need to create an * ONC/RPC client, represented by classes derived from OncRpcClient. * The most generic way to generate an ONC/RPC client is as follows: use * {@link #newOncRpcClient(InetAddress, int, int, int) newOncRpcClient(...)} * and specify: * *

    *
  • the host (of class InetAddress) where the ONC/RPC server resides, *
  • the ONC/RPC program number of the server to contact, *
  • the program's version number, *
  • and finally the IP protocol to use when talking to the server. This can be * either {@link OncRpcProtocols#ONCRPC_UDP} or * {@link OncRpcProtocols#ONCRPC_TCP}. *
* *

The next code snippet shows how to create an ONC/RPC client, which can * communicate over UDP/IP with the ONC/RPC server for program number * 0x49678 on the same host (by coincidence, this is the program * number of the ACPLT/KS protocol). * *

 * OncRpcClient client;
 * try {
 *     client = OncRpcClient.newOncRpcClient(
 *         InetAddress.getByName("localhost"),
 *         0x49678, 1,
 *         OncRpcProtocols.ONCRPC_UDP);
 * } catch ( OncRpcProgramNotRegisteredException e ) {
 *     System.out.println("ONC/RPC program server not found");
 *     System.exit(0);
 * } catch ( OncRpcException e ) {
 *     System.out.println("Could not contact portmapper:");
 *     e.printStackTrace(System.out);
 *     System.exit(0);
 * } catch ( IOException e ) {
 *     System.out.println("Could not contact portmapper:");
 *     e.printStackTrace(System.out);
 *     System.exit(0);
 * }
 * 
* *

This code snippet also shows exception handling. The most common error * you'll see is probably an {@link OncRpcProgramNotRegisteredException}, in * case no such program number is currently registered at the specified host. * An {@link OncRpcProgramNotRegisteredException} is a subclass of * {@link OncRpcException} with a detail of * {@link OncRpcException#RPC_PROGNOTREGISTERED}. * In case no ONC/RPC portmapper is available at the specified host, you'll * get an {@link OncRpcTimeoutException} instead (which is again a subclass of * OncRpcException with a detail of * {@link OncRpcException#RPC_TIMEDOUT}). * You might also get an IOException when using TCP/IP and the server * can not be contacted because it does not accept new connections. * *

Instead of calling * {@link #newOncRpcClient(InetAddress, int, int, int) OncRpcClient.newOncRpcClient(...)} * you can also directly create objects of classes * {@link OncRpcTcpClient} and {@link OncRpcUdpClient} if you know at compile * time which kind of IP protocol you will use. * *

With a client proxy in your hands, you can now issue ONC/RPC calls. As * a really, really simple example -- did I say "simple example"? -- we start * with the famous ONC/RPC ping call. This call sends no parameters and expects * no return from an ONC/RPC server. It is just used to check whether a server * is still responsive. * *

 * System.out.print("pinging server: ");
 * try {
 *     client.call(0, XdrVoid.XDR_VOID, XdrVoid.XDR_VOID);
 * } catch ( OncRpcException e ) {
 *     System.out.println("method call failed unexpectedly:");
 *     e.printStackTrace(System.out);
 *     System.exit(1);
 * }
 * System.out.println("server is alive.");
 * 
* *

By definition, the ONC/RPC ping call has program number 0 and expects * no parameters and replies with no result. Thus we just specify an empty * parameter and result in the form of the static {@link XdrVoid#XDR_VOID} * object, when calling the ping procedure in the server using the * {@link #call(int, XdrAble, XdrAble) call(...)} method. * *

For more complex and sometimes more useful ONC/RPC calls, you will need * to write appropriate ONC/RPC parameter and reply classes. Unfortunately, * at this time there's no compiler available to compile .x files * into appropriate Java classes. Well -- surely a lot of people will now associate * completely wrong things with "x files", but in our case there's no new age * or whatever mumbo jumbo involved, but definitions of XDR data structures * instead. * * For the next example, let's pretend our server provides the answer to all * questions when called with procedure number 42. Let's also pretend that * this ONC/RPC call expects a question in form of a string and returns the * answer as an integer. So we need to define two classes, one for the call's * parameters and one for the reply. But let us first examine the class * containing a call's parameters: * *

 * class Parameters implements XdrAble {
 *     public String question;
 *
 *     public void xdrEncode(XdrEncodingStream xdr)
 *         throws OncRpcException, IOException {
 *         xdr.xdrEncodeString(question);
 *     }
 *     public void xdrDecode(XdrDecodingStream xdr)
 *         throws OncRpcException, IOException {
 *         question = xdr.xdrDecodeString();
 *     }
 * }
 * 
* *

The Parameters class implements {@link XdrAble}, so instances * of it can be sent and received over the network using Sun's XDR protocol. * What exactly is sent over the wire is up to the two methods * {@link XdrAble#xdrEncode xdrEncode(...)} and * {@link XdrAble#xdrDecode xdrDecode(...)}. The xdrEncode method * is responsible to "encode" the data to be sent over the network. On the * other side, xdrDecode is responsible to restore an object's * state from the data received over the network. In our example, these methods * either send or receive a string. * *

The class defining the reply of our the-answer-to-all-questions ONC/RPC * call is now straightforward: * *

 * class Answer implements XdrAble {
 *     public int definitiveAnswer;
 *
 *     public void xdrEncode(XdrEncodingStream xdr)
 *         throws OncRpcException, IOException {
 *         xdr.xdrEncodeInt(definitiveAnswer);
 *     }
 *     public void xdrDecode(XdrDecodingStream xdr)
 *         throws OncRpcException, IOException {
 *         definitiveAnswer = xdr.xdrDecodeInt();
 *     }
 * }
 * 
* *

Finally, to ask a question, you need to create the parameter object and * fill it with the parameters to be sent. Then create the object later receiving * the reply. Finally issue the ONC/RPC call: * *

 * Parameters parameters = new Parameters();
 * parameters.question = "What is the final answer to all our questions?";
 *
 * Answer answer = new Answer();
 *
 * try {
 *     client.call(42, parameters, answer);
 * } catch ( OncRpcException e ) {
 * } catch ( IOException e ) {
 * }
 * System.out.println(parameters.question);
 * System.out.println("And the answer is: " + answer.definitiveAnswer);
 * 
* *

When you do not need the client proxy object any longer, you should * return the resources it occupies to the system. Use the {@link #close} * method for this. * *

 * client.close();
 * client = null; // Hint to the garbage (wo)man
 * 
* *

{@link OncRpcClientAuth Authentication} can be done as follows: just * create an authentication object and hand it over to the ONC/RPC client * object. * *

 * OncRpcClientAuth auth = new OncRpcClientAuthUnix(
 *                                 "marvin@ford.prefect",
 *                                 42, 1001, new int[0]);
 * client.setAuth(auth);
 * 
* * The {@link OncRpcClientAuthUnix authentication AUTH_UNIX} will * handle shorthand credentials (of type AUTH_SHORT) transparently. * If you do not set any authentication object after creating an ONC/RPC client * object, AUTH_NONE is used automatically. * *

TCP-based ONC/RPC clients also support call batching (exception handling * ommited for clarity): * *

 * OncRpcTcpClient client = new OncRpcTcpClient(
 *     InetAddress.getByName("localhost"),
 *     myprogramnumber, myprogramversion,
 *     OncRpcProtocols.ONCRPC_TCP);
 * client.callBatch(42, myparams, false);
 * client.callBatch(42, myotherparams, false);
 * client.callBatch(42, myfinalparams, true);
 * 
* * In the example above, three calls are batched in a row and only be sent * all together with the third call. Note that batched calls must not expect * replies, with the only exception being the last call in a batch: * *
 * client.callBatch(42, myparams, false);
 * client.callBatch(42, myotherparams, false);
 * client.call(43, myfinalparams, myfinalresult);
 * 
* * @see OncRpcPortmapClient * @see OncRpcTcpClient * @see OncRpcUdpClient * @see OncRpcClientAuth * * @version $Revision: 1.3 $ $Date: 2003/08/14 13:48:33 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public abstract class OncRpcClient { /** * Constructs an OncRpcClient object (the generic part). If * no port number is given (that is, port is 0), * then a port lookup using the portmapper at host is done. * * @param host Host address where the desired ONC/RPC server resides. * @param program Program number of the desired ONC/RPC server. * @param version Version number of the desired ONC/RPC server. * @param protocol {@link OncRpcProtocols Protocol} to be used for * ONC/RPC calls. This information is necessary, so port lookups through * the portmapper can be done. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ protected OncRpcClient(InetAddress host, int program, int version, int port, int protocol) throws OncRpcException, IOException { // // Set up the basics... // this.host = host; this.program = program; this.version = version; // // Initialize the message identifier with some more-or-less random // value. // long seed = System.currentTimeMillis(); xid = ((int) seed) ^ ((int) (seed >>> 32)); // // If the port number of the ONC/RPC server to contact is not yet // known, try to find it out. For this we need to contact the portmap // process at the given host and ask it for the desired program. // // In case of tunneling through the HTTP protocol, we accept a port // number of zero and do not resolve it. This task is left up to // the other end of the HTTP tunnel (at the web server). // if ( (port == 0) && (protocol != OncRpcProtocols.ONCRPC_HTTP) ) { OncRpcPortmapClient portmap = new OncRpcPortmapClient(host); try { port = portmap.getPort(program, version, protocol); } finally { portmap.close(); } } this.port = port; } /** * Creates a new ONC/RPC client object, which can handle the requested * protocol. * * @param host Host address where the desired ONC/RPC server resides. * @param program Program number of the desired ONC/RPC server. * @param version Version number of the desired ONC/RPC server. * @param protocol {@link OncRpcProtocols Protocol} to be used for * ONC/RPC calls. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public static OncRpcClient newOncRpcClient(InetAddress host, int program, int version, int protocol) throws OncRpcException, IOException { return newOncRpcClient(host, program, version, 0, protocol); } /** * Creates a new ONC/RPC client object, which can handle the requested * protocol. * * @param host Host address where the desired ONC/RPC server resides. * @param program Program number of the desired ONC/RPC server. * @param version Version number of the desired ONC/RPC server. * @param port Port number of the ONC/RPC server. Specifiy 0 * if this is not known and the portmap process located at host should * be contacted to find out the port. * @param protocol {@link OncRpcProtocols Protocol} to be used for * ONC/RPC calls. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public static OncRpcClient newOncRpcClient(InetAddress host, int program, int version, int port, int protocol) throws OncRpcException, IOException { // // Now we need to create a protocol client object, which will know // how to create the network connection and how to send and receive // data to and from it. // switch ( protocol ) { case OncRpcProtocols.ONCRPC_UDP: return new OncRpcUdpClient(host, program, version, port); case OncRpcProtocols.ONCRPC_TCP: return new OncRpcTcpClient(host, program, version, port); default: throw(new OncRpcException(OncRpcException.RPC_UNKNOWNPROTO)); } } /** * Close the connection to an ONC/RPC server and free all network-related * resources. Well -- at least hope, that the Java VM will sometimes free * some resources. Sigh. * * @throws OncRpcException if an ONC/RPC error occurs. */ public void close() throws OncRpcException { } /** * Calls a remote procedure on an ONC/RPC server. * *

The OncRpcUdpClient uses a similar timeout scheme as * the genuine Sun C implementation of ONC/RPC: it starts with a timeout * of one second when waiting for a reply. If no reply is received within * this time frame, the client doubles the timeout, sends a new request * and then waits again for a reply. In every case the client will wait * no longer than the total timeout set through the * {@link #setTimeout(int)} method. * * @param procedureNumber Procedure number of the procedure to call. * @param params The parameters of the procedure to call, contained * in an object which implements the {@link XdrAble} interface. * @param result The object receiving the result of the procedure call. * * @throws OncRpcException if an ONC/RPC error occurs. */ public synchronized void call(int procedureNumber, XdrAble params, XdrAble result) throws OncRpcException { // // Use the default version number as specified for this client. // call(procedureNumber, version, params, result); } /** * Calls a remote procedure on an ONC/RPC server. * * @param procedureNumber Procedure number of the procedure to call. * @param versionNumber Protocol version number. * @param parameters The parameters of the procedure to call, contained * in an object which implements the {@link XdrAble} interface. * @param result The object receiving the result of the procedure call. * * @throws OncRpcException if an ONC/RPC error occurs. */ public abstract void call(int procedureNumber, int versionNumber, XdrAble parameters, XdrAble result) throws OncRpcException; /** * Set the timout for remote procedure calls to wait for an answer from * the ONC/RPC server. If the timeout expires, * {@link #call(int, XdrAble, XdrAble)} will raise a * {@link java.io.InterruptedIOException}. The default timeout value is * 30 seconds (30,000 milliseconds). The timeout must be > 0. * A timeout of zero indicated batched calls, for which no reply message * is expected. * * @param milliseconds Timeout in milliseconds. A timeout of zero indicates * batched calls. */ public void setTimeout(int milliseconds) { if ( milliseconds < 0 ) { throw(new IllegalArgumentException("timeouts can not be negative.")); } timeout = milliseconds; } /** * Retrieve the current timeout set for remote procedure calls. A timeout * of zero indicates batching calls (no reply message is expected). * * @return Current timeout. */ public int getTimeout() { return timeout; } /** * Returns the program number specified when creating this client. * * @return ONC/RPC program number. */ public int getProgram() { return program; } /** * Returns the version number specified when creating this client. * * @return ONC/RPC version number of ONC/RPC program. */ public int getVersion() { return version; } /** * Returns the IP address of the server's host this client is connected to. * * @return IP address of host. */ public InetAddress getHost() { return host; } /** * Returns port number of the server this client is connected to. * * @return port number of ONC/RPC server. */ public int getPort() { return port; } /** * Sets the authentication to be used when making ONC/RPC calls. * * @param auth Authentication protocol handling object encapsulating * authentication information. */ public void setAuth(OncRpcClientAuth auth) { this.auth = auth; } /** * Returns the current authentication. * * @return Authentication protocol handling object encapsulating * authentication information. */ public OncRpcClientAuth getAuth() { return auth; } /** * Set the character encoding for (de-)serializing strings. * * @param characterEncoding the encoding to use for (de-)serializing strings. * If null, the system's default encoding is to be used. */ public abstract void setCharacterEncoding(String characterEncoding); /** * Get the character encoding for (de-)serializing strings. * * @return the encoding currently used for (de-)serializing strings. * If null, then the system's default encoding is used. */ public abstract String getCharacterEncoding(); /** * Create next message identifier. Message identifiers are used to match * corresponding ONC/RPC call and reply messages. */ protected void nextXid() { xid++; } /** * Internet address of the host where the ONC/RPC server we want to * communicate with is located at. */ protected InetAddress host; /** * Timeout (in milliseconds) for communication with an ONC/RPC server. * ONC/RPC calls through the {@link #call(int, XdrAble, XdrAble)} method * will throw an exception if no answer from the ONC/RPC server is * received within the timeout time span. */ protected int timeout = 30000; /** * Program number of the ONC/RPC server to communicate with. */ protected int program; /** * Version number of the ONC/RPC server to communicate with. */ protected int version; /** * Port number at which the ONC/RPC server can be contacted. */ protected int port; /** * The message id (also sometimes known as "transaction id") used for * the next call message. */ protected int xid; /** * Authentication protocol object to be used when issuing ONC/RPC calls. */ protected OncRpcClientAuth auth; } // End of OncRpcClient.javaremotetea-1.0.7/src/org/acplt/oncrpc/OncRpcClientAuth.java0000644005374700003410000000700707716406374024617 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/OncRpcClientAuth.java,v 1.1.1.1 2003/08/13 12:03:40 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; import java.io.IOException; /** * The OncRpcClientAuth class is the base class for handling * all protocol issues of ONC/RPC authentication on the client side. As it * stands, it does not do very much with the exception of defining the contract * for the behaviour of derived classes with respect to protocol handling * issues. * *

Authentication on the client side can be done as follows: just * create an authentication object and hand it over to the ONC/RPC client * object. * *

 * OncRpcClientAuth auth = new OncRpcClientAuthUnix(
 *                                 "marvin@ford.prefect",
 *                                 42, 1001, new int[0]);
 * client.setAuth(auth);
 * 
* * The {@link OncRpcClientAuthUnix authentication AUTH_UNIX} will * handle shorthand credentials (of type AUTH_SHORT transparently). * If you do not set any authentication object after creating an ONC/RPC client * object, AUTH_NONE is used automatically. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:40 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public abstract class OncRpcClientAuth { /** * Encodes ONC/RPC authentication information in form of a credential * and a verifier when sending an ONC/RPC call message. * * @param xdr XDR stream where to encode the credential and the verifier * to. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ protected abstract void xdrEncodeCredVerf(XdrEncodingStream xdr) throws OncRpcException, IOException; /** * Decodes ONC/RPC authentication information in form of a verifier * when receiving an ONC/RPC reply message. * * @param xdr XDR stream from which to receive the verifier sent together * with an ONC/RPC reply message. * * @throws OncRpcAuthenticationException if the received verifier is * not kosher. * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ protected abstract void xdrDecodeVerf(XdrDecodingStream xdr) throws OncRpcException, IOException; /** * Indicates whether the ONC/RPC authentication credential can be * refreshed. * * @return true, if the credential can be refreshed */ protected abstract boolean canRefreshCred(); } // End of OncRpcClientAuth.java remotetea-1.0.7/src/org/acplt/oncrpc/OncRpcClientAuthNone.java0000644005374700003410000001021507716406374025432 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/OncRpcClientAuthNone.java,v 1.1.1.1 2003/08/13 12:03:40 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; import java.io.IOException; /** * The OncRpcClientAuthNone class handles protocol issues of * ONC/RPC AUTH_NONE authentication. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:40 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class OncRpcClientAuthNone extends OncRpcClientAuth { /** * Encodes ONC/RPC authentication information in form of a credential * and a verifier when sending an ONC/RPC call message. * * @param xdr XDR stream where to encode the credential and the verifier * to. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ protected void xdrEncodeCredVerf(XdrEncodingStream xdr) throws OncRpcException, IOException { // // The credential only consists of the indication of AUTH_NONE with // no opaque authentication data following. // xdr.xdrEncodeInt(OncRpcAuthType.ONCRPC_AUTH_NONE); xdr.xdrEncodeInt(0); // // But we also need to encode the verifier. This is always of type // AUTH_NONE too. For some obscure historical reasons, we have to // deal with credentials and verifiers, although they belong together, // according to Sun's specification. // xdr.xdrEncodeInt(OncRpcAuthType.ONCRPC_AUTH_NONE); xdr.xdrEncodeInt(0); } /** * Decodes ONC/RPC authentication information in form of a verifier * when receiving an ONC/RPC reply message. * * @param xdr XDR stream from which to receive the verifier sent together * with an ONC/RPC reply message. * * @throws OncRpcAuthenticationException if the received verifier is * not kosher. * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ protected void xdrDecodeVerf(XdrDecodingStream xdr) throws OncRpcException, IOException { // // Make sure that we received a AUTH_NONE verifier and that it // does not contain any opaque data. Anything different from this // is not kosher and an authentication exception will be thrown. // if ( (xdr.xdrDecodeInt() != OncRpcAuthType.ONCRPC_AUTH_NONE) || (xdr.xdrDecodeInt() != 0) ) { throw(new OncRpcAuthenticationException( OncRpcAuthStatus.ONCRPC_AUTH_FAILED)); } } /** * Indicates whether the ONC/RPC authentication credential can be * refreshed. * * @return true, if the credential can be refreshed */ protected boolean canRefreshCred() { // // Nothing to do here, as AUTH_NONE doesn't know anything of // credential refreshing. How refreshing... // return false; } /** * Contains a singleton which comes in handy if you just need an * AUTH_NONE authentification for an ONC/RPC client. */ public static final OncRpcClientAuthNone AUTH_NONE = new OncRpcClientAuthNone(); } // End of OncRpcClientAuthNone.java remotetea-1.0.7/src/org/acplt/oncrpc/OncRpcClientAuthUnix.java0000644005374700003410000002656707716406374025477 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/OncRpcClientAuthUnix.java,v 1.1.1.1 2003/08/13 12:03:40 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; import java.io.IOException; /** * The OncRpcClientAuthUnix class handles protocol issues of * ONC/RPC AUTH_UNIX (and thus AUTH_SHORT) * authentication. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:40 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class OncRpcClientAuthUnix extends OncRpcClientAuth { /** * Constructs a new OncRpcClientAuthUnix authentication * protocol handling object capable of handling AUTH_UNIX * and AUTH_SHORT. * *

Please note that the credential information is typically only * unique within a particular domain of machines, user IDs and * group IDs. * * @param machinename Name of the caller's machine (like * "ebankruptcy-dot-com", just for instance...). * @param uid Caller's effective user ID. * @param gid Caller's effective group ID. * @param gids Array of group IDs the caller is a member of. */ public OncRpcClientAuthUnix(String machinename, int uid, int gid, int [] gids) { this.stamp = (int)(System.currentTimeMillis() / 1000); this.machinename = machinename; this.uid = uid; this.gid = gid; this.gids = gids; } /** * Constructs a new OncRpcClientAuthUnix authentication * protocol handling object capable of handling AUTH_UNIX * and AUTH_SHORT. * *

Please note that the credential information is typically only * unique within a particular domain of machines, user IDs and * group IDs. * * @param machinename Name of the caller's machine (like * "ebankruptcy-dot-com", just for instance...). * @param uid Caller's effective user ID. * @param gid Caller's effective group ID. */ public OncRpcClientAuthUnix(String machinename, int uid, int gid) { this(machinename, uid, gid, NO_GIDS); } /** * Encodes ONC/RPC authentication information in form of a credential * and a verifier when sending an ONC/RPC call message. The * AUTH_UNIX authentication method only uses the credential * but no verifier. If the ONC/RPC server sent a AUTH_SHORT * "shorthand" credential together with the previous reply message, it * is used instead of the original credential. * * @param xdr XDR stream where to encode the credential and the verifier * to. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ protected void xdrEncodeCredVerf(XdrEncodingStream xdr) throws OncRpcException, IOException { if ( shorthandCred == null ) { // // Encode the credential, which contains some unsecure information // about user and group ID, etc. Note that the credential itself // is encoded as a variable-sized bunch of octets. // if ( (gids.length > OncRpcAuthConstants.ONCRPC_MAX_GROUPS) || (machinename.length() > OncRpcAuthConstants.ONCRPC_MAX_MACHINE_NAME) ) { throw(new OncRpcAuthenticationException( OncRpcAuthStatus.ONCRPC_AUTH_FAILED)); } xdr.xdrEncodeInt(OncRpcAuthType.ONCRPC_AUTH_UNIX); int len = 4 // length of stamp + ((machinename.length() + 7) & ~3) // len string incl. len + 4 // length of uid + 4 // length of gid + gids.length * 4 + 4 // length of vector of gids incl. len ; if ( len > OncRpcAuthConstants.ONCRPC_MAX_AUTH_BYTES ) { throw(new OncRpcAuthenticationException( OncRpcAuthStatus.ONCRPC_AUTH_FAILED)); } xdr.xdrEncodeInt(len); xdr.xdrEncodeInt(stamp); xdr.xdrEncodeString(machinename); xdr.xdrEncodeInt(uid); xdr.xdrEncodeInt(gid); xdr.xdrEncodeIntVector(gids); } else { // // Use shorthand credential instead of original credential. // xdr.xdrEncodeInt(OncRpcAuthType.ONCRPC_AUTH_SHORT); xdr.xdrEncodeDynamicOpaque(shorthandCred); } // // We also need to encode the verifier, which is always of // type AUTH_NONE. // xdr.xdrEncodeInt(OncRpcAuthType.ONCRPC_AUTH_NONE); xdr.xdrEncodeInt(0); } /** * Decodes ONC/RPC authentication information in form of a verifier * when receiving an ONC/RPC reply message. * * @param xdr XDR stream from which to receive the verifier sent together * with an ONC/RPC reply message. * * @throws OncRpcAuthenticationException if the received verifier is * not kosher. * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ protected void xdrDecodeVerf(XdrDecodingStream xdr) throws OncRpcException, IOException { // // The verifier sent in response to AUTH_UNIX or AUTH_SHORT credentials // can only be AUTH_NONE or AUTH_SHORT. In the latter case we drop // any old shorthand credential and use the new one. // switch ( xdr.xdrDecodeInt() ) { case OncRpcAuthType.ONCRPC_AUTH_NONE: // // Make sure that the verifier does not contain any opaque data. // Anything different from this is not kosher and an authentication // exception will be thrown. // if ( xdr.xdrDecodeInt() != 0 ) { throw(new OncRpcAuthenticationException( OncRpcAuthStatus.ONCRPC_AUTH_FAILED)); } break; case OncRpcAuthType.ONCRPC_AUTH_SHORT: // // Fetch the credential from the XDR stream and make sure that // it does conform to the length restriction as set forth in // the ONC/RPC protocol. // shorthandCred = xdr.xdrDecodeDynamicOpaque(); if ( shorthandCred.length > OncRpcAuthConstants.ONCRPC_MAX_AUTH_BYTES ) { throw(new OncRpcAuthenticationException( OncRpcAuthStatus.ONCRPC_AUTH_FAILED)); } break; default: // // Do not accept any other kind of verifier sent. // throw(new OncRpcAuthenticationException( OncRpcAuthStatus.ONCRPC_AUTH_INVALIDRESP)); } } /** * Indicates whether the ONC/RPC authentication credential can be * refreshed. * * @return true, if the credential can be refreshed */ protected boolean canRefreshCred() { // // If we don't use a shorthand credential at this time, then there's // no hope to refresh the credentials. // if ( shorthandCred == null ) { return false; } // // Otherwise just dump the shorthand credentials and let the caller // retry. This will probably result in the ONC/RPC server replying // with a new shorthand credential. // shorthandCred = null; // // Ah, yes. We need to update the "stamp" (more a timestamp, but // Sun coding style is sometimes interesting). As is my style too. // stamp = (int)(System.currentTimeMillis() / 1000); // // Oh, yes. We can refresh the credential. Maybe. // return true; } /** * Sets the timestamp information in the credential. * * @param stamp New timestamp */ public void setStamp(int stamp) { this.stamp = stamp; } /** * Returns the timestamp information from the credential. * * @return timestamp from credential. */ public int getStamp() { return stamp; } /** * Sets the machine name information in the credential. * * @param machinename Machine name. */ public void setMachinename(String machinename) { this.machinename = machinename; } /** * Returns the machine name information from the credential. * * @return machine name. */ public String getMachinename() { return machinename; } /** * Sets the user ID in the credential. * * @param uid User ID. */ public void setUid(int uid) { this.uid = uid; } /** * Returns the user ID from the credential. * * @return user ID. */ public int getUid() { return uid; } /** * Sets the group ID in the credential. * * @param gid Group ID. */ public void setGid(int gid) { this.gid = gid; } /** * Returns the group ID from the credential. * * @return group ID. */ public int getGid() { return gid; } /** * Sets the group IDs in the credential. * * @param gids Array of group IDs. */ public void setGids(int [] gids) { this.gids = gids; } /** * Returns the group IDs from the credential. * * @return array of group IDs. */ public int [] getGids() { return gids; } /** * Contains timestamp as supplied through credential. */ private int stamp; /** * Contains the machine name of caller supplied through credential. */ private String machinename; /** * Contains the user ID of caller supplied through credential. */ private int uid; /** * Contains the group ID of caller supplied through credential. */ private int gid; /** * Contains a set of group IDs the caller belongs to, as supplied * through credential. */ private int [] gids; /** * Holds the "shorthand" credentials of type AUTH_SHORT * optionally returned by an ONC/RPC server to be used on subsequent * ONC/RPC calls. */ private byte [] shorthandCred; /** * Contains an empty array of group IDs. */ public final static int [] NO_GIDS = new int [0]; } // End of OncRpcClientAuthUnix.javaremotetea-1.0.7/src/org/acplt/oncrpc/OncRpcClientCallMessage.java0000644005374700003410000000702207716406374026073 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/OncRpcClientCallMessage.java,v 1.1.1.1 2003/08/13 12:03:40 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; import java.io.IOException; /** * The OncRpcClientCallMessage class represents a remote procedure * call message on the client side. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:40 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class OncRpcClientCallMessage extends OncRpcCallMessage { /** * Constructs and initialises a new ONC/RPC call message header. * * @param messageId An identifier choosen by an ONC/RPC client to uniquely * identify matching call and reply messages. * @param program Program number of the remote procedure to call. * @param version Program version number of the remote procedure to call. * @param procedure Procedure number (identifier) of the procedure to call. * @param auth Authentication protocol handling object. */ public OncRpcClientCallMessage(int messageId, int program, int version, int procedure, OncRpcClientAuth auth) { super(messageId, program, version, procedure); this.auth = auth; } /** * Encodes -- that is: serializes -- a ONC/RPC message header object * into a XDR stream according to RFC 1831. * * @param xdr An encoding XDR stream where to put the mess in. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException { xdr.xdrEncodeInt(messageId); xdr.xdrEncodeInt(messageType); xdr.xdrEncodeInt(oncRpcVersion); xdr.xdrEncodeInt(program); xdr.xdrEncodeInt(version); xdr.xdrEncodeInt(procedure); // // Now encode the authentication data. If we have an authentication // protocol handling object at hand, then we let do the dirty work // for us. Otherwise, we fall back to AUTH_NONE handling. // if ( auth != null ) { auth.xdrEncodeCredVerf(xdr); } else { xdr.xdrEncodeInt(OncRpcAuthType.ONCRPC_AUTH_NONE); xdr.xdrEncodeInt(0); xdr.xdrEncodeInt(OncRpcAuthType.ONCRPC_AUTH_NONE); xdr.xdrEncodeInt(0); } } /** * Client-side authentication protocol handling object to use when * decoding the reply message. */ protected OncRpcClientAuth auth; } // End of OncRpcClientCallMessage.java remotetea-1.0.7/src/org/acplt/oncrpc/OncRpcClientReplyMessage.java0000644005374700003410000002013307716406374026311 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/OncRpcClientReplyMessage.java,v 1.1.1.1 2003/08/13 12:03:40 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; import java.io.IOException; /** * The OncRpcReplyMessage class represents an ONC/RPC reply * message as defined by ONC/RPC in RFC 1831. Such messages are sent back by * ONC/RPC to servers to clients and contain (in case of real success) the * result of a remote procedure call. * *

The decision to define only one single class for the accepted and * rejected replies was driven by the motivation not to use polymorphism * and thus have to upcast and downcast references all the time. * *

The derived classes are only provided for convinience on the server * side. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:40 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class OncRpcClientReplyMessage extends OncRpcReplyMessage { /** * Initializes a new OncRpcReplyMessage object to represent * an invalid state. This default constructor should only be used if in the * next step the real state of the reply message is immediately decoded * from a XDR stream. * * @param auth Client-side authentication protocol handling object which * is to be used when decoding the verifier data contained in the reply. */ public OncRpcClientReplyMessage(OncRpcClientAuth auth) { super(); this.auth = auth; } /** * Check whether this OncRpcReplyMessage represents an * accepted and successfully executed remote procedure call. * * @return true if remote procedure call was accepted and * successfully executed. */ public boolean successfullyAccepted() { return (replyStatus == OncRpcReplyStatus.ONCRPC_MSG_ACCEPTED) && (acceptStatus == OncRpcAcceptStatus.ONCRPC_SUCCESS); } /** * Return an appropriate exception object according to the state this * reply message header object is in. The exception object then can be * thrown. * * @return Exception object of class {@link OncRpcException} or a subclass * thereof. */ public OncRpcException newException() { switch ( replyStatus ) { case OncRpcReplyStatus.ONCRPC_MSG_ACCEPTED: switch ( acceptStatus ) { case OncRpcAcceptStatus.ONCRPC_SUCCESS: return new OncRpcException(OncRpcException.RPC_SUCCESS); case OncRpcAcceptStatus.ONCRPC_PROC_UNAVAIL: return new OncRpcException(OncRpcException.RPC_PROCUNAVAIL); case OncRpcAcceptStatus.ONCRPC_PROG_MISMATCH: return new OncRpcException(OncRpcException.RPC_PROGVERSMISMATCH); case OncRpcAcceptStatus.ONCRPC_PROG_UNAVAIL: return new OncRpcException(OncRpcException.RPC_PROGUNAVAIL); case OncRpcAcceptStatus.ONCRPC_GARBAGE_ARGS: return new OncRpcException(OncRpcException.RPC_CANTDECODEARGS); case OncRpcAcceptStatus.ONCRPC_SYSTEM_ERR: return new OncRpcException(OncRpcException.RPC_SYSTEMERROR); } break; case OncRpcReplyStatus.ONCRPC_MSG_DENIED: switch ( rejectStatus ) { case OncRpcRejectStatus.ONCRPC_AUTH_ERROR: return new OncRpcAuthenticationException(authStatus); case OncRpcRejectStatus.ONCRPC_RPC_MISMATCH: return new OncRpcException(OncRpcException.RPC_FAILED); } break; } return new OncRpcException(); } /** * Decodes -- that is: deserializes -- a ONC/RPC message header object * from a XDR stream. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException { messageId = xdr.xdrDecodeInt(); // // Make sure that we are really decoding an ONC/RPC message call // header. Otherwise, throw the appropriate OncRpcException exception. // messageType = xdr.xdrDecodeInt(); if ( messageType != OncRpcMessageType.ONCRPC_REPLY ) { throw(new OncRpcException(OncRpcException.RPC_WRONGMESSAGE)); } replyStatus = xdr.xdrDecodeInt(); switch ( replyStatus ) { case OncRpcReplyStatus.ONCRPC_MSG_ACCEPTED: // // Decode the information returned for accepted message calls. // If we have an associated client-side authentication protocol // object, we use that. Otherwise we fall back to the default // handling of only the AUTH_NONE authentication. // if ( auth != null ) { auth.xdrDecodeVerf(xdr); } else { // // If we don't have a protocol handler and the server sent its // reply using another authentication scheme than AUTH_NONE, we // will throw an exception. Also we check that no-one is // actually sending opaque information within AUTH_NONE. // if ( xdr.xdrDecodeInt() != OncRpcAuthType.ONCRPC_AUTH_NONE ) { throw(new OncRpcAuthenticationException( OncRpcAuthStatus.ONCRPC_AUTH_FAILED)); } if ( xdr.xdrDecodeInt() != 0 ) { throw(new OncRpcAuthenticationException( OncRpcAuthStatus.ONCRPC_AUTH_FAILED)); } } // // Even if the call was accepted by the server, it can still // indicate an error. Depending on the status of the accepted // call we will receive an indication about the range of // versions a particular program (server) supports. // acceptStatus = xdr.xdrDecodeInt(); switch ( acceptStatus ) { case OncRpcAcceptStatus.ONCRPC_PROG_MISMATCH: lowVersion = xdr.xdrDecodeInt(); highVersion = xdr.xdrDecodeInt(); break; default: // // Otherwise "open ended set of problem", like the author // of Sun's ONC/RPC source once wrote... // break; } break; case OncRpcReplyStatus.ONCRPC_MSG_DENIED: // // Encode the information returned for denied message calls. // rejectStatus = xdr.xdrDecodeInt(); switch ( rejectStatus ) { case OncRpcRejectStatus.ONCRPC_RPC_MISMATCH: lowVersion = xdr.xdrDecodeInt(); highVersion = xdr.xdrDecodeInt(); break; case OncRpcRejectStatus.ONCRPC_AUTH_ERROR: authStatus = xdr.xdrDecodeInt(); break; default: } break; } } /** * Client-side authentication protocol handling object to use when * decoding the reply message. */ protected OncRpcClientAuth auth; } // End of OncRpcClientReplyMessage.java remotetea-1.0.7/src/org/acplt/oncrpc/OncRpcClientStub.java0000644005374700003410000001015307716406400024615 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/OncRpcClientStub.java,v 1.1.1.1 2003/08/13 12:03:44 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; import java.io.IOException; import java.net.InetAddress; /** * The abstract OncRpcClientStub class is the base class to * build ONC/RPC-program specific clients upon. This class is typically * only used by jrpcgen generated clients, which provide a particular * set of remote procedures as defined in a x-file. * *

When you do not need the client proxy object any longer, you should * return the resources it occupies to the system. Use the {@link #close} * method for this. * *

 * client.close();
 * client = null; // Hint to the garbage (wo)man
 * 
* * @see OncRpcTcpClient * @see OncRpcUdpClient * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:44 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public abstract class OncRpcClientStub { /** * Construct a new OncRpcClientStub for communication with * a remote ONC/RPC server. * * @param host Host address where the desired ONC/RPC server resides. * @param program Program number of the desired ONC/RPC server. * @param version Version number of the desired ONC/RPC server. * @param protocol {@link OncRpcProtocols Protocol} to be used for * ONC/RPC calls. This information is necessary, so port lookups through * the portmapper can be done. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public OncRpcClientStub(InetAddress host, int program, int version, int port, int protocol) throws OncRpcException, IOException { client = OncRpcClient.newOncRpcClient(host, program, version, port, protocol); } /** * Construct a new OncRpcClientStub which uses the given * client proxy object for communication with a remote ONC/RPC server. * * @param client ONC/RPC client proxy object implementing a particular * IP protocol. */ public OncRpcClientStub(OncRpcClient client) throws OncRpcException, IOException { this.client = client; } /** * Close the connection to an ONC/RPC server and free all network-related * resources. Well -- at least hope, that the Java VM will sometimes free * some resources. Sigh. * * @throws OncRpcException if an ONC/RPC error occurs. */ public void close() throws OncRpcException { if ( client != null ) { try { client.close(); } finally { client = null; } } } /** * Returns ONC/RPC client proxy object used for communication with a * remote ONC/RPC server. * * @return ONC/RPC client proxy. */ public OncRpcClient getClient() { return client; } /** * The real ONC/RPC client which is responsible for handling a particular * IP protocol. */ protected OncRpcClient client; } // End of OncRpcClientStub.java remotetea-1.0.7/src/org/acplt/oncrpc/OncRpcConstants.java0000644005374700003410000000412310335174350024512 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/OncRpcConstants.java,v 1.3 2005/11/11 21:02:47 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; /** * A collection of constants generally usefull for ONC/RPC. * * @version $Revision: 1.3 $ $Date: 2005/11/11 21:02:47 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public interface OncRpcConstants { /** * The current version of the Remote Tea Java library as a string. */ public static final String REMOTETEA_VERSION_STRING = "1.0.4"; /** * The current major version number of the Remote Tea Java library. */ public static final int REMOTETEA_VERSION_MAJOR = 1; /** * The current minor version number of the Remote Tea Java library. */ public static final int REMOTETEA_VERSION_MINOR = 0; /** * The current patch level of the Remote Tea Java library. */ public static final int REMOTETEA_VERSION_PATCHLEVEL = 4; /** * The current preversion version number. If not zero, then this * indicates a preversion (no, not perversion... ooops, sorry). */ public static final int REMOTETEA_VERSION_PREVERSION = 0; } // End of OncRpcConstants.javaremotetea-1.0.7/src/org/acplt/oncrpc/OncRpcDumpResult.java0000644005374700003410000000751407716406376024670 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/OncRpcDumpResult.java,v 1.1.1.1 2003/08/13 12:03:41 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; import java.io.IOException; import java.util.Vector; /** * Objects of class OncRpcDumpResult represent the outcome of * the PMAP_DUMP operation on a portmapper. OncRpcDumpResults are * (de-)serializeable, so they can be flushed down XDR streams. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:41 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class OncRpcDumpResult implements XdrAble { /** * Vector of server ident objects describing the currently registered * ONC/RPC servers (also known as "programmes"). */ public Vector servers; /** * Initialize an OncRpcServerIdent object. Afterwards, the * servers field is initialized to contain no elements. */ public OncRpcDumpResult() { servers = new Vector(); } /** * Encodes -- that is: serializes -- the result of a PMAP_DUMP operationg * into a XDR stream. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException { if ( servers == null ) { xdr.xdrEncodeBoolean(false); } else { // // Now encode all server ident objects into the xdr stream. Each // object is preceeded by a boolan, which indicates to the receiver // whether an object follows. After the last object has been // encoded the receiver will find a boolean false in the stream. // int count = servers.size(); int index = 0; while ( count > 0 ) { xdr.xdrEncodeBoolean(true); ((XdrAble) servers.elementAt(index)).xdrEncode(xdr); index++; count--; } xdr.xdrEncodeBoolean(false); } } /** * Decodes -- that is: deserializes -- the result from a PMAP_DUMP remote * procedure call from a XDR stream. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException { // // Calling removeAllElements() instead of clear() preserves // pre-JDK2 compatibility. // servers.removeAllElements(); // // Pull the server ident object off the xdr stream. Each object is // preceeded by a boolean value indicating whether there is still an // object in the pipe. // while ( xdr.xdrDecodeBoolean() ) { servers.addElement(new OncRpcServerIdent(xdr)); } } } // End of OncRpcDumpResult.java remotetea-1.0.7/src/org/acplt/oncrpc/OncRpcException.java0000644005374700003410000002411110736716020024474 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/OncRpcException.java,v 1.3 2008/01/02 15:13:35 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; /** * The class OncRpcException indicates ONC/RPC conditions * that a reasonable application might want to catch. We follow here the * notation established by the Java environment that exceptions can be * caught while errors usually can't. Because we don't want to throw our * applications out of the virtual machine (should I mock here "out of the * window"?), we only define exceptions. * *

The class OncRpcException also defines a set of ONC/RPC * error codes as defined by RFC 1831. Note that all these error codes are * solely used on the client-side or server-side, but never transmitted * over the wire. For error codes transmitted over the network, refer to * {@link OncRpcAcceptStatus} and {@link OncRpcRejectStatus}. * * @version $Revision: 1.3 $ $Date: 2008/01/02 15:13:35 $ $State: Exp $ $Locker: $ * @author Harald Albrecht * * @see java.lang.Exception */ public class OncRpcException extends Exception { /** * Defines the serial version UID for OncRpcException. */ private static final long serialVersionUID = -2170017056632137324L; /** * Constructs an OncRpcException with a reason of * {@link OncRpcException#RPC_FAILED}. */ public OncRpcException() { this(OncRpcException.RPC_FAILED); } /** * Constructs an OncRpcException with the specified detail * message. * * @param s The detail message. */ public OncRpcException(String s) { super(); reason = RPC_FAILED; message = s; } /** * Constructs an OncRpcException with the specified detail * reason and message. For possible reasons, see below. * * @param r The detail reason. * @param s The detail message. */ public OncRpcException(int r, String s) { super(); reason = r; message = s; } /** * Constructs an OncRpcException with the specified detail * reason. The detail message is derived automatically from the reason. * * @param r The reason. This can be one of the constants -- oops, that * should be "public final static integers" -- defined in this * interface. */ public OncRpcException(int r) { super(); reason = r; switch ( r ) { case RPC_CANTENCODEARGS: message = "can not encode RPC arguments"; break; case RPC_CANTDECODERES: message = "can not decode RPC result"; break; case RPC_CANTRECV: message = "can not receive ONC/RPC data"; break; case RPC_CANTSEND: message = "can not send ONC/RPC data"; break; case RPC_TIMEDOUT: message = "ONC/RPC call timed out"; break; case RPC_VERSMISMATCH: message = "ONC/RPC version mismatch"; break; case RPC_AUTHERROR: message = "ONC/RPC authentification error"; break; case RPC_PROGUNAVAIL: message = "ONC/RPC program not available"; break; case RPC_CANTDECODEARGS: message = "can not decode ONC/RPC arguments"; break; case RPC_PROGVERSMISMATCH: message = "ONC/RPC program version mismatch"; break; case RPC_PROCUNAVAIL: message = "ONC/RPC procedure not available"; break; case RPC_SYSTEMERROR: message = "ONC/RPC system error"; break; case RPC_UNKNOWNPROTO: message = "unknown protocol"; break; case RPC_PMAPFAILURE: message = "ONC/RPC portmap failure"; break; case RPC_PROGNOTREGISTERED: message = "ONC/RPC program not registered"; break; case RPC_FAILED: message = "ONC/RPC generic failure"; break; case RPC_BUFFEROVERFLOW: message = "ONC/RPC buffer overflow"; break; case RPC_BUFFERUNDERFLOW: message = "ONC/RPC buffer underflow"; break; case RPC_WRONGMESSAGE: message = "wrong ONC/RPC message type received"; break; case RPC_CANNOTREGISTER: message = "cannot register ONC/RPC port with local portmap"; break; case RPC_SUCCESS: default: break; } } /** * Returns the error message string of this ONC/RPC object. * * @return The error message string of this OncRpcException * object if it was created either with an error message string or an * ONC/RPC error code. */ public String getMessage() { return message; } /** * Returns the error reason of this ONC/RPC exception object. * * @return The error reason of this OncRpcException object if * it was {@link #OncRpcException(int) created} with an error reason; or * RPC_FAILED if it was {@link #OncRpcException() created} * with no error reason. */ public int getReason() { return reason; } /** * The remote procedure call was carried out successfully. */ public static final int RPC_SUCCESS = 0; /** * The client can not encode the argments to be sent for the remote * procedure call. */ public static final int RPC_CANTENCODEARGS = 1; /** * The client can not decode the result from the remote procedure call. */ public static final int RPC_CANTDECODERES = 2; /** * Encoded information can not be sent. */ public static final int RPC_CANTSEND = 3; /** * Information to be decoded can not be received. */ public static final int RPC_CANTRECV = 4; /** * The remote procedure call timed out. */ public static final int RPC_TIMEDOUT = 5; /** * ONC/RPC versions of server and client are not compatible. */ public static final int RPC_VERSMISMATCH = 6; /** * The ONC/RPC server did not accept the authentication sent by the * client. Bad girl/guy! */ public static final int RPC_AUTHERROR = 7; /** * The ONC/RPC server does not support this particular program. */ public static final int RPC_PROGUNAVAIL = 8; /** * The ONC/RPC server does not support this particular version of the * program. */ public static final int RPC_PROGVERSMISMATCH = 9; /** * The given procedure is not available at the ONC/RPC server. */ public static final int RPC_PROCUNAVAIL = 10; /** * The ONC/RPC server could not decode the arguments sent within the * call message. */ public static final int RPC_CANTDECODEARGS = 11; /** * The ONC/RPC server encountered a system error and thus was not able * to carry out the requested remote function call successfully. */ public static final int RPC_SYSTEMERROR = 12; /** * The caller specified an unknown/unsupported IP protocol. Currently, * only {@link OncRpcProtocols#ONCRPC_TCP} and * {@link OncRpcProtocols#ONCRPC_UDP} are supported. */ public static final int RPC_UNKNOWNPROTO = 17; /** * The portmapper could not be contacted at the given host. */ public static final int RPC_PMAPFAILURE = 14; /** * The requested program is not registered with the given host. */ public static final int RPC_PROGNOTREGISTERED = 15; /** * A generic ONC/RPC exception occured. Shit happens... */ public static final int RPC_FAILED = 16; /** * A buffer overflow occured with an encoding XDR stream. This happens * if you use UDP-based (datagram-based) XDR streams and you try to encode * more data than can fit into the sending buffers. */ public static final int RPC_BUFFEROVERFLOW = 42; /** * A buffer underflow occured with an decoding XDR stream. This happens * if you try to decode more data than was sent by the other communication * partner. */ public static final int RPC_BUFFERUNDERFLOW = 43; /** * Either a ONC/RPC server or client received the wrong type of ONC/RPC * message when waiting for a request or reply. Currently, only the * decoding methods of the classes {@link OncRpcCallMessage} and * {@link OncRpcReplyMessage} throw exceptions with this reason. */ public static final int RPC_WRONGMESSAGE = 44; /** * Indicates that a server could not register a transport with the * ONC/RPC port mapper. */ public static final int RPC_CANNOTREGISTER = 45; /** * Specific detail (reason) about this OncRpcException, * like the ONC/RPC error code, as defined by the RPC_xxx * constants of this interface. * * @serial */ private int reason; /** * Specific detail about this OncRpcException, like a * detailed error message. * * @serial */ private String message; } // End of OncRpcException.java remotetea-1.0.7/src/org/acplt/oncrpc/OncRpcGetPortResult.java0000644005374700003410000000517607716406376025351 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/OncRpcGetPortResult.java,v 1.1.1.1 2003/08/13 12:03:41 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; import java.io.IOException; /** * The OncRpcGetPortResult class represents the result from * a PMAP_GETPORT remote procedure call to the ONC/RPC portmapper. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:41 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class OncRpcGetPortResult implements XdrAble { /** * The port number of the ONC/RPC in question. This is the only interesting * piece of information in this class. Go live with it, you don't have * alternatives. */ public int port; /** * Default constructor for initializing an OncRpcGetPortParams * result object. It sets the port member to a useless value. */ public OncRpcGetPortResult() { port = 0; } /** * Encodes -- that is: serializes -- an OncRpcGetPortParams * object into a XDR stream. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException { xdr.xdrEncodeInt(port); } /** * Decodes -- that is: deserializes -- an OncRpcGetPortParams * object from a XDR stream. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException { port = xdr.xdrDecodeInt(); } } // End of OncRpcGetPortResult.java remotetea-1.0.7/src/org/acplt/oncrpc/OncRpcHttpClient.java0000644005374700003410000006746310335176244024640 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/OncRpcHttpClient.java,v 1.5 2005/11/11 21:18:43 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; import java.io.IOException; import java.io.InterruptedIOException; import org.acplt.oncrpc.web.*; /** * ONC/RPC client which communicates with ONC/RPC servers over the network * using the ISO/OSI level 7 application protocol HTTP as a tunnel. * *

Please note that currently no standard exists about how to tunnel * XDR data over HTTP connections. There are a few solutions out there, but * they are more or less incompatible due to the lack of an RFC. So I'm now * adding yet another proprietary solution. * *

The protocol which is used here is rather simple and tries to be * compatible with as much firewall systems as possible. For this to achieve, * both the ONC/RPC calls as well as their replies are first base64 encoded, * before they are sent through the tunnel. This way, calls and replies appear * to be ordinary text documents of mime type "text/plain". * *

Calls will appear to be something like this, carrying redirection * information. Note that we do not include ONC/RPC call information in the * header section, as this is already included in the ONC/RPC call itself. * So including it in the header would just make it easier to play games * with the header. *

 *     CALL host name:port protocol TEA/1<CR><LF>
 *     B0D0EADSDEADBEEF...<CR><LF>
 *     ...<CR><LF>
 *     DEADBE==<CR><LF>
 * 
* *

Replies do not carry the redirection head, but only the base64 encoded * data of the ONC/RPC reply: *

 *     B0D0EADSDEADBEEF...<CR><LF>
 *     ...<CR><LF>
 *     DEADBE==<CR><LF>
 * 
* *

The decoding from the base64 encoded data is carried out by the * {@link XdrHttpDecodingStream} class. * *

I'm not using eecks-emm-ell on purpose (net yet). While it is surely * fun to play with and it has its merits, just to create yet another RPC * tunnel parsing XML is still too large an overhead to accept. Despite cynics * pointing out that the Internet is already that slow so that XML overhead * will not be visible at all, I nevertheless disagree. On the other hand, * XML would be really fine to be misused for yet another proprietary and * misguided ASCII, pardon UTF-8, data format... *

 *     <?xml version="1.0"?>
 *     <!DOCTYPE oncrpc-call SYSTEM "oncrpc-call.dtd">
 *     <oncrpc-call server="foo.bar.com" protocol="tcp">
 *         B0D0EADSDEADBEEF...<CR><LF>
 *         ...<CR><LF>
 *         DEADBE==<CR><LF>
 *     </oncrpc-call>
 * 
* *

The answer then could be represented as follows: *

 *     <?xml version="1.0"?>
 *     <!DOCTYPE oncrpc-reply SYSTEM "oncrpc-reply.dtd">
 *     <oncrpc-reply>
 *         B0D0EADSDEADBEEF...<CR><LF>
 *         ...<CR><LF>
 *         DEADBE==<CR><LF>
 *     </oncrpc-reply>
 * 
* *

So it should be fairly easy to switch over to XML if someone will * insist on it. Reminds me of my Xmas lecture about "Internet Technologies -- * Sacred Land of the Automation Industry?"... * * @version $Revision: 1.5 $ $Date: 2005/11/11 21:18:43 $ $State: Exp $ $Locker: $ * @author Harald Albrecht * * @see XdrHttpDecodingStream * @see org.acplt.oncrpc.web.HttpClientConnection */ public class OncRpcHttpClient extends OncRpcClient { /** * Constructs a new OncRpcHttpClient object, which connects * to the ONC/RPC server at host for calling remote procedures * of the given { program, version }. At the other end of the HTTP tunnel, * TCP/IP is used to call the ONC/RPC server. * *

Note that the HTTP connection is not build before the first ONC/RPC * call is done through the {@link #call} method. The HTTP client tries to * keep the connection alive but reconnects if necessary. Nevertheless, as * it signals all failures, the caller has to handle reconnect situations * -- but this is easy to achieve. * * @param hostname The DNS name of the host where the ONC/RPC server * resides. * @param cgiHandlerPath The path to the CGI Handler which will redirect * ONC/RPC calls to the particular ONC/RPC servers. * @param oncrpcHostname The DNS name of the ONC/RPC server to contact. * @param program Program number of the ONC/RPC server to call. * @param version Program version number. * @param port The port number where the ONC/RPC server can be contacted. * If 0, then the other end of the HTTP tunnel will try to * ask the portmapper at host for the port number. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public OncRpcHttpClient(String hostname, String cgiHandlerPath, String oncrpcHostname, int program, int version, int port) throws OncRpcException, IOException { this(hostname, HttpClientConnection.HTTP_DEFAULTPORT, cgiHandlerPath, oncrpcHostname, program, version, port, OncRpcProtocols.ONCRPC_TCP); } /** * Constructs a new OncRpcHttpClient object, which connects * to the ONC/RPC server at host for calling remote procedures * of the given { program, version }. * *

Note that the HTTP connection is not build before the first ONC/RPC * call is done through the {@link #call} method. The HTTP client tries to * keep the connection alive but reconnects if necessary. Nevertheless, as * it signals all failures, the caller has to handle reconnect situations * -- but this is easy to achieve. * * @param hostname The DNS name of the host where the ONC/RPC server * resides. * @param cgiHandlerPath The path to the CGI Handler which will redirect * ONC/RPC calls to the particular ONC/RPC servers. * @param oncrpcHostname The DNS name of the ONC/RPC server to contact. * @param program Program number of the ONC/RPC server to call. * @param version Program version number. * @param port The port number where the ONC/RPC server can be contacted. * If 0, then the other end of the HTTP tunnel will try to * ask the portmapper at host for the port number. * @param protocol Transport protocol to be used by the other end of * the tunnel to call the ONC/RPC server. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public OncRpcHttpClient(String hostname, String cgiHandlerPath, String oncrpcHostname, int program, int version, int port, int protocol) throws OncRpcException, IOException { this(hostname, HttpClientConnection.HTTP_DEFAULTPORT, cgiHandlerPath, oncrpcHostname, program, version, port, protocol); } /** * Constructs a new OncRpcHttpClient object, which connects * to the ONC/RPC server at host for calling remote procedures * of the given { program, version }. * *

Note that the HTTP connection is not build before the first ONC/RPC * call is done through the {@link #call} method. The HTTP client tries to * keep the connection alive but reconnects if necessary. Nevertheless, as * it signals all failures, the caller has to handle reconnect situations * -- but this is easy to achieve. * * @param hostname The DNS name of the host where the ONC/RPC server * resides. * @param httpPort The port number where the HTTP server is to be * contacted. * @param cgiHandlerPath The path to the CGI Handler which will redirect * ONC/RPC calls to the particular ONC/RPC servers. * @param oncrpcHostname The DNS name of the ONC/RPC server to contact. * @param program Program number of the ONC/RPC server to call. * @param version Program version number. * @param port The port number where the ONC/RPC server can be contacted. * If 0, then the other end of the HTTP tunnel will try to * ask the portmapper at host for the port number. * @param protocol Transport protocol to be used by the other end of * the tunnel to call the ONC/RPC server. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public OncRpcHttpClient(String hostname, int httpPort, String cgiHandlerPath, String oncrpcHostname, int program, int version, int port, int protocol) throws OncRpcException, IOException { // // Construct the inherited part of our object. This will also try to // lookup the port of the desired ONC/RPC server, if no port number // was specified (port = 0). // // PLEASE NOTE: // - We supply a null InetAddress to our parent class, as we do not // make use of an InetAddress at all but rather juggle with the // plain host name. This is necessary in order to support virtual // hosting of web servers, and the HTTP client object needs to // know to which particular web server it contacts, despite of // the server's internet address. // - The parent class will not try to look up the port address // as we signal that we are going to use HTTP tunneling. // super(null, program, version, -1, OncRpcProtocols.ONCRPC_HTTP); this.httpPort = httpPort; this.cgiHandlerPath = cgiHandlerPath; this.oncrpcHostname = oncrpcHostname; this.oncrpcProtocol = protocol; this.port = port; // // We need to work with the host name instead of its address // so we can support virtual web hosting, where multiple DNS names // map to the same IP address, and the client sends the host name // it wants to contact within the HTTP requests. // this.hostname = hostname; httpClient = new HttpClientConnection(hostname, httpPort); // // Create the necessary encoding and decoding streams, so we can // communicate at all. // FIXME: write specialized dynamically buffered encoding stream! sendingXdr = new XdrBufferEncodingStream(8192); receivingXdr = new XdrHttpDecodingStream(httpClient); } /** * Close the connection to an ONC/RPC server and free all network-related * resources. Well -- at least hope, that the Java VM will sometimes free * some resources. Sigh. * * @throws OncRpcException if an ONC/RPC error occurs. */ public void close() throws OncRpcException { if ( httpClient != null ) { httpClient.close(); httpClient = null; } // // Close both XDR streams individually to avoid missing the second // one when the first one throws an exception. // if ( sendingXdr != null ) { try { sendingXdr.close(); } catch ( IOException e ) { } finally { sendingXdr = null; } } if ( receivingXdr != null ) { try { receivingXdr.close(); } catch ( IOException e ) { } finally { receivingXdr = null; } } } /** * Calls a remote procedure on an ONC/RPC server. * *

FIXME: timeout control? * * @param procedureNumber Procedure number of the procedure to call. * @param versionNumber Protocol version number. * @param params The parameters of the procedure to call, contained * in an object which implements the {@link XdrAble} interface. * @param result The object receiving the result of the procedure call. * * @throws OncRpcException if an ONC/RPC error occurs. */ public synchronized void call(int procedureNumber, int versionNumber, XdrAble params, XdrAble result) throws OncRpcException { int responseCode; Refresh: for ( int refreshesLeft = 1; refreshesLeft >= 0; --refreshesLeft ) { // // First, build the ONC/RPC call header. Then put the sending // stream into a known state and encode the parameters to be // sent. Finally tell the encoding stream to send all its data // to the server. Then wait for an answer, receive it and decode // it. So that's the bottom line of what we do right here. // nextXid(); OncRpcClientCallMessage callHeader = new OncRpcClientCallMessage(xid, program, versionNumber, procedureNumber, auth); OncRpcClientReplyMessage replyHeader = new OncRpcClientReplyMessage(auth); // // Send call message to server. If we receive an IOException, // then we'll throw the appropriate ONC/RPC (client) exception. // Note that we use a connected stream, so we don't need to // specify a destination when beginning serialization. // try { sendingXdr.beginEncoding(null, 0); callHeader.xdrEncode(sendingXdr); params.xdrEncode(sendingXdr); sendingXdr.endEncoding(); } catch ( IOException e ) { throw(new OncRpcException(OncRpcException.RPC_CANTSEND, e.getLocalizedMessage())); } // // Embedd the ONC/RPC call request within an unsuspiciously // looking ASCII page. Well, while I don't like this, it is // a good way to get access to a remote system from behind // a company's firewall, when the sysadmin disables free access // to that "domain of darkness" also known as "The Internet". // StringBuffer prefix = new StringBuffer(512); // // For calls we need to add some "bang information" (courtesty of // UU), so the other end of the HTTP tunnel can redirect the // ONC/RPC calls to the proper ONC/RPC server. Note that we // send only the bare minimum for routing. The missing information // is already contained in the ONC/RPC header following, so we // do not duplicate it. I want to avoid making it too easy to // spoof redirection information. // prefix.append("CALL "); // tunnel method prefix.append(oncrpcHostname); // host to contact if ( port > 0 ) { // optional port number prefix.append(":"); prefix.append(port); } prefix.append(" "); prefix.append(oncrpcProtocol); // transport protocol prefix.append(" "); prefix.append(HttpTunnelConstants.TUNNEL_PROTO_ID); prefix.append("\r\n"); // // Terminate header section. // prefix.append("\r\n"); // // Ccalculate the length of the full content, including the // ASCII-ized ONC/RPC call record. // int contentLength = sendingXdr.getXdrLength(); int lineCount = (contentLength + (HttpTunnelConstants.BYTES_PER_LINE - 1)) / HttpTunnelConstants.BYTES_PER_LINE; int realLength = prefix.length() + ((contentLength + 2) / 3) * 4 + lineCount * 2 ; // FIXME byte [] xdrData = sendingXdr.getXdrData(); // // We are now ready to start the POST request, which will carry // our ONC/RPC call record to the HTTP server and beyond it to // the destination ONC/RPC server. // try { httpClient.beginPostRequest(cgiHandlerPath, "text/plain", realLength); // // First, send the HTTP tunnel ONC/RPC header. This header // contains "routing information", so that the receiver at // the other end of the HTTP tunnel can redirect the call // to the appropriate ONC/RPC server. // String s = prefix.toString(); httpClient.writeContentBytes(s.getBytes(), 0, s.length()); // // Next, encode the binary XDR data. This is done in blocks, // speeding up things a little bit by avoiding making too // many single calls into the output stream (although buffered). // byte [] lines = new byte[HttpTunnelConstants.ENCODED_BYTES_PER_LINE_CRLF * HttpTunnelConstants.LINES_PER_BLOCK]; int xdrOffset = 0; int offset = 0; while ( contentLength >= HttpTunnelConstants.BYTES_PER_LINE ) { if ( offset >= (HttpTunnelConstants.ENCODED_BYTES_PER_LINE_CRLF * HttpTunnelConstants.LINES_PER_BLOCK) ) { httpClient.writeContentBytes(lines, 0, offset); offset = 0; } offset += Base64.encode(xdrData, xdrOffset, HttpTunnelConstants.BYTES_PER_LINE, lines, offset); lines[offset++] = 13; lines[offset++] = 10; xdrOffset += HttpTunnelConstants.BYTES_PER_LINE; contentLength -= HttpTunnelConstants.BYTES_PER_LINE; } // // If there's still data left over which did not fill a // complete line then generate the last line and flush it. // if ( contentLength > 0 ) { if ( offset >= (HttpTunnelConstants.ENCODED_BYTES_PER_LINE_CRLF * HttpTunnelConstants.LINES_PER_BLOCK) ) { httpClient.writeContentBytes(lines, 0, offset); offset = 0; } offset += Base64.encode(xdrData, xdrOffset, contentLength, lines, offset); lines[offset++] = 13; lines[offset++] = 10; } if ( offset > 0 ) { httpClient.writeContentBytes(lines, 0, offset); } // // Indicate the end of the request, so that all data gets sent // to the HTTP server for processing. // httpClient.endPostRequest(); } catch ( IOException e ) { throw(new OncRpcException(OncRpcException.RPC_CANTSEND, e.getLocalizedMessage())); } // // Receive reply message from server -- at least try to do so... // IMPORTANT NOTE: // - we do not support batched calls through HTTP tunnels, as then // an additional record layer would have been to be put between // the HTTP post and the base64 encoding layer. // try { // // In contrast to TCP/IP and UDP/IP-based transports, we // can expect the tunnel to be responding with the matching // ONC/RPC reply. If it does not, there's no way of waiting // for another reply -- because we only have the strict // "one call, one reply" interaction scheme at our hands. // Nevertheless: we still check for a matching reply, but can // not wait for another one suddenly popping up from the // HTTP tunnel. // // // First, pull off the reply message header of the // XDR stream. In case we also received a verifier // from the server and this verifier was invalid, broken // or tampered with, we will get an // OncRpcAuthenticationException right here, which will // propagate up to the caller. If the server reported // an authentication problem itself, then this will // be handled as any other rejected ONC/RPC call. // // While that sounds easy, it is hard work in the face // of decoding the Base64 encoded data. But we have the // decoding HTTP/XDR stream to delegate all this dirty // work to... // receivingXdr.beginDecoding(); // // Make sure that we got an okay from the web server and // some data. // responseCode = httpClient.getResponseCode(); if ( (responseCode < 200) || (responseCode >= 300) ) { // FIXME throw(new OncRpcException(OncRpcException.RPC_FAILED, "HTTP tunnel response error " + responseCode)); } // // Pull off the RPC header from the HTTP stream. // replyHeader.xdrDecode(receivingXdr); // // Only deserialize the result, if the reply matches the // call. Otherwise skip this record. // if ( replyHeader.messageId != callHeader.messageId ) { receivingXdr.endDecoding(); // FIXME: CHECKME exception code throw(new OncRpcException(OncRpcException.RPC_WRONGMESSAGE)); } // // Make sure that the call was accepted. In case of unsuccessful // calls, throw an exception, if it's not an authentication // exception. In that case try to refresh the credential first. // if ( !replyHeader.successfullyAccepted() ) { receivingXdr.endDecoding(); // // Check whether there was an authentication // problem. In this case first try to refresh the // credentials. // if ( (refreshesLeft > 0) && (replyHeader.replyStatus == OncRpcReplyStatus.ONCRPC_MSG_DENIED) && (replyHeader.rejectStatus == OncRpcRejectStatus.ONCRPC_AUTH_ERROR) && (auth.canRefreshCred()) ) { continue Refresh; } // // Nope. No chance. This gets tough. // throw(replyHeader.newException()); } result.xdrDecode(receivingXdr); // // Free pending resources of buffer and exit the call loop, // returning the reply to the caller through the result // object. // receivingXdr.endDecoding(); return; } catch ( InterruptedIOException e ) { // // In case our time run out, we throw an exception. // throw(new OncRpcTimeoutException()); } catch ( IOException e ) { // // Argh. Trouble with the transport. Seems like we can't // receive data. Gosh. Go away! // throw(new OncRpcException(OncRpcException.RPC_CANTRECV, e.getLocalizedMessage())); } } // for ( refreshesLeft ) } /** * Set the character encoding for (de-)serializing strings. * * @param characterEncoding the encoding to use for (de-)serializing strings. * If null, the system's default encoding is to be used. */ public void setCharacterEncoding(String characterEncoding) { sendingXdr.setCharacterEncoding(characterEncoding); receivingXdr.setCharacterEncoding(characterEncoding); } /** * Get the character encoding for (de-)serializing strings. * * @return the encoding currently used for (de-)serializing strings. * If null, then the system's default encoding is used. */ public String getCharacterEncoding() { return receivingXdr.getCharacterEncoding(); } /** * Returns the host name of the HTTP server we are connected to. * * @return host name. */ public String getHostname() { return hostname; } /** * Returns the port of the HTTP server we are connected to. * * @return port number. */ public int getHttpPort() { return httpPort; } /** * DNS name of host where to contact HTTP server. Note that we can not * use an InetAddress here as we have to support virtual * hosting, where several DNS names share the same IP address. */ private String hostname; /** * Port number where the HTTP server can be contacted. */ private int httpPort; /** * Path of cgi program redirecting ONC/RPC calls to the appropriate * ONC/RPC servers. */ private String cgiHandlerPath; /** * DNS name of ONC/RPC server receiving the calls. */ private String oncrpcHostname; /** * Transport protocol to be used by the other end of the tunnel to * contact the ONC/RPC server. */ private int oncrpcProtocol; /** * The HTTP client responsible for handling the HTTP connection. It is * a classic example of delegation, isn't it? */ private HttpClientConnection httpClient; /** * FIXME: use the right encoding stream! * XDR encoding stream used for sending requests via UDP/IP to an ONC/RPC * server. */ private XdrBufferEncodingStream sendingXdr; /** * XDR decoding stream used when receiving replies via an HTTP tunnel * from an ONC/RPC server. */ private XdrHttpDecodingStream receivingXdr; } // End of OncRpcHttpClient.java remotetea-1.0.7/src/org/acplt/oncrpc/OncRpcMessage.java0000644005374700003410000000455607716622226024145 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/OncRpcMessage.java,v 1.2 2003/08/14 07:56:37 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; /** * The OncRpcMessage class is an abstract superclass for all * the message types ONC/RPC defines (well, an overwhelming count of two). * The only things common to all ONC/RPC messages are a message identifier * and the message type. All other things do not come in until derived * classes are introduced. * * @version $Revision: 1.2 $ $Date: 2003/08/14 07:56:37 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public abstract class OncRpcMessage { /** * Constructs a new OncRpcMessage object with default * values: a given message type and no particular message identifier. */ public OncRpcMessage(int messageId) { this.messageId = messageId; messageType = -1; } /** * The message id is used to identify matching ONC/RPC calls and * replies. This is typically choosen by the communication partner * sending a request. The matching reply then must have the same * message identifier, so the receiver can match calls and replies. */ public int messageId; /** * The kind of ONC/RPC message, which can be either a call or a * reply. Can be one of the constants defined in {@link OncRpcMessageType}. * * @see OncRpcMessageType */ public int messageType; } // End of OncRpcMessage.java remotetea-1.0.7/src/org/acplt/oncrpc/OncRpcMessageType.java0000644005374700003410000000414107716406376025003 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/OncRpcMessageType.java,v 1.1.1.1 2003/08/13 12:03:41 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; /** * A collection of constants used for ONC/RPC messages to identify the * type of message. Currently, ONC/RPC messages can be either calls or * replies. Calls are sent by ONC/RPC clients to servers to call a remote * procedure (for you "ohohpies" that can be translated into the buzzword * "method"). A server then will answer with a corresponding reply message * (but not in the case of batched calls). * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:41 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public interface OncRpcMessageType { /** * Identifies an ONC/RPC call. By a "call" a client request that a server * carries out a particular remote procedure. */ public static final int ONCRPC_CALL = 0; /** * Identifies an ONC/RPC reply. A server responds with a "reply" after * a client has sent a "call" for a particular remote procedure, sending * back the results of calling that procedure. */ public static final int ONCRPC_REPLY = 1; } // End of OncRpcMessageType.java remotetea-1.0.7/src/org/acplt/oncrpc/OncRpcPortmapClient.java0000644005374700003410000004177707716406376025356 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/OncRpcPortmapClient.java,v 1.1.1.1 2003/08/13 12:03:41 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000, 2001, 2002 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; import java.io.IOException; import java.net.InetAddress; /** * The class OncRpcPortmapClient is a specialized ONC/RPC client, * which can talk to the portmapper on a given host using the famous * UDP/IP datagram-oriented internet protocol. In addition, it is also possible * to contact portmappers using TCP/IP. For this, the constructor of the * OncRpcPortmapClient class also accepts a protocol parameter * ({@link OncRpcPortmapClient#OncRpcPortmapClient(InetAddress, int)}). * * Technically spoken, instances of OncRpcPortmapClient are proxy objects. * OncRpcPortmapClient objects currently speak protocol version * 2. The newer transport-independent protocol versions 3 and 4 are * not supported as the transport-independent ONC/RPC implementation is not * that widely in use due to the brain-damaged design of XTI. If you should * ever have programmed using XTI (transport independent interface) then you'll * know what I mean and probably agree with me. Otherwise, in case you find XTI * the best thing since the Win32 API, please implement the rpcbind protocol * versions 3 and 4 and give it to the community -- thank you. * *

Here are some simple examples of how to use the portmapper proxy object. * We first start with one of the most interesting operations, which can be * performed on portmappers, querying the port of a local or remote ONC/RPC * server. * *

To query the port number of an ONC/RPC server, we need to contact the * portmapper at the host machine where the server is running. The following * code snippet just contacts the local portmapper. try blocks * are ommited for brevity -- but remember that you almost allways need to catch * {@link OncRpcException} as well as IOException. * *

 * OncRpcPortmapClient portmap =
 *     new OncRpcPortmapClient(InetAddress.getByName("localhost"));
 * 
* *

With the portmapper proxy object in our hands we can now ask for the port * number of a particular ONC/RPC server. In this (ficious) example we ask for * the ONC/RPC program (server) number 0x49678 (by coincidence this * happens to be the program number of the ACPLT/KS * protocol). To ask for the port number of a given program number, use the * {@link OncRpcPortmapClient#getPort(int, int, int) getPort(...)} method. * *

 * int port;
 * try {
 *     port = portmap.getPort(0x49678, 1, OncRpcProtocols.ONCRPC_UDP);
 * } catch ( OncRpcProgramNotRegisteredException e ) {
 *     System.out.println("ONC/RPC program server not found");
 *     System.exit(0);
 * } catch ( OncRpcException e ) {
 *     System.out.println("Could not contact portmapper:");
 *     e.printStackTrace(System.out);
 *     System.exit(0);
 * }
 * System.out.println("Program available at port " + port);
 * 
* *

In the call to {@link OncRpcPortmapClient#getPort(int, int, int) getPort(...)}, the * first parameter specifies the ONC/RPC program number, the secondm parameter * specifies the program's version number, and the third parameter specifies * the IP protocol to use when issueing ONC/RPC calls. Currently, only * {@link OncRpcProtocols#ONCRPC_UDP} and {@link OncRpcProtocols#ONCRPC_TCP} are * supported. But who needs other protocols anyway?! * *

In case {@link OncRpcPortmapClient#getPort(int, int, int) getPort(...)} succeeds, it * returns the number of the port where the appropriate ONC/RPC server waits * for incoming ONC/RPC calls. If the ONC/RPC program is not registered with * the particular ONC/RPC portmapper, an {@link OncRpcProgramNotRegisteredException} * is thrown (which is a subclass of {@link OncRpcException} with a detail * reason of {@link OncRpcException#RPC_PROGNOTREGISTERED}. * *

A second typical example of how to use the portmapper is retrieving a * list of the currently registered servers. We use the * {@link OncRpcPortmapClient#listServers} method for this purpose in the * following example, and print the list we got. * *

 * OncRpcServerIdent [] list = null;
 * try {
 *     list = portmap.listServers();
 * } catch ( OncRpcException e ) {
 *     e.printStackTrace(System.out);
 *     System.exit(20);
 * }
 * for ( int i = 0; i < list.length; ++i ) {
 *     System.out.println(list[i].program + " " + list[i].version + " "
 *                        + list[i].protocol + " " + list[i].port);
 * }
 * 
* *

When you do not need the client proxy object any longer, you should * return the resources it occupies to the system. Use the {@link #close} * method for this. * *

 * portmap.close();
 * portmap = null; // Hint to the garbage (wo)man
 * 
* *

For another code example, please consult * src/tests/org/acplt/oncrpc/PortmapGetPortTest.java. * * @see OncRpcClient * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:41 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class OncRpcPortmapClient { /** * Constructs and initializes an ONC/RPC client object, which can * communicate with the portmapper at the specified host using the * UDP/IP datagram-oriented internet protocol. * * @param host Host where to contact the portmapper. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public OncRpcPortmapClient(InetAddress host) throws OncRpcException, IOException { this(host, OncRpcProtocols.ONCRPC_UDP, 0); } /** * Constructs and initializes an ONC/RPC client object, which can * communicate with the portmapper at the given host using the * speicified protocol. * * @param host Host where to contact the portmapper. * @param protocol Protocol to use for contacting the portmapper. This * can be either OncRpcProtocols.ONCRPC_UDP or * OncRpcProtocols.ONCRPC_TCP (HTTP is currently * not supported). * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public OncRpcPortmapClient(InetAddress host, int protocol) throws OncRpcException, IOException { this(host, protocol, -1); } /** * Constructs and initializes an ONC/RPC client object, which can * communicate with the portmapper at the given host using the * speicified protocol. * * @param host Host where to contact the portmapper. * @param protocol Protocol to use for contacting the portmapper. This * can be either OncRpcProtocols.ONCRPC_UDP or * OncRpcProtocols.ONCRPC_TCP (HTTP is currently * not supported). * @param timeout Timeout in milliseconds for connection operation. This * parameter applies only when using TCP/IP for talking to the * portmapper. A negative timeout indicates that the * implementation-specific timeout setting of the JVM and java.net * implementation should be used instead. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public OncRpcPortmapClient(InetAddress host, int protocol, int timeout) throws OncRpcException, IOException { switch ( protocol ) { case OncRpcProtocols.ONCRPC_UDP: portmapClient = new OncRpcUdpClient(host, PMAP_PROGRAM, PMAP_VERSION, PMAP_PORT); break; case OncRpcProtocols.ONCRPC_TCP: portmapClient = new OncRpcTcpClient(host, PMAP_PROGRAM, PMAP_VERSION, PMAP_PORT, 0, // default buff size timeout); break; default: throw(new OncRpcException(OncRpcException.RPC_UNKNOWNPROTO)); } } /** * Closes the connection to the portmapper. * * @throws OncRpcException */ public void close() throws OncRpcException { portmapClient.close(); } /** * Returns the client proxy object used for communicating with the * portmapper. * * @return portmap client proxy object (subclass of OncRpcClient). */ public OncRpcClient getOncRpcClient() { return portmapClient; } /** * Asks the portmapper this OncRpcPortmapClient object is * a proxy for, for the port number of a particular ONC/RPC server * identified by the information tuple {program number, program version, * protocol}. * * @param program Program number of the remote procedure call in question. * @param version Program version number. * @param protocol Protocol lateron used for communication with the * ONC/RPC server in question. This can be one of the protocols constants * defined in the {@link OncRpcProtocols} interface. * * @return port number of ONC/RPC server in question. * * @throws OncRpcException if the portmapper is not available (detail is * {@link OncRpcException#RPC_PMAPFAILURE}). * @throws OncRpcProgramNotRegisteredException if the requested program * is not available. */ public int getPort(int program, int version, int protocol) throws OncRpcException { // // Fill in the request parameters. Note that params.port is // not used. BTW - it is automatically initialized as 0 by the // constructor of the OncRpcServerParams class. // OncRpcServerIdent params = new OncRpcServerIdent(program, version, protocol, 0); OncRpcGetPortResult result = new OncRpcGetPortResult(); // // Try to contact the portmap process. If something goes "boing" // at this stage, then rethrow the exception as a generic portmap // failure exception. Otherwise, if the port number returned is // zero, then no appropriate server was found. In this case, // throw an exception, that the program requested could not be // found. // try { portmapClient.call(OncRpcPortmapServices.PMAP_GETPORT, params, result); } catch ( OncRpcException e ) { throw(new OncRpcException(OncRpcException.RPC_PMAPFAILURE)); } // // In case the program is not registered, throw an exception too. // if ( result.port == 0 ) { throw(new OncRpcProgramNotRegisteredException()); } return result.port; } /** * Register an ONC/RPC with the given program number, version and protocol * at the given port with the portmapper. * * @param program The number of the program to be registered. * @param version The version number of the program. * @param protocol The protocol spoken by the ONC/RPC server. Can be one * of the {@link OncRpcProtocols} constants. * @param port The port number where the ONC/RPC server can be reached. * * @return Indicates whether registration succeeded (true) or * was denied by the portmapper (false). * * @throws OncRpcException if the portmapper is not available (detail is * {@link OncRpcException#RPC_PMAPFAILURE}). */ public boolean setPort(int program, int version, int protocol, int port) throws OncRpcException { // // Fill in the request parameters. // OncRpcServerIdent params = new OncRpcServerIdent(program, version, protocol, port); XdrBoolean result = new XdrBoolean(false); // // Try to contact the portmap process. If something goes "boing" // at this stage, then rethrow the exception as a generic portmap // failure exception. // try { portmapClient.call(OncRpcPortmapServices.PMAP_SET, params, result); } catch ( OncRpcException e ) { throw(new OncRpcException(OncRpcException.RPC_PMAPFAILURE)); } return result.booleanValue(); } /** * Unregister an ONC/RPC with the given program number and version. The * portmapper will remove all entries with the same program number and * version, regardless of the protocol and port number. * * @param program The number of the program to be unregistered. * @param version The version number of the program. * * @return Indicates whether deregistration succeeded (true) * or was denied by the portmapper (false). * * @throws OncRpcException if the portmapper is not available (detail is * {@link OncRpcException#RPC_PMAPFAILURE}). */ public boolean unsetPort(int program, int version) throws OncRpcException { // // Fill in the request parameters. // OncRpcServerIdent params = new OncRpcServerIdent(program, version, 0, 0); XdrBoolean result = new XdrBoolean(false); // // Try to contact the portmap process. If something goes "boing" // at this stage, then rethrow the exception as a generic portmap // failure exception. // try { portmapClient.call(OncRpcPortmapServices.PMAP_UNSET, params, result); } catch ( OncRpcException e ) { throw(new OncRpcException(OncRpcException.RPC_PMAPFAILURE)); } return result.booleanValue(); } /** * Retrieves a list of all registered ONC/RPC servers at the same host * as the contacted portmapper. * * @return vector of server descriptions (see * class {@link OncRpcServerIdent}). * * @throws OncRpcException if the portmapper is not available (detail is * {@link OncRpcException#RPC_PMAPFAILURE}). */ public OncRpcServerIdent [] listServers() throws OncRpcException { // // Fill in the request parameters. // OncRpcDumpResult result = new OncRpcDumpResult(); // // Try to contact the portmap process. If something goes "boing" // at this stage, then rethrow the exception as a generic portmap // failure exception. // try { portmapClient.call(OncRpcPortmapServices.PMAP_DUMP, XdrVoid.XDR_VOID, result); } catch ( OncRpcException e ) { throw(new OncRpcException(OncRpcException.RPC_PMAPFAILURE)); } // // Copy the server ident object references from the Vector // into the vector (array). // OncRpcServerIdent [] info = new OncRpcServerIdent[result.servers.size()]; result.servers.copyInto(info); return info; } /** * Ping the portmapper (try to call procedure 0). * * @throws OncRpcException if the portmapper is not available (detail is * {@link OncRpcException#RPC_PMAPFAILURE}). */ public void ping() throws OncRpcException { try { portmapClient.call(0, XdrVoid.XDR_VOID, XdrVoid.XDR_VOID); } catch ( OncRpcException e ) { throw(new OncRpcException(OncRpcException.RPC_PMAPFAILURE)); } } /** * Well-known port where the portmap process can be found on Internet hosts. */ public static final int PMAP_PORT = 111; /** * Program number of the portmapper as defined in RFC 1832. */ public static final int PMAP_PROGRAM = 100000; /** * Program version number of the portmapper as defined in RFC 1832. */ public static final int PMAP_VERSION = 2; /** * The particular transport-specific ONC/RPC client object used for * talking to the portmapper. */ protected OncRpcClient portmapClient; } // public class OncRpcPortmapClient // End of OncRpcPortmapClient.java remotetea-1.0.7/src/org/acplt/oncrpc/OncRpcPortmapServices.java0000644005374700003410000000427607716406376025714 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/OncRpcPortmapServices.java,v 1.1.1.1 2003/08/13 12:03:41 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; /** * A collection of constants used for ONC/RPC messages to identify the * remote procedure calls offered by ONC/RPC portmappers. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:41 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public interface OncRpcPortmapServices { /** * Procedure number of portmap service to register an ONC/RPC server. */ public static final int PMAP_SET = 1; /** * Procedure number of portmap service to unregister an ONC/RPC server. */ public static final int PMAP_UNSET = 2; /** * Procedure number of portmap service to retrieve port number of * a particular ONC/RPC server. */ public static final int PMAP_GETPORT = 3; /** * Procedure number of portmap service to return information about all * currently registered ONC/RPC servers. */ public static final int PMAP_DUMP = 4; /** * Procedure number of portmap service to indirectly call a remote * procedure an ONC/RPC server through the ONC/RPC portmapper. */ public static final int PMAP_CALLIT = 5; } // End of OncRpcPortmapServices.java remotetea-1.0.7/src/org/acplt/oncrpc/OncRpcProgramNotRegisteredException.java0000644005374700003410000000370410335174422030527 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/OncRpcProgramNotRegisteredException.java,v 1.2 2005/11/11 21:03:30 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; /** * The class OncRpcProgramNotRegisteredException indicates * that the requests ONC/RPC program is not available at the specified host. * * @version $Revision: 1.2 $ $Date: 2005/11/11 21:03:30 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class OncRpcProgramNotRegisteredException extends OncRpcException { /** * Defines the serial version UID for OncRpcProgramNotRegisteredException. */ private static final long serialVersionUID = 5073156463000368270L; /** * Constructs an ONC/RPC program not registered exception with a detail * code of OncRpcException.RPC_PROGNOTREGISTERED and an * appropriate clear-text detail message. */ public OncRpcProgramNotRegisteredException() { super(OncRpcException.RPC_PROGNOTREGISTERED); } } // End of OncRpcProgramNotRegisteredException.java remotetea-1.0.7/src/org/acplt/oncrpc/OncRpcProtocols.java0000644005374700003410000000442007716406376024541 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/OncRpcProtocols.java,v 1.1.1.1 2003/08/13 12:03:41 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; /** * A collection of protocol constants used by the ONC/RPC package. Each * constant defines one of the possible transport protocols, which can be * used for communication between ONC/RPC clients and servers. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:41 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public interface OncRpcProtocols { /** * Use the UDP protocol of the IP (Internet Protocol) suite as the * network communication protocol for doing remote procedure calls. * This is the same as the IPPROTO_UDP definition from the famous * BSD socket API. */ public static final int ONCRPC_UDP = 17; /** * Use the TCP protocol of the IP (Internet Protocol) suite as the * network communication protocol for doing remote procedure calls. * This is the same as the IPPROTO_TCP definition from the famous * BSD socket API. */ public static final int ONCRPC_TCP = 6; /** * Use the HTTP application protocol for tunneling ONC remote procedure * calls. This is definetely not similiar to any definition in the * famous BSD socket API. */ public static final int ONCRPC_HTTP = -42; } // End of OncRpcProtocols.java remotetea-1.0.7/src/org/acplt/oncrpc/OncRpcRejectStatus.java0000644005374700003410000000353707716406376025205 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/OncRpcRejectStatus.java,v 1.1.1.1 2003/08/13 12:03:41 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; /** * A collection of constants used to describe why a remote procedure call * message was rejected. This constants are used in {@link OncRpcReplyMessage} * objects, which represent rejected messages if their * {@link OncRpcReplyMessage#replyStatus} field has the value * {@link OncRpcReplyStatus#ONCRPC_MSG_DENIED}. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:41 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public interface OncRpcRejectStatus { /** * Wrong ONC/RPC protocol version used in call (it needs to be version 2). */ public static final int ONCRPC_RPC_MISMATCH = 0; /** * The remote ONC/RPC server could not authenticate the caller. */ public static final int ONCRPC_AUTH_ERROR = 1; } // End of OncRpcRejectStatus.java remotetea-1.0.7/src/org/acplt/oncrpc/OncRpcReplyMessage.java0000644005374700003410000001366607716622254025164 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/OncRpcReplyMessage.java,v 1.2 2003/08/14 07:56:59 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; /** * The OncRpcReplyMessage class represents an ONC/RPC reply * message as defined by ONC/RPC in RFC 1831. Such messages are sent back by * ONC/RPC to servers to clients and contain (in case of real success) the * result of a remote procedure call. * *

The decision to define only one single class for the accepted and * rejected replies was driven by the motivation not to use polymorphism * and thus have to upcast and downcast references all the time. * *

The derived classes are only provided for convinience on the server * side. * * @version $Revision: 1.2 $ $Date: 2003/08/14 07:56:59 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public abstract class OncRpcReplyMessage extends OncRpcMessage { /** * The reply status of the reply message. This can be either * {@link OncRpcReplyStatus#ONCRPC_MSG_ACCEPTED} or * {@link OncRpcReplyStatus#ONCRPC_MSG_DENIED}. Depending on the value * of this field, other fields of an instance of * OncRpcReplyMessage become important. * *

The decision to define only one single class for the accepted and * rejected replies was driven by the motivation not to use polymorphism * and thus have to upcast and downcast references all the time. */ public int replyStatus; /** * Acceptance status in case this reply was sent in response to an * accepted call ({@link OncRpcReplyStatus#ONCRPC_MSG_ACCEPTED}). This * field can take any of the values defined in the * {@link OncRpcAcceptStatus} interface. * *

Note that even for accepted calls that only in the case of * {@link OncRpcAcceptStatus#ONCRPC_SUCCESS} result data will follow * the reply message header. */ public int acceptStatus; /** * Rejectance status in case this reply sent in response to a * rejected call ({@link OncRpcReplyStatus#ONCRPC_MSG_DENIED}). This * field can take any of the values defined in the * {@link OncRpcRejectStatus} interface. */ public int rejectStatus; /** * Lowest supported version in case of * {@link OncRpcRejectStatus#ONCRPC_RPC_MISMATCH} and * {@link OncRpcAcceptStatus#ONCRPC_PROG_MISMATCH}. */ public int lowVersion; /** * Highest supported version in case of * {@link OncRpcRejectStatus#ONCRPC_RPC_MISMATCH} and * {@link OncRpcAcceptStatus#ONCRPC_PROG_MISMATCH}. */ public int highVersion; /** * Contains the reason for authentification failure in the case * of {@link OncRpcRejectStatus#ONCRPC_AUTH_ERROR}. */ public int authStatus; /** * Initializes a new OncRpcReplyMessage object to represent * an invalid state. This default constructor should only be used if in the * next step the real state of the reply message is immediately decoded * from a XDR stream. */ public OncRpcReplyMessage() { super(0); messageType = OncRpcMessageType.ONCRPC_REPLY; replyStatus = OncRpcReplyStatus.ONCRPC_MSG_ACCEPTED; acceptStatus = OncRpcAcceptStatus.ONCRPC_SYSTEM_ERR; rejectStatus = UNUSED_PARAMETER; lowVersion = 0; highVersion = 0; authStatus = UNUSED_PARAMETER; } /** * Initializes a new OncRpcReplyMessage object and initializes * its complete state from the given parameters. * *

Note that depending on the reply, acceptance and rejectance status * some parameters are unused and can be specified as * UNUSED_PARAMETER. * * @param call The ONC/RPC call this reply message corresponds to. * @param replyStatus The reply status (see {@link OncRpcReplyStatus}). * @param acceptStatus The acceptance state (see {@link OncRpcAcceptStatus}). * @param rejectStatus The rejectance state (see {@link OncRpcRejectStatus}). * @param lowVersion lowest supported version. * @param highVersion highest supported version. * @param authStatus The autentication state (see {@link OncRpcAuthStatus}). */ public OncRpcReplyMessage(OncRpcCallMessage call, int replyStatus, int acceptStatus, int rejectStatus, int lowVersion, int highVersion, int authStatus) { super(call.messageId); messageType = OncRpcMessageType.ONCRPC_REPLY; this.replyStatus = replyStatus; this.acceptStatus = acceptStatus; this.rejectStatus = rejectStatus; this.lowVersion = lowVersion; this.highVersion = highVersion; this.authStatus = authStatus; } /** * Dummy, which can be used to identify unused parameters when constructing * OncRpcReplyMessage objects. */ public static final int UNUSED_PARAMETER = 0; } // End of OncRpcReplyMessage.java remotetea-1.0.7/src/org/acplt/oncrpc/OncRpcReplyStatus.java0000644005374700003410000000323707716406376025061 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/OncRpcReplyStatus.java,v 1.1.1.1 2003/08/13 12:03:41 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; /** * A collection of constants used to identify the (overall) status of an * ONC/RPC reply message. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:41 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public interface OncRpcReplyStatus { /** * Reply status identifying that the corresponding message call was * accepted. */ public static final int ONCRPC_MSG_ACCEPTED = 0; /** * Reply status identifying that the corresponding message call was * denied. */ public static final int ONCRPC_MSG_DENIED = 1; } // End of OncRpcReplyStatus.java remotetea-1.0.7/src/org/acplt/oncrpc/OncRpcServerIdent.java0000644005374700003410000001027407716406376025013 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/OncRpcServerIdent.java,v 1.1.1.1 2003/08/13 12:03:41 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; import java.io.IOException; /** * The class OncRpcServerIdent represents an tuple * { program, version, protocol, port} uniquely identifying a particular * ONC/RPC server on a given host. This information is used, for instance, * as the ONC/RPC portmap PMAP_GETPORT call parameters. * *

An OncRpcServerIdent can be directly serialized into an * encoding XDR stream (that is more political correct than "flushed down * the toilet"). * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:41 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class OncRpcServerIdent implements XdrAble { /** * The program number of the ONC/RPC server in question. */ public int program; /** * The program version number of the ONC/RPC server in question. */ public int version; /** * The protocol used for communicating with the ONC/RPC server in question. * This can be one of the constants ("public final static int") defined * in the {@link OncRpcProtocols} interface. */ public int protocol; /** * The port number of the ONC/RPC server in question. */ public int port; /** * Constuct an OncRpcServerIdent object with senseless * default values for the requested program number, version number, * protocol type and port number. */ public OncRpcServerIdent() { program = 0; version = 0; protocol = 0; port = 0; } /** * Constructs an OncRpcServerIdent object with the * requested program number, version number, protocol type and port * number. */ public OncRpcServerIdent(int program, int version, int protocol, int port) { this.program = program; this.version = version; this.protocol = protocol; this.port = port; } /** * Constructs an OncRpcServerIdent object and restores * its state from the given XDR stream. */ public OncRpcServerIdent(XdrDecodingStream xdr) throws OncRpcException, IOException { xdrDecode(xdr); } /** * Encodes -- that is: serializes -- an OncRpcServerIdent object * into a XDR stream. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException { xdr.xdrEncodeInt(program); xdr.xdrEncodeInt(version); xdr.xdrEncodeInt(protocol); xdr.xdrEncodeInt(port); } /** * Decodes -- that is: deserializes -- an OncRpcServerIdent object * from a XDR stream. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException { program = xdr.xdrDecodeInt(); version = xdr.xdrDecodeInt(); protocol = xdr.xdrDecodeInt(); port = xdr.xdrDecodeInt(); } } // End of OncRpcServerIdent.java remotetea-1.0.7/src/org/acplt/oncrpc/OncRpcTcpClient.java0000644005374700003410000005556010335174516024442 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/OncRpcTcpClient.java,v 1.5 2005/11/11 21:04:30 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; import java.io.IOException; import java.io.InterruptedIOException; import java.net.InetAddress; import java.net.Socket; /** * ONC/RPC client which communicates with ONC/RPC servers over the network * using the stream-oriented protocol TCP/IP. * * @version $Revision: 1.5 $ $Date: 2005/11/11 21:04:30 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class OncRpcTcpClient extends OncRpcClient { /** * Constructs a new OncRpcTcpClient object, which connects * to the ONC/RPC server at host for calling remote procedures * of the given { program, version }. * *

Note that the construction of an OncRpcTcpClient * object will result in communication with the portmap process at * host. * * @param host The host where the ONC/RPC server resides. * @param program Program number of the ONC/RPC server to call. * @param version Program version number. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public OncRpcTcpClient(InetAddress host, int program, int version) throws OncRpcException, IOException { this(host, program, version, 0, 0); } /** * Constructs a new OncRpcTcpClient object, which connects * to the ONC/RPC server at host for calling remote procedures * of the given { program, version }. * *

Note that the construction of an OncRpcTcpClient * object will result in communication with the portmap process at * host if port is 0. * * @param host The host where the ONC/RPC server resides. * @param program Program number of the ONC/RPC server to call. * @param version Program version number. * @param port The port number where the ONC/RPC server can be contacted. * If 0, then the OncRpcUdpClient object will * ask the portmapper at host for the port number. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public OncRpcTcpClient(InetAddress host, int program, int version, int port) throws OncRpcException, IOException { this(host, program, version, port, 0); } /** * Constructs a new OncRpcTcpClient object, which connects * to the ONC/RPC server at host for calling remote procedures * of the given { program, version }. * *

Note that the construction of an OncRpcTcpClient * object will result in communication with the portmap process at * host if port is 0. * * @param host The host where the ONC/RPC server resides. * @param program Program number of the ONC/RPC server to call. * @param version Program version number. * @param port The port number where the ONC/RPC server can be contacted. * If 0, then the OncRpcUdpClient object will * ask the portmapper at host for the port number. * @param bufferSize Size of receive and send buffers. In contrast to * UDP-based ONC/RPC clients, messages larger than the specified * buffer size can still be sent and received. The buffer is only * necessary to handle the messages and the underlaying streams will * break up long messages automatically into suitable pieces. * Specifying zero will select the default buffer size (currently * 8192 bytes). * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public OncRpcTcpClient(InetAddress host, int program, int version, int port, int bufferSize) throws OncRpcException, IOException { this(host, program, version, port, bufferSize, -1); } /** * Constructs a new OncRpcTcpClient object, which connects * to the ONC/RPC server at host for calling remote procedures * of the given { program, version }. * *

Note that the construction of an OncRpcTcpClient * object will result in communication with the portmap process at * host if port is 0. * * @param host The host where the ONC/RPC server resides. * @param program Program number of the ONC/RPC server to call. * @param version Program version number. * @param port The port number where the ONC/RPC server can be contacted. * If 0, then the OncRpcUdpClient object will * ask the portmapper at host for the port number. * @param bufferSize Size of receive and send buffers. In contrast to * UDP-based ONC/RPC clients, messages larger than the specified * buffer size can still be sent and received. The buffer is only * necessary to handle the messages and the underlaying streams will * break up long messages automatically into suitable pieces. * Specifying zero will select the default buffer size (currently * 8192 bytes). * @param timeout Maximum timeout in milliseconds when connecting to * the ONC/RPC server. If negative, a default implementation-specific * timeout setting will apply. Note that this timeout only applies * to the connection phase, but not to later communication. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public OncRpcTcpClient(InetAddress host, int program, int version, int port, int bufferSize, int timeout) throws OncRpcException, IOException { // // Construct the inherited part of our object. This will also try to // lookup the port of the desired ONC/RPC server, if no port number // was specified (port = 0). // super(host, program, version, port, OncRpcProtocols.ONCRPC_TCP); // // Let the host operating system choose which port (and network // interface) to use. Then set the buffer sizes for sending and // receiving UDP datagrams. Finally set the destination of packets. // if ( bufferSize == 0 ) { bufferSize = 8192; // default setting } if ( bufferSize < 1024 ) { bufferSize = 1024; } // // Note that we use this.port at this time, because the superclass // might have resolved the port number in case the caller specified // simply 0 as the port number. // socketHelper = new OncRpcTcpSocketHelper(); socket = socketHelper.connect(host, this.port, timeout); socket.setTcpNoDelay(true); if ( socketHelper.getSendBufferSize() < bufferSize ) { socketHelper.setSendBufferSize(bufferSize); } if ( socketHelper.getReceiveBufferSize() < bufferSize ) { socketHelper.setReceiveBufferSize(bufferSize); } // // Create the necessary encoding and decoding streams, so we can // communicate at all. // sendingXdr = new XdrTcpEncodingStream(socket, bufferSize); receivingXdr = new XdrTcpDecodingStream(socket, bufferSize); } /** * Close the connection to an ONC/RPC server and free all network-related * resources. Well -- at least hope, that the Java VM will sometimes free * some resources. Sigh. * * @throws OncRpcException if an ONC/RPC error occurs. */ public void close() throws OncRpcException { if ( socket != null ) { try { socket.close(); } catch ( IOException e ) { } socket = null; } if ( sendingXdr != null ) { try { sendingXdr.close(); } catch ( IOException e ) { } sendingXdr = null; } if ( receivingXdr != null ) { try { receivingXdr.close(); } catch ( IOException e ) { } receivingXdr = null; } } /** * Calls a remote procedure on an ONC/RPC server. * *

Please note that while this method supports call batching by * setting the communication timeout to zero * (setTimeout(0)) you should better use * {@link #batchCall} as it provides better control over when the * batch should be flushed to the server. * * @param procedureNumber Procedure number of the procedure to call. * @param versionNumber Protocol version number. * @param params The parameters of the procedure to call, contained * in an object which implements the {@link XdrAble} interface. * @param result The object receiving the result of the procedure call. * * @throws OncRpcException if an ONC/RPC error occurs. */ public synchronized void call(int procedureNumber, int versionNumber, XdrAble params, XdrAble result) throws OncRpcException { Refresh: for ( int refreshesLeft = 1; refreshesLeft >= 0; --refreshesLeft ) { // // First, build the ONC/RPC call header. Then put the sending // stream into a known state and encode the parameters to be // sent. Finally tell the encoding stream to send all its data // to the server. Then wait for an answer, receive it and decode // it. So that's the bottom line of what we do right here. // nextXid(); OncRpcClientCallMessage callHeader = new OncRpcClientCallMessage(xid, program, versionNumber, procedureNumber, auth); OncRpcClientReplyMessage replyHeader = new OncRpcClientReplyMessage(auth); // // Send call message to server. If we receive an IOException, // then we'll throw the appropriate ONC/RPC (client) exception. // Note that we use a connected stream, so we don't need to // specify a destination when beginning serialization. // try { socket.setSoTimeout(transmissionTimeout); sendingXdr.beginEncoding(null, 0); callHeader.xdrEncode(sendingXdr); params.xdrEncode(sendingXdr); if ( timeout != 0 ) { sendingXdr.endEncoding(); } else { sendingXdr.endEncoding(false); } } catch ( IOException e ) { throw(new OncRpcException(OncRpcException.RPC_CANTSEND, e.getLocalizedMessage())); } // // Receive reply message from server -- at least try to do so... // In case of batched calls we don't need no stinkin' answer, so // we can do other, more interesting things. // if ( timeout == 0 ) { return; } try { // // Keep receiving until we get the matching reply. // while ( true ) { socket.setSoTimeout(timeout); receivingXdr.beginDecoding(); socket.setSoTimeout(transmissionTimeout); // // First, pull off the reply message header of the // XDR stream. In case we also received a verifier // from the server and this verifier was invalid, broken // or tampered with, we will get an // OncRpcAuthenticationException right here, which will // propagate up to the caller. If the server reported // an authentication problem itself, then this will // be handled as any other rejected ONC/RPC call. // try { replyHeader.xdrDecode(receivingXdr); } catch ( OncRpcException e ) { // // ** SF bug #1262106 ** // // We ran into some sort of trouble. Usually this will have // been a buffer underflow. Whatever, end the decoding process // and ensure this way that the next call has a chance to start // from a clean state. // receivingXdr.endDecoding(); throw(e); } // // Only deserialize the result, if the reply matches the // call. Otherwise skip this record. // if ( replyHeader.messageId == callHeader.messageId ) { break; } receivingXdr.endDecoding(); } // // Make sure that the call was accepted. In case of unsuccessful // calls, throw an exception, if it's not an authentication // exception. In that case try to refresh the credential first. // if ( !replyHeader.successfullyAccepted() ) { receivingXdr.endDecoding(); // // Check whether there was an authentication // problem. In this case first try to refresh the // credentials. // if ( (refreshesLeft > 0) && (replyHeader.replyStatus == OncRpcReplyStatus.ONCRPC_MSG_DENIED) && (replyHeader.rejectStatus == OncRpcRejectStatus.ONCRPC_AUTH_ERROR) && (auth != null) && auth.canRefreshCred() ) { continue Refresh; } // // Nope. No chance. This gets tough. // throw(replyHeader.newException()); } try { result.xdrDecode(receivingXdr); } catch ( OncRpcException e ) { // // ** SF bug #1262106 ** // // We ran into some sort of trouble. Usually this will have // been a buffer underflow. Whatever, end the decoding process // and ensure this way that the next call has a chance to start // from a clean state. // receivingXdr.endDecoding(); throw(e); } // // Free pending resources of buffer and exit the call loop, // returning the reply to the caller through the result // object. // receivingXdr.endDecoding(); return; } catch ( InterruptedIOException e ) { // // In case our time run out, we throw an exception. // throw(new OncRpcTimeoutException()); } catch ( IOException e ) { // // Argh. Trouble with the transport. Seems like we can't // receive data. Gosh. Go away! // throw(new OncRpcException(OncRpcException.RPC_CANTRECV, e.getLocalizedMessage())); } } // for ( refreshesLeft ) } /** * Issues a batched call for a remote procedure to an ONC/RPC server. * Below is a small example (exception handling ommited for clarity): * *

     * OncRpcTcpClient client = new OncRpcTcpClient(
     *     InetAddress.getByName("localhost"),
     *     myprogramnumber, myprogramversion,
     *     OncRpcProtocols.ONCRPC_TCP);
     * client.callBatch(42, myparams, false);
     * client.callBatch(42, myotherparams, false);
     * client.callBatch(42, myfinalparams, true);
     * 
* * In the example above, three calls are batched in a row and only be sent * all together with the third call. Note that batched calls must not expect * replies, with the only exception being the last call in a batch: * *
     * client.callBatch(42, myparams, false);
     * client.callBatch(42, myotherparams, false);
     * client.call(43, myfinalparams, myfinalresult);
     * 
* * @param procedureNumber Procedure number of the procedure to call. * @param params The parameters of the procedure to call, contained * in an object which implements the {@link XdrAble} interface. * @param flush Make sure that all pending batched calls are sent to * the server. * * @throws OncRpcException if an ONC/RPC error occurs. */ public synchronized void batchCall(int procedureNumber, XdrAble params, boolean flush) throws OncRpcException { // // First, build the ONC/RPC call header. Then put the sending // stream into a known state and encode the parameters to be // sent. Finally tell the encoding stream to send all its data // to the server. We don't then need to wait for an answer. And // we don't need to take care of credential refreshes either. // nextXid(); OncRpcClientCallMessage callHeader = new OncRpcClientCallMessage(xid, program, version, procedureNumber, auth); // // Send call message to server. If we receive an IOException, // then we'll throw the appropriate ONC/RPC (client) exception. // Note that we use a connected stream, so we don't need to // specify a destination when beginning serialization. // try { socket.setSoTimeout(transmissionTimeout); sendingXdr.beginEncoding(null, 0); callHeader.xdrEncode(sendingXdr); params.xdrEncode(sendingXdr); sendingXdr.endEncoding(flush); } catch ( IOException e ) { throw(new OncRpcException(OncRpcException.RPC_CANTSEND, e.getLocalizedMessage())); } } /** * Set the timout for remote procedure calls to wait for an answer from * the ONC/RPC server. If the timeout expires, * {@link #call(int, XdrAble, XdrAble)} will raise a * {@link java.io.InterruptedIOException}. The default timeout value is * 30 seconds (30,000 milliseconds). The timeout must be > 0. * A timeout of zero indicates a batched call, for which no reply message * is expected. * * @param milliseconds Timeout in milliseconds. A timeout of zero indicates * batched calls. */ public void setTimeout(int milliseconds) { super.setTimeout(milliseconds); } /** * Set the timeout used during transmission of data. If the flow of data * when sending calls or receiving replies blocks longer than the given * timeout, an exception is thrown. The timeout must be > 0. * * @param milliseconds Transmission timeout in milliseconds. */ public void setTransmissionTimeout(int milliseconds) { if ( milliseconds <= 0 ) { throw(new IllegalArgumentException("transmission timeout must be > 0")); } transmissionTimeout = milliseconds; } /** * Retrieve the current timeout used during transmission phases (call and * reply phases). * * @return Current transmission timeout. */ public int getTransmissionTimeout() { return transmissionTimeout; } /** * Set the character encoding for (de-)serializing strings. * * @param characterEncoding the encoding to use for (de-)serializing strings. * If null, the system's default encoding is to be used. */ public void setCharacterEncoding(String characterEncoding) { receivingXdr.setCharacterEncoding(characterEncoding); sendingXdr.setCharacterEncoding(characterEncoding); } /** * Get the character encoding for (de-)serializing strings. * * @return the encoding currently used for (de-)serializing strings. * If null, then the system's default encoding is used. */ public String getCharacterEncoding() { return receivingXdr.getCharacterEncoding(); } /** * TCP socket used for stream-oriented communication with an ONC/RPC * server. */ private Socket socket; /** * Socket helper object supplying missing methods for JDK 1.1 * backwards compatibility. So much for compile once, does not run * everywhere. */ private OncRpcTcpSocketHelper socketHelper; /** * XDR encoding stream used for sending requests via TCP/IP to an ONC/RPC * server. */ protected XdrTcpEncodingStream sendingXdr; /** * XDR decoding stream used when receiving replies via TCP/IP from an * ONC/RPC server. */ protected XdrTcpDecodingStream receivingXdr; /** * Timeout during the phase where data is sent within calls, or data is * received within replies. */ protected int transmissionTimeout = 30000; } // End of OncRpcTcpClient.javaremotetea-1.0.7/src/org/acplt/oncrpc/OncRpcTcpSocketHelper.java0000644005374700003410000005107510627063312025604 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/OncRpcTcpSocketHelper.java,v 1.3 2007/05/29 19:45:46 haraldalbrecht Exp $ * * Copyright (c) 2001 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; import java.io.IOException; import java.net.*; import java.lang.reflect.*; /** * Wraps JRE-specific networking code for TCP/IP-based client sockets. * So much for compile once, make it unuseable everywhere. Why could our * great Sun simply not get their socket class straight from the beginning? * The BSD socket API has been around since long enough and that real * network applications need to control certain aspects of the transport * layer's behaviour was also well known at this time -- looks like the * one exceptions was -- and still is -- Sun, and the second one is MS. * *

Sun always toutes Java as the perfect network "whatever" (replace with * buzzword-of-the-day, like "programming language", "operating system",...) * and especially their support for the Web. Sweet irony that it took them * until JRE 1.3 to realize that half-closed connections are the way * to do HTTP/1.0 non-persistent connections. And even more irony that * they are now beginning to understand about polled network i/o. * *

The following JRE-dependent methods are wrapped and will just do * nothing or return fake information on old JRE plattforms. The number * after each method wrapper indicates the first JRE version supporting * a particular feature: *

  • *
  • setSendBufferSize() -- 1.2 *
  • setReceiveBufferSize() -- 1.2 *
  • * *

    The following methods have been around since JDK 1.1, so we * do not need to wrap them as we will never support JDK 1.0 -- let * it rest in piece(s): *

      *
    • getTcpNoDelay() / setTcpNoDelay() *
    • getSoTimeout() / setSoTimeout() *
    * *

    In order to support connect() timeouts before JDK 1.4, there's * now a connect() method available. It is more than just a * simple wrapper for pre JDK 1.4. * * @version $Revision: 1.3 $ $Date: 2007/05/29 19:45:46 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class OncRpcTcpSocketHelper { /** * Creates a stream socket helper and associates it with the given * stream-based socket. * * @param socket The socket associated with this helper. */ public OncRpcTcpSocketHelper(Socket socket) { this(); this.socket = socket; } /** * Creates a stream socket helper but does not associates it with * a real stream socket object. You need to call {@link #connect} * lateron for a timeout-controlled connect. */ public OncRpcTcpSocketHelper() { inspectSocketClassMethods(); } /** * Connects to specified TCP port at given host address, but aborts * after timeout milliseconds if the connection could not be established * within this time frame. * *

    On pre-JRE 1.4 systems, this method will create a new thread * to handle connection establishment. This should be no problem, as in * general you might not want to connect to many ONC/RPC servers at the * same time; but surely someone will soon pop up with a perfect * reason just to do so... * * @param timeout Timeout in milliseconds for connection operation. * A negative timeout leaves the exact timeout up to the particular * JVM and java.net implementation. * * @throws IOException with the message "connect interrupted" in case the * timeout was reached before the connection could be established. */ public Socket connect(InetAddress address, int port, int timeout) throws IOException { if ( timeout < 0 ) { // // Leave the timeout up to the JVM and java.net implementation. // socket = new Socket(address, port); return socket; } // // Otherwise we have to implement a user-controlled timeout... // if ( methodConnect != null ) { // // Easy going. This JRE can do timeout-controlled connects // itself. Fine. We just need to invoke the proper connect method. // First, we call the Socket constructor without any parameters // to create an unconnected socket (new in JRE 1.4), then we // connect it to the destination -- well, at least we try to do so. // try { socket = (Socket) ctor.newInstance(new Object [] {}); methodConnect.invoke(socket, new Object [] { address, new Integer(timeout) }); } catch ( InvocationTargetException e ) { Throwable t = e.getTargetException(); if ( t instanceof SocketException ) { throw((SocketException) t); } else if ( t instanceof IllegalArgumentException ) { throw((IllegalArgumentException) t); } } catch ( IllegalAccessException e ) { throw(new SocketException(e.getMessage())); } catch ( InstantiationException e ) { // This should never happen, but who knows... throw(new SocketException(e.getMessage())); } } else { // // Sigh. We have to emulate timeout-controlled connects ourself. // What a lousy JRE. // // Solution: we create a thread which will try to connect. It // will signal us when it succeeded or some exception was thrown. // We then wait for the signal for the given amount of time. In // case our wait times out, we let the thread go... // Connectiator connectiator = new Connectiator(address, port); connectiator.start(); synchronized ( connectiator ) { try { connectiator.wait(timeout); } catch ( InterruptedException ie ) { // // Please note that we already reacquired the lock on the // connectiator again, so we can signal it that we are // not interested any more. However, this will not directly // terminate it, as this is not possible. // connectiator.notRequiredAnyMore(); // // Now inform the caller that something went awry. // throw(new IOException("connect interrupted")); } // // Now find out whether the connection could be made within // the time limit or not. We still need to hold the lock so // we avoid race conditions when the connection thread just // connects while we timed out. // // We either could connect successfully, or the connect operation // threw an exception before we timed out. In case we could not // connect because the socket constructor failed, we simply // rethrow the exception. // IOException ie = connectiator.getIOException(); if ( ie != null ) { throw(ie); } socket = connectiator.getSocket(); if ( socket == null ) { // // Same behaviour as constructor immediately trying to // establish a connection. // throw(new NoRouteToHostException("Operation timed out: connect")); } // Well done. So to speak. } connectiator = null; // just to made the point... } return socket; } /** * The class Connectiator has a short and sometimes sad * life, as its only purpose is trying to connect to a TCP port at * another host machine. */ private class Connectiator extends Thread { /** * Construct a new Connectiator that can later be used * connect to the given TCP port at the host specified. Note that we * do not try to establish the connection yet; this has to be done * later using the {@link #run} method. */ public Connectiator(InetAddress address, int port) { this.address = address; this.port = port; } public void run() { // // We need temporary object references here, as we are not allowed // to assign to the object's member references "socket" and "ie" // before we acquired the lock. // Socket mysocket = null; IOException myie = null; try { mysocket = new Socket(address, port); } catch ( IOException ie ) { myie = ie; } // // Acquire lock, so we can permanently set the connect's outcome // and notify the waiting socket helper object that we did // our job -- either good or not so good. // synchronized ( this ) { socket = mysocket; ioexception = myie; this.notify(); if ( hitTheBucket && (socket != null) ) { try { socket.close(); } catch ( IOException e ) { } } } } /** * Return exception caused by connection operation, if any, or * null if no exception was thrown. * *

    Note that we do not need to synchronize this method as the caller * calls us when it is already holding the lock on us. * * @return Connection operation exception or null. */ public IOException getIOException() { return ioexception; } /** * Return socket created by connection establishment, or * null if the connection could not be established. * *

    Note that we do not need to synchronize this method as the caller * calls us when it is already holding the lock on us. * * @return Socket or null. */ public Socket getSocket() { return socket; } /** * Indicates that the caller initiating this Thread is not interested * in its results any more. * *

    Note that we do not need to synchronize this method as the caller * calls us when it is already holding the lock on us. */ public void notRequiredAnyMore() { hitTheBucket = true; try { this.interrupt(); } catch ( SecurityException e ) { } } /** * Host to connect to. */ private InetAddress address; /** * TCP port to connect to. */ private int port; /** * IOException caused by connection attempt, if any, * or null. */ private IOException ioexception; /** * Socket object, if the connection could be established, or * null. */ private Socket socket; /** * Flag to indicate that the socket is not needed, as the caller * timed out. */ private boolean hitTheBucket = false; } /** * Sets the socket's send buffer size as a hint to the underlying * transport layer to use appropriately sized I/O buffers. If the class * libraries of the underlying JRE do not support setting the send * buffer size, this is silently ignored. * * @param size The size to which to set the send buffer size. This value * must be greater than 0. * * @throws SocketException if the socket's send buffer size could not * be set, because the transport layer decided against accepting the * new buffer size. * @throws IllegalArgumentException if size is 0 or negative. */ public void setSendBufferSize(int size) throws SocketException { if ( methodSetSendBufferSize != null ) { try { methodSetSendBufferSize.invoke(socket, new Object [] { new Integer(size) }); } catch ( InvocationTargetException e ) { Throwable t = e.getTargetException(); if ( t instanceof SocketException ) { throw((SocketException) t); } else if ( t instanceof IllegalArgumentException ) { throw((IllegalArgumentException) t); } } catch ( IllegalAccessException e ) { throw(new SocketException(e.getMessage())); } } } /** * Get size of send buffer for this socket. * * @return Size of send buffer. * * @throws SocketException If the transport layer could not be queried * for the size of this socket's send buffer. */ public int getSendBufferSize() throws SocketException { if ( methodGetSendBufferSize != null ) { try { Object result = methodGetSendBufferSize.invoke(socket, (Object[]) null); if ( result instanceof Integer ) { return ((Integer) result).intValue(); } } catch ( InvocationTargetException e ) { Throwable t = e.getTargetException(); if ( t instanceof SocketException ) { throw((SocketException) t); } throw(new SocketException(t.getMessage())); } catch ( IllegalAccessException e ) { throw(new SocketException(e.getMessage())); } } // // Without knowing better we can only return fake information. // For quite some solaris OS revisions, the buffer size returned // is beyond their typical configuration, with only 8k for fragment // reassemble set asside by the IP layer. What a NOS... // return 65536; } /** * Sets the socket's receive buffer size as a hint to the underlying * transport layer to use appropriately sized I/O buffers. If the class * libraries of the underlying JRE do not support setting the receive * buffer size, this is silently ignored. * * @param size The size to which to set the receive buffer size. This value * must be greater than 0. * * @throws SocketException if the socket's receive buffer size could not * be set, because the transport layer decided against accepting the * new buffer size. * @throws IllegalArgumentException if size is 0 or negative. */ public void setReceiveBufferSize(int size) throws SocketException { if ( methodSetSendBufferSize != null ) { try { methodSetReceiveBufferSize.invoke(socket, new Object [] { new Integer(size) }); } catch ( InvocationTargetException e ) { Throwable t = e.getTargetException(); if ( t instanceof SocketException ) { throw((SocketException) t); } else if ( t instanceof IllegalArgumentException ) { throw((IllegalArgumentException) t); } } catch ( IllegalAccessException e ) { throw(new SocketException(e.getMessage())); } } } /** * Get size of receive buffer for this socket. * * @return Size of receive buffer. * * @throws SocketException If the transport layer could not be queried * for the size of this socket's receive buffer. */ public int getReceiveBufferSize() throws SocketException { if ( methodGetReceiveBufferSize != null ) { try { Object result = methodGetReceiveBufferSize.invoke(socket, (Object[]) null); if ( result instanceof Integer ) { return ((Integer) result).intValue(); } } catch ( InvocationTargetException e ) { Throwable t = e.getTargetException(); if ( t instanceof SocketException ) { throw((SocketException) t); } throw(new SocketException(t.getMessage())); } catch ( IllegalAccessException e ) { throw(new SocketException(e.getMessage())); } } // // Without knowing better we can only return fake information. // For quite some solaris OS revisions, the buffer size returned // is beyond their typical configuration, with only 8k for fragment // reassemble set asside by the IP layer. What a NOS... // return 65536; } /** * Looks up methods of class Socket whether they are supported by the * class libraries of the JRE we are currently executing on. */ protected void inspectSocketClassMethods() { Class socketClass = Socket.class; // JRE 1.2 specific stuff try { methodSetSendBufferSize = socketClass.getMethod("setSendBufferSize", new Class [] {int.class}); methodGetSendBufferSize = socketClass.getMethod("getSendBufferSize", (Class[]) null); } catch ( Exception e ) { } try { methodSetReceiveBufferSize = socketClass.getMethod("setReceiveBufferSize", new Class [] {int.class}); methodGetReceiveBufferSize = socketClass.getMethod("getReceiveBufferSize", (Class[]) null); } catch ( Exception e ) { } // JRE 1.4 specific stuff try { ctor = socketClass.getConstructor(new Class [] {}); methodConnect = socketClass.getMethod("connect", new Class [] {InetAddress.class, int.class}); } catch ( Exception e ) { } } /** * The socket for which we have to help out with some missing methods. */ private Socket socket; /** * Method Socket.setSendBufferSize or null if not available * in the class library of a particular JRE. */ private Method methodSetSendBufferSize; /** * Method Socket.setReceiverBufferSize or null if not available * in the class library of a particular JRE. */ private Method methodSetReceiveBufferSize; /** * Method Socket.getSendBufferSize or null if not available * in the class library of a particular JRE. */ private Method methodGetSendBufferSize; /** * Method Socket.getReceiveBufferSize or null if not available * in the class library of a particular JRE. */ private Method methodGetReceiveBufferSize; /** * Method Socket.connect with timeout or null if not available * in the class library of a particular JRE. */ private Method methodConnect; /** * Constructor Socket() without any parameters or null if not available * in the class library of a particular JRE. */ private Constructor ctor; } // End of OncRpcTcpSocketHelper.java remotetea-1.0.7/src/org/acplt/oncrpc/OncRpcTimeoutException.java0000644005374700003410000000334310335174554026054 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/OncRpcTimeoutException.java,v 1.2 2005/11/11 21:05:00 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; /** * The class OncRpcTimeoutException indicates a timed out * call exception. * * @version $Revision: 1.2 $ $Date: 2005/11/11 21:05:00 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class OncRpcTimeoutException extends OncRpcException { /** * Defines the serial version UID for OncRpcTimeoutException. */ private static final long serialVersionUID = 2777518173161399732L; /** * Initializes an OncRpcTimeoutException * with a detail of {@link OncRpcException#RPC_TIMEDOUT}. */ public OncRpcTimeoutException() { super(RPC_TIMEDOUT); } } // End of OncRpcTimeoutException.java remotetea-1.0.7/src/org/acplt/oncrpc/OncRpcUdpClient.java0000644005374700003410000010126410627054534024436 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/OncRpcUdpClient.java,v 1.6 2007/05/29 18:48:27 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; import java.io.IOException; import java.io.InterruptedIOException; import java.net.InetAddress; import java.net.DatagramSocket; /** * ONC/RPC client which communicates with ONC/RPC servers over the network * using the datagram-oriented protocol UDP/IP. * * @version $Revision: 1.6 $ $Date: 2007/05/29 18:48:27 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class OncRpcUdpClient extends OncRpcClient { /** * Constructs a new OncRpcUdpClient object, which connects * to the ONC/RPC server at host for calling remote procedures * of the given { program, version }. * *

    Note that the construction of an OncRpcUdpProtocolClient * object will result in communication with the portmap process at * host if port is 0. * * @param host The host where the ONC/RPC server resides. * @param program Program number of the ONC/RPC server to call. * @param version Program version number. * @param port The port number where the ONC/RPC server can be contacted. * If 0, then the OncRpcUdpClient object will * ask the portmapper at host for the port number. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public OncRpcUdpClient(InetAddress host, int program, int version, int port) throws OncRpcException, IOException { this(host, program, version, port, 8192); } /** * Constructs a new OncRpcUdpClient object, which connects * to the ONC/RPC server at host for calling remote procedures * of the given { program, version }. * *

    Note that the construction of an OncRpcUdpProtocolClient * object will result in communication with the portmap process at * host if port is 0. * * @param host The host where the ONC/RPC server resides. * @param program Program number of the ONC/RPC server to call. * @param version Program version number. * @param port The port number where the ONC/RPC server can be contacted. * If 0, then the OncRpcUdpClient object will * ask the portmapper at host for the port number. * @param bufferSize The buffer size used for sending and receiving UDP * datagrams. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public OncRpcUdpClient(InetAddress host, int program, int version, int port, int bufferSize) throws OncRpcException, IOException { // // Construct the inherited part of our object. This will also try to // lookup the port of the desired ONC/RPC server, if no port number // was specified (port = 0). // super(host, program, version, port, OncRpcProtocols.ONCRPC_UDP); // // Let the host operating system choose which port (and network // interface) to use. Then set the buffer sizes for sending and // receiving UDP datagrams. Finally set the destination of packets. // if ( bufferSize < 1024 ) { bufferSize = 1024; } socket = new DatagramSocket(); socketHelper = new OncRpcUdpSocketHelper(socket); if ( socketHelper.getSendBufferSize() < bufferSize ) { socketHelper.setSendBufferSize(bufferSize); } if ( socketHelper.getReceiveBufferSize() < bufferSize ) { socketHelper.setReceiveBufferSize(bufferSize); } // // Note: we don't do a // socket.connect(host, this.port); // here anymore. XdrUdpEncodingStream long since then supported // specifying the destination of an ONC/RPC UDP packet when // start serialization. In addition, connecting a UDP socket disables // the socket's ability to receive broadcasts. Without connecting you // can send an ONC/RPC call to the broadcast address of the network // and receive multiple replies. // // Create the necessary encoding and decoding streams, so we can // communicate at all. // sendingXdr = new XdrUdpEncodingStream(socket, bufferSize); receivingXdr = new XdrUdpDecodingStream(socket, bufferSize); } /** * Close the connection to an ONC/RPC server and free all network-related * resources. Well -- at least hope, that the Java VM will sometimes free * some resources. Sigh. * * @throws OncRpcException if an ONC/RPC error occurs. */ public void close() throws OncRpcException { if ( socket != null ) { socket.close(); socket = null; } if ( sendingXdr != null ) { try { sendingXdr.close(); } catch ( IOException e ) { } sendingXdr = null; } if ( receivingXdr != null ) { try { receivingXdr.close(); } catch ( IOException e ) { } receivingXdr = null; } } /** * Calls a remote procedure on an ONC/RPC server. * *

    The OncRpcUdpClient uses a similar timeout scheme as * the genuine Sun C implementation of ONC/RPC: it starts with a timeout * of one second when waiting for a reply. If no reply is received within * this time frame, the client doubles the timeout, sends a new request * and then waits again for a reply. In every case the client will wait * no longer than the total timeout set through the * {@link #setTimeout(int)} method. * * @param procedureNumber Procedure number of the procedure to call. * @param versionNumber Protocol version number. * @param params The parameters of the procedure to call, contained * in an object which implements the {@link XdrAble} interface. * @param result The object receiving the result of the procedure call. * * @throws OncRpcException if an ONC/RPC error occurs. */ public synchronized void call(int procedureNumber, int versionNumber, XdrAble params, XdrAble result) throws OncRpcException { Refresh: for ( int refreshesLeft = 1; refreshesLeft >= 0; --refreshesLeft ) { // // First, build the ONC/RPC call header. Then put the sending // stream into a known state and encode the parameters to be // sent. Finally tell the encoding stream to send all its data // to the server. Then wait for an answer, receive it and decode // it. So that's the bottom line of what we do right here. // nextXid(); // // We only create our request message once and reuse it in case // retransmission should be necessary -- with the exception being // credential refresh. In this case we need to create a new // request message. // OncRpcClientCallMessage callHeader = new OncRpcClientCallMessage(xid, program, versionNumber, procedureNumber, auth); OncRpcClientReplyMessage replyHeader = new OncRpcClientReplyMessage(auth); long stopTime = System.currentTimeMillis() + timeout; int resendTimeout = retransmissionTimeout; // // Now enter the great loop where we send calls out to the server // and then sit there waiting for a reply. If none comes, we first // resend our call after one second, then two seconds, four seconds, // and so on, until we have reached the timeout for the call in total. // Note that this setting only applies if exponential back-off // retransmission has been selected. Per default we do not retransmit // any more, in order to be in line with the SUNRPC implementations. // do { try { // // Send call message to server. Remember that we've already // "connected" the datagram socket, so java.net knows whom // to send the datagram packets. // sendingXdr.beginEncoding(host, port); callHeader.xdrEncode(sendingXdr); params.xdrEncode(sendingXdr); sendingXdr.endEncoding(); } catch ( IOException e ) { throw(new OncRpcException(OncRpcException.RPC_CANTSEND, e.getLocalizedMessage())); } // // Receive reply message from server -- at least try to do so... // In case of batched calls we don't need no stinkin' answer, so // we can do other, more interesting things. // if ( timeout == 0 ) { return; } // // Wait for an answer to arrive... // for ( ;; ) { try { int currentTimeout = (int)(stopTime - System.currentTimeMillis()); if ( currentTimeout > resendTimeout ) { currentTimeout = resendTimeout; } else if ( currentTimeout < 1 ) { // // as setSoTimeout interprets a timeout of zero as // infinite (?§$@%&!!!) we need to ensure that we // have a finite timeout, albeit maybe an infinitesimal // finite one. currentTimeout = 1; } socket.setSoTimeout(currentTimeout); receivingXdr.beginDecoding(); // // Only accept incomming reply if it comes from the same // address we've sent the ONC/RPC call to. Otherwise throw // away the datagram packet containing the reply and start // over again, waiting for the next reply to arrive. // if ( host.equals(receivingXdr.getSenderAddress()) ) { // // First, pull off the reply message header of the // XDR stream. In case we also received a verifier // from the server and this verifier was invalid, broken // or tampered with, we will get an // OncRpcAuthenticationException right here, which will // propagate up to the caller. If the server reported // an authentication problem itself, then this will // be handled as any other rejected ONC/RPC call. // try { replyHeader.xdrDecode(receivingXdr); } catch ( OncRpcException e ) { // // ** SF bug #1262106 ** // // We ran into some sort of trouble. Usually this will have // been a buffer underflow. Whatever, end the decoding process // and ensure this way that the next call has a chance to start // from a clean state. // receivingXdr.endDecoding(); throw(e); } // // Only deserialize the result, if the reply matches the call // and if the reply signals a successful call. In case of an // unsuccessful call (which mathes our call nevertheless) throw // an exception. // if ( replyHeader.messageId == callHeader.messageId ) { if ( !replyHeader.successfullyAccepted() ) { receivingXdr.endDecoding(); // // Check whether there was an authentication // problem. In this case first try to refresh the // credentials. // if ( (refreshesLeft > 0) && (replyHeader.replyStatus == OncRpcReplyStatus.ONCRPC_MSG_DENIED) && (replyHeader.rejectStatus == OncRpcRejectStatus.ONCRPC_AUTH_ERROR) && (auth != null) && auth.canRefreshCred() ) { // // Think about using a TAB size of four ;) // // Another instance of "CONTINUE considered // useful"... // continue Refresh; } // // Nope. No chance. This gets tough. // throw(replyHeader.newException()); } // // The reply header is okay and the call had been // accepted by the ONC/RPC server, so we can now // proceed to decode the outcome of the RPC. // try { result.xdrDecode(receivingXdr); } catch ( OncRpcException e ) { // // ** SF bug #1262106 ** // // We ran into some sort of trouble. Usually this will have // been a buffer underflow. Whatever, end the decoding process // and ensure this way that the next call has a chance to start // from a clean state. // receivingXdr.endDecoding(); throw(e); } // // Free pending resources of buffer and exit the call loop, // returning the reply to the caller through the result // object. // receivingXdr.endDecoding(); return; } else { // // The message id did no match -- probably some // old UDP datagram which just popped up from the // middle of the Internet. // // Yet another case of "CONTINUE considered not // harmful"... // // [Nothing to do here, just wait for the next datagram] } } else { // // IP address of received UDP datagram is not the same // as the IP address of the ONC/RPC server. // // [Nothing to do here, just wait for the next datagram] } } catch ( InterruptedIOException e ) { // // Note that we only catch timeouts here, but no other // exceptions. Those others will go up further until someone // catches them. The timeouts are caught, so they can do no // damage but instead we start another round of sending a // request and waiting for a reply. Reminds me of NASA and // their "Mars Polar Lander"... // // Note that we need to leave the inner waiting loop here, // as we might need to resend the (lost) RPC request // datagram. // break; } catch ( IOException e ) { // // Argh. Trouble with the transport. Seems like we can't // receive data. Gosh. Go away! // try { receivingXdr.endDecoding(); // skip UDP record } catch ( IOException ioe ) { } throw(new OncRpcException(OncRpcException.RPC_CANTRECV, e.getLocalizedMessage())); } catch ( OncRpcException e ) { // // Ooops. An ONC/RPC exception. Let us rethrow this one, // as we won't have nothin' to do with it... // try { receivingXdr.endDecoding(); // skip UDP record } catch ( IOException ioe ) { } // // Well, in case we got not a *reply* RPC message back, // we keep listening for messages. // if ( e.getReason() != OncRpcException.RPC_WRONGMESSAGE ) { throw(e); } } // // We can not make use of the reply we just received, so // we need to dump it. // // This should raise no exceptions, when skipping the UDP // record. So if one is raised, we will rethrow an ONC/RPC // exception instead. // try { receivingXdr.endDecoding(); } catch ( IOException e ) { throw(new OncRpcException(OncRpcException.RPC_CANTRECV, e.getLocalizedMessage())); } } // // We only reach this code part beyond the inner waiting // loop if we run in a timeout and might need to retransmit // // According to the retransmission strategy choosen, update the // current retransmission (resending) timeout. // if ( retransmissionMode == OncRpcUdpRetransmissionMode.EXPONENTIAL ) { resendTimeout *= 2; } } while ( System.currentTimeMillis() < stopTime ); // // That's it -- this shity server does not talk to us. Now, due to // the indecent language used in the previous sentence, this software // can not be exported any longer to some countries of the world. // But this is surely not my problem, but rather theirs. So go away // and hide yourself in the dark with all your zombies (or maybe // kangaroos). // throw(new OncRpcTimeoutException()); } // for ( refreshesLeft ) } /** * Broadcast a remote procedure call to several ONC/RPC servers. For this * you'll need to specify either a multicast address or the subnet's * broadcast address when creating a OncRpcUdpClient. For * every reply received, an event containing the reply is sent to the * OncRpcBroadcastListener listener, which is the last * parameter to the this method. * *

    In contrast to the {@link #call(int, XdrAble, XdrAble)} method, * broadcastCall will only send the ONC/RPC call once. It * will then wait for answers until the timeout as set by * {@link #setTimeout(int)} expires without resending the reply. * *

    Note that you might experience unwanted results when using * authentication types other than {@link OncRpcClientAuthNone}, causing * messed up authentication protocol handling objects. This depends on * the type of authentication used. For AUTH_UNIX nothing * bad happens as long as none of the servers replies with a shorthand * verifier. If it does, then this shorthand will be used on all subsequent * ONC/RPC calls, something you probably do not want at all. * * @param procedureNumber Procedure number of the procedure to call. * @param params The parameters of the procedure to call, contained * in an object which implements the {@link XdrAble} interface. * @param result The object receiving the result of the procedure call. * Note that this object is reused to deserialize all incomming replies * one after another. * @param listener Listener which will get an {@link OncRpcBroadcastEvent} * for every reply received. * * @throws OncRpcException if an ONC/RPC error occurs. */ public synchronized void broadcastCall(int procedureNumber, XdrAble params, XdrAble result, OncRpcBroadcastListener listener) throws OncRpcException { // // First, build the ONC/RPC call header. Then put the sending // stream into a known state and encode the parameters to be // sent. Finally tell the encoding stream to broadcast all its data. // Then wait for answers, receive and decode them one at a time. // nextXid(); OncRpcClientCallMessage callHeader = new OncRpcClientCallMessage(xid, program, version, procedureNumber, auth); OncRpcClientReplyMessage replyHeader = new OncRpcClientReplyMessage(auth); // // Broadcast the call. Note that we send the call only once and will // never resend it. // try { // // Send call message to server. Remember that we've already // "connected" the datagram socket, so java.net knows whom // to send the datagram packets. // sendingXdr.beginEncoding(host, port); callHeader.xdrEncode(sendingXdr); params.xdrEncode(sendingXdr); sendingXdr.endEncoding(); } catch ( IOException e ) { throw(new OncRpcException(OncRpcException.RPC_CANTSEND, e.getLocalizedMessage())); } // // Now enter the great loop where sit waiting for replies to our // broadcast call to come in. In every case, we wait until the // (total) timeout expires. // long stopTime = System.currentTimeMillis() + timeout; do { try { // // Calculate timeout until the total timeout is reached, so // we can try to meet the overall deadline. // int currentTimeout = (int)(stopTime - System.currentTimeMillis()); if ( currentTimeout < 0 ) { currentTimeout = 0; } socket.setSoTimeout(currentTimeout); // // Then wait for datagrams to arrive... // receivingXdr.beginDecoding(); replyHeader.xdrDecode(receivingXdr); // // Only deserialize the result, if the reply matches the call // and if the reply signals a successful call. In case of an // unsuccessful call (which mathes our call nevertheless) throw // an exception. // if ( replyHeader.messageId == callHeader.messageId ) { if ( !replyHeader.successfullyAccepted() ) { // // We got a notification of a rejected call. We silently // ignore such replies and continue listening for other // replies. // receivingXdr.endDecoding(); /* fall through to time check */ } result.xdrDecode(receivingXdr); // // Notify a potential listener of the reply. // if ( listener != null ) { OncRpcBroadcastEvent evt = new OncRpcBroadcastEvent( this, receivingXdr.getSenderAddress(), procedureNumber, params, result); listener.replyReceived(evt); } // // Free pending resources of buffer and exit the call loop, // returning the reply to the caller through the result // object. // receivingXdr.endDecoding(); /* fall through to time check */ } else { // // This should raise no exceptions, when skipping the UDP // record. So if one is raised, we will rethrow an ONC/RPC // exception instead. // try { receivingXdr.endDecoding(); } catch ( IOException e ) { throw(new OncRpcException(OncRpcException.RPC_CANTRECV, e.getLocalizedMessage())); } /* fall through to time check */ } } catch ( InterruptedIOException e ) { // // Note that we only catch timeouts here, but no other // exceptions. Those others will go up further until someone // catches them. If we get the timeout we know that it // could be time to leave the stage and so we fall through // to the total timeout check. // /* fall through to time check */ } catch ( IOException e ) { // // Argh. Trouble with the transport. Seems like we can't // receive data. Gosh. Go away! // throw(new OncRpcException(OncRpcException.RPC_CANTRECV, e.getLocalizedMessage())); } } while ( System.currentTimeMillis() < stopTime ); return; } /** * Set the {@link OncRpcUdpRetransmissionMode retransmission mode} for * lost remote procedure calls. The default retransmission mode is * {@link OncRpcUdpRetransmissionMode#FIXED}. * * @param mode Retransmission mode (either fixed or exponential). */ public void setRetransmissionMode(int mode) { retransmissionMode = mode; } /** * Retrieve the current * {@link OncRpcUdpRetransmissionMode retransmission mode} set for * retransmission of lost ONC/RPC calls. * * @return Current retransmission mode. */ public int getRetransmissionMode() { return retransmissionMode; } /** * Set the retransmission timout for remote procedure calls to wait for * an answer from the ONC/RPC server before resending the call. The * default retransmission timeout is the 30 seconds. The retransmission * timeout must be > 0. To disable retransmission of lost calls, set * the retransmission timeout to be the same value as the timeout. * * @param milliseconds Timeout in milliseconds. A timeout of zero indicates * batched calls. */ public void setRetransmissionTimeout(int milliseconds) { if ( milliseconds <= 0 ) { throw(new IllegalArgumentException("timeouts must be positive.")); } retransmissionTimeout = milliseconds; } /** * Retrieve the current retransmission timeout set for remote procedure * calls. * * @return Current retransmission timeout. */ public int getRetransmissionTimeout() { return retransmissionTimeout; } /** * Set the character encoding for (de-)serializing strings. * * @param characterEncoding the encoding to use for (de-)serializing strings. * If null, the system's default encoding is to be used. */ public void setCharacterEncoding(String characterEncoding) { receivingXdr.setCharacterEncoding(characterEncoding); sendingXdr.setCharacterEncoding(characterEncoding); } /** * Get the character encoding for (de-)serializing strings. * * @return the encoding currently used for (de-)serializing strings. * If null, then the system's default encoding is used. */ public String getCharacterEncoding() { return receivingXdr.getCharacterEncoding(); } /** * UDP socket used for datagram-based communication with an ONC/RPC * server. */ private DatagramSocket socket; /** * Socket helper object supplying missing methods for JDK 1.1 * backwards compatibility. So much for compile once, does not run * everywhere. */ private OncRpcUdpSocketHelper socketHelper; /** * XDR encoding stream used for sending requests via UDP/IP to an ONC/RPC * server. */ protected XdrUdpEncodingStream sendingXdr; /** * XDR decoding stream used when receiving replies via UDP/IP from an * ONC/RPC server. */ protected XdrUdpDecodingStream receivingXdr; /** * Retransmission timeout used for resending ONC/RPC calls when an ONC/RPC * server does not answer fast enough. The default retransmission timeout * is identical to the overall timeout for ONC/RPC calls (thus UDP/IP-based * clients will not retransmit lost calls). * * @see OncRpcUdpClient#retransmissionMode * @see OncRpcClient#setTimeout */ protected int retransmissionTimeout = super.timeout; /** * Retransmission mode used when resending ONC/RPC calls. Default mode is * {@link OncRpcUdpRetransmissionMode#FIXED fixed timeout mode}. * * @see OncRpcUdpRetransmissionMode */ protected int retransmissionMode = OncRpcUdpRetransmissionMode.FIXED; } // End of OncRpcUdpClient.java remotetea-1.0.7/src/org/acplt/oncrpc/OncRpcUdpRetransmissionMode.java0000644005374700003410000000403207716406400027036 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/OncRpcUdpRetransmissionMode.java,v 1.1.1.1 2003/08/13 12:03:43 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; /** * A collection of constants used to identify the retransmission schemes * when using {@link OncRpcUdpClient UDP/IP-based ONC/RPC clients}. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:43 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public interface OncRpcUdpRetransmissionMode { /** * In exponentional back-off retransmission mode, UDP/IP-based ONC/RPC * clients first wait a given retransmission timeout period before * sending the ONC/RPC call again. The retransmission timeout then is * doubled on each try. */ public static final int EXPONENTIAL = 0; /** * In fixed retransmission mode, UDP/IP-based ONC/RPC clients wait a * given retransmission timeout period before send the ONC/RPC call again. * The retransmission timeout is not changed between consecutive tries * but is fixed instead. */ public static final int FIXED = 1; } // End of OncRpcUdpRetransmissionMode.java remotetea-1.0.7/src/org/acplt/oncrpc/OncRpcUdpSocketHelper.java0000644005374700003410000002323710627063312025605 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/OncRpcUdpSocketHelper.java,v 1.3 2007/05/29 19:45:46 haraldalbrecht Exp $ * * Copyright (c) 2001 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; import java.net.*; import java.lang.reflect.*; /** * Wraps JRE-specific networking code for UDP/IP-based client sockets. * So much for compile once, make it unuseable everywhere. * *

    The following JRE-dependent methods are wrapped and will just do * nothing or return fake information on old JRE plattforms. The number * after each method wrapper indicates the first JRE version supporting * a particular feature: *

  • *
  • setSendBufferSize() -- 1.2 *
  • setReceiveBufferSize() -- 1.2 *
  • * *

    The following methods have been around since JDK 1.1, so we * do not need to wrap them as we will never support JDK 1.0 -- let * it rest in piece(s): *

      *
    • getTcpNoDelay() / setTcpNoDelay() *
    • getSoTimeout() / setSoTimeout() *
    * * @version $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/OncRpcUdpSocketHelper.java,v 1.3 2007/05/29 19:45:46 haraldalbrecht Exp $ * @author Harald Albrecht */ public class OncRpcUdpSocketHelper { /** * Creates a datagram socket and binds it to an arbitrary available port * on the local host machine. */ public OncRpcUdpSocketHelper(DatagramSocket socket) { this.socket = socket; queryMethods(); } /** * Sets the socket's send buffer size as a hint to the underlying * transport layer to use appropriately sized I/O buffers. If the class * libraries of the underlying JRE do not support setting the send * buffer size, this is silently ignored. * * @param size The size to which to set the send buffer size. This value * must be greater than 0. * * @throws SocketException if the socket's send buffer size could not * be set, because the transport layer decided against accepting the * new buffer size. * @throws IllegalArgumentException if size is 0 or negative. */ public void setSendBufferSize(int size) throws SocketException { if ( methodSetSendBufferSize != null ) { try { methodSetSendBufferSize.invoke(socket, new Object [] { new Integer(size) }); } catch ( InvocationTargetException e ) { Throwable t = e.getTargetException(); if ( t instanceof SocketException ) { throw((SocketException) t); } else if ( t instanceof IllegalArgumentException ) { throw((IllegalArgumentException) t); } throw(new SocketException(t.getMessage())); } catch ( IllegalAccessException e ) { throw(new SocketException(e.getMessage())); } } } /** * Get size of send buffer for this socket. * * @return Size of send buffer. * * @throws SocketException If the transport layer could not be queried * for the size of this socket's send buffer. */ public int getSendBufferSize() throws SocketException { if ( methodGetSendBufferSize != null ) { try { Object result = methodGetSendBufferSize.invoke(socket, (Object[]) null); if ( result instanceof Integer ) { return ((Integer) result).intValue(); } } catch ( InvocationTargetException e ) { Throwable t = e.getTargetException(); if ( t instanceof SocketException ) { throw((SocketException) t); } throw(new SocketException(t.getMessage())); } catch ( IllegalAccessException e ) { throw(new SocketException(e.getMessage())); } } // // Without knowing better we can only return fake information. // For quite some solaris OS revisions, the buffer size returned // is beyond their typical configuration, with only 8k for fragment // reassemble set asside by the IP layer. What a NOS... // return 65536; } /** * Sets the socket's receive buffer size as a hint to the underlying * transport layer to use appropriately sized I/O buffers. If the class * libraries of the underlying JRE do not support setting the receive * buffer size, this is silently ignored. * * @param size The size to which to set the receive buffer size. This value * must be greater than 0. * * @throws SocketException if the socket's receive buffer size could not * be set, because the transport layer decided against accepting the * new buffer size. * @throws IllegalArgumentException if size is 0 or negative. */ public void setReceiveBufferSize(int size) throws SocketException { if ( methodSetReceiveBufferSize != null ) { try { methodSetReceiveBufferSize.invoke(socket, new Object [] { new Integer(size) }); } catch ( InvocationTargetException e ) { Throwable t = e.getTargetException(); if ( t instanceof SocketException ) { throw((SocketException) t); } else if ( t instanceof IllegalArgumentException ) { throw((IllegalArgumentException) t); } } catch ( IllegalAccessException e ) { throw(new SocketException(e.getMessage())); } } } /** * Get size of receive buffer for this socket. * * @return Size of receive buffer. * * @throws SocketException If the transport layer could not be queried * for the size of this socket's receive buffer. */ public int getReceiveBufferSize() throws SocketException { if ( methodGetReceiveBufferSize != null ) { try { Object result = methodGetReceiveBufferSize.invoke(socket, (Object[]) null); if ( result instanceof Integer ) { return ((Integer) result).intValue(); } } catch ( InvocationTargetException e ) { Throwable t = e.getTargetException(); if ( t instanceof SocketException ) { throw((SocketException) t); } throw(new SocketException(t.getMessage())); } catch ( IllegalAccessException e ) { throw(new SocketException(e.getMessage())); } } // // Without knowing better we can only return fake information. // For quite some solaris OS revisions, the buffer size returned // is beyond their typical configuration, with only 8k for fragment // reassemble set asside by the IP layer. What a NOS... // return 65536; } /** * Looks up methods of class DatagramSocket whether they are supported * by the class libraries of the JRE we are currently executing on. */ protected void queryMethods() { Class c = DatagramSocket.class; try { methodSetSendBufferSize = c.getMethod("setSendBufferSize", new Class [] {int.class}); methodGetSendBufferSize = c.getMethod("getSendBufferSize", (Class[]) null); } catch ( Exception e ) { } try { methodSetReceiveBufferSize = c.getMethod("setReceiveBufferSize", new Class [] {int.class}); methodGetReceiveBufferSize = c.getMethod("getReceiveBufferSize", (Class[]) null); } catch ( Exception e ) { } } /** * The datagram socket for which we have to help out with some missing * methods. */ private DatagramSocket socket; /** * Method Socket.setSendBufferSize or null if not available * in the class library of a particular JRE. */ private Method methodSetSendBufferSize; /** * Method Socket.setReceiverBufferSize or null if not available * in the class library of a particular JRE. */ private Method methodSetReceiveBufferSize; /** * Method Socket.getSendBufferSize or null if not available * in the class library of a particular JRE. */ private Method methodGetSendBufferSize; /** * Method Socket.getReceiveBufferSize or null if not available * in the class library of a particular JRE. */ private Method methodGetReceiveBufferSize; } // End of OncRpcUdpSocketHelper.java remotetea-1.0.7/src/org/acplt/oncrpc/XdrAble.java0000644005374700003410000000435007716406400022757 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/XdrAble.java,v 1.1.1.1 2003/08/13 12:03:43 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; import java.io.IOException; /** * Defines the interface for all classes that should be able to be * serialized into XDR streams, and deserialized or constructed from * XDR streams. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:43 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public interface XdrAble { /** * Encodes -- that is: serializes -- an object into a XDR stream in * compliance to RFC 1832. * * @param xdr XDR stream to which information is sent for encoding. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public abstract void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException; /** * Decodes -- that is: deserializes -- an object from a XDR stream in * compliance to RFC 1832. * * @param xdr XDR stream from which decoded information is retrieved. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public abstract void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException; } // End of XdrAble.java remotetea-1.0.7/src/org/acplt/oncrpc/XdrBoolean.java0000644005374700003410000000643007716406400023474 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/XdrBoolean.java,v 1.1.1.1 2003/08/13 12:03:43 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; import java.io.IOException; /** * Instances of the class XdrBoolean represent (de-)serializeable * booleans, which are especially useful in cases where a result with only a * single boolean is expected from a remote function call or only a single * boolean parameter needs to be supplied. * *

    Please note that this class is somewhat modelled after Java's primitive * data type wrappers. As for these classes, the XDR data type wrapper classes * follow the concept of values with no identity, so you are not allowed to * change the value after you've created a value object. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:43 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class XdrBoolean implements XdrAble { /** * Constructs and initializes a new XdrBoolean object. * * @param value Boolean value. */ public XdrBoolean(boolean value) { this.value = value; } /** * Constructs and initializes a new XdrBoolean object. */ public XdrBoolean() { this.value = false; } /** * Returns the value of this XdrBoolean object as a boolean * primitive. * * @return The primitive boolean value of this object. */ public boolean booleanValue() { return this.value; } /** * Encodes -- that is: serializes -- a XDR boolean into a XDR stream in * compliance to RFC 1832. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException { xdr.xdrEncodeBoolean(value); } /** * Decodes -- that is: deserializes -- a XDR boolean from a XDR stream in * compliance to RFC 1832. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException { value = xdr.xdrDecodeBoolean(); } /** * The encapsulated boolean value itself. */ private boolean value; } // End of XdrBoolean.java remotetea-1.0.7/src/org/acplt/oncrpc/XdrBufferDecodingStream.java0000644005374700003410000002464210335174714026145 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/XdrBufferDecodingStream.java,v 1.2 2005/11/11 21:06:36 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; import java.io.*; import java.net.*; /** * The XdrBufferDecodingStream class provides the necessary * functionality to {@link XdrDecodingStream} to retrieve XDR packets from * a byte buffer. * * @version $Revision: 1.2 $ $Date: 2005/11/11 21:06:36 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class XdrBufferDecodingStream extends XdrDecodingStream { /** * Construct a new XdrUdpDecodingStream object and associate * it with a buffer containing encoded XDR data. * * @param buffer Buffer containing encoded XDR data. * @param encodedLength Length of encoded XDR data within the buffer. * * @throws IllegalArgumentException if encodedLength is not * a multiple of four. */ public XdrBufferDecodingStream(byte [] buffer, int encodedLength) { setXdrData(buffer, encodedLength); } /** * Construct a new XdrUdpDecodingStream object and associate * it with a buffer containing encoded XDR data. * * @param buffer Buffer containing encoded XDR data. * * @throws IllegalArgumentException if the size of the buffer is not * a multiple of four. */ public XdrBufferDecodingStream(byte [] buffer) { setXdrData(buffer, buffer.length); } /** * Sets the buffer containing encoded XDR data as well as the length of * the encoded data. * * @param buffer Buffer containing encoded XDR data. * @param encodedLength Length of encoded XDR data within the buffer. * * @throws IllegalArgumentException if encodedLength is not * a multiple of four. */ public void setXdrData(byte [] buffer, int encodedLength) { // // Make sure that the buffer size is a multiple of four, otherwise // throw an exception. // if ( (encodedLength < 0) || (encodedLength & 3) != 0 ) { throw(new IllegalArgumentException("length of encoded data must be a multiple of four and must not be negative")); } this.buffer = buffer; this.encodedLength = encodedLength; bufferIndex = 0; bufferHighmark = -4; } /** * Returns the Internet address of the sender of the current XDR data. * This method should only be called after {@link #beginDecoding}, * otherwise it might return stale information. * * @return InetAddress of the sender of the current XDR data. */ public InetAddress getSenderAddress() { return null; } /** * Returns the port number of the sender of the current XDR data. * This method should only be called after {@link #beginDecoding}, * otherwise it might return stale information. * * @return Port number of the sender of the current XDR data. */ public int getSenderPort() { return 0; } /** * Initiates decoding of the next XDR record. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void beginDecoding() throws OncRpcException, IOException { bufferIndex = 0; bufferHighmark = encodedLength - 4; } /** * End decoding of the current XDR record. The general contract of * endDecoding is that calling it is an indication that * the current record is no more interesting to the caller and any * allocated data for this record can be freed. * *

    This method overrides {@link XdrDecodingStream#endDecoding}. It does nothing * more than resetting the buffer pointer (eeek! a pointer in Java!!!) back * to the begin of an empty buffer, so attempts to decode data will fail * until the buffer is filled again. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void endDecoding() throws OncRpcException, IOException { bufferIndex = 0; bufferHighmark = -4; } /** * Closes this decoding XDR stream and releases any system resources * associated with this stream. A closed XDR stream cannot perform decoding * operations and cannot be reopened. * *

    This implementation frees the allocated buffer. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void close() throws OncRpcException, IOException { buffer = null; } /** * Decodes (aka "deserializes") a "XDR int" value received from a * XDR stream. A XDR int is 32 bits wide -- the same width Java's "int" * data type has. * * @return The decoded int value. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public int xdrDecodeInt() throws OncRpcException, IOException { if ( bufferIndex <= bufferHighmark ) { // // There's enough space in the buffer to hold at least one // XDR int. So let's retrieve it now. // Note: buffer[...] gives a byte, which is signed. So if we // add it to the value (which is int), it has to be widened // to 32 bit, so its sign is propagated. To avoid this sign // madness, we have to "and" it with 0xFF, so all unwanted // bits are cut off after sign extension. Sigh. // int value = buffer[bufferIndex++]; value = (value << 8) + (buffer[bufferIndex++] & 0xFF); value = (value << 8) + (buffer[bufferIndex++] & 0xFF); value = (value << 8) + (buffer[bufferIndex++] & 0xFF); return value; } else { throw(new OncRpcException(OncRpcException.RPC_BUFFERUNDERFLOW)); } } /** * Decodes (aka "deserializes") an opaque value, which is nothing more * than a series of octets (or 8 bits wide bytes). Because the length * of the opaque value is given, we don't need to retrieve it from the * XDR stream. This is different from * {@link #xdrDecodeOpaque(byte[], int, int)} where * first the length of the opaque value is retrieved from the XDR stream. * * @param length Length of opaque data to decode. * * @return Opaque data as a byte vector. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public byte [] xdrDecodeOpaque(int length) throws OncRpcException, IOException { // // First make sure that the length is always a multiple of four. // int alignedLength = length; if ( (alignedLength & 3) != 0 ) { alignedLength = (alignedLength & ~3) + 4; } // // Now allocate enough memory to hold the data to be retrieved. // byte [] bytes = new byte[length]; if ( length > 0 ) { if ( bufferIndex <= bufferHighmark - alignedLength + 4 ) { System.arraycopy(buffer, bufferIndex, bytes, 0, length); } else { throw(new OncRpcException(OncRpcException.RPC_BUFFERUNDERFLOW)); } } bufferIndex += alignedLength; return bytes; } /** * Decodes (aka "deserializes") a XDR opaque value, which is represented * by a vector of byte values, and starts at offset with a * length of length. Only the opaque value is decoded, so the * caller has to know how long the opaque value will be. The decoded data * is always padded to be a multiple of four (because that's what the * sender does). * * @param opaque Byte vector which will receive the decoded opaque value. * @param offset Start offset in the byte vector. * @param length the number of bytes to decode. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrDecodeOpaque(byte [] opaque, int offset, int length) throws OncRpcException, IOException { // // First make sure that the length is always a multiple of four. // int alignedLength = length; if ( (alignedLength & 3) != 0 ) { alignedLength = (alignedLength & ~3) + 4; } // // Now allocate enough memory to hold the data to be retrieved. // if ( length > 0 ) { if ( bufferIndex <= bufferHighmark - alignedLength + 4 ) { System.arraycopy(buffer, bufferIndex, opaque, offset, length); } else { throw(new OncRpcException(OncRpcException.RPC_BUFFERUNDERFLOW)); } } bufferIndex += alignedLength; } /** * The buffer which will be filled from the datagram socket and then * be used to supply the information when decoding data. */ private byte [] buffer; /** * Length of encoded data in buffer. */ private int encodedLength; /** * The read pointer is an index into the buffer. */ private int bufferIndex; /** * Index of the last four byte word in the buffer, which has been read * in from the datagram socket. */ private int bufferHighmark; } // End of XdrBufferDecodingStream.java remotetea-1.0.7/src/org/acplt/oncrpc/XdrBufferEncodingStream.java0000644005374700003410000001773407716652732026175 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/XdrBufferEncodingStream.java,v 1.2 2003/08/14 11:26:50 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; import java.io.*; import java.net.*; /** * The XdrBufferEncodingStream class provides a buffer-based * XDR stream. * * @version $Revision: 1.2 $ $Date: 2003/08/14 11:26:50 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class XdrBufferEncodingStream extends XdrEncodingStream { /** * Constructs a new XdrBufferEncodingStream with a buffer * to encode data into of the given size. * * @param bufferSize Size of buffer to store encoded data in. */ public XdrBufferEncodingStream(int bufferSize) { if ( (bufferSize < 0) || (bufferSize & 3) != 0 ) { throw(new IllegalArgumentException("size of buffer must be a multiple of four and must not be negative")); } this.buffer = new byte[bufferSize]; bufferIndex = 0; bufferHighmark = buffer.length - 4; } /** * Constructs a new XdrBufferEncodingStream with a given * buffer. * * @param buffer Buffer to store encoded information in. * * @throws IllegalArgumentException if encodedLength is not * a multiple of four. */ public XdrBufferEncodingStream(byte [] buffer) { // // Make sure that the buffer size is a multiple of four, otherwise // throw an exception. // if ( (buffer.length & 3) != 0 ) { throw(new IllegalArgumentException("size of buffer must be a multiple of four")); } this.buffer = buffer; bufferIndex = 0; bufferHighmark = buffer.length - 4; } /** * Returns the amount of encoded data in the buffer. * * @return length of data encoded in buffer. */ public int getXdrLength() { return bufferIndex; } /** * Returns the buffer holding encoded data. * * @return Buffer with encoded data. */ public byte [] getXdrData() { return buffer; } /** * Begins encoding a new XDR record. This involves resetting this * encoding XDR stream back into a known state. * * @param receiverAddress Indicates the receiver of the XDR data. This can be * null for XDR streams connected permanently to a * receiver (like in case of TCP/IP based XDR streams). * @param receiverPort Port number of the receiver. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void beginEncoding(InetAddress receiverAddress, int receiverPort) throws OncRpcException, IOException { bufferIndex = 0; } /** * Flushes this encoding XDR stream and forces any buffered output bytes * to be written out. The general contract of endEncoding is that * calling it is an indication that the current record is finished and any * bytes previously encoded should immediately be written to their intended * destination. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void endEncoding() throws OncRpcException, IOException { } /** * Closes this encoding XDR stream and releases any system resources * associated with this stream. The general contract of close * is that it closes the encoding XDR stream. A closed XDR stream cannot * perform encoding operations and cannot be reopened. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void close() throws OncRpcException, IOException { buffer = null; } /** * Encodes (aka "serializes") a "XDR int" value and writes it down a * XDR stream. A XDR int is 32 bits wide -- the same width Java's "int" * data type has. This method is one of the basic methods all other * methods can rely on. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrEncodeInt(int value) throws OncRpcException, IOException { if ( bufferIndex <= bufferHighmark ) { // // There's enough space in the buffer, so encode this int as // four bytes (french octets) in big endian order (that is, the // most significant byte comes first. // buffer[bufferIndex++] = (byte)(value >>> 24); buffer[bufferIndex++] = (byte)(value >>> 16); buffer[bufferIndex++] = (byte)(value >>> 8); buffer[bufferIndex++] = (byte) value; } else { throw(new OncRpcException(OncRpcException.RPC_BUFFEROVERFLOW)); } } /** * Encodes (aka "serializes") a XDR opaque value, which is represented * by a vector of byte values, and starts at offset with a * length of length. Only the opaque value is encoded, but * no length indication is preceeding the opaque value, so the receiver * has to know how long the opaque value will be. The encoded data is * always padded to be a multiple of four. If the given length is not a * multiple of four, zero bytes will be used for padding. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrEncodeOpaque(byte [] value, int offset, int length) throws OncRpcException, IOException { // // First calculate the number of bytes needed for padding. // int padding = (4 - (length & 3)) & 3; if ( bufferIndex <= bufferHighmark - (length + padding) ) { System.arraycopy(value, offset, buffer, bufferIndex, length); bufferIndex += length; if ( padding != 0 ) { // // If the length of the opaque data was not a multiple, then // pad with zeros, so the write pointer (argh! how comes Java // has a pointer...?!) points to a byte, which has an index // of a multiple of four. // System.arraycopy(paddingZeros, 0, buffer, bufferIndex, padding); bufferIndex += padding; } } else { throw(new OncRpcException(OncRpcException.RPC_BUFFEROVERFLOW)); } } /** * The buffer which will receive the encoded information, before it * is sent via a datagram socket. */ private byte [] buffer; /** * The write pointer is an index into the buffer. */ private int bufferIndex; /** * Index of the last four byte word in the buffer. */ private int bufferHighmark; /** * Some zeros, only needed for padding -- like in real life. */ private static final byte [] paddingZeros = { 0, 0, 0, 0 }; } // End of XdrBufferEncodingStream.java remotetea-1.0.7/src/org/acplt/oncrpc/XdrByte.java0000644005374700003410000000631307716406400023020 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/XdrByte.java,v 1.1.1.1 2003/08/13 12:03:43 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; import java.io.IOException; /** * Instances of the class XdrByte represent (de-)serializeable * bytes, which are especially useful in cases where a result with only a * single byte is expected from a remote function call or only a single * byte parameter needs to be supplied. * *

    Please note that this class is somewhat modelled after Java's primitive * data type wrappers. As for these classes, the XDR data type wrapper classes * follow the concept of values with no identity, so you are not allowed to * change the value after you've created a value object. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:43 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class XdrByte implements XdrAble { /** * Constructs and initializes a new XdrByte object. * * @param value Byte value. */ public XdrByte(byte value) { this.value = value; } /** * Constructs and initializes a new XdrByte object. */ public XdrByte() { this.value = 0; } /** * Returns the value of this XdrByte object as a byte * primitive. * * @return The primitive byte value of this object. */ public byte byteValue() { return this.value; } /** * Encodes -- that is: serializes -- a XDR byte into a XDR stream in * compliance to RFC 1832. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException { xdr.xdrEncodeByte(value); } /** * Decodes -- that is: deserializes -- a XDR byte from a XDR stream in * compliance to RFC 1832. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException { value = xdr.xdrDecodeByte(); } /** * The encapsulated byte value itself. */ private byte value; } // End of XdrByte.javaremotetea-1.0.7/src/org/acplt/oncrpc/XdrBytes.java0000644005374700003410000000642107716406400023203 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/XdrBytes.java,v 1.1.1.1 2003/08/13 12:03:43 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; import java.io.IOException; /** * Instances of the class XdrBytes represent (de-)serializeable * bytes values, which are especially useful in cases where a result with only a * single bytes value is expected from a remote function call or only a single * bytes value parameter needs to be supplied. * *

    Please note that this class is somewhat modelled after Java's primitive * data type wrappers. As for these classes, the XDR data type wrapper classes * follow the concept of values with no identity, so you are not allowed to * change the value after you've created a value object. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:43 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class XdrBytes implements XdrAble { /** * Constructs and initializes a new XdrBytes object. * * @param value bytes vector */ public XdrBytes(byte [] value) { this.value = value; } /** * Constructs and initializes a new XdrBytes object. */ public XdrBytes() { this.value = null; } /** * Returns the value of this XdrBytes object as a byte * vector. * * @return The primitive byte[] value of this object. */ public byte [] bytesValue() { return this.value; } /** * Encodes -- that is: serializes -- a XDR bytes value into a XDR stream in * compliance to RFC 1832. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException { xdr.xdrEncodeByteVector(value); } /** * Decodes -- that is: deserializes -- a XDR bytes value from a XDR stream in * compliance to RFC 1832. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException { value = xdr.xdrDecodeByteVector(); } /** * The encapsulated bytes value itself. */ private byte [] value; } // End of XdrBytes.javaremotetea-1.0.7/src/org/acplt/oncrpc/XdrChar.java0000644005374700003410000000633107716406400022772 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/XdrChar.java,v 1.1.1.1 2003/08/13 12:03:44 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; import java.io.IOException; /** * Instances of the class XdrChar represent (de-)serializeable * chars, which are especially useful in cases where a result with only a * single char is expected from a remote function call or only a single * char parameter needs to be supplied. * *

    Please note that this class is somewhat modelled after Java's primitive * data type wrappers. As for these classes, the XDR data type wrapper classes * follow the concept of values with no identity, so you are not allowed to * change the value after you've created a value object. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:44 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class XdrChar implements XdrAble { /** * Constructs and initializes a new XdrChar object. * * @param value Char value. */ public XdrChar(char value) { this.value = value; } /** * Constructs and initializes a new XdrChar object. */ public XdrChar() { this.value = 0; } /** * Returns the value of this XdrChar object as a char * primitive. * * @return The primitive char value of this object. */ public char charValue() { return this.value; } /** * Encodes -- that is: serializes -- a XDR char into a XDR stream in * compliance to RFC 1832. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException { xdr.xdrEncodeByte((byte)value); } /** * Decodes -- that is: deserializes -- a XDR char from a XDR stream in * compliance to RFC 1832. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException { value = (char) xdr.xdrDecodeByte(); } /** * The encapsulated char value itself. */ private char value; } // End of XdrChar.java remotetea-1.0.7/src/org/acplt/oncrpc/XdrDecodingStream.java0000644005374700003410000005357207716673422025030 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/XdrDecodingStream.java,v 1.3 2003/08/14 13:48:33 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; import java.io.IOException; import java.net.InetAddress; /** * Defines the abstract base class for all decoding XDR streams. A decoding * XDR stream returns data in the form of Java data types which it reads * from a data source (for instance, network or memory buffer) in the * platform-independent XDR format. * *

    Derived classes need to implement the {@link #xdrDecodeInt()}, * {@link #xdrDecodeOpaque(int)} and * {@link #xdrDecodeOpaque(byte[], int, int)} methods to make this complete * mess workable. * * @version $Revision: 1.3 $ $Date: 2003/08/14 13:48:33 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public abstract class XdrDecodingStream { /** * Returns the Internet address of the sender of the current XDR data. * This method should only be called after {@link #beginDecoding}, otherwise * it might return stale information. * * @return InetAddress of the sender of the current XDR data. */ public abstract InetAddress getSenderAddress(); /** * Returns the port number of the sender of the current XDR data. * This method should only be called after {@link #beginDecoding}, otherwise * it might return stale information. * * @return Port number of the sender of the current XDR data. */ public abstract int getSenderPort(); /** * Initiates decoding of the next XDR record. This typically involves * filling the internal buffer with the next datagram from the network, or * reading the next chunk of data from a stream-oriented connection. In * case of memory-based communication this might involve waiting for * some other process to fill the buffer and signal availability of new * XDR data. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public abstract void beginDecoding() throws OncRpcException, IOException; /** * End decoding of the current XDR record. The general contract of * endDecoding is that calling it is an indication that * the current record is no more interesting to the caller and any * allocated data for this record can be freed. * *

    The endDecoding method of XdrDecodingStream * does nothing. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void endDecoding() throws OncRpcException, IOException { } /** * Closes this decoding XDR stream and releases any system resources * associated with this stream. The general contract of close * is that it closes the decoding XDR stream. A closed XDR stream cannot * perform decoding operations and cannot be reopened. * *

    The close method of XdrDecodingStream * does nothing. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void close() throws OncRpcException, IOException { } /** * Decodes (aka "deserializes") a "XDR int" value received from a * XDR stream. A XDR int is 32 bits wide -- the same width Java's "int" * data type has. This method is one of the basic methods all other * methods can rely on. Because it's so basic, derived classes have to * implement it. * * @return The decoded int value. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public abstract int xdrDecodeInt() throws OncRpcException, IOException; /** * Decodes (aka "deserializes") an opaque value, which is nothing more * than a series of octets (or 8 bits wide bytes). Because the length * of the opaque value is given, we don't need to retrieve it from the * XDR stream. * *

    Note that this is a basic abstract method, which needs to be * implemented in derived classes. * * @param length Length of opaque data to decode. * * @return Opaque data as a byte vector. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public abstract byte [] xdrDecodeOpaque(int length) throws OncRpcException, IOException; /** * Decodes (aka "deserializes") a XDR opaque value, which is represented * by a vector of byte values, and starts at offset with a * length of length. Only the opaque value is decoded, so the * caller has to know how long the opaque value will be. The decoded data * is always padded to be a multiple of four (because that's what the * sender does). * *

    Derived classes must ensure that the proper semantic is maintained. * * @param opaque Byte vector which will receive the decoded opaque value. * @param offset Start offset in the byte vector. * @param length the number of bytes to decode. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. * @throws IndexOutOfBoundsException if the given opaque * byte vector isn't large enough to receive the result. */ public abstract void xdrDecodeOpaque(byte [] opaque, int offset, int length) throws OncRpcException, IOException; /** * Decodes (aka "deserializes") a XDR opaque value, which is represented * by a vector of byte values. Only the opaque value is decoded, so the * caller has to know how long the opaque value will be. The decoded data * is always padded to be a multiple of four (because that's what the * sender does). * * @param opaque Byte vector which will receive the decoded opaque value. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final void xdrDecodeOpaque(byte [] opaque) throws OncRpcException, IOException { xdrDecodeOpaque(opaque, 0, opaque.length); } /** * Decodes (aka "deserializes") a XDR opaque value, which is represented * by a vector of byte values. The length of the opaque value to decode * is pulled off of the XDR stream, so the caller does not need to know * the exact length in advance. The decoded data is always padded to be * a multiple of four (because that's what the sender does). * * @return The byte vector containing the decoded data. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final byte [] xdrDecodeDynamicOpaque() throws OncRpcException, IOException { int length = xdrDecodeInt(); byte [] opaque = new byte[length]; if ( length != 0 ) { xdrDecodeOpaque(opaque); } return opaque; } /** * Decodes (aka "deserializes") a vector of bytes, which is nothing more * than a series of octets (or 8 bits wide bytes), each packed into its * very own 4 bytes (XDR int). Byte vectors are decoded together with a * preceeding length value. This way the receiver doesn't need to know * the length of the vector in advance. * * @return The byte vector containing the decoded data. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final byte [] xdrDecodeByteVector() throws OncRpcException, IOException { int length = xdrDecodeInt(); if ( length > 0 ) { byte [] bytes = new byte[length]; for ( int i = 0; i < length; ++i ) { bytes[i] = (byte) xdrDecodeInt(); } return bytes; } else { return new byte[0]; } } /** * Decodes (aka "deserializes") a vector of bytes, which is nothing more * than a series of octets (or 8 bits wide bytes), each packed into its * very own 4 bytes (XDR int). * * @param length of vector to read. * * @return The byte vector containing the decoded data. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final byte [] xdrDecodeByteFixedVector(int length) throws OncRpcException, IOException { if ( length > 0 ) { byte [] bytes = new byte[length]; for ( int i = 0; i < length; ++i ) { bytes[i] = (byte) xdrDecodeInt(); } return bytes; } else { return new byte[0]; } } /** * Decodes (aka "deserializes") a byte read from this XDR stream. * * @return Decoded byte value. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final byte xdrDecodeByte() throws OncRpcException, IOException { return (byte) xdrDecodeInt(); } /** * Decodes (aka "deserializes") a short (which is a 16 bit quantity) * read from this XDR stream. * * @return Decoded short value. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final short xdrDecodeShort() throws OncRpcException, IOException { return (short) xdrDecodeInt(); } /** * Decodes (aka "deserializes") a long (which is called a "hyper" in XDR * babble and is 64 bits wide) read from a XDR stream. * * @return Decoded long value. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final long xdrDecodeLong() throws OncRpcException, IOException { // // Similiar to xdrEncodeLong: just read in two ints in network order. // return (((long) xdrDecodeInt()) << 32) + (((long) xdrDecodeInt()) & 0x00000000FFFFFFFFl); } /** * Decodes (aka "deserializes") a float (which is a 32 bits wide floating * point entity) read from a XDR stream. * * @return Decoded float value. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final float xdrDecodeFloat() throws OncRpcException, IOException { return Float.intBitsToFloat(xdrDecodeInt()); } /** * Decodes (aka "deserializes") a double (which is a 64 bits wide floating * point entity) read from a XDR stream. * * @return Decoded double value. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final double xdrDecodeDouble() throws OncRpcException, IOException { return Double.longBitsToDouble(xdrDecodeLong()); } /** * Decodes (aka "deserializes") a boolean read from a XDR stream. * * @return Decoded boolean value. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final boolean xdrDecodeBoolean() throws OncRpcException, IOException { return xdrDecodeInt() != 0 ? true : false; } /** * Decodes (aka "deserializes") a string read from a XDR stream. * If a character encoding has been set for this stream, then this * will be used for conversion. * * @return Decoded String value. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final String xdrDecodeString() throws OncRpcException, IOException { int length = xdrDecodeInt(); if ( length > 0 ) { byte [] bytes = new byte[length]; xdrDecodeOpaque(bytes, 0, length); return (characterEncoding != null) ? new String(bytes, characterEncoding) : new String(bytes); } else { return new String(); } } /** * Decodes (aka "deserializes") a vector of short integers read from a * XDR stream. * * @return Decoded vector of short integers. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final short [] xdrDecodeShortVector() throws OncRpcException, IOException { int length = xdrDecodeInt(); short [] value = new short[length]; for ( int i = 0; i < length; ++i ) { value[i] = xdrDecodeShort(); } return value; } /** * Decodes (aka "deserializes") a vector of short integers read from a * XDR stream. * * @param length of vector to read. * * @return Decoded vector of short integers. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final short [] xdrDecodeShortFixedVector(int length) throws OncRpcException, IOException { short [] value = new short[length]; for ( int i = 0; i < length; ++i ) { value[i] = xdrDecodeShort(); } return value; } /** * Decodes (aka "deserializes") a vector of ints read from a XDR stream. * * @return Decoded int vector. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final int [] xdrDecodeIntVector() throws OncRpcException, IOException { int length = xdrDecodeInt(); int [] value = new int[length]; for ( int i = 0; i < length; ++i ) { value[i] = xdrDecodeInt(); } return value; } /** * Decodes (aka "deserializes") a vector of ints read from a XDR stream. * * @param length of vector to read. * * @return Decoded int vector. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final int [] xdrDecodeIntFixedVector(int length) throws OncRpcException, IOException { int [] value = new int[length]; for ( int i = 0; i < length; ++i ) { value[i] = xdrDecodeInt(); } return value; } /** * Decodes (aka "deserializes") a vector of longs read from a XDR stream. * * @return Decoded long vector. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final long [] xdrDecodeLongVector() throws OncRpcException, IOException { int length = xdrDecodeInt(); long [] value = new long[length]; for ( int i = 0; i < length; ++i ) { value[i] = xdrDecodeLong(); } return value; } /** * Decodes (aka "deserializes") a vector of longs read from a XDR stream. * * @param length of vector to read. * * @return Decoded long vector. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final long [] xdrDecodeLongFixedVector(int length) throws OncRpcException, IOException { long [] value = new long[length]; for ( int i = 0; i < length; ++i ) { value[i] = xdrDecodeLong(); } return value; } /** * Decodes (aka "deserializes") a vector of floats read from a XDR stream. * * @return Decoded float vector. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final float [] xdrDecodeFloatVector() throws OncRpcException, IOException { int length = xdrDecodeInt(); float [] value = new float[length]; for ( int i = 0; i < length; ++i ) { value[i] = xdrDecodeFloat(); } return value; } /** * Decodes (aka "deserializes") a vector of floats read from a XDR stream. * * @param length of vector to read. * * @return Decoded float vector. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final float [] xdrDecodeFloatFixedVector(int length) throws OncRpcException, IOException { float [] value = new float[length]; for ( int i = 0; i < length; ++i ) { value[i] = xdrDecodeFloat(); } return value; } /** * Decodes (aka "deserializes") a vector of doubles read from a XDR stream. * * @return Decoded double vector. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final double [] xdrDecodeDoubleVector() throws OncRpcException, IOException { int length = xdrDecodeInt(); double [] value = new double[length]; for ( int i = 0; i < length; ++i ) { value[i] = xdrDecodeDouble(); } return value; } /** * Decodes (aka "deserializes") a vector of doubles read from a XDR stream. * * @param length of vector to read. * * @return Decoded double vector. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final double [] xdrDecodeDoubleFixedVector(int length) throws OncRpcException, IOException { double [] value = new double[length]; for ( int i = 0; i < length; ++i ) { value[i] = xdrDecodeDouble(); } return value; } /** * Decodes (aka "deserializes") a vector of booleans read from a XDR stream. * * @return Decoded boolean vector. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final boolean [] xdrDecodeBooleanVector() throws OncRpcException, IOException { int length = xdrDecodeInt(); boolean [] value = new boolean[length]; for ( int i = 0; i < length; ++i ) { value[i] = xdrDecodeBoolean(); } return value; } /** * Decodes (aka "deserializes") a vector of booleans read from a XDR stream. * * @param length of vector to read. * * @return Decoded boolean vector. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final boolean [] xdrDecodeBooleanFixedVector(int length) throws OncRpcException, IOException { boolean [] value = new boolean[length]; for ( int i = 0; i < length; ++i ) { value[i] = xdrDecodeBoolean(); } return value; } /** * Decodes (aka "deserializes") a vector of strings read from a XDR stream. * * @return Decoded String vector. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final String [] xdrDecodeStringVector() throws OncRpcException, IOException { int length = xdrDecodeInt(); String [] value = new String[length]; for ( int i = 0; i < length; ++i ) { value[i] = xdrDecodeString(); } return value; } /** * Decodes (aka "deserializes") a vector of strings read from a XDR stream. * * @param length of vector to read. * * @return Decoded String vector. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final String [] xdrDecodeStringFixedVector(int length) throws OncRpcException, IOException { String [] value = new String[length]; for ( int i = 0; i < length; ++i ) { value[i] = xdrDecodeString(); } return value; } /** * Set the character encoding for deserializing strings. * * @param characterEncoding the encoding to use for deserializing strings. * If null, the system's default encoding is to be used. */ public void setCharacterEncoding(String characterEncoding) { this.characterEncoding = characterEncoding; } /** * Get the character encoding for deserializing strings. * * @return the encoding currently used for deserializing strings. * If null, then the system's default encoding is used. */ public String getCharacterEncoding() { return characterEncoding; } /** * Encoding to use when deserializing strings or null if * the system's default encoding should be used. */ private String characterEncoding = null; } // End of XdrDecodingStream.java remotetea-1.0.7/src/org/acplt/oncrpc/XdrDouble.java0000644005374700003410000000637307716406400023335 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/XdrDouble.java,v 1.1.1.1 2003/08/13 12:03:44 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; import java.io.IOException; /** * Instances of the class XdrDouble represent (de-)serializeable * doubles, which are especially useful in cases where a result with only a * single double is expected from a remote function call or only a single * double parameter needs to be supplied. * *

    Please note that this class is somewhat modelled after Java's primitive * data type wrappers. As for these classes, the XDR data type wrapper classes * follow the concept of values with no identity, so you are not allowed to * change the value after you've created a value object. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:44 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class XdrDouble implements XdrAble { /** * Constructs and initializes a new XdrDouble object. * * @param value Double value. */ public XdrDouble(double value) { this.value = value; } /** * Constructs and initializes a new XdrDouble object. */ public XdrDouble() { this.value = 0; } /** * Returns the value of this XdrDouble object as a double * primitive. * * @return The primitive double value of this object. */ public double doubleValue() { return this.value; } /** * Encodes -- that is: serializes -- a XDR double into a XDR stream in * compliance to RFC 1832. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException { xdr.xdrEncodeDouble(value); } /** * Decodes -- that is: deserializes -- a XDR double from a XDR stream in * compliance to RFC 1832. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException { value = xdr.xdrDecodeDouble(); } /** * The encapsulated double value itself. */ private double value; } // End of XdrDouble.javaremotetea-1.0.7/src/org/acplt/oncrpc/XdrDynamicOpaque.java0000644005374700003410000000650607716406400024660 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/XdrDynamicOpaque.java,v 1.1.1.1 2003/08/13 12:03:44 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; import java.io.IOException; /** * Instances of the class XdrDynamicOpaque represent (de-)serializeable * dynamic-size opaque values, which are especially useful in cases where a result with only a * single opaque value is expected from a remote function call or only a single * opaque value parameter needs to be supplied. * *

    Please note that this class is somewhat modelled after Java's primitive * data type wrappers. As for these classes, the XDR data type wrapper classes * follow the concept of values with no identity, so you are not allowed to * change the value after you've created a value object. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:44 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class XdrDynamicOpaque implements XdrAble { /** * Constructs and initializes a new XdrDynamicOpaque object. */ public XdrDynamicOpaque() { this.value = null; } /** * Constructs and initializes a new XdrDynamicOpaque object. */ public XdrDynamicOpaque(byte [] value) { this.value = value; } /** * Returns the value of this XdrDynamicOpaque object as a byte * vector. * * @return The primitive byte[] value of this object. */ public byte [] dynamicOpaqueValue() { return this.value; } /** * Encodes -- that is: serializes -- a XDR opaque into a XDR stream in * compliance to RFC 1832. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException { xdr.xdrEncodeDynamicOpaque(value); } /** * Decodes -- that is: deserializes -- a XDR opaque from a XDR stream in * compliance to RFC 1832. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException { value = xdr.xdrDecodeDynamicOpaque(); } /** * The encapsulated opaque value itself. */ private byte [] value; } // End of XdrDynamicOpaque.javaremotetea-1.0.7/src/org/acplt/oncrpc/XdrEncodingStream.java0000644005374700003410000006042207716673422025032 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/XdrEncodingStream.java,v 1.2 2003/08/14 13:48:33 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; import java.io.IOException; import java.net.InetAddress; /** * Defines the abstract base class for all encoding XDR streams. An encoding * XDR stream receives data in the form of Java data types and writes it to * a data sink (for instance, network or memory buffer) in the * platform-independent XDR format. * *

    Derived classes need to implement the {@link #xdrEncodeInt(int)}, * {@link #xdrEncodeOpaque(byte[])} and * {@link #xdrEncodeOpaque(byte[], int, int)} methods to make this complete * mess workable. * * @version $Revision: 1.2 $ $Date: 2003/08/14 13:48:33 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public abstract class XdrEncodingStream { /** * Begins encoding a new XDR record. This typically involves resetting this * encoding XDR stream back into a known state. * * @param receiverAddress Indicates the receiver of the XDR data. This can * be null for XDR streams connected permanently to a * receiver (like in case of TCP/IP based XDR streams). * @param receiverPort Port number of the receiver. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void beginEncoding(InetAddress receiverAddress, int receiverPort) throws OncRpcException, IOException { } /** * Flushes this encoding XDR stream and forces any buffered output bytes * to be written out. The general contract of endEncoding is that * calling it is an indication that the current record is finished and any * bytes previously encoded should immediately be written to their intended * destination. * *

    The endEncoding method of XdrEncodingStream * does nothing. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void endEncoding() throws OncRpcException, IOException { } /** * Closes this encoding XDR stream and releases any system resources * associated with this stream. The general contract of close * is that it closes the encoding XDR stream. A closed XDR stream cannot * perform encoding operations and cannot be reopened. * *

    The close method of XdrEncodingStream * does nothing. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void close() throws OncRpcException, IOException { } /** * Encodes (aka "serializes") a "XDR int" value and writes it down a * XDR stream. A XDR int is 32 bits wide -- the same width Java's "int" * data type has. This method is one of the basic methods all other * methods can rely on. Because it's so basic, derived classes have to * implement it. * * @param value The int value to be encoded. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public abstract void xdrEncodeInt(int value) throws OncRpcException, IOException; /** * Encodes (aka "serializes") a XDR opaque value, which is represented * by a vector of byte values, and starts at offset with a * length of length. Only the opaque value is encoded, but * no length indication is preceeding the opaque value, so the receiver * has to know how long the opaque value will be. The encoded data is * always padded to be a multiple of four. If the given length is not a * multiple of four, zero bytes will be used for padding. * *

    Derived classes must ensure that the proper semantic is maintained. * * @param value The opaque value to be encoded in the form of a series of * bytes. * @param offset Start offset in the data. * @param length the number of bytes to encode. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public abstract void xdrEncodeOpaque(byte [] value, int offset, int length) throws OncRpcException, IOException; /** * Encodes (aka "serializes") a XDR opaque value, which is represented * by a vector of byte values. The length of the opaque value is written * to the XDR stream, so the receiver does not need to know * the exact length in advance. The encoded data is always padded to be * a multiple of four to maintain XDR alignment. * * @param value The opaque value to be encoded in the form of a series of * bytes. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final void xdrEncodeDynamicOpaque(byte [] value) throws OncRpcException, IOException { xdrEncodeInt(value.length); xdrEncodeOpaque(value); } /** * Encodes (aka "serializes") a XDR opaque value, which is represented * by a vector of byte values. Only the opaque value is encoded, but * no length indication is preceeding the opaque value, so the receiver * has to know how long the opaque value will be. The encoded data is * always padded to be a multiple of four. If the length of the given byte * vector is not a multiple of four, zero bytes will be used for padding. * * @param value The opaque value to be encoded in the form of a series of * bytes. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final void xdrEncodeOpaque(byte [] value) throws OncRpcException, IOException { xdrEncodeOpaque(value, 0, value.length); } /** * Encodes (aka "serializes") a XDR opaque value, which is represented * by a vector of byte values. Only the opaque value is encoded, but * no length indication is preceeding the opaque value, so the receiver * has to know how long the opaque value will be. The encoded data is * always padded to be a multiple of four. If the length of the given byte * vector is not a multiple of four, zero bytes will be used for padding. * * @param value The opaque value to be encoded in the form of a series of * bytes. * @param length of vector to write. This parameter is used as a sanity * check. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. * @throws IllegalArgumentException if the length of the vector does not * match the specified length. */ public final void xdrEncodeOpaque(byte [] value, int length) throws OncRpcException, IOException { if ( value.length != length ) { throw(new IllegalArgumentException("array size does not match protocol specification")); } xdrEncodeOpaque(value, 0, value.length); } /** * Encodes (aka "serializes") a vector of bytes, which is nothing more * than a series of octets (or 8 bits wide bytes), each packed into its * very own 4 bytes (XDR int). Byte vectors are encoded together with a * preceeding length value. This way the receiver doesn't need to know * the length of the vector in advance. * * @param value Byte vector to encode. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final void xdrEncodeByteVector(byte [] value) throws OncRpcException, IOException { int length = value.length; // well, silly optimizations appear here... xdrEncodeInt(length); if ( length != 0 ) { // // For speed reasons, we do sign extension here, but the higher bits // will be removed again when deserializing. // for ( int i = 0; i < length; ++i ) { xdrEncodeInt((int) value[i]); } } } /** * Encodes (aka "serializes") a vector of bytes, which is nothing more * than a series of octets (or 8 bits wide bytes), each packed into its * very own 4 bytes (XDR int). * * @param value Byte vector to encode. * @param length of vector to write. This parameter is used as a sanity * check. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. * @throws IllegalArgumentException if the length of the vector does not * match the specified length. */ public final void xdrEncodeByteFixedVector(byte [] value, int length) throws OncRpcException, IOException { if ( value.length != length ) { throw(new IllegalArgumentException("array size does not match protocol specification")); } if ( length != 0 ) { // // For speed reasons, we do sign extension here, but the higher bits // will be removed again when deserializing. // for ( int i = 0; i < length; ++i ) { xdrEncodeInt((int) value[i]); } } } /** * Encodes (aka "serializes") a byte and write it down this XDR stream. * * @param value Byte value to encode. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final void xdrEncodeByte(byte value) throws OncRpcException, IOException { // // For speed reasons, we do sign extension here, but the higher bits // will be removed again when deserializing. // xdrEncodeInt((int) value); } /** * Encodes (aka "serializes") a short (which is a 16 bits wide quantity) * and write it down this XDR stream. * * @param value Short value to encode. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final void xdrEncodeShort(short value) throws OncRpcException, IOException { xdrEncodeInt((int) value); } /** * Encodes (aka "serializes") a long (which is called a "hyper" in XDR * babble and is 64 bits wide) and write it down this XDR stream. * * @param value Long value to encode. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final void xdrEncodeLong(long value) throws OncRpcException, IOException { // // Just encode the long (which is called a "hyper" in XDR babble) as // two ints in network order, that is: big endian with the high int // comming first. // xdrEncodeInt((int)(value >>> 32)); xdrEncodeInt((int)(value & 0xFFFFFFFF)); } /** * Encodes (aka "serializes") a float (which is a 32 bits wide floating * point quantity) and write it down this XDR stream. * * @param value Float value to encode. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final void xdrEncodeFloat(float value) throws OncRpcException, IOException { xdrEncodeInt(Float.floatToIntBits(value)); } /** * Encodes (aka "serializes") a double (which is a 64 bits wide floating * point quantity) and write it down this XDR stream. * * @param value Double value to encode. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final void xdrEncodeDouble(double value) throws OncRpcException, IOException { xdrEncodeLong(Double.doubleToLongBits(value)); } /** * Encodes (aka "serializes") a boolean and writes it down this XDR stream. * * @param value Boolean value to be encoded. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final void xdrEncodeBoolean(boolean value) throws OncRpcException, IOException { xdrEncodeInt(value ? 1 : 0); } /** * Encodes (aka "serializes") a string and writes it down this XDR stream. * * @param value String value to be encoded. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final void xdrEncodeString(String value) throws OncRpcException, IOException { if ( characterEncoding != null ) { xdrEncodeDynamicOpaque(value.getBytes(characterEncoding)); } else { xdrEncodeDynamicOpaque(value.getBytes()); } } /** * Encodes (aka "serializes") a vector of short integers and writes it down * this XDR stream. * * @param value short vector to be encoded. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final void xdrEncodeShortVector(short [] value) throws OncRpcException, IOException { int size = value.length; xdrEncodeInt(size); for ( int i = 0; i < size; i++ ) { xdrEncodeShort(value[i]); } } /** * Encodes (aka "serializes") a vector of short integers and writes it down * this XDR stream. * * @param value short vector to be encoded. * @param length of vector to write. This parameter is used as a sanity * check. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. * @throws IllegalArgumentException if the length of the vector does not * match the specified length. */ public final void xdrEncodeShortFixedVector(short [] value, int length) throws OncRpcException, IOException { if ( value.length != length ) { throw(new IllegalArgumentException("array size does not match protocol specification")); } for ( int i = 0; i < length; i++ ) { xdrEncodeShort(value[i]); } } /** * Encodes (aka "serializes") a vector of ints and writes it down * this XDR stream. * * @param value int vector to be encoded. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final void xdrEncodeIntVector(int [] value) throws OncRpcException, IOException { int size = value.length; xdrEncodeInt(size); for ( int i = 0; i < size; i++ ) { xdrEncodeInt(value[i]); } } /** * Encodes (aka "serializes") a vector of ints and writes it down * this XDR stream. * * @param value int vector to be encoded. * @param length of vector to write. This parameter is used as a sanity * check. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. * @throws IllegalArgumentException if the length of the vector does not * match the specified length. */ public final void xdrEncodeIntFixedVector(int [] value, int length) throws OncRpcException, IOException { if ( value.length != length ) { throw(new IllegalArgumentException("array size does not match protocol specification")); } for ( int i = 0; i < length; i++ ) { xdrEncodeInt(value[i]); } } /** * Encodes (aka "serializes") a vector of long integers and writes it down * this XDR stream. * * @param value long vector to be encoded. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final void xdrEncodeLongVector(long [] value) throws OncRpcException, IOException { int size = value.length; xdrEncodeInt(size); for ( int i = 0; i < size; i++ ) { xdrEncodeLong(value[i]); } } /** * Encodes (aka "serializes") a vector of long integers and writes it down * this XDR stream. * * @param value long vector to be encoded. * @param length of vector to write. This parameter is used as a sanity * check. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. * @throws IllegalArgumentException if the length of the vector does not * match the specified length. */ public final void xdrEncodeLongFixedVector(long [] value, int length) throws OncRpcException, IOException { if ( value.length != length ) { throw(new IllegalArgumentException("array size does not match protocol specification")); } for ( int i = 0; i < length; i++ ) { xdrEncodeLong(value[i]); } } /** * Encodes (aka "serializes") a vector of floats and writes it down * this XDR stream. * * @param value float vector to be encoded. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final void xdrEncodeFloatVector(float [] value) throws OncRpcException, IOException { int size = value.length; xdrEncodeInt(size); for ( int i = 0; i < size; i++ ) { xdrEncodeFloat(value[i]); } } /** * Encodes (aka "serializes") a vector of floats and writes it down * this XDR stream. * * @param value float vector to be encoded. * @param length of vector to write. This parameter is used as a sanity * check. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. * @throws IllegalArgumentException if the length of the vector does not * match the specified length. */ public final void xdrEncodeFloatFixedVector(float [] value, int length) throws OncRpcException, IOException { if ( value.length != length ) { throw(new IllegalArgumentException("array size does not match protocol specification")); } for ( int i = 0; i < length; i++ ) { xdrEncodeFloat(value[i]); } } /** * Encodes (aka "serializes") a vector of doubles and writes it down * this XDR stream. * * @param value double vector to be encoded. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final void xdrEncodeDoubleVector(double [] value) throws OncRpcException, IOException { int size = value.length; xdrEncodeInt(size); for ( int i = 0; i < size; i++ ) { xdrEncodeDouble(value[i]); } } /** * Encodes (aka "serializes") a vector of doubles and writes it down * this XDR stream. * * @param value double vector to be encoded. * @param length of vector to write. This parameter is used as a sanity * check. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. * @throws IllegalArgumentException if the length of the vector does not * match the specified length. */ public final void xdrEncodeDoubleFixedVector(double [] value, int length) throws OncRpcException, IOException { if ( value.length != length ) { throw(new IllegalArgumentException("array size does not match protocol specification")); } for ( int i = 0; i < length; i++ ) { xdrEncodeDouble(value[i]); } } /** * Encodes (aka "serializes") a vector of booleans and writes it down * this XDR stream. * * @param value long vector to be encoded. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final void xdrEncodeBooleanVector(boolean [] value) throws OncRpcException, IOException { int size = value.length; xdrEncodeInt(size); for ( int i = 0; i < size; i++ ) { xdrEncodeBoolean(value[i]); } } /** * Encodes (aka "serializes") a vector of booleans and writes it down * this XDR stream. * * @param value long vector to be encoded. * @param length of vector to write. This parameter is used as a sanity * check. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. * @throws IllegalArgumentException if the length of the vector does not * match the specified length. */ public final void xdrEncodeBooleanFixedVector(boolean [] value, int length) throws OncRpcException, IOException { if ( value.length != length ) { throw(new IllegalArgumentException("array size does not match protocol specification")); } for ( int i = 0; i < length; i++ ) { xdrEncodeBoolean(value[i]); } } /** * Encodes (aka "serializes") a vector of strings and writes it down * this XDR stream. * * @param value String vector to be encoded. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public final void xdrEncodeStringVector(String [] value) throws OncRpcException, IOException { int size = value.length; xdrEncodeInt(size); for ( int i = 0; i < size; i++ ) { xdrEncodeString(value[i]); } } /** * Encodes (aka "serializes") a vector of strings and writes it down * this XDR stream. * * @param value String vector to be encoded. * @param length of vector to write. This parameter is used as a sanity * check. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. * @throws IllegalArgumentException if the length of the vector does not * match the specified length. */ public final void xdrEncodeStringFixedVector(String [] value, int length) throws OncRpcException, IOException { if ( value.length != length ) { throw(new IllegalArgumentException("array size does not match protocol specification")); } for ( int i = 0; i < length; i++ ) { xdrEncodeString(value[i]); } } /** * Set the character encoding for serializing strings. * * @param characterEncoding the encoding to use for serializing strings. * If null, the system's default encoding is to be used. */ public void setCharacterEncoding(String characterEncoding) { this.characterEncoding = characterEncoding; } /** * Get the character encoding for serializing strings. * * @return the encoding currently used for serializing strings. * If null, then the system's default encoding is used. */ public String getCharacterEncoding() { return characterEncoding; } /** * Encoding to use when serializing strings or null if * the system's default encoding should be used. */ private String characterEncoding = null; } // End of XdrEncodingStream.java remotetea-1.0.7/src/org/acplt/oncrpc/XdrFloat.java0000644005374700003410000000634307716406374023177 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/XdrFloat.java,v 1.1.1.1 2003/08/13 12:03:40 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; import java.io.IOException; /** * Instances of the class XdrFloat represent (de-)serializeable * floats, which are especially useful in cases where a result with only a * single float is expected from a remote function call or only a single * float parameter needs to be supplied. * *

    Please note that this class is somewhat modelled after Java's primitive * data type wrappers. As for these classes, the XDR data type wrapper classes * follow the concept of values with no identity, so you are not allowed to * change the value after you've created a value object. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:40 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class XdrFloat implements XdrAble { /** * Constructs and initializes a new XdrFloat object. * * @param value Float value. */ public XdrFloat(float value) { this.value = value; } /** * Constructs and initializes a new XdrFloat object. */ public XdrFloat() { this.value = 0; } /** * Returns the value of this XdrFloat object as a float * primitive. * * @return The primitive float value of this object. */ public float floatValue() { return this.value; } /** * Encodes -- that is: serializes -- a XDR float into a XDR stream in * compliance to RFC 1832. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException { xdr.xdrEncodeFloat(value); } /** * Decodes -- that is: deserializes -- a XDR float from a XDR stream in * compliance to RFC 1832. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException { value = xdr.xdrDecodeFloat(); } /** * The encapsulated float value itself. */ private float value; } // End of XdrFloat.javaremotetea-1.0.7/src/org/acplt/oncrpc/XdrHttpDecodingStream.java0000644005374700003410000003671210335176720025653 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/XdrHttpDecodingStream.java,v 1.3 2005/11/11 21:23:44 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; import java.io.*; import java.net.*; import org.acplt.oncrpc.web.HttpClientConnection; import org.acplt.oncrpc.web.HttpTunnelConstants; import org.acplt.oncrpc.web.Base64; /** * The XdrHttpDecodingStream class provides the necessary * functionality to {@link XdrDecodingStream} to receive XDR data through * HTTP tunnels. * *

    Please note that there is currently no standard about how to tunnel * XDR data over HTTP connections. There are a (quite a) few solutions out * there, but they are more or less incompatible due to the lack of a RFC. * *

    This class is responsible solely for receiving ONC/RPC replies. * The reply data is base64 encoded and embedded within an ordinary plain * ASCII page, as is shown in this example. * *

     *     DEADBEEFDEADBEEFDEADBEEF...<CR><LF>
     *     B0D0EADSDEADBEEFB0D0EADS...<CR><LF>
     *     ...<CR><LF>
     *     DEADBE==<CR><LF>
     * 
    * *

    Parsing is minimalistic to make the whole sucker as fast as possible (not * looking at Java's performance at all). * * @version $Revision: 1.3 $ $Date: 2005/11/11 21:23:44 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class XdrHttpDecodingStream extends XdrDecodingStream { /** * Constructs a new XdrHttpDecodingStream. * * @param httpClient HTTP client connection from which to read the * encoded and embedded ONC/RPC reply message. */ public XdrHttpDecodingStream(HttpClientConnection httpClient) { this.httpClient = httpClient; // // // Calculate the buffer size depending on the number of plain // ASCII lines we try to read and process as one chunk. Then allocate // the necessary buffers. // int lines = HttpTunnelConstants.LINES_PER_BLOCK; int bufferSize = lines * HttpTunnelConstants.BYTES_PER_LINE; int asciiBufferSize = lines * HttpTunnelConstants.ENCODED_BYTES_PER_LINE_CRLF; buffer = new byte[bufferSize]; asciiBuffer = new byte[asciiBufferSize]; this.asciiBufferSize = asciiBufferSize; // // Reset the incomming buffer, just to be sure. // bufferIndex = 0; bufferHighmark = -4; } /** * Returns the Internet address of the sender of the current XDR data. * This method should only be called after {@link #beginDecoding}, * otherwise it might return stale information. * * @return InetAddress of the sender of the current XDR data. */ public InetAddress getSenderAddress() { return null; // FIXME } /** * Returns the port number of the sender of the current XDR data. * This method should only be called after {@link #beginDecoding}, * otherwise it might return stale information. * * @return Port number of the sender of the current XDR data. */ public int getSenderPort() { return 0; // FIXME } /** * Initiates decoding of the next XDR record. For HTTP-based XDR we * just read the content delivered with the answer to the POST command. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void beginDecoding() throws OncRpcException, IOException { // // Note that we don't assume getting a content length in advance, // but instead read 'till we drop. This is assumption is necessary // because we can not rely on keep-alive connections but instead // need to be able to deal with ordinay the close-after-receipt // interaction pattern of older HTTP versions. // httpClient.beginDecoding(); // // Just set up the (binary) data buffer to contain no data so that // the next decoding of some XDR data will result in the buffer being // filled from the HTTP connection. Delegation is sooo sweeeet! // bufferIndex = 0; bufferHighmark = -4; } /** * End decoding of the current XDR record. The general contract of * endDecoding is that calling it is an indication that * the current record is no more interesting to the caller and any * allocated data for this record can be freed. * *

    To help the HTTP connection keeping alive, we swallow all data * until we reach the end. If this is not possible, either because the * server indicated that it can not keep the connection open, the content * length was unknown in advance, or we got an I/O exception, we close * the connection. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void endDecoding() throws OncRpcException, IOException { // // Let the HTTP client object handle all the crude aspects of keeping // alive connections, swallowing unwanted chunked data, etc. // try { httpClient.endDecoding(); } catch ( IOException e ) { } // // Make sure that no-one can accidently retrieve any stale data from // the decoding buffer. // bufferIndex = 0; bufferHighmark = -4; } /** * Closes this decoding XDR stream and releases any system resources * associated with this stream. A closed XDR stream cannot perform decoding * operations and cannot be reopened. * *

    This implementation frees the allocated buffer but does not close * the associated datagram socket. It only throws away the reference to * this socket. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void close() throws OncRpcException, IOException { // // Do not close the httpClient, as it does not belong to us, but we // simply got a reference to use this particular client. // httpClient = null; buffer = null; } /** * Receives more encoded data over the HTTP connection and decodes it into * octets, making them available through the buffer field. */ private void fill() throws OncRpcException, IOException { // // In the first step we receive the base64 encoded plain ASCII data // through the HTTP connection one block at a time. // int charsRead; try { int remaining = httpClient.getRemainingContentLength(); if ( remaining < 0 ) { charsRead = httpClient.readContentBytes(asciiBuffer, 0, asciiBufferSize); } else { charsRead = httpClient.readContentBytes(asciiBuffer, 0, remaining); } } catch ( ProtocolException e ) { throw(new OncRpcException(OncRpcException.RPC_BUFFERUNDERFLOW)); } // // In the next step we decode the base64 data and store the octets into // the real buffer. // int decoded = 0; int encoded = 0; int toDecode; while ( charsRead > 0 ) { // FIXME: more sanity checks... // We currently simply assume that the last two characters are CRLF // and thus skip them. toDecode = charsRead >= HttpTunnelConstants.ENCODED_BYTES_PER_LINE ? HttpTunnelConstants.ENCODED_BYTES_PER_LINE : (charsRead - 2); decoded += Base64.decode(asciiBuffer, encoded, toDecode, buffer, decoded); // // FIXME: check CRLF // encoded += toDecode + 2; charsRead -= toDecode + 2; } // // Set the buffer "pointers" accordingly. // bufferIndex = 0; bufferHighmark = decoded - 4; } /** * Decodes (aka "deserializes") a "XDR int" value received from a * XDR stream. A XDR int is 32 bits wide -- the same width Java's "int" * data type has. * * @return The decoded int value. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public int xdrDecodeInt() throws OncRpcException, IOException { if ( bufferIndex > bufferHighmark ) { fill(); } // // There's enough space in the buffer to hold at least one // XDR int. So let's retrieve it now. // Note: buffer[...] gives a byte, which is signed. So if we // add it to the value (which is int), it has to be widened // to 32 bit, so its sign is propagated. To avoid this sign // madness, we have to "and" it with 0xFF, so all unwanted // bits are cut off after sign extension. Sigh. // int value = buffer[bufferIndex++] & 0xFF; value = (value << 8) + (buffer[bufferIndex++] & 0xFF); value = (value << 8) + (buffer[bufferIndex++] & 0xFF); value = (value << 8) + (buffer[bufferIndex++] & 0xFF); return value; } /** * Decodes (aka "deserializes") an opaque value, which is nothing more * than a series of octets (or 8 bits wide bytes). Because the length * of the opaque value is given, we don't need to retrieve it from the * XDR stream. This is different from * {@link #xdrDecodeOpaque(byte[], int, int)} where * first the length of the opaque value is retrieved from the XDR stream. * * @param length Length of opaque data to decode. * * @return Opaque data as a byte vector. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public byte [] xdrDecodeOpaque(int length) throws OncRpcException, IOException { int padding = (4 - (length & 3)) & 3; int offset = 0; // current offset into bytes vector int toCopy; // // Now allocate enough memory to hold the data to be retrieved and // get part after part from the buffer. // byte [] bytes = new byte[length]; if ( bufferIndex > bufferHighmark ) { fill(); } while ( length > 0 ) { toCopy = bufferHighmark - bufferIndex + 4; if ( toCopy >= length ) { // // The buffer holds more data than we need. So copy the bytes // and leave the stage. // System.arraycopy(buffer, bufferIndex, bytes, offset, length); bufferIndex += length; // No need to adjust "offset", because this is the last round. break; } else { // // We need to copy more data than currently available from our // buffer, so we copy all we can get our hands on, then fill // the buffer again and repeat this until we got all we want. // System.arraycopy(buffer, bufferIndex, bytes, offset, toCopy); bufferIndex += toCopy; offset += toCopy; length -= toCopy; fill(); } } bufferIndex += padding; return bytes; } /** * Decodes (aka "deserializes") a XDR opaque value, which is represented * by a vector of byte values, and starts at offset with a * length of length. Only the opaque value is decoded, so the * caller has to know how long the opaque value will be. The decoded data * is always padded to be a multiple of four (because that's what the * sender does). * * @param opaque Byte vector which will receive the decoded opaque value. * @param offset Start offset in the byte vector. * @param length the number of bytes to decode. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrDecodeOpaque(byte [] opaque, int offset, int length) throws OncRpcException, IOException { int padding = (4 - (length & 3)) & 3; int toCopy; // // Now get part after part and fill the byte vector. // if ( bufferIndex > bufferHighmark ) { fill(); } while ( length > 0 ) { toCopy = bufferHighmark - bufferIndex + 4; if ( toCopy >= length ) { // // The buffer holds more data than we need. So copy the bytes // and leave the stage. // System.arraycopy(buffer, bufferIndex, opaque, offset, length); bufferIndex += length; // No need to adjust "offset", because this is the last round. break; } else { // // We need to copy more data than currently available from our // buffer, so we copy all we can get our hands on, then fill // the buffer again and repeat this until we got all we want. // System.arraycopy(buffer, bufferIndex, opaque, offset, toCopy); bufferIndex += toCopy; offset += toCopy; length -= toCopy; fill(); } } bufferIndex += padding; } /** * Client HTTP tunnel to retrieve embedded XDR records from. */ private HttpClientConnection httpClient; /** * The buffer which will be filled from the datagram socket and then * be used to supply the information when decoding data. */ private byte [] buffer; /** * The buffer receiving base64 encoded plain ASCII data from a HTTP web * server. This buffer is only used for immediate decoding of the binary * data, which is then stored in the usual buffer field. */ private byte [] asciiBuffer; /** * Size of buffer for receiving the base64 encoded plain ASCII data. The * encoded data is then immediately decoded after recept into "ordinary" * binary data, which is stored in the usual buffer field. */ private int asciiBufferSize; /** * The read pointer is an index into the buffer. */ private int bufferIndex; /** * Index of the last four byte word in the buffer, which has been read * in from the datagram socket. */ private int bufferHighmark; } // End of XdrHttpDecodingStreamremotetea-1.0.7/src/org/acplt/oncrpc/XdrInt.java0000644005374700003410000000626707716406374022671 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/XdrInt.java,v 1.1.1.1 2003/08/13 12:03:40 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; import java.io.IOException; /** * Instances of the class XdrInt represent (de-)serializeable * integers, which are especially useful in cases where a result with only a * single int is expected from a remote function call or only a single * int parameter needs to be supplied. * *

    Please note that this class is somewhat modelled after Java's primitive * data type wrappers. As for these classes, the XDR data type wrapper classes * follow the concept of values with no identity, so you are not allowed to * change the value after you've created a value object. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:40 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class XdrInt implements XdrAble { /** * Constructs and initializes a new XdrInt object. * * @param value Int value. */ public XdrInt(int value) { this.value = value; } /** * Constructs and initializes a new XdrInt object. */ public XdrInt() { this.value = 0; } /** * Returns the value of this XdrInt object as a int * primitive. * * @return The primitive int value of this object. */ public int intValue() { return this.value; } /** * Encodes -- that is: serializes -- a XDR int into a XDR stream in * compliance to RFC 1832. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException { xdr.xdrEncodeInt(value); } /** * Decodes -- that is: deserializes -- a XDR int from a XDR stream in * compliance to RFC 1832. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException { value = xdr.xdrDecodeInt(); } /** * The encapsulated int value itself. */ private int value; } // End of XdrInt.javaremotetea-1.0.7/src/org/acplt/oncrpc/XdrLong.java0000644005374700003410000000633107716406374023026 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/XdrLong.java,v 1.1.1.1 2003/08/13 12:03:40 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; import java.io.IOException; /** * Instances of the class XdrLong represent (de-)serializeable * longs (64 bit), which are especially useful in cases where a result with only a * single long is expected from a remote function call or only a single * long parameter needs to be supplied. * *

    Please note that this class is somewhat modelled after Java's primitive * data type wrappers. As for these classes, the XDR data type wrapper classes * follow the concept of values with no identity, so you are not allowed to * change the value after you've created a value object. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:40 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class XdrLong implements XdrAble { /** * Constructs and initializes a new XdrLong object. * * @param value Long value. */ public XdrLong(long value) { this.value = value; } /** * Constructs and initializes a new XdrLong object. */ public XdrLong() { this.value = 0; } /** * Returns the value of this XdrLong object as a long * primitive. * * @return The primitive long value of this object. */ public long longValue() { return this.value; } /** * Encodes -- that is: serializes -- a XDR long into a XDR stream in * compliance to RFC 1832. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException { xdr.xdrEncodeLong(value); } /** * Decodes -- that is: deserializes -- a XDR long from a XDR stream in * compliance to RFC 1832. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException { value = xdr.xdrDecodeLong(); } /** * The encapsulated long value itself. */ private long value; } // End of XdrLong.javaremotetea-1.0.7/src/org/acplt/oncrpc/XdrOpaque.java0000644005374700003410000000654407716406374023367 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/XdrOpaque.java,v 1.1.1.1 2003/08/13 12:03:40 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; import java.io.IOException; /** * Instances of the class XdrOpaque represent (de-)serializeable * fixed-size opaque values, which are especially useful in cases where a result with only a * single opaque value is expected from a remote function call or only a single * opaque value parameter needs to be supplied. * *

    Please note that this class is somewhat modelled after Java's primitive * data type wrappers. As for these classes, the XDR data type wrapper classes * follow the concept of values with no identity, so you are not allowed to * change the value after you've created a value object. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:40 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class XdrOpaque implements XdrAble { /** * Constructs and initializes a new XdrOpaque object. */ public XdrOpaque(byte [] value) { this.value = value; } /** * Constructs and initializes a new XdrOpaque object given * only the size of the opaque value. * * @param length size of opaque value. */ public XdrOpaque(int length) { this.value = new byte[length]; } /** * Returns the value of this XdrOpaque object as a byte * vector. * * @return The primitive byte[] value of this object. */ public byte [] opaqueValue() { return this.value; } /** * Encodes -- that is: serializes -- a XDR opaque into a XDR stream in * compliance to RFC 1832. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException { xdr.xdrEncodeOpaque(value); } /** * Decodes -- that is: deserializes -- a XDR opaque from a XDR stream in * compliance to RFC 1832. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException { xdr.xdrDecodeOpaque(value); } /** * The encapsulated opaque value itself. */ private byte [] value; } // End of XdrOpaque.javaremotetea-1.0.7/src/org/acplt/oncrpc/XdrShort.java0000644005374700003410000000634407716406374023232 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/XdrShort.java,v 1.1.1.1 2003/08/13 12:03:40 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; import java.io.IOException; /** * Instances of the class XdrShort represent (de-)serializeable * shorts, which are especially useful in cases where a result with only a * single short is expected from a remote function call or only a single * short parameter needs to be supplied. * *

    Please note that this class is somewhat modelled after Java's primitive * data type wrappers. As for these classes, the XDR data type wrapper classes * follow the concept of values with no identity, so you are not allowed to * change the value after you've created a value object. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:40 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class XdrShort implements XdrAble { /** * Constructs and initializes a new XdrShort object. * * @param value Short value. */ public XdrShort(short value) { this.value = value; } /** * Constructs and initializes a new XdrShort object. */ public XdrShort() { this.value = 0; } /** * Returns the value of this XdrShort object as a short * primitive. * * @return The primitive short value of this object. */ public short shortValue() { return this.value; } /** * Encodes -- that is: serializes -- a XDR short into a XDR stream in * compliance to RFC 1832. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException { xdr.xdrEncodeShort(value); } /** * Decodes -- that is: deserializes -- a XDR short from a XDR stream in * compliance to RFC 1832. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException { value = xdr.xdrDecodeShort(); } /** * The encapsulated short value itself. */ private short value; } // End of XdrShort.java remotetea-1.0.7/src/org/acplt/oncrpc/XdrString.java0000644005374700003410000000637607716406374023406 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/XdrString.java,v 1.1.1.1 2003/08/13 12:03:40 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; import java.io.IOException; /** * Instances of the class XdrString represent (de-)serializeable * strings, which are especially useful in cases where a result with only a * single string is expected from a remote function call or only a single * string parameter needs to be supplied. * *

    Please note that this class is somewhat modelled after Java's primitive * data type wrappers. As for these classes, the XDR data type wrapper classes * follow the concept of values with no identity, so you are not allowed to * change the value after you've created a value object. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:40 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class XdrString implements XdrAble { /** * Constructs and initializes a new XdrString object. * * @param value String value. */ public XdrString(String value) { this.value = value; } /** * Constructs and initializes a new XdrString object. */ public XdrString() { this.value = null; } /** * Returns the value of this XdrString object as a string * primitive. * * @return The primitive String value of this object. */ public String stringValue() { return this.value; } /** * Encodes -- that is: serializes -- a XDR string into a XDR stream in * compliance to RFC 1832. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException { xdr.xdrEncodeString(value); } /** * Decodes -- that is: deserializes -- a XDR string from a XDR stream in * compliance to RFC 1832. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException { value = xdr.xdrDecodeString(); } /** * The encapsulated string value itself. */ private String value; } // End of XdrString.javaremotetea-1.0.7/src/org/acplt/oncrpc/XdrTcpDecodingStream.java0000644005374700003410000004377610335175000025460 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/XdrTcpDecodingStream.java,v 1.2 2005/11/11 21:07:27 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; import java.io.*; import java.net.*; /** * The XdrTcpDecodingStream class provides the necessary * functionality to {@link XdrDecodingStream} to receive XDR records from the * network using the stream-oriented TCP/IP. * * @version $Revision: 1.2 $ $Date: 2005/11/11 21:07:27 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class XdrTcpDecodingStream extends XdrDecodingStream { /** * Construct a new XdrTcpDecodingStream object and associate * it with the given streamingSocket for TCP/IP-based * communication. * * @param streamingSocket Socket from which XDR data is received. * @param bufferSize Size of packet buffer for storing received XDR * data. */ public XdrTcpDecodingStream(Socket streamingSocket, int bufferSize) throws IOException { socket = streamingSocket; stream = socket.getInputStream(); // // If the given buffer size is too small, start with a more sensible // size. Next, if bufferSize is not a multiple of four, round it up to // the next multiple of four. // if ( bufferSize < 1024 ) { bufferSize = 1024; } if ( (bufferSize & 3) != 0 ) { bufferSize = (bufferSize + 4) & ~3; } // // Set up the buffer and the buffer pointers (no, this is still // Java). // buffer = new byte[bufferSize]; bufferIndex = 0; bufferHighmark = -4; lastFragment = false; fragmentLength = 0; } /** * Returns the Internet address of the sender of the current XDR data. * This method should only be called after {@link #beginDecoding}, otherwise * it might return stale information. * * @return InetAddress of the sender of the current XDR data. */ public InetAddress getSenderAddress() { return socket.getInetAddress(); } /** * Returns the port number of the sender of the current XDR data. * This method should only be called after {@link #beginDecoding}, otherwise * it might return stale information. * * @return Port number of the sender of the current XDR data. */ public int getSenderPort() { return socket.getPort(); } /** * Initiates decoding of the next XDR record. For TCP-based XDR decoding * streams this reads in the next chunk of data from the network socket * (a chunk of data is not necessary the same as a fragment, just enough * to fill the internal buffer or receive the remaining part of a fragment). * *

    Read in the next bunch of bytes. This can be either a complete fragment, * or if the fragments sent by the communication partner are too large for * our buffer, only parts of fragments. In every case, this method ensures * that there will be more data available in the buffer (or else an * exception thrown). * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void beginDecoding() throws OncRpcException, IOException { fill(); } /** * Read into buffer exactly the amound of bytes specified. * * @param stream Input stream to read byte data from. * @param bytes buffer receiving data. * @param bytesToRead number of bytes to read into buffer. * * @throws OncRpcException if EOF is reached before all bytes could * be read. * @throws IOException if an I/O error occurs. */ private void readBuffer(InputStream stream, byte [] bytes, int bytesToRead) throws IOException, OncRpcException { int bytesRead; int byteOffset = 0; while ( bytesToRead > 0 ) { bytesRead = stream.read(bytes, byteOffset, bytesToRead); if ( bytesRead <= 0 ) { // // Stream is at EOF -- note that bytesRead is not allowed // to be zero here, as we asked for at least one byte... // throw(new OncRpcException(OncRpcException.RPC_CANTRECV)); } bytesToRead -= bytesRead; byteOffset += bytesRead; } } /** * Fills the internal buffer with the next chunk of data. The chunk is * either as long as the buffer or as long as the remaining part of the * current XDR fragment, whichever is smaller. * *

    This method does not accept empty XDR record fragments with the * only exception of a final trailing empty fragment. This special case * is accepted as some ONC/RPC implementations emit such trailing * empty fragments whenever the encoded data is a full multiple of their * internal record buffer size. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ private void fill() throws OncRpcException, IOException { // // If the buffer is empty but there are still bytes left to read, // refill the buffer. We have also to take care of the record marking // within the stream. // // Remember that lastFragment is reset by the endDecoding() method. // This once used to be a while loop, but it has been dropped since // we do not accept empty records any more -- with the only exception // being a final trailing empty XDR record. // // Did we already read in all data belonging to the current XDR // record, or are there bytes left to be read? // if ( fragmentLength <= 0 ) { if ( lastFragment ) { // // In case there is no more data in the current XDR record // (as we already saw the last fragment), throw an exception. // throw(new OncRpcException(OncRpcException.RPC_BUFFERUNDERFLOW)); } // // First read in the header of the next fragment. // byte bytes[] = new byte[4]; readBuffer(stream, bytes, 4); // // Watch the sign bit! // fragmentLength = bytes[0] & 0xFF; fragmentLength = (fragmentLength << 8) + (bytes[1] & 0xFF); fragmentLength = (fragmentLength << 8) + (bytes[2] & 0xFF); fragmentLength = (fragmentLength << 8) + (bytes[3] & 0xFF); if ( (fragmentLength & 0x80000000) != 0 ) { fragmentLength &= 0x7FFFFFFF; lastFragment = true; } else { lastFragment = false; } // // Sanity check on incomming fragment length: the length must // be at least four bytes long, otherwise this fragment does // not make sense. There are ONC/RPC implementations that send // empty trailing fragments, so we accept them here. // Also check for fragment lengths which are not a multiple of // four -- and thus are invalid. // if ( (fragmentLength & 3) != 0 ) { throw(new IOException("ONC/RPC XDR fragment length is not a multiple of four")); } if ( (fragmentLength == 0) && !lastFragment ) { throw(new IOException("empty ONC/RPC XDR fragment which is not a trailing fragment")); } } // // When the reach this stage, there is (still) data to be read for the // current XDR record *fragment*. // // Now read in the next buffer. Depending on how much bytes are still // to read within this frame, we either fill the buffer not completely // (with still some bytes to read in from the next round) or // completely. // bufferIndex = 0; if ( fragmentLength < buffer.length ) { readBuffer(stream, buffer, fragmentLength); bufferHighmark = fragmentLength - 4; fragmentLength = 0; } else { readBuffer(stream, buffer, buffer.length); bufferHighmark = buffer.length - 4; fragmentLength -= buffer.length; } } /** * End decoding of the current XDR record. The general contract of * endDecoding is that calling it is an indication that * the current record is no more interesting to the caller and any * allocated data for this record can be freed. * *

    This method overrides {@link XdrDecodingStream#endDecoding}. It reads in * and throws away fragments until it reaches the last fragment. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void endDecoding() throws OncRpcException, IOException { try { // // Drain the stream until we reach the end of the current record. // while ( !lastFragment || (fragmentLength != 0) ) { fill(); } } finally { // // Try to reach a sane state, although this is rather questionable // in case of timeouts in the middle of a record. // bufferIndex = 0; bufferHighmark = -4; lastFragment = false; fragmentLength = 0; } } /** * Closes this decoding XDR stream and releases any system resources * associated with this stream. A closed XDR stream cannot perform decoding * operations and cannot be reopened. * *

    This implementation frees the allocated buffer but does not close * the associated datagram socket. It only throws away the reference to * this socket. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void close() throws OncRpcException, IOException { buffer = null; stream = null; socket = null; } /** * Decodes (aka "deserializes") a "XDR int" value received from a * XDR stream. A XDR int is 32 bits wide -- the same width Java's "int" * data type has. * * @return The decoded int value. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public int xdrDecodeInt() throws OncRpcException, IOException { // // This might look funny in the first place, but this way we can // properly handle trailing empty XDR record fragments. In this // case fill() will return without any now data the first time // and on the second time a buffer underflow exception is thrown. // while ( bufferIndex > bufferHighmark ) { fill(); } // // There's enough space in the buffer to hold at least one // XDR int. So let's retrieve it now. // Note: buffer[...] gives a byte, which is signed. So if we // add it to the value (which is int), it has to be widened // to 32 bit, so its sign is propagated. To avoid this sign // madness, we have to "and" it with 0xFF, so all unwanted // bits are cut off after sign extension. Sigh. // int value = buffer[bufferIndex++] & 0xFF; value = (value << 8) + (buffer[bufferIndex++] & 0xFF); value = (value << 8) + (buffer[bufferIndex++] & 0xFF); value = (value << 8) + (buffer[bufferIndex++] & 0xFF); return value; } /** * Decodes (aka "deserializes") an opaque value, which is nothing more * than a series of octets (or 8 bits wide bytes). Because the length * of the opaque value is given, we don't need to retrieve it from the * XDR stream. This is different from * {@link #xdrDecodeOpaque(byte[], int, int)} where * first the length of the opaque value is retrieved from the XDR stream. * * @param length Length of opaque data to decode. * * @return Opaque data as a byte vector. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public byte [] xdrDecodeOpaque(int length) throws OncRpcException, IOException { int padding = (4 - (length & 3)) & 3; int offset = 0; // current offset into bytes vector int toCopy; // // Now allocate enough memory to hold the data to be retrieved and // get part after part from the buffer. // byte [] bytes = new byte[length]; // // As for the while loop, see the comment in xdrDecodeInt(). // while ( bufferIndex > bufferHighmark ) { fill(); } while ( length > 0 ) { toCopy = bufferHighmark - bufferIndex + 4; if ( toCopy >= length ) { // // The buffer holds more data than we need. So copy the bytes // and leave the stage. // System.arraycopy(buffer, bufferIndex, bytes, offset, length); bufferIndex += length; // No need to adjust "offset", because this is the last round. break; } else { // // We need to copy more data than currently available from our // buffer, so we copy all we can get our hands on, then fill // the buffer again and repeat this until we got all we want. // System.arraycopy(buffer, bufferIndex, bytes, offset, toCopy); bufferIndex += toCopy; offset += toCopy; length -= toCopy; // NB: no problems with trailing empty fragments, so we skip // the while loop here. fill(); } } bufferIndex += padding; return bytes; } /** * Decodes (aka "deserializes") a XDR opaque value, which is represented * by a vector of byte values, and starts at offset with a * length of length. Only the opaque value is decoded, so the * caller has to know how long the opaque value will be. The decoded data * is always padded to be a multiple of four (because that's what the * sender does). * * @param opaque Byte vector which will receive the decoded opaque value. * @param offset Start offset in the byte vector. * @param length the number of bytes to decode. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrDecodeOpaque(byte [] opaque, int offset, int length) throws OncRpcException, IOException { int padding = (4 - (length & 3)) & 3; int toCopy; // // Now get part after part and fill the byte vector. // if ( bufferIndex > bufferHighmark ) { fill(); } while ( length > 0 ) { toCopy = bufferHighmark - bufferIndex + 4; if ( toCopy >= length ) { // // The buffer holds more data than we need. So copy the bytes // and leave the stage. // System.arraycopy(buffer, bufferIndex, opaque, offset, length); bufferIndex += length; // No need to adjust "offset", because this is the last round. break; } else { // // We need to copy more data than currently available from our // buffer, so we copy all we can get our hands on, then fill // the buffer again and repeat this until we got all we want. // System.arraycopy(buffer, bufferIndex, opaque, offset, toCopy); bufferIndex += toCopy; offset += toCopy; length -= toCopy; fill(); } } bufferIndex += padding; } /** * The streaming socket to be used when receiving this XDR stream's * buffer contents. */ private Socket socket; /** * The input stream used to pull the bytes off the network. */ InputStream stream; /** * The buffer which will be filled from the datagram socket and then * be used to supply the information when decoding data. */ private byte [] buffer; /** * The read pointer is an index into the buffer. */ private int bufferIndex; /** * Index of the last four byte word in the buffer, which has been read * in from the datagram socket. */ private int bufferHighmark; /** * Remaining number of bytes in this fragment -- and still to read. */ private int fragmentLength; /** * Flag indicating that we've read the last fragment and thus reached * the end of the record. */ private boolean lastFragment; } // End of XdrTcpDecodingStreamremotetea-1.0.7/src/org/acplt/oncrpc/XdrTcpEncodingStream.java0000644005374700003410000003166607716650534025510 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/XdrTcpEncodingStream.java,v 1.2 2003/08/14 11:07:39 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; import java.io.*; import java.net.*; /** * The XdrTcpEncodingStream class provides the necessary * functionality to {@link XdrEncodingStream} to send XDR records to the * network using the stream-oriented TCP/IP. * * @version $Revision: 1.2 $ $Date: 2003/08/14 11:07:39 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class XdrTcpEncodingStream extends XdrEncodingStream { /** * Construct a new XdrTcpEncodingStream object and associate * it with the given streamingSocket for TCP/IP-based * communication. * * @param streamingSocket Socket to which XDR data is sent. * @param bufferSize Size of packet buffer for temporarily storing * outgoing XDR data. */ public XdrTcpEncodingStream(Socket streamingSocket, int bufferSize) throws IOException { socket = streamingSocket; stream = socket.getOutputStream(); // // If the given buffer size is too small, start with a more sensible // size. Next, if bufferSize is not a multiple of four, round it up to // the next multiple of four. // if ( bufferSize < 1024 ) { bufferSize = 1024; } if ( (bufferSize & 3) != 0 ) { bufferSize = (bufferSize + 4) & ~3; } // // Set up the buffer and the buffer pointers (no, this is still // Java). // buffer = new byte[bufferSize]; bufferFragmentHeaderIndex = 0; bufferIndex = 4; bufferHighmark = bufferSize - 4; } /** * Returns the Internet address of the sender of the current XDR data. * This method should only be called after {@link #beginEncoding}, * otherwise it might return stale information. * * @return InetAddress of the sender of the current XDR data. */ public InetAddress getSenderAddress() { return socket.getInetAddress(); } /** * Returns the port number of the sender of the current XDR data. * This method should only be called after {@link #beginEncoding}, * otherwise it might return stale information. * * @return Port number of the sender of the current XDR data. */ public int getSenderPort() { return socket.getPort(); } /** * Begins encoding a new XDR record. This typically involves resetting this * encoding XDR stream back into a known state. * * @param receiverAddress Indicates the receiver of the XDR data. This can be * null for XDR streams connected permanently to a * receiver (like in case of TCP/IP based XDR streams). * @param receiverPort Port number of the receiver. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void beginEncoding(InetAddress receiverAddress, int receiverPort) throws OncRpcException, IOException { // // Begin encoding with the four byte word after the fragment header, // which also four bytes wide. We have to remember where we can find // the fragment header as we support batching/pipelining calls, so // several requests (each in its own fragment) can be simultaneously // in the write buffer. // //bufferFragmentHeaderIndex = bufferIndex; //bufferIndex += 4; } /** * Flushes this encoding XDR stream and forces any buffered output bytes * to be written out. The general contract of endEncoding is that * calling it is an indication that the current record is finished and any * bytes previously encoded should immediately be written to their intended * destination. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void endEncoding() throws OncRpcException, IOException { flush(true, false); } /** * Ends the current record fort this encoding XDR stream. If the parameter * flush is true any buffered output bytes are * immediately written to their intended destination. If flush * is false, then more than one record can be pipelined, for * instance, to batch several ONC/RPC calls. In this case the ONC/RPC * server must not send a reply (with the exception for the last * call in a batch, which might be trigger a reply). Otherwise, you will * most probably cause an interaction deadlock between client and server. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void endEncoding(boolean flush) throws OncRpcException, IOException { flush(true, !flush); } /** * Flushes the current contents of the buffer as one fragment to the * network. * * @param lastFragment true if this is the last fragment of * the current XDR record. * @param batch if last fragment and batch is * true, then the buffer is not flushed to the network * but instead we wait for more records to be encoded. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ private void flush(boolean lastFragment, boolean batch) throws OncRpcException, IOException { // // Encode the fragment header. We have to take batching/pipelining // into account, so multiple complete fragments may be waiting in // the same write buffer. The variable bufferFragmentHeaderIndex // points to the place where we should store this fragment's header. // int fragmentLength = bufferIndex - bufferFragmentHeaderIndex - 4; if ( lastFragment ) { fragmentLength |= 0x80000000; } buffer[bufferFragmentHeaderIndex] = (byte)(fragmentLength >>> 24); buffer[bufferFragmentHeaderIndex + 1] = (byte)(fragmentLength >>> 16); buffer[bufferFragmentHeaderIndex + 2] = (byte)(fragmentLength >>> 8); buffer[bufferFragmentHeaderIndex + 3] = (byte) fragmentLength; if ( !lastFragment // buffer is full, so we have to flush || !batch // buffer not full, but last fragment and not in batch || (bufferIndex >= bufferHighmark) // not enough space for next // fragment header and one int ) { // // Finally write the buffer's contents into the vastness of // network space. This has to be done when we do not need to // pipeline calls and if there is still enough space left in // the buffer for the fragment header and at least a single // int. // stream.write(buffer, 0, bufferIndex); stream.flush(); // // Reset write pointer after the fragment header int within // buffer, so the next bunch of data can be encoded. // bufferFragmentHeaderIndex = 0; bufferIndex = 4; } else { // // Batch/pipeline several consecuting XDR records. So do not // flush the buffer yet to the network but instead wait for more // data. // bufferFragmentHeaderIndex = bufferIndex; bufferIndex += 4; } } /** * Closes this encoding XDR stream and releases any system resources * associated with this stream. The general contract of close * is that it closes the encoding XDR stream. A closed XDR stream cannot * perform encoding operations and cannot be reopened. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void close() throws OncRpcException, IOException { buffer = null; socket = null; } /** * Encodes (aka "serializes") a "XDR int" value and writes it down a * XDR stream. A XDR int is 32 bits wide -- the same width Java's "int" * data type has. This method is one of the basic methods all other * methods can rely on. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrEncodeInt(int value) throws OncRpcException, IOException { if ( bufferIndex > bufferHighmark ) { flush(false, false); } // // There's enough space in the buffer, so encode this int as // four bytes (french octets) in big endian order (that is, the // most significant byte comes first. // buffer[bufferIndex++] = (byte)(value >>> 24); buffer[bufferIndex++] = (byte)(value >>> 16); buffer[bufferIndex++] = (byte)(value >>> 8); buffer[bufferIndex++] = (byte) value; } /** * Encodes (aka "serializes") a XDR opaque value, which is represented * by a vector of byte values, and starts at offset with a * length of length. Only the opaque value is encoded, but * no length indication is preceeding the opaque value, so the receiver * has to know how long the opaque value will be. The encoded data is * always padded to be a multiple of four. If the given length is not a * multiple of four, zero bytes will be used for padding. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrEncodeOpaque(byte [] value, int offset, int length) throws OncRpcException, IOException { int padding = (4 - (length & 3)) & 3; int toCopy; while ( length > 0 ) { toCopy = bufferHighmark - bufferIndex + 4; if ( toCopy >= length ) { // // The buffer has more free space than we need. So copy the // bytes and leave the stage. // System.arraycopy(value, offset, buffer, bufferIndex, length); bufferIndex += length; // No need to adjust "offset", because this is the last round. break; } else { // // We need to copy more data than currently available from our // buffer, so we copy all we can get our hands on, then fill // the buffer again and repeat this until we got all we want. // System.arraycopy(value, offset, buffer, bufferIndex, toCopy); bufferIndex += toCopy; offset += toCopy; length -= toCopy; flush(false, false); } } System.arraycopy(paddingZeros, 0, buffer, bufferIndex, padding); bufferIndex += padding; } /** * The streaming socket to be used when receiving this XDR stream's * buffer contents. */ private Socket socket; /** * The output stream used to get rid of bytes going off to the network. */ OutputStream stream; /** * The buffer which will be filled from the datagram socket and then * be used to supply the information when decoding data. */ private byte [] buffer; /** * The write pointer is an index into the buffer. */ private int bufferIndex; /** * Index of the last four byte word in the buffer. */ private int bufferHighmark; /** * Index of fragment header within buffer. */ private int bufferFragmentHeaderIndex; /** * Some zeros, only needed for padding -- like in real life. */ private static final byte [] paddingZeros = { 0, 0, 0, 0 }; } // End of XdrTcpEncodingStream.java remotetea-1.0.7/src/org/acplt/oncrpc/XdrUdpDecodingStream.java0000644005374700003410000002457610335175014025464 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/XdrUdpDecodingStream.java,v 1.2 2005/11/11 21:07:40 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; import java.io.*; import java.net.*; /** * The XdrUdpDecodingStream class provides the necessary * functionality to {@link XdrDecodingStream} to receive XDR packets from the * network using the datagram-oriented UDP/IP. * * @version $Revision: 1.2 $ $Date: 2005/11/11 21:07:40 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class XdrUdpDecodingStream extends XdrDecodingStream { /** * Construct a new XdrUdpDecodingStream object and associate * it with the given datagramSocket for UDP/IP-based * communication. This constructor is typically used when communicating * with servers over UDP/IP using a "connected" datagram socket. * * @param datagramSocket Datagram socket from which XDR data is received. * @param bufferSize Size of packet buffer for storing received XDR * datagrams. */ public XdrUdpDecodingStream(DatagramSocket datagramSocket, int bufferSize) { socket = datagramSocket; // // If the given buffer size is too small, start with a more sensible // size. Next, if bufferSize is not a multiple of four, round it up to // the next multiple of four. // if ( bufferSize < 1024 ) { bufferSize = 1024; } if ( (bufferSize & 3) != 0 ) { bufferSize = (bufferSize + 4) & ~3; } buffer = new byte[bufferSize]; bufferIndex = 0; bufferHighmark = -4; } /** * Returns the Internet address of the sender of the current XDR data. * This method should only be called after {@link #beginDecoding}, * otherwise it might return stale information. * * @return InetAddress of the sender of the current XDR data. */ public InetAddress getSenderAddress() { return senderAddress; } /** * Returns the port number of the sender of the current XDR data. * This method should only be called after {@link #beginDecoding}, * otherwise it might return stale information. * * @return Port number of the sender of the current XDR data. */ public int getSenderPort() { return senderPort; } /** * Initiates decoding of the next XDR record. For UDP-based XDR decoding * streams this reads in the next datagram from the network socket. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void beginDecoding() throws OncRpcException, IOException { DatagramPacket packet = new DatagramPacket(buffer, buffer.length); socket.receive(packet); senderAddress = packet.getAddress(); senderPort = packet.getPort(); bufferIndex = 0; bufferHighmark = packet.getLength() - 4; } /** * End decoding of the current XDR record. The general contract of * endDecoding is that calling it is an indication that * the current record is no more interesting to the caller and any * allocated data for this record can be freed. * *

    This method overrides {@link XdrDecodingStream#endDecoding}. It does nothing * more than resetting the buffer pointer (eeek! a pointer in Java!!!) back * to the begin of an empty buffer, so attempts to decode data will fail * until the buffer is filled again. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void endDecoding() throws OncRpcException, IOException { bufferIndex = 0; bufferHighmark = -4; } /** * Closes this decoding XDR stream and releases any system resources * associated with this stream. A closed XDR stream cannot perform decoding * operations and cannot be reopened. * *

    This implementation frees the allocated buffer but does not close * the associated datagram socket. It only throws away the reference to * this socket. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void close() throws OncRpcException, IOException { buffer = null; socket = null; } /** * Decodes (aka "deserializes") a "XDR int" value received from a * XDR stream. A XDR int is 32 bits wide -- the same width Java's "int" * data type has. * * @return The decoded int value. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public int xdrDecodeInt() throws OncRpcException, IOException { if ( bufferIndex <= bufferHighmark ) { // // There's enough space in the buffer to hold at least one // XDR int. So let's retrieve it now. // Note: buffer[...] gives a byte, which is signed. So if we // add it to the value (which is int), it has to be widened // to 32 bit, so its sign is propagated. To avoid this sign // madness, we have to "and" it with 0xFF, so all unwanted // bits are cut off after sign extension. Sigh. // int value = buffer[bufferIndex++]; value = (value << 8) + (buffer[bufferIndex++] & 0xFF); value = (value << 8) + (buffer[bufferIndex++] & 0xFF); value = (value << 8) + (buffer[bufferIndex++] & 0xFF); return value; } else { throw(new OncRpcException(OncRpcException.RPC_BUFFERUNDERFLOW)); } } /** * Decodes (aka "deserializes") an opaque value, which is nothing more * than a series of octets (or 8 bits wide bytes). Because the length * of the opaque value is given, we don't need to retrieve it from the * XDR stream. This is different from * {@link #xdrDecodeOpaque(byte[], int, int)} where * first the length of the opaque value is retrieved from the XDR stream. * * @param length Length of opaque data to decode. * * @return Opaque data as a byte vector. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public byte [] xdrDecodeOpaque(int length) throws OncRpcException, IOException { // // First make sure that the length is always a multiple of four. // int alignedLength = length; if ( (alignedLength & 3) != 0 ) { alignedLength = (alignedLength & ~3) + 4; } // // Now allocate enough memory to hold the data to be retrieved. // byte [] bytes = new byte[length]; if ( length > 0 ) { if ( bufferIndex <= bufferHighmark - alignedLength + 4 ) { System.arraycopy(buffer, bufferIndex, bytes, 0, length); } else { throw(new OncRpcException(OncRpcException.RPC_BUFFERUNDERFLOW)); } } bufferIndex += alignedLength; return bytes; } /** * Decodes (aka "deserializes") a XDR opaque value, which is represented * by a vector of byte values, and starts at offset with a * length of length. Only the opaque value is decoded, so the * caller has to know how long the opaque value will be. The decoded data * is always padded to be a multiple of four (because that's what the * sender does). * * @param opaque Byte vector which will receive the decoded opaque value. * @param offset Start offset in the byte vector. * @param length the number of bytes to decode. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrDecodeOpaque(byte [] opaque, int offset, int length) throws OncRpcException, IOException { // // First make sure that the length is always a multiple of four. // int alignedLength = length; if ( (alignedLength & 3) != 0 ) { alignedLength = (alignedLength & ~3) + 4; } // // Now allocate enough memory to hold the data to be retrieved. // if ( length > 0 ) { if ( bufferIndex <= bufferHighmark - alignedLength + 4 ) { System.arraycopy(buffer, bufferIndex, opaque, offset, length); } else { throw(new OncRpcException(OncRpcException.RPC_BUFFERUNDERFLOW)); } } bufferIndex += alignedLength; } /** * The datagram socket to be used when receiving this XDR stream's * buffer contents. */ private DatagramSocket socket; /** * Sender's address of current buffer contents. */ private InetAddress senderAddress = null; /** * The senders's port. */ private int senderPort = 0; /** * The buffer which will be filled from the datagram socket and then * be used to supply the information when decoding data. */ private byte [] buffer; /** * The read pointer is an index into the buffer. */ private int bufferIndex; /** * Index of the last four byte word in the buffer, which has been read * in from the datagram socket. */ private int bufferHighmark; } // End of XdrUdpDecodingStream remotetea-1.0.7/src/org/acplt/oncrpc/XdrUdpEncodingStream.java0000644005374700003410000002006007716650534025474 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/XdrUdpEncodingStream.java,v 1.2 2003/08/14 11:07:39 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; import java.io.*; import java.net.*; /** * The XdrUdpDecodingStream class provides the necessary * functionality to {@link XdrDecodingStream} to send XDR packets over the * network using the datagram-oriented UDP/IP. * * @version $Revision: 1.2 $ $Date: 2003/08/14 11:07:39 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class XdrUdpEncodingStream extends XdrEncodingStream { /** * Creates a new UDP-based encoding XDR stream, associated with the * given datagram socket. * * @param datagramSocket Datagram-based socket to use to get rid of * encoded data. * @param bufferSize Size of buffer to store encoded data before it * is sent as one datagram. */ public XdrUdpEncodingStream(DatagramSocket datagramSocket, int bufferSize) { socket = datagramSocket; // // If the given buffer size is too small, start with a more sensible // size. Next, if bufferSize is not a multiple of four, round it up to // the next multiple of four. // if ( bufferSize < 1024 ) { bufferSize = 1024; } if ( (bufferSize & 3) != 0 ) { bufferSize = (bufferSize + 4) & ~3; } buffer = new byte[bufferSize]; bufferIndex = 0; bufferHighmark = bufferSize - 4; } /** * Begins encoding a new XDR record. This involves resetting this * encoding XDR stream back into a known state. * * @param receiverAddress Indicates the receiver of the XDR data. This can be * null for XDR streams connected permanently to a * receiver (like in case of TCP/IP based XDR streams). * @param receiverPort Port number of the receiver. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void beginEncoding(InetAddress receiverAddress, int receiverPort) throws OncRpcException, IOException { this.receiverAddress = receiverAddress; this.receiverPort = receiverPort; bufferIndex = 0; } /** * Flushes this encoding XDR stream and forces any buffered output bytes * to be written out. The general contract of endEncoding is that * calling it is an indication that the current record is finished and any * bytes previously encoded should immediately be written to their intended * destination. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void endEncoding() throws OncRpcException, IOException { DatagramPacket packet = new DatagramPacket(buffer, bufferIndex, receiverAddress, receiverPort); socket.send(packet); } /** * Closes this encoding XDR stream and releases any system resources * associated with this stream. The general contract of close * is that it closes the encoding XDR stream. A closed XDR stream cannot * perform encoding operations and cannot be reopened. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void close() throws OncRpcException, IOException { buffer = null; socket = null; } /** * Encodes (aka "serializes") a "XDR int" value and writes it down a * XDR stream. A XDR int is 32 bits wide -- the same width Java's "int" * data type has. This method is one of the basic methods all other * methods can rely on. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrEncodeInt(int value) throws OncRpcException, IOException { if ( bufferIndex <= bufferHighmark ) { // // There's enough space in the buffer, so encode this int as // four bytes (french octets) in big endian order (that is, the // most significant byte comes first. // buffer[bufferIndex++] = (byte)(value >>> 24); buffer[bufferIndex++] = (byte)(value >>> 16); buffer[bufferIndex++] = (byte)(value >>> 8); buffer[bufferIndex++] = (byte) value; } else { throw(new OncRpcException(OncRpcException.RPC_BUFFEROVERFLOW)); } } /** * Encodes (aka "serializes") a XDR opaque value, which is represented * by a vector of byte values, and starts at offset with a * length of length. Only the opaque value is encoded, but * no length indication is preceeding the opaque value, so the receiver * has to know how long the opaque value will be. The encoded data is * always padded to be a multiple of four. If the given length is not a * multiple of four, zero bytes will be used for padding. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrEncodeOpaque(byte [] value, int offset, int length) throws OncRpcException, IOException { // // First calculate the number of bytes needed for padding. // int padding = (4 - (length & 3)) & 3; if ( bufferIndex <= bufferHighmark - (length + padding) ) { System.arraycopy(value, offset, buffer, bufferIndex, length); bufferIndex += length; if ( padding != 0 ) { // // If the length of the opaque data was not a multiple, then // pad with zeros, so the write pointer (argh! how comes Java // has a pointer...?!) points to a byte, which has an index // of a multiple of four. // System.arraycopy(paddingZeros, 0, buffer, bufferIndex, padding); bufferIndex += padding; } } else { throw(new OncRpcException(OncRpcException.RPC_BUFFEROVERFLOW)); } } /** * The datagram socket to be used when sending this XDR stream's * buffer contents. */ private DatagramSocket socket; /** * Receiver address of current buffer contents when flushed. */ private InetAddress receiverAddress = null; /** * The receiver's port. */ private int receiverPort = 0; /** * The buffer which will receive the encoded information, before it * is sent via a datagram socket. */ private byte [] buffer; /** * The write pointer is an index into the buffer. */ private int bufferIndex; /** * Index of the last four byte word in the buffer. */ private int bufferHighmark; /** * Some zeros, only needed for padding -- like in real life. */ private static final byte [] paddingZeros = { 0, 0, 0, 0 }; } // End of XdrUdpEncodingStream remotetea-1.0.7/src/org/acplt/oncrpc/XdrUnion.java0000644005374700003410000001617407716406376023227 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/XdrUnion.java,v 1.1.1.1 2003/08/13 12:03:41 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; import java.io.IOException; import java.io.InvalidClassException; /** * The abstract base class XdrUnion helps (de-)serializing * polymorphic classes. This class should not be confused with C unions in * general. Instead XdrUnion is an object-oriented construct * which helps in deploying polymorphism. For examples on how to use this, * please take a look at the "ACPLTea Java Library" package, which is also * available from www.acplt.org/ks. As a sidenote, the * serialization scheme implemented by XdrUnion is only a question * of getting used to it: after serializing the type code of the polymorphic * class, the variant part is serialized first before the common part. This * behaviour stems from the ACPLT C++ Communication Library and has been * retained for compatibility reasons. As it doesn't hurt, you won't mind * anyway. * *

    To use polymorphism with XDR streams, you'll have to derive your own base * class (let's call it foo from XdrUnion * and implement the two methods * {@link #xdrEncodeCommon(XdrEncodingStream)} and * {@link #xdrDecodeCommon(XdrDecodingStream)}. Do not overwrite * the methods xdrEncode and xdrDecode! * *

    Then, in your foo-derived classes, like bar * and baz, implement the other two methods * {@link #xdrEncodeVariant(XdrEncodingStream)} and * {@link #xdrDecodeVariant(XdrDecodingStream)}. In addition, implement * {@link #getXdrTypeCode} to return an int, uniquely identifying your * class. Note that this identifier only needs to be unique within the scope * of your foo class. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:41 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public abstract class XdrUnion implements XdrAble { /** * Returns the so-called type code which identifies a derived class when * encoded or decoded. Note that the type code is not globally unique, but * rather it is only unique within the derived classes of a direct descend * of XdrUnion. If foo is derived from XdrUnion * and foo is the base class for bar and * baz, then the type code needs only be unique between * bar and baz. * * @return Type code identifying an object's class when encoding or * decoding the object into or from a XDR stream. */ public abstract int getXdrTypeCode(); /** * Encodes -- that is: serializes -- an object into a XDR stream in * compliance to RFC 1832. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException { // // For historial reasons (read: "for dumb and pure idiotic reasons") // and compatibility with the ACPLT/KS C++ Communication Library we // encode/decode the variant part *first* before encoding/decoding // the common part. // xdr.xdrEncodeInt(getXdrTypeCode()); xdrEncodeVariant(xdr); xdrEncodeCommon(xdr); } /** * Decodes -- that is: deserializes -- an object from a XDR stream in * compliance to RFC 1832. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException { // // Make sure that when deserializing this object's state that // the stream provides state information indeed intended for this // particular class. // int xdrTypeCode = xdr.xdrDecodeInt(); if ( xdrTypeCode != getXdrTypeCode() ) { throw(new InvalidClassException(this.getClass().getName(), "non-matching XDR type code received.")); } // // For historial reasons (read: "for dumb and pure idiotic reasons") // and compatibility with the ACPLT/KS C++ Communication Library we // encode/decode the variant part *first* before encoding/decoding // the common part. // xdrDecodeVariant(xdr); xdrDecodeCommon(xdr); } /** * Encodes -- that is: serializes -- the common part of an object into * a XDR stream in compliance to RFC 1832. Note that the common part is * deserialized after the variant part. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public abstract void xdrEncodeCommon(XdrEncodingStream xdr) throws OncRpcException, IOException; /** * Decodes -- that is: deserializes -- the common part of an object from * a XDR stream in compliance to RFC 1832. Note that the common part is * deserialized after the variant part. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public abstract void xdrDecodeCommon(XdrDecodingStream xdr) throws OncRpcException, IOException; /** * Encodes -- that is: serializes -- the variant part of an object into * a XDR stream in compliance to RFC 1832. Note that the variant part is * deserialized before the common part. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public abstract void xdrEncodeVariant(XdrEncodingStream xdr) throws OncRpcException, IOException; /** * Decodes -- that is: deserializes -- the variant part of an object from * a XDR stream in compliance to RFC 1832. Note that the variant part is * deserialized before the common part. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public abstract void xdrDecodeVariant(XdrDecodingStream xdr) throws OncRpcException, IOException; } // End of XdrUnion.java remotetea-1.0.7/src/org/acplt/oncrpc/XdrVoid.java0000644005374700003410000000532007716406376023027 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/org/acplt/oncrpc/XdrVoid.java,v 1.1.1.1 2003/08/13 12:03:41 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.acplt.oncrpc; import java.io.IOException; /** * Instances of the class XdrVoid represent (de-)serializeable * voids, which are especially useful in cases where no result is expected * from a remote function call or no parameters are supplied. * *

    Please note that this class is somewhat modelled after Java's primitive * data type wrappers. As for these classes, the XDR data type wrapper classes * follow the concept of values with no identity, so you are not allowed to * change the value after you've created a value object. * * @version $Revision: 1.1.1.1 $ $Date: 2003/08/13 12:03:41 $ $State: Exp $ $Locker: $ * @author Harald Albrecht */ public class XdrVoid implements XdrAble { /** * Encodes -- that is: serializes -- a void into a XDR stream in * compliance to RFC 1832. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException { } /** * Decodes -- that is: deserializes -- a void from a XDR stream in * compliance to RFC 1832. * * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException { } /** * Static XdrVoid instance, which can be used in cases * where no data is to be serialized or deserialized but some ONC/RPC * function expects a reference to a XDR-able object. */ public final static XdrVoid XDR_VOID = new XdrVoid(); } // End of XdrVoid.java remotetea-1.0.7/src/org/acplt/oncrpc/package.html0000644005374700003410000004272010627063312023053 0ustar piccainstrumentation ONC/RPC for Java package Sun's ONC/RPC Remote Procedure Call mechanism.

    This package implements Sun's ONC/RPC Remote Procedure Call specification (see RFC 1831, RFC 1832, RFC 1833).

    Functionality currently supported:

    • RPC calls over TCP/IP as well as UDP/IP.
    • RPC client functionality.
    • RPC server functionality (see package org.acplt.oncrpc.server).
    • Querying the ONC/RPC portmapper.
    • jrpcgen-utility for converting x-files into Java classes.
    • Support for authentication types AUTH_NONE, AUTH_UNIX and AUTH_SHORT on both the client and the server side.

    To manually convert x-files into serializable Java classes, first map the primitive rpcgen data types (and thus the data types described in RFC 1832 to some extend) onto Java's primitive data types. The following table should help you doing this.
    rpcgen / RFC 1832Java
    char
    (used as character)
    8 bits / platform dependent byte8 bits xdr.xdrEncodeByte(byte)
    byte = xdr.xdrDecodeByte()
    unsigned char
    (used as character)
    8 bits / platform dependent byte8 bits xdr.xdrEncodeByte(byte)
    byte = xdr.xdrDecodeByte()
    char
    (used as 8 bit quantitiy)
    8 bits / platform dependent byte8 bits xdr.xdrEncodeByte(byte)
    byte = xdr.xdrDecodeByte()
    unsigned char
    (used as 8 bit quantitiy)
    8 bits / platform dependent byte8 bits xdr.xdrEncodeByte(byte)
    byte = xdr.xdrDecodeByte()
    shortplatform dependent short16 bits xdr.xdrEncodeShort(short)
    short = xdr.xdrDecodeShort()
    unsigned shortplatform dependent short16 bits xdr.xdrEncodeShort(short)
    short = xdr.xdrDecodeShort()
    int32 bits int32 bits xdr.xdrEncodeInt(int)
    int = xdr.xdrDecodeInt()
    unsigned int32 bits int32 bits xdr.xdrEncodeInt(int)
    int = xdr.xdrDecodeInt()
    hyper64 bits long64 bits xdr.xdrEncodeLong(long)
    long = xdr.xdrDecodeLong()
    unsigned hyper64 bits long64 bits xdr.xdrEncodeLong(long)
    long = xdr.xdrDecodeLong()
    enum32 bits int32 bits xdr.xdrEncodeInt(int)
    int = xdr.xdrDecodeInt()
    bool  boolean  xdr.xdrEncodeBoolean(boolean)
    boolean = xdr.xdrDecodeBoolean()
    float32 bits float32 bits xdr.xdrEncodeFloat(float)
    float = xdr.xdrDecodeFloat()
    double64 bits double64 bits xdr.xdrEncodeDouble(double)
    double = xdr.xdrDecodeDouble()
    quadruple128 bits n/a   
    opaque[n]exactly n octets byte[]n bytes xdr.xdrEncodeOpaque(byte[])
    byte[] = xdr.xdrDecodeOpaque(n)
    opaque<n>4 bytes size followed by
    at most n octets
    byte[]?? bytes xdr.xdrEncodeDynamicOpaque(byte[])
    byte[] = xdr.xdrDecodeDynamicOpaque()
    opaque<>4 bytes size followed by
    ?? octets
    byte[]?? bytes xdr.xdrEncodeDynamicOpaque(byte[])
    byte[] = xdr.xdrDecodeDynamicOpaque()
    string<n>4 bytes size followed by
    at most n octets
    String?? bytes xdr.xdrEncodeString(String)
    String = xdr.xdrDecodeString()
    string<>4 bytes size followed by
    ?? octets
    String?? bytes xdr.xdrEncodeString(String)
    String = xdr.xdrDecodeString()
    void0 bits XdrVoid  xdrvoid.xdrEncode(xdr)
    xdrvoid.xdrDecode(xdr)

    The Remote Tea library also provides method to (de-) serialize vector data types of variable length, as shown below. To (de-) derialize fixed-size vectors, use the ...FixedVector() variants and supply the protocol-defined size of the vector -- see the next table but one.
    rpcgen / RFC 1832Java
    opaque<>4 bytes size followed by
    ?? octets
    byte[] xdr.xdrEncodeDynamicOpaque(byte[])
    byte[] = xdr.xdrDecodeDynamicOpaque()
    char<>
    char short<>
    4 bytes size followed by
    ?? chars
    byte[] xdr.xdrEncodeByteVector(byte[])
    byte[] = xdr.xdrDecodeByteVector()
    short<>
    unsigned short<>
    4 bytes size followed by
    ?? shorts
    short[] xdr.xdrEncodeShortVector(short[])
    short[] = xdr.xdrDecodeShortVector()
    int<>
    unsigned int<>
    4 bytes size followed by
    ?? ints
    int[] xdr.xdrEncodeIntVector(int[])
    int[] = xdr.xdrDecodeIntVector()
    long<>
    unsigned long<>
    4 bytes size followed by
    ?? longs
    int[] xdr.xdrEncodeIntVector(int[])
    int[] = xdr.xdrDecodeIntVector()
    hyper<>
    unsigned hyper<>
    4 bytes size followed by
    ?? hypers
    long[] xdr.xdrEncodeLongVector(long[])
    long[] = xdr.xdrDecodeLongVector()
    enum<>4 bytes size followed by
    ?? enums
    int[] xdr.xdrEncodeIntVector(int[])
    int[] = xdr.xdrDecodeIntVector()
    bool<>4 bytes size followed by
    ?? bools
    boolean[] xdr.xdrEncodeBooleanVector(boolean[])
    boolean[] = xdr.xdrDecodeBooleanVector()
    float<>4 bytes size followed by
    ?? floats
    float[] xdr.xdrEncodeFloatVector(float[])
    float[] = xdr.xdrDecodeFloatVector()
    double<>4 bytes size followed by
    ?? doubles
    double[] xdr.xdrEncodeDoubleVector(double[])
    double[] = xdr.xdrDecodeDoubleVector()

    And now for (de-) serializing fixed-size vectors:
    rpcgen / RFC 1832Java
    char[n]
    char short[n]
    4 bytes size followed by
    n chars
    byte[] xdr.xdrEncodeByteFixedVector(byte[], int n)
    byte[] = xdr.xdrDecodeByteFixedVector(int n)
    short[n]
    unsigned short[n]
    4 bytes size followed by
    n shorts
    short[] xdr.xdrEncodeShortFixedVector(short[], int n)
    short[] = xdr.xdrDecodeShortFixedVector(int n)
    int[n]
    unsigned int[n]
    4 bytes size followed by
    n ints
    int[] xdr.xdrEncodeIntFixedVector(int[], int n)
    int[] = xdr.xdrDecodeIntFixedVector(int n)
    long[n]
    unsigned long[n]
    4 bytes size followed by
    n longs
    int[] xdr.xdrEncodeIntFixedVector(int[], int n)
    int[] = xdr.xdrDecodeIntFixedVector(int n)
    hyper[n]
    unsigned hyper[n]
    4 bytes size followed by
    n hypers
    long[] xdr.xdrEncodeLongFixedVector(long[], int n)
    long[] = xdr.xdrDecodeLongFixedVector(int n)
    enum[n]4 bytes size followed by
    n enums
    int[] xdr.xdrEncodeIntFixedVector(int[], int n)
    int[] = xdr.xdrDecodeIntFixedVector(int n)
    bool[n]4 bytes size followed by
    n bools
    boolean[] xdr.xdrEncodeBooleanFixedVector(boolean[], int n)
    boolean[] = xdr.xdrDecodeBooleanFixedVector(int n)
    float[n]4 bytes size followed by
    n floats
    float[] xdr.xdrEncodeFloatFixedVector(float[], int n)
    float[] = xdr.xdrDecodeFloatFixedVector(int n)
    double[n]4 bytes size followed by
    n doubles
    double[] xdr.xdrEncodeDoubleFixedVector(double[], int n)
    double[] = xdr.xdrDecodeDoubleFixedVector(int n)

    For every structure you encounter in a .x file, write a Java class, which implements the XdrAble interface. For instance, taking this snippet from a rpcgen source file...

    struct foo {
        int bar;
        float baz;
        struct foo *next;
    };
    

    ...struct foo is translated into Java ONC/RPC babble as:

    class foo implements XdrAble {
       // members of foo structure
       public int bar;
       public float baz;
       public foo next;
    
       // serialize / encode foo
        public void xdrEncode(XdrEncodingStream xdr)
               throws OncRpcException, IOException {
            xdr.xdrEncodeInt(bar);
            xdr.xdrEncodeFloat(baz);
            if ( next == null ) {
                xdr.xdrEncodeBoolean(false);
            } else {
                xdr.xdrEncodeBoolean(true);
                next.xdrEncode(xdr);
            }
        }
    
        // deserialize / decode foo
        public void xdrDecode(XdrDecodingStream xdr)
               throws OncRpcException, IOException {
            bar = xdr.xdrDecodeInt();
            baz = xdr.xdrDecodeFloat();
            if ( !xdr.xdrDecodeBoolean() ) {
                next = null;
            } else {
                next = new foo();
                next.xdrDecode(xdr);
            }
        }
    }
    

    The previous example also shows how to deal with pointers (eeek!) in .x files. The are simply transformed into references -- quite a difference, really.

    Tanslating a descriminated union is typically done the simple and silly way. Silly, because unions can not really be represented in the Java language. You need to transform them into a class (structure) instead, and this will lead to a rather ugly form.

    union foo switch (FOOTYPE type) {
        case BAR_CLASS:
            bar u_bar;
        case BAZ_CLASS:
            baz u_baz;
    }
    
    should become
    class foo implements XdrAble {
        // descriminant value
        public int type;
        // arm declarations
        public bar u_bar;
        public baz u_baz;
    
        // descriminant-arm values
        public static int BAR_CLASS = 1;
        public static int BAZ_CLASS = 2;
    
        // serialize / encode foo
        public void xdrEncode(XdrEncodingStream xdr)
               throws OncRpcException, IOException {
            xdr.xdrEncodeInt(type);
            switch ( type ) {
            case BAR_CLASS:
                u_bar.xdrEncode(xdr); break;
            case BAZ_CLASS:
                u_baz.xdrEncode(xdr); break;
            }
        }
    
        // deserialize / decode foo
        public void xdrDecode(XdrDecodingStream xdr)
               throws OncRpcException, IOException {
            type = xdr.xdrDecodeInt();
            switch ( type ) {
            case BAR_CLASS:
                u_bar = new bar(); u_bar.xdrDecode(xdr); break;
            case BAZ_CLASS:
                u_baz = new bar(); u_bar.xdrDecode(xdr); break;
            }
        }
    }
    

    You can also take advantage of polymorphism when translating descriminated unions into a class hierarchy. You should then write an abstract base class with only one static member function capable of constructing the appropriate instance from the XDR stream. The tricky part about this is getting the descriminant value into the stream or out of it without having to duplicate the decoding code into the constructor. With the skeleton below you should be able to do this easily, but you should remember to never recycle an object reference and never deserialize the state of the object a second time from a XDR stream!

    abstract class foobase implements XdrAble {
        // construct a bar, baz,... class from XDR stream
        public static foobase xdrNew(XdrDecodingStream xdr)
               throws OncRpcException, IOException {
            foobase obj = null;
            switch ( xdr.xdrDecodeInt() ) {
            case BAR_CLASS:
                obj = new bar(); break;
            case BAZ_CLASS:
                obj = new baz(); break;
            }
            obj.xdrDecode(xdr);
            return obj;
        }
    
        public abstract void xdrEncode(XdrEncodingStream xdr)
               throws OncRpcException, IOException;
        public abstract void xdrDecode(XdrDecodingStream xdr)
               throws OncRpcException, IOException;
    
        // descriminant values
        public static int BAR_CLASS = 1;
        public static int BAZ_CLASS = 2;
    }
    
    class bar extends foobase {
        public void xdrEncode(XdrEncodingStream xdr)
               throws OncRpcException, IOException {
            // encode your members here...
            // dont forget to encode the descriminant value
            xdr.xdrEncodeInt(BAR_CLASS);
            xdr.xdrEncodeFloat(noah);
        }
        public void xdrDecode(XdrDecodingStream xdr)
               throws OncRpcException, IOException {
            // decode your members here...
            // but *NEVER* decode the descriminant value
            noah = xdr.xdrDecodeFloat();
        }
    }
    
    

    This package is part of the ACPLT/KS ACPLTea Java Library package.

    (c) 1999, 2006 Harald Albrecht.
    (c) 1999, 2002 Lehrstuhl für Prozeßleittechnik, Aachen University of Technology, Germany.

    This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License along with this program (see the file COPYING.LIB for more details); if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. remotetea-1.0.7/src/tests/0000755005374700003410000000000010736702150016552 5ustar piccainstrumentationremotetea-1.0.7/src/tests/org/0000755005374700003410000000000010736702150017341 5ustar piccainstrumentationremotetea-1.0.7/src/tests/org/acplt/0000755005374700003410000000000010736702150020444 5ustar piccainstrumentationremotetea-1.0.7/src/tests/org/acplt/oncrpc/0000755005374700003410000000000010736702150021730 5ustar piccainstrumentationremotetea-1.0.7/src/tests/org/acplt/oncrpc/jrpcgen/0000755005374700003410000000000010736702150023360 5ustar piccainstrumentationremotetea-1.0.7/src/tests/org/acplt/oncrpc/jrpcgen/ANSWER.java0000644005374700003410000000300710627063200025215 0ustar piccainstrumentation/* * Automatically generated by jrpcgen 1.0.7 on 29.05.07 21:34 * jrpcgen is part of the "Remote Tea" ONC/RPC package for Java * See http://remotetea.sourceforge.net for details */ package tests.org.acplt.oncrpc.jrpcgen; import org.acplt.oncrpc.*; import java.io.IOException; public class ANSWER implements XdrAble, java.io.Serializable { public int value; public int wrong; public int the_answer; public int check_hash; private static final long serialVersionUID = 5165359675382683141L; public ANSWER() { } public ANSWER(XdrDecodingStream xdr) throws OncRpcException, IOException { xdrDecode(xdr); } public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException { xdr.xdrEncodeInt(value); switch ( value ) { case 40: case 41: xdr.xdrEncodeInt(wrong); break; case 42: xdr.xdrEncodeInt(the_answer); break; default: xdr.xdrEncodeInt(check_hash); break; } } public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException { value = xdr.xdrDecodeInt(); switch ( value ) { case 40: case 41: wrong = xdr.xdrDecodeInt(); break; case 42: the_answer = xdr.xdrDecodeInt(); break; default: check_hash = xdr.xdrDecodeInt(); break; } } } // End of ANSWER.java remotetea-1.0.7/src/tests/org/acplt/oncrpc/jrpcgen/ENUMBAZ.java0000644005374700003410000000056710627063200025327 0ustar piccainstrumentation/* * Automatically generated by jrpcgen 1.0.7 on 29.05.07 21:34 * jrpcgen is part of the "Remote Tea" ONC/RPC package for Java * See http://remotetea.sourceforge.net for details */ package tests.org.acplt.oncrpc.jrpcgen; /** * Enumeration (collection of constants). */ public interface ENUMBAZ { public static final int E_BAZ = demo.C_B; } // End of ENUMBAZ.java remotetea-1.0.7/src/tests/org/acplt/oncrpc/jrpcgen/ENUMBAZ2.java0000644005374700003410000000057210627063200025405 0ustar piccainstrumentation/* * Automatically generated by jrpcgen 1.0.7 on 29.05.07 21:34 * jrpcgen is part of the "Remote Tea" ONC/RPC package for Java * See http://remotetea.sourceforge.net for details */ package tests.org.acplt.oncrpc.jrpcgen; /** * Enumeration (collection of constants). */ public interface ENUMBAZ2 { public static final int E_BAZ = demo2.C_B; } // End of ENUMBAZ2.java remotetea-1.0.7/src/tests/org/acplt/oncrpc/jrpcgen/ENUMFOO.java0000644005374700003410000000104610627063200025327 0ustar piccainstrumentation/* * Automatically generated by jrpcgen 1.0.7 on 29.05.07 21:34 * jrpcgen is part of the "Remote Tea" ONC/RPC package for Java * See http://remotetea.sourceforge.net for details */ package tests.org.acplt.oncrpc.jrpcgen; /** * Enumeration (collection of constants). */ public interface ENUMFOO { public static final int FOO = 0; public static final int BAR = 0+1; public static final int BAZ_1 = demo.C_B; public static final int BAZ_2 = demo.C_B+1; public static final int BAZ_3 = ENUMBAZ.E_BAZ; } // End of ENUMFOO.java remotetea-1.0.7/src/tests/org/acplt/oncrpc/jrpcgen/ENUMFOO2.java0000644005374700003410000000105310627063200025407 0ustar piccainstrumentation/* * Automatically generated by jrpcgen 1.0.7 on 29.05.07 21:34 * jrpcgen is part of the "Remote Tea" ONC/RPC package for Java * See http://remotetea.sourceforge.net for details */ package tests.org.acplt.oncrpc.jrpcgen; /** * Enumeration (collection of constants). */ public interface ENUMFOO2 { public static final int FOO = 0; public static final int BAR = 0+1; public static final int BAZ_1 = demo2.C_B; public static final int BAZ_2 = demo2.C_B+1; public static final int BAZ_3 = ENUMBAZ2.E_BAZ; } // End of ENUMFOO2.java remotetea-1.0.7/src/tests/org/acplt/oncrpc/jrpcgen/LINKEDLIST.java0000644005374700003410000000303110627063200025655 0ustar piccainstrumentation/* * Automatically generated by jrpcgen 1.0.7 on 29.05.07 21:34 * jrpcgen is part of the "Remote Tea" ONC/RPC package for Java * See http://remotetea.sourceforge.net for details */ package tests.org.acplt.oncrpc.jrpcgen; import org.acplt.oncrpc.*; import java.io.IOException; public class LINKEDLIST implements XdrAble, java.io.Serializable { protected int foo; protected LINKEDLIST next; private static final long serialVersionUID = -9187504517170663946L; public void setFoo(int x) { this.foo = x; } public int getFoo() { return this.foo; } public void setNext(LINKEDLIST x) { this.next = x; } public LINKEDLIST getNext() { return this.next; } public LINKEDLIST() { } public LINKEDLIST(XdrDecodingStream xdr) throws OncRpcException, IOException { xdrDecode(xdr); } public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException { LINKEDLIST $this = this; do { xdr.xdrEncodeInt($this.foo); $this = $this.next; xdr.xdrEncodeBoolean($this != null); } while ( $this != null ); } public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException { LINKEDLIST $this = this; LINKEDLIST $next; do { $this.foo = xdr.xdrDecodeInt(); $next = xdr.xdrDecodeBoolean() ? new LINKEDLIST() : null; $this.next = $next; $this = $next; } while ( $this != null ); } } // End of LINKEDLIST.java remotetea-1.0.7/src/tests/org/acplt/oncrpc/jrpcgen/SILLYSTRUCT.java0000644005374700003410000000573710627063200026073 0ustar piccainstrumentation/* * Automatically generated by jrpcgen 1.0.7 on 29.05.07 21:34 * jrpcgen is part of the "Remote Tea" ONC/RPC package for Java * See http://remotetea.sourceforge.net for details */ package tests.org.acplt.oncrpc.jrpcgen; import org.acplt.oncrpc.*; import java.io.IOException; public class SILLYSTRUCT implements XdrAble, java.io.Serializable { protected byte [] fixedbuffer; protected byte [] buffer; protected byte [] fixedbytes; protected byte [] bytes; protected int ui1; protected int ui2; protected String nonsense; private static final long serialVersionUID = 4109809708757592008L; public void setFixedbuffer(byte[] x) { this.fixedbuffer = x; } public void setFixedbuffer(int index, byte x) { this.fixedbuffer[index] = x; } public byte[] getFixedbuffer() { return this.fixedbuffer; } public byte getFixedbuffer(int index) { return this.fixedbuffer[index]; } public void setBuffer(byte[] x) { this.buffer = x; } public void setBuffer(int index, byte x) { this.buffer[index] = x; } public byte[] getBuffer() { return this.buffer; } public byte getBuffer(int index) { return this.buffer[index]; } public void setFixedbytes(byte[] x) { this.fixedbytes = x; } public void setFixedbytes(int index, byte x) { this.fixedbytes[index] = x; } public byte[] getFixedbytes() { return this.fixedbytes; } public byte getFixedbytes(int index) { return this.fixedbytes[index]; } public void setBytes(byte[] x) { this.bytes = x; } public void setBytes(int index, byte x) { this.bytes[index] = x; } public byte[] getBytes() { return this.bytes; } public byte getBytes(int index) { return this.bytes[index]; } public void setUi1(int x) { this.ui1 = x; } public int getUi1() { return this.ui1; } public void setUi2(int x) { this.ui2 = x; } public int getUi2() { return this.ui2; } public void setNonsense(String x) { this.nonsense = x; } public String getNonsense() { return this.nonsense; } public SILLYSTRUCT() { } public SILLYSTRUCT(XdrDecodingStream xdr) throws OncRpcException, IOException { xdrDecode(xdr); } public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException { xdr.xdrEncodeByteFixedVector(fixedbuffer, 512); xdr.xdrEncodeByteVector(buffer); xdr.xdrEncodeOpaque(fixedbytes, demo.FIXEDBUFFERLENGTH); xdr.xdrEncodeDynamicOpaque(bytes); xdr.xdrEncodeInt(ui1); xdr.xdrEncodeInt(ui2); xdr.xdrEncodeString(nonsense); } public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException { fixedbuffer = xdr.xdrDecodeByteFixedVector(512); buffer = xdr.xdrDecodeByteVector(); fixedbytes = xdr.xdrDecodeOpaque(demo.FIXEDBUFFERLENGTH); bytes = xdr.xdrDecodeDynamicOpaque(); ui1 = xdr.xdrDecodeInt(); ui2 = xdr.xdrDecodeInt(); nonsense = xdr.xdrDecodeString(); } } // End of SILLYSTRUCT.java remotetea-1.0.7/src/tests/org/acplt/oncrpc/jrpcgen/SOMERESULT.java0000644005374700003410000000307610627063200025726 0ustar piccainstrumentation/* * Automatically generated by jrpcgen 1.0.7 on 29.05.07 21:34 * jrpcgen is part of the "Remote Tea" ONC/RPC package for Java * See http://remotetea.sourceforge.net for details */ package tests.org.acplt.oncrpc.jrpcgen; import org.acplt.oncrpc.*; import java.io.IOException; public class SOMERESULT implements XdrAble, java.io.Serializable { protected int error; protected String typedesc; protected byte [] data; private static final long serialVersionUID = -6867149493429413131L; public void setError(int x) { this.error = x; } public int getError() { return this.error; } public void setTypedesc(String x) { this.typedesc = x; } public String getTypedesc() { return this.typedesc; } public void setData(byte[] x) { this.data = x; } public void setData(int index, byte x) { this.data[index] = x; } public byte[] getData() { return this.data; } public byte getData(int index) { return this.data[index]; } public SOMERESULT() { } public SOMERESULT(XdrDecodingStream xdr) throws OncRpcException, IOException { xdrDecode(xdr); } public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException { xdr.xdrEncodeInt(error); xdr.xdrEncodeString(typedesc); xdr.xdrEncodeDynamicOpaque(data); } public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException { error = xdr.xdrDecodeInt(); typedesc = xdr.xdrDecodeString(); data = xdr.xdrDecodeDynamicOpaque(); } } // End of SOMERESULT.java remotetea-1.0.7/src/tests/org/acplt/oncrpc/jrpcgen/STRING.java0000644005374700003410000000171410627063200025227 0ustar piccainstrumentation/* * Automatically generated by jrpcgen 1.0.7 on 29.05.07 21:34 * jrpcgen is part of the "Remote Tea" ONC/RPC package for Java * See http://remotetea.sourceforge.net for details */ package tests.org.acplt.oncrpc.jrpcgen; import org.acplt.oncrpc.*; import java.io.IOException; public class STRING implements XdrAble, java.io.Serializable { public String value; private static final long serialVersionUID = -5513160560686984193L; public STRING() { } public STRING(String value) { this.value = value; } public STRING(XdrDecodingStream xdr) throws OncRpcException, IOException { xdrDecode(xdr); } public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException { xdr.xdrEncodeString(value); } public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException { value = xdr.xdrDecodeString(); } } // End of STRING.java remotetea-1.0.7/src/tests/org/acplt/oncrpc/jrpcgen/STRINGVECTOR.java0000644005374700003410000000230410627063200026146 0ustar piccainstrumentation/* * Automatically generated by jrpcgen 1.0.7 on 29.05.07 21:34 * jrpcgen is part of the "Remote Tea" ONC/RPC package for Java * See http://remotetea.sourceforge.net for details */ package tests.org.acplt.oncrpc.jrpcgen; import org.acplt.oncrpc.*; import java.io.IOException; public class STRINGVECTOR implements XdrAble, java.io.Serializable { public STRING [] value; private static final long serialVersionUID = -6645878168698853047L; public STRINGVECTOR() { } public STRINGVECTOR(STRING [] value) { this.value = value; } public STRINGVECTOR(XdrDecodingStream xdr) throws OncRpcException, IOException { xdrDecode(xdr); } public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException { { int $size = value.length; xdr.xdrEncodeInt($size); for ( int $idx = 0; $idx < $size; ++$idx ) { value[$idx].xdrEncode(xdr); } } } public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException { { int $size = xdr.xdrDecodeInt(); value = new STRING[$size]; for ( int $idx = 0; $idx < $size; ++$idx ) { value[$idx] = new STRING(xdr); } } } } // End of STRINGVECTOR.java remotetea-1.0.7/src/tests/org/acplt/oncrpc/jrpcgen/TREE.java0000644005374700003410000000404010627063200024753 0ustar piccainstrumentation/* * Automatically generated by jrpcgen 1.0.7 on 29.05.07 21:34 * jrpcgen is part of the "Remote Tea" ONC/RPC package for Java * See http://remotetea.sourceforge.net for details */ package tests.org.acplt.oncrpc.jrpcgen; import org.acplt.oncrpc.*; import java.io.IOException; public class TREE implements XdrAble, java.io.Serializable { protected String key; protected String value; protected TREE left; protected TREE right; private static final long serialVersionUID = 2403962346676670641L; public void setKey(String x) { this.key = x; } public String getKey() { return this.key; } public void setValue(String x) { this.value = x; } public String getValue() { return this.value; } public void setLeft(TREE x) { this.left = x; } public TREE getLeft() { return this.left; } public void setRight(TREE x) { this.right = x; } public TREE getRight() { return this.right; } public TREE() { } public TREE(XdrDecodingStream xdr) throws OncRpcException, IOException { xdrDecode(xdr); } public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException { TREE $this = this; do { xdr.xdrEncodeString($this.key); xdr.xdrEncodeString($this.value); if ( $this.left != null ) { xdr.xdrEncodeBoolean(true); $this.left.xdrEncode(xdr); } else { xdr.xdrEncodeBoolean(false); }; $this = $this.right; xdr.xdrEncodeBoolean($this != null); } while ( $this != null ); } public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException { TREE $this = this; TREE $next; do { $this.key = xdr.xdrDecodeString(); $this.value = xdr.xdrDecodeString(); $this.left = xdr.xdrDecodeBoolean() ? new TREE(xdr) : null; $next = xdr.xdrDecodeBoolean() ? new TREE() : null; $this.right = $next; $this = $next; } while ( $this != null ); } } // End of TREE.java remotetea-1.0.7/src/tests/org/acplt/oncrpc/jrpcgen/TREE2.java0000644005374700003410000000304510627063200025041 0ustar piccainstrumentation/* * Automatically generated by jrpcgen 1.0.7 on 29.05.07 21:34 * jrpcgen is part of the "Remote Tea" ONC/RPC package for Java * See http://remotetea.sourceforge.net for details */ package tests.org.acplt.oncrpc.jrpcgen; import org.acplt.oncrpc.*; import java.io.IOException; public class TREE2 implements XdrAble { public String key; public String value; public TREE2 left; public TREE2 right; public TREE2() { } public TREE2(XdrDecodingStream xdr) throws OncRpcException, IOException { xdrDecode(xdr); } public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException { TREE2 $this = this; do { xdr.xdrEncodeString($this.key); xdr.xdrEncodeString($this.value); if ( $this.left != null ) { xdr.xdrEncodeBoolean(true); $this.left.xdrEncode(xdr); } else { xdr.xdrEncodeBoolean(false); }; $this = $this.right; xdr.xdrEncodeBoolean($this != null); } while ( $this != null ); } public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException { TREE2 $this = this; TREE2 $next; do { $this.key = xdr.xdrDecodeString(); $this.value = xdr.xdrDecodeString(); $this.left = xdr.xdrDecodeBoolean() ? new TREE2(xdr) : null; $next = xdr.xdrDecodeBoolean() ? new TREE2() : null; $this.right = $next; $this = $next; } while ( $this != null ); } } // End of TREE2.java remotetea-1.0.7/src/tests/org/acplt/oncrpc/jrpcgen/UNION.java0000644005374700003410000000226210627063200025110 0ustar piccainstrumentation/* * Automatically generated by jrpcgen 1.0.7 on 29.05.07 21:34 * jrpcgen is part of the "Remote Tea" ONC/RPC package for Java * See http://remotetea.sourceforge.net for details */ package tests.org.acplt.oncrpc.jrpcgen; import org.acplt.oncrpc.*; import java.io.IOException; public class UNION implements XdrAble, java.io.Serializable { public boolean okay; public LINKEDLIST list; private static final long serialVersionUID = -5038378683068054714L; public UNION() { } public UNION(XdrDecodingStream xdr) throws OncRpcException, IOException { xdrDecode(xdr); } public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException { xdr.xdrEncodeBoolean(okay); if ( okay == true ) { if ( list != null ) { xdr.xdrEncodeBoolean(true); list.xdrEncode(xdr); } else { xdr.xdrEncodeBoolean(false); }; } } public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException { okay = xdr.xdrDecodeBoolean(); if ( okay == true ) { list = xdr.xdrDecodeBoolean() ? new LINKEDLIST(xdr) : null; } } } // End of UNION.java remotetea-1.0.7/src/tests/org/acplt/oncrpc/jrpcgen/demo.java0000644005374700003410000000226710627063200025151 0ustar piccainstrumentation/* * Automatically generated by jrpcgen 1.0.7 on 29.05.07 21:34 * jrpcgen is part of the "Remote Tea" ONC/RPC package for Java * See http://remotetea.sourceforge.net for details */ package tests.org.acplt.oncrpc.jrpcgen; /** * A collection of constants used by the "demo" ONC/RPC program. */ public interface demo { public static final int foo_1 = 4; public static final int ll_1 = 5; public static final int echo_1 = 1; public static final int readSomeResult_1 = 42; public static final int test_2 = 100; public static final int checkfoo_2 = 3; public static final int checkfoo_1 = 3; public static final int C_C = 42; public static final int C_A = C_C; public static final int C_B = C_A; public static final int concat_1 = 2; public static final int cat3_2 = 43; public static final int FIXEDBUFFERLENGTH = 64; public static final int cat_2 = 42; public static final int llcat_2 = 55; public static final int FIRST_DEMO_VERSION = 1; public static final int NULL_2 = 0; public static final int NULL_1 = 0; public static final int DEMO = 0x20049678; public static final int SECOND_DEMO_VERSION = 2; } // End of demo.java remotetea-1.0.7/src/tests/org/acplt/oncrpc/jrpcgen/demo.x0000644005374700003410000000373610627060210024477 0ustar piccainstrumentation/* * demo.x -- demonstrates and tests some jrpcgen features. It doesn't * boil down to a useful example, it just checks a few things * within code generation. * * To compile, use * java -jar jrpcgen.jar -p tests.org.acplt.oncrpc.jrpcgen -nobackup demo.x */ typedef string STRING<>; typedef STRING STRINGVECTOR<>; /* Check that dependencies are followed when dumping constants */ const C_B = C_A; const C_A = C_C; const C_C = 42; /* Check enumerations */ enum ENUMBAZ { E_BAZ = C_B }; enum ENUMFOO { FOO, BAR, BAZ_1 = C_B, BAZ_2, BAZ_3 = E_BAZ }; const FIXEDBUFFERLENGTH = 64; struct LINKEDLIST { int foo; struct LINKEDLIST *next; }; struct TREE { string key<>; string value<>; struct TREE *left; struct TREE *right; }; union UNION switch ( bool okay ) { case TRUE: LINKEDLIST *list; default: void; }; union ANSWER switch ( int value ) { case 40: case 41: int wrong; case 42: int the_answer; default: int check_hash; }; struct SILLYSTRUCT { char fixedbuffer[512]; char buffer<128>; opaque fixedbytes[FIXEDBUFFERLENGTH]; opaque bytes<32>; unsigned int ui1; unsigned ui2; string nonsense<>; }; struct SOMERESULT { int error; string typedesc<>; opaque data<>; }; program DEMO { version FIRST_DEMO_VERSION { void NULL(void) = 0; string echo(string) = 1; string concat(STRINGVECTOR) = 2; bool checkfoo(ENUMFOO) = 3; ENUMFOO foo(void) = 4; LINKEDLIST ll(LINKEDLIST) = 5; SOMERESULT readSomeResult(void) = 42; } = 1; version SECOND_DEMO_VERSION { void NULL(void) = 0; string cat(string, string) = 42; string cat3(string one, string two, string three) = 43; string checkfoo(ENUMFOO foo) = 3; LINKEDLIST llcat(LINKEDLIST l1, LINKEDLIST l2) = 55; void test(string a, ENUMFOO b, ENUMFOO c, int d) = 100; } = 2; } = 0x20049678; /* End of file demo.x */ remotetea-1.0.7/src/tests/org/acplt/oncrpc/jrpcgen/demo2.java0000644005374700003410000000071710627063200025231 0ustar piccainstrumentation/* * Automatically generated by jrpcgen 1.0.7 on 29.05.07 21:34 * jrpcgen is part of the "Remote Tea" ONC/RPC package for Java * See http://remotetea.sourceforge.net for details */ package tests.org.acplt.oncrpc.jrpcgen; /** * A collection of constants used by the "demo2" ONC/RPC program. */ public interface demo2 { public static final int C_C = 42; public static final int C_A = C_C; public static final int C_B = C_A; } // End of demo2.java remotetea-1.0.7/src/tests/org/acplt/oncrpc/jrpcgen/demo2.x0000644005374700003410000000140010335200504024541 0ustar piccainstrumentation/* * demo2.x -- demonstrates and tests some jrpcgen features. It doesn't * boil down to a useful example, it just checks a few things * within code generation. * * This test tests code generation with a missing program * section, which is now accepted. * * To compile, use * java -jar jrpcgen.jar -p tests.org.acplt.oncrpc.jrpcgen -nobackup demo-2.x */ /* Check that dependencies are followed when dumping constants */ const C_B = C_A; const C_A = C_C; const C_C = 42; /* Check enumerations */ enum ENUMBAZ2 { E_BAZ = C_B }; enum ENUMFOO2 { FOO, BAR, BAZ_1 = C_B, BAZ_2, BAZ_3 = E_BAZ }; struct TREE2 { string key<>; string value<>; struct TREE2 *left; struct TREE2 *right; }; /* End of file demo2.x */ remotetea-1.0.7/src/tests/org/acplt/oncrpc/jrpcgen/demoClient.java0000644005374700003410000003307210627063200026306 0ustar piccainstrumentation/* * Automatically generated by jrpcgen 1.0.7 on 29.05.07 21:34 * jrpcgen is part of the "Remote Tea" ONC/RPC package for Java * See http://remotetea.sourceforge.net for details */ package tests.org.acplt.oncrpc.jrpcgen; import org.acplt.oncrpc.*; import java.io.IOException; import java.net.InetAddress; /** * The class demoClient implements the client stub proxy * for the DEMO remote program. It provides method stubs * which, when called, in turn call the appropriate remote method (procedure). */ public class demoClient extends OncRpcClientStub { /** * Constructs a demoClient client stub proxy object * from which the DEMO remote program can be accessed. * @param host Internet address of host where to contact the remote program. * @param protocol {@link org.acplt.oncrpc.OncRpcProtocols Protocol} to be * used for ONC/RPC calls. * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public demoClient(InetAddress host, int protocol) throws OncRpcException, IOException { super(host, demo.DEMO, 2, 0, protocol); } /** * Constructs a demoClient client stub proxy object * from which the DEMO remote program can be accessed. * @param host Internet address of host where to contact the remote program. * @param port Port number at host where the remote program can be reached. * @param protocol {@link org.acplt.oncrpc.OncRpcProtocols Protocol} to be * used for ONC/RPC calls. * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public demoClient(InetAddress host, int port, int protocol) throws OncRpcException, IOException { super(host, demo.DEMO, 2, port, protocol); } /** * Constructs a demoClient client stub proxy object * from which the DEMO remote program can be accessed. * @param client ONC/RPC client connection object implementing a particular * protocol. * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public demoClient(OncRpcClient client) throws OncRpcException, IOException { super(client); } /** * Constructs a demoClient client stub proxy object * from which the DEMO remote program can be accessed. * @param host Internet address of host where to contact the remote program. * @param program Remote program number. * @param version Remote program version number. * @param protocol {@link org.acplt.oncrpc.OncRpcProtocols Protocol} to be * used for ONC/RPC calls. * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public demoClient(InetAddress host, int program, int version, int protocol) throws OncRpcException, IOException { super(host, program, version, 0, protocol); } /** * Constructs a demoClient client stub proxy object * from which the DEMO remote program can be accessed. * @param host Internet address of host where to contact the remote program. * @param program Remote program number. * @param version Remote program version number. * @param port Port number at host where the remote program can be reached. * @param protocol {@link org.acplt.oncrpc.OncRpcProtocols Protocol} to be * used for ONC/RPC calls. * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public demoClient(InetAddress host, int program, int version, int port, int protocol) throws OncRpcException, IOException { super(host, program, version, port, protocol); } /** * Call remote procedure NULL_1. * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void NULL_1() throws OncRpcException, IOException { XdrVoid args$ = XdrVoid.XDR_VOID; XdrVoid result$ = XdrVoid.XDR_VOID; client.call(demo.NULL_1, demo.FIRST_DEMO_VERSION, args$, result$); } /** * Call remote procedure echo_1. * @param arg1 parameter (of type String) to the remote procedure call. * @return Result from remote procedure call (of type String). * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public String echo_1(String arg1) throws OncRpcException, IOException { XdrString args$ = new XdrString(arg1); XdrString result$ = new XdrString(); client.call(demo.echo_1, demo.FIRST_DEMO_VERSION, args$, result$); return result$.stringValue(); } /** * Call remote procedure concat_1. * @param arg1 parameter (of type STRINGVECTOR) to the remote procedure call. * @return Result from remote procedure call (of type String). * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public String concat_1(STRINGVECTOR arg1) throws OncRpcException, IOException { XdrString result$ = new XdrString(); client.call(demo.concat_1, demo.FIRST_DEMO_VERSION, arg1, result$); return result$.stringValue(); } /** * Call remote procedure checkfoo_1. * @param arg1 parameter (of type ENUMFOO) to the remote procedure call. * @return Result from remote procedure call (of type boolean). * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public boolean checkfoo_1(int arg1) throws OncRpcException, IOException { XdrInt args$ = new XdrInt(arg1); XdrBoolean result$ = new XdrBoolean(); client.call(demo.checkfoo_1, demo.FIRST_DEMO_VERSION, args$, result$); return result$.booleanValue(); } /** * Call remote procedure foo_1. * @return Result from remote procedure call (of type ENUMFOO). * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public int foo_1() throws OncRpcException, IOException { XdrVoid args$ = XdrVoid.XDR_VOID; XdrInt result$ = new XdrInt(); client.call(demo.foo_1, demo.FIRST_DEMO_VERSION, args$, result$); return result$.intValue(); } /** * Call remote procedure ll_1. * @param arg1 parameter (of type LINKEDLIST) to the remote procedure call. * @return Result from remote procedure call (of type LINKEDLIST). * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public LINKEDLIST ll_1(LINKEDLIST arg1) throws OncRpcException, IOException { LINKEDLIST result$ = new LINKEDLIST(); client.call(demo.ll_1, demo.FIRST_DEMO_VERSION, arg1, result$); return result$; } /** * Call remote procedure readSomeResult_1. * @return Result from remote procedure call (of type SOMERESULT). * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public SOMERESULT readSomeResult_1() throws OncRpcException, IOException { XdrVoid args$ = XdrVoid.XDR_VOID; SOMERESULT result$ = new SOMERESULT(); client.call(demo.readSomeResult_1, demo.FIRST_DEMO_VERSION, args$, result$); return result$; } /** * Call remote procedure NULL_2. * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void NULL_2() throws OncRpcException, IOException { XdrVoid args$ = XdrVoid.XDR_VOID; XdrVoid result$ = XdrVoid.XDR_VOID; client.call(demo.NULL_2, demo.SECOND_DEMO_VERSION, args$, result$); } /** * Call remote procedure cat_2. * @param arg1 parameter (of type String) to the remote procedure call. * @param arg2 parameter (of type String) to the remote procedure call. * @return Result from remote procedure call (of type String). * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public String cat_2(String arg1, String arg2) throws OncRpcException, IOException { class XdrAble$ implements XdrAble { public String arg1; public String arg2; public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException { xdr.xdrEncodeString(arg1); xdr.xdrEncodeString(arg2); } public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException { } }; XdrAble$ args$ = new XdrAble$(); args$.arg1 = arg1; args$.arg2 = arg2; XdrString result$ = new XdrString(); client.call(demo.cat_2, demo.SECOND_DEMO_VERSION, args$, result$); return result$.stringValue(); } /** * Call remote procedure cat3_2. * @param one parameter (of type String) to the remote procedure call. * @param two parameter (of type String) to the remote procedure call. * @param three parameter (of type String) to the remote procedure call. * @return Result from remote procedure call (of type String). * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public String cat3_2(String one, String two, String three) throws OncRpcException, IOException { class XdrAble$ implements XdrAble { public String one; public String two; public String three; public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException { xdr.xdrEncodeString(one); xdr.xdrEncodeString(two); xdr.xdrEncodeString(three); } public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException { } }; XdrAble$ args$ = new XdrAble$(); args$.one = one; args$.two = two; args$.three = three; XdrString result$ = new XdrString(); client.call(demo.cat3_2, demo.SECOND_DEMO_VERSION, args$, result$); return result$.stringValue(); } /** * Call remote procedure checkfoo_2. * @param foo parameter (of type ENUMFOO) to the remote procedure call. * @return Result from remote procedure call (of type String). * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public String checkfoo_2(int foo) throws OncRpcException, IOException { XdrInt args$ = new XdrInt(foo); XdrString result$ = new XdrString(); client.call(demo.checkfoo_2, demo.SECOND_DEMO_VERSION, args$, result$); return result$.stringValue(); } /** * Call remote procedure llcat_2. * @param l1 parameter (of type LINKEDLIST) to the remote procedure call. * @param l2 parameter (of type LINKEDLIST) to the remote procedure call. * @return Result from remote procedure call (of type LINKEDLIST). * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public LINKEDLIST llcat_2(LINKEDLIST l1, LINKEDLIST l2) throws OncRpcException, IOException { class XdrAble$ implements XdrAble { public LINKEDLIST l1; public LINKEDLIST l2; public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException { l1.xdrEncode(xdr); l2.xdrEncode(xdr); } public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException { } }; XdrAble$ args$ = new XdrAble$(); args$.l1 = l1; args$.l2 = l2; LINKEDLIST result$ = new LINKEDLIST(); client.call(demo.llcat_2, demo.SECOND_DEMO_VERSION, args$, result$); return result$; } /** * Call remote procedure test_2. * @param a parameter (of type String) to the remote procedure call. * @param b parameter (of type ENUMFOO) to the remote procedure call. * @param c parameter (of type ENUMFOO) to the remote procedure call. * @param d parameter (of type int) to the remote procedure call. * @throws OncRpcException if an ONC/RPC error occurs. * @throws IOException if an I/O error occurs. */ public void test_2(String a, int b, int c, int d) throws OncRpcException, IOException { class XdrAble$ implements XdrAble { public String a; public int b; public int c; public int d; public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException { xdr.xdrEncodeString(a); xdr.xdrEncodeInt(b); xdr.xdrEncodeInt(c); xdr.xdrEncodeInt(d); } public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException { } }; XdrAble$ args$ = new XdrAble$(); args$.a = a; args$.b = b; args$.c = c; args$.d = d; XdrVoid result$ = XdrVoid.XDR_VOID; client.call(demo.test_2, demo.SECOND_DEMO_VERSION, args$, result$); } } // End of demoClient.java remotetea-1.0.7/src/tests/org/acplt/oncrpc/jrpcgen/demoClientExample.java0000644005374700003410000001426107716624540027640 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/tests/org/acplt/oncrpc/jrpcgen/demoClientExample.java,v 1.2 2003/08/14 08:17:04 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package tests.org.acplt.oncrpc.jrpcgen; import org.acplt.oncrpc.*; import java.net.InetAddress; /** * */ public class demoClientExample { /** * */ public static void main(String [] args) { demoClient client = null; try { client = new demoClient(InetAddress.getByName("127.0.0.1"), OncRpcProtocols.ONCRPC_TCP); } catch ( Exception e ) { System.out.println("demoClientExample: oops when creating RPC client:"); e.printStackTrace(System.out); } client.getClient().setTimeout(300*1000); System.out.print("About to ping: "); try { client.NULL_1(); System.out.println("ok"); } catch ( Exception e ) { e.printStackTrace(System.out); return; } System.out.print("About to echo: "); try { String text = "Hello, Remote Tea!"; String echo = client.echo_1(text); if ( !echo.equals(text) ) { System.out.println(" oops. Got \"" + echo + "\" instead of \"" + text + "\""); } System.out.println("ok. Echo: \"" + echo + "\""); } catch ( Exception e ) { e.printStackTrace(System.out); return; } System.out.print("About to concatenating: "); try { STRINGVECTOR strings = new STRINGVECTOR(); strings.value = new STRING[3]; strings.value[0] = new STRING("Hello, "); strings.value[1] = new STRING("Remote "); strings.value[2] = new STRING("Tea!"); String echo = client.concat_1(strings); System.out.println("ok. Echo: \"" + echo + "\""); } catch ( Exception e ) { e.printStackTrace(System.out); return; } System.out.print("About to concatenating exactly three strings: "); try { String echo = client.cat3_2("(arg1:Hello )", "(arg2:Remote )", "(arg3:Tea!)"); System.out.println("ok. Echo: \"" + echo + "\""); } catch ( Exception e ) { e.printStackTrace(System.out); return; } System.out.print("About to check for foo: "); try { if ( client.checkfoo_1(ENUMFOO.BAR) ) { System.out.println("oops: but a bar is not a foo!"); return; } System.out.print("not bar: "); if ( !client.checkfoo_1(ENUMFOO.FOO) ) { System.out.println("oops: a foo should be a foo!"); return; } System.out.println("but a foo. ok."); } catch ( Exception e ) { e.printStackTrace(System.out); return; } System.out.print("About to get a foo: "); try { if ( client.foo_1() != ENUMFOO.FOO ) { System.out.println("oops: got a bar instead of a foo!"); return; } System.out.println("ok."); } catch ( Exception e ) { e.printStackTrace(System.out); return; } System.out.print("About to get a numbered foo string: "); try { String echo = client.checkfoo_2(42); System.out.println("ok. Echo: \"" + echo + "\""); } catch ( Exception e ) { e.printStackTrace(System.out); return; } System.out.print("Linked List test: "); try { LINKEDLIST node1 = new LINKEDLIST(); node1.foo = 0; LINKEDLIST node2 = new LINKEDLIST(); node2.foo = 8; node1.next = node2; LINKEDLIST node3 = new LINKEDLIST(); node3.foo = 15; node2.next = node3; LINKEDLIST list = client.ll_1(node1); System.out.print("ok. Echo: "); while ( list != null ) { System.out.print(list.foo + ", "); list = list.next; } System.out.println(); } catch ( Exception e ) { e.printStackTrace(System.out); return; } System.out.print("Linking Linked Lists test: "); try { LINKEDLIST node1 = new LINKEDLIST(); node1.foo = 0; LINKEDLIST node2 = new LINKEDLIST(); node2.foo = 8; LINKEDLIST node3 = new LINKEDLIST(); node3.foo = 15; node2.next = node3; LINKEDLIST list = client.llcat_2(node2, node1); System.out.print("ok. Echo: "); while ( list != null ) { System.out.print(list.foo + ", "); list = list.next; } System.out.println(); } catch ( Exception e ) { e.printStackTrace(System.out); return; } try { client.close(); } catch ( Exception e ) { System.out.println("demoClientExample: oops when closing client:"); e.printStackTrace(System.out); } client = null; System.out.println("All tests passed."); } } // End of demoClientExample.java remotetea-1.0.7/src/tests/org/acplt/oncrpc/jrpcgen/demoServer.java0000644005374700003410000000664510627060210026342 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/tests/org/acplt/oncrpc/jrpcgen/demoServer.java,v 1.3 2007/05/29 19:19:03 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package tests.org.acplt.oncrpc.jrpcgen; import org.acplt.oncrpc.*; import java.io.IOException; /** * */ public class demoServer extends demoServerStub { /** * */ public demoServer() throws OncRpcException, IOException { super(); } /** * */ public void NULL_1() { // definetely nothing to do here... } /** * */ public void NULL_2() { // definetely nothing to do here... } /** * */ public String echo_1(String params) { return params; } /** * */ public boolean checkfoo_1(int params) { return params == ENUMFOO.FOO; } /** * */ public int foo_1() { return ENUMFOO.FOO; } /** * */ public String concat_1(STRINGVECTOR params) { StringBuffer result = new StringBuffer(); int size = params.value.length; for ( int idx = 0; idx < size; ++idx ) { result.append(params.value[idx].value); } return result.toString(); } /** * */ public LINKEDLIST ll_1(LINKEDLIST params) { LINKEDLIST newNode = new LINKEDLIST(); newNode.foo = 42; newNode.next = params; return newNode; } /** * */ public SOMERESULT readSomeResult_1() { SOMERESULT res = new SOMERESULT(); return res; } /** * */ public String cat_2(String arg1, String arg2) { return arg1 + arg2; } /** * */ public String cat3_2(String one, String two, String three) { return one + two + three; } /** * */ public String checkfoo_2(int foo) { return "You are foo" + foo + "."; } /** * */ public LINKEDLIST llcat_2(LINKEDLIST l1, LINKEDLIST l2) { l2.next = l1; return l2; } /** * */ public void test_2(String a, int b, int c, int d) { } /** * */ public static void main(String [] args) { System.out.println("Starting demoServer..."); try { demoServer server = new demoServer(); server.run(); } catch ( Exception e ) { System.out.println("demoServer oops:"); e.printStackTrace(System.out); } System.out.println("demoServer stopped."); } } // End of demoServer.java remotetea-1.0.7/src/tests/org/acplt/oncrpc/jrpcgen/demoServerStub.java0000644005374700003410000001761110627063200027175 0ustar piccainstrumentation/* * Automatically generated by jrpcgen 1.0.7 on 29.05.07 21:34 * jrpcgen is part of the "Remote Tea" ONC/RPC package for Java * See http://remotetea.sourceforge.net for details */ package tests.org.acplt.oncrpc.jrpcgen; import org.acplt.oncrpc.*; import java.io.IOException; import java.net.InetAddress; import org.acplt.oncrpc.server.*; /** */ public abstract class demoServerStub extends OncRpcServerStub implements OncRpcDispatchable { public demoServerStub() throws OncRpcException, IOException { this(0); } public demoServerStub(int port) throws OncRpcException, IOException { this(null, port); } public demoServerStub(InetAddress bindAddr, int port) throws OncRpcException, IOException { info = new OncRpcServerTransportRegistrationInfo [] { new OncRpcServerTransportRegistrationInfo(demo.DEMO, 1), new OncRpcServerTransportRegistrationInfo(demo.DEMO, 2), }; transports = new OncRpcServerTransport [] { new OncRpcUdpServerTransport(this, bindAddr, port, info, 32768), new OncRpcTcpServerTransport(this, bindAddr, port, info, 32768) }; } public void dispatchOncRpcCall(OncRpcCallInformation call, int program, int version, int procedure) throws OncRpcException, IOException { if ( version == 1 ) { switch ( procedure ) { case 0: { call.retrieveCall(XdrVoid.XDR_VOID); NULL_1(); call.reply(XdrVoid.XDR_VOID); break; } case 1: { XdrString args$ = new XdrString(); call.retrieveCall(args$); XdrString result$ = new XdrString(echo_1(args$.stringValue())); call.reply(result$); break; } case 2: { STRINGVECTOR args$ = new STRINGVECTOR(); call.retrieveCall(args$); XdrString result$ = new XdrString(concat_1(args$)); call.reply(result$); break; } case 3: { XdrInt args$ = new XdrInt(); call.retrieveCall(args$); XdrBoolean result$ = new XdrBoolean(checkfoo_1(args$.intValue())); call.reply(result$); break; } case 4: { call.retrieveCall(XdrVoid.XDR_VOID); XdrInt result$ = new XdrInt(foo_1()); call.reply(result$); break; } case 5: { LINKEDLIST args$ = new LINKEDLIST(); call.retrieveCall(args$); LINKEDLIST result$ = ll_1(args$); call.reply(result$); break; } case 42: { call.retrieveCall(XdrVoid.XDR_VOID); SOMERESULT result$ = readSomeResult_1(); call.reply(result$); break; } default: call.failProcedureUnavailable(); } } else if ( version == 2 ) { switch ( procedure ) { case 0: { call.retrieveCall(XdrVoid.XDR_VOID); NULL_2(); call.reply(XdrVoid.XDR_VOID); break; } case 42: { class XdrAble$ implements XdrAble { public String arg1; public String arg2; public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException { } public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException { arg1 = xdr.xdrDecodeString(); arg2 = xdr.xdrDecodeString(); } }; XdrAble$ args$ = new XdrAble$(); call.retrieveCall(args$); XdrString result$ = new XdrString(cat_2(args$.arg1, args$.arg2)); call.reply(result$); break; } case 43: { class XdrAble$ implements XdrAble { public String one; public String two; public String three; public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException { } public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException { one = xdr.xdrDecodeString(); two = xdr.xdrDecodeString(); three = xdr.xdrDecodeString(); } }; XdrAble$ args$ = new XdrAble$(); call.retrieveCall(args$); XdrString result$ = new XdrString(cat3_2(args$.one, args$.two, args$.three)); call.reply(result$); break; } case 3: { XdrInt args$ = new XdrInt(); call.retrieveCall(args$); XdrString result$ = new XdrString(checkfoo_2(args$.intValue())); call.reply(result$); break; } case 55: { class XdrAble$ implements XdrAble { public LINKEDLIST l1; public LINKEDLIST l2; public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException { } public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException { l1 = new LINKEDLIST(xdr); l2 = new LINKEDLIST(xdr); } }; XdrAble$ args$ = new XdrAble$(); call.retrieveCall(args$); LINKEDLIST result$ = llcat_2(args$.l1, args$.l2); call.reply(result$); break; } case 100: { class XdrAble$ implements XdrAble { public String a; public int b; public int c; public int d; public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException { } public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException { a = xdr.xdrDecodeString(); b = xdr.xdrDecodeInt(); c = xdr.xdrDecodeInt(); d = xdr.xdrDecodeInt(); } }; XdrAble$ args$ = new XdrAble$(); call.retrieveCall(args$); test_2(args$.a, args$.b, args$.c, args$.d); call.reply(XdrVoid.XDR_VOID); break; } default: call.failProcedureUnavailable(); } } else { call.failProgramUnavailable(); } } public abstract void NULL_1(); public abstract String echo_1(String arg1); public abstract String concat_1(STRINGVECTOR arg1); public abstract boolean checkfoo_1(int arg1); public abstract int foo_1(); public abstract LINKEDLIST ll_1(LINKEDLIST arg1); public abstract SOMERESULT readSomeResult_1(); public abstract void NULL_2(); public abstract String cat_2(String arg1, String arg2); public abstract String cat3_2(String one, String two, String three); public abstract String checkfoo_2(int foo); public abstract LINKEDLIST llcat_2(LINKEDLIST l1, LINKEDLIST l2); public abstract void test_2(String a, int b, int c, int d); } // End of demoServerStub.java remotetea-1.0.7/src/tests/org/acplt/oncrpc/Base64Test.java0000644005374700003410000000540307716406412024467 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/tests/org/acplt/oncrpc/Base64Test.java,v 1.1.1.1 2003/08/13 12:03:53 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package tests.org.acplt.oncrpc; import org.acplt.oncrpc.web.Base64; public class Base64Test { public boolean bytecmp(byte [] b1, byte [] b2, int len) { for ( int i = 0; i < len; ++i ) { if ( b1[i] != b2[i] ) { return false; } } return true; } public void check(String test, byte [] source, int lenSource, int lenEncoded) { byte [] encoded = new byte[((source.length + 2) / 3 * 4)]; byte [] decoded = new byte[source.length]; System.out.print(test + ": "); int len = Base64.encode(source, 0, lenSource, encoded, 0); if ( len != lenEncoded ) { System.out.println("**failed**. Expected encoded length = " + lenEncoded + ", got length = " + len); return; } len = Base64.decode(encoded, 0, len, decoded, 0); if ( len != lenSource ) { System.out.println("**failed**. Decoded length mismatch, expected " + lenSource + ", got " + len); return; } System.out.println("passed."); } public Base64Test() { byte [] source = "The Foxboro jumps over the lazy I/A".getBytes(); check("test-1", source, 1, 4); check("test-2", source, 2, 4); check("test-3", source, 3, 4); check("test-4", source, 4, 8); check("test-5", source, source.length, ((source.length + 2) / 3) * 4); } public static void main(String[] args) { System.out.println("Base64Test"); try { new Base64Test(); } catch ( Exception e ) { e.printStackTrace(System.out); } } } // End of Base64Test.javaremotetea-1.0.7/src/tests/org/acplt/oncrpc/BroadcastClientTest.java0000644005374700003410000000723107716624452026513 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/tests/org/acplt/oncrpc/BroadcastClientTest.java,v 1.2 2003/08/14 08:16:10 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package tests.org.acplt.oncrpc; import java.io.IOException; import java.net.*; import java.util.Vector; import org.acplt.oncrpc.*; public class BroadcastClientTest implements OncRpcBroadcastListener { // // List of addresses of portmappers that replied to our call... // Vector portmappers = new Vector(); // // Remember addresses of replies for later processing. Please note // that you should not do any lengthy things (like DNS name lookups) // in this event handler, as you will otherwise miss some incomming // replies because the OS will drop them. // public void replyReceived(OncRpcBroadcastEvent evt) { portmappers.add(evt.getReplyAddress()); System.out.print("."); } public BroadcastClientTest() throws OncRpcException, IOException { // // Create a portmap client object, which can then be used to contact // the local ONC/RPC ServerTest test server. // OncRpcUdpClient client = new OncRpcUdpClient(InetAddress.getByName("255.255.255.255"), 100000, 2, 111); // // Ping all portmappers in this subnet... // System.out.print("pinging portmappers in subnet: "); client.setTimeout(5*1000); try { client.broadcastCall(0, XdrVoid.XDR_VOID, XdrVoid.XDR_VOID, this); } catch ( OncRpcException e ) { System.out.println("method call failed unexpectedly:"); e.printStackTrace(System.out); System.exit(1); } System.out.println("done."); // // Print addresses of all portmappers found... // for ( int idx = 0; idx < portmappers.size(); ++idx ) { System.out.println("Found: " + ((InetAddress) portmappers.elementAt(idx)).getHostName() + " (" + ((InetAddress) portmappers.elementAt(idx)).getHostAddress() + ")"); } // // Release resources bound by portmap client object as soon as possible // so might help the garbage wo/man. Yeah, this is now a political // correct comment. // client.close(); client = null; } public static void main(String[] args) { System.out.println("BroadcastClientTest"); try { new BroadcastClientTest(); } catch ( Exception e ) { e.printStackTrace(System.out); } } } // End of BroadcastClientTest.javaremotetea-1.0.7/src/tests/org/acplt/oncrpc/EchoClientTest.html0000644005374700003410000000274607716654166025525 0ustar piccainstrumentation Project EchoClientTest

    EchoClientTest.java


    This example demonstrates how to write a simple ONC/RPC client. To test the client, you'll need to run ServerTest.java at the same time as this is corresponding server. This client just sends a few strings to the server, which the server will simply bounce.


    This test is part of the ACPLT/KS ACPLTea Java Library package.

    (c) 1999 Lehrstuhl für Prozeßleittechnik, Aachen University of Technology, Germany.

    This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License along with this program (see the file COPYING.LIB for more details); if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. remotetea-1.0.7/src/tests/org/acplt/oncrpc/EchoClientTest.java0000644005374700003410000001175507716406412025467 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/tests/org/acplt/oncrpc/EchoClientTest.java,v 1.1.1.1 2003/08/13 12:03:53 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package tests.org.acplt.oncrpc; import java.io.IOException; import java.net.*; import org.acplt.oncrpc.*; public class EchoClientTest { public EchoClientTest() throws OncRpcException, IOException { // // Create a portmap client object, which can then be used to contact // the local ONC/RPC ServerTest test server. // OncRpcClient client = new OncRpcTcpClient(InetAddress.getByName("localhost"), 0x49679, 1, 0); // // Ping the test server... // System.out.print("pinging test server: "); try { client.call(0, XdrVoid.XDR_VOID, XdrVoid.XDR_VOID); } catch ( OncRpcException e ) { System.out.println("method call failed unexpectedly:"); e.printStackTrace(System.out); System.exit(1); } System.out.println("test server is alive."); // // Now check the echo RPC call... // String [] messages = { "Open Source", "is not yet", "another buzzword." }; checkEcho(client, messages); // // Now test AUTH_UNIX authentication. First start with an // invalid credential... // OncRpcClientAuth auth = new OncRpcClientAuthUnix( "marvin", 0, 0, new int[0]); client.setAuth(auth); System.out.print("checking AUTH_UNIX with invalid credential: "); try { client.call(0, XdrVoid.XDR_VOID, XdrVoid.XDR_VOID); } catch ( OncRpcAuthenticationException ae ) { if ( ae.getAuthStatus() != OncRpcAuthStatus.ONCRPC_AUTH_BADCRED ) { System.out.println("received wrong authentication exception with status of " + ae.getAuthStatus()); ae.printStackTrace(System.out); System.exit(1); } } catch ( OncRpcException e ) { System.out.println("method call failed unexpectedly:"); e.printStackTrace(System.out); System.exit(1); } System.out.println("passed."); auth = new OncRpcClientAuthUnix( "marvin", 42, 815, new int[0]); client.setAuth(auth); messages = new String[] { "AUTH_UNIX", "is like", "*NO* authentication", "--", "it", "uses", "*NO CRYPTOGRAPHY*", "for securing", "ONC/RPC messages" }; checkEcho(client, messages); client.setAuth(null); // // Release resources bound by ONC/RPC client object as soon as possible // so might help the garbage wo/man. Yeah, this is now a political // correct comment. // client.close(); client = null; } public void checkEcho(OncRpcClient client, String [] messages) { for ( int idx = 0; idx < messages.length; ++idx ) { XdrString params = new XdrString(messages[idx]); XdrString result = new XdrString(); System.out.print("checking echo: "); try { client.call(1, params, result); } catch ( OncRpcException e ) { System.out.println("method call failed unexpectedly:"); e.printStackTrace(System.out); System.exit(1); } if ( !params.stringValue().equals(result.stringValue()) ) { System.out.println("answer does not match call:"); System.out.println(" expected: \"" + params.stringValue() + "\""); System.out.println(" but got: \"" + result.stringValue() + "\""); System.exit(1); } System.out.println(result.stringValue()); } } public static void main(String[] args) { System.out.println("EchoClientTest"); try { new EchoClientTest(); } catch ( Exception e ) { e.printStackTrace(System.out); } } } // End of EchoClientTest.javaremotetea-1.0.7/src/tests/org/acplt/oncrpc/EchoHttpClientTest.java0000644005374700003410000000756507716637446026350 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/tests/org/acplt/oncrpc/EchoHttpClientTest.java,v 1.2 2003/08/14 09:49:58 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package tests.org.acplt.oncrpc; import java.io.IOException; import org.acplt.oncrpc.*; public class EchoHttpClientTest { public EchoHttpClientTest() throws OncRpcException, IOException { // // Create a portmap client object, which can then be used to contact // the local ONC/RPC ServerTest test server. // OncRpcClient client = new OncRpcHttpClient("localhost", "/teatunnel", "localhost", OncRpcPortmapClient.PMAP_PROGRAM, OncRpcPortmapClient.PMAP_VERSION, OncRpcPortmapClient.PMAP_PORT, OncRpcProtocols.ONCRPC_UDP); client.call(0, XdrVoid.XDR_VOID, XdrVoid.XDR_VOID); OncRpcDumpResult result = new OncRpcDumpResult(); client.call(OncRpcPortmapServices.PMAP_DUMP, XdrVoid.XDR_VOID, result); // new OncRpcHttpClient("localhost", // "/teatunnel", // "localhost", // 0x49679, 1, 0); // // Now check the echo RPC call... // String [] messages = { "Open Source", "is not yet", "another buzzword." }; checkEcho(client, messages); // // Release resources bound by ONC/RPC client object as soon as possible // so might help the garbage wo/man. Yeah, this is now a political // correct comment. // client.close(); client = null; } public void checkEcho(OncRpcClient client, String [] messages) { for ( int idx = 0; idx < messages.length; ++idx ) { XdrString params = new XdrString(messages[idx]); XdrString result = new XdrString(); System.out.print("checking echo: "); try { client.call(1, params, result); } catch ( OncRpcException e ) { System.out.println("method call failed unexpectedly:"); e.printStackTrace(System.out); System.exit(1); } if ( !params.stringValue().equals(result.stringValue()) ) { System.out.println("answer does not match call:"); System.out.println(" expected: \"" + params.stringValue() + "\""); System.out.println(" but got: \"" + result.stringValue() + "\""); System.exit(1); } System.out.println(result.stringValue()); } } public static void main(String[] args) { System.out.println("EchoHttpClientTest"); try { new EchoHttpClientTest(); } catch ( Exception e ) { e.printStackTrace(System.out); } } } // End of EchoHttpClientTest.javaremotetea-1.0.7/src/tests/org/acplt/oncrpc/EmbeddedPortmapTest.java0000644005374700003410000001061707716637366026520 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/tests/org/acplt/oncrpc/EmbeddedPortmapTest.java,v 1.2 2003/08/14 09:49:10 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package tests.org.acplt.oncrpc; import java.io.IOException; import java.net.*; import org.acplt.oncrpc.*; import org.acplt.oncrpc.apps.jportmap.*; public class EmbeddedPortmapTest { public OncRpcEmbeddedPortmap epm; public EmbeddedPortmapTest() throws IOException, OncRpcException, UnknownHostException { // // Diagnostic: Is a portmapper already running? // System.out.print("Checking for portmap service: "); boolean externalPortmap = OncRpcEmbeddedPortmap.isPortmapRunning(); if ( externalPortmap ) { System.out.println("A portmap service is already running."); } else { System.out.println("No portmap service available."); } // // Create embedded portmap service and check whether is has sprung // into action. // System.out.print("Creating embedded portmap instance: "); try { epm = new OncRpcEmbeddedPortmap(); } catch ( IOException e ) { System.out.println("ERROR: failed:"); e.printStackTrace(System.out); } catch ( OncRpcException e ) { System.out.println("ERROR: failed:"); e.printStackTrace(System.out); } if ( !epm.embeddedPortmapInUse() ) { System.out.print("embedded service not used: "); } else { System.out.print("embedded service started: "); } if ( epm.embeddedPortmapInUse() == externalPortmap ) { System.out.println("ERROR: no service available or both."); return; } System.out.println("Passed."); // // Now register dummy ONC/RPC program. Note that the embedded // portmap service must not automatically spin down when deregistering // the non-existing dummy program. // OncRpcPortmapClient pmap = new OncRpcPortmapClient(InetAddress.getByName("127.0.0.1")); System.out.print("Deregistering non-existing program: "); pmap.unsetPort(12345678, 42); System.out.println("Passed."); System.out.print("Registering dummy program: "); pmap.setPort(12345678, 42, OncRpcProtocols.ONCRPC_TCP, 42); System.out.println("Passed."); System.out.println("Press any key to continue..."); byte [] b = new byte[1]; System.in.read(b); System.out.print("Deregistering dummy program: "); pmap.unsetPort(12345678, 42); System.out.println("Passed."); System.out.println("Press any key to continue..."); System.in.read(b); // // Check that an embedded portmap service spins down properly if it // was started within this test. // if ( OncRpcEmbeddedPortmap.isPortmapRunning() && !externalPortmap ) { System.out.println("ERROR: embedded portmap service still running."); } } public static void main(String[] args) { System.out.println("EmbeddedPortmapTest"); try { new EmbeddedPortmapTest(); } catch ( Exception e ) { e.printStackTrace(System.out); } System.out.println("Test finished."); System.out.println("Press any key to continue..."); byte [] b = new byte[1]; try { System.in.read(b); } catch ( IOException e ) { } } } // End of EmbeddedPortmapTest.javaremotetea-1.0.7/src/tests/org/acplt/oncrpc/HttpTunnelPortmapTest.java0000644005374700003410000002460707716637446027137 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/tests/org/acplt/oncrpc/HttpTunnelPortmapTest.java,v 1.2 2003/08/14 09:49:58 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package tests.org.acplt.oncrpc; import java.io.IOException; import org.acplt.oncrpc.*; public class HttpTunnelPortmapTest { public HttpTunnelPortmapTest() throws OncRpcException, IOException { // // Create a portmap client object, which can then be used to contact // a local or remote ONC/RPC portmap process. In this test we contact // the local portmapper. // OncRpcClient portmap = new OncRpcHttpClient( "localhost", // name of host where the tunnel gateway resides "/teatunnel", // path to gateway "localhost", // name of host where ONC/RPC server is located OncRpcPortmapClient.PMAP_PROGRAM, OncRpcPortmapClient.PMAP_VERSION, OncRpcPortmapClient.PMAP_PORT, OncRpcProtocols.ONCRPC_TCP // transport protocol to use by // gateway to contact ONC/RPC server. ); // // Ping the portmapper... // System.out.print("pinging portmapper: "); try { portmap.call(0, XdrVoid.XDR_VOID, XdrVoid.XDR_VOID); } catch ( OncRpcException e ) { System.out.println("method call failed unexpectedly:"); e.printStackTrace(System.out); System.exit(1); } System.out.println("portmapper is alive."); // // Ask for a non-existent ONC/RPC server. // int port; System.out.print("getPort() for non-existing program: "); try { port = getPort(portmap, 1, 1, OncRpcProtocols.ONCRPC_UDP); System.out.println("method call failed (program found)."); } catch ( OncRpcException e ) { if ( e.getReason() != OncRpcException.RPC_PROGNOTREGISTERED ) { System.out.println("method call failed unexpectedly:"); e.printStackTrace(System.out); System.exit(10); } System.out.println("succeeded (RPC_PROGNOTREGISTERED)."); } // // Register dummy ONC/RPC server. // System.out.print("setPort() dummy server identification: "); try { setPort(portmap, 1, 42, OncRpcProtocols.ONCRPC_UDP, 65535); } catch ( OncRpcException e ) { System.out.println("method call failed unexpectedly:"); e.printStackTrace(System.out); System.exit(12); } System.out.println("succeeded."); // // Now dump the current list of registered servers. // OncRpcServerIdent [] list = null; int i; boolean found = false; System.out.print("listServers(): "); try { list = listServers(portmap); } catch ( OncRpcException e ) { System.out.println("method call failed unexpectedly:"); e.printStackTrace(System.out); System.exit(20); } System.out.println("succeeded."); for ( i = 0; i < list.length; ++i ) { if ( (list[i].program == 1) && (list[i].version == 42) && (list[i].protocol == OncRpcProtocols.ONCRPC_UDP) && (list[i].port == 65535) ) { found = true; } System.out.println(" " + list[i].program + " " + list[i].version + " " + list[i].protocol + " " + list[i].port); } if ( !found ) { System.out.println("registered dummy server ident not found."); System.exit(22); } // // Deregister dummy ONC/RPC server. // System.out.print("unsetPort() dummy server identification: "); try { unsetPort(portmap, 1, 42); } catch ( OncRpcException e ) { System.out.println("method call failed unexpectedly:"); e.printStackTrace(System.out); System.exit(12); } System.out.println("succeeded."); // // Now dump again the current list of registered servers. // found = false; list = null; System.out.print("listServers(): "); try { list = listServers(portmap); } catch ( OncRpcException e ) { System.out.println("method call failed unexpectedly:"); e.printStackTrace(System.out); System.exit(20); } System.out.println("succeeded."); for ( i = 0; i < list.length; ++i ) { if ( (list[i].program == 1) && (list[i].version == 42) && (list[i].protocol == OncRpcProtocols.ONCRPC_UDP) && (list[i].port == 65535) ) { found = true; break; } } if ( found ) { System.out.println("registered dummy server ident still found after deregistering."); System.exit(22); } // // Release resources bound by portmap client object as soon as possible // so might help the garbage wo/man. Yeah, this is now a political // correct comment. // portmap.close(); portmap = null; } public static void main(String[] args) { System.out.println("HttpTunnelPortmapTest"); try { new HttpTunnelPortmapTest(); } catch ( Exception e ) { e.printStackTrace(System.out); } } // // Directly stolen from org.acplt.oncrpc.OncRpcPortmapClient... // public int getPort(OncRpcClient client, int program, int version, int protocol) throws OncRpcException { // // Fill in the request parameters. Note that params.port is // not used. BTW - it is automatically initialized as 0 by the // constructor of the OncRpcServerParams class. // OncRpcServerIdent params = new OncRpcServerIdent(program, version, protocol, 0); OncRpcGetPortResult result = new OncRpcGetPortResult(); // // Try to contact the portmap process. If something goes "boing" // at this stage, then rethrow the exception as a generic portmap // failure exception. Otherwise, if the port number returned is // zero, then no appropriate server was found. In this case, // throw an exception, that the program requested could not be // found. // try { client.call(OncRpcPortmapServices.PMAP_GETPORT, params, result); } catch ( OncRpcException e ) { throw(new OncRpcException(OncRpcException.RPC_PMAPFAILURE)); } // // In case the program is not registered, throw an exception too. // if ( result.port == 0 ) { throw(new OncRpcProgramNotRegisteredException()); } return result.port; } public boolean setPort(OncRpcClient client, int program, int version, int protocol, int port) throws OncRpcException { // // Fill in the request parameters. // OncRpcServerIdent params = new OncRpcServerIdent(program, version, protocol, port); XdrBoolean result = new XdrBoolean(false); // // Try to contact the portmap process. If something goes "boing" // at this stage, then rethrow the exception as a generic portmap // failure exception. // try { client.call(OncRpcPortmapServices.PMAP_SET, params, result); } catch ( OncRpcException e ) { throw(new OncRpcException(OncRpcException.RPC_PMAPFAILURE)); } return result.booleanValue(); } public boolean unsetPort(OncRpcClient client, int program, int version) throws OncRpcException { // // Fill in the request parameters. // OncRpcServerIdent params = new OncRpcServerIdent(program, version, 0, 0); XdrBoolean result = new XdrBoolean(false); // // Try to contact the portmap process. If something goes "boing" // at this stage, then rethrow the exception as a generic portmap // failure exception. // try { client.call(OncRpcPortmapServices.PMAP_UNSET, params, result); } catch ( OncRpcException e ) { throw(new OncRpcException(OncRpcException.RPC_PMAPFAILURE)); } return result.booleanValue(); } public OncRpcServerIdent [] listServers(OncRpcClient client) throws OncRpcException { // // Fill in the request parameters. // OncRpcDumpResult result = new OncRpcDumpResult(); // // Try to contact the portmap process. If something goes "boing" // at this stage, then rethrow the exception as a generic portmap // failure exception. // try { client.call(OncRpcPortmapServices.PMAP_DUMP, XdrVoid.XDR_VOID, result); } catch ( OncRpcException e ) { throw(new OncRpcException(OncRpcException.RPC_PMAPFAILURE)); } // // Copy the server ident object references from the Vector // into the vector (array). // OncRpcServerIdent [] info = new OncRpcServerIdent[result.servers.size()]; result.servers.copyInto(info); return info; } } // End of HttpTunnelPortmapTest.java remotetea-1.0.7/src/tests/org/acplt/oncrpc/PortmapGetPortTest.html0000644005374700003410000000443407716406412026420 0ustar piccainstrumentation Project GetEPTest

    PortmapGetPortTest.java


    Demonstrates and tests the ONC/RPC portmap client object (class OncRpcPortmapClient). At the same time UDP-based streams are tested too by this example, as communication with the portmapper is UDP/IP-based.

    • Create portmapper proxy object of class OncRpcPortmapClient. to contact the portmapper on the local host.
    • Ask for the port number using the OncRpcPortmapClient.getPort method of a particular non-existing ONC/RPC server on the local host to test exceptions.
    • List all registered ONC/RPC servers using OncRpcPortmapClient.listServers method.
    • Release resources and give portmapper proxy object free.


    This test is part of the ACPLT/KS ACPLTea Java Library package.

    (c) 1999 Lehrstuhl für Prozeßleittechnik, Aachen University of Technology, Germany.

    This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License along with this program (see the file COPYING.LIB for more details); if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

    remotetea-1.0.7/src/tests/org/acplt/oncrpc/PortmapGetPortTest.java0000644005374700003410000001424207716406412026373 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/tests/org/acplt/oncrpc/PortmapGetPortTest.java,v 1.1.1.1 2003/08/13 12:03:53 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package tests.org.acplt.oncrpc; import java.io.IOException; import java.net.*; import org.acplt.oncrpc.*; public class PortmapGetPortTest { public PortmapGetPortTest() throws OncRpcException, IOException { // // Create a portmap client object, which can then be used to contact // a local or remote ONC/RPC portmap process. In this test we contact // the local portmapper. // OncRpcPortmapClient portmap = new OncRpcPortmapClient(InetAddress.getByName("localhost")); //portmap.setRetransmissionMode(OncRpcUdpRetransmissionMode.FIXED); //portmap.setRetransmissionTimeout(3*1000); // // Ping the portmapper... // System.out.print("pinging portmapper: "); try { portmap.ping(); } catch ( OncRpcException e ) { System.out.println("method call failed unexpectedly:"); e.printStackTrace(System.out); System.exit(1); } System.out.println("portmapper is alive."); // // Ask for a non-existent ONC/RPC server. // int port; System.out.print("getPort() for non-existing program: "); try { port = portmap.getPort(1, 1, OncRpcProtocols.ONCRPC_UDP); System.out.println("method call failed (program found)."); } catch ( OncRpcException e ) { if ( e.getReason() != OncRpcException.RPC_PROGNOTREGISTERED ) { System.out.println("method call failed unexpectedly:"); e.printStackTrace(System.out); System.exit(10); } System.out.println("succeeded (RPC_PROGNOTREGISTERED)."); } // // Register dummy ONC/RPC server. // System.out.print("setPort() dummy server identification: "); try { portmap.setPort(1, 42, OncRpcProtocols.ONCRPC_UDP, 65535); } catch ( OncRpcException e ) { System.out.println("method call failed unexpectedly:"); e.printStackTrace(System.out); System.exit(12); } System.out.println("succeeded."); // // Now dump the current list of registered servers. // OncRpcServerIdent [] list = null; int i; boolean found = false; System.out.print("listServers(): "); try { list = portmap.listServers(); } catch ( OncRpcException e ) { System.out.println("method call failed unexpectedly:"); e.printStackTrace(System.out); System.exit(20); } System.out.println("succeeded."); for ( i = 0; i < list.length; ++i ) { if ( (list[i].program == 1) && (list[i].version == 42) && (list[i].protocol == OncRpcProtocols.ONCRPC_UDP) && (list[i].port == 65535) ) { found = true; } System.out.println(" " + list[i].program + " " + list[i].version + " " + list[i].protocol + " " + list[i].port); } if ( !found ) { System.out.println("registered dummy server ident not found."); System.exit(22); } // // Deregister dummy ONC/RPC server. // System.out.print("unsetPort() dummy server identification: "); try { portmap.unsetPort(1, 42); } catch ( OncRpcException e ) { System.out.println("method call failed unexpectedly:"); e.printStackTrace(System.out); System.exit(12); } System.out.println("succeeded."); // // Now dump again the current list of registered servers. // found = false; list = null; System.out.print("listServers(): "); try { list = portmap.listServers(); } catch ( OncRpcException e ) { System.out.println("method call failed unexpectedly:"); e.printStackTrace(System.out); System.exit(20); } System.out.println("succeeded."); for ( i = 0; i < list.length; ++i ) { if ( (list[i].program == 1) && (list[i].version == 42) && (list[i].protocol == OncRpcProtocols.ONCRPC_UDP) && (list[i].port == 65535) ) { found = true; break; } } if ( found ) { System.out.println("registered dummy server ident still found after deregistering."); System.exit(22); } // // Release resources bound by portmap client object as soon as possible // so might help the garbage wo/man. Yeah, this is now a political // correct comment. // portmap.close(); portmap = null; } public static void main(String[] args) { System.out.println("PortmapGetPortTest"); try { new PortmapGetPortTest(); } catch ( Exception e ) { e.printStackTrace(System.out); } } } // End of PortmapGetPortTest.java remotetea-1.0.7/src/tests/org/acplt/oncrpc/PseudoHttpServer.java0000644005374700003410000000445207716637446026111 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/tests/org/acplt/oncrpc/PseudoHttpServer.java,v 1.2 2003/08/14 09:49:58 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package tests.org.acplt.oncrpc; import java.io.*; import java.net.*; public class PseudoHttpServer { public PseudoHttpServer() throws IOException { ServerSocket sock = new ServerSocket(80); for ( ;; ) { try { Socket client = sock.accept(); System.out.println("--REQUEST--"); BufferedReader in = new BufferedReader( new InputStreamReader(client.getInputStream())); String line; for ( ;; ) { line = in.readLine(); if ( line == null ) { break; } System.out.println(line); } System.out.println("--/REQUEST--"); in.close(); client.close(); } catch ( IOException e ) { System.out.println(); System.out.println("----"); } } } public static void main(String[] args) { System.out.println("PseudoHttpServer"); try { new PseudoHttpServer(); } catch ( Exception e ) { e.printStackTrace(System.out); } } } // End of PseudoHttpServer.javaremotetea-1.0.7/src/tests/org/acplt/oncrpc/ServerTest.html0000644005374700003410000000323007716406412024730 0ustar piccainstrumentation Project ServerTest

    ServerTest.java


    This example demonstrates how to write a simple ONC/RPC server. It registers an ONC/PRC program (number 0x49679) and accepts calls over TCP/IP and UDP/IP. To stop the server you should send it a call for program #42, procedure #42 with version #42. For this you should use the rpcinfo command line utility coming with your favourite ONC/RPC distribution.


    This test is part of the ACPLT/KS ACPLTea Java Library package.

    (c) 1999 Lehrstuhl für Prozeßleittechnik, Aachen University of Technology, Germany.

    This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License along with this program (see the file COPYING.LIB for more details); if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

    remotetea-1.0.7/src/tests/org/acplt/oncrpc/ServerTest.java0000644005374700003410000002111707716406412024711 0ustar piccainstrumentation/* * $Header: /cvsroot/remotetea/remotetea/src/tests/org/acplt/oncrpc/ServerTest.java,v 1.1.1.1 2003/08/13 12:03:53 haraldalbrecht Exp $ * * Copyright (c) 1999, 2000 * Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen * D-52064 Aachen, Germany. * All rights reserved. * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package tests.org.acplt.oncrpc; import java.io.IOException; import java.net.*; import org.acplt.oncrpc.*; import org.acplt.oncrpc.server.*; public class ServerTest implements OncRpcDispatchable { public class ShutdownHookThread extends Thread { private ServerTest svr; public ShutdownHookThread(ServerTest svr) { this.svr = svr; } public void run() { System.out.println("Shutdown Hook Thread activated"); svr.shutdown(); } } // // Flag to signal shut down of the server. // public Object leaveTheStage = new Object(); // // Shorthand credential use counter. // public int shorthandCredCounter = 0; // // // public ServerTest() throws OncRpcException, IOException { OncRpcUdpServerTransport udpTrans = new OncRpcUdpServerTransport(this, 55555, 0x49679, 1, 8192); final OncRpcTcpServerTransport tcpTrans = new OncRpcTcpServerTransport(this, 55555, 0x49679, 1, 8192); Runtime.getRuntime().addShutdownHook(new ShutdownHookThread(this)); udpTrans.register(); tcpTrans.register(); System.out.println("Server started."); tcpTrans.listen(); udpTrans.listen(); // // Reality Check: open a connection to the TCP/IP server socket // waiting for incoming connection, thus testing proper shutdown // behaviour later... // OncRpcTcpClient client = new OncRpcTcpClient( InetAddress.getByName("127.0.0.1"), 0x49679, 1, 0); // // Now wait for the shutdown to become signalled... Note that // a simple call to wait() without the outer loop would not be // sufficient as we might get spurious wake-ups due to // interruptions. // for ( ;; ) { synchronized ( leaveTheStage ) { try { leaveTheStage.wait(); break; } catch ( InterruptedException e ) { } } } System.out.println("Server shutting down..."); // // Unregister TCP-based transport. Then close it. This will // also automatically bring down the threads handling individual // TCP transport connections. // tcpTrans.unregister(); tcpTrans.close(); // // Unregister UDP-based transport. Then close it. This will // automatically bring down the thread which handles the // UDP transport. // udpTrans.unregister(); udpTrans.close(); System.out.println("Server shut down."); } // // Indicate that the server should be shut down. Sad enough that the // Java Environment can not cope with signals. I know that they're not // universially available -- but why shouldn't be there a class providing // this functionality and in case the runtime environment does not support // sending and receiving signals, it either throws an exception or gives // some indication otherwise. It wouldn't be bad and we would be sure // that the appropriate class is always available. // public void shutdown() { if ( leaveTheStage != null ) { System.out.println("Requesting server to shut down..."); synchronized ( leaveTheStage ) { leaveTheStage.notify(); } } } // // Handle incomming calls... // public void dispatchOncRpcCall(OncRpcCallInformation call, int program, int version, int procedure) throws OncRpcException, IOException { // // Spit out some diagnosis messages... // System.out.println("Incomming call for program " + Integer.toHexString(program) + "; version " + version + "; procedure " + Integer.toHexString(procedure) + "; auth type " + call.callMessage.auth.getAuthenticationType()); // // Handle incomming credentials... // if ( call.callMessage.auth.getAuthenticationType() == OncRpcAuthType.ONCRPC_AUTH_UNIX ) { OncRpcServerAuthUnix auth = (OncRpcServerAuthUnix) call.callMessage.auth; if ( (auth.uid != 42) && (auth.gid != 815) ) { throw(new OncRpcAuthenticationException( OncRpcAuthStatus.ONCRPC_AUTH_BADCRED)); } // // Suggest shorthand authentication... // XdrBufferEncodingStream xdr = new XdrBufferEncodingStream(8); xdr.beginEncoding(null, 0); xdr.xdrEncodeInt(42); xdr.xdrEncodeInt(~42); xdr.endEncoding(); // // ATTENTION: this will return the *whole* buffer created by the // constructor of XdrBufferEncodingStream(len) above. So make sure // that you really want to return the whole buffer! // auth.setShorthandVerifier(xdr.getXdrData()); } else if ( call.callMessage.auth.getAuthenticationType() == OncRpcAuthType.ONCRPC_AUTH_SHORT ) { // // Check shorthand credentials. // OncRpcServerAuthShort auth = (OncRpcServerAuthShort) call.callMessage.auth; XdrBufferDecodingStream xdr = new XdrBufferDecodingStream(auth.getShorthandCred()); xdr.beginDecoding(); int credv1 = xdr.xdrDecodeInt(); int credv2 = xdr.xdrDecodeInt(); xdr.endDecoding(); if ( credv1 != ~credv2 ) { System.out.println("AUTH_SHORT rejected"); throw(new OncRpcAuthenticationException( OncRpcAuthStatus.ONCRPC_AUTH_REJECTEDCRED)); } if ( (++shorthandCredCounter % 3) == 0 ) { System.out.println("AUTH_SHORT too old"); throw(new OncRpcAuthenticationException( OncRpcAuthStatus.ONCRPC_AUTH_REJECTEDCRED)); } System.out.println("AUTH_SHORT accepted"); } // // Now dispatch incomming calls... // switch ( procedure ) { case 0: // // The usual ONC/RPC PING (aka "NULL" procedure) // call.retrieveCall(XdrVoid.XDR_VOID); call.reply(XdrVoid.XDR_VOID); break; case 1: { // // echo string parameter // XdrString param = new XdrString(); call.retrieveCall(param); System.out.println("Parameter: \"" + param.stringValue() + "\""); call.reply(param); break; } case 42: // // This is a special call to shut down the server... // if ( (program == 42) && (version == 42) ) { call.retrieveCall(XdrVoid.XDR_VOID); call.reply(XdrVoid.XDR_VOID); shutdown(); break; } // // For all unknown calls, send back an error reply. // default: call.failProcedureUnavailable(); } } public static void main(String[] args) { System.out.println("ServerTest"); try { new ServerTest(); } catch ( Exception e ) { e.printStackTrace(System.out); } } } // End of PortmapGetPortTest.java