Roadmap for the version 1.2 release
-----------------------------------

Changes marked with (*) would be incompatible with current back-ends
and could require a degree of rewriting.

Bug fixing
----------

See the TODO file for a list of current bugs which need to be fixed.

Max users and classes of users (wu-ftpd)
----------------------------------------

Add support for classes of users, and allow the maximum number of
users to be set globally (as now) and per-class. Add a flag which
stops a particular user from logging in more than once (again, per
user, per class or globally).

[Implementation complete]

The current "max clients" configuration option will be preserved
and extended so that you can also specify the maximum number of
clients in a class or for a particular user:

max clients: 100		  # global max. clients
max clients: 10 class anonymous	  # only 10 anonymous clients allowed
max clients: 1 each class users   # each person in "users" can log in
				  # only once (no limit on max users, however)
max clients: 2 user pete,rich     # pete and rich can only log in twice

In all cases, the most restrictive rule is the one which wins (ie.
each rule is checked, and all must be OK before a person is allowed
to log in).

The user's current class name will be available in the
$ftps->{class} variable, and will also be made available
to the appropriate access control rules.

The actual implementation will need to use a shared file to
store the state of each connection. The file is stored on local
disk, and will be locked using the POSIX fcntl interface [BSD?].
The same shared file can also store quotas, credits, etc.

A "SITE WHO" command can be added, compatible with glftpd, which
lists all users logged in. It will be worthwhile restricting this
command to just a specific class or classes of users by using
advanced command filters (see below).

[ => See sharedstate.txt ]

Upload and download quotas and credits (glftpd)
-----------------------------------------------

Implement a system of quotas and credits for users, classes.

Implementation:

XXXXXXXXX







Bandwidth throttling (glftpd)
-----------------------------

Allow upload & download bandwidth to be throttled, per user, per class
and/or globally.

Implementation:

Because of the complexity of implementation, it will not be
possible to throttle traffic across several FTP connections.
ie. If you apply a 10 kbps limit to class "users", then each
user will be able to use up to 10 kbps EACH, NOT all people in
class "users" will together be limited to 10 kbps across
all connections.

Also, throttling will only affect the Data connection, not
the Control connection.

A new "throttle bandwidth" configuration option will be added:

throttle bandwidth: 20 kbps user rich    # "rich" can use 20 kbps
throttle bandwidth: 10 kbps class users  # each user throttled to 10 kbps
throttle bandwidth: 100 kbps             # no user is allowed > 100 kbps

The rules are evaluated in order until one matches. That is the
rule which is used.

NB. bps == bits/second; Bps == Bytes/second; kbps == 1024 bits/second;
KBps == 1024 Bytes/second == 8192 bits/second; mbps == 1048576
bits/second; MBps == 8388608 bits/second.

The implementation is fairly simple: just a few more modifications
to _RETR_command and _store, and some careful timing.



XXX Perl evaluation ???




Hooks, scripts, delegation and modules (*)
--------------------------------------

The current system for implementing the VFS through object inheritance
is good and will stay.

However, there are some hooks which it would be nice to override
without having to create an entire personality. I'm thinking of things
like pre_configuration_hook, quit_hook and so on. It would also be
nice to be able to trigger the running of an external script in places
(perhaps an external shell script, or a Perl script evaluated inside
the server itself). Furthermore it would be nice to be able to chain
hooks so that several independent actions could be performed on, say,
a quit event.

It seems that for these hooks, the current system of using object
inheritance isn't the best method. Instead I would like to replace it
with some form of loadable modules. It would work something like this:

<configuration file>

quit hook: /usr/lib/scripts/quit.pl

[or]

quit hook: { perl code ... }

[or]

load module: /usr/lib/modules/feature.pl

</configuration file>

(A module could override several hooks, and you could load several
modules and each would be called in turn for a particular hook).

This is the current complete list of hooks:

  pre_configuration_hook
  options_hook
  post_configuration_hook
  post_bind_hook
  pre_accept_hook
  post_accept_hook
  access_control_hook
  process_limits_hook
  authentication_hook
  user_login_hook
  root_directory_hook
  pre_command_hook
  command_filter_hook
  transfer_hook        [*]
  post_command_hook
  pre_store_hook       [*]
  post_store_hook      [*]
  pre_retrieve_hook    [*]
  post_retrieve_hook   [*]
  system_error_hook
  quit_hook

[ => modules.txt ]

Upload and download hooks
-------------------------

Add hooks which are called when a complete file has been uploaded or
downloaded. You could use this hook, for example, to email the
administrator after a file has been uploaded, or to check the MD5 sum
of an uploaded file to ensure it isn't corrupt.

Sort out log files and xferlogs
-------------------------------

Currently we have several different and competing forms of logging.
In some places, we log the same event to no fewer than 3 different
places! This needs to be sorted out.

Make error logs required rather than optional.

Global exit function, END block
-------------------------------

Replace direct calls to CORE::exit with calls to $self->exit which
allows meaningful action to be taken in all cases where the server
exits. This might be implemented instead (or in addition) with a
global END block in the core server.

Advanced command filters
------------------------

Current "command filter" is fairly useless for several reasons.
I suggest that we keep it for backwards compatibility, but
deprecate it. In its place, add an advanced filtering
functionality based on classes and users.

Implementation:

restrict command: "SITE WHO" $class eq "users" || $user eq "rich"

... would allow for everyone in class "users" plus user "rich", but
deny for everyone else.

restrict command: "SITE EXEC" $class eq "staff"

... would allow for only "staff", and deny for everyone else.

Command names are matched case insensitively, with a single
space matching any number of whitespace characters.

The default for all commands is to allow for all.

[Implementation complete.]

Archive mode
------------

Complete this feature, including support for Tar-format downloads.

Archive filters and generators can be implemented as loadable modules.

Add PGP encryption filters for downloads, and, if possible, uploads.
I don't have the resources to do a full SSL implementation, and this
should satisfy most requirements.

Better handling of symbolic links
---------------------------------

Symbolic links are not handled very well at the moment. The code
has a lot of places which does stuff like this:

 my ($type) = $fileh->status;
 if ($type eq 'f') { do something }
 elsif ($type eq 'd') { do something else }
 else { don't really know what to do ... }

There is also a lot of confusion over stat vs. lstat.

Symbolic links should be recognized as a separate type equal in
importance to files and directories.

[ Long listings now work correctly. However there is still a lot of
code to review to fix the above problem.]

License, (C) copyright changes
------------------------------

The core server, and the personalities and modules distributed with it
will remain GPL.

However, I would like to modify the license slightly to make it clear
that people may implement their own personalities, and those may
remain closed source, if they wish. The same would apply to modules
that people might want to write. Currently, this is implied, but not
stated anywhere.

The copyright of the server will be broadened to include all current
and former contributors explicitly. This will ensure the continued
freedom of the code by making it harder for one company to retake
ownership of the code.
