1 /*****************************************************************************
2 * RRDtool 1.3rc3 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-2007 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[-E|--slope-mode]\n"
145 "\t\t[-N|--no-gridfit]\n"
146 "\t\t[-X|--units-exponent value]\n"
147 "\t\t[-L|--units-length value]\n"
148 "\t\t[-S|--step seconds]\n"
149 "\t\t[-f|--imginfo printfstr]\n"
150 "\t\t[-a|--imgformat PNG]\n"
151 "\t\t[-c|--color COLORTAG#rrggbb[aa]] [-t|--title string]\n"
152 "\t\t[-W|--watermark string]\n"
153 "\t\t[DEF:vname=rrd:ds-name:CF]\n");
154 const char *help_graph3 =
155 N_("\t\t[CDEF:vname=rpn-expression]\n"
156 "\t\t[VDEF:vdefname=rpn-expression]\n"
157 "\t\t[PRINT:vdefname:format]\n"
158 "\t\t[GPRINT:vdefname:format]\n" "\t\t[COMMENT:text]\n"
159 "\t\t[SHIFT:vname:offset]\n"
160 "\t\t[TICK:vname#rrggbb[aa][:[fraction][:legend]]]\n"
161 "\t\t[HRULE:value#rrggbb[aa][:legend]]\n"
162 "\t\t[VRULE:value#rrggbb[aa][:legend]]\n"
163 "\t\t[LINE[width]:vname[#rrggbb[aa][:[legend][:STACK]]]]\n"
164 "\t\t[AREA:vname[#rrggbb[aa][:[legend][:STACK]]]]\n"
165 "\t\t[PRINT:vname:CF:format] (deprecated)\n"
166 "\t\t[GPRINT:vname:CF:format] (deprecated)\n"
167 "\t\t[STACK:vname[#rrggbb[aa][:legend]]] (deprecated)\n\n");
168 const char *help_tune1 =
169 N_(" * tune - Modify some basic properties of an RRD\n\n"
170 "\trrdtool tune filename\n"
171 "\t\t[--heartbeat|-h ds-name:heartbeat]\n"
172 "\t\t[--data-source-type|-d ds-name:DST]\n"
173 "\t\t[--data-source-rename|-r old-name:new-name]\n"
174 "\t\t[--minimum|-i ds-name:min] [--maximum|-a ds-name:max]\n"
175 "\t\t[--deltapos scale-value] [--deltaneg scale-value]\n"
176 "\t\t[--failure-threshold integer]\n"
177 "\t\t[--window-length integer]\n"
178 "\t\t[--alpha adaptation-parameter]\n");
179 const char *help_tune2 =
180 N_(" * tune - Modify some basic properties of an RRD\n\n"
181 "\t\t[--beta adaptation-parameter]\n"
182 "\t\t[--gamma adaptation-parameter]\n"
183 "\t\t[--gamma-deviation adaptation-parameter]\n"
184 "\t\t[--aberrant-reset ds-name]\n\n");
185 const char *help_resize =
187 (" * resize - alter the length of one of the RRAs in an RRD\n\n"
188 "\trrdtool resize filename rranum GROW|SHRINK rows\n\n");
189 const char *help_xport =
190 N_("* xport - generate XML dump from one or several RRD\n\n"
191 "\trrdtool xport [-s|--start seconds] [-e|--end seconds]\n"
192 "\t\t[-m|--maxrows rows]\n" "\t\t[--step seconds]\n"
193 "\t\t[--enumds]\n" "\t\t[DEF:vname=rrd:ds-name:CF]\n"
194 "\t\t[CDEF:vname=rpn-expression]\n"
195 "\t\t[XPORT:vname:legend]\n\n");
196 const char *help_quit =
197 N_(" * quit - closing a session in remote mode\n\n"
198 "\trrdtool quit\n\n");
199 const char *help_ls =
200 N_(" * ls - lists all *.rrd files in current directory\n\n"
202 const char *help_cd =
203 N_(" * cd - changes the current directory\n\n"
204 "\trrdtool cd new directory\n\n");
205 const char *help_mkdir =
206 N_(" * mkdir - creates a new directory\n\n"
207 "\trrdtool mkdir newdirectoryname\n\n");
208 const char *help_pwd =
209 N_(" * pwd - returns the current working directory\n\n"
210 "\trrdtool pwd\n\n");
211 const char *help_lic =
212 N_("RRDtool is distributed under the Terms of the GNU General\n"
213 "Public License Version 2. (www.gnu.org/copyleft/gpl.html)\n\n"
214 "For more information read the RRD manpages\n\n");
215 enum { C_NONE, C_CREATE, C_DUMP, C_INFO, C_RESTORE, C_LAST,
216 C_LASTUPDATE, C_FIRST, C_UPDATE, C_FETCH, C_GRAPH, C_GRAPHV,
218 C_RESIZE, C_XPORT, C_QUIT, C_LS, C_CD, C_MKDIR, C_PWD,
221 int help_cmd = C_NONE;
224 if (!strcmp(cmd, "create"))
226 else if (!strcmp(cmd, "dump"))
228 else if (!strcmp(cmd, "info"))
230 else if (!strcmp(cmd, "restore"))
231 help_cmd = C_RESTORE;
232 else if (!strcmp(cmd, "last"))
234 else if (!strcmp(cmd, "lastupdate"))
235 help_cmd = C_LASTUPDATE;
236 else if (!strcmp(cmd, "first"))
238 else if (!strcmp(cmd, "update"))
240 else if (!strcmp(cmd, "updatev"))
241 help_cmd = C_UPDATEV;
242 else if (!strcmp(cmd, "fetch"))
244 else if (!strcmp(cmd, "graph"))
246 else if (!strcmp(cmd, "graphv"))
248 else if (!strcmp(cmd, "tune"))
250 else if (!strcmp(cmd, "resize"))
252 else if (!strcmp(cmd, "xport"))
254 else if (!strcmp(cmd, "quit"))
256 else if (!strcmp(cmd, "ls"))
258 else if (!strcmp(cmd, "cd"))
260 else if (!strcmp(cmd, "mkdir"))
262 else if (!strcmp(cmd, "pwd"))
265 fprintf(stdout, _(help_main), PACKAGE_VERSION, __DATE__, __TIME__);
269 fputs(_(help_list), stdout);
271 fputs(_(help_listremote), stdout);
275 fputs(_(help_create), stdout);
278 fputs(_(help_dump), stdout);
281 fputs(_(help_info), stdout);
284 fputs(_(help_restore), stdout);
287 fputs(_(help_last), stdout);
290 fputs(_(help_lastupdate), stdout);
293 fputs(_(help_first), stdout);
296 fputs(_(help_update), stdout);
299 fputs(_(help_updatev), stdout);
302 fputs(_(help_fetch), stdout);
305 fputs(_(help_graph0), stdout);
306 fputs(_(help_graph1), stdout);
307 fputs(_(help_graph2), stdout);
308 fputs(_(help_graph3), stdout);
311 fputs(_(help_graphv0), stdout);
312 fputs(_(help_graph1), stdout);
313 fputs(_(help_graph2), stdout);
314 fputs(_(help_graph3), stdout);
317 fputs(_(help_tune1), stdout);
318 fputs(_(help_tune2), stdout);
321 fputs(_(help_resize), stdout);
324 fputs(_(help_xport), stdout);
327 fputs(_(help_quit), stdout);
330 fputs(_(help_ls), stdout);
333 fputs(_(help_cd), stdout);
336 fputs(_(help_mkdir), stdout);
339 fputs(_(help_pwd), stdout);
342 fputs(_(help_lic), stdout);
345 static char *fgetslong(
350 size_t bufsize = MAX_LENGTH;
354 return *aLinePtr = 0;
355 if (!(linebuf = malloc(bufsize))) {
356 perror("fgetslong: malloc");
360 while (fgets(linebuf + eolpos, MAX_LENGTH, stream)) {
361 eolpos += strlen(linebuf + eolpos);
362 if (linebuf[eolpos - 1] == '\n')
363 return *aLinePtr = linebuf;
364 bufsize += MAX_LENGTH;
365 if (!(linebuf = realloc(linebuf, bufsize))) {
366 perror("fgetslong: realloc");
370 return *aLinePtr = linebuf[0] ? linebuf : 0;
381 #ifdef MUST_DISABLE_SIGFPE
382 signal(SIGFPE, SIG_IGN);
384 #ifdef MUST_DISABLE_FPMASK
388 setlocale(LC_ALL, "");
391 #if defined(HAVE_LIBINTL_H) && defined(BUILD_LIBINTL)
392 bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
393 bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
394 textdomain(GETTEXT_PACKAGE);
401 if (((argc == 2) || (argc == 3)) && !strcmp("-", argv[1])) {
403 struct rusage myusage;
404 struct timeval starttime;
405 struct timeval currenttime;
407 gettimeofday(&starttime, NULL);
410 if ((argc == 3) && strcmp("", argv[2])) {
424 "ERROR: can't change root to '%s' errno=%d\n",
432 "ERROR: change root is not supported by your OS "
433 "or at least by this copy of rrdtool\n");
440 if (strcmp(firstdir, "")) {
443 fprintf(stderr, "ERROR: %s\n", rrd_strerror(errno));
448 while (fgetslong(&aLine, stdin)) {
449 if ((argc = CountArgs(aLine)) == 0) {
450 printf("ERROR: not enough arguments\n");
452 if ((myargv = (char **) malloc((argc + 1) *
453 sizeof(char *))) == NULL) {
457 if ((argc = CreateArgs(argv[0], aLine, argc, myargv)) < 0) {
458 printf("ERROR: creating arguments\n");
460 int ret = HandleInputLine(argc, myargv, stdout);
465 getrusage(RUSAGE_SELF, &myusage);
466 gettimeofday(¤ttime, NULL);
467 printf("OK u:%1.2f s:%1.2f r:%1.2f\n",
468 (double) myusage.ru_utime.tv_sec +
469 (double) myusage.ru_utime.tv_usec / 1000000.0,
470 (double) myusage.ru_stime.tv_sec +
471 (double) myusage.ru_stime.tv_usec / 1000000.0,
472 (double) (currenttime.tv_sec - starttime.tv_sec)
473 + (double) (currenttime.tv_usec -
481 fflush(stdout); /* this is important for pipes to work */
484 } else if (argc == 2) {
487 } else if (argc == 3 && !strcmp(argv[1], "help")) {
491 exit(HandleInputLine(argc, argv, stderr));
496 /* HandleInputLine is NOT thread safe - due to readdir issues,
497 resolving them portably is not really simple. */
503 #if defined(HAVE_OPENDIR) && defined (HAVE_READDIR)
504 DIR *curdir; /* to read current dir with ls */
507 #if defined(HAVE_SYS_STAT_H)
510 char *cwd; /* To hold current working dir on call to pwd */
512 /* Reset errno to 0 before we start.
516 if (argc > 1 && strcmp("quit", argv[1]) == 0) {
518 printf("ERROR: invalid parameter count for quit\n");
523 #if defined(HAVE_OPENDIR) && defined(HAVE_READDIR) && defined(HAVE_CHDIR)
524 if (argc > 1 && strcmp("cd", argv[1]) == 0) {
526 printf("ERROR: invalid parameter count for cd\n");
529 #if ! defined(HAVE_CHROOT) || ! defined(HAVE_GETUID)
530 if (getuid() == 0 && !ChangeRoot) {
532 ("ERROR: chdir security problem - rrdtool is running as "
533 "root but not chroot!\n");
539 printf("ERROR: %s\n", rrd_strerror(errno));
544 if (argc > 1 && strcmp("pwd", argv[1]) == 0) {
546 printf("ERROR: invalid parameter count for pwd\n");
549 cwd = getcwd(NULL, MAXPATH);
551 printf("ERROR: %s\n", rrd_strerror(errno));
558 if (argc > 1 && strcmp("mkdir", argv[1]) == 0) {
560 printf("ERROR: invalid parameter count for mkdir\n");
563 #if ! defined(HAVE_CHROOT) || ! defined(HAVE_GETUID)
564 if (getuid() == 0 && !ChangeRoot) {
566 ("ERROR: mkdir security problem - rrdtool is running as "
567 "root but not chroot!\n");
571 mkdir(argv[2], 0777);
573 printf("ERROR: %s\n", rrd_strerror(errno));
578 if (argc > 1 && strcmp("ls", argv[1]) == 0) {
580 printf("ERROR: invalid parameter count for ls\n");
583 if ((curdir = opendir(".")) != NULL) {
584 while ((dent = readdir(curdir)) != NULL) {
585 if (!stat(dent->d_name, &st)) {
586 if (S_ISDIR(st.st_mode)) {
587 printf("d %s\n", dent->d_name);
589 if (strlen(dent->d_name) > 4 && S_ISREG(st.st_mode)) {
591 (dent->d_name + NAMLEN(dent) - 4, ".rrd")
592 || !strcmp(dent->d_name + NAMLEN(dent) - 4,
594 printf("- %s\n", dent->d_name);
601 printf("ERROR: %s\n", rrd_strerror(errno));
606 #endif /* opendir and readdir */
610 || strcmp("help", argv[1]) == 0
611 || strcmp("--help", argv[1]) == 0
612 || strcmp("-help", argv[1]) == 0
613 || strcmp("-?", argv[1]) == 0 || strcmp("-h", argv[1]) == 0) {
618 if (strcmp("create", argv[1]) == 0)
619 rrd_create(argc - 1, &argv[1]);
620 else if (strcmp("dump", argv[1]) == 0)
621 rrd_dump(argc - 1, &argv[1]);
622 else if (strcmp("info", argv[1]) == 0 || strcmp("updatev", argv[1]) == 0) {
625 if (strcmp("info", argv[1]) == 0)
627 data = rrd_info(argc - 1, &argv[1]);
629 data = rrd_update_v(argc - 1, &argv[1]);
634 else if (strcmp("--version", argv[1]) == 0 ||
635 strcmp("version", argv[1]) == 0 ||
636 strcmp("v", argv[1]) == 0 ||
637 strcmp("-v", argv[1]) == 0 || strcmp("-version", argv[1]) == 0)
638 printf("RRDtool " PACKAGE_VERSION
639 " Copyright by Tobi Oetiker, 1997-2008 (%f)\n",
641 else if (strcmp("restore", argv[1]) == 0)
642 rrd_restore(argc - 1, &argv[1]);
643 else if (strcmp("resize", argv[1]) == 0)
644 rrd_resize(argc - 1, &argv[1]);
645 else if (strcmp("last", argv[1]) == 0)
646 printf("%ld\n", rrd_last(argc - 1, &argv[1]));
647 else if (strcmp("lastupdate", argv[1]) == 0) {
651 unsigned long ds_cnt, i;
653 if (rrd_lastupdate(argc - 1, &argv[1], &last_update,
654 &ds_cnt, &ds_namv, &last_ds) == 0) {
655 for (i = 0; i < ds_cnt; i++)
656 printf(" %s", ds_namv[i]);
658 printf("%10lu:", last_update);
659 for (i = 0; i < ds_cnt; i++) {
660 printf(" %s", last_ds[i]);
668 } else if (strcmp("first", argv[1]) == 0)
669 printf("%ld\n", rrd_first(argc - 1, &argv[1]));
670 else if (strcmp("update", argv[1]) == 0)
671 rrd_update(argc - 1, &argv[1]);
672 else if (strcmp("fetch", argv[1]) == 0) {
673 time_t start, end, ti;
674 unsigned long step, ds_cnt, i, ii;
675 rrd_value_t *data, *datai;
679 (argc - 1, &argv[1], &start, &end, &step, &ds_cnt, &ds_namv,
683 for (i = 0; i < ds_cnt; i++)
684 printf("%20s", ds_namv[i]);
686 for (ti = start + step; ti <= end; ti += step) {
687 printf("%10lu:", ti);
688 for (ii = 0; ii < ds_cnt; ii++)
689 printf(" %0.10e", *(datai++));
692 for (i = 0; i < ds_cnt; i++)
697 } else if (strcmp("xport", argv[1]) == 0) {
699 unsigned long int j = 0;
700 time_t start, end, ti;
701 unsigned long step, col_cnt, row_cnt;
702 rrd_value_t *data, *ptr;
706 size_t vtag_s = strlen(COL_DATA_TAG) + 10;
707 char *vtag = malloc(vtag_s);
709 for (i = 2; i < argc; i++) {
710 if (strcmp("--enumds", argv[i]) == 0)
715 (argc - 1, &argv[1], &xxsize, &start, &end, &step, &col_cnt,
716 &legend_v, &data) != -1) {
717 row_cnt = (end - start) / step;
719 printf("<?xml version=\"1.0\" encoding=\"%s\"?>\n\n",
721 printf("<%s>\n", ROOT_TAG);
722 printf(" <%s>\n", META_TAG);
723 printf(" <%s>%lu</%s>\n", META_START_TAG,
724 (unsigned long) start + step, META_START_TAG);
725 printf(" <%s>%lu</%s>\n", META_STEP_TAG, step, META_STEP_TAG);
726 printf(" <%s>%lu</%s>\n", META_END_TAG, (unsigned long) end,
728 printf(" <%s>%lu</%s>\n", META_ROWS_TAG, row_cnt,
730 printf(" <%s>%lu</%s>\n", META_COLS_TAG, col_cnt,
732 printf(" <%s>\n", LEGEND_TAG);
733 for (j = 0; j < col_cnt; j++) {
737 printf(" <%s>%s</%s>\n", LEGEND_ENTRY_TAG, entry,
742 printf(" </%s>\n", LEGEND_TAG);
743 printf(" </%s>\n", META_TAG);
744 printf(" <%s>\n", DATA_TAG);
745 for (ti = start + step; ti <= end; ti += step) {
746 printf(" <%s>", DATA_ROW_TAG);
747 printf("<%s>%lu</%s>", COL_TIME_TAG, ti, COL_TIME_TAG);
748 for (j = 0; j < col_cnt; j++) {
749 rrd_value_t newval = DNAN;
753 snprintf(vtag, vtag_s, "%s%lu", COL_DATA_TAG, j);
755 snprintf(vtag, vtag_s, "%s", COL_DATA_TAG);
758 printf("<%s>NaN</%s>", vtag, vtag);
760 printf("<%s>%0.10e</%s>", vtag, newval, vtag);
764 printf("</%s>\n", DATA_ROW_TAG);
767 printf(" </%s>\n", DATA_TAG);
768 printf("</%s>\n", ROOT_TAG);
771 } else if (strcmp("graph", argv[1]) == 0) {
774 #ifdef notused /*XXX*/
775 const char *imgfile = argv[2]; /* rrd_graph changes argv pointer */
780 int tostdout = (strcmp(argv[2], "-") == 0);
783 for (i = 2; i < argc; i++) {
784 if (strcmp(argv[i], "--imginfo") == 0
785 || strcmp(argv[i], "-f") == 0) {
791 (argc - 1, &argv[1], &calcpr, &xsize, &ysize, NULL, &ymin,
793 if (!tostdout && !imginfo)
794 printf("%dx%d\n", xsize, ysize);
796 for (i = 0; calcpr[i]; i++) {
798 printf("%s\n", calcpr[i]);
805 } else if (strcmp("graphv", argv[1]) == 0) {
806 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]);
813 } else if (strcmp("tune", argv[1]) == 0)
814 rrd_tune(argc - 1, &argv[1]);
816 rrd_set_error("unknown function '%s'", argv[1]);
818 if (rrd_test_error()) {
819 fprintf(out, "ERROR: %s\n", rrd_get_error());
833 while (aLine[i] == ' ')
835 while (aLine[i] != 0) {
836 if ((aLine[i] == ' ') && inarg) {
839 if ((aLine[i] != ' ') && !inarg) {
849 * CreateArgs - take a string (aLine) and tokenize
864 /* remove trailing space and newlines */
865 while (len && aLine[len] <= ' ') {
869 /* sikp leading blanks */
870 while (*aLine && *aLine <= ' ')
896 pargv[argc++] = putP;
904 pargv[argc++] = putP;