This is pretty long; there's design stuff towards the end so if you're at
all interested in development you might want to skim through.
>>>>> "DB" == Dave Barr <firstname.lastname@example.org> writes:
DB> I for one think that TLB should be integrated with Majordomo.
I am not completely certain that putting _all_ of TLB into Majordomo is
what people would want. It does a bit too much and it isn't small.
Unfortunately, Majordomo talks SMTP itself you lose the ability to use an
external batcher like TLB or bulk_mailer.
OK, how about making several modules and letting the Majordomo owner at the
site decide which to use? Anyway, that's more of an implementation detail.
DB> Perhaps we should start divergent source trees here and offer only bug
DB> fixes for 1.94 (1.95, etc) but start integrating TLB and the config
DB> file dump stuff now for 2.0beta tree?
I dislike the idea of diverging the trees because it can be a real pain of
both trees are changing with some rapidity. On the other hand, if one
branch is only getting small fixes it isn't a problem.
DB> Diverging source trees works well for the Linux kernel and others.
Actually Linus really doesn't like to do it; witness the agonizing over the
decision to branch 2.1. You really want to wait as long as possible before
you can branch.
I suppose the real question centers around just what we want 1.95 to be.
We really should decide this, but perhaps we need to wait and see just how
1.94 fares. We've been talking about a lot of minor features that people
want, but with the code in its current state there's only a couple of
people with the intestinal fortitude to actually add them.
Here's what I _wanted_ to do with the guts of 1.95:
Take out all of the commands (do_*) from majordomo and move them into
mj_cmds.pl or somesuch.
Remove deflist handling from each command and make it separate, so you call
commands that can take the default list as:
Remove list handling code from all commands and put it in mj_list.pl. The
idea is that you have one subroutine, add_address_to_file or something
which takes care of all of the locking issues and such. The same goes for
removing an address, checking for the presence of an address, etc. This
makes it really easy to have a command that, say, removes a user form the
main list and puts them on the digest list (or the nomail list) or adds a
secondary allowed address for a poster (for restrict_post checks) or
I decided to stop there. This isn't really all that much work, and the
mj_list.pl stuff lets you write a quick command line subscribe-unsubscribe
tool (which acts as a nice proof of concept).
When I actually got into this, though, I found that I kept wanting to do
more. I wrote up some documentation on how I might want the command
processing engine to work. I tried to come up with something where you
could write a command and tell the system what kind of arguments it needs
and have it work without having to rewrite the top-level interface. In
other words, the email interface would know how to deal with it and could
put it automatically in a help file, while the Web interface would know
what kind of buttons to put up and such. Here's a set of rough notes I
took. Keep in mind that I was still thinking perl4 compatibility (i.e. get
this into 1.95) then. I'm not now, as I understand that this should be 2.0
stuff. Please feel free to comment; I'm not attached to any of this.
Have a list of commands that are legal.
For each command, have of argument_checking function names, a list of
pre-functions and a list of post_functions.
The args need to be well defined, so an interface can tell what is required
and parse arguments, put up buttons, whatever.
For each function, a (faked) list of parameters:
@legal_commands = ("subscribe", "list_name\001email_address");
# subscribe takes a list_name and an email_address.
Arguments are checked by a function like:
Perhaps there could be additional structures that define exactly what kind
of data is expected for each (string, switch, password); this could be
useful for a web, tk, or curses interface.
A big problem is commands that take variable numbers of arguments. One way
is to allow unchecked arguments, which are just passed on. Another is to
allow a list of alternates. (For perl4 compatability separate alternates
by \002, for perl5 only, use a list of lists.)
Another problem is commands that eat the rest of the file as input, like
newconfig. Provide for this with an "argument", multi_line, which would
tell the email interface to eat te rest of the input and perhaps tell
another interface to open a multiline text entry widget.
Additional lists, pre_COMMAND and post_COMMAND, contain names of functions
that should be executed before and after COMMAND is executed. They will
receive the same argument list that COMMAND receives; that is, the user
input will have been pre-munged by the interface code into the proper form
(if necessary). OR: should these be allowed to modify the arguments in
some way? This way you could do deflist munging with a pre_command.
Remember that the internal interface doesn't get to use the filehandles
that the external interface has (it might not be running on the same
machine), so it just can't assume it can read stuff from the incoming email
Internal interface functions are not things like "lock_file" or
"add_address_to_file", they are things lile "subscribe" and "index".
External interface, email:
Break down into functions and args as we currently do.
Check for valid_command, if not, complain.
Check arguments. Stuff them in an array, call check_arguments. Note that
we may have to supply the list name _if_ we allow a default. This is the
job of the external interface, not the internal one because the internal
subscribe doesn't care about default lists.
Thie means that valid_list_name will (probably) get called multiple times
by the email list to see if a list name was provided. Tough.
Calling conventions for internal interface functions:
Each internal interface function of course takes the arguments it requires.
The address should be one string, not a whole pile of separate strings. It
returns a list containing a numeric return code and a string (possibly
multi-line) which explains the result.
The numeric return should be 0 for failure, positive for success and
negative for tentative success (authorization required, for example).
The string returned should properly explain what has happened:
"Subscribe to list $list_name succeeded."
"Your request to $whoami:\n
$command $list_name $email_address\n
must be authenticated. [...]"
This string should be appropriate for all interfaces.
%legal_commands = (
# approve is probably a special case in that it's only useful for the email
# interface. Other interfaces will have different methods of authorizing
# admin stuff. This is an example of how an interface can add its own
# Aargh, no way to easily append to a hash!
%legal_commands = (