mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-08-14 22:22:31 +00:00
* Added "working_directory" option that calls chdir.
* Added "session_on_completion" option which saves the session torrent when a download finishes. * Handle SIGTERM gracefully, saving session torrents etc. * Implemented session directory lockfile, use "session_lock" option to disable. git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@629 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
@@ -99,7 +99,7 @@ DownloadFactory::receive_load() {
|
||||
if (std::strncmp(m_uri.c_str(), "http://", 7) == 0) {
|
||||
// Http handling here.
|
||||
m_stream = new std::stringstream;
|
||||
HttpQueue::iterator itr = m_manager->get_http_queue().insert(m_uri, m_stream);
|
||||
HttpQueue::iterator itr = m_manager->http_queue().insert(m_uri, m_stream);
|
||||
|
||||
(*itr)->signal_done().slots().push_front(sigc::mem_fun(*this, &DownloadFactory::receive_loaded));
|
||||
(*itr)->signal_failed().slots().push_front(sigc::mem_fun(*this, &DownloadFactory::receive_failed));
|
||||
@@ -139,7 +139,7 @@ DownloadFactory::receive_success() {
|
||||
|
||||
Manager::DListItr itr = m_manager->insert(m_stream, m_printLog);
|
||||
|
||||
if (itr == m_manager->get_download_list().end()) {
|
||||
if (itr == m_manager->download_list().end()) {
|
||||
// core::Manager should already have added the error message to
|
||||
// the log.
|
||||
m_slotFinished();
|
||||
@@ -206,7 +206,7 @@ DownloadFactory::receive_success() {
|
||||
if (m_start)
|
||||
m_manager->start(*itr, m_printLog);
|
||||
|
||||
m_manager->get_download_store().save(*itr);
|
||||
m_manager->download_store().save(*itr);
|
||||
}
|
||||
|
||||
m_slotFinished();
|
||||
|
||||
@@ -52,16 +52,44 @@
|
||||
namespace core {
|
||||
|
||||
void
|
||||
DownloadStore::use(const std::string& path) {
|
||||
m_path = path;
|
||||
DownloadStore::enable(bool lock) {
|
||||
if (is_enabled())
|
||||
throw torrent::input_error("Session directory already enabled.");
|
||||
|
||||
if (!m_path.empty() && *m_path.rbegin() != '/')
|
||||
m_path += '/';
|
||||
if (m_path.empty())
|
||||
return;
|
||||
|
||||
if (lock)
|
||||
m_lockfile.set_path(m_path + "rtorrent.lock");
|
||||
else
|
||||
m_lockfile.set_path(std::string());
|
||||
|
||||
if (!m_lockfile.try_lock())
|
||||
throw torrent::input_error("Could not lock session directory: \"" + m_path + "\".");
|
||||
}
|
||||
|
||||
void
|
||||
DownloadStore::disable() {
|
||||
if (!is_enabled())
|
||||
return;
|
||||
|
||||
m_lockfile.unlock();
|
||||
}
|
||||
|
||||
void
|
||||
DownloadStore::set_path(const std::string& path) {
|
||||
if (is_enabled())
|
||||
throw torrent::input_error("Tried to change session directory while it is enabled.");
|
||||
|
||||
if (!path.empty() && *path.rbegin() != '/')
|
||||
m_path = path + '/';
|
||||
else
|
||||
m_path = path;
|
||||
}
|
||||
|
||||
void
|
||||
DownloadStore::save(Download* d) {
|
||||
if (!is_active())
|
||||
if (!is_enabled())
|
||||
return;
|
||||
|
||||
std::fstream f((create_filename(d) + ".new").c_str(), std::ios::out | std::ios::trunc);
|
||||
@@ -92,7 +120,7 @@ DownloadStore::save(Download* d) {
|
||||
|
||||
void
|
||||
DownloadStore::remove(Download* d) {
|
||||
if (!is_active())
|
||||
if (!is_enabled())
|
||||
return;
|
||||
|
||||
::unlink(create_filename(d).c_str());
|
||||
@@ -100,7 +128,7 @@ DownloadStore::remove(Download* d) {
|
||||
|
||||
utils::Directory
|
||||
DownloadStore::get_formated_entries() {
|
||||
if (!is_active())
|
||||
if (!is_enabled())
|
||||
return utils::Directory();
|
||||
|
||||
utils::Directory d(m_path);
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "utils/directory.h"
|
||||
#include "utils/lockfile.h"
|
||||
|
||||
namespace core {
|
||||
|
||||
@@ -48,22 +49,26 @@ class Download;
|
||||
class DownloadStore {
|
||||
public:
|
||||
|
||||
// Disable by passing an empty string.
|
||||
void use(const std::string& path);
|
||||
bool is_enabled() { return m_lockfile.is_locked(); }
|
||||
|
||||
bool is_active() { return !m_path.empty(); }
|
||||
void enable(bool lock);
|
||||
void disable();
|
||||
|
||||
void save(Download* d);
|
||||
void remove(Download* d);
|
||||
const std::string& path() const { return m_path; }
|
||||
void set_path(const std::string& path);
|
||||
|
||||
void save(Download* d);
|
||||
void remove(Download* d);
|
||||
|
||||
// Currently shows all entries in the correct format.
|
||||
utils::Directory get_formated_entries();
|
||||
utils::Directory get_formated_entries();
|
||||
|
||||
private:
|
||||
static bool is_correct_format(std::string f);
|
||||
std::string create_filename(Download* d);
|
||||
static bool is_correct_format(std::string f);
|
||||
std::string create_filename(Download* d);
|
||||
|
||||
std::string m_path;
|
||||
std::string m_path;
|
||||
utils::Lockfile m_lockfile;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
+6
-5
@@ -107,6 +107,7 @@ Manager::initialize_first() {
|
||||
torrent::initialize(m_pollManager->get_torrent_poll());
|
||||
}
|
||||
|
||||
// Most of this should be possible to move out.
|
||||
void
|
||||
Manager::initialize_second() {
|
||||
torrent::Http::set_factory(m_pollManager->get_http_stack()->get_http_factory());
|
||||
@@ -116,11 +117,8 @@ Manager::initialize_second() {
|
||||
|
||||
// Register slots to be called when a download is inserted/erased,
|
||||
// opened or closed.
|
||||
// m_downloadList.slot_map_insert()["0_initialize_bencode"] = sigc::mem_fun(*this, &Manager::initialize_bencode);
|
||||
m_downloadList.slot_map_insert()["1_connect_network_log"] = sigc::bind(sigc::ptr_fun(&connect_signal_network_log), sigc::mem_fun(m_logComplete, &Log::push_front));
|
||||
// m_downloadList.slot_map_insert()["1_connect_tracker_log"] = sigc::bind(sigc::ptr_fun(&connect_signal_tracker_log), sigc::mem_fun(m_logComplete, &Log::push_front));
|
||||
m_downloadList.slot_map_insert()["1_connect_storage_log"] = sigc::bind(sigc::ptr_fun(&connect_signal_storage_log), sigc::mem_fun(m_logComplete, &Log::push_front));
|
||||
//m_downloadList.slot_map_insert()["1_enable_udp_trackers"] = sigc::bind(sigc::mem_fun(&core::Download::enable_udp_trackers), true);
|
||||
|
||||
m_downloadList.slot_map_erase()["1_hash_queue_remove"] = sigc::mem_fun(m_hashQueue, &HashQueue::remove);
|
||||
m_downloadList.slot_map_erase()["1_store_remove"] = sigc::mem_fun(m_downloadStore, &DownloadStore::remove);
|
||||
@@ -319,9 +317,12 @@ Manager::receive_download_done_hash_checked(Download* d) {
|
||||
if (!d->get_download().is_active())
|
||||
m_downloadList.start(d);
|
||||
|
||||
if (control->variables()->get_string("session_on_completion") == "yes")
|
||||
m_downloadStore.save(d);
|
||||
|
||||
// Don't send if we did a hash check and found incompelete chunks.
|
||||
//if (d->is_done())
|
||||
d->get_download().tracker_send_completed();
|
||||
if (d->is_done())
|
||||
d->get_download().tracker_send_completed();
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
+4
-4
@@ -60,10 +60,10 @@ public:
|
||||
|
||||
Manager();
|
||||
|
||||
DownloadList& get_download_list() { return m_downloadList; }
|
||||
DownloadStore& get_download_store() { return m_downloadStore; }
|
||||
HashQueue& get_hash_queue() { return m_hashQueue; }
|
||||
HttpQueue& get_http_queue() { return m_httpQueue; }
|
||||
DownloadList& download_list() { return m_downloadList; }
|
||||
DownloadStore& download_store() { return m_downloadStore; }
|
||||
HashQueue& hash_queue() { return m_hashQueue; }
|
||||
HttpQueue& http_queue() { return m_httpQueue; }
|
||||
|
||||
PollManager* get_poll_manager() { return m_pollManager; }
|
||||
Log& get_log_important() { return m_logImportant; }
|
||||
|
||||
Reference in New Issue
Block a user