summaryrefslogtreecommitdiffstats
path: root/commands
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2014-12-08 14:54:09 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2014-12-08 14:54:09 +0100
commit3eade89c7573f8893fe045290e374d4502092e13 (patch)
treedefd4218ff82053d44f54595af4e882ea7eb988a /commands
parentc2b5a7015b7323af4b7c8cf19a06b954f4f09949 (diff)
parent7962e7a0b423a5dfba251622f64d3891f69a55c0 (diff)
downloadbarebox-3eade89c7573f8893fe045290e374d4502092e13.tar.gz
barebox-3eade89c7573f8893fe045290e374d4502092e13.tar.xz
Merge branch 'for-next/persistent-vars'
Conflicts: arch/arm/boards/efika-mx-smartbook/defaultenv-efikasb/config
Diffstat (limited to 'commands')
-rw-r--r--commands/Kconfig21
-rw-r--r--commands/Makefile2
-rw-r--r--commands/cp.c36
-rw-r--r--commands/defaultenv.c95
-rw-r--r--commands/global.c5
-rw-r--r--commands/loadenv.c11
-rw-r--r--commands/magicvar.c111
-rw-r--r--commands/nv.c84
8 files changed, 336 insertions, 29 deletions
diff --git a/commands/Kconfig b/commands/Kconfig
index 52ba8b3822..2a73bf1f87 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -674,6 +674,20 @@ endmenu
menu "Environment"
+config CMD_NV
+ select GLOBALVAR
+ tristate
+ prompt "nv"
+ help
+ create, set or remove non volatile variables.
+
+ Usage: nv [-r] VAR[=VALUE]
+
+ Add a new config non volatile named VAR, optionally set to VALUE.
+
+ Options:
+ -r remove a non volatile variable
+
config CMD_EXPORT
depends on ENVIRONMENT_VARIABLES
tristate
@@ -685,6 +699,13 @@ config CMD_EXPORT
Export an environment variable to subsequently executed scripts.
+config CMD_DEFAULTENV
+ tristate
+ select ENV_HANDLING
+ prompt "defaultenv"
+ help
+ restore environment from default environment
+
config CMD_GLOBAL
select GLOBALVAR
tristate
diff --git a/commands/Makefile b/commands/Makefile
index be174969b0..99a65d4609 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -107,3 +107,5 @@ obj-$(CONFIG_CMD_HWCLOCK) += hwclock.o
obj-$(CONFIG_CMD_USBGADGET) += usbgadget.o
obj-$(CONFIG_CMD_FIRMWARELOAD) += firmwareload.o
obj-$(CONFIG_CMD_CMP) += cmp.o
+obj-$(CONFIG_CMD_NV) += nv.o
+obj-$(CONFIG_CMD_DEFAULTENV) += defaultenv.o
diff --git a/commands/cp.c b/commands/cp.c
index af7a3d4dc0..4f1c068dd6 100644
--- a/commands/cp.c
+++ b/commands/cp.c
@@ -39,14 +39,17 @@ static int do_cp(int argc, char *argv[])
int last_is_dir = 0;
int i;
int opt;
- int verbose = 0;
+ int verbose = 0, recursive = 0;
int argc_min;
- while ((opt = getopt(argc, argv, "v")) > 0) {
+ while ((opt = getopt(argc, argv, "vr")) > 0) {
switch (opt) {
case 'v':
verbose = 1;
break;
+ case 'r':
+ recursive = 1;
+ break;
}
}
@@ -60,24 +63,31 @@ static int do_cp(int argc, char *argv[])
last_is_dir = 1;
}
- if (argc > argc_min && !last_is_dir) {
+ if (((recursive && argc - optind > 2) || (argc > argc_min)) && !last_is_dir) {
printf("cp: target `%s' is not a directory\n", argv[argc - 1]);
return 1;
}
+ if (recursive && argc - optind == 2 && !last_is_dir) {
+ ret = make_directory(argv[argc - 1]);
+ if (ret)
+ goto out;
+ }
+
for (i = optind; i < argc - 1; i++) {
- if (last_is_dir) {
- char *dst;
- dst = concat_path_file(argv[argc - 1], basename(argv[i]));
+ char *dst;
+ dst = concat_path_file(argv[argc - 1], basename(argv[i]));
+
+ if (recursive)
+ ret = copy_recursive(argv[i], dst);
+ else if (last_is_dir)
ret = copy_file(argv[i], dst, verbose);
- free(dst);
- if (ret)
- goto out;
- } else {
+ else
ret = copy_file(argv[i], argv[argc - 1], verbose);
- if (ret)
- goto out;
- }
+
+ free(dst);
+ if (ret)
+ goto out;
}
ret = 0;
diff --git a/commands/defaultenv.c b/commands/defaultenv.c
new file mode 100644
index 0000000000..bae2d78f47
--- /dev/null
+++ b/commands/defaultenv.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2014 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <common.h>
+#include <getopt.h>
+#include <command.h>
+#include <envfs.h>
+#include <errno.h>
+#include <fs.h>
+#include <libfile.h>
+#include <malloc.h>
+#include <globalvar.h>
+
+static int do_defaultenv(int argc, char *argv[])
+{
+ char *dirname;
+ int opt, ret;
+ char *restorepath = "/";
+ char *from, *to;
+ int restore = 0, scrub = 0;
+
+ while ((opt = getopt(argc, argv, "p:rs")) > 0) {
+ switch (opt) {
+ case 'r':
+ restore = 1;
+ break;
+ case 'p':
+ restorepath = optarg;
+ break;
+ case 's':
+ scrub = 1;
+ break;
+ default:
+ return COMMAND_ERROR_USAGE;
+ }
+ }
+
+ if (!restore || argc != optind)
+ return COMMAND_ERROR_USAGE;
+
+ dirname = "/env";
+
+ make_directory(dirname);
+
+ ret = defaultenv_load("/.defaultenv", 0);
+ if (ret)
+ return ret;
+
+ from = asprintf("/.defaultenv/%s", restorepath);
+ to = asprintf("%s/%s", dirname, restorepath);
+
+ printf("Restoring %s from default environment\n", restorepath);
+
+ if (scrub)
+ unlink_recursive(to, NULL);
+
+ ret = copy_recursive(from, to);
+ free(from);
+ free(to);
+
+ nvvar_load();
+
+ unlink_recursive("/.defaultenv", NULL);
+
+ return ret;
+}
+
+BAREBOX_CMD_HELP_START(defaultenv)
+BAREBOX_CMD_HELP_TEXT("Options:")
+BAREBOX_CMD_HELP_OPT("-r", "restore default environment")
+BAREBOX_CMD_HELP_OPT("-s", "scrub, remove files not in default environment")
+BAREBOX_CMD_HELP_OPT("-p <PATH>", "limit to <PATH>")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(defaultenv)
+ .cmd = do_defaultenv,
+ BAREBOX_CMD_DESC("Restore environment from default environment")
+ BAREBOX_CMD_OPTS("[-rs] [-p <PATH>]")
+ BAREBOX_CMD_GROUP(CMD_GRP_ENV)
+ BAREBOX_CMD_HELP(cmd_defaultenv_help)
+BAREBOX_CMD_END
diff --git a/commands/global.c b/commands/global.c
index f14df3821a..581913d289 100644
--- a/commands/global.c
+++ b/commands/global.c
@@ -37,6 +37,11 @@ static int do_global(int argc, char *argv[])
}
}
+ if (argc == optind) {
+ globalvar_print();
+ return 0;
+ }
+
argc -= optind;
argv += optind;
diff --git a/commands/loadenv.c b/commands/loadenv.c
index 8b15af49df..91ce5e707c 100644
--- a/commands/loadenv.c
+++ b/commands/loadenv.c
@@ -27,12 +27,13 @@
#include <errno.h>
#include <fs.h>
#include <malloc.h>
+#include <globalvar.h>
static int do_loadenv(int argc, char *argv[])
{
char *filename = NULL, *dirname;
unsigned flags = 0;
- int opt;
+ int opt, ret;
int scrub = 0;
int defaultenv = 0;
@@ -97,9 +98,13 @@ static int do_loadenv(int argc, char *argv[])
printf("loading environment from %s\n", defaultenv ? "defaultenv" : filename);
if (defaultenv)
- return defaultenv_load(dirname, flags);
+ ret = defaultenv_load(dirname, flags);
else
- return envfs_load(filename, dirname, flags);
+ ret = envfs_load(filename, dirname, flags);
+
+ nvvar_load();
+
+ return ret;
}
BAREBOX_CMD_HELP_START(loadenv)
diff --git a/commands/magicvar.c b/commands/magicvar.c
index cf1fe45d9d..6737eb533d 100644
--- a/commands/magicvar.c
+++ b/commands/magicvar.c
@@ -3,34 +3,118 @@
#include <getopt.h>
#include <environment.h>
#include <magicvar.h>
+#include <malloc.h>
-static int do_magicvar(int argc, char *argv[])
+static LIST_HEAD(magicvars);
+
+struct magicvar_dyn {
+ char *name;
+ char *description;
+ struct list_head list;
+};
+
+static void magicvar_print_one(struct magicvar_dyn *md, int verbose)
+{
+ printf("%-32s %s\n", md->name, md->description);
+
+ if (verbose) {
+ const char *val = getenv(md->name);
+ if (val && strlen(val))
+ printf(" %s\n", val);
+ }
+}
+
+struct magicvar_dyn *magicvar_find(const char *name)
{
+ struct magicvar_dyn *md;
+
+ list_for_each_entry(md, &magicvars, list)
+ if (!strcmp(md->name, name))
+ return md;
+
+ return NULL;
+}
+
+static void magicvar_remove(struct magicvar_dyn *md)
+{
+ free(md->name);
+ free(md->description);
+ list_del(&md->list);
+ free(md);
+}
+
+static int compare(struct list_head *a, struct list_head *b)
+{
+ char *na = (char*)list_entry(a, struct magicvar_dyn, list)->name;
+ char *nb = (char*)list_entry(b, struct magicvar_dyn, list)->name;
+
+ return strcmp(na, nb);
+}
+
+static int magicvar_add(const char *name, const char *description)
+{
+ struct magicvar_dyn *md;
+
+ md = magicvar_find(name);
+ if (md)
+ magicvar_remove(md);
+
+ md = xzalloc(sizeof(*md));
+ md->name = xstrdup(name);
+ md->description = xstrdup(description);
+
+ list_add_sort(&md->list, &magicvars, compare);
+
+ return 0;
+}
+
+static void magicvar_build(void)
+{
+ static int first = 1;
struct magicvar *m;
+
+ if (!first)
+ return;
+
+ for (m = &__barebox_magicvar_start;
+ m != &__barebox_magicvar_end;
+ m++)
+ magicvar_add(m->name, m->description);
+
+ first = 0;
+}
+
+static int do_magicvar(int argc, char *argv[])
+{
+ struct magicvar_dyn *md;
int opt;
- int verbose = 0;
+ int verbose = 0, add = 0;
- while ((opt = getopt(argc, argv, "v")) > 0) {
+ magicvar_build();
+
+ while ((opt = getopt(argc, argv, "va")) > 0) {
switch (opt) {
case 'v':
verbose = 1;
break;
+ case 'a':
+ add = 1;
+ break;
default:
return COMMAND_ERROR_USAGE;
}
}
- for (m = &__barebox_magicvar_start;
- m != &__barebox_magicvar_end;
- m++) {
- printf("%-32s %s\n", m->name, m->description);
- if (verbose) {
- const char *val = getenv(m->name);
- if (val && strlen(val))
- printf(" %s\n", val);
- }
+ if (add) {
+ if (optind + 2 != argc)
+ return COMMAND_ERROR_USAGE;
+
+ return magicvar_add(argv[optind], argv[optind + 1]);
}
+ list_for_each_entry(md, &magicvars, list)
+ magicvar_print_one(md, verbose);
+
return 0;
}
@@ -38,12 +122,13 @@ static int do_magicvar(int argc, char *argv[])
BAREBOX_CMD_HELP_START(magicvar)
BAREBOX_CMD_HELP_TEXT("Options:")
BAREBOX_CMD_HELP_OPT ("-v", "verbose (list all value if there is one)")
+BAREBOX_CMD_HELP_OPT ("-a <NAME> <DESC>", "Add a new magicvar")
BAREBOX_CMD_HELP_END
BAREBOX_CMD_START(magicvar)
.cmd = do_magicvar,
BAREBOX_CMD_DESC("list information about magic variables")
- BAREBOX_CMD_OPTS("[-v]")
+ BAREBOX_CMD_OPTS("[-va]")
BAREBOX_CMD_HELP(cmd_magicvar_help)
BAREBOX_CMD_GROUP(CMD_GRP_ENV)
BAREBOX_CMD_END
diff --git a/commands/nv.c b/commands/nv.c
new file mode 100644
index 0000000000..8cebb856f4
--- /dev/null
+++ b/commands/nv.c
@@ -0,0 +1,84 @@
+/*
+ * nv.c - non volatile shell variables
+ *
+ * Copyright (c) 2014 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <common.h>
+#include <malloc.h>
+#include <command.h>
+#include <globalvar.h>
+#include <environment.h>
+#include <getopt.h>
+
+static int do_nv(int argc, char *argv[])
+{
+ int opt;
+ int do_remove = 0;
+ int ret;
+ char *value;
+
+ while ((opt = getopt(argc, argv, "r")) > 0) {
+ switch (opt) {
+ case 'r':
+ do_remove = 1;
+ break;
+ default:
+ return COMMAND_ERROR_USAGE;
+ }
+ }
+
+ if (argc == optind) {
+ nvvar_print();
+ return 0;
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 1)
+ return COMMAND_ERROR_USAGE;
+
+ value = strchr(argv[0], '=');
+ if (value) {
+ *value = 0;
+ value++;
+ }
+
+ if (do_remove)
+ ret = nvvar_remove(argv[0]);
+ else
+ ret = nvvar_add(argv[0], value);
+
+ return ret;
+}
+
+BAREBOX_CMD_HELP_START(nv)
+BAREBOX_CMD_HELP_TEXT("Add a new non volatile variable named VAR, optionally set to VALUE.")
+BAREBOX_CMD_HELP_TEXT("non volatile variables are persistent variables that overwrite the")
+BAREBOX_CMD_HELP_TEXT("global variables of the same name. Their value is saved with")
+BAREBOX_CMD_HELP_TEXT("'saveenv'.")
+BAREBOX_CMD_HELP_TEXT("")
+BAREBOX_CMD_HELP_TEXT("Options:")
+BAREBOX_CMD_HELP_OPT("-r", "remove a non volatile variable")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(nv)
+ .cmd = do_nv,
+ BAREBOX_CMD_DESC("create or set non volatile variables")
+ BAREBOX_CMD_OPTS("[-r] VAR[=VALUE]")
+ BAREBOX_CMD_GROUP(CMD_GRP_ENV)
+ BAREBOX_CMD_HELP(cmd_nv_help)
+BAREBOX_CMD_END