mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-08-17 07:32:32 +00:00
* 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:
@@ -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 \
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
])
|
||||
])
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)));
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user