RTDECL(int) RTEnvClone(PRTENV pEnv, RTENV EnvToClone)
{
    /*
     * Validate input and figure out how many variable to clone and where to get them.
     */
    bool fCaseSensitive = true;
    bool fPutEnvBlock   = false;
    size_t cVars;
    const char * const *papszEnv;
#ifdef RTENV_HAVE_WENVIRON
    PCRTUTF16 const * papwszEnv;
#endif
    PRTENVINTERNAL pIntEnvToClone;
    AssertPtrReturn(pEnv, VERR_INVALID_POINTER);
    if (EnvToClone == RTENV_DEFAULT)
    {
        cVars = 0;
        pIntEnvToClone = NULL;
#ifdef RTENV_HAVE_WENVIRON
        papszEnv  = NULL;
        papwszEnv = (PCRTUTF16 * const)_wenviron;
        if (!papwszEnv)
        {
            _wgetenv(L"Path"); /* Force the CRT to initalize it. */
            papwszEnv = (PCRTUTF16 * const)_wenviron;
        }
        if (papwszEnv)
            while (papwszEnv[cVars])
                cVars++;
#else
        papszEnv = rtEnvDefault();
        if (papszEnv)
            while (papszEnv[cVars])
                cVars++;
#endif

#if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS)
        /* DOS systems was case insensitive.  A prime example is the 'Path'
           variable on windows which turns into the 'PATH' variable. */
        fCaseSensitive = false;
#endif
    }
    else
    {
        pIntEnvToClone = EnvToClone;
        AssertPtrReturn(pIntEnvToClone, VERR_INVALID_HANDLE);
        AssertReturn(pIntEnvToClone->u32Magic == RTENV_MAGIC, VERR_INVALID_HANDLE);
        RTENV_LOCK(pIntEnvToClone);

        fPutEnvBlock = pIntEnvToClone->fPutEnvBlock;
        papszEnv = pIntEnvToClone->papszEnv;
        cVars = pIntEnvToClone->cVars;
    }

    /*
     * Create the duplicate.
     */
    PRTENVINTERNAL pIntEnv;
    int rc = rtEnvCreate(&pIntEnv, cVars + 1 /* NULL */, fCaseSensitive, fPutEnvBlock);
    if (RT_SUCCESS(rc))
    {
        pIntEnv->cVars = cVars;
        pIntEnv->papszEnv[pIntEnv->cVars] = NULL;
        if (EnvToClone == RTENV_DEFAULT)
        {
            /* ASSUMES the default environment is in the current codepage. */
            size_t  iDst = 0;
            for (size_t iSrc = 0; iSrc < cVars; iSrc++)
            {
#ifdef RTENV_HAVE_WENVIRON
                int rc2 = RTUtf16ToUtf8(papwszEnv[iSrc], &pIntEnv->papszEnv[iDst]);
#else
                int rc2 = RTStrCurrentCPToUtf8(&pIntEnv->papszEnv[iDst], papszEnv[iSrc]);
#endif
                if (RT_SUCCESS(rc2))
                {
                    /* Make sure it contains an '='. */
                    iDst++;
                    if (strchr(pIntEnv->papszEnv[iDst - 1], '='))
                        continue;
                    rc2 = RTStrAAppend(&pIntEnv->papszEnv[iDst - 1], "=");
                    if (RT_SUCCESS(rc2))
                        continue;
                }
                else if (rc2 == VERR_NO_TRANSLATION)
                {
                    rc = VWRN_ENV_NOT_FULLY_TRANSLATED;
                    continue;
                }

                /* failed fatally. */
                pIntEnv->cVars = iDst;
                RTEnvDestroy(pIntEnv);
                return rc2;
            }
            pIntEnv->cVars = iDst;
        }
        else
        {
            for (size_t iVar = 0; iVar < cVars; iVar++)
            {
                char *pszVar = RTStrDup(papszEnv[iVar]);
                if (RT_UNLIKELY(!pszVar))
                {
                    RTENV_UNLOCK(pIntEnvToClone);

                    pIntEnv->cVars = iVar;
                    RTEnvDestroy(pIntEnv);
                    return VERR_NO_STR_MEMORY;
                }
                pIntEnv->papszEnv[iVar] = pszVar;
            }
        }

        /* done */
        *pEnv = pIntEnv;
    }

    if (pIntEnvToClone)
        RTENV_UNLOCK(pIntEnvToClone);
    return rc;
}
RTDECL(int) RTEnvCreate(PRTENV pEnv)
{
    AssertPtrReturn(pEnv, VERR_INVALID_POINTER);
    return rtEnvCreate(pEnv, RTENV_GROW_SIZE, true /*fCaseSensitive*/, false /*fPutEnvBlock*/);
}
示例#3
0
RTDECL(int) RTEnvClone(PRTENV pEnv, RTENV EnvToClone)
{
    /*
     * Validate input and figure out how many variable to clone and where to get them.
     */
    size_t cVars;
    const char * const *papszEnv;
    PRTENVINTERNAL pIntEnvToClone;
    AssertPtrReturn(pEnv, VERR_INVALID_POINTER);
    if (EnvToClone == RTENV_DEFAULT)
    {
        pIntEnvToClone = NULL;
        papszEnv = rtEnvDefault();
        cVars = 0;
        if (papszEnv)
            while (papszEnv[cVars])
                cVars++;
    }
    else
    {
        pIntEnvToClone = EnvToClone;
        AssertPtrReturn(pIntEnvToClone, VERR_INVALID_HANDLE);
        AssertReturn(pIntEnvToClone->u32Magic == RTENV_MAGIC, VERR_INVALID_HANDLE);
        RTENV_LOCK(pIntEnvToClone);

        papszEnv = pIntEnvToClone->papszEnv;
        cVars = pIntEnvToClone->cVars;
    }

    /*
     * Create the duplicate.
     */
    PRTENVINTERNAL pIntEnv;
    int rc = rtEnvCreate(&pIntEnv, cVars + 1 /* NULL */);
    if (RT_SUCCESS(rc))
    {
        pIntEnv->cVars = cVars;
        pIntEnv->papszEnv[pIntEnv->cVars] = NULL;
        if (EnvToClone == RTENV_DEFAULT)
        {
            /* ASSUMES the default environment is in the current codepage. */
            size_t  iDst = 0;
            for (size_t iSrc = 0; iSrc < cVars; iSrc++)
            {
                int rc2 = RTStrCurrentCPToUtf8(&pIntEnv->papszEnv[iDst], papszEnv[iSrc]);
                if (RT_SUCCESS(rc2))
                    iDst++;
                else if (rc2 == VERR_NO_TRANSLATION)
                    rc = VWRN_ENV_NOT_FULLY_TRANSLATED;
                else
                {
                    pIntEnv->cVars = iDst;
                    RTEnvDestroy(pIntEnv);
                    return rc2;
                }
            }
            pIntEnv->cVars = iDst;
        }
        else
        {
            for (size_t iVar = 0; iVar < cVars; iVar++)
            {
                char *pszVar = RTStrDup(papszEnv[iVar]);
                if (RT_UNLIKELY(!pszVar))
                {
                    RTENV_UNLOCK(pIntEnvToClone);

                    pIntEnv->cVars = iVar;
                    RTEnvDestroy(pIntEnv);
                    return VERR_NO_STR_MEMORY;
                }
                pIntEnv->papszEnv[iVar] = pszVar;
            }
        }

        /* done */
        *pEnv = pIntEnv;
    }

    if (pIntEnvToClone)
        RTENV_UNLOCK(pIntEnvToClone);
    return rc;
}
示例#4
0
RTDECL(int) RTEnvCloneUtf16Block(PRTENV phEnv, PCRTUTF16 pwszzBlock, uint32_t fFlags)
{
    AssertPtrReturn(pwszzBlock, VERR_INVALID_POINTER);
    AssertReturn(!fFlags, VERR_INVALID_FLAGS);

    /*
     * Count the number of variables in the block.
     */
    uint32_t  cVars = 0;
    PCRTUTF16 pwsz  = pwszzBlock;
    while (*pwsz != '\0')
    {
        cVars++;
        pwsz += RTUtf16Len(pwsz) + 1;
        AssertReturn(cVars < _256K, VERR_OUT_OF_RANGE);
    }

    /*
     * Create the duplicate.
     */
    PRTENVINTERNAL pIntEnv;
    int rc = rtEnvCreate(&pIntEnv, cVars + 1 /* NULL */, false /*fCaseSensitive*/, false /*fPutEnvBlock*/);
    if (RT_SUCCESS(rc))
    {
        pIntEnv->cVars = cVars;
        pIntEnv->papszEnv[pIntEnv->cVars] = NULL;

        size_t iDst = 0;
        for (pwsz = pwszzBlock; *pwsz != '\0'; pwsz += RTUtf16Len(pwsz) + 1)
        {
            int rc2 = RTUtf16ToUtf8(pwsz, &pIntEnv->papszEnv[iDst]);
            if (RT_SUCCESS(rc2))
            {
                /* Make sure it contains an '='. */
                const char *pszEqual = strchr(pIntEnv->papszEnv[iDst], '=');
                if (!pszEqual)
                {
                    rc2 = RTStrAAppend(&pIntEnv->papszEnv[iDst], "=");
                    if (RT_SUCCESS(rc2))
                        pszEqual = strchr(pIntEnv->papszEnv[iDst], '=');

                }
                if (pszEqual)
                {
                    /* Check for duplicates, keep the last version. */
                    const char *pchVar        = pIntEnv->papszEnv[iDst];
                    size_t      cchVarNmAndEq = pszEqual - pchVar;
                    for (size_t iDst2 = 0; iDst2 < iDst; iDst2++)
                        if (pIntEnv->pfnCompare(pIntEnv->papszEnv[iDst2], pchVar, cchVarNmAndEq) == 0)
                        {
                            RTStrFree(pIntEnv->papszEnv[iDst2]);
                            pIntEnv->papszEnv[iDst2] = pIntEnv->papszEnv[iDst];
                            pIntEnv->papszEnv[iDst]  = NULL;
                            iDst--;
                            break;
                        }
                    iDst++;
                    continue;
                }
                iDst++;
            }

            /* failed fatally. */
            pIntEnv->cVars = iDst;
            RTEnvDestroy(pIntEnv);
            return rc2;
        }
        Assert(iDst <= pIntEnv->cVars);
        pIntEnv->cVars = iDst;

        /* done */
        *phEnv = pIntEnv;
    }
    return rc;
}
示例#5
0
RTDECL(int) RTEnvCreate(PRTENV pEnv)
{
    AssertPtrReturn(pEnv, VERR_INVALID_POINTER);
    return rtEnvCreate(pEnv, RTENV_GROW_SIZE);
}