blocxx
|
00001 /******************************************************************************* 00002 * Copyright (C) 2005 Novell, Inc. All rights reserved. 00003 * 00004 * Redistribution and use in source and binary forms, with or without 00005 * modification, are permitted provided that the following conditions are met: 00006 * 00007 * - Redistributions of source code must retain the above copyright notice, 00008 * this list of conditions and the following disclaimer. 00009 * 00010 * - Redistributions in binary form must reproduce the above copyright notice, 00011 * this list of conditions and the following disclaimer in the documentation 00012 * and/or other materials provided with the distribution. 00013 * 00014 * - Neither the name of Novell, Inc., nor the names of its 00015 * contributors may be used to endorse or promote products derived from this 00016 * software without specific prior written permission. 00017 * 00018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' 00019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00021 * ARE DISCLAIMED. IN NO EVENT SHALL Novell, Inc., OR THE 00022 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00023 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00024 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 00025 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 00026 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 00027 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 00028 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00029 *******************************************************************************/ 00030 00035 #include "blocxx/BLOCXX_config.h" 00036 #include "blocxx/EnvVars.hpp" 00037 #include "blocxx/Environ.hpp" 00038 00039 #include <algorithm> 00040 #include <cstring> 00041 00042 namespace BLOCXX_NAMESPACE 00043 { 00044 00045 namespace 00046 { 00047 00048 void getKeyValue( 00049 const char *const strArg, 00050 String& key, 00051 String& value) 00052 { 00053 key.erase(); 00054 value.erase(); 00055 00056 const char* p = ::strchr(strArg, '='); 00057 if(p) 00058 { 00059 key = String(strArg, size_t(p-strArg)); 00060 value = p+1; 00061 } 00062 } 00063 00064 inline bool isValidKey(const String &key) 00065 { 00066 // 00067 // SUSv3 specifies that the setenv() function shall fail, 00068 // if the environment variable name is NULL, empty or 00069 // contains a '=' character: 00070 // 00071 return key.length() && key.indexOf('=') == String::npos; 00072 } 00073 00074 } // End of anonymous namespace 00075 00077 EnvVars::EnvVars(EEnvVarFlag flag) 00078 : m_envMap() 00079 , m_envp(0) 00080 { 00081 if(flag == E_CURRENT_ENVIRONMENT) 00082 { 00083 fillEnvMap(environ, m_envMap); 00084 } 00085 } 00086 00088 EnvVars::EnvVars(const char* const envp[]) 00089 : m_envMap() 00090 , m_envp(0) 00091 { 00092 fillEnvMap(envp, m_envMap); 00093 } 00094 00096 EnvVars::~EnvVars() 00097 { 00098 deleteEnvp(); 00099 } 00100 00102 // STATIC 00103 void 00104 EnvVars::fillEnvMap(EnvMap& envMap) 00105 { 00106 fillEnvMap(environ, envMap); 00107 } 00108 00110 // STATIC 00111 void 00112 EnvVars::fillEnvMap(const char* const envp[], EnvMap& envMap) 00113 { 00114 envMap.clear(); 00115 String key, value; 00116 for(size_t i = 0; envp[i]; i++) 00117 { 00118 getKeyValue(envp[i], key, value); 00119 if(isValidKey(key)) 00120 { 00121 envMap[key] = value; 00122 } 00123 } 00124 } 00125 00127 void 00128 EnvVars::deleteEnvp() const 00129 { 00130 if(m_envp) 00131 { 00132 int i; 00133 00134 // Delete all char pointers env var array 00135 for(i = 0; m_envp[i]; i++) 00136 { 00137 // m_envp[i] may be null if deleteEnvp was called because an 00138 // exception was caught while trying to allocate the array 00139 // in getenvp() 00140 delete [] m_envp[i]; 00141 } 00142 00143 delete [] m_envp; // Delete pointer array 00144 m_envp = 0; 00145 } 00146 } 00147 00149 String 00150 EnvVars::getValue(const String& key, 00151 const String& notFoundRetVal) const 00152 { 00153 EnvMap::const_iterator it = m_envMap.find(key); 00154 return (it != m_envMap.end()) ? it->second : notFoundRetVal; 00155 } 00156 00158 const char* const* 00159 EnvVars::getenvp() const 00160 { 00161 if(!m_envp) 00162 { 00163 int i; 00164 m_envp = new char* [m_envMap.size()+1]; 00165 std::fill(m_envp, m_envp+m_envMap.size()+1, (char*)0); 00166 try 00167 { 00168 EnvMap::const_iterator it = m_envMap.begin(); 00169 for(i = 0; it != m_envMap.end(); i++, it++) 00170 { 00171 size_t klen = it->first.length(); 00172 size_t vlen = it->second.length(); 00173 00174 m_envp[i] = new char[klen + vlen + 2]; 00175 ::strcpy(m_envp[i], it->first.c_str()); 00176 m_envp[i][klen] = '='; 00177 ::strcpy(m_envp[i]+klen+1, it->second.c_str()); 00178 } 00179 } 00180 catch(...) 00181 { 00182 deleteEnvp(); // Delete what has been allocated thus far. 00183 throw; // Re-throw this exception 00184 } 00185 } 00186 00187 return m_envp; 00188 } 00189 00191 bool 00192 EnvVars::removeVar(const String& varName) 00193 { 00194 bool cc = false; 00195 EnvMap::iterator it = m_envMap.find(varName); 00196 if (it != m_envMap.end()) 00197 { 00198 cc = true; 00199 deleteEnvp(); 00200 m_envMap.erase(it); 00201 } 00202 00203 return cc; 00204 } 00205 00207 bool 00208 EnvVars::addVar(const String& name, const String& value) 00209 { 00210 bool cc = false; 00211 if(isValidKey(name) && m_envMap.find(name) == m_envMap.end()) 00212 { 00213 cc = true; 00214 deleteEnvp(); 00215 m_envMap[name] = value; 00216 } 00217 return cc; 00218 } 00219 00221 bool 00222 EnvVars::setVar(const String& key, const String& value) 00223 { 00224 bool cc = false; 00225 if( isValidKey(key)) 00226 { 00227 cc = true; 00228 deleteEnvp(); 00229 m_envMap[key] = value; 00230 } 00231 return cc; 00232 } 00233 00235 bool 00236 EnvVars::setVar(const String& keyValue) 00237 { 00238 String key, value; 00239 getKeyValue(keyValue.c_str(), key, value); 00240 return setVar(key, value); 00241 } 00242 00244 bool 00245 EnvVars::updateVar(const String& name, const String& value) 00246 { 00247 bool cc = false; 00248 EnvMap::iterator it = m_envMap.find(name); 00249 if (it != m_envMap.end()) 00250 { 00251 cc = true; 00252 deleteEnvp(); 00253 it->second = value; 00254 } 00255 00256 return cc; 00257 } 00258 00259 } // End of BLOCXX_NAMESPACE