/* * Copyright (c) 2023, Meta * * SPDX-License-Identifier: Apache-2.0 */ #include "posix_shell.h" #include #include #include #include #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);