The xenstore wire command argument parsing of the different commands
is repeating some patterns multiple times. Add some helper functions
to avoid the duplicated code.

Signed-off-by: Juergen Gross <jgr...@suse.com>
---
 tools/xenstore/xenstored_core.c   | 66 ++++++++++++++--------------
 tools/xenstore/xenstored_domain.c | 90 +++++++++++++++++++--------------------
 2 files changed, 77 insertions(+), 79 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 3faab6e..c7a7c45 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -745,13 +745,25 @@ char *canonicalize(struct connection *conn, const char 
*node)
        return (char *)node;
 }
 
+static struct node *get_node_canonicalized(struct connection *conn,
+                                          const void *ctx,
+                                          const char *name,
+                                          char **canonical_name,
+                                          enum xs_perm_type perm)
+{
+       char *tmp_name;
+
+       if (!canonical_name)
+               canonical_name = &tmp_name;
+       *canonical_name = canonicalize(conn, name);
+       return get_node(conn, ctx, *canonical_name, perm);
+}
+
 static int send_directory(struct connection *conn, struct buffered_data *in)
 {
        struct node *node;
-       const char *name = onearg(in);
 
-       name = canonicalize(conn, name);
-       node = get_node(conn, in, name, XS_PERM_READ);
+       node = get_node_canonicalized(conn, in, onearg(in), NULL, XS_PERM_READ);
        if (!node)
                return errno;
 
@@ -764,7 +776,7 @@ static int send_directory_part(struct connection *conn,
                               struct buffered_data *in)
 {
        unsigned int off, len, maxlen, genlen;
-       char *name, *child, *data;
+       char *child, *data;
        struct node *node;
        char gen[24];
 
@@ -772,15 +784,13 @@ static int send_directory_part(struct connection *conn,
                return EINVAL;
 
        /* First arg is node name. */
-       name = canonicalize(conn, in->buffer);
+       node = get_node_canonicalized(conn, in, in->buffer, NULL, XS_PERM_READ);
+       if (!node)
+               return errno;
 
        /* Second arg is childlist offset. */
        off = atoi(in->buffer + strlen(in->buffer) + 1);
 
-       node = get_node(conn, in, name, XS_PERM_READ);
-       if (!node)
-               return errno;
-
        genlen = snprintf(gen, sizeof(gen), "%"PRIu64, node->generation) + 1;
 
        /* Offset behind list: just return a list with an empty string. */
@@ -820,10 +830,8 @@ static int send_directory_part(struct connection *conn,
 static int do_read(struct connection *conn, struct buffered_data *in)
 {
        struct node *node;
-       const char *name = onearg(in);
 
-       name = canonicalize(conn, name);
-       node = get_node(conn, in, name, XS_PERM_READ);
+       node = get_node_canonicalized(conn, in, onearg(in), NULL, XS_PERM_READ);
        if (!node)
                return errno;
 
@@ -962,8 +970,7 @@ static int do_write(struct connection *conn, struct 
buffered_data *in)
        offset = strlen(vec[0]) + 1;
        datalen = in->used - offset;
 
-       name = canonicalize(conn, vec[0]);
-       node = get_node(conn, in, name, XS_PERM_WRITE);
+       node = get_node_canonicalized(conn, in, vec[0], &name, XS_PERM_WRITE);
        if (!node) {
                /* No permissions, invalid input? */
                if (errno != ENOENT)
@@ -987,13 +994,10 @@ static int do_write(struct connection *conn, struct 
buffered_data *in)
 static int do_mkdir(struct connection *conn, struct buffered_data *in)
 {
        struct node *node;
-       const char *name = onearg(in);
+       char *name;
 
-       if (!name)
-               return EINVAL;
-
-       name = canonicalize(conn, name);
-       node = get_node(conn, in, name, XS_PERM_WRITE);
+       node = get_node_canonicalized(conn, in, onearg(in), &name,
+                                     XS_PERM_WRITE);
 
        /* If it already exists, fine. */
        if (!node) {
@@ -1103,10 +1107,10 @@ static int do_rm(struct connection *conn, struct 
buffered_data *in)
 {
        struct node *node;
        int ret;
-       const char *name = onearg(in);
+       char *name;
 
-       name = canonicalize(conn, name);
-       node = get_node(conn, in, name, XS_PERM_WRITE);
+       node = get_node_canonicalized(conn, in, onearg(in), &name,
+                                     XS_PERM_WRITE);
        if (!node) {
                /* Didn't exist already?  Fine, if parent exists. */
                if (errno == ENOENT) {
@@ -1138,12 +1142,10 @@ static int do_rm(struct connection *conn, struct 
buffered_data *in)
 static int do_get_perms(struct connection *conn, struct buffered_data *in)
 {
        struct node *node;
-       const char *name = onearg(in);
        char *strings;
        unsigned int len;
 
-       name = canonicalize(conn, name);
-       node = get_node(conn, in, name, XS_PERM_READ);
+       node = get_node_canonicalized(conn, in, onearg(in), NULL, XS_PERM_READ);
        if (!node)
                return errno;
 
@@ -1168,15 +1170,15 @@ static int do_set_perms(struct connection *conn, struct 
buffered_data *in)
                return EINVAL;
 
        /* First arg is node name. */
-       name = canonicalize(conn, in->buffer);
+       /* We must own node to do this (tools can do this too). */
+       node = get_node_canonicalized(conn, in, in->buffer, &name,
+                                     XS_PERM_WRITE | XS_PERM_OWNER);
+       if (!node)
+               return errno;
+
        permstr = in->buffer + strlen(in->buffer) + 1;
        num--;
 
-       /* We must own node to do this (tools can do this too). */
-       node = get_node(conn, in, name, XS_PERM_WRITE|XS_PERM_OWNER);
-       if (!node)
-               return errno;
-
        perms = talloc_array(node, struct xs_permissions, num);
        if (!xs_strings_to_perms(perms, num, permstr))
                return errno;
diff --git a/tools/xenstore/xenstored_domain.c 
b/tools/xenstore/xenstored_domain.c
index 0b2af13..2443b08 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -399,6 +399,18 @@ int do_introduce(struct connection *conn, struct 
buffered_data *in)
        return 0;
 }
 
+static struct domain *find_connected_domain(unsigned int domid)
+{
+       struct domain *domain;
+
+       domain = find_domain_by_domid(domid);
+       if (!domain)
+               return ERR_PTR(-ENOENT);
+       if (!domain->conn)
+               return ERR_PTR(-EINVAL);
+       return domain;
+}
+
 int do_set_target(struct connection *conn, struct buffered_data *in)
 {
        char *vec[2];
@@ -413,18 +425,13 @@ int do_set_target(struct connection *conn, struct 
buffered_data *in)
        domid = atoi(vec[0]);
        tdomid = atoi(vec[1]);
 
-        domain = find_domain_by_domid(domid);
-       if (!domain)
-               return ENOENT;
-        if (!domain->conn)
-               return EINVAL;
+        domain = find_connected_domain(domid);
+       if (IS_ERR(domain))
+               return -PTR_ERR(domain);
 
-        tdomain = find_domain_by_domid(tdomid);
-       if (!tdomain)
-               return ENOENT;
-
-        if (!tdomain->conn)
-               return EINVAL;
+        tdomain = find_connected_domain(tdomid);
+       if (IS_ERR(tdomain))
+               return -PTR_ERR(tdomain);
 
         talloc_reference(domain->conn, tdomain->conn);
         domain->conn->target = tdomain->conn;
@@ -434,29 +441,33 @@ int do_set_target(struct connection *conn, struct 
buffered_data *in)
        return 0;
 }
 
+static struct domain *onearg_domain(struct connection *conn,
+                                   struct buffered_data *in)
+{
+       const char *domid_str = onearg(in);
+       unsigned int domid;
+
+       if (!domid_str)
+               return ERR_PTR(-EINVAL);
+
+       domid = atoi(domid_str);
+       if (!domid)
+               return ERR_PTR(-EINVAL);
+
+       if (domain_is_unprivileged(conn))
+               return ERR_PTR(-EACCES);
+
+       return find_connected_domain(domid);
+}
+
 /* domid */
 int do_release(struct connection *conn, struct buffered_data *in)
 {
-       const char *domid_str = onearg(in);
        struct domain *domain;
-       unsigned int domid;
 
-       if (!domid_str)
-               return EINVAL;
-
-       domid = atoi(domid_str);
-       if (!domid)
-               return EINVAL;
-
-       if (domain_is_unprivileged(conn))
-               return EACCES;
-
-       domain = find_domain_by_domid(domid);
-       if (!domain)
-               return ENOENT;
-
-       if (!domain->conn)
-               return EINVAL;
+       domain = onearg_domain(conn, in);
+       if (IS_ERR(domain))
+               return -PTR_ERR(domain);
 
        talloc_free(domain->conn);
 
@@ -468,25 +479,10 @@ int do_release(struct connection *conn, struct 
buffered_data *in)
 int do_resume(struct connection *conn, struct buffered_data *in)
 {
        struct domain *domain;
-       unsigned int domid;
-       const char *domid_str = onearg(in);
 
-       if (!domid_str)
-               return EINVAL;
-
-       domid = atoi(domid_str);
-       if (!domid)
-               return EINVAL;
-
-       if (domain_is_unprivileged(conn))
-               return EACCES;
-
-       domain = find_domain_by_domid(domid);
-       if (!domain)
-               return ENOENT;
-
-       if (!domain->conn)
-               return EINVAL;
+       domain = onearg_domain(conn, in);
+       if (IS_ERR(domain))
+               return -PTR_ERR(domain);
 
        domain->shutdown = 0;
        
-- 
2.6.6


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

Reply via email to