File Coverage

blib/lib/Mail/Qmail/Filter/SkipQueue.pm
Criterion Covered Total %
statement 8 41 19.5
branch 0 22 0.0
condition 0 9 0.0
subroutine 3 5 60.0
pod 1 1 100.0
total 12 78 15.3


line stmt bran cond sub pod time code
1 1     1   763 use 5.014;
  1         3  
2 1     1   4 use warnings;
  1         2  
  1         39  
3              
4              
5             our $VERSION = '1.01';
6              
7             use Mo qw(coerce);
8 1     1   4 extends 'Mail::Qmail::Filter';
  1         1  
  1         5  
9              
10             my $self = shift;
11             my $message = $self->message;
12 0     0 1    
13 0           require Qmail::Deliverable and Qmail::Deliverable->import('dot_qmail')
14             unless defined &dot_qmail;
15 0 0 0        
16             my $dot_qmail;
17             for ( $message->to ) {
18 0           my $_dot_qmail = dot_qmail($_)
19 0           or return $self->debug( 'No .qmail file found for rcpt' => $_ );
20 0 0         $self->debug( 'using file' => $_dot_qmail );
21             return $self->debug('Delivery to different .qmail files not supported')
22 0           if defined $dot_qmail && $_dot_qmail ne $dot_qmail;
23 0 0 0       $dot_qmail = $_dot_qmail;
24             }
25 0            
26             open my $fh, '<', $dot_qmail
27             or return $self->debug( "Cannot read $dot_qmail", $! );
28 0 0          
29             my @commands;
30             while ( defined( my $line = <$fh> ) ) {
31 0           next if /^#/;
32 0           chomp $line;
33 0 0         if ( $line !~ /^\|/ ) {
34 0           $self->debug( 'Delivery method not supported', $line );
35 0 0         }
36 0           else {
37             push @commands, $line;
38             }
39 0           }
40              
41             local $ENV{SENDER} = $message->from;
42             for (@commands) {
43 0           require Capture::Tiny and Capture::Tiny->import('capture_merged')
44 0           unless defined &capture_merged;
45 0 0 0       my ( $output, $exitcode ) = capture_merged(
46             sub {
47             open my $fh, $_ or return $self->debug( "Cannot start $_", $! );
48             print $fh $message->body;
49 0 0   0     close $fh;
50 0           $?;
51 0           }
52 0           );
53             $output = join '/', split /\n/, $output;
54 0           $exitcode >>= 8;
55 0           $self->debug( qq("$_" returned with exit code $exitcode) => $output );
56 0           next if $exitcode == 0;
57 0           last if $exitcode == 99;
58 0 0         $self->reject($output) if $exitcode == 100;
59 0 0         return;
60 0 0         }
61 0            
62             $self->debug( action => 'delivered' );
63             }
64 0            
65             1;
66              
67              
68             =head1 NAME
69              
70             Mail::Qmail::Filter::SkipQueue -
71             deliver message using external commands
72              
73             =head1 SYNOPSIS
74              
75             use Mail::Qmail::Filter;
76            
77             Mail::Qmail::Filter->new->add_filter(
78             '::SkipQueue',
79             )->run;
80              
81             =head1 DESCRIPTION
82              
83             This L<Mail::Qmail::Filter> plugin tries to find the appropriate C<.qmail> file
84             for all recipients and pipes the message to any command lines listed in those
85             files.
86             That is, it tries to deliver the message itself, circumventing C<qmail-local>.
87             The usual rules for exit codes from the programs called apply.
88             Other delivery methods, namely maildir or mbox lines, are not supported
89             and will be skipped.
90              
91             =head1 DISCLAIMER
92              
93             This plugin is considered experimental.
94             I implemented it as a proof-of-concept when developing
95             L<Mail::Qmail::Filter::CheckDeliverability>.
96             I do not recommend to use it a production environment.
97              
98             =head1 SEE ALSO
99              
100             L<Mail::Qmail::Filter/COMMON PARAMETERS FOR ALL FILTERS>,
101             L<Mail::Qmail::Filter::CheckDeliverability>
102              
103             =head1 LICENSE AND COPYRIGHT
104              
105             Copyright 2019 Martin Sluka.
106              
107             This module is free software; you can redistribute it and/or modify it
108             under the terms of the the Artistic License (2.0). You may obtain a
109             copy of the full license at:
110              
111             L<http://www.perlfoundation.org/artistic_license_2_0>
112              
113             Any use, modification, and distribution of the Standard or Modified
114             Versions is governed by this Artistic License. By using, modifying or
115             distributing the Package, you accept this license. Do not use, modify,
116             or distribute the Package, if you do not accept this license.
117              
118             If your Modified Version has been derived from a Modified Version made
119             by someone other than you, you are nevertheless required to ensure that
120             your Modified Version complies with the requirements of this license.
121              
122             This license does not grant you the right to use any trademark, service
123             mark, tradename, or logo of the Copyright Holder.
124              
125             This license includes the non-exclusive, worldwide, free-of-charge
126             patent license to make, have made, use, offer to sell, sell, import and
127             otherwise transfer the Package with respect to any patent claims
128             licensable by the Copyright Holder that are necessarily infringed by the
129             Package. If you institute patent litigation (including a cross-claim or
130             counterclaim) against any party alleging that the Package constitutes
131             direct or contributory patent infringement, then this Artistic License
132             to you shall terminate on the date that such litigation is filed.
133              
134             Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER
135             AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
136             THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
137             PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY
138             YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR
139             CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR
140             CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE,
141             EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
142              
143             =cut