131 lines
2.3 KiB
C
131 lines
2.3 KiB
C
|
/*
|
||
|
* Copyright (c) 2023, Meta
|
||
|
*
|
||
|
* SPDX-License-Identifier: Apache-2.0
|
||
|
*/
|
||
|
|
||
|
#include "posix_shell.h"
|
||
|
|
||
|
#include <ctype.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
#include <zephyr/shell/shell.h>
|
||
|
|
||
|
#define HELP_ENV_GET "[NAME]"
|
||
|
#define HELP_ENV_SET "NAME VALUE | NAME=VALUE"
|
||
|
#define HELP_ENV_UNSET "NAME.."
|
||
|
|
||
|
static int cmd_env_get(const struct shell *sh, size_t argc, char **argv)
|
||
|
{
|
||
|
const char *name;
|
||
|
const char *value;
|
||
|
|
||
|
switch (argc) {
|
||
|
case 1: {
|
||
|
extern char **environ;
|
||
|
/* list all environment variables */
|
||
|
if (environ != NULL) {
|
||
|
for (char **envp = environ; *envp != NULL; ++envp) {
|
||
|
shell_print(sh, "%s", *envp);
|
||
|
}
|
||
|
}
|
||
|
} break;
|
||
|
case 2:
|
||
|
/* list a specific environment variable */
|
||
|
name = argv[1];
|
||
|
value = getenv(name);
|
||
|
if (value != NULL) {
|
||
|
shell_print(sh, "%s", value);
|
||
|
}
|
||
|
break;
|
||
|
default:
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
|
||
|
return EXIT_SUCCESS;
|
||
|
}
|
||
|
|
||
|
static bool is_shell_env_name(const char *name)
|
||
|
{
|
||
|
char c;
|
||
|
|
||
|
if (name == NULL || name[0] == '\0') {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
for (size_t i = 0, N = strlen(name); i < N; ++i) {
|
||
|
c = name[i];
|
||
|
|
||
|
if (c == '_') {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if (isalpha(c)) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if (i > 0 && isdigit(c)) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
static int cmd_env_set(const struct shell *sh, size_t argc, char **argv)
|
||
|
{
|
||
|
int ret;
|
||
|
char *value;
|
||
|
const char *name;
|
||
|
|
||
|
switch (argc) {
|
||
|
case 2:
|
||
|
name = argv[1];
|
||
|
value = strchr(argv[1], '=');
|
||
|
if (value != NULL) {
|
||
|
*value = '\0';
|
||
|
++value;
|
||
|
}
|
||
|
break;
|
||
|
case 3:
|
||
|
name = argv[1];
|
||
|
value = argv[2];
|
||
|
break;
|
||
|
default:
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
|
||
|
/* silently drop "poorly conditioned" environment variables */
|
||
|
if (!is_shell_env_name(name)) {
|
||
|
shell_print(sh, "bad name");
|
||
|
return EXIT_SUCCESS;
|
||
|
}
|
||
|
|
||
|
ret = setenv(name, value, 1);
|
||
|
if (ret == -1) {
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
|
||
|
return EXIT_SUCCESS;
|
||
|
}
|
||
|
|
||
|
static int cmd_env_unset(const struct shell *sh, size_t argc, char **argv)
|
||
|
{
|
||
|
for (--argc, ++argv; argc > 0; --argc, ++argv) {
|
||
|
(void)unsetenv(argv[0]);
|
||
|
}
|
||
|
|
||
|
return EXIT_SUCCESS;
|
||
|
}
|
||
|
|
||
|
SHELL_STATIC_SUBCMD_SET_CREATE(sub_env, SHELL_CMD(set, NULL, HELP_ENV_SET, cmd_env_set),
|
||
|
SHELL_CMD(get, NULL, HELP_ENV_GET, cmd_env_get),
|
||
|
SHELL_CMD(unset, NULL, HELP_ENV_UNSET, cmd_env_unset),
|
||
|
SHELL_SUBCMD_SET_END /* Array terminated. */
|
||
|
);
|
||
|
|
||
|
POSIX_CMD_ADD(env, &sub_env, "Print system information", NULL, 1, 255);
|