124
140
// to know if it should be written as a multifile torrent
125
141
// or not. e.g. test/test there's one file and one directory
126
142
// and they have the same name.
129
145
// this is true if the torrent is private. i.e., is should not
130
146
// be announced on the dht
149
// if set to one, a merkle torrent will be generated
150
bool m_merkle_torrent:1;
152
// if set, include the 'mtime' modification time in the
154
bool m_include_mtime:1;
156
// if set, symbolic links are declared as such in
157
// the torrent file. The full data of the pointed-to
158
// file is still included
159
bool m_include_symlinks:1;
136
164
inline bool default_pred(boost::filesystem::path const&) { return true; }
165
#if TORRENT_USE_WPATH
166
inline bool wdefault_pred(boost::filesystem::wpath const&) { return true; }
169
inline bool ignore_subdir(std::string const& leaf)
170
{ return leaf == ".." || leaf == "."; }
172
inline bool ignore_subdir(std::wstring const& leaf)
173
{ return leaf == L".." || leaf == L"."; }
138
175
inline void nop(int i) {}
140
template <class Pred>
141
void add_files_impl(file_storage& fs, boost::filesystem::path const& p
142
, boost::filesystem::path const& l, Pred pred)
177
int TORRENT_EXPORT get_file_attributes(boost::filesystem::path const& p);
178
#if TORRENT_USE_WPATH
179
int TORRENT_EXPORT get_file_attributes(boost::filesystem::wpath const& p);
182
std::time_t TORRENT_EXPORT get_file_mtime(boost::filesystem::path const& p);
183
#if TORRENT_USE_WPATH
184
std::time_t TORRENT_EXPORT get_file_mtime(boost::filesystem::wpath const& p);
187
fs::path TORRENT_EXPORT get_symlink_path(boost::filesystem::path const& p);
188
#if TORRENT_USE_WPATH
189
fs::path TORRENT_EXPORT get_symlink_path(boost::filesystem::wpath const& p);
192
template <class Pred, class Str, class PathTraits>
193
void add_files_impl(file_storage& fs, boost::filesystem::basic_path<Str, PathTraits> const& p
194
, boost::filesystem::basic_path<Str, PathTraits> const& l, Pred pred)
144
using boost::filesystem::path;
145
using boost::filesystem::directory_iterator;
146
if (!pred(l)) return;
196
using boost::filesystem::basic_path;
197
using boost::filesystem::basic_directory_iterator;
198
basic_path<Str, PathTraits> f(p / l);
199
if (!pred(f)) return;
148
200
if (is_directory(f))
150
for (directory_iterator i(f), end; i != end; ++i)
202
for (basic_directory_iterator<basic_path<Str, PathTraits> > i(f), end; i != end; ++i)
152
204
#if BOOST_VERSION < 103600
153
std::string leaf = i->path().leaf();
205
Str const& leaf = i->path().leaf();
155
std::string leaf = i->path().filename();
207
Str const& leaf = i->path().filename();
157
if (leaf == ".." || leaf == ".") continue;
209
if (ignore_subdir(leaf)) continue;
158
210
add_files_impl(fs, p, l / leaf, pred);
163
fs.add_file(l, file_size(f));
215
int file_flags = get_file_attributes(f);
216
std::time_t mtime = get_file_mtime(f);
217
//Masking all bits to check if the file is a symlink
218
if(file_flags & file_storage::attribute_symlink)
220
fs::path sym_path = get_symlink_path(f);
221
fs.add_file(l, 0 ,file_flags, mtime, sym_path);
225
fs.add_file(l, file_size(f), file_flags, mtime);
168
233
template <class Pred>
169
234
void add_files(file_storage& fs, boost::filesystem::path const& file, Pred p)
236
using boost::filesystem::path;
171
237
boost::filesystem::path f = file;
172
238
#if BOOST_VERSION < 103600
173
239
if (f.leaf() == ".") f = f.branch_path();
174
detail::add_files_impl(fs, complete(f).branch_path(), f.leaf(), p);
240
detail::add_files_impl(fs, complete(f).branch_path(), path(f.leaf()), p);
176
242
if (f.filename() == ".") f = f.parent_path();
177
detail::add_files_impl(fs, complete(f).parent_path(), f.filename(), p);
243
detail::add_files_impl(fs, complete(f).parent_path(), path(f.filename()), p);
181
247
inline void add_files(file_storage& fs, boost::filesystem::path const& file)
249
using boost::filesystem::path;
183
250
boost::filesystem::path f = file;
184
251
#if BOOST_VERSION < 103600
185
252
if (f.leaf() == ".") f = f.branch_path();
186
detail::add_files_impl(fs, complete(f).branch_path(), f.leaf(), detail::default_pred);
253
detail::add_files_impl(fs, complete(f).branch_path(), path(f.leaf()), detail::default_pred);
188
255
if (f.filename() == ".") f = f.parent_path();
189
detail::add_files_impl(fs, complete(f).parent_path(), f.filename(), detail::default_pred);
256
detail::add_files_impl(fs, complete(f).parent_path(), path(f.filename()), detail::default_pred);
262
piece_holder(int bytes): m_piece(page_aligned_allocator::malloc(bytes)) {}
263
~piece_holder() { page_aligned_allocator::free(m_piece); }
264
char* bytes() { return m_piece; }
193
269
template <class Fun>
194
270
void set_piece_hashes(create_torrent& t, boost::filesystem::path const& p, Fun f
195
271
, error_code& ec)
201
277
// calculate the hash for all pieces
202
278
int num = t.num_pieces();
279
piece_holder buf(t.piece_length());
280
for (int i = 0; i < num; ++i)
282
// read hits the disk and will block. Progress should
283
// be updated in between reads
284
st->read(buf.bytes(), i, 0, t.piece_size(i));
290
hasher h(buf.bytes(), t.piece_size(i));
291
t.set_hash(i, h.final());
296
#ifndef BOOST_NO_EXCEPTIONS
298
void set_piece_hashes(create_torrent& t, boost::filesystem::path const& p, Fun f)
301
set_piece_hashes(t, p, f, ec);
302
if (ec) throw libtorrent_exception(ec);
305
inline void set_piece_hashes(create_torrent& t, boost::filesystem::path const& p)
308
set_piece_hashes(t, p, detail::nop, ec);
309
if (ec) throw libtorrent_exception(ec);
313
inline void set_piece_hashes(create_torrent& t, boost::filesystem::path const& p, error_code& ec)
315
set_piece_hashes(t, p, detail::nop, ec);
318
#if TORRENT_USE_WPATH
321
template <class Pred>
322
void add_files(file_storage& fs, boost::filesystem::wpath const& file, Pred p)
324
using boost::filesystem::wpath;
326
#if BOOST_VERSION < 103600
327
if (f.leaf() == L".") f = f.branch_path();
328
detail::add_files_impl(fs, complete(f).branch_path(), wpath(f.leaf()), p);
330
if (f.filename() == L".") f = f.parent_path();
331
detail::add_files_impl(fs, complete(f).parent_path(), wpath(f.filename()), p);
335
inline void add_files(file_storage& fs, boost::filesystem::wpath const& file)
337
using boost::filesystem::wpath;
339
#if BOOST_VERSION < 103600
340
if (f.leaf() == L".") f = f.branch_path();
341
detail::add_files_impl(fs, complete(f).branch_path(), wpath(f.leaf()), detail::wdefault_pred);
343
if (f.filename() == L".") f = f.parent_path();
344
detail::add_files_impl(fs, complete(f).parent_path(), wpath(f.filename()), detail::wdefault_pred);
349
void set_piece_hashes(create_torrent& t, boost::filesystem::wpath const& p, Fun f
354
wchar_utf8(p.string(), utf8);
355
boost::scoped_ptr<storage_interface> st(
356
default_storage_constructor(const_cast<file_storage&>(t.files()), 0, utf8, fp));
358
// calculate the hash for all pieces
359
int num = t.num_pieces();
203
360
std::vector<char> buf(t.piece_length());
204
361
for (int i = 0; i < num; ++i)