Copying files from one computer to another over a network should be a simple matter, yet the majority of tools complicate this task unnecessarily. File Tosser is a collection of scripts and code examples that demonstrate a very simple approach to serving files across a network.
File Tosser is not responsible for any file meta-data, and is unaware of hard links, symlinks and devices. If you need to send this sort of thing use tar(1) on your files first, or find another protocol.
One of my favorite things about Linux is that it has let me recycle old boxen by turning them into firewalls. A few of the firewalls I've created have been only barely fast enough to keep up with ssh(1) connections running at cable-modem speed, and were limiting my scp(1) transfers on the LAN to a few hundred kbps. A good solution for moving the occasional file to or from it over the LAN is netcat - nc(1):
On the sending computer:
nc -l -p 12345 < file.to.send
On the receiving computer:
nc sending.computer 12345 > destination.file
This solution is good because it only requires a working TCP stack at both ends, however when I need to copy multiple files or copy files at as part of a cron job, this just won't cut it. "it" the original tosser was written to fill this role. It can be set to run from inetd as a normal user, and at less than 10 lines of shell script it is easy to verify that it is not a security risk.
Later I started using the original tosser on a remote box with an unreliable connection, launched from an sshd(8) authorized_keys file. Eventually I noticed that I was wasting time and cycles verifying RSA keys for each file when sending lots of small files. I was also having to re-send entire files when the connection failed during a transfer, wasting time and bandwidth. "ft" the improved tosser was written to solve these problems. ft is still pretty light at less than 30 lines of shell script.
it – The original tosser. it can send one file per session. ft – The improved tosser. ft is backwards compatible with it, can send multiple files, and resume interrupted transfers. Things should be made as simple as possible – but no simpler.
it protocol:
ft protocol:
Both protocols require an 8-bit clean connection like the one provided by ssh(1) or nc(1). telnet(1) is not 8-bit clean and will not work. Neither protocol can handle file names with embedded CRs.. but only a moron would do that.
Set up a user account for the server
adduser --disabled-password tosser
Make sure the user has the required access to read all the files you want to serve, and execute the server script.
Create an access list of files you want to serve
The format is up to you. You could use a simple list of files:
find -type f /path/to/shared/files >/home/tosser/access.list
or a list with file lengths:
find -type f /path/to/shared/files | while read fn; do echo `wc -c "$fn"`
done >/home/tosser/access.list
or even md5sums:
find -type f /path/to/shared/files | while read fn; do echo `md5sum "$fn"`
done >/home/tosser/access.list
It makes sense to include the path to the access list in the access list so that a client can download the list of files it has access to (and perhaps verify files' sizes or md5sums)
Choose a server and customize its settings
Open the server script in your favorite text editor and change the following: If you are using a simple list of files:
ACCESS_LIST="/bin/cat /home/tosser/access.list"
If you included file lengths or md5sums:
ACCESS_LIST="/usr/bin/cut -d' ' -f 2- /home/tosser/access.list"
Trigger the server from inetd or ssh
If you want to provide access to the server over a simple TCP connection with only network-level security, add a line like the following to /etc/inetd.conf:
12345 stream tcp nowait tosser /usr/sbin/tcpd /path/to/server
Use whatever port is convenient.
If you want real security, generate some ssh keys for the clients that will be accessing your server and add a line for each client to /home/tosser/.ssh/authorized_keys like the following:
command="/path/to/server",no-port-forwarding,no-X11-forwarding (ssh public key)
to allow ssh(1) RSA login but keep password login disabled you need to edit /etc/shadow and change the tosser line that starts with:
tosser:!: ...
to:
tosser:*: ...
I don't use anything fancy at the moment, although I may write a tosser browser with my Urwid UI library and Speedometer code at some point.
To download the latest index of files from an inetd(8) tosser server:
echo /home/tosser/access.list | nc host port > access.list
or from an sshd(8) tosser server:
echo /home/tosser/access.list | ssh -i tosser_key tosser@host > access.list
To fetch a file from an inetd(8) tosser server:
echo /path/to/file_i_want | nc port host > dest_file
or from an sshd(8) tosser server:
echo /path/to/file_i_want | ssh -i tosser_key tosser@host > dest_file
Zygo Blaxell - for the original idea I expanded upon