예제 #1
0
int
rrd_parse_legend(char *line, unsigned int *eaten, graph_desc_t *gdp) {
    int i;

    if (line[*eaten]=='\0' || line[*eaten]==':') {
	dprintf("- no (or: empty) legend found\n");
	return 0;
    }

    i=scan_for_col(&line[*eaten],FMT_LEG_LEN,gdp->legend);

    (*eaten)+=i;

    if (line[*eaten]!='\0' && line[*eaten]!=':') {
	rrd_set_error("Legend too long");
	return 1;
    } else {
	return 0;
    }
}
예제 #2
0
/* Parsing of PART, VRULE, HRULE, LINE, AREA, STACK and TICK
** is done in one function.
**
** Stacking PART, VRULE, HRULE or TICK is not allowed.
**
** If a number (which is valid to enter) is more than a
** certain amount of characters, it is caught as an error.
** While this is arguable, so is entering fixed numbers
** with more than MAX_VNAME_LEN significant digits.
*/
int
rrd_parse_PVHLAST(char *line, unsigned int *eaten, graph_desc_t *gdp, image_desc_t *im) {
    int i,j,k;
    int colorfound=0;
    char tmpstr[MAX_VNAME_LEN + 10];	/* vname#RRGGBBAA\0 */
    static int spacecnt = 0;

    if (spacecnt == 0) {        
	float one_space = gfx_get_text_width(im->canvas, 0,
                               im->text_prop[TEXT_PROP_LEGEND].font,
                               im->text_prop[TEXT_PROP_LEGEND].size,
                               im->tabwidth,"    ", 0) / 4.0;
	float target_space = gfx_get_text_width(im->canvas, 0,
                               im->text_prop[TEXT_PROP_LEGEND].font,
                               im->text_prop[TEXT_PROP_LEGEND].size,
                               im->tabwidth,"oo", 0);
	spacecnt =  target_space / one_space;	
        dprintf("- spacecnt: %i onespace: %f targspace: %f\n",spacecnt,one_space,target_space);
    }


    dprintf("- parsing '%s'\n",&line[*eaten]);

    /* have simpler code in the drawing section */
    if ( gdp->gf == GF_STACK ){
	    gdp->stack=1;
    }

    i=scan_for_col(&line[*eaten],MAX_VNAME_LEN+9,tmpstr);
    if (line[*eaten+i]!='\0' && line[*eaten+i]!=':') {
	rrd_set_error("Cannot parse line '%s'",line);
	return 1;
    }

    j=i; while (j>0 && tmpstr[j]!='#') j--;

    if (j) {
	tmpstr[j]='\0';
    }

    /* Number or vname ?
     * It is a number only if "k" equals either "j" or "i",
     * depending on which is appropriate
     */
    dprintf("- examining value '%s'\n",tmpstr);
    k=0;
    if (gdp->gf == GF_VRULE) {
	sscanf(tmpstr,"%li%n",&gdp->xrule,&k);
	if (((j!=0)&&(k==j))||((j==0)&&(k==i))) {
		dprintf("- found time: %li\n",gdp->xrule);
	} else {
		gdp->xrule=0;	/* reset the value to "none" */
	}
    } else {
	sscanf(tmpstr,"%lf%n",&gdp->yrule,&k);
	if (((j!=0)&&(k==j))||((j==0)&&(k==i))) {
		dprintf("- found number: %f\n",gdp->yrule);
	} else {
		gdp->yrule=DNAN;	/* reset the value to "none" */
	}
    }
    if (((j!=0)&&(k!=j))||((j==0)&&(k!=i))) {
	if ((gdp->vidx=find_var(im,tmpstr))<0) {
	    rrd_set_error("Not a valid vname: %s in line %s",tmpstr,line);
	    return 1;
	}
	dprintf("- found vname: '%s' vidx %li\n",tmpstr,gdp->vidx);
    }

    if (j) {
	j++;
	dprintf("- examining color '%s'\n",&tmpstr[j]);
	if (rrd_parse_color(&tmpstr[j],gdp)) {
	    rrd_set_error("Could not parse color in '%s'",&tmpstr[j]);
	    return 1;
	}
	dprintf("- parsed color 0x%08x\n",(unsigned int)gdp->col);
	colorfound=1;
    } else {
	dprintf("- no color present in '%s'\n",tmpstr);
    }

    (*eaten) += i; /* after vname#color */
    if (line[*eaten]!='\0') {
	(*eaten)++;	/* after colon */
    }

    if (gdp->gf == GF_TICK) {
	dprintf("- parsing '%s'\n",&line[*eaten]);
	dprintf("- looking for optional TICK number\n");
	j=0;
	sscanf(&line[*eaten],"%lf%n",&gdp->yrule,&j);
	if (j) {
	    if (line[*eaten+j]!='\0' && line[*eaten+j]!=':') {
		rrd_set_error("Cannot parse TICK fraction '%s'",line);
		return 1;
	    }
	    dprintf("- found number %f\n",gdp->yrule);
	    if (gdp->yrule > 1.0 || gdp->yrule < -1.0) {
		rrd_set_error("Tick factor should be <= 1.0");
		return 1;
	    }
	    (*eaten)+=j;
	} else {
            dprintf("- not found, defaulting to 0.1\n");
            gdp->yrule=0.1;
	}
	if (line[*eaten] == '\0') {
	    dprintf("- done parsing line\n");
	    return 0;
	} else { if (line[*eaten] == ':') {
	   	    (*eaten)++;	   
	         } else {
   	             rrd_set_error("Can't make sense of that TICK line");
	           return 1;
                 }
        }
    }

    dprintf("- parsing '%s'\n",&line[*eaten]);

    /* Legend is next.  A legend without a color is an error.
    ** Stacking an item without having a legend is OK however
    ** then an empty legend should be specified.
    **   LINE:val#color:STACK	means legend is string "STACK"
    **   LINE:val#color::STACK	means no legend, and do STACK
    **   LINE:val:STACK		is an error (legend but no color)
    **   LINE:val::STACK	means no legend, and do STACK
    */
    if (colorfound) {
	int err=0;
        char *linecp = strdup(line);
	dprintf("- looking for optional legend\n");
	
	dprintf("- examining '%s'\n",&line[*eaten]);
	if (linecp[*eaten] != '\0' && linecp[*eaten] != ':') {
	    int spi;		
	    /* If the legend is not empty, it has to be prefixed with spacecnt ' ' characters. This then gets
	     * replaced by the color box later on. */
	    for (spi=0;spi<spacecnt && (*eaten) > 1;spi++){
   	       linecp[--(*eaten)]=' ';
	    }
	}

	if (rrd_parse_legend(linecp, eaten, gdp)) err=1;
	free(linecp);
	if (err) return 1;

	dprintf("- found legend '%s'\n", &gdp->legend[2]);
    } else {
	dprintf("- skipping empty legend\n");
	if (line[*eaten] != '\0' && line[*eaten] != ':') {
	    rrd_set_error("Legend set but no color: %s",&line[*eaten]);
	    return 1;
	}
    }
    if (line[*eaten]=='\0') {
	dprintf("- done parsing line\n");
	return 0;
    }
    (*eaten)++;	/* after colon */

    /* PART, HRULE, VRULE and TICK cannot be stacked. */
    if (   (gdp->gf == GF_HRULE)
	|| (gdp->gf == GF_VRULE)
#ifdef WITH_PIECHART
	|| (gdp->gf == GF_PART)
#endif
	|| (gdp->gf == GF_TICK)
	) return 0;

    dprintf("- parsing '%s'\n",&line[*eaten]);
    if (line[*eaten]!='\0') {
	dprintf("- still more, should be STACK\n");
	j=scan_for_col(&line[*eaten],5,tmpstr);
	if (line[*eaten+j]!='\0' && line[*eaten+j]!=':') {
	    /* not 5 chars */
	    rrd_set_error("Garbage found where STACK expected");
	    return 1;
	}
	if (!strcmp("STACK",tmpstr)) {
	    dprintf("- found STACK\n");
	    gdp->stack=1;
	    (*eaten)+=j;
	} else {
	    rrd_set_error("Garbage found where STACK expected");
	    return 1;
	}
    }
    if (line[*eaten]=='\0') {
	dprintf("- done parsing line\n");
	return 0;
    }
    (*eaten)++;
    dprintf("- parsing '%s'\n",&line[*eaten]);

    return 0;
}
예제 #3
0
int
rrd_parse_def(char *line, unsigned int *eaten, graph_desc_t *gdp, image_desc_t *im) {
    int			i=0;
    char 		command[7]; /* step, start, end, reduce */
    char		tmpstr[256];
    struct rrd_time_value	start_tv,end_tv;
    time_t		start_tmp=0,end_tmp=0;
    char		*parsetime_error=NULL;

    start_tv.type   = end_tv.type=ABSOLUTE_TIME;
    start_tv.offset = end_tv.offset=0;
    localtime_r(&gdp->start, &start_tv.tm);
    localtime_r(&gdp->end, &end_tv.tm);
    
    dprintf("- parsing '%s'\n",&line[*eaten]);
    dprintf("- from line '%s'\n",line);

    if (rrd_parse_vname(line,eaten,gdp,im)) return 1;
    i=scan_for_col(&line[*eaten],254,gdp->rrd);
    if (line[*eaten+i]!=':') {
	rrd_set_error("Problems reading database name");
	return 1;
    }
    (*eaten)+=++i;
    dprintf("- using file '%s'\n",gdp->rrd);

    i=0;
    sscanf(&line[*eaten], DS_NAM_FMT ":%n", gdp->ds_nam,&i);
    if (!i) {
	rrd_set_error("Cannot parse DS in '%s'",line);
	return 1;
    }
    (*eaten)+=i;
    dprintf("- using DS '%s'\n",gdp->ds_nam);

    if (rrd_parse_CF(line,eaten,gdp,&gdp->cf)) return 1;
    gdp->cf_reduce = gdp->cf;
    
    if (line[*eaten]=='\0') return 0;

    while (1) {
	dprintf("- optional parameter follows: %s\n", &line[*eaten]);
	i=0;
	sscanf(&line[*eaten], "%6[a-z]=%n", command, &i);
	if (!i) {
	    rrd_set_error("Parse error in '%s'",line);
	    return 1;
	}
	(*eaten)+=i;
	dprintf("- processing '%s'\n",command);
	if (!strcmp("reduce",command)) {
	  if (rrd_parse_CF(line,eaten,gdp,&gdp->cf_reduce)) return 1;
	  if (line[*eaten] != '\0')
	      (*eaten)--;
	} else if (!strcmp("step",command)) {
	    i=0;
	    sscanf(&line[*eaten],"%lu%n",&gdp->step,&i);
	    (*eaten)+=i;
	    dprintf("- using step %lu\n",gdp->step);
	} else if (!strcmp("start",command)) {
	    i=scan_for_col(&line[*eaten],255,tmpstr);
	    (*eaten)+=i;
	    if ((parsetime_error = parsetime(tmpstr, &start_tv))) {
		rrd_set_error( "start time: %s", parsetime_error );
		return 1;
	    }
	    dprintf("- done parsing:  '%s'\n",&line[*eaten]);
	} else if (!strcmp("end",command)) {
	    i=scan_for_col(&line[*eaten],255,tmpstr);
	    (*eaten)+=i;
	    if ((parsetime_error = parsetime(tmpstr, &end_tv))) {
		rrd_set_error( "end time: %s", parsetime_error );
		return 1;
	    }
	    dprintf("- done parsing:  '%s'\n",&line[*eaten]);
	} else {
	    rrd_set_error("Parse error in '%s'",line);
	    return 1;
	}
	if (line[*eaten]=='\0') break;
	if (line[*eaten]!=':') {
	    dprintf("- Expected to see end of string but got '%s'\n",\
							 &line[*eaten]);
	    rrd_set_error("Parse error in '%s'",line);
	    return 1;
	}
	(*eaten)++;
    }
    if (proc_start_end(&start_tv,&end_tv,&start_tmp,&end_tmp) == -1){
	/* error string is set in parsetime.c */
	return 1;
    }
    if (start_tmp < 3600*24*365*10) {
	rrd_set_error("the first entry to fetch should be "
			"after 1980 (%ld)",start_tmp);
	return 1;
    }

    if (end_tmp < start_tmp) {
	rrd_set_error("start (%ld) should be less than end (%ld)",
			start_tmp, end_tmp);
	return 1;
    }

    gdp->start = start_tmp;
    gdp->end = end_tmp;

    dprintf("- start time %lu\n",gdp->start);
    dprintf("- end   time %lu\n",gdp->end);

    return 0;
}
예제 #4
0
파일: rrd_xport.c 프로젝트: blair/orca
/* mostly rrd_graph(), just pushed a bit here and stretched a bit there */
int
rrd_xport(int argc, char **argv, int *xsize,
          time_t         *start,
          time_t         *end,        /* which time frame do you want ?
				       * will be changed to represent reality */
          unsigned long  *step,       /* which stepsize do you want?
				       * will be changed to represent reality */
          unsigned long  *col_cnt,    /* number of data columns in the result */
          char           ***legend_v, /* legend entries */
          rrd_value_t    **data)      /* two dimensional array containing the data */

