view · edit · print · history

CGI interface to daemon is for managing and preview of the daemon state. There is also torrent_watchdog script for automatic torrent queue processing and mail notification.


  • multithreading (eg. 10 torrents simultaneously with nice priority)
  • Multitracker, PEX support, UPNP support, Encryption support, Bandwith limiting
  • automatic seeding when torrent finishes (configurable)
  • configurable port
  • WWW interface transmission.cgi can be public (no password) as there is no delete provided. (old versions)
  • Clutch WWW Interface with username and password. (for versions > 1.31)
  • Accelerator keys (ALT-key) for CGI interface. See help for underlined keys.
  • Per torrent and cumulative status
  • start/stop/push/bypass and other commands available in WWW interface
  • lightweight - low memory footprint
  • tracker scrape info. Suggest best seed torrent from target dir.
  • watchdog for auto restart/queue processing with cron
  • syslog watchdog events
  • mail notify when torrent finishes
  • no state database required. Directory tree is database (slow, but fail-safe)
  • stable and portable. Developed on Asus WL-500g Deluxe with Oleg firmware

Quick start guide

New version of Transmission based on the 1.3 branch is now available via ipkg install. Most of the instructions below the dividing line are now invalid. Transmission 1.3x comes with Clutch Web UI.

1) setup optware ipkg
2) # ipkg update
3) # ipkg install transmission

4) forward port 51413 to NAS

5) (recommend to create and login as a non-root user, root user might work too)
6) $ mkdir -p $HOME/Downloads
7) $ /opt/bin/transmission-daemon -w $HOME/Downloads
   $ pidof transmission-daemon  # should return 3 process ID's
8) connect to web UI http:// YOUR-NAS-IP-ADDRESS:9091/

The above should get you started, usage of the web UI should be straight-forward. If you have any problem starting transmission-daemon on step 7

7.1) # killall transmission-daemon
7.2) # /opt/bin/transmission-daemon -h
7.3) # /opt/bin/transmission-daemon -f

NOTE: With UnSlung? 6.x and Transmission 1.4 it was 'killall transmission-da' (NOT 'killall transmission-daemon'). Using 'ps -A' or 'ps' command you will see this.


Transmission 2.73+

February 1, 2014 Download the pre-built .ipk from here: http:// transmissionbt.net/transmission273p.zip

For changes see:

http:// github.com/cfpp2p/transmission/commits/svn/trunk http:// github.com/cfpp2p/transmission/commits/master

all bug fixes and enhancements through current version 2.77+ (core) and 2.82+ (except rename)

and optimized for NSLU2.

also version for temporary pieces included

Working very nicely, extremely stable.

use the regular or the piece-temp, whatever you prefer

reference: http:// trac.transmissionbt.com/ticket/532#comment:148

February 1, 2014 Download the pre-built .ipk from here: http:// transmissionbt.net/transmission273p.zip

you can review and/or compile the source code for the above at: http:// github.com/cfpp2p/transmission/wiki

to install:

ipkg install transmission_2.73+-1_armeb.ipk


ipkg install transmission_2.73+-1_armeb-pcTMP.ipk

be SURE to include the .ipk else ipkg install will try to download it

you may need to:

ipkg remove transmission if there is a version conflict


don't forget:

Package: transmission

Version: 2.77+-1

Depends: openssl, libcurl, libevent, zlib


04/02/2014 A very good update to the remote GUI is ready:

http:// transmissionbt.net/Win_GUI-040214.zip (Windows ONLY) 04/02/2014

This newer one has enhancements and fixes over the older one. Recommend.


Here is a very very nice Graphical User Interface for transmission 2.77+

http:// computerfixpro.com/WIN_GUI.zip (Windows ONLY) 09/16/2013

that supports the download queue and status, filter torrents with errors,

graphing, etc. many nice things. Give credit to Ivanal:

http:// code.google.com/p/transmisson-remote-gui/issues/detail?id=463

who worked hard to produce a fantastic update to:

http:// code.google.com/p/transmisson-remote-gui/ (MAC, LINUX, WIN)


Native compile/build Transmission


Version 1.8x and above

Version 2.22-2 is fully functional

Due to the hard work of a couple of people. They deserve a hard earned THANKS from everyone...

_______________________________________________________________________ _______________________________________________________________________ _______________________________________________________________________

Versions 1.8x seems to be broken for many.

See http:// trac.transmissionbt.com/ticket/2858

as well as other major problems reported for ARM and .ipk

Revert back to version 1.76 which works excellent.

Get version 1.76 for NSLU2 here:

http:// computerfixpro.com/Transmission-176-NSLU2.zip

Note: Version 2.0x is currently (July 2010) in optware, but is still broken.

Version 1.73-1 NOTES

August 2, 2009 SRS

umask support was added in v1.73. You may change its value in the

/root/.config/transmission-daemon/settings.json file:

it is set as "umask": 18, this is decimal 18 or octal 022, which is

the most commonly used value. From the documentation:

' umask: Number (default = 022) Set transmission's file mode creation mask.

See { the umask(2) manpage} for more information. Users who want their

saved torrents to be world-writable may want to set this value to 0. '

Note: The client must be closed before making changes to settings.json,

otherwise settings will be reverted to it's previous state.


A lot of people are asking why Transmisson "freezes" when it starts

downloading a torrent.

This is usually because "preallocation": 2, is the value in settings.json.

From the documentation:

' * preallocation: Number (0 = Off, 1 = Fast, 2 = Full (slower but reduces disk fragmentation), default = 1) '

I keep the default setting of 2 which is very slow, but sometimes

use a value of 1 which is fast and seems to work fine.

Version 1.70-2 NOTES

June, 7, 2009 SRS

For private trackers you should disable the new Distributed hash table (DHT) support.

When Using transmission-daemon Web GUI this is ENABLED by default!

This can only be disabled by editing the settings.json file.

Use 'vi' to edit:

vi /root/.config/transmission-daemon/settings.json

change line to: "dht-enabled": false,

You may want to disable this for public trackers in many cases also.

Version 1.70 seems to work very nicely and fixes several irritations/bugs of version 1.61.

