diff --git a/src/Makefile.am b/src/Makefile.am index 1c4ccfef..b21edc62 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -17,7 +17,6 @@ libsub_root_a_SOURCES = \ core/http_queue.h \ core/manager.cc \ core/manager.h \ - core/range_map.h \ core/view.cc \ core/view.h \ core/view_manager.cc \ @@ -171,7 +170,6 @@ libsub_root_a_SOURCES = \ utils/functional.h \ utils/gzip.cc \ utils/gzip.h \ - utils/list_focus.h \ utils/lockfile.cc \ utils/lockfile.h \ utils/waitpid_queue.cc \ diff --git a/src/command_local.cc b/src/command_local.cc index ab73fe15..7bc71b61 100644 --- a/src/command_local.cc +++ b/src/command_local.cc @@ -77,54 +77,6 @@ group_insert(const torrent::Object::list_type& args) { return name; } -static const int file_print_use_space = 0x1; -static const int file_print_delim_space = 0x2; - -void -file_print_list(torrent::Object::list_const_iterator first, torrent::Object::list_const_iterator last, FILE* output, int flags) { - while (first != last) { - switch (first->type()) { - case torrent::Object::TYPE_STRING: - fprintf(output, (const char*)" %s" + !(flags & file_print_use_space), first->as_string().c_str()); - break; - case torrent::Object::TYPE_VALUE: - fprintf(output, (const char*)" %" PRIi64 + !(flags & file_print_use_space), first->as_value()); - break; - case torrent::Object::TYPE_LIST: - file_print_list(first->as_list().begin(), first->as_list().end(), output, 0); - break; - case torrent::Object::TYPE_NONE: - break; - default: - throw torrent::input_error("Invalid type."); - } - - flags |= (flags & file_print_delim_space) >> 1; - first++; - } -} - -torrent::Object -cmd_file_append(const torrent::Object::list_type& args) { - if (args.empty()) - throw torrent::input_error("Invalid number of arguments."); - - FILE* output = fopen(args.front().as_string().c_str(), "a"); - - if (output == nullptr) - throw torrent::input_error("Could not append to file '" + args.front().as_string() + "': " + std::strerror(errno)); - - try { - file_print_list(++args.begin(), args.end(), output, file_print_delim_space); - fprintf(output, "\n"); - } catch (...) { - fclose(output); - throw; - } - fclose(output); - return torrent::Object(); -} - void initialize_command_local() { core::DownloadList* dList = control->core()->download_list(); diff --git a/src/core/download_list.cc b/src/core/download_list.cc index 6006adb2..12b0e814 100644 --- a/src/core/download_list.cc +++ b/src/core/download_list.cc @@ -709,6 +709,10 @@ DownloadList::confirm_finished(Download* download) { if (choke_up.is_string_empty()) choke_up = rpc::call_command("protocol.choke_heuristics.up.seed", torrent::Object(), rpc::make_target(download)); if (choke_down.is_string_empty()) choke_down = rpc::call_command("protocol.choke_heuristics.down.seed", torrent::Object(), rpc::make_target(download)); + // libtorrent refuses initial seeding on an active download. + if (download->is_active() && conn_current.as_string() == "initial_seed") + conn_current = "seed"; + rpc::call_command("d.connection_current.set", conn_current, rpc::make_target(download)); rpc::call_command("d.up.choke_heuristics.set", choke_up, rpc::make_target(download)); rpc::call_command("d.down.choke_heuristics.set", choke_down, rpc::make_target(download)); diff --git a/src/core/manager.h b/src/core/manager.h index 942c4088..6d7b17e9 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -8,7 +8,6 @@ #include #include "download_list.h" -#include "range_map.h" namespace torrent { class Bencode; diff --git a/src/core/range_map.h b/src/core/range_map.h deleted file mode 100644 index c6cb0281..00000000 --- a/src/core/range_map.h +++ /dev/null @@ -1,199 +0,0 @@ -// rTorrent - BitTorrent client -// Copyright (C) 2005-2008, Jari Sundell -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell - - -#ifndef RTORRENT_CORE_RANGE_MAP_H -#define RTORRENT_CORE_RANGE_MAP_H - -#include -#include - -namespace core { - -// Associate values with a range of keys, and retrieve for any key in the range. - -// The template arguments have the same semantics as std::map. -// Exception: if set_merge is used, the value type must have a defined operator ==. -template, - typename Alloc = std::allocator > > -class RangeMap : private std::map, Compare, - typename std::allocator_traits::template rebind_alloc>>> { - - typedef std::map, Compare, - typename std::allocator_traits::template rebind_alloc>>> base_type; - - //std::allocator_traits::template rebind_alloc>> - -public: - RangeMap() = default; - RangeMap(const Compare& c) : base_type(c) {} - - typedef typename base_type::iterator iterator; - typedef typename base_type::reverse_iterator reverse_iterator; - typedef typename base_type::const_iterator const_iterator; - typedef typename base_type::const_reverse_iterator const_reverse_iterator; - - // using typename base_type::const_iterator; - // using typename base_type::const_reverse_iterator; - - using base_type::clear; - using base_type::swap; - - using base_type::size; - using base_type::empty; - - using base_type::begin; - using base_type::end; - using base_type::rbegin; - using base_type::rend; - - using base_type::key_comp; - using base_type::value_comp; - - // Store a value for the range [begin, end). Returns iterator for the range. - const_iterator set_range(const Key& begin, const Key& end, const T& value); - - // Same, but merge adjacent ranges having the same value. Returns iterator for the merged range. - const_iterator set_merge(Key begin, const Key& end, const T& value); - - // Find range containing the given key, or end(). - const_iterator find(const Key& key) const; - - // Retrieve value for key in a range, throw std::out_of_range if range does not exist. - const T& get(const Key& key) const; - - // Retrieve value for key in a range, return def if range does not exist. - T get(const Key& key, T def) const; - -private: - iterator crop_overlap(const Key& begin, const Key& end); -}; - -// Semantics of an entry: -// .first End of range (exclusive), map key. -// .second.first Beginning of range. -// .second.second Value. - -template -inline typename RangeMap::iterator -RangeMap::crop_overlap(const Key& _begin, const Key& _end) { - typename RangeMap::iterator itr = base_type::upper_bound(_begin); - - while (itr != end() && key_comp()(itr->second.first, _end)) { - // There's a subrange before the new begin: need new entry (new range end means new key). - if (key_comp()(itr->second.first, _begin)) - base_type::insert(itr, typename RangeMap::value_type(_begin, itr->second)); - - // Old end is within our range: erase entry. - if (!key_comp()(_end, itr->first)) { - base_type::erase(itr++); - - // Otherwise simply set the new begin of the old range. - } else { - itr->second.first = _end; - ++itr; - } - } - - return itr; -} - -template -inline typename RangeMap::const_iterator -RangeMap::set_merge(Key _begin, const Key& _end, const T& value) { - if (!key_comp()(_begin, _end)) - return end(); - - // Crop overlapping ranges and return iterator to first range after the one we're inserting. - typename RangeMap::iterator itr = crop_overlap(_begin, _end); - - // Check if range before new one is adjacent and has same value: if so erase it and use its beginning. - if (itr != begin()) { - typename RangeMap::iterator prev = itr; - if (!key_comp()((--prev)->first, _begin) && prev->second.second == value) { - _begin = prev->second.first; - base_type::erase(prev); - } - } - - // Range after new one is adjacent and has same value: set new beginning. - if (itr != end() && !key_comp()(_end, itr->second.first) && itr->second.second == value) { - itr->second.first = _begin; - return itr; - } - - // Otherwise, this range isn't mergeable, make new entry. - return base_type::insert(itr, typename RangeMap::value_type(_end, typename RangeMap::mapped_type(_begin, value))); -} - -template -inline typename RangeMap::const_iterator -RangeMap::set_range(const Key& _begin, const Key& _end, const T& value) { - if (!key_comp()(_begin, _end)) - return end(); - - return base_type::insert(crop_overlap(_begin, _end), typename RangeMap::value_type(_end, typename RangeMap::mapped_type(_begin, value))); -} - -template -inline typename RangeMap::const_iterator -RangeMap::find(const Key& key) const { - typename RangeMap::const_iterator itr = base_type::upper_bound(key); - - if (itr != end() && key_comp()(key, itr->second.first)) - itr = end(); - - return itr; -} - -template -inline const T& -RangeMap::get(const Key& key) const { - typename RangeMap::const_iterator itr = find(key); - - if (itr == end()) - throw std::out_of_range("RangeMap::get"); - - return itr->second.second; -} - -template -inline T -RangeMap::get(const Key& key, T def) const { - typename RangeMap::const_iterator itr = find(key); - return (itr == end() ? def : itr->second.second); -} - -} - -#endif diff --git a/src/display/utils.h b/src/display/utils.h index 69d89281..2180a89f 100644 --- a/src/display/utils.h +++ b/src/display/utils.h @@ -16,15 +16,12 @@ namespace utils { namespace torrent { class ClientInfo; - class Entry; } class Control; namespace display { -char* print_string(char* first, char* last, char* str); - char* print_hhmmss(char* first, char* last, time_t t); char* print_hhmmss_local(char* first, char* last, time_t t); char* print_ddhhmm(char* first, char* last, time_t t); @@ -42,9 +39,6 @@ char* print_download_percentage_done(char* first, char* last, core::Downlo char* print_client_version(char* first, char* last, const torrent::ClientInfo& clientInfo); -char* print_entry_tags(char* first, char* last); -char* print_entry_file(char* first, char* last, const torrent::Entry& entry); - char* print_status_throttle_limit(char* first, char* last, bool up, const std::vector& throttle_names); char* print_status_throttle_rate(char* first, char* last, bool up, const std::vector& throttle_names, const double& global_rate); diff --git a/src/display/window_download_chunks_seen.cc b/src/display/window_download_chunks_seen.cc index 88c74c7a..1ee75629 100644 --- a/src/display/window_download_chunks_seen.cc +++ b/src/display/window_download_chunks_seen.cc @@ -57,7 +57,8 @@ WindowDownloadChunksSeen::redraw() { const torrent::TransferList* transfers = m_download->download()->transfer_list(); std::vector transferChunks(transfers->begin(), transfers->end()); - std::sort(transferChunks.begin(), transferChunks.end()); + std::sort(transferChunks.begin(), transferChunks.end(), + [](const auto& left, const auto& right) { return left->index() < right->index(); }); std::vector::const_iterator itrTransfer = transferChunks.begin(); diff --git a/src/input/bindings.h b/src/input/bindings.h index f5080f32..54038e84 100644 --- a/src/input/bindings.h +++ b/src/input/bindings.h @@ -69,8 +69,6 @@ public: bool pressed(int key); - void ignore(int key) { (*this)[key] = slot_void(); } - private: bool m_enabled{true}; }; diff --git a/src/rpc/parse.cc b/src/rpc/parse.cc index e49dde66..9e8b4d58 100644 --- a/src/rpc/parse.cc +++ b/src/rpc/parse.cc @@ -161,7 +161,7 @@ parse_object(const char* first, const char* last, torrent::Object* dest, bool (* if (++depth >= max_parse_depth) throw torrent::input_error("Max parse depth reached."); - if (*first == '{') { + if (first != last && *first == '{') { *dest = torrent::Object::create_list(); first = parse_list(first + 1, last, dest, &parse_is_delim_block, depth); first = parse_skip_wspace(first, last); @@ -171,7 +171,7 @@ parse_object(const char* first, const char* last, torrent::Object* dest, bool (* return ++first; - } else if (*first == '(') { + } else if (first != last && *first == '(') { int32_t parentheses = 1; while (first + 1 != last && *(first + 1) == '(') { @@ -393,7 +393,7 @@ convert_to_value_nothrow(const torrent::Object& src, int64_t* value, int base, i == unpacked.as_string().c_str() + unpacked.as_string().size(); case torrent::Object::TYPE_RAW_STRING: { - const torrent::raw_string& str = src.as_raw_string(); + const torrent::raw_string& str = unpacked.as_raw_string(); auto buffer = std::make_unique(str.size() + 1); std::memcpy(buffer.get(), str.data(), str.size()); diff --git a/src/rpc/xmlrpc_c.cc b/src/rpc/xmlrpc_c.cc index b85142f4..b54b4542 100644 --- a/src/rpc/xmlrpc_c.cc +++ b/src/rpc/xmlrpc_c.cc @@ -440,6 +440,8 @@ XmlRpc::cleanup() { xmlrpc_registry_free((xmlrpc_registry*)m_registry); xmlrpc_env_clean((xmlrpc_env*)m_env); delete (xmlrpc_env*)m_env; + m_env = nullptr; + m_registry = nullptr; } bool diff --git a/src/signal_handler.cc b/src/signal_handler.cc index 3d5bbf27..66e89e5e 100644 --- a/src/signal_handler.cc +++ b/src/signal_handler.cc @@ -63,8 +63,10 @@ SignalHandler::set_block(unsigned int signum) { sigemptyset(&mask); sigaddset(&mask, signum); - if (pthread_sigmask(SIG_BLOCK, &mask, NULL) == -1) - throw std::logic_error("Could not block signal: " + std::string(std::strerror(errno))); + int result = pthread_sigmask(SIG_BLOCK, &mask, NULL); + + if (result != 0) + throw std::logic_error("Could not block signal: " + std::string(std::strerror(result))); } void @@ -77,8 +79,10 @@ SignalHandler::set_unblock(unsigned int signum) { sigemptyset(&mask); sigaddset(&mask, signum); - if (pthread_sigmask(SIG_UNBLOCK, &mask, NULL) == -1) - throw std::logic_error("Could not unblock signal: " + std::string(std::strerror(errno))); + int result = pthread_sigmask(SIG_UNBLOCK, &mask, NULL); + + if (result != 0) + throw std::logic_error("Could not unblock signal: " + std::string(std::strerror(result))); } void diff --git a/src/ui/download.h b/src/ui/download.h index bb7a39ed..fdfb7a10 100644 --- a/src/ui/download.h +++ b/src/ui/download.h @@ -6,7 +6,6 @@ #include #include "display/manager.h" -#include "utils/list_focus.h" #include "element_base.h" diff --git a/src/ui/element_menu.cc b/src/ui/element_menu.cc index b9a9ad8f..b27507fa 100644 --- a/src/ui/element_menu.cc +++ b/src/ui/element_menu.cc @@ -179,7 +179,7 @@ ElementMenu::set_entry(size_type idx, bool triggerSlot) { m_entry = idx; focus_entry(m_entry); - if (triggerSlot) + if (triggerSlot && m_entry < size()) base_type::operator[](m_entry).m_slotFocus(); m_window->mark_dirty(); diff --git a/src/utils/list_focus.h b/src/utils/list_focus.h deleted file mode 100644 index 068d1496..00000000 --- a/src/utils/list_focus.h +++ /dev/null @@ -1,158 +0,0 @@ -// rTorrent - BitTorrent client -// Copyright (C) 2005-2011, Jari Sundell -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell - - -#ifndef RTORRENT_UTILS_LIST_FOCUS_H -#define RTORRENT_UTILS_LIST_FOCUS_H - -#include -#include - -namespace utils { - -// Can't make this class inherit privately due to gcc PR 14258. - -template -class ListFocus { -public: - typedef Base base_type; - typedef std::function slot_void; - typedef std::list signal_void; - - typedef typename base_type::iterator iterator; - typedef typename base_type::const_iterator const_iterator; - typedef typename base_type::reverse_iterator reverse_iterator; - typedef typename base_type::const_reverse_iterator const_reverse_iterator; - - typedef typename base_type::value_type value_type; - - ListFocus(base_type* b = nullptr) : m_base(b) { if (b) m_focus = b->end(); } - - // Convinience functions, would have added more through using, but - // can't. - iterator begin() { return m_base->begin(); } - iterator end() { return m_base->end(); } - reverse_iterator rbegin() { return m_base->rbegin(); } - reverse_iterator rend() { return m_base->rend(); } - - // Don't do erase on this object without making sure focus is right. - base_type& base() { return *m_base; } - - iterator get_focus() { return m_focus; } - void set_focus(iterator itr); - - // These are looping increment/decrements. - iterator inc_focus(); - iterator dec_focus(); - - iterator erase(iterator itr); - void remove(const value_type& v); - - // Be careful with copying signals. - signal_void& signal_changed() { return m_signal_changed; } - -private: - void emit_changed(); - - base_type* m_base; - iterator m_focus; - - signal_void m_signal_changed; -}; - -template -void -ListFocus::set_focus(iterator itr) { - m_focus = itr; - emit_changed(); -} - -template -typename ListFocus::iterator -ListFocus::inc_focus() { - if (m_focus != end()) - ++m_focus; - else - m_focus = begin(); - - emit_changed(); - return m_focus; -} - -template -typename ListFocus::iterator -ListFocus::dec_focus() { - if (m_focus != begin()) - --m_focus; - else - m_focus = end(); - - emit_changed(); - return m_focus; -} - -template -typename ListFocus::iterator -ListFocus::erase(iterator itr) { - if (itr == m_focus) { - m_focus = m_base->erase(itr); - emit_changed(); - return m_focus; - } - - return m_base->erase(itr); -} - -template -void -ListFocus::remove(const value_type& v) { - iterator first = begin(); - iterator last = end(); - - while (first != last) - if (*first == v) - first = erase(first); - else - ++first; -} - -template -void -ListFocus::emit_changed() { - for (const auto& itr : m_signal_changed) - itr(); -} - -} - -#endif