blocxx

EnvVars.cpp

Go to the documentation of this file.
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