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"
13 #include "../rrd_config.h"
18 #include "rrd_xport.h"
43 #define MAX_LENGTH 10000
50 const char *help_main =
52 " Copyright 1997-2008 by Tobias Oetiker <tobi@oetiker.ch>\n"
54 "Usage: rrdtool [options] command command_options\n\n");
56 const char *help_list =
58 ("Valid commands: create, update, updatev, graph, graphv, dump, restore,\n"
59 "\t\tlast, lastupdate, first, info, fetch, tune,\n"
60 "\t\tresize, xport, flush\n\n");
62 const char *help_listremote =
63 N_("Valid remote commands: quit, ls, cd, mkdir, pwd\n\n");
66 const char *help_create =
67 N_("* create - create a new RRD\n\n"
68 "\trrdtool create filename [--start|-b start time]\n"
69 "\t\t[--step|-s step]\n"
70 "\t\t[DS:ds-name:DST:dst arguments]\n"
71 "\t\t[RRA:CF:cf arguments]\n\n");
73 const char *help_dump =
74 N_("* dump - dump an RRD to XML\n\n"
75 "\trrdtool dump filename.rrd >filename.xml\n\n");
77 const char *help_info =
78 N_("* info - returns the configuration and status of the RRD\n\n"
79 "\trrdtool info filename.rrd\n\n");
81 const char *help_restore =
82 N_("* restore - restore an RRD file from its XML form\n\n"
83 "\trrdtool restore [--range-check|-r] [--force-overwrite|-f] filename.xml filename.rrd\n\n");
85 const char *help_last =
86 N_("* last - show last update time for RRD\n\n"
87 "\trrdtool last filename.rrd\n\n");
89 const char *help_lastupdate =
90 N_("* lastupdate - returns the most recent datum stored for\n"
91 " each DS in an RRD\n\n" "\trrdtool lastupdate filename.rrd\n\n");
93 const char *help_first =
94 N_("* first - show first update time for RRA within an RRD\n\n"
95 "\trrdtool first filename.rrd [--rraindex number]\n\n");
97 const char *help_update =
98 N_("* update - update an RRD\n\n"
99 "\trrdtool update filename\n"
100 "\t\t[--template|-t ds-name:ds-name:...]\n"
101 "\t\t[--daemon <address>]\n"
102 "\t\ttime|N:value[:value...]\n\n"
103 "\t\tat-time@value[:value...]\n\n"
104 "\t\t[ time:value[:value...] ..]\n\n");
106 const char *help_updatev =
107 N_("* updatev - a verbose version of update\n"
108 "\treturns information about values, RRAs, and datasources updated\n\n"
109 "\trrdtool updatev filename\n"
110 "\t\t[--template|-t ds-name:ds-name:...]\n"
111 "\t\ttime|N:value[:value...]\n\n"
112 "\t\tat-time@value[:value...]\n\n"
113 "\t\t[ time:value[:value...] ..]\n\n");
115 const char *help_fetch =
116 N_("* fetch - fetch data out of an RRD\n\n"
117 "\trrdtool fetch filename.rrd CF\n"
118 "\t\t[-r|--resolution resolution]\n"
119 "\t\t[-s|--start start] [-e|--end end]\n"
120 "\t\t[--daemon <address>]\n\n");
122 const char *help_flush =
123 N_("* flush - flush cached data out to an RRD file\n\n"
124 "\trrdtool flush filename.rrd\n"
125 "\t\t[--daemon <address>]\n\n");
127 /* break up very large strings (help_graph, help_tune) for ISO C89 compliance*/
129 const char *help_graph0 =
130 N_("* graph - generate a graph from one or several RRD\n\n"
131 "\trrdtool graph filename [-s|--start seconds] [-e|--end seconds]\n");
132 const char *help_graphv0 =
133 N_("* graphv - generate a graph from one or several RRD\n"
134 " with meta data printed before the graph\n\n"
135 "\trrdtool graphv filename [-s|--start seconds] [-e|--end seconds]\n");
136 const char *help_graph1 =
137 N_("\t\t[-x|--x-grid x-axis grid and label]\n"
138 "\t\t[-Y|--alt-y-grid] [--full-size-mode]\n"
139 "\t\t[-y|--y-grid y-axis grid and label]\n"
140 "\t\t[-v|--vertical-label string] [-w|--width pixels]\n"
141 "\t\t[--right-axis scale:shift] [--right-axis-label label]\n"
142 "\t\t[--right-axis-format format]\n"
143 "\t\t[-h|--height pixels] [-o|--logarithmic]\n"
144 "\t\t[-u|--upper-limit value] [-z|--lazy]\n"
145 "\t\t[-l|--lower-limit value] [-r|--rigid]\n"
146 "\t\t[-g|--no-legend] [--daemon <address>]\n"
147 "\t\t[-F|--force-rules-legend]\n" "\t\t[-j|--only-graph]\n");
148 const char *help_graph2 =
149 N_("\t\t[-n|--font FONTTAG:size:font]\n"
150 "\t\t[-m|--zoom factor]\n"
151 "\t\t[-A|--alt-autoscale]\n"
152 "\t\t[-M|--alt-autoscale-max]\n"
153 "\t\t[-R|--font-render-mode {normal,light,mono}]\n"
154 "\t\t[-B|--font-smoothing-threshold size]\n"
155 "\t\t[-T|--tabwidth width]\n"
156 "\t\t[-E|--slope-mode]\n"
157 "\t\t[-N|--no-gridfit]\n"
158 "\t\t[-X|--units-exponent value]\n"
159 "\t\t[-L|--units-length value]\n"
160 "\t\t[-S|--step seconds]\n"
161 "\t\t[-f|--imginfo printfstr]\n"
162 "\t\t[-a|--imgformat PNG]\n"
163 "\t\t[-c|--color COLORTAG#rrggbb[aa]] [-t|--title string]\n"
164 "\t\t[-W|--watermark string]\n"
165 "\t\t[DEF:vname=rrd:ds-name:CF]\n");
166 const char *help_graph3 =
167 N_("\t\t[CDEF:vname=rpn-expression]\n"
168 "\t\t[VDEF:vdefname=rpn-expression]\n"
169 "\t\t[PRINT:vdefname:format]\n"
170 "\t\t[GPRINT:vdefname:format]\n" "\t\t[COMMENT:text]\n"
171 "\t\t[SHIFT:vname:offset]\n"
172 "\t\t[TICK:vname#rrggbb[aa][:[fraction][:legend]]]\n"
173 "\t\t[HRULE:value#rrggbb[aa][:legend]]\n"
174 "\t\t[VRULE:value#rrggbb[aa][:legend]]\n"
175 "\t\t[LINE[width]:vname[#rrggbb[aa][:[legend][:STACK]]]]\n"
176 "\t\t[AREA:vname[#rrggbb[aa][:[legend][:STACK]]]]\n"
177 "\t\t[PRINT:vname:CF:format] (deprecated)\n"
178 "\t\t[GPRINT:vname:CF:format] (deprecated)\n"
179 "\t\t[STACK:vname[#rrggbb[aa][:legend]]] (deprecated)\n\n");
180 const char *help_tune1 =
181 N_(" * tune - Modify some basic properties of an RRD\n\n"
182 "\trrdtool tune filename\n"
183 "\t\t[--heartbeat|-h ds-name:heartbeat]\n"
184 "\t\t[--data-source-type|-d ds-name:DST]\n"
185 "\t\t[--data-source-rename|-r old-name:new-name]\n"
186 "\t\t[--minimum|-i ds-name:min] [--maximum|-a ds-name:max]\n"
187 "\t\t[--deltapos scale-value] [--deltaneg scale-value]\n"
188 "\t\t[--failure-threshold integer]\n"
189 "\t\t[--window-length integer]\n"
190 "\t\t[--alpha adaptation-parameter]\n");
191 const char *help_tune2 =
192 N_(" * tune - Modify some basic properties of an RRD\n\n"
193 "\t\t[--beta adaptation-parameter]\n"
194 "\t\t[--gamma adaptation-parameter]\n"
195 "\t\t[--gamma-deviation adaptation-parameter]\n"
196 "\t\t[--aberrant-reset ds-name]\n\n");
197 const char *help_resize =
199 (" * resize - alter the length of one of the RRAs in an RRD\n\n"
200 "\trrdtool resize filename rranum GROW|SHRINK rows\n\n");
201 const char *help_xport =
202 N_("* xport - generate XML dump from one or several RRD\n\n"
203 "\trrdtool xport [-s|--start seconds] [-e|--end seconds]\n"
204 "\t\t[-m|--maxrows rows]\n" "\t\t[--step seconds]\n"
205 "\t\t[--enumds]\n" "\t\t[DEF:vname=rrd:ds-name:CF]\n"
206 "\t\t[CDEF:vname=rpn-expression]\n"
207 "\t\t[XPORT:vname:legend]\n\n");
208 const char *help_quit =
209 N_(" * quit - closing a session in remote mode\n\n"
210 "\trrdtool quit\n\n");
211 const char *help_ls =
212 N_(" * ls - lists all *.rrd files in current directory\n\n"
214 const char *help_cd =
215 N_(" * cd - changes the current directory\n\n"
216 "\trrdtool cd new directory\n\n");
217 const char *help_mkdir =
218 N_(" * mkdir - creates a new directory\n\n"
219 "\trrdtool mkdir newdirectoryname\n\n");
220 const char *help_pwd =
221 N_(" * pwd - returns the current working directory\n\n"
222 "\trrdtool pwd\n\n");
223 const char *help_lic =
224 N_("RRDtool is distributed under the Terms of the GNU General\n"
225 "Public License Version 2. (www.gnu.org/copyleft/gpl.html)\n\n"
226 "For more information read the RRD manpages\n\n");
227 enum { C_NONE, C_CREATE, C_DUMP, C_INFO, C_RESTORE, C_LAST,
228 C_LASTUPDATE, C_FIRST, C_UPDATE, C_FETCH, C_GRAPH, C_GRAPHV,
230 C_RESIZE, C_XPORT, C_QUIT, C_LS, C_CD, C_MKDIR, C_PWD,
233 int help_cmd = C_NONE;
236 if (!strcmp(cmd, "create"))
238 else if (!strcmp(cmd, "dump"))
240 else if (!strcmp(cmd, "info"))
242 else if (!strcmp(cmd, "restore"))
243 help_cmd = C_RESTORE;
244 else if (!strcmp(cmd, "last"))
246 else if (!strcmp(cmd, "lastupdate"))
247 help_cmd = C_LASTUPDATE;
248 else if (!strcmp(cmd, "first"))
250 else if (!strcmp(cmd, "update"))
252 else if (!strcmp(cmd, "updatev"))
253 help_cmd = C_UPDATEV;
254 else if (!strcmp(cmd, "fetch"))
256 else if (!strcmp(cmd, "flush"))
258 else if (!strcmp(cmd, "graph"))
260 else if (!strcmp(cmd, "graphv"))
262 else if (!strcmp(cmd, "tune"))
264 else if (!strcmp(cmd, "resize"))
266 else if (!strcmp(cmd, "xport"))
268 else if (!strcmp(cmd, "quit"))
270 else if (!strcmp(cmd, "ls"))
272 else if (!strcmp(cmd, "cd"))
274 else if (!strcmp(cmd, "mkdir"))
276 else if (!strcmp(cmd, "pwd"))
279 fprintf(stdout, _(help_main), PACKAGE_VERSION, __DATE__, __TIME__);
283 fputs(_(help_list), stdout);
285 fputs(_(help_listremote), stdout);
289 fputs(_(help_create), stdout);
292 fputs(_(help_dump), stdout);
295 fputs(_(help_info), stdout);
298 fputs(_(help_restore), stdout);
301 fputs(_(help_last), stdout);
304 fputs(_(help_lastupdate), stdout);
307 fputs(_(help_first), stdout);
310 fputs(_(help_update), stdout);
313 fputs(_(help_updatev), stdout);
316 fputs(_(help_fetch), stdout);
319 fputs(_(help_flush), stdout);
322 fputs(_(help_graph0), stdout);
323 fputs(_(help_graph1), stdout);
324 fputs(_(help_graph2), stdout);
325 fputs(_(help_graph3), stdout);
328 fputs(_(help_graphv0), stdout);
329 fputs(_(help_graph1), stdout);
330 fputs(_(help_graph2), stdout);
331 fputs(_(help_graph3), stdout);
334 fputs(_(help_tune1), stdout);
335 fputs(_(help_tune2), stdout);
338 fputs(_(help_resize), stdout);
341 fputs(_(help_xport), stdout);
344 fputs(_(help_quit), stdout);
347 fputs(_(help_ls), stdout);
350 fputs(_(help_cd), stdout);
353 fputs(_(help_mkdir), stdout);
356 fputs(_(help_pwd), stdout);
359 fputs(_(help_lic), stdout);
362 static char *fgetslong(
367 size_t bufsize = MAX_LENGTH;
371 return *aLinePtr = 0;
372 if (!(linebuf = malloc(bufsize))) {
373 perror("fgetslong: malloc");
377 while (fgets(linebuf + eolpos, MAX_LENGTH, stream)) {
378 eolpos += strlen(linebuf + eolpos);
379 if (linebuf[eolpos - 1] == '\n')
380 return *aLinePtr = linebuf;
381 bufsize += MAX_LENGTH;
382 if (!(linebuf = realloc(linebuf, bufsize))) {
384 perror("fgetslong: realloc");
389 return *aLinePtr = linebuf;
392 return *aLinePtr = 0;
403 #ifdef MUST_DISABLE_SIGFPE
404 signal(SIGFPE, SIG_IGN);
406 #ifdef MUST_DISABLE_FPMASK
410 setlocale(LC_ALL, "");
413 #if defined(HAVE_LIBINTL_H) && defined(BUILD_LIBINTL)
414 bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
415 bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
416 textdomain(GETTEXT_PACKAGE);
423 if (((argc == 2) || (argc == 3)) && !strcmp("-", argv[1])) {
425 struct rusage myusage;
426 struct timeval starttime;
427 struct timeval currenttime;
429 gettimeofday(&starttime, NULL);
432 if ((argc == 3) && strcmp("", argv[2])) {
443 if (chroot(argv[2]) != 0){
444 fprintf(stderr, "ERROR: chroot %s: %s\n", argv[2],rrd_strerror(errno));
451 "ERROR: change root is not supported by your OS "
452 "or at least by this copy of rrdtool\n");
459 if (strcmp(firstdir, "")) {
460 if (chdir(firstdir) != 0){
461 fprintf(stderr, "ERROR: chdir %s %s\n", firstdir,rrd_strerror(errno));
466 while (fgetslong(&aLine, stdin)) {
467 if ((argc = CountArgs(aLine)) == 0) {
469 printf("ERROR: not enough arguments\n");
471 if ((myargv = (char **) malloc((argc + 1) *
472 sizeof(char *))) == NULL) {
476 if ((argc = CreateArgs(argv[0], aLine, argc, myargv)) < 0) {
479 printf("ERROR: creating arguments\n");
481 int ret = HandleInputLine(argc, myargv, stdout);
486 getrusage(RUSAGE_SELF, &myusage);
487 gettimeofday(¤ttime, NULL);
488 printf("OK u:%1.2f s:%1.2f r:%1.2f\n",
489 (double) myusage.ru_utime.tv_sec +
490 (double) myusage.ru_utime.tv_usec / 1000000.0,
491 (double) myusage.ru_stime.tv_sec +
492 (double) myusage.ru_stime.tv_usec / 1000000.0,
493 (double) (currenttime.tv_sec - starttime.tv_sec)
494 + (double) (currenttime.tv_usec -
502 fflush(stdout); /* this is important for pipes to work */
505 } else if (argc == 2) {
508 } else if (argc == 3 && !strcmp(argv[1], "help")) {
512 exit(HandleInputLine(argc, argv, stderr));
517 /* HandleInputLine is NOT thread safe - due to readdir issues,
518 resolving them portably is not really simple. */
524 #if defined(HAVE_OPENDIR) && defined (HAVE_READDIR)
525 DIR *curdir; /* to read current dir with ls */
528 #if defined(HAVE_SYS_STAT_H)
531 char *cwd; /* To hold current working dir on call to pwd */
533 /* Reset errno to 0 before we start.
536 if (argc > 1 && strcmp("quit", argv[1]) == 0) {
538 printf("ERROR: invalid parameter count for quit\n");
543 #if defined(HAVE_OPENDIR) && defined(HAVE_READDIR) && defined(HAVE_CHDIR)
544 if (argc > 1 && strcmp("cd", argv[1]) == 0) {
546 printf("ERROR: invalid parameter count for cd\n");
549 #if ! defined(HAVE_CHROOT) || ! defined(HAVE_GETUID)
550 if (getuid() == 0 && !ChangeRoot) {
552 ("ERROR: chdir security problem - rrdtool is running as "
553 "root but not chroot!\n");
557 if (chdir(argv[2]) != 0){
558 printf("ERROR: chdir %s %s\n", argv[2], rrd_strerror(errno));
563 if (argc > 1 && strcmp("pwd", argv[1]) == 0) {
565 printf("ERROR: invalid parameter count for pwd\n");
568 cwd = getcwd(NULL, MAXPATH);
570 printf("ERROR: getcwd %s\n", rrd_strerror(errno));
577 if (argc > 1 && strcmp("mkdir", argv[1]) == 0) {
579 printf("ERROR: invalid parameter count for mkdir\n");
582 #if ! defined(HAVE_CHROOT) || ! defined(HAVE_GETUID)
583 if (getuid() == 0 && !ChangeRoot) {
585 ("ERROR: mkdir security problem - rrdtool is running as "
586 "root but not chroot!\n");
590 if(mkdir(argv[2], 0777)!=0){
591 printf("ERROR: mkdir %s: %s\n", argv[2],rrd_strerror(errno));
596 if (argc > 1 && strcmp("ls", argv[1]) == 0) {
598 printf("ERROR: invalid parameter count for ls\n");
601 if ((curdir = opendir(".")) != NULL) {
602 while ((dent = readdir(curdir)) != NULL) {
603 if (!stat(dent->d_name, &st)) {
604 if (S_ISDIR(st.st_mode)) {
605 printf("d %s\n", dent->d_name);
607 if (strlen(dent->d_name) > 4 && S_ISREG(st.st_mode)) {
609 (dent->d_name + NAMLEN(dent) - 4, ".rrd")
610 || !strcmp(dent->d_name + NAMLEN(dent) - 4,
612 printf("- %s\n", dent->d_name);
619 printf("ERROR: opendir .: %s\n", rrd_strerror(errno));
624 #endif /* opendir and readdir */
628 || strcmp("help", argv[1]) == 0
629 || strcmp("--help", argv[1]) == 0
630 || strcmp("-help", argv[1]) == 0
631 || strcmp("-?", argv[1]) == 0 || strcmp("-h", argv[1]) == 0) {
636 if (strcmp("create", argv[1]) == 0)
637 rrd_create(argc - 1, &argv[1]);
638 else if (strcmp("dump", argv[1]) == 0)
639 rrd_dump(argc - 1, &argv[1]);
640 else if (strcmp("info", argv[1]) == 0 || strcmp("updatev", argv[1]) == 0) {
643 if (strcmp("info", argv[1]) == 0)
645 data = rrd_info(argc - 1, &argv[1]);
647 data = rrd_update_v(argc - 1, &argv[1]);
648 rrd_info_print(data);
652 else if (strcmp("--version", argv[1]) == 0 ||
653 strcmp("version", argv[1]) == 0 ||
654 strcmp("v", argv[1]) == 0 ||
655 strcmp("-v", argv[1]) == 0 || strcmp("-version", argv[1]) == 0)
656 printf("RRDtool " PACKAGE_VERSION
657 " Copyright by Tobi Oetiker, 1997-2008 (%f)\n",
659 else if (strcmp("restore", argv[1]) == 0)
660 rrd_restore(argc - 1, &argv[1]);
661 else if (strcmp("resize", argv[1]) == 0)
662 rrd_resize(argc - 1, &argv[1]);
663 else if (strcmp("last", argv[1]) == 0)
664 printf("%ld\n", rrd_last(argc - 1, &argv[1]));
665 else if (strcmp("lastupdate", argv[1]) == 0) {
666 rrd_lastupdate(argc - 1, &argv[1]);
667 } else if (strcmp("first", argv[1]) == 0)
668 printf("%ld\n", rrd_first(argc - 1, &argv[1]));
669 else if (strcmp("update", argv[1]) == 0)
670 rrd_update(argc - 1, &argv[1]);
671 else if (strcmp("fetch", argv[1]) == 0) {
672 time_t start, end, ti;
673 unsigned long step, ds_cnt, i, ii;
674 rrd_value_t *data, *datai;
678 (argc - 1, &argv[1], &start, &end, &step, &ds_cnt, &ds_namv,
682 for (i = 0; i < ds_cnt; i++)
683 printf("%20s", ds_namv[i]);
685 for (ti = start + step; ti <= end; ti += step) {
686 printf("%10lu:", ti);
687 for (ii = 0; ii < ds_cnt; ii++)
688 printf(" %0.10e", *(datai++));
691 for (i = 0; i < ds_cnt; i++)
696 } else if (strcmp("xport", argv[1]) == 0) {
698 unsigned long int j = 0;
699 time_t start, end, ti;
700 unsigned long step, col_cnt, row_cnt;
701 rrd_value_t *data, *ptr;
705 size_t vtag_s = strlen(COL_DATA_TAG) + 10;
706 char *vtag = malloc(vtag_s);
708 for (i = 2; i < argc; i++) {
709 if (strcmp("--enumds", argv[i]) == 0)
714 (argc - 1, &argv[1], &xxsize, &start, &end, &step, &col_cnt,
715 &legend_v, &data) != -1) {
716 row_cnt = (end - start) / step;
718 printf("<?xml version=\"1.0\" encoding=\"%s\"?>\n\n",
720 printf("<%s>\n", ROOT_TAG);
721 printf(" <%s>\n", META_TAG);
722 printf(" <%s>%lu</%s>\n", META_START_TAG,
723 (unsigned long) start + step, META_START_TAG);
724 printf(" <%s>%lu</%s>\n", META_STEP_TAG, step, META_STEP_TAG);
725 printf(" <%s>%lu</%s>\n", META_END_TAG, (unsigned long) end,
727 printf(" <%s>%lu</%s>\n", META_ROWS_TAG, row_cnt,
729 printf(" <%s>%lu</%s>\n", META_COLS_TAG, col_cnt,
731 printf(" <%s>\n", LEGEND_TAG);
732 for (j = 0; j < col_cnt; j++) {
736 printf(" <%s>%s</%s>\n", LEGEND_ENTRY_TAG, entry,
741 printf(" </%s>\n", LEGEND_TAG);
742 printf(" </%s>\n", META_TAG);
743 printf(" <%s>\n", DATA_TAG);
744 for (ti = start + step; ti <= end; ti += step) {
745 printf(" <%s>", DATA_ROW_TAG);
746 printf("<%s>%lu</%s>", COL_TIME_TAG, ti, COL_TIME_TAG);
747 for (j = 0; j < col_cnt; j++) {
748 rrd_value_t newval = DNAN;
752 snprintf(vtag, vtag_s, "%s%lu", COL_DATA_TAG, j);
754 snprintf(vtag, vtag_s, "%s", COL_DATA_TAG);
757 printf("<%s>NaN</%s>", vtag, vtag);
759 printf("<%s>%0.10e</%s>", vtag, newval, vtag);
763 printf("</%s>\n", DATA_ROW_TAG);
766 printf(" </%s>\n", DATA_TAG);
767 printf("</%s>\n", ROOT_TAG);
770 } else if (strcmp("graph", argv[1]) == 0) {
773 #ifdef notused /*XXX*/
774 const char *imgfile = argv[2]; /* rrd_graph changes argv pointer */
779 int tostdout = (strcmp(argv[2], "-") == 0);
782 for (i = 2; i < argc; i++) {
783 if (strcmp(argv[i], "--imginfo") == 0
784 || strcmp(argv[i], "-f") == 0) {
790 (argc - 1, &argv[1], &calcpr, &xsize, &ysize, NULL, &ymin,
792 if (!tostdout && !imginfo)
793 printf("%dx%d\n", xsize, ysize);
795 for (i = 0; calcpr[i]; i++) {
797 printf("%s\n", calcpr[i]);
804 } else if (strcmp("graphv", argv[1]) == 0) {
805 rrd_info_t *grinfo = NULL; /* 1 to distinguish it from the NULL that rrd_graph sends in */
807 grinfo = rrd_graph_v(argc - 1, &argv[1]);
809 rrd_info_print(grinfo);
810 rrd_info_free(grinfo);
813 } else if (strcmp("tune", argv[1]) == 0)
814 rrd_tune(argc - 1, &argv[1]);
815 else if (strcmp("flush", argv[1]) == 0)
816 rrd_cmd_flush(argc - 1, &argv[1]);
818 rrd_set_error("unknown function '%s'", argv[1]);
820 if (rrd_test_error()) {
821 fprintf(out, "ERROR: %s\n", rrd_get_error());
835 while (aLine[i] == ' ')
837 while (aLine[i] != 0) {
838 if ((aLine[i] == ' ') && inarg) {
841 if ((aLine[i] != ' ') && !inarg) {
851 * CreateArgs - take a string (aLine) and tokenize
866 /* remove trailing space and newlines */
867 while (len && aLine[len] <= ' ') {
871 /* sikp leading blanks */
872 while (*aLine && *aLine <= ' ')
898 pargv[argc++] = putP;
906 pargv[argc++] = putP;