uses iconv by default on linux to convert filenames from utf-8 to the current locale
This commit is contained in:
parent
c51f5863dd
commit
b809028bda
|
@ -102,5 +102,13 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define TORRENT_UPNP_LOGGING
|
#define TORRENT_UPNP_LOGGING
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !TORRENT_USE_WPATH && defined TORRENT_LINUX
|
||||||
|
// libiconv presnce, not implemented yet
|
||||||
|
#define TORRENT_USE_LOCALE_FILENAMES 1
|
||||||
|
#else
|
||||||
|
#define TORRENT_USE_LOCALE_FILENAMES 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif // TORRENT_CONFIG_HPP_INCLUDED
|
#endif // TORRENT_CONFIG_HPP_INCLUDED
|
||||||
|
|
||||||
|
|
|
@ -61,6 +61,15 @@ namespace libtorrent
|
||||||
std::string const& url, std::string argument);
|
std::string const& url, std::string argument);
|
||||||
|
|
||||||
TORRENT_EXPORT std::string to_hex(std::string const& s);
|
TORRENT_EXPORT std::string to_hex(std::string const& s);
|
||||||
|
|
||||||
|
#if TORRENT_USE_WPATH
|
||||||
|
TORRENT_EXPORT std::wstring convert_to_wstring(std::string const& s);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if TORRENT_USE_LOCALE_FILENAMES
|
||||||
|
TORRENT_EXPORT std::string convert_to_native(std::string const& s);
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // TORRENT_ESCAPE_STRING_HPP_INCLUDED
|
#endif // TORRENT_ESCAPE_STRING_HPP_INCLUDED
|
||||||
|
|
|
@ -81,12 +81,6 @@ namespace libtorrent
|
||||||
storage_mode_compact
|
storage_mode_compact
|
||||||
};
|
};
|
||||||
|
|
||||||
#if TORRENT_USE_WPATH
|
|
||||||
|
|
||||||
TORRENT_EXPORT std::wstring safe_convert(std::string const& s);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
TORRENT_EXPORT std::vector<std::pair<size_type, std::time_t> > get_filesizes(
|
TORRENT_EXPORT std::vector<std::pair<size_type, std::time_t> > get_filesizes(
|
||||||
file_storage const& t
|
file_storage const& t
|
||||||
, fs::path p);
|
, fs::path p);
|
||||||
|
|
|
@ -48,6 +48,22 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "libtorrent/assert.hpp"
|
#include "libtorrent/assert.hpp"
|
||||||
#include "libtorrent/escape_string.hpp"
|
#include "libtorrent/escape_string.hpp"
|
||||||
|
|
||||||
|
#if TORRENT_USE_WPATH
|
||||||
|
|
||||||
|
#ifdef BOOST_WINDOWS
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <boost/filesystem/exception.hpp>
|
||||||
|
#include "libtorrent/utf8.hpp"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if TORRENT_USE_LOCALE_FILENAMES
|
||||||
|
#include <iconv.h>
|
||||||
|
#include <locale.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -393,5 +409,50 @@ namespace libtorrent
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if TORRENT_USE_WPATH
|
||||||
|
std::wstring convert_to_wstring(std::string const& s)
|
||||||
|
{
|
||||||
|
std::wstring ret;
|
||||||
|
int result = libtorrent::utf8_wchar(s, ret);
|
||||||
|
#ifndef BOOST_WINDOWS
|
||||||
|
return ret;
|
||||||
|
#else
|
||||||
|
if (result == 0) return ret;
|
||||||
|
|
||||||
|
ret.clear();
|
||||||
|
const char* end = &s[0] + s.size();
|
||||||
|
for (const char* i = &s[0]; i < end;)
|
||||||
|
{
|
||||||
|
wchar_t c = '.';
|
||||||
|
int result = std::mbtowc(&c, i, end - i);
|
||||||
|
if (result > 0) i += result;
|
||||||
|
else ++i;
|
||||||
|
ret += c;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if TORRENT_USE_LOCALE_FILENAMES
|
||||||
|
std::string convert_to_native(std::string const& s)
|
||||||
|
{
|
||||||
|
// the empty string represents the local dependent encoding
|
||||||
|
static iconv_t iconv_handle = iconv_open("", "UTF-8");
|
||||||
|
if (iconv_handle == iconv_t(-1)) return s;
|
||||||
|
std::string ret;
|
||||||
|
size_t insize = s.size();
|
||||||
|
size_t outsize = insize * 4;
|
||||||
|
ret.resize(outsize);
|
||||||
|
char const* in = &s[0];
|
||||||
|
char* out = &ret[0];
|
||||||
|
size_t retval = iconv(iconv_handle, (char**)&in, &insize,
|
||||||
|
&out, &outsize);
|
||||||
|
if (retval == (size_t)-1) return s;
|
||||||
|
ret.resize(outsize);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
14
src/file.cpp
14
src/file.cpp
|
@ -65,9 +65,9 @@ BOOST_STATIC_ASSERT(sizeof(lseek(0, 0, 0)) >= 8);
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#if TORRENT_USE_WPATH
|
#if TORRENT_USE_WPATH || TORRENT_USE_LOCALE_FILENAMES
|
||||||
// for safe_convert
|
// for convert_to_wstring and convert_to_native
|
||||||
#include "libtorrent/storage.hpp"
|
#include "libtorrent/escape_string.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "libtorrent/assert.hpp"
|
#include "libtorrent/assert.hpp"
|
||||||
|
@ -179,7 +179,7 @@ namespace libtorrent
|
||||||
};
|
};
|
||||||
|
|
||||||
#if TORRENT_USE_WPATH
|
#if TORRENT_USE_WPATH
|
||||||
m_path = safe_convert(path.external_file_string());
|
m_path = convert_to_wstring(path.external_file_string());
|
||||||
#else
|
#else
|
||||||
m_path = utf8_native(path.external_file_string());
|
m_path = utf8_native(path.external_file_string());
|
||||||
#endif
|
#endif
|
||||||
|
@ -220,8 +220,14 @@ namespace libtorrent
|
||||||
#else
|
#else
|
||||||
static const int no_buffer_flag[] = {0, 0};
|
static const int no_buffer_flag[] = {0, 0};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if TORRENT_USE_LOCALE_FILENAMES
|
||||||
|
m_fd = ::open(convert_to_native(path.external_file_string()).c_str()
|
||||||
|
, mode_array[mode & rw_mask] | no_buffer_flag[(mode & no_buffer) >> 2], permissions);
|
||||||
|
#else
|
||||||
m_fd = ::open(path.external_file_string().c_str()
|
m_fd = ::open(path.external_file_string().c_str()
|
||||||
, mode_array[mode & rw_mask] | no_buffer_flag[(mode & no_buffer) >> 2], permissions);
|
, mode_array[mode & rw_mask] | no_buffer_flag[(mode & no_buffer) >> 2], permissions);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef TORRENT_LINUX
|
#ifdef TORRENT_LINUX
|
||||||
// workaround for linux bug
|
// workaround for linux bug
|
||||||
|
|
100
src/storage.cpp
100
src/storage.cpp
|
@ -100,43 +100,9 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if TORRENT_USE_WPATH
|
#if TORRENT_USE_WPATH || TORRENT_USE_LOCALE_FILENAMES
|
||||||
|
// for convert_to_wstring and convert_to_native
|
||||||
#ifdef BOOST_WINDOWS
|
#include "libtorrent/escape_string.hpp"
|
||||||
#include <windows.h>
|
|
||||||
#else
|
|
||||||
#include <fcntl.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <boost/filesystem/exception.hpp>
|
|
||||||
#include "libtorrent/utf8.hpp"
|
|
||||||
#include "libtorrent/buffer.hpp"
|
|
||||||
|
|
||||||
namespace libtorrent
|
|
||||||
{
|
|
||||||
std::wstring safe_convert(std::string const& s)
|
|
||||||
{
|
|
||||||
std::wstring ret;
|
|
||||||
int result = libtorrent::utf8_wchar(s, ret);
|
|
||||||
#ifndef BOOST_WINDOWS
|
|
||||||
return ret;
|
|
||||||
#else
|
|
||||||
if (result == 0) return ret;
|
|
||||||
|
|
||||||
ret.clear();
|
|
||||||
const char* end = &s[0] + s.size();
|
|
||||||
for (const char* i = &s[0]; i < end;)
|
|
||||||
{
|
|
||||||
wchar_t c = '.';
|
|
||||||
int result = std::mbtowc(&c, i, end - i);
|
|
||||||
if (result > 0) i += result;
|
|
||||||
else ++i;
|
|
||||||
ret += c;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace fs = boost::filesystem;
|
namespace fs = boost::filesystem;
|
||||||
|
@ -222,7 +188,9 @@ namespace libtorrent
|
||||||
size_type size = 0;
|
size_type size = 0;
|
||||||
std::time_t time = 0;
|
std::time_t time = 0;
|
||||||
#if TORRENT_USE_WPATH
|
#if TORRENT_USE_WPATH
|
||||||
fs::wpath f = safe_convert((p / i->path).string());
|
fs::wpath f = convert_to_wstring((p / i->path).string());
|
||||||
|
#elif TORRENT_USE_LOCALE_FILENAMES
|
||||||
|
fs::path f = convert_to_native((p / i->path).string());
|
||||||
#else
|
#else
|
||||||
fs::path f = p / i->path;
|
fs::path f = p / i->path;
|
||||||
#endif
|
#endif
|
||||||
|
@ -273,7 +241,9 @@ namespace libtorrent
|
||||||
if (i->pad_file) continue;
|
if (i->pad_file) continue;
|
||||||
|
|
||||||
#if TORRENT_USE_WPATH
|
#if TORRENT_USE_WPATH
|
||||||
fs::wpath f = safe_convert((p / i->path).string());
|
fs::wpath f = convert_to_wstring((p / i->path).string());
|
||||||
|
#elif TORRENT_USE_LOCALE_FILENAMES
|
||||||
|
fs::path f = convert_to_native(p / i->path);
|
||||||
#else
|
#else
|
||||||
fs::path f = p / i->path;
|
fs::path f = p / i->path;
|
||||||
#endif
|
#endif
|
||||||
|
@ -535,9 +505,13 @@ namespace libtorrent
|
||||||
last_path = dir;
|
last_path = dir;
|
||||||
|
|
||||||
#if TORRENT_USE_WPATH
|
#if TORRENT_USE_WPATH
|
||||||
fs::wpath wp = safe_convert(last_path.string());
|
fs::wpath wp = convert_to_wstring(last_path.string());
|
||||||
if (!exists(wp))
|
if (!exists(wp))
|
||||||
create_directories(wp);
|
create_directories(wp);
|
||||||
|
#elif TORRENT_USE_LOCALE_FILENAMES
|
||||||
|
fs::path p = convert_to_native(last_path.string());
|
||||||
|
if (!exists(p))
|
||||||
|
create_directories(p);
|
||||||
#else
|
#else
|
||||||
if (!exists(last_path))
|
if (!exists(last_path))
|
||||||
create_directories(last_path);
|
create_directories(last_path);
|
||||||
|
@ -558,7 +532,7 @@ namespace libtorrent
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if TORRENT_USE_WPATH
|
#if TORRENT_USE_WPATH
|
||||||
fs::wpath file_path = safe_convert((m_save_path / file_iter->path).string());
|
fs::wpath file_path = convert_to_wstring((m_save_path / file_iter->path).string());
|
||||||
#else
|
#else
|
||||||
fs::path file_path = m_save_path / file_iter->path;
|
fs::path file_path = m_save_path / file_iter->path;
|
||||||
#endif
|
#endif
|
||||||
|
@ -609,8 +583,11 @@ namespace libtorrent
|
||||||
m_pool.release(old_name);
|
m_pool.release(old_name);
|
||||||
|
|
||||||
#if TORRENT_USE_WPATH
|
#if TORRENT_USE_WPATH
|
||||||
fs::wpath old_path = safe_convert(old_name.string());
|
fs::wpath old_path = convert_to_wstring(old_name.string());
|
||||||
fs::wpath new_path = safe_convert((m_save_path / new_filename).string());
|
fs::wpath new_path = convert_to_wstring((m_save_path / new_filename).string());
|
||||||
|
#elif TORRENT_USE_LOCALE_FILENAMES
|
||||||
|
fs::path const& old_path = convert_to_native(old_name.string());
|
||||||
|
fs::path new_path = convert_to_native((m_save_path / new_filename).string());
|
||||||
#else
|
#else
|
||||||
fs::path const& old_path = old_name;
|
fs::path const& old_path = old_name;
|
||||||
fs::path new_path = m_save_path / new_filename;
|
fs::path new_path = m_save_path / new_filename;
|
||||||
|
@ -686,12 +663,18 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
#if TORRENT_USE_WPATH
|
#if TORRENT_USE_WPATH
|
||||||
try
|
try
|
||||||
{ fs::remove(safe_convert(p)); }
|
{ fs::remove(convert_to_wstring(p)); }
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
error = errno;
|
error = errno;
|
||||||
error_file = p;
|
error_file = p;
|
||||||
}
|
}
|
||||||
|
#elif TORRENT_USE_LOCALE_FILENAMES
|
||||||
|
if (std::remove(convert_to_native(p).c_str()) != 0 && errno != ENOENT)
|
||||||
|
{
|
||||||
|
error = errno;
|
||||||
|
error_file = p;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
if (std::remove(p.c_str()) != 0 && errno != ENOENT)
|
if (std::remove(p.c_str()) != 0 && errno != ENOENT)
|
||||||
{
|
{
|
||||||
|
@ -709,12 +692,18 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
#if TORRENT_USE_WPATH
|
#if TORRENT_USE_WPATH
|
||||||
try
|
try
|
||||||
{ fs::remove(safe_convert(*i)); }
|
{ fs::remove(convert_to_wstring(*i)); }
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
error = errno;
|
error = errno;
|
||||||
error_file = *i;
|
error_file = *i;
|
||||||
}
|
}
|
||||||
|
#elif TORRENT_USE_LOCALE_FILENAMES
|
||||||
|
if (std::remove(convert_to_native(*i).c_str()) != 0 && errno != ENOENT)
|
||||||
|
{
|
||||||
|
error = errno;
|
||||||
|
error_file = *i;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
if (std::remove(i->c_str()) != 0 && errno != ENOENT)
|
if (std::remove(i->c_str()) != 0 && errno != ENOENT)
|
||||||
{
|
{
|
||||||
|
@ -903,9 +892,9 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return match_filesizes(files(), m_save_path, file_sizes
|
return match_filesizes(files(), m_save_path, file_sizes
|
||||||
, !full_allocation_mode, &error);
|
, !full_allocation_mode, &error);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns true on success
|
// returns true on success
|
||||||
|
@ -922,11 +911,17 @@ namespace libtorrent
|
||||||
save_path = complete(save_path);
|
save_path = complete(save_path);
|
||||||
|
|
||||||
#if TORRENT_USE_WPATH
|
#if TORRENT_USE_WPATH
|
||||||
fs::wpath wp = safe_convert(save_path.string());
|
fs::wpath wp = convert_to_wstring(save_path.string());
|
||||||
if (!exists(wp))
|
if (!exists(wp))
|
||||||
create_directory(wp);
|
create_directory(wp);
|
||||||
else if (!is_directory(wp))
|
else if (!is_directory(wp))
|
||||||
return false;
|
return false;
|
||||||
|
#elif TORRENT_USE_LOCALE_FILENAMES
|
||||||
|
fs::path p = convert_to_native(save_path.string());
|
||||||
|
if (!exists(p))
|
||||||
|
create_directory(p);
|
||||||
|
else if (!is_directory(p))
|
||||||
|
return false;
|
||||||
#else
|
#else
|
||||||
if (!exists(save_path))
|
if (!exists(save_path))
|
||||||
create_directory(save_path);
|
create_directory(save_path);
|
||||||
|
@ -937,8 +932,11 @@ namespace libtorrent
|
||||||
m_pool.release(this);
|
m_pool.release(this);
|
||||||
|
|
||||||
#if TORRENT_USE_WPATH
|
#if TORRENT_USE_WPATH
|
||||||
old_path = safe_convert((m_save_path / files().name()).string());
|
old_path = convert_to_wstring((m_save_path / files().name()).string());
|
||||||
new_path = safe_convert((save_path / files().name()).string());
|
new_path = convert_to_wstring((save_path / files().name()).string());
|
||||||
|
#elif TORRENT_USE_LOCALE_FILENAMES
|
||||||
|
old_path = convert_to_native((m_save_path / files().name()).string());
|
||||||
|
new_path = convert_to_native((save_path / files().name().string()));
|
||||||
#else
|
#else
|
||||||
old_path = m_save_path / files().name();
|
old_path = m_save_path / files().name();
|
||||||
new_path = save_path / files().name();
|
new_path = save_path / files().name();
|
||||||
|
@ -1858,8 +1856,10 @@ ret:
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
#if TORRENT_USE_WPATH
|
#if TORRENT_USE_WPATH
|
||||||
fs::wpath wf = safe_convert(f.string());
|
fs::wpath wf = convert_to_wstring(f.string());
|
||||||
file_exists = exists(wf);
|
file_exists = exists(wf);
|
||||||
|
#elif TORRENT_USE_LOCALE_FILENAMES
|
||||||
|
file_exists = exists(convert_to_native(f.string()));
|
||||||
#else
|
#else
|
||||||
file_exists = exists(f);
|
file_exists = exists(f);
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue