agent action arguments passed correctly from object tool (issue #984)
authorVictor Kirhenshtein <victor@netxms.org>
Wed, 25 May 2016 20:48:24 +0000 (23:48 +0300)
committerVictor Kirhenshtein <victor@netxms.org>
Wed, 25 May 2016 20:48:24 +0000 (23:48 +0300)
12 files changed:
src/java/client/netxms-client/src/main/java/org/netxms/client/NXCSession.java
src/java/client/netxms-client/src/test/java/org/netxms/client/AgentTest.java
src/java/netxms-eclipse/ObjectTools/META-INF/MANIFEST.MF
src/java/netxms-eclipse/ObjectTools/src/org/netxms/ui/eclipse/objecttools/api/ObjectToolExecutor.java
src/java/netxms-eclipse/ObjectTools/src/org/netxms/ui/eclipse/objecttools/views/AgentActionResults.java
src/server/core/session.cpp
src/server/tools/nxaction/.cproject [new file with mode: 0644]
src/server/tools/nxaction/.project [new file with mode: 0644]
src/server/tools/nxaction/.settings/language.settings.xml [new file with mode: 0644]
webui/webapp/ObjectTools/META-INF/MANIFEST.MF
webui/webapp/ObjectTools/src/org/netxms/ui/eclipse/objecttools/api/ObjectToolExecutor.java
webui/webapp/ObjectTools/src/org/netxms/ui/eclipse/objecttools/views/AgentActionResults.java

index 4ff2501..19b5beb 100644 (file)
@@ -4890,12 +4890,13 @@ public class NXCSession
     *
     * @param nodeId Node object ID
     * @param action Action name
+    * @param args Action arguments
     * @throws IOException  if socket I/O error occurs
     * @throws NXCException if NetXMS server returns an error or operation was timed out
     */
-   public void executeAction(long nodeId, String action) throws IOException, NXCException
+   public void executeAction(long nodeId, String action, String[] args) throws IOException, NXCException
    {
-      executeAction(nodeId, action, false, null, null);
+      executeAction(nodeId, action, args, false, null, null);
    }
 
    /**
@@ -4903,19 +4904,32 @@ public class NXCSession
     *
     * @param nodeId Node object ID
     * @param action Action name
+    * @param args Action arguments
     * @param receiveOutput true if action's output has to be read
     * @param listener listener for action's output or null
     * @param writer writer for action's output or null
     * @throws IOException  if socket I/O error occurs
     * @throws NXCException if NetXMS server returns an error or operation was timed out
     */
-   public void executeAction(long nodeId, String action, boolean receiveOutput, final TextOutputListener listener, final Writer writer) throws IOException, NXCException
+   public void executeAction(long nodeId, String action, String[] args, boolean receiveOutput, final TextOutputListener listener, final Writer writer) throws IOException, NXCException
    {
       NXCPMessage msg = newMessage(NXCPCodes.CMD_EXECUTE_ACTION);
       msg.setFieldInt32(NXCPCodes.VID_OBJECT_ID, (int) nodeId);
       msg.setField(NXCPCodes.VID_ACTION_NAME, action);
       msg.setField(NXCPCodes.VID_RECEIVE_OUTPUT, receiveOutput);
       
+      if (args != null)
+      {
+         msg.setFieldInt16(NXCPCodes.VID_NUM_ARGS, args.length);
+         long fieldId = NXCPCodes.VID_ACTION_ARG_BASE;
+         for(String a : args)
+            msg.setField(fieldId++, a);
+      }
+      else
+      {
+         msg.setFieldInt16(NXCPCodes.VID_NUM_ARGS, 0);
+      }
+      
       MessageHandler handler = receiveOutput ? new MessageHandler() {
          @Override
          public boolean processMessage(NXCPMessage m)
index d37030c..06bea06 100644 (file)
@@ -27,7 +27,7 @@ public class AgentTest extends AbstractSessionTest
    {
       final NXCSession session = connect();
       
-      session.executeAction(TestConstants.LOCAL_NODE_ID, TestConstants.ACTION, true, new TextOutputListener() {
+      session.executeAction(TestConstants.LOCAL_NODE_ID, TestConstants.ACTION, null, true, new TextOutputListener() {
          @Override
          public void messageReceived(String text)
          {
index cf8e5ae..54a5391 100644 (file)
@@ -2,19 +2,19 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: NXMC Object Tools plugin
 Bundle-SymbolicName: org.netxms.ui.eclipse.objecttools;singleton:=true
-Bundle-Version: 2.0.7
+Bundle-Version: 2.0.8
 Bundle-Activator: org.netxms.ui.eclipse.objecttools.Activator
 Bundle-Vendor: netxms.org
 Require-Bundle: org.eclipse.ui;bundle-version="3.8.2",
  org.eclipse.core.runtime;bundle-version="3.8.0",
  org.eclipse.core.expressions;bundle-version="3.4.400",
  org.eclipse.ui.console;bundle-version="3.5.100",
- org.netxms.ui.eclipse.clientlibrary;bundle-version="2.0.6",
- org.netxms.ui.eclipse.console;bundle-version="2.0.5",
- org.netxms.ui.eclipse.usermanager;bundle-version="2.0.0",
+ org.netxms.ui.eclipse.clientlibrary;bundle-version="2.0.10",
+ org.netxms.ui.eclipse.console;bundle-version="2.0.10",
+ org.netxms.ui.eclipse.usermanager;bundle-version="2.0.8",
  org.netxms.ui.eclipse.snmp;bundle-version="2.0.0",
- org.netxms.ui.eclipse.objectbrowser,
- org.netxms.ui.eclipse.filemanager;bundle-version="2.0.5"
+ org.netxms.ui.eclipse.objectbrowser;bundle-version="2.0.7",
+ org.netxms.ui.eclipse.filemanager;bundle-version="2.0.6"
 Bundle-RequiredExecutionEnvironment: JavaSE-1.6
 Bundle-ActivationPolicy: lazy
 Export-Package: org.netxms.ui.eclipse.objecttools.api
index bb764f1..786ca1c 100644 (file)
@@ -20,9 +20,11 @@ package org.netxms.ui.eclipse.objecttools.api;
 
 import java.io.IOException;
 import java.net.URLEncoder;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Comparator;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import org.eclipse.core.runtime.IProgressMonitor;
@@ -281,6 +283,89 @@ public final class ObjectToolExecutor
          MessageDialogHelper.openError(window.getShell(), Messages.get().ObjectToolsDynamicMenu_Error, String.format(Messages.get().ObjectToolsDynamicMenu_ErrorOpeningView, e.getLocalizedMessage()));
       }
    }
+   
+   /**
+    * Split command line into tokens
+    *  
+    * @param input
+    * @return
+    */
+   private static String[] splitCommandLine(String input)
+   {
+      char[] in = input.toCharArray();
+      List<String> args = new ArrayList<String>();
+      
+      StringBuilder sb = new StringBuilder();
+      int state = 0;
+      for(char c : in)
+      {
+         switch(state)
+         {
+            case 0: // normal
+               if (Character.isSpaceChar(c))
+               {
+                  args.add(sb.toString());
+                  sb = new StringBuilder();
+                  state = 3;
+               }
+               else if (c == '"')
+               {
+                  state = 1;
+               }
+               else if (c == '\'')
+               {
+                  state = 2;
+               }
+               else
+               {
+                  sb.append(c);
+               }
+               break;
+            case 1: // double quoted string
+               if (c == '"')
+               {
+                  state = 0;
+               }
+               else
+               {
+                  sb.append(c);
+               }
+               break;
+            case 2: // single quoted string
+               if (c == '\'')
+               {
+                  state = 0;
+               }
+               else
+               {
+                  sb.append(c);
+               }
+               break;
+            case 3: // skip
+               if (!Character.isSpaceChar(c))
+               {
+                  if (c == '"')
+                  {
+                     state = 1;
+                  }
+                  else if (c == '\'')
+                  {
+                     state = 2;
+                  }
+                  else
+                  {
+                     sb.append(c);
+                     state = 0;
+                  }
+               }
+               break;
+         }
+      }
+      if (state != 3)
+         args.add(sb.toString());
+      
+      return args.toArray(new String[args.size()]);
+   }
 
    /**
     * @param node
@@ -290,7 +375,9 @@ public final class ObjectToolExecutor
    private static void executeAgentAction(final NodeInfo node, final ObjectTool tool, Map<String, String> inputValues)
    {
       final NXCSession session = (NXCSession)ConsoleSharedData.getSession();
-      final String action = substituteMacros(tool.getData(), node, inputValues);
+      String[] parts = splitCommandLine(substituteMacros(tool.getData(), node, inputValues));
+      final String action = parts[0];
+      final String[] args = Arrays.copyOfRange(parts, 1, parts.length);
       
       if ((tool.getFlags() & ObjectTool.GENERATES_OUTPUT) == 0)
       {      
@@ -304,7 +391,7 @@ public final class ObjectToolExecutor
             @Override
             protected void runInternal(IProgressMonitor monitor) throws Exception
             {
-               session.executeAction(node.object.getObjectId(), action);
+               session.executeAction(node.object.getObjectId(), action, args);
                runInUIThread(new Runnable() {
                   @Override
                   public void run()
@@ -322,7 +409,7 @@ public final class ObjectToolExecutor
          try
          {
             AgentActionResults view = (AgentActionResults)window.getActivePage().showView(AgentActionResults.ID, secondaryId, IWorkbenchPage.VIEW_ACTIVATE);
-            view.executeAction(action);
+            view.executeAction(action, args);
          }
          catch(Exception e)
          {
index a97037f..fa5b11f 100644 (file)
@@ -42,6 +42,7 @@ public class AgentActionResults extends AbstractCommandResults implements TextOu
 
    private IOConsoleOutputStream out;
    private String lastAction = null;
+   private String[] lastArgs = null;
    private Action actionRestart;
    
    /**
@@ -55,7 +56,7 @@ public class AgentActionResults extends AbstractCommandResults implements TextOu
          @Override
          public void run()
          {
-            executeAction(lastAction);
+            executeAction(lastAction, lastArgs);
          }
       };
       actionRestart.setEnabled(false);
@@ -100,12 +101,13 @@ public class AgentActionResults extends AbstractCommandResults implements TextOu
    /**
     * @param action
     */
-   public void executeAction(final String action)
+   public void executeAction(final String action, final String[] args)
    {
       actionRestart.setEnabled(false);
       final NXCSession session = (NXCSession)ConsoleSharedData.getSession();
       out = console.newOutputStream();
       lastAction = action;
+      lastArgs = args;
       ConsoleJob job = new ConsoleJob(String.format(Messages.get().ObjectToolsDynamicMenu_ExecuteOnNode, session.getObjectName(nodeId)), null, Activator.PLUGIN_ID, null) {
          @Override
          protected String getErrorMessage()
@@ -118,7 +120,7 @@ public class AgentActionResults extends AbstractCommandResults implements TextOu
          {
             try
             {
-               session.executeAction(nodeId, action, true, AgentActionResults.this, null);
+               session.executeAction(nodeId, action, args, true, AgentActionResults.this, null);
                out.write(Messages.get().LocalCommandResults_Terminated);
             }
             finally
index cec4ece..077a96e 100644 (file)
@@ -7810,6 +7810,9 @@ void ClientSession::executeAction(NXCPMessage *pRequest)
    {
       if (object->getObjectClass() == OBJECT_NODE)
       {
+         TCHAR action[MAX_PARAM_NAME];
+         pRequest->getFieldAsString(VID_ACTION_NAME, action, MAX_PARAM_NAME);
+
          if (object->checkAccessRights(m_dwUserId, OBJECT_ACCESS_CONTROL))
          {
             AgentConnection *pConn;
@@ -7817,25 +7820,37 @@ void ClientSession::executeAction(NXCPMessage *pRequest)
             pConn = ((Node *)object)->createAgentConnection();
             if (pConn != NULL)
             {
-               TCHAR action[MAX_PARAM_NAME];
-               pRequest->getFieldAsString(VID_ACTION_NAME, action, MAX_PARAM_NAME);
+               TCHAR *argv[64];
+               int argc = pRequest->getFieldAsInt16(VID_NUM_ARGS);
+               if (argc > 64)
+               {
+                  debugPrintf(4, _T("executeAction: too many arguments (%d)"), argc);
+                  argc = 64;
+               }
+               UINT32 fieldId = VID_ACTION_ARG_BASE;
+               for(int i = 0; i < argc; i++)
+                  argv[i] = pRequest->getFieldAsString(fieldId++);
 
                UINT32 rcc;
                bool withOutput = pRequest->getFieldAsBoolean(VID_RECEIVE_OUTPUT);
                if (withOutput)
                {
                   ActionExecutionData data(this, pRequest->getId());
-                  rcc = pConn->execAction(action, 0, NULL, true, ActionExecuteCallback, &data);
+                  rcc = pConn->execAction(action, argc, argv, true, ActionExecuteCallback, &data);
                }
                else
                {
-                  rcc = pConn->execAction(action, 0, NULL);
+                  rcc = pConn->execAction(action, argc, argv);
                }
 
+               for(int i = 0; i < argc; i++)
+                  free(argv[i]);
+
                switch(rcc)
                {
                   case ERR_SUCCESS:
                      msg.setField(VID_RCC, RCC_SUCCESS);
+                     writeAuditLog(AUDIT_OBJECTS, false, object->getId(), _T("Executed agent action %s"), action);
                      break;
                   case ERR_ACCESS_DENIED:
                      msg.setField(VID_RCC, RCC_ACCESS_DENIED);
@@ -7860,6 +7875,7 @@ void ClientSession::executeAction(NXCPMessage *pRequest)
          else
          {
             msg.setField(VID_RCC, RCC_ACCESS_DENIED);
+            writeAuditLog(AUDIT_OBJECTS, false, object->getId(), _T("Access denied on executing agent action %s"), action);
          }
       }
       else
diff --git a/src/server/tools/nxaction/.cproject b/src/server/tools/nxaction/.cproject
new file mode 100644 (file)
index 0000000..563f3fb
--- /dev/null
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+       <storageModule moduleId="org.eclipse.cdt.core.settings">
+               <cconfiguration id="cdt.managedbuild.toolchain.gnu.base.360356126">
+                       <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.base.360356126" moduleId="org.eclipse.cdt.core.settings" name="Default">
+                               <externalSettings/>
+                               <extensions>
+                                       <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+                               </extensions>
+                       </storageModule>
+                       <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+                               <configuration artifactName="${ProjName}" buildProperties="" description="" id="cdt.managedbuild.toolchain.gnu.base.360356126" name="Default" parent="org.eclipse.cdt.build.core.emptycfg">
+                                       <folderInfo id="cdt.managedbuild.toolchain.gnu.base.360356126.1510628381" name="/" resourcePath="">
+                                               <toolChain id="cdt.managedbuild.toolchain.gnu.base.196947163" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.base">
+                                                       <targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.target.gnu.platform.base.1871588323" name="Debug Platform" osList="linux,hpux,aix,qnx" superClass="cdt.managedbuild.target.gnu.platform.base"/>
+                                                       <builder id="cdt.managedbuild.target.gnu.builder.base.1412242527" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.base"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.archiver.base.605968838" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cpp.compiler.base.1291043094" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.base">
+                                                               <option id="gnu.cpp.compiler.option.include.paths.1099723416" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" valueType="includePath">
+                                                                       <listOptionValue builtIn="false" value="&quot;${NETXMS_BASE}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${NETXMS_BASE}/include&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${NETXMS_BASE}/src/server/include&quot;"/>
+                                                               </option>
+                                                               <option id="gnu.cpp.compiler.option.preprocessor.def.485882341" name="Defined symbols (-D)" superClass="gnu.cpp.compiler.option.preprocessor.def" valueType="definedSymbols">
+                                                                       <listOptionValue builtIn="false" value="_THREAD_SAFE"/>
+                                                                       <listOptionValue builtIn="false" value="TRE_WCHAR=1"/>
+                                                                       <listOptionValue builtIn="false" value="UNICODE"/>
+                                                                       <listOptionValue builtIn="false" value="_GNU_SOURCE"/>
+                                                               </option>
+                                                               <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.725460048" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.c.compiler.base.804216584" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.base">
+                                                               <option id="gnu.c.compiler.option.include.paths.1667628094" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
+                                                                       <listOptionValue builtIn="false" value="&quot;${NETXMS_BASE}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${NETXMS_BASE}/include&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${NETXMS_BASE}/src/server/include&quot;"/>
+                                                               </option>
+                                                               <option id="gnu.c.compiler.option.preprocessor.def.symbols.944208369" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" valueType="definedSymbols">
+                                                                       <listOptionValue builtIn="false" value="_THREAD_SAFE"/>
+                                                                       <listOptionValue builtIn="false" value="TRE_WCHAR=1"/>
+                                                                       <listOptionValue builtIn="false" value="UNICODE"/>
+                                                                       <listOptionValue builtIn="false" value="_GNU_SOURCE"/>
+                                                               </option>
+                                                               <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1882030988" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.c.linker.base.1083350962" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.base"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cpp.linker.base.509182396" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.base">
+                                                               <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.1868640402" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
+                                                                       <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+                                                                       <additionalInput kind="additionalinput" paths="$(LIBS)"/>
+                                                               </inputType>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.assembler.base.321447268" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.base">
+                                                               <option id="gnu.both.asm.option.include.paths.764282431" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" valueType="includePath">
+                                                                       <listOptionValue builtIn="false" value="&quot;${NETXMS_BASE}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${NETXMS_BASE}/include&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${NETXMS_BASE}/src/server/include&quot;"/>
+                                                               </option>
+                                                               <inputType id="cdt.managedbuild.tool.gnu.assembler.input.993905148" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
+                                                       </tool>
+                                               </toolChain>
+                                       </folderInfo>
+                               </configuration>
+                       </storageModule>
+                       <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+               </cconfiguration>
+       </storageModule>
+       <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+               <project id="nxaction.null.86345292" name="nxaction"/>
+       </storageModule>
+       <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
+       <storageModule moduleId="scannerConfiguration">
+               <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+               <scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.base.360356126;cdt.managedbuild.toolchain.gnu.base.360356126.1510628381;cdt.managedbuild.tool.gnu.cpp.compiler.base.1291043094;cdt.managedbuild.tool.gnu.cpp.compiler.input.725460048">
+                       <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+               </scannerConfigBuildInfo>
+               <scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.base.360356126;cdt.managedbuild.toolchain.gnu.base.360356126.1510628381;cdt.managedbuild.tool.gnu.c.compiler.base.804216584;cdt.managedbuild.tool.gnu.c.compiler.input.1882030988">
+                       <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+               </scannerConfigBuildInfo>
+       </storageModule>
+</cproject>
diff --git a/src/server/tools/nxaction/.project b/src/server/tools/nxaction/.project
new file mode 100644 (file)
index 0000000..0e6d87f
--- /dev/null
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>nxaction</name>
+       <comment></comment>
+       <projects>
+               <project>libnetxms</project>
+               <project>libnxsrv</project>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+                       <triggers>clean,full,incremental,</triggers>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+                       <triggers>full,incremental,</triggers>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.cdt.core.cnature</nature>
+               <nature>org.eclipse.cdt.core.ccnature</nature>
+               <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+               <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+       </natures>
+       <filteredResources>
+               <filter>
+                       <id>1464202083768</id>
+                       <name></name>
+                       <type>6</type>
+                       <matcher>
+                               <id>org.eclipse.ui.ide.multiFilter</id>
+                               <arguments>1.0-name-matches-false-false-*.o</arguments>
+                       </matcher>
+               </filter>
+               <filter>
+                       <id>1464202083775</id>
+                       <name></name>
+                       <type>6</type>
+                       <matcher>
+                               <id>org.eclipse.ui.ide.multiFilter</id>
+                               <arguments>1.0-name-matches-false-false-*.lo</arguments>
+                       </matcher>
+               </filter>
+       </filteredResources>
+</projectDescription>
diff --git a/src/server/tools/nxaction/.settings/language.settings.xml b/src/server/tools/nxaction/.settings/language.settings.xml
new file mode 100644 (file)
index 0000000..c80781b
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<project>
+       <configuration id="cdt.managedbuild.toolchain.gnu.base.360356126" name="Default">
+               <extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
+                       <provider class="org.eclipse.cdt.core.language.settings.providers.LanguageSettingsGenericProvider" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider" name="CDT User Setting Entries" prefer-non-shared="true"/>
+                       <provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
+                       <provider copy-of="extension" id="org.eclipse.cdt.managedbuilder.core.GCCBuildCommandParser"/>
+                       <provider-reference id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" ref="shared-provider"/>
+                       <provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
+               </extension>
+       </configuration>
+</project>
index bf6146e..b9f00e7 100644 (file)
@@ -2,15 +2,15 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: NXMC Object Tools plugin
 Bundle-SymbolicName: org.netxms.ui.eclipse.objecttools;singleton:=true
-Bundle-Version: 2.0.7
+Bundle-Version: 2.0.8
 Bundle-Activator: org.netxms.ui.eclipse.objecttools.Activator
 Bundle-Vendor: netxms.org
 Require-Bundle: org.eclipse.rap.ui;bundle-version="2.3.1",
  org.eclipse.core.runtime;bundle-version="3.8.0",
  org.eclipse.core.expressions;bundle-version="3.4.401",
- org.netxms.ui.eclipse.clientlibrary;bundle-version="2.0.9",
+ org.netxms.ui.eclipse.clientlibrary;bundle-version="2.0.10",
  org.netxms.webui.core;bundle-version="2.0.10",
- org.netxms.ui.eclipse.usermanager;bundle-version="2.0.4",
+ org.netxms.ui.eclipse.usermanager;bundle-version="2.0.8",
  org.netxms.ui.eclipse.snmp;bundle-version="2.0.0",
  org.eclipse.rap.addons.filedialog;bundle-version="0.6.0",
  org.netxms.ui.eclipse.objectbrowser;bundle-version="2.0.7",
index 628a953..f419d6a 100644 (file)
 package org.netxms.ui.eclipse.objecttools.api;
 
 import java.net.URLEncoder;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Comparator;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import org.eclipse.core.runtime.IProgressMonitor;
@@ -277,6 +279,89 @@ public final class ObjectToolExecutor
       }
    }
 
+   /**
+    * Split command line into tokens
+    *  
+    * @param input
+    * @return
+    */
+   private static String[] splitCommandLine(String input)
+   {
+      char[] in = input.toCharArray();
+      List<String> args = new ArrayList<String>();
+      
+      StringBuilder sb = new StringBuilder();
+      int state = 0;
+      for(char c : in)
+      {
+         switch(state)
+         {
+            case 0: // normal
+               if (Character.isSpaceChar(c))
+               {
+                  args.add(sb.toString());
+                  sb = new StringBuilder();
+                  state = 3;
+               }
+               else if (c == '"')
+               {
+                  state = 1;
+               }
+               else if (c == '\'')
+               {
+                  state = 2;
+               }
+               else
+               {
+                  sb.append(c);
+               }
+               break;
+            case 1: // double quoted string
+               if (c == '"')
+               {
+                  state = 0;
+               }
+               else
+               {
+                  sb.append(c);
+               }
+               break;
+            case 2: // single quoted string
+               if (c == '\'')
+               {
+                  state = 0;
+               }
+               else
+               {
+                  sb.append(c);
+               }
+               break;
+            case 3: // skip
+               if (!Character.isSpaceChar(c))
+               {
+                  if (c == '"')
+                  {
+                     state = 1;
+                  }
+                  else if (c == '\'')
+                  {
+                     state = 2;
+                  }
+                  else
+                  {
+                     sb.append(c);
+                     state = 0;
+                  }
+               }
+               break;
+         }
+      }
+      if (state != 3)
+         args.add(sb.toString());
+      
+      return args.toArray(new String[args.size()]);
+   }
+   
    /**
     * @param node
     * @param tool
@@ -285,7 +370,9 @@ public final class ObjectToolExecutor
    private static void executeAgentAction(final NodeInfo node, final ObjectTool tool, Map<String, String> inputValues)
    {
       final NXCSession session = (NXCSession)ConsoleSharedData.getSession();
-      final String action = substituteMacros(tool.getData(), node, inputValues);
+      String[] parts = splitCommandLine(substituteMacros(tool.getData(), node, inputValues));
+      final String action = parts[0];
+      final String[] args = Arrays.copyOfRange(parts, 1, parts.length);
       
       if ((tool.getFlags() & ObjectTool.GENERATES_OUTPUT) == 0)
       {      
@@ -299,7 +386,7 @@ public final class ObjectToolExecutor
             @Override
             protected void runInternal(IProgressMonitor monitor) throws Exception
             {
-               session.executeAction(node.object.getObjectId(), action);
+               session.executeAction(node.object.getObjectId(), action, args);
                runInUIThread(new Runnable() {
                   @Override
                   public void run()
@@ -317,7 +404,7 @@ public final class ObjectToolExecutor
          try
          {
             AgentActionResults view = (AgentActionResults)window.getActivePage().showView(AgentActionResults.ID, secondaryId, IWorkbenchPage.VIEW_ACTIVATE);
-            view.executeAction(action);
+            view.executeAction(action, args);
          }
          catch(Exception e)
          {
index 250409c..275a78a 100644 (file)
@@ -42,6 +42,7 @@ public class AgentActionResults extends AbstractCommandResults implements TextOu
 
    private IOConsoleOutputStream out;
    private String lastAction = null;
+   private String[] lastArgs = null;
    private Action actionRestart;
    
    /**
@@ -55,7 +56,7 @@ public class AgentActionResults extends AbstractCommandResults implements TextOu
          @Override
          public void run()
          {
-            executeAction(lastAction);
+            executeAction(lastAction, lastArgs);
          }
       };
       actionRestart.setEnabled(false);
@@ -100,12 +101,13 @@ public class AgentActionResults extends AbstractCommandResults implements TextOu
    /**
     * @param action
     */
-   public void executeAction(final String action)
+   public void executeAction(final String action, final String[] args)
    {
       actionRestart.setEnabled(false);
       final NXCSession session = (NXCSession)ConsoleSharedData.getSession();
       out = console.newOutputStream();
       lastAction = action;
+      lastArgs = args;
       ConsoleJob job = new ConsoleJob(String.format(Messages.get().ObjectToolsDynamicMenu_ExecuteOnNode, session.getObjectName(nodeId)), null, Activator.PLUGIN_ID, null) {
          @Override
          protected String getErrorMessage()
@@ -118,7 +120,7 @@ public class AgentActionResults extends AbstractCommandResults implements TextOu
          {
             try
             {
-               session.executeAction(nodeId, action, true, AgentActionResults.this, null);
+               session.executeAction(nodeId, action, args, true, AgentActionResults.this, null);
                out.write(Messages.get(getDisplay()).LocalCommandResults_Terminated);
             }
             finally