X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Frrd_daemon.c;h=df31d514212199ddf21bdf7de767f7c27ae43b0c;hb=7c1813445012ad944e2d19c00acbb6809a5341bc;hp=5f25e1582adb6b546c529041c974000ac48bbb61;hpb=7e34dda6b303b67abb6b3a64b7357c91b2432c5f;p=rrdtool.git diff --git a/src/rrd_daemon.c b/src/rrd_daemon.c index 5f25e15..df31d51 100644 --- a/src/rrd_daemon.c +++ b/src/rrd_daemon.c @@ -91,11 +91,6 @@ # define __attribute__(x) /**/ #endif -#if 0 -/* FIXME: I don't want to declare strdup myself! */ -extern char *strdup (const char *s); -#endif - /* * Types */ @@ -167,7 +162,7 @@ static void sig_term_handler (int s __attribute__((unused))) /* {{{ */ */ static int enqueue_cache_item (cache_item_t *ci) /* {{{ */ { - RRDD_LOG (LOG_DEBUG, "handle_request_update: Adding %s to the update queue.", + RRDD_LOG (LOG_DEBUG, "enqueue_cache_item: Adding %s to the update queue.", ci->file); if (ci == NULL) @@ -178,12 +173,19 @@ static int enqueue_cache_item (cache_item_t *ci) /* {{{ */ assert (ci->next == NULL); + if (ci->values_num == 0) + return (0); + if (cache_queue_tail == NULL) cache_queue_head = ci; else cache_queue_tail->next = ci; cache_queue_tail = ci; + ci->flags |= CI_FLAGS_IN_QUEUE; + + ci->flags |= CI_FLAGS_IN_QUEUE; + return (0); } /* }}} int enqueue_cache_item */ @@ -204,7 +206,8 @@ static gboolean tree_callback_flush (gpointer key /* {{{ */ now = *((time_t *) data); if (((now - ci->last_flush_time) >= config_write_interval) - && ((ci->flags & CI_FLAGS_IN_QUEUE) == 0)) + && ((ci->flags & CI_FLAGS_IN_QUEUE) == 0) + && (ci->values_num > 0)) enqueue_cache_item (ci); return (TRUE); @@ -315,12 +318,70 @@ static void *queue_thread_main (void *args __attribute__((unused))) /* {{{ */ return (NULL); } /* }}} void *queue_thread_main */ +static int buffer_get_field (char **buffer_ret, /* {{{ */ + size_t *buffer_size_ret, char **field_ret) +{ + char *buffer; + size_t buffer_pos; + size_t buffer_size; + char *field; + size_t field_size; + int status; + + buffer = *buffer_ret; + buffer_pos = 0; + buffer_size = *buffer_size_ret; + field = *buffer_ret; + field_size = 0; + + /* This is ensured by `handle_request'. */ + assert (buffer[buffer_size - 1] == ' '); + + status = -1; + while (buffer_pos < buffer_size) + { + /* Check for end-of-field or end-of-buffer */ + if (buffer[buffer_pos] == ' ') + { + field[field_size] = 0; + field_size++; + buffer_pos++; + status = 0; + break; + } + /* Handle escaped characters. */ + else if (buffer[buffer_pos] == '\\') + { + if (buffer_pos >= (buffer_size - 1)) + break; + buffer_pos++; + field[field_size] = buffer[buffer_pos]; + field_size++; + buffer_pos++; + } + /* Normal operation */ + else + { + field[field_size] = buffer[buffer_pos]; + field_size++; + buffer_pos++; + } + } /* while (buffer_pos < buffer_size) */ + + if (status != 0) + return (status); + + *buffer_ret = buffer + buffer_pos; + *buffer_size_ret = buffer_size - buffer_pos; + *field_ret = field; + + return (0); +} /* }}} int buffer_get_field */ + static int handle_request_update (int fd, /* {{{ */ - char *buffer, int buffer_size __attribute__((unused))) + char *buffer, size_t buffer_size) { char *file; - char *value; - char *buffer_ptr; int values_num = 0; int status; @@ -331,15 +392,17 @@ static int handle_request_update (int fd, /* {{{ */ now = time (NULL); - buffer_ptr = buffer; - - file = buffer_ptr; - buffer_ptr += strlen (file) + 1; + status = buffer_get_field (&buffer, &buffer_size, &file); + if (status != 0) + { + RRDD_LOG (LOG_INFO, "handle_request_update: Cannot get file name."); + return (-1); + } pthread_mutex_lock (&cache_lock); ci = g_tree_lookup (cache_tree, file); - if (ci == NULL) + if (ci == NULL) /* {{{ */ { ci = (cache_item_t *) malloc (sizeof (cache_item_t)); if (ci == NULL) @@ -368,15 +431,20 @@ static int handle_request_update (int fd, /* {{{ */ RRDD_LOG (LOG_DEBUG, "handle_request_update: Created new tree node %s.", ci->file); - } + } /* }}} */ assert (ci != NULL); - while (*buffer_ptr != 0) + while (buffer_size > 0) { char **temp; + char *value; - value = buffer_ptr; - buffer_ptr += strlen (value) + 1; + status = buffer_get_field (&buffer, &buffer_size, &value); + if (status != 0) + { + RRDD_LOG (LOG_INFO, "handle_request_update: Error reading field."); + break; + } temp = (char **) realloc (ci->values, sizeof (char *) * (ci->values_num + 1)); @@ -399,7 +467,8 @@ static int handle_request_update (int fd, /* {{{ */ } if (((now - ci->last_flush_time) >= config_write_interval) - && ((ci->flags & CI_FLAGS_IN_QUEUE) == 0)) + && ((ci->flags & CI_FLAGS_IN_QUEUE) == 0) + && (ci->values_num > 0)) { enqueue_cache_item (ci); pthread_cond_signal (&cache_cond); @@ -410,7 +479,7 @@ static int handle_request_update (int fd, /* {{{ */ snprintf (answer, sizeof (answer), "0 Enqueued %i value(s)\n", values_num); answer[sizeof (answer) - 1] = 0; - status = write (fd, answer, sizeof (answer)); + status = write (fd, answer, strlen (answer)); if (status < 0) { status = errno; @@ -424,29 +493,41 @@ static int handle_request_update (int fd, /* {{{ */ static int handle_request (int fd) /* {{{ */ { char buffer[4096]; - int buffer_size; + size_t buffer_size; + char *buffer_ptr; + char *command; + int status; - buffer_size = read (fd, buffer, sizeof (buffer)); - if (buffer_size < 1) + status = read (fd, buffer, sizeof (buffer)); + if (status < 1) { RRDD_LOG (LOG_ERR, "handle_request: read(2) failed."); return (-1); } + buffer_size = status; assert (((size_t) buffer_size) <= sizeof (buffer)); - if ((buffer[buffer_size - 2] != 0) - || (buffer[buffer_size - 1] != 0)) + if (buffer[buffer_size - 1] != '\n') { RRDD_LOG (LOG_INFO, "handle_request: malformed request."); return (-1); } + /* Place the normal field separator at the end to simplify + * `buffer_get_field's work. */ + buffer[buffer_size - 1] = ' '; + + buffer_ptr = buffer; + command = NULL; + status = buffer_get_field (&buffer_ptr, &buffer_size, &command); + if (status != 0) + { + RRDD_LOG (LOG_INFO, "handle_request: Unable parse command."); + return (-1); + } - /* fields in the buffer a separated by null bytes. */ - if (strcmp (buffer, "update") == 0) + if (strcmp (command, "update") == 0) { - int offset = strlen ("update") + 1; - return (handle_request_update (fd, buffer + offset, - buffer_size - offset)); + return (handle_request_update (fd, buffer_ptr, buffer_size)); } else {