1 /*****************************************************************************
2 * RRDtool 1.3.2 Copyright by Tobi Oetiker, 1997-2008
3 *****************************************************************************
4 * rrd_tool.c Startup wrapper
5 *****************************************************************************/
7 #if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__) && !defined(HAVE_CONFIG_H)
8 #include "../win32/config.h"
11 #include "../rrd_config.h"
16 #include "rrd_xport.h"
41 #define MAX_LENGTH 10000
48 const char *help_main =
50 " Copyright 1997-2008 by Tobias Oetiker <tobi@oetiker.ch>\n"
52 "Usage: rrdtool [options] command command_options\n\n");
54 const char *help_list =
56 ("Valid commands: create, update, updatev, graph, graphv, dump, restore,\n"
57 "\t\tlast, lastupdate, first, info, fetch, tune,\n"
58 "\t\tresize, xport, flush\n\n");
60 const char *help_listremote =
61 N_("Valid remote commands: quit, ls, cd, mkdir, pwd\n\n");
64 const char *help_create =
65 N_("* create - create a new RRD\n\n"
66 "\trrdtool create filename [--start|-b start time]\n"
67 "\t\t[--step|-s step]\n"
68 "\t\t[DS:ds-name:DST:dst arguments]\n"
69 "\t\t[RRA:CF:cf arguments]\n\n");
71 const char *help_dump =
72 N_("* dump - dump an RRD to XML\n\n"
73 "\trrdtool dump filename.rrd >filename.xml\n"
74 "\t\t[--header|-h {xsd,dtd}]\n\n");
76 const char *help_info =
77 N_("* info - returns the configuration and status of the RRD\n\n"
78 "\trrdtool info filename.rrd\n\n");
80 const char *help_restore =
81 N_("* restore - restore an RRD file from its XML form\n\n"
82 "\trrdtool restore [--range-check|-r] [--force-overwrite|-f] filename.xml filename.rrd\n\n");
84 const char *help_last =
85 N_("* last - show last update time for RRD\n\n"
86 "\trrdtool last filename.rrd\n\n");
88 const char *help_lastupdate =
89 N_("* lastupdate - returns the most recent datum stored for\n"
90 " each DS in an RRD\n\n" "\trrdtool lastupdate filename.rrd\n\n");
92 const char *help_first =
93 N_("* first - show first update time for RRA within an RRD\n\n"
94 "\trrdtool first filename.rrd [--rraindex number]\n\n");
96 const char *help_update =
97 N_("* update - update an RRD\n\n"
98 "\trrdtool update filename\n"
99 "\t\t[--template|-t ds-name:ds-name:...]\n"
100 "\t\t[--daemon <address>]\n"
101 "\t\ttime|N:value[:value...]\n\n"
102 "\t\tat-time@value[:value...]\n\n"
103 "\t\t[ time:value[:value...] ..]\n\n");
105 const char *help_updatev =
106 N_("* updatev - a verbose version of update\n"
107 "\treturns information about values, RRAs, and datasources updated\n\n"
108 "\trrdtool updatev filename\n"
109 "\t\t[--template|-t ds-name:ds-name:...]\n"
110 "\t\ttime|N:value[:value...]\n\n"
111 "\t\tat-time@value[:value...]\n\n"
112 "\t\t[ time:value[:value...] ..]\n\n");
114 const char *help_fetch =
115 N_("* fetch - fetch data out of an RRD\n\n"
116 "\trrdtool fetch filename.rrd CF\n"
117 "\t\t[-r|--resolution resolution]\n"
118 "\t\t[-s|--start start] [-e|--end end]\n"
119 "\t\t[--daemon <address>]\n\n");
121 const char *help_flush =
122 N_("* flush - flush cached data out to an RRD file\n\n"
123 "\trrdtool flush filename.rrd\n"
124 "\t\t[--daemon <address>]\n\n");
126 /* break up very large strings (help_graph, help_tune) for ISO C89 compliance*/
128 const char *help_graph0 =
129 N_("* graph - generate a graph from one or several RRD\n\n"
130 "\trrdtool graph filename [-s|--start seconds] [-e|--end seconds]\n");
131 const char *help_graphv0 =
132 N_("* graphv - generate a graph from one or several RRD\n"
133 " with meta data printed before the graph\n\n"
134 "\trrdtool graphv filename [-s|--start seconds] [-e|--end seconds]\n");
135 const char *help_graph1 =
136 N_("\t\t[-x|--x-grid x-axis grid and label]\n"
137 "\t\t[-Y|--alt-y-grid] [--full-size-mode]\n"
138 "\t\t[-y|--y-grid y-axis grid and label]\n"
139 "\t\t[-v|--vertical-label string] [-w|--width pixels]\n"
140 "\t\t[-h|--height pixels] [-o|--logarithmic]\n"
141 "\t\t[-u|--upper-limit value] [-z|--lazy]\n"
142 "\t\t[-l|--lower-limit value] [-r|--rigid]\n"
143 "\t\t[-g|--no-legend] [--daemon <address>]\n"
144 "\t\t[-F|--force-rules-legend]\n" "\t\t[-j|--only-graph]\n");
145 const char *help_graph2 =
146 N_("\t\t[-n|--font FONTTAG:size:font]\n"
147 "\t\t[-m|--zoom factor]\n"
148 "\t\t[-A|--alt-autoscale]\n"
149 "\t\t[-M|--alt-autoscale-max]\n"
150 "\t\t[-R|--font-render-mode {normal,light,mono}]\n"
151 "\t\t[-B|--font-smoothing-threshold size]\n"
152 "\t\t[-T|--tabwidth width]\n"
153 "\t\t[-E|--slope-mode]\n"
154 "\t\t[-N|--no-gridfit]\n"
155 "\t\t[-X|--units-exponent value]\n"
156 "\t\t[-L|--units-length value]\n"
157 "\t\t[-S|--step seconds]\n"
158 "\t\t[-f|--imginfo printfstr]\n"
159 "\t\t[-a|--imgformat PNG]\n"
160 "\t\t[-c|--color COLORTAG#rrggbb[aa]] [-t|--title string]\n"
161 "\t\t[-W|--watermark string]\n"
162 "\t\t[DEF:vname=rrd:ds-name:CF]\n");
163 const char *help_graph3 =
164 N_("\t\t[CDEF:vname=rpn-expression]\n"
165 "\t\t[VDEF:vdefname=rpn-expression]\n"
166 "\t\t[PRINT:vdefname:format]\n"
167 "\t\t[GPRINT:vdefname:format]\n" "\t\t[COMMENT:text]\n"
168 "\t\t[SHIFT:vname:offset]\n"
169 "\t\t[TICK:vname#rrggbb[aa][:[fraction][:legend]]]\n"
170 "\t\t[HRULE:value#rrggbb[aa][:legend]]\n"
171 "\t\t[VRULE:value#rrggbb[aa][:legend]]\n"
172 "\t\t[LINE[width]:vname[#rrggbb[aa][:[legend][:STACK]]]]\n"
173 "\t\t[AREA:vname[#rrggbb[aa][:[legend][:STACK]]]]\n"
174 "\t\t[PRINT:vname:CF:format] (deprecated)\n"
175 "\t\t[GPRINT:vname:CF:format] (deprecated)\n"
176 "\t\t[STACK:vname[#rrggbb[aa][:legend]]] (deprecated)\n\n");
177 const char *help_tune1 =
178 N_(" * tune - Modify some basic properties of an RRD\n\n"
179 "\trrdtool tune filename\n"
180 "\t\t[--heartbeat|-h ds-name:heartbeat]\n"
181 "\t\t[--data-source-type|-d ds-name:DST]\n"
182 "\t\t[--data-source-rename|-r old-name:new-name]\n"
183 "\t\t[--minimum|-i ds-name:min] [--maximum|-a ds-name:max]\n"
184 "\t\t[--deltapos scale-value] [--deltaneg scale-value]\n"
185 "\t\t[--failure-threshold integer]\n"
186 "\t\t[--window-length integer]\n"
187 "\t\t[--alpha adaptation-parameter]\n");
188 const char *help_tune2 =
189 N_(" * tune - Modify some basic properties of an RRD\n\n"
190 "\t\t[--beta adaptation-parameter]\n"
191 "\t\t[--gamma adaptation-parameter]\n"
192 "\t\t[--gamma-deviation adaptation-parameter]\n"
193 "\t\t[--aberrant-reset ds-name]\n\n");
194 const char *help_resize =
196 (" * resize - alter the length of one of the RRAs in an RRD\n\n"
197 "\trrdtool resize filename rranum GROW|SHRINK rows\n\n");
198 const char *help_xport =
199 N_("* xport - generate XML dump from one or several RRD\n\n"
200 "\trrdtool xport [-s|--start seconds] [-e|--end seconds]\n"
201 "\t\t[-m|--maxrows rows]\n" "\t\t[--step seconds]\n"
202 "\t\t[--enumds]\n" "\t\t[DEF:vname=rrd:ds-name:CF]\n"
203 "\t\t[CDEF:vname=rpn-expression]\n"
204 "\t\t[XPORT:vname:legend]\n\n");
205 const char *help_quit =
206 N_(" * quit - closing a session in remote mode\n\n"
207 "\trrdtool quit\n\n");
208 const char *help_ls =
209 N_(" * ls - lists all *.rrd files in current directory\n\n"
211 const char *help_cd =
212 N_(" * cd - changes the current directory\n\n"
213 "\trrdtool cd new directory\n\n");
214 const char *help_mkdir =
215 N_(" * mkdir - creates a new directory\n\n"
216 "\trrdtool mkdir newdirectoryname\n\n");
217 const char *help_pwd =
218 N_(" * pwd - returns the current working directory\n\n"
219 "\trrdtool pwd\n\n");
220 const char *help_lic =
221 N_("RRDtool is distributed under the Terms of the GNU General\n"
222 "Public License Version 2. (www.gnu.org/copyleft/gpl.html)\n\n"
223 "For more information read the RRD manpages\n\n");
224 enum { C_NONE, C_CREATE, C_DUMP, C_INFO, C_RESTORE, C_LAST,
225 C_LASTUPDATE, C_FIRST, C_UPDATE, C_FETCH, C_GRAPH, C_GRAPHV,
227 C_RESIZE, C_XPORT, C_QUIT, C_LS, C_CD, C_MKDIR, C_PWD,
230 int help_cmd = C_NONE;
233 if (!strcmp(cmd, "create"))
235 else if (!strcmp(cmd, "dump"))
237 else if (!strcmp(cmd, "info"))
239 else if (!strcmp(cmd, "restore"))
240 help_cmd = C_RESTORE;
241 else if (!strcmp(cmd, "last"))
243 else if (!strcmp(cmd, "lastupdate"))
244 help_cmd = C_LASTUPDATE;
245 else if (!strcmp(cmd, "first"))
247 else if (!strcmp(cmd, "update"))
249 else if (!strcmp(cmd, "updatev"))
250 help_cmd = C_UPDATEV;
251 else if (!strcmp(cmd, "fetch"))
253 else if (!strcmp(cmd, "flush"))
255 else if (!strcmp(cmd, "graph"))
257 else if (!strcmp(cmd, "graphv"))
259 else if (!strcmp(cmd, "tune"))
261 else if (!strcmp(cmd, "resize"))
263 else if (!strcmp(cmd, "xport"))
265 else if (!strcmp(cmd, "quit"))
267 else if (!strcmp(cmd, "ls"))
269 else if (!strcmp(cmd, "cd"))
271 else if (!strcmp(cmd, "mkdir"))
273 else if (!strcmp(cmd, "pwd"))
276 fprintf(stdout, _(help_main), PACKAGE_VERSION, __DATE__, __TIME__);
280 fputs(_(help_list), stdout);
282 fputs(_(help_listremote), stdout);
286 fputs(_(help_create), stdout);
289 fputs(_(help_dump), stdout);
292 fputs(_(help_info), stdout);
295 fputs(_(help_restore), stdout);
298 fputs(_(help_last), stdout);
301 fputs(_(help_lastupdate), stdout);
304 fputs(_(help_first), stdout);
307 fputs(_(help_update), stdout);
310 fputs(_(help_updatev), stdout);
313 fputs(_(help_fetch), stdout);
316 fputs(_(help_flush), stdout);
319 fputs(_(help_graph0), stdout);
320 fputs(_(help_graph1), stdout);
321 fputs(_(help_graph2), stdout);
322 fputs(_(help_graph3), stdout);
325 fputs(_(help_graphv0), stdout);
326 fputs(_(help_graph1), stdout);
327 fputs(_(help_graph2), stdout);
328 fputs(_(help_graph3), stdout);
331 fputs(_(help_tune1), stdout);
332 fputs(_(help_tune2), stdout);
335 fputs(_(help_resize), stdout);
338 fputs(_(help_xport), stdout);
341 fputs(_(help_quit), stdout);
344 fputs(_(help_ls), stdout);
347 fputs(_(help_cd), stdout);
350 fputs(_(help_mkdir), stdout);
353 fputs(_(help_pwd), stdout);
356 fputs(_(help_lic), stdout);
359 static char *fgetslong(
364 size_t bufsize = MAX_LENGTH;
368 return *aLinePtr = 0;
369 if (!(linebuf = malloc(bufsize))) {
370 perror("fgetslong: malloc");
374 while (fgets(linebuf + eolpos, MAX_LENGTH, stream)) {
375 eolpos += strlen(linebuf + eolpos);
376 if (linebuf[eolpos - 1] == '\n')
377 return *aLinePtr = linebuf;
378 bufsize += MAX_LENGTH;
379 if (!(linebuf = realloc(linebuf, bufsize))) {
381 perror("fgetslong: realloc");
386 return *aLinePtr = linebuf;
389 return *aLinePtr = 0;
400 #ifdef MUST_DISABLE_SIGFPE
401 signal(SIGFPE, SIG_IGN);
403 #ifdef MUST_DISABLE_FPMASK
407 setlocale(LC_ALL, "");
410 #if defined(HAVE_LIBINTL_H) && defined(BUILD_LIBINTL)
411 bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
412 bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
413 textdomain(GETTEXT_PACKAGE);
420 if (((argc == 2) || (argc == 3)) && !strcmp("-", argv[1])) {
422 struct rusage myusage;
423 struct timeval starttime;
424 struct timeval currenttime;
426 gettimeofday(&starttime, NULL);
429 if ((argc == 3) && strcmp("", argv[2])) {
440 if (chroot(argv[2]) != 0){
441 fprintf(stderr, "ERROR: chroot %s: %s\n", argv[2],rrd_strerror(errno));
448 "ERROR: change root is not supported by your OS "
449 "or at least by this copy of rrdtool\n");
456 if (strcmp(firstdir, "")) {
457 if (chdir(firstdir) != 0){
458 fprintf(stderr, "ERROR: chdir %s %s\n", firstdir,rrd_strerror(errno));
463 while (fgetslong(&aLine, stdin)) {
464 if ((argc = CountArgs(aLine)) == 0) {
466 printf("ERROR: not enough arguments\n");
468 if ((myargv = (char **) malloc((argc + 1) *
469 sizeof(char *))) == NULL) {
473 if ((argc = CreateArgs(argv[0], aLine, argc, myargv)) < 0) {
476 printf("ERROR: creating arguments\n");
478 int ret = HandleInputLine(argc, myargv, stdout);
483 getrusage(RUSAGE_SELF, &myusage);
484 gettimeofday(¤ttime, NULL);
485 printf("OK u:%1.2f s:%1.2f r:%1.2f\n",
486 (double) myusage.ru_utime.tv_sec +
487 (double) myusage.ru_utime.tv_usec / 1000000.0,
488 (double) myusage.ru_stime.tv_sec +
489 (double) myusage.ru_stime.tv_usec / 1000000.0,
490 (double) (currenttime.tv_sec - starttime.tv_sec)
491 + (double) (currenttime.tv_usec -
499 fflush(stdout); /* this is important for pipes to work */
502 } else if (argc == 2) {
505 } else if (argc == 3 && !strcmp(argv[1], "help")) {
509 exit(HandleInputLine(argc, argv, stderr));
514 /* HandleInputLine is NOT thread safe - due to readdir issues,
515 resolving them portably is not really simple. */
521 #if defined(HAVE_OPENDIR) && defined (HAVE_READDIR)
522 DIR *curdir; /* to read current dir with ls */
525 #if defined(HAVE_SYS_STAT_H)
528 char *cwd; /* To hold current working dir on call to pwd */
530 /* Reset errno to 0 before we start.
533 if (argc > 1 && strcmp("quit", argv[1]) == 0) {
535 printf("ERROR: invalid parameter count for quit\n");
540 #if defined(HAVE_OPENDIR) && defined(HAVE_READDIR) && defined(HAVE_CHDIR)
541 if (argc > 1 && strcmp("cd", argv[1]) == 0) {
543 printf("ERROR: invalid parameter count for cd\n");
546 #if ! defined(HAVE_CHROOT) || ! defined(HAVE_GETUID)
547 if (getuid() == 0 && !ChangeRoot) {
549 ("ERROR: chdir security problem - rrdtool is running as "
550 "root but not chroot!\n");
554 if (chdir(argv[2]) != 0){
555 printf("ERROR: chdir %s %s\n", argv[2], rrd_strerror(errno));
560 if (argc > 1 && strcmp("pwd", argv[1]) == 0) {
562 printf("ERROR: invalid parameter count for pwd\n");
565 cwd = getcwd(NULL, MAXPATH);
567 printf("ERROR: getcwd %s\n", rrd_strerror(errno));
574 if (argc > 1 && strcmp("mkdir", argv[1]) == 0) {
576 printf("ERROR: invalid parameter count for mkdir\n");
579 #if ! defined(HAVE_CHROOT) || ! defined(HAVE_GETUID)
580 if (getuid() == 0 && !ChangeRoot) {
582 ("ERROR: mkdir security problem - rrdtool is running as "
583 "root but not chroot!\n");
587 if(mkdir(argv[2], 0777)!=0){
588 printf("ERROR: mkdir %s: %s\n", argv[2],rrd_strerror(errno));
593 if (argc > 1 && strcmp("ls", argv[1]) == 0) {
595 printf("ERROR: invalid parameter count for ls\n");
598 if ((curdir = opendir(".")) != NULL) {
599 while ((dent = readdir(curdir)) != NULL) {
600 if (!stat(dent->d_name, &st)) {
601 if (S_ISDIR(st.st_mode)) {
602 printf("d %s\n", dent->d_name);
604 if (strlen(dent->d_name) > 4 && S_ISREG(st.st_mode)) {
606 (dent->d_name + NAMLEN(dent) - 4, ".rrd")
607 || !strcmp(dent->d_name + NAMLEN(dent) - 4,
609 printf("- %s\n", dent->d_name);
616 printf("ERROR: opendir .: %s\n", rrd_strerror(errno));
621 #endif /* opendir and readdir */
625 || strcmp("help", argv[1]) == 0
626 || strcmp("--help", argv[1]) == 0
627 || strcmp("-help", argv[1]) == 0
628 || strcmp("-?", argv[1]) == 0 || strcmp("-h", argv[1]) == 0) {
633 if (strcmp("create", argv[1]) == 0)
634 rrd_create(argc - 1, &argv[1]);
635 else if (strcmp("dump", argv[1]) == 0)
636 rrd_dump(argc - 1, &argv[1]);
637 else if (strcmp("info", argv[1]) == 0 || strcmp("updatev", argv[1]) == 0) {
640 if (strcmp("info", argv[1]) == 0)
642 data = rrd_info(argc - 1, &argv[1]);
644 data = rrd_update_v(argc - 1, &argv[1]);
645 rrd_info_print(data);
649 else if (strcmp("--version", argv[1]) == 0 ||
650 strcmp("version", argv[1]) == 0 ||
651 strcmp("v", argv[1]) == 0 ||
652 strcmp("-v", argv[1]) == 0 || strcmp("-version", argv[1]) == 0)
653 printf("RRDtool " PACKAGE_VERSION
654 " Copyright by Tobi Oetiker, 1997-2008 (%f)\n",
656 else if (strcmp("restore", argv[1]) == 0)
657 rrd_restore(argc - 1, &argv[1]);
658 else if (strcmp("resize", argv[1]) == 0)
659 rrd_resize(argc - 1, &argv[1]);
660 else if (strcmp("last", argv[1]) == 0)
661 printf("%ld\n", rrd_last(argc - 1, &argv[1]));
662 else if (strcmp("lastupdate", argv[1]) == 0) {
663 rrd_lastupdate(argc - 1, &argv[1]);
664 } else if (strcmp("first", argv[1]) == 0)
665 printf("%ld\n", rrd_first(argc - 1, &argv[1]));
666 else if (strcmp("update", argv[1]) == 0)
667 rrd_update(argc - 1, &argv[1]);
668 else if (strcmp("fetch", argv[1]) == 0) {
669 time_t start, end, ti;
670 unsigned long step, ds_cnt, i, ii;
671 rrd_value_t *data, *datai;
675 (argc - 1, &argv[1], &start, &end, &step, &ds_cnt, &ds_namv,
679 for (i = 0; i < ds_cnt; i++)
680 printf("%20s", ds_namv[i]);
682 for (ti = start + step; ti <= end; ti += step) {
683 printf("%10lu:", ti);
684 for (ii = 0; ii < ds_cnt; ii++)
685 printf(" %0.10e", *(datai++));
688 for (i = 0; i < ds_cnt; i++)
693 } else if (strcmp("xport", argv[1]) == 0) {
695 unsigned long int j = 0;
696 time_t start, end, ti;
697 unsigned long step, col_cnt, row_cnt;
698 rrd_value_t *data, *ptr;
702 size_t vtag_s = strlen(COL_DATA_TAG) + 10;
703 char *vtag = malloc(vtag_s);
705 for (i = 2; i < argc; i++) {
706 if (strcmp("--enumds", argv[i]) == 0)
711 (argc - 1, &argv[1], &xxsize, &start, &end, &step, &col_cnt,
712 &legend_v, &data) != -1) {
713 row_cnt = (end - start) / step;
715 printf("<?xml version=\"1.0\" encoding=\"%s\"?>\n\n",
717 printf("<%s>\n", ROOT_TAG);
718 printf(" <%s>\n", META_TAG);
719 printf(" <%s>%lu</%s>\n", META_START_TAG,
720 (unsigned long) start + step, META_START_TAG);
721 printf(" <%s>%lu</%s>\n", META_STEP_TAG, step, META_STEP_TAG);
722 printf(" <%s>%lu</%s>\n", META_END_TAG, (unsigned long) end,
724 printf(" <%s>%lu</%s>\n", META_ROWS_TAG, row_cnt,
726 printf(" <%s>%lu</%s>\n", META_COLS_TAG, col_cnt,
728 printf(" <%s>\n", LEGEND_TAG);
729 for (j = 0; j < col_cnt; j++) {
733 printf(" <%s>%s</%s>\n", LEGEND_ENTRY_TAG, entry,
738 printf(" </%s>\n", LEGEND_TAG);
739 printf(" </%s>\n", META_TAG);
740 printf(" <%s>\n", DATA_TAG);
741 for (ti = start + step; ti <= end; ti += step) {
742 printf(" <%s>", DATA_ROW_TAG);
743 printf("<%s>%lu</%s>", COL_TIME_TAG, ti, COL_TIME_TAG);
744 for (j = 0; j < col_cnt; j++) {
745 rrd_value_t newval = DNAN;
749 snprintf(vtag, vtag_s, "%s%lu", COL_DATA_TAG, j);
751 snprintf(vtag, vtag_s, "%s", COL_DATA_TAG);
754 printf("<%s>NaN</%s>", vtag, vtag);
756 printf("<%s>%0.10e</%s>", vtag, newval, vtag);
760 printf("</%s>\n", DATA_ROW_TAG);
763 printf(" </%s>\n", DATA_TAG);
764 printf("</%s>\n", ROOT_TAG);
767 } else if (strcmp("graph", argv[1]) == 0) {
770 #ifdef notused /*XXX*/
771 const char *imgfile = argv[2]; /* rrd_graph changes argv pointer */
776 int tostdout = (strcmp(argv[2], "-") == 0);
779 for (i = 2; i < argc; i++) {
780 if (strcmp(argv[i], "--imginfo") == 0
781 || strcmp(argv[i], "-f") == 0) {
787 (argc - 1, &argv[1], &calcpr, &xsize, &ysize, NULL, &ymin,
789 if (!tostdout && !imginfo)
790 printf("%dx%d\n", xsize, ysize);
792 for (i = 0; calcpr[i]; i++) {
794 printf("%s\n", calcpr[i]);
801 } else if (strcmp("graphv", argv[1]) == 0) {
802 rrd_info_t *grinfo = NULL; /* 1 to distinguish it from the NULL that rrd_graph sends in */
804 grinfo = rrd_graph_v(argc - 1, &argv[1]);
806 rrd_info_print(grinfo);
807 rrd_info_free(grinfo);
810 } else if (strcmp("tune", argv[1]) == 0)
811 rrd_tune(argc - 1, &argv[1]);
812 else if (strcmp("flush", argv[1]) == 0)
813 rrd_cmd_flush(argc - 1, &argv[1]);
815 rrd_set_error("unknown function '%s'", argv[1]);
817 if (rrd_test_error()) {
818 fprintf(out, "ERROR: %s\n", rrd_get_error());
832 while (aLine[i] == ' ')
834 while (aLine[i] != 0) {
835 if ((aLine[i] == ' ') && inarg) {
838 if ((aLine[i] != ' ') && !inarg) {
848 * CreateArgs - take a string (aLine) and tokenize
863 /* remove trailing space and newlines */
864 while (len && aLine[len] <= ' ') {
868 /* sikp leading blanks */
869 while (*aLine && *aLine <= ' ')
895 pargv[argc++] = putP;
903 pargv[argc++] = putP;