From 4a48f1cf6caab40fa3741d93f8c825078e4820f2 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:

---
 opends/src/build-tools/windows/service.c |  264 ++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 202 insertions(+), 62 deletions(-)

diff --git a/opends/src/build-tools/windows/service.c b/opends/src/build-tools/windows/service.c
index f476653..fe1ca4c 100644
--- a/opends/src/build-tools/windows/service.c
+++ b/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;
     }
   }

--
Gitblit v1.10.0