Added scheduled file upload callback registaration
authorZev <zev@radensolutions.com>
Tue, 6 Oct 2015 13:07:07 +0000 (16:07 +0300)
committerZev <zev@radensolutions.com>
Tue, 6 Oct 2015 13:07:07 +0000 (16:07 +0300)
include/appagent.h
include/nms_util.h
src/libnetxms/tools.cpp
src/server/core/schedule.cpp
src/server/core/script.cpp
src/server/core/upload_job.cpp
src/server/include/nms_script.h
src/server/include/nxcore_schedule.h

index 9f3ed46..6b04df5 100644 (file)
@@ -1,4 +1,4 @@
-/* 
+/*
 ** NetXMS - Network Management System
 ** Copyright (C) 2003-2013 Victor Kirhenshtein
 **
index 32e2340..0a37d97 100644 (file)
@@ -1429,6 +1429,17 @@ BOOL LIBNETXMS_EXPORTABLE RegexpMatchW(const WCHAR *str, const WCHAR *expr, bool
 #define RegexpMatch RegexpMatchA
 #endif
 
+/**
+ * Parse parameters line func(param1, param2,...)
+ */
+bool LIBNETXMS_EXPORTABLE ParseParameterArgA(const TCHAR *param, int index, char *arg, int maxSize);
+bool LIBNETXMS_EXPORTABLE ParseParameterArgW(const TCHAR *param, int index, WCHAR *arg, int maxSize);
+#ifdef UNICODE
+#define ParseParameterArg ParseParameterArgW
+#else
+#define ParseParameterArg ParseParameterArgA
+#endif
+
 const TCHAR LIBNETXMS_EXPORTABLE *ExpandFileName(const TCHAR *name, TCHAR *buffer, size_t bufSize, bool allowShellCommand);
 BOOL LIBNETXMS_EXPORTABLE CreateFolder(const TCHAR *directory);
 TCHAR LIBNETXMS_EXPORTABLE *Trim(TCHAR *str);
index dcec8d4..314bf2e 100644 (file)
@@ -2601,3 +2601,135 @@ TCHAR LIBNETXMS_EXPORTABLE *GetHeapInfo()
    return _tcsdup(_T("No heap information API available"));
 #endif
 }
