*** empty log message ***

This commit is contained in:
Arvid Norberg 2005-06-16 15:41:04 +00:00
parent eca5300ebb
commit 0320e097d6
8 changed files with 158 additions and 44 deletions

View File

@ -103,33 +103,34 @@
<li><a class="reference" href="#invalid-request-alert" id="id83" name="id83">invalid_request_alert</a></li>
<li><a class="reference" href="#torrent-finished-alert" id="id84" name="id84">torrent_finished_alert</a></li>
<li><a class="reference" href="#metadata-received-alert" id="id85" name="id85">metadata_received_alert</a></li>
<li><a class="reference" href="#dispatcher" id="id86" name="id86">dispatcher</a></li>
<li><a class="reference" href="#fastresume-rejected-alert" id="id86" name="id86">fastresume_rejected_alert</a></li>
<li><a class="reference" href="#dispatcher" id="id87" name="id87">dispatcher</a></li>
</ul>
</li>
<li><a class="reference" href="#exceptions" id="id87" name="id87">exceptions</a><ul>
<li><a class="reference" href="#invalid-handle" id="id88" name="id88">invalid_handle</a></li>
<li><a class="reference" href="#duplicate-torrent" id="id89" name="id89">duplicate_torrent</a></li>
<li><a class="reference" href="#invalid-encoding" id="id90" name="id90">invalid_encoding</a></li>
<li><a class="reference" href="#type-error" id="id91" name="id91">type_error</a></li>
<li><a class="reference" href="#invalid-torrent-file" id="id92" name="id92">invalid_torrent_file</a></li>
<li><a class="reference" href="#exceptions" id="id88" name="id88">exceptions</a><ul>
<li><a class="reference" href="#invalid-handle" id="id89" name="id89">invalid_handle</a></li>
<li><a class="reference" href="#duplicate-torrent" id="id90" name="id90">duplicate_torrent</a></li>
<li><a class="reference" href="#invalid-encoding" id="id91" name="id91">invalid_encoding</a></li>
<li><a class="reference" href="#type-error" id="id92" name="id92">type_error</a></li>
<li><a class="reference" href="#invalid-torrent-file" id="id93" name="id93">invalid_torrent_file</a></li>
</ul>
</li>
<li><a class="reference" href="#examples" id="id93" name="id93">examples</a><ul>
<li><a class="reference" href="#dump-torrent" id="id94" name="id94">dump_torrent</a></li>
<li><a class="reference" href="#simple-client" id="id95" name="id95">simple client</a></li>
<li><a class="reference" href="#examples" id="id94" name="id94">examples</a><ul>
<li><a class="reference" href="#dump-torrent" id="id95" name="id95">dump_torrent</a></li>
<li><a class="reference" href="#simple-client" id="id96" name="id96">simple client</a></li>
</ul>
</li>
<li><a class="reference" href="#fast-resume" id="id96" name="id96">fast resume</a><ul>
<li><a class="reference" href="#file-format" id="id97" name="id97">file format</a></li>
<li><a class="reference" href="#fast-resume" id="id97" name="id97">fast resume</a><ul>
<li><a class="reference" href="#file-format" id="id98" name="id98">file format</a></li>
</ul>
</li>
<li><a class="reference" href="#extensions" id="id98" name="id98">extensions</a><ul>
<li><a class="reference" href="#chat-messages" id="id99" name="id99">chat messages</a></li>
<li><a class="reference" href="#metadata-from-peers" id="id100" name="id100">metadata from peers</a></li>
<li><a class="reference" href="#extensions" id="id99" name="id99">extensions</a><ul>
<li><a class="reference" href="#chat-messages" id="id100" name="id100">chat messages</a></li>
<li><a class="reference" href="#metadata-from-peers" id="id101" name="id101">metadata from peers</a></li>
</ul>
</li>
<li><a class="reference" href="#filename-checks" id="id101" name="id101">filename checks</a></li>
<li><a class="reference" href="#acknowledgements" id="id102" name="id102">acknowledgements</a></li>
<li><a class="reference" href="#filename-checks" id="id102" name="id102">filename checks</a></li>
<li><a class="reference" href="#acknowledgements" id="id103" name="id103">acknowledgements</a></li>
</ul>
</div>
<div class="section" id="introduction">
@ -886,9 +887,6 @@ struct torrent_handle
bool is_piece_filtered(int index) const;
std::vector&lt;bool&gt; filtered_pieces() const;
int num_complete() const;
int num_incomplete() const;
bool has_metadata() const;
boost::filsystem::path save_path() const;
@ -1980,6 +1978,23 @@ struct metadata_received_alert: alert
torrent_handle handle;
};
</pre>
</div>
<div class="section" id="fastresume-rejected-alert">
<h2><a name="fastresume-rejected-alert">fastresume_rejected_alert</a></h2>
<p>This alert is generated when a fastresume file has been passed to <tt class="docutils literal"><span class="pre">add_torrent</span></tt> but the
files on disk did not match the fastresume file. The string explaints the reason why the
resume file was rejected. It is generated at severity level <tt class="docutils literal"><span class="pre">warning</span></tt>.</p>
<pre class="literal-block">
struct fastresume_rejected_alert: alert
{
fastresume_rejected_alert(torrent_handle const&amp; h
, std::string const&amp; msg);
virtual std::auto_ptr&lt;alert&gt; clone() const;
torrent_handle handle;
};
</pre>
<!-- chat_message_alert
- - - - - - - - - - - - - - - - - -

