mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

jvergara
22.30.2007 b54e25e8af0e73b7ddaca4eaec088803ea6a7e4f
Fix for Issues #1025 and #1248 ('stop-ds.bat should be able to stop server even if LDAP port' and 'cannot stop server through status panel').

The goal of these changes is to be able to have exactly the same user interface in Windows and Unix to stop the server. In windows we force the user to provide LDAP credentials even if the command is going to be run locally. The goal is to allow to stop the server using only system credentials (as we do in UNIX) when the user does not provide arguments when calling stop-ds.bat.

In order to do this I have written some native code. This native code is called when we start the server to:
1. Launch the java process and get the associated PID.
2. Create a server.pid file as we do for UNIX systems to store the PID of the process.

The native code that stops the server reads the PID file contents and tries to stop the process associated with the PID.

In order to allow the users to be able to build the product with independence of the platform, the binaries will be included with the source code. The code used to generate these binaries will also be provided.

I have generated 1 executable called winlauncher.exe. The binaries will be committed in the source tree under lib (with activation.jar and mail.jar). They will also be installed under <server root>\lib.

The native code is in the files winlauncher.c and winlauncher.h. These files are placed under the new directory build-tools/src/windows.

I have tried to keep the native code simple and leave as much logic as I could into the batch files (for instance everything related to the discovery of the java binaries) so that the administrators can play with them.

A README file has been also been included to explain how to generate the binaries.

Extras:
When we call start-ds from the command line, the server will not stop when the command prompt window is closed (unless start-ds was called to run in not-detached mode). The next step is to register DS as a service to avoid the server to be stopped when the user logs out.

When we call setup (with no arguments) or the statuspanel the generated process (and windows) will no longer get killed when the command prompt window is killed.

When the user double-clicks on the setup.bat or the statuspanel.bat files, the command prompt window only appears briefly. Today when we do this a command prompt window stays open until we close setup or the status panel window.
4 files added
10 files modified
1205 ■■■■■ changed files
opends/build-tools/src/windows/README 72 ●●●●● patch | view | raw | blame | history
opends/build-tools/src/windows/winlauncher.c 561 ●●●●● patch | view | raw | blame | history
opends/build-tools/src/windows/winlauncher.h 37 ●●●●● patch | view | raw | blame | history
opends/lib/winlauncher.exe patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/QuickSetup.java 35 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties 53 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/ui/DirectoryManagerAuthenticationDialog.java 2 ●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/uninstaller/UninstallCli.java 305 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/uninstaller/UninstallLauncher.java 10 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/uninstaller/Uninstaller.java 4 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/uninstaller/UserUninstallData.java 42 ●●●●● patch | view | raw | blame | history
opends/src/statuspanel/org/opends/statuspanel/StatusPanelController.java 65 ●●●●● patch | view | raw | blame | history
opends/src/statuspanel/org/opends/statuspanel/resources/Resources.properties 7 ●●●● patch | view | raw | blame | history
opends/src/statuspanel/org/opends/statuspanel/ui/LoginDialog.java 12 ●●●● patch | view | raw | blame | history
opends/build-tools/src/windows/README
New file
@@ -0,0 +1,72 @@
/*
 * 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 2007 Sun Microsystems, Inc.
 */
 WHAT is winlauncher.exe
 ========================
 winlauncher.exe is a small windows executable that is intended to be used by
 the command line files to perform certain operations.  It is not intended to
 be a final user interface and that is one of the reasons why is placed under
 the lib subdirectory.
 See the comments in winlauncher.c file for more information.
 INSTRUCTIONS TO COMPILE winlauncher
 ========================
 Using Visual C++ and the command line  you must set your environment
 variables to point to your Visual Studio install.  You can set the environment
 variables by changing to the \bin subdirectory of your Visual C++ installation
 and running the VCVARS32.bat batch file.
 This will basically update your PATH, INCLUDE and LIB environment variables
 to point to the correct paths of your Visual Studio install.
Go to the directory where the source files winlauncher.c and winlauncher.h are
and launch the following command:
> cl winlauncher.c
This will generate the binary winlauncher.exe.
************************
Using Visual C++ graphical interface you just must to Create a Project and add
winlauncher.c and winlauncher.h to the project.   You can build winlauncher.c
and then winlauncher.exe with the commands in the menu 'Build'.
************************
Using gcc (for instance you can get it with the open source project MinGW -
Minimalist GNU for Windows), you must include the directory where the gcc
binaries are on your PATH environment variable.
Go to the directory where the source files winlauncher.c and winlauncher.h are
and launch the following command:
> gcc winlauncher.c -o winlauncher.exe
This will generate the binary winlauncher.exe.
opends/build-tools/src/windows/winlauncher.c
New file
@@ -0,0 +1,561 @@
/*
 * 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 2007 Sun Microsystems, Inc.
 */
