]> granicus.if.org Git - icinga2/commitdiff
Implemented command pipe (sort of).
authorGunnar Beutner <gunnar.beutner@netways.de>
Mon, 21 Jan 2013 12:08:08 +0000 (13:08 +0100)
committerGunnar Beutner <gunnar.beutner@netways.de>
Mon, 21 Jan 2013 12:08:08 +0000 (13:08 +0100)
components/compat/compatcomponent.cpp
components/compat/compatcomponent.h
lib/base/socket.cpp

index 2faa003d856e5459b7d90d6d105c42b66b20a974..367b5573ebfb35a9f0da6944ee1aecdb48844fa2 100644 (file)
@@ -29,31 +29,48 @@ using namespace icinga;
 
 const String CompatComponent::DefaultStatusPath = Application::GetLocalStateDir() + "/status.dat";
 const String CompatComponent::DefaultObjectsPath = Application::GetLocalStateDir() + "/objects.cache";
+const String CompatComponent::DefaultCommandPath = Application::GetLocalStateDir() + "/icinga.cmd";
 
 /**
- * Reads status path from config
+ * Retrieves the status.dat path.
+ *
  * @returns statuspath from config, or static default
  */
 String CompatComponent::GetStatusPath(void) const
 {
-       Value statuspath = GetConfig()->Get("status_path");
-       if(statuspath.IsEmpty())
+       Value statusPath = GetConfig()->Get("status_path");
+       if (statusPath.IsEmpty())
                return DefaultStatusPath;
        else
-               return statuspath;
+               return statusPath;
 }
 
 /**
- * Reads objects path from config
+ * Retrieves the objects.cache path.
+ *
  * @returns objectspath from config, or static default
  */
 String CompatComponent::GetObjectsPath(void) const
 {
-        Value objectspath = GetConfig()->Get("objects_path");
-        if(objectspath.IsEmpty())
-                return DefaultObjectsPath;
-        else
-                return objectspath;
+       Value objectsPath = GetConfig()->Get("objects_path");
+       if (objectsPath.IsEmpty())
+               return DefaultObjectsPath;
+       else
+               return objectsPath;
+}
+
+/**
+ * Retrieves the icinga.cmd path.
+ *
+ * @returns icinga.cmd path
+ */
+String CompatComponent::GetCommandPath(void) const
+{
+       Value commandPath = GetConfig()->Get("command_path");
+       if (commandPath.IsEmpty())
+               return DefaultCommandPath;
+       else
+               return commandPath;
 }
 
 /**
@@ -66,6 +83,9 @@ void CompatComponent::Start(void)
        m_StatusTimer->OnTimerExpired.connect(boost::bind(&CompatComponent::StatusTimerHandler, this));
        m_StatusTimer->Start();
        m_StatusTimer->Reschedule(0);
+
+       m_CommandThread = thread(boost::bind(&CompatComponent::CommandPipeThread, this, GetCommandPath()));
+       m_CommandThread.detach();
 }
 
 /**
@@ -75,6 +95,49 @@ void CompatComponent::Stop(void)
 {
 }
 
+void CompatComponent::CommandPipeThread(const String& commandPath)
+{
+       (void) unlink(commandPath.CStr());
+
+       int rc = mkfifo(commandPath.CStr(), S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
+
+       if (rc < 0)
+               throw_exception(PosixException("mkfifo() failed", errno));
+
+       for (;;) {
+               int fd = open(commandPath.CStr(), O_RDONLY);
+
+               if (fd < 0)
+                       throw_exception(PosixException("open() failed", errno));
+
+               FILE *fp = fdopen(fd, "r");
+
+               if (fp == NULL) {
+                       close(fd);
+                       throw_exception(PosixException("fdopen() failed", errno));
+               }
+
+               char line[2048];
+
+               while (fgets(line, sizeof(line), fp) != NULL) {
+                       // remove trailing new-line
+                       while (strlen(line) > 0 &&
+                           (line[strlen(line) - 1] == '\r' || line[strlen(line) - 1] == '\n'))
+                               line[strlen(line) - 1] = '\0';
+
+                       String command = line;
+                       Event::Post(boost::bind(&CompatComponent::ProcessCommand, this, command));
+               }
+
+               fclose(fp);
+       }
+}
+
+void CompatComponent::ProcessCommand(const String& command)
+{
+       Logger::Write(LogInformation, "compat", "Received command: " + command);
+}
+
 void CompatComponent::DumpHostStatus(ofstream& fp, const Host::Ptr& host)
 {
        int state;
index 08d1b57e94c57bfb786cb4ec81cdfaa9add50731..fc06c91902a1f3a961f34110842c134932e21793 100644 (file)
@@ -34,9 +34,14 @@ public:
 
 private:
        Timer::Ptr m_StatusTimer;
+       thread m_CommandThread;
 
        String GetStatusPath(void) const;
        String GetObjectsPath(void) const;
+       String GetCommandPath(void) const;
+
+       void CommandPipeThread(const String& commandPath);
+       void ProcessCommand(const String& command);
 
        void DumpHostStatus(ofstream& fp, const Host::Ptr& host);
        void DumpHostObject(ofstream& fp, const Host::Ptr& host);
@@ -64,6 +69,7 @@ private:
 
        static const String DefaultStatusPath;
        static const String DefaultObjectsPath;
+       static const String DefaultCommandPath;
 };
 
 }
index 33f0891821ea44df404de4f0313c77e235345a94..e73582cb6a79d7b7f63f71db5b8644291cba4af9 100644 (file)
@@ -51,6 +51,7 @@ void Socket::Start(void)
        assert(!m_ReadThread.joinable() && !m_WriteThread.joinable());
        assert(GetFD() != INVALID_SOCKET);
 
+       // TODO: figure out why we're not using "this" here
        m_ReadThread = thread(boost::bind(&Socket::ReadThreadProc, static_cast<Socket::Ptr>(GetSelf())));
        m_ReadThread.detach();