dnl the official version number is
dnl a.b.c
- AC_INIT([rrdtool],[1.3.0])
+ AC_INIT([rrdtool],[1.3.1])
dnl for testing a numberical version number comes handy
dnl the released version are
dnl a.bccc
dnl the devel versions will be something like
dnl a.b999yymmddhh
- NUMVERS=1.3000
+ NUMVERS=1.3001
AC_SUBST(NUMVERS)
dnl for the linker to understand which version the library is compatible with
dnl Check for the compiler and static/shared library creation.
-AC_PROG_CC
AC_PROG_CPP
+AC_PROG_CC
+AM_PROG_CC_C_O
AC_PROG_LIBTOOL
dnl Try to detect/use GNU features
have_broken_isfinite=no],have_broken_isfinite=yes,[
case "${target}" in
hppa*-*-hpux*) have_broken_isfinite=yes ;;
+ sparc-sun-solaris2.8) have_broken_isfinite=yes ;;
*) have_broken_isfinite=no ;;
esac])
])
EX_CHECK_ALL(cairo, cairo_svg_surface_create, cairo-svg.h, cairo-svg, 1.4.6, http://cairographics.org/releases/, "")
EX_CHECK_ALL(cairo, cairo_pdf_surface_create, cairo-pdf.h, cairo-pdf, 1.4.6, http://cairographics.org/releases/, "")
EX_CHECK_ALL(cairo, cairo_ps_surface_create, cairo-ps.h, cairo-ps, 1.4.6, http://cairographics.org/releases/, "")
-dnl EX_CHECK_ALL(glib-2.0, glib_check_version, glib.h, glib-2.0, 2.12.12, ftp://ftp.gtk.org/pub/glib/2.12/, "")
+EX_CHECK_ALL(glib-2.0, glib_check_version, glib.h, glib-2.0, 2.12.12, ftp://ftp.gtk.org/pub/glib/2.12/, "")
EX_CHECK_ALL(pango-1.0, pango_cairo_context_set_font_options, pango/pango.h, pangocairo, 1.17, http://ftp.gnome.org/pub/GNOME/sources/pango/1.17, "")
EX_CHECK_ALL(xml2, xmlParseFile, libxml/parser.h, libxml-2.0, 2.6.31, http://xmlsoft.org/downloads.html, /usr/include/libxml2)
How many digits should rrdtool assume the y-axis labels to be? You
may have to use this option to make enough space once you start
-fideling with the y-axis labeling.
+fiddling with the y-axis labeling.
[B<--units=si>]
Only generate the graph if the current graph is out of date or not existent.
Note, that only the image size will be returned, if you run with lazy even
- when using graphv.
+ when using graphv and even when using PRINT.
+[B<--daemon> I<address>]
+
+Address of the L<rrdcached(1)> daemon. If specified, a C<flush> command is sent
+to the server before reading the RRD files. This allows the graph to contain
+fresh data even if the daemon is configured to cache values for a long time. To
+specify a UNIX domain socket use the prefix C<unix:>, see example below. Other
+addresses are interpreted as normal network addresses, i.E<nbsp>e. IPv4 or IPv6
+addresses in most cases.
+
+ rrdtool graph [...] --daemon unix:/var/run/rrdcached.sock [...]
+
[B<-f>|B<--imginfo> I<printfstr>]
After the image has been created, the graph function uses printf
See L<rrdgraph_graph> for the exact format.
-=back
-
=head2 graphv
Calling rrdtool with the graphv option will return information in the
Especially the 'graph_*' keys are new. They help applications that want to
know what is where on the graph.
+=head1 ENVIRONMENT VARIABLES
+
+The following environment variables may be used to change the behavior of
+C<rrdtoolE<nbsp>graph>:
+
+=over 4
+
+=item B<RRDCACHED_ADDRESS>
+
+If this environment variable is set it will have the same effect as specifying
+the C<--daemon> option on the command line. If both are present, the command
+line argument takes precedence.
+
+=back
+
=head1 SEE ALSO
L<rrdgraph> gives an overview of how B<rrdtool graph> works.
/*****************************************************************************
- * RRDtool 1.3.0 Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3.1 Copyright by Tobi Oetiker, 1997-2008
*****************************************************************************
* rrdlib.h Public header file for librrd
*****************************************************************************
time_t rrd_last(
int,
char **);
- int rrd_lastupdate(
- int argc,
- char **argv,
- time_t *last_update,
- unsigned long *ds_cnt,
- char ***ds_namv,
- char ***last_ds);
+ int rrd_lastupdate(int argc, char **argv);
time_t rrd_first(
int,
char **);
unsigned long *,
char ***,
rrd_value_t **);
+ int rrd_cmd_flush (int argc, char **argv);
void rrd_freemem(
void *mem);
const char *_template,
int argc,
const char **argv);
- int rrd_fetch_r(
- const char *filename,
- const char *cf,
- time_t *start,
- time_t *end,
- unsigned long *step,
- unsigned long *ds_cnt,
- char ***ds_namv,
- rrd_value_t **data);
+ int rrd_fetch_r (
+ const char *filename,
+ const char *cf,
+ time_t *start,
+ time_t *end,
+ unsigned long *step,
+ unsigned long *ds_cnt,
+ char ***ds_namv,
+ rrd_value_t **data);
int rrd_dump_r(
const char *filename,
char *outname);
- time_t rrd_last_r(
- const char *filename);
+ time_t rrd_last_r (const char *filename);
+ int rrd_lastupdate_r (const char *filename,
+ time_t *ret_last_update,
+ unsigned long *ret_ds_count,
+ char ***ret_ds_names,
+ char ***ret_last_ds);
time_t rrd_first_r(
const char *filename,
int rraindex);
#if defined(__GNUC__) && defined (RRD_EXPORT_DEPRECATED)
# define RRD_DEPRECATED __attribute__((deprecated))
#else
- # define RRD_DEPRECATED /**/
+ # define RRD_DEPRECATED /**/
#endif
-
- void rrd_free (rrd_t *rrd)
- RRD_DEPRECATED;
- void rrd_init (rrd_t *rrd)
- RRD_DEPRECATED;
-
- rrd_file_t *rrd_open (const char *const file_name, rrd_t *rrd,
- unsigned rdwr)
- RRD_DEPRECATED;
-
- void rrd_dontneed (rrd_file_t *rrd_file, rrd_t *rrd)
- RRD_DEPRECATED;
- int rrd_close (rrd_file_t *rrd_file)
- RRD_DEPRECATED;
- ssize_t rrd_read (rrd_file_t *rrd_file, void *buf, size_t count)
- RRD_DEPRECATED;
- ssize_t rrd_write (rrd_file_t *rrd_file,
- const void *buf, size_t count)
- RRD_DEPRECATED;
- void rrd_flush (rrd_file_t *rrd_file)
- RRD_DEPRECATED;
- off_t rrd_seek (rrd_file_t *rrd_file, off_t off, int whence)
- RRD_DEPRECATED;
- off_t rrd_tell (rrd_file_t *rrd_file)
- RRD_DEPRECATED;
- int rrd_lock (rrd_file_t *file)
- RRD_DEPRECATED;
- #endif /* defined(_RRD_TOOL_H) || defined(RRD_EXPORT_DEPRECATED) */
+ void rrd_free(
+ rrd_t *rrd)
+ RRD_DEPRECATED;
+ void rrd_init(
+ rrd_t *rrd)
+ RRD_DEPRECATED;
+
+ rrd_file_t *rrd_open(
+ const char *const file_name,
+ rrd_t *rrd,
+ unsigned rdwr)
+ RRD_DEPRECATED;
+
+ void rrd_dontneed(
+ rrd_file_t *rrd_file,
+ rrd_t *rrd)
+ RRD_DEPRECATED;
+ int rrd_close(
+ rrd_file_t *rrd_file)
+ RRD_DEPRECATED;
+ ssize_t rrd_read(
+ rrd_file_t *rrd_file,
+ void *buf,
+ size_t count)
+ RRD_DEPRECATED;
+ ssize_t rrd_write(
+ rrd_file_t *rrd_file,
+ const void *buf,
+ size_t count)
+ RRD_DEPRECATED;
+ void rrd_flush(
+ rrd_file_t *rrd_file)
+ RRD_DEPRECATED;
+ off_t rrd_seek(
+ rrd_file_t *rrd_file,
+ off_t off,
+ int whence)
+ RRD_DEPRECATED;
+ off_t rrd_tell(
+ rrd_file_t *rrd_file)
+ RRD_DEPRECATED;
+ int rrd_lock(
+ rrd_file_t *file)
+ RRD_DEPRECATED;
+ #endif /* defined(_RRD_TOOL_H) || defined(RRD_EXPORT_DEPRECATED) */
#endif /* _RRDLIB_H */
/*****************************************************************************
- * RRDtool 1.3.0 Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3.1 Copyright by Tobi Oetiker, 1997-2008
*****************************************************************************
* rrd_dump Display a RRD
*****************************************************************************
*****************************************************************************/
#include "rrd_tool.h"
#include "rrd_rpncalc.h"
+#include "rrd_client.h"
#if !(defined(NETWARE) || defined(WIN32))
extern char *tzname[2];
{
int rc;
int opt_noheader = 0;
+ char *opt_daemon = NULL;
/* init rrd clean */
int opt;
int option_index = 0;
static struct option long_options[] = {
+ {"daemon", required_argument, 0, 'd'},
{"no-header", no_argument, 0, 'n'},
{0, 0, 0, 0}
};
- opt = getopt_long(argc, argv, "n", long_options, &option_index);
+ opt = getopt_long(argc, argv, "d:n", long_options, &option_index);
if (opt == EOF)
break;
switch (opt) {
+ case 'd':
+ if (opt_daemon != NULL)
+ free (opt_daemon);
+ opt_daemon = strdup (optarg);
+ if (opt_daemon == NULL)
+ {
+ rrd_set_error ("strdup failed.");
+ return (-1);
+ }
+ break;
+
case 'n':
opt_noheader = 1;
break;
return (-1);
}
+ if (opt_daemon == NULL)
+ {
+ char *temp;
+
+ temp = getenv (ENV_RRDCACHED_ADDRESS);
+ if (temp != NULL)
+ {
+ opt_daemon = strdup (temp);
+ if (opt_daemon == NULL)
+ {
+ rrd_set_error("strdup failed.");
+ return (-1);
+ }
+ }
+ }
+
+ if (opt_daemon != NULL)
+ {
+ int status;
+
+ status = rrdc_connect (opt_daemon);
+ if (status != 0)
+ {
+ rrd_set_error ("rrdc_connect failed with status %i.", status);
+ return (-1);
+ }
+
+ status = rrdc_flush (argv[optind]);
+ if (status != 0)
+ {
+ rrd_set_error ("rrdc_flush (%s) failed with status %i.",
+ argv[optind], status);
+ return (-1);
+ }
+
+ rrdc_disconnect ();
+ } /* if (opt_daemon) */
+
if ((argc - optind) == 2) {
rc = rrd_dump_opt_r(argv[optind], argv[optind + 1], opt_noheader);
} else {
/*****************************************************************************
- * RRDtool 1.3.0 Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3.1 Copyright by Tobi Oetiker, 1997-2008
*****************************************************************************
* rrd_fetch.c read date from an rrd to use for further processing
*****************************************************************************
*****************************************************************************/
#include "rrd_tool.h"
+#include "rrd_client.h"
#include "rrd_is_thread_safe.h"
/*#define DEBUG*/
long step_tmp = 1;
time_t start_tmp = 0, end_tmp = 0;
const char *cf;
+ char *opt_daemon = NULL;
+ int status;
rrd_time_value_t start_tv, end_tv;
char *parsetime_error = NULL;
{"resolution", required_argument, 0, 'r'},
{"start", required_argument, 0, 's'},
{"end", required_argument, 0, 'e'},
+ {"daemon", required_argument, 0, 'd'},
{0, 0, 0, 0}
};
int option_index = 0;
int opt;
- opt = getopt_long(argc, argv, "r:s:e:", long_options, &option_index);
+ opt = getopt_long(argc, argv, "r:s:e:d:", long_options, &option_index);
if (opt == EOF)
break;
case 'r':
step_tmp = atol(optarg);
break;
+
+ case 'd':
+ if (opt_daemon != NULL)
+ free (opt_daemon);
+ opt_daemon = strdup (optarg);
+ if (opt_daemon == NULL)
+ {
+ rrd_set_error ("strdup failed.");
+ return (-1);
+ }
+ break;
+
case '?':
rrd_set_error("unknown option '-%c'", optopt);
return (-1);
return -1;
}
+ if (opt_daemon == NULL)
+ {
+ char *temp;
+
+ temp = getenv (ENV_RRDCACHED_ADDRESS);
+ if (temp != NULL)
+ {
+ opt_daemon = strdup (temp);
+ if (opt_daemon == NULL)
+ {
+ rrd_set_error("strdup failed.");
+ return (-1);
+ }
+ }
+ }
+
+ if (opt_daemon != NULL)
+ {
+ status = rrdc_connect (opt_daemon);
+ if (status != 0)
+ {
+ rrd_set_error ("rrdc_connect failed with status %i.", status);
+ return (-1);
+ }
+
+ status = rrdc_flush (argv[optind]);
+ if (status != 0)
+ {
+ rrd_set_error ("rrdc_flush (%s) failed with status %i.",
+ argv[optind], status);
+ return (-1);
+ }
+
+ rrdc_disconnect ();
+ } /* if (opt_daemon) */
+
cf = argv[optind + 1];
- if (rrd_fetch_r(argv[optind], cf, start, end, step, ds_cnt, ds_namv, data)
- != 0)
+ status = rrd_fetch_r(argv[optind], cf, start, end, step,
+ ds_cnt, ds_namv, data);
+ if (status != 0)
return (-1);
return (0);
}
return (rrd_fetch_fn
(filename, cf_idx, start, end, step, ds_cnt, ds_namv, data));
-}
+} /* int rrd_fetch_r */
int rrd_fetch_fn(
const char *filename, /* name of the rrd */
/****************************************************************************
- * RRDtool 1.3.0 Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3.1 Copyright by Tobi Oetiker, 1997-2008
****************************************************************************
* rrd__graph.c produce graphs from data in rrdfiles
****************************************************************************/
#endif
#include "rrd_graph.h"
+#include "rrd_client.h"
/* some constant definitions */
#endif
text_prop_t text_prop[] = {
- {8.0, RRD_DEFAULT_FONT}
+ {8.0, RRD_DEFAULT_FONT,NULL}
, /* default */
- {9.0, RRD_DEFAULT_FONT}
+ {9.0, RRD_DEFAULT_FONT,NULL}
, /* title */
- {7.0, RRD_DEFAULT_FONT}
+ {7.0, RRD_DEFAULT_FONT,NULL}
, /* axis */
- {8.0, RRD_DEFAULT_FONT}
+ {8.0, RRD_DEFAULT_FONT,NULL}
, /* unit */
- {8.0, RRD_DEFAULT_FONT} /* legend */
+ {8.0, RRD_DEFAULT_FONT,NULL} /* legend */
+ ,
+ {5.5, RRD_DEFAULT_FONT,NULL} /* watermark */
};
xlab_t xlab[] = {
conv_if(AXIS, TEXT_PROP_AXIS);
conv_if(UNIT, TEXT_PROP_UNIT);
conv_if(LEGEND, TEXT_PROP_LEGEND);
+ conv_if(WATERMARK, TEXT_PROP_WATERMARK);
return -1;
}
if (im == NULL)
return 0;
+
+ if (im->use_rrdcached)
+ {
+ rrdc_disconnect ();
+ im->use_rrdcached = 0;
+ }
+
for (i = 0; i < (unsigned) im->gdes_c; i++) {
if (im->gdes[i].data_first) {
/* careful here, because a single pointer can occur several times */
if (im->rendered_image) {
free(im->rendered_image);
}
+
+ if (im->layout) {
+ g_object_unref (im->layout);
+ }
+
if (im->surface)
cairo_surface_destroy(im->surface);
+
if (status)
fprintf(stderr, "OOPS: Cairo has issues it can't even die: %s\n",
cairo_status_to_string(status));
-
+
return 0;
}
if (!skip) {
unsigned long ft_step = im->gdes[i].step; /* ft_step will record what we got from fetch */
+ /* Flush the file if
+ * - a connection to the daemon has been established
+ * - this is the first occurrence of that RRD file
+ */
+ if (im->use_rrdcached)
+ {
+ int status;
+
+ status = 0;
+ for (ii = 0; ii < i; ii++)
+ {
+ if (strcmp (im->gdes[i].rrd, im->gdes[ii].rrd) == 0)
+ {
+ status = 1;
+ break;
+ }
+ }
+
+ if (status == 0)
+ {
+ status = rrdc_flush (im->gdes[i].rrd);
+ if (status != 0)
+ {
+ rrd_set_error ("rrdc_flush (%s) failed with status %i.",
+ im->gdes[i].rrd, status);
+ return (-1);
+ }
+ }
+ } /* if (im->use_rrdcached) */
+
if ((rrd_fetch_fn(im->gdes[i].rrd,
im->gdes[i].cf,
&im->gdes[i].start,
im->
text_prop
[TEXT_PROP_LEGEND].
- font,
- im->
- text_prop
- [TEXT_PROP_LEGEND].
- size,
+ font_desc,
im->tabwidth, im->gdes[i].legend);
leg_c++;
} else {
im->
text_prop
[TEXT_PROP_LEGEND].
- font,
- im->
- text_prop
- [TEXT_PROP_LEGEND].
- size,
+ font_desc,
im->tabwidth, im->gdes[ii].legend)
+ legspace[ii]
+ glue;
im->graph_col[GRC_FONT],
im->
text_prop[TEXT_PROP_AXIS].
- font,
- im->
- text_prop[TEXT_PROP_AXIS].
- size, im->tabwidth, 0.0,
+ font_desc,
+ im->tabwidth, 0.0,
GFX_H_RIGHT, GFX_V_CENTER, graph_label);
gfx_line(im, X0 - 2, Y0, X0, Y0,
MGRIDWIDTH, im->graph_col[GRC_MGRID]);
im->graph_col[GRC_FONT],
im->
text_prop[TEXT_PROP_AXIS].
- font,
- im->
- text_prop[TEXT_PROP_AXIS].
- size, im->tabwidth, 0.0,
+ font_desc,
+ im->tabwidth, 0.0,
GFX_H_RIGHT, GFX_V_CENTER, graph_label);
/* minor grid */
if (mid < 4 && exfrac == 1) {
im->graph_col[GRC_FONT],
im->
text_prop[TEXT_PROP_AXIS].
- font,
- im->
- text_prop[TEXT_PROP_AXIS].
- size, im->tabwidth, 0.0,
+ font_desc,
+ im->tabwidth, 0.0,
GFX_H_CENTER, GFX_V_TOP, graph_label);
}
im->graph_col[GRC_FONT],
im->
text_prop[TEXT_PROP_AXIS].
- font,
- im->
- text_prop[TEXT_PROP_AXIS].
- size, im->tabwidth, 0.0,
+ font_desc,
+ im->tabwidth, 0.0,
GFX_H_CENTER, GFX_V_CENTER, nodata);
}
}
im->graph_col[GRC_FONT],
im->
text_prop[TEXT_PROP_UNIT].
- font,
- im->
- text_prop[TEXT_PROP_UNIT].
- size, im->tabwidth,
+ font_desc,
+ im->tabwidth,
RRDGRAPH_YLEGEND_ANGLE, GFX_H_CENTER, GFX_V_CENTER, im->ylegend);
/* graph title */
gfx_text(im,
im->graph_col[GRC_FONT],
im->
text_prop[TEXT_PROP_TITLE].
- font,
- im->
- text_prop[TEXT_PROP_TITLE].
- size, im->tabwidth, 0.0, GFX_H_CENTER, GFX_V_TOP, im->title);
+ font_desc,
+ im->tabwidth, 0.0, GFX_H_CENTER, GFX_V_TOP, im->title);
/* rrdtool 'logo' */
water_color = im->graph_col[GRC_FONT];
water_color.alpha = 0.3;
gfx_text(im, im->ximg - 4, 5,
water_color,
im->
- text_prop[TEXT_PROP_AXIS].
- font, 5.5, im->tabwidth,
+ text_prop[TEXT_PROP_WATERMARK].
+ font_desc, im->tabwidth,
-90, GFX_H_LEFT, GFX_V_TOP, "RRDTOOL / TOBI OETIKER");
/* graph watermark */
if (im->watermark[0] != '\0') {
im->ximg / 2, im->yimg - 6,
water_color,
im->
- text_prop[TEXT_PROP_AXIS].
- font, 5.5, im->tabwidth, 0,
+ text_prop[TEXT_PROP_WATERMARK].
+ font_desc, im->tabwidth, 0,
GFX_H_CENTER, GFX_V_BOTTOM, im->watermark);
}
im->graph_col[GRC_FONT],
im->
text_prop
- [TEXT_PROP_LEGEND].font,
- im->
- text_prop
- [TEXT_PROP_LEGEND].size,
+ [TEXT_PROP_LEGEND].font_desc,
im->tabwidth, 0.0,
GFX_H_LEFT, GFX_V_BOTTOM, im->gdes[i].legend);
/* The legend for GRAPH items starts with "M " to have
im->
text_prop
[TEXT_PROP_LEGEND].
- font,
- im->
- text_prop
- [TEXT_PROP_LEGEND].
- size, im->tabwidth, "o") * 1.2;
+ font_desc,
+ im->tabwidth, "o") * 1.2;
boxV = boxH;
/* shift the box up a bit */
Y0 -= boxV * 0.4;
im->
text_prop
[TEXT_PROP_AXIS].
- font,
- im->
- text_prop
- [TEXT_PROP_AXIS].
- size, im->tabwidth, "0") * im->unitslength;
+ font_desc,
+ im->tabwidth, "0") * im->unitslength;
}
}
double areazero = 0.0;
graph_desc_t *lastgdes = NULL;
rrd_infoval_t info;
- PangoFontMap *font_map = pango_cairo_font_map_get_default();
- /* if we are lazy and there is nothing to PRINT ... quit now */
- if (lazy && im->prt_c == 0) {
+ // PangoFontMap *font_map = pango_cairo_font_map_get_default();
+
+ /* if we want and can be lazy ... quit now */
+ if (lazy) {
info.u_cnt = im->ximg;
grinfo_push(im, sprintf_alloc("image_width"), RD_I_CNT, info);
info.u_cnt = im->yimg;
* if there are no graph elements (i==0) we stop here ...
* if we are lazy, try to quit ...
*/
- i = print_calc(im);
+ i = print_calc(im);
if (i < 0)
return -1;
(im->surface, CAIRO_SVG_VERSION_1_1);
break;
};
+ cairo_destroy(im->cr);
im->cr = cairo_create(im->surface);
cairo_set_antialias(im->cr, im->graph_antialias);
cairo_scale(im->cr, im->zoom, im->zoom);
- pango_cairo_font_map_set_resolution(PANGO_CAIRO_FONT_MAP(font_map), 100);
+ // pango_cairo_font_map_set_resolution(PANGO_CAIRO_FONT_MAP(font_map), 100);
gfx_new_area(im, 0, 0, 0, im->yimg,
im->ximg, im->yimg, im->graph_col[GRC_BACK]);
gfx_add_point(im, im->ximg, 0);
*ysize = 0;
*ymin = 0;
*ymax = 0;
- while (walker) {
+ while (walker) {
if (strcmp(walker->key, "image_width") == 0) {
*xsize = walker->value.u_int;
} else if (strcmp(walker->key, "image_height") == 0) {
{
image_desc_t im;
rrd_info_t *grinfo;
-
rrd_graph_init(&im);
/* a dummy surface so that we can measure text sizes for placements */
- im.surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 10, 10);
- im.cr = cairo_create(im.surface);
+
rrd_graph_options(argc, argv, &im);
if (rrd_test_error()) {
rrd_info_free(im.grinfo);
if (im.imginfo) {
rrd_infoval_t info;
+ char *filename;
+ filename = im.graphfile + strlen(im.graphfile);
+ while (filename > im.graphfile) {
+ if (*(filename - 1) == '/' || *(filename - 1) == '\\')
+ break;
+ filename--;
+ }
info.u_str =
sprintf_alloc(im.imginfo,
- im.graphfile,
+ filename,
(long) (im.zoom *
im.ximg), (long) (im.zoom * im.yimg));
grinfo_push(&im, sprintf_alloc("image_info"), RD_I_STR, info);
return grinfo;
}
+ static void
+ rrd_set_font_desc (
+ image_desc_t *im,int prop,char *font, double size ){
+ static text_prop_t tp_cache[] = { {-1,"",NULL}, {-1,"",NULL}, {-1,"",NULL}, {-1,"",NULL}, {-1,"",NULL}, {-1,"",NULL}};
+
+ if (tp_cache[prop].font_desc == NULL){
+ if (prop > 0 && tp_cache[0].font_desc != NULL){
+ tp_cache[prop].font_desc = pango_font_description_copy (tp_cache[0].font_desc);
+ strcpy(tp_cache[prop].font,tp_cache[0].font);
+ tp_cache[prop].size = tp_cache[0].size;
+ }
+ else {
+ tp_cache[prop].font_desc = pango_font_description_new();
+ }
+ im->text_prop[prop].font_desc = pango_font_description_copy (tp_cache[prop].font_desc);
+ }
+
+ if (font != NULL && strcmp(tp_cache[prop].font,font) != 0){
+ pango_font_description_free(tp_cache[prop].font_desc);
+ pango_font_description_free(im->text_prop[prop].font_desc);
+ tp_cache[prop].font_desc = pango_font_description_from_string( font );
+ im->text_prop[prop].font_desc = pango_font_description_copy( tp_cache[prop].font_desc );
+ strncpy(tp_cache[prop].font, font, sizeof(text_prop[prop].font) - 1);
+ tp_cache[prop].font[sizeof(text_prop[prop].font) - 1] = '\0';
+ strcpy(im->text_prop[prop].font,tp_cache[prop].font);
+ }
+ if (size != 0 && size != (tp_cache[prop].size)){
+ pango_font_description_set_size(tp_cache[prop].font_desc, size * PANGO_SCALE);
+ pango_font_description_set_size(im->text_prop[prop].font_desc, size * PANGO_SCALE);
+ im->text_prop[prop].size = size;
+ tp_cache[prop].size = size;
+ }
+ if (im->text_prop[prop].size < 0){
+ im->text_prop[prop].size = tp_cache[prop].size;
+ im->text_prop[prop].font_desc = pango_font_description_copy( tp_cache[prop].font_desc );
+ strcpy(im->text_prop[prop].font,tp_cache[prop].font);
+ }
+ // fprintf(stderr,"%d %s\n",prop,pango_font_description_to_string(im->text_prop[prop].font_desc));
+ }
+
void rrd_graph_init(
image_desc_t
*im)
{
unsigned int i;
+ char *deffont = getenv("RRD_DEFAULT_FONT");
#ifdef HAVE_TZSET
tzset();
#endif
#endif
im->base = 1000;
- im->cr = NULL;
im->draw_x_grid = 1;
im->draw_y_grid = 1;
im->extra_flags = 0;
im->grinfo_current = (rrd_info_t *) NULL;
im->imgformat = IF_PNG;
im->imginfo = NULL;
+ im->use_rrdcached = 0;
im->lazy = 0;
im->logarithmic = 0;
im->maxval = DNAN;
im->rendered_image = NULL;
im->slopemode = 0;
im->step = 0;
- im->surface = NULL;
im->symbol = ' ';
im->tabwidth = 40.0;
im->title[0] = '\0';
im->yorigin = 0;
im->ysize = 100;
im->zoom = 1;
+
+ im->surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 10, 10);
+ im->cr = cairo_create(im->surface);
+
+ for (i = 0; i < DIM(text_prop); i++) {
+ im->text_prop[i].size = -1;
+ rrd_set_font_desc(im,i, deffont ? deffont : text_prop[i].font,text_prop[i].size);
+ }
+
+ im->layout = pango_cairo_create_layout(im->cr);
+ pango_cairo_context_set_resolution(pango_layout_get_context(im->layout), 100);
+
cairo_font_options_set_hint_style
(im->font_options, CAIRO_HINT_STYLE_FULL);
cairo_font_options_set_hint_metrics
(im->font_options, CAIRO_HINT_METRICS_ON);
cairo_font_options_set_antialias(im->font_options, CAIRO_ANTIALIAS_GRAY);
+
+
+
for (i = 0; i < DIM(graph_col); i++)
im->graph_col[i] = graph_col[i];
- {
- char *deffont;
-
- deffont = getenv("RRD_DEFAULT_FONT");
- if (deffont != NULL) {
- for (i = 0; i < DIM(text_prop); i++) {
- strncpy(text_prop[i].font, deffont,
- sizeof(text_prop[i].font) - 1);
- text_prop[i].font[sizeof(text_prop[i].font) - 1] = '\0';
- }
- }
- }
- for (i = 0; i < DIM(text_prop); i++) {
- im->text_prop[i].size = text_prop[i].size;
- strcpy(im->text_prop[i].font, text_prop[i].font);
- }
+
+
}
+
void rrd_graph_options(
int argc,
char *argv[],
{ "watermark", required_argument, 0, 'W'},
{ "alt-y-mrtg", no_argument, 0, 1000}, /* this has no effect it is just here to save old apps from crashing when they use it */
{ "pango-markup", no_argument, 0, 'P'},
+ { "daemon", required_argument, 0, 'd'},
{ 0, 0, 0, 0}
};
/* *INDENT-ON* */
int col_start, col_end;
opt = getopt_long(argc, argv,
- "s:e:x:y:v:w:h:D:iu:l:rb:oc:n:m:t:f:a:I:zgjFYAMEX:L:S:T:NR:B:W:kP",
+ "s:e:x:y:v:w:h:D:iu:l:rb:oc:n:m:t:f:a:I:zgjFYAMEX:L:S:T:NR:B:W:kPd:",
long_options, &option_index);
if (opt == EOF)
break;
for (propidx = sindex;
propidx < TEXT_PROP_LAST; propidx++) {
if (size > 0) {
- im->text_prop[propidx].size = size;
+ rrd_set_font_desc(im,propidx,NULL,size);
}
if ((int) strlen(optarg) > end) {
if (optarg[end] == ':') {
- strncpy(im->text_prop[propidx].font,
- optarg + end + 1, 255);
- im->text_prop[propidx].font[255] = '\0';
+ rrd_set_font_desc(im,propidx,optarg + end + 1,0);
} else {
rrd_set_error
("expected : after font size in '%s'",
strncpy(im->watermark, optarg, 100);
im->watermark[99] = '\0';
break;
+ case 'd':
+ {
+ int status;
+ if (im->use_rrdcached)
+ {
+ rrd_set_error ("You cannot specify --daemon "
+ "more than once.");
+ return;
+ }
+ status = rrdc_connect (optarg);
+ if (status != 0)
+ {
+ rrd_set_error ("rrdc_connect(%s) failed with status %i.",
+ optarg, status);
+ return;
+ }
+ im->use_rrdcached = 1;
+ break;
+ }
case '?':
if (optopt != 0)
rrd_set_error("unknown option '%c'", optopt);
rrd_set_error("unknown option '%s'", argv[optind - 1]);
return;
}
+ } /* while (1) */
+
+ if (im->use_rrdcached == 0)
+ {
+ char *temp;
+
+ temp = getenv (ENV_RRDCACHED_ADDRESS);
+ if (temp != NULL)
+ {
+ int status;
+
+ status = rrdc_connect (temp);
+ if (status != 0)
+ {
+ rrd_set_error ("rrdc_connect(%s) failed with status %i.",
+ temp, status);
+ return;
+ }
+ im->use_rrdcached = 1;
+ }
}
+
+ pango_cairo_context_set_font_options(pango_layout_get_context(im->layout), im->font_options);
+ pango_layout_context_changed(im->layout);
+
+
if (im->logarithmic && im->minval <= 0) {
rrd_set_error
src = &im->gdes[dst->vidx];
data = src->data + src->ds;
end =
- src->end_orig % (long)src->step ==
- 0 ? src->end_orig : (src->end_orig + (long)src->step -
- src->end_orig % (long)src->step);
+ src->end_orig % (long) src->step ==
+ 0 ? src->end_orig : (src->end_orig + (long) src->step -
+ src->end_orig % (long) src->step);
steps = (end - src->start) / src->step;
#if 0
, VDEF_LSLINT /* least squares line y_intercept */
, VDEF_LSLCORREL /* least squares line correlation coefficient */
};
- enum text_prop_en { TEXT_PROP_DEFAULT = 0, /* default settings */
+ enum text_prop_en {
+ TEXT_PROP_DEFAULT = 0, /* default settings */
TEXT_PROP_TITLE, /* properties for the title */
TEXT_PROP_AXIS, /* for the numbers next to the axis */
TEXT_PROP_UNIT, /* for the vertical unit description */
- TEXT_PROP_LEGEND, /* fot the legend below the graph */
+ TEXT_PROP_LEGEND, /* for the legend below the graph */
+ TEXT_PROP_WATERMARK, /* for the little text to the side of the graph */
TEXT_PROP_LAST
};
typedef struct text_prop_t {
double size;
char font[1024];
+ PangoFontDescription *font_desc;
} text_prop_t;
char *imginfo; /* construct an <IMG ... tag and return
as first retval */
enum gfx_if_en imgformat; /* image format */
+ int use_rrdcached;
int lazy; /* only update the image if there is
reasonable probablility that the
existing one is out of date */
cairo_t *cr; /* drawin context */
cairo_font_options_t *font_options; /* cairo font options */
cairo_antialias_t graph_antialias; /* antialiasing for the graph */
-
+ PangoLayout *layout; /* the pango layout we use for writing fonts */
rrd_info_t *grinfo; /* root pointer to extra graph info */
rrd_info_t *grinfo_current; /* pointing to current entry */
} image_desc_t;
char *const);
void rrd_graph_init(
image_desc_t *);
+
void rrd_graph_options(
int,
char **,
double x,
double y,
gfx_color_t color,
- char *font,
- double size,
+ PangoFontDescription *font_desc,
double tabwidth,
double angle,
enum gfx_h_align_en h_align,
double gfx_get_text_width(
image_desc_t *im,
double start,
- char *font,
- double size,
+ PangoFontDescription *font_desc,
double tabwidth,
char *text);
void grinfo_push(
image_desc_t *im,
char *key,
- rrd_info_type_t type,
- rrd_infoval_t value);
+ rrd_info_type_t type, rrd_infoval_t value);
/*****************************************************************************
- * RRDtool 1.3.0 Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3.1 Copyright by Tobi Oetiker, 1997-2008
*****************************************************************************
* rrd_info Get Information about the configuration of an RRD
*****************************************************************************/
#include "rrd_tool.h"
#include "rrd_rpncalc.h"
+#include "rrd_client.h"
#include <stdarg.h>
/* proto */
char **argv)
{
rrd_info_t *info;
+ char *opt_daemon = NULL;
- if (argc < 2) {
- rrd_set_error("please specify an rrd");
- return NULL;
+ optind = 0;
+ opterr = 0; /* initialize getopt */
+
+ while (42) {
+ int opt;
+ int option_index = 0;
+ static struct option long_options[] = {
+ {"daemon", required_argument, 0, 'd'},
+ {0, 0, 0, 0}
+ };
+
+ opt = getopt_long(argc, argv, "d:", long_options, &option_index);
+
+ if (opt == EOF)
+ break;
+
+ switch (opt) {
+ case 'd':
+ if (opt_daemon != NULL)
+ free (opt_daemon);
+ opt_daemon = strdup (optarg);
+ if (opt_daemon == NULL)
+ {
+ rrd_set_error ("strdup failed.");
+ return (NULL);
+ }
+ break;
+
+ default:
+ rrd_set_error ("Usage: rrdtool %s [--daemon <addr>] <file>",
+ argv[0]);
+ return (NULL);
+ break;
+ }
+ } /* while (42) */
+
+ if ((argc - optind) != 1) {
+ rrd_set_error ("Usage: rrdtool %s [--daemon <addr>] <file>",
+ argv[0]);
+ return (NULL);
}
- info = rrd_info_r(argv[1]);
+ if (opt_daemon == NULL)
+ {
+ char *temp;
- return (info);
-}
+ temp = getenv (ENV_RRDCACHED_ADDRESS);
+ if (temp != NULL)
+ {
+ opt_daemon = strdup (temp);
+ if (opt_daemon == NULL)
+ {
+ rrd_set_error("strdup failed.");
+ return (NULL);
+ }
+ }
+ }
+
+ if (opt_daemon != NULL)
+ {
+ int status;
+
+ status = rrdc_connect (opt_daemon);
+ if (status != 0)
+ {
+ rrd_set_error ("rrdc_connect failed with status %i.", status);
+ return (NULL);
+ }
+ status = rrdc_flush (argv[optind]);
+ if (status != 0)
+ {
+ rrd_set_error ("rrdc_flush (%s) failed with status %i.",
+ argv[optind], status);
+ return (NULL);
+ }
+ rrdc_disconnect ();
+ } /* if (opt_daemon) */
+
+ info = rrd_info_r(argv[optind]);
+
+ return (info);
+} /* rrd_info_t *rrd_info */
rrd_info_t *rrd_info_r(
char *filename)
/*****************************************************************************
- * RRDtool 1.3.0 Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3.1 Copyright by Tobi Oetiker, 1997-2008
*****************************************************************************
* rrd_last.c
*****************************************************************************
*****************************************************************************/
#include "rrd_tool.h"
+#include "rrd_client.h"
time_t rrd_last(
int argc,
char **argv)
{
- if (argc < 2) {
- rrd_set_error("please specify an rrd");
+ char *opt_daemon = NULL;
+
+ optind = 0;
+ opterr = 0; /* initialize getopt */
+
+ while (42) {
+ int opt;
+ int option_index = 0;
+ static struct option long_options[] = {
+ {"daemon", required_argument, 0, 'd'},
+ {0, 0, 0, 0}
+ };
+
+ opt = getopt_long(argc, argv, "d:", long_options, &option_index);
+
+ if (opt == EOF)
+ break;
+
+ switch (opt) {
+ case 'd':
+ if (opt_daemon != NULL)
+ free (opt_daemon);
+ opt_daemon = strdup (optarg);
+ if (opt_daemon == NULL)
+ {
+ rrd_set_error ("strdup failed.");
+ return (-1);
+ }
+ break;
+
+ default:
+ rrd_set_error ("Usage: rrdtool %s [--daemon <addr>] <file>",
+ argv[0]);
+ return (-1);
+ break;
+ }
+ } /* while (42) */
+
+ if ((argc - optind) != 1) {
+ rrd_set_error ("Usage: rrdtool %s [--daemon <addr>] <file>",
+ argv[0]);
return (-1);
}
- return (rrd_last_r(argv[1]));
-}
+ if (opt_daemon == NULL)
+ {
+ char *temp;
+ temp = getenv (ENV_RRDCACHED_ADDRESS);
+ if (temp != NULL)
+ {
+ opt_daemon = strdup (temp);
+ if (opt_daemon == NULL)
+ {
+ rrd_set_error("strdup failed.");
+ return (-1);
+ }
+ }
+ }
+
+ if (opt_daemon != NULL)
+ {
+ int status;
+
+ status = rrdc_connect (opt_daemon);
+ if (status != 0)
+ {
+ rrd_set_error ("rrdc_connect failed with status %i.", status);
+ return (-1);
+ }
+
+ status = rrdc_flush (argv[optind]);
+ if (status != 0)
+ {
+ rrd_set_error ("rrdc_flush (%s) failed with status %i.",
+ argv[optind], status);
+ return (-1);
+ }
+
+ rrdc_disconnect ();
+ } /* if (opt_daemon) */
+
+ return (rrd_last_r (argv[optind]));
+}
time_t rrd_last_r(
const char *filename)
/*****************************************************************************
- * RRDtool 1.3.0 Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3.1 Copyright by Tobi Oetiker, 1997-2008
+ * Copyright by Florian Forster, 2008
*****************************************************************************
* rrd_lastupdate Get the last datum entered for each DS
*****************************************************************************/
#include "rrd_tool.h"
#include "rrd_rpncalc.h"
+#include "rrd_client.h"
#include <stdarg.h>
-int rrd_lastupdate(
- int argc,
- char **argv,
- time_t *last_update,
- unsigned long *ds_cnt,
- char ***ds_namv,
- char ***last_ds)
+int rrd_lastupdate (int argc, char **argv)
+{
+ time_t last_update;
+ char **ds_names;
+ char **last_ds;
+ unsigned long ds_count, i;
+ int status;
+
+ char *opt_daemon = NULL;
+
+ optind = 0;
+ opterr = 0; /* initialize getopt */
+
+ while (42) {
+ int opt;
+ int option_index = 0;
+ static struct option long_options[] = {
+ {"daemon", required_argument, 0, 'd'},
+ {0, 0, 0, 0}
+ };
+
+ opt = getopt_long (argc, argv, "d:", long_options, &option_index);
+
+ if (opt == EOF)
+ break;
+
+ switch (opt) {
+ case 'd':
+ if (opt_daemon != NULL)
+ free (opt_daemon);
+ opt_daemon = strdup (optarg);
+ if (opt_daemon == NULL)
+ {
+ rrd_set_error ("strdup failed.");
+ return (-1);
+ }
+ break;
+
+ default:
+ rrd_set_error ("Usage: rrdtool %s [--daemon <addr>] <file>",
+ argv[0]);
+ return (-1);
+ break;
+ }
+ } /* while (42) */
+
+ if ((argc - optind) != 1) {
+ rrd_set_error ("Usage: rrdtool %s [--daemon <addr>] <file>",
+ argv[0]);
+ return (-1);
+ }
+
+ if (opt_daemon == NULL)
+ {
+ char *temp;
+
+ temp = getenv (ENV_RRDCACHED_ADDRESS);
+ if (temp != NULL)
+ {
+ opt_daemon = strdup (temp);
+ if (opt_daemon == NULL)
+ {
+ rrd_set_error("strdup failed.");
+ return (-1);
+ }
+ }
+ }
+
+ if (opt_daemon != NULL)
+ {
+ status = rrdc_connect (opt_daemon);
+ if (status != 0)
+ {
+ rrd_set_error ("rrdc_connect failed with status %i.", status);
+ return (-1);
+ }
+
+ status = rrdc_flush (argv[optind]);
+ if (status != 0)
+ {
+ rrd_set_error ("rrdc_flush (%s) failed with status %i.",
+ argv[optind], status);
+ return (-1);
+ }
+
+ rrdc_disconnect ();
+ } /* if (opt_daemon) */
+
+ status = rrd_lastupdate_r (argv[optind],
+ &last_update, &ds_count, &ds_names, &last_ds);
+ if (status != 0)
+ return (status);
+
+ for (i = 0; i < ds_count; i++)
+ printf(" %s", ds_names[i]);
+ printf ("\n\n");
+
+ printf ("%10lu:", last_update);
+ for (i = 0; i < ds_count; i++) {
+ printf(" %s", last_ds[i]);
+ free(last_ds[i]);
+ free(ds_names[i]);
+ }
+ printf("\n");
+
+ free(last_ds);
+ free(ds_names);
+
+ return (0);
+} /* int rrd_lastupdate */
+
+int rrd_lastupdate_r(const char *filename,
+ time_t *ret_last_update,
+ unsigned long *ret_ds_count,
+ char ***ret_ds_names,
+ char ***ret_last_ds)
{
unsigned long i = 0;
- char *filename;
rrd_t rrd;
rrd_file_t *rrd_file;
- if (argc < 2) {
- rrd_set_error("please specify an rrd");
- goto err_out;
+ rrd_file = rrd_open(filename, &rrd, RRD_READONLY);
+ if (rrd_file == NULL) {
+ rrd_free(&rrd);
+ return (-1);
}
- filename = argv[1];
- rrd_file = rrd_open(filename, &rrd, RRD_READONLY);
- if (rrd_file == NULL)
- goto err_free;
-
- *last_update = rrd.live_head->last_up;
- *ds_cnt = rrd.stat_head->ds_cnt;
- if (((*ds_namv) =
- (char **) malloc(rrd.stat_head->ds_cnt * sizeof(char *))) == NULL) {
- rrd_set_error("malloc fetch ds_namv array");
- goto err_close;
+ *ret_last_update = rrd.live_head->last_up;
+ *ret_ds_count = rrd.stat_head->ds_cnt;
+ *ret_ds_names = (char **) malloc (rrd.stat_head->ds_cnt * sizeof(char *));
+ if (*ret_ds_names == NULL) {
+ rrd_set_error ("malloc fetch ret_ds_names array");
+ rrd_close (rrd_file);
+ rrd_free (&rrd);
+ return (-1);
}
+ memset (*ret_ds_names, 0, rrd.stat_head->ds_cnt * sizeof(char *));
- if (((*last_ds) =
- (char **) malloc(rrd.stat_head->ds_cnt * sizeof(char *))) == NULL) {
- rrd_set_error("malloc fetch last_ds array");
- goto err_free_ds_namv;
+ *ret_last_ds = (char **) malloc (rrd.stat_head->ds_cnt * sizeof(char *));
+ if (*ret_last_ds == NULL) {
+ rrd_set_error ("malloc fetch ret_last_ds array");
+ free (*ret_ds_names);
+ *ret_ds_names = NULL;
+ rrd_close (rrd_file);
+ rrd_free (&rrd);
+ return (-1);
}
+ memset (*ret_last_ds, 0, rrd.stat_head->ds_cnt * sizeof(char *));
for (i = 0; i < rrd.stat_head->ds_cnt; i++) {
- (*ds_namv)[i] = sprintf_alloc("%s", rrd.ds_def[i].ds_nam);
- (*last_ds)[i] = sprintf_alloc("%s", rrd.pdp_prep[i].last_ds);
+ (*ret_ds_names)[i] = sprintf_alloc("%s", rrd.ds_def[i].ds_nam);
+ (*ret_last_ds)[i] = sprintf_alloc("%s", rrd.pdp_prep[i].last_ds);
+
+ if (((*ret_ds_names)[i] == NULL) || ((*ret_last_ds)[i] == NULL))
+ break;
+ }
+
+ /* Check if all names and values could be copied and free everything if
+ * not. */
+ if (i < rrd.stat_head->ds_cnt) {
+ rrd_set_error ("sprintf_alloc failed");
+ for (i = 0; i < rrd.stat_head->ds_cnt; i++) {
+ if ((*ret_ds_names)[i] != NULL)
+ {
+ free ((*ret_ds_names)[i]);
+ (*ret_ds_names)[i] = NULL;
+ }
+ if ((*ret_last_ds)[i] != NULL)
+ {
+ free ((*ret_last_ds)[i]);
+ (*ret_last_ds)[i] = NULL;
+ }
+ }
+ free (*ret_ds_names);
+ *ret_ds_names = NULL;
+ free (*ret_last_ds);
+ *ret_last_ds = NULL;
+ rrd_close (rrd_file);
+ rrd_free (&rrd);
+ return (-1);
}
rrd_free(&rrd);
rrd_close(rrd_file);
return (0);
-
- err_free_ds_namv:
- free(*ds_namv);
- err_close:
- rrd_close(rrd_file);
- err_free:
- rrd_free(&rrd);
- err_out:
- return (-1);
-}
+} /* int rrd_lastupdate_r */
/*****************************************************************************
- * RRDtool 1.3.0 Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3.1 Copyright by Tobi Oetiker, 1997-2008
*****************************************************************************
* rrd_tool.c Startup wrapper
*****************************************************************************/
N_
("Valid commands: create, update, updatev, graph, graphv, dump, restore,\n"
"\t\tlast, lastupdate, first, info, fetch, tune,\n"
- "\t\tresize, xport\n\n");
+ "\t\tresize, xport, flush\n\n");
const char *help_listremote =
N_("Valid remote commands: quit, ls, cd, mkdir, pwd\n\n");
const char *help_update =
N_("* update - update an RRD\n\n"
"\trrdtool update filename\n"
- "\t\t--template|-t ds-name:ds-name:...\n"
+ "\t\t[--template|-t ds-name:ds-name:...]\n"
+ "\t\t[--daemon <address>]\n"
"\t\ttime|N:value[:value...]\n\n"
"\t\tat-time@value[:value...]\n\n"
"\t\t[ time:value[:value...] ..]\n\n");
N_("* updatev - a verbose version of update\n"
"\treturns information about values, RRAs, and datasources updated\n\n"
"\trrdtool updatev filename\n"
- "\t\t--template|-t ds-name:ds-name:...\n"
+ "\t\t[--template|-t ds-name:ds-name:...]\n"
"\t\ttime|N:value[:value...]\n\n"
"\t\tat-time@value[:value...]\n\n"
"\t\t[ time:value[:value...] ..]\n\n");
N_("* fetch - fetch data out of an RRD\n\n"
"\trrdtool fetch filename.rrd CF\n"
"\t\t[-r|--resolution resolution]\n"
- "\t\t[-s|--start start] [-e|--end end]\n\n");
+ "\t\t[-s|--start start] [-e|--end end]\n"
+ "\t\t[--daemon <address>]\n\n");
+
+ const char *help_flush =
+ N_("* flush - flush cached data out to an RRD file\n\n"
+ "\trrdtool flush filename.rrd\n"
+ "\t\t[--daemon <address>]\n\n");
/* break up very large strings (help_graph, help_tune) for ISO C89 compliance*/
"\t\t[-h|--height pixels] [-o|--logarithmic]\n"
"\t\t[-u|--upper-limit value] [-z|--lazy]\n"
"\t\t[-l|--lower-limit value] [-r|--rigid]\n"
- "\t\t[-g|--no-legend]\n"
+ "\t\t[-g|--no-legend] [--daemon <address>]\n"
"\t\t[-F|--force-rules-legend]\n" "\t\t[-j|--only-graph]\n");
const char *help_graph2 =
N_("\t\t[-n|--font FONTTAG:size:font]\n"
C_LASTUPDATE, C_FIRST, C_UPDATE, C_FETCH, C_GRAPH, C_GRAPHV,
C_TUNE,
C_RESIZE, C_XPORT, C_QUIT, C_LS, C_CD, C_MKDIR, C_PWD,
- C_UPDATEV
+ C_UPDATEV, C_FLUSH
};
int help_cmd = C_NONE;
help_cmd = C_UPDATEV;
else if (!strcmp(cmd, "fetch"))
help_cmd = C_FETCH;
+ else if (!strcmp(cmd, "flush"))
+ help_cmd = C_FLUSH;
else if (!strcmp(cmd, "graph"))
help_cmd = C_GRAPH;
else if (!strcmp(cmd, "graphv"))
case C_FETCH:
fputs(_(help_fetch), stdout);
break;
+ case C_FLUSH:
+ fputs(_(help_flush), stdout);
+ break;
case C_GRAPH:
fputs(_(help_graph0), stdout);
fputs(_(help_graph1), stdout);
return *aLinePtr = linebuf;
bufsize += MAX_LENGTH;
if (!(linebuf = realloc(linebuf, bufsize))) {
+ free(linebuf);
perror("fgetslong: realloc");
exit(1);
}
}
- return *aLinePtr = linebuf[0] ? linebuf : 0;
+ if (linebuf[0]){
+ return *aLinePtr = linebuf;
+ }
+ free(linebuf);
+ return *aLinePtr = 0;
}
int main(
== 0) {
#ifdef HAVE_CHROOT
- chroot(argv[2]);
- if (errno != 0) {
- fprintf(stderr,
- "ERROR: can't change root to '%s' errno=%d\n",
- argv[2], errno);
+ if (chroot(argv[2]) != 0){
+ fprintf(stderr, "ERROR: chroot %s: %s\n", argv[2],rrd_strerror(errno));
exit(errno);
}
ChangeRoot = 1;
}
}
if (strcmp(firstdir, "")) {
- chdir(firstdir);
- if (errno != 0) {
- fprintf(stderr, "ERROR: %s\n", rrd_strerror(errno));
+ if (chdir(firstdir) != 0){
+ fprintf(stderr, "ERROR: chdir %s %s\n", firstdir,rrd_strerror(errno));
exit(errno);
}
}
while (fgetslong(&aLine, stdin)) {
if ((argc = CountArgs(aLine)) == 0) {
+ free(aLine);
printf("ERROR: not enough arguments\n");
}
if ((myargv = (char **) malloc((argc + 1) *
exit(1);
}
if ((argc = CreateArgs(argv[0], aLine, argc, myargv)) < 0) {
+ free(aLine);
+ free(myargv);
printf("ERROR: creating arguments\n");
} else {
int ret = HandleInputLine(argc, myargv, stdout);
/* Reset errno to 0 before we start.
*/
- errno = 0;
if (RemoteMode) {
if (argc > 1 && strcmp("quit", argv[1]) == 0) {
if (argc > 2) {
return (1);
}
#endif
- chdir(argv[2]);
- if (errno != 0) {
- printf("ERROR: %s\n", rrd_strerror(errno));
+ if (chdir(argv[2]) != 0){
+ printf("ERROR: chdir %s %s\n", argv[2], rrd_strerror(errno));
return (1);
}
return (0);
}
cwd = getcwd(NULL, MAXPATH);
if (cwd == NULL) {
- printf("ERROR: %s\n", rrd_strerror(errno));
+ printf("ERROR: getcwd %s\n", rrd_strerror(errno));
return (1);
}
printf("%s\n", cwd);
return (1);
}
#endif
- mkdir(argv[2], 0777);
- if (errno != 0) {
- printf("ERROR: %s\n", rrd_strerror(errno));
+ if(mkdir(argv[2], 0777)!=0){
+ printf("ERROR: mkdir %s: %s\n", argv[2],rrd_strerror(errno));
return (1);
}
return (0);
}
closedir(curdir);
} else {
- printf("ERROR: %s\n", rrd_strerror(errno));
+ printf("ERROR: opendir .: %s\n", rrd_strerror(errno));
return (errno);
}
return (0);
else if (strcmp("last", argv[1]) == 0)
printf("%ld\n", rrd_last(argc - 1, &argv[1]));
else if (strcmp("lastupdate", argv[1]) == 0) {
- time_t last_update;
- char **ds_namv;
- char **last_ds;
- unsigned long ds_cnt, i;
-
- if (rrd_lastupdate(argc - 1, &argv[1], &last_update,
- &ds_cnt, &ds_namv, &last_ds) == 0) {
- for (i = 0; i < ds_cnt; i++)
- printf(" %s", ds_namv[i]);
- printf("\n\n");
- printf("%10lu:", last_update);
- for (i = 0; i < ds_cnt; i++) {
- printf(" %s", last_ds[i]);
- free(last_ds[i]);
- free(ds_namv[i]);
- }
- printf("\n");
- free(last_ds);
- free(ds_namv);
- }
+ rrd_lastupdate(argc - 1, &argv[1]);
} else if (strcmp("first", argv[1]) == 0)
printf("%ld\n", rrd_first(argc - 1, &argv[1]));
else if (strcmp("update", argv[1]) == 0)
} else if (strcmp("tune", argv[1]) == 0)
rrd_tune(argc - 1, &argv[1]);
+ else if (strcmp("flush", argv[1]) == 0)
+ rrd_cmd_flush(argc - 1, &argv[1]);
else {
rrd_set_error("unknown function '%s'", argv[1]);
}
/*****************************************************************************
- * RRDtool 1.3.0 Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3.1 Copyright by Tobi Oetiker, 1997-2008
*****************************************************************************
* rrd_tool.h Common Header File
*****************************************************************************/
int rrd_create_fn(
const char *file_name,
rrd_t *rrd);
- int rrd_fetch_fn(
- const char *filename,
- enum cf_en cf_idx,
- time_t *start,
- time_t *end,
- unsigned long *step,
- unsigned long *ds_cnt,
- char ***ds_namv,
- rrd_value_t **data);
+ int rrd_fetch_fn (const char *filename,
+ enum cf_en cf_idx,
+ time_t *start,
+ time_t *end,
+ unsigned long *step,
+ unsigned long *ds_cnt,
+ char ***ds_namv,
+ rrd_value_t **data);
#define RRD_READONLY (1<<0)
#define RRD_READWRITE (1<<1)
/*****************************************************************************
- * RRDtool 1.3.0 Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3.1 Copyright by Tobi Oetiker, 1997-2008
+ * Copyright by Florian Forster, 2008
*****************************************************************************
* rrd_update.c RRD Update Function
*****************************************************************************
#include "rrd_is_thread_safe.h"
#include "unused.h"
+#include "rrd_client.h"
+
#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)
/*
* WIN32 does not have gettimeofday and struct timeval. This is a quick and dirty
{
struct option long_options[] = {
{"template", required_argument, 0, 't'},
+ {"daemon", required_argument, 0, 'd'},
{0, 0, 0, 0}
};
int option_index = 0;
int opt;
char *tmplt = NULL;
int rc = -1;
+ char *opt_daemon = NULL;
optind = 0;
opterr = 0; /* initialize getopt */
while (1) {
- opt = getopt_long(argc, argv, "t:", long_options, &option_index);
+ opt = getopt_long(argc, argv, "t:d:", long_options, &option_index);
if (opt == EOF)
break;
tmplt = strdup(optarg);
break;
+ case 'd':
+ if (opt_daemon != NULL)
+ free (opt_daemon);
+ opt_daemon = strdup (optarg);
+ if (opt_daemon == NULL)
+ {
+ rrd_set_error("strdup failed.");
+ goto out;
+ }
+ break;
+
case '?':
rrd_set_error("unknown option '%s'", argv[optind - 1]);
goto out;
goto out;
}
+ if ((tmplt != NULL) && (opt_daemon != NULL))
+ {
+ rrd_set_error("The caching opt_daemon cannot be used together with "
+ "templates yet.");
+ goto out;
+ }
+
+ if ((tmplt == NULL) && (opt_daemon == NULL))
+ {
+ char *temp;
+
+ temp = getenv (ENV_RRDCACHED_ADDRESS);
+ if (temp != NULL)
+ {
+ opt_daemon = strdup (temp);
+ if (opt_daemon == NULL)
+ {
+ rrd_set_error("strdup failed.");
+ goto out;
+ }
+ }
+ }
+
+ if (opt_daemon != NULL)
+ {
+ int status;
+
+ status = rrdc_connect (opt_daemon);
+ if (status != 0)
+ {
+ rrd_set_error("Unable to connect to opt_daemon: %s",
+ (status < 0)
+ ? "Internal error"
+ : rrd_strerror (status));
+ goto out;
+ }
+
+ status = rrdc_update (/* file = */ argv[optind],
+ /* values_num = */ argc - optind - 1,
+ /* values = */ (void *) (argv + optind + 1));
+ if (status != 0)
+ {
+ rrd_set_error("Failed sending the values to the opt_daemon: %s",
+ (status < 0)
+ ? "Internal error"
+ : rrd_strerror (status));
+ }
+ else
+ {
+ rc = 0;
+ }
+
+ rrdc_disconnect ();
+ goto out;
+ } /* if (opt_daemon != NULL) */
+
rc = rrd_update_r(argv[optind], tmplt,
argc - optind - 1, (const char **) (argv + optind + 1));
out:
- free(tmplt);
+ if (tmplt != NULL)
+ {
+ free(tmplt);
+ tmplt = NULL;
+ }
+ if (opt_daemon != NULL)
+ {
+ free (opt_daemon);
+ opt_daemon = NULL;
+ }
return rc;
}
rra_step_cnt, updvals, tmpl_idx, tmpl_cnt,
&pcdp_summary, version, skip_update,
&schedule_smooth) == -1) {
- if (rrd_test_error()) { /* Should have error string always here */
- char *save_error;
-
- /* Prepend file name to error message */
- if ((save_error = strdup(rrd_get_error())) != NULL) {
- rrd_set_error("%s: %s", filename, save_error);
- free(save_error);
- }
- }
+ if (rrd_test_error()) { /* Should have error string always here */
+ char *save_error;
+
+ /* Prepend file name to error message */
+ if ((save_error = strdup(rrd_get_error())) != NULL) {
+ rrd_set_error("%s: %s", filename, save_error);
+ free(save_error);
+ }
+ }
free(arg_copy);
break;
}
/****************************************************************************
- * RRDtool 1.3.0 Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3.1 Copyright by Tobi Oetiker, 1997-2008
****************************************************************************
* rrd_xport.c export RRD data
****************************************************************************/
#include "rrd_graph.h"
#include "rrd_xport.h"
#include "unused.h"
+#include "rrd_client.h"
#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)
#include <io.h>
char ***legend_v, /* legend entries */
rrd_value_t **data)
{ /* two dimensional array containing the data */
-
image_desc_t im;
time_t start_tmp = 0, end_tmp = 0;
rrd_time_value_t start_tv, end_tv;
{"maxrows", required_argument, 0, 'm'},
{"step", required_argument, 0, 261},
{"enumds", no_argument, 0, 262}, /* these are handled in the frontend ... */
+ {"daemon", required_argument, 0, 'd'},
{0, 0, 0, 0}
};
int option_index = 0;
int opt;
- opt = getopt_long(argc, argv, "s:e:m:", long_options, &option_index);
+ opt = getopt_long(argc, argv, "s:e:m:d:", long_options, &option_index);
if (opt == EOF)
break;
return -1;
}
break;
+ case 'd':
+ {
+ int status;
+ if (im.use_rrdcached)
+ {
+ rrd_set_error ("You cannot specify --daemon "
+ "more than once.");
+ return (-1);
+ }
+ status = rrdc_connect (optarg);
+ if (status != 0)
+ {
+ rrd_set_error ("rrdc_connect(%s) failed with status %i.",
+ optarg, status);
+ return (-1);
+ }
+ im.use_rrdcached = 1;
+ break;
+ }
+
case '?':
rrd_set_error("unknown option '%s'", argv[optind - 1]);
return -1;
return (-1);
}
+ if (im.use_rrdcached == 0)
+ {
+ char *temp;
+
+ temp = getenv (ENV_RRDCACHED_ADDRESS);
+ if (temp != NULL)
+ {
+ int status;
+
+ status = rrdc_connect (temp);
+ if (status != 0)
+ {
+ rrd_set_error ("rrdc_connect(%s) failed with status %i.",
+ temp, status);
+ return (-1);
+ }
+ im.use_rrdcached = 1;
+ }
+ }
+
if (rrd_xport_fn(&im, start, end, step, col_cnt, legend_v, data) == -1) {
im_free(&im);
return -1;