forked from premiere/premiere-libtorrent
fixed inconsistency when creating torrents with symlinks
This commit is contained in:
parent
a0a8c695ab
commit
c51e0a2a86
|
@ -26,6 +26,7 @@
|
|||
incoming connection
|
||||
* added more detailed instrumentation of the disk I/O thread
|
||||
|
||||
* fixed inconsistency when creating torrents with symlinks
|
||||
* properly detect windows version to initialize half-open connection limit
|
||||
* fixed bug in url encoder where $ would not be encoded
|
||||
|
||||
|
|
|
@ -58,12 +58,16 @@ add_files
|
|||
::
|
||||
|
||||
template <class Pred>
|
||||
void add_files(file_storage& fs, boost::filesystem::path const& path, Pred p);
|
||||
void add_files(file_storage& fs, boost::filesystem::path const& path, Pred p
|
||||
, boost::uint32_t flags = 0);
|
||||
template <class Pred>
|
||||
void add_files(file_storage& fs, boost::filesystem::wpath const& path, Pred p);
|
||||
void add_files(file_storage& fs, boost::filesystem::wpath const& path, Pred p
|
||||
, boost::uint32_t flags = 0);
|
||||
|
||||
void add_files(file_storage& fs, boost::filesystem::path const& path);
|
||||
void add_files(file_storage& fs, boost::filesystem::wpath const& path);
|
||||
void add_files(file_storage& fs, boost::filesystem::path const& path
|
||||
, boost::uint32_t flags = 0);
|
||||
void add_files(file_storage& fs, boost::filesystem::wpath const& path
|
||||
, boost::uint32_t flags = 0);
|
||||
|
||||
Adds the file specified by ``path`` to the ``file_storage`` object. In case ``path``
|
||||
refers to a diretory, files will be added recursively from the directory.
|
||||
|
@ -84,6 +88,9 @@ are traveresed.
|
|||
|
||||
The ".." directory is never traversed.
|
||||
|
||||
The ``flags`` argument should be the same as the flags passed to the `create_torrent`_
|
||||
constructor.
|
||||
|
||||
set_piece_hashes()
|
||||
==================
|
||||
|
||||
|
@ -224,7 +231,8 @@ The ``create_torrent`` class has the following synopsis::
|
|||
, symlink = 8
|
||||
, calculate_file_hashes = 16
|
||||
};
|
||||
create_torrent(file_storage& fs, int piece_size = 0, int pad_size_limit = -1, int flags = optimize);
|
||||
create_torrent(file_storage& fs, int piece_size = 0, int pad_size_limit = -1
|
||||
, int flags = optimize);
|
||||
create_torrent(torrent_info const& ti);
|
||||
|
||||
entry generate() const;
|
||||
|
@ -258,7 +266,8 @@ create_torrent()
|
|||
, symlink = 8
|
||||
, calculate_file_hashes = 16
|
||||
};
|
||||
create_torrent(file_storage& fs, int piece_size = 0, int pad_size_limit = -1, int flags = optimize);
|
||||
create_torrent(file_storage& fs, int piece_size = 0, int pad_size_limit = -1
|
||||
, int flags = optimize);
|
||||
create_torrent(torrent_info const& ti);
|
||||
|
||||
The ``piece_size`` is the size of each piece in bytes. It must
|
||||
|
@ -300,11 +309,10 @@ modification_time
|
|||
files.
|
||||
|
||||
symlink
|
||||
If this flag is defined, files that are symlinks get a symlink attribute
|
||||
set on them. The file data will still be the same, the symlink will always
|
||||
be followed when opening the file, but the file list will include the path
|
||||
of the symlink so that the original directory structure can be reproduced
|
||||
on the downloading side.
|
||||
If this flag is set, files that are symlinks get a symlink attribute
|
||||
set on them and their data will not be included in the torrent. This
|
||||
is useful if you need to reconstruct a file hierarchy which contains
|
||||
symlinks.
|
||||
|
||||
calculate_file_hashes
|
||||
If this is set, the `set_piece_hashes()`_ function will, as it calculates
|
||||
|
|
|
@ -77,6 +77,8 @@ void print_usage()
|
|||
" than bytes will be piece-aligned\n"
|
||||
"-s bytes specifies a piece size for the torrent\n"
|
||||
" This has to be a multiple of 16 kiB\n"
|
||||
"-l Don't follow symlinks, instead encode them as\n"
|
||||
" links in the torrent file\n"
|
||||
"-o file specifies the output filename of the torrent file\n"
|
||||
" If this is not specified, the torrent file is\n"
|
||||
" printed to the standard out, except on windows\n"
|
||||
|
@ -150,6 +152,9 @@ int main(int argc, char* argv[])
|
|||
case 'f':
|
||||
flags |= create_torrent::calculate_file_hashes;
|
||||
break;
|
||||
case 'l':
|
||||
flags |= create_torrent::symlinks;
|
||||
break;
|
||||
default:
|
||||
print_usage();
|
||||
return 1;
|
||||
|
@ -160,7 +165,7 @@ int main(int argc, char* argv[])
|
|||
file_pool fp;
|
||||
std::string full_path = libtorrent::complete(argv[1]);
|
||||
|
||||
add_files(fs, full_path, file_filter);
|
||||
add_files(fs, full_path, file_filter, flags);
|
||||
if (fs.num_files() == 0)
|
||||
{
|
||||
fputs("no files specified.\n", stderr);
|
||||
|
|
|
@ -180,22 +180,32 @@ namespace libtorrent
|
|||
|
||||
template <class Pred>
|
||||
void add_files_impl(file_storage& fs, std::string const& p
|
||||
, std::string const& l, Pred pred)
|
||||
, std::string const& l, Pred pred, boost::uint32_t flags)
|
||||
{
|
||||
std::string f = combine_path(p, l);
|
||||
if (!pred(f)) return;
|
||||
error_code ec;
|
||||
file_status s;
|
||||
stat_file(f, &s, ec);
|
||||
stat_file(f, &s, ec, (flags & create_torrent::symlinks) ? dont_follow_links : 0);
|
||||
if (ec) return;
|
||||
|
||||
if (s.mode & file_status::directory)
|
||||
// recurse into directories
|
||||
bool recurse = s.mode & file_status::directory;
|
||||
|
||||
// if the file is not a link or we're following links, and it's a directory
|
||||
// only then should we recurse
|
||||
#ifndef TORRENT_WINDOWS
|
||||
if ((s.mode & file_status::link) && (flags & create_torrent::symlinks))
|
||||
recurse = false;
|
||||
#endif
|
||||
|
||||
if (recurse)
|
||||
{
|
||||
for (directory i(f, ec); !i.done(); i.next(ec))
|
||||
{
|
||||
std::string leaf = i.file();
|
||||
if (ignore_subdir(leaf)) continue;
|
||||
add_files_impl(fs, p, combine_path(l, leaf), pred);
|
||||
add_files_impl(fs, p, combine_path(l, leaf), pred, flags);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -204,7 +214,8 @@ namespace libtorrent
|
|||
int file_flags = get_file_attributes(f);
|
||||
|
||||
// mask all bits to check if the file is a symlink
|
||||
if (file_flags & file_storage::attribute_symlink)
|
||||
if ((file_flags & file_storage::attribute_symlink)
|
||||
&& (flags & create_torrent::symlinks))
|
||||
{
|
||||
std::string sym_path = get_symlink_path(f);
|
||||
fs.add_file(l, 0, file_flags, s.mtime, sym_path);
|
||||
|
@ -218,14 +229,15 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
template <class Pred>
|
||||
void add_files(file_storage& fs, std::string const& file, Pred p)
|
||||
void add_files(file_storage& fs, std::string const& file, Pred p, boost::uint32_t flags = 0)
|
||||
{
|
||||
detail::add_files_impl(fs, parent_path(complete(file)), filename(file), p);
|
||||
detail::add_files_impl(fs, parent_path(complete(file)), filename(file), p, flags);
|
||||
}
|
||||
|
||||
inline void add_files(file_storage& fs, std::string const& file)
|
||||
inline void add_files(file_storage& fs, std::string const& file, boost::uint32_t flags = 0)
|
||||
{
|
||||
detail::add_files_impl(fs, parent_path(complete(file)), filename(file), detail::default_pred);
|
||||
detail::add_files_impl(fs, parent_path(complete(file)), filename(file)
|
||||
, detail::default_pred, flags);
|
||||
}
|
||||
|
||||
struct piece_holder
|
||||
|
@ -318,18 +330,20 @@ namespace libtorrent
|
|||
// wstring versions
|
||||
|
||||
template <class Pred>
|
||||
void add_files(file_storage& fs, std::wstring const& wfile, Pred p)
|
||||
void add_files(file_storage& fs, std::wstring const& wfile, Pred p, boost::uint32_t flags = 0)
|
||||
{
|
||||
std::string utf8;
|
||||
wchar_utf8(wfile, utf8);
|
||||
detail::add_files_impl(fs, parent_path(complete(utf8)), filename(utf8), p);
|
||||
detail::add_files_impl(fs, parent_path(complete(utf8))
|
||||
, filename(utf8), p, flags);
|
||||
}
|
||||
|
||||
inline void add_files(file_storage& fs, std::wstring const& wfile)
|
||||
inline void add_files(file_storage& fs, std::wstring const& wfile, boost::uint32_t flags = 0)
|
||||
{
|
||||
std::string utf8;
|
||||
wchar_utf8(wfile, utf8);
|
||||
detail::add_files_impl(fs, parent_path(complete(utf8)), filename(utf8), detail::default_pred);
|
||||
detail::add_files_impl(fs, parent_path(complete(utf8))
|
||||
, filename(utf8), detail::default_pred, flags);
|
||||
}
|
||||
|
||||
template <class Fun>
|
||||
|
|
|
@ -104,8 +104,9 @@ namespace libtorrent
|
|||
int mode;
|
||||
};
|
||||
|
||||
enum stat_flags_t { dont_follow_links = 1 };
|
||||
TORRENT_EXPORT void stat_file(std::string const& f, file_status* s
|
||||
, error_code& ec);
|
||||
, error_code& ec, int flags = 0);
|
||||
TORRENT_EXPORT void rename(std::string const& f
|
||||
, std::string const& newf, error_code& ec);
|
||||
TORRENT_EXPORT void create_directories(std::string const& f
|
||||
|
|
|
@ -170,6 +170,7 @@ namespace libtorrent
|
|||
, m_merkle_torrent(ti.is_merkle_torrent())
|
||||
, m_include_mtime(false)
|
||||
, m_include_symlinks(false)
|
||||
, m_calculate_file_hashes(false)
|
||||
{
|
||||
TORRENT_ASSERT(ti.is_valid());
|
||||
if (ti.creation_date()) m_creation_date = *ti.creation_date();
|
||||
|
|
10
src/file.cpp
10
src/file.cpp
|
@ -126,7 +126,8 @@ BOOST_STATIC_ASSERT((libtorrent::file::no_buffer & libtorrent::file::attribute_m
|
|||
|
||||
namespace libtorrent
|
||||
{
|
||||
void stat_file(std::string const& inf, file_status* s, error_code& ec)
|
||||
void stat_file(std::string const& inf, file_status* s
|
||||
, error_code& ec, int flags)
|
||||
{
|
||||
ec.clear();
|
||||
|
||||
|
@ -149,7 +150,12 @@ namespace libtorrent
|
|||
}
|
||||
#else
|
||||
struct stat ret;
|
||||
if (::stat(f.c_str(), &ret) < 0)
|
||||
int retval;
|
||||
if (flags & dont_follow_links)
|
||||
retval = ::lstat(f.c_str(), &ret);
|
||||
else
|
||||
retval = ::stat(f.c_str(), &ret);
|
||||
if (retval < 0)
|
||||
{
|
||||
ec.assign(errno, boost::system::get_generic_category());
|
||||
return;
|
||||
|
|
Loading…
Reference in New Issue