/* See LICENSE file for copyright and license details. */
#ifndef LIBENV_H
#define LIBENV_H
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
#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