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

Reply via email to