File Coverage

blib/lib/MIME/Entity.pm
Criterion Covered Total %
statement 347 407 85.2
branch 161 240 67.0
condition 46 79 58.2
subroutine 43 50 86.0
pod 32 38 84.2
total 629 814 77.2


line stmt bran cond sub pod time code
1             package MIME::Entity;
2              
3              
4             =head1 NAME
5              
6             MIME::Entity - class for parsed-and-decoded MIME message
7              
8              
9             =head1 SYNOPSIS
10              
11             Before reading further, you should see L to make sure that
12             you understand where this module fits into the grand scheme of things.
13             Go on, do it now. I'll wait.
14              
15             Ready? Ok...
16              
17             ### Create an entity:
18             $top = MIME::Entity->build(From => 'me@myhost.com',
19             To => 'you@yourhost.com',
20             Subject => "Hello, nurse!",
21             Data => \@my_message);
22              
23             ### Attach stuff to it:
24             $top->attach(Path => $gif_path,
25             Type => "image/gif",
26             Encoding => "base64");
27              
28             ### Sign it:
29             $top->sign;
30              
31             ### Output it:
32             $top->print(\*STDOUT);
33              
34              
35             =head1 DESCRIPTION
36              
37             A subclass of B.
38              
39             This package provides a class for representing MIME message entities,
40             as specified in RFCs 2045, 2046, 2047, 2048 and 2049.
41              
42              
43             =head1 EXAMPLES
44              
45             =head2 Construction examples
46              
47             Create a document for an ordinary 7-bit ASCII text file (lots of
48             stuff is defaulted for us):
49              
50             $ent = MIME::Entity->build(Path=>"english-msg.txt");
51              
52             Create a document for a text file with 8-bit (Latin-1) characters:
53              
54             $ent = MIME::Entity->build(Path =>"french-msg.txt",
55             Encoding =>"quoted-printable",
56             From =>'jean.luc@inria.fr',
57             Subject =>"C'est bon!");
58              
59             Create a document for a GIF file (the description is completely optional;
60             note that we have to specify content-type and encoding since they're
61             not the default values):
62              
63             $ent = MIME::Entity->build(Description => "A pretty picture",
64             Path => "./docs/mime-sm.gif",
65             Type => "image/gif",
66             Encoding => "base64");
67              
68             Create a document that you already have the text for, using "Data":
69              
70             $ent = MIME::Entity->build(Type => "text/plain",
71             Encoding => "quoted-printable",
72             Data => ["First line.\n",
73             "Second line.\n",
74             "Last line.\n"]);
75              
76             Create a multipart message, with the entire structure given
77             explicitly:
78              
79             ### Create the top-level, and set up the mail headers:
80             $top = MIME::Entity->build(Type => "multipart/mixed",
81             From => 'me@myhost.com',
82             To => 'you@yourhost.com',
83             Subject => "Hello, nurse!");
84              
85             ### Attachment #1: a simple text document:
86             $top->attach(Path=>"./testin/short.txt");
87              
88             ### Attachment #2: a GIF file:
89             $top->attach(Path => "./docs/mime-sm.gif",
90             Type => "image/gif",
91             Encoding => "base64");
92              
93             ### Attachment #3: text we'll create with text we have on-hand:
94             $top->attach(Data => $contents);
95              
96             Suppose you don't know ahead of time that you'll have attachments?
97             No problem: you can "attach" to singleparts as well:
98              
99             $top = MIME::Entity->build(From => 'me@myhost.com',
100             To => 'you@yourhost.com',
101             Subject => "Hello, nurse!",
102             Data => \@my_message);
103             if ($GIF_path) {
104             $top->attach(Path => $GIF_path,
105             Type => 'image/gif');
106             }
107              
108             Copy an entity (headers, parts... everything but external body data):
109              
110             my $deepcopy = $top->dup;
111              
112              
113              
114             =head2 Access examples
115              
116             ### Get the head, a MIME::Head:
117             $head = $ent->head;
118              
119             ### Get the body, as a MIME::Body;
120             $bodyh = $ent->bodyhandle;
121              
122             ### Get the intended MIME type (as declared in the header):
123             $type = $ent->mime_type;
124              
125             ### Get the effective MIME type (in case decoding failed):
126             $eff_type = $ent->effective_type;
127              
128             ### Get preamble, parts, and epilogue:
129             $preamble = $ent->preamble; ### ref to array of lines
130             $num_parts = $ent->parts;
131             $first_part = $ent->parts(0); ### an entity
132             $epilogue = $ent->epilogue; ### ref to array of lines
133              
134              
135             =head2 Manipulation examples
136              
137             Muck about with the body data:
138              
139             ### Read the (unencoded) body data:
140             if ($io = $ent->open("r")) {
141             while (defined($_ = $io->getline)) { print $_ }
142             $io->close;
143             }
144              
145             ### Write the (unencoded) body data:
146             if ($io = $ent->open("w")) {
147             foreach (@lines) { $io->print($_) }
148             $io->close;
149             }
150              
151             ### Delete the files for any external (on-disk) data:
152             $ent->purge;
153              
154             Muck about with the signature:
155              
156             ### Sign it (automatically removes any existing signature):
157             $top->sign(File=>"$ENV{HOME}/.signature");
158              
159             ### Remove any signature within 15 lines of the end:
160             $top->remove_sig(15);
161              
162             Muck about with the headers:
163              
164             ### Compute content-lengths for singleparts based on bodies:
165             ### (Do this right before you print!)
166             $entity->sync_headers(Length=>'COMPUTE');
167              
168             Muck about with the structure:
169              
170             ### If a 0- or 1-part multipart, collapse to a singlepart:
171             $top->make_singlepart;
172              
173             ### If a singlepart, inflate to a multipart with 1 part:
174             $top->make_multipart;
175              
176             Delete parts:
177              
178             ### Delete some parts of a multipart message:
179             my @keep = grep { keep_part($_) } $msg->parts;
180             $msg->parts(\@keep);
181              
182              
183             =head2 Output examples
184              
185             Print to filehandles:
186              
187             ### Print the entire message:
188             $top->print(\*STDOUT);
189              
190             ### Print just the header:
191             $top->print_header(\*STDOUT);
192              
193             ### Print just the (encoded) body... includes parts as well!
194             $top->print_body(\*STDOUT);
195              
196             Stringify... note that C can also be written C;
197             the methods are synonymous, and neither form will be deprecated.
198              
199             If you set the variable $MIME::Entity::BOUNDARY_DELIMITER to a string,
200             that string will be used as the line-end delimiter on output. If it is not set,
201             the line ending will be a newline character (\n)
202              
203             NOTE that $MIME::Entity::BOUNDARY_DELIMITER only applies to structural
204             parts of the MIME data generated by this package and to the Base64
205             encoded output; if a part internally uses a different line-end
206             delimiter and is output as-is, the line-ending is not changed to match
207             $MIME::Entity::BOUNDARY_DELIMITER.
208              
209             ### Stringify the entire message:
210             print $top->stringify; ### or $top->as_string
211              
212             ### Stringify just the header:
213             print $top->stringify_header; ### or $top->header_as_string
214              
215             ### Stringify just the (encoded) body... includes parts as well!
216             print $top->stringify_body; ### or $top->body_as_string
217              
218             Debug:
219              
220             ### Output debugging info:
221             $entity->dump_skeleton(\*STDERR);
222              
223              
224              
225             =head1 PUBLIC INTERFACE
226              
227             =cut
228              
229             #------------------------------
230              
231             ### Pragmas:
232 22     22   606707 use vars qw(@ISA $VERSION);
  22         51  
  22         1484  
233 22     22   162 use strict;
  22         37  
  22         686  
234              
235             ### System modules:
236 22     22   103 use Carp;
  22         44  
  22         1806  
237              
238             ### Other modules:
239 22     22   13853 use Mail::Internet 1.28 ();
  22         262843  
  22         1084  
240 22     22   3385 use Mail::Field 1.05 ();
  22         21553  
  22         969  
241              
242             ### Kit modules:
243 22     22   2789 use MIME::Tools qw(:config :msgs :utils);
  22         135  
  22         4823  
244 22     22   3762 use MIME::Head;
  22         77  
  22         739  
245 22     22   3221 use MIME::Body;
  22         54  
  22         587  
246 22     22   12556 use MIME::Decoder;
  22         90  
  22         124204  
