From accfaa1c0915810fc63008e313df3a968f21a210 Mon Sep 17 00:00:00 2001
From: neil_a_wilson <neil_a_wilson@localhost>
Date: Wed, 25 Oct 2006 18:55:52 +0000
Subject: [PATCH] Make several changes to administrative shell scripts provided with OpenDS. All of these changes fall under the blanket of issue 882, but are also associated with a number of individual sub-issues.

---
 opendj-sdk/opends/resource/bin/ldappasswordmodify.sh                        |   49 -
 opendj-sdk/opends/resource/bin/backup.sh                                    |   51 -
 opendj-sdk/opends/resource/bin/ldapmodify.sh                                |   50 -
 opendj-sdk/opends/resource/bin/export-ldif.sh                               |   51 -
 opendj-sdk/opends/resource/bin/stop-ds.sh                                   |   78 +
 opendj-sdk/opends/src/server/org/opends/server/util/MultiOutputStream.java  |  195 ++++++
 opendj-sdk/opends/src/server/org/opends/server/messages/CoreMessages.java   |   12 
 opendj-sdk/opends/resource/bin/verify-index.sh                              |   51 -
 opendj-sdk/opends/resource/bin/ldifsearch.sh                                |   49 -
 opendj-sdk/opends/src/server/org/opends/server/core/DirectoryServer.java    |   92 ++
 opendj-sdk/opends/resource/bin/import-ldif.sh                               |   50 -
 opendj-sdk/opends/resource/bin/configure-ds.sh                              |   51 -
 opendj-sdk/opends/resource/bin/ldif-diff.sh                                 |   49 -
 opendj-sdk/opends/resource/bin/ldapcompare.sh                               |   49 -
 opendj-sdk/opends/resource/bin/start-ds.sh                                  |   82 +
 opendj-sdk/opends/src/server/org/opends/server/tools/WaitForFileDelete.java |  301 +++++++++
 opendj-sdk/opends/resource/bin/_server-script.sh                            |   99 +++
 opendj-sdk/opends/resource/bin/restore.sh                                   |   50 -
 opendj-sdk/opends/resource/bin/encode-password.sh                           |   51 -
 opendj-sdk/opends/resource/bin/ldifmodify.sh                                |   50 -
 opendj-sdk/opends/resource/bin/_client-script.sh                            |   97 +++
 opendj-sdk/opends/resource/bin/ldapdelete.sh                                |   49 -
 opendj-sdk/opends/resource/bin/ldapsearch.sh                                |   49 -
 opendj-sdk/opends/resource/bin/makeldif.sh                                  |   52 -
 opendj-sdk/opends/resource/setup.sh                                         |   64 +
 opendj-sdk/opends/src/server/org/opends/server/messages/ToolMessages.java   |   87 ++
 26 files changed, 1,127 insertions(+), 781 deletions(-)

