blob: 48b3b2a94e31c9958a92538a696658aeca6ee51f [file] [log] [blame]
/*
* 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);