diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2012-12-07 16:42:04 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2012-12-07 16:42:04 +0100 |
commit | e5373920525a82339b6818c2b9ffdcce81af2c1b (patch) | |
tree | ec16d65801687debbab06a0bb9855ab962d1b51d | |
parent | 4bdb250c9f40abcadd63a1eb86c9364c4ca9c0d7 (diff) | |
parent | 1533521bff4121dcd8dc37ef34fd09fc6a5018fb (diff) | |
download | barebox-e5373920525a82339b6818c2b9ffdcce81af2c1b.tar.gz barebox-e5373920525a82339b6818c2b9ffdcce81af2c1b.tar.xz |
Merge branch 'for-next/commands'
-rw-r--r-- | commands/loadenv.c | 53 | ||||
-rw-r--r-- | commands/rm.c | 28 | ||||
-rw-r--r-- | common/environment.c | 12 | ||||
-rw-r--r-- | common/startup.c | 4 | ||||
-rw-r--r-- | include/environment.h | 7 | ||||
-rw-r--r-- | include/fs.h | 2 | ||||
-rw-r--r-- | lib/Makefile | 1 | ||||
-rw-r--r-- | lib/recursive_action.c | 1 | ||||
-rw-r--r-- | lib/unlink-recursive.c | 56 | ||||
-rw-r--r-- | scripts/bareboxenv.c | 2 |
10 files changed, 147 insertions, 19 deletions
diff --git a/commands/loadenv.c b/commands/loadenv.c index 5bf17406b2..48284d7a03 100644 --- a/commands/loadenv.c +++ b/commands/loadenv.c @@ -21,27 +21,68 @@ */ #include <common.h> +#include <getopt.h> #include <command.h> #include <environment.h> +#include <fs.h> static int do_loadenv(int argc, char *argv[]) { char *filename, *dirname; + unsigned flags = 0; + int opt; + int scrub = 0; - if (argc < 3) + while ((opt = getopt(argc, argv, "ns")) > 0) { + switch (opt) { + case 'n': + flags |= ENV_FLAG_NO_OVERWRITE; + break; + case 's': + scrub = 1; + break; + default: + return COMMAND_ERROR_USAGE; + } + } + + if (argc - optind < 2) dirname = "/env"; else - dirname = argv[2]; - if (argc < 2) + dirname = argv[optind + 1]; + + if (argc - optind < 1) filename = default_environment_path; else - filename = argv[1]; + filename = argv[optind]; + + if (scrub) { + int ret; + + ret = unlink_recursive(dirname, NULL); + if (ret) { + eprintf("cannot remove %s: %s\n", dirname, + strerror(-ret)); + return 1; + } + + ret = mkdir(dirname, 0); + if (ret) { + eprintf("cannot create %s: %s\n", dirname, + strerror(-ret)); + return ret; + } + } + printf("loading environment from %s\n", filename); - return envfs_load(filename, dirname); + + return envfs_load(filename, dirname, flags); } BAREBOX_CMD_HELP_START(loadenv) -BAREBOX_CMD_HELP_USAGE("loadenv [ENVFS] [DIRECTORY]\n") +BAREBOX_CMD_HELP_USAGE("loadenv OPTIONS [ENVFS] [DIRECTORY]\n") +BAREBOX_CMD_HELP_OPT("-n", "do not overwrite existing files\n") +BAREBOX_CMD_HELP_OPT("-s", "scrub old environment\n") BAREBOX_CMD_HELP_SHORT("Load environment from ENVFS into DIRECTORY (default: /dev/env0 -> /env).\n") BAREBOX_CMD_HELP_END diff --git a/commands/rm.c b/commands/rm.c index 4e765acf7a..5486005d9b 100644 --- a/commands/rm.c +++ b/commands/rm.c @@ -19,17 +19,36 @@ #include <common.h> #include <command.h> #include <fs.h> +#include <getopt.h> #include <errno.h> static int do_rm(int argc, char *argv[]) { - int i = 1; + int i, opt, recursive = 0; + + while ((opt = getopt(argc, argv, "r")) > 0) { + switch (opt) { + case 'r': + recursive = 1; + break; + default: + return COMMAND_ERROR_USAGE; + } + } if (argc < 2) return COMMAND_ERROR_USAGE; + i = optind; + while (i < argc) { - if (unlink(argv[i])) { + int ret; + + if (recursive) + ret = unlink_recursive(argv[i], NULL); + else + ret = unlink(argv[i]); + if (ret) { printf("could not remove %s: %s\n", argv[i], errno_str()); return 1; } @@ -40,8 +59,9 @@ static int do_rm(int argc, char *argv[]) } static const __maybe_unused char cmd_rm_help[] = -"Usage: rm [FILES]\n" -"Remove files\n"; +"Usage: rm [OPTIONS] [FILES]\n" +"Remove files\n" +"-r remove directories and their contents recursively\n"; BAREBOX_CMD_START(rm) .cmd = do_rm, diff --git a/common/environment.c b/common/environment.c index 69c4c0aa76..e11cd9dd47 100644 --- a/common/environment.c +++ b/common/environment.c @@ -206,7 +206,7 @@ EXPORT_SYMBOL(envfs_save); * Note: This function will also be used on the host! See note in the header * of this file. */ -int envfs_load(char *filename, char *dir) +int envfs_load(char *filename, char *dir, unsigned flags) { struct envfs_super super; void *buf = NULL, *buf_free = NULL; @@ -316,6 +316,14 @@ int envfs_load(char *filename, char *dir) } free(str); } else { + struct stat s; + + if (flags & ENV_FLAG_NO_OVERWRITE && + !stat(str, &s)) { + printf("skip %s\n", str); + goto skip; + } + fd = open(str, O_WRONLY | O_CREAT | O_TRUNC, 0644); free(str); if (fd < 0) { @@ -333,7 +341,7 @@ int envfs_load(char *filename, char *dir) } close(fd); } - +skip: buf += PAD4(inode_size); size -= headerlen_full + PAD4(inode_size) + sizeof(struct envfs_inode); diff --git a/common/startup.c b/common/startup.c index 7bb3c73c12..14409a217d 100644 --- a/common/startup.c +++ b/common/startup.c @@ -108,12 +108,12 @@ void start_barebox (void) debug("initcalls done\n"); #ifdef CONFIG_ENV_HANDLING - if (envfs_load(default_environment_path, "/env")) { + if (envfs_load(default_environment_path, "/env", 0)) { #ifdef CONFIG_DEFAULT_ENVIRONMENT printf("no valid environment found on %s. " "Using default environment\n", default_environment_path); - envfs_load("/dev/defaultenv", "/env"); + envfs_load("/dev/defaultenv", "/env", 0); #endif } #endif diff --git a/include/environment.h b/include/environment.h index 4184977009..096c1697c4 100644 --- a/include/environment.h +++ b/include/environment.h @@ -75,9 +75,6 @@ int env_push_context(void); /* defaults to /dev/env0 */ extern char *default_environment_path; -int envfs_load(char *filename, char *dirname); -int envfs_save(char *filename, char *dirname); - int export(const char *); struct stat; @@ -86,6 +83,10 @@ int file_save_action(const char *, struct stat *, void *, int); #endif /* __BAREBOX__ */ +#define ENV_FLAG_NO_OVERWRITE (1 << 0) +int envfs_load(char *filename, char *dirname, unsigned flags); +int envfs_save(char *filename, char *dirname); + /* This part is used for the host and the target */ struct action_data { int fd; diff --git a/include/fs.h b/include/fs.h index 3d5714c1fb..8ff7300919 100644 --- a/include/fs.h +++ b/include/fs.h @@ -182,4 +182,6 @@ void automount_remove(const char *_path); int automount_add(const char *path, const char *cmd); void automount_print(void); +int unlink_recursive(const char *path, char **failedpath); + #endif /* __FS_H */ diff --git a/lib/Makefile b/lib/Makefile index eb0af9248e..635d52e653 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -36,3 +36,4 @@ obj-$(CONFIG_BITREV) += bitrev.o obj-$(CONFIG_QSORT) += qsort.o obj-y += gui/ obj-$(CONFIG_XYMODEM) += xymodem.o +obj-y += unlink-recursive.o diff --git a/lib/recursive_action.c b/lib/recursive_action.c index 5bc2595db9..345d3db0ce 100644 --- a/lib/recursive_action.c +++ b/lib/recursive_action.c @@ -130,7 +130,6 @@ int recursive_action(const char *fileName, return 0; return 1; done_nak_warn: - printf("%s", fileName); return 0; } diff --git a/lib/unlink-recursive.c b/lib/unlink-recursive.c new file mode 100644 index 0000000000..a4885538c0 --- /dev/null +++ b/lib/unlink-recursive.c @@ -0,0 +1,56 @@ +#include <common.h> +#include <libbb.h> +#include <fs.h> + +static char unlink_recursive_failedpath[PATH_MAX]; + +struct data { + int error; +}; + +static int file_action(const char *filename, struct stat *statbuf, + void *userdata, int depth) +{ + struct data *data = userdata; + int ret; + + ret = unlink(filename); + if (ret) { + strcpy(unlink_recursive_failedpath, filename); + data->error = ret; + } + + return ret ? 0 : 1; +} + +static int dir_action(const char *dirname, struct stat *statbuf, + void *userdata, int depth) +{ + struct data *data = userdata; + int ret; + + ret = rmdir(dirname); + if (ret) { + strcpy(unlink_recursive_failedpath, dirname); + data->error = ret; + } + + return ret ? 0 : 1; +} + +int unlink_recursive(const char *path, char **failedpath) +{ + struct data data = {}; + int ret; + + if (failedpath) + *failedpath = NULL; + + ret = recursive_action(path, ACTION_RECURSE | ACTION_DEPTHFIRST, + file_action, dir_action, &data, 0); + + if (!ret && failedpath) + *failedpath = unlink_recursive_failedpath; + + return ret ? 0 : errno; +} diff --git a/scripts/bareboxenv.c b/scripts/bareboxenv.c index 5fdc62e238..707d63dd81 100644 --- a/scripts/bareboxenv.c +++ b/scripts/bareboxenv.c @@ -191,7 +191,7 @@ int main(int argc, char *argv[]) if (load) { if (verbose) printf("loading env from file %s to %s\n", filename, dirname); - envfs_load(filename, dirname); + envfs_load(filename, dirname, 0); } if (save) { if (verbose) |