# # 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_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.