Version 1.42-1 NOTES

  • With version 1.42 functionality for an IP address
  • whitelist became active for the WebGUI?.
  • ( See http:// trac.transmissionbt.com/ticket/1583 )
  • So you MUST specify the "rpc-whitelist" setting in the
  • settings.json file. You can do so by editing settings.json
  • directly or using the -a option when starting
  • transmission-daemon:
  • -a --allowed x.x.x.x,...
  • Allow RPC accecss to a comma-delimited whitelist
  • of IP addresses. Wildcards can be specified
  • in an address by using '*'.
  • Default: "" Example: "127.0.0.*,192.168.1.*"
  • The option sticks in future starts of transmission-daemon.
  • A value of *.*.*.* allows all IP addresses.
  • Also note the rpc-whitelist-enabled key is NON functional
  • for the clutch WebGUI?
  • The port of the web interface is configurable with the -p option (example: -p 8081). Without it, the port seems to be random.
  • In my case, streaming videos over smb does not work flawlessly with transmission running. As a workaround, I put a naive cgi in the httpd/html folder to be able to start/stop it conveniently. Might as well share, if anyone is interested.

LINKS="<a href=\"transmission-manager.cgi?start\">Start</a><br/>
<a href=\"transmission-manager.cgi?stop\">Stop</a><br/>
<a href=\"http:// slug:8081/transmission/web\">Transmission</a>"
case $action in
/etc/init.d/S88transmission > /dev/null
BODY="Starting: $SUCCESS (0=ok)<br/>$LINKS"
/etc/init.d/K88transmission > /dev/null
BODY="Stopping: $SUCCESS (0=ok)<br/>$LINKS"
echo "Content-type: text/html"
echo "<html>"
echo "<head><title>transmission manager</title></head>"
echo "<body>"
echo "<body>"
echo "$BODY"
echo "</body>"
echo "</html>"


avgjoe - Upon successfully installing 1.3x under ipkg you must start the transmission daemon. I have created a basic start script which will fetch the new version of the blocklist from bluetack and start the transmission-daemon:


# update blocklist
cd /root/.config/transmission-daemon/blocklists
wget -q http:// www.bluetack.co.uk/config/level1.gz
if test -f level1.gz; then
   rm level1
   gunzip level1.gz
   chmod go+r level1

if [ -n "`pidof transmission-daemon`" ]; then
   kill -9 `pidof transmission-daemon`

/opt/bin/transmission-daemon -b

Clutch interface can be found at: http:// <YOUR_NAS_IP>:9091/transmission/web/index.html

You can modify config either using web UI, or by editing /root/.config/transmission-daemon/settings.json

See also http:// trac.transmissionbt.com/wiki/Headless%20Transmisison


  You will need to change the following

   Your crontab file is
     */30 * * * * root /opt/bin/nice /opt/sbin/transmission_watchdog

   Also, use ext2,ext3.  Fat/fat32 will have problems with torrents over 5 gigs(not a file size issue,2gig limit) but just reads and writes, it locks up the router, and can corrupt files.

Questions & Answer on 1.3x

  • Is there a way to use blocklist with the transmissiond (cgi interface)?


For queue torrent file processing there should exist tree directories:

  • source - User should copy .torrent files here
  • work - Used for torrent processing
  • target - Place where finished torrents are put

Typical file flow is source -> work -> target For every torrent file from source, directory with the same name is created. Then torrent file is moved into this directory and transmissiond is run in background and constantly supervised with transmission_watchdog. The only way for moving finished active torrent into target dir is with Watchdog and not with Push.

CGI interface to daemon after each command lists all torrents in database. This time consuming can be interrupted at any time by giving next command or pressing stop button in WWW browser. This can be done for all commands except URL, Note and Rename as the action on torrent is taken during listing. This means that listing should not be interrupted until torrent is listed. In general there is no problem of interrupting listing at any point. This will not invalidate database which is file system alone.

Fetch command is useful only for fetching torrent files without passkey as there is no possibility to pass cookies to server. Use with care. Proper fetch would be "download in browser and then upload to server". This can only be done by browser plugin.

Troubles with tracker communication can be seen in syslog file. There is no association of active thread and reported problem from tracker. User should resolve this alone.

Install notes

Before running transmission user should carefully inspect variables in transmission.conf and create SOURCE, WORK, and TARGET directories

transmission_watchdog cares for queue processing and should be run every 30 minutes with cron. /opt/etc/crontab entry should look like:

 # m  h dom mon dow user command
 */30 *    * * *   admin nice transmission_watchdog 

For graphing to work properly, gnuplot and syslog is required. As log can accumulate it is recommended that logrotate is used for flushing old logs.

Accessing/Uploading .torrent files

You can do this either via fetch method that's available while viewing transmission.cgi (no cookie support!) and also with ftp and samba.

I prefer the ftp way since its locked with pass and very easy to start you only need to install vsftpd:
ipkg install vsftpd

Login details are set to your root login and pass by default.

For samba you need to try it yourself. Wiki: http:// wiki.openwrt.org/SambaHowto??highlight=%28samba%29

Using Transmission

by wirespot

A lot of people, myself included, are probably having some trouble when they first run into Oleo web interface for torrent download (transmission.cgi). That's because it's a little different from the torrent programs they're used to. So I'm going to describe what's going on under the hood.

There are 3 pieces of software working on the torrents:

  1. transmissiond. This is the actual workhorse that's downloading and uploading a torrent. If you run "ps" in a console you will see several of them working (if you have torrents running). Every time a torrent starts, one of these comes along and takes charge of it.
  2. transmission_watchdog. This one runs periodically, usually every 30 minutes, and is in charge of moving torrents around the queues (from "queued" to "active" to "done").
  3. transmission.cgi this is the actual web interface and is the thing you use to see your torrents and control them.

How to use the torrents

You start by putting a torrent file under the source/ directory. You can do this in many ways: you can download it on a desktop computer and FTP or SCP it to the router; you can SSH to the router, go into that directory and wget it from a website; you can use the "Fetch" button in the web interface to give the URL and the cgi will wget it and put it under source/.

All torrents found under source/ are automatically seen as part of the "Queued" set of torrents. If there are no torrents in the "Active" set, the watchdog will fetch the first one in the Queued set the next time it runs and make it Active. Or, you can manually make as many torrents as you want Active by selecting them and using the Push button in the interface.

Everytime the watchdog runs it will also check for completed Active torrents (the ones seeding) and will move them to the Completed set, where they stop moving and wait for you to come get the files.

You can manually pause an Active torrent by selecting it and using the Push button. This will stop the torrent and put it in the Suspended set. It will not leave this set anymore unless you select it and use the Push button again. (That's right, Push does two different things; when the torrent is first Queued it moves it to Active, and then it moves it between Active and Suspended; there's no way to move it back to Queued anymore).

Active torrents (and their files) are found under the work/ dir. Queued torrents are under source/. Completed torrents are under target/. Suspended torrents are under work/, but are temporarily renamed to ".torrent.suspended".

What other buttons do:

  • List: this one gives the complete list of all the torrents in all the queues.
  • Update: this one updates the Active information with actual data. Since this update is an expensive operation for the router, it is usually cached and you need to press Update to refresh it. Otherwise, using List will only show the same old info.
  • Bypass: this will mark active torrent to be bypasswd by watchdow when it tries to enqueue new torrents from source. Use this for big and slow torrents that will be bypasswd by others.
  • Watchdog: this will force the watchdog to run now instead of waiting for the next normal time. This is useful if you see that a torrent has finished downloading and is seeding, but you don't want to wait for it to be moved to Completed the next time the watchdog would normally run. (Please note that you should let torrents seed so other people can benefit too. Instead of stopping that torrent, consider Push-ing a Queued one instead.)
  • Pause: this will stop all torrents temporarily. It does this by telling all transmissiond programs to die. It doesn't move torrents around the queues at all, there simply aren't downloads or uploads going. This will be marked clearly in big bold letters saying "torrent processing paused". Use Pause again to resume the Active torrents.
  • Info will show some information about the torrent (tracker, what files are in it and so on).
  • Log will try to create a graph showing the state of the downloads. Depends on whether you have gnuplot installed. (I personally prefer rrdtool, look around the forum for the rrdtool tutorial.)
  • Remove will mark a torrent for removal, and Purge will actually DELETE BOTH THE TORRENT AND THE FILES FOR IT. So be careful with it. Note that removal can be used for unfinished (suspended) torrents only. For removing torrents from target use other commands like rm -rf torrent-dir
  • Scrape will attempt to ask the tracker for the scrape info, and Best will attempt to suggest the best seed torrent from the completed ones.
  • Note will add your personal note to the torrent, in case you want to jot down something about it.

X-wrt notes

WAN Access

In order to make the torrent client pass your firewall you MUST open the torrent port to be "connectable" the other ports are options if you want to access your router from some other WAN location:

 vi etc/config/firewall

Add the lines:

 accept:proto=tcp port=65534
 accept:proto=tcp dport=22
 accept:proto=tcp dport=8008
 accept:proto=tcp dport=21


 65534 - a must for torrent
 22    - ssh (optional)
 8008  - transmission.cgi (optional)
 21    - ftp (optional)

WWW firewall setting should look like the following image:

http:// img79.imageshack.us/img79/1609/xwrtfirewalllz5.png

Circular syslog

There is also possibility to use circular syslog, but this requires changes to transmission.cgi source code. Size be increased to 100k or more to see logs for more than one day.

http://i(approve sites) mg176.imageshack.us/img176/5545/xwrtsyslogmv7.png

Syslog on OpenWrt

OpenWrt comes with its own syslog that by default uses 16 kB circular syslog. It looks like that only circular syslog is started at boot and that symbolic link is needed to start user configured syslog. This can be done with

  root@oleo:/etc/rc.d# ln -s /etc/init.d/syslog /etc/rc.d/S15syslogd

but check for existance of syslog entry in /etc/rc.d before! This will give us to possibility to use regular file. It is recommended that syslog file is set as /var/log/messages and that size is limited to 100kB. This eliminates logrotate requirement for Transmission. Note that /var/log/messages resides in RAM. But we can spare 100kB of it.

Crontab on OpenWrt

It is recommended that we use OpenWrt cron daemon as it comes built in. One needs just add the following line to /etc/crontabs/root file:

 */30 * * * * nice /opt/sbin/transmission_watchdog

To let execute on startup, just run this command:

  root@oleo:/etc/rc.d# /etc/rc.d/S50cron enable

Oleg firmware and Transmission

by Moody Blue

My objective was to setup Oleg with Transmission and Samba2. This guide is written supposing that your PC runs Windows, and you want to use your router as a file server (to schedule backups, for example) and Torrent client.

Step 1 - Install required HW and SW

  1. ) Connect your PC to the wl-500gP using an ethernet cable (you should not use wireless during Step 1), and make sure that you can connect to the Ethernet
  2. ) Download and install putty and ASUS fw restoration utility
  3. ) Download Oleg firmware
  4. ) Unplug all USB devices from the router, and disconnect the modem cable
  5. ) Using the web interface, reset the router to factory settings
  6. ) Put the router in restoration mode
  7. ) Start ASUS firmware restoration utility and load Oleg fw into the router. Do not interrupt this step, the router may have to be repaired or replaced if you interrupt the load. The router will reboot automatically
  8. ) Connect the modem cable, and parametrize the router using web interface (at this stage the userid/password is admin/admin). Here are some of my parameters:
  • Maintain as the router's IP address, and limit DHCP to
  • Deactivate ftp and samba
  • Allow ping from WAN side
  • Activate Telnet service
  • If you use wireless, select 32mW as the transmission power and activate the maximum possible security supported by your PC's (in my case WEP128? + mac access + hide SSID)

