Re: [Xen-devel] [PATCH v2 2/2] xenstore-client: Add option for raw in-/output

2018-07-31 Thread Wei Liu
On Tue, Jul 31, 2018 at 04:56:54AM +0200, Marek Marczykowski-Górecki wrote:
> From: Simon Gaiser 
> 
> Parsing/generating the escape sequences used by xenstore-client is non
> trivial. So make scripting (for use in stubdom) easier by adding a raw
> option.
> 
> [added man page entries, facor out expand_buffer]
> Signed-off-by: Marek Marczykowski-Górecki 

Acked-by: Wei Liu 

___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH v2 2/2] xenstore-client: Add option for raw in-/output

2018-07-30 Thread Marek Marczykowski-Górecki
From: Simon Gaiser 

Parsing/generating the escape sequences used by xenstore-client is non
trivial. So make scripting (for use in stubdom) easier by adding a raw
option.

[added man page entries, facor out expand_buffer]
Signed-off-by: Marek Marczykowski-Górecki 
---
Changes in v2:
 - man page entries
 - factor out expand_buffer
---
 docs/man/xenstore-read.pod.1 |  4 ++
 docs/man/xenstore-write.pod.1|  4 ++
 tools/xenstore/xenstore_client.c | 65 
 3 files changed, 57 insertions(+), 16 deletions(-)

diff --git a/docs/man/xenstore-read.pod.1 b/docs/man/xenstore-read.pod.1
index 256d58fb7d..5496de17a8 100644
--- a/docs/man/xenstore-read.pod.1
+++ b/docs/man/xenstore-read.pod.1
@@ -20,6 +20,10 @@ Prefix value with key name.
 
 Connect to the Xenstore daemon using a local socket only.
 
+=item B<-R>
+
+Read raw value, skip escaping non-printable characters (\x..).
+
 =back
 
 =head1 BUGS
diff --git a/docs/man/xenstore-write.pod.1 b/docs/man/xenstore-write.pod.1
index 424ab0e30e..78cbbe1a69 100644
--- a/docs/man/xenstore-write.pod.1
+++ b/docs/man/xenstore-write.pod.1
@@ -17,6 +17,10 @@ provided to write them at once - in one Xenstore transaction.
 
 Connect to the Xenstore daemon using a local socket only.
 
+=item B<-R>
+
+Write raw value, skip parsing escaped characters (\x..).
+
 =back
 
 =head1 BUGS
diff --git a/tools/xenstore/xenstore_client.c b/tools/xenstore/xenstore_client.c
index 3d14d37e62..3afc630ab8 100644
--- a/tools/xenstore/xenstore_client.c
+++ b/tools/xenstore/xenstore_client.c
@@ -44,6 +44,17 @@ static struct expanding_buffer ebuf;
 
 static int output_size = 0;
 
+/* make sure there is at least 'len' more space in output_buf */
+static void expand_buffer(size_t len)
+{
+if (output_pos + len > output_size) {
+output_size += len + 1024;
+output_buf = realloc(output_buf, output_size);
+if (output_buf == NULL)
+err(1, "malloc");
+}
+}
+
 static void
 output(const char *fmt, ...) {
 va_list ap;
@@ -55,12 +66,7 @@ output(const char *fmt, ...) {
 if (len < 0)
err(1, "output");
 va_end(ap);
-if (len + 1 + output_pos > output_size) {
-   output_size += len + 1024;
-   output_buf = realloc(output_buf, output_size);
-   if (output_buf == NULL)
-   err(1, "malloc");
-}
+expand_buffer(len + 1);
 va_start(ap, fmt);
 if (vsnprintf(_buf[output_pos], len + 1, fmt, ap) != len)
err(1, "output");
@@ -68,6 +74,14 @@ output(const char *fmt, ...) {
 output_pos += len;
 }
 
+static void
+output_raw(const char *data, int len)
+{
+expand_buffer(len);
+memcpy(_buf[output_pos], data, len);
+output_pos += len;
+}
+
 static void
 usage(enum mode mode, int incl_mode, const char *progname)
 {
@@ -78,10 +92,10 @@ usage(enum mode mode, int incl_mode, const char *progname)
errx(1, "Usage: %s  [-h] [...]", progname);
 case MODE_read:
mstr = incl_mode ? "read " : "";
-   errx(1, "Usage: %s %s[-h] [-p] [-s] key [...]", progname, mstr);
+   errx(1, "Usage: %s %s[-h] [-p] [-s] [-R] key [...]", progname, mstr);
 case MODE_write:
mstr = incl_mode ? "write " : "";
-   errx(1, "Usage: %s %s[-h] [-s] key value [...]", progname, mstr);
+   errx(1, "Usage: %s %s[-h] [-s] [-R] key value [...]", progname, mstr);
 case MODE_rm:
mstr = incl_mode ? "rm " : "";
errx(1, "Usage: %s %s[-h] [-s] [-t] key [...]", progname, mstr);
@@ -293,7 +307,8 @@ do_watch(struct xs_handle *xsh, int max_events)
 
 static int
 perform(enum mode mode, int optind, int argc, char **argv, struct xs_handle 
*xsh,
-xs_transaction_t xth, int prefix, int tidy, int upto, int recurse, int 
nr_watches)
+xs_transaction_t xth, int prefix, int tidy, int upto, int recurse, int 
nr_watches,
+int raw)
 {
 switch (mode) {
 case MODE_ls:
@@ -322,17 +337,27 @@ perform(enum mode mode, int optind, int argc, char 
**argv, struct xs_handle *xsh
 }
 if (prefix)
 output("%s: ", argv[optind]);
-output("%s\n", sanitise_value(, val, len));
+if (raw)
+output_raw(val, len);
+else
+output("%s\n", sanitise_value(, val, len));
 free(val);
 optind++;
 break;
 }
 case MODE_write: {
 char *val_spec = argv[optind + 1];
+char *val;
 unsigned len;
-expanding_buffer_ensure(, strlen(val_spec)+1);
-unsanitise_value(ebuf.buf, , val_spec);
-if (!xs_write(xsh, xth, argv[optind], ebuf.buf, len)) {
+if (raw) {
+val = val_spec;
+len = strlen(val_spec);
+} else {
+expanding_buffer_ensure(, strlen(val_spec)+1);
+unsanitise_value(ebuf.buf, , val_spec);
+val = ebuf.buf;
+}
+if (!xs_write(xsh, xth,