diff --git a/opendj-sdk/opends/resource/bin/_client-script.sh b/opendj-sdk/opends/resource/bin/_client-script.sh
new file mode 100755
index 0000000..9f92e2a
--- /dev/null
+++ b/opendj-sdk/opends/resource/bin/_client-script.sh
@@ -0,0 +1,97 @@
+#!/bin/sh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License").  You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at
+# trunk/opends/resource/legal-notices/OpenDS.LICENSE
+# or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at
+# trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+# add the following below this CDDL HEADER, with the fields enclosed
+# by brackets "[]" replaced with your own identifying * information:
+#      Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+#      Portions Copyright 2006 Sun Microsystems, Inc.
+
+
+# This script is used to invoke various client-side processes.  It should not
+# be invoked directly by end users.
+if test -z "${OPENDS_INVOKE_CLASS}"
+then
+  echo "ERROR:  OPENDS_INVOKE_CLASS environment variable is not set."
+  exit 1
+fi
+
+
+# See if JAVA_HOME is set.  If not, then see if there is a java executable in
+# the path and try to figure it out.
+if test -z "${JAVA_BIN}"
+then
+  if test -z "${JAVA_HOME}"
+  then
+    JAVA_BIN=`which java 2> /dev/null`
+    if test ${?} -eq 0
+    then
+      export JAVA_BIN
+    else
+      echo "Please set JAVA_HOME to the root of a Java 5.0 installation."
+      exit 1
+    fi
+  else
+    JAVA_BIN=${JAVA_HOME}/bin/java
+    export JAVA_BIN
+  fi
+fi
+
+
+# Explicitly set the PATH, LD_LIBRARY_PATH, LD_PRELOAD, and other important
+# system environment variables for security and compatibility reasons.
+PATH=/bin:/usr/bin
+LD_LIBRARY_PATH=
+LD_LIBRARY_PATH_32=
+LD_LIBRARY_PATH_64=
+LD_PRELOAD=
+LD_PRELOAD_32=
+LD_PRELOAD_64=
+export PATH LD_LIBRARY_PATH LD_LIBRARY_PATH_32 LD_LIBRARY_PATH_64 \
+       LD_PRELOAD LD_PRELOAD_32 LD_PRELOAD_34
+
+
+# Capture the current working directory so that we can change to it later.
+# Then capture the location of this script and the Directory Server instance
+# root so that we can use them to create appropriate paths.
+WORKING_DIR=`pwd`
+
+cd `dirname "${0}"`
+SCRIPT_DIR=`pwd`
+
+cd ..
+INSTANCE_ROOT=`pwd`
+export INSTANCE_ROOT
+
+cd "${WORKING_DIR}"
+
+
+# Configure the appropriate CLASSPATH.
+CLASSPATH=${INSTANCE_ROOT}/classes
+for JAR in ${INSTANCE_ROOT}/lib/*.jar
+do
+  CLASSPATH=${CLASSPATH}:${JAR}
+done
+export CLASSPATH
+
+
+# Launch the appropriate server utility.
+"${JAVA_BIN}" ${JAVA_ARGS} "${OPENDS_INVOKE_CLASS}" "${@}"
diff --git a/opendj-sdk/opends/resource/bin/_server-script.sh b/opendj-sdk/opends/resource/bin/_server-script.sh
new file mode 100755
index 0000000..0915084
--- /dev/null
+++ b/opendj-sdk/opends/resource/bin/_server-script.sh
@@ -0,0 +1,99 @@
+#!/bin/sh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License").  You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at
+# trunk/opends/resource/legal-notices/OpenDS.LICENSE
+# or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at
+# trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+# add the following below this CDDL HEADER, with the fields enclosed
+# by brackets "[]" replaced with your own identifying * information:
+#      Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+#      Portions Copyright 2006 Sun Microsystems, Inc.
+
+
+# This script is used to invoke various server-side processes.  It should not
+# be invoked directly by end users.
+if test -z "${OPENDS_INVOKE_CLASS}"
+then
+  echo "ERROR:  OPENDS_INVOKE_CLASS environment variable is not set."
+  exit 1
+fi
+
+
+# See if JAVA_HOME is set.  If not, then see if there is a java executable in
+# the path and try to figure it out.
+if test -z "${JAVA_BIN}"
+then
+  if test -z "${JAVA_HOME}"
+  then
+    JAVA_BIN=`which java 2> /dev/null`
+    if test ${?} -eq 0
+    then
+      export JAVA_BIN
+    else
+      echo "Please set JAVA_HOME to the root of a Java 5.0 installation."
+      exit 1
+    fi
+  else
+    JAVA_BIN=${JAVA_HOME}/bin/java
+    export JAVA_BIN
+  fi
+fi
+
+
+# Explicitly set the PATH, LD_LIBRARY_PATH, LD_PRELOAD, and other important
+# system environment variables for security and compatibility reasons.
+PATH=/bin:/usr/bin
+LD_LIBRARY_PATH=
+LD_LIBRARY_PATH_32=
+LD_LIBRARY_PATH_64=
+LD_PRELOAD=
+LD_PRELOAD_32=
+LD_PRELOAD_64=
+export PATH LD_LIBRARY_PATH LD_LIBRARY_PATH_32 LD_LIBRARY_PATH_64 \
+       LD_PRELOAD LD_PRELOAD_32 LD_PRELOAD_34
+
+
+# Capture the current working directory so that we can change to it later.
+# Then capture the location of this script and the Directory Server instance
+# root so that we can use them to create appropriate paths.
+WORKING_DIR=`pwd`
+
+cd `dirname "${0}"`
+SCRIPT_DIR=`pwd`
+
+cd ..
+INSTANCE_ROOT=`pwd`
+export INSTANCE_ROOT
+
+cd "${WORKING_DIR}"
+
+
+# Configure the appropriate CLASSPATH.
+CLASSPATH=${INSTANCE_ROOT}/classes
+for JAR in ${INSTANCE_ROOT}/lib/*.jar
+do
+  CLASSPATH=${CLASSPATH}:${JAR}
+done
+export CLASSPATH
+
+
+# Launch the appropriate server utility.
+"${JAVA_BIN}" ${JAVA_ARGS} "${OPENDS_INVOKE_CLASS}" \
+     --configClass org.opends.server.extensions.ConfigFileHandler \
+     --configFile "${INSTANCE_ROOT}/config/config.ldif" "${@}"
diff --git a/opendj-sdk/opends/resource/bin/backup.sh b/opendj-sdk/opends/resource/bin/backup.sh
index 8625e4d..a80260b 100755
--- a/opendj-sdk/opends/resource/bin/backup.sh
+++ b/opendj-sdk/opends/resource/bin/backup.sh
@@ -26,49 +26,10 @@
 #      Portions Copyright 2006 Sun Microsystems, Inc.
 
 
-# Capture the current working directory so that we can change to it later.
-# Then apture the location of this script and the Directory Server instance
-# root so that we can use them to create appropriate paths.
-WORKING_DIR=`pwd`
+# This script may be used to perform a backup of one or more Directory Server
+# backends.
+OPENDS_INVOKE_CLASS="org.opends.server.tools.BackUpDB"
+export OPENDS_INVOKE_CLASS
 
-cd `dirname $0`
-SCRIPT_DIR=`pwd`
-
-cd ..
-INSTANCE_ROOT=`pwd`
-export INSTANCE_ROOT
-
-cd ${WORKING_DIR}
-
-
-# See if JAVA_HOME is set.  If not, then see if there is a java executable in
-# the path and try to figure it out.
-if test -z "${JAVA_BIN}"
-then
-  if test -z "${JAVA_HOME}"
-  then
-    JAVA_BIN=`which java 2> /dev/null`
-    if test $? -eq 0
-    then
-      export JAVA_BIN
-    else
-      echo "Please set JAVA_HOME to the root of a Java 5.0 installation."
-      exit 1
-    fi
-  else
-    JAVA_BIN=${JAVA_HOME}/bin/java
-    export JAVA_BIN
-  fi
-fi
-
-CLASSPATH=${INSTANCE_ROOT}/classes
-for JAR in ${INSTANCE_ROOT}/lib/*.jar
-do
-    CLASSPATH=${CLASSPATH}:${JAR}
-done
-export CLASSPATH
-
-
-${JAVA_BIN} ${JAVA_ARGS} org.opends.server.tools.BackUpDB \
-     --configClass org.opends.server.extensions.ConfigFileHandler \
-     --configFile ${INSTANCE_ROOT}/config/config.ldif "${@}"
+SCRIPT_DIR=`dirname "${0}"`
+"${SCRIPT_DIR}/_server-script.sh" "${@}"
diff --git a/opendj-sdk/opends/resource/bin/configure-ds.sh b/opendj-sdk/opends/resource/bin/configure-ds.sh
index 2cde0d8..23553d5 100755
--- a/opendj-sdk/opends/resource/bin/configure-ds.sh
+++ b/opendj-sdk/opends/resource/bin/configure-ds.sh
@@ -26,49 +26,10 @@
 #      Portions Copyright 2006 Sun Microsystems, Inc.
 
 
-# Capture the current working directory so that we can change to it later.
-# Then apture the location of this script and the Directory Server instance
-# root so that we can use them to create appropriate paths.
-WORKING_DIR=`pwd`
+# This script may be used to configure an existing Directory Server
+# installation.
+OPENDS_INVOKE_CLASS="org.opends.server.tools.ConfigureDS"
+export OPENDS_INVOKE_CLASS
 
-cd `dirname $0`
-SCRIPT_DIR=`pwd`
-
-cd ..
-INSTANCE_ROOT=`pwd`
-export INSTANCE_ROOT
-
-cd ${WORKING_DIR}
-
-
-# See if JAVA_HOME is set.  If not, then see if there is a java executable in
-# the path and try to figure it out.
-if test -z "${JAVA_BIN}"
-then
-  if test -z "${JAVA_HOME}"
-  then
-    JAVA_BIN=`which java 2> /dev/null`
-    if test $? -eq 0
-    then
-      export JAVA_BIN
-    else
-      echo "Please set JAVA_HOME to the root of a Java 5.0 installation."
-      exit 1
-    fi
-  else
-    JAVA_BIN=${JAVA_HOME}/bin/java
-    export JAVA_BIN
-  fi
-fi
-
-CLASSPATH=${INSTANCE_ROOT}/classes
-for JAR in ${INSTANCE_ROOT}/lib/*.jar
-do
-    CLASSPATH=${CLASSPATH}:${JAR}
-done
-export CLASSPATH
-
-
-${JAVA_BIN} ${JAVA_ARGS} org.opends.server.tools.ConfigureDS \
-     --configClass org.opends.server.extensions.ConfigFileHandler \
-     --configFile ${INSTANCE_ROOT}/config/config.ldif "${@}"
+SCRIPT_DIR=`dirname "${0}"`
+"${SCRIPT_DIR}/_server-script.sh" "${@}"
diff --git a/opendj-sdk/opends/resource/bin/encode-password.sh b/opendj-sdk/opends/resource/bin/encode-password.sh
index 8a2b24a..0dd53d3 100755
--- a/opendj-sdk/opends/resource/bin/encode-password.sh
+++ b/opendj-sdk/opends/resource/bin/encode-password.sh
@@ -26,49 +26,10 @@
 #      Portions Copyright 2006 Sun Microsystems, Inc.
 
 
-# Capture the current working directory so that we can change to it later.
-# Then apture the location of this script and the Directory Server instance
-# root so that we can use them to create appropriate paths.
-WORKING_DIR=`pwd`
+# This script may be used to encode clear-text passwords or verify whether a
+# given clear-text password matches a provided encoded password.
+OPENDS_INVOKE_CLASS="org.opends.server.tools.EncodePassword"
+export OPENDS_INVOKE_CLASS
 
-cd `dirname $0`
-SCRIPT_DIR=`pwd`
-
-cd ..
-INSTANCE_ROOT=`pwd`
-export INSTANCE_ROOT
-
-cd ${WORKING_DIR}
-
-
-# See if JAVA_HOME is set.  If not, then see if there is a java executable in
-# the path and try to figure it out.
-if test -z "${JAVA_BIN}"
-then
-  if test -z "${JAVA_HOME}"
-  then
-    JAVA_BIN=`which java 2> /dev/null`
-    if test $? -eq 0
-    then
-      export JAVA_BIN
-    else
-      echo "Please set JAVA_HOME to the root of a Java 5.0 installation."
-      exit 1
-    fi
-  else
-    JAVA_BIN=${JAVA_HOME}/bin/java
-    export JAVA_BIN
-  fi
-fi
-
-CLASSPATH=${INSTANCE_ROOT}/classes
-for JAR in ${INSTANCE_ROOT}/lib/*.jar
-do
-    CLASSPATH=${CLASSPATH}:${JAR}
-done
-export CLASSPATH
-
-
-${JAVA_BIN} ${JAVA_ARGS} org.opends.server.tools.EncodePassword \
-     --configClass org.opends.server.extensions.ConfigFileHandler \
-     --configFile ${INSTANCE_ROOT}/config/config.ldif "${@}"
+SCRIPT_DIR=`dirname "${0}"`
+"${SCRIPT_DIR}/_server-script.sh" "${@}"
diff --git a/opendj-sdk/opends/resource/bin/export-ldif.sh b/opendj-sdk/opends/resource/bin/export-ldif.sh
index 8d83ddc..bf5fb5d 100755
--- a/opendj-sdk/opends/resource/bin/export-ldif.sh
+++ b/opendj-sdk/opends/resource/bin/export-ldif.sh
@@ -26,49 +26,10 @@
 #      Portions Copyright 2006 Sun Microsystems, Inc.
 
 
-# Capture the current working directory so that we can change to it later.
-# Then apture the location of this script and the Directory Server instance
-# root so that we can use them to create appropriate paths.
-WORKING_DIR=`pwd`
+# This script may be used to perform an LDIF export for a Directory Server
+# backend.
+OPENDS_INVOKE_CLASS="org.opends.server.tools.ExportLDIF"
+export OPENDS_INVOKE_CLASS
 
-cd `dirname $0`
-SCRIPT_DIR=`pwd`
-
-cd ..
-INSTANCE_ROOT=`pwd`
-export INSTANCE_ROOT
-
-cd ${WORKING_DIR}
-
-
-# See if JAVA_HOME is set.  If not, then see if there is a java executable in
-# the path and try to figure it out.
-if test -z "${JAVA_BIN}"
-then
-  if test -z "${JAVA_HOME}"
-  then
-    JAVA_BIN=`which java 2> /dev/null`
-    if test $? -eq 0
-    then
-      export JAVA_BIN
-    else
-      echo "Please set JAVA_HOME to the root of a Java 5.0 installation."
-      exit 1
-    fi
-  else
-    JAVA_BIN=${JAVA_HOME}/bin/java
-    export JAVA_BIN
-  fi
-fi
-
-CLASSPATH=${INSTANCE_ROOT}/classes
-for JAR in ${INSTANCE_ROOT}/lib/*.jar
-do
-    CLASSPATH=${CLASSPATH}:${JAR}
-done
-export CLASSPATH
-
-
-${JAVA_BIN} ${JAVA_ARGS} org.opends.server.tools.ExportLDIF \
-     --configClass org.opends.server.extensions.ConfigFileHandler \
-     --configFile ${INSTANCE_ROOT}/config/config.ldif "${@}"
+SCRIPT_DIR=`dirname "${0}"`
+"${SCRIPT_DIR}/_server-script.sh" "${@}"
diff --git a/opendj-sdk/opends/resource/bin/import-ldif.sh b/opendj-sdk/opends/resource/bin/import-ldif.sh
index ea31d43..e077470 100755
--- a/opendj-sdk/opends/resource/bin/import-ldif.sh
+++ b/opendj-sdk/opends/resource/bin/import-ldif.sh
@@ -26,49 +26,9 @@
 #      Portions Copyright 2006 Sun Microsystems, Inc.
 
 
-# Capture the current working directory so that we can change to it later.
-# Then apture the location of this script and the Directory Server instance
-# root so that we can use them to create appropriate paths.
-WORKING_DIR=`pwd`
+# This script may be used to import LDIF data into a Directory Server backend.
+OPENDS_INVOKE_CLASS="org.opends.server.tools.ImportLDIF"
+export OPENDS_INVOKE_CLASS
 
-cd `dirname $0`
-SCRIPT_DIR=`pwd`
-
-cd ..
-INSTANCE_ROOT=`pwd`
-export INSTANCE_ROOT
-
-cd ${WORKING_DIR}
-
-
-# See if JAVA_HOME is set.  If not, then see if there is a java executable in
-# the path and try to figure it out.
-if test -z "${JAVA_BIN}"
-then
-  if test -z "${JAVA_HOME}"
-  then
-    JAVA_BIN=`which java 2> /dev/null`
-    if test $? -eq 0
-    then
-      export JAVA_BIN
-    else
-      echo "Please set JAVA_HOME to the root of a Java 5.0 installation."
-      exit 1
-    fi
-  else
-    JAVA_BIN=${JAVA_HOME}/bin/java
-    export JAVA_BIN
-  fi
-fi
-
-CLASSPATH=${INSTANCE_ROOT}/classes
-for JAR in ${INSTANCE_ROOT}/lib/*.jar
-do
-    CLASSPATH=${CLASSPATH}:${JAR}
-done
-export CLASSPATH
-
-
-${JAVA_BIN} ${JAVA_ARGS} org.opends.server.tools.ImportLDIF \
-     --configClass org.opends.server.extensions.ConfigFileHandler \
-     --configFile ${INSTANCE_ROOT}/config/config.ldif "${@}"
+SCRIPT_DIR=`dirname "${0}"`
+"${SCRIPT_DIR}/_server-script.sh" "${@}"
diff --git a/opendj-sdk/opends/resource/bin/ldapcompare.sh b/opendj-sdk/opends/resource/bin/ldapcompare.sh
index a1ae0a0..1c6c6c5 100755
--- a/opendj-sdk/opends/resource/bin/ldapcompare.sh
+++ b/opendj-sdk/opends/resource/bin/ldapcompare.sh
@@ -26,48 +26,9 @@
 #      Portions Copyright 2006 Sun Microsystems, Inc.
 
 
-# Capture the current working directory so that we can change to it later.
-# Then capture the location of this script and the Directory Server instance
-# root so that we can use them to create appropriate paths.
-WORKING_DIR=`pwd`
+# This script may be used to perform LDAP compare operations.
+OPENDS_INVOKE_CLASS="org.opends.server.tools.LDAPCompare"
+export OPENDS_INVOKE_CLASS
 
-cd `dirname $0`
-SCRIPT_DIR=`pwd`
-
-cd ..
-INSTANCE_ROOT=`pwd`
-export INSTANCE_ROOT
-
-cd ${WORKING_DIR}
-
-
-# See if JAVA_HOME is set.  If not, then see if there is a java executable in
-# the path and try to figure it out.
-if test -z "${JAVA_BIN}"
-then
-  if test -z "${JAVA_HOME}"
-  then
-    JAVA_BIN=`which java 2> /dev/null`
-    if test $? -eq 0
-    then
-      export JAVA_BIN
-    else
-      echo "Please set JAVA_HOME to the root of a Java 5.0 installation."
-      exit 1
-    fi
-  else
-    JAVA_BIN=${JAVA_HOME}/bin/java
-    export JAVA_BIN
-  fi
-fi
-
-CLASSPATH=${INSTANCE_ROOT}/classes
-for JAR in ${INSTANCE_ROOT}/lib/*.jar
-do
-  CLASSPATH=${CLASSPATH}:${JAR}
-done
-export CLASSPATH
-
-
-${JAVA_BIN} ${JAVA_ARGS} org.opends.server.tools.LDAPCompare "$@" 
-
+SCRIPT_DIR=`dirname "${0}"`
+"${SCRIPT_DIR}/_client-script.sh" "${@}"
diff --git a/opendj-sdk/opends/resource/bin/ldapdelete.sh b/opendj-sdk/opends/resource/bin/ldapdelete.sh
index a0d1ac7..c106488 100755
--- a/opendj-sdk/opends/resource/bin/ldapdelete.sh
+++ b/opendj-sdk/opends/resource/bin/ldapdelete.sh
@@ -26,48 +26,9 @@
 #      Portions Copyright 2006 Sun Microsystems, Inc.
 
 
-# Capture the current working directory so that we can change to it later.
-# Then capture the location of this script and the Directory Server instance
-# root so that we can use them to create appropriate paths.
-WORKING_DIR=`pwd`
+# This script may be used to perform LDAP delete operations.
+OPENDS_INVOKE_CLASS="org.opends.server.tools.LDAPDelete"
+export OPENDS_INVOKE_CLASS
 
-cd `dirname $0`
-SCRIPT_DIR=`pwd`
-
-cd ..
-INSTANCE_ROOT=`pwd`
-export INSTANCE_ROOT
-
-cd ${WORKING_DIR}
-
-
-# See if JAVA_HOME is set.  If not, then see if there is a java executable in
-# the path and try to figure it out.
-if test -z "${JAVA_BIN}"
-then
-  if test -z "${JAVA_HOME}"
-  then
-    JAVA_BIN=`which java 2> /dev/null`
-    if test $? -eq 0
-    then
-      export JAVA_BIN
-    else
-      echo "Please set JAVA_HOME to the root of a Java 5.0 installation."
-      exit 1
-    fi
-  else
-    JAVA_BIN=${JAVA_HOME}/bin/java
-    export JAVA_BIN
-  fi
-fi
-
-CLASSPATH=${INSTANCE_ROOT}/classes
-for JAR in ${INSTANCE_ROOT}/lib/*.jar
-do
-  CLASSPATH=${CLASSPATH}:${JAR}
-done
-export CLASSPATH
-
-
-${JAVA_BIN} ${JAVA_ARGS} org.opends.server.tools.LDAPDelete "$@" 
-
+SCRIPT_DIR=`dirname "${0}"`
+"${SCRIPT_DIR}/_client-script.sh" "${@}"
diff --git a/opendj-sdk/opends/resource/bin/ldapmodify.sh b/opendj-sdk/opends/resource/bin/ldapmodify.sh
index 7399653..a281e3b 100755
--- a/opendj-sdk/opends/resource/bin/ldapmodify.sh
+++ b/opendj-sdk/opends/resource/bin/ldapmodify.sh
@@ -26,48 +26,10 @@
 #      Portions Copyright 2006 Sun Microsystems, Inc.
 
 
-# Capture the current working directory so that we can change to it later.
-# Then capture the location of this script and the Directory Server instance
-# root so that we can use them to create appropriate paths.
-WORKING_DIR=`pwd`
+# This script may be used to perform LDAP add, delete, modify, and modify DN
+# operations.
+OPENDS_INVOKE_CLASS="org.opends.server.tools.LDAPModify"
+export OPENDS_INVOKE_CLASS
 
-cd `dirname $0`
-SCRIPT_DIR=`pwd`
-
-cd ..
-INSTANCE_ROOT=`pwd`
-export INSTANCE_ROOT
-
-cd ${WORKING_DIR}
-
-
-# See if JAVA_HOME is set.  If not, then see if there is a java executable in
-# the path and try to figure it out.
-if test -z "${JAVA_BIN}"
-then
-  if test -z "${JAVA_HOME}"
-  then
-    JAVA_BIN=`which java 2> /dev/null`
-    if test $? -eq 0
-    then
-      export JAVA_BIN
-    else
-      echo "Please set JAVA_HOME to the root of a Java 5.0 installation."
-      exit 1
-    fi
-  else
-    JAVA_BIN=${JAVA_HOME}/bin/java
-    export JAVA_BIN
-  fi
-fi
-
-CLASSPATH=${INSTANCE_ROOT}/classes
-for JAR in ${INSTANCE_ROOT}/lib/*.jar
-do
-  CLASSPATH=${CLASSPATH}:${JAR}
-done
-export CLASSPATH
-
-
-${JAVA_BIN} ${JAVA_ARGS} org.opends.server.tools.LDAPModify "$@" 
-
+SCRIPT_DIR=`dirname "${0}"`
+"${SCRIPT_DIR}/_client-script.sh" "${@}"
diff --git a/opendj-sdk/opends/resource/bin/ldappasswordmodify.sh b/opendj-sdk/opends/resource/bin/ldappasswordmodify.sh
index 874bb7d..be7e42f 100755
--- a/opendj-sdk/opends/resource/bin/ldappasswordmodify.sh
+++ b/opendj-sdk/opends/resource/bin/ldappasswordmodify.sh
@@ -26,48 +26,9 @@
 #      Portions Copyright 2006 Sun Microsystems, Inc.
 
 
-# Capture the current working directory so that we can change to it later.
-# Then capture the location of this script and the Directory Server instance
-# root so that we can use them to create appropriate paths.
-WORKING_DIR=`pwd`
+# This script may be used to perform LDAP password modify operations.
+OPENDS_INVOKE_CLASS="org.opends.server.tools.LDAPPasswordModify"
+export OPENDS_INVOKE_CLASS
 
-cd `dirname $0`
-SCRIPT_DIR=`pwd`
-
-cd ..
-INSTANCE_ROOT=`pwd`
-export INSTANCE_ROOT
-
-cd ${WORKING_DIR}
-
-
-# See if JAVA_HOME is set.  If not, then see if there is a java executable in
-# the path and try to figure it out.
-if test -z "${JAVA_BIN}"
-then
-  if test -z "${JAVA_HOME}"
-  then
-    JAVA_BIN=`which java 2> /dev/null`
-    if test $? -eq 0
-    then
-      export JAVA_BIN
-    else
-      echo "Please set JAVA_HOME to the root of a Java 5.0 installation."
-      exit 1
-    fi
-  else
-    JAVA_BIN=${JAVA_HOME}/bin/java
-    export JAVA_BIN
-  fi
-fi
-
-CLASSPATH=${INSTANCE_ROOT}/classes
-for JAR in ${INSTANCE_ROOT}/lib/*.jar
-do
-  CLASSPATH=${CLASSPATH}:${JAR}
-done
-export CLASSPATH
-
-
-${JAVA_BIN} ${JAVA_ARGS} org.opends.server.tools.LDAPPasswordModify "$@" 
-
+SCRIPT_DIR=`dirname "${0}"`
+"${SCRIPT_DIR}/_client-script.sh" "${@}"
diff --git a/opendj-sdk/opends/resource/bin/ldapsearch.sh b/opendj-sdk/opends/resource/bin/ldapsearch.sh
index 4f88f16..cbec1d0 100755
--- a/opendj-sdk/opends/resource/bin/ldapsearch.sh
+++ b/opendj-sdk/opends/resource/bin/ldapsearch.sh
@@ -26,48 +26,9 @@
 #      Portions Copyright 2006 Sun Microsystems, Inc.
 
 
-# Capture the current working directory so that we can change to it later.
-# Then capture the location of this script and the Directory Server instance
-# root so that we can use them to create appropriate paths.
-WORKING_DIR=`pwd`
+# This script may be used to perform LDAP search operations.
+OPENDS_INVOKE_CLASS="org.opends.server.tools.LDAPSearch"
+export OPENDS_INVOKE_CLASS
 
-cd `dirname $0`
-SCRIPT_DIR=`pwd`
-
-cd ..
-INSTANCE_ROOT=`pwd`
-export INSTANCE_ROOT
-
-cd ${WORKING_DIR}
-
-
-# See if JAVA_HOME is set.  If not, then see if there is a java executable in
-# the path and try to figure it out.
-if test -z "${JAVA_BIN}"
-then
-  if test -z "${JAVA_HOME}"
-  then
-    JAVA_BIN=`which java 2> /dev/null`
-    if test $? -eq 0
-    then
-      export JAVA_BIN
-    else
-      echo "Please set JAVA_HOME to the root of a Java 5.0 installation."
-      exit 1
-    fi
-  else
-    JAVA_BIN=${JAVA_HOME}/bin/java
-    export JAVA_BIN
-  fi
-fi
-
-CLASSPATH=${INSTANCE_ROOT}/classes
-for JAR in ${INSTANCE_ROOT}/lib/*.jar
-do
-  CLASSPATH=${CLASSPATH}:${JAR}
-done
-export CLASSPATH
-
-
-${JAVA_BIN} ${JAVA_ARGS} org.opends.server.tools.LDAPSearch "$@" 
-
+SCRIPT_DIR=`dirname "${0}"`
+"${SCRIPT_DIR}/_client-script.sh" "${@}"
diff --git a/opendj-sdk/opends/resource/bin/ldif-diff.sh b/opendj-sdk/opends/resource/bin/ldif-diff.sh
index 33155d8..77a144a 100755
--- a/opendj-sdk/opends/resource/bin/ldif-diff.sh
+++ b/opendj-sdk/opends/resource/bin/ldif-diff.sh
@@ -26,48 +26,9 @@
 #      Portions Copyright 2006 Sun Microsystems, Inc.
 
 
-# Capture the current working directory so that we can change to it later.
-# Then capture the location of this script and the Directory Server instance
-# root so that we can use them to create appropriate paths.
-WORKING_DIR=`pwd`
+# This script may be used to compare the contents of two LDIF files.
+OPENDS_INVOKE_CLASS="org.opends.server.tools.LDIFDiff"
+export OPENDS_INVOKE_CLASS
 
-cd `dirname $0`
-SCRIPT_DIR=`pwd`
-
-cd ..
-INSTANCE_ROOT=`pwd`
-export INSTANCE_ROOT
-
-cd ${WORKING_DIR}
-
-
-# See if JAVA_HOME is set.  If not, then see if there is a java executable in
-# the path and try to figure it out.
-if test -z "${JAVA_BIN}"
-then
-  if test -z "${JAVA_HOME}"
-  then
-    JAVA_BIN=`which java 2> /dev/null`
-    if test $? -eq 0
-    then
-      export JAVA_BIN
-    else
-      echo "Please set JAVA_HOME to the root of a Java 5.0 installation."
-      exit 1
-    fi
-  else
-    JAVA_BIN=${JAVA_HOME}/bin/java
-    export JAVA_BIN
-  fi
-fi
-
-CLASSPATH=${INSTANCE_ROOT}/classes
-for JAR in ${INSTANCE_ROOT}/lib/*.jar
-do
-  CLASSPATH=${CLASSPATH}:${JAR}
-done
-export CLASSPATH
-
-
-${JAVA_BIN} ${JAVA_ARGS} org.opends.server.tools.LDIFDiff "$@" 
-
+SCRIPT_DIR=`dirname "${0}"`
+"${SCRIPT_DIR}/_client-script.sh" "${@}"
diff --git a/opendj-sdk/opends/resource/bin/ldifmodify.sh b/opendj-sdk/opends/resource/bin/ldifmodify.sh
index e464bbc..d7c8693 100755
--- a/opendj-sdk/opends/resource/bin/ldifmodify.sh
+++ b/opendj-sdk/opends/resource/bin/ldifmodify.sh
@@ -26,49 +26,9 @@
 #      Portions Copyright 2006 Sun Microsystems, Inc.
 
 
-# Capture the current working directory so that we can change to it later.
-# Then capture the location of this script and the Directory Server instance
-# root so that we can use them to create appropriate paths.
-WORKING_DIR=`pwd`
+# This script may be used to alter the contents of an LDIF file.
+OPENDS_INVOKE_CLASS="org.opends.server.tools.LDIFModify"
+export OPENDS_INVOKE_CLASS
 
-cd `dirname $0`
-SCRIPT_DIR=`pwd`
-
-cd ..
-INSTANCE_ROOT=`pwd`
-export INSTANCE_ROOT
-
-cd ${WORKING_DIR}
-
-
-# See if JAVA_HOME is set.  If not, then see if there is a java executable in
-# the path and try to figure it out.
-if test -z "${JAVA_BIN}"
-then
-  if test -z "${JAVA_HOME}"
-  then
-    JAVA_BIN=`which java 2> /dev/null`
-    if test $? -eq 0
-    then
-      export JAVA_BIN
-    else
-      echo "Please set JAVA_HOME to the root of a Java 5.0 installation."
-      exit 1
-    fi
-  else
-    JAVA_BIN=${JAVA_HOME}/bin/java
-    export JAVA_BIN
-  fi
-fi
-
-CLASSPATH=${INSTANCE_ROOT}/classes
-for JAR in ${INSTANCE_ROOT}/lib/*.jar
-do
-  CLASSPATH=${CLASSPATH}:${JAR}
-done
-export CLASSPATH
-
-
-${JAVA_BIN} ${JAVA_ARGS} org.opends.server.tools.LDIFModify \
-            -c ${INSTANCE_ROOT}/config/config.ldif "$@" 
-
+SCRIPT_DIR=`dirname "${0}"`
+"${SCRIPT_DIR}/_server-script.sh" "${@}"
diff --git a/opendj-sdk/opends/resource/bin/ldifsearch.sh b/opendj-sdk/opends/resource/bin/ldifsearch.sh
index ac613e2..fb8958d 100755
--- a/opendj-sdk/opends/resource/bin/ldifsearch.sh
+++ b/opendj-sdk/opends/resource/bin/ldifsearch.sh
@@ -26,48 +26,9 @@
 #      Portions Copyright 2006 Sun Microsystems, Inc.
 
 
-# Capture the current working directory so that we can change to it later.
-# Then capture the location of this script and the Directory Server instance
-# root so that we can use them to create appropriate paths.
-WORKING_DIR=`pwd`
+# This script may be used to perform searches in an LDIF file.
+OPENDS_INVOKE_CLASS="org.opends.server.tools.LDIFSearch"
+export OPENDS_INVOKE_CLASS
 
-cd `dirname $0`
-SCRIPT_DIR=`pwd`
-
-cd ..
-INSTANCE_ROOT=`pwd`
-export INSTANCE_ROOT
-
-cd ${WORKING_DIR}
-
-
-# See if JAVA_HOME is set.  If not, then see if there is a java executable in
-# the path and try to figure it out.
-if test -z "${JAVA_BIN}"
-then
-  if test -z "${JAVA_HOME}"
-  then
-    JAVA_BIN=`which java 2> /dev/null`
-    if test $? -eq 0
-    then
-      export JAVA_BIN
-    else
-      echo "Please set JAVA_HOME to the root of a Java 5.0 installation."
-      exit 1
-    fi
-  else
-    JAVA_BIN=${JAVA_HOME}/bin/java
-    export JAVA_BIN
-  fi
-fi
-
-CLASSPATH=${INSTANCE_ROOT}/classes
-for JAR in ${INSTANCE_ROOT}/lib/*.jar
-do
-  CLASSPATH=${CLASSPATH}:${JAR}
-done
-export CLASSPATH
-
-
-${JAVA_BIN} ${JAVA_ARGS} org.opends.server.tools.LDIFSearch "$@" 
-
+SCRIPT_DIR=`dirname "${0}"`
+"${SCRIPT_DIR}/_client-script.sh" "${@}"
diff --git a/opendj-sdk/opends/resource/bin/makeldif.sh b/opendj-sdk/opends/resource/bin/makeldif.sh
index 447b7de..9129946 100755
--- a/opendj-sdk/opends/resource/bin/makeldif.sh
+++ b/opendj-sdk/opends/resource/bin/makeldif.sh
@@ -26,50 +26,10 @@
 #      Portions Copyright 2006 Sun Microsystems, Inc.
 
 
-# Capture the current working directory so that we can change to it later.
-# Then apture the location of this script and the Directory Server instance
-# root so that we can use them to create appropriate paths.
-WORKING_DIR=`pwd`
+# This script may be used to generate LDIF data based on a provided template.
+OPENDS_INVOKE_CLASS="org.opends.server.tools.makeldif.MakeLDIF"
+export OPENDS_INVOKE_CLASS
 
-cd `dirname $0`
-SCRIPT_DIR=`pwd`
-
-cd ..
-INSTANCE_ROOT=`pwd`
-export INSTANCE_ROOT
-
-cd ${WORKING_DIR}
-
-
-# See if JAVA_HOME is set.  If not, then see if there is a java executable in
-# the path and try to figure it out.
-if test -z "${JAVA_BIN}"
-then
-  if test -z "${JAVA_HOME}"
-  then
-    JAVA_BIN=`which java 2> /dev/null`
-    if test $? -eq 0
-    then
-      export JAVA_BIN
-    else
-      echo "Please set JAVA_HOME to the root of a Java 5.0 installation."
-      exit 1
-    fi
-  else
-    JAVA_BIN=${JAVA_HOME}/bin/java
-    export JAVA_BIN
-  fi
-fi
-
-CLASSPATH=${INSTANCE_ROOT}/classes
-for JAR in ${INSTANCE_ROOT}/lib/*.jar
-do
-    CLASSPATH=${CLASSPATH}:${JAR}
-done
-export CLASSPATH
-
-
-${JAVA_BIN} ${JAVA_ARGS} org.opends.server.tools.makeldif.MakeLDIF \
-     --configClass org.opends.server.extensions.ConfigFileHandler \
-     --configFile ${INSTANCE_ROOT}/config/config.ldif \
-     --resourcePath ${INSTANCE_ROOT}/config/MakeLDIF "${@}"
+SCRIPT_DIR=`dirname "${0}"`
+"${SCRIPT_DIR}/_server-script.sh" \
+     --resourcePath "${SCRIPT_DIR}/../config/MakeLDIF" "${@}"
diff --git a/opendj-sdk/opends/resource/bin/restore.sh b/opendj-sdk/opends/resource/bin/restore.sh
index 7df0aaf..6758eb9 100755
--- a/opendj-sdk/opends/resource/bin/restore.sh
+++ b/opendj-sdk/opends/resource/bin/restore.sh
@@ -26,49 +26,9 @@
 #      Portions Copyright 2006 Sun Microsystems, Inc.
 
 
-# Capture the current working directory so that we can change to it later.
-# Then apture the location of this script and the Directory Server instance
-# root so that we can use them to create appropriate paths.
-WORKING_DIR=`pwd`
+# This script may be used to perform a restore of a Directory Server backend.
+OPENDS_INVOKE_CLASS="org.opends.server.tools.RestoreDB"
+export OPENDS_INVOKE_CLASS
 
-cd `dirname $0`
-SCRIPT_DIR=`pwd`
-
-cd ..
-INSTANCE_ROOT=`pwd`
-export INSTANCE_ROOT
-
-cd ${WORKING_DIR}
-
-
-# See if JAVA_HOME is set.  If not, then see if there is a java executable in
-# the path and try to figure it out.
-if test -z "${JAVA_BIN}"
-then
-  if test -z "${JAVA_HOME}"
-  then
-    JAVA_BIN=`which java 2> /dev/null`
-    if test $? -eq 0
-    then
-      export JAVA_BIN
-    else
-      echo "Please set JAVA_HOME to the root of a Java 5.0 installation."
-      exit 1
-    fi
-  else
-    JAVA_BIN=${JAVA_HOME}/bin/java
-    export JAVA_BIN
-  fi
-fi
-
-CLASSPATH=${INSTANCE_ROOT}/classes
-for JAR in ${INSTANCE_ROOT}/lib/*.jar
-do
-    CLASSPATH=${CLASSPATH}:${JAR}
-done
-export CLASSPATH
-
-
-${JAVA_BIN} ${JAVA_ARGS} org.opends.server.tools.RestoreDB \
-     --configClass org.opends.server.extensions.ConfigFileHandler \
-     --configFile ${INSTANCE_ROOT}/config/config.ldif "${@}"
+SCRIPT_DIR=`dirname "${0}"`
+"${SCRIPT_DIR}/_server-script.sh" "${@}"
diff --git a/opendj-sdk/opends/resource/bin/start-ds.sh b/opendj-sdk/opends/resource/bin/start-ds.sh
index 53a7c45..1472766 100755
--- a/opendj-sdk/opends/resource/bin/start-ds.sh
+++ b/opendj-sdk/opends/resource/bin/start-ds.sh
@@ -26,21 +26,6 @@
 #      Portions Copyright 2006 Sun Microsystems, Inc.
 
 
-# Capture the current working directory so that we can change to it later.
-# Then apture the location of this script and the Directory Server instance
-# root so that we can use them to create appropriate paths.
-WORKING_DIR=`pwd`
-
-cd `dirname $0`
-SCRIPT_DIR=`pwd`
-
-cd ..
-INSTANCE_ROOT=`pwd`
-export INSTANCE_ROOT
-
-cd ${WORKING_DIR}
-
-
 # See if JAVA_HOME is set.  If not, then see if there is a java executable in
 # the path and try to figure it out.
 if test -z "${JAVA_BIN}"
@@ -48,7 +33,7 @@
   if test -z "${JAVA_HOME}"
   then
     JAVA_BIN=`which java 2> /dev/null`
-    if test $? -eq 0
+    if test ${?} -eq 0
     then
       export JAVA_BIN
     else
@@ -61,29 +46,72 @@
   fi
 fi
 
+
+# Explicitly set the PATH, LD_LIBRARY_PATH, LD_PRELOAD, and other important
+# system environment variables for security and compatibility reasons.
+PATH=/bin:/usr/bin
+LD_LIBRARY_PATH=
+LD_LIBRARY_PATH_32=
+LD_LIBRARY_PATH_64=
+LD_PRELOAD=
+LD_PRELOAD_32=
+LD_PRELOAD_64=
+export PATH LD_LIBRARY_PATH LD_LIBRARY_PATH_32 LD_LIBRARY_PATH_64 \
+       LD_PRELOAD LD_PRELOAD_32 LD_PRELOAD_34
+
+
+# Capture the current working directory so that we can change to it later.
+# Then capture the location of this script and the Directory Server instance
+# root so that we can use them to create appropriate paths.
+WORKING_DIR=`pwd`
+
+cd `dirname "${0}"`
+SCRIPT_DIR=`pwd`
+
+cd ..
+INSTANCE_ROOT=`pwd`
+export INSTANCE_ROOT
+
+cd "${WORKING_DIR}"
+
+
+# Configure the appropriate CLASSPATH.
 CLASSPATH=${INSTANCE_ROOT}/classes
 for JAR in ${INSTANCE_ROOT}/lib/*.jar
 do
-    CLASSPATH=${CLASSPATH}:${JAR}
+  CLASSPATH=${CLASSPATH}:${JAR}
 done
 export CLASSPATH
 
 
+# Specify the locations of important files that may be used when the server
+# is starting.
+CONFIG_FILE=${INSTANCE_ROOT}/config/config.ldif
+PID_FILE=${INSTANCE_ROOT}/logs/server.pid
+LOG_FILE=${INSTANCE_ROOT}/logs/server.out
+STARTING_FILE=${INSTANCE_ROOT}/logs/server.starting
+
+
 # See if "-nodetach" was specified as the first command-line argument.  If it
 # was, then don't use nohup to send to the background, and send all output to
 # both the console and a log file.
 if test "${1}" = "-nodetach"
 then
   shift
-  ${JAVA_BIN} ${JAVA_ARGS} \
-	org.opends.server.core.DirectoryServer \
-	--configClass org.opends.server.extensions.ConfigFileHandler \
-	--configFile ${INSTANCE_ROOT}/config/config.ldif \
-        "$@" 2>&1 | tee -i -a ${INSTANCE_ROOT}/logs/server.out
+  echo $$ > "${PID_FILE}"
+  rm -f "${PID_FILE}" "${LOG_FILE}"
+  exec "${JAVA_BIN}" ${JAVA_ARGS} \
+       org.opends.server.core.DirectoryServer \
+       --configClass org.opends.server.extensions.ConfigFileHandler \
+       --configFile "${CONFIG_FILE}" --noDetach "${@}"
 else
-  nohup ${JAVA_BIN} ${JAVA_ARGS} \
-	org.opends.server.core.DirectoryServer \
-	--configClass org.opends.server.extensions.ConfigFileHandler \
-	--configFile ${INSTANCE_ROOT}/config/config.ldif \
-        "$@" >> ${INSTANCE_ROOT}/logs/server.out 2>&1 &
+  touch "${STARTING_FILE}"
+  nohup "${JAVA_BIN}" ${JAVA_ARGS} \
+       org.opends.server.core.DirectoryServer \
+       --configClass org.opends.server.extensions.ConfigFileHandler \
+       --configFile "${CONFIG_FILE}" "${@}" > "${LOG_FILE}" 2>&1 &
+  echo $! > "${PID_FILE}"
+  "${JAVA_BIN}" -Xms8M -Xmx8M org.opends.server.tools.WaitForFileDelete \
+       --targetFile "${STARTING_FILE}" --logFile "${LOG_FILE}"
+  exit ${?}
 fi
diff --git a/opendj-sdk/opends/resource/bin/stop-ds.sh b/opendj-sdk/opends/resource/bin/stop-ds.sh
index f2ffafd..5b62199 100755
--- a/opendj-sdk/opends/resource/bin/stop-ds.sh
+++ b/opendj-sdk/opends/resource/bin/stop-ds.sh
@@ -26,19 +26,13 @@
 #      Portions Copyright 2006 Sun Microsystems, Inc.
 
 
-# Capture the current working directory so that we can change to it later.
-# Then apture the location of this script and the Directory Server instance
-# root so that we can use them to create appropriate paths.
-WORKING_DIR=`pwd`
-
-cd `dirname $0`
-SCRIPT_DIR=`pwd`
-
-cd ..
-INSTANCE_ROOT=`pwd`
-export INSTANCE_ROOT
-
-cd ${WORKING_DIR}
+# This script may be used to request that the Directory Server shut down.
+# It operates in two different ways, depending on how it is invoked.  If it
+# is invoked without any arguments and a local PID file is available, then it
+# will stop the server by sending a TERM signal to the process, and this
+# script will wait until the server has stopped before exiting.  If any
+# arguments were provided or there is no local PID file, then it will attempt
+# to stop the server using an LDAP request.
 
 
 # See if JAVA_HOME is set.  If not, then see if there is a java executable in
@@ -48,7 +42,7 @@
   if test -z "${JAVA_HOME}"
   then
     JAVA_BIN=`which java 2> /dev/null`
-    if test $? -eq 0
+    if test ${?} -eq 0
     then
       export JAVA_BIN
     else
@@ -61,12 +55,64 @@
   fi
 fi
 
+
+# Explicitly set the PATH, LD_LIBRARY_PATH, LD_PRELOAD, and other important
+# system environment variables for security and compatibility reasons.
+PATH=/bin:/usr/bin
+LD_LIBRARY_PATH=
+LD_LIBRARY_PATH_32=
+LD_LIBRARY_PATH_64=
+LD_PRELOAD=
+LD_PRELOAD_32=
+LD_PRELOAD_64=
+export PATH LD_LIBRARY_PATH LD_LIBRARY_PATH_32 LD_LIBRARY_PATH_64 \
+       LD_PRELOAD LD_PRELOAD_32 LD_PRELOAD_34
+
+
+# Capture the current working directory so that we can change to it later.
+# Then capture the location of this script and the Directory Server instance
+# root so that we can use them to create appropriate paths.
+WORKING_DIR=`pwd`
+
+cd `dirname "${0}"`
+SCRIPT_DIR=`pwd`
+
+cd ..
+INSTANCE_ROOT=`pwd`
+export INSTANCE_ROOT
+
+cd "${WORKING_DIR}"
+
+
+# Configure the appropriate CLASSPATH.
 CLASSPATH=${INSTANCE_ROOT}/classes
 for JAR in ${INSTANCE_ROOT}/lib/*.jar
 do
-    CLASSPATH=${CLASSPATH}:${JAR}
+  CLASSPATH=${CLASSPATH}:${JAR}
 done
 export CLASSPATH
 
 
-${JAVA_BIN} ${JAVA_ARGS} org.opends.server.tools.StopDS "${@}"
+# See if any arguments were provided and if a local PID file exists.  If there
+# were no arguments and there is a PID file, then try to stop the server with
+# a kill command.
+if test -z "${1}" 
+then
+  if test -f "${INSTANCE_ROOT}/logs/server.pid"
+  then
+    kill `cat "${INSTANCE_ROOT}/logs/server.pid"`
+    EXIT_CODE=${?}
+    if test "${EXIT_CODE}" -eq 0
+    then
+      "${JAVA_BIN}" -Xms8M -Xmx8M org.opends.server.tools.WaitForFileDelete \
+           --targetFile "${INSTANCE_ROOT}/logs/server.pid" \
+           --logFile "${INSTANCE_ROOT}/logs/errors"
+      EXIT_CODE=${?}
+    fi
+    exit ${EXIT_CODE}
+  fi
+fi
+
+
+# If we've gotten here, then we should try to stop the server over LDAP.
+"${JAVA_BIN}" ${JAVA_ARGS} org.opends.server.tools.StopDS "${@}"
diff --git a/opendj-sdk/opends/resource/bin/verify-index.sh b/opendj-sdk/opends/resource/bin/verify-index.sh
index a28caf9..2aad97c 100644
--- a/opendj-sdk/opends/resource/bin/verify-index.sh
+++ b/opendj-sdk/opends/resource/bin/verify-index.sh
@@ -26,49 +26,10 @@
 #      Portions Copyright 2006 Sun Microsystems, Inc.
 
 
-# Capture the current working directory so that we can change to it later.
-# Then apture the location of this script and the Directory Server instance
-# root so that we can use them to create appropriate paths.
-WORKING_DIR=`pwd`
+# This script may be used to perform validation on the contents of a Directory
+# Server backend storing its data in the Berkeley DB Java Edition.
+OPENDS_INVOKE_CLASS="org.opends.server.tools.VerifyIndex"
+export OPENDS_INVOKE_CLASS
 
-cd `dirname $0`
-SCRIPT_DIR=`pwd`
-
-cd ..
-INSTANCE_ROOT=`pwd`
-export INSTANCE_ROOT
-
-cd ${WORKING_DIR}
-
-
-# See if JAVA_HOME is set.  If not, then see if there is a java executable in
-# the path and try to figure it out.
-if test -z "${JAVA_BIN}"
-then
-  if test -z "${JAVA_HOME}"
-  then
-    JAVA_BIN=`which java 2> /dev/null`
-    if test $? -eq 0
-    then
-      export JAVA_BIN
-    else
-      echo "Please set JAVA_HOME to the root of a Java 5.0 installation."
-      exit 1
-    fi
-  else
-    JAVA_BIN=${JAVA_HOME}/bin/java
-    export JAVA_BIN
-  fi
-fi
-
-CLASSPATH=${INSTANCE_ROOT}/classes
-for JAR in ${INSTANCE_ROOT}/lib/*.jar
-do
-    CLASSPATH=${CLASSPATH}:${JAR}
-done
-export CLASSPATH
-
-
-${JAVA_BIN} ${JAVA_ARGS} org.opends.server.tools.VerifyIndex \
-     --configClass org.opends.server.extensions.ConfigFileHandler \
-     --configFile ${INSTANCE_ROOT}/config/config.ldif "${@}"
+SCRIPT_DIR=`dirname "${0}"`
+"${SCRIPT_DIR}/_server-script.sh" "${@}"
diff --git a/opendj-sdk/opends/resource/setup.sh b/opendj-sdk/opends/resource/setup.sh
index 90a3487..d2b8313 100755
--- a/opendj-sdk/opends/resource/setup.sh
+++ b/opendj-sdk/opends/resource/setup.sh
@@ -26,20 +26,6 @@
 #      Portions Copyright 2006 Sun Microsystems, Inc.
 
 
-# Capture the current working directory so that we can change to it later.
-# Then apture the location of this script and the Directory Server instance
-# root so that we can use them to create appropriate paths.
-WORKING_DIR=`pwd`
-
-cd `dirname $0`
-SCRIPT_DIR=`pwd`
-
-INSTANCE_ROOT=${SCRIPT_DIR}
-export INSTANCE_ROOT
-
-cd ${WORKING_DIR}
-
-
 # See if JAVA_HOME is set.  If not, then see if there is a java executable in
 # the path and try to figure it out.
 if test -z "${JAVA_BIN}"
@@ -47,7 +33,7 @@
   if test -z "${JAVA_HOME}"
   then
     JAVA_BIN=`which java 2> /dev/null`
-    if test $? -eq 0
+    if test ${?} -eq 0
     then
       export JAVA_BIN
     else
@@ -60,10 +46,39 @@
   fi
 fi
 
+
+# Explicitly set the PATH, LD_LIBRARY_PATH, LD_PRELOAD, and other important
+# system environment variables for security and compatibility reasons.
+PATH=/bin:/usr/bin
+LD_LIBRARY_PATH=
+LD_LIBRARY_PATH_32=
+LD_LIBRARY_PATH_64=
+LD_PRELOAD=
+LD_PRELOAD_32=
+LD_PRELOAD_64=
+export PATH LD_LIBRARY_PATH LD_LIBRARY_PATH_32 LD_LIBRARY_PATH_64 \
+       LD_PRELOAD LD_PRELOAD_32 LD_PRELOAD_34
+
+
+# Capture the current working directory so that we can change to it later.
+# Then capture the location of this script and the Directory Server instance
+# root so that we can use them to create appropriate paths.
+WORKING_DIR=`pwd`
+
+cd `dirname "${0}"`
+SCRIPT_DIR=`pwd`
+
+INSTANCE_ROOT=${SCRIPT_DIR}
+export INSTANCE_ROOT
+
+cd "${WORKING_DIR}"
+
+
+# Configure the appropriate CLASSPATH.
 CLASSPATH=${INSTANCE_ROOT}/classes
 for JAR in ${INSTANCE_ROOT}/lib/*.jar
 do
-    CLASSPATH=${CLASSPATH}:${JAR}
+  CLASSPATH=${CLASSPATH}:${JAR}
 done
 export CLASSPATH
 
@@ -71,13 +86,13 @@
 # Determine whether the detected Java environment is acceptable for use.
 if test -z "${JAVA_ARGS}"
 then
-  ${JAVA_BIN} -client org.opends.server.tools.InstallDS -t 2> /dev/null
-  if test $? -eq 0
+  "${JAVA_BIN}" -client org.opends.server.tools.InstallDS -t 2> /dev/null
+  if test ${?} -eq 0
   then
     JAVA_ARGS="-client"
   else
-    ${JAVA_BIN} org.opends.server.tools.InstallDS -t 2> /dev/null
-    if test $? -ne 0
+    "${JAVA_BIN}" org.opends.server.tools.InstallDS -t 2> /dev/null
+    if test ${?} -ne 0
     then
       echo "ERROR:  The detected Java version could not be used.  Please set "
       echo "        JAVA_HOME to the root of a Java 5.0 installation."
@@ -85,8 +100,8 @@
     fi
   fi
 else
-  ${JAVA_BIN} ${JAVA_ARGS} org.opends.server.tools.InstallDS -t 2> /dev/null
-  if test $? -ne 0
+  "${JAVA_BIN}" ${JAVA_ARGS} org.opends.server.tools.InstallDS -t 2> /dev/null
+  if test ${?} -ne 0
   then
     echo "ERROR:  The detected Java version could not be used.  Please set "
     echo "        JAVA_HOME to the root of a Java 5.0 installation."
@@ -95,7 +110,8 @@
 fi
 
 
-${JAVA_BIN} ${JAVA_ARGS} org.opends.server.tools.InstallDS \
+# Launch the setup process.
+"${JAVA_BIN}" ${JAVA_ARGS} org.opends.server.tools.InstallDS \
      --configClass org.opends.server.extensions.ConfigFileHandler \
-     --configFile ${INSTANCE_ROOT}/config/config.ldif -P ${0} "${@}"
+     --configFile "${INSTANCE_ROOT}/config/config.ldif" -P "${0}" "${@}"
 
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/DirectoryServer.java b/opendj-sdk/opends/src/server/org/opends/server/core/DirectoryServer.java
index abc190e..25ac8f5 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/DirectoryServer.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/DirectoryServer.java
@@ -27,6 +27,9 @@
 package org.opends.server.core;
 
 
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.PrintStream;
 import java.net.InetAddress;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -142,6 +145,7 @@
 import org.opends.server.types.ResultCode;
 import org.opends.server.types.Schema;
 import org.opends.server.types.WritabilityMode;
+import org.opends.server.util.MultiOutputStream;
 import org.opends.server.util.TimeThread;
 import org.opends.server.util.args.ArgumentException;
 import org.opends.server.util.args.ArgumentParser;
@@ -1041,6 +1045,16 @@
       // Deregister the startup-specific debug and error loggers.
       removeDebugLogger(startupDebugLogger);
       removeErrorLogger(startupErrorLogger);
+
+
+      // If a server.starting file exists, then remove it.
+      File serverStartingFile =
+                new File(configHandler.getServerRoot() + File.separator +
+                         "logs" + File.separator + "server.starting");
+      if (serverStartingFile.exists())
+      {
+        serverStartingFile.delete();
+      }
     }
   }
 
@@ -7408,6 +7422,7 @@
     BooleanArgument displayUsage = null;
     BooleanArgument dumpMessages = null;
     BooleanArgument fullVersion  = null;
+    BooleanArgument noDetach     = null;
     BooleanArgument systemInfo   = null;
     BooleanArgument version      = null;
     StringArgument  configClass  = null;
@@ -7460,6 +7475,12 @@
       argParser.addArgument(dumpMessages);
 
 
+      noDetach = new BooleanArgument("nodetach", 'N', "noDetach",
+                                     MSGID_DSCORE_DESCRIPTION_NODETACH);
+      noDetach.setHidden(true);
+      argParser.addArgument(noDetach);
+
+
       displayUsage = new BooleanArgument("help", 'H', "help",
                                          MSGID_DSCORE_DESCRIPTION_USAGE);
       argParser.addArgument(displayUsage);
@@ -7539,6 +7560,8 @@
                          System.getProperty("java.vm.version"));
       System.out.println("JVM Vendor:             " +
                          System.getProperty("java.vm.vendor"));
+      System.out.println("Java Home:              " +
+                         System.getProperty("java.home"));
       System.out.println("Class Path:             " +
                          System.getProperty("java.class.path"));
       System.out.println("Current Directory:      " +
@@ -7581,6 +7604,75 @@
     }
 
 
+    // Redirect standard output and standard error to the server.out file.  If
+    // the server hasn't detached from the terminal, then also continue writing
+    // to the original standard output and standard error.  Also, configure the
+    // JVM to delete the PID file on exit, if it exists.
+    PrintStream serverOutStream;
+    try
+    {
+      // We need to figure out where to put the file.  See if the server root
+      // is available as an environment variable and if so then use it.
+      // Otherwise, try to figure it out from the location of the config file.
+      String serverRoot = System.getenv(ENV_VAR_INSTANCE_ROOT);
+      if (serverRoot == null)
+      {
+        serverRoot = new File(configFile.getValue()).getParentFile().
+                              getParentFile().getAbsolutePath();
+      }
+
+      if (serverRoot == null)
+      {
+        System.err.println("WARNING:  Unable to determine server root in " +
+                           "order to redirect standard output and standard " +
+                           "error.");
+      }
+      else
+      {
+        File logDir = new File(serverRoot + File.separator + "logs");
+        if (logDir.exists())
+        {
+          FileOutputStream fos =
+               new FileOutputStream(new File(logDir, "server.out"), true);
+          serverOutStream = new PrintStream(fos);
+
+          if (noDetach.isPresent())
+          {
+            MultiOutputStream multiStream =
+                 new MultiOutputStream(System.out, serverOutStream);
+            serverOutStream = new PrintStream(multiStream);
+          }
+
+          System.setOut(serverOutStream);
+          System.setErr(serverOutStream);
+
+          File f = new File(logDir, "server.pid");
+          if (f.exists())
+          {
+            f.deleteOnExit();
+          }
+
+          f = new File(logDir, "server.starting");
+          if (f.exists())
+          {
+            f.deleteOnExit();
+          }
+        }
+        else
+        {
+          System.err.println("WARNING:  Unable to redirect standard output " +
+                             "and standard error because the logs directory " +
+                             logDir.getAbsolutePath() + " does not exist.");
+        }
+      }
+    }
+    catch (Exception e)
+    {
+      System.err.println("WARNING:  Unable to redirect standard output and " +
+                         "standard error:  " + stackTraceToSingleLineString(e));
+    }
+
+
     // Bootstrap and start the Directory Server.
     DirectoryServer directoryServer = DirectoryServer.getInstance();
     try
diff --git a/opendj-sdk/opends/src/server/org/opends/server/messages/CoreMessages.java b/opendj-sdk/opends/src/server/org/opends/server/messages/CoreMessages.java
index 57acb02..f4d0c07 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/messages/CoreMessages.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/messages/CoreMessages.java
@@ -5937,6 +5937,15 @@
 
 
   /**
+   * The message ID for the message that will be used as the description for the
+   * noDetach command-line argument.  This does not take any arguments.
+   */
+  public static final int MSGID_DSCORE_DESCRIPTION_NODETACH =
+       CATEGORY_MASK_CORE | SEVERITY_MASK_INFORMATIONAL | 567;
+
+
+
+  /**
    * Associates a set of generic messages with the message IDs defined
    * in this class.
    */
