-
- image_desc_t im;
- int i;
- long long_tmp;
- time_t start_tmp=0,end_tmp=0;
- char scan_gtm[12],scan_mtm[12],scan_ltm[12],col_nam[12];
- char symname[100];
- unsigned int col_red,col_green,col_blue;
- long scancount;
- int linepass = 0; /* stack can only follow directly after LINE* AREA or STACK */
- struct time_value start_tv, end_tv;
- char *parsetime_error = NULL;
- int stroff;
-
- (*prdata)=NULL;
-
- parsetime("end-24h", &start_tv);
- parsetime("now", &end_tv);
-
- im.xlab_user.minsec = -1;
- im.xgif=0;
- im.ygif=0;
- im.xsize = 400;
- im.ysize = 100;
- im.step = 0;
- im.ylegend[0] = '\0';
- im.title[0] = '\0';
- im.minval = DNAN;
- im.maxval = DNAN;
- im.interlaced = 0;
- im.unitsexponent= 9999;
- im.extra_flags= 0;
- im.rigid = 0;
- im.imginfo = NULL;
- im.lazy = 0;
- im.logarithmic = 0;
- im.ygridstep = DNAN;
- im.draw_x_grid = 1;
- im.draw_y_grid = 1;
- im.base = 1000;
- im.prt_c = 0;
- im.gdes_c = 0;
- im.gdes = NULL;
- im.imgformat = IF_GIF; /* we default to GIF output */
-
- for(i=0;i<DIM(graph_col);i++)
- im.graph_col[i].red=-1;
-
-
- while (1){
- static struct option long_options[] =
- {
- {"start", required_argument, 0, 's'},
- {"end", required_argument, 0, 'e'},
- {"x-grid", required_argument, 0, 'x'},
- {"y-grid", required_argument, 0, 'y'},
- {"vertical-label",required_argument,0,'v'},
- {"width", required_argument, 0, 'w'},
- {"height", required_argument, 0, 'h'},
- {"interlaced", no_argument, 0, 'i'},
- {"upper-limit",required_argument, 0, 'u'},
- {"lower-limit",required_argument, 0, 'l'},
- {"rigid", no_argument, 0, 'r'},
- {"base", required_argument, 0, 'b'},
- {"logarithmic",no_argument, 0, 'o'},
- {"color", required_argument, 0, 'c'},
- {"title", required_argument, 0, 't'},
- {"imginfo", required_argument, 0, 'f'},
- {"imgformat", required_argument, 0, 'a'},
- {"lazy", no_argument, 0, 'z'},
- {"no-legend", no_argument, 0, 'g'},
- {"alt-y-grid", no_argument, 0, 257 },
- {"alt-autoscale", no_argument, 0, 258 },
- {"alt-autoscale-max", no_argument, 0, 259 },
- {"units-exponent",required_argument, 0, 260},
- {"step", required_argument, 0, 261},
- {0,0,0,0}};
- int option_index = 0;
- int opt;
-
-
- opt = getopt_long(argc, argv,
- "s:e:x:y:v:w:h:iu:l:rb:oc:t:f:a:z:g",
- long_options, &option_index);
-
- if (opt == EOF)
- break;
-
- switch(opt) {
- case 257:
- im.extra_flags |= ALTYGRID;
- break;
- case 258:
- im.extra_flags |= ALTAUTOSCALE;
- break;
- case 259:
- im.extra_flags |= ALTAUTOSCALE_MAX;
- break;
- case 'g':
- im.extra_flags |= NOLEGEND;
- break;
- case 260:
- im.unitsexponent = atoi(optarg);
- break;
- case 261:
- im.step = atoi(optarg);
- break;
- case 's':
- if ((parsetime_error = parsetime(optarg, &start_tv))) {
- rrd_set_error( "start time: %s", parsetime_error );
- return -1;
- }
- break;
- case 'e':
- if ((parsetime_error = parsetime(optarg, &end_tv))) {
- rrd_set_error( "end time: %s", parsetime_error );
- return -1;
- }
- break;
- case 'x':
- if(strcmp(optarg,"none") == 0){
- im.draw_x_grid=0;
- break;
- };
-
- if(sscanf(optarg,
- "%10[A-Z]:%ld:%10[A-Z]:%ld:%10[A-Z]:%ld:%ld:%n",
- scan_gtm,
- &im.xlab_user.gridst,
- scan_mtm,
- &im.xlab_user.mgridst,
- scan_ltm,
- &im.xlab_user.labst,
- &im.xlab_user.precis,
- &stroff) == 7 && stroff != 0){
- strncpy(im.xlab_form, optarg+stroff, sizeof(im.xlab_form) - 1);
- if((im.xlab_user.gridtm = tmt_conv(scan_gtm)) == -1){
- rrd_set_error("unknown keyword %s",scan_gtm);
- return -1;
- } else if ((im.xlab_user.mgridtm = tmt_conv(scan_mtm)) == -1){
- rrd_set_error("unknown keyword %s",scan_mtm);
- return -1;
- } else if ((im.xlab_user.labtm = tmt_conv(scan_ltm)) == -1){
- rrd_set_error("unknown keyword %s",scan_ltm);
- return -1;
- }
- im.xlab_user.minsec = 1;
- im.xlab_user.stst = im.xlab_form;
- } else {
- rrd_set_error("invalid x-grid format");
- return -1;
- }
- break;
- case 'y':
-
- if(strcmp(optarg,"none") == 0){
- im.draw_y_grid=0;
- break;
- };
-
- if(sscanf(optarg,
- "%lf:%d",
- &im.ygridstep,
- &im.ylabfact) == 2) {
- if(im.ygridstep<=0){
- rrd_set_error("grid step must be > 0");
- return -1;
- } else if (im.ylabfact < 1){
- rrd_set_error("label factor must be > 0");
- return -1;
- }
- } else {
- rrd_set_error("invalid y-grid format");
- return -1;
- }
- break;
- case 'v':
- strncpy(im.ylegend,optarg,150);
- im.ylegend[150]='\0';
- break;
- case 'u':
- im.maxval = atof(optarg);
- break;
- case 'l':
- im.minval = atof(optarg);
- break;
- case 'b':
- im.base = atol(optarg);
- if(im.base != 1024 && im.base != 1000 ){
- rrd_set_error("the only sensible value for base apart from 1000 is 1024");
- return -1;
- }
- break;
- case 'w':
- long_tmp = atol(optarg);
- if (long_tmp < 10) {
- rrd_set_error("width below 10 pixels");
- return -1;
- }
- im.xsize = long_tmp;
- break;
- case 'h':
- long_tmp = atol(optarg);
- if (long_tmp < 10) {
- rrd_set_error("height below 10 pixels");
- return -1;
- }
- im.ysize = long_tmp;
- break;
- case 'i':
- im.interlaced = 1;
- break;
- case 'r':
- im.rigid = 1;
- break;
- case 'f':
- im.imginfo = optarg;
- break;
- case 'a':
- if((im.imgformat = if_conv(optarg)) == -1) {
- rrd_set_error("unsupported graphics format '%s'",optarg);
- return -1;
- }
- break;
- case 'z':
- im.lazy = 1;
- break;
- case 'o':
- im.logarithmic = 1;
- if (isnan(im.minval))
- im.minval=1;
- break;
- case 'c':
- if(sscanf(optarg,
- "%10[A-Z]#%2x%2x%2x",
- col_nam,&col_red,&col_green,&col_blue) == 4){
- int ci;
- if((ci=grc_conv(col_nam)) != -1){
- im.graph_col[ci].red=col_red;
- im.graph_col[ci].green=col_green;
- im.graph_col[ci].blue=col_blue;
- } else {
- rrd_set_error("invalid color name '%s'",col_nam);
- }
- } else {
- rrd_set_error("invalid color def format");
- return -1;
- }
- break;
- case 't':
- strncpy(im.title,optarg,150);
- im.title[150]='\0';
- break;
-
- case '?':
+ int prlines = 0;
+ rrd_info_t *grinfo = NULL;
+ rrd_info_t *walker;
+
+ grinfo = rrd_graph_v(argc, argv);
+ if (grinfo == NULL)
+ return -1;
+ walker = grinfo;
+ (*prdata) = NULL;
+ while (walker) {
+ if (strcmp(walker->key, "image_info") == 0) {
+ prlines++;
+ if (((*prdata) =
+ (char**)rrd_realloc((*prdata),
+ (prlines + 1) * sizeof(char *))) == NULL) {
+ rrd_set_error("realloc prdata");
+ return 0;
+ }
+ /* imginfo goes to position 0 in the prdata array */
+ (*prdata)[prlines - 1] = (char*)malloc((strlen(walker->value.u_str)
+ + 2) * sizeof(char));
+ strcpy((*prdata)[prlines - 1], walker->value.u_str);
+ (*prdata)[prlines] = NULL;
+ }
+ /* skip anything else */
+ walker = walker->next;
+ }
+ walker = grinfo;
+ *xsize = 0;
+ *ysize = 0;
+ *ymin = 0;
+ *ymax = 0;
+ while (walker) {
+ if (strcmp(walker->key, "image_width") == 0) {
+ *xsize = walker->value.u_cnt;
+ } else if (strcmp(walker->key, "image_height") == 0) {
+ *ysize = walker->value.u_cnt;
+ } else if (strcmp(walker->key, "value_min") == 0) {
+ *ymin = walker->value.u_val;
+ } else if (strcmp(walker->key, "value_max") == 0) {
+ *ymax = walker->value.u_val;
+ } else if (strncmp(walker->key, "print", 5) == 0) { /* keys are prdate[0..] */
+ prlines++;
+ if (((*prdata) =
+ (char**)rrd_realloc((*prdata),
+ (prlines + 1) * sizeof(char *))) == NULL) {
+ rrd_set_error("realloc prdata");
+ return 0;
+ }
+ (*prdata)[prlines - 1] = (char*)malloc((strlen(walker->value.u_str)
+ + 2) * sizeof(char));
+ (*prdata)[prlines] = NULL;
+ strcpy((*prdata)[prlines - 1], walker->value.u_str);
+ } else if (strcmp(walker->key, "image") == 0) {
+ if ( fwrite(walker->value.u_blo.ptr, walker->value.u_blo.size, 1,
+ (stream ? stream : stdout)) == 0 && ferror(stream ? stream : stdout)){
+ rrd_set_error("writing image");
+ return 0;
+ }
+ }
+ /* skip anything else */
+ walker = walker->next;
+ }
+ rrd_info_free(grinfo);
+ return 0;
+}
+
+
+/* Some surgery done on this function, it became ridiculously big.
+** Things moved:
+** - initializing now in rrd_graph_init()
+** - options parsing now in rrd_graph_options()
+** - script parsing now in rrd_graph_script()
+*/
+rrd_info_t *rrd_graph_v(
+ int argc,
+ char **argv)
+{
+ image_desc_t im;
+ rrd_info_t *grinfo;
+ char *old_locale;
+ rrd_graph_init(&im);
+ /* a dummy surface so that we can measure text sizes for placements */
+ old_locale = setlocale(LC_NUMERIC, "C");
+ rrd_graph_options(argc, argv, &im);
+ if (rrd_test_error()) {
+ rrd_info_free(im.grinfo);
+ im_free(&im);
+ return NULL;
+ }
+
+ if (optind >= argc) {
+ rrd_info_free(im.grinfo);
+ im_free(&im);
+ rrd_set_error("missing filename");
+ return NULL;
+ }
+
+ if (strlen(argv[optind]) >= MAXPATH) {
+ rrd_set_error("filename (including path) too long");
+ rrd_info_free(im.grinfo);
+ im_free(&im);
+ return NULL;
+ }
+
+ strncpy(im.graphfile, argv[optind], MAXPATH - 1);
+ im.graphfile[MAXPATH - 1] = '\0';
+
+ if (strcmp(im.graphfile, "-") == 0) {
+ im.graphfile[0] = '\0';
+ }
+
+ rrd_graph_script(argc, argv, &im, 1);
+ setlocale(LC_NUMERIC, old_locale); /* reenable locale for rendering the graph */
+
+ if (rrd_test_error()) {
+ rrd_info_free(im.grinfo);
+ im_free(&im);
+ return NULL;
+ }
+
+ /* Everything is now read and the actual work can start */
+
+ if (graph_paint(&im) == -1) {
+ rrd_info_free(im.grinfo);
+ im_free(&im);
+ return NULL;
+ }
+
+
+ /* The image is generated and needs to be output.
+ ** Also, if needed, print a line with information about the image.
+ */
+
+ if (im.imginfo) {
+ rrd_infoval_t info;
+ char *path;
+ char *filename;
+
+ path = strdup(im.graphfile);
+ filename = basename(path);
+ info.u_str =
+ sprintf_alloc(im.imginfo,
+ filename,
+ (long) (im.zoom *
+ im.ximg), (long) (im.zoom * im.yimg));
+ grinfo_push(&im, sprintf_alloc("image_info"), RD_I_STR, info);
+ free(info.u_str);
+ free(path);
+ }
+ if (im.rendered_image) {
+ rrd_infoval_t img;
+
+ img.u_blo.size = im.rendered_image_size;
+ img.u_blo.ptr = im.rendered_image;
+ grinfo_push(&im, sprintf_alloc("image"), RD_I_BLO, img);
+ }
+ grinfo = im.grinfo;
+ im_free(&im);
+ return grinfo;
+}
+
+static void
+rrd_set_font_desc (
+ image_desc_t *im,int prop,char *font, double size ){
+ if (font){
+ strncpy(im->text_prop[prop].font, font, sizeof(text_prop[prop].font) - 1);
+ im->text_prop[prop].font[sizeof(text_prop[prop].font) - 1] = '\0';
+ im->text_prop[prop].font_desc = pango_font_description_from_string( font );
+ };
+ if (size > 0){
+ im->text_prop[prop].size = size;
+ };
+ if (im->text_prop[prop].font_desc && im->text_prop[prop].size ){
+ pango_font_description_set_size(im->text_prop[prop].font_desc, im->text_prop[prop].size * PANGO_SCALE);
+ };
+}
+
+void rrd_graph_init(
+ image_desc_t
+ *im)
+{
+ unsigned int i;
+ char *deffont = getenv("RRD_DEFAULT_FONT");
+ static PangoFontMap *fontmap = NULL;
+ PangoContext *context;
+
+#ifdef HAVE_TZSET
+ tzset();
+#endif
+
+ im->base = 1000;
+ im->daemon_addr = NULL;
+ im->draw_x_grid = 1;
+ im->draw_y_grid = 1;
+ im->draw_3d_border = 2;
+ im->dynamic_labels = 0;
+ im->extra_flags = 0;
+ im->font_options = cairo_font_options_create();
+ im->forceleftspace = 0;
+ im->gdes_c = 0;
+ im->gdes = NULL;
+ im->graph_antialias = CAIRO_ANTIALIAS_GRAY;
+ im->grid_dash_off = 1;
+ im->grid_dash_on = 1;
+ im->gridfit = 1;
+ im->grinfo = (rrd_info_t *) NULL;
+ im->grinfo_current = (rrd_info_t *) NULL;
+ im->imgformat = IF_PNG;
+ im->imginfo = NULL;
+ im->lazy = 0;
+ im->legenddirection = TOP_DOWN;
+ im->legendheight = 0;
+ im->legendposition = SOUTH;
+ im->legendwidth = 0;
+ im->logarithmic = 0;
+ im->maxval = DNAN;
+ im->minval = 0;
+ im->minval = DNAN;
+ im->prt_c = 0;
+ im->rigid = 0;
+ im->rendered_image_size = 0;
+ im->rendered_image = NULL;
+ im->slopemode = 0;
+ im->step = 0;
+ im->symbol = ' ';
+ im->tabwidth = 40.0;
+ im->title[0] = '\0';
+ im->unitsexponent = 9999;
+ im->unitslength = 6;
+ im->viewfactor = 1.0;
+ im->watermark[0] = '\0';
+ im->with_markup = 0;
+ im->ximg = 0;
+ im->xlab_user.minsec = -1;
+ im->xorigin = 0;
+ im->xOriginLegend = 0;
+ im->xOriginLegendY = 0;
+ im->xOriginLegendY2 = 0;
+ im->xOriginTitle = 0;
+ im->xsize = 400;
+ im->ygridstep = DNAN;
+ im->yimg = 0;
+ im->ylegend[0] = '\0';
+ im->second_axis_scale = 0; /* 0 disables it */
+ im->second_axis_shift = 0; /* no shift by default */
+ im->second_axis_legend[0] = '\0';
+ im->second_axis_format[0] = '\0';
+ im->yorigin = 0;
+ im->yOriginLegend = 0;
+ im->yOriginLegendY = 0;
+ im->yOriginLegendY2 = 0;
+ im->yOriginTitle = 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);
+ }
+
+ if (fontmap == NULL){
+ fontmap = pango_cairo_font_map_get_default();
+ }
+
+ context = pango_cairo_font_map_create_context((PangoCairoFontMap*)fontmap);
+
+ pango_cairo_context_set_resolution(context, 100);
+
+ pango_cairo_update_context(im->cr,context);
+
+ im->layout = pango_layout_new(context);
+
+// im->layout = pango_cairo_create_layout(im->cr);
+
+
+ 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];
+
+
+}
+
+
+void rrd_graph_options(
+ int argc,
+ char *argv[],
+ image_desc_t
+ *im)
+{
+ int stroff;
+ char *parsetime_error = NULL;
+ char scan_gtm[12], scan_mtm[12], scan_ltm[12], col_nam[12];
+ time_t start_tmp = 0, end_tmp = 0;
+ long long_tmp;
+ rrd_time_value_t start_tv, end_tv;
+ long unsigned int color;
+
+ /* defines for long options without a short equivalent. should be bytes,
+ and may not collide with (the ASCII value of) short options */
+#define LONGOPT_UNITS_SI 255
+
+/* *INDENT-OFF* */
+ struct option long_options[] = {
+ { "alt-autoscale", no_argument, 0, 'A'},
+ { "imgformat", required_argument, 0, 'a'},
+ { "font-smoothing-threshold", required_argument, 0, 'B'},
+ { "base", required_argument, 0, 'b'},
+ { "color", required_argument, 0, 'c'},
+ { "full-size-mode", no_argument, 0, 'D'},
+ { "daemon", required_argument, 0, 'd'},
+ { "slope-mode", no_argument, 0, 'E'},
+ { "end", required_argument, 0, 'e'},
+ { "force-rules-legend", no_argument, 0, 'F'},
+ { "imginfo", required_argument, 0, 'f'},
+ { "graph-render-mode", required_argument, 0, 'G'},
+ { "no-legend", no_argument, 0, 'g'},
+ { "height", required_argument, 0, 'h'},
+ { "no-minor", no_argument, 0, 'I'},
+ { "interlaced", no_argument, 0, 'i'},
+ { "alt-autoscale-min", no_argument, 0, 'J'},
+ { "only-graph", no_argument, 0, 'j'},
+ { "units-length", required_argument, 0, 'L'},
+ { "lower-limit", required_argument, 0, 'l'},
+ { "alt-autoscale-max", no_argument, 0, 'M'},
+ { "zoom", required_argument, 0, 'm'},
+ { "no-gridfit", no_argument, 0, 'N'},
+ { "font", required_argument, 0, 'n'},
+ { "logarithmic", no_argument, 0, 'o'},
+ { "pango-markup", no_argument, 0, 'P'},
+ { "font-render-mode", required_argument, 0, 'R'},
+ { "rigid", no_argument, 0, 'r'},
+ { "step", required_argument, 0, 'S'},
+ { "start", required_argument, 0, 's'},
+ { "tabwidth", required_argument, 0, 'T'},
+ { "title", required_argument, 0, 't'},
+ { "upper-limit", required_argument, 0, 'u'},
+ { "vertical-label", required_argument, 0, 'v'},
+ { "watermark", required_argument, 0, 'W'},
+ { "width", required_argument, 0, 'w'},
+ { "units-exponent", required_argument, 0, 'X'},
+ { "x-grid", required_argument, 0, 'x'},
+ { "alt-y-grid", no_argument, 0, 'Y'},
+ { "y-grid", required_argument, 0, 'y'},
+ { "lazy", no_argument, 0, 'z'},
+ { "units", required_argument, 0, LONGOPT_UNITS_SI},
+ { "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 */
+ { "disable-rrdtool-tag",no_argument, 0, 1001},
+ { "right-axis", required_argument, 0, 1002},
+ { "right-axis-label", required_argument, 0, 1003},
+ { "right-axis-format", required_argument, 0, 1004},
+ { "legend-position", required_argument, 0, 1005},
+ { "legend-direction", required_argument, 0, 1006},
+ { "border", required_argument, 0, 1007},
+ { "grid-dash", required_argument, 0, 1008},
+ { "dynamic-labels", no_argument, 0, 1009},
+ { 0, 0, 0, 0}
+};
+/* *INDENT-ON* */
+
+ optind = 0;
+ opterr = 0; /* initialize getopt */
+ rrd_parsetime("end-24h", &start_tv);
+ rrd_parsetime("now", &end_tv);
+ while (1) {
+ int option_index = 0;
+ int opt;
+ int col_start, col_end;
+
+ opt = getopt_long(argc, argv,
+ "Aa:B:b:c:Dd:Ee:Ff:G:gh:IiJjL:l:Nn:Bb:oPR:rS:s:T:t:u:v:W:w:X:x:Yy:z",
+ long_options, &option_index);
+ if (opt == EOF)
+ break;
+ switch (opt) {
+ case 'I':
+ im->extra_flags |= NOMINOR;
+ break;
+ case 'Y':
+ im->extra_flags |= ALTYGRID;
+ break;
+ case 'A':
+ im->extra_flags |= ALTAUTOSCALE;
+ break;
+ case 'J':
+ im->extra_flags |= ALTAUTOSCALE_MIN;
+ break;
+ case 'M':
+ im->extra_flags |= ALTAUTOSCALE_MAX;
+ break;
+ case 'j':
+ im->extra_flags |= ONLY_GRAPH;
+ break;
+ case 'g':
+ im->extra_flags |= NOLEGEND;
+ break;
+ case 1005:
+ if (strcmp(optarg, "north") == 0) {
+ im->legendposition = NORTH;
+ } else if (strcmp(optarg, "west") == 0) {
+ im->legendposition = WEST;
+ } else if (strcmp(optarg, "south") == 0) {
+ im->legendposition = SOUTH;
+ } else if (strcmp(optarg, "east") == 0) {
+ im->legendposition = EAST;
+ } else {
+ rrd_set_error("unknown legend-position '%s'", optarg);
+ return;
+ }
+ break;
+ case 1006:
+ if (strcmp(optarg, "topdown") == 0) {
+ im->legenddirection = TOP_DOWN;
+ } else if (strcmp(optarg, "bottomup") == 0) {
+ im->legenddirection = BOTTOM_UP;
+ } else {
+ rrd_set_error("unknown legend-position '%s'", optarg);
+ return;
+ }
+ break;
+ case 'F':
+ im->extra_flags |= FORCE_RULES_LEGEND;
+ break;
+ case 1001:
+ im->extra_flags |= NO_RRDTOOL_TAG;
+ break;
+ case LONGOPT_UNITS_SI:
+ if (im->extra_flags & FORCE_UNITS) {
+ rrd_set_error("--units can only be used once!");
+ return;
+ }
+ if (strcmp(optarg, "si") == 0)
+ im->extra_flags |= FORCE_UNITS_SI;
+ else {
+ rrd_set_error("invalid argument for --units: %s", optarg);
+ return;
+ }
+ break;
+ case 'X':
+ im->unitsexponent = atoi(optarg);
+ break;
+ case 'L':
+ im->unitslength = atoi(optarg);
+ im->forceleftspace = 1;
+ break;
+ case 'T':
+ im->tabwidth = atof(optarg);
+ break;
+ case 'S':
+ im->step = atoi(optarg);
+ break;
+ case 'N':
+ im->gridfit = 0;
+ break;
+ case 'P':
+ im->with_markup = 1;
+ break;
+ case 's':
+ if ((parsetime_error = rrd_parsetime(optarg, &start_tv))) {
+ rrd_set_error("start time: %s", parsetime_error);
+ return;
+ }
+ break;
+ case 'e':
+ if ((parsetime_error = rrd_parsetime(optarg, &end_tv))) {
+ rrd_set_error("end time: %s", parsetime_error);
+ return;
+ }
+ break;
+ case 'x':
+ if (strcmp(optarg, "none") == 0) {
+ im->draw_x_grid = 0;
+ break;
+ };
+ if (sscanf(optarg,
+ "%10[A-Z]:%ld:%10[A-Z]:%ld:%10[A-Z]:%ld:%ld:%n",
+ scan_gtm,
+ &im->xlab_user.gridst,
+ scan_mtm,
+ &im->xlab_user.mgridst,
+ scan_ltm,
+ &im->xlab_user.labst,
+ &im->xlab_user.precis, &stroff) == 7 && stroff != 0) {
+ strncpy(im->xlab_form, optarg + stroff,
+ sizeof(im->xlab_form) - 1);
+ im->xlab_form[sizeof(im->xlab_form) - 1] = '\0';
+ if ((int)
+ (im->xlab_user.gridtm = tmt_conv(scan_gtm)) == -1) {
+ rrd_set_error("unknown keyword %s", scan_gtm);
+ return;
+ } else if ((int)
+ (im->xlab_user.mgridtm = tmt_conv(scan_mtm))
+ == -1) {
+ rrd_set_error("unknown keyword %s", scan_mtm);
+ return;
+ } else if ((int)
+ (im->xlab_user.labtm = tmt_conv(scan_ltm)) == -1) {
+ rrd_set_error("unknown keyword %s", scan_ltm);
+ return;
+ }
+ im->xlab_user.minsec = 1;
+ im->xlab_user.stst = im->xlab_form;
+ } else {
+ rrd_set_error("invalid x-grid format");
+ return;
+ }
+ break;
+ case 'y':
+
+ if (strcmp(optarg, "none") == 0) {
+ im->draw_y_grid = 0;
+ break;
+ };
+ if (sscanf(optarg, "%lf:%d", &im->ygridstep, &im->ylabfact) == 2) {
+ if (im->ygridstep <= 0) {
+ rrd_set_error("grid step must be > 0");
+ return;
+ } else if (im->ylabfact < 1) {
+ rrd_set_error("label factor must be > 0");
+ return;
+ }
+ } else {
+ rrd_set_error("invalid y-grid format");
+ return;
+ }
+ break;
+ case 1007:
+ im->draw_3d_border = atoi(optarg);
+ break;
+ case 1008: /* grid-dash */
+ if(sscanf(optarg,
+ "%lf:%lf",
+ &im->grid_dash_on,
+ &im->grid_dash_off) != 2) {
+ rrd_set_error("expected grid-dash format float:float");
+ return;
+ }
+ break;
+ case 1009: /* enable dynamic labels */
+ im->dynamic_labels = 1;
+ break;
+ case 1002: /* right y axis */
+
+ if(sscanf(optarg,
+ "%lf:%lf",
+ &im->second_axis_scale,
+ &im->second_axis_shift) == 2) {
+ if(im->second_axis_scale==0){
+ rrd_set_error("the second_axis_scale must not be 0");
+ return;
+ }
+ } else {
+ rrd_set_error("invalid right-axis format expected scale:shift");
+ return;
+ }
+ break;
+ case 1003:
+ strncpy(im->second_axis_legend,optarg,150);
+ im->second_axis_legend[150]='\0';
+ break;
+ case 1004:
+ if (bad_format(optarg)){
+ rrd_set_error("use either %le or %lf formats");
+ return;
+ }
+ strncpy(im->second_axis_format,optarg,150);
+ im->second_axis_format[150]='\0';
+ break;
+ case 'v':
+ strncpy(im->ylegend, optarg, 150);
+ im->ylegend[150] = '\0';
+ break;
+ case 'u':
+ im->maxval = atof(optarg);
+ break;
+ case 'l':
+ im->minval = atof(optarg);
+ break;
+ case 'b':
+ im->base = atol(optarg);
+ if (im->base != 1024 && im->base != 1000) {
+ rrd_set_error
+ ("the only sensible value for base apart from 1000 is 1024");
+ return;
+ }
+ break;
+ case 'w':
+ long_tmp = atol(optarg);
+ if (long_tmp < 10) {
+ rrd_set_error("width below 10 pixels");
+ return;
+ }
+ im->xsize = long_tmp;
+ break;
+ case 'h':
+ long_tmp = atol(optarg);
+ if (long_tmp < 10) {
+ rrd_set_error("height below 10 pixels");
+ return;
+ }
+ im->ysize = long_tmp;
+ break;
+ case 'D':
+ im->extra_flags |= FULL_SIZE_MODE;
+ break;
+ case 'i':
+ /* interlaced png not supported at the moment */
+ break;
+ case 'r':
+ im->rigid = 1;
+ break;
+ case 'f':
+ im->imginfo = optarg;
+ break;
+ case 'a':
+ if ((int)
+ (im->imgformat = if_conv(optarg)) == -1) {
+ rrd_set_error("unsupported graphics format '%s'", optarg);
+ return;
+ }
+ break;
+ case 'z':
+ im->lazy = 1;
+ break;
+ case 'E':
+ im->slopemode = 1;
+ break;
+ case 'o':
+ im->logarithmic = 1;
+ break;
+ case 'c':
+ if (sscanf(optarg,
+ "%10[A-Z]#%n%8lx%n",
+ col_nam, &col_start, &color, &col_end) == 2) {
+ int ci;
+ int col_len = col_end - col_start;
+
+ switch (col_len) {
+ case 3:
+ color =
+ (((color & 0xF00) * 0x110000) | ((color & 0x0F0) *
+ 0x011000) |
+ ((color & 0x00F)
+ * 0x001100)
+ | 0x000000FF);
+ break;
+ case 4:
+ color =
+ (((color & 0xF000) *
+ 0x11000) | ((color & 0x0F00) *
+ 0x01100) | ((color &
+ 0x00F0) *
+ 0x00110) |
+ ((color & 0x000F) * 0x00011)
+ );
+ break;
+ case 6:
+ color = (color << 8) + 0xff /* shift left by 8 */ ;
+ break;
+ case 8:
+ break;
+ default:
+ rrd_set_error("the color format is #RRGGBB[AA]");
+ return;
+ }
+ if ((ci = grc_conv(col_nam)) != -1) {
+ im->graph_col[ci] = gfx_hex_to_col(color);
+ } else {
+ rrd_set_error("invalid color name '%s'", col_nam);
+ return;
+ }
+ } else {
+ rrd_set_error("invalid color def format");
+ return;
+ }
+ break;
+ case 'n':{
+ char prop[15];
+ double size = 1;
+ int end;
+
+ if (sscanf(optarg, "%10[A-Z]:%lf%n", prop, &size, &end) >= 2) {
+ int sindex, propidx;
+
+ if ((sindex = text_prop_conv(prop)) != -1) {
+ for (propidx = sindex;
+ propidx < TEXT_PROP_LAST; propidx++) {
+ if (size > 0) {
+ rrd_set_font_desc(im,propidx,NULL,size);
+ }
+ if ((int) strlen(optarg) > end+2) {
+ if (optarg[end] == ':') {
+ rrd_set_font_desc(im,propidx,optarg + end + 1,0);
+ } else {
+ rrd_set_error
+ ("expected : after font size in '%s'",
+ optarg);
+ return;
+ }
+ }
+ /* only run the for loop for DEFAULT (0) for
+ all others, we break here. woodo programming */
+ if (propidx == sindex && sindex != 0)
+ break;
+ }
+ } else {
+ rrd_set_error("invalid fonttag '%s'", prop);
+ return;
+ }
+ } else {
+ rrd_set_error("invalid text property format");
+ return;
+ }
+ break;
+ }
+ case 'm':
+ im->zoom = atof(optarg);
+ if (im->zoom <= 0.0) {
+ rrd_set_error("zoom factor must be > 0");
+ return;
+ }
+ break;
+ case 't':
+ strncpy(im->title, optarg, 150);
+ im->title[150] = '\0';
+ break;
+ case 'R':
+ if (strcmp(optarg, "normal") == 0) {
+ cairo_font_options_set_antialias
+ (im->font_options, CAIRO_ANTIALIAS_GRAY);
+ cairo_font_options_set_hint_style
+ (im->font_options, CAIRO_HINT_STYLE_FULL);
+ } else if (strcmp(optarg, "light") == 0) {
+ cairo_font_options_set_antialias
+ (im->font_options, CAIRO_ANTIALIAS_GRAY);
+ cairo_font_options_set_hint_style
+ (im->font_options, CAIRO_HINT_STYLE_SLIGHT);
+ } else if (strcmp(optarg, "mono") == 0) {
+ cairo_font_options_set_antialias
+ (im->font_options, CAIRO_ANTIALIAS_NONE);
+ cairo_font_options_set_hint_style
+ (im->font_options, CAIRO_HINT_STYLE_FULL);
+ } else {
+ rrd_set_error("unknown font-render-mode '%s'", optarg);
+ return;
+ }
+ break;
+ case 'G':
+ if (strcmp(optarg, "normal") == 0)
+ im->graph_antialias = CAIRO_ANTIALIAS_GRAY;
+ else if (strcmp(optarg, "mono") == 0)
+ im->graph_antialias = CAIRO_ANTIALIAS_NONE;
+ else {
+ rrd_set_error("unknown graph-render-mode '%s'", optarg);
+ return;
+ }
+ break;
+ case 'B':
+ /* not supported curently */
+ break;
+ case 'W':
+ strncpy(im->watermark, optarg, 100);
+ im->watermark[99] = '\0';
+ break;
+ case 'd':
+ {
+ if (im->daemon_addr != NULL)
+ {
+ rrd_set_error ("You cannot specify --daemon "
+ "more than once.");
+ return;
+ }
+
+ im->daemon_addr = strdup(optarg);
+ if (im->daemon_addr == NULL)
+ {
+ rrd_set_error("strdup failed");
+ return;
+ }
+
+ break;
+ }
+ case '?':