[commons-daemon] 26/52: Imported Upstream version 1.0.4

Tony Mancill tmancill at moszumanska.debian.org
Wed Nov 12 05:31:30 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 07c125b11d4a2131775919b415a5aabc4e77b144
Author: tony mancill <tmancill at debian.org>
Date:   Fri Nov 7 07:59:33 2014 -0800

    Imported Upstream version 1.0.4
---
 README                                             |  18 +-
 RELEASE-NOTES.txt                                  |  52 +++-
 build.xml                                          |  14 +-
 pom.xml                                            |   8 +-
 src/assembly/native-src.xml                        |  14 +-
 src/assembly/src.xml                               |   4 +-
 src/java/org/apache/commons/daemon/Daemon.java     |   8 +-
 .../apache/commons/daemon/DaemonInitException.java |  45 ++++
 .../daemon/support/DaemonConfiguration.java        | 195 +++++++++++++++
 .../commons/daemon/support/DaemonLoader.java       |  92 ++++---
 .../commons/daemon/support/DaemonWrapper.java      | 267 +++++++++++++++++++++
 .../nt/procrun/apps/prunmgr/prunmgr.manifest       |  10 -
 src/native/unix/CHANGES.txt                        |   9 +-
 src/native/unix/INSTALL.txt                        |  10 +
 src/native/unix/Makedefs.in                        |   6 +-
 src/native/unix/Makefile.in                        |   4 +-
 src/native/unix/configure                          | 152 +++++++++++-
 src/native/unix/configure.in                       |  21 +-
 src/native/unix/man/jsvc.1.xml                     |  28 ++-
 src/native/unix/native/Makefile.in                 |   5 +-
 src/native/unix/native/Tomcat.sh                   |  78 ------
 src/native/unix/native/arguments.c                 |   5 +-
 src/native/unix/native/debug.c                     |  30 ++-
 src/native/unix/native/debug.h                     |   8 +-
 src/native/unix/native/help.c                      |   6 +-
 src/native/unix/native/home.c                      |   6 +-
 src/native/unix/native/java.c                      |  54 +++--
 src/native/unix/native/jsvc-unix.c                 | 235 +++++++++++++++---
 src/native/unix/native/location.c                  |   2 +
 src/native/unix/native/locks.c                     |   3 +-
 src/native/unix/native/signals.c                   |   4 +-
 src/native/unix/native/version.h                   |   2 +-
 src/native/unix/support/apfunctions.m4             |  72 +++++-
 src/native/unix/support/apsupport.m4               |   4 +-
 src/native/unix/support/mkdist.sh                  | 104 ++++++++
 src/native/windows/README                          |  25 ++
 src/native/{nt/procrun => windows}/README.dev      |   4 +-
 .../{nt/procrun => windows}/apps/prunmgr/Makefile  |   0
 .../{nt/procrun => windows}/apps/prunmgr/prunmgr.c |   0
 .../{nt/procrun => windows}/apps/prunmgr/prunmgr.h |   8 +-
 src/native/windows/apps/prunmgr/prunmgr.manifest   |  26 ++
 .../procrun => windows}/apps/prunmgr/prunmgr.rc    |  82 +++----
 .../{nt/procrun => windows}/apps/prunsrv/Makefile  |   2 +-
 .../{nt/procrun => windows}/apps/prunsrv/prunsrv.c | 178 ++++++++++----
 .../{nt/procrun => windows}/apps/prunsrv/prunsrv.h |   6 +-
 .../procrun => windows}/apps/prunsrv/prunsrv.rc    |  10 +-
 .../{nt/procrun => windows}/include/Makefile.inc   |  36 +--
 .../{nt/procrun => windows}/include/apxwin.h       |   1 +
 .../{nt/procrun => windows}/include/cmdline.h      |   0
 .../{nt/procrun => windows}/include/console.h      |   0
 src/native/{nt/procrun => windows}/include/gui.h   |   0
 .../{nt/procrun => windows}/include/handles.h      |   0
 .../{nt/procrun => windows}/include/javajni.h      |  19 +-
 src/native/{nt/procrun => windows}/include/log.h   |   0
 .../{nt/procrun => windows}/include/registry.h     |   0
 .../{nt/procrun => windows}/include/rprocess.h     |   0
 .../{nt/procrun => windows}/include/service.h      |   0
 .../{nt/procrun => windows}/resources/commons.bmp  | Bin
 .../{nt/procrun => windows}/resources/license.rtf  |   0
 .../{nt/procrun => windows}/resources/procrunr.ico | Bin
 .../{nt/procrun => windows}/resources/procruns.ico | Bin
 .../{nt/procrun => windows}/resources/procrunw.ico | Bin
 .../{nt/procrun => windows}/resources/susers.bmp   | Bin
 src/native/{nt/procrun => windows}/src/cmdline.c   |   0
 src/native/{nt/procrun => windows}/src/console.c   |   0
 src/native/{nt/procrun => windows}/src/gui.c       |   3 +-
 src/native/{nt/procrun => windows}/src/handles.c   |   0
 src/native/{nt/procrun => windows}/src/javajni.c   | 203 +++++++++++-----
 src/native/{nt/procrun => windows}/src/log.c       |  88 ++++---
 src/native/{nt/procrun => windows}/src/mclib.c     |  15 +-
 src/native/{nt/procrun => windows}/src/mclib.h     |   0
 src/native/{nt/procrun => windows}/src/private.h   |   0
 src/native/{nt/procrun => windows}/src/registry.c  |   8 +-
 src/native/{nt/procrun => windows}/src/rprocess.c  |   0
 src/native/{nt/procrun => windows}/src/service.c   |  17 +-
 src/native/{nt/procrun => windows}/src/utils.c     |   0
 src/native/{nt/procrun => windows}/xdocs/index.xml |   0
 src/samples/AloneService.java                      |  35 +--
 src/samples/Native.c                               |   4 +-
 src/samples/ProcrunService.java                    | 100 ++++++--
 src/samples/ServiceDaemon.java                     |  35 +--
 .../{SimpleDaemon.java => SimpleApplication.java}  | 160 ++++++------
 src/samples/SimpleApplication.sh                   |  57 +++++
 src/samples/SimpleDaemon.java                      |  24 +-
 src/{native/unix/native => samples}/Tomcat5.sh     |   0
 src/samples/Tomcat7.sh                             | 203 ++++++++++++++++
 src/samples/build.xml                              |  22 +-
 src/samples/build/classes/AloneService.class       | Bin 0 -> 2809 bytes
 src/samples/build/classes/ProcrunService.class     | Bin 0 -> 3972 bytes
 src/samples/build/classes/ServiceDaemon.class      | Bin 0 -> 2981 bytes
 .../build/classes/ServiceDaemonReadThread.class    | Bin 0 -> 617 bytes
 .../build/classes/SimpleApplication$Handler.class  | Bin 0 -> 3730 bytes
 .../classes/SimpleApplication$ShutdownHook.class   | Bin 0 -> 625 bytes
 src/samples/build/classes/SimpleApplication.class  | Bin 0 -> 3335 bytes
 .../build/classes/SimpleDaemon$Handler.class       | Bin 0 -> 4021 bytes
 src/samples/build/classes/SimpleDaemon.class       | Bin 0 -> 3444 bytes
 96 files changed, 2339 insertions(+), 607 deletions(-)

diff --git a/README b/README
index c1df51e..5c4de0a 100644
--- a/README
+++ b/README
@@ -3,26 +3,24 @@ ant dist
 
 The Java portion of Commons Daemon requires Java 1.3 or later to build
 
-To build the native part:
+To build the native parts:
 1 - jsvc:
+  jsvc is only for Un*x systems
   cd src/native/unix; configure; make
   You need a gnu make.
   The jsvc executable is created in the dist directory.
-  There is a INSTALL.txt src/native/unix - please have a look at it.
+  There is a INSTALL.txt in src/native/unix - please have a look at it.
 
-  On Windows an additional step is needed:
-  cd src/native/windows; make
-  There is a README in src/native/windows - please have a look at it.
-  The exe files are created in dist.
 2 - procrun:
   procrun is only for windows
-  cd src\native\windows\procrun\apps
+  cd src\native\windows\apps
   cd prunsrv
-  nmake -f prunsrv.x86 (prunsrv.amd64 | prunsrv.ia64)
+  nmake [CPU=(X86|X64|I64)]
   cd ..\prunmgr
-  nmake -f prunmgs.x86
+  nmake [CPU=(X86|X64|I64)]
   (It is also possible to use the MS development tools).
-[Note: the directory in SVN is currently called src/native/nt, not src/native/windows]
+
+  See also the README files in src\native\windows
 
 To build the documentation: (See http://commons.apache.org/building.html).
 mvn site:generate
diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt
index 5294620..d94a8e3 100644
--- a/RELEASE-NOTES.txt
+++ b/RELEASE-NOTES.txt
@@ -1,26 +1,55 @@
-$Id: RELEASE-NOTES.txt 980519 2010-07-29 17:32:38Z mturk $
+$Id: RELEASE-NOTES.txt 1025823 2010-10-21 05:06:56Z mturk $
 
             Commons Daemon Package
-               Version 1.0.3
+               Version 1.0.4
                 Release Notes
 
 
 INTRODUCTION:
 
+Commons Daemon is a set of utilities and Java support classes for running
+Java applications as server processes. 
+Commonly known as 'daemon' processes in Unix terminology (hence the name),
+on Windows they are called 'services'.
+
 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.
 
 
+Compatibility with 1.0.3
+------------------------
+Binary compatible - Yes
+
+Source compatible - Yes
+
+Semantic compatible - Yes
+
+Commons DAEMON 1.0.3 requires a minimum of JDK 1.3
+
+
 NEW FEATURES:
 
+* DAEMON-180: Add DaemonWrapper to allow running standard applications
+              as daemons. (1.0.4)
+* DAEMON-179: Allow procrun to use java/lang/System as --ShutdownClass. (1.0.4)
+* DAEMON-178: Allow jsvc umask to be configured at build time
+* DAEMON-177: Allow fail during init with nicer message. (1.0.4)
+* DAEMON-176: Create config.nice during configure step. (1.0.4)
+* DAEMON-173: Allow --JavaHome=jdk and --JavaHome=jre options that
+              will guess default JavaHome from the registry. (1.0.4)
+* DAEMON-160: Remove obsolete code; rename native/nt as native/windows (1.0.4)
+* DAEMON-144: Drop sample dependency on Commons Collections ExtendedProperties (1.0.4)
+* DAEMON-95:  Support log rotation using SIGUSR1 (1.0.4)
+* DAEMON-80:  Syslog support for jsvc (1.0.4)
+
 * DAEMON-138: Add --PidFile option to allow storing running process id. (1.0.3)
 * DAEMON-137: Add --LogJniMessages allowing to configure JNI verbose message
               logging. By default those messages were always logged. (1.0.3)
 * DAEMON-140: Add missing Java6 parameters -ea, da, -esa, -dsa, -showversion
               and their long name synonyms. (1.0.3)
-* DAEMON-142: Add option to display procrun version.
+* DAEMON-142: Add option to display procrun version. (1.0.3)
 * DAEMON-166: Add classpath .jar expansion. If the classpath
               element ends with asterisk it will evaluate to all .jar files
               found in the path. (1.0.3)
@@ -41,9 +70,12 @@ NEW FEATURES:
 
 BUG FIXES:
 
+1.0.4: DAEMON-95, DAEMON-171, DAEMON-100, DAEMON-164, DAEMON-165, DAEMON-175,
+       DAEMON-177, DAEMON-150, DAEMON-163, DAEMON-182, DAEMON-181
+
 1.0.3: DAEMON-108, DAEMON-128, DAEMON-139, DAEMON-143, DAEMON-148,
        DAEMON-135, DAEMON-155, DAEMON-159, DAEMON-161, DAEMON-145, DAEMON-146,
-       DAEMON-167, DAEMON-168
+       DAEMON-167, DAEMON-168, DAEMON-154, DAEMON-149
 
 1.0.2: DAEMON-16, DAEMON-31, DAEMON-40, DAEMON-45, DAEMON-49, DAEMON-60,
        DAEMON-84, DAEMON-90, DAEMON-91, DAEMON-92, DAEMON-93, DAEMON-94,
@@ -55,3 +87,15 @@ BUG FIXES:
 
 1.0.1: 304310,  30177, 27523, 29465, 31614, 33580, 31613, 34851.
 
+Feedback
+--------
+Open source works best when you give feedback:
+http://commons.apache.org/daemon/
+
+Please direct all bug reports to JIRA
+https://issues.apache.org/jira/browse/DAEMON
+
+Or subscribe to the commons-user mailing list (prefix emails by [daemon])
+http://commons.apache.org/mail-lists.html
+
+The Commons-DAEMON Team
\ No newline at end of file
diff --git a/build.xml b/build.xml
index 0f667b9..e5a9975 100644
--- a/build.xml
+++ b/build.xml
@@ -19,7 +19,7 @@
 
 <!--
         "Daemon" component of the Apache Commons Subproject
-        $Id: build.xml 980661 2010-07-30 06:47:02Z mturk $
+        $Id: build.xml 1024342 2010-10-19 18:04:56Z mturk $
 -->
 
 
@@ -59,7 +59,7 @@
   <property name="component.title"         value="Java Daemons"/>
 
   <!-- The current version number of this component -->
-  <property name="component.version"       value="1.0.3"/>
+  <property name="component.version"       value="1.0.4"/>
 
   <!-- The base directory for compilation targets -->
   <property name="build.home"              value="target"/>
@@ -237,8 +237,12 @@
         -->
       <fileset dir="src/native/unix" />
     </copy>
+    <copy file="src/samples/Tomcat5.sh"
+          todir="${native.path}/unix/samples"/>
+    <copy file="src/samples/Tomcat7.sh"
+          todir="${native.path}/unix/samples"/>
     <copy todir="${native.path}/windows">
-      <fileset dir="src/native/nt/procrun" />
+      <fileset dir="src/native/windows" />
     </copy>
     <copy file="LICENSE.txt"
           todir="${native.path}"/>
@@ -252,10 +256,12 @@
         <include name="${native.name}/**" />
         <exclude name="${native.name}/unix/configure" />
         <exclude name="${native.name}/unix/support/*.sh" />
+        <exclude name="${native.name}/unix/samples/*.sh" />
       </tarfileset>
       <tarfileset dir="${dist.home}/bin/native" mode="755">
         <include name="${native.name}/unix/configure" />
         <include name="${native.name}/unix/support/*.sh" />
+        <include name="${native.name}/unix/samples/*.sh" />
       </tarfileset>
     </tar>
     <zip zipfile="${dist.home}/bin/${native.name}.zip">
@@ -263,10 +269,12 @@
         <include name="${native.name}/**" />
         <exclude name="${native.name}/unix/configure" />
         <exclude name="${native.name}/unix/support/*.sh" />
+        <exclude name="${native.name}/unix/samples/*.sh" />
       </zipfileset>
       <zipfileset dir="${dist.home}/bin/native" filemode="755">
         <include name="${native.name}/unix/configure" />
         <include name="${native.name}/unix/support/*.sh" />
+        <include name="${native.name}/unix/samples/*.sh" />
       </zipfileset>
     </zip>
 
diff --git a/pom.xml b/pom.xml
index 906fe6b..213bc3d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -25,9 +25,9 @@
     <version>17</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
-  <groupId>org.apache.commons</groupId>
+  <groupId>commons-daemon</groupId>
   <artifactId>commons-daemon</artifactId>
-  <version>1.0.3</version>
+  <version>1.0.4</version>
   <name>Commons Daemon</name>
   <!-- Daemon started in Commons in 2002 with an import of code from Tomcat,
        which is why the NOTICE file has an earlier date than the inceptionYear -->
@@ -92,10 +92,10 @@
     <maven.compile.source>1.3</maven.compile.source>
     <maven.compile.target>1.3</maven.compile.target>
     <commons.componentid>daemon</commons.componentid>
-    <commons.release.version>1.0.3</commons.release.version>
+    <commons.release.version>1.0.4</commons.release.version>
     <commons.jira.id>DAEMON</commons.jira.id>
     <commons.jira.pid>12310468</commons.jira.pid>
-  </properties> 
+  </properties>
 
   <build>
     <sourceDirectory>src/java</sourceDirectory>
diff --git a/src/assembly/native-src.xml b/src/assembly/native-src.xml
index 5a5b204..2f675cb 100644
--- a/src/assembly/native-src.xml
+++ b/src/assembly/native-src.xml
@@ -54,7 +54,17 @@
             </includes>
         </fileSet>
         <fileSet>
-            <directory>src/native/nt/procrun</directory>
+            <directory>src/samples</directory>
+            <outputDirectory>unix/samples</outputDirectory>
+            <lineEnding>lf</lineEnding>
+            <fileMode>775</fileMode>
+            <includes>
+                <include>Tomcat5.sh</include>
+                <include>Tomcat7.sh</include>
+            </includes>
+        </fileSet>
+        <fileSet>
+            <directory>src/native/windows</directory>
             <outputDirectory>windows</outputDirectory>
             <lineEnding>crlf</lineEnding>
             <excludes>
@@ -67,7 +77,7 @@
             <fileMode>664</fileMode>
         </fileSet>
         <fileSet>
-            <directory>src/native/nt/procrun</directory>
+            <directory>src/native/windows</directory>
             <outputDirectory>windows</outputDirectory>
             <includes>
                 <include>**/*.ico</include>
diff --git a/src/assembly/src.xml b/src/assembly/src.xml
index 622c532..0861f60 100644
--- a/src/assembly/src.xml
+++ b/src/assembly/src.xml
@@ -40,7 +40,7 @@
                 <exclude>**/*.sh</exclude>
                 <exclude>native/unix/configure</exclude>
                 <exclude>native/unix/autom4te.cache/**</exclude>
-                <exclude>native/nt/**</exclude>
+                <exclude>native/windows/**</exclude>
                 <exclude>media/**</exclude>
                 <exclude>site/**</exclude>
             </excludes>
@@ -48,7 +48,7 @@
         <fileSet>
             <directory>src</directory>
             <includes>
-                <include>native/nt/procrun/**</include>
+                <include>native/windows/**</include>
             </includes>
         </fileSet>
         <fileSet>
diff --git a/src/java/org/apache/commons/daemon/Daemon.java b/src/java/org/apache/commons/daemon/Daemon.java
index 8f40fe4..14b8f3c 100644
--- a/src/java/org/apache/commons/daemon/Daemon.java
+++ b/src/java/org/apache/commons/daemon/Daemon.java
@@ -29,7 +29,7 @@ package org.apache.commons.daemon;
  * fashion.
  * </p>
  * @author Pier Fumagalli
- * @version 1.0 <i>(CVS $Revision: 925054 $)</i>
+ * @version 1.0 <i>(CVS $Revision: 1023303 $)</i>
  */
 public interface Daemon
 {
@@ -63,12 +63,14 @@ public interface Daemon
      *
      * @param context A <code>DaemonContext</code> object used to
      * communicate with the container.
-     *
+     * @exception DaemonInitException An exception that prevented 
+     * initialization where you want to display a nice message to the user,
+     * rather than a stack trace.
      * @exception Exception Any exception preventing a successful
      *                      initialization.
      */
     public void init(DaemonContext context)
-        throws Exception;
+        throws DaemonInitException, Exception;
 
     /**
      * Start the operation of this <code>Daemon</code> instance. This
diff --git a/src/java/org/apache/commons/daemon/DaemonInitException.java b/src/java/org/apache/commons/daemon/DaemonInitException.java
new file mode 100644
index 0000000..ddc29ac
--- /dev/null
+++ b/src/java/org/apache/commons/daemon/DaemonInitException.java
@@ -0,0 +1,45 @@
+/*
+ *  Copyright 2010 Media Service Provider Ltd
+ *
+ *  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./*
+ *
+ */
+package org.apache.commons.daemon;
+
+/**
+ * Throw this during init if you can't initialise yourself for some expected 
+ * reason.  Using this exception will cause the exception's message to come out
+ * on stdout, rather than a dirty great stacktrace.
+ * @author Nick Griffiths (nicobrevin at gmail.com)
+ */
+public class DaemonInitException extends Exception {
+
+  //don't rely on Throwable#getCause (jdk1.4)
+  private final Throwable cause;
+
+  public DaemonInitException(String message) {
+    super(message);
+    this.cause = null;
+  }
+
+  public DaemonInitException(String message, Throwable cause) {
+    super(message);
+    this.cause = cause;
+  }
+
+  public String getMessageWithCause() {
+    String extra = this.cause == null ? "" : ": " + this.cause.getMessage();
+    return getMessage() + extra;
+  }
+
+}
diff --git a/src/java/org/apache/commons/daemon/support/DaemonConfiguration.java b/src/java/org/apache/commons/daemon/support/DaemonConfiguration.java
new file mode 100644
index 0000000..0dd8b38
--- /dev/null
+++ b/src/java/org/apache/commons/daemon/support/DaemonConfiguration.java
@@ -0,0 +1,195 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You 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.
+ */
+
+package org.apache.commons.daemon.support;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Properties;
+import java.text.ParseException;
+
+/**
+ * Used by jsvc for Daemon configuration.
+ * <p>
+ * Configuration is read from properties file.
+ * If no properties file is given the <code>daemon.properties</code>
+ * is used from the current directory.
+ * </p>
+ * <p>
+ * The properties file can have property values expanded at runtime
+ * by using System properties or execution environment. The part
+ * of the property value between <code>${</code> and <code>}</code>
+ * will be used as System property or environment key. If found then
+ * the entire <code>${foo}</code> will be replaced by the value of
+ * either system property or environment variable named <code>foo</code>.
+ * </p>
+ * <p>
+ * If no variable is found the <code>${foo}</code>  will be passed as is.
+ * In case of <code>$${foo}</code> this will be unescaped and resulting
+ * value will be <code>${foo}</code>.
+ * </p>
+ *
+ * @version 1.0 <i>(SVN $Revision: 925053 $)</i>
+ * @author Mladen Turk
+ */
+public final class DaemonConfiguration
+{
+    /**
+     * Default configuration file name.
+     */
+    protected final static String DEFAULT_CONFIG        = "daemon.properties";
+    /**
+     * Property prefix
+     */
+    protected final static String PREFIX                = "daemon.";
+    private   final static String BTOKEN                = "${";
+    private   final static String ETOKEN                = "}";
+
+
+    private final Properties configurationProperties;
+    private final Properties systemProperties;
+
+    /**
+     * Default constructor
+     */
+    public DaemonConfiguration()
+    {
+        configurationProperties = new Properties();
+        systemProperties        = System.getProperties();
+    }
+
+    /**
+     * Load the configuration properties file.
+     *
+     * @param fileName The properties file to load.
+     * @return <code>true</code> if the file was loaded.
+     */
+    public boolean load(String fileName)
+    {
+        boolean ok = false;
+        try {
+            if (fileName == null)
+                fileName = DEFAULT_CONFIG;
+            FileInputStream file = new FileInputStream(fileName);
+            configurationProperties.clear();
+            configurationProperties.load(file);
+            ok = true;
+        }
+        catch (FileNotFoundException ex) {
+            // fileName does not exist
+        }
+        catch (IOException ex) {
+            // Error reading properties file
+        }
+        return ok;
+    }
+
+    private String expandProperty(String propValue)
+        throws ParseException
+    {
+        StringBuffer expanded;
+        int btoken;
+        int ctoken = 0;
+
+        if (propValue == null)
+            return null;
+        expanded = new StringBuffer();
+        btoken   = propValue.indexOf(BTOKEN);
+        while (btoken != -1) {
+            if (btoken > 0 && propValue.charAt(btoken - 1) == BTOKEN.charAt(0)) {
+                // Skip and unquote.
+                expanded.append(propValue.substring(ctoken, btoken));
+                ctoken = btoken + 1;
+                btoken = propValue.indexOf(BTOKEN, btoken + BTOKEN.length());
+                continue;
+            }
+            int etoken = propValue.indexOf(ETOKEN, btoken);
+            if (etoken != -1) {
+                String variable = propValue.substring(btoken + BTOKEN.length(), etoken);
+                String sysvalue = systemProperties.getProperty(variable);
+                if (sysvalue == null) {
+                    // Try with the environment if there was no
+                    // property by that name.
+                    sysvalue = System.getenv(variable);
+                }
+                if (sysvalue != null) {
+                    String strtoken = propValue.substring(ctoken, btoken);
+                    expanded.append(strtoken);
+                    expanded.append(sysvalue);
+                    ctoken = etoken + ETOKEN.length();
+                }
+            }
+            else {
+                // We have "${" without "}"
+                throw new ParseException("Error while looking for teminating '" +
+                                         ETOKEN + "'", btoken);
+            }
+            btoken = propValue.indexOf(BTOKEN, etoken + ETOKEN.length());
+        }
+        // Add what's left.
+        expanded.append(propValue.substring(ctoken, propValue.length()));
+        return expanded.toString();
+    }
+
+    /**
+     * Get the configuration property.
+     * @param name The name of the property to get.
+     *
+     * @throws ParseException if the property is wrongly formatted.
+     */
+    public String getProperty(String name)
+        throws ParseException
+    {
+        if (name == null)
+            return null;
+        else
+            return expandProperty(configurationProperties.getProperty(PREFIX + name));
+    }
+
+    /**
+     * Get the configuration property array.
+     * <p>
+     * Property array is constructed form the lsit of properties
+     * which end with <code>[index]</code>
+     * </p>
+     * <pre>
+     * daemon.arg[0] = argument 1
+     * daemon.arg[1] = argument 2
+     * daemon.arg[2] = argument 3
+     * </pre>
+     * @param name The name of the property array to get.
+     *
+     * @throws ParseException if the property is wrongly formatted.
+     */
+    public String[] getPropertyArray(String name)
+        throws ParseException
+    {
+        ArrayList list = new ArrayList();
+        String    args;
+
+        // Load daemon.arg[0] ... daemon.arg[n] into the String array.
+        //
+        while ((args = getProperty(name + "[" + list.size() + "]")) != null) {
+            list.add(args);
+        }
+        return (String[])list.toArray(new String[list.size()]);
+    }
+
+}
+
diff --git a/src/java/org/apache/commons/daemon/support/DaemonLoader.java b/src/java/org/apache/commons/daemon/support/DaemonLoader.java
index 38a491a..388d9a1 100644
--- a/src/java/org/apache/commons/daemon/support/DaemonLoader.java
+++ b/src/java/org/apache/commons/daemon/support/DaemonLoader.java
@@ -19,13 +19,15 @@ package org.apache.commons.daemon.support;
 
 import org.apache.commons.daemon.DaemonContext;
 import org.apache.commons.daemon.DaemonController;
+import org.apache.commons.daemon.DaemonInitException;
 
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 
 /*
  * Used by jsvc for Daemon management.
  *
- * @version 1.0 <i>(SVN $Revision: 925053 $)</i>
+ * @version 1.0 <i>(SVN $Revision: 1023471 $)</i>
  */
 public final class DaemonLoader
 {
@@ -50,6 +52,12 @@ public final class DaemonLoader
                            " (build " +
                            System.getProperty("java.vm.version") +
                            ", " + System.getProperty("java.vm.info") + ")");
+        System.err.println("commons daemon version \"" +
+                System.getProperty("commons.daemon.version") + "\"");
+        System.err.println("commons daemon process (id: " +
+                           System.getProperty("commons.daemon.process.id") +
+                           ", parent: " +
+                           System.getProperty("commons.daemon.process.parent") + ")");
     }
 
     public static boolean check(String cn)
@@ -88,7 +96,7 @@ public final class DaemonLoader
         return true;
     }
 