@@ -7208,6 +7217,9 @@
     registerMessage(MSGID_DSCORE_DESCRIPTION_DUMPMESSAGES,
                     "Dumps a list of all messages that have been defined " +
                     "for use in the Directory Server.");
+    registerMessage(MSGID_DSCORE_DESCRIPTION_NODETACH,
+                    "Indicates that the Directory Server has not detached " +
+                    "from the terminal used to start it.");
     registerMessage(MSGID_DSCORE_DESCRIPTION_USAGE,
                     "Displays usage information for the Directory Server.");
     registerMessage(MSGID_DSCORE_CANNOT_INITIALIZE_ARGS,
diff --git a/opendj-sdk/opends/src/server/org/opends/server/messages/ToolMessages.java b/opendj-sdk/opends/src/server/org/opends/server/messages/ToolMessages.java
index 97c9ca2..cb7b2e8 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/messages/ToolMessages.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/messages/ToolMessages.java
@@ -6632,6 +6632,73 @@
 
 
   /**
+   * The message ID for the message that will be used as the description for the
+   * targetFile argument.  It does not take any arguments.
+   */
+  public static final int MSGID_WAIT4DEL_DESCRIPTION_TARGET_FILE =
+       CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 675;
+
+
+
+  /**
+   * The message ID for the message that will be used as the description for the
+   * logFile argument.  It does not take any arguments.
+   */
+  public static final int MSGID_WAIT4DEL_DESCRIPTION_LOG_FILE =
+       CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 676;
+
+
+
+  /**
+   * The message ID for the message that will be used as the description for the
+   * timeout argument.  It does not take any arguments.
+   */
+  public static final int MSGID_WAIT4DEL_DESCRIPTION_TIMEOUT =
+       CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 677;
+
+
+
+  /**
+   * The message ID for the message that will be used as the description for the
+   * help argument.  It does not take any arguments.
+   */
+  public static final int MSGID_WAIT4DEL_DESCRIPTION_HELP =
+       CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 678;
+
+
+
+  /**
+   * The message ID for the message that will be used if an error occurs while
+   * attempting to initialize the command-line argument parser.  This takes a
+   * single argument, which is a message explaining the problem that occurred.
+   */
+  public static final int MSGID_WAIT4DEL_CANNOT_INITIALIZE_ARGS =
+       CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 679;
+
+
+
+  /**
+   * The message ID for the message that will be used if an error occurs while
+   * parsing the provided command-line arguments.  This takes a single argument,
+   * which is a message explaining the problem that occurred.
+   */
+  public static final int MSGID_WAIT4DEL_ERROR_PARSING_ARGS =
+       CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 680;
+
+
+
+  /**
+   * The message ID for the message that will be used if an error occurs while
+   * trying to open the log file for reading.  This takes two arguments, which
+   * are the path to the log file and a message explaining the problem that
+   * occurred.
+   */
+  public static final int MSGID_WAIT4DEL_CANNOT_OPEN_LOG_FILE =
+       CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_WARNING | 681;
+
+
+
+  /**
    * Associates a set of generic messages with the message IDs defined in this
    * class.
    */
@@ -8794,6 +8861,26 @@
     registerMessage(MSGID_LDAPPWMOD_COULD_NOT_DECODE_RESPONSE_VALUE,
                     "Unable to decode the password modify response value:  " +
                     "%s.");
+
+
+    registerMessage(MSGID_WAIT4DEL_DESCRIPTION_TARGET_FILE,
+                    "Specifies the path to the file to watch for deletion.");
+    registerMessage(MSGID_WAIT4DEL_DESCRIPTION_LOG_FILE,
+                    "Specifies the path to a file containing log output to " +
+                    "monitor.");
+    registerMessage(MSGID_WAIT4DEL_DESCRIPTION_TIMEOUT,
+                    "The maximum length of time in seconds to wait for the " +
+                    "target file to be deleted before exiting.");
+    registerMessage(MSGID_WAIT4DEL_DESCRIPTION_HELP,
+                    "Displays this usage information.");
+    registerMessage(MSGID_WAIT4DEL_CANNOT_INITIALIZE_ARGS,
+                    "An unexpected error occurred while attempting to " +
+                    "initialize the command-line arguments:  %s.");
+    registerMessage(MSGID_WAIT4DEL_ERROR_PARSING_ARGS,
+                    "An error occurred while parsing the command-line " +
+                    "arguments:  %s.");
+    registerMessage(MSGID_WAIT4DEL_CANNOT_OPEN_LOG_FILE,
+                    "WARNING:  Unable to open log file %s for reading:  %s.");
   }
 }
 
