File: help

package info (click to toggle)
qpsmtpd 0.84-9
  • links: PTS
  • area: main
  • in suites: wheezy
  • size: 1,376 kB
  • sloc: perl: 8,012; sh: 382; makefile: 61
file content (145 lines) | stat: -rw-r--r-- 3,918 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
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