diff --git a/include/libtorrent/create_torrent.hpp b/include/libtorrent/create_torrent.hpp index 7b247da3c..cd101e149 100644 --- a/include/libtorrent/create_torrent.hpp +++ b/include/libtorrent/create_torrent.hpp @@ -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::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 void add_files_impl(file_storage& fs, boost::filesystem::basic_path const& p , boost::filesystem::basic_path const& l, Pred pred) @@ -187,7 +190,8 @@ namespace libtorrent else { 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 - diff --git a/include/libtorrent/file_storage.hpp b/include/libtorrent/file_storage.hpp index a69f9a198..0587764b1 100644 --- a/include/libtorrent/file_storage.hpp +++ b/include/libtorrent/file_storage.hpp @@ -67,6 +67,7 @@ namespace libtorrent // This is always 0 unless parts of the torrent is // compressed into a single file, such as a so-called part file. size_type file_base; + std::time_t mtime; bool pad_file:1; bool hidden_attribute:1; bool executable_attribute:1; @@ -96,11 +97,11 @@ namespace libtorrent }; 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); #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 set_name(std::wstring const& n); #endif diff --git a/src/create_torrent.cpp b/src/create_torrent.cpp index 22c3336b6..b8cb8b636 100644 --- a/src/create_torrent.cpp +++ b/src/create_torrent.cpp @@ -33,6 +33,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/create_torrent.hpp" #include "libtorrent/file_pool.hpp" #include "libtorrent/storage.hpp" +#include "libtorrent/escape_string.hpp" #include #include @@ -59,7 +60,7 @@ namespace libtorrent { #ifdef TORRENT_WINDOWS -#ifdef TORRENT_USE_WPATH +#if TORRENT_USE_WPATH std::wstring path = convert_to_wstring(p.external_file_string()); DWORD attr = GetFileAttributesW(path.c_str()); #else @@ -82,12 +83,53 @@ namespace libtorrent DWORD attr = GetFileAttributesW(path.c_str()); if (attr & FILE_ATTRIBUTE_HIDDEN) return file_storage::attribute_hidden; 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 std::string utf8; wchar_utf8(p.string(), utf8); - struct stat s; - if (stat(utf8.c_str(), &s) < 0) return 0; - return (s.st_mode & S_IXUSR) ? file_storage::attribute_executable : 0; + utf8 = convert_to_native(utf8); + return get_file_mtime(utf8.c_str()); #endif } } @@ -263,7 +305,15 @@ namespace libtorrent if (!m_multifile) { + info["mtime"] = m_files.at(0).mtime; 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 { @@ -276,6 +326,7 @@ namespace libtorrent { files.list().push_back(entry()); entry& file_e = files.list().back(); + file_e["mtime"] = i->mtime; file_e["length"] = i->size; entry& path_e = file_e["path"]; diff --git a/src/file_storage.cpp b/src/file_storage.cpp index 330e8b10a..e320b5165 100644 --- a/src/file_storage.cpp +++ b/src/file_storage.cpp @@ -37,7 +37,6 @@ POSSIBILITY OF SUCH DAMAGE. #include #include - namespace libtorrent { file_storage::file_storage() @@ -77,11 +76,11 @@ namespace libtorrent 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; wchar_utf8(file.string(), utf8); - add_file(utf8, size, flags); + add_file(utf8, size, flags, mtime); } #endif @@ -165,7 +164,7 @@ namespace libtorrent 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); #if BOOST_VERSION < 103600 @@ -195,6 +194,7 @@ namespace libtorrent e.pad_file = bool(flags & pad_file); e.hidden_attribute = bool(flags & attribute_hidden); e.executable_attribute = bool(flags & attribute_executable); + e.mtime = mtime; m_total_size += size; } diff --git a/src/torrent_info.cpp b/src/torrent_info.cpp index 00bd709be..5f500d745 100644 --- a/src/torrent_info.cpp +++ b/src/torrent_info.cpp @@ -223,6 +223,9 @@ namespace libtorrent target.path = root_dir; 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 // because if it exists, it is more // likely to be correctly encoded @@ -612,6 +615,22 @@ namespace libtorrent e.path = name; e.offset = 0; 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 if (e.path.string().find("_____padding_file_") != std::string::npos) e.pad_file = true;