line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
1
|
|
|
1
|
|
915
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
42
|
|
2
|
|
|
|
|
|
|
package Email::Filter 1.035; |
3
|
|
|
|
|
|
|
# ABSTRACT: Library for creating easy email filters |
4
|
|
|
|
|
|
|
|
5
|
1
|
|
|
1
|
|
370
|
use Email::LocalDelivery; |
|
1
|
|
|
|
|
42357
|
|
|
1
|
|
|
|
|
30
|
|
6
|
1
|
|
|
1
|
|
703
|
use Email::Simple; |
|
1
|
|
|
|
|
4863
|
|
|
1
|
|
|
|
|
31
|
|
7
|
1
|
|
|
1
|
|
631
|
use Class::Trigger; |
|
1
|
|
|
|
|
1115
|
|
|
1
|
|
|
|
|
6
|
|
8
|
1
|
|
|
1
|
|
827
|
use IPC::Run qw(run); |
|
1
|
|
|
|
|
28669
|
|
|
1
|
|
|
|
|
62
|
|
9
|
|
|
|
|
|
|
|
10
|
1
|
|
|
1
|
|
11
|
use constant DELIVERED => 0; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
74
|
|
11
|
1
|
|
|
1
|
|
6
|
use constant TEMPFAIL => 75; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
36
|
|
12
|
1
|
|
|
1
|
|
5
|
use constant REJECTED => 100; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
407
|
|
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
#pod =head1 SYNOPSIS |
15
|
|
|
|
|
|
|
#pod |
16
|
|
|
|
|
|
|
#pod use Email::Filter; |
17
|
|
|
|
|
|
|
#pod my $mail = Email::Filter->new(emergency => "~/emergency_mbox"); |
18
|
|
|
|
|
|
|
#pod $mail->pipe("listgate", "p5p") if $mail->from =~ /perl5-porters/; |
19
|
|
|
|
|
|
|
#pod $mail->accept("perl") if $mail->from =~ /perl/; |
20
|
|
|
|
|
|
|
#pod $mail->reject("We do not accept spam") if $mail->subject =~ /enlarge/; |
21
|
|
|
|
|
|
|
#pod $mail->ignore if $mail->subject =~ /boring/i; |
22
|
|
|
|
|
|
|
#pod ... |
23
|
|
|
|
|
|
|
#pod $mail->exit(0); |
24
|
|
|
|
|
|
|
#pod $mail->accept("~/Mail/Archive/backup"); |
25
|
|
|
|
|
|
|
#pod $mail->exit(1); |
26
|
|
|
|
|
|
|
#pod $mail->accept() |
27
|
|
|
|
|
|
|
#pod |
28
|
|
|
|
|
|
|
#pod =head1 DESCRIPTION |
29
|
|
|
|
|
|
|
#pod |
30
|
|
|
|
|
|
|
#pod This module replaces C or C, and allows you to write |
31
|
|
|
|
|
|
|
#pod programs describing how your mail should be filtered. |
32
|
|
|
|
|
|
|
#pod |
33
|
|
|
|
|
|
|
#pod =head1 TRIGGERS |
34
|
|
|
|
|
|
|
#pod |
35
|
|
|
|
|
|
|
#pod Users of C will note that this class is much leaner than |
36
|
|
|
|
|
|
|
#pod the one it replaces. For instance, it has no logging; the concept of |
37
|
|
|
|
|
|
|
#pod "local options" has gone away, and so on. This is a deliberate design |
38
|
|
|
|
|
|
|
#pod decision to make the class as simple and maintainable as possible. |
39
|
|
|
|
|
|
|
#pod |
40
|
|
|
|
|
|
|
#pod To make up for this, however, C contains a trigger |
41
|
|
|
|
|
|
|
#pod mechanism provided by L, to allow you to add your own |
42
|
|
|
|
|
|
|
#pod functionality. You do this by calling the C method: |
43
|
|
|
|
|
|
|
#pod |
44
|
|
|
|
|
|
|
#pod Email::Filter->add_trigger( after_accept => \&log_accept ); |
45
|
|
|
|
|
|
|
#pod |
46
|
|
|
|
|
|
|
#pod Hopefully this will also help subclassers. |
47
|
|
|
|
|
|
|
#pod |
48
|
|
|
|
|
|
|
#pod The methods below will list which triggers they provide. |
49
|
|
|
|
|
|
|
#pod |
50
|
|
|
|
|
|
|
#pod =head1 ERROR RECOVERY |
51
|
|
|
|
|
|
|
#pod |
52
|
|
|
|
|
|
|
#pod If something bad happens during the C or C method, or |
53
|
|
|
|
|
|
|
#pod the C object gets destroyed without being properly |
54
|
|
|
|
|
|
|
#pod handled, then a fail-safe error recovery process is called. This first |
55
|
|
|
|
|
|
|
#pod checks for the existence of the C setting, and tries to |
56
|
|
|
|
|
|
|
#pod deliver to that mailbox. If there is no emergency mailbox or that |
57
|
|
|
|
|
|
|
#pod delivery failed, then the program will either exit with a temporary |
58
|
|
|
|
|
|
|
#pod failure error code, queuing the mail for redelivery later, or produce a |
59
|
|
|
|
|
|
|
#pod warning to standard error, depending on the status of the C |
60
|
|
|
|
|
|
|
#pod setting. |
61
|
|
|
|
|
|
|
#pod |
62
|
|
|
|
|
|
|
#pod =cut |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
sub done_ok { |
65
|
2
|
|
|
2
|
0
|
9
|
my $self = shift; |
66
|
2
|
|
|
|
|
6
|
$self->{delivered} = 1; |
67
|
2
|
50
|
|
|
|
13
|
exit DELIVERED unless $self->{noexit}; |
68
|
|
|
|
|
|
|
} |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
sub fail_badly { |
71
|
0
|
|
|
0
|
0
|
0
|
my $self = shift; |
72
|
0
|
|
|
|
|
0
|
$self->{giveup} = 1; # Don't get caught by DESTROY |
73
|
0
|
0
|
|
|
|
0
|
exit TEMPFAIL unless $self->{noexit}; |
74
|
0
|
|
|
|
|
0
|
warn "Message ".$self->simple->header("Message-ID"). |
75
|
|
|
|
|
|
|
"was never handled properly\n"; |
76
|
|
|
|
|
|
|
} |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
sub fail_gracefully { |
79
|
0
|
|
|
0
|
0
|
0
|
my $self = shift; |
80
|
0
|
|
|
|
|
0
|
our $FAILING_GRACEFULLY; |
81
|
0
|
0
|
0
|
|
|
0
|
if ($self->{emergency} and ! $FAILING_GRACEFULLY) { |
82
|
0
|
|
|
|
|
0
|
local $FAILING_GRACEFULLY = 1; |
83
|
0
|
0
|
|
|
|
0
|
$self->done_ok if $self->accept($self->{emergency}); |
84
|
|
|
|
|
|
|
} |
85
|
0
|
|
|
|
|
0
|
$self->fail_badly; |
86
|
|
|
|
|
|
|
} |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
sub DESTROY { |
89
|
1
|
|
|
1
|
|
537
|
my $self = shift; |
90
|
|
|
|
|
|
|
return if $self->{delivered} # All OK. |
91
|
|
|
|
|
|
|
or $self->{giveup} # Tried emergency, didn't work. |
92
|
1
|
0
|
33
|
|
|
216
|
or !$self->{emergency}; # Not much we can do. |
|
|
|
0
|
|
|
|
|
93
|
0
|
|
|
|
|
0
|
$self->fail_gracefully(); |
94
|
|
|
|
|
|
|
} |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
#pod =method new |
97
|
|
|
|
|
|
|
#pod |
98
|
|
|
|
|
|
|
#pod Email::Filter->new(); # Read from STDIN |
99
|
|
|
|
|
|
|
#pod Email::Filter->new(data => $string); # Read from string |
100
|
|
|
|
|
|
|
#pod |
101
|
|
|
|
|
|
|
#pod Email::Filter->new(emergency => "~simon/urgh"); |
102
|
|
|
|
|
|
|
#pod # Deliver here in case of error |
103
|
|
|
|
|
|
|
#pod |
104
|
|
|
|
|
|
|
#pod This takes an email either from standard input, the usual case when |
105
|
|
|
|
|
|
|
#pod called as a mail filter, or from a string. |
106
|
|
|
|
|
|
|
#pod |
107
|
|
|
|
|
|
|
#pod You may also provide an "emergency" option, which is a filename to |
108
|
|
|
|
|
|
|
#pod deliver the mail to if it couldn't, for some reason, be handled |
109
|
|
|
|
|
|
|
#pod properly. |
110
|
|
|
|
|
|
|
#pod |
111
|
|
|
|
|
|
|
#pod =over 3 |
112
|
|
|
|
|
|
|
#pod |
113
|
|
|
|
|
|
|
#pod =item Hint |
114
|
|
|
|
|
|
|
#pod |
115
|
|
|
|
|
|
|
#pod If you put your constructor in a C block, like so: |
116
|
|
|
|
|
|
|
#pod |
117
|
|
|
|
|
|
|
#pod use Email::Filter; |
118
|
|
|
|
|
|
|
#pod BEGIN { $item = Email::Filter->new(emergency => "~simon/urgh"); } |
119
|
|
|
|
|
|
|
#pod |
120
|
|
|
|
|
|
|
#pod right at the top of your mail filter script, you'll even be protected |
121
|
|
|
|
|
|
|
#pod from losing mail even in the case of syntax errors in your script. How |
122
|
|
|
|
|
|
|
#pod neat is that? |
123
|
|
|
|
|
|
|
#pod |
124
|
|
|
|
|
|
|
#pod =back |
125
|
|
|
|
|
|
|
#pod |
126
|
|
|
|
|
|
|
#pod This method provides the C trigger, called once an object is |
127
|
|
|
|
|
|
|
#pod instantiated. |
128
|
|
|
|
|
|
|
#pod |
129
|
|
|
|
|
|
|
#pod =cut |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
sub new { |
132
|
1
|
|
|
1
|
1
|
745
|
my $class = shift; |
133
|
1
|
|
|
|
|
5
|
my %stuff = @_; |
134
|
1
|
|
|
|
|
2
|
my $data; |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
{ |
137
|
1
|
|
|
|
|
1
|
local $/; |
|
1
|
|
|
|
|
14
|
|
138
|
1
|
50
|
|
|
|
10
|
$data = exists $stuff{data} ? $stuff{data} : scalar ; |
139
|
|
|
|
|
|
|
# shave any leading From_ line |
140
|
1
|
|
|
|
|
3
|
$data =~ s/^From .*?[\x0a\x0d]// |
141
|
|
|
|
|
|
|
} |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
my $obj = bless { |
144
|
|
|
|
|
|
|
mail => Email::Simple->new($data), |
145
|
|
|
|
|
|
|
emergency => $stuff{emergency}, |
146
|
1
|
|
50
|
|
|
8
|
noexit => ($stuff{noexit} || 0) |
147
|
|
|
|
|
|
|
}, $class; |
148
|
1
|
|
|
|
|
388
|
$obj->call_trigger("new"); |
149
|
1
|
|
|
|
|
94
|
return $obj; |
150
|
|
|
|
|
|
|
} |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
#pod =method exit |
153
|
|
|
|
|
|
|
#pod |
154
|
|
|
|
|
|
|
#pod $mail->exit(1|0); |
155
|
|
|
|
|
|
|
#pod |
156
|
|
|
|
|
|
|
#pod Sets or clears the 'exit' flag which determines whether or not the |
157
|
|
|
|
|
|
|
#pod following methods exit after successful completion. |
158
|
|
|
|
|
|
|
#pod |
159
|
|
|
|
|
|
|
#pod The sense-inverted 'noexit' method is also provided for backwards |
160
|
|
|
|
|
|
|
#pod compatibility with C, but setting "noexit" to "yes" got a |
161
|
|
|
|
|
|
|
#pod bit mind-bending after a while. |
162
|
|
|
|
|
|
|
#pod |
163
|
|
|
|
|
|
|
#pod =cut |
164
|
|
|
|
|
|
|
|
165
|
1
|
|
|
1
|
1
|
1060
|
sub exit { $_[0]->{noexit} = !$_[1]; } |
166
|
0
|
|
|
0
|
0
|
0
|
sub noexit { $_[0]->{noexit} = $_[1]; } |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
#pod =method simple |
169
|
|
|
|
|
|
|
#pod |
170
|
|
|
|
|
|
|
#pod $mail->simple(); |
171
|
|
|
|
|
|
|
#pod |
172
|
|
|
|
|
|
|
#pod Gets and sets the underlying C object for this filter; |
173
|
|
|
|
|
|
|
#pod see L for more details. |
174
|
|
|
|
|
|
|
#pod |
175
|
|
|
|
|
|
|
#pod =cut |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
sub simple { |
178
|
3
|
|
|
3
|
1
|
9
|
my ($filter, $mail) = @_; |
179
|
3
|
50
|
|
|
|
11
|
if ($mail) { $filter->{mail} = $mail; } |
|
0
|
|
|
|
|
0
|
|
180
|
3
|
|
|
|
|
20
|
return $filter->{mail}; |
181
|
|
|
|
|
|
|
} |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
#pod =method header |
184
|
|
|
|
|
|
|
#pod |
185
|
|
|
|
|
|
|
#pod $mail->header("X-Something") |
186
|
|
|
|
|
|
|
#pod |
187
|
|
|
|
|
|
|
#pod Returns the specified mail headers. In scalar context, returns the |
188
|
|
|
|
|
|
|
#pod first such header; in list context, returns them all. |
189
|
|
|
|
|
|
|
#pod |
190
|
|
|
|
|
|
|
#pod =cut |
191
|
|
|
|
|
|
|
|
192
|
0
|
|
|
0
|
1
|
0
|
sub header { my ($mail, $head) = @_; $mail->simple->header($head); } |
|
0
|
|
|
|
|
0
|
|
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
#pod =method body |
195
|
|
|
|
|
|
|
#pod |
196
|
|
|
|
|
|
|
#pod $mail->body() |
197
|
|
|
|
|
|
|
#pod |
198
|
|
|
|
|
|
|
#pod Returns the body text of the email |
199
|
|
|
|
|
|
|
#pod |
200
|
|
|
|
|
|
|
#pod =cut |
201
|
|
|
|
|
|
|
|
202
|
0
|
|
|
0
|
1
|
0
|
sub body { $_[0]->simple->body } |
203
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
#pod =method from |
205
|
|
|
|
|
|
|
#pod |
206
|
|
|
|
|
|
|
#pod =method to |
207
|
|
|
|
|
|
|
#pod |
208
|
|
|
|
|
|
|
#pod =method cc |
209
|
|
|
|
|
|
|
#pod |
210
|
|
|
|
|
|
|
#pod =method bcc |
211
|
|
|
|
|
|
|
#pod |
212
|
|
|
|
|
|
|
#pod =method subject |
213
|
|
|
|
|
|
|
#pod |
214
|
|
|
|
|
|
|
#pod =method received |
215
|
|
|
|
|
|
|
#pod |
216
|
|
|
|
|
|
|
#pod $mail-> |
217
|
|
|
|
|
|
|
#pod |
218
|
|
|
|
|
|
|
#pod Convenience accessors for C |
219
|
|
|
|
|
|
|
#pod |
220
|
|
|
|
|
|
|
#pod =cut |
221
|
|
|
|
|
|
|
|
222
|
1
|
|
|
1
|
|
7
|
{ no strict 'refs'; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
403
|
|
223
|
|
|
|
|
|
|
for my $head (qw(From To CC Bcc Subject Received)) { |
224
|
0
|
|
|
0
|
|
0
|
*{lc $head} = sub { $_[0]->header($head) } |
225
|
|
|
|
|
|
|
} |
226
|
|
|
|
|
|
|
} |
227
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
#pod =method ignore |
229
|
|
|
|
|
|
|
#pod |
230
|
|
|
|
|
|
|
#pod Ignores this mail, exiting unconditionally unless C has been set |
231
|
|
|
|
|
|
|
#pod to false. |
232
|
|
|
|
|
|
|
#pod |
233
|
|
|
|
|
|
|
#pod This method provides the "ignore" trigger. |
234
|
|
|
|
|
|
|
#pod |
235
|
|
|
|
|
|
|
#pod =cut |
236
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
sub ignore { |
238
|
0
|
|
|
0
|
1
|
0
|
$_[0]->call_trigger("ignore"); |
239
|
0
|
|
|
|
|
0
|
$_[0]->done_ok; |
240
|
|
|
|
|
|
|
} |
241
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
#pod =method accept |
243
|
|
|
|
|
|
|
#pod |
244
|
|
|
|
|
|
|
#pod $mail->accept(); |
245
|
|
|
|
|
|
|
#pod $mail->accept(@where); |
246
|
|
|
|
|
|
|
#pod |
247
|
|
|
|
|
|
|
#pod Accepts the mail into a given mailbox or mailboxes. |
248
|
|
|
|
|
|
|
#pod Unix C<~/> and C<~user/> prefices are resolved. If no mailbox is given, |
249
|
|
|
|
|
|
|
#pod the default is determined according to L: |
250
|
|
|
|
|
|
|
#pod C<$ENV{MAIL}>, F, F, or |
251
|
|
|
|
|
|
|
#pod F<~you/Maildir/>. |
252
|
|
|
|
|
|
|
#pod |
253
|
|
|
|
|
|
|
#pod This provides the C and C triggers, and |
254
|
|
|
|
|
|
|
#pod exits unless C has been set to false. They are passed a reference to the |
255
|
|
|
|
|
|
|
#pod C<@where> array. |
256
|
|
|
|
|
|
|
#pod |
257
|
|
|
|
|
|
|
#pod =cut |
258
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
sub accept { |
260
|
1
|
|
|
1
|
1
|
1093
|
my ($self, @where) = @_; |
261
|
1
|
|
|
|
|
7
|
$self->call_trigger("before_accept", \@where); |
262
|
|
|
|
|
|
|
# Unparsing and reparsing is so fast we prefer to do that in order |
263
|
|
|
|
|
|
|
# to keep to LocalDelivery's clean interface. |
264
|
1
|
50
|
|
|
|
76
|
if (Email::LocalDelivery->deliver($self->simple->as_string, @where)) { |
265
|
1
|
|
|
|
|
8057
|
$self->call_trigger("after_accept", \@where); |
266
|
1
|
|
|
|
|
176
|
$self->done_ok; |
267
|
|
|
|
|
|
|
} else { |
268
|
0
|
|
|
|
|
0
|
$self->fail_gracefully(); |
269
|
|
|
|
|
|
|
} |
270
|
|
|
|
|
|
|
} |
271
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
#pod =method reject |
273
|
|
|
|
|
|
|
#pod |
274
|
|
|
|
|
|
|
#pod $mail->reject("Go away!"); |
275
|
|
|
|
|
|
|
#pod |
276
|
|
|
|
|
|
|
#pod This rejects the email; if called in a pipe from a mail transport agent, (such |
277
|
|
|
|
|
|
|
#pod as in a F<~/.forward> file) the mail will be bounced back to the sender as |
278
|
|
|
|
|
|
|
#pod undeliverable. If a reason is given, this will be included in the bounce. |
279
|
|
|
|
|
|
|
#pod |
280
|
|
|
|
|
|
|
#pod This calls the C trigger. C has no effect here. |
281
|
|
|
|
|
|
|
#pod |
282
|
|
|
|
|
|
|
#pod =cut |
283
|
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
sub reject { |
285
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
286
|
0
|
|
|
|
|
0
|
$self->call_trigger("reject"); |
287
|
0
|
|
|
|
|
0
|
$self->{delivered} = 1; |
288
|
0
|
|
|
|
|
0
|
$! = REJECTED; die @_,"\n"; |
|
0
|
|
|
|
|
0
|
|
289
|
|
|
|
|
|
|
} |
290
|
|
|
|
|
|
|
|
291
|
|
|
|
|
|
|
#pod =method pipe |
292
|
|
|
|
|
|
|
#pod |
293
|
|
|
|
|
|
|
#pod $mail->pipe(qw[sendmail foo\@bar.com]); |
294
|
|
|
|
|
|
|
#pod |
295
|
|
|
|
|
|
|
#pod Pipes the mail to an external program, returning the standard output |
296
|
|
|
|
|
|
|
#pod from that program if C has been set to false. The program and each |
297
|
|
|
|
|
|
|
#pod of its arguments must be supplied in a list. This allows you to do |
298
|
|
|
|
|
|
|
#pod things like: |
299
|
|
|
|
|
|
|
#pod |
300
|
|
|
|
|
|
|
#pod $mail->exit(0); |
301
|
|
|
|
|
|
|
#pod $mail->simple(Email::Simple->new($mail->pipe("spamassassin"))); |
302
|
|
|
|
|
|
|
#pod $mail->exit(1); |
303
|
|
|
|
|
|
|
#pod |
304
|
|
|
|
|
|
|
#pod in the absence of decent C support. |
305
|
|
|
|
|
|
|
#pod |
306
|
|
|
|
|
|
|
#pod If the program returns a non-zero exit code, the behaviour is dependent |
307
|
|
|
|
|
|
|
#pod on the status of the C flag. If this flag is set to true (the |
308
|
|
|
|
|
|
|
#pod default), then C tries to recover. (See L) |
309
|
|
|
|
|
|
|
#pod If not, nothing is returned. |
310
|
|
|
|
|
|
|
#pod |
311
|
|
|
|
|
|
|
#pod If the last argument to C is a reference to a hash, it is taken to |
312
|
|
|
|
|
|
|
#pod contain parameters to modify how C itself behaves. The only useful |
313
|
|
|
|
|
|
|
#pod parameter at this time is: |
314
|
|
|
|
|
|
|
#pod |
315
|
|
|
|
|
|
|
#pod header_only - only pipe the header, not the body |
316
|
|
|
|
|
|
|
#pod |
317
|
|
|
|
|
|
|
#pod =cut |
318
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
sub pipe { |
320
|
2
|
|
|
2
|
1
|
1950
|
my ($self, @program) = @_; |
321
|
2
|
|
|
|
|
4
|
my $arg; |
322
|
2
|
50
|
|
|
|
9
|
$arg = (ref $program[-1] eq 'HASH') ? (pop @program) : {}; |
323
|
|
|
|
|
|
|
|
324
|
2
|
|
|
|
|
4
|
my $stdout; |
325
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
my $string = $arg->{header_only} |
327
|
2
|
50
|
|
|
|
11
|
? $self->simple->header_obj->as_string |
328
|
|
|
|
|
|
|
: $self->simple->as_string; |
329
|
|
|
|
|
|
|
|
330
|
2
|
|
|
|
|
358
|
$self->call_trigger("pipe", \@program, $arg); |
331
|
2
|
100
|
|
|
|
105
|
if (eval {run(\@program, \$string, \$stdout)} ) { |
|
2
|
|
|
|
|
11
|
|
332
|
1
|
|
|
|
|
8346
|
$self->done_ok; |
333
|
1
|
|
|
|
|
14
|
return $stdout; |
334
|
|
|
|
|
|
|
} |
335
|
1
|
50
|
|
|
|
1675
|
$self->fail_gracefully() unless $self->{noexit}; |
336
|
1
|
|
|
|
|
10
|
return; |
337
|
|
|
|
|
|
|
} |
338
|
|
|
|
|
|
|
|
339
|
|
|
|
|
|
|
1; |
340
|
|
|
|
|
|
|
|
341
|
|
|
|
|
|
|
__END__ |