diff --git a/opendj-sdk/opends/src/server/org/opends/server/tools/WaitForFileDelete.java b/opendj-sdk/opends/src/server/org/opends/server/tools/WaitForFileDelete.java
new file mode 100644
index 0000000..c3760a0
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/tools/WaitForFileDelete.java
@@ -0,0 +1,301 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying * information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Portions Copyright 2006 Sun Microsystems, Inc.
+ */
+package org.opends.server.tools;
+
+
+
+import java.io.File;
+import java.io.RandomAccessFile;
+
+import org.opends.server.util.args.ArgumentException;
+import org.opends.server.util.args.ArgumentParser;
+import org.opends.server.util.args.BooleanArgument;
+import org.opends.server.util.args.IntegerArgument;
+import org.opends.server.util.args.StringArgument;
+
+import static org.opends.server.messages.MessageHandler.*;
+import static org.opends.server.messages.ToolMessages.*;
+import static org.opends.server.util.StaticUtils.*;
+
+
+
+/**
+ * This program provides a simple tool that will wait for a specified file to be
+ * deleted before exiting.  It can be used in the process of confirming that the
+ * server has completed its startup or shutdown process.
+ */
+public class WaitForFileDelete
+{
+  /**
+   * The fully-qualified name of this class for debugging purposes.
+   */
+  private static final String CLASS_NAME =
+       "org.opends.server.tools.WaitForFileDelete";
+
+
+
+  /**
+   * The exit code value that will be used if the target file is deleted
+   * successfully.
+   */
+  public static final int EXIT_CODE_SUCCESS = 0;
+
+
+
+  /**
+   * The exit code value that will be used if an internal error occurs within
+   * this program.
+   */
+  public static final int EXIT_CODE_INTERNAL_ERROR = 1;
+
+
+
+  /**
+   * The exit code value that will be used if a timeout occurs while waiting for
+   * the file to be removed.
+   */
+  public static final int EXIT_CODE_TIMEOUT = 2;
+
+
+
+  /**
+   * The position at which to wrap long lines.
+   */
+  public static final int MAX_LINE_WIDTH = 79;
+
+
+
+  /**
+   * Processes the command-line arguments and initiates the process of waiting
+   * for the file to be removed.
+   *
+   * @param  args  The command-line arguments provided to this program.
+   */
+  public static void main(String[] args)
+  {
+    try
+    {
+      int exitCode = mainWait(args);
+      if (exitCode != EXIT_CODE_SUCCESS)
+      {
+        System.exit(exitCode);
+      }
+    }
+    catch (Exception e)
+    {
+      e.printStackTrace();
+      System.exit(EXIT_CODE_INTERNAL_ERROR);
+    }
+  }
+
+
+
+  /**
+   * Processes the command-line arguments and then waits for the specified file
+   * to be removed.
+   *
+   * @param  args  The command-line arguments provided to this program.
+   *
+   * @return  An integer value of zero if the file was deleted successfully, or
+   *          some other value if a problem occurred.
+   */
+  public static int mainWait(String[] args)
+  {
+    // Create all of the command-line arguments for this program.
+    BooleanArgument showUsage      = null;
+    IntegerArgument timeout        = null;
+    StringArgument  logFilePath    = null;
+    StringArgument  targetFilePath = null;
+
+    ArgumentParser argParser = new ArgumentParser(CLASS_NAME, false);
+
+    try
+    {
+      targetFilePath =
+           new StringArgument("targetfile", 'f', "targetFile", true, false,
+                              true, "{path}", null, null,
+                              MSGID_WAIT4DEL_DESCRIPTION_TARGET_FILE);
+      argParser.addArgument(targetFilePath);
+
+
+      logFilePath = new StringArgument("logfile", 'l', "logFile", false, false,
+                                       true, "{path}", null, null,
+                                       MSGID_WAIT4DEL_DESCRIPTION_LOG_FILE);
+      argParser.addArgument(logFilePath);
+
+
+      timeout = new IntegerArgument("timeout", 't', "timeout", true, false,
+                                    true, "{seconds}", 60, null, true, 0, false,
+                                    0, MSGID_WAIT4DEL_DESCRIPTION_TIMEOUT);
+      argParser.addArgument(timeout);
+
+
+      showUsage = new BooleanArgument("help", 'H', "help",
+                                      MSGID_WAIT4DEL_DESCRIPTION_HELP);
+      argParser.addArgument(showUsage);
+      argParser.setUsageArgument(showUsage);
+    }
+    catch (ArgumentException ae)
+    {
+      int    msgID   = MSGID_WAIT4DEL_CANNOT_INITIALIZE_ARGS;
+      String message = getMessage(msgID, ae.getMessage());
+      System.err.println(wrapText(message, MAX_LINE_WIDTH));
+      return EXIT_CODE_INTERNAL_ERROR;
+    }
+
+
+    // Parse the command-line arguments provided to the program.
+    try
+    {
+      argParser.parseArguments(args);
+    }
+    catch (ArgumentException ae)
+    {
+      int    msgID   = MSGID_WAIT4DEL_ERROR_PARSING_ARGS;
+      String message = getMessage(msgID, ae.getMessage());
+
+      System.err.println(wrapText(message, MAX_LINE_WIDTH));
+      System.err.println(argParser.getUsage());
+      return EXIT_CODE_INTERNAL_ERROR;
+    }
+
+
+    // If we should just display usage information, then print it and exit.
+    if (showUsage.isPresent())
+    {
+      return EXIT_CODE_SUCCESS;
+    }
+
+
+    // Get the file to watch.  If it doesn't exist now, then exit immediately.
+    File targetFile = new File(targetFilePath.getValue());
+    if (! targetFile.exists())
+    {
+      return EXIT_CODE_SUCCESS;
+    }
+
+
+    // If a log file was specified, then open it.
+    long logFileOffset = 0L;
+    RandomAccessFile logFile = null;
+    if (logFilePath.isPresent())
+    {
+      try
+      {
+        File f = new File(logFilePath.getValue());
+        if (f.exists())
+        {
+          logFile = new RandomAccessFile(f, "r");
+          logFileOffset = logFile.length();
+          logFile.seek(logFileOffset);
+        }
+      }
+      catch (Exception e)
+      {
+        int    msgID   = MSGID_WAIT4DEL_CANNOT_OPEN_LOG_FILE;
+        String message = getMessage(msgID, logFilePath.getValue(),
+                                    String.valueOf(e));
+        System.err.println(wrapText(message, MAX_LINE_WIDTH));
+
+        logFile = null;
+      }
+    }
+
+
+    // Figure out when to stop waiting.
+    long stopWaitingTime;
+    try
+    {
+      long timeoutMillis = 1000L * Integer.parseInt(timeout.getValue());
+      if (timeoutMillis > 0)
+      {
+        stopWaitingTime = System.currentTimeMillis() + timeoutMillis;
+      }
+      else
+      {
+        stopWaitingTime = Long.MAX_VALUE;
+      }
+    }
+    catch (Exception e)
+    {
+      // This shouldn't happen, but if it does then ignore it.
+      stopWaitingTime = System.currentTimeMillis() + 60000;
+    }
+
+
+    // Operate in a loop, printing out any applicable log messages and waiting
+    // for the target file to be removed.
+    byte[] logBuffer = new byte[8192];
+    while (System.currentTimeMillis() < stopWaitingTime)
+    {
+      if (logFile != null)
+      {
+        try
+        {
+          while (logFile.length() > logFileOffset)
+          {
+            int bytesRead = logFile.read(logBuffer);
+            if (bytesRead > 0)
+            {
+              System.out.write(logBuffer, 0, bytesRead);
+              System.out.flush();
+              logFileOffset += bytesRead;
+            }
+          }
+        }
+        catch (Exception e)
+        {
+          // We'll just ignore this.
+        }
+      }
+
+
+      if (! targetFile.exists())
+      {
+        break;
+      }
+      else
+      {
+        try
+        {
+          Thread.sleep(10);
+        } catch (InterruptedException ie) {}
+      }
+    }
+
+
+    if (targetFile.exists())
+    {
+      return EXIT_CODE_TIMEOUT;
+    }
+    else
+    {
+      return EXIT_CODE_SUCCESS;
+    }
+  }
+}
+
diff --git a/opendj-sdk/opends/src/server/org/opends/server/util/MultiOutputStream.java b/opendj-sdk/opends/src/server/org/opends/server/util/MultiOutputStream.java
new file mode 100644
index 0000000..62d6bdd
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/util/MultiOutputStream.java
@@ -0,0 +1,195 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying * information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Portions Copyright 2006 Sun Microsystems, Inc.
+ */
+package org.opends.server.util;
+
+
+
+import java.io.OutputStream;
+
+import static org.opends.server.loggers.Debug.*;
+
+
+
+/**
+ * This class defines a simple {@code OutputStream} object that can be used to
+ * write all messages to multiple targets at the same time, much like the UNIX
+ * "tee" command.  Note that this class will never throw any exceptions
+ */
+public final class MultiOutputStream
+       extends OutputStream
+{
+  /**
+   * The fully-qualified name of this class for debugging purposes.
+   */
+  private static final String CLASS_NAME =
+       "org.opends.server.util.MultiOutputStream";
+
+
+
+  // The set of target output streams to which all messages will be written;
+  private final OutputStream[] targetStreams;
+
+
+
+  /**
+   * Creates a new {@code MultiOutputStream} object that will write all messages
+   * to all of the target streams.
+   *
+   * @param  targetStreams  The set of print streams to which all messages
+   *                        should be written.  This must not be {@code null},
+   *                        nor may it contain any {@code null} elements.
+   */
+  public MultiOutputStream(OutputStream... targetStreams)
+  {
+    assert debugConstructor(CLASS_NAME, String.valueOf(targetStreams));
+
+    Validator.ensureNotNull(targetStreams);
+
+    this.targetStreams = targetStreams;
+  }
+
+
+
+  /**
+   * Closes all of the underlying output streams.
+   */
+  public void close()
+  {
+    assert debugEnter(CLASS_NAME, "close");
+
+    for (OutputStream s : targetStreams)
+    {
+      try
+      {
+        s.close();
+      }
+      catch (Exception e)
+      {
+        assert debugException(CLASS_NAME, "close", e);
+      }
+    }
+  }
+
+
+
+  /**
+   * Flushes all of the underlying output streams.
+   */
+  public void flush()
+  {
+    assert debugEnter(CLASS_NAME, "flush");
+
+    for (OutputStream s : targetStreams)
+    {
+      try
+      {
+        s.flush();
+      }
+      catch (Exception e)
+      {
+        assert debugException(CLASS_NAME, "flush", e);
+      }
+    }
+  }
+
+
+
+  /**
+   * Writes the contents of the provided byte array to all of the underlying
+   * output streams.
+   *
+   * @param  b  The byte array containing the data to be written.
+   */
+  public void write(byte[] b)
+  {
+    assert debugEnter(CLASS_NAME, "write", "byte[" + b.length + "]");
+
+    for (OutputStream s : targetStreams)
+    {
+      try
+      {
+        s.write(b);
+      }
+      catch (Exception e)
+      {
+        assert debugException(CLASS_NAME, "write", e);
+      }
+    }
+  }
+
+
+
+  /**
+   * Writes the specified portion of the provided byte array to all of the
+   * underlying output streams.
+   *
+   * @param  b    The byte array containing the data to be written.
+   * @param  off  The position at which the data to write begins in the array.
+   * @param  len  The number of bytes to b written.
+   */
+  public void write(byte[] b, int off, int len)
+  {
+    assert debugEnter(CLASS_NAME, "write", "byte[" + b.length + "]");
+
+    for (OutputStream s : targetStreams)
+    {
+      try
+      {
+        s.write(b, off, len);
+      }
+      catch (Exception e)
+      {
+        assert debugException(CLASS_NAME, "write", e);
+      }
+    }
+  }
+
+
+
+  /**
+   * Writes the specified byte to the set of target output streams.
+   *
+   * @param  b  The byte to be written.
+   */
+  public void write(int b)
+  {
+    assert debugEnter(CLASS_NAME, "write", StaticUtils.byteToHex((byte) b));
+
+    for (OutputStream s : targetStreams)
+    {
+      try
+      {
+        s.write(b);
+      }
+      catch (Exception e)
+      {
+        assert debugException(CLASS_NAME, "write", e);
+      }
+    }
+  }
+}
+

--
Gitblit v1.10.0