- In LAN IP Setting / Host name specify a hostname of your choice (mine is MyASUS?)

  1. ) Reboot the router (using web interface)

You may have to calibrate the wireless part (it took me about 2 weeks to reach an acceptable setup)

Step 2 - Prepare the disk

From now on you can use wireless if you want.

  1. ) Connect the disk to the router
  2. ) Start putty in Windows (all the remaining actions should be performed in line mode, not web interface). Point it to, telnet, keyboard with Linux function keys
  3. ) Format the disk with 3 primary partitions, first with +512M for swap (select type 82), second with +1G (for /opt), and 3rd for the rest (for /mnt). Use fdisk help to guide you.
    insmod scsi_mod && insmod sd_mod && insmod usb-storage && sleep 5s fdisk /dev/discs/disc0/disc4) Reboot
  4. ) Format and mount the disk
    insmod scsi_mod && insmod sd_mod && insmod usb-storage && sleep 5s mkswap /dev/discs/disc0/part1 swapon /dev/discs/disc0/part1 mke2fs -j /dev/discs/disc0/part2 mount /dev/discs/disc0/part2 /opt mke2fs -j /dev/discs/disc0/part3 mount /dev/discs/disc0/part3 /mnt7) Install base packages (ignore errors regarding wl500g):
    cd /opt/ mkdir /opt/tmp mkdir /opt/tmp/ipkg wget http://ipkg.nslu2-linux.org/feeds/optware/oleg/cross/stable/ipkg-opt_0.99.163-9_mipsel.ipk ipkg.sh install ipkg-opt_0.99.163-9_mipsel.ipk wget http://ipkg.nslu2-linux.org/feeds/optware/oleg/cross/stable/uclibc-opt_0.9.28-13_mipsel.ipk ipkg.sh install uclibc-opt_0.9.28-13_mipsel.ipk ipkg update ipkg install nano rm *.ipk8) Create startup scripts
    mkdir -p /usr/local/sbin nano /usr/local/sbin/post-bootHere is my post-boot file:
    1. !/bin/sh
    2. test if USB disc has been attached
    3. if not - then insert needed modules
    if [ ! -d /dev/discs ]
       insmod scsi_mod && insmod sd_mod && insmod usb-storage && sleep 5s
  1. ) Wait for /opt to mount mount /dev/discs/disc0/part2 /opt mount /dev/discs/disc0/part3 /mnt
  while [ $i -le 30 ]
     if [ -d /opt/etc ]
