+ 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;
+}
+
+int
+rrd_parse_vdef(char *line, unsigned int *eaten, graph_desc_t *gdp, image_desc_t *im) {
+ char tmpstr[MAX_VNAME_LEN+1]; /* vname\0 */
+ int i=0;
+
+ dprintf("- parsing '%s'\n",&line[*eaten]);
+ if (rrd_parse_vname(line,eaten,gdp,im)) return 1;
+
+ sscanf(&line[*eaten], DEF_NAM_FMT ",%n", tmpstr,&i);
+ if (!i) {
+ rrd_set_error("Cannot parse line '%s'",line);
+ return 1;
+ }
+ if ((gdp->vidx=find_var(im,tmpstr))<0) {
+ rrd_set_error("Not a valid vname: %s in line %s",tmpstr,line);
+ return 1;
+ }
+ if ( im->gdes[gdp->vidx].gf != GF_DEF
+ && im->gdes[gdp->vidx].gf != GF_CDEF) {
+ rrd_set_error("variable '%s' not DEF nor "
+ "CDEF in VDEF '%s'", tmpstr,gdp->vname);
+ return 1;
+ }
+ dprintf("- found vname: '%s' vidx %li\n",tmpstr,gdp->vidx);
+ (*eaten)+=i;
+
+ dprintf("- calling vdef_parse with param '%s'\n",&line[*eaten]);
+ vdef_parse(gdp,&line[*eaten]);
+ while (line[*eaten]!='\0'&&line[*eaten]!=':')
+ (*eaten)++;
+
+ return 0;
+}
+
+int
+rrd_parse_cdef(char *line, unsigned int *eaten, graph_desc_t *gdp, image_desc_t *im) {
+ dprintf("- parsing '%s'\n",&line[*eaten]);
+ if (rrd_parse_vname(line,eaten,gdp,im)) return 1;
+ if ((gdp->rpnp = rpn_parse(
+ (void *)im,
+ &line[*eaten],
+ &find_var_wrapper)
+ )==NULL) {
+ rrd_set_error("invalid rpn expression in: %s",&line[*eaten]);
+ return 1;
+ };
+ while (line[*eaten]!='\0'&&line[*eaten]!=':')
+ (*eaten)++;
+ return 0;
+}
+
+void
+rrd_graph_script(int argc, char *argv[], image_desc_t *im, int optno) {
+ int i;
+
+ for (i=optind+optno;i<argc;i++) {
+ graph_desc_t *gdp;
+ unsigned int eaten=0;
+
+ if (gdes_alloc(im)) return; /* the error string is already set */
+ gdp = &im->gdes[im->gdes_c-1];
+#ifdef DEBUG
+ gdp->debug = 1;
+#endif
+
+ if (rrd_parse_find_gf(argv[i],&eaten,gdp)) return;
+
+ switch (gdp->gf) {
+ case GF_SHIFT: /* vname:value */
+ if (rrd_parse_shift(argv[i],&eaten,gdp,im)) return;
+ break;
+ case GF_XPORT:
+ if (rrd_parse_xport(argv[i],&eaten,gdp,im)) return;
+ break;
+ case GF_PRINT: /* vname:CF:format -or- vname:format */
+ case GF_GPRINT: /* vname:CF:format -or- vname:format */
+ if (rrd_parse_print(argv[i],&eaten,gdp,im)) return;
+ break;
+ case GF_COMMENT: /* text */
+ if (rrd_parse_legend(argv[i],&eaten,gdp)) return;
+ break;
+#ifdef WITH_PIECHART
+ case GF_PART: /* value[#color[:legend]] */
+#endif
+ case GF_VRULE: /* value#color[:legend] */
+ case GF_HRULE: /* value#color[:legend] */
+ case GF_LINE: /* vname-or-value[#color[:legend]][:STACK] */
+ case GF_AREA: /* vname-or-value[#color[:legend]][:STACK] */
+ case GF_STACK: /* vname-or-value[#color[:legend]] */
+ case GF_TICK: /* vname#color[:num[:legend]] */
+ if (rrd_parse_PVHLAST(argv[i],&eaten,gdp,im)) return;
+ break;
+ /* data acquisition */
+ case GF_DEF: /* vname=x:DS:CF:[:step=#][:start=#][:end=#] */
+ if (rrd_parse_def(argv[i],&eaten,gdp,im)) return;
+ break;
+ case GF_CDEF: /* vname=rpn-expression */
+ if (rrd_parse_cdef(argv[i],&eaten,gdp,im)) return;
+ break;
+ case GF_VDEF: /* vname=rpn-expression */
+ if (rrd_parse_vdef(argv[i],&eaten,gdp,im)) return;
+ break;
+ }
+ if (gdp->debug) {
+ dprintf("used %i out of %i chars\n",eaten,strlen(argv[i]));
+ dprintf("parsed line: '%s'\n",argv[i]);
+ dprintf("remaining: '%s'\n",&argv[i][eaten]);
+ if (eaten >= strlen(argv[i]))
+ dprintf("Command finished successfully\n");
+ }
+ if (eaten < strlen(argv[i])) {
+ rrd_set_error("Garbage '%s' after command:\n%s",
+ &argv[i][eaten],argv[i]);
+ return;
+ }
+ }
+}