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