Author: vetinari
Date: Fri Dec  7 01:15:00 2007
New Revision: 827

Added:
   trunk/plugins/help

Log:
add help plugin, hooking the new hook_help

Added: trunk/plugins/help
==============================================================================
--- (empty file)
+++ trunk/plugins/help  Fri Dec  7 01:15:00 2007
@@ -0,0 +1,145 @@
+#
+#
+#
+
+=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 {
+    my ($self,$qp,%args) = @_;
+    my ($file, $cmd);
+    unless (%args) {
+        $config{help_dir} = './help/';
+    }
+    foreach (keys %args) {
+        /^(\w+)$/ or
+            $self->log(LOGWARN, "Invalid argument for the 'help' plugin $_"), 
+            next;
+        $cmd = $1;
+        if ($cmd eq 'not_implemented') {
+            $config{'not_implemented'} = $args{'not_implemented'};
+        }
+        elsif ($cmd eq 'help_dir') {
+            $file = $args{$cmd};
+            $file =~ m#^([\w\.\-/]+)$#
+              or $self->log(LOGERROR, 
+                            "Invalid charachters in filename for command 
$cmd"),
+                next; 
+            $config{'help_dir'} = $1;
+        }
+        else {
+            $file = $args{$cmd};
+            $file =~ m#^([\w\.\-/]+)$#
+              or $self->log(LOGERROR, 
+                            "Invalid charachters in filename for command 
$cmd"),
+                 next;
+            $file = $1;
+            if ($file =~ m#/#) {
+                -e $file 
+                  or $self->log(LOGWARN, "No help file for command '$cmd'"),
+                     next;
+            }
+            else {
+                $file = "help/$file";
+                if (-e "help/$file") { ## FIXME: path
+                    $file = "help/$file";
+                } 
+                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];
+
+    unless ($cmd =~ /^(\w+)$/) { # else someone could request 
+                                 # "HELP ../../../../../../../../etc/passwd"
+        $self->qp->respond(502, "Invalid command name");
+        return DONE;
+    }
+    $cmd = $1;
+
+    if (exists $config{$cmd}) {
+        $help = read_helpfile($config{$cmd}, $cmd)
+            or $self->log(LOGERROR, "failed to open help file for $cmd: $!"),
+               return OK, "No help available for SMTP command: $cmd";
+    }
+    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";
+    }
+    $help = "No help available for SMTP command: $cmd" # empty file
+      unless $help;
+    return OK, split(/\n/, $help);
+}
+
+sub read_helpfile {
+    my ($file,$cmd) = @_;
+    my $help;
+    open HELP, $file
+        or return undef;
+    { 
+        local $/ = undef;
+        $help = <HELP>;
+    };
+    close HELP;
+    return $help;
+}
+
+# vim: ts=4 sw=4 expandtab syn=perl

Reply via email to