xref: /netbsd-src/external/ibm-public/postfix/dist/src/util/clean_env.c (revision c48c605c14fd8622b523d1d6a3f0c0bad133ea89)
1 /*	$NetBSD: clean_env.c,v 1.3 2023/12/23 20:30:46 christos Exp $	*/
2 
3 /*++
4 /* NAME
5 /*	clean_env 3
6 /* SUMMARY
7 /*	clean up the environment
8 /* SYNOPSIS
9 /*	#include <clean_env.h>
10 /*
11 /*	void	clean_env(preserve_list)
12 /*	const char **preserve_list;
13 /*
14 /*	void	update_env(preserve_list)
15 /*	const char **preserve_list;
16 /* DESCRIPTION
17 /*	clean_env() reduces the process environment to the bare minimum.
18 /*	The function takes a null-terminated list of arguments.
19 /*	Each argument specifies the name of an environment variable
20 /*	that should be preserved, or specifies a name=value that should
21 /*	be entered into the new environment.
22 /*
23 /*	update_env() applies name=value settings, but otherwise does not
24 /*	change the process environment.
25 /* DIAGNOSTICS
26 /*	Fatal error: out of memory.
27 /* SEE ALSO
28 /*	safe_getenv(3), guarded getenv()
29 /* LICENSE
30 /* .ad
31 /* .fi
32 /*	The Secure Mailer license must be distributed with this software.
33 /* AUTHOR(S)
34 /*	Wietse Venema
35 /*	IBM T.J. Watson Research
36 /*	P.O. Box 704
37 /*	Yorktown Heights, NY 10598, USA
38 /*
39 /*	Wietse Venema
40 /*	Google, Inc.
41 /*	111 8th Avenue
42 /*	New York, NY 10011, USA
43 /*--*/
44 
45 /* System library. */
46 
47 #include <sys_defs.h>
48 #include <stdlib.h>
49 #include <unistd.h>
50 #include <string.h>
51 
52 /* Utility library. */
53 
54 #include <msg.h>
55 #include <mymalloc.h>
56 #include <argv.h>
57 #include <safe.h>
58 #include <clean_env.h>
59 #include <stringops.h>
60 
61 /* clean_env - clean up the environment */
62 
clean_env(char ** preserve_list)63 void    clean_env(char **preserve_list)
64 {
65     extern char **environ;
66     ARGV   *save_list;
67     char   *value;
68     char  **cpp;
69     char   *copy;
70     char   *key;
71     char   *val;
72     const char *err;
73 
74     /*
75      * Preserve or specify selected environment variables.
76      */
77     save_list = argv_alloc(10);
78     for (cpp = preserve_list; *cpp; cpp++) {
79 	if (strchr(*cpp, '=') != 0) {
80 	    copy = mystrdup(*cpp);
81 	    err = split_nameval(copy, &key, &val);
82 	    if (err != 0)
83 		msg_fatal("clean_env: %s in: %s", err, *cpp);
84 	    argv_add(save_list, key, val, (char *) 0);
85 	    myfree(copy);
86 	} else if ((value = safe_getenv(*cpp)) != 0) {
87 	    argv_add(save_list, *cpp, value, (char *) 0);
88 	}
89     }
90 
91     /*
92      * Truncate the process environment, if available. On some systems
93      * (Ultrix!), environ can be a null pointer.
94      */
95     if (environ)
96 	environ[0] = 0;
97 
98     /*
99      * Restore preserved environment variables.
100      */
101     for (cpp = save_list->argv; *cpp; cpp += 2)
102 	if (setenv(cpp[0], cpp[1], 1))
103 	    msg_fatal("setenv(%s, %s): %m", cpp[0], cpp[1]);
104 
105     /*
106      * Cleanup.
107      */
108     argv_free(save_list);
109 }
110 
111 /* update_env - apply name=value settings only */
112 
update_env(char ** preserve_list)113 void    update_env(char **preserve_list)
114 {
115     char  **cpp;
116     ARGV   *save_list;
117     char   *copy;
118     char   *key;
119     char   *val;
120     const char *err;
121 
122     /*
123      * Extract name=value settings.
124      */
125     save_list = argv_alloc(10);
126     for (cpp = preserve_list; *cpp; cpp++) {
127 	if (strchr(*cpp, '=') != 0) {
128 	    copy = mystrdup(*cpp);
129 	    err = split_nameval(copy, &key, &val);
130 	    if (err != 0)
131 		msg_fatal("update_env: %s in: %s", err, *cpp);
132 	    argv_add(save_list, key, val, (char *) 0);
133 	    myfree(copy);
134 	}
135     }
136 
137     /*
138      * Apply name=value settings.
139      */
140     for (cpp = save_list->argv; *cpp; cpp += 2)
141 	if (setenv(cpp[0], cpp[1], 1))
142 	    msg_fatal("setenv(%s, %s): %m", cpp[0], cpp[1]);
143 
144     /*
145      * Cleanup.
146      */
147     argv_free(save_list);
148 }
149 
150 #ifdef TEST
151 
152 #include <stdlib.h>
153 #include <vstream.h>
154 
main(int argc,char ** argv)155 int     main(int argc, char **argv)
156 {
157     extern char **environ;
158     char  **cpp;
159 
160     clean_env(argv + 1);
161     for (cpp = environ; *cpp; cpp++)
162 	vstream_printf("%s\n", *cpp);
163     vstream_fflush(VSTREAM_OUT);
164     exit(0);
165 }
166 
167 #endif
168