ctdb-tools: Add -x option to specify delimiter for machine readable output
authorMartin Schwenke <martin@meltin.net>
Wed, 19 Nov 2014 06:15:21 +0000 (17:15 +1100)
committerKarolin Seeger <kseeger@samba.org>
Wed, 10 Dec 2014 19:56:08 +0000 (20:56 +0100)
To support this, update printm() to replace ':' in format string with
options.machineseparator, which is a string but must contain a single
character.

Signed-off-by: Martin Schwenke <martin@meltin.net>
Reviewed-by: Amitay Isaacs <amitay@gmail.com>
(cherry picked from commit 3b90e45bae555cc4a47fe9958b86628d41084868)

ctdb/doc/ctdb.1.xml
ctdb/tools/ctdb.c

index efa5d8532626d7462aaaa9d749c7369039e2a33d..08ed5640c791bf1ffbc381f56ee63d11c57fdb84 100644 (file)
       <listitem>
        <para>
          Produce output in machine readable form for easier parsing
-         by scripts. Not all commands support this option.
+         by scripts. This uses a field delimiter of ':'.  Not all
+         commands support this option.
+       </para>
+      </listitem>
+      </varlistentry>
+
+      <varlistentry><term>-x <parameter>SEPARATOR</parameter></term>
+      <listitem>
+       <para>
+         Use SEPARATOR to delimit fields in machine readable output.
+         This implies -Y.
        </para>
       </listitem>
       </varlistentry>
index db989324c00b1f1e73ff1afe23efb358093f8bf3..5a111af6a9820b0f7f918f7a564fe9321cb2078c 100644 (file)
@@ -43,6 +43,7 @@ static struct {
        uint32_t pnn;
        uint32_t *nodes;
        int machinereadable;
+       const char *machineseparator;
        int verbose;
        int maxruntime;
        int printemptyrecords;
@@ -75,9 +76,18 @@ static int printm(const char *format, ...)
 {
        va_list ap;
        int ret;
+       size_t len = strlen(format);
+       char new_format[len+1];
+
+       strcpy(new_format, format);
+
+       if (options.machineseparator[0] != ':') {
+               all_string_sub(new_format,
+                              ":", options.machineseparator, len + 1);
+       }
 
        va_start(ap, format);
-       ret = vprintf(format, ap);
+       ret = vprintf(new_format, ap);
        va_end(ap);
 
        return ret;
@@ -6346,7 +6356,8 @@ static void usage(void)
 "Usage: ctdb [options] <control>\n" \
 "Options:\n" \
 "   -n <node>          choose node number, or 'all' (defaults to local node)\n"
-"   -Y                 generate machinereadable output\n"
+"   -Y                 generate machine readable output\n"
+"   -x <char>          specify delimiter for machine readable output\n"
 "   -v                 generate verbose output\n"
 "   -t <timelimit>     set timelimit for control in seconds (default %u)\n", options.timelimit);
        printf("Controls:\n");
@@ -6378,7 +6389,8 @@ int main(int argc, const char *argv[])
                POPT_CTDB_CMDLINE
                { "timelimit", 't', POPT_ARG_INT, &options.timelimit, 0, "timelimit", "integer" },
                { "node",      'n', POPT_ARG_STRING, &nodestring, 0, "node", "integer|all" },
-               { "machinereadable", 'Y', POPT_ARG_NONE, &options.machinereadable, 0, "enable machinereadable output", NULL },
+               { "machinereadable", 'Y', POPT_ARG_NONE, &options.machinereadable, 0, "enable machine readable output", NULL },
+               { NULL, 'x', POPT_ARG_STRING, &options.machineseparator, 0, "specify separator for machine readable output", "char" },
                { "verbose",    'v', POPT_ARG_NONE, &options.verbose, 0, "enable verbose output", NULL },
                { "maxruntime", 'T', POPT_ARG_INT, &options.maxruntime, 0, "die if runtime exceeds this limit (in seconds)", "integer" },
                { "print-emptyrecords", 0, POPT_ARG_NONE, &options.printemptyrecords, 0, "print the empty records when dumping databases (catdb, cattdb, dumpdbbackup)", NULL },
@@ -6436,6 +6448,20 @@ int main(int argc, const char *argv[])
                }
        }
 
+       if (options.machineseparator != NULL) {
+               if (strlen(options.machineseparator) != 1) {
+                       printf("Invalid separator \"%s\" - "
+                              "must be single character\n",
+                              options.machineseparator);
+                       exit(1);
+               }
+
+               /* -x implies -Y */
+               options.machinereadable = true;
+       } else if (options.machinereadable) {
+               options.machineseparator = ":";
+       }
+
        signal(SIGALRM, ctdb_alarm);
        alarm(options.maxruntime);