pathhost-posix.cpp revision a438caaf732f7839dc66b4f8dad672527845a003
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync/* $Id$ */
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync/** @file
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync * IPRT - Path Conversions, POSIX.
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync */
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync
c7814cf6e1240a519cbec0441e033d0e2470ed00vboxsync/*
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync * Copyright (C) 2006-2010 Oracle Corporation
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync *
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 *
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 *
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
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync/*******************************************************************************
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync* Header Files *
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync*******************************************************************************/
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync#define LOG_GROUP RTLOGGROUP_PATH
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync#include "internal/iprt.h"
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync#include "internal/path.h"
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync#include "internal/string.h"
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync#include "internal/thread.h"
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync#include <iprt/env.h>
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync#include <iprt/string.h>
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync#include <iprt/once.h>
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync
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. */
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsyncstatic char g_szFsCodeset[32];
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync/**
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync * Do a case insensitive compare where the 2nd string is known and can be case
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync * folded when writing the code.
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync *
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.
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync */
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsyncstatic int rtPathStrICmp(const char *pszStr1, const char *pszUpper, const char *pszLower)
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync{
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync Assert(strlen(pszLower) == strlen(pszUpper));
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync for (;;)
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync {
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync char ch1 = *pszStr1++;
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync char ch2Upper = *pszUpper++;
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync char ch2Lower = *pszLower++;
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync if ( ch1 != ch2Upper
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync && ch1 != ch2Lower)
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync return ch1 < ch2Upper ? -1 : 1;
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync if (!ch1)
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync return 0;
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync }
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync}
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync/**
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync * Is the specified codeset something we can treat as UTF-8.
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync *
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync * @returns true if we can do UTF-8 passthru, false if not.
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync * @param pszCodeset The codeset in question.
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync */
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsyncstatic bool rtPathConvInitIsUtf8(const char *pszCodeset)
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync{
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync /* Paranoia. */
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync if (!pszCodeset)
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync return false;
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync /*
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync * Avoid RTStrICmp at this point.
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync */
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync static struct
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync {
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync const char *pszUpper;
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync const char *pszLower;
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync } const s_aUtf8Compatible[] =
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync {
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync /* The default locale. */
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync { "C" , "c" },
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync { "POSIX" , "posix" },
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync /* 7-bit ASCII. */
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync { "ANSI_X3.4-1968" , "ansi_x3.4-1968" },
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync { "ANSI_X3.4-1986" , "ansi_x3.4-1986" },
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync { "US-ASCII" , "us-ascii" },
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync { "ISO646-US" , "iso646-us" },
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync { "ISO_646.IRV:1991" , "iso_646.irv:1991" },
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync { "ISO-IR-6" , "iso-ir-6" },
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync { "IBM367" , "ibm367" },
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync /* UTF-8 */
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync { "UTF-8" , "utf-8" },
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync { "UTF8" , "utf8" },
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync { "ISO-10646/UTF-8" , "iso-10646/utf-8" },
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync { "ISO-10646/UTF8" , "iso-10646/utf8" }
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync };
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync
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;
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync return false;
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync}
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync/**
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync * Init once for the path conversion code.
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync *
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync * @returns IPRT status code.
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync * @param pvUser1 Unused.
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync * @param pvUser2 Unused.
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync */
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsyncstatic DECLCALLBACK(int32_t) rtPathConvInitOnce(void *pvUser)
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync{
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync /*
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.)
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync */
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync char *pszEnvValue = NULL;
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync char szEnvValue[sizeof(g_szFsCodeset)];
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))
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync return rc;
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync if (RT_SUCCESS(rc))
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync pszEnvValue = RTStrStrip(szEnvValue);
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync if (pszEnvValue && *pszEnvValue)
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync {
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync g_fPassthruUtf8 = rtPathConvInitIsUtf8(pszEnvValue);
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync g_enmFsToUtf8Idx = RTSTRICONV_FS_TO_UTF8;
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync g_enmUtf8ToFsIdx = RTSTRICONV_UTF8_TO_FS;
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync strcpy(g_szFsCodeset, pszEnvValue);
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync }
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync else
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync {
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync const char *pszCodeset = rtStrGetLocaleCodeset();
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync size_t cchCodeset = pszCodeset ? strlen(pszCodeset) : sizeof(g_szFsCodeset);
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync if (cchCodeset >= sizeof(g_szFsCodeset))
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync /* This shouldn't happen, but we'll manage. */
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync g_szFsCodeset[0] = '\0';
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync else
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync {
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync memcpy(g_szFsCodeset, pszCodeset, cchCodeset + 1);
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync pszCodeset = g_szFsCodeset;
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync }
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync g_fPassthruUtf8 = rtPathConvInitIsUtf8(pszCodeset);
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync g_enmFsToUtf8Idx = RTSTRICONV_LOCALE_TO_UTF8;
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync g_enmUtf8ToFsIdx = RTSTRICONV_UTF8_TO_LOCALE;
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync }
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync NOREF(pvUser);
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync return VINF_SUCCESS;
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync}
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsyncint rtPathToNative(char const **ppszNativePath, const char *pszPath, const char *pszBasePath)
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync{
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync *ppszNativePath = NULL;
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync int rc = RTOnce(&g_OnceInitPathConv, rtPathConvInitOnce, NULL);
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync if (RT_SUCCESS(rc))
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync {
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync if (g_fPassthruUtf8 || !*pszPath)
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync *ppszNativePath = pszPath;
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync else
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync rc = rtStrConvert(pszPath, strlen(pszPath), "UTF-8",
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync (char **)ppszNativePath, 0, g_szFsCodeset,
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync 2, g_enmUtf8ToFsIdx);
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync }
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync NOREF(pszBasePath); /* We don't query the FS for codeset preferences. */
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync return rc;
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync}
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsyncvoid rtPathFreeNative(char const *pszNativePath, const char *pszPath)
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync{
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync if ( pszNativePath != pszPath
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync && pszNativePath)
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync RTStrFree((char *)pszNativePath);
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync}
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsyncint rtPathFromNative(const char **ppszPath, const char *pszNativePath, const char *pszBasePath)
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync{
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync *ppszPath = NULL;
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync int rc = RTOnce(&g_OnceInitPathConv, rtPathConvInitOnce, NULL);
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync if (RT_SUCCESS(rc))
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync {
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync if (g_fPassthruUtf8 || !*pszNativePath)
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync {
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync size_t cCpsIgnored;
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync size_t cchNativePath;
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync rc = rtUtf8Length(pszNativePath, RTSTR_MAX, &cCpsIgnored, &cchNativePath);
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync if (RT_SUCCESS(rc))
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync {
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync char *pszPath;
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync *ppszPath = pszPath = RTStrAlloc(cchNativePath + 1);
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync if (pszPath)
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync memcpy(pszPath, pszNativePath, cchNativePath + 1);
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync else
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync rc = VERR_NO_STR_MEMORY;
4f4877d6f6ea6dbe54cba4595450e5c837d5d419vboxsync }
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync }
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync else
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync rc = rtStrConvert(pszNativePath, strlen(pszNativePath), g_szFsCodeset,
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync (char **)ppszPath, 0, "UTF-8",
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync 2, g_enmFsToUtf8Idx);
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync }
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync NOREF(pszBasePath); /* We don't query the FS for codeset preferences. */
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync return rc;
2d1ce39e8bc6e75cadfc0a48ada30c52bc3eae0evboxsync}
void rtPathFreeIprt(const char *pszPath, const char *pszNativePath)
{
if ( pszPath != pszNativePath
&& pszPath)
RTStrFree((char *)pszPath);
}
int rtPathFromNativeCopy(char *pszPath, size_t cbPath, const char *pszNativePath, const char *pszBasePath)
{
int rc = RTOnce(&g_OnceInitPathConv, rtPathConvInitOnce, NULL);
if (RT_SUCCESS(rc))
{
if (g_fPassthruUtf8 || !*pszNativePath)
rc = RTStrCopy(pszPath, cbPath, pszNativePath);
else if (cbPath)
rc = rtStrConvert(pszNativePath, strlen(pszNativePath), g_szFsCodeset,
&pszPath, cbPath, "UTF-8",
2, g_enmFsToUtf8Idx);
else
rc = VERR_BUFFER_OVERFLOW;
}
NOREF(pszBasePath); /* We don't query the FS for codeset preferences. */
return rc;
}
int rtPathFromNativeDup(char **ppszPath, const char *pszNativePath, const char *pszBasePath)
{
int rc = RTOnce(&g_OnceInitPathConv, rtPathConvInitOnce, NULL);
if (RT_SUCCESS(rc))
{
if (g_fPassthruUtf8 || !*pszNativePath)
rc = RTStrDupEx(ppszPath, pszNativePath);
else
rc = rtStrConvert(pszNativePath, strlen(pszNativePath), g_szFsCodeset,
ppszPath, 0, "UTF-8",
2, g_enmFsToUtf8Idx);
}
NOREF(pszBasePath); /* We don't query the FS for codeset preferences. */
return rc;
}