pathhost-posix.cpp revision c9579522f347fc3fda6b3f4add0b355981cd7758
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync/* $Id$ */
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync/** @file
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * IPRT - Path Convertions, POSIX.
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync */
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync/*
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * Copyright (C) 2006-2010 Oracle Corporation
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync *
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * available from http://www.virtualbox.org. This file is free software;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * you can redistribute it and/or modify it under the terms of the GNU
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * General Public License (GPL) as published by the Free Software
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync *
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * The contents of this file may alternatively be used under the terms
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * of the Common Development and Distribution License Version 1.0
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * VirtualBox OSE distribution, in which case the provisions of the
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * CDDL are applicable instead of those of the GPL.
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync *
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * You may elect to license modified versions of this file under the
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * terms and conditions of either the GPL or the CDDL or both.
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync */
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync/*******************************************************************************
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync* Header Files *
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync*******************************************************************************/
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync#define LOG_GROUP RTLOGGROUP_PATH
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync#include "internal/iprt.h"
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync#include "internal/path.h"
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync#include "internal/thread.h"
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync#include <iprt/env.h>
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync#include <iprt/string.h>
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync#include <iprt/once.h>
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync/*******************************************************************************
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync* Global Variables *
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync*******************************************************************************/
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync/** Initialize once object. */
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsyncstatic RTONCE g_OnceInitPathConv = RTONCE_INITIALIZER;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync/** If set, then we can pass UTF-8 thru directly. */
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsyncstatic bool g_fPassthruUtf8 = false;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync/** The UTF-8 to FS iconv cache entry. */
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsyncstatic RTSTRICONV g_enmUtf8ToFsIdx = RTSTRICONV_UTF8_TO_LOCALE;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync/** The FS to UTF-8 iconv cache entry. */
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsyncstatic RTSTRICONV g_enmFsToUtf8Idx = RTSTRICONV_LOCALE_TO_UTF8;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync/** The codeset we're using. */
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsyncstatic char g_szFsCodeset[32];
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync/**
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * Do a case insensitive compare where the 2nd string is known and can be case
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * folded when writing the code.
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync *
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * @returns see strcmp.
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * @param pszStr1 The string to compare against pszLower and
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * pszUpper.
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * @param pszUpper The upper case edition of the 2nd string.
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * @param pszLower The lower case edition of the 2nd string.
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync */
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsyncstatic int rtPathStrICmp(const char *pszStr1, const char *pszUpper, const char *pszLower)
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync{
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync Assert(strlen(pszLower) == strlen(pszUpper));
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync for (;;)
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync {
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync char ch1 = *pszStr1++;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync char ch2Upper = *pszUpper++;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync char ch2Lower = *pszLower++;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync if ( ch1 != ch2Upper
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync && ch1 != ch2Lower)
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync return ch1 < ch2Upper ? -1 : 1;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync if (!ch1)
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync return 0;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync }
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync}
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync/**
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync * Is the specified codeset something we can treat as UTF-8.
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync *
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync * @returns true if we can do UTF-8 passthru, false if not.
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * @param pszCodeset The codeset in question.
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync */
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsyncstatic bool rtPathConvInitIsUtf8(const char *pszCodeset)
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync{
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync /* Paranoia. */
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync if (!pszCodeset)
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync return false;
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync /*
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync * Avoid RTStrICmp at this point.
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync */
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync static struct
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync {
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync const char *pszUpper;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync const char *pszLower;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync } const s_aUtf8Compatible[] =
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync {
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync /* The default locale. */
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync { "C" , "c" },
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync { "POSIX" , "posix" },
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync /* 7-bit ASCII. */
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync { "ANSI_X3.4-1968" , "ansi_x3.4-1968" },
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync { "ANSI_X3.4-1986" , "ansi_x3.4-1986" },
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync { "US-ASCII" , "us-ascii" },
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync { "ISO646-US" , "iso646-us" },
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync { "ISO_646.IRV:1991" , "iso_646.irv:1991" },
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync { "ISO-IR-6" , "iso-ir-6" },
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync { "IBM367" , "ibm367" },
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync /* UTF-8 */
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync { "UTF-8" , "utf-8" },
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync { "UTF8" , "utf8" },
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync { "ISO-10646/UTF-8" , "iso-10646/utf-8" },
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync { "ISO-10646/UTF8" , "iso-10646/utf8" }
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync };
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync for (size_t i = 0; i < RT_ELEMENTS(s_aUtf8Compatible); i++)
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync if (!rtPathStrICmp(pszCodeset, s_aUtf8Compatible[i].pszUpper, s_aUtf8Compatible[i].pszLower))
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync return true;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync return false;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync}
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync/**
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * Init once for the path conversion code.
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync *
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * @returns IPRT status code.
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * @param pvUser1 Unused.
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * @param pvUser2 Unused.
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync */
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsyncstatic DECLCALLBACK(int32_t) rtPathConvInitOnce(void *pvUser1, void *pvUser2)
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync{
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync /*
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * Read the environment variable, no mercy on misconfigs here except that
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync * empty values are quietly ignored. (We use a temp buffer for stripping.)
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync */
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync char *pszEnvValue = NULL;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync char szEnvValue[sizeof(g_szFsCodeset)];
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync int rc = RTEnvGetEx(RTENV_DEFAULT, RTPATH_CODESET_ENV_VAR, szEnvValue, sizeof(szEnvValue), NULL);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync if (rc != VERR_ENV_VAR_NOT_FOUND && RT_FAILURE(rc))
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync return rc;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync if (RT_SUCCESS(rc))
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync pszEnvValue = RTStrStrip(szEnvValue);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync if (pszEnvValue && *pszEnvValue)
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync {
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync g_fPassthruUtf8 = rtPathConvInitIsUtf8(pszEnvValue);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync g_enmFsToUtf8Idx = RTSTRICONV_FS_TO_UTF8;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync g_enmUtf8ToFsIdx = RTSTRICONV_UTF8_TO_FS;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync strcpy(g_szFsCodeset, pszEnvValue);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync }
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync else
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync {
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync const char *pszCodeset = rtStrGetLocaleCodeset();
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync size_t cchCodeset = pszCodeset ? strlen(pszCodeset) : sizeof(g_szFsCodeset);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync if (cchCodeset >= sizeof(g_szFsCodeset))
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync /* This shouldn't happen, but we'll manage. */
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync g_szFsCodeset[0] = '\0';
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync else
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync {
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync memcpy(g_szFsCodeset, pszCodeset, cchCodeset + 1);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync pszCodeset = g_szFsCodeset;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync }
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync g_fPassthruUtf8 = rtPathConvInitIsUtf8(pszCodeset);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync g_enmFsToUtf8Idx = RTSTRICONV_LOCALE_TO_UTF8;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync g_enmUtf8ToFsIdx = RTSTRICONV_UTF8_TO_LOCALE;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync }
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync NOREF(pvUser1); NOREF(pvUser2);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync return VINF_SUCCESS;
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync}
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsyncint rtPathToNative(char const **ppszNativePath, const char *pszPath, const char *pszBasePath)
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync{
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync *ppszNativePath = NULL;
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync int rc = RTOnce(&g_OnceInitPathConv, rtPathConvInitOnce, NULL, NULL);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync if (RT_SUCCESS(rc))
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync {
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync if (g_fPassthruUtf8 || !*pszPath)
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync *ppszNativePath = pszPath;
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync else
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync rc = rtStrConvert(pszPath, strlen(pszPath), "UTF-8",
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync (char **)ppszNativePath, 0, g_szFsCodeset,
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync 2, g_enmUtf8ToFsIdx);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync }
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync NOREF(pszBasePath); /* We don't query the FS for codeset preferences. */
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync return rc;
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync}
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsyncvoid rtPathFreeNative(char const *pszNativePath, const char *pszPath)
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync{
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync if ( pszNativePath != pszPath
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync && pszNativePath)
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync RTStrFree((char *)pszNativePath);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync}
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsyncint rtPathFromNative(const char **ppszPath, const char *pszNativePath, const char *pszBasePath)
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync{
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync *ppszPath = NULL;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync int rc = RTOnce(&g_OnceInitPathConv, rtPathConvInitOnce, NULL, NULL);
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync if (RT_SUCCESS(rc))
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync {
87f68d052aecda193e89e8f41ec147606c7f4e0bvboxsync if (g_fPassthruUtf8 || !*pszNativePath)
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync {
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync size_t cCpsIgnored;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync size_t cchNativePath;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync rc = rtUtf8Length(pszNativePath, RTSTR_MAX, &cCpsIgnored, &cchNativePath);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync if (RT_SUCCESS(rc))
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync {
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync char *pszPath;
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync *ppszPath = pszPath = RTStrAlloc(cchNativePath + 1);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync if (pszPath)
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync memcpy(pszPath, pszNativePath, cchNativePath + 1);
5c2e23084fe3d3163d8f441b99cfd9d2f76b6b2avboxsync else
rc = VERR_NO_STR_MEMORY;
}
}
else
rc = rtStrConvert(pszNativePath, strlen(pszNativePath), g_szFsCodeset,
(char **)ppszPath, 0, "UTF-8",
2, g_enmFsToUtf8Idx);
}
NOREF(pszBasePath); /* We don't query the FS for codeset preferences. */
return rc;
}
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, 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, 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;
}