You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
130 lines
2.3 KiB
130 lines
2.3 KiB
/* |
|
* 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);
|
|
|