aboutsummaryrefslogblamecommitdiffstats
path: root/libenv.h
blob: 8e125098e5590c6803be5090dd527135355c8cb6 (plain) (tree)
















































                                                                                          
                                      

























                                               
                                                













                                                  

                                             











                                                 

                                               




                                   
                                               





























                                                         
                                         







                                                         
                                         







                                                         
                                         





























                                                       

                                                   








                                                       
                                        







                                                

                                                   

















                                                       

                                                   







































                                                              
                                             




















                                                                                                                        
                                                                    














                                                                                            
                                                                    






                                                                                              
                                                                                        











                                                                                           
                                                                                        












                                                                                             
                                                                                   











                                                                                           
                                                                                   












                                                                                                 
                                                                                        











                                                                                           
                                                                                        












                                                                                             
                                                                                   











                                                                                           
                                                                                   















                                                                                                 
                                                                                        














                                                                                           
                                                                                        















                                                                                                    
                                                                                   














                                                                                           
                                                                                   















                                                                                                        
                                                                                        














                                                                                           
                                                                                        















                                                                                                    
                                                                                   














                                                                                           
                                                                                   













                                                                                                        
/* 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 terminal's 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 includes, for example, 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 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 configure
	 * the user's Internet connection,
	 * including mainly proxies
	 */
	LIBENV_INTERNET,

	/**
	 * Environment variables that configure
	 * 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
	 * also have at least LIBENV_PATH
	 */
	LIBENV_SYSTEM_PATHS,

	/**
	 * Environment variables that list directories
	 * configured for the user
	 * 
	 * Environment variables with this classification
	 * also have at least LIBENV_PATH
	 */
	LIBENV_USER_PATHS,

	/**
	 * Environment variables that contain
	 * current and past working directories
	 * 
	 * Environment variables with this classification
	 * also have at least 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 can safely be
	 * kept 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 logging in as a new user
	 * 
	 * Any environment variable with this
	 * classification has at least one other
	 * classification
	 */
	LIBENV_LOGIN_UNSAFE,

	/**
	 * Environment variables that can safely be
	 * kept when logging in as 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 can safely be
	 * kept 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 environment 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 enough 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 enough 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 environment 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 environment 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 environment 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 environment 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 environment 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 environment 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 environment 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 environment 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 environment 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 environment 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 environment 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 environment 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 environment 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 environment 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 environment 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 environment 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