view · edit · print · history


Btpd is a lightweight bittorrent daemon. It is able to handle multiple torrents in one process.

How to install

ipkg install btpd


Btpd consists of 3 files:
-btpd - the daemon
-btcli - the command line program to add / remove / stop / start / give stats / list /etc
-btinfo - a program designed to show the contents of a .torrent file

Advantages & disadvantages

btpd can, like enhanced-ctorrent, be combined with a script to automatically start downloading .torrents that are saved in a certain folder. It has the advantage that you don't need screen for monitoring, but on the other hand: there is no webbased control script available (yet).


I have made the following script for automatic downloading (in my case /usr/sbin/btpd.sh):

#set -x
wantedratio="100"                        # percentage

# --- check whether btpd is running; it tends to quit every few hours when downloading ---
if [ "`ps | grep "btpd --" | grep -v grep | wc | cut -b 7-8`" -lt 1 ]; then
 btpd --bw-in $bandwidth_in --bw-out $bandwidth_out -p $port

# --- check for new torrents ---
cd $torrentdir
torrentfile=`ls | grep .torrent | head -n 1`
if [ "$torrentfile" != "" ]; then
 if [ "`btinfo "$torrentfile" 2> /dev/null | wc | cut -b 4-10`" -eq 0 ]; then
  mv "$torrentfile" "$invaliddir"
  Set_Led beep1

 newdir=`btinfo "$torrentfile" | grep Name | sed -e "s/Name: //" | sed -e "s/[/\]/./g"`
 mkdir "$finisheddir/$newdir"
 chmod 777 "$finisheddir/$newdir"
 mv "$torrentfile" "$finisheddir/$newdir"
 cd "$finisheddir/$newdir"
 btcli add -d . "$torrentfile"
 Set_Led beep2 &
 sleep 1
 killall Set_Led

# --- check status ---
btnod=`btcli list | grep % | wc | sed -e 's/ */ /g' | cut -d " " -f 2`
for i in $(seq 1 $btnod);
 line=`btcli list | grep % | tr "\n" "\t" | cut -f $i`
 btrest=`echo "$line" | cut -b 43- | sed -e 's/ */\*/g'`

 btname=`echo "$line" | cut -b 1-42 | sed -e 's/   *//g'`
 btnr=`echo "$btrest" | cut -d "*" -f 2`
 btratio=`echo "$btrest" | cut -d "*" -f 6 | sed "s/\.//g"`
 btpct=`echo "$btrest" | cut -d "*" -f 4`
 btdir=`echo "$btname" | sed -e 's/[/\]/./g'`

 cd "$finisheddir/$btdir"*
 if [ $btpct != "100.0%" ];
  [ -e "./DOWNLOADING.txt" ] && `rm "./DOWNLOADING.txt"`
  btcli stat $btnr | grep -v DLOAD > "./DOWNLOADING.txt"
  chmod 777 "./DOWNLOADING.txt"
  if [ $btratio -ge $wantedratio ];
   chmod -R 755 .
   btcli del $btnr
   [ -e "./DOWNLOADING.txt" ] && `rm "./DOWNLOADING.txt"`
   [ -e "./SEEDING.txt" ] && `rm "./SEEDING.txt"`
   Set_Led beep3 &
   sleep 1
   killall Set_Led
   if [ -e "./DOWNLOADING.txt" ]; then
    chmod -R 755 .
    rm "./DOWNLOADING.txt"
    Set_Led beep2 &
    sleep 1
    killall Set_Led
   [ -e "./SEEDING.txt" ] && `rm "./SEEDING.txt"`
   btcli stat $btnr | grep -v DLOAD > "./SEEDING.txt"
   chmod 755 "./SEEDING.txt"


to run this:
* ipkg update
* ipkg install bash coreutils btpd findutils
* mkdir /public/torrents
* mkdir /public/torrents/invalid 
* mkdir /public/downloads (or whatever folder suits you)
* chmod -R 777 /public/torrents
* chmod 755 /public/downloads
* edit the script to change the port and directories to your desire
* save the script in desired directory (ie /usr/sbin) as btpd.sh
* chmod 555 btpd.sh
* update your firewall to allow incoming traffic on your desired torrent port
* add to cron: echo '*/2 * * * * root /usr/sbin/btpd.sh &>/dev/null' >> /etc/crontab

Some info on usage: if you save a .torrent to the torrentdir, the script will pick it up in max 2 minutes. Should the torrent be found to be defective, the slug will beep once (haven't seen this happen in months, but if it does: try another program. It probably WILL accept it!). If the slug beeps twice, it has accepted the torrent and started downloading (a DOWNLOADING.txt will appear in the folder it's downloading to). The downloadfolder is a subdirectory of $finisheddir and its name is determined by the name found inside the .torrent file.
Once the download is finished, the slug will beep twice again. As long as it's still seeding, you'll see a text file in the download directory, called SEEDING.txt. Once the seeding has reached the desired ratio, the torrent will stop seeding, the slug will beep three times, and the torrentname will be added to the file 'finished_seeding.txt'.

From Gabriel (21/9-2007):

