| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
# Copyrights 2001-2023 by [Mark Overmeer ]. |
|
2
|
|
|
|
|
|
|
# For other contributors see ChangeLog. |
|
3
|
|
|
|
|
|
|
# See the manual pages for details on the licensing terms. |
|
4
|
|
|
|
|
|
|
# Pod stripped from pm file by OODoc 2.03. |
|
5
|
|
|
|
|
|
|
# This code is part of distribution Mail-Message. Meta-POD processed with |
|
6
|
|
|
|
|
|
|
# OODoc into POD and HTML manual-pages. See README.md |
|
7
|
|
|
|
|
|
|
# Copyright Mark Overmeer. Licensed under the same terms as Perl itself. |
|
8
|
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
package Mail::Message::Body::Multipart; |
|
10
|
34
|
|
|
34
|
|
934
|
use vars '$VERSION'; |
|
|
34
|
|
|
|
|
84
|
|
|
|
34
|
|
|
|
|
1846
|
|
|
11
|
|
|
|
|
|
|
$VERSION = '3.013'; |
|
12
|
|
|
|
|
|
|
|
|
13
|
34
|
|
|
34
|
|
216
|
use base 'Mail::Message::Body'; |
|
|
34
|
|
|
|
|
120
|
|
|
|
34
|
|
|
|
|
4929
|
|
|
14
|
|
|
|
|
|
|
|
|
15
|
34
|
|
|
34
|
|
260
|
use strict; |
|
|
34
|
|
|
|
|
82
|
|
|
|
34
|
|
|
|
|
824
|
|
|
16
|
34
|
|
|
34
|
|
197
|
use warnings; |
|
|
34
|
|
|
|
|
84
|
|
|
|
34
|
|
|
|
|
1102
|
|
|
17
|
|
|
|
|
|
|
|
|
18
|
34
|
|
|
34
|
|
203
|
use Mail::Message::Body::Lines; |
|
|
34
|
|
|
|
|
87
|
|
|
|
34
|
|
|
|
|
1188
|
|
|
19
|
34
|
|
|
34
|
|
211
|
use Mail::Message::Part; |
|
|
34
|
|
|
|
|
111
|
|
|
|
34
|
|
|
|
|
1215
|
|
|
20
|
|
|
|
|
|
|
|
|
21
|
34
|
|
|
34
|
|
15055
|
use Mail::Box::FastScalar; |
|
|
34
|
|
|
|
|
101
|
|
|
|
34
|
|
|
|
|
1033
|
|
|
22
|
34
|
|
|
34
|
|
228
|
use Carp; |
|
|
34
|
|
|
|
|
76
|
|
|
|
34
|
|
|
|
|
100188
|
|
|
23
|
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
sub init($) |
|
26
|
40
|
|
|
40
|
0
|
114
|
{ my ($self, $args) = @_; |
|
27
|
40
|
|
|
|
|
77
|
my $based = $args->{based_on}; |
|
28
|
40
|
100
|
66
|
|
|
257
|
$args->{mime_type} ||= defined $based ? $based->type : 'multipart/mixed'; |
|
29
|
|
|
|
|
|
|
|
|
30
|
40
|
|
|
|
|
180
|
$self->SUPER::init($args); |
|
31
|
|
|
|
|
|
|
|
|
32
|
40
|
|
|
|
|
92
|
my @parts; |
|
33
|
40
|
100
|
|
|
|
150
|
if($args->{parts}) |
|
34
|
31
|
|
|
|
|
55
|
{ foreach my $raw (@{$args->{parts}}) |
|
|
31
|
|
|
|
|
92
|
|
|
35
|
54
|
50
|
|
|
|
114
|
{ next unless defined $raw; |
|
36
|
54
|
|
|
|
|
180
|
my $cooked = Mail::Message::Part->coerce($raw, $self); |
|
37
|
|
|
|
|
|
|
|
|
38
|
54
|
50
|
|
|
|
150
|
$self->log(ERROR => 'Data not convertible to a message (type is ' |
|
39
|
|
|
|
|
|
|
, ref $raw,")\n"), next unless defined $cooked; |
|
40
|
|
|
|
|
|
|
|
|
41
|
54
|
|
|
|
|
148
|
push @parts, $cooked; |
|
42
|
|
|
|
|
|
|
} |
|
43
|
|
|
|
|
|
|
} |
|
44
|
|
|
|
|
|
|
|
|
45
|
40
|
|
|
|
|
107
|
my $preamble = $args->{preamble}; |
|
46
|
40
|
50
|
66
|
|
|
139
|
$preamble = Mail::Message::Body->new(data => $preamble) |
|
47
|
|
|
|
|
|
|
if defined $preamble && ! ref $preamble; |
|
48
|
|
|
|
|
|
|
|
|
49
|
40
|
|
|
|
|
77
|
my $epilogue = $args->{epilogue}; |
|
50
|
40
|
50
|
66
|
|
|
119
|
$epilogue = Mail::Message::Body->new(data => $epilogue) |
|
51
|
|
|
|
|
|
|
if defined $epilogue && ! ref $epilogue; |
|
52
|
|
|
|
|
|
|
|
|
53
|
40
|
100
|
|
|
|
150
|
if($based) |
|
54
|
24
|
|
33
|
|
|
112
|
{ $self->boundary($args->{boundary} || $based->boundary); |
|
55
|
|
|
|
|
|
|
$self->{MMBM_preamble} |
|
56
|
24
|
100
|
|
|
|
128
|
= defined $preamble ? $preamble : $based->preamble; |
|
57
|
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
$self->{MMBM_parts} |
|
59
|
|
|
|
|
|
|
= @parts ? \@parts |
|
60
|
24
|
100
|
66
|
|
|
98
|
: !$args->{parts} && $based->isMultipart |
|
|
|
100
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
? [ $based->parts('ACTIVE') ] |
|
62
|
|
|
|
|
|
|
: []; |
|
63
|
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
$self->{MMBM_epilogue} |
|
65
|
24
|
100
|
|
|
|
80
|
= defined $epilogue ? $epilogue : $based->epilogue; |
|
66
|
|
|
|
|
|
|
} |
|
67
|
|
|
|
|
|
|
else |
|
68
|
16
|
|
66
|
|
|
99
|
{ $self->boundary($args->{boundary} ||$self->type->attribute('boundary')); |
|
69
|
16
|
|
|
|
|
68
|
$self->{MMBM_preamble} = $preamble; |
|
70
|
16
|
|
|
|
|
50
|
$self->{MMBM_parts} = \@parts; |
|
71
|
16
|
|
|
|
|
38
|
$self->{MMBM_epilogue} = $epilogue; |
|
72
|
|
|
|
|
|
|
} |
|
73
|
|
|
|
|
|
|
|
|
74
|
40
|
|
|
|
|
216
|
$self; |
|
75
|
|
|
|
|
|
|
} |
|
76
|
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
sub isMultipart() {1} |
|
78
|
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
# A multipart body is never binary itself. The parts may be. |
|
80
|
|
|
|
|
|
|
sub isBinary() {0} |
|
81
|
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
sub clone() |
|
83
|
3
|
|
|
3
|
1
|
8
|
{ my $self = shift; |
|
84
|
3
|
|
|
|
|
9
|
my $preamble = $self->preamble; |
|
85
|
3
|
|
|
|
|
10
|
my $epilogue = $self->epilogue; |
|
86
|
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
my $body = ref($self)->new |
|
88
|
|
|
|
|
|
|
( $self->logSettings |
|
89
|
|
|
|
|
|
|
, based_on => $self |
|
90
|
|
|
|
|
|
|
, preamble => ($preamble ? $preamble->clone : undef) |
|
91
|
|
|
|
|
|
|
, epilogue => ($epilogue ? $epilogue->clone : undef) |
|
92
|
3
|
100
|
|
|
|
17
|
, parts => [ map {$_->clone} $self->parts('ACTIVE') ] |
|
|
7
|
100
|
|
|
|
35
|
|
|
93
|
|
|
|
|
|
|
); |
|
94
|
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
} |
|
96
|
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
sub nrLines() |
|
98
|
22
|
|
|
22
|
1
|
47
|
{ my $self = shift; |
|
99
|
22
|
|
|
|
|
38
|
my $nr = 1; # trailing part-sep |
|
100
|
|
|
|
|
|
|
|
|
101
|
22
|
100
|
|
|
|
56
|
if(my $preamble = $self->preamble) |
|
102
|
3
|
|
|
|
|
11
|
{ $nr += $preamble->nrLines; |
|
103
|
3
|
50
|
|
|
|
12
|
$nr++ if $preamble->endsOnNewline; |
|
104
|
|
|
|
|
|
|
} |
|
105
|
|
|
|
|
|
|
|
|
106
|
22
|
|
|
|
|
67
|
foreach my $part ($self->parts('ACTIVE')) |
|
107
|
33
|
|
|
|
|
129
|
{ $nr += 1 + $part->nrLines; |
|
108
|
33
|
100
|
|
|
|
98
|
$nr++ if $part->body->endsOnNewline; |
|
109
|
|
|
|
|
|
|
} |
|
110
|
|
|
|
|
|
|
|
|
111
|
22
|
100
|
|
|
|
103
|
if(my $epilogue = $self->epilogue) |
|
112
|
3
|
|
|
|
|
8
|
{ $nr += $epilogue->nrLines; |
|
113
|
|
|
|
|
|
|
} |
|
114
|
|
|
|
|
|
|
|
|
115
|
22
|
|
|
|
|
62
|
$nr; |
|
116
|
|
|
|
|
|
|
} |
|
117
|
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
sub size() |
|
119
|
26
|
|
|
26
|
1
|
49
|
{ my $self = shift; |
|
120
|
26
|
|
|
|
|
65
|
my $bbytes = length($self->boundary) +4; # \n--$b\n |
|
121
|
|
|
|
|
|
|
|
|
122
|
26
|
|
|
|
|
63
|
my $bytes = $bbytes +2; # last boundary, \n--$b--\n |
|
123
|
26
|
100
|
|
|
|
73
|
if(my $preamble = $self->preamble) |
|
124
|
6
|
|
|
|
|
23
|
{ $bytes += $preamble->size } |
|
125
|
20
|
|
|
|
|
42
|
else { $bytes -= 1 } # no leading \n |
|
126
|
|
|
|
|
|
|
|
|
127
|
26
|
|
|
|
|
78
|
$bytes += $bbytes + $_->size foreach $self->parts('ACTIVE'); |
|
128
|
26
|
100
|
|
|
|
80
|
if(my $epilogue = $self->epilogue) |
|
129
|
7
|
|
|
|
|
19
|
{ $bytes += $epilogue->size; |
|
130
|
|
|
|
|
|
|
} |
|
131
|
26
|
|
|
|
|
74
|
$bytes; |
|
132
|
|
|
|
|
|
|
} |
|
133
|
|
|
|
|
|
|
|
|
134
|
4
|
|
|
4
|
1
|
15
|
sub string() { join '', shift->lines } |
|
135
|
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
sub lines() |
|
137
|
4
|
|
|
4
|
1
|
8
|
{ my $self = shift; |
|
138
|
|
|
|
|
|
|
|
|
139
|
4
|
|
|
|
|
15
|
my $boundary = $self->boundary; |
|
140
|
4
|
|
|
|
|
6
|
my @lines; |
|
141
|
|
|
|
|
|
|
|
|
142
|
4
|
|
|
|
|
15
|
my $preamble = $self->preamble; |
|
143
|
4
|
50
|
|
|
|
11
|
push @lines, $preamble->lines if $preamble; |
|
144
|
|
|
|
|
|
|
|
|
145
|
4
|
|
|
|
|
13
|
foreach my $part ($self->parts('ACTIVE')) |
|
146
|
|
|
|
|
|
|
{ # boundaries start with \n |
|
147
|
8
|
100
|
|
|
|
97
|
if(!@lines) { ; } |
|
|
|
50
|
|
|
|
|
|
|
148
|
4
|
|
|
|
|
10
|
elsif($lines[-1] =~ m/\n$/) { push @lines, "\n" } |
|
149
|
0
|
|
|
|
|
0
|
else { $lines[-1] .= "\n" } |
|
150
|
8
|
|
|
|
|
37
|
push @lines, "--$boundary\n", $part->lines; |
|
151
|
|
|
|
|
|
|
} |
|
152
|
|
|
|
|
|
|
|
|
153
|
4
|
50
|
|
|
|
75
|
if(!@lines) { ; } |
|
|
|
50
|
|
|
|
|
|
|
154
|
4
|
|
|
|
|
9
|
elsif($lines[-1] =~ m/\n$/) { push @lines, "\n" } |
|
155
|
0
|
|
|
|
|
0
|
else { $lines[-1] .= "\n" } |
|
156
|
4
|
|
|
|
|
12
|
push @lines, "--$boundary--"; |
|
157
|
|
|
|
|
|
|
|
|
158
|
4
|
50
|
|
|
|
11
|
if(my $epilogue = $self->epilogue) |
|
159
|
0
|
|
|
|
|
0
|
{ $lines[-1] .= "\n"; |
|
160
|
0
|
|
|
|
|
0
|
push @lines, $epilogue->lines; |
|
161
|
|
|
|
|
|
|
} |
|
162
|
|
|
|
|
|
|
|
|
163
|
4
|
50
|
|
|
|
63
|
wantarray ? @lines : \@lines; |
|
164
|
|
|
|
|
|
|
} |
|
165
|
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
sub file() # It may be possible to speed-improve the next |
|
167
|
0
|
|
|
0
|
1
|
0
|
{ my $self = shift; # code, which first produces a full print of |
|
168
|
0
|
|
|
|
|
0
|
my $text; # the message in memory... |
|
169
|
0
|
|
|
|
|
0
|
my $dump = Mail::Box::FastScalar->new(\$text); |
|
170
|
0
|
|
|
|
|
0
|
$self->print($dump); |
|
171
|
0
|
|
|
|
|
0
|
$dump->seek(0,0); |
|
172
|
0
|
|
|
|
|
0
|
$dump; |
|
173
|
|
|
|
|
|
|
} |
|
174
|
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
sub print(;$) |
|
176
|
8
|
|
|
8
|
1
|
19
|
{ my $self = shift; |
|
177
|
8
|
|
33
|
|
|
24
|
my $out = shift || select; |
|
178
|
|
|
|
|
|
|
|
|
179
|
8
|
|
|
|
|
57
|
my $boundary = $self->boundary; |
|
180
|
8
|
|
|
|
|
15
|
my $count = 0; |
|
181
|
8
|
100
|
|
|
|
25
|
if(my $preamble = $self->preamble) |
|
182
|
2
|
|
|
|
|
16
|
{ $preamble->print($out); |
|
183
|
2
|
|
|
|
|
4
|
$count++; |
|
184
|
|
|
|
|
|
|
} |
|
185
|
|
|
|
|
|
|
|
|
186
|
8
|
50
|
|
|
|
24
|
if(ref $out eq 'GLOB') |
|
187
|
0
|
|
|
|
|
0
|
{ foreach my $part ($self->parts('ACTIVE')) |
|
188
|
0
|
0
|
|
|
|
0
|
{ print $out "\n" if $count++; |
|
189
|
0
|
|
|
|
|
0
|
print $out "--$boundary\n"; |
|
190
|
0
|
|
|
|
|
0
|
$part->print($out); |
|
191
|
|
|
|
|
|
|
} |
|
192
|
0
|
0
|
|
|
|
0
|
print $out "\n" if $count++; |
|
193
|
0
|
|
|
|
|
0
|
print $out "--$boundary--"; |
|
194
|
|
|
|
|
|
|
} |
|
195
|
|
|
|
|
|
|
else |
|
196
|
8
|
|
|
|
|
24
|
{ foreach my $part ($self->parts('ACTIVE')) |
|
197
|
13
|
100
|
|
|
|
47
|
{ $out->print("\n") if $count++; |
|
198
|
13
|
|
|
|
|
108
|
$out->print("--$boundary\n"); |
|
199
|
13
|
|
|
|
|
150
|
$part->print($out); |
|
200
|
|
|
|
|
|
|
} |
|
201
|
8
|
100
|
|
|
|
30
|
$out->print("\n") if $count++; |
|
202
|
8
|
|
|
|
|
69
|
$out->print("--$boundary--"); |
|
203
|
|
|
|
|
|
|
} |
|
204
|
|
|
|
|
|
|
|
|
205
|
8
|
100
|
|
|
|
85
|
if(my $epilogue = $self->epilogue) |
|
206
|
2
|
|
|
|
|
8
|
{ $out->print("\n"); |
|
207
|
2
|
|
|
|
|
21
|
$epilogue->print($out); |
|
208
|
|
|
|
|
|
|
} |
|
209
|
|
|
|
|
|
|
|
|
210
|
8
|
|
|
|
|
20
|
$self; |
|
211
|
|
|
|
|
|
|
} |
|
212
|
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
sub foreachLine($) |
|
215
|
0
|
|
|
0
|
1
|
0
|
{ my ($self, $code) = @_; |
|
216
|
0
|
|
|
|
|
0
|
$self->log(ERROR => "You cannot use foreachLine on a multipart"); |
|
217
|
0
|
|
|
|
|
0
|
confess; |
|
218
|
|
|
|
|
|
|
} |
|
219
|
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
sub check() |
|
221
|
0
|
|
|
0
|
1
|
0
|
{ my $self = shift; |
|
222
|
0
|
|
|
0
|
|
0
|
$self->foreachComponent( sub {$_[1]->check} ); |
|
|
0
|
|
|
|
|
0
|
|
|
223
|
|
|
|
|
|
|
} |
|
224
|
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
sub encode(@) |
|
226
|
0
|
|
|
0
|
1
|
0
|
{ my ($self, %args) = @_; |
|
227
|
0
|
|
|
0
|
|
0
|
$self->foreachComponent( sub {$_[1]->encode(%args)} ); |
|
|
0
|
|
|
|
|
0
|
|
|
228
|
|
|
|
|
|
|
} |
|
229
|
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
sub encoded() |
|
231
|
19
|
|
|
19
|
1
|
46
|
{ my $self = shift; |
|
232
|
19
|
|
|
34
|
|
162
|
$self->foreachComponent( sub {$_[1]->encoded} ); |
|
|
34
|
|
|
|
|
147
|
|
|
233
|
|
|
|
|
|
|
} |
|
234
|
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
sub read($$$$) |
|
236
|
7
|
|
|
7
|
1
|
33
|
{ my ($self, $parser, $head, $bodytype) = @_; |
|
237
|
|
|
|
|
|
|
|
|
238
|
7
|
|
|
|
|
20
|
my $boundary = $self->boundary; |
|
239
|
|
|
|
|
|
|
|
|
240
|
7
|
|
|
|
|
62
|
$parser->pushSeparator("--$boundary"); |
|
241
|
7
|
|
|
|
|
47
|
my @msgopts = $self->logSettings; |
|
242
|
|
|
|
|
|
|
|
|
243
|
7
|
|
|
|
|
18
|
my $te; |
|
244
|
7
|
100
|
100
|
|
|
28
|
$te = lc $1 |
|
245
|
|
|
|
|
|
|
if +($head->get('Content-Transfer-Encoding') || '') =~ m/(\w+)/; |
|
246
|
|
|
|
|
|
|
|
|
247
|
7
|
|
|
|
|
26
|
my @sloppyopts = |
|
248
|
|
|
|
|
|
|
( mime_type => 'text/plain' |
|
249
|
|
|
|
|
|
|
, transfer_encoding => $te |
|
250
|
|
|
|
|
|
|
); |
|
251
|
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
# Get preamble. |
|
253
|
7
|
|
|
|
|
18
|
my $headtype = ref $head; |
|
254
|
|
|
|
|
|
|
|
|
255
|
7
|
|
|
|
|
29
|
my $begin = $parser->filePosition; |
|
256
|
7
|
|
|
|
|
36
|
my $preamble = Mail::Message::Body::Lines->new(@msgopts, @sloppyopts) |
|
257
|
|
|
|
|
|
|
->read($parser, $head); |
|
258
|
|
|
|
|
|
|
|
|
259
|
7
|
100
|
|
|
|
42
|
$preamble->nrLines |
|
260
|
|
|
|
|
|
|
or undef $preamble; |
|
261
|
|
|
|
|
|
|
|
|
262
|
7
|
100
|
|
|
|
32
|
$self->{MMBM_preamble} = $preamble |
|
263
|
|
|
|
|
|
|
if defined $preamble; |
|
264
|
|
|
|
|
|
|
|
|
265
|
|
|
|
|
|
|
# Get the parts. |
|
266
|
|
|
|
|
|
|
|
|
267
|
7
|
|
|
|
|
24
|
my ($has_epilogue, @parts); |
|
268
|
7
|
|
|
|
|
23
|
while(my $sep = $parser->readSeparator) |
|
269
|
20
|
100
|
|
|
|
200
|
{ if($sep =~ m/--\Q$boundary\E--[ \t]*\n?/) |
|
270
|
|
|
|
|
|
|
{ # Per RFC 2046, a CRLF after the close-delimiter marks the presence |
|
271
|
|
|
|
|
|
|
# of an epilogue. Preserve the epilogue, even if empty, so that the |
|
272
|
|
|
|
|
|
|
# printed multipart body will also have the CRLF. |
|
273
|
|
|
|
|
|
|
# This, however, is complicated w.r.t. mbox folders. |
|
274
|
7
|
|
|
|
|
29
|
$has_epilogue = $sep =~ /\n/; |
|
275
|
7
|
|
|
|
|
16
|
last; |
|
276
|
|
|
|
|
|
|
} |
|
277
|
|
|
|
|
|
|
|
|
278
|
13
|
|
|
|
|
73
|
my $part = Mail::Message::Part->new |
|
279
|
|
|
|
|
|
|
( @msgopts |
|
280
|
|
|
|
|
|
|
, container => $self |
|
281
|
|
|
|
|
|
|
); |
|
282
|
|
|
|
|
|
|
|
|
283
|
13
|
50
|
|
|
|
59
|
last unless $part->readFromParser($parser, $bodytype); |
|
284
|
13
|
50
|
33
|
|
|
53
|
push @parts, $part |
|
285
|
|
|
|
|
|
|
if $part->head->names || $part->body->size; |
|
286
|
|
|
|
|
|
|
} |
|
287
|
7
|
|
|
|
|
24
|
$self->{MMBM_parts} = \@parts; |
|
288
|
|
|
|
|
|
|
|
|
289
|
|
|
|
|
|
|
# Get epilogue |
|
290
|
|
|
|
|
|
|
|
|
291
|
7
|
|
|
|
|
28
|
$parser->popSeparator; |
|
292
|
7
|
|
|
|
|
25
|
my $epilogue = Mail::Message::Body::Lines->new(@msgopts, @sloppyopts) |
|
293
|
|
|
|
|
|
|
->read($parser, $head); |
|
294
|
|
|
|
|
|
|
|
|
295
|
7
|
0
|
|
|
|
33
|
my $end = defined $epilogue ? ($epilogue->fileLocation)[1] |
|
|
|
0
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
: @parts ? ($parts[-1]->body->fileLocation)[1] |
|
297
|
|
|
|
|
|
|
: defined $preamble ? ($preamble->fileLocation)[1] |
|
298
|
|
|
|
|
|
|
: $begin; |
|
299
|
7
|
|
|
|
|
37
|
$self->fileLocation($begin, $end); |
|
300
|
|
|
|
|
|
|
|
|
301
|
7
|
100
|
66
|
|
|
51
|
$has_epilogue || $epilogue->nrLines |
|
302
|
|
|
|
|
|
|
or undef $epilogue; |
|
303
|
|
|
|
|
|
|
|
|
304
|
7
|
100
|
|
|
|
26
|
$self->{MMBM_epilogue} = $epilogue |
|
305
|
|
|
|
|
|
|
if defined $epilogue; |
|
306
|
|
|
|
|
|
|
|
|
307
|
7
|
|
|
|
|
51
|
$self; |
|
308
|
|
|
|
|
|
|
} |
|
309
|
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
#------------------------------------------ |
|
311
|
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
sub foreachComponent($) |
|
314
|
19
|
|
|
19
|
1
|
53
|
{ my ($self, $code) = @_; |
|
315
|
19
|
|
|
|
|
41
|
my $changes = 0; |
|
316
|
|
|
|
|
|
|
|
|
317
|
19
|
|
|
|
|
34
|
my $new_preamble; |
|
318
|
19
|
100
|
|
|
|
53
|
if(my $preamble = $self->preamble) |
|
319
|
2
|
|
|
|
|
7
|
{ $new_preamble = $code->($self, $preamble); |
|
320
|
2
|
100
|
|
|
|
12
|
$changes++ unless $preamble == $new_preamble; |
|
321
|
|
|
|
|
|
|
} |
|
322
|
|
|
|
|
|
|
|
|
323
|
19
|
|
|
|
|
36
|
my $new_epilogue; |
|
324
|
19
|
100
|
|
|
|
45
|
if(my $epilogue = $self->epilogue) |
|
325
|
2
|
|
|
|
|
6
|
{ $new_epilogue = $code->($self, $epilogue); |
|
326
|
2
|
100
|
|
|
|
8
|
$changes++ unless $epilogue == $new_epilogue; |
|
327
|
|
|
|
|
|
|
} |
|
328
|
|
|
|
|
|
|
|
|
329
|
19
|
|
|
|
|
47
|
my @new_bodies; |
|
330
|
19
|
|
|
|
|
56
|
foreach my $part ($self->parts('ACTIVE')) |
|
331
|
30
|
|
|
|
|
128
|
{ my $part_body = $part->body; |
|
332
|
30
|
|
|
|
|
95
|
my $new_body = $code->($self, $part_body); |
|
333
|
|
|
|
|
|
|
|
|
334
|
30
|
100
|
|
|
|
90
|
$changes++ if $new_body != $part_body; |
|
335
|
30
|
|
|
|
|
113
|
push @new_bodies, [$part, $new_body]; |
|
336
|
|
|
|
|
|
|
} |
|
337
|
|
|
|
|
|
|
|
|
338
|
19
|
100
|
|
|
|
87
|
return $self unless $changes; |
|
339
|
|
|
|
|
|
|
|
|
340
|
10
|
|
|
|
|
21
|
my @new_parts; |
|
341
|
10
|
|
|
|
|
28
|
foreach (@new_bodies) |
|
342
|
21
|
|
|
|
|
53
|
{ my ($part, $body) = @$_; |
|
343
|
21
|
|
|
|
|
74
|
my $new_part = Mail::Message::Part->new |
|
344
|
|
|
|
|
|
|
( head => $part->head->clone, |
|
345
|
|
|
|
|
|
|
container => undef |
|
346
|
|
|
|
|
|
|
); |
|
347
|
21
|
|
|
|
|
91
|
$new_part->body($body); |
|
348
|
21
|
|
|
|
|
58
|
push @new_parts, $new_part; |
|
349
|
|
|
|
|
|
|
} |
|
350
|
|
|
|
|
|
|
|
|
351
|
10
|
|
|
|
|
70
|
my $constructed = (ref $self)->new |
|
352
|
|
|
|
|
|
|
( preamble => $new_preamble |
|
353
|
|
|
|
|
|
|
, parts => \@new_parts |
|
354
|
|
|
|
|
|
|
, epilogue => $new_epilogue |
|
355
|
|
|
|
|
|
|
, based_on => $self |
|
356
|
|
|
|
|
|
|
); |
|
357
|
|
|
|
|
|
|
|
|
358
|
|
|
|
|
|
|
$_->container($constructed) |
|
359
|
10
|
|
|
|
|
44
|
foreach @new_parts; |
|
360
|
|
|
|
|
|
|
|
|
361
|
10
|
|
|
|
|
57
|
$constructed; |
|
362
|
|
|
|
|
|
|
} |
|
363
|
|
|
|
|
|
|
|
|
364
|
|
|
|
|
|
|
|
|
365
|
|
|
|
|
|
|
sub attach(@) |
|
366
|
2
|
|
|
2
|
1
|
7
|
{ my $self = shift; |
|
367
|
2
|
|
|
|
|
8
|
my $new = ref($self)->new |
|
368
|
|
|
|
|
|
|
( based_on => $self |
|
369
|
|
|
|
|
|
|
, parts => [$self->parts, @_] |
|
370
|
|
|
|
|
|
|
); |
|
371
|
|
|
|
|
|
|
} |
|
372
|
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
|
|
374
|
|
|
|
|
|
|
sub stripSignature(@) |
|
375
|
1
|
|
|
1
|
1
|
3
|
{ my $self = shift; |
|
376
|
|
|
|
|
|
|
|
|
377
|
1
|
|
|
|
|
4
|
my @allparts = $self->parts; |
|
378
|
1
|
|
|
|
|
2
|
my @parts = grep {! $_->body->mimeType->isSignature} @allparts; |
|
|
2
|
|
|
|
|
38
|
|
|
379
|
|
|
|
|
|
|
|
|
380
|
1
|
50
|
|
|
|
35
|
@allparts==@parts ? $self |
|
381
|
|
|
|
|
|
|
: (ref $self)->new(based_on => $self, parts => \@parts); |
|
382
|
|
|
|
|
|
|
} |
|
383
|
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
#------------------------------------------ |
|
385
|
|
|
|
|
|
|
|
|
386
|
|
|
|
|
|
|
|
|
387
|
103
|
|
|
103
|
1
|
361
|
sub preamble() {shift->{MMBM_preamble}} |
|
388
|
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
|
|
390
|
107
|
|
|
107
|
1
|
300
|
sub epilogue() {shift->{MMBM_epilogue}} |
|
391
|
|
|
|
|
|
|
|
|
392
|
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
sub parts(;$) |
|
394
|
157
|
|
|
157
|
1
|
379
|
{ my $self = shift; |
|
395
|
157
|
100
|
|
|
|
350
|
return @{$self->{MMBM_parts}} unless @_; |
|
|
66
|
|
|
|
|
354
|
|
|
396
|
|
|
|
|
|
|
|
|
397
|
91
|
|
|
|
|
147
|
my $what = shift; |
|
398
|
91
|
|
|
|
|
132
|
my @parts = @{$self->{MMBM_parts}}; |
|
|
91
|
|
|
|
|
237
|
|
|
399
|
|
|
|
|
|
|
|
|
400
|
0
|
|
|
|
|
0
|
$what eq 'RECURSE' ? (map {$_->parts('RECURSE')} @parts) |
|
401
|
|
|
|
|
|
|
: $what eq 'ALL' ? @parts |
|
402
|
0
|
|
|
|
|
0
|
: $what eq 'DELETED' ? (grep {$_->isDeleted} @parts) |
|
403
|
154
|
|
|
|
|
415
|
: $what eq 'ACTIVE' ? (grep {not $_->isDeleted} @parts) |
|
404
|
91
|
0
|
|
|
|
438
|
: ref $what eq 'CODE'? (grep {$what->($_)} @parts) |
|
|
0
|
50
|
|
|
|
0
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
: ($self->log(ERROR => "Unknown criterium $what to select parts."), return ()); |
|
406
|
|
|
|
|
|
|
} |
|
407
|
|
|
|
|
|
|
|
|
408
|
|
|
|
|
|
|
|
|
409
|
13
|
|
|
13
|
1
|
124
|
sub part($) { shift->{MMBM_parts}[shift] } |
|
410
|
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
sub partNumberOf($) |
|
412
|
8
|
|
|
8
|
1
|
22
|
{ my ($self, $part) = @_; |
|
413
|
8
|
|
|
|
|
22
|
my $msg = $self->message; |
|
414
|
8
|
50
|
|
|
|
28
|
unless($msg) |
|
415
|
0
|
|
|
|
|
0
|
{ $self->log(ERROR => 'multipart is not connected'); |
|
416
|
0
|
|
|
|
|
0
|
return 'ERROR'; |
|
417
|
|
|
|
|
|
|
} |
|
418
|
|
|
|
|
|
|
|
|
419
|
8
|
100
|
|
|
|
54
|
my $base = $msg->isa('Mail::Message::Part') ? $msg->partNumber.'.' : ''; |
|
420
|
|
|
|
|
|
|
|
|
421
|
8
|
|
|
|
|
23
|
my @parts = $self->parts('ACTIVE'); |
|
422
|
8
|
|
|
|
|
28
|
foreach my $partnr (0..@parts) |
|
423
|
15
|
100
|
|
|
|
93
|
{ return $base.($partnr+1) |
|
424
|
|
|
|
|
|
|
if $parts[$partnr] == $part; |
|
425
|
|
|
|
|
|
|
} |
|
426
|
0
|
|
|
|
|
0
|
$self->log(ERROR => 'multipart is not found or not active'); |
|
427
|
0
|
|
|
|
|
0
|
'ERROR'; |
|
428
|
|
|
|
|
|
|
} |
|
429
|
|
|
|
|
|
|
|
|
430
|
|
|
|
|
|
|
|
|
431
|
|
|
|
|
|
|
sub boundary(;$) |
|
432
|
112
|
|
|
112
|
1
|
201
|
{ my $self = shift; |
|
433
|
112
|
|
|
|
|
306
|
my $mime = $self->type; |
|
434
|
|
|
|
|
|
|
|
|
435
|
112
|
100
|
|
|
|
313
|
unless(@_) |
|
436
|
71
|
|
|
|
|
262
|
{ my $boundary = $mime->attribute('boundary'); |
|
437
|
71
|
50
|
|
|
|
332
|
return $boundary if defined $boundary; |
|
438
|
|
|
|
|
|
|
} |
|
439
|
|
|
|
|
|
|
|
|
440
|
41
|
100
|
66
|
|
|
462
|
my $boundary = @_ && defined $_[0] ? (shift) : "boundary-".int rand(1000000); |
|
441
|
41
|
|
|
|
|
140
|
$self->type->attribute(boundary => $boundary); |
|
442
|
|
|
|
|
|
|
} |
|
443
|
|
|
|
|
|
|
|
|
444
|
|
|
|
|
|
|
sub endsOnNewline() { 1 } |
|
445
|
|
|
|
|
|
|
|
|
446
|
0
|
0
|
|
0
|
0
|
|
sub toplevel() { my $msg = shift->message; $msg ? $msg->toplevel : undef} |
|
|
0
|
|
|
|
|
|
|
|
447
|
|
|
|
|
|
|
|
|
448
|
|
|
|
|
|
|
#------------------------------------------- |
|
449
|
|
|
|
|
|
|
|
|
450
|
|
|
|
|
|
|
|
|
451
|
|
|
|
|
|
|
1; |