From 1232cd44cb6dc2ac54892a01a8eb7c429dd3553b Mon Sep 17 00:00:00 2001 From: rakshasa Date: Tue, 24 Jul 2007 23:12:42 +0000 Subject: [PATCH] * Properly catch exceptions from commands called from DownloadFactory. * The print command was not properly adding the final nul char to the buffer. * Added 'get_d_name' command. git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@944 e378c898-3ddf-0310-93e7-cc216c733640 --- src/command_download.cc | 3 ++- src/command_ui.cc | 2 +- src/core/download_factory.cc | 27 ++++++++++++++++++++++++++- src/core/download_list.cc | 5 +++++ src/core/download_list.h | 6 ++++++ src/main.cc | 5 ++++- src/rpc/command_scheduler.cc | 2 +- src/rpc/parse_commands.h | 5 +++++ 8 files changed, 50 insertions(+), 5 deletions(-) diff --git a/src/command_download.cc b/src/command_download.cc index e4cec1a0..a75d889a 100644 --- a/src/command_download.cc +++ b/src/command_download.cc @@ -264,8 +264,9 @@ add_copy_to_download(const char* src, const char* dest) { void initialize_command_download() { - ADD_CD_VOID("base_path", &retrieve_d_base_path); + ADD_CD_VOID("base_path", &retrieve_d_base_path); ADD_CD_VOID("base_filename", &retrieve_d_base_filename); + ADD_CD_STRING_UNI("name", rak::on(std::mem_fun(&core::Download::download), std::mem_fun(&torrent::Download::name))); ADD_CD_LIST("create_link", rak::bind_ptr_fn(&apply_d_change_link, 0)); ADD_CD_LIST("delete_link", rak::bind_ptr_fn(&apply_d_change_link, 1)); diff --git a/src/command_ui.cc b/src/command_ui.cc index f4d28eb6..8d1d9dbf 100644 --- a/src/command_ui.cc +++ b/src/command_ui.cc @@ -108,7 +108,7 @@ apply_print(const torrent::Object& rawArgs) { { int len = std::min(itr->as_string().size(), buffer + 1024 - current); - std::memcpy(current, itr->as_string().c_str(), len); + std::memcpy(current, itr->as_string().c_str(), len + 1); current += len; break; } diff --git a/src/core/download_factory.cc b/src/core/download_factory.cc index 4bcdafc8..26c04d7e 100644 --- a/src/core/download_factory.cc +++ b/src/core/download_factory.cc @@ -230,7 +230,32 @@ DownloadFactory::receive_success() { return; } - std::for_each(m_commands.begin(), m_commands.end(), rak::bind1st(std::ptr_fun(&rpc::parse_command_d_multiple_std), download)); + // Save the info-hash just in case the commands decide to delete it. + torrent::HashString infohash = download->download()->info_hash(); + + try { + std::for_each(m_commands.begin(), m_commands.end(), rak::bind1st(std::ptr_fun(&rpc::parse_command_d_multiple_std), download)); + + if (m_manager->download_list()->find(infohash) == m_manager->download_list()->end()) + throw torrent::input_error("The newly created download was removed."); + + } catch (torrent::input_error& e) { + std::string msg = "Command on torrent creation failed: " + std::string(e.what()); + + if (m_printLog) { + m_manager->get_log_important().push_front(msg); + m_manager->get_log_complete().push_front(msg); + } + + if (m_manager->download_list()->find(infohash) != m_manager->download_list()->end()) { + // Should stop it, mark it bad. Perhaps even delete it? + download->set_hash_failed(true); + download->set_message(msg); + // m_manager->download_list()->erase(m_manager->download_list()->find(infohash.data())); + } + + return m_slotFinished(); + } // When a download scheduler is implemented, this is handled by the // above insertion into download list. diff --git a/src/core/download_list.cc b/src/core/download_list.cc index 9be7797d..c2c82b15 100644 --- a/src/core/download_list.cc +++ b/src/core/download_list.cc @@ -92,6 +92,11 @@ DownloadList::session_save() { std::for_each(begin(), end(), std::bind1st(std::mem_fun(&DownloadStore::save), control->core()->download_store())); } +DownloadList::iterator +DownloadList::find(const torrent::HashString& hash) { + return std::find_if(begin(), end(), rak::equal(hash, rak::on(std::mem_fun(&Download::download), std::mem_fun(&torrent::Download::info_hash)))); +} + DownloadList::iterator DownloadList::find_hex(const char* hash) { torrent::HashString key; diff --git a/src/core/download_list.h b/src/core/download_list.h index 4347f67c..72b56c4c 100644 --- a/src/core/download_list.h +++ b/src/core/download_list.h @@ -43,6 +43,10 @@ #include #include +namespace torrent { + class HashString; +} + namespace core { class Download; @@ -78,6 +82,8 @@ public: void session_save(); + iterator find(const torrent::HashString& hash); + iterator find_hex(const char* hash); Download* find_hex_ptr(const char* hash); diff --git a/src/main.cc b/src/main.cc index 9be0b8e5..6d4ab907 100644 --- a/src/main.cc +++ b/src/main.cc @@ -269,7 +269,10 @@ main(int argc, char** argv) { } catch (std::exception& e) { display::Canvas::cleanup(); - delete control; + + // Safe to delete here? Seem to cause problems if cleanup hasn't + // been called. + //delete control; std::cout << "rtorrent: " << e.what() << std::endl; return -1; diff --git a/src/rpc/command_scheduler.cc b/src/rpc/command_scheduler.cc index 8c6dc874..4affd07a 100644 --- a/src/rpc/command_scheduler.cc +++ b/src/rpc/command_scheduler.cc @@ -97,7 +97,7 @@ CommandScheduler::call_item(value_type item) { // removed. try { - rpc::parse_command_single_std(item->command()); + rpc::parse_command_multiple_std(item->command()); } catch (torrent::input_error& e) { if (m_slotErrorMessage.is_valid()) diff --git a/src/rpc/parse_commands.h b/src/rpc/parse_commands.h index 221f37d1..39f798b2 100644 --- a/src/rpc/parse_commands.h +++ b/src/rpc/parse_commands.h @@ -81,6 +81,11 @@ parse_command_d_single_std(core::Download* download, const std::string& cmd) { parse_command_d_single(download, cmd.c_str(), cmd.c_str() + cmd.size()); } +inline void +parse_command_multiple_std(const std::string& cmd) { + parse_command_multiple(NULL, cmd.c_str(), cmd.c_str() + cmd.size()); +} + inline torrent::Object call_command(const char* key, const torrent::Object& obj) { return commands.call_command(key, obj); } inline torrent::Object call_command_void(const char* key) { return commands.call_command(key, torrent::Object()); } inline std::string call_command_string(const char* key) { return commands.call_command(key, torrent::Object()).as_string(); }