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\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\n");
75 const char *help_info =
76 N_("* info - returns the configuration and status of the RRD\n\n"
77 "\trrdtool info filename.rrd\n\n");
79 const char *help_restore =
80 N_("* restore - restore an RRD file from its XML form\n\n"
81 "\trrdtool restore [--range-check|-r] [--force-overwrite|-f] filename.xml filename.rrd\n\n");
83 const char *help_last =
84 N_("* last - show last update time for RRD\n\n"
85 "\trrdtool last filename.rrd\n\n");
87 const char *help_lastupdate =
88 N_("* lastupdate - returns the most recent datum stored for\n"
89 " each DS in an RRD\n\n" "\trrdtool lastupdate filename.rrd\n\n");
91 const char *help_first =
92 N_("* first - show first update time for RRA within an RRD\n\n"
93 "\trrdtool first filename.rrd [--rraindex number]\n\n");
95 const char *help_update =
96 N_("* update - update an RRD\n\n"
97 "\trrdtool update filename\n"
98 "\t\t--template|-t ds-name:ds-name:...\n"
99 "\t\ttime|N:value[:value...]\n\n"
100 "\t\tat-time@value[:value...]\n\n"
101 "\t\t[ time:value[:value...] ..]\n\n");
103 const char *help_updatev =
104 N_("* updatev - a verbose version of update\n"
105 "\treturns information about values, RRAs, and datasources updated\n\n"
106 "\trrdtool updatev filename\n"
107 "\t\t--template|-t ds-name:ds-name:...\n"
108 "\t\ttime|N:value[:value...]\n\n"
109 "\t\tat-time@value[:value...]\n\n"
110 "\t\t[ time:value[:value...] ..]\n\n");
112 const char *help_fetch =
113 N_("* fetch - fetch data out of an RRD\n\n"
114 "\trrdtool fetch filename.rrd CF\n"
115 "\t\t[-r|--resolution resolution]\n"
116 "\t\t[-s|--start start] [-e|--end end]\n\n");
118 /* break up very large strings (help_graph, help_tune) for ISO C89 compliance*/
120 const char *help_graph0 =
121 N_("* graph - generate a graph from one or several RRD\n\n"
122 "\trrdtool graph filename [-s|--start seconds] [-e|--end seconds]\n");
123 const char *help_graphv0 =
124 N_("* graphv - generate a graph from one or several RRD\n"
125 " with meta data printed before the graph\n\n"
126 "\trrdtool graphv filename [-s|--start seconds] [-e|--end seconds]\n");
127 const char *help_graph1 =
128 N_("\t\t[-x|--x-grid x-axis grid and label]\n"
129 "\t\t[-Y|--alt-y-grid]\n"
130 "\t\t[-y|--y-grid y-axis grid and label]\n"
131 "\t\t[-v|--vertical-label string] [-w|--width pixels]\n"
132 "\t\t[-h|--height pixels] [-o|--logarithmic]\n"
133 "\t\t[-u|--upper-limit value] [-z|--lazy]\n"
134 "\t\t[-l|--lower-limit value] [-r|--rigid]\n"
135 "\t\t[-g|--no-legend]\n"
136 "\t\t[-F|--force-rules-legend]\n" "\t\t[-j|--only-graph]\n");
137 const char *help_graph2 =
138 N_("\t\t[-n|--font FONTTAG:size:font]\n"
139 "\t\t[-m|--zoom factor]\n"
140 "\t\t[-A|--alt-autoscale]\n"
141 "\t\t[-M|--alt-autoscale-max]\n"
142 "\t\t[-R|--font-render-mode {normal,light,mono}]\n"
143 "\t\t[-B|--font-smoothing-threshold size]\n"
144 "\t\t[-T|--tabwidth width]\n"
145 "\t\t[-E|--slope-mode]\n"
146 "\t\t[-N|--no-gridfit]\n"
147 "\t\t[-X|--units-exponent value]\n"
148 "\t\t[-L|--units-length value]\n"
149 "\t\t[-S|--step seconds]\n"
150 "\t\t[-f|--imginfo printfstr]\n"
151 "\t\t[-a|--imgformat PNG]\n"
152 "\t\t[-c|--color COLORTAG#rrggbb[aa]] [-t|--title string]\n"
153 "\t\t[-W|--watermark string]\n"
154 "\t\t[DEF:vname=rrd:ds-name:CF]\n");
155 const char *help_graph3 =
156 N_("\t\t[CDEF:vname=rpn-expression]\n"
157 "\t\t[VDEF:vdefname=rpn-expression]\n"
158 "\t\t[PRINT:vdefname:format]\n"
159 "\t\t[GPRINT:vdefname:format]\n" "\t\t[COMMENT:text]\n"
160 "\t\t[SHIFT:vname:offset]\n"
161 "\t\t[TICK:vname#rrggbb[aa][:[fraction][:legend]]]\n"
162 "\t\t[HRULE:value#rrggbb[aa][:legend]]\n"
163 "\t\t[VRULE:value#rrggbb[aa][:legend]]\n"
164 "\t\t[LINE[width]:vname[#rrggbb[aa][:[legend][:STACK]]]]\n"
165 "\t\t[AREA:vname[#rrggbb[aa][:[legend][:STACK]]]]\n"
166 "\t\t[PRINT:vname:CF:format] (deprecated)\n"
167 "\t\t[GPRINT:vname:CF:format] (deprecated)\n"
168 "\t\t[STACK:vname[#rrggbb[aa][:legend]]] (deprecated)\n\n");
169 const char *help_tune1 =
170 N_(" * tune - Modify some basic properties of an RRD\n\n"
171 "\trrdtool tune filename\n"
172 "\t\t[--heartbeat|-h ds-name:heartbeat]\n"
173 "\t\t[--data-source-type|-d ds-name:DST]\n"
174 "\t\t[--data-source-rename|-r old-name:new-name]\n"
175 "\t\t[--minimum|-i ds-name:min] [--maximum|-a ds-name:max]\n"
176 "\t\t[--deltapos scale-value] [--deltaneg scale-value]\n"
177 "\t\t[--failure-threshold integer]\n"
178 "\t\t[--window-length integer]\n"
179 "\t\t[--alpha adaptation-parameter]\n");
180 const char *help_tune2 =
181 N_(" * tune - Modify some basic properties of an RRD\n\n"
182 "\t\t[--beta adaptation-parameter]\n"
183 "\t\t[--gamma adaptation-parameter]\n"
184 "\t\t[--gamma-deviation adaptation-parameter]\n"
185 "\t\t[--aberrant-reset ds-name]\n\n");
186 const char *help_resize =
188 (" * resize - alter the length of one of the RRAs in an RRD\n\n"
189 "\trrdtool resize filename rranum GROW|SHRINK rows\n\n");
190 const char *help_xport =
191 N_("* xport - generate XML dump from one or several RRD\n\n"
192 "\trrdtool xport [-s|--start seconds] [-e|--end seconds]\n"
193 "\t\t[-m|--maxrows rows]\n" "\t\t[--step seconds]\n"
194 "\t\t[--enumds]\n" "\t\t[DEF:vname=rrd:ds-name:CF]\n"
195 "\t\t[CDEF:vname=rpn-expression]\n"
196 "\t\t[XPORT:vname:legend]\n\n");
197 const char *help_quit =
198 N_(" * quit - closing a session in remote mode\n\n"
199 "\trrdtool quit\n\n");
200 const char *help_ls =
201 N_(" * ls - lists all *.rrd files in current directory\n\n"
203 const char *help_cd =
204 N_(" * cd - changes the current directory\n\n"
205 "\trrdtool cd new directory\n\n");
206 const char *help_mkdir =
207 N_(" * mkdir - creates a new directory\n\n"
208 "\trrdtool mkdir newdirectoryname\n\n");
209 const char *help_pwd =
210 N_(" * pwd - returns the current working directory\n\n"
211 "\trrdtool pwd\n\n");
212 const char *help_lic =
213 N_("RRDtool is distributed under the Terms of the GNU General\n"
214 "Public License Version 2. (www.gnu.org/copyleft/gpl.html)\n\n"
215 "For more information read the RRD manpages\n\n");
216 enum { C_NONE, C_CREATE, C_DUMP, C_INFO, C_RESTORE, C_LAST,
217 C_LASTUPDATE, C_FIRST, C_UPDATE, C_FETCH, C_GRAPH, C_GRAPHV,
219 C_RESIZE, C_XPORT, C_QUIT, C_LS, C_CD, C_MKDIR, C_PWD,
222 int help_cmd = C_NONE;
225 if (!strcmp(cmd, "create"))
227 else if (!strcmp(cmd, "dump"))
229 else if (!strcmp(cmd, "info"))
231 else if (!strcmp(cmd, "restore"))
232 help_cmd = C_RESTORE;
233 else if (!strcmp(cmd, "last"))
235 else if (!strcmp(cmd, "lastupdate"))
236 help_cmd = C_LASTUPDATE;
237 else if (!strcmp(cmd, "first"))
239 else if (!strcmp(cmd, "update"))
241 else if (!strcmp(cmd, "updatev"))
242 help_cmd = C_UPDATEV;
243 else if (!strcmp(cmd, "fetch"))
245 else if (!strcmp(cmd, "graph"))
247 else if (!strcmp(cmd, "graphv"))
249 else if (!strcmp(cmd, "tune"))
251 else if (!strcmp(cmd, "resize"))
253 else if (!strcmp(cmd, "xport"))
255 else if (!strcmp(cmd, "quit"))
257 else if (!strcmp(cmd, "ls"))
259 else if (!strcmp(cmd, "cd"))
261 else if (!strcmp(cmd, "mkdir"))
263 else if (!strcmp(cmd, "pwd"))
266 fprintf(stdout, _(help_main), PACKAGE_VERSION, __DATE__, __TIME__);
270 fputs(_(help_list), stdout);
272 fputs(_(help_listremote), stdout);
276 fputs(_(help_create), stdout);
279 fputs(_(help_dump), stdout);
282 fputs(_(help_info), stdout);
285 fputs(_(help_restore), stdout);
288 fputs(_(help_last), stdout);
291 fputs(_(help_lastupdate), stdout);
294 fputs(_(help_first), stdout);
297 fputs(_(help_update), stdout);
300 fputs(_(help_updatev), stdout);
303 fputs(_(help_fetch), stdout);
306 fputs(_(help_graph0), stdout);
307 fputs(_(help_graph1), stdout);
308 fputs(_(help_graph2), stdout);
309 fputs(_(help_graph3), stdout);
312 fputs(_(help_graphv0), stdout);
313 fputs(_(help_graph1), stdout);
314 fputs(_(help_graph2), stdout);
315 fputs(_(help_graph3), stdout);
318 fputs(_(help_tune1), stdout);
319 fputs(_(help_tune2), stdout);
322 fputs(_(help_resize), stdout);
325 fputs(_(help_xport), stdout);
328 fputs(_(help_quit), stdout);
331 fputs(_(help_ls), stdout);
334 fputs(_(help_cd), stdout);
337 fputs(_(help_mkdir), stdout);
340 fputs(_(help_pwd), stdout);
343 fputs(_(help_lic), stdout);
346 static char *fgetslong(
351 size_t bufsize = MAX_LENGTH;
355 return *aLinePtr = 0;
356 if (!(linebuf = malloc(bufsize))) {
357 perror("fgetslong: malloc");
361 while (fgets(linebuf + eolpos, MAX_LENGTH, stream)) {
362 eolpos += strlen(linebuf + eolpos);
363 if (linebuf[eolpos - 1] == '\n')
364 return *aLinePtr = linebuf;
365 bufsize += MAX_LENGTH;
366 if (!(linebuf = realloc(linebuf, bufsize))) {
368 perror("fgetslong: realloc");
373 return *aLinePtr = linebuf;
376 return *aLinePtr = 0;
387 #ifdef MUST_DISABLE_SIGFPE
388 signal(SIGFPE, SIG_IGN);
390 #ifdef MUST_DISABLE_FPMASK
394 setlocale(LC_ALL, "");
397 #if defined(HAVE_LIBINTL_H) && defined(BUILD_LIBINTL)
398 bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
399 bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
400 textdomain(GETTEXT_PACKAGE);
407 if (((argc == 2) || (argc == 3)) && !strcmp("-", argv[1])) {
409 struct rusage myusage;
410 struct timeval starttime;
411 struct timeval currenttime;
413 gettimeofday(&starttime, NULL);
416 if ((argc == 3) && strcmp("", argv[2])) {
427 if (chroot(argv[2]) != 0){
428 fprintf(stderr, "ERROR: chroot %s: %s\n", argv[2],rrd_strerror(errno));
435 "ERROR: change root is not supported by your OS "
436 "or at least by this copy of rrdtool\n");
443 if (strcmp(firstdir, "")) {
444 if (chdir(firstdir) != 0){
445 fprintf(stderr, "ERROR: chdir %s %s\n", firstdir,rrd_strerror(errno));
450 while (fgetslong(&aLine, stdin)) {
451 if ((argc = CountArgs(aLine)) == 0) {
453 printf("ERROR: not enough arguments\n");
455 if ((myargv = (char **) malloc((argc + 1) *
456 sizeof(char *))) == NULL) {
460 if ((argc = CreateArgs(argv[0], aLine, argc, myargv)) < 0) {
463 printf("ERROR: creating arguments\n");
465 int ret = HandleInputLine(argc, myargv, stdout);
470 getrusage(RUSAGE_SELF, &myusage);
471 gettimeofday(¤ttime, NULL);
472 printf("OK u:%1.2f s:%1.2f r:%1.2f\n",
473 (double) myusage.ru_utime.tv_sec +
474 (double) myusage.ru_utime.tv_usec / 1000000.0,
475 (double) myusage.ru_stime.tv_sec +
476 (double) myusage.ru_stime.tv_usec / 1000000.0,
477 (double) (currenttime.tv_sec - starttime.tv_sec)
478 + (double) (currenttime.tv_usec -
486 fflush(stdout); /* this is important for pipes to work */
489 } else if (argc == 2) {
492 } else if (argc == 3 && !strcmp(argv[1], "help")) {
496 exit(HandleInputLine(argc, argv, stderr));
501 /* HandleInputLine is NOT thread safe - due to readdir issues,
502 resolving them portably is not really simple. */
508 #if defined(HAVE_OPENDIR) && defined (HAVE_READDIR)
509 DIR *curdir; /* to read current dir with ls */
512 #if defined(HAVE_SYS_STAT_H)
515 char *cwd; /* To hold current working dir on call to pwd */
517 /* Reset errno to 0 before we start.
520 if (argc > 1 && strcmp("quit", argv[1]) == 0) {
522 printf("ERROR: invalid parameter count for quit\n");
527 #if defined(HAVE_OPENDIR) && defined(HAVE_READDIR) && defined(HAVE_CHDIR)
528 if (argc > 1 && strcmp("cd", argv[1]) == 0) {
530 printf("ERROR: invalid parameter count for cd\n");
533 #if ! defined(HAVE_CHROOT) || ! defined(HAVE_GETUID)
534 if (getuid() == 0 && !ChangeRoot) {
536 ("ERROR: chdir security problem - rrdtool is running as "
537 "root but not chroot!\n");
541 if (chdir(argv[2]) != 0){
542 printf("ERROR: chdir %s %s\n", argv[2], rrd_strerror(errno));
547 if (argc > 1 && strcmp("pwd", argv[1]) == 0) {
549 printf("ERROR: invalid parameter count for pwd\n");
552 cwd = getcwd(NULL, MAXPATH);
554 printf("ERROR: getcwd %s\n", rrd_strerror(errno));
561 if (argc > 1 && strcmp("mkdir", argv[1]) == 0) {
563 printf("ERROR: invalid parameter count for mkdir\n");
566 #if ! defined(HAVE_CHROOT) || ! defined(HAVE_GETUID)
567 if (getuid() == 0 && !ChangeRoot) {
569 ("ERROR: mkdir security problem - rrdtool is running as "
570 "root but not chroot!\n");
574 if(mkdir(argv[2], 0777)!=0){
575 printf("ERROR: mkdir %s: %s\n", argv[2],rrd_strerror(errno));
580 if (argc > 1 && strcmp("ls", argv[1]) == 0) {
582 printf("ERROR: invalid parameter count for ls\n");
585 if ((curdir = opendir(".")) != NULL) {
586 while ((dent = readdir(curdir)) != NULL) {
587 if (!stat(dent->d_name, &st)) {
588 if (S_ISDIR(st.st_mode)) {
589 printf("d %s\n", dent->d_name);
591 if (strlen(dent->d_name) > 4 && S_ISREG(st.st_mode)) {
593 (dent->d_name + NAMLEN(dent) - 4, ".rrd")
594 || !strcmp(dent->d_name + NAMLEN(dent) - 4,
596 printf("- %s\n", dent->d_name);
603 printf("ERROR: opendir .: %s\n", rrd_strerror(errno));
608 #endif /* opendir and readdir */
612 || strcmp("help", argv[1]) == 0
613 || strcmp("--help", argv[1]) == 0
614 || strcmp("-help", argv[1]) == 0
615 || strcmp("-?", argv[1]) == 0 || strcmp("-h", argv[1]) == 0) {
620 if (strcmp("create", argv[1]) == 0)
621 rrd_create(argc - 1, &argv[1]);
622 else if (strcmp("dump", argv[1]) == 0)
623 rrd_dump(argc - 1, &argv[1]);
624 else if (strcmp("info", argv[1]) == 0 || strcmp("updatev", argv[1]) == 0) {
627 if (strcmp("info", argv[1]) == 0)
629 data = rrd_info(argc - 1, &argv[1]);
631 data = rrd_update_v(argc - 1, &argv[1]);
632 rrd_info_print(data);
636 else if (strcmp("--version", argv[1]) == 0 ||
637 strcmp("version", argv[1]) == 0 ||
638 strcmp("v", argv[1]) == 0 ||
639 strcmp("-v", argv[1]) == 0 || strcmp("-version", argv[1]) == 0)
640 printf("RRDtool " PACKAGE_VERSION
641 " Copyright by Tobi Oetiker, 1997-2008 (%f)\n",
643 else if (strcmp("restore", argv[1]) == 0)
644 rrd_restore(argc - 1, &argv[1]);
645 else if (strcmp("resize", argv[1]) == 0)
646 rrd_resize(argc - 1, &argv[1]);
647 else if (strcmp("last", argv[1]) == 0)
648 printf("%ld\n", rrd_last(argc - 1, &argv[1]));
649 else if (strcmp("lastupdate", argv[1]) == 0) {
653 unsigned long ds_cnt, i;
655 if (rrd_lastupdate(argc - 1, &argv[1], &last_update,
656 &ds_cnt, &ds_namv, &last_ds) == 0) {
657 for (i = 0; i < ds_cnt; i++)
658 printf(" %s", ds_namv[i]);
660 printf("%10lu:", last_update);
661 for (i = 0; i < ds_cnt; i++) {
662 printf(" %s", last_ds[i]);
670 } else if (strcmp("first", argv[1]) == 0)
671 printf("%ld\n", rrd_first(argc - 1, &argv[1]));
672 else if (strcmp("update", argv[1]) == 0)
673 rrd_update(argc - 1, &argv[1]);
674 else if (strcmp("fetch", argv[1]) == 0) {
675 time_t start, end, ti;
676 unsigned long step, ds_cnt, i, ii;
677 rrd_value_t *data, *datai;
681 (argc - 1, &argv[1], &start, &end, &step, &ds_cnt, &ds_namv,
685 for (i = 0; i < ds_cnt; i++)
686 printf("%20s", ds_namv[i]);
688 for (ti = start + step; ti <= end; ti += step) {
689 printf("%10lu:", ti);
690 for (ii = 0; ii < ds_cnt; ii++)
691 printf(" %0.10e", *(datai++));
694 for (i = 0; i < ds_cnt; i++)
699 } else if (strcmp("xport", argv[1]) == 0) {
701 unsigned long int j = 0;
702 time_t start, end, ti;
703 unsigned long step, col_cnt, row_cnt;
704 rrd_value_t *data, *ptr;
708 size_t vtag_s = strlen(COL_DATA_TAG) + 10;
709 char *vtag = malloc(vtag_s);
711 for (i = 2; i < argc; i++) {
712 if (strcmp("--enumds", argv[i]) == 0)
717 (argc - 1, &argv[1], &xxsize, &start, &end, &step, &col_cnt,
718 &legend_v, &data) != -1) {
719 row_cnt = (end - start) / step;
721 printf("<?xml version=\"1.0\" encoding=\"%s\"?>\n\n",
723 printf("<%s>\n", ROOT_TAG);
724 printf(" <%s>\n", META_TAG);
725 printf(" <%s>%lu</%s>\n", META_START_TAG,
726 (unsigned long) start + step, META_START_TAG);
727 printf(" <%s>%lu</%s>\n", META_STEP_TAG, step, META_STEP_TAG);
728 printf(" <%s>%lu</%s>\n", META_END_TAG, (unsigned long) end,
730 printf(" <%s>%lu</%s>\n", META_ROWS_TAG, row_cnt,
732 printf(" <%s>%lu</%s>\n", META_COLS_TAG, col_cnt,
734 printf(" <%s>\n", LEGEND_TAG);
735 for (j = 0; j < col_cnt; j++) {
739 printf(" <%s>%s</%s>\n", LEGEND_ENTRY_TAG, entry,
744 printf(" </%s>\n", LEGEND_TAG);
745 printf(" </%s>\n", META_TAG);
746 printf(" <%s>\n", DATA_TAG);
747 for (ti = start + step; ti <= end; ti += step) {
748 printf(" <%s>", DATA_ROW_TAG);
749 printf("<%s>%lu</%s>", COL_TIME_TAG, ti, COL_TIME_TAG);
750 for (j = 0; j < col_cnt; j++) {
751 rrd_value_t newval = DNAN;
755 snprintf(vtag, vtag_s, "%s%lu", COL_DATA_TAG, j);
757 snprintf(vtag, vtag_s, "%s", COL_DATA_TAG);
760 printf("<%s>NaN</%s>", vtag, vtag);
762 printf("<%s>%0.10e</%s>", vtag, newval, vtag);
766 printf("</%s>\n", DATA_ROW_TAG);
769 printf(" </%s>\n", DATA_TAG);
770 printf("</%s>\n", ROOT_TAG);
773 } else if (strcmp("graph", argv[1]) == 0) {
776 #ifdef notused /*XXX*/
777 const char *imgfile = argv[2]; /* rrd_graph changes argv pointer */
782 int tostdout = (strcmp(argv[2], "-") == 0);
785 for (i = 2; i < argc; i++) {
786 if (strcmp(argv[i], "--imginfo") == 0
787 || strcmp(argv[i], "-f") == 0) {
793 (argc - 1, &argv[1], &calcpr, &xsize, &ysize, NULL, &ymin,
795 if (!tostdout && !imginfo)
796 printf("%dx%d\n", xsize, ysize);
798 for (i = 0; calcpr[i]; i++) {
800 printf("%s\n", calcpr[i]);
807 } else if (strcmp("graphv", argv[1]) == 0) {
808 rrd_info_t *grinfo = NULL; /* 1 to distinguish it from the NULL that rrd_graph sends in */
810 grinfo = rrd_graph_v(argc - 1, &argv[1]);
812 rrd_info_print(grinfo);
813 rrd_info_free(grinfo);
816 } else if (strcmp("tune", argv[1]) == 0)
817 rrd_tune(argc - 1, &argv[1]);
819 rrd_set_error("unknown function '%s'", argv[1]);
821 if (rrd_test_error()) {
822 fprintf(out, "ERROR: %s\n", rrd_get_error());
836 while (aLine[i] == ' ')
838 while (aLine[i] != 0) {
839 if ((aLine[i] == ' ') && inarg) {
842 if ((aLine[i] != ' ') && !inarg) {
852 * CreateArgs - take a string (aLine) and tokenize
867 /* remove trailing space and newlines */
868 while (len && aLine[len] <= ' ') {
872 /* sikp leading blanks */
873 while (*aLine && *aLine <= ' ')
899 pargv[argc++] = putP;
907 pargv[argc++] = putP;