1/*
2 * Copyright (c) 2000-2003, 2007 Sendmail, Inc. and its suppliers.
3 *	All rights reserved.
4 *
5 * By using this file, you agree to the terms and conditions set
6 * forth in the LICENSE file which can be found at the top level of
7 * the sendmail distribution.
8 *
9 */
10
11#pragma ident	"%Z%%M%	%I%	%E% SMI"
12
13#include <sm/gen.h>
14SM_RCSID("@(#)$Id: config.c,v 1.31 2007/03/14 21:21:49 ca Exp $")
15
16#include <stdlib.h>
17#include <sm/heap.h>
18#include <sm/string.h>
19#include <sm/conf.h>
20
21/*
22**  PUTENV -- emulation of putenv() in terms of setenv()
23**
24**	Not needed on Posix-compliant systems.
25**	This doesn't have full Posix semantics, but it's good enough
26**		for sendmail.
27**
28**	Parameter:
29**		env -- the environment to put.
30**
31**	Returns:
32**		0 on success, < 0 on failure.
33*/
34
35#if NEEDPUTENV
36
37# if NEEDPUTENV == 2		/* no setenv(3) call available */
38
39int
40putenv(str)
41	char *str;
42{
43	char **current;
44	int matchlen, envlen = 0;
45	char *tmp;
46	char **newenv;
47	static bool first = true;
48	extern char **environ;
49
50	/*
51	**  find out how much of str to match when searching
52	**  for a string to replace.
53	*/
54
55	if ((tmp = strchr(str, '=')) == NULL || tmp == str)
56		matchlen = strlen(str);
57	else
58		matchlen = (int) (tmp - str);
59	++matchlen;
60
61	/*
62	**  Search for an existing string in the environment and find the
63	**  length of environ.  If found, replace and exit.
64	*/
65
66	for (current = environ; *current != NULL; current++)
67	{
68		++envlen;
69
70		if (strncmp(str, *current, matchlen) == 0)
71		{
72			/* found it, now insert the new version */
73			*current = (char *) str;
74			return 0;
75		}
76	}
77
78	/*
79	**  There wasn't already a slot so add space for a new slot.
80	**  If this is our first time through, use malloc(), else realloc().
81	*/
82
83	if (first)
84	{
85		newenv = (char **) sm_malloc(sizeof(char *) * (envlen + 2));
86		if (newenv == NULL)
87			return -1;
88
89		first = false;
90		(void) memcpy(newenv, environ, sizeof(char *) * envlen);
91	}
92	else
93	{
94		newenv = (char **) sm_realloc((char *) environ,
95					      sizeof(char *) * (envlen + 2));
96		if (newenv == NULL)
97			return -1;
98	}
99
100	/* actually add in the new entry */
101	environ = newenv;
102	environ[envlen] = (char *) str;
103	environ[envlen + 1] = NULL;
104
105	return 0;
106}
107
108# else /* NEEDPUTENV == 2 */
109
110int
111putenv(env)
112	char *env;
113{
114	char *p;
115	int l;
116	char nbuf[100];
117
118	p = strchr(env, '=');
119	if (p == NULL)
120		return 0;
121	l = p - env;
122	if (l > sizeof nbuf - 1)
123		l = sizeof nbuf - 1;
124	memmove(nbuf, env, l);
125	nbuf[l] = '\0';
126	return setenv(nbuf, ++p, 1);
127}
128
129# endif /* NEEDPUTENV == 2 */
130#endif /* NEEDPUTENV */
131/*
132**  UNSETENV -- remove a variable from the environment
133**
134**	Not needed on newer systems.
135**
136**	Parameters:
137**		name -- the string name of the environment variable to be
138**			deleted from the current environment.
139**
140**	Returns:
141**		none.
142**
143**	Globals:
144**		environ -- a pointer to the current environment.
145**
146**	Side Effects:
147**		Modifies environ.
148*/
149
150#if !HASUNSETENV
151
152void
153unsetenv(name)
154	char *name;
155{
156	extern char **environ;
157	register char **pp;
158	int len = strlen(name);
159
160	for (pp = environ; *pp != NULL; pp++)
161	{
162		if (strncmp(name, *pp, len) == 0 &&
163		    ((*pp)[len] == '=' || (*pp)[len] == '\0'))
164			break;
165	}
166
167	for (; *pp != NULL; pp++)
168		*pp = pp[1];
169}
170
171#endif /* !HASUNSETENV */
172
173char *SmCompileOptions[] =
174{
175#if SM_CONF_BROKEN_STRTOD
176	"SM_CONF_BROKEN_STRTOD",
177#endif /* SM_CONF_BROKEN_STRTOD */
178#if SM_CONF_GETOPT
179	"SM_CONF_GETOPT",
180#endif /* SM_CONF_GETOPT */
181#if SM_CONF_LDAP_INITIALIZE
182	"SM_CONF_LDAP_INITIALIZE",
183#endif /* SM_CONF_LDAP_INITIALIZE */
184#if SM_CONF_LDAP_MEMFREE
185	"SM_CONF_LDAP_MEMFREE",
186#endif /* SM_CONF_LDAP_MEMFREE */
187#if SM_CONF_LONGLONG
188	"SM_CONF_LONGLONG",
189#endif /* SM_CONF_LONGLONG */
190#if SM_CONF_MEMCHR
191	"SM_CONF_MEMCHR",
192#endif /* SM_CONF_MEMCHR */
193#if SM_CONF_MSG
194	"SM_CONF_MSG",
195#endif /* SM_CONF_MSG */
196#if SM_CONF_QUAD_T
197	"SM_CONF_QUAD_T",
198#endif /* SM_CONF_QUAD_T */
199#if SM_CONF_SEM
200	"SM_CONF_SEM",
201#endif /* SM_CONF_SEM */
202#if SM_CONF_SETITIMER
203	"SM_CONF_SETITIMER",
204#endif /* SM_CONF_SETITIMER */
205#if SM_CONF_SIGSETJMP
206	"SM_CONF_SIGSETJMP",
207#endif /* SM_CONF_SIGSETJMP */
208#if SM_CONF_SHM
209	"SM_CONF_SHM",
210#endif /* SM_CONF_SHM */
211#if SM_CONF_SHM_DELAY
212	"SM_CONF_SHM_DELAY",
213#endif /* SM_CONF_SHM_DELAY */
214#if SM_CONF_SSIZE_T
215	"SM_CONF_SSIZE_T",
216#endif /* SM_CONF_SSIZE_T */
217#if SM_CONF_STDBOOL_H
218	"SM_CONF_STDBOOL_H",
219#endif /* SM_CONF_STDBOOL_H */
220#if SM_CONF_STDDEF_H
221	"SM_CONF_STDDEF_H",
222#endif /* SM_CONF_STDDEF_H */
223
224#if 0
225/* XXX this is always enabled (for now) */
226#if SM_CONF_STRL
227	"SM_CONF_STRL",
228#endif /* SM_CONF_STRL */
229#endif /* 0 */
230
231#if SM_CONF_SYS_CDEFS_H
232	"SM_CONF_SYS_CDEFS_H",
233#endif /* SM_CONF_SYS_CDEFS_H */
234#if SM_CONF_SYSEXITS_H
235	"SM_CONF_SYSEXITS_H",
236#endif /* SM_CONF_SYSEXITS_H */
237#if SM_CONF_UID_GID
238	"SM_CONF_UID_GID",
239#endif /* SM_CONF_UID_GID */
240#if DO_NOT_USE_STRCPY
241	"DO_NOT_USE_STRCPY",
242#endif /* DO_NOT_USE_STRCPY */
243#if SM_HEAP_CHECK
244	"SM_HEAP_CHECK",
245#endif /* SM_HEAP_CHECK */
246#if defined(SM_OS_NAME) && defined(__STDC__)
247	"SM_OS=sm_os_" SM_OS_NAME,
248#endif /* defined(SM_OS_NAME) && defined(__STDC__) */
249#if SM_VA_STD
250	"SM_VA_STD",
251#endif /* SM_VA_STD */
252#if USEKSTAT
253	"USEKSTAT",
254#endif /* USEKSTAT */
255#if USEPROCMEMINFO
256	"USEPROCMEMINFO",
257#endif /* USEPROCMEMINFO */
258#if USESWAPCTL
259	"USESWAPCTL",
260#endif /* USESWAPCTL */
261	NULL
262};
263