[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |