int rrd_parse_find_gf(char *line, unsigned int *eaten, graph_desc_t *gdp) { char funcname[11],c1=0; int i=0; /* start an argument with DEBUG to be able to see how it is parsed */ sscanf(&line[*eaten], "DEBUG%n", &i); if (i) { gdp->debug=1; (*eaten)+=i; i=0; dprintf("Scanning line '%s'\n",&line[*eaten]); } sscanf(&line[*eaten], "%10[A-Z]%n%c", funcname, &i, &c1); if (!i) { rrd_set_error("Could not make sense out of '%s'",line); return 1; } if ((int)(gdp->gf=gf_conv(funcname)) == -1) { rrd_set_error("'%s' is not a valid function name", funcname); return 1; } else { dprintf("- found function name '%s'\n",funcname); } if (gdp->gf == GF_LINE) { if (c1 == ':') { gdp->linewidth=1; dprintf("- - using default width of 1\n"); } else { double width; (*eaten)+=i; if (sscanf(&line[*eaten],"%lf%n:",&width,&i)) { if (width < 0 || isnan(width) || isinf(width) ) { rrd_set_error("LINE width is %lf. It must be finite and >= 0 though",width); return 1; } gdp->linewidth=width; dprintf("- - using width %f\n",width); } else { rrd_set_error("LINE width: %s",line); return 1; } } } else { if (c1 != ':') { rrd_set_error("Malformed %s command: %s",funcname,line); return 1; } } (*eaten)+=++i; return 0; }
void rrd_graph_script( int argc, char *argv[], image_desc_t *const im, int optno) { int i; /* and now handle the things*/ parsedargs_t pa; initParsedArguments(&pa); /* loop arguments */ for (i = optno; i < argc; i++) { /* release parsed args - avoiding late cleanups*/ freeParsedArguments(&pa); /* processed parsed args */ if (parseArguments(argv[i],&pa)) { return; } /* dumpArguments(&pa); */ /* now let us handle the field based on the first command or cmd=...*/ char*cmd=NULL; /* and try to get via cmd */ char* t=getKeyValueArgument("cmd",255,&pa); if (t) { cmd=t; } else if ((t=getKeyValueArgument("pos0",255,&pa))) { cmd=t; } else { rrd_set_error("no command set in argument %s",pa.arg_orig); freeParsedArguments(&pa); return; } /* convert to enum but handling LINE special*/ enum gf_en gf = (enum gf_en) -1; gf=gf_conv(cmd); if ((int)gf == -1) { if (strncmp("LINE",cmd,4)==0) { gf=GF_LINE; addToArguments(&pa,NULL,"linewidth",cmd+4,0); } else { rrd_set_error("'%s' is not a valid function name in %s", cmd,pa.arg_orig ); return; } } /* now we can handle the commands */ int r=0; switch (gf) { case GF_XAXIS: r=parse_axis(gf,&pa,im); break; case GF_YAXIS: r=parse_axis(gf,&pa,im); break; case GF_DEF: r=parse_def(gf,&pa,im); break; case GF_CDEF: r=parse_cvdef(gf,&pa,im); break; case GF_VDEF: r=parse_cvdef(gf,&pa,im); break; case GF_LINE: r=parse_line(gf,&pa,im); break; case GF_AREA: r=parse_area(gf,&pa,im); break; case GF_PRINT: r=parse_gprint(gf,&pa,im); break; case GF_GPRINT: r=parse_gprint(gf,&pa,im); break; case GF_COMMENT: r=parse_comment(gf,&pa,im); break; case GF_HRULE: r=parse_hvrule(gf,&pa,im); break; case GF_VRULE: r=parse_hvrule(gf,&pa,im); break; case GF_STACK: r=parse_stack(gf,&pa,im); break; case GF_TICK: r=parse_tick(gf,&pa,im); break; case GF_TEXTALIGN: r=parse_textalign(gf,&pa,im); break; case GF_SHIFT: r=parse_shift(gf,&pa,im); break; case GF_XPORT: r=parse_xport(gf,&pa,im); break; /* unsupported types right now */ } /* handle the return error case */ if (r) { freeParsedArguments(&pa); return;} /* check for unprocessed keyvalue args */ char *s; if ((s=checkUnusedValues(&pa))) { /* set error message */ rrd_set_error("Unused Arguments \"%s\" in command : %s",s,pa.arg_orig); free(s); /* exit early */ freeParsedArguments(&pa); return; } } /* finally free arguments */ freeParsedArguments(&pa); }
/* 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; }