-    public static boolean load(String cn, String ar[])
+    public static boolean load(String className, String args[])
     {
         try {
             /* Make sure any previous instance is garbage collected */
@@ -96,11 +104,11 @@ public final class DaemonLoader
 
             /* Check if the underlying libray supplied a valid list of
                arguments */
-            if (ar == null)
-                ar = new String[0];
+            if (args == null)
+                args = new String[0];
 
             /* Check the class name */
-            if (cn == null)
+            if (className == null)
                 throw new NullPointerException("Null class name specified");
 
             /* Get the ClassLoader loading this class */
@@ -109,31 +117,42 @@ public final class DaemonLoader
                 System.err.println("Cannot retrieve ClassLoader instance");
                 return false;
             }
-
-            /* Find the required class */
-            Class c = cl.loadClass(cn);
-
+            Class c;
+            if (className.charAt(0) == '@') {
+                /* Wrapp the class with DaemonWrapper
+                 * and modify arguments to include the real class name.
+                 */
+                c = DaemonWrapper.class;
+                String[] a = new String[args.length + 2];
+                a[0] = "-start";
+                a[1] = className.substring(1);
+                System.arraycopy(args, 0, a, 2, args.length);
+                args = a;
+            }
+            else
+                c = cl.loadClass(className);
             /* This should _never_ happen, but doublechecking doesn't harm */
             if (c == null)
-                throw new ClassNotFoundException(cn);
-
-            /* Check interface */
+                throw new ClassNotFoundException(className);
+            /* Check interfaces */
             boolean isdaemon = false;
+
             try {
                 Class dclass =
                     cl.loadClass("org.apache.commons.daemon.Daemon");
                 isdaemon = dclass.isAssignableFrom(c);
-            } catch (Exception cnfex) {
+            }
+            catch (Exception cnfex) {
                 // Swallow if Daemon not found.
             }
 
             /* Check methods */
-            Class[]myclass = new Class[1];
+            Class[] myclass = new Class[1];
             if (isdaemon) {
                 myclass[0] = DaemonContext.class;
             }
             else {
-                myclass[0] = ar.getClass();
+                myclass[0] = args.getClass();
             }
 
             init    = c.getMethod("init", myclass);
@@ -155,7 +174,7 @@ public final class DaemonLoader
 
                 /* Create context */
                 Context context = new Context();
-                context.setArguments(ar);
+                context.setArguments(args);
                 context.setController(controller);
 
                 /* Now we want to call the init method in the class */
@@ -165,11 +184,23 @@ public final class DaemonLoader
             }
             else {
                 Object arg[] = new Object[1];
-                arg[0] = ar;
+                arg[0] = args;
                 init.invoke(daemon, arg);
             }
 
-        } catch (Throwable t) {
+        }
+        catch (InvocationTargetException e) {
+            Throwable thrown = e.getTargetException();
+            /* DaemonInitExceptions can fail with a nicer message */
+            if (thrown instanceof DaemonInitException) {
+                failed(((DaemonInitException) thrown).getMessageWithCause());
+            }
+            else {
+                thrown.printStackTrace(System.err);
+            }
+            return false;
+        }
+        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).
              */
@@ -306,41 +337,32 @@ public final class DaemonLoader
         }
 
         public void fail()
-            throws IllegalStateException
         {
             fail(null, null);
         }
 
         public void fail(String message)
-            throws IllegalStateException
         {
             fail(message, null);
         }
 
         public void fail(Exception exception)
-            throws IllegalStateException
         {
             fail(null, exception);
         }
 
         public void fail(String message, Exception exception)
-            throws IllegalStateException
         {
             synchronized (this) {
-                if (!this.isAvailable()) {
-                    throw new IllegalStateException();
-                }
-                else {
-                    this.setAvailable(false);
-                    String msg = message;
-                    if (exception != null) {
-                        if (msg != null)
-                            msg = msg + ": " + exception.toString();
-                        else
-                            msg = exception.toString();
-                    }
-                    DaemonLoader.failed(msg);
+                this.setAvailable(false);
+                String msg = message;
+                if (exception != null) {
+                    if (msg != null)
+                        msg = msg + ": " + exception.toString();
+                    else
+                        msg = exception.toString();
                 }
+                DaemonLoader.failed(msg);
             }
         }
 
diff --git a/src/java/org/apache/commons/daemon/support/DaemonWrapper.java b/src/java/org/apache/commons/daemon/support/DaemonWrapper.java
new file mode 100644
index 0000000..b7e1cc0
--- /dev/null
+++ b/src/java/org/apache/commons/daemon/support/DaemonWrapper.java
@@ -0,0 +1,267 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You 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: Main.java 937350 2010-04-23 16:03:39Z mturk $ */
+
+package org.apache.commons.daemon.support;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import org.apache.commons.daemon.Daemon;
+import org.apache.commons.daemon.DaemonContext;
+
+/**
+ * Implementation of the Daemon that allows running
+ * standard applications as daemons.
+ * The applications must have the mechanism to manage
+ * the application lifecycle.
+ *
+ * @version 1.0 <i>(SVN $Revision: 925053 $)</i>
+ * @author Mladen Turk
+ */
+public class DaemonWrapper implements Daemon
+{
+
+    private final static String ARGS            = "args";
+    private final static String START_CLASS     = "start";
+    private final static String START_METHOD    = "start.method";
+    private final static String STOP_CLASS      = "stop";
+    private final static String STOP_METHOD     = "stop.method";
+    private final static String STOP_ARGS       = "stop.args";
+    private String              configFileName  = null;
+    private final DaemonConfiguration config;
+
+    private final Invoker             startup;
+    private final Invoker             shutdown;
+
+    public DaemonWrapper()
+    {
+        super();
+        config   = new DaemonConfiguration();
+        startup  = new Invoker();
+        shutdown = new Invoker();
+    }
+
+    /**
+     * Called from DaemonLoader on init stage.
+     * <p>
+     * Accepts the following configuration arguments:
+     * <ul>
+     * <li>-daemon-properties: - load DaemonConfiguration properties from the specified file to act as defaults</li>
+     * <li>-start: set start class name</li>
+     * <li>-start-method: set start method name</li>
+     * <li>-stop: set stop class name</li>
+     * <li>-stop-method: set stop method name</li>
+     * <li>-stop-argument: set optional argument to stop method</li>
+     * <li>Anything else is treated as a startup argument</li>
+     * </ul>
+     * <p>
+     * The following "-daemon-properties" are recognised:
+     * <ul>
+     * <li>args (startup argument)</li>
+     * <li>start</li>
+     * <li>start.method</li>
+     * <li>stop</li>
+     * <li>stop.method</li>
+     * <li>stop.args</li>
+     * </ul>
+     * These are used to set the corresponding item if it has not already been
+     * set by the command arguments. <b>However, note that args and stop.args are
+     * appended to any existing values.</b>
+     */
+    public void init(DaemonContext context)
+        throws Exception
+    {
+        String[] args = context.getArguments();
+
+        if (args != null) {
+            int i;
+            // Parse our arguments and remove them
+            // from the final argument array we are
+            // passing to our child.
+            for (i = 0; i < args.length; i++) {
+                if (args[i].equals("--")) {
+                    // Done with argument processing
+                    break;
+                }
+                else if (args[i].equals("-daemon-properties")) {
+                    if (++i == args.length)
+                        throw new IllegalArgumentException(args[i - 1]);
+                    configFileName = args[i];
+                }
+                else if (args[i].equals("-start")) {
+                    if (++i == args.length)
+                        throw new IllegalArgumentException(args[i - 1]);
+                    startup.setClassName(args[i]);
+                }
+                else if (args[i].equals("-start-method")) {
+                    if (++i == args.length)
+                        throw new IllegalArgumentException(args[i - 1]);
+                    startup.setMethodName(args[i]);
+                }
+                else if (args[i].equals("-stop")) {
+                    if (++i == args.length)
+                        throw new IllegalArgumentException(args[i - 1]);
+                    shutdown.setClassName(args[i]);
+                }
+                else if (args[i].equals("-stop-method")) {
+                    if (++i == args.length)
+                        throw new IllegalArgumentException(args[i - 1]);
+                    shutdown.setMethodName(args[i]);
+                }
+                else if (args[i].equals("-stop-argument")) {
+                    if (++i == args.length)
+                        throw new IllegalArgumentException(args[i - 1]);
+                    String[] aa = new String[1];
+                    aa[0] = args[i];
+                    shutdown.addArguments(aa);
+                }
+                else {
+                    // This is not our option.
+                    // Everything else will be forwarded to the main
+                    break;
+                }
+            }
+            if (args.length > i) {
+                String[] copy = new String[args.length - i];
+                System.arraycopy(args, i, copy, 0, copy.length);
+                startup.addArguments(copy);
+            }
+        }
+        if (config.load(configFileName)) {
+            // Setup params if not set via cmdline.
+            startup.setClassName(config.getProperty(START_CLASS));
+            startup.setMethodName(config.getProperty(START_METHOD));
+            // Merge the config with command line arguments
+            startup.addArguments(config.getPropertyArray(ARGS));
+
+            shutdown.setClassName(config.getProperty(STOP_CLASS));
+            shutdown.setMethodName(config.getProperty(STOP_METHOD));
+            shutdown.addArguments(config.getPropertyArray(STOP_ARGS));
+        }
+        startup.validate();
+        shutdown.validate();
+    }
+
+    /**
+     */
+    public void start()
+        throws Exception
+    {
+        startup.invoke();
+    }
+
+    /**
+     */
+    public void stop()
+        throws Exception
+    {
+        shutdown.invoke();
+    }
+
+    /**
+     */
+    public void destroy()
+    {
+        // Nothing for the moment
+        System.err.println("DaemonWrapper: instance " + this.hashCode() + " destroy");
+    }
+
+    // Internal class for wrapping the start/stop methods
+    class Invoker
+    {
+        private String      name = null;
+        private String      call = null;
+        private String[]    args = null;
+        private Method      inst = null;
+        private Class       main = null;
+
+        protected Invoker()
+        {
+        }
+
+        protected void setClassName(String name)
+        {
+            if (this.name == null)
+                this.name = name;
+        }
+        protected void setMethodName(String name)
+        {
+            if (this.call == null)
+                this.call = name;
+        }
+        protected void addArguments(String[] args)
+        {
+            if (args != null) {
+                ArrayList aa = new ArrayList();
+                if (this.args != null)
+                    aa.addAll(Arrays.asList(this.args));
+                aa.addAll(Arrays.asList(args));
+                this.args = (String[])aa.toArray(new String[aa.size()]);
+            }
+        }
+
+        protected void invoke()
+            throws Exception
+        {
+            if (name.equals("System") && call.equals("exit")) {
+                // Just call a System.exit()
+                // The start method was probably installed
+                // a shutdown hook.
+                System.exit(0);
+            }
+            else {
+                Object obj   = main.newInstance();
+                Object arg[] = new Object[1];
+
+                arg[0] = args;
+                inst.invoke(obj, arg);
+            }
+        }
+        // Load the class using reflection
+        protected void validate()
+            throws Exception
+        {
+            /* Check the class name */
+            if (name == null) {
+                name = "System";
+                call = "exit";
+                return;
+            }
+            if (args == null)
+                args = new String[0];
+            if (call == null)
+                call = "main";
+
+            // Get the ClassLoader loading this class
+            ClassLoader cl = DaemonWrapper.class.getClassLoader();
+            if (cl == null)
+                throw new NullPointerException("Cannot retrieve ClassLoader instance");
+            Class[] ca = new Class[1];
+            ca[0]      = args.getClass();
+            // Find the required class
+            main = cl.loadClass(name);
+            if (main == null)
+                throw new ClassNotFoundException(name);
+            // Find the required method.
+            // NoSuchMethodException will be thrown if matching method
+            // is not found.
+            inst = main.getMethod(call, ca);
+        }
+    }
+}
diff --git a/src/native/nt/procrun/apps/prunmgr/prunmgr.manifest b/src/native/nt/procrun/apps/prunmgr/prunmgr.manifest
deleted file mode 100644
index 7d4e33b..0000000
--- a/src/native/nt/procrun/apps/prunmgr/prunmgr.manifest
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
-<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> 
-<assemblyIdentity version="3.1.0.0" processorArchitecture="*" name="Apache.Procrun.Prunmgr" type="win32" /> 
-<description>Apache Procrun Service Manager</description> 
-<dependency> 
-<dependentAssembly> 
-<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*" /> 
-</dependentAssembly> 
-</dependency> 
-</assembly> 
diff --git a/src/native/unix/CHANGES.txt b/src/native/unix/CHANGES.txt
index eaa7603..4872da2 100644
--- a/src/native/unix/CHANGES.txt
+++ b/src/native/unix/CHANGES.txt
@@ -1,5 +1,12 @@
 APACHE COMMONS DAEMON (UNIX) CHANGELOG:
-Last modified at [$Date: 2010-03-15 10:50:28 +0100 (Mon, 15 Mar 2010) $]
+Last modified at [$Date: 2010-10-20 08:13:44 +0200 (Wed, 20 Oct 2010) $]
+
+Changes with 1.0.4
+  * Add DaemonWrapper to allow running standard applications
+    as daemons. (DAEMON-180)
+  * Support log rotation using SIGUSR1 (DAEMON-95)
+  * Fix FreeBSD build (DAEMON-171)
+  * Add support for config.nice and strip utility (DAEMON-176)
 
 Changes with 1.0.3
   * Implement fail() method (DAEMON-128)
diff --git a/src/native/unix/INSTALL.txt b/src/native/unix/INSTALL.txt
index f1a5917..16225bc 100644
--- a/src/native/unix/INSTALL.txt
+++ b/src/native/unix/INSTALL.txt
@@ -67,3 +67,13 @@ the fat binaries enter the specific parameters before calling configure
    ./configure
    make
 
+Optional Build flags
+
+Make process allows specifying additional compilation flags at compile time
+by using EXTRA_CFLAGS and EXTRA_LDFLAGS either as environment variables
+or defined along the make command line
+
+    make EXTRA_CFLAGS="-march=i586"
+
+will cause -march=i586 to be added to the configure generated CFLAGS.
+The same applies to EXTRA_LDFLAGS which will be added at link stage.
diff --git a/src/native/unix/Makedefs.in b/src/native/unix/Makedefs.in
index 07fb502..68bc498 100644
--- a/src/native/unix/Makedefs.in
+++ b/src/native/unix/Makedefs.in
@@ -16,17 +16,19 @@
 #
 
 # @author  Pier Fumagalli <mailto:pier.fumagalli at eng.sun.com>
-# @version $Id: Makedefs.in 480475 2006-11-29 08:31:47Z bayard $
+# @version $Id: Makedefs.in 1023247 2010-10-16 11:21:22Z mturk $
 
 CC = @CC@
 JAVAC = @JAVAC@
 JAR = @JAR@
 CFLAGS = @CFLAGS@
+INCLUDES = @INCLUDES@
 LDFLAGS = @LDFLAGS@
 LIBS = @LIBS@
 JAVACFLAGS = @JAVACFLAGS@
 RANLIB = @RANLIB@
 LDCMD = @LDCMD@
+STRIP = @STRIP@
 
 .c.o:
-	$(CC) $(CFLAGS) -c $< -o $@
+	$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(INCLUDES) -c $< -o $@
diff --git a/src/native/unix/Makefile.in b/src/native/unix/Makefile.in
index c8c48da..ceccaf6 100644
--- a/src/native/unix/Makefile.in
+++ b/src/native/unix/Makefile.in
@@ -16,7 +16,7 @@
 #
 
 # @author  Pier Fumagalli <mailto:pier.fumagalli at eng.sun.com>
-# @version $Id: Makefile.in 480475 2006-11-29 08:31:47Z bayard $
+# @version $Id: Makefile.in 1003756 2010-10-02 08:59:48Z mturk $
 
 SUBDIRS = native
 
@@ -32,9 +32,11 @@ distclean: clean
 	rm -f config.cache
 	rm -f config.log
 	rm -f config.status
+	rm -f config.nice
 	rm -f native/Makefile
 	rm -f Makefile
 	rm -f Makedefs
+	rm -rf autom4te.cache
 
 realclean: distclean
 	rm -f configure
diff --git a/src/native/unix/configure b/src/native/unix/configure
index c486179..e8ef758 100755
--- a/src/native/unix/configure
+++ b/src/native/unix/configure
@@ -272,7 +272,7 @@ 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_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 STRIP  [...]
 ac_subst_files=''
 
 # Initialize some variables set by options.
@@ -1278,6 +1278,57 @@ ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
 
 
 
+  rm -f config.nice
+  cat >config.nice<<EOF
+#! /bin/sh
+#
+# Created by configure
+
+EOF
+  if test -n "$CC"; then
+    echo "CC=\"$CC\"; export CC" >> config.nice
+  fi
+  if test -n "$CFLAGS"; then
+    echo "CFLAGS=\"$CFLAGS\"; export CFLAGS" >> config.nice
+  fi
+  if test -n "$CPPFLAGS"; then
+    echo "CPPFLAGS=\"$CPPFLAGS\"; export CPPFLAGS" >> config.nice
+  fi
+  if test -n "$LDFLAGS"; then
+    echo "LDFLAGS=\"$LDFLAGS\"; export LDFLAGS" >> config.nice
+  fi
+  if test -n "$LIBS"; then
+    echo "LIBS=\"$LIBS\"; export LIBS" >> config.nice
+  fi
+  if test -n "$STRIPFLAGS"; then
+    echo "STRIPFLAGS=\"$STRIPFLAGS\"; export STRIPFLAGS" >> config.nice
+  fi
+  if test -n "$INCLUDES"; then
+    echo "INCLUDES=\"$INCLUDES\"; export INCLUDES" >> config.nice
+  fi
+# Retrieve command-line arguments.
+  eval "set x $0 $ac_configure_args"
+  shift
+
+  for arg
+  do
+
+ap_last=
+ap_cur="$arg"
+while test "x${ap_cur}" != "x${ap_last}";
+do
+  ap_last="${ap_cur}"
+  ap_cur=`eval "echo ${ap_cur}"`
+done
+arg="${ap_cur}"
+
+    echo "\"$arg\" \\" >> config.nice
+  done
+  echo '"$@"' >> config.nice
+  chmod +x config.nice
+
+
+
   printf "*** %s ***\n" "Current host" 1>&2
 
 
@@ -2368,6 +2419,86 @@ else
   RANLIB="$ac_cv_prog_RANLIB"
 fi
 
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; 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_STRIP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # 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_STRIP="${ac_tool_prefix}strip"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+  echo "$as_me:$LINENO: result: $STRIP" >&5
+echo "${ECHO_T}$STRIP" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+  ac_ct_STRIP=$STRIP
+  # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; 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_STRIP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_STRIP"; then
+  ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # 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_STRIP="strip"
+    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_STRIP" && ac_cv_prog_ac_ct_STRIP=":"
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+  echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5
+echo "${ECHO_T}$ac_ct_STRIP" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  STRIP=$ac_ct_STRIP
+else
+  STRIP="$ac_cv_prog_STRIP"
+fi
+
 
 
   printf "*** %s ***\n" "Host support" 1>&2
@@ -2441,7 +2572,7 @@ echo "$as_me: error: Unsupported operating system \"$host_os\"" >&2;}
   i?86)
     CFLAGS="$CFLAGS -DCPU=\\\"i386\\\""
     HOST_CPU=i386;;
-  x86_64)
+  x86_64 | amd64)
     CFLAGS="$CFLAGS -DCPU=\\\"amd64\\\""
     HOST_CPU=amd64;;
   bs2000)
@@ -2506,7 +2637,7 @@ then
   else
     cd /System/Library/Frameworks/JavaVM.framework/Headers
   fi
-  CFLAGS="$CFLAGS -I`/bin/pwd -P`"
+  INCLUDES="$INCLUDES -I`/bin/pwd -P`"
   cd $_prevdir
   unset _prevdir
 fi
@@ -2966,7 +3097,7 @@ echo "$as_me: error: jar not found" >&2;}
 
 if test "$supported_os" != "darwin"
 then
-  CFLAGS="$CFLAGS -I$JAVA_HOME/include -I$JAVA_HOME/include/$supported_os"
+  INCLUDES="$INCLUDES -I$JAVA_HOME/include -I$JAVA_HOME/include/$supported_os"
 fi
 
 if test "$GCC" = "yes"
@@ -2980,7 +3111,7 @@ then
    LDCMD="$CC"
 fi
 
-if test "$supported_os" == "linux"
+if test "$supported_os" = "linux"
 then
 
 echo "$as_me:$LINENO: checking for cap_init in -lcap" >&5
@@ -3053,6 +3184,14 @@ fi
 
 fi
 
+if test -z "$STRIPFLAGS"
+then
+   STRIP="@: "
+else
+   STRIP="$STRIP $STRIPFLAGS"
+fi
+
+
 
   printf "*** %s ***\n" "Writing output files" 1>&2
 
@@ -3711,6 +3850,8 @@ 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 STRIP@,$STRIP,;t t
+s, at ac_ct_STRIP@,$ac_ct_STRIP,;t t
 s, at JAVA_HOME@,$JAVA_HOME,;t t
 s, at SABLEVM@,$SABLEVM,;t t
 s, at KAFFEVM@,$KAFFEVM,;t t
@@ -3720,6 +3861,7 @@ s, at JAVACFLAGS@,$JAVACFLAGS,;t t
 s, at JARSABLE@,$JARSABLE,;t t
 s, at JAR@,$JAR,;t t
 s, at LDCMD@,$LDCMD,;t t
+s, at INCLUDES@,$INCLUDES,;t t
 s, at LIBOBJS@,$LIBOBJS,;t t
 s, at LTLIBOBJS@,$LTLIBOBJS,;t t
 CEOF
diff --git a/src/native/unix/configure.in b/src/native/unix/configure.in
index 78b9694..1b6aecd 100644
--- a/src/native/unix/configure.in
+++ b/src/native/unix/configure.in
@@ -17,7 +17,7 @@ dnl
 
 dnl -------------------------------------------------------------------------
 dnl Author  Pier Fumagalli <mailto:pier.fumagalli at eng.sun.com>
-dnl Version $Id: configure.in 980496 2010-07-29 16:10:32Z mturk $
+dnl Version $Id: configure.in 1003756 2010-10-02 08:59:48Z mturk $
 dnl -------------------------------------------------------------------------
 
 dnl -------------------------------------------------------------------------
@@ -32,6 +32,10 @@ sinclude(./support/apsupport.m4)dnl
 AC_INIT(configure.in)
 AC_CONFIG_AUX_DIR(./support)
 
+dnl Generate ./config.nice for reproducing runs of configure
+dnl
+AP_CONFIG_NICE(config.nice)
+
 dnl -------------------------------------------------------------------------
 dnl Check current host (forget about cross compilation) and validate it
 dnl against the cache (fail if the cache differs)
@@ -46,6 +50,7 @@ dnl -------------------------------------------------------------------------
 AP_MSG_HEADER([C-Language compilation tools])
 AC_PROG_CC()
 AC_CHECK_TOOL(RANLIB, ranlib, :)
+AC_CHECK_TOOL(STRIP, strip, :)
 
 dnl -------------------------------------------------------------------------
 dnl Check if this host is supported
@@ -66,7 +71,7 @@ then
   else
     cd /System/Library/Frameworks/JavaVM.framework/Headers
   fi
-  CFLAGS="$CFLAGS -I`/bin/pwd -P`"
+  INCLUDES="$INCLUDES -I`/bin/pwd -P`"
   cd $_prevdir
   unset _prevdir
 fi
@@ -82,7 +87,7 @@ AP_PROG_JAVAC()
 AP_PROG_JAR()
 if test "$supported_os" != "darwin"
 then
-  CFLAGS="$CFLAGS -I$JAVA_HOME/include -I$JAVA_HOME/include/$supported_os"
+  INCLUDES="$INCLUDES -I$JAVA_HOME/include -I$JAVA_HOME/include/$supported_os"
 fi
 
 dnl -------------------------------------------------------------------------
@@ -101,11 +106,19 @@ then
    LDCMD="$CC"
 fi
 AC_SUBST(LDCMD)
-if test "$supported_os" == "linux"
+if test "$supported_os" = "linux"
 then
 AC_CHECK_LIB([cap], [cap_init], [CFLAGS="$CFLAGS -DHAVE_LIBCAP" ; LIBS="$LIBS -lcap"])
 fi
 
+if test -z "$STRIPFLAGS"
+then
+   STRIP="@: "
+else
+   STRIP="$STRIP $STRIPFLAGS"
+fi
+
+AC_SUBST(INCLUDES)
 dnl -------------------------------------------------------------------------
 dnl Random programs we need to compile locally
 dnl -------------------------------------------------------------------------
diff --git a/src/native/unix/man/jsvc.1.xml b/src/native/unix/man/jsvc.1.xml
index 055c603..5180aa7 100644
--- a/src/native/unix/man/jsvc.1.xml
+++ b/src/native/unix/man/jsvc.1.xml
@@ -21,8 +21,8 @@
   <refmeta>
     <refentrytitle>JSVC</refentrytitle>
     <manvolnum>1</manvolnum>
-    <refmiscinfo class='date'>May 2005</refmiscinfo>
-    <refmiscinfo class='source'>Jsvc version 1.0.1</refmiscinfo>
+    <refmiscinfo class='date'>October 2010</refmiscinfo>
+    <refmiscinfo class='source'>Jsvc version 1.0.4</refmiscinfo>
     <refmiscinfo class='manual'>Apache Commons project</refmiscinfo>
   </refmeta>
   <refnamediv id='name'>
@@ -36,7 +36,7 @@
       <arg choice='opt'>-jvm <replaceable>JVM name</replaceable></arg>
       <arg choice='opt'>-classpath <replaceable>path</replaceable></arg>
       <arg choice='opt'>-cp <replaceable>path</replaceable></arg>
