[commons-daemon] 01/52: Imported Upstream version 1.0
Tony Mancill
tmancill at moszumanska.debian.org
Wed Nov 12 05:31:26 UTC 2014
This is an automated email from the git hooks/post-receive script.
tmancill pushed a commit to branch master
in repository commons-daemon.
commit ac42f6a1fe0ddb5970c0142414d5d3d8684e78a1
Author: tony mancill <tmancill at debian.org>
Date: Fri Nov 7 07:59:26 2014 -0800
Imported Upstream version 1.0
---
KEYS | 51 +
LICENSE | 15 +
LICENSE.txt | 202 ++
PROPOSAL.html | 140 +
README | 21 +
RELEASE-NOTES.txt | 25 +
STATUS.html | 74 +
build-maven.xml | 204 ++
build.properties.sample | 6 +
build.xml | 256 ++
project.properties | 15 +
project.xml | 55 +
src/conf/MANIFEST.MF | 5 +
src/docs/daemon.css | 128 +
src/docs/daemon.html | 261 ++
src/java/org/apache/commons/daemon/Daemon.java | 144 +
.../org/apache/commons/daemon/DaemonContext.java | 87 +
.../apache/commons/daemon/DaemonController.java | 106 +
.../org/apache/commons/daemon/DaemonListener.java | 65 +
.../apache/commons/daemon/DaemonPermission.java | 427 +++
.../commons/daemon/support/DaemonLoader.java | 362 ++
src/media/logo.xcf | Bin 0 -> 22934 bytes
src/native/nt/Makefile | 3 +
src/native/nt/README | 62 +
src/native/nt/executables/vdmoniadm/icon1.ico | Bin 0 -> 766 bytes
src/native/nt/executables/vdmoniadm/resource.h | 82 +
src/native/nt/executables/vdmoniadm/vdmoniadm.dsp | 121 +
src/native/nt/executables/vdmoniadm/vdmoniadm.dsw | 29 +
src/native/nt/executables/vdmoniadm/vdmoniadm.rc | 344 ++
src/native/nt/executables/vdmonisvc/resource.h | 69 +
src/native/nt/executables/vdmonisvc/vdmonisvc.dsp | 122 +
src/native/nt/executables/vdmonisvc/vdmonisvc.dsw | 29 +
src/native/nt/executables/vdmonisvc/vdmonisvc.rc | 105 +
src/native/nt/lib/moni_inst.h | 14 +
src/native/nt/moni/Makefile | 15 +
src/native/nt/moni/vdmoniadm.c | 635 ++++
src/native/nt/moni/vdmonisvc.c | 748 +++++
src/native/nt/procrun/License.rtf | 30 +
src/native/nt/procrun/Makefile | 20 +
src/native/nt/procrun/extend.h | 3 +
src/native/nt/procrun/icoi.ico | Bin 0 -> 318 bytes
src/native/nt/procrun/icos.ico | Bin 0 -> 318 bytes
src/native/nt/procrun/icow.ico | Bin 0 -> 318 bytes
src/native/nt/procrun/jakarta-banner.bmp | Bin 0 -> 25462 bytes
src/native/nt/procrun/java/Test.java | 18 +
src/native/nt/procrun/procgui.c | 1300 +++++++
src/native/nt/procrun/procrun.c | 3306 ++++++++++++++++++
src/native/nt/procrun/procrun.dev | 62 +
src/native/nt/procrun/procrun.dsp | 293 ++
src/native/nt/procrun/procrun.dsw | 41 +
src/native/nt/procrun/procrun.h | 359 ++
src/native/nt/procrun/procrun.rc | 232 ++
src/native/nt/procrun/procrun.sln | 39 +
src/native/nt/procrun/procrun.vcproj | 374 +++
src/native/nt/procrun/procrund.dev | 62 +
src/native/nt/procrun/procrunw.dev | 70 +
src/native/nt/procrun/proctry.ico | Bin 0 -> 1078 bytes
src/native/nt/procrun/readme.txt | 149 +
src/native/nt/procrun/splash.bmp | Bin 0 -> 116718 bytes
src/native/nt/procrun/testchild/testchild.c | 121 +
src/native/nt/procrun/testchild/testchild.dsp | 106 +
src/native/nt/procrun/testchild/testchild.vcproj | 120 +
src/native/nt/service/Makefile | 7 +
src/native/nt/service/instmain.c | 477 +++
src/native/nt/service/instsvc.dsp | 104 +
src/native/nt/service/instsvc.dsw | 29 +
src/native/nt/signals/kills.c | 88 +
src/native/nt/supcalls_nt/vdenv.c | 219 ++
src/native/unix/INSTALL.txt | 36 +
src/native/unix/Makedefs.in | 71 +
src/native/unix/Makefile.in | 80 +
src/native/unix/configure | 3530 ++++++++++++++++++++
src/native/unix/configure.in | 140 +
src/native/unix/native/Makefile.in | 43 +
src/native/unix/native/Tomcat.sh | 77 +
src/native/unix/native/Tomcat5.sh | 76 +
src/native/unix/native/arguments.c | 262 ++
src/native/unix/native/arguments.h | 79 +
src/native/unix/native/debug.c | 53 +
src/native/unix/native/debug.h | 58 +
src/native/unix/native/dso-dlfcn.c | 55 +
src/native/unix/native/dso-dyld.c | 131 +
src/native/unix/native/dso.h | 27 +
src/native/unix/native/help.c | 83 +
src/native/unix/native/help.h | 17 +
src/native/unix/native/home.c | 243 ++
src/native/unix/native/home.h | 44 +
src/native/unix/native/java.c | 437 +++
src/native/unix/native/java.h | 28 +
src/native/unix/native/jsvc-unix.c | 514 +++
src/native/unix/native/jsvc.h | 46 +
src/native/unix/native/location.c | 111 +
src/native/unix/native/location.h | 22 +
src/native/unix/native/replace.c | 109 +
src/native/unix/native/replace.h | 37 +
src/native/unix/native/signals.c | 99 +
src/native/unix/support/apfunctions.m4 | 80 +
src/native/unix/support/apjava.m4 | 130 +
src/native/unix/support/apsupport.m4 | 126 +
src/native/unix/support/buildconf.sh | 74 +
src/native/unix/support/config.guess | 1371 ++++++++
src/native/unix/support/config.sub | 1362 ++++++++
src/native/unix/support/install.sh | 251 ++
src/samples/AloneDaemon.sh | 27 +
src/samples/AloneService.java | 168 +
src/samples/README.txt | 37 +
src/samples/ServiceDaemon.java | 174 +
src/samples/ServiceDaemon.sh | 25 +
src/samples/ServiceDaemonReadThread.java | 83 +
src/samples/SimpleDaemon.java | 342 ++
src/samples/SimpleDaemon.sh | 23 +
src/samples/build.xml | 75 +
.../org/apache/commons/daemon/SimpleDaemon.java | 344 ++
xdocs/binaries.xml | 49 +
xdocs/faq.xml | 50 +
xdocs/images/logo.gif | Bin 0 -> 4540 bytes
xdocs/images/logo.png | Bin 0 -> 13595 bytes
xdocs/index.xml | 93 +
xdocs/jsvc.xml | 172 +
xdocs/navigation.xml | 37 +
xdocs/procrun.xml | 189 ++
xdocs/style/project.css | 5 +
122 files changed, 24451 insertions(+)
diff --git a/KEYS b/KEYS
new file mode 100644
index 0000000..d598597
--- /dev/null
+++ b/KEYS
@@ -0,0 +1,51 @@
+This file contains the PGP&GPG keys of various Apache developers.
+Please don't use them for email unless you have to. Their main
+purpose is code signing.
+
+Apache users: pgp < KEYS
+Apache developers:
+ (pgpk -ll <your name> && pgpk -xa <your name>) >> this file.
+ or
+ (gpg --fingerprint --list-sigs <your name>
+ && gpg --armor --export <your name>) >> this file.
+
+Apache developers: please ensure that your key is also available via the
+PGP keyservers (such as pgpkeys.mit.edu).
+
+Type Bits/KeyID Date User ID
+pub 1024D/86867BA6 2001-11-22 Jean-Frederic Clere (jfclere) <JFrederic.Clere at fujitsu-siemens.com>
+
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.3.3 (GNU/Linux)
+
+mQGiBDv9Gx8RBADclmKwDLcibNVipQnhYW+bFIpuQjQnRrqRwn3gXM+/luzzJYJ4
+bbWpw13zjX0EkrAJ8qH2A/d0EIU1eZ0zHrLgRvMUfLGFUX7FFFw18JKFLTVGhG4/
+8sSl3ydHSA2Kd1PF6xjBP7iM7sg5dJfEkyMzvK5H4F0ZpTqy3087wsg1wwCgitRy
+Zg4x3lWZSkOwBj472qaO9GkD/2q6kyWfAK6XFe3GuB5AAs3poMfN1eqW+duM4TA8
+zUiWK0Wxx4JXJbL7n0i4d+JdXJsrjSjF++KKfelcxsrSxoUIBegez25MUSvHe09D
+R3nqkY8CVO+viEtzRBqkSgCMbUjAtfkQ+vp2jDnWSmmkNfY0OYAzt+KRyJKcjUSJ
+gvOOA/45+DN9wuTELoFTvsXh1JgOL/QvW1fmQ2HrcQk94BkzIsfVGWClCiig5gNw
+LCxTbfgA5htpI8U7vPR9/5gH7U8Wy3HR6xQUZxcbttMeYit2VbDEJzF5r5S0pJvD
+vyk3n1kiKU7r49sjhxGgE8J/VvDpO6YcIsDs8LoULwuJTg0DTrRDSmVhbi1GcmVk
+ZXJpYyBDbGVyZSAoamZjbGVyZSkgPEpGcmVkZXJpYy5DbGVyZUBmdWppdHN1LXNp
+ZW1lbnMuY29tPohGBBARAgAGBQJAEVHcAAoJEFd7hHVGA0DQsUsAoK2SuAnTybek
+AJkFmei/kbv59fA+AJ4/smxUz6EGuNmWOYwnHTxPz09c4IhXBBMRAgAXBQI7/Rsf
+BQsHCgMEAxUDAgMWAgECF4AACgkQ0+/mtoaGe6amGQCeJU5VZ8QCi8+PY0QJHPA6
+3e5uPyoAmgOWIwFm8A/xmW8qjEvVAWtbTjZxiJwEEwECAAYFAj/F+7gACgkQN+P0
+X+5l4yHDEwQAwp2yr9mwHIti5D2tvgNDQjOw9K/qbGbQ1IH3f/BLF0J5EHxYxUSt
+E0glh8GPJOi1U+0Jv999W/8xnOs5Tf16d0DmhscXvylxWYGis1PcoqA2zemaWuVM
+nBoJaA89gPiwconEEvdxym7vBGK1Lodz+ote2doiuCsWSjcfl74LFxeInAQTAQIA
+BgUCP8dbpwAKCRArAsNF4kSQGcqYA/9ZkL7Uwy1xZ8EPAQT6eXVCmS743C3Mc2kr
+Cv8CEnsVNQrsQMYzkU2OjsJ09semmIHnvpx14i8cGlLRoKpfNn7V+O6wmMEHr2zn
+HlMtDsgvk8FK12cDGGxUlHr9sz6wOTQyZG3bNLA9iQPUlHAjTTZlISx55i3/opKQ
+yI5LzOMaSrkBDQQ7/RsjEAQAgmxZUhfrnVv0M9qJJw3p/B6KpeENUOwlEE2z46EA
+HGIGYC67EeoXPWgiH9yreKmQYENTnvTPwHpjhYVNOFDad3YB5PdRGEb8fNEbmvfd
+qf/Fe0DocCAVW9lxPGrOZy9o/MOic+3krP24r8Zvcg9AB/yOR9NUQCYr0Wzk7FIE
+pA8AAwUD+QEZVtjanNFNe2rELJjGL09VDIjosgcFA/wyBBtl8tYZRL3ZY4PFlNuo
+3I6RqjK0+vU+GfnmdqFcokUE1uKjFASnNDW8/PYS9Kr/SuNRMccR/iYBNXLEVb5s
+AE/CMpZ4aH+0yS0Qbb2p9/qdtSsZdbkOzG5i0/O+bvr3PidPfHyIiEYEGBECAAYF
+Ajv9GyMACgkQ0+/mtoaGe6Z/VACfX9EytEEDrY0Ab8QIrLKKWIQyhxgAnj2YNJPb
+I+vcsJ1VqwUvX7xQvY3A
+=6E4I
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..4b98d6d
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,15 @@
+/*
+ Copyright 2001-2004 The Apache Software Foundation.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/PROPOSAL.html b/PROPOSAL.html
new file mode 100644
index 0000000..18250bd
--- /dev/null
+++ b/PROPOSAL.html
@@ -0,0 +1,140 @@
+<html>
+<head>
+<title>Proposal for Daemon Package</title>
+</head>
+<body bgcolor="white">
+
+<div align="center">
+<h1>Proposal for <em>Daemon</em> Package</h1>
+</div>
+
+<h3>(0) Rationale</h3>
+
+ <P>
+ Since 1994, the Java™ programming language evolved and became a
+ valid tool to develop, other than applets and client applications,
+ reliable and performant server applications. The major disadvantage of
+ the Java™ platform is that still today the only portable way to
+ start a Java™ applcation relies on a single point of entry: the
+ <CODE><EM CLASS="key">public static void</EM> main(<EM CLASS="ref">String</EM>[])</CODE>
+ method.
+ </P>
+ <P>
+ Having a single-point of entry is a valid solution for client
+ applications, where interactively a user can command to the application
+ to quit (which can terminate the Virtual Machine process at calling the
+ <CODE><EM CLASS="ref">System</EM>.exit(<EM CLASS="key">int</EM>)</CODE>
+ method), but in those cases where the application is not interactive
+ (server applications) there is currently no portable way to notify
+ the Virtual Machine of its imminent shutdown.
+ </P>
+ <P>
+ A server application written in Java might have to perform several tasks
+ before being able to shutdown the Virtual Machine process. For example
+ in the case of a Servlet container, before the VM process is shut down,
+ sessions might need to be serialized to disk, and web applications need
+ to be destroyed.
+ </P>
+ <P>
+ One common solution to this problem is to create (for example) a
+ <CODE><EM CLASS="ref">ServerSocket</EM></CODE> and wait for a particular
+ message to be issued. When the message is received, all operations
+ required to shut down the server applications are performed and at the
+ end the <CODE><EM CLASS="ref">System</EM>.exit</CODE> method is called
+ to terminate the Virtual Machine process. This method, however, implies
+ several disadvantages and risks: for example in case of a system-wide
+ shutdown, it might happen that the Virtual Machine process will be shut
+ down directly by the operating system, without notifying the running
+ server application. Or, for example, if an attacker finds out what is
+ the required message to send to the server, and discovers a way to send
+ this message to the running server application, he can easily interrupt
+ the operation of a server, bypassing all the security restrictions
+ implemented in the operating system.
+ </P>
+ <P>
+ Most multi-user operating systems already have a way in which server
+ applications are started and stopped, under Unix based operating systems
+ non interactive server applications are called <em>daemons</em> and are
+ controlled by the operating system with a set of specified
+ <em>signals</em>. Under Windows such programs are called <em>services</em>
+ and are controlled by appropriate calls to specific functions defined in
+ the application binary, but although the ways of dealing with the problem
+ are different, in both cases the operating system can notify a server
+ application of its imminent shutdown, and the application has the
+ ability to perform certain tasks before its process of execution is
+ destroyed.
+ </P>
+
+<h3>(1) Scope of the Package</h3>
+
+ <P>
+ The scope of this specification is to define an API in line with the
+ current Java™ Platform APIs to support an alternative invocation
+ mechanism which could be used instead of the above mentioned
+ <CODE><EM CLASS="key">public static void</EM> main(<EM CLASS="ref">String</EM>[])</CODE>
+ method. This specification cover the behavior and life cycle of what
+ we define as "Java ™ daemons", or, in other words,
+ non interactive Java™ applications.
+ </P>
+ <P>
+ This specification does not cover how the container of a Java™
+ daemon must be implemented, or how to build a native liaison between
+ the operating system and the <CODE><EM CLASS="ref">Daemon</EM></CODE>
+ interface, but defines the relation between the an operating system
+ process and the <CODE><EM CLASS="ref">Daemon</EM></CODE> implementation
+ life cycle. It should be trivial for implementors to build a native
+ liaison and container for Java™ daemons.
+ </P>
+ <P>
+ This specification, together with the related API documentation, can be
+ used by software deveopers to build portable non interactive applications
+ based on the Java™ platform.
+ </P>
+
+<h3>(1.5) Interaction With Other Packages</h3>
+
+<p><em>Daemon</em> relies only on standard JDK 1.2 (or later) APIs for
+production deployment. It utilizes the JUnit unit testing framework for
+developing and executing unit tests, but this is of interest only to
+developers of the component. Daemon will be a dependency for
+several existing components in the open source world.</p>
+
+<p>No external configuration files are utilized.</p>
+
+
+<h3>(2) Initial Source of the Package</h3>
+
+<p>The original Java classes come from the Jakarta Tomcat 4.0 project.</p>
+
+<p>The proposed package name for the new component is
+<code>org.apache.commons.daemon</code>.</p>
+
+
+<h3>(3) Required Jakarta-Commons Resources</h3>
+
+<ul>
+<li>CVS Repository - New directory <code>daemon</code> in the
+ <code>jakarta-commons</code> CVS repository.</li>
+<li>Mailing List - Discussions will take place on the general
+ <em>commons-dev at jakarta.apache.org</em> mailing list. To help
+ list subscribers identify messages of interest, it is suggested that
+ the message subject of messages about this component be prefixed with
+ [Daemon].</li>
+<li>Bugzilla - New component "Daemon" under the "Commons" product
+ category, with appropriate version identifiers as needed.</li>
+<li>Jyve FAQ - New category "commons-daemon" (when available).</li>
+</ul>
+
+
+<h3>(4) Initial Committers</h3>
+
+<p>The initial committers on the Daemon component shall be:</p>
+<ul>
+<li>Jean-Frederic Clere</li>
+<li>Pier Fumagalli</li>
+<li>Remy Maucherat</li>
+
+
+
+</body>
+</html>
diff --git a/README b/README
new file mode 100644
index 0000000..4e29af6
--- /dev/null
+++ b/README
@@ -0,0 +1,21 @@
+To build the JAVA part:
+ant dist
+
+To build the native part:
+1 - jsvc:
+ cd src/native/unix; configure; make
+ You need a gnu make.
+ The jsvc executable could be found in dist.
+
+ On windoze the additional step is needed:
+ cd src/native/nt; make
+ There is a README in src/native/nt please have a look to it.
+ The exe files are created in dist.
+2 - procrun:
+ procrun is only for windows
+ cd src/native/nt/procrun; make
+ (It is also possible to use the m$ developement tools).
+
+To build the documentation:
+maven site:generate
+(Do not forget to get ../project.xml (jakarta-commons/project.xml)
diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt
new file mode 100644
index 0000000..dd9efff
--- /dev/null
+++ b/RELEASE-NOTES.txt
@@ -0,0 +1,25 @@
+$Id: RELEASE-NOTES.txt,v 1.2 2004/01/13 15:07:07 yoavs Exp $
+
+ Commons Daemon Package
+ Version 1.0
+ Release Notes
+
+
+INTRODUCTION:
+
+This document contains the release notes for this version of the Commons
+Daemon package, and highlights changes since the previous version. The
+current release adds new features and bug fixes, and is being done now to
+follow the release early/release often mentality.
+
+
+NEW FEATURES:
+
+* Initial import to Commons, including the daemon Java API, and jsvc
+ for Unix and Windows NT/2K/XP, which allows running a Java program
+ as a native operating system daemon
+
+
+BUG FIXES:
+
+
diff --git a/STATUS.html b/STATUS.html
new file mode 100644
index 0000000..92b0757
--- /dev/null
+++ b/STATUS.html
@@ -0,0 +1,74 @@
+<html>
+<head>
+<title>Status File for Jakarta Commons "Daemon" Component</title>
+</head>
+<body bgcolor="white">
+
+
+<div align="center">
+<h1>The Jakarta Commons <em>Daemon</em> Component</h1>
+$Id: STATUS.html,v 1.2 2003/12/31 03:53:52 billbarker Exp $<br />
+<a href="#Introduction">[Introduction]</a>
+<a href="#Dependencies">[Dependencies]</a>
+<a href="#Release Info">[Release Info]</a>
+<a href="#Committers">[Committers]</a>
+<br /><br />
+</div>
+
+
+<a name="Introduction"></a>
+<h3>1. INTRODUCTION</h3>
+
+<p>The <em>Daemon</em> Component contains a set of Java and native code,
+including:</p>
+<ul>
+<li>A set of Java interfaces applications must implement</li>
+<li>Unix native code to control a Java daemon from a Unix operating system</li>
+<li>Win32 code to control a Java daemon from a NT based Windows operating
+system</li>
+</ul>
+<p>This code was originally developped as part of the Tomcat project.</p>
+
+
+<a name="Dependencies"></a>
+<h3>2. DEPENDENCIES</h3>
+
+<p>The <em>Daemon</em> component is dependent upon the following external
+components for development and use:</p>
+<ul>
+<li><a href="http://java.sun.com/j2se">Java Development Kit</a>
+ (Version 1.2 or later)</li>
+<li><a href="http://www.junit.org">JUnit Testing Framework</a>
+ (Version 3.7 or later) - for unit tests only, not required
+ for deployment</li>
+</ul>
+
+
+<a name="Release Info"></a>
+<h3>3. RELEASE INFO</h3>
+
+<p>Current Release: Daemon is yet to be released. We hope it will be RSN.</p>
+
+<p></p>
+
+
+<a name="Committers"></a>
+<h3>4. COMMITTERS</h3>
+
+<p>The following individuals are the primary developers and maintainers of this
+component. Developers who plan to use <em>Daemon</em> in their own
+projects are encouraged to collaborate on the future development of this
+component to ensure that it continues to meet a variety of needs.</p>
+<ul>
+<li>Jean-Frederic Clere</li>
+<li>Pier Fumagalli</li>
+<li>Patrick Luby</li>
+<li>Costin Manolache</li>
+<li>Remy Maucherat</li>
+<li>Yoav Shapira</li>
+<li>Bill Barker</li>
+</ul>
+
+
+</body>
+</html>
diff --git a/build-maven.xml b/build-maven.xml
new file mode 100644
index 0000000..a49fb4b
--- /dev/null
+++ b/build-maven.xml
@@ -0,0 +1,204 @@
+<?xml version="1.0"?>
+
+<project name="maven" default="maven:jar" basedir=".">
+
+ <!-- Give user a chance to override without editing this file
+ (and without typing -D each time they invoke a target) -->
+
+ <!-- Allow any user specific values to override the defaults -->
+ <property file="${user.home}/build.properties" />
+ <!-- Allow user defaults for this build -->
+ <property file="build.properties" />
+ <!-- Set default values for the project -->
+ <property file="project.properties" />
+
+ <!-- maven:start -->
+
+ <!-- ================================================================== -->
+ <!-- D E L E G A T O R S -->
+ <!-- ================================================================== -->
+
+
+ <target name="maven:site">
+ <ant antfile="${maven.home}/plugins/docs/build.xml" target="site"/>
+ </target>
+
+
+ <target name="maven:dist">
+ <ant antfile="${maven.home}/plugins/core/build.xml" target="dist"/>
+ </target>
+
+
+ <target name="maven:env">
+ <ant antfile="${maven.home}/plugins/core/build.xml" target="env"/>
+ </target>
+
+
+ <target name="maven:test">
+ <ant antfile="${maven.home}/plugins/test/build.xml" target="test"/>
+ </target>
+
+
+ <target name="maven:announce">
+ <ant antfile="${maven.home}/plugins/core/build.xml" target="announce"/>
+ </target>
+
+
+ <target name="maven:activity-log">
+ <ant antfile="${maven.home}/plugins/docs/build.xml" target="activity-log"/>
+ </target>
+
+
+ <target name="maven:compile">
+ <ant antfile="${maven.home}/plugins/core/build.xml" target="compile"/>
+ </target>
+
+
+ <target name="maven:validate-war">
+ <ant antfile="${maven.home}/plugins/j2ee/build.xml" target="validate-war"/>
+ </target>
+
+
+ <target name="maven:pdf">
+ <ant antfile="${maven.home}/plugins/docs/build.xml" target="pdf"/>
+ </target>
+
+
+ <target name="maven:iutest">
+ <ant antfile="${maven.home}/plugins/iutest/build.xml" target="iutest"/>
+ </target>
+
+
+ <target name="maven:deploy-site">
+ <ant antfile="${maven.home}/plugins/docs/build.xml" target="deploy-site"/>
+ </target>
+
+
+ <target name="maven:deploy-dist">
+ <ant antfile="${maven.home}/plugins/core/build.xml" target="deploy-dist"/>
+ </target>
+
+
+ <target name="maven:war">
+ <ant antfile="${maven.home}/plugins/j2ee/build.xml" target="war"/>
+ </target>
+
+
+ <target name="maven:verify-project">
+ <ant antfile="${maven.home}/plugins/core/build.xml" target="verify-project"/>
+ </target>
+
+
+ <target name="maven:cvs-change-log">
+ <ant antfile="${maven.home}/plugins/docs/build.xml" target="cvs-change-log"/>
+ </target>
+
+
+ <target name="maven:ear">
+ <ant antfile="${maven.home}/plugins/j2ee/build.xml" target="ear"/>
+ </target>
+
+
+ <target name="maven:cross-ref">
+ <ant antfile="${maven.home}/plugins/docs/build.xml" target="cross-ref"/>
+ </target>
+
+
+ <target name="maven:update-jars">
+ <ant antfile="${maven.home}/plugins/core/build.xml" target="update-jars"/>
+ </target>
+
+
+ <target name="maven:validate-pom">
+ <ant antfile="${maven.home}/plugins/core/build.xml" target="validate-pom"/>
+ </target>
+
+
+ <target name="maven:install-jar">
+ <ant antfile="${maven.home}/plugins/core/build.xml" target="install-jar"/>
+ </target>
+
+
+ <target name="maven:fo">
+ <ant antfile="${maven.home}/plugins/docs/build.xml" target="fo"/>
+ </target>
+
+
+ <target name="maven:javadocs">
+ <ant antfile="${maven.home}/plugins/docs/build.xml" target="javadocs"/>
+ </target>
+
+
+ <target name="maven:validate-struts-war">
+ <ant antfile="${maven.home}/plugins/struts/build.xml" target="validate-struts-war"/>
+ </target>
+
+
+ <target name="maven:task-list">
+ <ant antfile="${maven.home}/plugins/docs/build.xml" target="task-list"/>
+ </target>
+
+
+ <target name="maven:ejb">
+ <ant antfile="${maven.home}/plugins/j2ee/build.xml" target="ejb"/>
+ </target>
+
+
+ <target name="maven:docs">
+ <ant antfile="${maven.home}/plugins/docs/build.xml" target="docs"/>
+ </target>
+
+
+ <target name="maven:clean">
+ <ant antfile="${maven.home}/plugins/core/build.xml" target="clean"/>
+ </target>
+
+
+ <target name="maven:dist-build">
+ <ant antfile="${maven.home}/plugins/core/build.xml" target="dist-build"/>
+ </target>
+
+
+ <target name="maven:metrics">
+ <ant antfile="${maven.home}/plugins/metrics/build.xml" target="metrics"/>
+ </target>
+
+
+ <target name="maven:docs-quick">
+ <ant antfile="${maven.home}/plugins/docs/build.xml" target="docs-quick"/>
+ </target>
+
+
+ <target name="maven:run-singletest">
+ <ant antfile="${maven.home}/plugins/test/build.xml" target="run-singletest"/>
+ </target>
+
+
+ <target name="maven:check-source">
+ <ant antfile="${maven.home}/plugins/core/build.xml" target="check-source"/>
+ </target>
+
+
+ <target name="maven:generate-reactor">
+ <ant antfile="${maven.home}/plugins/reactor/build.xml" target="generate-reactor"/>
+ </target>
+
+
+ <target name="maven:jar">
+ <ant antfile="${maven.home}/plugins/core/build.xml" target="jar"/>
+ </target>
+
+
+ <target name="maven:maven-update">
+ <ant antfile="${maven.home}/plugins/core/build.xml" target="maven-update"/>
+ </target>
+
+
+ <target name="maven:gump-descriptor">
+ <ant antfile="${maven.home}/plugins/core/build.xml" target="gump-descriptor"/>
+ </target>
+
+
+ <!-- maven:end -->
+
+</project>
diff --git a/build.properties.sample b/build.properties.sample
new file mode 100644
index 0000000..1843e6c
--- /dev/null
+++ b/build.properties.sample
@@ -0,0 +1,6 @@
+# The directory containing your binary distribution of JUnit,
+# version 3.7 or later
+junit.home = /usr/local/junit3.7
+
+# The pathname of the "junit.jar" JAR file
+junit.jar = ${junit.home}/junit.jar
diff --git a/build.xml b/build.xml
new file mode 100644
index 0000000..b8ed949
--- /dev/null
+++ b/build.xml
@@ -0,0 +1,256 @@
+<project name="Daemon" default="compile" basedir=".">
+
+
+<!--
+ "Daemon" component of the Jakarta Commons Subproject
+ $Id: build.xml,v 1.3 2004/01/13 15:07:07 yoavs Exp $
+-->
+
+
+<!-- ========== Initialize Properties ===================================== -->
+
+
+ <property file="build.properties"/> <!-- Component local -->
+ <property file="../build.properties"/> <!-- Commons local -->
+ <property file="${user.home}/build.properties"/> <!-- User local -->
+
+
+<!-- ========== External Dependencies ===================================== -->
+
+
+ <!-- The directory containing your binary distribution of JUnit,
+ version 3.7 or later -->
+ <property name="junit.home" value="/usr/local/junit3.7"/>
+
+
+<!-- ========== Derived Values ============================================ -->
+
+
+ <!-- The pathname of the "junit.jar" JAR file -->
+ <property name="junit.jar" value="${junit.home}/junit.jar"/>
+
+
+<!-- ========== Component Declarations ==================================== -->
+
+
+ <!-- The name of this component -->
+ <property name="component.name" value="daemon"/>
+
+ <!-- The primary package name of this component -->
+ <property name="component.package" value="org.apache.commons.daemon"/>
+
+ <!-- The title of this component -->
+ <property name="component.title" value="Java Daemons"/>
+
+ <!-- The current version number of this component -->
+ <property name="component.version" value="1.0"/>
+
+ <!-- The base directory for compilation targets -->
+ <property name="build.home" value="target"/>
+
+ <!-- The base directory for component executable files -->
+ <property name="bin.home" value="src/bin"/>
+
+ <!-- The base directory for component configuration files -->
+ <property name="conf.home" value="src/conf"/>
+
+ <!-- The base directory for distribution targets -->
+ <property name="dist.home" value="dist"/>
+
+ <!-- The base directory for component sources -->
+ <property name="source.home" value="src/java"/>
+
+ <!-- The base directory for unit test sources -->
+ <property name="test.home" value="src/test"/>
+
+ <!-- The ant dir (usefull for non standard layout) -->
+ <property name="ant.lib" value="${ant.home}/lib"/>
+
+ <!-- The pattern to be used to grab ant jars (usefull for non standard layout) -->
+ <property name="ant.jars.pattern" value="*.jar"/>
+
+
+<!-- ========== Compiler Defaults ========================================= -->
+
+
+ <!-- Should Java compilations set the 'debug' compiler option? -->
+ <property name="compile.debug" value="true"/>
+
+ <!-- Should Java compilations set the 'deprecation' compiler option? -->
+ <property name="compile.deprecation" value="true"/>
+
+ <!-- Should Java compilations set the 'optimize' compiler option? -->
+ <property name="compile.optimize" value="true"/>
+
+ <!-- Construct compile classpath -->
+ <path id="compile.classpath">
+ <pathelement location="${build.home}/classes"/>
+ </path>
+
+
+<!-- ========== Test Execution Defaults =================================== -->
+
+
+ <!-- Construct unit test classpath -->
+ <path id="test.classpath">
+ <pathelement location="${build.home}/classes"/>
+ <pathelement location="${build.home}/tests"/>
+ <pathelement location="${junit.jar}"/>
+ </path>
+
+ <!-- Should all tests fail if one does? -->
+ <property name="test.failonerror" value="true"/>
+
+ <!-- The test runner to execute -->
+ <property name="test.runner" value="junit.textui.TestRunner"/>
+
+
+<!-- ========== Executable Targets ======================================== -->
+
+
+ <target name="init"
+ description="Initialize and evaluate conditionals">
+ <echo message="-------- ${component.name} ${component.version} --------"/>
+ <filter token="name" value="${component.name}"/>
+ <filter token="package" value="${component.package}"/>
+ <filter token="version" value="${component.version}"/>
+ </target>
+
+
+ <target name="prepare" depends="init"
+ description="Prepare build directory">
+ <mkdir dir="${build.home}"/>
+ <mkdir dir="${build.home}/classes"/>
+ <mkdir dir="${build.home}/conf"/>
+ <mkdir dir="${build.home}/tests"/>
+ </target>
+
+
+ <target name="static" depends="prepare"
+ description="Copy static files to build directory">
+ <tstamp/>
+ <copy todir="${build.home}/conf" filtering="on">
+ <fileset dir="${conf.home}" includes="*.MF"/>
+ </copy>
+ </target>
+
+
+ <target name="compile" depends="static"
+ description="Compile shareable components">
+ <javac srcdir="${source.home}"
+ destdir="${build.home}/classes"
+ debug="${compile.debug}"
+ deprecation="${compile.deprecation}"
+ optimize="${compile.optimize}">
+ <classpath refid="compile.classpath"/>
+ </javac>
+ <!-- Copy all of the resource files -->
+ <copy todir="${build.home}/classes" filtering="on">
+ <fileset dir="${source.home}" excludes="**/*.java"/>
+ </copy>
+ <!-- Make the English resource files the default resource -->
+ <copy todir="${build.home}/classes" filtering="on">
+ <fileset dir="${source.home}" includes="**/*_en.properties"/>
+ <mapper type="glob" from="*_en.properties" to="*.properties"/>
+ </copy>
+ </target>
+
+
+ <target name="compile.tests" depends="compile"
+ description="Compile unit test cases">
+ <javac srcdir="${test.home}"
+ destdir="${build.home}/tests"
+ debug="${compile.debug}"
+ deprecation="${compile.deprecation}"
+ optimize="${compile.optimize}">
+ <classpath refid="test.classpath"/>
+ </javac>
+ <copy todir="${build.home}/tests" filtering="on">
+ <fileset dir="${test.home}" excludes="**/*.java"/>
+ </copy>
+ </target>
+
+
+ <target name="clean"
+ description="Clean build and distribution directories">
+ <delete dir="${build.home}"/>
+ <delete dir="${dist.home}"/>
+ </target>
+
+
+ <target name="all" depends="clean,compile"
+ description="Clean and compile all components"/>
+
+
+ <target name="javadoc" depends="compile"
+ description="Create component Javadoc documentation">
+ <mkdir dir="${dist.home}"/>
+ <mkdir dir="${dist.home}/docs"/>
+ <mkdir dir="${dist.home}/docs/api"/>
+ <javadoc sourcepath="${source.home}"
+ destdir="${dist.home}/docs/api"
+ packagenames="org.apache.commons.*"
+ author="true"
+ version="true"
+ doctitle="<h1>${component.title}</h1>"
+ windowtitle="${component.title} (Version ${component.version})"
+ bottom="Copyright (c) 2001-2002 - Apache Software Foundation">
+ <classpath refid="compile.classpath"/>
+ <classpath location="${ant.lib}/ant.jar"/>
+ </javadoc>
+ </target>
+
+
+ <target name="dist" depends="compile,javadoc"
+ description="Create binary distribution">
+ <mkdir dir="${dist.home}"/>
+ <mkdir dir="${dist.home}/lib"/>
+ <mkdir dir="${dist.home}/logs"/>
+ <copy file="LICENSE"
+ todir="${dist.home}"/>
+ <copy file="RELEASE-NOTES.txt"
+ todir="${dist.home}"/>
+ <copy todir="${dist.home}/bin/unix/jsvc-src">
+ <fileset dir="src/native/unix" />
+ </copy>
+ <fixcrlf srcdir="${dist.home}/bin/unix" eol="lf" />
+ <tar compression="gzip" destfile="${dist.home}/bin/jsvc.tar.gz"
+ basedir="${dist.home}/bin/unix" />
+ <delete dir="${dist.home}/bin/unix" />
+ <antcall target="jar"/>
+ </target>
+
+
+ <target name="jar" depends="compile"
+ description="Create jar">
+ <mkdir dir="${dist.home}"/>
+ <mkdir dir="${dist.home}/bin"/>
+ <mkdir dir="${build.home}/classes/META-INF"/>
+ <copy file="LICENSE"
+ tofile="${build.home}/classes/META-INF/LICENSE.txt"/>
+ <jar jarfile="${dist.home}/commons-${component.name}.jar"
+ basedir="${build.home}/classes"
+ manifest="${build.home}/conf/MANIFEST.MF"
+ includes="org/apache/commons/daemon/**"/>
+ </target>
+
+
+ <target name="install-jar" depends="jar"
+ description="--> Installs jar file in ${lib.repo}">
+ <copy todir="${lib.repo}" filtering="off">
+ <fileset dir="${dist.home}">
+ <include name="commons-${component.name}.jar"/>
+ </fileset>
+ </copy>
+ </target>
+
+
+<!-- ========== Unit Test Targets ========================================= -->
+
+
+ <target name="test" depends="compile.tests"
+ description="Run all unit test cases">
+ </target>
+
+
+</project>
diff --git a/project.properties b/project.properties
new file mode 100755
index 0000000..ff1bc8b
--- /dev/null
+++ b/project.properties
@@ -0,0 +1,15 @@
+##
+# Properties that override Maven build defaults
+##
+
+#maven.checkstyle.properties=${basedir}/checkstyle.xml
+maven.test.failure = false
+maven.junit.fork=true
+maven.linkcheck.enable=false
+
+maven.xdoc.date=left
+maven.xdoc.version=${pom.currentVersion}
+maven.xdoc.developmentProcessUrl=http://jakarta.apache.org/commons/charter.html
+maven.xdoc.poweredby.image=maven-feather.png
+
+
diff --git a/project.xml b/project.xml
new file mode 100644
index 0000000..f8a2114
--- /dev/null
+++ b/project.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<project>
+ <extend>../commons-build/project.xml</extend>
+ <name>Daemon</name>
+ <id>commons-daemon</id>
+ <logo>/images/logo.gif</logo>
+ <currentVersion>1.0</currentVersion>
+
+ <organization>
+ <name>Apache Software Foundation</name>
+ <url>http://jakarta.apache.org/</url>
+ <logo>http://jakarta.apache.org/images/jakarta-logo.gif</logo>
+ </organization>
+ <logo>/images/logo.png</logo>
+
+ <inceptionYear>2003</inceptionYear>
+ <gumpRepositoryId>jakarta</gumpRepositoryId>
+ <shortDescription>Commons Daemon</shortDescription>
+
+ <description>
+ Commons Daemon
+ </description>
+
+ <developers>
+ <developer>
+ <name>Jean-Frederic Clere</name>
+ <id>jfclere</id>
+ <email>jfrederic.clere at fujitsu-siemens.com</email>
+ <organization>FSC</organization>
+ </developer>
+
+ <developer>
+ <name>Remy Maucherat</name>
+ <id>remm</id>
+ <email>remm at apache.org</email>
+ <organization>Apache</organization>
+ </developer>
+
+ <developer>
+ <name>Yoav Shapira</name>
+ <id>yoavs</id>
+ <email>yoavs at apache.org</email>
+ <organization>Apache</organization>
+ </developer>
+
+ <developer>
+ <name>Bill Barker</name>
+ <id>billbarker</id>
+ <email>billbarker at apache.org</email>
+ <organization>Apache</organization>
+ </developer>
+ </developers>
+
+</project>
diff --git a/src/conf/MANIFEST.MF b/src/conf/MANIFEST.MF
new file mode 100644
index 0000000..2f6c767
--- /dev/null
+++ b/src/conf/MANIFEST.MF
@@ -0,0 +1,5 @@
+Extension-Name: @package@
+Specification-Vendor: Apache Software Foundation
+Specification-Version: 1.0
+Implementation-Vendor: Apache Software Foundation
+Implementation-Version: @version@
diff --git a/src/docs/daemon.css b/src/docs/daemon.css
new file mode 100644
index 0000000..ac3e25b
--- /dev/null
+++ b/src/docs/daemon.css
@@ -0,0 +1,128 @@
+BODY {
+ font-family: arial, helvetica, sans-serif;
+ font-size: 10pt;
+ text-align: justify;
+}
+
+H1 {
+ border-width: 2px;
+ border-style: ridge;
+ border-color: #cccccc;
+ background-color: #ddddff;
+ font-size: 14pt;
+ font-weight: bold;
+ text-align: center;
+ padding: 2px;
+}
+
+H2 {
+ border-width: 2px;
+ border-style: ridge;
+ border-color: #cccccc;
+ background-color: #eeeeff;
+ font-size: 12pt;
+ font-weight: bold;
+ text-align: left;
+ padding: 2px;
+}
+
+H3 {
+ font-size: 10pt;
+ font-weight: bold;
+ text-align: left;
+}
+
+H4 {
+ font-size: 8pt;
+ font-weight: normal;
+ font-style: italic;
+ text-align: center;
+}
+
+P {
+ margin-left: 20px;
+}
+
+P.note {
+ border-width: 1px;
+ border-style: ridge;
+ border-color: #cccccc;
+ background-color: #ffffee;
+ font-size: 8pt;
+ font-weight: normal;
+ text-align: justify;
+ margin-left: 20%;
+ margin-right: 20%;
+ padding: 4px;
+}
+
+P.copyright {
+ font-size: 8pt;
+ font-weight: normal;
+ text-align: center;
+}
+
+PRE {
+ border-width: 1px;
+ border-style: ridge;
+ border-color: #cccccc;
+ background-color: #eeeeee;
+ font-size: 8pt;
+ font-weight: normal;
+ text-align: left;
+ margin-left: 10%;
+ margin-right: 10%;
+ padding: 4px;
+}
+
+CODE {
+ font-size: 8pt;
+ white-space: pre;
+ font-weight: normal;
+}
+
+EM.key {
+ color: #000099;
+ font-style: normal;
+ white-space: pre;
+}
+
+EM.ref {
+ color: #990000;
+ font-style: normal;
+ white-space: pre
+}
+
+EM.com {
+ color: #009900;
+ font-style: normal;
+ white-space: pre
+}
+
+OL {
+ list-style: decimal outside;
+ font-size: 10pt;
+}
+
+OL OL {
+ list-style: lower-alpha outside;
+ font-size: 8pt;
+}
+
+A:link {
+ color: #0000ee;
+ text-decoration: none;
+ white-space: pre;
+}
+
+A:visited {
+ color: #0000ee;
+ text-decoration: none;
+ white-space: pre;
+}
+
+A:active {
+ color: #0000ee;
+ text-decoration: none;
+ white-space: pre;
+}
diff --git a/src/docs/daemon.html b/src/docs/daemon.html
new file mode 100644
index 0000000..0474a0f
--- /dev/null
+++ b/src/docs/daemon.html
@@ -0,0 +1,261 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<HTML>
+ <HEAD>
+ <TITLE>Apache Daemon Specification - Version 1.0</TITLE>
+ <LINK REL="stylesheet" TYPE="text/css" HREF="daemon.css" TITLE="daemon">
+ <META HTTP-EQUIV="content-type" CONTENT="text/html; charset=ISO-8859-1">
+ </HEAD>
+ <BODY>
+
+ <H1>Apache Daemon Specification</H1>
+ <H4>Version 1.0</H4>
+
+ <P CLASS="note">
+ <strong>Abstract:</strong>
+ This document specifies the behavior and life cycle of an abstract
+ Java™ daemon, in relation to its native container. In addition
+ it defines a mechanism for controlling a daemon, and its interaction
+ with the native OS process in which its existance is confined.
+ </P>
+
+ <H2>Index</H2>
+ <OL>
+ <LI><A HREF="#1">Introduction</A>
+ <LI><A HREF="#2">Scope of this specification</A>
+ <LI><A HREF="#3">The Daemon interface and its life cycle</A>
+ <OL>
+ <LI><A HREF="#3A">Instantiation</A>
+ <LI><A HREF="#3B">Initialization</A>
+ <LI><A HREF="#3C">Startup</A>
+ <LI><A HREF="#3D">Stop</A>
+ <LI><A HREF="#3E">Destruction</A>
+ </OL>
+ </OL>
+
+ <A NAME="1"><H2>Introduction</H2></A>
+ <P>
+ Since 1994, the Java™ programming language evolved and became a
+ valid tool to develop, other than applets and client applications,
+ reliable and performant server applications. The major disadvantage of
+ the Java™ platform is that still today the only portable way to
+ start a Java™ applcation relies on a single point of entry: the
+ <CODE><EM CLASS="key">public static void</EM> main(<EM CLASS="ref">String</EM>[])</CODE>
+ method.
+ </P>
+ <P>
+ Having a single-point of entry is a valid solution for client
+ applications, where interactively a user can command to the application
+ to quit (which can terminate the Virtual Machine process at calling the
+ <CODE><EM CLASS="ref">System</EM>.exit(<EM CLASS="key">int</EM>)</CODE>
+ method), but in those cases where the application is not interactive
+ (server applications) there is currently no portable way to notify
+ the Virtual Machine of its imminent shutdown.
+ </P>
+ <P>
+ A server application written in Java might have to perform several tasks
+ before being able to shutdown the Virtual Machine process. For example
+ in the case of a Servlet container, before the VM process is shut down,
+ sessions might need to be serialized to disk, and web applications need
+ to be destroyed.
+ </P>
+ <P>
+ One common solution to this problem is to create (for example) a
+ <CODE><EM CLASS="ref">ServerSocket</EM></CODE> and wait for a particular
+ message to be issued. When the message is received, all operations
+ required to shut down the server applications are performed and at the
+ end the <CODE><EM CLASS="ref">System</EM>.exit</CODE> method is called
+ to terminate the Virtual Machine process. This method, however, implies
+ several disadvantages and risks: for example in case of a system-wide
+ shutdown, it might happen that the Virtual Machine process will be shut
+ down directly by the operating system, without notifying the running
+ server application. Or, for example, if an attacker finds out what is
+ the required message to send to the server, and discovers a way to send
+ this message to the running server application, he can easily interrupt
+ the operation of a server, bypassing all the security restrictions
+ implemented in the operating system.
+ </P>
+ <P>
+ Most multi-user operating systems already have a way in which server
+ applications are started and stopped, under Unix based operating systems
+ non interactive server applications are called <em>daemons</em> and are
+ controlled by the operating system with a set of specified
+ <em>signals</em>. Under Windows such programs are called <em>daemons</em>
+ and are controlled by appropriate calls to specific functions defined in
+ the application binary, but although the ways of dealing with the problem
+ are different, in both cases the operating system can notify a server
+ application of its imminent shutdown, and the application has the
+ ability to perform certain tasks before its process of execution is
+ destroyed.
+ </P>
+
+ <A NAME="2"><H2>Scope of this specification</H2></A>
+ <P>
+ The scope of this specification is to define an API in line with the
+ current Java™ Platform APIs to support an alternative invocation
+ mechanism which could be used instead of the above mentioned
+ <CODE><EM CLASS="key">public static void</EM> main(<EM CLASS="ref">String</EM>[])</CODE>
+ method. This specification cover the behavior and life cycle of what
+ we define as "Java ™ daemons", or, in other words,
+ non interactive Java™ applications.
+ </P>
+ <P>
+ This specification does not cover how the container of a Java™
+ daemon must be implemented, or how to build a native liaison between
+ the operating system and the <CODE><EM CLASS="ref">Daemon</EM></CODE>
+ interface, but defines the relation between the an operating system
+ process and the <CODE><EM CLASS="ref">Daemon</EM></CODE> implementation
+ life cycle. It should be trivial for implementors to build a native
+ liaison and container for Java™ daemons.
+ </P>
+ <P>
+ This specification, together with the related API documentation, can be
+ used by software deveopers to build portable non interactive applications
+ based on the Java™ platform.
+ </P>
+
+ <A NAME="3"><H2>The Daemon interface and its life cycle</H2></A>
+ <P>
+ The <CODE><EM CLASS="ref">Daemon</EM></CODE> interface (defined as
+ follows) is the main interface representing a Java™ daemon:
+ </P>
+<PRE>
+<EM CLASS="key">package</EM> org.apache.commons.daemon;
+
+<EM CLASS="key">public interface</EM> <EM CLASS="ref">Daemon</EM>
+<EM CLASS="key">extends</EM> <EM CLASS="ref">Runnable</EM> {
+
+ <EM CLASS="key">public void</EM> init(<EM CLASS="ref">DaemonContext</EM> context)
+ throws <EM CLASS="ref">Exception</EM>;
+
+ <EM CLASS="key">public void</EM> run();
+
+ <EM CLASS="key">public void</EM> die();
+
+ <EM CLASS="key">public void</EM> destroy();
+}</PRE>
+ <P>
+ A daemon is managed through a well defined life cycle that defines how
+ it is loaded, initialized, started, stopped and destroyed. This life
+ cycle is expressed in the API by the <CODE>init(...)</CODE>,
+ <CODE>run()</CODE>, <CODE>die()</CODE> and <CODE>destroy()</CODE> methods
+ of the <CODE><EM CLASS="ref">Daemon</EM></CODE> interface.
+ </P>
+
+ <A NAME="3A"><H3>Instantiation</H3></A>
+ <P>
+ The daemon container is responsible for instantiating daemons. Because
+ of this, concrete implementations of the <CODE><EM CLASS="ref">Daemon</EM></CODE>
+ interface must always expose a public void constructor, which will be
+ used by the daemon container to create instances of the class.
+ For example:
+ </P>
+
+<PRE>
+<EM CLASS="key">package</EM> mypackage;
+
+<EM CLASS="key">import</EM> org.apache.commons.daemon.*;
+
+
+<EM CLASS="key">public class</EM> <EM CLASS="ref">MyDaemon</EM>
+<EM CLASS="key">implements</EM> <EM CLASS="ref">Daemon</EM> {
+
+ <EM CLASS="com">/** This constructor must be here. */</EM>
+ <EM CLASS="key">public</EM> MyDaemon() {
+ super();
+ ...
+ }
+ ...
+}</PRE>
+ <P>
+ Once the Virtual Machine process is started in the underlying operating
+ system, and the Virtual Machine itself is created and configured, the
+ daemon container associated with its native liaison constructs a new
+ instance of the concrete class implementing the
+ <CODE><EM CLASS="ref">Daemon</EM></CODE> instance. It is not defined by
+ this specification how the instance is constructed, or how many instances
+ of one or more concrete daemons implementation can coexist in the same
+ Virtual Machine.
+ </P>
+ <P>
+ As a side note, in case of multiple daemons running within the scope
+ of the same virtual machine, developers should not rely on static
+ methods and variables for proper operation, as it is advisable for
+ security reasons to load each different daemon instance in a separate
+ class loader.
+ </P>
+
+ <A NAME="3B"><H3>Initialization</H3></A>
+ <P>
+ After the daemon instance has been constructed, the container must
+ initialize it before it can be started. Initialization is provided so
+ that a daemon can read persisten configuration data, access native
+ resources, and perform other one-time activities.
+ </P>
+ <P>
+ Under certain operating systems (typically Unix based operating systems),
+ and if the native liaison of the container supports and it is configured
+ accordingly, this method might be called with super-user privileges.
+ For example, within the scope of this method, it might be wise to create
+ all required <CODE><EM CLASS="ref">ServerSocket</EM></CODE> instances (as
+ under several operating systems this requires super-user privileges).
+ </P>
+ <P>
+ That said, it is very important that within the scope of this method
+ "untrusted" data cannot be processed (for example, starting
+ an acceptor thread on a <CODE><EM CLASS="ref">ServerSocket</EM></CODE>
+ which receives and processes data from unknown sources), as this would
+ serious security hazards.
+ </P>
+ <P>
+ The daemon container must guarantee that the <CODE>init(...)</CODE>
+ method is called at least once, and only once on an instance of a
+ daemon object, and that it will be called before any access to the
+ <CODE>run()</CODE>, <CODE>die()</CODE> or <CODE>destroy()</CODE>
+ methods.
+ </P>
+ <P>
+ During initialization, the daemon instance can throw any
+ <CODE><EM CLASS="ref">Exception</EM></CODE> preventing a the successful
+ completion of the <CODE>init(...)</CODE> method. In this case the daemon
+ instance must not be started, and the <CODE>destroy()</CODE> method must
+ not be called before the instance is released by the container to allow
+ garbage collecting.
+ </P>
+
+ <A NAME="3C"><H3>Startup</H3></A>
+ <P>
+ As the <CODE><EM CLASS="ref">Daemon</EM></CODE> interface extends the
+ <CODE><EM CLASS="ref">Runnable</EM></CODE> interface, to start the
+ operation of a daemon, the container calls the <CODE>run()</CODE> method
+ within the scope of a <CODE><EM CLASS="ref">Thread</EM></CODE>. A
+ daemon is said to be "running" until the thread
+ </P>
+
+
+
+ <HR>
+ <P CLASS="copyright">
+ Author Pier Fumagalli
+ <A HREF="mailto:pier.fumagalli at sun.com"><pier.fumagalli at sun.com></A>
+ <BR>
+ Copyright © 2001, The Apache Software Foundation
+ <A HREF="http://www.apache.org/"><http://www.apache.org/></A>
+ <BR>
+ All rights reserved.
+ </P>
+
+ <P CLASS="copyright">
+ Sun, Sun Microsystems, Solaris, and Java are trademarks or registered
+ trademarks of Sun Microsystems, Inc.
+ <A HREF="http://www.sun.com/"><http://www.sun.com/></A>
+ <BR>
+ UNIX® is a registered trademark in the United States and other
+ countries, exclusively licensed through X/Open Company, Ltd.
+ <A HREF="http://www.opengroup.org/"><http://www.opengroup.org/></A>
+ <BR>
+ Windows, WinNT and Win32 are registered trademark of Microsoft Corp.
+ <A HREF="http://www.microsoft.com/"><http://www.microsoft.com/></A>
+ </P>
+ </P>
+ </BODY>
+</HTML>
diff --git a/src/java/org/apache/commons/daemon/Daemon.java b/src/java/org/apache/commons/daemon/Daemon.java
new file mode 100644
index 0000000..79c2320
--- /dev/null
+++ b/src/java/org/apache/commons/daemon/Daemon.java
@@ -0,0 +1,144 @@
+/* ========================================================================= *
+ * *
+ * The Apache Software License, Version 1.1 *
+ * *
+ * Copyright (c) 2001 The Apache Software Foundation. *
+ * All rights reserved. *
+ * *
+ * ========================================================================= *
+ * *
+ * Redistribution and use in source and binary forms, with or without modi- *
+ * fication, are permitted provided that the following conditions are met: *
+ * *
+ * 1. Redistributions of source code must retain the above copyright notice *
+ * notice, this list of conditions and the following disclaimer. *
+ * *
+ * 2. Redistributions in binary form must reproduce the above copyright *
+ * notice, this list of conditions and the following disclaimer in the *
+ * documentation and/or other materials provided with the distribution. *
+ * *
+ * 3. The end-user documentation included with the redistribution, if any, *
+ * must include the following acknowlegement: *
+ * *
+ * "This product includes software developed by the Apache Software *
+ * Foundation <http://www.apache.org/>." *
+ * *
+ * Alternately, this acknowlegement may appear in the software itself, if *
+ * and wherever such third-party acknowlegements normally appear. *
+ * *
+ * 4. The names "The Jakarta Project", and "Apache Software Foundation" *
+ * must not be used to endorse or promote products derived from this *
+ * software without prior written permission. For written permission, *
+ * please contact <apache at apache.org>. *
+ * *
+ * 5. Products derived from this software may not be called "Apache" nor may *
+ * "Apache" appear in their names without prior written permission of the *
+ * Apache Software Foundation. *
+ * *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES *
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY *
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL *
+ * THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY *
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL *
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS *
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) *
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, *
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN *
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
+ * POSSIBILITY OF SUCH DAMAGE. *
+ * *
+ * ========================================================================= *
+ * *
+ * This software consists of voluntary contributions made by many indivi- *
+ * duals on behalf of the Apache Software Foundation. For more information *
+ * on the Apache Software Foundation, please see <http://www.apache.org/>. *
+ * *
+ * ========================================================================= */
+
+package org.apache.commons.daemon;
+
+/**
+ * This interface provides support for native daemon invocation. Using
+ * a platform dependant helper program classes that implement the
+ * <code>Daemon</code> interface can be initialized, started and
+ * stopped according to the convensions of the underlying operating
+ * system.
+ * <p>
+ * Implementors of this interface must also provide a public constructor
+ * with no arguments so that instances can be created in an automated
+ * fashion.
+ * </p>
+ * @author Pier Fumagalli
+ * @author Copyright © 2000-2001 <a href="http://www.apache.org/">The
+ * Apache Software Foundation</a>. All rights reserved.
+ * @version 1.0 <i>(CVS $Revision: 1.3 $)</i>
+ */
+public interface Daemon {
+
+ /**
+ * Initialize this <code>Daemon</code> instance.
+ * <p>
+ * This method gets called once the JVM process is created and the
+ * <code>Daemon</code> instance is created thru its empty public
+ * constructor.
+ * </p>
+ * <p>
+ * Under certain operating systems (typically Unix based operating
+ * systems) and if the native invocation framework is configured to do
+ * so, this method might be called with <i>super-user</i> privileges.
+ * </p>
+ * <p>
+ * For example, it might be wise to create <code>ServerSocket</code>
+ * instances within the scope of this method, and perform all operations
+ * requiring <i>super-user</i> privileges in the underlying operating
+ * system.
+ * </p>
+ * <p>
+ * Apart from set up and allocation of native resources, this method
+ * must not start the actual operation of the <code>Daemon</code> (such
+ * as starting threads calling the <code>ServerSocket.accept()</code>
+ * method) as this would impose some serious security hazards. The
+ * start of operation must be performed in the <code>start()</code>
+ * method.
+ * </p>
+ *
+ * @param context A <code>DaemonContext</code> object used to
+ * communicate with the container.
+ *
+ * @exception Exception Any exception preventing a successful
+ * initialization.
+ */
+ public void init(DaemonContext context)
+ throws Exception;
+
+ /**
+ * Start the operation of this <code>Daemon</code> instance. This
+ * method is to be invoked by the environment after the init()
+ * method has been successfully invoked and possibly the security
+ * level of the JVM has been dropped. <code>Implementors of this
+ * method are free to start any number of threads, but need to
+ * return control avfter having done that to enable invocation of
+ * the stop()-method.
+ */
+ public void start()
+ throws Exception;
+
+ /**
+ * Stop the operation of this <code>Daemon</code> instance. Note
+ * that the proper place to free any allocated resources such as
+ * sockets or file descriptors is in the destroy method, as the
+ * container may restart the Daemon by calling start() after
+ * stop().
+ */
+ public void stop()
+ throws Exception;
+
+ /**
+ * Free any resources allocated by this daemon such as file
+ * descriptors or sockets. This method gets called by the container
+ * after stop() has been called, before the JVM exits. The Daemon
+ * can not be restarted after this method has been called without a
+ * new call to the init() method.
+ */
+ public void destroy();
+}
diff --git a/src/java/org/apache/commons/daemon/DaemonContext.java b/src/java/org/apache/commons/daemon/DaemonContext.java
new file mode 100644
index 0000000..2d5e60e
--- /dev/null
+++ b/src/java/org/apache/commons/daemon/DaemonContext.java
@@ -0,0 +1,87 @@
+/* ========================================================================= *
+ * *
+ * The Apache Software License, Version 1.1 *
+ * *
+ * Copyright (c) 2001 The Apache Software Foundation. *
+ * All rights reserved. *
+ * *
+ * ========================================================================= *
+ * *
+ * Redistribution and use in source and binary forms, with or without modi- *
+ * fication, are permitted provided that the following conditions are met: *
+ * *
+ * 1. Redistributions of source code must retain the above copyright notice *
+ * notice, this list of conditions and the following disclaimer. *
+ * *
+ * 2. Redistributions in binary form must reproduce the above copyright *
+ * notice, this list of conditions and the following disclaimer in the *
+ * documentation and/or other materials provided with the distribution. *
+ * *
+ * 3. The end-user documentation included with the redistribution, if any, *
+ * must include the following acknowlegement: *
+ * *
+ * "This product includes software developed by the Apache Software *
+ * Foundation <http://www.apache.org/>." *
+ * *
+ * Alternately, this acknowlegement may appear in the software itself, if *
+ * and wherever such third-party acknowlegements normally appear. *
+ * *
+ * 4. The names "The Jakarta Project", and "Apache Software Foundation" *
+ * must not be used to endorse or promote products derived from this *
+ * software without prior written permission. For written permission, *
+ * please contact <apache at apache.org>. *
+ * *
+ * 5. Products derived from this software may not be called "Apache" nor may *
+ * "Apache" appear in their names without prior written permission of the *
+ * Apache Software Foundation. *
+ * *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES *
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY *
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL *
+ * THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY *
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL *
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS *
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) *
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, *
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN *
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
+ * POSSIBILITY OF SUCH DAMAGE. *
+ * *
+ * ========================================================================= *
+ * *
+ * This software consists of voluntary contributions made by many indivi- *
+ * duals on behalf of the Apache Software Foundation. For more information *
+ * on the Apache Software Foundation, please see <http://www.apache.org/>. *
+ * *
+ * ========================================================================= */
+
+package org.apache.commons.daemon;
+
+
+/**
+ * Defines a set of methods that a Daemon instance can use to
+ * communicate with the Daemon container.
+ *
+ * @author Pier Fumagalli
+ * @author Copyright © 2000-2001 <a href="http://www.apache.org/">The
+ * Apache Software Foundation</a>. All rights reserved.
+ * @version 1.0 <i>(CVS $Revision: 1.3 $)</i>
+ */
+public interface DaemonContext {
+
+ /**
+ * Returns <code>DaemonController</code> object that can be used
+ * to control the <code>Daemon</code> instance that this
+ * <code>DaemonContext</code> is passed to.
+ */
+ public DaemonController getController();
+
+ /**
+ * Returns an array of <code>String</code> arguments supplied by
+ * the environment. corresponding to the array of arguments given
+ * in the <code>public static void main()</code> method used as an
+ * entry point to most other java programs.
+ */
+ public String[] getArguments();
+
+}
diff --git a/src/java/org/apache/commons/daemon/DaemonController.java b/src/java/org/apache/commons/daemon/DaemonController.java
new file mode 100644
index 0000000..2ef2c90
--- /dev/null
+++ b/src/java/org/apache/commons/daemon/DaemonController.java
@@ -0,0 +1,106 @@
+/* ========================================================================= *
+ * *
+ * The Apache Software License, Version 1.1 *
+ * *
+ * Copyright (c) 2001 The Apache Software Foundation. *
+ * All rights reserved. *
+ * *
+ * ========================================================================= *
+ * *
+ * Redistribution and use in source and binary forms, with or without modi- *
+ * fication, are permitted provided that the following conditions are met: *
+ * *
+ * 1. Redistributions of source code must retain the above copyright notice *
+ * notice, this list of conditions and the following disclaimer. *
+ * *
+ * 2. Redistributions in binary form must reproduce the above copyright *
+ * notice, this list of conditions and the following disclaimer in the *
+ * documentation and/or other materials provided with the distribution. *
+ * *
+ * 3. The end-user documentation included with the redistribution, if any, *
+ * must include the following acknowlegement: *
+ * *
+ * "This product includes software developed by the Apache Software *
+ * Foundation <http://www.apache.org/>." *
+ * *
+ * Alternately, this acknowlegement may appear in the software itself, if *
+ * and wherever such third-party acknowlegements normally appear. *
+ * *
+ * 4. The names "The Jakarta Project", and "Apache Software Foundation" *
+ * must not be used to endorse or promote products derived from this *
+ * software without prior written permission. For written permission, *
+ * please contact <apache at apache.org>. *
+ * *
+ * 5. Products derived from this software may not be called "Apache" nor may *
+ * "Apache" appear in their names without prior written permission of the *
+ * Apache Software Foundation. *
+ * *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES *
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY *
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL *
+ * THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY *
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL *
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS *
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) *
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, *
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN *
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
+ * POSSIBILITY OF SUCH DAMAGE. *
+ * *
+ * ========================================================================= *
+ * *
+ * This software consists of voluntary contributions made by many indivi- *
+ * duals on behalf of the Apache Software Foundation. For more information *
+ * on the Apache Software Foundation, please see <http://www.apache.org/>. *
+ * *
+ * ========================================================================= */
+
+package org.apache.commons.daemon;
+
+
+/**
+ *
+ * @author Pier Fumagalli
+ * @author Copyright © 2000-2001 <a href="http://www.apache.org/">The
+ * Apache Software Foundation</a>. All rights reserved.
+ * @version 1.0 <i>(CVS $Revision: 1.2 $)</i>
+ */
+public interface DaemonController {
+
+ /**
+ *
+ */
+ public void shutdown()
+ throws IllegalStateException;
+
+ /**
+ *
+ */
+ public void reload()
+ throws IllegalStateException;
+
+ /**
+ *
+ */
+ public void fail()
+ throws IllegalStateException;
+
+ /**
+ *
+ */
+ public void fail(String message)
+ throws IllegalStateException;
+
+ /**
+ *
+ */
+ public void fail(Exception exception)
+ throws IllegalStateException;
+
+ /**
+ *
+ */
+ public void fail(String message, Exception exception)
+ throws IllegalStateException;
+
+}
diff --git a/src/java/org/apache/commons/daemon/DaemonListener.java b/src/java/org/apache/commons/daemon/DaemonListener.java
new file mode 100644
index 0000000..df64f08
--- /dev/null
+++ b/src/java/org/apache/commons/daemon/DaemonListener.java
@@ -0,0 +1,65 @@
+/* ========================================================================= *
+ * *
+ * The Apache Software License, Version 1.1 *
+ * *
+ * Copyright (c) 2001 The Apache Software Foundation. *
+ * All rights reserved. *
+ * *
+ * ========================================================================= *
+ * *
+ * Redistribution and use in source and binary forms, with or without modi- *
+ * fication, are permitted provided that the following conditions are met: *
+ * *
+ * 1. Redistributions of source code must retain the above copyright notice *
+ * notice, this list of conditions and the following disclaimer. *
+ * *
+ * 2. Redistributions in binary form must reproduce the above copyright *
+ * notice, this list of conditions and the following disclaimer in the *
+ * documentation and/or other materials provided with the distribution. *
+ * *
+ * 3. The end-user documentation included with the redistribution, if any, *
+ * must include the following acknowlegement: *
+ * *
+ * "This product includes software developed by the Apache Software *
+ * Foundation <http://www.apache.org/>." *
+ * *
+ * Alternately, this acknowlegement may appear in the software itself, if *
+ * and wherever such third-party acknowlegements normally appear. *
+ * *
+ * 4. The names "The Jakarta Project", and "Apache Software Foundation" *
+ * must not be used to endorse or promote products derived from this *
+ * software without prior written permission. For written permission, *
+ * please contact <apache at apache.org>. *
+ * *
+ * 5. Products derived from this software may not be called "Apache" nor may *
+ * "Apache" appear in their names without prior written permission of the *
+ * Apache Software Foundation. *
+ * *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES *
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY *
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL *
+ * THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY *
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL *
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS *
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) *
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, *
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN *
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
+ * POSSIBILITY OF SUCH DAMAGE. *
+ * *
+ * ========================================================================= *
+ * *
+ * This software consists of voluntary contributions made by many indivi- *
+ * duals on behalf of the Apache Software Foundation. For more information *
+ * on the Apache Software Foundation, please see <http://www.apache.org/>. *
+ * *
+ * ========================================================================= */
+
+package org.apache.commons.daemon;
+
+import java.util.EventListener;
+
+public interface DaemonListener extends EventListener {
+
+}
+
diff --git a/src/java/org/apache/commons/daemon/DaemonPermission.java b/src/java/org/apache/commons/daemon/DaemonPermission.java
new file mode 100644
index 0000000..3e84926
--- /dev/null
+++ b/src/java/org/apache/commons/daemon/DaemonPermission.java
@@ -0,0 +1,427 @@
+/* ========================================================================= *
+ * *
+ * The Apache Software License, Version 1.1 *
+ * *
+ * Copyright (c) 2001 The Apache Software Foundation. *
+ * All rights reserved. *
+ * *
+ * ========================================================================= *
+ * *
+ * Redistribution and use in source and binary forms, with or without modi- *
+ * fication, are permitted provided that the following conditions are met: *
+ * *
+ * 1. Redistributions of source code must retain the above copyright notice *
+ * notice, this list of conditions and the following disclaimer. *
+ * *
+ * 2. Redistributions in binary form must reproduce the above copyright *
+ * notice, this list of conditions and the following disclaimer in the *
+ * documentation and/or other materials provided with the distribution. *
+ * *
+ * 3. The end-user documentation included with the redistribution, if any, *
+ * must include the following acknowlegement: *
+ * *
+ * "This product includes software developed by the Apache Software *
+ * Foundation <http://www.apache.org/>." *
+ * *
+ * Alternately, this acknowlegement may appear in the software itself, if *
+ * and wherever such third-party acknowlegements normally appear. *
+ * *
+ * 4. The names "The Jakarta Project", and "Apache Software Foundation" *
+ * must not be used to endorse or promote products derived from this *
+ * software without prior written permission. For written permission, *
+ * please contact <apache at apache.org>. *
+ * *
+ * 5. Products derived from this software may not be called "Apache" nor may *
+ * "Apache" appear in their names without prior written permission of the *
+ * Apache Software Foundation. *
+ * *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES *
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY *
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL *
+ * THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY *
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL *
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS *
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) *
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, *
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN *
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
+ * POSSIBILITY OF SUCH DAMAGE. *
+ * *
+ * ========================================================================= *
+ * *
+ * This software consists of voluntary contributions made by many indivi- *
+ * duals on behalf of the Apache Software Foundation. For more information *
+ * on the Apache Software Foundation, please see <http://www.apache.org/>. *
+ * *
+ * ========================================================================= */
+
+package org.apache.commons.daemon;
+
+import java.security.Permission;
+import java.util.StringTokenizer;
+
+/**
+ * This class represents the permissions to control and query the status of
+ * a <code>Daemon</code>. A <code>DaemonPermission</code> consists of a
+ * target name and a list of actions associated with it.
+ * <p>
+ * In this specification version the only available target name for this
+ * permission is "control", but further releases may add more target
+ * names to fine-tune the access that needs to be granted to the caller.
+ * </p>
+ * <p>
+ * Actions are defined by a string of comma-separated values, as shown in the
+ * table below. The empty string implies no permission at all, while the
+ * special "*" value implies all permissions for the given
+ * name:
+ * </p>
+ * <p>
+ * <table width="100%" border="1">
+ * <tr>
+ * <th>Target"Name</th>
+ * <th>Action</th>
+ * <th>Description</th>
+ * </tr>
+ * <tr>
+ * <td rowspan="5">"control"</td>
+ * <td>"start"</td>
+ * <td>
+ * The permission to call the <code>start()</code> method in an instance
+ * of a <code>DaemonController</code> interface.
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>"stop"</td>
+ * <td>
+ * The permission to call the <code>stop()</code> method in an instance
+ * of a <code>DaemonController</code> interface.
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>"shutdown"</td>
+ * <td>
+ * The permission to call the <code>shutdown()</code> method in an instance
+ * of a <code>DaemonController</code> interface.
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>"reload"</td>
+ * <td>
+ * The permission to call the <code>reload()</code> method in an instance
+ * of a <code>DaemonController</code> interface.
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>"*"</td>
+ * <td>
+ * The special wildcard action implies all above-mentioned action. This is
+ * equal to construct a permission with the "start, stop, shutdown,
+ * reload" list of actions.
+ * </td>
+ * </tr>
+ * </table>
+ * </p>
+ *
+ * @author Pier Fumagalli
+ * @author Copyright © 2000-2001 <a href="http://www.apache.org/">The
+ * Apache Software Foundation</a>. All rights reserved.
+ * @version 1.0 <i>(CVS $Revision: 1.2 $)</i>
+ */
+public final class DaemonPermission extends Permission {
+
+ /* ==================================================================== */
+ /* Constants. */
+
+ /**
+ * The target name when associated with control actions
+ * ("control").
+ */
+ protected static final String CONTROL = "control";
+
+ /**
+ * The target type when associated with control actions.
+ */
+ protected static final int TYPE_CONTROL = 1;
+
+ /**
+ * The action name associated with the permission to call the
+ * <code>DaemonController.start()</code> method.
+ */
+ protected static final String CONTROL_START = "start";
+
+ /**
+ * The action name associated with the permission to call the
+ * <code>DaemonController.stop()</code> method.
+ */
+ protected static final String CONTROL_STOP = "stop";
+
+ /**
+ * The action name associated with the permission to call the
+ * <code>DaemonController.shutdown()</code> method.
+ */
+ protected static final String CONTROL_SHUTDOWN = "shutdown";
+
+ /**
+ * The action name associated with the permission to call the
+ * <code>DaemonController.reload()</code> method.
+ */
+ protected static final String CONTROL_RELOAD = "reload";
+
+ /**
+ * The action mask associated with the permission to call the
+ * <code>DaemonController.start()</code> method.
+ */
+ protected static final int MASK_CONTROL_START = 0x01;
+
+ /**
+ * The action mask associated with the permission to call the
+ * <code>DaemonController.stop()</code> method.
+ */
+ protected static final int MASK_CONTROL_STOP = 0x02;
+
+ /**
+ * The action mask associated with the permission to call the
+ * <code>DaemonController.shutdown()</code> method.
+ */
+ protected static final int MASK_CONTROL_SHUTDOWN = 0x04;
+
+ /**
+ * The action mask associated with the permission to call the
+ * <code>DaemonController.reload()</code> method.
+ */
+ protected static final int MASK_CONTROL_RELOAD = 0x08;
+
+ /**
+ * The "wildcard" action implying all actions for the given
+ * target name.
+ */
+ protected static final String WILDCARD = "*";
+
+ /* ==================================================================== */
+ /* Instance variables */
+
+ /** The type of this permission object. */
+ private transient int type = 0;
+ /** The permission mask associated with this permission object. */
+ private transient int mask = 0;
+ /** The String representation of this permission object. */
+ private transient String desc = null;
+
+ /* ==================================================================== */
+ /* Constructors */
+
+ /**
+ * Create a new <code>DaemonPermission</code> instance with a specified
+ * permission name.
+ * <p>
+ * This constructor will create a new <code>DaemonPermission</code>
+ * instance that <b>will not</b> grant any permission to the caller.
+ *
+ * @param target The target name of this permission.
+ * @exception IllegalArgumentException If the specified target name is not
+ * supported.
+ */
+ public DaemonPermission (String target)
+ throws IllegalArgumentException {
+ // Setup the target name of this permission object.
+ super(target);
+
+ // Check if the permission target name was specified
+ if (target==null)
+ throw new IllegalArgumentException("Null permission name");
+
+ // Check if this is a "control" permission and set up accordingly.
+ if (CONTROL.equalsIgnoreCase(target)) {
+ type=TYPE_CONTROL;
+ return;
+ }
+
+ // If we got here, we have an invalid permission name.
+ throw new IllegalArgumentException("Invalid permission name \""+
+ target+"\" specified");
+ }
+
+ /**
+ * Create a new <code>DaemonPermission</code> instance with a specified
+ * permission name and a specified list of actions.
+ * <p>
+ * </p>
+ *
+ * @param target The target name of this permission.
+ * @param actions The list of actions permitted by this permission.
+ * @exception IllegalArgumentException If the specified target name is not
+ * supported, or the specified list of actions includes an
+ * invalid value.
+ */
+ public DaemonPermission(String target, String actions)
+ throws IllegalArgumentException {
+ // Setup this instance's target name.
+ this(target);
+
+ // Create the appropriate mask if this is a control permission.
+ if (this.type==TYPE_CONTROL) {
+ this.mask=this.createControlMask(actions);
+ return;
+ }
+ }
+
+ /* ==================================================================== */
+ /* Public methods */
+
+ /**
+ * Return the list of actions permitted by this instance of
+ * <code>DaemonPermission</code> in its canonical form.
+ *
+ * @return The canonicalized list of actions.
+ */
+ public String getActions() {
+ if (this.type==TYPE_CONTROL) {
+ return(this.createControlActions(this.mask));
+ }
+ return("");
+ }
+
+ /**
+ * Return the hash code for this <code>DaemonPermission</code> instance.
+ *
+ * @return An hash code value.
+ */
+ public int hashCode() {
+ this.setupDescription();
+ return(this.desc.hashCode());
+ }
+
+ /**
+ * Check if a specified object equals <code>DaemonPermission</code>.
+ *
+ * @return <b>true</b> or <b>false</b> wether the specified object equals
+ * this <code>DaemonPermission</code> instance or not.
+ */
+ public boolean equals(Object object) {
+ if (object == this) return(true);
+
+ if (!(object instanceof DaemonPermission)) return false;
+
+ DaemonPermission that = (DaemonPermission)object;
+
+ if (this.type!=that.type) return(false);
+ return(this.mask==that.mask);
+ }
+
+ /**
+ * Check if this <code>DaemonPermission</code> implies another
+ * <code>Permission</code>.
+ *
+ * @return <b>true</b> or <b>false</b> wether the specified permission
+ * is implied by this <code>DaemonPermission</code> instance or
+ * not.
+ */
+ public boolean implies(Permission permission) {
+ if (permission == this) return(true);
+
+ if (!(permission instanceof DaemonPermission)) return false;
+
+ DaemonPermission that = (DaemonPermission)permission;
+
+ if (this.type!=that.type) return(false);
+ return((this.mask&that.mask)==that.mask);
+ }
+
+ /**
+ * Return a <code>String</code> representation of this instance.
+ *
+ * @return A <code>String</code> representing this
+ * <code>DaemonPermission</code> instance.
+ */
+ public String toString() {
+ this.setupDescription();
+ return(new String(this.desc));
+ }
+
+ /* ==================================================================== */
+ /* Private methods */
+
+ /** Create a String description for this permission instance. */
+ private void setupDescription() {
+ if (this.desc!=null) return;
+
+ StringBuffer buf=new StringBuffer();
+ buf.append(this.getClass().getName());
+ buf.append('[');
+ switch (this.type) {
+ case (TYPE_CONTROL): {
+ buf.append(CONTROL);
+ break;
+ }
+ default: {
+ buf.append("UNKNOWN");
+ break;
+ }
+ }
+ buf.append(':');
+ buf.append(this.getActions());
+ buf.append(']');
+
+ this.desc=buf.toString();
+ }
+
+ /** Create a permission mask for a given control actions string. */
+ private int createControlMask(String actions)
+ throws IllegalArgumentException {
+ if (actions==null) return(0);
+
+ int mask=0;
+ StringTokenizer tok=new StringTokenizer(actions,",",false);
+ while (tok.hasMoreTokens()) {
+ String val=tok.nextToken().trim();
+
+ if (WILDCARD.equals(val)) {
+ return(MASK_CONTROL_START|MASK_CONTROL_STOP|
+ MASK_CONTROL_SHUTDOWN|MASK_CONTROL_RELOAD);
+ } else if (CONTROL_START.equalsIgnoreCase(val)) {
+ mask=mask|MASK_CONTROL_START;
+ } else if (CONTROL_STOP.equalsIgnoreCase(val)) {
+ mask=mask|MASK_CONTROL_STOP;
+ } else if (CONTROL_SHUTDOWN.equalsIgnoreCase(val)) {
+ mask=mask|MASK_CONTROL_SHUTDOWN;
+ } else if (CONTROL_RELOAD.equalsIgnoreCase(val)) {
+ mask=mask|MASK_CONTROL_RELOAD;
+ } else {
+ throw new IllegalArgumentException("Invalid action name \""+
+ val+"\" specified");
+ }
+ }
+ return(mask);
+ }
+
+ /** Create a actions list for a given control permission mask. */
+ private String createControlActions(int mask) {
+ StringBuffer buf=new StringBuffer();
+ boolean sep=false;
+
+ if ((mask&MASK_CONTROL_START)==MASK_CONTROL_START) {
+ sep=true;
+ buf.append(CONTROL_START);
+ }
+
+ if ((mask&MASK_CONTROL_STOP)==MASK_CONTROL_STOP) {
+ if (sep) buf.append(",");
+ else sep=true;
+ buf.append(CONTROL_STOP);
+ }
+
+ if ((mask&MASK_CONTROL_SHUTDOWN)==MASK_CONTROL_SHUTDOWN) {
+ if (sep) buf.append(",");
+ else sep=true;
+ buf.append(CONTROL_SHUTDOWN);
+ }
+
+ if ((mask&MASK_CONTROL_RELOAD)==MASK_CONTROL_RELOAD) {
+ if (sep) buf.append(",");
+ else sep=true;
+ buf.append(CONTROL_RELOAD);
+ }
+
+ return buf.toString();
+ }
+}
diff --git a/src/java/org/apache/commons/daemon/support/DaemonLoader.java b/src/java/org/apache/commons/daemon/support/DaemonLoader.java
new file mode 100644
index 0000000..0ffccce
--- /dev/null
+++ b/src/java/org/apache/commons/daemon/support/DaemonLoader.java
@@ -0,0 +1,362 @@
+/* ========================================================================= *
+ * *
+ * The Apache Software License, Version 1.1 *
+ * *
+ * Copyright (c) 1999-2003 The Apache Software Foundation. *
+ * All rights reserved. *
+ * *
+ * ========================================================================= *
+ * *
+ * Redistribution and use in source and binary forms, with or without modi- *
+ * fication, are permitted provided that the following conditions are met: *
+ * *
+ * 1. Redistributions of source code must retain the above copyright notice *
+ * notice, this list of conditions and the following disclaimer. *
+ * *
+ * 2. Redistributions in binary form must reproduce the above copyright *
+ * notice, this list of conditions and the following disclaimer in the *
+ * documentation and/or other materials provided with the distribution. *
+ * *
+ * 3. The end-user documentation included with the redistribution, if any, *
+ * must include the following acknowlegement: *
+ * *
+ * "This product includes software developed by the Apache Software *
+ * Foundation <http://www.apache.org/>." *
+ * *
+ * Alternately, this acknowlegement may appear in the software itself, if *
+ * and wherever such third-party acknowlegements normally appear. *
+ * *
+ * 4. The names "The Jakarta Project", "WebApp", and "Apache Software *
+ * Foundation" must not be used to endorse or promote products derived *
+ * from this software without prior written permission. For written *
+ * permission, please contact <apache at apache.org>. *
+ * *
+ * 5. Products derived from this software may not be called "Apache" nor may *
+ * "Apache" appear in their names without prior written permission of the *
+ * Apache Software Foundation. *
+ * *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES *
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY *
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL *
+ * THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY *
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL *
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS *
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) *
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, *
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN *
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
+ * POSSIBILITY OF SUCH DAMAGE. *
+ * *
+ * ========================================================================= *
+ * *
+ * This software consists of voluntary contributions made by many indivi- *
+ * duals on behalf of the Apache Software Foundation. For more information *
+ * on the Apache Software Foundation, please see <http://www.apache.org/>. *
+ * *
+ * ========================================================================= */
+
+/* @version $Id: DaemonLoader.java,v 1.3 2003/09/27 16:49:13 jfclere Exp $ */
+
+package org.apache.commons.daemon.support;
+
+import org.apache.commons.daemon.Daemon;
+import org.apache.commons.daemon.DaemonContext;
+import org.apache.commons.daemon.DaemonController;
+
+import java.lang.reflect.Method;
+
+public final class DaemonLoader {
+
+ private static Controller controller = null;
+ private static Context context = null;
+ private static Object daemon = null;
+ /* Methods to call */
+ private static Method init = null;
+ private static Method start = null;
+ private static Method stop = null;
+ private static Method destroy = null;
+
+ public static void version() {
+ System.err.println("java version \""+
+ System.getProperty("java.version")+
+ "\"");
+ System.err.println(System.getProperty("java.runtime.name")+
+ " (build "+
+ System.getProperty("java.runtime.version")+
+ ")");
+ System.err.println(System.getProperty("java.vm.name")+
+ " (build "+
+ System.getProperty("java.vm.version")+
+ ", "+
+ System.getProperty("java.vm.info")+
+ ")");
+ }
+
+ public static boolean check(String cn) {
+ try {
+ /* Check the class name */
+ if (cn==null)
+ throw new NullPointerException("Null class name specified");
+
+ /* Get the ClassLoader loading this class */
+ ClassLoader cl=DaemonLoader.class.getClassLoader();
+ if (cl==null) {
+ System.err.println("Cannot retrieve ClassLoader instance");
+ return(false);
+ }
+
+ /* Find the required class */
+ Class c=cl.loadClass(cn);
+
+ /* This should _never_ happen, but doublechecking doesn't harm */
+ if (c==null) throw new ClassNotFoundException(cn);
+
+ /* Create a new instance of the daemon */
+ Object s=c.newInstance();
+
+ } catch (Throwable t) {
+ /* In case we encounter ANY error, we dump the stack trace and
+ return false (load, start and stop won't be called). */
+ t.printStackTrace(System.err);
+ return(false);
+ }
+ /* The class was loaded and instantiated correctly, we can return */
+ return(true);
+ }
+
+ public static boolean load(String cn, String ar[]) {
+ try {
+ /* Make sure any previous instance is garbage collected */
+ System.gc();
+
+ /* Check if the underlying libray supplied a valid list of
+ arguments */
+ if (ar==null) ar=new String[0];
+
+ /* Check the class name */
+ if (cn==null)
+ throw new NullPointerException("Null class name specified");
+
+ /* Get the ClassLoader loading this class */
+ ClassLoader cl=DaemonLoader.class.getClassLoader();
+ if (cl==null) {
+ System.err.println("Cannot retrieve ClassLoader instance");
+ return(false);
+ }
+
+ /* Find the required class */
+ Class c=cl.loadClass(cn);
+
+ /* This should _never_ happen, but doublechecking doesn't harm */
+ if (c==null) throw new ClassNotFoundException(cn);
+
+ /* Check interface */
+ Class[] interf = c.getInterfaces();
+ boolean isdaemon = false;
+ if ( interf != null ) {
+ for(int i=0;i<interf.length;i++) {
+ if (interf[i].getName().equals("org.apache.commons.daemon.Daemon"))
+ isdaemon = true;
+ }
+ }
+ /* Check methods */
+ Class[] myclass = new Class[1];
+ if (isdaemon) {
+ myclass[0] = DaemonContext.class;
+ } else {
+ myclass[0] = ar.getClass();
+ }
+
+ init = c.getMethod("init",myclass);
+
+ myclass = null;
+ start = c.getMethod("start",myclass);
+
+ stop = c.getMethod("stop",myclass);
+
+ destroy = c.getMethod("destroy",myclass);
+
+ /* Create a new instance of the daemon */
+ daemon=c.newInstance();
+
+ if (isdaemon) {
+ /* Create a new controller instance */
+ controller=new Controller();
+
+ /* Set the availability flag in the controller */
+ controller.setAvailable(false);
+
+ /* Create context */
+ context = new Context();
+ context.setArguments(ar);
+ context.setController(controller);
+
+ /* Now we want to call the init method in the class */
+ Object arg[] = new Object[1];
+ arg[0] = context;
+ init.invoke(daemon,arg);
+ } else {
+ Object arg[] = new Object[1];
+ arg[0] = ar;
+ init.invoke(daemon,arg);
+ }
+
+ } catch (Throwable t) {
+ /* In case we encounter ANY error, we dump the stack trace and
+ return false (load, start and stop won't be called). */
+ t.printStackTrace(System.err);
+ return(false);
+ }
+ /* The class was loaded and instantiated correctly, we can return */
+ return(true);
+ }
+
+ public static boolean start() {
+ try {
+ /* Attempt to start the daemon */
+ Object arg[] = null;
+ start.invoke(daemon,arg);
+
+ /* Set the availability flag in the controller */
+ if (controller != null)
+ controller.setAvailable(true);
+
+ } catch (Throwable t) {
+ /* In case we encounter ANY error, we dump the stack trace and
+ return false (load, start and stop won't be called). */
+ t.printStackTrace(System.err);
+ return(false);
+ }
+ return(true);
+ }
+
+ public static boolean stop() {
+ try {
+ /* Set the availability flag in the controller */
+ if (controller != null)
+ controller.setAvailable(false);
+
+ /* Attempt to stop the daemon */
+ Object arg[] = null;
+ stop.invoke(daemon,arg);
+
+ /* Run garbage collector */
+ System.gc();
+
+ } catch (Throwable t) {
+ /* In case we encounter ANY error, we dump the stack trace and
+ return false (load, start and stop won't be called). */
+ t.printStackTrace(System.err);
+ return(false);
+ }
+ return(true);
+ }
+
+ public static boolean destroy() {
+ try {
+ /* Attempt to stop the daemon */
+ Object arg[] = null;
+ destroy.invoke(daemon,arg);
+
+ /* Run garbage collector */
+ daemon=null;
+ controller=null;
+ System.gc();
+
+ } catch (Throwable t) {
+ /* In case we encounter ANY error, we dump the stack trace and
+ return false (load, start and stop won't be called). */
+ t.printStackTrace(System.err);
+ return(false);
+ }
+ return(true);
+ }
+
+ private static native void shutdown(boolean reload);
+
+ public static class Controller implements DaemonController {
+
+ boolean available=false;
+
+ private Controller() {
+ super();
+ this.setAvailable(false);
+ }
+
+ private boolean isAvailable() {
+ synchronized (this) {
+ return(this.available);
+ }
+ }
+
+ private void setAvailable(boolean available) {
+ synchronized (this) {
+ this.available=available;
+ }
+ }
+
+ public void shutdown() throws IllegalStateException {
+ synchronized (this) {
+ if (!this.isAvailable()) {
+ throw new IllegalStateException();
+ } else {
+ this.setAvailable(false);
+ DaemonLoader.shutdown(false);
+ }
+ }
+ }
+
+ public void reload() throws IllegalStateException {
+ synchronized (this) {
+ if (!this.isAvailable()) {
+ throw new IllegalStateException();
+ } else {
+ this.setAvailable(false);
+ DaemonLoader.shutdown(true);
+ }
+ }
+ }
+
+ public void fail()
+ throws IllegalStateException {
+ }
+
+ public void fail(String message)
+ throws IllegalStateException {
+ }
+
+ public void fail(Exception exception)
+ throws IllegalStateException {
+ }
+
+ public void fail(String message, Exception exception)
+ throws IllegalStateException {
+ }
+
+ }
+
+ public static class Context implements DaemonContext {
+
+ DaemonController controller = null;
+
+ String[] args = null;
+
+ public DaemonController getController() {
+ return controller;
+ }
+
+ public void setController(DaemonController controller) {
+ this.controller = controller;
+ }
+
+ public String[] getArguments() {
+ return args;
+ }
+
+ public void setArguments(String[] args) {
+ this.args = args;
+ }
+
+ }
+
+}
diff --git a/src/media/logo.xcf b/src/media/logo.xcf
new file mode 100644
index 0000000..a19d1c9
Binary files /dev/null and b/src/media/logo.xcf differ
diff --git a/src/native/nt/Makefile b/src/native/nt/Makefile
new file mode 100644
index 0000000..229d5f9
--- /dev/null
+++ b/src/native/nt/Makefile
@@ -0,0 +1,3 @@
+all:
+ (cd service; make)
+ (cd moni; make)
diff --git a/src/native/nt/README b/src/native/nt/README
new file mode 100644
index 0000000..00ef5a7
--- /dev/null
+++ b/src/native/nt/README
@@ -0,0 +1,62 @@
+To build the service utilities for windows you will need:
+- MS Visual C++ (I have used version 5.0).
+- CYGWIN to build the jsvc.exe.
+- A Java Platform 2 compliant SDK to run the service.
+
+Structure of the utilies:
+- bin: exe files.
+- executables/vdmoniadm: project files for the desktop program.
+- executables/vdmonisvc: project files for the sevice wrapper.
+- lib: contains the common include file.
+- moni: contains sources of the vdmoniadm and vdmonisvc.
+- service: contains the sources and the project for the test installer.
+- signals: contains the kill() emulation logic.
+- supcalls_nt: contains the environment emulation logic.
+
+How to use it:
+1 - Build the jsvc.exe (See jakarta-tomcat-4.0/service).
+ It produces:
+ - service.jar
+ - jsvc.exe
+
+2- Create the following directories:
+ c:\home\jakarta\bin
+ c:\home\jakarta\lib
+
+3 - Copy
+ From jakarta-tomcat-4.0/service:
+ service.jar to lib
+ jsvc.exe to bin
+ From winnt:
+ INSTSVC.exe to bin
+ vdmoniadm.exe to bin
+ vdmonisvc to bin.
+
+4 - In a MSDOS windows run INSTSVC
+ It creates all informations to start the service.
+ The service is not started automaticly use control_panel+service and
+ and make it automatic after testing it starts and stops correctly.
+
+ It creates the registry values needed for the environment to start jsvc.exe
+ JAKARTA_HOME
+ CYGWIN (You have to set it to your cygwin directory home).
+ JAVA_HOME (You have to set it to your JAVA_HOME directory).
+ HOSTNAME (not yet used)
+ HOSTPORT (not yet used)
+ I use regedit to modify these values.
+
+5 - Using the explorer go to profiles/allusers/program/startup and add a link
+ to vdmoniadm.exe.
+
+6 - Reboot the machine and logon.
+ You should see a "nice" icon in the System Task-bar indicating that the
+ Java service is running. A right click on the icon calls a small menu.
+ Restart: (not yet implemented).
+ Configure: (not yet implemented).
+ Stop: Stops the java service.
+
+It is still a work in progress and blabla...
+
+Have fun...
+
+ Jean-Frederic <jfrederic.clere AT fujitsu-siemens.com>
diff --git a/src/native/nt/executables/vdmoniadm/icon1.ico b/src/native/nt/executables/vdmoniadm/icon1.ico
new file mode 100644
index 0000000..a42536d
Binary files /dev/null and b/src/native/nt/executables/vdmoniadm/icon1.ico differ
diff --git a/src/native/nt/executables/vdmoniadm/resource.h b/src/native/nt/executables/vdmoniadm/resource.h
new file mode 100644
index 0000000..65877c3
--- /dev/null
+++ b/src/native/nt/executables/vdmoniadm/resource.h
@@ -0,0 +1,82 @@
+/* ========================================================================= *
+ * *
+ * The Apache Software License, Version 1.1 *
+ * *
+ * Copyright (c) 1999-2002 The Apache Software Foundation. *
+ * All rights reserved. *
+ * *
+ * ========================================================================= *
+ * *
+ * Redistribution and use in source and binary forms, with or without modi- *
+ * fication, are permitted provided that the following conditions are met: *
+ * *
+ * 1. Redistributions of source code must retain the above copyright notice *
+ * notice, this list of conditions and the following disclaimer. *
+ * *
+ * 2. Redistributions in binary form must reproduce the above copyright *
+ * notice, this list of conditions and the following disclaimer in the *
+ * documentation and/or other materials provided with the distribution. *
+ * *
+ * 3. The end-user documentation included with the redistribution, if any, *
+ * must include the following acknowlegement: *
+ * *
+ * "This product includes software developed by the Apache Software *
+ * Foundation <http://www.apache.org/>." *
+ * *
+ * Alternately, this acknowlegement may appear in the software itself, if *
+ * and wherever such third-party acknowlegements normally appear. *
+ * *
+ * 4. The names "The Jakarta Project", "WebApp", and "Apache Software *
+ * Foundation" must not be used to endorse or promote products derived *
+ * from this software without prior written permission. For written *
+ * permission, please contact <apache at apache.org>. *
+ * *
+ * 5. Products derived from this software may not be called "Apache" nor may *
+ * "Apache" appear in their names without prior written permission of the *
+ * Apache Software Foundation. *
+ * *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES *
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY *
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL *
+ * THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY *
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL *
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS *
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) *
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, *
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN *
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
+ * POSSIBILITY OF SUCH DAMAGE. *
+ * *
+ * ========================================================================= *
+ * *
+ * This software consists of voluntary contributions made by many indivi- *
+ * duals on behalf of the Apache Software Foundation. For more information *
+ * on the Apache Software Foundation, please see <http://www.apache.org/>. *
+ * *
+ * ========================================================================= */
+
+/* @version $Id: resource.h,v 1.1.1.1 2003/09/04 23:28:20 yoavs Exp $ */
+/* Used by vdmoniadm.rc */
+#define NO_ACCESS 1
+#define NO_ACCESS_MONI 2
+#define ALREADY_STOP 3
+#define ERROR_STATUS 4
+#define ALREADY_START 5
+#define CANNOT_START 6
+#define ID_TASKICON 7
+#define CANNOT_START_VDCOM 7
+#define CANNOT_START_VDCONF 8
+#define ID_STOP_VDMONI 40002
+#define ID_PROPRETY 40003
+#define ID_START_VDCOM 40008
+
+/* Next default values for new objects */
+
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 103
+#define _APS_NEXT_COMMAND_VALUE 40009
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/src/native/nt/executables/vdmoniadm/vdmoniadm.dsp b/src/native/nt/executables/vdmoniadm/vdmoniadm.dsp
new file mode 100644
index 0000000..70d8042
--- /dev/null
+++ b/src/native/nt/executables/vdmoniadm/vdmoniadm.dsp
@@ -0,0 +1,121 @@
+# Microsoft Developer Studio Project File - Name="vdmoniadm" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=vdmoniadm - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "vdmoniadm.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "vdmoniadm.mak" CFG="vdmoniadm - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "vdmoniadm - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "vdmoniadm - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "vdmoniadm - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /I "." /I "../../lib" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 oldnames.lib msvcrt.lib kernel32.lib advapi32.lib user32.lib gdi32.lib shell32.lib /nologo /subsystem:windows /machine:I386 /nodefaultlib /out:"../../bin/vdmoniadm.exe"
+
+!ELSEIF "$(CFG)" == "vdmoniadm - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "." /I "../../lib" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 oldnames.lib msvcrt.lib kernel32.lib advapi32.lib user32.lib gdi32.lib shell32.lib /nologo /subsystem:windows /debug /machine:I386 /nodefaultlib /out:"../../bin/vdmoniadm.exe" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "vdmoniadm - Win32 Release"
+# Name "vdmoniadm - Win32 Debug"
+# Begin Group "moni"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\moni\vdmoniadm.c
+# End Source File
+# End Group
+# Begin Group "lib"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\lib\moni_inst.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\icon1.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\vdmoniadm.rc
+
+!IF "$(CFG)" == "vdmoniadm - Win32 Release"
+
+!ELSEIF "$(CFG)" == "vdmoniadm - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# End Target
+# End Project
diff --git a/src/native/nt/executables/vdmoniadm/vdmoniadm.dsw b/src/native/nt/executables/vdmoniadm/vdmoniadm.dsw
new file mode 100644
index 0000000..c0fdb9b
--- /dev/null
+++ b/src/native/nt/executables/vdmoniadm/vdmoniadm.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 5.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "vdmoniadm"=.\vdmoniadm.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/src/native/nt/executables/vdmoniadm/vdmoniadm.rc b/src/native/nt/executables/vdmoniadm/vdmoniadm.rc
new file mode 100644
index 0000000..5c4ce70
--- /dev/null
+++ b/src/native/nt/executables/vdmoniadm/vdmoniadm.rc
@@ -0,0 +1,344 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// German (Germany) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU)
+#ifdef _WIN32
+LANGUAGE LANG_GERMAN, SUBLANG_GERMAN
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+STOPYESNO DIALOG DISCARDABLE 0, 0, 186, 95
+STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "OnServe-Monitor"
+FONT 8, "MS Sans Serif"
+BEGIN
+ DEFPUSHBUTTON "OK",IDOK,113,55,50,14
+ PUSHBUTTON "Abbrechen",IDCANCEL,19,56,50,14
+ LTEXT "Sind Sie sicher, da� Sie den OnServe-Monitor beenden wollen?",
+ IDC_STATIC,31,17,120,26
+END
+
+STARTYESNO DIALOG DISCARDABLE 0, 0, 186, 95
+STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "OnServe-Monitor"
+FONT 8, "MS Sans Serif"
+BEGIN
+ PUSHBUTTON "Abbrechen",IDCANCEL,71,54,50,14
+ LTEXT "Der OnServe-Monitor wird gestartet. Bitte warten...",
+ IDC_STATIC,31,17,120,26
+END
+
+PLEASEWAIT DIALOG DISCARDABLE 0, 0, 186, 95
+STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "OnServe-Monitor"
+FONT 8, "MS Sans Serif"
+BEGIN
+ PUSHBUTTON "Abbrechen",IDCANCEL,71,54,50,14
+ LTEXT "Der OnServe Monitor wird beendet. Bitte warten...",
+ IDC_STATIC,31,17,120,26
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ "STOPYESNO", DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 179
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 88
+ END
+
+ "STARTYESNO", DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 179
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 88
+ END
+
+ "PLEASEWAIT", DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 179
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 88
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+MENU MENU DISCARDABLE
+BEGIN
+ POPUP "no display"
+ BEGIN
+ MENUITEM "Online-Monitor Kommandos.", ID_START_VDCOM
+ MENUITEM "OnServe Konfigurieren.", ID_PROPRETY
+ MENUITEM "Online-Monitor stoppen.", ID_STOP_VDMONI
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ NO_ACCESS "Mit dieser Kennung d�rfen Sie OnServe nicht beenden."
+ NO_ACCESS_MONI "Der Dienst kann nicht erreicht werden!"
+ ALREADY_STOP "Der OnServe-Monitor ist nicht gestartet."
+ ERROR_STATUS "Der Zustand des Dienstes kann nicht ermittelt werden."
+ ALREADY_START "Der OnServe-Monitor ist bereits gestartet."
+ CANNOT_START "Der OnServe-Monitor kann nicht gestartet werden."
+ CANNOT_START_VDCOM "Das Kommando-Programm des OnServe-Monitors kann nicht gestartet werden."
+ CANNOT_START_VDCONF "Das OnServe-Konfigurationsprogramm kann nicht gestartet werden."
+END
+
+#endif // German (Germany) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+STARTYESNO DIALOG DISCARDABLE 0, 0, 186, 95
+STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "OnServe Monitor"
+FONT 8, "MS Sans Serif"
+BEGIN
+ PUSHBUTTON "Cancel",IDCANCEL,71,54,50,14
+ LTEXT "The OnServe Monitor is being started. Please Wait....",
+ IDC_STATIC,31,17,120,26
+END
+
+STOPYESNO DIALOG DISCARDABLE 0, 0, 186, 95
+STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "OnServe Monitor"
+FONT 8, "MS Sans Serif"
+BEGIN
+ DEFPUSHBUTTON "OK",IDOK,113,55,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,19,56,50,14
+ LTEXT "Are you sure you want to stop the OnServe Monitor?",
+ IDC_STATIC,31,17,120,26
+END
+
+PLEASEWAIT DIALOG DISCARDABLE 0, 0, 186, 95
+STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "OnServe Monitor"
+FONT 8, "MS Sans Serif"
+BEGIN
+ PUSHBUTTON "Cancel",IDCANCEL,71,54,50,14
+ LTEXT "The OnServe Monitor is being stopped. Please Wait....",
+ IDC_STATIC,31,17,120,26
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ "STARTYESNO", DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 179
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 88
+ END
+
+ "STOPYESNO", DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 179
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 88
+ END
+
+ "PLEASEWAIT", DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 179
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 88
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+MENU MENU DISCARDABLE
+BEGIN
+ POPUP "no display"
+ BEGIN
+ MENUITEM "Restart Jakarta service", ID_START_VDCOM
+ MENUITEM "Configure Jakarta service", ID_PROPRETY
+ MENUITEM "Stop Jakarta service", ID_STOP_VDMONI
+ END
+END
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+ONSERVE ICON DISCARDABLE "icon1.ico"
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,1
+ PRODUCTVERSION 1,0,0,1
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "Siemens AG\0"
+ VALUE "FileDescription", "OnServe Service Administration..\0"
+ VALUE "FileVersion", "3.0.0.1\0"
+ VALUE "InternalName", "vdmoniadm\0"
+ VALUE "LegalCopyright", "Copyright � 1998-2001, Apache Software Foundation \0"
+ VALUE "OriginalFilename", "vdmonisvc.exe\0"
+ VALUE "ProductName", "OnServe\0"
+ VALUE "ProductVersion", "3.0 A00\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ NO_ACCESS "Your login does not allow you to stop OnServe."
+ NO_ACCESS_MONI "Cannot access to the service!"
+ ALREADY_STOP "OnServe Monitor is not running."
+ ERROR_STATUS "Cannot get the status of the service."
+ ALREADY_START "OnServe Monitor is already started."
+ CANNOT_START "Cannot start the OnServe Monitor."
+ CANNOT_START_VDCOM "Cannot start the OnServe monitor commands program."
+ CANNOT_START_VDCONF "Cannot start the OnServe Configuration program."
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/src/native/nt/executables/vdmonisvc/resource.h b/src/native/nt/executables/vdmonisvc/resource.h
new file mode 100644
index 0000000..83c6f1b
--- /dev/null
+++ b/src/native/nt/executables/vdmonisvc/resource.h
@@ -0,0 +1,69 @@
+/* ========================================================================= *
+ * *
+ * The Apache Software License, Version 1.1 *
+ * *
+ * Copyright (c) 1999-2001 The Apache Software Foundation. *
+ * All rights reserved. *
+ * *
+ * ========================================================================= *
+ * *
+ * Redistribution and use in source and binary forms, with or without modi- *
+ * fication, are permitted provided that the following conditions are met: *
+ * *
+ * 1. Redistributions of source code must retain the above copyright notice *
+ * notice, this list of conditions and the following disclaimer. *
+ * *
+ * 2. Redistributions in binary form must reproduce the above copyright *
+ * notice, this list of conditions and the following disclaimer in the *
+ * documentation and/or other materials provided with the distribution. *
+ * *
+ * 3. The end-user documentation included with the redistribution, if any, *
+ * must include the following acknowlegement: *
+ * *
+ * "This product includes software developed by the Apache Software *
+ * Foundation <http://www.apache.org/>." *
+ * *
+ * Alternately, this acknowlegement may appear in the software itself, if *
+ * and wherever such third-party acknowlegements normally appear. *
+ * *
+ * 4. The names "The Jakarta Project", "WebApp", and "Apache Software *
+ * Foundation" must not be used to endorse or promote products derived *
+ * from this software without prior written permission. For written *
+ * permission, please contact <apache at apache.org>. *
+ * *
+ * 5. Products derived from this software may not be called "Apache" nor may *
+ * "Apache" appear in their names without prior written permission of the *
+ * Apache Software Foundation. *
+ * *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES *
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY *
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL *
+ * THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY *
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL *
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS *
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) *
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, *
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN *
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
+ * POSSIBILITY OF SUCH DAMAGE. *
+ * *
+ * ========================================================================= *
+ * *
+ * This software consists of voluntary contributions made by many indivi- *
+ * duals on behalf of the Apache Software Foundation. For more information *
+ * on the Apache Software Foundation, please see <http://www.apache.org/>. *
+ * *
+ * ========================================================================= */
+
+/* @version $Id: resource.h,v 1.1.1.1 2003/09/04 23:28:20 yoavs Exp $ */
+/* Used by vdmonisvc.rc */
+
+/* Next default values for new objects */
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 105
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1004
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/src/native/nt/executables/vdmonisvc/vdmonisvc.dsp b/src/native/nt/executables/vdmonisvc/vdmonisvc.dsp
new file mode 100644
index 0000000..b023470
--- /dev/null
+++ b/src/native/nt/executables/vdmonisvc/vdmonisvc.dsp
@@ -0,0 +1,122 @@
+# Microsoft Developer Studio Project File - Name="vdmonisvc" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=vdmonisvc - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "vdmonisvc.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "vdmonisvc.mak" CFG="vdmonisvc - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "vdmonisvc - Win32 Release" (based on\
+ "Win32 (x86) Console Application")
+!MESSAGE "vdmonisvc - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "vdmonisvc - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir ".\vdmonisvc"
+# PROP BASE Intermediate_Dir ".\vdmonisvc"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../lib" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "WINPC" /FR /YX /FD /c
+# ADD BASE RSC /l 0x407 /d "NDEBUG"
+# ADD RSC /l 0x407 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib gdi32.lib user32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib msvcrt.lib oldnames.lib /nologo /subsystem:console /machine:I386 /nodefaultlib /out:"../../bin/vdmonisvc.exe"
+
+!ELSEIF "$(CFG)" == "vdmonisvc - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir ".\CleanSv0"
+# PROP BASE Intermediate_Dir ".\CleanSv0"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c
+# ADD CPP /nologo /MD /W3 /Gm /GX /Zi /Od /I "../../lib" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "WINPC" /FR /YX /FD /c
+# ADD BASE RSC /l 0x407 /d "_DEBUG"
+# ADD RSC /l 0x407 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386
+# ADD LINK32 user32.lib oldnames.lib kernel32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib msvcrt.lib /nologo /subsystem:console /debug /machine:I386 /nodefaultlib /out:"../../bin/vdmonisvc.exe"
+
+!ENDIF
+
+# Begin Target
+
+# Name "vdmonisvc - Win32 Release"
+# Name "vdmonisvc - Win32 Debug"
+# Begin Group "supcalls_nt"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\supcalls_nt\vdenv.c
+# End Source File
+# End Group
+# Begin Group "signals"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\signals\kills.c
+# End Source File
+# End Group
+# Begin Group "moni"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\moni\vdmonisvc.c
+# End Source File
+# End Group
+# Begin Group "moni_nt"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\moni_nt\service.c
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\vdmonisvc.rc
+# End Source File
+# End Target
+# End Project
diff --git a/src/native/nt/executables/vdmonisvc/vdmonisvc.dsw b/src/native/nt/executables/vdmonisvc/vdmonisvc.dsw
new file mode 100644
index 0000000..bf30bea
--- /dev/null
+++ b/src/native/nt/executables/vdmonisvc/vdmonisvc.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 5.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "vdmonisvc"=.\vdmonisvc.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/src/native/nt/executables/vdmonisvc/vdmonisvc.rc b/src/native/nt/executables/vdmonisvc/vdmonisvc.rc
new file mode 100644
index 0000000..dec8783
--- /dev/null
+++ b/src/native/nt/executables/vdmonisvc/vdmonisvc.rc
@@ -0,0 +1,105 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,1
+ PRODUCTVERSION 1,0,0,1
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "Siemens AG\0"
+ VALUE "FileDescription", "OnServe Service application.\0"
+ VALUE "FileVersion", "3.0.0.1\0"
+ VALUE "InternalName", "vdmonisvc\0"
+ VALUE "LegalCopyright", "Copyright � 1998-2001, Apache Software Foundation.\0"
+ VALUE "OriginalFilename", "vdmonisvc.exe\0"
+ VALUE "ProductName", "OnServe\0"
+ VALUE "ProductVersion", "3.0 A00\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/src/native/nt/lib/moni_inst.h b/src/native/nt/lib/moni_inst.h
new file mode 100644
index 0000000..326649e
--- /dev/null
+++ b/src/native/nt/lib/moni_inst.h
@@ -0,0 +1,14 @@
+/*
+ * include for the service installation
+ */
+#define SZAPPNAME "JavaService"
+#define SZSERVICENAME "jsvc" // name of service
+#define SZDEPENDENCIES ""
+#define SZSERVICEDISPLAYNAME "Java Service" // name to display
+#define SZKEY_ONSERVE "SOFTWARE\\apache\\jakarta\\1.0"
+#define SZKEY_ONSERVEARG "SOFTWARE\\apache\\jakarta\\1.0\\arguments"
+#define SZKEY_F_DIR "F_DIR"
+#define SZDEFMONISVCPATH "\\vdmonisvc.exe"
+#define SZCYGWINPATH "c:\\gnu"
+#define SZJAKARTA_HOME "c:\\home\\jakarta"
+#define SZJAVA_HOME "c:\\jdk1.3.1"
diff --git a/src/native/nt/moni/Makefile b/src/native/nt/moni/Makefile
new file mode 100644
index 0000000..5832ff5
--- /dev/null
+++ b/src/native/nt/moni/Makefile
@@ -0,0 +1,15 @@
+INCLUDE=-I../lib
+BIN=../../../../dist
+all: $(BIN)/vdmoniadm $(BIN)/vdmonisvc
+
+$(BIN)/vdmoniadm: vdmoniadm.c
+ gcc $(INCLUDE) -I../executables/vdmoniadm vdmoniadm.c \
+ -o $(BIN)/vdmoniadm -lgdi32
+$(BIN)/vdmonisvc: vdmonisvc.c vdenv.o kills.o
+ gcc -mno-cygwin -I/usr/include $(INCLUDE) -I../executables/vdmonisvc \
+ -DCYGWIN vdmonisvc.c \
+ -o $(BIN)/vdmonisvc vdenv.o kills.o
+vdenv.o: ../supcalls_nt/vdenv.c
+ gcc $(INCLUDE) -c ../supcalls_nt/vdenv.c
+kills.o: ../signals/kills.c
+ gcc $(INCLUDE) -c ../signals/kills.c
diff --git a/src/native/nt/moni/vdmoniadm.c b/src/native/nt/moni/vdmoniadm.c
new file mode 100644
index 0000000..9fcc124
--- /dev/null
+++ b/src/native/nt/moni/vdmoniadm.c
@@ -0,0 +1,635 @@
+/* ========================================================================= *
+ * *
+ * The Apache Software License, Version 1.1 *
+ * *
+ * Copyright (c) 1999-2001 The Apache Software Foundation. *
+ * All rights reserved. *
+ * *
+ * ========================================================================= *
+ * *
+ * Redistribution and use in source and binary forms, with or without modi- *
+ * fication, are permitted provided that the following conditions are met: *
+ * *
+ * 1. Redistributions of source code must retain the above copyright notice *
+ * notice, this list of conditions and the following disclaimer. *
+ * *
+ * 2. Redistributions in binary form must reproduce the above copyright *
+ * notice, this list of conditions and the following disclaimer in the *
+ * documentation and/or other materials provided with the distribution. *
+ * *
+ * 3. The end-user documentation included with the redistribution, if any, *
+ * must include the following acknowlegement: *
+ * *
+ * "This product includes software developed by the Apache Software *
+ * Foundation <http://www.apache.org/>." *
+ * *
+ * Alternately, this acknowlegement may appear in the software itself, if *
+ * and wherever such third-party acknowlegements normally appear. *
+ * *
+ * 4. The names "The Jakarta Project", "WebApp", and "Apache Software *
+ * Foundation" must not be used to endorse or promote products derived *
+ * from this software without prior written permission. For written *
+ * permission, please contact <apache at apache.org>. *
+ * *
+ * 5. Products derived from this software may not be called "Apache" nor may *
+ * "Apache" appear in their names without prior written permission of the *
+ * Apache Software Foundation. *
+ * *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES *
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY *
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL *
+ * THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY *
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL *
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS *
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) *
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, *
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN *
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
+ * POSSIBILITY OF SUCH DAMAGE. *
+ * *
+ * ========================================================================= *
+ * *
+ * This software consists of voluntary contributions made by many indivi- *
+ * duals on behalf of the Apache Software Foundation. For more information *
+ * on the Apache Software Foundation, please see <http://www.apache.org/>. *
+ * *
+ * ========================================================================= */
+
+/* @version $Id: vdmoniadm.c,v 1.1.1.1 2003/09/04 23:28:20 yoavs Exp $ */
+
+#include <windows.h> /* required for all Windows applications */
+#include <stdio.h> /* for sprintf */
+#include <io.h>
+#include <fcntl.h>
+#include <shellapi.h>
+#include <winuser.h>
+
+#include "resource.h"
+#include "moni_inst.h"
+
+
+
+#define WINWIDTH 680
+#define WINHEIGHT 460
+
+#define CLASSMAIN
+#define VM_ICON_MESS WM_USER+1
+#define VM_ID_TIMER WM_USER+2
+#define VM_START_ICON WM_USER+3
+#define VM_ID_TIMER1 WM_USER+4
+#define VM_ID_TIMER2 WM_USER+5
+
+BOOL InitApplication(HANDLE hInstance);
+
+HANDLE hInst; /* current instance */
+SC_HANDLE hManager=NULL;
+SC_HANDLE hService=NULL;
+int optmode; /* start, stop or check. */
+int flagdown = 0;
+
+#define VDMONISTART 0
+#define VDMONISTOP 1
+#define VDMONICHECK 2
+
+#define NORMALWINDOW WS_OVERLAPPED|WS_SYSMENU|WS_MINIMIZEBOX|WS_MAXIMIZEBOX
+#define ICONWINDOW WS_CAPTION|WS_POPUPWINDOW|WS_MINIMIZEBOX|WS_MAXIMIZEBOX
+
+
+/* display a message read from resources */
+
+static void DisplayMess(HWND hDlg,int item)
+{
+char MessBox[256];
+
+ if (LoadString(hInst,item,MessBox,sizeof(MessBox)))
+ MessageBox(hDlg, MessBox,"ERROR" , MB_OK);
+ else {
+ sprintf(MessBox,"ERROR %d",item);
+ MessageBox(hDlg, MessBox,"ERROR" , MB_OK);
+ }
+}
+/*
+ * MyTaskBarAddIcon - adds an icon to the taskbar status area.
+ * Returns TRUE if successful or FALSE otherwise.
+ * hwnd - handle of the window to receive callback messages
+ * uID - identifier of the icon
+ * hicon - handle of the icon to add
+ * lpszTip - ToolTip text
+ */
+BOOL MyTaskBarAddIcon(HWND hWnd)
+{
+ BOOL res;
+ NOTIFYICONDATA notifyicondata;
+ HICON hicon;
+
+ notifyicondata.cbSize=sizeof(notifyicondata);
+ notifyicondata.hWnd=hWnd;
+ notifyicondata.uID=ID_TASKICON;
+ notifyicondata.uFlags= NIF_ICON|NIF_MESSAGE|NIF_TIP;
+ notifyicondata.uCallbackMessage=VM_ICON_MESS;
+ hicon = LoadIcon(hInst,"OnServe");
+ notifyicondata.hIcon = hicon;
+ strcpy(notifyicondata.szTip,"Jakarta Service");
+
+
+ res = Shell_NotifyIcon(NIM_ADD,¬ifyicondata);
+
+ if (hicon)
+ DestroyIcon(hicon);
+
+ return res;
+}
+/*
+ * MyTaskBarDeleteIcon - deletes an icon from the taskbar
+ * status area.
+ * Returns TRUE if successful or FALSE otherwise.
+ * hwnd - handle of the window that added the icon
+ * uID - identifier of the icon to delete
+ */
+BOOL MyTaskBarDeleteIcon(HWND hwnd)
+{
+ BOOL res;
+ NOTIFYICONDATA tnid;
+
+ tnid.cbSize = sizeof(NOTIFYICONDATA);
+ tnid.hWnd = hwnd;
+ tnid.uID = ID_TASKICON;
+
+ res = Shell_NotifyIcon(NIM_DELETE, &tnid);
+ return res;
+}
+
+/* start the vdcom process */
+void StartVdcom(HWND hDlg)
+{
+STARTUPINFO StartupInfo;
+PROCESS_INFORMATION ProcessInformation;
+
+ memset(&StartupInfo,'\0',sizeof(StartupInfo));
+ StartupInfo.cb = sizeof(STARTUPINFO);
+
+ if (!CreateProcess(NULL,"vdcom.exe",NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS,
+ NULL,NULL, &StartupInfo, &ProcessInformation)) {
+ DisplayMess(hDlg,CANNOT_START_VDCOM);
+ return;
+ }
+ /* the handle to the process */
+ CloseHandle(ProcessInformation.hProcess);
+ CloseHandle(ProcessInformation.hThread);
+}
+/* start the vdconf process */
+void StartVdconf(HWND hDlg)
+{
+STARTUPINFO StartupInfo;
+PROCESS_INFORMATION ProcessInformation;
+
+ memset(&StartupInfo,'\0',sizeof(StartupInfo));
+ StartupInfo.cb = sizeof(STARTUPINFO);
+
+ if (!CreateProcess(NULL,"vdconf.exe",NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS,
+ NULL,NULL, &StartupInfo, &ProcessInformation)) {
+ DisplayMess(hDlg,CANNOT_START_VDCONF);
+ return;
+ }
+ /* the handle to the process */
+ CloseHandle(ProcessInformation.hProcess);
+ CloseHandle(ProcessInformation.hThread);
+}
+
+/* test if service is running */
+BOOL IsRunning(HWND hDlg)
+{
+ SERVICE_STATUS svcStatus;
+
+ if (!QueryServiceStatus(hService, &svcStatus)) {
+ DisplayMess(hDlg,ERROR_STATUS);
+ PostQuitMessage(0);
+ return(FALSE);
+ }
+ else {
+ if (SERVICE_RUNNING == svcStatus.dwCurrentState)
+ return(TRUE);
+ }
+ return(FALSE);
+
+}
+/* test if service is stoppped */
+BOOL IsStopped(HWND hDlg)
+{
+ SERVICE_STATUS svcStatus;
+
+ if (!QueryServiceStatus(hService, &svcStatus)) {
+ DisplayMess(hDlg,ERROR_STATUS);
+ PostQuitMessage(0);
+ return(FALSE);
+ }
+ else {
+ if (SERVICE_STOPPED == svcStatus.dwCurrentState)
+ return(TRUE);
+ }
+ return(FALSE);
+
+}
+/* Yes/No dialog box */
+LRESULT APIENTRY StopYesNo(
+ HWND hDlg, /* window handle of the dialog box */
+ UINT message, /* type of message */
+ UINT wParam, /* message-specific information */
+ LONG lParam)
+{
+ SERVICE_STATUS svcStatus;
+
+ switch (message) {
+ case WM_COMMAND: /* message: received a command */
+ if (LOWORD(wParam) == IDOK) { /* "OK" box selected */
+ if (!IsStopped(hDlg)) {
+ ControlService(hService, SERVICE_CONTROL_STOP, &svcStatus);
+ EndDialog(hDlg, TRUE);
+ }
+ else
+ EndDialog(hDlg, FALSE);
+ }
+ if (LOWORD(wParam) == IDCANCEL)
+ EndDialog(hDlg, FALSE);
+ return(TRUE);
+ } /* End switch message */
+ return (FALSE); /* Didn't process a message */
+ UNREFERENCED_PARAMETER(lParam);
+}
+/* Please wait stopping dialog box */
+LRESULT APIENTRY PleaseWait(
+ HWND hDlg, /* window handle of the dialog box */
+ UINT message, /* type of message */
+ UINT wParam, /* message-specific information */
+ LONG lParam)
+{
+
+ switch (message) {
+ case WM_INITDIALOG:
+ SetTimer(hDlg,VM_ID_TIMER2,5000,NULL); /* wait 5 seconds. */
+ case WM_COMMAND: /* message: received a command */
+ if (LOWORD(wParam) == IDCANCEL)
+ EndDialog(hDlg, FALSE);
+ return(TRUE);
+ case WM_TIMER:
+ if(IsStopped(hDlg))
+ EndDialog(hDlg, TRUE);
+ else
+ SetTimer(hDlg,VM_ID_TIMER2,5000,NULL); /* wait 5 seconds. */
+ return(TRUE);
+ } /* End switch message */
+ return (FALSE); /* Didn't process a message */
+ UNREFERENCED_PARAMETER(lParam);
+}
+LRESULT APIENTRY StartYesNo(
+ HWND hDlg, /* window handle of the dialog box */
+ UINT message, /* type of message */
+ UINT wParam, /* message-specific information */
+ LONG lParam)
+{
+
+ switch (message) {
+ case WM_INITDIALOG:
+ if (!StartService(hService,0,NULL)) {
+ DisplayMess(hDlg,CANNOT_START);
+ PostQuitMessage(0);
+ }
+ /* test if running, if not set a timer. */
+ /* wait until service is start */
+ if (IsRunning(hDlg))
+ EndDialog(hDlg, TRUE);
+ else
+ SetTimer(hDlg,VM_ID_TIMER1,5000,NULL); /* wait 5 seconds. */
+ return(TRUE);
+
+ case WM_TIMER:
+ if(IsRunning(hDlg))
+ EndDialog(hDlg, TRUE);
+ else
+ SetTimer(hDlg,VM_ID_TIMER1,5000,NULL); /* wait 5 seconds. */
+ return(TRUE);
+
+ case WM_COMMAND: /* message: received a command */
+ if (LOWORD(wParam) == IDCANCEL) {
+ if (IsRunning(hDlg))
+ EndDialog(hDlg, TRUE);
+ else
+ PostQuitMessage(0);
+ }
+ return(TRUE);
+
+ } /* End switch message */
+ return (FALSE); /* Didn't process a message */
+ UNREFERENCED_PARAMETER(lParam);
+}
+
+/* Display the menu */
+
+void ShowMenu(HWND hWnd)
+{
+ HMENU hMenu,hMenu1;
+ POINT point;
+
+ hMenu = LoadMenu(hInst,"MENU");
+ SetMenu(hWnd,hMenu);
+ hMenu1 = GetSubMenu(hMenu,0);
+
+ GetCursorPos(&point);
+
+ SetForegroundWindow(hWnd); /* MS bug. */
+ TrackPopupMenuEx(hMenu1,TPM_RIGHTALIGN|TPM_BOTTOMALIGN|TPM_LEFTBUTTON|TPM_RIGHTBUTTON,
+ point.x,point.y,hWnd,NULL);
+ PostMessage(hWnd, WM_USER, 0, 0); /* MS bug. */
+ DestroyMenu(hMenu);
+
+}
+/****************************************************************************\
+*
+* FUNCTION: InitInstance(HANDLE, int)
+*
+* PURPOSE: Saves instance handle and creates main window
+*
+*\***************************************************************************/
+
+BOOL InitInstance(
+ HANDLE hInstance, /* Current instance identifier. */
+ int nCmdShow) /* Param for first ShowWindow() call. */
+{
+ HWND hWnd; /* Main window handle. */
+ DWORD dwStyle,dwExStyle;
+
+
+ /* Save the instance handle in static variable, which will be used in */
+ /* many subsequence calls from this application to Windows. */
+
+ hInst = hInstance;
+
+ /* Create a main window for this application instance. */
+
+ if (optmode == VDMONISTART || optmode == VDMONICHECK) {
+ dwStyle = ICONWINDOW;
+ dwExStyle = WS_EX_APPWINDOW;
+ }
+ else {
+ dwStyle = NORMALWINDOW;
+ dwExStyle = 0;
+ }
+
+ hWnd = CreateWindowEx(
+ dwExStyle,
+ "OnServe", /* See RegisterClass() call. */
+ "OnServe Monitor Control", /* Text for window title bar. */
+ dwStyle, /* Window style.*/
+ CW_USEDEFAULT, /* Default horizontal position. */
+ CW_USEDEFAULT, /* Default vertical position. */
+ WINWIDTH, /* Windows width. */
+ WINHEIGHT, /* Windows height. */
+ NULL, /* Overlapped windows have no parent. */
+ NULL, /* Use the window class menu. */
+ hInstance, /* This instance owns this window. */
+ NULL /* Pointer not needed. */
+ );
+
+
+ /* If window could not be created, return "failure" */
+
+ if (!hWnd) {
+ return (FALSE);
+ }
+
+ return (TRUE); /* Returns the value from PostQuitMessage */
+
+}
+/****************************************************************************\
+*
+* FUNCTION: MainWndProc(HWND, unsigned, WORD, LONG)
+*
+* PURPOSE: Processes main window messages
+*
+*\***************************************************************************/
+
+LONG APIENTRY MainWndProc(
+ HWND hWnd, /* window handle */
+ UINT message, /* type of message */
+ UINT wParam, /* additional information */
+ LONG lParam) /* additional information */
+{
+ SERVICE_STATUS svcStatus;
+
+ switch (message) {
+ case WM_CREATE:
+
+ /* acces to service manager. */
+ hManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
+ if (hManager==NULL) {
+ DisplayMess(hWnd,NO_ACCESS);
+ PostQuitMessage(0);
+ break;
+ }
+ /* access to monitor service. */
+ hService = OpenService(hManager, SZSERVICENAME, SERVICE_ALL_ACCESS);
+ if (hService==NULL) {
+ DisplayMess(hWnd,NO_ACCESS_MONI);
+ PostQuitMessage(0);
+ break;
+ }
+ /* check if running. */
+ if (QueryServiceStatus(hService, &svcStatus)) {
+ /* and see if the service is stopped */
+ if (SERVICE_STOPPED == svcStatus.dwCurrentState &&
+ optmode == VDMONISTOP) {
+ DisplayMess(hWnd,ALREADY_STOP);
+ PostQuitMessage(0);
+ break;
+ }
+ else if (SERVICE_RUNNING == svcStatus.dwCurrentState &&
+ optmode == VDMONISTART) {
+ DisplayMess(hWnd,ALREADY_START);
+ PostQuitMessage(0);
+ break;
+ }
+
+ }
+ else {
+ DisplayMess(hWnd,ERROR_STATUS);
+ PostQuitMessage(0);
+ break;
+ }
+
+ /* DialogBoxes Yes/No */
+ if (optmode == VDMONISTART)
+ DialogBox(hInst, /* current instance */
+ "StartYesNo", /* resource to use */
+ hWnd, /* parent handle */
+ StartYesNo); /* instance address */
+ else if (optmode == VDMONISTOP)
+ if (DialogBox(hInst,"StopYesNo",hWnd,StopYesNo))
+ DialogBox(hInst,"PleaseWait",hWnd,PleaseWait);
+
+
+ if (optmode == VDMONISTOP)
+ PostQuitMessage(0);
+ else {
+ SetTimer(hWnd,VM_ID_TIMER,5000,NULL);
+ MyTaskBarAddIcon(hWnd);
+ }
+
+ break; /* WM_CREATE */
+
+ case VM_ICON_MESS:
+ switch ((UINT)lParam) {
+ case WM_LBUTTONDBLCLK:
+ StartVdcom(hWnd);
+ break;
+ case WM_RBUTTONDOWN:
+ flagdown = 1;
+ break;
+ case WM_RBUTTONUP:
+ if (flagdown == 1) {
+ flagdown = 2;
+ /* show a menu. */
+ ShowMenu(hWnd);
+ }
+ break;
+ }
+ break;
+
+
+ case WM_TIMER:
+ /* check if service is running */
+ if (QueryServiceStatus(hService, &svcStatus)) {
+ /* and see if the service is stopped */
+ if (SERVICE_STOPPED == svcStatus.dwCurrentState) {
+ MyTaskBarDeleteIcon(hWnd);
+ PostQuitMessage(0);
+ }
+ SetTimer(hWnd,VM_ID_TIMER,5000,NULL);
+ return(0);
+ }
+ break;
+
+ case VM_START_ICON:
+ /* add the icon and timer. */
+ MyTaskBarAddIcon(hWnd);
+ SetTimer(hWnd,VM_ID_TIMER,5000,NULL);
+ break;
+
+ case WM_COMMAND:
+ /* command for the popup menu. */
+ switch (LOWORD(wParam)) {
+ case ID_START_VDCOM:
+ StartVdcom(hWnd);
+ break;
+ case ID_STOP_VDMONI:
+ if (DialogBox(hInst,"StopYesNo",hWnd,StopYesNo))
+ DialogBox(hInst,"PleaseWait",hWnd,PleaseWait);
+ break;
+ case ID_PROPRETY:
+ StartVdconf(hWnd);
+ break;
+
+ }
+ break;
+
+ /*
+ * Clean up.
+ */
+ case WM_DESTROY:
+ if (hService!=NULL)
+ CloseServiceHandle(hService);
+ if (hManager!=NULL)
+ CloseServiceHandle(hManager);
+ PostQuitMessage(0);
+ break;
+
+ default: /* Passes it on if unproccessed */
+ return (DefWindowProc(hWnd, message, wParam, lParam));
+
+ }
+ return (0);
+
+}
+
+/****************************************************************************
+*
+* FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)
+*
+* PURPOSE: calls initialization function, processes message loop
+*
+*\***************************************************************************/
+
+WINAPI WinMain(
+ HINSTANCE hInstance,
+ HINSTANCE hPrevInstance,
+ LPSTR lpCmdLine,
+ int nCmdShow
+ )
+{
+
+ MSG msg;
+
+ UNREFERENCED_PARAMETER( lpCmdLine );
+ if (strcmp(lpCmdLine,"start")==0)
+ optmode = VDMONISTART;
+ else if (strcmp(lpCmdLine,"stop")==0)
+ optmode = VDMONISTOP;
+ else
+ optmode = VDMONICHECK;
+
+ if (!hPrevInstance) /* Other instances of app running? */
+ if (!InitApplication(hInstance)) /* Initialize shared things */
+ return (FALSE); /* Exits if unable to initialize */
+
+ /*
+ * Perform initializations that apply to a specific instance
+ */
+ if (!InitInstance(hInstance, nCmdShow))
+ return (FALSE);
+
+ /*
+ * Acquire and dispatch messages until a WM_QUIT message is received.
+ */
+ while (GetMessage(&msg, /* message structure */
+ NULL, /* handle of window receiving the message */
+ 0, /* lowest message to examine */
+ 0)) /* highest message to examine */
+ {
+ TranslateMessage(&msg); /* Translates virtual key codes */
+ DispatchMessage(&msg); /* Dispatches message to window */
+ }
+ return (msg.wParam); /* Returns the value from PostQuitMessage */
+}
+
+/****************************************************************************
+*
+* FUNCTION: InitApplication(HANDLE)
+*
+* PURPOSE: Initializes window data and registers window class
+*
+*\***************************************************************************/
+
+BOOL InitApplication(HANDLE hInstance) /* current instance */
+{
+ WNDCLASS wc;
+
+ /* Fill in window class structure with parameters that describe the */
+ /* main window. */
+
+ wc.style = 0; /* Class style(s). */
+ wc.lpfnWndProc = (WNDPROC)MainWndProc;/* Function to retrieve messages for */
+ /* windows of this class. */
+ wc.cbClsExtra = 0; /* No per-class extra data. */
+ wc.cbWndExtra = 0; /* No per-window extra data. */
+ wc.hIcon = LoadIcon (hInstance, "onserve"); /* Icon name from .RC */
+ wc.hInstance = hInstance; /* Application that owns the class. */
+ wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wc.hbrBackground = GetStockObject(WHITE_BRUSH);
+ wc.lpszMenuName = "onservemenu"; /* Name of menu resource in .RC file. */
+ wc.lpszClassName = "OnServe"; /* Name used in call to CreateWindow. */
+
+ /* Register the window class and return success/failure code. */
+
+ return (RegisterClass(&wc));
+
+}
+
diff --git a/src/native/nt/moni/vdmonisvc.c b/src/native/nt/moni/vdmonisvc.c
new file mode 100644
index 0000000..dee44bd
--- /dev/null
+++ b/src/native/nt/moni/vdmonisvc.c
@@ -0,0 +1,748 @@
+/* ========================================================================= *
+ * *
+ * The Apache Software License, Version 1.1 *
+ * *
+ * Copyright (c) 1999-2001 The Apache Software Foundation. *
+ * All rights reserved. *
+ * *
+ * ========================================================================= *
+ * *
+ * Redistribution and use in source and binary forms, with or without modi- *
+ * fication, are permitted provided that the following conditions are met: *
+ * *
+ * 1. Redistributions of source code must retain the above copyright notice *
+ * notice, this list of conditions and the following disclaimer. *
+ * *
+ * 2. Redistributions in binary form must reproduce the above copyright *
+ * notice, this list of conditions and the following disclaimer in the *
+ * documentation and/or other materials provided with the distribution. *
+ * *
+ * 3. The end-user documentation included with the redistribution, if any, *
+ * must include the following acknowlegement: *
+ * *
+ * "This product includes software developed by the Apache Software *
+ * Foundation <http://www.apache.org/>." *
+ * *
+ * Alternately, this acknowlegement may appear in the software itself, if *
+ * and wherever such third-party acknowlegements normally appear. *
+ * *
+ * 4. The names "The Jakarta Project", "WebApp", and "Apache Software *
+ * Foundation" must not be used to endorse or promote products derived *
+ * from this software without prior written permission. For written *
+ * permission, please contact <apache at apache.org>. *
+ * *
+ * 5. Products derived from this software may not be called "Apache" nor may *
+ * "Apache" appear in their names without prior written permission of the *
+ * Apache Software Foundation. *
+ * *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES *
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY *
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL *
+ * THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY *
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL *
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS *
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) *
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, *
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN *
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
+ * POSSIBILITY OF SUCH DAMAGE. *
+ * *
+ * ========================================================================= *
+ * *
+ * This software consists of voluntary contributions made by many indivi- *
+ * duals on behalf of the Apache Software Foundation. For more information *
+ * on the Apache Software Foundation, please see <http://www.apache.org/>. *
+ * *
+ * ========================================================================= */
+
+/* @version $Id: vdmonisvc.c,v 1.1.1.1 2003/09/04 23:28:20 yoavs Exp $ */
+
+/* jsvc monitor service module:
+ * Implements the body of the service.
+ * It reads the register entry and starts the jsvc.
+ */
+
+#include <windows.h>
+#include <winuser.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <process.h>
+#include <time.h>
+#ifdef CYGWIN
+#else
+#include <tchar.h>
+#endif
+#include "moni_inst.h"
+
+/* globals */
+SERVICE_STATUS ssStatus;
+SERVICE_STATUS_HANDLE sshStatusHandle;
+DWORD dwErr;
+HANDLE hServerStopEvent = NULL;
+HANDLE hMonitorProcess = NULL;
+
+/*
+ * NT/other detection
+ * from src/os/win32/service.c (httpd-1.3!).
+ */
+
+BOOL isWindowsNT(void)
+{
+ static BOOL once = FALSE;
+ static BOOL isNT = FALSE;
+
+ if (!once)
+ {
+ OSVERSIONINFO osver;
+ osver.dwOSVersionInfoSize = sizeof(osver);
+ if (GetVersionEx(&osver))
+ if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT)
+ isNT = TRUE;
+ once = TRUE;
+ }
+ return isNT;
+}
+
+/* Event logger routine */
+
+VOID AddToMessageLog(LPTSTR lpszMsg)
+{
+ TCHAR szMsg[256];
+ HANDLE hEventSource;
+ LPTSTR lpszStrings[2];
+
+
+ dwErr = GetLastError();
+
+ /* Use event logging to log the error. */
+
+ if (isWindowsNT())
+ hEventSource = RegisterEventSource(NULL, TEXT(SZSERVICENAME));
+ else
+ hEventSource = NULL;
+
+#ifdef CYGWIN
+ sprintf(szMsg, TEXT("%s ERROR: %d"), TEXT(SZSERVICENAME), dwErr);
+#else
+ _stprintf(szMsg, TEXT("%s ERROR: %d"), TEXT(SZSERVICENAME), dwErr);
+#endif
+ lpszStrings[0] = szMsg;
+ lpszStrings[1] = lpszMsg;
+
+ if (hEventSource != NULL) {
+ ReportEvent(hEventSource, /* handle of event source */
+ EVENTLOG_ERROR_TYPE, /* event type */
+ 0, /* event category */
+ 0, /* event ID */
+ NULL, /* current user's SID */
+ 2, /* strings in lpszStrings */
+ 0, /* no bytes of raw data */
+ lpszStrings, /* array of error strings */
+ NULL); /* no raw data */
+
+ (VOID) DeregisterEventSource(hEventSource);
+ } else {
+ /* Default to a trace file */
+ FILE *log;
+ log = fopen("c:/jakarta-service.log","a+");
+ if (log != NULL) {
+ struct tm *newtime;
+ time_t long_time;
+
+ time( &long_time );
+ newtime = localtime( &long_time );
+
+ if (dwErr)
+ fprintf(log,"%.24s:%s: %s\n",asctime(newtime),szMsg, lpszMsg);
+ else
+ fprintf(log,"%.24s: %s\n",asctime(newtime), lpszMsg);
+ fclose(log);
+ }
+ }
+}
+
+/*
+ *
+ * FUNCTION: ServiceStop
+ *
+ * PURPOSE: Stops the service
+ *
+ * PARAMETERS:
+ * none
+ *
+ * RETURN VALUE:
+ * none
+ *
+ * COMMENTS:
+ * If a ServiceStop procedure is going to
+ * take longer than 3 seconds to execute,
+ * it should spawn a thread to execute the
+ * stop code, and return. Otherwise, the
+ * ServiceControlManager will believe that
+ * the service has stopped responding.
+ *
+ */
+VOID ServiceStop()
+{
+ if ( hServerStopEvent )
+ SetEvent(hServerStopEvent);
+}
+
+/*
+ * Wait for the monitor process to stop
+ */
+int WaitForMonitor(int num)
+{
+ DWORD qreturn;
+ int i;
+
+ for (i=0;i<num;i++) {
+ if (hMonitorProcess == NULL) break;
+ if (GetExitCodeProcess(hMonitorProcess, &qreturn)) {
+ if (qreturn == STILL_ACTIVE) {
+ Sleep(1000);
+ continue;
+ }
+ hMonitorProcess = NULL;
+ break;
+ }
+ break;
+ }
+ if (i==num)
+ return -1;
+ return 0;
+}
+/* This group of functions are provided for the service/console app
+ * to register itself a HandlerRoutine to accept tty or service messages
+ * adapted from src/os/win32/Win9xConHook.c (httpd-1.3!).
+ */
+
+/* This is the WndProc procedure for our invisible window.
+ * When our subclasssed tty window receives the WM_CLOSE, WM_ENDSESSION,
+ * or WM_QUERYENDSESSION messages, the message is dispatched to our hidden
+ * window (this message process), and we call the installed HandlerRoutine
+ * that was registered by the app.
+ */
+#ifndef ENDSESSION_LOGOFF
+#define ENDSESSION_LOGOFF 0x80000000
+#endif
+static LRESULT CALLBACK ttyConsoleCtrlWndProc(HWND hwnd, UINT msg,
+ WPARAM wParam, LPARAM lParam)
+{
+ int qreturn;
+ if (msg == WM_CREATE) {
+ AddToMessageLog(TEXT("ttyConsoleCtrlWndProc WM_CREATE"));
+ return 0;
+ } else if (msg == WM_DESTROY) {
+ AddToMessageLog(TEXT("ttyConsoleCtrlWndProc WM_DESTROY"));
+ return 0;
+ } else if (msg == WM_CLOSE) {
+ /* Call StopService?. */
+ AddToMessageLog(TEXT("ttyConsoleCtrlWndProc WM_CLOSE"));
+ return 0; /* May return 1 if StopService failed. */
+ } else if ((msg == WM_QUERYENDSESSION) || (msg == WM_ENDSESSION)) {
+ if (lParam & ENDSESSION_LOGOFF) {
+ /* Here we have nothing to our hidden windows should stay. */
+ AddToMessageLog(TEXT("ttyConsoleCtrlWndProc LOGOFF"));
+ return(1); /* Otherwise it cancels the logoff */
+ } else {
+ /* Stop Service. */
+ AddToMessageLog(TEXT("ttyConsoleCtrlWndProc SHUTDOWN"));
+ ServiceStop();
+
+ /* Wait until it stops. */
+ qreturn = WaitForMonitor(3);
+
+ if (msg == WM_QUERYENDSESSION) {
+ AddToMessageLog(
+ TEXT("ttyConsoleCtrlWndProc SHUTDOWN (query)"));
+ if (qreturn) {
+ AddToMessageLog(
+ TEXT("Cancelling shutdown: cannot stop service"));
+ return(0);
+ }
+ } else
+ AddToMessageLog(TEXT("ttyConsoleCtrlWndProc SHUTDOWN"));
+ return(1); /* Otherwise it cancels the shutdown. */
+ }
+ }
+ return (DefWindowProc(hwnd, msg, wParam, lParam));
+}
+/* ttyConsoleCreateThread is the process that runs within the user app's
+ * context. It creates and pumps the messages of a hidden monitor window,
+ * watching for messages from the system, or the associated subclassed tty
+ * window. Things can happen in our context that can't be done from the
+ * tty's context, and visa versa, so the subclass procedure and this hidden
+ * window work together to make it all happen.
+ */
+static DWORD WINAPI ttyConsoleCtrlThread()
+{
+ HWND monitor_hwnd;
+ WNDCLASS wc;
+ MSG msg;
+ wc.style = CS_GLOBALCLASS;
+ wc.lpfnWndProc = ttyConsoleCtrlWndProc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 8;
+ wc.hInstance = NULL;
+ wc.hIcon = NULL;
+ wc.hCursor = NULL;
+ wc.hbrBackground = NULL;
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = "ApacheJakartaService";
+
+ if (!RegisterClass(&wc)) {
+ AddToMessageLog(TEXT("RegisterClass failed"));
+ return 0;
+ }
+
+ /* Create an invisible window */
+ monitor_hwnd = CreateWindow(wc.lpszClassName,
+ "ApacheJakartaService",
+ WS_OVERLAPPED & ~WS_VISIBLE,
+ CW_USEDEFAULT, CW_USEDEFAULT,
+ CW_USEDEFAULT, CW_USEDEFAULT,
+ NULL, NULL,
+ GetModuleHandle(NULL), NULL);
+
+ if (!monitor_hwnd) {
+ AddToMessageLog(TEXT("RegisterClass failed"));
+ return 0;
+ }
+
+ while (GetMessage(&msg, NULL, 0, 0))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+
+ return 0;
+}
+/*
+ * Register the process to resist logoff and start the thread that will receive
+ * the shutdown via a hidden window.
+ */
+BOOL Windows9xServiceCtrlHandler()
+{
+ HANDLE hThread;
+ DWORD tid;
+ HINSTANCE hkernel;
+ DWORD (WINAPI *register_service_process)(DWORD, DWORD) = NULL;
+
+ /* If we have not yet done so */
+ FreeConsole();
+
+ /* Make sure the process will resist logoff */
+ hkernel = LoadLibrary("KERNEL32.DLL");
+ if (!hkernel) {
+ AddToMessageLog(TEXT("LoadLibrary KERNEL32.DLL failed"));
+ return 0;
+ }
+ register_service_process = (DWORD (WINAPI *)(DWORD, DWORD))
+ GetProcAddress(hkernel, "RegisterServiceProcess");
+ if (register_service_process == NULL) {
+ AddToMessageLog(TEXT("dlsym RegisterServiceProcess failed"));
+ return 0;
+ }
+ if (!register_service_process(0,TRUE)) {
+ FreeLibrary(hkernel);
+ AddToMessageLog(TEXT("register_service_process failed"));
+ return 0;
+ }
+ AddToMessageLog(TEXT("jsvc registered as a service"));
+
+ /*
+ * To be handle notice the shutdown, we need a thread and window.
+ */
+ hThread = CreateThread(NULL, 0, ttyConsoleCtrlThread,
+ (LPVOID)NULL, 0, &tid);
+ if (hThread) {
+ CloseHandle(hThread);
+ return TRUE;
+ }
+ AddToMessageLog(TEXT("jsvc shutdown listener start failed"));
+ return TRUE;
+}
+
+/*
+ *
+ * FUNCTION: ReportStatusToSCMgr()
+ *
+ * PURPOSE: Sets the current status of the service and
+ * reports it to the Service Control Manager
+ *
+ * PARAMETERS:
+ * dwCurrentState - the state of the service
+ * dwWin32ExitCode - error code to report
+ * dwWaitHint - worst case estimate to next checkpoint
+ *
+ * RETURN VALUE:
+ * TRUE - success
+ * FALSE - failure
+ *
+ * COMMENTS:
+ *
+ */
+BOOL ReportStatusToSCMgr(DWORD dwCurrentState,
+ DWORD dwWin32ExitCode,
+ DWORD dwWaitHint)
+{
+ static DWORD dwCheckPoint = 1;
+ BOOL fResult = TRUE;
+
+
+ if (dwCurrentState == SERVICE_START_PENDING)
+ ssStatus.dwControlsAccepted = 0;
+ else
+ ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
+
+ ssStatus.dwCurrentState = dwCurrentState;
+ ssStatus.dwWin32ExitCode = dwWin32ExitCode;
+ ssStatus.dwWaitHint = dwWaitHint;
+
+ if ( ( dwCurrentState == SERVICE_RUNNING ) ||
+ ( dwCurrentState == SERVICE_STOPPED ) )
+ ssStatus.dwCheckPoint = 0;
+ else
+ ssStatus.dwCheckPoint = dwCheckPoint++;
+
+
+ /* Report the status of the service to the service control manager. */
+
+ if (!(fResult = SetServiceStatus( sshStatusHandle, &ssStatus))) {
+ AddToMessageLog(TEXT("SetServiceStatus"));
+ }
+ return fResult;
+}
+
+/*
+ * Report event to the Service Manager
+ */
+int ReportManager(int event)
+{
+ if (isWindowsNT())
+ return(ReportStatusToSCMgr(
+ event, /* service state */
+ NO_ERROR, /* exit code */
+ 3000)); /* wait hint */
+ return(1);
+}
+
+/*
+ *
+ * FUNCTION: ServiceStart
+ *
+ * PURPOSE: Actual code of the service
+ * that does the work.
+ *
+ * PARAMETERS:
+ * dwArgc - number of command line arguments
+ * lpszArgv - array of command line arguments
+ *
+ * RETURN VALUE:
+ * none
+ *
+ * COMMENTS:
+ * The default behavior is to read the registry and start jsvc.
+ * The service stops when hServerStopEvent is signalled, the jsvc
+ * is stopped via TermPid(pid) (see kills.c).
+ *
+ */
+VOID ServiceStart (DWORD dwArgc, LPTSTR *lpszArgv)
+{
+char Data[512];
+DWORD qreturn;
+STARTUPINFO StartupInfo;
+PROCESS_INFORMATION ProcessInformation;
+char *qptr;
+
+
+ /* Service initialization */
+ ProcessInformation.hProcess = NULL;
+
+ /* report the status to the service control manager. */
+
+ AddToMessageLog(TEXT("ServiceStart: starting"));
+ if (!ReportManager(SERVICE_START_PENDING))
+ goto cleanup;
+
+ /*
+ * create the event object. The control handler function signals
+ * this event when it receives the "stop" control code.
+ *
+ */
+ hServerStopEvent = CreateEvent(
+ NULL, /* no security attributes */
+ TRUE, /* manual reset event */
+ FALSE, /* not-signalled */
+ NULL); /* no name */
+
+ if ( hServerStopEvent == NULL)
+ goto cleanup;
+
+ /* report the status to the service control manager. */
+ if (!ReportManager(SERVICE_START_PENDING))
+ goto cleanup;
+
+ /* Read the registry and set environment. */
+ if (OnServeSetEnv()) {
+ AddToMessageLog(TEXT("ServiceStart: read environment failed"));
+ goto cleanup;
+ }
+
+ if (!ReportManager(SERVICE_START_PENDING))
+ goto cleanup;
+
+ /* set the start path for jsvc.exe */
+ qptr = getenv("JAKARTA_HOME");
+ if (qptr==NULL || strlen(qptr)==0) {
+ AddToMessageLog(TEXT("ServiceStart: read JAKARTA_HOME failed"));
+ goto cleanup;
+ }
+
+ /* Build the start jsvc command according to the registry information. */
+ strcpy(Data,qptr);
+ BuildCommand(Data);
+ AddToMessageLog(TEXT(Data));
+
+ /* create the jsvc process. */
+ AddToMessageLog(TEXT("ServiceStart: start jsvc"));
+ memset(&StartupInfo,'\0',sizeof(StartupInfo));
+ StartupInfo.cb = sizeof(STARTUPINFO);
+
+ if (!CreateProcess(NULL,Data,NULL,NULL,FALSE,
+ DETACHED_PROCESS|NORMAL_PRIORITY_CLASS,
+ NULL,NULL, &StartupInfo, &ProcessInformation))
+ goto cleanup;
+ AddToMessageLog(TEXT("ServiceStart: jsvc started"));
+ CloseHandle(ProcessInformation.hThread);
+ ProcessInformation.hThread = NULL;
+ hMonitorProcess = ProcessInformation.hProcess;
+
+ if (!ReportManager(SERVICE_START_PENDING))
+ goto cleanup;
+
+ /* wait until the process is completly created. */
+/* With the DETACHED_PROCESS it does not work...
+ if (WaitForInputIdle(ProcessInformation.hProcess , INFINITE)) {
+ AddToMessageLog(TEXT("ServiceStart: jsvc stopped after creation"));
+ goto cleanup;
+ }
+ */
+
+ /*
+ * jsvc is now running.
+ * report the status to the service control manager.
+ */
+
+ if (!ReportManager(SERVICE_RUNNING))
+ goto cleanup;
+
+ /* End of initialization */
+
+ /*
+ *
+ * Service is now running, perform work until shutdown:
+ * Check every 60 seconds if the monitor is up.
+ *
+ */
+
+ for (;;) {
+ qreturn = WaitForSingleObject(hServerStopEvent,60000); /* each minutes. */
+
+ if (qreturn == WAIT_FAILED) break;/* something have gone wrong. */
+
+ if (qreturn == WAIT_TIMEOUT) {
+ /* timeout check the monitor. */
+ if (GetExitCodeProcess(ProcessInformation.hProcess, &qreturn)) {
+ if (qreturn == STILL_ACTIVE) continue;
+ }
+ AddToMessageLog(TEXT("ServiceStart: jsvc crashed"));
+ hMonitorProcess = NULL;
+ CloseHandle(hServerStopEvent);
+ CloseHandle(ProcessInformation.hProcess);
+ exit(0); /* exit ungracefully so
+ * Service Control Manager
+ * will attempt a restart. */
+
+ break; /*failed. */
+ }
+
+ /* stop the monitor by signal(event) */
+ sprintf(Data,"ServiceStart: stopping jsvc: %d",
+ ProcessInformation.dwProcessId);
+ AddToMessageLog(Data);
+
+ if (TermPid(ProcessInformation.dwProcessId)) {
+ AddToMessageLog(TEXT("ServiceStart: jsvc stop failed"));
+ break;
+ }
+ WaitForMonitor(6);
+ AddToMessageLog(TEXT("ServiceStart: jsvc stopped"));
+ break; /* finished!!! */
+ }
+
+ cleanup:
+
+ AddToMessageLog(TEXT("ServiceStart: stopped"));
+ if (hServerStopEvent)
+ CloseHandle(hServerStopEvent);
+
+ if (ProcessInformation.hProcess)
+ CloseHandle(ProcessInformation.hProcess);
+
+}
+
+/*
+ *
+ * FUNCTION: service_ctrl
+ *
+ * PURPOSE: This function is called by the SCM whenever
+ * ControlService() is called on this service.
+ *
+ * PARAMETERS:
+ * dwCtrlCode - type of control requested
+ *
+ * RETURN VALUE:
+ * none
+ *
+ * COMMENTS:
+ *
+ */
+VOID WINAPI service_ctrl(DWORD dwCtrlCode)
+{
+ /* Handle the requested control code. */
+ switch(dwCtrlCode)
+ {
+ /* Stop the service.
+ *
+ * SERVICE_STOP_PENDING should be reported before
+ * setting the Stop Event - hServerStopEvent - in
+ * ServiceStop(). This avoids a race condition
+ * which may result in a 1053 - The Service did not respond...
+ * error.
+ */
+ case SERVICE_CONTROL_STOP:
+ ReportStatusToSCMgr(SERVICE_STOP_PENDING, NO_ERROR, 0);
+ ServiceStop();
+ return;
+
+ /* Update the service status. */
+ case SERVICE_CONTROL_INTERROGATE:
+ break;
+
+ /* invalid control code */
+ default:
+ break;
+
+ }
+
+ ReportStatusToSCMgr(ssStatus.dwCurrentState, NO_ERROR, 0);
+}
+
+/*
+ *
+ * FUNCTION: service_main
+ *
+ * PURPOSE: To perform actual initialization of the service
+ *
+ * PARAMETERS:
+ * dwArgc - number of command line arguments
+ * lpszArgv - array of command line arguments
+ *
+ * RETURN VALUE:
+ * none
+ *
+ * COMMENTS:
+ * This routine performs the service initialization and then calls
+ * the user defined ServiceStart() routine to perform majority
+ * of the work.
+ *
+ */
+void WINAPI service_main(DWORD dwArgc, LPTSTR *lpszArgv)
+{
+
+ AddToMessageLog(TEXT("service_main:starting"));
+
+ /* register our service control handler: */
+ sshStatusHandle = RegisterServiceCtrlHandler( TEXT(SZSERVICENAME),
+ service_ctrl);
+
+ if (!sshStatusHandle) {
+ AddToMessageLog(TEXT("service_main:RegisterServiceCtrlHandler failed"));
+ goto cleanup;
+ }
+
+ /* SERVICE_STATUS members that don't change in example */
+ ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
+ ssStatus.dwServiceSpecificExitCode = 0;
+
+
+ /* report the status to the service control manager. */
+ if (!ReportStatusToSCMgr(SERVICE_START_PENDING,NO_ERROR,3000)) {
+ AddToMessageLog(TEXT("service_main:ReportStatusToSCMgr failed"));
+ goto cleanup;
+ }
+
+
+ ServiceStart( dwArgc, lpszArgv );
+
+cleanup:
+ /*
+ * try to report the stopped status to the service control manager.
+ */
+ if (sshStatusHandle)
+ (VOID)ReportStatusToSCMgr(
+ SERVICE_STOPPED,
+ dwErr,
+ 0);
+
+ AddToMessageLog(TEXT("service_main:stopped"));
+ return;
+}
+
+/*
+ *
+ * FUNCTION: main
+ *
+ * PURPOSE: entrypoint for service
+ *
+ * PARAMETERS:
+ * argc - number of command line arguments
+ * argv - array of command line arguments
+ *
+ * RETURN VALUE:
+ * none
+ *
+ * COMMENTS:
+ * main() either performs the command line task, or
+ * call StartServiceCtrlDispatcher to register the
+ * main service thread. When the this call returns,
+ * the service has stopped, so exit.
+ *
+ */
+#ifdef CYGWIN
+int main(int argc, char **argv)
+#else
+void _CRTAPI1 main(int argc, char **argv)
+#endif
+{
+ SERVICE_TABLE_ENTRY dispatchTable[] =
+ {
+ { TEXT(SZSERVICENAME), (LPSERVICE_MAIN_FUNCTION)service_main },
+ { NULL, NULL }
+ };
+
+ AddToMessageLog(TEXT("StartService starting"));
+ if (isWindowsNT()) {
+ if (!StartServiceCtrlDispatcher(dispatchTable)) {
+ AddToMessageLog(TEXT("StartServiceCtrlDispatcher failed."));
+ return;
+ }
+ AddToMessageLog(TEXT("StartService started"));
+ } else {
+ Windows9xServiceCtrlHandler();
+ ServiceStart(argc,argv);
+ AddToMessageLog(TEXT("StartService stopped"));
+ }
+}
diff --git a/src/native/nt/procrun/License.rtf b/src/native/nt/procrun/License.rtf
new file mode 100644
index 0000000..f81125d
--- /dev/null
+++ b/src/native/nt/procrun/License.rtf
@@ -0,0 +1,30 @@
+{\rtf1\ansi\ansicpg1252\uc1 \deff0\deflang1033\deflangfe1033{\fonttbl{\f0\froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f1\fswiss\fcharset0\fprq2{\*\panose 020b0604020202020204}Arial;}
+{\f34\froman\fcharset238\fprq2 Times New Roman CE;}{\f35\froman\fcharset204\fprq2 Times New Roman Cyr;}{\f37\froman\fcharset161\fprq2 Times New Roman Greek;}{\f38\froman\fcharset162\fprq2 Times New Roman Tur;}
+{\f39\froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f40\froman\fcharset178\fprq2 Times New Roman (Arabic);}{\f41\froman\fcharset186\fprq2 Times New Roman Baltic;}{\f42\fswiss\fcharset238\fprq2 Arial CE;}{\f43\fswiss\fcharset204\fprq2 Arial Cyr;}
+{\f45\fswiss\fcharset161\fprq2 Arial Greek;}{\f46\fswiss\fcharset162\fprq2 Arial Tur;}{\f47\fswiss\fcharset177\fprq2 Arial (Hebrew);}{\f48\fswiss\fcharset178\fprq2 Arial (Arabic);}{\f49\fswiss\fcharset186\fprq2 Arial Baltic;}}
+{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;
+\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0
+\fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext0 Normal;}{\*\cs10 \additive Default Paragraph Font;}{\*\cs15 \additive \ul\cf2 \sbasedon10 Hyperlink;}}{\info{\author Mladen Turk}{\operator Sara D Wilken}{\creatim\yr2003\mo4\dy9\hr14\min37}
+{\revtim\yr2004\mo2\dy10\hr21\min22}{\version4}{\edmins2}{\nofpages1}{\nofwords370}{\nofchars2113}{\*\company Apache Software Foundation}{\nofcharsws0}{\vern8269}}
+\widowctrl\ftnbj\aenddoc\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\hyphcaps0\horzdoc\dghspace120\dgvspace120\dghorigin1701\dgvorigin1984\dghshow0\dgvshow3\jcompress\viewkind4\viewscale100\nolnhtadjtbl \fet0\sectd \linex0\sectdefaultcl
+{\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5
+\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang
+{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain \ql \li0\ri0\nowidctlpar\faauto\rin0\lin0\itap0 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\b\f1\fs20 The Apac
+he Software License, Version 2.0
+\par }{\f1\fs18
+\par }{\f1\fs18 Copyright 2002-2004 The Apache Software Foundation.
+\par
+\par Licensed under the Apache License, Version 2.0 (the "License");
+\par you may not use this file except in compliance with the License.
+\par You may obtain a copy of the License at
+\par
+\par }{\field{\*\fldinst {\f1\fs18 HYPERLINK "http://www.apache.org/licenses/LICENSE-2.0" }{\f1\fs18 {\*\datafield
+00d0c9ea79f9bace118c8200aa004ba90b0200000003000000e0c9ea79f9bace118c8200aa004ba90b5600000068007400740070003a002f002f007700770077002e006100700061006300680065002e006f00720067002f006c006900630065006e007300650073002f004c004900430045004e00530045002d0032002e00
+30000000}}}{\fldrslt {\cs15\ul\cf2 http://www.apache.org/licenses/LICENSE-2.0}}}{\f1\fs18
+\par
+\par Unless required by applicable law or agreed to in writing, software
+\par distributed under the License is distributed on an "AS IS" BASIS,
+\par WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+\par See the License for the specific language governing permissions and
+\par limitations under the License.}{\f1\fs18
+\par }}
\ No newline at end of file
diff --git a/src/native/nt/procrun/Makefile b/src/native/nt/procrun/Makefile
new file mode 100644
index 0000000..735fb55
--- /dev/null
+++ b/src/native/nt/procrun/Makefile
@@ -0,0 +1,20 @@
+JAVA_HOME=c:/j2sdk1.4.1_01
+INCLUDE=-I. -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/win32
+BIN=.
+# CFLAGS for debugging
+#CFLAGS=-D_DEBUG
+
+all: $(BIN)/procrun $(BIN)/procrunw
+
+$(BIN)/procrun: procrun.c
+ gcc -mno-cygwin $(INCLUDE) $(CFLAGS) -DPROCRUN_CONSOLE procrun.c \
+ -lshlwapi \
+ -o $(BIN)/procrun
+
+$(BIN)/procrunw: procrun.c
+ gcc -mno-cygwin $(INCLUDE) $(CFLAGS) -DPROCRUN_WINAPP -c procgui.c
+ gcc -mno-cygwin $(INCLUDE) $(CFLAGS) -DPROCRUN_WINAPP procrun.c \
+ procgui.o \
+ -lshlwapi \
+ -lcomctl32 \
+ -o $(BIN)/procrunw
diff --git a/src/native/nt/procrun/extend.h b/src/native/nt/procrun/extend.h
new file mode 100644
index 0000000..8101612
--- /dev/null
+++ b/src/native/nt/procrun/extend.h
@@ -0,0 +1,3 @@
+/*
+ * procrun GUI extension includes.
+ */
diff --git a/src/native/nt/procrun/icoi.ico b/src/native/nt/procrun/icoi.ico
new file mode 100644
index 0000000..1f04870
Binary files /dev/null and b/src/native/nt/procrun/icoi.ico differ
diff --git a/src/native/nt/procrun/icos.ico b/src/native/nt/procrun/icos.ico
new file mode 100644
index 0000000..b6f6f1e
Binary files /dev/null and b/src/native/nt/procrun/icos.ico differ
diff --git a/src/native/nt/procrun/icow.ico b/src/native/nt/procrun/icow.ico
new file mode 100644
index 0000000..3b310c6
Binary files /dev/null and b/src/native/nt/procrun/icow.ico differ
diff --git a/src/native/nt/procrun/jakarta-banner.bmp b/src/native/nt/procrun/jakarta-banner.bmp
new file mode 100644
index 0000000..c78cb95
Binary files /dev/null and b/src/native/nt/procrun/jakarta-banner.bmp differ
diff --git a/src/native/nt/procrun/java/Test.java b/src/native/nt/procrun/java/Test.java
new file mode 100644
index 0000000..12f92f1
--- /dev/null
+++ b/src/native/nt/procrun/java/Test.java
@@ -0,0 +1,18 @@
+import java.io.*;
+import java.lang.*;
+
+public class Test implements Runnable {
+ public static void main (String args[]) {
+ Thread t = new Thread( new Test());
+ t.run();
+ }
+ public void run(){
+ try {
+ System.out.println("Simple Stdout message");
+ System.err.println("Simple Stderr message");
+ Thread.sleep(5000);
+ } catch( Throwable t ) {
+ t.printStackTrace(System.err);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/native/nt/procrun/procgui.c b/src/native/nt/procrun/procgui.c
new file mode 100644
index 0000000..4cbf5ab
--- /dev/null
+++ b/src/native/nt/procrun/procgui.c
@@ -0,0 +1,1300 @@
+/* ====================================================================
+ Copyright 2002-2004 The Apache Software Foundation.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+/* ====================================================================
+ * procrun
+ *
+ * Contributed by Mladen Turk <mturk at apache.org>
+ *
+ * 05 Aug 2002
+ * ====================================================================
+ */
+#if defined(PROCRUN_WINAPP)
+
+#ifndef STRICT
+#define STRICT
+#endif
+#ifndef OEMRESOURCE
+#define OEMRESOURCE
+#endif
+
+#include <windows.h>
+#include <windowsx.h>
+#include <commctrl.h>
+#include <objbase.h>
+#include <shlobj.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <Shlwapi.h>
+#include <io.h>
+#include <fcntl.h>
+#include <process.h>
+#include <time.h>
+#include <stdarg.h>
+#include <jni.h>
+
+#include "procrun.h"
+
+#define WM_TRAYMESSAGE (WM_APP+1)
+#define WM_TIMER_TIMEOUT 10
+#define MAX_LOADSTRING 200
+#define MAX_LISTCOUNT 8192
+#define CONWRAP_SUCCESS 0
+#define CONWRAP_ENOARGS 1
+#define CONWRAP_EARG 2
+#define CONWRAP_EFATAL 3
+
+#ifndef PSH_NOCONTEXTHELP
+#define PSH_NOCONTEXTHELP 0x02000000
+#endif
+
+#define MAX_LIST_ITEMS 4000 /* maximum items in ListView */
+
+extern int g_proc_mode;
+/* The main envronment for services */
+extern procrun_t *g_env;
+
+int ac_use_try = 0;
+int ac_use_dlg = 0;
+int ac_use_show = 0;
+int ac_use_props = 0;
+int ac_use_lview = 1;
+/* default splash timeout 5 seconds */
+int ac_splash_timeout = 5000;
+int ac_lview_current = 0;
+HINSTANCE ac_instance;
+HWND ac_main_hwnd;
+HWND ac_list_hwnd;
+char *ac_cmdline;
+char *ac_cmdname;
+char *ac_splash_msg = NULL;
+
+RECT ac_winpos = {-1, 0, 640, 480};
+
+static procrun_t *ac_env = NULL;
+static HICON ac_main_icon;
+static HICON ac_try_icon;
+static HICON ac_try_stop;
+static UINT ac_taskbar_created;
+static HWND ac_console_hwnd = NULL;
+static char *ac_stdout_lines[MAX_LISTCOUNT + 1];
+static HWND ac_splash_hwnd = NULL;
+static HWND ac_splist_hwnd;
+static int ac_lv_iicon = 0;
+
+
+static prcrun_lview_t lv_columns[] = {
+ { "Type", 80 },
+ { "Message", 532 },
+ { NULL, 0 },
+};
+
+static char *lv_infos[] = {
+ "Info",
+ "Warning",
+ "Error"
+};
+
+prcrun_lview_t *ac_columns = &lv_columns[0];
+
+INT_PTR ac_show_properties(HWND owner);
+
+/* Create the list view using ac_columns struct.
+ * You may change the ac_columns to a different layout
+ * (see the tomcat.c for example)
+ */
+static void lv_create_view(HWND hdlg, LPRECT pr, LPRECT pw)
+{
+ LV_COLUMN lvc;
+ int i = 0;
+ HIMAGELIST imlist;
+ HICON hicon;
+ prcrun_lview_t *col = ac_columns;
+
+ imlist = ImageList_Create(16, 16, ILC_COLORDDB | ILC_MASK, 4, 0);
+ hicon = LoadImage(ac_instance, MAKEINTRESOURCE(IDI_ICOI),
+ IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
+ ImageList_AddIcon(imlist, hicon);
+ hicon = LoadImage(ac_instance, MAKEINTRESOURCE(IDI_ICOW),
+ IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
+ ImageList_AddIcon(imlist, hicon);
+ hicon = LoadImage(ac_instance, MAKEINTRESOURCE(IDI_ICOS),
+ IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
+ ImageList_AddIcon(imlist, hicon);
+ ImageList_AddIcon(imlist, hicon);
+
+ ac_list_hwnd = CreateWindowEx(0L, WC_LISTVIEW, "",
+ WS_VISIBLE | WS_CHILD |
+ LVS_REPORT | WS_EX_CLIENTEDGE,
+ 0, 0, pr->right - pr->left,
+ pr->bottom - abs((pw->top - pw->bottom)),
+ hdlg, NULL, ac_instance, NULL);
+ lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
+ lvc.fmt = LVCFMT_LEFT;
+
+ ListView_SetImageList(ac_list_hwnd,imlist, LVSIL_SMALL);
+
+ while (col->label) {
+ lvc.iSubItem = i;
+ lvc.cx = col->width;
+ lvc.pszText = col->label;
+ ListView_InsertColumn(ac_list_hwnd, i, &lvc );
+ ++col;
+ ++i;
+ }
+#ifdef LVS_EX_FULLROWSELECT
+ ListView_SetExtendedListViewStyleEx(ac_list_hwnd, 0,
+ LVS_EX_FULLROWSELECT |
+ LVS_EX_INFOTIP);
+#endif
+
+}
+
+/*
+ * Find the first occurrence of find in s.
+ * This is the case insesitive version of strstr
+ * that the MSVCRT is missing
+ */
+static char *
+stristr(register const char *s, register const char *find)
+{
+ register char c, sc;
+ register size_t len;
+
+ if ((c = *find++) != 0) {
+ len = strlen(find);
+ do {
+ do {
+ if ((sc = *s++) == 0)
+ return (NULL);
+ } while (sc != toupper(c));
+ } while (strnicmp(s, find, len) != 0);
+ s--;
+ }
+ return ((char *)s);
+}
+
+/* Parse the stdout messages and try to figure out what it is about.
+ * Display the icon in the list view acording to that message.
+ * If param from is nonzero (from stderr), display the error icon.
+ */
+void parse_list_string(const char *str, int from)
+{
+ int row = 0x7FFFFFFF;
+ LV_ITEM lvi;
+
+ if (!from) {
+ /* some general messages
+ * chnage to suit the particular app.
+ */
+ if (stristr(str, "INFO"))
+ ac_lv_iicon = 0;
+ else if (stristr(str, "WARNING"))
+ ac_lv_iicon = 1;
+ else if (stristr(str, "WARN "))
+ ac_lv_iicon = 1;
+ else if (stristr(str, "ERROR"))
+ ac_lv_iicon = 2;
+ else if (stristr(str, "SEVERE"))
+ ac_lv_iicon = 2;
+ }
+ else /* if this is from stderr set the error icon */
+ ac_lv_iicon = 2;
+
+ memset(&lvi, 0, sizeof(LV_ITEM));
+ lvi.mask = LVIF_IMAGE | LVIF_TEXT;
+ lvi.iItem = ac_lview_current;
+ lvi.iImage = ac_lv_iicon;
+ lvi.pszText = lv_infos[ac_lv_iicon];
+ lvi.cchTextMax = 8;
+ row = ListView_InsertItem(ac_list_hwnd, &lvi);
+ if (row == -1)
+ return;
+ ListView_SetItemText(ac_list_hwnd, row, 1, (char *)str);
+ ListView_EnsureVisible(ac_list_hwnd,
+ ListView_GetItemCount(ac_list_hwnd) - 1,
+ FALSE);
+
+ ac_lview_current++;
+}
+
+lv_parse_cb_t lv_parser = parse_list_string;
+
+/* Try icon helper
+ * Add/Change/Delete icon from the windows try.
+ */
+void ac_show_try_icon(HWND hwnd, DWORD message, const char *tip, int stop)
+{
+
+ NOTIFYICONDATA nid;
+ if (!ac_use_try)
+ return;
+
+ ZeroMemory(&nid,sizeof(nid));
+ nid.cbSize = sizeof(NOTIFYICONDATA);
+ nid.hWnd = hwnd;
+ nid.uID = 0xFF;
+ nid.uFlags = NIF_ICON | NIF_MESSAGE;
+ if (tip)
+ nid.uFlags |= NIF_TIP;
+
+ nid.uCallbackMessage = WM_TRAYMESSAGE;
+
+ if (message != NIM_DELETE)
+ nid.hIcon = stop ? ac_try_stop : ac_try_icon;
+ else
+ nid.hIcon = NULL;
+ if (tip)
+ strcpy(nid.szTip, tip);
+
+ Shell_NotifyIcon(message, &nid);
+}
+
+/* Main console dialog print function
+ * The str comes either from redirected child's stdout
+ * or stderr pipe.
+ */
+void ac_add_list_string(const char *str, int len, int from)
+{
+ static int nqueue = 0;
+ static int nlen = 0, olen = 0;
+ static int litems = 0;
+ int i;
+
+ if (str) {
+ if (ac_splash_hwnd) {
+ if (ac_splash_msg &&
+ !strnicmp(str, ac_splash_msg, strlen(ac_splash_msg))) {
+ ac_show_try_icon(ac_main_hwnd, NIM_MODIFY, ac_cmdname, 0);
+ EndDialog(ac_splash_hwnd, TRUE);
+ ac_splash_hwnd = NULL;
+ }
+ else
+ SendMessage(ac_splist_hwnd, LB_INSERTSTRING, 0, (LPARAM)str);
+ }
+ /* Ensure that we dont have more the MAX_LISTCOUNT
+ * in the queue
+ */
+ if (nqueue > MAX_LISTCOUNT - 1) {
+ free(ac_stdout_lines[0]);
+ /* TODO: improve performance */
+ for (i = 1; i < MAX_LISTCOUNT; i++)
+ ac_stdout_lines[i - 1] = ac_stdout_lines[i];
+ --nqueue;
+ }
+ /* add the string to the queue */
+ ac_stdout_lines[nqueue++] = strdup(str);
+ nlen = max(nlen, len);
+ }
+ /* If there is no window or the queue is empty return */
+ if (!ac_list_hwnd || !nqueue)
+ return;
+ /* Ok. We have the window open and something in the queue.
+ * Flush that to the screen.
+ */
+ if (ac_use_lview) {
+ for (i = 0; i < nqueue; i++) {
+ /* Call the list view callback parser */
+ (*lv_parser)(ac_stdout_lines[i], from);
+ if (litems++ > MAX_LIST_ITEMS)
+ ListView_DeleteItem(ac_list_hwnd, 0);
+ }
+ }
+ else
+ {
+ /* Flush all the lines from the queue */
+ for (i = 0; i < nqueue; i++) {
+ ListBox_AddString(ac_list_hwnd, ac_stdout_lines[i]);
+ /* Ensure no more then MAX_LIST_ITEMS are maintained.
+ * This ensures that we dont waste to much system resources.
+ */
+ if (litems++ > MAX_LIST_ITEMS)
+ ListBox_DeleteString(ac_list_hwnd, 0);
+
+ }
+ if (olen < nlen) {
+ olen = nlen;
+ SendMessage(ac_list_hwnd, LB_SETHORIZONTALEXTENT,
+ (WPARAM) 10 * olen, (LPARAM) 0);
+ }
+ }
+ /* Remove all the lines from the queue */
+ for (i = 0; i < nqueue; i++) {
+ free(ac_stdout_lines[i]);
+ ac_stdout_lines[i] = NULL;
+ }
+ nqueue = 0;
+}
+
+/* Add the item to the Try popup menu
+ */
+static void ac_append_menu_item(HMENU menu, UINT menu_id, char *name, int isdef, int enabled)
+{
+ MENUITEMINFO mii;
+
+ ZeroMemory(&mii, sizeof(MENUITEMINFO));
+ mii.cbSize = sizeof(MENUITEMINFO);
+ mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
+ if (strlen(name)) {
+ mii.fType = MFT_STRING;
+ mii.wID = menu_id;
+ if (isdef)
+ mii.fState = MFS_DEFAULT;
+ if (!enabled)
+ mii.fState |= MFS_DISABLED;
+ mii.dwTypeData = name;
+ }
+ else
+ mii.fType = MFT_SEPARATOR;
+ InsertMenuItem(menu, menu_id, FALSE, &mii);
+}
+
+/* Show the Try popup menu
+ */
+static void ac_show_try_menu(HWND hwnd)
+{
+ HMENU menu;
+ POINT pt;
+ char tmp[MAX_LOADSTRING];
+
+ if (!ac_use_try)
+ return;
+ menu = CreatePopupMenu();
+ if (menu) {
+ if (ac_use_dlg) {
+ ac_append_menu_item(menu, IDM_CONSOLE, "Open Console Monitor", 1, 1);
+ ac_append_menu_item(menu, 0, "", 0, 1);
+ }
+ ac_append_menu_item(menu, IDM_ABOUT, "About", 0, 1);
+ ac_append_menu_item(menu, IDM_OPTIONS, "Properties", 0, 1);
+ strcpy(tmp, "Shutdown: ");
+ strcat(tmp, g_env->m->service.name);
+ ac_append_menu_item(menu, IDM_EXIT, tmp, 0, 1);
+
+ if (!SetForegroundWindow(hwnd))
+ SetForegroundWindow(NULL);
+ GetCursorPos(&pt);
+ TrackPopupMenu(menu, TPM_LEFTALIGN|TPM_RIGHTBUTTON,
+ pt.x, pt.y, 0, hwnd, NULL);
+ DestroyMenu(menu);
+ }
+}
+
+/* Sopy selected items from the console dialog
+ * to the windows clipboard
+ */
+static int ac_copy_to_clipboard()
+{
+ HGLOBAL hglbcopy = NULL;
+ DWORD sel, i;
+ char buf[MAX_PATH + 2], *str;
+ int *si = NULL;
+
+ if (!OpenClipboard(NULL))
+ return -1;
+ EmptyClipboard();
+
+ if (ac_use_lview) {
+ sel = ListView_GetSelectedCount(ac_list_hwnd);
+ if (sel != LB_ERR && sel > 0) {
+ int curr;
+ str = malloc((MAX_PATH+4)*sel);
+ str[0] = '\0';
+ curr = ListView_GetNextItem(ac_list_hwnd, -1, LVNI_SELECTED);
+ for (i = 0; i < sel && curr >= 0; i++) {
+ int j;
+ for(j=0; j < 3; j++) {
+ ListView_GetItemText(ac_list_hwnd, curr, j, buf, MAX_PATH);
+ strcat(buf, j < 2 ? "\t" : "\r\n");
+ strcat(str, buf);
+ }
+ curr = ListView_GetNextItem(ac_list_hwnd, curr, LVNI_SELECTED);
+ }
+ sel = strlen(str);
+ if(sel > 0) {
+ hglbcopy = GlobalAlloc(GMEM_MOVEABLE, sel+1);
+ strcpy(GlobalLock(hglbcopy), str);
+ }
+ free(str);
+
+ }
+ }
+ else {
+ sel = SendMessage(ac_list_hwnd, LB_GETSELCOUNT, (WPARAM)0, (LPARAM)0);
+ if (sel != LB_ERR && sel > 0) {
+ si = (int *)malloc(sel * sizeof(int));
+ str = malloc((MAX_PATH + 2) * sel);
+ str[0] = '\0';
+ SendMessage(ac_list_hwnd, LB_GETSELITEMS, (WPARAM)sel, (LPARAM)si);
+ for (i = 0; i < sel; i++) {
+ SendMessage(ac_list_hwnd, LB_GETTEXT, (WPARAM)si[i], (LPARAM)buf);
+ strcat(buf, "\r\n");
+ strcat(str, buf);
+ }
+ sel = strlen(str);
+ if(sel > 0) {
+ hglbcopy = GlobalAlloc(GMEM_MOVEABLE, sel+1);
+ strcpy(GlobalLock(hglbcopy), str);
+ }
+ free(str);
+ free(si);
+ }
+ }
+
+ if(hglbcopy != NULL) {
+ GlobalUnlock(hglbcopy);
+ SetClipboardData(CF_TEXT, hglbcopy);
+ }
+ CloseClipboard();
+ return 0;
+}
+
+/* Center the hwnd on the user desktop */
+void ac_center_window(HWND hwnd)
+{
+ RECT rc, rw;
+ int cw, ch;
+ int x, y;
+ if (!ac_use_try)
+ return;
+
+ /* Get the Height and Width of the child window */
+ GetWindowRect(hwnd, &rc);
+ cw = rc.right - rc.left;
+ ch = rc.bottom - rc.top;
+
+ /* Get the limits of the 'workarea' */
+ if (!SystemParametersInfo(
+ SPI_GETWORKAREA,
+ sizeof(RECT),
+ &rw, 0)) {
+ rw.left = rw.top = 0;
+ rw.right = GetSystemMetrics(SM_CXSCREEN);
+ rw.bottom = GetSystemMetrics(SM_CYSCREEN);
+ }
+
+ /* Calculate new X and Y position*/
+ x = (rw.right - cw)/2;
+ y = (rw.bottom - ch)/2;
+ SetWindowPos(hwnd, HWND_TOP, x, y, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW);
+}
+
+static void ac_calc_center()
+{
+ RECT rWorkArea;
+ BOOL bResult;
+
+
+ /* Get the limits of the 'workarea' */
+ bResult = SystemParametersInfo(
+ SPI_GETWORKAREA,
+ sizeof(RECT),
+ &rWorkArea,
+ 0);
+ if (!bResult) {
+ rWorkArea.left = rWorkArea.top = 0;
+ rWorkArea.right = GetSystemMetrics(SM_CXSCREEN);
+ rWorkArea.bottom = GetSystemMetrics(SM_CYSCREEN);
+ }
+
+ /* Calculate new X and Y position*/
+ ac_winpos.left = (rWorkArea.right - ac_winpos.right) / 2;
+ ac_winpos.top = (rWorkArea.bottom - ac_winpos.bottom) / 2;
+}
+
+LRESULT CALLBACK ac_about_dlg_proc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ HWND hrich;
+ HRSRC rsrc;
+ HGLOBAL glob;
+ char *txt;
+
+ switch (message) {
+ case WM_INITDIALOG:
+ ac_center_window(hDlg);
+ hrich = GetDlgItem(hDlg, IDC_RICHEDIT21);
+ rsrc = FindResource(GetModuleHandle(NULL), MAKEINTRESOURCE(IDR_RTFLIC), "RTF");
+ glob = LoadResource(GetModuleHandle(NULL), rsrc);
+ txt = (char *)LockResource(glob);
+ SendMessage(hrich, WM_SETTEXT, 0, (LPARAM)txt);
+ return TRUE;
+
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) {
+ EndDialog(hDlg, LOWORD(wParam));
+ return TRUE;
+ }
+ break;
+ }
+ return FALSE;
+}
+
+LRESULT CALLBACK ac_console_dlg_proc(HWND hdlg, UINT message, WPARAM wparam, LPARAM lparam)
+{
+
+ RECT r, m;
+ static HWND status_bar;
+
+ switch (message) {
+ case WM_INITDIALOG:
+ ac_console_hwnd = hdlg;
+ SetWindowText(hdlg, ac_cmdname);
+ ac_list_hwnd = GetDlgItem(hdlg, IDL_STDOUT);
+ if (ac_use_lview)
+ ShowWindow(ac_list_hwnd, SW_HIDE);
+ status_bar = CreateStatusWindow(0x0800 /* SBT_TOOLTIPS */
+ | WS_CHILD | WS_VISIBLE,
+ ac_cmdline, hdlg, IDC_STATBAR);
+
+ if (!ac_use_try) {
+ LONG w = GetWindowLong(hdlg, GWL_STYLE);
+ w &= ~WS_MINIMIZEBOX;
+ SetWindowLong(hdlg, GWL_STYLE, w);
+ }
+
+ if (ac_winpos.left < 0)
+ ac_calc_center();
+
+ SetWindowPos(hdlg, HWND_TOP, ac_winpos.left, ac_winpos.top,
+ ac_winpos.right, ac_winpos.bottom, SWP_SHOWWINDOW);
+
+ GetWindowRect(status_bar, &r);
+ GetClientRect(hdlg, &m);
+ if (!ac_use_lview)
+ MoveWindow(ac_list_hwnd, 0, 0, m.right - m.left, m.bottom - abs((r.top - r.bottom)), TRUE);
+ else
+ lv_create_view(hdlg, &m, &r);
+
+ ac_add_list_string(NULL, 0, 0);
+ SetForegroundWindow(ac_console_hwnd);
+ SetActiveWindow(ac_console_hwnd);
+
+ break;
+ case WM_SIZE:
+ switch (LOWORD(wparam)) {
+ case SIZE_MINIMIZED:
+ GetWindowRect(hdlg, &ac_winpos);
+ if (!ac_use_try) {
+ ShowWindow(hdlg, SW_RESTORE);
+ return FALSE;
+ }
+ ShowWindow(hdlg, SW_HIDE);
+ return TRUE;
+ break;
+ default:
+ GetWindowRect(status_bar, &r);
+ MoveWindow(status_bar, 0, HIWORD(lparam) - (r.top - r.bottom),
+ LOWORD(lparam), (r.top - r.bottom), TRUE);
+ GetClientRect(hdlg, &m);
+ MoveWindow(ac_list_hwnd, 0, 0, LOWORD(lparam), HIWORD(lparam) - abs((r.top - r.bottom)), TRUE);
+ break;
+ }
+ break;
+ case WM_COMMAND:
+ switch (LOWORD(wparam)) {
+ case IDM_MENU_EXIT:
+ EndDialog(hdlg, TRUE);
+ ac_list_hwnd = NULL;
+ ac_console_hwnd = NULL;
+ ac_show_try_icon(ac_main_hwnd, NIM_MODIFY, ac_cmdname, 1);
+ SetEvent(g_env->m->events[0]);
+ break;
+ case IDM_MENU_EDIT:
+ ac_copy_to_clipboard();
+ break;
+ case IDM_MENU_ABOUT:
+ DialogBox(ac_instance, MAKEINTRESOURCE(IDD_ABOUTBOX),
+ hdlg, (DLGPROC)ac_about_dlg_proc);
+ break;
+ }
+ break;
+ case WM_QUIT:
+ case WM_CLOSE:
+ GetWindowRect(hdlg, &ac_winpos);
+ if (!ac_use_try) {
+ EndDialog(hdlg, TRUE);
+ ac_list_hwnd = NULL;
+ ac_console_hwnd = NULL;
+ SetEvent(g_env->m->events[0]);
+ PostQuitMessage(CONWRAP_SUCCESS);
+ }
+ else
+ ShowWindow(ac_console_hwnd, SW_HIDE);
+ return TRUE;
+ default:
+ return FALSE;
+ }
+
+ return FALSE;
+}
+
+/* Browse dialog.
+ * Brose either for file or folder.
+ * TODO: add some file filters.
+ */
+int ac_browse_for_dialog(HWND hwnd, char *str, size_t len, int files)
+{
+ int rv = 0;
+
+ BROWSEINFO bi;
+ ITEMIDLIST *il , *ir;
+ LPMALLOC pMalloc;
+
+ memset(&bi, 0, sizeof(BROWSEINFO));
+ SHGetSpecialFolderLocation(hwnd, CSIDL_DRIVES, &il);
+ if (files)
+ bi.lpszTitle = PROCRUN_GUI_DISPLAY " :\nSelect Folder!";
+ else
+ bi.lpszTitle = PROCRUN_GUI_DISPLAY " :\nSelect File!";
+ bi.pszDisplayName = str;
+ bi.hwndOwner = hwnd;
+ bi.ulFlags = BIF_EDITBOX;
+ if (files)
+ bi.ulFlags |= BIF_BROWSEINCLUDEFILES;
+
+ bi.lpfn = NULL;
+ bi.lParam = 0;
+ bi.iImage = 0;
+ bi.pidlRoot = il;
+
+ if ((ir = SHBrowseForFolder(&bi)) != NULL) {
+ SHGetPathFromIDList(ir, str);
+
+ rv = 1;
+ }
+ if (SHGetMalloc(&pMalloc)) {
+ pMalloc->lpVtbl->Free(pMalloc, il);
+ pMalloc->lpVtbl->Release(pMalloc);
+ }
+ return rv;
+
+}
+
+/* Service option dialogs
+ */
+void CALLBACK PropSheetCallback(HWND hwndPropSheet, UINT uMsg, LPARAM lParam)
+{
+ switch(uMsg) {
+ case PSCB_PRECREATE:
+ {
+ LPDLGTEMPLATE lpTemplate = (LPDLGTEMPLATE)lParam;
+ if (!(lpTemplate->style & WS_SYSMENU))
+ lpTemplate->style |= WS_SYSMENU;
+
+ }
+ break;
+ case PSCB_INITIALIZED:
+ break;
+
+ }
+}
+
+LRESULT CALLBACK dlg_service_proc(HWND hdlg,
+ UINT uMessage,
+ WPARAM wParam,
+ LPARAM lParam)
+{
+
+ LPNMHDR lpnmhdr;
+ int argc = 2;
+ char *argv[10];
+ char txt[4096];
+ process_t p;
+
+ switch (uMessage) {
+ case WM_COMMAND:
+ PropSheet_Changed(GetParent(hdlg), hdlg);
+ switch (LOWORD(wParam)) {
+ case RC_BTN_BIP:
+ if (ac_browse_for_dialog(hdlg, txt, 1024, 1))
+ SetDlgItemText(hdlg, RC_TXT_IP,
+ txt);
+ return TRUE;
+ break;
+ case RC_BTN_BWP:
+ if (ac_browse_for_dialog(hdlg, txt, 1024, 0))
+ SetDlgItemText(hdlg, RC_TXT_WP,
+ txt);
+ return TRUE;
+ break;
+ }
+ break;
+ case WM_INITDIALOG:
+ ac_center_window(GetParent(hdlg));
+ SetDlgItemText(hdlg, RC_TXT_SN, g_env->m->service.display ?
+ g_env->m->service.display : g_env->m->service.name);
+ SetDlgItemText(hdlg, RC_TXT_SD, g_env->m->service.description);
+ SetDlgItemText(hdlg, RC_TXT_IP, g_env->m->service.image);
+ SetDlgItemText(hdlg, RC_TXT_WP, g_env->m->service.path);
+ SetDlgItemText(hdlg, RC_TXT_UN, g_env->m->service.account);
+ SetDlgItemText(hdlg, RC_TXT_UP, g_env->m->service.password);
+ if (g_env->m->service.startup == SERVICE_AUTO_START)
+ CheckDlgButton(hdlg, RC_CHK_AUTO, BST_CHECKED);
+
+ break;
+
+ case WM_NOTIFY:
+ lpnmhdr = (NMHDR FAR *)lParam;
+
+ switch (lpnmhdr->code) {
+ case PSN_APPLY: /* sent when OK or Apply button pressed */
+ memcpy(&p, g_env->m, sizeof(process_t));
+ p.pool = pool_create();
+ p.service.name = g_env->m->service.name;
+ argc = 2;
+ if (GetDlgItemText(hdlg, RC_TXT_SD, txt, 4095) > 0) {
+ argv[argc++] = "--" PROCRUN_PARAMS_DESCRIPTION;
+ argv[argc++] = &txt[0];
+ argv[argc] = NULL;
+ procrun_update_service(&p, argc, argv);
+ }
+ if (GetDlgItemText(hdlg, RC_TXT_IP, txt, 4095) > 0) {
+ argc = 2;
+ argv[argc++] = "--" PROCRUN_PARAMS_IMAGE;
+ argv[argc++] = &txt[0];
+ argv[argc] = NULL;
+ procrun_update_service(&p, argc, argv);
+ }
+ if (GetDlgItemText(hdlg, RC_TXT_WP, txt, 4095) > 0) {
+ argc = 2;
+ argv[argc++] = "--" PROCRUN_PARAMS_WORKPATH;
+ argv[argc++] = &txt[0];
+ argv[argc] = NULL;
+ procrun_update_service(&p, argc, argv);
+ }
+ if (GetDlgItemText(hdlg, RC_TXT_UN, txt, 64) > 0) {
+ argc = 2;
+ argv[argc++] = "--" PROCRUN_PARAMS_ACCOUNT;
+ argv[argc++] = &txt[0];
+ argv[argc] = NULL;
+ if (GetDlgItemText(hdlg, RC_TXT_UP, &txt[128], 64) > 0) {
+ argv[argc++] = "--" PROCRUN_PARAMS_PASSWORD;
+ argv[argc++] = &txt[128];
+ procrun_update_service(&p, argc, argv);
+ }
+ }
+ else if (g_env->m->service.account) {
+ argc = 2;
+ argv[argc++] = "--" PROCRUN_PARAMS_ACCOUNT;
+ argv[argc++] = "-";
+ argv[argc++] = "--" PROCRUN_PARAMS_PASSWORD;
+ argv[argc++] = "-";
+ argv[argc] = NULL;
+ procrun_update_service(&p, argc, argv);
+ }
+ /* TODO: check if the param is changed */
+ argc = 2;
+ argv[argc++] = "--" PROCRUN_PARAMS_STARTUP;
+ if (IsDlgButtonChecked(hdlg, RC_CHK_AUTO))
+ argv[argc++] = "auto";
+ else
+ argv[argc++] = "manual";
+
+ argv[argc] = NULL;
+ procrun_update_service(&p, argc, argv);
+ pool_destroy(p.pool);
+ break;
+ case PSN_RESET: /* sent when Cancel button pressed */
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return FALSE;
+}
+
+LRESULT CALLBACK dlg_java_proc(HWND hdlg,
+ UINT uMessage,
+ WPARAM wParam,
+ LPARAM lParam)
+{
+
+ LPNMHDR lpnmhdr;
+ int argc = 2;
+ char *argv[10];
+ char txt[4096];
+ process_t p;
+ char *s, *d;
+
+ switch (uMessage) {
+ case WM_COMMAND:
+ PropSheet_Changed(GetParent(hdlg), hdlg);
+ switch (LOWORD(wParam)) {
+ case RC_BTN_JVM:
+ if (ac_browse_for_dialog(hdlg, txt, 1024, 1))
+ SetDlgItemText(hdlg, RC_TXT_JVM,
+ txt);
+ return TRUE;
+ break;
+ }
+
+ break;
+ case WM_INITDIALOG:
+ SetDlgItemText(hdlg, RC_TXT_JVM, g_env->m->java.display);
+ sprintf(txt, "%s;%s;%s", g_env->m->java.start_class,
+ g_env->m->java.start_method,
+ g_env->m->java.start_param);
+ SetDlgItemText(hdlg, RC_TXT_SC, txt);
+ sprintf(txt, "%s;%s;%s", g_env->m->java.stop_class,
+ g_env->m->java.stop_method,
+ g_env->m->java.stop_param);
+ SetDlgItemText(hdlg, RC_TXT_EC, txt);
+ if (g_env->m->java.display &&
+ !strcmp(g_env->m->java.display, "auto"))
+ CheckDlgButton(hdlg, RC_CHK_JVM, BST_CHECKED);
+
+ memset(txt, 0, 4096);
+ d = &txt[0];
+ for (s = g_env->m->java.opts; s && *s; s++) {
+ sprintf(d, "%s\r\n", s);
+ d += strlen(d);
+ while (*s)
+ s++;
+ }
+ SetDlgItemText(hdlg, RC_TXT_JO, txt);
+ break;
+ case WM_NOTIFY:
+ lpnmhdr = (NMHDR FAR *)lParam;
+
+ switch (lpnmhdr->code) {
+ case PSN_APPLY: /* sent when OK or Apply button pressed */
+ memcpy(&p, g_env->m, sizeof(process_t));
+ argc = 2;
+ p.pool = pool_create();
+ if (IsDlgButtonChecked(hdlg, RC_CHK_JVM)) {
+ argv[argc++] = "--" PROCRUN_PARAMS_JVM;
+ argv[argc++] = "auto";
+ }
+ else if (GetDlgItemText(hdlg, RC_TXT_JVM, txt, 4095) > 0) {
+ argv[argc++] = "--" PROCRUN_PARAMS_JVM;
+ argv[argc++] = &txt[0];
+ }
+ if (argc > 2)
+ procrun_update_service(&p, argc, argv);
+
+ if (GetDlgItemText(hdlg, RC_TXT_SC, txt, 4095) > 0) {
+ argc = 2;
+ argv[argc++] = "--" PROCRUN_PARAMS_STARTCLASS;
+ argv[argc++] = &txt[0];
+ procrun_update_service(&p, argc, argv);
+ }
+ if (GetDlgItemText(hdlg, RC_TXT_EC, txt, 4095) > 0) {
+ argc = 2;
+ argv[argc++] = "--" PROCRUN_PARAMS_STOPCLASS;
+ argv[argc++] = &txt[0];
+ procrun_update_service(&p, argc, argv);
+ }
+ if (GetDlgItemText(hdlg, RC_TXT_JO, txt, 4095) > 0) {
+ char *c = &txt[0];
+ char b[4096] = {0};
+ int i = 0;
+ argc = 2;
+ while (*c) {
+ if (*c == '\n')
+ b[i++] = '#';
+ else if (*c != '\r')
+ b[i++] = *c;
+ ++c;
+ }
+ b[i] = '\0';
+ argv[argc++] = "--" PROCRUN_PARAMS_JVM_OPTS;
+ argv[argc++] = &b[0];
+ procrun_update_service(&p, argc, argv);
+ }
+ pool_destroy(p.pool);
+ break;
+ case PSN_RESET: /* sent when Cancel button pressed */
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return FALSE;
+}
+
+LRESULT CALLBACK dlg_stream_proc(HWND hdlg,
+ UINT uMessage,
+ WPARAM wParam,
+ LPARAM lParam)
+{
+
+ LPNMHDR lpnmhdr;
+ int argc = 2;
+ char *argv[10];
+ char txt[4096];
+ process_t p;
+
+ switch (uMessage) {
+ case WM_COMMAND:
+ PropSheet_Changed(GetParent(hdlg), hdlg);
+ switch (LOWORD(wParam)) {
+ case RC_BTN_STDI:
+ if (ac_browse_for_dialog(hdlg, txt, 1024, 1))
+ SetDlgItemText(hdlg, RC_TXT_STDI,
+ txt);
+ return TRUE;
+ break;
+ case RC_BTN_STDO:
+ if (ac_browse_for_dialog(hdlg, txt, 1024, 1))
+ SetDlgItemText(hdlg, RC_TXT_STDO,
+ txt);
+ return TRUE;
+ break;
+ case RC_BTN_STDE:
+ if (ac_browse_for_dialog(hdlg, txt, 1024, 1))
+ SetDlgItemText(hdlg, RC_TXT_STDE,
+ txt);
+ return TRUE;
+ break;
+ }
+
+ break;
+ case WM_INITDIALOG:
+ SetDlgItemText(hdlg, RC_TXT_STDI, g_env->m->service.inname);
+ SetDlgItemText(hdlg, RC_TXT_STDO, g_env->m->service.outname);
+ SetDlgItemText(hdlg, RC_TXT_STDE, g_env->m->service.errname);
+
+ break;
+
+ case WM_NOTIFY:
+ lpnmhdr = (NMHDR FAR *)lParam;
+
+ switch (lpnmhdr->code) {
+ case PSN_APPLY: /* sent when OK or Apply button pressed */
+ memcpy(&p, g_env->m, sizeof(process_t));
+ p.pool = pool_create();
+ if (GetDlgItemText(hdlg, RC_TXT_STDI, txt, 4095) > 0) {
+ argc = 2;
+ argv[argc++] = "--" PROCRUN_PARAMS_STDINFILE;
+ argv[argc++] = &txt[0];
+ procrun_update_service(&p, argc, argv);
+ }
+ if (GetDlgItemText(hdlg, RC_TXT_STDO, txt, 4095) > 0) {
+ argc = 2;
+ argv[argc++] = "--" PROCRUN_PARAMS_STDOUTFILE;
+ argv[argc++] = &txt[0];
+ procrun_update_service(&p, argc, argv);
+ }
+ if (GetDlgItemText(hdlg, RC_TXT_STDE, txt, 4095) > 0) {
+ argc = 2;
+ argv[argc++] = "--" PROCRUN_PARAMS_STDERRFILE;
+ argv[argc++] = &txt[0];
+ procrun_update_service(&p, argc, argv);
+ }
+ pool_destroy(p.pool);
+
+ break;
+ case PSN_RESET: /* sent when Cancel button pressed */
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return FALSE;
+}
+
+
+INT_PTR ac_show_properties(HWND owner)
+{
+ PROPSHEETPAGE psp[3];
+ PROPSHEETHEADER psh;
+ char title[256];
+
+ strcpy(title, ac_cmdline);
+ strcat(title, " Service properties");
+ psp[0].dwSize = sizeof(PROPSHEETPAGE);
+ psp[0].dwFlags = PSP_USETITLE;
+ psp[0].hInstance = ac_instance;
+ psp[0].pszTemplate = MAKEINTRESOURCE(RC_DLG_SRVOPT);
+ psp[0].pszIcon = NULL;
+ psp[0].pfnDlgProc = (DLGPROC)dlg_service_proc;
+ psp[0].pszTitle = TEXT("Service");
+ psp[0].lParam = 0;
+
+ psp[1].dwSize = sizeof(PROPSHEETPAGE);
+ psp[1].dwFlags = PSP_USETITLE;
+ psp[1].hInstance = ac_instance;
+ psp[1].pszTemplate = MAKEINTRESOURCE(RC_DLG_JVMOPT);
+ psp[1].pszIcon = NULL;
+ psp[1].pfnDlgProc = (DLGPROC)dlg_java_proc;
+ psp[1].pszTitle = TEXT("Java VM");
+ psp[1].lParam = 0;
+
+ psp[2].dwSize = sizeof(PROPSHEETPAGE);
+ psp[2].dwFlags = PSP_USETITLE;
+ psp[2].hInstance = ac_instance;
+ psp[2].pszTemplate = MAKEINTRESOURCE(RC_DLG_STDOPT);
+ psp[2].pszIcon = NULL;
+ psp[2].pfnDlgProc = (DLGPROC)dlg_stream_proc;
+ psp[2].pszTitle = TEXT("Standard Streams");
+ psp[2].lParam = 0;
+
+ psh.dwSize = sizeof(PROPSHEETHEADER);
+ psh.dwFlags = PSH_PROPSHEETPAGE | PSH_USEICONID | PSH_USECALLBACK | PSH_NOCONTEXTHELP;
+ psh.hwndParent = owner;
+ psh.hInstance = ac_instance;
+ psh.pszIcon = MAKEINTRESOURCE(IDI_ICOCONWRAP);
+#if (_WIN32_IE >= 0x0500)
+ psh.pszbmHeader = MAKEINTRESOURCE(IDB_BMPJAKARTA);
+#endif
+ psh.pszCaption = title;
+ psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
+ psh.ppsp = (LPCPROPSHEETPAGE) &psp;
+ psh.pfnCallback = (PFNPROPSHEETCALLBACK)PropSheetCallback;
+ psh.nStartPage = 0;
+ return PropertySheet(&psh);
+}
+
+
+LRESULT CALLBACK ac_splash_dlg_proc(HWND hdlg, UINT message, WPARAM wparam, LPARAM lparam)
+{
+
+ switch (message) {
+ case WM_INITDIALOG:
+ ac_splash_hwnd = hdlg;
+ ac_center_window(hdlg);
+ ac_splist_hwnd = GetDlgItem(hdlg, IDL_INFO);
+ break;
+ }
+
+ return FALSE;
+}
+
+/* main (invisible) window procedure
+ *
+ */
+LRESULT CALLBACK ac_main_wnd_proc(HWND hwnd, UINT message,
+ WPARAM wparam, LPARAM lparam)
+{
+ if (message == ac_taskbar_created) {
+ /* restore the tray icon on shell restart */
+ ac_show_try_icon(hwnd, NIM_ADD, ac_cmdname, 0);
+ return DefWindowProc(hwnd, message, wparam, lparam);
+ }
+ switch (message) {
+ case WM_CREATE:
+ ac_main_hwnd = hwnd;
+ if (ac_use_props) {
+ PostMessage(hwnd, WM_COMMAND, IDM_OPTIONS, 0);
+ return FALSE;
+ }
+
+ if (ac_use_try)
+ ac_show_try_icon(hwnd, NIM_ADD, ac_cmdname, 1);
+ /* add the 20 s timer for startup to avoid zombie spash
+ * if something goes wrong.
+ */
+ SetTimer(hwnd, WM_TIMER_TIMEOUT, ac_splash_timeout, NULL);
+ if (ac_use_try) {
+ DialogBox(ac_instance, MAKEINTRESOURCE(IDD_DLGSPLASH),
+ hwnd, (DLGPROC)ac_splash_dlg_proc);
+ }
+ if (ac_use_show) {
+ DialogBox(ac_instance, MAKEINTRESOURCE(IDD_DLGCONSOLE),
+ hwnd, (DLGPROC)ac_console_dlg_proc);
+ }
+ break;
+ case WM_TIMER:
+ switch (wparam) {
+ case WM_TIMER_TIMEOUT:
+ if (ac_use_try)
+ ac_show_try_icon(hwnd, NIM_MODIFY, ac_cmdname, 0);
+ if (ac_use_try && ac_splash_hwnd)
+ EndDialog(ac_splash_hwnd, TRUE);
+ break;
+ }
+ break;
+ case WM_DESTROY:
+ case WM_QUIT:
+ if (ac_use_try);
+ ac_show_try_icon(hwnd, NIM_DELETE, NULL, 0);
+ SetEvent(g_env->m->events[0]);
+ break;
+ case WM_TRAYMESSAGE:
+ switch(lparam) {
+ case WM_LBUTTONDBLCLK:
+ if (ac_console_hwnd) {
+ ShowWindow(ac_console_hwnd, SW_SHOW);
+ ShowWindow(ac_console_hwnd, SW_RESTORE);
+ }
+ else
+ DialogBox(ac_instance, MAKEINTRESOURCE(IDD_DLGCONSOLE),
+ hwnd, (DLGPROC)ac_console_dlg_proc);
+ SetForegroundWindow(ac_console_hwnd);
+ SetActiveWindow(ac_console_hwnd);
+ break;
+ case WM_RBUTTONUP:
+ ac_show_try_menu(hwnd);
+ break;
+ }
+ break;
+ case WM_COMMAND:
+ switch (LOWORD(wparam)) {
+ case IDM_EXIT:
+ ac_show_try_icon(hwnd, NIM_MODIFY, ac_cmdname, 1);
+ SetEvent(g_env->m->events[0]);
+ return TRUE;
+ break;
+ case IDM_CONSOLE:
+ if (ac_console_hwnd) {
+ ShowWindow(ac_console_hwnd, SW_SHOW);
+ ShowWindow(ac_console_hwnd, SW_RESTORE);
+ }
+ else
+ DialogBox(ac_instance, MAKEINTRESOURCE(IDD_DLGCONSOLE),
+ hwnd, (DLGPROC)ac_console_dlg_proc);
+ break;
+ case IDM_ABOUT:
+ DialogBox(ac_instance, MAKEINTRESOURCE(IDD_ABOUTBOX),
+ hwnd, (DLGPROC)ac_about_dlg_proc);
+ break;
+ case IDM_OPTIONS:
+ ac_show_properties(NULL);
+ if (ac_use_props)
+ PostMessage(hwnd, WM_QUIT, 0, 0);
+
+ break;
+ }
+ default:
+ return DefWindowProc(hwnd, message, wparam, lparam);
+ }
+
+ return FALSE;
+}
+
+/* Create main invisible window */
+static HWND ac_create_main_window(HINSTANCE instance, const char *wclass, const char *title)
+{
+ HWND hwnd = NULL;
+ WNDCLASSEX wcex;
+
+ wcex.cbSize = sizeof(WNDCLASSEX);
+
+ wcex.style = CS_HREDRAW | CS_VREDRAW;
+ wcex.lpfnWndProc = ac_main_wnd_proc;
+ wcex.cbClsExtra = 0;
+ wcex.cbWndExtra = 0;
+ wcex.hInstance = instance;
+ wcex.hIcon = ac_main_icon = (HICON)LoadImage(instance, MAKEINTRESOURCE(IDI_ICOCONWRAP),
+ IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR);
+ wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
+ wcex.lpszMenuName = 0;
+ wcex.lpszClassName = wclass;
+ wcex.hIconSm = (HICON)LoadImage(instance, MAKEINTRESOURCE(IDI_ICOCONWRAP),
+ IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
+ ac_try_icon = (HICON)LoadImage(instance, MAKEINTRESOURCE(IDI_ICOCONTRY),
+ IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
+ ac_try_stop = (HICON)LoadImage(instance, MAKEINTRESOURCE(IDI_ICOCONTRYSTOP),
+ IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
+ if (RegisterClassEx(&wcex))
+ hwnd = CreateWindow(wclass, title,
+ 0, 0, 0, 0, 0,
+ NULL, NULL, instance, NULL);
+
+
+ return hwnd;
+
+}
+
+/* Main GUI application thread
+ * launched from procrun_main.
+ */
+DWORD WINAPI gui_thread(LPVOID param)
+{
+ DWORD rv = 0;
+ MSG msg;
+ /* single instance mutex */
+ HANDLE mutex;
+
+ procrun_t *env = ac_env = (procrun_t *)param;
+ char cname[MAX_LOADSTRING];
+ char cmutex[MAX_PATH];
+
+ if (!param || !env->m->service.name)
+ return -1;
+ strcpy(cname, env->m->service.name);
+ strcat(cname, "_CLASS");
+ strcpy(cmutex, env->m->service.name);
+ strcat(cmutex, "_MUTEX");
+ if (env->m->service.description)
+ ac_cmdline = env->m->service.description;
+ else
+ ac_cmdline = env->m->service.name;
+ if (env->m->service.display)
+ ac_cmdname = env->m->service.display;
+ else
+ ac_cmdname = env->m->service.name;
+
+ /* Ensure that only one instance of a service is running
+ * TODO: Allow the //ES// and //MS// to run withouth that
+ * restriction, but reather use that mutex to signal
+ * the //GT// of a params change.
+ */
+ mutex = CreateMutex(NULL, FALSE, cmutex);
+ if ((mutex == NULL) || (GetLastError() == ERROR_ALREADY_EXISTS)) {
+ char msg[2048];
+ sprintf(msg, "Starting: %s\nApplication is already running",
+ env->m->service.name);
+ MessageBox(NULL, msg, "Second instance",
+ MB_OK | MB_ICONEXCLAMATION | MB_SYSTEMMODAL);
+ if (mutex)
+ CloseHandle(mutex);
+ SetEvent(env->m->events[0]);
+ return 0;
+ }
+
+#if defined(PROCRUN_EXTENDED)
+ /* Init all the extended properties
+ * like splash, listview, etc..
+ *
+ */
+ acx_init_extended();
+#endif
+ ac_main_hwnd = ac_create_main_window(ac_instance, cname,
+ env->m->service.name);
+
+ InitCommonControls();
+ if (ac_main_hwnd) {
+ if (ac_use_try)
+ ac_taskbar_created = RegisterWindowMessage("TaskbarCreated");
+ /* Main message loop */
+ while (GetMessage(&msg, NULL, 0, 0)) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ }
+ if (mutex)
+ CloseHandle(mutex);
+ ac_main_hwnd = NULL;
+ /* Signal to procrun_main we are done */
+ SetEvent(env->m->events[0]);
+ return rv;
+}
+
+#endif /* PROCRUN_WINAPP */
diff --git a/src/native/nt/procrun/procrun.c b/src/native/nt/procrun/procrun.c
new file mode 100644
index 0000000..0f5de34
--- /dev/null
+++ b/src/native/nt/procrun/procrun.c
@@ -0,0 +1,3306 @@
+/* ====================================================================
+ Copyright 2002-2004 The Apache Software Foundation.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/* ====================================================================
+ * procrun
+ *
+ * Contributed by Mladen Turk <mturk at apache.org>
+ *
+ * 05 Aug 2002
+ * ====================================================================
+ */
+
+#ifndef STRICT
+#define STRICT
+#endif
+#ifndef OEMRESOURCE
+#define OEMRESOURCE
+#endif
+
+#include <windows.h>
+#include <windowsx.h>
+#include <commctrl.h>
+#include <objbase.h>
+#include <shlobj.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <Shlwapi.h>
+#include <io.h>
+#include <fcntl.h>
+#include <process.h>
+#include <time.h>
+#include <stdarg.h>
+#include <jni.h>
+
+#include "procrun.h"
+
+typedef HANDLE (__stdcall * PFNCREATERTHRD)(HANDLE, LPSECURITY_ATTRIBUTES,
+ DWORD, LPTHREAD_START_ROUTINE,
+ LPVOID, DWORD, LPDWORD);
+typedef jint (JNICALL *JNI_GETDEFAULTJAVAVMINITARGS)(void *);
+typedef jint (JNICALL *JNI_CREATEJAVAVM)(JavaVM **, JNIEnv **, void *);
+typedef jint (JNICALL *JNI_GETCREATEDJAVAVMS)(JavaVM **, int, int *);
+
+JNI_GETDEFAULTJAVAVMINITARGS jni_JNI_GetDefaultJavaVMInitArgs = NULL;
+JNI_CREATEJAVAVM jni_JNI_CreateJavaVM = NULL;
+JNI_GETCREATEDJAVAVMS jni_JNI_GetCreatedJavaVMs = NULL;
+
+int report_service_status(DWORD, DWORD, DWORD, process_t *);
+int procrun_redirect(char *program, char **envp, procrun_t *env, int starting);
+
+static int g_proc_stderr_file = 0;
+int g_proc_mode = 0;
+/* The main envronment for services */
+procrun_t *g_env = NULL;
+static int g_is_windows_nt = 0;
+
+#ifdef PROCRUN_WINAPP
+
+
+#endif
+
+#ifdef _DEBUG
+void log_write(char *string)
+{
+ FILE *fd;
+ fd = fopen("c:\\jakarta-service.txt","a");
+ if (fd == NULL)
+ return;
+ fprintf(fd,string);
+ if (string[strlen(string)-1]!='\n')
+ fprintf(fd,"\n");
+ fclose(fd);
+}
+void dbprintf(char *format, ...)
+{
+ va_list args;
+ char tid[4096 + 128];
+ char buffer[4096];
+ int len;
+
+ if (!format) {
+ len = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ GetLastError(),
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ buffer,
+ 4096,
+ NULL);
+ }
+ else {
+ va_start(args, format);
+ len = _vsnprintf(buffer, 4096, format, args);
+ va_end(args);
+ }
+ if (len > 0) {
+ sprintf(tid, "[%04X:%08d] %s", GetCurrentThreadId(),time(NULL), buffer);
+ if (g_proc_stderr_file > 0)
+ write(g_proc_stderr_file, tid, strlen(tid));
+ else
+ fprintf(stderr,tid);
+ log_write(tid);
+#ifdef _DEBUG_TRACE
+ OutputDebugString(tid);
+#endif
+ }
+}
+#define DBPRINTF0(v1) dbprintf(v1)
+#define DBPRINTF1(v1, v2) dbprintf(v1, v2)
+#define DBPRINTF2(v1, v2, v3) dbprintf(v1, v2, v3)
+#else
+#define DBPRINTF0(v1)
+#define DBPRINTF1(v1, v2)
+#define DBPRINTF2(v1, v2, v3)
+#endif
+
+/* Create the memory pool.
+ * Memory pool is fixed size (PROC_POOL_SIZE -> 128 by default)
+ * It ensures that all the memory and HANDELS gets freed
+ * when the procrun exits
+ */
+pool_t *pool_create()
+{
+ pool_t *pool = malloc(sizeof(pool_t));
+ if (pool) {
+ InitializeCriticalSection(&pool->lock);
+ pool->size = 0;
+ pool->mp[0].m = NULL;
+ pool->mp[0].h = NULL;
+ }
+ return pool;
+}
+
+/* Destroy the memory pool
+ * each pool slot can have allocated memory block
+ * and/or associated windows HANDLE that can be
+ * release with CloseHandle.
+ */
+int pool_destroy(pool_t *pool)
+{
+ int i = 0;
+ for (i = 0; i < pool->size; i++) {
+ if (pool->mp[i].m) {
+ free(pool->mp[i].m);
+ }
+ if (pool->mp[i].h != INVALID_HANDLE_VALUE && pool->mp[i].h != NULL) {
+ CloseHandle(pool->mp[i].h);
+ }
+ }
+ DeleteCriticalSection(&pool->lock);
+ free(pool);
+ return i;
+}
+
+/* Allocation functions
+ * They doesn't check for overflow
+ */
+static void *pool_alloc(pool_t *pool, size_t size)
+{
+ void *m = malloc(size);
+ EnterCriticalSection(&pool->lock);
+ pool->mp[pool->size].h = INVALID_HANDLE_VALUE;
+ pool->mp[pool->size++].m = m;
+ LeaveCriticalSection(&pool->lock);
+ return m;
+}
+
+static void *pool_calloc(pool_t *pool, size_t size)
+{
+ void *m = calloc(size, 1);
+ EnterCriticalSection(&pool->lock);
+ pool->mp[pool->size].h = INVALID_HANDLE_VALUE;
+ pool->mp[pool->size++].m = m;
+ LeaveCriticalSection(&pool->lock);
+ return m;
+}
+
+static char *pool_strdup(pool_t *pool, const char *src)
+{
+ char *s = strdup(src);
+ EnterCriticalSection(&pool->lock);
+ pool->mp[pool->size].h = INVALID_HANDLE_VALUE;
+ pool->mp[pool->size++].m = s;
+ LeaveCriticalSection(&pool->lock);
+ return s;
+}
+
+/* Attach the Handle to the pool
+ * The handle will be released on pool_destroy
+ * using CloseHandle API call
+ */
+static void *pool_handle(pool_t *pool, HANDLE h)
+{
+ EnterCriticalSection(&pool->lock);
+ pool->mp[pool->size].h = h;
+ pool->mp[pool->size++].m = NULL;
+ LeaveCriticalSection(&pool->lock);
+ return h;
+}
+
+static BOOL pool_close_handle(pool_t *pool, HANDLE h)
+{
+ int i;
+ EnterCriticalSection(&pool->lock);
+ for(i=0; i < pool->size; i++) {
+ if(pool->mp[i].h == h)
+ pool->mp[i].h = INVALID_HANDLE_VALUE;
+ }
+ LeaveCriticalSection(&pool->lock);
+ return CloseHandle(h);
+}
+
+/* Very simple encryption for hiding password
+ * they can be easily decrypted cause the key
+ * is hadcoded (100) in the code.
+ * It can be easily cracked if someone finds that needed.
+ * XXX: The solution is to either use the CryproAPI
+ * or our own account management.
+ */
+static void simple_encrypt(int seed, const char *str, unsigned char bytes[256])
+{
+ int i;
+ char sc[256];
+
+ srand(seed);
+ memset(sc, 0, 256);
+ strncpy(sc, str, 255);
+ for (i = 0; i < 256; i ++) {
+ bytes[i] = ((rand() % 256) ^ sc[i]);
+ }
+}
+
+static void simple_decrypt(int seed, char *str, unsigned char bytes[256])
+{
+ int i;
+ char sc[256];
+
+ srand(seed);
+ for (i = 0; i < 256; i ++) {
+ sc[i] = ((rand() % 256) ^ bytes[i]);
+ }
+ strcpy(str, sc);
+}
+
+/* Injects the 'ExitProcess' to the child
+ * The function tries to kill the child process
+ * without using 'hard' mathods like TerminateChild.
+ * At first it sends the CTRL+C and CTRL+BREAK to the
+ * child process. If that fails (the child doesn't exit)
+ * it creates the remote thread in the address space of
+ * the child process, and calls the ExitProcess function,
+ * inside the child process.
+ * Finaly it calls the TerminateProcess all of the above
+ * fails.
+ * Well designed console clients usually exits on closing
+ * stdin stream, so this function not be called in most cases.
+ */
+static void inject_exitprocess(PROCESS_INFORMATION *child)
+{
+ PFNCREATERTHRD pfn_CreateRemoteThread;
+ UINT exit_code = 2303;
+ HANDLE rt = NULL, dup = NULL;
+ DWORD rtid, stat;
+ BOOL isok;
+
+ if (!child || !child->hProcess) {
+ DBPRINTF0("No process\n");
+ return;
+ }
+ if (!GetExitCodeProcess(child->hProcess, &stat) ||
+ (stat != STILL_ACTIVE)) {
+ DBPRINTF1("The child process %d isn't active any more\n",
+ child->dwProcessId);
+ child->hProcess = NULL;
+ child->dwProcessId = 0;
+ return;
+ }
+ GenerateConsoleCtrlEvent(CTRL_C_EVENT, child->dwProcessId);
+ GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, child->dwProcessId);
+#if 1
+ /* Wait for a child to capture CTRL_ events. */
+ WaitForSingleObject(child->hThread, 2000);
+#endif
+ if (!GetExitCodeProcess(child->hProcess, &stat) ||
+ (stat != STILL_ACTIVE)) {
+ child->hProcess = NULL;
+ child->dwProcessId = 0;
+ DBPRINTF0("Breaked by CTRL+C event\n");
+ return;
+ }
+ DBPRINTF1("Injecting ExitProcess to the child process %d\n",
+ child->dwProcessId);
+
+ pfn_CreateRemoteThread = (PFNCREATERTHRD)GetProcAddress(
+ GetModuleHandle("KERNEL32.DLL"),
+ "CreateRemoteThread");
+
+ isok = DuplicateHandle(GetCurrentProcess(),
+ child->hProcess,
+ GetCurrentProcess(),
+ &dup,
+ PROCESS_ALL_ACCESS,
+ FALSE, 0);
+ isok = GetExitCodeProcess((isok) ? dup : child->hProcess, &stat);
+ if (pfn_CreateRemoteThread) {
+ FARPROC pfnExitProc;
+ if (isok && stat == STILL_ACTIVE) {
+
+ pfnExitProc = GetProcAddress(GetModuleHandle("KERNEL32.DLL"),
+ "ExitProcess");
+ rt = pfn_CreateRemoteThread(child->hProcess,
+ NULL,
+ 0,
+ (LPTHREAD_START_ROUTINE)pfnExitProc,
+ (PVOID)exit_code, 0, &rtid);
+ }
+ }
+ else {
+ if (isok && stat == STILL_ACTIVE) {
+ DBPRINTF0("Could not CreateRemoteThread... Forcing TerminateProcess\n");
+ TerminateProcess(child->hProcess, exit_code);
+ }
+ }
+
+ if (rt) {
+ if (WaitForSingleObject(child->hProcess, 2000) == WAIT_OBJECT_0) {
+ CloseHandle(rt);
+ DBPRINTF0("Exited cleanly\n");
+ }
+ else {
+ DBPRINTF0("Forcing TerminateProcess\n");
+ TerminateProcess(child->hProcess, exit_code);
+ }
+ }
+ if (dup)
+ CloseHandle(dup);
+}
+
+int __cdecl compare(const void *arg1, const void *arg2)
+{
+ return _stricoll(*((char **)arg1),*((char **)arg2));
+}
+
+/* Merge two char arrays and make
+ * zero separated, double-zero terminated
+ * string
+ */
+static char * merge_arrays(char **one, char **two, process_t *proc)
+{
+ int len = 0, n, cnt = 0;
+ char *envp, *p;
+
+ for (n = 0; one[n]; n++) {
+ len += (strlen(one[n]) + 1);
+ cnt++;
+ }
+ for (n = 0; two[n]; n++) {
+ len += (strlen(two[n]) + 1);
+ cnt++;
+ }
+ p = envp = (char *)pool_calloc(proc->pool, len + 1);
+
+ for (n = 0; one[n]; n++) {
+ strcpy(p, one[n]);
+ p += strlen(one[n]) + 1;
+ }
+ for (n = 0; two[n]; n++) {
+ strcpy(p, two[n]);
+ p += strlen(two[n]) + 1;
+ }
+ return envp;
+}
+
+/* Make the environment string
+ * for the child process.
+ * The original environment of the calling process
+ * is merged with the current environment.
+ */
+static char * make_environment(char **envarr, char **envorg, process_t *proc)
+{
+ int len = 0, n, cnt = 0;
+ char *envp, *p, **tmp;
+
+ for (n = 0; envarr[n]; n++) {
+ len += strlen(envarr[n]) + 1;
+ cnt++;
+ }
+ for (n = 0; envorg[n]; n++) {
+ len += strlen(envorg[n]) + 1;
+ cnt++;
+ }
+ if (proc->java.jpath) {
+ len += strlen(proc->java.jpath) + 2;
+ cnt++;
+ }
+ p = envp = (char *)pool_calloc(proc->pool, len + 1);
+ if (!p)
+ return NULL;
+ tmp = (char **)calloc(cnt + 1, sizeof(char *));
+ cnt = 0;
+ for (n = 0; envarr[n]; n++) {
+ tmp[cnt++] = envarr[n];
+ }
+ for (n = 0; envorg[n]; n++) {
+ if (STRN_COMPARE(envorg[n], PROCRUN_ENV_STDIN)) {}
+ else if (STRN_COMPARE(envorg[n], PROCRUN_ENV_STDOUT)) {}
+ else if (STRN_COMPARE(envorg[n], PROCRUN_ENV_STDERR)) {}
+ else if (STRN_COMPARE(envorg[n], PROCRUN_ENV_PPID)) {}
+ else if (STRNI_COMPARE(envorg[n], "PATH=") &&
+ proc->java.jpath) {
+ tmp[cnt] = pool_calloc(proc->pool, strlen(envorg[n]) +
+ strlen(proc->java.jpath) + 2);
+ strcpy(tmp[cnt], envorg[n]);
+ strcat(tmp[cnt], ";");
+ strcat(tmp[cnt], proc->java.jpath);
+ DBPRINTF1("New PATH %s", tmp[cnt]);
+ ++cnt;
+ }
+ else
+ tmp[cnt++] = envorg[n];
+ }
+ qsort((void *)tmp, (size_t)n, sizeof(char *), compare);
+ for (n = 0; tmp[n]; n++) {
+ strcpy(p, tmp[n]);
+ p += strlen(tmp[n]) + 1;
+ }
+ free(tmp);
+ return envp;
+}
+
+/* Make the character string array form
+ * zero separated, double-zero terminated
+ * strings. Those strings comes from some
+ * Windows api calls, like GetEnvironmentStrings
+ * This string format is also used in Registry (REG_MULTI_SZ)
+ */
+static int make_array(const char *str, char **arr, int size, process_t *proc)
+{
+ int i = 0;
+ char *p;
+
+ if (!str)
+ return 0;
+ for (p = (char *)str; p && *p; p++) {
+ arr[i] = pool_strdup(proc->pool, p);
+ while (*p)
+ p++;
+ i++;
+ if (i + 1 > size)
+ break;
+ }
+ return i;
+}
+
+/* Simple string unqouting
+ * TODO: Handle multiqoutes.
+ */
+static char *remove_quotes(char * string) {
+ char *p = string, *q = string;
+ while (*p) {
+ if(*p != '\"' && *p != '\'')
+ *q++ = *p;
+ ++p;
+ }
+ *q = '\0';
+ return string;
+}
+
+/* Parse command line argument.
+ * First command param starts with //name//value
+ */
+static int parse_args(int argc, char **argv, process_t *proc)
+{
+ int mode = 0;
+ char *arg = argv[1];
+
+ if ((strlen(arg) > 5) && arg[0] == '/' && arg[1] == '/') {
+ if (STRN_COMPARE(arg, PROC_ARG_ENVPREFIX)) {
+ proc->env_prefix = arg + STRN_SIZE(PROC_ARG_ENVPREFIX);
+ mode = PROCRUN_CMD_ENVPREFIX;
+ }
+ else if (STRN_COMPARE(arg, PROC_ARG_RUN_JAVA)) {
+ proc->java.path = pool_strdup(proc->pool, arg +
+ STRN_SIZE(PROC_ARG_RUN_JAVA));
+ mode = PROCRUN_CMD_RUN_JAVA;
+ }
+ else if (STRN_COMPARE(arg, PROC_ARG_INSTALL_SERVICE)) {
+ proc->service.name = pool_strdup(proc->pool, arg +
+ STRN_SIZE(PROC_ARG_INSTALL_SERVICE));
+ mode = PROCRUN_CMD_INSTALL_SERVICE;
+ }
+ else if (STRN_COMPARE(arg, PROC_ARG_RUN_SERVICE)) {
+ proc->service.name = pool_strdup(proc->pool, arg +
+ STRN_SIZE(PROC_ARG_RUN_SERVICE));
+ mode = PROCRUN_CMD_RUN_SERVICE;
+ }
+ else if (STRN_COMPARE(arg, PROC_ARG_TEST_SERVICE)) {
+ proc->service.name = pool_strdup(proc->pool, arg +
+ STRN_SIZE(PROC_ARG_TEST_SERVICE));
+ mode = PROCRUN_CMD_TEST_SERVICE;
+ }
+#ifdef PROCRUN_WINAPP
+ else if (STRN_COMPARE(arg, PROC_ARG_GUIT_SERVICE)) {
+ proc->service.name = pool_strdup(proc->pool, arg +
+ STRN_SIZE(PROC_ARG_GUIT_SERVICE));
+ mode = PROCRUN_CMD_GUIT_SERVICE;
+ ac_use_try = 1;
+ ac_use_dlg = 1;
+ }
+ else if (STRN_COMPARE(arg, PROC_ARG_GUID_SERVICE)) {
+ proc->service.name = pool_strdup(proc->pool, arg +
+ STRN_SIZE(PROC_ARG_GUID_SERVICE));
+ mode = PROCRUN_CMD_GUID_SERVICE;
+ ac_use_dlg = 1;
+ ac_use_show = 1;
+ }
+ else if (STRN_COMPARE(arg, PROC_ARG_GUID_PROCESS)) {
+ mode = PROCRUN_CMD_GUID_PROCESS;
+ ac_use_dlg = 1;
+ ac_use_show = 1;
+ }
+ else if (STRN_COMPARE(arg, PROC_ARG_EDIT_SERVICE)) {
+ proc->service.name = pool_strdup(proc->pool, arg +
+ STRN_SIZE(PROC_ARG_EDIT_SERVICE));
+
+ mode = PROCRUN_CMD_EDIT_SERVICE;
+ ac_use_props = 1;
+ }
+#endif
+ else if (STRN_COMPARE(arg, PROC_ARG_STOP_SERVICE)) {
+ proc->service.name = pool_strdup(proc->pool, arg +
+ STRN_SIZE(PROC_ARG_STOP_SERVICE));
+ mode = PROCRUN_CMD_STOP_SERVICE;
+ }
+ else if (STRN_COMPARE(arg, PROC_ARG_DELETE_SERVICE)) {
+ proc->service.name = pool_strdup(proc->pool, arg +
+ STRN_SIZE(PROC_ARG_DELETE_SERVICE));
+ mode = PROCRUN_CMD_DELETE_SERVICE;
+ }
+ else if (STRN_COMPARE(arg, PROC_ARG_UPDATE_SERVICE)) {
+ proc->service.name = pool_strdup(proc->pool, arg +
+ STRN_SIZE(PROC_ARG_UPDATE_SERVICE));
+ mode = PROCRUN_CMD_UPDATE_SERVICE;
+ }
+ }
+ return mode;
+}
+
+/* Print some statistics about the current process
+ *
+ */
+static void debug_process(int argc, char **argv, process_t *p)
+{
+ DBPRINTF1("DUMPING %s\n", argv[0]);
+ DBPRINTF0(" SERVICE:\n");
+ DBPRINTF1(" name : %s\n", p->service.name);
+ DBPRINTF1(" description : %s\n", p->service.description);
+ DBPRINTF1(" path : %s\n", p->service.path);
+ DBPRINTF1(" image : %s\n", p->service.image);
+ DBPRINTF1(" infile : %s\n", p->service.inname);
+ DBPRINTF1(" outfile : %s\n", p->service.outname);
+ DBPRINTF1(" errfile : %s\n", p->service.errname);
+ DBPRINTF1(" argvw : %s\n", p->argw);
+ DBPRINTF0(" JAVAVM:\n");
+ DBPRINTF1(" name : %s\n", p->java.path);
+ DBPRINTF1(" start : %s\n", p->java.start_class);
+ DBPRINTF1(" stop : %s\n", p->java.stop_class);
+ DBPRINTF1(" start method: %s\n", p->java.start_method);
+ DBPRINTF1(" stop method : %s\n", p->java.stop_method);
+ DBPRINTF1(" start param : %s\n", p->java.start_param);
+ DBPRINTF1(" stop param : %s\n", p->java.stop_param);
+
+ DBPRINTF0("DONE...\n");
+}
+
+/* Add the environment variable 'name=value'
+ * to the environment that will be passed to the child process.
+ */
+static int procrun_addenv(char *name, char *value, int val, process_t *proc)
+{
+ int i;
+
+ for (i = 0; i < PROC_ENV_COUNT; i++)
+ if (proc->env[i] == NULL)
+ break;
+ if (i < PROC_ENV_COUNT) {
+ if (value) {
+ proc->env[i] = (char *)pool_alloc(proc->pool, strlen(name) +
+ strlen(value) + 1);
+ strcpy(proc->env[i], name);
+ strupr(proc->env[i]);
+ strcat(proc->env[i], value);
+ }
+ else {
+ proc->env[i] = (char *)pool_alloc(proc->pool, strlen(name) + 34);
+ strcpy(proc->env[i], name);
+ strupr(proc->env[i]);
+ itoa(val, proc->env[i] + strlen(name), 10);
+ }
+ return i;
+ }
+ else
+ return -1;
+}
+
+/* Read the environment.
+ * This function reads the procrun defined environment
+ * variables passed from the calling process,
+ * if the calling process is a procrun instance.
+ */
+static int procrun_readenv(process_t *proc, char **envp)
+{
+ int i, rv = 0;
+ char *env;
+ HANDLE h;
+
+ for (i = 0; envp[i]; i++) {
+ env = envp[i];
+ if (STRN_COMPARE(env, PROCRUN_ENV_STDIN)) {
+ h = (HANDLE)atoi(env + STRN_SIZE(PROCRUN_ENV_STDIN));
+ if (!DuplicateHandle(proc->pinfo.hProcess,
+ h,
+ proc->pinfo.hProcess,
+ &proc->h_stdin[0],
+ 0L, TRUE, DUPLICATE_SAME_ACCESS)) {
+ DBPRINTF1("%s\tDuplicateHandle for STDIN failed\n", env[i]);
+ proc->h_stdin[0] = INVALID_HANDLE_VALUE;
+ return 0;
+ }
+ CloseHandle(h);
+ ++rv;
+ }
+ else if (STRN_COMPARE(env, PROCRUN_ENV_STDOUT)) {
+ h = (HANDLE)atoi(env + STRN_SIZE(PROCRUN_ENV_STDOUT));
+ if (!DuplicateHandle(proc->pinfo.hProcess,
+ h,
+ proc->pinfo.hProcess,
+ &proc->h_stdout[1],
+ 0L, TRUE, DUPLICATE_SAME_ACCESS)) {
+ DBPRINTF1("%s\tDuplicateHandle for STDOUT failed\n", env[i]);
+ proc->h_stdout[1] = INVALID_HANDLE_VALUE;
+ return 0;
+ }
+ CloseHandle(h);
+ ++rv;
+ }
+ else if (STRN_COMPARE(env, PROCRUN_ENV_STDERR)) {
+ h = (HANDLE)atoi(env + STRN_SIZE(PROCRUN_ENV_STDERR));
+ if (!DuplicateHandle(proc->pinfo.hProcess,
+ h,
+ proc->pinfo.hProcess,
+ &proc->h_stderr[1],
+ 0L, TRUE, DUPLICATE_SAME_ACCESS)) {
+ DBPRINTF1("%s\tDuplicateHandle for STDERR failed\n", env[i]);
+ proc->h_stderr[1] = INVALID_HANDLE_VALUE;
+ return 0;
+ }
+ CloseHandle(h);
+ ++rv;
+ }
+ else if (STRN_COMPARE(env, PROCRUN_ENV_ERRFILE)) {
+ h = (HANDLE)atoi(env + STRN_SIZE(PROCRUN_ENV_ERRFILE));
+ g_proc_stderr_file = _open_osfhandle((long)h,
+ _O_APPEND | _O_TEXT);
+ }
+ else if (STRN_COMPARE(env, PROCRUN_ENV_PPID)) {
+ proc->ppid = atoi(env + STRN_SIZE(PROCRUN_ENV_PPID));
+ }
+
+ }
+ return rv;
+}
+
+/* Find the default jvm.dll
+ * The function scans through registry and finds
+ * default JRE jvm.dll.
+ */
+static char* procrun_guess_jvm(process_t *proc)
+{
+ HKEY hkjs;
+ char jvm[MAX_PATH+1];
+ char reg[MAX_PATH+1];
+ char *cver;
+ unsigned long err, klen = MAX_PATH;
+
+ strcpy(reg, JAVASOFT_REGKEY);
+ cver = ®[sizeof(JAVASOFT_REGKEY)-1];
+
+ if ((err = RegOpenKeyEx(HKEY_LOCAL_MACHINE, reg,
+ 0, KEY_READ, &hkjs)) != ERROR_SUCCESS) {
+ DBPRINTF0("procrun_guess_jvm() failed to open Registry key\n");
+ return NULL;
+ }
+ if ((err = RegQueryValueEx(hkjs, "CurrentVersion", NULL, NULL,
+ (unsigned char *)cver,
+ &klen)) != ERROR_SUCCESS) {
+ DBPRINTF0("procrun_guess_jvm() failed obtaining Current Java Version\n");
+ RegCloseKey(hkjs);
+ return NULL;
+ }
+ RegCloseKey(hkjs);
+
+ if ((err = RegOpenKeyEx(HKEY_LOCAL_MACHINE, reg,
+ 0, KEY_READ, &hkjs) ) != ERROR_SUCCESS) {
+ DBPRINTF1("procrun_guess_jvm() failed to open Registry key %s\n", reg);
+ return NULL;
+ }
+ klen = MAX_PATH;
+ if ((err = RegQueryValueEx(hkjs, "RuntimeLib", NULL, NULL,
+ (unsigned char *)jvm,
+ &klen)) != ERROR_SUCCESS) {
+ DBPRINTF0("procrun_guess_jvm() failed obtaining Runtime Library\n");
+ RegCloseKey(hkjs);
+ return NULL;
+ }
+ RegCloseKey(hkjs);
+
+ return pool_strdup(proc->pool, jvm);
+}
+
+/* Find the java/javaw (depending on image)
+ * The function locates the JavaHome Registry entry
+ * and merges that path with the requested image
+ */
+
+static char* procrun_guess_java(process_t *proc, const char *image)
+{
+ HKEY hkjs;
+ char jbin[MAX_PATH+1];
+ char reg[MAX_PATH+1];
+ char *cver;
+ unsigned long err, klen = MAX_PATH;
+
+ if((cver = getenv("JAVA_HOME")) != NULL) {
+ strcpy(jbin,cver);
+ } else {
+ strcpy(reg, JAVASOFT_REGKEY);
+ cver = ®[sizeof(JAVASOFT_REGKEY)-1];
+
+ if ((err = RegOpenKeyEx(HKEY_LOCAL_MACHINE, reg,
+ 0, KEY_READ, &hkjs)) != ERROR_SUCCESS) {
+ DBPRINTF0("procrun_guess_jvm() failed to open Registry key\n");
+ return NULL;
+ }
+ if ((err = RegQueryValueEx(hkjs, "CurrentVersion", NULL, NULL,
+ (unsigned char *)cver,
+ &klen)) != ERROR_SUCCESS) {
+ DBPRINTF0("procrun_guess_jvm() failed obtaining Current Java Version\n");
+ RegCloseKey(hkjs);
+ return NULL;
+ }
+ RegCloseKey(hkjs);
+
+ if ((err = RegOpenKeyEx(HKEY_LOCAL_MACHINE, reg,
+ 0, KEY_READ, &hkjs) ) != ERROR_SUCCESS) {
+ DBPRINTF1("procrun_guess_jvm() failed to open Registry key %s\n", reg);
+ return NULL;
+ }
+ klen = MAX_PATH;
+ if ((err = RegQueryValueEx(hkjs, "JavaHome", NULL, NULL,
+ (unsigned char *)jbin,
+ &klen)) != ERROR_SUCCESS) {
+ DBPRINTF0("procrun_guess_jvm() failed obtaining Java path\n");
+ RegCloseKey(hkjs);
+ return NULL;
+ }
+ RegCloseKey(hkjs);
+ }
+ strcat(jbin, "\\bin\\");
+ strcat(jbin, image);
+ strcat(jbin, ".exe");
+ return pool_strdup(proc->pool, jbin);
+}
+
+/* Find the system JavaHome path.
+ * The "JAVA_HOME" environment variable
+ * gets procedance over registry settings
+ */
+static char* procrun_guess_java_home(process_t *proc)
+{
+ HKEY hkjs;
+ char jbin[MAX_PATH+1];
+ char reg[MAX_PATH+1];
+ char *cver;
+ unsigned long err, klen = MAX_PATH;
+
+ if ((cver = getenv("JAVA_HOME")) != NULL) {
+ strcpy(jbin, cver);
+ strcat(jbin, "\\bin");
+ return pool_strdup(proc->pool, jbin);
+ }
+ strcpy(reg, JAVAHOME_REGKEY);
+ cver = ®[sizeof(JAVAHOME_REGKEY)-1];
+
+ if ((err = RegOpenKeyEx(HKEY_LOCAL_MACHINE, reg,
+ 0, KEY_READ, &hkjs)) != ERROR_SUCCESS) {
+ DBPRINTF0("procrun_guess_jvm() failed to open Registry key\n");
+ return NULL;
+ }
+ if ((err = RegQueryValueEx(hkjs, "CurrentVersion", NULL, NULL,
+ (unsigned char *)cver,
+ &klen)) != ERROR_SUCCESS) {
+ DBPRINTF0("procrun_guess_jvm() failed obtaining Current Java SDK Version\n");
+ RegCloseKey(hkjs);
+ return NULL;
+ }
+ RegCloseKey(hkjs);
+
+ if ((err = RegOpenKeyEx(HKEY_LOCAL_MACHINE, reg,
+ 0, KEY_READ, &hkjs)) != ERROR_SUCCESS) {
+ DBPRINTF1("procrun_guess_jvm() failed to open Registry key %s\n", reg);
+ return NULL;
+ }
+ klen = MAX_PATH;
+ if ((err = RegQueryValueEx(hkjs, "JavaHome", NULL, NULL,
+ (unsigned char *)jbin,
+ &klen)) != ERROR_SUCCESS) {
+ DBPRINTF0("procrun_guess_jvm() failed obtaining Java Home\n");
+ RegCloseKey(hkjs);
+ return NULL;
+ }
+ RegCloseKey(hkjs);
+ procrun_addenv("JAVA_HOME", jbin, 0, proc);
+ strcat(jbin, "\\bin");
+ return pool_strdup(proc->pool, jbin);
+}
+
+/* Read the service parameters from the registry
+ *
+ */
+static int procrun_service_params(process_t *proc)
+{
+ HKEY key;
+ char skey[256];
+ char kval[MAX_PATH];
+ unsigned long klen;
+ DWORD err;
+
+ if (!proc->service.name)
+ return 0;
+
+ sprintf(skey, PROCRUN_REGKEY_RPARAMS, proc->service.name);
+ DBPRINTF1("getting key: %s\n", skey);
+ if ((err = RegOpenKeyEx(HKEY_LOCAL_MACHINE, skey,
+ 0, KEY_READ, &key)) == ERROR_SUCCESS) {
+
+ klen = MAX_PATH;
+ if ((err = RegQueryValueEx(key, PROCRUN_PARAMS_DESCRIPTION, NULL, NULL,
+ (unsigned char *)kval,
+ &klen)) == ERROR_SUCCESS) {
+ proc->service.description = pool_strdup(proc->pool, kval);
+ }
+ klen = MAX_PATH;
+ if ((err = RegQueryValueEx(key, PROCRUN_PARAMS_DISPLAY, NULL, NULL,
+ (unsigned char *)kval,
+ &klen)) == ERROR_SUCCESS) {
+ proc->service.display = pool_strdup(proc->pool, kval);
+ }
+ klen = MAX_PATH;
+ if ((err = RegQueryValueEx(key, PROCRUN_PARAMS_WORKPATH, NULL, NULL,
+ (unsigned char *)kval,
+ &klen)) == ERROR_SUCCESS) {
+ proc->service.path = pool_strdup(proc->pool, kval);
+ }
+ if ((err = RegQueryValueEx(key, PROCRUN_PARAMS_IMAGE, NULL, NULL,
+ NULL,
+ &klen)) == ERROR_SUCCESS) {
+ proc->service.image = (char *)pool_alloc(proc->pool, klen);
+ if ((err = RegQueryValueEx(key, PROCRUN_PARAMS_IMAGE, NULL, NULL,
+ (unsigned char *)proc->service.image,
+ &klen)) != ERROR_SUCCESS) {
+ proc->service.image = NULL;
+ }
+ }
+ klen = MAX_PATH;
+ if ((err = RegQueryValueEx(key, PROCRUN_PARAMS_ACCOUNT, NULL, NULL,
+ (unsigned char *)kval,
+ &klen)) == ERROR_SUCCESS) {
+ proc->service.account = pool_strdup(proc->pool, kval);
+ }
+ klen = MAX_PATH;
+ if ((err = RegQueryValueEx(key, PROCRUN_PARAMS_PASSWORD, NULL, NULL,
+ (unsigned char *)kval,
+ &klen)) == ERROR_SUCCESS) {
+ proc->service.password = pool_calloc(proc->pool, 256);
+ simple_decrypt(100, proc->service.password, kval);
+ }
+ klen = MAX_PATH;
+ if ((err = RegQueryValueEx(key, PROCRUN_PARAMS_STARTUP, NULL, NULL,
+ (unsigned char *)kval,
+ &klen)) == ERROR_SUCCESS) {
+ if (!strcmp(kval, "auto"))
+ proc->service.startup = SERVICE_AUTO_START;
+ else
+ proc->service.startup = SERVICE_DEMAND_START;
+ }
+ klen = MAX_PATH;
+ if ((err = RegQueryValueEx(key, PROCRUN_PARAMS_STARTCLASS, NULL, NULL,
+ (unsigned char *)kval,
+ &klen)) == ERROR_SUCCESS) {
+ char *p;
+ p = strchr(kval, ';');
+ if (p) *p = '\0';
+ proc->java.start_class = pool_strdup(proc->pool, kval);
+ if (p) {
+ ++p;
+ proc->java.start_method = pool_strdup(proc->pool, p);
+ p = strchr(proc->java.start_method, ';');
+ if (p) {
+ *p = '\0';
+ ++p;
+ proc->java.start_param = pool_strdup(proc->pool, p);
+ }
+ }
+ }
+ klen = MAX_PATH;
+ if ((err = RegQueryValueEx(key, PROCRUN_PARAMS_STOPCLASS, NULL, NULL,
+ (unsigned char *)kval,
+ &klen)) == ERROR_SUCCESS) {
+ char *p;
+ p = strchr(kval, ';');
+ if (p) *p = '\0';
+ proc->java.stop_class = pool_strdup(proc->pool, kval);
+ if (p) {
+ ++p;
+ proc->java.stop_method = pool_strdup(proc->pool, p);
+ p = strchr(proc->java.stop_method, ';');
+ if (p) {
+ *p = '\0';
+ ++p;
+ proc->java.stop_param = pool_strdup(proc->pool, p);
+ }
+ }
+ }
+ klen = MAX_PATH;
+ if ((err = RegQueryValueEx(key, PROCRUN_PARAMS_STDINFILE, NULL, NULL,
+ (unsigned char *)kval,
+ &klen)) == ERROR_SUCCESS) {
+ proc->service.infile = CreateFile(kval,
+ GENERIC_READ,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (proc->service.infile != INVALID_HANDLE_VALUE) {
+ if (proc->h_stdin[1] != INVALID_HANDLE_VALUE)
+ pool_close_handle(proc->pool, proc->h_stdin[1]);
+ proc->h_stdin[1] = proc->service.infile;
+ proc->service.inname = pool_strdup(proc->pool, kval);
+ }
+ pool_handle(proc->pool, proc->service.infile);
+ }
+ klen = MAX_PATH;
+ if ((err = RegQueryValueEx(key, PROCRUN_PARAMS_STDOUTFILE, NULL, NULL,
+ (unsigned char *)kval,
+ &klen)) == ERROR_SUCCESS) {
+ proc->service.outfile = CreateFile(kval,
+ GENERIC_WRITE,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (proc->service.outfile != INVALID_HANDLE_VALUE) {
+ SetFilePointer(proc->service.outfile, 0L, NULL, FILE_END);
+ if (proc->h_stdout[1] != INVALID_HANDLE_VALUE)
+ pool_close_handle(proc->pool, proc->h_stdout[1]);
+ proc->h_stdout[1] = proc->service.outfile;
+ proc->service.outname = pool_strdup(proc->pool, kval);
+ }
+ pool_handle(proc->pool, proc->service.outfile);
+ }
+ klen = MAX_PATH;
+ if ((err = RegQueryValueEx(key, PROCRUN_PARAMS_STDERRFILE, NULL, NULL,
+ (unsigned char *)kval,
+ &klen)) == ERROR_SUCCESS) {
+ proc->service.errfile = CreateFile(kval,
+ GENERIC_WRITE,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (proc->service.errfile != INVALID_HANDLE_VALUE) {
+ SetFilePointer(proc->service.errfile, 0L, NULL, FILE_END);
+ if (proc->h_stderr[1] != INVALID_HANDLE_VALUE)
+ pool_close_handle(proc->pool, proc->h_stderr[1]);
+ proc->h_stderr[1] = proc->service.errfile;
+ proc->service.errname = pool_strdup(proc->pool, kval);
+ }
+ pool_handle(proc->pool, proc->service.errfile);
+ }
+ if ((err = RegQueryValueEx(key, PROCRUN_PARAMS_CMDARGS, NULL, NULL,
+ NULL,
+ &klen)) == ERROR_SUCCESS) {
+ proc->argw = (char *)pool_alloc(proc->pool, klen);
+ if ((err = RegQueryValueEx(key, PROCRUN_PARAMS_CMDARGS, NULL, NULL,
+ (unsigned char *)proc->argw,
+ &klen)) != ERROR_SUCCESS) {
+ proc->argw = NULL;
+ }
+
+ }
+ if ((err = RegQueryValueEx(key, PROCRUN_PARAMS_JVM_OPTS, NULL, NULL,
+ NULL,
+ &klen)) == ERROR_SUCCESS) {
+ proc->java.opts = (char *)pool_alloc(proc->pool, klen);
+ if ((err = RegQueryValueEx(key, PROCRUN_PARAMS_JVM_OPTS, NULL, NULL,
+ (unsigned char *)proc->java.opts,
+ &klen)) != ERROR_SUCCESS) {
+ proc->java.opts = NULL;
+ }
+ }
+#ifdef PROCRUN_WINAPP
+ klen = MAX_PATH;
+ if ((err = RegQueryValueEx(key, PROCRUN_PARAMS_WINPOS, NULL, NULL,
+ (unsigned char *)kval,
+ &klen)) == ERROR_SUCCESS) {
+ sscanf(kval, "%d %d %d %d", &ac_winpos.left, &ac_winpos.right,
+ &ac_winpos.top, &ac_winpos.bottom);
+ }
+
+ klen = MAX_PATH;
+ if ((err = RegQueryValueEx(key, PROCRUN_PARAMS_USELVIEW, NULL, NULL,
+ (unsigned char *)kval,
+ &klen)) == ERROR_SUCCESS) {
+ ac_use_lview = atoi(kval);
+ }
+#endif
+ klen = MAX_PATH;
+ if ((err = RegQueryValueEx(key, PROCRUN_PARAMS_ENVIRONMENT, NULL, NULL,
+ NULL,
+ &klen)) == ERROR_SUCCESS) {
+ proc->service.environment = (char *)pool_alloc(proc->pool, klen);
+ if ((err = RegQueryValueEx(key, PROCRUN_PARAMS_ENVIRONMENT, NULL, NULL,
+ (unsigned char *)proc->service.environment,
+ &klen)) != ERROR_SUCCESS) {
+ proc->service.environment = NULL;
+ }
+ }
+
+ RegCloseKey(key);
+ return 0;
+ }
+ else
+ return -1;
+}
+
+/* Decide if we need the java
+ * Check the registry and decide how the java
+ * is going to be loaded.
+ * Using inprocess jvm.dll or as a child process running java.exe
+ */
+static int procrun_load_jvm(process_t *proc, int mode)
+{
+ int has_java = 0;
+ char jvm_path[MAX_PATH + 1];
+
+ if (!proc->java.start_class) {
+ return 0;
+ }
+ jvm_path[0] = '\0';
+ switch (mode) {
+ case PROCRUN_CMD_RUN_JAVA:
+ has_java = 1;
+ break;
+ case PROCRUN_CMD_RUN_SERVICE:
+ case PROCRUN_CMD_TEST_SERVICE:
+ case PROCRUN_CMD_GUIT_SERVICE:
+ case PROCRUN_CMD_GUID_SERVICE:
+ case PROCRUN_CMD_EDIT_SERVICE:
+ {
+ HKEY key;
+ char skey[256];
+ unsigned long klen = MAX_PATH;
+ DWORD err;
+ sprintf(skey, PROCRUN_REGKEY_RPARAMS, proc->service.name);
+ if ((err = RegOpenKeyEx(HKEY_LOCAL_MACHINE, skey,
+ 0, KEY_READ, &key)) == ERROR_SUCCESS) {
+
+ if ((err = RegQueryValueEx(key, PROCRUN_PARAMS_JVM,
+ NULL, NULL,
+ (unsigned char *)jvm_path,
+ &klen)) == ERROR_SUCCESS) {
+ has_java = 1;
+ }
+ RegCloseKey(key);
+ }
+ }
+ break;
+ }
+ if (has_java) {
+ UINT em;
+ if (strlen(jvm_path)) {
+ proc->java.display = pool_strdup(proc->pool, jvm_path);
+ if (strlen(jvm_path) < 6)
+ proc->java.path = procrun_guess_jvm(proc);
+ else
+ proc->java.path = pool_strdup(proc->pool, jvm_path);
+ if (strnicmp(jvm_path, "java", 4) == 0) {
+ proc->java.jbin = procrun_guess_java(proc, jvm_path);
+ proc->java.jpath = procrun_guess_java_home(proc);
+ }
+ }
+ DBPRINTF1("jvm dll path %s\n", proc->java.path);
+ DBPRINTF1("java path %s\n", proc->java.jpath);
+ DBPRINTF1("java bin %s\n", proc->java.jbin);
+ if (!proc->java.path || !proc->java.start_method) {
+ DBPRINTF0("java path or start method missing\n");
+ return -1;
+ } else if (proc->java.jbin != NULL) {
+ DBPRINTF0("forking no need to load java dll\n");
+ return 0; // If forking, don't bother with the load.
+ }
+ /* Try to load the jvm dll */
+ em = SetErrorMode(SEM_FAILCRITICALERRORS);
+ proc->java.dll = LoadLibraryEx(proc->java.path, NULL, 0);
+ if (!proc->java.dll)
+ proc->java.dll = LoadLibraryEx(proc->java.path, NULL,
+ LOAD_WITH_ALTERED_SEARCH_PATH);
+ SetErrorMode(em);
+ if (!proc->java.dll) {
+ DBPRINTF0(NULL);
+ DBPRINTF0("Cannot load java dll\n");
+ return -1;
+ }
+ /* resolve symbols */
+ jni_JNI_GetDefaultJavaVMInitArgs = (JNI_GETDEFAULTJAVAVMINITARGS)
+ GetProcAddress(proc->java.dll,
+ "JNI_GetDefaultJavaVMInitArgs");
+ jni_JNI_CreateJavaVM = (JNI_CREATEJAVAVM)
+ GetProcAddress(proc->java.dll,
+ "JNI_CreateJavaVM");
+ jni_JNI_GetCreatedJavaVMs = (JNI_GETCREATEDJAVAVMS)
+ GetProcAddress(proc->java.dll,
+ "JNI_GetCreatedJavaVMs");
+ if (jni_JNI_GetDefaultJavaVMInitArgs == NULL ||
+ jni_JNI_CreateJavaVM == NULL ||
+ jni_JNI_GetCreatedJavaVMs == NULL) {
+ DBPRINTF0(NULL);
+ DBPRINTF0("Cannot find JNI routines in java dll\n");
+ FreeLibrary(proc->java.dll);
+ proc->java.dll = NULL;
+ return -1;
+ }
+ DBPRINTF1("JVM %s Loaded\n", proc->java.path);
+ }
+ return 0;
+}
+
+/* JVM hooks */
+static int jni_exit_signaled = 0;
+static int jni_exit_code = 0;
+static int jni_abort_signaled = 0;
+
+static void jni_exit_hook(int code)
+{
+ jni_exit_signaled = -1;
+#if 1
+ jni_abort_signaled = -1;
+#endif
+ jni_exit_code = code;
+
+ DBPRINTF1("JVM exit hook called %d\n", code);
+}
+
+static void jni_abort_hook()
+{
+ jni_abort_signaled = -1;
+
+ DBPRINTF0("JVM abort hook called\n");
+}
+
+/* 'Standard' JNI functions
+ *
+ */
+
+static JNIEnv *jni_attach(process_t *proc)
+{
+ JNIEnv *env = NULL;
+ int err;
+ JavaVM *jvm = proc->java.jvm;
+
+ if (jvm == NULL || jni_abort_signaled)
+ return NULL;
+ err = (*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_2);
+ if (err == 0)
+ return env;
+ if (err != JNI_EDETACHED) {
+ return NULL;
+ }
+ err = (*jvm)->AttachCurrentThread(jvm,
+ (void **)&env,
+ NULL);
+ if (err != 0) {
+ return NULL;
+ }
+ return env;
+}
+
+static int jni_detach(process_t *proc)
+{
+ JavaVM *jvm = proc->java.jvm;
+
+ if (jvm == NULL || jni_abort_signaled)
+ return -1;
+ return (*jvm)->DetachCurrentThread(jvm);
+}
+
+/* Destroy the jvm.
+ * This method stops the current jvm calling
+ * configured stop methods and destroys the loaded jvm.
+ */
+static int procrun_destroy_jvm(process_t *proc, HANDLE jh)
+{
+ JavaVM *jvm = proc->java.jvm;
+ int err;
+ JNIEnv *env;
+
+ DBPRINTF2("procrun_destroy_jvm dll %08x jvm %08x\n",proc->java.dll,proc->java.jvm);
+ if (!proc->java.dll || !jvm) {
+ if(proc->java.stop_class != NULL && proc->java.stop_method != NULL && g_env->c->pinfo.dwProcessId) {
+ process_t tc = *g_env->c, tm = *g_env->m;
+ procrun_t tproc;
+ HANDLE threads[2];
+ tproc.c = &tc;
+ tproc.m = &tm;
+ procrun_redirect(proc->service.image,
+ proc->envp, &tproc, 0);
+ threads[0] = tc.pinfo.hThread;
+ threads[1] = g_env->c->pinfo.hThread;
+ WaitForMultipleObjects(2,threads, TRUE, 60000);
+ }
+
+ return 0;
+ }
+ env = jni_attach(proc);
+ if (!env) {
+ DBPRINTF0("jni_attach failed\n");
+ goto cleanup;
+ }
+ if (proc->java.stop_bridge && proc->java.stop_mid) {
+ jclass strclass;
+ jarray jargs = NULL;
+ DBPRINTF1("Calling shutdown %s\n", proc->java.stop_class);
+
+ strclass = (*env)->FindClass(env, "java/lang/String");
+ if (proc->java.stop_param) {
+ jstring arg = (*env)->NewStringUTF(env, proc->java.stop_param);
+ jargs = (*env)->NewObjectArray(env, 1, strclass, NULL);
+ (*env)->SetObjectArrayElement(env, jargs, 0, arg);
+ }
+ (*env)->CallStaticVoidMethod(env,
+ proc->java.stop_bridge,
+ proc->java.stop_mid,
+ jargs);
+ if(jh != NULL)
+ WaitForSingleObject(jh, 60000);
+ }
+ else if (!proc->java.jbin) {
+ /* Call java.lang.System.exit(0) */
+ jclass sysclass;
+ jmethodID exitid;
+ sysclass = (*env)->FindClass(env, "java/lang/System");
+ if (!sysclass)
+ goto cleanup;
+ exitid = (*env)->GetStaticMethodID(env, sysclass, "exit", "(I)V");
+ if (!exitid)
+ goto cleanup;
+ report_service_status(SERVICE_STOPPED, 0, 0,
+ g_env->m);
+ DBPRINTF0("Forcing shutdown using System.exit(0)\n");
+
+ (*env)->CallStaticVoidMethod(env, sysclass, exitid, 0);
+ }
+cleanup:
+ err = (*jvm)->DestroyJavaVM(jvm);
+ FreeLibrary(proc->java.dll);
+ proc->java.dll = NULL;
+ return err;
+}
+
+/* Initialize loaded jvm.dll
+ * Pass the startup options to the jvm,
+ * and regiter the start/top classes and methods
+ */
+static int procrun_init_jvm(process_t *proc)
+{
+ int jvm_version;
+ JDK1_1InitArgs vm_args11;
+ JavaVMInitArgs vm_args;
+ JavaVMOption options[32];
+ JNIEnv *env;
+ JavaVM *jvm;
+ jclass strclass;
+ jarray jargs = NULL;
+ char *cp;
+ char *opts[32];
+ int optn, i, err;
+
+ vm_args11.version = JNI_VERSION_1_2;
+
+ DBPRINTF0("Initializing JVM\n");
+ if (jni_JNI_GetDefaultJavaVMInitArgs(&vm_args11) != 0) {
+ DBPRINTF0("Could not find Default InitArgs\n");
+ return -1;
+ }
+ jvm_version= vm_args11.version;
+
+ if (jvm_version != JNI_VERSION_1_2) {
+ DBPRINTF1("Found: %X expecting 1.2 Java Version\n", jvm_version);
+ return -1;
+ }
+ if(proc->service.path != NULL) {
+ SetCurrentDirectory(proc->service.path);
+ }
+ optn = make_array(proc->java.opts, opts, 30, proc);
+ for (i = 0; i < optn; i++)
+ options[i].optionString = remove_quotes(opts[i]);
+ cp = (char *)pool_alloc(proc->pool, strlen("-Djava.class.path=") +
+ strlen(proc->service.image) + 1);
+ strcpy(cp, "-Djava.class.path=");
+ strcat(cp, remove_quotes(proc->service.image));
+ options[optn++].optionString = cp;
+ DBPRINTF1("-Djava.class.path=%s", proc->service.image);
+ /* Set the abort and exit hooks */
+#if 0
+ options[optn].optionString = "exit";
+ options[optn++].extraInfo = jni_exit_hook;
+#endif
+ options[optn].optionString = "abort";
+ options[optn++].extraInfo = jni_abort_hook;
+
+ for (i = 0; i < optn; i++)
+ DBPRINTF2("OPT %d %s", i , options[i].optionString);
+
+ vm_args.version = JNI_VERSION_1_2;
+ vm_args.options = options;
+ vm_args.nOptions = optn;
+ vm_args.ignoreUnrecognized = JNI_TRUE;
+
+ err = jni_JNI_CreateJavaVM(&jvm, &env, &vm_args);
+ if (err == JNI_EEXIST) {
+ int vmcount;
+
+ jni_JNI_GetCreatedJavaVMs(&jvm, 1, &vmcount);
+ if (jvm == NULL) {
+ DBPRINTF0("Error creating JVM\n");
+ return -1;
+ }
+ }
+ proc->java.jvm = jvm;
+ for (i = 0; i < (int)strlen(proc->java.start_class); i++) {
+ if (proc->java.start_class[i] == '.')
+ proc->java.start_class[i] = '/';
+ }
+ proc->java.start_bridge = (*env)->FindClass(env, proc->java.start_class);
+ if (!proc->java.start_bridge) {
+ DBPRINTF1("Couldn't find Startup class %s\n", proc->java.start_class);
+ goto cleanup;
+ }
+ proc->java.start_mid = (*env)->GetStaticMethodID(env, proc->java.start_bridge,
+ proc->java.start_method,
+ "([Ljava/lang/String;)V");
+
+ if (!proc->java.start_mid) {
+ DBPRINTF1("Couldn't find Startup class method %s\n", proc->java.start_method);
+ goto cleanup;
+ }
+ if (proc->java.stop_class && proc->java.stop_method) {
+ for (i = 0; i < (int)strlen(proc->java.stop_class); i++) {
+ if (proc->java.stop_class[i] == '.')
+ proc->java.stop_class[i] = '/';
+ }
+ proc->java.stop_bridge = (*env)->FindClass(env, proc->java.stop_class);
+ if (!proc->java.stop_bridge) {
+ goto cleanup;
+ }
+ proc->java.stop_mid = (*env)->GetStaticMethodID(env, proc->java.stop_bridge,
+ proc->java.stop_method,
+ "([Ljava/lang/String;)V");
+ }
+
+ /* check if we have java.exe as worker process
+ * in that case don't call the startup class.
+ */
+ if (proc->java.jbin != NULL) {
+ return 0;
+ }
+ strclass = (*env)->FindClass(env, "java/lang/String");
+ if (proc->java.start_param) {
+ jstring arg = (*env)->NewStringUTF(env, proc->java.start_param);
+ jargs = (*env)->NewObjectArray(env, 1, strclass, NULL);
+ (*env)->SetObjectArrayElement(env, jargs, 0, arg);
+ }
+ (*env)->CallStaticVoidMethod(env,
+ proc->java.start_bridge,
+ proc->java.start_mid,
+ jargs);
+
+ DBPRINTF1("JVM Main class %s finished\n", proc->java.start_class);
+ return 0;
+cleanup:
+ if (proc->java.jvm) {
+ (*(proc->java.jvm))->DestroyJavaVM(proc->java.jvm);
+ FreeLibrary(proc->java.dll);
+ proc->java.dll = NULL;
+ proc->java.jvm = NULL;
+ }
+ return -1;
+}
+
+/* Thread that waits for child process to exit
+ * When the child process exits, it sets the
+ * event so that we can exit
+ */
+DWORD WINAPI wait_thread(LPVOID param)
+{
+ procrun_t *env = (procrun_t *)param;
+
+ /* Wait util a process has finished its initialization. */
+ WaitForInputIdle(env->c->pinfo.hProcess, INFINITE);
+ WaitForSingleObject(env->c->pinfo.hThread, INFINITE);
+ pool_close_handle(env->c->pool, env->c->pinfo.hThread);
+ env->c->pinfo.hThread = NULL;
+ env->c->pinfo.dwProcessId = 0;
+ SetEvent(env->m->events[1]);
+
+ return 0;
+}
+
+/* Redirected stdout reader thread
+ * It reads char at a time and writes
+ * either to stdout handle (file or pipe)
+ * or calls the gui console printer function.
+ */
+DWORD WINAPI stdout_thread(LPVOID param)
+{
+ unsigned char ch;
+ DWORD readed, written;
+ procrun_t *env = (procrun_t *)param;
+#ifdef PROCRUN_WINAPP
+ static unsigned char buff[MAX_PATH + 1];
+ int n = 0;
+#endif
+
+ while (env->c->h_stdout[3] &&
+ (ReadFile(env->c->h_stdout[3], &ch, 1, &readed, NULL) == TRUE)) {
+ if (readed) {
+#ifdef PROCRUN_WINAPP
+ if (ac_use_dlg) {
+ if (ch == '\n' || n >= MAX_PATH) {
+ buff[n] = '\0';
+ DBPRINTF1("RD %s", buff);
+ ac_add_list_string(buff, n, 0);
+ n = 0;
+ }
+ else if (ch == '\t' && n < (MAX_PATH - 4)) {
+ int i; /* replace the TAB with four spaces */
+ for (i = 0; i < 4; ++i)
+ buff[n++] = ' ';
+ }
+ else if (ch != '\r') /* skip the CR and BELL */
+ buff[n++] = ch;
+ else if (ch != '\b')
+ buff[n++] = ' ';
+ SwitchToThread();
+ }
+#endif
+ if (WriteFile(env->m->h_stdout[0], &ch, 1, &written, NULL) == TRUE) {
+ SwitchToThread();
+ }
+ else
+ break;
+ readed = 0;
+ }
+ }
+ /* The client has closed it side of a pipe
+ * meaning that he has finished
+ */
+ SetEvent(env->m->events[2]);
+ return 0;
+}
+
+/* Redirected stderr reader thread
+ * It reads char at a time and writes
+ * either to stderr handle (file or pipe)
+ * or calls the gui console printer function.
+ */
+
+DWORD WINAPI stderr_thread(LPVOID param)
+{
+ unsigned char ch;
+ DWORD readed, written;
+ procrun_t *env = (procrun_t *)param;
+#ifdef PROCRUN_WINAPP
+ static unsigned char buff[MAX_PATH + 1];
+ int n = 0;
+#endif
+
+ while (env->c->h_stderr[3] &&
+ (ReadFile(env->c->h_stderr[3], &ch, 1, &readed, NULL) == TRUE)) {
+ if (readed) {
+#ifdef PROCRUN_WINAPP
+ if (ac_use_dlg) {
+ if (ch == '\n' || n >= MAX_PATH) {
+ buff[n] = '\0';
+ DBPRINTF1("RD %s", buff);
+ ac_add_list_string(buff, n, 1);
+ n = 0;
+ }
+ else if (ch == '\t' && n < (MAX_PATH - 4)) {
+ int i;
+ for (i = 0; i < 4; ++i)
+ buff[n++] = ' ';
+ }
+ else if (ch != '\r')
+ buff[n++] = ch;
+ else if (ch != '\b')
+ buff[n++] = ' ';
+ SwitchToThread();
+ }
+#endif
+ if (WriteFile(env->m->h_stderr[0], &ch, 1, &written, NULL) == TRUE) {
+ SwitchToThread();
+ }
+ else
+ break;
+ readed = 0;
+ }
+ }
+ SetEvent(env->m->events[3]);
+ return 0;
+}
+
+/* Created redirection pipes, and close the unused sides.
+ *
+ */
+static int procrun_create_pipes(procrun_t *env)
+{
+ SECURITY_ATTRIBUTES sa;
+
+ sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+ sa.bInheritHandle = TRUE;
+ sa.lpSecurityDescriptor = NULL;
+
+ /* redirect stdout */
+ if (env->m->h_stdout[1] == INVALID_HANDLE_VALUE)
+ env->m->h_stdout[0] = GetStdHandle(STD_OUTPUT_HANDLE);
+ else
+ env->m->h_stdout[0] = env->m->h_stdout[1];
+
+ if (!CreatePipe(&env->c->h_stdout[0],
+ &env->c->h_stdout[1], &sa, 0)) {
+ DBPRINTF0(NULL);
+ return -1;
+ }
+ SetStdHandle(STD_OUTPUT_HANDLE, env->c->h_stdout[1]);
+ pool_handle(env->c->pool, env->c->h_stdout[1]);
+
+ if (!DuplicateHandle(env->m->pinfo.hProcess,
+ env->c->h_stdout[0],
+ env->m->pinfo.hProcess,
+ &env->c->h_stdout[3],
+ 0, FALSE, DUPLICATE_SAME_ACCESS)) {
+ DBPRINTF0(NULL);
+ return -1;
+ }
+ pool_close_handle(env->c->pool, env->c->h_stdout[0]);
+ pool_handle(env->c->pool, env->c->h_stdout[3]);
+
+ /* redirect stderr */
+ if (env->m->h_stderr[1] == INVALID_HANDLE_VALUE)
+ env->m->h_stderr[0] = GetStdHandle(STD_ERROR_HANDLE);
+ else
+ env->m->h_stderr[0] = env->m->h_stderr[1];
+
+ if (!CreatePipe(&env->c->h_stderr[0],
+ &env->c->h_stderr[1], &sa, 0)) {
+ DBPRINTF0(NULL);
+ return -1;
+ }
+ SetStdHandle(STD_ERROR_HANDLE, env->c->h_stderr[1]);
+ pool_handle(env->c->pool, env->c->h_stderr[1]);
+
+ if (!DuplicateHandle(env->m->pinfo.hProcess,
+ env->c->h_stderr[0],
+ env->m->pinfo.hProcess,
+ &env->c->h_stderr[3],
+ 0, FALSE, DUPLICATE_SAME_ACCESS)) {
+ DBPRINTF0(NULL);
+ return -1;
+ }
+ pool_close_handle(env->c->pool, env->c->h_stderr[0]);
+ pool_handle(env->c->pool, env->c->h_stderr[3]);
+
+ /* redirect stdin */
+ if (env->m->h_stdin[1] == INVALID_HANDLE_VALUE)
+ env->m->h_stdin[0] = GetStdHandle(STD_INPUT_HANDLE);
+ else
+ env->m->h_stdin[0] = env->m->h_stdin[1];
+
+ if (!CreatePipe(&env->c->h_stdin[0],
+ &env->c->h_stdin[1], &sa, 0)) {
+ DBPRINTF0(NULL);
+ return -1;
+ }
+ SetStdHandle(STD_INPUT_HANDLE, env->c->h_stdin[0]);
+ pool_handle(env->c->pool, env->c->h_stdin[0]);
+ if (!DuplicateHandle(env->m->pinfo.hProcess,
+ env->c->h_stdin[1],
+ env->m->pinfo.hProcess,
+ &env->c->h_stdin[3],
+ 0, FALSE, DUPLICATE_SAME_ACCESS)) {
+ DBPRINTF0(NULL);
+ return -1;
+ }
+
+ pool_close_handle(env->c->pool, env->c->h_stdin[1]);
+ pool_handle(env->c->pool, env->c->h_stdin[3]);
+
+ return 0;
+}
+
+/* Write the specified file to the childs stdin.
+ * This function wraps 'child.exe <some_file'
+ */
+static int procrun_write_stdin(procrun_t *env)
+{
+ DWORD readed, written;
+ char buf[PROC_BUFSIZE];
+
+ if (!env->m->service.infile)
+ return -1;
+
+ for (;;) {
+ if (!ReadFile(env->m->service.infile, buf, PROC_BUFSIZE,
+ &readed, NULL) || readed == 0)
+ break;
+ SwitchToThread();
+ if (!WriteFile(env->c->h_stdin[3], buf, readed,
+ &written, NULL))
+ break;
+ SwitchToThread();
+ }
+
+ /* Close the pipe handle so the child process stops reading. */
+ if (!pool_close_handle(env->c->pool, env->c->h_stdin[3]))
+ return -1;
+ env->c->h_stdin[3] = INVALID_HANDLE_VALUE;
+ return 0;
+}
+
+/* Make the command line for starting or stopping
+ * java process.
+ */
+static char * set_command_line(procrun_t *env, char *program, int starting){
+ int i, j, len = strlen(env->m->argw) + 8192;
+ char *opts[64], *nargw;
+ char *javaClass = starting ? env->m->java.start_class : env->m->java.stop_class,
+ *javaParam = starting ? env->m->java.start_param : env->m->java.stop_param;
+
+ j = make_array(env->m->java.opts, opts, 60, env->m);
+
+ for (i = 0; i < j; i++)
+ len += strlen(opts[i]);
+
+ nargw = pool_calloc(env->m->pool, len);
+ if(starting)
+ strcpy(nargw, env->m->argw);
+ else
+ strcpy(nargw, "java");
+ strcat(nargw, " ");
+ for (i = 0; i < j; i++) {
+ strcat(nargw, opts[i]);
+ strcat(nargw, " ");
+ }
+ strcat(nargw, "-Djava.class.path=");
+ if (strchr(program, ' ')) {
+ strcat(nargw, "\"");
+ strcat(nargw, program);
+ strcat(nargw, "\"");
+ }
+ else
+ strcat(nargw, program);
+ strcat(nargw, " ");
+ strcat(nargw, javaClass);
+ if (javaParam) {
+ strcat(nargw, " ");
+ strcat(nargw, javaParam);
+ }
+ env->m->argw = nargw;
+ program = env->m->java.jbin;
+ return program;
+}
+
+/* Main redirection function.
+ * Create the redirection pipes
+ * Make the child's environment
+ * Make the command line
+ * Logon as different user
+ * Create the child process
+ */
+int procrun_redirect(char *program, char **envp, procrun_t *env, int starting)
+{
+ STARTUPINFO si;
+ DWORD id;
+
+ if (!program) {
+#ifdef PROCRUN_WINAPP
+ MessageBox(NULL, "Service not found ", env->m->service.name,
+ MB_OK | MB_ICONERROR);
+#else
+ fprintf(stderr, "Service not found %s\n", env->m->service.name);
+#endif
+ return -1;
+ }
+ memset(&si, 0, sizeof(STARTUPINFO));
+ si.cb = sizeof(si);
+ si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
+ si.wShowWindow = SW_HIDE;
+
+ if(starting) {
+ if (procrun_create_pipes(env)) {
+ DBPRINTF0("Create pipe failed.\n");
+ return -1;
+ }
+ si.hStdOutput = env->c->h_stdout[1];
+ si.hStdError = env->c->h_stderr[1];
+ si.hStdInput = env->c->h_stdin[0];
+ }
+ else
+ si.dwFlags = STARTF_USESHOWWINDOW;
+
+ env->m->envw = make_environment(env->c->env, envp, env->m);
+ DBPRINTF1("Creating process %s.\n", program);
+ DBPRINTF1("Creating process %s.\n", env->m->argw);
+ /* for java.exe merge Arguments and Java options */
+ if (env->m->java.jbin) {
+ program = set_command_line(env, program, starting);
+ }
+ DBPRINTF2("RUN [%s] %s\n", program, env->m->argw);
+ if (env->m->service.account && env->m->service.password && starting) {
+ /* Run the child process under a different user account */
+ HANDLE user, token;
+ DBPRINTF2("RUNASUSER %s@%s\n", env->m->service.account, env->m->service.password);
+ if (!LogonUser(env->m->service.account,
+ NULL,
+ env->m->service.password,
+ LOGON32_LOGON_SERVICE,
+ LOGON32_PROVIDER_DEFAULT,
+ &user)) {
+ DBPRINTF0(NULL);
+ DBPRINTF0("LogonUser failed\n");
+ return -1;
+ }
+
+ DuplicateTokenEx(user,
+ TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY,
+ NULL,
+ SecurityImpersonation,
+ TokenPrimary,
+ &token);
+ DBPRINTF0(NULL);
+
+ DBPRINTF2("Launching as %s:%s", env->m->service.account, env->m->service.password);
+ ImpersonateLoggedOnUser(token);
+ DBPRINTF0(NULL);
+ si.lpDesktop = (LPSTR) "Winsta0\\Default";
+ if (!CreateProcessAsUser(token,
+ program,
+ env->m->argw,
+ NULL,
+ NULL,
+ TRUE,
+ CREATE_SUSPENDED | CREATE_NEW_CONSOLE |
+ CREATE_NEW_PROCESS_GROUP,
+ env->m->envw,
+ env->m->service.path,
+ &si,
+ &env->c->pinfo)) {
+
+ DBPRINTF1("Error redirecting '%s'\n", program);
+ DBPRINTF0(NULL);
+ return -1;
+ }
+ }
+ else {
+ if (!CreateProcess(program,
+ env->m->argw,
+ NULL,
+ NULL,
+ TRUE,
+ CREATE_SUSPENDED | CREATE_NEW_CONSOLE |
+ CREATE_NEW_PROCESS_GROUP,
+ env->m->envw,
+ env->m->service.path,
+ &si,
+ &env->c->pinfo)) {
+
+ DBPRINTF1("Error redirecting '%s'\n", program);
+ DBPRINTF0(NULL);
+ return -1;
+ }
+ }
+ DBPRINTF1("started child thread %08x",env->c->pinfo.hThread);
+ if(starting) {
+ pool_handle(env->c->pool, env->c->pinfo.hThread);
+ pool_handle(env->c->pool, env->c->pinfo.hProcess);
+
+ SetStdHandle(STD_OUTPUT_HANDLE, env->m->h_stdout[0]);
+ SetStdHandle(STD_ERROR_HANDLE, env->m->h_stderr[0]);
+ SetStdHandle(STD_INPUT_HANDLE, env->m->h_stdin[0]);
+ pool_close_handle(env->c->pool, env->c->h_stdout[1]);
+ pool_close_handle(env->c->pool, env->c->h_stderr[1]);
+ pool_close_handle(env->c->pool, env->c->h_stdin[0]);
+
+ CloseHandle(CreateThread(NULL, 0, stdout_thread, env, 0, &id));
+ CloseHandle(CreateThread(NULL, 0, stderr_thread, env, 0, &id));
+ ResumeThread(env->c->pinfo.hThread);
+ CloseHandle(CreateThread(NULL, 0, wait_thread, env, 0, &id));
+
+ procrun_write_stdin(env);
+ }
+ else
+ ResumeThread(env->c->pinfo.hThread);
+ return 0;
+}
+
+/* Delete the value from the registry
+ */
+static int del_service_param(process_t *proc, const char *name)
+{
+ HKEY key;
+ char skey[256];
+ DWORD err, c;
+
+ sprintf(skey, PROCRUN_REGKEY_RPARAMS, proc->service.name);
+ if ((err = RegCreateKeyEx(HKEY_LOCAL_MACHINE, skey, 0, NULL,
+ 0, KEY_ALL_ACCESS,
+ NULL, &key, &c)) != ERROR_SUCCESS) {
+ DBPRINTF0(NULL);
+ DBPRINTF2("Failed Opening [%s] [%d]\n", skey, err);
+ return -1;
+ }
+
+ err = RegDeleteValue(key, name);
+ RegCloseKey(key);
+ return (err != ERROR_SUCCESS);
+
+}
+
+/* Update or create the value in the registry
+ *
+ */
+static int set_service_param(process_t *proc, const char *name,
+ const char *value, int len, int service)
+{
+ HKEY key;
+ char skey[256];
+ DWORD err;
+ DWORD c, type = REG_SZ;
+
+
+ if (service == 1) {
+ sprintf(skey, PROCRUN_REGKEY_SERVICES, proc->service.name);
+ if ((err = RegOpenKeyEx(HKEY_LOCAL_MACHINE, skey,
+ 0, KEY_SET_VALUE, &key)) != ERROR_SUCCESS) {
+ DBPRINTF2("Failed Creating [%s] name [%s]\n", skey, name);
+ return -1;
+ }
+ }
+ else {
+ sprintf(skey, PROCRUN_REGKEY_RPARAMS, proc->service.name);
+ if ((err = RegCreateKeyEx(HKEY_LOCAL_MACHINE, skey, 0, NULL,
+ 0, KEY_SET_VALUE,
+ NULL, &key, &c)) != ERROR_SUCCESS) {
+ DBPRINTF0(NULL);
+ DBPRINTF2("Failed Creating [%s] [%d]\n", skey, err);
+ return -1;
+ }
+ }
+ DBPRINTF2("Creating [%s] name [%s]\n", skey, name);
+ DBPRINTF2("Creating [%s] value [%s]\n", skey, value);
+ if (value) {
+ if (service == 2)
+ type = REG_BINARY;
+ else if (len > 0)
+ type = REG_MULTI_SZ;
+ else
+ len = strlen(value);
+ err = RegSetValueEx(key, name, 0, type,
+ (unsigned char *)value, len);
+ }
+ else
+ err = RegSetValueEx(key, name, 0, REG_DWORD,
+ (unsigned char *)&len, sizeof(int));
+
+ RegCloseKey(key);
+ return (err != ERROR_SUCCESS);
+}
+static const char *location_jvm_default[] = {
+ "\\jre\\bin\\classic\\jvm.dll", /* Sun JDK 1.3 */
+ "\\bin\\classic\\jvm.dll", /* Sun JRE 1.3 */
+ "\\jre\\bin\\client\\jvm.dll", /* Sun JDK 1.4 */
+ "\\bin\\client\\jvm.dll", /* Sun JRE 1.4 */
+ NULL,
+};
+
+/*
+ * Attempt to locate the jvm from the installation.
+ */
+static char *procrun_find_java(process_t *proc, char *jhome)
+{
+ char path[MAX_PATH+1];
+ int x = 0;
+ HMODULE hm;
+ for(x=0; location_jvm_default[x] != NULL; x++) {
+ strcpy(path,jhome);
+ strcat(path,location_jvm_default[x]);
+ hm = LoadLibraryEx(path, NULL, 0);
+ if(hm != NULL) {
+ DBPRINTF1("Found library at %s\n",path);
+ FreeLibrary(hm);
+ return pool_strdup(proc->pool, path);
+ }
+ }
+ return NULL;
+}
+
+/*
+ * Process the arguments and fill the process_t stuct.
+ */
+static int process_args(process_t *proc, int argc, char **argv,
+ char **java, char *path)
+{
+ int arglen = 0;
+ char *argp;
+ int i,n, sp;
+
+ /* parse command line */
+ *java = NULL;
+ if (!GetModuleFileName(NULL, path, MAX_PATH -
+ strlen(proc->service.name) - 7)) {
+ DBPRINTF0("GetModuleFileName failed\n");
+ return -1;
+ }
+ strcat(path, " " PROC_ARG_RUN_SERVICE);
+ sp = strchr(proc->service.name, ' ') != NULL;
+ if(sp) {
+ strcat(path,"\"");
+ }
+ strcat(path, proc->service.name);
+ if(sp) {
+ strcat(path,"\"");
+ }
+ for (i = 2; i < argc; i++) {
+ DBPRINTF2("Parsing %d [%s]\n", i, argv[i]);
+ if (strlen(argv[i]) > 2 && argv[i][0] == '-' && argv[i][1] == '-') {
+ argp = &argv[i][2];
+ if (STRNI_COMPARE(argp, PROCRUN_PARAMS_IMAGE))
+ proc->service.image = pool_strdup(proc->pool, argv[++i]);
+ else if (STRNI_COMPARE(argp, PROCRUN_PARAMS_DESCRIPTION))
+ proc->service.description = pool_strdup(proc->pool, argv[++i]);
+ else if (STRNI_COMPARE(argp, PROCRUN_PARAMS_DISPLAY))
+ proc->service.display = argv[++i];
+ else if (STRNI_COMPARE(argp, PROCRUN_PARAMS_WORKPATH))
+ proc->service.path = pool_strdup(proc->pool, argv[++i]);
+ else if (STRNI_COMPARE(argp, PROCRUN_PARAMS_JVM_OPTS)) {
+ proc->java.opts = pool_calloc(proc->pool, strlen(argv[++i]) + 2);
+ strcpy(proc->java.opts, argv[i]);
+ }
+ else if (STRNI_COMPARE(argp, PROCRUN_PARAMS_JVM))
+ *java = argv[++i];
+ else if (STRNI_COMPARE(argp, PROCRUN_PARAMS_STDINFILE))
+ proc->service.inname = pool_strdup(proc->pool, argv[++i]);
+ else if (STRNI_COMPARE(argp, PROCRUN_PARAMS_STDOUTFILE))
+ proc->service.outname = pool_strdup(proc->pool, argv[++i]);
+ else if (STRNI_COMPARE(argp, PROCRUN_PARAMS_STDERRFILE))
+ proc->service.errname = pool_strdup(proc->pool, argv[++i]);
+ else if (STRNI_COMPARE(argp, PROCRUN_PARAMS_STARTCLASS))
+ proc->java.start_class = pool_strdup(proc->pool, argv[++i]);
+ else if (STRNI_COMPARE(argp, PROCRUN_PARAMS_STOPCLASS))
+ proc->java.stop_class = pool_strdup(proc->pool, argv[++i]);
+ else if (STRNI_COMPARE(argp, PROCRUN_PARAMS_STARTUP)) {
+ ++i;
+ if (stricmp(argv[i], "auto") == 0)
+ proc->service.startup = SERVICE_AUTO_START;
+ else if (stricmp(argv[i], "manual") == 0)
+ proc->service.startup = SERVICE_DEMAND_START;
+ }
+ else if (STRNI_COMPARE(argp, PROCRUN_PARAMS_ACCOUNT))
+ proc->service.account = pool_strdup(proc->pool, argv[++i]);
+ else if (STRNI_COMPARE(argp, PROCRUN_PARAMS_PASSWORD))
+ proc->service.password = pool_strdup(proc->pool, argv[++i]);
+ else if (STRNI_COMPARE(argp, PROCRUN_PARAMS_INSTALL)) {
+ strcpy(path, argv[++i]);
+ strcat(path, " " PROC_ARG_RUN_SERVICE);
+ if(sp) {
+ strcat(path,"\"");
+ }
+ strcat(path, proc->service.name);
+ if(sp) {
+ strcat(path, "\"");
+ }
+ }
+ else if (STRNI_COMPARE(argp, PROCRUN_PARAMS_ENVIRONMENT)) {
+ proc->service.environment = pool_strdup(proc->pool, argv[++i]);
+ }
+ else {
+ DBPRINTF1("Unrecognized option %s\n", argv[i]);
+ break;
+ }
+ }
+ else {
+ DBPRINTF1("Not an Command option option %s\n", argv[i]);
+ break;
+ }
+ }
+ if (*java && !strnicmp(*java, "java", 4)) {
+ arglen = strlen(*java) + 1;
+ } else if(*java) {
+ int jlen = strlen(*java) +1;
+ if(stricmp(*java+(jlen-5),".dll")) {
+ /* Assume it is the java installation */
+ char *njava = procrun_find_java(proc, *java);
+ DBPRINTF1("Attempting to locate jvm from %s\n",*java);
+ if(njava != NULL) {
+ *java = njava;
+ }
+ }
+ } else if (proc->service.name)
+ arglen = strlen(proc->service.name) + 1;
+ for (n = i; n < argc; n++) {
+ arglen += (strlen(argv[n]) + 1);
+ if (strchr(argv[n], ' '))
+ arglen += 2;
+ }
+ if (arglen) {
+ ++arglen;
+ proc->argw = (char *)pool_calloc(proc->pool, arglen);
+ if (*java && !strnicmp(*java, "java", 4))
+ strcpy(proc->argw, *java);
+ else
+ strcpy(proc->argw, proc->service.name);
+ for (n = i; n < argc; n++) {
+ strcat(proc->argw, " ");
+ if (strchr(argv[n], ' ')) {
+ strcat(proc->argw, "\"");
+ strcat(proc->argw, argv[n]);
+ strcat(proc->argw, "\"");
+ }
+ else
+ strcat(proc->argw, argv[n]);
+ DBPRINTF1("Adding cmdline %s\n", argv[n]);
+ }
+ }
+ if (!proc->service.startup)
+ proc->service.startup = SERVICE_AUTO_START;
+ return 0;
+}
+
+/*
+ * Save the parameters in registry
+ */
+void save_service_params(process_t *proc, char *java)
+{
+ int i;
+
+ if (proc->argw)
+ set_service_param(proc, PROCRUN_PARAMS_CMDARGS, proc->argw, 0, 0);
+ if (proc->service.description) {
+ set_service_param(proc, PROCRUN_PARAMS_DESCRIPTION,
+ proc->service.description, 0, 0);
+ set_service_param(proc, PROCRUN_PARAMS_DESCRIPTION,
+ proc->service.description, 0, 1);
+ }
+ if (proc->service.display) {
+ set_service_param(proc, PROCRUN_PARAMS_DISPLAY,
+ proc->service.display, 0, 0);
+ set_service_param(proc, PROCRUN_PARAMS_DISPLAY,
+ proc->service.display, 0, 1);
+ }
+ if (proc->service.image)
+ set_service_param(proc, PROCRUN_PARAMS_IMAGE,
+ proc->service.image, 0, 0);
+ if (proc->service.path)
+ set_service_param(proc, PROCRUN_PARAMS_WORKPATH,
+ proc->service.path, 0, 0);
+ if (proc->service.inname)
+ set_service_param(proc, PROCRUN_PARAMS_STDINFILE,
+ proc->service.inname, 0, 0);
+ if (proc->service.outname)
+ set_service_param(proc, PROCRUN_PARAMS_STDOUTFILE,
+ proc->service.outname, 0, 0);
+ if (proc->service.errname)
+ set_service_param(proc, PROCRUN_PARAMS_STDERRFILE,
+ proc->service.errname, 0, 0);
+ if (java)
+ set_service_param(proc, PROCRUN_PARAMS_JVM,
+ java, 0, 0);
+ if (proc->java.start_class)
+ set_service_param(proc, PROCRUN_PARAMS_STARTCLASS,
+ proc->java.start_class, 0, 0);
+ if (proc->java.stop_class)
+ set_service_param(proc, PROCRUN_PARAMS_STOPCLASS,
+ proc->java.stop_class, 0, 0);
+ /* Account and password allways comes as pair */
+ if (proc->service.account && proc->service.password) {
+ if (*proc->service.account == '-') {
+ del_service_param(proc, PROCRUN_PARAMS_ACCOUNT);
+ del_service_param(proc, PROCRUN_PARAMS_PASSWORD);
+ }
+ else {
+ unsigned char b[256];
+ set_service_param(proc, PROCRUN_PARAMS_ACCOUNT,
+ proc->service.account, 0, 0);
+ simple_encrypt(100, proc->service.password, b);
+ set_service_param(proc, PROCRUN_PARAMS_PASSWORD,
+ b, 256, 2);
+ }
+
+ }
+ if (proc->service.environment) {
+ int l = strlen(proc->service.environment);
+ for(i=0; i < l; i++) {
+ if(proc->service.environment[i] == '#')
+ proc->service.environment[i] = '\0';
+ }
+ set_service_param(proc, PROCRUN_PARAMS_ENVIRONMENT,
+ proc->service.environment, l+2, 0);
+ }
+
+
+ if (proc->service.startup != SERVICE_NO_CHANGE)
+ set_service_param(proc, PROCRUN_PARAMS_STARTUP,
+ proc->service.startup == SERVICE_AUTO_START ? "auto" : "manual",
+ 0, 0);
+
+ if (proc->java.opts) {
+ int l = strlen(proc->java.opts);
+ /* change the string to zero separated for MULTI_SZ */
+ for (i = 0; i < l; i ++) {
+ if (proc->java.opts[i] == '#')
+ proc->java.opts[i] = '\0';
+ }
+ set_service_param(proc, PROCRUN_PARAMS_JVM_OPTS,
+ proc->java.opts, l + 2, 0);
+ }
+}
+
+/* Install the service
+ */
+static int procrun_install_service(process_t *proc, int argc, char **argv)
+{
+ SC_HANDLE service;
+ SC_HANDLE manager;
+ char path[MAX_PATH+1] = {0};
+ char *java = NULL;
+
+ if (!proc->service.name) {
+ return -1;
+ }
+
+ if (process_args(proc, argc, argv, &java, path)) {
+ DBPRINTF0("Installing NT service: process_args failed\n");
+ return -1;
+ }
+
+ DBPRINTF2("Installing NT service %s %s", path, proc->service.display);
+
+ manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
+ if (!manager) {
+ return -1;
+ }
+
+ service = CreateService(manager,
+ proc->service.name,
+ proc->service.display,
+ SERVICE_ALL_ACCESS,
+ SERVICE_WIN32_OWN_PROCESS,
+ proc->service.startup,
+ SERVICE_ERROR_NORMAL,
+ path,
+ NULL,
+ NULL,
+ SERVICE_DEPENDENCIES,
+ NULL,
+ NULL);
+ if (service) {
+ CloseServiceHandle(service);
+ CloseServiceHandle(manager);
+ }
+ else {
+ DBPRINTF0("CreateService failed\n");
+ CloseServiceHandle(manager);
+ return -1;
+ }
+
+ /* Save parameters in registry */
+ save_service_params(proc,java);
+
+ DBPRINTF0("NT service installed succesfully\n");
+ SetEvent(proc->events[0]);
+ return 0;
+}
+
+/* Install service on win9x */
+static int procrun_install_service9x(process_t *proc, int argc, char **argv)
+{
+ HKEY hkey;
+ DWORD rv;
+ char szPath[MAX_PATH+1] = {0};
+
+ char path[MAX_PATH+1];
+ char *display = NULL;
+ char *java = NULL;
+
+ DBPRINTF0( "InstallSvc for non-NT\r\n");
+
+ if (!proc->service.name) {
+ return -1;
+ }
+
+ rv = RegCreateKey(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows"
+ "\\CurrentVersion\\RunServices", &hkey);
+ if (rv != ERROR_SUCCESS) {
+ DBPRINTF0( "Could not open the RunServices registry key\r\n");
+ return -1;
+ }
+
+ if (process_args(proc, argc, argv, &java, path)) {
+ DBPRINTF0("Installing service: process_args failed\n");
+ return -1;
+ }
+
+ DBPRINTF1("Installing service %s\n", path);
+
+ rv = RegSetValueEx(hkey, proc->service.name, 0, REG_SZ,
+ (unsigned char *) path,
+ strlen(path) + 1);
+ RegCloseKey(hkey);
+ if (rv != ERROR_SUCCESS) {
+ DBPRINTF2( "Could not add %s:%s to RunServices Registry Key\r\n",
+ proc->service.name, path);
+ return -1;
+ }
+
+ strcpy(szPath,
+ "SYSTEM\\CurrentControlSet\\Services\\");
+ strcat(szPath,proc->service.name);
+ rv = RegCreateKey(HKEY_LOCAL_MACHINE, szPath, &hkey);
+ if (rv != ERROR_SUCCESS) {
+ DBPRINTF1( "Could not create/open the %s registry key\r\n",
+ szPath);
+ return -1;
+ }
+ rv = RegSetValueEx(hkey, "ImagePath", 0, REG_SZ,
+ (unsigned char *) path,
+ strlen(path) + 1);
+ if (rv != ERROR_SUCCESS) {
+ RegCloseKey(hkey);
+ DBPRINTF0( "Could not add ImagePath to our Registry Key\r\n");
+ return -1;
+ }
+ rv = RegSetValueEx(hkey, "DisplayName", 0, REG_SZ,
+ (unsigned char *) proc->service.display,
+ strlen(proc->service.display) + 1);
+ RegCloseKey(hkey);
+ if (rv != ERROR_SUCCESS) {
+ DBPRINTF0( "Could not add DisplayName to our Registry Key\r\n");
+ return -1;
+ }
+
+ /* Save parameters in registry */
+ save_service_params(proc,java);
+
+ DBPRINTF0("service installed succesfully\n");
+ SetEvent(proc->events[0]);
+ return 0;
+}
+
+/* Update the service parameters
+ * This is the main parser for //US//
+ */
+int procrun_update_service(process_t *proc, int argc, char **argv)
+{
+ SC_HANDLE service;
+ SC_HANDLE manager;
+ char *argp;
+ char path[MAX_PATH+1];
+ char *java = NULL;
+ int arglen = 0, sp;
+
+ int i, n;
+ if (!proc->service.name) {
+ return -1;
+ }
+ if (!GetModuleFileName(NULL, path, MAX_PATH -
+ strlen(proc->service.name) - 7)) {
+ DBPRINTF0(NULL);
+ return -1;
+ }
+ sp = strchr(proc->service.name, ' ') != NULL;
+ strcat(path, " " PROC_ARG_RUN_SERVICE);
+ if(sp) {
+ strcat(path,"\"");
+ }
+ strcat(path, proc->service.name);
+ if(sp) {
+ strcat(path, "\"");
+ }
+ DBPRINTF1("Updating service %s\n", path);
+
+ manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
+ if (!manager) {
+ DBPRINTF0(NULL);
+ return -1;
+ }
+ service = OpenService(manager, proc->service.name, SERVICE_ALL_ACCESS);
+ if (!service) {
+ DBPRINTF0(NULL);
+ CloseServiceHandle(manager);
+ return -1;
+ }
+ proc->service.startup = SERVICE_NO_CHANGE;
+ proc->service.image = NULL;
+ proc->service.description = NULL;
+ proc->service.path = NULL;
+ proc->service.inname = NULL;
+ proc->service.outname = NULL;
+ proc->service.errname = NULL;
+ proc->java.start_class = NULL;
+ proc->java.stop_class = NULL;
+ proc->java.opts = NULL;
+ proc->service.account = NULL;
+ proc->service.password = NULL;
+ proc->service.display = NULL;
+ proc->argw = NULL;
+ /* parse command line */
+ for (i = 2; i < argc; i++) {
+ if (strlen(argv[i]) > 2 && argv[i][0] == '-' && argv[i][1] == '-') {
+ argp = &argv[i][2];
+ if (STRNI_COMPARE(argp, PROCRUN_PARAMS_IMAGE))
+ proc->service.image = pool_strdup(proc->pool, argv[++i]);
+ else if (STRNI_COMPARE(argp, PROCRUN_PARAMS_DESCRIPTION))
+ proc->service.description = pool_strdup(proc->pool, argv[++i]);
+ else if (STRNI_COMPARE(argp, PROCRUN_PARAMS_DISPLAY))
+ proc->service.display = argv[++i];
+ else if (STRNI_COMPARE(argp, PROCRUN_PARAMS_WORKPATH))
+ proc->service.path = pool_strdup(proc->pool, argv[++i]);
+ else if (STRNI_COMPARE(argp, PROCRUN_PARAMS_JVM_OPTS)) {
+ proc->java.opts = pool_calloc(proc->pool, strlen(argv[++i]) + 2);
+ strcpy(proc->java.opts, argv[i]);
+ }
+ else if (STRNI_COMPARE(argp, PROCRUN_PARAMS_JVM))
+ java = argv[++i];
+ else if (STRNI_COMPARE(argp, PROCRUN_PARAMS_STDINFILE))
+ proc->service.inname = pool_strdup(proc->pool, argv[++i]);
+ else if (STRNI_COMPARE(argp, PROCRUN_PARAMS_STDOUTFILE))
+ proc->service.outname = pool_strdup(proc->pool, argv[++i]);
+ else if (STRNI_COMPARE(argp, PROCRUN_PARAMS_STDERRFILE))
+ proc->service.errname = pool_strdup(proc->pool, argv[++i]);
+ else if (STRNI_COMPARE(argp, PROCRUN_PARAMS_STARTCLASS))
+ proc->java.start_class = pool_strdup(proc->pool, argv[++i]);
+ else if (STRNI_COMPARE(argp, PROCRUN_PARAMS_STOPCLASS))
+ proc->java.stop_class = pool_strdup(proc->pool, argv[++i]);
+ else if (STRNI_COMPARE(argp, PROCRUN_PARAMS_STARTUP)) {
+ ++i;
+ if (stricmp(argv[i], "auto") == 0)
+ proc->service.startup = SERVICE_AUTO_START;
+ else if (stricmp(argv[i], "manual") == 0)
+ proc->service.startup = SERVICE_DEMAND_START;
+ }
+ else if (STRNI_COMPARE(argp, PROCRUN_PARAMS_ACCOUNT))
+ proc->service.account = pool_strdup(proc->pool, argv[++i]);
+ else if (STRNI_COMPARE(argp, PROCRUN_PARAMS_PASSWORD))
+ proc->service.password = pool_strdup(proc->pool, argv[++i]);
+ else if (STRNI_COMPARE(argp, PROCRUN_PARAMS_ENVIRONMENT))
+ proc->service.environment = pool_strdup(proc->pool, argv[++i]);
+ else
+ break;
+ }
+ else
+ break;
+ }
+
+ if (java && strnicmp(java, "java", 4)) {
+ int jlen = strlen(java) + 1;
+ if(stricmp(java+(jlen-5),".dll")) {
+ /* Assume it is the java installation */
+ char *njava = procrun_find_java(proc, java);
+ DBPRINTF1("Attempting to locate jvm from %s\n",java);
+ if(njava != NULL) {
+ java = njava;
+ }
+ }
+ }
+
+ if (i < argc) {
+ if (java && !strnicmp(java, "java", 4))
+ arglen = strlen(java) + 1;
+ else if (proc->service.name)
+ arglen = strlen(proc->service.name) + 1;
+ for (n = i; n < argc; n++) {
+ arglen += strlen(argv[n]) + 1;
+ if (strchr(argv[n], ' '))
+ arglen += 2;
+ }
+ if (arglen) {
+ ++arglen;
+ proc->argw = (char *)pool_calloc(proc->pool, arglen);
+ if (java && !strnicmp(java, "java", 4))
+ strcpy(proc->argw, java);
+ else
+ strcpy(proc->argw, proc->service.name);
+ for (n = i; n < argc; n++) {
+ strcat(proc->argw, " ");
+ if (strchr(argv[n], ' ')) {
+ strcat(proc->argw, "\"");
+ strcat(proc->argw, argv[n]);
+ strcat(proc->argw, "\"");
+ }
+ else
+ strcat(proc->argw, argv[n]);
+ DBPRINTF1("Adding cmdline %s\n", argv[n]);
+ }
+ }
+ }
+ ChangeServiceConfig(service,
+ SERVICE_NO_CHANGE,
+ proc->service.startup,
+ SERVICE_NO_CHANGE,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ proc->service.display);
+
+ CloseServiceHandle(service);
+ CloseServiceHandle(manager);
+
+ save_service_params(proc,java);
+
+ return 0;
+}
+
+/* Delete the service
+ * Removes the service form registry and SCM.
+ * Stop the service if running.
+ */
+static int procrun_delete_service(process_t *proc)
+{
+ SC_HANDLE service;
+ SC_HANDLE manager;
+ SERVICE_STATUS status;
+ char skey[MAX_PATH+1];
+ DWORD err;
+
+ if (!proc->service.name) {
+ return -1;
+ }
+ DBPRINTF1("Deleting service %s", proc->service.name);
+
+ sprintf(skey, PROCRUN_REGKEY_RSERVICES, proc->service.name);
+ if ((err = SHDeleteKey(HKEY_LOCAL_MACHINE, skey)) != ERROR_SUCCESS) {
+ DBPRINTF2("Failed Deleting [%s] [%d]\n", skey, err);
+ }
+
+ manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
+ if (!manager) {
+ DBPRINTF0(NULL);
+ return -1;
+ }
+ service = OpenService(manager, proc->service.name, SERVICE_ALL_ACCESS);
+
+ if (service) {
+ BOOL ss = FALSE;
+ QueryServiceStatus(service, &status);
+ if (status.dwCurrentState != SERVICE_RUNNING)
+ ss = DeleteService(service);
+ else {
+ /* Stop the service */
+ if (ControlService(service, SERVICE_CONTROL_STOP, &status)) {
+ Sleep(1000);
+ while (QueryServiceStatus(service, &status)) {
+ if (status.dwCurrentState == SERVICE_STOP_PENDING)
+ Sleep(1000);
+ else
+ break;
+ }
+ }
+ QueryServiceStatus(service, &status);
+ if (status.dwCurrentState != SERVICE_RUNNING)
+ ss = DeleteService(service);
+ }
+ CloseServiceHandle(service);
+ CloseServiceHandle(manager);
+ if (!ss)
+ return -1;
+ }
+ else {
+ DBPRINTF0(NULL);
+ CloseServiceHandle(manager);
+ return -1;
+ }
+ DBPRINTF0("NT service deleted succesfully\n");
+ SetEvent(proc->events[0]);
+ return 0;
+}
+
+/* remove service (non NT) stopping it looks ugly!!! so we let it run. */
+static int procrun_delete_service9x(process_t *proc)
+{
+ HKEY hkey;
+ DWORD rv;
+
+ if (!proc->service.name) {
+ return -1;
+ }
+ DBPRINTF1("Deleting service %s", proc->service.name);
+
+ rv = RegOpenKey(HKEY_LOCAL_MACHINE,
+ "Software\\Microsoft\\Windows\\CurrentVersion\\RunServices",
+ &hkey);
+ if (rv != ERROR_SUCCESS) {
+ DBPRINTF0( "Could not open the RunServices registry key.\r\n");
+ return -1;
+ }
+ rv = RegDeleteValue(hkey, proc->service.name);
+ RegCloseKey(hkey);
+ if (rv != ERROR_SUCCESS)
+ DBPRINTF0( "Could not delete the RunServices entry.\r\n");
+
+ rv = RegOpenKey(HKEY_LOCAL_MACHINE,
+ "SYSTEM\\CurrentControlSet\\Services", &hkey);
+ if (rv != ERROR_SUCCESS) {
+ DBPRINTF0( "Could not open the Services registry key.\r\n");
+ return -1;
+ }
+ rv = RegDeleteKey(hkey, proc->service.name);
+ RegCloseKey(hkey);
+ if (rv != ERROR_SUCCESS) {
+ DBPRINTF0( "Could not delete the Services registry key.\r\n");
+ return -1;
+ }
+ DBPRINTF0("service deleted succesfull\n");
+ SetEvent(proc->events[0]);
+ return 0;
+}
+
+/* This is the WndProc procedure for our invisible window.
+ * When our subclasssed tty window receives the WM_CLOSE, WM_ENDSESSION,
+ * or WM_QUERYENDSESSION messages, the message is dispatched to our hidden
+ * window (this message process), and we call the installed HandlerRoutine
+ * that was registered by the app.
+ */
+#ifndef ENDSESSION_LOGOFF
+#define ENDSESSION_LOGOFF 0x80000000
+#endif
+static LRESULT CALLBACK ttyConsoleCtrlWndProc(HWND hwnd, UINT msg,
+ WPARAM wParam, LPARAM lParam)
+{
+
+ if (msg == WM_CREATE) {
+ DBPRINTF0("ttyConsoleCtrlWndProc WM_CREATE\n");
+ return 0;
+ } else if (msg == WM_DESTROY) {
+ DBPRINTF0("ttyConsoleCtrlWndProc WM_DESTROY\n");
+ return 0;
+ } else if (msg == WM_CLOSE) {
+ /* Call StopService?. */
+ DBPRINTF0("ttyConsoleCtrlWndProc WM_CLOSE\n");
+ return 0; /* May return 1 if StopService failed. */
+ } else if ((msg == WM_QUERYENDSESSION) || (msg == WM_ENDSESSION)) {
+ if (lParam & ENDSESSION_LOGOFF) {
+ /* Here we have nothing to our hidden windows should stay. */
+ DBPRINTF0(TEXT("ttyConsoleCtrlWndProc LOGOFF\n"));
+ return(1); /* Otherwise it cancels the logoff */
+ } else {
+ /* Stop Service. */
+ DBPRINTF0("ttyConsoleCtrlWndProc SHUTDOWN\n");
+ SetEvent(g_env->m->events[0]);
+
+ /* Wait for the JVM to stop */
+ DBPRINTF1("Stopping: main thread %08x\n",g_env->m->pinfo.hThread);
+ if (g_env->m->pinfo.hThread != NULL) {
+ DBPRINTF0("ttyConsoleCtrlWndProc waiting for main\n");
+ WaitForSingleObject(g_env->m->pinfo.hThread, 60000);
+ DBPRINTF0("ttyConsoleCtrlWndProc main thread finished\n");
+ }
+
+ return(1); /* Otherwise it cancels the shutdown. */
+ }
+ }
+ return (DefWindowProc(hwnd, msg, wParam, lParam));
+}
+/* ttyConsoleCreateThread is the process that runs within the user app's
+ * context. It creates and pumps the messages of a hidden monitor window,
+ * watching for messages from the system, or the associated subclassed tty
+ * window. Things can happen in our context that can't be done from the
+ * tty's context, and visa versa, so the subclass procedure and this hidden
+ * window work together to make it all happen.
+ */
+static DWORD WINAPI ttyConsoleCtrlThread(LPVOID param)
+{
+ HWND monitor_hwnd;
+ WNDCLASS wc;
+ MSG msg;
+ wc.style = CS_GLOBALCLASS;
+ wc.lpfnWndProc = ttyConsoleCtrlWndProc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 8;
+ wc.hInstance = NULL;
+ wc.hIcon = NULL;
+ wc.hCursor = NULL;
+ wc.hbrBackground = NULL;
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = "ApacheJakartaService";
+
+ if (!RegisterClass(&wc)) {
+ DBPRINTF0("RegisterClass failed\n");
+ return 0;
+ }
+
+ /* Create an invisible window */
+ monitor_hwnd = CreateWindow(wc.lpszClassName,
+ "ApacheJakartaService",
+ WS_OVERLAPPED & ~WS_VISIBLE,
+ CW_USEDEFAULT, CW_USEDEFAULT,
+ CW_USEDEFAULT, CW_USEDEFAULT,
+ NULL, NULL,
+ GetModuleHandle(NULL), NULL);
+
+ if (!monitor_hwnd) {
+ DBPRINTF0("RegisterClass failed\n");
+ return 0;
+ }
+
+ while (GetMessage(&msg, NULL, 0, 0))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+
+ return 0;
+}
+/*
+ * Register the process to resist logoff and start the thread that will receive
+ * the shutdown via a hidden window.
+ */
+BOOL Windows9xServiceCtrlHandler()
+{
+ HANDLE hThread;
+ DWORD tid;
+ HINSTANCE hkernel;
+ DWORD (WINAPI *register_service_process)(DWORD, DWORD) = NULL;
+
+ /* If we have not yet done so */
+ FreeConsole();
+
+ /* Make sure the process will resist logoff */
+ hkernel = LoadLibrary("KERNEL32.DLL");
+ if (!hkernel) {
+ DBPRINTF0("LoadLibrary KERNEL32.DLL failed\n");
+ return 0;
+ }
+ register_service_process = (DWORD (WINAPI *)(DWORD, DWORD))
+ GetProcAddress(hkernel, "RegisterServiceProcess");
+ if (register_service_process == NULL) {
+ DBPRINTF0("dlsym RegisterServiceProcess failed\n");
+ return 0;
+ }
+ if (!register_service_process(0,TRUE)) {
+ FreeLibrary(hkernel);
+ DBPRINTF0("register_service_process failed\n");
+ return 0;
+ }
+ DBPRINTF0("procrun registered as a service\n");
+
+ /*
+ * To be handle notice the shutdown, we need a thread and window.
+ */
+ hThread = CreateThread(NULL, 0, ttyConsoleCtrlThread,
+ (LPVOID)NULL, 0, &tid);
+ if (hThread) {
+ CloseHandle(hThread);
+ return TRUE;
+ }
+ DBPRINTF0("jsvc shutdown listener start failed\n");
+ return TRUE;
+}
+
+/* Report the service status to the SCM
+ */
+int report_service_status(DWORD dwCurrentState,
+ DWORD dwWin32ExitCode,
+ DWORD dwWaitHint,
+ process_t *proc)
+{
+ static DWORD dwCheckPoint = 1;
+ BOOL fResult = TRUE;
+
+ if (proc->service.mode && proc->service.h_status) {
+ if (dwCurrentState == SERVICE_START_PENDING)
+ proc->service.status.dwControlsAccepted = 0;
+ else
+ proc->service.status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
+
+ proc->service.status.dwCurrentState = dwCurrentState;
+ proc->service.status.dwWin32ExitCode = dwWin32ExitCode;
+ proc->service.status.dwWaitHint = dwWaitHint;
+
+ if ((dwCurrentState == SERVICE_RUNNING) ||
+ (dwCurrentState == SERVICE_STOPPED))
+ proc->service.status.dwCheckPoint = 0;
+ else
+ proc->service.status.dwCheckPoint = dwCheckPoint++;
+ if (g_is_windows_nt)
+ fResult = SetServiceStatus(proc->service.h_status, &proc->service.status);
+ if (!fResult) {
+ DBPRINTF0("SetServiceStatus Failed\n");
+ DBPRINTF0(NULL);
+ }
+ }
+ return fResult;
+}
+
+/* Service controll handler
+ */
+void WINAPI service_ctrl(DWORD dwCtrlCode)
+{
+ switch (dwCtrlCode) {
+ case SERVICE_CONTROL_STOP:
+ report_service_status(SERVICE_STOP_PENDING, NO_ERROR, 0,
+ g_env->m);
+ DBPRINTF0("ServiceCtrl STOP\n");
+ SetEvent(g_env->m->events[0]);
+ return;
+ case SERVICE_CONTROL_INTERROGATE:
+ break;
+ default:
+ break;
+ }
+
+ report_service_status(g_env->m->service.status.dwCurrentState,
+ NO_ERROR, 0, g_env->m);
+}
+
+/* Console controll handler
+ *
+ */
+BOOL WINAPI console_ctrl(DWORD dwCtrlType)
+{
+ switch (dwCtrlType) {
+ case CTRL_BREAK_EVENT:
+ DBPRINTF0("Captured CTRL+BREAK Event\n");
+ SetEvent(g_env->m->events[0]);
+ return TRUE;
+ case CTRL_C_EVENT:
+ DBPRINTF0("Captured CTRL+C Event\n");
+ SetEvent(g_env->m->events[0]);
+ return TRUE;
+ case CTRL_CLOSE_EVENT:
+ DBPRINTF0("Captured CLOSE Event\n");
+ SetEvent(g_env->m->events[0]);
+ return TRUE;
+ case CTRL_SHUTDOWN_EVENT:
+ DBPRINTF0("Captured SHUTDOWN Event\n");
+ SetEvent(g_env->m->events[0]);
+ return TRUE;
+ break;
+
+ }
+ return FALSE;
+}
+
+/* Main JVM thread
+ * Like redirected process, the redirected JVM application
+ * is run in the separate thread.
+ */
+DWORD WINAPI java_thread(LPVOID param)
+{
+ DWORD rv;
+ procrun_t *env = (procrun_t *)param;
+
+ if (!param)
+ return -1;
+ rv = procrun_init_jvm(env->m);
+ jni_detach(env->m);
+
+ SetEvent(env->m->events[0]);
+ return rv;
+}
+
+int service_main(int argc, char **argv)
+{
+ DWORD fired = 0;
+ HANDLE jh;
+ int rv = -1;
+
+
+ g_env->m->service.status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
+ g_env->m->service.status.dwCurrentState = SERVICE_START_PENDING;
+ g_env->m->service.status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE;
+ g_env->m->service.status.dwWin32ExitCode = 0;
+ g_env->m->service.status.dwServiceSpecificExitCode = 0;
+ g_env->m->service.status.dwCheckPoint = 0;
+ g_env->m->service.status.dwWaitHint = 0;
+
+ g_env->m->service.status.dwServiceSpecificExitCode = 0;
+ if (g_env->m->service.mode && g_is_windows_nt) {
+ g_env->m->service.h_status = RegisterServiceCtrlHandler(g_env->m->service.name,
+ service_ctrl);
+ if (!g_env->m->service.h_status)
+ goto cleanup;
+ } else
+ g_env->m->service.h_status = 0;
+
+ report_service_status(SERVICE_START_PENDING, NO_ERROR, 3000,
+ g_env->m);
+ if (g_env->m->java.dll) {
+ if (g_env->m->java.jbin == NULL) {
+ DWORD id;
+ /* Create the main JVM thread so we don't get blocked */
+ jh = CreateThread(NULL, 0, java_thread, g_env, 0, &id);
+ pool_handle(g_env->m->pool, jh);
+ rv = 0;
+ }
+ else {
+ /* Redirect java or javaw */
+ if ((rv = procrun_init_jvm(g_env->m)) == 0) {
+ rv = procrun_redirect(g_env->m->service.image,
+ g_env->m->envp, g_env, 1);
+ }
+ }
+ }
+ else {
+ rv = procrun_redirect(g_env->m->service.image,
+ g_env->m->envp, g_env, 1);
+ }
+ if (rv == 0) {
+ report_service_status(SERVICE_RUNNING, NO_ERROR, 0,
+ g_env->m);
+ DBPRINTF2("Service %s Started %d\n", g_env->m->service.name, rv);
+
+ }
+ /* Wait for shutdown event or child exit */
+ while (rv == 0) {
+ fired = WaitForMultipleObjects(4, g_env->m->events,
+ FALSE, INFINITE);
+
+ if (fired == WAIT_OBJECT_0 ||
+ fired == (WAIT_OBJECT_0 + 1) ||
+ fired == WAIT_TIMEOUT)
+ break;
+ }
+
+cleanup:
+ DBPRINTF1("Stoping Service %s\n", g_env->m->service.name);
+ report_service_status(SERVICE_STOP_PENDING, NO_ERROR, 3000,
+ g_env->m);
+ procrun_destroy_jvm(g_env->m, jh);
+
+ inject_exitprocess(&g_env->c->pinfo);
+ report_service_status(SERVICE_STOPPED, 0, 0,
+ g_env->m);
+
+ DBPRINTF0("Setting Shutdown Event 0\n");
+ SetEvent(g_env->m->events[0]);
+ return rv;
+}
+
+/* Procrun main function
+ */
+int procrun_main(int argc, char **argv, char **envp, procrun_t *env)
+{
+ int i, mode = 0;
+ char event[64];
+ DWORD fired;
+ int rv = -1;
+ OSVERSIONINFO osver;
+ HANDLE handle;
+ BOOL isok;
+
+ SERVICE_TABLE_ENTRY dispatch_table[] = {
+ {NULL, NULL},
+ {NULL, NULL}
+ };
+
+ osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ if (GetVersionEx(&osver)) {
+ if (osver.dwPlatformId >= VER_PLATFORM_WIN32_NT)
+ g_is_windows_nt = 1;
+ }
+ DBPRINTF1("OS Version %d\n", g_is_windows_nt);
+
+ /* Set console handler to capture CTRL events */
+ SetConsoleCtrlHandler((PHANDLER_ROUTINE)console_ctrl, TRUE);
+ env->m->pool = pool_create();
+ env->c->pool = pool_create();
+ for (i = 0; i < 4; i ++) {
+ env->m->h_stdin[i] = INVALID_HANDLE_VALUE;
+ env->m->h_stdout[i] = INVALID_HANDLE_VALUE;
+ env->m->h_stderr[i] = INVALID_HANDLE_VALUE;
+ env->c->h_stdin[i] = INVALID_HANDLE_VALUE;
+ env->c->h_stdout[i] = INVALID_HANDLE_VALUE;
+ env->c->h_stderr[i] = INVALID_HANDLE_VALUE;
+ }
+
+ env->m->pinfo.dwProcessId = GetCurrentProcessId();
+ env->m->pinfo.dwThreadId = GetCurrentThreadId();
+
+ isok = DuplicateHandle(GetCurrentProcess(),GetCurrentProcess(),
+ GetCurrentProcess(),&handle,PROCESS_ALL_ACCESS,
+ FALSE,0);
+ if (isok)
+ env->m->pinfo.hProcess = handle;
+ else {
+ DBPRINTF0("DuplicateHandle failed on Process\n");
+ env->m->pinfo.hProcess = GetCurrentProcess();
+ }
+
+
+ isok = DuplicateHandle(GetCurrentProcess(),GetCurrentThread(),
+ GetCurrentProcess(),&handle,PROCESS_ALL_ACCESS,
+ FALSE,0);
+ if (isok)
+ env->m->pinfo.hThread = handle;
+ else {
+ DBPRINTF0("DuplicateHandle failed on Thread\n");
+ env->m->pinfo.hThread = GetCurrentThread();
+ }
+ env->m->envp = envp;
+
+ DBPRINTF2("handles: proc %08x thread %08x\n",env->m->pinfo.hProcess,env->m->pinfo.hThread);
+
+ SetProcessShutdownParameters(0x300, SHUTDOWN_NORETRY);
+ if (argc > 1)
+ mode = parse_args(argc, argv, env->m);
+ else /* nothing to do. exit... */
+ return 0;
+
+ procrun_readenv(env->m, envp);
+
+ /* Add the pid to the client env */
+ procrun_addenv(PROCRUN_ENV_PPID, NULL, (int)GetCurrentProcessId(),
+ env->m);
+
+ procrun_service_params(env->m);
+ /* Check if we have a JVM */
+ if (procrun_load_jvm(env->m, mode) < 0)
+ goto cleanup;
+ if(env->m->service.environment) {
+ char *nenv = env->m->service.environment;
+ while(*nenv) {
+ char *cenv = pool_strdup(env->c->pool, nenv);
+ char *equals = strchr(cenv, '=');
+ if(equals != NULL) {
+ char *value = nenv + (equals-cenv)+1;
+ *++equals = '\0';
+ procrun_addenv(cenv, value, 0, env->c);
+ }
+ nenv += strlen(nenv)+1;
+ }
+ }
+ /* Create the four events that will cause us to exit
+ */
+ sprintf(event, "PROC_SHUTDOWN_EVENT%d", GetCurrentProcessId());
+ env->m->events[0] = CreateEvent(NULL, TRUE, FALSE, event);
+ sprintf(event, "PROC_EXITWAIT_EVENT%d", GetCurrentProcessId());
+ env->m->events[1] = CreateEvent(NULL, TRUE, FALSE, event);
+ sprintf(event, "PROC_CLOSESTDOUT_EVENT%d", GetCurrentProcessId());
+ env->m->events[2] = CreateEvent(NULL, TRUE, FALSE, event);
+ sprintf(event, "PROC_CLOSESTDERR_EVENT%d", GetCurrentProcessId());
+ env->m->events[3] = CreateEvent(NULL, TRUE, FALSE, event);
+ pool_handle(env->m->pool, env->m->events[0]);
+ pool_handle(env->m->pool, env->m->events[1]);
+ pool_handle(env->m->pool, env->m->events[2]);
+ pool_handle(env->m->pool, env->m->events[3]);
+
+ DBPRINTF2("running in mode %d %p\n", mode, env->m->java.dll);
+ DBPRINTF1("Events %p\n", env->m->events[0]);
+
+ switch (mode) {
+ /* Standard run modes */
+ case PROCRUN_CMD_TEST_SERVICE:
+#ifdef PROCRUN_WINAPP
+ /*
+ * GUIT: Display as Try application
+ * GUOD: Immediately popup console dialog wrapper
+ */
+ case PROCRUN_CMD_GUIT_SERVICE:
+ case PROCRUN_CMD_GUID_SERVICE:
+ {
+ DWORD gi;
+ /* This one if for about box */
+ LoadLibrary("riched32.dll");
+ CreateThread(NULL, 0, gui_thread, g_env, 0, &gi);
+ }
+#else
+ if (env->m->service.description)
+ SetConsoleTitle(env->m->service.description);
+ else if (env->m->service.name)
+ SetConsoleTitle(env->m->service.name);
+#endif
+#ifdef _DEBUG
+ debug_process(argc, argv, env->m);
+#endif
+ service_main(argc, argv);
+ break;
+#ifdef PROCRUN_WINAPP
+ /* Display the service properties dialog
+ */
+ case PROCRUN_CMD_EDIT_SERVICE:
+ LoadLibrary("riched32.dll");
+ gui_thread(g_env);
+ break;
+#endif
+ /* Management modes */
+ case PROCRUN_CMD_INSTALL_SERVICE:
+ if (g_is_windows_nt)
+ rv = procrun_install_service(env->m, argc, argv);
+ else
+ rv = procrun_install_service9x(env->m, argc, argv);
+ break;
+ case PROCRUN_CMD_UPDATE_SERVICE:
+ if (g_is_windows_nt) {
+ rv = procrun_update_service(env->m, argc, argv);
+ SetEvent(env->m->events[0]);
+ }
+ else {
+ // rv = procrun_update_service9x(env->m, argc, argv);
+ rv = -1;
+ DBPRINTF0("UPDATE SERVICE is unimplemented on 9x for now\n");
+ }
+ break;
+ case PROCRUN_CMD_DELETE_SERVICE:
+ if (g_is_windows_nt)
+ rv = procrun_delete_service(env->m);
+ else
+ rv = procrun_delete_service9x(env->m);
+ break;
+ case PROCRUN_CMD_STOP_SERVICE:
+ rv = -1;
+ DBPRINTF0("STOP SERVICE is unimplemented for now\n");
+ break;
+ case PROCRUN_CMD_RUN_SERVICE:
+ if (g_proc_stderr_file==0) {
+ g_proc_stderr_file = open("c:/jakarta-service.log",O_CREAT|O_APPEND|O_RDWR);
+ if (g_proc_stderr_file < 0)
+ g_proc_stderr_file = 0;
+ }
+ debug_process(argc, argv, env->m);
+ env->m->service.mode = 1;
+ if (g_is_windows_nt) {
+ dispatch_table[0].lpServiceName = env->m->service.name;
+ dispatch_table[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)service_main;
+ rv = (StartServiceCtrlDispatcher(dispatch_table) == FALSE);
+ } else {
+ Windows9xServiceCtrlHandler();
+ service_main(argc,argv);
+ }
+ break;
+#ifdef PROCRUN_WINAPP
+ case PROCRUN_CMD_GUID_PROCESS:
+ /* run as WIN32 application */
+ {
+ DWORD gi;
+ ac_use_try = 1;
+ LoadLibrary("riched32.dll");
+ CreateThread(NULL, 0, gui_thread, g_env, 0, &gi);
+ }
+ env->m->service.name = argv[0];
+ env->m->service.description = argv[2];
+ rv = procrun_redirect(argv[2], envp, env, 1);
+ break;
+
+#endif
+ default:
+ /* Run the process
+ * We can be master or called by env.
+ */
+ rv = procrun_redirect(argv[1], envp, env, 1);
+ break;
+ }
+
+ /* Wait for shutdown event or child exit */
+ while (rv == 0) {
+ fired = WaitForMultipleObjects(4, env->m->events,
+ FALSE, INFINITE);
+
+ if (fired == WAIT_OBJECT_0 ||
+ fired == (WAIT_OBJECT_0 + 1) ||
+ fired == WAIT_TIMEOUT)
+ break;
+ }
+ DBPRINTF1("Exiting from mode %d\n", mode);
+ /* clean up... */
+cleanup:
+
+#ifdef PROCRUN_WINAPP
+ if (ac_main_hwnd)
+ ac_show_try_icon(ac_main_hwnd, NIM_DELETE, NULL, 0);
+#endif
+ procrun_destroy_jvm(env->m, NULL);
+ inject_exitprocess(&env->c->pinfo);
+ i = pool_destroy(env->m->pool);
+ i = pool_destroy(env->c->pool);
+ if (g_proc_stderr_file)
+ close(g_proc_stderr_file);
+ return 0;
+}
+
+static procrun_t *alloc_environment()
+{
+
+ procrun_t *env = (procrun_t *)malloc(sizeof(procrun_t));
+ if (env) {
+ env->m = (process_t *)calloc(1, sizeof(process_t));
+ env->c = (process_t *)calloc(1, sizeof(process_t));
+ }
+ return env;
+}
+
+static void free_environment(procrun_t *env)
+{
+ if (env) {
+ free(env->m);
+ free(env->c);
+ free(env);
+ env = NULL;
+ }
+}
+
+#if defined(PROCRUN_WINAPP)
+#pragma message("Compiling WIN32 Application mode")
+
+int WINAPI WinMain(HINSTANCE hInstance,
+ HINSTANCE hPrevInstance,
+ LPSTR lpCmdLine,
+ int nCmdShow)
+{
+ int rv;
+ procrun_t *env = alloc_environment();
+ g_proc_mode = PROCRUN_MODE_WINAPP;
+ g_env = env;
+ ac_instance = hInstance;
+ rv = procrun_main(__argc, __argv, _environ, env);
+
+ free_environment(env);
+ return rv;
+}
+#elif defined(PROCRUN_CONSOLE)
+#pragma message("Compiling CONSOLE Application mode")
+
+void __cdecl main(int argc, char **argv)
+{
+
+ procrun_t *env = alloc_environment();
+ g_proc_mode = PROCRUN_MODE_CONSOLE;
+ g_env = env;
+
+ procrun_main(argc, argv, _environ, env);
+
+ free_environment(env);
+}
+#elif defined(PROCRUN_WINDLL)
+#pragma message("Compiling Control Panel Application mode")
+
+BOOL WINAPI DllMain(HINSTANCE hInst,
+ ULONG ulReason,
+ LPVOID lpReserved)
+{
+
+ switch (ulReason) {
+ case DLL_PROCESS_ATTACH:
+ g_env = NULL;
+ break;
+ case DLL_PROCESS_DETACH:
+ free_environment(g_env);
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+/* DLL mode functions
+ * Ment to be used either from other programs
+ * or from installers
+ */
+
+/* Install the service.
+ * This is a wrapper for //IS//
+ */
+__declspec(dllexport) void InstallService(const char *service_name,
+ const char *install,
+ const char *image_path,
+ const char *display_name,
+ const char *description)
+{
+ int argc = 0;
+ char *argv[12];
+ char b[MAX_PATH];
+
+ procrun_t *env = alloc_environment();
+ g_proc_mode = PROCRUN_MODE_WINDLL;
+ g_env = env;
+
+ argv[argc++] = "PROCRUN.DLL";
+ strcpy(b, PROC_ARG_INSTALL_SERVICE);
+ strcat(b, service_name);
+ argv[argc++] = b;
+ argv[argc++] = "--" PROCRUN_PARAMS_IMAGE;
+ argv[argc++] = (char *)image_path;
+ argv[argc++] = "--" PROCRUN_PARAMS_INSTALL;
+ argv[argc++] = (char *)install;
+ argv[argc++] = "--" PROCRUN_PARAMS_DISPLAY;
+ argv[argc++] = (char *)display_name;
+ argv[argc++] = "--" PROCRUN_PARAMS_DESCRIPTION;
+ argv[argc++] = (char *)description;
+
+ procrun_main(argc, argv, _environ, env);
+
+ free_environment(env);
+ g_env = NULL;
+}
+
+/* Update the service.
+ * This is a wrapper for //US//
+ *
+ */
+
+__declspec(dllexport) void UpdateService(const char *service_name,
+ const char *param,
+ const char *value)
+{
+ int argc = 0;
+ char *argv[4];
+ char b[MAX_PATH], p[MAX_PATH];
+
+ procrun_t *env = alloc_environment();
+ g_proc_mode = PROCRUN_MODE_WINDLL;
+ g_env = env;
+
+ argv[argc++] = "PROCRUN.DLL";
+ strcpy(b, PROC_ARG_UPDATE_SERVICE);
+ strcat(b, service_name);
+ strcpy(p, "--");
+ strcat(p, param);
+ argv[argc++] = b;
+ argv[argc++] = p;
+ argv[argc++] = (char *)value;
+
+ procrun_main(argc, argv, _environ, env);
+
+ free_environment(env);
+ g_env = NULL;
+}
+
+/* Remove the service.
+ * This is a wrapper for //DS//
+ */
+
+__declspec(dllexport) void RemoveService(const char *service_name)
+{
+ int argc = 0;
+ char *argv[4];
+ char b[MAX_PATH];
+
+ procrun_t *env = alloc_environment();
+ g_proc_mode = PROCRUN_MODE_WINDLL;
+ g_env = env;
+
+ argv[argc++] = "PROCRUN.DLL";
+ strcpy(b, PROC_ARG_DELETE_SERVICE);
+ strcat(b, service_name);
+ argv[argc++] = b;
+ procrun_main(argc, argv, _environ, env);
+
+ free_environment(env);
+ g_env = NULL;
+}
+
+#else
+#error Unknown application mode
+#endif
+
diff --git a/src/native/nt/procrun/procrun.dev b/src/native/nt/procrun/procrun.dev
new file mode 100644
index 0000000..111b011
--- /dev/null
+++ b/src/native/nt/procrun/procrun.dev
@@ -0,0 +1,62 @@
+[Project]
+FileName=procrun.dev
+Name=procrun
+UnitCount=2
+Type=1
+Ver=1
+ObjFiles=
+Includes=C:\DEVTOOLS\JAVA\141\include;C:\DEVTOOLS\JAVA\141\include\win32
+Libs=
+PrivateResource=procrun_private.rc
+ResourceIncludes=
+MakeIncludes=
+Resources=procrun.rc
+Compiler=-DPROCRUN_CONSOLE -O2
+Linker=-lshlwapi
+IsCpp=0
+Icon=
+ExeOutput=bin
+ObjectOutput=release
+OverrideOutput=0
+OverrideOutputName=procrun.exe
+HostApplication=
+Folders=
+CommandLine=
+IncludeVersionInfo=0
+SupportXPThemes=0
+CompilerSet=0
+CompilerSettings=000000000000000000
+
+[Unit1]
+FileName=procrun.c
+Folder=procrun
+Compile=1
+CompileCpp=0
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit2]
+FileName=procrun.h
+Folder=procrun
+Compile=1
+CompileCpp=0
+OverrideBuildCmd=0
+BuildCmd=
+
+[VersionInfo]
+Major=0
+Minor=1
+Release=1
+Build=1
+LanguageID=1033
+CharsetID=1252
+CompanyName=
+FileVersion=
+FileDescription=Developed using the Dev-C++ IDE
+InternalName=
+LegalCopyright=
+LegalTrademarks=
+OriginalFilename=
+ProductName=
+ProductVersion=
+
diff --git a/src/native/nt/procrun/procrun.dsp b/src/native/nt/procrun/procrun.dsp
new file mode 100644
index 0000000..7f0f120
--- /dev/null
+++ b/src/native/nt/procrun/procrun.dsp
@@ -0,0 +1,293 @@
+# Microsoft Developer Studio Project File - Name="procrun" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=procrun - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "procrun.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "procrun.mak" CFG="procrun - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "procrun - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE "procrun - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "procrun - Win32 Debug CONSOLE" (based on "Win32 (x86) Application")
+!MESSAGE "procrun - Win32 Release CONSOLE" (based on "Win32 (x86) Application")
+!MESSAGE "procrun - Win32 DebugDLL" (based on "Win32 (x86) Application")
+!MESSAGE "procrun - Win32 ReleaseDLL" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "procrun - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "$(JAVA_HOME)\include" /I "$(JAVA_HOME)\include\win32" /D "_WIN32" /D "WIN32" /D "_DEBUG" /D "_DEBUG_TRACE" /D "_WINDOWS" /D "STRICT" /D _WIN32_WINNT=0x0400 /D "PROCRUN_WINAPP" /D "_MBCS" /GZ PRECOMP_VC7_TOBEREMOVED /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "$(JAVA_HOME)\include" /I "$(JAVA_HOME)\include\win32" /D "_WIN32" /D "WIN32" /D "_DEBUG" /D "_DEBUG_TRACE" /D "_WINDOWS" /D "STRICT" /D _WIN32_WINNT=0x0400 /D "PROCRUN_WINAPP" /D "_MBCS" /GZ /c
+# ADD BASE MTL /nologo /win32
+# ADD MTL /nologo /win32
+# ADD BASE RSC /l 0x409 /d "_MSC_VER"
+# ADD RSC /l 0x409 /d "_MSC_VER"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib /nologo /subsystem:windows /debug /machine:IX86 /out:"Debug\procrunw.exe" /pdbtype:sept
+# SUBTRACT BASE LINK32 /pdb:none
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib /nologo /subsystem:windows /debug /machine:IX86 /out:"bin\procrunwd.exe" /pdbtype:sept
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "procrun - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /Zi /O2 /I "$(JAVA_HOME)\include" /I "$(JAVA_HOME)\include\win32" /D "_WIN32" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "STRICT" /D _WIN32_WINNT=0x0400 /D "PROCRUN_WINAPP" /D "_MBCS" /GF PRECOMP_VC7_TOBEREMOVED /c
+# ADD CPP /nologo /MD /W3 /GX /Zi /O2 /I "$(JAVA_HOME)\include" /I "$(JAVA_HOME)\include\win32" /D "_WIN32" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "STRICT" /D _WIN32_WINNT=0x0400 /D "PROCRUN_WINAPP" /D "_MBCS" /GF /c
+# ADD BASE MTL /nologo /win32
+# ADD MTL /nologo /win32
+# ADD BASE RSC /l 0x409 /d "_MSC_VER"
+# ADD RSC /l 0x409 /d "_MSC_VER"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib /nologo /subsystem:windows /debug /machine:IX86 /out:"bin\procrunw.exe" /pdbtype:sept /opt:ref /opt:icf
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib /nologo /subsystem:windows /debug /machine:IX86 /out:"bin\procrunw.exe" /pdbtype:sept /opt:ref /opt:icf
+
+!ELSEIF "$(CFG)" == "procrun - Win32 Debug CONSOLE"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "DebugCONSOLE"
+# PROP BASE Intermediate_Dir "DebugCONSOLE"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "DebugCONSOLE"
+# PROP Intermediate_Dir "DebugCONSOLE"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "$(JAVA_HOME)\include" /I "$(JAVA_HOME)\include\win32" /D "_WIN32" /D "WIN32" /D "_DEBUG" /D "_DEBUG_TRACE" /D "_CONSOLE" /D "STRICT" /D _WIN32_WINNT=0x0400 /D "PROCRUN_CONSOLE" /D "_MBCS" /GZ PRECOMP_VC7_TOBEREMOVED /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "$(JAVA_HOME)\include" /I "$(JAVA_HOME)\include\win32" /D "_WIN32" /D "WIN32" /D "_DEBUG" /D "_DEBUG_TRACE" /D "_CONSOLE" /D "STRICT" /D _WIN32_WINNT=0x0400 /D "PROCRUN_CONSOLE" /D "_MBCS" /GZ /c
+# ADD BASE MTL /nologo /win32
+# ADD MTL /nologo /win32
+# ADD BASE RSC /l 0x409
+# ADD RSC /l 0x409
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib /nologo /subsystem:console /debug /machine:IX86 /pdbtype:sept
+# SUBTRACT BASE LINK32 /pdb:none
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib /nologo /subsystem:console /debug /machine:IX86 /out:"bin\procrund.exe" /pdbtype:sept
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "procrun - Win32 Release CONSOLE"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "ReleaseCONSOLE"
+# PROP BASE Intermediate_Dir "ReleaseCONSOLE"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "ReleaseCONSOLE"
+# PROP Intermediate_Dir "ReleaseCONSOLE"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /Zi /O2 /I "$(JAVA_HOME)\include" /I "$(JAVA_HOME)\include\win32" /D "_WIN32" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "STRICT" /D _WIN32_WINNT=0x0400 /D "PROCRUN_CONSOLE" /D "_MBCS" /GF PRECOMP_VC7_TOBEREMOVED /c
+# ADD CPP /nologo /MD /W3 /GX /Zi /O2 /I "$(JAVA_HOME)\include" /I "$(JAVA_HOME)\include\win32" /D "_WIN32" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "STRICT" /D _WIN32_WINNT=0x0400 /D "PROCRUN_CONSOLE" /D "_MBCS" /GF /c
+# ADD BASE MTL /nologo /win32
+# ADD MTL /nologo /win32
+# ADD BASE RSC /l 0x409
+# ADD RSC /l 0x409
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib /nologo /subsystem:console /debug /machine:IX86 /out:"bin\procrun.exe" /pdbtype:sept /opt:ref /opt:icf
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib /nologo /subsystem:console /debug /machine:IX86 /out:"bin\procrun.exe" /pdbtype:sept /opt:ref /opt:icf
+
+!ELSEIF "$(CFG)" == "procrun - Win32 DebugDLL"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "DebugDLL"
+# PROP BASE Intermediate_Dir "DebugDLL"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "DebugDLL"
+# PROP Intermediate_Dir "DebugDLL"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "$(JAVA_HOME)\include" /I "$(JAVA_HOME)\include\win32" /D "_WIN32" /D "WIN32" /D "_DEBUG" /D "_DEBUG_TRACE" /D "_WINDOWS" /D "STRICT" /D _WIN32_WINNT=0x0400 /D "PROCRUN_WINDLL" /D "_MBCS" /GZ PRECOMP_VC7_TOBEREMOVED /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "$(JAVA_HOME)\include" /I "$(JAVA_HOME)\include\win32" /D "_WIN32" /D "WIN32" /D "_DEBUG" /D "_DEBUG_TRACE" /D "_WINDOWS" /D "STRICT" /D _WIN32_WINNT=0x0400 /D "PROCRUN_WINDLL" /D "_MBCS" /GZ /c
+# ADD BASE MTL /nologo /win32
+# ADD MTL /nologo /win32
+# ADD BASE RSC /l 0x409
+# ADD RSC /l 0x409
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib /nologo /subsystem:windows /dll /debug /machine:IX86 /pdbtype:sept
+# SUBTRACT BASE LINK32 /pdb:none
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib /nologo /subsystem:windows /dll /debug /machine:IX86 /out:"bin\procrund.dll" /pdbtype:sept
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "procrun - Win32 ReleaseDLL"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "ReleaseDLL"
+# PROP BASE Intermediate_Dir "ReleaseDLL"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "ReleaseDLL"
+# PROP Intermediate_Dir "ReleaseDLL"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /Zi /O2 /I "$(JAVA_HOME)\include" /I "$(JAVA_HOME)\include\win32" /D "_WIN32" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "STRICT" /D _WIN32_WINNT=0x0400 /D "PROCRUN_WINDLL" /D "_MBCS" /GF PRECOMP_VC7_TOBEREMOVED /c
+# ADD CPP /nologo /MD /W3 /GX /Zi /O2 /I "$(JAVA_HOME)\include" /I "$(JAVA_HOME)\include\win32" /D "_WIN32" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "STRICT" /D _WIN32_WINNT=0x0400 /D "PROCRUN_WINDLL" /D "_MBCS" /GF /c
+# ADD BASE MTL /nologo /win32
+# ADD MTL /nologo /win32
+# ADD BASE RSC /l 0x409
+# ADD RSC /l 0x409
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib /nologo /subsystem:windows /dll /debug /machine:IX86 /out:"bin\procrun.dll" /pdbtype:sept /opt:ref /opt:icf
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib /nologo /subsystem:windows /dll /debug /machine:IX86 /out:"bin\procrun.dll" /pdbtype:sept /opt:ref /opt:icf
+
+!ENDIF
+
+# Begin Target
+
+# Name "procrun - Win32 Debug"
+# Name "procrun - Win32 Release"
+# Name "procrun - Win32 Debug CONSOLE"
+# Name "procrun - Win32 Release CONSOLE"
+# Name "procrun - Win32 DebugDLL"
+# Name "procrun - Win32 ReleaseDLL"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;def;odl;idl;hpj;bat;asm"
+# Begin Source File
+
+SOURCE=procgui.c
+DEP_CPP_PROCG=\
+ ".\procrun.h"\
+ "C:\DEVTOOLS\JAVA\142\include\jni.h"\
+ "C:\DEVTOOLS\JAVA\142\include\win32\jni_md.h"\
+
+# End Source File
+# Begin Source File
+
+SOURCE=procrun.c
+DEP_CPP_PROCR=\
+ ".\procrun.h"\
+ "C:\DEVTOOLS\JAVA\142\include\jni.h"\
+ "C:\DEVTOOLS\JAVA\142\include\win32\jni_md.h"\
+
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl;inc"
+# Begin Source File
+
+SOURCE=procrun.h
+# End Source File
+# Begin Source File
+
+SOURCE=resource.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# Begin Source File
+
+SOURCE="jakarta-banner.bmp"
+# End Source File
+# Begin Source File
+
+SOURCE=procrun.rc
+
+!IF "$(CFG)" == "procrun - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "procrun - Win32 Release"
+
+# ADD BASE RSC /l 0x41a
+# ADD RSC /l 0x41a /d "PROCRUN_WINAPP"
+
+!ELSEIF "$(CFG)" == "procrun - Win32 Debug CONSOLE"
+
+!ELSEIF "$(CFG)" == "procrun - Win32 Release CONSOLE"
+
+!ELSEIF "$(CFG)" == "procrun - Win32 DebugDLL"
+
+!ELSEIF "$(CFG)" == "procrun - Win32 ReleaseDLL"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=proctry.ico
+# End Source File
+# Begin Source File
+
+SOURCE=tomcatp.ico
+# End Source File
+# Begin Source File
+
+SOURCE=tomcatr.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\tomcats.ico
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=License.rtf
+# End Source File
+# End Target
+# End Project
diff --git a/src/native/nt/procrun/procrun.dsw b/src/native/nt/procrun/procrun.dsw
new file mode 100644
index 0000000..ad0ad14
--- /dev/null
+++ b/src/native/nt/procrun/procrun.dsw
@@ -0,0 +1,41 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "procrun"=.\procrun.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "testchild"=.\testchild\testchild.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/src/native/nt/procrun/procrun.h b/src/native/nt/procrun/procrun.h
new file mode 100644
index 0000000..30394a8
--- /dev/null
+++ b/src/native/nt/procrun/procrun.h
@@ -0,0 +1,359 @@
+/* ====================================================================
+ Copyright 2002-2004 The Apache Software Foundation.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/* ====================================================================
+ * procrun
+ *
+ * Contributed by Mladen Turk <mturk at apache.org>
+ *
+ * 05 Aug 2002
+ * ====================================================================
+ */
+
+#ifndef PROC_H_INCLUDED
+#define PROC_H_INCLUDED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(PROCRUN_EXTENDED)
+#include "extend.h"
+#endif
+
+#define IDD_DLGCONSOLE 101
+#define IDS_CONWRAPTITLE 102
+#define IDS_CONWRAPCLASS 103
+#define IDM_CONSOLE 104
+#define IDM_EXIT 105
+#define IDI_ICOCONWRAP 106
+#define IDC_STATBAR 107
+#define IDC_SSTATUS 108
+#define IDB_BMPHEADER 109
+#define IDL_STDOUT 110
+#define IDR_CMENU 111
+#define IDM_MENU_EXIT 112
+#define IDM_MENU_EDIT 113
+#define IDM_MENU_ABOUT 114
+#define IDI_ICOCONTRY 115
+#define IDR_RTFLIC 116
+#define IDB_BMPJAKARTA 117
+#define IDD_ABOUTBOX 118
+#define IDC_RICHEDIT21 119
+#define IDM_ABOUT 120
+#define IDI_ICOCONTRYSTOP 121
+#define IDB_BMPSPLASH 122
+#define IDD_DLGSPLASH 123
+#define IDL_INFO 124
+#define IDI_ICOI 125
+#define IDI_ICOS 126
+#define IDI_ICOW 127
+#define IDM_OPTIONS 128
+#define RC_DLG_SRVOPT 130
+#define RC_LBL_VER 131
+#define RC_LISTVIEW 132
+
+#define RC_TAB_SRVOPT 1000
+#define RC_GRP_MSP 1001
+#define RC_BTN_APPLY 1002
+#define RC_LBL_SN 1003
+#define RC_TXT_SN 1004
+#define RC_LBL_SD 1005
+#define RC_TXT_SD 1006
+#define RC_LBL_IP 1007
+#define RC_TXT_IP 1008
+#define RC_BTN_BIP 1009
+#define RC_LBL_WP 1010
+#define RC_TXT_WP 1011
+#define RC_BTN_BWP 1012
+#define RC_CHK_AUTO 1013
+#define RC_LBL_UN 1014
+#define RC_TXT_UN 1015
+#define RC_LBL_UP 1016
+#define RC_TXT_UP 1017
+#define RC_DLG_JVMOPT 1999
+#define RC_GRP_JVMOPT 2000
+#define RC_LBL_JVM 2001
+#define RC_TXT_JVM 2002
+#define RC_BTN_JVM 2003
+#define RC_CHK_JVM 2004
+#define RC_LBL_JO 2005
+#define RC_TXT_JO 2006
+#define RC_LBL_SC 2007
+#define RC_TXT_SC 2008
+#define RC_LBL_EC 2009
+#define RC_TXT_EC 2010
+#define RC_DLG_STDOPT 2999
+#define RC_GRP_STDOPT 3000
+#define RC_LBL_STDI 3001
+#define RC_TXT_STDI 3002
+#define RC_BTN_STDI 3003
+#define RC_CHK_STDI 3004
+#define RC_LBL_STDO 3005
+#define RC_TXT_STDO 3006
+#define RC_BTN_STDO 3007
+#define RC_LBL_STDE 3008
+#define RC_TXT_STDE 3009
+#define RC_BTN_STDE 3010
+#define RC_ABOUT_TXT 3012
+
+#define IDC_STATIC -1
+
+#define PROC_ENV_COUNT 32
+#define PROC_ARG_COUNT 128
+#define PROC_BUFSIZE 4096
+#define PROC_POOL_SIZE 128
+#define PROC_VERSION "1.1.0\0"
+#define SERVICE_DEPENDENCIES "Tcpip\0Afd\0\0"
+
+#define PROC_ARG_ENVPREFIX "//EP//"
+#define PROC_ARG_RUN_JAVA "//RJ//"
+#define PROC_ARG_INSTALL_SERVICE "//IS//"
+#define PROC_ARG_RUN_SERVICE "//RS//"
+#define PROC_ARG_STOP_SERVICE "//SS//"
+#define PROC_ARG_DELETE_SERVICE "//DS//"
+#define PROC_ARG_TEST_SERVICE "//TS//"
+#define PROC_ARG_GUIT_SERVICE "//GT//"
+#define PROC_ARG_GUID_SERVICE "//GD//"
+#define PROC_ARG_GUID_PROCESS "//GP//"
+#define PROC_ARG_UPDATE_SERVICE "//US//"
+#define PROC_ARG_EDIT_SERVICE "//ES//"
+
+#define PROCRUN_VERSION_STR "1.1"
+
+#ifndef PROCRUN_REGKEY_ROOT
+#define PROCRUN_REGKEY_ROOT "SOFTWARE\\Apache Software Foundation\\Process Runner " PROCRUN_VERSION_STR
+#endif
+
+#ifndef PROCRUN_GUI_DISPLAY
+#define PROCRUN_GUI_DISPLAY "Apache Process Runner"
+#endif
+
+#define PROCRUN_REGKEY_SERVICES "System\\CurrentControlSet\\Services\\%s"
+#define PROCRUN_REGKEY_PARAMS "System\\CurrentControlSet\\Services\\%s\\Parameters"
+#define PROCRUN_REGKEY_RSERVICES PROCRUN_REGKEY_ROOT "\\%s"
+#define PROCRUN_REGKEY_RPARAMS PROCRUN_REGKEY_ROOT "\\%s\\Parameters"
+
+#define JAVASOFT_REGKEY "SOFTWARE\\JavaSoft\\Java Runtime Environment\\"
+#define JAVAHOME_REGKEY "SOFTWARE\\JavaSoft\\Java Development Kit\\"
+
+#define PROCRUN_PARAMS_DISPLAY "DisplayName"
+#define PROCRUN_PARAMS_IMAGE "ImagePath"
+#define PROCRUN_PARAMS_DESCRIPTION "Description"
+#define PROCRUN_PARAMS_CMDARGS "Arguments"
+#define PROCRUN_PARAMS_WORKPATH "WorkingPath"
+#define PROCRUN_PARAMS_JVM "Java"
+#define PROCRUN_PARAMS_JVM_OPTS "JavaOptions"
+#define PROCRUN_PARAMS_STDINFILE "StdInputFile"
+#define PROCRUN_PARAMS_STDOUTFILE "StdOutputFile"
+#define PROCRUN_PARAMS_STDERRFILE "StdErrorFile"
+#define PROCRUN_PARAMS_STARTCLASS "StartupClass"
+#define PROCRUN_PARAMS_STOPCLASS "ShutdownClass"
+#define PROCRUN_PARAMS_STARTUP "Startup"
+#define PROCRUN_PARAMS_ACCOUNT "User"
+#define PROCRUN_PARAMS_PASSWORD "Password"
+#define PROCRUN_PARAMS_INSTALL "Install"
+#define PROCRUN_PARAMS_ENVIRONMENT "Environment"
+/* Console Window position and color */
+#define PROCRUN_PARAMS_WINPOS "WindowPosition"
+#define PROCRUN_PARAMS_WINCLR "WindowColor"
+#define PROCRUN_PARAMS_WINBACK "WindowBackground"
+#define PROCRUN_PARAMS_USELVIEW "WindowListView"
+
+
+#define PROCRUN_DEFAULT_CLASS "Main"
+
+#define PROCRUN_ENV_PPID "PROCRUN_PPID="
+#define PROCRUN_ENV_STDIN "PROCRUN_STDIN="
+#define PROCRUN_ENV_STDOUT "PROCRUN_STDOUT="
+#define PROCRUN_ENV_STDERR "PROCRUN_STDERR="
+#define PROCRUN_ENV_ERRFILE "PROCRUN_ERRFILE="
+#define PROCRUN_ENV_SHMNAME "PROCRUN_SHMNAME="
+
+#define STRN_SIZE(x) (sizeof(x) - 1)
+#define STRN_COMPARE(x, s) (strncmp((x), (s), sizeof((s)) -1) == 0)
+#define STRNI_COMPARE(x, s) (strnicmp((x), (s), sizeof((s)) -1) == 0)
+#define STR_NOT_NULL(s) { if((s) == NULL) (s) = ""; }
+
+ enum {
+ PROCRUN_MODE_WINAPP = 1,
+ PROCRUN_MODE_GUI,
+ PROCRUN_MODE_CONSOLE,
+ PROCRUN_MODE_WINDLL
+ };
+
+ enum {
+ PROCRUN_CMD_ENVPREFIX = 1,
+ PROCRUN_CMD_RUN_JAVA,
+ PROCRUN_CMD_INSTALL_SERVICE,
+ PROCRUN_CMD_RUN_SERVICE,
+ PROCRUN_CMD_TEST_SERVICE,
+ PROCRUN_CMD_GUIT_SERVICE,
+ PROCRUN_CMD_GUID_SERVICE,
+ PROCRUN_CMD_STOP_SERVICE,
+ PROCRUN_CMD_DELETE_SERVICE,
+ PROCRUN_CMD_UPDATE_SERVICE,
+ PROCRUN_CMD_EDIT_SERVICE,
+ PROCRUN_CMD_GUID_PROCESS
+ };
+
+ typedef struct mpool_t mpool_t;
+ struct mpool_t {
+ void *m;
+ HANDLE h;
+ };
+
+ typedef struct pool_t pool_t;
+ struct pool_t {
+ mpool_t mp[PROC_POOL_SIZE];
+ CRITICAL_SECTION lock;
+ int size;
+ };
+
+ typedef struct buffer_t buffer_t;
+ struct buffer_t {
+ char *buf;
+ int siz;
+ int len;
+ int pos;
+ };
+
+ typedef struct service_t service_t;
+ struct service_t {
+ char *name;
+ char *description;
+ char *display;
+ char *path;
+ char *image;
+ char *account;
+ char *password;
+ char *environment;
+ HANDLE infile;
+ HANDLE outfile;
+ HANDLE errfile;
+ char *inname;
+ char *outname;
+ char *errname;
+ SERVICE_STATUS status;
+ SERVICE_STATUS_HANDLE h_status;
+ int mode;
+ int startup;
+ };
+
+ typedef struct java_t java_t;
+ struct java_t {
+ char *path;
+ char *jpath;
+ char *jbin;
+ char *start_class;
+ char *stop_class;
+ HMODULE dll;
+ JavaVM *jvm;
+ JNIEnv *env;
+ jclass start_bridge;
+ jclass stop_bridge;
+ jmethodID start_mid;
+ jmethodID stop_mid;
+ char *start_method;
+ char *stop_method;
+ char *start_param;
+ char *stop_param;
+ char *opts;
+ char *display;
+ };
+
+ typedef struct process_t process_t;
+ struct process_t {
+ HANDLE events[4];
+ HANDLE h_stdin[4];
+ HANDLE h_stdout[4];
+ HANDLE h_stderr[4];
+ char *files[3];
+ buffer_t buff_in;
+ buffer_t buff_out;
+ buffer_t buff_err;
+ PROCESS_INFORMATION pinfo;
+ int ppid;
+ char *env[PROC_ENV_COUNT];
+ char **envp;
+ char *argw;
+ char *envw;
+ char *env_prefix;
+ service_t service;
+ java_t java;
+ pool_t *pool;
+ };
+
+ typedef struct procrun_t procrun_t;
+ struct procrun_t {
+ process_t *m;
+ process_t *c;
+ };
+
+ int procrun_main(int argc, char **argv, char **envp, procrun_t *env);
+ int procrun_update_service(process_t *proc, int argc, char **argv);
+ void save_service_params(process_t *proc, char *java);
+ pool_t *pool_create();
+ int pool_destroy(pool_t *pool);
+
+ typedef struct prcrun_lview_t {
+ char * label;
+ DWORD width;
+ } prcrun_lview_t;
+
+#if !defined(PROCRUN_CONSOLE)
+
+extern DWORD WINAPI gui_thread(LPVOID param);
+
+extern void ac_add_list_string(const char *str, int len, int from);
+extern int ac_use_try;
+extern int ac_use_dlg;
+extern int ac_use_show;
+extern int ac_use_props;
+extern int ac_use_lview;
+extern int ac_lview_current;
+extern int ac_splash_timeout;
+
+extern RECT ac_winpos;
+extern HINSTANCE ac_instance;
+extern HWND ac_main_hwnd;
+extern HWND ac_list_hwnd;
+extern char *ac_cmdname;
+extern char *ac_splash_msg;
+extern prcrun_lview_t *ac_columns;
+
+void ac_show_try_icon(HWND hwnd, DWORD message, const char *tip, int stop);
+void ac_center_window(HWND hwnd);
+
+typedef void (*lv_parse_cb_t)(const char *data, int from);
+
+extern lv_parse_cb_t lv_parser;
+
+#if defined(PROCRUN_EXTENDED)
+
+void acx_init_extended();
+
+
+#endif
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PROC_H_INCLUDED */
+
diff --git a/src/native/nt/procrun/procrun.rc b/src/native/nt/procrun/procrun.rc
new file mode 100644
index 0000000..ccd6bf1
--- /dev/null
+++ b/src/native/nt/procrun/procrun.rc
@@ -0,0 +1,232 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2000-2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" must
+ * not be used to endorse or promote products derived from this
+ * software without prior written permission. For written
+ * permission, please contact apache at apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * Portions of this software are based upon public domain software
+ * originally written at the National Center for Supercomputing Applications,
+ * University of Illinois, Urbana-Champaign.
+ */
+
+#include "procrun.h"
+#include "windows.h"
+
+#ifndef PROCRUN_CONSOLE
+#if !defined(EXT_ICOCONWRAP)
+IDI_ICOCONWRAP ICON "proctry.ico"
+#endif
+#if !defined(EXT_ICOCONTRY)
+IDI_ICOCONTRY ICON "proctry.ico"
+#endif
+#if !defined(EXT_ICOCONTRY)
+IDI_ICOCONTRYSTOP ICON "proctry.ico"
+#endif
+
+IDR_RTFLIC RTF "License.rtf"
+
+#if !defined(EXT_BMPSPLASH)
+BMPSPLASH BITMAP "splash.bmp"
+#endif
+
+IDI_ICOI ICON "icoi.ico"
+IDI_ICOS ICON "icos.ico"
+IDI_ICOW ICON "icow.ico"
+
+BMPJAKARTA BITMAP "jakarta-banner.bmp"
+IDR_CMENU MENUEX DISCARDABLE
+BEGIN
+ POPUP "&Process",65535,MFT_STRING,MFS_ENABLED
+ BEGIN
+ MENUITEM "E&xit", IDM_MENU_EXIT
+ END
+ POPUP "&Edit",65535,MFT_STRING,MFS_ENABLED
+ BEGIN
+ MENUITEM "&Copy", IDM_MENU_EDIT
+ END
+ POPUP "&Help",65535,MFT_STRING | MFT_RIGHTJUSTIFY,MFS_ENABLED
+ BEGIN
+ MENUITEM "&About", IDM_MENU_ABOUT
+ END
+END
+
+IDD_DLGCONSOLE DIALOGEX 0, 0, 480, 240
+STYLE DS_3DLOOK | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION |
+ WS_SYSMENU | WS_THICKFRAME
+EXSTYLE WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT
+CAPTION "Apache Service Monitor"
+MENU IDR_CMENU
+FONT 10, "Courier New"
+BEGIN
+ LISTBOX IDL_STDOUT,0,0,200,200,NOT LBS_NOTIFY | LBS_USETABSTOPS |
+ LBS_NOINTEGRALHEIGHT | LBS_EXTENDEDSEL | NOT WS_BORDER |
+ WS_VSCROLL | WS_HSCROLL | WS_TABSTOP,WS_EX_CLIENTEDGE
+END
+
+IDD_ABOUTBOX DIALOGEX 0, 0, 337, 167
+STYLE DS_SETFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU
+CAPTION "About Apache Process Runner"
+FONT 8, "Microsoft Sans Serif", 400, 0, 0x0
+BEGIN
+ DEFPUSHBUTTON "&OK",IDOK,285,150,50,14
+ CONTROL "",IDC_RICHEDIT21,"RichEdit20A",ES_MULTILINE |
+ ES_READONLY | WS_BORDER | WS_VSCROLL,0,31,335,115
+ CONTROL "BMPJAKARTA",IDC_STATIC,"Static",SS_BITMAP,0,0,337,30
+ LTEXT "Apache Process Runner ver. 1.1.0",IDC_STATIC,2,150,270,12
+END
+
+RC_DLG_SRVOPT DIALOGEX 0, 0, 337, 186
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_VISIBLE | WS_BORDER
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ GROUPBOX " Main Service Parameters ",RC_GRP_MSP,4,16,324,158
+ CONTROL "Auto Start",RC_CHK_AUTO,"Button",BS_AUTOCHECKBOX |
+ BS_LEFTTEXT | WS_TABSTOP,20,153,62,12
+ LTEXT "Name :",RC_LBL_SN,22,48,50,12
+ EDITTEXT RC_TXT_SN,76,48,179,12,ES_AUTOHSCROLL | ES_READONLY |
+ NOT WS_TABSTOP
+ LTEXT "Description :",RC_LBL_SD,22,66,50,12
+ EDITTEXT RC_TXT_SD,76,66,219,12,ES_AUTOHSCROLL
+ LTEXT "Image path :",RC_LBL_IP,21,79,50,12
+ EDITTEXT RC_TXT_IP,75,79,219,12,ES_AUTOHSCROLL
+ PUSHBUTTON "...",RC_BTN_BIP,297,79,18,12
+ LTEXT "Work path :",RC_LBL_WP,21,94,50,12
+ EDITTEXT RC_TXT_WP,75,92,219,12,ES_AUTOHSCROLL
+ PUSHBUTTON "...",RC_BTN_BWP,297,92,18,12
+ LTEXT "Username :",RC_LBL_UN,21,105,50,12
+ EDITTEXT RC_TXT_UN,75,105,108,12,ES_AUTOHSCROLL
+ LTEXT "Password :",RC_LBL_UP,21,118,50,12
+ EDITTEXT RC_TXT_UP,75,118,108,12,ES_PASSWORD | ES_AUTOHSCROLL
+END
+
+RC_DLG_JVMOPT DIALOGEX 0, 0, 337, 186
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_VISIBLE | WS_BORDER
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ GROUPBOX " Java Virtual Machine ",RC_GRP_JVMOPT,4,16,324,158
+ CONTROL "Auto",RC_CHK_JVM,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT |
+ WS_TABSTOP,22,48,62,12
+ LTEXT "Java VM :",RC_LBL_JVM,22,66,50,12
+ EDITTEXT RC_TXT_JVM,76,66,219,12,ES_AUTOHSCROLL
+ PUSHBUTTON "...",RC_BTN_JVM,298,66,18,12
+ LTEXT "Java Options :",RC_LBL_JO,22,82,50,12
+ EDITTEXT RC_TXT_JO,76,82,219,30,ES_MULTILINE | ES_AUTOHSCROLL |
+ ES_WANTRETURN | WS_VSCROLL
+ LTEXT "Start class :",RC_LBL_SC,22,120,50,12
+ EDITTEXT RC_TXT_SC,76,120,219,12,ES_AUTOHSCROLL
+ LTEXT "Stop class :",RC_LBL_EC,22,138,50,12
+ EDITTEXT RC_TXT_EC,76,138,219,12,ES_AUTOHSCROLL
+END
+
+RC_DLG_STDOPT DIALOGEX 0, 0, 337, 186
+STYLE DS_SETFONT | WS_CHILD | WS_VISIBLE | WS_BORDER
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ GROUPBOX " Standard I/O Streams ",RC_GRP_STDOPT,4,16,324,158
+ CONTROL "Read on startup",RC_CHK_STDI,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,76,66,55,12
+ LTEXT "Input :",RC_LBL_STDI,22,48,50,12
+ EDITTEXT RC_TXT_STDI,76,48,219,12,ES_AUTOHSCROLL
+ PUSHBUTTON "...",RC_BTN_STDI,298,48,18,12
+ LTEXT "Output :",RC_LBL_STDO,22,84,50,12
+ EDITTEXT RC_TXT_STDO,76,84,219,12,ES_AUTOHSCROLL
+ PUSHBUTTON "...",RC_BTN_STDO,298,84,18,12
+ LTEXT "Error :",RC_LBL_STDE,22,102,50,12
+ EDITTEXT RC_TXT_STDE,76,102,219,12,ES_AUTOHSCROLL
+ PUSHBUTTON "...",RC_BTN_STDE,298,102,18,12
+END
+
+IDD_DLGSPLASH DIALOGEX 0, 0, 322, 151
+STYLE DS_SYSMODAL | DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE |
+ WS_BORDER
+EXSTYLE WS_EX_TOPMOST
+FONT 8, "Microsoft Sans Serif", 400, 0, 0x0
+BEGIN
+ LISTBOX IDL_INFO,7,126,217,9, LBS_NOINTEGRALHEIGHT |
+ LBS_NOSEL | NOT WS_BORDER | NOT LBS_USETABSTOPS
+ CONTROL "BMPSPLASH",IDC_STATIC,"Static",SS_BITMAP |
+ SS_CENTERIMAGE,0,0,322,151
+END
+
+#endif
+
+1 VERSIONINFO
+ FILEVERSION 2,1,1,0
+ PRODUCTVERSION 2,1,1,0
+ FILEFLAGSMASK 0x3fL
+#if defined(_DEBUG)
+ FILEFLAGS 0x03L
+#else
+ FILEFLAGS 0x02L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "All rights reserved. The license is available at <http://www.apache.org/LICENSE.txt>. The Apache HTTP Server project pages are at <http://httpd.apache.org/>.\0"
+ VALUE "CompanyName", "Apache Software Foundation\0"
+ VALUE "FileDescription", "Apache Process Runner\0"
+ VALUE "FileVersion", PROC_VERSION
+ VALUE "InternalName", "procrunw.exe\0"
+ VALUE "LegalCopyright", "Copyright � 2000-2003 The Apache Software Foundation.\0"
+ VALUE "OriginalFilename", "procrunw.exe\0"
+ VALUE "ProductName", "Apache Process Runner\0"
+ VALUE "ProductVersion", PROC_VERSION
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/src/native/nt/procrun/procrun.sln b/src/native/nt/procrun/procrun.sln
new file mode 100644
index 0000000..482830d
--- /dev/null
+++ b/src/native/nt/procrun/procrun.sln
@@ -0,0 +1,39 @@
+Microsoft Visual Studio Solution File, Format Version 8.00
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "procrun", "procrun.vcproj", "{A90DF83B-1E82-4610-AFA2-3AC7010BF5D9}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testchild", "testchild\testchild.vcproj", "{C815B005-1292-47F7-9052-F46676CE2879}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfiguration) = preSolution
+ Debug = Debug
+ Debug CONSOLE = Debug CONSOLE
+ Release = Release
+ Release CONSOLE = Release CONSOLE
+ EndGlobalSection
+ GlobalSection(ProjectConfiguration) = postSolution
+ {A90DF83B-1E82-4610-AFA2-3AC7010BF5D9}.Debug.ActiveCfg = Debug|Win32
+ {A90DF83B-1E82-4610-AFA2-3AC7010BF5D9}.Debug.Build.0 = Debug|Win32
+ {A90DF83B-1E82-4610-AFA2-3AC7010BF5D9}.Debug CONSOLE.ActiveCfg = Debug CONSOLE|Win32
+ {A90DF83B-1E82-4610-AFA2-3AC7010BF5D9}.Debug CONSOLE.Build.0 = Debug CONSOLE|Win32
+ {A90DF83B-1E82-4610-AFA2-3AC7010BF5D9}.Release.ActiveCfg = Release|Win32
+ {A90DF83B-1E82-4610-AFA2-3AC7010BF5D9}.Release.Build.0 = Release|Win32
+ {A90DF83B-1E82-4610-AFA2-3AC7010BF5D9}.Release CONSOLE.ActiveCfg = ReleaseDLL|Win32
+ {A90DF83B-1E82-4610-AFA2-3AC7010BF5D9}.Release CONSOLE.Build.0 = ReleaseDLL|Win32
+ {C815B005-1292-47F7-9052-F46676CE2879}.Debug.ActiveCfg = Debug|Win32
+ {C815B005-1292-47F7-9052-F46676CE2879}.Debug.Build.0 = Debug|Win32
+ {C815B005-1292-47F7-9052-F46676CE2879}.Debug CONSOLE.ActiveCfg = Debug|Win32
+ {C815B005-1292-47F7-9052-F46676CE2879}.Debug CONSOLE.Build.0 = Debug|Win32
+ {C815B005-1292-47F7-9052-F46676CE2879}.Release.ActiveCfg = Release|Win32
+ {C815B005-1292-47F7-9052-F46676CE2879}.Release.Build.0 = Release|Win32
+ {C815B005-1292-47F7-9052-F46676CE2879}.Release CONSOLE.ActiveCfg = Release|Win32
+ {C815B005-1292-47F7-9052-F46676CE2879}.Release CONSOLE.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ EndGlobalSection
+ GlobalSection(ExtensibilityAddIns) = postSolution
+ EndGlobalSection
+EndGlobal
diff --git a/src/native/nt/procrun/procrun.vcproj b/src/native/nt/procrun/procrun.vcproj
new file mode 100644
index 0000000..02b3676
--- /dev/null
+++ b/src/native/nt/procrun/procrun.vcproj
@@ -0,0 +1,374 @@
+<?xml version="1.0" encoding="windows-1250"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="procrun"
+ ProjectGUID="{A90DF83B-1E82-4610-AFA2-3AC7010BF5D9}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ OptimizeForProcessor="0"
+ AdditionalIncludeDirectories="$(JAVA_HOME)\include,$(JAVA_HOME)\include\win32"
+ PreprocessorDefinitions="_WIN32,WIN32,_DEBUG,_DEBUG_TRACE,_WINDOWS,STRICT,_WIN32_WINNT=0x0400,PROCRUN_WINAPP"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="FALSE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="comctl32.lib shlwapi.lib"
+ OutputFile="Debug/tomcatw.exe"
+ LinkIncremental="2"
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile="$(OutDir)/procrun.pdb"
+ SubSystem="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_MSC_VER"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="1"
+ OmitFramePointers="TRUE"
+ AdditionalIncludeDirectories="$(JAVA_HOME)\include,$(JAVA_HOME)\include\win32"
+ PreprocessorDefinitions="_WIN32,WIN32,NDEBUG,_WINDOWS,STRICT,_WIN32_WINNT=0x0400,PROCRUN_WINAPP"
+ StringPooling="TRUE"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="TRUE"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="FALSE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="comctl32.lib shlwapi.lib"
+ OutputFile="bin/tomcatw.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="TRUE"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_MSC_VER"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Debug CONSOLE|Win32"
+ OutputDirectory="DebugCONSOLE"
+ IntermediateDirectory="DebugCONSOLE"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(JAVA_HOME)\include,$(JAVA_HOME)\include\win32"
+ PreprocessorDefinitions="_WIN32,WIN32,_DEBUG,_DEBUG_TRACE,_CONSOLE,STRICT,_WIN32_WINNT=0x0400,PROCRUN_CONSOLE"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="FALSE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="comctl32.lib shlwapi.lib"
+ OutputFile="Debug/tomcat.exe"
+ LinkIncremental="2"
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile="$(OutDir)/procrun.pdb"
+ SubSystem="1"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release CONSOLE|Win32"
+ OutputDirectory="ReleaseCONSOLE"
+ IntermediateDirectory="ReleaseCONSOLE"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="1"
+ OmitFramePointers="TRUE"
+ AdditionalIncludeDirectories="$(JAVA_HOME)\include,$(JAVA_HOME)\include\win32"
+ PreprocessorDefinitions="_WIN32,WIN32,NDEBUG,_CONSOLE,STRICT,_WIN32_WINNT=0x0400,PROCRUN_CONSOLE"
+ StringPooling="TRUE"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="TRUE"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="FALSE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="comctl32.lib shlwapi.lib"
+ OutputFile="bin/tomcat.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="TRUE"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="DebugDLL|Win32"
+ OutputDirectory="DebugDLL"
+ IntermediateDirectory="DebugDLL"
+ ConfigurationType="2"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(JAVA_HOME)\include,$(JAVA_HOME)\include\win32"
+ PreprocessorDefinitions="_WIN32,WIN32,_DEBUG,_DEBUG_TRACE,_WINDOWS,STRICT,_WIN32_WINNT=0x0400,PROCRUN_WINDLL"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="FALSE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="comctl32.lib shlwapi.lib"
+ OutputFile="Debug/tomcat.cpl"
+ LinkIncremental="2"
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile="$(OutDir)/procrun.pdb"
+ SubSystem="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="ReleaseDLL|Win32"
+ OutputDirectory="ReleaseDLL"
+ IntermediateDirectory="ReleaseDLL"
+ ConfigurationType="2"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="1"
+ OmitFramePointers="TRUE"
+ AdditionalIncludeDirectories="$(JAVA_HOME)\include,$(JAVA_HOME)\include\win32"
+ PreprocessorDefinitions="_WIN32,WIN32,NDEBUG,_WINDOWS,STRICT,_WIN32_WINNT=0x0400,PROCRUN_WINDLL"
+ StringPooling="TRUE"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="TRUE"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="FALSE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="comctl32.lib shlwapi.lib"
+ OutputFile="bin/tomcat.cpl"
+ LinkIncremental="1"
+ GenerateDebugInformation="TRUE"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm">
+ <File
+ RelativePath="procgui.c">
+ </File>
+ <File
+ RelativePath="procrun.c">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc">
+ <File
+ RelativePath="procrun.h">
+ </File>
+ <File
+ RelativePath="resource.h">
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
+ <File
+ RelativePath="jakarta-banner.bmp">
+ </File>
+ <File
+ RelativePath="procrun.rc">
+ </File>
+ <File
+ RelativePath="proctry.ico">
+ </File>
+ <File
+ RelativePath="tomcatp.ico">
+ </File>
+ <File
+ RelativePath="tomcatr.ico">
+ </File>
+ </Filter>
+ <File
+ RelativePath="License.rtf">
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/src/native/nt/procrun/procrund.dev b/src/native/nt/procrun/procrund.dev
new file mode 100644
index 0000000..a0792ca
--- /dev/null
+++ b/src/native/nt/procrun/procrund.dev
@@ -0,0 +1,62 @@
+[Project]
+FileName=procrund.dev
+Name=procrun
+UnitCount=2
+Type=3
+Ver=1
+ObjFiles=
+Includes=C:\DEVTOOLS\JAVA\141\include;C:\DEVTOOLS\JAVA\141\include\win32
+Libs=
+PrivateResource=procrun_private.rc
+ResourceIncludes=
+MakeIncludes=
+Resources=procrun.rc
+Compiler=-DPROCRUN_WINDLL -O2
+Linker=-lshlwapi
+IsCpp=0
+Icon=
+ExeOutput=bin
+ObjectOutput=ReleaseDLL
+OverrideOutput=1
+OverrideOutputName=procrun.dll
+HostApplication=
+Folders=
+CommandLine=
+IncludeVersionInfo=0
+SupportXPThemes=0
+CompilerSet=0
+CompilerSettings=000000000000000000
+
+[Unit1]
+FileName=procrun.c
+Folder=procrun
+Compile=1
+CompileCpp=0
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit2]
+FileName=procrun.h
+Folder=procrun
+Compile=1
+CompileCpp=0
+OverrideBuildCmd=0
+BuildCmd=
+
+[VersionInfo]
+Major=0
+Minor=1
+Release=1
+Build=1
+LanguageID=1033
+CharsetID=1252
+CompanyName=
+FileVersion=
+FileDescription=Developed using the Dev-C++ IDE
+InternalName=
+LegalCopyright=
+LegalTrademarks=
+OriginalFilename=
+ProductName=
+ProductVersion=
+
diff --git a/src/native/nt/procrun/procrunw.dev b/src/native/nt/procrun/procrunw.dev
new file mode 100644
index 0000000..82f3243
--- /dev/null
+++ b/src/native/nt/procrun/procrunw.dev
@@ -0,0 +1,70 @@
+[Project]
+FileName=procrunw.dev
+Name=procrun
+UnitCount=3
+Type=0
+Ver=1
+ObjFiles=
+Includes=C:\DEVTOOLS\JAVA\141\include;C:\DEVTOOLS\JAVA\141\include\win32
+Libs=
+PrivateResource=procrun_private.rc
+ResourceIncludes=
+MakeIncludes=
+Resources=procrun.rc
+Compiler=-DPROCRUN_WINAPP -O2
+Linker=-lshlwapi -lcomctl32
+IsCpp=0
+Icon=
+ExeOutput=bin
+ObjectOutput=release
+OverrideOutput=0
+OverrideOutputName=procrunw.exe
+HostApplication=
+Folders=
+CommandLine=
+IncludeVersionInfo=0
+SupportXPThemes=0
+CompilerSet=0
+CompilerSettings=000000000000000000
+
+[Unit1]
+FileName=procrun.c
+Folder=procrun
+Compile=1
+CompileCpp=0
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit2]
+FileName=procrun.h
+Folder=procrun
+Compile=1
+CompileCpp=0
+OverrideBuildCmd=0
+BuildCmd=
+
+[VersionInfo]
+Major=0
+Minor=1
+Release=1
+Build=1
+LanguageID=1033
+CharsetID=1252
+CompanyName=
+FileVersion=
+FileDescription=Developed using the Dev-C++ IDE
+InternalName=
+LegalCopyright=
+LegalTrademarks=
+OriginalFilename=
+ProductName=
+ProductVersion=
+
+[Unit3]
+FileName=procgui.c
+Folder=procrun
+Compile=1
+CompileCpp=0
+OverrideBuildCmd=0
+BuildCmd=
+
diff --git a/src/native/nt/procrun/proctry.ico b/src/native/nt/procrun/proctry.ico
new file mode 100644
index 0000000..ab60f9e
Binary files /dev/null and b/src/native/nt/procrun/proctry.ico differ
diff --git a/src/native/nt/procrun/readme.txt b/src/native/nt/procrun/readme.txt
new file mode 100644
index 0000000..3565d72
--- /dev/null
+++ b/src/native/nt/procrun/readme.txt
@@ -0,0 +1,149 @@
+Procrun
+
+Features:
+
+1. Redirect console applications
+2. Running redirected applications as services
+3. Console or Windows GUI application mode to avoid any
+ temporarily flashing console windows in case the procrun
+ is invoked by a GUI program.
+4. Running Java applications using default or specified JVM
+5. Service management Install/Start/Stop/Delete/Update
+
+
+Invocation:
+
+procrun [action] [options] [parameters]
+
+Actions:
+Actions are two letter codes encapsulated inside double slashes followed
+by service name. The service name has to be without spaces.
+
+//IS//<serviceName> Install the service
+//RS//<serviceName> Run service
+ called only when running as service. Do not call that
+ directly.
+//DS//<serviceName> Delete the service
+//TS//<serviceName> Test the service
+ Run service as ordinary console application.
+//US//<serviceName> Update service
+ Change services startup parameters
+//GT//<serviceName> Test (Run) the service using windows try
+ The service will run and put the icon in the
+ system try.
+//GD//<serviceName> Test (Run) the service using windows try
+ The service will run and and show console window.
+
+
+Options:
+Options are used for install and update actions and are written to the
+serviceName registry parameters.
+Options are followed with option parameter. If the option parameter
+needs spaces it has to be quoted.
+
+--DisplayName <service display name>
+ This is the name shown in the Windows Services
+ manager.
+--Description <service description>
+ This is the service description shown in the windows
+ Services manager.
+
+--ImagePath <full path to process executable>
+ Full path to the executable to be run as service,
+ or name of the Java Class Path. In cases when the
+ service runs JVM or Java binary this is the
+ parameter passed to -Djava.class.path option.
+
+--Arguments <arguments passed to the service>
+ Arguments are enclosed inside double quotation
+ marks and passed to the service image
+
+--WorkingPath <services working path>
+ Sets the working path to the desired value.
+
+--Java [auto|java|path to the jvm.dll]
+ auto:
+ Auto will cause to load the default JVM read
+ read from registry.
+ java[w]:
+ The default java.exe or javaw.exe will be
+ located and executed with
+ -Djava.class.path=ImagePath
+ If neither java or auto are specified then this
+ parameter is treated as full path to the jvm.dll
+
+--JavaOptions <list of java options>
+ This is the list of options to be passed to the JVM
+ The options are separated using hash (#) simbol.
+ For Example:
+ -Xmx=100M#-Djava.compiler=NONE
+
+--StartupClass <class name>
+ Class name that will be called if started from JVM
+ when the applications starts.
+ The method name is separated by semicolon after the
+ class name.
+ The parameters passed to the class method are semicolon
+ separated values after the method name.
+ For example:
+ org/apache/jk/apr/TomcatStarter;Main;start
+
+--ShutdownClass <class name>
+ Class name that will be called if started from JVM
+ when the applications stops. The class has to have
+ the method Main.
+ The method name is separated by semicolon after the
+ class name.
+ The parameters passed to the class method are semicolon
+ separated values after the method name.
+ For example:
+ org/apache/jk/apr/TomcatStarter;Main;stop;some;dummy;params
+
+--StdInputFile <path to the file>
+ The file that will be read an passed as standard
+ input stream to the redirected application
+--StdOutputFile <path to the file>
+ Path to the redirected stdout.
+--StdErrorFile <path to the file>
+ Path to the redirected stderr.
+
+--Startup <auto|manual>
+ The services startup mode Automatic or Manual.
+ Default value is auto.
+
+--User <username>
+ The User account used for launching redirected process.
+
+--Password <password>
+ The password of User account used for launching
+ redirected process.
+
+--Install <procrun.exe>
+ Used as Service manager ImagePath when installing
+ service from installation program using procrunw.
+
+Examples:
+
+Installing Tomcat as service:
+ procrun //IS//Tomcat4 --DisplayName "Tomcat 4.1.19" \
+ --Description "Tomcat 4.1.19 LE JDK 1.4 http://jakarta.apache.org" \
+ --ImagePath "c:\devtools\tomcat\41\bin\bootstrap.jar" \
+ --StartupClass org.apache.catalina.startup.Bootstrap;main;start \
+ --ShutdownClass org.apache.catalina.startup.Bootstrap;main;stop \
+ --Java auto
+
+Installing Tomcat as service without popup console window:
+ procrunw //IS//Tomcat4 --DisplayName "Tomcat 4.1.19" \
+ --Description "Tomcat 4.1.19 LE JDK 1.4 http://jakarta.apache.org" \
+ --Install "c:\devtools\tomcat\41\bin\procrun.exe"
+
+After installing you may call update service to add or change service
+parameters:
+ procrunw //US//Tomcat4 \
+ --ImagePath "c:\devtools\tomcat\41\bin\bootstrap.jar" \
+ --StartupClass org.apache.catalina.startup.Bootstrap;main;start \
+ --ShutdownClass org.apache.catalina.startup.Bootstrap;main;stop \
+ --Java auto
+
+Notice:
+ You may change all parameters except service name and Install image.
diff --git a/src/native/nt/procrun/splash.bmp b/src/native/nt/procrun/splash.bmp
new file mode 100644
index 0000000..ff67143
Binary files /dev/null and b/src/native/nt/procrun/splash.bmp differ
diff --git a/src/native/nt/procrun/testchild/testchild.c b/src/native/nt/procrun/testchild/testchild.c
new file mode 100644
index 0000000..1789c43
--- /dev/null
+++ b/src/native/nt/procrun/testchild/testchild.c
@@ -0,0 +1,121 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2000-2002 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" must
+ * not be used to endorse or promote products derived from this
+ * software without prior written permission. For written
+ * permission, please contact apache at apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * Portions of this software are based upon public domain software
+ * originally written at the National Center for Supercomputing Applications,
+ * University of Illinois, Urbana-Champaign.
+ */
+
+/* ====================================================================
+ * testchild.c
+ *
+ * Contributed by Mladen Turk <mturk at mappingsoft.com>
+ *
+ * 05 Aug 2002
+ * ====================================================================
+ */
+
+#ifndef STRICT
+#define STRICT
+#endif
+#ifndef OEMRESOURCE
+#define OEMRESOURCE
+#endif
+
+#include <windows.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <io.h>
+#include <fcntl.h>
+#include <process.h>
+#include <time.h>
+#include <stdarg.h>
+
+BOOL WINAPI ControlHandler ( DWORD dwCtrlType )
+{
+ switch (dwCtrlType) {
+ case CTRL_BREAK_EVENT:
+ printf("got CTRL+BREAK Event\n");
+ exit(1);
+ return TRUE;
+ case CTRL_C_EVENT:
+ printf("got CTRL+C Event\n");
+ exit(2);
+ return TRUE;
+ break;
+
+ }
+ return FALSE;
+}
+
+//int main(int argc, char **argv, char **envp)
+void __cdecl main(int argc, char **argv)
+
+{
+ int i;
+ char **envp = _environ;
+ SetConsoleCtrlHandler(ControlHandler, TRUE);
+
+ printf("Testing child\n");
+ printf("ARGV:\n");
+ for (i = 0; i < argc; i++)
+ printf("\t%d %s\n", i, argv[i]);
+ printf("ENVP:\n");
+ for (i = 0; envp[i]; i++)
+ printf("\t%d %s\n", i, envp[i]);
+
+ printf("\nChild done...\n");
+ fflush(stdout);
+ for (i = 0; i < 1000; i++)
+ Sleep(100);
+}
\ No newline at end of file
diff --git a/src/native/nt/procrun/testchild/testchild.dsp b/src/native/nt/procrun/testchild/testchild.dsp
new file mode 100644
index 0000000..2d85bcb
--- /dev/null
+++ b/src/native/nt/procrun/testchild/testchild.dsp
@@ -0,0 +1,106 @@
+# Microsoft Developer Studio Project File - Name="testchild" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=testchild - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "testchild.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "testchild.mak" CFG="testchild - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "testchild - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE "testchild - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "testchild - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /ZI /W3 /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Gm PRECOMP_VC7_TOBEREMOVED /GZ /c /GX
+# ADD CPP /nologo /MDd /ZI /W3 /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Gm PRECOMP_VC7_TOBEREMOVED /GZ /c /GX
+# ADD BASE MTL /nologo /win32
+# ADD MTL /nologo /win32
+# ADD BASE RSC /l 1033
+# ADD RSC /l 1033
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /out:"Debug\testchild.exe" /incremental:yes /debug /pdb:"Debug\testchild.pdb" /pdbtype:sept /subsystem:console /machine:ix86
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /out:"Debug\testchild.exe" /incremental:yes /debug /pdb:"Debug\testchild.pdb" /pdbtype:sept /subsystem:console /machine:ix86
+
+!ELSEIF "$(CFG)" == "testchild - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /Zi /W3 /O2 /Ob1 /Oy /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /GF /Gy PRECOMP_VC7_TOBEREMOVED /c /GX
+# ADD CPP /nologo /MD /Zi /W3 /O2 /Ob1 /Oy /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /GF /Gy PRECOMP_VC7_TOBEREMOVED /c /GX
+# ADD BASE MTL /nologo /win32
+# ADD MTL /nologo /win32
+# ADD BASE RSC /l 1033
+# ADD RSC /l 1033
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /out:"Release\testchild.exe" /incremental:no /debug /pdbtype:sept /subsystem:console /opt:ref /opt:icf /machine:ix86
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /out:"Release\testchild.exe" /incremental:no /debug /pdbtype:sept /subsystem:console /opt:ref /opt:icf /machine:ix86
+
+!ENDIF
+
+# Begin Target
+
+# Name "testchild - Win32 Debug"
+# Name "testchild - Win32 Release"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;def;odl;idl;hpj;bat;asm"
+# Begin Source File
+
+SOURCE=testchild.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl;inc"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
+
diff --git a/src/native/nt/procrun/testchild/testchild.vcproj b/src/native/nt/procrun/testchild/testchild.vcproj
new file mode 100644
index 0000000..e3cacb1
--- /dev/null
+++ b/src/native/nt/procrun/testchild/testchild.vcproj
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding = "windows-1250"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.00"
+ Name="testchild"
+ ProjectGUID="{C815B005-1292-47F7-9052-F46676CE2879}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/testchild.exe"
+ LinkIncremental="2"
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile="$(OutDir)/testchild.pdb"
+ SubSystem="1"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="1"
+ OmitFramePointers="TRUE"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ StringPooling="TRUE"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="TRUE"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/testchild.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="TRUE"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ </Configuration>
+ </Configurations>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm">
+ <File
+ RelativePath="testchild.c">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc">
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/src/native/nt/service/Makefile b/src/native/nt/service/Makefile
new file mode 100644
index 0000000..863af10
--- /dev/null
+++ b/src/native/nt/service/Makefile
@@ -0,0 +1,7 @@
+INCLUDE=-I../lib -I ../../unix/native
+../../../../dist/INSTSVC: instmain.c arguments.o debug.o
+ gcc $(INCLUDE) instmain.c -o ../../../../dist/INSTSVC arguments.o debug.o
+arguments.o: ../../unix/native/arguments.c
+ gcc -c $(INCLUDE) ../../unix/native/arguments.c
+debug.o: ../../unix/native/debug.c
+ gcc -c $(INCLUDE) ../../unix/native/debug.c
diff --git a/src/native/nt/service/instmain.c b/src/native/nt/service/instmain.c
new file mode 100644
index 0000000..0d12ca5
--- /dev/null
+++ b/src/native/nt/service/instmain.c
@@ -0,0 +1,477 @@
+/* ========================================================================= *
+ * *
+ * The Apache Software License, Version 1.1 *
+ * *
+ * Copyright (c) 1999-2001 The Apache Software Foundation. *
+ * All rights reserved. *
+ * *
+ * ========================================================================= *
+ * *
+ * Redistribution and use in source and binary forms, with or without modi- *
+ * fication, are permitted provided that the following conditions are met: *
+ * *
+ * 1. Redistributions of source code must retain the above copyright notice *
+ * notice, this list of conditions and the following disclaimer. *
+ * *
+ * 2. Redistributions in binary form must reproduce the above copyright *
+ * notice, this list of conditions and the following disclaimer in the *
+ * documentation and/or other materials provided with the distribution. *
+ * *
+ * 3. The end-user documentation included with the redistribution, if any, *
+ * must include the following acknowlegement: *
+ * *
+ * "This product includes software developed by the Apache Software *
+ * Foundation <http://www.apache.org/>." *
+ * *
+ * Alternately, this acknowlegement may appear in the software itself, if *
+ * and wherever such third-party acknowlegements normally appear. *
+ * *
+ * 4. The names "The Jakarta Project", "WebApp", and "Apache Software *
+ * Foundation" must not be used to endorse or promote products derived *
+ * from this software without prior written permission. For written *
+ * permission, please contact <apache at apache.org>. *
+ * *
+ * 5. Products derived from this software may not be called "Apache" nor may *
+ * "Apache" appear in their names without prior written permission of the *
+ * Apache Software Foundation. *
+ * *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES *
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY *
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL *
+ * THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY *
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL *
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS *
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) *
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, *
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN *
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
+ * POSSIBILITY OF SUCH DAMAGE. *
+ * *
+ * ========================================================================= *
+ * *
+ * This software consists of voluntary contributions made by many indivi- *
+ * duals on behalf of the Apache Software Foundation. For more information *
+ * on the Apache Software Foundation, please see <http://www.apache.org/>. *
+ * *
+ * ========================================================================= */
+
+/* @version $Id: instmain.c,v 1.1.1.1 2003/09/04 23:28:20 yoavs Exp $ */
+
+/*
+ * jsvc.exe install program, create the service JavaService
+ */
+
+/* includes */
+#include <windows.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "moni_inst.h"
+
+/* Definitions for booleans */
+typedef enum {
+ false,
+ true
+} bool;
+#include "arguments.h"
+
+VOID Usage()
+{
+ printf( "\r\n - Java service installer\r\n\r\n");
+ printf( " - Usage :\r\n");
+
+ printf( " To install Java service : InstSvc -install ");
+ printf( " [-home JAVA_HOME] [-Dproperty=value]\r\n");
+ printf( " [-cp CLASSPATH] startclass\r\n");
+ printf( " Like:\r\n");
+
+ printf( " InstSvc -install -home c:\\jdk1.3.1_02");
+ printf( " -Dcatalina.home=/home1/jakarta/jakarta-tomcat-4.1/build");
+ printf( " -Djava.io.tmpdir=/var/tmp ");
+ printf( " -cp \"c:\\jdk1.3.1_02\\lib\\tools.jar;");
+ printf( "c:\\home1\\jakarta\\jakarta-tomcat-4.1\\build\\bin\\commons-daemon.jar;");
+ printf( "c:\\home1\\jakarta\\jakarta-tomcat-4.1\\build\\bin\\bootstrap.jar\"");
+ printf( " org.apache.catalina.startup.BootstrapService\r\n");
+
+ printf( " To remove Java service : InstSvc -remove\r\n\r\n");
+ printf( " Use regedit if you want to change something\r\n\r\n");
+ printf( " Note that the service keys are stored under:\r\n");
+ printf( " HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\");
+ printf( "%s",SZSERVICENAME);
+ printf( "\r\n");
+ printf( " The environment keys in:\r\n");
+ printf( " ");
+ printf( "%s",SZKEY_ONSERVE);
+ printf( "\r\n");
+ return;
+}
+
+/* from src/os/win32/service.c (httpd-1.3!) */
+
+BOOL isWindowsNT(void)
+{
+ static BOOL once = FALSE;
+ static BOOL isNT = FALSE;
+
+ if (!once)
+ {
+ OSVERSIONINFO osver;
+ osver.dwOSVersionInfoSize = sizeof(osver);
+ if (GetVersionEx(&osver))
+ if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT)
+ isNT = TRUE;
+ once = TRUE;
+ }
+ return isNT;
+}
+
+
+/* remove the service (first stop it!) NT version */
+
+BOOL RemoveSvcNT (VOID)
+{
+ BOOL removed;
+ SC_HANDLE hManager;
+ SC_HANDLE hService;
+ SERVICE_STATUS svcStatus;
+ DWORD dwCount;
+
+ removed = FALSE;
+ /* open service control manager with full access right */
+ hManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
+ if (NULL != hManager) {
+ /* open existing service */
+ hService = OpenService(hManager, SZSERVICENAME, SERVICE_ALL_ACCESS);
+ if (NULL != hService) {
+ /* get the status of the service */
+ if (QueryServiceStatus(hService, &svcStatus)) {
+ /* and see if the service is stopped */
+ if (SERVICE_STOPPED != svcStatus.dwCurrentState) {
+ /* if not stop the service */
+ ControlService(hService, SERVICE_CONTROL_STOP, &svcStatus);
+ }
+ dwCount = 0;
+ do {
+ if (SERVICE_STOPPED == svcStatus.dwCurrentState) {
+ /* delete the service */
+ if (DeleteService(hService)) {
+ removed = TRUE;
+ break;
+ }
+ }
+ /* wait 10 seconds for the service to stop */
+ Sleep(10000);
+ if (!QueryServiceStatus(hService, &svcStatus)) {
+ /* something went wrong */
+ break;
+ }
+ dwCount++;
+ } while (10 > dwCount);
+ }
+ /* close service handle */
+ CloseServiceHandle(hService);
+ }
+ /* close service control manager */
+ CloseServiceHandle(hManager);
+ }
+ return removed;
+} /* RemoveSvc */
+
+/* remove service (non NT) stopping it looks ugly!!! */
+BOOL RemoveSvc (VOID)
+{
+ HKEY hkey;
+ DWORD rv;
+
+ rv = RegOpenKey(HKEY_LOCAL_MACHINE,
+ "Software\\Microsoft\\Windows\\CurrentVersion\\RunServices",
+ &hkey);
+ if (rv != ERROR_SUCCESS) {
+ printf( "Could not open the RunServices registry key.\r\n");
+ return FALSE;
+ }
+ rv = RegDeleteValue(hkey, SZSERVICENAME);
+ RegCloseKey(hkey);
+ if (rv != ERROR_SUCCESS)
+ printf( "Could not delete the RunServices entry.\r\n");
+
+ rv = RegOpenKey(HKEY_LOCAL_MACHINE,
+ "SYSTEM\\CurrentControlSet\\Services", &hkey);
+ if (rv != ERROR_SUCCESS) {
+ printf( "Could not open the Services registry key.\r\n");
+ return FALSE;
+ }
+ rv = RegDeleteKey(hkey, SZSERVICENAME);
+ RegCloseKey(hkey);
+ if (rv != ERROR_SUCCESS) {
+ printf( "Could not delete the Services registry key.\r\n");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+/* Install service (NT version) */
+
+BOOL InstallSvcNT (CHAR *svcExePath)
+{
+ BOOL installed;
+ SC_HANDLE hManager;
+ SC_HANDLE hService;
+
+ installed = FALSE;
+ /* open the service control manager with full access right */
+ hManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
+ if (NULL != hManager) {
+ /* create the service
+ hService = CreateService(hManager,
+ SZSERVICENAME, /* name of the service */
+ SZSERVICEDISPLAYNAME, /* description */
+ SERVICE_ALL_ACCESS,
+ SERVICE_WIN32_OWN_PROCESS, /* type of service */
+ SERVICE_DEMAND_START, /* AUTO_START, startmode */
+ SERVICE_ERROR_NORMAL, /* error treatment */
+ svcExePath, /* path_name */
+ NULL, /* no load order enty */
+ NULL, /* no tag identifier. */
+ NULL, /* dependencies. */
+ NULL, /* LocalSystem account */
+ NULL); /* dummy user password */
+ if (NULL != hService) {
+ /* close service handle */
+ CloseServiceHandle(hService);
+ installed = TRUE;
+ }
+ } else {
+ printf( "OpenSCManager failed\r\n");
+ }
+ return installed;
+}
+
+/* Install service */
+
+BOOL InstallSvc (CHAR *svcExePath)
+{
+ HKEY hkey;
+ DWORD rv;
+ char szPath[MAX_PATH];
+
+ printf( "InstallSvc for non-NT\r\n");
+
+ rv = RegCreateKey(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows"
+ "\\CurrentVersion\\RunServices", &hkey);
+ if (rv != ERROR_SUCCESS) {
+ printf( "Could not open the RunServices registry key\r\n");
+ return FALSE;
+ }
+ rv = RegSetValueEx(hkey, SZSERVICENAME, 0, REG_SZ,
+ (unsigned char *) svcExePath,
+ strlen(svcExePath) + 1);
+ RegCloseKey(hkey);
+ if (rv != ERROR_SUCCESS) {
+ printf( "Could not add %s:%s ",SZSERVICENAME, svcExePath);
+ printf( "to RunServices Registry Key\r\n");
+ return FALSE;
+ }
+
+ strcpy(szPath,
+ "SYSTEM\\CurrentControlSet\\Services\\");
+ strcat(szPath,SZSERVICENAME);
+ rv = RegCreateKey(HKEY_LOCAL_MACHINE, szPath, &hkey);
+ if (rv != ERROR_SUCCESS) {
+ printf( "Could not create/open the %s registry key\r\n",
+ szPath);
+ return FALSE;
+ }
+ rv = RegSetValueEx(hkey, "ImagePath", 0, REG_SZ,
+ (unsigned char *) svcExePath,
+ strlen(svcExePath) + 1);
+ if (rv != ERROR_SUCCESS) {
+ RegCloseKey(hkey);
+ printf( "Could not add ImagePath to our Registry Key\r\n");
+ return FALSE;
+ }
+ rv = RegSetValueEx(hkey, "DisplayName", 0, REG_SZ,
+ (unsigned char *) SZSERVICEDISPLAYNAME,
+ strlen(SZSERVICEDISPLAYNAME) + 1);
+ RegCloseKey(hkey);
+ if (rv != ERROR_SUCCESS) {
+ printf( "Could not add DisplayName to our Registry Key\r\n");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*
+ * Fill the registry with the environment variables
+ */
+BOOL InstallEnv (char *var, char *value)
+{
+ BOOL installed;
+ HKEY hKey;
+
+ installed = FALSE;
+ /* create the parameters registry tree */
+ log_debug("InstallEnv: %s:%s",var,value);
+ if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_LOCAL_MACHINE, SZKEY_ONSERVE, 0,
+ NULL,REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NULL,
+ &hKey, NULL)) {
+ /* key is created or opened */
+ RegSetValueEx(hKey,var,0,REG_SZ,(BYTE *)value,lstrlen(value)+1);
+ RegCloseKey(hKey);
+ installed = TRUE;
+ }
+ return installed;
+} /* InstallEnv */
+
+/*
+ * Add the arguments to start jsvc like -Dcatalina.home=/home/jakarta/tomcat.
+ */
+BOOL InstallEnvParm(int i,char *value)
+{
+ BOOL installed;
+ HKEY hKey;
+ char var[64];
+
+ sprintf(var,"arg%d",i);
+ log_debug("InstallEnvParm: %s:%s",var,value);
+
+ installed = FALSE;
+ /* create the parameters registry tree */
+ if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_LOCAL_MACHINE,
+ SZKEY_ONSERVEARG, 0,
+ NULL,REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NULL,
+ &hKey, NULL)) {
+ /* key is created or opened */
+ RegSetValueEx(hKey,var,0,REG_SZ,
+ (BYTE *)value,lstrlen(value)+1);
+ RegCloseKey(hKey);
+ installed = TRUE;
+ }
+ return installed;
+}
+
+/*
+ * Remove the created keys
+ */
+BOOL RemoveEnv()
+{
+ HKEY hkey;
+ DWORD rv;
+
+ log_debug("RemoveEnv");
+
+ rv = RegOpenKey(HKEY_LOCAL_MACHINE,
+ NULL,
+ &hkey);
+ if (rv != ERROR_SUCCESS) {
+ printf( "Could not open the jsvc registry key.\r\n");
+ return FALSE;
+ }
+ rv = RegDeleteKey(hkey, SZKEY_ONSERVE);
+ RegCloseKey(hkey);
+ if (rv != ERROR_SUCCESS)
+ printf( "Could not delete the jsvc entry.\r\n");
+
+ /* remove the key tree if empty */
+
+ return TRUE;
+}
+
+
+/*
+ * Install or remove the OnServe service and Key in the registry.
+ * no parameter install the OnServe.
+ * -REMOVE: desinstall the OnServe service and Keys.
+ */
+
+INT main (INT argc, CHAR *argv[])
+{
+ BOOL done;
+ arg_data *args=NULL;
+ char szPath[512];
+ char szExePath[512];
+ int i;
+
+ printf( "\r\n - Copyright (c) 2001 The Apache Software Foundation. \r\n");
+ printf( "\r\n");
+ if (GetModuleFileName(NULL, szPath, sizeof(szPath))) {
+ printf( "%s\r\n",szPath);
+ }
+
+ args=arguments(argc,argv);
+ if (args==NULL) {
+ Usage();
+ return(1);
+ }
+
+
+ if (args->install==true) {
+ if (args->home==NULL) {
+ printf( "home empty or not defined...\r\n\r\n");
+ Usage();
+ return(1);
+ }
+ if (args->clas==NULL) {
+ printf( "startclass empty or not defined...\r\n\r\n");
+ Usage();
+ return(1);
+ }
+ printf( "\r\ninstalling...\r\n\r\n");
+
+ /* get the patch from the executable name */
+ for(i=strlen(szPath);i>0;i--)
+ if (szPath[i]=='\\') {
+ szPath[i]='\0';
+ break;
+ }
+ strcpy(szExePath,szPath);
+ strcat(szExePath,SZDEFMONISVCPATH);
+ /* install jsvcservice.exe as a service */
+ if (isWindowsNT())
+ done = InstallSvcNT(szExePath);
+ else
+ done = InstallSvc(szExePath);
+
+ if (done)
+ printf( "InstallSvc done\r\n");
+ else
+ printf( "InstallSvc failed\r\n");
+
+ /* install the environment variable in registry */
+
+ /* should get it from szPath */
+ InstallEnv("JAKARTA_HOME",szPath);
+
+ InstallEnv("CYGWIN",SZCYGWINPATH); /* need APR to get ride of it */
+
+ InstallEnv("JAVA_HOME",args->home);
+
+ InstallEnv("STARTCLASS",args->clas);
+
+ if (args->onum==0) return(0);
+
+ for(i=0;i<args->onum;i++)
+ InstallEnvParm(i,args->opts[i]);
+
+ return(0);
+ }
+
+ if (args->remove==true) {
+ /* remove the service. removing the keys not yet done!!! */
+ printf( "\r\n - removing Java Service...\r\n\r\n");
+ if (isWindowsNT())
+ done = RemoveSvcNT();
+ else
+ done = RemoveSvc();
+ if (!done) {
+ printf( "\r\n - REMOVE FAILED....\r\n\r\n");
+ return(2);
+ }
+ RemoveEnv();
+ return(0);
+ }
+ printf( "\r\nonly -install or -remove supported...\r\n\r\n");
+ Usage();
+ return(1);
+}
diff --git a/src/native/nt/service/instsvc.dsp b/src/native/nt/service/instsvc.dsp
new file mode 100644
index 0000000..dcc2256
--- /dev/null
+++ b/src/native/nt/service/instsvc.dsp
@@ -0,0 +1,104 @@
+# Microsoft Developer Studio Project File - Name="InstSvc" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=InstSvc - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "INSTSVC.MAK".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "INSTSVC.MAK" CFG="InstSvc - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "InstSvc - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "InstSvc - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "InstSvc - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir ".\Release"
+# PROP BASE Intermediate_Dir ".\Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir ".\InstSvc.Release"
+# PROP Intermediate_Dir ".\InstSvc.Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c
+# ADD CPP /nologo /W3 /GX /O2 /I "../lib" /D "WIN32" /D "_CONSOLE" /YX /FD /D "NDEBUG" /c
+# ADD BASE RSC /l 0x407 /d "NDEBUG"
+# ADD RSC /l 0x407 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../bin/INSTSVC.exe"
+
+!ELSEIF "$(CFG)" == "InstSvc - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir ".\Debug"
+# PROP BASE Intermediate_Dir ".\Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir ".\InstSvc.Debug"
+# PROP Intermediate_Dir ".\InstSvc.Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c
+# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /FR /YX /FD /c
+# ADD BASE RSC /l 0x407 /d "_DEBUG"
+# ADD RSC /l 0x407 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386
+
+!ENDIF
+
+# Begin Target
+
+# Name "InstSvc - Win32 Release"
+# Name "InstSvc - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
+# Begin Source File
+
+SOURCE=.\instmain.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
+# Begin Source File
+
+SOURCE=..\lib\moni_inst.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/src/native/nt/service/instsvc.dsw b/src/native/nt/service/instsvc.dsw
new file mode 100644
index 0000000..5ef42f8
--- /dev/null
+++ b/src/native/nt/service/instsvc.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 5.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "InstSvc"=.\INSTSVC.DSP - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/src/native/nt/signals/kills.c b/src/native/nt/signals/kills.c
new file mode 100644
index 0000000..dbc2f98
--- /dev/null
+++ b/src/native/nt/signals/kills.c
@@ -0,0 +1,88 @@
+/* ========================================================================= *
+ * *
+ * The Apache Software License, Version 1.1 *
+ * *
+ * Copyright (c) 1999-2001 The Apache Software Foundation. *
+ * All rights reserved. *
+ * *
+ * ========================================================================= *
+ * *
+ * Redistribution and use in source and binary forms, with or without modi- *
+ * fication, are permitted provided that the following conditions are met: *
+ * *
+ * 1. Redistributions of source code must retain the above copyright notice *
+ * notice, this list of conditions and the following disclaimer. *
+ * *
+ * 2. Redistributions in binary form must reproduce the above copyright *
+ * notice, this list of conditions and the following disclaimer in the *
+ * documentation and/or other materials provided with the distribution. *
+ * *
+ * 3. The end-user documentation included with the redistribution, if any, *
+ * must include the following acknowlegement: *
+ * *
+ * "This product includes software developed by the Apache Software *
+ * Foundation <http://www.apache.org/>." *
+ * *
+ * Alternately, this acknowlegement may appear in the software itself, if *
+ * and wherever such third-party acknowlegements normally appear. *
+ * *
+ * 4. The names "The Jakarta Project", "WebApp", and "Apache Software *
+ * Foundation" must not be used to endorse or promote products derived *
+ * from this software without prior written permission. For written *
+ * permission, please contact <apache at apache.org>. *
+ * *
+ * 5. Products derived from this software may not be called "Apache" nor may *
+ * "Apache" appear in their names without prior written permission of the *
+ * Apache Software Foundation. *
+ * *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES *
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY *
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL *
+ * THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY *
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL *
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS *
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) *
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, *
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN *
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
+ * POSSIBILITY OF SUCH DAMAGE. *
+ * *
+ * ========================================================================= *
+ * *
+ * This software consists of voluntary contributions made by many indivi- *
+ * duals on behalf of the Apache Software Foundation. For more information *
+ * on the Apache Software Foundation, please see <http://www.apache.org/>. *
+ * *
+ * ========================================================================= */
+
+/* @version $Id: kills.c,v 1.1.1.1 2003/09/04 23:28:20 yoavs Exp $ */
+
+/*
+ * as Windows does not support signal, jsvc uses events to emulate them.
+ * The supported signal is SIGTERM.
+ * signals.c contains the signal handler logic.
+ */
+#include <windows.h>
+#include <stdio.h>
+
+/*
+ * Send a clean termination signal to a process
+ * it is like kill(pid,SIGTERM);
+ */
+int TermPid(long pid)
+{
+char Name[256];
+HANDLE hevint;
+BOOL rc;
+
+ sprintf(Name,"TERM%ld",pid);
+
+ hevint = OpenEvent(EVENT_MODIFY_STATE,FALSE,Name);
+ if (hevint == NULL) return(-1); /* failed */
+
+ rc = SetEvent(hevint);
+ CloseHandle(hevint);
+
+ if (rc) return(0);
+ return(-1);
+}
diff --git a/src/native/nt/supcalls_nt/vdenv.c b/src/native/nt/supcalls_nt/vdenv.c
new file mode 100644
index 0000000..f2653c3
--- /dev/null
+++ b/src/native/nt/supcalls_nt/vdenv.c
@@ -0,0 +1,219 @@
+/* ========================================================================= *
+ * *
+ * The Apache Software License, Version 1.1 *
+ * *
+ * Copyright (c) 1999-2001 The Apache Software Foundation. *
+ * All rights reserved. *
+ * *
+ * ========================================================================= *
+ * *
+ * Redistribution and use in source and binary forms, with or without modi- *
+ * fication, are permitted provided that the following conditions are met: *
+ * *
+ * 1. Redistributions of source code must retain the above copyright notice *
+ * notice, this list of conditions and the following disclaimer. *
+ * *
+ * 2. Redistributions in binary form must reproduce the above copyright *
+ * notice, this list of conditions and the following disclaimer in the *
+ * documentation and/or other materials provided with the distribution. *
+ * *
+ * 3. The end-user documentation included with the redistribution, if any, *
+ * must include the following acknowlegement: *
+ * *
+ * "This product includes software developed by the Apache Software *
+ * Foundation <http://www.apache.org/>." *
+ * *
+ * Alternately, this acknowlegement may appear in the software itself, if *
+ * and wherever such third-party acknowlegements normally appear. *
+ * *
+ * 4. The names "The Jakarta Project", "WebApp", and "Apache Software *
+ * Foundation" must not be used to endorse or promote products derived *
+ * from this software without prior written permission. For written *
+ * permission, please contact <apache at apache.org>. *
+ * *
+ * 5. Products derived from this software may not be called "Apache" nor may *
+ * "Apache" appear in their names without prior written permission of the *
+ * Apache Software Foundation. *
+ * *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES *
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY *
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL *
+ * THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY *
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL *
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS *
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) *
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, *
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN *
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
+ * POSSIBILITY OF SUCH DAMAGE. *
+ * *
+ * ========================================================================= *
+ * *
+ * This software consists of voluntary contributions made by many indivi- *
+ * duals on behalf of the Apache Software Foundation. For more information *
+ * on the Apache Software Foundation, please see <http://www.apache.org/>. *
+ * *
+ * ========================================================================= */
+
+/* @version $Id: vdenv.c,v 1.1.1.1 2003/09/04 23:28:20 yoavs Exp $ */
+
+/* Read the Win-NT register and set the jsvc environment variable. */
+/* XXX We should use a property file instead registry */
+
+/* XXX Set the PATH (for dynamic linking!) what about libapr*.so? */
+
+#include <windows.h>
+#include "moni_inst.h"
+
+#define ENVSIZE 1024
+
+int MySetEnvironmentVariable(char *name, char *data)
+{
+char Variable[ENVSIZE];
+
+ strcpy(Variable,name);
+ strcat(Variable,"=");
+ strcat(Variable,data);
+ if (putenv(Variable)) return(-1);
+ return(0);
+}
+/*
+ * FUNCTION: OnServeSetEnv()
+ *
+ * PURPOSE: Actual code of the routine that reads the registry and
+ * set the OnServe environment variables.
+ * The PATH is needed for the dynamic linking.
+ *
+ * RETURN VALUE:
+ * 0 : All OK.
+ * <0: Something Failed. (Registry cannot be read or one key cannot be read).
+ *
+*/
+int OnServeSetEnv ()
+{
+HKEY hKey=NULL;
+DWORD Type;
+char jakarta_home[ENVSIZE]; /* for the path */
+char cygwin[ENVSIZE]; /* for the path */
+char Data[ENVSIZE];
+DWORD LData;
+int qreturn=0;
+
+
+ /* Read the registry and set environment. */
+ if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, SZKEY_ONSERVE,
+ 0, KEY_READ,&hKey) != ERROR_SUCCESS)
+ return(-1);
+
+ /* read key and set environment. */
+
+ /* JAKARTA_HOME */
+ LData = sizeof(Data);
+ if (RegQueryValueEx(hKey,"JAKARTA_HOME",NULL,&Type,Data,&LData)==ERROR_SUCCESS) {
+ strcpy(jakarta_home,Data);
+ MySetEnvironmentVariable("JAKARTA_HOME",Data);
+ }
+ else
+ qreturn = -2;
+
+ /* CYGWIN */
+ LData = sizeof(Data);
+ if (RegQueryValueEx(hKey,"CYGWIN",NULL,&Type,Data,&LData)==ERROR_SUCCESS) {
+ strcpy(cygwin,Data);
+ MySetEnvironmentVariable("CYGWIN",Data);
+ }
+ else
+ qreturn = -3;
+
+ /* JAVA_HOME */
+ LData = sizeof(Data);
+ if (RegQueryValueEx(hKey,"JAVA_HOME",NULL,&Type,Data,&LData)
+ ==ERROR_SUCCESS) {
+ MySetEnvironmentVariable("JAVA_HOME",Data);
+ }
+ else
+ qreturn = -4;
+
+ RegCloseKey(hKey);
+ hKey = NULL;
+
+ /* set the PATH otherwise nothing works!!! */
+ LData = sizeof(Data);
+ if (!GetEnvironmentVariable("PATH",Data,LData)) {
+ strcpy(Data,jakarta_home);
+ }
+ else {
+ strcat(Data,";");
+ strcat(Data,jakarta_home);
+ }
+ strcat(Data,"\\bin");
+
+ strcat(Data,";");
+ strcat(Data,cygwin);
+ strcat(Data,"\\bin");
+
+ MySetEnvironmentVariable("PATH",Data);
+
+ return(qreturn);
+}
+
+/*
+ * Build the jsvc.exe command using the registry information.
+ */
+int BuildCommand(char *data)
+{
+ int i;
+ LONG lRet;
+ DWORD dwIndex;
+ char name[128];
+ DWORD lname;
+ char value[256];
+ DWORD lvalue;
+ DWORD nvalue;
+ DWORD Type;
+ HKEY hKey=NULL;
+
+
+ strcat(data,"\\jsvc.exe -nodetach ");
+
+ /* Read the registry and set environment. */
+ if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, SZKEY_ONSERVEARG,
+ 0, KEY_READ,&hKey) != ERROR_SUCCESS)
+ return(-1);
+ if (RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL,
+ &nvalue,NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
+ return(-2);
+
+ /* Read the arguments */
+ for (i=0;i<nvalue;i++) {
+ lname = sizeof(name);
+ lvalue = sizeof(value);
+
+ lRet = RegEnumValue (hKey, i, name, &lname, NULL, NULL,
+ value, &lvalue);
+ if (lRet != ERROR_SUCCESS) {
+ RegCloseKey(hKey);
+ return(-3);
+ }
+
+ strncat(data,value,lvalue);
+ strcat(data," ");
+ }
+ RegCloseKey(hKey);
+
+ /* Read the start class. */
+ if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, SZKEY_ONSERVE,
+ 0, KEY_READ,&hKey) != ERROR_SUCCESS)
+ return(-4);
+ lvalue = sizeof(value);
+ if (RegQueryValueEx(hKey,"STARTCLASS",NULL,&Type,value,&lvalue)
+ !=ERROR_SUCCESS) {
+ RegCloseKey(hKey);
+ return(-5);
+ }
+ RegCloseKey(hKey);
+
+ strncat(data,value,lvalue);
+
+ return(0);
+}
diff --git a/src/native/unix/INSTALL.txt b/src/native/unix/INSTALL.txt
new file mode 100644
index 0000000..60c04f5
--- /dev/null
+++ b/src/native/unix/INSTALL.txt
@@ -0,0 +1,36 @@
+To build the service libraries and binary under an UNIX operating
+system you will need:
+
+ An ANSI-C compliant compiler (GCC is good)
+ GNU AutoConf
+ A Java Platform 2 compliant SDK
+
+First of all you need to build the "configure" program with:
+
+ sh support/buildconf.sh
+(Note it is possible to replace sh by any compatible shell like bash, ksh).
+
+Once the configure script is generated, run it (remember to specify
+either the --with-java=<dir> parameter or set the JAVA_HOME environment
+to point to your JDK installation. For example:
+
+ ./configure --with-java=/usr/java
+
+or
+
+ JAVA_HOME=/usr/java
+ export JAVA_HOME
+ ./configure
+
+If your operating system is supported, configure will go thru cleanly,
+otherwise it will report an error (please send us the details of your
+OS/JDK, or a patch against the sources). To build the binaries and
+libraries simply do:
+
+ make
+
+This will generate the file: ./jsvc.
+It should be straightforward from here on. To check the allowed parameters
+for the jsvc binary simply do
+
+ ./native/jsvc -help
diff --git a/src/native/unix/Makedefs.in b/src/native/unix/Makedefs.in
new file mode 100644
index 0000000..2154bdf
--- /dev/null
+++ b/src/native/unix/Makedefs.in
@@ -0,0 +1,71 @@
+# ========================================================================= #
+# #
+# The Apache Software License, Version 1.1 #
+# #
+# Copyright (c) 1999-2001 The Apache Software Foundation. #
+# All rights reserved. #
+# #
+# ========================================================================= #
+# #
+# Redistribution and use in source and binary forms, with or without modi- #
+# fication, are permitted provided that the following conditions are met: #
+# #
+# 1. Redistributions of source code must retain the above copyright notice #
+# notice, this list of conditions and the following disclaimer. #
+# #
+# 2. Redistributions in binary form must reproduce the above copyright #
+# notice, this list of conditions and the following disclaimer in the #
+# documentation and/or other materials provided with the distribution. #
+# #
+# 3. The end-user documentation included with the redistribution, if any, #
+# must include the following acknowlegement: #
+# #
+# "This product includes software developed by the Apache Software #
+# Foundation <http://www.apache.org/>." #
+# #
+# Alternately, this acknowlegement may appear in the software itself, if #
+# and wherever such third-party acknowlegements normally appear. #
+# #
+# 4. The names "The Jakarta Project", "WebApp", and "Apache Software #
+# Foundation" must not be used to endorse or promote products derived #
+# from this software without prior written permission. For written #
+# permission, please contact <apache at apache.org>. #
+# #
+# 5. Products derived from this software may not be called "Apache" nor may #
+# "Apache" appear in their names without prior written permission of the #
+# Apache Software Foundation. #
+# #
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES #
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY #
+# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL #
+# THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY #
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL #
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS #
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) #
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, #
+# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN #
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE #
+# POSSIBILITY OF SUCH DAMAGE. #
+# #
+# ========================================================================= #
+# #
+# This software consists of voluntary contributions made by many indivi- #
+# duals on behalf of the Apache Software Foundation. For more information #
+# on the Apache Software Foundation, please see <http://www.apache.org/>. #
+# #
+# ========================================================================= #
+
+# @author Pier Fumagalli <mailto:pier.fumagalli at eng.sun.com>
+# @version $Id: Makedefs.in,v 1.1.1.1 2003/09/04 23:28:20 yoavs Exp $
+
+CC = @CC@
+JAVAC = @JAVAC@
+JAR = @JAR@
+CFLAGS = @CFLAGS@
+LDFLAGS = @LDFLAGS@
+JAVACFLAGS = @JAVACFLAGS@
+RANLIB = @RANLIB@
+LDCMD = @LDCMD@
+
+.c.o:
+ $(CC) $(CFLAGS) -c $< -o $@
diff --git a/src/native/unix/Makefile.in b/src/native/unix/Makefile.in
new file mode 100644
index 0000000..ba4fc2b
--- /dev/null
+++ b/src/native/unix/Makefile.in
@@ -0,0 +1,80 @@
+# ========================================================================= #
+# #
+# The Apache Software License, Version 1.1 #
+# #
+# Copyright (c) 1999-2001 The Apache Software Foundation. #
+# All rights reserved. #
+# #
+# ========================================================================= #
+# #
+# Redistribution and use in source and binary forms, with or without modi- #
+# fication, are permitted provided that the following conditions are met: #
+# #
+# 1. Redistributions of source code must retain the above copyright notice #
+# notice, this list of conditions and the following disclaimer. #
+# #
+# 2. Redistributions in binary form must reproduce the above copyright #
+# notice, this list of conditions and the following disclaimer in the #
+# documentation and/or other materials provided with the distribution. #
+# #
+# 3. The end-user documentation included with the redistribution, if any, #
+# must include the following acknowlegement: #
+# #
+# "This product includes software developed by the Apache Software #
+# Foundation <http://www.apache.org/>." #
+# #
+# Alternately, this acknowlegement may appear in the software itself, if #
+# and wherever such third-party acknowlegements normally appear. #
+# #
+# 4. The names "The Jakarta Project", "WebApp", and "Apache Software #
+# Foundation" must not be used to endorse or promote products derived #
+# from this software without prior written permission. For written #
+# permission, please contact <apache at apache.org>. #
+# #
+# 5. Products derived from this software may not be called "Apache" nor may #
+# "Apache" appear in their names without prior written permission of the #
+# Apache Software Foundation. #
+# #
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES #
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY #
+# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL #
+# THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY #
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL #
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS #
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) #
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, #
+# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN #
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE #
+# POSSIBILITY OF SUCH DAMAGE. #
+# #
+# ========================================================================= #
+# #
+# This software consists of voluntary contributions made by many indivi- #
+# duals on behalf of the Apache Software Foundation. For more information #
+# on the Apache Software Foundation, please see <http://www.apache.org/>. #
+# #
+# ========================================================================= #
+
+# @author Pier Fumagalli <mailto:pier.fumagalli at eng.sun.com>
+# @version $Id: Makefile.in,v 1.1.1.1 2003/09/04 23:28:20 yoavs Exp $
+
+SUBDIRS = native
+
+all: native/all
+
+native/all:
+ $(MAKE) -C native all
+
+clean:
+ $(MAKE) -C native clean
+
+distclean: clean
+ rm -f config.cache
+ rm -f config.log
+ rm -f config.status
+ rm -f native/Makefile
+ rm -f Makefile
+ rm -f Makedefs
+
+realclean: distclean
+ rm -f configure
diff --git a/src/native/unix/configure b/src/native/unix/configure
new file mode 100755
index 0000000..ef6b96e
--- /dev/null
+++ b/src/native/unix/configure
@@ -0,0 +1,3530 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.57.
+#
+# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
+# Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+ set -o posix
+fi
+
+# Support unset when possible.
+if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+ LC_TELEPHONE LC_TIME
+do
+ if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then
+ eval $as_var=C; export $as_var
+ else
+ $as_unset $as_var
+ fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)$' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+ /^X\/\(\/\/\)$/{ s//\1/; q; }
+ /^X\/\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" || {
+ # Find who we are. Look in the path if we contain no path at all
+ # relative or not.
+ case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+ ;;
+ esac
+ # We did not find ourselves, most probably we were run as `sh COMMAND'
+ # in which case we are not to be found in the path.
+ if test "x$as_myself" = x; then
+ as_myself=$0
+ fi
+ if test ! -f "$as_myself"; then
+ { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+ { (exit 1); exit 1; }; }
+ fi
+ case $CONFIG_SHELL in
+ '')
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for as_base in sh bash ksh sh5; do
+ case $as_dir in
+ /*)
+ if ("$as_dir/$as_base" -c '
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
+ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+ CONFIG_SHELL=$as_dir/$as_base
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+ fi;;
+ esac
+ done
+done
+;;
+ esac
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line before each line; the second 'sed' does the real
+ # work. The second script uses 'N' to pair each line-number line
+ # with the numbered line, and appends trailing '-' during
+ # substitution so that $LINENO is not a special case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
+ sed '=' <$as_myself |
+ sed '
+ N
+ s,$,-,
+ : loop
+ s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+ t loop
+ s,-$,,
+ s,^['$as_cr_digits']*\n,,
+ ' >$as_me.lineno &&
+ chmod +x $as_me.lineno ||
+ { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensible to this).
+ . ./$as_me.lineno
+ # Exit status is that of the last command.
+ exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+ *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T=' ' ;;
+ *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+ *) ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+ # We could just check for DJGPP; but this test a) works b) is more generic
+ # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+ if test -f conf$$.exe; then
+ # Don't use ln at all; we don't have any links
+ as_ln_s='cp -p'
+ else
+ as_ln_s='ln -s'
+ fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_config_libobj_dir=.
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete. It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+
+ac_unique_file="configure.in"
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT RANLIB ac_ct_RANLIB JAVA_H [...]
+ac_subst_files=''
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+ac_prev=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_option in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+ { (exit 1); exit 1; }; }
+ ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+ eval "enable_$ac_feature=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+ { (exit 1); exit 1; }; }
+ ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+ case $ac_option in
+ *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_$ac_feature='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid package name: $ac_package" >&2
+ { (exit 1); exit 1; }; }
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case $ac_option in
+ *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_$ac_package='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid package name: $ac_package" >&2
+ { (exit 1); exit 1; }; }
+ ac_package=`echo $ac_package | sed 's/-/_/g'`
+ eval "with_$ac_package=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+ { (exit 1); exit 1; }; }
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+ { (exit 1); exit 1; }; }
+ ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+ eval "$ac_envvar='$ac_optarg'"
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ { echo "$as_me: error: missing argument to $ac_option" >&2
+ { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+ eval ac_val=$`echo $ac_var`
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+ *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+ localstatedir libdir includedir oldincludedir infodir mandir
+do
+ eval ac_val=$`echo $ac_var`
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) ;;
+ *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+ If a cross compiler is detected then cross compile mode will be used." >&2
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$0" : 'X\(//\)[^/]' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+ { (exit 1); exit 1; }; }
+ else
+ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+ { (exit 1); exit 1; }; }
+ fi
+fi
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+ { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+ { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_CC_set=${CC+set}
+ac_env_CC_value=$CC
+ac_cv_env_CC_set=${CC+set}
+ac_cv_env_CC_value=$CC
+ac_env_CFLAGS_set=${CFLAGS+set}
+ac_env_CFLAGS_value=$CFLAGS
+ac_cv_env_CFLAGS_set=${CFLAGS+set}
+ac_cv_env_CFLAGS_value=$CFLAGS
+ac_env_LDFLAGS_set=${LDFLAGS+set}
+ac_env_LDFLAGS_value=$LDFLAGS
+ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
+ac_cv_env_LDFLAGS_value=$LDFLAGS
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures this package to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+ cat <<_ACEOF
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --infodir=DIR info documentation [PREFIX/info]
+ --mandir=DIR man documentation [PREFIX/man]
+_ACEOF
+
+ cat <<\_ACEOF
+
+System types:
+ --build=BUILD configure for building on BUILD [guessed]
+ --host=HOST cross-compile to build programs to run on HOST [BUILD]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+
+ cat <<\_ACEOF
+
+Optional Packages:
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --with-java=DIR Specify the location of your JDK installation
+
+Some influential environment variables:
+ CC C compiler command
+ CFLAGS C compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ CPPFLAGS C/C++ preprocessor flags, e.g. -I<include dir> if you have
+ headers in a nonstandard directory <include dir>
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ ac_popdir=`pwd`
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d $ac_dir || continue
+ ac_builddir=.
+
+if test "$ac_dir" != .; then
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+ ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+ .) # No --srcdir option. We are building in place.
+ ac_srcdir=.
+ if test -z "$ac_top_builddir"; then
+ ac_top_srcdir=.
+ else
+ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+ fi ;;
+ [\\/]* | ?:[\\/]* ) # Absolute path.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir ;;
+ *) # Relative path.
+ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
+# absolute.
+ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
+ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
+ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
+ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
+
+ cd $ac_dir
+ # Check for guested configure; otherwise get Cygnus style configure.
+ if test -f $ac_srcdir/configure.gnu; then
+ echo
+ $SHELL $ac_srcdir/configure.gnu --help=recursive
+ elif test -f $ac_srcdir/configure; then
+ echo
+ $SHELL $ac_srcdir/configure --help=recursive
+ elif test -f $ac_srcdir/configure.ac ||
+ test -f $ac_srcdir/configure.in; then
+ echo
+ $ac_configure --help
+ else
+ echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi
+ cd $ac_popdir
+ done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+ cat <<\_ACEOF
+
+Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
+Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit 0
+fi
+exec 5>config.log
+cat >&5 <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by $as_me, which was
+generated by GNU Autoconf 2.57. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo = `(hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ echo "PATH: $as_dir"
+done
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_sep=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+ ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+ 2)
+ ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+ # Get rid of the leading space.
+ ac_sep=" "
+ ;;
+ esac
+ done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+{
+ (set) 2>&1 |
+ case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ sed -n \
+ "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+ ;;
+ *)
+ sed -n \
+ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+ ;;
+ esac;
+}
+ echo
+
+ cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=$`echo $ac_var`
+ echo "$ac_var='"'"'$ac_val'"'"'"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ cat <<\_ASBOX
+## ------------- ##
+## Output files. ##
+## ------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=$`echo $ac_var`
+ echo "$ac_var='"'"'$ac_val'"'"'"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+ echo
+ sed "/^$/d" confdefs.h | sort
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ echo "$as_me: caught signal $ac_signal"
+ echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core core.* *.core &&
+ rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+ ' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special
+ # files actually), so we avoid doing that.
+ if test -f "$cache_file"; then
+ { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . $cache_file;;
+ *) . ./$cache_file;;
+ esac
+ fi
+else
+ { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+ sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+ eval ac_new_val="\$ac_env_${ac_var}_value"
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ { echo "$as_me:$LINENO: former value: $ac_old_val" >&5
+echo "$as_me: former value: $ac_old_val" >&2;}
+ { echo "$as_me:$LINENO: current value: $ac_new_val" >&5
+echo "$as_me: current value: $ac_new_val" >&2;}
+ ac_cache_corrupted=:
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+ ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ac_aux_dir=
+for ac_dir in ./support $srcdir/./support; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ elif test -f $ac_dir/shtool; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/shtool install -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in ./support $srcdir/./support" >&5
+echo "$as_me: error: cannot find install-sh or install.sh in ./support $srcdir/./support" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"
+ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
+
+
+
+ printf "*** %s ***\n" "Current host" 1>&2
+
+
+# Make sure we can run config.sub.
+$ac_config_sub sun4 >/dev/null 2>&1 ||
+ { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5
+echo "$as_me: error: cannot run $ac_config_sub" >&2;}
+ { (exit 1); exit 1; }; }
+
+echo "$as_me:$LINENO: checking build system type" >&5
+echo $ECHO_N "checking build system type... $ECHO_C" >&6
+if test "${ac_cv_build+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_build_alias=$build_alias
+test -z "$ac_cv_build_alias" &&
+ ac_cv_build_alias=`$ac_config_guess`
+test -z "$ac_cv_build_alias" &&
+ { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5
+echo "$as_me: error: cannot guess build type; you must specify one" >&2;}
+ { (exit 1); exit 1; }; }
+ac_cv_build=`$ac_config_sub $ac_cv_build_alias` ||
+ { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;}
+ { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_build" >&5
+echo "${ECHO_T}$ac_cv_build" >&6
+build=$ac_cv_build
+build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+echo "$as_me:$LINENO: checking host system type" >&5
+echo $ECHO_N "checking host system type... $ECHO_C" >&6
+if test "${ac_cv_host+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_host_alias=$host_alias
+test -z "$ac_cv_host_alias" &&
+ ac_cv_host_alias=$ac_cv_build_alias
+ac_cv_host=`$ac_config_sub $ac_cv_host_alias` ||
+ { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;}
+ { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_host" >&5
+echo "${ECHO_T}$ac_cv_host" >&6
+host=$ac_cv_host
+host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+
+ echo "$as_me:$LINENO: checking cached host system type" >&5
+echo $ECHO_N "checking cached host system type... $ECHO_C" >&6
+ if { test x"${ac_cv_host_system_type+set}" = x"set" &&
+ test x"$ac_cv_host_system_type" != x"$host" ; }
+ then
+ echo "$as_me:$LINENO: result: $ac_cv_host_system_type" >&5
+echo "${ECHO_T}$ac_cv_host_system_type" >&6
+ { { echo "$as_me:$LINENO: error: remove the \"$cache_file\" file and re-run configure" >&5
+echo "$as_me: error: remove the \"$cache_file\" file and re-run configure" >&2;}
+ { (exit 1); exit 1; }; }
+ else
+ echo "$as_me:$LINENO: result: ok" >&5
+echo "${ECHO_T}ok" >&6
+ ac_cv_host_system_type="$host"
+ fi
+
+
+
+
+ printf "*** %s ***\n" "C-Language compilation tools" 1>&2
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ CC=$ac_ct_CC
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ CC=$ac_ct_CC
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$ac_ct_CC" && break
+done
+
+ CC=$ac_ct_CC
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+ "checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+ (eval $ac_compiler --version </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+ (eval $ac_compiler -v </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+ (eval $ac_compiler -V </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+echo "$as_me:$LINENO: checking for C compiler default output" >&5
+echo $ECHO_N "checking for C compiler default output... $ECHO_C" >&6
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
+ (eval $ac_link_default) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # Find the output, starting from the most likely. This scheme is
+# not robust to junk in `.', hence go to wildcards (a.*) only as a last
+# resort.
+
+# Be careful to initialize this variable, since it used to be cached.
+# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ac_cv_exeext=
+# b.out is created by i960 compilers.
+for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+ ;;
+ conftest.$ac_ext )
+ # This is the source file.
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ # FIXME: I believe we export ac_cv_exeext for Libtool,
+ # but it would be cool to find out if it's true. Does anybody
+ # maintain Libtool? --akim.
+ export ac_cv_exeext
+ break;;
+ * )
+ break;;
+ esac
+done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+ { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6
+
+# Check the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+ if { ac_try='./$ac_file'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ fi
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6
+
+echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ export ac_cv_exeext
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
+if test "${ac_cv_objext+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_compiler_gnu=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+CFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_g+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_prog_cc_g=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cc_g=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_prog_cc_stdc=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX -qlanglvl=ansi
+# Ultrix and OSF/1 -std1
+# HP-UX 10.20 and later -Ae
+# HP-UX older versions -Aa -D_HPUX_SOURCE
+# SVR4 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_prog_cc_stdc=$ac_arg
+break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.$ac_objext
+done
+rm -f conftest.$ac_ext conftest.$ac_objext
+CC=$ac_save_CC
+
+fi
+
+case "x$ac_cv_prog_cc_stdc" in
+ x|xno)
+ echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
+ *)
+ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+ CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+# Some people use a C++ compiler to compile C. Since we use `exit',
+# in C++ we need to declare it. In case someone uses the same compiler
+# for both compiling C and C++ we need to have the C++ compiler decide
+# the declaration of exit, since it's the most demanding environment.
+cat >conftest.$ac_ext <<_ACEOF
+#ifndef __cplusplus
+ choke me
+#endif
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ for ac_declaration in \
+ ''\
+ '#include <stdlib.h>' \
+ 'extern "C" void std::exit (int) throw (); using std::exit;' \
+ 'extern "C" void std::exit (int); using std::exit;' \
+ 'extern "C" void exit (int) throw ();' \
+ 'extern "C" void exit (int);' \
+ 'void exit (int);'
+do
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+$ac_declaration
+int
+main ()
+{
+exit (42);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+ echo '#ifdef __cplusplus' >>confdefs.h
+ echo $ac_declaration >>confdefs.h
+ echo '#endif' >>confdefs.h
+fi
+
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_RANLIB+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+ echo "$as_me:$LINENO: result: $RANLIB" >&5
+echo "${ECHO_T}$RANLIB" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+ ac_ct_RANLIB=$RANLIB
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_RANLIB"; then
+ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_RANLIB="ranlib"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+ echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
+echo "${ECHO_T}$ac_ct_RANLIB" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ RANLIB=$ac_ct_RANLIB
+else
+ RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+
+
+ printf "*** %s ***\n" "Java compilation tools" 1>&2
+
+
+
+
+# Check whether --with-java or --without-java was given.
+if test "${with_java+set}" = set; then
+ withval="$with_java"
+
+ echo "$as_me:$LINENO: checking JAVA_HOME" >&5
+echo $ECHO_N "checking JAVA_HOME... $ECHO_C" >&6
+ if test -d "$withval"
+ then
+ JAVA_HOME="$withval"
+ echo "$as_me:$LINENO: result: $JAVA_HOME" >&5
+echo "${ECHO_T}$JAVA_HOME" >&6
+ else
+ echo "$as_me:$LINENO: result: failed" >&5
+echo "${ECHO_T}failed" >&6
+ { { echo "$as_me:$LINENO: error: $withval is not a directory" >&5
+echo "$as_me: error: $withval is not a directory" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+
+
+fi;
+ if test x"$JAVA_HOME" = x
+ then
+ { { echo "$as_me:$LINENO: error: Java Home not defined. Rerun with --with-java=... parameter" >&5
+echo "$as_me: error: Java Home not defined. Rerun with --with-java=... parameter" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+
+
+ # Extract the first word of "javac", so it can be a program name with args.
+set dummy javac; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_JAVAC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $JAVAC in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_JAVAC="$JAVAC" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $JAVA_HOME/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_JAVAC="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ test -z "$ac_cv_path_JAVAC" && ac_cv_path_JAVAC="NONE"
+ ;;
+esac
+fi
+JAVAC=$ac_cv_path_JAVAC
+
+if test -n "$JAVAC"; then
+ echo "$as_me:$LINENO: result: $JAVAC" >&5
+echo "${ECHO_T}$JAVAC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ if test "$JAVAC" = "NONE"
+ then
+ # Extract the first word of "javac", so it can be a program name with args.
+set dummy javac; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_JAVAC_PATH+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $JAVAC_PATH in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_JAVAC_PATH="$JAVAC_PATH" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_JAVAC_PATH="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ test -z "$ac_cv_path_JAVAC_PATH" && ac_cv_path_JAVAC_PATH="NONE"
+ ;;
+esac
+fi
+JAVAC_PATH=$ac_cv_path_JAVAC_PATH
+
+if test -n "$JAVAC_PATH"; then
+ echo "$as_me:$LINENO: result: $JAVAC_PATH" >&5
+echo "${ECHO_T}$JAVAC_PATH" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ JAVAC=$JAVAC_PATH
+ fi
+ if test "$JAVAC" = "NONE"
+ then
+ { { echo "$as_me:$LINENO: error: javac not found" >&5
+echo "$as_me: error: javac not found" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+
+ echo "$as_me:$LINENO: checking wether the Java compiler ($JAVAC) works" >&5
+echo $ECHO_N "checking wether the Java compiler ($JAVAC) works... $ECHO_C" >&6
+if test "${ap_cv_prog_javac_works+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ echo "public class Test {}" > Test.java
+ $JAVAC $JAVACFLAGS Test.java > /dev/null 2>&1
+ if test $? -eq 0
+ then
+ rm -f Test.java Test.class
+ ap_cv_prog_javac_works=yes
+ else
+ rm -f Test.java Test.class
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ { { echo "$as_me:$LINENO: error: installation or configuration problem: javac cannot compile" >&5
+echo "$as_me: error: installation or configuration problem: javac cannot compile" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+
+fi
+echo "$as_me:$LINENO: result: $ap_cv_prog_javac_works" >&5
+echo "${ECHO_T}$ap_cv_prog_javac_works" >&6
+
+
+
+
+
+
+ # Extract the first word of "jar", so it can be a program name with args.
+set dummy jar; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_JAR+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $JAR in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_JAR="$JAR" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $JAVA_HOME/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_JAR="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ test -z "$ac_cv_path_JAR" && ac_cv_path_JAR="NONE"
+ ;;
+esac
+fi
+JAR=$ac_cv_path_JAR
+
+if test -n "$JAR"; then
+ echo "$as_me:$LINENO: result: $JAR" >&5
+echo "${ECHO_T}$JAR" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ if test "$JAR" = "NONE"
+ then
+ # Extract the first word of "jar", so it can be a program name with args.
+set dummy jar; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_JAR_PATH+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $JAR_PATH in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_JAR_PATH="$JAR_PATH" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_JAR_PATH="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ test -z "$ac_cv_path_JAR_PATH" && ac_cv_path_JAR_PATH="NONE"
+ ;;
+esac
+fi
+JAR_PATH=$ac_cv_path_JAR_PATH
+
+if test -n "$JAR_PATH"; then
+ echo "$as_me:$LINENO: result: $JAR_PATH" >&5
+echo "${ECHO_T}$JAR_PATH" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ JAR=$JAR_PATH
+ fi
+ if test "$JAR" = "NONE"
+ then
+ { { echo "$as_me:$LINENO: error: jar not found" >&5
+echo "$as_me: error: jar not found" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+
+
+
+
+
+ printf "*** %s ***\n" "Host support" 1>&2
+
+
+
+ echo "$as_me:$LINENO: checking C flags dependant on host system type" >&5
+echo $ECHO_N "checking C flags dependant on host system type... $ECHO_C" >&6
+ case $host_cpu in
+ powerpc)
+ CFLAGS="$CFLAGS -DCPU=\\\"$host_cpu\\\"" ;;
+ sparc)
+ CFLAGS="$CFLAGS -DCPU=\\\"$host_cpu\\\"" ;;
+ i?86)
+ CFLAGS="$CFLAGS -DCPU=\\\"i386\\\"" ;;
+ bs2000)
+ CFLAGS="$CFLAGS -DCPU=\\\"osd\\\" -DCHARSET_EBCDIC -DOSD_POSIX"
+ supported_os="osd"
+ LDFLAGS="-Kno_link_stdlibs -B llm4 -l BLSLIB $LDFLAGS"
+ LDCMD="cc"
+ ;;
+ mips)
+ CFLAGS="$CFLAGS -DCPU=\\\"mips\\\""
+ supported_os="mips"
+ ;;
+ *)
+ echo "$as_me:$LINENO: result: failed" >&5
+echo "${ECHO_T}failed" >&6
+ { { echo "$as_me:$LINENO: error: Unsupported CPU architecture \"$host_cpu\"" >&5
+echo "$as_me: error: Unsupported CPU architecture \"$host_cpu\"" >&2;}
+ { (exit 1); exit 1; }; };;
+ esac
+
+ case $host_os in
+ darwin*)
+ CFLAGS="$CFLAGS -DOS_DARWIN -DDSO_DYLD"
+ supported_os="darwin"
+ ;;
+ solaris*)
+ CFLAGS="$CFLAGS -DOS_SOLARIS -DDSO_DLFCN"
+ supported_os="solaris"
+ LDFLAGS="$LDFLAGS -ldl -lthread"
+ ;;
+ linux*)
+ CFLAGS="$CFLAGS -DOS_LINUX -DDSO_DLFCN"
+ supported_os="linux"
+ LDFLAGS="$LDFLAGS -ldl"
+ ;;
+ cygwin)
+ CFLAGS="$CFLAGS -DOS_CYGWIN -DDSO_DLFCN -DNO_SETSID"
+ supported_os="win32"
+ ;;
+ sysv)
+ CFLAGS="$CFLAGS -DOS_SYSV -DDSO_DLFCN"
+ LDFLAGS="$LDFLAGS -ldl"
+ ;;
+ sysv4)
+ CFLAGS="$CFLAGS -DOS_SYSV -DDSO_DLFCN -Kthread"
+ LDFLAGS="-Kthread $LDFLAGS -ldl"
+ ;;
+ freebsd4.?)
+ CFLAGS="$CFLAGS -DOS_FREEBSD -DDSO_DLFCN -D_THREAD_SAFE -pthread"
+ LDFLAGS="-pthread $LDFLAGS"
+ supported_os="freebsd"
+ ;;
+ *)
+ echo "$as_me:$LINENO: result: failed" >&5
+echo "${ECHO_T}failed" >&6
+ { { echo "$as_me:$LINENO: error: Unsupported operating system \"$host_os\"" >&5
+echo "$as_me: error: Unsupported operating system \"$host_os\"" >&2;}
+ { (exit 1); exit 1; }; }
+ ;;
+ esac
+ echo "$as_me:$LINENO: result: ok" >&5
+echo "${ECHO_T}ok" >&6
+
+
+if test "$supported_os" = "darwin"
+then
+ _prevdir=`/bin/pwd`
+ cd $JAVA_HOME
+ cd ..
+ cd Headers
+ CFLAGS="$CFLAGS -I`/bin/pwd -P`"
+ cd $_prevdir
+ unset _prevdir
+else
+ CFLAGS="$CFLAGS -I$JAVA_HOME/include -I$JAVA_HOME/include/$supported_os"
+fi
+
+if test "$GCC" = "yes"
+then
+ CFLAGS="$CFLAGS -Wall -Wstrict-prototypes"
+ echo "$as_me:$LINENO: result: gcc flags added" >&5
+echo "${ECHO_T}gcc flags added" >&6
+fi
+if test -z "$LDCMD"
+then
+ LDCMD="$CC"
+fi
+
+
+
+ printf "*** %s ***\n" "Writing output files" 1>&2
+
+
+ ac_config_files="$ac_config_files Makefile Makedefs native/Makefile"
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+ (set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n \
+ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+ ;;
+ esac;
+} |
+ sed '
+ t clear
+ : clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+ if test -w $cache_file; then
+ test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+ cat confcache >$cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[ ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[ ]*$//;
+}'
+fi
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+#
+# If the first sed substitution is executed (which looks for macros that
+# take arguments), then we branch to the quote section. Otherwise,
+# look for a macro that doesn't take arguments.
+cat >confdef2opt.sed <<\_ACEOF
+t clear
+: clear
+s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g
+t quote
+s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g
+t quote
+d
+: quote
+s,[ `~#$^&*(){}\\|;'"<>?],\\&,g
+s,\[,\\&,g
+s,\],\\&,g
+s,\$,$$,g
+p
+_ACEOF
+# We use echo to avoid assuming a particular line-breaking character.
+# The extra dot is to prevent the shell from consuming trailing
+# line-breaks from the sub-command output. A line-break within
+# single-quotes doesn't work because, if this script is created in a
+# platform that uses two characters for line-breaks (e.g., DOS), tr
+# would break.
+ac_LF_and_DOT=`echo; echo .`
+DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'`
+rm -f confdef2opt.sed
+
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_i=`echo "$ac_i" |
+ sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+ # 2. Add them.
+ ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+ ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+ set -o posix
+fi
+
+# Support unset when possible.
+if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+ LC_TELEPHONE LC_TIME
+do
+ if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then
+ eval $as_var=C; export $as_var
+ else
+ $as_unset $as_var
+ fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)$' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+ /^X\/\(\/\/\)$/{ s//\1/; q; }
+ /^X\/\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" || {
+ # Find who we are. Look in the path if we contain no path at all
+ # relative or not.
+ case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+ ;;
+ esac
+ # We did not find ourselves, most probably we were run as `sh COMMAND'
+ # in which case we are not to be found in the path.
+ if test "x$as_myself" = x; then
+ as_myself=$0
+ fi
+ if test ! -f "$as_myself"; then
+ { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ case $CONFIG_SHELL in
+ '')
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for as_base in sh bash ksh sh5; do
+ case $as_dir in
+ /*)
+ if ("$as_dir/$as_base" -c '
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
+ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+ CONFIG_SHELL=$as_dir/$as_base
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+ fi;;
+ esac
+ done
+done
+;;
+ esac
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line before each line; the second 'sed' does the real
+ # work. The second script uses 'N' to pair each line-number line
+ # with the numbered line, and appends trailing '-' during
+ # substitution so that $LINENO is not a special case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
+ sed '=' <$as_myself |
+ sed '
+ N
+ s,$,-,
+ : loop
+ s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+ t loop
+ s,-$,,
+ s,^['$as_cr_digits']*\n,,
+ ' >$as_me.lineno &&
+ chmod +x $as_me.lineno ||
+ { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensible to this).
+ . ./$as_me.lineno
+ # Exit status is that of the last command.
+ exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+ *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T=' ' ;;
+ *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+ *) ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+ # We could just check for DJGPP; but this test a) works b) is more generic
+ # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+ if test -f conf$$.exe; then
+ # Don't use ln at all; we don't have any links
+ as_ln_s='cp -p'
+ else
+ as_ln_s='ln -s'
+ fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling. Logging --version etc. is OK.
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by $as_me, which was
+generated by GNU Autoconf 2.57. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+ echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+ echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+ echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+ echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number, then exit
+ -q, --quiet do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+
+Configuration files:
+$config_files
+
+Report bugs to <bug-autoconf at gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+config.status
+configured by $0, generated by GNU Autoconf 2.57,
+ with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value. By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=*)
+ ac_option=`expr "x$1" : 'x\([^=]*\)='`
+ ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ -*)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ *) # This is not an option, so the user has probably given explicit
+ # arguments.
+ ac_option=$1
+ ac_need_defaults=false;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --vers* | -V )
+ echo "$ac_cs_version"; exit 0 ;;
+ --he | --h)
+ # Conflict between --help and --header
+ { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+ { (exit 1); exit 1; }; };;
+ --help | --hel | -h )
+ echo "$ac_cs_usage"; exit 0 ;;
+ --debug | --d* | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+ $ac_shift
+ CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+ ac_need_defaults=false;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+ { (exit 1); exit 1; }; } ;;
+
+ *) ac_config_targets="$ac_config_targets $1" ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+ echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+ exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+
+
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_config_target in $ac_config_targets
+do
+ case "$ac_config_target" in
+ # Handling of arguments.
+ "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ "Makedefs" ) CONFIG_FILES="$CONFIG_FILES Makedefs" ;;
+ "native/Makefile" ) CONFIG_FILES="$CONFIG_FILES native/Makefile" ;;
+ *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+ trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+ trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+ test -n "$tmp" && test -d "$tmp"
+} ||
+{
+ tmp=./confstat$$-$RANDOM
+ (umask 077 && mkdir $tmp)
+} ||
+{
+ echo "$me: cannot create a temporary directory in ." >&2
+ { (exit 1); exit 1; }
+}
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+ # Protect against being on the right side of a sed subst in config.status.
+ sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+ s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s, at SHELL@,$SHELL,;t t
+s, at PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s, at PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s, at PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s, at PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s, at PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s, at PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s, at exec_prefix@,$exec_prefix,;t t
+s, at prefix@,$prefix,;t t
+s, at program_transform_name@,$program_transform_name,;t t
+s, at bindir@,$bindir,;t t
+s, at sbindir@,$sbindir,;t t
+s, at libexecdir@,$libexecdir,;t t
+s, at datadir@,$datadir,;t t
+s, at sysconfdir@,$sysconfdir,;t t
+s, at sharedstatedir@,$sharedstatedir,;t t
+s, at localstatedir@,$localstatedir,;t t
+s, at libdir@,$libdir,;t t
+s, at includedir@,$includedir,;t t
+s, at oldincludedir@,$oldincludedir,;t t
+s, at infodir@,$infodir,;t t
+s, at mandir@,$mandir,;t t
+s, at build_alias@,$build_alias,;t t
+s, at host_alias@,$host_alias,;t t
+s, at target_alias@,$target_alias,;t t
+s, at DEFS@,$DEFS,;t t
+s, at ECHO_C@,$ECHO_C,;t t
+s, at ECHO_N@,$ECHO_N,;t t
+s, at ECHO_T@,$ECHO_T,;t t
+s, at LIBS@,$LIBS,;t t
+s, at build@,$build,;t t
+s, at build_cpu@,$build_cpu,;t t
+s, at build_vendor@,$build_vendor,;t t
+s, at build_os@,$build_os,;t t
+s, at host@,$host,;t t
+s, at host_cpu@,$host_cpu,;t t
+s, at host_vendor@,$host_vendor,;t t
+s, at host_os@,$host_os,;t t
+s, at CC@,$CC,;t t
+s, at CFLAGS@,$CFLAGS,;t t
+s, at LDFLAGS@,$LDFLAGS,;t t
+s, at CPPFLAGS@,$CPPFLAGS,;t t
+s, at ac_ct_CC@,$ac_ct_CC,;t t
+s, at EXEEXT@,$EXEEXT,;t t
+s, at OBJEXT@,$OBJEXT,;t t
+s, at RANLIB@,$RANLIB,;t t
+s, at ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
+s, at JAVA_HOME@,$JAVA_HOME,;t t
+s, at JAVAC@,$JAVAC,;t t
+s, at JAVAC_PATH@,$JAVAC_PATH,;t t
+s, at JAVACFLAGS@,$JAVACFLAGS,;t t
+s, at JAR@,$JAR,;t t
+s, at JAR_PATH@,$JAR_PATH,;t t
+s, at LDCMD@,$LDCMD,;t t
+s, at LIBOBJS@,$LIBOBJS,;t t
+s, at LTLIBOBJS@,$LTLIBOBJS,;t t
+CEOF
+
+_ACEOF
+
+ cat >>$CONFIG_STATUS <<\_ACEOF
+ # Split the substitutions into bite-sized pieces for seds with
+ # small command number limits, like on Digital OSF/1 and HP-UX.
+ ac_max_sed_lines=48
+ ac_sed_frag=1 # Number of current file.
+ ac_beg=1 # First line for current file.
+ ac_end=$ac_max_sed_lines # Line after last line for current file.
+ ac_more_lines=:
+ ac_sed_cmds=
+ while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+ else
+ sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+ fi
+ if test ! -s $tmp/subs.frag; then
+ ac_more_lines=false
+ else
+ # The purpose of the label and of the branching condition is to
+ # speed up the sed processing (if there are no `@' at all, there
+ # is no need to browse any of the substitutions).
+ # These are the two extra sed commands mentioned above.
+ (echo ':t
+ /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+ fi
+ ac_sed_frag=`expr $ac_sed_frag + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_lines`
+ fi
+ done
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+ fi
+fi # test -n "$CONFIG_FILES"
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case $ac_file in
+ - | *:- | *:-:* ) # input from stdin
+ cat >$tmp/stdin
+ ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ * ) ac_file_in=$ac_file.in ;;
+ esac
+
+ # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+ ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ { if $as_mkdir_p; then
+ mkdir -p "$ac_dir"
+ else
+ as_dir="$ac_dir"
+ as_dirs=
+ while test ! -d "$as_dir"; do
+ as_dirs="$as_dir $as_dirs"
+ as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ done
+ test ! -n "$as_dirs" || mkdir $as_dirs
+ fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+ { (exit 1); exit 1; }; }; }
+
+ ac_builddir=.
+
+if test "$ac_dir" != .; then
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+ ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+ .) # No --srcdir option. We are building in place.
+ ac_srcdir=.
+ if test -z "$ac_top_builddir"; then
+ ac_top_srcdir=.
+ else
+ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+ fi ;;
+ [\\/]* | ?:[\\/]* ) # Absolute path.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir ;;
+ *) # Relative path.
+ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
+# absolute.
+ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
+ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
+ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
+ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
+
+
+
+ if test x"$ac_file" != x-; then
+ { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+ rm -f "$ac_file"
+ fi
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ if test x"$ac_file" = x-; then
+ configure_input=
+ else
+ configure_input="$ac_file. "
+ fi
+ configure_input=$configure_input"Generated from `echo $ac_file_in |
+ sed 's,.*/,,'` by configure."
+
+ # First look for the input files in the build tree, otherwise in the
+ # src tree.
+ ac_file_inputs=`IFS=:
+ for f in $ac_file_in; do
+ case $f in
+ -) echo $tmp/stdin ;;
+ [\\/$]*)
+ # Absolute (can't be DOS-style, as IFS=:)
+ test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ echo $f;;
+ *) # Relative
+ if test -f "$f"; then
+ # Build tree
+ echo $f
+ elif test -f "$srcdir/$f"; then
+ # Source tree
+ echo $srcdir/$f
+ else
+ # /dev/null tree
+ { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ fi;;
+ esac
+ done` || { (exit 1); exit 1; }
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+ sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s, at configure_input@,$configure_input,;t t
+s, at srcdir@,$ac_srcdir,;t t
+s, at abs_srcdir@,$ac_abs_srcdir,;t t
+s, at top_srcdir@,$ac_top_srcdir,;t t
+s, at abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s, at builddir@,$ac_builddir,;t t
+s, at abs_builddir@,$ac_abs_builddir,;t t
+s, at top_builddir@,$ac_top_builddir,;t t
+s, at abs_top_builddir@,$ac_abs_top_builddir,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+ rm -f $tmp/stdin
+ if test x"$ac_file" != x-; then
+ mv $tmp/out $ac_file
+ else
+ cat $tmp/out
+ rm -f $tmp/out
+ fi
+
+done
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || { (exit 1); exit 1; }
+fi
+
+
+
+ printf "*** %s ***\n" "All done" 1>&2
+
+
+echo "$as_me:$LINENO: result: Now you can issue \"make\"" >&5
+echo "${ECHO_T}Now you can issue \"make\"" >&6
diff --git a/src/native/unix/configure.in b/src/native/unix/configure.in
new file mode 100644
index 0000000..c6f8420
--- /dev/null
+++ b/src/native/unix/configure.in
@@ -0,0 +1,140 @@
+dnl =========================================================================
+dnl
+dnl The Apache Software License, Version 1.1
+dnl
+dnl Copyright (c) 1999-2001 The Apache Software Foundation.
+dnl All rights reserved.
+dnl
+dnl =========================================================================
+dnl
+dnl Redistribution and use in source and binary forms, with or without modi-
+dnl fication, are permitted provided that the following conditions are met:
+dnl
+dnl 1. Redistributions of source code must retain the above copyright notice
+dnl notice, this list of conditions and the following disclaimer.
+dnl
+dnl 2. Redistributions in binary form must reproduce the above copyright
+dnl notice, this list of conditions and the following disclaimer in the
+dnl documentation and/or other materials provided with the distribution.
+dnl
+dnl 3. The end-user documentation included with the redistribution, if any,
+dnl must include the following acknowlegement:
+dnl
+dnl "This product includes software developed by the Apache Software
+dnl Foundation <http://www.apache.org/>."
+dnl
+dnl Alternately, this acknowlegement may appear in the software itself, if
+dnl and wherever such third-party acknowlegements normally appear.
+dnl
+dnl 4. The names "The Jakarta Project", "WebApp", and "Apache Software
+dnl Foundation" must not be used to endorse or promote products derived
+dnl from this software without prior written permission. For written
+dnl permission, please contact <apache at apache.org>.
+dnl
+dnl 5. Products derived from this software may not be called "Apache" nor may
+dnl "Apache" appear in their names without prior written permission of the
+dnl Apache Software Foundation.
+dnl
+dnl THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES
+dnl INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+dnl AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+dnl THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+dnl DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+dnl DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+dnl OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+dnl HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+dnl STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+dnl ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+dnl POSSIBILITY OF SUCH DAMAGE.
+dnl
+dnl =========================================================================
+dnl
+dnl This software consists of voluntary contributions made by many indivi-
+dnl duals on behalf of the Apache Software Foundation. For more information
+dnl on the Apache Software Foundation, please see <http://www.apache.org/>.
+dnl
+dnl =========================================================================
+
+dnl -------------------------------------------------------------------------
+dnl Author Pier Fumagalli <mailto:pier.fumagalli at eng.sun.com>
+dnl Version $Id: configure.in,v 1.2 2003/09/12 09:08:51 jfclere Exp $
+dnl -------------------------------------------------------------------------
+
+dnl -------------------------------------------------------------------------
+dnl Initialize AutoConf
+dnl -------------------------------------------------------------------------
+sinclude(./support/apfunctions.m4)dnl
+sinclude(./support/apjava.m4)dnl
+sinclude(./support/apsupport.m4)dnl
+AC_INIT(configure.in)
+AC_CONFIG_AUX_DIR(./support)
+
+dnl -------------------------------------------------------------------------
+dnl Check current host (forget about cross compilation) and validate it
+dnl against the cache (fail if the cache differs)
+dnl -------------------------------------------------------------------------
+AP_MSG_HEADER([Current host])
+AC_CANONICAL_HOST()
+AP_CANONICAL_HOST_CHECK()
+
+dnl -------------------------------------------------------------------------
+dnl Check C environment
+dnl -------------------------------------------------------------------------
+AP_MSG_HEADER([C-Language compilation tools])
+AC_PROG_CC()
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+
+dnl -------------------------------------------------------------------------
+dnl Check JAVA environment
+dnl -------------------------------------------------------------------------
+AP_MSG_HEADER([Java compilation tools])
+AP_JAVA()
+AP_PROG_JAVAC()
+AP_PROG_JAR()
+
+dnl -------------------------------------------------------------------------
+dnl Check if this host is supported
+dnl -------------------------------------------------------------------------
+AP_MSG_HEADER([Host support])
+AP_SUPPORTED_HOST()
+if test "$supported_os" = "darwin"
+then
+ _prevdir=`/bin/pwd`
+ cd $JAVA_HOME
+ cd ..
+ cd Headers
+ CFLAGS="$CFLAGS -I`/bin/pwd -P`"
+ cd $_prevdir
+ unset _prevdir
+else
+ CFLAGS="$CFLAGS -I$JAVA_HOME/include -I$JAVA_HOME/include/$supported_os"
+fi
+
+dnl -------------------------------------------------------------------------
+dnl Add gcc specific CFLAGS.
+dnl -------------------------------------------------------------------------
+if test "$GCC" = "yes"
+then
+ CFLAGS="$CFLAGS -Wall -Wstrict-prototypes"
+ AC_MSG_RESULT([gcc flags added])
+fi
+dnl -------------------------------------------------------------------------
+dnl Add gcc specific CFLAGS.
+dnl -------------------------------------------------------------------------
+if test -z "$LDCMD"
+then
+ LDCMD="$CC"
+fi
+AC_SUBST(LDCMD)
+
+dnl -------------------------------------------------------------------------
+dnl Random programs we need to compile locally
+dnl -------------------------------------------------------------------------
+AP_MSG_HEADER([Writing output files])
+AC_OUTPUT(Makefile Makedefs native/Makefile)
+
+dnl -------------------------------------------------------------------------
+dnl Done
+dnl -------------------------------------------------------------------------
+AP_MSG_HEADER([All done])
+AC_MSG_RESULT([Now you can issue "make"])
diff --git a/src/native/unix/native/Makefile.in b/src/native/unix/native/Makefile.in
new file mode 100644
index 0000000..93ea2b7
--- /dev/null
+++ b/src/native/unix/native/Makefile.in
@@ -0,0 +1,43 @@
+#
+# Copyright 2001-2004 The Apache Software Foundation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# @author Pier Fumagalli <mailto:pier.fumagalli at eng.sun.com>
+# @version $Id: Makefile.in,v 1.2 2004/02/09 15:55:21 jfclere Exp $
+
+include ../Makedefs
+
+OBJS = arguments.o \
+ debug.o \
+ dso-dlfcn.o \
+ dso-dyld.o \
+ help.o \
+ home.o \
+ java.o \
+ location.o \
+ replace.o \
+ signals.o
+
+all: jsvc libservice.a
+
+libservice.a: $(OBJS)
+ ar cr libservice.a $(OBJS)
+ $(RANLIB) libservice.a
+
+jsvc: jsvc-unix.o libservice.a
+ $(LDCMD) $(LDFLAGS) jsvc-unix.o libservice.a -o ../jsvc
+
+clean:
+ rm -f $(OBJS) ../jsvc jsvc-unix.o libservice.a
+
diff --git a/src/native/unix/native/Tomcat.sh b/src/native/unix/native/Tomcat.sh
new file mode 100755
index 0000000..c4333c7
--- /dev/null
+++ b/src/native/unix/native/Tomcat.sh
@@ -0,0 +1,77 @@
+#!/bin/sh
+##############################################################################
+#
+# Copyright 2001-2004 The Apache Software Foundation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+##############################################################################
+#
+# Small shell script to show how to start/stop Tomcat using jsvc
+# If you want to have Tomcat running on port 80 please modify the server.xml
+# file:
+#
+# <!-- Define a non-SSL HTTP/1.1 Connector on port 80 -->
+# <Connector className="org.apache.catalina.connector.http.HttpConnector"
+# port="80" minProcessors="5" maxProcessors="75"
+# enableLookups="true" redirectPort="8443"
+# acceptCount="10" debug="0" connectionTimeout="60000"/>
+#
+# This is for of Tomcat-4.1.x (Apache Tomcat/4.1)
+#
+# Adapt the following lines to your configuration
+JAVA_HOME=/usr/java/jdk1.3.1
+CATALINA_HOME=/home1/jakarta/jakarta-tomcat-4.1/build
+DAEMON_HOME=/home1/jakarta/jakarta-commons/daemon
+TOMCAT_USER=jakarta
+TMP_DIR=/var/tmp
+CATALINA_OPTS=
+CLASSPATH=\
+$JAVA_HOME/lib/tools.jar:\
+$DAEMON_HOME/dist/commons-daemon.jar:\
+$CATALINA_HOME/bin/bootstrap.jar
+
+case "$1" in
+ start)
+ #
+ # Start Tomcat
+ #
+ $DAEMON_HOME/src/native/unix/jsvc \
+ -user $TOMCAT_USER \
+ -home $JAVA_HOME \
+ -Dcatalina.home=$CATALINA_HOME \
+ -Djava.io.tmpdir=$TMP_DIR \
+ -outfile $CATALINA_HOME/logs/catalina.out \
+ -errfile '&1' \
+ $CATALINA_OPTS \
+ -cp $CLASSPATH \
+ org.apache.catalina.startup.BootstrapService
+ #
+ # To get a verbose JVM
+ #-verbose \
+ # To get a debug of jsvc.
+ #-debug \
+ ;;
+
+ stop)
+ #
+ # Stop Tomcat
+ #
+ PID=`cat /var/run/jsvc.pid`
+ kill $PID
+ ;;
+
+ *)
+ echo "Usage tomcat.sh start/stop"
+ exit 1;;
+esac
diff --git a/src/native/unix/native/Tomcat5.sh b/src/native/unix/native/Tomcat5.sh
new file mode 100755
index 0000000..87a4c49
--- /dev/null
+++ b/src/native/unix/native/Tomcat5.sh
@@ -0,0 +1,76 @@
+#!/bin/sh
+##############################################################################
+#
+# Copyright 2004 The Apache Software Foundation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##############################################################################
+#
+# Small shell script to show how to start/stop Tomcat using jsvc
+# If you want to have Tomcat running on port 80 please modify the server.xml
+# file:
+#
+# <!-- Define a non-SSL HTTP/1.1 Connector on port 80 -->
+# <Connector className="org.apache.catalina.connector.http.HttpConnector"
+# port="80" minProcessors="5" maxProcessors="75"
+# enableLookups="true" redirectPort="8443"
+# acceptCount="10" debug="0" connectionTimeout="60000"/>
+#
+# That is for Tomcat-5.0.x (Apache Tomcat/5.0)
+#
+# Adapt the following lines to your configuration
+JAVA_HOME=/usr/java/j2sdk1.4.2_03
+CATALINA_HOME=/home/tomcat5/jakarta-tomcat-5/build
+DAEMON_HOME=/home/tomcat5/jakarta-commons/daemon
+TOMCAT_USER=tomcat5
+TMP_DIR=/var/tmp
+CATALINA_OPTS=
+CLASSPATH=\
+$JAVA_HOME/lib/tools.jar:\
+$CATALINA_HOME/bin/commons-daemon.jar:\
+$CATALINA_HOME/bin/bootstrap.jar
+
+case "$1" in
+ start)
+ #
+ # Start Tomcat
+ #
+ $DAEMON_HOME/src/native/unix/jsvc \
+ -user $TOMCAT_USER \
+ -home $JAVA_HOME \
+ -Dcatalina.home=$CATALINA_HOME \
+ -Djava.io.tmpdir=$TMP_DIR \
+ -outfile $CATALINA_HOME/logs/catalina.out \
+ -errfile '&1' \
+ $CATALINA_OPTS \
+ -cp $CLASSPATH \
+ org.apache.catalina.startup.Bootstrap
+ #
+ # To get a verbose JVM
+ #-verbose \
+ # To get a debug of jsvc.
+ #-debug \
+ ;;
+
+ stop)
+ #
+ # Stop Tomcat
+ #
+ PID=`cat /var/run/jsvc.pid`
+ kill $PID
+ ;;
+
+ *)
+ echo "Usage tomcat.sh start/stop"
+ exit 1;;
+esac
diff --git a/src/native/unix/native/arguments.c b/src/native/unix/native/arguments.c
new file mode 100644
index 0000000..d7cbd9d
--- /dev/null
+++ b/src/native/unix/native/arguments.c
@@ -0,0 +1,262 @@
+/*
+ Copyright 2001-2004 The Apache Software Foundation.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+/* @version $Id: arguments.c,v 1.4 2004/02/09 15:55:21 jfclere Exp $ */
+#include "jsvc.h"
+
+/* Return the argument of a command line option */
+static char *optional(int argc, char *argv[], int argi) {
+
+ argi++;
+ if (argi>=argc) return(NULL);
+ if (argv[argi]==NULL) return(NULL);
+ if (argv[argi][0]=='-') return(NULL);
+ return(strdup(argv[argi]));
+}
+
+/* Parse command line arguments */
+static arg_data *parse(int argc, char *argv[]) {
+ arg_data *args=NULL;
+ char *temp=NULL;
+ char *cmnd=NULL;
+ int tlen=0;
+ int x=0;
+
+ /* Create the default command line arguments */
+ args=(arg_data *)malloc(sizeof(arg_data));
+ args->pidf="/var/run/jsvc.pid"; /* The default PID file */
+ args->user=NULL; /* No user switching by default */
+ args->dtch=true; /* Do detach from parent */
+ args->vers=false; /* Don't display version */
+ args->help=false; /* Don't display help */
+ args->chck=false; /* Don't do a check-only startup */
+ args->install=false; /* Don't install as a service */
+ args->remove=false; /* Don't remove the installed service */
+ args->service=false; /* Don't run as a service */
+ args->name=NULL; /* No VM version name */
+ args->home=NULL; /* No default JAVA_HOME */
+ args->onum=0; /* Zero arguments, but let's have some room */
+ args->opts=(char **)malloc(argc*sizeof(char *));
+ args->clas=NULL; /* No class predefined */
+ args->anum=0; /* Zero class specific arguments but make room*/
+ args->outfile="/dev/null"; /* Swallow by default */
+ args->errfile="/dev/null"; /* Swallow by default */
+ args->args=(char **)malloc(argc*sizeof(char *));
+
+ /* Set up the command name */
+ cmnd=strrchr(argv[0],'/');
+ if (cmnd==NULL) cmnd=argv[0];
+ else cmnd++;
+ log_prog=strdup(cmnd);
+
+ /* Iterate thru command line arguments */
+ for (x=1; x<argc; x++) {
+
+ if ((strcmp(argv[x],"-cp")==0)||(strcmp(argv[x],"-classpath")==0)) {
+ temp=optional(argc,argv,x++);
+ if (temp==NULL) {
+ log_error("Invalid classpath specified");
+ return(NULL);
+ }
+ tlen=strlen(temp)+20;
+ args->opts[args->onum]=(char *)malloc(tlen*sizeof(char));
+ sprintf(args->opts[args->onum],"-Djava.class.path=%s",temp);
+ args->onum++;
+
+ } else if (strcmp(argv[x],"-jvm")==0) {
+ args->name=optional(argc,argv,x++);
+ if (args->name==NULL) {
+ log_error("Invalid Java VM name specified");
+ return(NULL);
+ }
+
+ } else if (strcmp(argv[x],"-home")==0) {
+ args->home=optional(argc,argv,x++);
+ if (args->home==NULL) {
+ log_error("Invalid Java Home specified");
+ return(NULL);
+ }
+
+ } else if (strcmp(argv[x],"-user")==0) {
+ args->user=optional(argc,argv,x++);
+ if (args->user==NULL) {
+ log_error("Invalid user name specified");
+ return(NULL);
+ }
+
+ } else if (strcmp(argv[x],"-version")==0) {
+ args->vers=true;
+ args->dtch=false;
+
+ } else if ((strcmp(argv[x],"-?")==0)||(strcmp(argv[x],"-help")==0)
+ ||(strcmp(argv[x],"--help")==0)) {
+ args->help=true;
+ args->dtch=false;
+ return(args);
+
+ } else if (strcmp(argv[x],"-X")==0) {
+ log_error("Option -X currently unsupported");
+ log_error("Please use \"java -X\" to see your extra VM options");
+
+ } else if (strcmp(argv[x],"-debug")==0) {
+ log_debug_flag=true;
+
+ } else if (strcmp(argv[x],"-check")==0) {
+ args->chck=true;
+ args->dtch=false;
+
+ } else if (strcmp(argv[x],"-nodetach")==0) {
+ args->dtch=false;
+
+ } else if (strcmp(argv[x],"-service")==0) {
+ args->service=true;
+
+ } else if (strcmp(argv[x],"-install")==0) {
+ args->install=true;
+
+ } else if (strcmp(argv[x],"-remove")==0) {
+ args->remove=true;
+
+ } else if (strcmp(argv[x],"-pidfile")==0) {
+ args->pidf=optional(argc,argv,x++);
+ if (args->pidf==NULL) {
+ log_error("Invalid PID file specified");
+ return(NULL);
+ }
+
+ } else if(strcmp(argv[x],"-outfile") == 0) {
+ args->outfile=optional(argc, argv, x++);
+ if(args->outfile == NULL) {
+ log_error("Invalid Output File specified");
+ return(NULL);
+ }
+ } else if(strcmp(argv[x],"-errfile") == 0) {
+ args->errfile=optional(argc, argv, x++);
+ if(args->errfile == NULL) {
+ log_error("Invalid Error File specified");
+ return(NULL);
+ }
+ }else if (strstr(argv[x],"-verbose")==argv[x]) {
+ args->opts[args->onum++]=strdup(argv[x]);
+
+ } else if (strcmp(argv[x],"-D")==0) {
+ log_error("Parameter -D must be followed by <name>=<value>");
+ return(NULL);
+
+ } else if (strstr(argv[x],"-D")==argv[x]) {
+ temp=strchr(argv[x],'=');
+ if (temp==NULL) {
+ log_debug("Parameter -D must contain one '=' character");
+ }
+ if (temp==argv[x]+2) {
+ log_error("A property name must be specified before '='");
+ return(NULL);
+ }
+ args->opts[args->onum++]=strdup(argv[x]);
+
+ } else if (strstr(argv[x],"-X")==argv[x]) {
+ args->opts[args->onum++]=strdup(argv[x]);
+
+ } else if (strstr(argv[x],"-")==argv[x]) {
+ log_error("Invalid option %s",argv[x]);
+ return(NULL);
+
+ } else {
+ args->clas=strdup(argv[x]);
+ break;
+ }
+ }
+
+ if (args->clas==NULL && args->remove==false) {
+ log_error("No class specified");
+ return(NULL);
+ }
+
+ x++;
+ while (x<argc) args->args[args->anum++]=strdup(argv[x++]);
+
+ return(args);
+}
+static char *IsYesNo(bool par)
+{
+ switch (par) {
+ case false: return("No");
+ case true: return("Yes");
+ }
+ return ("[Error]");
+}
+static char *IsTrueFalse(bool par)
+{
+ switch (par) {
+ case false: return("False");
+ case true: return("True");
+ }
+ return ("[Error]");
+}
+static char *IsEnabledDisabled(bool par)
+{
+ switch (par) {
+ case true: return("Enabled");
+ case false: return("Disabled");
+ }
+ return ("[Error]");
+}
+
+/* Main entry point: parse command line arguments and dump them */
+arg_data *arguments(int argc, char *argv[]) {
+ arg_data *args=parse(argc,argv);
+ int x=0;
+
+ if (args==NULL) {
+ log_error("Cannot parse command line arguments");
+ return(NULL);
+ }
+
+ if (log_debug_flag==true) {
+ char *temp;
+
+ log_debug("+-- DUMPING PARSED COMMAND LINE ARGUMENTS --------------");
+
+ log_debug("| Detach: %s",IsTrueFalse(args->dtch));
+
+ log_debug("| Show Version: %s",IsYesNo(args->vers));
+
+ log_debug("| Show Help: %s",IsYesNo(args->help));
+
+ log_debug("| Check Only: %s",IsEnabledDisabled(args->chck));
+
+ log_debug("| Run as service: %s",IsYesNo(args->service));
+
+ log_debug("| Install service: %s",IsYesNo(args->install));
+
+ log_debug("| Remove service: %s",IsYesNo(args->remove));
+
+ log_debug("| JVM Name: \"%s\"",PRINT_NULL(args->name));
+ log_debug("| Java Home: \"%s\"",PRINT_NULL(args->home));
+ log_debug("| PID File: \"%s\"",PRINT_NULL(args->pidf));
+ log_debug("| User Name: \"%s\"",PRINT_NULL(args->user));
+
+ log_debug("| Extra Options: %d",args->onum);
+ for (x=0; x<args->onum; x++) log_debug("| \"%s\"",args->opts[x]);
+
+ log_debug("| Class Invoked: \"%s\"",PRINT_NULL(args->clas));
+
+ log_debug("| Class Arguments: %d",args->anum);
+ for (x=0; x<args->anum; x++)log_debug("| \"%s\"",args->args[x]);
+ log_debug("+-------------------------------------------------------");
+ }
+
+ return(args);
+}
diff --git a/src/native/unix/native/arguments.h b/src/native/unix/native/arguments.h
new file mode 100644
index 0000000..2dd68f1
--- /dev/null
+++ b/src/native/unix/native/arguments.h
@@ -0,0 +1,79 @@
+/*
+ Copyright 2001-2004 The Apache Software Foundation.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+/* @version $Id: arguments.h,v 1.2 2004/02/09 15:55:21 jfclere Exp $ */
+#ifndef __JSVC_ARGUMENTS_H__
+#define __JSVC_ARGUMENTS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * The structure holding all parsed command line options.
+ */
+typedef struct {
+ /** The name of the PID file. */
+ char *pidf;
+ /** The name of the user. */
+ char *user;
+ /** The name of the JVM to use. */
+ char *name;
+ /** The JDK or JRE installation path (JAVA_HOME). */
+ char *home;
+ /** Options used to invoke the JVM. */
+ char **opts;
+ /** Number of JVM options. */
+ int onum;
+ /** The name of the class to invoke. */
+ char *clas;
+ /** Command line arguments to the class. */
+ char **args;
+ /** Number of class command line arguments. */
+ int anum;
+ /** Wether to detach from parent process or not. */
+ bool dtch;
+ /** Wether to print the VM version number or not. */
+ bool vers;
+ /** Wether to display the help page or not. */
+ bool help;
+ /** Only check environment without running the service. */
+ bool chck;
+ /** Install as a service (win32) */
+ bool install;
+ /** Remove when installed as a service (win32) */
+ bool remove;
+ /** Run as a service (win32) */
+ bool service;
+ /** Destination for stdout */
+ char *outfile;
+ /** Destination for stderr */
+ char *errfile;
+} arg_data;
+
+/**
+ * Parse command line arguments.
+ *
+ * @param argc The number of command line arguments.
+ * @param argv Pointers to the different arguments.
+ * @return A pointer to a arg_data structure containing the parsed command
+ * line arguments, or NULL if an error was detected.
+ */
+arg_data *arguments(int argc, char *argv[]);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* ifndef __JSVC_ARGUMENTS_H__ */
diff --git a/src/native/unix/native/debug.c b/src/native/unix/native/debug.c
new file mode 100644
index 0000000..2ba44ed
--- /dev/null
+++ b/src/native/unix/native/debug.c
@@ -0,0 +1,53 @@
+/*
+ Copyright 2001-2004 The Apache Software Foundation.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+/* @version $Id: debug.c,v 1.2 2004/02/09 15:55:21 jfclere Exp $ */
+#include "jsvc.h"
+
+/* Wether debug is enabled or not */
+bool log_debug_flag = false;
+
+/* The name of the jsvc binary. */
+char *log_prog = "jsvc";
+
+/* Dump a debug message to stderr */
+void log_debug(const char *fmt, ...) {
+ va_list ap;
+
+ if (log_debug_flag==false) return;
+ if (fmt==NULL) return;
+
+ va_start(ap,fmt);
+ fprintf(stderr,"%s debug: ",log_prog);
+ vfprintf(stderr,fmt,ap);
+ fprintf(stderr,"\n");
+ fflush(stderr);
+ va_end(ap);
+}
+
+/* Dump an error message to stderr */
+void log_error(const char *fmt, ...) {
+ va_list ap;
+
+ if (fmt==NULL) return;
+
+ va_start(ap,fmt);
+ fprintf(stderr,"%s error: ",log_prog);
+ vfprintf(stderr,fmt,ap);
+ fprintf(stderr,"\n");
+ fflush(stderr);
+ va_end(ap);
+}
+
diff --git a/src/native/unix/native/debug.h b/src/native/unix/native/debug.h
new file mode 100644
index 0000000..6baf555
--- /dev/null
+++ b/src/native/unix/native/debug.h
@@ -0,0 +1,58 @@
+/*
+ Copyright 2001-2004 The Apache Software Foundation.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+/* @version $Id: debug.h,v 1.3 2004/02/09 15:55:21 jfclere Exp $ */
+#ifndef __JSVC_DEBUG_H__
+#define __JSVC_DEBUG_H__
+
+/**
+ * Wether debugging is enabled or not.
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern bool log_debug_flag;
+
+/**
+ * The name of the jsvc binary.
+ */
+extern char *log_prog;
+
+/**
+ * Helper macro to avoid NPEs in printf.
+ */
+#define PRINT_NULL(x) ((x) == NULL ? "null" : (x))
+
+/**
+ * Dump a debug message.
+ *
+ * @param fmt The printf style message format.
+ * @param ... Any optional parameter for the message.
+ */
+void log_debug(const char *fmt, ...);
+
+/**
+ * Dump an error message.
+ *
+ * @param fmt The printf style message format.
+ * @param ... Any optional parameter for the message.
+ */
+void log_error(const char *fmt, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ifndef __JSVC_DEBUG_H__ */
diff --git a/src/native/unix/native/dso-dlfcn.c b/src/native/unix/native/dso-dlfcn.c
new file mode 100644
index 0000000..9611a45
--- /dev/null
+++ b/src/native/unix/native/dso-dlfcn.c
@@ -0,0 +1,55 @@
+/*
+ Copyright 2001-2004 The Apache Software Foundation.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+/* @version $Id: dso-dlfcn.c,v 1.2 2004/02/09 15:55:21 jfclere Exp $ */
+#include "jsvc.h"
+
+#ifdef DSO_DLFCN
+
+#include <dlfcn.h>
+
+#ifdef OS_LINUX
+bool ld_library_path_set=false;
+#endif /* ifdef OS_LINUX */
+
+/* Initialize all DSO stuff */
+bool dso_init() {
+ return(true);
+}
+
+/* Attempt to link a library from a specified filename */
+dso_handle dso_link(const char *path) {
+ log_debug("Attemtping to load library %s",path);
+
+ return((void *)dlopen(path,RTLD_GLOBAL|RTLD_NOW));
+}
+
+/* Attempt to unload a library */
+bool dso_unlink(dso_handle libr) {
+ if (dlclose(libr)==0) return(true);
+ else return(false);
+}
+
+/* Get the address for a specifed symbol */
+void *dso_symbol(dso_handle hdl, const char *nam) {
+ return(dlsym(hdl,nam));
+}
+
+/* Return the error message from dlopen */
+char *dso_error() {
+ return(dlerror());
+}
+
+#endif /* ifdef DSO_DLFCN */
diff --git a/src/native/unix/native/dso-dyld.c b/src/native/unix/native/dso-dyld.c
new file mode 100644
index 0000000..2dfcef5
--- /dev/null
+++ b/src/native/unix/native/dso-dyld.c
@@ -0,0 +1,131 @@
+/*
+ Copyright 2001-2004 The Apache Software Foundation.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+/* @version $Id: dso-dyld.c,v 1.2 2004/02/09 15:55:21 jfclere Exp $ */
+#include "jsvc.h"
+
+#ifdef DSO_DYLD
+
+#include <mach-o/dyld.h>
+
+/* Print an error message and abort all if a specified symbol wasn't found */
+static void nosymbol(const char *s) {
+ log_error("Cannot find symbol '%s' in library",s);
+ abort();
+}
+
+/* We found two symbols for the same name in two different modules */
+static NSModule multiple(NSSymbol s, NSModule om, NSModule nm) {
+ NSModule ret=nm;
+
+ log_debug("Symbol \"%s\" found in modules \"%s\" and \"%s\" (using %s)",
+ NSNameOfSymbol(s), NSNameOfModule(om), NSNameOfModule(nm),
+ NSNameOfModule(ret));
+
+ return(ret);
+}
+
+/* We got an error while linking a module, and if it's not a warning we have
+ to abort the whole program */
+static void linkedit(NSLinkEditErrors category, int number, const char *file,
+ const char *message) {
+ log_error("Errors during link edit of file \"%s\" (error=%d): %s", file,
+ number,message);
+ /* Check if this error was only a warning */
+ if (category!=NSLinkEditWarningError) {
+ log_error("Cannot continue");
+ abort();
+ }
+}
+
+/* Initialize all DSO stuff */
+bool dso_init() {
+ NSLinkEditErrorHandlers h;
+
+ h.undefined=nosymbol;
+ h.multiple=multiple;
+ h.linkEdit=linkedit;
+
+ NSInstallLinkEditErrorHandlers(&h);
+ return(true);
+}
+
+/* Attempt to link a library from a specified filename */
+dso_handle dso_link(const char *path) {
+ /* We need to load the library publically as NSModuleFileImage is not
+ yet implemented (at least for non MH_BUNDLE libraries */
+ if (NSAddLibrary(path)!=TRUE) return(NULL);
+ /* We need to return a non-null value, even if it has no meaning. One day
+ this whole crap will be fixed */
+ return((void *)!NULL);
+}
+
+/* Attempt to unload a library */
+bool dso_unlink(dso_handle libr) {
+ /* Check the handle */
+ if (libr==NULL) {
+ log_error("Attempting to unload a module without handle");
+ return(false);
+ }
+
+ /* We don't have a module, so, we don't really have to do anything */
+ return(true);
+}
+
+/* Get the address for a specifed symbol */
+void *dso_symbol(dso_handle hdl, const char *nam) {
+ NSSymbol sym=NULL;
+ NSModule mod=NULL;
+ char *und=NULL;
+ void *add=NULL;
+ int x=0;
+
+ /* Check parameters */
+ if (hdl==NULL) {
+ log_error("Invalid library handler specified");
+ return(NULL);
+ }
+
+ if (nam==NULL) {
+ log_error("Invalid symbol name specified");
+ return(NULL);
+ }
+
+ /* Process the correct name (add a _ before the name) */
+ while (nam[x]!='\0') x++;
+ und=(char*)malloc(sizeof(char)*(x+2));
+ while(x>=0) und[x+1]=nam[x--];
+ und[0]='_';
+
+ /* Find the symbol */
+ sym=NSLookupAndBindSymbol(und);
+ free(und);
+ if (sym==NULL) return(NULL);
+
+ /* Dump some debugging output since this part is shaky */
+ mod=NSModuleForSymbol(sym);
+ add=NSAddressOfSymbol(sym);
+ log_debug("Symbol \"%s\" found in module \"%s\" at address \"0x%08X\"",
+ NSNameOfSymbol(sym),NSNameOfModule(mod),add);
+
+ /* We want to return the address of the symbol */
+ return(add);
+}
+/* Return the error message from dlopen: Well we already print it */
+char *dso_error() {
+ return("no additional message");
+}
+
+#endif /* ifdef DSO_DYLD */
diff --git a/src/native/unix/native/dso.h b/src/native/unix/native/dso.h
new file mode 100644
index 0000000..f9b330d
--- /dev/null
+++ b/src/native/unix/native/dso.h
@@ -0,0 +1,27 @@
+/*
+ Copyright 2001-2004 The Apache Software Foundation.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+/* @version $Id: dso.h,v 1.2 2004/02/09 15:55:21 jfclere Exp $ */
+#include "jsvc.h"
+
+/**
+ * A library handle represents a unique pointer to its location in memory.
+ */
+typedef void *dso_handle;
+
+bool dso_init(void);
+dso_handle dso_link(const char *pth);
+bool dso_unlink(dso_handle lib);
+void *dso_symbol(dso_handle lib, const char *nam);
diff --git a/src/native/unix/native/help.c b/src/native/unix/native/help.c
new file mode 100644
index 0000000..f2c145b
--- /dev/null
+++ b/src/native/unix/native/help.c
@@ -0,0 +1,83 @@
+/*
+ Copyright 2001-2004 The Apache Software Foundation.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+/* @version $Id: help.c,v 1.4 2004/02/09 15:55:21 jfclere Exp $ */
+#include "jsvc.h"
+
+void help(home_data *data) {
+ int x;
+
+ printf("Usage: %s [-options] class [args...]\n",log_prog);
+ printf("\n");
+ printf("Where options include:\n");
+ printf("\n");
+
+ printf(" -jvm <JVM name>\n");
+ printf(" use a specific Java Virtual Machine. Available JVMs:\n");
+ printf(" ");
+ for (x=0; x<data->jnum; x++) {
+ printf(" '%s'",PRINT_NULL(data->jvms[x]->name));
+ }
+ printf("\n");
+
+ printf(" -cp / -classpath <directories and zip/jar files>\n");
+ printf(" set search path for service classes and resouces\n");
+
+ printf(" -home <directory>\n");
+ printf(" set the path of your JDK or JRE installation (or set\n");
+ printf(" the JAVA_HOME environment variable)\n");
+
+ printf(" -version\n");
+ printf(" show the current Java environment version (to check\n");
+ printf(" correctness of -home and -jvm. Implies -nodetach)\n");
+
+ printf(" -help / -?\n");
+ printf(" show this help page (implies -nodetach)\n");
+
+ printf(" -nodetach\n");
+ printf(" don't detach from parent process and become a daemon\n");
+
+ printf(" -debug\n");
+ printf(" verbosely print debugging information\n");
+
+ printf(" -check\n");
+ printf(" only check service (implies -nodetach)\n");
+
+ printf(" -user\n");
+ printf(" user used to run the daemon (defaults to current user)\n");
+
+ printf(" -verbose[:class|gc|jni]\n");
+ printf(" enable verbose output\n");
+
+ printf(" -outfile </full/path/to/file>\n");
+ printf(" Location for output from stdout (defaults to /dev/null)\n");
+ printf(" Use the value '&2' to simulate '1>&2'\n");
+
+ printf(" -errfile </full/path/to/file>\n");
+ printf(" Location for output from stderr (defaults to /dev/null)\n");
+ printf(" Use the value '&1' to simulate '2>&1'\n");
+
+ printf(" -pidfile </full/path/to/file>\n");
+ printf(" Location for output from the file containing the pid of jsvc\n");
+ printf(" (defaults to /var/run/jsvc.pid)\n");
+
+ printf(" -D<name>=<value>\n");
+ printf(" set a Java system property\n");
+
+ printf(" -X<option>\n");
+ printf(" set Virtual Machine specific option\n");
+
+ printf("\n");
+}
diff --git a/src/native/unix/native/help.h b/src/native/unix/native/help.h
new file mode 100644
index 0000000..b765983
--- /dev/null
+++ b/src/native/unix/native/help.h
@@ -0,0 +1,17 @@
+/*
+ Copyright 2001-2004 The Apache Software Foundation.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+/* @version $Id: help.h,v 1.2 2004/02/09 15:55:21 jfclere Exp $ */
+void help(home_data *data);
diff --git a/src/native/unix/native/home.c b/src/native/unix/native/home.c
new file mode 100644
index 0000000..596519c
--- /dev/null
+++ b/src/native/unix/native/home.c
@@ -0,0 +1,243 @@
+/*
+ Copyright 2001-2004 The Apache Software Foundation.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+/* @version $Id: home.c,v 1.7 2004/02/09 15:55:21 jfclere Exp $ */
+#include "jsvc.h"
+
+/* Check if a path is a directory */
+static bool checkdir(char *path) {
+ struct stat home;
+
+ if (path==NULL) return(false);
+ if (stat(path,&home)!=0) return(false);
+ if (S_ISDIR(home.st_mode)) return(true);
+ return(false);
+}
+
+/* Check if a path is a file */
+static bool checkfile(char *path) {
+ struct stat home;
+
+ if (path==NULL) return(false);
+ if (stat(path,&home)!=0) return(false);
+ if (S_ISREG(home.st_mode)) return(true);
+ return(false);
+}
+
+/* Parse a VM configuration file */
+static bool parse(home_data *data) {
+ FILE *cfgf=fopen(data->cfgf,"r");
+ char *ret=NULL, *sp;
+ char buf[1024];
+
+ if (cfgf==NULL) {
+ log_debug("Can't open %s\n",data->cfgf);
+ return(false);
+ }
+
+ data->jvms=(home_jvm **)malloc(256*sizeof(home_jvm *));
+
+ while((ret=fgets(buf,1024,cfgf))!=NULL) {
+ char *tmp=strchr(ret,'#');
+ int pos;
+
+ /* Clear the string at the first occurrence of '#' */
+ if (tmp!=NULL) tmp[0]='\0';
+
+ /* Trim the string (including leading '-' chars */
+ while((ret[0]==' ')||(ret[0]=='\t')||(ret[0]=='-')) ret++;
+ pos=strlen(ret);
+ while(pos>=0) {
+ if ((ret[pos]=='\r')||(ret[pos]=='\n')||(ret[pos]=='\t')||
+ (ret[pos]=='\0')||(ret[pos]==' ')) {
+ ret[pos--]='\0';
+ } else break;
+ }
+ /* Format changed for 1.4 JVMs */
+ sp = strchr(ret, ' ');
+ if(sp != NULL)
+ *sp = '\0';
+
+ /* Did we find something significant? */
+ if (strlen(ret)>0) {
+ char *libf=NULL;
+ int x=0;
+
+ log_debug("Found VM %s definition in configuration",ret);
+ while(location_jvm_configured[x]!=NULL) {
+ char *orig=location_jvm_configured[x];
+ char temp[1024];
+ char repl[1024];
+ int k;
+
+ k=replace(temp,1024,orig,"$JAVA_HOME",data->path);
+ if (k!=0) {
+ log_error("Can't replace home in VM library (%d)",k);
+ return(false);
+ }
+ k=replace(repl,1024,temp,"$VM_NAME",ret);
+ if (k!=0) {
+ log_error("Can't replace name in VM library (%d)",k);
+ return(false);
+ }
+
+ log_debug("Checking library %s",repl);
+ if (checkfile(repl)) {
+ libf=strdup(repl);
+ break;
+ }
+ x++;
+ }
+
+ if (libf==NULL) {
+ log_debug("Cannot locate library for VM %s (skipping)",ret);
+ } else {
+ data->jvms[data->jnum]=(home_jvm *)malloc(sizeof(home_jvm));
+ data->jvms[data->jnum]->name=strdup(ret);
+ data->jvms[data->jnum]->libr=libf;
+ data->jnum++;
+ data->jvms[data->jnum]=NULL;
+ }
+ }
+ }
+ return(true);
+}
+
+/* Build a Java Home structure for a path */
+static home_data *build(char *path) {
+ home_data *data=NULL;
+ char *cfgf=NULL;
+ char buf[1024];
+ int x=0;
+ int k=0;
+
+ if (path==NULL) return(NULL);
+
+ log_debug("Attempting to locate Java Home in %s",path);
+ if (checkdir(path)==false) {
+ log_debug("Path %s is not a directory",path);
+ return(NULL);
+ }
+
+ while(location_jvm_cfg[x]!=NULL) {
+ if ((k=replace(buf,1024,location_jvm_cfg[x],"$JAVA_HOME",path))!=0) {
+ log_error("Error replacing values for jvm.cfg (%d)",k);
+ return(NULL);
+ }
+ log_debug("Attempting to locate VM configuration file %s",buf);
+ if(checkfile(buf)==true) {
+ log_debug("Found VM configuration file at %s",buf);
+ cfgf=strdup(buf);
+ break;
+ }
+ x++;
+ }
+
+ data=(home_data *)malloc(sizeof(home_data));
+ data->path=strdup(path);
+ data->cfgf=cfgf;
+ data->jvms=NULL;
+ data->jnum=0;
+
+ /* We don't have a jvm.cfg configuration file, so all we have to do is
+ trying to locate the "default" Java Virtual Machine library */
+ if (cfgf==NULL) {
+ log_debug("VM configuration file not found");
+ x=0;
+ while(location_jvm_default[x]!=NULL) {
+ char *libr=location_jvm_default[x];
+
+ if ((k=replace(buf,1024,libr,"$JAVA_HOME",path))!=0) {
+ log_error("Error replacing values for JVM library (%d)",k);
+ return(NULL);
+ }
+ log_debug("Attempting to locate VM library %s",buf);
+ if (checkfile(buf)==true) {
+ data->jvms=(home_jvm **)malloc(2*sizeof(home_jvm *));
+ data->jvms[0]=(home_jvm *)malloc(sizeof(home_jvm));
+ data->jvms[0]->name=NULL;
+ data->jvms[0]->libr=strdup(buf);
+ data->jvms[1]=NULL;
+ data->jnum=1;
+ return(data);
+ }
+ x++;
+ }
+
+ return(data);
+ }
+
+ /* If we got here, we most definitely found a jvm.cfg file */
+ if (parse(data)==false) {
+ log_error("Cannot parse VM configuration file %s",data->cfgf);
+ }
+
+ return(data);
+}
+
+/* Find the Java Home */
+static home_data *find(char *path) {
+ home_data *data=NULL;
+ int x=0;
+
+ if (path==NULL) {
+ log_debug("Home not specified on command line, using environment");
+ path=getenv("JAVA_HOME");
+ }
+
+ if (path==NULL) {
+ log_debug("Home not on command line or in environment, searching");
+ while (location_home[x]!=NULL) {
+ if ((data=build(location_home[x]))!=NULL) {
+ log_debug("Java Home located in %s",data->path);
+ return(data);
+ }
+ x++;
+ }
+ } else {
+ if ((data=build(path))!=NULL) {
+ log_debug("Java Home located in %s",data->path);
+ return(data);
+ }
+ }
+
+ return(NULL);
+}
+
+/* Main entry point: locate home and dump structure */
+home_data *home(char *path) {
+ home_data *data=find(path);
+ int x=0;
+
+ if (data==NULL) {
+ log_error("Cannot locate Java Home");
+ return(NULL);
+ }
+
+ if (log_debug_flag==true) {
+ log_debug("+-- DUMPING JAVA HOME STRUCTURE ------------------------");
+ log_debug("| Java Home: \"%s\"",PRINT_NULL(data->path));
+ log_debug("| Java VM Config.: \"%s\"",PRINT_NULL(data->cfgf));
+ log_debug("| Found JVMs: %d",data->jnum);
+ for (x=0; x<data->jnum; x++) {
+ home_jvm *jvm=data->jvms[x];
+ log_debug("| JVM Name: \"%s\"",PRINT_NULL(jvm->name));
+ log_debug("| \"%s\"",PRINT_NULL(jvm->libr));
+ }
+ log_debug("+-------------------------------------------------------");
+ }
+
+ return(data);
+}
diff --git a/src/native/unix/native/home.h b/src/native/unix/native/home.h
new file mode 100644
index 0000000..d4d6f56
--- /dev/null
+++ b/src/native/unix/native/home.h
@@ -0,0 +1,44 @@
+/*
+ Copyright 2001-2004 The Apache Software Foundation.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+/* @version $Id: home.h,v 1.2 2004/02/09 15:55:21 jfclere Exp $ */
+#ifndef __JSVC_HOME_H__
+#define __JSVC_HOME_H__
+
+typedef struct home_jvm home_jvm;
+typedef struct home_data home_data;
+
+struct home_jvm {
+ char *name;
+ char *libr;
+};
+
+struct home_data {
+ char *path;
+ char *cfgf;
+ home_jvm **jvms;
+ int jnum;
+};
+
+/**
+ * Attempt to locate a Java Home directory and build its structure.
+ *
+ * @param path The java home path specified on the command line.
+ * @return A home_data structure containing all informations related to
+ * the Java environment, or NULL if no home was found.
+ */
+home_data *home(char *path);
+
+#endif /* ifndef __JSVC_HOME_H__ */
diff --git a/src/native/unix/native/java.c b/src/native/unix/native/java.c
new file mode 100644
index 0000000..f00b458
--- /dev/null
+++ b/src/native/unix/native/java.c
@@ -0,0 +1,437 @@
+/*
+ Copyright 2001-2004 The Apache Software Foundation.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+/* @version $Id: java.c,v 1.3 2004/02/09 15:55:21 jfclere Exp $ */
+#include "jsvc.h"
+
+#ifdef OS_CYGWIN
+typedef long long __int64;
+#endif
+#include <jni.h>
+
+#ifdef CHARSET_EBCDIC
+#ifdef OSD_POSIX
+#include <ascii_ebcdic.h>
+#define jsvc_xlate_to_ascii(b) _e2a(b)
+#define jsvc_xlate_from_ascii(b) _a2e(b)
+#endif
+#else
+#define jsvc_xlate_to_ascii(b) /* NOOP */
+#define jsvc_xlate_from_ascii(b) /* NOOP */
+#endif
+
+static JavaVM *jvm=NULL;
+static JNIEnv *env=NULL;
+static jclass cls=NULL;
+
+#define FALSE 0
+#define TRUE !FALSE
+
+static void shutdown(JNIEnv *env, jobject source, jboolean reload) {
+ log_debug("Shutdown requested (reload is %d)",reload);
+ if (reload==TRUE) main_reload();
+ else main_shutdown();
+}
+
+char *java_library(arg_data *args, home_data *data) {
+ char *libf=NULL;
+
+ /* Did we find ANY virtual machine? */
+ if (data->jnum==0) {
+ log_error("Cannot find any VM in Java Home %s",data->path);
+ return(false);
+ }
+
+ /* Select the VM */
+ if (args->name==NULL) {
+ libf=data->jvms[0]->libr;
+ log_debug("Using default JVM in %s",libf);
+ } else {
+ int x;
+ for (x=0; x<data->jnum; x++) {
+ if (data->jvms[x]->name==NULL) continue;
+ if (strcmp(args->name,data->jvms[x]->name)==0) {
+ libf=data->jvms[x]->libr;
+ log_debug("Using specific JVM in %s",libf);
+ break;
+ }
+ }
+ if (libf==NULL) {
+ log_error("Invalid JVM name specified %s",args->name);
+ return(NULL);
+ }
+ }
+ return(libf);
+}
+
+/* Initialize the JVM and its environment, loading libraries and all */
+bool java_init(arg_data *args, home_data *data) {
+#ifdef OS_DARWIN
+ dso_handle apph=NULL;
+ char appf[1024];
+#endif /* ifdef OS_DARWIN */
+ jint (*symb)(JavaVM **, JNIEnv **, JavaVMInitArgs *);
+ JNINativeMethod nativemethod;
+ JavaVMOption *opt=NULL;
+ dso_handle libh=NULL;
+ JavaVMInitArgs arg;
+ char *libf=NULL;
+ jint ret;
+ int x;
+ char loaderclass[]=LOADER;
+ char shutdownclass[]="shutdown";
+ char shutdownparams[]="(Z)V";
+
+ /* Decide WHAT virtual machine we need to use */
+ libf=java_library(args,data);
+ if (libf==NULL) {
+ log_error("Cannot locate JVM library file");
+ return(false);
+ }
+
+ /* Initialize the DSO library */
+ if (dso_init()!=true) {
+ log_error("Cannot initialize the dynamic library loader");
+ return(false);
+ }
+
+ /* Load the JVM library */
+ libh=dso_link(libf);
+ if (libh==NULL) {
+ log_error("Cannot dynamically link to %s",libf);
+ log_error("%s",dso_error());
+ return(false);
+ }
+ log_debug("JVM library %s loaded",libf);
+
+#ifdef OS_DARWIN
+ /* MacOS/X actually has two libraries, one with the REAL vm, and one for
+ the VM startup. The first one (libappshell.dyld) contains CreateVM */
+ if (replace(appf,1024,"$JAVA_HOME/../Libraries/libappshell.dylib",
+ "$JAVA_HOME",data->path)!=0) {
+ log_error("Cannot replace values in loader library");
+ return(false);
+ }
+ apph=dso_link(appf);
+ if (apph==NULL) {
+ log_error("Cannot load required shell library %s",appf);
+ return(false);
+ }
+ log_debug("Shell library %s loaded",appf);
+#endif /* ifdef OS_DARWIN */
+ symb=dso_symbol(libh,"JNI_CreateJavaVM");
+ if (symb==NULL) {
+#ifdef OS_DARWIN
+ symb=dso_symbol(apph,"JNI_CreateJavaVM");
+ if (symb==NULL) {
+#endif /* ifdef OS_DARWIN */
+ log_error("Cannot find JVM library entry point");
+ return(false);
+#ifdef OS_DARWIN
+ }
+#endif /* ifdef OS_DARWIN */
+ }
+ log_debug("JVM library entry point found (0x%08X)",symb);
+
+ /* Prepare the VM initialization arguments */
+ arg.version=JNI_VERSION_1_2;
+ arg.ignoreUnrecognized=FALSE;
+ arg.nOptions=args->onum;
+ if (arg.nOptions==0) {
+ arg.options=NULL;
+ } else {
+ opt=(JavaVMOption *)malloc(arg.nOptions*sizeof(JavaVMOption));
+ for (x=0; x<args->onum; x++) {
+ opt[x].optionString=strdup(args->opts[x]);
+ jsvc_xlate_to_ascii(opt[x].optionString);
+ opt[x].extraInfo=NULL;
+ }
+ arg.options=opt;
+ }
+
+ /* Do some debugging */
+ if (log_debug_flag==true) {
+ log_debug("+-- DUMPING JAVA VM CREATION ARGUMENTS -----------------");
+ log_debug("| Version: %x",arg.version);
+ log_debug("| Ignore Unrecognized Arguments: %s",
+ arg.ignoreUnrecognized==TRUE?"True":"False");
+ log_debug("| Extra options: %d",arg.nOptions);
+
+ for (x=0; x<args->onum; x++) {
+ jsvc_xlate_from_ascii(opt[x].optionString);
+ log_debug("| \"%s\" (0x%08x)",opt[x].optionString,
+ opt[x].extraInfo);
+ jsvc_xlate_to_ascii(opt[x].optionString);
+ }
+ log_debug("+-------------------------------------------------------");
+ }
+
+ /* And finally create the Java VM */
+ ret=(*symb)(&jvm, &env, &arg);
+ if (ret!=0) {
+ log_error("Cannot create Java VM");
+ return(false);
+ }
+ log_debug("Java VM created successfully");
+
+ jsvc_xlate_to_ascii(loaderclass);
+ cls=(*env)->FindClass(env,loaderclass);
+ jsvc_xlate_from_ascii(loaderclass);
+ if (cls==NULL) {
+ log_error("Cannot find daemon loader %s",loaderclass);
+ return(false);
+ }
+ log_debug("Class %s found",loaderclass);
+
+ jsvc_xlate_to_ascii(shutdownclass);
+ nativemethod.name=shutdownclass;
+ jsvc_xlate_to_ascii(shutdownparams);
+ nativemethod.signature=shutdownparams;
+ nativemethod.fnPtr=shutdown;
+ if((*env)->RegisterNatives(env,cls,&nativemethod,1)!=0) {
+ log_error("Cannot register native methods");
+ return(false);
+ }
+ log_debug("Native methods registered");
+
+ return(true);
+}
+
+/* Destroy the Java VM */
+bool JVM_destroy(int exit) {
+ jclass system=NULL;
+ jmethodID method;
+ char System[]="java/lang/System";
+ char exitclass[]="exit";
+ char exitparams[]="(I)V";
+
+ jsvc_xlate_to_ascii(System);
+ system=(*env)->FindClass(env,System);
+ jsvc_xlate_from_ascii(System);
+ if (system==NULL) {
+ log_error("Cannot find class %s",System);
+ return(false);
+ }
+
+ jsvc_xlate_to_ascii(exitclass);
+ jsvc_xlate_to_ascii(exitparams);
+ method=(*env)->GetStaticMethodID(env,system,exitclass,exitparams);
+ if (method==NULL) {
+ log_error("Cannot found \"System.exit(int)\" entry point");
+ return(false);
+ }
+
+ log_debug("Calling System.exit(%d)",exit);
+ (*env)->CallStaticVoidMethod(env,system,method,(jint)exit);
+
+ /* We shouldn't get here, but just in case... */
+ log_debug("Destroying the Java VM");
+ if ((*jvm)->DestroyJavaVM(jvm)!=0) return(false);
+ log_debug("Java VM destroyed");
+ return(true);
+}
+
+/* Call the load method in our DaemonLoader class */
+bool java_load(arg_data *args) {
+ jclass stringClass=NULL;
+ jstring className=NULL;
+ jstring currentArgument=NULL;
+ jobjectArray stringArray=NULL;
+ jmethodID method=NULL;
+ jboolean ret=FALSE;
+ int x;
+ char lang[]="java/lang/String";
+ char load[]="load";
+ char loadparams[]="(Ljava/lang/String;[Ljava/lang/String;)Z";
+
+ jsvc_xlate_to_ascii(args->clas);
+ className=(*env)->NewStringUTF(env,args->clas);
+ jsvc_xlate_from_ascii(args->clas);
+ if (className==NULL) {
+ log_error("Cannot create string for class name");
+ return(false);
+ }
+
+ jsvc_xlate_to_ascii(lang);
+ stringClass=(*env)->FindClass(env,lang);
+ jsvc_xlate_from_ascii(lang);
+ if (stringClass==NULL) {
+ log_error("Cannot find class java/lang/String");
+ return(false);
+ }
+
+ stringArray=(*env)->NewObjectArray(env,args->anum,stringClass,NULL);
+ if (stringArray==NULL) {
+ log_error("Cannot create arguments array");
+ return(false);
+ }
+
+ for (x=0; x<args->anum; x++) {
+ jsvc_xlate_to_ascii(args->args[x]);
+ currentArgument=(*env)->NewStringUTF(env,args->args[x]);
+ jsvc_xlate_from_ascii(args->args[x]);
+ if (currentArgument==NULL) {
+ log_error("Cannot create string for argument %s",args->args[x]);
+ return(false);
+ }
+ (*env)->SetObjectArrayElement(env,stringArray,x,currentArgument);
+ }
+
+ jsvc_xlate_to_ascii(load);
+ jsvc_xlate_to_ascii(loadparams);
+ method=(*env)->GetStaticMethodID(env,cls,load,loadparams);
+ if (method==NULL) {
+ log_error("Cannot found Daemon Loader \"load\" entry point");
+ return(false);
+ }
+
+ ret=(*env)->CallStaticBooleanMethod(env,cls,method,className,stringArray);
+ if (ret==FALSE) {
+ log_error("Cannot load daemon");
+ return(false);
+ }
+
+ log_debug("Daemon loaded successfully");
+ return(true);
+}
+
+/* Call the start method in our daemon loader */
+bool java_start(void) {
+ jmethodID method;
+ jboolean ret;
+ char start[]="start";
+ char startparams[]="()Z";
+
+ jsvc_xlate_to_ascii(start);
+ jsvc_xlate_to_ascii(startparams);
+ method=(*env)->GetStaticMethodID(env,cls,start,startparams);
+ if (method==NULL) {
+ log_error("Cannot found Daemon Loader \"start\" entry point");
+ return(false);
+ }
+
+ ret=(*env)->CallStaticBooleanMethod(env,cls,method);
+ if (ret==FALSE) {
+ log_error("Cannot start daemon");
+ return(false);
+ }
+
+ log_debug("Daemon started successfully");
+ return(true);
+}
+
+/* Call the stop method in our daemon loader */
+bool java_stop(void) {
+ jmethodID method;
+ jboolean ret;
+ char stop[]="stop";
+ char stopparams[]="()Z";
+
+ jsvc_xlate_to_ascii(stop);
+ jsvc_xlate_to_ascii(stopparams);
+ method=(*env)->GetStaticMethodID(env,cls,stop,stopparams);
+ if (method==NULL) {
+ log_error("Cannot found Daemon Loader \"stop\" entry point");
+ return(false);
+ }
+
+ ret=(*env)->CallStaticBooleanMethod(env,cls,method);
+ if (ret==FALSE) {
+ log_error("Cannot stop daemon");
+ return(false);
+ }
+
+ log_debug("Daemon stopped successfully");
+ return(true);
+}
+
+/* Call the version method in our daemon loader */
+bool java_version(void) {
+ jmethodID method;
+ char version[]="version";
+ char versionparams[]="()Z";
+
+ jsvc_xlate_to_ascii(version);
+ jsvc_xlate_to_ascii(versionparams);
+ method=(*env)->GetStaticMethodID(env,cls,version,versionparams);
+ if (method==NULL) {
+ log_error("Cannot found Daemon Loader \"version\" entry point");
+ return(false);
+ }
+
+ (*env)->CallStaticVoidMethod(env,cls,method);
+ return(true);
+}
+
+/* Call the check method in our DaemonLoader class */
+bool java_check(arg_data *args) {
+ jstring className=NULL;
+ jmethodID method=NULL;
+ jboolean ret=FALSE;
+ char check[]="check";
+ char checkparams[]="(Ljava/lang/String;)Z";
+
+ log_debug("Checking daemon");
+
+ jsvc_xlate_to_ascii(args->clas);
+ className=(*env)->NewStringUTF(env,args->clas);
+ jsvc_xlate_from_ascii(args->clas);
+ if (className==NULL) {
+ log_error("Cannot create string for class name");
+ return(false);
+ }
+
+ jsvc_xlate_to_ascii(check);
+ jsvc_xlate_to_ascii(checkparams);
+ method=(*env)->GetStaticMethodID(env,cls,check,checkparams);
+ if (method==NULL) {
+ log_error("Cannot found Daemon Loader \"check\" entry point");
+ return(false);
+ }
+
+ ret=(*env)->CallStaticBooleanMethod(env,cls,method,className);
+ if (ret==FALSE) {
+ log_error("An error was detected checking the %s daemon",args->clas);
+ return(false);
+ }
+
+ log_debug("Daemon checked successfully");
+ return(true);
+}
+
+/* Call the destroy method in our daemon loader */
+bool java_destroy(void) {
+ jmethodID method;
+ jboolean ret;
+ char destroy[]="destroy";
+ char destroyparams[]="()Z";
+
+ jsvc_xlate_to_ascii(destroy);
+ jsvc_xlate_to_ascii(destroyparams);
+ method=(*env)->GetStaticMethodID(env,cls,destroy,destroyparams);
+ if (method==NULL) {
+ log_error("Cannot found Daemon Loader \"destroy\" entry point");
+ return(false);
+ }
+
+ ret=(*env)->CallStaticBooleanMethod(env,cls,method);
+ if (ret==FALSE) {
+ log_error("Cannot destroy daemon");
+ return(false);
+ }
+
+ log_debug("Daemon destroyed successfully");
+ return(true);
+}
diff --git a/src/native/unix/native/java.h b/src/native/unix/native/java.h
new file mode 100644
index 0000000..42d13fd
--- /dev/null
+++ b/src/native/unix/native/java.h
@@ -0,0 +1,28 @@
+/*
+ Copyright 2001-2004 The Apache Software Foundation.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+/* @version $Id: java.h,v 1.3 2004/02/09 15:55:21 jfclere Exp $ */
+
+#define LOADER "org/apache/commons/daemon/support/DaemonLoader"
+
+char *java_library(arg_data *args, home_data *data);
+bool java_init(arg_data *args, home_data *data);
+bool java_destroy(void);
+bool java_load(arg_data *args);
+bool java_start(void);
+bool java_stop(void);
+bool java_version(void);
+bool java_check(arg_data *args);
+bool JVM_destroy(int exit);
diff --git a/src/native/unix/native/jsvc-unix.c b/src/native/unix/native/jsvc-unix.c
new file mode 100644
index 0000000..2ff271f
--- /dev/null
+++ b/src/native/unix/native/jsvc-unix.c
@@ -0,0 +1,514 @@
+/*
+ Copyright 2001-2004 The Apache Software Foundation.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+/* @version $Id: jsvc-unix.c,v 1.9 2004/02/09 15:55:21 jfclere Exp $ */
+#include "jsvc.h"
+
+#include <signal.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <pwd.h>
+#ifdef OS_LINUX
+#include <sys/prctl.h>
+#include <sys/syscall.h>
+#define _LINUX_FS_H
+#include <linux/capability.h>
+#endif
+
+extern char **environ;
+
+pid_t controlled=0; /* the son process pid */
+static bool stopping=false;
+static bool doreload=false;
+static void (*handler_int)(int)=NULL;
+static void (*handler_hup)(int)=NULL;
+static void (*handler_trm)(int)=NULL;
+
+static void handler(int sig) {
+ switch (sig) {
+ case SIGTERM: {
+ log_debug("Caught SIGTERM: Scheduling a shutdown");
+ if (stopping==true) {
+ log_error("Shutdown or reload already scheduled");
+ } else {
+ stopping=true;
+ }
+ if (handler_trm!=NULL) (*handler_trm)(sig);
+ break;
+ }
+
+ case SIGINT: {
+ log_debug("Caught SIGINT: Scheduling a shutdown");
+ if (stopping==true) {
+ log_error("Shutdown or reload already scheduled");
+ } else {
+ stopping=true;
+ }
+ if (handler_int!=NULL) (*handler_int)(sig);
+ break;
+ }
+
+ case SIGHUP: {
+ log_debug("Caught SIGHUP: Scheduling a reload");
+ if (stopping==true) {
+ log_error("Shutdown or reload already scheduled");
+ } else {
+ stopping=true;
+ doreload=true;
+ }
+ if (handler_hup!=NULL) (*handler_hup)(sig);
+ break;
+ }
+
+ default: {
+ log_debug("Caught unknown signal %d",sig);
+ break;
+ }
+ }
+}
+
+/* user and group */
+static int set_user_group(char *user, int uid, int gid)
+{
+ if (user!=NULL) {
+ if (setgid(gid)!=0) {
+ log_error("Cannot set group id for user '%s'",user);
+ return(-1);
+ }
+ if (setuid(uid)!=0) {
+ log_error("Cannot set user id for user '%s'",user);
+ return(-1);
+ }
+ log_debug("user changed to '%s'",user);
+ }
+ return(0);
+}
+/* Set linux capability, user and group */
+#ifdef OS_LINUX
+/* CAPSALL is to allow to read/write at any location */
+#define CAPSALL (1 << CAP_NET_BIND_SERVICE)+ \
+ (1 << CAP_SETUID)+ \
+ (1 << CAP_SETGID)+ \
+ (1 << CAP_DAC_READ_SEARCH)+ \
+ (1 << CAP_DAC_OVERRIDE)
+#define CAPSMAX (1 << CAP_NET_BIND_SERVICE)+ \
+ (1 << CAP_DAC_READ_SEARCH)+ \
+ (1 << CAP_DAC_OVERRIDE)
+/* That a more reasonable configuration */
+#define CAPS (1 << CAP_NET_BIND_SERVICE)+ \
+ (1 << CAP_SETUID)+ \
+ (1 << CAP_SETGID)
+/* probably the only one Java could use */
+#define CAPSMIN (1 << CAP_NET_BIND_SERVICE)
+static int set_caps(int caps)
+{
+ struct __user_cap_header_struct caphead;
+ struct __user_cap_data_struct cap;
+
+ memset(&caphead, 0, sizeof caphead);
+ caphead.version = _LINUX_CAPABILITY_VERSION;
+ caphead.pid = 0;
+ memset(&cap, 0, sizeof cap);
+ cap.effective = caps;
+ cap.permitted = caps;
+ cap.inheritable = caps;
+ if (syscall(__NR_capset, &caphead, &cap) < 0) {
+ log_error("syscall failed in set_caps");
+ return(-1);
+ }
+ return(0);
+}
+static int linuxset_user_group(char *user, int uid, int gid)
+{
+ /* set capabilities enough for binding port 80 setuid/getuid */
+ if (set_caps(CAPS)!=0)
+ return(-1);
+
+ /* make sure they are kept after setuid */
+ if (prctl(PR_SET_KEEPCAPS,1,0,0,0) < 0) {
+ log_error("prctl failed in linuxset_user_group");
+ return(-1);
+ }
+
+ /* set setuid/getuid */
+ if (set_user_group(user,uid,gid)!=0) {
+ log_error("set_user_group failed in linuxset_user_group");
+ return(-1);
+ }
+
+ /* set capability to binding port 80 read conf */
+ if (set_caps(CAPSMIN)!=0)
+ return(-1);
+
+ return(0);
+}
+#endif
+
+
+static bool checkuser(char *user, uid_t *uid, gid_t *gid) {
+ struct passwd *pwds=NULL;
+ int status=0;
+ pid_t pid=0;
+
+ /* Do we actually _have_ to switch user? */
+ if (user==NULL) return(true);
+
+ pwds=getpwnam(user);
+ if (pwds==NULL) {
+ log_error("Invalid user name '%s' specified",user);
+ return(false);
+ }
+
+ *uid=pwds->pw_uid;
+ *gid=pwds->pw_gid;
+
+ /* Validate the user name in another process */
+ pid=fork();
+ if (pid==-1) {
+ log_error("Cannot validate user name");
+ return(false);
+ }
+
+ /* If we're in the child process, let's validate */
+ if (pid==0) {
+ if (set_user_group(user,*uid,*gid)!=0)
+ exit(1);
+ /* If we got here we switched user/group */
+ exit(0);
+ }
+
+ while (waitpid(pid,&status,0)!=pid);
+
+ /* The child must have exited cleanly */
+ if (WIFEXITED(status)) {
+ status=WEXITSTATUS(status);
+
+ /* If the child got out with 0 the user is ok */
+ if (status==0) {
+ log_debug("User '%s' validated",user);
+ return(true);
+ }
+ }
+
+ log_error("Error validating user '%s'",user);
+ return(false);
+}
+
+#ifdef OS_CYGWIN
+static void cygwincontroller() {
+ raise(SIGTERM);
+}
+#endif
+static void controller(int sig) {
+ switch (sig) {
+ case SIGTERM:
+ case SIGINT:
+ case SIGHUP:
+ log_debug("Forwarding signal %d to process %d",sig,controlled);
+ kill(controlled,sig);
+ signal(sig,controller);
+ break;
+ default:
+ log_debug("Caught unknown signal %d",sig);
+ break;
+ }
+}
+/*
+ * Return the address of the current signal handler and set the new one.
+ */
+static void * signal_set(int sig, void * newHandler) {
+ void *hand;
+
+ hand=signal(sig,newHandler);
+#ifdef SIG_ERR
+ if (hand==SIG_ERR)
+ hand=NULL;
+#endif
+ if (hand==handler || hand==controller)
+ hand=NULL;
+ return(hand);
+}
+
+/*
+ * son process logic.
+ */
+
+static int child(arg_data *args, home_data *data, uid_t uid, gid_t gid) {
+ FILE *pidf=fopen(args->pidf,"w");
+ pid_t pidn=getpid();
+ int ret=0;
+
+ /* Write the our pid in the pid file */
+ if (pidf!=NULL) {
+ fprintf(pidf,"%d\n",(int)pidn);
+ fclose(pidf);
+ } else {
+ log_error("Cannot open PID file %s, PID is %d",args->pidf,pidn);
+ }
+
+ /* create a new process group to prevent kill 0 killing the monitor process */
+#if defined(OS_FREEBSD) || defined(OS_DARWIN)
+ setpgid(0,0);
+#else
+ setpgrp();
+#endif
+
+#ifdef OS_LINUX
+ /* setuid()/setgid() only apply the current thread so we must do it now */
+ if (linuxset_user_group(args->user,uid,gid)!=0)
+ return(4);
+#endif
+ /* Initialize the Java VM */
+ if (java_init(args,data)!=true) return(1);
+
+ /* Check wether we need to dump the VM version */
+ if (args->vers==true) {
+ if (java_version()!=true) {
+ return(-1);
+ } else return(0);
+ }
+
+ /* Do we have to do a "check-only" initialization? */
+ if (java_check(args)!=true) return(2);
+ else if (args->chck==true) {
+ printf("Service \"%s\" checked successfully\n",args->clas);
+ return(0);
+ }
+
+ /* Load the service */
+ if (java_load(args)!=true) return(3);
+
+ /* Downgrade user */
+#ifdef OS_LINUX
+ if (set_caps(0)!=0) {
+ log_debug("set_caps (0) failed");
+ return(4);
+ }
+#else
+ if (set_user_group(args->user,uid,gid)!=0)
+ return(4);
+#endif
+
+ /* Start the service */
+ if (java_start()!=true) return(5);
+
+ /* Install signal handlers */
+ handler_hup=signal_set(SIGHUP,handler);
+ handler_trm=signal_set(SIGTERM,handler);
+ handler_int=signal_set(SIGINT,handler);
+ controlled = getpid();
+ log_debug("Waiting for a signal to be delivered");
+ while (!stopping) sleep(60); /* pause() not threadsafe */
+ log_debug("Shutdown or reload requested: exiting");
+
+ /* Stop the service */
+ if (java_stop()!=true) return(6);
+
+ if (doreload==true) ret=123;
+ else ret=0;
+
+ /* Destroy the service */
+ java_destroy();
+
+ /* Destroy the Java VM */
+ if (JVM_destroy(ret)!=true) return(7);
+
+ return(ret);
+}
+
+/*
+ * freopen close the file first and then open the new file
+ * that is not very good if we are try to trace the output
+ * note the code assumes that the errors are configuration errors.
+ */
+static FILE *loc_freopen(char *outfile, char *mode, FILE *stream)
+{
+ FILE *ftest;
+ ftest = fopen(outfile,mode);
+ if (ftest == NULL) {
+ fprintf(stderr,"Unable to redirect to %s\n", outfile);
+ return(stream);
+ }
+ fclose(ftest);
+ return(freopen(outfile,mode,stream));
+}
+
+/**
+ * Redirect stdin, stdout, stderr.
+ */
+static void set_output(char *outfile, char *errfile) {
+ freopen("/dev/null", "r", stdin);
+ log_debug("redirecting stdout to %s and stderr to %s",outfile,errfile);
+
+ /* make sure the debug goes out */
+ if (log_debug_flag==true && strcmp(errfile,"/dev/null") == 0)
+ return;
+
+ /* Handle malicious case here */
+ if(strcmp(outfile, "&2") == 0 && strcmp(errfile,"&1") == 0) {
+ outfile="/dev/null";
+ }
+ if(strcmp(outfile, "&2") != 0) {
+ loc_freopen(outfile, "a", stdout);
+ }
+
+ if(strcmp(errfile,"&1") != 0) {
+ loc_freopen(errfile, "a", stderr);
+ } else {
+ close(2);
+ dup(1);
+ }
+ if(strcmp(outfile, "&2") == 0) {
+ close(1);
+ dup(2);
+ }
+}
+
+int main(int argc, char *argv[]) {
+ arg_data *args=NULL;
+ home_data *data=NULL;
+ int status=0;
+ pid_t pid=0;
+ uid_t uid=0;
+ gid_t gid=0;
+
+ /* Parse command line arguments */
+ args=arguments(argc,argv);
+ if (args==NULL) return(1);
+
+ /* Let's check if we can switch user/group IDs */
+ if (checkuser(args->user, &uid, &gid)==false) return(1);
+
+ /* Retrieve JAVA_HOME layout */
+ data=home(args->home);
+ if (data==NULL) return(1);
+
+ /* Check for help */
+ if (args->help==true) {
+ help(data);
+ return(0);
+ }
+
+#ifdef OS_LINUX
+ /* On some UNIX operating systems, we need to REPLACE this current
+ process image with another one (thru execve) to allow the correct
+ loading of VMs (notably this is for Linux). Set, replace, and go. */
+ if (strcmp(argv[0],"jsvc.exec")!=0) {
+ char *oldpath=getenv("LD_LIBRARY_PATH");
+ char *libf=java_library(args,data);
+ char *old=argv[0];
+ char buf[2048];
+ char *tmp=NULL;
+ char *p1=NULL;
+ char *p2=NULL;
+
+ p1=strdup(libf);
+ tmp=strrchr(p1,'/');
+ if (tmp!=NULL) tmp[0]='\0';
+
+ p2=strdup(p1);
+ tmp=strrchr(p2,'/');
+ if (tmp!=NULL) tmp[0]='\0';
+
+ if (oldpath==NULL) snprintf(buf,2048,"%s:%s",p1,p2);
+ else snprintf(buf,2048,"%s:%s:%s",oldpath,p1,p2);
+
+ tmp=strdup(buf);
+ setenv("LD_LIBRARY_PATH",tmp,1);
+
+ log_debug("Invoking w/ LD_LIBRARY_PATH=%s",getenv("LD_LIBRARY_PATH"));
+
+ argv[0]="jsvc.exec";
+ execve(old,argv,environ);
+ log_error("Cannot execute JSVC executor process");
+ return(1);
+ }
+ log_debug("Running w/ LD_LIBRARY_PATH=%s",getenv("LD_LIBRARY_PATH"));
+#endif /* ifdef OS_LINUX */
+
+ /* If we have to detach, let's do it now */
+ if (args->dtch==true) {
+ pid=fork();
+ if (pid==-1) {
+ log_error("Cannot detach from parent process");
+ return(1);
+ }
+ /* If we're in the parent process, we siply quit */
+ if (pid!=0) return(0);
+#ifndef NO_SETSID
+ setsid();
+#endif
+ }
+
+ set_output(args->outfile, args->errfile);
+
+ /* We have to fork: this process will become the controller and the other
+ will be the child */
+ while ((pid=fork())!=-1) {
+ /* We forked (again), if this is the child, we go on normally */
+ if (pid==0) exit(child(args,data,uid,gid));
+
+ /* We are in the controller, we have to forward all interesting signals
+ to the child, and wait for it to die */
+ controlled=pid;
+#ifdef OS_CYGWIN
+ SetTerm(cygwincontroller);
+#endif
+ signal(SIGHUP,controller);
+ signal(SIGTERM,controller);
+ signal(SIGINT,controller);
+
+ while (waitpid(pid,&status,0)!=pid);
+
+ /* The child must have exited cleanly */
+ if (WIFEXITED(status)) {
+ status=WEXITSTATUS(status);
+
+ /* If the child got out with 123 he wants to be restarted */
+ if (status==123) {
+ log_debug("Reloading service");
+ continue;
+ }
+ /* If the child got out with 0 he is shutting down */
+ if (status==0) {
+ log_debug("Service shut down");
+ return(0);
+ }
+ /* Otherwise we don't rerun it */
+ log_error("Service exit with a return value of %d",status);
+ return(1);
+ } else {
+ log_error("Service did not exit cleanly",status);
+ return(1);
+ }
+ }
+
+ /* Got out of the loop? A fork() failed then. */
+ log_error("Cannot decouple controller/child processes");
+ return(1);
+
+}
+
+void main_reload(void) {
+ log_debug("Killing self with HUP signal");
+ kill(controlled,SIGHUP);
+}
+
+void main_shutdown(void) {
+ log_debug("Killing self with TERM signal");
+ kill(controlled,SIGTERM);
+}
+
diff --git a/src/native/unix/native/jsvc.h b/src/native/unix/native/jsvc.h
new file mode 100644
index 0000000..aa1255f
--- /dev/null
+++ b/src/native/unix/native/jsvc.h
@@ -0,0 +1,46 @@
+/*
+ Copyright 2001-2004 The Apache Software Foundation.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+/* @version $Id: jsvc.h,v 1.2 2004/02/09 15:55:21 jfclere Exp $ */
+#ifndef __JSVC_H__
+#define __JSVC_H__
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+/* Definitions for booleans */
+typedef enum {
+ false,
+ true
+} bool;
+
+#include "debug.h"
+#include "arguments.h"
+#include "home.h"
+#include "location.h"
+#include "replace.h"
+#include "dso.h"
+#include "java.h"
+#include "help.h"
+
+int main(int argc, char *argv[]);
+void main_reload(void);
+void main_shutdown(void);
+
+#endif /* ifndef __JSVC_H__ */
diff --git a/src/native/unix/native/location.c b/src/native/unix/native/location.c
new file mode 100644
index 0000000..e6721cc
--- /dev/null
+++ b/src/native/unix/native/location.c
@@ -0,0 +1,111 @@
+/*
+ Copyright 2001-2004 The Apache Software Foundation.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+/* @version $Id: location.c,v 1.3 2004/02/09 15:55:21 jfclere Exp $ */
+#include "jsvc.h"
+
+/* Locations of various JVM files. We have to deal with all this madness since
+ we're not distributed togheter (yet!) with an official VM distribution. All
+ this CRAP needs improvement, and based on the observation of default
+ distributions of VMs and OSes. If it doesn't work for you, please report
+ your VM layout (ls -laR) and system details (build/config.guess) so that we
+ can improve the search algorithms. */
+
+/* If JAVA_HOME is not defined we search this list of paths (OS-dependant)
+ to find the default location of the JVM. */
+char *location_home[] = {
+#if defined(OS_DARWIN)
+ "/System/Library/Frameworks/JavaVM.framework/Home",
+ "/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home/",
+#elif defined(OS_LINUX) || defined(OS_SOLARIS) || defined(OS_BSD)
+ "/usr/java",
+ "/usr/local/java",
+#elif defined(OS_CYGWIN)
+ "/cygdrive/c/WINNT/system32/java",
+#elif defined(OS_SYSV)
+ "/opt/java",
+ "/opt/java/jdk13",
+#endif
+ NULL,
+};
+
+/* The jvm.cfg file defines the VMs available for invocation. So far, on all
+ all systems I've seen it's in $JAVA_HOME/lib. If this file is not found,
+ then the "default" VMs (from location_jvm_default) is searched, otherwise,
+ we're going to look thru the "configured" VMs (from lod_cfgvm) lying
+ somewhere around JAVA_HOME. (Only two, I'm happy) */
+char *location_jvm_cfg[] = {
+ "$JAVA_HOME/jre/lib/jvm.cfg", /* JDK */
+ "$JAVA_HOME/lib/jvm.cfg", /* JRE */
+ NULL,
+};
+
+/* This is the list of "defaults" VM (searched when jvm.cfg is not found, as
+ in the case of most JDKs 1.2.2 */
+char *location_jvm_default[] = {
+#if defined(OS_DARWIN)
+ "$JAVA_HOME/../Libraries/libjvm.dylib",
+#elif defined(OS_CYGWIN)
+ "$JAVA_HOME/jre/bin/classic/jvm.dll", /* Sun JDK 1.3 */
+ "$JAVA_HOME/jre/bin/client/jvm.dll", /* Sun JDK 1.4 */
+#elif defined(OS_LINUX) || defined(OS_SOLARIS) || defined(OS_BSD) || defined(OS_SYSV) || defined(OS_FREEBSD)
+ "$JAVA_HOME/jre/lib/" CPU "/classic/libjvm.so", /* Sun JDK 1.2 */
+ "$JAVA_HOME/jre/lib/" CPU "/client/libjvm.so", /* Sun JDK 1.3 */
+ "$JAVA_HOME/jre/lib/" CPU "/libjvm.so", /* Sun JDK */
+ "$JAVA_HOME/lib/" CPU "/classic/libjvm.so", /* Sun JRE 1.2 */
+ "$JAVA_HOME/lib/" CPU "/client/libjvm.so", /* Sun JRE 1.3 */
+ "$JAVA_HOME/lib/" CPU "/libjvm.so", /* Sun JRE */
+ "$JAVA_HOME/jre/bin/" CPU "/classic/libjvm.so", /* IBM JDK 1.3 */
+ "$JAVA_HOME/jre/bin/" CPU "/libjvm.so", /* IBM JDK */
+ "$JAVA_HOME/bin/" CPU "/classic/libjvm.so", /* IBM JRE 1.3 */
+ "$JAVA_HOME/bin/" CPU "/libjvm.so", /* IBM JRE */
+ /* Those are "weirdos: if we got here, we're probably in troubles and
+ we're not going to find anything, but hope never dies... */
+ "$JAVA_HOME/jre/lib/" CPU "/classic/green_threads/libjvm.so",
+ "$JAVA_HOME/jre/lib/classic/libjvm.so",
+ "$JAVA_HOME/jre/lib/client/libjvm.so",
+ "$JAVA_HOME/jre/lib/libjvm.so",
+ "$JAVA_HOME/lib/classic/libjvm.so",
+ "$JAVA_HOME/lib/client/libjvm.so",
+ "$JAVA_HOME/lib/libjvm.so",
+ "$JAVA_HOME/jre/bin/classic/libjvm.so",
+ "$JAVA_HOME/jre/bin/client/libjvm.so",
+ "$JAVA_HOME/jre/bin/libjvm.so",
+ "$JAVA_HOME/bin/classic/libjvm.so",
+ "$JAVA_HOME/bin/client/libjvm.so",
+ "$JAVA_HOME/bin/libjvm.so",
+#endif
+ NULL,
+};
+
+/* This is the list of "configured" VM (searched when jvm.cfg is found, as
+ in the case of most JDKs 1.3 (not IBM, for example), way easier than
+ before, and lovely, indeed... */
+char *location_jvm_configured[] = {
+#if defined(OS_DARWIN)
+ "$JAVA_HOME/../Libraries/lib$VM_NAME.dylib",
+#elif defined(OS_CYGWIN)
+ "$JAVA_HOME/jre/bin/$VM_NAME/jvm.dll", /* Sun JDK 1.3 */
+#elif defined(OS_LINUX) || defined(OS_SOLARIS) || defined(OS_BSD) || defined(OS_FREEBSD)
+ "$JAVA_HOME/jre/lib/" CPU "/$VM_NAME/libjvm.so",/* Sun JDK 1.3 */
+ "$JAVA_HOME/lib/" CPU "/$VM_NAME/libjvm.so", /* Sun JRE 1.3 */
+#elif defined(OS_SYSV)
+ "$JAVA_HOME/jre/lib/" CPU "/$VM_NAME/dce_threads/libjvm.so",
+ "$JAVA_HOME/jre/lib/" CPU "/$VM_NAME/green_threads/libjvm.so",
+ "$JAVA_HOME/lib/" CPU "/$VM_NAME/dce_threads/libjvm.so",
+ "$JAVA_HOME/lib/" CPU "/$VM_NAME/green_threads/libjvm.so",
+#endif
+ NULL,
+};
diff --git a/src/native/unix/native/location.h b/src/native/unix/native/location.h
new file mode 100644
index 0000000..4ab3c32
--- /dev/null
+++ b/src/native/unix/native/location.h
@@ -0,0 +1,22 @@
+/*
+ Copyright 2001-2004 The Apache Software Foundation.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+/* @version $Id: location.h,v 1.2 2004/02/09 15:55:21 jfclere Exp $ */
+#include "jsvc.h"
+
+extern char *location_home[];
+extern char *location_jvm_cfg[];
+extern char *location_jvm_default[];
+extern char *location_jvm_configured[];
diff --git a/src/native/unix/native/replace.c b/src/native/unix/native/replace.c
new file mode 100644
index 0000000..3e91783
--- /dev/null
+++ b/src/native/unix/native/replace.c
@@ -0,0 +1,109 @@
+/*
+ Copyright 2001-2004 The Apache Software Foundation.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+/* @version $Id: replace.c,v 1.2 2004/02/09 15:55:21 jfclere Exp $ */
+#include "jsvc.h"
+
+/* Replace all occurrences of a string in another */
+int replace(char *new, int len, char *old, char *mch, char *rpl) {
+ char *tmp;
+ int count;
+ int shift;
+ int nlen;
+ int olen;
+ int mlen;
+ int rlen;
+ int x;
+
+ /* The new buffer is NULL, fail */
+ if (new==NULL) return(-1);
+ /* The length of the buffer is less than zero, fail */
+ if (len<0) return(-2);
+ /* The old buffer is NULL, fail */
+ if (old==NULL) return(-3);
+
+ /* The string to be matched is NULL or empty, simply copy */
+ if ((mch==NULL)||(strlen(mch)==0)) {
+ olen=strlen(old);
+ if (len<=olen) return(olen+1);
+ strcpy(new,old);
+ return(0);
+ }
+
+ /* The string to be replaced is NULL, assume it's an empty string */
+ if (rpl==NULL) rpl="";
+
+ /* Evaluate some lengths */
+ olen=strlen(old);
+ mlen=strlen(mch);
+ rlen=strlen(rpl);
+
+ /* Calculate how many times the mch string appears in old */
+ tmp=old;
+ count=0;
+ while((tmp=strstr(tmp,mch))!=NULL) {
+ count++;
+ tmp+=mlen;
+ }
+
+ /* We have no matches, simply copy */
+ if (count==0) {
+ olen=strlen(old);
+ if (len<=olen) return(olen+1);
+ strcpy(new,old);
+ return(0);
+ }
+
+ /* Calculate how big the buffer must be to hold the translation
+ and of how many bytes we need to shift the data */
+ shift=rlen-mlen;
+ nlen=olen+(shift*count);
+ /* printf("Count=%d Shift= %d OLen=%d NLen=%d\n",count,shift,olen,nlen); */
+
+ /* Check if we have enough size in the buffer */
+ if (nlen>=len) return(nlen+1);
+
+ /* Copy over the old buffer in the new one (save memory) */
+ strcpy(new,old);
+
+ /* Start replacing */
+ tmp=new;
+ while((tmp=strstr(tmp,mch))!=NULL) {
+ /* If shift is > 0 we need to move data from right to left */
+ if (shift>0) {
+ for (x=(strlen(tmp)+shift);x>shift;x--) {
+ /*
+ printf("src %c(%d) dst %c(%d)\n",
+ tmp[x-shift],tmp[x-shift],tmp[x],tmp[x]);
+ */
+ tmp[x]=tmp[x-shift];
+ }
+ /* If shift is < 0 we need to move data from left to right */
+ } else if (shift<0) {
+ for (x=mlen;x<strlen(tmp)-shift;x++) {
+ /*
+ printf("src %c(%d) dst %c(%d)\n",
+ tmp[x],tmp[x],tmp[x+shift],tmp[x+shift]);
+ */
+ tmp[x+shift]=tmp[x];
+ }
+ }
+ /* If shift is = 0 we don't have to shift data */
+ strncpy(tmp,rpl,rlen);
+ tmp+=rlen;
+ /* printf("\"%s\"\n",tmp); */
+ }
+ return(0);
+}
diff --git a/src/native/unix/native/replace.h b/src/native/unix/native/replace.h
new file mode 100644
index 0000000..a111a4a
--- /dev/null
+++ b/src/native/unix/native/replace.h
@@ -0,0 +1,37 @@
+/*
+ Copyright 2001-2004 The Apache Software Foundation.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+/* @version $Id: replace.h,v 1.2 2004/02/09 15:55:21 jfclere Exp $ */
+#ifndef __JSVC_REPLACE_H__
+#define __JSVC_REPLACE_H__
+
+/**
+ * Replace all occurrences of mch in old with the new string rpl, and
+ * stores the result in new, provided that its length (specified in len)
+ * is enough.
+ *
+ * @param new The buffer where the result of the replace operation will be
+ * stored into.
+ * @param len The length of the previous buffer.
+ * @param old The string where occurrences of mtch must be searched.
+ * @param mch The characters to match in old (and to be replaced)
+ * @param rpl The characters that will be replaced in place of mch.
+ * @return Zero on success, a value less than 0 if an error was encountered
+ * or a value greater than zero (indicating the required storage size
+ * for new) if the buffer was too short to hold the new string.
+ */
+int replace(char *new, int len, char *old, char *mch, char *rpl);
+
+#endif /* ifndef __JSVC_REPLACE_H__ */
diff --git a/src/native/unix/native/signals.c b/src/native/unix/native/signals.c
new file mode 100644
index 0000000..87fdaf0
--- /dev/null
+++ b/src/native/unix/native/signals.c
@@ -0,0 +1,99 @@
+/*
+ Copyright 2001-2004 The Apache Software Foundation.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+/* @version $Id: signals.c,v 1.2 2004/02/09 15:55:21 jfclere Exp $ */
+
+/*
+ * as Windows does not support signal, jsvc use event to emulate them.
+ * The supported signal is SIGTERM.
+ * The kills.c contains the kill logic.
+ */
+#ifdef OS_CYGWIN
+#include <windows.h>
+#include <stdio.h>
+static void (*HandleTerm)()=NULL; /* address of the handler routine. */
+
+/*
+ * Event handling routine
+ */
+void v_difthf(LPVOID par)
+{
+HANDLE hevint; /* make a local copy because the parameter is shared! */
+
+ hevint = (HANDLE) par;
+
+ for (;;) {
+ if (WaitForSingleObject(hevint,INFINITE) == WAIT_FAILED) {
+ /* something have gone wrong. */
+ return; /* may be something more is needed. */
+ }
+
+ /* call the interrupt handler. */
+ if (HandleTerm==NULL) return;
+ HandleTerm();
+ }
+}
+
+/*
+ * set a routine handler for the signal
+ * note that it cannot be used to change the signal handler
+ */
+int SetTerm(void (*func)())
+{
+char Name[256];
+HANDLE hevint, hthread;
+DWORD ThreadId;
+SECURITY_ATTRIBUTES sa;
+SECURITY_DESCRIPTOR sd;
+
+ sprintf(Name,"TERM%ld",GetCurrentProcessId());
+
+ /*
+ * event cannot be inherited.
+ * the event is reseted to nonsignaled after the waiting thread is released.
+ * the start state is resetted.
+ */
+
+ /* Initialize the new security descriptor. */
+ InitializeSecurityDescriptor (&sd, SECURITY_DESCRIPTOR_REVISION);
+
+ /* Add a NULL descriptor ACL to the security descriptor. */
+ SetSecurityDescriptorDacl (&sd, TRUE, (PACL)NULL, FALSE);
+
+ sa.nLength = sizeof(sa);
+ sa.lpSecurityDescriptor = &sd;
+ sa.bInheritHandle = TRUE;
+
+
+ /* It works also with NULL instead &sa!! */
+ hevint = CreateEvent(&sa,FALSE, FALSE,Name);
+
+ HandleTerm = (int (*)()) func;
+
+ if (hevint == NULL) return(-1); /* failed */
+
+ /* create the thread to wait for event */
+ hthread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE) v_difthf,
+ (LPVOID) hevint, 0, &ThreadId);
+ if (hthread == NULL) {
+ /* failed remove the event */
+ CloseHandle(hevint); /* windows will remove it. */
+ return(-1);
+ }
+
+ CloseHandle(hthread); /* not needed */
+ return(0);
+}
+#endif
diff --git a/src/native/unix/support/apfunctions.m4 b/src/native/unix/support/apfunctions.m4
new file mode 100644
index 0000000..b535245
--- /dev/null
+++ b/src/native/unix/support/apfunctions.m4
@@ -0,0 +1,80 @@
+dnl =========================================================================
+dnl
+dnl The Apache Software License, Version 1.1
+dnl
+dnl Copyright (c) 1999-2001 The Apache Software Foundation.
+dnl All rights reserved.
+dnl
+dnl =========================================================================
+dnl
+dnl Redistribution and use in source and binary forms, with or without modi-
+dnl fication, are permitted provided that the following conditions are met:
+dnl
+dnl 1. Redistributions of source code must retain the above copyright notice
+dnl notice, this list of conditions and the following disclaimer.
+dnl
+dnl 2. Redistributions in binary form must reproduce the above copyright
+dnl notice, this list of conditions and the following disclaimer in the
+dnl documentation and/or other materials provided with the distribution.
+dnl
+dnl 3. The end-user documentation included with the redistribution, if any,
+dnl must include the following acknowlegement:
+dnl
+dnl "This product includes software developed by the Apache Software
+dnl Foundation <http://www.apache.org/>."
+dnl
+dnl Alternately, this acknowlegement may appear in the software itself, if
+dnl and wherever such third-party acknowlegements normally appear.
+dnl
+dnl 4. The names "The Jakarta Project", "WebApp", and "Apache Software
+dnl Foundation" must not be used to endorse or promote products derived
+dnl from this software without prior written permission. For written
+dnl permission, please contact <apache at apache.org>.
+dnl
+dnl 5. Products derived from this software may not be called "Apache" nor may
+dnl "Apache" appear in their names without prior written permission of the
+dnl Apache Software Foundation.
+dnl
+dnl THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES
+dnl INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+dnl AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+dnl THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+dnl DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+dnl DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+dnl OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+dnl HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+dnl STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+dnl ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+dnl POSSIBILITY OF SUCH DAMAGE.
+dnl
+dnl =========================================================================
+dnl
+dnl This software consists of voluntary contributions made by many indivi-
+dnl duals on behalf of the Apache Software Foundation. For more information
+dnl on the Apache Software Foundation, please see <http://www.apache.org/>.
+dnl
+dnl =========================================================================
+
+dnl -------------------------------------------------------------------------
+dnl Author Pier Fumagalli <mailto:pier.fumagalli at eng.sun.com>
+dnl Version $Id: apfunctions.m4,v 1.1.1.1 2003/09/04 23:28:20 yoavs Exp $
+dnl -------------------------------------------------------------------------
+
+AC_DEFUN(AP_MSG_HEADER,[
+ printf "*** %s ***\n" "$1" 1>&2
+ AC_PROVIDE([$0])
+])
+
+AC_DEFUN(AP_CANONICAL_HOST_CHECK,[
+ AC_MSG_CHECKING([cached host system type])
+ if { test x"${ac_cv_host_system_type+set}" = x"set" &&
+ test x"$ac_cv_host_system_type" != x"$host" ; }
+ then
+ AC_MSG_RESULT([$ac_cv_host_system_type])
+ AC_MSG_ERROR([remove the \"$cache_file\" file and re-run configure])
+ else
+ AC_MSG_RESULT(ok)
+ ac_cv_host_system_type="$host"
+ fi
+ AC_PROVIDE([$0])
+])
diff --git a/src/native/unix/support/apjava.m4 b/src/native/unix/support/apjava.m4
new file mode 100644
index 0000000..e190b9f
--- /dev/null
+++ b/src/native/unix/support/apjava.m4
@@ -0,0 +1,130 @@
+dnl =========================================================================
+dnl
+dnl The Apache Software License, Version 1.1
+dnl
+dnl Copyright (c) 1999-2001 The Apache Software Foundation.
+dnl All rights reserved.
+dnl
+dnl =========================================================================
+dnl
+dnl Redistribution and use in source and binary forms, with or without modi-
+dnl fication, are permitted provided that the following conditions are met:
+dnl
+dnl 1. Redistributions of source code must retain the above copyright notice
+dnl notice, this list of conditions and the following disclaimer.
+dnl
+dnl 2. Redistributions in binary form must reproduce the above copyright
+dnl notice, this list of conditions and the following disclaimer in the
+dnl documentation and/or other materials provided with the distribution.
+dnl
+dnl 3. The end-user documentation included with the redistribution, if any,
+dnl must include the following acknowlegement:
+dnl
+dnl "This product includes software developed by the Apache Software
+dnl Foundation <http://www.apache.org/>."
+dnl
+dnl Alternately, this acknowlegement may appear in the software itself, if
+dnl and wherever such third-party acknowlegements normally appear.
+dnl
+dnl 4. The names "The Jakarta Project", "WebApp", and "Apache Software
+dnl Foundation" must not be used to endorse or promote products derived
+dnl from this software without prior written permission. For written
+dnl permission, please contact <apache at apache.org>.
+dnl
+dnl 5. Products derived from this software may not be called "Apache" nor may
+dnl "Apache" appear in their names without prior written permission of the
+dnl Apache Software Foundation.
+dnl
+dnl THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES
+dnl INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+dnl AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+dnl THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+dnl DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+dnl DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+dnl OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+dnl HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+dnl STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+dnl ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+dnl POSSIBILITY OF SUCH DAMAGE.
+dnl
+dnl =========================================================================
+dnl
+dnl This software consists of voluntary contributions made by many indivi-
+dnl duals on behalf of the Apache Software Foundation. For more information
+dnl on the Apache Software Foundation, please see <http://www.apache.org/>.
+dnl
+dnl =========================================================================
+
+dnl -------------------------------------------------------------------------
+dnl Author Pier Fumagalli <mailto:pier.fumagalli at eng.sun.com>
+dnl Version $Id: apjava.m4,v 1.2 2003/09/25 11:13:02 jfclere Exp $
+dnl -------------------------------------------------------------------------
+
+AC_DEFUN([AP_PROG_JAVAC_WORKS],[
+ AC_CACHE_CHECK([wether the Java compiler ($JAVAC) works],ap_cv_prog_javac_works,[
+ echo "public class Test {}" > Test.java
+ $JAVAC $JAVACFLAGS Test.java > /dev/null 2>&1
+ if test $? -eq 0
+ then
+ rm -f Test.java Test.class
+ ap_cv_prog_javac_works=yes
+ else
+ rm -f Test.java Test.class
+ AC_MSG_RESULT(no)
+ AC_MSG_ERROR([installation or configuration problem: javac cannot compile])
+ fi
+ ])
+])
+
+dnl AC_PATH_PROG does not work (it checks first PATH then our parameter).
+dnl so we do 2 checks.
+AC_DEFUN([AP_PROG_JAVAC],[
+ AC_PATH_PROG(JAVAC,javac,NONE,$JAVA_HOME/bin)
+ if test "$JAVAC" = "NONE"
+ then
+ AC_PATH_PROG(JAVAC_PATH,javac,NONE,$PATH)
+ JAVAC=$JAVAC_PATH
+ fi
+ if test "$JAVAC" = "NONE"
+ then
+ AC_MSG_ERROR([javac not found])
+ fi
+ AP_PROG_JAVAC_WORKS()
+ AC_PROVIDE([$0])
+ AC_SUBST(JAVAC)
+ AC_SUBST(JAVACFLAGS)
+])
+
+AC_DEFUN([AP_PROG_JAR],[
+ AC_PATH_PROG(JAR,jar,NONE,$JAVA_HOME/bin)
+ if test "$JAR" = "NONE"
+ then
+ AC_PATH_PROG(JAR_PATH,jar,NONE,$PATH)
+ JAR=$JAR_PATH
+ fi
+ if test "$JAR" = "NONE"
+ then
+ AC_MSG_ERROR([jar not found])
+ fi
+ AC_PROVIDE([$0])
+ AC_SUBST(JAR)
+])
+
+AC_DEFUN([AP_JAVA],[
+ AC_ARG_WITH(java,[ --with-java=DIR Specify the location of your JDK installation],[
+ AC_MSG_CHECKING([JAVA_HOME])
+ if test -d "$withval"
+ then
+ JAVA_HOME="$withval"
+ AC_MSG_RESULT([$JAVA_HOME])
+ else
+ AC_MSG_RESULT([failed])
+ AC_MSG_ERROR([$withval is not a directory])
+ fi
+ AC_SUBST(JAVA_HOME)
+ ])
+ if test x"$JAVA_HOME" = x
+ then
+ AC_MSG_ERROR([Java Home not defined. Rerun with --with-java=[...] parameter])
+ fi
+])
diff --git a/src/native/unix/support/apsupport.m4 b/src/native/unix/support/apsupport.m4
new file mode 100644
index 0000000..89a5a1a
--- /dev/null
+++ b/src/native/unix/support/apsupport.m4
@@ -0,0 +1,126 @@
+dnl =========================================================================
+dnl
+dnl The Apache Software License, Version 1.1
+dnl
+dnl Copyright (c) 1999-2001 The Apache Software Foundation.
+dnl All rights reserved.
+dnl
+dnl =========================================================================
+dnl
+dnl Redistribution and use in source and binary forms, with or without modi-
+dnl fication, are permitted provided that the following conditions are met:
+dnl
+dnl 1. Redistributions of source code must retain the above copyright notice
+dnl notice, this list of conditions and the following disclaimer.
+dnl
+dnl 2. Redistributions in binary form must reproduce the above copyright
+dnl notice, this list of conditions and the following disclaimer in the
+dnl documentation and/or other materials provided with the distribution.
+dnl
+dnl 3. The end-user documentation included with the redistribution, if any,
+dnl must include the following acknowlegement:
+dnl
+dnl "This product includes software developed by the Apache Software
+dnl Foundation <http://www.apache.org/>."
+dnl
+dnl Alternately, this acknowlegement may appear in the software itself, if
+dnl and wherever such third-party acknowlegements normally appear.
+dnl
+dnl 4. The names "The Jakarta Project", "WebApp", and "Apache Software
+dnl Foundation" must not be used to endorse or promote products derived
+dnl from this software without prior written permission. For written
+dnl permission, please contact <apache at apache.org>.
+dnl
+dnl 5. Products derived from this software may not be called "Apache" nor may
+dnl "Apache" appear in their names without prior written permission of the
+dnl Apache Software Foundation.
+dnl
+dnl THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES
+dnl INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+dnl AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+dnl THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+dnl DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+dnl DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+dnl OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+dnl HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+dnl STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+dnl ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+dnl POSSIBILITY OF SUCH DAMAGE.
+dnl
+dnl =========================================================================
+dnl
+dnl This software consists of voluntary contributions made by many indivi-
+dnl duals on behalf of the Apache Software Foundation. For more information
+dnl on the Apache Software Foundation, please see <http://www.apache.org/>.
+dnl
+dnl =========================================================================
+
+dnl -------------------------------------------------------------------------
+dnl Author Pier Fumagalli <mailto:pier.fumagalli at eng.sun.com>
+dnl Version $Id: apsupport.m4,v 1.3 2003/09/25 13:38:27 jfclere Exp $
+dnl -------------------------------------------------------------------------
+
+AC_DEFUN(AP_SUPPORTED_HOST,[
+ AC_MSG_CHECKING([C flags dependant on host system type])
+ case $host_cpu in
+ powerpc)
+ CFLAGS="$CFLAGS -DCPU=\\\"$host_cpu\\\"" ;;
+ sparc)
+ CFLAGS="$CFLAGS -DCPU=\\\"$host_cpu\\\"" ;;
+ i?86)
+ CFLAGS="$CFLAGS -DCPU=\\\"i386\\\"" ;;
+ bs2000)
+ CFLAGS="$CFLAGS -DCPU=\\\"osd\\\" -DCHARSET_EBCDIC -DOSD_POSIX"
+ supported_os="osd"
+ LDFLAGS="-Kno_link_stdlibs -B llm4 -l BLSLIB $LDFLAGS"
+ LDCMD="cc"
+ ;;
+ mips)
+ CFLAGS="$CFLAGS -DCPU=\\\"mips\\\""
+ supported_os="mips"
+ ;;
+ *)
+ AC_MSG_RESULT([failed])
+ AC_MSG_ERROR([Unsupported CPU architecture "$host_cpu"]);;
+ esac
+
+ case $host_os in
+ darwin*)
+ CFLAGS="$CFLAGS -DOS_DARWIN -DDSO_DYLD"
+ supported_os="darwin"
+ ;;
+ solaris*)
+ CFLAGS="$CFLAGS -DOS_SOLARIS -DDSO_DLFCN"
+ supported_os="solaris"
+ LDFLAGS="$LDFLAGS -ldl -lthread"
+ ;;
+ linux*)
+ CFLAGS="$CFLAGS -DOS_LINUX -DDSO_DLFCN"
+ supported_os="linux"
+ LDFLAGS="$LDFLAGS -ldl"
+ ;;
+ cygwin)
+ CFLAGS="$CFLAGS -DOS_CYGWIN -DDSO_DLFCN -DNO_SETSID"
+ supported_os="win32"
+ ;;
+ sysv)
+ CFLAGS="$CFLAGS -DOS_SYSV -DDSO_DLFCN"
+ LDFLAGS="$LDFLAGS -ldl"
+ ;;
+ sysv4)
+ CFLAGS="$CFLAGS -DOS_SYSV -DDSO_DLFCN -Kthread"
+ LDFLAGS="-Kthread $LDFLAGS -ldl"
+ ;;
+ freebsd4.?)
+ CFLAGS="$CFLAGS -DOS_FREEBSD -DDSO_DLFCN -D_THREAD_SAFE -pthread"
+ LDFLAGS="-pthread $LDFLAGS"
+ supported_os="freebsd"
+ ;;
+ *)
+ AC_MSG_RESULT([failed])
+ AC_MSG_ERROR([Unsupported operating system "$host_os"])
+ ;;
+ esac
+ AC_MSG_RESULT([ok])
+ AC_SUBST(CFLAGS)
+])
diff --git a/src/native/unix/support/buildconf.sh b/src/native/unix/support/buildconf.sh
new file mode 100644
index 0000000..b79edc0
--- /dev/null
+++ b/src/native/unix/support/buildconf.sh
@@ -0,0 +1,74 @@
+#!/bin/sh
+# ========================================================================= #
+# #
+# The Apache Software License, Version 1.1 #
+# #
+# Copyright (c) 1999-2001 The Apache Software Foundation. #
+# All rights reserved. #
+# #
+# ========================================================================= #
+# #
+# Redistribution and use in source and binary forms, with or without modi- #
+# fication, are permitted provided that the following conditions are met: #
+# #
+# 1. Redistributions of source code must retain the above copyright notice #
+# notice, this list of conditions and the following disclaimer. #
+# #
+# 2. Redistributions in binary form must reproduce the above copyright #
+# notice, this list of conditions and the following disclaimer in the #
+# documentation and/or other materials provided with the distribution. #
+# #
+# 3. The end-user documentation included with the redistribution, if any, #
+# must include the following acknowlegement: #
+# #
+# "This product includes software developed by the Apache Software #
+# Foundation <http://www.apache.org/>." #
+# #
+# Alternately, this acknowlegement may appear in the software itself, if #
+# and wherever such third-party acknowlegements normally appear. #
+# #
+# 4. The names "The Jakarta Project", "WebApp", and "Apache Software #
+# Foundation" must not be used to endorse or promote products derived #
+# from this software without prior written permission. For written #
+# permission, please contact <apache at apache.org>. #
+# #
+# 5. Products derived from this software may not be called "Apache" nor may #
+# "Apache" appear in their names without prior written permission of the #
+# Apache Software Foundation. #
+# #
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES #
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY #
+# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL #
+# THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY #
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL #
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS #
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) #
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, #
+# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN #
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE #
+# POSSIBILITY OF SUCH DAMAGE. #
+# #
+# ========================================================================= #
+# #
+# This software consists of voluntary contributions made by many indivi- #
+# duals on behalf of the Apache Software Foundation. For more information #
+# on the Apache Software Foundation, please see <http://www.apache.org/>. #
+# #
+# ========================================================================= #
+
+# @author Pier Fumagalli <mailto:pier.fumagalli at eng.sun.com>
+# @version $Id: buildconf.sh,v 1.2 2003/09/12 09:05:57 jfclere Exp $
+
+# The cache of automake always brings problems when changing *.m4 files.
+rm -rf autom4te.cache
+
+if test -f configure.in ; then
+ autoconf
+ if test $? -ne 0 ; then
+ echo "$0: cannot generate configure script"
+ else
+ echo "$0: configure script generated successfully"
+ fi
+else
+ echo "$0: cannot find source file configure.in"
+fi
diff --git a/src/native/unix/support/config.guess b/src/native/unix/support/config.guess
new file mode 100644
index 0000000..ba66165
--- /dev/null
+++ b/src/native/unix/support/config.guess
@@ -0,0 +1,1371 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+# Free Software Foundation, Inc.
+
+timestamp='2001-04-20'
+
+# This file 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 of the License, or
+# (at your option) any later version.
+#
+# This program 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 this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Written by Per Bothner <bothner at cygnus.com>.
+# Please send patches to <config-patches at gnu.org>.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub. If it succeeds, it prints the system name on stdout, and
+# exits with 0. Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches at gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 93, 94, 95, 96, 97, 98, 99, 2000
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit 0 ;;
+ --version | -v )
+ echo "$version" ; exit 0 ;;
+ --help | --h* | -h )
+ echo "$usage"; exit 0 ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help" >&2
+ exit 1 ;;
+ * )
+ break ;;
+ esac
+done
+
+if test $# != 0; then
+ echo "$me: too many arguments$help" >&2
+ exit 1
+fi
+
+
+dummy=dummy-$$
+trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script.
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,) echo "int dummy(){}" > $dummy.c
+ for c in cc gcc c89 ; do
+ ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1
+ if test $? = 0 ; then
+ CC_FOR_BUILD="$c"; break
+ fi
+ done
+ rm -f $dummy.c $dummy.o $dummy.rel
+ if test x"$CC_FOR_BUILD" = x ; then
+ CC_FOR_BUILD=no_compiler_found
+ fi
+ ;;
+ ,,*) CC_FOR_BUILD=$CC ;;
+ ,*,*) CC_FOR_BUILD=$HOST_CC ;;
+esac
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi at noc.rutgers.edu 8/24/94.)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+ PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ *:NetBSD:*:*)
+ # Netbsd (nbsd) targets should (where applicable) match one or
+ # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+ # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
+ # switched to ELF, *-*-netbsd* would select the old
+ # object file format. This provides both forward
+ # compatibility and a consistent mechanism for selecting the
+ # object file format.
+ # Determine the machine/vendor (is the vendor relevant).
+ case "${UNAME_MACHINE}" in
+ amiga) machine=m68k-unknown ;;
+ arm32) machine=arm-unknown ;;
+ atari*) machine=m68k-atari ;;
+ sun3*) machine=m68k-sun ;;
+ mac68k) machine=m68k-apple ;;
+ macppc) machine=powerpc-apple ;;
+ hp3[0-9][05]) machine=m68k-hp ;;
+ ibmrt|romp-ibm) machine=romp-ibm ;;
+ *) machine=${UNAME_MACHINE}-unknown ;;
+ esac
+ # The Operating System including object format, if it has switched
+ # to ELF recently, or will in the future.
+ case "${UNAME_MACHINE}" in
+ i386|sparc|amiga|arm*|hp300|mvme68k|vax|atari|luna68k|mac68k|news68k|next68k|pc532|sun3*|x68k)
+ if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep __ELF__ >/dev/null
+ then
+ # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+ # Return netbsd for either. FIX?
+ os=netbsd
+ else
+ os=netbsdelf
+ fi
+ ;;
+ *)
+ os=netbsd
+ ;;
+ esac
+ # The OS release
+ release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+ # contains redundant information, the shorter form:
+ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+ echo "${machine}-${os}${release}"
+ exit 0 ;;
+ alpha:OSF1:*:*)
+ if test $UNAME_RELEASE = "V4.0"; then
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ fi
+ # A Vn.n version is a released version.
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ cat <<EOF >$dummy.s
+ .data
+\$Lformat:
+ .byte 37,100,45,37,120,10,0 # "%d-%x\n"
+
+ .text
+ .globl main
+ .align 4
+ .ent main
+main:
+ .frame \$30,16,\$26,0
+ ldgp \$29,0(\$27)
+ .prologue 1
+ .long 0x47e03d80 # implver \$0
+ lda \$2,-1
+ .long 0x47e20c21 # amask \$2,\$1
+ lda \$16,\$Lformat
+ mov \$0,\$17
+ not \$1,\$18
+ jsr \$26,printf
+ ldgp \$29,0(\$26)
+ mov 0,\$16
+ jsr \$26,exit
+ .end main
+EOF
+ $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
+ if test "$?" = 0 ; then
+ case `./$dummy` in
+ 0-0)
+ UNAME_MACHINE="alpha"
+ ;;
+ 1-0)
+ UNAME_MACHINE="alphaev5"
+ ;;
+ 1-1)
+ UNAME_MACHINE="alphaev56"
+ ;;
+ 1-101)
+ UNAME_MACHINE="alphapca56"
+ ;;
+ 2-303)
+ UNAME_MACHINE="alphaev6"
+ ;;
+ 2-307)
+ UNAME_MACHINE="alphaev67"
+ ;;
+ esac
+ fi
+ rm -f $dummy.s $dummy
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ exit 0 ;;
+ Alpha\ *:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # Should we change UNAME_MACHINE based on the output of uname instead
+ # of the specific Alpha model?
+ echo alpha-pc-interix
+ exit 0 ;;
+ 21064:Windows_NT:50:3)
+ echo alpha-dec-winnt3.5
+ exit 0 ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-unknown-sysv4
+ exit 0;;
+ amiga:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ *:[Aa]miga[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-amigaos
+ exit 0 ;;
+ arc64:OpenBSD:*:*)
+ echo mips64el-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ arc:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ hkmips:OpenBSD:*:*)
+ echo mips-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ pmax:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sgi:OpenBSD:*:*)
+ echo mips-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ wgrisc:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ *:OS/390:*:*)
+ echo i370-ibm-openedition
+ exit 0 ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit 0;;
+ SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit 0;;
+ Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+ # akee at wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ echo pyramid-pyramid-sysv3
+ else
+ echo pyramid-pyramid-bsd
+ fi
+ exit 0 ;;
+ NILE*:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit 0 ;;
+ sun4H:SunOS:5.*:*)
+ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ i86pc:SunOS:5.*:*)
+ echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:6*:*)
+ # According to config.sub, this is the proper way to canonicalize
+ # SunOS6. Hard to guess exactly what SunOS6 will be like, but
+ # it's likely to be more like Solaris than SunOS4.
+ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:*:*)
+ case "`/usr/bin/arch -k`" in
+ Series*|S4*)
+ UNAME_RELEASE=`uname -v`
+ ;;
+ esac
+ # Japanese Language versions have a version number like `4.1.3-JL'.
+ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ exit 0 ;;
+ sun3*:SunOS:*:*)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ exit 0 ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ ;;
+ sun4)
+ echo sparc-sun-sunos${UNAME_RELEASE}
+ ;;
+ esac
+ exit 0 ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit 0 ;;
+ atari*:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ # The situation for MiNT is a little confusing. The machine name
+ # can be virtually everything (everything which is not
+ # "atarist" or "atariste" at least should have a processor
+ # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
+ # to the lowercase version "mint" (or "freemint"). Finally
+ # the system name "TOS" denotes a system which is actually not
+ # MiNT. But MiNT is downward compatible to TOS, so this should
+ # be no problem.
+ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit 0 ;;
+ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit 0 ;;
+ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit 0 ;;
+ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+ echo m68k-milan-mint${UNAME_RELEASE}
+ exit 0 ;;
+ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+ echo m68k-hades-mint${UNAME_RELEASE}
+ exit 0 ;;
+ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+ echo m68k-unknown-mint${UNAME_RELEASE}
+ exit 0 ;;
+ sun3*:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mac68k:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme68k:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme88k:OpenBSD:*:*)
+ echo m88k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit 0 ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit 0 ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix${UNAME_RELEASE}
+ exit 0 ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix${UNAME_RELEASE}
+ exit 0 ;;
+ 2020:CLIX:*:* | 2430:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
+ exit 0 ;;
+ mips:*:*:UMIPS | mips:*:*:RISCos)
+ sed 's/^ //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h> /* for printf() prototype */
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+ #if defined (host_mips) && defined (MIPSEB)
+ #if defined (SYSTYPE_SYSV)
+ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_SVR4)
+ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ #endif
+ #endif
+ exit (-1);
+ }
+EOF
+ $CC_FOR_BUILD $dummy.c -o $dummy \
+ && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+ && rm -f $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
+ echo mips-mips-riscos${UNAME_RELEASE}
+ exit 0 ;;
+ Motorola:PowerMAX_OS:*:*)
+ echo powerpc-motorola-powermax
+ exit 0 ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit 0 ;;
+ m88k:CX/UX:7*:*)
+ echo m88k-harris-cxux7
+ exit 0 ;;
+ m88k:*:4*:R4*)
+ echo m88k-motorola-sysv4
+ exit 0 ;;
+ m88k:*:3*:R3*)
+ echo m88k-motorola-sysv3
+ exit 0 ;;
+ AViiON:dgux:*:*)
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+ then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+ [ ${TARGET_BINARY_INTERFACE}x = x ]
+ then
+ echo m88k-dg-dgux${UNAME_RELEASE}
+ else
+ echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ fi
+ else
+ echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit 0 ;;
+ M88*:*:R3*:*)
+ # Delta 88k system running SVR3
+ echo m88k-motorola-sysv3
+ exit 0 ;;
+ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+ echo m88k-tektronix-sysv3
+ exit 0 ;;
+ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+ echo m68k-tektronix-bsd
+ exit 0 ;;
+ *:IRIX*:*:*)
+ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ exit 0 ;;
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ i*86:AIX:*:*)
+ echo i386-ibm-aix
+ exit 0 ;;
+ ia64:AIX:*:*)
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+ exit 0 ;;
+ *:AIX:2:3)
+ if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+ sed 's/^ //' << EOF >$dummy.c
+ #include <sys/systemcfg.h>
+
+ main()
+ {
+ if (!__power_pc())
+ exit(1);
+ puts("powerpc-ibm-aix3.2.5");
+ exit(0);
+ }
+EOF
+ $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
+ echo rs6000-ibm-aix3.2.5
+ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ echo rs6000-ibm-aix3.2.4
+ else
+ echo rs6000-ibm-aix3.2
+ fi
+ exit 0 ;;
+ *:AIX:*:[45])
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'`
+ if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+ else
+ IBM_ARCH=powerpc
+ fi
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+ exit 0 ;;
+ *:AIX:*:*)
+ echo rs6000-ibm-aix
+ exit 0 ;;
+ ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ echo romp-ibm-bsd4.4
+ exit 0 ;;
+ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ exit 0 ;; # report: romp-ibm BSD 4.3
+ *:BOSX:*:*)
+ echo rs6000-bull-bosx
+ exit 0 ;;
+ DPX/2?00:B.O.S.:*:*)
+ echo m68k-bull-sysv3
+ exit 0 ;;
+ 9000/[34]??:4.3bsd:1.*:*)
+ echo m68k-hp-bsd
+ exit 0 ;;
+ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+ echo m68k-hp-bsd4.4
+ exit 0 ;;
+ 9000/[34678]??:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ case "${UNAME_MACHINE}" in
+ 9000/31? ) HP_ARCH=m68000 ;;
+ 9000/[34]?? ) HP_ARCH=m68k ;;
+ 9000/[678][0-9][0-9])
+ case "${HPUX_REV}" in
+ 11.[0-9][0-9])
+ if [ -x /usr/bin/getconf ]; then
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+ case "${sc_cpu_version}" in
+ 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+ 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+ 532) # CPU_PA_RISC2_0
+ case "${sc_kernel_bits}" in
+ 32) HP_ARCH="hppa2.0n" ;;
+ 64) HP_ARCH="hppa2.0w" ;;
+ esac ;;
+ esac
+ fi ;;
+ esac
+ if [ "${HP_ARCH}" = "" ]; then
+ sed 's/^ //' << EOF >$dummy.c
+
+ #define _HPUX_SOURCE
+ #include <stdlib.h>
+ #include <unistd.h>
+
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
+
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
+EOF
+ (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy`
+ if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi
+ rm -f $dummy.c $dummy
+ fi ;;
+ esac
+ echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ exit 0 ;;
+ ia64:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ echo ia64-hp-hpux${HPUX_REV}
+ exit 0 ;;
+ 3050*:HI-UX:*:*)
+ sed 's/^ //' << EOF >$dummy.c
+ #include <unistd.h>
+ int
+ main ()
+ {
+ long cpu = sysconf (_SC_CPU_VERSION);
+ /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+ true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
+ results, however. */
+ if (CPU_IS_PA_RISC (cpu))
+ {
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+ default: puts ("hppa-hitachi-hiuxwe2"); break;
+ }
+ }
+ else if (CPU_IS_HP_MC68K (cpu))
+ puts ("m68k-hitachi-hiuxwe2");
+ else puts ("unknown-hitachi-hiuxwe2");
+ exit (0);
+ }
+EOF
+ $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
+ echo unknown-hitachi-hiuxwe2
+ exit 0 ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ echo hppa1.1-hp-bsd
+ exit 0 ;;
+ 9000/8??:4.3bsd:*:*)
+ echo hppa1.0-hp-bsd
+ exit 0 ;;
+ *9??*:MPE/iX:*:*)
+ echo hppa1.0-hp-mpeix
+ exit 0 ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ echo hppa1.1-hp-osf
+ exit 0 ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ exit 0 ;;
+ i*86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit 0 ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit 0 ;;
+ hppa*:OpenBSD:*:*)
+ echo hppa-unknown-openbsd
+ exit 0 ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+ exit 0 ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit 0 ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+ exit 0 ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+ exit 0 ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+ exit 0 ;;
+ CRAY*X-MP:*:*:*)
+ echo xmp-cray-unicos
+ exit 0 ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE}
+ exit 0 ;;
+ CRAY*[A-Z]90:*:*:*)
+ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
+ exit 0 ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY*T3D:*:*:*)
+ echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY*T3E:*:*:*)
+ echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY*SV1:*:*:*)
+ echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY-2:*:*:*)
+ echo cray2-cray-unicos
+ exit 0 ;;
+ F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+ FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit 0 ;;
+ hp300:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ sparc*:BSD/OS:*:*)
+ echo sparc-unknown-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ *:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ *:FreeBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit 0 ;;
+ *:OpenBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ exit 0 ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin
+ exit 0 ;;
+ i*:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit 0 ;;
+ i*:PW*:*)
+ echo ${UNAME_MACHINE}-pc-pw32
+ exit 0 ;;
+ i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+ # UNAME_MACHINE based on the output of uname instead of i386?
+ echo i386-pc-interix
+ exit 0 ;;
+ i*:UWIN*:*)
+ echo ${UNAME_MACHINE}-pc-uwin
+ exit 0 ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin
+ exit 0 ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ *:GNU:*:*)
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit 0 ;;
+ i*86:Minix:*:*)
+ echo ${UNAME_MACHINE}-pc-minix
+ exit 0 ;;
+ arm*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ ia64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux
+ exit 0 ;;
+ m68*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ mips:Linux:*:*)
+ cat >$dummy.c <<EOF
+#ifdef __cplusplus
+#include <stdio.h> /* for printf() prototype */
+int main (int argc, char *argv[]) {
+#else
+int main (argc, argv) int argc; char *argv[]; {
+#endif
+#ifdef __MIPSEB__
+ printf ("%s-unknown-linux-gnu\n", argv[1]);
+#endif
+#ifdef __MIPSEL__
+ printf ("%sel-unknown-linux-gnu\n", argv[1]);
+#endif
+ return 0;
+}
+EOF
+ $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm -f $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
+ ;;
+ ppc:Linux:*:*)
+ # Determine Lib Version
+ cat >$dummy.c <<EOF
+#include <features.h>
+#if defined(__GLIBC__)
+extern char __libc_version[];
+extern char __libc_release[];
+#endif
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+#if defined(__GLIBC__)
+ printf("%s %s\n", __libc_version, __libc_release);
+#else
+ printf("unknown\n");
+#endif
+ return 0;
+}
+EOF
+ LIBC=""
+ $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null
+ if test "$?" = 0 ; then
+ ./$dummy | grep 1\.99 > /dev/null
+ if test "$?" = 0 ; then LIBC="libc1" ; fi
+ fi
+ rm -f $dummy.c $dummy
+ echo powerpc-unknown-linux-gnu${LIBC}
+ exit 0 ;;
+ alpha:Linux:*:*)
+ cat <<EOF >$dummy.s
+ .data
+ \$Lformat:
+ .byte 37,100,45,37,120,10,0 # "%d-%x\n"
+ .text
+ .globl main
+ .align 4
+ .ent main
+ main:
+ .frame \$30,16,\$26,0
+ ldgp \$29,0(\$27)
+ .prologue 1
+ .long 0x47e03d80 # implver \$0
+ lda \$2,-1
+ .long 0x47e20c21 # amask \$2,\$1
+ lda \$16,\$Lformat
+ mov \$0,\$17
+ not \$1,\$18
+ jsr \$26,printf
+ ldgp \$29,0(\$26)
+ mov 0,\$16
+ jsr \$26,exit
+ .end main
+EOF
+ LIBC=""
+ $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
+ if test "$?" = 0 ; then
+ case `./$dummy` in
+ 0-0) UNAME_MACHINE="alpha" ;;
+ 1-0) UNAME_MACHINE="alphaev5" ;;
+ 1-1) UNAME_MACHINE="alphaev56" ;;
+ 1-101) UNAME_MACHINE="alphapca56" ;;
+ 2-303) UNAME_MACHINE="alphaev6" ;;
+ 2-307) UNAME_MACHINE="alphaev67" ;;
+ esac
+ objdump --private-headers $dummy | \
+ grep ld.so.1 > /dev/null
+ if test "$?" = 0 ; then
+ LIBC="libc1"
+ fi
+ fi
+ rm -f $dummy.s $dummy
+ echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+ exit 0 ;;
+ parisc:Linux:*:* | hppa:Linux:*:*)
+ # Look for CPU level
+ case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+ PA7*) echo hppa1.1-unknown-linux-gnu ;;
+ PA8*) echo hppa2.0-unknown-linux-gnu ;;
+ *) echo hppa-unknown-linux-gnu ;;
+ esac
+ exit 0 ;;
+ parisc64:Linux:*:* | hppa64:Linux:*:*)
+ echo hppa64-unknown-linux-gnu
+ exit 0 ;;
+ s390:Linux:*:* | s390x:Linux:*:*)
+ echo ${UNAME_MACHINE}-ibm-linux
+ exit 0 ;;
+ sh*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ sparc:Linux:*:* | sparc64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ x86_64:Linux:*:*)
+ echo x86_64-unknown-linux-gnu
+ exit 0 ;;
+ i*86:Linux:*:*)
+ # The BFD linker knows what the default object file format is, so
+ # first see if it will tell us. cd to the root directory to prevent
+ # problems with other programs or directories called `ld' in the path.
+ ld_supported_emulations=`cd /; ld --help 2>&1 \
+ | sed -ne '/supported emulations:/!d
+ s/[ ][ ]*/ /g
+ s/.*supported emulations: *//
+ s/ .*//
+ p'`
+ case "$ld_supported_emulations" in
+ i*86linux)
+ echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+ exit 0
+ ;;
+ elf_i*86)
+ TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+ ;;
+ i*86coff)
+ echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+ exit 0
+ ;;
+ esac
+ # Either a pre-BFD a.out linker (linux-gnuoldld)
+ # or one that does not give us useful --help.
+ # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout.
+ # If ld does not provide *any* "supported emulations:"
+ # that means it is gnuoldld.
+ test -z "$ld_supported_emulations" && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0
+ case "${UNAME_MACHINE}" in
+ i*86)
+ VENDOR=pc;
+ ;;
+ *)
+ VENDOR=unknown;
+ ;;
+ esac
+ # Determine whether the default compiler is a.out or elf
+ cat >$dummy.c <<EOF
+#include <features.h>
+#ifdef __cplusplus
+#include <stdio.h> /* for printf() prototype */
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+#ifdef __ELF__
+# ifdef __GLIBC__
+# if __GLIBC__ >= 2
+ printf ("%s-${VENDOR}-linux-gnu\n", argv[1]);
+# else
+ printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
+# endif
+# else
+ printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
+# endif
+#else
+ printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]);
+#endif
+ return 0;
+}
+EOF
+ $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm -f $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
+ test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
+ ;;
+# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions
+# are messed up and put the nodename in both sysname and nodename.
+ i*86:DYNIX/ptx:4*:*)
+ echo i386-sequent-sysv4
+ exit 0 ;;
+ i*86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit 0 ;;
+ i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+ UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+ fi
+ exit 0 ;;
+ i*86:*:5:7*)
+ # Fixed at (any) Pentium or better
+ UNAME_MACHINE=i586
+ if [ ${UNAME_SYSTEM} = "UnixWare" ] ; then
+ echo ${UNAME_MACHINE}-sco-sysv${UNAME_RELEASE}uw${UNAME_VERSION}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ i*86:*:3.2:*)
+ if test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ elif /bin/uname -X 2>/dev/null >/dev/null ; then
+ UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \
+ && UNAME_MACHINE=i686
+ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ else
+ echo ${UNAME_MACHINE}-pc-sysv32
+ fi
+ exit 0 ;;
+ i*86:*DOS:*:*)
+ echo ${UNAME_MACHINE}-pc-msdosdjgpp
+ exit 0 ;;
+ pc:*:*:*)
+ # Left here for compatibility:
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i386.
+ echo i386-pc-msdosdjgpp
+ exit 0 ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit 0 ;;
+ paragon:*:*:*)
+ echo i860-intel-osf1
+ exit 0 ;;
+ i860:*:4.*:*) # i860-SVR4
+ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+ echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ else # Add other i860-SVR4 vendors below as they are discovered.
+ echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ fi
+ exit 0 ;;
+ mini*:CTIX:SYS*5:*)
+ # "miniframe"
+ echo m68010-convergent-sysv
+ exit 0 ;;
+ M68*:*:R3V[567]*:*)
+ test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+ 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
+ OS_REL=''
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && echo i486-ncr-sysv4 && exit 0 ;;
+ m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit 0 ;;
+ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ rs6000:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+ echo powerpc-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
+ exit 0 ;;
+ RM*:ReliantUNIX-*:*:*)
+ echo mips-sni-sysv4
+ exit 0 ;;
+ RM*:SINIX-*:*:*)
+ echo mips-sni-sysv4
+ exit 0 ;;
+ *:SINIX-*:*:*)
+ if uname -p 2>/dev/null >/dev/null ; then
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ echo ${UNAME_MACHINE}-sni-sysv4
+ else
+ echo ns32k-sni-sysv
+ fi
+ exit 0 ;;
+ PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel at ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit 0 ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes at openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit 0 ;;
+ *:*:*:FTX*)
+ # From seanf at swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit 0 ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${UNAME_RELEASE}
+ exit 0 ;;
+ news*:NEWS-OS:6*:*)
+ echo mips-sony-newsos6
+ exit 0 ;;
+ R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+ if [ -d /usr/nec ]; then
+ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit 0 ;;
+ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
+ echo powerpc-apple-beos
+ exit 0 ;;
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit 0 ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux${UNAME_RELEASE}
+ exit 0 ;;
+ SX-5:SUPER-UX:*:*)
+ echo sx5-nec-superux${UNAME_RELEASE}
+ exit 0 ;;
+ Power*:Rhapsody:*:*)
+ echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ exit 0 ;;
+ *:Rhapsody:*:*)
+ echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ exit 0 ;;
+ *:Darwin:*:*)
+ echo `uname -p`-apple-darwin${UNAME_RELEASE}
+ exit 0 ;;
+ *:procnto*:*:* | *:QNX:[0123456789]*:*)
+ if test "${UNAME_MACHINE}" = "x86pc"; then
+ UNAME_MACHINE=pc
+ fi
+ echo `uname -p`-${UNAME_MACHINE}-nto-qnx
+ exit 0 ;;
+ *:QNX:*:4*)
+ echo i386-pc-qnx
+ exit 0 ;;
+ NSR-[KW]:NONSTOP_KERNEL:*:*)
+ echo nsr-tandem-nsk${UNAME_RELEASE}
+ exit 0 ;;
+ *:NonStop-UX:*:*)
+ echo mips-compaq-nonstopux
+ exit 0 ;;
+ BS2000:POSIX*:*:*)
+ echo bs2000-siemens-sysv
+ exit 0 ;;
+ DS/*:UNIX_System_V:*:*)
+ echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+ exit 0 ;;
+ *:Plan9:*:*)
+ # "uname -m" is not consistent, so use $cputype instead. 386
+ # is converted to i386 for consistency with other x86
+ # operating systems.
+ if test "$cputype" = "386"; then
+ UNAME_MACHINE=i386
+ else
+ UNAME_MACHINE="$cputype"
+ fi
+ echo ${UNAME_MACHINE}-unknown-plan9
+ exit 0 ;;
+ i*86:OS/2:*:*)
+ # If we were able to find `uname', then EMX Unix compatibility
+ # is probably installed.
+ echo ${UNAME_MACHINE}-pc-os2-emx
+ exit 0 ;;
+ *:TOPS-10:*:*)
+ echo pdp10-unknown-tops10
+ exit 0 ;;
+ *:TENEX:*:*)
+ echo pdp10-unknown-tenex
+ exit 0 ;;
+ KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+ echo pdp10-dec-tops20
+ exit 0 ;;
+ XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+ echo pdp10-xkl-tops20
+ exit 0 ;;
+ *:TOPS-20:*:*)
+ echo pdp10-unknown-tops20
+ exit 0 ;;
+ *:ITS:*:*)
+ echo pdp10-unknown-its
+ exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+ /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
+ I don't know.... */
+ printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+ printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+ "4"
+#else
+ ""
+#endif
+ ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+ printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+ printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+ int version;
+ version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+ if (version < 4)
+ printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+ else
+ printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+ exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+ printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+ printf ("ns32k-encore-mach\n"); exit (0);
+#else
+ printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+ printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+ printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+ printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+ struct utsname un;
+
+ uname(&un);
+
+ if (strncmp(un.version, "V2", 2) == 0) {
+ printf ("i386-sequent-ptx2\n"); exit (0);
+ }
+ if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+ printf ("i386-sequent-ptx1\n"); exit (0);
+ }
+ printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+# include <sys/param.h>
+# if defined (BSD)
+# if BSD == 43
+ printf ("vax-dec-bsd4.3\n"); exit (0);
+# else
+# if BSD == 199006
+ printf ("vax-dec-bsd4.3reno\n"); exit (0);
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# endif
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# else
+ printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+ printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+ exit (1);
+}
+EOF
+
+$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0
+rm -f $dummy.c $dummy
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+ case `getsysinfo -f cpu_type` in
+ c1*)
+ echo c1-convex-bsd
+ exit 0 ;;
+ c2*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit 0 ;;
+ c34*)
+ echo c34-convex-bsd
+ exit 0 ;;
+ c38*)
+ echo c38-convex-bsd
+ exit 0 ;;
+ c4*)
+ echo c4-convex-bsd
+ exit 0 ;;
+ esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+ ftp://ftp.gnu.org/pub/gnu/config/
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches at gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo = `(hostinfo) 2>/dev/null`
+/bin/universe = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/src/native/unix/support/config.sub b/src/native/unix/support/config.sub
new file mode 100644
index 0000000..93a3a14
--- /dev/null
+++ b/src/native/unix/support/config.sub
@@ -0,0 +1,1362 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+# Free Software Foundation, Inc.
+
+timestamp='2001-05-11'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine. It does not imply ALL GNU software can.
+#
+# This file 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 of the License, or
+# (at your option) any later version.
+#
+# This program 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 this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Please send patches to <config-patches at gnu.org>.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support. The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+ $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches at gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit 0 ;;
+ --version | -v )
+ echo "$version" ; exit 0 ;;
+ --help | --h* | -h )
+ echo "$usage"; exit 0 ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help"
+ exit 1 ;;
+
+ *local*)
+ # First pass through any local machine types.
+ echo $1
+ exit 0;;
+
+ * )
+ break ;;
+ esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+ exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+ exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ nto-qnx* | linux-gnu* | storm-chaos* | os2-emx*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+ then os=`echo $1 | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work. We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+ -sun*os*)
+ # Prevent following clause from handling this invalid input.
+ ;;
+ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple | -axis)
+ os=
+ basic_machine=$1
+ ;;
+ -sim | -cisco | -oki | -wec | -winbond)
+ os=
+ basic_machine=$1
+ ;;
+ -scout)
+ ;;
+ -wrs)
+ os=-vxworks
+ basic_machine=$1
+ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+ -sco5)
+ os=-sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -udk*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -isc)
+ os=-isc2.2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -clix*)
+ basic_machine=clipper-intergraph
+ ;;
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+ -ptx*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ ;;
+ -windowsnt*)
+ os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ ;;
+ -psos*)
+ os=-psos
+ ;;
+ -mint | -mint[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+ # Recognize the basic CPU types without company name.
+ # Some are omitted here because they have special meanings below.
+ tahoe | i860 | ia64 | m32r | m68k | m68000 | m88k | ns32k | arc \
+ | arm | arme[lb] | arm[bl]e | armv[2345] | armv[345][lb] | strongarm | xscale \
+ | pyramid | mn10200 | mn10300 | tron | a29k \
+ | 580 | i960 | h8300 \
+ | x86 | ppcbe | mipsbe | mipsle | shbe | shle \
+ | hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \
+ | hppa64 \
+ | alpha | alphaev[4-8] | alphaev56 | alphapca5[67] \
+ | alphaev6[78] \
+ | we32k | ns16k | clipper | i370 | sh | sh[34] \
+ | powerpc | powerpcle \
+ | 1750a | dsp16xx | pdp10 | pdp11 \
+ | mips16 | mips64 | mipsel | mips64el \
+ | mips64orion | mips64orionel | mipstx39 | mipstx39el \
+ | mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \
+ | mips64vr5000 | miprs64vr5000el | mcore | s390 | s390x \
+ | sparc | sparclet | sparclite | sparc64 | sparcv9 | sparcv9b \
+ | v850 | c4x \
+ | thumb | d10v | d30v | fr30 | avr | openrisc | tic80 \
+ | pj | pjl | h8500 | z8k)
+ basic_machine=$basic_machine-unknown
+ ;;
+ m6811 | m68hc11 | m6812 | m68hc12)
+ # Motorola 68HC11/12.
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | z8k | v70 | w65 | z8k)
+ ;;
+
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i*86 | x86_64)
+ basic_machine=$basic_machine-pc
+ ;;
+ # Object if more than one company name word.
+ *-*-*)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+ # Recognize the basic CPU types with company name.
+ # FIXME: clean up the formatting here.
+ vax-* | tahoe-* | i*86-* | i860-* | ia64-* | m32r-* | m68k-* | m68000-* \
+ | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | c[123]* \
+ | arm-* | armbe-* | armle-* | armv*-* | strongarm-* | xscale-* \
+ | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
+ | power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \
+ | xmp-* | ymp-* \
+ | x86-* | ppcbe-* | mipsbe-* | mipsle-* | shbe-* | shle-* \
+ | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* \
+ | hppa2.0n-* | hppa64-* \
+ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphapca5[67]-* \
+ | alphaev6[78]-* \
+ | we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \
+ | clipper-* | orion-* \
+ | sparclite-* | pdp10-* | pdp11-* | sh-* | sh[34]-* | sh[34]eb-* \
+ | powerpc-* | powerpcle-* | sparc64-* | sparcv9-* | sparcv9b-* | sparc86x-* \
+ | mips16-* | mips64-* | mipsel-* \
+ | mips64el-* | mips64orion-* | mips64orionel-* \
+ | mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \
+ | mipstx39-* | mipstx39el-* | mcore-* \
+ | f30[01]-* | f700-* | s390-* | s390x-* | sv1-* | t3e-* \
+ | [cjt]90-* \
+ | m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \
+ | thumb-* | v850-* | d30v-* | tic30-* | tic80-* | c30-* | fr30-* \
+ | bs2000-* | tic54x-* | c54x-* | x86_64-* | pj-* | pjl-*)
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+ 386bsd)
+ basic_machine=i386-unknown
+ os=-bsd
+ ;;
+ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+ basic_machine=m68000-att
+ ;;
+ 3b*)
+ basic_machine=we32k-att
+ ;;
+ a29khif)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ adobe68k)
+ basic_machine=m68010-adobe
+ os=-scout
+ ;;
+ alliant | fx80)
+ basic_machine=fx80-alliant
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=-bsd
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=-sysv
+ ;;
+ amiga | amiga-*)
+ basic_machine=m68k-unknown
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-unknown
+ os=-amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-unknown
+ os=-sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=-sysv
+ ;;
+ apollo68bsd)
+ basic_machine=m68k-apollo
+ os=-bsd
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=-bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=-bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=-bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=-bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=-bsd
+ ;;
+ cray | ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ cray2)
+ basic_machine=cray2-cray
+ os=-unicos
+ ;;
+ [cjt]90)
+ basic_machine=${basic_machine}-cray
+ os=-unicos
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ ;;
+ cris | cris-* | etrax*)
+ basic_machine=cris-axis
+ ;;
+ da30 | da30-*)
+ basic_machine=m68k-da30
+ ;;
+ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ ;;
+ delta | 3300 | motorola-3300 | motorola-delta \
+ | 3300-motorola | delta-motorola)
+ basic_machine=m68k-motorola
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=-sysv3
+ ;;
+ dpx20 | dpx20-*)
+ basic_machine=rs6000-bull
+ os=-bosx
+ ;;
+ dpx2* | dpx2*-bull)
+ basic_machine=m68k-bull
+ os=-sysv3
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=-ebmon
+ ;;
+ elxsi)
+ basic_machine=elxsi-elxsi
+ os=-bsd
+ ;;
+ encore | umax | mmax)
+ basic_machine=ns32k-encore
+ ;;
+ es1800 | OSE68k | ose68k | ose | OSE)
+ basic_machine=m68k-ericsson
+ os=-ose
+ ;;
+ fx2800)
+ basic_machine=i860-alliant
+ ;;
+ genix)
+ basic_machine=ns32k-ns
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=-sysv
+ ;;
+ go32)
+ basic_machine=i386-pc
+ os=-go32
+ ;;
+ h3050r* | hiux*)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=-hms
+ ;;
+ h8300xray)
+ basic_machine=h8300-hitachi
+ os=-xray
+ ;;
+ h8500hms)
+ basic_machine=h8500-hitachi
+ os=-hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=-sysv3
+ ;;
+ hp300-*)
+ basic_machine=m68k-hp
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=-bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=-hpux
+ ;;
+ hp3k9[0-9][0-9] | hp9[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k2[0-9][0-9] | hp9k31[0-9])
+ basic_machine=m68000-hp
+ ;;
+ hp9k3[2-9][0-9])
+ basic_machine=m68k-hp
+ ;;
+ hp9k6[0-9][0-9] | hp6[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k7[0-79][0-9] | hp7[0-79][0-9])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k78[0-9] | hp78[0-9])
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][13679] | hp8[0-9][13679])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][0-9] | hp8[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hppa-next)
+ os=-nextstep3
+ ;;
+ hppaosf)
+ basic_machine=hppa1.1-hp
+ os=-osf
+ ;;
+ hppro)
+ basic_machine=hppa1.1-hp
+ os=-proelf
+ ;;
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ ;;
+# I'm not sure what "Sysv32" means. Should this be sysv3.2?
+ i*86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+ ;;
+ i*86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv4
+ ;;
+ i*86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv
+ ;;
+ i*86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-solaris2
+ ;;
+ i386mach)
+ basic_machine=i386-mach
+ os=-mach
+ ;;
+ i386-vsta | vsta)
+ basic_machine=i386-unknown
+ os=-vsta
+ ;;
+ iris | iris4d)
+ basic_machine=mips-sgi
+ case $os in
+ -irix*)
+ ;;
+ *)
+ os=-irix4
+ ;;
+ esac
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
+ m88k-omron*)
+ basic_machine=m88k-omron
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ mingw32)
+ basic_machine=i386-pc
+ os=-mingw32
+ ;;
+ miniframe)
+ basic_machine=m68000-convergent
+ ;;
+ *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+ mipsel*-linux*)
+ basic_machine=mipsel-unknown
+ os=-linux-gnu
+ ;;
+ mips*-linux*)
+ basic_machine=mips-unknown
+ os=-linux-gnu
+ ;;
+ mips3*-*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ ;;
+ mips3*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+ ;;
+ mmix*)
+ basic_machine=mmix-knuth
+ os=-mmixware
+ ;;
+ monitor)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ msdos)
+ basic_machine=i386-pc
+ os=-msdos
+ ;;
+ mvs)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+ ;;
+ netbsd386)
+ basic_machine=i386-unknown
+ os=-netbsd
+ ;;
+ netwinder)
+ basic_machine=armv4l-rebel
+ os=-linux
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=-newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=-newsos
+ ;;
+ news-3600 | risc-news)
+ basic_machine=mips-sony
+ os=-newsos
+ ;;
+ necv70)
+ basic_machine=v70-nec
+ os=-sysv
+ ;;
+ next | m*-next )
+ basic_machine=m68k-next
+ case $os in
+ -nextstep* )
+ ;;
+ -ns2*)
+ os=-nextstep2
+ ;;
+ *)
+ os=-nextstep3
+ ;;
+ esac
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=-cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=-cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=-nindy
+ ;;
+ mon960)
+ basic_machine=i960-intel
+ os=-mon960
+ ;;
+ nonstopux)
+ basic_machine=mips-compaq
+ os=-nonstopux
+ ;;
+ np1)
+ basic_machine=np1-gould
+ ;;
+ nsr-tandem)
+ basic_machine=nsr-tandem
+ ;;
+ op50n-* | op60c-*)
+ basic_machine=hppa1.1-oki
+ os=-proelf
+ ;;
+ OSE68000 | ose68000)
+ basic_machine=m68000-ericsson
+ os=-ose
+ ;;
+ os68k)
+ basic_machine=m68k-none
+ os=-os68k
+ ;;
+ pa-hitachi)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=-osf
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ pentium | p5 | k5 | k6 | nexgen)
+ basic_machine=i586-pc
+ ;;
+ pentiumpro | p6 | 6x86 | athlon)
+ basic_machine=i686-pc
+ ;;
+ pentiumii | pentium2)
+ basic_machine=i686-pc
+ ;;
+ pentium-* | p5-* | k5-* | k6-* | nexgen-*)
+ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-* | 6x86-* | athlon-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumii-* | pentium2-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pn)
+ basic_machine=pn-gould
+ ;;
+ power) basic_machine=power-ibm
+ ;;
+ ppc) basic_machine=powerpc-unknown
+ ;;
+ ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle | ppc-le | powerpc-little)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+ basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ps2)
+ basic_machine=i386-ibm
+ ;;
+ pw32)
+ basic_machine=i586-unknown
+ os=-pw32
+ ;;
+ rom68k)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ rm[46]00)
+ basic_machine=mips-siemens
+ ;;
+ rtpc | rtpc-*)
+ basic_machine=romp-ibm
+ ;;
+ sa29200)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh)
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
+ sparclite-wrs)
+ basic_machine=sparclite-wrs
+ os=-vxworks
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=-sysv2
+ ;;
+ spur)
+ basic_machine=spur-unknown
+ ;;
+ st2000)
+ basic_machine=m68k-tandem
+ ;;
+ stratus)
+ basic_machine=i860-stratus
+ os=-sysv4
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=-sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=-sunos4
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=-sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=-sunos4
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=-sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=-sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=-solaris2
+ ;;
+ sun3 | sun3-*)
+ basic_machine=m68k-sun
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ ;;
+ sv1)
+ basic_machine=sv1-cray
+ os=-unicos
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=-dynix
+ ;;
+ t3e)
+ basic_machine=t3e-cray
+ os=-unicos
+ ;;
+ tic54x | c54x*)
+ basic_machine=tic54x-unknown
+ os=-coff
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
+ tower | tower-32)
+ basic_machine=m68k-ncr
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=-sym1
+ ;;
+ v810 | necv810)
+ basic_machine=v810-nec
+ os=-none
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=-sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=-vms
+ ;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=-vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=-vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ w65*)
+ basic_machine=w65-wdc
+ os=-none
+ ;;
+ w89k-*)
+ basic_machine=hppa1.1-winbond
+ os=-proelf
+ ;;
+ xmp)
+ basic_machine=xmp-cray
+ os=-unicos
+ ;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
+ z8k-*-coff)
+ basic_machine=z8k-unknown
+ os=-sim
+ ;;
+ none)
+ basic_machine=none-none
+ os=-none
+ ;;
+
+# Here we handle the default manufacturer of certain CPU types. It is in
+# some cases the only manufacturer, in others, it is the most popular.
+ w89k)
+ basic_machine=hppa1.1-winbond
+ ;;
+ op50n)
+ basic_machine=hppa1.1-oki
+ ;;
+ op60c)
+ basic_machine=hppa1.1-oki
+ ;;
+ mips)
+ if [ x$os = x-linux-gnu ]; then
+ basic_machine=mips-unknown
+ else
+ basic_machine=mips-mips
+ fi
+ ;;
+ romp)
+ basic_machine=romp-ibm
+ ;;
+ rs6000)
+ basic_machine=rs6000-ibm
+ ;;
+ vax)
+ basic_machine=vax-dec
+ ;;
+ pdp10)
+ # there are many clones, so DEC is not a safe bet
+ basic_machine=pdp10-unknown
+ ;;
+ pdp11)
+ basic_machine=pdp11-dec
+ ;;
+ we32k)
+ basic_machine=we32k-att
+ ;;
+ sh3 | sh4)
+ basic_machine=sh-unknown
+ ;;
+ sparc | sparcv9 | sparcv9b)
+ basic_machine=sparc-sun
+ ;;
+ cydra)
+ basic_machine=cydra-cydrome
+ ;;
+ orion)
+ basic_machine=orion-highlevel
+ ;;
+ orion105)
+ basic_machine=clipper-highlevel
+ ;;
+ mac | mpw | mac-mpw)
+ basic_machine=m68k-apple
+ ;;
+ pmac | pmac-mpw)
+ basic_machine=powerpc-apple
+ ;;
+ c4x*)
+ basic_machine=c4x-none
+ os=-coff
+ ;;
+ *-unknown)
+ # Make sure to match an already-canonicalized machine name.
+ ;;
+ *)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+ *-digital*)
+ basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+ ;;
+ *-commodore*)
+ basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ ;;
+ *)
+ ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+ # First match some system type aliases
+ # that might get confused with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -svr4*)
+ os=-sysv4
+ ;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ ;;
+ # First accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST END IN A *, to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+ | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
+ | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
+ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* | -os2*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -qnx*)
+ case $basic_machine in
+ x86-* | i*86-*)
+ ;;
+ *)
+ os=-nto$os
+ ;;
+ esac
+ ;;
+ -nto*)
+ os=-nto-qnx
+ ;;
+ -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+ | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
+ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+ ;;
+ -mac*)
+ os=`echo $os | sed -e 's|mac|macos|'`
+ ;;
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
+ -sunos5*)
+ os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ ;;
+ -sunos6*)
+ os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ ;;
+ -opened*)
+ os=-openedition
+ ;;
+ -wince*)
+ os=-wince
+ ;;
+ -osfrose*)
+ os=-osfrose
+ ;;
+ -osf*)
+ os=-osf
+ ;;
+ -utek*)
+ os=-bsd
+ ;;
+ -dynix*)
+ os=-bsd
+ ;;
+ -acis*)
+ os=-aos
+ ;;
+ -386bsd)
+ os=-bsd
+ ;;
+ -ctix* | -uts*)
+ os=-sysv
+ ;;
+ -ns2 )
+ os=-nextstep2
+ ;;
+ -nsk*)
+ os=-nsk
+ ;;
+ # Preserve the version number of sinix5.
+ -sinix5.*)
+ os=`echo $os | sed -e 's|sinix|sysv|'`
+ ;;
+ -sinix*)
+ os=-sysv4
+ ;;
+ -triton*)
+ os=-sysv3
+ ;;
+ -oss*)
+ os=-sysv3
+ ;;
+ -svr4)
+ os=-sysv4
+ ;;
+ -svr3)
+ os=-sysv3
+ ;;
+ -sysvr4)
+ os=-sysv4
+ ;;
+ # This must come after -sysvr4.
+ -sysv*)
+ ;;
+ -ose*)
+ os=-ose
+ ;;
+ -es1800*)
+ os=-ose
+ ;;
+ -xenix)
+ os=-xenix
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ os=-mint
+ ;;
+ -none)
+ ;;
+ *)
+ # Get rid of the `-' at the beginning of $os.
+ os=`echo $os | sed 's/[^-]*-//'`
+ echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system. Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-rebel)
+ os=-linux
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
+ pdp10-*)
+ os=-tops20
+ ;;
+ pdp11-*)
+ os=-none
+ ;;
+ *-dec | vax-*)
+ os=-ultrix4.2
+ ;;
+ m68*-apollo)
+ os=-domain
+ ;;
+ i386-sun)
+ os=-sunos4.0.2
+ ;;
+ m68000-sun)
+ os=-sunos3
+ # This also exists in the configure program, but was not the
+ # default.
+ # os=-sunos4
+ ;;
+ m68*-cisco)
+ os=-aout
+ ;;
+ mips*-cisco)
+ os=-elf
+ ;;
+ mips*-*)
+ os=-elf
+ ;;
+ *-tti) # must be before sparc entry or we get the wrong os.
+ os=-sysv3
+ ;;
+ sparc-* | *-sun)
+ os=-sunos4.1.1
+ ;;
+ *-be)
+ os=-beos
+ ;;
+ *-ibm)
+ os=-aix
+ ;;
+ *-wec)
+ os=-proelf
+ ;;
+ *-winbond)
+ os=-proelf
+ ;;
+ *-oki)
+ os=-proelf
+ ;;
+ *-hp)
+ os=-hpux
+ ;;
+ *-hitachi)
+ os=-hiux
+ ;;
+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+ os=-sysv
+ ;;
+ *-cbm)
+ os=-amigaos
+ ;;
+ *-dg)
+ os=-dgux
+ ;;
+ *-dolphin)
+ os=-sysv3
+ ;;
+ m68k-ccur)
+ os=-rtu
+ ;;
+ m88k-omron*)
+ os=-luna
+ ;;
+ *-next )
+ os=-nextstep
+ ;;
+ *-sequent)
+ os=-ptx
+ ;;
+ *-crds)
+ os=-unos
+ ;;
+ *-ns)
+ os=-genix
+ ;;
+ i370-*)
+ os=-mvs
+ ;;
+ *-next)
+ os=-nextstep3
+ ;;
+ *-gould)
+ os=-sysv
+ ;;
+ *-highlevel)
+ os=-bsd
+ ;;
+ *-encore)
+ os=-bsd
+ ;;
+ *-sgi)
+ os=-irix
+ ;;
+ *-siemens)
+ os=-sysv4
+ ;;
+ *-masscomp)
+ os=-rtu
+ ;;
+ f30[01]-fujitsu | f700-fujitsu)
+ os=-uxpv
+ ;;
+ *-rom68k)
+ os=-coff
+ ;;
+ *-*bug)
+ os=-coff
+ ;;
+ *-apple)
+ os=-macos
+ ;;
+ *-atari*)
+ os=-mint
+ ;;
+ *)
+ os=-none
+ ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer. We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+ *-unknown)
+ case $os in
+ -riscix*)
+ vendor=acorn
+ ;;
+ -sunos*)
+ vendor=sun
+ ;;
+ -aix*)
+ vendor=ibm
+ ;;
+ -beos*)
+ vendor=be
+ ;;
+ -hpux*)
+ vendor=hp
+ ;;
+ -mpeix*)
+ vendor=hp
+ ;;
+ -hiux*)
+ vendor=hitachi
+ ;;
+ -unos*)
+ vendor=crds
+ ;;
+ -dgux*)
+ vendor=dg
+ ;;
+ -luna*)
+ vendor=omron
+ ;;
+ -genix*)
+ vendor=ns
+ ;;
+ -mvs* | -opened*)
+ vendor=ibm
+ ;;
+ -ptx*)
+ vendor=sequent
+ ;;
+ -vxsim* | -vxworks*)
+ vendor=wrs
+ ;;
+ -aux*)
+ vendor=apple
+ ;;
+ -hms*)
+ vendor=hitachi
+ ;;
+ -mpw* | -macos*)
+ vendor=apple
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ vendor=atari
+ ;;
+ esac
+ basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ ;;
+esac
+
+echo $basic_machine$os
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/src/native/unix/support/install.sh b/src/native/unix/support/install.sh
new file mode 100644
index 0000000..398a88e
--- /dev/null
+++ b/src/native/unix/support/install.sh
@@ -0,0 +1,251 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission. M.I.T. makes no representations about the
+# suitability of this software for any purpose. It is provided "as is"
+# without express or implied warranty.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch. It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+ case $1 in
+ -c) instcmd="$cpprog"
+ shift
+ continue;;
+
+ -d) dir_arg=true
+ shift
+ continue;;
+
+ -m) chmodcmd="$chmodprog $2"
+ shift
+ shift
+ continue;;
+
+ -o) chowncmd="$chownprog $2"
+ shift
+ shift
+ continue;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift
+ shift
+ continue;;
+
+ -s) stripcmd="$stripprog"
+ shift
+ continue;;
+
+ -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+ shift
+ continue;;
+
+ -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+ shift
+ continue;;
+
+ *) if [ x"$src" = x ]
+ then
+ src=$1
+ else
+ # this colon is to work around a 386BSD /bin/sh bug
+ :
+ dst=$1
+ fi
+ shift
+ continue;;
+ esac
+done
+
+if [ x"$src" = x ]
+then
+ echo "install: no input file specified"
+ exit 1
+else
+ :
+fi
+
+if [ x"$dir_arg" != x ]; then
+ dst=$src
+ src=""
+
+ if [ -d $dst ]; then
+ instcmd=:
+ chmodcmd=""
+ else
+ instcmd=$mkdirprog
+ fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad
+# if $src (and thus $dsttmp) contains '*'.
+
+ if [ -f $src -o -d $src ]
+ then
+ :
+ else
+ echo "install: $src does not exist"
+ exit 1
+ fi
+
+ if [ x"$dst" = x ]
+ then
+ echo "install: no destination specified"
+ exit 1
+ else
+ :
+ fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+ if [ -d $dst ]
+ then
+ dst="$dst"/`basename $src`
+ else
+ :
+ fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+# this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='
+ '
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+ pathcomp="${pathcomp}${1}"
+ shift
+
+ if [ ! -d "${pathcomp}" ] ;
+ then
+ $mkdirprog "${pathcomp}"
+ else
+ :
+ fi
+
+ pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+ $doit $instcmd $dst &&
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else : ; fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else : ; fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else : ; fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else : ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+ if [ x"$transformarg" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ dstfile=`basename $dst $transformbasename |
+ sed $transformarg`$transformbasename
+ fi
+
+# don't allow the sed command to completely eliminate the filename
+
+ if [ x"$dstfile" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ :
+ fi
+
+# Make a temp file name in the proper directory.
+
+ dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+ $doit $instcmd $src $dsttmp &&
+
+ trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing. If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else :;fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else :;fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else :;fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else :;fi &&
+
+# Now rename the file to the real destination.
+
+ $doit $rmcmd -f $dstdir/$dstfile &&
+ $doit $mvcmd $dsttmp $dstdir/$dstfile
+
+fi &&
+
+
+exit 0
diff --git a/src/samples/AloneDaemon.sh b/src/samples/AloneDaemon.sh
new file mode 100755
index 0000000..fe1320b
--- /dev/null
+++ b/src/samples/AloneDaemon.sh
@@ -0,0 +1,27 @@
+#!/bin/sh
+#
+# Small shell script to show how to start the sample services.
+# That is for linux, if your are using cygwin look to ServiceDaemon.sh.
+#
+# Adapt the following lines to your configuration
+JAVA_HOME=`echo $JAVA_HOME`
+DAEMON_HOME=`(cd ../..; pwd)`
+USER_HOME=`(cd ../../../..; pwd)`
+TOMCAT_USER=`echo $USER`
+CLASSPATH=\
+$DAEMON_HOME/dist/commons-daemon.jar:\
+$USER_HOME/commons-collections-2.1/commons-collections.jar:\
+$DAEMON_HOME/dist/aloneservice.jar
+
+$DAEMON_HOME/src/native/unix/jsvc \
+ -home $JAVA_HOME \
+ -cp $CLASSPATH \
+ -pidfile ./pidfile \
+ -debug \
+ AloneService
+#
+# To get a verbose JVM
+#-verbose \
+# To get a debug of jsvc.
+#-debug \
+# -user $TOMCAT_USER \
diff --git a/src/samples/AloneService.java b/src/samples/AloneService.java
new file mode 100644
index 0000000..179a332
--- /dev/null
+++ b/src/samples/AloneService.java
@@ -0,0 +1,168 @@
+/* ========================================================================= *
+ * *
+ * The Apache Software License, Version 1.1 *
+ * *
+ * Copyright (c) 1999-2001 The Apache Software Foundation. *
+ * All rights reserved. *
+ * *
+ * ========================================================================= *
+ * *
+ * Redistribution and use in source and binary forms, with or without modi- *
+ * fication, are permitted provided that the following conditions are met: *
+ * *
+ * 1. Redistributions of source code must retain the above copyright notice *
+ * notice, this list of conditions and the following disclaimer. *
+ * *
+ * 2. Redistributions in binary form must reproduce the above copyright *
+ * notice, this list of conditions and the following disclaimer in the *
+ * documentation and/or other materials provided with the distribution. *
+ * *
+ * 3. The end-user documentation included with the redistribution, if any, *
+ * must include the following acknowlegement: *
+ * *
+ * "This product includes software developed by the Apache Software *
+ * Foundation <http://www.apache.org/>." *
+ * *
+ * Alternately, this acknowlegement may appear in the software itself, if *
+ * and wherever such third-party acknowlegements normally appear. *
+ * *
+ * 4. The names "The Jakarta Project", "WebApp", and "Apache Software *
+ * Foundation" must not be used to endorse or promote products derived *
+ * from this software without prior written permission. For written *
+ * permission, please contact <apache at apache.org>. *
+ * *
+ * 5. Products derived from this software may not be called "Apache" nor may *
+ * "Apache" appear in their names without prior written permission of the *
+ * Apache Software Foundation. *
+ * *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES *
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY *
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL *
+ * THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY *
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL *
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS *
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) *
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, *
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN *
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
+ * POSSIBILITY OF SUCH DAMAGE. *
+ * *
+ * ========================================================================= *
+ * *
+ * This software consists of voluntary contributions made by many indivi- *
+ * duals on behalf of the Apache Software Foundation. For more information *
+ * on the Apache Software Foundation, please see <http://www.apache.org/>. *
+ * *
+ * ========================================================================= */
+
+/* @version $Id: AloneService.java,v 1.1 2003/09/27 15:45:02 jfclere Exp $ */
+
+import java.io.*;
+import java.net.*;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Enumeration;
+
+import org.apache.commons.collections.ExtendedProperties;
+import java.io.IOException;
+import java.util.Iterator;
+
+/*
+ * That is like the ServiceDaemon but it does used the interface.
+ */
+public class AloneService {
+
+ private ExtendedProperties prop = null;
+ private Process proc[] = null;
+ private ServiceDaemonReadThread readout[] = null;
+ private ServiceDaemonReadThread readerr[] = null;
+
+ protected void finalize() {
+ System.err.println("ServiceDaemon: instance "+this.hashCode()+
+ " garbage collected");
+ }
+
+ /**
+ * init and destroy were added in jakarta-tomcat-daemon.
+ */
+ public void init(String[] arguments)
+ throws Exception {
+ /* Set the err */
+ System.setErr(new PrintStream(new FileOutputStream(new File("/ServiceDaemon.err"),true)));
+ System.err.println("ServiceDaemon: instance "+this.hashCode()+
+ " init");
+
+ /* read the properties file */
+ prop = new ExtendedProperties("startfile");
+
+ /* create an array to store the processes */
+ int i=0;
+ for (Iterator e = prop.getKeys(); e.hasNext() ;) {
+ e.next();
+ i++;
+ }
+ System.err.println("ServiceDaemon: init for " + i + " processes");
+ proc = new Process[i];
+ readout = new ServiceDaemonReadThread[i];
+ readerr = new ServiceDaemonReadThread[i];
+ for (i=0;i<proc.length;i++) {
+ proc[i] = null;
+ readout[i] = null;
+ readerr[i] = null;
+ }
+
+ System.err.println("ServiceDaemon: init done ");
+
+ }
+
+ public void start() {
+ /* Dump a message */
+ System.err.println("ServiceDaemon: starting");
+
+ /* Start */
+ int i=0;
+ for (Iterator e = prop.getKeys(); e.hasNext() ;) {
+ String name = (String) e.next();
+ System.err.println("ServiceDaemon: starting: " + name + " : " + prop.getString(name));
+ try {
+ proc[i] = Runtime.getRuntime().exec(prop.getString(name));
+ } catch(Exception ex) {
+ System.err.println("Exception: " + ex);
+ }
+ /* Start threads to read from Error and Out streams */
+ readerr[i] =
+ new ServiceDaemonReadThread(proc[i].getErrorStream());
+ readout[i] =
+ new ServiceDaemonReadThread(proc[i].getInputStream());
+ readerr[i].start();
+ readout[i].start();
+ i++;
+ }
+ }
+
+ public void stop()
+ throws IOException, InterruptedException {
+ /* Dump a message */
+ System.err.println("ServiceDaemon: stopping");
+
+ for (int i=0;i<proc.length;i++) {
+ if ( proc[i]==null)
+ continue;
+ proc[i].destroy();
+ try {
+ proc[i].waitFor();
+ } catch(InterruptedException ex) {
+ System.err.println("ServiceDaemon: exception while stopping:" +
+ ex);
+ }
+ }
+
+ System.err.println("ServiceDaemon: stopped");
+ }
+
+ public void destroy() {
+ System.err.println("ServiceDaemon: instance "+this.hashCode()+
+ " destroy");
+ }
+
+}
diff --git a/src/samples/README.txt b/src/samples/README.txt
new file mode 100644
index 0000000..008c6df
--- /dev/null
+++ b/src/samples/README.txt
@@ -0,0 +1,37 @@
+The directory contains examples of java daemons.
+The examples are compiled using ant (just type ant). Each example creates a
+jar file in ../../dist
+
+SimpleDaemon:
+
+SimpleDaemon demonstrates the feature of the daemon ofered by
+jakarta-commons-sandbox/daemon.
+To run it adapt the SimpleDaemon.sh file and connect to it using:
+telnet localhost 1200
+Additional information in ../native/unix/INSTALL.txt
+
+ServiceDaemon:
+
+ServiceDaemon allows to start programs using the jakarta daemon.
+That could be usefull when using cygwin under win9x because cygwin only offers
+services support under win NT/2000/XP.
+(See in ../native/nt/README how to install jsvc as a service in win32).
+
+It uses jakarta Commons Collections:
+http://jakarta.apache.org/commons/collections.html
+To use it you need at least commons-collections-1.0
+
+You have to create a file named startfile that uses a property format:
+name = string to start the program
+
+For example:
+sshd=/usr/sbin/sshd -D
+router1=/home/Standard/router/router pop3 pop3.example.net
+router2=/home/Standard/router/smtp smtp.example.net
+socks5=/usr/local/bin/socks5 -f
+
+To run it adapt the ServiceDaemon.sh file.
+
+AloneService:
+
+AloneService is like ServiceDaemon except it does not use the Daemon interface.
diff --git a/src/samples/ServiceDaemon.java b/src/samples/ServiceDaemon.java
new file mode 100644
index 0000000..766420a
--- /dev/null
+++ b/src/samples/ServiceDaemon.java
@@ -0,0 +1,174 @@
+/* ========================================================================= *
+ * *
+ * The Apache Software License, Version 1.1 *
+ * *
+ * Copyright (c) 1999-2001 The Apache Software Foundation. *
+ * All rights reserved. *
+ * *
+ * ========================================================================= *
+ * *
+ * Redistribution and use in source and binary forms, with or without modi- *
+ * fication, are permitted provided that the following conditions are met: *
+ * *
+ * 1. Redistributions of source code must retain the above copyright notice *
+ * notice, this list of conditions and the following disclaimer. *
+ * *
+ * 2. Redistributions in binary form must reproduce the above copyright *
+ * notice, this list of conditions and the following disclaimer in the *
+ * documentation and/or other materials provided with the distribution. *
+ * *
+ * 3. The end-user documentation included with the redistribution, if any, *
+ * must include the following acknowlegement: *
+ * *
+ * "This product includes software developed by the Apache Software *
+ * Foundation <http://www.apache.org/>." *
+ * *
+ * Alternately, this acknowlegement may appear in the software itself, if *
+ * and wherever such third-party acknowlegements normally appear. *
+ * *
+ * 4. The names "The Jakarta Project", "WebApp", and "Apache Software *
+ * Foundation" must not be used to endorse or promote products derived *
+ * from this software without prior written permission. For written *
+ * permission, please contact <apache at apache.org>. *
+ * *
+ * 5. Products derived from this software may not be called "Apache" nor may *
+ * "Apache" appear in their names without prior written permission of the *
+ * Apache Software Foundation. *
+ * *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES *
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY *
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL *
+ * THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY *
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL *
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS *
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) *
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, *
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN *
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
+ * POSSIBILITY OF SUCH DAMAGE. *
+ * *
+ * ========================================================================= *
+ * *
+ * This software consists of voluntary contributions made by many indivi- *
+ * duals on behalf of the Apache Software Foundation. For more information *
+ * on the Apache Software Foundation, please see <http://www.apache.org/>. *
+ * *
+ * ========================================================================= */
+
+/* @version $Id: ServiceDaemon.java,v 1.1.1.1 2003/09/04 23:28:20 yoavs Exp $ */
+
+import java.io.*;
+import java.net.*;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Enumeration;
+import org.apache.commons.daemon.Daemon;
+import org.apache.commons.daemon.DaemonController;
+import org.apache.commons.daemon.DaemonContext;
+
+import org.apache.commons.collections.ExtendedProperties;
+import java.io.IOException;
+import java.util.Iterator;
+
+public class ServiceDaemon implements Daemon {
+
+ private ExtendedProperties prop = null;
+ private Process proc[] = null;
+ private ServiceDaemonReadThread readout[] = null;
+ private ServiceDaemonReadThread readerr[] = null;
+
+ public ServiceDaemon() {
+ super();
+ System.err.println("ServiceDaemon: instance "+this.hashCode()+
+ " created");
+ }
+
+ protected void finalize() {
+ System.err.println("ServiceDaemon: instance "+this.hashCode()+
+ " garbage collected");
+ }
+
+ /**
+ * init and destroy were added in jakarta-tomcat-daemon.
+ */
+ public void init(DaemonContext context)
+ throws Exception {
+ /* Set the err */
+ System.setErr(new PrintStream(new FileOutputStream(new File("ServiceDaemon.err")),true));
+ System.err.println("ServiceDaemon: instance "+this.hashCode()+
+ " init");
+
+ /* read the properties file */
+ prop = new ExtendedProperties("startfile");
+
+ /* create an array to store the processes */
+ int i=0;
+ for (Iterator e = prop.getKeys(); e.hasNext() ;) {
+ e.next();
+ i++;
+ }
+ System.err.println("ServiceDaemon: init for " + i + " processes");
+ proc = new Process[i];
+ readout = new ServiceDaemonReadThread[i];
+ readerr = new ServiceDaemonReadThread[i];
+ for (i=0;i<proc.length;i++) {
+ proc[i] = null;
+ readout[i] = null;
+ readerr[i] = null;
+ }
+
+ System.err.println("ServiceDaemon: init done ");
+
+ }
+
+ public void start() {
+ /* Dump a message */
+ System.err.println("ServiceDaemon: starting");
+
+ /* Start */
+ int i=0;
+ for (Iterator e = prop.getKeys(); e.hasNext() ;) {
+ String name = (String) e.next();
+ System.err.println("ServiceDaemon: starting: " + name + " : " + prop.getString(name));
+ try {
+ proc[i] = Runtime.getRuntime().exec(prop.getString(name));
+ } catch(Exception ex) {
+ System.err.println("Exception: " + ex);
+ }
+ /* Start threads to read from Error and Out streams */
+ readerr[i] =
+ new ServiceDaemonReadThread(proc[i].getErrorStream());
+ readout[i] =
+ new ServiceDaemonReadThread(proc[i].getInputStream());
+ readerr[i].start();
+ readout[i].start();
+ i++;
+ }
+ }
+
+ public void stop()
+ throws IOException, InterruptedException {
+ /* Dump a message */
+ System.err.println("ServiceDaemon: stopping");
+
+ for (int i=0;i<proc.length;i++) {
+ if ( proc[i]==null)
+ continue;
+ proc[i].destroy();
+ try {
+ proc[i].waitFor();
+ } catch(InterruptedException ex) {
+ System.err.println("ServiceDaemon: exception while stopping:" +
+ ex);
+ }
+ }
+
+ System.err.println("ServiceDaemon: stopped");
+ }
+
+ public void destroy() {
+ System.err.println("ServiceDaemon: instance "+this.hashCode()+
+ " destroy");
+ }
+
+}
diff --git a/src/samples/ServiceDaemon.sh b/src/samples/ServiceDaemon.sh
new file mode 100755
index 0000000..ae1d960
--- /dev/null
+++ b/src/samples/ServiceDaemon.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+#
+# Small shell script to show how to start the sample services.
+#
+# Adapt the following lines to your configuration
+JAVA_HOME=/cygdrive/c/jdk1.3.1_02
+HOME=c:\\cygwin\\home\\Standard
+DAEMON_HOME=$HOME\\jakarta-commons-sandbox\\daemon
+DAEMON_HOME_SH=/home/Standard/jakarta-commons-sandbox/daemon
+TOMCAT_USER=jakarta
+CLASSPATH=\
+$DAEMON_HOME\\dist\\commons-daemon.jar\;\
+$HOME\\commons-collections-1.0\\commons-collections.jar\;\
+$DAEMON_HOME\\dist\\Service.jar
+
+$DAEMON_HOME_SH/dist/jsvc \
+ -home $JAVA_HOME \
+ -cp $CLASSPATH \
+ ServiceDaemon
+#
+# To get a verbose JVM
+#-verbose \
+# To get a debug of jsvc.
+#-debug \
+# -user $TOMCAT_USER \
diff --git a/src/samples/ServiceDaemonReadThread.java b/src/samples/ServiceDaemonReadThread.java
new file mode 100644
index 0000000..7390ec1
--- /dev/null
+++ b/src/samples/ServiceDaemonReadThread.java
@@ -0,0 +1,83 @@
+
+/* ========================================================================= *
+ * *
+ * The Apache Software License, Version 1.1 *
+ * *
+ * Copyright (c) 1999-2001 The Apache Software Foundation. *
+ * All rights reserved. *
+ * *
+ * ========================================================================= *
+ * *
+ * Redistribution and use in source and binary forms, with or without modi- *
+ * fication, are permitted provided that the following conditions are met: *
+ * *
+ * 1. Redistributions of source code must retain the above copyright notice *
+ * notice, this list of conditions and the following disclaimer. *
+ * *
+ * 2. Redistributions in binary form must reproduce the above copyright *
+ * notice, this list of conditions and the following disclaimer in the *
+ * documentation and/or other materials provided with the distribution. *
+ * *
+ * 3. The end-user documentation included with the redistribution, if any, *
+ * must include the following acknowlegement: *
+ * *
+ * "This product includes software developed by the Apache Software *
+ * Foundation <http://www.apache.org/>." *
+ * *
+ * Alternately, this acknowlegement may appear in the software itself, if *
+ * and wherever such third-party acknowlegements normally appear. *
+ * *
+ * 4. The names "The Jakarta Project", "WebApp", and "Apache Software *
+ * Foundation" must not be used to endorse or promote products derived *
+ * from this software without prior written permission. For written *
+ * permission, please contact <apache at apache.org>. *
+ * *
+ * 5. Products derived from this software may not be called "Apache" nor may *
+ * "Apache" appear in their names without prior written permission of the *
+ * Apache Software Foundation. *
+ * *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES *
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY *
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL *
+ * THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY *
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL *
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS *
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) *
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, *
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN *
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
+ * POSSIBILITY OF SUCH DAMAGE. *
+ * *
+ * ========================================================================= *
+ * *
+ * This software consists of voluntary contributions made by many indivi- *
+ * duals on behalf of the Apache Software Foundation. For more information *
+ * on the Apache Software Foundation, please see <http://www.apache.org/>. *
+ * *
+ * ========================================================================= */
+
+/* @version $Id: ServiceDaemonReadThread.java,v 1.1.1.1 2003/09/04 23:28:20 yoavs Exp $ */
+import java.io.InputStream;
+import java.io.IOException;
+import java.lang.Thread;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+
+public class ServiceDaemonReadThread extends Thread {
+ private BufferedReader in;
+ ServiceDaemonReadThread(InputStream in) {
+ this.in = new BufferedReader(new InputStreamReader(in));
+ }
+ public void run() {
+ String buff;
+ for (;;) {
+ try {
+ buff = in.readLine();
+ if (buff == null) break;
+ System.err.print(in.readLine());
+ } catch (IOException ex) {
+ break; // Exit thread.
+ }
+ }
+ }
+}
diff --git a/src/samples/SimpleDaemon.java b/src/samples/SimpleDaemon.java
new file mode 100644
index 0000000..b25808b
--- /dev/null
+++ b/src/samples/SimpleDaemon.java
@@ -0,0 +1,342 @@
+/* ========================================================================= *
+ * *
+ * The Apache Software License, Version 1.1 *
+ * *
+ * Copyright (c) 1999-2001 The Apache Software Foundation. *
+ * All rights reserved. *
+ * *
+ * ========================================================================= *
+ * *
+ * Redistribution and use in source and binary forms, with or without modi- *
+ * fication, are permitted provided that the following conditions are met: *
+ * *
+ * 1. Redistributions of source code must retain the above copyright notice *
+ * notice, this list of conditions and the following disclaimer. *
+ * *
+ * 2. Redistributions in binary form must reproduce the above copyright *
+ * notice, this list of conditions and the following disclaimer in the *
+ * documentation and/or other materials provided with the distribution. *
+ * *
+ * 3. The end-user documentation included with the redistribution, if any, *
+ * must include the following acknowlegement: *
+ * *
+ * "This product includes software developed by the Apache Software *
+ * Foundation <http://www.apache.org/>." *
+ * *
+ * Alternately, this acknowlegement may appear in the software itself, if *
+ * and wherever such third-party acknowlegements normally appear. *
+ * *
+ * 4. The names "The Jakarta Project", "WebApp", and "Apache Software *
+ * Foundation" must not be used to endorse or promote products derived *
+ * from this software without prior written permission. For written *
+ * permission, please contact <apache at apache.org>. *
+ * *
+ * 5. Products derived from this software may not be called "Apache" nor may *
+ * "Apache" appear in their names without prior written permission of the *
+ * Apache Software Foundation. *
+ * *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES *
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY *
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL *
+ * THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY *
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL *
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS *
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) *
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, *
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN *
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
+ * POSSIBILITY OF SUCH DAMAGE. *
+ * *
+ * ========================================================================= *
+ * *
+ * This software consists of voluntary contributions made by many indivi- *
+ * duals on behalf of the Apache Software Foundation. For more information *
+ * on the Apache Software Foundation, please see <http://www.apache.org/>. *
+ * *
+ * ========================================================================= */
+
+/* @version $Id: SimpleDaemon.java,v 1.1.1.1 2003/09/04 23:28:20 yoavs Exp $ */
+
+import java.io.*;
+import java.net.*;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Vector;
+import org.apache.commons.daemon.Daemon;
+import org.apache.commons.daemon.DaemonController;
+import org.apache.commons.daemon.DaemonContext;
+
+public class SimpleDaemon implements Daemon, Runnable {
+
+ private ServerSocket server=null;
+ private Thread thread=null;
+ private DaemonController controller=null;
+ private boolean stopping=false;
+ private String directory=null;
+ private Vector handlers=null;
+
+ public SimpleDaemon() {
+ super();
+ System.err.println("SimpleDaemon: instance "+this.hashCode()+
+ " created");
+ this.handlers=new Vector();
+ }
+
+ protected void finalize() {
+ System.err.println("SimpleDaemon: instance "+this.hashCode()+
+ " garbage collected");
+ }
+
+ /**
+ * init and destroy were added in jakarta-tomcat-daemon.
+ */
+ public void init(DaemonContext context)
+ throws Exception {
+ System.err.println("SimpleDaemon: instance "+this.hashCode()+
+ " init");
+
+ int port=1200;
+
+ String[] a = context.getArguments();
+
+ if (a.length>0) port=Integer.parseInt(a[0]);
+ if (a.length>1) this.directory=a[1];
+ else this.directory="/tmp";
+
+ /* Dump a message */
+ System.err.println("SimpleDaemon: loading on port "+port);
+
+ /* Set up this simple daemon */
+ this.controller=context.getController();
+ this.server=new ServerSocket(port);
+ this.thread=new Thread(this);
+ }
+
+ public void start() {
+ /* Dump a message */
+ System.err.println("SimpleDaemon: starting");
+
+ /* Start */
+ this.thread.start();
+ }
+
+ public void stop()
+ throws IOException, InterruptedException {
+ /* Dump a message */
+ System.err.println("SimpleDaemon: stopping");
+
+ /* Close the ServerSocket. This will make our thread to terminate */
+ this.stopping=true;
+ this.server.close();
+
+ /* Wait for the main thread to exit and dump a message */
+ this.thread.join(5000);
+ System.err.println("SimpleDaemon: stopped");
+ }
+
+ public void destroy() {
+ System.err.println("SimpleDaemon: instance "+this.hashCode()+
+ " destroy");
+ }
+
+ public void run() {
+ int number=0;
+
+ System.err.println("SimpleDaemon: started acceptor loop");
+ try {
+ while(!this.stopping) {
+ Socket socket=this.server.accept();
+ Handler handler=new Handler(socket,this,this.controller);
+ handler.setConnectionNumber(number++);
+ handler.setDirectoryName(this.directory);
+ new Thread(handler).start();
+ }
+ } catch (IOException e) {
+ /* Don't dump any error message if we are stopping. A IOException
+ is generated when the ServerSocket is closed in stop() */
+ if (!this.stopping) e.printStackTrace(System.err);
+ }
+
+ /* Terminate all handlers that at this point are still open */
+ Enumeration openhandlers=this.handlers.elements();
+ while (openhandlers.hasMoreElements()) {
+ Handler handler=(Handler)openhandlers.nextElement();
+ System.err.println("SimpleDaemon: dropping connection "+
+ handler.getConnectionNumber());
+ handler.close();
+ }
+
+ System.err.println("SimpleDaemon: exiting acceptor loop");
+ }
+
+ protected void addHandler(Handler handler) {
+ synchronized (handler) {
+ this.handlers.add(handler);
+ }
+ }
+
+ protected void removeHandler(Handler handler) {
+ synchronized (handler) {
+ this.handlers.remove(handler);
+ }
+ }
+
+ public static class Handler implements Runnable {
+
+ private DaemonController controller=null;
+ private SimpleDaemon parent=null;
+ private String directory=null;
+ private Socket socket=null;
+ private int number=0;
+
+ public Handler(Socket s, SimpleDaemon p, DaemonController c) {
+ super();
+ this.socket=s;
+ this.parent=p;
+ this.controller=c;
+ }
+
+ public void run() {
+ this.parent.addHandler(this);
+ System.err.println("SimpleDaemon: connection "+this.number+
+ " opened from "+this.socket.getInetAddress());
+ try {
+ InputStream in=this.socket.getInputStream();
+ OutputStream out=this.socket.getOutputStream();
+ handle(in,out);
+ this.socket.close();
+ } catch (IOException e) {
+ e.printStackTrace(System.err);
+ }
+ System.err.println("SimpleDaemon: connection "+this.number+
+ " closed");
+ this.parent.removeHandler(this);
+ }
+
+ public void close() {
+ try {
+ this.socket.close();
+ } catch (IOException e) {
+ e.printStackTrace(System.err);
+ }
+ }
+
+ public void setConnectionNumber(int number) {
+ this.number=number;
+ }
+
+ public int getConnectionNumber() {
+ return(this.number);
+ }
+
+ public void setDirectoryName(String directory) {
+ this.directory=directory;
+ }
+
+ public String getDirectoryName() {
+ return(this.directory);
+ }
+
+ public void log(String name)
+ throws IOException {
+ OutputStream file=new FileOutputStream(name,true);
+ PrintStream out=new PrintStream(file);
+ SimpleDateFormat fmt=new SimpleDateFormat();
+
+ out.println(fmt.format(new Date()));
+ out.close();
+ file.close();
+ }
+
+ public void handle(InputStream in, OutputStream os) {
+ PrintStream out=new PrintStream(os);
+
+ while(true) {
+ try {
+ /* If we don't have data in the System InputStream, we want
+ to ask to the user for an option. */
+ if (in.available()==0) {
+ out.println();
+ out.println("Please select one of the following:");
+ out.println(" 1) Shutdown");
+ out.println(" 2) Reload");
+ out.println(" 3) Create a file");
+ out.println(" 4) Disconnect");
+ out.print("Your choiche: ");
+ }
+
+ /* Read an option from the client */
+ int x=in.read();
+
+ switch (x) {
+ /* If the socket was closed, we simply return */
+ case -1:
+ return;
+
+ /* Attempt to shutdown */
+ case '1':
+ out.println("Attempting a shutdown...");
+ try {
+ this.controller.shutdown();
+ } catch (IllegalStateException e) {
+ out.println();
+ out.println("Can't shutdown now");
+ e.printStackTrace(out);
+ }
+ break;
+
+ /* Attempt to reload */
+ case '2':
+ out.println("Attempting a reload...");
+ try {
+ this.controller.reload();
+ } catch (IllegalStateException e) {
+ out.println();
+ out.println("Can't reload now");
+ e.printStackTrace(out);
+ }
+ break;
+
+ /* Disconnect */
+ case '3':
+ String name=this.getDirectoryName()+
+ "/SimpleDaemon."+
+ this.getConnectionNumber()+
+ ".tmp";
+ try {
+ this.log(name);
+ out.println("File '"+name+"' created");
+ } catch (IOException e) {
+ e.printStackTrace(out);
+ }
+ break;
+
+ /* Disconnect */
+ case '4':
+ out.println("Disconnecting...");
+ return;
+
+ /* Discard any carriage return / newline characters */
+ case '\r':
+ case '\n':
+ break;
+
+ /* We got something that we weren't supposed to get */
+ default:
+ out.println("Unknown option '"+(char)x+"'");
+ break;
+
+ }
+
+ /* If we get an IOException we return (disconnect) */
+ } catch (IOException e) {
+ System.err.println("SimpleDaemon: IOException in "+
+ "connection "+
+ this.getConnectionNumber());
+ return;
+ }
+ }
+ }
+ }
+}
diff --git a/src/samples/SimpleDaemon.sh b/src/samples/SimpleDaemon.sh
new file mode 100755
index 0000000..941792d
--- /dev/null
+++ b/src/samples/SimpleDaemon.sh
@@ -0,0 +1,23 @@
+#!/bin/sh
+#
+# Small shell script to show how to start the sample services.
+#
+# Adapt the following lines to your configuration
+JAVA_HOME=`echo $JAVA_HOME`
+DAEMON_HOME=`(cd ../..; pwd)`
+TOMCAT_USER=`echo $USER`
+CLASSPATH=\
+$DAEMON_HOME/dist/commons-daemon.jar:\
+$DAEMON_HOME/dist/SimpleDaemon.jar
+
+$DAEMON_HOME/src/native/unix/jsvc \
+ -user $TOMCAT_USER \
+ -home $JAVA_HOME \
+ -cp $CLASSPATH \
+ -pidfile ./pidfile \
+ SimpleDaemon \
+#
+# To get a verbose JVM
+#-verbose \
+# To get a debug of jsvc.
+#-debug \
diff --git a/src/samples/build.xml b/src/samples/build.xml
new file mode 100644
index 0000000..1d5a90f
--- /dev/null
+++ b/src/samples/build.xml
@@ -0,0 +1,75 @@
+<project name="daemons samples" default="jars" basedir=".">
+
+<!-- ========== Initialize Properties ===================================== -->
+ <property file="build.properties"/>
+ <property name="commons-daemon.jar" value="../../dist/commons-daemon.jar"/>
+ <property name="dist.home" value="../../dist"/>
+ <property name="build.home" value="./build"/>
+ <property name="source.home" value="."/>
+ <property name="commons-collections.jar" value="${user.home}/commons-collections-2.1/commons-collections.jar"/>
+
+ <target name="jars" depends="SimpleDaemon,ServiceDaemon,AloneService"/>
+
+ <target name="SimpleDaemon" depends="compile"
+ description="Create SimpleDaemon.jar">
+ <mkdir dir="${dist.home}"/>
+ <mkdir dir="${build.home}/classes/META-INF"/>
+ <copy file="../../../LICENSE"
+ tofile="${build.home}/classes/META-INF/LICENSE.txt"/>
+ <jar jarfile="${dist.home}/SimpleDaemon.jar">
+ <fileset dir="${build.home}/classes">
+ <include name="SimpleDaemon*.class" />
+ </fileset>
+ </jar>
+ </target>
+
+ <target name="ServiceDaemon" depends="compile"
+ description="Create ServiceDaemon.jar">
+ <mkdir dir="${dist.home}"/>
+ <mkdir dir="${build.home}/classes/META-INF"/>
+ <copy file="../../../LICENSE"
+ tofile="${build.home}/classes/META-INF/LICENSE.txt"/>
+ <jar jarfile="${dist.home}/service.jar">
+ <fileset dir="${build.home}/classes">
+ <include name="ServiceDaemon*.class" />
+ </fileset>
+ </jar>
+ </target>
+
+ <target name="AloneService" depends="compile"
+ description="Create aloneservice.jar">
+ <mkdir dir="${dist.home}"/>
+ <mkdir dir="${build.home}/classes/META-INF"/>
+ <copy file="../../../LICENSE"
+ tofile="${build.home}/classes/META-INF/LICENSE.txt"/>
+ <jar jarfile="${dist.home}/aloneservice.jar">
+ <fileset dir="${build.home}/classes">
+ <include name="AloneService*.class" />
+ <include name="ServiceDaemonReadThread*.class" />
+ </fileset>
+ </jar>
+ </target>
+
+ <target name="compile" depends="prepare"
+ description="Create class files">
+ <javac srcdir="${source.home}"
+ destdir="${build.home}/classes"
+ debug="${compile.debug}"
+ deprecation="${compile.deprecation}"
+ optimize="${compile.optimize}">
+ <classpath refid="compile.classpath"/>
+ </javac>
+ </target>
+
+ <target name="prepare">
+ <mkdir dir="${build.home}"/>
+ <mkdir dir="${build.home}/classes"/>
+ </target>
+
+ <!-- Construct compile classpath -->
+ <path id="compile.classpath">
+ <pathelement location="${commons-daemon.jar}"/>
+ <pathelement location="${commons-collections.jar}"/>
+ </path>
+
+</project>
diff --git a/src/test/org/apache/commons/daemon/SimpleDaemon.java b/src/test/org/apache/commons/daemon/SimpleDaemon.java
new file mode 100644
index 0000000..2065e87
--- /dev/null
+++ b/src/test/org/apache/commons/daemon/SimpleDaemon.java
@@ -0,0 +1,344 @@
+/* ========================================================================= *
+ * *
+ * The Apache Software License, Version 1.1 *
+ * *
+ * Copyright (c) 1999-2001 The Apache Software Foundation. *
+ * All rights reserved. *
+ * *
+ * ========================================================================= *
+ * *
+ * Redistribution and use in source and binary forms, with or without modi- *
+ * fication, are permitted provided that the following conditions are met: *
+ * *
+ * 1. Redistributions of source code must retain the above copyright notice *
+ * notice, this list of conditions and the following disclaimer. *
+ * *
+ * 2. Redistributions in binary form must reproduce the above copyright *
+ * notice, this list of conditions and the following disclaimer in the *
+ * documentation and/or other materials provided with the distribution. *
+ * *
+ * 3. The end-user documentation included with the redistribution, if any, *
+ * must include the following acknowlegement: *
+ * *
+ * "This product includes software developed by the Apache Software *
+ * Foundation <http://www.apache.org/>." *
+ * *
+ * Alternately, this acknowlegement may appear in the software itself, if *
+ * and wherever such third-party acknowlegements normally appear. *
+ * *
+ * 4. The names "The Jakarta Project", "WebApp", and "Apache Software *
+ * Foundation" must not be used to endorse or promote products derived *
+ * from this software without prior written permission. For written *
+ * permission, please contact <apache at apache.org>. *
+ * *
+ * 5. Products derived from this software may not be called "Apache" nor may *
+ * "Apache" appear in their names without prior written permission of the *
+ * Apache Software Foundation. *
+ * *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES *
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY *
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL *
+ * THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY *
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL *
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS *
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) *
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, *
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN *
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
+ * POSSIBILITY OF SUCH DAMAGE. *
+ * *
+ * ========================================================================= *
+ * *
+ * This software consists of voluntary contributions made by many indivi- *
+ * duals on behalf of the Apache Software Foundation. For more information *
+ * on the Apache Software Foundation, please see <http://www.apache.org/>. *
+ * *
+ * ========================================================================= */
+
+/* @version $Id: SimpleDaemon.java,v 1.1.1.1 2003/09/04 23:28:20 yoavs Exp $ */
+
+package org.apache.commons.daemon;
+
+import java.io.*;
+import java.net.*;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Vector;
+import org.apache.commons.daemon.Daemon;
+import org.apache.commons.daemon.DaemonController;
+import org.apache.commons.daemon.DaemonContext;
+
+public class SimpleDaemon implements Daemon, Runnable {
+
+ private ServerSocket server=null;
+ private Thread thread=null;
+ private DaemonController controller=null;
+ private boolean stopping=false;
+ private String directory=null;
+ private Vector handlers=null;
+
+ public SimpleDaemon() {
+ super();
+ System.err.println("SimpleDaemon: instance "+this.hashCode()+
+ " created");
+ this.handlers=new Vector();
+ }
+
+ protected void finalize() {
+ System.err.println("SimpleDaemon: instance "+this.hashCode()+
+ " garbage collected");
+ }
+
+ /**
+ * init and destroy were added in jakarta-tomcat-daemon.
+ */
+ public void init(DaemonContext context)
+ throws Exception {
+ System.err.println("SimpleDaemon: instance "+this.hashCode()+
+ " init");
+
+ int port=1200;
+
+ String[] a = context.getArguments();
+
+ if (a.length>0) port=Integer.parseInt(a[0]);
+ if (a.length>1) this.directory=a[1];
+ else this.directory="/tmp";
+
+ /* Dump a message */
+ System.err.println("SimpleDaemon: loading on port "+port);
+
+ /* Set up this simple daemon */
+ this.controller=context.getController();
+ this.server=new ServerSocket(port);
+ this.thread=new Thread(this);
+ }
+
+ public void start() {
+ /* Dump a message */
+ System.err.println("SimpleDaemon: starting");
+
+ /* Start */
+ this.thread.start();
+ }
+
+ public void stop()
+ throws IOException, InterruptedException {
+ /* Dump a message */
+ System.err.println("SimpleDaemon: stopping");
+
+ /* Close the ServerSocket. This will make our thread to terminate */
+ this.stopping=true;
+ this.server.close();
+
+ /* Wait for the main thread to exit and dump a message */
+ this.thread.join(5000);
+ System.err.println("SimpleDaemon: stopped");
+ }
+
+ public void destroy() {
+ System.err.println("SimpleDaemon: instance "+this.hashCode()+
+ " destroy");
+ }
+
+ public void run() {
+ int number=0;
+
+ System.err.println("SimpleDaemon: started acceptor loop");
+ try {
+ while(!this.stopping) {
+ Socket socket=this.server.accept();
+ Handler handler=new Handler(socket,this,this.controller);
+ handler.setConnectionNumber(number++);
+ handler.setDirectoryName(this.directory);
+ new Thread(handler).start();
+ }
+ } catch (IOException e) {
+ /* Don't dump any error message if we are stopping. A IOException
+ is generated when the ServerSocket is closed in stop() */
+ if (!this.stopping) e.printStackTrace(System.err);
+ }
+
+ /* Terminate all handlers that at this point are still open */
+ Enumeration openhandlers=this.handlers.elements();
+ while (openhandlers.hasMoreElements()) {
+ Handler handler=(Handler)openhandlers.nextElement();
+ System.err.println("SimpleDaemon: dropping connection "+
+ handler.getConnectionNumber());
+ handler.close();
+ }
+
+ System.err.println("SimpleDaemon: exiting acceptor loop");
+ }
+
+ protected void addHandler(Handler handler) {
+ synchronized (handler) {
+ this.handlers.add(handler);
+ }
+ }
+
+ protected void removeHandler(Handler handler) {
+ synchronized (handler) {
+ this.handlers.remove(handler);
+ }
+ }
+
+ public static class Handler implements Runnable {
+
+ private DaemonController controller=null;
+ private SimpleDaemon parent=null;
+ private String directory=null;
+ private Socket socket=null;
+ private int number=0;
+
+ public Handler(Socket s, SimpleDaemon p, DaemonController c) {
+ super();
+ this.socket=s;
+ this.parent=p;
+ this.controller=c;
+ }
+
+ public void run() {
+ this.parent.addHandler(this);
+ System.err.println("SimpleDaemon: connection "+this.number+
+ " opened from "+this.socket.getInetAddress());
+ try {
+ InputStream in=this.socket.getInputStream();
+ OutputStream out=this.socket.getOutputStream();
+ handle(in,out);
+ this.socket.close();
+ } catch (IOException e) {
+ e.printStackTrace(System.err);
+ }
+ System.err.println("SimpleDaemon: connection "+this.number+
+ " closed");
+ this.parent.removeHandler(this);
+ }
+
+ public void close() {
+ try {
+ this.socket.close();
+ } catch (IOException e) {
+ e.printStackTrace(System.err);
+ }
+ }
+
+ public void setConnectionNumber(int number) {
+ this.number=number;
+ }
+
+ public int getConnectionNumber() {
+ return(this.number);
+ }
+
+ public void setDirectoryName(String directory) {
+ this.directory=directory;
+ }
+
+ public String getDirectoryName() {
+ return(this.directory);
+ }
+
+ public void log(String name)
+ throws IOException {
+ OutputStream file=new FileOutputStream(name,true);
+ PrintStream out=new PrintStream(file);
+ SimpleDateFormat fmt=new SimpleDateFormat();
+
+ out.println(fmt.format(new Date()));
+ out.close();
+ file.close();
+ }
+
+ public void handle(InputStream in, OutputStream os) {
+ PrintStream out=new PrintStream(os);
+
+ while(true) {
+ try {
+ /* If we don't have data in the System InputStream, we want
+ to ask to the user for an option. */
+ if (in.available()==0) {
+ out.println();
+ out.println("Please select one of the following:");
+ out.println(" 1) Shutdown");
+ out.println(" 2) Reload");
+ out.println(" 3) Create a file");
+ out.println(" 4) Disconnect");
+ out.print("Your choiche: ");
+ }
+
+ /* Read an option from the client */
+ int x=in.read();
+
+ switch (x) {
+ /* If the socket was closed, we simply return */
+ case -1:
+ return;
+
+ /* Attempt to shutdown */
+ case '1':
+ out.println("Attempting a shutdown...");
+ try {
+ this.controller.shutdown();
+ } catch (IllegalStateException e) {
+ out.println();
+ out.println("Can't shutdown now");
+ e.printStackTrace(out);
+ }
+ break;
+
+ /* Attempt to reload */
+ case '2':
+ out.println("Attempting a reload...");
+ try {
+ this.controller.reload();
+ } catch (IllegalStateException e) {
+ out.println();
+ out.println("Can't reload now");
+ e.printStackTrace(out);
+ }
+ break;
+
+ /* Disconnect */
+ case '3':
+ String name=this.getDirectoryName()+
+ "/SimpleDaemon."+
+ this.getConnectionNumber()+
+ ".tmp";
+ try {
+ this.log(name);
+ out.println("File '"+name+"' created");
+ } catch (IOException e) {
+ e.printStackTrace(out);
+ }
+ break;
+
+ /* Disconnect */
+ case '4':
+ out.println("Disconnecting...");
+ return;
+
+ /* Discard any carriage return / newline characters */
+ case '\r':
+ case '\n':
+ break;
+
+ /* We got something that we weren't supposed to get */
+ default:
+ out.println("Unknown option '"+(char)x+"'");
+ break;
+
+ }
+
+ /* If we get an IOException we return (disconnect) */
+ } catch (IOException e) {
+ System.err.println("SimpleDaemon: IOException in "+
+ "connection "+
+ this.getConnectionNumber());
+ return;
+ }
+ }
+ }
+ }
+}
diff --git a/xdocs/binaries.xml b/xdocs/binaries.xml
new file mode 100644
index 0000000..2afc143
--- /dev/null
+++ b/xdocs/binaries.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0"?>
+
+<document>
+
+ <properties>
+ <title>Daemon : binaries</title>
+ <author email="jfrederic.clere at fujitsu-siemens.con">Jean-Frederic Clere</author>
+ </properties>
+
+<body>
+<section name="What to download">
+<p>
+In the directory
+<a href="http://www.apache.org/dist/jakarta/commons/daemon/binaries/">binaries</a>
+you found subdirectories containing executables
+corresponding to your operating system. If your machine is not in the list
+mail us we will try to make it available or try to build it on your own.
+The files are compressed tar files. They are named jvm_name-os_name.
+For example: In the directory freebsd we have jdk1.4.1-FreeBSD_4.9.tar.gz
+That a file build on FreeBSD 4.9 using the FreeBSD JVM 1.4.1.
+</p>
+</section>
+
+<section name="What to do to get the excutable">
+<subsection name="jsvc">
+<p>
+You have to do the following:
+<ul>
+ <li>Find the nearest tar file corresponding to our configuration.</li>
+ <li>Download it.</li>
+ <li>Uncompress the tar file and extract it (better with a gnu tar).</li>
+ <li>Copy the executable in the location where you want to run it.</li>
+ <li>Write a rc shell
+ (see in src/samples and src/native/unix/native/Tomcat.sh)
+ to get your java application started as a daemon.
+ </li>
+</ul>
+</p>
+</subsection>
+<subsection name="procrun">
+<p>
+The procrun.exe has to be installed as a service.
+(See <a href="procrun.html">procrun</a> for more information.
+</p>
+</subsection>
+</section>
+
+</body>
+</document>
diff --git a/xdocs/faq.xml b/xdocs/faq.xml
new file mode 100644
index 0000000..40162d6
--- /dev/null
+++ b/xdocs/faq.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0"?>
+
+<document>
+
+ <properties>
+ <title>Daemon : FAQ</title>
+ <author email="jfrederic.clere at fujitsu-siemens.con">Jean-Frederic Clere</author>
+ </properties>
+
+<body>
+<section name="Buildconf problems">
+<p>
+<source>
+$ sh support/buildconf.sh
+autoconf: Undefined macros:
+***BUG in Autoconf--please report*** AC_PATH
+***BUG in Autoconf--please report*** AC_PATH
+***BUG in Autoconf--please report*** AC_PATH
+</source>
+Your version of autoconf is to old, upgrade your autoconf and retry.
+Or run support/buildconf.sh in another machine and copy the daemon tree in
+the machine where you want to compile jsvc.
+</p>
+</section>
+
+<section name="Configure problems">
+<p>
+<source>
+configure: creating ./config.status
+config.status: creating Makefile
+mv: Makefile: set owner/group (was: 1670/0): Operation not permitted
+config.status: creating Makedefs
+mv: Makedefs: set owner/group (was: 1670/0): Operation not permitted
+config.status: creating native/Makefile
+mv: native/Makefile: set owner/group (was: 1670/0): Operation not permitted
+*** All done ***
+Now you can issue "make"
+</source>
+You should ignore those error messages they are normal in FreeBSD.
+config.status creates files in /tmp and move them in the current directory.
+When FreeBSD creates files it sets the group of the files to
+the group of the directory where the files are created.
+So if /tmp is group "wheel" the files are "wheel". When moving the files in
+the current directory (if you are not member of group "wheel")
+the group "wheel" cannot be set on the moved files.
+</p>
+</section>
+
+</body>
+</document>
diff --git a/xdocs/images/logo.gif b/xdocs/images/logo.gif
new file mode 100644
index 0000000..115dbe5
Binary files /dev/null and b/xdocs/images/logo.gif differ
diff --git a/xdocs/images/logo.png b/xdocs/images/logo.png
new file mode 100644
index 0000000..e71253a
Binary files /dev/null and b/xdocs/images/logo.png differ
diff --git a/xdocs/index.xml b/xdocs/index.xml
new file mode 100644
index 0000000..bcc4683
--- /dev/null
+++ b/xdocs/index.xml
@@ -0,0 +1,93 @@
+<?xml version="1.0"?>
+
+<document>
+
+ <properties>
+ <title>Daemon : Java based daemons or services</title>
+ <author email="jfrederic.clere at fujitsu-siemens.con">Jean-Frederic Clere</author>
+ </properties>
+
+<body>
+<section name="Introduction">
+<p>
+ Since 1994, the Java programming language evolved and became a
+ valid tool to develop, other than applets and client applications,
+ reliable and performant server applications. The major disadvantage of
+ the Java platform is that still today the only portable way to
+ start a Java application relies on a single point of entry: the
+ <CODE><EM CLASS="key">public static void</EM>
+ main(<EM CLASS="ref">String</EM>[])</CODE> method.
+</p>
+<p>
+ Having a single-point of entry is a valid solution for client
+ applications, where interactively a user can command to the application
+ to quit (which can terminate the Virtual Machine process at calling the
+ <CODE><EM CLASS="ref">System</EM>.exit(<EM CLASS="key">int</EM>)</CODE>
+ method), but in those cases where the application is not interactive
+ (server applications) there is currently no portable way to notify
+ the Virtual Machine of its imminent shutdown.
+</p>
+<p>
+ A server application written in Java might have to perform several tasks
+ before being able to shutdown the Virtual Machine process. For example
+ in the case of a Servlet container, before the VM process is shut down,
+ sessions might need to be serialized to disk, and web applications need
+ to be destroyed.
+</p>
+<p>
+ One common solution to this problem is to create (for example) a
+ <CODE><EM CLASS="ref">ServerSocket</EM></CODE> and wait for a particular
+ message to be issued. When the message is received, all operations
+ required to shut down the server applications are performed and at the
+ end the <CODE><EM CLASS="ref">System</EM>.exit</CODE> method is called
+ to terminate the Virtual Machine process. This method, however, implies
+ several disadvantages and risks: for example in case of a system-wide
+ shutdown, it might happen that the Virtual Machine process will be shut
+ down directly by the operating system, without notifying the running
+ server application. Or, for example, if an attacker finds out what is
+ the required message to send to the server, and discovers a way to send
+ this message to the running server application, he can easily interrupt
+ the operation of a server, bypassing all the security restrictions
+ implemented in the operating system.
+</p>
+<p>
+ Most multi-user operating systems already have a way in which server
+ applications are started and stopped, under Unix based operating systems
+ non interactive server applications are called <em>daemons</em> and are
+ controlled by the operating system with a set of specified
+ <em>signals</em>. Under Windows such programs are called <em>services</em>
+ and are controlled by appropriate calls to specific functions defined in
+ the application binary, but although the ways of dealing with the problem
+ are different, in both cases the operating system can notify a server
+ application of its imminent shutdown, and the application has the
+ ability to perform certain tasks before its process of execution is
+ destroyed.
+</p>
+</section>
+
+<section name="Structure">
+<p>
+ Daemon is made of 2 parts. One written in C that makes the interface to
+ the operating system and the other in Java that provides the
+ Daemon API.
+</p>
+</section>
+
+<section name="Platforms">
+<p>
+ Actually win32 and the UNIX like platforms are supported.
+ For win32 platfroms use <a href="procrun.html">procrun</a>.
+ For UNIX like platforms use <a href="jsvc.html">jsvc</a>.
+</p>
+</section>
+<section name="Initial Source of the Package">
+
+<p>The original Java classes come from the Jakarta Tomcat 4.0 project.</p>
+
+<p>The proposed package name for the Daemon component is
+<code>org.apache.commons.daemon</code>.
+</p>
+</section>
+
+</body>
+</document>
diff --git a/xdocs/jsvc.xml b/xdocs/jsvc.xml
new file mode 100644
index 0000000..db7d41c
--- /dev/null
+++ b/xdocs/jsvc.xml
@@ -0,0 +1,172 @@
+<?xml version="1.0"?>
+
+<document>
+
+ <properties>
+ <title>Daemon : Java Service</title>
+ <author email="jfrederic.clere at fujitsu-siemens.con">Jean-Frederic Clere</author>
+ </properties>
+
+<body>
+<section name="Introduction">
+<p>
+ Actualy only the UNIX like platforms are supported.
+ The sources are located in the src/native/unix subdirectory of the
+ project sources.
+ For win32 platfroms the cygwin emulation layer is used. See
+ <a href="http://www.cygwin.com/"> cygwin</a> for more informations.
+</p>
+<p>
+ In the futur <a href="http://apr.apache.org/"> APR </a> may be used
+ to provide more convinient platform support.
+</p>
+</section>
+
+<section name="Building from cvs">
+<p>
+To build under an UNIX operating system you will need:
+<ul>
+ <li>GNU AutoConf (at least version 2.53)</li>
+ <li>An ANSI-C compliant compiler (GCC is good)</li>
+ <li>GNU Make</li>
+ <li>A Java Platform 2 compliant SDK</li>
+</ul>
+
+
+You need to build the "configure" program with:
+
+ sh support/buildconf.sh
+(Note it is possible to replace sh by any compatible shell like bash, ksh).
+
+The result should be something like:
+<source>
+support/buildconf.sh
+support/buildconf.sh: configure script generated successfully
+</source>
+Once the configure script is generated, follow the next section.
+</p>
+</section>
+
+<section name="Building for a release tarball">
+<p>
+To build the binary under an UNIX operating system you will need:
+<ul>
+ <li>An ANSI-C compliant compiler (GCC is good)</li>
+ <li>GNU Make</li>
+ <li>A Java Platform 2 compliant SDK</li>
+</ul>
+
+You have to specify the JAVA_HOME of the SDK
+either the --with-java=<dir> parameter or set the JAVA_HOME environment
+to point to your SDK installation. For example:
+<source>
+ ./configure --with-java=/usr/java
+</source>
+or
+<source>
+ export JAVA_HOME
+ ./configure
+</source>
+
+If your operating system is supported, configure will go thru cleanly,
+otherwise it will report an error (please send us the details of your
+OS/JDK, or a patch against the sources). To build the binaries and
+libraries simply do:
+<source>
+ make
+</source>
+This will generate the executable file jsvc.
+</p>
+</section>
+
+<section name="Starting jsvc">
+<p>
+To check the allowed parameters for the jsvc binary simply do:
+<source>
+./jsvc -help
+Usage: jsvc [-options] class [args...]
+
+Where options include:
+
+ -jvm <JVM name>
+ use a specific Java Virtual Machine. Available JVMs:
+ '(null)'
+ -cp / -classpath <directories and zip/jar files>
+ set search path for service classes and resouces
+ -home <directory>
+ set the path of your JDK or JRE installation (or set
+ the JAVA_HOME environment variable)
+ -version
+ show the current Java environment version (to check
+ correctness of -home and -jvm. Implies -nodetach)
+ -help / -?
+ show this help page (implies -nodetach)
+ -nodetach
+ don't detach from parent process and become a daemon
+ -debug
+ verbosely print debugging information
+ -check
+ only check service (implies -nodetach)
+ -user
+ user used to run the daemon (defaults to current user)
+ -verbose[:class|gc|jni]
+ enable verbose output
+ -outfile </full/path/to/file>
+ Location for output from stdout (defaults to /dev/null)
+ Use the value '&2' to simulate '1>&2'
+ -errfile </full/path/to/file>
+ Location for output from stderr (defaults to /dev/null)
+ Use the value '&1' to simulate '2>&1'
+ -pidfile </full/path/to/file>
+ Location for output from the file containing the pid of jsvc
+ (defaults to /var/run/jsvc.pid)
+ -D<name>=<value>
+ set a Java system property
+ -X<option>
+ set Virtual Machine specific option
+
+</source>
+</p>
+
+</section>
+<section name="Using jsvc">
+<p>
+There two ways to use jsvc: via a Class that implements the Daemon interface or
+via calling a Class that have the required methods.
+For example Tomcat-4.1.x uses the Daemon interface
+and Tomcat-5.0.x provide a Class whose methods are called by jsvc directly.
+</p>
+<subsection name="Via Daemon interface">
+<p>
+You have to do the following.
+<ul>
+ <li>Write a Class that implements the Daemon interface (MyClass).</li>
+ <li>Put it in the jarfile (my.jar).</li>
+ <li>Call jsvc like:
+ <source>
+ jsvc -cp commons-daemon.jar:my.jar MyClass
+ </source>
+ </li>
+</ul>
+</p>
+</subsection>
+<subsection name="Directly">
+<p>
+You have to write a Class (MyClass) that implements the following methods:
+<ul>
+ <li>void init(String[] arguments): Here open the configuration files, create the trace file, create
+ the ServerSockets, the Threads</li>
+ <li>void start(): Start the Thread, accept incomming connections</li>
+ <li>void stop(): Inform the Thread to live the run(), close the ServerSockets</li>
+ <li>void destroy(): Destroy any object created in init()</li>
+</ul>
+Store it in a jarfile and use as above:
+<source>
+ jsvc -cp commons-daemon.jar:my.jar MyClass
+</source>
+</p>
+</subsection>
+</section>
+
+</body>
+</document>
diff --git a/xdocs/navigation.xml b/xdocs/navigation.xml
new file mode 100644
index 0000000..58f198b
--- /dev/null
+++ b/xdocs/navigation.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<!DOCTYPE project [
+<!ENTITY commons-nav SYSTEM "../../commons-build/incl_nav.xml">
+]>
+
+<project name="Daemon">
+
+ <title>Daemon</title>
+ <organizationLogo href="/images/jakarta-logo-blue.gif">
+ Jakarta
+ </organizationLogo>
+
+ <body>
+ <links>
+ <item name="Jakarta Commons"
+ href="http://jakarta.apache.org/commons/"/>
+ </links>
+
+ <menu name="Commons Daemon">
+ <item name="Overview"
+ href="/index.html"/>
+ <item name="Procrun"
+ href="/procrun.html"/>
+ <item name="Jsvc"
+ href="/jsvc.html"/>
+ <item name="Native binaries"
+ href="/binaries.html"/>
+ <item name="FAQ"
+ href="/faq.html"/>
+
+ </menu>
+
+ &commons-nav;
+
+ </body>
+</project>
diff --git a/xdocs/procrun.xml b/xdocs/procrun.xml
new file mode 100644
index 0000000..ec8511e
--- /dev/null
+++ b/xdocs/procrun.xml
@@ -0,0 +1,189 @@
+<?xml version="1.0"?>
+
+<document>
+
+ <properties>
+ <title>Daemon : Procrun</title>
+ <author email="jfrederic.clere at fujitsu-siemens.con">Jean-Frederic Clere</author>
+ <author email="william.barker at wilshire.com">Bill Barker</author>
+ <author email="mladen.turk at gisdata.hr">Mladen Turk</author>
+ </properties>
+
+<body>
+<section name="Introduction">
+<p>
+ Actualy only the win32 platforms are supported.
+</p>
+</section>
+<section name="Building">
+<p>
+ It is possible to use cygwin to build procrun.
+ <a href="http://www.cygwin.com/"> cygwin</a> for more informations.
+</p>
+<p>
+ If you have access to MSVC (version 6.0 or higher), then simply
+ open the corresponding build project file.
+ <ul>
+ <li>For MSVC 6.x, use <code>procrun.dsw</code></li>
+ <li>For MSVC.NET, use <code>procrun.sln</code></li>
+ </ul>
+ At this point, you need to select from the build menu which version you
+ want to build (select either the release or debug build, depending on
+ your preferences). The selections are:
+ <ul>
+ <li><code>procrun</code> if you want the GUI interface</li>
+ <li><code>procrun CONSOLE</code> if you don't want the GUI interface</li>
+ <li><code>procrun DLL</code> if you want the Control Panel application</li>
+ </ul>
+</p>
+</section>
+<section name="Using procrun">
+<subsection name="Installing the service">
+<p>
+ The first thing that you must do is to install your service. As a
+ special case, if you haved installed Tomcat 5 via the installer, then it
+ will do this for you, and you can skip this step.
+</p>
+<p>
+ To install the service, you need to use the <code>//IS//</code> parameter.
+ Use <code>tomcatw.exe</code> if you want to run the Graphical version,
+ or <code>tomcat.exe</code> for the non-Graphical version. For example:
+ <source>
+ tomcat //IS//Tomcat5 --DisplayName "Tomcat 5.0.12" \
+ --Description "Tomcat 5.0.12 JDK 1.4 http://jakarta.apache.org" \
+ --ImagePath "c:\devtools\tomcat\5.0\bin\bootstrap.jar" \
+ --StartupClass org.apache.catalina.startup.Bootstrap;main;start \
+ --ShutdownClass org.apache.catalina.startup.Bootstrap;main;stop \
+ --Java auto
+ </source>
+ <table>
+ <caption>The options available for installation are</caption>
+ <tr><th>--DisplayName</th>
+ <td>This is the name shown in the Windows Services manager.</td></tr>
+ <tr><th>--Description</th>
+ <td>This is the service description shown in the windows Services manager.</td></tr>
+ <tr><th>--ImagePath</th>
+ <td>Full path to the executable to be run as service,
+ or name of the Java Class Path. In cases when the
+ service runs JVM or Java binary this is the
+ parameter passed to -Djava.class.path option.</td></tr>
+ <tr><th>--Arguments</th>
+ <td>Arguments are enclosed inside double quotation
+ marks and passed to the service image.</td></tr>
+ <tr><th>--WorkingPath</th>
+ <td>Sets the working path to the desired value.</td></tr>
+ <tr><th>--Java</th>
+ <td><ul>
+ <li>auto:
+ Auto will cause to load the default JVM read
+ read from registry.</li>
+ <li>java[w]:
+ The default java.exe or javaw.exe will be
+ located and executed with
+ -Djava.class.path=ImagePath</li>
+ <li>If neither java or auto are specified then this
+ parameter is treated as either the full path to the
+ <code>jvm.dll</code>, or as the path to the Java
+ installation.</li>
+ </ul></td></tr>
+ <tr><th>--JavaOptions</th>
+ <td> This is the list of options to be passed to the JVM
+ The options are separated using hash (#) simbol.
+ For Example:
+ -Xmx=100M#-Djava.compiler=NONE</td></tr>
+ <tr><th>--StartupClass</th>
+ <td>Class name that will be called if started from JVM
+ when the applications starts.
+ The method name is separated by semicolon after the
+ class name.
+ The parameters passed to the class method are semicolon
+ separated values after the method name.
+ For example:
+ org/apache/jk/apr/TomcatStarter;Main;start</td></tr>
+ <tr><th>--ShutdownClass</th>
+ <td>Class name that will be called if started from JVM
+ when the applications stops. The class has to have
+ the method Main.
+ The method name is separated by semicolon after the
+ class name.
+ The parameters passed to the class method are semicolon
+ separated values after the method name.
+ For example:
+ org/apache/jk/apr/TomcatStarter;Main;stop;some;dummy;params</td></tr>
+ <tr><th>--StdInputFile</th>
+ <td>The file that will be read an passed as standard
+ input stream to the redirected application</td></tr>
+ <tr><th>--StdOutputFile</th>
+ <td>Path to the redirected stdout.</td></tr>
+ <tr><th>--StdErrorFile</th>
+ <td>Path to the redirected stderr.</td></tr>
+ <tr><th>--Startup</th>
+ <td>The services startup mode Automatic or Manual.
+ Default value is auto.</td></tr>
+ <tr><th>--User</th>
+ <td>The User account used for launching redirected process.</td></tr>
+ <tr><th>--Password</th>
+ <td>The password of User account used for launching
+ redirected process.</td></tr>
+ <tr><th>--Install</th>
+ <td>Used as Service manager ImagePath when installing
+ service from installation program using procrunw.</td></tr>
+ </table>
+</p>
+</subsection>
+<subsection name="Running the service">
+<p>
+ You can use the Windows Service Manager to stop and start the
+ service, as you would for any other service. This is the recommended way
+ to manage the service.</p>
+<p>
+ To test the service, or to simply run the process manually, use the //GT//
+ option for the Graphical version. For example:
+ <source>
+ tomcatw //GT//Tomcat5
+ </source>
+ To test the non-Graphical version, use the //TS// option. For example:
+ <source>
+ tomcat //TS//Tomcat5
+ </source>
+ Either of these will start your service as a normal program running under
+ the identity of the currently logged in user. It is
+ <strong>Important</strong> that the Service is stopped before testing, or
+ these commands will fail.</p>
+</subsection>
+<subsection name="Changing the Service Parameters from the GUI">
+<p>
+ To change the Service settings using the GUI interface, use the //ES// option with
+ <code>tomcatw.exe</code>. You can then change the settings by entering
+ the new values in the correct boxes. For example:
+ <source>
+ tomcatw //ES//Tomcat5
+ </source>
+</p>
+</subsection>
+<subsection name="Changing the Service Parameters from the Command Line">
+<p>
+ To change the Service settings from the command line, use the //US// option.
+ The parameters are the same as for <a href="#Installing%20the%20service">
+ Installing the service</a>. For example:
+ <source>
+ tomcat //US//Tomcat5 --Java c:\jsdk1.4.1_02\jre\bin\client\jvm.dll \
+ --StdOutputFile c:\Tomcat5\logs\stdout.txt \
+ --StdErrorFile c:\Tomcat5\logs\stderr.txt
+ </source>
+</p>
+</subsection>
+<subsection name="Removing the Service">
+<p>
+ To remove the service, use the //DS// option. For example:
+ <source>
+ tomcat //DS//Tomcat5
+ </source>
+ This command will remove the service from the Windows Service Manager, but
+ it will still allow you to run it via the //GT// or //TS// options.
+</p>
+</subsection>
+</section>
+
+</body>
+</document>
diff --git a/xdocs/style/project.css b/xdocs/style/project.css
new file mode 100644
index 0000000..031480c
--- /dev/null
+++ b/xdocs/style/project.css
@@ -0,0 +1,5 @@
+#banner, #banner td {
+ background: #fff;
+ color: #000;
+}
+
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/commons-daemon.git
More information about the pkg-java-commits
mailing list