* [PATCH 1/2] rm: implement -r
@ 2012-11-29 19:27 Sascha Hauer
2012-11-29 19:27 ` [PATCH 2/2] loadenv: allow more fine grained environment loading Sascha Hauer
0 siblings, 1 reply; 2+ messages in thread
From: Sascha Hauer @ 2012-11-29 19:27 UTC (permalink / raw)
To: barebox
To recursively remove files and directories.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
commands/rm.c | 28 ++++++++++++++++++++----
include/fs.h | 2 ++
lib/Makefile | 1 +
lib/recursive_action.c | 1 -
lib/unlink-recursive.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 83 insertions(+), 5 deletions(-)
create mode 100644 lib/unlink-recursive.c
diff --git a/commands/rm.c b/commands/rm.c
index 4e765ac..5486005 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/include/fs.h b/include/fs.h
index 3d5714c..8ff7300 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 eb0af92..635d52e 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 5bc2595..345d3db 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 0000000..a488553
--- /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;
+}
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 2+ messages in thread
* [PATCH 2/2] loadenv: allow more fine grained environment loading
2012-11-29 19:27 [PATCH 1/2] rm: implement -r Sascha Hauer
@ 2012-11-29 19:27 ` Sascha Hauer
0 siblings, 0 replies; 2+ messages in thread
From: Sascha Hauer @ 2012-11-29 19:27 UTC (permalink / raw)
To: barebox
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 <s.hauer@pengutronix.de>
---
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 5bf1740..48284d7 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/common/environment.c b/common/environment.c
index 69c4c0a..e11cd9d 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 7bb3c73..14409a2 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 4184977..096c169 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 5fdc62e..707d63d 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)
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2012-11-29 19:27 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-11-29 19:27 [PATCH 1/2] rm: implement -r Sascha Hauer
2012-11-29 19:27 ` [PATCH 2/2] loadenv: allow more fine grained environment loading Sascha Hauer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox