/* See LICENSE file for copyright and license details. */ #ifndef LIBENV_H #define LIBENV_H #include #include #include #if defined(__GNUC__) # define LIBENV_MALLOC__ __attribute__((__malloc__, __warn_unused_result__)) # define LIBENV_RET_NONNULL__ __attribute__((__returns_nonnull__, __warn_unused_result__)) #else # define LIBENV_MALLOC__ # define LIBENV_RET_NONNULL__ #endif /** * Environment variable class */ enum libenv_class { /** * Used to mark the end of a class list in * for a variadic function */ LIBENV_END = 0, /* Classes: */ /** * Environment variables necessary for the * graphical environment */ LIBENV_DISPLAY, /** * Environment variables that configure * the graphical environment */ LIBENV_DISPLAY_CONFIG, /** * Environment variables that describe * the desktop environment */ LIBENV_DESKTOP, /** * Environment variables that describe * the terminals capabilities */ LIBENV_TERMINAL_CAPS, /** * Environment variables that describe * the terminals but is only meaningful * for the local host */ LIBENV_LOCAL_TERMINAL, /** * Environment variables that configure * the locale */ LIBENV_LOCALE, /** * Environment variables that configure * the timezone */ LIBENV_TIMEZONE, /** * Environment variables that describe * the current session * * This for example includes variables * added by SSH to describe the remote * connection * * This does not include display, desktop, * or terminal information, nor does * include information to identify the * user */ LIBENV_SESSION, /** * Environment variables that configure * the user's theme * * This is excludes variables listed * for LIBENV_THEME_PLUGIN except in the * hypothetical scenario where it names * a plugin and additional configurations */ LIBENV_THEME_CONFIG, /** * Environment variables that describe * the plugins the user's theme requires */ LIBENV_THEME_PLUGIN, /** * Environment variables that configures * the user's internet configurations, * including mainly proxies */ LIBENV_INTERNET, /** * Environment variables that configures * the user's audio */ LIBENV_AUDIO, /** * Environment variables that describe * any information gathered about the * user from passwd(5) or login parameters */ LIBENV_USER, /** * Environment variables that default * applications configured for the user */ LIBENV_APPLICATIONS, /** * Environment variables that configure * preferences, for the user, for various * applications */ LIBENV_PREFERENCES, /** * Environment variables that list directories * configured system wide (but could be * overwritten for the user) * * Environment variables with this classification * has at least also LIBENV_PATH */ LIBENV_SYSTEM_PATHS, /** * Environment variables that list directories * configured for the user * * Environment variables with this classification * has at least also LIBENV_PATH */ LIBENV_USER_PATHS, /** * Environment variables that contain * current and past working directories * * Environment variables with this classification * has at least also LIBENV_PATH */ LIBENV_PWD, /** * Environment variables that contain * information about the executed utility */ LIBENV_EXEC, /** * Environment variables that contain * filesystem paths * * Any environment variable with this * classification has at least one other * classification */ LIBENV_PATH, /** * Environment variables that should be removed * when entering a remote session * * Any environment variable with this * classification has at least one other * classification */ LIBENV_REMOTE_UNSAFE, /** * Environment variables that should be can * safely be kepted when entering a remote * session * * Any environment variable with this * classification has at least one other * classification */ LIBENV_REMOTE_SAFE, /** * Environment variables that should be removed * when entering a logging into a new user * * Any environment variable with this * classification has at least one other * classification */ LIBENV_LOGIN_UNSAFE, /** * Environment variables that should be can * safely be kepted when entering a logging * into a new user * * Any environment variable with this * classification has at least one other * classification */ LIBENV_LOGIN_SAFE, /** * Environment variables that should be removed * when escalating privileges * * Any environment variable with this * classification has at least one other * classification */ LIBENV_SU_UNSAFE, /** * Environment variables that should be can * safely be kepted when escalating privileges * * Any environment variable with this * classification has at least one other * classification */ LIBENV_SU_SAFE /* = 26 */ }; /** * Environment variable name and classification */ struct libenv_variable { /** * The name of the environment variable */ const char *name; /** * Bitset of `enum libenv_class`'s the variable * is classified under * * For any value `c` in `enum libenv_class` except * `LIBENV_END`, `(.classes[c / 64] >> (c % 64)) & 1` * is 1 iff the variable belongs to the class; however * the application must verify that `c / 64` is less * than the value output by `libenv_get_complete_list` * to its first argument * * For the sake of simplicity, the lowest-valued bit * in the first `uint64_t` is always 0 */ const uint64_t *classes; }; /** * Get the list of recognised environment variable, * the list will container their names and classes * * This function does not read the current environment, * and may return unset environemnt variables * * @param nclasswords_out Output parameter for the number of elements in each returned * `struct libenv_variable`'s `.classes`, may be `NULL` * @param count_out Output parameter for the number of elements in the returned list, * sans a terminal `{NULL, NULL}` element, may be `NULL` * @return Statically allocated list of all recognised environment variables */ LIBENV_RET_NONNULL__ const struct libenv_variable *libenv_get_complete_list(size_t *nclasswords_out, size_t *count_out); /** * Get a list of environment variables names (which need not be set * in the current environment) that fall into either of the specified * variable classes * * @param classes_head,classes_tail List of variable classes, must end with `LIBENV_END` * @return List of unique environment variable names, the caller should * deallocate the returned list, when done with it, using the * free(3) function, however the elements of the list are * statically allocated and should not be deallocated or modified, * `NULL` on failure * * @throws ENOMEM Not enought memory available to allocate the list */ LIBENV_MALLOC__ const char **libenv_vget_chosen_list(enum libenv_class, va_list); /** * Get a list of environment variables names (which need not be set * in the current environment) that fall into either of the specified * variable classes * * @param classes_head... List of variable classes, must end with `LIBENV_END` * @return List of unique environment variable names, the caller should * deallocate the returned list, when done with it, using the * free(3) function, however the elements of the list are * statically allocated and should not be deallocated or modified, * `NULL` on failure * * @throws ENOMEM Not enought memory available to allocate the list */ LIBENV_MALLOC__ const char **libenv_get_chosen_list(enum libenv_class, ... /*, LIBENV_END */); /** * Given a list of environment variable names, remove the variables * that belong to all of the specified environment variable classes * * @param variables `NULL`-terminated list environemnt variable names; may be `NULL`, * which causes the function to return 0; unless `NULL` the list * will be updated * @param classes The list of environment variable classes, must end with `LIBENV_END` * @return The new number of elements in `variables`; `variables[return]` will * be `NULL` provided that `variables` itself it not `NULL` */ size_t libenv_vfilter_name_list(const char **, va_list); /** * Given a list of environment variable names, remove the variables * that belong to all of the specified environment variable classes * * @param variables `NULL`-terminated list environemnt variable names; may be `NULL`, * which causes the function to return 0; unless `NULL` the list * will be updated * @param ... The list of environment variable classes, must end with `LIBENV_END`, * each argument must have the type `enum libenv_class` * @return The new number of elements in `variables`; `variables[return]` will * be `NULL` provided that `variables` itself it not `NULL` */ size_t libenv_filter_name_list(const char **, /* enum libenv_class */ ... /*, LIBENV_END */); /** * Given a list of environment variables, with values, remove the variables * that belong to all of the specified environment variable classes * * @param variables `NULL`-terminated list environemnt variables; may be `NULL`, * which causes the function to return 0; unless `NULL` the list * will be updated * @param classes The list of environment variable classes, must end with `LIBENV_END` * @return The new number of elements in `variables`; `variables[return]` will * be `NULL` provided that `variables` itself it not `NULL` */ size_t libenv_vfilter_variable_list(const char **, va_list); /** * Given a list of environment variables, with values, remove the variables * that belong to all of the specified environment variable classes * * @param variables `NULL`-terminated list environemnt variables; may be `NULL`, * which causes the function to return 0; unless `NULL` the list * will be updated * @param ... The list of environment variable classes, must end with `LIBENV_END`, * each argument must have the type `enum libenv_class` * @return The new number of elements in `variables`; `variables[return]` will * be `NULL` provided that `variables` itself it not `NULL` */ size_t libenv_filter_variable_list(const char **, /* enum libenv_class */ ... /*, LIBENV_END */); /** * Given a list of environment variable names, remove any variable that * does not belong to any of the specified environment variable classes * * @param variables `NULL`-terminated list environemnt variable names; may be `NULL`, * which causes the function to return 0; unless `NULL` the list * will be updated * @param classes The list of environment variable classes, must end with `LIBENV_END` * @return The new number of elements in `variables`; `variables[return]` will * be `NULL` provided that `variables` itself it not `NULL` */ size_t libenv_vselect_name_list(const char **, va_list); /** * Given a list of environment variable names, remove any variable that * does not belong to any of the specified environment variable classes * * @param variables `NULL`-terminated list environemnt variable names; may be `NULL`, * which causes the function to return 0; unless `NULL` the list * will be updated * @param ... The list of environment variable classes, must end with `LIBENV_END`, * each argument must have the type `enum libenv_class` * @return The new number of elements in `variables`; `variables[return]` will * be `NULL` provided that `variables` itself it not `NULL` */ size_t libenv_select_name_list(const char **, /* enum libenv_class */ ... /*, LIBENV_END */); /** * Given a list of environment variables, with values, remove any variable * that does not belong to any of the specified environment variable classes * * @param variables `NULL`-terminated list environemnt variables; may be `NULL`, * which causes the function to return 0; unless `NULL` the list * will be updated * @param classes The list of environment variable classes, must end with `LIBENV_END` * @return The new number of elements in `variables`; `variables[return]` will * be `NULL` provided that `variables` itself it not `NULL` */ size_t libenv_vselect_variable_list(const char **, va_list); /** * Given a list of environment variables, with values, remove any variable * that does not belong to any of the specified environment variable classes * * @param variables `NULL`-terminated list environemnt variables; may be `NULL`, * which causes the function to return 0; unless `NULL` the list * will be updated * @param ... The list of environment variable classes, must end with `LIBENV_END`, * each argument must have the type `enum libenv_class` * @return The new number of elements in `variables`; `variables[return]` will * be `NULL` provided that `variables` itself it not `NULL` */ size_t libenv_select_variable_list(const char **, /* enum libenv_class */ ... /*, LIBENV_END */); /** * Given a list of environment variable names, remove the variables * that belong to all of the specified environment variable classes * * Any element removed from `variables` will be deallocated using * the free(3) function * * @param variables `NULL`-terminated list environemnt variable names; may be `NULL`, * which causes the function to return 0; unless `NULL` the list * will be updated * @param classes The list of environment variable classes, must end with `LIBENV_END` * @return The new number of elements in `variables`; `variables[return]` will * be `NULL` provided that `variables` itself it not `NULL` */ size_t libenv_vfilter_name_list_with_dealloc(char **, va_list); /** * Given a list of environment variable names, remove the variables * that belong to all of the specified environment variable classes * * Any element removed from `variables` will be deallocated using * the free(3) function * * @param variables `NULL`-terminated list environemnt variable names; may be `NULL`, * which causes the function to return 0; unless `NULL` the list * will be updated * @param ... The list of environment variable classes, must end with `LIBENV_END`, * each argument must have the type `enum libenv_class` * @return The new number of elements in `variables`; `variables[return]` will * be `NULL` provided that `variables` itself it not `NULL` */ size_t libenv_filter_name_list_with_dealloc(char **, /* enum libenv_class */ ... /*, LIBENV_END */); /** * Given a list of environment variables, with values, remove the variables * that belong to all of the specified environment variable classes * * Any element removed from `variables` will be deallocated using * the free(3) function * * @param variables `NULL`-terminated list environemnt variables; may be `NULL`, * which causes the function to return 0; unless `NULL` the list * will be updated * @param classes The list of environment variable classes, must end with `LIBENV_END` * @return The new number of elements in `variables`; `variables[return]` will * be `NULL` provided that `variables` itself it not `NULL` */ size_t libenv_vfilter_variable_list_with_dealloc(char **, va_list); /** * Given a list of environment variables, with values, remove the variables * that belong to all of the specified environment variable classes * * Any element removed from `variables` will be deallocated using * the free(3) function * * @param variables `NULL`-terminated list environemnt variables; may be `NULL`, * which causes the function to return 0; unless `NULL` the list * will be updated * @param ... The list of environment variable classes, must end with `LIBENV_END`, * each argument must have the type `enum libenv_class` * @return The new number of elements in `variables`; `variables[return]` will * be `NULL` provided that `variables` itself it not `NULL` */ size_t libenv_filter_variable_list_with_dealloc(char **, /* enum libenv_class */ ... /*, LIBENV_END */); /** * Given a list of environment variable names, remove any variable that * does not belong to any of the specified environment variable classes * * Any element removed from `variables` will be deallocated using * the free(3) function * * @param variables `NULL`-terminated list environemnt variable names; may be `NULL`, * which causes the function to return 0; unless `NULL` the list * will be updated * @param classes The list of environment variable classes, must end with `LIBENV_END` * @return The new number of elements in `variables`; `variables[return]` will * be `NULL` provided that `variables` itself it not `NULL` */ size_t libenv_vselect_name_list_with_dealloc(char **, va_list); /** * Given a list of environment variable names, remove any variable that * does not belong to any of the specified environment variable classes * * Any element removed from `variables` will be deallocated using * the free(3) function * * @param variables `NULL`-terminated list environemnt variable names; may be `NULL`, * which causes the function to return 0; unless `NULL` the list * will be updated * @param ... The list of environment variable classes, must end with `LIBENV_END`, * each argument must have the type `enum libenv_class` * @return The new number of elements in `variables`; `variables[return]` will * be `NULL` provided that `variables` itself it not `NULL` */ size_t libenv_select_name_list_with_dealloc(char **, /* enum libenv_class */ ... /*, LIBENV_END */); /** * Given a list of environment variables, with values, remove any variable * that does not belong to any of the specified environment variable classes * * Any element removed from `variables` will be deallocated using * the free(3) function * * @param variables `NULL`-terminated list environemnt variables; may be `NULL`, * which causes the function to return 0; unless `NULL` the list * will be updated * @param classes The list of environment variable classes, must end with `LIBENV_END` * @return The new number of elements in `variables`; `variables[return]` will * be `NULL` provided that `variables` itself it not `NULL` */ size_t libenv_vselect_variable_list_with_dealloc(char **, va_list); /** * Given a list of environment variables, with values, remove any variable * that does not belong to any of the specified environment variable classes * * Any element removed from `variables` will be deallocated using * the free(3) function * * @param variables `NULL`-terminated list environemnt variables; may be `NULL`, * which causes the function to return 0; unless `NULL` the list * will be updated * @param ... The list of environment variable classes, must end with `LIBENV_END`, * each argument must have the type `enum libenv_class` * @return The new number of elements in `variables`; `variables[return]` will * be `NULL` provided that `variables` itself it not `NULL` */ size_t libenv_select_variable_list_with_dealloc(char **, /* enum libenv_class */ ... /*, LIBENV_END */); #undef LIBENV_MALLOC__ #undef LIBENV_RET_NONNULL__ #endif