View File

@ -816,9 +816,6 @@ Its declaration looks like this::
bool is_piece_filtered(int index) const;
std::vector<bool> filtered_pieces() const;
int num_complete() const;
int num_incomplete() const;
bool has_metadata() const;
boost::filsystem::path save_path() const;
@ -2014,6 +2011,26 @@ It is generated at severity level ``info``.
};
fastresume_rejected_alert
-------------------------
This alert is generated when a fastresume file has been passed to ``add_torrent`` but the
files on disk did not match the fastresume file. The string explaints the reason why the
resume file was rejected. It is generated at severity level ``warning``.
::
struct fastresume_rejected_alert: alert
{
fastresume_rejected_alert(torrent_handle const& h
, std::string const& msg);
virtual std::auto_ptr<alert> clone() const;
torrent_handle handle;
};
.. chat_message_alert
------------------

View File

@ -523,8 +523,7 @@ int main(int argc, char* argv[])
{
i->get_download_queue(queue);
for (std::vector<partial_piece_info>::iterator i = queue.begin();
i != queue.end();
++i)
i != queue.end(); ++i)
{
out.width(4);
out.fill(' ');

View File

@ -232,6 +232,21 @@ namespace libtorrent
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new listen_failed_alert(*this)); }
};
struct fastresume_rejected_alert: alert
{
fastresume_rejected_alert(torrent_handle const& h
, std::string const& msg)
: alert(alert::warning, msg)
, handle(h)
{}
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new fastresume_rejected_alert(*this)); }
torrent_handle handle;
};
}

View File

@ -115,7 +115,8 @@ namespace libtorrent
void parse_resume_data(
const entry& rd
, const torrent_info& info);
, const torrent_info& info
, std::string& error);
std::vector<int> piece_map;
std::vector<piece_picker::downloading_piece> unfinished_pieces;

View File

