From 1533521bff4121dcd8dc37ef34fd09fc6a5018fb Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 29 Nov 2012 20:22:58 +0100 Subject: loadenv: allow more fine grained environment loading This implements two new options for the loadenv command: -s: removes (scrubs) old directory contents to be able to create a fresh environment from for example /dev/defaultenv -n: no overwrite. Do not overwrite existing files. This allows to keep parts of the old environment. Signed-off-by: Sascha Hauer --- commands/loadenv.c | 53 +++++++++++++++++++++++++++++++++++++++++++++------ common/environment.c | 12 ++++++++++-- common/startup.c | 4 ++-- include/environment.h | 7 ++++--- scripts/bareboxenv.c | 2 +- 5 files changed, 64 insertions(+), 14 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 +#include #include #include +#include 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/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/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) -- cgit v1.2.3