File Coverage

blib/lib/Mail/IspMailGate/Filter.pm
Criterion Covered Total %
statement 68 90 75.5
branch 20 38 52.6
condition 4 9 44.4
subroutine 8 13 61.5
pod 8 9 88.8
total 108 159 67.9


line stmt bran cond sub pod time code
1             # -*- perl -*-
2             #
3              
4             require 5.004;
5 11     11   6245 use strict;
  11         25  
  11         14276  
6              
7              
8             package Mail::IspMailGate::Filter;
9              
10             $Mail::IspMailGate::Filter::VERSION = "1.000";
11              
12 0     0 1 0 sub getSign { "X-ispMailGateFilter"; };
13              
14             #####################################################################
15             #
16             # Name: new
17             #
18             # Purpse: Filter constructor
19             #
20             # Inputs: $class - This class
21             # $attr - hash ref to the attributes
22             # 1) 'direction' : 'pos' for the positive direction
23             # 'neg' for the negative direction
24             #
25             # Returns: Object or error message
26             #
27             #####################################################################
28              
29             sub new ($$$) {
30 9     9 1 12079 my ($class, $attr) = @_;
31 9         25 my ($self) = {};
32 9 50       47 if (ref($attr) ne 'HASH') {
33 0         0 return "Attribute reference is not a hash ref, but: " . ref($attr);
34             }
35 9         17 my ($key);
36 9         32 foreach $key (keys %$attr) {
37 8         23 $self->{$key} = $attr->{$key};
38             }
39              
40 9   33     76 bless($self, (ref($class) || $class));
41 9         61 $self;
42             }
43              
44             #####################################################################
45             #
46             # Name: filterFile
47             #
48             # Purpse: do the filter process for one file
49             #
50             # Inputs: $self - This class
51             # $attr - hash-ref to filter attribute
52             # 1. 'body'
53             # 2. 'parser'
54             # 3. 'head'
55             # 4. 'globHead' the header of the whole Mail
56             #
57             # Returns: error message, if any
58             #
59             #####################################################################
60              
61             sub filterFile ($$$) {
62 44     44 1 103 my ($self, $attr) = @_;
63 44 50       181 if (ref($attr) ne 'HASH') {
64 0         0 die "No hash ref of attributes but: " . ref($attr);
65             }
66 44         185 my ($body) = $attr->{'body'};
67 44         261 my ($ifile) = $body->path();
68 44 50       2717 if (!(-f $ifile)) {
69 0         0 return "The file $ifile does not exist";
70             }
71 44         763 '';
72             }
73              
74             #####################################################################
75             #
76             # Name: setEncoding
77             #
78             # Purpse: set a reasonable encoding type, for the filtered mail
79             #
80             # Inputs: $self - This class
81             # $entity - The entity
82             #
83             # Returns: error-message if any
84             #
85             #####################################################################
86              
87             sub setEncoding ($$$) {
88 0     0 0 0 my ($self, $entity) = @_;
89 0         0 my ($head) = $entity->head();
90              
91 0         0 '';
92             }
93              
94             #####################################################################
95             #
96             # Name: mustFilter
97             #
98             # Purpose: determines wether this message must be filtered and
99             # allowed to modify $self the message and so on
100             #
101             # Inputs: $self - This class
102             # $entity - the whole message
103             #
104             #
105             # Returns: 1 if it must be, else 0
106             #
107             #####################################################################
108              
109             sub mustFilter ($$) {
110 0     0 1 0 my($self, $entity) = @_;
111 0         0 return 1;
112             }
113              
114             #####################################################################
115             #
116             # Name: hookFilter
117             #
118             # Purpose: a function which is called after the filtering process
119             #
120             # Inputs: $self - This class
121             # $entity - the whole message
122             #
123             #
124             # Returns: errormessage if any
125             #
126             #####################################################################
127              
128             sub hookFilter ($$) {
129 0     0 1 0 my($self, $entity) = @_;
130 0         0 '';
131             }
132              
133              
134             #####################################################################
135             #
136             # Name: doFilter
137             #
138             # Purpose: does the filtering process
139             #
140             # Inputs: $self - This class
141             # $attr - a hash ref to the attributes
142             # Following things are needed !!!!
143             # 1) 'entity': a ref to the Entity object
144             # 2) 'parser': a ref to a Parser object
145             #
146             # Returns: error message, if any
147             #
148             #####################################################################
149              
150             sub doFilter ($$) {
151 14     14 1 112915 my($self, $attr) = @_;
152 14         45 my ($entity) = $attr->{'entity'};
153 14 100       93 if(!$self->mustFilter($entity)) {
154 2         12 '';
155             } else {
156 12         63 $self->recdoFilter($attr) . $self->hookFilter($entity);
157             }
158             }
159              
160              
161             #####################################################################
162             #
163             # Name: recdoFilter
164             #
165             # Purpse: does the filtering process recursively by manipulating the
166             # given entity
167             #
168             # Inputs: $self - This class
169             # $attr - a hash ref to the attributes
170             # Following things are needed !!!!
171             # 1) 'entity': a ref to the Entity object
172             # 2) 'parser': a ref to a Parser object
173             #
174             # Returns: error message, if any
175             #
176             #####################################################################
177              
178             sub recdoFilter ($$) {
179 68     68 1 230 my ($self, $attr) = @_;
180 68 50       308 if (ref($attr) ne 'HASH') {
181 0         0 die "Attributes are not a hash ref, but: " . ref($attr);
182             }
183 68         153 my ($entity) = $attr->{'entity'};
184 68         191 my ($parser) = $attr->{'parser'};
185              
186 68 100       11107 my($globHead) = exists($attr->{'globHead'}) ? $attr->{'globHead'} : $entity->head();
187            
188 68         748 my ($mult) = $entity->is_multipart();
189 68 50       30189 if (!defined($mult)) {
    100          
190 0         0 die "Could not determine if the Entity is multipart or not";
191             } elsif ($mult) {
192 24         231 my (@parts) = $entity->parts;
193 24         357 my ($part);
194 24         80 my ($retstr) = '';
195 24         63 foreach $part (@parts) {
196 56         681 my($result) = $self->recdoFilter({ 'entity' => $part,
197             'parser' => $parser,
198             'globHead' => $globHead,
199             'main' => $attr->{'main'}});
200 56 50       7513 if (defined($result)) {
201 56         502 $retstr .= $result;
202             }
203             }
204 24         508 $entity->parts(\@parts);
205 24         867 return ($retstr);
206             }
207              
208 44         190 my ($head) = $entity->head();
209 44         778 my ($sign) = $head->get($self->getSign());
210 44 50       1847 if (!defined($sign)) {
211 44         105 $sign = '';
212             }
213            
214 44         222 my ($bodyh) = $entity->bodyhandle;
215 44         497 my ($ifile);
216 44 50       602 if (!defined($ifile = $bodyh->path())) {
217 0         0 die "message body is not stored in a file";
218             }
219 44         718 my ($fattr) = { 'head' => $head,
220             'body' => $bodyh,
221             'globHead' => $globHead,
222             'parser' => $parser,
223             'main' => $attr->{'main'}};
224 44         398 my ($err) = $self->filterFile($fattr, $parser);
225 44 100       485 if ($err) {
226 6         248 return "Error filtering $ifile: $err";
227             }
228             # $self->setEncoding($entity);
229             # $head->replace($self->getSign(), $self->{'direction'});
230              
231 38         1969 '';
232             }
233              
234              
235             sub IsEq ($$) {
236 3     3 1 9 my($self, $cmp) = @_;
237 3         64 ref($self) eq ref($cmp);
238             }
239              
240              
241             package Mail::IspMailGate::Filter::InOut;
242              
243             @Mail::IspMailGate::Filter::InOut::ISA = qw(Mail::IspMailGate::Filter);
244              
245              
246             #####################################################################
247             #
248             # Name: mustFilter
249             #
250             # Purpose: Based on the filter configuration and the message
251             # header, determine whether we are running in input
252             # ('positive') or output ('negative') mode.
253             #
254             # Inputs: $self - This class
255             # $entity - the whole message
256             #
257             # Returns: TRUE is filtering must occurr, FALSE otherwise.
258             # In the former case the attribute
259             # $self->{'recDirection'} is set to either 'pos' or
260             # 'neg'.
261             #
262             #####################################################################
263              
264             sub mustFilter ($$) {
265 4     4   6 my($self, $entity) = @_;
266 4         15 my($head) = $entity->head();
267 4         38 my($sign) = $head->get($self->getSign());
268 4         97 my($direction);
269 4 50       16 if (!defined($sign)) {
270 4         15 $sign = '';
271             }
272 4 50       20 if (defined($direction = $self->{'direction'})) {
273 4 100 66     52 if (($self->{'direction'} eq $sign) ||
      33        
274             ($self->{'direction'} eq 'neg' && $sign eq '')) {
275 2         14 return 0;
276             }
277             } else {
278 0 0       0 $direction = ($sign eq 'pos') ? 'neg' : 'pos';
279             }
280 2         6 $self->{'recDirection'} = $direction;
281 2         15 1;
282             }
283              
284              
285             #####################################################################
286             #
287             # Name: hookFilter
288             #
289             # Purpse: a function which is called after the filtering process
290             #
291             # Inputs: $self - This class
292             # $entity - the whole message
293             #
294             # Returns: errormessage if any
295             #
296             #####################################################################
297              
298             sub hookFilter ($$) {
299 2     2   11 my($self, $entity) = @_;
300 2         47 my($head) = $entity->head;
301 2         42 $head->set($self->getSign(), $self->{'recDirection'});
302 2         679 delete $self->{'recDirection'};
303 2         12 '';
304             }
305              
306              
307             sub IsEq ($$) {
308 0     0     my($self, $cmp) = @_;
309 0 0         if (ref($self) eq ref($cmp)) {
310 0 0         if ($self->{'direction'}) {
311 0 0         if ($cmp->{'direction'}) {
312 0           return $self->{'direction'} eq $cmp->{'direction'};
313             }
314             } else {
315 0           return !$cmp->{'direction'};
316             }
317             }
318 0           return 0;
319             }
320              
321             1;
322              
323              
324             __END__