OW_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 "OW_config.h"
00036 #include "OW_EnvVars.hpp"
00037 
00038 #include <algorithm>
00039 #include <cstring>
00040 
00041 #if defined(OW_DARWIN)
00042 // On MacOSX, environ is not defined in shared libraries.  It is only provided
00043 // for executables.  Since the linker must resolve all symbols at link time,
00044 // the normal extern declaration of environ won't work.  As a substitute, we
00045 // need to use this:
00046 #include <crt_externs.h>
00047 #define environ (*_NSGetEnviron())
00048 
00049 // For more details on the subject, follow one of these links:
00050 // http://lists.gnu.org/archive/html/bug-guile/2004-01/msg00013.html
00051 // http://lists.apple.com/archives/darwin-dev/2005/Mar/msg00132.html
00052 // http://www.metapkg.org/wiki/15 (under the linking problems)
00053 
00054 #else /* !DARWIN */
00055 // according to man environ:
00056 // This variable must be declared in the user program, but is
00057 // declared in the header file unistd.h in case the header files came from
00058 // libc4 or libc5, and in case they came from glibc and _GNU_SOURCE was
00059 // defined.
00060 extern char** environ;
00061 #endif
00062 
00063 namespace OW_NAMESPACE
00064 {
00065 
00066 namespace
00067 {
00068 
00069 void getKeyValue(
00070    const char *const strArg, 
00071    String& key, 
00072    String& value)
00073 {
00074    key.erase();
00075    value.erase();
00076 
00077    const char* p = ::strchr(strArg, '=');
00078    if(p && *(p+1))
00079    {
00080       key = String(strArg, size_t(p-strArg));
00081       value = p+1;
00082    }
00083 }
00084 
00085 }  // End of anonymous namespace
00086 
00088 EnvVars::EnvVars(EEnvVarFlag flag)
00089    : m_envMap()
00090    , m_envp(0)
00091 {
00092    if(flag == E_CURRENT_ENVIRONMENT)
00093    {
00094       fillEnvMap(environ, m_envMap);
00095    }
00096 }
00097 
00099 EnvVars::EnvVars(const char* const envp[])
00100    : m_envMap()
00101    , m_envp(0)
00102 {
00103    fillEnvMap(envp, m_envMap);
00104 }
00105 
00107 EnvVars::~EnvVars()
00108 {
00109    deleteEnvp();
00110 }
00111 
00113 // STATIC
00114 void 
00115 EnvVars::fillEnvMap(const char* const envp[], EnvMap& envMap)
00116 {
00117    envMap.clear();
00118    String key, value;
00119    for(size_t i = 0; envp[i]; i++)
00120    {
00121       getKeyValue(envp[i], key, value);
00122       if(key.length())
00123       {
00124          envMap[key] = value;
00125       }
00126    }
00127 }
00128 
00130 void 
00131 EnvVars::deleteEnvp() const
00132 {
00133    if(m_envp)
00134    {
00135       int i;
00136    
00137       // Delete all char pointers env var array
00138       for(i = 0; m_envp[i]; i++)
00139       {
00140          // m_envp[i] may be null if deleteEnvp was called because an
00141          // exception was caught while trying to allocate the array
00142          // in getenvp()
00143          delete [] m_envp[i];
00144       }
00145 
00146       delete [] m_envp;    // Delete pointer array
00147       m_envp = 0;
00148    }
00149 }
00150 
00152 String 
00153 EnvVars::getValue(const String& key, 
00154    const String& notFoundRetVal) const
00155 {
00156    EnvMap::const_iterator it = m_envMap.find(key);
00157    return (it != m_envMap.end()) ? it->second : notFoundRetVal;
00158 }
00159 
00161 const char* const* 
00162 EnvVars::getenvp() const
00163 {
00164    if(!m_envp && m_envMap.size())
00165    {
00166       int i;
00167       m_envp = new char* [m_envMap.size()+1];
00168       std::fill(m_envp, m_envp+m_envMap.size()+1, (char*)0);
00169       try
00170       {
00171          EnvMap::const_iterator it = m_envMap.begin();
00172          for(i = 0, it = m_envMap.begin(); it != m_envMap.end(); i++, it++)
00173          {
00174             m_envp[i] = new char[it->first.length() + 
00175                it->second.length() + 1];
00176             ::strcpy(m_envp[i], it->first.c_str());
00177             m_envp[i][it->first.length()] = '=';
00178             ::strcpy(m_envp[i]+it->first.length()+1, it->second.c_str());
00179          }
00180       }
00181       catch(...)
00182       {
00183          deleteEnvp();  // Delete what has been allocated thus far.
00184          throw;         // Re-throw this exception
00185       }
00186    }
00187 
00188    return m_envp;
00189 }
00190 
00192 bool 
00193 EnvVars::removeVar(const String& varName)
00194 {
00195    bool cc = false;
00196    EnvMap::iterator it = m_envMap.find(varName);
00197    if (it != m_envMap.end())
00198    {
00199       cc = true;
00200       deleteEnvp();
00201       m_envMap.erase(it);
00202    }
00203 
00204    return cc;
00205 }
00206 
00208 bool 
00209 EnvVars::addVar(const String& name, const String& value)
00210 {
00211    bool cc = false;
00212    if(m_envMap.find(name) == m_envMap.end())
00213    {
00214       cc = true;
00215       deleteEnvp();
00216       m_envMap[name] = value;
00217    }
00218    return cc;
00219 }
00220 
00222 void 
00223 EnvVars::setVar(const String& key, const String& value)
00224 {
00225    deleteEnvp();
00226    m_envMap[key] = value;
00227 }
00228 
00230 void 
00231 EnvVars::setVar(const String& keyValue)
00232 {
00233    String key, value;
00234    getKeyValue(keyValue.c_str(), key, value);
00235    if(key.length())
00236    {
00237       setVar(key, value);
00238    }
00239 }
00240 
00242 bool 
00243 EnvVars::updateVar(const String& name, const String& value)
00244 {
00245    bool cc = false;
00246    EnvMap::iterator it = m_envMap.find(name);
00247    if (it != m_envMap.end())
00248    {
00249       cc = true;
00250       deleteEnvp();
00251       it->second = value;
00252    }
00253 
00254    return cc;
00255 }
00256 
00257 }  // End of OW_NAMESPACE

Generated on Thu Feb 9 08:47:59 2006 for openwbem by  doxygen 1.4.6