Installing rTorrent and hellanzb on CentOS5 64-bit VPS

Overview

The aim of this guide is to walk through the process of getting rTorrent and hellanzb working on a VPS running CentOS5 (64-bit version). ((I’m guessing the guide will still work for higher kernel versions in the 2.6 series, but experience has taught me to hedge my bets))

In the interests of the author’s sanity, It is assumed that the reader has some familiarity with Unix command-line operations, and that the reader knows what the various permissions octals mean in Unix.

Please read the TODO to see what still needs fixing.

Assumptions

  • Operating System is CentOS5 64-bit, kernel 2.6.1x series 1)
  • CentOS5 is running on a OpenVZ VPS.
  • gcc, make, automake and autoconf installed
  • A text editor you are comfortable with (nano ((nano is not installed by default)) is recommended) but you can always use vi if you are hardcore
  • Working FTP Server (ProFTPD is highly recommended)
  • Installing software while logged in as root does not strike you as heresy.
  • Patience – lots of it.

Installing rTorrent

The Easy Way

rTorrent’s dependency tree is fairly long and very specific on the minimum versions required. The core dependency list is as follows:

  • pkg-config
  • libsigc++
  • curl 7.19.2 or higher
  • xmlrpc-c

Reminder: The rest of this section assumes you will be executing the commands as root

pkg-config

The current version of pkg-config (at the time of writing this guide) is 0.23. You can check the version information on the pkg-config website while the actual source tarballs are in the release directory.

The following set of commands will install pkg-config:

 wget http://pkgconfig.freedesktop.org/releases/pkg-config-0.23.tar.gz
tar zxf pkg-config-0.23.tar.gz
cd pkg-config-0.23
./configure
make
make install

libsigc++

Make sure you have rpmforge in your list of repositories. See this section for instructions if you are not sure how to proceed. If you have rpmforge already installed, you need to execute the following command:
yum install libsigc++20 libsigc++20-devel
Now to check if everything went ok with the libsigc++ install. Open the file ld.so.conf
nano -w /etc/ld.so.conf
and add the following lines:

/usr/local/lib/
/usr/include/
/usr/lib64/
/usr/lib
/usr/local/include/

Save and exit. Now run the following commands:

/sbin/ldconfig
pkg-config --cflags --libs sigc++-2.0

If everything went well, you should see something similar to the output below:

[root@centos]# pkg-config --cflags --libs sigc++-2.0
-I/usr/local/include/sigc++-2.0 -I/usr/local/lib/sigc++-2.0/include -L/usr/local/lib -lsigc-2.0

curl