247              
248             @ISA = qw(Mail::Internet);
249              
250              
251             #------------------------------
252             #
253             # Globals...
254             #
255             #------------------------------
256              
257             ### The package version, both in 1.23 style *and* usable by MakeMaker:
258             $VERSION = "5.517";
259              
260             ### Boundary counter:
261             my $BCount = 0;
262              
263             ### Standard "Content-" MIME fields, for scrub():
264             my $StandardFields = 'Description|Disposition|Id|Type|Transfer-Encoding';
265              
266             ### Known Mail/MIME fields... these, plus some general forms like
267             ### "x-*", are recognized by build():
268             my %KnownField = map {$_=>1}
269             qw(
270             bcc cc comments date encrypted
271             from keywords message-id mime-version organization
272             received references reply-to return-path sender
273             subject to
274             );
275              
276             ### Fallback preamble and epilogue:
277             my $DefPreamble = [ "This is a multi-part message in MIME format..." ];
278             my $DefEpilogue = [ ];
279              
280             #==============================
281             #
282             # Utilities, private
283             #
284              
285             #------------------------------
286             #
287             # known_field FIELDNAME
288             #
289             # Is this a recognized Mail/MIME field?
290             #
291             sub known_field {
292 105     105 0 141 my $field = lc(shift);
293 105 100       391 $KnownField{$field} or ($field =~ m{^(content|resent|x)-.});
294             }
295              
296             #------------------------------
297             #
298             # make_boundary
299             #
300             # Return a unique boundary string.
301             # This is used both internally and by MIME::ParserBase, but it is NOT in
302             # the public interface! Do not use it!
303             #
304             # We generate one containing a "=_", as RFC2045 suggests:
305             # A good strategy is to choose a boundary that includes a character
306             # sequence such as "=_" which can never appear in a quoted-printable
307             # body. See the definition of multipart messages in RFC 2046.
308             #
309             sub make_boundary {
310 6     6 0 59 return "----------=_".scalar(time)."-$$-".$BCount++;
311             }
312              
313              
314              
315              
316              
317              
318             #==============================
319              
320             =head2 Construction
321              
322             =over 4
323              
324             =cut
325              
326              
327             #------------------------------
328              
329             =item new [SOURCE]
330              
331             I
332             Create a new, empty MIME entity.
333             Basically, this uses the Mail::Internet constructor...
334              
335             If SOURCE is an ARRAYREF, it is assumed to be an array of lines
336             that will be used to create both the header and an in-core body.
337              
338             Else, if SOURCE is defined, it is assumed to be a filehandle
339             from which the header and in-core body is to be read.
340              
341             B in either case, the body will not be I merely read!
342              
343             =cut
344              
345             sub new {
346 252     252 1 540 my $class = shift;
347 252         1822 my $self = $class->Mail::Internet::new(@_); ### inherited
348 252         20040 $self->{ME_Parts} = []; ### no parts extracted
349 252         666 $self;
350             }
351              
352             =item ambiguous_content
353              
354             I
355              
356             Returns true if this entity I has
357             a C that indicates ambiguous content.
358              
359             Note carefully the difference between:
360              
361             $entity->head->ambiguous_content();
362              
363             and
364              
365             $entity->ambiguous_content();
366              
367             The first returns true only if this specific entity's headers indicate
368             ambiguity. The second returns true if this entity
369             I has headers that indicate ambiguity.
370              
371             =cut
372             sub ambiguous_content {
373 23     23 1 91 my ($self) = @_;
374              
375 23 100       78 return 1 if $self->head->ambiguous_content;
376 13 100       61 return 0 unless $self->is_multipart;
377              
378 6         31 foreach my $part ($self->parts) {
379 12 100       50 return 1 if $part->ambiguous_content;
380             }
381 1         11 return 0;
382             }
383              
384             ###------------------------------
385              
386             =item add_part ENTITY, [OFFSET]
387              
388             I
389             Assuming we are a multipart message, add a body part (a MIME::Entity)
390             to the array of body parts. Returns the part that was just added.
391              
392             If OFFSET is positive, the new part is added at that offset from the
393             beginning of the array of parts. If it is negative, it counts from
394             the end of the array. (An INDEX of -1 will place the new part at the
395             very end of the array, -2 will place it as the penultimate item in the
396             array, etc.) If OFFSET is not given, the new part is added to the end
397             of the array.
398             I
399              
400             B in general, you only want to attach parts to entities
401             with a content-type of C).
402              
403             =cut
404              
405             sub add_part {
406 151     151 1 452 my ($self, $part, $index) = @_;
407 151 50       424 defined($index) or $index = -1;
408              
409             ### Make $index count from the end if negative:
410 151 50       356 $index = $#{$self->{ME_Parts}} + 2 + $index if ($index < 0);
  151         420  
411 151         294 splice(@{$self->{ME_Parts}}, $index, 0, $part);
  151         437  
412 151         327 $part;
413             }
414              
415             #------------------------------
416              
417             =item attach PARAMHASH
418              
419             I
420             The real quick-and-easy way to create multipart messages.
421             The PARAMHASH is used to C a new entity; this method is
422             basically equivalent to:
423              
424             $entity->add_part(ref($entity)->build(PARAMHASH, Top=>0));
425              
426             B normally, you attach to multipart entities; however, if you
427             attach something to a singlepart (like attaching a GIF to a text
428             message), the singlepart will be coerced into a multipart automatically.
429              
430             =cut
431              
432             sub attach {
433 10     10 1 648 my $self = shift;
434 10         27 $self->make_multipart;
435 10         39 $self->add_part(ref($self)->build(@_, Top=>0));
436             }
437              
438             #------------------------------
439              
440             =item build PARAMHASH
441              
442             I
443             A quick-and-easy catch-all way to create an entity. Use it like this
444             to build a "normal" single-part entity:
445              
446             $ent = MIME::Entity->build(Type => "image/gif",
447             Encoding => "base64",
448             Path => "/path/to/xyz12345.gif",
449             Filename => "saveme.gif",
450             Disposition => "attachment");
451              
452             And like this to build a "multipart" entity:
453              
454             $ent = MIME::Entity->build(Type => "multipart/mixed",
455             Boundary => "---1234567");
456              
457             A minimal MIME header will be created. If you want to add or modify
458             any header fields afterwards, you can of course do so via the underlying
459             head object... but hey, there's now a prettier syntax!
460              
461             $ent = MIME::Entity->build(Type =>"multipart/mixed",
462             From => $myaddr,
463             Subject => "Hi!",
464             'X-Certified' => ['SINED',
465             'SEELED',
466             'DELIVERED']);
467              
468             Normally, an C header field is output which contains this
469             toolkit's name and version (plus this module's RCS version).
470             This will allow any bad MIME we generate to be traced back to us.
471             You can of course overwrite that header with your own:
472              
473             $ent = MIME::Entity->build(Type => "multipart/mixed",
474             'X-Mailer' => "myprog 1.1");
475              
476             Or remove it entirely:
477              
478             $ent = MIME::Entity->build(Type => "multipart/mixed",
479             'X-Mailer' => undef);
480              
481             OK, enough hype. The parameters are:
482              
483             =over 4
484              
485             =item (FIELDNAME)
486              
487             Any field you want placed in the message header, taken from the
488             standard list of header fields (you don't need to worry about case):
489              
490             Bcc Encrypted Received Sender
491             Cc From References Subject
492             Comments Keywords Reply-To To
493             Content-* Message-ID Resent-* X-*
494             Date MIME-Version Return-Path
495             Organization
496              
497             To give experienced users some veto power, these fields will be set
498             I the ones I set... so be careful: I
499             (like C) unless you know what you're doing!
500              
501             To specify a fieldname that's I in the above list, even one that's
502             identical to an option below, just give it with a trailing C<":">,
503             like C<"My-field:">. When in doubt, that I signals a mail
504             field (and it sort of looks like one too).
505              
506             =item Boundary
507              
508             I
509             The boundary string. As per RFC-2046, it must consist only
510             of the characters C<[0-9a-zA-Z'()+_,-./:=?]> and space (you'll be
511             warned, and your boundary will be ignored, if this is not the case).
512             If you omit this, a random string will be chosen... which is probably
513             safer.
514              
515             =item Charset
516              
517             I
518             The character set.
519              
520             =item Data
521              
522             I
523             An alternative to Path (q.v.): the actual data, either as a scalar
524             or an array reference (whose elements are joined together to make
525             the actual scalar). The body is opened on the data using
526             MIME::Body::InCore.
527              
528             Note that for text parts, the Data scalar or array is assumed to be
529             encoded in a suitable character encoding (as if by C)
530             rather than a native Perl string. The encoding you use must, of
531             course, match the C option of the C header.
532              
533             =item Description
534              
535             I
536             The text of the content-description.
537             If you don't specify it, the field is not put in the header.
538              
539             =item Disposition
540              
541             I
542             The basic content-disposition (C<"attachment"> or C<"inline">).
543             If you don't specify it, it defaults to "inline" for backwards
544             compatibility. I
545              
546             =item Encoding
547              
548             I
549             The content-transfer-encoding.
550             If you don't specify it, a reasonable default is put in.
551             You can also give the special value '-SUGGEST', to have it chosen for
552             you in a heavy-duty fashion which scans the data itself.
553              
554             =item Filename
555              
556             I
557             The recommended filename. Overrides any name extracted from C.
558             The information is stored both the deprecated (content-type) and
559             preferred (content-disposition) locations. If you explicitly want to
560             I a recommended filename (even when Path is used), supply this
561             as empty or undef.
562              
563             =item Id
564              
565             I
566             Set the content-id.
567              
568             =item Path
569              
570             I
571             The path to the file to attach. The body is opened on that file
572             using MIME::Body::File.
573              
574             =item Top
575              
576             I
577             Is this a top-level entity? If so, it must sport a MIME-Version.
578             The default is true. (NB: look at how C uses it.)
579              
580             =item Type
581              
582             I
583             The basic content-type (C<"text/plain">, etc.).
584             If you don't specify it, it defaults to C<"text/plain">
585             as per RFC 2045. I
586              
587             =back
588              
589             =cut
590              
591             sub build {
592 39     39 1 946440 my ($self, @paramlist) = @_;
593 39         122 my %params = @paramlist;
594 39         59 my ($field, $filename, $boundary);
595              
596             ### Create a new entity, if needed:
597 39 50       139 ref($self) or $self = $self->new;
598              
599              
600             ### GET INFO...
601              
602             ### Get sundry field:
603 39   100     111 my $type = $params{Type} || 'text/plain';
604 39         61 my $charset = $params{Charset};
605 39         81 my $is_multipart = ($type =~ m{^multipart/}i);
606 39   100     101 my $encoding = $params{Encoding} || '';
607 39         56 my $desc = $params{Description};
608 39 100       78 my $top = exists($params{Top}) ? $params{Top} : 1;
609 39   100     158 my $disposition = $params{Disposition} || 'inline';
610 39         58 my $id = $params{Id};
611              
612             ### Get recommended filename, allowing explicit no-value value:
613 39   100     185 my ($path_fname) = (($params{Path}||'') =~ m{([^/]+)\Z});
614 39 100       112 $filename = (exists($params{Filename}) ? $params{Filename} : $path_fname);
615 39 50 66     118 $filename = undef if (defined($filename) and $filename eq '');
616              
617             ### Type-check sanity:
618 39 100       107 if ($type =~ m{^(multipart/|message/(rfc822|partial|external-body|delivery-status|disposition-notification|feedback-report)$)}i) {
619 7 100       371 ($encoding =~ /^(|7bit|8bit|binary|-suggest)$/i)
620             or croak "can't have encoding $encoding for message type $type!";
621             }
622              
623             ### Multipart or not? Do sanity check and fixup:
624 37 100       100 if ($is_multipart) { ### multipart...
625              
626             ### Get any supplied boundary, and check it:
627 5 100       13 if (defined($boundary = $params{Boundary})) { ### they gave us one...
628 2 50       8 if ($boundary eq '') {
    50          
629 0         0 whine "empty string not a legal boundary: I'm ignoring it";
630 0         0 $boundary = undef;
631             }
632             elsif ($boundary =~ m{[^0-9a-zA-Z_\'\(\)\+\,\.\/\:\=\?\- ]}) {
633 0         0 whine "boundary ignored: illegal characters ($boundary)";
634 0         0 $boundary = undef;
635             }
636             }
637              
638             ### If we have to roll our own boundary, do so:
639 5 100       30 defined($boundary) or $boundary = make_boundary();
640             }
641             else { ### single part...
642             ### Create body:
643 32 100       75 if ($params{Path}) {
    50          
644 14         108 $self->bodyhandle(new MIME::Body::File $params{Path});
645             }
646             elsif (defined($params{Data})) {
647 18         137 $self->bodyhandle(new MIME::Body::InCore $params{Data});
648             }
649             else {
650 0         0 die "can't build entity: no body, and not multipart\n";
651             }
652              
653             ### Check whether we need to binmode(): [Steve Kilbane]
654 32 100       111 $self->bodyhandle->binmode(1) unless textual_type($type);
655             }
656              
657              
658             ### MAKE HEAD...
659              
660             ### Create head:
661 37         92 my $head = new MIME::Head;
662 37         954 $self->head($head);
663 37         114 $head->modify(1);
664              
665             ### Add content-type field:
666 37         296 $field = new Mail::Field 'Content_type'; ### not a typo :-(
667 37         109 $field->type($type);
668 37 100       75 $field->charset($charset) if $charset;
669 37 100       175 $field->name($filename) if defined($filename);
670 37 100       83 $field->boundary($boundary) if defined($boundary);
671 37         85 $head->replace('Content-type', $field->stringify);
672              
673             ### Now that both body and content-type are available, we can suggest
674             ### content-transfer-encoding (if desired);
675 37 100       6264 if (!$encoding) {
    100          
676 30         141 $encoding = $self->suggest_encoding_lite;
677             }
678             elsif (lc($encoding) eq '-suggest') {
679 3         8 $encoding = $self->suggest_encoding;
680             }
681              
682             ### Add content-disposition field (if not multipart):
683 37 100       81 unless ($is_multipart) {
684 32         141 $field = new Mail::Field 'Content_disposition'; ### not a typo :-(
685 32         157 $field->type($disposition);
686 32 100       100 $field->filename($filename) if defined($filename);
687 32         81 $head->replace('Content-disposition', $field->stringify);
688             }
689              
690             ### Add other MIME fields:
691 37 50       4981 $head->replace('Content-transfer-encoding', $encoding) if $encoding;
692 37 50       5273 $head->replace('Content-description', $desc) if $desc;
693              
694             # Content-Id value should be surrounded by < >, but versions before 5.428
695             # did not do this. So, we check, and add if the caller has not done so
696             # already.
697 37 100       81 if( defined $id ) {
698 2 100       10 if( $id !~ /^<.*>$/ ) {
699 1         3 $id = "<$id>";
700             }
701 2         7 $head->replace('Content-id', $id);
702             }
703 37 100       624 $head->replace('MIME-Version', '1.0') if $top;
704              
705             ### Add the X-Mailer field, if top level (use default value if not given):
706 37 100       3815 $top and $head->replace('X-Mailer',
707             "MIME-tools ".(MIME::Tools->version).
708             " (Entity " .($VERSION).")");
709              
710             ### Add remaining user-specified fields, if any:
711 37         3739 while (@paramlist) {
712 107         2714 my ($tag, $value) = (shift @paramlist, shift @paramlist);
713              
714             ### Get fieldname, if that's what it is:
715 107 100       338 if ($tag =~ /^-(.*)/s) { $tag = lc($1) } ### old style, b.c.
  2 50       4  
    100          
716 0         0 elsif ($tag =~ /(.*):$/s ) { $tag = lc($1) } ### new style
717 21         22 elsif (known_field(lc($tag))) { 1 } ### known field
718 84         180 else { next; } ### not a field
719              
720             ### Clear head, get list of values, and add them:
721 23         87 $head->delete($tag);
722 23 50       522 foreach $value (ref($value) ? @$value : ($value)) {
723 23 50 33     108 (defined($value) && ($value ne '')) or next;
724 23         57 $head->add($tag, $value);
725             }
726             }
727              
728             ### Done!
729 37         617 $self;
730             }
731              
732             #------------------------------
733              
734             =item dup
735              
736             I
737             Duplicate the entity. Does a deep, recursive copy, I
738             external data in bodyhandles is I copied to new files!
739             Changing the data in one entity's data file, or purging that entity,
740             I affect its duplicate. Entities with in-core data probably need
741             not worry.
742              
743             =cut
744              
745             sub dup {
746 7     7 1 15 my $self = shift;
747 7         14 local($_);
748              
749             ### Self (this will also dup the header):
750 7         41 my $dup = bless $self->SUPER::dup(), ref($self);
751              
752             ### Any simple inst vars:
753 7 50       1238 foreach (keys %$self) {$dup->{$_} = $self->{$_} unless ref($self->{$_})};
  20         82  
754              
755             ### Bodyhandle:
756 7 100       26 $dup->bodyhandle($self->bodyhandle ? $self->bodyhandle->dup : undef);
757              
758             ### Preamble and epilogue:
759 7         17 foreach (qw(ME_Preamble ME_Epilogue)) {
760 14 100       39 $dup->{$_} = [@{$self->{$_}}] if $self->{$_};
  2         7  
761             }
762              
763             ### Parts:
764 7         17 $dup->{ME_Parts} = [];
765 7         14 foreach (@{$self->{ME_Parts}}) { push @{$dup->{ME_Parts}}, $_->dup }
  7         19  
  4         7  
  4         13  
766              
767             ### Done!
768 7         24 $dup;
769             }
770              
771             =back
772              
773             =cut
774              
775              
776              
777              
778              
779             #==============================
780              
781             =head2 Access
782              
783             =over 4
784              
785             =cut
786              
787              
788             #------------------------------
789              
790             =item body [VALUE]
791              
792             I
793             Get the I (transport-ready) body, as an array of lines.
794             Returns an array reference. Each array entry is a newline-terminated
795             line.
796              
797             This is a read-only data structure: changing its contents will have
798             no effect. Its contents are identical to what is printed by
799             L.
800              
801             Provided for compatibility with Mail::Internet, so that methods
802             like C will work. Note however that if VALUE is given,
803             a fatal exception is thrown, since you cannot use this method to
804             I the lines of the encoded message.
805              
806             If you want the raw (unencoded) body data, use the L
807             method to get and use a MIME::Body. The content-type of the entity
808             will tell you whether that body is best read as text (via getline())
809             or raw data (via read()).
810              
811             =cut
812              
813             sub body {
814 3     3 1 6359 my ($self, $value) = @_;
815 3   50     68 my $boundary_delimiter = $MIME::Entity::BOUNDARY_DELIMITER || "\n";
816 3 50       34 if (@_ > 1) { ### setting body line(s)...
817 0         0 croak "you cannot use body() to set the encoded contents\n";
818             } else {
819 3         8 my $output = '';
820 3 50       41 my $fh = IO::File->new(\$output, '>:') or croak("Cannot open in-memory file: $!");
821 3         450 $self->print_body($fh);
822 3         9 close($fh);
823 3         20 my @ary = split(/\n/, $output);
824             # Each line needs the terminating newline
825 3         12 @ary = map { "$_$boundary_delimiter" } @ary;
  27         70  
826              
827 3         52 return \@ary;
828             }
829             }
830              
831             #------------------------------
832              
833             =item bodyhandle [VALUE]
834              
835             I
836             Get or set an abstract object representing the body of the message.
837             The body holds the decoded message data.
838              
839             B
840             An entity will have either a body or parts: not both.
841             This method will I return an object if this entity can
842             have a body; otherwise, it will return undefined.
843             Whether-or-not a given entity can have a body is determined by
844             (1) its content type, and (2) whether-or-not the parser was told to
845             extract nested messages:
846              
847             Type: | Extract nested? | bodyhandle() | parts()
848             -----------------------------------------------------------------------
849             multipart/* | - | undef | 0 or more MIME::Entity
850             message/* | true | undef | 0 or 1 MIME::Entity
851             message/* | false | MIME::Body | empty list
852             (other) | - | MIME::Body | empty list
853              
854             If C I given, the current bodyhandle is returned,
855             or undef if the entity cannot have a body.
856              
857             If C I given, the bodyhandle is set to the new value,
858             and the previous value is returned.
859              
860             See L for more info.
861              
862             =cut
863              
864             sub bodyhandle {
865 659     659 1 15253 my ($self, $newvalue) = @_;
866 659         1180 my $value = $self->{ME_Bodyhandle};
867 659 100       1588 $self->{ME_Bodyhandle} = $newvalue if (@_ > 1);
868 659         2290 $value;
869             }
870              
871             #------------------------------
872              
873             =item effective_type [MIMETYPE]
874              
875             I
876             Set/get the I MIME type of this entity. This is I
877             identical to the actual (or defaulted) MIME type, but in some cases
878             it differs. For example, from RFC-2045:
879              
880             Any entity with an unrecognized Content-Transfer-Encoding must be
881             treated as if it has a Content-Type of "application/octet-stream",
882             regardless of what the Content-Type header field actually says.
883              
884             Why? because if we can't decode the message, then we have to take
885             the bytes as-is, in their (unrecognized) encoded form. So the
886             message ceases to be a "text/foobar" and becomes a bunch of undecipherable
887             bytes -- in other words, an "application/octet-stream".
888              
889             Such an entity, if parsed, would have its effective_type() set to
890             C<"application/octet_stream">, although the mime_type() and the contents
891             of the header would remain the same.
892              
893             If there is no effective type, the method just returns what
894             mime_type() would.
895              
896             B the effective type is "sticky"; once set, that effective_type()
897             will always be returned even if the conditions that necessitated setting
898             the effective type become no longer true.
899              
900             =cut
901              
902             sub effective_type {
903 354     354 1 576 my $self = shift;
904 354 50       782 $self->{ME_EffType} = shift if @_;
905 354 50       1225 return ($self->{ME_EffType} ? lc($self->{ME_EffType}) : $self->mime_type);
906             }
907              
908              
909             #------------------------------
910              
911             =item epilogue [LINES]
912              
913             I
914             Get/set the text of the epilogue, as an array of newline-terminated LINES.
915             Returns a reference to the array of lines, or undef if no epilogue exists.
916              
917             If there is a epilogue, it is output when printing this entity; otherwise,
918             a default epilogue is used. Setting the epilogue to undef (not []!) causes
919             it to fallback to the default.
920              
921             =cut
922              
923             sub epilogue {
924 65     65 1 196 my ($self, $lines) = @_;
925 65 100       260 $self->{ME_Epilogue} = $lines if @_ > 1;
926 65         212 $self->{ME_Epilogue};
927             }
928              
929             #------------------------------
930              
931             =item head [VALUE]
932              
933             I
934             Get/set the head.
935              
936             If there is no VALUE given, returns the current head. If none
937             exists, an empty instance of MIME::Head is created, set, and returned.
938              
939             B This is a patch over a problem in Mail::Internet, which doesn't
940             provide a method for setting the head to some given object.
941              
942             =cut
943              
944             sub head {
945 2331     2331 1 1212162 my ($self, $value) = @_;
946 2331 100       5987 (@_ > 1) and $self->{'mail_inet_head'} = $value;
947 2331   66     10426 $self->{'mail_inet_head'} ||= new MIME::Head; ### KLUDGE!
948             }
949              
950             #------------------------------
951              
952             =item is_multipart
953              
954             I
955             Does this entity's effective MIME type indicate that it's a multipart entity?
956             Returns undef (false) if the answer couldn't be determined, 0 (false)
957             if it was determined to be false, and true otherwise.
958             Note that this says nothing about whether or not parts were extracted.
959              
960             NOTE: we switched to effective_type so that multiparts with
961             bad or missing boundaries could be coerced to an effective type
962             of C.
963              
964              
965             =cut
966              
967             sub is_multipart {
968 46     46 1 238 my $self = shift;
969 46 50       111 $self->head or return undef; ### no head, so no MIME type!
970 46         134 my ($type, $subtype) = split('/', $self->effective_type);
971 46 100       365 (($type eq 'multipart') ? 1 : 0);
972             }
973              
974             #------------------------------
975              
976             =item mime_type
977              
978             I
979             A purely-for-convenience method. This simply relays the request to the
980             associated MIME::Head object.
981             If there is no head, returns undef in a scalar context and
982             the empty array in a list context.
983              
984             B consider using effective_type() instead,
985             especially if you obtained the entity from a MIME::Parser.
986              
987             =cut
988              
989             sub mime_type {
990 444     444 1 1178 my $self = shift;
991 444 0       917 $self->head or return (wantarray ? () : undef);
    50          
992 444         979 $self->head->mime_type;
993             }
994              
995             #------------------------------
996              
997             =item open READWRITE
998              
999             I
1000             A purely-for-convenience method. This simply relays the request to the
1001             associated MIME::Body object (see MIME::Body::open()).
1002             READWRITE is either 'r' (open for read) or 'w' (open for write).
1003              
1004             If there is no body, returns false.
1005              
1006             =cut
1007              
1008             sub open {
1009 74     74 1 116 my $self = shift;
1010 74 50       331 $self->bodyhandle and $self->bodyhandle->open(@_);
1011             }
1012              
1013             #------------------------------
1014              
1015             =item parts
1016              
1017             =item parts INDEX
1018              
1019             =item parts ARRAYREF
1020              
1021             I
1022             Return the MIME::Entity objects which are the sub parts of this
1023             entity (if any).
1024              
1025             I returns the array of all sub parts,
1026             returning the empty array if there are none (e.g., if this is a single
1027             part message, or a degenerate multipart). In a scalar context, this
1028             returns you the number of parts.
1029              
1030             I return the INDEXed part,
1031             or undef if it doesn't exist.
1032              
1033             I then this method I
1034             the parts to a copy of that array, and returns the parts. This can
1035             be used to delete parts, as follows:
1036              
1037             ### Delete some parts of a multipart message:
1038             $msg->parts([ grep { keep_part($_) } $msg->parts ]);
1039              
1040              
1041             B for multipart messages, the preamble and epilogue are I
1042             considered parts. If you need them, use the C and C
1043             methods.
1044              
1045             B there are ways of parsing with a MIME::Parser which cause
1046             certain message parts (such as those of type C)
1047             to be "reparsed" into pseudo-multipart entities. You should read the
1048             documentation for those options carefully: it I possible for
1049             a diddled entity to not be multipart, but still have parts attached to it!
1050              
1051             See L for a discussion of parts vs. bodies.
1052              
1053             =cut
1054              
1055             sub parts {
1056 232     232 1 5989 my $self = shift;
1057 232 100       648 ref($_[0]) and return @{$self->{ME_Parts} = [@{$_[0]}]}; ### set the parts
  5         11  
  5         30  
1058 227 100       841 (@_ ? $self->{ME_Parts}[$_[0]] : @{$self->{ME_Parts}});
  116         441  
1059             }
1060              
1061             #------------------------------
1062              
1063             =item parts_DFS
1064              
1065             I
1066             Return the list of all MIME::Entity objects included in the entity,
1067             starting with the entity itself, in depth-first-search order.
1068             If the entity has no parts, it alone will be returned.
1069              
1070             I
1071              
1072             =cut
1073              
1074             sub parts_DFS {
1075 0     0 1 0 my $self = shift;
1076 0         0 return ($self, map { $_->parts_DFS } $self->parts);
  0         0  
1077             }
1078              
1079             #------------------------------
1080              
1081             =item preamble [LINES]
1082              
1083             I
1084             Get/set the text of the preamble, as an array of newline-terminated LINES.
1085             Returns a reference to the array of lines, or undef if no preamble exists
1086             (e.g., if this is a single-part entity).
1087              
1088             If there is a preamble, it is output when printing this entity; otherwise,
1089             a default preamble is used. Setting the preamble to undef (not []!) causes
1090             it to fallback to the default.
1091              
1092             =cut
1093              
1094             sub preamble {
1095 72     72 1 3120 my ($self, $lines) = @_;
1096 72 100       289 $self->{ME_Preamble} = $lines if @_ > 1;
1097 72         212 $self->{ME_Preamble};
1098             }
1099              
1100              
1101              
1102              
1103              
1104             =back
1105              
1106             =cut
1107              
1108              
1109              
1110              
1111             #==============================
1112              
1113             =head2 Manipulation
1114              
1115             =over 4
1116              
1117             =cut
1118              
1119             #------------------------------
1120              
1121             =item make_multipart [SUBTYPE], OPTSHASH...
1122              
1123             I
1124             Force the entity to be a multipart, if it isn't already.
1125             We do this by replacing the original [singlepart] entity with a new
1126             multipart that has the same non-MIME headers ("From", "Subject", etc.),
1127             but all-new MIME headers ("Content-type", etc.). We then create
1128             a copy of the original singlepart, I the non-MIME headers
1129             from that, and make it a part of the new multipart. So this:
1130              
1131             From: me
1132             To: you
1133             Content-type: text/plain
1134             Content-length: 12
1135              
1136             Hello there!
1137              
1138             Becomes something like this:
1139              
1140             From: me
1141             To: you
1142             Content-type: multipart/mixed; boundary="----abc----"
1143              
1144             ------abc----
1145             Content-type: text/plain
1146             Content-length: 12
1147              
1148             Hello there!
1149             ------abc------
1150              
1151             The actual type of the new top-level multipart will be "multipart/SUBTYPE"
1152             (default SUBTYPE is "mixed").
1153              
1154             Returns 'DONE' if we really did inflate a singlepart to a multipart.
1155             Returns 'ALREADY' (and does nothing) if entity is I multipart
1156             and Force was not chosen.
1157              
1158             If OPTSHASH contains Force=>1, then we I bump the top-level's
1159             content and content-headers down to a subpart of this entity, even if
1160             this entity is already a multipart. This is apparently of use to
1161             people who are tweaking messages after parsing them.
1162              
1163             =cut
1164              
1165             sub make_multipart {
1166 12     12 1 24 my ($self, $subtype, %opts) = @_;
1167 12         15 my $tag;
1168 12   50     79 $subtype ||= 'mixed';
1169 12         32 my $force = $opts{Force};
1170              
1171             ### Trap for simple case: already a multipart?
1172 12 100 66     26 return 'ALREADY' if ($self->is_multipart and !$force);
1173              
1174             ### Rip out our guts, and spew them into our future part:
1175 3         14 my $part = bless {%$self}, ref($self); ### part is a shallow copy
1176 3         8 %$self = (); ### lobotomize ourselves!
1177 3         7 $self->head($part->head->dup); ### dup the header
1178              
1179             ### Remove content headers from top-level, and set it up as a multipart:
1180 3         7 foreach $tag (grep {/^content-/i} $self->head->tags) {
  11         41  
1181 3         185 $self->head->delete($tag);
1182             }
1183 3         104 $self->head->mime_attr('Content-type' => "multipart/$subtype");
1184 3         11 $self->head->mime_attr('Content-type.boundary' => make_boundary());
1185              
1186             ### Remove NON-content headers from the part:
1187 3         9 foreach $tag (grep {!/^content-/i} $part->head->tags) {
  11         25  
1188 8         363 $part->head->delete($tag);
1189             }
1190              
1191             ### Add the [sole] part:
1192 3         93 $self->{ME_Parts} = [];
1193 3         11 $self->add_part($part);
1194 3         6 'DONE';
1195             }
1196              
1197             #------------------------------
1198              
1199             =item make_singlepart
1200              
1201             I
1202             If the entity is a multipart message with one part, this tries hard to
1203             rewrite it as a singlepart, by replacing the content (and content headers)
1204             of the top level with those of the part. Also crunches 0-part multiparts
1205             into singleparts.
1206              
1207             Returns 'DONE' if we really did collapse a multipart to a singlepart.
1208             Returns 'ALREADY' (and does nothing) if entity is already a singlepart.
1209             Returns '0' (and does nothing) if it can't be made into a singlepart.
1210              
1211             =cut
1212              
1213             sub make_singlepart {
1214 1     1 1 12 my $self = shift;
1215              
1216             ### Trap for simple cases:
1217 1 50       5 return 'ALREADY' if !$self->is_multipart; ### already a singlepart?
1218 1 50       5 return '0' if ($self->parts > 1); ### can this even be done?
1219              
1220             # Get rid of all our existing content info
1221 1         3 my $tag;
1222 1         4 foreach $tag (grep {/^content-/i} $self->head->tags) {
  13         55  
1223 1         5 $self->head->delete($tag);
1224             }
1225              
1226 1 50       224 if ($self->parts == 1) { ### one part
1227 0         0 my $part = $self->parts(0);
1228              
1229             ### Populate ourselves with any content info from the part:
1230 0         0 foreach $tag (grep {/^content-/i} $part->head->tags) {
  0         0  
1231 0         0 foreach ($part->head->get($tag)) { $self->head->add($tag, $_) }
  0         0  
1232             }
1233              
1234             ### Save reconstructed header, replace our guts, and restore header:
1235 0         0 my $new_head = $self->head;
1236 0         0 %$self = %$part; ### shallow copy is ok!
1237 0         0 $self->head($new_head);
1238              
1239             ### One more thing: the part *may* have been a multi with 0 or 1 parts!
1240 0 0       0 return $self->make_singlepart(@_) if $self->is_multipart;
1241             }
1242             else { ### no parts!
1243 1         6 $self->head->mime_attr('Content-type'=>'text/plain'); ### simple
1244             }
1245 1         10 'DONE';
1246             }
1247              
1248             #------------------------------
1249              
1250             =item purge
1251              
1252             I
1253             Recursively purge (e.g., unlink) all external (e.g., on-disk) body parts
1254             in this message. See MIME::Body::purge() for details.
1255              
1256             B this does I delete the directories that those body parts
1257             are contained in; only the actual message data files are deleted.
1258             This is because some parsers may be customized to create intermediate
1259             directories while others are not, and it's impossible for this class
1260             to know what directories are safe to remove. Only your application
1261             program truly knows that.
1262              
1263             B one good way is to
1264             use C, and then do this before parsing
1265             your next message:
1266              
1267             $parser->filer->purge();
1268              
1269             I wouldn't attempt to read those body files after you do this, for
1270             obvious reasons. As of MIME-tools 4.x, each body's path I undefined
1271             after this operation. I warned you I might do this; truly I did.
1272              
1273             I
1274              
1275             =cut
1276              
1277             sub purge {
1278 4     4 1 10 my $self = shift;
1279 4 100       13 $self->bodyhandle and $self->bodyhandle->purge; ### purge me
1280 4         16 foreach ($self->parts) { $_->purge } ### recurse
  3         12  
1281 4         10 1;
1282             }
1283              
1284             #------------------------------
1285             #
1286             # _do_remove_sig
1287             #
1288             # Private. Remove a signature within NLINES lines from the end of BODY.
1289             # The signature must be flagged by a line containing only "-- ".
1290              
1291             sub _do_remove_sig {
1292 4     4   13 my ($body, $nlines) = @_;
1293 4   100     19 $nlines ||= 10;
1294 4         9 my $i = 0;
1295              
1296 4   50     12 my $line = int(@$body) || return;
1297 4   66     20 while ($i++ < $nlines and $line--) {
1298 25 100       102 if ($body->[$line] =~ /\A--[ \040][\r\n]+\Z/) {
1299 2         6 $#{$body} = $line-1;
  2         10  
1300 2         6 return;
1301             }
1302             }
1303             }
1304              
1305             #------------------------------
1306              
1307             =item remove_sig [NLINES]
1308              
1309             I
1310             Attempts to remove a user's signature from the body of a message.
1311              
1312             It does this by looking for a line matching C within the last
1313             C of the message. If found then that line and all lines after
1314             it will be removed. If C is not given, a default value of 10
1315             will be used. This would be of most use in auto-reply scripts.
1316              
1317             For MIME entity, this method is reasonably cautious: it will only
1318             attempt to un-sign a message with a content-type of C.
1319              
1320             If you send remove_sig() to a multipart entity, it will relay it to
1321             the first part (the others usually being the "attachments").
1322              
1323             B currently slurps the whole message-part into core as an
1324             array of lines, so you probably don't want to use this on extremely
1325             long messages.
1326              
1327             Returns truth on success, false on error.
1328              
1329             =cut
1330              
1331             sub remove_sig {
1332 3     3 1 823 my $self = shift;
1333 3         8 my $nlines = shift;
1334              
1335             # If multipart, we only attempt to remove the sig from the first
1336             # part. This is usually a good assumption for multipart/mixed, but
1337             # may not always be correct. It is also possibly incorrect on
1338             # multipart/alternative (both may have sigs).
1339 3 100       10 if( $self->is_multipart ) {
1340 2         10 my $first_part = $self->parts(0);
1341 2 100       9 if( $first_part ) {
1342 1         24 return $first_part->remove_sig(@_);
1343             }
1344 1         6 return undef;
1345             }
1346              
1347             ### Refuse non-textual unless forced:
1348 1 50       6 textual_type($self->head->mime_type)
1349             or return error "I won't un-sign a non-text message unless I'm forced";
1350              
1351             ### Get body data, as an array of newline-terminated lines:
1352 1 50       5 $self->bodyhandle or return undef;
1353 1         4 my @body = $self->bodyhandle->as_lines;
1354              
1355             ### Nuke sig:
1356 1         7 _do_remove_sig(\@body, $nlines);
1357              
1358             ### Output data back into body:
1359 1         5 my $io = $self->bodyhandle->open("w");
1360 1         4 foreach (@body) { $io->print($_) }; ### body data
  6         92  
1361 1         9 $io->close;
1362              
1363             ### Done!
1364 1         82 1;
1365             }
1366              
1367             #------------------------------
1368              
1369             =item sign PARAMHASH
1370              
1371             I
1372             Append a signature to the message. The params are:
1373              
1374             =over 4
1375              
1376             =item Attach
1377              
1378             Instead of appending the text, add it to the message as an attachment.
1379             The disposition will be C, and the description will indicate
1380             that it is a signature. The default behavior is to append the signature
1381             to the text of the message (or the text of its first part if multipart).
1382             I
1383              
1384             =item File
1385              
1386             Use the contents of this file as the signature.
1387             Fatal error if it can't be read.
1388             I
1389              
1390             =item Force
1391              
1392             Sign it even if the content-type isn't C. Useful for
1393             non-standard types like C, but be careful!
1394             I
1395              
1396             =item Remove
1397              
1398             Normally, we attempt to strip out any existing signature.
1399             If true, this gives us the NLINES parameter of the remove_sig call.
1400             If zero but defined, tells us I to remove any existing signature.
1401             If undefined, removal is done with the default of 10 lines.
1402             I
1403              
1404             =item Signature
1405              
1406             Use this text as the signature. You can supply it as either
1407             a scalar, or as a ref to an array of newline-terminated scalars.
1408             I
1409              
1410             =back
1411              
1412             For MIME messages, this method is reasonably cautious: it will only
1413             attempt to sign a message with a content-type of C, unless
1414             C is specified.
1415              
1416             If you send this message to a multipart entity, it will relay it to
1417             the first part (the others usually being the "attachments").
1418              
1419             B currently slurps the whole message-part into core as an
1420             array of lines, so you probably don't want to use this on extremely
1421             long messages.
1422              
1423             Returns true on success, false otherwise.
1424              
1425             =cut
1426              
1427             sub sign {
1428 6     6 1 1151 my $self = shift;
1429 6         23 my %params = @_;
1430 6         13 my $io;
1431              
1432 6   50     28 my $boundary_delimiter = $MIME::Entity::BOUNDARY_DELIMITER || "\n";
1433             ### If multipart and not attaching, try to sign our first part:
1434 6 100 66     16 if ($self->is_multipart and !$params{Attach}) {
1435 3         13 return $self->parts(0)->sign(@_);
1436             }
1437              
1438             ### Get signature:
1439 3         8 my $sig;
1440 3 50       13 if (defined($sig = $params{Signature})) { ### scalar or array
    50          
1441 0 0       0 $sig = (ref($sig) ? join('', @$sig) : $sig);
1442             }
1443             elsif ($params{File}) { ### file contents
1444 3 50       24 my $fh = IO::File->new( $params{File} ) or croak "can't open $params{File}: $!";
1445 3         523 $sig = join('', $fh->getlines);
1446 3 50       21 $fh->close or croak "can't close $params{File}: $!";
1447             }
1448             else {
1449 0         0 croak "no signature given!";
1450             }
1451              
1452             ### Add signature to message as appropriate:
1453 3 50       79 if ($params{Attach}) { ### Attach .sig as new part...
1454 0         0 return $self->attach(Type => 'text/plain',
1455             Description => 'Signature',
1456             Disposition => 'inline',
1457             Encoding => '-SUGGEST',
1458             Data => $sig);
1459             }
1460             else { ### Add text of .sig to body data...
1461              
1462             ### Refuse non-textual unless forced:
1463 3 0 33     11 ($self->head->mime_type =~ m{text/}i or $params{Force}) or
1464             return error "I won't sign a non-text message unless I'm forced";
1465              
1466             ### Get body data, as an array of newline-terminated lines:
1467 3 50       12 $self->bodyhandle or return undef;
1468 3         9 my @body = $self->bodyhandle->as_lines;
1469              
1470             ### Nuke any existing sig?
1471 3 50 66     21 if (!defined($params{Remove}) || ($params{Remove} > 0)) {
1472 3         14 _do_remove_sig(\@body, $params{Remove});
1473             }
1474              
1475             ### Output data back into body, followed by signature:
1476 3         8 my $line;
1477 3 50       11 $io = $self->open("w") or croak("open: $!");
1478 3         9 foreach $line (@body) { $io->print($line) }; ### body data
  18         134  
1479 3 50 50     35 (($body[-1]||'') =~ /\n\Z/) or $io->print($boundary_delimiter); ### ensure final \n
1480 3         47 $io->print("-- $boundary_delimiter$sig"); ### separator + sig
1481 3 50       24 $io->close or croak("close: $!");
1482 3         536 return 1; ### done!
1483             }
1484             }
1485              
1486             #------------------------------
1487              
1488             =item suggest_encoding
1489              
1490             I
1491             Based on the effective content type, return a good suggested encoding.
1492              
1493             C and C types have their bodies scanned line-by-line
1494             for 8-bit characters and long lines; lack of either means that the
1495             message is 7bit-ok. Other types are chosen independent of their body:
1496              
1497             Major type: 7bit ok? Suggested encoding:
1498             -----------------------------------------------------------
1499             text yes 7bit
1500             text no quoted-printable
1501             message yes 7bit
1502             message no binary
1503             multipart * binary (in case some parts are bad)
1504             image, etc... * base64
1505              
1506             =cut
1507              
1508             ### TO DO: resolve encodings of nested entities (possibly in sync_headers).
1509              
1510             sub suggest_encoding {
1511 3     3 1 5 my $self = shift;
1512              
1513 3         6 my ($type) = split '/', $self->effective_type;
1514 3 100 66     11 if (($type eq 'text') || ($type eq 'message')) { ### scan message body
1515 2 0       5 $self->bodyhandle || return ($self->parts ? 'binary' : '7bit');
    50          
1516 2         2 my ($IO, $unclean);
1517 2 50       3 if ($IO = $self->bodyhandle->open("r")) {
1518             ### Scan message for 7bit-cleanliness
1519 2         2 local $_;
1520 2         87 while (defined($_ = $IO->getline)) {
1521 6 100 66     33 last if ($unclean = ((length($_) > 999) or /[\200-\377]/));
1522             }
1523              
1524             ### Return '7bit' if clean; try and encode if not...
1525             ### Note that encodings are not permitted for messages!
1526 2 50       31 return ($unclean
    100          
1527             ? (($type eq 'message') ? 'binary' : 'quoted-printable')
1528             : '7bit');
1529             }
1530             }
1531             else {
1532 1 50       3 return ($type eq 'multipart') ? 'binary' : 'base64';
1533             }
1534             }
1535              
1536             sub suggest_encoding_lite {
1537 30     30 0 48 my $self = shift;
1538 30         66 my ($type) = split '/', $self->effective_type;
1539 30 100       188 return (($type =~ /^(text|message|multipart)$/) ? 'binary' : 'base64');
1540             }
1541              
1542             #------------------------------
1543              
1544             =item sync_headers OPTIONS
1545              
1546             I
1547             This method does a variety of activities which ensure that
1548             the MIME headers of an entity "tree" are in-synch with the body parts
1549             they describe. It can be as expensive an operation as printing
1550             if it involves pre-encoding the body parts; however, the aim is to
1551             produce fairly clean MIME. B
1552             this if processing and re-sending MIME from an outside source.>
1553              
1554             The OPTIONS is a hash, which describes what is to be done.
1555              
1556             =over 4
1557              
1558              
1559             =item Length
1560              
1561             One of the "official unofficial" MIME fields is "Content-Length".
1562             Normally, one doesn't care a whit about this field; however, if
1563             you are preparing output destined for HTTP, you may. The value of
1564             this option dictates what will be done:
1565              
1566             B means to set a C field for every non-multipart
1567             part in the entity, and to blank that field out for every multipart
1568             part in the entity.
1569              
1570             B means that C fields will all
1571             be blanked out. This is fast, painless, and safe.
1572              
1573             B (the default) means to take no action.
1574              
1575              
1576             =item Nonstandard
1577              
1578             Any header field beginning with "Content-" is, according to the RFC,
1579             a MIME field. However, some are non-standard, and may cause problems
1580             with certain MIME readers which interpret them in different ways.
1581              
1582             B means that all such fields will be blanked out. This is
1583             done I the B option (q.v.) is examined and acted upon.
1584              
1585             B (the default) means to take no action.
1586              
1587              
1588             =back
1589              
1590             Returns a true value if everything went okay, a false value otherwise.
1591              
1592             =cut
1593              
1594             sub sync_headers {
1595 5     5 1 20 my $self = shift;
1596 5 100       21 my $opts = ((int(@_) % 2 == 0) ? {@_} : shift);
1597 5         11 my $ENCBODY; ### keep it around until done!
1598              
1599             ### Get options:
1600 5   50     18 my $o_nonstandard = ($opts->{Nonstandard} || 0);
1601 5   50     13 my $o_length = ($opts->{Length} || 0);
1602              
1603             ### Get head:
1604 5         16 my $head = $self->head;
1605              
1606             ### What to do with "nonstandard" MIME fields?
1607 5 50       15 if ($o_nonstandard eq 'ERASE') { ### Erase them...
1608 5         9 my $tag;
1609 5         30 foreach $tag ($head->tags()) {
1610 19 50 66     258 if (($tag =~ /\AContent-/i) &&
1611             ($tag !~ /\AContent-$StandardFields\Z/io)) {
1612 0         0 $head->delete($tag);
1613             }
1614             }
1615             }
1616              
1617             ### What to do with the "Content-Length" MIME field?
1618 5 50       16 if ($o_length eq 'COMPUTE') { ### Compute the content length...
    0          
1619 5         11 my $content_length = '';
1620              
1621             ### We don't have content-lengths in multiparts...
1622 5 100       15 if ($self->is_multipart) { ### multipart...
1623 1         9 $head->delete('Content-length');
1624             }
1625             else { ### singlepart...
1626              
1627             ### Get the encoded body, if we don't have it already:
1628 4 50       12 unless ($ENCBODY) {
1629 4   50     16 $ENCBODY = tmpopen() || die "can't open tmpfile";
1630 4         2512 $self->print_body($ENCBODY); ### write encoded to tmpfile
1631             }
1632              
1633             ### Analyse it:
1634 4         25 $ENCBODY->seek(0,2); ### fast-forward
1635 4         262 $content_length = $ENCBODY->tell; ### get encoded length
1636 4         37 $ENCBODY->seek(0,0); ### rewind
1637              
1638             ### Remember:
1639 4         38 $self->head->replace('Content-length', $content_length);
1640             }
1641             }
1642             elsif ($o_length eq 'ERASE') { ### Erase the content-length...
1643 0         0 $head->delete('Content-length');
1644             }
1645              
1646             ### Done with everything for us!
1647 5         823 undef($ENCBODY);
1648              
1649             ### Recurse:
1650 5         1659 my $part;
1651 5 50       21 foreach $part ($self->parts) { $part->sync_headers($opts) or return undef }
  4         14  
1652 5         23 1;
1653             }
1654              
1655             #------------------------------
1656              
1657             =item tidy_body
1658              
1659             I
1660             Currently unimplemented for MIME messages. Does nothing, returns false.
1661              
1662             =cut
1663              
1664             sub tidy_body {
1665 0     0 1 0 usage "MIME::Entity::tidy_body currently does nothing";
1666 0         0 0;
1667             }
1668              
1669             =back
1670              
1671             =cut
1672              
1673              
1674              
1675              
1676              
1677             #==============================
1678              
1679             =head2 Output
1680              
1681             =over 4
1682              
1683             =cut
1684              
1685             #------------------------------
1686              
1687             =item dump_skeleton [FILEHANDLE]
1688              
1689             I
1690             Dump the skeleton of the entity to the given FILEHANDLE, or
1691             to the currently-selected one if none given.
1692              
1693             Each entity is output with an appropriate indentation level,
1694             the following selection of attributes:
1695              
1696             Content-type: multipart/mixed
1697             Effective-type: multipart/mixed
1698             Body-file: NONE
1699             Subject: Hey there!
1700             Num-parts: 2
1701              
1702             This is really just useful for debugging purposes; I make no guarantees
1703             about the consistency of the output format over time.
1704              
1705             =cut
1706              
1707             sub dump_skeleton {
1708 0     0 1 0 my ($self, $fh, $indent) = @_;
1709 0 0       0 $fh or $fh = select;
1710 0 0       0 defined($indent) or $indent = 0;
1711 0         0 my $ind = ' ' x $indent;
1712 0         0 my $part;
1713 22     22   255 no strict 'refs';
  22         51  
  22         8114  
1714              
1715              
1716             ### The content type:
1717 0   0     0 print $fh $ind,"Content-type: ", ($self->mime_type||'UNKNOWN'),"\n";
1718 0   0     0 print $fh $ind,"Effective-type: ", ($self->effective_type||'UNKNOWN'),"\n";
1719              
1720             ### The name of the file containing the body (if any!):
1721 0 0       0 my $path = ($self->bodyhandle ? $self->bodyhandle->path : undef);
1722 0   0     0 print $fh $ind, "Body-file: ", ($path || 'NONE'), "\n";
1723              
1724             ### The recommended file name (thanks to Allen Campbell):
1725 0         0 my $filename = $self->head->recommended_filename;
1726 0 0       0 print $fh $ind, "Recommended-filename: ", $filename, "\n" if ($filename);
1727              
1728             ### The subject (note: already a newline if 2.x!)
1729 0         0 my $subj = $self->head->get('subject',0);
1730 0 0       0 defined($subj) or $subj = '';
1731 0         0 chomp($subj);
1732 0 0       0 print $fh $ind, "Subject: $subj\n" if $subj;
1733              
1734             ### The parts:
1735 0         0 my @parts = $self->parts;
1736 0 0       0 print $fh $ind, "Num-parts: ", int(@parts), "\n" if @parts;
1737 0         0 print $fh $ind, "--\n";
1738 0         0 foreach $part (@parts) {
1739 0         0 $part->dump_skeleton($fh, $indent+1);
1740             }
1741             }
1742              
1743             #------------------------------
1744              
1745             =item print [OUTSTREAM]
1746              
1747             I
1748             Print the entity to the given OUTSTREAM, or to the currently-selected
1749             filehandle if none given. OUTSTREAM can be a filehandle, or any object
1750             that responds to a print() message.
1751              
1752             The entity is output as a valid MIME stream! This means that the
1753             header is always output first, and the body data (if any) will be
1754             encoded if the header says that it should be.
1755             For example, your output may look like this:
1756              
1757             Subject: Greetings
1758             Content-transfer-encoding: base64
1759              
1760             SGkgdGhlcmUhCkJ5ZSB0aGVyZSEK
1761              
1762             I
1763             the preamble, parts, and epilogue are all output with appropriate
1764             boundaries separating each.
1765             Any bodyhandle is ignored:
1766              
1767             Content-type: multipart/mixed; boundary="*----*"
1768             Content-transfer-encoding: 7bit
1769              
1770             [Preamble]
1771             --*----*
1772             [Entity: Part 0]
1773             --*----*
1774             [Entity: Part 1]
1775             --*----*--
1776             [Epilogue]
1777              
1778             I
1779             then we're looking at a normal singlepart entity: the body is output
1780             according to the encoding specified by the header.
1781             If no body exists, a warning is output and the body is treated as empty:
1782              
1783             Content-type: image/gif
1784             Content-transfer-encoding: base64
1785              
1786             [Encoded body]
1787              
1788             I
1789             then we're probably looking at a "re-parsed" singlepart, usually one
1790             of type C (you can get entities like this if you set the
1791             C option on the parser to true).
1792             In this case, the parts are output with single blank lines separating each,
1793             and any bodyhandle is ignored:
1794              
1795             Content-type: message/rfc822
1796             Content-transfer-encoding: 7bit
1797              
1798             [Entity: Part 0]
1799              
1800             [Entity: Part 1]
1801              
1802             In all cases, when outputting a "part" of the entity, this method
1803             is invoked recursively.
1804              
1805             B the output is very likely I going to be identical
1806             to any input you parsed to get this entity. If you're building
1807             some sort of email handler, it's up to you to save this information.
1808              
1809             =cut
1810              
1811 22     22   185 use Symbol;
  22         53  
  22         27728  
1812             sub print {
1813 67     67 1 16206 my ($self, $out) = @_;
1814 67   100     401 my $boundary_delimiter = $MIME::Entity::BOUNDARY_DELIMITER || "\n";
1815 67 100       196 $out = select if @_ < 2;
1816 67 100       265 $out = Symbol::qualify($out,scalar(caller)) unless ref($out);
1817              
1818 67         491 $self->print_header($out); ### the header
1819 67         721 $out->print($boundary_delimiter);
1820 67         503 $self->print_body($out); ### the "stuff after the header"
1821             }
1822              
1823             #------------------------------
1824              
1825             =item print_body [OUTSTREAM]
1826              
1827             I
1828             Print the body of the entity to the given OUTSTREAM, or to the
1829             currently-selected filehandle if none given. OUTSTREAM can be a
1830             filehandle, or any object that responds to a print() message.
1831              
1832             The body is output for inclusion in a valid MIME stream; this means
1833             that the body data will be encoded if the header says that it should be.
1834              
1835             B by "body", we mean "the stuff following the header".
1836             A printed multipart body includes the printed representations of its subparts.
1837              
1838             B The body is I in an un-encoded form; however, the idea is that
1839             the transfer encoding is used to determine how it should be I
1840             This means that the C method is always guaranteed to get you
1841             a sendmail-ready stream whose body is consistent with its head.
1842             If you want the I to be output, you can either read it from
1843             the bodyhandle yourself, or use:
1844              
1845             $ent->bodyhandle->print($outstream);
1846              
1847             which uses read() calls to extract the information, and thus will
1848             work with both text and binary bodies.
1849              
1850             B Please supply an OUTSTREAM. This override method differs
1851             from Mail::Internet's behavior, which outputs to the STDOUT if no
1852             filehandle is given: this may lead to confusion.
1853              
1854             =cut
1855              
1856             sub print_body {
1857 83     83 1 4133 my ($self, $out) = @_;
1858 83   33     258 $out ||= select;
1859 83         301 my ($type) = split '/', lc($self->mime_type); ### handle by MIME type
1860 83   100     460 my $boundary_delimiter = $MIME::Entity::BOUNDARY_DELIMITER || "\n";
1861              
1862             ### Multipart...
1863 83 100       383 if ($type eq 'multipart') {
    50          
1864 12         42 my $boundary = $self->head->multipart_boundary;
1865              
1866             ### Preamble:
1867 12         54 my $plines = $self->preamble;
1868 12 100       67 if (defined $plines) {
1869             # Defined, so output the preamble if it exists (avoiding additional
1870             # newline as per ticket 60931)
1871 9 100       79 $out->print( join('', @$plines) . $boundary_delimiter) if (@$plines > 0);
1872             } else {
1873             # Undefined, so use default preamble
1874 3         41 $out->print( join('', @$DefPreamble) . $boundary_delimiter . $boundary_delimiter );
1875             }
1876              
1877             ### Parts:
1878 12         77 my $part;
1879 12         41 foreach $part ($self->parts) {
1880 33         239 $out->print("--$boundary$boundary_delimiter");
1881 33         303 $part->print($out);
1882 33         88 $out->print($boundary_delimiter); ### needed for next delim/close
1883             }
1884 12         118 $out->print("--$boundary--$boundary_delimiter");
1885              
1886             ### Epilogue:
1887 12 100       70 my $epilogue = join('', @{ $self->epilogue || $DefEpilogue });
  12         43  
1888 12 100       62 if ($epilogue ne '') {
1889 1         4 $out->print($epilogue);
1890 1 50       31 $out->print($boundary_delimiter) if ($epilogue !~ /\n\Z/); ### be nice
1891             }
1892             }
1893              
1894             ### Singlepart type with parts...
1895             ### This makes $ent->print handle message/rfc822 bodies
1896             ### when parse_nested_messages('NEST') is on [idea by Marc Rouleau].
1897             elsif ($self->parts) {
1898 0         0 my $need_sep = 0;
1899 0         0 my $part;
1900 0         0 foreach $part ($self->parts) {
1901 0 0       0 $out->print("$boundary_delimiter$boundary_delimiter") if $need_sep++;
1902 0         0 $part->print($out);
1903             }
1904             }
1905              
1906             ### Singlepart type, or no parts: output body...
1907             else {
1908 71 50       218 $self->bodyhandle ? $self->print_bodyhandle($out)
1909             : whine "missing body; treated as empty";
1910             }
1911 83         255 1;
1912             }
1913              
1914             #------------------------------
1915             #
1916             # print_bodyhandle
1917             #
1918             # Instance method, unpublicized. Print just the bodyhandle, *encoded*.
1919             #
1920             # WARNING: $self->print_bodyhandle() != $self->bodyhandle->print()!
1921             # The former encodes, and the latter does not!
1922             #
1923             sub print_bodyhandle {
1924 71     71 0 179 my ($self, $out) = @_;
1925 71   33     200 $out ||= select;
1926              
1927 71   50     222 my $IO = $self->open("r") || die "open body: $!";
1928 71 100       2753 if ( $self->bodyhandle->is_encoded ) {
1929             ### Transparent mode: data is already encoded, so no
1930             ### need to encode it again
1931 7         16 my $buf;
1932 7         38 $out->print($buf) while ($IO->read($buf, 8192));
1933             } else {
1934             ### Get the encoding, defaulting to "binary" if unsupported:
1935 64   50     170 my $encoding = ($self->head->mime_encoding || 'binary');
1936 64         496 my $decoder = best MIME::Decoder $encoding;
1937 64         194 $decoder->head($self->head); ### associate with head, if any
1938 64 100       178 $decoder->encode($IO, $out, textual_type($self->head->mime_type) ? 1 : 0) || return error "encoding failed";
    50          
1939             }
1940              
1941 71         504 $IO->close;
1942 71         1122 1;
1943             }
1944              
1945             #------------------------------
1946              
1947             =item print_header [OUTSTREAM]
1948              
1949             I
1950             Output the header to the given OUTSTREAM. You really should supply
1951             the OUTSTREAM.
1952              
1953             =cut
1954              
1955             ### Inherited.
1956              
1957             #------------------------------
1958              
1959             =item stringify
1960              
1961             I
1962             Return the entity as a string, exactly as C would print it.
1963             The body will be encoded as necessary, and will contain any subparts.
1964             You can also use C.
1965              
1966             =cut
1967              
1968             sub stringify {
1969 19     19 1 305 my ($self) = @_;
1970 19         42 my $output = '';
1971 19 50       144 my $fh = IO::File->new( \$output, '>:' ) or croak("Cannot open in-memory file: $!");
1972 19         1367 $self->print($fh);
1973 19         103 $fh->close;
1974 19         194 return $output;
1975             }
1976              
1977 18     18 1 5248 sub as_string { shift->stringify }; ### silent BC
1978              
1979             #------------------------------
1980              
1981             =item stringify_body
1982              
1983             I
1984             Return the I message body as a string, exactly as C
1985             would print it. You can also use C.
1986              
1987             If you want the I body, and you are dealing with a
1988             singlepart message (like a "text/plain"), use C instead:
1989              
1990             if ($ent->bodyhandle) {
1991             $unencoded_data = $ent->bodyhandle->as_string;
1992             }
1993             else {
1994             ### this message has no body data (but it might have parts!)
1995             }
1996              
1997             =cut
1998              
1999             sub stringify_body {
2000 0     0 1   my ($self) = @_;
2001 0           my $output = '';
2002 0 0         my $fh = IO::File->new( \$output, '>:' ) or croak("Cannot open in-memory file: $!");
2003 0           $self->print_body($fh);
2004 0           $fh->close;
2005 0           return $output;
2006             }
2007              
2008 0     0 0   sub body_as_string { shift->stringify_body }
2009              
2010             #------------------------------
2011              
2012             =item stringify_header
2013              
2014             I
2015             Return the header as a string, exactly as C would print it.
2016             You can also use C.
2017              
2018             =cut
2019              
2020             sub stringify_header {
2021 0     0 1   shift->head->stringify;
2022             }
2023 0     0 0   sub header_as_string { shift->stringify_header }
2024              
2025              
2026             1;
2027             __END__