#include "winlauncher.h"
// ----------------------------------------------------
// Generates the pid file name for a given instanceDir.
// Returns TRUE if the command name could be initiated and
// FALSE otherwise (buffer overflow because the resulting
// string is bigger than maxSize).
// ----------------------------------------------------
BOOL getPidFile(const char* instanceDir, char* pidFile, unsigned int maxSize)
{
    BOOL returnValue;
    char* relativePath = "\\logs\\server.pid";
    if ((strlen(relativePath) + strlen(instanceDir)) < maxSize)
    {
        sprintf(pidFile, "%s\\logs\\server.pid", instanceDir);
        returnValue = TRUE;
    }
    else
    {
        returnValue = FALSE;
    }
    return returnValue;
} // getPidFile
// ----------------------------------------------------
// Tells whether a file exists or not.  If the file exists
// returns TRUE and FALSE otherwise.
// ----------------------------------------------------
BOOL fileExists(const char *fileName)
{
   struct stat finfo;
   BOOL returnValue = FALSE;
   if(stat(fileName, &finfo) < 0)
   {
      returnValue = FALSE;
   }
   else
   {
      returnValue = TRUE;
   }
   return returnValue;
} // fileExists
// ----------------------------------------------------
// Deletes the pid file for a given instance directory.
// If the file could be deleted (or it does not exist)
// returns TRUE and FALSE otherwise.
// ----------------------------------------------------
BOOL deletePidFile(const char* instanceDir)
{
    BOOL returnValue = FALSE;
    char pidFile[PATH_SIZE];
    int nTries = 10;
    // Sometimes the lock on the system in windows takes time to be released.
    if (getPidFile(instanceDir, pidFile, PATH_SIZE))
    {
        while (fileExists(pidFile) && (nTries > 0) && !returnValue)
        {
            if (remove(pidFile) == 0)
            {
                returnValue = TRUE;
            }
            else
            {
                Sleep(500);
                nTries--;
            }
        }
    }
    return returnValue;
}  // deletePidFile
// ----------------------------------------------------
// Returns the pid stored in the pid file for a given server
// instance directory.  If the pid could not be retrieved
// it returns 0.
// ----------------------------------------------------
int getPid(const char* instanceDir)
{
    int returnValue;
    char pidFile[PATH_SIZE];
    FILE *f;
    char buf[BUF_SIZE];
    int read;
    if (getPidFile(instanceDir, pidFile, PATH_SIZE))
    {
        if ((f = fopen(pidFile, "r")) != NULL)
        {
            read = fread(buf, 1, sizeof(buf),f);
        }
        fclose(f);
        returnValue = (int)strtol(buf, (char **)NULL, 10);
    }
    else
    {
        returnValue = 0;
    }
    return returnValue;
}  // getPid
// ----------------------------------------------------
// Kills the process associated with the provided pid.
// Returns TRUE if the process could be killed or the
// process did not exist and false otherwise.
// ----------------------------------------------------
BOOL killProcess(int pid)
{
    BOOL processDead;
    HANDLE procHandle = OpenProcess(
       PROCESS_TERMINATE               // to terminate the process
       | PROCESS_QUERY_INFORMATION,    // to get exit code
       FALSE,                          // handle is not inheritable
       pid
       );
    if (procHandle == NULL)
    {
       // process already dead
       processDead = TRUE;
    }
    else
    {
       if (!TerminateProcess(procHandle, 0))
       {
          // failed to terminate the process
          processDead = FALSE;
       }
       else
       {
          // wait for the process to end.
          DWORD exitCode;
          int nTries = 20;
          processDead = FALSE;
          while ((nTries > 0) && !processDead)
          {
             GetExitCodeProcess(procHandle, &exitCode);
             if (exitCode == STILL_ACTIVE)
             {
                 // process is still alive, let's wait 1 sec and loop again
                 Sleep(1000);
                 nTries--;
             }
             else
             {
                 processDead = TRUE;
             }
          }
       }
       CloseHandle(procHandle);
    }
    return processDead;
} // killProcess
// ----------------------------------------------------
// Creates the pid file for a given instance directory.
// and a given pid.
// If the file could be created returns TRUE and FALSE
// otherwise.
// ----------------------------------------------------
BOOL createPidFile(const char* instanceDir, int pid)
{
    BOOL returnValue = FALSE;
    char pidFile[PATH_SIZE];
    FILE *f;
    if (getPidFile(instanceDir, pidFile, PATH_SIZE))
    {
        if ((f = fopen(pidFile, "w")) != NULL)
        {
            fprintf(f, "%d", pid);
            fclose (f);
            returnValue = TRUE;
        }
        else
        {
            returnValue = FALSE;
        }
    }
    else
    {
        returnValue = FALSE;
    }
    return returnValue;
}  // createPidFile
// ----------------------------------------------------
// Function used to create a process with the given command.
// The information about the process is stored in procInfo.
// The function returns TRUE if the process could be created
// and FALSE otherwise.
// ----------------------------------------------------
BOOL createChildProcess(char* command, BOOL background,
PROCESS_INFORMATION* procInfo)
{
   BOOL createOk;
   STARTUPINFO startInfo; // info to pass to the new process
   DWORD processFlag; // background process flag
   // reset process info first
   ZeroMemory(procInfo, sizeof(PROCESS_INFORMATION));
   // initialize handles to pass to the child process
   ZeroMemory(&startInfo, sizeof(STARTUPINFO));
   startInfo.cb = sizeof(STARTUPINFO);
   startInfo.dwFlags |= STARTF_USESTDHANDLES;  // use handles above
   // Create the child process
   processFlag = background == TRUE ? DETACHED_PROCESS : 0;
   createOk = CreateProcess(
      NULL,          // application name
      command,       // command line
      NULL,          // process security attributes
      NULL,          // primary thread security attributes
      TRUE,          // handles are inherited
      processFlag,   // creation flags
      NULL,          // use parent's environment
      NULL,          // use parent's current directory
      &startInfo,    // STARTUPINFO pointer
      procInfo       // receives PROCESS_INFORMATION
      );
   if (!createOk)
   {
      fprintf(stderr, "Failed to create child process [%s]\n", command);
   }
   return createOk;
} // createChildProcess
// ----------------------------------------------------
// Function used to launch a process for the given command
// If the process could be created it returns the pid of
// the created process and -1 otherwise.
// ----------------------------------------------------
int spawn(const char* command)
{
    DWORD childPid; // child's pid
    PROCESS_INFORMATION procInfo; // info on the new process
    BOOL createOk;
    createOk = createChildProcess((char*)command, TRUE, &procInfo);
    if(createOk)
    {
        childPid = procInfo.dwProcessId;
    }
    if (childPid != -1)
    {
        return childPid;
    }
    else
    {
        return -1;
    }
} // spawn
// ----------------------------------------------------
// Elaborate the command line: "cmd arg1 arg2..."
// If an arg contains white space(s) then add " " to protect them
// but don't do it for option (an option starts with -).
// Returns TRUE if the command name could be initiated and
// FALSE otherwise (buffer overflow because the resulting
// string is bigger than maxSize).
// ----------------------------------------------------
BOOL getCommandLine(const char* argv[], char* command, unsigned int maxSize)
{
   int curCmdInd = 0;
   int i = 0;
   BOOL overflow = FALSE;
   while ((argv[i] != NULL) && !overflow)
   {
      const char* curarg = argv[i++];
      if (i > 1)
      {
          if (curCmdInd + strlen(" ") < maxSize)
          {
              sprintf (&command[curCmdInd], " ");
              curCmdInd = strlen(command);
          }
          else
          {
              overflow = TRUE;
          }
      }
      if (curarg[0] != '\0')
      {
         int argInd = 0;
         if (curarg[0] == '"')
         {
            // there is a quote: no need to add extra quotes
         }
         else
         {
             while (curarg[argInd] != ' '
                && curarg[argInd] != '\0'
                && curarg[argInd] != '\n')
            {
               argInd++;
            }
         }
         if (curarg[0] != '"' && curarg[argInd] == ' ')
         {
             if (curCmdInd + strlen("\"\"") + strlen(curarg) < maxSize)
             {
                 // no begining quote and white space inside => add quotes
                 sprintf (&command[curCmdInd], "\"%s\"", curarg);
                 curCmdInd = strlen (command);
             }
             else
             {
                 overflow = TRUE;
             }
         }
         else
         {
             if (curCmdInd + strlen(curarg) < maxSize)
             {
                 // no white space or quotes detected, keep the arg as is
                 sprintf (&command[curCmdInd], "%s", curarg);
                 curCmdInd = strlen (command);
             }
             else
             {
                 overflow = TRUE;
             }
         }
      } else {
            if (curCmdInd + strlen("\"\"") < maxSize)
            {
                sprintf (&command[curCmdInd], "\"\"");
                curCmdInd = strlen (command);
            }
            else
            {
                overflow = TRUE;
            }
      }
   }
   return !overflow;
} // getCommandLine
// ----------------------------------------------------
// Function called when we want to start the server.
// This function expects the following parameter to be passed:
// the directory of the server we want to start and the
// command line (and its argumets) that we want to execute (basically the java
// command that we want to start the server).  The main reasons
// to have the command line passed are:
// 1. Keep the native code as minimal as possible.
// 2. Allow the administrator some flexibility in the way the
// server is started by leaving most of the logic in the command-line.
//
// This approach makes things to be closer between what is proposed
// in windows and in UNIX systems.
//
// If the instance could be started the code will write the pid of the process
// of the server in file that can be used for instance to stop the server
// (see stop.c).
//
// Returns the pid of the process of the instance if it could be started and -1
// otherwise.
// ----------------------------------------------------
int start(const char* instanceDir, char* argv[])
{
    int returnValue;
    int childPid;
    char command[COMMAND_SIZE];
    if (getCommandLine(argv, command, COMMAND_SIZE))
    {
        childPid = spawn(command);
        if (childPid > 0)
        {
            createPidFile(instanceDir, childPid);
            returnValue = childPid;
        }
        else
        {
            returnValue = -1;
        }
    }
    else
    {
        returnValue = -1;
    }
    return returnValue;
} // start
// ----------------------------------------------------
// Function called when we want to stop the server.
// This code is called by the stop-ds.bat batch file to stop the server
// in windows.
// This function expects just one parameter to be passed
// to the executable: the directory of the server we want
// to stop.
//
// If the instance could be stopped the pid file
// is removed.  This is done for security reasons: if we do
// not delete the pid file and the old pid of the process
// is used by a new process, when we call again this executable
// the new process will be killed.
// Note: even if the code in the class org.opends.server.core.DirectoryServer
// sets the pid file to be deleted on the exit of the process
// the file is not always deleted.
//
// Returns 0 if the instance could be stopped using the
// pid stored in a file of the server installation and
// -1 otherwise.
// ----------------------------------------------------
int stop(const char* instanceDir)
{
    int returnCode = -1;
    int childPid;
    childPid = getPid(instanceDir);
    if (childPid != 0)
    {
        if (killProcess(childPid))
        {
            returnCode = 0;
            deletePidFile(instanceDir);
        }
    }
    return returnCode;
} // stop
// ----------------------------------------------------
// Function called when we want to launch simply a process without attaching
// it to any command prompt (the difference with start is basically that here
// we create no pid file).
// This code is called for instance by the statuspanel.bat batch file to launch
// the status panel on windows.
// The goal of these methods is:
// Be able to launch batch files with double-click and not having a
// prompt-window associated with it.
// Launch batch files from the prompt that generate a java process that does not
// block the prompt and that keeps running even if the prompt window is closed.
//
// This function expects the following parameter to be passed:
// the directory of the server we want to start and the
// command line that we want to execute (basically the java
// command that we want to display the status panel).  The main reasons
// to have the command line passed are:
// 1. Keep the native code as minimal as possible.
// 2. Allow the administrator some flexibility in the way the
// server is started by leaving most of the logic in the command-line.
//
// Returns the pid of the process associated with the command if it could be
// launched and -1 otherwise.
// ----------------------------------------------------
int launch(char* argv[])
{
    int returnValue;
    char command[COMMAND_SIZE];
    if (getCommandLine(argv, command, COMMAND_SIZE))
    {
        returnValue = spawn(command);
    }
    else
    {
        returnValue = -1;
    }
    return returnValue;
} // launch
// ----------------------------------------------------
// main function called by the executable.  This code is
// called by the start-ds.bat, stop-ds.bat and statuspanel.bat batch files.
//
// The code assumes that the first passed argument is the subcommand to be
// executed and the second argument the directory of the server.  The rest
// of the arguments are the arguments specific to each subcommand (see the
// comments for the functions start, stop and launch).
// ----------------------------------------------------
int main(int argc, char* argv[])
{
    int returnCode;
    char* subcommand = argv[1];
    char* instanceDir = argv[2];
    argv += 3;
    if (strcmp(subcommand, "start") == 0)
    {
        returnCode = start(instanceDir, argv);
    }
    else if (strcmp(subcommand, "stop") == 0)
    {
        returnCode = stop(instanceDir);
    }
    else if (strcmp(subcommand, "launch") == 0)
    {
        returnCode = launch(argv);
    }
    else
    {
        fprintf(stderr, "Unknown subcommand: [%s]", subcommand);
        returnCode = -1;
    }
    return returnCode;
}
opends/build-tools/src/windows/winlauncher.h
New file
@@ -0,0 +1,37 @@
/*
 * 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 2007 Sun Microsystems, Inc.
 */
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <process.h>
#include <windows.h>
#define PATH_SIZE 1024
#define BUF_SIZE 1024
#define COMMAND_SIZE 2048
opends/lib/winlauncher.exe
Binary files differ
opends/src/quicksetup/org/opends/quicksetup/QuickSetup.java
@@ -54,7 +54,6 @@
import org.opends.quicksetup.installer.offline.OfflineInstaller;
import org.opends.quicksetup.installer.webstart.WebStartDownloader;
import org.opends.quicksetup.installer.webstart.WebStartInstaller;
import org.opends.quicksetup.ui.DirectoryManagerAuthenticationDialog;
import org.opends.quicksetup.ui.QuickSetupDialog;
import org.opends.quicksetup.ui.UIFactory;
import org.opends.quicksetup.uninstaller.UninstallProgressDescriptor;
@@ -463,42 +462,16 @@
            }
            else
            {
              if (Utils.isUnix())
              if (displayConfirmation(
                      getMsg("confirm-uninstall-server-running-msg"),
                      getMsg("confirm-uninstall-server-running-title")))
              {
                if (displayConfirmation(
                    getMsg("confirm-uninstall-server-running-unix-msg"),
                    getMsg("confirm-uninstall-server-running-unix-title")))
                {
                  getUserUninstallData().setStopServer(true);
                  launchUninstallation();
                  setCurrentStep(nextStep(cStep));
                }
                else
                {
                  getUserUninstallData().setStopServer(false);
                }
              }
              else
              } else
              {
                DirectoryManagerAuthenticationDialog dlg =
                  new DirectoryManagerAuthenticationDialog(
                      getDialog().getFrame(), installStatus);
                dlg.setModal(true);
                dlg.packAndShow();
                if (dlg.isCancelled())
                {
                  getUserUninstallData().setStopServer(false);
                }
                else
                {
                  getUserUninstallData().setStopServer(dlg.getStopServer());
                  getUserUninstallData().setDirectoryManagerDn(
                      dlg.getDirectoryManagerDn());
                  getUserUninstallData().setDirectoryManagerPwd(
                      dlg.getDirectoryManagerPwd());
                  launchUninstallation();
                  setCurrentStep(nextStep(cStep));
                }
              }
            }
          }
opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties
@@ -69,22 +69,7 @@
#
# Uninstall command line messages
#
uninstall-launcher-usage-windows=This utility may be used to uninstall the \
Directory Server.\n\Usage:  {0} {options}\n        where {options} include:\n\
--cli\n\    Specifies to use the command line uninstall.  If not specified the \
graphical\n\    interface will be launched.\n\
-H  or   --help\n    Displays usage information for this program.\n\n\
The following options will only be taken into account if the option --cli \n\
(command line) is specified\n\
-D {rootDN}  or   --rootUserDN {rootDN}\n    Specifies the DN of the \
Administrative User (Directory Manager) of the Directory Server.\n\
-w {password}  or   --rootUserPassword {password}\n    Specifies the password \
of the Administrative User (Directory Manager) of the Directory Server.\n\
-W {filename}  or   --rootUserPasswordFile {filename}\n    Specifies the path \
to a file containing the password for the Administrative\n\    User \
of the Directory Server.\n\
-s  or   --silentUninstall\n    Perform a silent uninstall.
uninstall-launcher-usage-unix=This utility may be used to uninstall the \
uninstall-launcher-usage=This utility may be used to uninstall the \
Directory Server.\n\
Usage:  {0} {options}\n        where {options} include:\n\
--cli\n\    Specifies to use the command line uninstall.  If not specified the \
@@ -97,22 +82,7 @@
uninstall-launcher-launching-cli=Launching command line uninstall...
uninstall-launcher-gui-launched-failed=\n\nThe graphical Uninstall launch \
failed.\n\nLaunching command line Uninstall...
cli-uninstall-root-user-dn-not-provided=You must provide a value for the \
option -D (or --rootUserDN)
cli-uninstall-root-user-pwd-not-provided=You must provide a value for the \
option -w (or --rootUserPassword)
cli-uninstall-root-user-pwd-file-not-provided=You must provide a value for the \
option -W (or --rootUserPasswordFile)
cli-uninstall-data-missing-to-shutdown-server=The server is currently running \
and must be stopped before uninstallation can \
continue.  You must provide the Authentication DN (option -D or \
--rootUserDN) and the password (option -w or --rootUserPassword) or the file \
containing the password (option -W or --rootUserPasswordFile) of the \
Administrative User.
cli-uninstall-unknown-argument=Unknown argument {0}
cli-uninstall-pwd-and-pwd-file-provided=You cannot provide Authentication User \
Password (-w or --rootUserPassword) and Authentication User Password File \
(-W or --rootUserPasswordFile) at the same time.
cli-uninstall-yes-short=y
cli-uninstall-yes-long=yes
cli-uninstall-no-short=n
@@ -145,21 +115,7 @@
permanently delete the files?
cli-uninstall-confirm-delete-files=The files will be permanently deleted, are \
you sure you want to continue?
cli-uninstall-stop-authentication-generic-prompt1=The server is currently \
running and must be stopped before uninstallation can continue.
cli-uninstall-stop-authentication-generic-prompt2=You must provide an \
Administrative User DN and password to stop the server.
cli-uninstall-error-reading-pwd-file=Could not read the password from \
file {0}.  Check that the file path is correct, that you have access rights to \
it and that it contains a password.
cli-uninstall-prompt-dn=Administrative User DN
cli-uninstall-prompt-pwd=Administrative User Password:
cli-uninstall-server-stopped=The Server is Stopped.
cli-uninstall-cannot-connect-to-shutdown-with-cause=Could not connect to the \
Directory Server with the provided credentials.  The possible causes for this \
are:\n{0}
cli-uninstall-cannot-connect-to-shutdown-without-cause=Could not connect to \
the Directory Server with the provided credentials.
#
# Dialog titles
@@ -205,12 +161,12 @@
All selected files will be permanently deleted, are you sure you\n\
want to continue?
confirm-uninstall-server-not-running-title=Confirm Uninstall
confirm-uninstall-server-running-unix-msg=Server is Running\n\
confirm-uninstall-server-running-msg=Server is Running\n\
The OpenDS server is currently running and must be stopped before\n\
uninstallation can continue. Do you want the uninstaller to stop\n\
the server for you and continue with the uninstall? If you click\n\
No, you will need to stop the server manually to continue.
confirm-uninstall-server-running-unix-title=Server is Running
confirm-uninstall-server-running-title=Server is Running
#
@@ -236,7 +192,8 @@
error-browser-close-button-tooltip=Close this window
#
# Dialog asking Directory manager credentials to shutdown server in Windows.
# Dialog asking Directory manager credentials to shutdown server through
# Protocol.
#
shutdown-directory-manager-dialog-title=Authentication Required
shutdown-directory-manager-dialog-msg=<b>Directory Server is Running</b><br>\
opends/src/quicksetup/org/opends/quicksetup/ui/DirectoryManagerAuthenticationDialog.java
@@ -57,7 +57,7 @@
/**
 * This class is a dialog that appears when the user must provide authentication
 * of Directory Manager to connect to the Directory Server in order to be
 * able to do a shutdown. This is currently required for Windows.
 * able to do a shutdown.
 */
