# 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
|