[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] Added --tidy flag to xenstore-rm that recursively removes any empty directories



# HG changeset patch
# User emellor@xxxxxxxxxxxxxxxxxxxxxx
# Node ID bb127c984f740a23e8314168436cdba0e2752f05
# Parent  fd7b8b0514667457cdb036fb62aedda57564bfd7
Added --tidy flag to xenstore-rm that recursively removes any empty directories
left by the primary removal.

Signed-off-by: Ewan Mellor <ewan@xxxxxxxxxxxxx>

diff -r fd7b8b051466 -r bb127c984f74 tools/xenstore/xenstore_client.c
--- a/tools/xenstore/xenstore_client.c  Sat Oct 15 08:32:10 2005
+++ b/tools/xenstore/xenstore_client.c  Sat Oct 15 11:52:38 2005
@@ -24,15 +24,32 @@
     errx(1, "Usage: %s [-h] [-p] [-s] key [...]", progname);
 #elif defined(CLIENT_write)
     errx(1, "Usage: %s [-h] [-s] key value [...]", progname);
-#elif defined(CLIENT_rm) || defined(CLIENT_exists) || defined(CLIENT_list)
+#elif defined(CLIENT_rm)
+    errx(1, "Usage: %s [-h] [-s] [-t] key [...]", progname);
+#elif defined(CLIENT_exists) || defined(CLIENT_list)
     errx(1, "Usage: %s [-h] [-s] key [...]", progname);
 #endif
 }
+
+
+#if defined(CLIENT_rm)
+static int
+do_rm(char * path, struct xs_handle *xsh, struct xs_transaction_handle *xth)
+{
+    if (xs_rm(xsh, xth, path)) {
+        return 0;
+    }
+    else {
+        warnx("could not remove path %s", path);
+        return 1;
+    }
+}
+#endif
 
 
 static int
 perform(int optind, int argc, char **argv, struct xs_handle *xsh,
-        struct xs_transaction_handle *xth, int prefix)
+        struct xs_transaction_handle *xth, int prefix, int tidy)
 {
     while (optind < argc) {
 #if defined(CLIENT_read)
@@ -54,10 +71,49 @@
        }
        optind += 2;
 #elif defined(CLIENT_rm)
-       if (!xs_rm(xsh, xth, argv[optind])) {
-           warnx("could not remove path %s", argv[optind]);
-           return 1;
-       }
+        /* Remove the specified path.  If the tidy flag is set, then also
+           remove any containing directories that are both empty and have no
+           value attached, and repeat, recursing all the way up to the root if
+           necessary.
+        */
+
+        char *path = argv[optind];
+
+        if (tidy) {
+            /* Copy path, because we can't modify argv because we will need it
+               again if xs_transaction_end gives us EAGAIN. */
+            char *p = malloc(strlen(path) + 1);
+            strcpy(p, path);
+            path = p;
+
+        again:
+            if (do_rm(path, xsh, xth)) {
+                return 1;
+            }
+
+            char *slash = strrchr(p, '/');
+            if (slash) {
+                char *val;
+                *slash = '\0';
+                val = xs_read(xsh, xth, p, NULL);
+                if (val && strlen(val) == 0) {
+                    unsigned int num;
+                    char ** list = xs_directory(xsh, xth, p, &num);
+
+                    if (list && num == 0) {
+                        goto again;
+                    }
+                }
+            }
+
+            free(path);
+        }
+        else {
+            if (do_rm(path, xsh, xth)) {
+                return 1;
+            }
+        }
+
        optind++;
 #elif defined(CLIENT_exists)
        char *val = xs_read(xsh, xth, argv[optind], NULL);
@@ -94,21 +150,26 @@
     struct xs_transaction_handle *xth;
     int ret = 0, socket = 0;
     int prefix = 0;
+    int tidy = 0;
 
     while (1) {
        int c, index = 0;
        static struct option long_options[] = {
            {"help", 0, 0, 'h'},
+            {"socket", 0, 0, 's'},
 #if defined(CLIENT_read) || defined(CLIENT_list)
            {"prefix", 0, 0, 'p'},
-#endif
-            {"socket", 0, 0, 's'},
+#elif defined(CLIENT_rm)
+            {"tidy",   0, 0, 't'},
+#endif
            {0, 0, 0, 0}
        };
 
        c = getopt_long(argc, argv, "hs"
 #if defined(CLIENT_read) || defined(CLIENT_list)
                        "p"
+#elif defined(CLIENT_rm)
+                        "t"
 #endif
                        , long_options, &index);
        if (c == -1)
@@ -125,6 +186,10 @@
        case 'p':
            prefix = 1;
            break;
+#elif defined(CLIENT_rm)
+       case 't':
+           tidy = 1;
+           break;
 #endif
        }
     }
@@ -149,7 +214,7 @@
     if (xth == NULL)
        errx(1, "couldn't start transaction");
 
-    ret = perform(optind, argc, argv, xsh, xth, prefix);
+    ret = perform(optind, argc, argv, xsh, xth, prefix, tidy);
 
     if (!xs_transaction_end(xsh, xth, ret)) {
        if (ret == 0 && errno == EAGAIN)

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.