[rrd-developers] [PATCH] rrd_client: Do not rewrite path names when accessing remote daemons.
Sebastian Harl
sh at tokkee.org
Sat Oct 3 23:23:00 CEST 2009
When talking to a local daemon (thru a UNIX socket), relative path names are
resolved to absolute path names to allow for transparent integration into
existing solutions (as requested by Tobi).
However, when talking to a remote daemon, absolute path names are not allowed,
since path name translation is done by the server (relative to the base
directory).
---
program/src/rrd_client.c | 84 ++++++++++++++++++++++++++++++++++++++--------
1 files changed, 70 insertions(+), 14 deletions(-)
diff --git a/program/src/rrd_client.c b/program/src/rrd_client.c
index 8e60664..013b7e3 100644
--- a/program/src/rrd_client.c
+++ b/program/src/rrd_client.c
@@ -17,6 +17,7 @@
*
* Authors:
* Florian octo Forster <octo at verplant.org>
+ * Sebastian tokkee Harl <sh at tokkee.org>
**/
#include "rrd.h"
@@ -51,6 +52,45 @@ static int sd = -1;
static FILE *sh = NULL;
static char *sd_path = NULL; /* cache the path for sd */
+/* get_path: Return a path name appropriate to be sent to the daemon.
+ *
+ * When talking to a local daemon (thru a UNIX socket), relative path names
+ * are resolved to absolute path names to allow for transparent integration
+ * into existing solutions (as requested by Tobi). Else, absolute path names
+ * are not allowed, since path name translation is done by the server.
+ *
+ * One must hold `lock' when calling this function. */
+static const char *get_path (const char *path, char *resolved_path) /* {{{ */
+{
+ const char *ret = path;
+ int is_unix = 0;
+
+ if ((*sd_path == '/')
+ || (strncmp ("unix:", sd_path, strlen ("unix:")) == 0))
+ is_unix = 1;
+
+ if (*path == '/') /* absolute path */
+ {
+ if (! is_unix)
+ {
+ rrd_set_error ("absolute path names not allowed when talking "
+ "to a remote daemon");
+ return (NULL);
+ }
+ /* else: nothing to do */
+ }
+ else /* relative path */
+ {
+ if (is_unix)
+ {
+ realpath (path, resolved_path);
+ ret = resolved_path;
+ }
+ /* else: nothing to do */
+ }
+ return (ret);
+} /* }}} char *get_path */
+
/* One must hold `lock' when calling `close_connection'. */
static void close_connection (void) /* {{{ */
{
@@ -255,19 +295,13 @@ static int request (const char *buffer, size_t buffer_size, /* {{{ */
int status;
rrdc_response_t *res;
- pthread_mutex_lock (&lock);
-
if (sh == NULL)
- {
- pthread_mutex_unlock (&lock);
return (ENOTCONN);
- }
status = (int) fwrite (buffer, buffer_size, /* nmemb = */ 1, sh);
if (status != 1)
{
close_connection ();
- pthread_mutex_unlock (&lock);
rrd_set_error("request: socket error (%d) while talking to rrdcached",
status);
return (-1);
@@ -277,8 +311,6 @@ static int request (const char *buffer, size_t buffer_size, /* {{{ */
res = NULL;
status = response_read (&res);
- pthread_mutex_unlock (&lock);
-
if (status != 0)
{
if (status < 0)
@@ -528,19 +560,29 @@ int rrdc_update (const char *filename, int values_num, /* {{{ */
if (status != 0)
return (ENOBUFS);
- /* change to absolute path for rrdcached */
- if (*filename != '/' && realpath(filename, file_path) != NULL)
- filename = file_path;
+ pthread_mutex_lock (&lock);
+ filename = get_path (filename, file_path);
+ if (filename == NULL)
+ {
+ pthread_mutex_unlock (&lock);
+ return (-1);
+ }
status = buffer_add_string (filename, &buffer_ptr, &buffer_free);
if (status != 0)
+ {
+ pthread_mutex_unlock (&lock);
return (ENOBUFS);
+ }
for (i = 0; i < values_num; i++)
{
status = buffer_add_value (values[i], &buffer_ptr, &buffer_free);
if (status != 0)
+ {
+ pthread_mutex_unlock (&lock);
return (ENOBUFS);
+ }
}
assert (buffer_free < sizeof (buffer));
@@ -550,6 +592,8 @@ int rrdc_update (const char *filename, int values_num, /* {{{ */
res = NULL;
status = request (buffer, buffer_size, &res);
+ pthread_mutex_unlock (&lock);
+
if (status != 0)
return (status);
@@ -580,13 +624,20 @@ int rrdc_flush (const char *filename) /* {{{ */
if (status != 0)
return (ENOBUFS);
- /* change to absolute path for rrdcached */
- if (*filename != '/' && realpath(filename, file_path) != NULL)
- filename = file_path;
+ pthread_mutex_lock (&lock);
+ filename = get_path (filename, file_path);
+ if (filename == NULL)
+ {
+ pthread_mutex_unlock (&lock);
+ return (-1);
+ }
status = buffer_add_string (filename, &buffer_ptr, &buffer_free);
if (status != 0)
+ {
+ pthread_mutex_unlock (&lock);
return (ENOBUFS);
+ }
assert (buffer_free < sizeof (buffer));
buffer_size = sizeof (buffer) - buffer_free;
@@ -595,6 +646,8 @@ int rrdc_flush (const char *filename) /* {{{ */
res = NULL;
status = request (buffer, buffer_size, &res);
+ pthread_mutex_unlock (&lock);
+
if (status != 0)
return (status);
@@ -659,7 +712,10 @@ int rrdc_stats_get (rrdc_stats_t **ret_stats) /* {{{ */
* }}} */
res = NULL;
+ pthread_mutex_lock (&lock);
status = request ("STATS\n", strlen ("STATS\n"), &res);
+ pthread_mutex_unlock (&lock);
+
if (status != 0)
return (status);
--
1.6.5.rc2
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: Digital signature
Url : http://lists.oetiker.ch/pipermail/rrd-developers/attachments/20091003/d1b0775b/attachment.pgp
More information about the rrd-developers
mailing list