summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2012-12-07 16:42:04 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2012-12-07 16:42:04 +0100
commite5373920525a82339b6818c2b9ffdcce81af2c1b (patch)
treeec16d65801687debbab06a0bb9855ab962d1b51d
parent4bdb250c9f40abcadd63a1eb86c9364c4ca9c0d7 (diff)
parent1533521bff4121dcd8dc37ef34fd09fc6a5018fb (diff)
downloadbarebox-e5373920525a82339b6818c2b9ffdcce81af2c1b.tar.gz
barebox-e5373920525a82339b6818c2b9ffdcce81af2c1b.tar.xz
Merge branch 'for-next/commands'
-rw-r--r--commands/loadenv.c53
-rw-r--r--commands/rm.c28
-rw-r--r--common/environment.c12
-rw-r--r--common/startup.c4
-rw-r--r--include/environment.h7
-rw-r--r--include/fs.h2
-rw-r--r--lib/Makefile1
-rw-r--r--lib/recursive_action.c1
-rw-r--r--lib/unlink-recursive.c56
-rw-r--r--scripts/bareboxenv.c2
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)