+ status = buffer_get_field(&buffer, &buffer_size, &file);
+ if (status != 0)
+ return syntax_error(sock,cmd);
+
+ get_abs_path(&file, file_tmp);
+ if (!check_file_access(file, sock)) return 0;
+
+ pthread_mutex_lock(&cache_lock);
+ found = g_tree_remove(cache_tree, file);
+ pthread_mutex_unlock(&cache_lock);
+
+ if (found == TRUE)
+ {
+ if (sock != NULL)
+ journal_write("forget", file);
+
+ return send_response(sock, RESP_OK, "Gone!\n");
+ }
+ else
+ return send_response(sock, RESP_ERR, "%s\n", rrd_strerror(ENOENT));
+
+ /* NOTREACHED */
+ assert(1==0);
+} /* }}} static int handle_request_forget */
+
+static int handle_request_queue (HANDLER_PROTO) /* {{{ */
+{
+ cache_item_t *ci;
+
+ pthread_mutex_lock(&cache_lock);
+
+ ci = cache_queue_head;
+ while (ci != NULL)
+ {
+ add_response_info(sock, "%d %s\n", ci->values_num, ci->file);
+ ci = ci->next;
+ }
+
+ pthread_mutex_unlock(&cache_lock);
+
+ return send_response(sock, RESP_OK, "in queue.\n");
+} /* }}} int handle_request_queue */
+
+static int handle_request_update (HANDLER_PROTO) /* {{{ */
+{
+ char *file, file_tmp[PATH_MAX];
+ int values_num = 0;
+ int status;
+ char orig_buf[CMD_MAX];
+
+ cache_item_t *ci;
+
+ /* save it for the journal later */
+ strncpy(orig_buf, buffer, sizeof(orig_buf)-1);
+
+ status = buffer_get_field (&buffer, &buffer_size, &file);
+ if (status != 0)
+ return syntax_error(sock,cmd);
+
+ pthread_mutex_lock(&stats_lock);
+ stats_updates_received++;
+ pthread_mutex_unlock(&stats_lock);
+
+ get_abs_path(&file, file_tmp);
+ if (!check_file_access(file, sock)) return 0;
+
+ pthread_mutex_lock (&cache_lock);
+ ci = g_tree_lookup (cache_tree, file);
+
+ if (ci == NULL) /* {{{ */
+ {
+ struct stat statbuf;
+ cache_item_t *tmp;
+
+ /* don't hold the lock while we setup; stat(2) might block */
+ pthread_mutex_unlock(&cache_lock);
+
+ memset (&statbuf, 0, sizeof (statbuf));
+ status = stat (file, &statbuf);
+ if (status != 0)
+ {
+ RRDD_LOG (LOG_NOTICE, "handle_request_update: stat (%s) failed.", file);
+
+ status = errno;
+ if (status == ENOENT)
+ return send_response(sock, RESP_ERR, "No such file: %s\n", file);
+ else
+ return send_response(sock, RESP_ERR,
+ "stat failed with error %i.\n", status);
+ }
+ if (!S_ISREG (statbuf.st_mode))
+ return send_response(sock, RESP_ERR, "Not a regular file: %s\n", file);
+
+ if (access(file, R_OK|W_OK) != 0)
+ return send_response(sock, RESP_ERR, "Cannot read/write %s: %s\n",
+ file, rrd_strerror(errno));
+
+ ci = (cache_item_t *) malloc (sizeof (cache_item_t));
+ if (ci == NULL)
+ {
+ RRDD_LOG (LOG_ERR, "handle_request_update: malloc failed.");