+ else
+ rrd_parsetime ("-86400", &start_tv);
+
+ /* Parse end time */
+ if (end_str != NULL)
+ {
+ const char *errmsg;
+
+ errmsg = rrd_parsetime (end_str, &end_tv);
+ if (errmsg != NULL)
+ return (send_response(sock, RESP_ERR,
+ "Cannot parse end time `%s': %s\n", end_str, errmsg));
+ }
+ else
+ rrd_parsetime ("now", &end_tv);
+
+ start_tm = 0;
+ end_tm = 0;
+ status = rrd_proc_start_end (&start_tv, &end_tv, &start_tm, &end_tm);
+ if (status != 0)
+ return (send_response(sock, RESP_ERR,
+ "rrd_proc_start_end failed: %s\n", rrd_get_error ()));
+
+ step = -1;
+ ds_cnt = 0;
+ ds_namv = NULL;
+ data = NULL;
+
+ status = rrd_fetch_r (file, cf, &start_tm, &end_tm, &step,
+ &ds_cnt, &ds_namv, &data);
+ if (status != 0)
+ return (send_response(sock, RESP_ERR,
+ "rrd_fetch_r failed: %s\n", rrd_get_error ()));
+
+ add_response_info (sock, "FlushVersion: %lu\n", 1);
+ add_response_info (sock, "Start: %lu\n", (unsigned long) start_tm);
+ add_response_info (sock, "End: %lu\n", (unsigned long) end_tm);
+ add_response_info (sock, "Step: %lu\n", step);
+ add_response_info (sock, "DSCount: %lu\n", ds_cnt);
+
+#define SSTRCAT(buffer,str,buffer_fill) do { \
+ size_t str_len = strlen (str); \
+ if ((buffer_fill + str_len) > sizeof (buffer)) \
+ str_len = sizeof (buffer) - buffer_fill; \
+ if (str_len > 0) { \
+ strncpy (buffer + buffer_fill, str, str_len); \
+ buffer_fill += str_len; \
+ assert (buffer_fill <= sizeof (buffer)); \
+ if (buffer_fill == sizeof (buffer)) \
+ buffer[buffer_fill - 1] = 0; \
+ else \
+ buffer[buffer_fill] = 0; \
+ } \
+ } while (0)
+
+ { /* Add list of DS names */
+ char linebuf[1024];
+ size_t linebuf_fill;
+
+ memset (linebuf, 0, sizeof (linebuf));
+ linebuf_fill = 0;
+ for (i = 0; i < ds_cnt; i++)
+ {
+ if (i > 0)
+ SSTRCAT (linebuf, " ", linebuf_fill);
+ SSTRCAT (linebuf, ds_namv[i], linebuf_fill);
+ }
+ add_response_info (sock, "DSName: %s\n", linebuf);
+ }
+
+ /* Add the actual data */
+ assert (step > 0);
+ data_ptr = data;
+ for (t = start_tm + step; t <= end_tm; t += step)
+ {
+ char linebuf[1024];
+ size_t linebuf_fill;
+ char tmp[128];
+
+ memset (linebuf, 0, sizeof (linebuf));
+ linebuf_fill = 0;
+ for (i = 0; i < ds_cnt; i++)
+ {
+ snprintf (tmp, sizeof (tmp), " %0.10e", *data_ptr);
+ tmp[sizeof (tmp) - 1] = 0;
+ SSTRCAT (linebuf, tmp, linebuf_fill);
+
+ data_ptr++;
+ }
+
+ add_response_info (sock, "%10lu:%s\n", (unsigned long) t, linebuf);
+ } /* for (t) */
+
+ return (send_response (sock, RESP_OK, "Success\n"));
+#undef SSTRCAT
+} /* }}} int handle_request_fetch */
+
+/* we came across a "WROTE" entry during journal replay.
+ * throw away any values that we have accumulated for this file
+ */
+static int handle_request_wrote (HANDLER_PROTO) /* {{{ */
+{
+ cache_item_t *ci;
+ const char *file = buffer;
+
+ pthread_mutex_lock(&cache_lock);
+
+ ci = g_tree_lookup(cache_tree, file);
+ if (ci == NULL)
+ {
+ pthread_mutex_unlock(&cache_lock);
+ return (0);
+ }
+
+ if (ci->values)
+ rrd_free_ptrs((void ***) &ci->values, &ci->values_num);