Older versions of curl have bugs with some advanced features that libtorrent uses (( http://libtorrent.rakshasa.no/wiki/LibTorrentKnownIssues#Inabilitytoconnecttotrackersorannouncestimeout )) . Hence, rtorrent requires curl 7.19.2 or higher to be installed. However, CentOS 5 only ships with 7.15.5 and there are no updates available on the standard repositories.The current version of curl (at the time of writing this guide) is 7.19.3. You can check the version information on the curl website while the actual source tarballs are available on the download page.

Installing curl is fairly standard:

wget http://curl.haxx.se/download/curl-7.19.3.tar.gz
tar zxf curl-7.19.3.tar.gz
cd curl-7.19.3
./configure
make
make install

The curl make process can take a very long time, so this might be a good time to go get yourself a sandwich. Once the install process finishes, we need to check if the libraries are visible to pkg-config:

/sbin/ldconfig
pkg-config --cflags --libs libcurl
You should see the following output after the pkg-config command listed above:
[root@centos]# pkg-config --cflags --libs libcurl
-I/usr/local/include -L/usr/local/lib -lcurl

Now we move to the most important dependency for rtorrent, XMLRPC-C.

XMLRPC-C

XMLRPC-C comes in 3 flavours: Super-Stable, Stable and Advanced. While the Super-Stable version is available as a regular tarball, it seems like getting that version to work reliably is a hit-and-miss affair ((http://libtorrent.rakshasa.no/ticket/1028)). We are instead going to build the Advanced version for use with rtorrent.

To get the Advanced version source files, we need to install the subversion client:

yum install subversion

Next, we need to install a missing dependency for XMLRPC-C ((http://fr.rpmfind.net/linux/RPM/fedora/updates/testing/7/i386/xmlrpc-c-1.06.25-1.fc7.i386.html)):

yum install libxml2-devel

Now, we start the XMLRPC-C build process:

REPOS=http://xmlrpc-c.svn.sourceforge.net/svnroot/xmlrpc-c/advanced
svn checkout $REPOS xmlrpc-c #This puts the source tree in a directory called xmlrpc-c in your current directory#
svn up
cd xmlrpc-c
./configure --disable-cplusplus
make
make install

The following command must execute without any errors:

[root@centos]# xmlrpc-c-config server-util --libs
-L/usr/local/lib -lxmlrpc_server -lxmlrpc -lxmlrpc_util -lxmlrpc_xmlparse -lxmlrpc_xmltok

Any errors at this stage means the rtorrent install will fail. Double-check that you have executed all the commands listed above starting from the section on installing curl.

Now that we have all the dependencies for rtorrent in place, it's time to get started with installing rtorrent.

libtorrent/rTorrent

The latest build of rTorrent has a lot of functionality for managing torrents automatically. Plus, wTorrent relies on the latest build of rTorrent for much of it's functionality.

Start by checking out the latest rTorrent build from the repository:

mkdir rtorrent-svn
cd rtorrent-svn
svn co svn://rakshasa.no/libtorrent/trunk
svn up
Next we install some dependencies for libtorrent to compile successfully:
yum install openssl-devel libidn-devel

Run the following commands to install libtorrent:

cd trunk
cd libtorrent
./autogen.sh
./configure
make
make install

Check if the libtorrent install took:

/sbin/ldconfig
pkg-config --cflags --libs libtorrent

You should see the following output after the pkg-config command listed above:
[root@centos]# pkg-config --cflags --libs libtorrent
-I/usr/local/include -L/usr/local/lib -ltorrent
If everything is in order, it's time to start the rTorrent install:

cd ../rtorrent
./autogen.sh
./configure --with-xmlrpc-c
make
make install

If everything executes without errors, congratulations! You have a working rTorrent install ready for use. Before you can start using rTorrent though, you need to setup the rTorrent configuration file.

Creating a basic .rtorrent.rc file

rTorrent looks a file called ”.rtorrent.rc” in the home directory of the user launching rTorrent. A sample .rtorrent.rc file is included below. A few things to note about this sample file:

  • Download/Upload speeds are set to unlimited (You may want to limit this to around 60-70% of your total VPS link speed)
  • Downloads are saved in ~/downloads
  • Make sure to point the session variable to a directory that exists.
  • rTorrent listens for XMLRPC connection on localhost, port 5000
# This is an example resource file for rTorrent. Copy to
# ~/.rtorrent.rc and enable/modify the options as needed. Remember to
# uncomment the options you wish to enable.

# Maximum and minimum number of peers to connect to per torrent.
#min_peers = 40
#max_peers = 100

# Same as above but for seeding completed torrents (-1 = same as downloading)
# Don't set this too high, otherwise you will be seeding very slowly.
min_peers_seed = 5
max_peers_seed = 15

# Maximum number of simultanious uploads per torrent.
# Don't set this too high, otherwise you will be seeding very slowly.
max_uploads = 10

# Global upload and download rate in KiB. "0" for unlimited.
# Change this based on the total bandwidth available for your VPS
download_rate = 0
upload_rate = 0

# Default directory to save the downloaded torrents.
# make sure the path exists!
directory = ~/downloads

# Default session directory. Make sure you don't run multiple instance
# of rtorrent using the same session directory.
# Absolute path used here to enable "stop" functionality in the rtorrent init.d script
session = /home/rt/sessions/

#exec log
execute_log = ~/rtorrentexec.log

# Close torrents when diskspace is low.
#schedule = low_diskspace,5,60,close_low_diskspace=100M

# Stop torrents when reaching upload ratio in percent,
# when also reaching total upload in bytes, or when
# reaching final upload ratio in percent.

# Enable the default ratio group.
ratio.enable=

# Change the limits, the defaults should be sufficient.
ratio.min.set=100
ratio.max.set=200
ratio.upload.set=20M

# The ip address the listening socket and outgoing connections is
# bound to.
#bind = 127.0.0.1
#bind = rakshasa.no

# Port range to use for listening.
port_range = 6890-6999

# Start opening ports at a random position within the port range.
#port_random = no

# Check hash for finished torrents. Might be usefull until the bug is
# fixed that causes lack of diskspace not to be properly reported.
#check_hash = no

# Set whetever the client should try to connect to UDP trackers.
#use_udp_trackers = yes

# Alternative calls to bind and ip that should handle dynamic ip's.
#schedule = ip_tick,0,1800,ip=rakshasa
#schedule = bind_tick,0,1800,bind=rakshasa

# Encryption options, set to none (default) or any combination of the following:
# allow_incoming, try_outgoing, require, require_RC4, enable_retry, prefer_plaintext
#
# The example value allows incoming encrypted connections, starts unencrypted
# outgoing connections but retries with encryption if they fail, preferring
# plaintext to RC4 encryption after the encrypted handshake
#
# encryption = allow_incoming,enable_retry,prefer_plaintext
encryption = allow_incoming,try_outgoing,enable_retry

# Enable DHT support for trackerless torrents or when all trackers are down.
# May be set to "disable" (completely disable DHT), "off" (do not start DHT),
# "auto" (start and stop DHT as needed), or "on" (start DHT immediately).
# The default is "off". For DHT to work, a session directory must be defined.
#
# dht = auto

# UDP port to use for DHT.
#
# dht_port = 6881

# Enable peer exchange (for torrents not marked private)
#
# peer_exchange = yes

#XMLRPC
scgi_port = localhost:5000

#umask
umask = 0022

#
# Do not modify the following parameters unless you know what you're doing.
#

# Hash read-ahead controls how many MB to request the kernel to read
# ahead. If the value is too low the disk may not be fully utilized,
# while if too high the kernel might not be able to keep the read
# pages in memory thus end up trashing.
#hash_read_ahead = 10

# Interval between attempts to check the hash, in milliseconds.
#hash_interval = 100

# Number of attempts to check the hash while using the mincore status,
# before forcing. Overworked systems might need lower values to get a
# decent hash checking rate.
#hash_max_tries = 10
Now that you have a .rtorrent.rc file setup, it's time to actually launch rTorrent.

Working with rTorrent

Launch rTorrent by running the following command:

/usr/local/bin/rtorrent

You should find yourself looking a fairly spartan window:

rtorrent-main

Let's start by loading a new torrent meta-file. Torrent meta-files can be loaded into rTorrent using the Backspace key. Auto-completion of directories using the Tab key and wildcards (example: *.torrent) is supported.

Once you have a torrent loaded, you can use the following list of commands to manage rTorrent:

CommandDescription
Ctrl+SStart download. Runs hash first unless already done.
Ctrl+DStop an active download, or remove a stopped download.
Ctrl+QInitiate shutdown
↑/ ↓Select item
Go back to the previous screen.
Switch to Download View.
LView log. Exit by pressing Space.

There is one problem with launching rTorrent from a regular shell window. Once you type in Ctrl+Q to exit from rTorrent, it shuts down completely, stopping all your in-progress torrents. The next section will deal with how to keep rTorrent running in the background as well as how to launch rTorrent on startup.

Running rTorrent as a Service

We will be using dtach to keep rTorrent running in the background ((The other option is screen, which is a better screen-multiplexer program but requires a lot more privileges to run)). To install dtach, execute the following command:

yum install dtach

Now you can launch rtorrent using dtach:

dtach -c /tmp/dtach-rtorrent rtorrent

Once rTorrent launches, press Ctrl+\. You will get the following message at the shell:

[root@centos]# dtach -c /tmp/dtach-rtorrent rtorrent
[detached]

You can verify that rTorrent is still running by running the following command:

[root@centos]# ls -l /tmp/dtach*
srw------- 1 root root 0 Apr 2 01:33 /tmp/dtach-rtorrent

To reconnect the rTorrent session in the background, type

dtach -a /tmp/dtach-rtorrent

In order to launch rTorrent at startup, we need to create an entry in the init.d folder as well as a configuration file that the init.d script can read.

These commands need to be executed while logged in as root

The configuration file can be created as follows:

touch /etc/rtorrent.init.conf
nano -w /etc/rtorrent.init.conf

Now copy and paste the following text into your rtorrent.init.conf file:

##Start Configuration##
#Do not put a space on either side of the equal signs e.g.
# user = user
# will not work

# system user to run as
user="rt"

# the full path to the filename where you store your rtorrent configuration
config="/home/rt/.rtorrent.rc"

# set of options to run with
options=""

# file to log to (makes for easier debugging if something goes wrong)
logfile="/home/rt/rtorrentInit.log"
Save and exit. If you want, you can get the file directly on your server as follows:
cd /etc
wget http://wiki.theaveragegeek.com/samples/rtorrent.init.conf
Make sure to also create the logfile
touch /home/rt/rtorrentInit.log
The next step is to create the entry in the init.d folder:
touch /etc/init.d/rtorrent
nano -w /etc/init.d/rtorrent
Add the following text to your rtorrent file in the init.d folder:
#!/bin/sh
#
#
#############
######
#############
# This script depends on dtach.
# Based on the script created by lostnihilist at http://libtorrent.rakshasa.no/attachment/wiki/RTorrentCommonTasks/rtorrentInit.sh
# Licensed under the GPLv2 by average_geek: contact_at_theaveragegeek_dot_com
##############
######
##############
#/etc/rc.d/init.d/rtorrent
# chkconfig: 235 80 30
# description: Run rtorrent as a Daemon service using dtach
# processname: rtorrent
# Source function library.
. /etc/rc.d/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
#VARIABLES#
. /etc/rtorrent.init.conf
PATH=/usr/bin:/usr/local/bin:/usr/local/sbin:/sbin:/bin:/usr/sbin
DESC="rtorrent via dtach"
NAME=rtorrent
DAEMON=$NAME
SCRIPTNAME=/etc/init.d/$NAME
RETVAL=0
lockfile=${LOCKFILE-/var/lock/subsys/rtorrent}

# Check that networking is up.
[ ${NETWORKING} = "no" ] && exit 0

#Functions
checkconfig() {
exists=0

for i in `echo "$PATH" | tr ':' '\n'` ; do
if [ -f $i/$NAME ] ; then
exists=1
appdir=$i
apppath=$i/$NAME
break
fi
done

if ! [ -x "$apppath" ] ; then
echo "cannot find executable rtorrent binary in PATH $appdir" | tee -a "$logfile" >&2
exit 3
fi

if [ $exists -eq 0 ] ; then
echo "cannot find rtorrent binary in PATH $PATH" | tee -a "$logfile" >&2
exit 3
fi

if ! [ -r "${config}" ] ; then
echo "cannot find readable config ${config}. check that it is there and permissions are appropriate" | tee -a "$logfile" >&2
exit 3
fi

session=`getsession "$config"`
if ! [ -d "${session}" ] ; then
echo "cannot find readable session directory ${session} from config ${config}. check permissions" | tee -a "$logfile" >&2
exit 3
fi
}

getsession() {

session=`awk '/^[[:space:]]*session[[:space:]]*=[[:space:]]*/{print($3)}' "$config"`
echo $session
}

start() {

daemon `su -c "dtach -n /tmp/dtach-"${DAEMON}" rtorrent ${options} 2>&1 1>/dev/null" ${user} | tee -a "$logfile" >&2`

RETVAL=$?
echo
[ $RETVAL -eq 0 ] && touch ${lockfile}

}

stop() {

killproc $NAME

RETVAL=$?
echo
[ $RETVAL -eq 0 ] && rm -f ${lockfile}

}
#End Functions
#Script

checkconfig

case "$1" in

start)
echo -n "Starting $DESC: $NAME"
start
;;

stop)
echo -n "Stopping $DESC: $NAME"
stop
;;

restart|force-reload)
echo -n "Restarting $DESC: $NAME"
stop
sleep 1
start
;;

*)
echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
exit 1
;;

esac

exit 0

Now we need to make the rtorrent file executable:

chmod 755 /etc/init.d/rtorrent

Next we add rTorrent to the list of startup services:

chkconfig --add rtorrent

Now you can start rTorrent using the following command:

/etc/init.d/rtorrent start

If there are no problems with your configuration file, you should see the following:

[root@centos]# /etc/init.d/rtorrent start
Starting rtorrent via dtach: rtorrent [ OK ]

Verify that rTorrent is running with the following command:

ls -l /tmp/dtach*

You should see the following:

[root@centos]# ls -l /tmp/dtach*
srw------- 1 root root 0 Apr 2 01:33 /tmp/dtach-rtorrent

Caveats

Unfortunately, launching rTorrent as a starup service this way comes with some limitations:

  • The startup script launches rTorrent through a couple of layers of redirection. This means that sometimes, rTorrent can fail to start but the startup script still says “Starting rtorrent via dtach: rtorrent [ OK ]”
  • Another problem is that if rTorrent finds any problems in the .rtorrent.rc file, it does not send the message to stderr but rather to stdout (i.e. on-screen)
  • So if you make a change to your .rtorrent.rc file you might want to check for any problems by launching rTorrent the usual way, i.e.,
    /usr/local/bin/rtorrent

    Installing hellanzb

    In case you are wondering what hellanzb is, it “is a Python application designed for *nix environments that retrieves nzb files and fully processes them. The goal being to make getting files from Usenet as hands-free as possible.”

    hellanzb's dependency list is deceptively simple:

    • Twisted
    • unrar/unzip
    • par2cmdline
    • pyOpenSSL (if you want to use SSL connections to your Usenet provider)

    The reality of course is a bit more complicated. Let's get started with Twisted.

    hellanzb dependencies

    hellanzb's core dependency is Twisted - a networking stack written in Python. Twisted in turn, relies on zope.interface and python headers. Let's start with the core python headers install:

    yum install python-devel

    While zope.interface is available as a simple tarball, I never managed to get the build to work. The only thing that did work was a default file that I located on a 3rd-party repository ((http://rpm.pbone.net/index.php3/stat/4/idpl/10370620/com/python-ZopeInterface-3.3.0-1.el5.pp.x86_64.rpm.html)) :

    wget ftp://ftp.pbone.net/mirror/ftp.pramberger.at/systems/linux/contrib/rhel5/x86_64/python-ZopeInterface-3.3.0-1.el5.pp.x86_64.rpm
    rpm -ivh python-ZopeInterface-3.3.0-1.el5.pp.x86_64.rpm

    Now we can get started with Twisted. The current version of Twisted (at the time of writing this article) is 8.2.0 . You can find the latest version info on the Twisted website, and a link to the source tarball is available on the home page as well. Installation is as follows:

    wget http://tmrc.mit.edu/mirror/twisted/Twisted/8.2/Twisted-8.2.0.tar.bz2#md5=c85f151999df3ecf04c49a781b4438d2
    tar jxf Twisted-8.2.0.tar.bz2
    cd Twisted-8.2.0/
    python setup.py install --install-lib /usr/lib/python2.4/site-packages

    The odd install path for Twisted is due to a bug in the way Python packages get installed on 64-bit OS'es. See this bug report.

    The next set of dependencies for hellanzb are for unrar/unzip. If you have been using the instructions listed in this article on how to install rTorrent, you should have the rpmforge repository installed. The only thing left to do is to execute the following command:

    yum install unrar unzip

    Now we move par2cmdline. In case you are wondering what this program does, you should read this article on PAR files. The latest version of the par2cmdline client for UNIX (at the time of writing this article) is 0.3. You can download the source tarball from the clients section of the parchive website.

    Unfortunately, a bug in gcc 4.x.x prevents par2cmdline from compiling properly unless a patch is applied ((http://slackbuilds.org/repository/12.2/system/par2cmdline/)) . The complete process for building par2cmdline goes like this:

    wget http://prdownloads.sourceforge.net/parchive/par2cmdline-0.3.tar.gz?download
    tar zxf par2cmdline-0.3.tar.gz
    cd par2cmdline-0.3/
    wget http://slackbuilds.org/slackbuilds/12.2/system/par2cmdline/par2cmdline-0.4-gcc4.patch
    yum install patch
    patch reedsolomon.cpp par2cmdline-0.4-gcc4.patch
    ./configure
    make
    make install

    Optional:Finally, we install PyOpenSSL:

    yum install PyOpenSSL

    Building hellanzb

    At the time of writing this article, the latest version of hellanzb was 0.13. You can check the version info on hellanzb's website while the actual source tarballs are available in the distfiles folder. You could be adventurous and try the nightly builds in the distfiles folder, but the stable version works well enough.

    wget http://www.hellanzb.com/distfiles/hellanzb-0.13.tar.gz
    tar zxf hellanzb-0.13.tar.gz
    cd hellanzb-0.13
    python setup.py install

    If everything went well, you have a working hellanzb install. Now it's time to configure hellanzb.

    Creating a hellanzb.conf file

    hellanzb looks for a configuration file called “hellanzb.conf” in the /usr/etc folder. A sample hellanzb.conf file is given below. You should note the following about this sample conf file:

    • Download speeds are set to 150kB/s (You may want to limit this to around 30% of your total VPS link speed) ((hellanzb 0.13 has a problem with speed limits due to a bug in the underlying twisted network stack))
    • Finished Downloads are saved in /home/nzb/downloads/completed_files
    • hellanzb listens for XMLRPC connection on localhost, port 8760
    #
    # hellanzb.conf - sample hellanzb configuration file
    #
    # To quickly get started, change the default defineServer() call and the
    # Hellanzb.PREFIX_DIR directory
    #
    # This is actually interpreted python code: strings must be surrounded by
    # quotes, numbers and the 'None' keyword should not
    #
    # $Id: hellanzb.conf.sample 1057 2007-03-27 04:13:53Z pjenvey $
    
    # Log output to this file, set to None (no single quotes) for no logging
    Hellanzb.LOG_FILE = '/var/tmp/hellanzb.log'
    
    # Uncomment this line to log DEBUG messages to the specified file
    #Hellanzb.DEBUG_MODE = '/var/tmp/hellanzb-debug.log'
    
    # Automatically roll over both log files when they reach LOG_FILE_MAX_BYTES
    # size
    Hellanzb.LOG_FILE_MAX_BYTES = 131072
    
    # Save LOG_FILE_BACKUP_COUNT of those rolled over log files
    Hellanzb.LOG_FILE_BACKUP_COUNT = 0
    
    # Define server connections. Servers can have multiple hosts, hellanzb will
    # persist the number of connections to each specified server. There may be
    # multiple defineServer lines.
    
    # Set both the username and password to 'None' (without the quotes) if your
    # usenet server does not require authorization
    
    #Following is an example of a standard Usenet server
    defineServer(id = 'ChangeMe',
    hosts = [ 'news.changeme.com:119' ],
    
    username = 'user',
    password = 'pass',
    #username = None, # no auth
    #password = None,
    
    connections = 4,
    antiIdle = 4.5 * 60, # 4 minutes, 30 seconds, 0 to disable
    #bindTo = '204.31.33.7', # connect FROM this ip address
    #enabled = False, # disable this server
    #skipGroupCmd = False, # skip sending nntp GROUP commands
    #fillserver = 0, # defaults to 0 (a main server).
    # fillservers must have values > 0
    # (priority)
    ssl = False
    )
    
    #Following is an example of a Secure Usenet server
    #defineServer(id = 'SecureMe',
    # hosts = [ 'secure.news.changeme.com:443' ],
    #
    # username = 'ssluser',
    # password = 'sslpass',
    # #username = None, # no auth
    # #password = None,
    #
    # connections = 4,
    # antiIdle = 4.5 * 60, # 4 minutes, 30 seconds, 0 to disable
    # #bindTo = '204.31.33.7', # connect FROM this ip address
    # #enabled = False, # disable this server
    # #skipGroupCmd = False, # skip sending nntp GROUP commands
    # #fillserver = 0, # defaults to 0 (a main server).
    # # fillservers must have values > 0
    # # (priority)
    # ssl = True
    # )
    
    # Uncomment this line to limit all server connections to the specified KB/s
    # bandwidth
    Hellanzb.MAX_RATE = 150 # limit to 150kB/s
    
    # Important locations
    # Make sure the path mentioned in Hellanzb.PREFIX_DIR exists!
    Hellanzb.PREFIX_DIR = '/home/nzb/downloads/'
    
    # Where to put queued .nzb files
    Hellanzb.QUEUE_DIR = Hellanzb.PREFIX_DIR + 'nzb/daemon.queue/'
    
    # Where the fully processed archives go
    Hellanzb.DEST_DIR = Hellanzb.PREFIX_DIR + 'completed_files/'
    
    # The .nzb currently being downloaded is stored here
    Hellanzb.CURRENT_DIR = Hellanzb.PREFIX_DIR + 'nzb/daemon.current/'
    
    # The archive currently being downloaded is stored here
    Hellanzb.WORKING_DIR = Hellanzb.PREFIX_DIR + 'nzb/daemon.inprogress/'
    
    # Archives interrupted in the middle of downloading are stored here temporarily
    Hellanzb.POSTPONED_DIR = Hellanzb.PREFIX_DIR + 'nzb/daemon.postponed/'
    
    # Archives currently being processed. May contains archive directories, or
    # symbolic links to archive directories
    Hellanzb.PROCESSING_DIR = Hellanzb.PREFIX_DIR + 'nzb/daemon.processing/'
    
    # Temp storage
    Hellanzb.TEMP_DIR = Hellanzb.PREFIX_DIR + 'nzb/daemon.temp/'
    
    # Filename to store hellanzb state in between CTRL-Cs. The state (includes the
    # order of the queue, and smart par recovery information) is intermittently
    # written out as XML to this file
    Hellanzb.STATE_XML_FILE = Hellanzb.PREFIX_DIR + 'nzb/hellanzbState.xml'
    
    # _Sub directory within the nzb archive dir_ to move processed files to
    Hellanzb.PROCESSED_SUBDIR = 'processed'
    
    # Remove the PROCESSED_SUBDIR if the archive was successfully post processed.
    # Warning: The normal Hellanzb.LOG_FILE should be enabled with this option --
    # for a record of what hellanzb deletes
    Hellanzb.DELETE_PROCESSED = True
    
    # Maximum amount of memory used to cache encoded Article data segments.
    # hellanzb will write article data to disk when this cache is exceeded
    # Available settings:
    # -1: Unlimited size
    # 0: Disable cache (only cache to disk)
    # >0: Limit cache to this size, in bytes, KB, MB, e.g.:
    # 1024 '1024KB' '100MB' '1GB'
    #Hellanzb.CACHE_LIMIT = '2048KB'
    
    # Save archives into a sub directory of DEST_DIR named after their newzbin.com
    # category (when queued using the enqueuenewzbin XMLRPC call); e.g. Apps,
    # Movies, Music
    Hellanzb.CATEGORIZE_DEST = False
    
    # Disable SMART_PAR (download all PAR files)
    #Hellanzb.SMART_PAR = False
    
    # Supply a path to the (un)rar command
    Hellanzb.UNRAR_CMD = '/usr/local/bin/unrar'
    
    # Supply a path to the par2 command
    Hellanzb.PAR2_CMD = '/usr/local/bin/par2'
    
    # Skip unraring during post processing
    #Hellanzb.SKIP_UNRAR = False
    
    # Supply a path to the optional macbinconv command (for converting MacBinary
    # files)
    #Hellanzb.MACBINCONV_CMD = None
    
    # hellanzb inherits the umask from the current user's environment (unless it's
    # running in daemon mode). The umask can be forced with this option
    #IMPT NOTE: Following mask works in CentOS. Default UMASK is 0022
    #Hellanzb.UMASK = 022
    
    # Supported music types (case insensitive) and optionally their decompression
    # executables
    # and the file type that executable will decompress to (case insensitive). The
    # exes must be in the PATH.
    #
    # will be replaced with the name of music file
    # optional is with the specified extension
    #
    # None means these files don't need to be decompressed
    defineMusicType('wav', None, None)
    defineMusicType('mp3', None, None)
    #defineMusicType('ape', 'mac -d', 'wav')
    #defineMusicType('flac', 'flac -d -- ', 'wav')
    #defineMusicType('shn', 'shorten -x < > ', 'wav')
    
    # Max files we should decompress at the same time
    Hellanzb.MAX_DECOMPRESSION_THREADS = 2
    
    # Enable Mac OS X Growl notifications
    Hellanzb.GROWL_NOTIFY = False
    
    # The growl notification server, in the format 'hostname'
    Hellanzb.GROWL_SERVER = 'IP'
    
    # The growl password
    Hellanzb.GROWL_PASSWORD = 'password'
    
    # Enable libNotify Daemon notifications
    Hellanzb.LIBNOTIFY_NOTIFY = False
    
    # Disable ANSI color codes in the main screen (preserves the in place scroller)
    #Hellanzb.DISABLE_COLORS = False
    
    # Disable ALL ANSI color codes in the main screen (for terminals that don't
    # support ANY ANSI codes
    #Hellanzb.DISABLE_ANSI = False
    
    # Hostname for the XMLRPC client to connect to. By default, localhost
    # Do not change this
    Hellanzb.XMLRPC_SERVER = 'localhost'
    
    # Port number the XML RPC server will listen on, and the client will connect to.
    # Set to 'None' (without the quotes!) for no XML RPC server
    # Following port is default for hellanzb. Change it to head off potential bot-attacks
    # hellanzb will listen on this port *ON ALL IPS* (incl. public facing ones)
    Hellanzb.XMLRPC_PORT = 8760
    
    # Password for the XML RPC server. You might probably never use this, but the
    # command line XML RPC calls do -- it should definitely be changed from its
    # default value. The XML RPC username is hardcoded as 'hellanzb' -- E.g. URL:
    # http://hellanzb:changeme@localhost:8760
    Hellanzb.XMLRPC_PASSWORD = 'changemenow'
    
    # Username/Password to http://www.newzbin.com for automatic NZB downloading
    Hellanzb.NEWZBIN_USERNAME = 'newzbin'
    Hellanzb.NEWZBIN_PASSWORD = 'password'
    
    # If any of the following file types are missing from the archive and cannot be
    # repaired, continue processing because they're unimportant (case insensitive)
    Hellanzb.NOT_REQUIRED_FILE_TYPES = [ 'log', 'm3u', 'nfo', 'nzb', 'sfv', 'txt' ]
    
    # Don't get rid of (move into the PROCESSED dir) the following file types when
    # finished post processing (case insensitive)
    #Hellanzb.KEEP_FILE_TYPES = [ 'log', 'm3u', 'nfo', 'nzb', 'sfv', 'txt' ]
    Hellanzb.KEEP_FILE_TYPES = [ 'nfo', 'txt' ]
    
    # List of alternative file extensions matched as NZB files in the QUEUE_DIR.
    # The 'nzb' file extension is always matched
    #Hellanzb.OTHER_NZB_FILE_TYPES = [ 'xml' ]
    
    # Support extracting NZBs from ZIP files with this suffix (case insensitive) in
    # QUEUE_DIR. Defaults to '.nzb.zip'. Set to False to disable.
    #Hellanzb.NZB_ZIPS = '.nzb.zip'
    
    # Support extracting NZBs from GZIP files with this suffix (case insensitive)
    # in QUEUE_DIR. Defaults to '.nzb.gz'. Set to False to disable.
    #Hellanzb.NZB_GZIPS = '.nzb.gz'
    
    # Delay enqueueing new, recently modified NZB files added to the QUEUE_DIR until
    # this many seconds have passed since the NZB's last modification time (defaults
    # to 10 seconds)
    #Hellanzb.NZBQUEUE_MDELAY = 10
    
    # Optional external handler script. hellanzb will run this script after post
    # processing an archive, with the following arguments:
    #
    # handler_script type archiveName destDir elapsedTime parMessage
    #
    # type: post processing result, either 'SUCCESS' or 'ERROR'
    # archiveName: name of the archive, e.g. 'Usenet_Post5'
    # destDir: where the archive ended up, e.g. '/ext2/usenet/Usenet_Post5'
    # elapsedTime: a pretty string showing how long post processing took, e.g.
    # '10m 37s'
    # parMessage: optional post processing message. e.g. '(No Pars)'
    # Hellanzb.EXTERNAL_HANDLER_SCRIPT = '~/bin/post_hellanzb.sh'
    

    Working with hellanzb

    It might not seem possible, but hellanzb boasts an interface even more spartan than rTorrent. hellanzb can be launched with the following command:
    /usr/bin/hellanzb.py
    Once hellanzb starts, you will see the following in your SSH session:

    hellanzb-main

    In order to have hellanzb process nzb files, you need to place them in the “Hellanzb.QUEUE_DIR” folder ((That would be /home/nzb/usenet/nzb/daemon.queue/ if you used the sample hellanzb.conf from this wiki)) .

    Unlike rTorrent, hellanzb ships with a “daemon” mode built-in, so you can start it as a service very easily by issuing the following command:

    /usr/bin/hellanzb.py -D

    In order to see what hellanzb is currently doing, you can use the following command:

    /usr/bin/hellanzb.py status

    Let's now see how to add hellanzb to the list of services on startup.

    Running hellanzb as a Service

    In order to launch hellanzb at startup, we use a process identical to the one used for rTorrent. First, we create an entry in the init.d folder and then add a configuration file that the init.d script can read.

    These commands need to be executed while logged in as root

    The configuration file can be created as follows:

    touch /etc/hellanzb.init.conf
    nano -w /etc/hellanzb.init.conf

    Now copy and paste the following text into your hellanzb.init.conf file:

    ##Start Configuration##
    #Do not put a space on either side of the equal signs e.g.
    # user = user
    # will not work
    
    # system user to run as
    user="nzb"
    
    # the full path to the filename where you store your hellanzb configuration
    config="/usr/etc/hellanzb.conf"
    
    # file to log to (makes for easier debugging if something goes wrong)
    logfile="/home/nzb/hellanzbinit.log"
    Save and exit. If you want, you can get the file directly on your server as follows:
    cd /etc
    wget http://wiki.theaveragegeek.com/samples/hellanzb.init.conf
    Make sure to also create the logfile
    touch /home/nzb/hellanzbinit.log
    The next step is to create the entry in the init.d folder:
    touch /etc/init.d/hellanzb
    nano -w /etc/init.d/hellanzb
    Add the following text to your rtorrent file in the init.d folder:
    #!/bin/sh
    #
    #############
    ######
    #############
    # Licensed under the GPLv2 by average_geek: contact_at_theaveragegeek_dot_com
    ##############
    ######
    ##############
    #/etc/rc.d/init.d/hellanzb
    # chkconfig: 235 80 30
    # description: Run hellanzb as a Daemon service
    # processname: hellanzb
    # Source function library.
    . /etc/rc.d/init.d/functions
    # Source networking configuration.
    . /etc/sysconfig/network
    #VARIABLES#
    . /etc/hellanzb.init.conf
    PATH=/usr/bin:/usr/local/bin:/usr/local/sbin:/sbin:/bin:/usr/sbin
    DESC="hellanzb daemon"
    NAME=hellanzb.py
    DAEMON=$NAME
    SCRIPTNAME=/etc/init.d/$NAME
    RETVAL=0
    lockfile=${LOCKFILE-/var/lock/subsys/hellanzb}
    
    # Check that networking is up.
    [ ${NETWORKING} = "no" ] && exit 0
    
    #Functions
    checkconfig() {
    exists=0
    
    for i in `echo "$PATH" | tr ':' '\n'` ; do
    if [ -f $i/$NAME ] ; then
    exists=1
    appdir=$i
    apppath=$i/$NAME
    break
    fi
    done
    
    if ! [ -x "$apppath" ] ; then
    echo "cannot find executable hellanzb binary in PATH $appdir" | tee -a "$logfile" >&2
    exit 3
    fi
    
    if [ $exists -eq 0 ] ; then
    echo "cannot find hellanzb binary in PATH $PATH" | tee -a "$logfile" >&2
    exit 3
    fi
    
    if ! [ -r "${config}" ] ; then
    echo "cannot find readable config ${config}. check that it is there and permissions are appropriate" | tee -a "$logfile" >&2
    exit 3
    fi
    
    dlpath=`getsession "$config"`
    if ! [ -d "${dlpath}" ] ; then
    echo "cannot find the download directory ${session} from config ${config}. check permissions" | tee -a "$logfile" >&2
    exit 3
    fi
    }
    
    getsession() {
    
    path=`awk '/^Hellanzb.PREFIX_DIR[[:space:]]*=[[:space:]]*/ { print $3 }' "$config"`
    trimpath=`echo $path | sed -e s/\'//g`
    echo $trimpath
    }
    
    start() {
    
    [ -d "${base}" ] && cd "${base}"
    
    daemon `su -c "/usr/bin/hellanzb.py -D 2>&1 1>/dev/null" ${user} | tee -a "$logfile" >&2`
    
    RETVAL=$?
    echo
    [ $RETVAL -eq 0 ] && touch ${lockfile}
    
    }
    
    stop() {
    
    killproc $NAME
    
    RETVAL=$?
    echo
    [ $RETVAL -eq 0 ] && rm -f ${lockfile}
    
    }
    #End Functions
    #Script
    
    checkconfig
    
    case "$1" in
    
    start)
    echo -n "Starting $DESC: $NAME"
    start
    ;;
    
    stop)
    echo -n "Stopping $DESC: $NAME"
    stop
    ;;
    
    restart|force-reload)
    echo -n "Restarting $DESC: $NAME"
    stop
    sleep 1
    start
    ;;
    
    *)
    echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
    exit 1
    ;;
    
    esac
    
    exit 0
    

    Now we need to make the hellanzb file executable:

    chmod 755 /etc/init.d/hellanzb

    If you would like to skip copying and pasting text into your shell session, you can run the following commands instead:

    cd /etc/init.d/
    wget http://wiki.theaveragegeek.com/samples/hellanzb.sh
    mv hellanzb.sh hellanzb
    chmod 755 /etc/init.d/hellanzb

    Next we add hellanzb to the list of startup services:

    chkconfig --add hellanzb

    Now you can start hellanzb using the following command:

    /etc/init.d/hellanzb start

    If there are no problems with your configuration file, you should see the following:

    [root@centos]# /etc/init.d/hellanzb start
    Starting hellanzb daemon: hellanzb.py [ OK ]

    Verify that hellanzb is running with the following command:

    ps ax | grep hellanzb

    You should see the following:

    [root@centos]# ps ax | grep hellanzb
    10084 ? Sl 0:00 /usr/bin/python /usr/bin/hellanzb.py -D
    10236 pts/1 R+ 0:00 grep hellanzb

    Other Tips

    Download files via FTP reliably

    If you are using ProFTPD as your FTP server, you want to add the following line to your proftpd.conf file: (usually located in /etc)

    UseSendfile off

    This is recommended as there are some issues with VPS kernels that can cause timeouts on large transfers - See this article

    Fixing the sudo error

    By now you would be familiar with this annoying problem every time you issue the sudo command:

    [user@centos ~]$ sudo su -
    Password:
    audit_log_user_command(): Connection refused

    This is actually due to a bug in the version of sudo that ships with Red Hat. You can check out this blog post for instructions on how to upgrade your version of sudo which will fix this annoying error message.

    SAFE USAGE

    Copyright laws and laws pertaining to patents and inventions protect original works of authorship and inventions. Individuals who reproduce, distribute copies, receive copies, publicly perform or display works or inventions other than their own and without the consent of the owners or holders of rights, or their authorized agents, in original works of authorship or inventions, may be in violation of copyright, patent or other intellectual property infringement. The authors and contributors of this article do not encourage or condone the illegal copying of copyrighted material. This is not intended to be legal counsel or advice. If you have any questions, consult your attorney. ((Taken directly from the hellanzb README at http://www.hellanzb.com/trac/hellanzb/browser/trunk/README ))

    TODO

    1. Fix the inevitable spelling errors/bugs in this article?