FETCH command (only tcp4 so far)
authorChristian Thaeter <ct@pipapo.org>
Mon, 22 Oct 2007 18:57:49 +0000 (20:57 +0200)
committerChristian Thaeter <ct@pipapo.org>
Mon, 22 Oct 2007 18:57:49 +0000 (20:57 +0200)
src/rxpd_connection_cmd.c

index f1a2c67..c447692 100644 (file)
@@ -261,22 +261,18 @@ rxpd_connection_cmd_FETCH (struct rxpd_connection* self)
   line = rxpd_buffer_readline (&self->in);
   if (*line)
     {
-      pth_rwlock_acquire (&self->file->lock, PTH_RWLOCK_RW, FALSE, NULL);
-
-      rxpd_file_rules_delete (self->file);
+      /* parse line */
 
       char* list = strrchr (line, '/');
-      // TODO error handling
       if (!list)
-        rxpd_die ("syntax error");
+        goto esyntax;
 
       *list = '\0';
       ++ list;
 
       char* port = strrchr (line, ':');
-      // TODO error handling / unix domain sockets
       if (!port)
-        rxpd_die ("syntax error");
+        goto esyntax;
 
       *port = '\0';
       ++ port;
@@ -284,7 +280,13 @@ rxpd_connection_cmd_FETCH (struct rxpd_connection* self)
       struct addrinfo* addrs = NULL;
       int aierr;
 
+      /* resolve peer */
       aierr = getaddrinfo (line, port, NULL, &addrs);
+      if (aierr)
+        {
+          rxpd_buffer_printf (&self->out, "#ERROR: resolving '%s': %s\n", line, gai_strerror (aierr));
+          return;
+        }
 
       rxpd_log (base, LOG_INFO, "fetching list '%s' from '%s(%s)' at port '%s' to '%s'\n",
                 list,
@@ -293,18 +295,55 @@ rxpd_connection_cmd_FETCH (struct rxpd_connection* self)
                 port,
                 self->file->node.key);
 
-      if (aierr)
-        rxpd_die ("resolv error %s\n", gai_strerror (aierr));
+      /* establish connection */
+      int fd = socket (addrs->ai_family, addrs->ai_socktype, addrs->ai_protocol);
+      if (fd == -1 || connect (fd, addrs->ai_addr, addrs->ai_addrlen))
+        {
+          freeaddrinfo (addrs);
+          rxpd_buffer_printf (&self->out, "#ERROR: error connecting '%s': %s\n", line, strerror (errno));
+          return;
+        }
+      freeaddrinfo (addrs);
 
-      // connect
-      // send dump
-      // add recieving event
+      /* send DUMP command and fetch data */
+      struct rxpd_buffer in;
+      struct rxpd_buffer out;
+      rxpd_buffer_init (&in, fd);
+      rxpd_buffer_init (&out, fd);
 
-      freeaddrinfo (addrs);
+      rxpd_buffer_printf (&out, "DUMP:%s\n", list);
+
+      char* line;
+      while ((line = rxpd_buffer_readline (&in)))
+        {
+          if (*line && strncmp (line, "#ERROR:", sizeof ("#ERROR:")-1))
+            {
+              struct rxpd_rule* rule;
+              rule = rxpd_rule_new (line);
+              if (!rule)
+                rxpd_die ("rule creation failed on '%s'\n", line);
 
+              llist_insert_tail (&self->tmp_list, &rule->node);
+            }
+          else
+            rxpd_log (base, LOG_INFO, "purge remote side error '%s'\n", line);
+        }
+      rxpd_log (base, LOG_DEBUG, "finished dump\n");
 
+      close (fd);
+
+      pth_rwlock_acquire (&self->file->lock, PTH_RWLOCK_RW, FALSE, NULL);
+      rxpd_file_rules_delete (self->file);
+      llist_insertlist_next (&self->file->rules, &self->tmp_list);
       pth_rwlock_release (&self->file->lock);
 
+      rxpd_buffer_printf (&self->out, "#OK:\n");
+    }
+  else
+    {
+    esyntax:
+      rxpd_buffer_printf (&self->out, "#ERROR: syntax error\n");
     }
 }