#
# read this with 'perldoc README.plugins'  ...
#

=head1 qpsmtpd plugin system; developer documentation

See the examples in plugins/ and ask questions on the qpsmtpd
mailinglist; subscribe by sending mail to qpsmtpd-subscribe@perl.org.

=head1 General return codes

Each plugin must return an allowed constant for the hook and (usually)
optionally a "message".

Generally all plugins for a hook are processed until one returns
something other than "DECLINED".

Plugins are run in the order they are listed in the "plugins"
configuration.

=over 4

=item OK

Action allowed

=item DENY

Action denied

=item DENYSOFT

Action denied; return a temporary rejection code (say 450 instead of 550).

=item DENYHARD

Action denied; return a permanent rejection code and disconnect the client.
Use this for "rude" clients.

=item DECLINED

Plugin declined work; proceed as usual.  This return code is _always_
_allowed_ unless noted otherwise.

=item DONE

Finishing processing of the request.  Usually used when the plugin
sent the response to the client.

=back

See more detailed description for each hook below.

=head1 Hooks

=head2 mail

Called right after the envelope sender address is passed.  The plugin
gets passed a Mail::Address object.  Default is to allow the
recipient.

Allowed return codes

  OK       - sender allowed
  DENY     - Return a hard failure code
  DENYSOFT - Return a soft failure code
  DENYHARD - Return a hard failure code and disconnect
  DONE     - skip further processing


=head2 rcpt

Hook for the "rcpt" command.  Defaults to deny the mail with a soft
error code.

Allowed return codes

  OK       - recipient allowed
  DENY     - Return a hard failure code
  DENYSOFT - Return a soft failure code
  DENYHARD - Return a hard failure code and disconnect
  DONE     - skip further processing

=head2 data

Hook for the "data" command.  Defaults to '354, "go ahead"'.

  DENY     - Return a hard failure code
  DENYSOFT - Return a soft failure code
  DENYHARD - Return a hard failure code and disconnect
  DONE     - Plugin took care of receiving data and calling the queue (not
             recommended)

=head2 data_post

Hook after receiving all data; just before the message is queued.

  DENY     - Return a hard failure code
  DENYSOFT - Return a soft failure code
  DENYHARD - Return a hard failure code and disconnect
  DONE     - skip further processing (message will not be queued)

All other codes and the message will be queued normally

=head2 queue

Called on completion of the DATA command.

   DONE     - skip further processing (plugin gave response code)
   OK       - Return success message 
   DENY     - Return hard failure code
   DENYSOFT - Return soft failure code
  DENYHARD - Return a hard failure code and disconnect

Any other code will return a soft failure code.


=head2 connect

Allowed return codes:

  OK       - Stop processing plugins, give the default response
  DECLINED - Process the next plugin
  DONE     - Stop processing plugins and don't give the default response


=head2 quit

Called on the "quit" command.

Allowed return codes:

  DONE 

Works like the "connect" hook.

=head2 helo

Called on "helo" from the client.

  DENY - Return a 550 code
  DENYSOFT - Return a 450 code
  DENYHARD - Return a hard failure code and disconnect
  DONE - Qpsmtpd won't do anything; the plugin sent the message
  DECLINED - Qpsmtpd will send the standard HELO message


=head2 unrecognized_command

Called when we get a command that isn't recognized.

  DENY - Return 521 and disconnect the client
  DONE - Qpsmtpd won't do anything; the plugin responded 
  Anything else - Return '500 Unrecognized command'

=head2 disconnect

Called just before we shutdown a connection.

The return code is ignored.  If a plugin returns anything but DECLINED
the following plugins will not be run (like with all other hooks).

=head2 deny

Called when another hook returns DENY or DENYSOFT.  First parameter is
the previous hook return code; the second parameter the message the
hook returned. 

Returning DONE or OK will stop the next deny hook from being run.
DECLINED will make qpsmtpd run the remaining configured deny hooks.

=head2 vrfy

Hook for the "VRFY" command.  Defaults to returning a message telling
the user to just try sending the message.

Allowed return codes:

   OK       - Recipient Exists
   DENY     - Return a hard failure code
   DONE     - Return nothing and move on
   Anything Else - Return a 252

=head1 Return Values and Notes

Insert stuff here about how:

    - if we're in a transaction, the results of a callback are stored
in
    $self->transaction->notes( $code->{name})->{"hook_$hook"}->{return}

    - if we're in a connection, store things in the connection notes instead.


=head1 Include Files

(put more about how the $Include stuff works here)

With the $Include stuff you order using the filename of the plugin.d
file. So if you have a plugin called xyz but want it to come early on,
you call it's config file 00_xyz, but that file still refers to the
plugin called xyz.

=head1 Temporary Files

The temporary file and directory functions can be used for plugin specific
workfiles and will automatically be deleted at the end of the current
transaction.

=over 4

=item temp_file()

Returns a unique name of a file located in the default spool directory, but
does not open that file (i.e. it is the name not a file handle).

=item temp_dir()

Returns the name of a unique directory located in the default spool
directory, after creating the directory with 0700 rights.  If you need a
directory with different rights (say for an antivirus daemon), you will
need to use the base function $self->qp->temp_dir() which takes a single
parameter for the permissions requested (see L<mkdir> for details).  A
directory created like this will B<not> be deleted when the transaction is
ended.

=item spool_dir()

Returns the configured system-wide spool directory.

=back