+ time_t now;
+
+ avl_node_t *node;
+ cache_item_t ci_temp;
+ cache_item_t *ci;
+
+ char answer[4096];
+
+ now = time (NULL);
+
+ RRDD_LOG (LOG_DEBUG, "handle_request_update (%i, %p, %i)",
+ fd, (void *) buffer, buffer_size);
+
+ buffer_ptr = buffer;
+
+ file = buffer_ptr;
+ buffer_ptr += strlen (file) + 1;
+
+ ci_temp.file = file;
+
+ pthread_mutex_lock (&cache_lock);
+
+ node = avl_search (cache_tree, (void *) &ci_temp);
+ if (node == NULL)
+ {
+ ci = (cache_item_t *) malloc (sizeof (cache_item_t));
+ if (ci == NULL)
+ {
+ pthread_mutex_unlock (&cache_lock);
+ RRDD_LOG (LOG_ERR, "handle_request_update: malloc failed.");
+ return (-1);
+ }
+ memset (ci, 0, sizeof (cache_item_t));
+
+ ci->file = strdup (file);
+ if (ci->file == NULL)
+ {
+ pthread_mutex_unlock (&cache_lock);
+ RRDD_LOG (LOG_ERR, "handle_request_update: malloc failed.");
+ free (ci);
+ return (-1);
+ }
+
+ ci->values = NULL;
+ ci->values_num = 0;
+ ci->last_flush_time = now;
+ ci->flags = CI_FLAGS_IN_TREE;
+
+ if (avl_insert (cache_tree, (void *) ci) == NULL)
+ {
+ pthread_mutex_unlock (&cache_lock);
+ RRDD_LOG (LOG_ERR, "handle_request_update: avl_insert failed.");
+ free (ci->file);
+ free (ci);
+ return (-1);
+ }
+
+ RRDD_LOG (LOG_DEBUG, "handle_request_update: Created new AVL node %s.",
+ ci->file);
+ }
+ else /* if (ci != NULL) */
+ {
+ ci = (cache_item_t *) node->item;
+ }
+ assert (ci != NULL);
+
+ while (*buffer_ptr != 0)
+ {
+ char **temp;
+
+ value = buffer_ptr;
+ buffer_ptr += strlen (value) + 1;
+
+ temp = (char **) realloc (ci->values,
+ sizeof (char *) * (ci->values_num + 1));
+ if (temp == NULL)
+ {
+ RRDD_LOG (LOG_ERR, "handle_request_update: realloc failed.");
+ continue;
+ }
+ ci->values = temp;
+
+ ci->values[ci->values_num] = strdup (value);
+ if (ci->values[ci->values_num] == NULL)
+ {
+ RRDD_LOG (LOG_ERR, "handle_request_update: strdup failed.");
+ continue;
+ }
+ ci->values_num++;
+
+ values_num++;
+ }
+
+ /* FIXME: Timeout should not be hard-coded. */
+ if (((now - ci->last_flush_time) > 300)
+ && ((ci->flags & CI_FLAGS_IN_QUEUE) == 0))
+ {
+ RRDD_LOG (LOG_DEBUG, "handle_request_update: Adding %s to the update queue.",
+ ci->file);
+
+ assert (ci->next == NULL);
+
+ if (cache_queue_tail == NULL)
+ cache_queue_head = ci;
+ else
+ cache_queue_tail->next = ci;
+ cache_queue_tail = ci;
+
+ pthread_cond_signal (&cache_cond);
+ }
+
+ pthread_mutex_unlock (&cache_lock);
+
+ snprintf (answer, sizeof (answer), "0 Enqueued %i value(s)\n", values_num);
+ answer[sizeof (answer) - 1] = 0;
+
+ write (fd, answer, sizeof (answer));
+
+ return (0);
+} /* }}} int handle_request_update */
+
+static int handle_request (int fd) /* {{{ */