2012-04-29 10:35:59 +02:00
|
|
|
#!perl -w
|
2007-12-07 10:15:00 +01:00
|
|
|
|
|
|
|
=head1 NAME
|
|
|
|
|
|
|
|
help - default help plugin for qpsmtpd
|
|
|
|
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
|
|
|
|
The B<help> plugin gives the answers for the help command. It can be configured
|
|
|
|
to return C<502 Not implemented>.
|
|
|
|
|
|
|
|
Without any arguments, the C<help_dir> is set to F<./help/>.
|
|
|
|
|
|
|
|
=head1 OPTIONS
|
|
|
|
|
|
|
|
=over 4
|
|
|
|
|
|
|
|
=item not_implemented (1|0)
|
|
|
|
|
|
|
|
If this option is set (and the next argument is true), the plugin answers,
|
|
|
|
that the B<HELP> command is not implemented
|
|
|
|
|
|
|
|
=item help_dir /path/to/help/files/
|
|
|
|
|
|
|
|
When a client requests help for C<COMMAND> the file F</path/to/help/files/
|
|
|
|
. lc(COMMAND)> is dumped to the client if it exists.
|
|
|
|
|
|
|
|
=item COMMAND HELPFILE
|
|
|
|
|
|
|
|
Any other argument pair is treated as command / help file pair. The file is
|
|
|
|
expexted in the F<help/> sub directory. If the client calls C<HELP COMMAND>
|
|
|
|
the contents of HELPFILE are dumped to him.
|
|
|
|
|
|
|
|
=back
|
|
|
|
|
|
|
|
=head1 NOTES
|
|
|
|
|
|
|
|
The hard coded F<help/> path should be changed.
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
my %config = ();
|
|
|
|
|
|
|
|
sub register {
|
2013-04-21 06:50:39 +02:00
|
|
|
my ($self, $qp, %args) = @_;
|
2007-12-07 10:15:00 +01:00
|
|
|
my ($file, $cmd);
|
|
|
|
unless (%args) {
|
|
|
|
$config{help_dir} = './help/';
|
|
|
|
}
|
|
|
|
foreach (keys %args) {
|
2013-04-21 06:50:39 +02:00
|
|
|
/^(\w+)$/
|
|
|
|
or $self->log(LOGWARN, "Invalid argument for the 'help' plugin $_"),
|
|
|
|
next;
|
2007-12-07 10:15:00 +01:00
|
|
|
$cmd = $1;
|
|
|
|
if ($cmd eq 'not_implemented') {
|
|
|
|
$config{'not_implemented'} = $args{'not_implemented'};
|
|
|
|
}
|
|
|
|
elsif ($cmd eq 'help_dir') {
|
|
|
|
$file = $args{$cmd};
|
|
|
|
$file =~ m#^([\w\.\-/]+)$#
|
2013-04-21 06:50:39 +02:00
|
|
|
or $self->log(LOGERROR,
|
2007-12-07 10:15:00 +01:00
|
|
|
"Invalid charachters in filename for command $cmd"),
|
2013-04-21 06:50:39 +02:00
|
|
|
next;
|
2007-12-07 10:15:00 +01:00
|
|
|
$config{'help_dir'} = $1;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$file = $args{$cmd};
|
|
|
|
$file =~ m#^([\w\.\-/]+)$#
|
2013-04-21 06:50:39 +02:00
|
|
|
or $self->log(LOGERROR,
|
2007-12-07 10:15:00 +01:00
|
|
|
"Invalid charachters in filename for command $cmd"),
|
2013-04-21 06:50:39 +02:00
|
|
|
next;
|
2007-12-07 10:15:00 +01:00
|
|
|
$file = $1;
|
|
|
|
if ($file =~ m#/#) {
|
2013-04-21 06:50:39 +02:00
|
|
|
-e $file
|
2007-12-07 10:15:00 +01:00
|
|
|
or $self->log(LOGWARN, "No help file for command '$cmd'"),
|
2013-04-21 06:50:39 +02:00
|
|
|
next;
|
2007-12-07 10:15:00 +01:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
$file = "help/$file";
|
2013-04-21 06:50:39 +02:00
|
|
|
if (-e "help/$file") { ## FIXME: path
|
2007-12-07 10:15:00 +01:00
|
|
|
$file = "help/$file";
|
2013-04-21 06:50:39 +02:00
|
|
|
}
|
2007-12-07 10:15:00 +01:00
|
|
|
else {
|
|
|
|
$self->log(LOGWARN, "No help file for command '$cmd'");
|
|
|
|
next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$config{lc $cmd} = $file;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return DECLINED;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub hook_help {
|
|
|
|
my ($self, $transaction, @args) = @_;
|
|
|
|
my ($help, $cmd);
|
|
|
|
|
|
|
|
if ($config{not_implemented}) {
|
|
|
|
$self->qp->respond(502, "Not implemented.");
|
|
|
|
return DONE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return OK, "Try 'HELP COMMAND' for getting help on COMMAND"
|
|
|
|
unless $args[0];
|
|
|
|
|
|
|
|
$cmd = lc $args[0];
|
|
|
|
|
2013-04-21 06:50:39 +02:00
|
|
|
unless ($cmd =~ /^(\w+)$/) { # else someone could request
|
|
|
|
# "HELP ../../../../../../../../etc/passwd"
|
2007-12-07 10:15:00 +01:00
|
|
|
$self->qp->respond(502, "Invalid command name");
|
|
|
|
return DONE;
|
|
|
|
}
|
|
|
|
$cmd = $1;
|
|
|
|
|
|
|
|
if (exists $config{$cmd}) {
|
|
|
|
$help = read_helpfile($config{$cmd}, $cmd)
|
2013-04-21 06:50:39 +02:00
|
|
|
or $self->log(LOGERROR, "failed to open help file for $cmd: $!"),
|
|
|
|
return OK, "No help available for SMTP command: $cmd";
|
2007-12-07 10:15:00 +01:00
|
|
|
}
|
2013-04-21 06:50:39 +02:00
|
|
|
elsif (exists $config{'help_dir'} && -e $config{'help_dir'} . "/$cmd") {
|
|
|
|
$help = read_helpfile($config{help_dir} . "/$cmd", $cmd)
|
|
|
|
or $self->log(LOGERROR, "failed to open help file for $cmd: $!"),
|
|
|
|
return OK, "No help available for SMTP command: $cmd";
|
2007-12-07 10:15:00 +01:00
|
|
|
}
|
2013-04-21 06:50:39 +02:00
|
|
|
$help = "No help available for SMTP command: $cmd" # empty file
|
2007-12-07 10:15:00 +01:00
|
|
|
unless $help;
|
|
|
|
return OK, split(/\n/, $help);
|
|
|
|
}
|
|
|
|
|
|
|
|
sub read_helpfile {
|
2013-04-21 06:50:39 +02:00
|
|
|
my ($file, $cmd) = @_;
|
2007-12-07 10:15:00 +01:00
|
|
|
my $help;
|
|
|
|
open HELP, $file
|
2013-04-21 06:50:39 +02:00
|
|
|
or return undef;
|
|
|
|
{
|
2007-12-07 10:15:00 +01:00
|
|
|
local $/ = undef;
|
|
|
|
$help = <HELP>;
|
|
|
|
};
|
|
|
|
close HELP;
|
|
|
|
return $help;
|
|
|
|
}
|
|
|
|
|