+
+/**
+ * Get arguments for parameters like name(arg1,...)
+ * Returns FALSE on processing error
+ */
+static bool ParseParameterArgInternal(const TCHAR *param, int index, TCHAR *arg, int maxSize)
+{
+   const TCHAR *ptr1, *ptr2;
+   int state, currIndex, pos;
+   bool success = true;
+
+   arg[0] = 0;    // Default is empty string
+   ptr1 = _tcschr(param, _T('('));
+   if (ptr1 == NULL)
+      return true;  // No arguments at all
+   for(ptr2 = ptr1 + 1, currIndex = 1, state = 0, pos = 0; state != -1; ptr2++)
+   {
+      switch(state)
+      {
+         case 0:  // Normal
+            switch(*ptr2)
+            {
+               case _T(')'):
+                  if (currIndex == index)
+                     arg[pos] = 0;
+                  state = -1;    // Finish processing
+                  break;
+               case _T('"'):
+                  state = 1;     // String
+                  break;
+               case _T('\''):        // String, type 2
+                  state = 2;
+                  break;
+               case _T(','):
+                  if (currIndex == index)
+                  {
+                     arg[pos] = 0;
+                     state = -1;
+                  }
+                  else
+                  {
+                     currIndex++;
+                  }
+                  break;
+               case 0:
+                  state = -1;       // Finish processing
+                  success = false;  // Set error flag
+                  break;
+               default:
+                  if ((currIndex == index) && (pos < maxSize - 1))
+                     arg[pos++] = *ptr2;
+            }
+            break;
+         case 1:  // String in ""
+            switch(*ptr2)
+            {
+               case _T('"'):
+                  state = 0;     // Normal
+                  break;
+               case 0:
+                  state = -1;       // Finish processing
+                  success = false;  // Set error flag
+                  break;
+               default:
+                  if ((currIndex == index) && (pos < maxSize - 1))
+                     arg[pos++] = *ptr2;
+            }
+            break;
+         case 2:  // String in ''
+            switch(*ptr2)
+            {
+               case _T('\''):
+                  state = 0;     // Normal
+                  break;
+               case 0:
+                  state = -1;       // Finish processing
+                  success = false;  // Set error flag
+                  break;
+               default:
+                  if ((currIndex == index) && (pos < maxSize - 1))
+                     arg[pos++] = *ptr2;
+            }
+            break;
+      }
+   }
+
+   if (success)
+      StrStrip(arg);
+   return success;
+}
+
+/**
+ * Get arguments for parameters like name(arg1,...) as multibyte string
+ * Returns FALSE on processing error
+ */
+bool LIBNETXMS_EXPORTABLE ParseParameterArgA(const TCHAR *param, int index, char *arg, int maxSize)
+{
+#ifdef UNICODE
+       WCHAR *temp = (WCHAR *)malloc(maxSize * sizeof(WCHAR));
+       bool success = ParseParameterArgInternal(param, index, temp, maxSize);
+       if (success)
+       {
+               WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK | WC_DEFAULTCHAR, temp, -1, arg, maxSize, NULL, NULL);
+               arg[maxSize - 1] = 0;
+       }
+       free(temp);
+       return success;
+#else
+       return ParseParameterArgInternal(param, index, arg, maxSize);
+#endif
+}
+
+/**
+ * Get arguments for parameters like name(arg1,...) as UNICODE string
+ * Returns FALSE on processing error
+ */
+bool LIBNETXMS_EXPORTABLE ParseParameterArgW(const TCHAR *param, int index, WCHAR *arg, int maxSize)
+{
+#ifdef UNICODE
+       return ParseParameterArgInternal(param, index, arg, maxSize);
+#else
+       char *temp = (char *)malloc(maxSize);
+       bool success = ParseParameterArgInternal(param, index, temp, maxSize);
+       if (success)
+       {
+               MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, temp, -1, arg, maxSize);
+               arg[maxSize - 1] = 0;
+       }
+       free(temp);
+       return success;
+#endif
+}
index 0a66413..fb549b5 100644 (file)
@@ -125,7 +125,8 @@ void Schedule::run(ScheduleCallback *callback)
    bool oneTimeSchedule = !_tcscmp(m_schedule, _T(""));
 
    setFlag(SCHEDULE_IN_PROGRES);
-   callback->m_func(m_params);
+   ScheduleParameters param(m_params, m_owner);
+   callback->m_func(&param);
    setLastExecutionTime(time(NULL));
 
    if (oneTimeSchedule)
@@ -596,6 +597,7 @@ static THREAD_RESULT THREAD_CALL OneTimeEventThread(void *arg)
       MutexUnlock(s_oneTimeScheduleLock);
    }
    DbgPrintf(3, _T("OneTimeEventThread: stopped"));