-      <arg choice='opt'>-home <replaceable>directory</replaceable></arg>
+      <arg choice='opt'>-java-home <replaceable>directory</replaceable></arg>
       <arg choice='opt'>-version</arg>
       <arg choice='opt'>-help</arg>
       <arg choice='opt'>-?</arg>
@@ -72,14 +72,14 @@
         </listitem>
       </varlistentry>
       <varlistentry>
-        <term><option>-cp/ -classpath</option> directory and zip/jar 
+        <term><option>-cp/ -classpath</option> directory and zip/jar
           files</term>
         <listitem>
           <para>set search path for service classes and resouces</para>
         </listitem>
       </varlistentry>
       <varlistentry>
-        <term><option>-home</option> directory</term>
+        <term><option>-java-home</option> directory</term>
         <listitem>
           <para>set the path of your JDK or JRE installation (or set
                 the JAVA_HOME environment variable)
@@ -146,21 +146,25 @@
       <varlistentry>
         <term><option>-outfile</option> /full/path/to/file</term>
         <listitem>
-          <para>Location for output from stdout (defaults to /dev/null). Use 
-            the value '&2' to simulate '1>&2'</para>
+          <para>Location for output from stdout (defaults to
+            /dev/null). Use the value '&2' to simulate
+            '1>&2', or 'SYSLOG' to send output to the system
+            log.</para>
         </listitem>
       </varlistentry>
       <varlistentry>
         <term><option>-errfile</option> /full/path/to/file</term>
         <listitem>
-          <para>Location for output from stderr (defaults to /dev/null). Use 
-            the value '&1' to simulate '2>&1'</para>
+          <para>Location for output from stderr (defaults to
+            /dev/null). Use the value '&1' to simulate
+            '2>&1', or 'SYSLOG' to send output to the system
+            log.</para>
         </listitem>
       </varlistentry>
       <varlistentry>
         <term><option>-pidfile</option> /full/path/to/file</term>
         <listitem>
-          <para>Location for output from the file containing the pid of jsvc 
+          <para>Location for output from the file containing the pid of jsvc
             (defaults to /var/run/jsvc.pid)</para>
         </listitem>
       </varlistentry>
@@ -180,8 +184,8 @@
   </refsect1>
 
   <refsect1 id='author'><title>AUTHOR</title>
-    <para>JSVC is part of the Apache Commons Daemon project. Authors are 
-      Jean-Frederic Clere, Remy Maucherat, Yoav Shapira, Bill Barker. JSVC is 
+    <para>JSVC is part of the Apache Commons Daemon project. Authors are
+      Jean-Frederic Clere, Remy Maucherat, Yoav Shapira, Bill Barker. JSVC is
       under the Apache License Version 2.0.</para>
   </refsect1>
 
diff --git a/src/native/unix/native/Makefile.in b/src/native/unix/native/Makefile.in
index 346fffb..fb6b5e5 100644
--- a/src/native/unix/native/Makefile.in
+++ b/src/native/unix/native/Makefile.in
@@ -15,7 +15,7 @@
 # limitations under the License.
 #
 # @author  Pier Fumagalli <mailto:pier.fumagalli at eng.sun.com>
-# @version $Id: Makefile.in 909069 2010-02-11 16:43:36Z mturk $
+# @version $Id: Makefile.in 1025844 2010-10-21 06:17:47Z mturk $
 
 include ../Makedefs
 
@@ -38,7 +38,8 @@ libservice.a: $(OBJS)
 	$(RANLIB) libservice.a
 
 jsvc: jsvc-unix.o libservice.a
-	$(LDCMD) $(LDFLAGS) jsvc-unix.o libservice.a $(LIBS) -o ../jsvc
+	$(LDCMD) $(LDFLAGS) $(EXTRA_LDFLAGS) jsvc-unix.o libservice.a $(LIBS) -o ../jsvc
+	$(STRIP) ../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
deleted file mode 100755
index 3765fb4..0000000
--- a/src/native/unix/native/Tomcat.sh
+++ /dev/null
@@ -1,78 +0,0 @@
-#!/bin/sh
-##############################################################################
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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/arguments.c b/src/native/unix/native/arguments.c
index d38ddc1..9ba9f43 100644
--- a/src/native/unix/native/arguments.c
+++ b/src/native/unix/native/arguments.c
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-/* @version $Id: arguments.c 967041 2010-07-23 10:59:51Z mturk $ */
+/* @version $Id: arguments.c 1023099 2010-10-15 20:26:38Z mturk $ */
 #include "jsvc.h"
 #include <limits.h>
 #include <glob.h>
@@ -211,7 +211,8 @@ static arg_data *parse(int argc, char *argv[])
                 return NULL;
             }
         }
-        else if (!strcmp(argv[x], "-home")) {
+        else if (!strcmp(argv[x], "-home") ||
+                 !strcmp(argv[x], "-java-home")) {
             args->home = optional(argc, argv, x++);
             if (args->home == NULL) {
                 log_error("Invalid Java Home specified");
diff --git a/src/native/unix/native/debug.c b/src/native/unix/native/debug.c
index 7fc4c4b..aab484e 100644
--- a/src/native/unix/native/debug.c
+++ b/src/native/unix/native/debug.c
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-/* @version $Id: debug.c 921765 2010-03-11 10:03:32Z mturk $ */
+/* @version $Id: debug.c 982549 2010-08-05 11:43:42Z mturk $ */
 #include "jsvc.h"
 #include <sys/types.h>
 #include <unistd.h>
@@ -23,6 +23,12 @@
 /* Wether debug is enabled or not */
 bool log_debug_flag = false;
 
+/* Wether SYSLOG logging (for stderr) is enable or not. */
+bool log_stderr_syslog_flag = false;
+
+/* Wether SYSLOG logging (for stdout) is enable or not. */
+bool log_stdout_syslog_flag = false;
+
 /* The name of the jsvc binary. */
 char *log_prog = "jsvc";
 
@@ -39,12 +45,13 @@ void log_debug(const char *fmt, ...)
     if (fmt == NULL)
         return;
 
-    now   = time(NULL);
-    nowtm = localtime(&now);
-    strftime(buff, sizeof(buff), "%d/%m/%Y %T", nowtm);
-
     va_start(ap, fmt);
-    fprintf(stderr, "%s %d %s debug: ", buff, getpid(), log_prog);
+    if (log_stderr_syslog_flag) {
+        now   = time(NULL);
+        nowtm = localtime(&now);
+        strftime(buff, sizeof(buff), "%d/%m/%Y %T", nowtm);
+        fprintf(stderr, "%s %d %s debug: ", buff, getpid(), log_prog);
+    }
     vfprintf(stderr, fmt, ap);
     fprintf(stderr, "\n");
     fflush(stderr);
@@ -62,12 +69,13 @@ void log_error(const char *fmt, ...)
     if (fmt == NULL)
         return;
 
-    now = time(NULL);
-    nowtm = localtime(&now);
-    strftime(buff, sizeof(buff), "%d/%m/%Y %T", nowtm);
-
     va_start(ap, fmt);
-    fprintf(stderr, "%s %d %s error: ", buff, getpid(), log_prog);
+    if (log_stderr_syslog_flag) {
+        now   = time(NULL);
+        nowtm = localtime(&now);
+        strftime(buff, sizeof(buff), "%d/%m/%Y %T", nowtm);
+        fprintf(stderr, "%s %d %s error: ", buff, getpid(), log_prog);
+    }
     vfprintf(stderr, fmt, ap);
     fprintf(stderr, "\n");
     fflush(stderr);
diff --git a/src/native/unix/native/debug.h b/src/native/unix/native/debug.h
index 3a1331c..7e1025c 100644
--- a/src/native/unix/native/debug.h
+++ b/src/native/unix/native/debug.h
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-/* @version $Id: debug.h 921765 2010-03-11 10:03:32Z mturk $ */
+/* @version $Id: debug.h 982549 2010-08-05 11:43:42Z mturk $ */
 #ifndef __JSVC_DEBUG_H__
 #define __JSVC_DEBUG_H__
 
@@ -26,6 +26,12 @@ extern "C" {
  */
 extern bool log_debug_flag;
 
+/* Wether SYSLOG logging (for stderr) is enable or not. */
+extern bool log_stderr_syslog_flag;
+
+/* Wether SYSLOG logging (for stdout) is enable or not. */
+extern bool log_stdout_syslog_flag;
+
 /**
  * The name of the jsvc binary.
  */
diff --git a/src/native/unix/native/help.c b/src/native/unix/native/help.c
index 668b68c..e337825 100644
--- a/src/native/unix/native/help.c
+++ b/src/native/unix/native/help.c
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-/* @version $Id: help.c 923087 2010-03-15 07:00:01Z mturk $ */
+/* @version $Id: help.c 1023182 2010-10-16 05:26:53Z mturk $ */
 #include "jsvc.h"
 
 void help(home_data *data)
@@ -35,9 +35,9 @@ void help(home_data *data)
     }
     printf("\n");
 
-    printf("    -cp / -classpath <directories and zip/jar files>\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("    -java-home | -home <directory>\n");
     printf("        set the path of your JDK or JRE installation (or set\n");
     printf("        the JAVA_HOME environment variable)\n");
 
diff --git a/src/native/unix/native/home.c b/src/native/unix/native/home.c
index bfa66d9..8a411fe 100644
--- a/src/native/unix/native/home.c
+++ b/src/native/unix/native/home.c
@@ -5,16 +5,16 @@
    The ASF licenses this file to You 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 921765 2010-03-11 10:03:32Z mturk $ */
+/* @version $Id: home.c 1000002 2010-09-22 14:48:37Z mturk $ */
 #include "jsvc.h"
 
 /* Check if a path is a directory */
diff --git a/src/native/unix/native/java.c b/src/native/unix/native/java.c
index f6b3738..75d19d2 100644
--- a/src/native/unix/native/java.c
+++ b/src/native/unix/native/java.c
@@ -14,12 +14,13 @@
  * limitations under the License.
  */
 
-/* @version $Id: java.c 923123 2010-03-15 09:20:00Z mturk $ */
+/* @version $Id: java.c 1023457 2010-10-17 11:06:15Z mturk $ */
 #include "jsvc.h"
 
 #ifdef OS_CYGWIN
 typedef long long __int64;
 #endif
+#include <unistd.h>
 #include <jni.h>
 
 #ifdef CHARSET_EBCDIC
@@ -102,6 +103,8 @@ char *java_library(arg_data *args, home_data *data)
     return libf;
 }
 
+typedef jint (*jvm_create_t)(JavaVM **, JNIEnv **, JavaVMInitArgs *);
+
 /* Initialize the JVM and its environment, loading libraries and all */
 bool java_init(arg_data *args, home_data *data)
 {
@@ -110,7 +113,7 @@ bool java_init(arg_data *args, home_data *data)
     char appf[1024];
     struct stat sb;
 #endif /* ifdef OS_DARWIN */
-    jint(*symb) (JavaVM **, JNIEnv **, JavaVMInitArgs *);
+    jvm_create_t symb = NULL;
     JNINativeMethod nativemethods[2];
     JavaVMOption *opt = NULL;
     dso_handle libh   = NULL;
@@ -123,7 +126,7 @@ bool java_init(arg_data *args, home_data *data)
     char shutdownparams[] = "(Z)V";
     char failedmethod[]   = "failed";
     char failedparams[]   = "(Ljava/lang/String;)V";
-
+    char daemonprocid[64];
     /* Decide WHAT virtual machine we need to use */
     libf = java_library(args, data);
     if (libf == NULL) {
@@ -186,10 +189,10 @@ bool java_init(arg_data *args, home_data *data)
 #if defined(OSD_POSIX) || defined(HAVE_KAFFEVM)
     /* BS2000 and kaffe does not allow to call JNI_CreateJavaVM indirectly */
 #else
-    symb = dso_symbol(libh, "JNI_CreateJavaVM");
+    symb = (jvm_create_t)dso_symbol(libh, "JNI_CreateJavaVM");
     if (symb == NULL) {
 #ifdef OS_DARWIN
-        symb = dso_symbol(apph, "JNI_CreateJavaVM");
+        symb = (jvm_create_t)dso_symbol(apph, "JNI_CreateJavaVM");
         if (symb == NULL) {
 #endif /* ifdef OS_DARWIN */
             log_error("Cannot find JVM library entry point");
@@ -225,17 +228,32 @@ bool java_init(arg_data *args, home_data *data)
     }
 #endif
     arg.ignoreUnrecognized = FALSE;
-    arg.nOptions = args->onum;
-    arg.nOptions++;             /* Add abort code */
+    arg.nOptions = args->onum + 4; /* pid, ppid and abort */
     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;
     }
+    /* Add our daemon process id */
+    snprintf(daemonprocid, sizeof(daemonprocid),
+             "-Dcommons.daemon.process.id=%d", (int)getpid());
+    opt[x].optionString = strdup(daemonprocid);
+    jsvc_xlate_to_ascii(opt[x].optionString);
+    opt[x++].extraInfo  = NULL;
+    snprintf(daemonprocid, sizeof(daemonprocid),
+             "-Dcommons.daemon.process.parent=%d", (int)getppid());
+    opt[x].optionString = strdup(daemonprocid);
+    jsvc_xlate_to_ascii(opt[x].optionString);
+    opt[x++].extraInfo  = NULL;
+    snprintf(daemonprocid, sizeof(daemonprocid),
+             "-Dcommons.daemon.version=%s", JSVC_VERSION_STRING);
+    opt[x].optionString = strdup(daemonprocid);
+    jsvc_xlate_to_ascii(opt[x].optionString);
+    opt[x++].extraInfo  = NULL;
     opt[x].optionString = strdup("abort");
     jsvc_xlate_to_ascii(opt[x].optionString);
-    opt[x].extraInfo = java_abort123;
+    opt[x].extraInfo = (void *)java_abort123;
     arg.options = opt;
 
     /* Do some debugging */
@@ -244,7 +262,7 @@ bool java_init(arg_data *args, home_data *data)
         log_debug("| Version:                       %#08x", arg.version);
         log_debug("| Ignore Unrecognized Arguments: %s",
                   arg.ignoreUnrecognized == TRUE ? "True" : "False");
-        log_debug("| Extra options:                 %d", arg.nOptions);
+        log_debug("| Extra options:                 %d", args->onum);
 
         for (x = 0; x < args->onum; x++) {
             jsvc_xlate_from_ascii(opt[x].optionString);
@@ -253,6 +271,15 @@ bool java_init(arg_data *args, home_data *data)
             jsvc_xlate_to_ascii(opt[x].optionString);
         }
         log_debug("+-------------------------------------------------------");
+        log_debug("| Internal options:              %d", arg.nOptions - args->onum);
+
+        for (; x < arg.nOptions; 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 */
@@ -283,12 +310,12 @@ bool java_init(arg_data *args, home_data *data)
     nativemethods[0].name = shutdownmethod;
     jsvc_xlate_to_ascii(shutdownparams);
     nativemethods[0].signature = shutdownparams;
-    nativemethods[0].fnPtr = shutdown;
+    nativemethods[0].fnPtr = (void *)shutdown;
     jsvc_xlate_to_ascii(failedmethod);
     nativemethods[1].name = failedmethod;
     jsvc_xlate_to_ascii(failedparams);
     nativemethods[1].signature = failedparams;
-    nativemethods[1].fnPtr = failed;
+    nativemethods[1].fnPtr = (void *)failed;
 
     if ((*env)->RegisterNatives(env, cls, nativemethods, 2) != 0) {
         log_error("Cannot register native methods");
@@ -360,7 +387,6 @@ bool java_load(arg_data *args)
 
     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;
@@ -375,8 +401,8 @@ bool java_load(arg_data *args)
     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) {
+            jsvc_xlate_from_ascii(args->args[x]);
             log_error("Cannot create string for argument %s", args->args[x]);
             return false;
         }
@@ -489,7 +515,7 @@ bool java_version(void)
 {
     jmethodID method;
     char version[] = "version";
-    char versionparams[] = "()Z";
+    char versionparams[] = "()V";
 
     jsvc_xlate_to_ascii(version);
     jsvc_xlate_to_ascii(versionparams);
diff --git a/src/native/unix/native/jsvc-unix.c b/src/native/unix/native/jsvc-unix.c
index efd6648..0de193f 100644
--- a/src/native/unix/native/jsvc-unix.c
+++ b/src/native/unix/native/jsvc-unix.c
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-/* @version $Id: jsvc-unix.c 980512 2010-07-29 17:10:17Z mturk $ */
+/* @version $Id: jsvc-unix.c 1023277 2010-10-16 13:08:31Z mturk $ */
 #include "jsvc.h"
 
 #include <signal.h>
@@ -24,8 +24,11 @@
 #include <sys/wait.h>
 #include <fcntl.h>
 #include <stdio.h>
+#include <string.h>
 #include <pwd.h>
 #include <grp.h>
+#include <syslog.h>
+#include <errno.h>
 #ifdef OS_LINUX
 #include <sys/prctl.h>
 #include <sys/syscall.h>
@@ -42,17 +45,28 @@
 #define F_ULOCK 0               /* Unlock a previously locked region */
 #define F_LOCK  1               /* Lock a region for exclusive use */
 #endif
-
+#ifndef JSVC_UMASK
+#define JSVC_UMASK 0077
+#endif
 extern char **environ;
 
 static mode_t envmask;          /* mask to create the files */
 
 pid_t controlled = 0;           /* the child process pid */
+pid_t logger_pid = 0;           /* the logger 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 bool doreopen = false;
+typedef void (*sighandler_t)(int);
+static sighandler_t handler_int  = NULL;
+static sighandler_t handler_usr1 = NULL;
+static sighandler_t handler_hup  = NULL;
+static sighandler_t handler_trm  = NULL;
+
+static int run_controller(arg_data *args, home_data *data, uid_t uid,
+                          gid_t gid);
+static void set_output(char *outfile, char *errfile, bool redirectstdin,
+                       char *procname);
 
 #ifdef OS_CYGWIN
 /*
@@ -112,6 +126,10 @@ static void handler(int sig)
                 doreload = true;
             }
         break;
+        case SIGUSR1:
+             log_debug("Caught SIGUSR1: Reopening logs");
+             doreopen = true;
+        break;
         default:
             log_debug("Caught unknown signal %d", sig);
         break;
@@ -119,7 +137,7 @@ static void handler(int sig)
 }
 
 /* user and group */
-static int set_user_group(char *user, int uid, int gid)
+static int set_user_group(const char *user, int uid, int gid)
 {
     if (user != NULL) {
         if (setgid(gid) != 0) {
@@ -245,21 +263,24 @@ static int set_caps(int caps)
 }
 #endif
 
-static int linuxset_user_group(char *user, int uid, int gid)
+static int linuxset_user_group(const char *user, int uid, int gid)
 {
     int caps_set = 0;
+
+    if (user == NULL)
+        return 0;
     /* set capabilities enough for binding port 80 setuid/getuid */
     if (getuid() == 0) {
         if (set_caps(CAPS) != 0) {
             if (getuid() != uid) {
-                log_error("set_caps(CAPS) failed");
+                log_error("set_caps(CAPS) failed for user '%s'", user);
                 return -1;
             }
-            log_debug("set_caps(CAPS) failed");
+            log_debug("set_caps(CAPS) failed for user '%s'", user);
         }
         /* 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");
+            log_error("prctl failed in for user '%s'", user);
             return -1;
         }
         caps_set = 1;
@@ -267,7 +288,7 @@ static int linuxset_user_group(char *user, int uid, int gid)
 
     /* set setuid/getuid */
     if (set_user_group(user, uid, gid) != 0) {
-        log_error("set_user_group failed in linuxset_user_group");
+        log_error("set_user_group failed for user '%s'", user);
         return -1;
     }
 
@@ -275,10 +296,10 @@ static int linuxset_user_group(char *user, int uid, int gid)
         /* set capability to binding port 80 read conf */
         if (set_caps(CAPSMIN) != 0) {
             if (getuid() != uid) {
-                log_error("set_caps(CAPSMIN) failed");
+                log_error("set_caps(CAPSMIN) failed for user '%s'", user);
                 return -1;
             }
-            log_debug("set_caps(CAPSMIN) failed");
+            log_debug("set_caps(CAPSMIN) failed for user '%s'", user);
         }
     }
 
@@ -352,6 +373,7 @@ static void controller(int sig)
         case SIGTERM:
         case SIGINT:
         case SIGHUP:
+        case SIGUSR1:
             log_debug("Forwarding signal %d to process %d", sig, controlled);
             kill(controlled, sig);
             signal(sig, controller);
@@ -365,9 +387,9 @@ static void controller(int sig)
 /*
  * Return the address of the current signal handler and set the new one.
  */
-static void *signal_set(int sig, void *newHandler)
+static sighandler_t signal_set(int sig, sighandler_t newHandler)
 {
-    void *hand;
+    sighandler_t hand;
 
     hand = signal(sig, newHandler);
 #ifdef SIG_ERR
@@ -376,7 +398,7 @@ static void *signal_set(int sig, void *newHandler)
 #endif
     if (hand == handler || hand == controller)
         hand = NULL;
-    return (hand);
+    return hand;
 }
 
 /*
@@ -635,6 +657,8 @@ static int child(arg_data *args, home_data *data, uid_t uid, gid_t gid)
 
     /* Check wether we need to dump the VM version */
     if (args->vers == true) {
+        log_error("jsvc (Apache Commons Daemon) " JSVC_VERSION_STRING);
+        log_error("Copyright (c) 1999-2010 Apache Software Foundation.");
         if (java_version() != true) {
             return -1;
         }
@@ -666,7 +690,7 @@ static int child(arg_data *args, home_data *data, uid_t uid, gid_t gid)
 
     /* Downgrade user */
 #ifdef OS_LINUX
-    if (set_caps(0) != 0) {
+    if (args->user && set_caps(0) != 0) {
         log_debug("set_caps (0) failed");
         return 4;
     }
@@ -686,6 +710,7 @@ static int child(arg_data *args, home_data *data, uid_t uid, gid_t gid)
 
     /* Install signal handlers */
     handler_hup = signal_set(SIGHUP, handler);
+    handler_usr1 = signal_set(SIGUSR1, handler);
     handler_trm = signal_set(SIGTERM, handler);
     handler_int = signal_set(SIGINT, handler);
     controlled = getpid();
@@ -700,6 +725,10 @@ static int child(arg_data *args, home_data *data, uid_t uid, gid_t gid)
         /* pause() is not threadsafe */
         sleep(60);
 #endif
+        if(doreopen) {
+            doreopen = false;
+            set_output(args->outfile, args->errfile, args->redirectstdin, args->procname);
+        }
     }
     remove_tmp_file(args);
     log_debug("Shutdown or reload requested: exiting");
@@ -741,11 +770,63 @@ static FILE *loc_freopen(char *outfile, char *mode, FILE * stream)
     return freopen(outfile, mode, stream);
 }
 
+#define LOGBUF_SIZE 1024
+
+/* Read from file descriptors. Log to syslog. */
+static int logger_child(int out_fd, int err_fd, char *procname)
+{
+    fd_set rfds;
+    struct timeval tv;
+    int retval, n;
+    char buf[LOGBUF_SIZE];
+
+    if (out_fd > err_fd) {
+        n = out_fd + 1;
+    } else {
+        n = err_fd + 1;
+    }
+
+    openlog(procname, LOG_PID, LOG_DAEMON);
+
+    while (1) {
+        FD_ZERO(&rfds);
+        FD_SET(out_fd, &rfds);
+        FD_SET(err_fd, &rfds);
+        tv.tv_sec = 60;
+        tv.tv_usec = 0;
+        retval = select(n, &rfds, NULL, NULL, &tv);
+        if (retval == -1)
+            syslog(LOG_ERR, "select: %s", strerror(errno));
+        else if (retval) {
+            if (FD_ISSET(out_fd, &rfds)) {
+                ssize_t n = read(out_fd, buf, LOGBUF_SIZE-1);
+                if (n < 0) {
+                    syslog(LOG_ERR, "read: %s", strerror(errno));
+                } else if (n > 0 && buf[0] != '\n') {
+                    buf[n] = 0;
+                    syslog(LOG_INFO, "%s", buf);
+                }
+            }
+            if (FD_ISSET(err_fd, &rfds)) {
+                ssize_t n = read(err_fd, buf, LOGBUF_SIZE-1);
+                if (n < 0) {
+                    syslog(LOG_ERR, "read: %s", strerror(errno));
+                } else if (n > 0 && buf[0] != '\n') {
+                    buf[n] = 0;
+                    syslog(LOG_ERR, "%s", buf);
+                }
+            }
+        }
+    }
+}
+
 /**
  *  Redirect stdin, stdout, stderr.
  */
-static void set_output(char *outfile, char *errfile, bool redirectstdin)
+static void set_output(char *outfile, char *errfile, bool redirectstdin, char *procname)
 {
+    int out_pipe[2] = {0, 0}, err_pipe[2] = {0, 0}, fork_needed = 0;
+
     if (redirectstdin == true) {
         freopen("/dev/null", "r", stdin);
     }
@@ -755,25 +836,87 @@ static void set_output(char *outfile, char *errfile, bool redirectstdin)
     /* 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, "&1") == 0 && strcmp(errfile, "&2") == 0)
+        return;
+    if (strcmp(outfile, "SYSLOG") == 0) {
+        freopen("/dev/null", "a", stdout);
+        /* Send stdout to syslog through a logger process */
+        if (pipe(out_pipe) == -1) {
+            log_error("cannot create stdout pipe: %s",
+                      strerror(errno));
+        }
+        else {
+            fork_needed = 1;
+            log_stdout_syslog_flag = true;
+        }
     }
-    if (strcmp(outfile, "&2") != 0) {
-        loc_freopen(outfile, "a", stdout);
+    else if (strcmp(outfile, "&2")) {
+        if (strcmp(outfile, "&1")) {
+            /* Redirect stdout to a file */
+            loc_freopen(outfile, "a", stdout);
+        }
     }
 
-    if (strcmp(errfile, "&1") != 0) {
-        loc_freopen(errfile, "a", stderr);
+    if (strcmp(errfile, "SYSLOG") == 0) {
+        freopen("/dev/null", "a", stderr);
+        /* Send stderr to syslog through a logger process */
+        if (pipe(err_pipe) == -1) {
+            log_error("cannot create stderr pipe: %s",
+                      strerror(errno));
+        }
+        else {
+            fork_needed = 1;
+            log_stderr_syslog_flag = true;
+        }
     }
-    else {
+    else if (strcmp(errfile, "&1")) {
+        if (strcmp(errfile, "&2")) {
+            /* Redirect stderr to a file */
+            loc_freopen(errfile, "a", stderr);
+        }
+    }
+    if (strcmp(errfile, "&1") == 0 && strcmp(outfile, "&1")) {
+        /*
+         * -errfile &1 -outfile foo
+         * Redirect stderr to stdout
+         */
         close(2);
-        dup(1);
+        dup2(1, 2);
     }
-    if (strcmp(outfile, "&2") == 0) {
+    if (strcmp(outfile, "&2") == 0 && strcmp(errfile, "&2")) {
+        /*
+         * -outfile &2 -errfile foo
+         * Redirect stdout to stderr
+         */
         close(1);
-        dup(2);
+        dup2(2, 1);
+    }
+
+    if (fork_needed) {
+        pid_t pid = fork();
+        if (pid == -1) {
+            log_error("cannot create logger process: %s", strerror(errno));
+        } else {
+            if (pid) {
+                logger_pid = pid;
+                if (out_pipe[0] != 0) {
+                    close(out_pipe[0]);
+                    if (dup2(out_pipe[1], 1) == -1) {
+                        log_error("cannot redirect stdout to pipe for syslog: %s",
+                                  strerror(errno));
+                    }
+                }
+                if (err_pipe[0] != 0) {
+                    close(err_pipe[0]);
+                    if (dup2(err_pipe[1], 2) == -1) {
+                        log_error("cannot redirect stderr to pipe for syslog: %s",
+                                  strerror(errno));
+                    }
+                }
+            } else {
+                exit(logger_child(out_pipe[0], err_pipe[0], procname));
+            }
+        }
     }
 }
 
@@ -781,11 +924,10 @@ 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;
-    time_t laststart;
+    int res;
 
     /* Parse command line arguments */
     args = arguments(argc, argv);
@@ -889,12 +1031,35 @@ int main(int argc, char *argv[])
 #endif
     }
 
-    envmask = umask(0077);
-    set_output(args->outfile, args->errfile, args->redirectstdin);
+    /*
+     * umask() uses inverse logic; bits are CLEAR for allowed access.
+     */
+    if ((~JSVC_UMASK) & 0022) {
+        log_error("NOTICE: jsvc umask of %03o allows "
+                  "write permission to group and/or other", JSVC_UMASK);
+    }
+    envmask = umask(JSVC_UMASK);
+    set_output(args->outfile, args->errfile, args->redirectstdin, args->procname);
+    log_debug("Switching umask back to %03o from %03o", envmask, JSVC_UMASK);
+    res = run_controller(args, data, uid, gid);
+    if (logger_pid != 0) {
+        kill(logger_pid, SIGTERM);
+    }
+
+    return res;
+}
+
+static int run_controller(arg_data *args, home_data *data, uid_t uid,
+                          gid_t gid)
+{
+    pid_t pid = 0;
+
 
     /* We have to fork: this process will become the controller and the other
        will be the child */
     while ((pid = fork()) != -1) {
+        time_t laststart;
+        int status = 0;
         /* We forked (again), if this is the child, we go on normally */
         if (pid == 0)
             exit(child(args, data, uid, gid));
@@ -907,6 +1072,7 @@ int main(int argc, char *argv[])
         SetTerm(cygwincontroller);
 #endif
         signal(SIGHUP, controller);
+        signal(SIGUSR1, controller);
         signal(SIGTERM, controller);
         signal(SIGINT, controller);
 
@@ -975,4 +1141,3 @@ void main_shutdown(void)
     log_debug("Killing self with TERM signal");
     kill(controlled, SIGTERM);
 }
-
diff --git a/src/native/unix/native/location.c b/src/native/unix/native/location.c
index 8ba2ed2..53ad1cc 100644
--- a/src/native/unix/native/location.c
+++ b/src/native/unix/native/location.c
@@ -81,9 +81,11 @@ char *location_jvm_default[] = {
     "$JAVA_HOME/jre/lib/" CPU "/libkaffevm.so",         /* kaffe */
 #endif
     "$JAVA_HOME/jre/lib/" CPU "/classic/libjvm.so",     /* Sun JDK 1.2 */
+    "$JAVA_HOME/jre/lib/" CPU "/server/libjvm.so",      /* Sun JDK 1.4 */
     "$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 "/server/libjvm.so",          /* Sun JRE 1.4 */
     "$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 */
diff --git a/src/native/unix/native/locks.c b/src/native/unix/native/locks.c
index a007923..50cb440 100644
--- a/src/native/unix/native/locks.c
+++ b/src/native/unix/native/locks.c
@@ -46,6 +46,7 @@ int lockf(int fildes, int function, off_t size)
 
     return fcntl(fildes, F_SETLK, &buf);
 }
-
+#else
+const char __unused_locks_c[] = __FILE__;
 #endif
 
diff --git a/src/native/unix/native/signals.c b/src/native/unix/native/signals.c
index 214a7d8..aab1d51 100644
--- a/src/native/unix/native/signals.c
+++ b/src/native/unix/native/signals.c
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-/* @version $Id: signals.c 921765 2010-03-11 10:03:32Z mturk $ */
+/* @version $Id: signals.c 982560 2010-08-05 12:05:30Z mturk $ */
 
 /*
  * as Windows does not support signal, jsvc uses events to emulate them.
@@ -99,5 +99,7 @@ int SetTerm(void (*func) (void))
     CloseHandle(hthread);       /* not needed */
     return 0;
 }
+#else
+const char __unused_signals_c[] = __FILE__;
 #endif
 
diff --git a/src/native/unix/native/version.h b/src/native/unix/native/version.h
index 6f0ae06..79de645 100644
--- a/src/native/unix/native/version.h
+++ b/src/native/unix/native/version.h
@@ -31,7 +31,7 @@
 #define JSVC_MINOR_VERSION      0
 
 /** patch level */
-#define JSVC_PATCH_VERSION      3
+#define JSVC_PATCH_VERSION      4
 
 /**
  *  This symbol is defined for internal, "development" copies of JSVC.
diff --git a/src/native/unix/support/apfunctions.m4 b/src/native/unix/support/apfunctions.m4
index 1d8dd74..6167a0e 100644
--- a/src/native/unix/support/apfunctions.m4
+++ b/src/native/unix/support/apfunctions.m4
@@ -17,7 +17,7 @@ dnl
 
 dnl -------------------------------------------------------------------------
 dnl Author  Pier Fumagalli <mailto:pier.fumagalli at eng.sun.com>
-dnl Version $Id: apfunctions.m4 480469 2006-11-29 08:22:04Z bayard $
+dnl Version $Id: apfunctions.m4 1003756 2010-10-02 08:59:48Z mturk $
 dnl -------------------------------------------------------------------------
 
 AC_DEFUN(AP_MSG_HEADER,[
@@ -38,3 +38,73 @@ AC_DEFUN(AP_CANONICAL_HOST_CHECK,[
   fi
   AC_PROVIDE([$0])
 ])
+
+dnl Iteratively interpolate the contents of the second argument
+dnl until interpolation offers no new result. Then assign the
+dnl final result to $1.
+dnl
+dnl Example:
+dnl
+dnl foo=1
+dnl bar='${foo}/2'
+dnl baz='${bar}/3'
+dnl AP_EXPAND_VAR(fraz, $baz)
+dnl   $fraz is now "1/2/3"
+dnl
+AC_DEFUN([AP_EXPAND_VAR], [
+ap_last=
+ap_cur="$2"
+while test "x${ap_cur}" != "x${ap_last}";
+do
+  ap_last="${ap_cur}"
+  ap_cur=`eval "echo ${ap_cur}"`
+done
+$1="${ap_cur}"
+])
+
+dnl
+dnl AP_CONFIG_NICE(filename)
+dnl
+dnl Saves a snapshot of the configure command-line for later reuse
+dnl
+AC_DEFUN([AP_CONFIG_NICE], [
+  rm -f $1
+  cat >$1<<EOF
+#! /bin/sh
+#
+# Created by configure
+
+EOF
+  if test -n "$CC"; then
+    echo "CC=\"$CC\"; export CC" >> $1
+  fi
+  if test -n "$CFLAGS"; then
+    echo "CFLAGS=\"$CFLAGS\"; export CFLAGS" >> $1
+  fi
+  if test -n "$CPPFLAGS"; then
+    echo "CPPFLAGS=\"$CPPFLAGS\"; export CPPFLAGS" >> $1
+  fi
+  if test -n "$LDFLAGS"; then
+    echo "LDFLAGS=\"$LDFLAGS\"; export LDFLAGS" >> $1
+  fi
+  if test -n "$LIBS"; then
+    echo "LIBS=\"$LIBS\"; export LIBS" >> $1
+  fi
+  if test -n "$STRIPFLAGS"; then
+    echo "STRIPFLAGS=\"$STRIPFLAGS\"; export STRIPFLAGS" >> $1
+  fi
+  if test -n "$INCLUDES"; then
+    echo "INCLUDES=\"$INCLUDES\"; export INCLUDES" >> $1
+  fi
+# Retrieve command-line arguments.
+  eval "set x $[0] $ac_configure_args"
+  shift
+
+  for arg
+  do
+    AP_EXPAND_VAR(arg, $arg)
+    echo "\"[$]arg\" \\" >> $1
+  done
+  echo '"[$]@"' >> $1
+  chmod +x $1
+])dnl
diff --git a/src/native/unix/support/apsupport.m4 b/src/native/unix/support/apsupport.m4
index 0787c11..453cbcc 100644
--- a/src/native/unix/support/apsupport.m4
+++ b/src/native/unix/support/apsupport.m4
@@ -17,7 +17,7 @@ dnl
 
 dnl -------------------------------------------------------------------------
 dnl Author  Pier Fumagalli <mailto:pier.fumagalli at eng.sun.com>
-dnl Version $Id: apsupport.m4 751284 2009-03-07 15:41:45Z markt $
+dnl Version $Id: apsupport.m4 996963 2010-09-14 15:55:47Z mturk $
 dnl -------------------------------------------------------------------------
 
 AC_DEFUN(AP_SUPPORTED_HOST,[
@@ -84,7 +84,7 @@ AC_DEFUN(AP_SUPPORTED_HOST,[
   i?86)
     CFLAGS="$CFLAGS -DCPU=\\\"i386\\\""
     HOST_CPU=i386;;
-  x86_64)
+  x86_64 | amd64)
     CFLAGS="$CFLAGS -DCPU=\\\"amd64\\\""
     HOST_CPU=amd64;;
   bs2000)
diff --git a/src/native/unix/support/mkdist.sh b/src/native/unix/support/mkdist.sh
new file mode 100755
index 0000000..855d473
--- /dev/null
+++ b/src/native/unix/support/mkdist.sh
@@ -0,0 +1,104 @@
+#!/bin/sh
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+#
+# Create Commons Daemon native package distribution on UNIX systems.
+# You should execute this script from the src/native/unix directory
+#
+# support/mkdist.sh <arch> [os]
+#
+# This will create something like commons-daemon-1.2.3-bin-os-arch.tar.gz
+# The version numbers are parsed from the native/version.h file.
+# If the os argument is not provided current os name will be used.
+#
+#
+gpgopts="-ba"
+arch=""
+for o
+do
+    case "$o" in
+    *=*) a=`echo "$o" | sed 's/^[-_a-zA-Z0-9]*=//'`
+     ;;
+    *) a=''
+     ;;
+    esac
+    case "$o" in
+        --passphrase=*  )
+            gpgopts="$gpgopts --passphrase $a"
+            shift
+        ;;
+        --arch=*  )
+            arch="$a"
+            shift
+        ;;
+        --os=*  )
+            osname="$a"
+            shift
+        ;;
+        * )
+            break
+        ;;
+    esac
+done
+
+
+if [ ".$arch" = . ];then
+  arch=`uname -m 2>/dev/null | tr '[A-Z]' '[a-z]'` || arch="unknown"
+  echo "No architecture provided. Using $arch"
+fi
+if [ ".$osname" = . ];then
+  osname=`uname -s 2>/dev/null | tr '[A-Z]' '[a-z]'` || osname="unknown"
+  echo "No OS name provided. Using $osname"
+fi
+topdir=.
+major_sed='/#define.*JSVC_MAJOR_VERSION/s/^[^0-9]*\([0-9]*\).*$/\1/p'
+minor_sed='/#define.*JSVC_MINOR_VERSION/s/^[^0-9]*\([0-9]*\).*$/\1/p'
+patch_sed='/#define.*JSVC_PATCH_VERSION/s/^[^0-9]*\([0-9]*\).*$/\1/p'
+vmajor="`sed -n $major_sed $topdir/native/version.h`"
+vminor="`sed -n $minor_sed $topdir/native/version.h`"
+vpatch="`sed -n $patch_sed $topdir/native/version.h`"
+verdst="commons-daemon-$vmajor.$vminor.$vpatch-bin-$osname-$arch"
+extfiles="LICENSE.txt NOTICE.txt RELEASE-NOTES.txt"
+for i in $extfiles
+do
+  cp ../../../$i .
+done
+# Try to locate a MD5 binary
+md5_bin="`which md5sum 2>/dev/null || type md5sum 2>&1`"
+if [ -x "$md5_bin" ]; then
+    MD5SUM="$md5_bin --binary "
+else
+    MD5SUM="echo 00000000000000000000000000000000 "
+fi
+# Try to locate a SHA1 binary
+sha1_bin="`which sha1sum 2>/dev/null || type sha1sum 2>&1`"
+if [ -x "$sha1_bin" ]; then
+    SHA1SUM="$sha1_bin --binary "
+else
+    SHA1SUM="echo 0000000000000000000000000000000000000000 "
+fi
+dstfile=$verdst.tar.gz
+echo "Creating $dstfile ..."
+tar cfz $dstfile jsvc $extfiles
+if [ ".$?" = .0 ]; then
+  echo "Signing $dstfile"
+  gpg $gpgopts $dstfile
+  $MD5SUM $dstfile > $dstfile.md5
+  $SHA1SUM $dstfile > $dstfile.sha1
+else
+  rm $verdst.tar.gz >/dev/null 2>&1
+fi
+rm $extfiles
diff --git a/src/native/windows/README b/src/native/windows/README
new file mode 100644
index 0000000..28612cb
--- /dev/null
+++ b/src/native/windows/README
@@ -0,0 +1,25 @@
+Note: MAKE SURE you first build the java part (using Ant) otherwise the dist
+directory is not created).
+
+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.
+
+The Windows applications are found in:
+
+apps/prunmgr
+apps/prunsrv
+
+The common source files are in
+
+src
+include
+resources
+
+The Makefiles in the apps/ directories can be used with MS Visual C++ 5.0.
+They will not work with earlier versions of nmake
+
+Note that later versions of Visual C++ can be set up to build the applications,
+however they may generate executables linked with a later version of the MS "C"
+runtime library (MSVCRTL), and may not work properly with all versions of Java.
diff --git a/src/native/nt/procrun/README.dev b/src/native/windows/README.dev
similarity index 83%
rename from src/native/nt/procrun/README.dev
rename to src/native/windows/README.dev
index d8a60d0..d40aa33 100644
--- a/src/native/nt/procrun/README.dev
+++ b/src/native/windows/README.dev
@@ -6,7 +6,7 @@ Configuring and Building Commons Daemon on Windows
 ==================================================
 
 Using Visual Studio, you can build the Commons Daemon.
-The Makefile make file has a bunch of documentation about it's
+The Makefile make file has a bunch of documentation about its
 options, but a trivial build is simply;
 
   nmake CPU=X86
@@ -18,7 +18,7 @@ Needed Tools
 
 Commons Daemon needs the Microsoft Visual C 6/SP5 to
 build the x86 binaries. This is because this compiler
-doesn't create MSVCRTnn.DLL dependecies which will
+doesn't create MSVCRTnn.DLL dependencies which will
 be loaded inside running JVM if used.
 For building AMD64/EMT64 binaries use the Platform SDK
 for Windows Server 2003R2.
diff --git a/src/native/nt/procrun/apps/prunmgr/Makefile b/src/native/windows/apps/prunmgr/Makefile
similarity index 100%
rename from src/native/nt/procrun/apps/prunmgr/Makefile
rename to src/native/windows/apps/prunmgr/Makefile
diff --git a/src/native/nt/procrun/apps/prunmgr/prunmgr.c b/src/native/windows/apps/prunmgr/prunmgr.c
similarity index 100%
rename from src/native/nt/procrun/apps/prunmgr/prunmgr.c
rename to src/native/windows/apps/prunmgr/prunmgr.c
diff --git a/src/native/nt/procrun/apps/prunmgr/prunmgr.h b/src/native/windows/apps/prunmgr/prunmgr.h
similarity index 99%
rename from src/native/nt/procrun/apps/prunmgr/prunmgr.h
rename to src/native/windows/apps/prunmgr/prunmgr.h
index 1670c13..38c88d3 100644
--- a/src/native/nt/procrun/apps/prunmgr/prunmgr.h
+++ b/src/native/windows/apps/prunmgr/prunmgr.h
@@ -13,18 +13,18 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
- 
+
 /* ====================================================================
  * Contributed by Mladen Turk <mturk at apache.org>
  * 05 Aug 2003
- * ==================================================================== 
+ * ====================================================================
  */
 
 #ifndef _PRUNMGR_H
 #define _PRUNMGR_H
 
 #undef  PRG_VERSION
-#define PRG_VERSION    "1.0.3.0" 
+#define PRG_VERSION    "1.0.4.0"
 #define PRG_REGROOT   L"Apache Software Foundation\\Procrun 2.0"
 
 #define IDM_TM_EXIT                     2000
@@ -136,6 +136,6 @@
 #define IDS_ERRSREG                     3122
 
 #define IDS_NOTIMPLEMENTED              3199
- 
+
 #endif /* _PRUNMGR_H */
 
diff --git a/src/native/windows/apps/prunmgr/prunmgr.manifest b/src/native/windows/apps/prunmgr/prunmgr.manifest
new file mode 100644
index 0000000..247be77
--- /dev/null
+++ b/src/native/windows/apps/prunmgr/prunmgr.manifest
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You 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.
+-->
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+<assemblyIdentity version="3.1.0.0" processorArchitecture="*" name="Apache.Procrun.Prunmgr" type="win32" />
+<description>Apache Procrun Service Manager</description>
+<dependency>
+<dependentAssembly>
+<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*" />
+</dependentAssembly>
+</dependency>
+</assembly>
diff --git a/src/native/nt/procrun/apps/prunmgr/prunmgr.rc b/src/native/windows/apps/prunmgr/prunmgr.rc
similarity index 90%
rename from src/native/nt/procrun/apps/prunmgr/prunmgr.rc
rename to src/native/windows/apps/prunmgr/prunmgr.rc
index 4c3d5ad..3856cc5 100644
--- a/src/native/nt/procrun/apps/prunmgr/prunmgr.rc
+++ b/src/native/windows/apps/prunmgr/prunmgr.rc
@@ -13,20 +13,20 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
- 
+
 #include "apxwin.h"
 #include "prunmgr.h"
 
 #define RSTR_PSM        "Commons Daemon Service Manager"
 #define RSTR_SCMATS     "Service Manager is attempting to "
- 
-IDI_MAINICON         ICON                   "../../resources/procrunw.ico" 
-IDI_ICONSTOP         ICON                   "../../resources/procruns.ico" 
-IDI_ICONRUN          ICON                   "../../resources/procrunr.ico" 
+
+IDI_MAINICON         ICON                   "../../resources/procrunw.ico"
+IDI_ICONSTOP         ICON                   "../../resources/procruns.ico"
+IDI_ICONRUN          ICON                   "../../resources/procrunr.ico"
 IDR_LICENSE          RTF                    "../../resources/license.rtf"
 BMP_JAKARTA          BITMAP                 "../../resources/commons.bmp"
 
-#if 0 
+#if 0
 BMP_APMNUHDR         BITMAP                 "../../resources/apmnuhdr.bmp"
 #endif
 
@@ -38,17 +38,17 @@ CAPTION "Apache Service Manager"
 FONT 8, "Microsoft Sans Serif", 400, 0, 0x0
 BEGIN
     DEFPUSHBUTTON   "&OK",IDOK,285,150,50,14
-    CONTROL         "",IDC_LICENSE,"RichEdit20A",ES_MULTILINE | 
+    CONTROL         "",IDC_LICENSE,"RichEdit20A",ES_MULTILINE |
                     ES_READONLY | WS_BORDER | WS_VSCROLL,0,31,335,115
     CONTROL         "BMP_JAKARTA",IDC_STATIC,"Static",SS_BITMAP|0x00000040L,0,0,337,30
     LTEXT           " ",IDC_ABOUTAPP,2,150,270,12
-    LTEXT           "Copyright � 2000-2010 The Apache Software Foundation.",IDC_STATIC,2,160,270,12
-    LTEXT           "http://commons.apache.org",IDC_STATIC,2,170,270,12 
+    LTEXT           "Copyright � 2000-2010 The Apache Software Foundation.",IDC_STATIC,2,160,270,12
+    LTEXT           "http://commons.apache.org",IDC_STATIC,2,170,270,12
     PUSHBUTTON      "&System Info",IAB_SYSINF,285,170,50,14
 END
 
 IDD_PROGRESS DIALOGEX 0, 0, 322, 92
-STYLE DS_SYSMODAL | DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | 
+STYLE DS_SYSMODAL | DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP |
     WS_CAPTION | WS_SYSMENU
 EXSTYLE WS_EX_TOPMOST
 CAPTION "Apache Commons Daemon Service Manager"
@@ -62,7 +62,7 @@ BEGIN
     CONTROL         "",IDDP_PROGRESS,"msctls_progress32",WS_BORDER,10,50,302,
                     14
     ICON            IDI_MAINICON,IDC_STATIC,10,4,20,20,0,WS_EX_TRANSPARENT
-END 
+END
 
 IDD_SELUSER DIALOGEX 0, 0, 410, 201
 STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU |
@@ -76,10 +76,10 @@ BEGIN
     DEFPUSHBUTTON   "OK",IDOK,292,180,50,14,WS_DISABLED
     PUSHBUTTON      "Cancel",IDCANCEL,348,180,50,14
     LTEXT           "Look In:",IDC_STATIC,10,9,27,8
-    CONTROL         "",IDSU_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | 
-                    LVS_SORTASCENDING | LVS_SHAREIMAGELISTS | LVS_ALIGNLEFT | WS_BORDER | 
+    CONTROL         "",IDSU_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL |
+                    LVS_SORTASCENDING | LVS_SHAREIMAGELISTS | LVS_ALIGNLEFT | WS_BORDER |
                     WS_TABSTOP,0,26,410,149,WS_EX_CLIENTEDGE
-    CONTROL         "",IDSU_COMBO,"ComboBoxEx32",CBS_DROPDOWNLIST | 
+    CONTROL         "",IDSU_COMBO,"ComboBoxEx32",CBS_DROPDOWNLIST |
                     WS_VSCROLL | WS_TABSTOP,47,6,260,80
 END
 
@@ -96,9 +96,9 @@ BEGIN
     LTEXT           "Pat&h to executable:",IDC_STATIC,10,63,66,8
     EDITTEXT        IDC_PPSGDEXE,10,75,240,12,ES_AUTOHSCROLL | WS_DISABLED
     LTEXT           "Startup typ&e:",IDC_STATIC,10,94,46,8
-    COMBOBOX        IDC_PPSGCMBST,70,93,180,80,CBS_DROPDOWNLIST | WS_VSCROLL | 
+    COMBOBOX        IDC_PPSGCMBST,70,93,180,80,CBS_DROPDOWNLIST | WS_VSCROLL |
                     WS_TABSTOP
-    CONTROL         "",IDC_STATIC,"Static",SS_ETCHEDHORZ,10,128,240,1                    
+    CONTROL         "",IDC_STATIC,"Static",SS_ETCHEDHORZ,10,128,240,1
     LTEXT           "Service Status:",IDC_STATIC,10,138,52,8
     LTEXT           "  ",IDC_PPSGSTATUS,70,138,240,8
     PUSHBUTTON      "&Start",IDC_PPSGSTART,10,160,55,14,WS_DISABLED
@@ -131,23 +131,23 @@ STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
 FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
     LTEXT           "&Level:",IDC_STATIC,10,18,46,8
-    COMBOBOX        IDC_PPLGLEVEL,70,17,180,80,CBS_DROPDOWNLIST | WS_VSCROLL | 
+    COMBOBOX        IDC_PPLGLEVEL,70,17,180,80,CBS_DROPDOWNLIST | WS_VSCROLL |
                     WS_TABSTOP
     LTEXT           "Log &path: ",IDC_STATIC,10,33,50,8
     EDITTEXT        IDC_PPLGPATH,10,45,218,12,ES_AUTOHSCROLL
-    PUSHBUTTON      "...",IDC_PPLGBPATH,232,44,18,14 
+    PUSHBUTTON      "...",IDC_PPLGBPATH,232,44,18,14
     LTEXT           "Log prefix: ",IDC_STATIC,10,63,50,8
     EDITTEXT        IDC_PPLGPREFIX,70,62,158,12,ES_AUTOHSCROLL
 
     LTEXT           "Pid file: ",IDC_STATIC,10,81,50,8
     EDITTEXT        IDC_PPLGPIDFILE,70,82,158,12,ES_AUTOHSCROLL
-    
+
     LTEXT           "Redirect Stdout: ",IDC_STATIC,10,105,80,8
     EDITTEXT        IDC_PPLGSTDOUT,10,117,218,12,ES_AUTOHSCROLL
-    PUSHBUTTON      "...",IDC_PPLGBSTDOUT,232,116,18,14 
+    PUSHBUTTON      "...",IDC_PPLGBSTDOUT,232,116,18,14
     LTEXT           "Redirect Stderror: ",IDC_STATIC,10,135,80,8
     EDITTEXT        IDC_PPLGSTDERR,10,147,218,12,ES_AUTOHSCROLL
-    PUSHBUTTON      "...",IDC_PPLGBSTDERR,232,146,18,14 
+    PUSHBUTTON      "...",IDC_PPLGBSTDERR,232,146,18,14
 END
 
 IDD_PROPPAGE_JVM DIALOGEX 0, 0, 260, 186
@@ -158,11 +158,11 @@ BEGIN
                     WS_TABSTOP,10,8,72,12
     LTEXT           "Java Virtual Machine: ",IDC_STATIC,10,23,80,8
     EDITTEXT        IDC_PPJJVM,10,35,218,12,ES_AUTOHSCROLL
-    PUSHBUTTON      "...",IDC_PPJBJVM,232,34,18,14 
+    PUSHBUTTON      "...",IDC_PPJBJVM,232,34,18,14
     LTEXT           "Java Classpath:",IDC_STATIC,10,53,66,8
     EDITTEXT        IDC_PPJCLASSPATH,10,65,240,12,ES_AUTOHSCROLL
     LTEXT           "Java Options:",IDC_STATIC,10,83,66,8
-    EDITTEXT        IDC_PPJOPTIONS,10,95,240,40,ES_MULTILINE | ES_AUTOHSCROLL | 
+    EDITTEXT        IDC_PPJOPTIONS,10,95,240,40,ES_MULTILINE | ES_AUTOHSCROLL |
                     ES_WANTRETURN | WS_VSCROLL
     LTEXT           "Initial memory pool:",IDC_STATIC,10,140,80,8
     EDITTEXT        IDC_PPJMS,90,139,100,12,ES_AUTOHSCROLL | ES_NUMBER
@@ -183,20 +183,20 @@ BEGIN
     EDITTEXT        IDC_PPRCLASS,10,20,240,12,ES_AUTOHSCROLL
     LTEXT           "Image: ",IDC_STATIC,10,38,80,8
     EDITTEXT        IDC_PPRIMAGE,10,50,218,12,ES_AUTOHSCROLL | WS_DISABLED
-    PUSHBUTTON      "...",IDC_PPRBIMAGE,232,49,18,14,WS_DISABLED 
+    PUSHBUTTON      "...",IDC_PPRBIMAGE,232,49,18,14,WS_DISABLED
     LTEXT           "Working Path: ",IDC_STATIC,10,68,80,8
     EDITTEXT        IDC_PPRWPATH,10,80,218,12,ES_AUTOHSCROLL
     PUSHBUTTON      "...",IDC_PPRBWPATH,232,79,18,14
     LTEXT           "&Method: ",IDC_STATIC,10,98,50,8
     EDITTEXT        IDC_PPRMETHOD,70,97,180,12,ES_AUTOHSCROLL
     LTEXT           "&Arguments: ",IDC_STATIC,10,115,50,8
-    EDITTEXT        IDC_PPRARGS,70,114,180,30,ES_MULTILINE | ES_AUTOHSCROLL | 
+    EDITTEXT        IDC_PPRARGS,70,114,180,30,ES_MULTILINE | ES_AUTOHSCROLL |
                     ES_WANTRETURN | WS_VSCROLL
     LTEXT           "&Timeout: ",IDC_STATIC,10,150,50,8
     EDITTEXT        IDC_PPRTIMEOUT,70,149,100,12,ES_AUTOHSCROLL | WS_DISABLED
     LTEXT           "sec.",IDC_STATIC,175,150,25,8
     LTEXT           "&Mode: ",IDC_STATIC,10,168,50,8
-    COMBOBOX        IDC_PPRMODE,70,167,180,80,CBS_DROPDOWNLIST | WS_VSCROLL | 
+    COMBOBOX        IDC_PPRMODE,70,167,180,80,CBS_DROPDOWNLIST | WS_VSCROLL |
                     WS_TABSTOP
 END
 
@@ -208,29 +208,29 @@ BEGIN
     EDITTEXT        IDC_PPSCLASS,10,20,240,12,ES_AUTOHSCROLL
     LTEXT           "Image: ",IDC_STATIC,10,38,80,8
     EDITTEXT        IDC_PPSIMAGE,10,50,218,12,ES_AUTOHSCROLL | WS_DISABLED
-    PUSHBUTTON      "...",IDC_PPSBIMAGE,232,49,18,14,WS_DISABLED 
+    PUSHBUTTON      "...",IDC_PPSBIMAGE,232,49,18,14,WS_DISABLED
     LTEXT           "Working Path: ",IDC_STATIC,10,68,80,8
     EDITTEXT        IDC_PPSWPATH,10,80,218,12,ES_AUTOHSCROLL
-    PUSHBUTTON      "...",IDC_PPSBWPATH,232,79,18,14 
+    PUSHBUTTON      "...",IDC_PPSBWPATH,232,79,18,14
     LTEXT           "&Method: ",IDC_STATIC,10,98,50,8
     EDITTEXT        IDC_PPSMETHOD,70,97,180,12,ES_AUTOHSCROLL
     LTEXT           "&Arguments: ",IDC_STATIC,10,115,50,8
-    EDITTEXT        IDC_PPSARGS,70,114,180,30,ES_MULTILINE | ES_AUTOHSCROLL | 
+    EDITTEXT        IDC_PPSARGS,70,114,180,30,ES_MULTILINE | ES_AUTOHSCROLL |
                     ES_WANTRETURN | WS_VSCROLL
     LTEXT           "&Timeout: ",IDC_STATIC,10,150,50,8
     EDITTEXT        IDC_PPSTIMEOUT,70,149,100,12,ES_AUTOHSCROLL | ES_NUMBER
     LTEXT           "sec.",IDC_STATIC,175,150,25,8
     LTEXT           "&Mode: ",IDC_STATIC,10,168,50,8
-    COMBOBOX        IDC_PPSMODE,70,167,180,80,CBS_DROPDOWNLIST | WS_VSCROLL | 
+    COMBOBOX        IDC_PPSMODE,70,167,180,80,CBS_DROPDOWNLIST | WS_VSCROLL |
                     WS_TABSTOP
 END
 
-STRINGTABLE 
+STRINGTABLE
 BEGIN
     IDS_APPLICATION     RSTR_PSM
-    IDS_APPVERSION      "Version 1.0.3"
+    IDS_APPVERSION      "Version 1.0.4"
     IDS_APPFULLNAME     RSTR_PSM " Version " PRG_VERSION
-    IDS_APPCOPYRIGHT    "Copyright � 2000-2010 The Apache Software Foundation"
+    IDS_APPCOPYRIGHT    "Copyright � 2000-2010 The Apache Software Foundation"
     IDS_APPDESCRIPTION  "Apache Commons Daemon Service Management Tool"
     IDS_ALREAY_RUNING   "An instance of '%S' application is already running"
     IDS_ERRORCMD        "Unknown command line option '%s'\nSee the manual for command line usage."
@@ -238,29 +238,29 @@ BEGIN
     IDS_HSSTOP          RSTR_SCMATS "stop the following service ..."
     IDS_HSRESTART       RSTR_SCMATS "to restart the following service ..."
     IDS_HSPAUSE         RSTR_SCMATS "to pause the following service ..."
-    IDS_VALIDPASS       "Please enter a valid password"    
+    IDS_VALIDPASS       "Please enter a valid password"
     IDS_PPGENERAL       "General"
     IDS_PPLOGON         "Log On"
     IDS_PPLOGGING       "Logging"
     IDS_PPJAVAVM        "Java"
     IDS_PPSTART         "Startup"
     IDS_PPSTOP          "Shutdown"
-    IDS_NOTIMPLEMENTED  "Sorry, but this feature is not implemented yet"         
+    IDS_NOTIMPLEMENTED  "Sorry, but this feature is not implemented yet"
     IDS_LGPATHTITLE     "Select Log root folder"
     IDS_ALLFILES        "All Files (*.*)\0*.*\0"
     IDS_DLLFILES        "Dynamic Link Libraries (*.dll)\0*.dll\0"
     IDS_EXEFILES        "Executables (*.exe)\0*.exe\0"
     IDS_LGSTDOUT        "Select Stdoutput filename"
     IDS_LGSTDERR        "Select Stderror filename"
-    IDS_PPJBJVM         "Select Java Virtual Machine DLL"    
-    IDS_PPWPATH         "Select Working path"    
-    IDS_PPIMAGE         "Select Executable Image"    
+    IDS_PPJBJVM         "Select Java Virtual Machine DLL"
+    IDS_PPWPATH         "Select Working path"
+    IDS_PPIMAGE         "Select Executable Image"
     IDS_ERRSREG         "Unable to open the service registry key"
 END
 
 1 VERSIONINFO
- FILEVERSION 1,0,3,0
- PRODUCTVERSION 1,0,3,0
+ FILEVERSION 1,0,4,0
+ PRODUCTVERSION 1,0,4,0
  FILEFLAGSMASK 0x3fL
 #if defined(_DEBUG)
  FILEFLAGS 0x03L
@@ -280,7 +280,7 @@ BEGIN
       VALUE "FileDescription", RSTR_PSM "\0"
       VALUE "FileVersion", PRG_VERSION
       VALUE "InternalName", RSTR_PSM "\0"
-      VALUE "LegalCopyright", "Copyright � 2000-2010 The Apache Software Foundation.\0"
+      VALUE "LegalCopyright", "Copyright � 2000-2010 The Apache Software Foundation.\0"
       VALUE "OriginalFilename", "prunmgr.exe\0"
       VALUE "ProductName", RSTR_PSM "\0"
       VALUE "ProductVersion", PRG_VERSION
diff --git a/src/native/nt/procrun/apps/prunsrv/Makefile b/src/native/windows/apps/prunsrv/Makefile
similarity index 98%
rename from src/native/nt/procrun/apps/prunsrv/Makefile
rename to src/native/windows/apps/prunsrv/Makefile
index 4289a4d..6f300a8 100644
--- a/src/native/nt/procrun/apps/prunsrv/Makefile
+++ b/src/native/windows/apps/prunsrv/Makefile
@@ -29,7 +29,7 @@ SRCDIR = .\..\..
 !ENDIF
 
 !IF "$(CPU)" == "X86"
-LFLAGS = $(LFLAGS) /stack:0x50000
+LFLAGS = $(LFLAGS) /stack:0x64000
 !ENDIF
 
 LFLAGS = $(LFLAGS) /version:1.0
diff --git a/src/native/nt/procrun/apps/prunsrv/prunsrv.c b/src/native/windows/apps/prunsrv/prunsrv.c
similarity index 91%
rename from src/native/nt/procrun/apps/prunsrv/prunsrv.c
rename to src/native/windows/apps/prunsrv/prunsrv.c
index ac0c6e1..dad0ea6 100644
--- a/src/native/nt/procrun/apps/prunsrv/prunsrv.c
+++ b/src/native/windows/apps/prunsrv/prunsrv.c
@@ -41,10 +41,12 @@
 #define STDERR_FILENO 2
 #define ONE_MINUTE    (60 * 1000)
 
-#ifdef WIN64
+#ifdef _WIN64
 #define KREG_WOW6432  KEY_WOW64_32KEY
+#define PRG_BITS      64
 #else
 #define KREG_WOW6432  0
+#define PRG_BITS      32
 #endif
 
 typedef struct APX_STDWRAP {
@@ -59,6 +61,8 @@ typedef struct APX_STDWRAP {
 static LPCWSTR      PRSRV_AUTO   = L"auto";
 static LPCWSTR      PRSRV_JAVA   = L"java";
 static LPCWSTR      PRSRV_JVM    = L"jvm";
+static LPCWSTR      PRSRV_JDK    = L"jdk";
+static LPCWSTR      PRSRV_JRE    = L"jre";
 static LPCWSTR      PRSRV_MANUAL = L"manual";
 static LPCWSTR      PRSRV_JBIN   = L"\\bin\\java.exe";
 static LPCWSTR      PRSRV_SIGNAL = L"SIGNAL";
@@ -229,6 +233,9 @@ static HANDLE gSignalThread  = NULL;
 static HANDLE gPidfileHandle = NULL;
 static LPWSTR gPidfileName   = NULL;
 static BOOL   gSignalValid   = TRUE;
+static APXJAVA_THREADARGS gRargs;
+static APXJAVA_THREADARGS gSargs;
+
 
 DWORD WINAPI eventThread(LPVOID lpParam)
 {
@@ -251,7 +258,7 @@ DWORD WINAPI eventThread(LPVOID lpParam)
  * If stderrfile is not specified it will
  * go to stdoutfile.
  */
-static BOOL redirectStdStreams(APX_STDWRAP *lpWrapper)
+static BOOL redirectStdStreams(APX_STDWRAP *lpWrapper, LPAPXCMDLINE lpCmdline)
 {
     BOOL aErr = FALSE;
     BOOL aOut = FALSE;
@@ -261,10 +268,14 @@ static BOOL redirectStdStreams(APX_STDWRAP *lpWrapper)
     /* redirect to file or console */
     if (lpWrapper->szStdOutFilename) {
         if (lstrcmpiW(lpWrapper->szStdOutFilename, PRSRV_AUTO) == 0) {
+            WCHAR lsn[1024];
             aOut = TRUE;
+            lstrcpyW(lsn, lpCmdline->szApplication);
+            lstrlocaseW(lsn);
+            lstrcatW(lsn, L"-stdout");
             lpWrapper->szStdOutFilename = apxLogFile(gPool,
                                                      lpWrapper->szLogPath,
-                                                     L"service-stdout",
+                                                     lsn,
                                                      NULL, TRUE);
         }
         /* Delete the file if not in append mode
@@ -278,13 +289,19 @@ static BOOL redirectStdStreams(APX_STDWRAP *lpWrapper)
             *stdout = *lpWrapper->fpStdOutFile;
             setvbuf(stdout, NULL, _IONBF, 0);
         }
+        else
+            lpWrapper->szStdOutFilename = NULL;
     }
     if (lpWrapper->szStdErrFilename) {
         if (lstrcmpiW(lpWrapper->szStdErrFilename, PRSRV_AUTO) == 0) {
+            WCHAR lsn[1024];
             aErr = TRUE;
+            lstrcpyW(lsn, lpCmdline->szApplication);
+            lstrlocaseW(lsn);
+            lstrcatW(lsn, L"-stderr");
             lpWrapper->szStdErrFilename = apxLogFile(gPool,
                                                      lpWrapper->szLogPath,
-                                                     L"service-stderr",
+                                                     lsn,
                                                      NULL, TRUE);
         }
         if (!aErr)
@@ -295,6 +312,8 @@ static BOOL redirectStdStreams(APX_STDWRAP *lpWrapper)
             *stderr = *lpWrapper->fpStdErrFile;
             setvbuf(stderr, NULL, _IONBF, 0);
         }
+        else
+            lpWrapper->szStdOutFilename = NULL;
     }
     else if (lpWrapper->fpStdOutFile) {
         _dup2(_fileno(lpWrapper->fpStdOutFile), 2);
@@ -330,14 +349,11 @@ static void printUsage(LPAPXCMDLINE lpCmdline, BOOL isHelp)
 
 static void printVersion(void)
 {
-#ifdef _WIN64
-    int b = 64;
-#else
-    int b = 32;
-#endif
     fwprintf(stderr, L"Commons Daemon Service Runner version %S/Win%d (%S)\n",
-            PRG_VERSION, b, __DATE__);
-    fwprintf(stderr, L"Copyright (c) 2000-2010 The Apache Software Foundation.\n");
+            PRG_VERSION, PRG_BITS, __DATE__);
+    fwprintf(stderr, L"Copyright (c) 2000-2010 The Apache Software Foundation.\n\n"
+                     L"For bug reporting instructions, please see:\n"
+                     L"<URL:https://issues.apache.org/jira/browse/DAEMON>.");
 }
 
 /* Display configuration parameters */
@@ -381,6 +397,11 @@ static BOOL loadConfiguration(LPAPXCMDLINE lpCmdline)
     APXHANDLE hRegistry;
     int i = 0;
 
+    if (!lpCmdline->szApplication) {
+        /* Handle empty service names */
+        apxLogWrite(APXLOG_MARK_WARN "No service name provided");
+        return FALSE;
+    }
     SetLastError(ERROR_SUCCESS);
     hRegistry = apxCreateRegistryW(gPool, KEY_READ | KREG_WOW6432,
                                    PRG_REGROOT,
@@ -786,6 +807,13 @@ BOOL child_callback(APXHANDLE hObject, UINT uMsg,
     return TRUE;
 }
 
+static int onExitHook(void)
+{
+    apxLogWrite(APXLOG_MARK_DEBUG "On exit hook called ...");
+    reportServiceStatus(SERVICE_STOPPED, NO_ERROR, 0);
+    return 0;    
+}
+
 /* Executed when the service receives stop event */
 static DWORD WINAPI serviceStop(LPVOID lpParameter)
 {
@@ -813,24 +841,32 @@ static DWORD WINAPI serviceStop(LPVOID lpParameter)
             apxLogWrite(APXLOG_MARK_ERROR "Failed creating java %S", _jni_jvmpath);
             return 1;
         }
-        if (!apxJavaInitialize(hWorker, _jni_classpath, _jni_jvmoptions,
-                               SO_JVMMS, SO_JVMMX, SO_JVMSS, SO_JNIVFPRINTF)) {
-            rv = 2;
-            apxLogWrite(APXLOG_MARK_ERROR "Failed initializing java %s", _jni_classpath);
-            goto cleanup;
-        }
-        if (!apxJavaLoadMainClass(hWorker, _jni_sclass, _jni_smethod, _jni_sparam)) {
-            rv = 2;
-            apxLogWrite(APXLOG_MARK_ERROR "Failed loading main %s class %s",
-                        _jni_rclass, _jni_classpath);
-            goto cleanup;
-        }
+        gSargs.hJava            = hWorker;
+        gSargs.szClassPath      = _jni_classpath;
+        gSargs.lpOptions        = _jni_jvmoptions;
+        gSargs.dwMs             = SO_JVMMS;
+        gSargs.dwMx             = SO_JVMMX;
+        gSargs.dwSs             = SO_JVMSS;
+        gSargs.bJniVfprintf     = SO_JNIVFPRINTF;
+        gSargs.szClassName      = _jni_sclass;
+        gSargs.szMethodName     = _jni_smethod;
+        gSargs.lpArguments      = _jni_sparam;
+        gSargs.szStdErrFilename = NULL;
+        gSargs.szStdOutFilename = NULL;
+
+        if (lstrcmpA(_jni_sclass, "java/lang/System") == 0)
+            _onexit(onExitHook);
         /* Create sutdown event */
         gShutdownEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
-        if (!apxJavaStart(hWorker)) {
+        if (!apxJavaStart(&gSargs)) {
             apxLogWrite(APXLOG_MARK_ERROR "Failed starting java");
             rv = 3;
         }
+        else if (lstrcmpA(_jni_sclass, "java/lang/System") == 0) {
+            reportServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, 5000);
+            apxLogWrite(APXLOG_MARK_DEBUG "Forcing java jni System.exit worker to finish...");
+            return 0;
+        }
         else {
             apxLogWrite(APXLOG_MARK_DEBUG "Waiting for java jni stop worker to finish...");
             apxJavaWait(hWorker, INFINITE, FALSE);
@@ -841,6 +877,14 @@ static DWORD WINAPI serviceStop(LPVOID lpParameter)
     else if (SO_STOPMODE) { /* Only in case we have a stop mode */
         DWORD nArgs;
         LPWSTR *pArgs;
+
+        if (!SO_STOPIMAGE) {
+            apxLogWrite(APXLOG_MARK_ERROR "Missing service ImageFile");
+            if (!_service_mode)
+                apxDisplayError(FALSE, NULL, 0, "Service '%S' is missing the ImageFile",
+                                _service_name ? _service_name : L"unknown");
+            return 1;
+        }
         /* Redirect process */
         hWorker = apxCreateProcessW(gPool,
                                     0,
@@ -989,20 +1033,20 @@ static DWORD serviceStart()
             apxLogWrite(APXLOG_MARK_ERROR "Failed creating java %S", _jni_jvmpath);
             return 1;
         }
-        if (!apxJavaInitialize(gWorker, _jni_classpath, _jni_jvmoptions,
-                               SO_JVMMS, SO_JVMMX, SO_JVMSS, SO_JNIVFPRINTF)) {
-            rv = 2;
-            apxLogWrite(APXLOG_MARK_ERROR "Failed initializing java %s", _jni_classpath);
-            goto cleanup;
-        }
-        if (!apxJavaLoadMainClass(gWorker, _jni_rclass, _jni_rmethod, _jni_rparam)) {
-            rv = 3;
-            apxLogWrite(APXLOG_MARK_ERROR "Failed loading main %s class %s", _jni_rclass, _jni_classpath);
-            goto cleanup;
-        }
-        apxJavaSetOut(gWorker, TRUE,  gStdwrap.szStdErrFilename);
-        apxJavaSetOut(gWorker, FALSE, gStdwrap.szStdOutFilename);
-        if (!apxJavaStart(gWorker)) {
+        gRargs.hJava            = gWorker;
+        gRargs.szClassPath      = _jni_classpath;
+        gRargs.lpOptions        = _jni_jvmoptions;
+        gRargs.dwMs             = SO_JVMMS;
+        gRargs.dwMx             = SO_JVMMX;
+        gRargs.dwSs             = SO_JVMSS;
+        gRargs.bJniVfprintf     = SO_JNIVFPRINTF;
+        gRargs.szClassName      = _jni_rclass;
+        gRargs.szMethodName     = _jni_rmethod;
+        gRargs.lpArguments      = _jni_rparam;
+        gRargs.szStdErrFilename = gStdwrap.szStdErrFilename;
+        gRargs.szStdOutFilename = gStdwrap.szStdOutFilename;
+
+        if (!apxJavaStart(&gRargs)) {
             rv = 4;
             apxLogWrite(APXLOG_MARK_ERROR "Failed to start Java");
             goto cleanup;
@@ -1010,6 +1054,13 @@ static DWORD serviceStart()
         apxLogWrite(APXLOG_MARK_DEBUG "Java started %s", _jni_rclass);
     }
     else {
+        if (!SO_STARTIMAGE) {
+            apxLogWrite(APXLOG_MARK_ERROR "Missing service ImageFile");
+            if (!_service_mode)
+                apxDisplayError(FALSE, NULL, 0, "Service '%S' is missing the ImageFile",
+                                _service_name ? _service_name : L"unknown");
+            return 1;
+        }
         /* Redirect process */
         gWorker = apxCreateProcessW(gPool,
                                     0,
@@ -1221,6 +1272,14 @@ void WINAPI serviceMain(DWORD argc, LPTSTR *argv)
             LPWSTR jx = NULL, szJH = SO_JAVAHOME;
             if (!szJH)
                 szJH = apxGetJavaSoftHome(gPool, FALSE);
+            else if (!lstrcmpiW(szJH, PRSRV_JDK)) {
+                /* Figure out the JDK JavaHome */
+                szJH = apxGetJavaSoftHome(gPool, FALSE);
+            }
+            else if (!lstrcmpiW(szJH, PRSRV_JRE)) {
+                /* Figure out the JRE JavaHome */
+                szJH = apxGetJavaSoftHome(gPool, TRUE);
+            }
             if (szJH) {
                 jx = apxPoolAlloc(gPool, (lstrlenW(szJH) + 16) * sizeof(WCHAR));
                 lstrcpyW(jx, szJH);
@@ -1248,6 +1307,14 @@ void WINAPI serviceMain(DWORD argc, LPTSTR *argv)
             LPWSTR jx = NULL, szJH = SO_JAVAHOME;
             if (!szJH)
                 szJH = apxGetJavaSoftHome(gPool, FALSE);
+            else if (!lstrcmpiW(szJH, PRSRV_JDK)) {
+                /* Figure out the JDK JavaHome */
+                szJH = apxGetJavaSoftHome(gPool, FALSE);
+            }
+            else if (!lstrcmpiW(szJH, PRSRV_JRE)) {
+                /* Figure out the JRE JavaHome */
+                szJH = apxGetJavaSoftHome(gPool, TRUE);
+            }
             if (szJH) {
                 jx = apxPoolAlloc(gPool, (lstrlenW(szJH) + 16) * sizeof(WCHAR));
                 lstrcpyW(jx, szJH);
@@ -1340,7 +1407,7 @@ cleanup:
 /* Run the service in the debug mode */
 BOOL docmdDebugService(LPAPXCMDLINE lpCmdline)
 {
-    BOOL rv = FALSE;
+    BOOL rv = TRUE;
 
     _service_mode = FALSE;
     _service_name = lpCmdline->szApplication;
@@ -1370,6 +1437,19 @@ BOOL docmdRunService(LPAPXCMDLINE lpCmdline)
     return rv;
 }
 
+static const char *gSzProc[] = {
+    "",
+    "parse command line arguments",
+    "load configuration",
+    "run service as console application",
+    "run service",
+    "stop service",
+    "update service parameters",
+    "install service",
+    "delete service",
+    NULL
+};
+
 void __cdecl main(int argc, char **argv)
 {
     UINT rv = 0;
@@ -1411,7 +1491,8 @@ void __cdecl main(int argc, char **argv)
     apxLogOpen(gPool, SO_LOGPATH, SO_LOGPREFIX);
     apxLogLevelSetW(NULL, SO_LOGLEVEL);
     apxLogWrite(APXLOG_MARK_DEBUG "Commons Daemon procrun log initialized");
-    apxLogWrite(APXLOG_MARK_INFO "Commons Daemon procrun (%s) started", PRG_VERSION);
+    apxLogWrite(APXLOG_MARK_INFO "Commons Daemon procrun (%s %d-bit) started",
+                PRG_VERSION, PRG_BITS);
 
     AplZeroMemory(&gStdwrap, sizeof(APX_STDWRAP));
 
@@ -1421,12 +1502,12 @@ void __cdecl main(int argc, char **argv)
         gStdwrap.szStdOutFilename = SO_STDOUTPUT;
         gStdwrap.szStdErrFilename = SO_STDERROR;
     }
-    redirectStdStreams(&gStdwrap);
+    redirectStdStreams(&gStdwrap, lpCmdline);
     if (lpCmdline->dwCmdIndex == 2) {
         SYSTEMTIME t;
         GetLocalTime(&t);
         fprintf(stdout, "\n%d-%02d-%02d %02d:%02d:%02d "
-                        "Commons Daemon procrun stdout initialized\n",
+                        "Commons Daemon procrun stdout initialized",
                         t.wYear, t.wMonth, t.wDay,
                         t.wHour, t.wMinute, t.wSecond);
         fprintf(stderr, "\n%d-%02d-%02d %02d:%02d:%02d "
@@ -1474,9 +1555,18 @@ void __cdecl main(int argc, char **argv)
     }
 
 cleanup:
-    if (rv)
+    if (rv) {
+        int ipx = 0;
+        if (rv > 0 && rv < 7)
+            ipx = rv;
         apxLogWrite(APXLOG_MARK_ERROR "Commons Daemon procrun failed "
-                                      "with exit value: %d", rv);
+                                      "with exit value: %d (Failed to %s)",
+                                      rv, gSzProc[ipx]);
+        if (ipx > 2 && !_service_mode) {
+            /* Print something to the user console */
+            apxDisplayError(FALSE, NULL, 0, "Failed to %s", gSzProc[ipx]);
+        }
+    }
     else
         apxLogWrite(APXLOG_MARK_INFO "Commons Daemon procrun finished");
     if (lpCmdline)
diff --git a/src/native/nt/procrun/apps/prunsrv/prunsrv.h b/src/native/windows/apps/prunsrv/prunsrv.h
similarity index 96%
rename from src/native/nt/procrun/apps/prunsrv/prunsrv.h
rename to src/native/windows/apps/prunsrv/prunsrv.h
index 8c3c389..2c5c08f 100644
--- a/src/native/nt/procrun/apps/prunsrv/prunsrv.h
+++ b/src/native/windows/apps/prunsrv/prunsrv.h
@@ -13,19 +13,19 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
- 
+
 /* ====================================================================
  * jar2exe -- convert .jar file to WIN32 executable.
  * Contributed by Mladen Turk <mturk at apache.org>
  * 05 Aug 2003
- * ==================================================================== 
+ * ====================================================================
  */
 
 #ifndef _PRUNSRV_H
 #define _PRUNSRV_H
 
 #undef  PRG_VERSION
-#define PRG_VERSION    "1.0.3.0" 
+#define PRG_VERSION    "1.0.4.0"
 #define PRG_REGROOT   L"Apache Software Foundation\\Procrun 2.0"
 
 #endif /* _PRUNSRV_H */
diff --git a/src/native/nt/procrun/apps/prunsrv/prunsrv.rc b/src/native/windows/apps/prunsrv/prunsrv.rc
similarity index 91%
rename from src/native/nt/procrun/apps/prunsrv/prunsrv.rc
rename to src/native/windows/apps/prunsrv/prunsrv.rc
index ae02271..4628b0e 100644
--- a/src/native/nt/procrun/apps/prunsrv/prunsrv.rc
+++ b/src/native/windows/apps/prunsrv/prunsrv.rc
@@ -13,17 +13,17 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
- 
+
 #include "apxwin.h"
 #include "prunsrv.h"
 
 #define RSTR_PRUNSRV "Commons Daemon Service Runner"
 
-IDI_MAINICON         ICON                   "../../resources/procrunw.ico" 
+IDI_MAINICON         ICON                   "../../resources/procrunw.ico"
 
 1 VERSIONINFO
- FILEVERSION 1,0,3,0
- PRODUCTVERSION 1,0,3,0
+ FILEVERSION 1,0,4,0
+ PRODUCTVERSION 1,0,4,0
  FILEFLAGSMASK 0x3fL
 #if defined(_DEBUG)
  FILEFLAGS 0x03L
@@ -43,7 +43,7 @@ BEGIN
       VALUE "FileDescription", RSTR_PRUNSRV "\0"
       VALUE "FileVersion", PRG_VERSION
       VALUE "InternalName", RSTR_PRUNSRV "\0"
-      VALUE "LegalCopyright", "Copyright � 2000-2010 The Apache Software Foundation.\0"
+      VALUE "LegalCopyright", "Copyright � 2000-2010 The Apache Software Foundation.\0"
       VALUE "OriginalFilename", "prunsrv.exe\0"
       VALUE "ProductName", RSTR_PRUNSRV "\0"
       VALUE "ProductVersion", PRG_VERSION
diff --git a/src/native/nt/procrun/include/Makefile.inc b/src/native/windows/include/Makefile.inc
similarity index 92%
rename from src/native/nt/procrun/include/Makefile.inc
rename to src/native/windows/include/Makefile.inc
index 00854a5..d5a0183 100644
--- a/src/native/nt/procrun/include/Makefile.inc
+++ b/src/native/windows/include/Makefile.inc
@@ -22,13 +22,15 @@
 #                 This file defines CPU architecture and basic compiler
 #                 and linker parameters.
 # Common params:
-#                 CPU       Compile for specified CPU. Supported CPU's are:
+#                 CPU       Compile for specified CPU. Supported CPUs are:
 #                           X86 (Common x86 architecture)
 #                           X64 (AMD64/EMT64 architecture)
 #                           I64 (Intel IA64 architecture)
 #                           If not specified it will default to the
-#                           PROCESSOR_ARCHITECTURE environment variable
-#                           or to the X86 if not specified.
+#                           BUILD_CPU environment variable, failing that
+#                           It will default to the
+#                           PROCESSOR_ARCHITECTURE/ARCHITEW6432 environment variables
+#                           or failing that it will default to X86.
 #                 WINVER    Compile for specified Windows version
 #                           WINNT   for Windows 2000 and up(default)
 #                           WINXP   for Windows XP and up
@@ -92,8 +94,22 @@ RC = rc.exe
 MT = mt.exe
 !ENDIF
 
-# Use BUILD_CPU if CPU was not set
+# If CPU is not defined, apply defaults
 !IF !DEFINED(CPU) || "$(CPU)" == ""
+# Set BUILD_CPU if it is not yet set
+!IF !DEFINED(BUILD_CPU) || "$(BUILD_CPU)" == ""
+!IF "$(PROCESSOR_ARCHITECTURE)" == ""
+!IF "$(PROCESSOR_ARCHITEW6432)" == ""
+# Default to x86, will be upcased later
+BUILD_CPU=x86
+!ELSE
+BUILD_CPU=$(PROCESSOR_ARCHITEW6432)
+!ENDIF
+!ELSE
+BUILD_CPU=$(PROCESSOR_ARCHITECTURE)
+!ENDIF
+!ENDIF
+# Check BUILD_CPU and reset value if necessary
 !IF "$(BUILD_CPU)" == "i386" || "$(BUILD_CPU)" == "x86" || "$(BUILD_CPU)" == "i686"
 CPU=X86
 !ENDIF
@@ -103,17 +119,9 @@ CPU=X64
 !IF "$(BUILD_CPU)" == "ia64" || "$(BUILD_CPU)" == "i64"
 CPU=I64
 !ENDIF
-!ENDIF
-# Figure out CPU from the current host
+# did we manage to set CPU?
 !IF !DEFINED(CPU) || "$(CPU)" == ""
-!IF "$(PROCESSOR_ARCHITECTURE)" == ""
-!IF "$(PROCESSOR_ARCHITEW6432)" == ""
-CPU=X86
-!ELSE
-CPU=$(PROCESSOR_ARCHITEW6432)
-!ENDIF
-!ELSE
-CPU=$(PROCESSOR_ARCHITECTURE)
+!ERROR Unexpected value of BUILD_CPU: $(BUILD_CPU) or PROCESSOR_ARCHITECTURE=$(PROCESSOR_ARCHITECTURE) or PROCESSOR_ARCHITEW6432=$(PROCESSOR_ARCHITEW6432).
 !ENDIF
 !ENDIF
 
diff --git a/src/native/nt/procrun/include/apxwin.h b/src/native/windows/include/apxwin.h
similarity index 99%
rename from src/native/nt/procrun/include/apxwin.h
rename to src/native/windows/include/apxwin.h
index 3659b11..2766956 100644
--- a/src/native/nt/procrun/include/apxwin.h
+++ b/src/native/windows/include/apxwin.h
@@ -206,6 +206,7 @@ LPSTR   lstrlcatA(LPSTR dst, int siz, LPCSTR src);
 LPWSTR  lstrlcatW(LPWSTR dst, int siz, LPCWSTR src);
 LPSTR   lstrlcpyA(LPSTR dst, int siz, LPCSTR src);
 LPWSTR  lstrlcpyW(LPWSTR dst, int siz, LPCWSTR src);
+LPWSTR  lstrlocaseW(LPWSTR str);
 
 PSECURITY_ATTRIBUTES GetNullACL();
 void CleanNullACL(void *sa);
diff --git a/src/native/nt/procrun/include/cmdline.h b/src/native/windows/include/cmdline.h
similarity index 100%
rename from src/native/nt/procrun/include/cmdline.h
rename to src/native/windows/include/cmdline.h
diff --git a/src/native/nt/procrun/include/console.h b/src/native/windows/include/console.h
similarity index 100%
rename from src/native/nt/procrun/include/console.h
rename to src/native/windows/include/console.h
diff --git a/src/native/nt/procrun/include/gui.h b/src/native/windows/include/gui.h
similarity index 100%
rename from src/native/nt/procrun/include/gui.h
rename to src/native/windows/include/gui.h
diff --git a/src/native/nt/procrun/include/handles.h b/src/native/windows/include/handles.h
similarity index 100%
rename from src/native/nt/procrun/include/handles.h
rename to src/native/windows/include/handles.h
diff --git a/src/native/nt/procrun/include/javajni.h b/src/native/windows/include/javajni.h
similarity index 79%
rename from src/native/nt/procrun/include/javajni.h
rename to src/native/windows/include/javajni.h
index 1787eda..012e27a 100644
--- a/src/native/nt/procrun/include/javajni.h
+++ b/src/native/windows/include/javajni.h
@@ -21,6 +21,23 @@ __APXBEGIN_DECLS
 
 #define     APX_JVM_DESTROY 0x00000001
 
+typedef struct stAPXJAVA_THREADARGS
+{
+    LPVOID      hJava;
+    LPCSTR      szClassPath;
+    LPCVOID     lpOptions;
+    DWORD       dwMs;
+    DWORD       dwMx;
+    DWORD       dwSs;
+    DWORD       bJniVfprintf;
+    LPCSTR      szClassName;
+    LPCSTR      szMethodName;
+    LPCVOID     lpArguments;    
+    BOOL        setErrorOrOut;
+    LPCWSTR     szStdErrFilename;
+    LPCWSTR     szStdOutFilename;
+} APXJAVA_THREADARGS, *LPAPXJAVA_THREADARGS;
+
 APXHANDLE   apxCreateJava(APXHANDLE hPool, LPCWSTR szJvmDllPath);
 
 BOOL        apxJavaInitialize(APXHANDLE hJava, LPCSTR szClassPath,
@@ -35,7 +52,7 @@ BOOL        apxJavaLoadMainClass(APXHANDLE hJava, LPCSTR szClassName,
                                  LPCSTR szMethodName,
                                  LPCVOID lpArguments);
 
-BOOL        apxJavaStart(APXHANDLE hJava);
+BOOL        apxJavaStart(LPAPXJAVA_THREADARGS pArgs);
 
 DWORD       apxJavaWait(APXHANDLE hJava, DWORD dwMilliseconds, BOOL bKill);
 
diff --git a/src/native/nt/procrun/include/log.h b/src/native/windows/include/log.h
similarity index 100%
rename from src/native/nt/procrun/include/log.h
rename to src/native/windows/include/log.h
diff --git a/src/native/nt/procrun/include/registry.h b/src/native/windows/include/registry.h
similarity index 100%
rename from src/native/nt/procrun/include/registry.h
rename to src/native/windows/include/registry.h
diff --git a/src/native/nt/procrun/include/rprocess.h b/src/native/windows/include/rprocess.h
similarity index 100%
rename from src/native/nt/procrun/include/rprocess.h
rename to src/native/windows/include/rprocess.h
diff --git a/src/native/nt/procrun/include/service.h b/src/native/windows/include/service.h
similarity index 100%
rename from src/native/nt/procrun/include/service.h
rename to src/native/windows/include/service.h
diff --git a/src/native/nt/procrun/resources/commons.bmp b/src/native/windows/resources/commons.bmp
similarity index 100%
rename from src/native/nt/procrun/resources/commons.bmp
rename to src/native/windows/resources/commons.bmp
diff --git a/src/native/nt/procrun/resources/license.rtf b/src/native/windows/resources/license.rtf
similarity index 100%
rename from src/native/nt/procrun/resources/license.rtf
rename to src/native/windows/resources/license.rtf
diff --git a/src/native/nt/procrun/resources/procrunr.ico b/src/native/windows/resources/procrunr.ico
similarity index 100%
rename from src/native/nt/procrun/resources/procrunr.ico
rename to src/native/windows/resources/procrunr.ico
diff --git a/src/native/nt/procrun/resources/procruns.ico b/src/native/windows/resources/procruns.ico
similarity index 100%
rename from src/native/nt/procrun/resources/procruns.ico
rename to src/native/windows/resources/procruns.ico
diff --git a/src/native/nt/procrun/resources/procrunw.ico b/src/native/windows/resources/procrunw.ico
similarity index 100%
rename from src/native/nt/procrun/resources/procrunw.ico
rename to src/native/windows/resources/procrunw.ico
diff --git a/src/native/nt/procrun/resources/susers.bmp b/src/native/windows/resources/susers.bmp
similarity index 100%
rename from src/native/nt/procrun/resources/susers.bmp
rename to src/native/windows/resources/susers.bmp
diff --git a/src/native/nt/procrun/src/cmdline.c b/src/native/windows/src/cmdline.c
similarity index 100%
rename from src/native/nt/procrun/src/cmdline.c
rename to src/native/windows/src/cmdline.c
diff --git a/src/native/nt/procrun/src/console.c b/src/native/windows/src/console.c
similarity index 100%
rename from src/native/nt/procrun/src/console.c
rename to src/native/windows/src/console.c
diff --git a/src/native/nt/procrun/src/gui.c b/src/native/windows/src/gui.c
similarity index 99%
rename from src/native/nt/procrun/src/gui.c
rename to src/native/windows/src/gui.c
index 9cff3b1..db41b3a 100644
--- a/src/native/nt/procrun/src/gui.c
+++ b/src/native/windows/src/gui.c
@@ -146,7 +146,8 @@ BOOL apxCenterWindow(HWND hwndChild, HWND hwndParent)
     GetWindowRect(hwndChild, &rChild);
     wChild = rChild.right - rChild.left;
     hChild = rChild.bottom - rChild.top;
-
+    if (hwndParent == NULL)
+        hwndParent = GetDesktopWindow();
     /* Get the Height and Width of the parent window */
     GetWindowRect(hwndParent, &rParent);
     wParent = rParent.right - rParent.left;
diff --git a/src/native/nt/procrun/src/handles.c b/src/native/windows/src/handles.c
similarity index 100%
rename from src/native/nt/procrun/src/handles.c
rename to src/native/windows/src/handles.c
diff --git a/src/native/nt/procrun/src/javajni.c b/src/native/windows/src/javajni.c
similarity index 86%
rename from src/native/nt/procrun/src/javajni.c
rename to src/native/windows/src/javajni.c
index 93b8ca4..da09fec 100644
--- a/src/native/nt/procrun/src/javajni.c
+++ b/src/native/windows/src/javajni.c
@@ -15,6 +15,8 @@
  */
 
 #include "apxwin.h"
+#include "handles.h"
+#include "javajni.h"
 #include "private.h"
 
 #include <jni.h>
@@ -61,7 +63,6 @@ static DYNLOAD_FPTR_DECLARE(SetDllDirectoryW) = NULL;
 #define JVM_EXCEPTION_CHECK(jvm) \
     ((*((jvm)->lpEnv))->ExceptionCheck((jvm)->lpEnv) != JNI_OK)
 
-#ifdef _DEBUG
 #define JVM_EXCEPTION_CLEAR(jvm) \
     APXMACRO_BEGIN                                              \
     if ((jvm)->lpEnv) {                                         \
@@ -70,15 +71,6 @@ static DYNLOAD_FPTR_DECLARE(SetDllDirectoryW) = NULL;
             (*((jvm)->lpEnv))->ExceptionClear((jvm)->lpEnv);    \
         }                                                       \
     } APXMACRO_END
-#else
-#define JVM_EXCEPTION_CLEAR(jvm) \
-    APXMACRO_BEGIN                                              \
-    if ((jvm)->lpEnv) {                                         \
-        if ((*((jvm)->lpEnv))->ExceptionCheck((jvm)->lpEnv)) {  \
-            (*((jvm)->lpEnv))->ExceptionClear((jvm)->lpEnv);    \
-        }                                                       \
-    } APXMACRO_END
-#endif
 
 #define JNI_LOCAL_UNREF(obj) \
         (*(lpJava->lpEnv))->DeleteLocalRef(lpJava->lpEnv, obj)
@@ -119,12 +111,32 @@ typedef struct APXJAVAVM {
     HANDLE          hWorkerThread;
     DWORD           iWorkerThread;
     DWORD           dwWorkerStatus;
-
+    SIZE_T          szStackSize;
 } APXJAVAVM, *LPAPXJAVAVM;
 
+/* This is no longer exported in jni.h
+ * However java uses it internally to get
+ * the default stack size
+ */
+typedef struct APX_JDK1_1InitArgs {
+    jint version;
+
+    char **properties;
+    jint checkSource;
+    jint nativeStackSize;
+    jint javaStackSize;
+    jint minHeapSize;
+    jint maxHeapSize;
+    jint verifyMode;
+    char *classpath;
+
+    char padding[128];
+} APX_JDK1_1InitArgs;
+
 #define JAVA_CLASSPATH      "-Djava.class.path="
 #define JAVA_CLASSPATH_W    L"-Djava.class.path="
 #define JAVA_CLASSSTRING    "java/lang/String"
+#define MSVCRT71_DLLNAME    L"\\msvcrt71.dll"
 
 static __inline BOOL __apxJvmAttach(LPAPXJAVAVM lpJava)
 {
@@ -176,7 +188,34 @@ static BOOL __apxLoadJvmDll(LPCWSTR szJvmDllPath)
     /* Suppress the not found system popup message */
     errMode = SetErrorMode(SEM_FAILCRITICALERRORS);
 
+    apxLogWrite(APXLOG_MARK_DEBUG "loading jvm '%S'", dllJvmPath);
     _st_sys_jvmDllHandle = LoadLibraryExW(dllJvmPath, NULL, 0);
+    if (GetFileAttributesW(szJvmDllPath) != INVALID_FILE_ATTRIBUTES) {
+        /* Try to load the MSVCRTxx.dll before JVM.dll
+         */
+        WCHAR  jreBinPath[SIZ_PATHLEN];
+        WCHAR  crtBinPath[SIZ_PATHLEN];
+        DWORD  i, l = 0;
+
+        lstrlcpyW(jreBinPath, SIZ_PATHLEN, dllJvmPath);
+        for (i = lstrlenW(jreBinPath); i > 0, l < 2; i--) {
+            if (jreBinPath[i] == L'\\' || jreBinPath[i] == L'/') {
+                jreBinPath[i] = L'\0';
+                lstrlcpyW(crtBinPath, SIZ_PATHLEN, jreBinPath);
+                lstrlcatW(crtBinPath, SIZ_PATHLEN, MSVCRT71_DLLNAME);
+                if (GetFileAttributesW(crtBinPath) != INVALID_FILE_ATTRIBUTES) {
+                    if (LoadLibraryW(crtBinPath)) {
+                        /* Found MSVCRTxx.dll
+                         */
+                        apxLogWrite(APXLOG_MARK_DEBUG "preloaded '%S'",
+                                    crtBinPath);
+                        break;
+                    }
+                }
+                l++;
+            }
+        }
+    }
     /* This shuldn't happen, but try to search in %PATH% */
     if (IS_INVALID_HANDLE(_st_sys_jvmDllHandle))
         _st_sys_jvmDllHandle = LoadLibraryExW(dllJvmPath, NULL,
@@ -192,6 +231,8 @@ static BOOL __apxLoadJvmDll(LPCWSTR szJvmDllPath)
             if (jreBinPath[i] == L'\\' || jreBinPath[i] == L'/') {
                 jreBinPath[i] = L'\0';
                 DYNLOAD_CALL(SetDllDirectoryW)(jreBinPath);
+                apxLogWrite(APXLOG_MARK_DEBUG "Setting DLL search path to '%S'",
+                            jreBinPath);
                 l++;
             }
         }
@@ -267,9 +308,12 @@ apxCreateJava(APXHANDLE hPool, LPCWSTR szJvmDllPath)
     LPAPXJAVAVM  lpJava;
     jsize        iVmCount;
     JavaVM       *lpJvm = NULL;
+    struct       APX_JDK1_1InitArgs jArgs1_1;
 
     if (!__apxLoadJvmDll(szJvmDllPath))
         return NULL;
+
+
     /*
      */
     if (DYNLOAD_FPTR(JNI_GetCreatedJavaVMs)(&lpJvm, 1, &iVmCount) != JNI_OK) {
@@ -287,6 +331,16 @@ apxCreateJava(APXHANDLE hPool, LPCWSTR szJvmDllPath)
     lpJava = APXHANDLE_DATA(hJava);
     lpJava->lpJvm = lpJvm;
     lpJava->iVmCount = iVmCount;
+
+    /* Guess the stack size
+     */
+    AplZeroMemory(&jArgs1_1, sizeof(jArgs1_1));
+    jArgs1_1.version = JNI_VERSION_1_1;
+    DYNLOAD_FPTR(JNI_GetDefaultJavaVMInitArgs)(&jArgs1_1);
+    if (jArgs1_1.javaStackSize < 0 || jArgs1_1.javaStackSize > (2048 * 1024))
+        jArgs1_1.javaStackSize = 0;
+    lpJava->szStackSize = (SIZE_T)jArgs1_1.javaStackSize;
+
     if (!_st_sys_jvm)
         _st_sys_jvm = lpJvm;
     return hJava;
@@ -338,10 +392,7 @@ static DWORD __apxMultiSzToJvmOptions(APXHANDLE hPool,
         l = __apxGetMultiSzLengthA(lpString, &n);
     }
     n += nExtra;
-    if (IS_INVALID_HANDLE(hPool))
-        buff = apxPoolAlloc(hPool, (n + 1) * sizeof(JavaVMOption) + (l + 1));
-    else
-        buff = apxAlloc((n + 1) * sizeof(JavaVMOption) + (l + 1));
+    buff = apxPoolAlloc(hPool, (n + 1) * sizeof(JavaVMOption) + (l + 1));
 
     *lppArray = (JavaVMOption *)buff;
     p = (LPSTR)(buff + (n + 1) * sizeof(JavaVMOption));
@@ -610,24 +661,10 @@ apxJavaInitialize(APXHANDLE hJava, LPCSTR szClassPath,
         apxFree(szCp);
         apxFree(lpJvmOptions);
     }
-    /* Load standard classes */
-    if (rv) {
-        jclass jClazz = JNICALL_1(FindClass, JAVA_CLASSSTRING);
-        if (!jClazz) {
-            apxLogWrite(APXLOG_MARK_ERROR "FindClass "  JAVA_CLASSSTRING " failed");
-            goto cleanup;
-        }
-        lpJava->clString.jClazz = JNICALL_1(NewGlobalRef, jClazz);
-        JNI_LOCAL_UNREF(jClazz);
-
+    if (rv)
         return TRUE;
-    }
     else
         return FALSE;
-
-cleanup:
-    JVM_EXCEPTION_CLEAR(lpJava);
-    return FALSE;
 }
 
 /* ANSI version only */
@@ -733,12 +770,21 @@ apxJavaLoadMainClass(APXHANDLE hJava, LPCSTR szClassName,
     DWORD       nArgs;
     LPAPXJAVAVM lpJava;
     jclass      jClazz;
+    LPCSTR      szSignature = "([Ljava/lang/String;)V";
 
     if (hJava->dwType != APXHANDLE_TYPE_JVM)
         return FALSE;
     lpJava = APXHANDLE_DATA(hJava);
     if (!__apxJvmAttach(lpJava))
         return FALSE;
+    jClazz = JNICALL_1(FindClass, JAVA_CLASSSTRING);
+    if (!jClazz) {
+        JVM_EXCEPTION_CLEAR(lpJava);
+        apxLogWrite(APXLOG_MARK_ERROR "FindClass "  JAVA_CLASSSTRING " failed");
+        return FALSE;
+    }
+    lpJava->clString.jClazz = JNICALL_1(NewGlobalRef, jClazz);
+    JNI_LOCAL_UNREF(jClazz);
 
     /* Find the class */
     jClazz  = JNICALL_1(FindClass, szClassName);
@@ -753,29 +799,36 @@ apxJavaLoadMainClass(APXHANDLE hJava, LPCSTR szClassName,
 
     if (!szMethodName)
         szMethodName = "main";
+    if (lstrcmpA(szClassName, "java/lang/System") == 0) {
+        /* Usable only for exit method, so force */
+        szSignature  = "(I)V";
+        szMethodName = "exit";
+    }
     lstrlcpyA(lpJava->clWorker.sClazz, 1024, szClassName);
     lstrlcpyA(lpJava->clWorker.sMethod, 512, szMethodName);
     lpJava->clWorker.jMethod = JNICALL_3(GetStaticMethodID,
                                          lpJava->clWorker.jClazz,
-                                         szMethodName, "([Ljava/lang/String;)V");
+                                         szMethodName, szSignature);
     if (!lpJava->clWorker.jMethod) {
         JVM_EXCEPTION_CLEAR(lpJava);
         apxLogWrite(APXLOG_MARK_ERROR "Method 'static void %s(String[])' not found in Class %s",
                 szMethodName, szClassName);
         return FALSE;
     }
-    nArgs = apxMultiSzToArrayW(hJava->hPool, lpArguments, &lpArgs);
-    lpJava->clWorker.jArgs = JNICALL_3(NewObjectArray, nArgs,
-                                       lpJava->clString.jClazz, NULL);
-    if (nArgs) {
-        DWORD i;
-        for (i = 0; i < nArgs; i++) {
-            jstring arg = JNICALL_2(NewString, lpArgs[i], lstrlenW(lpArgs[i]));
-            JNICALL_3(SetObjectArrayElement, lpJava->clWorker.jArgs, i, arg);
-            apxLogWrite(APXLOG_MARK_DEBUG "argv[%d] = %S", i, lpArgs[i]);
+    if (lstrcmpA(szClassName, "java/lang/System")) {
+        nArgs = apxMultiSzToArrayW(hJava->hPool, lpArguments, &lpArgs);
+        lpJava->clWorker.jArgs = JNICALL_3(NewObjectArray, nArgs,
+                                           lpJava->clString.jClazz, NULL);
+        if (nArgs) {
+            DWORD i;
+            for (i = 0; i < nArgs; i++) {
+                jstring arg = JNICALL_2(NewString, lpArgs[i], lstrlenW(lpArgs[i]));
+                JNICALL_3(SetObjectArrayElement, lpJava->clWorker.jArgs, i, arg);
+                apxLogWrite(APXLOG_MARK_DEBUG "argv[%d] = %S", i, lpArgs[i]);
+            }
         }
+        apxFree(lpArgs);
     }
-    apxFree(lpArgs);
     return TRUE;
 }
 
@@ -788,11 +841,31 @@ static DWORD WINAPI __apxJavaWorkerThread(LPVOID lpParameter)
 #define WORKER_EXIT(x)  { rv = x; goto finished; }
     DWORD rv = 0;
     LPAPXJAVAVM lpJava;
-    APXHANDLE   hJava = (APXHANDLE)lpParameter;
-    /* This shouldn't happen */
+    LPAPXJAVA_THREADARGS pArgs = (LPAPXJAVA_THREADARGS)lpParameter;
+    APXHANDLE hJava;
+
+    hJava = (APXHANDLE)pArgs->hJava;
     if (hJava->dwType != APXHANDLE_TYPE_JVM)
-        WORKER_EXIT(0);
-    lpJava = APXHANDLE_DATA(hJava);
+        WORKER_EXIT(1);
+
+    if (!apxJavaInitialize(pArgs->hJava,
+                           pArgs->szClassPath,
+                           pArgs->lpOptions,
+                           pArgs->dwMs, pArgs->dwMx, pArgs->dwSs,
+                           pArgs->bJniVfprintf)) {
+        WORKER_EXIT(2);
+    }
+
+    if (!apxJavaLoadMainClass(pArgs->hJava,
+                              pArgs->szClassName,
+                              pArgs->szMethodName,
+                              pArgs->lpArguments)) {
+        WORKER_EXIT(2);
+    }
+    apxJavaSetOut(pArgs->hJava, TRUE,  pArgs->szStdErrFilename);
+    apxJavaSetOut(pArgs->hJava, FALSE, pArgs->szStdOutFilename);
+
+    lpJava = APXHANDLE_DATA(pArgs->hJava);
     /* Check if we have a class and a method */
     if (!lpJava->clWorker.jClazz || !lpJava->clWorker.jMethod)
         WORKER_EXIT(2);
@@ -805,41 +878,43 @@ static DWORD WINAPI __apxJavaWorkerThread(LPVOID lpParameter)
               lpJava->clWorker.jClazz,
               lpJava->clWorker.jMethod,
               lpJava->clWorker.jArgs);
-
-    JVM_EXCEPTION_CLEAR(lpJava);
-    __apxJvmDetach(lpJava);
-    apxLogWrite(APXLOG_MARK_DEBUG "Java Worker thread %s:%s finished",
-                lpJava->clWorker.sClazz, lpJava->clWorker.sMethod);
+    if (JVM_EXCEPTION_CHECK(lpJava)) {
+        WORKER_EXIT(4);
+    }
+    else {
+        __apxJvmDetach(lpJava);
+    }
 finished:
     lpJava->dwWorkerStatus = 0;
-    apxLogWrite(APXLOG_MARK_DEBUG "Java Worker thread finished %s:%s",
-                lpJava->clWorker.sClazz, lpJava->clWorker.sMethod);
+    apxLogWrite(APXLOG_MARK_DEBUG "Java Worker thread finished %s:%s with status=%d",
+                lpJava->clWorker.sClazz, lpJava->clWorker.sMethod, rv);
     ExitThread(rv);
     /* never gets here but keep the compiler happy */
     return 0;
 }
 
-
-BOOL
-apxJavaStart(APXHANDLE hJava)
+apxJavaStart(LPAPXJAVA_THREADARGS pArgs)
 {
 
     LPAPXJAVAVM lpJava;
-
-    if (hJava->dwType != APXHANDLE_TYPE_JVM)
-        return FALSE;
-    lpJava = APXHANDLE_DATA(hJava);
-
-    lpJava->hWorkerThread = CreateThread(NULL, 0, __apxJavaWorkerThread,
-                                         hJava, CREATE_SUSPENDED,
+    lpJava = APXHANDLE_DATA(pArgs->hJava);
+    lpJava->hWorkerThread = CreateThread(NULL,
+                                         lpJava->szStackSize,
+                                         __apxJavaWorkerThread,
+                                         pArgs, CREATE_SUSPENDED,
                                          &lpJava->iWorkerThread);
     if (IS_INVALID_HANDLE(lpJava->hWorkerThread)) {
         apxLogWrite(APXLOG_MARK_SYSERR);
         return FALSE;
     }
     ResumeThread(lpJava->hWorkerThread);
-    /* Give some time to initialize the thread */
-    Sleep(1000);
+    if (lstrcmpA(lpJava->clWorker.sClazz, "java/lang/System")) {
+        /* Give some time to initialize the thread
+         * Unless we are calling System.exit(0).
+         * This will be hanled by _onexit hook.
+         */
+        Sleep(1000);
+    }
     return TRUE;
 }
 
diff --git a/src/native/nt/procrun/src/log.c b/src/native/windows/src/log.c
similarity index 83%
rename from src/native/nt/procrun/src/log.c
rename to src/native/windows/src/log.c
index e55854d..939aa58 100644
--- a/src/native/nt/procrun/src/log.c
+++ b/src/native/windows/src/log.c
@@ -18,13 +18,13 @@
 #include "private.h"
 #include <stdio.h>
 
-#define LINE_SEP    "\n"
+#define LINE_SEP    "\r\n"
 #define LOGF_EXT    L".%04d-%02d-%02d.log"
 
 static LPCSTR _log_level[] = {
     "[debug] ",
-    "[info] ",
-    "[warn] ",
+    "[info]  ",
+    "[warn]  ",
     "[error] ",
     NULL
 };
@@ -112,7 +112,16 @@ HANDLE apxLogOpen(
     if (!szPath) {
         if (GetSystemDirectoryW(sPath, MAX_PATH) == 0)
             return INVALID_HANDLE_VALUE;
-        lstrlcatW(sPath, MAX_PATH, L"\\LogFiles\\Apache");
+        lstrlcatW(sPath, MAX_PATH, L"\\LogFiles");
+        if (!CreateDirectoryW(sPath, NULL) && GetLastError() != ERROR_ALREADY_EXISTS) {
+            if (!CreateDirectoryW(sPath, NULL))
+                return INVALID_HANDLE_VALUE;
+        }
+        lstrlcatW(sPath, MAX_PATH, L"\\Apache");
+        if (!CreateDirectoryW(sPath, NULL) && GetLastError() != ERROR_ALREADY_EXISTS) {
+            if (!CreateDirectoryW(sPath, NULL))
+                return INVALID_HANDLE_VALUE;
+        }
     }
     else {
         lstrlcpyW(sPath, MAX_PATH, szPath);
@@ -125,7 +134,7 @@ HANDLE apxLogOpen(
               sysTime.wMonth,
               sysTime.wDay);
     if (!(h = (apx_logfile_st *)apxPoolCalloc(hPool, sizeof(apx_logfile_st))))
-        return NULL;
+        return INVALID_HANDLE_VALUE;
     /* Set default level to info */
     h->dwLogLevel = APXLOG_LEVEL_INFO;
     CreateDirectoryW(sPath, NULL);
@@ -141,6 +150,13 @@ HANDLE apxLogOpen(
                       OPEN_ALWAYS,
                       FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH | FILE_FLAG_SEQUENTIAL_SCAN,
                       NULL);
+    if (h->hFile == INVALID_HANDLE_VALUE) {
+        /* Make sure we write somewhere */
+        h = &_st_sys_errhandle;
+        apxDisplayError(FALSE, NULL, 0,
+                        "Unable to create logger at '%S'\n", sPath);
+        return (HANDLE)h;
+    }
     /* Set this file as system log file */
     if (!_st_sys_loghandle)
         _st_sys_loghandle = h;
@@ -231,7 +247,7 @@ apxLogWrite(
     ...)
 {
     va_list args;
-    CHAR    buffer[1024+32];
+    CHAR    buffer[1024+32] = "";
     LPSTR   szBp;
     int     len = 0;
     LPCSTR  f = szFile;
@@ -258,16 +274,26 @@ apxLogWrite(
         if(f != szFile)
             f++;
     }
-    szBp = &buffer[0];
+    else
+        f = "";
+    szBp = buffer;
     if (!szFormat) {
-        FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM |
-                       FORMAT_MESSAGE_IGNORE_INSERTS,
-                       NULL,
-                       err,
-                       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-                       szBp,
-                       1000,
-                       NULL);
+        if (err == 0) {
+            lstrcpyA(szBp, "Unknown error code");
+            if (dwLevel == APXLOG_LEVEL_ERROR) {
+                szBp += 18;
+                wsprintfA(szBp, " occured in (%s:%d) ", f, dwLine);
+            }
+        }
+        else
+            FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM |
+                           FORMAT_MESSAGE_IGNORE_INSERTS,
+                           NULL,
+                           err,
+                           MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+                           szBp,
+                           1000,
+                           NULL);
     }
     else {
         va_start(args, szFormat);
@@ -277,10 +303,10 @@ apxLogWrite(
     len = lstrlenA(buffer);
     if (len > 0) {
         /* Remove trailing line separator */
-        if (buffer[len - 1] == '\n') {
-            buffer[len - 1] = '\0';
-            --len;
-        }
+        if (buffer[len - 1] == '\n')
+            buffer[--len] = '\0';
+        if (len > 0 && buffer[len - 1] == '\r')
+            buffer[--len] = '\0';
         if (!IS_INVALID_HANDLE(lf->hFile)) {
             SYSTEMTIME t;
             GetLocalTime(&t);
@@ -303,8 +329,9 @@ apxLogWrite(
                 wsprintfA(sb, "(%10s:%-4d) ", f, dwLine);
                 WriteFile(lf->hFile, sb, lstrlenA(sb), &wr, NULL);
             }
-            WriteFile(lf->hFile, buffer, len, &wr, NULL);
-            
+            if (len)
+                WriteFile(lf->hFile, buffer, len, &wr, NULL);
+
             /* Terminate the line */
             WriteFile(lf->hFile, LINE_SEP, sizeof(LINE_SEP) - 1, &wr, NULL);
 #ifdef _DEBUG_FULL
@@ -365,6 +392,8 @@ apxDisplayError(
         if(f != szFile)
             f++;
     }
+    else
+        f = "";
     sysbuf[0] = '\0';
     if (err != ERROR_SUCCESS) {
         len = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM |
@@ -375,15 +404,13 @@ apxDisplayError(
                              sysbuf,
                              SIZ_DESLEN,
                              NULL);
+        sysbuf[len] = '\0';
         if (len > 0) {
-            sysbuf[len] = '\0';
-            if (sysbuf[len - 1] == '\n') {
-                sysbuf[len - 1] = '\0';
-                --len;
-            }
+            if (sysbuf[len - 1] == '\n')
+                sysbuf[--len] = '\0';
+            if (len > 0 && sysbuf[len - 1] == '\r')
+                sysbuf[--len] = '\0';
         }
-        else
-            sysbuf[0] = '\0';
     }
     if (szFormat) {
         va_start(args, szFormat);
@@ -394,7 +421,7 @@ apxDisplayError(
             wsprintfA(sb, "%s (%d)", f, dwLine);
             lstrcatA(sysbuf, sb);
         }
-        lstrlcatA(sysbuf, SIZ_HUGLEN, "\n");
+        lstrlcatA(sysbuf, SIZ_HUGLEN, LINE_SEP);
         lstrlcatA(sysbuf, SIZ_HUGLEN, buffer);
     }
     len = lstrlenA(sysbuf);
@@ -409,7 +436,8 @@ apxDisplayError(
         }
         else {
             fputs(sysbuf, stderr);
-            fputc('\n', stderr);
+            if (!szFormat)
+                fputs(LINE_SEP, stderr);
             fflush(stderr);
         }
     }
diff --git a/src/native/nt/procrun/src/mclib.c b/src/native/windows/src/mclib.c
similarity index 98%
rename from src/native/nt/procrun/src/mclib.c
rename to src/native/windows/src/mclib.c
index dee50f9..ef9c7a4 100644
--- a/src/native/nt/procrun/src/mclib.c
+++ b/src/native/windows/src/mclib.c
@@ -311,7 +311,7 @@ lstrlcatA(LPSTR dst, int siz, LPCSTR src)
     /* Find the end of dst and adjust bytes left but don't go past end */
     while (n-- != 0 && *d != '\0')
         d++;
-    dlen = d - dst;
+    dlen = (int)(d - dst);
     n = siz - dlen;
 
     if (n == 0)
@@ -339,7 +339,7 @@ lstrlcatW(LPWSTR dst, int siz, LPCWSTR src)
     /* Find the end of dst and adjust bytes left but don't go past end */
     while (n-- != 0 && *d != '\0')
         d++;
-    dlen = d - dst;
+    dlen = (int)(d - dst);
     n = siz - dlen;
 
     if (n == 0)
@@ -407,3 +407,14 @@ lstrlcpyW(LPWSTR dst, int siz, LPCWSTR src)
 
     return d;
 }
+
+LPWSTR
+lstrlocaseW(LPWSTR str)
+{
+    LPWSTR  p = str;
+    while (p && *p != 0) {
+        *p = towlower(*p);
+        p++;
+    }
+    return str;
+}
diff --git a/src/native/nt/procrun/src/mclib.h b/src/native/windows/src/mclib.h
similarity index 100%
rename from src/native/nt/procrun/src/mclib.h
rename to src/native/windows/src/mclib.h
diff --git a/src/native/nt/procrun/src/private.h b/src/native/windows/src/private.h
similarity index 100%
rename from src/native/nt/procrun/src/private.h
rename to src/native/windows/src/private.h
diff --git a/src/native/nt/procrun/src/registry.c b/src/native/windows/src/registry.c
similarity index 99%
rename from src/native/nt/procrun/src/registry.c
rename to src/native/windows/src/registry.c
index 0936ec3..c284f22 100644
--- a/src/native/nt/procrun/src/registry.c
+++ b/src/native/windows/src/registry.c
@@ -236,10 +236,14 @@ apxCreateRegistryW(APXHANDLE hPool, REGSAM samDesired,
     HKEY      hSparamKey = NULL;
     HKEY      hUparamKey = NULL;
 
-    if (!szKeyName || lstrlenW(szKeyName) > SIZ_RESMAX)
+    if (!szKeyName || lstrlenW(szKeyName) > SIZ_RESMAX) {
+        SetLastError(ERROR_INVALID_PARAMETER);
         return NULL;
-    if (szRoot && lstrlenW(szRoot) > SIZ_RESMAX)
+    }
+    if (szRoot && lstrlenW(szRoot) > SIZ_RESMAX) {
+        SetLastError(ERROR_INVALID_PARAMETER);
         return NULL;
+    }
 
     /* make the HKLM\\SOFTWARE key */
     lstrcpyW(buff, REGSOFTWARE_ROOT);
diff --git a/src/native/nt/procrun/src/rprocess.c b/src/native/windows/src/rprocess.c
similarity index 100%
rename from src/native/nt/procrun/src/rprocess.c
rename to src/native/windows/src/rprocess.c
diff --git a/src/native/nt/procrun/src/service.c b/src/native/windows/src/service.c
similarity index 98%
rename from src/native/nt/procrun/src/service.c
rename to src/native/windows/src/service.c
index 4c69f83..e666928 100644
--- a/src/native/nt/procrun/src/service.c
+++ b/src/native/windows/src/service.c
@@ -39,14 +39,21 @@ typedef struct APXSERVICE {
 
 } APXSERVICE, *LPAPXSERVICE;
 
+static WCHAR __invalidPathChars[] = L"<>:\"/\\:|?*";
 static BOOL __apxIsValidServiceName(LPCWSTR szServiceName)
 {
-    do {
-        if (!IsCharAlphaNumericW(*szServiceName)) {
-            apxDisplayError(FALSE, NULL, 0, "NonAlpha %d", *szServiceName);
-            return FALSE;
+    WCHAR ch;
+    int   i = 0;
+    while ((ch = szServiceName[i++])) {
+        int j = 0;
+        while (__invalidPathChars[j]) {
+            if (ch < 30 || ch == __invalidPathChars[j++]) {
+                apxDisplayError(FALSE, NULL, 0, "Service '%S' contains invalid character '%C'",
+                                szServiceName, ch);
+                return FALSE;
+            }
         }
-    } while( *(++szServiceName));
+    }
     return TRUE;
 }
 
diff --git a/src/native/nt/procrun/src/utils.c b/src/native/windows/src/utils.c
similarity index 100%
rename from src/native/nt/procrun/src/utils.c
rename to src/native/windows/src/utils.c
diff --git a/src/native/nt/procrun/xdocs/index.xml b/src/native/windows/xdocs/index.xml
similarity index 100%
rename from src/native/nt/procrun/xdocs/index.xml
rename to src/native/windows/xdocs/index.xml
diff --git a/src/samples/AloneService.java b/src/samples/AloneService.java
index b2aef12..604b446 100644
--- a/src/samples/AloneService.java
+++ b/src/samples/AloneService.java
@@ -15,21 +15,20 @@
  *  limitations under the License.
  */
 
-/* @version $Id: AloneService.java 941216 2010-05-05 09:21:53Z sebb $ */
+/* @version $Id: AloneService.java 1024526 2010-10-20 05:21:16Z mturk $ */
 
-import java.io.File;
+import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.PrintStream;
-import java.util.Iterator;
-
-import org.apache.commons.collections.ExtendedProperties;
+import java.util.Enumeration;
+import java.util.Properties;
 
 /*
  * That is like the ServiceDaemon but it does not use the Daemon interface.
  */
 public class AloneService {
 
-    private ExtendedProperties prop = null;
+    private Properties prop = null;
     private Process proc[] = null;
     private ServiceDaemonReadThread readout[] = null;
     private ServiceDaemonReadThread readerr[] = null;
@@ -45,17 +44,23 @@ public class AloneService {
     public void init(String[] arguments)
     throws Exception {
         /* Set the err */
-        System.setErr(new PrintStream(new FileOutputStream(new File("/ServiceDaemon.err"),true)));
+        System.setErr(new PrintStream(new FileOutputStream("/ServiceDaemon.err",true)));
         System.err.println("ServiceDaemon: instance "+this.hashCode()+
                            " init");
 
         /* read the properties file */
-        prop = new ExtendedProperties("startfile");
-
+        prop = new Properties();
+        try {
+            prop.load(new FileInputStream("startfile"));
+        }
+        catch (Exception e) {
+            // Cannot find startfile.properties.
+            // XXX: Should we print something?
+        }
         /* create an array to store the processes */
         int i=0;
-        for (Iterator e = prop.getKeys(); e.hasNext() ;) {
-            e.next();
+        for (Enumeration e = prop.keys(); e.hasMoreElements() ;) {
+            e.nextElement();
             i++;
         }
         System.err.println("ServiceDaemon: init for " + i + " processes");
@@ -78,11 +83,11 @@ public class AloneService {
 
         /* 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));
+        for (Enumeration e = prop.keys(); e.hasMoreElements() ;) {
+           String name = (String) e.nextElement();
+           System.err.println("ServiceDaemon: starting: " + name + " : " + prop.getProperty(name));
            try {
-               proc[i] = Runtime.getRuntime().exec(prop.getString(name));
+               proc[i] = Runtime.getRuntime().exec(prop.getProperty(name));
            } catch(Exception ex) {
                System.err.println("Exception: " + ex);
            }
diff --git a/src/samples/Native.c b/src/samples/Native.c
index 953539f..52d0cd1 100644
--- a/src/samples/Native.c
+++ b/src/samples/Native.c
@@ -18,7 +18,7 @@
  * Native routine to core JVM
  */
 #include <jni.h>
- 
+
 #ifndef _Included_Native
 #define _Included_Native
 #ifdef __cplusplus
@@ -36,7 +36,7 @@ JNIEXPORT void JNICALL Java_SimpleDaemon_toto
     memcpy(&i, &i, i);
     memset(&i, ' ', 1024);
 }
- 
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/samples/ProcrunService.java b/src/samples/ProcrunService.java
index c8a4db2..b944460 100644
--- a/src/samples/ProcrunService.java
+++ b/src/samples/ProcrunService.java
@@ -3,6 +3,16 @@ import java.io.IOException;
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
 import java.util.Date;
+//import java.util.Enumeration;
+import java.util.Iterator;
+//import java.util.List;
+//import java.util.Map;
+import java.util.Properties;
+import java.util.TreeSet;
+//import java.net.InterfaceAddress;
+//import java.net.NetworkInterface;
+//import java.net.SocketException;
+
 
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -19,14 +29,14 @@ import java.util.Date;
  * 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.
- * 
+ *
  */
 
 /**
  * Sample service implementation for use with Windows Procrun.
  * <p>
  * Use the main() method for running as a Java (external) service.
- * Use the start() and stop() methods for running as a jvm (in-process) service 
+ * Use the start() and stop() methods for running as a jvm (in-process) service
  */
 public class ProcrunService implements Runnable {
 
@@ -34,16 +44,16 @@ public class ProcrunService implements Runnable {
     private static final long MS_PER_SEC = 1000L; // Milliseconds in a second
 
     private static volatile Thread thrd; // start and stop are called from different threads
-    
+
     private final long pause; // How long to pause in service loop
 
     private final File stopFile;
-    
+
     /**
-     * 
+     *
      * @param wait seconds to wait in loop
      * @param filename optional filename - if non-null, run loop will stop when it disappears
-     * @throws IOException 
+     * @throws IOException
      */
     private ProcrunService(long wait, File file) {
         pause=wait;
@@ -56,12 +66,12 @@ public class ProcrunService implements Runnable {
     }
 
     private static void usage(){
-        System.err.println("Must supply the argument 'start' or 'stop'");        
+        System.err.println("Must supply the argument 'start' or 'stop'");
     }
 
     /**
      * Helper method for process args with defaults.
-     * 
+     *
      * @param args array of string arguments, may be empty
      * @param argnum which argument to extract
      * @return the argument or null
@@ -74,13 +84,74 @@ public class ProcrunService implements Runnable {
         }
     }
 
+    private static void logSystemEnvironment()
+    {
+        ClassLoader cl = Thread.currentThread().getContextClassLoader();
+        if (cl == null)
+            log("Missing currentThread context ClassLoader");
+        else
+            log("Using context ClassLoader : " + cl.toString());
+        log("Program environment: ");
+
+// Java 1.5+ code
+//        Map        em = System.getenv();
+//        TreeSet    es = new TreeSet(em.keySet());
+//        for (Iterator i = es.iterator(); i.hasNext();) {
+//            String n = (String)i.next();
+//            log(n + " ->  " + em.get(n));
+//        }
+
+        log("System properties: ");
+        Properties ps = System.getProperties();
+        TreeSet    ts = new TreeSet(ps.keySet());
+        for (Iterator i = ts.iterator(); i.hasNext();) {
+            String n = (String)i.next();
+            log(n + " ->  " + ps.get(n));
+        }
+
+// Java 1.6+ code
+//        log("Network interfaces: ");
+//        log("LVPMU (L)oopback (V)irtual (P)ointToPoint (M)multicastSupport (U)p");
+//        try {
+//            for (Enumeration e = NetworkInterface.getNetworkInterfaces(); e.hasMoreElements();) {
+//                NetworkInterface n = (NetworkInterface)e.nextElement();
+//                char [] flags = { '-', '-', '-', '-', '-'};
+//                if (n.isLoopback())
+//                    flags[0] = 'x';
+//                if (n.isVirtual())
+//                    flags[1] = 'x';
+//                if (n.isPointToPoint())
+//                    flags[2] = 'x';
+//                if (n.supportsMulticast())
+//                    flags[3] = 'x';
+//                if (n.isUp())
+//                    flags[4] = 'x';
+//                String neti = new String(flags) + "   " + n.getName() + "\t";
+//                for (Enumeration i = n.getSubInterfaces(); i.hasMoreElements();) {
+//                    NetworkInterface s = (NetworkInterface)i.nextElement();
+//                    neti += " [" + s.getName() + "]";
+//                }
+//                log(neti + " -> " + n.getDisplayName());
+//                List i = n.getInterfaceAddresses();
+//                if (!i.isEmpty()) {
+//                    for (int x = 0; x < i.size(); x++) {
+//                        InterfaceAddress a = (InterfaceAddress)i.get(x);
+//                        log("        " + a.toString());
+//                    }
+//                }
+//            }
+//        } catch (SocketException e) {
+//            // Ignore
+//        }
+    }
+
     /**
      * Common entry point for start and stop service functions.
      * To allow for use with Java mode, a temporary file is created
      * by the start service, and a deleted by the stop service.
-     * 
+     *
      * @param args [start [pause time] | stop]
-     * @throws IOException if there are problems creating or deleting the temporary file 
+     * @throws IOException if there are problems creating or deleting the temporary file
      */
     public static void main(String[] args) throws IOException {
         final int argc = args.length;
@@ -105,7 +176,7 @@ public class ProcrunService implements Runnable {
 
     /**
      * Start the jvm version of the service, and waits for it to complete.
-     * 
+     *
      * @param args optional, arg[0] = timeout (seconds)
      */
     public static void start(String [] args) {
@@ -140,7 +211,7 @@ public class ProcrunService implements Runnable {
             thrd.interrupt();
         } else {
             log("No thread to interrupt");
-        }        
+        }
     }
 
     /**
@@ -149,8 +220,7 @@ public class ProcrunService implements Runnable {
      */
     public void run() {
         log("Started thread in "+System.getProperty("user.dir"));
-        log("user.name="+System.getProperty("user.name"));
-        log("user.home="+System.getProperty("user.home"));
+        logSystemEnvironment();
         while(stopFile == null || stopFile.exists()){
             try {
                 log("pausing...");
@@ -166,7 +236,7 @@ public class ProcrunService implements Runnable {
         DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss ");
         System.out.println(df.format(new Date())+msg);
     }
-    
+
     protected void finalize(){
         log("Finalize called from thread "+Thread.currentThread());
     }
diff --git a/src/samples/ServiceDaemon.java b/src/samples/ServiceDaemon.java
index 3eb6b92..af217c1 100644
--- a/src/samples/ServiceDaemon.java
+++ b/src/samples/ServiceDaemon.java
@@ -15,21 +15,22 @@
  *  limitations under the License.
  */
 
-/* @version $Id: ServiceDaemon.java 937350 2010-04-23 16:03:39Z sebb $ */
+/* @version $Id: ServiceDaemon.java 1024526 2010-10-20 05:21:16Z mturk $ */
 
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.PrintStream;
-import java.util.Iterator;
+import java.util.Enumeration;
+import java.util.Properties;
 
-import org.apache.commons.collections.ExtendedProperties;
 import org.apache.commons.daemon.Daemon;
 import org.apache.commons.daemon.DaemonContext;
 
 public class ServiceDaemon implements Daemon {
 
-    private ExtendedProperties prop = null;
+    private Properties prop = null;
     private Process proc[] = null;
     private ServiceDaemonReadThread readout[] = null;
     private ServiceDaemonReadThread readerr[] = null;
@@ -56,12 +57,18 @@ public class ServiceDaemon implements Daemon {
                            " init");
 
         /* read the properties file */
-        prop = new ExtendedProperties("startfile");
-
+        prop = new Properties();
+        try {
+            prop.load(new FileInputStream("startfile"));
+        }
+        catch (Exception e) {
+            // Cannot find startfile.properties.
+            // XXX: Should we print something?
+        }
         /* create an array to store the processes */
         int i=0;
-        for (Iterator e = prop.getKeys(); e.hasNext() ;) {
-            e.next();
+        for (Enumeration e = prop.keys(); e.hasMoreElements() ;) {
+            e.nextElement();
             i++;
         }
         System.err.println("ServiceDaemon: init for " + i + " processes");
@@ -84,12 +91,12 @@ public class ServiceDaemon implements Daemon {
 
         /* 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) {
+        for (Enumeration e = prop.keys(); e.hasMoreElements() ;) {
+            String name = (String) e.nextElement();
+            System.err.println("ServiceDaemon: starting: " + name + " : " + prop.getProperty(name));
+            try {
+                proc[i] = Runtime.getRuntime().exec(prop.getProperty(name));
+            } catch(Exception ex) {
                System.err.println("Exception: " + ex);
            }
            /* Start threads to read from Error and Out streams */
diff --git a/src/samples/SimpleDaemon.java b/src/samples/SimpleApplication.java
similarity index 73%
copy from src/samples/SimpleDaemon.java
copy to src/samples/SimpleApplication.java
index 640523b..ab67c67 100644
--- a/src/samples/SimpleDaemon.java
+++ b/src/samples/SimpleApplication.java
@@ -15,7 +15,7 @@
  *  limitations under the License.
  */
 
-/* @version $Id: SimpleDaemon.java 937350 2010-04-23 16:03:39Z sebb $ */
+/* @version $Id: SimpleApplication.java 937350 2010-04-23 16:03:39Z sebb $ */
 
 import java.io.File;
 import java.io.FileOutputStream;
@@ -23,7 +23,7 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.PrintStream;
-import java.io.UnsupportedEncodingException;
+//import java.io.UnsupportedEncodingException;
 import java.net.ServerSocket;
 import java.net.Socket;
 import java.text.SimpleDateFormat;
@@ -31,70 +31,75 @@ import java.util.Date;
 import java.util.Enumeration;
 import java.util.Vector;
 
-import org.apache.commons.daemon.Daemon;
-import org.apache.commons.daemon.DaemonContext;
-import org.apache.commons.daemon.DaemonController;
-
-public class SimpleDaemon implements Daemon, Runnable {
+public class SimpleApplication implements Runnable {
 
     private ServerSocket server=null;
     private Thread thread=null;
-    private DaemonController controller=null;
     private volatile boolean stopping=false;
     private String directory=null;
     private final Vector handlers;
 
     public static native void toto();
 
-    public SimpleDaemon() {
+    public SimpleApplication()
+    {
         super();
-        System.err.println("SimpleDaemon: instance "+this.hashCode()+
+        System.err.println("SimpleApplication: instance "+this.hashCode()+
                            " created");
         this.handlers=new Vector();
     }
 
     protected void finalize() {
-        System.err.println("SimpleDaemon: instance "+this.hashCode()+
+        System.err.println("SimpleApplication: instance "+this.hashCode()+
                            " garbage collected");
     }
 
     /**
-     * init and destroy were added in jakarta-tomcat-daemon.
+     * Main methos
      */
-    public void init(DaemonContext context)
-    throws Exception {
-        System.err.println("SimpleDaemon: instance "+this.hashCode()+
-                           " init");
-
+    public static void main(String[] args)
+        throws Exception
+    {
+        SimpleApplication app = new SimpleApplication();
+        System.err.println("SimpleApplication: instance " + app.hashCode()+
+                           " init " + args.length);
         int port=1200;
+        for (int i = 0; i < args.length; i++) {
+            System.err.println("SimpleApplication: arg " + i +
+                    " = " + args[i]);
 
-        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";
+        }
+        if (args.length > 0 && args[0].length() > 0)
+            port=Integer.parseInt(args[0]);
+        if (args.length > 1)
+            app.directory = args[1];
+        else
+            app.directory="/tmp";
 
         /* Dump a message */
-        System.err.println("SimpleDaemon: loading on port "+port);
-
+        System.err.println("SimpleApplication: loading on port "+port);
+        Runtime.getRuntime().addShutdownHook(new ShutdownHook(app));
         /* Set up this simple daemon */
-        this.controller=context.getController();
-        this.server=new ServerSocket(port);
-        this.thread=new Thread(this);
+        app.server = new ServerSocket(port);
+        app.thread = new Thread(app);
+        app.start();
     }
 
-    public void start() {
+    public void start()
+    {
         /* Dump a message */
-        System.err.println("SimpleDaemon: starting");
+        System.err.println("SimpleApplication: starting");
 
         /* Start */
         this.thread.start();
     }
 
     public void stop()
-    throws IOException, InterruptedException {
+        throws IOException, InterruptedException
+    {
         /* Dump a message */
-        System.err.println("SimpleDaemon: stopping");
+        System.err.println("SimpleApplication: stopping");
 
         /* Close the ServerSocket. This will make our thread to terminate */
         this.stopping=true;
@@ -102,22 +107,24 @@ public class SimpleDaemon implements Daemon, Runnable {
 
         /* Wait for the main thread to exit and dump a message */
         this.thread.join(5000);
-        System.err.println("SimpleDaemon: stopped");
+        System.err.println("SimpleApplication: stopped");
     }
 
-    public void destroy() {
-        System.err.println("SimpleDaemon: instance "+this.hashCode()+
+    public void destroy()
+    {
+        System.err.println("SimpleApplication: instance "+this.hashCode()+
                            " destroy");
     }
 
-    public void run() {
+    public void run()
+    {
         int number=0;
 
-        System.err.println("SimpleDaemon: started acceptor loop");
+        System.err.println("SimpleApplication: started acceptor loop");
         try {
             while(!this.stopping) {
                 Socket socket=this.server.accept();
-                Handler handler=new Handler(socket,this,this.controller);
+                Handler handler=new Handler(socket,this);
                 handler.setConnectionNumber(number++);
                 handler.setDirectoryName(this.directory);
                 new Thread(handler).start();
@@ -132,12 +139,12 @@ public class SimpleDaemon implements Daemon, Runnable {
         Enumeration openhandlers=this.handlers.elements();
         while (openhandlers.hasMoreElements()) {
             Handler handler=(Handler)openhandlers.nextElement();
-            System.err.println("SimpleDaemon: dropping connection "+
+            System.err.println("SimpleApplication: dropping connection "+
                                handler.getConnectionNumber());
             handler.close();
         }
 
-        System.err.println("SimpleDaemon: exiting acceptor loop");
+        System.err.println("SimpleApplication: exiting acceptor loop");
     }
 
     protected void addHandler(Handler handler) {
@@ -152,24 +159,42 @@ public class SimpleDaemon implements Daemon, Runnable {
         }
     }
 
+    public static class ShutdownHook extends Thread
+    {
+        private final SimpleApplication instance;
+
+        public ShutdownHook(SimpleApplication instance)
+        {
+            this.instance = instance;
+        }
+        public void run()
+        {
+            System.out.println("Shutting down");
+            try {
+                instance.stop();
+            }
+            catch (Exception e) {
+                e.printStackTrace(System.err);
+            }
+        }
+    }
+
     public static class Handler implements Runnable {
 
-        private final DaemonController controller;
-        private final SimpleDaemon parent;
+        private final SimpleApplication parent;
         private String directory=null; // Only set before thread is started
         private final Socket socket;
         private int number=0; // Only set before thread is started
 
-        public Handler(Socket s, SimpleDaemon p, DaemonController c) {
+        public Handler(Socket s, SimpleApplication p) {
             super();
             this.socket=s;
             this.parent=p;
-            this.controller=c;
         }
 
         public void run() {
             this.parent.addHandler(this);
-            System.err.println("SimpleDaemon: connection "+this.number+
+            System.err.println("SimpleApplication: connection "+this.number+
                                " opened from "+this.socket.getInetAddress());
             try {
                 InputStream in=this.socket.getInputStream();
@@ -179,7 +204,7 @@ public class SimpleDaemon implements Daemon, Runnable {
             } catch (IOException e) {
                 e.printStackTrace(System.err);
             }
-            System.err.println("SimpleDaemon: connection "+this.number+
+            System.err.println("SimpleApplication: connection "+this.number+
                                " closed");
             this.parent.removeHandler(this);
         }
@@ -230,11 +255,11 @@ public class SimpleDaemon implements Daemon, Runnable {
 
         public void handle(InputStream in, OutputStream os) {
             PrintStream out=null;
-            try {
-                out=new PrintStream(os, true, "US-ASCII");
-            } catch (UnsupportedEncodingException ex) {
-                out=new PrintStream(os);
-            }
+//            try {
+//                out=new PrintStream(os, true, "US-ASCII"); // Java 1.4+
+//            } catch (UnsupportedEncodingException ex) {
+                out=new PrintStream(os, true);
+//            }
 
             while(true) {
                 try {
@@ -244,11 +269,10 @@ public class SimpleDaemon implements Daemon, Runnable {
                         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.println("    5) Cause a core of the JVM");
-                        out.println("    6) Create a directory");
+                        out.println("    2) Create a file");
+                        out.println("    3) Disconnect");
+                        out.println("    4) Cause a core of the JVM");
+                        out.println("    5) Create a directory");
                         out.print("Your choice: ");
                     }
 
@@ -264,7 +288,7 @@ public class SimpleDaemon implements Daemon, Runnable {
                         case '1':
                             out.println("Attempting a shutdown...");
                             try {
-                                this.controller.shutdown();
+                                System.exit(0);
                             } catch (IllegalStateException e) {
                                 out.println();
                                 out.println("Can't shutdown now");
@@ -272,22 +296,10 @@ public class SimpleDaemon implements Daemon, Runnable {
                             }
                             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;
-
                         /* Create a file */
-                        case '3':
+                        case '2':
                             String name=this.getDirectoryName()+
-                                        "/SimpleDaemon."+
+                                        "/SimpleApplication."+
                                         this.getConnectionNumber()+
                                         ".tmp";
                             try {
@@ -299,21 +311,21 @@ public class SimpleDaemon implements Daemon, Runnable {
                             break;
 
                         /* Disconnect */
-                        case '4':
+                        case '3':
                             out.println("Disconnecting...");
                             return;
 
                         /* Crash JVM in a native call: It need an so file ;-) */
-                        case '5':
+                        case '4':
                             System.load(System.getProperty("native.library", "./Native.so"));
                             toto();
                             break;
 
                         /* Create a directory (PR 30177 with 1.4.x and 1.5.0 */
-                        case '6':
+                        case '5':
                             String name1=this.getDirectoryName()+
                                         "/a/b/c/d/e"+
-                                        "/SimpleDaemon."+
+                                        "/SimpleApplication."+
                                         this.getConnectionNumber()+
                                         ".tmp";
                             try {
@@ -339,7 +351,7 @@ public class SimpleDaemon implements Daemon, Runnable {
 
                 /* If we get an IOException we return (disconnect) */
                 } catch (IOException e) {
-                    System.err.println("SimpleDaemon: IOException in "+
+                    System.err.println("SimpleApplication: IOException in "+
                                        "connection "+
                                        this.getConnectionNumber());
                     return;
diff --git a/src/samples/SimpleApplication.sh b/src/samples/SimpleApplication.sh
new file mode 100755
index 0000000..a6e3bc2
--- /dev/null
+++ b/src/samples/SimpleApplication.sh
@@ -0,0 +1,57 @@
+#!/bin/sh
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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 the sample services.
+#
+# Adapt the following lines to your configuration
+JAVA_HOME=/opt/java6
+PROGRAM=SimpleApplication
+CLASSPATH=`pwd`/$PROGRAM.jar:`pwd`/commons-daemon-1.0.4-dev.jar
+
+case "$1" in
+  start )
+    shift
+    ./jsvc \
+        -home $JAVA_HOME \
+        -cp $CLASSPATH \
+        -nodetach \
+        -errfile "&2" \
+        -pidfile `pwd`/$PROGRAM.pid \
+        @$PROGRAM \
+        -start-method main \
+        $*
+    exit $?
+    ;;
+  stop )
+    shift
+    ./jsvc \
+        -home $JAVA_HOME \
+        -cp $CLASSPATH \
+        -stop \
+        -nodetach \
+        -errfile "&2" \
+        -pidfile `pwd`/$PROGRAM.pid \
+        @$PROGRAM \
+        -start-method main \
+        $*
+    exit $?
+    ;;
+    * )
+    echo 'Usage SimpleApplication.sh start | stop'
+    exit 1
+    ;;
+esac
diff --git a/src/samples/SimpleDaemon.java b/src/samples/SimpleDaemon.java
index 640523b..8c02592 100644
--- a/src/samples/SimpleDaemon.java
+++ b/src/samples/SimpleDaemon.java
@@ -15,7 +15,7 @@
  *  limitations under the License.
  */
 
-/* @version $Id: SimpleDaemon.java 937350 2010-04-23 16:03:39Z sebb $ */
+/* @version $Id: SimpleDaemon.java 1023476 2010-10-17 12:29:08Z mturk $ */
 
 import java.io.File;
 import java.io.FileOutputStream;
@@ -23,7 +23,7 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.PrintStream;
-import java.io.UnsupportedEncodingException;
+//import java.io.UnsupportedEncodingException;
 import java.net.ServerSocket;
 import java.net.Socket;
 import java.text.SimpleDateFormat;
@@ -34,6 +34,7 @@ import java.util.Vector;
 import org.apache.commons.daemon.Daemon;
 import org.apache.commons.daemon.DaemonContext;
 import org.apache.commons.daemon.DaemonController;
+import org.apache.commons.daemon.DaemonInitException;
 
 public class SimpleDaemon implements Daemon, Runnable {
 
@@ -69,8 +70,13 @@ public class SimpleDaemon implements Daemon, Runnable {
         int port=1200;
 
         String[] a = context.getArguments();
-
-        if (a.length>0) port=Integer.parseInt(a[0]);
+        try {
+            if ( a.length > 0)
+                port=Integer.parseInt(a[0]);
+        }
+        catch (NumberFormatException ex) {
+            throw new DaemonInitException("parsing port", ex);
+        }
         if (a.length>1) this.directory=a[1];
         else this.directory="/tmp";
 
@@ -230,11 +236,11 @@ public class SimpleDaemon implements Daemon, Runnable {
 
         public void handle(InputStream in, OutputStream os) {
             PrintStream out=null;
-            try {
-                out=new PrintStream(os, true, "US-ASCII");
-            } catch (UnsupportedEncodingException ex) {
-                out=new PrintStream(os);
-            }
+//            try {
+//                out=new PrintStream(os, true, "US-ASCII"); // Java 1.4+
+//            } catch (UnsupportedEncodingException ex) {
+                out=new PrintStream(os, true);
+//            }
 
             while(true) {
                 try {
diff --git a/src/native/unix/native/Tomcat5.sh b/src/samples/Tomcat5.sh
similarity index 100%
rename from src/native/unix/native/Tomcat5.sh
rename to src/samples/Tomcat5.sh
diff --git a/src/samples/Tomcat7.sh b/src/samples/Tomcat7.sh
new file mode 100755
index 0000000..c6275b8
--- /dev/null
+++ b/src/samples/Tomcat7.sh
@@ -0,0 +1,203 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+#
+# resolve links - $0 may be a softlink
+ARG0="$0"
+while [ -h "$ARG0" ]; do
+  ls=`ls -ld "$ARG0"`
+  link=`expr "$ls" : '.*-> \(.*\)$'`
+  if expr "$link" : '/.*' > /dev/null; then
+    ARG0="$link"
+  else
+    ARG0="`dirname $ARG0`/$link"
+  fi
+done
+DIRNAME="`dirname $ARG0`"
+PROGRAM="`basename $ARG0`"
+for o
+do
+  case "$o" in
+    --java-home )
+        JAVA_HOME="$2"
+        shift; shift;
+        continue
+    ;;
+    --catalina-home )
+        CATALINA_HOME="$2"
+        shift; shift;
+        continue
+    ;;
+    --catalina-base )
+        CATALINA_BASE="$2"
+        shift; shift;
+        continue
+    ;;
+    --catalina-pid )
+        CATALINA_PID="$2"
+        shift; shift;
+        continue
+    ;;
+    --tomcat-user )
+        TOMCAT_USER="$2"
+        shift; shift;
+        continue
+    ;;
+    * )
+        break
+    ;;
+  esac
+done
+
+# Setup parameters for running the jsvc
+#
+test ".$TOMCAT_USER" = . && TOMCAT_USER=tomcat
+# Set JAVA_HOME to working JDK or JRE
+# JAVA_HOME=/opt/jdk-1.6.0.22
+# If not set we'll try to guess the JAVA_HOME
+# from java binary if on the PATH
+#
+if [ -z "$JAVA_HOME" ]; then
+    JAVA_BIN="`which java 2>/dev/null || type java 2>&1`"
+    test -x "$JAVA_BIN" && JAVA_HOME="`dirname $JAVA_BIN`"
+    test ".$JAVA_HOME" != . && JAVA_HOME=`cd "$JAVA_HOME/.." >/dev/null; pwd`
+else
+    JAVA_BIN="$JAVA_HOME/bin/java"
+fi
+
+# Only set CATALINA_HOME if not already set
+test ".$CATALINA_HOME" = . && CATALINA_HOME=`cd "$DIRNAME/.." >/dev/null; pwd`
+test ".$CATALINA_BASE" = . && CATALINA_BASE="$CATALINA_HOME"
+test ".$CATALINA_MAIN" = . && CATALINA_MAIN=org.apache.catalina.startup.Bootstrap
+test ".$JSVC" = . && JSVC="$CATALINA_BASE/bin/jsvc"
+
+# Ensure that any user defined CLASSPATH variables are not used on startup,
+# but allow them to be specified in setenv.sh, in rare case when it is needed.
+CLASSPATH=
+JAVA_OPTS=
+if [ -r "$CATALINA_BASE/bin/setenv.sh" ]; then
+  . "$CATALINA_BASE/bin/setenv.sh"
+elif [ -r "$CATALINA_HOME/bin/setenv.sh" ]; then
+  . "$CATALINA_HOME/bin/setenv.sh"
+fi
+
+# Add on extra jar files to CLASSPATH
+test ".$CLASSPATH" != . && CLASSPATH="${CLASSPATH}:"
+CLASSPATH="$CLASSPATH$CATALINA_HOME/bin/bootstrap.jar:$CATALINA_HOME/bin/commons-daemon.jar"
+
+test ".$CATALINA_OUT" = . && CATALINA_OUT="$CATALINA_BASE/logs/catalina-daemon.out"
+test ".$CATALINA_TMP" = . && CATALINA_TMP="$CATALINA_BASE/temp"
+
+# Add tomcat-juli.jar to classpath
+# tomcat-juli.jar can be over-ridden per instance
+if [ -r "$CATALINA_BASE/bin/tomcat-juli.jar" ] ; then
+  CLASSPATH="$CLASSPATH:$CATALINA_BASE/bin/tomcat-juli.jar"
+else
+  CLASSPATH="$CLASSPATH:$CATALINA_HOME/bin/tomcat-juli.jar"
+fi
+# Set juli LogManager config file if it is present and an override has not been issued
+if [ -z "$LOGGING_CONFIG" ]; then
+  if [ -r "$CATALINA_BASE/conf/logging.properties" ]; then
+    LOGGING_CONFIG="-Djava.util.logging.config.file=$CATALINA_BASE/conf/logging.properties"
+  else
+    # Bugzilla 45585
+    LOGGING_CONFIG="-Dnop"
+  fi
+fi
+
+test ".$LOGGING_MANAGER" = . && LOGGING_MANAGER="-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager"
+JAVA_OPTS="$JAVA_OPTS $LOGGING_MANAGER"
+
+# Set -pidfile
+test ".$CATALINA_PID" = . && CATALINA_PID="$CATALINA_BASE/logs/catalina-daemon.pid"
+
+# ----- Execute The Requested Command -----------------------------------------
+case "$1" in
+    run     )
+      shift
+      "$JSVC" $* \
+      -java-home "$JAVA_HOME" \
+      -pidfile "$CATALINA_PID" \
+      -wait 10 \
+      -nodetach \
+      -outfile "&1" \
+      -errfile "&2" \
+      -classpath "$CLASSPATH" \
+      "$LOGGING_CONFIG" $JAVA_OPTS $CATALINA_OPTS \
+      -Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" \
+      -Dcatalina.base="$CATALINA_BASE" \
+      -Dcatalina.home="$CATALINA_HOME" \
+      -Djava.io.tmpdir="$CATALINA_TMP" \
+      $CATALINA_MAIN
+      exit $?
+    ;;
+    start   )
+      "$JSVC" \
+      -java-home "$JAVA_HOME" \
+      -user $TOMCAT_USER \
+      -pidfile "$CATALINA_PID" \
+      -wait 10 \
+      -outfile "$CATALINA_OUT" \
+      -errfile "&1" \
+      -classpath "$CLASSPATH" \
+      "$LOGGING_CONFIG" $JAVA_OPTS $CATALINA_OPTS \
+      -Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" \
+      -Dcatalina.base="$CATALINA_BASE" \
+      -Dcatalina.home="$CATALINA_HOME" \
+      -Djava.io.tmpdir="$CATALINA_TMP" \
+      $CATALINA_MAIN
+      exit $?
+    ;;
+    stop    )
+      "$JSVC" \
+      -stop \
+      -pidfile "$CATALINA_PID" \
+      -classpath "$CLASSPATH" \
+      -Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" \
+      -Dcatalina.base="$CATALINA_BASE" \
+      -Dcatalina.home="$CATALINA_HOME" \
+      -Djava.io.tmpdir="$CATALINA_TMP" \
+      $CATALINA_MAIN
+      exit $?
+    ;;
+    version  )
+      "$JSVC" \
+      -java-home "$JAVA_HOME" \
+      -pidfile "$CATALINA_PID" \
+      -classpath "$CLASSPATH" \
+      -errfile "&2" \
+      -version \
+      -check \
+      $CATALINA_MAIN
+      if [ "$?" = 0 ]; then
+        "$JAVA_BIN" \
+        -classpath "$CATALINA_HOME/lib/catalina.jar" \
+        org.apache.catalina.util.ServerInfo
+      fi
+      exit $?
+    ;;
+    *       )
+      echo "Unkown command: \`$1'"
+      echo "Usage: $PROGRAM ( commands ... )"
+      echo "commands:"
+      echo "  run               Start Catalina without detaching from console"
+      echo "  start             Start Catalina"
+      echo "  stop              Stop Catalina"
+      echo "  version           What version of commons daemon and Tomcat"
+      echo "                    are you running?"
+      exit 1
+    ;;
+esac
diff --git a/src/samples/build.xml b/src/samples/build.xml
index ab2b646..70904d1 100644
--- a/src/samples/build.xml
+++ b/src/samples/build.xml
@@ -23,10 +23,7 @@
   <property name="build.home"  value="./build"/>
   <property name="source.home" value="."/>
 
-  <property name="maven.repo.local" value="${user.home}/.m2/repository"/>
-  <property name="commons-collections.jar" value="${maven.repo.local}/commons-collections/commons-collections/3.1/commons-collections-3.1.jar"/>
-
-  <target name="jars" depends="SimpleDaemon,ServiceDaemon,AloneService,ProcrunService"/>
+  <target name="jars" depends="SimpleDaemon,SimpleApplication,ServiceDaemon,AloneService,ProcrunService"/>
 
   <target name="clean" description="Remove output files">
     <delete quiet="true">
@@ -34,7 +31,7 @@
       <fileset dir="${dist.home}" includes="SimpleDaemon.jar service.jar aloneservice.jar ProcrunService.jar"/>
     </delete>
   </target>
-  
+
   <target name="SimpleDaemon" depends="compile"
    description="Create SimpleDaemon.jar">
     <mkdir      dir="${dist.home}"/>
@@ -49,6 +46,20 @@
     </jar>
   </target>
 
+  <target name="SimpleApplication" depends="compile"
+          description="Create SimpleApplication.jar">
+      <mkdir      dir="${dist.home}"/>
+      <jar    jarfile="${dist.home}/SimpleApplication.jar">
+          <metainf dir="../..">
+              <include name="NOTICE.txt"/>
+              <include name="LICENSE.txt"/>
+          </metainf>
+          <fileset dir="${build.home}/classes">
+              <include name="SimpleApplication*.class" />
+          </fileset>
+      </jar>
+  </target>
+
   <target name="ServiceDaemon" depends="compile"
    description="Create ServiceDaemon.jar">
     <mkdir      dir="${dist.home}"/>
@@ -117,7 +128,6 @@
   <path id="compile.classpath">
     <!-- output jar filename may vary between releases -->
     <fileset dir="../../dist" includes="commons-daemon-*.jar"/>
-    <pathelement location="${commons-collections.jar}"/>
   </path>
 
 </project>
diff --git a/src/samples/build/classes/AloneService.class b/src/samples/build/classes/AloneService.class
new file mode 100644
index 0000000..c59c503
Binary files /dev/null and b/src/samples/build/classes/AloneService.class differ
diff --git a/src/samples/build/classes/ProcrunService.class b/src/samples/build/classes/ProcrunService.class
new file mode 100644
index 0000000..5438d2e
Binary files /dev/null and b/src/samples/build/classes/ProcrunService.class differ
diff --git a/src/samples/build/classes/ServiceDaemon.class b/src/samples/build/classes/ServiceDaemon.class
new file mode 100644
index 0000000..cfc4b02
Binary files /dev/null and b/src/samples/build/classes/ServiceDaemon.class differ
diff --git a/src/samples/build/classes/ServiceDaemonReadThread.class b/src/samples/build/classes/ServiceDaemonReadThread.class
new file mode 100644
index 0000000..a2b5c7e
Binary files /dev/null and b/src/samples/build/classes/ServiceDaemonReadThread.class differ
diff --git a/src/samples/build/classes/SimpleApplication$Handler.class b/src/samples/build/classes/SimpleApplication$Handler.class
new file mode 100644
index 0000000..62de685
Binary files /dev/null and b/src/samples/build/classes/SimpleApplication$Handler.class differ
diff --git a/src/samples/build/classes/SimpleApplication$ShutdownHook.class b/src/samples/build/classes/SimpleApplication$ShutdownHook.class
new file mode 100644
index 0000000..405f265
Binary files /dev/null and b/src/samples/build/classes/SimpleApplication$ShutdownHook.class differ
diff --git a/src/samples/build/classes/SimpleApplication.class b/src/samples/build/classes/SimpleApplication.class
new file mode 100644
index 0000000..e18eb66
Binary files /dev/null and b/src/samples/build/classes/SimpleApplication.class differ
diff --git a/src/samples/build/classes/SimpleDaemon$Handler.class b/src/samples/build/classes/SimpleDaemon$Handler.class
new file mode 100644
index 0000000..d7202a4
Binary files /dev/null and b/src/samples/build/classes/SimpleDaemon$Handler.class differ
diff --git a/src/samples/build/classes/SimpleDaemon.class b/src/samples/build/classes/SimpleDaemon.class
new file mode 100644
index 0000000..5034497
Binary files /dev/null and b/src/samples/build/classes/SimpleDaemon.class differ

-- 
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