diff options
author | Mattias Andrée <m@maandree.se> | 2025-01-30 18:42:27 +0100 |
---|---|---|
committer | Mattias Andrée <m@maandree.se> | 2025-01-30 18:42:27 +0100 |
commit | aebf2524909f0c0e3aec7f78fa01ad908f7da3a0 (patch) | |
tree | 86881e1b1b299990e6726eda5dde3f1f77c4f180 | |
download | libenv-aebf2524909f0c0e3aec7f78fa01ad908f7da3a0.tar.gz libenv-aebf2524909f0c0e3aec7f78fa01ad908f7da3a0.tar.bz2 libenv-aebf2524909f0c0e3aec7f78fa01ad908f7da3a0.tar.xz |
First commit
Signed-off-by: Mattias Andrée <m@maandree.se>
54 files changed, 2047 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a071ed4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*\#* +*~ +*.o +*.a +*.lo +*.su +*.so +*.so.* +*.dll +*.dylib +*.gch +*.gcov +*.gcno +*.gcda @@ -0,0 +1,15 @@ +ISC License + +© 2025 Mattias Andrée <m@maandree.se> + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..18d3ff1 --- /dev/null +++ b/Makefile @@ -0,0 +1,116 @@ +.POSIX: + +CONFIGFILE = config.mk +include $(CONFIGFILE) + +OS = linux +# Linux: linux +# Mac OS: macos +# Windows: windows +include mk/$(OS).mk + + +LIB_MAJOR = 1 +LIB_MINOR = 0 +LIB_VERSION = $(LIB_MAJOR).$(LIB_MINOR) +LIB_NAME = env + + +OBJ =\ + libenv_get_complete_list.o\ + $(OBJ_TESTABLE) + +OBJ_TESTABLE_PUBLIC =\ + libenv_vget_chosen_list.o\ + libenv_get_chosen_list.o\ + libenv_vfilter_name_list.o\ + libenv_filter_name_list.o\ + libenv_vfilter_variable_list.o\ + libenv_filter_variable_list.o\ + libenv_vselect_name_list.o\ + libenv_select_name_list.o\ + libenv_vselect_variable_list.o\ + libenv_select_variable_list.o\ + libenv_vfilter_name_list_with_dealloc.o\ + libenv_filter_name_list_with_dealloc.o\ + libenv_vfilter_variable_list_with_dealloc.o\ + libenv_filter_variable_list_with_dealloc.o\ + libenv_vselect_name_list_with_dealloc.o\ + libenv_select_name_list_with_dealloc.o\ + libenv_vselect_variable_list_with_dealloc.o\ + libenv_select_variable_list_with_dealloc.o\ + +OBJ_TESTABLE =\ + $(OBJ_TESTABLE_PUBLIC)\ + libenv_vprocess_list__.o + +OBJ_PUBLIC =\ + libenv_get_complete_list.o\ + $(OBJ_TESTABLE_PUBLIC) + +HDR =\ + libenv.h\ + common.h + +MAN3 =\ + $(OBJ_PUBLIC:.o=.3)\ + enum_libenv_class.3\ + libenv_class.3\ + struct_libenv_variable.3\ + libenv_variable.3 + +MAN7 =\ + libenv.7 + +LOBJ = $(OBJ:.o=.lo) + + +all: libenv.a libenv.$(LIBEXT) +$(OBJ): $(HDR) +$(LOBJ): $(HDR) + +.c.o: + $(CC) -c -o $@ $< $(CFLAGS) $(CPPFLAGS) + +.c.lo: + $(CC) -fPIC -c -o $@ $< $(CFLAGS) $(CPPFLAGS) + +libenv.a: $(OBJ) + @rm -f -- $@ + $(AR) rc $@ $(OBJ) + $(AR) ts $@ > /dev/null + +libenv.$(LIBEXT): $(LOBJ) + $(CC) $(LIBFLAGS) -o $@ $(LOBJ) $(LDFLAGS) + +install: libenv.a libenv.$(LIBEXT) + mkdir -p -- "$(DESTDIR)$(PREFIX)/lib" + mkdir -p -- "$(DESTDIR)$(PREFIX)/include" + mkdir -p -- "$(DESTDIR)$(MANPREFIX)/man3" + mkdir -p -- "$(DESTDIR)$(MANPREFIX)/man7" + cp -- libenv.a "$(DESTDIR)$(PREFIX)/lib/" + cp -- libenv.$(LIBEXT) "$(DESTDIR)$(PREFIX)/lib/libenv.$(LIBMINOREXT)" + $(FIX_INSTALL_NAME) "$(DESTDIR)$(PREFIX)/lib/libenv.$(LIBMINOREXT)" + ln -sf -- libenv.$(LIBMINOREXT) "$(DESTDIR)$(PREFIX)/lib/libenv.$(LIBMAJOREXT)" + ln -sf -- libenv.$(LIBMAJOREXT) "$(DESTDIR)$(PREFIX)/lib/libenv.$(LIBEXT)" + cp -- libenv.h "$(DESTDIR)$(PREFIX)/include/" + cp -P -- $(MAN3) "$(DESTDIR)$(MANPREFIX)/man3/" + cp -P -- $(MAN7) "$(DESTDIR)$(MANPREFIX)/man7/" + +uninstall: + -rm -f -- "$(DESTDIR)$(PREFIX)/lib/libenv.a" + -rm -f -- "$(DESTDIR)$(PREFIX)/lib/libenv.$(LIBMAJOREXT)" + -rm -f -- "$(DESTDIR)$(PREFIX)/lib/libenv.$(LIBMINOREXT)" + -rm -f -- "$(DESTDIR)$(PREFIX)/lib/libenv.$(LIBEXT)" + -rm -f -- "$(DESTDIR)$(PREFIX)/include/libenv.h" + -cd -- "$(DESTDIR)$(MANPREFIX)/man3/" && rm -f -- $(MAN3) + -cd -- "$(DESTDIR)$(MANPREFIX)/man7/" && rm -f -- $(MAN7) + +clean: + -rm -f -- *.o *.a *.lo *.su *.so *.so.* *.dll *.dylib + -rm -f -- *.gch *.gcov *.gcno *.gcda *.$(LIBEXT) + +.SUFFIXES: +.SUFFIXES: .lo .o .c + +.PHONY: all install uninstall clean @@ -0,0 +1,25 @@ +NAME + libenv - Environment sanitation library + +SYNOPSIS + #include <libenv.h> + + Link with -lenv. + +DESCRIPTION + The libenv software library is C library designed to help + utilities perform sanitation of environment variables. + + Some utilities need to remove environment variables that are + not appropriate for the new context that the utility entires. + Likewise some utilities may meed to remove all except some + special environment variables. libenv provides a database of + environment variable variables that could be interesting and + provides functionality to describe the new context the is is + entered and filter out environment variables accordingly. + +SEE ALSO + libenv_filter_variable_list(3), + libenv_select_variable_list(3), + libenv_get_chosen_list(3), + libenv_get_complete_list(3) diff --git a/common.h b/common.h new file mode 100644 index 0000000..02af2a1 --- /dev/null +++ b/common.h @@ -0,0 +1,30 @@ +/* See LICENSE file for copyright and license details. */ +#include "libenv.h" +#include <stdlib.h> + + +#define HAVE_HEAD 1 +#define NO_HEAD 0 + +#define NAMES 1 +#define VARIABLES 0 + +#define FILTER 1, 1 +#define SELECT 0, 0 + + +size_t libenv_vprocess_list__(void *, enum libenv_class, va_list, int have_head, int names, int filter, int all, int dealloc); + +static inline size_t +libenv_vprocess_list_without_dealloc__(const char **variables, enum libenv_class classes_head, va_list classes_tail, + int have_head, int names, int filter, int all) +{ + return libenv_vprocess_list__(variables, classes_head, classes_tail, have_head, names, filter, all, 0); +} + +static inline size_t +libenv_vprocess_list_with_dealloc__(char **variables, enum libenv_class classes_head, va_list classes_tail, + int have_head, int names, int filter, int all) +{ + return libenv_vprocess_list__(variables, classes_head, classes_tail, have_head, names, filter, all, 1); +} diff --git a/config.mk b/config.mk new file mode 100644 index 0000000..f4adf12 --- /dev/null +++ b/config.mk @@ -0,0 +1,8 @@ +PREFIX = /usr +MANPREFIX = $(PREFIX)/share/man + +CC = c99 + +CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_GNU_SOURCE +CFLAGS = +LDFLAGS = diff --git a/enum_libenv_class.3 b/enum_libenv_class.3 new file mode 100644 index 0000000..25edd60 --- /dev/null +++ b/enum_libenv_class.3 @@ -0,0 +1,197 @@ +.TH ENUM_LIBENV_CLASS 3 libenv +.SH NAME +enum libenv_class - Environment variables classes + +.SH SYNOPSIS +.nf +#include <libenv.h> + +enum libenv_class { + LIBENV_END = 0, + /* ... members omitted, see listing below ... */ +}; +.fi + +.SH DESCRIPTION +The +.B enum libenv_class +contains one dummy value, +.IR LIBENV_END , +used to mark the end of a class list for variadic functions. +In addition to this dummy value, it also contains the following +values used to describe a class of environment variables: +.TP +.B LIBENV_DISPLAY +Environment variables necessary for the +graphical environment. +.TP +.B LIBENV_DISPLAY_CONFIG +Environment variables that configure +the graphical environment. +.TP +.B LIBENV_DESKTOP +Environment variables that describe +the desktop environment. +.TP +.B LIBENV_TERMINAL_CAPS +Environment variables that describe +the terminals capabilities. +.TP +.B LIBENV_LOCAL_TERMINAL +Environment variables that describe +the terminals but is only meaningful +for the local host. +.TP +.B LIBENV_LOCALE +Environment variables that configure +the locale. +.TP +.B LIBENV_TIMEZONE +Environment variables that configure +the timezone. +.TP +.B LIBENV_SESSION +Environment variables that describe +the current session. + +This for example includes variables +added by +.BR sshd (8) +to describe the remote connection. + +This does not include display, desktop, +or terminal information, nor does +include information to identify the +user. +.TP +.B LIBENV_THEME_CONFIG +Environment variables that configure +the user's theme. + +This is excludes variables listed for +.I LIBENV_THEME_PLUGIN +except in the +hypothetical scenario where it names +a plugin and additional configurations. +.TP +.B LIBENV_THEME_PLUGIN +Environment variables that describe +the plugins the user's theme requires. +.TP +.B LIBENV_INTERNET +Environment variables that configures +the user's internet configurations, +including mainly proxies. +.TP +.B LIBENV_AUDIO +Environment variables that configures +the user's audio. +.TP +.B LIBENV_USER +Environment variables that describe +any information gathered about the +user from +.BR passwd (5) +or login parameters. +.TP +.B LIBENV_APPLICATIONS +Environment variables that default +applications configured for the user. +.TP +.B LIBENV_PREFERENCES +Environment variables that configure +preferences, for the user, for various +applications. +.TP +.B LIBENV_SYSTEM_PATHS +Environment variables that list directories +configured system wide (but could be +overwritten for the user). + +Environment variables with this classification +has at least also +.IR LIBENV_PATH . +.TP +.B LIBENV_USER_PATHS +Environment variables that list directories +configured for the user. + +Environment variables with this classification +has at least also +.IR LIBENV_PATH . +.TP +.B LIBENV_PWD +Environment variables that contain +current and past working directories. + +Environment variables with this classification +has at least also +.IR LIBENV_PATH . +.TP +.B LIBENV_EXEC +Environment variables that contain +information about the executed utility. +.TP +.B LIBENV_PATH +Environment variables that contain +filesystem paths. + +Any environment variable with this +classification has at least one other +classification. +.TP +.B LIBENV_REMOTE_UNSAFE +Environment variables that should be removed +when entering a remote session. + +Any environment variable with this +classification has at least one other +classification. +.TP +.B LIBENV_REMOTE_SAFE +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. +.TP +.B LIBENV_LOGIN_UNSAFE +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. +.TP +.B LIBENV_LOGIN_SAFE +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. +.TP +.B LIBENV_SU_UNSAFE +Environment variables that should be removed +when escalating privileges. + +Any environment variable with this +classification has at least one other +classification. +.TP +.B LIBENV_SU_SAFE +Environment variables that should be can +safely be kepted when escalating privileges. + +Any environment variable with this +classification has at least one other +classification. + +.SH SEE ALSO +.BR libenv (7), +.BR libenv_get_chosen_list (3), +.BR libenv_filter_variable_list (3), +.BR libenv_select_variable_list (3). diff --git a/libenv.7 b/libenv.7 new file mode 100644 index 0000000..638a47f --- /dev/null +++ b/libenv.7 @@ -0,0 +1,33 @@ +.TH LIBENV 7 libenv +.SH NAME +libenv - Environment sanitation library + +.SH SYNOPSIS +.nf +#include <libenv.h> +.fi +.PP +Link with +.IR -lenv . + +.SH DESCRIPTION +The +.B libenv +software library is C library designed to help +utilities perform sanitation of environment variables. +.PP +Some utilities need to remove environment variables that are +not appropriate for the new context that the utility entires. +Likewise some utilities may meed to remove all except some +special environment variables. +.B libenv +provides a database of +environment variable variables that could be interesting and +provides functionality to describe the new context the is is +entered and filter out environment variables accordingly. + +.SH SEE ALSO +.BR libenv_filter_variable_list (3), +.BR libenv_select_variable_list (3), +.BR libenv_get_chosen_list (3), +.BR libenv_get_complete_list (3). diff --git a/libenv.h b/libenv.h new file mode 100644 index 0000000..a1ac96d --- /dev/null +++ b/libenv.h @@ -0,0 +1,563 @@ +/* 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 diff --git a/libenv_class.3 b/libenv_class.3 new file mode 120000 index 0000000..bda9b00 --- /dev/null +++ b/libenv_class.3 @@ -0,0 +1 @@ +enum_libenv_class.3
\ No newline at end of file diff --git a/libenv_filter_name_list.3 b/libenv_filter_name_list.3 new file mode 100644 index 0000000..8f9d44d --- /dev/null +++ b/libenv_filter_name_list.3 @@ -0,0 +1,82 @@ +.TH LIBENV_FILTER_NAME_LIST 3 libenv +.SH NAME +libenv_filter_name_list - Remove unwanted environment variables + +.SH SYNOPSIS +.nf +#include <libenv.h> + +size_t libenv_filter_name_list(const char **\fIvariables\fP, /* enum libenv_class */ ... /*, LIBENV_END */); +size_t libenv_vfilter_name_list(const char **\fIvariables\fP, va_list); +size_t libenv_filter_name_list_with_dealloc(char **\fIvariables\fP, /* enum libenv_class */ ... /*, LIBENV_END */); +size_t libenv_vfilter_name_list_with_dealloc(char **\fIvariables\fP, va_list); +.fi +.PP +Link with +.IR -lenv . + +.SH DESCRIPTION +The +.BR libenv_filter_name_list () +function removes element in +.I variables +that matches the name of an environment variable that +belong to all of the environment variable classes listed +after the +.I variables +argument. The list must end with +.I LIBENV_END +to mark indicate to the function that there are no +more arguments to read. +.PP +.I variables +should be a +.I NULL +terminated list, but may be +.IR NULL . +.PP +The +.BR libenv_filter_name_list_with_dealloc () +fucntion is a variant of the +.BR libenv_filter_name_list () +function that deallocates, using the +.BR free (3) +function, any remove element. +.PP +The +.BR libenv_vfilter_name_list () +and +.BR libenv_vfilter_name_list_with_dealloc () +functions are variants of the +.BR libenv_filter_name_list () +and +.BR libenv_filter_name_list_with_dealloc () +functions, respectively, that uses +.I va_list +instead of being properly variadic. + +.SH RETURN VALUE +The +.BR libenv_filter_name_list (), +.BR libenv_vfilter_name_list (), +.BR libenv_filter_name_list_with_dealloc (), +and +.BR libenv_vfilter_name_list_with_dealloc () +functions return the new number of elements in +.IR variables , +exclucing the +.I NULL +element at the end of the list. +0 if +.I variables +is +.IR NULL . + +.SH ERRORS +None. + +.SH SEE ALSO +.BR libenv (7), +.BR enum_libenv_class (3), +.BR libenv_filter_variable_list (3), +.BR libenv_select_name_list (3). diff --git a/libenv_filter_name_list.c b/libenv_filter_name_list.c new file mode 100644 index 0000000..bfcf3a2 --- /dev/null +++ b/libenv_filter_name_list.c @@ -0,0 +1,15 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +size_t +libenv_filter_name_list(const char **variables, ...) +{ + va_list classes; + va_start(classes, variables); + return libenv_vfilter_name_list(variables, classes); + va_end(classes); +} + + +/* TODO test */ diff --git a/libenv_filter_name_list_with_dealloc.3 b/libenv_filter_name_list_with_dealloc.3 new file mode 120000 index 0000000..2659ef1 --- /dev/null +++ b/libenv_filter_name_list_with_dealloc.3 @@ -0,0 +1 @@ +libenv_filter_name_list.3
\ No newline at end of file diff --git a/libenv_filter_name_list_with_dealloc.c b/libenv_filter_name_list_with_dealloc.c new file mode 100644 index 0000000..986be3b --- /dev/null +++ b/libenv_filter_name_list_with_dealloc.c @@ -0,0 +1,15 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +size_t +libenv_filter_name_list_with_dealloc(char **variables, ...) +{ + va_list classes; + va_start(classes, variables); + return libenv_vfilter_name_list_with_dealloc(variables, classes); + va_end(classes); +} + + +/* TODO test */ diff --git a/libenv_filter_variable_list.3 b/libenv_filter_variable_list.3 new file mode 100644 index 0000000..641f162 --- /dev/null +++ b/libenv_filter_variable_list.3 @@ -0,0 +1,84 @@ +.TH LIBENV_FILTER_VARIABLE_LIST 3 libenv +.SH NAME +libenv_filter_variable_list - Remove unwanted environment variables + +.SH SYNOPSIS +.nf +#include <libenv.h> + +size_t libenv_filter_variable_list(const char **\fIvariables\fP, /* enum libenv_class */ ... /*, LIBENV_END */); +size_t libenv_vfilter_variable_list(const char **\fIvariables\fP, va_list); +size_t libenv_filter_variable_list_with_dealloc(char **\fIvariables\fP, /* enum libenv_class */ ... /*, LIBENV_END */); +size_t libenv_vfilter_variable_list_with_dealloc(char **\fIvariables\fP, va_list); +.fi +.PP +Link with +.IR -lenv . + +.SH DESCRIPTION +The +.BR libenv_filter_variable_list () +function removes element in +.I variables +that matches the name, optionally with an equals sign +.RB ( = ) +followed by anything, of an environment variable that +belong to all of the environment variable classes listed +after the +.I variables +argument. The list must end with +.I LIBENV_END +to mark indicate to the function that there are no +more arguments to read. +.PP +.I variables +should be a +.I NULL +terminated list, but may be +.IR NULL . +.PP +The +.BR libenv_filter_variable_list_with_dealloc () +fucntion is a variant of the +.BR libenv_filter_variable_list () +function that deallocates, using the +.BR free (3) +function, any remove element. +.PP +The +.BR libenv_vfilter_variable_list () +and +.BR libenv_vfilter_variable_list_with_dealloc () +functions are variants of the +.BR libenv_filter_variable_list () +and +.BR libenv_filter_variable_list_with_dealloc () +functions, respectively, that uses +.I va_list +instead of being properly variadic. + +.SH RETURN VALUE +The +.BR libenv_filter_variable_list (), +.BR libenv_vfilter_variable_list (), +.BR libenv_filter_variable_list_with_dealloc (), +and +.BR libenv_vfilter_variable_list_with_dealloc () +functions return the new number of elements in +.IR variables , +exclucing the +.I NULL +element at the end of the list. +0 if +.I variables +is +.IR NULL . + +.SH ERRORS +None. + +.SH SEE ALSO +.BR libenv (7), +.BR enum_libenv_class (3), +.BR libenv_filter_name_list (3), +.BR libenv_select_variable_list (3). diff --git a/libenv_filter_variable_list.c b/libenv_filter_variable_list.c new file mode 100644 index 0000000..fa02ef9 --- /dev/null +++ b/libenv_filter_variable_list.c @@ -0,0 +1,15 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +size_t +libenv_filter_variable_list(const char **variables, ...) +{ + va_list classes; + va_start(classes, variables); + return libenv_vfilter_variable_list(variables, classes); + va_end(classes); +} + + +/* TODO test */ diff --git a/libenv_filter_variable_list_with_dealloc.3 b/libenv_filter_variable_list_with_dealloc.3 new file mode 120000 index 0000000..93f6429 --- /dev/null +++ b/libenv_filter_variable_list_with_dealloc.3 @@ -0,0 +1 @@ +libenv_filter_variable_list.3
\ No newline at end of file diff --git a/libenv_filter_variable_list_with_dealloc.c b/libenv_filter_variable_list_with_dealloc.c new file mode 100644 index 0000000..6332659 --- /dev/null +++ b/libenv_filter_variable_list_with_dealloc.c @@ -0,0 +1,15 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +size_t +libenv_filter_variable_list_with_dealloc(char **variables, ...) +{ + va_list classes; + va_start(classes, variables); + return libenv_vfilter_variable_list_with_dealloc(variables, classes); + va_end(classes); +} + + +/* TODO test */ diff --git a/libenv_get_chosen_list.3 b/libenv_get_chosen_list.3 new file mode 100644 index 0000000..0b87403 --- /dev/null +++ b/libenv_get_chosen_list.3 @@ -0,0 +1,69 @@ +.TH LIBENV_GET_CHOSEN_LIST 3 libenv +.SH NAME +libenv_get_chosen_list - List recognised environment variables by class + +.SH SYNOPSIS +.nf +#include <libenv.h> + +const char **libenv_get_chosen_list(enum libenv_class, ... /*, LIBENV_END */); +const char **libenv_vget_chosen_list(enum libenv_class, va_list); +.fi +.PP +Link with +.IR -lenv . + +.SH DESCRIPTION +The +.BR libenv_get_chosen_list () +function returns a +.I NULL +terminated list of the names of all environment variables, that it knows of, +regardless if they are set in the environemnt, and that belong to at least +one of the environment variable classes listed in the functions argument list. +The argument list must be termianted with +.I LIBENV_END +so that the function knonws when there are no more arguments to read. +.PP +The +.BR libenv_vget_chosen_list () +function is a variant of the +.BR libenv_get_chosen_list () +function that uses +.I va_list +rather than being properly variadic. + +.SH RETURN VALUE +Upon successful completion, the +.BR libenv_get_chosen_list () +and +.BR libenv_vget_chosen_list () +functions return a +.IR NULL - +terminated list of statically allocated +strings, representing environment variable names. +The returned list, but not it's element, shall +be deallocated using the +.BR free (3) +function. On failure +.I NULL +is returned and +.I errno +is appropriately set to describe the error. + +.SH ERRORS +The +.BR libenv_get_chosen_list () +and +.BR libenv_vget_chosen_list () +functions may fail if: +.TP +.B ENOMEM +Insufficient memory available. + +.SH SEE ALSO +.BR libenv (7), +.BR enum_libenv_class (3), +.BR libenv_get_complete_list (3), +.BR libenv_filter_variable_list (3), +.BR libenv_select_variable_list (3). diff --git a/libenv_get_chosen_list.c b/libenv_get_chosen_list.c new file mode 100644 index 0000000..f4975fd --- /dev/null +++ b/libenv_get_chosen_list.c @@ -0,0 +1,15 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +const char ** +libenv_get_chosen_list(enum libenv_class classes_head, ...) +{ + va_list classes_tail; + va_start(classes_tail, classes_head); + return libenv_vget_chosen_list(classes_head, classes_tail); + va_end(classes_tail); +} + + +/* TODO test */ diff --git a/libenv_get_complete_list.3 b/libenv_get_complete_list.3 new file mode 100644 index 0000000..83038a3 --- /dev/null +++ b/libenv_get_complete_list.3 @@ -0,0 +1,82 @@ +.TH LIBENV_GET_COMPLETE_LIST 3 libenv +.SH NAME +libenv_get_complete_list - List all recognised environment variables + +.SH SYNOPSIS +.nf +#include <libenv.h> + +struct libenv_variable { + const char *\fIname\fP; + const uint64_t *\fIclasses\fP; +}; + +const struct libenv_variable *libenv_get_complete_list(size_t *\fInclasswords_out\fP, size_t *\fIcount_out\fP); +.fi +.PP +Link with +.IR -lenv . + +.SH DESCRIPTION +The +.BR libenv_get_complete_list () +function returns a list of all environment variables the library knows of, +regardless of whether they are set in the environment. The function returns +a list of +.I struct libenv_variable +elements, for each of them, +.I .name +will be set to the name of the environment variable and +.I .classes +will be set to a bit field of classes the environment variable +belongs to. If +.IR (.classes[i]>>b)&1 , +then the +.BR "enum libenv_class" (3) +member with the value +.I i*64+b +describes a class the environment variable belongs to. (Make sure that you +do not compare against values greeater than or equal to +.IR *nclasswords_out*64 .) +The bit corresponding to +.I LIBENV_END +will always be 0. +.PP +Unless +.I nclasswords_out +is +.IR NULL , +.I *nclasswords_out +will be set to the number of elements +.RB ( uint64_t 's) +in each +.I .classes +for each returned +.IR "struct libenv_variable" . +.PP +Unless +.I count_out +is +.IR NULL , +.I *count_out +will be set to the number of returned environment variables. + +.SH RETURN VALUE +The +.BR libenv_get_complete_list (3) +function returns a statically allocated list of environment variables +along with the classifications; the list will contain +.I *count_out +(as set when the function returns) elements, plus one extra element, +at the end, having both its fields set to +.IR NULL . + +.SH ERRORS +None. + +.SH SEE ALSO +.BR libenv (7), +.BR enum_libenv_class (3), +.BR libenv_get_chosen_list (3), +.BR libenv_filter_variable_list (3), +.BR libenv_select_variable_list (3). diff --git a/libenv_get_complete_list.c b/libenv_get_complete_list.c new file mode 100644 index 0000000..9a542c9 --- /dev/null +++ b/libenv_get_complete_list.c @@ -0,0 +1,211 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +#define NCLASSWORDS 1U + + +#define _(E) ((uint64_t)1 << (E)) + +#define SU_SAFE _(LIBENV_SU_SAFE) +#define SU_UNSAFE _(LIBENV_SU_UNSAFE) +#define LOGIN_SAFE _(LIBENV_LOGIN_SAFE) +#define LOGIN_UNSAFE _(LIBENV_LOGIN_UNSAFE) +#define REMOTE_SAFE _(LIBENV_REMOTE_SAFE) +#define REMOTE_UNSAFE _(LIBENV_REMOTE_UNSAFE) +#define PATH (_(LIBENV_PATH) | REMOTE_UNSAFE) + +#define DECLARE(VAR, ENUMS_)\ + static const uint64_t VAR[NCLASSWORDS] = {ENUMS_} + +DECLARE(classes__display, _(LIBENV_DISPLAY) | SU_SAFE | LOGIN_SAFE | REMOTE_UNSAFE); +DECLARE(classes__display_config, _(LIBENV_DISPLAY_CONFIG) | SU_SAFE | LOGIN_SAFE | REMOTE_UNSAFE); +DECLARE(classes__desktop, _(LIBENV_DESKTOP) | SU_SAFE | LOGIN_SAFE | REMOTE_SAFE); +DECLARE(classes__terminal_caps, _(LIBENV_TERMINAL_CAPS) | SU_SAFE | LOGIN_SAFE | REMOTE_SAFE); +DECLARE(classes__local_terminal, _(LIBENV_LOCAL_TERMINAL) | SU_SAFE | LOGIN_SAFE | REMOTE_UNSAFE); +DECLARE(classes__locale, _(LIBENV_LOCALE) | SU_SAFE | LOGIN_UNSAFE | REMOTE_UNSAFE); +DECLARE(classes__locale__path, _(LIBENV_LOCALE) | SU_SAFE | LOGIN_UNSAFE | PATH); +DECLARE(classes__timezone, _(LIBENV_TIMEZONE) | SU_SAFE | LOGIN_UNSAFE | REMOTE_UNSAFE); +DECLARE(classes__timezone__path, _(LIBENV_TIMEZONE) | SU_SAFE | LOGIN_UNSAFE | PATH); +DECLARE(classes__session, _(LIBENV_SESSION) | SU_SAFE | LOGIN_SAFE | REMOTE_UNSAFE); +DECLARE(classes__theme_config, _(LIBENV_THEME_CONFIG) | SU_SAFE | LOGIN_UNSAFE | REMOTE_SAFE); +DECLARE(classes__theme_plugin, _(LIBENV_THEME_PLUGIN) | SU_UNSAFE | LOGIN_UNSAFE | REMOTE_UNSAFE); +DECLARE(classes__internet, _(LIBENV_INTERNET) | SU_SAFE | LOGIN_UNSAFE | REMOTE_UNSAFE); +DECLARE(classes__audio, _(LIBENV_AUDIO) | SU_SAFE | LOGIN_SAFE | REMOTE_UNSAFE); +DECLARE(classes__user, _(LIBENV_USER) | SU_UNSAFE | LOGIN_UNSAFE | REMOTE_UNSAFE); +DECLARE(classes__applications, _(LIBENV_APPLICATIONS) | SU_SAFE | LOGIN_UNSAFE | REMOTE_UNSAFE); +DECLARE(classes__preferences, _(LIBENV_PREFERENCES) | SU_SAFE | LOGIN_UNSAFE | REMOTE_SAFE); +DECLARE(classes__system_paths, _(LIBENV_SYSTEM_PATHS) | SU_SAFE | LOGIN_UNSAFE | PATH); +DECLARE(classes__user_paths, _(LIBENV_USER_PATHS) | SU_SAFE | LOGIN_UNSAFE | PATH); +DECLARE(classes__pwd, _(LIBENV_PWD) | SU_SAFE | LOGIN_UNSAFE | PATH); +DECLARE(classes__exec__path, _(LIBENV_EXEC) | SU_SAFE | LOGIN_UNSAFE | PATH); + +#undef _ +#undef SU_SAFE +#undef SU_UNSAFE +#undef LOGIN_SAFE +#undef LOGIN_UNSAFE +#undef REMOTE_SAFE +#undef REMOTE_UNSAFE +#undef PATH +#undef DECLARE +#define V(S) {S, CLASSES} + + +static struct libenv_variable list[] = { + +#define CLASSES classes__display + V("DISPLAY"), + V("WAYLAND_DISPLAY"), + V("XAUTHORITY"), + V("XDG_SEAT"), + V("XDG_SEAT_PATH"), + V("XDG_VTNR"), +#undef CLASSES + +#define CLASSES classes__display_config + V("SDL_VIDEO_FULLSCREEN_DISPLAY"), + V("XMODIFIERS"), +#undef CLASSES + +#define CLASSES classes__desktop + V("DESKTOP_SESSION"), + V("GTK_CSD"), + V("XDG_SESSION_PATH"), + V("XDG_SESSION_DESKTOP"), + V("XDG_SESSION_TYPE"), + V("XDG_SESSION_CLASS"), + V("XDG_SESSION_ID"), + V("_JAVA_AWT_WM_NOREPARENTING"), +#undef CLASSES + +#define CLASSES classes__terminal_caps + V("TERM"), + V("COLORTERM"), + V("VTE_VERSION"), +#undef CLASSES + +#define CLASSES classes__local_terminal + V("TERMINATOR_UUID"), +#undef CLASSES + +#define CLASSES classes__locale + V("LANG"), + V("LANGUAGE"), + V("LOCALE"), + V("LC_CTYPE"), + V("LC_NUMERIC"), + V("LC_TIME"), + V("LC_COLLATE"), + V("LC_MONETARY"), + V("LC_MESSAGES"), + V("LC_PAPER"), + V("LC_NAME"), + V("LC_ADDRESS"), + V("LC_TELEPHONE"), + V("LC_MEASUREMENT"), + V("LC_IDENTIFICATION"), + V("LC_ALL"), +#undef CLASSES + +#define CLASSES classes__locale__path + V("LOCPATH"), + V("NLSPATH"), +#undef CLASSES + +#define CLASSES classes__timezone + V("TZ"), +#undef CLASSES + +#define CLASSES classes__timezone__path + V("TZDIR"), +#undef CLASSES + +#define CLASSES classes__session + V("SSH_CLIENT"), + V("SSH_CONNECTION"), + V("SSH_TTY"), +#undef CLASSES + +#define CLASSES classes__theme_config + V("LS_COLORS"), +#undef CLASSES + +#define CLASSES classes__theme_plugin + V("GTK_THEME"), + V("QT_STYLE_OVERRIDE"), + V("QT_QPA_PLATFORMTHEME"), +#undef CLASSES + +#define CLASSES classes__internet + V("ftp_proxy"), + V("http_proxy"), +#undef CLASSES + +#define CLASSES classes__audio + V("MAIN_ALSA_MIXER"), + V("MAIN_ALSA_CARD"), +#undef CLASSES + +#define CLASSES classes__user + V("LOGNAME"), + V("HOME"), + V("SHELL"), +#undef CLASSES + +#define CLASSES classes__applications + V("EDITOR"), + V("VISUAL"), + V("BROWSER"), + V("PAGER"), +#undef CLASSES + +#define CLASSES classes__preferences + V("MANSECT"), + V("_JAVA_OPTIONS"), +#undef CLASSES + +#define CLASSES classes__system_paths + V("PATH"), + V("XDG_DATA_DIRS"), + V("XDG_CONFIG_DIRS"), + V("MANPATH"), + V("INFODIR"), + V("JAVA_HOME"), +#undef CLASSES + +#define CLASSES classes__user_paths + V("XDG_SPOOL_HOME"), + V("XDG_CACHE_HOME"), + V("XDG_STATE_HOME"), + V("XDG_RUNTIME_DIR"), + V("XDG_DATA_HOME"), + V("XDG_CONFIG_HOME"), + V("GNUPGHOME"), + V("MPLAYER_HOME"), +#undef CLASSES + +#define CLASSES classes__pwd + V("PWD"), + V("OLDPWD"), +#undef CLASSES + +#define CLASSES classes__exec__path + V("_"), +#undef CLASSES + + {NULL, NULL} +}; + + +#undef V + + +const struct libenv_variable * +libenv_get_complete_list(size_t *nclasswords_out, size_t *count_out) /* TODO test */ +{ + if (nclasswords_out) + *nclasswords_out = NCLASSWORDS; + if (count_out) + *count_out = sizeof(list) / sizeof(*list) - 1U; + return list; +} diff --git a/libenv_select_name_list.3 b/libenv_select_name_list.3 new file mode 100644 index 0000000..6addcd1 --- /dev/null +++ b/libenv_select_name_list.3 @@ -0,0 +1,82 @@ +.TH LIBENV_SELECT_NAME_LIST 3 libenv +.SH NAME +libenv_select_name_list - Keep wanted environment variables + +.SH SYNOPSIS +.nf +#include <libenv.h> + +size_t libenv_select_name_list(const char **\fIvariables\fP, /* enum libenv_class */ ... /*, LIBENV_END */); +size_t libenv_vselect_name_list(const char **\fIvariables\fP, va_list \fIclasses\fP); +size_t libenv_select_name_list_with_dealloc(char **\fIvariables\fP, /* enum libenv_class */ ... /*, LIBENV_END */); +size_t libenv_vselect_name_list_with_dealloc(char **\fIvariables\fP, va_list \fIclasses\fP); +.fi +.PP +Link with +.IR -lenv . + +.SH DESCRIPTION +The +.BR libenv_select_name_list () +function removes element in +.I variables +that matches the name of an environment variable that +do not belong to ant of the environment variable classes +listed after the +.I variables +argument. The list must end with +.I LIBENV_END +to mark indicate to the function that there are no +more arguments to read. +.PP +.I variables +should be a +.I NULL +terminated list, but may be +.IR NULL . +.PP +The +.BR libenv_select_name_list_with_dealloc () +fucntion is a variant of the +.BR libenv_select_name_list () +function that deallocates, using the +.BR free (3) +function, any remove element. +.PP +The +.BR libenv_vselect_name_list () +and +.BR libenv_vselect_name_list_with_dealloc () +functions are variants of the +.BR libenv_select_name_list () +and +.BR libenv_select_name_list_with_dealloc () +functions, respectively, that uses +.I va_list +instead of being properly variadic. + +.SH RETURN VALUE +The +.BR libenv_select_name_list (), +.BR libenv_vselect_name_list (), +.BR libenv_select_name_list_with_dealloc (), +and +.BR libenv_vselect_name_list_with_dealloc () +functions return the new number of elements in +.IR variables , +exclucing the +.I NULL +element at the end of the list. +0 if +.I variables +is +.IR NULL . + +.SH ERRORS +None. + +.SH SEE ALSO +.BR libenv (7), +.BR enum_libenv_class (3), +.BR libenv_select_variable_list (3), +.BR libenv_filter_name_list (3). diff --git a/libenv_select_name_list.c b/libenv_select_name_list.c new file mode 100644 index 0000000..705e499 --- /dev/null +++ b/libenv_select_name_list.c @@ -0,0 +1,15 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +size_t +libenv_select_name_list(const char **variables, ...) +{ + va_list classes; + va_start(classes, variables); + return libenv_vselect_name_list(variables, classes); + va_end(classes); +} + + +/* TODO test */ diff --git a/libenv_select_name_list_with_dealloc.3 b/libenv_select_name_list_with_dealloc.3 new file mode 120000 index 0000000..cdc3847 --- /dev/null +++ b/libenv_select_name_list_with_dealloc.3 @@ -0,0 +1 @@ +libenv_select_name_list.3
\ No newline at end of file diff --git a/libenv_select_name_list_with_dealloc.c b/libenv_select_name_list_with_dealloc.c new file mode 100644 index 0000000..b6bc0ca --- /dev/null +++ b/libenv_select_name_list_with_dealloc.c @@ -0,0 +1,15 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +size_t +libenv_select_name_list_with_dealloc(char **variables, ...) +{ + va_list classes; + va_start(classes, variables); + return libenv_vselect_name_list_with_dealloc(variables, classes); + va_end(classes); +} + + +/* TODO test */ diff --git a/libenv_select_variable_list.3 b/libenv_select_variable_list.3 new file mode 100644 index 0000000..2ec8427 --- /dev/null +++ b/libenv_select_variable_list.3 @@ -0,0 +1,84 @@ +.TH LIBENV_SELECT_VARIABLE_LIST 3 libenv +.SH NAME +libenv_select_variable_list - Keep wanted environment variables + +.SH SYNOPSIS +.nf +#include <libenv.h> + +size_t libenv_select_variable_list(const char **\fIvariables\fP, /* enum libenv_class */ ... /*, LIBENV_END */); +size_t libenv_vselect_variable_list(const char **\fIvariables\fP, va_list \fIclasses\fP); +size_t libenv_select_variable_list_with_dealloc(char **\fIvariables\fP, /* enum libenv_class */ ... /*, LIBENV_END */); +size_t libenv_vselect_variable_list_with_dealloc(char **\fIvariables\fP, va_list \fIclasses\fP); +.fi +.PP +Link with +.IR -lenv . + +.SH DESCRIPTION +The +.BR libenv_select_variable_list () +function removes element in +.I variables +that matches the name, optionally with an equals sign +.RB ( = ) +followed by anything, of an environment variable that +do not belong to any of the environment variable classes +listed after the +.I variables +argument. The list must end with +.I LIBENV_END +to mark indicate to the function that there are no +more arguments to read. +.PP +.I variables +should be a +.I NULL +terminated list, but may be +.IR NULL . +.PP +The +.BR libenv_select_variable_list_with_dealloc () +fucntion is a variant of the +.BR libenv_select_variable_list () +function that deallocates, using the +.BR free (3) +function, any remove element. +.PP +The +.BR libenv_vselect_variable_list () +and +.BR libenv_vselect_variable_list_with_dealloc () +functions are variants of the +.BR libenv_select_variable_list () +and +.BR libenv_select_variable_list_with_dealloc () +functions, respectively, that uses +.I va_list +instead of being properly variadic. + +.SH RETURN VALUE +The +.BR libenv_select_variable_list (), +.BR libenv_vselect_variable_list (), +.BR libenv_select_variable_list_with_dealloc (), +and +.BR libenv_vselect_variable_list_with_dealloc () +functions return the new number of elements in +.IR variables , +exclucing the +.I NULL +element at the end of the list. +0 if +.I variables +is +.IR NULL . + +.SH ERRORS +None. + +.SH SEE ALSO +.BR libenv (7), +.BR enum_libenv_class (3), +.BR libenv_select_name_list (3), +.BR libenv_filter_variable_list (3). diff --git a/libenv_select_variable_list.c b/libenv_select_variable_list.c new file mode 100644 index 0000000..ff902af --- /dev/null +++ b/libenv_select_variable_list.c @@ -0,0 +1,15 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +size_t +libenv_select_variable_list(const char **variables, ...) +{ + va_list classes; + va_start(classes, variables); + return libenv_vselect_variable_list(variables, classes); + va_end(classes); +} + + +/* TODO test */ diff --git a/libenv_select_variable_list_with_dealloc.3 b/libenv_select_variable_list_with_dealloc.3 new file mode 120000 index 0000000..a3d0b53 --- /dev/null +++ b/libenv_select_variable_list_with_dealloc.3 @@ -0,0 +1 @@ +libenv_select_variable_list.3
\ No newline at end of file diff --git a/libenv_select_variable_list_with_dealloc.c b/libenv_select_variable_list_with_dealloc.c new file mode 100644 index 0000000..0018577 --- /dev/null +++ b/libenv_select_variable_list_with_dealloc.c @@ -0,0 +1,15 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +size_t +libenv_select_variable_list_with_dealloc(char **variables, ...) +{ + va_list classes; + va_start(classes, variables); + return libenv_vselect_variable_list_with_dealloc(variables, classes); + va_end(classes); +} + + +/* TODO test */ diff --git a/libenv_variable.3 b/libenv_variable.3 new file mode 120000 index 0000000..1be54f7 --- /dev/null +++ b/libenv_variable.3 @@ -0,0 +1 @@ +struct_libenv_variable.3
\ No newline at end of file diff --git a/libenv_vfilter_name_list.3 b/libenv_vfilter_name_list.3 new file mode 120000 index 0000000..2659ef1 --- /dev/null +++ b/libenv_vfilter_name_list.3 @@ -0,0 +1 @@ +libenv_filter_name_list.3
\ No newline at end of file diff --git a/libenv_vfilter_name_list.c b/libenv_vfilter_name_list.c new file mode 100644 index 0000000..7ed841a --- /dev/null +++ b/libenv_vfilter_name_list.c @@ -0,0 +1,12 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +size_t +libenv_vfilter_name_list(const char **variables, va_list classes) +{ + return libenv_vprocess_list_without_dealloc__(variables, 0, classes, NO_HEAD, NAMES, FILTER); +} + + +/* TODO test */ diff --git a/libenv_vfilter_name_list_with_dealloc.3 b/libenv_vfilter_name_list_with_dealloc.3 new file mode 120000 index 0000000..a302738 --- /dev/null +++ b/libenv_vfilter_name_list_with_dealloc.3 @@ -0,0 +1 @@ +libenv_vfilter_name_list.3
\ No newline at end of file diff --git a/libenv_vfilter_name_list_with_dealloc.c b/libenv_vfilter_name_list_with_dealloc.c new file mode 100644 index 0000000..5140c57 --- /dev/null +++ b/libenv_vfilter_name_list_with_dealloc.c @@ -0,0 +1,12 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +size_t +libenv_vfilter_name_list_with_dealloc(char **variables, va_list classes) +{ + return libenv_vprocess_list_with_dealloc__(variables, 0, classes, NO_HEAD, NAMES, FILTER); +} + + +/* TODO test */ diff --git a/libenv_vfilter_variable_list.3 b/libenv_vfilter_variable_list.3 new file mode 120000 index 0000000..93f6429 --- /dev/null +++ b/libenv_vfilter_variable_list.3 @@ -0,0 +1 @@ +libenv_filter_variable_list.3
\ No newline at end of file diff --git a/libenv_vfilter_variable_list.c b/libenv_vfilter_variable_list.c new file mode 100644 index 0000000..6e8f371 --- /dev/null +++ b/libenv_vfilter_variable_list.c @@ -0,0 +1,12 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +size_t +libenv_vfilter_variable_list(const char **variables, va_list classes) +{ + return libenv_vprocess_list_without_dealloc__(variables, 0, classes, NO_HEAD, VARIABLES, FILTER); +} + + +/* TODO test */ diff --git a/libenv_vfilter_variable_list_with_dealloc.3 b/libenv_vfilter_variable_list_with_dealloc.3 new file mode 120000 index 0000000..bdbaea6 --- /dev/null +++ b/libenv_vfilter_variable_list_with_dealloc.3 @@ -0,0 +1 @@ +libenv_vfilter_variable_list.3
\ No newline at end of file diff --git a/libenv_vfilter_variable_list_with_dealloc.c b/libenv_vfilter_variable_list_with_dealloc.c new file mode 100644 index 0000000..65431db --- /dev/null +++ b/libenv_vfilter_variable_list_with_dealloc.c @@ -0,0 +1,12 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +size_t +libenv_vfilter_variable_list_with_dealloc(char **variables, va_list classes) +{ + return libenv_vprocess_list_with_dealloc__(variables, 0, classes, NO_HEAD, VARIABLES, FILTER); +} + + +/* TODO test */ diff --git a/libenv_vget_chosen_list.3 b/libenv_vget_chosen_list.3 new file mode 120000 index 0000000..8878673 --- /dev/null +++ b/libenv_vget_chosen_list.3 @@ -0,0 +1 @@ +libenv_get_chosen_list.3
\ No newline at end of file diff --git a/libenv_vget_chosen_list.c b/libenv_vget_chosen_list.c new file mode 100644 index 0000000..2a5e1e6 --- /dev/null +++ b/libenv_vget_chosen_list.c @@ -0,0 +1,23 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +const char ** +libenv_vget_chosen_list(enum libenv_class classes_head, va_list classes_tail) +{ + size_t count; + const struct libenv_variable *vars; + const char **names; + size_t i; + vars = libenv_get_complete_list(NULL, &count); + names = malloc((count + 1U) * sizeof(*names)); + if (!names) + return NULL; + for (i = 0; i < count; i++) + names[i] = vars[i].name; + libenv_vprocess_list_without_dealloc__(names, classes_head, classes_tail, HAVE_HEAD, NAMES, SELECT); + return names; +} + + +/* TODO test */ diff --git a/libenv_vprocess_list__.c b/libenv_vprocess_list__.c new file mode 100644 index 0000000..1124a63 --- /dev/null +++ b/libenv_vprocess_list__.c @@ -0,0 +1,64 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +static int +matches(const char *var, const struct libenv_variable *known, int is_name_only, + enum libenv_class classes_head, va_list classes_tail, int all, size_t nclasswords) +{ + size_t i, w, b; + for (; known->name; known++) { + for (i = 0;; i++) + if (var[i] != known->name[i]) + break; + if (known->name[i]) + continue; + if (var[i] == (is_name_only ? '\0' : '=')) + goto found; + } + return 0; + +found: + for (; classes_head; classes_head = va_arg(classes_tail, enum libenv_class)) { + w = (size_t)classes_head / 64U; + b = (size_t)classes_head % 64U; + if (w >= nclasswords && ((known->classes[w] >> b) & 1)) { + if (!all) + return 1; + } else { + if (all) + return 0; + } + } + return all; +} + +size_t +libenv_vprocess_list__(void *variables_, enum libenv_class classes_head, va_list classes_tail, + int have_head, int names, int filter, int all, int dealloc) +{ + char **variables = variables_; + const struct libenv_variable *known; + size_t nclasswords; + size_t i, n = 0; + va_list classes_tail_2; + + if (!variables) + return 0; + if (!have_head) + classes_head = va_arg(classes_tail, enum libenv_class); + + known = libenv_get_complete_list(&nclasswords, NULL); + + for (i = 0; variables[i]; i++) { + va_copy(classes_tail_2, classes_tail); + if (filter ^ matches(variables[i], known, names, classes_head, classes_tail_2, all, nclasswords)) + variables[n++] = variables[i]; + else if (dealloc) + free(variables[i]); + va_end(classes_tail_2); + } + + variables[n] = NULL; + return n; +} diff --git a/libenv_vselect_name_list.3 b/libenv_vselect_name_list.3 new file mode 120000 index 0000000..cdc3847 --- /dev/null +++ b/libenv_vselect_name_list.3 @@ -0,0 +1 @@ +libenv_select_name_list.3
\ No newline at end of file diff --git a/libenv_vselect_name_list.c b/libenv_vselect_name_list.c new file mode 100644 index 0000000..5eef51e --- /dev/null +++ b/libenv_vselect_name_list.c @@ -0,0 +1,12 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +size_t +libenv_vselect_name_list(const char **variables, va_list classes) +{ + return libenv_vprocess_list_without_dealloc__(variables, 0, classes, NO_HEAD, NAMES, SELECT); +} + + +/* TODO test */ diff --git a/libenv_vselect_name_list_with_dealloc.3 b/libenv_vselect_name_list_with_dealloc.3 new file mode 120000 index 0000000..1e34bf7 --- /dev/null +++ b/libenv_vselect_name_list_with_dealloc.3 @@ -0,0 +1 @@ +libenv_vselect_name_list.3
\ No newline at end of file diff --git a/libenv_vselect_name_list_with_dealloc.c b/libenv_vselect_name_list_with_dealloc.c new file mode 100644 index 0000000..95f35ed --- /dev/null +++ b/libenv_vselect_name_list_with_dealloc.c @@ -0,0 +1,12 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +size_t +libenv_vselect_name_list_with_dealloc(char **variables, va_list classes) +{ + return libenv_vprocess_list_with_dealloc__(variables, 0, classes, NO_HEAD, NAMES, SELECT); +} + + +/* TODO test */ diff --git a/libenv_vselect_variable_list.3 b/libenv_vselect_variable_list.3 new file mode 120000 index 0000000..a3d0b53 --- /dev/null +++ b/libenv_vselect_variable_list.3 @@ -0,0 +1 @@ +libenv_select_variable_list.3
\ No newline at end of file diff --git a/libenv_vselect_variable_list.c b/libenv_vselect_variable_list.c new file mode 100644 index 0000000..0e57710 --- /dev/null +++ b/libenv_vselect_variable_list.c @@ -0,0 +1,12 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +size_t +libenv_vselect_variable_list(const char **variables, va_list classes) +{ + return libenv_vprocess_list_without_dealloc__(variables, 0, classes, NO_HEAD, VARIABLES, SELECT); +} + + +/* TODO test */ diff --git a/libenv_vselect_variable_list_with_dealloc.3 b/libenv_vselect_variable_list_with_dealloc.3 new file mode 120000 index 0000000..aaa2e0e --- /dev/null +++ b/libenv_vselect_variable_list_with_dealloc.3 @@ -0,0 +1 @@ +libenv_vselect_variable_list.3
\ No newline at end of file diff --git a/libenv_vselect_variable_list_with_dealloc.c b/libenv_vselect_variable_list_with_dealloc.c new file mode 100644 index 0000000..cec9d7a --- /dev/null +++ b/libenv_vselect_variable_list_with_dealloc.c @@ -0,0 +1,12 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +size_t +libenv_vselect_variable_list_with_dealloc(char **variables, va_list classes) +{ + return libenv_vprocess_list_with_dealloc__(variables, 0, classes, NO_HEAD, VARIABLES, SELECT); +} + + +/* TODO test */ diff --git a/mk/linux.mk b/mk/linux.mk new file mode 100644 index 0000000..ad58f69 --- /dev/null +++ b/mk/linux.mk @@ -0,0 +1,6 @@ +LIBEXT = so +LIBFLAGS = -shared -Wl,-soname,lib$(LIB_NAME).$(LIBEXT).$(LIB_MAJOR) +LIBMAJOREXT = $(LIBEXT).$(LIB_MAJOR) +LIBMINOREXT = $(LIBEXT).$(LIB_VERSION) + +FIX_INSTALL_NAME = : diff --git a/mk/macos.mk b/mk/macos.mk new file mode 100644 index 0000000..7e2d25c --- /dev/null +++ b/mk/macos.mk @@ -0,0 +1,6 @@ +LIBEXT = dylib +LIBFLAGS = -dynamiclib -Wl,-compatibility_version,$(LIB_MAJOR) -Wl,-current_version,$(LIB_VERSION) +LIBMAJOREXT = $(LIB_MAJOR).$(LIBEXT) +LIBMINOREXT = $(LIB_VERSION).$(LIBEXT) + +FIX_INSTALL_NAME = install_name_tool -id "$(PREFIX)/lib/libenv.$(LIBMAJOREXT)" diff --git a/mk/windows.mk b/mk/windows.mk new file mode 100644 index 0000000..ed5ec8d --- /dev/null +++ b/mk/windows.mk @@ -0,0 +1,6 @@ +LIBEXT = dll +LIBFLAGS = -shared +LIBMAJOREXT = $(LIB_MAJOR).$(LIBEXT) +LIBMINOREXT = $(LIB_VERSION).$(LIBEXT) + +FIX_INSTALL_NAME = : diff --git a/struct_libenv_variable.3 b/struct_libenv_variable.3 new file mode 120000 index 0000000..8bb2806 --- /dev/null +++ b/struct_libenv_variable.3 @@ -0,0 +1 @@ +libenv_get_complete_list.3
\ No newline at end of file |