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> 14 SM_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 39 int 40 putenv(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 110 int 111 putenv(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 152 void 153 unsetenv(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 173 char *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