public class DirectoryManagerAuthenticationDialog extends JDialog
{
opends/src/quicksetup/org/opends/quicksetup/uninstaller/UninstallCli.java
@@ -31,7 +31,6 @@
import java.io.ByteArrayOutputStream;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Set;
import org.opends.quicksetup.CurrentInstallStatus;
@@ -581,166 +580,19 @@
  {
    boolean cancelled = false;
    String errorMsg = null;
    if (installStatus.isServerRunning())
    {
      if (Utils.isWindows())
      {
        if (silentUninstall)
        {
          String dn = userData.getDirectoryManagerDn();
          String pwd = userData.getDirectoryManagerPwd();
          if ((dn == null) || (pwd == null))
          {
            errorMsg = getMsg("cli-uninstall-data-missing-to-shutdown-server");
          }
          else
          {
            if (!canConnectAsAdministrativeUser(installStatus.getLdapUrl(),
                userData.getDirectoryManagerDn(),
                userData.getDirectoryManagerPwd()))
            {
              errorMsg = getErrorMsgConnecting(dn, pwd, installStatus);
            }
          }
          if (errorMsg != null)
          {
            throw new UserUninstallDataException(null, errorMsg);
          }
        }
        else
        {
          /* Ask for the Directory Manager Dn and password if they were not
           * provided.
           */
          boolean askForDn = userData.getDirectoryManagerDn() == null;
          boolean askForPwd = userData.getDirectoryManagerPwd() == null;
          boolean prompted = false;
          if (!askForDn && !askForPwd)
          {
            String dn = userData.getDirectoryManagerDn();
            String pwd = userData.getDirectoryManagerPwd();
            if (!canConnectAsAdministrativeUser(installStatus.getLdapUrl(),
                dn, pwd))
            {
              System.out.println(LINE_SEPARATOR+LINE_SEPARATOR+getMsg(
              "cli-uninstall-stop-authentication-generic-prompt1"));
              System.out.println(getErrorMsgConnecting(dn, pwd, installStatus));
              askForDn = true;
              askForPwd = true;
            }
            else
            {
              String[] validValues = {
                  getMsg("cli-uninstall-yes-short"),
                  getMsg("cli-uninstall-no-short"),
                  getMsg("cli-uninstall-yes-long"),
                  getMsg("cli-uninstall-no-long")
              };
              String answer = promptConfirm(
                  getMsg("cli-uninstall-confirm-stop"),
                  getMsg("cli-uninstall-yes-long"), validValues);
              if (getMsg("cli-uninstall-no-short").equalsIgnoreCase(answer) ||
                  getMsg("cli-uninstall-no-long").equalsIgnoreCase(answer))
              {
                cancelled = true;
              }
            }
          }
          else
          {
            System.out.println(
                getMsg("cli-uninstall-stop-authentication-generic-prompt1"));
          }
          while (askForDn || askForPwd)
          {
            if (!prompted)
            {
              System.out.println(
                getMsg("cli-uninstall-stop-authentication-generic-prompt2"));
            }
            if (askForDn)
            {
              String defaultDn = userData.getDirectoryManagerDn();
              if ((defaultDn == null) || !Utils.isDn(defaultDn))
              {
                Set<String> dns = installStatus.getDirectoryManagerDns();
                if (dns.size() > 0)
                {
                  defaultDn = dns.iterator().next();
                }
                else
                {
                  defaultDn = "cn=Directory Manager";
                }
              }
              userData.setDirectoryManagerDn(
                  promptForString(getMsg("cli-uninstall-prompt-dn"),
                  defaultDn));
              prompted = true;
            }
            if (askForPwd)
            {
              userData.setDirectoryManagerPwd(promptForPassword(
                  getMsg("cli-uninstall-prompt-pwd")));
              prompted = true;
            }
            String dn = userData.getDirectoryManagerDn();
            String pwd = userData.getDirectoryManagerPwd();
            if (!canConnectAsAdministrativeUser(installStatus.getLdapUrl(),
                dn, pwd))
            {
              if (installStatus.isServerRunning())
              {
                System.out.println(LINE_SEPARATOR+getErrorMsgConnecting(dn, pwd,
                    installStatus));
                askForDn = true;
                askForPwd = true;
              }
              else
              {
                /* The server was stopped while we asked the user to provide
                 * authentication.  Inform of this and return.
                 */
                System.out.println(
                    getMsg("cli-uninstall-server-stopped"));
                askForDn = false;
                askForPwd = false;
                /* Ask for confirmation to delete files */
                cancelled = !confirmDeleteFiles();
              }
            }
            else
            {
              askForDn = false;
              askForPwd = false;
              /* Ask for confirmation to stop server */
              cancelled = !confirmToStopServer();
            }
          }
        }
      }
      else
      {
        if (!silentUninstall)
        {
          /* Ask for confirmation to stop server */
          cancelled = !confirmToStopServer();
            /* Ask for confirmation to stop server */
            cancelled = !confirmToStopServer();
        }
      }
      if (!cancelled)
      {
        /* During all the confirmations, the server might be stopped. */
        userData.setStopServer(installStatus.isServerRunning());
      }
        if (!cancelled)
        {
            /* During all the confirmations, the server might be stopped. */
            userData.setStopServer(installStatus.isServerRunning());
        }
    }
    else
    {
@@ -754,63 +606,6 @@
    return cancelled;
  }
  /**
   * Commodity method providing a localized message when we cannot connect to
   * the server.
   * @param dn the DN used to connect to the server.
   * @param pwd the password used to connect to the server.
   * @param installStatus the CurrentInstallStatus object describing the
   * status of the installation.
   * @return a localized message when we cannot connect to the server.
   */
  private String getErrorMsgConnecting(String dn, String pwd,
      CurrentInstallStatus installStatus)
  {
    String msg;
    ArrayList<String> possibleCauses = new ArrayList<String>();
    if ("".equals(dn.trim()))
    {
      possibleCauses.add(getMsg("empty-directory-manager-dn"));
    }
    else if (!Utils.isDn(dn))
    {
      possibleCauses.add(getMsg("not-a-directory-manager-dn"));
    }
    else
    {
      boolean found = false;
      Iterator<String> it =
        installStatus.getDirectoryManagerDns().iterator();
      while (it.hasNext() && !found)
      {
        found = Utils.areDnsEqual(dn, it.next());
      }
      if (!found)
      {
        possibleCauses.add(getMsg("not-a-directory-manager-in-config"));
      }
    }
    if ("".equals(pwd))
    {
      possibleCauses.add(getMsg("empty-pwd"));
    }
    if (possibleCauses.size() > 0)
    {
      // Message with causes
      String[] arg = {
          Utils.getStringFromCollection(possibleCauses, "\n")
      };
      msg = getMsg("cli-uninstall-cannot-connect-to-shutdown-with-cause", arg);
    }
    else
    {
      // Generic message
      msg = getMsg("cli-uninstall-cannot-connect-to-shutdown-without-cause");
    }
    return msg;
  }
  /**
   * Returns <CODE>true</CODE> if this is a silent uninstall and
@@ -859,69 +654,6 @@
      {
        // Ignore
      }
      else if (Utils.isWindows() &&
          (args[i].equalsIgnoreCase("-D") ||
          args[i].equalsIgnoreCase("--rootUserDN")))
      {
        if (i+1 >= args.length)
        {
          errors.add(getMsg("cli-uninstall-root-user-dn-not-provided"));
        }
        else
        {
          if (args[i+1].indexOf("-") == 0)
          {
            errors.add(getMsg("cli-uninstall-root-user-dn-not-provided"));
          }
          else
          {
            userData.setDirectoryManagerDn(args[i+1]);
            i++;
          }
        }
      }
      else if (Utils.isWindows() &&
          (args[i].equals("-w") ||
          args[i].equalsIgnoreCase("--rootUserPassword")))
      {
        if (i+1 >= args.length)
        {
          errors.add(getMsg("cli-uninstall-root-user-pwd-not-provided"));
        }
        else
        {
          if (args[i+1].indexOf("-") == 0)
          {
            errors.add(getMsg("cli-uninstall-root-user-pwd-not-provided"));
          }
          else
          {
            directoryManagerPwd = args[i+1];
            i++;
          }
        }
      }
      else if (Utils.isWindows() &&
          (args[i].equals("-W") ||
          args[i].equalsIgnoreCase("--rootUserPasswordFile")))
      {
        if (i+1 >= args.length)
        {
          errors.add(getMsg("cli-uninstall-root-user-pwd-file-not-provided"));
        }
        else
        {
          if (args[i+1].indexOf("-") == 0)
          {
            errors.add(getMsg("cli-uninstall-root-user-pwd-file-not-provided"));
          }
          else
          {
            directoryManagerPwdFile = args[i+1];
            i++;
          }
        }
      }
      else
      {
        String[] arg = {args[i]};
@@ -929,29 +661,6 @@
      }
    }
    if ((directoryManagerPwdFile != null) && (directoryManagerPwd != null))
    {
      errors.add(getMsg("cli-uninstall-pwd-and-pwd-file-provided"));
    }
    else
    {
      String pwd;
      if (directoryManagerPwdFile != null)
      {
        pwd = readPwdFromFile(directoryManagerPwdFile);
        if (pwd == null)
        {
          String[] arg = {directoryManagerPwdFile};
          errors.add(getMsg("cli-uninstall-error-reading-pwd-file", arg));
        }
      }
      else
      {
        pwd = directoryManagerPwd;
      }
      userData.setDirectoryManagerPwd(pwd);
    }
    if (errors.size() > 0)
    {
      String msg = Utils.getStringFromCollection(errors,
opends/src/quicksetup/org/opends/quicksetup/uninstaller/UninstallLauncher.java
@@ -192,15 +192,7 @@
     * This is required because the usage message contains '{' characters that
     * mess up the MessageFormat.format method.
     */
    String msg;
    if (Utils.isWindows())
    {
      msg = getMsg("uninstall-launcher-usage-windows");
    }
    else
    {
      msg = getMsg("uninstall-launcher-usage-unix");
    }
    String msg = getMsg("uninstall-launcher-usage");
    msg = msg.replace("{0}", arg);
    System.err.println(msg);
  }
opends/src/quicksetup/org/opends/quicksetup/uninstaller/Uninstaller.java
@@ -637,10 +637,6 @@
    if (Utils.isWindows())
    {
      argList.add(Utils.getPath(getBinariesPath(), "stop-ds.bat"));
      argList.add("--bindDN");
      argList.add(userData.getDirectoryManagerDn());
      argList.add("--bindPassword");
      argList.add(userData.getDirectoryManagerPwd());
    } else
    {
      argList.add(Utils.getPath(getBinariesPath(), "stop-ds"));
opends/src/quicksetup/org/opends/quicksetup/uninstaller/UserUninstallData.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2006 Sun Microsystems, Inc.
 *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
 */
package org.opends.quicksetup.uninstaller;
@@ -48,9 +48,6 @@
  private boolean stopServer;
  private String directoryManagerDn;
  private String directoryManagerPwd;
  /**
   * Sets the database directories located outside the installation which must
   * be removed.
@@ -230,42 +227,5 @@
  {
    return stopServer;
  }
  /**
   * Sets the DN to be used to shut down the server in Windows.
   * @param directoryManagerDn the DN to be used to shut down the server in
   * Windows.
   */
  public void setDirectoryManagerDn(String directoryManagerDn)
  {
    this.directoryManagerDn = directoryManagerDn;
  }
  /**
   * Returns the DN to be used to shut down the server in Windows.
   * @return the DN to be used to shut down the server in Windows.
   */
  public String getDirectoryManagerDn()
  {
    return directoryManagerDn;
  }
  /**
   * Sets the password to be used to shut down the server in Windows.
   * @param password the password to be used to shut down the server in Windows.
   */
  public void setDirectoryManagerPwd(String password)
  {
    this.directoryManagerPwd = password;
  }
  /**
   * Returns the password to be used to shut down the server in Windows.
   * @return the password to be used to shut down the server in Windows.
   */
  public String getDirectoryManagerPwd()
  {
    return directoryManagerPwd;
  }
}
opends/src/statuspanel/org/opends/statuspanel/StatusPanelController.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
 */
package org.opends.statuspanel;
@@ -280,24 +280,7 @@
    }
    else
    {
      boolean stopServer = false;
      if (requiresAuthenticationToStop())
      {
        getLoginDialog().pack();
        Utils.centerOnComponent(getLoginDialog(), getStatusPanelDialog());
        getLoginDialog().setVisible(true);
        if (!getLoginDialog().isCancelled())
        {
          serverStatusPooler.setAuthentication(
              getLoginDialog().getDirectoryManagerDn(),
              getLoginDialog().getDirectoryManagerPwd());
          stopServer = confirmStop();
        }
      }
      else
      {
        stopServer = confirmStop();
      }
      boolean stopServer = confirmStop();
      if (stopServer)
      {
@@ -378,24 +361,7 @@
    }
    else
    {
      boolean restartServer = false;
      if (requiresAuthenticationToRestart())
      {
        getLoginDialog().pack();
        Utils.centerOnComponent(getLoginDialog(), getStatusPanelDialog());
        getLoginDialog().setVisible(true);
        if (!getLoginDialog().isCancelled())
        {
          serverStatusPooler.setAuthentication(
              getLoginDialog().getDirectoryManagerDn(),
              getLoginDialog().getDirectoryManagerPwd());
          restartServer = confirmRestart();
        }
      }
      else
      {
        restartServer = confirmRestart();
      }
      boolean restartServer = confirmRestart();
      if (restartServer)
      {
@@ -693,10 +659,6 @@
    if (Utils.isWindows())
    {
      argList.add(Utils.getPath(getBinariesPath(), "stop-ds.bat"));
      argList.add("--bindDN");
      argList.add(getLoginDialog().getDirectoryManagerDn());
      argList.add("--bindPassword");
      argList.add(getLoginDialog().getDirectoryManagerPwd());
    } else
    {
      argList.add(Utils.getPath(getBinariesPath(), "stop-ds"));
@@ -1217,25 +1179,4 @@
  {
    return serverStatusPooler.isAuthenticated();
  }
  private boolean requiresAuthenticationToStop()
  {
    boolean requireAuthentication;
    ServerStatusDescriptor desc = serverStatusPooler.getLastDescriptor();
    if (desc == null)
    {
      requireAuthentication = Utils.isWindows() && !isAuthenticated();
    }
    else
    {
      requireAuthentication = Utils.isWindows() &&
      (!isAuthenticated() || desc.getErrorMessage() != null);
    }
    return requireAuthentication;
  }
  private boolean requiresAuthenticationToRestart()
  {
    return requiresAuthenticationToStop();
  }
}
opends/src/statuspanel/org/opends/statuspanel/resources/Resources.properties
@@ -20,7 +20,7 @@
#
# CDDL HEADER END
#
#      Portions Copyright 2007 Sun Microsystems, Inc.
#      Portions Copyright 2006-2007 Sun Microsystems, Inc.
#
#
# This file contains the primary Directory Server configuration.  It must not
@@ -64,9 +64,6 @@
opends-version-label=OpenDS Version:
java-version-label=Java Version:
login-dialog-title=Authentication Required
login-dialog-windows-msg=You must provide an Administrative User DN and \
password to retrieve monitoring information and to be able to Stop and Restart \
the Directory Server.
server-started-label=Started
server-stopped-label=Stopped
server-starting-label=Starting
@@ -133,7 +130,7 @@
#
# Login Dialog
#
login-dialog-unix-msg=You must provide an Administrative User DN and password \
login-dialog-msg=You must provide an Administrative User DN and password \
to retrieve monitoring information.
login-dn-label=Administrative User DN:
login-dn-tooltip=Enter the distinguished name (DN) of the \
opends/src/statuspanel/org/opends/statuspanel/ui/LoginDialog.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
 */
package org.opends.statuspanel.ui;
@@ -168,16 +168,8 @@
    gbc.fill = GridBagConstraints.BOTH;
    gbc.gridwidth = GridBagConstraints.REMAINDER;
    gbc.insets.left = 0;
    String msg;
    String msg = getMsg("login-dialog-msg");
    if (Utils.isWindows())
    {
      msg = getMsg("login-dialog-windows-msg");
    }
    else
    {
      msg = getMsg("login-dialog-unix-msg");
    }
    JTextComponent textPane =
      UIFactory.makeHtmlPane(msg, UIFactory.INSTRUCTIONS_FONT);
    textPane.setOpaque(false);