Very nice - if it worked!

Running the script i keep getting error:

line 13: [: -lt: unary operator expected

From HN (24/9-2007):

Re: Gabriel: I think your error has been resolved now.

From Timer (09/1-2008) :

Maybe a noob question but keep getting error on line 40: 'tpd2.sh: line 40: syntax error near unexpected token ` 'tpd2.sh: line 40: `for (( i = 1 ; i <= $btnod; i++ )) I can't find any token matching problem...

From hbel (26/1-2008) :

facing the same problem ...

From Adam (01-Feb-08):

Works flawlessly, "out of the box". Big thank you to the author of this topic! :)

From Bram (22-Feb-08):

Change the for-loop code as follows OLD: for ( i = 1 ; i <= $btnod; i++ ) NEW: for i in $(seq 1 $btnod);

From Svennoe (23-mar-08):

&>/dev/null needs to be added to the crontab right after the command, so your command should look like this '*/2 * * * * root /usr/sbin/btpd.sh &>/dev/null' >> /etc/crontab

From HN (24-mar-08):

@Svennoe, @Bram: thanks for your input. I've changed the script according to your suggestions. @Adam: thanks! Glad I could help.

From Alan (02-apr-08):

Works very well, but I couldn't get it to execute under cron (ipkg cron) for root user until I made the following modifications:

Declared some new variables (find these paths using 'which xxx' with xxx being the command name)


then replaced the commands in the scripts with the appropriate variables i.e. for btcli, replace with $BTCLI

edit by CR (27-JUN-2008): This is due to the environment variables - they differ from cron to actual shell environment. You could have saved a lot of work if you just set PATH to /opt/bin :)

From Nowhere Man (02-APR-08):

Awesome little script. I did have to add a "-d /root/.btpd" option when invoking btpd to get it to work properly on my slug, but it seems to be doing the job as expected. Thanks!

From HN (13-APR-08):

I just had to reinstall my slug. Seems that the newest version of coreutils and busybox have a stripped version of 'find', which doesn't allow the -maxdepth option. So I changed the line to torrentfile=`ls | grep .torrent | head -n 1` . This is probably even faster.

From DAG (19-APR-08):

Created a php script to do basic monitoring. I dropped the following into /opt/share/www/lighttpd/bt.php. To monitor goto http://unslung:8081/bt.php?refresh=60(approve sites).

if ($refresh = $_GET['refresh']) {
        <meta http-equiv="refresh" content="<?php echo $refresh; ?>" />
<html><title>BTPD monitor</title>
<h1>BTPD monitor</h1>
if ($delete=$_GET['delete'])
        $output=shell_exec("/opt/bin/btcli del $delete; sleep 2");
        echo "<pre>$output</pre>";
$output=shell_exec("/opt/bin/btcli list");
if ( count($array) == 2 )
<p><b>No torrents</b></p>


<table  bordercolor="#0066FF" border="1">
        <tr><th align=left border=0>Name</th><th border=0 align=left>Complete</th></tr>

$pos=strpos( $array[0], "NUM" );
for ($i=1; $i < count($array)-1; $i++ )
        $row=preg_split("/[\s]+/",substr($array[$i],$pos,strlen($array[$i])-$pos ));
        echo "<tr><td>$name</td><td>$row[3]/$row[4]</td><td><a href='bt.php?delete=$row[1]'>remove</a></td>";
        echo "<a href='bt.php?refresh=60'>refresh</a>";

From Tumaini (2-JUN-08):

Is there something missing in the current version of the btpd.sh-script? My slug keeps beeping twice about every 2 minutes, unless I uncomment the line here (marked with ->):

 newdir=`btinfo "$torrentfile" | grep Name | sed -e "s/Name: //" | sed -e "s/[/\]/./g"`
 mkdir "$finisheddir/$newdir"
 chmod 777 "$finisheddir/$newdir"
 mv "$torrentfile" "$finisheddir/$newdir"
 cd "$finisheddir/$newdir"
 btcli add -d . "$torrentfile"
-> Set_Led beep2 &
 sleep 1
 killall Set_Led

From HN (15-JUN-08):

Tumaini, have you CHMODed? your /torrents and /downloads directory right? it kinda sounds like the slug can't move the .torrent to a new directory.

From CR (26-JUN-08):

Your "btpd running" check did not work for me (don't know why, check did always return that btpd was not running), so checked with

# --- check whether btpd is running; it tends to quit every few hours when down$
if [ "$(pidof btpd)" ]; then

From Girish (06-FEB-09):

When I run btpd, I get following error

[err] clock_gettime: Invalid argument

Is there anything I am doing wrong?

From HN (08-06-09):

Girish, btpd had been upgraded to version 0.15, which didn't work. To make it work: ipkg remove btpd, ipkg update, ipkg install btpd

view · edit · print · history · Last edited by HN.
Based on work by Girish, CR, HN, Tumaini, DAG, Alan, christhenowheremancom, Svennoe, makka, Bram Snip, Adam, hbel, Timer, and Gabriel S Hansen.
Originally by HN.
Page last modified on June 08, 2009, at 02:36 PM