sleep 1
 i=`expr $i + 1`
  1. ) Activate swap swapon /dev/discs/disc0/part1
  2. to let midnight commander run on terminals, make alias for colored mc
 echo "export TERMINFO=/opt/share/terminfo">>/etc/profile
 echo "alias mc=\"mc -c\"">>/etc/profile
  1. Run all active services - active means starts with S

Next let's create the post-firewall file

nano /usr/local/sbin/post-firewallHere is my post-firewall
## set default policy
iptables -P INPUT DROP
## deny ftp access from WAN
iptables -I INPUT 1 -p tcp -i "$1" --syn --dport 21 -j DROP
## Allow access to various router services from WAN
## Remove 22 8008 and 901 if you don't want to logon from WAN
for P in 65534 22 8008 901; do
  iptables -I INPUT 1 -p tcp --syn -i "$1" --dport $P -j ACCEPT
doneCreate remaining files:
touch /usr/local/sbin/post-mount
touch /usr/local/sbin/pre-shutdown
chmod +x /usr/local/sbin/*

!!!! 9) Save to flash and reboot

[@ flashfs save && flashfs commit && flashfs enable && reboot

At the end of this Step2 the router should be able to boot, mount the disk, and use the swap. You can verify this with


This should produce an output similar to

[xxxx@MyASUS root]$ mount
/dev/root on / type squashfs (ro)
none on /dev type devfs (rw)
proc on /proc type proc (rw)
ramfs on /tmp type ramfs (rw)
usbfs on /proc/bus/usb type usbfs (rw)
/dev/discs/disc0/part2 on /opt type ext3 (rw)
/dev/discs/disc0/part3 on /mnt type ext3 (rw)
[xxxx@MyASUS root]$ free
              total         used         free       shared      buffers
  Mem:        30140        13744        16396            0         4148
 Swap:       500712            0       500712
Total:       530852        13744       517108

Step3 - Install samba2

Samba2 comes with a web interface from where you can parametrize and restart the service without rebooting the router. It was my choice to have file server services provided by the router.

 ipkg install mc
 ipkg install xinetd
 ipkg install samba2

Create folder for samba shares

 mkdir /mnt/share
 chmod ugoa+w /mnt/shareCreate rc.unslung 

(if you want to start all your services automatically after each reboot)

nano /opt/etc/init.d/rc.unslung

Here is my rc.unslung file:

 # Start all init scripts in /opt/etc/init.d
 # executing them in numerical order.
 for i in /opt/etc/init.d/S??* ;do 
    # Ignore dangling symlinks (if any).
    [ ! -f "$i" ] && continue

    case "$i" in
           # Source shell script for speed.
               trap - INT QUIT TSTP
               set start
               . $i
           # No sh extension, so fork subprocess.
           $i start

 Edit /opt/etc/xinetd.d/swat file (with nano or mc) to update the "user = root" line with your userid.
 Make rc.unslung executable, and execute it to start xinetd and samba2

 chmod +x /opt/etc/init.d/rc.unslung

Open your browser to http:// and parametrize samba at your will. I have removed all shares and created two new ones:

 * Share (pointing to /mnt/share)
 - Torrent (pointing to /mnt/torrent)

Step 4 - Install Transmission

This was my choice for torrent client. It's Very easy to use. You can either store .torrent files in //myasus/torrent/source or use Transmission's fetch button. At the moment transmission is going through changes, so what follows may not apply in the near future.

 ipkg install cron
 ipkg install gnuplot
 ipkg install logrotate
 ipkg install transmission

Create torrent directories

 mkdir /mnt/torrent
 mkdir /mnt/torrent/source
 mkdir /mnt/torrent/target
 mkdir /mnt/torrent/work
 chmod ugoa+w /mnt/torrent
 chmod ugoa+w /mnt/torrent/source
 chmod ugoa+w /mnt/torrent/target
 chmod ugoa+w /mnt/torrent/work

Using mc, edit /opt/etc/transmission.conf and replace all tmp/harddisk by mnt. Also replace USER=admin by your correct userid, and update TIMEZONE if needed.

In case your admin userid was changed to something else, pls edit /opt/share/www/cgi-bin/transmission.cgi accordingly.

Edit your /opt/etc/crontab file. Mine is (replace xxxx with your admin userid):

 # ---------- ---------- Default is Empty ---------- ---------- #
 */30 * * * * xxxx nice /opt/sbin/transmission_watchdog
 0 0 * * * xxxx /opt/sbin/logrotate -f /opt/etc/logrotate.conf &>/dev/null