+   return THREAD_OK;
 }
 
 /**
@@ -628,6 +630,7 @@ static THREAD_RESULT THREAD_CALL CronCheckThread(void *arg)
       MutexUnlock(s_cronScheduleLock);
    } while(!SleepAndCheckForShutdown(60)); //sleep 1 minute
    DbgPrintf(3, _T("CronCheckThread: stopped"));
+   return THREAD_OK;
 }
 
 /**
index 3a66434..7b47c41 100644 (file)
@@ -238,12 +238,12 @@ void ImportScript(ConfigEntry *config)
    ReloadScript(id);
 }
 
-void LIBNXSL_EXPORTABLE ExecuteScript(const TCHAR *param)
+void LIBNXSL_EXPORTABLE ExecuteScript(const ScheduleParameters *param)
 {
    size_t bufSize = 512;
    TCHAR *buffer[512];
    TCHAR name[256];
-   nx_strncpy(name, param, 256);
+   nx_strncpy(name, param->m_params, 256);
    Trim(name);
 
    ObjectArray<NXSL_Value> args(16, 16, false);
index 7524a07..76beb37 100644 (file)
@@ -29,6 +29,55 @@ int FileUploadJob::m_activeJobs = 0;
 int FileUploadJob::m_maxActiveJobs = 10;
 MUTEX FileUploadJob::m_sharedDataMutex = INVALID_MUTEX_HANDLE;
 
+void ScheduledUploadFile(const ScheduleParameters *params)
+{
+   //get parameters - node id or name, server file name, agent file name
+   TCHAR nodeId[8];
+   TCHAR serverFile[MAX_PATH];
+   TCHAR agentFile[MAX_PATH];
+   ParseParameterArg(params->m_params, 1, nodeId, 8);
+   ParseParameterArg(params->m_params, 1, serverFile, MAX_PATH);
+   ParseParameterArg(params->m_params, 1, agentFile, MAX_PATH);
+   if(nodeId == NULL || serverFile == NULL || agentFile == NULL)
+   {
+      DbgPrintf(4, _T("UploadFile: One of parameters was nodeId=\'%s\', serverFile=\'%s\', agentFile=\'%s\'"),
+            nodeId, serverFile, agentFile);
+      return;
+   }
+
+   UINT32 id = _tcstoul(nodeId, NULL, 0);
+   Node *object = (Node *)FindObjectById(id, OBJECT_NODE);
+   if (object != NULL)
+   {
+      if (object->checkAccessRights(params->m_userId, OBJECT_ACCESS_CONTROL))
+      {
+         TCHAR fullPath[MAX_PATH];
+
+         // Create full path to the file store
+         _tcscpy(fullPath, g_netxmsdDataDir);
+         _tcscat(fullPath, DDIR_FILES);
+         _tcscat(fullPath, FS_PATH_SEPARATOR);
+         int len = (int)_tcslen(fullPath);
+         nx_strncpy(&fullPath[len], GetCleanFileName(serverFile), MAX_PATH - len);
+
+         ServerJob *job = new FileUploadJob((Node *)object, fullPath, agentFile, params->m_userId, false);
+         if (AddJob(job))
+         {
+            DbgPrintf(4, _T("ScheduledUploadFile: File(%s) uploaded to %s node, to %s "), serverFile, object->getName(), agentFile);
+            //auditlog?
+         }
+         else
+         {
+            delete job;
+         }
+      }
+      else
+         DbgPrintf(4, _T("ScheduledUploadFile: Access to node %s denied"), object->getName());
+   }
+   else
+      DbgPrintf(4, _T("ScheduledUploadFile: Node with id[%d(%s)] not found"), id, nodeId);
+}
+
 /**
  * Static initializer
  */
@@ -36,6 +85,7 @@ void FileUploadJob::init()
 {
        m_sharedDataMutex = MutexCreate();
        m_maxActiveJobs = ConfigReadInt(_T("MaxActiveUploadJobs"), 10);
+       RegisterSchedulerTaskHandler(_T("Upload.File"), ScheduledUploadFile, SYSTEM_ACCESS_SCHEDULE_SCRIPT);
 }
 
 /**
index b744b4e..49e64a4 100644 (file)
@@ -158,6 +158,7 @@ public:
        virtual void trace(int level, const TCHAR *text);
 };
 
+class ScheduleParameters;
 /**
  * Functions
  */
@@ -168,7 +169,7 @@ UINT32 ResolveScriptName(const TCHAR *name);
 void CreateScriptExportRecord(String &xml, UINT32 id);
 void ImportScript(ConfigEntry *config);
 NXSL_VM *FindHookScript(const TCHAR *hookName);
-void ExecuteScript(const TCHAR *param);
+void ExecuteScript(const ScheduleParameters *param);
 bool ParseValueList(TCHAR **start, ObjectArray<NXSL_Value> &args);
 
 /**
index cca5d65..902f5c6 100644 (file)
@@ -33,8 +33,9 @@
 
 class Schedule;
 class ScheduleCallback;
+class ScheduleParameters;
 
-typedef void (*scheduled_action_executor)(const TCHAR *params);
+typedef void (*scheduled_action_executor)(const ScheduleParameters *params);
 
 /**
  * Static fields
@@ -68,6 +69,16 @@ public:
    ScheduleCallback(scheduled_action_executor func, UINT64 accessRight) { m_func = func; m_accessRight = accessRight; }
 };
 
+class ScheduleParameters
+{
+public:
+   TCHAR *m_params;
+   UINT32 m_userId;
+
+   ScheduleParameters(TCHAR *param, UINT32 userId){m_params = _tcsdup(param); m_userId = userId; }
+   ScheduleParameters(){ delete m_params; }
+};
+
 class Schedule
 {
 private: