From fa7c8f7b445628ebd7e6dde1535a06eb24f09d24 Mon Sep 17 00:00:00 2001
From: jvergara <jvergara@localhost>
Date: Fri, 04 May 2007 21:15:31 +0000
Subject: [PATCH] Fix a number of issues with David's approval:
---
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java | 12 +
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Launcher.java | 30 +-
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/InstallLauncher.java | 32 ++
opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/StatusPanelLauncher.java | 84 +++++++
opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/StatusLog.java | 89 ++++++++
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/uninstaller/Uninstaller.java | 8
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/uninstaller/UninstallLauncher.java | 32 ++
opendj-sdk/opends/src/server/org/opends/server/tools/ConfigureWindowsService.java | 17 +
opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/DatabaseDescriptor.java | 21 -
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgradeLauncher.java | 12
opendj-sdk/opends/lib/opends_service.exe | 0
opendj-sdk/opends/src/build-tools/windows/winlauncher.h | 2
opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/BaseDNDescriptor.java | 6
opendj-sdk/opends/src/build-tools/windows/service.c | 264 ++++++++++++++++++-----
opendj-sdk/opends/lib/winlauncher.exe | 0
opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/resources/Resources.properties | 4
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties | 12 +
17 files changed, 510 insertions(+), 115 deletions(-)
diff --git a/opendj-sdk/opends/lib/opends_service.exe b/opendj-sdk/opends/lib/opends_service.exe
index 6afb651..251dd05 100755
--- a/opendj-sdk/opends/lib/opends_service.exe
+++ b/opendj-sdk/opends/lib/opends_service.exe
Binary files differ
diff --git a/opendj-sdk/opends/lib/winlauncher.exe b/opendj-sdk/opends/lib/winlauncher.exe
index 35a9fb4..a3d6b45 100755
--- a/opendj-sdk/opends/lib/winlauncher.exe
+++ b/opendj-sdk/opends/lib/winlauncher.exe
Binary files differ
diff --git a/opendj-sdk/opends/src/build-tools/windows/service.c b/opendj-sdk/opends/src/build-tools/windows/service.c
index f476653..fe1ca4c 100644
--- a/opendj-sdk/opends/src/build-tools/windows/service.c
+++ b/opendj-sdk/opends/src/build-tools/windows/service.c
@@ -32,6 +32,7 @@
HANDLE _terminationEvent = NULL;
char *_instanceDir = NULL;
HANDLE _eventLog = NULL;
+char * _logFile = NULL;
BOOL DEBUG = FALSE;
@@ -73,15 +74,15 @@
} // registerServiceHandler
// ---------------------------------------------------
-// Debug utility. If the _eventLog is not NULL and the DEBUG variable is
-// TRUE send the message to the event log.
-// If the _eventLog is NULL and the DEBUG variable is TRUE send the message
-// to the standard output.
+// Debug utility.
+// If the _eventLog is NULL and the DEBUG variable is TRUE write the message
+// in a log file.
// ---------------------------------------------------
void debug(char* msg)
{
if (DEBUG == TRUE)
{
+ /*
if (_eventLog != NULL)
{
const char* args[1];
@@ -100,9 +101,55 @@
NULL // no war data
);
}
+ */
+
+ // Log to the file
+ FILE *fp;
+ if (_logFile == NULL)
+ {
+ char path [MAX_PATH];
+ if (_instanceDir != NULL)
+ {
+ int length = strlen(_instanceDir);
+ if ((length > 0) && (_instanceDir[length - 1] == '\\'))
+ {
+ sprintf(path, "%slogs\\windows-service.out", _instanceDir);
+ _logFile = strdup(path);
+ }
+ else
+ {
+ sprintf(path, "%s\\logs\\windows-service.out", _instanceDir);
+ _logFile = strdup(path);
+ }
+ }
+ else
+ {
+ char execName [MAX_PATH];
+ char instanceDir [MAX_PATH];
+ int length;
+ GetModuleFileName (
+ NULL,
+ execName,
+ MAX_PATH
+ );
+ length = strlen(execName) - strlen("lib\\opends_service.exe");
+ if (length > 0)
+ {
+ strncpy(instanceDir, execName, length);
+ instanceDir[length] = '\0';
+ sprintf(path, "%slogs\\windows-service.out", instanceDir);
+ _logFile = strdup(path);
+ }
+ }
+ }
+ if ((_logFile != NULL) && ((fp = fopen(_logFile, "a")) != NULL))
+ {
+ fprintf(fp, "%s\n", msg);
+ fclose(fp);
+ }
else
{
- fprintf(stdout, "%s\n", msg);
+ fprintf(stdout, "Could not create log file.\n");
}
}
}
@@ -454,6 +501,7 @@
if(_locking(fd, LK_NBLCK, 1) != -1)
{
*running = FALSE;
+ _locking(fd, LK_UNLCK, 1);
}
else
{
@@ -472,12 +520,14 @@
}
else
{
+ debug("Could not open lock file.");
*running = FALSE;
returnValue = SERVICE_RETURN_ERROR;
}
}
else
{
+ debug("Lock file path is too long.");
*running = FALSE;
returnValue = SERVICE_RETURN_ERROR;
}
@@ -495,16 +545,21 @@
// init out params
char* relativePath = "\\bat\\start-ds.bat";
char command[COMMAND_SIZE];
+
if (strlen(relativePath)+strlen(_instanceDir)+1 < COMMAND_SIZE)
{
sprintf(command, "\"%s%s\" --windowsNetStart", _instanceDir, relativePath);
// launch the command
- if (spawn(command, FALSE) != 0)
+ if (spawn(command, FALSE) != -1)
{
// Try to see if server is really running
int nTries = 10;
BOOL running = FALSE;
+
+ debug("doStartApplication: the spawn of the process worked.");
+ debug("Command:");
+ debug(command);
// Wait to be able to launch the java process in order it to free the lock
// on the file.
Sleep(3000);
@@ -518,24 +573,31 @@
{
Sleep(2000);
}
+ nTries--;
}
if (running)
{
returnValue = SERVICE_RETURN_OK;
+ debug("doStartApplication: server running.");
}
else
{
returnValue = SERVICE_RETURN_ERROR;
+ debug("doStartApplication: server not running.");
}
}
else
{
+
returnValue = SERVICE_RETURN_ERROR;
+ debug("doStartApplication: spawn failed. Sent command:");
+ debug(command);
}
}
else
{
returnValue = SERVICE_RETURN_ERROR;
+ debug("doStartApplication: the command path name is too long.");
}
return returnValue;
} // doStartApplication
@@ -556,11 +618,14 @@
sprintf(command, "\"%s%s\" --windowsNetStop", _instanceDir, relativePath);
// launch the command
- if (spawn(command, FALSE) != 0)
+ if (spawn(command, FALSE) != -1)
{
// Try to see if server is really stopped
int nTries = 10;
BOOL running = TRUE;
+
+ debug("doStopApplication: the spawn of the process worked.");
+
// Wait to be able to launch the java process in order it to free the lock
// on the file.
Sleep(3000);
@@ -578,20 +643,25 @@
if (!running)
{
returnValue = SERVICE_RETURN_OK;
+ debug("doStopApplication: server stopped.");
}
else
{
returnValue = SERVICE_RETURN_ERROR;
+ debug("doStopApplication: server NOT stopped.");
}
}
else
{
returnValue = SERVICE_RETURN_ERROR;
+ debug("doStopApplication: spawn failed. Sent command:");
+ debug(command);
}
}
else
{
returnValue = SERVICE_RETURN_ERROR;
+ debug("doStopApplication: the command path name is too long.");
}
return returnValue;
} // doStopApplication
@@ -604,7 +674,7 @@
// The string stored in serviceBinPath looks like
// <SERVER_ROOT>/lib/service.exe start <_instanceDir>
// It is up to the caller of the function to allocate
-// at least MAX_PATH bytes in serviceBinPath.
+// at least COMMAND_SIZE bytes in serviceBinPath.
// The function returns SERVICE_RETURN_OK if we could create the binary
// path name and SERVICE_RETURN_ERROR otherwise.
// ---------------------------------------------------------------
@@ -625,6 +695,7 @@
{
// failed to get the path of the executable file
returnValue = SERVICE_RETURN_ERROR;
+ debug("Could not get the path of the executable file.\n");
}
else
{
@@ -632,11 +703,12 @@
{
// buffer was too small, executable name is probably not valid
returnValue = SERVICE_RETURN_ERROR;
+ debug("The name of the module file is too long.");
}
else
{
if (strlen(fileName) + strlen(" start ") + strlen(_instanceDir)
- < MAX_PATH)
+ < COMMAND_SIZE)
{
sprintf(serviceBinPath, "%s start \"%s\"", fileName,
_instanceDir);
@@ -645,6 +717,8 @@
{
// buffer was too small, executable name is probably not valid
returnValue = SERVICE_RETURN_ERROR;
+ fprintf(stdout,
+ "The name of the resulting windows service command is too long.\n");
}
}
}
@@ -657,7 +731,7 @@
// product. All commands are supposed to be unique because they have
// the instance dir as parameter.
//
-// The functions returns SERVICE_RETURN_OK if we could create a service name
+// The functions returns SERVICE_RETURN_OK if we could get a service name
// and SERVICE_RETURN_ERROR otherwise.
// The serviceName buffer must be allocated OUTSIDE the function and its
// minimum size must be of 256 (the maximum string length of a Service Name).
@@ -696,6 +770,11 @@
sprintf(serviceName, curService.serviceName);
returnValue = SERVICE_RETURN_OK;
}
+ else
+ {
+ debug("The service name found is too long:");
+ debug(curService.serviceName);
+ }
break;
}
}
@@ -811,18 +890,28 @@
void serviceMain(int argc, char* argv[])
{
// returned status
- char cmdToRun[MAX_PATH];
+ char cmdToRun[COMMAND_SIZE];
char serviceName[MAX_SERVICE_NAME];
ServiceReturnCode code;
// a checkpoint value indicate the progress of an operation
DWORD checkPoint = CHECKPOINT_FIRST_VALUE;
SERVICE_STATUS_HANDLE serviceStatusHandle;
+ debug("serviceMain called.");
+
code = createServiceBinPath(cmdToRun);
if (code == SERVICE_RETURN_OK)
{
code = getServiceName(cmdToRun, serviceName);
+ if (code != SERVICE_RETURN_OK)
+ {
+ debug("serviceMain: could not get service name.");
+ }
+ }
+ else
+ {
+ debug("serviceMain: failed to create service bin path.");
}
if (code == SERVICE_RETURN_OK)
@@ -835,6 +924,10 @@
{
_serviceStatusHandle = &serviceStatusHandle;
}
+ else
+ {
+ debug("serviceMain: failed to register service handler.");
+ }
}
@@ -978,15 +1071,17 @@
ServiceReturnCode code;
DWORD checkpoint;
BOOL running;
+ debug("serviceHandler called.");
switch (controlCode)
{
case SERVICE_CONTROL_SHUTDOWN:
// If system is shuting down then stop the service
// -> no break here
+ debug("serviceHandler: Shutdown.");
case SERVICE_CONTROL_STOP:
{
// update service status to STOP_PENDING
- debug("Stop called");
+ debug("serviceHandler: Stop.");
_serviceCurStatus = SERVICE_STOP_PENDING;
checkpoint = CHECKPOINT_FIRST_VALUE;
updateServiceStatus (
@@ -1042,39 +1137,44 @@
// Request to pause the service
// ----------------------------
case SERVICE_CONTROL_PAUSE:
- // not supported
- break;
+ // not supported
+ debug("serviceHandler: pause.");
+ break;
// Request to resume the service
// -----------------------------
case SERVICE_CONTROL_CONTINUE:
- // not supported
- break;
+ // not supported
+ debug("serviceHandler: continue.");
+ break;
// Interrogate the service status
// ------------------------------
case SERVICE_CONTROL_INTERROGATE:
- code = isServerRunning(&running);
- if (code != SERVICE_RETURN_OK)
- {
-
- }
- else if (running)
- {
- _serviceCurStatus = SERVICE_RUNNING;
- }
- else
- {
- _serviceCurStatus = SERVICE_STOPPED;
- }
- updateServiceStatus (
- _serviceCurStatus,
- NO_ERROR,
- 0,
- CHECKPOINT_NO_ONGOING_OPERATION,
- TIMEOUT_NONE,
- _serviceStatusHandle
- );
+ debug("serviceHandler: interrogate.");
+ code = isServerRunning(&running);
+ if (code != SERVICE_RETURN_OK)
+ {
+ debug("serviceHandler: error interrogating.");
+ }
+ else if (running)
+ {
+ _serviceCurStatus = SERVICE_RUNNING;
+ debug("serviceHandler: service running.");
+ }
+ else
+ {
+ _serviceCurStatus = SERVICE_STOPPED;
+ debug("serviceHandler: service stopped.");
+ }
+ updateServiceStatus (
+ _serviceCurStatus,
+ NO_ERROR,
+ 0,
+ CHECKPOINT_NO_ONGOING_OPERATION,
+ TIMEOUT_NONE,
+ _serviceStatusHandle
+ );
break;
// Other codes are ignored
@@ -1090,7 +1190,7 @@
//
// scm is the SCM handler (must not be NULL)
// serviceName the name of the service.
-// It is up to the caller of the function to allocate at least MAX_PATH bytes
+// It is up to the caller of the function to allocate at least COMMAND_SIZE bytes
// in binPathName.
// The function returns SERVICE_RETURN_OK if we could create the binary
// path name and SERVICE_RETURN_ERROR otherwise.
@@ -1100,8 +1200,6 @@
char* binPathName)
{
ServiceReturnCode returnValue;
- // pathtname to return
- char* binPathname = NULL;
// handle to the service
SC_HANDLE myService = NULL;
@@ -1150,16 +1248,31 @@
}
else
{
+ char msg[200];
+ sprintf(msg,
+ "getBinaryPath: error calling QueryServiceConfig. Code [%d]",
+ errCode);
+ // error
+ debug(msg);
break;
}
}
else
{
- if (strlen(serviceConfig->lpBinaryPathName) < MAX_PATH)
+ if (strlen(serviceConfig->lpBinaryPathName) < COMMAND_SIZE)
{
sprintf(binPathName, serviceConfig->lpBinaryPathName);
returnValue = SERVICE_RETURN_OK;
}
+ else
+ {
+ debug(
+ "getBinaryPath: the length of the binary path name is too big.");
+ debug("serviceName:");
+ debug(serviceName);
+ debug("binary path:");
+ debug(serviceConfig->lpBinaryPathName);
+ }
}
}
}
@@ -1225,7 +1338,6 @@
}
else
{
- debug("getServiceList: error More Data.");
// buffer is not big enough: try again with a proper size
dataSize += neededSize;
lpServiceData = (ENUM_SERVICE_STATUS*)calloc(
@@ -1247,7 +1359,10 @@
DWORD lastError = GetLastError();
if (lastError != ERROR_MORE_DATA)
{
+ char msg[200];
returnValue = SERVICE_RETURN_ERROR;
+ sprintf(msg, "getServiceList: second try generic error. Code [%d]",
+ lastError);
}
else
{
@@ -1271,6 +1386,7 @@
}
else
{
+ debug("getServiceList: error opening scm.");
returnValue = SERVICE_RETURN_ERROR;
}
@@ -1286,7 +1402,7 @@
*nbServices = aux;
if (aux > 0)
{
- char binPath[MAX_PATH];
+ char binPath[COMMAND_SIZE];
l = (ServiceDescriptor*)calloc(sizeof(ServiceDescriptor), aux);
for (i = 0; i < aux; i++)
{
@@ -1298,6 +1414,11 @@
{
l[i].cmdToRun = strdup(binPath);
}
+ else
+ {
+ debug("Error getting binary path name of service:");
+ debug(l[i].serviceName);
+ }
curService++;
}
*serviceList = l;
@@ -1506,7 +1627,6 @@
BOOL success;
SERVICE_DESCRIPTION serviceDescription;
serviceDescription.lpDescription = description;
-
success = ChangeServiceConfig2(
myService,
SERVICE_CONFIG_DESCRIPTION,
@@ -1661,9 +1781,10 @@
int createService(char* displayName, char* description)
{
int returnCode = 0;
- char cmdToRun[MAX_PATH];
+ char cmdToRun[COMMAND_SIZE];
ServiceReturnCode code;
+ debug("Creating service.");
code = createServiceBinPath(cmdToRun);
if (code == SERVICE_RETURN_OK)
@@ -1676,7 +1797,6 @@
// OpenDS is registered as a service.
code = SERVICE_ALREADY_EXISTS;
createRegistryKey(serviceName);
- debug("createService: service already exists for this instance.");
}
else
{
@@ -1690,23 +1810,34 @@
{
createRegistryKey(serviceName);
}
+ else
+ {
+ debug("Could not get a service name for command to run");
+ }
}
}
}
-
+ else
+ {
+ debug("createService could not create bin path.");
+ }
switch (code)
{
case SERVICE_RETURN_OK:
returnCode = 0;
+ debug("Service successfully created.");
break;
case SERVICE_ALREADY_EXISTS:
returnCode = 1;
+ debug("Service already exists.");
break;
case DUPLICATED_SERVICE_NAME:
returnCode = 2;
+ debug("Duplicated service name.");
break;
default:
returnCode = 3;
+ debug("Unexpected error creating service.");
}
return returnCode;
@@ -1724,10 +1855,11 @@
int serviceState()
{
int returnCode = 0;
- char cmdToRun[MAX_PATH];
+ char cmdToRun[COMMAND_SIZE];
char serviceName[MAX_SERVICE_NAME];
ServiceReturnCode code;
+ debug("Getting service state.");
code = createServiceBinPath(cmdToRun);
if (code == SERVICE_RETURN_OK)
@@ -1739,15 +1871,18 @@
// OpenDS is registered as a service.
fprintf(stdout, serviceName);
returnCode = 0;
+ debug("Service is enabled.");
}
else
{
returnCode = 1;
+ debug("Service is disabled.");
}
}
else
{
returnCode = 2;
+ debug("An error occurred getting the service status.");
}
return returnCode;
@@ -1766,10 +1901,13 @@
{
int returnCode = 0;
ServiceReturnCode code = serviceNameInUse(serviceName);
-
+
+ debug("Removing service.");
+
if (code != SERVICE_IN_USE)
{
returnCode = 1;
+ debug("Service does not exist.");
}
else
{
@@ -1780,16 +1918,19 @@
case SERVICE_RETURN_OK:
removeRegistryKey(serviceName);
returnCode = 0;
+ debug("Service successfully removed.");
break;
case SERVICE_MARKED_FOR_DELETION:
removeRegistryKey(serviceName);
returnCode = 2;
+ debug("Service marked for deletion.");
break;
default:
returnCode = 3;
+ debug("Unexpected error removing service.");
}
}
-
+
return returnCode;
} // removeServiceWithServiceName
@@ -1805,7 +1946,7 @@
int removeService()
{
int returnCode = 0;
- char cmdToRun[MAX_PATH];
+ char cmdToRun[COMMAND_SIZE];
char serviceName[MAX_SERVICE_NAME];
ServiceReturnCode code;
@@ -1843,7 +1984,7 @@
{
int returnCode;
char serviceName[MAX_SERVICE_NAME];
- char cmdToRun[MAX_PATH];
+ char cmdToRun[COMMAND_SIZE];
ServiceReturnCode code;
code = createServiceBinPath(cmdToRun);
@@ -1945,10 +2086,9 @@
{
char* subcommand;
int returnCode = 0;
-
if (argc <= 1)
{
- fprintf(stderr,
+ fprintf(stdout,
"Subcommand required: create, state, remove, start or cleanup.\n");
returnCode = -1;
}
@@ -1959,7 +2099,7 @@
{
if (argc <= 4)
{
- fprintf(stderr,
+ fprintf(stdout,
"Subcommand create requires instance dir, service name and description.\n");
returnCode = -1;
}
@@ -1975,7 +2115,7 @@
{
if (argc <= 2)
{
- fprintf(stderr,
+ fprintf(stdout,
"Subcommand state requires instance dir.\n");
returnCode = -1;
}
@@ -1991,7 +2131,7 @@
{
if (argc <= 2)
{
- fprintf(stderr,
+ fprintf(stdout,
"Subcommand remove requires instance dir.\n");
returnCode = -1;
}
@@ -2007,14 +2147,14 @@
{
if (argc <= 2)
{
- fprintf(stderr,
+ fprintf(stdout,
"Subcommand start requires instance dir.\n");
returnCode = -1;
}
else
{
_instanceDir = strdup(argv[2]);
- updateDebugFlag(argv, argc, 3);
+ DEBUG = TRUE;
returnCode = startService();
free(_instanceDir);
}
@@ -2023,7 +2163,7 @@
{
if (argc <= 2)
{
- fprintf(stderr,
+ fprintf(stdout,
"Subcommand isrunning requires instance dir.\n");
returnCode = -1;
}
@@ -2050,7 +2190,7 @@
{
if (argc <= 2)
{
- fprintf(stderr,
+ fprintf(stdout,
"Subcommand cleanup requires service name.\n");
returnCode = -1;
}
@@ -2065,7 +2205,7 @@
else
{
- fprintf(stderr, "Unknown subcommand: [%s]\n", subcommand);
+ fprintf(stdout, "Unknown subcommand: [%s]\n", subcommand);
returnCode = -1;
}
}
diff --git a/opendj-sdk/opends/src/build-tools/windows/winlauncher.h b/opendj-sdk/opends/src/build-tools/windows/winlauncher.h
index e577a39..beb5414 100644
--- a/opendj-sdk/opends/src/build-tools/windows/winlauncher.h
+++ b/opendj-sdk/opends/src/build-tools/windows/winlauncher.h
@@ -33,6 +33,6 @@
#define PATH_SIZE 1024
#define BUF_SIZE 1024
-#define COMMAND_SIZE 2048
+#define COMMAND_SIZE 2100
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Launcher.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Launcher.java
index a98b705..785847d 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Launcher.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Launcher.java
@@ -169,27 +169,25 @@
}
catch (Throwable t)
{
- try {
- QuickSetupLog.initLogFileHandler(File.createTempFile(
- "opends-launcher-", ".log"));
+ if (QuickSetupLog.isInitialized())
+ {
LOG.log(Level.WARNING, "Error launching GUI: "+t);
+ StringBuilder buf = new StringBuilder();
while (t != null)
{
StackTraceElement[] stack = t.getStackTrace();
for (int i = 0; i < stack.length; i++)
{
- LOG.log(Level.WARNING, stack[i].toString());
+ buf.append(stack[i].toString()+"\n");
}
t = t.getCause();
if (t != null)
{
- LOG.log(Level.WARNING, "Root cause:");
+ buf.append("Root cause:\n");
}
}
- } catch (Throwable t2) {
- System.err.println("Unable to initialize log");
- t2.printStackTrace();
+ LOG.log(Level.WARNING, buf.toString());
}
}
}
@@ -199,7 +197,7 @@
* problems with the display environment.
*/
PrintStream printStream = System.err;
- //System.setErr(new EmptyPrintStream());
+ System.setErr(new EmptyPrintStream());
t.start();
try
{
@@ -269,8 +267,10 @@
* Called if launching of the GUI failed. Here
* subclasses can so application specific things
* like print a message.
+ * @param logFileName the log file containing more information about why
+ * the launch failed.
*/
- protected abstract void guiLaunchFailed();
+ protected abstract void guiLaunchFailed(String logFileName);
/**
* The main method which is called by the uninstall command lines.
@@ -286,7 +286,15 @@
willLaunchGui();
int exitCode = launchGui(args);
if (exitCode != 0) {
- guiLaunchFailed();
+ File logFile = QuickSetupLog.getLogFile();
+ if (logFile != null)
+ {
+ guiLaunchFailed(logFile.toString());
+ }
+ else
+ {
+ guiLaunchFailed(null);
+ }
exitCode = launchCli(args, createCliApplication());
if (exitCode != 0) {
preExit();
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/InstallLauncher.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/InstallLauncher.java
index 74456e7..2202c6d 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/InstallLauncher.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/InstallLauncher.java
@@ -26,11 +26,14 @@
*/
package org.opends.quicksetup.installer;
+import java.io.File;
import java.util.ArrayList;
+import java.util.logging.Logger;
import org.opends.quicksetup.Launcher;
import org.opends.quicksetup.CliApplication;
import org.opends.quicksetup.Installation;
+import org.opends.quicksetup.QuickSetupLog;
import org.opends.quicksetup.util.Utils;
/**
@@ -41,6 +44,16 @@
*/
public class InstallLauncher extends Launcher {
+ /** Prefix for log files. */
+ static public final String LOG_FILE_PREFIX = "opends-setup-";
+
+ /** Suffix for log files. */
+ static public final String LOG_FILE_SUFFIX = ".log";
+
+ static private final Logger LOG =
+ Logger.getLogger(InstallLauncher.class.getName());
+
+
/**
* The main method which is called by the setup command lines.
*
@@ -49,6 +62,13 @@
* will pass to the org.opends.server.tools.InstallDS class.
*/
public static void main(String[] args) {
+ try {
+ QuickSetupLog.initLogFileHandler(
+ File.createTempFile(LOG_FILE_PREFIX, LOG_FILE_SUFFIX));
+ } catch (Throwable t) {
+ System.err.println("Unable to initialize log");
+ t.printStackTrace();
+ }
new InstallLauncher(args).launch();
}
@@ -89,8 +109,16 @@
/**
* {@inheritDoc}
*/
- protected void guiLaunchFailed() {
- System.err.println(getMsg("setup-launcher-gui-launched-failed"));
+ protected void guiLaunchFailed(String logFileName) {
+ if (logFileName != null)
+ {
+ System.err.println(getMsg("setup-launcher-gui-launched-failed-details",
+ logFileName));
+ }
+ else
+ {
+ System.err.println(getMsg("setup-launcher-gui-launched-failed"));
+ }
}
/**
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java
index 120e9d5..24b7e7f 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java
@@ -35,6 +35,7 @@
import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.util.*;
+import java.util.logging.Logger;
import java.awt.event.WindowEvent;
import javax.naming.NamingException;
@@ -87,6 +88,8 @@
// Constants used to do checks
private static final int MIN_DIRECTORY_MANAGER_PWD = 1;
+ private static final Logger LOG = Logger.getLogger(Installer.class.getName());
+
/**
* The minimum integer value that can be used for a port.
*/
@@ -134,6 +137,15 @@
lstSteps.add(NEW_SUFFIX_OPTIONS);
lstSteps.add(REVIEW);
lstSteps.add(PROGRESS);
+ try {
+ if (!QuickSetupLog.isInitialized())
+ QuickSetupLog.initLogFileHandler(
+ File.createTempFile(
+ InstallLauncher.LOG_FILE_PREFIX,
+ InstallLauncher.LOG_FILE_SUFFIX));
+ } catch (IOException e) {
+ System.err.println("Failed to initialize log");
+ }
}
/**
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties
index 2e07a86..2100300 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties
@@ -102,6 +102,9 @@
setup-launcher-launching-gui=Launching graphical setup...
setup-launcher-gui-launched-failed=\n\nThe graphical Setup launch failed.\n\n\
Launching command line Setup...
+setup-launcher-gui-launched-failed-details=\n\nThe graphical Setup launch \
+failed. Check file {0} for more details.\n\n\
+Launching command line Setup...
#
# Uninstall command line messages
@@ -119,6 +122,9 @@
uninstall-launcher-launching-cli=Launching command line uninstall...
uninstall-launcher-gui-launched-failed=\n\nThe graphical Uninstall launch \
failed.\n\nLaunching command line Uninstall...
+uninstall-launcher-gui-launched-failed-details=\n\nThe graphical Uninstall \
+launch failed. Check file {0} for more details.\n\nLaunching command line \
+Uninstall...
cli-uninstall-unknown-argument=Unknown argument {0}
cli-uninstall-yes-short=y
cli-uninstall-yes-long=yes
@@ -170,6 +176,8 @@
upgrade-launcher-launching-cli=Launching command line upgrade...
upgrade-launcher-gui-launched-failed=\n\nThe graphical upgrade launch \
failed.\n\nLaunching command line upgrade...
+upgrade-launcher-gui-launched-failed-details=\n\nThe graphical upgrade launch \
+failed. Check file {0} for more details.\n\nLaunching command line upgrade...
cli-upgrade-unknown-argument=Unknown argument {0}
@@ -856,7 +864,9 @@
error-configuring=Error Configuring Directory Server.
error-configuring-certificate=Error Configuring Certificates.
error-enabling-windows-service=Error Enabling Windows service.
-error-disabling-windows-service=Error Disabling Windows service.
+error-disabling-windows-service=Error Disabling Windows service. Try to kill \
+the process opends_service.exe and the running the \
+{0}\\bat\\windows-service.bat -d command-line to disable the service manually.
error-creating-base-entry=Error Creating Base Entry.
error-importing-ldif=Error Importing LDIF File.
error-import-automatically-generated=Error Importing Automatically- Generated \
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/uninstaller/UninstallLauncher.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/uninstaller/UninstallLauncher.java
index f7c3967..85462c1 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/uninstaller/UninstallLauncher.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/uninstaller/UninstallLauncher.java
@@ -27,9 +27,13 @@
package org.opends.quicksetup.uninstaller;
+import java.io.File;
+import java.util.logging.Logger;
+
import org.opends.quicksetup.CliApplication;
import org.opends.quicksetup.Launcher;
import org.opends.quicksetup.Installation;
+import org.opends.quicksetup.QuickSetupLog;
import org.opends.quicksetup.util.Utils;
/**
@@ -40,6 +44,15 @@
*/
public class UninstallLauncher extends Launcher {
+ /** Prefix for log files. */
+ static public final String LOG_FILE_PREFIX = "opends-uninstall-";
+
+ /** Suffix for log files. */
+ static public final String LOG_FILE_SUFFIX = ".log";
+
+ static private final Logger LOG =
+ Logger.getLogger(UninstallLauncher.class.getName());
+
/**
* The main method which is called by the setup command lines.
*
@@ -48,6 +61,13 @@
* will pass to the org.opends.server.tools.InstallDS class.
*/
public static void main(String[] args) {
+ try {
+ QuickSetupLog.initLogFileHandler(
+ File.createTempFile(LOG_FILE_PREFIX, LOG_FILE_SUFFIX));
+ } catch (Throwable t) {
+ System.err.println("Unable to initialize log");
+ t.printStackTrace();
+ }
new UninstallLauncher(args).launch();
}
@@ -63,8 +83,16 @@
/**
* {@inheritDoc}
*/
- protected void guiLaunchFailed() {
- System.err.println(getMsg("uninstall-launcher-gui-launched-failed"));
+ protected void guiLaunchFailed(String logFilePath) {
+ if (logFilePath != null)
+ {
+ System.err.println(getMsg(
+ "uninstall-launcher-gui-launched-failed-details", logFilePath));
+ }
+ else
+ {
+ System.err.println(getMsg("uninstall-launcher-gui-launched-failed"));
+ }
}
/**
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/uninstaller/Uninstaller.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/uninstaller/Uninstaller.java
index 1032d64..f22b29f 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/uninstaller/Uninstaller.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/uninstaller/Uninstaller.java
@@ -30,7 +30,6 @@
import org.opends.quicksetup.*;
import static org.opends.quicksetup.Step.PROGRESS;
import static org.opends.quicksetup.Step.REVIEW;
-import org.opends.quicksetup.ui.FieldName;
import org.opends.quicksetup.ui.*;
import org.opends.quicksetup.util.Utils;
import org.opends.quicksetup.util.BackgroundTask;
@@ -39,6 +38,7 @@
import java.io.*;
import java.util.*;
+import java.util.logging.Logger;
import java.awt.event.WindowEvent;
/**
@@ -60,6 +60,9 @@
private UninstallCliHelper cliHelper = new UninstallCliHelper();
+ private static final Logger LOG =
+ Logger.getLogger(Uninstaller.class.getName());
+
/**
* {@inheritDoc}
*/
@@ -950,7 +953,8 @@
getMsg("progress-disabling-windows-service")));
int code = ConfigureWindowsService.disableService(System.out, System.err);
- String errorMessage = getMsg("error-disabling-windows-service");
+ String errorMessage = getMsg("error-disabling-windows-service",
+ getInstallationPath());
switch (code) {
case ConfigureWindowsService.SERVICE_DISABLE_SUCCESS:
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgradeLauncher.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgradeLauncher.java
index 38c2648..61de1e8 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgradeLauncher.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgradeLauncher.java
@@ -121,8 +121,16 @@
/**
* {@inheritDoc}
*/
- protected void guiLaunchFailed() {
- System.err.println(getMsg("upgrade-launcher-gui-launched-failed"));
+ protected void guiLaunchFailed(String logFilePath) {
+ if (logFilePath != null)
+ {
+ System.err.println(getMsg("upgrade-launcher-gui-launched-failed-details",
+ logFilePath));
+ }
+ else
+ {
+ System.err.println(getMsg("upgrade-launcher-gui-launched-failed"));
+ }
}
private UpgradeLauncher(String[] args) {
diff --git a/opendj-sdk/opends/src/server/org/opends/server/tools/ConfigureWindowsService.java b/opendj-sdk/opends/src/server/org/opends/server/tools/ConfigureWindowsService.java
index e4d6103..9a5988a 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/tools/ConfigureWindowsService.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/tools/ConfigureWindowsService.java
@@ -61,6 +61,8 @@
private static final String CLASS_NAME =
"org.opends.server.tools.ConfigureWindowsService";
+ private static final String DEBUG_OPTION = "--debug";
+
private static int ERROR = 1;
/**
@@ -387,7 +389,8 @@
"create",
serverRoot,
getMessage(MSGID_WINDOWS_SERVICE_NAME, (Object[]) null),
- getMessage(MSGID_WINDOWS_SERVICE_DESCRIPTION, serverRoot)
+ getMessage(MSGID_WINDOWS_SERVICE_DESCRIPTION, serverRoot),
+ DEBUG_OPTION
};
try
{
@@ -427,6 +430,8 @@
}
catch (Throwable t)
{
+ err.println("Fucking throwable: "+t);
+ t.printStackTrace();
returnValue = SERVICE_ENABLE_ERROR;
msg = getMessage(MSGID_WINDOWS_SERVICE_ENABLE_ERROR,
(Object[])null);
@@ -453,7 +458,8 @@
String[] cmd = {
getBinaryFullPath(),
"remove",
- serverRoot
+ serverRoot,
+ DEBUG_OPTION
};
try
{
@@ -493,6 +499,7 @@
}
catch (Throwable t)
{
+ t.printStackTrace();
returnValue = SERVICE_DISABLE_ERROR;
msg = getMessage(MSGID_WINDOWS_SERVICE_DISABLE_ERROR,
(Object[])null);
@@ -520,7 +527,8 @@
String[] cmd = {
getBinaryFullPath(),
"cleanup",
- serviceName
+ serviceName,
+ DEBUG_OPTION
};
try
{
@@ -582,7 +590,8 @@
String[] cmd = {
getBinaryFullPath(),
"state",
- serverRoot
+ serverRoot,
+ DEBUG_OPTION
};
try
{
diff --git a/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/BaseDNDescriptor.java b/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/BaseDNDescriptor.java
index c4c5a5a..1974a64 100644
--- a/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/BaseDNDescriptor.java
+++ b/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/BaseDNDescriptor.java
@@ -98,7 +98,11 @@
equals = (getType() == desc.getType()) &&
Utils.areDnsEqual(getDn(), desc.getDn()) &&
(getAgeOfOldestMissingChange() == desc.getAgeOfOldestMissingChange()) &&
- (getMissingChanges() == desc.getMissingChanges());
+ (getMissingChanges() == desc.getMissingChanges()) &&
+ getDatabase().getBackendID().equals(
+ desc.getDatabase().getBackendID()) &&
+ (getDatabase().getEntries() == desc.getDatabase().getEntries());
+
}
}
else
diff --git a/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/DatabaseDescriptor.java b/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/DatabaseDescriptor.java
index e474b01..3f1a296 100644
--- a/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/DatabaseDescriptor.java
+++ b/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/DatabaseDescriptor.java
@@ -29,8 +29,6 @@
import java.util.Set;
-import org.opends.quicksetup.util.Utils;
-
/**
* This class is used to represent a Database and is aimed to be used by the
* classes in the DatabasesTableModel class.
@@ -99,24 +97,7 @@
if (equals)
{
- for (BaseDNDescriptor baseDn1 : baseDns)
- {
- boolean found = false;
- for (BaseDNDescriptor baseDn2 : desc.getBaseDns())
- {
- found = Utils.areDnsEqual(baseDn1.getDn(),
- baseDn2.getDn());
- if (found)
- {
- break;
- }
- }
- if (!found)
- {
- equals = false;
- break;
- }
- }
+ equals = baseDns.equals(desc.getBaseDns());
}
}
}
diff --git a/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/StatusLog.java b/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/StatusLog.java
new file mode 100644
index 0000000..970b4c1
--- /dev/null
+++ b/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/StatusLog.java
@@ -0,0 +1,89 @@
+/*
+ * 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.
+ */
+package org.opends.statuspanel;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.logging.FileHandler;
+import java.util.logging.SimpleFormatter;
+import java.util.logging.Logger;
+import java.util.logging.Level;
+import java.util.Date;
+import java.text.DateFormat;
+
+/**
+ * Utilities for setting up Status application log.
+ */
+public class StatusLog {
+
+ static private File logFile = null;
+
+ /**
+ * Creates a new file handler for writing log messages to the file indicated
+ * by <code>file</code>.
+ * @param file log file to which log messages will be written
+ * @throws IOException if something goes wrong
+ */
+ static public void initLogFileHandler(File file) throws IOException {
+ if (!isInitialized()) {
+ logFile = file;
+ FileHandler fileHandler = new FileHandler(logFile.getCanonicalPath());
+ fileHandler.setFormatter(new SimpleFormatter());
+ Logger logger = Logger.getLogger("org.opends.statuspanel");
+ logger.setUseParentHandlers(false); // disable logging to console
+ logger.addHandler(fileHandler);
+ logger.log(Level.INFO, getInitialLogRecord());
+ }
+ }
+
+ /**
+ * Gets the name of the log file.
+ * @return File representing the log file
+ */
+ static public File getLogFile() {
+ return logFile;
+ }
+
+ /**
+ * Indicates whether or not the log file has been initialized.
+ * @return true when the log file has been initialized
+ */
+ static public boolean isInitialized() {
+ return logFile != null;
+ }
+
+ static private String getInitialLogRecord() {
+ StringBuffer sb = new StringBuffer()
+ .append("Status application launched " +
+ DateFormat.getDateTimeInstance(DateFormat.LONG,
+ DateFormat.LONG).
+ format(new Date()));
+ return sb.toString();
+ }
+
+}
+
diff --git a/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/StatusPanelLauncher.java b/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/StatusPanelLauncher.java
index 5da9c76..3c19010 100644
--- a/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/StatusPanelLauncher.java
+++ b/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/StatusPanelLauncher.java
@@ -27,7 +27,10 @@
package org.opends.statuspanel;
import java.io.ByteArrayOutputStream;
+import java.io.File;
import java.io.PrintStream;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import org.opends.quicksetup.util.Utils;
import org.opends.quicksetup.Installation;
@@ -40,12 +43,28 @@
*/
public class StatusPanelLauncher
{
+ /** Prefix for log files. */
+ static public final String LOG_FILE_PREFIX = "opends-status-";
+
+ /** Suffix for log files. */
+ static public final String LOG_FILE_SUFFIX = ".log";
+
+ static private final Logger LOG =
+ Logger.getLogger(StatusPanelLauncher.class.getName());
+
/**
* The main method which is called by the control panel command lines.
* @param args the arguments passed by the command lines.
*/
public static void main(String[] args)
{
+ try {
+ StatusLog.initLogFileHandler(
+ File.createTempFile(LOG_FILE_PREFIX, LOG_FILE_SUFFIX));
+ } catch (Throwable t) {
+ System.err.println("Unable to initialize log");
+ t.printStackTrace();
+ }
boolean printUsage = false;
if ((args != null) && (args.length > 4))
{
@@ -70,7 +89,20 @@
int exitCode = launchGuiStatusPanel(args);
if (exitCode != 0)
{
- System.err.println(getMsg("status-panel-launcher-gui-launch-failed"));
+ String logFileName = null;
+ if (StatusLog.getLogFile() != null)
+ {
+ logFileName = StatusLog.getLogFile().toString();
+ }
+ if (logFileName != null)
+ {
+ System.err.println(getMsg(
+ "status-panel-launcher-gui-launch-failed-details", logFileName));
+ }
+ else
+ {
+ System.err.println(getMsg("status-panel-launcher-gui-launch-failed"));
+ }
System.exit(exitCode);
}
}
@@ -99,10 +131,36 @@
{
public void run()
{
- // Setup MacOSX native menu bar before AWT is loaded.
- Utils.setMacOSXMenuBar(getMsg("statuspanel-dialog-title"));
- SplashScreen.main(args);
- returnValue[0] = 0;
+ try
+ {
+ // Setup MacOSX native menu bar before AWT is loaded.
+ Utils.setMacOSXMenuBar(getMsg("statuspanel-dialog-title"));
+ SplashScreen.main(args);
+ returnValue[0] = 0;
+ }
+ catch (Throwable t)
+ {
+ if (StatusLog.isInitialized())
+ {
+ LOG.log(Level.WARNING, "Error launching GUI: "+t);
+ StringBuilder buf = new StringBuilder();
+ while (t != null)
+ {
+ StackTraceElement[] stack = t.getStackTrace();
+ for (int i = 0; i < stack.length; i++)
+ {
+ buf.append(stack[i].toString()+"\n");
+ }
+
+ t = t.getCause();
+ if (t != null)
+ {
+ buf.append("Root cause:\n");
+ }
+ }
+ LOG.log(Level.WARNING, buf.toString());
+ }
+ }
}
});
/*
@@ -110,7 +168,7 @@
* problems with the display environment.
*/
PrintStream printStream = System.err;
- //System.setErr(new EmptyPrintStream());
+ System.setErr(new EmptyPrintStream());
t.start();
try
{
@@ -154,6 +212,20 @@
Utils.getCommandLineMaxLineWidth());
}
+ /**
+ * Creates an internationaized message based on the input key and
+ * properly formatted for the terminal.
+ * @param key for the message in the bundle
+ * @param args String... arguments for the message
+ * @return String message properly formatted for the terminal
+ */
+ private static String getMsg(String key, String... args)
+ {
+ return org.opends.server.util.StaticUtils.wrapText(
+ getI18n().getMsg(key, args),
+ Utils.getCommandLineMaxLineWidth());
+ }
+
private static ResourceProvider getI18n()
{
return ResourceProvider.getInstance();
diff --git a/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/resources/Resources.properties b/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/resources/Resources.properties
index 0cbcf8f..1011830 100644
--- a/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/resources/Resources.properties
+++ b/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/resources/Resources.properties
@@ -38,6 +38,8 @@
-?, -H, --help\n Display this usage information.
status-panel-launcher-gui-launch-failed=Could not launch Status Panel. Check \
that you have access to the display.
+status-panel-launcher-gui-launch-failed-details=Could not launch Status \
+Panel. Check that you have access to the display. Check file {0} for details.
#
# StatusPanel
@@ -89,7 +91,7 @@
replicated-column=Replication
missing-changes-column=Missing Changes
age-of-oldest-missing-change-column=<html>Age of Oldest<br>Missing \
-Change (hh:mm:ss)
+Change<br>(hh:mm:ss)
age-of-oldest-missing-change-column-cli=Age of Oldest Missing Change (hh:mm:ss)
enabled-label=Enabled
disabled-label=Disabled
--
Gitblit v1.10.0