@ -68,7 +68,8 @@ namespace libtorrent
bool match_filesizes(
torrent_info const& t
, boost::filesystem::path p
, std::vector<std::pair<size_type, std::time_t> > const& sizes);
, std::vector<std::pair<size_type, std::time_t> > const& sizes
, std::string* error = 0);
struct file_allocation_failed: std::exception
{

View File

@ -127,7 +127,8 @@ namespace libtorrent { namespace detail
try
{
assert(t != 0);
t->parse_resume_data(t->resume_data, t->torrent_ptr->torrent_file());
std::string error_msg;
t->parse_resume_data(t->resume_data, t->torrent_ptr->torrent_file(), error_msg);
// clear the resume data now that it has been used
// (the fast resume data is now parsed and stored in t)
@ -142,6 +143,15 @@ namespace libtorrent { namespace detail
continue;
}
boost::mutex::scoped_lock l2(m_ses.m_mutex);
if (!error_msg.empty() && m_ses.m_alerts.should_post(alert::warning))
{
m_ses.m_alerts.post_alert(fastresume_rejected_alert(
t->torrent_ptr->get_handle()
, error_msg));
}
m_ses.m_torrents.insert(std::make_pair(t->info_hash, t->torrent_ptr));
if (t->torrent_ptr->is_seed() && m_ses.m_alerts.should_post(alert::info))
{
@ -1188,7 +1198,8 @@ namespace libtorrent
void detail::piece_checker_data::parse_resume_data(
const entry& resume_data
, const torrent_info& info)
, const torrent_info& info
, std::string& error)
{
// if we don't have any resume data, return
if (resume_data.type() == entry::undefined_t) return;
@ -1198,16 +1209,26 @@ namespace libtorrent
try
{
if (rd["file-format"].string() != "libtorrent resume file")
{
error = "missing file format tag";
return;
}
if (rd["file-version"].integer() != 1)
if (rd["file-version"].integer() > 1)
{
error = "incompatible file version "
+ boost::lexical_cast<std::string>(rd["file-version"].integer());
return;
}
// verify info_hash
const std::string &hash = rd["info-hash"].string();
std::string real_hash((char*)info.info_hash().begin(), (char*)info.info_hash().end());
if (hash != real_hash)
{
error = "mismatching info-hash: " + hash;
return;
}
// the peers
@ -1218,8 +1239,7 @@ namespace libtorrent
std::vector<address> tmp_peers;
tmp_peers.reserve(peer_list.size());
for (entry::list_type::iterator i = peer_list.begin();
i != peer_list.end();
++i)
i != peer_list.end(); ++i)
{
address a(
(*i)["ip"].string().c_str()
@ -1233,24 +1253,32 @@ namespace libtorrent
// read piece map
const entry::list_type& slots = rd["slots"].list();
if ((int)slots.size() > info.num_pieces())
{
error = "file has more slots than torrent (" + boost::lexical_cast<std::string>(slots.size()) + ")";
return;
}
std::vector<int> tmp_pieces;
tmp_pieces.reserve(slots.size());
for (entry::list_type::const_iterator i = slots.begin();
i != slots.end();
++i)
i != slots.end(); ++i)
{
int index = (int)i->integer();
if (index >= info.num_pieces() || index < -2)
{
error = "too high index number in slot map (" + boost::lexical_cast<std::string>(index) + ")";
return;
}
tmp_pieces.push_back(index);
}
int num_blocks_per_piece = (int)rd["blocks per piece"].integer();
if (num_blocks_per_piece != info.piece_length() / torrent_ptr->block_size())
{
error = "invalid number of blocks per piece (" + boost::lexical_cast<std::string>(num_blocks_per_piece) + ")";
return;
}
// the unfinished pieces
@ -1259,19 +1287,25 @@ namespace libtorrent
std::vector<piece_picker::downloading_piece> tmp_unfinished;
tmp_unfinished.reserve(unfinished.size());
for (entry::list_type::iterator i = unfinished.begin();
i != unfinished.end();
++i)
i != unfinished.end(); ++i)
{
piece_picker::downloading_piece p;
p.index = (int)(*i)["piece"].integer();
if (p.index < 0 || p.index >= info.num_pieces())
{
error = "invalid piece index in unfinished piece list (" + boost::lexical_cast<std::string>(p.index) + ")";
return;
}
const std::string& bitmask = (*i)["bitmask"].string();
const int num_bitmask_bytes = std::max(num_blocks_per_piece / 8, 1);
if ((int)bitmask.size() != num_bitmask_bytes) return;
if ((int)bitmask.size() != num_bitmask_bytes)
{
error = "invalid size of bitmask (" + boost::lexical_cast<std::string>(bitmask.size()) + ")";
return;
}
for (int j = 0; j < num_bitmask_bytes; ++j)
{
unsigned char bits = bitmask[j];
@ -1291,6 +1325,8 @@ namespace libtorrent
{
// this piece is marked as unfinished
// but doesn't have any storage
error = "piece " + boost::lexical_cast<std::string>(p.index) + " is "
"marked as unfinished, but doesn't have any storage";
return;
}
@ -1306,7 +1342,10 @@ namespace libtorrent
// crc's didn't match, don't use the resume data
if (ad.integer() != adler)
{
error = "checksum mismatch on piece " + boost::lexical_cast<std::string>(p.index);
return;
}
tmp_unfinished.push_back(p);
}
@ -1329,7 +1368,11 @@ namespace libtorrent
, boost::bind(std::less<int>(), _1, 0)) == tmp_pieces.end())
{
if (info.num_files() != (int)file_sizes.size())
{
error = "the number of files does not match the torrent ("
+ boost::lexical_cast<std::string>(file_sizes.size()) + ")";
return;
}
std::vector<std::pair<size_type, std::time_t> >::iterator
fs = file_sizes.begin();
@ -1338,12 +1381,17 @@ namespace libtorrent
for (torrent_info::file_iterator i = info.begin_files()
, end(info.end_files()); i != end; ++i, ++fs)
{
if (i->size != fs->first) return;
if (i->size != fs->first)
{
error = "file size for '" + i->path.native_file_string() + "' was expected to be "
+ boost::lexical_cast<std::string>(i->size) + " bytes";
return;
}
}
}
if (!match_filesizes(info, save_path, file_sizes))
if (!match_filesizes(info, save_path, file_sizes, &error))
return;
piece_map.swap(tmp_pieces);

View File

@ -185,16 +185,20 @@ namespace libtorrent
bool match_filesizes(
torrent_info const& t
, path p
, std::vector<std::pair<size_type, std::time_t> > const& sizes)
, std::vector<std::pair<size_type, std::time_t> > const& sizes
, std::string* error)
{
if ((int)sizes.size() != t.num_files()) return false;
if ((int)sizes.size() != t.num_files())
{
if (error) *error = "mismatching number of files";
return false;
}
p = complete(p);
std::vector<std::pair<size_type, std::time_t> >::const_iterator s
= sizes.begin();
for (torrent_info::file_iterator i = t.begin_files();
i != t.end_files();
++i, ++s)
i != t.end_files(); ++i, ++s)
{
size_type size = 0;
std::time_t time = 0;
@ -205,8 +209,22 @@ namespace libtorrent
time = last_write_time(f);
}
catch (std::exception&) {}
if (size != s->first || time != s->second)
if (size != s->first)
{
if (error) *error = "filesize mismatch for file '"
+ i->path.native_file_string()
+ "', expected to be " + boost::lexical_cast<std::string>(s->first)
+ " bytes";
return false;
}
if (time != s->second)
{
if (error) *error = "timestamp mismatch for file '"
+ i->path.native_file_string()
+ "', expected to have modification date "
+ boost::lexical_cast<std::string>(s->second);
return false;
}
}
return true;
}