Documentation is not quite finished yet.

pyftpd is a is a multiplatform (currently tested only on linux, solaris,
hp/ux and windows95/98/2000) ftp daemon written in python. It can work
under normal user account and does not require any special rights to
start. Thanks to the modular design, there are possible many different
authentification schemes, most notably anonymous user authentification,
authentification from internal database of users (these are virtual
users, independent from the operating system users), and
authentification against PAM[1].

pyftpd uses its own permission modules, and can pinpoint user
permissions down to a simple file and simple ftp operation.

pyftpd uses python threads; if your python interpreter was compiled
without thread support, it will use forking instead, with limited
functionality (limiting number of simultaneously logged users and some
other options won't work). If neither threads nor fork is available,
pyftpd will serve just one connection at a time.

The main pyftpd configuration is in file config.py. Configuration for
additional modules is in files modulename_configure.py. You can change
configuration either by editing appropriate file, or by running
graphical configuration tool (Tkinter required). Configuration tool for
config.py file is called configure_configure.py, configuration tools for
other modules are called configure_modulename.py. When you launch
configure_configure.py, in the window you are configuring only the list
of authentification modules (Edit button is a bit misleading - it does
not edit, but rather change the authentification module). Global options
are accessible via the Option button.

To configure individual modules, you have to run appropriate configure_*.py
scripts.

On virtual and real paths: Path to a file or directory, as seen on the
disk, is a real path. This is the path you enter in perm_acl_module.
However, path as visible to ftp clients can be mangled in some ways[2].
The mangled visible path is called virtual path, and this is the path
you enter as Initial dir or in auth_cwd_module.

On performance: pyftpd, when possible, uses multiple threads, which
means it manages the memory (which is the decisive factor when serving
many clients) in quite an efficient way. As an example, on my Debian
Linux with python 1.5.2, idle server takes 1564kB RAM, of which 588kB is
shareable with eventual other python interpreter. Each connected client
takes additional 44kB memory, and some more kB when up/downloading a
file (this is configurable via sbufsize and rbufsize options). Compare
with proftpd 1.2.0, which (in standalone mode) takes 532kB (not counting
libc and other system libraries) and each connected client takes
additional 312kB memory. Or with wu-ftpd, which takes 492kB memory, and
each connection takes additional 344kB. This is due to multithreaded
model of pyftpd, compared to forking of other daemons.

On the other hand, there is a little nice single-threaded ftp server,
using non blocking sockets and poll, called betaftpd
(http://members.xoom.com/sneeze/betaftpd-lynx.html), which takes 220kB
memory, and each connections takes additional 12kB. This shows up the
efficiency of C over python :-).



[1] It is currently not quite functioning. 

[2] Virtual directories are planned "real soon now". So far this applies 
    only to MS windows with posix path emulation turned on.
