bool xs_strings_to_perms(struct xs_permissions *perms, unsigned int num,
const char *strings);
-/* Convert permissions to a string (up to len MAX_STRLEN(unsigned int)+1). */
-bool xs_perm_to_string(const struct xs_permissions *perm,
- char *buffer, size_t buf_len);
-
-/* Given a string and a length, count how many strings (nul terms). */
-unsigned int xs_count_strings(const char *strings, unsigned int len);
-
-/* Sanitising (quoting) possibly-binary strings. */
-struct expanding_buffer {
- char *buf;
- int avail;
-};
-
-/* Ensure that given expanding buffer has at least min_avail characters. */
-char *expanding_buffer_ensure(struct expanding_buffer *, int min_avail);
-
-/* sanitise_value() may return NULL if malloc fails. */
-char *sanitise_value(struct expanding_buffer *, const char *val, unsigned len);
-
-/* *out_len_r on entry is ignored; out must be at least strlen(in)+1 bytes. */
-void unsanitise_value(char *out, unsigned *out_len_r, const char *in);
-
#endif /* XENSTORE_LIB_H */
diff --git a/tools/libs/store/Makefile b/tools/libs/store/Makefile
index bee57b5629..43b018aa8c 100644
--- a/tools/libs/store/Makefile
+++ b/tools/libs/store/Makefile
@@ -1,8 +1,8 @@
XEN_ROOT=$(CURDIR)/../../..
include $(XEN_ROOT)/tools/Rules.mk
-MAJOR = 3.0
-MINOR = 3
+MAJOR = 4
+MINOR = 0
ifeq ($(CONFIG_Linux),y)
APPEND_LDFLAGS += -ldl
diff --git a/tools/libs/store/libxenstore.map b/tools/libs/store/libxenstore.map
index 9854305a2c..7e6c7bdd30 100644
--- a/tools/libs/store/libxenstore.map
+++ b/tools/libs/store/libxenstore.map
@@ -1,4 +1,4 @@
-VERS_3.0.3 {
+VERS_4.0 {
global:
xs_open;
xs_close;
@@ -32,18 +32,10 @@ VERS_3.0.3 {
xs_control_command;
xs_debug_command;
xs_suspend_evtchn_port;
- xs_daemon_rootdir;
xs_daemon_rundir;
xs_daemon_socket;
xs_daemon_socket_ro;
- xs_domain_dev;
- xs_daemon_tdb;
xs_write_all;
xs_strings_to_perms;
- xs_perm_to_string;
- xs_count_strings;
- expanding_buffer_ensure;
- sanitise_value;
- unsanitise_value;
local: *; /* Do not expose anything by default */
};
diff --git a/tools/libs/store/xs.c b/tools/libs/store/xs.c
index c91377c27f..7a9a8b1656 100644
--- a/tools/libs/store/xs.c
+++ b/tools/libs/store/xs.c
@@ -34,6 +34,7 @@
#include <stdint.h>
#include <errno.h>
#include "xenstore.h"
+#include "xs_lib.h"
#include "list.h"
#include "utils.h"
@@ -1358,117 +1359,6 @@ static void *read_thread(void *arg)
}
#endif
-char *expanding_buffer_ensure(struct expanding_buffer *ebuf, int min_avail)
-{
- int want;
- char *got;
-
- if (ebuf->avail >= min_avail)
- return ebuf->buf;
-
- if (min_avail >= INT_MAX/3)
- return 0;
-
- want = ebuf->avail + min_avail + 10;
- got = realloc(ebuf->buf, want);
- if (!got)
- return 0;
-
- ebuf->buf = got;
- ebuf->avail = want;
- return ebuf->buf;
-}
-
-char *sanitise_value(struct expanding_buffer *ebuf,
- const char *val, unsigned len)
-{
- int used, remain, c;
- unsigned char *ip;
-
-#define ADD(c) (ebuf->buf[used++] = (c))
-#define ADDF(f,c) (used += sprintf(ebuf->buf+used, (f), (c)))
-
- assert(len < INT_MAX/5);
-
- ip = (unsigned char *)val;
- used = 0;
- remain = len;
-
- if (!expanding_buffer_ensure(ebuf, remain + 1))
- return NULL;
-
- while (remain-- > 0) {
- c= *ip++;
-
- if (c >= ' ' && c <= '~' && c != '\\') {
- ADD(c);
- continue;
- }
-
- if (!expanding_buffer_ensure(ebuf, used + remain + 5))
- /* for "<used>\\nnn<remain>\0" */
- return 0;
-
- ADD('\\');
- switch (c) {
- case '\t': ADD('t'); break;
- case '\n': ADD('n'); break;
- case '\r': ADD('r'); break;
- case '\\': ADD('\\'); break;
- default:
- if (c < 010) ADDF("%03o", c);
- else ADDF("x%02x", c);
- }
- }
-
- ADD(0);
- assert(used <= ebuf->avail);
- return ebuf->buf;
-
-#undef ADD
-#undef ADDF
-}
-
-void unsanitise_value(char *out, unsigned *out_len_r, const char *in)
-{
- const char *ip;
- char *op;
- unsigned c;
- int n;
-
- for (ip = in, op = out; (c = *ip++); *op++ = c) {
- if (c == '\\') {
- c = *ip++;
-
-#define GETF(f) do { \
- n = 0; \
- sscanf(ip, f "%n", &c, &n); \
- ip += n; \
- } while (0)
-
- switch (c) {
- case 't': c= '\t'; break;
- case 'n': c= '\n'; break;
- case 'r': c= '\r'; break;
- case '\\': c= '\\'; break;
- case 'x': GETF("%2x"); break;
- case '0': case '4':
- case '1': case '5':
- case '2': case '6':
- case '3': case '7': --ip; GETF("%3o"); break;
- case 0: --ip; break;
- default:;
- }
-#undef GETF
- }
- }
-
- *op = 0;
-
- if (out_len_r)
- *out_len_r = op - out;
-}
-
/*
* Local variables:
* mode: C
diff --git a/tools/xenstore/Makefile b/tools/xenstore/Makefile
index ab89e22d3a..01c9ccc70f 100644
--- a/tools/xenstore/Makefile
+++ b/tools/xenstore/Makefile
@@ -78,8 +78,8 @@ xenstored.a: $(XENSTORED_OBJS)
$(CLIENTS): xenstore
ln -f xenstore $@
-xenstore: xenstore_client.o
- $(CC) $< $(LDFLAGS) $(LDLIBS_libxenstore) $(LDLIBS_libxentoolcore)
$(SOCKET_LIBS) -o $@ $(APPEND_LDFLAGS)
+xenstore: xenstore_client.o xs_lib.o
+ $(CC) $^ $(LDFLAGS) $(LDLIBS_libxenstore) $(LDLIBS_libxentoolcore)
$(SOCKET_LIBS) -o $@ $(APPEND_LDFLAGS)
xenstore-control: xenstore_control.o
$(CC) $< $(LDFLAGS) $(LDLIBS_libxenstore) $(LDLIBS_libxenctrl)
$(LDLIBS_libxenguest) $(LDLIBS_libxentoolcore) $(SOCKET_LIBS) -o $@
$(APPEND_LDFLAGS)
diff --git a/tools/xenstore/utils.h b/tools/xenstore/utils.h
index 87713a8e5d..9d012b97c1 100644
--- a/tools/xenstore/utils.h
+++ b/tools/xenstore/utils.h
@@ -7,6 +7,17 @@
#include <xen-tools/libs.h>
+#include "xenstore_lib.h"
+
+/* Header of the node record in tdb. */
+struct xs_tdb_record_hdr {
+ uint64_t generation;
+ uint32_t num_perms;
+ uint32_t datalen;
+ uint32_t childlen;
+ struct xs_permissions perms[0];
+};
+
/* Is A == B ? */
#define streq(a,b) (strcmp((a),(b)) == 0)
diff --git a/tools/xenstore/xenstore_client.c b/tools/xenstore/xenstore_client.c
index ddbafc5175..0628ba275e 100644
--- a/tools/xenstore/xenstore_client.c
+++ b/tools/xenstore/xenstore_client.c
@@ -22,6 +22,8 @@
#include <sys/ioctl.h>
+#include "xs_lib.h"
+
#define PATH_SEP '/'
#define MAX_PATH_LEN 256
diff --git a/tools/xenstore/xenstored_control.c b/tools/xenstore/xenstored_control.c
index 52d4817679..995f671f35 100644
--- a/tools/xenstore/xenstored_control.c
+++ b/tools/xenstore/xenstored_control.c
@@ -34,6 +34,7 @@
#include "utils.h"
#include "talloc.h"
+#include "xs_lib.h"
#include "xenstored_core.h"
#include "xenstored_control.h"
#include "xenstored_domain.h"
diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 02ae390e25..4b7b71cfb3 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -46,7 +46,7 @@
#include "utils.h"
#include "list.h"
#include "talloc.h"
-#include "xenstore_lib.h"
+#include "xs_lib.h"
#include "xenstored_core.h"
#include "xenstored_watch.h"
#include "xenstored_transaction.h"
@@ -542,11 +542,11 @@ static int write_node(struct connection *conn, struct
node *node,
return write_node_raw(conn, &key, node, no_quota_check);
}
-enum xs_perm_type perm_for_conn(struct connection *conn,
- const struct node_perms *perms)
+unsigned int perm_for_conn(struct connection *conn,
+ const struct node_perms *perms)
{
unsigned int i;
- enum xs_perm_type mask = XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER;
+ unsigned int mask = XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER;
/* Owners and tools get it all... */
if (!domain_is_unprivileged(conn) || perms->p[0].id == conn->id
@@ -584,7 +584,7 @@ char *get_parent(const void *ctx, const char *node)
* Temporary memory allocations are done with ctx.
*/
static int ask_parents(struct connection *conn, const void *ctx,
- const char *name, enum xs_perm_type *perm)
+ const char *name, unsigned int *perm)
{
struct node *node;
@@ -618,10 +618,9 @@ static int ask_parents(struct connection *conn, const void *ctx,
* Temporary memory allocations are done with ctx.
*/
static int errno_from_parents(struct connection *conn, const void *ctx,
- const char *node, int errnum,
- enum xs_perm_type perm)
+ const char *node, int errnum, unsigned int perm)
{
- enum xs_perm_type parent_perm = XS_PERM_NONE;
+ unsigned int parent_perm = XS_PERM_NONE;
/* We always tell them about memory failures. */
if (errnum == ENOMEM)
@@ -641,7 +640,7 @@ static int errno_from_parents(struct connection *conn,
const void *ctx,
static struct node *get_node(struct connection *conn,
const void *ctx,
const char *name,
- enum xs_perm_type perm)
+ unsigned int perm)
{
struct node *node;
@@ -873,7 +872,7 @@ static struct node *get_node_canonicalized(struct connection *conn,
const void *ctx,
const char *name,
char **canonical_name,
- enum xs_perm_type perm)
+ unsigned int perm)
{
char *tmp_name;
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index b50ea3f57d..6a6d0448e8 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -185,8 +185,8 @@ void send_ack(struct connection *conn, enum
xsd_sockmsg_type type);
char *canonicalize(struct connection *conn, const void *ctx, const char
*node);
/* Get access permissions. */
-enum xs_perm_type perm_for_conn(struct connection *conn,
- const struct node_perms *perms);
+unsigned int perm_for_conn(struct connection *conn,
+ const struct node_perms *perms);
/* Write a node to the tdb data base. */
int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
@@ -200,8 +200,6 @@ struct connection *new_connection(connwritefn_t *write,
connreadfn_t *read);
struct connection *get_connection_by_id(unsigned int conn_id);
void check_store(void);
void corrupt(struct connection *conn, const char *fmt, ...);
-enum xs_perm_type perm_for_conn(struct connection *conn,
- const struct node_perms *perms);
/* Is this a valid node name? */
bool is_valid_nodename(const char *node);
diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c
index db89e0141f..aca0a71bad 100644
--- a/tools/xenstore/xenstored_watch.c
+++ b/tools/xenstore/xenstored_watch.c
@@ -124,7 +124,7 @@ static bool watch_permitted(struct connection *conn, const
void *ctx,
const char *name, struct node *node,
struct node_perms *perms)
{
- enum xs_perm_type perm;
+ unsigned int perm;
struct node *parent;
char *parent_name;
diff --git a/tools/xenstore/xs_lib.c b/tools/xenstore/xs_lib.c
index 80c03acbea..10fa4c3ad0 100644
--- a/tools/xenstore/xs_lib.c
+++ b/tools/xenstore/xs_lib.c
@@ -16,12 +16,13 @@
License along with this library; If not, see
<http://www.gnu.org/licenses/>.
*/
+#include <assert.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
-#include "xenstore_lib.h"
+#include "xs_lib.h"
/* Common routines for the Xen store daemon and client library. */
@@ -179,3 +180,114 @@ unsigned int xs_count_strings(const char *strings, unsigned int len)
return num;
}
+
+char *expanding_buffer_ensure(struct expanding_buffer *ebuf, int min_avail)
+{
+ int want;
+ char *got;
+
+ if (ebuf->avail >= min_avail)
+ return ebuf->buf;
+
+ if (min_avail >= INT_MAX/3)
+ return 0;
+
+ want = ebuf->avail + min_avail + 10;
+ got = realloc(ebuf->buf, want);
+ if (!got)
+ return 0;
+
+ ebuf->buf = got;
+ ebuf->avail = want;
+ return ebuf->buf;
+}
+
+char *sanitise_value(struct expanding_buffer *ebuf,
+ const char *val, unsigned len)
+{
+ int used, remain, c;
+ unsigned char *ip;
+
+#define ADD(c) (ebuf->buf[used++] = (c))
+#define ADDF(f,c) (used += sprintf(ebuf->buf+used, (f), (c)))
+
+ assert(len < INT_MAX/5);
+
+ ip = (unsigned char *)val;
+ used = 0;
+ remain = len;
+
+ if (!expanding_buffer_ensure(ebuf, remain + 1))
+ return NULL;
+
+ while (remain-- > 0) {
+ c= *ip++;
+
+ if (c >= ' ' && c <= '~' && c != '\\') {
+ ADD(c);
+ continue;
+ }
+
+ if (!expanding_buffer_ensure(ebuf, used + remain + 5))
+ /* for "<used>\\nnn<remain>\0" */
+ return 0;
+
+ ADD('\\');
+ switch (c) {
+ case '\t': ADD('t'); break;
+ case '\n': ADD('n'); break;
+ case '\r': ADD('r'); break;
+ case '\\': ADD('\\'); break;
+ default:
+ if (c < 010) ADDF("%03o", c);
+ else ADDF("x%02x", c);
+ }
+ }
+
+ ADD(0);
+ assert(used <= ebuf->avail);
+ return ebuf->buf;
+
+#undef ADD
+#undef ADDF
+}
+
+void unsanitise_value(char *out, unsigned *out_len_r, const char *in)
+{
+ const char *ip;
+ char *op;
+ unsigned c;
+ int n;
+
+ for (ip = in, op = out; (c = *ip++); *op++ = c) {
+ if (c == '\\') {
+ c = *ip++;
+
+#define GETF(f) do { \
+ n = 0; \
+ sscanf(ip, f "%n", &c, &n); \
+ ip += n; \
+ } while (0)
+
+ switch (c) {
+ case 't': c= '\t'; break;
+ case 'n': c= '\n'; break;
+ case 'r': c= '\r'; break;
+ case '\\': c= '\\'; break;
+ case 'x': GETF("%2x"); break;
+ case '0': case '4':
+ case '1': case '5':
+ case '2': case '6':
+ case '3': case '7': --ip; GETF("%3o"); break;
+ case 0: --ip; break;
+ default:;
+ }
+#undef GETF
+ }
+ }
+
+ *op = 0;
+
+ if (out_len_r)
+ *out_len_r = op - out;
+}
diff --git a/tools/xenstore/xs_lib.h b/tools/xenstore/xs_lib.h
new file mode 100644
index 0000000000..efa05997d6
--- /dev/null
+++ b/tools/xenstore/xs_lib.h
@@ -0,0 +1,50 @@
+/*
+ Common routines between Xen store user library and daemon.
+ Copyright (C) 2005 Rusty Russell IBM Corporation
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; If not, see
<http://www.gnu.org/licenses/>.
+*/
+
+#ifndef XS_LIB_H
+#define XS_LIB_H
+
+#include "xenstore_lib.h"
+
+const char *xs_daemon_rootdir(void);
+const char *xs_domain_dev(void);
+const char *xs_daemon_tdb(void);
+
+/* Convert permissions to a string (up to len MAX_STRLEN(unsigned int)+1). */
+bool xs_perm_to_string(const struct xs_permissions *perm,
+ char *buffer, size_t buf_len);
+
+/* Given a string and a length, count how many strings (nul terms). */
+unsigned int xs_count_strings(const char *strings, unsigned int len);
+
+/* Sanitising (quoting) possibly-binary strings. */
+struct expanding_buffer {
+ char *buf;
+ int avail;
+};
+
+/* Ensure that given expanding buffer has at least min_avail characters. */
+char *expanding_buffer_ensure(struct expanding_buffer *, int min_avail);
+
+/* sanitise_value() may return NULL if malloc fails. */
+char *sanitise_value(struct expanding_buffer *, const char *val, unsigned len);
+
+/* *out_len_r on entry is ignored; out must be at least strlen(in)+1 bytes. */
+void unsanitise_value(char *out, unsigned *out_len_r, const char *in);
+
+#endif /* XS_LIB_H */
diff --git a/tools/xenstore/xs_tdb_dump.c b/tools/xenstore/xs_tdb_dump.c
index f74676cf1c..5d2db392b4 100644
--- a/tools/xenstore/xs_tdb_dump.c
+++ b/tools/xenstore/xs_tdb_dump.c
@@ -17,7 +17,7 @@ static uint32_t total_size(struct xs_tdb_record_hdr *hdr)
+ hdr->datalen + hdr->childlen;
}
-static char perm_to_char(enum xs_perm_type perm)
+static char perm_to_char(unsigned int perm)
{
return perm == XS_PERM_READ ? 'r' :
perm == XS_PERM_WRITE ? 'w' :