pathhost-posix.cpp revision a438caaf732f7839dc66b4f8dad672527845a003
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync * IPRT - Path Conversions, POSIX.
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync * Copyright (C) 2006-2010 Oracle Corporation
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync * available from http://www.virtualbox.org. This file is free software;
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync * you can redistribute it and/or modify it under the terms of the GNU
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync * General Public License (GPL) as published by the Free Software
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync * The contents of this file may alternatively be used under the terms
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync * of the Common Development and Distribution License Version 1.0
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync * VirtualBox OSE distribution, in which case the provisions of the
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync * CDDL are applicable instead of those of the GPL.
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync * You may elect to license modified versions of this file under the
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync * terms and conditions of either the GPL or the CDDL or both.
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync/*******************************************************************************
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync* Header Files *
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync*******************************************************************************/
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync/*******************************************************************************
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync* Global Variables *
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync*******************************************************************************/
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync/** Initialize once object. */
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsyncstatic RTONCE g_OnceInitPathConv = RTONCE_INITIALIZER;
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync/** If set, then we can pass UTF-8 thru directly. */
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsyncstatic bool g_fPassthruUtf8 = false;
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync/** The UTF-8 to FS iconv cache entry. */
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsyncstatic RTSTRICONV g_enmUtf8ToFsIdx = RTSTRICONV_UTF8_TO_LOCALE;
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync/** The FS to UTF-8 iconv cache entry. */
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsyncstatic RTSTRICONV g_enmFsToUtf8Idx = RTSTRICONV_LOCALE_TO_UTF8;
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync/** The codeset we're using. */
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync * Do a case insensitive compare where the 2nd string is known and can be case
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync * folded when writing the code.
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync * @returns see strcmp.
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync * @param pszStr1 The string to compare against pszLower and
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync * pszUpper.
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync * @param pszUpper The upper case edition of the 2nd string.
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync * @param pszLower The lower case edition of the 2nd string.
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsyncstatic int rtPathStrICmp(const char *pszStr1, const char *pszUpper, const char *pszLower)
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync * Is the specified codeset something we can treat as UTF-8.
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync * @returns true if we can do UTF-8 passthru, false if not.
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync * @param pszCodeset The codeset in question.
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsyncstatic bool rtPathConvInitIsUtf8(const char *pszCodeset)
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync /* Paranoia. */
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync return false;
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync * Avoid RTStrICmp at this point.
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync static struct
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync const char *pszUpper;
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync const char *pszLower;
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync /* The default locale. */
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync /* 7-bit ASCII. */
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync /* UTF-8 */
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync for (size_t i = 0; i < RT_ELEMENTS(s_aUtf8Compatible); i++)
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync if (!rtPathStrICmp(pszCodeset, s_aUtf8Compatible[i].pszUpper, s_aUtf8Compatible[i].pszLower))
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync return true;
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync return false;
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync * Init once for the path conversion code.
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync * @returns IPRT status code.
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync * @param pvUser1 Unused.
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync * @param pvUser2 Unused.
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsyncstatic DECLCALLBACK(int32_t) rtPathConvInitOnce(void *pvUser)
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync * Read the environment variable, no mercy on misconfigs here except that
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync * empty values are quietly ignored. (We use a temp buffer for stripping.)
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync int rc = RTEnvGetEx(RTENV_DEFAULT, RTPATH_CODESET_ENV_VAR, szEnvValue, sizeof(szEnvValue), NULL);
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync if (rc != VERR_ENV_VAR_NOT_FOUND && RT_FAILURE(rc))
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync g_fPassthruUtf8 = rtPathConvInitIsUtf8(pszEnvValue);
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync size_t cchCodeset = pszCodeset ? strlen(pszCodeset) : sizeof(g_szFsCodeset);
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync /* This shouldn't happen, but we'll manage. */
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync g_fPassthruUtf8 = rtPathConvInitIsUtf8(pszCodeset);
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsyncint rtPathToNative(char const **ppszNativePath, const char *pszPath, const char *pszBasePath)
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync int rc = RTOnce(&g_OnceInitPathConv, rtPathConvInitOnce, NULL);
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync rc = rtStrConvert(pszPath, strlen(pszPath), "UTF-8",
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync NOREF(pszBasePath); /* We don't query the FS for codeset preferences. */
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsyncvoid rtPathFreeNative(char const *pszNativePath, const char *pszPath)
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsyncint rtPathFromNative(const char **ppszPath, const char *pszNativePath, const char *pszBasePath)
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync int rc = RTOnce(&g_OnceInitPathConv, rtPathConvInitOnce, NULL);
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync rc = rtUtf8Length(pszNativePath, RTSTR_MAX, &cCpsIgnored, &cchNativePath);
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync *ppszPath = pszPath = RTStrAlloc(cchNativePath + 1);
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync rc = rtStrConvert(pszNativePath, strlen(pszNativePath), g_szFsCodeset,
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync NOREF(pszBasePath); /* We don't query the FS for codeset preferences. */
&& pszPath)
int rtPathFromNativeCopy(char *pszPath, size_t cbPath, const char *pszNativePath, const char *pszBasePath)
else if (cbPath)
return rc;
return rc;