File Coverage

blib/lib/MIME/Entity.pm
Criterion Covered Total %
statement 341 401 85.0
branch 155 234 66.2
condition 46 79 58.2
subroutine 42 49 85.7
pod 31 37 83.7
total 615 800 76.8


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