diff options
author | emellor@leeni.uk.xensource.com <emellor@leeni.uk.xensource.com> | 2005-10-15 12:52:38 +0100 |
---|---|---|
committer | emellor@leeni.uk.xensource.com <emellor@leeni.uk.xensource.com> | 2005-10-15 12:52:38 +0100 |
commit | 9f7fae040f0dda775703f4c5f3731230bd5f6f68 (patch) | |
tree | 5b7c2196489cd6d32eb20db964ef830ed43d6e74 /tools/xenstore/xenstore_client.c | |
parent | a9634a6106b5ea444557428333dd717e861b2b8c (diff) | |
download | xen-9f7fae040f0dda775703f4c5f3731230bd5f6f68.tar.gz xen-9f7fae040f0dda775703f4c5f3731230bd5f6f68.tar.bz2 xen-9f7fae040f0dda775703f4c5f3731230bd5f6f68.zip |
Added --tidy flag to xenstore-rm that recursively removes any empty directories
left by the primary removal.
Signed-off-by: Ewan Mellor <ewan@xensource.com>
Diffstat (limited to 'tools/xenstore/xenstore_client.c')
-rw-r--r-- | tools/xenstore/xenstore_client.c | 81 |
1 files changed, 73 insertions, 8 deletions
diff --git a/tools/xenstore/xenstore_client.c b/tools/xenstore/xenstore_client.c index f70f95557c..d18b2de5e1 100644 --- a/tools/xenstore/xenstore_client.c +++ b/tools/xenstore/xenstore_client.c @@ -24,15 +24,32 @@ usage(const char *progname) 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 @@ perform(int optind, int argc, char **argv, struct xs_handle *xsh, } 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 @@ main(int argc, char **argv) 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'}, +#elif defined(CLIENT_rm) + {"tidy", 0, 0, 't'}, #endif - {"socket", 0, 0, 's'}, {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 @@ main(int argc, char **argv) case 'p': prefix = 1; break; +#elif defined(CLIENT_rm) + case 't': + tidy = 1; + break; #endif } } @@ -149,7 +214,7 @@ main(int argc, char **argv) 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) |