{
    image_desc_t   im;
    int            i;
    long           long_tmp;
    time_t	   start_tmp=0,end_tmp=0;
    char           symname[100];
    long           scancount;
    struct rrd_time_value start_tv, end_tv;
    char           *parsetime_error = NULL;

    parsetime("end-24h", &start_tv);
    parsetime("now", &end_tv);

    /* use the default values from rrd_graph.c */
    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.unitslength= 9;
    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 */

    while (1) {
        static struct option long_options[] =
        {
            {"start",      required_argument, 0,  's'},
            {"end",        required_argument, 0,  'e'},
            {"maxrows",    required_argument, 0,  'm'},
            {"step",       required_argument, 0,   261},
            {0,0,0,0}
        };
        int option_index = 0;
        int opt;

        opt = getopt_long(argc, argv, "s:e:m:",
                          long_options, &option_index);

        if (opt == EOF)
            break;

        switch(opt) {
        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 'm':
            long_tmp = atol(optarg);
            if (long_tmp < 10) {
                rrd_set_error("maxrows below 10 rows");
                return -1;
            }
            im.xsize = long_tmp;
            break;

        case '?':
            if (optopt != 0)
                rrd_set_error("unknown option '%c'", optopt);
            else
                rrd_set_error("unknown option '%s'",argv[optind-1]);
            return -1;
        }
    }

    /*
    if (optind >= argc) {
       rrd_set_error("missing filename");
       return -1;
    }
    */

    if (proc_start_end(&start_tv,&end_tv,&start_tmp,&end_tmp) == -1) {
        return -1;
    }

    if (start_tmp < 3600*24*365*10) {
        rrd_set_error("the first entry to fetch should be after 1980 (%ld)",start_tmp);
        return -1;
    }

    if (end_tmp < start_tmp) {
        rrd_set_error("start (%ld) should be less than end (%ld)",
                      start_tmp, end_tmp);
        return -1;
    }

    im.start = start_tmp;
    im.end = end_tmp;


    for(i=optind; i<argc; i++) {
        int   argstart=0;
        int   strstart=0;
        char  varname[30],*rpnex;
        gdes_alloc(&im);
        if(sscanf(argv[i],"%10[A-Z0-9]:%n",symname,&argstart)==1) {
            if((im.gdes[im.gdes_c-1].gf=gf_conv(symname))==-1) {
                im_free(&im);
                rrd_set_error("unknown function '%s'",symname);
                return -1;
            }
        } else {
            rrd_set_error("can't parse '%s'",argv[i]);
            im_free(&im);
            return -1;
        }

        switch(im.gdes[im.gdes_c-1].gf) {
        case GF_CDEF:
            if((rpnex = malloc(strlen(&argv[i][argstart])*sizeof(char)))==NULL) {
                rrd_set_error("malloc for CDEF");
                return -1;
            }
            if(sscanf(
                        &argv[i][argstart],
                        DEF_NAM_FMT "=%[^: ]",
                        im.gdes[im.gdes_c-1].vname,
                        rpnex) != 2) {
                im_free(&im);
                free(rpnex);
                rrd_set_error("can't parse CDEF '%s'",&argv[i][argstart]);
                return -1;
            }
            /* checking for duplicate DEF CDEFS */
            if(find_var(&im,im.gdes[im.gdes_c-1].vname) != -1) {
                im_free(&im);
                rrd_set_error("duplicate variable '%s'",
                              im.gdes[im.gdes_c-1].vname);
                return -1;
            }
            if((im.gdes[im.gdes_c-1].rpnp = str2rpn(&im,rpnex))== NULL) {
                rrd_set_error("invalid rpn expression '%s'", rpnex);
                im_free(&im);
                return -1;
            }
            free(rpnex);
            break;
        case GF_DEF:
            if (sscanf(
                        &argv[i][argstart],
                        DEF_NAM_FMT "=%n",
                        im.gdes[im.gdes_c-1].vname,
                        &strstart)== 1 && strstart) { /* is the = did not match %n returns 0 */
                if(sscanf(&argv[i][argstart
                                   +strstart
                                   +scan_for_col(&argv[i][argstart+strstart],
                                                 MAXPATH,im.gdes[im.gdes_c-1].rrd)],
                          ":" DS_NAM_FMT ":" CF_NAM_FMT,
                          im.gdes[im.gdes_c-1].ds_nam,
                          symname) != 2) {
                    im_free(&im);
                    rrd_set_error("can't parse DEF '%s' -2",&argv[i][argstart]);
                    return -1;
                }
            } else {
                im_free(&im);
                rrd_set_error("can't parse DEF '%s'",&argv[i][argstart]);
                return -1;
            }

            /* checking for duplicate DEF CDEFS */
            if (find_var(&im,im.gdes[im.gdes_c-1].vname) != -1) {
                im_free(&im);
                rrd_set_error("duplicate variable '%s'",
                              im.gdes[im.gdes_c-1].vname);
                return -1;
            }
            if((im.gdes[im.gdes_c-1].cf=cf_conv(symname))==-1) {
                im_free(&im);
                rrd_set_error("unknown cf '%s'",symname);
                return -1;
            }
            break;
        case GF_XPORT:
            if((scancount=sscanf(
                              &argv[i][argstart],
                              "%29[^:]:%n",
                              varname,
                              &strstart))>=1) {
                if(strstart <= 0) {
                    im.gdes[im.gdes_c-1].legend[0] = '\0';
                } else {
                    scan_for_col(&argv[i][argstart+strstart],FMT_LEG_LEN,im.gdes[im.gdes_c-1].legend);
                }
                if((im.gdes[im.gdes_c-1].vidx=find_var(&im,varname))==-1) {
                    im_free(&im);
                    rrd_set_error("unknown variable '%s'",varname);
                    return -1;
                }
            } else {
                im_free(&im);
                rrd_set_error("can't parse '%s'",&argv[i][argstart]);
                return -1;
            }
            break;
        default:
            break;
        }

    }

    if (im.gdes_c == 0) {
        rrd_set_error("can't make a graph without contents");
        im_free(&im);
        return(-1);
    }

    if (rrd_xport_fn(&im, start, end, step, col_cnt, legend_v, data) == -1) {
        im_free(&im);
        return -1;
    }

    im_free(&im);
    return 0;
}