added support for preserving modification time of files in torrents
This commit is contained in:
parent
3e3c60b1ca
commit
5de60fad78
|
@ -161,6 +161,9 @@ namespace libtorrent
|
||||||
int TORRENT_EXPORT get_file_attributes(boost::filesystem::path const& p);
|
int TORRENT_EXPORT get_file_attributes(boost::filesystem::path const& p);
|
||||||
int TORRENT_EXPORT get_file_attributes(boost::filesystem::wpath const& p);
|
int TORRENT_EXPORT get_file_attributes(boost::filesystem::wpath const& p);
|
||||||
|
|
||||||
|
std::time_t TORRENT_EXPORT get_file_mtime(boost::filesystem::path const& p);
|
||||||
|
std::time_t TORRENT_EXPORT get_file_mtime(boost::filesystem::wpath const& p);
|
||||||
|
|
||||||
template <class Pred, class Str, class PathTraits>
|
template <class Pred, class Str, class PathTraits>
|
||||||
void add_files_impl(file_storage& fs, boost::filesystem::basic_path<Str, PathTraits> const& p
|
void add_files_impl(file_storage& fs, boost::filesystem::basic_path<Str, PathTraits> const& p
|
||||||
, boost::filesystem::basic_path<Str, PathTraits> const& l, Pred pred)
|
, boost::filesystem::basic_path<Str, PathTraits> const& l, Pred pred)
|
||||||
|
@ -187,7 +190,8 @@ namespace libtorrent
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int file_flags = get_file_attributes(f);
|
int file_flags = get_file_attributes(f);
|
||||||
fs.add_file(l, file_size(f), file_flags);
|
std::time_t mtime = get_file_mtime(f);
|
||||||
|
fs.add_file(l, file_size(f), file_flags, mtime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -349,4 +353,3 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,7 @@ namespace libtorrent
|
||||||
// This is always 0 unless parts of the torrent is
|
// This is always 0 unless parts of the torrent is
|
||||||
// compressed into a single file, such as a so-called part file.
|
// compressed into a single file, such as a so-called part file.
|
||||||
size_type file_base;
|
size_type file_base;
|
||||||
|
std::time_t mtime;
|
||||||
bool pad_file:1;
|
bool pad_file:1;
|
||||||
bool hidden_attribute:1;
|
bool hidden_attribute:1;
|
||||||
bool executable_attribute:1;
|
bool executable_attribute:1;
|
||||||
|
@ -96,11 +97,11 @@ namespace libtorrent
|
||||||
};
|
};
|
||||||
|
|
||||||
void add_file(file_entry const& e);
|
void add_file(file_entry const& e);
|
||||||
void add_file(fs::path const& p, size_type size, int flags = 0);
|
void add_file(fs::path const& p, size_type size, int flags = 0, std::time_t mtime = 0);
|
||||||
void rename_file(int index, std::string const& new_filename);
|
void rename_file(int index, std::string const& new_filename);
|
||||||
|
|
||||||
#ifndef BOOST_FILESYSTEM_NARROW_ONLY
|
#ifndef BOOST_FILESYSTEM_NARROW_ONLY
|
||||||
void add_file(fs::wpath const& p, size_type size, int flags = 0);
|
void add_file(fs::wpath const& p, size_type size, int flags = 0, std::time_t mtime = 0);
|
||||||
void rename_file(int index, std::wstring const& new_filename);
|
void rename_file(int index, std::wstring const& new_filename);
|
||||||
void set_name(std::wstring const& n);
|
void set_name(std::wstring const& n);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -33,6 +33,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "libtorrent/create_torrent.hpp"
|
#include "libtorrent/create_torrent.hpp"
|
||||||
#include "libtorrent/file_pool.hpp"
|
#include "libtorrent/file_pool.hpp"
|
||||||
#include "libtorrent/storage.hpp"
|
#include "libtorrent/storage.hpp"
|
||||||
|
#include "libtorrent/escape_string.hpp"
|
||||||
|
|
||||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||||
#include <boost/date_time/gregorian/gregorian.hpp>
|
#include <boost/date_time/gregorian/gregorian.hpp>
|
||||||
|
@ -59,7 +60,7 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
#ifdef TORRENT_WINDOWS
|
#ifdef TORRENT_WINDOWS
|
||||||
|
|
||||||
#ifdef TORRENT_USE_WPATH
|
#if TORRENT_USE_WPATH
|
||||||
std::wstring path = convert_to_wstring(p.external_file_string());
|
std::wstring path = convert_to_wstring(p.external_file_string());
|
||||||
DWORD attr = GetFileAttributesW(path.c_str());
|
DWORD attr = GetFileAttributesW(path.c_str());
|
||||||
#else
|
#else
|
||||||
|
@ -82,12 +83,53 @@ namespace libtorrent
|
||||||
DWORD attr = GetFileAttributesW(path.c_str());
|
DWORD attr = GetFileAttributesW(path.c_str());
|
||||||
if (attr & FILE_ATTRIBUTE_HIDDEN) return file_storage::attribute_hidden;
|
if (attr & FILE_ATTRIBUTE_HIDDEN) return file_storage::attribute_hidden;
|
||||||
return 0;
|
return 0;
|
||||||
|
#else
|
||||||
|
std::string native;
|
||||||
|
wchar_utf8(p.string(), native);
|
||||||
|
native = convert_to_native(native);
|
||||||
|
|
||||||
|
struct stat s;
|
||||||
|
if (stat(native.c_str(), &s) < 0) return 0;
|
||||||
|
return (s.st_mode & S_IXUSR) ? file_storage::attribute_executable : 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
std::time_t get_file_mtime(char const* path)
|
||||||
|
{
|
||||||
|
#ifdef TORRENT_WINDOWS
|
||||||
|
struct _stat s;
|
||||||
|
if (::_stat(path, &s) < 0) return 0;
|
||||||
|
#else
|
||||||
|
struct stat s;
|
||||||
|
if (lstat(path, &s) < 0) return 0;
|
||||||
|
#endif
|
||||||
|
return s.st_mtime;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::time_t TORRENT_EXPORT get_file_mtime(boost::filesystem::path const& p)
|
||||||
|
{
|
||||||
|
#if defined TORRENT_WINDOWS && TORRENT_USE_WPATH
|
||||||
|
std::wstring path = convert_to_wstring(p.external_file_string());
|
||||||
|
struct _stat s;
|
||||||
|
if (::_wstat(path.c_str(), &s) < 0) return 0;
|
||||||
|
return s.st_mtime;
|
||||||
|
#else
|
||||||
|
std::string path = convert_to_native(p.external_file_string());
|
||||||
|
return get_file_mtime(p.string().c_str());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
std::time_t TORRENT_EXPORT get_file_mtime(boost::filesystem::wpath const& p)
|
||||||
|
{
|
||||||
|
#ifdef TORRENT_WINDOWS
|
||||||
|
struct _stat s;
|
||||||
|
if (::_wstat(p.string().c_str(), &s) < 0) return 0;
|
||||||
|
return s.st_mtime;
|
||||||
#else
|
#else
|
||||||
std::string utf8;
|
std::string utf8;
|
||||||
wchar_utf8(p.string(), utf8);
|
wchar_utf8(p.string(), utf8);
|
||||||
struct stat s;
|
utf8 = convert_to_native(utf8);
|
||||||
if (stat(utf8.c_str(), &s) < 0) return 0;
|
return get_file_mtime(utf8.c_str());
|
||||||
return (s.st_mode & S_IXUSR) ? file_storage::attribute_executable : 0;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -263,7 +305,15 @@ namespace libtorrent
|
||||||
|
|
||||||
if (!m_multifile)
|
if (!m_multifile)
|
||||||
{
|
{
|
||||||
|
info["mtime"] = m_files.at(0).mtime;
|
||||||
info["length"] = m_files.at(0).size;
|
info["length"] = m_files.at(0).size;
|
||||||
|
if (m_files.at(0).pad_file || m_files.at(0).hidden_attribute || m_files.at(0).executable_attribute)
|
||||||
|
{
|
||||||
|
std::string& attr = info["attr"].string();
|
||||||
|
if (m_files.at(0).pad_file) attr += 'p';
|
||||||
|
if (m_files.at(0).hidden_attribute) attr += 'h';
|
||||||
|
if (m_files.at(0).executable_attribute) attr += 'x';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -276,6 +326,7 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
files.list().push_back(entry());
|
files.list().push_back(entry());
|
||||||
entry& file_e = files.list().back();
|
entry& file_e = files.list().back();
|
||||||
|
file_e["mtime"] = i->mtime;
|
||||||
file_e["length"] = i->size;
|
file_e["length"] = i->size;
|
||||||
entry& path_e = file_e["path"];
|
entry& path_e = file_e["path"];
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <boost/bind.hpp>
|
#include <boost/bind.hpp>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
file_storage::file_storage()
|
file_storage::file_storage()
|
||||||
|
@ -77,11 +76,11 @@ namespace libtorrent
|
||||||
m_files[index].path = utf8;
|
m_files[index].path = utf8;
|
||||||
}
|
}
|
||||||
|
|
||||||
void file_storage::add_file(fs::wpath const& file, size_type size, int flags)
|
void file_storage::add_file(fs::wpath const& file, size_type size, int flags, std::time_t mtime)
|
||||||
{
|
{
|
||||||
std::string utf8;
|
std::string utf8;
|
||||||
wchar_utf8(file.string(), utf8);
|
wchar_utf8(file.string(), utf8);
|
||||||
add_file(utf8, size, flags);
|
add_file(utf8, size, flags, mtime);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -165,7 +164,7 @@ namespace libtorrent
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void file_storage::add_file(fs::path const& file, size_type size, int flags)
|
void file_storage::add_file(fs::path const& file, size_type size, int flags, std::time_t mtime)
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(size >= 0);
|
TORRENT_ASSERT(size >= 0);
|
||||||
#if BOOST_VERSION < 103600
|
#if BOOST_VERSION < 103600
|
||||||
|
@ -195,6 +194,7 @@ namespace libtorrent
|
||||||
e.pad_file = bool(flags & pad_file);
|
e.pad_file = bool(flags & pad_file);
|
||||||
e.hidden_attribute = bool(flags & attribute_hidden);
|
e.hidden_attribute = bool(flags & attribute_hidden);
|
||||||
e.executable_attribute = bool(flags & attribute_executable);
|
e.executable_attribute = bool(flags & attribute_executable);
|
||||||
|
e.mtime = mtime;
|
||||||
m_total_size += size;
|
m_total_size += size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -223,6 +223,9 @@ namespace libtorrent
|
||||||
target.path = root_dir;
|
target.path = root_dir;
|
||||||
target.file_base = 0;
|
target.file_base = 0;
|
||||||
|
|
||||||
|
size_type ts = dict.dict_find_int_value("mtime", -1);
|
||||||
|
if (ts >= 0) target.mtime = std::time_t(ts);
|
||||||
|
|
||||||
// prefer the name.utf-8
|
// prefer the name.utf-8
|
||||||
// because if it exists, it is more
|
// because if it exists, it is more
|
||||||
// likely to be correctly encoded
|
// likely to be correctly encoded
|
||||||
|
@ -612,6 +615,22 @@ namespace libtorrent
|
||||||
e.path = name;
|
e.path = name;
|
||||||
e.offset = 0;
|
e.offset = 0;
|
||||||
e.size = info.dict_find_int_value("length", -1);
|
e.size = info.dict_find_int_value("length", -1);
|
||||||
|
size_type ts = info.dict_find_int_value("mtime", -1);
|
||||||
|
if (ts >= 0)
|
||||||
|
e.mtime = std::time_t(ts);
|
||||||
|
lazy_entry const* attr = info.dict_find_string("attr");
|
||||||
|
if (attr)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < attr->string_length(); ++i)
|
||||||
|
{
|
||||||
|
switch (attr->string_ptr()[i])
|
||||||
|
{
|
||||||
|
case 'x': e.executable_attribute = true; break;
|
||||||
|
case 'h': e.hidden_attribute = true; break;
|
||||||
|
case 'p': e.pad_file = true; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
// bitcomet pad file
|
// bitcomet pad file
|
||||||
if (e.path.string().find("_____padding_file_") != std::string::npos)
|
if (e.path.string().find("_____padding_file_") != std::string::npos)
|
||||||
e.pad_file = true;
|
e.pad_file = true;
|
||||||
|
|
Loading…
Reference in New Issue