Create S05syslogd, this is necessary to replace logging on memory by logging on disk, and make it available for gnuplot.

nano /opt/etc/init.d/S05syslogd

Here is mine:

 # Startup script for syslogd
 # Stop myself if running
 if [ -n "`pidof syslogd`" ]; then
   killall syslogd 2>/dev/null

 /sbin/syslogd -m 0 -O /opt/var/log/messages -S -l 7

Make it executable, and reboot:

 chmod +x /opt/etc/init.d/S05syslogd
 You can access Transmission from Windows pointing your browser to    


Next Steps (optional)

Access router from WAN:

  1. Activate Dropbear (see initial post of this thread)
  2. In the web interface disable Telnet and enable DynDNS
  3. Create two entries in putty, one for LAN, another for WAN access
  4. Implement SSL security as discussed here

Install notes for transmission on NSLU2 with Unslung 6.8

The optware package for transmission doesn't deliver everything right. It points to wrong file-locaties etc. The easiest way is to copy the filecontents of the files described here, to your files and sometimes to change filelocations.

Adjusted transmission.cgi

This file can be copied from /opt/share/www/cgi-bin to /home/httpd/html/cgi-bin (you need to create the directory cgi-bin). You can call the webinterface in your webbrowser by something like: http:// (use your slugs-ip-adress instead of!). The file-contents of transmission.cgi can be changed to (I've removed al the comments, as this wiki transforms the #'s into numbers):

. /opt/etc/transmission.conf

export PATH

    if [ -n "`ls ${WORK}/*/*.torrent 2>/dev/null | head -n 1`" ] ; then
	ls -1  ${WORK}/*/*.torrent > ${ACTIVE}	
    	rm -f ${ACTIVE}
    if [ -n "`ls ${TARGET}/*/*.seeding 2>/dev/null | head -n 1`" ] ; then
        ls -1  ${TARGET}/*/*.seeding >> ${ACTIVE}
    [ -f ${PIDFILE} ] && kill -HUP `cat ${PIDFILE}`
    echo "STARTTIME=\"${STARTTIME}\"


    if [ -f ${PIDFILE} ]; then
        PID=`cat ${PIDFILE}`
        if `grep -q transmissiond /proc/${PID}/cmdline 2> /dev/null` ; then
            kill -USR1 ${PID}
            sleep 1     
            for TORRENT in ${WORK}/*/*.torrent ${TARGET}/*/*.torrent.seeding
                do if [ -d "${TORRENT%/*}" ]; then
                    if [ -f "${INFO}" ]; then
	                . "${INFO}"
	                if [ -f "${LOG}" ]; then
	                    .  "${LOG}"
	                    STATUS=".status not found for ${TORRENT}"
	echo "<p>Transmission daemon is not running.</p>"
	echo "<p>Status not updated!</p>"

    if [ -f "${INFO}" ] ; then
	 . "${INFO}" 
    [ -z "${STARTTIME}" ] && STARTTIME=`date +"${DATE_FORMAT}"`

_stop_torrent ()
    if [ -f  "${INFO}"  ] ; then
	. "${INFO}"
	[ -z "${ENDTIME}" ] && ENDTIME=`date +"${DATE_FORMAT}"`
	STATUS=`echo "${STATUS}"|sed -e 's/Progress: \([0-9\.]\{2,6\} %\).*/\1/p;d'`

    mkdir -p "$WORK/$TORRENTNAME"                                               
    chmod 777 "$WORK/$TORRENTNAME" 
    _start_torrent "${TORRENT}"

_suspend ()
    mv "${TORRENT}" "${TORRENT}.suspended"
    _stop_torrent "${TORRENT}"

_resume ()

    mv "${TORRENT}" "${TORRENT%.suspended}"
    _start_torrent "${TORRENT%.suspended}"

_seed ()

   if [ ! -f "${TARGET}${TORRENT#${TARGET}}" ] ; then
	echo "<b>Can only seed already done torrents</b>"

   if [ -f "${TORRENT%.seeding}" ]; then
	mv "${TORRENT}" "${TORRENT}.seeding"
	_start_torrent "${TORRENT}.seeding"
	mv "${TORRENT}" "${TORRENT%.seeding}"
	_stop_torrent "${TORRENT%.seeding}"

_purge ()
    LOG=`ls -1 $TARGET/*/.info 2>/dev/null | head -n 1`
    if [ -z "${LOG}" ] ; then
	echo "No .info to purge."
      echo "<pre>"
      for f in $TARGET/*/.info ; do
	  if [ -f "${TORRENT}" ]; then
		echo "<b>status $f not purged</b>"
          	echo "Puging ${DUMMY}"
		[ -f "${DUMMY}/.status" ] && rm "${DUMMY}/.status"
		. "${f}"
      echo "</pre>"

    REMOVED=`ls -1 $WORK/*/*.torrent.removed 2>/dev/null | head -n 1`
    if [ -n "${REMOVED}" ]; then
        echo "<pre>"
	for f in $WORK/*/*.torrent.removed ; do
		echo "Purging $DIR"
		rm -fr "${DIR}"			
        echo "</pre>"

_pause ()
    if [ -f "$WORK/.paused" ] ; then
	rm "$WORK/.paused"

	[ -e ${PIDFILE} ] && rm ${PIDFILE}
	export HOME
	if  false ; then
	        echo "Starting transmission daemon ..." 
                transmissiond -p ${LISTENING_PORT} \
                ${NAT_TRAVERSAL} \
		-w ${WATCHDOG} \
		-u ${UPLOAD_SPEED} \
		-i ${PIDFILE}   ${ACTIVE}
	    sleep 5
	    if [ -f ${PIDFILE} ]; then
		PID=`cat ${PIDFILE}`
		echo "<p>Transmission daemon started with PID=${PID}</p>"
		echo "<p><b>Transmission daemon failed to start</b></p>" 
	  echo "<p>transmission_watchdog will start Transmission daemon.</p>"
          echo "<p>Press Watchdog button to force watchdog queue processing</p>"
	touch "$WORK/.paused"
	kill -TERM `cat ${PIDFILE}`
	echo "<b>Stopping transmissison!</b>"
	echo "<p>Transmission will eventually stop. "
	echo "Last Log line should report transmissiond exiting.<p>"

_scrape ()
  for TORRENT in ${WORK}/*/*.torrent ${TARGET}/*/*.torrent* ; do
    if [ -f "${INFO}" ]; then
	. "${INFO}"
	SCRAPE=`transmissioncli -s "${TORRENT}" | grep seeder`
	if [ $DUMMY != 0 ]; then
	   echo "<p>${TORRENT} scrape failed</p>"
	echo "."
  echo " done."

_best_seed ()                     
    if [ -n "`ls ${TARGET}/*/*.torrent 2>/dev/null | head -n 1`" ] ; then
	for TORRENT in ${TARGET}/*/*.torrent ; do
	    if [ -f "${INFO}" ]; then
		. "${INFO}"
		QUOTIENT=`echo "${SCRAPE}" | sed -n -e '/seeder/s/\([0-9]\{1,\}\) seeder(s), \([0-9]\{1,\}\) leecher.*/(\2000\/(\1+1)/p;d'` 
		if [ ${RATIO} -gt ${BEST} ]; then
	echo "<h3>Best seed suggestion</h3>"
	echo "<p>${BESTTORRENT##*/}</p>"
	echo "<p>${BESTSCRAPE}</p>"
	echo "<b>No torrents to suggest for seeding</b>"

    TORRENT=$(echo "${FETCH}" |sed 's/%/\\x/g')
    TORRENT=$(echo -e "${TORRENT}")
    echo "<p>Fetching ${TORRENT}</p>"
    wget -q -P ${SOURCE} "${TORRENT}"  ||  echo "<p>wget ${TORRENT} failed</p>"

__find ()
    [ -n "${TORRENT}" ] && return

    if [ -n "`ls ${FILEPAT} 2>/dev/null | head -n 1`" ] ; then
	for i in $FILEPAT ; do
	    if [ $ID = $idx ]; then


_find ()
    __find "$WORK/*/*.torrent"
    __find "$TARGET/*/*.torrent.seeding"
    __find "$WORK/*/*.torrent.suspended"
    __find "$WORK/*/*.torrent.removed"
    __find "$SOURCE/*.torrent"
    __find "$TARGET/*/*.torrent" 
   [ -z "${TORRENT}" ] && echo "Assertion failed [ -z TORRENT ] in _find()" 

__list ()

    if [ -n "`ls ${FILEPAT} 2>/dev/null | head -n 1`" ]
	echo "<table>"
	echo "<thead><tr><td></td><td>${DESC}</td><td>status</td></tr>"
	echo "</thead><tbody>"
	for i in $FILEPAT
	    echo "<tr><td><input name=ID value=$idx type=radio></td>"
	    if [ -f "${P}/.info" ];then
	       . "${P}/.info" 
	    if [ -n "${SETURL}" -a "${idx}" = "${ID}" ]; then
	       URL=$(echo "${SETURL}" | sed 's/%/\\x/g')
               URL=$(echo -e "${URL}")
	    if 	[ -f "${P}/.bypass" ] ; then
	   	echo -n "<td bgcolor=#a2b5cd>"
	    	echo -n "<td>"
	    if [ -n "${URL}" ]; then
	       echo "<a href=\"${URL}\" target=_blank>${DUMMY}</a></td>"
	       echo "${DUMMY}</td>"
	    if [ -f "$P/.info" ] ; then
		echo "<td>${STATUS}"
		echo " Start: ${STARTTIME}"
		[ -n "${ENDTIME}" ] && echo " End: ${ENDTIME}"
		[ -n "${SCRAPE}" ] && echo " ${SCRAPE}"
		if [ -n "${SETNOTE}" -a "${idx}" = "${ID}" ]; then
                   NOTE=$(echo "${SETNOTE}" | sed 's/%/\\x/g')
                   NOTE=$(echo -e "${NOTE}")
		[ -n "${UPLOADED}" ] && echo " uploaded: ${UPLOADED} MB" 
		[ -n "${NOTE}" ] && echo " ${NOTE}"
		[ -f "${P}/.bypass" ] && echo ", bypassed"
		echo "</td></tr>"
	    idx=`expr $idx + 1`
	echo "</tbody></table>"

_list ()
    if [ -f "$WORK/.paused" ] ; then
	echo "<h3>Torrent processing paused!</h3>"
    __list "$WORK/*/*.torrent" "Active"
    __list "$TARGET/*/*.torrent.seeding" "Seeding"
    if [ -r "${SYSLOG}" ]; then
        SPEED=`tail ${SYSLOG}  | sed  -n '/transmissiond/s/.*\dl \([0-9.]\{1,\}\) ul \([0-9.]\{1,\}\).*/DOWNLOAD="\1";UPLOAD="\2"/p' | tail -1`
        eval "${SPEED}"
        if [ -n "${DOWNLOAD}"  ] ; then
	    echo "<table><tr><td>Total</td><td>Download ${DOWNLOAD}kB/s</td>"
	    echo "<td>Upload ${UPLOAD} kB/s</td></tr></table>"
            echo "<p>Unable to find recent transfer stats in syslog</p>"
        echo "<p>syslog: ${SYSLOG} unavailable for transfer stats!</p>"
    [ "${ACTION}" = "Update" ] && return
    __list "$WORK/*/*.torrent.suspended" "Suspended" 
    __list "$WORK/*/*.torrent.removed" "Removed" 
    __list "$SOURCE/*.torrent" "Queued"
    __list "$TARGET/*/*.torrent" "Done" 


_root_check () {
	if  [ ${USER} != admin -a  ${USER} != root ]; then
	    echo "You must be root! Because of killing stuff"
	    return 1
	return 0

_remove ()
    if [ -z "$ID" ] ; then
	echo "<b>Please select torrent first!</b>"


   if [ -f "${TORRENT%.torrent.suspended}.torrent.suspended" ]; then
	mv "${TORRENT}" "${TORRENT%.suspended}.removed"
	echo "<b>Can only remove suspended torrents!</b>"

    if [ -z "$ID" ] ; then
	echo "<b>Please select torrent first!</b>"

    if [ -f "${TORRENT%.suspended}.suspended" ]; then

    if [ -f "${WORK}${TORRENT#${WORK}}" ]; then
       if [ -f "${TORRENT%.torrent}.torrent" ]; then


    if [ -f "${TARGET}${TORRENT#${TARGET}}" ]; then

    if [ -f "${SOURCE}${TORRENT#${SOURCE}}" ]; then

    echo "<p><em>Nothing to push!</em></p>" 

    if [ -z "$ID" ] ; then
	echo "<b>Please select active torrent first!</b>"

    if [ -f "${WORK}${TORRENT#${WORK}}" ]; then
     	if [ -f "${DUMMY}" ]; then 
	    rm -f "${DUMMY}"
	    echo "This torrent is bypassed by watchdog" > "${DUMMY}"
    	echo "<p> Can only bypass active torrent!</p>"

_log ()

if [ ! -r ${SYSLOG} ]; then
  echo "<p>${SYSLOG} not readable. Properly configure syslogd at "
  echo "system startup.</p>"

echo "<pre>"
sed  -n -e "/ transmission.*:/{s/.*: \([0-9]\{1,10\}\) [0-9]\{1,\} dl \([0-9.]\{1,\}\) 
ul \([0-9.]\{1,\}\) ld \([0-9.]\{1,\}\)/\1 \2 -\3 \4/;t data;p;b;:data w ${GNUPLOT_DATA}" -e "}" ${SYSLOG} 
echo "</pre>"

if [ ! -x ${GNUPLOT} ]; then
  echo "<p>gnuplot: ${GNUPLOT} not found. Properly configure paths "
  echo "in transmission.conf for transfer graphing!</p>"

echo "<p>Creating graph...</p>"
cat > ${GNUPLOT_COMMAND} << __EOF__
set terminal png small size 800,320
set output '${GNUPLOT_OUTPUT}'
set xdata time
set timefmt "%s"
set format x "%H:%M\n%m/%d"
set ytics nomirror
set y2tics nomirror
set y2range [0:]
set ylabel "Transmission transfer rate [kB/s]"
set y2label "System load (5 min average)"
set y2tics 1
set xlabel "Time [UTC ${TZO} seconds]"
plot '${GNUPLOT_DATA}' using (\$1+86400+${TZO}):2 title 'download' axis x1y1 with impulses, \
     '${GNUPLOT_DATA}' using (\$1+86400+${TZO}):3 title 'upload' with impulses, \
     '${GNUPLOT_DATA}' using (\$1+86400+${TZO}):4 axis x1y2 title 'load' with lines


echo "<img src=\"${HTTP_IMG_LOCATION}\">"


_info ()
    if [ -z "$ID" ] ; then
	echo "<b>Please select torrent first!</b>"
    echo "<h3>Torrent file metainfo</h3>"
    echo "<pre>"
    transmissioncli -i "${TORRENT}"
    echo "<p>"
    transmissioncli -s "${TORRENT}" | grep "seeder"
    echo "</p></pre>"

_help ()
    cat << __EOF__
This is quick explanation of the buttons:
<dt><u>U</u>pdate<dd>updates active torrents status
<dt><u>P</u>ush<dd> Push selected torrent to other queue
<dt>Log<dd>shows <u>c</u>urrent transfer log graph
<dt><u>L</u>ist<dd>lists queued, active, suspended and completed torrents
<dt>U<u>R</u>L<dd>Enter URL location for torrent
<dt><u>N</u>ote<dd>Append your notes to torrent status
<dt>B<u>y</u>pass<dd>Bypass active torrent watchdog processing
<dt>Pur<u>g</u>e<dd>removes all logs from completed torrents and clean removed torrents
<dt><u>W</u>atchdog<dd>forces transmission_watchdog processing
<dt>Pau<u>s</u>e<dd>all active torrent processing should stop/resume imediately
<dt><u>R</u>emove<dd>mark torrent for purging
<dt><u>I</u>nfo<dd>shows selected torrent info (file content and size)
<dt>Scr<u>a</u>pe<dd>Update scrape info (seeders, leechers, downloaded)
     from tracker for downloaded torrents
<dt><u>B</u>est<dd>Search scrape for best done torrent and suggest seeding based on (leeches/seeds) ratio
<dt><u>F</u>etch<dd>Fetch torrent file from URL (link location)
<dt><u>H</u>elp<dd> Access keys <u>underlined</u>! Use Alt-Key for access. Button listing in descending importance.

<p>Explanation of usage is available at NSLU2 Optware <a href=http://www.nslu2-linux.org/wiki/Optware/Transmission>
Transmission daemon wiki page</a>.</p>

if [ -r /opt/share/doc/transmission/README.daemon ]; then 
	echo "<pre>" 
	cat /opt/share/doc/transmission/README.daemon
	echo "</pre>" 

cat << __EOF__                                 
Content-type: text/html

  <style type="text/css">
      BODY { background-color: #F8F4E7; color: #552800 }
      A:link { color: #0000A0 }
      A:visited { color: #A000A0 }
      THEAD {
        background: #D0D0D0;
        color: #000000;
        text-align: center;
      TBODY {
        background: #D0D0E7;
<form action=transmission.cgi method=get>
<input type=submit accesskey=u name=ACTION value=Update>
<input type=submit accesskey=p name=ACTION value=Push>
<input type=submit accesskey=l name=ACTION value=List>
<input type=submit accesskey=c name=ACTION value=Log>
<input type=submit accesskey=r name=SETURL value=URL 
 onClick='value=prompt("Enter URL location to torrent page", "http://")'>
<input type=submit accesskey=n name=SETNOTE value=Note
 onClick='value=prompt("Enter your notes for this torrent")'>
<input type=submit accesskey=y name=ACTION value=Bypass>
<input type=submit accesskey=s name=ACTION value=Pause>
<input type=submit accesskey=w name=ACTION value=Watchdog>
<input type=submit accesskey=r name=ACTION value=Remove>
<input type=submit accesskey=g name=ACTION value=Purge>
<input type=submit accesskey=i name=ACTION value=Info>
<input type=submit accesskey=a name=ACTION value=Scrape>
<input type=submit accesskey=b name=ACTION value=Best>
<input type=submit accesskey=f name=FETCH value=Fetch
onClick='value=prompt("Enter torrent link location for fetching")'>
<input type=submit accesskey=h name=ACTION value=Help>
<! img align=top alt="" src=pingvin.gif>


QUERY_STRING=`echo "$QUERY_STRING" | sed 's/&/;/g'`

[ -n "${FETCH}" ] && _fetch

case "${ACTION}" in
    Update)	_update_progress ; _list ;;
    Log)	_log ;;
    Push)	_push ; _list ;;
    Pause)	_pause ; _list ;;
    Remove)	_remove; _list ;;
    Purge)	_purge ;;
    Watchdog)	transmission_watchdog ;;
    Info)	_info ;;
    Help)	_help ;;
    Scrape)	_scrape ; _list;;
    Best)	_best_seed ; _list;;
    Bypass)	_bypass; _list ;;
    *) _list ;;

echo "<p>" ; ps ; free ; echo "</p>" 

cat << __EOF__  

  <li><a href=../source>source</a></li>
  <li><a href=../work>work</a></li>
  <li><a href=../target>target</a></li>
&copy; 2005-2007 oleo

You can create softlinks (ln -s ...) from /home/httpd/html to your source, work and target directory.

Adjusted transmission.conf

This file is located in /opt/etc/ Warning: adjust the locations for SOURCE, WORK and TARGET according to your wishes. The same for PIDFILE, ACTIVE and HOME. Also change the LISTENING_PORT if you need to

 (depending on your firewall-settings)

MAILOPT="-smail.somedomain.com -f"
DATE_FORMAT="%d %h %H:%M"










Remove S80busybox_httpd

This file is located in /opt/etc/init.d.

Adjust crontab

In /opt/etc/ edit the line in crontab which references to transmission_watchdog: admin must be replaced by root

Name a Torrent as you download it-- this is included with transmission 1.3x and up

I did this because some torrent sites use "download.torrent" as all the torrent names, this option allows you to name the torrent, so you can download more than 1 at a time, and give it a useful description

Note, do this after everything else is working. Change the following in transmission.cgi, there are three areas to change

edit 1(approx line 282) This take in account if you leave the prompt blank for the torrent name, it will use the default

old line  FILE=$(echo "${TORRENT}" |sed 's|^.*/||;s|?.*||')

new line  if [ ${#tname} < 1 ] ; then 
new line     FILE=$(echo "${TORRENT}" |sed 's|^.*/||;s|?.*||') 
new line  else 
new line     FILE=$(echo "${tname}.torrent") 
new line  fi 

edit 2 (approx line 620)this addes a hidden value and names the form so we can change it

old line  <form action=transmission.cgi method=get>

new line <form action=transmission.cgi method=get name="myform">
new line <input type="hidden" name="tname" value="">

edit 3(approx line 639) Adds the second prompt to name the torrent

old line onClick='value=prompt("Enter torrent link location for fetching")'>

new line onClick='value=prompt("Enter torrent link location for fetching");document.myform.tname.value=prompt("Enter Torrent Name")'>


  • Is there a way to enable encryption and also disable unencrypted communication?
    • Upgraded to Transmission 1.0.5 via ipkg and the new conf file came with encryption options. Also the transmission.cgi did not need to be edited and worked straight from the ipkg installation.
  • I just got an NSLU2 and installed the latest stable firmware (Unslung V2.3R63-uNSLUng-6.10-beta) -- I'm not sure if this has anything to do with it (since the instructions above say 6.8), but I can't get transmission.cgi to work; it always complays that it can't access /var/log/messages (using the included transmission.cgi, or the modified one above). I also tried the crontab & init.d/S05syslog modifications; made no difference. The only other variable (other than the Unslung version) is that I'm running it through lighttpd.
    • Not a developer here, but perhaps I might help. The only time I get the error message about /var/log/messages is when I haven't run the transmission daemon for a while. Once it starts logging stats into /var/log/messages, that error goes away. Just make sure that the daemon is running under a user that has read/write access to /var/log/messages I run the transmission.cgi off the standard thttpd
  • I keep getting an error when I try to download through Transmission. "Destination folder doesn't exist", even though my folders do exist. Most of all, id like Transmission to save my torrents to /share/hdd/data/public/Torrents (because I know where to find that folder! =D) //John
    • Have you edited your /root/.config/transmission-daemon/settings.json file? This is assuming you are running the daemon as root of course. Your setting for download dir should be as follows:
"download-dir": "\/share\/hdd\/data\/public\/Torrents",
  • Thank you for helping me. Problem solved. I have had a torrent file in Transmission that I've used for testing. Apparently, I had to remove it and add it again for Transmission to check the settings file. //John
  • With Transmission 1.4 I could download a 700 MB torrent with no problems. But trying a 30 GiB? torrent, it crashes my NSLU2 every time. No Clutch, no telnet access, no Unslung (6.8) web UI -- but for some reason, it still responds to ping requests over the network. What could be wrong? Swap space is 128 MB. //Michael
view · edit · print · history · Last edited by SRS.
Based on work by SRS, Rai, BrianZhou, axm, fmt, Michael, arthur92710, Snake98, Brad, John, avgjoe, DarkGafarro, thomas, ralph, oleo, deleted, Federico, crebain, marceln, fcarolo, and Joop Verdoorn.
Originally by oleo.
Page last modified on April 02, 2014, at 11:20 PM