]> granicus.if.org Git - pdns/commitdiff
apply variant of code in t714 so we can lauch pipe backend scripts with parameters...
authorBert Hubert <bert.hubert@netherlabs.nl>
Thu, 7 Mar 2013 09:55:38 +0000 (09:55 +0000)
committerBert Hubert <bert.hubert@netherlabs.nl>
Thu, 7 Mar 2013 09:55:38 +0000 (09:55 +0000)
git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@3111 d19b8d6e-7fed-0310-83ef-9ca221ded41b

modules/pipebackend/coprocess.cc
modules/pipebackend/coprocess.hh
modules/pipebackend/pipebackend.cc
modules/pipebackend/pipebackend.hh

index cc2b5198e651c3ca0dbc813f1ff01d64205f661f..1b85a286b0d8eb4d2e562640be48aded9bb2677e 100644 (file)
@@ -7,21 +7,26 @@
 #include <string.h>
 #include <sys/types.h>
 #include <sys/wait.h>
+#include <sys/un.h>
 #include <pdns/misc.hh>
 #include <pdns/ahuexception.hh>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <boost/algorithm/string.hpp>
+#include <vector>
 
 CoProcess::CoProcess(const string &command,int timeout, int infd, int outfd)
 {
-  const char *argv[2];
-  argv[0]=strdup(command.c_str());
-  argv[1]=0;
+  vector <string> v;
+  split(v, command, is_any_of(" "));
 
-  launch(argv,timeout,infd,outfd);
-}
+  const char *argv[v.size()+1];
+  argv[v.size()]=0;
 
-CoProcess::CoProcess(const char **argv, int timeout, int infd, int outfd)
-{
-  launch(argv,timeout,infd,outfd);
+  for (size_t n = 0; n < v.size(); n++)
+    argv[n]=v[n].c_str();
+  // we get away with not copying since nobody resizes v 
+  launch(argv, timeout, infd, outfd);
 }
 
 void CoProcess::launch(const char **argv, int timeout, int infd, int outfd)
@@ -158,6 +163,58 @@ void CoProcess::sendReceive(const string &snd, string &rcv)
   receive(rcv);
 
 }
+
+UnixRemote::UnixRemote(const string& path, int timeout) 
+{
+  d_fd = socket(AF_LOCAL, SOCK_STREAM, 0);
+  if(d_fd < 0)
+    throw AhuException("Unable to create UNIX domain socket: "+string(strerror(errno)));
+
+  struct sockaddr_un remote;
+  memset(&remote, 0, sizeof(remote));
+  remote.sun_family = AF_UNIX;
+  memset(remote.sun_path, 0, sizeof(remote.sun_path));
+  path.copy(remote.sun_path, sizeof(remote.sun_path), 0);
+
+  // fcntl(fd, F_SETFL, O_NONBLOCK, &sock);
+
+  if(connect(d_fd, (struct sockaddr*)&remote, sizeof(remote)) < 0)
+    unixDie("Unable to connect to remote '"+path+"' using UNIX domain socket");
+
+  d_fp = fdopen(d_fd, "r");
+}
+
+void UnixRemote::send(const string& line)
+{
+  string nline(line);
+  nline.append(1, '\n');
+  writen2(d_fd, nline);
+}
+
+void UnixRemote::receive(string& line)
+{
+  line.clear();
+  stringfgets(d_fp, line);
+  trim_right(line);
+}
+
+void UnixRemote::sendReceive(const string &snd, string &rcv)
+{
+  //  checkStatus();
+  send(snd);
+  receive(rcv);
+}
+
+bool isUnixSocket(const string& fname)
+{
+  struct stat st;
+  if(stat(fname.c_str(), &st) < 0)
+    return false; // not a unix socket in any case ;-)
+
+  return (st.st_mode & S_IFSOCK) == S_IFSOCK;
+}
+
+
 #ifdef TESTDRIVER
 main()
 {
index c2cc454d625f6762126bf2a464b16c06d3a53162..a405afc26535008584f76aab82b298e0c576dbf5 100644 (file)
@@ -5,20 +5,27 @@
 #include <stdio.h>
 #include <string>
 
-#include "pdns/namespaces.hh" 
+#include "pdns/namespaces.hh"
 
-class CoProcess
+class CoRemote
+{
+public:
+  virtual void sendReceive(const string &send, string &receive) = 0;
+  virtual void receive(string &rcv) = 0;
+  virtual void send(const string &send) = 0;
+
+};
+
+class CoProcess : public CoRemote
 {
 public:
   CoProcess(const string &command,int timeout=0, int infd=0, int outfd=1);
-  CoProcess(const char **argv, int timeout=0, int infd=0, int outfd=1);
   ~CoProcess();
-
-  void launch(const char **argv, int timeout=0, int infd=0, int outfd=1);
   void sendReceive(const string &send, string &receive);
   void receive(string &rcv);
   void send(const string &send);
 private:
+  void launch(const char **argv, int timeout=0, int infd=0, int outfd=1);
   void checkStatus();
   int d_fd1[2], d_fd2[2];
   int d_pid;
@@ -27,4 +34,18 @@ private:
   int d_timeout;
   FILE *d_fp;
 };
+
+class UnixRemote : public CoRemote
+{
+public:
+  UnixRemote(const string &path, int timeout=0);
+  ~UnixRemote();
+  void sendReceive(const string &send, string &receive);
+  void receive(string &rcv);
+  void send(const string &send);
+private:
+  int d_fd;
+  FILE *d_fp;
+};
+bool isUnixSocket(const string& fname);
 #endif
index 511d9e8af2b3539e66af96f19da66e1676222e12..daf3876dbe5b2b575d9278fdd52bd41ba6073dc4 100644 (file)
@@ -48,7 +48,10 @@ void CoWrapper::launch()
    if(d_cp)
       return;
 
-   d_cp=new CoProcess(d_command, d_timeout); 
+   if(isUnixSocket(d_command))
+     d_cp = new UnixRemote(d_command, d_timeout);
+   else
+     d_cp = new CoProcess(d_command, d_timeout); 
    d_cp->send("HELO\t"+lexical_cast<string>(::arg().asNum("pipebackend-abi-version")));
    string banner;
    d_cp->receive(banner); 
index 94712c870b8901c522d3e9030f219cf3cafc3077..6123d27715517bcf68debcd094f3ad3feca802ed 100644 (file)
@@ -25,7 +25,7 @@ public:
   void send(const string &line);
   void receive(string &line);
 private:
-  CoProcess* d_cp;
+  CoRemote* d_cp;
   string d_command;
   void launch();
   int d_timeout;