* Added "close_low_diskspace" option that closes active downloads on

filesystems with less space left than what was passed as the
argument. Patch by Josef Drexler, public domain.


git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@703 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
rakshasa
2006-05-25 19:44:13 +00:00
parent aaaf5d9a5d
commit 932296ce52
9 changed files with 245 additions and 1 deletions
+1
View File
@@ -8,6 +8,7 @@ EXTRA_DIST= \
rak/algorithm.h \
rak/error_number.h \
rak/file_stat.h \
rak/fs_stat.h \
rak/functional.h \
rak/functional_fun.h \
rak/path.h \
+2
View File
@@ -20,6 +20,8 @@ TORRENT_OTFD()
TORRENT_WITHOUT_VARIABLE_FDSET()
TORRENT_WITHOUT_NCURSESW()
TORRENT_WITHOUT_STATVFS()
TORRENT_WITHOUT_STATFS()
PKG_CHECK_MODULES(STUFF, sigc++-2.0 libtorrent >= 0.9.0,
CXXFLAGS="$CXXFLAGS $STUFF_CFLAGS $CURL_CFLAGS";
+11
View File
@@ -575,6 +575,17 @@ the event will not trigger more than once.
</para></listitem>
</varlistentry>
<varlistentry>
<term>close_low_diskspace = <replaceable>space</replaceable></term>
<listitem><para>
Close any active torrents on filesystems with less than
<emphasis>space</emphasis> diskspace left. Use with
<emphasis>schedule</emphasis>.
</para></listitem>
</varlistentry>
<varlistentry>
<term>load = <replaceable>file</replaceable></term>
<term>load_start = <replaceable>file</replaceable></term>
+3
View File
@@ -26,6 +26,9 @@
#schedule = watch_directory,5,5,load_start=./watch/*.torrent
#schedule = untied_directory,5,5,stop_untied=
# Close torrents when diskspace is low.
#schedule = untied_directory,5,60,close_low_diskspace=100M
# The ip address reported to the tracker.
#ip = 127.0.0.1
#ip = rakshasa.no
+84
View File
@@ -0,0 +1,84 @@
// rak - Rakshasa's toolbox
// Copyright (C) 2005-2006, 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 <jaris@ifi.uio.no>
//
// Skomakerveien 33
// 3185 Skoppum, NORWAY
#ifndef RAK_FS_STAT_H
#define RAK_FS_STAT_H
#include <string>
#include <inttypes.h>
#include <rak/error_number.h>
#if HAVE_SYS_VFS_H
#include <sys/vfs.h>
#endif
#if HAVE_SYS_STATVFS_H
#include <sys/statvfs.h>
#endif
#if HAVE_SYS_STATFS_H
#include <sys/statfs.h>
#endif
#if HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#if HAVE_SYS_MOUNT_H
#include <sys/mount.h>
#endif
namespace rak {
class fs_stat {
public:
typedef FS_STAT_SIZE_TYPE blocksize_type;
typedef FS_STAT_COUNT_TYPE blockcount_type;
typedef FS_STAT_STRUCT fs_stat_type;
bool update(int fd) { return FS_STAT_FD; }
bool update(const char* fn) { return FS_STAT_FN; }
bool update(const std::string& filename) { return update(filename.c_str()); }
blocksize_type blocksize() { return m_stat.f_bsize; }
blockcount_type blocks_avail() { return m_stat.f_bavail; }
int64_t bytes_avail() { return (int64_t) m_stat.f_bsize * m_stat.f_bavail; }
private:
fs_stat_type m_stat;
};
}
#endif
+116
View File
@@ -201,3 +201,119 @@ AC_DEFUN([TORRENT_WITHOUT_NCURSESW], [
)
])
])
AC_DEFUN([TORRENT_CHECK_STATVFS], [
AC_CHECK_HEADERS(sys/vfs.h sys/statvfs.h sys/statfs.h)
AC_MSG_CHECKING(for statvfs)
AC_TRY_LINK(
[
#if HAVE_SYS_VFS_H
#include <sys/vfs.h>
#endif
#if HAVE_SYS_STATVFS_H
#include <sys/statvfs.h>
#endif
#if HAVE_SYS_STATFS_H
#include <sys/statfs.h>
#endif
],[
struct statvfs s; fsblkcnt_t c;
statvfs("", &s);
fstatvfs(0, &s);
],
[
AC_DEFINE(FS_STAT_FD, [fstatvfs(fd, &m_stat) == 0], Function to determine filesystem stats from fd)
AC_DEFINE(FS_STAT_FN, [statvfs(fn, &m_stat) == 0], Function to determine filesystem stats from filename)
AC_DEFINE(FS_STAT_STRUCT, [struct statvfs], Type of second argument to statfs function)
AC_DEFINE(FS_STAT_SIZE_TYPE, [unsigned long], Type of block size member in stat struct)
AC_DEFINE(FS_STAT_COUNT_TYPE, [fsblkcnt_t], Type of block count member in stat struct)
AC_MSG_RESULT(ok)
have_stat_vfs=yes
],
[
AC_MSG_RESULT(no)
have_stat_vfs=no
])
])
AC_DEFUN([TORRENT_CHECK_STATFS], [
AC_CHECK_HEADERS(sys/statfs.h sys/param.h sys/mount.h)
AC_MSG_CHECKING(for statfs)
AC_TRY_LINK(
[
#if HAVE_SYS_STATFS_H
#include <sys/statfs.h>
#endif
#if HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#if HAVE_SYS_MOUNT_H
#include <sys/mount.h>
#endif
],[
struct statfs s;
statfs("", &s);
fstatfs(0, &s);
],
[
AC_DEFINE(FS_STAT_FD, [fstatfs(fd, &m_stat) == 0], Function to determine filesystem stats from fd)
AC_DEFINE(FS_STAT_FN, [statfs(fn, &m_stat) == 0], Function to determine filesystem stats from filename)
AC_DEFINE(FS_STAT_STRUCT, [struct statfs], Type of second argument to statfs function)
AC_DEFINE(FS_STAT_SIZE_TYPE, [long], Type of block size member in stat struct)
AC_DEFINE(FS_STAT_COUNT_TYPE, [long], Type of block count member in stat struct)
AC_MSG_RESULT(ok)
],
[
AC_MSG_RESULT(no)
])
])
AC_DEFUN([TORRENT_DISABLED_STATFS], [
AC_DEFINE(FS_STAT_FD, [(errno = ENOSYS) == 0], Function to determine filesystem stats from fd)
AC_DEFINE(FS_STAT_FN, [(errno = ENOSYS) == 0], Function to determine filesystem stats from filename)
AC_DEFINE(FS_STAT_STRUCT, [struct {blocksize_type f_bsize; blockcount_type f_bavail;}], Type of second argument to statfs function)
AC_DEFINE(FS_STAT_SIZE_TYPE, [int], Type of block size member in stat struct)
AC_DEFINE(FS_STAT_COUNT_TYPE, [int], Type of block count member in stat struct)
AC_MSG_RESULT(No filesystem stats available)
])
AC_DEFUN([TORRENT_WITHOUT_STATVFS], [
AC_ARG_WITH(statvfs,
[ --without-statvfs Don't try to use statvfs to find free diskspace.],
[
if test "$withval" = "yes"; then
TORRENT_CHECK_STATVFS
else
have_stat_vfs=no
fi
],
[
TORRENT_CHECK_STATVFS
])
])
AC_DEFUN([TORRENT_WITHOUT_STATFS], [
AC_ARG_WITH(statfs,
[ --without-statfs Don't try to use statfs to find free diskspace.],
[
if test "$have_stat_vfs" = "no"; then
if test "$withval" = "yes"; then
TORRENT_CHECK_STATFS
else
TORRENT_DISABLED_STATFS
fi
fi
],
[
if test "$have_stat_vfs" = "no"; then
TORRENT_CHECK_STATFS
if test "$have_stat_vfs" = "no"; then
TORRENT_DISABLED_STATFS
fi
fi
])
])
+1
View File
@@ -66,6 +66,7 @@ public:
bool is_open() const { return m_download.is_open(); }
bool is_active() const { return m_download.is_active(); }
bool is_done() const { return m_download.chunks_done() == m_download.chunks_total(); }
bool is_downloading() const { return is_active() && !is_done(); }
// FIXME: Fixed a bug in libtorrent that caused is_hash_checked to
// return true when the torrent is closed. Remove this redundant
+26
View File
@@ -41,12 +41,15 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <rak/file_stat.h>
#include <rak/fs_stat.h>
#include <rak/functional.h>
#include <rak/path.h>
#include <rak/string_manip.h>
#include <torrent/object.h>
#include <torrent/connection_manager.h>
#include <torrent/exceptions.h>
#include <torrent/file.h>
#include <torrent/path.h>
#include <torrent/torrent.h>
#include <torrent/tracker.h>
#include <torrent/tracker_list.h>
@@ -156,6 +159,28 @@ apply_remove_untied(Control* m) {
}
}
void
apply_close_low_diskspace(Control* m, int64_t arg) {
core::Manager::DListItr itr = m->core()->download_list()->begin();
while ((itr = std::find_if(itr, m->core()->download_list()->end(),
rak::equal(true, std::mem_fun(&core::Download::is_downloading))))
!= m->core()->download_list()->end()) {
rak::fs_stat stat;
std::string path = (*itr)->file_list()->root_dir() + (*itr)->file_list()->get(0).path()->as_string();
if (!stat.update(path)) {
m->core()->push_log(std::string("Cannot read free diskspace: ") + strerror(errno) + " for " + path);
} else if (stat.bytes_avail() < arg) {
m->core()->download_list()->close(*itr);
(*itr)->set_message(std::string("Low diskspace"));
}
++itr;
}
}
void
apply_encoding_list(__UNUSED Control* m, const std::string& arg) {
torrent::encoding_list()->push_back(arg);
@@ -407,6 +432,7 @@ initialize_option_handler(Control* c) {
variables->insert("stop_untied", new utils::VariableVoidSlot(rak::bind_ptr_fn(&apply_stop_untied, c)));
variables->insert("close_untied", new utils::VariableVoidSlot(rak::bind_ptr_fn(&apply_close_untied, c)));
variables->insert("remove_untied", new utils::VariableVoidSlot(rak::bind_ptr_fn(&apply_remove_untied, c)));
variables->insert("close_low_diskspace", new utils::VariableValueSlot(rak::value_fn(int64_t()), rak::bind_ptr_fn(&apply_close_low_diskspace, c)));
variables->insert("enable_trackers", new utils::VariableStringSlot(rak::value_fn(std::string()), rak::bind_ptr_fn(&apply_enable_trackers, c)));
variables->insert("encoding_list", new utils::VariableStringSlot(rak::value_fn(std::string()), rak::bind_ptr_fn(&apply_encoding_list, c)));
+1 -1
View File
@@ -175,7 +175,7 @@ bool
VariableMap::process_file(const std::string& path) {
std::fstream file(rak::path_expand(path).c_str(), std::ios::in);
if (!file.good())
if (!file.is_open())
return false;
int lineNumber = 0;