Hanno Hecker wrote:
Yes, it's the wrong place for creating connections to a DB. Maybe you
haven't seen it yet, this is from my (upcoming) plugin doc
(http://ankh-morp.org/~vetinari/tmp/plugins.pdf -> chapter 2.1)
I've been looking for something like this. Please allow me to make some
comments as I work through the document:
1. Why such huge margins?
2. While your "most simple plugin" at the bottom of page 1 is indeed
working, it's not very useful as a starting point, because it disables
the server and as such it's too invasive for playing around with.
3. You go on to describe init(), register(), and a little later logging,
and my first attempts were
sub init {
my ( $self, $qp, @args ) = @_;
$self->log( LOGINFO, "TEST: message 0" ); # DOESN'T WORK!
}
and
sub register {
my ( $self, $qp, %args ) = @_;
$self->log( LOGINFO, "TEST: message 1" ); # DOESN'T WORK!
}
Unfortunately, both don't work -- apparently, log() is not functional
from init() and register().
4. BTW, under "2.4 Logging" you list $self->pq->log() , but
$self->log() seems to be correct.
5. In the end I got to
sub hook_connect {
my ( $self, $transaction ) = @_;
$self->log( LOGINFO, "TEST: message 2" ); # OK
return ( DECLINED );
}
which finally looks like a useful starting point for further exploration.
6. Under "2.5 Information about the current plugin" you list a number of
methods, but plugin_name() is the only one I can get to work.
hook_name(), auth_user(), and auth_mechanism() cause the error message:
FATAL PLUGIN ERROR: Undefined subroutine
&Qpsmtpd::Plugin::myown::test_plugin
7. In "3 Return codes" you write that "plugins are run in the order they
are listed in the plugins configuration." Does that mean each one
receives the init() call, then each one the register() call, then each
one hook_pre_connection(), etc.?
8. You also write "generally all plugins for a hook are processed until
one returns something other than DECLINED." I'd suggest to make this
stronger, such as "unless you want keep other plugins from being
processed for this hook, you should return DECLINED."
9. In "4.5 hook_mail" you write "According to the SMTP protocol, you can
not reject an 'invalid' sender until after the RCPT stage." After some
thinking I guess this means we should either defer denying or use the
DISCONNECT variants, but never the plain ones. Adding a note to "DENY"
and "DENYSOFT" would be helpful.
10. In "4.7 hook_rcpt" I'd suggest to explain that DENY/DENYSOFT applies
only to the current recipient.
11. Under "2.2 Inheritance" I'd like to get some further information
such as what happens if the base plugin is not there, and how
inheritance affects the execution order of the hooks. Should the base
plugin be removed from the plugins config file? If not, should the
derived plugin be listed above or below its base plugin? Should the name
be given as it is returned by plugin_name() in the base plugin, or is it
its file name? Will the base plugin's init() be called automatically or
should this call be added to the sample code?
12. On page 2 you hit the unsuspecting reader with the sentences
"Because some of the callback names have characters invalid in
subroutine names, they must be translated. The current translation
routine is s/\W/_/g;."
This text is taken from README.plugins, and from the context there I
gather that it refers to hook names like "auth-plain" matching the
"hook_auth_plain" callback, etc. This is completely irrelevant -- either
we use the standard callback names, then we'll never need to call
register_hook(), or we use our own callback names and then we don't need
to translate anything.
Without the list of hook names (some of which use dashes and others use
underscores) the two sentences are useless. They certainly don't belong
near the beginning of your document.
Thank you for putting this together -- it's a great help already, and I
hope some of my comments are useful.
Hans