Merge branch 'ff/libcollectdclient'
[collectd.git] / src / libcollectdclient / client.c
index 7685544..b3f9644 100644 (file)
 
 #include "client.h"
 
+/* Secure/static macros. They work like `strcpy' and `strcat', but assure null
+ * termination. They work for static buffers only, because they use `sizeof'.
+ * The `SSTRCATF' combines the functionality of `snprintf' and `strcat' which
+ * is very useful to add formatted stuff to the end of a buffer. */
 #define SSTRCPY(d,s) do { \
     strncpy ((d), (s), sizeof (d)); \
     (d)[sizeof (d) - 1] = 0; \
@@ -680,7 +684,7 @@ int lcc_putval (lcc_connection_t *c, const lcc_value_list_t *vl) /* {{{ */
 {
   char ident_str[6 * LCC_NAME_LEN];
   char ident_esc[12 * LCC_NAME_LEN];
-  char command[1024];
+  char command[1024] = "";
   lcc_response_t res;
   int status;
   size_t i;
@@ -697,19 +701,11 @@ int lcc_putval (lcc_connection_t *c, const lcc_value_list_t *vl) /* {{{ */
   if (status != 0)
     return (status);
 
-  snprintf (command, sizeof (command), "PUTVAL %s",
+  SSTRCATF (command, "PUTVAL %s",
       lcc_strescape (ident_esc, ident_str, sizeof (ident_esc)));
-  command[sizeof (command) - 1] = 0;
 
   if (vl->interval > 0)
-  {
-    char option[64];
-
-    snprintf (option, sizeof (option), " interval=%i", vl->interval);
-    option[sizeof (option) - 1] = 0;
-
-    SSTRCAT (command, option);
-  }
+    SSTRCATF (command, " interval=%i", vl->interval);
 
   if (vl->time > 0)
     SSTRCATF (command, "%u", (unsigned int) vl->time);
@@ -744,8 +740,58 @@ int lcc_putval (lcc_connection_t *c, const lcc_value_list_t *vl) /* {{{ */
   return (0);
 } /* }}} int lcc_putval */
 
-/* TODO: Implement lcc_flush */
-int lcc_flush (lcc_connection_t *c, lcc_identifier_t *ident, int timeout);
+int lcc_flush (lcc_connection_t *c, const char *plugin, /* {{{ */
+    lcc_identifier_t *ident, int timeout)
+{
+  char command[1024];
+  lcc_response_t res;
+  int status;
+
+  if (c == NULL)
+  {
+    lcc_set_errno (c, EINVAL);
+    return (-1);
+  }
+
+  SSTRCPY (command, "FLUSH");
+
+  if (timeout > 0)
+    SSTRCATF (command, " timeout=%i", timeout);
+
+  if (plugin != NULL)
+  {
+    char buffer[2 * LCC_NAME_LEN];
+    SSTRCATF (command, " plugin=%s",
+        lcc_strescape (buffer, plugin, sizeof (buffer)));
+  }
+
+  if (ident != NULL)
+  {
+    char ident_str[6 * LCC_NAME_LEN];
+    char ident_esc[12 * LCC_NAME_LEN];
+
+    status = lcc_identifier_to_string (c, ident_str, sizeof (ident_str), ident);
+    if (status != 0)
+      return (status);
+
+    SSTRCATF (command, " identifier=%s",
+        lcc_strescape (ident_esc, ident_str, sizeof (ident_esc)));
+  }
+
+  status = lcc_sendreceive (c, command, &res);
+  if (status != 0)
+    return (status);
+
+  if (res.status != 0)
+  {
+    LCC_SET_ERRSTR (c, "Server error: %s", res.message);
+    lcc_response_free (&res);
+    return (-1);
+  }
+
+  lcc_response_free (&res);
+  return (0);
+} /* }}} int lcc_flush */
 
 /* TODO: Implement lcc_putnotif */