Mail-Message-4.05/0000755000175000001440000000000015166136132014430 5ustar00markovusers00000000000000Mail-Message-4.05/lib/0000755000175000001440000000000015166136132015176 5ustar00markovusers00000000000000Mail-Message-4.05/lib/Mail/0000755000175000001440000000000015166136132016060 5ustar00markovusers00000000000000Mail-Message-4.05/lib/Mail/Message/0000755000175000001440000000000015166136132017444 5ustar00markovusers00000000000000Mail-Message-4.05/lib/Mail/Message/Convert/0000755000175000001440000000000015166136132021064 5ustar00markovusers00000000000000Mail-Message-4.05/lib/Mail/Message/Convert/Html.pm0000644000175000001440000000726115166136116022336 0ustar00markovusers00000000000000# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::Convert::Html;{ our $VERSION = '4.05'; } use parent 'Mail::Message::Convert'; use strict; use warnings; use Log::Report 'mail-message', import => [ qw/__x error/ ]; #-------------------- sub init($) { my ($self, $args) = @_; $self->SUPER::init($args); my $produce = $args->{produce} || 'HTML'; $self->{MMCH_tail} = $produce eq 'HTML' ? '>' : $produce eq 'XHTML' ? ' />' : error __x"produce XHTML or HTML, not {what UNKNOWN}.", what => $produce; $self; } #-------------------- sub textToHtml(@) { my $self = shift; my @lines = @_; # copy is required foreach (@lines) { s/\&/&/gs; s/\/>/gs; s/\"/"/gs; } wantarray ? @lines : join('', @lines); } sub fieldToHtml($;$) { my ($self, $field, $subject) = @_; ''. $self->textToHtml($field->wellformedName) . ': ' . $self->fieldContentsToHtml($field, $subject); } sub headToHtmlTable($;$) { my ($self, $head) = (shift, shift); my $tp = @_ ? ' '.shift : ''; my $subject; if($self->{MMHC_mailto_subject}) { my $s = $head->get('subject'); use Mail::Message::Construct; $subject = Mail::Message::Construct->replySubject($s) if defined $s; } my @lines = "\n"; foreach my $f ($self->selectedFields($head)) { my $name_html = $self->textToHtml($f->wellformedName); my $cont_html = $self->fieldContentsToHtml($f, $subject); push @lines, qq(\n), qq( \n); } push @lines, "
$name_html:$cont_html
\n"; wantarray ? @lines : join('',@lines); } sub headToHtmlHead($@) { my ($self, $head) = (shift,shift); my %meta; while(@_) { my $k = shift; $meta{lc $k} = shift } my $title = delete $meta{title} || $head->get('subject') || ''; my @lines = ( "\n", "".$self->textToHtml($title) . "\n", ); my $author = delete $meta{author}; unless(defined $author) { my $from = $head->get('from'); my @addr = defined $from ? $from->addresses : (); $author = @addr ? $addr[0]->format : undef; } push @lines, '{MMCH_tail}\n" if defined $author; foreach my $f (map {lc} keys %meta) { next if $meta{$f} eq ''; # empty is skipped. push @lines, '{MMCH_tail}\n"; } foreach my $f ($self->selectedFields($head)) { next if exists $meta{$f->name}; push @lines, '{MMCH_tail}\n"; } push @lines, "\n"; wantarray ? @lines : join('',@lines); } my $atom = qr/[^()<>@,;:\\".\[\]\s[:cntrl:]]+/; my $email_address = qr/(($atom(?:\.$atom)*)\@($atom(?:\.$atom)+))/o; sub fieldContentsToHtml($;$) { my ($self, $field, $subj) = @_; my $subject = defined $subj ? '?subject='.$self->textToHtml($subj) : ''; my $body = $self->textToHtml($field->body); my $comment = $field->comment; $body =~ s#$email_address#$1#gx if $field->name =~ m/^(resent-)?(to|from|cc|bcc|reply\-to)$/; $body . ($comment ? '; '.$self->textToHtml($comment) : ''); } 1; Mail-Message-4.05/lib/Mail/Message/Convert/Html.pod0000644000175000001440000001267215166136117022507 0ustar00markovusers00000000000000=encoding utf8 =head1 NAME Mail::Message::Convert::Html - Format messages in HTML =head1 INHERITANCE Mail::Message::Convert::Html is a Mail::Message::Convert is a Mail::Reporter =head1 SYNOPSIS use Mail::Message::Convert::Html; my $Html = Mail::Message::Convert::Html->new; print $html->fieldToHtml($head); print $html->headToHtmlHead($head); print $html->headToHtmlTable($head); print $html->textToHtml($text); =head1 DESCRIPTION The package contains various translators which handle HTML or XHTML without the help of external modules. There are more HTML related modules, which do require extra packages to be installed. Extends L<"DESCRIPTION" in Mail::Message::Convert|Mail::Message::Convert/"DESCRIPTION">. =head1 METHODS Extends L<"METHODS" in Mail::Message::Convert|Mail::Message::Convert/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Message::Convert|Mail::Message::Convert/"Constructors">. =over 4 =item $class-EB(%options) Inherited, see L -Option --Defined in --Default fields Mail::Message::Convert head_mailto true produce HTML =over 2 =item fields => $name|$regex|\@names|\@regexes =item head_mailto => BOOLEAN Whether to replace e-mail addresses in some header lines with links. =item produce => 'HTML'|'XHTML' Produce HTML or XHTML output. The output is slightly different, even html browsers will usually accept the XHTML data. =back =back =head2 Attributes Extends L<"Attributes" in Mail::Message::Convert|Mail::Message::Convert/"Attributes">. =head2 Converting Extends L<"Converting" in Mail::Message::Convert|Mail::Message::Convert/"Converting">. =over 4 =item $obj-EB( $field, [$subject] ) Format one field from the header to HTML. When the header line usually contains e-mail addresses, the line is scanned and valid addresses are linked with an C anchor. The C<$subject> can be specified to be included in that link. =item $obj-EB( $field, [$subject] ) Reformat one header line field to HTML. The C<$field>'s name is printed in bold, followed by the formatted field content, which is produced by L. =item $obj-EB($head, $meta) Translate the selected header lines (fields) to an html page header. Each selected field will get its own meta line with the same name as the line. Furthermore, the C field will become the C, and C<From> is used for the C<Author>. Besides, you can specify your own meta fields, which will overrule header fields. Empty fields will not be included. When a C<title> is specified, this will become the html title, otherwise the C<Subject> field is taken. In list context, the lines are separately, where in scalar context the whole text is returned as one. If you need to add lines to the head (for instance, http-equiv lines), then splice them before the last element in the returned list. » example: my @head = $html->headToHtmlHead( $head, description => 'This is a message', generator => 'Mail::Box', ); splice @head, -1, 0, '<meta http-equiv=...>'; print @head; =item $obj-E<gt>B<headToHtmlTable>( $head, [$table_params] ) Produce a display of the L<selectedFields()|Mail::Message::Convert/"Converting"> of the header in a table shape. The optional C<$table_params> are added as parameters to the produced TABLE tag. In list context, the separate lines are returned. In scalar context, everything is returned as one. » example: print $html->headToHtmlTable($head, 'width="50%"'); =item $obj-E<gt>B<selectedFields>($head) Inherited, see L<Mail::Message::Convert/"Converting"> =item $obj-E<gt>B<textToHtml>($lines) Translate one or more C<$lines> from text into HTML. Each line is taken one after the other, and only simple things are translated. C<textToHtml> is able to convert large plain texts in a descent fashion. In scalar context, the resulting lines are returned as one. =back =head2 Error handling Extends L<"Error handling" in Mail::Message::Convert|Mail::Message::Convert/"Error handling">. =over 4 =item $obj-E<gt>B<AUTOLOAD>() Inherited, see L<Mail::Reporter/"Error handling"> =item $obj-E<gt>B<notImplemented>() Inherited, see L<Mail::Reporter/"Error handling"> =back =head2 Cleanup Extends L<"Cleanup" in Mail::Message::Convert|Mail::Message::Convert/"Cleanup">. =over 4 =item $obj-E<gt>B<DESTROY>() Inherited, see L<Mail::Reporter/"Cleanup"> =back =head1 DIAGNOSTICS =over 4 =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =item Error: produce XHTML or HTML, not $what. Cast by C<new()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. ����������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Convert/TextAutoformat.pod���������������������������������������0000644�0001750�0000144�00000006110�15166136117�024557� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Convert::TextAutoformat - Reformat plain text messages =head1 INHERITANCE Mail::Message::Convert::TextAutoformat is a Mail::Message::Convert is a Mail::Reporter =head1 SYNOPSIS use Mail::Message::Convert::TextAutoformat; my $af = Mail::Message::Convert::TextAutoformat->new; my $beautified_body = $af->autoformatBody($body); =head1 DESCRIPTION Play trics with plain text, for instance bodies with type C<text/plain> using Damian Conway's Text::Autoformat. Extends L<"DESCRIPTION" in Mail::Message::Convert|Mail::Message::Convert/"DESCRIPTION">. =head1 METHODS Extends L<"METHODS" in Mail::Message::Convert|Mail::Message::Convert/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Message::Convert|Mail::Message::Convert/"Constructors">. =over 4 =item $class-E<gt>B<new>(%options) Inherited, see L<Mail::Reporter/"Constructors"> -Option --Defined in --Default fields Mail::Message::Convert <see description> options +{ all => 1 } =over 2 =item fields => $name|$regex|\@names|\@regexes =item options => \%af The C<%af> options to pass to Text::Autoformat function C<autoformat()>. =back =back =head2 Attributes Extends L<"Attributes" in Mail::Message::Convert|Mail::Message::Convert/"Attributes">. =head2 Converting Extends L<"Converting" in Mail::Message::Convert|Mail::Message::Convert/"Converting">. =over 4 =item $obj-E<gt>B<autoformatBody>($body) Formats a single message body (a L<Mail::Message::Body|Mail::Message::Body> object) into a new body object using Text::Autoformat. The body should have content type C<text/plain>, otherwise the output is probably weird. =item $obj-E<gt>B<selectedFields>($head) Inherited, see L<Mail::Message::Convert/"Converting"> =back =head2 Error handling Extends L<"Error handling" in Mail::Message::Convert|Mail::Message::Convert/"Error handling">. =over 4 =item $obj-E<gt>B<AUTOLOAD>() Inherited, see L<Mail::Reporter/"Error handling"> =item $obj-E<gt>B<notImplemented>() Inherited, see L<Mail::Reporter/"Error handling"> =back =head2 Cleanup Extends L<"Cleanup" in Mail::Message::Convert|Mail::Message::Convert/"Cleanup">. =over 4 =item $obj-E<gt>B<DESTROY>() Inherited, see L<Mail::Reporter/"Cleanup"> =back =head1 DIAGNOSTICS =over 4 =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Convert/HtmlFormatPS.pod�����������������������������������������0000644�0001750�0000144�00000006040�15166136117�024113� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Convert::HtmlFormatPS - Convert HTML into PostScript =head1 INHERITANCE Mail::Message::Convert::HtmlFormatPS is a Mail::Message::Convert is a Mail::Reporter =head1 SYNOPSIS use Mail::Message::Convert::HtmlFormatPS; my $af = Mail::Message::Convert::HtmlFormatPS->new; my $postscript = $af->format($body); =head1 DESCRIPTION Translate an HTML/XHTML message body into a postscript body using HTML::FormatPS. Extends L<"DESCRIPTION" in Mail::Message::Convert|Mail::Message::Convert/"DESCRIPTION">. =head1 METHODS Extends L<"METHODS" in Mail::Message::Convert|Mail::Message::Convert/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Message::Convert|Mail::Message::Convert/"Constructors">. =over 4 =item $class-E<gt>B<new>(%options) C<%options> which start with capitals are blindly passed to HTML::FormatPS. As of this writing, that package defines BottomMargin, FontFamily, FontScale, HorizontalMargin, Leading, LeftMargin, PageNo, PaperHeight, PaperSize, PaperWidth, RightMargin, TopMargin, and VerticalMargin. Improves base, see L<Mail::Reporter/"Constructors"> -Option--Defined in --Default fields Mail::Message::Convert <not used> =over 2 =item fields => $name|$regex|\@names|\@regexes =back =back =head2 Attributes Extends L<"Attributes" in Mail::Message::Convert|Mail::Message::Convert/"Attributes">. =head2 Converting Extends L<"Converting" in Mail::Message::Convert|Mail::Message::Convert/"Converting">. =over 4 =item $obj-E<gt>B<format>($body) Pass an html or xhtml encoded body, and a plain text body is returned. Characters are translated into Latin1. =item $obj-E<gt>B<selectedFields>($head) Inherited, see L<Mail::Message::Convert/"Converting"> =back =head2 Error handling Extends L<"Error handling" in Mail::Message::Convert|Mail::Message::Convert/"Error handling">. =over 4 =item $obj-E<gt>B<AUTOLOAD>() Inherited, see L<Mail::Reporter/"Error handling"> =item $obj-E<gt>B<notImplemented>() Inherited, see L<Mail::Reporter/"Error handling"> =back =head2 Cleanup Extends L<"Cleanup" in Mail::Message::Convert|Mail::Message::Convert/"Cleanup">. =over 4 =item $obj-E<gt>B<DESTROY>() Inherited, see L<Mail::Reporter/"Cleanup"> =back =head1 DIAGNOSTICS =over 4 =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Convert/HtmlFormatText.pod���������������������������������������0000644�0001750�0000144�00000006542�15166136117�024524� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Convert::HtmlFormatText - Convert HTML into Text =head1 INHERITANCE Mail::Message::Convert::HtmlFormatText is a Mail::Message::Convert is a Mail::Reporter =head1 SYNOPSIS use Mail::Message::Convert::HtmlFormatText; my $af = Mail::Message::Convert::HtmlFormatText->new; my $plain_body = $af->format($body); =head1 DESCRIPTION Convert HTML/XHTML message body objects into plain text bodies using HTML::FormatText. This package requires HTML::TreeBuilder and HTML::FormatText which are not installed by default together with L<Mail::Box|Mail::Box>. See also L<Mail::Message::rebuild()|Mail::Message::Construct::Rebuild/"Constructing a message"> with rule C<text_alternative_for_html>. This module is a small wrapper around HTML::FormatText. Extends L<"DESCRIPTION" in Mail::Message::Convert|Mail::Message::Convert/"DESCRIPTION">. =head1 METHODS Extends L<"METHODS" in Mail::Message::Convert|Mail::Message::Convert/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Message::Convert|Mail::Message::Convert/"Constructors">. =over 4 =item $class-E<gt>B<new>(%options) Inherited, see L<Mail::Reporter/"Constructors"> -Option --Defined in --Default fields Mail::Message::Convert <see description> leftmargin 3 rightmargin 72 =over 2 =item fields => $name|$regex|\@names|\@regexes =item leftmargin => INTEGER The column of the left margin, passed to the formatter. =item rightmargin => INTEGER The column of the right margin, passed to the formatter. =back =back =head2 Attributes Extends L<"Attributes" in Mail::Message::Convert|Mail::Message::Convert/"Attributes">. =head2 Converting Extends L<"Converting" in Mail::Message::Convert|Mail::Message::Convert/"Converting">. =over 4 =item $obj-E<gt>B<format>($body) Pass an html/xhtml encoded body, and a plain text body is returned. Characters are translated into Latin1. =item $obj-E<gt>B<selectedFields>($head) Inherited, see L<Mail::Message::Convert/"Converting"> =back =head2 Error handling Extends L<"Error handling" in Mail::Message::Convert|Mail::Message::Convert/"Error handling">. =over 4 =item $obj-E<gt>B<AUTOLOAD>() Inherited, see L<Mail::Reporter/"Error handling"> =item $obj-E<gt>B<notImplemented>() Inherited, see L<Mail::Reporter/"Error handling"> =back =head2 Cleanup Extends L<"Cleanup" in Mail::Message::Convert|Mail::Message::Convert/"Cleanup">. =over 4 =item $obj-E<gt>B<DESTROY>() Inherited, see L<Mail::Reporter/"Cleanup"> =back =head1 DIAGNOSTICS =over 4 =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. ��������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Convert/MimeEntity.pod�������������������������������������������0000644�0001750�0000144�00000010353�15166136117�023661� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Convert::MimeEntity - translate Mail::Message to MIME::Entity vv =head1 INHERITANCE Mail::Message::Convert::MimeEntity is a Mail::Message::Convert is a Mail::Reporter =head1 SYNOPSIS use Mail::Message::Convert::MimeEntity; my $convert = Mail::Message::Convert::MimeEntity->new; my Mail::Message $msg = Mail::Message->new; my MIME::Entity $entity = $convert->export($msg); my MIME::Entity $entity = MIME::Entity->new; my Mail::Message $msg = $convert->from($entity); use Mail::Box::Manager; my $mgr = Mail::Box::Manager->new; my $folder = $mgr->open(folder => 'Outbox'); $folder->addMessage($entity); =head1 DESCRIPTION The MIME::Entity extends L<Mail::Internet|Mail::Internet> message with multiparts and more methods. The L<Mail::Message|Mail::Message> objects are more flexible in how the message parts are stored, and uses separate header and body objects. Extends L<"DESCRIPTION" in Mail::Message::Convert|Mail::Message::Convert/"DESCRIPTION">. =head1 METHODS Extends L<"METHODS" in Mail::Message::Convert|Mail::Message::Convert/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Message::Convert|Mail::Message::Convert/"Constructors">. =over 4 =item $class-E<gt>B<new>(%options) Inherited, see L<Mail::Message::Convert/"METHODS"> =back =head2 Attributes Extends L<"Attributes" in Mail::Message::Convert|Mail::Message::Convert/"Attributes">. =head2 Converting Extends L<"Converting" in Mail::Message::Convert|Mail::Message::Convert/"Converting">. =over 4 =item $obj-E<gt>B<export>( $message, [$parser] ) Returns a new MIME::Entity message object based on the information from the C<$message>, which is a L<Mail::Message|Mail::Message> object. You may want to supply your own C<$parser>, which is a MIME::Parser object, to change the parser flags. Without a C<$parser> object, one is created for you, with all the default settings. If C<undef> is passed, in place of a C<$message>, then an empty list is returned. When the parsing failes, then MIME::Parser throws an exception. » example: my $convert = Mail::Message::Convert::MimeEntity->new; my Mail::Message $msg = Mail::Message->new; my MIME::Entity $copy = $convert->export($msg); =item $obj-E<gt>B<from>($mime_object) Returns a new L<Mail::Message|Mail::Message> object based on the information from the specified MIME::Entity. If the conversion fails, the C<undef> is returned. If C<undef> is passed in place of an OBJECT, then an empty list is returned. » example: my $convert = Mail::Message::Convert::MimeEntity->new; my MIME::Entity $msg = MIME::Entity->new; my Mail::Message $copy = $convert->from($msg); =item $obj-E<gt>B<selectedFields>($head) Inherited, see L<Mail::Message::Convert/"Converting"> =back =head2 Error handling Extends L<"Error handling" in Mail::Message::Convert|Mail::Message::Convert/"Error handling">. =over 4 =item $obj-E<gt>B<AUTOLOAD>() Inherited, see L<Mail::Reporter/"Error handling"> =item $obj-E<gt>B<notImplemented>() Inherited, see L<Mail::Reporter/"Error handling"> =back =head2 Cleanup Extends L<"Cleanup" in Mail::Message::Convert|Mail::Message::Convert/"Cleanup">. =over 4 =item $obj-E<gt>B<DESTROY>() Inherited, see L<Mail::Reporter/"Cleanup"> =back =head1 DIAGNOSTICS =over 4 =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =item Error: converting from MIME::Entity but got a $class. Cast by C<from()> =item Error: export message must be a Mail::Message object, but is $what. Cast by C<export()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Convert/EmailSimple.pm�������������������������������������������0000644�0001750�0000144�00000002410�15166136116�023622� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::Convert::EmailSimple;{ our $VERSION = '4.05'; } use parent 'Mail::Message::Convert'; use strict; use warnings; use Log::Report 'mail-message', import => [ qw/__x error/ ]; use Mail::Internet (); use Mail::Header (); use Email::Simple (); use Mail::Message (); use Mail::Message::Head::Complete (); use Mail::Message::Body::Lines (); #-------------------- sub export($@) { my ($thing, $message) = @_; $message->isa('Mail::Message') or error __x"export message must be a Mail::Message, but is a {class}.", class => ref $message; Email::Simple->new($message->string); } sub from($@) { my ($thing, $email) = (shift, shift); $email->isa('Email::Simple') or error __x"converting from Email::Simple but got a {class}.", class => ref $email; Mail::Message->read($email->as_string); } 1; ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Convert/MailInternet.pm������������������������������������������0000644�0001750�0000144�00000003756�15166136116�024032� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::Convert::MailInternet;{ our $VERSION = '4.05'; } use parent 'Mail::Message::Convert'; use strict; use warnings; use Log::Report 'mail-message', import => [ qw/__x error/ ]; use Mail::Internet (); use Mail::Header (); use Mail::Message (); use Mail::Message::Head::Complete (); use Mail::Message::Body::Lines (); #-------------------- sub export($@) { my ($thing, $message) = (shift, shift); $message->isa('Mail::Message') or error __x"export message must be a Mail::Message object, but is {what UNKNOWN}.", what => $message; my $mi_head = Mail::Header->new; foreach my $field ($message->head->orderedFields) { $mi_head->add($field->Name, scalar $field->foldedBody); } Mail::Internet->new(Header => $mi_head, Body => [ $message->body->lines ], @_); } my @pref_order = qw/From To Cc Subject Date In-Reply-To References Content-Type/; sub from($@) { my ($thing, $mi) = (shift, shift); $mi->isa('Mail::Internet') or error __x"converting from Mail::Internet but got {what UNKNOWN}.", what => $mi; my $head = Mail::Message::Head::Complete->new; my $body = Mail::Message::Body::Lines->new(data => [ @{$mi->body} ]); my $mi_head = $mi->head; # The tags of Mail::Header are unordered, but we prefer some ordering. my %tags = map +(lc $_ => ucfirst $_), $mi_head->tags; my @tags; foreach (@pref_order) { push @tags, $_ if delete $tags{lc $_}; } push @tags, sort values %tags; foreach my $name (@tags) { $head->add($name, $_) for $mi_head->get($name); } Mail::Message->new(head => $head, body => $body, @_); } 1; ������������������Mail-Message-4.05/lib/Mail/Message/Convert/MailInternet.pod�����������������������������������������0000644�0001750�0000144�00000007645�15166136117�024202� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Convert::MailInternet - translate Mail::Message to Mail::Internet vv =head1 INHERITANCE Mail::Message::Convert::MailInternet is a Mail::Message::Convert is a Mail::Reporter =head1 SYNOPSIS use Mail::Message::Convert::MailInternet; my $convert = Mail::Message::Convert::MailInternet->new; my Mail::Message $msg = Mail::Message->new; my Mail::Internet $intern = $convert->export($msg); my Mail::Internet $intern = Mail::Internet->new; my Mail::Message $msg = $convert->from($intern); use Mail::Box::Manager; my $mgr = Mail::Box::Manager->new; my $folder = $mgr->open(folder => 'Outbox'); $folder->addMessage($intern); =head1 DESCRIPTION The L<Mail::Internet|Mail::Internet> class of messages is very popular for all kinds of message applications written in Perl. However, the format was developed when e-mail messages where still small and attachments where rare; L<Mail::Message|Mail::Message> is much more flexible in this respect. Extends L<"DESCRIPTION" in Mail::Message::Convert|Mail::Message::Convert/"DESCRIPTION">. =head1 METHODS Extends L<"METHODS" in Mail::Message::Convert|Mail::Message::Convert/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Message::Convert|Mail::Message::Convert/"Constructors">. =over 4 =item $class-E<gt>B<new>(%options) Inherited, see L<Mail::Message::Convert/"METHODS"> =back =head2 Attributes Extends L<"Attributes" in Mail::Message::Convert|Mail::Message::Convert/"Attributes">. =head2 Converting Extends L<"Converting" in Mail::Message::Convert|Mail::Message::Convert/"Converting">. =over 4 =item $obj-E<gt>B<export>($message, %options) Returns a new message object based on the information from a L<Mail::Message|Mail::Message> object. The C<$message> specified is an instance of a L<Mail::Message|Mail::Message>. » example: my $convert = Mail::Message::Convert::MailInternet->new; my Mail::Message $msg = Mail::Message->new; my Mail::Internet $copy = $convert->export($msg); =item $obj-E<gt>B<from>($object, %options) Returns a new L<Mail::Message|Mail::Message> object based on the information from a L<Mail::Internet|Mail::Internet> object. » example: my $convert = Mail::Message::Convert::MailInternet->new; my Mail::Internet $msg = Mail::Internet->new; my Mail::Message $copy = $convert->from($msg); =item $obj-E<gt>B<selectedFields>($head) Inherited, see L<Mail::Message::Convert/"Converting"> =back =head2 Error handling Extends L<"Error handling" in Mail::Message::Convert|Mail::Message::Convert/"Error handling">. =over 4 =item $obj-E<gt>B<AUTOLOAD>() Inherited, see L<Mail::Reporter/"Error handling"> =item $obj-E<gt>B<notImplemented>() Inherited, see L<Mail::Reporter/"Error handling"> =back =head2 Cleanup Extends L<"Cleanup" in Mail::Message::Convert|Mail::Message::Convert/"Cleanup">. =over 4 =item $obj-E<gt>B<DESTROY>() Inherited, see L<Mail::Reporter/"Cleanup"> =back =head1 DIAGNOSTICS =over 4 =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =item Error: converting from Mail::Internet but got a $what. Cast by C<from()> =item Error: export message must be a Mail::Message object, but is $what. Cast by C<export()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. �������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Convert/EmailSimple.pod������������������������������������������0000644�0001750�0000144�00000010034�15166136117�023772� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Convert::EmailSimple - translate Mail::Message to Email::Simple vv =head1 INHERITANCE Mail::Message::Convert::EmailSimple is a Mail::Message::Convert is a Mail::Reporter =head1 SYNOPSIS use Mail::Message::Convert::EmailSimple; my $convert = Mail::Message::Convert::EmailSimple->new; my Mail::Message $msg = Mail::Message->new; my Email::Simple $intern = $convert->export($msg); my Email::Simple $intern = Mail::Internet->new; my Mail::Message $msg = $convert->from($intern); use Mail::Box::Manager; my $mgr = Mail::Box::Manager->new; my $folder = $mgr->open(folder => 'Outbox'); $folder->addMessage($intern); =head1 DESCRIPTION The Email::Simple class is one of the base objects used by the large set of Email* modules, which implement many e-mail needs which are also supported by MailBox. You can use this class to gradularly move from a Email* based implementation into a MailBox implementation. The internals of this class are far from optimal. The conversion does work (thanks to Ricardo Signes), but is expensive in time and memory usage. It could easily be optimized. Extends L<"DESCRIPTION" in Mail::Message::Convert|Mail::Message::Convert/"DESCRIPTION">. =head1 METHODS Extends L<"METHODS" in Mail::Message::Convert|Mail::Message::Convert/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Message::Convert|Mail::Message::Convert/"Constructors">. =over 4 =item $class-E<gt>B<new>(%options) Inherited, see L<Mail::Message::Convert/"METHODS"> =back =head2 Attributes Extends L<"Attributes" in Mail::Message::Convert|Mail::Message::Convert/"Attributes">. =head2 Converting Extends L<"Converting" in Mail::Message::Convert|Mail::Message::Convert/"Converting">. =over 4 =item $obj-E<gt>B<export>($message, %options) Returns a new Email::Simple object based on the information from a L<Mail::Message|Mail::Message> object. The C<$message> specified is an instance of a L<Mail::Message|Mail::Message>. » example: my $convert = Mail::Message::Convert::EmailSimple->new; my Mail::Message $msg = Mail::Message->new; my Mail::Internet $copy = $convert->export($msg); =item $obj-E<gt>B<from>($object, %options) Returns a new L<Mail::Message|Mail::Message> object based on the information from an Email::Simple. » example: my $convert = Mail::Message::Convert::EmailSimple->new; my Mail::Internet $msg = Mail::Internet->new; my Mail::Message $copy = $convert->from($msg); =item $obj-E<gt>B<selectedFields>($head) Inherited, see L<Mail::Message::Convert/"Converting"> =back =head2 Error handling Extends L<"Error handling" in Mail::Message::Convert|Mail::Message::Convert/"Error handling">. =over 4 =item $obj-E<gt>B<AUTOLOAD>() Inherited, see L<Mail::Reporter/"Error handling"> =item $obj-E<gt>B<notImplemented>() Inherited, see L<Mail::Reporter/"Error handling"> =back =head2 Cleanup Extends L<"Cleanup" in Mail::Message::Convert|Mail::Message::Convert/"Cleanup">. =over 4 =item $obj-E<gt>B<DESTROY>() Inherited, see L<Mail::Reporter/"Cleanup"> =back =head1 DIAGNOSTICS =over 4 =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =item Error: converting from Email::Simple but got a $class. Cast by C<from()> =item Error: export message must be a Mail::Message, but is a $class. Cast by C<export()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Convert/HtmlFormatText.pm����������������������������������������0000644�0001750�0000144�00000002444�15166136116�024352� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::Convert::HtmlFormatText;{ our $VERSION = '4.05'; } use parent 'Mail::Message::Convert'; use strict; use warnings; use Log::Report 'mail-message', import => [ qw// ]; use HTML::TreeBuilder (); use HTML::FormatText (); use Mail::Message::Body::String (); #-------------------- sub init($) { my ($self, $args) = @_; $self->SUPER::init($args); $self->{MMCH_formatter} = HTML::FormatText->new( leftmargin => $args->{leftmargin} // 3,, rightmargin => $args->{rightmargin} // 72, ); $self; } #-------------------- sub format($) { my ($self, $body) = @_; my $dec = $body->encode(transfer_encoding => 'none'); my $tree = HTML::TreeBuilder->new_from_file($dec->file); (ref $body)->new( based_on => $body, mime_type => 'text/plain', charset => 'iso-8859-1', data => [ $self->{MMCH_formatter}->format($tree) ], ); } 1; ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Convert/MimeEntity.pm��������������������������������������������0000644�0001750�0000144�00000002372�15166136116�023514� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::Convert::MimeEntity;{ our $VERSION = '4.05'; } use parent 'Mail::Message::Convert'; use strict; use warnings; use Log::Report 'mail-message', import => [ qw/__x error/ ]; use MIME::Entity (); use MIME::Parser (); use Mail::Message (); #-------------------- sub export($$;$) { my ($self, $message, $parser) = @_; defined $message or return (); $message->isa('Mail::Message') or error __x"export message must be a Mail::Message object, but is {what UNKNOWN}.", what => $message; $parser ||= MIME::Parser->new; $parser->parse($message->file); } sub from($) { my ($self, $mime_ent) = @_; defined $mime_ent or return (); $mime_ent->isa('MIME::Entity') or error __x"converting from MIME::Entity but got a {class}.", class => ref $mime_ent; Mail::Message->read($mime_ent->as_string); } 1; ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Convert/TextAutoformat.pm����������������������������������������0000644�0001750�0000144�00000002025�15166136116�024411� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::Convert::TextAutoformat;{ our $VERSION = '4.05'; } use parent 'Mail::Message::Convert'; use strict; use warnings; use Log::Report 'mail-message', import => [ qw// ]; use Text::Autoformat qw/autoformat/; use Mail::Message::Body::String (); #-------------------- sub init($) { my ($self, $args) = @_; $self->SUPER::init($args); $self->{MMCA_options} = $args->{autoformat} || +{ all => 1 }; $self; } #-------------------- sub autoformatBody($) { my ($self, $body) = @_; (ref $body)->new(based_on => $body, data => autoformat($body->string, $self->{MMCA_options})); } 1; �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Convert/HtmlFormatPS.pm������������������������������������������0000644�0001750�0000144�00000002411�15166136116�023742� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::Convert::HtmlFormatPS;{ our $VERSION = '4.05'; } use parent 'Mail::Message::Convert'; use strict; use warnings; use Log::Report 'mail-message', import => [ qw// ]; use Mail::Message::Body::String (); use HTML::TreeBuilder (); use HTML::FormatPS (); #-------------------- sub init($) { my ($self, $args) = @_; my @formopts = map +($_ => delete $args->{$_}), grep m/^[A-Z]/, keys %$args; $self->SUPER::init($args); $self->{MMCH_formatter} = HTML::FormatPS->new(@formopts); $self; } #-------------------- sub format($) { my ($self, $body) = @_; my $dec = $body->encode(transfer_encoding => 'none'); my $tree = HTML::TreeBuilder->new_from_file($dec->file); (ref $body)->new( based_on => $body, mime_type => 'application/postscript', data => [ $self->{MMCH_formatter}->format($tree) ], ); } 1; �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Field/�����������������������������������������������������������0000755�0001750�0000144�00000000000�15166136132�020467� 5����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Field/Address.pm�������������������������������������������������0000644�0001750�0000144�00000004063�15166136116�022417� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::Field::Address;{ our $VERSION = '4.05'; } use parent 'Mail::Identity'; use strict; use warnings; use Log::Report 'mail-message', import => [ qw/__x error/ ]; use Mail::Message::Field::Addresses (); use Mail::Message::Field::Full (); use Scalar::Util qw/blessed/; my $format = 'Mail::Message::Field::Full'; #-------------------- use overload '""' => 'string', bool => sub {1}, cmp => sub { lc($_[0]->address) cmp lc($_[1]) }; #-------------------- sub coerce($@) { my ($class, $addr, %args) = @_; defined $addr or return (); blessed $addr or return $class->parse($addr); $addr->isa($class) and return $addr; my $from = $class->from($addr, %args) or error __x"cannot coerce a {type} into a {class}.", type => ref $addr // $addr, class => $class; bless $from, $class; } sub init($) { my ($self, $args) = @_; $self->SUPER::init($args); $self->{MMFA_encoding} = delete $args->{encoding}; $self; } sub parse($) { my $self = shift; my $parsed = Mail::Message::Field::Addresses->new(To => shift); defined $parsed ? ($parsed->addresses)[0] : (); } #-------------------- sub encoding() { $_[0]->{MMFA_encoding} } #-------------------- sub string() { my $self = shift; my @opts = (charset => $self->charset, encoding => $self->encoding); # language => $self->language my @parts; my $phrase = $self->phrase; push @parts, $format->createPhrase($phrase, @opts) if defined $phrase; my $address = $self->address; push @parts, @parts ? '<'.$address.'>' : $address; my $comment = $self->comment; push @parts, $format->createComment($comment, @opts) if defined $comment; join ' ', @parts; } 1; �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Field/Unstructured.pm��������������������������������������������0000644�0001750�0000144�00000002067�15166136117�023544� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::Field::Unstructured;{ our $VERSION = '4.05'; } use parent 'Mail::Message::Field::Full'; use strict; use warnings; use Log::Report 'mail-message', import => [ qw/__x warning/ ]; #-------------------- sub init($) { my ($self, $args) = @_; if($args->{body} && ($args->{encoding} || $args->{charset})) { $args->{body} = $self->encode($args->{body}, %$args); } $self->SUPER::init($args); ! defined $args->{attributes} or warning __x"attributes are not supported for unstructured fields."; ! defined $args->{extra} or warning __x"no extras for unstructured fields."; $self; } #-------------------- 1; �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Field/Date.pod���������������������������������������������������0000644�0001750�0000144�00000026157�15166136117�022066� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Field::Date - message header field with uris =head1 INHERITANCE Mail::Message::Field::Date is a Mail::Message::Field::Structured is a Mail::Message::Field::Full is a Mail::Message::Field is a Mail::Reporter =head1 SYNOPSIS my $f = Mail::Message::Field->new(Date => time); my $f = Mail::Message::Field::Date->new(Date => time); my $date = $f->date; # cleaned-up and validated my $time = $date->time; # converted to POSIX time =head1 DESCRIPTION Dates are a little more tricky than it should be: the formatting permits a few constructs more than other RFCs use for timestamps. For instance, a small subset of timezone abbreviations are permitted. The studied date field will reformat the content into a standard form. Extends L<"DESCRIPTION" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"DESCRIPTION">. =head1 OVERLOADED Extends L<"OVERLOADED" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"OVERLOADED">. =over 4 =item overload: B<""> stringification Inherited, see L<Mail::Message::Field::Full/"OVERLOADED"> =item overload: B<'""'> stringification Inherited, see L<Mail::Message::Field/"OVERLOADED"> =item overload: B<'0+'> numification Inherited, see L<Mail::Message::Field/"OVERLOADED"> =item overload: B<'<=>'> numeric comparison Inherited, see L<Mail::Message::Field/"OVERLOADED"> =item overload: B<bool> boolean Inherited, see L<Mail::Message::Field/"OVERLOADED"> =item overload: B<cmp> string comparison Inherited, see L<Mail::Message::Field/"OVERLOADED"> =back =head1 METHODS Extends L<"METHODS" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"Constructors">. =over 4 =item $obj-E<gt>B<clone>() Inherited, see L<Mail::Message::Field/"Constructors"> =item $class-E<gt>B<from>($field, %options) Inherited, see L<Mail::Message::Field::Full/"Constructors"> =item $class-E<gt>B<new>($data) Inherited, see L<Mail::Message::Field::Structured/"METHODS"> -Option --Defined in --Default attributes Mail::Message::Field::Structured <ignored> charset Mail::Message::Field::Full undef datum Mail::Message::Field::Structured undef encoding Mail::Message::Field::Full 'q' force Mail::Message::Field::Full false language Mail::Message::Field::Full undef =over 2 =item attributes => \@attributes|\%attributes =item charset => $charset =item datum => $date =item encoding => 'q'|'Q'|'b'|'B' =item force => BOOLEAN =item language => $language =back » example: my $mmfd = 'Mail::Message::Field::Date'; my $f = $mmfd->new(Date => time); =back =head2 Attributes Extends L<"Attributes" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"Attributes">. =over 4 =item $obj-E<gt>B<Name>() Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<body>() Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<folded>() Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<foldedBody>( [$body] ) Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<name>() Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<unfoldedBody>( [$body, [$wrap]] ) Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<wellformedName>( [STRING] ) Inherited, see L<Mail::Message::Field/"Attributes"> =back =head2 The field Extends L<"The field" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"The field">. =over 4 =item $any-E<gt>B<isStructured>( [$name] ) Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<length>() Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<nrLines>() Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<print>( [$fh] ) Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<size>() Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<string>( [$wrap] ) Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<toDisclose>() Inherited, see L<Mail::Message::Field/"The field"> =back =head2 Access to the body Extends L<"Access to the body" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"Access to the body">. =over 4 =item $obj-E<gt>B<decodedBody>(%options) Inherited, see L<Mail::Message::Field::Full/"Access to the body"> =back =head2 Access to the content Extends L<"Access to the content" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"Access to the content">. =over 4 =item $obj-E<gt>B<addAttribute>(...) Attributes are not supported for date fields. =item $obj-E<gt>B<addresses>() Inherited, see L<Mail::Message::Field/"Access to the content"> =item $obj-E<gt>B<attrPairs>() Inherited, see L<Mail::Message::Field::Structured/"Access to the content"> =item $obj-E<gt>B<attribute>( $object|<STRING, %options>|<$name,$value,%options> ) Inherited, see L<Mail::Message::Field::Structured/"Access to the content"> =item $obj-E<gt>B<attributes>() Inherited, see L<Mail::Message::Field::Structured/"Access to the content"> =item $obj-E<gt>B<beautify>() Inherited, see L<Mail::Message::Field::Full/"Access to the content"> =item $obj-E<gt>B<comment>( [STRING] ) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $any-E<gt>B<createComment>(STRING, %options) Inherited, see L<Mail::Message::Field::Full/"Access to the content"> =item $any-E<gt>B<createPhrase>(STRING, %options) Inherited, see L<Mail::Message::Field::Full/"Access to the content"> =item $obj-E<gt>B<date>() The validated and standardized date representation for this field. When the body of this field is not recognized, then this will return C<undef>. =item $any-E<gt>B<dateToTimestamp>(STRING) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $any-E<gt>B<stripCFWS>( [STRING] ) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $obj-E<gt>B<study>() Inherited, see L<Mail::Message::Field/"Access to the content"> =item $obj-E<gt>B<time>() Convert date into a timestamp, as produced with POSIX::time(). =item $any-E<gt>B<toDate>( [$time] ) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $obj-E<gt>B<toInt>() Inherited, see L<Mail::Message::Field/"Access to the content"> =back =head2 Internals Extends L<"Internals" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"Internals">. =over 4 =item $any-E<gt>B<decode>(STRING, %options) Inherited, see L<Mail::Message::Field::Full/"Internals"> =item $obj-E<gt>B<encode>(STRING, %options) Inherited, see L<Mail::Message::Field::Full/"Internals"> =back =head2 Parsing Extends L<"Parsing" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"Parsing">. =over 4 =item $obj-E<gt>B<consume>( $line | <$name,<$body|$objects>> ) Inherited, see L<Mail::Message::Field/"Parsing"> =item $any-E<gt>B<consumeComment>(STRING) Inherited, see L<Mail::Message::Field::Full/"Parsing"> =item $obj-E<gt>B<consumeDotAtom>(STRING) Inherited, see L<Mail::Message::Field::Full/"Parsing"> =item $any-E<gt>B<consumePhrase>(STRING) Inherited, see L<Mail::Message::Field::Full/"Parsing"> =item $obj-E<gt>B<datum>( [$value] ) Inherited, see L<Mail::Message::Field::Structured/"Parsing"> =item $obj-E<gt>B<defaultWrapLength>( [$length] ) Inherited, see L<Mail::Message::Field/"Parsing"> =item $any-E<gt>B<fold>( $name, $body, [$maxchars] ) Inherited, see L<Mail::Message::Field/"Parsing"> =item $obj-E<gt>B<parse>(STRING) Inherited, see L<Mail::Message::Field::Full/"Parsing"> =item $obj-E<gt>B<produceBody>() Inherited, see L<Mail::Message::Field::Full/"Parsing"> =item $obj-E<gt>B<setWrapLength>( [$length] ) Inherited, see L<Mail::Message::Field/"Parsing"> =item $obj-E<gt>B<stringifyData>(STRING|ARRAY|$objects) Inherited, see L<Mail::Message::Field/"Parsing"> =item $obj-E<gt>B<unfold>(STRING) Inherited, see L<Mail::Message::Field/"Parsing"> =back =head2 Error handling Extends L<"Error handling" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"Error handling">. =over 4 =item $obj-E<gt>B<AUTOLOAD>() Inherited, see L<Mail::Reporter/"Error handling"> =item $obj-E<gt>B<notImplemented>() Inherited, see L<Mail::Reporter/"Error handling"> =back =head2 Cleanup Extends L<"Cleanup" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"Cleanup">. =over 4 =item $obj-E<gt>B<DESTROY>() Inherited, see L<Mail::Reporter/"Cleanup"> =back =head1 DETAILS Extends L<"DETAILS" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"DETAILS">. =head1 DIAGNOSTICS =over 4 =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =item Warning: field content is not numerical: $content The numeric value of a field is requested (for instance the C<Lines> or C<Content-Length> fields should be numerical), however the data contains weird characters. Cast by C<toInt()> =item Error: field name too long (max $count), in '$name'. It is not specified in the RFCs how long a field name can be, but at least it should be a few characters shorter than the line wrap. Cast by C<fold()> =item Warning: illegal character in charset '$name'. The field is created with an utf8 string which only contains data from the specified character set. However, that character set can never be a valid name because it contains characters which are not permitted. Cast by C<encode()> =item Warning: illegal character in field name $name. A new field is being created which does contain characters not permitted by the RFCs. Using this field in messages may break other e-mail clients or transfer agents, and therefore mutulate or extinguish your message. Cast by C<consume()> =item Warning: illegal character in language '$name'. The field is created with data which is specified to be in a certain language, however, the name of the language cannot be valid: it contains characters which are not permitted by the RFCs. Cast by C<encode()> =item Warning: illegal encoding '$name', using 'q'. The RFCs only permit base64 (C<b > or C<B >) or quoted-printable (C<q> or C<Q>) encoding. Other than these four options are illegal. Cast by C<encode()> =item Error: no attributes for date fields. It is not possible to add attributes to date fields: it is not permitted by the RFCs. Cast by C<addAttribute()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Field/Structured.pm����������������������������������������������0000644�0001750�0000144�00000006370�15166136116�023201� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::Field::Structured;{ our $VERSION = '4.05'; } use parent 'Mail::Message::Field::Full'; use strict; use warnings; use Log::Report 'mail-message', import => [ qw// ]; use Mail::Message::Field::Attribute (); use Storable qw/dclone/; #-------------------- sub init($) { my ($self, $args) = @_; $self->{MMFS_attrs} = {}; $self->{MMFS_datum} = $args->{datum}; $self->SUPER::init($args); my $attr = $args->{attributes} || []; $attr = [ %$attr ] if ref $attr eq 'HASH'; while(@$attr) { my $name = shift @$attr; if(ref $name) { $self->attribute($name) } else { $self->attribute($name, shift @$attr) } } $self; } sub clone() { dclone(shift) } #-------------------- sub attribute($;$) { my ($self, $attr) = (shift, shift); my $name; if(ref $attr) { $name = $attr->name } elsif( !@_ ) { return $self->{MMFS_attrs}{lc $attr} } else { $name = $attr; $attr = Mail::Message::Field::Attribute->new($name, @_); } delete $self->{MMFF_body}; $self->{MMFS_attrs}{lc $name} = $attr; } sub attributes() { values %{$_[0]->{MMFS_attrs}} } sub beautify() { delete $_[0]->{MMFF_body} } sub attrPairs() { map +($_->name, $_->value), $_[0]->attributes } #-------------------- sub parse($) { my ($self, $string) = @_; for($string) { # remove FWS, even within quoted strings s/\r?\n(\s)/$1/gs; s/\r?\n/ /gs; s/\s+$//; } my $datum = ''; while(length $string && substr($string, 0, 1) ne ';') { (undef, $string) = $self->consumeComment($string); $datum .= $1 if $string =~ s/^([^;(]+)//; } $self->{MMFS_datum} = $datum; my $found = ''; while($string =~ m/\S/) { my $len = length $string; if($string =~ s/^\s*\;\s*// && length $found) { my ($name) = $found =~ m/^([^*]+)\*/; if($name && (my $cont = $self->attribute($name))) { $cont->addComponent($found); # continuation } else { my $attr = Mail::Message::Field::Attribute->new($found); $self->attribute($attr); } $found = ''; } (undef, $string) = $self->consumeComment($string); $string =~ s/^\n//; (my $text, $string) = $self->consumePhrase($string); $found .= $text if defined $text; if(length($string) == $len) { # nothing consumed, remove character to avoid endless loop $string =~ s/^\s*\S//; } } if(length $found) { my ($name) = $found =~ m/^([^*]+)\*/; if($name && (my $cont = $self->attribute($name))) { $cont->addComponent($found); # continuation } else { my $attr = Mail::Message::Field::Attribute->new($found); $self->attribute($attr); } } 1; } sub produceBody() { my $self = shift; my $attrs = $self->{MMFS_attrs}; my $datum = $self->{MMFS_datum}; join '; ', ($datum // ''), map $_->string, @{$attrs}{sort keys %$attrs}; } sub datum(@) { my $self = shift; @_ or return $self->{MMFS_datum}; delete $self->{MMFF_body}; $self->{MMFS_datum} = shift; } 1; ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Field/Full.pm����������������������������������������������������0000644�0001750�0000144�00000024367�15166136116�021745� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::Field::Full;{ our $VERSION = '4.05'; } use parent 'Mail::Message::Field'; use strict; use warnings; use utf8; use Log::Report 'mail-message', import => [ qw/__x error warning/ ]; use Encode (); use MIME::QuotedPrint (); use Storable qw/dclone/; use Mail::Message::Field::Addresses (); use Mail::Message::Field::AuthResults (); #use Mail::Message::Field::AuthRecChain (); use Mail::Message::Field::Date (); use Mail::Message::Field::DKIM (); use Mail::Message::Field::Structured (); use Mail::Message::Field::Unstructured (); use Mail::Message::Field::URIs (); my $atext = q[a-zA-Z0-9!#\$%&'*+\-\/=?^_`{|}~]; # from RFC5322 my $utf8_atext = q[\p{Alnum}!#\$%&'*+\-\/=?^_`{|}~]; # from RFC5335 my $atext_ill = q/\[\]/; # illegal, but still used (esp spam) #-------------------- use overload '""' => sub { shift->decodedBody }; #-------------------- my %implementation; BEGIN { $implementation{$_} = 'Addresses' for qw/from to sender cc bcc reply-to envelope-to resent-from resent-to resent-cc resent-bcc resent-reply-to resent-sender x-beenthere errors-to mail-follow-up x-loop delivered-to original-sender x-original-sender/; $implementation{$_} = 'URIs' for qw/list-help list-post list-subscribe list-unsubscribe list-archive list-owner/; $implementation{$_} = 'Structured' for qw/content-disposition content-type content-id/; $implementation{$_} = 'Date' for qw/date resent-date/; $implementation{$_} = 'AuthResults' for qw/authentication-results/; $implementation{$_} = 'DKIM' for qw/dkim-signature/; # $implementation{$_} = 'AuthRecChain' for qw/arc-authentication-results arc-message-signature arc-seal/; } sub new($;$$@) { my $class = shift; my $name = shift; my $body = @_ % 2 ? shift : undef; my %args = @_; $body = delete $args{body} if defined $args{body}; unless(defined $body) { (my $n, $body) = split /\s*\:\s*/s, $name, 2; $name = $n if defined $body; } $class eq __PACKAGE__ or return $class->SUPER::new(%args, name => $name, body => $body); # Look for best class to suit this field my $myclass = 'Mail::Message::Field::' . ($implementation{lc $name} || 'Unstructured'); $myclass->SUPER::new(%args, name => $name, body => $body); } sub init($) { my ($self, $args) = @_; $self->SUPER::init($args); $self->{MMFF_name} = $args->{name}; my $body = $args->{body}; if(!defined $body || !length $body || ref $body) { ; } # no body yet elsif(index($body, "\n") >= 0) { $self->foldedBody($body) } # body is already folded else { $self->unfoldedBody($body) } # body must be folded $self; } sub clone() { dclone(shift) } sub name() { lc shift->{MMFF_name}} sub Name() { $_[0]->{MMFF_name} } sub folded() { my $self = shift; wantarray or return $self->{MMFF_name}.':'.$self->foldedBody; my @lines = $self->foldedBody; my $first = $self->{MMFF_name}. ':'. shift @lines; ($first, @lines); } sub unfoldedBody($;$) { my ($self, $body) = (shift, shift); if(defined $body) { $self->foldedBody(scalar $self->fold($self->{MMFF_name}, $body)); return $body; } $self->foldedBody =~ s/\r?\n(\s)/$1/gr =~ s/\r?\n/ /gr =~ s/^\s+//r =~ s/\s+$//r; } sub foldedBody($) { my ($self, $body) = @_; if(@_==2) { $self->parse($body); $body =~ s/^\s*/ /m; $self->{MMFF_body} = $body; } elsif(defined($body = $self->{MMFF_body})) { ; } else { # Create a new folded body from the parts. $self->{MMFF_body} = $body = $self->fold($self->{MMFF_name}, $self->produceBody); } wantarray ? (split /^/, $body) : $body; } #-------------------- sub from($@) { my ($class, $field) = (shift, shift); defined $field ? $class->new($field->Name, $field->foldedBody, @_) : (); } #-------------------- sub decodedBody() { my $self = shift; $self->decode($self->unfoldedBody, @_); } #-------------------- sub createComment($@) { my ($thing, $comment) = (shift, shift); $comment = $thing->encode($comment, @_) if @_; # encoding required... # Correct dangling parenthesis local $_ = $comment; # work with a copy s#\\[()]#xx#g; # remove escaped parens s#[^()]#x#g; # remove other chars while( s#\(([^()]*)\)#x$1x# ) {;} # remove pairs of parens substr($comment, CORE::length($_), 0, '\\') while s#[()][^()]*$##; # add escape before remaining parens $comment =~ s#\\+$##; # backslash at end confuses "($comment)"; } sub createPhrase($) { my $self = shift; local $_ = shift; # I do not case whether it gets a but sloppy in the header string, # as long as it is functionally correct: no folding inside phrase quotes. return $_ = $self->encode($_, @_, force => 1) if length $_ > 50; $_ = $self->encode($_, @_) if @_; # encoding required... if( m/[^$atext]/ ) { s#\\#\\\\#g; s#"#\\"#g; $_ = qq["$_"]; } $_; } sub beautify() { $_[0] } #-------------------- sub _mime_word($$) { "$_[0]$_[1]?=" } sub _encode_b($) { MIME::Base64::encode_base64(shift, '') } sub _encode_q($) # RFC2047 sections 4.2 and 5 { my $chunk = shift; $chunk =~ s#([^a-zA-Z0-9!*+/_ -])#sprintf "=%02X", ord $1#ge; $chunk =~ s#([_\?,"])#sprintf "=%02X", ord $1#ge; $chunk =~ s/ /_/g; # special case for =? ?= use $chunk; } sub encode($@) { my ($self, $utf8, %args) = @_; my ($charset, $lang, $encoding); if($charset = $args{charset}) { warning __x"illegal character in charset '{name}'.", name => $charset if $charset =~ m/[\x00-\ ()<>@,;:"\/[\]?.=\\]/; } else { $charset = $utf8 =~ /\P{ASCII}/ ? 'utf8' : 'us-ascii'; } if($lang = $args{language}) { warning __x"illegal character in language '{name}'.", name => $lang if $lang =~ m/[\x00-\ ()<>@,;:"\/[\]?.=\\]/; } if($encoding = $args{encoding}) { unless($encoding =~ m/^[bBqQ]$/ ) { warning __x"illegal encoding '{name}', using 'q'.", name => $encoding; $encoding = 'q'; } } else { $encoding = 'q' } my $name = $args{name}; my $lname = defined $name ? length($name)+1 : 0; return $utf8 if lc($encoding) eq 'q' && length $utf8 < 70 && ($utf8 =~ m/\A[\p{IsASCII}]+\z/ms && !$args{force}); my $pre = '=?'. $charset. ($lang ? '*'.$lang : '') .'?'.$encoding.'?'; my @result; if(lc($encoding) eq 'q') { my $chunk = ''; my $llen = 73 - length($pre) - $lname; while(length(my $chr = substr($utf8, 0, 1, ''))) { $chr = _encode_q Encode::encode($charset, $chr, 0); if(bytes::length($chunk) + bytes::length($chr) > $llen) { push @result, _mime_word($pre, $chunk); $chunk = ''; $llen = 73 - length $pre; } $chunk .= $chr; } push @result, _mime_word($pre, $chunk) if length($chunk); } else { my $chunk = ''; my $llen = int((73 - length($pre) - $lname) / 4) * 3; while(length(my $chr = substr($utf8, 0, 1, ''))) { my $chr = Encode::encode($charset, $chr, 0); if(bytes::length($chunk) + bytes::length($chr) > $llen) { push @result, _mime_word($pre, _encode_b($chunk)); $chunk = ''; $llen = int((73 - length $pre) / 4) * 3; } $chunk .= $chr; } push @result, _mime_word($pre, _encode_b($chunk)) if length $chunk; } join ' ', @result; } sub _decoder($$$) { my ($charset, $encoding, $encoded) = @_; $charset =~ s/\*[^*]+$//; # language component not used my $to_utf8 = Encode::find_encoding($charset || 'us-ascii'); $to_utf8 or return $encoded; my $decoded; if($encoding !~ /\S/) { $decoded = $encoded; } elsif(lc($encoding) eq 'q') { # Quoted-printable encoded specific to mime-fields $decoded = MIME::QuotedPrint::decode_qp($encoded =~ s/_/ /gr); } elsif(lc($encoding) eq 'b') { # Base64 encoded require MIME::Base64; $decoded = MIME::Base64::decode_base64($encoded); } else { # unknown encodings ignored return $encoded; } $to_utf8->decode($decoded, Encode::FB_DEFAULT); # error-chars -> '?' } sub decode($@) { my $thing = shift; my @encoded = split /(\=\?[^?\s]*\?[bqBQ]?\?[^?]*\?\=)/, shift; @encoded or return ''; my %args = @_; my $is_text = exists $args{is_text} ? $args{is_text} : 1; my @decoded = shift @encoded; while(@encoded) { shift(@encoded) =~ /\=\?([^?\s]*)\?([^?\s]*)\?([^?]*)\?\=/; push @decoded, _decoder $1, $2, $3; @encoded or last; # in text, blanks between encoding must be removed, but otherwise kept if($is_text && $encoded[0] !~ m/\S/) { shift @encoded } else { push @decoded, shift @encoded } } join '', @decoded; } #-------------------- sub parse($) { $_[0] } sub consumePhrase($) { my ($thing, $string) = @_; my $phrase; if($string =~ s/^\s*\" ((?:[^"\r\n\\]*|\\.)*) (?:\"|\s*$)//x ) { ($phrase = $1) =~ s/\\\"/"/g; } elsif($string =~ s/^\s*((?:\=\?.*?\?\=|[${utf8_atext}${atext_ill}\ \t.])+)//o ) { ($phrase = $1) =~ s/\s+$//; CORE::length($phrase) or undef $phrase; } defined $phrase ? ($thing->decode($phrase), $string) : (undef, $string); } sub consumeComment($) { my ($thing, $string) = @_; # Backslashes are officially not permitted in comments, but not everyone # knows that. Nested parens are supported. $string =~ s/^\s* \( ((?:\\.|[^)])*) (?:\)|$) //x or return (undef, $string); # allow unterminated comments my $comment = $1; # Continue consuming characters until we have balanced parens, for # nested comments which are permitted. while(1) { (my $count = $comment) =~ s/\\./xx/g; last if +( $count =~ tr/(// ) == ( $count =~ tr/)// ); last if $string !~ s/^((?:\\.|[^)])*) \)//x; # cannot satisfy $comment .= ')'.$1; } for($comment) { s/^\s+//; s/\s+$//; s/\\ ( [()] )/$1/gx; # Remove backslashes before nested comment. } ($comment, $string); } sub consumeDotAtom($) { my ($self, $string) = @_; my ($atom, $comment); while(1) { (my $c, $string) = $self->consumeComment($string); if(defined $c) { $comment .= $c; next } $string =~ s/^\s*([$atext]+(?:\.[$atext]+)*)//o or last; $atom .= $1; } ($atom, $string, $comment); } sub produceBody() { $_[0]->{MMFF_body} } #-------------------- 1; �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Field/Attribute.pm�����������������������������������������������0000644�0001750�0000144�00000011312�15166136116�022770� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::Field::Attribute;{ our $VERSION = '4.05'; } use parent 'Mail::Reporter'; use strict; use warnings; use Log::Report 'mail-message', import => [ qw/__x error warning/ ]; use Encode (); #-------------------- use overload '""' => sub { $_[0]->value }, cmp => sub { my ($self, $other) = @_; UNIVERSAL::isa($other, 'Mail::Message::Field') ? (lc($_[0])->name cmp lc($_[1]->name) || $_[0]->value cmp $_[1]->value) : $_[0]->value cmp $_[1]; }, fallback => 1; #-------------------- sub new($$@) { my ($class, $attr) = (shift, shift); my $value = @_ % 2 == 1 ? shift : undef; $class->SUPER::new(attr => $attr, value => $value, @_); } sub init($$) { my ($self, $args) = @_; $self->SUPER::init($args); my ($attr, $value, $cont) = @$args{ qw/attr value use_continuations/ }; my $name = ($attr =~ m/^(.*?)(?:\*\d+)?\*?\s*\=\s*/ ? $1 : $attr); warning __x"illegal character in parameter name '{name}'.", name => $name if $name !~ m/^[!#-'*+\-.0-9A-Z^-~]+$/; $self->{MMFF_name} = $name; $self->{MMFF_usecont} = $cont // 1; $self->{MMFF_charset} = $args->{charset} if defined $args->{charset}; $self->{MMFF_language} = $args->{language} if defined $args->{language}; $self->value(defined $value ? "$value" : ''); # enforce stringification $self->addComponent($attr) if $attr ne $name; $self; } #-------------------- sub name() { $_[0]->{MMFF_name} } sub value(;$) { my $self = shift; if(@_) { delete $self->{MMFF_cont}; return $self->{MMFF_value} = shift; } exists $self->{MMFF_value} ? $self->{MMFF_value} : $self->decode; } sub addComponent($) { my ($self, $component) = @_; defined $component or return; delete $self->{MMFF_value}; my ($name, $value) = split /\=/, $component, 2; if( substr($name, -1) eq '*' && $value =~ m/^([^']*)\'([^']*)\'/ ) { $self->{MMFF_charset} = length $1 ? $1 : undef; $self->{MMFF_language} = length $2 ? $2 : undef; } if( $name =~ m/\*([0-9]+)\*?$/ ) { $self->{MMFF_cont}[$1] = $component } else { $self->{MMFF_cont} = [ $component ] } $component; } sub charset() { $_[0]->{MMFF_charset} } sub language() { $_[0]->{MMFF_language} } sub string() { my $self = shift; my $cont = $self->{MMFF_cont} || $self->encode; wantarray? @$cont : (join '; ', '', @$cont); } #-------------------- sub encode() { my $self = shift; my $value = $self->{MMFF_value}; my @lines; my ($pre, $encoded); my $charset = $self->{MMFF_charset} || ''; my $lang = $self->{MMFF_language} || ''; my $name = $self->{MMFF_name}; my $cont = $self->{MMFF_usecont}; if($charset || $lang) { $pre = "$name*0*=$charset'$lang'"; $value = Encode::encode($charset, $value, 0); $encoded = 1; } elsif(grep m/[^\x20-\x7E]/, $value) { $pre = "$name*0*=''"; $encoded = 1; } else { $pre = "$name*0="; $value =~ s/"/\\"/g; $encoded = 0; } if($encoded) { # Use encoding my @c = split //, $value; while(@c) { my $c = shift @c; $c = '%'. sprintf "%02X", ord $c unless $c =~ m/[a-zA-Z0-9]/; if($cont && length($pre) + length($c)> 76) { push @lines, $pre; $pre = $name . '*' . @lines . '*=' . $c; } else { $pre .= $c } } push @lines, $pre; } elsif($cont) { # Simple string, but with continuations while(1) { push @lines, $pre.'"'. substr($value, 0, 75-length($pre), '') .'"'; length $value or last; $pre = $name . '*' . @lines . '='; } } else { # Single string only push @lines, $pre . $value; } $lines[0] =~ s/\*0// if @lines==1; $self->{MMFF_cont} = \@lines; } sub decode() { my $self = shift; my $value = ''; foreach my $cont ( @{$self->{MMFF_cont}} ) { unless(defined $cont) { $value .= "[continuation missing]"; next; } (my $name, local $_) = split /\=/, $cont, 2; if(substr($name, -1) eq '*') { s/^[^']*\'[^']*\'//; s/\%([a-fA-F0-9]{2})/chr hex $1/ge; } elsif( s/^\"(.*)\"$/$1/ ) { s/\\\"/"/g } elsif( s/^\'(.*)\'$/$1/ ) { s/\\\'/'/g } $value .= $_; } my $charset = $self->{MMFF_charset}; $value = Encode::decode($charset, $value, 0) if $charset; $self->{MMFF_value} = $value; } #-------------------- sub mergeComponent($) { my ($self, $comp) = @_; my $cont = $self->{MMFF_cont} or error __x"too late to merge: value already changed."; $self->addComponent($_) for @{$comp->{MMFF_cont}}; $self; } 1; ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Field/Structured.pod���������������������������������������������0000644�0001750�0000144�00000032740�15166136117�023350� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Field::Structured - one line of a structured message header =head1 INHERITANCE Mail::Message::Field::Structured is a Mail::Message::Field::Full is a Mail::Message::Field is a Mail::Reporter Mail::Message::Field::Structured is extended by Mail::Message::Field::Addresses Mail::Message::Field::AuthResults Mail::Message::Field::DKIM Mail::Message::Field::Date Mail::Message::Field::URIs =head1 SYNOPSIS my $f = Mail::Message::Field::Full ->new('Content-Type' => 'text/html'); my @encode = (charset => 'jp', use_continuations => 1); $f->attribute('filename=passwd'); $f->attribute(filename => 'passwd', @encode); my $attr = Mail::Message::Field::Attribute->new(...); $f->attribute($attr); =head1 DESCRIPTION Extends L<"DESCRIPTION" in Mail::Message::Field::Full|Mail::Message::Field::Full/"DESCRIPTION">. =head1 OVERLOADED Extends L<"OVERLOADED" in Mail::Message::Field::Full|Mail::Message::Field::Full/"OVERLOADED">. =over 4 =item overload: B<""> stringification Inherited, see L<Mail::Message::Field::Full/"OVERLOADED"> =item overload: B<'""'> stringification Inherited, see L<Mail::Message::Field/"OVERLOADED"> =item overload: B<'0+'> numification Inherited, see L<Mail::Message::Field/"OVERLOADED"> =item overload: B<'<=>'> numeric comparison Inherited, see L<Mail::Message::Field/"OVERLOADED"> =item overload: B<bool> boolean Inherited, see L<Mail::Message::Field/"OVERLOADED"> =item overload: B<cmp> string comparison Inherited, see L<Mail::Message::Field/"OVERLOADED"> =back =head1 METHODS Extends L<"METHODS" in Mail::Message::Field::Full|Mail::Message::Field::Full/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Message::Field::Full|Mail::Message::Field::Full/"Constructors">. =over 4 =item $obj-E<gt>B<clone>() Inherited, see L<Mail::Message::Field/"Constructors"> =item $class-E<gt>B<from>($field, %options) Inherited, see L<Mail::Message::Field::Full/"Constructors"> =item $class-E<gt>B<new>(($line | $name, $body, @attributes), %options) =over 4 =item * B<new>(C<$line>) Pass a C<$line> as it could be found in a file: a (possibly folded) line which is terminated by a new-line. =item * B<new>(C<$name>, C<$body>, C<@attributes>, C<%options>) A set of values which shape the line. =back The C<$name> is a wellformed header name (you may use L<wellformedName()|Mail::Message::Field/"Attributes">) to be sure about the casing. The C<$body> is a string, one body object, or an ARRAY of body objects. In case of objects, they must fit to the constructor of the field: the types which are accepted may differ. The C<@attributes> LIST contains L<Mail::Message::Field::Attribute|Mail::Message::Field::Attribute> objects. Finally, there are some C<%options>. Improves base, see L<Mail::Message::Field::Full/"METHODS"> -Option --Defined in --Default attributes +[ ] charset Mail::Message::Field::Full undef datum undef encoding Mail::Message::Field::Full 'q' force Mail::Message::Field::Full false language Mail::Message::Field::Full undef =over 2 =item attributes => \@attributes|\%attributes There are various ways to specify these attributes: pass an ARRAY which list of key-value pairs representing C<@attributes>, or an HASH containing these pairs, or an ARRAY with L<Mail::Message::Field::Attribute|Mail::Message::Field::Attribute> objects. =item charset => $charset =item datum => $date The method name I<body> is very confusing, even in the RFC. In MailBox, for historical reasons, L<body()|Mail::Message::Field/"Attributes"> returns the part of the field contents before the first semi-colon. L<foldedBody()|Mail::Message::Field/"Attributes"> and L<unfoldedBody()|Mail::Message::Field/"Attributes"> address the whole field. There is no common name for the piece of data before the parameters (attributes) in the field-content mentioned in the RFCs, so let's call it C<datum>. =item encoding => 'q'|'Q'|'b'|'B' =item force => BOOLEAN =item language => $language =back » example: of a structured field my @attrs = (Mail::Message::Field::Attribute->new(...), ...); my %options = (extra => 'the color blue'); my $t = Mail::Message::Field::Full->new(To => \@addrs, @attrs, %options); =back =head2 Attributes Extends L<"Attributes" in Mail::Message::Field::Full|Mail::Message::Field::Full/"Attributes">. =over 4 =item $obj-E<gt>B<Name>() Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<body>() Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<folded>() Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<foldedBody>( [$body] ) Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<name>() Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<unfoldedBody>( [$body, [$wrap]] ) Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<wellformedName>( [STRING] ) Inherited, see L<Mail::Message::Field/"Attributes"> =back =head2 The field Extends L<"The field" in Mail::Message::Field::Full|Mail::Message::Field::Full/"The field">. =over 4 =item $any-E<gt>B<isStructured>( [$name] ) Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<length>() Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<nrLines>() Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<print>( [$fh] ) Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<size>() Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<string>( [$wrap] ) Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<toDisclose>() Inherited, see L<Mail::Message::Field/"The field"> =back =head2 Access to the body Extends L<"Access to the body" in Mail::Message::Field::Full|Mail::Message::Field::Full/"Access to the body">. =over 4 =item $obj-E<gt>B<decodedBody>(%options) Inherited, see L<Mail::Message::Field::Full/"Access to the body"> =back =head2 Access to the content Extends L<"Access to the content" in Mail::Message::Field::Full|Mail::Message::Field::Full/"Access to the content">. =over 4 =item $obj-E<gt>B<addresses>() Inherited, see L<Mail::Message::Field/"Access to the content"> =item $obj-E<gt>B<attrPairs>() Returns a list with attribute name and value pairs. =item $obj-E<gt>B<attribute>( $object|<STRING, %options>|<$name,$value,%options> ) Add an attribute to the field. The attributes are added left-to-right into the string representation of the field, although the order of the attributes is un-important, according to the RFCs. You may pass a fully prepared L<Mail::Message::Field::Attribute|Mail::Message::Field::Attribute> C<$object>, if you like to do all preparations for correct representation of the data yourself. You may also pass one C<STRING>, which is a fully prepared attribute. This C<STRING> will not be changed, so be careful about quoting and encodings. As third possibility, you can specify an attribute C<$name> and its C<$value>. An attribute object will be created for you implicitly in both cases where such object is not supplied, passing the C<%options>. See L<Mail::Message::Field::Attribute::new()|Mail::Message::Field::Attribute/"Constructors"> about the available C<%options>. The attribute object is returned, however, when continuations are used this may be an object you already know about. C<undef> is returned when construction fails (when the attribute is incorrect). Improves base, see L<Mail::Message::Field/"Access to the content"> » example: $f->attribute(filename => 'passwd'); $f->attribute(filename => 'passwd', use_continuations => 0); my $attr = Mail::Message::Field::Attribute->new(...); $f->attribute($attr); =item $obj-E<gt>B<attributes>() Returns a list with all attributes, which are all L<Mail::Message::Field::Attribute|Mail::Message::Field::Attribute> objects. The attributes are not ordered in any way. The list may be empty. Double attributes or continuations are folded into one. Improves base, see L<Mail::Message::Field/"Access to the content"> =item $obj-E<gt>B<beautify>() Inherited, see L<Mail::Message::Field::Full/"Access to the content"> =item $obj-E<gt>B<comment>( [STRING] ) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $any-E<gt>B<createComment>(STRING, %options) Inherited, see L<Mail::Message::Field::Full/"Access to the content"> =item $any-E<gt>B<createPhrase>(STRING, %options) Inherited, see L<Mail::Message::Field::Full/"Access to the content"> =item $any-E<gt>B<dateToTimestamp>(STRING) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $any-E<gt>B<stripCFWS>( [STRING] ) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $obj-E<gt>B<study>() Inherited, see L<Mail::Message::Field/"Access to the content"> =item $any-E<gt>B<toDate>( [$time] ) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $obj-E<gt>B<toInt>() Inherited, see L<Mail::Message::Field/"Access to the content"> =back =head2 Internals Extends L<"Internals" in Mail::Message::Field::Full|Mail::Message::Field::Full/"Internals">. =over 4 =item $any-E<gt>B<decode>(STRING, %options) Inherited, see L<Mail::Message::Field::Full/"Internals"> =item $obj-E<gt>B<encode>(STRING, %options) Inherited, see L<Mail::Message::Field::Full/"Internals"> =back =head2 Parsing Extends L<"Parsing" in Mail::Message::Field::Full|Mail::Message::Field::Full/"Parsing">. =over 4 =item $obj-E<gt>B<consume>( $line | <$name,<$body|$objects>> ) Inherited, see L<Mail::Message::Field/"Parsing"> =item $any-E<gt>B<consumeComment>(STRING) Inherited, see L<Mail::Message::Field::Full/"Parsing"> =item $obj-E<gt>B<consumeDotAtom>(STRING) Inherited, see L<Mail::Message::Field::Full/"Parsing"> =item $any-E<gt>B<consumePhrase>(STRING) Inherited, see L<Mail::Message::Field::Full/"Parsing"> =item $obj-E<gt>B<datum>( [$value] ) The part of the field before the semi-colon (C<;>). =item $obj-E<gt>B<defaultWrapLength>( [$length] ) Inherited, see L<Mail::Message::Field/"Parsing"> =item $any-E<gt>B<fold>( $name, $body, [$maxchars] ) Inherited, see L<Mail::Message::Field/"Parsing"> =item $obj-E<gt>B<parse>(STRING) Inherited, see L<Mail::Message::Field::Full/"Parsing"> =item $obj-E<gt>B<produceBody>() Inherited, see L<Mail::Message::Field::Full/"Parsing"> =item $obj-E<gt>B<setWrapLength>( [$length] ) Inherited, see L<Mail::Message::Field/"Parsing"> =item $obj-E<gt>B<stringifyData>(STRING|ARRAY|$objects) Inherited, see L<Mail::Message::Field/"Parsing"> =item $obj-E<gt>B<unfold>(STRING) Inherited, see L<Mail::Message::Field/"Parsing"> =back =head2 Error handling Extends L<"Error handling" in Mail::Message::Field::Full|Mail::Message::Field::Full/"Error handling">. =over 4 =item $obj-E<gt>B<AUTOLOAD>() Inherited, see L<Mail::Reporter/"Error handling"> =item $obj-E<gt>B<notImplemented>() Inherited, see L<Mail::Reporter/"Error handling"> =back =head2 Cleanup Extends L<"Cleanup" in Mail::Message::Field::Full|Mail::Message::Field::Full/"Cleanup">. =over 4 =item $obj-E<gt>B<DESTROY>() Inherited, see L<Mail::Reporter/"Cleanup"> =back =head1 DETAILS Extends L<"DETAILS" in Mail::Message::Field::Full|Mail::Message::Field::Full/"DETAILS">. =head1 DIAGNOSTICS =over 4 =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =item Warning: field content is not numerical: $content The numeric value of a field is requested (for instance the C<Lines> or C<Content-Length> fields should be numerical), however the data contains weird characters. Cast by C<toInt()> =item Error: field name too long (max $count), in '$name'. It is not specified in the RFCs how long a field name can be, but at least it should be a few characters shorter than the line wrap. Cast by C<fold()> =item Warning: illegal character in charset '$name'. The field is created with an utf8 string which only contains data from the specified character set. However, that character set can never be a valid name because it contains characters which are not permitted. Cast by C<encode()> =item Warning: illegal character in field name $name. A new field is being created which does contain characters not permitted by the RFCs. Using this field in messages may break other e-mail clients or transfer agents, and therefore mutulate or extinguish your message. Cast by C<consume()> =item Warning: illegal character in language '$name'. The field is created with data which is specified to be in a certain language, however, the name of the language cannot be valid: it contains characters which are not permitted by the RFCs. Cast by C<encode()> =item Warning: illegal encoding '$name', using 'q'. The RFCs only permit base64 (C<b > or C<B >) or quoted-printable (C<q> or C<Q>) encoding. Other than these four options are illegal. Cast by C<encode()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. ��������������������������������Mail-Message-4.05/lib/Mail/Message/Field/Full.pod���������������������������������������������������0000644�0001750�0000144�00000044555�15166136117�022115� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Field::Full - construct one smart line in a message header =head1 INHERITANCE Mail::Message::Field::Full is a Mail::Message::Field is a Mail::Reporter Mail::Message::Field::Full is extended by Mail::Message::Field::Structured Mail::Message::Field::Unstructured =head1 SYNOPSIS # Getting to understand the complexity of a header field ... my $fast = $msg->head->get('subject'); my $full = Mail::Message::Field::Full->from($fast); my $full = $msg->head->get('subject')->study; # same my $full = $msg->head->study('subject'); # same my $full = $msg->study('subject'); # same # ... or build a complex header field yourself my $f = Mail::Message::Field::Full->new('To'); my $f = Mail::Message::Field::Full->new('Subject: hi!'); my $f = Mail::Message::Field::Full->new(Subject => 'hi!'); =head1 DESCRIPTION This is the I<full> implementation of a header field: it has I<full> understanding of all predefined header fields. These objects will be quite slow, because header fields can be very complex. Of course, this class delivers the optimal result, but for a quite large penalty in performance and memory consumption. Are you willing to accept? This class supports the common header description from RFC2822 (formerly RFC822), the extensions with respect to character set encodings as specified in RFC2047, and the extensions on language specification and long parameter wrapping from RFC2231. If you do not need the latter two, then the L<Mail::Message::Field::Fast|Mail::Message::Field::Fast> and L<Mail::Message::Field::Flex|Mail::Message::Field::Flex> are enough for your application. RFC5322 (L<https://www.rfc-editor.org/rfc/rfc5322.html>) describes a long list of obsolete syntax for structured header fields. This mainly refers to disallowing white-spaces and folding on many inconvenient locations. This matches MailBox's natural behavior. Extends L<"DESCRIPTION" in Mail::Message::Field|Mail::Message::Field/"DESCRIPTION">. =head1 OVERLOADED Extends L<"OVERLOADED" in Mail::Message::Field|Mail::Message::Field/"OVERLOADED">. =over 4 =item overload: B<""> stringification In string context, the decoded body is returned, as if L<decodedBody()|Mail::Message::Field::Full/"Access to the body"> would have been called. =item overload: B<'""'> stringification Inherited, see L<Mail::Message::Field/"OVERLOADED"> =item overload: B<'0+'> numification Inherited, see L<Mail::Message::Field/"OVERLOADED"> =item overload: B<'<=>'> numeric comparison Inherited, see L<Mail::Message::Field/"OVERLOADED"> =item overload: B<bool> boolean Inherited, see L<Mail::Message::Field/"OVERLOADED"> =item overload: B<cmp> string comparison Inherited, see L<Mail::Message::Field/"OVERLOADED"> =back =head1 METHODS Extends L<"METHODS" in Mail::Message::Field|Mail::Message::Field/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Message::Field|Mail::Message::Field/"Constructors">. =over 4 =item $obj-E<gt>B<clone>() Inherited, see L<Mail::Message::Field/"Constructors"> =item $class-E<gt>B<from>($field, %options) Convert any C<$field> (a L<Mail::Message::Field|Mail::Message::Field> object) into a new L<Mail::Message::Field::Full|Mail::Message::Field::Full> object. This conversion is done the hard way: the string which is produced by the original object is parsed again. Usually, the string which is parsed is exactly the line (or lines) as found in the original input source, which is a good thing because Full fields are much more careful with the actual content. C<%options> are passed to the constructor (see L<new()|Mail::Message::Field::Full/"METHODS">). In any case, some extensions of this Full field class is returned. It depends on which field is created what kind of class we get. » example: my $fast = $msg->head->get('subject'); my $full = Mail::Message::Field::Full->from($fast); my $full = $msg->head->get('subject')->study; # same my $full = $msg->head->study('subject'); # same my $full = $msg->get('subject'); # same =item $class-E<gt>B<new>(($line | $name, [$body], @attributes), %options) Creating a new field object the correct way is a lot of work, because there is so much freedom in the RFCs, but at the same time so many restrictions. Most fields are implemented, but if you have your own field (and do no want to contribute it to MailBox), then simply call new on your own package. You have the choice to instantiate the object as string or in prepared parts: =over 4 =item * B<new>(C<$line>, C<%options>) Pass a C<$line> as it could be found in a file: a (possibly folded) line which is terminated by a new-line. =item * B<new>(C<$name>, [C<$body>], C<@attributes>, C<%options>) A set of values which shape the line. =back The C<$name> is a wellformed header name (you may use L<wellformedName()|Mail::Message::Field/"Attributes">) to be sure about the casing. The C<$body> is a string, one object, or an ARRAY of objects. In case of objects, they must fit to the constructor of the field: the types which are accepted may differ. The optional ATTRIBUTE list contains L<Mail::Message::Field::Attribute|Mail::Message::Field::Attribute> objects. Finally, there are some OPTIONS. Improves base, see L<Mail::Message::Field/"Constructors"> -Option --Default charset undef encoding 'q' force false language undef =over 2 =item charset => $charset The body is specified in UTF-8, and must become 7-bits ascii to be transmited. Specify a C<$charset> to which the multi-byte utf8 is converted before it gets encoded. See L<encode()|Mail::Message::Field::Full/"Internals">, which does the job. =item encoding => 'q'|'Q'|'b'|'B' Non-ascii characters are encoded using Quoted-Printable ('q' or 'Q') or Base64 ('b' or 'B') encoding. =item force => BOOLEAN Enforce encoding in the specified charset, even when it is not needed because the body does not contain any non-ascii characters. =item language => $language The C<$language> used can be specified, however is rarely used my mail clients. =back » example: my $s = Mail::Message::Field::Full->new('Subject: Hello World'); my $s = Mail::Message::Field::Full->new('Subject', 'Hello World'); my @attrs = (Mail::Message::Field::Attribute->new(...), ...); my @options = (extra => 'the color blue'); my $t = Mail::Message::Field::Full->new(To => \@addrs, @attrs, @options); =back =head2 Attributes Extends L<"Attributes" in Mail::Message::Field|Mail::Message::Field/"Attributes">. =over 4 =item $obj-E<gt>B<Name>() Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<body>() Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<folded>() Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<foldedBody>( [$body] ) Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<name>() Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<unfoldedBody>( [$body, [$wrap]] ) Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<wellformedName>( [STRING] ) Inherited, see L<Mail::Message::Field/"Attributes"> =back =head2 The field Extends L<"The field" in Mail::Message::Field|Mail::Message::Field/"The field">. =over 4 =item $any-E<gt>B<isStructured>( [$name] ) Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<length>() Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<nrLines>() Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<print>( [$fh] ) Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<size>() Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<string>( [$wrap] ) Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<toDisclose>() Inherited, see L<Mail::Message::Field/"The field"> =back =head2 Access to the body =over 4 =item $obj-E<gt>B<decodedBody>(%options) Returns the unfolded body of the field, where encodings are resolved. The returned line will still contain comments and such. The C<%options> are passed to the decoder, see L<decode()|Mail::Message::Field::Full/"Internals">. BE WARNED: if the field is a structured field, the content may change syntax, because of encapsulated special characters. By default, the body is decoded as text, which results in a small difference within comments as well (read the RFC). =back =head2 Access to the content Extends L<"Access to the content" in Mail::Message::Field|Mail::Message::Field/"Access to the content">. =over 4 =item $obj-E<gt>B<addresses>() Inherited, see L<Mail::Message::Field/"Access to the content"> =item $obj-E<gt>B<attribute>( $name, [$value] ) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $obj-E<gt>B<attributes>() Inherited, see L<Mail::Message::Field/"Access to the content"> =item $obj-E<gt>B<beautify>() For structured header fields, this removes the original encoding of the field's body (the format as it was offered to L<parse()|Mail::Message::Field::Full/"Parsing">), therefore the next request for the field will have to re-produce the read data clean and nice. For unstructured bodies, this method doesn't do a thing. =item $obj-E<gt>B<comment>( [STRING] ) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $any-E<gt>B<createComment>(STRING, %options) Create a comment to become part in a field. Comments are automatically included within parenthesis. Matching pairs of parenthesis are permitted within the C<STRING>. When a non-matching parenthesis are used, it is only permitted with an escape (a backslash) in front of them. These backslashes will be added automatically if needed (don't worry!). Backslashes will stay, except at the end, where it will be doubled. The C<%options> are C<charset>, C<language>, and C<encoding> as always. The created comment is returned. =item $any-E<gt>B<createPhrase>(STRING, %options) A phrase is a text which plays a well defined role. This is the main difference with comments, which have do specified meaning. Some special characters in the phrase will cause it to be surrounded with double quotes: do not specify them yourself. The C<%options> are C<charset>, C<language>, and C<encoding>, as always. =item $any-E<gt>B<dateToTimestamp>(STRING) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $any-E<gt>B<stripCFWS>( [STRING] ) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $obj-E<gt>B<study>() Inherited, see L<Mail::Message::Field/"Access to the content"> =item $any-E<gt>B<toDate>( [$time] ) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $obj-E<gt>B<toInt>() Inherited, see L<Mail::Message::Field/"Access to the content"> =back =head2 Internals =over 4 =item $any-E<gt>B<decode>(STRING, %options) Decode field encoded C<STRING> to an utf8 string. The input C<STRING> is part of a header field, and as such, may contain encoded words in “C<< =?...?.?...?= >>” format defined by RFC2047. The C<STRING> may contain multiple encoded parts, maybe using different character sets. Be warned: you MUST first interpret the field into parts, like phrases and comments, and then decode each part separately, otherwise the decoded text may interfere with your markup characters. Be warned: language information, which is defined in RFC2231, is ignored. Encodings with unknown charsets are left untouched [requires v2.085, otherwise croaked]. Unknown characters within an charset are replaced by a “C<?>”. -Option --Default is_text true =over 2 =item is_text => BOOLEAN Encoding on text is slightly more complicated than encoding structured data, because it contains blanks. Visible blanks have to be ignored between two encoded words in the text, but not when an encoded word follows or precedes an unencoded word. Phrases and comments are texts. =back » example: print Mail::Message::Field::Full->decode('=?iso-8859-1?Q?J=F8rgen?='); # prints JE<0slash>rgen =item $obj-E<gt>B<encode>(STRING, %options) Encode the (possibly utf8 encoded) C<STRING> to a string which is acceptable to the RFC2047 definition of a header: only containing us-ascii characters. -Option --Default charset 'us-ascii' encoding 'q' force false language undef name undef =over 2 =item charset => STRING C<STRING> is an utf8 string which has to be translated into any byte-wise character set for transport, because MIME-headers can only contain ascii characters. =item encoding => 'q'|'Q'|'b'|'B' The character encoding to be used. With C<q> or C<Q>, quoted-printable encoding will be used. With C<b > or C<B >, base64 encoding will be taken. =item force => BOOLEAN Encode the string, even when it only contains us-ascii characters. By default, this is off because it decreases readibility of the produced header fields. =item language => STRING RFC2231 defines how to specify language encodings in encoded words. The C<STRING> is a strandard iso language name. =item name => STRING When the name of the field is given, the first encoded line will be shorter. =back =back =head2 Parsing You probably do not want to call these parsing methods yourself: use the standard constructors (L<new()|Mail::Message::Field::Full/"METHODS">) and it will be done for you. Extends L<"Parsing" in Mail::Message::Field|Mail::Message::Field/"Parsing">. =over 4 =item $obj-E<gt>B<consume>( $line | <$name,<$body|$objects>> ) Inherited, see L<Mail::Message::Field/"Parsing"> =item $any-E<gt>B<consumeComment>(STRING) Try to read a comment from the C<STRING>. When successful, the comment without encapsulating parenthesis is returned, together with the rest of the string. =item $obj-E<gt>B<consumeDotAtom>(STRING) Returns three elemens: the atom-text, the rest string, and the concatenated comments. Both atom and comments can be C<undef>. =item $any-E<gt>B<consumePhrase>(STRING) Take the C<STRING>, and try to strip-off a valid phrase. In the obsolete phrase syntax, any sequence of words is accepted as phrase (as long as certain special characters are not used). RFC2822 is stricter: only one word or a quoted string is allowed. As always, the obsolete syntax is accepted, and the new syntax is produced. This method returns two elements: the phrase (or C<undef>) followed by the resulting string. The phrase will be removed from the optional quotes. Be warned that “C<"">” will return an empty, valid phrase. » example: my ($phrase, $rest) = $field->consumePhrase( q["hi!" <sales@example.com>] ); =item $obj-E<gt>B<defaultWrapLength>( [$length] ) Inherited, see L<Mail::Message::Field/"Parsing"> =item $any-E<gt>B<fold>( $name, $body, [$maxchars] ) Inherited, see L<Mail::Message::Field/"Parsing"> =item $obj-E<gt>B<parse>(STRING) Get the detailed information from the C<STRING>, and store the data found in the field object. The accepted input is very field type dependent. Unstructured fields do no parsing whatsoever. =item $obj-E<gt>B<produceBody>() Produce the text for the field, based on the information stored within the field object. Usually, you wish the exact same line as was found in the input source of a message. But when you have created a field yourself, it should get formatted. You may call L<beautify()|Mail::Message::Field::Full/"Access to the content"> on a preformatted field to enforce a call to this method when the field is needed later. =item $obj-E<gt>B<setWrapLength>( [$length] ) Inherited, see L<Mail::Message::Field/"Parsing"> =item $obj-E<gt>B<stringifyData>(STRING|ARRAY|$objects) Inherited, see L<Mail::Message::Field/"Parsing"> =item $obj-E<gt>B<unfold>(STRING) Inherited, see L<Mail::Message::Field/"Parsing"> =back =head2 Error handling Extends L<"Error handling" in Mail::Message::Field|Mail::Message::Field/"Error handling">. =over 4 =item $obj-E<gt>B<AUTOLOAD>() Inherited, see L<Mail::Reporter/"Error handling"> =item $obj-E<gt>B<notImplemented>() Inherited, see L<Mail::Reporter/"Error handling"> =back =head2 Cleanup Extends L<"Cleanup" in Mail::Message::Field|Mail::Message::Field/"Cleanup">. =over 4 =item $obj-E<gt>B<DESTROY>() Inherited, see L<Mail::Reporter/"Cleanup"> =back =head1 DETAILS Extends L<"DETAILS" in Mail::Message::Field|Mail::Message::Field/"DETAILS">. =head1 DIAGNOSTICS =over 4 =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =item Warning: field content is not numerical: $content The numeric value of a field is requested (for instance the C<Lines> or C<Content-Length> fields should be numerical), however the data contains weird characters. Cast by C<toInt()> =item Error: field name too long (max $count), in '$name'. It is not specified in the RFCs how long a field name can be, but at least it should be a few characters shorter than the line wrap. Cast by C<fold()> =item Warning: illegal character in charset '$name'. The field is created with an utf8 string which only contains data from the specified character set. However, that character set can never be a valid name because it contains characters which are not permitted. Cast by C<encode()> =item Warning: illegal character in field name $name. A new field is being created which does contain characters not permitted by the RFCs. Using this field in messages may break other e-mail clients or transfer agents, and therefore mutulate or extinguish your message. Cast by C<consume()> =item Warning: illegal character in language '$name'. The field is created with data which is specified to be in a certain language, however, the name of the language cannot be valid: it contains characters which are not permitted by the RFCs. Cast by C<encode()> =item Warning: illegal encoding '$name', using 'q'. The RFCs only permit base64 (C<b > or C<B >) or quoted-printable (C<q> or C<Q>) encoding. Other than these four options are illegal. Cast by C<encode()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. ���������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Field/Date.pm����������������������������������������������������0000644�0001750�0000144�00000005212�15166136117�021705� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::Field::Date;{ our $VERSION = '4.05'; } use parent 'Mail::Message::Field::Structured'; use warnings; use strict; use Log::Report 'mail-message', import => [ qw/__x error/ ]; use POSIX qw/mktime tzset/; #-------------------- my $dayname = qr/Mon|Tue|Wed|Thu|Fri|Sat|Sun/; my @months = qw/Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec/; my %monthnr; { my $i; $monthnr{$_} = ++$i for @months } my %tz = qw/ EDT -0400 EST -0500 CDT -0500 CST -0600 MDT -0600 MST -0700 PDT -0700 PST -0800 UT +0000 GMT +0000/; sub parse($) { my ($self, $string) = @_; my ($dn, $d, $mon, $y, $h, $min, $s, $z) = $string =~ m/ ^ \s* (?: ($dayname) \s* \, \s* )? # dayname (optional) ( 0?[1-9] | [12][0-9] | 3[01] ) \s+ # day ( [A-Z][a-z][a-z]|[0-9][0-9] ) \s+ # month ( (?: 19 | 20 | ) [0-9][0-9] ) \s+ # year ( [0-1]?[0-9] | 2[0-3] ) \s* # hour [:.] ( [0-5][0-9] ) \s* # minute (?: [:.] ( [0-5][0-9] ) )? \s* # second (optional) ( [+-][0-9]{4} | [A-Z]+ )? # zone # optionally followed by trash /x or return undef; $dn //= ''; $dn =~ s/\s+//g; $mon = $months[$mon-1] if $mon =~ /[0-9]+/; # Broken mail clients $y += 2000 if $y < 50; $y += 1900 if $y < 100; $z ||= '-0000'; $z = $tz{$z} || '-0000' if $z =~ m/[A-Z]/; $self->{MMFD_date} = sprintf "%s%02d %s %04d %02d:%02d:%02d %s", (length $dn ? "$dn, " : ''), $d, $mon, $y, $h, $min, $s // 0, $z; $self; } sub produceBody() { $_[0]->{MMFD_date} } #-------------------- sub addAttribute($;@) { my $self = shift; error __x"no attributes for date fields."; } sub date() { $_[0]->{MMFD_date} } sub time() { my $date = shift->date or return; my ($d, $mon, $y, $h, $min, $s, $z) = $date =~ m/ ^ (?:\w\w\w\,\s+)? (\d\d)\s+(\w+)\s+(\d\d\d\d) \s+ (\d\d)\:(\d\d)\:(\d\d) \s+ ([+-]\d\d\d\d)? \s* $ /x; my $oldtz = $ENV{TZ}; $ENV{TZ} = 'UTC'; tzset; my $timestamp = mktime $s, $min, $h, $d, $monthnr{$mon}-1, $y-1900; if(defined $oldtz) { $ENV{TZ} = $oldtz } else { delete $ENV{TZ} } tzset; $timestamp += ($1 eq '-' ? 1 : -1) * ($2*3600 + $3*60) if $z =~ m/^([+-])(\d\d)(\d\d)$/; $timestamp; } #-------------------- 1; ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Field/AuthResults.pm���������������������������������������������0000644�0001750�0000144�00000011212�15166136116�023307� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::Field::AuthResults;{ our $VERSION = '4.05'; } use parent 'Mail::Message::Field::Structured'; use warnings; use strict; use Log::Report 'mail-message', import => [ qw/__x error/ ]; use URI; #-------------------- #-------------------- sub init($) { my ($self, $args) = @_; $self->{MMFA_server} = delete $args->{server}; $self->{MMFA_version} = delete $args->{version}; $self->{MMFA_results} = []; $self->addResult($_) for @{delete $args->{results} || []}; $self->SUPER::init($args); } sub parse($) { my ($self, $string) = @_; $string =~ s/\r?\n/ /g; (undef, $string) = $self->consumeComment($string); $self->{MMFA_server} = $string =~ s/^\s*([.\w-]*\w)// ? $1 : 'unknown'; (undef, $string) = $self->consumeComment($string); $self->{MMFA_version} = $string =~ s/^\s*([0-9]+)// ? $1 : 1; (undef, $string) = $self->consumeComment($string); $string =~ s/^.*?\;/;/; # remove accidents my @results; while( $string =~ s/^\s*\;// ) { (undef, $string) = $self->consumeComment($string); if($string =~ s/^\s*none//) { (undef, $string) = $self->consumeComment($string); next; } my %result; push @results, \%result; $string =~ s/^\s*([\w-]*\w)// or next; $result{method} = $1; (undef, $string) = $self->consumeComment($string); if($string =~ s!^\s*/!!) { (undef, $string) = $self->consumeComment($string); $result{method_version} = $1 if $string =~ s/^\s*([0-9]+)//; } (undef, $string) = $self->consumeComment($string); if($string =~ s/^\s*\=//) { (undef, $string) = $self->consumeComment($string); $result{result} = $1 if $string =~ s/^\s*(\w+)//; } (my $comment, $string) = $self->consumeComment($string); if($comment) { $result{comment} = $comment; (undef, $string) = $self->consumeComment($string); } if($string =~ s/\s*reason//) { (undef, $string) = $self->consumeComment($string); if($string =~ s/\s*\=//) { (undef, $string) = $self->consumeComment($string); $result{reason} = $1 if $string =~ s/^\"([^"]*)\"// || $string =~ s/^\'([^']*)\'// || $string =~ s/^(\w+)//; } } while($string =~ /\S/) { (undef, $string) = $self->consumeComment($string); last if $string =~ /^\s*\;/; my $ptype = $string =~ s/^\s*([\w-]+)// ? $1 : last; (undef, $string) = $self->consumeComment($string); my ($property, $value); if($string =~ s/^\s*\.//) { (undef, $string) = $self->consumeComment($string); $property = $string =~ s/^\s*([\w-]+)// ? $1 : last; (undef, $string) = $self->consumeComment($string); if($string =~ s/^\s*\=//) { (undef, $string) = $self->consumeComment($string); $string =~ s/^\s+//; $string =~ s/^\"([^"]*)\"// || $string =~ s/^\'([^']*)\'// || $string =~ s/^([\w@.-]+)// or last; $value = $1; } } if(defined $value) { $result{"$ptype.$property"} = $value; } else { $string =~ s/^.*?\;/;/g; # recover from parser problem } } } $self->addResult($_) for @results; $self; } sub produceBody() { my $self = shift; my $source = $self->server; my $version = $self->version; $source .= " $version" if $version!=1; my @results; foreach my $r ($self->results) { my $method = $r->{method}; $method .= "/$r->{method_version}" if $r->{method_version} != 1; my $result = "$method=$r->{result}"; $result .= ' ' . $self->createComment($r->{comment}) if defined $r->{comment}; if(my $reason = $r->{reason}) { $reason =~ s/"/\\"/g; $result .= qq{ reason="$reason"}; } foreach my $prop (sort keys %$r) { index($prop, '.') > -1 or next; my $value = $r->{$prop}; $value =~ s/"/\\"/g; $result .= qq{ $prop="$value"}; } push @results, $result; } push @results, 'none' unless @results; join '; ', $source, @results; } #-------------------- sub addAttribute($;@) { my $self = shift; error __x"no attributes for Authentication-Results."; $self; } sub server() { $_[0]->{MMFA_server} } sub version() { $_[0]->{MMFA_version} } sub results() { @{ $_[0]->{MMFA_results}} } sub addResult($) { my $self = shift; my $r = @_==1 ? shift : {@_}; $r->{method} && $r->{result} or return (); $r->{method_version} ||= 1; push @{$self->{MMFA_results}}, $r; delete $self->{MMFF_body}; $r; } #-------------------- 1; ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Field/URIs.pod���������������������������������������������������0000644�0001750�0000144�00000027060�15166136117�022025� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Field::URIs - message header field with uris =head1 INHERITANCE Mail::Message::Field::URIs is a Mail::Message::Field::Structured is a Mail::Message::Field::Full is a Mail::Message::Field is a Mail::Reporter =head1 SYNOPSIS my $f = Mail::Message::Field->new('List-Post' => 'http://x.org/'); my $g = Mail::Message::Field->new('List-Post'); $g->addURI('http://x.org'); my $uri = URI->new(...); $g->addURI($uri); my @uris = $g->URIs; =head1 DESCRIPTION More recent RFCs prefer uri field notation over the various differentiated syntaxes. Especially the mailing-list RFCs use these fields all the time. This class can maintain these fields. Extends L<"DESCRIPTION" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"DESCRIPTION">. =head1 OVERLOADED Extends L<"OVERLOADED" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"OVERLOADED">. =over 4 =item overload: B<""> stringification Inherited, see L<Mail::Message::Field::Full/"OVERLOADED"> =item overload: B<'""'> stringification Inherited, see L<Mail::Message::Field/"OVERLOADED"> =item overload: B<'0+'> numification Inherited, see L<Mail::Message::Field/"OVERLOADED"> =item overload: B<'<=>'> numeric comparison Inherited, see L<Mail::Message::Field/"OVERLOADED"> =item overload: B<bool> boolean Inherited, see L<Mail::Message::Field/"OVERLOADED"> =item overload: B<cmp> string comparison Inherited, see L<Mail::Message::Field/"OVERLOADED"> =back =head1 METHODS Extends L<"METHODS" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"Constructors">. =over 4 =item $obj-E<gt>B<clone>() Inherited, see L<Mail::Message::Field/"Constructors"> =item $class-E<gt>B<from>($field, %options) Inherited, see L<Mail::Message::Field::Full/"Constructors"> =item $class-E<gt>B<new>($data) Inherited, see L<Mail::Message::Field::Structured/"METHODS"> -Option --Defined in --Default attributes Mail::Message::Field::Structured <ignored> charset Mail::Message::Field::Full undef datum Mail::Message::Field::Structured undef encoding Mail::Message::Field::Full 'q' force Mail::Message::Field::Full false language Mail::Message::Field::Full undef =over 2 =item attributes => \@attributes|\%attributes =item charset => $charset =item datum => $date =item encoding => 'q'|'Q'|'b'|'B' =item force => BOOLEAN =item language => $language =back » example: my $mmfu = 'Mail::Message::Field::URIs; my $f = $mmfu->new('List-Post' => 'mailto:x@y.com'); my $f = $mmfu->new('List-Post' => '<mailto:x@y.com>'); my $f = $mmfu->new('List-Post: <mailto:x@y.com>'); my $f = $mmfu->new('List-Post' => [ $uri, 'http://x.org' ]); =back =head2 Attributes Extends L<"Attributes" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"Attributes">. =over 4 =item $obj-E<gt>B<Name>() Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<body>() Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<folded>() Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<foldedBody>( [$body] ) Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<name>() Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<unfoldedBody>( [$body, [$wrap]] ) Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<wellformedName>( [STRING] ) Inherited, see L<Mail::Message::Field/"Attributes"> =back =head2 The field Extends L<"The field" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"The field">. =over 4 =item $any-E<gt>B<isStructured>( [$name] ) Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<length>() Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<nrLines>() Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<print>( [$fh] ) Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<size>() Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<string>( [$wrap] ) Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<toDisclose>() Inherited, see L<Mail::Message::Field/"The field"> =back =head2 Access to the body Extends L<"Access to the body" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"Access to the body">. =over 4 =item $obj-E<gt>B<decodedBody>(%options) Inherited, see L<Mail::Message::Field::Full/"Access to the body"> =back =head2 Access to the content Extends L<"Access to the content" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"Access to the content">. =over 4 =item $obj-E<gt>B<URIs>() Returns a list with all URIs defined by the field. Mind the lower-case 's' at the enc of the name. » example: my @uris = $field->URIs; =item $obj-E<gt>B<addAttribute>(...) Attributes are not supported for URI fields. =item $obj-E<gt>B<addURI>($uri) Add an C<$uri> to the field. The C<$uri> can be specified as URI object or as string which will be turned into an C<$uri> object. The added C<$uri> is returned. » example: adding an URI to an URI field my $f = Mail::Message::Field::URI->new('List-Post'); my $uri = URI->new("http://x.org"); $f->addURI($uri); $f->addURI("http://y.org"); # simpler $f->addURI("//y.org", "http"); =item $obj-E<gt>B<addresses>() Inherited, see L<Mail::Message::Field/"Access to the content"> =item $obj-E<gt>B<attrPairs>() Inherited, see L<Mail::Message::Field::Structured/"Access to the content"> =item $obj-E<gt>B<attribute>( $object|<STRING, %options>|<$name,$value,%options> ) Inherited, see L<Mail::Message::Field::Structured/"Access to the content"> =item $obj-E<gt>B<attributes>() Inherited, see L<Mail::Message::Field::Structured/"Access to the content"> =item $obj-E<gt>B<beautify>() Inherited, see L<Mail::Message::Field::Full/"Access to the content"> =item $obj-E<gt>B<comment>( [STRING] ) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $any-E<gt>B<createComment>(STRING, %options) Inherited, see L<Mail::Message::Field::Full/"Access to the content"> =item $any-E<gt>B<createPhrase>(STRING, %options) Inherited, see L<Mail::Message::Field::Full/"Access to the content"> =item $any-E<gt>B<dateToTimestamp>(STRING) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $any-E<gt>B<stripCFWS>( [STRING] ) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $obj-E<gt>B<study>() Inherited, see L<Mail::Message::Field/"Access to the content"> =item $any-E<gt>B<toDate>( [$time] ) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $obj-E<gt>B<toInt>() Inherited, see L<Mail::Message::Field/"Access to the content"> =back =head2 Internals Extends L<"Internals" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"Internals">. =over 4 =item $any-E<gt>B<decode>(STRING, %options) Inherited, see L<Mail::Message::Field::Full/"Internals"> =item $obj-E<gt>B<encode>(STRING, %options) Inherited, see L<Mail::Message::Field::Full/"Internals"> =back =head2 Parsing Extends L<"Parsing" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"Parsing">. =over 4 =item $obj-E<gt>B<consume>( $line | <$name,<$body|$objects>> ) Inherited, see L<Mail::Message::Field/"Parsing"> =item $any-E<gt>B<consumeComment>(STRING) Inherited, see L<Mail::Message::Field::Full/"Parsing"> =item $obj-E<gt>B<consumeDotAtom>(STRING) Inherited, see L<Mail::Message::Field::Full/"Parsing"> =item $any-E<gt>B<consumePhrase>(STRING) Inherited, see L<Mail::Message::Field::Full/"Parsing"> =item $obj-E<gt>B<datum>( [$value] ) Inherited, see L<Mail::Message::Field::Structured/"Parsing"> =item $obj-E<gt>B<defaultWrapLength>( [$length] ) Inherited, see L<Mail::Message::Field/"Parsing"> =item $any-E<gt>B<fold>( $name, $body, [$maxchars] ) Inherited, see L<Mail::Message::Field/"Parsing"> =item $obj-E<gt>B<parse>(STRING) Inherited, see L<Mail::Message::Field::Full/"Parsing"> =item $obj-E<gt>B<produceBody>() Inherited, see L<Mail::Message::Field::Full/"Parsing"> =item $obj-E<gt>B<setWrapLength>( [$length] ) Inherited, see L<Mail::Message::Field/"Parsing"> =item $obj-E<gt>B<stringifyData>(STRING|ARRAY|$objects) Inherited, see L<Mail::Message::Field/"Parsing"> =item $obj-E<gt>B<unfold>(STRING) Inherited, see L<Mail::Message::Field/"Parsing"> =back =head2 Error handling Extends L<"Error handling" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"Error handling">. =over 4 =item $obj-E<gt>B<AUTOLOAD>() Inherited, see L<Mail::Reporter/"Error handling"> =item $obj-E<gt>B<notImplemented>() Inherited, see L<Mail::Reporter/"Error handling"> =back =head2 Cleanup Extends L<"Cleanup" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"Cleanup">. =over 4 =item $obj-E<gt>B<DESTROY>() Inherited, see L<Mail::Reporter/"Cleanup"> =back =head1 DETAILS Extends L<"DETAILS" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"DETAILS">. =head1 DIAGNOSTICS =over 4 =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =item Warning: field content is not numerical: $content The numeric value of a field is requested (for instance the C<Lines> or C<Content-Length> fields should be numerical), however the data contains weird characters. Cast by C<toInt()> =item Error: field name too long (max $count), in '$name'. It is not specified in the RFCs how long a field name can be, but at least it should be a few characters shorter than the line wrap. Cast by C<fold()> =item Warning: illegal character in charset '$name'. The field is created with an utf8 string which only contains data from the specified character set. However, that character set can never be a valid name because it contains characters which are not permitted. Cast by C<encode()> =item Warning: illegal character in field name $name. A new field is being created which does contain characters not permitted by the RFCs. Using this field in messages may break other e-mail clients or transfer agents, and therefore mutulate or extinguish your message. Cast by C<consume()> =item Warning: illegal character in language '$name'. The field is created with data which is specified to be in a certain language, however, the name of the language cannot be valid: it contains characters which are not permitted by the RFCs. Cast by C<encode()> =item Warning: illegal encoding '$name', using 'q'. The RFCs only permit base64 (C<b > or C<B >) or quoted-printable (C<q> or C<Q>) encoding. Other than these four options are illegal. Cast by C<encode()> =item Error: no attributes for URI fields. Is is not possible to add attributes to URI fields: it is not permitted by the RFCs. Cast by C<addAttribute()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Field/URIs.pm����������������������������������������������������0000644�0001750�0000144�00000003356�15166136116�021660� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::Field::URIs;{ our $VERSION = '4.05'; } use parent 'Mail::Message::Field::Structured'; use warnings; use strict; use Log::Report 'mail-message', import => [ qw/__x error/ ]; use URI (); use Scalar::Util qw/blessed/; #-------------------- #-------------------- sub init($) { my ($self, $args) = @_; my ($body, @body); if($body = delete $args->{body}) { @body = ref $body eq 'ARRAY' ? @$body : ($body); @body or return (); } $self->{MMFU_uris} = []; if(@body > 1 || blessed $body[0]) { $self->addURI($_) for @body; } elsif(defined $body) { $body = "<$body>\n" unless index($body, '<') >= 0; $args->{body} = $body; } $self->SUPER::init($args); } sub parse($) { my ($self, $string) = @_; my @raw = $string =~ m/\<([^>]+)\>/g; # simply ignore all but <> $self->addURI($_) for @raw; $self; } sub produceBody() { my @uris = sort map $_->as_string, $_[0]->URIs; local $" = '>, <'; @uris ? "<@uris>" : undef; } #-------------------- sub addURI(@) { my $self = shift; my $uri = blessed $_[0] ? shift : URI->new(@_); push @{$self->{MMFU_uris}}, $uri->canonical if defined $uri; delete $self->{MMFF_body}; $uri; } sub URIs() { @{ $_[0]->{MMFU_uris}} } sub addAttribute($;@) { my $self = shift; error __x"no attributes for URI fields."; } #-------------------- 1; ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Field/Flex.pm����������������������������������������������������0000644�0001750�0000144�00000004231�15166136117�021726� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::Field::Flex;{ our $VERSION = '4.05'; } use parent 'Mail::Message::Field'; use strict; use warnings; use Log::Report 'mail-message', import => [ qw// ]; #-------------------- sub new($;$$@) { my $class = shift; my $args = @_ <= 2 || ! ref $_[-1] ? {} : ref $_[-1] eq 'ARRAY' ? { @{pop @_} } : pop @_; my ($name, $body) = $class->consume(@_==1 ? (shift) : (shift, shift)); defined $body or return (); # Attributes preferably stored in array to protect order. my $attr = $args->{attributes}; $attr = [ %$attr ] if defined $attr && ref $attr eq 'HASH'; push @$attr, @_; $class->SUPER::new(%$args, name => $name, body => $body, attributes => $attr); } sub init($) { my ($self, $args) = @_; @$self{ qw/MMFF_name MMFF_body/ } = @$args{ qw/name body/ }; $self->comment($args->{comment}) if exists $args->{comment}; my $attr = $args->{attributes}; $self->attribute(shift @$attr, shift @$attr) while @$attr; $self; } sub clone() { my $self = shift; (ref $self)->new($self->Name, $self->body); } sub length() { my $self = shift; length($self->{MMFF_name}) + 1 + length($self->{MMFF_body}); } sub name() { lc($_[0]->{MMFF_name}) } sub Name() { $_[0]->{MMFF_name} } sub folded(;$) { my $self = shift; wantarray or return $self->{MMFF_name}.':'.$self->{MMFF_body}; my @lines = $self->foldedBody; my $first = $self->{MMFF_name}. ':'. shift @lines; ($first, @lines); } sub unfoldedBody($;@) { my $self = shift; $self->{MMFF_body} = $self->fold($self->{MMFF_name}, @_) if @_; $self->unfold($self->{MMFF_body}); } sub foldedBody($) { my ($self, $body) = @_; if(@_==2) { $self->{MMFF_body} = $body } else { $body = $self->{MMFF_body} } wantarray ? (split /^/, $body) : $body; } 1; �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Field/Flex.pod���������������������������������������������������0000644�0001750�0000144�00000020234�15166136117�022075� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Field::Flex - one line of a message header =head1 INHERITANCE Mail::Message::Field::Flex is a Mail::Message::Field is a Mail::Reporter =head1 SYNOPSIS =head1 DESCRIPTION This is the flexible implementation of a field: it can easily be extended because it stores its data in a hash and the constructor (C<new>) and initializer (C<init>) are split. However, you pay the price in performance. L<Mail::Message::Field::Fast|Mail::Message::Field::Fast> is faster (as the name predicts). Extends L<"DESCRIPTION" in Mail::Message::Field|Mail::Message::Field/"DESCRIPTION">. =head1 OVERLOADED Extends L<"OVERLOADED" in Mail::Message::Field|Mail::Message::Field/"OVERLOADED">. =over 4 =item overload: B<'""'> stringification Inherited, see L<Mail::Message::Field/"OVERLOADED"> =item overload: B<'0+'> numification Inherited, see L<Mail::Message::Field/"OVERLOADED"> =item overload: B<'<=>'> numeric comparison Inherited, see L<Mail::Message::Field/"OVERLOADED"> =item overload: B<bool> boolean Inherited, see L<Mail::Message::Field/"OVERLOADED"> =item overload: B<cmp> string comparison Inherited, see L<Mail::Message::Field/"OVERLOADED"> =back =head1 METHODS Extends L<"METHODS" in Mail::Message::Field|Mail::Message::Field/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Message::Field|Mail::Message::Field/"Constructors">. =over 4 =item $obj-E<gt>B<clone>() Inherited, see L<Mail::Message::Field/"Constructors"> =item $class-E<gt>B<new>($line | ($name, ($body|$object|\@objects), [@attributes], [\%options|\@options])) If you stick to this flexible class of header fields, you have a bit more facilities than with L<Mail::Message::Field::Fast|Mail::Message::Field::Fast>. Amongst it, you can specify options with the creation. Possible arguments: =over 4 =item * B<new> C<$line> Pass a C<$line> as it could be found in a file: a (possibly folded) line which is terminated by a new-line. =item * B<new> C<$name>, (C<$body>|C<$object>|\C<@objects>), [C<@attributes>], [\C<%options>|\C<@options>] A set of values which shape the line. =back To be able to distinguish the different parameters, you will have to specify the C<@options> as ARRAY of option PAIRS, or HASH of C<%options>. The C<@attributes> are a flat LIST of key-value PAIRS. The C<$body> is specified as one string, one C<$object>, or an ARRAY of C<@objects>. See L<Mail::Message::Field|Mail::Message::Field>. Improves base, see L<Mail::Message::Field/"Constructors"> -Option --Default attributes +[ ] comment undef =over 2 =item attributes => \@attributes|\%attributes An ARRAY with contains of key-value pairs representing C<@attributes>, or reference to a HASH containing these pairs. This is an alternative notation for specifying C<@attributes> directly as method arguments. =item comment => $text A pre-formatted list of attributes. =encoding utf8 =back =back =head2 Attributes Extends L<"Attributes" in Mail::Message::Field|Mail::Message::Field/"Attributes">. =over 4 =item $obj-E<gt>B<Name>() Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<body>() Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<folded>() Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<foldedBody>( [$body] ) Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<name>() Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<unfoldedBody>( [$body, [$wrap]] ) Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<wellformedName>( [STRING] ) Inherited, see L<Mail::Message::Field/"Attributes"> =back =head2 The field Extends L<"The field" in Mail::Message::Field|Mail::Message::Field/"The field">. =over 4 =item $any-E<gt>B<isStructured>( [$name] ) Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<length>() Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<nrLines>() Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<print>( [$fh] ) Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<size>() Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<string>( [$wrap] ) Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<toDisclose>() Inherited, see L<Mail::Message::Field/"The field"> =back =head2 Access to the content Extends L<"Access to the content" in Mail::Message::Field|Mail::Message::Field/"Access to the content">. =over 4 =item $obj-E<gt>B<addresses>() Inherited, see L<Mail::Message::Field/"Access to the content"> =item $obj-E<gt>B<attribute>( $name, [$value] ) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $obj-E<gt>B<attributes>() Inherited, see L<Mail::Message::Field/"Access to the content"> =item $obj-E<gt>B<comment>( [STRING] ) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $any-E<gt>B<dateToTimestamp>(STRING) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $any-E<gt>B<stripCFWS>( [STRING] ) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $obj-E<gt>B<study>() Inherited, see L<Mail::Message::Field/"Access to the content"> =item $any-E<gt>B<toDate>( [$time] ) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $obj-E<gt>B<toInt>() Inherited, see L<Mail::Message::Field/"Access to the content"> =back =head2 Parsing Extends L<"Parsing" in Mail::Message::Field|Mail::Message::Field/"Parsing">. =over 4 =item $obj-E<gt>B<consume>( $line | <$name,<$body|$objects>> ) Inherited, see L<Mail::Message::Field/"Parsing"> =item $obj-E<gt>B<defaultWrapLength>( [$length] ) Inherited, see L<Mail::Message::Field/"Parsing"> =item $any-E<gt>B<fold>( $name, $body, [$maxchars] ) Inherited, see L<Mail::Message::Field/"Parsing"> =item $obj-E<gt>B<setWrapLength>( [$length] ) Inherited, see L<Mail::Message::Field/"Parsing"> =item $obj-E<gt>B<stringifyData>(STRING|ARRAY|$objects) Inherited, see L<Mail::Message::Field/"Parsing"> =item $obj-E<gt>B<unfold>(STRING) Inherited, see L<Mail::Message::Field/"Parsing"> =back =head2 Error handling Extends L<"Error handling" in Mail::Message::Field|Mail::Message::Field/"Error handling">. =over 4 =item $obj-E<gt>B<AUTOLOAD>() Inherited, see L<Mail::Reporter/"Error handling"> =item $obj-E<gt>B<notImplemented>() Inherited, see L<Mail::Reporter/"Error handling"> =back =head2 Cleanup Extends L<"Cleanup" in Mail::Message::Field|Mail::Message::Field/"Cleanup">. =over 4 =item $obj-E<gt>B<DESTROY>() Inherited, see L<Mail::Reporter/"Cleanup"> =back =head1 DETAILS Extends L<"DETAILS" in Mail::Message::Field|Mail::Message::Field/"DETAILS">. =head1 DIAGNOSTICS =over 4 =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =item Warning: field content is not numerical: $content The numeric value of a field is requested (for instance the C<Lines> or C<Content-Length> fields should be numerical), however the data contains weird characters. Cast by C<toInt()> =item Error: field name too long (max $count), in '$name'. It is not specified in the RFCs how long a field name can be, but at least it should be a few characters shorter than the line wrap. Cast by C<fold()> =item Warning: illegal character in field name $name. A new field is being created which does contain characters not permitted by the RFCs. Using this field in messages may break other e-mail clients or transfer agents, and therefore mutulate or extinguish your message. Cast by C<consume()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Field/Addresses.pm�����������������������������������������������0000644�0001750�0000144�00000013250�15166136117�022746� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::Field::Addresses;{ our $VERSION = '4.05'; } use parent 'Mail::Message::Field::Structured'; use strict; use warnings; use Log::Report 'mail-message', import => [ qw/__x error info warning/ ]; use Mail::Message::Field::AddrGroup (); use Mail::Message::Field::Address (); use List::Util qw/first/; use Scalar::Util qw/blessed/; #-------------------- # what is permitted for each field. my $address_list = +{ groups => 1, multi => 1 }; my $mailbox_list = +{ multi => 1 }; my $mailbox = +{ }; my %accepted = ( # defaults to $address_list from => $mailbox_list, sender => $mailbox, ); sub init($) { my ($self, $args) = @_; $self->{MMFF_groups} = []; my $def = lc $args->{name} =~ s/^resent\-//r; $self->{MMFF_defaults} = $accepted{$def} || $address_list; my ($body, @body); if($body = $args->{body}) { @body = ref $body eq 'ARRAY' ? @$body : ($body); @body or return (); } if(@body > 1 || ref $body[0]) { $self->addAddress($_) for @body; delete $args->{body}; } $self->SUPER::init($args); } #-------------------- sub addAddress(@) { my $self = shift; my $email = blessed $_[0] ? shift : undef; my %args = @_; my $group = delete $args{group} // ''; $email //= Mail::Message::Field::Address->new(%args); my $set = $self->group($group) // $self->addGroup(name => $group); $set->addAddress($email); $email; } sub addGroup(@) { my $self = shift; my $group = @_ == 1 ? shift : Mail::Message::Field::AddrGroup->new(@_); push @{$self->{MMFF_groups}}, $group; $group; } sub group($) { my ($self, $name) = @_; $name //= ''; first { lc($_->name) eq lc($name) } $self->groups; } sub groups() { @{ $_[0]->{MMFF_groups}} } sub groupNames() { map $_->name, $_[0]->groups } sub addresses() { map $_->addresses, $_[0]->groups } sub addAttribute($;@) { my $self = shift; error __x"no attributes for address fields."; } #-------------------- sub parse($) { my ($self, $string) = @_; my ($group, $email) = ('', undef); $string =~ s/\s+/ /gs; ADDRESS: while(1) { (my $comment, $string) = $self->consumeComment($string); my $start_length = length $string; if($string =~ s/^\s*\;//s ) { $group = ''; next ADDRESS } # end group if($string =~ s/^\s*\,//s ) { next ADDRESS} # end address (my $email, $string) = $self->consumeAddress($string); if(defined $email) { # Pattern starts with e-mail address ($comment, $string) = $self->consumeComment($string); $email->comment($comment) if defined $comment; } else { # Pattern not plain address my $real_phrase = $string =~ m/^\s*\"/; my @words; # In rfc2822 obs-phrase, we can have more than one word with # comments inbetween. WORD: while(1) { (my $word, $string) = $self->consumePhrase($string); defined $word or last; push @words, $word if length $word; ($comment, $string) = $self->consumeComment($string); if($string =~ s/^\s*\://s ) { $group = $word; # even empty groups must appear $self->addGroup(name => $group) unless $self->group($group); next ADDRESS; } } my $phrase = @words ? join ' ', @words : undef; my $angle; if($string =~ s/^\s*\<([^>]*)\>//s) { $angle = $1 } elsif($real_phrase) { warning __x"ignoring addressless phrase '{phrase}'.", phrase => $1 if $string =~ s/^\s*\"(.*?)\r?\n//; next ADDRESS; } elsif(defined $phrase) { ($angle = $phrase) =~ s/\s+/./g; undef $phrase; } ($comment, $string) = $self->consumeComment($string); # remove obsoleted route info. defined $angle or return 1; $angle =~ s/^\@.*?\://; ($email, $angle) = $self->consumeAddress($angle, phrase => $phrase, comment => $comment); } $self->addAddress($email, group => $group) if defined $email; return 1 if $string =~ m/^\s*$/s; # Do not get stuck on illegal characters last if $start_length == length $string; } warning __x"illegal part in address field {name}: {part}.", name => $self->Name, part => $string; 0; } sub produceBody() { my $self = shift; my @groups = sort { $a->name cmp $b->name } $self->groups; @groups or return ''; @groups > 1 or return $groups[0]->string; my $plain = $groups[0]->name eq '' && $groups[0]->addresses ? (shift @groups)->string.',' : ''; join ' ', $plain, (map $_->string, @groups); } sub consumeAddress($@) { my ($self, $string, @options) = @_; my ($local, $shorter, $loccomment); if($string =~ s/^\s*"((?:\\.|[^"])*)"\s*\@/@/) { # local part is quoted-string rfc2822 ($local, $shorter) = ($1, $string); $local =~ s/\\"/"/g; } else { ($local, $shorter, $loccomment) = $self->consumeDotAtom($string); $local =~ s/\s//g if defined $local; } defined $local && $shorter =~ s/^\s*\@// or return (undef, $string); (my $domain, $shorter, my $domcomment) = $self->consumeDomain($shorter); defined $domain or return (undef, $string); # loccomment and domcomment ignored my $email = Mail::Message::Field::Address->new(username => $local, domain => $domain, @options); ($email, $shorter); } sub consumeDomain($) { my ($self, $string) = @_; return ($self->stripCFWS($1), $string) if $string =~ s/\s*(\[(?:[^[]\\]*|\\.)*\])//; my ($atom, $rest, $comment) = $self->consumeDotAtom($string); $atom =~ s/\s//g if defined $atom; ($atom, $rest, $comment); } #-------------------- 1; ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Field/DKIM.pod���������������������������������������������������0000644�0001750�0000144�00000031075�15166136117�021730� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Field::DKIM - message header field for dkim signatures =head1 INHERITANCE Mail::Message::Field::DKIM is a Mail::Message::Field::Structured is a Mail::Message::Field::Full is a Mail::Message::Field is a Mail::Reporter =head1 SYNOPSIS my $f = Mail::Message::Field->new('DKIM-Signature' => '...'); my $g = Mail::Message::Field->new('DKIM-Signature'); $g->add... =head1 DESCRIPTION Decode the information contained in a DKIM header. You can also construct DKIM-Signature headers this way. However, verification and signing is not yet implemented. This implementation is based on RFC6376. Extends L<"DESCRIPTION" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"DESCRIPTION">. =head1 OVERLOADED Extends L<"OVERLOADED" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"OVERLOADED">. =over 4 =item overload: B<""> stringification Inherited, see L<Mail::Message::Field::Full/"OVERLOADED"> =item overload: B<'""'> stringification Inherited, see L<Mail::Message::Field/"OVERLOADED"> =item overload: B<'0+'> numification Inherited, see L<Mail::Message::Field/"OVERLOADED"> =item overload: B<'<=>'> numeric comparison Inherited, see L<Mail::Message::Field/"OVERLOADED"> =item overload: B<bool> boolean Inherited, see L<Mail::Message::Field/"OVERLOADED"> =item overload: B<cmp> string comparison Inherited, see L<Mail::Message::Field/"OVERLOADED"> =back =head1 METHODS Extends L<"METHODS" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"Constructors">. =over 4 =item $obj-E<gt>B<clone>() Inherited, see L<Mail::Message::Field/"Constructors"> =item $class-E<gt>B<from>($field, %options) Inherited, see L<Mail::Message::Field::Full/"Constructors"> =item $class-E<gt>B<new>($data) Inherited, see L<Mail::Message::Field::Structured/"METHODS"> -Option --Defined in --Default attributes Mail::Message::Field::Structured <ignored> charset Mail::Message::Field::Full undef datum Mail::Message::Field::Structured undef encoding Mail::Message::Field::Full 'q' force Mail::Message::Field::Full false language Mail::Message::Field::Full undef =over 2 =item attributes => \@attributes|\%attributes =item charset => $charset =item datum => $date =item encoding => 'q'|'Q'|'b'|'B' =item force => BOOLEAN =item language => $language =back =back =head2 Attributes Extends L<"Attributes" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"Attributes">. =over 4 =item $obj-E<gt>B<Name>() Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<body>() Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<folded>() Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<foldedBody>( [$body] ) Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<name>() Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<unfoldedBody>( [$body, [$wrap]] ) Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<wellformedName>( [STRING] ) Inherited, see L<Mail::Message::Field/"Attributes"> =back =head2 The field Extends L<"The field" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"The field">. =over 4 =item $any-E<gt>B<isStructured>( [$name] ) Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<length>() Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<nrLines>() Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<print>( [$fh] ) Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<size>() Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<string>( [$wrap] ) Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<toDisclose>() Inherited, see L<Mail::Message::Field/"The field"> =back =head2 Access to the body Extends L<"Access to the body" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"Access to the body">. =over 4 =item $obj-E<gt>B<decodedBody>(%options) Inherited, see L<Mail::Message::Field::Full/"Access to the body"> =back =head2 Access to the content Extends L<"Access to the content" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"Access to the content">. =over 4 =item $obj-E<gt>B<addAttribute>(...) Attributes are not supported here. =item $obj-E<gt>B<addTag>($name, $value|@values) Add a tag to the set. When the tag already exists, it is replaced. Names are (converted to) lower-case. When multiple values are given, they will be concatenated with a blank (and may get folded there later) =item $obj-E<gt>B<addresses>() Inherited, see L<Mail::Message::Field/"Access to the content"> =item $obj-E<gt>B<attrPairs>() Inherited, see L<Mail::Message::Field::Structured/"Access to the content"> =item $obj-E<gt>B<attribute>( $object|<STRING, %options>|<$name,$value,%options> ) Inherited, see L<Mail::Message::Field::Structured/"Access to the content"> =item $obj-E<gt>B<attributes>() Inherited, see L<Mail::Message::Field::Structured/"Access to the content"> =item $obj-E<gt>B<beautify>() Inherited, see L<Mail::Message::Field::Full/"Access to the content"> =item $obj-E<gt>B<comment>( [STRING] ) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $any-E<gt>B<createComment>(STRING, %options) Inherited, see L<Mail::Message::Field::Full/"Access to the content"> =item $any-E<gt>B<createPhrase>(STRING, %options) Inherited, see L<Mail::Message::Field::Full/"Access to the content"> =item $any-E<gt>B<dateToTimestamp>(STRING) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $any-E<gt>B<stripCFWS>( [STRING] ) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $obj-E<gt>B<study>() Inherited, see L<Mail::Message::Field/"Access to the content"> =item $obj-E<gt>B<tag>($name) Returns the value for the named tag. =item $any-E<gt>B<toDate>( [$time] ) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $obj-E<gt>B<toInt>() Inherited, see L<Mail::Message::Field/"Access to the content"> =back =head3 DKIM-Signature tags The tag methods return the tag-value content without any validation or modification. For many situations, the actual content does not need (expensive) validation and interpretation. =over 4 =item $obj-E<gt>B<tagAgentID>() The Agent or User Identifier (AUID). Defaults to C<@$domain> =item $obj-E<gt>B<tagAlgorithm>() Signature algorithm. Should be rsa-sha(1|256): check before use. Required. =item $obj-E<gt>B<tagBodyLength>() The number of octets which where used to calculate the hash. By default, the whole body was used. =item $obj-E<gt>B<tagC14N>() The canonicalization method used. Defaults to 'simple/simple'. =item $obj-E<gt>B<tagDomain>() The sub-domain (SDID) which claims responsibility for this signature. Required. =item $obj-E<gt>B<tagExpires>() The timestamp when the signature will expire. Recommended. =item $obj-E<gt>B<tagExtract>() Some headers from the original message packed together. =item $obj-E<gt>B<tagQueryMethods>() A colon-separated list of method which can be used to retrieve the public key. The default is "dns/txt" (currently the only valid option) =item $obj-E<gt>B<tagSelector>() The selector subdividing the domain tag. Required. =item $obj-E<gt>B<tagSignData>() Z<> =item $obj-E<gt>B<tagSignature>() Message signature in base64, with whitespaces removed. Required. =item $obj-E<gt>B<tagSignedHeaders>() The colon separated list of headers which need to be included in the signature. Required. =item $obj-E<gt>B<tagTimestamp>() When the signature was created in UNIX-like seconds (since 1970). Recommended. =item $obj-E<gt>B<tagVersion>() Signature header syntax version (usually 1) =back =head2 Internals Extends L<"Internals" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"Internals">. =over 4 =item $any-E<gt>B<decode>(STRING, %options) Inherited, see L<Mail::Message::Field::Full/"Internals"> =item $obj-E<gt>B<encode>(STRING, %options) Inherited, see L<Mail::Message::Field::Full/"Internals"> =back =head2 Parsing Extends L<"Parsing" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"Parsing">. =over 4 =item $obj-E<gt>B<consume>( $line | <$name,<$body|$objects>> ) Inherited, see L<Mail::Message::Field/"Parsing"> =item $any-E<gt>B<consumeComment>(STRING) Inherited, see L<Mail::Message::Field::Full/"Parsing"> =item $obj-E<gt>B<consumeDotAtom>(STRING) Inherited, see L<Mail::Message::Field::Full/"Parsing"> =item $any-E<gt>B<consumePhrase>(STRING) Inherited, see L<Mail::Message::Field::Full/"Parsing"> =item $obj-E<gt>B<datum>( [$value] ) Inherited, see L<Mail::Message::Field::Structured/"Parsing"> =item $obj-E<gt>B<defaultWrapLength>( [$length] ) Inherited, see L<Mail::Message::Field/"Parsing"> =item $any-E<gt>B<fold>( $name, $body, [$maxchars] ) Inherited, see L<Mail::Message::Field/"Parsing"> =item $obj-E<gt>B<parse>(STRING) Inherited, see L<Mail::Message::Field::Full/"Parsing"> =item $obj-E<gt>B<produceBody>() Inherited, see L<Mail::Message::Field::Full/"Parsing"> =item $obj-E<gt>B<setWrapLength>( [$length] ) Inherited, see L<Mail::Message::Field/"Parsing"> =item $obj-E<gt>B<stringifyData>(STRING|ARRAY|$objects) Inherited, see L<Mail::Message::Field/"Parsing"> =item $obj-E<gt>B<unfold>(STRING) Inherited, see L<Mail::Message::Field/"Parsing"> =back =head2 Error handling Extends L<"Error handling" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"Error handling">. =over 4 =item $obj-E<gt>B<AUTOLOAD>() Inherited, see L<Mail::Reporter/"Error handling"> =item $obj-E<gt>B<notImplemented>() Inherited, see L<Mail::Reporter/"Error handling"> =back =head2 Cleanup Extends L<"Cleanup" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"Cleanup">. =over 4 =item $obj-E<gt>B<DESTROY>() Inherited, see L<Mail::Reporter/"Cleanup"> =back =head1 DETAILS Extends L<"DETAILS" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"DETAILS">. =head1 DIAGNOSTICS =over 4 =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =item Warning: field content is not numerical: $content The numeric value of a field is requested (for instance the C<Lines> or C<Content-Length> fields should be numerical), however the data contains weird characters. Cast by C<toInt()> =item Error: field name too long (max $count), in '$name'. It is not specified in the RFCs how long a field name can be, but at least it should be a few characters shorter than the line wrap. Cast by C<fold()> =item Warning: illegal character in charset '$name'. The field is created with an utf8 string which only contains data from the specified character set. However, that character set can never be a valid name because it contains characters which are not permitted. Cast by C<encode()> =item Warning: illegal character in field name $name. A new field is being created which does contain characters not permitted by the RFCs. Using this field in messages may break other e-mail clients or transfer agents, and therefore mutulate or extinguish your message. Cast by C<consume()> =item Warning: illegal character in language '$name'. The field is created with data which is specified to be in a certain language, however, the name of the language cannot be valid: it contains characters which are not permitted by the RFCs. Cast by C<encode()> =item Warning: illegal encoding '$name', using 'q'. The RFCs only permit base64 (C<b > or C<B >) or quoted-printable (C<q> or C<Q>) encoding. Other than these four options are illegal. Cast by C<encode()> =item Error: no attributes for DKIM headers. Is is not possible to add attributes to this field. Cast by C<addAttribute()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Field/DKIM.pm����������������������������������������������������0000644�0001750�0000144�00000003750�15166136116�021560� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::Field::DKIM;{ our $VERSION = '4.05'; } use parent 'Mail::Message::Field::Structured'; use warnings; use strict; use Log::Report 'mail-message', import => [ qw/__x error/ ]; use URI (); #-------------------- sub init($) { my ($self, $args) = @_; $self->{MMFD_tags} = +{ v => 1, a => 'rsa-sha256' }; $self->SUPER::init($args); } sub parse($) { my ($self, $string) = @_; my $tags = $self->{MMFD_tags}; foreach (split /\;/, $string) { m/^\s*([a-z][a-z0-9_]*)\s*\=\s*([\s\x21-\x7E]+?)\s*$/is or next; # tag-values stay unparsed (for now) $self->addTag($1, $2); } (undef, $string) = $self->consumeComment($string); $self; } sub produceBody() { my $self = shift; } #-------------------- sub addAttribute($;@) { my $self = shift; error __x"no attributes for DKIM headers."; } sub addTag($$) { my ($self, $name) = (shift, lc shift); $self->{MMFD_tags}{$name} = join ' ', @_; $self; } sub tag($) { $_[0]->{MMFD_tags}{lc $_[1]} } #-------------------- sub tagAlgorithm() { $_[0]->tag('a') } sub tagSignData() { $_[0]->tag('b') } sub tagSignature() { $_[0]->tag('bh') } sub tagC14N() { $_[0]->tag('c') } sub tagDomain() { $_[0]->tag('d') } sub tagSignedHeaders() { $_[0]->tag('h') } sub tagAgentID() { $_[0]->tag('i') } sub tagBodyLength(){ $_[0]->tag('l') } sub tagQueryMethods() { $_[0]->tag('q') } sub tagSelector() { $_[0]->tag('s') } sub tagTimestamp() { $_[0]->tag('t') } sub tagExpires() { $_[0]->tag('x') } sub tagVersion() { $_[0]->tag('v') } sub tagExtract() { $_[0]->tag('z') } #-------------------- 1; ������������������������Mail-Message-4.05/lib/Mail/Message/Field/AuthResults.pod��������������������������������������������0000644�0001750�0000144�00000027207�15166136117�023471� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Field::AuthResults - message header field authentication result =head1 INHERITANCE Mail::Message::Field::AuthResults is a Mail::Message::Field::Structured is a Mail::Message::Field::Full is a Mail::Message::Field is a Mail::Reporter =head1 SYNOPSIS my $f = Mail::Message::Field->new('Authentication-Results' => '...'); my $g = Mail::Message::Field->new('Authentication-Results'); $g->addResult(method => 'dkim', result => 'fail'); =head1 DESCRIPTION Mail Transfer Agents may check the authenticity of an incoming message. They add 'Authentication-Results' headers, maybe more than one. This implementation is based on RFC7601. Extends L<"DESCRIPTION" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"DESCRIPTION">. =head1 OVERLOADED Extends L<"OVERLOADED" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"OVERLOADED">. =over 4 =item overload: B<""> stringification Inherited, see L<Mail::Message::Field::Full/"OVERLOADED"> =item overload: B<'""'> stringification Inherited, see L<Mail::Message::Field/"OVERLOADED"> =item overload: B<'0+'> numification Inherited, see L<Mail::Message::Field/"OVERLOADED"> =item overload: B<'<=>'> numeric comparison Inherited, see L<Mail::Message::Field/"OVERLOADED"> =item overload: B<bool> boolean Inherited, see L<Mail::Message::Field/"OVERLOADED"> =item overload: B<cmp> string comparison Inherited, see L<Mail::Message::Field/"OVERLOADED"> =back =head1 METHODS Extends L<"METHODS" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"Constructors">. =over 4 =item $obj-E<gt>B<clone>() Inherited, see L<Mail::Message::Field/"Constructors"> =item $class-E<gt>B<from>($field, %options) Inherited, see L<Mail::Message::Field::Full/"Constructors"> =item $class-E<gt>B<new>(%options) Inherited, see L<Mail::Message::Field::Structured/"METHODS"> -Option --Defined in --Default attributes Mail::Message::Field::Structured <ignored> charset Mail::Message::Field::Full undef datum Mail::Message::Field::Structured undef encoding Mail::Message::Field::Full 'q' force Mail::Message::Field::Full false language Mail::Message::Field::Full undef results [] server <required> version undef =over 2 =item attributes => \@attributes|\%attributes =item charset => $charset =item datum => $date =item encoding => 'q'|'Q'|'b'|'B' =item force => BOOLEAN =item language => $language =item results => ARRAY Each authentication method is represented by a HASH, which contains the 'method' and 'result' keys. Sometimes, there is a 'comment'. Properties of form 'ptype.pname' will be there as well. =item server => $domain Where the authentication tool ran. This should be your local service, otherwise you may accept spoofed headers! =item version => INTEGER =back =back =head2 Attributes Extends L<"Attributes" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"Attributes">. =over 4 =item $obj-E<gt>B<Name>() Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<body>() Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<folded>() Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<foldedBody>( [$body] ) Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<name>() Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<unfoldedBody>( [$body, [$wrap]] ) Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<wellformedName>( [STRING] ) Inherited, see L<Mail::Message::Field/"Attributes"> =back =head2 The field Extends L<"The field" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"The field">. =over 4 =item $any-E<gt>B<isStructured>( [$name] ) Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<length>() Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<nrLines>() Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<print>( [$fh] ) Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<size>() Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<string>( [$wrap] ) Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<toDisclose>() Inherited, see L<Mail::Message::Field/"The field"> =back =head2 Access to the body Extends L<"Access to the body" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"Access to the body">. =over 4 =item $obj-E<gt>B<decodedBody>(%options) Inherited, see L<Mail::Message::Field::Full/"Access to the body"> =back =head2 Access to the content Extends L<"Access to the content" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"Access to the content">. =over 4 =item $obj-E<gt>B<addAttribute>(...) Attributes are not supported here. =item $obj-E<gt>B<addResult>(HASH|PAIRS) Add new results to this header. Invalid results are ignored. =item $obj-E<gt>B<addresses>() Inherited, see L<Mail::Message::Field/"Access to the content"> =item $obj-E<gt>B<attrPairs>() Inherited, see L<Mail::Message::Field::Structured/"Access to the content"> =item $obj-E<gt>B<attribute>( $object|<STRING, %options>|<$name,$value,%options> ) Inherited, see L<Mail::Message::Field::Structured/"Access to the content"> =item $obj-E<gt>B<attributes>() Inherited, see L<Mail::Message::Field::Structured/"Access to the content"> =item $obj-E<gt>B<beautify>() Inherited, see L<Mail::Message::Field::Full/"Access to the content"> =item $obj-E<gt>B<comment>( [STRING] ) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $any-E<gt>B<createComment>(STRING, %options) Inherited, see L<Mail::Message::Field::Full/"Access to the content"> =item $any-E<gt>B<createPhrase>(STRING, %options) Inherited, see L<Mail::Message::Field::Full/"Access to the content"> =item $any-E<gt>B<dateToTimestamp>(STRING) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $obj-E<gt>B<results>() Returns a LIST of result HASHes. Each HASH at least contains keys 'method', 'method_version', and 'result'. =item $obj-E<gt>B<server>() The hostname which ran this authentication tool. =item $any-E<gt>B<stripCFWS>( [STRING] ) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $obj-E<gt>B<study>() Inherited, see L<Mail::Message::Field/"Access to the content"> =item $any-E<gt>B<toDate>( [$time] ) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $obj-E<gt>B<toInt>() Inherited, see L<Mail::Message::Field/"Access to the content"> =item $obj-E<gt>B<version>() The version of the 'Authentication-Results' header, which may be different from '1' (default) for successors of RFC7601. =back =head2 Internals Extends L<"Internals" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"Internals">. =over 4 =item $any-E<gt>B<decode>(STRING, %options) Inherited, see L<Mail::Message::Field::Full/"Internals"> =item $obj-E<gt>B<encode>(STRING, %options) Inherited, see L<Mail::Message::Field::Full/"Internals"> =back =head2 Parsing Extends L<"Parsing" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"Parsing">. =over 4 =item $obj-E<gt>B<consume>( $line | <$name,<$body|$objects>> ) Inherited, see L<Mail::Message::Field/"Parsing"> =item $any-E<gt>B<consumeComment>(STRING) Inherited, see L<Mail::Message::Field::Full/"Parsing"> =item $obj-E<gt>B<consumeDotAtom>(STRING) Inherited, see L<Mail::Message::Field::Full/"Parsing"> =item $any-E<gt>B<consumePhrase>(STRING) Inherited, see L<Mail::Message::Field::Full/"Parsing"> =item $obj-E<gt>B<datum>( [$value] ) Inherited, see L<Mail::Message::Field::Structured/"Parsing"> =item $obj-E<gt>B<defaultWrapLength>( [$length] ) Inherited, see L<Mail::Message::Field/"Parsing"> =item $any-E<gt>B<fold>( $name, $body, [$maxchars] ) Inherited, see L<Mail::Message::Field/"Parsing"> =item $obj-E<gt>B<parse>(STRING) Inherited, see L<Mail::Message::Field::Full/"Parsing"> =item $obj-E<gt>B<produceBody>() Inherited, see L<Mail::Message::Field::Full/"Parsing"> =item $obj-E<gt>B<setWrapLength>( [$length] ) Inherited, see L<Mail::Message::Field/"Parsing"> =item $obj-E<gt>B<stringifyData>(STRING|ARRAY|$objects) Inherited, see L<Mail::Message::Field/"Parsing"> =item $obj-E<gt>B<unfold>(STRING) Inherited, see L<Mail::Message::Field/"Parsing"> =back =head2 Error handling Extends L<"Error handling" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"Error handling">. =over 4 =item $obj-E<gt>B<AUTOLOAD>() Inherited, see L<Mail::Reporter/"Error handling"> =item $obj-E<gt>B<notImplemented>() Inherited, see L<Mail::Reporter/"Error handling"> =back =head2 Cleanup Extends L<"Cleanup" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"Cleanup">. =over 4 =item $obj-E<gt>B<DESTROY>() Inherited, see L<Mail::Reporter/"Cleanup"> =back =head1 DETAILS Extends L<"DETAILS" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"DETAILS">. =head1 DIAGNOSTICS =over 4 =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =item Warning: field content is not numerical: $content The numeric value of a field is requested (for instance the C<Lines> or C<Content-Length> fields should be numerical), however the data contains weird characters. Cast by C<toInt()> =item Error: field name too long (max $count), in '$name'. It is not specified in the RFCs how long a field name can be, but at least it should be a few characters shorter than the line wrap. Cast by C<fold()> =item Warning: illegal character in charset '$name'. The field is created with an utf8 string which only contains data from the specified character set. However, that character set can never be a valid name because it contains characters which are not permitted. Cast by C<encode()> =item Warning: illegal character in field name $name. A new field is being created which does contain characters not permitted by the RFCs. Using this field in messages may break other e-mail clients or transfer agents, and therefore mutulate or extinguish your message. Cast by C<consume()> =item Warning: illegal character in language '$name'. The field is created with data which is specified to be in a certain language, however, the name of the language cannot be valid: it contains characters which are not permitted by the RFCs. Cast by C<encode()> =item Warning: illegal encoding '$name', using 'q'. The RFCs only permit base64 (C<b > or C<B >) or quoted-printable (C<q> or C<Q>) encoding. Other than these four options are illegal. Cast by C<encode()> =item Error: no attributes for Authentication-Results. Is is not possible to add attributes to this field. Cast by C<addAttribute()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Field/Unstructured.pod�������������������������������������������0000644�0001750�0000144�00000025416�15166136117�023715� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Field::Unstructured - smart unstructured field =head1 INHERITANCE Mail::Message::Field::Unstructured is a Mail::Message::Field::Full is a Mail::Message::Field is a Mail::Reporter =head1 SYNOPSIS my $f = Mail::Message::Field::Unstructured->new('Comments', 'hi!'); =head1 DESCRIPTION Unstructured fields do contain information which is not restricted in any way. RFC2822 defines some unstructured fields, but by default all unknown fields are unstructured as well. Things like attributes and comments have no meaning for unstructured fields, but encoding does. Extends L<"DESCRIPTION" in Mail::Message::Field::Full|Mail::Message::Field::Full/"DESCRIPTION">. =head1 OVERLOADED Extends L<"OVERLOADED" in Mail::Message::Field::Full|Mail::Message::Field::Full/"OVERLOADED">. =over 4 =item overload: B<""> stringification Inherited, see L<Mail::Message::Field::Full/"OVERLOADED"> =item overload: B<'""'> stringification Inherited, see L<Mail::Message::Field/"OVERLOADED"> =item overload: B<'0+'> numification Inherited, see L<Mail::Message::Field/"OVERLOADED"> =item overload: B<'<=>'> numeric comparison Inherited, see L<Mail::Message::Field/"OVERLOADED"> =item overload: B<bool> boolean Inherited, see L<Mail::Message::Field/"OVERLOADED"> =item overload: B<cmp> string comparison Inherited, see L<Mail::Message::Field/"OVERLOADED"> =back =head1 METHODS Extends L<"METHODS" in Mail::Message::Field::Full|Mail::Message::Field::Full/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Message::Field::Full|Mail::Message::Field::Full/"Constructors">. =over 4 =item $obj-E<gt>B<clone>() Inherited, see L<Mail::Message::Field/"Constructors"> =item $class-E<gt>B<from>($field, %options) Inherited, see L<Mail::Message::Field::Full/"Constructors"> =item $class-E<gt>B<new>($data) When the C<$data> is specified as single line, the content part is considered to be correcly (character) encoded and escaped. Typically, it is a line as read from file. The folding of the line is kept as is. In case more than one argument is provided, the second is considered the BODY. Attributes and other special things are not defined for unstructured fields, and therefore not valid options. The BODY can be a single string, a single OBJECT, or an array of OBJECTS. The objects are stringified (into a comma separated list). Each BODY element is interpreted with the specified encoding. When the BODY is empty, the construction of the object fails: C<undef> is returned. Improves base, see L<Mail::Message::Field::Full/"METHODS"> -Option --Defined in --Default charset Mail::Message::Field::Full undef encoding Mail::Message::Field::Full 'q' force Mail::Message::Field::Full false language Mail::Message::Field::Full undef =over 2 =item charset => $charset =item encoding => 'q'|'Q'|'b'|'B' =item force => BOOLEAN =item language => $language =back » example: my $s = Mail::Message::Field::Unstructured->new('Comment', 'Hi!'); # Use autodetect my $s = Mail::Message::Field::Full->new('Comment', 'Hi!'); my $s = Mail::Message::Field::Full->new('Comment: Hi!'); =back =head2 Attributes Extends L<"Attributes" in Mail::Message::Field::Full|Mail::Message::Field::Full/"Attributes">. =over 4 =item $obj-E<gt>B<Name>() Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<body>() Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<folded>() Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<foldedBody>( [$body] ) Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<name>() Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<unfoldedBody>( [$body, [$wrap]] ) Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<wellformedName>( [STRING] ) Inherited, see L<Mail::Message::Field/"Attributes"> =back =head2 The field Extends L<"The field" in Mail::Message::Field::Full|Mail::Message::Field::Full/"The field">. =over 4 =item $any-E<gt>B<isStructured>( [$name] ) Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<length>() Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<nrLines>() Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<print>( [$fh] ) Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<size>() Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<string>( [$wrap] ) Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<toDisclose>() Inherited, see L<Mail::Message::Field/"The field"> =back =head2 Access to the body Extends L<"Access to the body" in Mail::Message::Field::Full|Mail::Message::Field::Full/"Access to the body">. =over 4 =item $obj-E<gt>B<decodedBody>(%options) Inherited, see L<Mail::Message::Field::Full/"Access to the body"> =back =head2 Access to the content Extends L<"Access to the content" in Mail::Message::Field::Full|Mail::Message::Field::Full/"Access to the content">. =over 4 =item $obj-E<gt>B<addresses>() Inherited, see L<Mail::Message::Field/"Access to the content"> =item $obj-E<gt>B<attribute>( $name, [$value] ) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $obj-E<gt>B<attributes>() Inherited, see L<Mail::Message::Field/"Access to the content"> =item $obj-E<gt>B<beautify>() Inherited, see L<Mail::Message::Field::Full/"Access to the content"> =item $obj-E<gt>B<comment>( [STRING] ) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $any-E<gt>B<createComment>(STRING, %options) Inherited, see L<Mail::Message::Field::Full/"Access to the content"> =item $any-E<gt>B<createPhrase>(STRING, %options) Inherited, see L<Mail::Message::Field::Full/"Access to the content"> =item $any-E<gt>B<dateToTimestamp>(STRING) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $any-E<gt>B<stripCFWS>( [STRING] ) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $obj-E<gt>B<study>() Inherited, see L<Mail::Message::Field/"Access to the content"> =item $any-E<gt>B<toDate>( [$time] ) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $obj-E<gt>B<toInt>() Inherited, see L<Mail::Message::Field/"Access to the content"> =back =head2 Internals Extends L<"Internals" in Mail::Message::Field::Full|Mail::Message::Field::Full/"Internals">. =over 4 =item $any-E<gt>B<decode>(STRING, %options) Inherited, see L<Mail::Message::Field::Full/"Internals"> =item $obj-E<gt>B<encode>(STRING, %options) Inherited, see L<Mail::Message::Field::Full/"Internals"> =back =head2 Parsing Extends L<"Parsing" in Mail::Message::Field::Full|Mail::Message::Field::Full/"Parsing">. =over 4 =item $obj-E<gt>B<consume>( $line | <$name,<$body|$objects>> ) Inherited, see L<Mail::Message::Field/"Parsing"> =item $any-E<gt>B<consumeComment>(STRING) Inherited, see L<Mail::Message::Field::Full/"Parsing"> =item $obj-E<gt>B<consumeDotAtom>(STRING) Inherited, see L<Mail::Message::Field::Full/"Parsing"> =item $any-E<gt>B<consumePhrase>(STRING) Inherited, see L<Mail::Message::Field::Full/"Parsing"> =item $obj-E<gt>B<defaultWrapLength>( [$length] ) Inherited, see L<Mail::Message::Field/"Parsing"> =item $any-E<gt>B<fold>( $name, $body, [$maxchars] ) Inherited, see L<Mail::Message::Field/"Parsing"> =item $obj-E<gt>B<parse>(STRING) Inherited, see L<Mail::Message::Field::Full/"Parsing"> =item $obj-E<gt>B<produceBody>() Inherited, see L<Mail::Message::Field::Full/"Parsing"> =item $obj-E<gt>B<setWrapLength>( [$length] ) Inherited, see L<Mail::Message::Field/"Parsing"> =item $obj-E<gt>B<stringifyData>(STRING|ARRAY|$objects) Inherited, see L<Mail::Message::Field/"Parsing"> =item $obj-E<gt>B<unfold>(STRING) Inherited, see L<Mail::Message::Field/"Parsing"> =back =head2 Error handling Extends L<"Error handling" in Mail::Message::Field::Full|Mail::Message::Field::Full/"Error handling">. =over 4 =item $obj-E<gt>B<AUTOLOAD>() Inherited, see L<Mail::Reporter/"Error handling"> =item $obj-E<gt>B<notImplemented>() Inherited, see L<Mail::Reporter/"Error handling"> =back =head2 Cleanup Extends L<"Cleanup" in Mail::Message::Field::Full|Mail::Message::Field::Full/"Cleanup">. =over 4 =item $obj-E<gt>B<DESTROY>() Inherited, see L<Mail::Reporter/"Cleanup"> =back =head1 DETAILS Extends L<"DETAILS" in Mail::Message::Field::Full|Mail::Message::Field::Full/"DETAILS">. =head1 DIAGNOSTICS =over 4 =item Warning: attributes are not supported for unstructured fields. Cast by C<new()> =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =item Warning: field content is not numerical: $content The numeric value of a field is requested (for instance the C<Lines> or C<Content-Length> fields should be numerical), however the data contains weird characters. Cast by C<toInt()> =item Error: field name too long (max $count), in '$name'. It is not specified in the RFCs how long a field name can be, but at least it should be a few characters shorter than the line wrap. Cast by C<fold()> =item Warning: illegal character in charset '$name'. The field is created with an utf8 string which only contains data from the specified character set. However, that character set can never be a valid name because it contains characters which are not permitted. Cast by C<encode()> =item Warning: illegal character in field name $name. A new field is being created which does contain characters not permitted by the RFCs. Using this field in messages may break other e-mail clients or transfer agents, and therefore mutulate or extinguish your message. Cast by C<consume()> =item Warning: illegal character in language '$name'. The field is created with data which is specified to be in a certain language, however, the name of the language cannot be valid: it contains characters which are not permitted by the RFCs. Cast by C<encode()> =item Warning: illegal encoding '$name', using 'q'. The RFCs only permit base64 (C<b > or C<B >) or quoted-printable (C<q> or C<Q>) encoding. Other than these four options are illegal. Cast by C<encode()> =item Warning: no extras for unstructured fields. Cast by C<new()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Field/Address.pod������������������������������������������������0000644�0001750�0000144�00000014332�15166136117�022566� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Field::Address - One e-mail address =head1 INHERITANCE Mail::Message::Field::Address is a Mail::Identity is a User::Identity::Item =head1 SYNOPSIS my $addr = Mail::Message::Field::Address->new(...); my $ui = User::Identity->new(...); my $addr = Mail::Message::Field::Address->coerce($ui); my $mi = Mail::Identity->new(...); my $addr = Mail::Message::Field::Address->coerce($mi); print $addr->address; print $addr->fullName; # possibly unicode! print $addr->domain; =head1 DESCRIPTION Many header fields can contain e-mail addresses. Each e-mail address can be represented by an object of this class. These objects will handle interpretation and character set encoding and decoding for you. Extends L<"DESCRIPTION" in Mail::Identity|Mail::Identity/"DESCRIPTION">. =head1 OVERLOADED =over 4 =item overload: B<'""'> stringification When the object is used in string context, it will return the encoded representation of the e-mail address, just like L<string()|Mail::Message::Field::Address/"Access to the content"> does. =item overload: B<'bool'> use as boolean The object used as boolean will always return C<true> =item overload: B<'cmp'> string comparison Two address objects are the same when their email addresses are the same. =back =head1 METHODS Extends L<"METHODS" in Mail::Identity|Mail::Identity/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Identity|Mail::Identity/"Constructors">. =over 4 =item $obj-E<gt>B<coerce>( <STRING|$object>, %options ) Try to coerce the C<$object> into a C<Mail::Message::Field::Address>. In case of a C<STRING>, it is interpreted as an email address. The C<%options> are passed to the object creation, and overrule the values found in the C<$object>. The result may be C<undef> or a newly created object. If the C<$object> is already of the correct type, it is returned unmodified. The C<$object> may currently be a L<Mail::Address|Mail::Address>, a L<Mail::Identity|Mail::Identity>, or a L<User::Identity|User::Identity>. In case of the latter, one of the user's addresses is chosen at random. =item $class-E<gt>B<new>( [$name], %options ) Inherited, see L<Mail::Identity/"Constructors"> =item $obj-E<gt>B<parse>(STRING) Parse the string for an address. You never know whether one or more addresses are specified on a line (often applications are wrong), therefore, the C<STRING> is first parsed for as many addresses as possible and then the one is taken at random. =back =head2 Attributes Extends L<"Attributes" in Mail::Identity|Mail::Identity/"Attributes">. =over 4 =item $obj-E<gt>B<address>() Inherited, see L<Mail::Identity/"Attributes"> =item $obj-E<gt>B<charset>() Inherited, see L<Mail::Identity/"Attributes"> =item $obj-E<gt>B<comment>( [STRING] ) Inherited, see L<Mail::Identity/"Attributes"> =item $obj-E<gt>B<description>() Inherited, see L<User::Identity::Item/"Attributes"> =item $obj-E<gt>B<domain>() Inherited, see L<Mail::Identity/"Attributes"> =item $obj-E<gt>B<language>() Inherited, see L<Mail::Identity/"Attributes"> =item $obj-E<gt>B<location>() Inherited, see L<Mail::Identity/"Attributes"> =item $obj-E<gt>B<name>( [$newname] ) Inherited, see L<User::Identity::Item/"Attributes"> =item $obj-E<gt>B<organization>() Inherited, see L<Mail::Identity/"Attributes"> =item $obj-E<gt>B<phrase>() Inherited, see L<Mail::Identity/"Attributes"> =item $obj-E<gt>B<username>() Inherited, see L<Mail::Identity/"Attributes"> =back =head2 Collections Extends L<"Collections" in Mail::Identity|Mail::Identity/"Collections">. =over 4 =item $obj-E<gt>B<add>($collection, $role) Inherited, see L<User::Identity::Item/"Collections"> =item $obj-E<gt>B<addCollection>( $object | <[$type], %options> ) Inherited, see L<User::Identity::Item/"Collections"> =item $obj-E<gt>B<collection>($name) Inherited, see L<User::Identity::Item/"Collections"> =item $obj-E<gt>B<parent>( [$parent] ) Inherited, see L<User::Identity::Item/"Collections"> =item $obj-E<gt>B<removeCollection>($object|$name) Inherited, see L<User::Identity::Item/"Collections"> =item $any-E<gt>B<type>() Inherited, see L<User::Identity::Item/"Collections"> =item $obj-E<gt>B<user>() Inherited, see L<User::Identity::Item/"Collections"> =back =head2 Searching Extends L<"Searching" in Mail::Identity|Mail::Identity/"Searching">. =over 4 =item $obj-E<gt>B<find>($collection, $role) Inherited, see L<User::Identity::Item/"Searching"> =back =head2 Accessors =over 4 =item $obj-E<gt>B<encoding>() Character-set encoding, like 'q' and 'b', to be used when non-ascii characters are to be transmitted. =back =head2 Access to the content =over 4 =item $obj-E<gt>B<string>() Returns an RFC compliant e-mail address, which will have character set encoding if needed. The objects are also overloaded to call this method in string context. » example: print $address->string; print $address; # via overloading =back =head1 DIAGNOSTICS =over 4 =item Error: cannot coerce a $type into a $class When addresses are specified to be included in header fields, they may be coerced into L<Mail::Message::Field::Address|Mail::Message::Field::Address> objects first. What you specify is not accepted as address specification. This may be an internal error. Cast by C<coerce()> =item Error: cannot load collection module for $type ($class): $@ Either the specified C<$type> does not exist, or that module named C<$class> returns compilation errors. If the type as specified in the warning is not the name of a package, you specified a nickname which was not defined. Maybe you forgot the 'require' the package which defines the nickname. Cast by C<addCollection()> =item Error: invalid collection $name. The collection with C<$name> does not exist and can not be created. Cast by C<add()> =item Error: this $object is not a collection. Cast by C<addCollection()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Field/AddrGroup.pm�����������������������������������������������0000644�0001750�0000144�00000003145�15166136116�022721� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::Field::AddrGroup;{ our $VERSION = '4.05'; } use parent 'User::Identity::Collection::Emails'; use strict; use warnings; use Log::Report 'mail-message', import => [ qw/__x error/ ]; use Scalar::Util qw/blessed/; #-------------------- use overload '""' => 'string'; #-------------------- sub string() { my $self = shift; my $name = $self->name; my @addr = sort map $_->string, $self->addresses; local $" = ', '; length $name ? "$name: @addr;" : @addr ? "@addr" : ''; } #-------------------- sub coerce($@) { my ($class, $addr, %args) = @_; defined $addr or return (); if(blessed $addr) { return $addr if $addr->isa($class); return bless $addr, $class if $addr->isa('User::Identity::Collection::Emails'); } error __x"cannot coerce a {type} into a {class}.", type => ref $addr // 'string', class => $class; } #-------------------- sub addAddress(@) { my $self = shift; my $addr = @_ > 1 ? Mail::Message::Field::Address->new(@_) : !$_[0] ? return () : Mail::Message::Field::Address->coerce(shift); $self->addRole($addr); $addr; } # roles are stored in a hash, so produce sub addresses() { $_[0]->roles } #-------------------- 1; ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Field/Fast.pm����������������������������������������������������0000644�0001750�0000144�00000003662�15166136116�021733� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::Field::Fast;{ our $VERSION = '4.05'; } use parent 'Mail::Message::Field'; use strict; use warnings; use Log::Report 'mail-message', import => [ qw// ]; use Scalar::Util qw/blessed/; #-------------------- # The DATA is stored as: [ NAME, FOLDED-BODY ] # The body is kept in a folded fashion, where each line starts with # a single blank. sub new($;$@) { my $class = shift; my ($name, $body) = $class->consume(@_==1 ? (shift) : (shift, shift)); defined $body or return (); my $self = bless +[$name, $body], $class; # Attributes $self->comment(shift) if @_==1; # one attribute line $self->attribute(shift, shift) while @_ > 1; # attribute pairs $self; } sub clone() { my $self = shift; bless +[ @$self ], ref $self; } sub length() { my $self = shift; length($self->[0]) + 1 + length($self->[1]); } sub name() { lc shift->[0] } sub Name() { $_[0]->[0] } sub folded() { my $self = shift; wantarray or return $self->[0] .':'. $self->[1]; my @lines = $self->foldedBody; my $first = $self->[0]. ':'. shift @lines; ($first, @lines); } sub unfoldedBody($;@) { my $self = shift; $self->[1] = $self->fold($self->[0], @_) if @_; $self->unfold($self->[1]); } sub foldedBody($) { my ($self, $body) = @_; if(@_==2) { $self->[1] = $body } else { $body = $self->[1] } wantarray ? (split m/^/, $body) : $body; } # For performance reasons only sub print(;$) { my $self = shift; my $fh = shift || select; $fh->print($self->[0].':'.$self->[1]); $self; } 1; ������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Field/Addresses.pod����������������������������������������������0000644�0001750�0000144�00000033140�15166136117�023114� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Field::Addresses - Fields with e-mail addresses =head1 INHERITANCE Mail::Message::Field::Addresses is a Mail::Message::Field::Structured is a Mail::Message::Field::Full is a Mail::Message::Field is a Mail::Reporter =head1 SYNOPSIS my $cc = Mail::Message::Field::Full->new('Cc'); my $me = Mail::Message::Field::Address->parse('"Test" <test@mail.box>') my $other = Mail::Message::Field::Address->new(phrase => 'Other', address => 'other@example.com'); $cc->addAddress($me); $cc->addAddress($other, group => 'them'); $cc->addAddress(phrase => 'third', address => 'more@any.museum', group => 'them'); my $group = $cc->addGroup(name => 'collegues'); $group->addAddress($me); $group->addAddress(phrase => "You", address => 'you@example.com'); my $msg = Mail::Message->build(Cc => $cc); print $msg->string; my $g = Mail::Message::Field::AddrGroup->new(...); $cc->addGroup($g); =head1 DESCRIPTION All header fields which contain e-mail addresses only. Not all address fields have the same possibilities, but they are all parsed the same: you never know how broken the applications are which produce those messages. When you try to create constructs which are not allowed for a certain kind of field, you will be warned. RFC5322 did allow address groups for "To" and "Cc", but not to be used in (amongst other) "From" and "Sender" fields. This restriction got lifted by RFC6854 (2013). L<https://www.rfc-editor.org/rfc/rfc6854> Extends L<"DESCRIPTION" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"DESCRIPTION">. =head1 OVERLOADED Extends L<"OVERLOADED" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"OVERLOADED">. =over 4 =item overload: B<""> stringification Inherited, see L<Mail::Message::Field::Full/"OVERLOADED"> =item overload: B<'""'> stringification Inherited, see L<Mail::Message::Field/"OVERLOADED"> =item overload: B<'0+'> numification Inherited, see L<Mail::Message::Field/"OVERLOADED"> =item overload: B<'<=>'> numeric comparison Inherited, see L<Mail::Message::Field/"OVERLOADED"> =item overload: B<bool> boolean Inherited, see L<Mail::Message::Field/"OVERLOADED"> =item overload: B<cmp> string comparison Inherited, see L<Mail::Message::Field/"OVERLOADED"> =back =head1 METHODS Extends L<"METHODS" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"Constructors">. =over 4 =item $obj-E<gt>B<clone>() Inherited, see L<Mail::Message::Field/"Constructors"> =item $class-E<gt>B<from>($field, %options) Inherited, see L<Mail::Message::Field::Full/"Constructors"> =item $class-E<gt>B<new>() Inherited, see L<Mail::Message::Field::Structured/"METHODS"> -Option --Defined in --Default attributes Mail::Message::Field::Structured <ignored> charset Mail::Message::Field::Full undef datum Mail::Message::Field::Structured undef encoding Mail::Message::Field::Full 'q' force Mail::Message::Field::Full false language Mail::Message::Field::Full undef =over 2 =item attributes => \@attributes|\%attributes =item charset => $charset =item datum => $date =item encoding => 'q'|'Q'|'b'|'B' =item force => BOOLEAN =item language => $language =back =back =head2 Attributes Extends L<"Attributes" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"Attributes">. =over 4 =item $obj-E<gt>B<Name>() Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<body>() Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<folded>() Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<foldedBody>( [$body] ) Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<name>() Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<unfoldedBody>( [$body, [$wrap]] ) Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<wellformedName>( [STRING] ) Inherited, see L<Mail::Message::Field/"Attributes"> =back =head2 The field Extends L<"The field" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"The field">. =over 4 =item $any-E<gt>B<isStructured>( [$name] ) Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<length>() Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<nrLines>() Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<print>( [$fh] ) Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<size>() Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<string>( [$wrap] ) Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<toDisclose>() Inherited, see L<Mail::Message::Field/"The field"> =back =head2 Access to the body Extends L<"Access to the body" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"Access to the body">. =over 4 =item $obj-E<gt>B<decodedBody>(%options) Inherited, see L<Mail::Message::Field::Full/"Access to the body"> =back =head2 Access to the content Extends L<"Access to the content" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"Access to the content">. =over 4 =item $obj-E<gt>B<addAddress>( [$address], %options ) Add an C<$address> to the field. The addresses are organized in groups. If no group is specified, the default group is taken to store the address in. If no C<$address> is specified, the option must be sufficient to create a L<Mail::Message::Field::Address|Mail::Message::Field::Address> from. See the C<%options> of L<Mail::Message::Field::Address::new()|Mail::Identity/"Constructors">. -Option--Default group '' =over 2 =item group => STRING =back =item $obj-E<gt>B<addAttribute>(...) Attributes are not supported for address fields. =item $obj-E<gt>B<addGroup>($group|%options) Add a group of addresses to this field. A C<$group> can be specified, which is a L<Mail::Message::Field::AddrGroup|Mail::Message::Field::AddrGroup> object, or one is created for you using the C<%options>. The group is returned. -Option--Default name '' =over 2 =item name => STRING =back =item $obj-E<gt>B<addresses>() Returns a list with all addresses defined in any group of addresses: all addresses which are specified on the line. The addresses are L<Mail::Message::Field::Address|Mail::Message::Field::Address> objects. Improves base, see L<Mail::Message::Field/"Access to the content"> » example: my @addr = $field->addresses; =item $obj-E<gt>B<attrPairs>() Inherited, see L<Mail::Message::Field::Structured/"Access to the content"> =item $obj-E<gt>B<attribute>( $object|<STRING, %options>|<$name,$value,%options> ) Inherited, see L<Mail::Message::Field::Structured/"Access to the content"> =item $obj-E<gt>B<attributes>() Inherited, see L<Mail::Message::Field::Structured/"Access to the content"> =item $obj-E<gt>B<beautify>() Inherited, see L<Mail::Message::Field::Full/"Access to the content"> =item $obj-E<gt>B<comment>( [STRING] ) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $any-E<gt>B<createComment>(STRING, %options) Inherited, see L<Mail::Message::Field::Full/"Access to the content"> =item $any-E<gt>B<createPhrase>(STRING, %options) Inherited, see L<Mail::Message::Field::Full/"Access to the content"> =item $any-E<gt>B<dateToTimestamp>(STRING) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $obj-E<gt>B<group>($name) Returns the group of addresses with the specified C<$name>, or C<undef> if it does not exist. If C<$name> is C<undef>, then the default groep is returned. =item $obj-E<gt>B<groupNames>() Returns a list with all group names which are defined. =item $obj-E<gt>B<groups>() Returns all address groups which are defined in this field. Each element is a L<Mail::Message::Field::AddrGroup|Mail::Message::Field::AddrGroup> object. =item $any-E<gt>B<stripCFWS>( [STRING] ) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $obj-E<gt>B<study>() Inherited, see L<Mail::Message::Field/"Access to the content"> =item $any-E<gt>B<toDate>( [$time] ) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $obj-E<gt>B<toInt>() Inherited, see L<Mail::Message::Field/"Access to the content"> =back =head2 Internals Extends L<"Internals" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"Internals">. =over 4 =item $any-E<gt>B<decode>(STRING, %options) Inherited, see L<Mail::Message::Field::Full/"Internals"> =item $obj-E<gt>B<encode>(STRING, %options) Inherited, see L<Mail::Message::Field::Full/"Internals"> =back =head2 Parsing Extends L<"Parsing" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"Parsing">. =over 4 =item $obj-E<gt>B<consume>( $line | <$name,<$body|$objects>> ) Inherited, see L<Mail::Message::Field/"Parsing"> =item $obj-E<gt>B<consumeAddress>(STRING, %options) Try to destilate address information from the C<STRING>. Returned are an address B<object> and the left-over string. If no address was found, the first returned value is C<undef>. =item $any-E<gt>B<consumeComment>(STRING) Inherited, see L<Mail::Message::Field::Full/"Parsing"> =item $obj-E<gt>B<consumeDomain>(STRING) Try to get a valid domain representation from C<STRING>. Returned are the domain string as found (or C<undef>) and the rest of the string. =item $obj-E<gt>B<consumeDotAtom>(STRING) Inherited, see L<Mail::Message::Field::Full/"Parsing"> =item $any-E<gt>B<consumePhrase>(STRING) Inherited, see L<Mail::Message::Field::Full/"Parsing"> =item $obj-E<gt>B<datum>( [$value] ) Inherited, see L<Mail::Message::Field::Structured/"Parsing"> =item $obj-E<gt>B<defaultWrapLength>( [$length] ) Inherited, see L<Mail::Message::Field/"Parsing"> =item $any-E<gt>B<fold>( $name, $body, [$maxchars] ) Inherited, see L<Mail::Message::Field/"Parsing"> =item $obj-E<gt>B<parse>($string) Inherited, see L<Mail::Message::Field::Full/"Parsing"> =item $obj-E<gt>B<produceBody>() Inherited, see L<Mail::Message::Field::Full/"Parsing"> =item $obj-E<gt>B<setWrapLength>( [$length] ) Inherited, see L<Mail::Message::Field/"Parsing"> =item $obj-E<gt>B<stringifyData>(STRING|ARRAY|$objects) Inherited, see L<Mail::Message::Field/"Parsing"> =item $obj-E<gt>B<unfold>(STRING) Inherited, see L<Mail::Message::Field/"Parsing"> =back =head2 Error handling Extends L<"Error handling" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"Error handling">. =over 4 =item $obj-E<gt>B<AUTOLOAD>() Inherited, see L<Mail::Reporter/"Error handling"> =item $obj-E<gt>B<notImplemented>() Inherited, see L<Mail::Reporter/"Error handling"> =back =head2 Cleanup Extends L<"Cleanup" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"Cleanup">. =over 4 =item $obj-E<gt>B<DESTROY>() Inherited, see L<Mail::Reporter/"Cleanup"> =back =head1 DETAILS Extends L<"DETAILS" in Mail::Message::Field::Structured|Mail::Message::Field::Structured/"DETAILS">. =head1 DIAGNOSTICS =over 4 =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =item Warning: field content is not numerical: $content The numeric value of a field is requested (for instance the C<Lines> or C<Content-Length> fields should be numerical), however the data contains weird characters. Cast by C<toInt()> =item Error: field name too long (max $count), in '$name'. It is not specified in the RFCs how long a field name can be, but at least it should be a few characters shorter than the line wrap. Cast by C<fold()> =item Warning: ignoring addressless phrase '$phrase'. Cast by C<parse()> =item Warning: illegal character in charset '$name'. The field is created with an utf8 string which only contains data from the specified character set. However, that character set can never be a valid name because it contains characters which are not permitted. Cast by C<encode()> =item Warning: illegal character in field name $name. A new field is being created which does contain characters not permitted by the RFCs. Using this field in messages may break other e-mail clients or transfer agents, and therefore mutulate or extinguish your message. Cast by C<consume()> =item Warning: illegal character in language '$name'. The field is created with data which is specified to be in a certain language, however, the name of the language cannot be valid: it contains characters which are not permitted by the RFCs. Cast by C<encode()> =item Warning: illegal encoding '$name', using 'q'. The RFCs only permit base64 (C<b > or C<B >) or quoted-printable (C<q> or C<Q>) encoding. Other than these four options are illegal. Cast by C<encode()> =item Warning: illegal part in address field $name: $part. Cast by C<parse()> =item Error: no attributes for address fields. Is is not possible to add attributes to address fields: it is not permitted by the RFCs. Cast by C<addAttribute()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Field/Fast.pod���������������������������������������������������0000644�0001750�0000144�00000022474�15166136117�022104� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Field::Fast - one line of a message header =head1 INHERITANCE Mail::Message::Field::Fast is a Mail::Message::Field is a Mail::Reporter =head1 SYNOPSIS See Mail::Message::Field =head1 DESCRIPTION This is the faster, but less flexible implementation of a header field. The data is stored in an array, and some hacks are made to speeds things up. Be gentle with me, and consider that each message contains many of these lines, so speed is very important here. Extends L<"DESCRIPTION" in Mail::Message::Field|Mail::Message::Field/"DESCRIPTION">. =head1 OVERLOADED Extends L<"OVERLOADED" in Mail::Message::Field|Mail::Message::Field/"OVERLOADED">. =over 4 =item overload: B<'""'> stringification Inherited, see L<Mail::Message::Field/"OVERLOADED"> =item overload: B<'0+'> numification Inherited, see L<Mail::Message::Field/"OVERLOADED"> =item overload: B<'<=>'> numeric comparison Inherited, see L<Mail::Message::Field/"OVERLOADED"> =item overload: B<bool> boolean Inherited, see L<Mail::Message::Field/"OVERLOADED"> =item overload: B<cmp> string comparison Inherited, see L<Mail::Message::Field/"OVERLOADED"> =back =head1 METHODS Extends L<"METHODS" in Mail::Message::Field|Mail::Message::Field/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Message::Field|Mail::Message::Field/"Constructors">. =over 4 =item $obj-E<gt>B<clone>() Inherited, see L<Mail::Message::Field/"Constructors"> =item $class-E<gt>B<new>(($line | $name, $body, [$attributes]), %options) The constructor of this object does not follow the usual practise within the L<Mail::Box|Mail::Box> suite: it does not use the constructor L<Mail::Reporter::new()|Mail::Reporter/"Constructors">. The method can be used in one of the following ways: =over 4 =item * B<new>(C<$line>, C<%options>) Pass a C<$line> as it could be found in a file: a (possibly folded) line which is terminated by a new-line. =item * B<new>(C<$name>, C<$body>, [C<$attributes>], C<%options>) A set of values which shape the line. =back Create a new header field object. Specify the whole C<$line> (encoded octets) at once, and it will be split-up for you. I case you already have the parts of the header line, you may specify them separately as C<$name> and field C<$body>. In case you specify a single C<$body> object, or an ARRAY of objects, these are processed to become suitable to fill a field, usually by simple strification. When you specify one or more L<Mail::Address|Mail::Address> objects, these are transformed into a string using their C<format> method. You may also add one L<Mail::Message::Field|Mail::Message::Field>, whose body is taken. In case of an array, the elements are joined into one string with a comma. The C<$attributes> can be exactly one string which may contain multiple attributes at once, quoted and formatted as required in RFC2822. As alternative, list of key-value pairs can be used. In this case, the values will get quoted if needed and everything formatted as the protocol demands. Improves base, see L<Mail::Message::Field/"Constructors"> » example: my $mime = Mail::Message::Field->new( 'Content-Type: text/plain; charset=US-ASCII'); my $mime = Mail::Message::Field->new( 'Content-Type' => 'text/plain; charset=US-ASCII'); my $mime = Mail::Message::Field->new( 'Content-Type' => 'text/plain', 'charset=US-ASCII'); my $mime = Mail::Message::Field->new( 'Content-Type' => 'text/plain', charset => 'Latin1'); my $mime = Mail::Message::Field->new( To => Mail::Address->new('My', 'me@example.com'); my $mime = Mail::Message::Field->new( Cc => [ Mail::Address->new('You', 'you@example.com'), Mail::Address->new('His', 'he@example.com') ]); But in practice, you can simply call my $head = Mail::Message::Head->new; $head->add( 'Content-Type' => 'text/plain', charset => 'utf8'); which implicitly calls this constructor (when needed). You can specify the same things for L<Mail::Message::Head::Complete::add()|Mail::Message::Head::Complete/"Access to the header"> as this C<new> accepts. =back =head2 Attributes Extends L<"Attributes" in Mail::Message::Field|Mail::Message::Field/"Attributes">. =over 4 =item $obj-E<gt>B<Name>() Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<body>() Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<folded>() Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<foldedBody>( [$body] ) Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<name>() Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<unfoldedBody>( [$body, [$wrap]] ) Inherited, see L<Mail::Message::Field/"Attributes"> =item $obj-E<gt>B<wellformedName>( [STRING] ) Inherited, see L<Mail::Message::Field/"Attributes"> =back =head2 The field Extends L<"The field" in Mail::Message::Field|Mail::Message::Field/"The field">. =over 4 =item $any-E<gt>B<isStructured>( [$name] ) Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<length>() Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<nrLines>() Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<print>( [$fh] ) Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<size>() Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<string>( [$wrap] ) Inherited, see L<Mail::Message::Field/"The field"> =item $obj-E<gt>B<toDisclose>() Inherited, see L<Mail::Message::Field/"The field"> =back =head2 Access to the content Extends L<"Access to the content" in Mail::Message::Field|Mail::Message::Field/"Access to the content">. =over 4 =item $obj-E<gt>B<addresses>() Inherited, see L<Mail::Message::Field/"Access to the content"> =item $obj-E<gt>B<attribute>( $name, [$value] ) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $obj-E<gt>B<attributes>() Inherited, see L<Mail::Message::Field/"Access to the content"> =item $obj-E<gt>B<comment>( [STRING] ) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $any-E<gt>B<dateToTimestamp>(STRING) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $any-E<gt>B<stripCFWS>( [STRING] ) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $obj-E<gt>B<study>() Inherited, see L<Mail::Message::Field/"Access to the content"> =item $any-E<gt>B<toDate>( [$time] ) Inherited, see L<Mail::Message::Field/"Access to the content"> =item $obj-E<gt>B<toInt>() Inherited, see L<Mail::Message::Field/"Access to the content"> =back =head2 Parsing Extends L<"Parsing" in Mail::Message::Field|Mail::Message::Field/"Parsing">. =over 4 =item $obj-E<gt>B<consume>( $line | <$name,<$body|$objects>> ) Inherited, see L<Mail::Message::Field/"Parsing"> =item $obj-E<gt>B<defaultWrapLength>( [$length] ) Inherited, see L<Mail::Message::Field/"Parsing"> =item $any-E<gt>B<fold>( $name, $body, [$maxchars] ) Inherited, see L<Mail::Message::Field/"Parsing"> =item $obj-E<gt>B<setWrapLength>( [$length] ) Inherited, see L<Mail::Message::Field/"Parsing"> =item $obj-E<gt>B<stringifyData>(STRING|ARRAY|$objects) Inherited, see L<Mail::Message::Field/"Parsing"> =item $obj-E<gt>B<unfold>(STRING) Inherited, see L<Mail::Message::Field/"Parsing"> =back =head2 Error handling Extends L<"Error handling" in Mail::Message::Field|Mail::Message::Field/"Error handling">. =over 4 =item $obj-E<gt>B<AUTOLOAD>() Inherited, see L<Mail::Reporter/"Error handling"> =item $obj-E<gt>B<notImplemented>() Inherited, see L<Mail::Reporter/"Error handling"> =back =head2 Cleanup Extends L<"Cleanup" in Mail::Message::Field|Mail::Message::Field/"Cleanup">. =over 4 =item $obj-E<gt>B<DESTROY>() Inherited, see L<Mail::Reporter/"Cleanup"> =back =head1 DETAILS Extends L<"DETAILS" in Mail::Message::Field|Mail::Message::Field/"DETAILS">. =head1 DIAGNOSTICS =over 4 =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =item Warning: field content is not numerical: $content The numeric value of a field is requested (for instance the C<Lines> or C<Content-Length> fields should be numerical), however the data contains weird characters. Cast by C<toInt()> =item Error: field name too long (max $count), in '$name'. It is not specified in the RFCs how long a field name can be, but at least it should be a few characters shorter than the line wrap. Cast by C<fold()> =item Warning: illegal character in field name $name. A new field is being created which does contain characters not permitted by the RFCs. Using this field in messages may break other e-mail clients or transfer agents, and therefore mutulate or extinguish your message. Cast by C<consume()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Field/AddrGroup.pod����������������������������������������������0000644�0001750�0000144�00000016244�15166136117�023074� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Field::AddrGroup - A group of Mail::Message::Field::Address objects =head1 INHERITANCE Mail::Message::Field::AddrGroup is a User::Identity::Collection::Emails is a User::Identity::Collection is a User::Identity::Item =head1 SYNOPSIS my $g = Mail::Message::Field::AddrGroup->new(name => 'name'); my $a = Mail::Message::Field::Address->new(...); $g->addAddress($a); my $f = Mail::Message::Field::Addresses->new; $f->addGroup($g); =head1 DESCRIPTION An address group collects a set of e-mail addresses (in this case they are L<Mail::Message::Field::Address|Mail::Message::Field::Address> objects). Extends L<"DESCRIPTION" in User::Identity::Collection::Emails|User::Identity::Collection::Emails/"DESCRIPTION">. =head1 OVERLOADED Extends L<"OVERLOADED" in User::Identity::Collection::Emails|User::Identity::Collection::Emails/"OVERLOADED">. =over 4 =item overload: B<""> stringification Returns the L<string()|Mail::Message::Field::AddrGroup/"METHODS"> value. =item overload: B<'""'> stringification Inherited, see L<User::Identity::Collection/"OVERLOADED"> =item overload: B<'@{}'> array dereference Inherited, see L<User::Identity::Collection/"OVERLOADED"> =back =head1 METHODS Extends L<"METHODS" in User::Identity::Collection::Emails|User::Identity::Collection::Emails/"METHODS">. =over 4 =item $obj-E<gt>B<string>() Returns the address group as string. When no name is specified, it will only be a comma separated list of addresses. With a name, the groups name will be prepended and a semi-colon appended. When no addresses where included and there is no name, then C<undef> is returned. =back =head2 Constructors Extends L<"Constructors" in User::Identity::Collection::Emails|User::Identity::Collection::Emails/"Constructors">. =over 4 =item $obj-E<gt>B<coerce>($object) Coerce an C<$object> into a L<Mail::Message::Field::AddrGroup|Mail::Message::Field::AddrGroup>. Currently, you can only coerce L<User::Identity::Collection::Emails|User::Identity::Collection::Emails> (which is the base class for this one) into this one. =item $class-E<gt>B<new>( [$name], %options ) Inherited, see L<User::Identity::Collection::Emails/"Constructors"> =back =head2 Attributes Extends L<"Attributes" in User::Identity::Collection::Emails|User::Identity::Collection::Emails/"Attributes">. =over 4 =item $obj-E<gt>B<description>() Inherited, see L<User::Identity::Item/"Attributes"> =item $obj-E<gt>B<itemType>() Inherited, see L<User::Identity::Collection/"Attributes"> =item $obj-E<gt>B<name>( [$newname] ) Inherited, see L<User::Identity::Item/"Attributes"> =item $obj-E<gt>B<roles>() Inherited, see L<User::Identity::Collection/"Attributes"> =back =head2 Collections Extends L<"Collections" in User::Identity::Collection::Emails|User::Identity::Collection::Emails/"Collections">. =over 4 =item $obj-E<gt>B<add>($collection, $role) Inherited, see L<User::Identity::Item/"Collections"> =item $obj-E<gt>B<addCollection>( $object | <[$type], %options> ) Inherited, see L<User::Identity::Item/"Collections"> =item $obj-E<gt>B<collection>($name) Inherited, see L<User::Identity::Item/"Collections"> =item $obj-E<gt>B<parent>( [$parent] ) Inherited, see L<User::Identity::Item/"Collections"> =item $obj-E<gt>B<removeCollection>($object|$name) Inherited, see L<User::Identity::Item/"Collections"> =item $any-E<gt>B<type>() Inherited, see L<User::Identity::Item/"Collections"> =item $obj-E<gt>B<user>() Inherited, see L<User::Identity::Item/"Collections"> =back =head2 Maintaining roles Extends L<"Maintaining roles" in User::Identity::Collection::Emails|User::Identity::Collection::Emails/"Maintaining roles">. =over 4 =item $obj-E<gt>B<addRole>($role|([$name], %options)) Inherited, see L<User::Identity::Collection/"Maintaining roles"> =item $obj-E<gt>B<removeRole>($role|$name) Inherited, see L<User::Identity::Collection/"Maintaining roles"> =item $obj-E<gt>B<renameRole>( <$role|$oldname>, $newname ) Inherited, see L<User::Identity::Collection/"Maintaining roles"> =item $obj-E<gt>B<sorted>() Inherited, see L<User::Identity::Collection/"Maintaining roles"> =back =head2 Searching Extends L<"Searching" in User::Identity::Collection::Emails|User::Identity::Collection::Emails/"Searching">. =over 4 =item $obj-E<gt>B<find>($name|CODE|undef) Inherited, see L<User::Identity::Collection/"Searching"> =back =head2 Addresses =over 4 =item $obj-E<gt>B<addAddress>(STRING|$address|%options) Add one e-mail address to the list which is maintained in the group. This is a wrapper around L<addRole()|User::Identity::Collection/"Maintaining roles"> adding flexibility on how addresses are specified. An C<$address> can be anything which is acceptable for L<Mail::Message::Field::Address::coerce()|Mail::Message::Field::Address/"Constructors"> or a list of options which will create such an object. » example: of adding an address to an address group my @data = (full_name => "Myself", address => 'me@tux.org'); $group->addAddress(@data); my $addr = Mail::Message::Field::Address->new(@data); $group->addAddress(@data); my $ma = Mail::Address->new(...); $group->addAddress($ma); =item $obj-E<gt>B<addresses>() Returns all addresses defined in this group. The addresses will be ordered alphabetically to make automated testing possible: roles are stored in a hash, so have an unpredictable order by default. » example: getting all addresses from a group my @addrs = $group->addresses; my @addrs = map $_->address, $self->roles; #same =back =head2 Error handling =head1 DIAGNOSTICS =over 4 =item Error: cannot coerce a $type into a $class. Cast by C<coerce()> =item Error: cannot create a $type to add this to my collection. Some options are specified to create a C<$type> object, which is native to this collection. However, for some reason this failed. Cast by C<addRole()> =item Error: cannot load collection module for $type ($class): $@ Either the specified C<$type> does not exist, or that module named C<$class> returns compilation errors. If the type as specified in the warning is not the name of a package, you specified a nickname which was not defined. Maybe you forgot the 'require' the package which defines the nickname. Cast by C<addCollection()> =item Error: cannot rename $from into $to: already exists. Cast by C<renameRole()> =item Error: cannot rename $from into $to: doesn't exist. Cast by C<renameRole()> =item Error: invalid collection $name. The collection with C<$name> does not exist and can not be created. Cast by C<add()> =item Error: this $object is not a collection. Cast by C<addCollection()> =item Error: wrong type of role for $collection: requires a $expect but got a $type. Each C<$collection> groups sets of roles of one specific type (C<$expect>). You cannot add objects of a different C<$type>. Cast by C<addRole()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Field/Attribute.pod����������������������������������������������0000644�0001750�0000144�00000016331�15166136117�023145� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Field::Attribute - one attribute of a full field =head1 INHERITANCE Mail::Message::Field::Attribute is a Mail::Reporter =head1 SYNOPSIS my $field = $msg->head->get('Content-Disposition') or return; my $full = $field->study; # full understanding in unicode my $filename = $full->attribute('filename') or return; print ref $filename; # this class name print $filename; # the attributes content in utf-8 print $filename->value; # same print $filename->string; # print string as was found in the file $filename->print(\*OUT); # print as was found in the file =head1 DESCRIPTION Attributes within MIME fields can be quite complex, and therefore be slow and consumes a lot of memory. The L<Mail::Message::Field::Fast|Mail::Message::Field::Fast> and L<Mail::Message::Field::Flex|Mail::Message::Field::Flex> simplify them the attributes a lot, which may result in erroneous behavior in rare cases. With the increase of non-western languages on Internet, the need for the complex headers becomes more and more in demand. A C<Mail::Message::Field::Attribute> can be found in any structured L<Mail::Message::Field::Full|Mail::Message::Field::Full> header field. Extends L<"DESCRIPTION" in Mail::Reporter|Mail::Reporter/"DESCRIPTION">. =head1 OVERLOADED =over 4 =item overload: B<""> stringification Returns the decoded content of the attribute. =item overload: B<cmp> string comparison When the second argument is a field, then both attribute name (case-sensitive) and the decoded value must be the same. Otherwise, the value is compared. =back =head1 METHODS Extends L<"METHODS" in Mail::Reporter|Mail::Reporter/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Reporter|Mail::Reporter/"Constructors">. =over 4 =item $class-E<gt>B<new>( <$name, [$value] | STRING>, %options ) Create a new attribute C<$name> with the optional C<$value>. If no C<$value> is specified, the first argument of this method is inspected for an equals sign C<'='>. If that character is present, the argument is taken as C<STRING>, containing a preformatted attribute which is processed. Otherwise, the argument is taken as name without C<$value>: set the value later with value(). Whether encoding takes place depends on the C<%options> and the existence of non-ascii characters in the C<$value>. The C<$name> can only contain ascii characters, hence is never encoded. To speed things up, attributes are not derived from the L<Mail::Reporter|Mail::Reporter> base-class. Improves base, see L<Mail::Reporter/"Constructors"> -Option --Default charset 'us-ascii' language undef use_continuations <C<true>> =over 2 =item charset => STRING The C<$value> is translated from utf-8 (Perl internal) to this character set, and the resulting string is encoded if required. C<us-ascii> is the normal encoding for e-mail. Valid character sets can be found with C<Encode::encodings(':all')>. =item language => STRING RFC2231 adds the possibility to specify a language with the field. When no language is specified, none is included in the encoding. Valid language names are defined by RFC2130. This module has only limited support for this feature. =item use_continuations => BOOLEAN Continuations are used to break-up long parameters into pieces which are no longer than 76 characters. Encodings are specified in RFC2231, but not supported by some Mail User Agents. =back » example: my $fn = Mail::Message::Field::Attribute->new(filename => 'xyz'); my $fattr = 'Mail::Message::Field::Attribute'; # abbrev my $fn = $fattr->new( filename => "Re\xC7u", charset => 'iso-8859-15', language => 'nl-BE' ); print $fn; # --> filename*=iso-8859-15'nl-BE'Re%C7u =back =head2 Attributes Extends L<"Attributes" in Mail::Reporter|Mail::Reporter/"Attributes">. =head2 Error handling Extends L<"Error handling" in Mail::Reporter|Mail::Reporter/"Error handling">. =over 4 =item $obj-E<gt>B<AUTOLOAD>() Inherited, see L<Mail::Reporter/"Error handling"> =item $obj-E<gt>B<notImplemented>() Inherited, see L<Mail::Reporter/"Error handling"> =back =head2 Cleanup Extends L<"Cleanup" in Mail::Reporter|Mail::Reporter/"Cleanup">. =over 4 =item $obj-E<gt>B<DESTROY>() Inherited, see L<Mail::Reporter/"Cleanup"> =back =head2 The attribute =over 4 =item $obj-E<gt>B<addComponent>(STRING) A component is a parameter as defined by RFC2045, optionally using encoding or continuations as defined by RFC2231. Components of an attribute are found when a field is being parsed. The RFCs are very strict on valid characters, but we cannot be: you have to accept what is coming in if you can. » example: my $param = Mail::Message::Field::Attribute->new; $param->addComponent("filename*=iso10646'nl-BE'%Re\47u"); =item $obj-E<gt>B<charset>() Returns the character set which is used for this parameter. If any component is added which contains character set information, this is directly available. Be warned that a character-set is case insensitive. =item $obj-E<gt>B<language>() Returns the language which is defined in the argument. If no language is defined C<undef> is returned, which should be interpreted as "ANY" =item $obj-E<gt>B<name>() Returns the name of this attribute. =item $obj-E<gt>B<string>() When called in LIST context, the lines are returned to be post-processed one after the other. In SCALAR context, this returns the formatted attribute list. =item $obj-E<gt>B<value>( [STRING] ) Returns the value of this parameter, optionally after setting it first. =back =head2 Attribute encoding =over 4 =item $obj-E<gt>B<decode>() Translate all known continuations into a value. The produced value is returned and may be utf-8 encoded or a plain string. =item $obj-E<gt>B<encode>() Z<> =back =head2 Internals =over 4 =item $obj-E<gt>B<mergeComponent>($attribute) Merge the components from the specified attribute into this attribute. This is needed when components of the same attribute are created separately. Merging is required by the field parsing. =back =head1 DIAGNOSTICS =over 4 =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =item Warning: illegal character in parameter name '$name'. The specified parameter name contains characters which are not permitted by the RFCs. You can better change the name into something which is accepted, or risk applications to corrupt or ignore the message. Cast by C<new()> =item Error: too late to merge: value already changed. Cast by C<mergeComponent()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Construct/�������������������������������������������������������0000755�0001750�0000144�00000000000�15166136132�021430� 5����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Construct/Read.pod�����������������������������������������������0000644�0001750�0000144�00000007455�15166136117�023025� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Construct::Read - read a Mail::Message from a file handle =head1 SYNOPSIS my $msg1 = Mail::Message->read(\*STDIN); my $msg2 = Mail::Message->read(\@lines); =head1 DESCRIPTION When complex methods are called on a C<Mail::Message> object, this package is autoloaded to support the reading of messages directly from any file handle. =head1 METHODS =head2 Constructing a message =over 4 =item $class-E<gt>B<read>($fh|$text|\$text|\@lines, %options) Read a message from a C<$fh>, C<$text> string, reference to a text string, or an ARRAY of C<@lines>. Most C<%options> are passed to the L<new()|Mail::Message/"Constructors"> of the message which is created, but a few extra are defined. Please have a look at L<build()|Mail::Message::Construct::Build/"Constructing a message"> and L<buildFromBody()|Mail::Message::Construct::Build/"Constructing a message"> before thinking about this C<read> method. Use this C<read> only when you have a file-handle like STDIN to parse from, or some external source of message lines. When you already have a separate set of head and body lines, then C<read> is certainly B<not> your best choice. Some people use this method in a procmail script: the message arrives at stdin, so we only have a filehandle. In this case, you are stuck with this method. The message is preceded by a line which can be used as message separator in mbox folders. See the example how to handle that one. This method will remove C<Status> and C<X-Status> fields when they appear in the source, to avoid the risk that these fields accidentally interfere with your internal administration, which may have security implications. -Option --Default body_type undef parser_class undef seekable false strip_status_fields true trusted true =over 2 =item body_type => $type Force a body C<$type> (any specific extension of the L<Mail::Message::Body|Mail::Message::Body> class) to be used to store the message content. Multipart and nested message parts pick their own type. =item parser_class => $type Enforce a certain parser C<$type> to be used, which must be an extension of the L<Mail::Box::Parser|Mail::Box::Parser> class otherwise taken. =item seekable => BOOLEAN Indicate that a seekable file-handle has been passed. In this case, we can use the L<Mail::Box::Parser::Perl|Mail::Box::Parser::Perl> parser which reads messages directly from the input stream. =item strip_status_fields => BOOLEAN Remove the C<Status> and C<X-Status> fields from the message after reading, to lower the risk that received messages from external sources interfere with your internal administration. If you want fields not to be stripped (you would like to disable the stripping) you probably process folders yourself, which is a Bad Thing! =item trusted => BOOLEAN =back » example: my $msg1 = Mail::Message->read(\*STDIN); my $msg2 = Mail::Message->read(\@lines); $folder->addMessages($msg1, $msg2); my $msg3 = Mail::Message->read(<<MSG); Subject: hello world To: you@example.com # warning: empty line required !!! Hi, greetings! MSG # procmail example my $fromline = <STDIN>; my $msg = Mail::Message->read(\*STDIN); my $coerced = $mboxfolder->addMessage($msg); $coerced->fromLine($fromline); =back =head1 DIAGNOSTICS =over 4 =item Error: cannot read message from a $source. Cast by C<read()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Construct/Bounce.pm����������������������������������������������0000644�0001750�0000144�00000003205�15166136116�023203� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message;{ our $VERSION = '4.05'; } use strict; use warnings; use Log::Report 'mail-message', import => [ qw/__x error trace/ ]; use Mail::Message::Head::Complete (); use Mail::Message::Field (); #-------------------- sub bounce(@) { my $self = shift; my $bounce = $self->clone; my $head = $bounce->head; if(@_==1 && ref $_[0] && $_[0]->isa('Mail::Message::Head::ResentGroup' )) { $head->addResentGroup(shift); return $bounce; } my @rgs = $head->resentGroups; my $rg = $rgs[0]; if(defined $rg) { $rg->delete; # Remove group to re-add it later: otherwise while(@_) # field order in header would be disturbed. { my $field = shift; ref $field ? $rg->set($field) : $rg->set($field, shift); } } elsif(@_) { $rg = Mail::Message::Head::ResentGroup->new(@_); } else { error __x"method bounce requires To, Cc, or Bcc."; } $rg->set(Date => Mail::Message::Field->toDate) unless defined $rg->date; unless(defined $rg->messageId) { my $msgid = $head->createMessageId; $rg->set('Message-ID' => "<$msgid>"); } $head->addResentGroup($rg); # Flag action to original message $self->label(passed => 1); # used by some maildir clients $bounce; } 1; �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Construct/Rebuild.pod��������������������������������������������0000644�0001750�0000144�00000023735�15166136117�023537� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Construct::Rebuild - modify a Mail::Message =head1 SYNOPSIS my $cleanup = $msg->rebuild; =head1 DESCRIPTION Modifying existing messages is a pain, certainly if this has to be done in an automated fashion. The problems are especially had when multiparts have to be created or removed. The L<rebuild()|Mail::Message::Construct::Rebuild/"Constructing a message"> method tries to simplify this task and add some standard features. =head1 METHODS =head2 Constructing a message =over 4 =item $obj-E<gt>B<rebuild>(%options) Reconstruct an existing message into something new. Returned is a new message when there were modifications made, C<undef> if the message has no body left, or the original message when no modifications had to be made. Examples of use: you have a message which only contains html, and you want to translate it into a multipart which contains the original html and the textual translation of it. Or, you have a message with parts flagged to be deleted, and you want those changes be incorparted in the memory structure. Another possibility: clear all the resent groups (see L<Mail::Message::Head::ResentGroup|Mail::Message::Head::ResentGroup>) from the header, before it is written to file. Reconstructing is a hazardous task, where multi level multiparts and nested messages come into play. The rebuild method tries to simplify handing these messages for you. -Option --Default extra_rules [] keep_message_id false rules <see text> =over 2 =item extra_rules => ARRAY The standard set of rules, which is the default for the C<rules> option, is a moderest setting. In stead of copying that list into a full set of rules of your own, you can also specify only some additional rules which will be prependend to the default rule set. The order of the rules is respected, which means that you do not always need to rewrite the whole rule is (see C<rule> option). For instance, the extra rule of C<removeDeletedParts> returns an C<undef>, which means that it cancels the effect of the default rule C<replaceDeletedParts>. =item keep_message_id => BOOLEAN The message-id is an unique identification of the message: no two messages with different content shall exist anywhere. However in practice, when a message is changed during transmission, the id is often incorrectly not changed. This may lead to complications in application which see both messages with the same id. =item rules => ARRAY The ARRAY is a list of rules, which each describe an action which will be called on each part which is found in the message. Most rules probably won't match, but some will bring changes to the content. Rules can be specified as method name, or as code reference. See the L</DETAILS> chapter in this manual page, and L<recursiveRebuildPart()|Mail::Message::Construct::Rebuild/"Internals">. By default, only the relatively safe transformations are performed: C<replaceDeletedParts>, C<descendMultiparts>, C<descendNested>, C<flattenMultiparts>, C<flattenEmptyMultiparts>. In the future, more safe transformations may be added to this list. =back » example: # remove all deleted parts my $cleaned = $msg->rebuild(keep_message_id => 1); $folder->addMessage($cleaned) if defined $cleaned; # Replace deleted parts by a place-holder my $cleaned = $msg->rebuild( keep_message_id => 1, extra_rules => [ 'removeEmpty', 'flattenMultiparts' ], ); =back =head2 Internals =over 4 =item $obj-E<gt>B<recursiveRebuildPart>($part, %options) Z<> -Option--Default rules <required> =over 2 =item rules => \@rules Rules are method names which can be called on messages and message parts objects. The ARRAY can also list code references which can be called. In any case, each rule will be called the same way: $code->(MESSAGE, PART) The return can be C<undef> or any complex construct based on a L<Mail::Message::Part|Mail::Message::Part> or coerceable into such a part. For each part, all rules are called in sequence. When a rule returns a changed object, the rules will start all over again, however C<undef> will immediately stop it. =back =back =head1 DETAILS =head2 Rebuilding a message Modifying an existing message is a complicated job. Not only do you need to know what you are willing to change, but you have to take care about multiparts (possibly nested in multiple levels), rfc822 encapsulated messages, header field consistency, and so on. The L<rebuild()|Mail::Message::Construct::Rebuild/"Constructing a message"> method let you focus on the task, and takes care of the rest. The L<rebuild()|Mail::Message::Construct::Rebuild/"Constructing a message"> method uses rules to transform the one message into an other. If one or more of the rules apply, a new message will be returned. A simple numeric comparison tells whether the message has changed. For example print "No change" if $message == $message->rebuild; Transformation is made with a set of rules. Each rule performs only a small step, which makes is easily configurable. The rules are ordered, and when one makes a change to the result, the result will be passed to all the rules again until no rule makes a change on the part anymore. A rule may also return C<undef> in which case the part will be removed from the (resulting) message. =head3 General rules This sections describes the general configuration rules: all quite straight forward transformations on the message structure. The rules marked with (*) are used by default. =over 4 =item * descendMultiparts (*) Apply the rules to the parts of (possibly nested) multiparts, not only to the top-level message. =item * descendNested (*) Apply the rules to the C<message/rfc822> encapsulated message as well. =item * flattenEmptyMultiparts (*) Multipart messages which do not have any parts left are replaced by a single part which contains the preamble, epilogue and a brief explanation. =item * flattenMultiparts (*) When a multipart contains only one part, that part will take the place of the multipart: the removal of a level of nesting. This way, the preamble and epilogue of the multipart (which do not have a meaning, officially) are lost. =item * flattenNesting Remove the C<message/rfc822> encapsulation. Only the content related lines of the encapsulated body are preserved one level higher. Other information will be lost, which is often not too bad. =item * removeDeletedParts All parts which are flagged for deletion are removed from the message without leaving a trace. If a nested message is encountered which has its encapsulated content flagged for deletion, it will be removed as a whole. =item * removeEmptyMultiparts Multipart messages which do not have any parts left are removed. The information in preamble and epiloge is lost. =item * removeEmptyBodies Simple message bodies which do not contain any lines of content are removed. This will loose the information which is stored in the headers of these bodies. =item * replaceDeletedParts (*) All parts of the message which are flagged for deletion are replace by a message which says that the part is deleted. =back You can specify a selection of these rules with L<rebuild(rules)|Mail::Message::Construct::Rebuild/"Constructing a message"> and L<rebuild(extra_rules)|Mail::Message::Construct::Rebuild/"Constructing a message">. =head3 Conversion rules This section describes the rules which try to be smart with the content. Please contribute with ideas and implementations. =over 4 =item * removeHtmlAlternativeToText When a multipart alternative is encountered, which contains both a plain text and an html part, then the html part is deleted. Especially useful in combination with the C<flattenMultiparts> rule. =item * textAlternativeForHtml Any C<text/html> part which is not accompanied by an alternative plain text part will have one added. You must have a working L<Mail::Message::Convert::HtmlFormatText|Mail::Message::Convert::HtmlFormatText>, which means that HTML::TreeBuilder and HTML::FormatText must be installed on your system. When you are planning to create an automatic html to plain text filter for your email, then have a look at L<https://github.com/logological/mimestrip> =head4 » Example: using parameter with C<textAlternativeForHtml> my $result = $msg->rebuild( extra_rules => [ 'textAlternativeForHtml' ], textAlternativeForHtml => { leftmargin => 0 }, ); =item * removeExtraAlternativeText [2.110] When a multipart alternative is encountered, deletes all its parts except for the last part (the preferred part in accordance with RFC2046). In practice, this normally results in the alternative plain text part being deleted of an html message. Useful in combination with the C<flattenMultiparts> rule. =back =head3 Adding your own rules If you have designed your own rule, please consider contributing this to L<Mail::Box|Mail::Box>; it may be useful for other people as well. Each rule is called my $new = $code->($message, $part, %options) where the C<%options> are defined by the C<rebuild()> method internals. At least the C<rules> option is passed, which is a full expansion of all the rules which will be applied. Your subroutine shall return C<$part> if no changes are needed, C<undef> if the part should be removed, and any newly constructed C<Mail::Message::Part> when a change is required. It is easiest to start looking at the source code of this package, and copy from a comparible routine. When you have your own routine, you simply call: my $rebuild_message = $message->rebuild( extra_rules => [ \&my_own_rule, 'other_rule' ], ); =head1 DIAGNOSTICS =over 4 =item Error: no rebuild rule $name defined. Cast by C<rebuild()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. �����������������������������������Mail-Message-4.05/lib/Mail/Message/Construct/Text.pm������������������������������������������������0000644�0001750�0000144�00000003427�15166136116�022722� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message;{ our $VERSION = '4.05'; } use strict; use warnings; use Log::Report 'mail-message', import => [ qw// ]; use IO::Lines (); #-------------------- sub string() { my $self = shift; $self->head->string . $self->body->string . ($self->endsOnNewline ? '' : "\n"); } sub lines() { my $self = shift; my @lines; my $file = IO::Lines->new(\@lines); $self->print($file); wantarray ? @lines : \@lines; } sub file() { my $self = shift; my $file = IO::Lines->new; $self->print($file); $file->seek(0, 0); $file; } sub printStructure(;$$) { my $self = shift; my $indent = @_==2 ? pop : defined $_[0] && !ref $_[0] ? shift : ''; my $fh = @_ ? shift : select; my $buffer; # only filled if filehandle==undef open $fh, '>:raw', \$buffer unless defined $fh; my $subject = $self->get('Subject') || ''; $subject = ": $subject" if length $subject; my $type = $self->get('Content-Type', 0) || ''; my $size = $self->size; my $deleted = $self->label('deleted') ? ', deleted' : ''; my $text = "$indent$type$subject ($size bytes$deleted)\n"; $fh->print($text); my $body = $self->body; my @parts = $body->isNested ? ($body->nested) : $body->isMultipart ? $body->parts : (); $_->printStructure($fh, $indent.' ') for @parts; $buffer; } #-------------------- 1; �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Construct/Reply.pod����������������������������������������������0000644�0001750�0000144�00000020371�15166136117�023235� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Construct::Reply - reply to a Mail::Message =head1 SYNOPSIS my Mail::Message $reply = $message->reply; my $quoted = $message->replyPrelude($head->get('From')); =head1 DESCRIPTION Complex functionality on L<Mail::Message|Mail::Message> objects is implemented in different files which are autoloaded. This file implements the functionality related to creating message replies. =head1 METHODS =head2 Constructing a message =over 4 =item $obj-E<gt>B<reply>(%options) Start a reply to this message. Some of the header-lines of the original message will be taken. A message-id will be assigned. Some header lines will be updated to facilitate message-thread detection (see L<Mail::Box::Thread::Manager|Mail::Box::Thread::Manager>). You may reply to a whole message or a message part. You may wish to overrule some of the default header settings for the reply immediately, or you may do that later with C<set> on the header. Addresses may be specified as string, or a L<Mail::Address|Mail::Address> object, or as array of L<Mail::Address|Mail::Address> objects. All C<%options> which are not listed below AND start with a capital, will be added as additional headers to the reply message. -Option --Default Bcc undef Cc <'cc' in current> From <'to' in current> Message-ID <uniquely generated> Subject replySubject() To <sender in current> body undef group_reply true include 'INLINE' max_signature 10 message_type Mail::Message postlude undef prelude undef quote '> ' signature undef strip_signature qr/^--\s/ =over 2 =item Bcc => $body|$address|\@addresses Receivers of blind carbon copies: their names will not be published to other message receivers. =item Cc => $body|$address|\@addresses The carbon-copy receivers, by default a copy of the C<Cc> field of the source message. =item From => $body|$address|\@addresses Your identification, by default taken from the C<To> field of the source message. =item Message-ID => $field|$line Supply a C<$field> or C<$line> as specific message-id for the reply. By default, one is generated for you. If there are no angles around your id, they will be added. =item Subject => $field|$line|CODE Force the subject line to the specific C<$field> or C<$line>, or the result of the subroutine specified by CODE. The subroutine will be called passing the subject of the original message as only argument. By default, L<Mail::Message::replySubject()|Mail::Message::Construct::Reply/"Constructing a message"> is used. =item To => $body|$address|\@addresses The destination of your message. By default taken from the C<Reply-To> field in the source message. If that field is not present as well, the C<From> line is scanned. If they all fail, C<undef> is returned by this method: no reply message produced. =item body => $body Usually, the reply method can create a nice, sufficient message from the source message's body. In case you like more complicated reformatting, you may also create a body yourself first, and pass this on to this C<reply> method. Some of the other options to this method will be ignored in this case. =item group_reply => BOOLEAN Will the people listed in the C<Cc> headers (those who received the message where you reply to now) also receive this message as carbon copy? =item include => 'NO'|'INLINE'|'ATTACH' Must the message where this is a reply to be included in the message? If C<NO> then not. With C<INLINE> a reply body is composed. C<ATTACH> will create a multi-part body, where the original message is added after the specified body. It is only possible to inline textual messages, therefore binary or multipart messages will always be enclosed as attachment. =item max_signature => INTEGER Passed to C<stripSignature> on the body as parameter C<max_lines>. Only effective for single-part messages. =item message_type => CLASS Create a message with the requested type. By default, it will be a L<Mail::Message|Mail::Message>. This is correct, because it will be coerced into the correct folder message type when it is added to that folder. =item postlude => $body|\@lines The C<@lines> which to be added after the quoted reply lines. Create a body for it first. This should not include the signature, which has its own option. The signature will be added after the postlude when the reply is INLINEd. =item prelude => $body|\@lines The C<@lines> which will be added before the quoted reply lines. If nothing is specified, the result of the L<replyPrelude()|Mail::Message::Construct::Reply/"Constructing a message"> method is taken. When C<undef> is specified, no prelude will be added. =item quote => CODE|STRING Mangle the lines of an C<INLINE>d reply with CODE, or by prepending a STRING to each line. The routine specified by CODE is called when the line is in C<$_>. By default, C<'E<gt> '> is added before each line. Specify C<undef> to disable quoting. This option is processed after the body has been decoded. =item signature => $body|$message The signature to be added in case of a multi-part reply. The mime-type of the signature body should indicate this is a used as such. However, in INLINE mode, the body will be taken, a line containing C<'-- '> added before it, and added behind the epilogue. =item strip_signature => REGEXP|STRING|CODE Remove the signature of the sender. The value of this parameter is passed to L<Mail::Message::Body::stripSignature(pattern)|Mail::Message::Body::Construct/"Constructing a body"> unless the source text is not included. The signature is stripped from the message before quoting. When a multipart body is encountered, and the message is included to ATTACH, the parts which look like signatures will be removed. If only one message remains, it will be the added as single attachment, otherwise a nested multipart will be the result. The value of this option does not matter, as long as it is present. See L<Mail::Message::Body::Multipart|Mail::Message::Body::Multipart>. =back » example: my $reply = $msg->reply( prelude => "No spam, please!\n\n", postlude => "\nGreetings\n", strip_signature => 1, signature => $my_pgp_key, group_reply => 1, 'Message-ID' => $uuid, # don't forget the quotes 'X-Extra' => 'additional header', ); =item $obj-E<gt>B<replyPrelude>( [STRING|$field|$address|\@addrs|\@fields] ) Produces a LIST of lines (usually only one), which will preceed the quoted body of the message. C<STRING> must comply to the RFC822 email address specification, and is usually the content of a C<To> or C<From> header line. If a C<$field> is given, the field's body must be compliant. Without argument --or when the argument is C<undef>-- a slightly different line is produced. In case an ARRAY of C<@addrs> or C<@fields> is passed, the first one is taken. This simplified situations where multiple addresses are a allowed. » example: characteristic example of the output On Thu Oct 13 04:54:34 1995, him@example.com wrote: =item $any-E<gt>B<replySubject>(STRING) Create a subject for a message which is a reply for this one. This routine tries to count the level of reply in subject field, and transform it into a standard form. Please contribute improvements. » example: subject --> Re: subject Re: subject --> Re[2]: subject Re[X]: subject --> Re[X+1]: subject subject (Re) --> Re[2]: subject subject (Forw) --> Re[2]: subject <blank> --> Re: your mail =back =head1 DIAGNOSTICS =over 4 =item Error: cannot include reply source as $kind. Unknown alternative for the C<include> option of L<reply()|Mail::Message::Construct::Reply/"Constructing a message">. Valid choices are C<NO>, C<INLINE>, and C<ATTACH>. Cast by C<reply()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Construct/Rebuild.pm���������������������������������������������0000644�0001750�0000144�00000015644�15166136117�023371� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message;{ our $VERSION = '4.05'; } use strict; use warnings; use Log::Report 'mail-message', import => [ qw/__x error trace/ ]; use Mail::Message::Head::Complete (); use Mail::Message::Body::Lines (); use Mail::Message::Body::Multipart (); use Mail::Box::FastScalar (); use Mail::Address (); use Scalar::Util qw/blessed/; use List::Util qw/first/; #-------------------- my @default_rules = qw/replaceDeletedParts descendMultiparts descendNested flattenMultiparts flattenEmptyMultiparts/; sub rebuild(@) { my ($self, %args) = @_; my $keep = delete $args{keep_message_id}; # Collect the rules to be run my @rules = $args{rules} ? @{delete $args{rules}} : @default_rules; unshift @rules, @{delete $args{extra_rules}} if $args{extra_rules}; unshift @rules, @{delete $args{extraRules}} if $args{extraRules}; #old name foreach my $rule (@rules) { next if ref $rule; $self->can($rule) or error __x"no rebuild rule '{name}' defined.", name => $rule; } # Start off with the message my $rebuild = $self->recursiveRebuildPart($self, %args, rules => \@rules) or return; # Be sure we end-up with a message if($rebuild->isa('Mail::Message::Part')) { # a bit too much information is lost: we are left without the # main message headers.... my $clone = Mail::Message->new(head => $self->head->clone); $clone->body($rebuild->body); # to update the Content lines $rebuild = $clone; } $keep or $rebuild->takeMessageId; $rebuild; } # The general rules sub flattenNesting($@) { my ($self, $part) = @_; $part->isNested ? $part->body->nested : $part; } sub flattenMultiparts($@) { my ($self, $part) = @_; $part->isMultipart or return $part; my @active = $part->parts('ACTIVE'); @active==1 ? $active[0] : $part; } sub removeEmptyMultiparts($@) { my ($self, $part) = @_; $part->isMultipart && $part->body->parts==0 ? undef : $part; } sub flattenEmptyMultiparts($@) { my ($self, $part) = @_; $part->isMultipart && $part->parts('ACTIVE')==0 or return $part; my $body = $part->body; my $preamble = $body->preamble || Mail::Message::Body::Lines->new(data => ''); my $epilogue = $body->epilogue; my $newbody = $preamble->concatenate($preamble, <<NO_PARTS, $epilogue); * PLEASE NOTE: * This multipart did not contain any parts (anymore) * and was therefore flattened. NO_PARTS my $rebuild = Mail::Message::Part->new(head => $part->head->clone, container => undef); $rebuild->body($newbody); $rebuild; } sub removeEmptyBodies($@) { my ($self, $part) = @_; $part->body->lines==0 ? undef : $part; } sub descendMultiparts($@) { my ($self, $part, %args) = @_; return $part unless $part->isMultipart; my $body = $part->body; my $changed = 0; my @newparts; foreach my $part ($body->parts) { my $new = $self->recursiveRebuildPart($part, %args); if(!defined $new) { $changed++ } elsif($new==$part) { push @newparts, $part } else { push @newparts, $new; $changed++ } } $changed or return $part; my $newbody = ref($body)->new(based_on => $body, parts => \@newparts); my $rebuild = ref($part)->new(head => $part->head->clone, container => undef); $rebuild->body($newbody); # update Content-* lines $rebuild; } sub descendNested($@) { my ($self, $part, %args) = @_; $part->isNested or return $part; my $body = $part->body; my $srcnested = $body->nested; my $newnested = $self->recursiveRebuildPart($srcnested, %args); defined $newnested or return undef; return $part if $newnested==$srcnested; # Changes in the encapsulated message my $newbody = (ref $body)->new(based_on => $body, nested => $newnested); my $rebuild = (ref $part)->new(head => $part->head->clone, container => undef); $rebuild->body($newbody); $rebuild; } sub removeDeletedParts($@) { my ($self, $part) = @_; $part->isDeleted ? undef : $part; } sub replaceDeletedParts($@) { my ($self, $part) = @_; ($part->isNested && $part->body->nested->isDeleted) || $part->isDeleted or return $part; my $structure = ''; my $output = Mail::Box::FastScalar->new(\$structure); $part->printStructure($output); my $dispfn = $part->body->dispositionFilename || ''; Mail::Message::Part->build(data => "Removed content:\n\n$structure\n$dispfn"); } # The more complex rules sub removeHtmlAlternativeToText($@) { my ($self, $part) = @_; $part->body->mimeType eq 'text/html' or return $part; my $container = $part->container; defined $container && $container->mimeType eq 'multipart/alternative' or return $part; # The HTML $part will be nulled when a plain text part is found foreach my $subpart ($container->parts) { return undef if $subpart->body->mimeType eq 'text/plain'; } $part; } sub removeExtraAlternativeText($@) { my ($self, $part) = @_; my $container = $part->container; $container && $container->mimeType eq 'multipart/alternative' or return $part; # The last part is the preferred part (as per RFC2046) my $last = ($container->parts)[-1]; $last && $part==$last ? $part : undef; } my $has_hft; sub textAlternativeForHtml($@) { my ($self, $part, %args) = @_; my $hft = 'Mail::Message::Convert::HtmlFormatText'; unless(defined $has_hft) { eval "require $hft"; $has_hft = $hft->can('format'); } $has_hft && $part->body->mimeType eq 'text/html' or return $part; my $container = $part->container; my $in_alt = defined $container && $container->mimeType eq 'multipart/alternative'; return $part if $in_alt && first { $_->body->mimeType eq 'text/plain' } $container->parts; # Create the plain part my $html_body = $part->body; my $plain_body = $hft->new(%args)->format($html_body); my $plain_part = Mail::Message::Part->new(container => undef); $plain_part->body($plain_body); return $container->attach($plain_part) if $in_alt; # Recreate the html part to loose some header lines my $html_part = Mail::Message::Part->new(container => undef); $html_part->body($html_body); # Create the new part, with the headers of the html part my $mp = Mail::Message::Body::Multipart->new(mime_type => 'multipart/alternative', parts => [ $plain_part, $html_part ]); my $newpart = (ref $part)->new(head => $part->head->clone, container => undef); $newpart->body($mp); $newpart; } #-------------------- sub recursiveRebuildPart($@) { my ($self, $part, %args) = @_; RULES: foreach my $rule (@{$args{rules}}) { my %params = ( %args, %{$args{$rule} || {}} ); my $rebuild = $self->$rule($part, %params) or return undef; if($part != $rebuild) { $part = $rebuild; redo RULES; } } $part; } #-------------------- 1; ��������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Construct/Forward.pod��������������������������������������������0000644�0001750�0000144�00000035432�15166136117�023552� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Construct::Forward - forwarding a Mail::Message =head1 SYNOPSIS my Mail::Message $forward = $message->forward(To => 'you'); $forward->send; =head1 DESCRIPTION Complex functionality on L<Mail::Message|Mail::Message> objects is implemented in different files which are autoloaded. This file implements the functionality related to creating forwarded messages. =head1 METHODS =head2 Constructing a message =over 4 =item $obj-E<gt>B<forward>(%options) Forward the content of this message. The body of the message to be forwarded is encapsulated in some accompanying text (if you have no wish for that, than C<bounce> is your choice). A L<Mail::Message|Mail::Message> object is returned on success. You may forward a whole message, but also message parts. You may wish to overrule some of the default header settings for the reply immediately, or you may do that later with C<set> on the header. When a multi-part body is encountered, and the message is included to ATTACH, the parts which look like signatures will be removed. If only one message remains, it will be the added as single attachment, otherwise a nested multipart will be the result. The value of this option does not matter, as long as it is present. See C<Mail::Message::Body::Multipart>. -Option --Default Bcc undef Cc undef Date <now> From <'to' in current> Message-ID <uniquely generated> Subject forwardSubject() To <required> body undef include <if body then 'NO' else C<'INLINE'>> preamble constructed from prelude and postlude signature undef =over 2 =item Bcc => $field|$string|$address|\@addresses Receivers of blind carbon copies: their names will not be published to other message receivers. =item Cc => $field|$string|$address|\@addresses The carbon-copy receivers, by default none. =item Date => $field|$date The content of the Date field to be used in the message sent. By default, the correctly formatted timestamp of 'now' is added. =item From => $field|$string|$address|\@addresses Your identification, by default taken from the C<To> field of the source message. =item Message-ID => $msgid Supply a STRING as specific message-id for the forwarded message. By default, one is generated for you. If there are no angles around your id, they will be added. =item Subject => $field|$string|CODE Force the subject line to the specific C<$field>, C<$string>, or the result of the subroutine specified by CODE. The subroutine will be called passing the subject of the original message as only argument. By default, the L<forwardSubject()|Mail::Message::Construct::Forward/"Constructing a message"> method is used. =item To => $field|$string|$address|\@addresses The destination of your message. Obligatory. The addresses may be specified as string, a L<Mail::Address|Mail::Address> object, or as ARRAY of L<Mail::Address|Mail::Address> objects. =item body => $body If you specify a fully prepared C<$body> object, it will be used as forwarded message contents. In this case, only the headers are constructed for you. =item include => 'NO'|'INLINE'|'ATTACH'|'ENCAPSULATE' Must the message where this is a reply to be included in the message? When C<INLINE> is given, you may pass the options of L<forwardInline()|Mail::Message::Construct::Forward/"Constructing a message"> as well. In many applications, the forward option C<as attachment> results in a structure which is produced when this option is set to C<ENCAPSULATE>. Their default behavior is usually C<INLINE>. It is only possible to inline textual messages, therefore binary or multi-part messages will always be enclosed as attachment. Read the details in section L</Creating a forward>. =item preamble => $string|$body Part which is attached before the forwarded message. If no preamble is given, then it is constructed from the prelude and postlude. When these are also not present, you will still get a one liner: the result of L<forwardPrelude()|Mail::Message::Construct::Forward/"Constructing a message"> =item signature => $body|$message The signature to be added in case of a multi-part forward. The mime-type of the signature body should indicate this is a used as such. However, in INLINE mode, the body will be taken, a line containing C<'-- '> added before it, and added behind the epilogue. =back =item $obj-E<gt>B<forwardAttach>(%options) Forward the message as I<flat> attachment to the specified C<preamble>. You can specify all options available to C<forward()>, although a C<preamble> which is provided as body object is required, and any specified C<body> is ignored. -Option --Default preamble <required> =over 2 =item preamble => $body|$part =back =item $obj-E<gt>B<forwardEncapsulate>(%options) Like L<forwardAttach()|Mail::Message::Construct::Forward/"Constructing a message">, but in this case the original message is first encapsulated as nested message in a L<Mail::Message::Body::Nested|Mail::Message::Body::Nested>, and then joint into a multipart. You can specify all options available to C<forward()>, although a C<preamble> which is provided as body object is required, and any specified C<body> is ignored. Signatures are not stripped. Signatures are not stripped. -Option --Default preamble <required> =over 2 =item preamble => $body|$part =back =item $obj-E<gt>B<forwardInline>(%options) This method is equivalent in behavior to L<forward()|Mail::Message::Construct::Forward/"Constructing a message"> with the option C<include> set to C<'INLINE'>. You can specify most of the fields which are available to L<forward()|Mail::Message::Construct::Forward/"Constructing a message"> except C<include> and C<body>. -Option --Default is_attached "[The forwarded message is attached]\n" max_signature 10 postlude undef prelude undef quote undef strip_signature qr/^--\s/ =over 2 =item is_attached => $text A forward on binary messages can not be inlined. Therefore, they are automatically translated into an attachment, as made by L<forwardAttach()|Mail::Message::Construct::Forward/"Constructing a message">. The obligatory preamble option to that method may be specified as option to this method, to be used in case of such a forward of a binary, but is otherwise constructed from the prelude, the value of this option, and the postlude. =item max_signature => INTEGER Passed to L<Mail::Message::Body::stripSignature(max_lines)|Mail::Message::Body::Construct/"Constructing a body">. Only effective for single-part messages. =item postlude => $body The line(s) which to be added after the quoted reply lines. Create a body for it first. This should not include the signature, which has its own option. The signature will be added after the postlude when the forwarded message is C<INLINE>d. =item prelude => $body The line(s) which will be added before the quoted forwarded lines. If nothing is specified, the result of the L<forwardPrelude()|Mail::Message::Construct::Forward/"Constructing a message"> method is used. When C<undef> is specified, no prelude will be added. Be not confused with the C<preamble>, which specifies the whole first part of the constructed message: the prelude will become the start of such part. =item quote => CODE|$leader Mangle the lines of an C<INLINE>d reply with CODE, or by prepending a C<$leader> characters to each line. The routine specified by CODE is called when the line is in C<$_>. By default, nothing is added before each line. This option is processed after the body has been decoded. =item strip_signature => REGEXP|STRING|CODE Remove the signature of the sender. The value of this parameter is passed to L<Mail::Message::Body::stripSignature(pattern)|Mail::Message::Body::Construct/"Constructing a body">, unless the source text is not included. The signature is stripped from the message before quoting. =back =item $obj-E<gt>B<forwardNo>(%options) Construct a forward, where the whole body of the message is already constructed. That complex body is usually produced in L<forwardInline()|Mail::Message::Construct::Forward/"Constructing a message">, L<forwardAttach()|Mail::Message::Construct::Forward/"Constructing a message">, or L<forwardEncapsulate()|Mail::Message::Construct::Forward/"Constructing a message">. The C<%options> are the same as for C<forward()> except that C<body> is required. Some other options, like C<preamble>, are ignored. -Option--Default body <required> =over 2 =item body => $body =back =item $obj-E<gt>B<forwardPostlude>() Added after the forwarded message. » example: ---- END forwarded message =item $obj-E<gt>B<forwardPrelude>() Create a few lines to be included before the forwarded message content. The return is an array of lines. » example: ---- BEGIN forwarded message From: him@somewhere.else.nl (Original Sender) To: me@example.com (Me the receiver) Cc: the.rest@world.net Date: Wed, 9 Feb 2000 15:44:05 -0500 <blank line> =item $obj-E<gt>B<forwardSubject>(STRING) Create a subject for a message which is a forward from this one. This routine tries to count the level of reply in subject field, and transform it into a standard form. Please contribute improvements. » example: subject --> Forw: subject Re: subject --> Forw: Re: subject Re[X]: subject --> Forw: Re[X]: subject <blank> --> Forwarded =back =head1 DETAILS =head2 Creating a forward The main difference between L<bounce()|Mail::Message::Construct::Bounce/"Constructing a message"> and L<forward()|Mail::Message::Construct::Forward/"Constructing a message"> is the reason for message processing. The I<bounce> has no intention to modify the content of message: the same information is passed-on to someplace else. This may mean some conversions, but for instance, the Message-ID does not need to be changed. The purpose of I<forward()> is to pass on information which is modified: annotated or reduced. The information is not sent back to the author of the original message (which is implemented by L<reply()|Mail::Message::Construct::Reply/"Constructing a message">), but to someone else. So: some information comes in, is modified, and than forwarded to someone else. Currently, there are four ways to get the original information included, which are explained in the next sections. After the creation of the forward, you may want to L<rebuild()|Mail::Message::Construct::Rebuild/"Constructing a message"> the message to remove unnecessary complexities. Of course, that is not required. =head3 forward, specify a body When you specify L<forward(body)|Mail::Message::Construct::Forward/"Constructing a message">, you have created your own body object to be used as content of the forwarded message. This implies that L<forward(include)|Mail::Message::Construct::Forward/"Constructing a message"> is C<'NO'>: no automatic generation of the forwarded body. =head3 forward, inline the original The L<forward(include)|Mail::Message::Construct::Forward/"Constructing a message"> is set to C<'INLINE'> (the default) This is the most complicated situation, but most often used by MUAs: the original message is inserted textually in the new body. You can set-up automatic stripping of signatures, the way of encapsulation, and texts which should be added before and after the encapsulated part. However, the result may not always be what you expect. For instance, some people use very long signatures which will not be automatically stripped because the pass the threshold. So, you probably need some manual intervention after the message is created and before it is sent. When a binary message is encountered, inlining is impossible. In that case, the message is treated as if C<'ENCAPSULATE'> was requested. =head3 forward, attach the original When L<forward(include)|Mail::Message::Construct::Forward/"Constructing a message"> is explicitly set to C<'ATTACH'> the result will be a multipart which contains two parts. The first part will be your message, and the second the body of the original message. This means that the headers of the forwarded message are used for the new message, and detached from the part which now contains the original body information. Content related headers will (of course) still be part of that part, but lines line C<To> and C<Subject> will not be stored with that part. As example of the structural transformation: # code: $original->printStructure; multipart/alternative: The source message text/plain: content in raw text text/html: content as html # code: $fwd = $original->forward(include => 'ATTACH'); # code: $fwd->printStructure multipart/mixed: The source message text/plain: prelude/postlude/signature multipart/alternative text/plain: content in raw text text/html: content as html =head3 forward, encapsulate the original When L<forward(include)|Mail::Message::Construct::Forward/"Constructing a message"> is explicitly set to C<'ENCAPSULATE'>, then the original message is left in-tact as good as possible. The lines of the original message are used in the main message header but also enclosed in the part header. The encapsulation is implemented using a nested message, content type C<message/rfc822>. As example of the structural transformation: # code: $original->printStructure; multipart/alternative: The source message text/plain: content in raw text text/html: content as html # code: $fwd = $original->forward(include => 'ENCAPSULATE'); # code: $fwd->printStructure multipart/mixed: The source message text/plain: prelude/postlude/signature message/rfc822 multipart/alternative: The source message text/plain: content in raw text text/html: content as html The message structure is much more complex, but no information is lost. This is probably the reason why many MUAs use this when the forward an original message as attachment. =head1 DIAGNOSTICS =over 4 =item Error: Cannot include forward source as $kind. Unknown alternative for the L<forward(include)|Mail::Message::Construct::Forward/"Constructing a message">. Valid choices are C<NO>, C<INLINE>, C<ATTACH>, and C<ENCAPSULATE>. Cast by C<forward()> =item Error: method forwardAttach requires a preamble. Cast by C<forwardAttach()> =item Error: method forwardEncapsulate requires a preamble. Cast by C<forwardEncapsulate()> =item Error: method forwardNo requires a To. Cast by C<forwardNo()> =item Error: method forwardNo requires a body. Cast by C<forwardNo()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Construct/Read.pm������������������������������������������������0000644�0001750�0000144�00000004442�15166136116�022647� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message;{ our $VERSION = '4.05'; } use strict; use warnings; use Log::Report 'mail-message', import => [ qw/__x error warning/ ]; use Mail::Box::Parser::Lines (); use Scalar::Util qw/blessed/; #-------------------- sub _scalar2lines($) { my $lines = [ split /^/, ${$_[0]} ]; # pop @$lines if @$lines && ! length $lines->[-1]; $lines; } sub read($@) { # try avoiding copy of large strings my ($class, undef, %args) = @_; my $trusted = exists $args{trusted} ? $args{trusted} : 1; my $strip_status = exists $args{strip_status_fields} ? delete $args{strip_status_fields} : 1; my $body_type = $args{body_type}; my $pclass = $args{parser_class}; my $parser; my $ref = ref $_[1]; if($args{seekable}) { $parser = ($pclass // 'Mail::Box::Parser::Perl') ->new(%args, filename => "file ($ref)", file => $_[1], trusted => $trusted); } else { my ($source, $lines); if(!$ref) { $source = 'scalar'; $lines = _scalar2lines \$_[1]; } elsif($ref eq 'SCALAR') { $source = 'ref scalar'; $lines = _scalar2lines $_[1]; } elsif($ref eq 'ARRAY') { $source = 'array of lines'; $lines = $_[1]; } elsif($ref eq 'GLOB' || (blessed $_[1] && $_[1]->isa('IO::Handle'))) { $source = "file ($ref)"; local $/ = undef; # slurp $lines = _scalar2lines \$_[1]->getline; } else { error __x"cannot read message from a {source}.", source => $_[1]/$ref; return undef; } $parser = ($pclass // 'Mail::Box::Parser::Lines') ->new(%args, source => $source, lines => $lines, trusted => $trusted); $body_type = 'Mail::Message::Body::Lines'; } my $self = $class->new(%args); $self->readFromParser($parser, $body_type); $parser->stop; my $head = $self->head; $head->set('Message-ID' => '<'.$self->messageId.'>') unless $head->get('Message-ID'); $head->delete('Status', 'X-Status') if $strip_status; $self; } 1; ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Construct/Bounce.pod���������������������������������������������0000644�0001750�0000144�00000006176�15166136117�023364� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Construct::Bounce - bounce a Mail::Message =head1 SYNOPSIS $message->bounce(To => 'you')->send; =head1 DESCRIPTION Complex functionality on L<Mail::Message|Mail::Message> objects is implemented in different files which are autoloaded. This file implements the functionality related to bouncing messages off to other destinations. B<Be warned:> bouncing messages was very common practice in the past, but does not play well together with SPF spam protection. Unless you bounce messages which originate from inside your own infrastructure, you may get the message rejected by the spam-filters of the receivers. The way around it, is to implement ARC... which the MailBox suite did not try (yet). =head1 METHODS =head2 Constructing a message =over 4 =item $obj-E<gt>B<bounce>( [<$rg_object|%options>] ) The program calling this method considers itself as an intermediate step in the message delivery process; it therefore leaves a resent group of header fields as trace. When a message is received, the Mail Transfer Agent (MTA) adds a C<Received> field to the header. As C<%options>, you may specify lines which are added to the resent group of that received field. C<Resent-*> is prepended before the field-names automatically, unless already present. You may also specify an instantiated L<Mail::Message::Head::ResentGroup|Mail::Message::Head::ResentGroup> (RG) object. See L<Mail::Message::Head::ResentGroup::new()|Mail::Message::Head::ResentGroup/"METHODS"> for the available options. This is required if you want to add a new resent group: create a new C<Received> line in the header as well. If you are planning to change the body of a bounce message, don't! Bounced messages have the same message-id as the original message, and therefore should have the same content (message-ids are universally unique). If you still insist, use L<Mail::Message::body()|Mail::Message/"The body">. » example: my $bounce = $folder->message(3)->bounce(To => 'you', Bcc => 'everyone'); $bounce->send; $outbox->addMessage($bounce); my $rg = Mail::Message::Head::ResentGroup->new(To => 'you', Received => 'from ... by ...'); $msg->bounce($rg)->send; =back =head1 DIAGNOSTICS =over 4 =item Error: method bounce requires To, Cc, or Bcc. The message L<bounce()|Mail::Message::Construct::Bounce/"Constructing a message"> method forwards a received message off to someone else without modification; you must specified it's new destination. If you have the urge not to specify any destination, you probably are looking for L<reply()|Mail::Message::Construct::Reply/"Constructing a message">. When you wish to modify the content, use L<forward()|Mail::Message::Construct::Forward/"Constructing a message">. Cast by C<bounce()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Construct/Forward.pm���������������������������������������������0000644�0001750�0000144�00000013771�15166136116�023405� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message;{ our $VERSION = '4.05'; } use strict; use warnings; use Log::Report 'mail-message', import => [ qw/__x error info trace/ ]; use Mail::Message::Body::Multipart (); use Mail::Message::Body::Nested (); use Scalar::Util qw/blessed/; #-------------------- # tests in t/57forw1f.t sub forward(@) { my $self = shift; my %args = @_; return $self->forwardNo(@_) if exists $args{body}; my $include = $args{include} || 'INLINE'; return $self->forwardInline(@_) if $include eq 'INLINE'; my $preamble = $args{preamble}; push @_, preamble => Mail::Message::Body->new(data => $preamble) if defined $preamble && ! ref $preamble; return $self->forwardAttach(@_) if $include eq 'ATTACH'; return $self->forwardEncapsulate(@_) if $include eq 'ENCAPSULATE'; error __x"cannot include forward source as {kind UNKNOWN}.", kind => $include; } sub forwardNo(@) { my ($self, %args) = @_; my $body = $args{body} or error __x"method forwardNo requires a body."; my $to = $args{To} or error __x"method forwardNo requires a To."; # # Collect header info # my $mainhead = $self->toplevel->head; # Where it comes from my $from = $args{From}; unless(defined $from) { my @from = $self->to; $from = \@from if @from; } # Create a subject my $srcsub = $args{Subject}; my $subject = ! defined $srcsub ? $self->forwardSubject($self->subject) : ref $srcsub ? $srcsub->($self->subject) : $srcsub; # Create a nice message-id my $msgid = $args{'Message-ID'} || $mainhead->createMessageId; $msgid = "<$msgid>" if $msgid && $msgid !~ /^\s*\<.*\>\s*$/; # Thread information my $origid = '<'.$self->messageId.'>'; my $refs = $mainhead->get('references'); my $forward = Mail::Message->buildFromBody( $body, From => ($from || '(undisclosed)'), To => $to, Subject => $subject, References => ($refs ? "$refs $origid" : $origid), ); my $newhead = $forward->head; $newhead->set(Cc => $args{Cc} ) if $args{Cc}; $newhead->set(Bcc => $args{Bcc} ) if $args{Bcc}; $newhead->set(Date => $args{Date}) if $args{Date}; # Ready $self->label(passed => 1); trace "Forward created from $origid"; $forward; } sub forwardInline(@) { my ($self, %args) = @_; my $body = $self->body; while(1) # simplify { if($body->isMultipart && $body->parts==1) { $body = $body->part(0)->body } elsif($body->isNested) { $body = $body->nested->body } else { last } } # Prelude must be a real body, otherwise concatenate will not work my $prelude = exists $args{prelude} ? $args{prelude} : $self->forwardPrelude; $prelude = Mail::Message::Body->new(data => $prelude) if defined $prelude && ! blessed $prelude; # Postlude my $postlude = exists $args{postlude} ? $args{postlude} : $self->forwardPostlude; # Binary bodies cannot be inlined, therefore they will be rewritten # into a forwardAttach... preamble must replace prelude and postlude. if($body->isMultipart || $body->isBinary) { $args{preamble} ||= $prelude->concatenate( $prelude, ($args{is_attached} || "[The forwarded message is attached]\n"), $postlude, ); return $self->forwardAttach(%args); } $body = $body->decoded; if((!exists $args{strip_signature} || $args{strip_signature}) && !$body->isNested) { $body = $body->stripSignature(pattern => $args{strip_signature}, max_lines => $args{max_signature}); } if(defined(my $quote = $args{quote})) { my $quoting = ref $quote ? $quote : sub { $quote . $_ }; $body = $body->foreachLine($quoting); } # # Create the message. # my $signature = $args{signature}; $signature = $signature->body if defined $signature && $signature->isa('Mail::Message'); my $composed = $body->concatenate( $prelude, $body, $postlude, (defined $signature ? "-- \n" : undef), $signature ); $self->forwardNo(%args, body => $composed); } sub forwardAttach(@) { my ($self, %args) = @_; my $body = $self->body; if($body->isMultipart) { $body = $body->stripSignature(pattern => $args{strip_signature}, max_lines => $args{max_signature}) if !exists $args{strip_signature} || $args{strip_signature}; $body = $body->part(0)->body if $body->parts == 1; } my $preamble = $args{preamble} or error __x"method forwardAttach requires a preamble."; my @parts = ($preamble, $body); push @parts, $args{signature} if defined $args{signature}; my $multi = Mail::Message::Body::Multipart->new(parts => \@parts); $self->forwardNo(%args, body => $multi); } sub forwardEncapsulate(@) { my ($self, %args) = @_; my $preamble = $args{preamble} or error __x"method forwardEncapsulate requires a preamble."; my $nested = Mail::Message::Body::Nested->new(nested => $self->clone); my @parts = ($preamble, $nested); push @parts, $args{signature} if defined $args{signature}; my $multi = Mail::Message::Body::Multipart->new(parts => \@parts); $self->forwardNo(%args, body => $multi); } # tests in t/57forw0s.t sub forwardSubject($) { my ($self, $subject) = @_; defined $subject && length $subject ? "Forw: $subject" : "Forwarded"; } sub forwardPrelude() { my $head = shift->head; my @lines = "---- BEGIN forwarded message\n"; my $from = $head->get('from'); my $to = $head->get('to'); my $cc = $head->get('cc'); my $date = $head->get('date'); push @lines, $from->string if defined $from; push @lines, $to->string if defined $to; push @lines, $cc->string if defined $cc; push @lines, $date->string if defined $date; push @lines, "\n"; \@lines; } sub forwardPostlude() { my $self = shift; [ "---- END forwarded message\n" ]; } #-------------------- 1; �������Mail-Message-4.05/lib/Mail/Message/Construct/Build.pm�����������������������������������������������0000644�0001750�0000144�00000010452�15166136116�023031� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message;{ our $VERSION = '4.05'; } use strict; use warnings; use Log::Report 'mail-message', import => [ qw/__x error info warning/ ]; use Mail::Message::Head::Complete (); use Mail::Message::Body::Lines (); use Mail::Message::Body::Multipart (); use Mail::Message::Body::Nested (); use Mail::Message::Field (); use Mail::Address (); use Scalar::Util qw/blessed/; #-------------------- sub build(@) { my $class = shift; ! $class->isa('Mail::Box::Message') or error __x"only build() Mail::Message's; they are not in a folder yet."; my @parts = ! blessed $_[0] ? () : $_[0]->isa('Mail::Message') ? shift : $_[0]->isa('Mail::Message::Body') ? shift : (); my ($head, @headerlines); my ($type, $transfenc, $dispose, $descr, $cid, $lang); while(@_) { my $key = shift; if(blessed $key && $key->isa('Mail::Message::Field')) { my $name = $key->name; if($name eq 'content-type') { $type = $key } elsif($name eq 'content-transfer-encoding') { $transfenc = $key } elsif($name eq 'content-disposition') { $dispose = $key } elsif($name eq 'content-description') { $descr = $key } elsif($name eq 'content-language') { $lang = $key } elsif($name eq 'content-id') { $cid = $key } else { push @headerlines, $key } next; } my $value = shift // next; my @data; if($key eq 'head') { $head = $value } elsif($key eq 'data') { @data = Mail::Message::Body->new(data => $value) } elsif($key eq 'file' || $key eq 'files') { @data = map Mail::Message::Body->new(file => $_), ref $value eq 'ARRAY' ? @$value : $value; } elsif($key eq 'attach') { foreach my $c (ref $value eq 'ARRAY' ? @$value : $value) { defined $c or next; push @data, blessed $c && $c->isa('Mail::Message') ? Mail::Message::Body::Nested->new(nested => $c) : $c; } } elsif($key =~ m/^content\-(type|transfer\-encoding|disposition|language|description|id)$/i ) { my $k = lc $1; my $field = Mail::Message::Field->new($key, $value); if($k eq 'type') { $type = $field } elsif($k eq 'disposition') { $dispose = $field } elsif($k eq 'description') { $descr = $field } elsif($k eq 'language') { $lang = $field } elsif($k eq 'id') { $cid = $field } else { $transfenc = $field } } elsif($key =~ m/^[A-Z]/) { push @headerlines, $key, $value } else { warning __x"skipped unknown key '{key}' in build.", key => $key; } push @parts, grep defined, @data; } my $body = @parts==0 ? Mail::Message::Body::Lines->new : @parts==1 ? $parts[0] : Mail::Message::Body::Multipart->new(parts => \@parts); # Setting the type explicitly, only after the body object is finalized $body->type($type) if defined $type; $body->disposition($dispose) if defined $dispose; $body->description($descr) if defined $descr; $body->language($lang) if defined $lang; $body->contentId($cid) if defined $cid; $body->transferEncoding($transfenc) if defined $transfenc; $class->buildFromBody($body, $head, @headerlines); } sub buildFromBody(@) { my ($class, $body) = (shift, shift); my $head; if(blessed $_[0] && $_[0]->isa('Mail::Message::Head')) { $head = shift } else { defined $_[0] or shift; # explicit undef as head $head = Mail::Message::Head::Complete->new; } while(@_) { if(blessed $_[0]) { $head->add(shift) } else { $head->add(shift, shift) } } my $message = $class->new(head => $head); $message->body($body); # be sure the message-id is actually stored in the header. defined $head->get('message-id') or $head->add('Message-Id' => '<'.$message->messageId.'>'); defined $head->get('Date') or $head->add(Date => Mail::Message::Field->toDate); defined $head->get('MIME-Version') or $head->add('MIME-Version' => '1.0'); # required by rfc2045 $message; } #-------------------- 1; ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Construct/Build.pod����������������������������������������������0000644�0001750�0000144�00000024274�15166136117�023207� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Construct::Build - building a Mail::Message from components =head1 SYNOPSIS my $msg1 = Mail::Message->build( From => 'me', data => "only two\nlines\n", ); my $msg2 = Mail::Message->buildFromBody($body); Mail::Message->build( From => 'me@myhost.com', To => 'you@yourhost.com', Subject => "Read our folder!", data => \@lines, file => 'folder.pdf', )->send(via => 'postfix'); =head1 DESCRIPTION Complex functionality on L<Mail::Message|Mail::Message> objects is implemented in different files which are autoloaded. This file implements the building of messages from various simpler components. =head1 METHODS =head2 Constructing a message =over 4 =item $class-E<gt>B<build>( [$message|$part|$body], @fields, %options ) Simplified message object builder. In case a C<$message> or message C<$part> is specified, a new message is created with the same body to start with, but new headers. A C<$body> may be specified as well. However, there are more ways to add data simply. You may pass C<@fields> as objects, even mixed with option PAIRS. The fields will be transmitted in the order they were created, so that might be needed. In the C<%options> LIST of paris, all keys which start with a capital are used as header-lines. Lower-cased fields are used for other purposes as listed below. Each field may be used more than once. Pairs where the value is C<undef> are ignored. If more than one C<data>, C<file>, and C<attach> is specified, a multi-parted message is created. Some C<Content-*> fields are treated separately: to enforce the content lines of the produced message body B<after> it has been created. For instance, to explicitly state that you wish a C<multipart/alternative> in stead of the default C<multipart/mixed>. If you wish to specify the type per datum, you need to start playing with L<Mail::Message::Body|Mail::Message::Body> objects yourself. This C<build> method will use L<buildFromBody()|Mail::Message::Construct::Build/"Constructing a message"> when the body object has been constructed. Together, they produce your message. -Option--Default attach undef data undef file undef files [ ] head undef =over 2 =item attach => $body|$part|$message|\@attach One attachment to the message. Each attachment can be full C<$message>, a C<$part>, or a C<$body>. Any C<$message> will get encapsulated into a C<message/rfc822> body. You can specify many items (may be of different types) at once. attach => $folder->message(3)->decoded # body attach => $folder->message(3) # message attach => [ $msg1, $msg2->part(6), $msg3->body ]; =item data => $text|\@lines The C<$text> for one part, specified as one string, or an ARRAY of C<@lines>. Each line, including the last, must be terminated by a newline. This argument is passed to L<Mail::Message::Body::new(data)|Mail::Message::Body/"Constructors"> to construct one. data => [ "line 1\n", "line 2\n" ] # array of lines data => <<'TEXT' # string line 1 line 2 TEXT =item file => $file|$fh|$io|\@files Create a body where the data is read from the specified C<$file> by name, filehandle C<$fh>, or C<$io> object of type IO::Handle. Also this body is used to create a L<Mail::Message::Body|Mail::Message::Body>. [2.119] You may even pass more than one file at once: 'file' and 'files' option are equivalent. my $in = IO::File->new('/etc/passwd', 'r'); file => 'picture.jpg' # filename file => $fh # IO::File or GLOB files => [ 'picture.jpg', $fh ] =item files => \@files Alias for option C<file>. =item head => $head Start with a prepared header, otherwise one is created. =back » example: my $msg = Mail::Message->build( From => 'me@home.nl', To => Mail::Address->new('your name', 'you@yourplace.aq'), Cc => 'everyone@example.com', Subject => "Let's talk",, $other_message->get('Bcc'), data => [ "This is\n", "the first part of\n", "the message\n" ], file => 'myself.gif', file => 'you.jpg', attach => $signature, ); my $msg = Mail::Message->build( To => 'you', 'Content-Type' => 'text/html', data => "<html></html>", ); =item $class-E<gt>B<buildFromBody>($body, [$head], $headers) Shape a message around a C<$body>. Bodies have information about their content in them, which is used to construct a header for the message. You may specify a C<$head> object which is pre-initialized, or one is created for you (also when C<$head> is C<undef>). Next to that, more C<$headers> can be specified which are stored in that header. Header fields are added in order, and before the header lines as defined by the body are taken. They may be supplied as key-value pairs or L<Mail::Message::Field|Mail::Message::Field> objects. In case of a key-value pair, the field's name is to be used as key and the value is a string, address (L<Mail::Address|Mail::Address> object), or array of addresses. A C<Date>, C<Message-Id>, and C<MIME-Version> field are added unless supplied. » example: my $type = Mail::Message::Field->new('Content-Type', 'text/html', 'charset="us-ascii"'); my @to = ( Mail::Address->new('Your name', 'you@example.com'), 'world@example.info', ); my $msg = Mail::Message->buildFromBody($body, From => 'me@example.nl', To => \@to, $type, ); =back =head1 DETAILS =head2 Building a message =head3 Rapid building Most messages you need to construct are relatively simple. MailBox tries to keep the message content immutable: only the administration around the message may change. Therefore: the only way to create a message is by specifying all content and header fields in one method call. =head3 Compared to MIME::Entity::build() The C<build> method in MailBox is modelled after the C<build> method as provided by MIMETools, but with a few simplifications: =over 4 =item * When a keys starts with a capital, than it is always a header field =item * When a keys is lower-cased, it is always something else =item * You use the real field-names, not abbreviations =item * All field names are accepted =item * You may specify field objects between key-value pairs =item * A lot of facts are auto-detected, like content-type and encoding =item * You can create a multipart at once =back Hum, reading the list above... what is equivalent? L<MIME::Entity> is not that simple after all! Let's look at an example from MIME::Entity's manual page: ### Create the top-level, and set up the mail headers: $top = MIME::Entity->build( Type => "multipart/mixed", From => 'me@myhost.com', To => 'you@yourhost.com', Subject => "Hello, nurse!", ); ### Attachment #1: a simple text document: $top->attach(Path=>"./testin/short.txt"); ### Attachment #2: a GIF file: $top->attach( Path => "./docs/mime-sm.gif", Type => "image/gif", Encoding => "base64", ); ### Attachment #3: text we'll create with text we have on-hand: $top->attach(Data => $contents); The MailBox equivalent could be my $msg = Mail::Message->build( From => 'me@myhost.com', To => 'you@yourhost.com', Subject => "Hello, nurse!", file => "./testin/short.txt", file => "./docs/mime-sm.gif", data => $contents, ); One of the simplifications is that L<MIME::Types|MIME::Types> is used to lookup the right content type and optimal transfer encoding based on L<MIME::Types|MIME::Types> knowledge. Suitable values for Content-Disposition and such fields are added as well. =head3 build, starting with nothing See L<build()|Mail::Message::Construct::Build/"Constructing a message">. =head3 buildFromBody, body becomes message See L<buildFromBody()|Mail::Message::Construct::Build/"Constructing a message">. =head3 The Content-* fields The various C<Content-*> fields are not as harmless as they look. For instance, the "Content-Type" field will have an effect on the default transfer encoding. When a message is built this way: my $msg = Mail::Message->build( 'Content-Type' => 'video/mpeg3', 'Content-Transfer-Encoding' => 'base64', 'Content-Disposition' => 'attachment', file => '/etc/passwd', ); then first a C<text/plain> body is constructed (L<MIME::Types|MIME::Types> does not find an extension on the filename so defaults to C<text/plain>), with no encoding. Only when that body is ready, the new type and requested encodings are set. The content of the body will get base64 encoded, because it is requested that way. What basically happens is this: my $head = ...other header lines...; my $body = Mail::Message::Body::Lines->new(file => '/etc/passwd'); $body->type('video/mpeg3'); $body->transferEncoding('base64'); $body->disposition('attachment'); my $msg = Mail::Message->buildFromBody($body, $head); A safer way to construct the message is: my $body = Mail::Message::Body::Lines->new( file => '/etc/passwd', mime_type => 'video/mpeg3', transfer_encoding => 'base64', disposition => 'attachment', ); my $msg = Mail::Message->buildFromBody( $body, ...other header lines... ); In the latter program, you will immediately start with a body of the right type. =head1 DIAGNOSTICS =over 4 =item Error: only build() Mail::Message's; they are not in a folder yet. You may wish to construct a message to be stored in a some kind of folder, but you need to do that in two steps. First, create a normal L<Mail::Message|Mail::Message>, and then add it to the folder. During this L<Mail::Box::addMessage()|Mail::Box/"The folder"> process, the message will get L<coerce()|Mail::Message/"Internals">-d into the right message type, adding storage information and the like. Cast by C<build()> =item Warning: skipped unknown key '$key' in build. Cast by C<build()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Construct/Reply.pm�����������������������������������������������0000644�0001750�0000144�00000013252�15166136116�023066� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message;{ our $VERSION = '4.05'; } use strict; use warnings; use Log::Report 'mail-message', import => [ qw/__x error info trace/ ]; use Mail::Message::Body::Multipart (); use Mail::Address (); use Scalar::Util qw/blessed/; #-------------------- # tests in t/55reply1r.t, demo in the examples/ directory sub reply(@) { my ($self, %args) = @_; my $body = $args{body}; my $strip = !exists $args{strip_signature} || $args{strip_signature}; my $include = $args{include} || 'INLINE'; if($include eq 'NO') { # Throw away real body. $body //= Mail::Message::Body->new(data => ["\n[The original message is not included]\n\n"]); } elsif($include eq 'INLINE' || $include eq 'ATTACH') { unless(defined $body) { # text attachment $body = $self->body; $body = $body->part(0)->body if $body->isMultipart && $body->parts==1; $body = $body->nested->body if $body->isNested; $body = $strip && ! $body->isMultipart && !$body->isBinary ? $body->decoded->stripSignature(pattern => $args{strip_signature}, max_lines => $args{max_signature}) : $body->decoded; } if($include eq 'INLINE' && $body->isMultipart) { $include = 'ATTACH' } elsif($include eq 'INLINE' && $body->isBinary) { $include = 'ATTACH'; $body = Mail::Message::Body::Multipart->new(parts => [$body]); } if($include eq 'INLINE') { my $quote = defined $args{quote} ? $args{quote} : exists $args{quote} ? undef : '> '; if(defined $quote) { my $quoting = ref $quote ? $quote : sub { $quote . $_ }; $body = $body->foreachLine($quoting); } } } else { error __x"cannot include reply source as {kind}.", kind => $include; } # # Collect header info # my $mainhead = $self->toplevel->head; # Where it comes from my $from = delete $args{From}; unless(defined $from) { my @from = $self->to; $from = \@from if @from; } # To whom to send my $to = delete $args{To} || $mainhead->get('reply-to') || $mainhead->get('from'); defined $to or return; # Add Cc my $cc = delete $args{Cc}; if(!defined $cc && $args{group_reply}) { my @cc = $self->cc; $cc = [ $self->cc ] if @cc; } # Create a subject my $srcsub = delete $args{Subject}; my $subject = ! defined $srcsub ? $self->replySubject($self->subject) : ref $srcsub ? $srcsub->($self->subject) : $srcsub; # Create a nice message-id my $msgid = delete $args{'Message-ID'}; $msgid = "<$msgid>" if $msgid && $msgid !~ /^\s*\<.*\>\s*$/; # Thread information my $origid = '<'.$self->messageId.'>'; my $refs = $mainhead->get('references'); # Prelude my $prelude = defined $args{prelude} ? $args{prelude} : exists $args{prelude} ? undef : [ $self->replyPrelude($to) ]; $prelude = Mail::Message::Body->new(data => $prelude) if defined $prelude && ! blessed $prelude; my $postlude = $args{postlude}; $postlude = Mail::Message::Body->new(data => $postlude) if defined $postlude && ! blessed $postlude; # # Create the message. # my $total; if($include eq 'NO') {$total = $body} elsif($include eq 'INLINE') { my $signature = $args{signature}; $signature = $signature->body if defined $signature && $signature->isa('Mail::Message'); $total = $body->concatenate($prelude, $body, $postlude, (defined $signature ? "-- \n$signature" : undef)); } elsif($include eq 'ATTACH') { my $intro = $prelude->concatenate($prelude, ["\n", "[Your message is attached]\n"], $postlude); $total = Mail::Message::Body::Multipart->new(parts => [ $intro, $body, $args{signature} ]); } my $msgtype = $args{message_type} || 'Mail::Message'; my $reply = $msgtype->buildFromBody( $total, From => $from || 'Undisclosed senders:;', To => $to, Subject => $subject, 'In-Reply-To' => $origid, References => ($refs ? "$refs $origid" : $origid), ); my $newhead = $reply->head; $newhead->set(Cc => $cc) if $cc; $newhead->set(Bcc => delete $args{Bcc}) if $args{Bcc}; $newhead->add($_ => $args{$_}) for sort grep /^[A-Z]/, keys %args; # Ready trace "Reply created from $origid"; $self->label(replied => 1); $reply; } # tests in t/35reply1rs.t sub replySubject($) { my ($thing, $subject) = @_; $subject = 'your mail' unless defined $subject && length $subject; my @subject = split /\:/, $subject; my $re_count = 1; # Strip multiple Re's from the start. while(@subject) { last if $subject[0] =~ /[A-QS-Za-qs-z][A-DF-Za-df-z]/; for(shift @subject) { while( /\bRe(?:\[\s*(\d+)\s*\]|\b)/g ) { $re_count += ($1 // 1); } } } # Strip multiple Re's from the end. if(@subject) { for($subject[-1]) { $re_count++ while s/\s*\(\s*(re|forw)\W*\)\s*$//i; } } # Create the new subject string. my $text = (join ':', @subject) || 'your mail'; s/^\s+//, s/\s+$// for $text; $re_count==1 ? "Re: $text" : "Re[$re_count]: $text"; } sub replyPrelude($) { my ($self, $who) = @_; $who = $who->[0] if ref $who eq 'ARRAY'; my $user = ! defined $who ? undef : ! blessed $who ? (Mail::Address->parse($who))[0] : $who->isa('Mail::Message::Field') ? ($who->addresses)[0] : $who; my $from = blessed $user && $user->isa('Mail::Address') ? ($user->name || $user->address || $user->format) : 'someone'; my $time = gmtime $self->timestamp; "On $time, $from wrote:\n"; } 1; ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Construct/Text.pod�����������������������������������������������0000644�0001750�0000144�00000004260�15166136117�023065� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Construct::Text - capture a Mail::Message as text =head1 SYNOPSIS my $text = $msg->string; my $text = "$msg"; # via overload my @text = $msg->lines; my @text = @$lines; # via overload my $fh = $msg->file; my $line = <$fh>; $msg->printStructure; =head1 DESCRIPTION Complex functionality on L<Mail::Message|Mail::Message> objects is implemented in different files which are autoloaded. This file implements the functionality related to creating message replies. =head1 METHODS =head2 The whole message as text =over 4 =item $obj-E<gt>B<file>() Returns the message as file-handle. =item $obj-E<gt>B<lines>() Returns the whole message as set of lines. In LIST context, copies of the lines are returned. In SCALAR context, a reference to an array of lines is returned. =item $obj-E<gt>B<printStructure>( [$fh|undef],[$indent] ) Print the structure of a message to the specified C<$fh> or the selected filehandle. When explicitly C<undef> is specified as handle, then the output will be returned as string. The message's subject and the types of all composing parts are displayed. C<$indent> specifies the initial indentation string: it is added in front of each line. The C<$indent> must contain at least one white-space. » example: my $msg = ...; $msg->printStructure(\*OUTPUT); $msg->printStructure; my $struct = $msg->printStructure(undef); # Possible output for one message: multipart/mixed: forwarded message from Pietje Puk (1550 bytes) text/plain (164 bytes) message/rfc822 (1043 bytes) multipart/alternative: A multipart alternative (942 bytes) text/plain (148 bytes, deleted) text/html (358 bytes) =item $obj-E<gt>B<string>() Returns the whole message as string. =back =head2 Flags =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Body/������������������������������������������������������������0000755�0001750�0000144�00000000000�15166136132�020341� 5����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Body/String.pm���������������������������������������������������0000644�0001750�0000144�00000005047�15166136117�022156� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::Body::String;{ our $VERSION = '4.05'; } use parent 'Mail::Message::Body'; use strict; use warnings; use Log::Report 'mail-message', import => [ qw/__x fault/ ]; use Mail::Box::FastScalar (); #-------------------- # The scalar is stored as reference to avoid a copy during creation of # a string object. sub _data_from_filename(@) { my ($self, $filename) = @_; delete $self->{MMBS_nrlines}; open my $in, '<:raw', $filename or fault __x"unable to read file {name} for message body scalar", name => $filename; my @lines = $in->getlines; $in->close; $self->{MMBS_nrlines} = @lines; $self->{MMBS_scalar} = join '', @lines; $self; } sub _data_from_filehandle(@) { my ($self, $fh) = @_; if(ref $fh eq 'Mail::Box::FastScalar') { my $lines = $fh->getlines; $self->{MMBS_nrlines} = @$lines; $self->{MMBS_scalar} = join '', @$lines; } else { my @lines = $fh->getlines; $self->{MMBS_nrlines} = @lines; $self->{MMBS_scalar} = join '', @lines; } $self; } sub _data_from_lines(@) { my ($self, $lines) = @_; $self->{MMBS_nrlines} = @$lines unless @$lines==1; $self->{MMBS_scalar} = @$lines==1 ? shift @$lines : join('', @$lines); $self; } sub clone() { my $self = shift; (ref $self)->new(data => $self->string, based_on => $self); } sub nrLines() { my $self = shift; return $self->{MMBS_nrlines} if defined $self->{MMBS_nrlines}; my $lines = $self->{MMBS_scalar} =~ tr/\n/\n/; $lines++ if $self->{MMBS_scalar} !~ m/\n\z/; $self->{MMBS_nrlines} = $lines; } sub size() { length $_[0]->{MMBS_scalar} } sub string() { $_[0]->{MMBS_scalar} } sub lines() { my @lines = split /^/, shift->{MMBS_scalar}; wantarray ? @lines : \@lines; } sub file() { Mail::Box::FastScalar->new(\shift->{MMBS_scalar}) } sub print(;$) { my $self = shift; my $fh = shift || select; $fh->print($self->{MMBS_scalar}); $self; } sub read($$;$@) { my ($self, $parser, $head, $bodytype) = splice @_, 0, 4; delete $self->{MMBS_nrlines}; (my $begin, my $end, $self->{MMBS_scalar}) = $parser->bodyAsString(@_); $self->fileLocation($begin, $end); $self; } sub endsOnNewline() { $_[0]->{MMBS_scalar} =~ m/\A\z|\n\z/ } 1; �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Body/Multipart.pod�����������������������������������������������0000644�0001750�0000144�00000044111�15166136117�023032� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Body::Multipart - body of a message with attachments =head1 INHERITANCE Mail::Message::Body::Multipart is a Mail::Message::Body is a Mail::Reporter Mail::Message::Body also extends Mail::Reporter is a Mail::Reporter =head1 SYNOPSIS See Mail::Message::Body if($body->isMultipart) { my @attachments = $body->parts; my $attachment3 = $body->part(2); my $before = $body->preamble; my $after = $body->epilogue; $body->part(1)->delete; } =head1 DESCRIPTION The body (content) of a message can be stored in various ways. In this manual-page you find the description of extra functionality you have when a message contains attachments (parts). The number of multipart alternatives is growing. A full list is maintained by IANA af L<https://www.iana.org/assignments/media-types/media-types.xhtml#multipart> =over 4 =item * multipart/mixed =item * multipart/alternative =item * multipart/related =item * multipart/report, RFC6522 =item * multipart/signed, RFC1847 =item * multipart/encrypted =item * multipart/multilingual, RFC8255 (unused) =back Extends L<"DESCRIPTION" in Mail::Message::Body|Mail::Message::Body/"DESCRIPTION">. =head1 OVERLOADED Extends L<"OVERLOADED" in Mail::Message::Body|Mail::Message::Body/"OVERLOADED">. =over 4 =item overload: B<'""'> stringification Inherited, see L<Mail::Message::Body/"OVERLOADED"> =item overload: B<'=='> numerical comparison Inherited, see L<Mail::Message::Body/"OVERLOADED"> =item overload: B<'@{}'> addressed as array Inherited, see L<Mail::Message::Body/"OVERLOADED"> =item overload: B<bool> true/false Inherited, see L<Mail::Message::Body/"OVERLOADED"> =back =head1 METHODS Extends L<"METHODS" in Mail::Message::Body|Mail::Message::Body/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Message::Body|Mail::Message::Body/"Constructors">. =over 4 =item $obj-E<gt>B<clone>() Inherited, see L<Mail::Message::Body/"Constructors"> =item $class-E<gt>B<new>(%options) Inherited, see L<Mail::Message::Body/"Constructors"> -Option --Defined in --Default based_on Mail::Message::Body undef boundary undef charset Mail::Message::Body 'PERL' checked Mail::Message::Body false content_id Mail::Message::Body undef data Mail::Message::Body undef description Mail::Message::Body undef disposition Mail::Message::Body undef eol Mail::Message::Body 'NATIVE' epilogue '' file Mail::Message::Body undef filename Mail::Message::Body undef language Mail::Message::Body undef message Mail::Message::Body undef mime_type Mail::Message::Body 'multipart/mixed' modified Mail::Message::Body false parts undef preamble undef transfer_encoding Mail::Message::Body 'none' =over 2 =item based_on => $body =item boundary => $separator The C<$separator> string to be used between parts of the message. This separator must be unique in case the message contains nested multiparts (which are not unusual). If C<undef>, a nice unique boundary will be generated. =item charset => $charset|'PERL'|<undef> =item checked => BOOLEAN =item content_id => STRING =item data => \@lines|$text =item description => STRING|$field =item disposition => STRING|$field =item eol => 'CR'|'LF'|'CRLF'|'NATIVE' =item epilogue => $body|$text The text which is included in the main body after the final boundary. This is usually empty, and has no meaning. Provide a C<$body> object or plain C<$text> (which will automatically translated into a C<text/plain> body). =item file => $file|$handle|$io =item filename => $file =item language => STRING|\@lang|$field =item message => $message =item mime_type => STRING|$field|$mime =item modified => BOOLEAN =item parts => [$message, $body, ...] Specifies an initial list of parts in this body. These may be full C<$message> objects, or C<$body> objects which will be transformed into messages before use. Each message is coerced into a L<Mail::Message::Part|Mail::Message::Part> object. MIME::Entity and L<Mail::Internet|Mail::Internet> objects are acceptable in the list, because they are coercible into L<Mail::Message::Part|Mail::Message::Part>'s. Values of C<undef> will be skipped silently. =item preamble => $body|$text The C<$text> which is included in the body before the first part. It is common use to include a text to warn the user that the message is a multipart. However, this was useful in earlier days: most mail agents are very capable in warning the user themselves. Provide a C<$body> object or plain C<$text> (which will automatically translated into a C<text/plain> body). =item transfer_encoding => STRING|$field =back » example: my $intro = Mail::Message::Body->new(data => ['part one']); my $pgp = Mail::Message::Body->new(data => ['part three']); my $body = Mail::Message::Body::Multipart->new( boundary => time . '--it-s-mine', preamble => "This is a multi-part message in MIME format.\n\n", parts => [ $intro, $folder->message(3)->decoded, $pgp ], ); =back =head2 Attributes Extends L<"Attributes" in Mail::Message::Body|Mail::Message::Body/"Attributes">. =over 4 =item $obj-E<gt>B<charsetDetectAlgorithm>( [CODE|undef|METHOD] ) Inherited, see L<Mail::Message::Body::Encode/"Attributes"> =back =head2 Constructing a body Extends L<"Constructing a body" in Mail::Message::Body|Mail::Message::Body/"Constructing a body">. =over 4 =item $obj-E<gt>B<attach>($messages|$bodies) Attach a list of C<$messages> to this multipart. A new body is returned. When you specify C<$bodies>, they will first be translated into real messages. MIME::Entity and L<Mail::Internet|Mail::Internet> objects may be specified too. In any case, the parts will be coerced into L<Mail::Message::Part|Mail::Message::Part>'s. Improves base, see L<Mail::Message::Body::Construct/"Constructing a body"> =item $obj-E<gt>B<charsetDetect>(%options) Inherited, see L<Mail::Message::Body::Encode/"Constructing a body"> =item $obj-E<gt>B<check>() Inherited, see L<Mail::Message::Body::Encode/"Constructing a body"> =item $obj-E<gt>B<concatenate>(@components) Inherited, see L<Mail::Message::Body::Construct/"Constructing a body"> =item $obj-E<gt>B<decoded>(%options) Inherited, see L<Mail::Message::Body/"Constructing a body"> =item $obj-E<gt>B<encode>(%options) Inherited, see L<Mail::Message::Body::Encode/"Constructing a body"> =item $obj-E<gt>B<encoded>(%options) Inherited, see L<Mail::Message::Body::Encode/"Constructing a body"> =item $obj-E<gt>B<eol>( ['CR'|'LF'|'CRLF'|'NATIVE'] ) Inherited, see L<Mail::Message::Body::Encode/"Constructing a body"> =item $obj-E<gt>B<foreachComponent>(CODE) Execute the C<CODE> for each component of the message: the preamble, the epilogue, and each of the parts. Each component is a body and is passed as second argument to the C<CODE>. The first argument is a reference to this multi-parted body. The C<CODE> returns a body object. When any of the returned bodies differs from the body which was passed, then a new multi-part body will be returned. Reference to the not-changed bodies and the changed bodies will be included in that new multi-part. » example: my $checked = $multi->foreachComponent(sub {$_[1]->check}); =item $obj-E<gt>B<foreachLine>((CODE)) It is NOT possible to call some code for each line of a multipart, because that would not only inflict damage to the body of each message part, but also to the headers and the part separators. Improves base, see L<Mail::Message::Body::Construct/"Constructing a body"> =item $obj-E<gt>B<stripSignature>(%options) Removes all parts which contains data usually defined as being signature. The L<MIME::Type|MIME::Type> module provides this knowledge. A new multipart is returned, containing the remaining parts. No C<%options> are defined yet, although some may be specified, because this method overrules the C<stripSignature> method for normal bodies. Improves base, see L<Mail::Message::Body::Construct/"Constructing a body"> -Option --Defined in --Default max_lines Mail::Message::Body::Construct 10 pattern Mail::Message::Body::Construct qr/^--\s?$/ result_type Mail::Message::Body::Construct <same as current> =over 2 =item max_lines => INTEGER|undef =item pattern => REGEX|STRING|CODE =item result_type => CLASS =back =item $obj-E<gt>B<unify>($body) Inherited, see L<Mail::Message::Body::Encode/"Constructing a body"> =back =head2 The body Extends L<"The body" in Mail::Message::Body|Mail::Message::Body/"The body">. =over 4 =item $obj-E<gt>B<isDelayed>() Inherited, see L<Mail::Message::Body/"The body"> =item $obj-E<gt>B<isMultipart>() Inherited, see L<Mail::Message::Body/"The body"> =item $obj-E<gt>B<isNested>() Inherited, see L<Mail::Message::Body/"The body"> =item $obj-E<gt>B<message>( [$message] ) Inherited, see L<Mail::Message::Body/"The body"> =item $obj-E<gt>B<partNumberOf>($part) Inherited, see L<Mail::Message::Body/"The body"> =back =head2 About the payload Extends L<"About the payload" in Mail::Message::Body|Mail::Message::Body/"About the payload">. =over 4 =item $obj-E<gt>B<charset>() Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<checked>( [BOOLEAN] ) Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<contentId>( [STRING|$field] ) Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<description>( [STRING|$field] ) Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<disposition>( [STRING|$field] ) Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<dispositionFilename>( [$directory] ) Inherited, see L<Mail::Message::Body::Encode/"About the payload"> =item $obj-E<gt>B<isBinary>() Inherited, see L<Mail::Message::Body::Encode/"About the payload"> =item $obj-E<gt>B<isText>() Inherited, see L<Mail::Message::Body::Encode/"About the payload"> =item $obj-E<gt>B<language>( [@langs|\@langs|$langs|$field] ) Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<mimeType>() Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<nrLines>() Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<size>() Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<transferEncoding>( [STRING|$field] ) Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<type>( [STRING|$field] ) Inherited, see L<Mail::Message::Body/"About the payload"> =back =head2 Access to the payload Extends L<"Access to the payload" in Mail::Message::Body|Mail::Message::Body/"Access to the payload">. =over 4 =item $obj-E<gt>B<boundary>( [STRING] ) Returns the boundary which is used to separate the parts in this body. If none was read from file, then one will be assigned. With C<STRING> you explicitly set the boundary to be used. =item $obj-E<gt>B<endsOnNewline>() Inherited, see L<Mail::Message::Body/"Access to the payload"> =item $obj-E<gt>B<epilogue>() Returns the epilogue; the text after the last message part (after the last real attachment). The epilogue is stored in a BODY object, and its encoding is taken from the general multipart header. =item $obj-E<gt>B<file>() Inherited, see L<Mail::Message::Body/"Access to the payload"> =item $obj-E<gt>B<lines>() Inherited, see L<Mail::Message::Body/"Access to the payload"> =item $obj-E<gt>B<part>($index) Returns only the part with the specified C<$index>. You may use a negative value here, which counts from the back in the list. Parts which are flagged to be deleted are included in the count. » example: $message->body->part(2)->print; $body->part(1)->delete; =item $obj-E<gt>B<parts>( [<'ALL'|'ACTIVE'|'DELETED'|'RECURSE'|$filter>] ) Return all parts by default, or when C<ALL> is specified. C<ACTIVE> returns the parts which are not flagged for deletion, as opposite to C<DELETED>. C<RECURSE> descents into all nested multiparts to collect all parts. You may also specify a code reference which is called for each nested part. The first argument will be the message part. When the code returns C<true>, the part is incorporated in the return list. » example: print "Number of attachments: ", scalar $message->body->parts('ACTIVE'); foreach my $part ($message->body->parts) { print "Type: ", $part->get('Content-Type'); } =item $obj-E<gt>B<preamble>() Returns the preamble; the text before the first message part (before the first real attachment). The preamble is stored in a BODY object, and its encoding is taken from the multipart header. =item $obj-E<gt>B<print>( [$fh] ) Inherited, see L<Mail::Message::Body/"Access to the payload"> =item $obj-E<gt>B<printEscapedFrom>($fh) Inherited, see L<Mail::Message::Body/"Access to the payload"> =item $obj-E<gt>B<string>() Inherited, see L<Mail::Message::Body/"Access to the payload"> =item $obj-E<gt>B<stripTrailingNewline>() Inherited, see L<Mail::Message::Body/"Access to the payload"> =item $obj-E<gt>B<write>(%options) Inherited, see L<Mail::Message::Body/"Access to the payload"> =back =head2 Internals Extends L<"Internals" in Mail::Message::Body|Mail::Message::Body/"Internals">. =over 4 =item $any-E<gt>B<addTransferEncHandler>( $name, <$class|$object> ) Inherited, see L<Mail::Message::Body::Encode/"Internals"> =item $obj-E<gt>B<contentInfoFrom>($head) Inherited, see L<Mail::Message::Body/"Internals"> =item $obj-E<gt>B<contentInfoTo>($head) Inherited, see L<Mail::Message::Body/"Internals"> =item $obj-E<gt>B<fileLocation>( [$begin, $end] ) Inherited, see L<Mail::Message::Body/"Internals"> =item $obj-E<gt>B<getTransferEncHandler>($type) Inherited, see L<Mail::Message::Body::Encode/"Internals"> =item $obj-E<gt>B<isModified>() Inherited, see L<Mail::Message::Body/"Internals"> =item $obj-E<gt>B<load>() Inherited, see L<Mail::Message::Body/"Internals"> =item $obj-E<gt>B<modified>( [BOOLEAN] ) Inherited, see L<Mail::Message::Body/"Internals"> =item $obj-E<gt>B<moveLocation>( [$distance] ) Inherited, see L<Mail::Message::Body/"Internals"> =item $obj-E<gt>B<read>( $parser, $head, $bodytype, [$chars, [$lines]] ) Inherited, see L<Mail::Message::Body/"Internals"> =back =head2 Error handling Extends L<"Error handling" in Mail::Message::Body|Mail::Message::Body/"Error handling">. =over 4 =item $obj-E<gt>B<AUTOLOAD>() Inherited, see L<Mail::Message::Body/"Error handling"> =item $obj-E<gt>B<notImplemented>() Inherited, see L<Mail::Reporter/"Error handling"> =item $obj-E<gt>B<notImplemented>() Inherited, see L<Mail::Reporter/"Error handling"> =back =head2 Cleanup Extends L<"Cleanup" in Mail::Message::Body|Mail::Message::Body/"Cleanup">. =over 4 =item $obj-E<gt>B<DESTROY>() Inherited, see L<Mail::Reporter/"Cleanup"> =item $obj-E<gt>B<DESTROY>() Inherited, see L<Mail::Reporter/"Cleanup"> =back =head1 DETAILS Extends L<"DETAILS" in Mail::Message::Body|Mail::Message::Body/"DETAILS">. =head1 DIAGNOSTICS =over 4 =item Warning: Content-Transfer-Encoding '$te' requires explicit charset, defaulted to utf-8. Cast by C<encode()> =item Error: You cannot use foreachLine on a multipart. L<foreachLine()|Mail::Message::Body::Multipart/"METHODS"> should be used on decoded message bodies only, because it would attempt to modify part-headers and separators as well, which is clearly not acceptable. Cast by C<foreachLine()> =item Error: cannot concatenate element $which Cast by C<concatenate()> =item Fault: cannot open $file to write body: $! Cast by C<write()> =item Warning: charset '$name' is not known. The encoding or decoding of a message body encounters a character set which is not understood by Perl's Encode module. Cast by C<encode()> =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =item Error: data not convertible to a message (type is $type) An object which is not coercable into a L<Mail::Message::Part|Mail::Message::Part> object was passed to the initiation. Cast by C<new()> =item Fault: error closing $file after write body: $! Cast by C<write()> =item Warning: no decoder defined for transfer encoding '$encoding'. The data (message body) is encoded in a way which is not currently understood, therefore no decoding (or recoding) can take place. Cast by C<encode()> =item Warning: no encoder defined for transfer encoding '$encoding'. The data (message body) has been decoded, but the required encoding is unknown. The decoded data is returned. Cast by C<encode()> =item Error: no filename parameter for write() body. Cast by C<write()> =item Error: part number needs multi-part or nested. Cast by C<partNumberOf()> =item Error: unknown criterium $what to select parts. Valid choices for part selections are C<ALL>, C<ACTIVE>, C<DELETED>, C<RECURSE> or a code reference. However, some other argument was passed. Cast by C<parts()> =item Error: unknown line terminator '$eol'. Cast by C<eol()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Body/Nested.pm���������������������������������������������������0000644�0001750�0000144�00000006317�15166136117�022133� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::Body::Nested;{ our $VERSION = '4.05'; } use parent 'Mail::Message::Body'; use strict; use warnings; use Log::Report 'mail-message', import => [ qw/__x error/ ]; use Mail::Message::Body::Lines (); use Mail::Message::Part (); #-------------------- sub init($) { my ($self, $args) = @_; $args->{mime_type} ||= 'message/rfc822'; $self->SUPER::init($args); my $nested; if(my $raw = $args->{nested}) { $nested = Mail::Message::Part->coerce($raw, $self) or error __x"data not convertible to a message (type is {class})", class => ref $raw; } $self->{MMBN_nested} = $nested; $self; } sub clone() { my $self = shift; (ref $self)->new(based_on => $self, nested => $self->nested->clone); } sub isNested() { 1 } sub isBinary() { $_[0]->nested->body->isBinary } sub nrLines() { $_[0]->nested->nrLines } sub size() { $_[0]->nested->size } sub string() { my $nested = $_[0]->nested; defined $nested ? $nested->string : '' } sub lines() { my $nested = $_[0]->nested; defined $nested ? $nested->lines : () } sub file() { my $nested = $_[0]->nested; defined $nested ? $nested->file : undef } sub print(;$) { my $self = shift; $self->nested->print(shift || select) } sub endsOnNewline() { $_[0]->nested->body->endsOnNewline } sub partNumberOf($) { my ($self, $part) = @_; $self->message->partNumber || '1'; } sub foreachLine($) { my ($self, $code) = @_; error __x"you cannot use foreachLine on a nested."; } sub check() { $_[0]->forNested( sub { $_[1]->check } ) } sub encode(@) { my ($self, %args) = @_; $self->forNested( sub { $_[1]->encode(%args) } ); } sub encoded() { $_[0]->forNested( sub { $_[1]->encoded } ) } sub read($$$$) { my ($self, $parser, $head, $bodytype) = @_; my $nest = Mail::Message::Part->new(container => undef); $nest->readFromParser($parser, $bodytype) or return; $nest->container($self); $self->{MMBN_nested} = $nest; $self; } sub fileLocation() { my $nested = $_[0]->nested; ( ($nested->head->fileLocation)[0], ($nested->body->fileLocation)[1] ); } sub moveLocation($) { my ($self, $dest) = @_; $dest or return $self; # no move my $nested = $self->nested; $nested->head->moveLocation($dest); $nested->body->moveLocation($dest); $self; } #-------------------- sub nested() { $_[0]->{MMBN_nested} } sub forNested($) { my ($self, $code) = @_; my $nested = $self->nested; my $body = $nested->body; my $new_body = $code->($self, $body) or return; $new_body != $body or return $self; my $new_nested = Mail::Message::Part->new(head => $nested->head->clone, container => undef); $new_nested->body($new_body); my $created = (ref $self)->new(based_on => $self, nested => $new_nested); $new_nested->container($created); $created; } sub toplevel() { my $msg = $_[0]->message; $msg ? $msg->toplevel : undef} 1; �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Body/Lines.pod���������������������������������������������������0000644�0001750�0000144�00000027557�15166136117�022142� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Body::Lines - body of a Mail::Message stored as array of lines =head1 INHERITANCE Mail::Message::Body::Lines is a Mail::Message::Body is a Mail::Reporter Mail::Message::Body also extends Mail::Reporter is a Mail::Reporter =head1 SYNOPSIS See Mail::Message::Body =head1 DESCRIPTION The body (content) of a message can be stored in various ways. In this documentation you find the description of extra functionality you have when a message is stored in an array of lines. Storing a whole message as an array of lines is useful when the data is not encoded, and you want to process it on a line-by-line basis (a common practice for inspecting message bodies). Extends L<"DESCRIPTION" in Mail::Message::Body|Mail::Message::Body/"DESCRIPTION">. =head1 OVERLOADED Extends L<"OVERLOADED" in Mail::Message::Body|Mail::Message::Body/"OVERLOADED">. =over 4 =item overload: B<'""'> stringification Inherited, see L<Mail::Message::Body/"OVERLOADED"> =item overload: B<'=='> numerical comparison Inherited, see L<Mail::Message::Body/"OVERLOADED"> =item overload: B<'@{}'> addressed as array Inherited, see L<Mail::Message::Body/"OVERLOADED"> =item overload: B<bool> true/false Inherited, see L<Mail::Message::Body/"OVERLOADED"> =back =head1 METHODS Extends L<"METHODS" in Mail::Message::Body|Mail::Message::Body/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Message::Body|Mail::Message::Body/"Constructors">. =over 4 =item $obj-E<gt>B<clone>() Inherited, see L<Mail::Message::Body/"Constructors"> =item $class-E<gt>B<new>(%options) Inherited, see L<Mail::Message::Body/"Constructors"> -Option --Defined in --Default based_on Mail::Message::Body undef charset Mail::Message::Body 'PERL' checked Mail::Message::Body false content_id Mail::Message::Body undef data Mail::Message::Body undef description Mail::Message::Body undef disposition Mail::Message::Body undef eol Mail::Message::Body 'NATIVE' file Mail::Message::Body undef filename Mail::Message::Body undef language Mail::Message::Body undef message Mail::Message::Body undef mime_type Mail::Message::Body 'text/plain' modified Mail::Message::Body false transfer_encoding Mail::Message::Body 'none' =over 2 =item based_on => $body =item charset => $charset|'PERL'|<undef> =item checked => BOOLEAN =item content_id => STRING =item data => \@lines|$text =item description => STRING|$field =item disposition => STRING|$field =item eol => 'CR'|'LF'|'CRLF'|'NATIVE' =item file => $file|$handle|$io =item filename => $file =item language => STRING|\@lang|$field =item message => $message =item mime_type => STRING|$field|$mime =item modified => BOOLEAN =item transfer_encoding => STRING|$field =back =back =head2 Attributes Extends L<"Attributes" in Mail::Message::Body|Mail::Message::Body/"Attributes">. =over 4 =item $obj-E<gt>B<charsetDetectAlgorithm>( [CODE|undef|METHOD] ) Inherited, see L<Mail::Message::Body::Encode/"Attributes"> =back =head2 Constructing a body Extends L<"Constructing a body" in Mail::Message::Body|Mail::Message::Body/"Constructing a body">. =over 4 =item $obj-E<gt>B<attach>(@messages, %options) Inherited, see L<Mail::Message::Body::Construct/"Constructing a body"> =item $obj-E<gt>B<charsetDetect>(%options) Inherited, see L<Mail::Message::Body::Encode/"Constructing a body"> =item $obj-E<gt>B<check>() Inherited, see L<Mail::Message::Body::Encode/"Constructing a body"> =item $obj-E<gt>B<concatenate>(@components) Inherited, see L<Mail::Message::Body::Construct/"Constructing a body"> =item $obj-E<gt>B<decoded>(%options) Inherited, see L<Mail::Message::Body/"Constructing a body"> =item $obj-E<gt>B<encode>(%options) Inherited, see L<Mail::Message::Body::Encode/"Constructing a body"> =item $obj-E<gt>B<encoded>(%options) Inherited, see L<Mail::Message::Body::Encode/"Constructing a body"> =item $obj-E<gt>B<eol>( ['CR'|'LF'|'CRLF'|'NATIVE'] ) Inherited, see L<Mail::Message::Body::Encode/"Constructing a body"> =item $obj-E<gt>B<foreachLine>(CODE) Inherited, see L<Mail::Message::Body::Construct/"Constructing a body"> =item $obj-E<gt>B<stripSignature>(%options) Inherited, see L<Mail::Message::Body::Construct/"Constructing a body"> =item $obj-E<gt>B<unify>($body) Inherited, see L<Mail::Message::Body::Encode/"Constructing a body"> =back =head2 The body Extends L<"The body" in Mail::Message::Body|Mail::Message::Body/"The body">. =over 4 =item $obj-E<gt>B<isDelayed>() Inherited, see L<Mail::Message::Body/"The body"> =item $obj-E<gt>B<isMultipart>() Inherited, see L<Mail::Message::Body/"The body"> =item $obj-E<gt>B<isNested>() Inherited, see L<Mail::Message::Body/"The body"> =item $obj-E<gt>B<message>( [$message] ) Inherited, see L<Mail::Message::Body/"The body"> =item $obj-E<gt>B<partNumberOf>($part) Inherited, see L<Mail::Message::Body/"The body"> =back =head2 About the payload Extends L<"About the payload" in Mail::Message::Body|Mail::Message::Body/"About the payload">. =over 4 =item $obj-E<gt>B<charset>() Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<checked>( [BOOLEAN] ) Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<contentId>( [STRING|$field] ) Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<description>( [STRING|$field] ) Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<disposition>( [STRING|$field] ) Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<dispositionFilename>( [$directory] ) Inherited, see L<Mail::Message::Body::Encode/"About the payload"> =item $obj-E<gt>B<isBinary>() Inherited, see L<Mail::Message::Body::Encode/"About the payload"> =item $obj-E<gt>B<isText>() Inherited, see L<Mail::Message::Body::Encode/"About the payload"> =item $obj-E<gt>B<language>( [@langs|\@langs|$langs|$field] ) Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<mimeType>() Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<nrLines>() Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<size>() Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<transferEncoding>( [STRING|$field] ) Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<type>( [STRING|$field] ) Inherited, see L<Mail::Message::Body/"About the payload"> =back =head2 Access to the payload Extends L<"Access to the payload" in Mail::Message::Body|Mail::Message::Body/"Access to the payload">. =over 4 =item $obj-E<gt>B<endsOnNewline>() Inherited, see L<Mail::Message::Body/"Access to the payload"> =item $obj-E<gt>B<file>() Inherited, see L<Mail::Message::Body/"Access to the payload"> =item $obj-E<gt>B<lines>() Inherited, see L<Mail::Message::Body/"Access to the payload"> =item $obj-E<gt>B<print>( [$fh] ) Inherited, see L<Mail::Message::Body/"Access to the payload"> =item $obj-E<gt>B<printEscapedFrom>($fh) Inherited, see L<Mail::Message::Body/"Access to the payload"> =item $obj-E<gt>B<string>() Inherited, see L<Mail::Message::Body/"Access to the payload"> =item $obj-E<gt>B<stripTrailingNewline>() Inherited, see L<Mail::Message::Body/"Access to the payload"> =item $obj-E<gt>B<write>(%options) Inherited, see L<Mail::Message::Body/"Access to the payload"> =back =head2 Internals Extends L<"Internals" in Mail::Message::Body|Mail::Message::Body/"Internals">. =over 4 =item $any-E<gt>B<addTransferEncHandler>( $name, <$class|$object> ) Inherited, see L<Mail::Message::Body::Encode/"Internals"> =item $obj-E<gt>B<contentInfoFrom>($head) Inherited, see L<Mail::Message::Body/"Internals"> =item $obj-E<gt>B<contentInfoTo>($head) Inherited, see L<Mail::Message::Body/"Internals"> =item $obj-E<gt>B<fileLocation>( [$begin, $end] ) Inherited, see L<Mail::Message::Body/"Internals"> =item $obj-E<gt>B<getTransferEncHandler>($type) Inherited, see L<Mail::Message::Body::Encode/"Internals"> =item $obj-E<gt>B<isModified>() Inherited, see L<Mail::Message::Body/"Internals"> =item $obj-E<gt>B<load>() Inherited, see L<Mail::Message::Body/"Internals"> =item $obj-E<gt>B<modified>( [BOOLEAN] ) Inherited, see L<Mail::Message::Body/"Internals"> =item $obj-E<gt>B<moveLocation>( [$distance] ) Inherited, see L<Mail::Message::Body/"Internals"> =item $obj-E<gt>B<read>( $parser, $head, $bodytype, [$chars, [$lines]] ) Inherited, see L<Mail::Message::Body/"Internals"> =back =head2 Error handling Extends L<"Error handling" in Mail::Message::Body|Mail::Message::Body/"Error handling">. =over 4 =item $obj-E<gt>B<AUTOLOAD>() Inherited, see L<Mail::Message::Body/"Error handling"> =item $obj-E<gt>B<notImplemented>() Inherited, see L<Mail::Reporter/"Error handling"> =item $obj-E<gt>B<notImplemented>() Inherited, see L<Mail::Reporter/"Error handling"> =back =head2 Cleanup Extends L<"Cleanup" in Mail::Message::Body|Mail::Message::Body/"Cleanup">. =over 4 =item $obj-E<gt>B<DESTROY>() Inherited, see L<Mail::Reporter/"Cleanup"> =item $obj-E<gt>B<DESTROY>() Inherited, see L<Mail::Reporter/"Cleanup"> =back =head1 DETAILS Extends L<"DETAILS" in Mail::Message::Body|Mail::Message::Body/"DETAILS">. =head1 DIAGNOSTICS =over 4 =item Warning: Content-Transfer-Encoding '$te' requires explicit charset, defaulted to utf-8. Cast by C<encode()> =item Error: cannot concatenate element $which Cast by C<concatenate()> =item Fault: cannot open $file to write body: $! Cast by C<write()> =item Warning: charset '$name' is not known. The encoding or decoding of a message body encounters a character set which is not understood by Perl's Encode module. Cast by C<encode()> =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =item Fault: error closing $file after write body: $! Cast by C<write()> =item Warning: no decoder defined for transfer encoding '$encoding'. The data (message body) is encoded in a way which is not currently understood, therefore no decoding (or recoding) can take place. Cast by C<encode()> =item Warning: no encoder defined for transfer encoding '$encoding'. The data (message body) has been decoded, but the required encoding is unknown. The decoded data is returned. Cast by C<encode()> =item Error: no filename parameter for write() body. Cast by C<write()> =item Error: part number needs multi-part or nested. Cast by C<partNumberOf()> =item Fault: unable to read file $name for message body lines: $! A L<Mail::Message::Body::Lines|Mail::Message::Body::Lines> object is to be created from a named file, but it is impossible to read that file to retrieve the lines within. Cast by C<new()> =item Error: unknown line terminator '$eol'. Cast by C<eol()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. �������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Body/File.pod����������������������������������������������������0000644�0001750�0000144�00000031301�15166136117�021725� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Body::File - body of a message temporarily stored in a file =head1 INHERITANCE Mail::Message::Body::File is a Mail::Message::Body is a Mail::Reporter Mail::Message::Body also extends Mail::Reporter is a Mail::Reporter =head1 SYNOPSIS See Mail::Message::Body =head1 DESCRIPTION The body (content) of a message can be stored in various ways. In this documentation you find the description of extra functionality you have when a message is stored in a file. Storing a whole message is a file is useful when the body is large. Although access through a file is slower, it is saving a lot of memory. Extends L<"DESCRIPTION" in Mail::Message::Body|Mail::Message::Body/"DESCRIPTION">. =head1 OVERLOADED Extends L<"OVERLOADED" in Mail::Message::Body|Mail::Message::Body/"OVERLOADED">. =over 4 =item overload: B<'""'> stringification Inherited, see L<Mail::Message::Body/"OVERLOADED"> =item overload: B<'=='> numerical comparison Inherited, see L<Mail::Message::Body/"OVERLOADED"> =item overload: B<'@{}'> addressed as array Inherited, see L<Mail::Message::Body/"OVERLOADED"> =item overload: B<bool> true/false Inherited, see L<Mail::Message::Body/"OVERLOADED"> =back =head1 METHODS Extends L<"METHODS" in Mail::Message::Body|Mail::Message::Body/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Message::Body|Mail::Message::Body/"Constructors">. =over 4 =item $obj-E<gt>B<clone>() Inherited, see L<Mail::Message::Body/"Constructors"> =item $class-E<gt>B<new>(%options) Inherited, see L<Mail::Message::Body/"Constructors"> -Option --Defined in --Default based_on Mail::Message::Body undef charset Mail::Message::Body 'PERL' checked Mail::Message::Body false content_id Mail::Message::Body undef data Mail::Message::Body undef description Mail::Message::Body undef disposition Mail::Message::Body undef eol Mail::Message::Body 'NATIVE' file Mail::Message::Body undef filename Mail::Message::Body undef language Mail::Message::Body undef message Mail::Message::Body undef mime_type Mail::Message::Body 'text/plain' modified Mail::Message::Body false transfer_encoding Mail::Message::Body 'none' =over 2 =item based_on => $body =item charset => $charset|'PERL'|<undef> =item checked => BOOLEAN =item content_id => STRING =item data => \@lines|$text =item description => STRING|$field =item disposition => STRING|$field =item eol => 'CR'|'LF'|'CRLF'|'NATIVE' =item file => $file|$handle|$io =item filename => $file =item language => STRING|\@lang|$field =item message => $message =item mime_type => STRING|$field|$mime =item modified => BOOLEAN =item transfer_encoding => STRING|$field =back =back =head2 Attributes Extends L<"Attributes" in Mail::Message::Body|Mail::Message::Body/"Attributes">. =over 4 =item $obj-E<gt>B<charsetDetectAlgorithm>( [CODE|undef|METHOD] ) Inherited, see L<Mail::Message::Body::Encode/"Attributes"> =back =head2 Constructing a body Extends L<"Constructing a body" in Mail::Message::Body|Mail::Message::Body/"Constructing a body">. =over 4 =item $obj-E<gt>B<attach>(@messages, %options) Inherited, see L<Mail::Message::Body::Construct/"Constructing a body"> =item $obj-E<gt>B<charsetDetect>(%options) Inherited, see L<Mail::Message::Body::Encode/"Constructing a body"> =item $obj-E<gt>B<check>() Inherited, see L<Mail::Message::Body::Encode/"Constructing a body"> =item $obj-E<gt>B<concatenate>(@components) Inherited, see L<Mail::Message::Body::Construct/"Constructing a body"> =item $obj-E<gt>B<decoded>(%options) Inherited, see L<Mail::Message::Body/"Constructing a body"> =item $obj-E<gt>B<encode>(%options) Inherited, see L<Mail::Message::Body::Encode/"Constructing a body"> =item $obj-E<gt>B<encoded>(%options) Inherited, see L<Mail::Message::Body::Encode/"Constructing a body"> =item $obj-E<gt>B<eol>( ['CR'|'LF'|'CRLF'|'NATIVE'] ) Inherited, see L<Mail::Message::Body::Encode/"Constructing a body"> =item $obj-E<gt>B<foreachLine>(CODE) Inherited, see L<Mail::Message::Body::Construct/"Constructing a body"> =item $obj-E<gt>B<stripSignature>(%options) Inherited, see L<Mail::Message::Body::Construct/"Constructing a body"> =item $obj-E<gt>B<unify>($body) Inherited, see L<Mail::Message::Body::Encode/"Constructing a body"> =back =head2 The body Extends L<"The body" in Mail::Message::Body|Mail::Message::Body/"The body">. =over 4 =item $obj-E<gt>B<isDelayed>() Inherited, see L<Mail::Message::Body/"The body"> =item $obj-E<gt>B<isMultipart>() Inherited, see L<Mail::Message::Body/"The body"> =item $obj-E<gt>B<isNested>() Inherited, see L<Mail::Message::Body/"The body"> =item $obj-E<gt>B<message>( [$message] ) Inherited, see L<Mail::Message::Body/"The body"> =item $obj-E<gt>B<partNumberOf>($part) Inherited, see L<Mail::Message::Body/"The body"> =back =head2 About the payload Extends L<"About the payload" in Mail::Message::Body|Mail::Message::Body/"About the payload">. =over 4 =item $obj-E<gt>B<charset>() Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<checked>( [BOOLEAN] ) Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<contentId>( [STRING|$field] ) Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<description>( [STRING|$field] ) Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<disposition>( [STRING|$field] ) Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<dispositionFilename>( [$directory] ) Inherited, see L<Mail::Message::Body::Encode/"About the payload"> =item $obj-E<gt>B<isBinary>() Inherited, see L<Mail::Message::Body::Encode/"About the payload"> =item $obj-E<gt>B<isText>() Inherited, see L<Mail::Message::Body::Encode/"About the payload"> =item $obj-E<gt>B<language>( [@langs|\@langs|$langs|$field] ) Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<mimeType>() Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<nrLines>() Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<size>() Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<transferEncoding>( [STRING|$field] ) Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<type>( [STRING|$field] ) Inherited, see L<Mail::Message::Body/"About the payload"> =back =head2 Access to the payload Extends L<"Access to the payload" in Mail::Message::Body|Mail::Message::Body/"Access to the payload">. =over 4 =item $obj-E<gt>B<endsOnNewline>() Inherited, see L<Mail::Message::Body/"Access to the payload"> =item $obj-E<gt>B<file>() Inherited, see L<Mail::Message::Body/"Access to the payload"> =item $obj-E<gt>B<lines>() Inherited, see L<Mail::Message::Body/"Access to the payload"> =item $obj-E<gt>B<print>() Inherited, see L<Mail::Message::Body/"Access to the payload"> =item $obj-E<gt>B<printEscapedFrom>($fh) Inherited, see L<Mail::Message::Body/"Access to the payload"> =item $obj-E<gt>B<string>() Inherited, see L<Mail::Message::Body/"Access to the payload"> =item $obj-E<gt>B<stripTrailingNewline>() Inherited, see L<Mail::Message::Body/"Access to the payload"> =item $obj-E<gt>B<write>(%options) Inherited, see L<Mail::Message::Body/"Access to the payload"> =back =head2 Internals Extends L<"Internals" in Mail::Message::Body|Mail::Message::Body/"Internals">. =over 4 =item $any-E<gt>B<addTransferEncHandler>( $name, <$class|$object> ) Inherited, see L<Mail::Message::Body::Encode/"Internals"> =item $obj-E<gt>B<contentInfoFrom>($head) Inherited, see L<Mail::Message::Body/"Internals"> =item $obj-E<gt>B<contentInfoTo>($head) Inherited, see L<Mail::Message::Body/"Internals"> =item $obj-E<gt>B<fileLocation>( [$begin, $end] ) Inherited, see L<Mail::Message::Body/"Internals"> =item $obj-E<gt>B<getTransferEncHandler>($type) Inherited, see L<Mail::Message::Body::Encode/"Internals"> =item $obj-E<gt>B<isModified>() Inherited, see L<Mail::Message::Body/"Internals"> =item $obj-E<gt>B<load>() Inherited, see L<Mail::Message::Body/"Internals"> =item $obj-E<gt>B<modified>( [BOOLEAN] ) Inherited, see L<Mail::Message::Body/"Internals"> =item $obj-E<gt>B<moveLocation>( [$distance] ) Inherited, see L<Mail::Message::Body/"Internals"> =item $obj-E<gt>B<read>() Inherited, see L<Mail::Message::Body/"Internals"> =item $obj-E<gt>B<tempFilename>( [$filename] ) Returns the name of the temporary file which is used to store this body. =back =head2 Error handling Extends L<"Error handling" in Mail::Message::Body|Mail::Message::Body/"Error handling">. =over 4 =item $obj-E<gt>B<AUTOLOAD>() Inherited, see L<Mail::Message::Body/"Error handling"> =item $obj-E<gt>B<notImplemented>() Inherited, see L<Mail::Reporter/"Error handling"> =item $obj-E<gt>B<notImplemented>() Inherited, see L<Mail::Reporter/"Error handling"> =back =head2 Cleanup Extends L<"Cleanup" in Mail::Message::Body|Mail::Message::Body/"Cleanup">. =over 4 =item $obj-E<gt>B<DESTROY>() The temporary file is automatically removed when the body is not required anymore. Improves base, see L<Mail::Reporter/"Cleanup"> =back =head1 DETAILS Extends L<"DETAILS" in Mail::Message::Body|Mail::Message::Body/"DETAILS">. =head1 DIAGNOSTICS =over 4 =item Warning: Content-Transfer-Encoding '$te' requires explicit charset, defaulted to utf-8. Cast by C<encode()> =item Error: cannot concatenate element $which Cast by C<concatenate()> =item Fault: cannot open $file to write body: $! Cast by C<write()> =item Fault: cannot read from file $name: $! Cast by C<nrLines()> =item Fault: cannot read from file $name: $! Cast by C<endsOnNewline()> =item Fault: cannot read from file $name: $! Cast by C<print()> =item Fault: cannot read from file $name: $! Cast by C<lines()> =item Fault: cannot read from file $name: $! Cast by C<string()> =item Fault: cannot write body to file $name: $! Cast by C<new()> =item Fault: cannot write to file $name: $! Cast by C<read()> =item Fault: cannot write to temporary body file $name: $! The message body is to be stored in a temporary file (probably because it is a large body), but for the indicated reason, this file cannot be created. Cast by C<new()> =item Fault: cannot write to temporary body file $name: $! Cast by C<new()> =item Warning: charset '$name' is not known. The encoding or decoding of a message body encounters a character set which is not understood by Perl's Encode module. Cast by C<encode()> =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =item Fault: error closing $file after write body: $! Cast by C<write()> =item Warning: no decoder defined for transfer encoding '$encoding'. The data (message body) is encoded in a way which is not currently understood, therefore no decoding (or recoding) can take place. Cast by C<encode()> =item Warning: no encoder defined for transfer encoding '$encoding'. The data (message body) has been decoded, but the required encoding is unknown. The decoded data is returned. Cast by C<encode()> =item Error: no filename parameter for write() body. Cast by C<write()> =item Error: part number needs multi-part or nested. Cast by C<partNumberOf()> =item Fault: unable to read file $name for message body file: $! A L<Mail::Message::Body::File|Mail::Message::Body::File> object is to be created from a named file, but it is impossible to read that file to retrieve the lines within. Therefore, no copy to a temporary file can be made. Cast by C<new()> =item Error: unknown line terminator '$eol'. Cast by C<eol()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Body/Nested.pod��������������������������������������������������0000644�0001750�0000144�00000032533�15166136117�022300� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Body::Nested - body of a message which contains a message =head1 INHERITANCE Mail::Message::Body::Nested is a Mail::Message::Body is a Mail::Reporter Mail::Message::Body also extends Mail::Reporter is a Mail::Reporter =head1 SYNOPSIS See Mail::Message::Body if($body->isNested) { my $nest = $body->nested; $nest->delete; } =head1 DESCRIPTION The body (content) of a message can be stored in various ways. In this manual-page you find the description of extra functionality you have when a message contains a nested message, like C<message/rfc822>. A nested message is different from a multipart message which contains only one element, because a nested message has a full set of message header fields defined by the RFC882, where a part of a multipart has only a few. But because we do not keep track whether all fields are presented, a C<Mail::Message::Part> is used anyway. B<WARNING:> Since 2023, at least outlook started to interpret RFC6533 incorrectly. Bodies of type 'message/rfc822' can only be 'nested', but when they (illegally) have Content-Transfer-Encoding, they can now behave like normal message parts (the same as a pdf or image). Extends L<"DESCRIPTION" in Mail::Message::Body|Mail::Message::Body/"DESCRIPTION">. =head1 OVERLOADED Extends L<"OVERLOADED" in Mail::Message::Body|Mail::Message::Body/"OVERLOADED">. =over 4 =item overload: B<'""'> stringification Inherited, see L<Mail::Message::Body/"OVERLOADED"> =item overload: B<'=='> numerical comparison Inherited, see L<Mail::Message::Body/"OVERLOADED"> =item overload: B<'@{}'> addressed as array Inherited, see L<Mail::Message::Body/"OVERLOADED"> =item overload: B<bool> true/false Inherited, see L<Mail::Message::Body/"OVERLOADED"> =back =head1 METHODS Extends L<"METHODS" in Mail::Message::Body|Mail::Message::Body/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Message::Body|Mail::Message::Body/"Constructors">. =over 4 =item $obj-E<gt>B<clone>() Inherited, see L<Mail::Message::Body/"Constructors"> =item $class-E<gt>B<new>(%options) Inherited, see L<Mail::Message::Body/"Constructors"> -Option --Defined in --Default based_on Mail::Message::Body undef charset Mail::Message::Body 'PERL' checked Mail::Message::Body false content_id Mail::Message::Body undef data Mail::Message::Body undef description Mail::Message::Body undef disposition Mail::Message::Body undef eol Mail::Message::Body 'NATIVE' file Mail::Message::Body undef filename Mail::Message::Body undef language Mail::Message::Body undef message Mail::Message::Body undef mime_type Mail::Message::Body 'message/rfc822' modified Mail::Message::Body false nested undef transfer_encoding Mail::Message::Body 'none' =over 2 =item based_on => $body =item charset => $charset|'PERL'|<undef> =item checked => BOOLEAN =item content_id => STRING =item data => \@lines|$text =item description => STRING|$field =item disposition => STRING|$field =item eol => 'CR'|'LF'|'CRLF'|'NATIVE' =item file => $file|$handle|$io =item filename => $file =item language => STRING|\@lang|$field =item message => $message =item mime_type => STRING|$field|$mime =item modified => BOOLEAN =item nested => $message The C<$message> which is encapsulated within this body. =item transfer_encoding => STRING|$field =back » example: my $msg = $folder->message(3); my $encaps= Mail::Message::Body::Nested->new(nested => $msg); # The body will be coerced into a message, which lacks a few # lines but we do not bother. my $intro = Mail::Message::Body->new(data => ...); my $body = Mail::Message::Body::Nested->new(nested => $intro); =back =head2 Attributes Extends L<"Attributes" in Mail::Message::Body|Mail::Message::Body/"Attributes">. =over 4 =item $obj-E<gt>B<charsetDetectAlgorithm>( [CODE|undef|METHOD] ) Inherited, see L<Mail::Message::Body::Encode/"Attributes"> =back =head2 Constructing a body Extends L<"Constructing a body" in Mail::Message::Body|Mail::Message::Body/"Constructing a body">. =over 4 =item $obj-E<gt>B<attach>(@messages, %options) Inherited, see L<Mail::Message::Body::Construct/"Constructing a body"> =item $obj-E<gt>B<charsetDetect>(%options) Inherited, see L<Mail::Message::Body::Encode/"Constructing a body"> =item $obj-E<gt>B<check>() Inherited, see L<Mail::Message::Body::Encode/"Constructing a body"> =item $obj-E<gt>B<concatenate>(@components) Inherited, see L<Mail::Message::Body::Construct/"Constructing a body"> =item $obj-E<gt>B<decoded>(%options) Inherited, see L<Mail::Message::Body/"Constructing a body"> =item $obj-E<gt>B<encode>(%options) Inherited, see L<Mail::Message::Body::Encode/"Constructing a body"> =item $obj-E<gt>B<encoded>(%options) Inherited, see L<Mail::Message::Body::Encode/"Constructing a body"> =item $obj-E<gt>B<eol>( ['CR'|'LF'|'CRLF'|'NATIVE'] ) Inherited, see L<Mail::Message::Body::Encode/"Constructing a body"> =item $obj-E<gt>B<foreachLine>((CODE)) It is NOT possible to call some code for each line of a nested because that would damage the header of the encapsulated message Improves base, see L<Mail::Message::Body::Construct/"Constructing a body"> =item $obj-E<gt>B<stripSignature>(%options) Inherited, see L<Mail::Message::Body::Construct/"Constructing a body"> =item $obj-E<gt>B<unify>($body) Inherited, see L<Mail::Message::Body::Encode/"Constructing a body"> =back =head2 The body Extends L<"The body" in Mail::Message::Body|Mail::Message::Body/"The body">. =over 4 =item $obj-E<gt>B<isDelayed>() Inherited, see L<Mail::Message::Body/"The body"> =item $obj-E<gt>B<isMultipart>() Inherited, see L<Mail::Message::Body/"The body"> =item $obj-E<gt>B<isNested>() Inherited, see L<Mail::Message::Body/"The body"> =item $obj-E<gt>B<message>( [$message] ) Inherited, see L<Mail::Message::Body/"The body"> =item $obj-E<gt>B<partNumberOf>($part) Inherited, see L<Mail::Message::Body/"The body"> =back =head2 About the payload Extends L<"About the payload" in Mail::Message::Body|Mail::Message::Body/"About the payload">. =over 4 =item $obj-E<gt>B<charset>() Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<checked>( [BOOLEAN] ) Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<contentId>( [STRING|$field] ) Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<description>( [STRING|$field] ) Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<disposition>( [STRING|$field] ) Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<dispositionFilename>( [$directory] ) Inherited, see L<Mail::Message::Body::Encode/"About the payload"> =item $obj-E<gt>B<isBinary>() Inherited, see L<Mail::Message::Body::Encode/"About the payload"> =item $obj-E<gt>B<isText>() Inherited, see L<Mail::Message::Body::Encode/"About the payload"> =item $obj-E<gt>B<language>( [@langs|\@langs|$langs|$field] ) Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<mimeType>() Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<nrLines>() Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<size>() Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<transferEncoding>( [STRING|$field] ) Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<type>( [STRING|$field] ) Inherited, see L<Mail::Message::Body/"About the payload"> =back =head2 Access to the payload Extends L<"Access to the payload" in Mail::Message::Body|Mail::Message::Body/"Access to the payload">. =over 4 =item $obj-E<gt>B<endsOnNewline>() Inherited, see L<Mail::Message::Body/"Access to the payload"> =item $obj-E<gt>B<file>() Inherited, see L<Mail::Message::Body/"Access to the payload"> =item $obj-E<gt>B<forNested>(CODE) Execute the C<CODE> for the nested message. This returns a new nested body object. Returns C<undef> when the C<CODE> returns C<undef>. =item $obj-E<gt>B<lines>() Inherited, see L<Mail::Message::Body/"Access to the payload"> =item $obj-E<gt>B<nested>() Returns the L<Mail::Message::Part|Mail::Message::Part> message which is enclosed within this body. =item $obj-E<gt>B<print>( [$fh] ) Inherited, see L<Mail::Message::Body/"Access to the payload"> =item $obj-E<gt>B<printEscapedFrom>($fh) Inherited, see L<Mail::Message::Body/"Access to the payload"> =item $obj-E<gt>B<string>() Inherited, see L<Mail::Message::Body/"Access to the payload"> =item $obj-E<gt>B<stripTrailingNewline>() Inherited, see L<Mail::Message::Body/"Access to the payload"> =item $obj-E<gt>B<write>(%options) Inherited, see L<Mail::Message::Body/"Access to the payload"> =back =head2 Internals Extends L<"Internals" in Mail::Message::Body|Mail::Message::Body/"Internals">. =over 4 =item $any-E<gt>B<addTransferEncHandler>( $name, <$class|$object> ) Inherited, see L<Mail::Message::Body::Encode/"Internals"> =item $obj-E<gt>B<contentInfoFrom>($head) Inherited, see L<Mail::Message::Body/"Internals"> =item $obj-E<gt>B<contentInfoTo>($head) Inherited, see L<Mail::Message::Body/"Internals"> =item $obj-E<gt>B<fileLocation>( [$begin, $end] ) Inherited, see L<Mail::Message::Body/"Internals"> =item $obj-E<gt>B<getTransferEncHandler>($type) Inherited, see L<Mail::Message::Body::Encode/"Internals"> =item $obj-E<gt>B<isModified>() Inherited, see L<Mail::Message::Body/"Internals"> =item $obj-E<gt>B<load>() Inherited, see L<Mail::Message::Body/"Internals"> =item $obj-E<gt>B<modified>( [BOOLEAN] ) Inherited, see L<Mail::Message::Body/"Internals"> =item $obj-E<gt>B<moveLocation>( [$distance] ) Inherited, see L<Mail::Message::Body/"Internals"> =item $obj-E<gt>B<read>( $parser, $head, $bodytype, [$chars, [$lines]] ) Inherited, see L<Mail::Message::Body/"Internals"> =back =head2 Error handling Extends L<"Error handling" in Mail::Message::Body|Mail::Message::Body/"Error handling">. =over 4 =item $obj-E<gt>B<AUTOLOAD>() Inherited, see L<Mail::Message::Body/"Error handling"> =item $obj-E<gt>B<notImplemented>() Inherited, see L<Mail::Reporter/"Error handling"> =item $obj-E<gt>B<notImplemented>() Inherited, see L<Mail::Reporter/"Error handling"> =back =head2 Cleanup Extends L<"Cleanup" in Mail::Message::Body|Mail::Message::Body/"Cleanup">. =over 4 =item $obj-E<gt>B<DESTROY>() Inherited, see L<Mail::Reporter/"Cleanup"> =item $obj-E<gt>B<DESTROY>() Inherited, see L<Mail::Reporter/"Cleanup"> =back =head1 DETAILS Extends L<"DETAILS" in Mail::Message::Body|Mail::Message::Body/"DETAILS">. =head1 DIAGNOSTICS =over 4 =item Warning: Content-Transfer-Encoding '$te' requires explicit charset, defaulted to utf-8. Cast by C<encode()> =item Error: cannot concatenate element $which Cast by C<concatenate()> =item Fault: cannot open $file to write body: $! Cast by C<write()> =item Warning: charset '$name' is not known. The encoding or decoding of a message body encounters a character set which is not understood by Perl's Encode module. Cast by C<encode()> =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =item Error: data not convertible to a message (type is $class) Cast by C<new()> =item Fault: error closing $file after write body: $! Cast by C<write()> =item Warning: no decoder defined for transfer encoding '$encoding'. The data (message body) is encoded in a way which is not currently understood, therefore no decoding (or recoding) can take place. Cast by C<encode()> =item Warning: no encoder defined for transfer encoding '$encoding'. The data (message body) has been decoded, but the required encoding is unknown. The decoded data is returned. Cast by C<encode()> =item Error: no filename parameter for write() body. Cast by C<write()> =item Error: part number needs multi-part or nested. Cast by C<partNumberOf()> =item Error: unknown line terminator '$eol'. Cast by C<eol()> =item Error: you cannot use foreachLine on a nested. L<foreachLine()|Mail::Message::Body::Nested/"METHODS"> should be used on decoded message bodies only, because it would modify the header of the encapsulated message. which is clearly not acceptable. Cast by C<foreachLine()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. ���������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Body/Lines.pm����������������������������������������������������0000644�0001750�0000144�00000004335�15166136116�021760� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::Body::Lines;{ our $VERSION = '4.05'; } use parent 'Mail::Message::Body'; use strict; use warnings; use Log::Report 'mail-message', import => [ qw/__x fault/ ]; use Mail::Box::Parser (); use IO::Lines (); #-------------------- sub _data_from_filename(@) { my ($self, $filename) = @_; open my $in, '<:raw', $filename or fault __x"unable to read file {name} for message body lines", name => $filename; $self->{MMBL_array} = [ $in->getlines ]; $in->close; $self; } sub _data_from_filehandle(@) { my ($self, $fh) = @_; $self->{MMBL_array} = ref $fh eq 'Mail::Box::FastScalar' ? $fh->getlines : [ $fh->getlines ]; $self; } sub _data_from_lines(@) { my ($self, $lines) = @_; $lines = [ split /^/, $lines->[0] ] # body passed in one string. if @$lines==1; $self->{MMBL_array} = $lines; $self; } sub clone() { my $self = shift; (ref $self)->new(data => [ $self->lines ], based_on => $self); } sub nrLines() { scalar @{ $_[0]->{MMBL_array}} } # Optimized to be computed only once. sub size() { my $self = shift; return $self->{MMBL_size} if exists $self->{MMBL_size}; my $size = 0; $size += length $_ for @{$self->{MMBL_array}}; $self->{MMBL_size} = $size; } sub string() { join '', @{$_[0]->{MMBL_array}} } sub lines() { wantarray ? @{$_[0]->{MMBL_array}} : $_[0]->{MMBL_array} } sub file() { IO::Lines->new($_[0]->{MMBL_array}) } sub print(;$) { my $self = shift; (shift || select)->print(@{$self->{MMBL_array}}); $self; } sub endsOnNewline() { my $last = $_[0]->{MMBL_array}[-1]; !defined $last || $last =~ /[\r\n]$/; } sub read($$;$@) { my ($self, $parser, $head, $bodytype) = splice @_, 0, 4; my ($begin, $end, $lines) = $parser->bodyAsList(@_); $lines or return undef; $self->fileLocation($begin, $end); $self->{MMBL_array} = $lines; $self; } 1; ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Body/File.pm�����������������������������������������������������0000644�0001750�0000144�00000010156�15166136116�021563� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::Body::File;{ our $VERSION = '4.05'; } use parent 'Mail::Message::Body'; use strict; use warnings; use Log::Report 'mail-message', import => [ qw/__x fault/ ]; use File::Temp qw/tempfile/; use File::Copy qw/copy/; use Fcntl qw/SEEK_END/; use Mail::Box::Parser (); use Mail::Message (); #-------------------- sub _data_from_filename(@) { my ($self, $filename) = @_; open my $in, '<:raw', $filename or fault __x"unable to read file {name} for message body file", name => $filename; my $file = $self->tempFilename; open my $out, '>:raw', $file or fault __x"cannot write to temporary body file {name}", name => $file; my $nrlines = 0; local $_; while(<$in>) { $out->print($_); $nrlines++ } $self->{MMBF_nrlines} = $nrlines; $self; } sub _data_from_filehandle(@) { my ($self, $fh) = @_; my $file = $self->tempFilename; my $nrlines = 0; open my $out, '>:raw', $file or fault __x"cannot write to temporary body file {name}", name => $file; local $_; while(<$fh>) { $out->print($_); $nrlines++; } $self->{MMBF_nrlines} = $nrlines; $self; } sub _data_from_lines(@) { my ($self, $lines) = @_; my $file = $self->tempFilename; open my $out, '>:raw', $file or fault __x"cannot write body to file {name}", name => $file; $out->print(@$lines); $self->{MMBF_nrlines} = @$lines; $self; } sub clone() { my $self = shift; my $clone = ref($self)->new(based_on => $self); copy $self->tempFilename, $clone->tempFilename or return; $clone->{MMBF_nrlines} = $self->{MMBF_nrlines}; $clone->{MMBF_size} = $self->{MMBF_size}; $self; } sub nrLines() { my $self = shift; return $self->{MMBF_nrlines} if defined $self->{MMBF_nrlines}; my $file = $self->tempFilename; my $nrlines = 0; open my $in, '<:raw', $file or fault __x"cannot read from file {name}", name => $file; local $_; $nrlines++ while <$in>; $self->{MMBF_nrlines} = $nrlines; } sub size() { my $self = shift; return $self->{MMBF_size} if exists $self->{MMBF_size}; my $size = eval { -s $self->tempFilename }; $size -= $self->nrLines if $Mail::Message::crlf_platform; # remove count for extra CR's $self->{MMBF_size} = $size; } sub string() { my $self = shift; my $file = $self->tempFilename; open my $in, '<:raw', $file or fault __x"cannot read from file {name}", name => $file; join '', $in->getlines; } sub lines() { my $self = shift; my $file = $self->tempFilename; open my $in, '<:raw', $file or fault __x"cannot read from file {name}", name => $file; my $r = $self->{MMBF_nrlines} = [ $in->getlines ]; wantarray ? @$r: $r; } sub file() { my $self = shift; open my($tmp), '<:raw', $self->tempFilename; $tmp; } sub print(;$) { my $self = shift; my $fh = shift || select; my $file = $self->tempFilename; open my $in, '<:raw', $file or fault __x"cannot read from file {name}", name => $file; $fh->print($_) while <$in>; $in->close; $self; } sub endsOnNewline() { my $self = shift; my $file = $self->tempFilename; open my $in, '<:raw', $file or fault __x"cannot read from file {name}", name => $file; $in->seek(-1, SEEK_END); $in->read(my $char, 1); $char eq "\n" || $char eq "\r"; } sub read($$;$@) { my ($self, $parser, $head, $bodytype) = splice @_, 0, 4; my $file = $self->tempFilename; open my $out, '>:raw', $file or fault __x"cannot write to file {name}", name => $file; (my $begin, my $end, $self->{MMBF_nrlines}) = $parser->bodyAsFile($out, @_); $out->close; $self->fileLocation($begin, $end); $self; } #-------------------- sub tempFilename(;$) { my $self = shift; @_ ? ($self->{MMBF_filename} = shift) : ($self->{MMBF_filename} //= (tempfile)[1]); } #-------------------- sub DESTROY { unlink $_[0]->tempFilename } 1; ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Body/Construct.pm������������������������������������������������0000644�0001750�0000144�00000005633�15166136116�022674� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::Body;{ our $VERSION = '4.05'; } # Mail::Message::Body::Construct adds functionality to Mail::Message::Body use strict; use warnings; use Log::Report 'mail-message', import => [ qw/__x error/ ]; use Scalar::Util qw/blessed/; use Mail::Message::Body::String (); use Mail::Message::Body::Lines (); #-------------------- sub foreachLine($) { my ($self, $code) = @_; my $changes = 0; my @result; foreach ($self->lines) { my $becomes = $code->(); if(defined $becomes) { push @result, $becomes; $changes++ if $becomes ne $_; } else { $changes++ } } $changes ? (ref $self)->new(based_on => $self, data => \@result) : $self; } sub concatenate(@) { my $self = shift; return $self if @_==1; my @unified; foreach (grep defined, @_) { push @unified, ! ref $_ ? $_ : ref $_ eq 'ARRAY' ? @$_ : $_->isa('Mail::Message') ? $_->body->decoded : $_->isa('Mail::Message::Body') ? $_->decoded : error(__x"cannot concatenate element {which}", which => $_); } (ref $self)->new( based_on => $self, mime_type => 'text/plain', data => join('', @unified), ); } sub attach(@) { my $self = shift; my @parts; push @parts, shift while @_ && blessed $_[0]; @parts or return $self; unshift @parts, $self->isNested ? $self->nested : $self->isMultipart ? $self->parts : $self; @parts==1 ? $parts[0] : Mail::Message::Body::Multipart->new(parts => \@parts, @_); } # tests in t/51stripsig.t sub stripSignature($@) { my ($self, %args) = @_; return $self if $self->mimeType->isBinary; my $p = $args{pattern}; my $pattern = ! defined $p ? qr/^--\s?$/ : ! ref $p ? qr/^\Q$p/ : $p; my $lines = $self->lines; # no copy! my $stop = defined $args{max_lines} ? @$lines - $args{max_lines} : exists $args{max_lines} ? 0 : @$lines-10; $stop = 0 if $stop < 0; my ($sigstart, $found); if(ref $pattern eq 'CODE') { for($sigstart = $#$lines; $sigstart >= $stop; $sigstart--) { $pattern->($lines->[$sigstart]) or next; $found = 1; last; } } else { for($sigstart = $#$lines; $sigstart >= $stop; $sigstart--) { $lines->[$sigstart] =~ $pattern or next; $found = 1; last; } } $found or return $self; my $bodytype = $args{result_type} || ref $self; my $stripped = $bodytype->new(based_on => $self, data => [ @$lines[0..$sigstart-1] ]); wantarray or return $stripped; my $sig = $bodytype->new(based_on => $self, data => [ @$lines[$sigstart..$#$lines] ]); ($stripped, $sig); } 1; �����������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Body/Multipart.pm������������������������������������������������0000644�0001750�0000144�00000023211�15166136116�022661� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::Body::Multipart;{ our $VERSION = '4.05'; } use parent 'Mail::Message::Body'; use strict; use warnings; use Log::Report 'mail-message', import => [ qw/__x error panic warning/ ]; use Scalar::Util qw/blessed/; use Mail::Message::Body::Lines (); use Mail::Message::Part (); use Mail::Box::FastScalar (); #-------------------- sub init($) { my ($self, $args) = @_; my $based = $args->{based_on}; $args->{mime_type} ||= defined $based ? $based->type : 'multipart/mixed'; $self->SUPER::init($args); my @parts; if($args->{parts}) { foreach my $raw (@{$args->{parts}}) { defined $raw or next; my $cooked = Mail::Message::Part->coerce($raw, $self); defined $cooked or error __x"data not convertible to a message (type is {class})", class => ref $raw; push @parts, $cooked; } } my $preamble = $args->{preamble}; $preamble = Mail::Message::Body->new(data => $preamble) if defined $preamble && ! blessed $preamble; my $epilogue = $args->{epilogue}; $epilogue = Mail::Message::Body->new(data => $epilogue) if defined $epilogue && ! blessed $epilogue; if($based) { $self->boundary($args->{boundary} || $based->boundary); $self->{MMBM_preamble} = $preamble // $based->preamble; $self->{MMBM_parts} = @parts ? \@parts : !$args->{parts} && $based->isMultipart ? [ $based->parts('ACTIVE') ] : []; $self->{MMBM_epilogue} = $epilogue // $based->epilogue; } else { $self->boundary($args->{boundary} ||$self->type->attribute('boundary')); $self->{MMBM_preamble} = $preamble; $self->{MMBM_parts} = \@parts; $self->{MMBM_epilogue} = $epilogue; } $self; } sub isMultipart() { 1 } sub isBinary() { 0 } # A multipart body is never binary itself. The parts may be. sub clone() { my $self = shift; my $preamble = $self->preamble; my $epilogue = $self->epilogue; my $body = (ref $self)->new( based_on => $self, preamble => ($preamble ? $preamble->clone : undef), epilogue => ($epilogue ? $epilogue->clone : undef), parts => [ map $_->clone, $self->parts('ACTIVE') ], ); } sub nrLines() { my $self = shift; my $nr = 1; # trailing part-sep if(my $preamble = $self->preamble) { $nr += $preamble->nrLines; $nr++ if $preamble->endsOnNewline; } foreach my $part ($self->parts('ACTIVE')) { $nr += 1 + $part->nrLines; $nr++ if $part->body->endsOnNewline; } if(my $epilogue = $self->epilogue) { # nrLines should match mbox counts, which is a bit # unclear w.r.t. the \n after a multipart separator # line. $nr += $epilogue->nrLines -1; } $nr; } sub size() { my $self = shift; my $bbytes = length($self->boundary) +4; # \n--$b\n my $bytes = $bbytes +2; # last boundary, \n--$b--\n if(my $preamble = $self->preamble) { $bytes += $preamble->size } else { $bytes -= 1 } # no leading \n $bytes += $bbytes + $_->size foreach $self->parts('ACTIVE'); if(my $epilogue = $self->epilogue) { $bytes += $epilogue->size; } $bytes; } sub string() { join '', $_[0]->lines } sub lines() { my $self = shift; my $boundary = $self->boundary; my $preamble = $self->preamble; my @lines; push @lines, $preamble->lines if $preamble; foreach my $part ($self->parts('ACTIVE')) { # boundaries start with \n if(!@lines) { ; } elsif($lines[-1] =~ m/\n$/) { push @lines, "\n" } else { $lines[-1] .= "\n" } push @lines, "--$boundary\n", $part->lines; } if(!@lines) { ; } elsif($lines[-1] =~ m/\n$/) { push @lines, "\n" } else { $lines[-1] .= "\n" } push @lines, "--$boundary--"; if(my $epilogue = $self->epilogue) { $lines[-1] .= "\n"; push @lines, $epilogue->lines; } wantarray ? @lines : \@lines; } sub file() # It may be possible to speed-improve the next code, which first { my $self = shift; # produces a full print of the message in memory... my $dump = Mail::Box::FastScalar->new; $self->print($dump); $dump->seek(0,0); $dump; } sub print(;$) { my $self = shift; my $out = shift || select; my $boundary = $self->boundary; my $count = 0; if(my $preamble = $self->preamble) { $preamble->print($out); $count++; } foreach my $part ($self->parts('ACTIVE')) { $out->print("\n") if $count++; $out->print("--$boundary\n"); $part->print($out); } $out->print("\n") if $count++; $out->print("--$boundary--"); if(my $epilogue = $self->epilogue) { $out->print("\n"); $epilogue->print($out); } $self; } sub endsOnNewline() { my $self = shift; my $epilogue = $self->epilogue or return 1; $epilogue =~ m/[\r\n]$/; } sub foreachLine($) { my ($self, $code) = @_; error __x"you cannot use foreachLine on a multipart."; } sub check() { my $self = shift; $self->foreachComponent( sub { $_[1]->check } ); } sub encode(@) { my ($self, %args) = @_; $self->foreachComponent( sub { $_[1]->encode(%args) } ); } sub encoded() { my $self = shift; $self->foreachComponent( sub { $_[1]->encoded } ); } sub read($$$$) { my ($self, $parser, $head, $bodytype) = @_; my $boundary = $self->boundary; $parser->pushSeparator("--$boundary"); my $te; $te = lc $1 if +($head->get('Content-Transfer-Encoding') || '') =~ m/(\w+)/; my @sloppyopts = (mime_type => 'text/plain', transfer_encoding => $te); # Get preamble. my $headtype = ref $head; my $begin = $parser->filePosition; my $preamble = Mail::Message::Body::Lines->new(@sloppyopts)->read($parser, $head); $preamble->nrLines or undef $preamble; $self->{MMBM_preamble} = $preamble if defined $preamble; # Get the parts. my ($has_epilogue, @parts); while(my $sep = $parser->readSeparator) { if($sep =~ m/^--\Q$boundary\E--[ \t]*\n?/) { # Per RFC 2046, a CRLF after the close-delimiter marks the presence # of an epilogue. Preserve the epilogue, even if empty, so that the # printed multipart body will also have the CRLF. # This, however, is complicated w.r.t. mbox folders. $has_epilogue = $sep =~ /\n/; last; } my $part = Mail::Message::Part->new(container => $self); $part->readFromParser($parser, $bodytype) or last; push @parts, $part if $part->head->names || $part->body->size; } $self->{MMBM_parts} = \@parts; # Get epilogue $parser->popSeparator; my $epilogue = Mail::Message::Body::Lines->new(@sloppyopts) ->read($parser, $head); my $end = defined $epilogue ? ($epilogue->fileLocation)[1] : @parts ? ($parts[-1]->body->fileLocation)[1] : defined $preamble ? ($preamble->fileLocation)[1] : $begin; $self->fileLocation($begin, $end); $has_epilogue || $epilogue->nrLines or undef $epilogue; $self->{MMBM_epilogue} = $epilogue if defined $epilogue; $self; } #-------------------- sub foreachComponent($) { my ($self, $code) = @_; my $changes = 0; my $new_preamble; if(my $preamble = $self->preamble) { $new_preamble = $code->($self, $preamble); $changes++ unless $preamble == $new_preamble; } my $new_epilogue; if(my $epilogue = $self->epilogue) { $new_epilogue = $code->($self, $epilogue); $changes++ unless $epilogue == $new_epilogue; } my @new_bodies; foreach my $part ($self->parts('ACTIVE')) { my $part_body = $part->body; my $new_body = $code->($self, $part_body); $changes++ if $new_body != $part_body; push @new_bodies, [$part, $new_body]; } $changes or return $self; my @new_parts; foreach (@new_bodies) { my ($part, $body) = @$_; my $new_part = Mail::Message::Part->new(head => $part->head->clone, container => undef); $new_part->body($body); push @new_parts, $new_part; } my $constructed = (ref $self)->new( preamble => $new_preamble, parts => \@new_parts, epilogue => $new_epilogue, based_on => $self, ); $_->container($constructed) for @new_parts; $constructed; } sub attach(@) { my $self = shift; (ref $self)->new(based_on => $self, parts => [ $self->parts, @_ ]); } sub stripSignature(@) { my $self = shift; my @allparts = $self->parts; my @parts = grep ! $_->body->mimeType->isSignature, @allparts; @allparts == @parts ? $self : (ref $self)->new(based_on => $self, parts => \@parts); } #-------------------- sub preamble() { $_[0]->{MMBM_preamble} } sub epilogue() { $_[0]->{MMBM_epilogue} } sub parts(;$) { my $self = shift; return @{$self->{MMBM_parts}} unless @_; my $what = shift; my @parts = @{$self->{MMBM_parts}}; $what eq 'RECURSE' ? (map $_->parts('RECURSE'), @parts) : $what eq 'ALL' ? @parts : $what eq 'DELETED' ? (grep $_->isDeleted, @parts) : $what eq 'ACTIVE' ? (grep !$_->isDeleted, @parts) : ref $what eq 'CODE'? (grep $what->($_), @parts) : error __x"unknown criterium {what} to select parts.", what => $what; } sub part($) { $_[0]->{MMBM_parts}[$_[1]] } sub partNumberOf($) { my ($self, $part) = @_; my $msg = $self->message or panic "multipart is not connected."; my $base = $msg->isa('Mail::Message::Part') ? $msg->partNumber.'.' : ''; my @parts = $self->parts('ACTIVE'); foreach my $partnr (0..@parts) { return $base.($partnr+1) if $parts[$partnr] == $part; } panic "multipart is not found or not active"; } sub boundary(;$) { my $self = shift; my $mime = $self->type; unless(@_) { my $boundary = $mime->attribute('boundary'); return $boundary if defined $boundary; } my $boundary = $_[0] // "boundary-".int rand(1000000); $self->type->attribute(boundary => $boundary); } sub toplevel() { my $msg = $_[0]->message; $msg ? $msg->toplevel : undef} 1; ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Body/Construct.pod�����������������������������������������������0000644�0001750�0000144�00000012106�15166136117�023034� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Body::Construct - adds functionality to Mail::Message::Body =head1 SYNOPSIS =head1 DESCRIPTION This package adds complex functionality to the L<Mail::Message::Body|Mail::Message::Body> class. This functions less often used, so many programs will not compile this package. =head1 METHODS =head2 Constructing a body =over 4 =item $obj-E<gt>B<attach>(@messages, %options) Make a multipart containing this body and the specified C<@messages>. The options are passed to the constructor of the multi-part body. If you need more control, create the multi-part body yourself. At least take a look at L<Mail::Message::Body::Multipart|Mail::Message::Body::Multipart>. The message-parts will be coerced into a L<Mail::Message::Part|Mail::Message::Part>, so you may attach L<Mail::Internet|Mail::Internet> or MIME::Entity objects if you want --see L<Mail::Message::coerce()|Mail::Message/"Internals">. A new body with attached messages is returned. » example: my $pgpkey = Mail::Message::Body::File->new(file => 'a.pgp'); my $msg = Mail::Message->buildFromBody($message->decoded->attach($pgpkey)); # The last message of the $multi multiparted body becomes a coerced $entity. my $entity = MIME::Entity->new; my $multi = $msg->body->attach($entity); # Now create a new message my $msg = Mail::Message->new(head => ..., body => $multi); =item $obj-E<gt>B<concatenate>(@components) Concatenate the textual content of a LIST of elements into one new body. The resulting body object is based on the callee, which may itself not be included in the result. Specify a list of text C<@components>. Each component can be =over 4 =item * a message (L<Mail::Message|Mail::Message>, the body of the message is used), =item * a plain body (L<Mail::Message::Body|Mail::Message::Body>), =item * C<undef> (which will be skipped), =item * a scalar (which is split into lines), or =item * an array of scalars (each providing one line). =back » example: # all arguments are Mail::Message::Body's. my $sum = $body->concatenate($preamble, $body, $epilogue, "-- \n" , $sig); =item $obj-E<gt>B<foreachLine>(CODE) Create a new body by performing an action on each of its lines. If none of the lines change, the current body will be returned, otherwise a new body is created of the same type as the current. The C<CODE> refers to a subroutine which is called, where C<$_> contains body's original line. DO NOT CHANGE C<$_>!!! The result of the routine is taken as new line. When the routine returns C<undef>, the line will be skipped. » example: my $content = $msg->decoded; my $reply = $content->foreachLine( sub { '> '.$_ } ); my $rev = $content->foreachLine( sub { reverse } ); sub filled() { length $_ > 1 ? $_ : undef } my $nonempty = $content->foreachLine( \&filled ); my $WRONG = $content->foreachLine( sub { s/a/A/ } ); my $right = $content->foreachLine( sub { s/a/A/r }); =item $obj-E<gt>B<stripSignature>(%options) Strip the signature from the body. The body must already be decoded otherwise the wrong lines may get stripped. Returned is the stripped version body, and in list context also the signature, encapsulated in its own body object. The signature separator is the first line of the returned signature body. The signature is added by the sender to tell about him- or herself. It is superfluous in some situations, for instance if you want to create a reply to the person's message you do not need to include that signature. If the body had no signature, the original body object is returned, and C<undef> for the signature body. -Option --Default max_lines 10 pattern qr/^--\s?$/ result_type <same as current> =over 2 =item max_lines => INTEGER|undef The maximum number of lines which can be the length of a signature. Specify C<undef> to remove the limit. =item pattern => REGEX|STRING|CODE Which pattern defines the line which indicates the separator between the message and the signature. In case of a STRING, this is matched to the beginning of the line, and REGEX is a full regular expression. In case of CODE, each line (from last to front) is passed to the specified subroutine as first argument. The subroutine must return TRUE when the separator is found. =item result_type => CLASS The type of body to be created for the stripped body (and maybe also to contain the stripped signature) =back » example: my $start = $message->decoded; my $start = $body->decoded; my $stripped = $start->stripSignature; my ($stripped, $sign) = $start->stripSignature (max_lines => 5, pattern => '-*-*-'); =back =head1 DIAGNOSTICS =over 4 =item Error: cannot concatenate element $which Cast by C<concatenate()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Body/String.pod��������������������������������������������������0000644�0001750�0000144�00000027651�15166136117�022331� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Body::String - body of a Mail::Message stored as single string =head1 INHERITANCE Mail::Message::Body::String is a Mail::Message::Body is a Mail::Reporter Mail::Message::Body also extends Mail::Reporter is a Mail::Reporter =head1 SYNOPSIS See Mail::Message::Body =head1 DESCRIPTION The body (content) of a message can be stored in various ways. In this documentation you will find the description of extra functionality you have when a message is stored as a single scalar. Storing a whole message in one string is only a smart choice when the content is small or encoded. Even when stored as a scalar, you can still treat the body as if the data is stored in lines or an external file, but this will be slower. Extends L<"DESCRIPTION" in Mail::Message::Body|Mail::Message::Body/"DESCRIPTION">. =head1 OVERLOADED Extends L<"OVERLOADED" in Mail::Message::Body|Mail::Message::Body/"OVERLOADED">. =over 4 =item overload: B<'""'> stringification Inherited, see L<Mail::Message::Body/"OVERLOADED"> =item overload: B<'=='> numerical comparison Inherited, see L<Mail::Message::Body/"OVERLOADED"> =item overload: B<'@{}'> addressed as array Inherited, see L<Mail::Message::Body/"OVERLOADED"> =item overload: B<bool> true/false Inherited, see L<Mail::Message::Body/"OVERLOADED"> =back =head1 METHODS Extends L<"METHODS" in Mail::Message::Body|Mail::Message::Body/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Message::Body|Mail::Message::Body/"Constructors">. =over 4 =item $obj-E<gt>B<clone>() Inherited, see L<Mail::Message::Body/"Constructors"> =item $class-E<gt>B<new>(%options) Inherited, see L<Mail::Message::Body/"Constructors"> -Option --Defined in --Default based_on Mail::Message::Body undef charset Mail::Message::Body 'PERL' checked Mail::Message::Body false content_id Mail::Message::Body undef data Mail::Message::Body undef description Mail::Message::Body undef disposition Mail::Message::Body undef eol Mail::Message::Body 'NATIVE' file Mail::Message::Body undef filename Mail::Message::Body undef language Mail::Message::Body undef message Mail::Message::Body undef mime_type Mail::Message::Body 'text/plain' modified Mail::Message::Body false transfer_encoding Mail::Message::Body 'none' =over 2 =item based_on => $body =item charset => $charset|'PERL'|<undef> =item checked => BOOLEAN =item content_id => STRING =item data => \@lines|$text =item description => STRING|$field =item disposition => STRING|$field =item eol => 'CR'|'LF'|'CRLF'|'NATIVE' =item file => $file|$handle|$io =item filename => $file =item language => STRING|\@lang|$field =item message => $message =item mime_type => STRING|$field|$mime =item modified => BOOLEAN =item transfer_encoding => STRING|$field =back =back =head2 Attributes Extends L<"Attributes" in Mail::Message::Body|Mail::Message::Body/"Attributes">. =over 4 =item $obj-E<gt>B<charsetDetectAlgorithm>( [CODE|undef|METHOD] ) Inherited, see L<Mail::Message::Body::Encode/"Attributes"> =back =head2 Constructing a body Extends L<"Constructing a body" in Mail::Message::Body|Mail::Message::Body/"Constructing a body">. =over 4 =item $obj-E<gt>B<attach>(@messages, %options) Inherited, see L<Mail::Message::Body::Construct/"Constructing a body"> =item $obj-E<gt>B<charsetDetect>(%options) Inherited, see L<Mail::Message::Body::Encode/"Constructing a body"> =item $obj-E<gt>B<check>() Inherited, see L<Mail::Message::Body::Encode/"Constructing a body"> =item $obj-E<gt>B<concatenate>(@components) Inherited, see L<Mail::Message::Body::Construct/"Constructing a body"> =item $obj-E<gt>B<decoded>(%options) Inherited, see L<Mail::Message::Body/"Constructing a body"> =item $obj-E<gt>B<encode>(%options) Inherited, see L<Mail::Message::Body::Encode/"Constructing a body"> =item $obj-E<gt>B<encoded>(%options) Inherited, see L<Mail::Message::Body::Encode/"Constructing a body"> =item $obj-E<gt>B<eol>( ['CR'|'LF'|'CRLF'|'NATIVE'] ) Inherited, see L<Mail::Message::Body::Encode/"Constructing a body"> =item $obj-E<gt>B<foreachLine>(CODE) Inherited, see L<Mail::Message::Body::Construct/"Constructing a body"> =item $obj-E<gt>B<stripSignature>(%options) Inherited, see L<Mail::Message::Body::Construct/"Constructing a body"> =item $obj-E<gt>B<unify>($body) Inherited, see L<Mail::Message::Body::Encode/"Constructing a body"> =back =head2 The body Extends L<"The body" in Mail::Message::Body|Mail::Message::Body/"The body">. =over 4 =item $obj-E<gt>B<isDelayed>() Inherited, see L<Mail::Message::Body/"The body"> =item $obj-E<gt>B<isMultipart>() Inherited, see L<Mail::Message::Body/"The body"> =item $obj-E<gt>B<isNested>() Inherited, see L<Mail::Message::Body/"The body"> =item $obj-E<gt>B<message>( [$message] ) Inherited, see L<Mail::Message::Body/"The body"> =item $obj-E<gt>B<partNumberOf>($part) Inherited, see L<Mail::Message::Body/"The body"> =back =head2 About the payload Extends L<"About the payload" in Mail::Message::Body|Mail::Message::Body/"About the payload">. =over 4 =item $obj-E<gt>B<charset>() Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<checked>( [BOOLEAN] ) Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<contentId>( [STRING|$field] ) Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<description>( [STRING|$field] ) Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<disposition>( [STRING|$field] ) Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<dispositionFilename>( [$directory] ) Inherited, see L<Mail::Message::Body::Encode/"About the payload"> =item $obj-E<gt>B<isBinary>() Inherited, see L<Mail::Message::Body::Encode/"About the payload"> =item $obj-E<gt>B<isText>() Inherited, see L<Mail::Message::Body::Encode/"About the payload"> =item $obj-E<gt>B<language>( [@langs|\@langs|$langs|$field] ) Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<mimeType>() Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<nrLines>() Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<size>() Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<transferEncoding>( [STRING|$field] ) Inherited, see L<Mail::Message::Body/"About the payload"> =item $obj-E<gt>B<type>( [STRING|$field] ) Inherited, see L<Mail::Message::Body/"About the payload"> =back =head2 Access to the payload Extends L<"Access to the payload" in Mail::Message::Body|Mail::Message::Body/"Access to the payload">. =over 4 =item $obj-E<gt>B<endsOnNewline>() Inherited, see L<Mail::Message::Body/"Access to the payload"> =item $obj-E<gt>B<file>() Inherited, see L<Mail::Message::Body/"Access to the payload"> =item $obj-E<gt>B<lines>() Inherited, see L<Mail::Message::Body/"Access to the payload"> =item $obj-E<gt>B<print>( [$fh] ) Inherited, see L<Mail::Message::Body/"Access to the payload"> =item $obj-E<gt>B<printEscapedFrom>($fh) Inherited, see L<Mail::Message::Body/"Access to the payload"> =item $obj-E<gt>B<string>() Inherited, see L<Mail::Message::Body/"Access to the payload"> =item $obj-E<gt>B<stripTrailingNewline>() Inherited, see L<Mail::Message::Body/"Access to the payload"> =item $obj-E<gt>B<write>(%options) Inherited, see L<Mail::Message::Body/"Access to the payload"> =back =head2 Internals Extends L<"Internals" in Mail::Message::Body|Mail::Message::Body/"Internals">. =over 4 =item $any-E<gt>B<addTransferEncHandler>( $name, <$class|$object> ) Inherited, see L<Mail::Message::Body::Encode/"Internals"> =item $obj-E<gt>B<contentInfoFrom>($head) Inherited, see L<Mail::Message::Body/"Internals"> =item $obj-E<gt>B<contentInfoTo>($head) Inherited, see L<Mail::Message::Body/"Internals"> =item $obj-E<gt>B<fileLocation>( [$begin, $end] ) Inherited, see L<Mail::Message::Body/"Internals"> =item $obj-E<gt>B<getTransferEncHandler>($type) Inherited, see L<Mail::Message::Body::Encode/"Internals"> =item $obj-E<gt>B<isModified>() Inherited, see L<Mail::Message::Body/"Internals"> =item $obj-E<gt>B<load>() Inherited, see L<Mail::Message::Body/"Internals"> =item $obj-E<gt>B<modified>( [BOOLEAN] ) Inherited, see L<Mail::Message::Body/"Internals"> =item $obj-E<gt>B<moveLocation>( [$distance] ) Inherited, see L<Mail::Message::Body/"Internals"> =item $obj-E<gt>B<read>( $parser, $head, $bodytype, [$chars, [$lines]] ) Inherited, see L<Mail::Message::Body/"Internals"> =back =head2 Error handling Extends L<"Error handling" in Mail::Message::Body|Mail::Message::Body/"Error handling">. =over 4 =item $obj-E<gt>B<AUTOLOAD>() Inherited, see L<Mail::Message::Body/"Error handling"> =item $obj-E<gt>B<notImplemented>() Inherited, see L<Mail::Reporter/"Error handling"> =item $obj-E<gt>B<notImplemented>() Inherited, see L<Mail::Reporter/"Error handling"> =back =head2 Cleanup Extends L<"Cleanup" in Mail::Message::Body|Mail::Message::Body/"Cleanup">. =over 4 =item $obj-E<gt>B<DESTROY>() Inherited, see L<Mail::Reporter/"Cleanup"> =item $obj-E<gt>B<DESTROY>() Inherited, see L<Mail::Reporter/"Cleanup"> =back =head1 DETAILS Extends L<"DETAILS" in Mail::Message::Body|Mail::Message::Body/"DETAILS">. =head1 DIAGNOSTICS =over 4 =item Warning: Content-Transfer-Encoding '$te' requires explicit charset, defaulted to utf-8. Cast by C<encode()> =item Fault: Unable to read file $name for message body scalar: $! A L<Mail::Message::Body::String|Mail::Message::Body::String> object is to be created from a named file, but it is impossible to read that file to retrieve the lines within. Cast by C<new()> =item Error: cannot concatenate element $which Cast by C<concatenate()> =item Fault: cannot open $file to write body: $! Cast by C<write()> =item Warning: charset '$name' is not known. The encoding or decoding of a message body encounters a character set which is not understood by Perl's Encode module. Cast by C<encode()> =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =item Fault: error closing $file after write body: $! Cast by C<write()> =item Warning: no decoder defined for transfer encoding '$encoding'. The data (message body) is encoded in a way which is not currently understood, therefore no decoding (or recoding) can take place. Cast by C<encode()> =item Warning: no encoder defined for transfer encoding '$encoding'. The data (message body) has been decoded, but the required encoding is unknown. The decoded data is returned. Cast by C<encode()> =item Error: no filename parameter for write() body. Cast by C<write()> =item Error: part number needs multi-part or nested. Cast by C<partNumberOf()> =item Error: unknown line terminator '$eol'. Cast by C<eol()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. ���������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Body/Encode.pod��������������������������������������������������0000644�0001750�0000144�00000023025�15166136117�022247� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Body::Encode - organize general message encodings =head1 SYNOPSIS my Mail::Message $msg = ...; my $decoded = $msg->decoded; my $encoded = $msg->encode(mime_type => 'image/gif', transfer_encoding => 'base64'); my $body = $msg->body; my $decoded = $body->decoded; my $encoded = $body->encode(transfer_encoding => '7bit'); =head1 DESCRIPTION Manages the message's body encodings and decodings on request of the main program. This package adds functionality to the L<Mail::Message::Body|Mail::Message::Body> class when the L<decoded()|Mail::Message::Body/"Constructing a body"> or L<encode()|Mail::Message::Body::Encode/"Constructing a body"> method is called. Four types of encodings are handled (in the right order) =over 4 =item * eol encoding Various operating systems have different ideas about how to encode the line termination. UNIX uses a LF character, MacOS uses a CR, and Windows uses a CR/LF combination. Messages which are transported over Internet will always use the CRLF separator. =item * transfer encoding Messages transmitted over Internet have to be plain ASCII. Complicated characters and binary files (like images and archives) must be encoded during transmission to an ASCII representation. The implementation of the required encoders and decoders is found in the L<Mail::Message::TransferEnc|Mail::Message::TransferEnc> set of packages. The related manual page lists the transfer encodings which are supported. =item * mime-type translation NOT IMPLEMENTED YET =item * charset conversion =back =head1 METHODS =head2 Attributes =over 4 =item $obj-E<gt>B<charsetDetectAlgorithm>( [CODE|undef|METHOD] ) When a body object does not specify its character-set, but that detail is required, then it gets autodetected. The default algorithm is implemented in L<charsetDetect()|Mail::Message::Body::Encode/"Constructing a body">. You may change this default algorithm, or pass option C<charset_detect> for each call to L<encode()|Mail::Message::Body::Encode/"Constructing a body">. When you call this method with an explicit C<undef>, you reset the default. (Without parameter) the current algorithm (C<CODE> or method name) is returned. =back =head2 Constructing a body =over 4 =item $obj-E<gt>B<charsetDetect>(%options) This is tricky. It is hard to detect whether the body originates from the program, or from an external source. And what about a database database? are those octets or strings? Please read L<Mail::Message::Body/Autodetection of character-set>. -Option --Default external <C<false>> =over 2 =item external => BOOLEAN Do only consider externally valid character-sets, implicitly: C<PERL> is not an acceptable answer. =back =item $obj-E<gt>B<check>() Check the content of the body not to include illegal characters. Which characters are considered illegal depends on the encoding of this body. A body is returned which is checked. This may be the body where this method is called upon, but also a new object, when serious changes had to be made. If the check could not be made, because the decoder is not defined, then C<undef> is returned. =item $obj-E<gt>B<encode>(%options) Encode (translate) a L<Mail::Message::Body|Mail::Message::Body> into a different format. See the DESCRIPTION above. Options which are not specified will not trigger conversions. -Option --Default charset PERL charset_detect <built-in> mime_type undef result_type <same as source> transfer_encoding undef =over 2 =item charset => CHARSET|'PERL' Only applies when the mime_type is textual. If the CHARSET is explicitly specified (for instance C<iso-8859-10>, then the data is being interpreted as raw bytes (blob), not as text. However, in case of C<PERL>, it is considered to be an internal representation of characters (either latin1 or Perl's utf8 --not the same as utf-8--, you should not want to know). This setting overrules the charset attribute in the mime_type FIELD. =item charset_detect => CODE When the body does not contain an explicit charset specification, then the RFC says it is C<us-ascii>. In reality, this is not C<true>: it is just an unknown character set. This often happens when text files are included as attachment, for instance a footer attachment. When you want to be smarter than the default charset detector, you can provide your own function for this parameter. The function will get the transfer-decoded version of this body. You can change the default globally via L<charsetDetectAlgorithm()|Mail::Message::Body::Encode/"Attributes">. =item mime_type => STRING|FIELD Convert into the specified mime type, which can be specified as STRING or FIELD. The FIELD is a L<Mail::Message::Field|Mail::Message::Field>-object, representing a C<Content-Type> mime header. The STRING must be valid content for such header, and will be converted into a FIELD object. The FIELD may contain attributes. Usually, it has a C<charset> attribute, which explains the CHARSET of the content after content transfer decoding. The C<charset> option will update/add this attribute. Otherwise (hopefully in rare cases) the CHARSET will be auto-detected when the body gets decoded. =item result_type => CLASS The type of body to be created when the body is changed to fulfill the request on re-coding. Also the intermediate stages in the translation process (if needed) will use this type. CLASS must extend L<Mail::Message::Body|Mail::Message::Body>. =item transfer_encoding => STRING|FIELD =back =item $obj-E<gt>B<encoded>(%options) Encode the body to a format what is acceptable to transmit or write to a folder file. This returns the body where this method was called upon when everything was already prepared, or a new encoded body otherwise. In either case, the body is checked. -Option --Default charset_detect <the default> =over 2 =item charset_detect => CODE See L<charsetDetectAlgorithm()|Mail::Message::Body::Encode/"Attributes">. =back =item $obj-E<gt>B<eol>( ['CR'|'LF'|'CRLF'|'NATIVE'] ) Returns the character (or characters) which are used to separate lines within this body. When a kind of separator is specified, the body is translated to contain the specified line endings. » example: my $body = $msg->decoded->eol('NATIVE'); my $char = $msg->decoded->eol; =item $obj-E<gt>B<unify>($body) Unify the type of the given C<$body> objects with the type of the called body. C<undef> is returned when unification is impossible. If the bodies have the same settings, the C<$body> object is returned unchanged. Examples: my $bodytype = Mail::Message::Body::Lines; my $html = $bodytype->new(mime_type=>'text/html', data => []); my $plain = $bodytype->new(mime_type=>'text/plain', ...); my $unified = $html->unify($plain); # $unified is the data of plain translated to html (if possible). =back =head2 About the payload =over 4 =item $obj-E<gt>B<dispositionFilename>( [$directory] ) Various fields are searched for C<filename> and C<name> attributes. Without C<$directory>, the name found will be returned unmodified. When a C<$directory> is given, a filename is composed. For security reasons, only the basename of the found name gets used and many potentially dangerous characters removed. If no name was found, or when the found name is already in use, then an unique name is generated. Don't forget to read RFC6266 section 4.3 for the security aspects in your email application. =item $obj-E<gt>B<isBinary>() Returns C<true> when the un-encoded message is binary data. This information is retrieved from knowledge provided by L<MIME::Types|MIME::Types>. =item $obj-E<gt>B<isText>() Returns C<true> when the un-encoded message contains printable text. =back =head2 Internals =over 4 =item $any-E<gt>B<addTransferEncHandler>( $name, <$class|$object> ) Relate the NAMEd transfer encoding to an OBJECTs or object of the specified C<$class>. In the latter case, an object of that C<$class> will be created on the moment that one is needed to do encoding or decoding. The C<$class> or C<$object> must extend L<Mail::Message::TransferEnc|Mail::Message::TransferEnc>. It will replace existing class and object for this C<$name>. Why aren't you contributing this class to MailBox? =item $obj-E<gt>B<getTransferEncHandler>($type) Get the transfer encoder/decoder which is able to handle C<$type>, or return C<undef> if there is no such handler. =back =head1 DIAGNOSTICS =over 4 =item Warning: Content-Transfer-Encoding '$te' requires explicit charset, defaulted to utf-8. Cast by C<encode()> =item Warning: charset '$name' is not known. The encoding or decoding of a message body encounters a character set which is not understood by Perl's Encode module. Cast by C<encode()> =item Warning: no decoder defined for transfer encoding '$encoding'. The data (message body) is encoded in a way which is not currently understood, therefore no decoding (or recoding) can take place. Cast by C<encode()> =item Warning: no encoder defined for transfer encoding '$encoding'. The data (message body) has been decoded, but the required encoding is unknown. The decoded data is returned. Cast by C<encode()> =item Error: unknown line terminator '$eol'. Cast by C<eol()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Body/Encode.pm���������������������������������������������������0000644�0001750�0000144�00000024407�15166136116�022105� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::Body;{ our $VERSION = '4.05'; } use parent 'Mail::Reporter'; use strict; use warnings; use utf8; use Log::Report 'mail-message', import => [ qw/__x error panic warning/ ]; use MIME::Types (); use File::Basename qw/basename/; use Encode qw/find_encoding from_to encode_utf8/; use List::Util qw/first/; use Scalar::Util qw/blessed/; use Mail::Message::Field (); use Mail::Message::Field::Full (); # http://www.iana.org/assignments/character-sets use Encode::Alias; define_alias(qr/^unicode-?1-?1-?utf-?([78])$/i => '"UTF-$1"'); # rfc1642 my $mime_types; #-------------------- #-------------------- sub charsetDetectAlgorithm(;$) { my $self = shift; $self->{MMBE_det} = shift if @_; $self->{MMBE_det} || 'charsetDetect'; } #-------------------- sub _char_enc($) { my ($self, $charset) = @_; return undef if !$charset || $charset eq 'PERL'; my $enc = find_encoding $charset or warning __x"charset '{name}' is not known.", name => $charset; $enc; } sub encode(@) { my ($self, %args) = @_; my $bodytype = $args{result_type} || ref $self; ### The content type my $type_from = $self->type; my $type_to = $args{mime_type} || $type_from->clone->study; blessed $type_to or $type_to = Mail::Message::Field::Full->new('Content-Type' => $type_to); ### Detect specified transfer-encodings my $transfer = $args{transfer_encoding} || $self->transferEncoding->clone; blessed $transfer or $transfer = Mail::Message::Field->new('Content-Transfer-Encoding' => $transfer); my $trans_was = lc $self->transferEncoding; my $trans_to = lc $transfer; ### Detect specified charsets my $is_text = $type_from =~ m!^text/!i; my ($char_was, $char_to, $from, $to); if($is_text) { $char_was = $type_from->attribute('charset'); # sometimes missing $char_to = $type_to->attribute('charset'); # usually missing if(my $charset = delete $args{charset}) { # Explicitly stated output charset if(!$char_to || $char_to ne $charset) { $char_to = $charset; $type_to->attribute(charset => $char_to); } } elsif(!$char_to && $char_was) { # By default, do not change charset $char_to = $char_was; $type_to->attribute(charset => $char_to); } if($char_to && $trans_to ne 'none' && $char_to eq 'PERL') { # We cannot leave the body into the 'PERL' charset when transfer-encoding is applied. warning __x"Content-Transfer-Encoding '{te}' requires explicit charset, defaulted to utf-8.", te => $trans_to; $char_to = 'utf-8'; } $from = $self->_char_enc($char_was); $to = $self->_char_enc($char_to); if($from && $to) { if($char_was ne $char_to && $from->name eq $to->name) { # modify source charset into a different alias $type_from->attribute(charset => $char_to); $char_was = $char_to; $from = $to; } return $self if $trans_was eq $trans_to && $char_was eq $char_to; } } elsif($trans_was eq $trans_to) { # No changes needed; return $self; } ### Apply transfer-decoding my $decoded; if($trans_was eq 'none') { $decoded = $self } elsif(my $decoder = $self->getTransferEncHandler($trans_was)) { $decoded = $decoder->decode($self, result_type => $bodytype) } else { warning __x"no decoder defined for transfer encoding '{encoding}'.", encoding => $trans_was; return $self; } ### Apply character-set recoding my $recoded; if($is_text) { unless($char_was) { # When we do not know the character-sets, try to auto-detect my $auto = $args{charset_detect} || $self->charsetDetectAlgorithm; $char_was = $decoded->$auto; $from = $self->_char_enc($char_was); $decoded->type->attribute(charset => $char_was); unless($char_to) { $char_to = $char_was; $type_to->attribute(charset => $char_to); $to = $from; } } my $text = $decoded->string; my $new_data = $to && $char_was eq 'PERL' ? $to->encode($text) : $from && $char_to eq 'PERL' ? $from->decode($text) : $to && $from && $char_was ne $char_to ? $to->encode($from->decode($text)) : undef; $recoded = $new_data ? $bodytype->new(based_on => $decoded, data => $new_data, mime_type => $type_to, checked => 1) : $decoded; } else { $recoded = $decoded; } ### Apply transfer-encoding my $trans; if($trans_to ne 'none') { $trans = $self->getTransferEncHandler($trans_to) or warning __x"no encoder defined for transfer encoding '{encoding}'.", encoding => $trans_to; } defined $trans ? $trans->encode($recoded, result_type => $bodytype) : $recoded; } sub charsetDetect(%) { my ($self, %args) = @_; my $text = $self->string; # Flagged as UTF8, so certainly created by the Perl program itself: # the content is not octets. if(utf8::is_utf8($text)) { $args{external} or return 'PERL'; $text = encode_utf8 $text; } # Only look for normal characters, first 1920 unicode characters # When there is any octet in 'utf-encoding'-space, but not an # legal utf8, than it's not utf8. return 'utf-8' if $text =~ m/ [\xC0-\xDF][\x80-\xBF] # 110xxxxx, 10xxxxxx | [\xE0-\xEF][\x80-\xBF]{2} # 1110xxxx, (10xxxxxx)² | [\xF0-\xF7][\x80-\xBF]{3} # 11110xxx, (10xxxxxx)3 /x && $text !~ m/[\xC0-\xFF][^\x80-\xBF]/ && $text !~ m/[\xC0-\xFF]\z/; # Produce 'us-ascii' when it suffices: it is the RFC compliant # default charset. $text =~ m/[\x80-\xFF]/ ? 'cp1252' : 'us-ascii'; } sub check() { my $self = shift; return $self if $self->checked; my $eol = $self->eol; my $encoding = $self->transferEncoding->body; return $self->eol($eol) if $encoding eq 'none'; my $encoder = $self->getTransferEncHandler($encoding); my $checked = $encoder ? $encoder->check($self)->eol($eol) : $self->eol($eol); $checked->checked(1); $checked; } sub encoded(%) { my ($self, %args) = @_; my $mime = $self->mimeType; if($mime->isBinary) { return $self->transferEncoding eq 'none' ? $self->encode(transfer_encoding => $mime->encoding) : $self->check; } my $charset = my $old_charset = $self->charset || ''; if(!$charset || $charset eq 'PERL') { my $auto = $args{charset_detect} || $self->charsetDetectAlgorithm; $charset = $self->$auto(external => 1); } my $enc_was = $self->transferEncoding; my $enc = $enc_was eq 'none' ? $mime->encoding : $enc_was; $enc_was eq $enc && $old_charset eq $charset ? $self->check : $self->encode(transfer_encoding => $enc, charset => $charset); } my $native_eol = $^O =~ m/^win/i ? 'CRLF' : $^O =~ m/^mac/i ? 'CR' : 'LF'; sub eol(;$) { my $self = shift; my $old_eol = $self->{MMBE_eol} ||= $native_eol; @_ or return $old_eol; my $eol = shift; $eol = $native_eol if $eol eq 'NATIVE'; $eol ne $old_eol || !$self->checked or return $self; my $lines = $self->lines; my $wrong = $eol eq 'CRLF' ? first { !/\015\012$/ } @$lines : $eol eq 'CR' ? first { !/\015$/ } @$lines : $eol eq 'LF' ? first { /\015\012$|\015$/ } @$lines : error(__x"unknown line terminator '{eol}'.", eol => $eol); $wrong or return $self; my $expect = $eol eq 'CRLF' ? "\015\012" : $eol eq 'CR' ? "\015" : "\012"; my @new = map s/[\015\012]+$/$expect/r, @$lines; (ref $self)->new(based_on => $self, eol => $eol, data => \@new); } sub unify($) { my ($self, $body) = @_; return $self if $self==$body; my $mime = $self->type; my $transfer = $self->transferEncoding; my $encoded = $body->encode(mime_type => $mime, transfer_encoding => $transfer); # Encode makes the best of it, but is it good enough? $mime eq $encoded->type && $transfer eq $encoded->transferEncoding ? $encoded : undef; } #-------------------- sub isBinary() { my $self = shift; $mime_types ||= MIME::Types->new(only_complete => 1); my $type = $self->type or return 1; my $mime = $mime_types->type($type->body) or return 1; $mime->isBinary; } sub isText() { not shift->isBinary } sub dispositionFilename(;$) { my $self = shift; my $raw; my $field; if($field = $self->disposition) { $field = $field->study if $field->can('study'); $raw = $field->attribute('filename') || $field->attribute('file') || $field->attribute('name'); } if(!defined $raw && ($field = $self->type)) { $field = $field->study if $field->can('study'); $raw = $field->attribute('filename') || $field->attribute('file') || $field->attribute('name'); } my $base; if(!defined $raw || !length $raw) {} elsif(index($raw, '?') >= 0) { eval 'require Mail::Message::Field::Full'; $base = Mail::Message::Field::Full->decode($raw); } else { $base = $raw; } @_ or return $base; my $dir = shift; my $filename = ''; if(defined $base) # RFC6266 section 4.3, very safe { $filename = basename $base =~ s/\s+/ /gr =~ s/ $//r =~ s/^ //r =~ s/[^\w .-]//gr; } my ($filebase, $ext) = length $filename && $filename =~ m/(.*)\.([^.]+)/ ? ($1, $2) : (part => ($self->mimeType->extensions)[0] || 'raw'); my $fn = File::Spec->catfile($dir, "$filebase.$ext"); for(my $unique = 1; -e $fn; $unique++) { $fn = File::Spec->catfile($dir, "$filebase-$unique.$ext"); } $fn; } #-------------------- my %transfer_encoder_classes = ( 'base64' => 'Mail::Message::TransferEnc::Base64', 'binary' => 'Mail::Message::TransferEnc::Binary', '8bit' => 'Mail::Message::TransferEnc::EightBit', 'quoted-printable' => 'Mail::Message::TransferEnc::QuotedPrint', '7bit' => 'Mail::Message::TransferEnc::SevenBit', ); my %transfer_encoders; # they are reused. sub getTransferEncHandler($) { my ($self, $type) = @_; return $transfer_encoders{$type} if exists $transfer_encoders{$type}; # they are reused. my $class = $transfer_encoder_classes{$type} or return; eval "require $class"; panic "Cannot load $class: $@\n" if $@; $transfer_encoders{$type} = $class->new; } sub addTransferEncHandler($$) { my ($this, $name, $what) = @_; my $class; if(ref $what) { $transfer_encoders{$name} = $what; $class = ref $what; } else { delete $transfer_encoders{$name}; $class = $what; } $transfer_encoder_classes{$name} = $class; $this; } 1; ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Head/������������������������������������������������������������0000755�0001750�0000144�00000000000�15166136132�020305� 5����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Head/ResentGroup.pod���������������������������������������������0000644�0001750�0000144�00000027342�15166136120�023273� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Head::ResentGroup - header fields tracking message delivery =head1 INHERITANCE Mail::Message::Head::ResentGroup is a Mail::Message::Head::FieldGroup is a Mail::Reporter =head1 SYNOPSIS use Mail::Message::Head::ResentGroup; my $rg = Mail::Message::Head::ResentGroup->new(head => $head, From => 'me@home.nl', To => 'You@tux.aq'); $head->addResentGroup($rg); my $rg = $head->addResentGroup(From => 'me'); my @from = $rg->From; my @rgs = $head->resentGroups; $rg[2]->delete if @rgs > 2; =head1 DESCRIPTION A I<resent group> is a set of header fields which describe one intermediate step in the message transport. Resent groups B<have NOTHING to do> with user activety; there is no relation to the C<user's> sense of creating reply, forward, or bounce messages at all! Extends L<"DESCRIPTION" in Mail::Message::Head::FieldGroup|Mail::Message::Head::FieldGroup/"DESCRIPTION">. =head1 METHODS Extends L<"METHODS" in Mail::Message::Head::FieldGroup|Mail::Message::Head::FieldGroup/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Message::Head::FieldGroup|Mail::Message::Head::FieldGroup/"Constructors">. =over 4 =item $obj-E<gt>B<clone>() Inherited, see L<Mail::Message::Head::FieldGroup/"Constructors"> =item $obj-E<gt>B<from>( [<$head|$message>, %options] ) WARNING: this method has two very different purposes. For backward compatibility reasons, without arguments L<resentFrom()|Mail::Message::Head::ResentGroup/"Access to the header"> is called to return the C<From> field of this resent group. With any arguments, a list of C<Mail::Message::Head::ResentGroup> objects is returned, taken from the specified C<$message> or message C<$head>. Improves base, see L<Mail::Message::Head::FieldGroup/"Constructors"> =item $any-E<gt>B<implementedTypes>() Inherited, see L<Mail::Message::Head::FieldGroup/"Constructors"> =item $class-E<gt>B<new>( [@fields], %options ) Create an object which maintains one set of resent headers. The C<@fields> are L<Mail::Message::Field|Mail::Message::Field> objects from the same header. All C<%options> which start with capitals will be used to construct additional fields. These option names are prepended with C<Resent-*>, keeping the capitization of what is specified. Improves base, see L<Mail::Message::Head::FieldGroup/"Constructors"> -Option --Defined in --Default Bcc undef Cc undef Date <now> Delivered-To undef From <required> Message-ID <uniquely created> Received <created> Return-Path undef Sender undef To undef head <created automatically> message_head undef software Mail::Message::Head::FieldGroup undef type Mail::Message::Head::FieldGroup undef version Mail::Message::Head::FieldGroup undef =over 2 =item Bcc => $text|$field|\@fields =item Cc => $text|$field|\@fields =item Date => $date When this resent-group is dispatched by the resender of the message. Like the C<Date> field, it is not the date and time that the message was actually transported. =item Delivered-To => $text|$field =item From => $text|$field|\@fields =item Message-ID => $text|$field The C<Resent-Message-ID> which identifies this resent group. The C<$field> must contain a message id. =item Received => $text The C<Received> field is the starting line for a resent group of header lines. If it is not defined, one is created using L<createReceived()|Mail::Message::Head::ResentGroup/"Internals">. =item Return-Path => $text|$field =item Sender => $text|$field Only permitted when more than one from address is specified. In this case, it selects one of these addresses as the main originator of the message. =item To => $text|$field|\@fields =item head => $head The C<$head> object where the data is stored in. By default a L<Mail::Message::Head::Partial|Mail::Message::Head::Partial> is created for you. =item message_head => $head The real C<$head> of the message where this resent group is part of. The C<head> used in this class is only a container for a subset of fields. =item software => STRING =item type => STRING =item version => STRING =back =back =head2 Attributes Extends L<"Attributes" in Mail::Message::Head::FieldGroup|Mail::Message::Head::FieldGroup/"Attributes">. =head2 The header Extends L<"The header" in Mail::Message::Head::FieldGroup|Mail::Message::Head::FieldGroup/"The header">. =over 4 =item $obj-E<gt>B<add>( <$field, $value> | $object ) All fields appear only once, so C<add()> behaves as L<set()|Mail::Message::Head::ResentGroup/"The header">. Improves base, see L<Mail::Message::Head::FieldGroup/"The header"> =item $obj-E<gt>B<addFields>( [$fieldnames] ) Not applicable to resent-groups: the same name can appear in more than one group. Therefore, a FIELDNAME is sufficiently distinctive. Improves base, see L<Mail::Message::Head::FieldGroup/"The header"> =item $obj-E<gt>B<attach>($head) Inherited, see L<Mail::Message::Head::FieldGroup/"The header"> =item $obj-E<gt>B<delete>() Inherited, see L<Mail::Message::Head::FieldGroup/"The header"> =item $obj-E<gt>B<fieldNames>() Inherited, see L<Mail::Message::Head::FieldGroup/"The header"> =item $obj-E<gt>B<fields>() Inherited, see L<Mail::Message::Head::FieldGroup/"The header"> =item $obj-E<gt>B<head>() Inherited, see L<Mail::Message::Head::FieldGroup/"The header"> =item $obj-E<gt>B<messageHead>( [$head] ) Returns (optionally after setting) the real header where this resent group belongs to. This may be C<undef> at creation, and then later filled in when L<Mail::Message::Head::Complete::addResentGroup()|Mail::Message::Head::Complete/"Access to the header"> is called. =item $obj-E<gt>B<orderedFields>() Returns the fields in the order as should appear in header according to rfc2822. For the C<Resent-*> fields of the group, the order is not that important, but the C<Return-Path>, C<Delivered-To>, and C<Received> must come first. Only fields mentioned in the RFC are returned. =item $obj-E<gt>B<set>( <$field, $value> | $object ) Set a C<$field> to a (new) C<$value>. The C<$field> names which do not start with 'Resent-*' but need it will have that added. It is also an option to specify a fully prepared message field C<$object>. In any case, a field C<$object> is returned. » example: my $rg = Mail::Message::Head::ResentGroup->new; $rg->set(To => 'fish@tux.aq'); $msg->addResentGroup($rg); $msg->send; $msg->bounce(To => 'fish@tux.aq')->send; # the same my $rg = Mail::Message::Head::ResentGroup->new(To => 'fish@tux.aq'); =back =head2 Access to the header Extends L<"Access to the header" in Mail::Message::Head::FieldGroup|Mail::Message::Head::FieldGroup/"Access to the header">. =over 4 =item $obj-E<gt>B<bcc>() In scalar context, the C<Resent-Bcc> field is returned. In list context, the addresses as specified within the bcc field are returned as L<Mail::Address|Mail::Address> objects. Bcc fields are not transmitted (hidden for external parties). =item $obj-E<gt>B<cc>() In scalar context, the C<Resent-Cc> field is returned. In list context, the addresses as specified within the cc field are returned as L<Mail::Address|Mail::Address> objects. =item $obj-E<gt>B<date>() Returns the C<Resent-Date> field, or C<undef> if it was not defined. =item $obj-E<gt>B<dateTimestamp>() The timestamp as stored within the C<Resent-Date> field converted to local system time. =item $obj-E<gt>B<deliveredTo>() The field which describes the C<Delivered-To> of this resent group. =item $obj-E<gt>B<destinations>() Returns a list of all addresses specified in the C<Resent-To>, C<-Cc>, and C<-Bcc> fields of this resent group. =item $any-E<gt>B<isResentGroupFieldName>($name) Z<> =item $obj-E<gt>B<messageId>() Returns the message-ID used for this group of resent lines. =item $obj-E<gt>B<received>() The field which describes the C<Received> data of this resent group. =item $obj-E<gt>B<receivedTimestamp>() The timestamp as stored within the C<Received> field converted to local system time. =item $obj-E<gt>B<resentFrom>() In scalar context, the C<Resent-From> field is returned. In list context, the addresses as specified within the from field are returned as L<Mail::Address|Mail::Address> objects. For reasons of backward compatibility and consistency, the L<from()|Mail::Message::Head::ResentGroup/"METHODS"> method will return the same as this method. =item $obj-E<gt>B<returnPath>() The field which describes the C<Return-Path> of this resent group. =item $obj-E<gt>B<sender>() In scalar context, the C<Resent-Sender> field is returned. In list context, the addresses as specified within the from field are returned as L<Mail::Address|Mail::Address> objects. =item $obj-E<gt>B<software>() Inherited, see L<Mail::Message::Head::FieldGroup/"Access to the header"> =item $obj-E<gt>B<to>() In scalar context, the C<Resent-To> field is returned. In list context, the addresses as specified within the to field are returned as L<Mail::Address|Mail::Address> objects. =item $obj-E<gt>B<type>() Inherited, see L<Mail::Message::Head::FieldGroup/"Access to the header"> =item $obj-E<gt>B<version>() Inherited, see L<Mail::Message::Head::FieldGroup/"Access to the header"> =back =head2 Internals Extends L<"Internals" in Mail::Message::Head::FieldGroup|Mail::Message::Head::FieldGroup/"Internals">. =over 4 =item $obj-E<gt>B<collectFields>( [$name] ) Inherited, see L<Mail::Message::Head::FieldGroup/"Internals"> =item $obj-E<gt>B<createReceived>( [$domain] ) Create a received field for this resent group. This is automatically called if none was specified during creation of this resent group object. The content of this field is described in RFC2821 section 4.4. It could use some improvement. =item $obj-E<gt>B<detected>($type, $software, $version) Inherited, see L<Mail::Message::Head::FieldGroup/"Internals"> =back =head2 Error handling Extends L<"Error handling" in Mail::Message::Head::FieldGroup|Mail::Message::Head::FieldGroup/"Error handling">. =over 4 =item $obj-E<gt>B<AUTOLOAD>() Inherited, see L<Mail::Reporter/"Error handling"> =item $obj-E<gt>B<details>() Inherited, see L<Mail::Message::Head::FieldGroup/"Error handling"> =item $obj-E<gt>B<notImplemented>() Inherited, see L<Mail::Reporter/"Error handling"> =item $obj-E<gt>B<print>( [$fh] ) Inherited, see L<Mail::Message::Head::FieldGroup/"Error handling"> =back =head2 Cleanup Extends L<"Cleanup" in Mail::Message::Head::FieldGroup|Mail::Message::Head::FieldGroup/"Cleanup">. =over 4 =item $obj-E<gt>B<DESTROY>() Inherited, see L<Mail::Reporter/"Cleanup"> =back =head1 DIAGNOSTICS =over 4 =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Head/ResentGroup.pm����������������������������������������������0000644�0001750�0000144�00000011164�15166136117�023126� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::Head::ResentGroup;{ our $VERSION = '4.05'; } use parent 'Mail::Message::Head::FieldGroup'; use strict; use warnings; use Log::Report 'mail-message', import => [ qw// ]; use Scalar::Util qw/weaken/; use Sys::Hostname qw/hostname/; use Mail::Address (); use Mail::Message::Field::Fast (); #-------------------- # all lower cased! my @ordered_field_names = ( 'return-path', 'delivered-to' , 'received', 'resent-date', 'resent-from', 'resent-sender', , 'resent-to', 'resent-cc', 'resent-bcc', 'resent-message-id' ); my %resent_field_names = map +($_ => 1), @ordered_field_names; sub init($$) { my ($self, $args) = @_; $self->SUPER::init($args); $self->{MMHR_real} = $args->{message_head}; $self->set(Received => $self->createReceived) if $self->orderedFields && ! $self->received; $self; } sub from($@) { @_==1 and return $_[0]->resentFrom; # backwards compat my ($class, $from, %args) = @_; my $head = $from->isa('Mail::Message::Head') ? $from : $from->head; my (@groups, $group, $return_path, $delivered_to); foreach my $field ($head->orderedFields) { my $name = $field->name; $resent_field_names{$name} or next; if($name eq 'return-path') { $return_path = $field } elsif($name eq 'delivered-to') { $delivered_to = $field } elsif(substr($name, 0, 7) eq 'resent-') { $group->add($field) if defined $group; } elsif($name eq 'received') { $group = Mail::Message::Head::ResentGroup ->new($field, message_head => $head); push @groups, $group; $group->add($delivered_to) if defined $delivered_to; undef $delivered_to; $group->add($return_path) if defined $return_path; undef $return_path; } } @groups; } #-------------------- sub messageHead(;$) { my $self = shift; @_ ? $self->{MMHR_real} = shift : $self->{MMHR_real}; } sub orderedFields() { my $head = shift->head; map { $head->get($_) || () } @ordered_field_names; } sub set($;$) { my $self = shift; my $field; if(@_==1) { $field = shift } else { my ($fn, $value) = @_; my $name = $resent_field_names{lc $fn} ? $fn : "Resent-$fn"; $field = Mail::Message::Field::Fast->new($name, $value); } $self->head->set($field); $field; } sub fields() { $_[0]->orderedFields } sub fieldNames() { map $_->Name, $_[0]->orderedFields } sub delete() { my $self = shift; my $head = $self->messageHead; $head->removeField($_) for $self->fields; $self; } sub add(@) { shift->set(@_) } sub addFields(@) { $_[0]->notImplemented } #-------------------- sub returnPath() { $_[0]->{MMHR_return_path} } sub deliveredTo() { $_[0]->head->get('Delivered-To') } sub received() { $_[0]->head->get('Received') } sub receivedTimestamp() { my $received = $_[0]->received or return; my $comment = $received->comment or return; Mail::Message::Field->dateToTimestamp($comment); } sub date($) { $_[0]->head->get('resent-date') } sub dateTimestamp() { my $date = $_[0]->date or return; Mail::Message::Field->dateToTimestamp($date->unfoldedBody); } sub resentFrom() { my $from = $_[0]->head->get('resent-from') or return (); wantarray ? $from->addresses : $from; } sub sender() { my $sender = $_[0]->head->get('resent-sender') or return (); wantarray ? $sender->addresses : $sender; } sub to() { my $to = $_[0]->head->get('resent-to') or return (); wantarray ? $to->addresses : $to; } sub cc() { my $cc = $_[0]->head->get('resent-cc') or return (); wantarray ? $cc->addresses : $cc; } sub bcc() { my $bcc = $_[0]->head->get('resent-bcc') or return (); wantarray ? $bcc->addresses : $bcc; } sub destinations() { my $self = shift; ($self->to, $self->cc, $self->bcc); } sub messageId() { $_[0]->head->get('resent-message-id') } sub isResentGroupFieldName($) { $resent_field_names{lc $_[1]} } #-------------------- my $unique_received_id = 'rc'.time; sub createReceived(;$) { my ($self, $domain) = @_; unless(defined $domain) { my $sender = ($self->sender)[0] || ($self->resentFrom)[0]; $domain = $sender->host if defined $sender; } my $received = "from $domain by ". hostname . ' with SMTP id ' . $unique_received_id++ . ' for ' . $self->head->get('Resent-To') # may be wrong . '; '. Mail::Message::Field->toDate; $received; } #-------------------- 1; ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Head/Complete.pod������������������������������������������������0000644�0001750�0000144�00000060607�15166136117�022575� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Head::Complete - the header of one message =head1 INHERITANCE Mail::Message::Head::Complete is a Mail::Message::Head is a Mail::Reporter Mail::Message::Head::Complete is extended by Mail::Message::Head::Partial Mail::Message::Replace::MailHeader Mail::Message::Head::Complete is realized by Mail::Message::Head::Delayed Mail::Message::Head::Subset =head1 SYNOPSIS my $head = Mail::Message::Head::Complete->new; See Mail::Message::Head =head1 DESCRIPTION Message headers can be in various states: unread, partially read, and fully read. This class represents a header of which all fields are known for sure: the complete set. Extends L<"DESCRIPTION" in Mail::Message::Head|Mail::Message::Head/"DESCRIPTION">. =head1 OVERLOADED Extends L<"OVERLOADED" in Mail::Message::Head|Mail::Message::Head/"OVERLOADED">. =over 4 =item overload: B<""> stringifaction Inherited, see L<Mail::Message::Head/"OVERLOADED"> =item overload: B<bool> true/false Inherited, see L<Mail::Message::Head/"OVERLOADED"> =back =head1 METHODS Extends L<"METHODS" in Mail::Message::Head|Mail::Message::Head/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Message::Head|Mail::Message::Head/"Constructors">. =over 4 =item $class-E<gt>B<build>( [PAIR|$field], ... ) Undefined values are interpreted as empty field values, and therefore skipped. Improves base, see L<Mail::Message::Head/"Constructors"> =item $obj-E<gt>B<clone>( [@names|ARRAY|Regexps] ) Make a copy of the header, optionally limited only to the header lines specified by C<@names>. See L<grepNames()|Mail::Message::Head::Complete/"Access to the header"> on the way these fields can be used. » example: my $newhead = $head->clone('Subject', 'Received'); =item $class-E<gt>B<new>(%options) Inherited, see L<Mail::Message::Head/"Constructors"> =back =head2 Attributes Extends L<"Attributes" in Mail::Message::Head|Mail::Message::Head/"Attributes">. =head2 The header Extends L<"The header" in Mail::Message::Head|Mail::Message::Head/"The header">. =over 4 =item $obj-E<gt>B<isDelayed>() Inherited, see L<Mail::Message::Head/"The header"> =item $obj-E<gt>B<isEmpty>() Inherited, see L<Mail::Message::Head/"The header"> =item $obj-E<gt>B<isModified>() Inherited, see L<Mail::Message::Head/"The header"> =item $obj-E<gt>B<knownNames>() Inherited, see L<Mail::Message::Head/"The header"> =item $obj-E<gt>B<message>( [$message] ) Inherited, see L<Mail::Message::Head/"The header"> =item $obj-E<gt>B<modified>( [BOOLEAN] ) Inherited, see L<Mail::Message::Head/"The header"> =item $obj-E<gt>B<nrLines>() Return the number of lines needed to display this header (including the trailing newline) =item $obj-E<gt>B<orderedFields>() Inherited, see L<Mail::Message::Head/"The header"> =item $obj-E<gt>B<size>() Return the number of bytes needed to display this header (including the trailing newline). On systems which use CRLF as line separator, the number of lines in the header (see L<nrLines()|Mail::Message::Head::Complete/"The header">) must be added to find the actual size in the file. =item $obj-E<gt>B<wrap>($integer) Re-fold all fields from the header to contain at most C<$integer> number of characters per line. » example: re-folding a header $msg->head->wrap(78); =back =head2 Access to the header Extends L<"Access to the header" in Mail::Message::Head|Mail::Message::Head/"Access to the header">. =over 4 =item $obj-E<gt>B<add>( $field | $line | <$name, $body, [$attrs]> ) Add a field to the header. If a field is added more than once, all values are stored in the header, in the order they are added. When a C<$field> object is specified (some L<Mail::Message::Field|Mail::Message::Field> instance), that will be added. Another possibility is to specify a raw header C<$line>, or a header line nicely split-up in C<$name> and C<$body>, in which case the field constructor is called for you. C<$line> or C<$body> specifications which are terminated by a new-line are considered to be correctly folded. Lines which are not terminated by a new-line will be folded when needed: new-lines will be added where required. It is strongly advised to let MailBox do the folding for you. The return value of this method is the L<Mail::Message::Field|Mail::Message::Field> object which is created (or was specified). » example: my $head = Mail::Message::Head->new; $head->add('Subject: hi!'); $head->add(From => 'me@home'); my $field = Mail::Message::Field->new('To: you@there'); $head->add($field); my Mail::Message::Field $s = $head->add(Sender => 'I'); =item $obj-E<gt>B<addListGroup>($object) A I<list group> is a set of header fields which contain data about a mailing list which was used to transmit the message. See L<Mail::Message::Head::ListGroup|Mail::Message::Head::ListGroup> for details about the implementation of the C<$object>. When you have a list group prepared, you can add it later using this method. You will get your private copy of the list group data in return, because the same group can be used for multiple messages. » example: of adding a list group to a header my $lg = Mail::Message::Head::ListGroup->new(...); my $own_lg = $msg->head->addListGroup($lg); =item $obj-E<gt>B<addResentGroup>($resent_group|$data) Add a C<$resent_group> (a L<Mail::Message::Head::ResentGroup|Mail::Message::Head::ResentGroup> object) to the header. If you specify C<$data>, that is used to create such group first. If no C<Received> line is specified, it will be created for you. These header lines have nothing to do with the user's sense of C<reply> or C<forward> actions: these lines trace the e-mail transport mechanism. » example: my $rg = Mail::Message::Head::ResentGroup->new(head => $head, ...); $head->addResentGroup($rg); my $rg = $head->addResentGroup(From => 'me'); =item $obj-E<gt>B<addSpamGroup>($object) A I<spam fighting group> is a set of header fields which contains data which is used to fight spam. See L<Mail::Message::Head::SpamGroup|Mail::Message::Head::SpamGroup> for details about the implementation of the C<$object>. When you have a spam group prepared, you can add it later using this method. You will get your private copy of the spam group data in return, because the same group can be used for multiple messages. » example: of adding a spam group to a header my $sg = Mail::Message::Head::SpamGroup->new(...); my $own_sg = $msg->head->addSpamGroup($sg); =item $obj-E<gt>B<count>($name) Count the number of fields with this C<$name>. Most fields will return 1: only one occurrence in the header. As example, the C<Received> fields are usually present more than once. =item $obj-E<gt>B<delete>($name) Remove the field with the specified name. If the header contained multiple lines with the same name, they will be replaced all together. This method simply calls L<reset()|Mail::Message::Head::Complete/"Access to the header"> without replacement fields. READ THE IMPORTANT WARNING IN L<removeField()|Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<get>( $name, [$index] ) Inherited, see L<Mail::Message::Head/"Access to the header"> =item $obj-E<gt>B<grepNames>( [@names|ARRAY|Regexps] ) Filter from all header fields those with names which start will any of the specified list. When no names are specified, all fields will be returned. The list is ordered as they where read from file, or added later. The C<@names> are considered regular expressions, and will all be matched case insensitive and attached to the front of the string only. You may also specify one or more prepared regexes. » example: my @f = $head->grepNames(); # same as $head->orderedFields my @f = $head->grepNames('X-', 'Subject', '); my @to = $head->grepNames('To\b'); # will only select To =item $obj-E<gt>B<listGroup>() Returns a I<list group> description: the set of headers which form the information about mailing list software used to transport the message. See also L<addListGroup()|Mail::Message::Head::Complete/"Access to the header"> and L<removeListGroup()|Mail::Message::Head::Complete/"Access to the header">. » example: use of listGroup() if(my $lg = $msg->head->listGroup) { $lg->print(\*STDERR); $lg->delete; } $msg->head->removeListGroup; =item $obj-E<gt>B<names>() Returns a full ordered list of known field names, as defined in the header. Fields which were reset() to be empty will still be listed here. =item $obj-E<gt>B<print>( [$fh] ) Print all headers to the specified C<$fh>, by default the selected filehandle. See L<printUndisclosed()|Mail::Message::Head::Complete/"Access to the header"> to limit the headers to include only the public headers. » example: $head->print(\*OUT); $head->print; # to selected file open my ($fh), '>:raw', $filename; $head->print($fh); =item $obj-E<gt>B<printSelected>($fh, <STRING|Regexp>, ...) Like the usual L<print()|Mail::Message::Head::Complete/"Access to the header">, the header lines are printed to the specified C<$fh>. In this case, however, only the fields with names as specified by C<STRING> (case insensative) or Regexp are printed. They will stay the in-order of the source header. » example: printing only a subset of the fields $head->printSelected(STDOUT, qw/Subject From To/, qr/^x\-(spam|xyz)\-/i) =item $obj-E<gt>B<printUndisclosed>( [$fh] ) Like the usual L<print()|Mail::Message::Head::Complete/"Access to the header">, the header lines are printed to the specified C<$fh>, by default the selected filehandle. In this case, however, C<Bcc> and C<Resent-Bcc> lines are included. =item $obj-E<gt>B<removeContentInfo>() Remove all body related fields from the header. The header will become partial. =item $obj-E<gt>B<removeField>($field) Remove the specified C<$field> object from the header. This is useful when there are possible more than one fields with the same name, and you need to remove exactly one of them. Also have a look at L<delete()|Mail::Message::Head::Complete/"Access to the header">, L<reset()|Mail::Message::Head::Complete/"Access to the header">, and L<set()|Mail::Message::Head::Complete/"Access to the header">. See also L<Mail::Message::Head::Partial::removeFields()|Mail::Message::Head::Partial/"Access to the header"> (mind the 's' at the end of the name), which accepts a string or regular expression as argument to select the fields to be removed. B<Warning>: for performance reasons, the header administration uses weak references (see L<Scalar::Util> method weaken()> to figure-out which fields have been removed. A header is a HASH of fields for fast search plus an ARRAY of weak references to remember the order of the fields, required for printing. If the field is removed from the HASH, the weak-ref is set to C<undef> and the field not printed. However... it is easy to disturb this process. Example: my $msg = ....; # subject ref-count = 1 + 0 = 1 $msg->head->delete('Subject'); # subject ref-count = 0 = 0: clean-up $msg->print; # subject doesn't show: ok But my $msg = ....; # subject ref-count = 1 + 0 = 1 my $s = $msg->head->get('subject'); # ref-count = 1 + 1 + 0 = 2 $msg->head->delete('Subject'); # subject ref-count = 1 + 0 = 1: no clean-up $msg->print; # subject DOES show: not ok undef $s; # ref-count becomes 0: clean-up $msg->print; # subject doesn't show: ok To avoid the latter situation, do not catch the field object, but only the field content. SAVE are all methods which return the text: my $s = $msg->head->get('subject')->body; my $s = $msg->head->get('subject')->unfoldedBody; my $s = $msg->head->get('subject')->foldedBody; my $s = $msg->head->get('subject')->foldedBody; my $s = $msg->get('subject'); my $s = $msg->subject; my $s = $msg->string; =item $obj-E<gt>B<removeFields>( <STRING|Regexp>, ... ) The header object is turned into a L<Mail::Message::Head::Partial|Mail::Message::Head::Partial> object which has a set of fields removed. Read about the implications and the possibilities in L<Mail::Message::Head::Partial::removeFields()|Mail::Message::Head::Partial/"Access to the header">. =item $obj-E<gt>B<removeFieldsExcept>( <STRING|Regexp>, ... ) The header object is turned into a L<Mail::Message::Head::Partial|Mail::Message::Head::Partial> object which has a set of fields removed. Read about the implications and the possibilities in L<Mail::Message::Head::Partial::removeFieldsExcept()|Mail::Message::Head::Partial/"Access to the header">. =item $obj-E<gt>B<removeListGroup>() Removes all fields related to mailing list administration at once. The header object is turned into a L<Mail::Message::Head::Partial|Mail::Message::Head::Partial> object. Read about the implications and the possibilities in L<Mail::Message::Head::Partial::removeListGroup()|Mail::Message::Head::Partial/"Access to the header">. =item $obj-E<gt>B<removeResentGroups>() Removes all resent groups at once. The header object is turned into a L<Mail::Message::Head::Partial|Mail::Message::Head::Partial> object. Read about the implications and the possibilities in L<Mail::Message::Head::Partial::removeResentGroups()|Mail::Message::Head::Partial/"Access to the header">. =item $obj-E<gt>B<removeSpamGroups>() Removes all fields which were added by various spam detection software at once. The header object is turned into a L<Mail::Message::Head::Partial|Mail::Message::Head::Partial> object. Read about the implications and the possibilities in L<Mail::Message::Head::Partial::removeSpamGroups()|Mail::Message::Head::Partial/"Access to the header">. =item $obj-E<gt>B<resentGroups>() Returns a list of L<Mail::Message::Head::ResentGroup|Mail::Message::Head::ResentGroup> objects which each represent one intermediate point in the message's transmission in the order as they appear in the header: the most recent one first. See also L<addResentGroup()|Mail::Message::Head::Complete/"Access to the header"> and L<removeResentGroups()|Mail::Message::Head::Complete/"Access to the header">. A resent group contains a set of header fields whose names start with C<Resent-*>. Before the first C<Resent> line is I<trace> information, which is composed of an optional C<Return-Path> field and an required C<Received> field. =item $obj-E<gt>B<reset>($name, @fields) Replace the values in the header fields named by C<$name> with the values specified in the list of C<@fields>. A single name can correspond to multiple repeated fields. READ THE IMPORTANT WARNING IN L<removeField()|Mail::Message::Head::Complete/"Access to the header"> Removing fields which are part of one of the predefined field groups is not a smart idea. You can better remove these fields as group, all together. For instance, the C<'Received'> lines are part of resent groups, C<'X-Spam'> is past of a spam group, and C<List-Post> belongs to a list group. You can delete a whole group with L<Mail::Message::Head::FieldGroup::delete()|Mail::Message::Head::FieldGroup/"The header">, or with methods which are provided by L<Mail::Message::Head::Partial|Mail::Message::Head::Partial>. If FIELDS is empty, the corresponding C<$name> fields will be removed. The location of removed fields in the header order will be remembered. Fields with the same name which are added later will appear at the remembered position. This is equivalent to the L<delete()|Mail::Message::Head::Complete/"Access to the header"> method. » example: # reduce number of 'Keywords' lines to last 5) my @keywords = $head->get('Keywords'); $head->reset('Keywords', @keywords[-5..-1]) if @keywords > 5; # Reduce the number of Received lines to only the last added one. my @rgs = $head->resentGroups; shift @rgs; # keep this one (later is added in front) $_->delete foreach @rgs; =item $obj-E<gt>B<set>( $field | $line | <$name, $body, [$attrs]> ) The C<set> method is similar to the L<add()|Mail::Message::Head::Complete/"Access to the header"> method, and takes the same options. However, existing values for fields will be removed before a new value is added. READ THE IMPORTANT WARNING IN L<removeField()|Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<spamDetected>() Returns whether one of the spam groups defines a report about spam. If there are not header fields in the message which relate to spam-detection software, C<undef> is returned. The spamgroups which report spam are returned. » example: $message->delete if $message->spamDetected; defined $message->spamDetected or call_spamassassin($message); =item $obj-E<gt>B<spamGroups>( [$names] ) Returns a list of L<Mail::Message::Head::SpamGroup|Mail::Message::Head::SpamGroup> objects, each collecting some lines which contain spam fighting information. When any C<$names> are given, then only these groups are returned. See also L<addSpamGroup()|Mail::Message::Head::Complete/"Access to the header"> and L<removeSpamGroups()|Mail::Message::Head::Complete/"Access to the header">. In scalar context, with exactly one NAME specified, that group will be returned. With more C<$names> or without C<$names>, a list will be returned (which defaults to the length of the list in scalar context). » example: use of listGroup() my @sg = $msg->head->spamGroups; $sg[0]->print(\*STDERR); $sg[-1]->delete; my $sg = $msg->head->spamGroups('SpamAssassin'); =item $obj-E<gt>B<string>() Returns the whole header as one scalar (in scalar context) or list of lines (list context). Triggers completion. =item $obj-E<gt>B<study>( $name, [$index] ) Inherited, see L<Mail::Message::Head/"Access to the header"> =back =head2 About the body Extends L<"About the body" in Mail::Message::Head|Mail::Message::Head/"About the body">. =over 4 =item $obj-E<gt>B<guessBodySize>() Inherited, see L<Mail::Message::Head/"About the body"> =item $obj-E<gt>B<guessTimeStamp>() Make a guess about when the message was origanally posted, based on the information found in the header's C<Date> field. For some kinds of folders, L<Mail::Message::guessTimestamp()|Mail::Message/"The header"> may produce a better result, for instance by looking at the modification time of the file in which the message is stored. Also some protocols, like POP can supply that information. =item $obj-E<gt>B<isMultipart>() Inherited, see L<Mail::Message::Head/"About the body"> =item $obj-E<gt>B<recvstamp>() Returns an indication about when the message was sent, but only using the C<Date> field in the header as last resort: we do not trust the sender of the message to specify the correct date. See L<timestamp()|Mail::Message::Head::Complete/"About the body"> when you do trust the sender. Many spam producers fake a date, which mess up the order of receiving things. The timestamp which is produced is derived from the Received headers, if they are present, and C<undef> otherwise. The timestamp is encoded as C<time> is on your system (see perldoc -f time), and as such usable for the C<gmtime> and C<localtime> methods. » example: of time-sorting folders with received messages my $folder = $mgr->open('InBox'); my @messages = sort {$a->recvstamp <=> $b->recvstamp} $folder->messages; » example: of time-sorting messages of mixed origin my $folder = $mgr->open('MyFolder'); # Pre-calculate timestamps to be sorted (for speed) my @stamps = map +[ ($_->timestamp || 0), $_ ], $folder->messages; my @sorted = map { $_->[1] } # get the message for the stamp sort {$a->[0] <=> $b->[0]} # stamps are numerics @stamps; =item $obj-E<gt>B<timestamp>() Returns an indication about when the message was sent, with as little guessing as possible. In this case, the date as specified by the sender is trusted. See L<recvstamp()|Mail::Message::Head::Complete/"About the body"> when you do not want to trust the sender. The timestamp is encoded as C<time> is on your system (see perldoc -f time), and as such usable for the C<gmtime> and C<localtime> methods. =back =head2 Internals Extends L<"Internals" in Mail::Message::Head|Mail::Message::Head/"Internals">. =over 4 =item $obj-E<gt>B<addNoRealize>($field) Inherited, see L<Mail::Message::Head/"Internals"> =item $obj-E<gt>B<addOrderedFields>($fields) Inherited, see L<Mail::Message::Head/"Internals"> =item $obj-E<gt>B<createFromLine>() For some mail-folder types separate messages by a line starting with 'C<From >'. If a message is moved to such folder from a folder-type which does not support these separators, this method is called to produce one. =item $obj-E<gt>B<createMessageId>() Creates a message-id for this message. This method will be run when a new message is created, or a message is discovered without the message-id header field. Message-ids are required for detection of message-threads. See L<messageIdPrefix()|Mail::Message::Head::Complete/"Internals">. =item $obj-E<gt>B<fileLocation>() Inherited, see L<Mail::Message::Head/"Internals"> =item $obj-E<gt>B<load>() Inherited, see L<Mail::Message::Head/"Internals"> =item $any-E<gt>B<messageIdPrefix>( [$prefix, [$hostname]|CODE] ) When options are provided, it sets a new way to create message-ids, as used by L<createMessageId()|Mail::Message::Head::Complete/"Internals">. You have two choices: either by providing a C<$prefix> and optionally a C<$hostname>, or a C<CODE> reference. The C<CODE> reference will be called with the header as first argument. You must ensure yourself that the returned value is RFC compliant. The C<$prefix> defaults to C<mailbox-$$>, the C<$hostname> defaults to the return of L<Net::Domains>'s function C<hostfqdn()>, or when not installed, the L<Sys::Hostname>'s function C<hostname()>. Inbetween the two, a nano-second time provided by L<Time::HiRes> is used. If that module is not available, C<time> is called at the start of the program, and incremented for each newly created id. In any case, a subroutine will be created to be used. A reference to that will be returned. When the method is called without arguments, but no subroutine is defined yet, one will be created. » example: setting a message prefix $head->messageIdPrefix('prefix'); Mail::Message::Head::Complete->messageIdPrefix('prefix'); my $code = $head->messageIdPrefix('mailbox', 'nohost'); sub new_msgid() { my $head = shift; "myid-$$-${(rand 10000)}@example.com"; } $many_msg->messageIdPrefix(\&new_msgid); Mail::Message::Head::Complete->messageIdPrefix(&new_msgid); =item $obj-E<gt>B<moveLocation>($distance) Inherited, see L<Mail::Message::Head/"Internals"> =item $obj-E<gt>B<read>($parser) Inherited, see L<Mail::Message::Head/"Internals"> =item $obj-E<gt>B<setNoRealize>($field) Inherited, see L<Mail::Message::Head/"Internals"> =back =head2 Error handling Extends L<"Error handling" in Mail::Message::Head|Mail::Message::Head/"Error handling">. =over 4 =item $obj-E<gt>B<AUTOLOAD>() Inherited, see L<Mail::Reporter/"Error handling"> =item $obj-E<gt>B<notImplemented>() Inherited, see L<Mail::Reporter/"Error handling"> =back =head2 Cleanup Extends L<"Cleanup" in Mail::Message::Head|Mail::Message::Head/"Cleanup">. =over 4 =item $obj-E<gt>B<DESTROY>() Inherited, see L<Mail::Reporter/"Cleanup"> =back =head1 DETAILS Extends L<"DETAILS" in Mail::Message::Head|Mail::Message::Head/"DETAILS">. =head1 DIAGNOSTICS =over 4 =item Warning: cannot remove field $name from header: not found. You ask to remove a field which is not known in the header. Using L<delete()|Mail::Message::Head::Complete/"Access to the header">, L<reset()|Mail::Message::Head::Complete/"Access to the header">, or L<set()|Mail::Message::Head::Complete/"Access to the header"> to do the job will not result in warnings: those methods check the existence of the field first. Cast by C<removeField()> =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =item Warning: field objects have an implied name ($name) Cast by C<build()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. �������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Head/ListGroup.pm������������������������������������������������0000644�0001750�0000144�00000015473�15166136116�022607� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later #XXX Do the list still exist? #XXX Add Simplelists package Mail::Message::Head::ListGroup;{ our $VERSION = '4.05'; } use parent 'Mail::Message::Head::FieldGroup'; use strict; use warnings; use Log::Report 'mail-message', import => [ qw/__x error/ ]; use List::Util qw/first/; use Scalar::Util qw/blessed/; #-------------------- sub init($$) { my ($self, $args) = @_; $self->SUPER::init($args); my $address = $args->{address}; if(!defined $address) { ; } elsif(!ref $address || !$address->isa('Mail::Message::Field::Address')) { require Mail::Message::Field::Address; my $mi = Mail::Message::Field::Address->coerce($address) or error __x"cannot convert '{address}' into an address object.", address => $address; $address = $mi; } $self->{MMHL_address} = $address if defined $args->{address}; $self->{MMHL_listname} = $args->{listname} if defined $args->{listname}; $self->{MMHL_rfc} = $args->{rfc} if defined $args->{rfc}; $self->{MMHL_fns} = []; $self; } sub from($) { my ($class, $from) = @_; my $head = $from->isa('Mail::Message::Head') ? $from : $from->head; my $self = $class->new(head => $head); $self->collectFields or return (); my ($type, $software, $version, $field); if(my $communigate = $head->get('X-ListServer')) { ($software, $version) = $communigate =~ m/^(.*)\s+LIST\s*([\d.]+)\s*$/i; $type = ($software =~ m/Pro/ ? 'CommuniGatePro' : 'CommuniGate'); } elsif(my $mailman = $head->get('X-Mailman-Version')) { $version = "$mailman"; $type = 'Mailman'; } elsif(my $majordomo = $head->get('X-Majordomo-Version')) { $version = "$majordomo"; $type = 'Majordomo'; } elsif(my $ecartis = $head->get('X-Ecartis-Version')) { ($software, $version) = $ecartis =~ m/^(.*)\s+(v[\d.]+)/; $type = 'Ecartis'; } elsif(my $listar = $head->get('X-Listar-Version')) { ($software, $version) = $listar =~ m/^(.*?)\s+(v[\w.]+)/; $type = 'Listar'; } elsif(defined($field = $head->get('List-Software')) && $field =~ m/listbox/i) { ($software, $version) = $field =~ m/^(\S*)\s*(v[\d.]+)\s*$/; $type = 'Listbox'; } elsif($field = first { m!LISTSERV-TCP/IP!s } $head->get('Received')) { # Listserv is hard to recognise ($software, $version) = $field =~ m!\( (LISTSERV-TCP/IP) \s+ release \s+ (\S+) \)!xs; $type = 'Listserv'; } elsif(defined($field = $head->get('X-Mailing-List')) && $field =~ m[archive/latest]) { $type = 'Smartlist' } elsif(defined($field = $head->get('Mailing-List')) && $field =~ m/yahoo/i ) { $type = 'YahooGroups' } elsif(defined($field) && $field =~ m/(ezmlm)/i ) { $type = 'Ezmlm' } elsif(my $fml = $head->get('X-MLServer')) { ($software, $version) = $fml =~ m/^\s*([^\s\[]+)\s*\[\S*\s*([^\]]*?)\s*\]/; $type = 'FML'; } elsif(defined($field = $head->get('List-Subscribe') || $head->get('List-Unsubscribe')) && $field =~ m/sympa/i) { $type = 'Sympa' } elsif(first { m/majordom/i } $head->get('Received')) { # Majordomo is hard to recognize $type = "Majordomo"; } elsif(defined($field = $head->get('List-ID')) && $field =~ m/listbox\.com/i) { $type = "Listbox" } $self->detected($type, $software, $version); $self; } sub rfc() { my $self = shift; return $self->{MMHL_rfc} if defined $self->{MMHL_rfc}; my $head = $self->head; defined $head->get('List-Post') ? 'rfc2369' : defined $head->get('List-Id') ? 'rfc2919' : undef; } sub address() { my $self = shift; return $self->{MMHL_address} if exists $self->{MMHL_address}; my $type = $self->type || 'Unknown'; my $head = $self->head; my ($field, $address); if($type eq 'Smartlist' && defined($field = $head->get('X-Mailing-List'))) { $address = $1 if $field =~ m/\<([^>]+)\>/ } elsif($type eq 'YahooGroups') { $address = $head->get('X-Apparently-To')->unfoldedBody } elsif($type eq 'Listserv') { $address = $head->get('Sender') } $address ||= $head->get('List-Post') || $head->get('Reply-To') || $head->get('Sender'); $address = $address->study if blessed $address; if(!defined $address) { ; } elsif(!ref $address) { $address =~ s/\bowner-|-(?:owner|bounce|admin)\@//i; $address = Mail::Message::Field::Address->new(address => $address); } elsif($address->isa('Mail::Message::Field::Addresses')) { # beautify $address = ($address->addresses)[0]; my $username = defined $address ? $address->username : ''; if($username =~ s/^owner-|-(owner|bounce|admin)$//i) { $address = Mail::Message::Field::Address->new(username => $username, domain => $address->domain); } } elsif($address->isa('Mail::Message::Field::URIs')) { my $uri = first { $_->scheme eq 'mailto' } $address->URIs; $address = defined $uri ? Mail::Message::Field::Address->new(address => $uri->to) : undef; } else # Don't understand life anymore :-( { undef $address; } $self->{MMHL_address} = $address; } sub listname() { my $self = shift; exists $self->{MMHL_listname} and return $self->{MMHL_listname}; my $head = $self->head; # Some lists have a field with the name only my $list = $head->get('List-ID') || $head->get('X-List') || $head->get('X-ML-Name'); my $listname; if(defined $list) { $listname = $list->study->decodedBody; } elsif(my $address = $self->address) { $listname = $address->phrase || $address->address; } $self->{MMHL_listname} = $listname; } #-------------------- my $list_field_names = qr/ ^ (?: List|X-Envelope|X-Original ) - | ^ (?: Precedence|Mailing-List|Approved-By ) $ | ^ X-(?: Loop|BeenThere|Sequence|List|Sender|MLServer ) $ | ^ X-(?: Mailman|Listar|Egroups|Encartis|ML ) - | ^ X-(?: Archive|Mailing|Original|Mail|ListServer ) - | ^ (?: Mail-Followup|Delivered|Errors|X-Apperently ) -To $ /xi; sub isListGroupFieldName($) { $_[1] =~ $list_field_names } #-------------------- sub collectFields() { my $self = shift; my @names = map $_->name, $self->head->grepNames($list_field_names); $self->addFields(@names); @names; } #-------------------- sub details() { my $self = shift; my $type = $self->type || 'Unknown'; my $software = $self->software; my $version = $self->version; undef $software if defined $software && $type eq $software; my $release = defined $software ? (defined $version ? " ($software $version)" : " ($software)") : (defined $version ? " ($version)" : ''); my $address = $self->address || 'unknown address'; my $fields = scalar $self->fields; "$type at $address$release, $fields fields"; } #-------------------- 1; �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Head/Complete.pm�������������������������������������������������0000644�0001750�0000144�00000023647�15166136116�022431� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::Head::Complete;{ our $VERSION = '4.05'; } use parent 'Mail::Message::Head'; use strict; use warnings; use Log::Report 'mail-message', import => [ qw/__x info trace warning/ ]; use Mail::Box::Parser (); use Mail::Message::Head::Partial (); use Scalar::Util qw/weaken blessed/; use List::Util qw/sum/; use Sys::Hostname qw/hostname/; #-------------------- sub clone(;@) { my $self = shift; my $copy = (ref $self)->new; $copy->addNoRealize($_->clone) for $self->grepNames(@_); $copy->modified(1); $copy; } sub build(@) { my $class = shift; my $self = $class->new; while(@_) { my $name = shift; defined $name or next; if($name->isa('Mail::Message::Field')) { $self->add($name); next; } my $content = shift; defined $content or next; if(ref $content && $content->isa('Mail::Message::Field')) { warning __x"field objects have an implied name ({name})", name => $name; $self->add($content); next; } $self->add($name, $content); } $self; } #-------------------- sub isDelayed() {0} sub nrLines() { sum 1, map $_->nrLines, shift->orderedFields } sub size() { sum 1, map $_->size, shift->orderedFields } sub wrap($) { my ($self, $length) = @_; $_->setWrapLength($length) for $self->orderedFields; } #-------------------- sub add(@) { my $self = shift; # Create object for this field. my $field = @_==1 && blessed $_[0] ? shift # A fully qualified field is added. : ($self->{MMH_field_type} // 'Mail::Message::Field::Fast')->new(@_); defined $field or return; # Put it in place. $field->setWrapLength; my $known = $self->{MMH_fields}; my $name = $field->name; # is already lower-cased $self->addOrderedFields($field); if(! defined $known->{$name}) { $known->{$name} = $field } elsif(ref $known->{$name} eq 'ARRAY') { push @{$known->{$name}}, $field } else { $known->{$name} = [ $known->{$name}, $field ] } $self->{MMH_modified}++; $field; } sub count($) { my $known = shift->{MMH_fields}; my $value = $known->{lc shift}; ! defined $value ? 0 : ref $value ? @$value : 1; } sub names() { $_[0]->knownNames } sub grepNames(@) { my $self = shift; my @take; push @take, (ref $_ eq 'ARRAY' ? @$_ : $_) for @_; @take or return $self->orderedFields; my $take; if(@take==1 && ref $take[0] eq 'Regexp') { $take = $take[0]; # one regexp prepared already } else { # I love this trick: local $" = ')|(?:'; $take = qr/^(?:(?:@take))/i; } grep $_->name =~ $take, $self->orderedFields; } my @skip_none = qw/content-transfer-encoding content-disposition content-description content-id/; my %skip_none = map +($_ => 1), @skip_none; sub set(@) { my $self = shift; @_!=1 || defined $_[0] or return; my $type = $self->{MMH_field_type} // 'Mail::Message::Field::Fast'; $self->{MMH_modified}++; # Create object for this field. my $field = @_==1 && blessed $_[0] ? shift->clone : $type->new(@_); my $name = $field->name; # is already lower-cased my $known = $self->{MMH_fields}; # Internally, non-existing content-info are in the body stored as 'none' # The header will not contain these lines. if($skip_none{$name} && $field->body eq 'none') { delete $known->{$name}; return $field; } $field->setWrapLength; $known->{$name} = $field; $self->addOrderedFields($field); $field; } sub reset($@) { my ($self, $name) = (shift, lc shift); my $known = $self->{MMH_fields}; if(@_==0) { $self->{MMH_modified}++ if delete $known->{$name}; return (); } $self->{MMH_modified}++; # Cloning required, otherwise double registrations will not be # removed from the ordered list: that's controled by 'weaken' my @fields = map $_->clone, @_; $known->{$name} = @_==1 ? $fields[0] : \@fields; $self->addOrderedFields(@fields); $self; } sub delete($) { $_[0]->reset($_[1]) } sub removeField($) { my ($self, $field) = @_; my $name = $field->name; my $known = $self->{MMH_fields}; if(!defined $known->{$name}) { ; } # complain elsif(ref $known->{$name} eq 'ARRAY') { for(my $i=0; $i < @{$known->{$name}}; $i++) { return splice @{$known->{$name}}, $i, 1 if $known->{$name}[$i] eq $field; } } elsif($known->{$name} eq $field) { return delete $known->{$name}; } warning __x"cannot remove field {name} from header: not found."; undef;; } sub removeFields(@) { my $self = shift; (bless $self, 'Mail::Message::Head::Partial')->removeFields(@_); } sub removeFieldsExcept(@) { my $self = shift; (bless $self, 'Mail::Message::Head::Partial')->removeFieldsExcept(@_); } sub removeContentInfo() { $_[0]->removeFields(qr/^Content-/, 'Lines') } sub removeResentGroups(@) { my $self = shift; (bless $self, 'Mail::Message::Head::Partial')->removeResentGroups(@_); } sub removeListGroup(@) { my $self = shift; (bless $self, 'Mail::Message::Head::Partial')->removeListGroup(@_); } sub removeSpamGroups(@) { my $self = shift; (bless $self, 'Mail::Message::Head::Partial')->removeSpamGroups(@_); } sub spamDetected() { my $self = shift; my @sgs = $self->spamGroups or return undef; grep $_->spamDetected, @sgs; } sub print(;$) { my $self = shift; my $fh = shift || select; $_->print($fh) for $self->orderedFields; $fh->print("\n"); $self; } sub printUndisclosed($) { my ($self, $fh) = @_; $_->print($fh) for grep $_->toDisclose, $self->orderedFields; $fh->print("\n"); $self; } sub printSelected($@) { my ($self, $fh) = (shift, shift); foreach my $field ($self->orderedFields) { my $Name = $field->Name; my $name = $field->name; my $found; foreach my $pattern (@_) { $found = ref $pattern ? ($Name =~ $pattern) : ($name eq lc $pattern); last if $found; } if(!$found) { ; } else { $fh->print("\n") } } $self; } sub toString() { $_[0]->string } sub string() { my $self = shift; my @lines = map $_->string, $self->orderedFields; push @lines, "\n"; wantarray ? @lines : join('', @lines); } sub resentGroups() { my $self = shift; require Mail::Message::Head::ResentGroup; Mail::Message::Head::ResentGroup->from($self); } sub addResentGroup(@) { my $self = shift; require Mail::Message::Head::ResentGroup; my $rg = @_==1 ? (shift) : Mail::Message::Head::ResentGroup->new(@_); my @fields = $rg->orderedFields; my $order = $self->{MMH_order}; # Look for the first line which relates to resent groups my $i; for($i=0; $i < @$order; $i++) { defined $order->[$i] or next; last if $rg->isResentGroupFieldName($order->[$i]->name); } my $known = $self->{MMH_fields}; while(@fields) { my $f = pop @fields; # Add to the order of fields splice @$order, $i, 0, $f; weaken( $order->[$i] ); my $name = $f->name; # Adds *before* in the list for get(). if(!defined $known->{$name}) { $known->{$name} = $f } elsif(ref $known->{$name} eq 'ARRAY'){ unshift @{$known->{$name}}, $f } else { $known->{$name} = [$f, $known->{$name}] } } $rg->messageHead($self); # Oh, the header has changed! $self->modified(1); $rg; } sub listGroup() { my $self = shift; eval "require 'Mail::Message::Head::ListGroup'"; Mail::Message::Head::ListGroup->from($self); } sub addListGroup($) { my ($self, $lg) = @_; $lg->attach($self); } sub spamGroups(@) { my $self = shift; require Mail::Message::Head::SpamGroup; my @types = @_ ? (types => \@_) : (); my @sgs = Mail::Message::Head::SpamGroup->from($self, @types); wantarray || @_ != 1 ? @sgs : $sgs[0]; } sub addSpamGroup($) { my ($self, $sg) = @_; $sg->attach($self); } #-------------------- sub timestamp() { $_[0]->guessTimestamp || time } sub recvstamp() { my $self = shift; return $self->{MMH_recvstamp} if exists $self->{MMH_recvstamp}; my $recvd = $self->get('received', 0) or return $self->{MMH_recvstamp} = undef; my $stamp = Mail::Message::Field->dateToTimestamp($recvd->comment); $self->{MMH_recvstamp} = defined $stamp && $stamp > 0 ? $stamp : undef; } sub guessTimestamp() { my $self = shift; return $self->{MMH_timestamp} if exists $self->{MMH_timestamp}; my $stamp; if(my $date = $self->get('date')) { $stamp = Mail::Message::Field->dateToTimestamp($date); } unless($stamp) { foreach (reverse $self->get('received')) { $stamp = Mail::Message::Field->dateToTimestamp($_->comment); last if $stamp; } } $self->{MMH_timestamp} = defined $stamp && $stamp > 0 ? $stamp : undef; } sub guessBodySize() { my $self = shift; my $cl = $self->get('Content-Length'); return $1 if defined $cl && $cl =~ m/(\d+)/; my $lines = $self->get('Lines'); # 40 chars per lines return $1 * 40 if defined $lines && $lines =~ m/(\d+)/; undef; } #-------------------- sub createFromLine() { my $self = shift; my $sender = $self->message->sender; my $stamp = $self->recvstamp || $self->timestamp || time; my $addr = defined $sender ? $sender->address : 'unknown'; "From $addr ".(gmtime $stamp)."\n" } my $msgid_creator; sub createMessageId() { $msgid_creator ||= $_[0]->messageIdPrefix; $msgid_creator->(@_); } sub messageIdPrefix(;$$) { my $thing = shift; return $msgid_creator if defined $msgid_creator && !@_; return $msgid_creator = shift if @_==1 && ref $_[0] eq 'CODE'; my $prefix = shift || "mailbox-$$"; my $hostname = shift; if(!defined $hostname) { eval "require Net::Domain"; $@ or $hostname = Net::Domain::hostfqdn(); } $hostname ||= hostname || 'localhost'; eval "require Time::HiRes"; if(Time::HiRes->can('gettimeofday')) { return $msgid_creator = sub { my ($sec, $micro) = Time::HiRes::gettimeofday(); "$prefix-$sec-$micro\@$hostname"; }; } my $unique_id = time; $msgid_creator = sub { $unique_id++; "$prefix-$unique_id\@$hostname" }; } 1; �����������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Head/SpamGroup.pm������������������������������������������������0000644�0001750�0000144�00000007566�15166136117�022601� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::Head::SpamGroup;{ our $VERSION = '4.05'; } use parent 'Mail::Message::Head::FieldGroup'; use strict; use warnings; use Log::Report 'mail-message', import => [ qw/panic/ ]; #-------------------- my %fighters; my $fighterfields; # one regexp for all fields sub knownFighters() { keys %fighters } sub fighter($;@) { my ($thing, $name) = (shift, shift); if(@_) { my %args = @_; defined $args{fields} or panic "requires fields"; defined $args{isspam} or panic "requires isspam"; $fighters{$name} = \%args; my @fields = map $_->{fields}, values %fighters; local $" = '|'; $fighterfields = qr/@fields/; } %{$fighters{$name}}; } BEGIN { __PACKAGE__->fighter( SpamAssassin => fields => qr/^X-Spam-/i, isspam => sub { my ($sg, $head) = @_; my $f = $head->get('X-Spam-Flag') || $head->get('X-Spam-Status'); $f ? $f =~ m/^yes\b/i : 0; }, version => sub { my ($sg, $head) = @_; my $assin = $head->get('X-Spam-Checker-Version') or return (); my ($software, $version) = $assin =~ m/^(.*)\s+(.*?)\s*$/; ($software, $version); }, ); __PACKAGE__->fighter( 'Habeas-SWE' => fields => qr/^X-Habeas-SWE/i, isspam => sub { my ($sg, $head) = @_; not $sg->habeasSweFieldsCorrect; }, ); __PACKAGE__->fighter( MailScanner => fields => qr/^X-MailScanner/i, isspam => sub { my ($sg, $head) = @_; my $subject = $head->get('subject'); $subject =~ m/^\{ (?:spam|virus)/xi; }, ); } sub from($@) { my ($class, $from, %args) = @_; my $head = $from->isa('Mail::Message::Head') ? $from : $from->head; my ($self, @detected); my @types = defined $args{types} ? @{$args{types}} : $class->knownFighters; foreach my $type (@types) { $self = $class->new(head => $head) unless defined $self; $self->collectFields($type) or next; my %fighter = $self->fighter($type); my ($software, $version) = defined $fighter{version} ? $fighter{version}->($self, $head) : (); $self->detected($type, $software, $version); $self->spamDetected( $fighter{isspam}->($self, $head) ); push @detected, $self; undef $self; # create a new one } @detected; } sub collectFields($) { my ($self, $set) = @_; my %fighter = $self->fighter($set) or panic "no spam set $set"; my @names = map $_->name, $self->head->grepNames($fighter{fields}); $self->addFields(@names) if @names; @names; } sub isSpamGroupFieldName($) { $_[1] =~ $fighterfields } my @habeas_lines = ( 'winter into spring', 'brightly anticipated', 'like Habeas SWE (tm)', 'Copyright 2002 Habeas (tm)', 'Sender Warranted Email (SWE) (tm). The sender of this', 'email in exchange for a license for this Habeas', 'warrant mark warrants that this is a Habeas Compliant', 'Message (HCM) and not spam. Please report use of this', 'mark in spam to <http://www.habeas.com/report/>.', ); sub habeasSweFieldsCorrect(;$) { my $self; if(@_ > 1) { my ($class, $thing) = @_; my $head = $thing->isa('Mail::Message::Head') ? $thing : $thing->head; $self = $head->spamGroups('Habeas-SWE') or return; } else { $self = shift; my $type = $self->type; defined $type && $type eq 'Habeas-SWE' or return; } my $head = $self->head; $self->fields == @habeas_lines or return; for(my $nr=1; $nr <= $#habeas_lines; $nr++) { my $f = $head->get("X-Habeas-SWE-$nr") or return; $f->unfoldedBody eq $habeas_lines[$nr-1] or return; } 1; } sub spamDetected(;$) { my $self = shift; @_? ($self->{MMFS_spam} = shift) : $self->{MMFS_spam}; } 1; ������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Head/FieldGroup.pod����������������������������������������������0000644�0001750�0000144�00000017750�15166136117�023066� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Head::FieldGroup - a sub set of fields in a header =head1 INHERITANCE Mail::Message::Head::FieldGroup is a Mail::Reporter Mail::Message::Head::FieldGroup is extended by Mail::Message::Head::ListGroup Mail::Message::Head::ResentGroup Mail::Message::Head::SpamGroup =head1 SYNOPSIS Never instantiated directly. =head1 DESCRIPTION Some fields have a combined meaning: a set of fields which represent one intermediate step during the transport of the message (a I<resent group>, implemented in L<Mail::Message::Head::ResentGroup|Mail::Message::Head::ResentGroup>), fields added by mailing list software (implemented in L<Mail::Message::Head::ListGroup|Mail::Message::Head::ListGroup>), or fields added by Spam detection related software (implemented by L<Mail::Message::Head::SpamGroup|Mail::Message::Head::SpamGroup>). Each set of fields can be extracted or added as group with objects which are based on the implementation in this class. Extends L<"DESCRIPTION" in Mail::Reporter|Mail::Reporter/"DESCRIPTION">. =head1 METHODS Extends L<"METHODS" in Mail::Reporter|Mail::Reporter/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Reporter|Mail::Reporter/"Constructors">. =over 4 =item $obj-E<gt>B<clone>() Make a copy of this object. The collected fieldnames are copied and the list type information. No deep copy is made for the header: this is only copied as reference. =item $obj-E<gt>B<from>($head|$message) Create a group of fields based on the specified C<$message> or message C<$head>. This may return one or more of the objects, which depends on the type of group. Mailing list fields are all stored in one object, where resent and spam groups can appear more than once. =item $any-E<gt>B<implementedTypes>() Returns a list of strings containing all possible return values for L<type()|Mail::Message::Head::FieldGroup/"Access to the header">. =item $class-E<gt>B<new>(@fields, %options) Construct an object which maintains one set of header C<@fields>. The C<@fields> may be specified as C<Mail::Message::Field> objects or as key-value pairs. The C<%options> and C<@fields> (as key-value pair) can be mixed: they are distinguished by their name, where the fields always start with a capital. The field objects must aways lead the C<%options>. Improves base, see L<Mail::Reporter/"Constructors"> -Option --Default head undef software undef type undef version undef =over 2 =item head => $head The C<$head> object is used to store the grouped fields in. If no header is specified, a L<Mail::Message::Head::Partial|Mail::Message::Head::Partial> is created for you. If you wish to scan the existing fields in a header, then use the L<from()|Mail::Message::Head::FieldGroup/"Constructors"> method. =item software => STRING Name of the software which produced the fields. =item type => STRING Group name for the fields. Often the same, or close to the same STRING, as the C<software> option contains. =item version => STRING Version number for the software which produced the fields. =back =back =head2 Attributes Extends L<"Attributes" in Mail::Reporter|Mail::Reporter/"Attributes">. =head2 The header =over 4 =item $obj-E<gt>B<add>( <$field, $value> | $object ) Add a field to the header, using the field group. When the field group is already attached to a real message header, it will appear in that one as well as being registered in this set. If no header is defined, the field only appears internally. » example: adding a field to a detached list group my $this = Mail::Message::Head::ListGroup->new(...); $this->add('List-Id' => 'mailbox'); $msg->addListGroup($this); $msg->send; » example: adding a field to an attached list group my $lg = Mail::Message::Head::ListGroup->from($msg); $lg->add('List-Id' => 'mailbox'); =item $obj-E<gt>B<addFields>( [$fieldnames] ) Add some C<$fieldnames> to the set. =item $obj-E<gt>B<attach>($head) Add a group of fields to a message C<$head>. The fields will be cloned(!) into the header, so that the field group object can be used again. » example: attaching a list group to a message my $lg = Mail::Message::Head::ListGroup->new(...); $lg->attach($msg->head); $msg->head->addListGroup($lg); # same $msg->head->addSpamGroup($sg); # also implemented with attach =item $obj-E<gt>B<delete>() Remove all the header lines which are combined in this fields group, from the header. =item $obj-E<gt>B<fieldNames>() Return the names of the fields which are used in this group. =item $obj-E<gt>B<fields>() Return the fields which are defined for this group. =item $obj-E<gt>B<head>() Returns the header object, which includes these fields. =back =head2 Access to the header =over 4 =item $obj-E<gt>B<software>() Returns the name of the software as is defined in the headers. The may be slightly different from the return value of L<type()|Mail::Message::Head::FieldGroup/"Access to the header">, but usually not too different. =item $obj-E<gt>B<type>() Returns an abstract name for the field group; which software is controlling it. C<undef> is returned in case the type is not known. Valid names are group type dependent: see the applicable manual pages. A list of all types can be retrieved with L<implementedTypes()|Mail::Message::Head::FieldGroup/"Constructors">. =item $obj-E<gt>B<version>() Returns the version number of the software used to produce the fields. Some kinds of software do leave such a trace, other cases will return C<undef> =back =head2 Internals =over 4 =item $obj-E<gt>B<collectFields>( [$name] ) Scan the header for fields which are usually contained in field group with the specified C<$name>. For mailinglist groups, you can not specify a C<$name>: only one set of headers will be found (all headers are considered to be produced by exactly one package of mailinglist software). This method is automatically called when a field group is constructed via L<from()|Mail::Message::Head::FieldGroup/"Constructors"> on an existing header or message. Returned are the names of the list header fields found, in scalar context the amount of fields. An empty list/zero indicates that there was no group to be found. Please warn the author of MailBox if you see that to few or too many fields are included. =item $obj-E<gt>B<detected>($type, $software, $version) Sets the values for the field group type, software, and version, prossibly to C<undef>. =back =head2 Error handling Extends L<"Error handling" in Mail::Reporter|Mail::Reporter/"Error handling">. =over 4 =item $obj-E<gt>B<AUTOLOAD>() Inherited, see L<Mail::Reporter/"Error handling"> =item $obj-E<gt>B<details>() Produce information about the detected/created field group, which may be helpful during debugging. A nicely formatted string is returned. =item $obj-E<gt>B<notImplemented>() Inherited, see L<Mail::Reporter/"Error handling"> =item $obj-E<gt>B<print>( [$fh] ) Print the group to the specified C<$fh>. This is probably only useful for debugging purposed. The output defaults to the selected file handle. =back =head2 Cleanup Extends L<"Cleanup" in Mail::Reporter|Mail::Reporter/"Cleanup">. =over 4 =item $obj-E<gt>B<DESTROY>() Inherited, see L<Mail::Reporter/"Cleanup"> =back =head1 DIAGNOSTICS =over 4 =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. ������������������������Mail-Message-4.05/lib/Mail/Message/Head/Partial.pm��������������������������������������������������0000644�0001750�0000144�00000005006�15166136117�022243� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::Head::Partial;{ our $VERSION = '4.05'; } use parent 'Mail::Message::Head::Complete'; use strict; use warnings; use Log::Report 'mail-message', import => [ qw// ]; use Scalar::Util qw/weaken/; #-------------------- sub removeFields(@) { my $self = shift; my $known = $self->{MMH_fields}; foreach my $match (@_) { if(ref $match) { $_ =~ $match && delete $known->{$_} for keys %$known } else { delete $known->{lc $match} } } $self->cleanupOrderedFields; } sub removeFieldsExcept(@) { my $self = shift; my $known = $self->{MMH_fields}; my %remove = map +($_ => 1), keys %$known; foreach my $match (@_) { if(ref $match) { $_ =~ $match && delete $remove{$_} for keys %remove } else { delete $remove{lc $match} } } delete @$known{ keys %remove }; $self->cleanupOrderedFields; } sub removeResentGroups() { my $self = shift; require Mail::Message::Head::ResentGroup; my $known = $self->{MMH_fields}; my $found = 0; foreach my $name (keys %$known) { Mail::Message::Head::ResentGroup->isResentGroupFieldName($name) or next; delete $known->{$name}; $found++; } $self->cleanupOrderedFields; $self->modified(1) if $found; $found; } sub removeListGroup() { my $self = shift; require Mail::Message::Head::ListGroup; my $known = $self->{MMH_fields}; my $found = 0; foreach my $name (keys %$known) { Mail::Message::Head::ListGroup->isListGroupFieldName($name) or next; delete $known->{$name}; $found++; } $self->cleanupOrderedFields if $found; $self->modified(1) if $found; $found; } sub removeSpamGroups() { my $self = shift; require Mail::Message::Head::SpamGroup; my $known = $self->{MMH_fields}; my $found = 0; foreach my $name (keys %$known) { Mail::Message::Head::SpamGroup->isSpamGroupFieldName($name) or next; delete $known->{$name}; $found++; } $self->cleanupOrderedFields if $found; $self->modified(1) if $found; $found; } sub cleanupOrderedFields() { my $self = shift; my @take = grep defined, @{$self->{MMH_order}}; weaken($_) for @take; $self->{MMH_order} = \@take; $self; } #-------------------- 1; ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Head/Partial.pod�������������������������������������������������0000644�0001750�0000144�00000034301�15166136117�022411� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Head::Partial - subset of header information of a message =head1 INHERITANCE Mail::Message::Head::Partial is a Mail::Message::Head::Complete is a Mail::Message::Head is a Mail::Reporter =head1 SYNOPSIS my $partial = $head->strip; $partial->isa('Mail::Message::Head') # true $partial->isDelayed # false $partial->isPartial # true $partial->removeFields( qr/^X-/ ); $partial->removeFieldsExcept( qw/To From/ ); $partial->removeResentGroups; $partial->removeListGroup; $partial->removeSpamGroups; =head1 DESCRIPTION Header information consumes a considerable amount of memory. Most of this information is only useful during a short period of time in your program, or sometimes it is not used at all. You then can decide to remove most of the header information. However, be warned that it will be lost permanently: the header (and therefore the message) gets mutulated! Extends L<"DESCRIPTION" in Mail::Message::Head::Complete|Mail::Message::Head::Complete/"DESCRIPTION">. =head1 OVERLOADED Extends L<"OVERLOADED" in Mail::Message::Head::Complete|Mail::Message::Head::Complete/"OVERLOADED">. =over 4 =item overload: B<""> stringifaction Inherited, see L<Mail::Message::Head/"OVERLOADED"> =item overload: B<bool> true/false Inherited, see L<Mail::Message::Head/"OVERLOADED"> =back =head1 METHODS Extends L<"METHODS" in Mail::Message::Head::Complete|Mail::Message::Head::Complete/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Message::Head::Complete|Mail::Message::Head::Complete/"Constructors">. =over 4 =item $class-E<gt>B<build>( [PAIR|$field], ... ) Inherited, see L<Mail::Message::Head::Complete/"Constructors"> =item $obj-E<gt>B<clone>( [@names|ARRAY|Regexps] ) Inherited, see L<Mail::Message::Head::Complete/"Constructors"> =item $class-E<gt>B<new>(%options) Inherited, see L<Mail::Message::Head/"Constructors"> =back =head2 Attributes Extends L<"Attributes" in Mail::Message::Head::Complete|Mail::Message::Head::Complete/"Attributes">. =head2 The header Extends L<"The header" in Mail::Message::Head::Complete|Mail::Message::Head::Complete/"The header">. =over 4 =item $obj-E<gt>B<isDelayed>() Inherited, see L<Mail::Message::Head/"The header"> =item $obj-E<gt>B<isEmpty>() Inherited, see L<Mail::Message::Head/"The header"> =item $obj-E<gt>B<isModified>() Inherited, see L<Mail::Message::Head/"The header"> =item $obj-E<gt>B<knownNames>() Inherited, see L<Mail::Message::Head/"The header"> =item $obj-E<gt>B<message>( [$message] ) Inherited, see L<Mail::Message::Head/"The header"> =item $obj-E<gt>B<modified>( [BOOLEAN] ) Inherited, see L<Mail::Message::Head/"The header"> =item $obj-E<gt>B<nrLines>() Inherited, see L<Mail::Message::Head::Complete/"The header"> =item $obj-E<gt>B<orderedFields>() Inherited, see L<Mail::Message::Head/"The header"> =item $obj-E<gt>B<size>() Inherited, see L<Mail::Message::Head::Complete/"The header"> =item $obj-E<gt>B<wrap>($integer) Inherited, see L<Mail::Message::Head::Complete/"The header"> =back =head2 Access to the header Extends L<"Access to the header" in Mail::Message::Head::Complete|Mail::Message::Head::Complete/"Access to the header">. =over 4 =item $obj-E<gt>B<add>( $field | $line | <$name, $body, [$attrs]> ) Inherited, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<addListGroup>($object) Inherited, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<addResentGroup>($resent_group|$data) Inherited, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<addSpamGroup>($object) Inherited, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<cleanupOrderedFields>() The header maintains a list of fields which are ordered in sequence of definition. It is required to maintain the header order to keep the related fields of resent groups together. The fields are also included in a hash, sorted on their name for fast access. The references to field objects in the hash are real, those in the ordered list are weak. So when field objects are removed from the hash, their references in the ordered list are automagically C<undef>'d. When many fields are removed, for instance with L<removeFields()|Mail::Message::Head::Partial/"Access to the header"> or L<removeFieldsExcept()|Mail::Message::Head::Partial/"Access to the header">, then it is useful to remove the list of undefs from the ordered list as well. In those cases, this method is called automatically, however you may have your own reasons to call this method. =item $obj-E<gt>B<count>($name) Inherited, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<delete>($name) Inherited, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<get>( $name, [$index] ) Inherited, see L<Mail::Message::Head/"Access to the header"> =item $obj-E<gt>B<grepNames>( [@names|ARRAY|Regexps] ) Inherited, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<listGroup>() Inherited, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<names>() Inherited, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<print>( [$fh] ) Inherited, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<printSelected>($fh, <STRING|Regexp>, ...) Inherited, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<printUndisclosed>( [$fh] ) Inherited, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<removeContentInfo>() Inherited, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<removeField>($field) Inherited, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<removeFields>( <STRING|Regexp>, ... ) Remove the fields from the header which are exactly named 'C<STRING>' (case insensitive) or match the regular expresssion. Do not forget to add the 'i' modifier to the regexp, because fields are case insensitive. See also L<removeField()|Mail::Message::Head::Complete/"Access to the header"> which is used to remove one field object from the header. The reverse specification can be made with C<removeFieldsExcept()>. Improves base, see L<Mail::Message::Head::Complete/"Access to the header"> » example: $head->removeFields('bcc', 'received'); $head->removeFields( qr/^content-/i ); =item $obj-E<gt>B<removeFieldsExcept>(STRING|Regexp, ...) Remove all fields from the header which are not equivalent to one of the specified STRINGs (case-insensitive) and which are not matching one of the REGular EXPressions. Do not forget to add the 'i' modifier to the Regexp, because fields are case insensitive. See also L<removeField()|Mail::Message::Head::Complete/"Access to the header"> which is used to remove one field object from the header. The reverse specification can be made with C<removeFields()>. Improves base, see L<Mail::Message::Head::Complete/"Access to the header"> » example: $head->removeFieldsExcept('subject', qr/^content-/i ); $head->removeFieldsExcept( qw/subject to from sender cc/ ); =item $obj-E<gt>B<removeListGroup>() Removes all header lines which are used to administer mailing lists. Which fields that are is explained in L<Mail::Message::Head::ListGroup|Mail::Message::Head::ListGroup>. Returned is the number of removed lines. Improves base, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<removeResentGroups>() Removes all header lines which are member of a I<resent group>, which are explained in L<Mail::Message::Head::ResentGroup|Mail::Message::Head::ResentGroup>. Returned is the number of removed lines. For removing single groups (for instance because you want to keep the last), use L<Mail::Message::Head::FieldGroup::delete()|Mail::Message::Head::FieldGroup/"The header">. Improves base, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<removeSpamGroups>() Removes all header lines which were produced by spam detection and spam-fighting software. Which fields that are is explained in L<Mail::Message::Head::SpamGroup|Mail::Message::Head::SpamGroup>. Returned is the number of removed lines. Improves base, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<resentGroups>() Inherited, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<reset>($name, @fields) Inherited, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<set>( $field | $line | <$name, $body, [$attrs]> ) Inherited, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<spamDetected>() Inherited, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<spamGroups>( [$names] ) Inherited, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<string>() Inherited, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<study>( $name, [$index] ) Inherited, see L<Mail::Message::Head/"Access to the header"> =back =head2 About the body Extends L<"About the body" in Mail::Message::Head::Complete|Mail::Message::Head::Complete/"About the body">. =over 4 =item $obj-E<gt>B<guessBodySize>() Inherited, see L<Mail::Message::Head/"About the body"> =item $obj-E<gt>B<guessTimeStamp>() Inherited, see L<Mail::Message::Head::Complete/"About the body"> =item $obj-E<gt>B<isMultipart>() Inherited, see L<Mail::Message::Head/"About the body"> =item $obj-E<gt>B<recvstamp>() Inherited, see L<Mail::Message::Head::Complete/"About the body"> =item $obj-E<gt>B<timestamp>() Inherited, see L<Mail::Message::Head::Complete/"About the body"> =back =head2 Internals Extends L<"Internals" in Mail::Message::Head::Complete|Mail::Message::Head::Complete/"Internals">. =over 4 =item $obj-E<gt>B<addNoRealize>($field) Inherited, see L<Mail::Message::Head/"Internals"> =item $obj-E<gt>B<addOrderedFields>($fields) Inherited, see L<Mail::Message::Head/"Internals"> =item $obj-E<gt>B<createFromLine>() Inherited, see L<Mail::Message::Head::Complete/"Internals"> =item $obj-E<gt>B<createMessageId>() Inherited, see L<Mail::Message::Head::Complete/"Internals"> =item $obj-E<gt>B<fileLocation>() Inherited, see L<Mail::Message::Head/"Internals"> =item $obj-E<gt>B<load>() Inherited, see L<Mail::Message::Head/"Internals"> =item $any-E<gt>B<messageIdPrefix>( [$prefix, [$hostname]|CODE] ) Inherited, see L<Mail::Message::Head::Complete/"Internals"> =item $obj-E<gt>B<moveLocation>($distance) Inherited, see L<Mail::Message::Head/"Internals"> =item $obj-E<gt>B<read>($parser) Inherited, see L<Mail::Message::Head/"Internals"> =item $obj-E<gt>B<setNoRealize>($field) Inherited, see L<Mail::Message::Head/"Internals"> =back =head2 Error handling Extends L<"Error handling" in Mail::Message::Head::Complete|Mail::Message::Head::Complete/"Error handling">. =over 4 =item $obj-E<gt>B<AUTOLOAD>() Inherited, see L<Mail::Reporter/"Error handling"> =item $obj-E<gt>B<notImplemented>() Inherited, see L<Mail::Reporter/"Error handling"> =back =head2 Cleanup Extends L<"Cleanup" in Mail::Message::Head::Complete|Mail::Message::Head::Complete/"Cleanup">. =over 4 =item $obj-E<gt>B<DESTROY>() Inherited, see L<Mail::Reporter/"Cleanup"> =back =head1 DETAILS Extends L<"DETAILS" in Mail::Message::Head::Complete|Mail::Message::Head::Complete/"DETAILS">. =head2 Ordered header fields Extends L<"Ordered header fields" in Mail::Message::Head::Complete|Mail::Message::Head::Complete/"Ordered header fields">. =head2 Head class implementation Extends L<"Head class implementation" in Mail::Message::Head::Complete|Mail::Message::Head::Complete/"Head class implementation">. =head2 Subsets of header fields Extends L<"Subsets of header fields" in Mail::Message::Head::Complete|Mail::Message::Head::Complete/"Subsets of header fields">. =head2 Reducing the header size A message header is very large in memory and quite large on disk, and therefore a good candidate for size reduction. One way to reduce the size is by simply eliminating superfluous header fields. Each field requires at least 100 bytes of run-time memory, so this may help! Before you start playing around with L<removeFields()|Mail::Message::Head::Partial/"Access to the header"> and L<removeFieldsExcept()|Mail::Message::Head::Partial/"Access to the header">, you may take a look at two large groups of fields which can be removes as sets: the resent headers and the mailinglist headers. Resent headers describe the intermediate steps in the transmission process for the messages. After successful delivery, they are rarely useful. When you are archiving a mailinglist, it is hardly ever useful to store a the list administration lines for each message as well. =head4 » see examples/reduce.pl in distribution foreach my $msg ($folder->messages) { $msg->head->removeResentGroups; $msg->head->removeResentList; } =head1 DIAGNOSTICS =over 4 =item Warning: cannot remove field $name from header: not found. You ask to remove a field which is not known in the header. Using L<delete()|Mail::Message::Head::Complete/"Access to the header">, L<reset()|Mail::Message::Head::Complete/"Access to the header">, or L<set()|Mail::Message::Head::Complete/"Access to the header"> to do the job will not result in warnings: those methods check the existence of the field first. Cast by C<removeField()> =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =item Warning: field objects have an implied name ($name) Cast by C<build()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Head/ListGroup.pod�����������������������������������������������0000644�0001750�0000144�00000022677�15166136117�022762� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Head::ListGroup - mailinglist related header fields =head1 INHERITANCE Mail::Message::Head::ListGroup is a Mail::Message::Head::FieldGroup is a Mail::Reporter =head1 SYNOPSIS my $lg = Mail::Message::Head::ListGroup->new(head => $head, ...); $head->addListGroup($lg); my $lg = $head->addListGroup(...); $lg->delete; =head1 DESCRIPTION A I<list group> is a set of header fields which are added by mailing-list managing software. This class knowns various details about that software. The knowledge and test messages which are used to initially implement this module is taken from Mail::ListDetector, written by Michael Stevens F<mailto:michael@etla.org>. The logic is redesigned to add flexibility and use the powerful MailBox features. Extends L<"DESCRIPTION" in Mail::Message::Head::FieldGroup|Mail::Message::Head::FieldGroup/"DESCRIPTION">. =head1 METHODS Extends L<"METHODS" in Mail::Message::Head::FieldGroup|Mail::Message::Head::FieldGroup/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Message::Head::FieldGroup|Mail::Message::Head::FieldGroup/"Constructors">. =over 4 =item $obj-E<gt>B<address>() Returns a L<Mail::Message::Field::Address|Mail::Message::Field::Address> object (or C<undef>) which defines the posting address of the mailing list. =item $obj-E<gt>B<clone>() Inherited, see L<Mail::Message::Head::FieldGroup/"Constructors"> =item $obj-E<gt>B<from>($head|$message) Create a C<Mail::Message::Head::ListGroup> based in the specified C<$message> or message C<$head>. Improves base, see L<Mail::Message::Head::FieldGroup/"Constructors"> =item $any-E<gt>B<implementedTypes>() Inherited, see L<Mail::Message::Head::FieldGroup/"Constructors"> =item $obj-E<gt>B<listname>() Returns the name of the mailing list, which is usually a part of the e-mail address which is used to post the messages to. =item $class-E<gt>B<new>($fields, %options) Construct an object which maintains one set of mailing list headers Improves base, see L<Mail::Message::Head::FieldGroup/"Constructors"> -Option --Defined in --Default address undef head Mail::Message::Head::FieldGroup undef listname <derived from address> rfc undef software Mail::Message::Head::FieldGroup undef type Mail::Message::Head::FieldGroup undef version Mail::Message::Head::FieldGroup undef =over 2 =item address => STRING|OBJECT Address of the mailing list, which may be specified as STRING or e-mail containing object (a L<Mail::Address|Mail::Address> or L<Mail::Identity|Mail::Identity>. In any case, the data is converted into a L<Mail::Identity|Mail::Identity>. =item head => $head =item listname => STRING A short textual representation of the mailing-list. =item rfc => 'rfc2919'|'rfc2369' Defines the mailing list software follows an rfc. =item software => STRING =item type => STRING =item version => STRING =back =item $obj-E<gt>B<rfc>() When the mailing list software follows the guidelines of one of the dedicated RFCs, then this will be returned otherwise C<undef>. The return values can be C<rfc2919>, C<rfc2369>, or C<undef>. =back =head2 Attributes Extends L<"Attributes" in Mail::Message::Head::FieldGroup|Mail::Message::Head::FieldGroup/"Attributes">. =head2 The header Extends L<"The header" in Mail::Message::Head::FieldGroup|Mail::Message::Head::FieldGroup/"The header">. =over 4 =item $obj-E<gt>B<add>( <$field, $value> | $object ) Inherited, see L<Mail::Message::Head::FieldGroup/"The header"> =item $obj-E<gt>B<addFields>( [$fieldnames] ) Inherited, see L<Mail::Message::Head::FieldGroup/"The header"> =item $obj-E<gt>B<attach>($head) Inherited, see L<Mail::Message::Head::FieldGroup/"The header"> =item $obj-E<gt>B<delete>() Inherited, see L<Mail::Message::Head::FieldGroup/"The header"> =item $obj-E<gt>B<fieldNames>() Inherited, see L<Mail::Message::Head::FieldGroup/"The header"> =item $obj-E<gt>B<fields>() Inherited, see L<Mail::Message::Head::FieldGroup/"The header"> =item $obj-E<gt>B<head>() Inherited, see L<Mail::Message::Head::FieldGroup/"The header"> =back =head2 Access to the header Extends L<"Access to the header" in Mail::Message::Head::FieldGroup|Mail::Message::Head::FieldGroup/"Access to the header">. =over 4 =item $any-E<gt>B<isListGroupFieldName>($name) Z<> =item $obj-E<gt>B<software>() Inherited, see L<Mail::Message::Head::FieldGroup/"Access to the header"> =item $obj-E<gt>B<type>() Inherited, see L<Mail::Message::Head::FieldGroup/"Access to the header"> =item $obj-E<gt>B<version>() Inherited, see L<Mail::Message::Head::FieldGroup/"Access to the header"> =back =head2 Internals Extends L<"Internals" in Mail::Message::Head::FieldGroup|Mail::Message::Head::FieldGroup/"Internals">. =over 4 =item $obj-E<gt>B<collectFields>() Scan the header for fields which are usually contained in mailing list software. This method is automatically called when a list group is constructed L<from()|Mail::Message::Head::ListGroup/"Constructors"> an existing header or message. Returned are the names of the list header fields found, in scalar context the amount. An empty list/zero indicates that this is not a mailing list message. Please warn the author of MailBox if you see that to few or too many fields are included. Improves base, see L<Mail::Message::Head::FieldGroup/"Internals"> =item $obj-E<gt>B<detected>($type, $software, $version) Inherited, see L<Mail::Message::Head::FieldGroup/"Internals"> =back =head2 Error handling Extends L<"Error handling" in Mail::Message::Head::FieldGroup|Mail::Message::Head::FieldGroup/"Error handling">. =over 4 =item $obj-E<gt>B<AUTOLOAD>() Inherited, see L<Mail::Reporter/"Error handling"> =item $obj-E<gt>B<details>() Produce information about the detected/create list group, which may be helpful during debugging, by default to the selected file handle. Improves base, see L<Mail::Message::Head::FieldGroup/"Error handling"> =item $obj-E<gt>B<notImplemented>() Inherited, see L<Mail::Reporter/"Error handling"> =item $obj-E<gt>B<print>( [$fh] ) Inherited, see L<Mail::Message::Head::FieldGroup/"Error handling"> =back =head2 Cleanup Extends L<"Cleanup" in Mail::Message::Head::FieldGroup|Mail::Message::Head::FieldGroup/"Cleanup">. =over 4 =item $obj-E<gt>B<DESTROY>() Inherited, see L<Mail::Reporter/"Cleanup"> =back =head1 DETAILS =head2 Mailing list fields =head3 Detected lists The L<Mail::Message::Head::ListGroup|Mail::Message::Head::ListGroup> class can detect many different mailing lists, some of which are very popular and some of which are rare. Numerous fields in a header are added when the message is passed through a mailing list server. Each list software has defined its own fields, sometimes woth conflicting definitions. There are also two RFCs about mailing list: C<rfc2919> and C<rfc2369>. The following lists are currently detected. Between parenthesis is the string returned by L<type()|Mail::Message::Head::FieldGroup/"Access to the header"> when that differs from the software name. =over 4 =item * CommuniGate Legacy commercial MacOS implementation by Stalker Software Inc. L<https://www.stalker.com/mac/default.html> =item * CommuniGate Pro (CommuniGatePro) Commercial rfc2919 compliant implementation by Stalker Software Inc. L<https://www.stalker.com> =item * Ecartis Commercial mailing list manager, formerly known as Listar. Produced by NodeRunner Computing. See L<https://www.ecartis.com>. =item * Ezmlm Open Source mailing list manager, available from L<https://www.ezmlm.org>. =item * FML Open Source mailing list manager, see L<https://www.fml.org>. =item * Listar Old name for Ecartis. =item * Listbox Mailing lists defined at L<https://listbox.com>. =item * Mailman GNU's mailing list manager, available from L<https://www.list.org>. =item * Majordomo Free (licenced) mailing list manager by Great Circle Associates, available from L<https://www.greatcircle.com/majordomo/> =item * Smartlist Related to procmail, as expressed by their shared main page at L<https://www.procmail.org/>. =item * Yahoo! Groups (YahooGroups) Mailing lists defined at L<https://groups.yahoo.com>. =item * Listserv Commercial mailing list manager, produced by L-Soft. See L<https://www.lsoft.com/>. =back =head1 DIAGNOSTICS =over 4 =item Error: cannot convert "$string" into an address object. The L<new(address)|Mail::Message::Head::ListGroup/"Constructors"> is coerced into a L<Mail::Message::Field::Address|Mail::Message::Field::Address>, which fails. Have a look at L<Mail::Message::Field::Address::coerce()|Mail::Message::Field::Address/"Constructors"> to see what valid arguments are. Cast by C<new()> =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. �����������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Head/SpamGroup.pod�����������������������������������������������0000644�0001750�0000144�00000017701�15166136120�022731� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Head::SpamGroup - spam fighting related header fields =head1 INHERITANCE Mail::Message::Head::SpamGroup is a Mail::Message::Head::FieldGroup is a Mail::Reporter =head1 SYNOPSIS my $sg = Mail::Message::Head::SpamGroup->new(head => $head, ...); $head->addSpamGroup($sg); my $sg = $head->addSpamGroup( <options> ); $sg->delete; my @sgs = $head->spamGroups; =head1 DESCRIPTION A I<spam group> is a set of header fields which are added by spam detection and spam fighting software. This class knows various details about that software. Extends L<"DESCRIPTION" in Mail::Message::Head::FieldGroup|Mail::Message::Head::FieldGroup/"DESCRIPTION">. =head1 METHODS Extends L<"METHODS" in Mail::Message::Head::FieldGroup|Mail::Message::Head::FieldGroup/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Message::Head::FieldGroup|Mail::Message::Head::FieldGroup/"Constructors">. =over 4 =item $obj-E<gt>B<clone>() Inherited, see L<Mail::Message::Head::FieldGroup/"Constructors"> =item $any-E<gt>B<fighter>($name, %options) Get the settings of a certain spam-fighter, optionally after setting them. The L<knownFighters()> method returns the defined names. The names are case-sensitive. The C<%options> are all passed as settings to the spamfilter, except the few which are listed here specifically. -Option --Default fields <required> isspam <required> version undef =over 2 =item fields => REGEXP The regular expression which indicates which of the header fields are added by the spam fighter software. =item isspam => CODE The CODE must return C<true> or C<false>, to indicate whether the spam fighter thinks that the message contains spam. The CODE ref is called with the spamgroup object (under construction) and the header which is inspected. =item version => CODE Can be called to collect the official name and the version of the software which is used to detect spam. The CODE ref is called with the spamgroup object (under construction) and the header which is inspected. =back » example: adding your own spam-fighter definitions Mail::Message::Head::SpamGroup->fighter( 'MY-OWN', fields => qw/^x-MY-SPAM-DETECTOR-/, isspam => sub { my ($sg, $head) = @_; $head->fields > 100 }, ); =item $obj-E<gt>B<from>($head|$message, %options) Returns a list of C<Mail::Message::Head::SpamGroup> objects, based on the specified C<$message> or message C<$head>. Improves base, see L<Mail::Message::Head::FieldGroup/"Constructors"> -Option--Default types undef =over 2 =item types => ARRAY-OF-NAMES Only the specified types will be tried. If the ARRAY is empty, an empty list is returned. Without this option, all sets are returned. =back =item $any-E<gt>B<habeasSweFieldsCorrect>( [$message|$head] ) Returns a C<true> value if the C<$message> or C<$head> contains C<Habeas-SWE> fields which are correct. Without argument, this is used as instance method on an existing Spam-Group. » example: checking Habeas-SWE fields if(Mail::Message::Head::SpamGroup->habeasSweFieldsCorrect($message)) { $message->label(spam => 0); } my $sg = $message->head->spamGroups('Habeas-SWE'); if($sg->habeasSweFieldsCorrect) { ... }; use List::Util 'first'; if(first {$_->habeasSweFieldsCorrect} $head->spamGroups) { ... } =item $any-E<gt>B<implementedTypes>() Inherited, see L<Mail::Message::Head::FieldGroup/"Constructors"> =item $any-E<gt>B<isSpamGroupFieldName>($name) Z<> =item $any-E<gt>B<knownFighters>() Returns an unsorted list of all names representing pre-defined spam-fighter software. You can ask details about them, and register more fighters with the L<fighter()|Mail::Message::Head::SpamGroup/"Constructors"> method. =item $class-E<gt>B<new>($fields, %options) Construct an object which maintains one set of fields which were added by spam fighting software. Improves base, see L<Mail::Message::Head::FieldGroup/"Constructors"> -Option --Defined in --Default head Mail::Message::Head::FieldGroup undef software Mail::Message::Head::FieldGroup undef type Mail::Message::Head::FieldGroup undef version Mail::Message::Head::FieldGroup undef =over 2 =item head => $head =item software => STRING =item type => STRING =item version => STRING =back =item $obj-E<gt>B<spamDetected>( [BOOLEAN] ) Returns (after setting) whether this group of spam headers thinks that this is spam. See L<Mail::Message::Head::Complete::spamDetected()|Mail::Message::Head::Complete/"Access to the header">. » example: die if $head->spamDetected; foreach my $sg ($head->spamGroups) { print $sg->type." found spam\n" if $sg->spamDetected; } =back =head2 Attributes Extends L<"Attributes" in Mail::Message::Head::FieldGroup|Mail::Message::Head::FieldGroup/"Attributes">. =head2 The header Extends L<"The header" in Mail::Message::Head::FieldGroup|Mail::Message::Head::FieldGroup/"The header">. =over 4 =item $obj-E<gt>B<add>( <$field, $value> | $object ) Inherited, see L<Mail::Message::Head::FieldGroup/"The header"> =item $obj-E<gt>B<addFields>( [$fieldnames] ) Inherited, see L<Mail::Message::Head::FieldGroup/"The header"> =item $obj-E<gt>B<attach>($head) Inherited, see L<Mail::Message::Head::FieldGroup/"The header"> =item $obj-E<gt>B<delete>() Inherited, see L<Mail::Message::Head::FieldGroup/"The header"> =item $obj-E<gt>B<fieldNames>() Inherited, see L<Mail::Message::Head::FieldGroup/"The header"> =item $obj-E<gt>B<fields>() Inherited, see L<Mail::Message::Head::FieldGroup/"The header"> =item $obj-E<gt>B<head>() Inherited, see L<Mail::Message::Head::FieldGroup/"The header"> =back =head2 Access to the header Extends L<"Access to the header" in Mail::Message::Head::FieldGroup|Mail::Message::Head::FieldGroup/"Access to the header">. =over 4 =item $obj-E<gt>B<software>() Inherited, see L<Mail::Message::Head::FieldGroup/"Access to the header"> =item $obj-E<gt>B<type>() Inherited, see L<Mail::Message::Head::FieldGroup/"Access to the header"> =item $obj-E<gt>B<version>() Inherited, see L<Mail::Message::Head::FieldGroup/"Access to the header"> =back =head2 Internals Extends L<"Internals" in Mail::Message::Head::FieldGroup|Mail::Message::Head::FieldGroup/"Internals">. =over 4 =item $obj-E<gt>B<collectFields>( [$name] ) Inherited, see L<Mail::Message::Head::FieldGroup/"Internals"> =item $obj-E<gt>B<detected>($type, $software, $version) Inherited, see L<Mail::Message::Head::FieldGroup/"Internals"> =back =head2 Error handling Extends L<"Error handling" in Mail::Message::Head::FieldGroup|Mail::Message::Head::FieldGroup/"Error handling">. =over 4 =item $obj-E<gt>B<AUTOLOAD>() Inherited, see L<Mail::Reporter/"Error handling"> =item $obj-E<gt>B<details>() Inherited, see L<Mail::Message::Head::FieldGroup/"Error handling"> =item $obj-E<gt>B<notImplemented>() Inherited, see L<Mail::Reporter/"Error handling"> =item $obj-E<gt>B<print>( [$fh] ) Inherited, see L<Mail::Message::Head::FieldGroup/"Error handling"> =back =head2 Cleanup Extends L<"Cleanup" in Mail::Message::Head::FieldGroup|Mail::Message::Head::FieldGroup/"Cleanup">. =over 4 =item $obj-E<gt>B<DESTROY>() Inherited, see L<Mail::Reporter/"Cleanup"> =back =head1 DIAGNOSTICS =over 4 =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. ���������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Head/FieldGroup.pm�����������������������������������������������0000644�0001750�0000144�00000006166�15166136117�022717� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::Head::FieldGroup;{ our $VERSION = '4.05'; } use parent 'Mail::Reporter'; use strict; use warnings; use Log::Report 'mail-message', import => [ qw/trace/ ]; use Scalar::Util qw/blessed/; #-------------------- sub new(@) { my $class = shift; my @fields; push @fields, shift while blessed $_[0]; $class->SUPER::new(@_, fields => \@fields); } sub init($$) { my ($self, $args) = @_; $self->SUPER::init($args); my $head = $self->{MMHF_head} = $args->{head} || Mail::Message::Head::Partial->new; $self->add($_) # add specified object fields for @{$args->{fields}}; $self->add($_, delete $args->{$_}) # add key-value paired fields for grep m/^[A-Z]/, keys %$args; $self->{MMHF_version} = $args->{version} if defined $args->{version}; $self->{MMHF_software} = $args->{software} if defined $args->{software}; $self->{MMHF_type} = $args->{type} if defined $args->{type}; $self->{MMHF_fns} = []; $self; } sub implementedTypes() { $_[0]->notImplemented } sub from($) { $_[0]->notImplemented } sub clone() { my $self = shift; my $clone = bless %$self, ref $self; $clone->{MMHF_fns} = [ $self->fieldNames ]; $clone; } #-------------------- sub head() { $_[0]->{MMHF_head} } sub attach($) { my ($self, $head) = @_; $head->add($_->clone) for $self->fields; $self; } sub delete() { my $self = shift; my $head = $self->head; $head->removeField($_) for $self->fields; $self; } sub add(@) { my $self = shift; my $field = $self->head->add(@_) or return (); push @{$self->{MMHF_fns}}, $field->name; $self; } sub fields() { my $self = shift; my $head = $self->head; map $head->get($_), $self->fieldNames; } sub fieldNames() { @{ $_[0]->{MMHF_fns}} } sub addFields(@) { my $self = shift; my $head = $self->head; push @{$self->{MMHF_fns}}, @_; @_; } #-------------------- sub version() { $_[0]->{MMHF_version} } sub software() { $_[0]->{MMHF_software} } sub type() { $_[0]->{MMHF_type} } #-------------------- sub detected($$$) { my $self = shift; @$self{ qw/MMHF_type MMHF_software MMHF_version/ } = @_; } sub collectFields(;$) { $_[0]->notImplemented } #-------------------- sub print(;$) { my $self = shift; my $out = shift || select; $_->print($out) for $self->fields; } sub details() { my $self = shift; my $type = $self->type || 'Unknown'; my $software = $self->software; undef $software if defined($software) && $type eq $software; my $version = $self->version; my $release = defined $software ? (defined $version ? " ($software $version)" : " ($software)") : (defined $version ? " ($version)" : ''); my $fields = scalar $self->fields; "$type $release, $fields fields"; } 1; ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/TransferEnc/�����������������������������������������������������0000755�0001750�0000144�00000000000�15166136132�021656� 5����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/TransferEnc/SevenBit.pm������������������������������������������0000644�0001750�0000144�00000002516�15166136116�023741� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::TransferEnc::SevenBit;{ our $VERSION = '4.05'; } use parent 'Mail::Message::TransferEnc'; use strict; use warnings; use Log::Report 'mail-message', import => [ qw// ]; #-------------------- sub name() { '7bit' } sub check($@) { my ($self, $body, %args) = @_; $body; } sub decode($@) { my ($self, $body, %args) = @_; $body->transferEncoding('none'); $body; } sub encode($@) { my ($self, $body, %args) = @_; my @lines; my $changes = 0; foreach ($body->lines) { $changes++ if s/([^\000-\127])/chr(ord($1) & 0x7f)/ge; $changes++ if s/[\000\013]//g; $changes++ if length > 997; push @lines, substr($_, 0, 996, '')."\n" while length > 997; push @lines, $_; } unless($changes) { $body->transferEncoding('7bit'); return $body; } my $bodytype = $args{result_type} || ref $body; $bodytype->new(based_on => $body, transfer_encoding => '7bit', data => \@lines); } 1; ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/TransferEnc/QuotedPrint.pod��������������������������������������0000644�0001750�0000144�00000011472�15166136120�024642� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::TransferEnc::QuotedPrint - handle quoted-printable message bodies =head1 INHERITANCE Mail::Message::TransferEnc::QuotedPrint is a Mail::Message::TransferEnc is a Mail::Reporter =head1 SYNOPSIS my Mail::Message $msg = ...; my $decoded = $msg->decoded; my $encoded = $msg->encode(transfer => 'quoted-printable'); =head1 DESCRIPTION Encode and decode message bodies for quoted-printable transfer encoding. The Quoted-Printable encoding is intended to represent data that largely consists of bytes that correspond to printable characters in the ASCII character set. Non-printable characters (as defined by English Americans) are represented by a triplet consisting of the character "=" followed by two hexadecimal digits. Extends L<"DESCRIPTION" in Mail::Message::TransferEnc|Mail::Message::TransferEnc/"DESCRIPTION">. =head1 METHODS Extends L<"METHODS" in Mail::Message::TransferEnc|Mail::Message::TransferEnc/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Message::TransferEnc|Mail::Message::TransferEnc/"Constructors">. =over 4 =item $class-E<gt>B<new>(%options) Inherited, see L<Mail::Reporter/"Constructors"> =back =head2 Attributes Extends L<"Attributes" in Mail::Message::TransferEnc|Mail::Message::TransferEnc/"Attributes">. =head2 The Encoder Extends L<"The Encoder" in Mail::Message::TransferEnc|Mail::Message::TransferEnc/"The Encoder">. =over 4 =item $class-E<gt>B<addTransferEncoder>($type, $class) Inherited, see L<Mail::Message::TransferEnc/"The Encoder"> =item $obj-E<gt>B<create>($type, %options) Inherited, see L<Mail::Message::TransferEnc/"The Encoder"> =item $obj-E<gt>B<name>() Inherited, see L<Mail::Message::TransferEnc/"The Encoder"> =back =head2 Encoding Extends L<"Encoding" in Mail::Message::TransferEnc|Mail::Message::TransferEnc/"Encoding">. =over 4 =item $obj-E<gt>B<check>($body, %options) Inherited, see L<Mail::Message::TransferEnc/"Encoding"> =item $obj-E<gt>B<decode>($body, %options) Decoding is tricky, and not without loss of information. Lines will stay separate lines, although they might have been joined before the encoding split them up. Characters which are not printable will be replaced by their octal value, and carriage returns (“C<=0D>”) at end of line are removed. Improves base, see L<Mail::Message::TransferEnc/"Encoding"> -Option --Defined in --Default result_type Mail::Message::TransferEnc <type of source body> =over 2 =item result_type => CLASS =back =item $obj-E<gt>B<encode>($body, %options) Encoding is to quoted-printable is a careful process: All characters outside the normal printing range, and including “C<< = >>” are encoded. They are translated into a “C<< = >>” followed by a two digit hex of the ascii value of the character. The same treatment is for white-spaces at the end of a line. The lines which are constructed which must be 76 characters max, not broken on encoded characters. Improves base, see L<Mail::Message::TransferEnc/"Encoding"> -Option --Defined in --Default result_type Mail::Message::TransferEnc <type of source body> =over 2 =item result_type => CLASS =back =back =head2 Error handling Extends L<"Error handling" in Mail::Message::TransferEnc|Mail::Message::TransferEnc/"Error handling">. =over 4 =item $obj-E<gt>B<AUTOLOAD>() Inherited, see L<Mail::Reporter/"Error handling"> =item $obj-E<gt>B<notImplemented>() Inherited, see L<Mail::Reporter/"Error handling"> =back =head2 Cleanup Extends L<"Cleanup" in Mail::Message::TransferEnc|Mail::Message::TransferEnc/"Cleanup">. =over 4 =item $obj-E<gt>B<DESTROY>() Inherited, see L<Mail::Reporter/"Cleanup"> =back =head1 DIAGNOSTICS =over 4 =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =item Error: decoder for transfer encoding $type does not work: $@ Compiling the required transfer encoding resulted in errors, which means that the decoder can not be used. Cast by C<create()> =item Error: no decoder for transfer encoding $type. A decoder for the specified type of transfer encoding is not implemented. Cast by C<create()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/TransferEnc/EightBit.pm������������������������������������������0000644�0001750�0000144�00000002502�15166136116�023714� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::TransferEnc::EightBit;{ our $VERSION = '4.05'; } use parent 'Mail::Message::TransferEnc'; use strict; use warnings; use Log::Report 'mail-message', import => [ qw// ]; #-------------------- sub name() { '8bit' } sub check($@) { my ($self, $body, %args) = @_; $body; } sub decode($@) { my ($self, $body, %args) = @_; $body->transferEncoding('none'); $body; } sub encode($@) { my ($self, $body, %args) = @_; my @lines; my $changes = 0; foreach ($body->lines) { $changes++ if s/[\000\013]//g; # there shouldn't be any NL inside a line. $changes++ if length > 997; push @lines, substr($_, 0, 996, '')."\n" while length > 997; push @lines, $_; } unless($changes) { $body->transferEncoding('8bit'); return $body; } my $bodytype = $args{result_type} || ref $body; $bodytype->new(based_on => $body, transfer_encoding => '8bit', data => \@lines); } 1; ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/TransferEnc/QuotedPrint.pm���������������������������������������0000644�0001750�0000144�00000002314�15166136117�024475� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::TransferEnc::QuotedPrint;{ our $VERSION = '4.05'; } use parent 'Mail::Message::TransferEnc'; use strict; use warnings; use utf8; use Log::Report 'mail-message', import => [ qw// ]; use MIME::QuotedPrint qw/encode_qp decode_qp/; #-------------------- sub name() { 'quoted-printable' } sub check($@) { my ($self, $body, %args) = @_; $body; } sub decode($@) { my ($self, $body, %args) = @_; my $bodytype = $args{result_type} || ref $body; $bodytype->new(based_on => $body, transfer_encoding => 'none', data => decode_qp($body->string)); } sub encode($@) { my ($self, $body, %args) = @_; my $bodytype = $args{result_type} || ref $body; $bodytype->new(based_on => $body, transfer_encoding => 'quoted-printable', data => encode_qp($body->string)); } 1; ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/TransferEnc/Binary.pod�������������������������������������������0000644�0001750�0000144�00000003462�15166136120�023610� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::TransferEnc::Binary - encode/decode binary message bodies =head1 INHERITANCE Mail::Message::TransferEnc::Binary is a Mail::Message::TransferEnc is a Mail::Reporter =head1 SYNOPSIS my Mail::Message $msg = ...; my $decoded = $msg->decoded; my $encoded = $msg->encode(transfer => 'binary'); =head1 DESCRIPTION Encode or decode message bodies for binary transfer encoding. This is totally no encoding. Extends L<"DESCRIPTION" in Mail::Message::TransferEnc|Mail::Message::TransferEnc/"DESCRIPTION">. =head1 METHODS Extends L<"METHODS" in Mail::Message::TransferEnc|Mail::Message::TransferEnc/"METHODS">. =head1 DIAGNOSTICS =over 4 =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =item Error: decoder for transfer encoding $type does not work: $@ Compiling the required transfer encoding resulted in errors, which means that the decoder can not be used. Cast by C<create()> =item Error: no decoder for transfer encoding $type. A decoder for the specified type of transfer encoding is not implemented. Cast by C<create()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/TransferEnc/Binary.pm��������������������������������������������0000644�0001750�0000144�00000002271�15166136116�023444� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::TransferEnc::Binary;{ our $VERSION = '4.05'; } use parent 'Mail::Message::TransferEnc'; use strict; use warnings; use Log::Report 'mail-message', import => [ qw// ]; #-------------------- sub name() { 'binary' } sub check($@) { my ($self, $body, %args) = @_; $body; } sub decode($@) { my ($self, $body, %args) = @_; $body->transferEncoding('none'); $body; } sub encode($@) { my ($self, $body, %args) = @_; my @lines; my $changes = 0; foreach ($body->lines) { $changes++ if s/[\000\013]//g; push @lines, $_; } unless($changes) { $body->transferEncoding('none'); return $body; } my $bodytype = $args{result_type} || ref($self->load); $bodytype->new(based_on => $body, transfer_encoding => 'none', data => \@lines); } 1; ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/TransferEnc/EightBit.pod�����������������������������������������0000644�0001750�0000144�00000004435�15166136120�024064� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::TransferEnc::EightBit - encode/decode 8bit message bodies =head1 INHERITANCE Mail::Message::TransferEnc::EightBit is a Mail::Message::TransferEnc is a Mail::Reporter =head1 SYNOPSIS my Mail::Message $msg = ...; my $decoded = $msg->decoded; my $encoded = $msg->encode(transfer => '8bit'); =head1 DESCRIPTION Encode or decode message bodies for 8bit transfer encoding. This is only very little encoding. According to the specs: RFC-2045 Section 2.8 defines legal `8bit' data: "8bit data" refers to data that is all represented as relatively short lines with 998 octets or less between CRLF line separation sequences [RFC-821]), but octets with decimal values greater than 127 may be used. As with "7bit data" CR and LF octets only occur as part of CRLF line separation sequences and no NULs are allowed. As you can safely conclude: decoding of these bodies is no work at all. Extends L<"DESCRIPTION" in Mail::Message::TransferEnc|Mail::Message::TransferEnc/"DESCRIPTION">. =head1 METHODS Extends L<"METHODS" in Mail::Message::TransferEnc|Mail::Message::TransferEnc/"METHODS">. =head1 DIAGNOSTICS =over 4 =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =item Error: decoder for transfer encoding $type does not work: $@ Compiling the required transfer encoding resulted in errors, which means that the decoder can not be used. Cast by C<create()> =item Error: no decoder for transfer encoding $type. A decoder for the specified type of transfer encoding is not implemented. Cast by C<create()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/TransferEnc/Base64.pm��������������������������������������������0000644�0001750�0000144�00000002616�15166136117�023250� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::TransferEnc::Base64;{ our $VERSION = '4.05'; } use parent 'Mail::Message::TransferEnc'; use strict; use warnings; use utf8; use Log::Report 'mail-message', import => [ qw/warning/ ]; use MIME::Base64 qw/decode_base64 encode_base64/; #-------------------- sub name() { 'base64' } sub check($@) { my ($self, $body, %args) = @_; $body; } sub decode($@) { my ($self, $body, %args) = @_; my $lines = decode_base64($body->string); unless($lines) { $body->transferEncoding('none'); return $body; } my $bodytype = $args{result_type} || ($body->isBinary ? 'Mail::Message::Body::File' : ref $body); $bodytype->new(based_on => $body, transfer_encoding => 'none', data => $lines); } sub encode($@) { my ($self, $body, %args) = @_; my $bodytype = $args{result_type} || ref $body; $bodytype->new( based_on => $body, checked => 1, transfer_encoding => 'base64', data => encode_base64($body->string), ); } 1; ������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/TransferEnc/Base64.pod�������������������������������������������0000644�0001750�0000144�00000010547�15166136120�023412� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::TransferEnc::Base64 - encode/decode base64 message bodies =head1 INHERITANCE Mail::Message::TransferEnc::Base64 is a Mail::Message::TransferEnc is a Mail::Reporter =head1 SYNOPSIS my Mail::Message $msg = ...; my $decoded = $msg->decoded; my $encoded = $msg->encode(transfer => 'base64'); =head1 DESCRIPTION Encode or decode message bodies with base64. The e-mail protocol and user agents can not handle binary data. Therefore, binary data -but even sometimes non-binary data- is encoded into ASCII, this is transportable. Base64 re-groups the bits of bytes, and maps them on characters. The data contains bytes of 8 bits (an I<octet>). These are repacked into groups of 6 bits, pointing in an array of characters containing “C<[A-Za-z0-9+/]>”. This way, three data bytes become 4 base64 bytes. The encoded data will be trailed by “C<< = >>” characters to align on four bytes. Extends L<"DESCRIPTION" in Mail::Message::TransferEnc|Mail::Message::TransferEnc/"DESCRIPTION">. =head1 METHODS Extends L<"METHODS" in Mail::Message::TransferEnc|Mail::Message::TransferEnc/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Message::TransferEnc|Mail::Message::TransferEnc/"Constructors">. =over 4 =item $class-E<gt>B<new>(%options) Inherited, see L<Mail::Reporter/"Constructors"> =back =head2 Attributes Extends L<"Attributes" in Mail::Message::TransferEnc|Mail::Message::TransferEnc/"Attributes">. =head2 The Encoder Extends L<"The Encoder" in Mail::Message::TransferEnc|Mail::Message::TransferEnc/"The Encoder">. =over 4 =item $class-E<gt>B<addTransferEncoder>($type, $class) Inherited, see L<Mail::Message::TransferEnc/"The Encoder"> =item $obj-E<gt>B<create>($type, %options) Inherited, see L<Mail::Message::TransferEnc/"The Encoder"> =item $obj-E<gt>B<name>() Inherited, see L<Mail::Message::TransferEnc/"The Encoder"> =back =head2 Encoding Extends L<"Encoding" in Mail::Message::TransferEnc|Mail::Message::TransferEnc/"Encoding">. =over 4 =item $obj-E<gt>B<check>($body, %options) Inherited, see L<Mail::Message::TransferEnc/"Encoding"> =item $obj-E<gt>B<decode>($body, %options) Inherited, see L<Mail::Message::TransferEnc/"Encoding"> -Option --Defined in --Default result_type Mail::Message::TransferEnc <type of source body> =over 2 =item result_type => CLASS =back =item $obj-E<gt>B<encode>($body, %options) Inherited, see L<Mail::Message::TransferEnc/"Encoding"> =back =head2 Error handling Extends L<"Error handling" in Mail::Message::TransferEnc|Mail::Message::TransferEnc/"Error handling">. =over 4 =item $obj-E<gt>B<AUTOLOAD>() Inherited, see L<Mail::Reporter/"Error handling"> =item $obj-E<gt>B<notImplemented>() Inherited, see L<Mail::Reporter/"Error handling"> =back =head2 Cleanup Extends L<"Cleanup" in Mail::Message::TransferEnc|Mail::Message::TransferEnc/"Cleanup">. =over 4 =item $obj-E<gt>B<DESTROY>() Inherited, see L<Mail::Reporter/"Cleanup"> =back =head1 DIAGNOSTICS =over 4 =item Warning: Base64 line length not padded on 4. While decoding base64 the data in a message body, a string was found which was not padded into a multiple of four bytes. This is illegal, and therefore this data is ignored. Cast by C<decode()> =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =item Error: decoder for transfer encoding $type does not work: $@ Compiling the required transfer encoding resulted in errors, which means that the decoder can not be used. Cast by C<create()> =item Error: no decoder for transfer encoding $type. A decoder for the specified type of transfer encoding is not implemented. Cast by C<create()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. ���������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/TransferEnc/SevenBit.pod�����������������������������������������0000644�0001750�0000144�00000004513�15166136120�024101� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::TransferEnc::SevenBit - encode/decode 7bit message bodies =head1 INHERITANCE Mail::Message::TransferEnc::SevenBit is a Mail::Message::TransferEnc is a Mail::Reporter =head1 SYNOPSIS my Mail::Message $msg = ...; my $decoded = $msg->decoded; my $encoded = $msg->encode(transfer => '7bit'); =head1 DESCRIPTION Encode or decode message bodies for 7bit transfer encoding. This is only very little encoding. According to the specs: RFC-2045 Section 2.7 defines legal `7bit' data: "7bit data" refers to data that is all represented as relatively short lines with 998 octets or less between CRLF line separation sequences [RFC-821]. No octets with decimal values greater than 127 are allowed and neither are NULs (octets with decimal value 0). CR (decimal value 13) and LF (decimal value 10) octets only occur as part of CRLF line separation sequences. As you can safely conclude: decoding of these bodies is no work at all. Extends L<"DESCRIPTION" in Mail::Message::TransferEnc|Mail::Message::TransferEnc/"DESCRIPTION">. =head1 METHODS Extends L<"METHODS" in Mail::Message::TransferEnc|Mail::Message::TransferEnc/"METHODS">. =head1 DIAGNOSTICS =over 4 =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =item Error: decoder for transfer encoding $type does not work: $@ Compiling the required transfer encoding resulted in errors, which means that the decoder can not be used. Cast by C<create()> =item Error: no decoder for transfer encoding $type. A decoder for the specified type of transfer encoding is not implemented. Cast by C<create()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Construct.pm�����������������������������������������������������0000644�0001750�0000144�00000003122�15166136116�021766� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message;{ our $VERSION = '4.05'; } use strict; use warnings; use Log::Report 'mail-message', import => [ qw// ]; #-------------------- our %locations = ( bounce => 'Bounce', build => 'Build', buildFromBody => 'Build', forward => 'Forward', forwardNo => 'Forward', forwardInline => 'Forward', forwardAttach => 'Forward', forwardEncapsulate => 'Forward', forwardSubject => 'Forward', forwardPrelude => 'Forward', forwardPostlude => 'Forward', read => 'Read', rebuild => 'Rebuild', reply => 'Reply', replySubject => 'Reply', replyPrelude => 'Reply', string => 'Text', lines => 'Text', file => 'Text', printStructure => 'Text', ); sub AUTOLOAD(@) { my $self = shift; our $AUTOLOAD; my $call = $AUTOLOAD =~ s/.*\:\://gr; if(my $mod = $locations{$call}) { eval "require Mail::Message::Construct::$mod"; die $@ if $@; return $self->$call(@_); } our @ISA; # produce error via Mail::Reporter $call = "${ISA[0]}::$call"; $self->$call(@_); } 1; ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Body.pod���������������������������������������������������������0000644�0001750�0000144�00000102713�15166136117�021054� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Body - the data of a body in a message =head1 INHERITANCE Mail::Message::Body has extra code in Mail::Message::Body::Construct Mail::Message::Body::Encode Mail::Message::Body is a Mail::Reporter Mail::Message::Body is a Mail::Reporter Mail::Message::Body is extended by Mail::Message::Body::File Mail::Message::Body::Lines Mail::Message::Body::Multipart Mail::Message::Body::Nested Mail::Message::Body::String Mail::Message::Body is realized by Mail::Message::Body::Delayed =head1 SYNOPSIS my Mail::Message $msg = ...; my $body = $msg->body; my @text = $body->lines; my $text = $body->string; my $file = $body->file; # IO::File $body->print(\*FILE); my $content_type = $body->type; my $transfer_encoding = $body->transferEncoding; my $encoded = $body->encode(mime_type => 'text/html', charset => 'us-ascii', transfer_encoding => 'none');\n"; my $decoded = $body->decoded; =head1 DESCRIPTION The encoding and decoding functionality of a L<Mail::Message::Body|Mail::Message::Body> is implemented in the L<Mail::Message::Body::Encode|Mail::Message::Body::Encode> package. That package is automatically loaded when encoding and decoding of messages needs to take place. Methods to simply build an process body objects are implemented in L<Mail::Message::Body::Construct|Mail::Message::Body::Construct>. The body of a message (a L<Mail::Message|Mail::Message> object) is stored in one of the many body types. The functionality of each body type is equivalent, but there are performance differences. Each body type has its own documentation with details about its implementation. Extends L<"DESCRIPTION" in Mail::Reporter|Mail::Reporter/"DESCRIPTION">. Extends L<"DESCRIPTION" in Mail::Reporter|Mail::Reporter/"DESCRIPTION">. =head1 OVERLOADED =over 4 =item overload: B<'""'> stringification Returns the body as string --which will trigger completion-- unless called to produce a string for C<Carp>. The latter to avoid deep recursions. » example: stringification of body print $msg->body; # implicit by print my $body = $msg->body; my $x = "$body"; # explicit by interpolation =item overload: B<'=='> numerical comparison compares if two references point to the same message. This only produces correct results is both arguments are message references B<within the same folder>. » example: use of numeric comparison on a body my $skip = $folder->message(3); foreach my $msg (@$folder) { next if $msg == $skip; $msg->send; } =item overload: B<'@{}'> addressed as array When a body object is used as being an array reference, the lines of the body are returned. This is the same as using L<lines()|Mail::Message::Body/"Access to the payload">. » example: using a body as array print $body->lines->[1]; # second line print $body->[1]; # same my @lines = $body->lines; my @lines = @$body; # same =item overload: B<bool> true/false Always returns a C<true> value, which is needed to have overloaded objects to be used as in C<if($body)>. Otherwise, C<if(defined $body)> would be needed to avoid a runtime error. =back =head1 METHODS Extends L<"METHODS" in Mail::Reporter|Mail::Reporter/"METHODS">. Extends L<"METHODS" in Mail::Reporter|Mail::Reporter/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Reporter|Mail::Reporter/"Constructors">. Extends L<"Constructors" in Mail::Reporter|Mail::Reporter/"Constructors">. =over 4 =item $obj-E<gt>B<clone>() Return a copy of this body, usually to be included in a cloned message. Use L<Mail::Message::clone()|Mail::Message/"Constructors"> for a whole message. =item $class-E<gt>B<new>(%options) BE WARNED that, what you specify here are encodings and such which are already in place. The options will not trigger conversions. When you need conversions, first create a body with options which tell what you've got, and then call L<encode()|Mail::Message::Body::Encode/"Constructing a body"> for what you need. Improves base, see L<Mail::Reporter/"Constructors"> -Option --Default based_on undef charset 'PERL' checked false content_id undef data undef description undef disposition undef eol 'NATIVE' file undef filename undef language undef message undef mime_type 'text/plain' modified false transfer_encoding 'none' =over 2 =item based_on => $body The information about encodings must be taken from the specified C<$body>, unless specified differently. =item charset => $charset|'PERL'|<undef> Defines the character-set which is used in the data. Only useful in combination with a C<mime_type> which refers to C<text> in any shape, which does not contain an explicit charset already. This field is case-insensitive. When a known CHARSET is provided and the mime-type says "text", then the data is expected to be raw octets in that particular encoding (see Encode). When 'PERL' is given, then then the data is in Perl's internal encoding; either cp1252 or utf8. More details in L</Character encoding PERL> =item checked => BOOLEAN Whether the added information has been check not to contain illegal octets with respect to the transfer encoding and mime type. If not checked, and then set as body for a message, it will be. =item content_id => STRING In C<multipart/related> MIME content, the C<content_id> is required to allow access to the related content via a C<< cid:<...> >> descriptor of an inline disposition. A C<Content-ID> is supposed to be globally unique. As such, it is common to append C<@computer.domain> to the end of some unique string. As other content in the C<multipart/related> container also needs to know what this C<Content-ID> is, this should be left to the imagination of the person making the content (for now). As a MIME header field, the C<Content-ID> string is expected to be inside angle brackets =item data => \@lines|$text The content of the body. The only way to set the content of a body is during the creation of the body. So if you want to modify the content of a message, you need to create a new body with the new content and add that to the body. The reason behind this, is that correct encodings and body information must be guaranteed. It avoids your hassle in calculating the number of lines in the body, and checking whether bad characters are enclosed in text. Specify C<@lines> each terminated by a newline, or one C<$text> which may contain multiple lines, separated and terminated by a newline. =item description => STRING|$field Informal information about the body content. The data relates to the C<Content-Description> field. Specify a STRING which will become the field content, or a real C<$field> object. =item disposition => STRING|$field How this message can be decomposed. The data relates to the C<Content-Disposition> field. Specify a STRING which will become the field content, or a real C<$field>. The content of this field is specified in RFC 1806. The body of the field can be C<inline>, to indicate that the body is intended to be displayed automatically upon display of the message. Use C<attachment> to indicate that they are separate from the main body of the mail message, and that their display should not be automatic, but contingent upon some further action of the user. The C<filename> attribute specifies a name to which is suggested to the reader of the message when it is extracted. RFC9078 adds type C<reaction>. This part content is restricted to a single line of emoji's. For this kind, you need to pass the C<$field> here, as well as mime-type C<text/plain>. =item eol => 'CR'|'LF'|'CRLF'|'NATIVE' Convert the message into having the specified string as line terminator for all lines in the body. C<NATIVE> is used to represent the C<\n> on the current platform and will be translated in the applicable one. BE WARNED that folders with a non-native encoding may appear on your platform, for instance in Windows folders handled from a UNIX system. The eol encoding has effect on the size of the body! =item file => $file|$handle|$io Read the data from the specified C<$file> name, file C<$handle>, or object of type C<IO::Handle>. =item filename => $file Overrule/set C<$file> name for content-disposition. =item language => STRING|\@lang|$field RFC3282 C<Content-Language> field, containing a comma separated list of language codes. =item message => $message The C<$message> where this body belongs to. =item mime_type => STRING|$field|$mime The type of data which is added. You may specify a content of a header line as STRING, or a C<$field> object. You may also specify a L<MIME::Type|MIME::Type> object. In any case, it will be kept internally as a real field (a L<Mail::Message::Field|Mail::Message::Field> object). This relates to the C<Content-Type> header field. A mime-type specification consists of two parts: a general class (C<text>, C<image>, C<application>, etc) and a specific sub-class. Examples for specific classes with C<text> are C<plain>, C<html>, and C<xml>. This field is case-insensitive but case preserving. The default mime-type is C<text/plain>, =item modified => BOOLEAN Whether the body is flagged modified, directly from its creation. =item transfer_encoding => STRING|$field The encoding that the data has. If the data is to be encoded, than you will have to call L<encode()|Mail::Message::Body::Encode/"Constructing a body"> after the body is created. That will return a new encoded body. This C<$field> is case-insensitive and relates to the C<Content-Transfer-Encoding> field in the header. =back » example: my $body = Mail::Message::Body::String->new(file => \*IN, mime_type => 'text/html; charset="ISO-8859-1"'); my $body = Mail::Message::Body::Lines->new(data => ["first\n", $second], charset => 'ISO-10646', transfer_encoding => 'none'); my $body = Mail::Message::Body::Lines->new(data => \@lines, transfer_encoding => 'base64'); my $body = Mail::Message::Body::Lines->new(file => 'picture.gif', mime_type => 'image/gif', content_id => '<12345@example.com>', disposition => 'inline'); =back =head2 Attributes Extends L<"Attributes" in Mail::Reporter|Mail::Reporter/"Attributes">. Extends L<"Attributes" in Mail::Reporter|Mail::Reporter/"Attributes">. =over 4 =item $obj-E<gt>B<charsetDetectAlgorithm>( [CODE|undef|METHOD] ) Inherited, see L<Mail::Message::Body::Encode/"Attributes"> =back =head2 Constructing a body =over 4 =item $obj-E<gt>B<attach>(@messages, %options) Inherited, see L<Mail::Message::Body::Construct/"Constructing a body"> =item $obj-E<gt>B<charsetDetect>(%options) Inherited, see L<Mail::Message::Body::Encode/"Constructing a body"> =item $obj-E<gt>B<check>() Inherited, see L<Mail::Message::Body::Encode/"Constructing a body"> =item $obj-E<gt>B<concatenate>(@components) Inherited, see L<Mail::Message::Body::Construct/"Constructing a body"> =item $obj-E<gt>B<decoded>(%options) Returns a body, an object which is (a sub-)class of a L<Mail::Message::Body|Mail::Message::Body>, which contains a simplified representation of textual data. The returned object may be the object where this is called on, but may also be a new body of any type. my $dec = $body->decoded; is equivalent with my $dec = $body->encode( mime_type => 'text/plain', transfer_encoding => 'none', charset => 'PERL', ); The C<$dec> which is returned is a body. Ask with the L<mimeType()|Mail::Message::Body/"About the payload"> method what is produced. This C<$dec> body is B<not related to a header>. -Option --Default result_type <same as current> =over 2 =item result_type => CLASS =back =item $obj-E<gt>B<encode>(%options) Inherited, see L<Mail::Message::Body::Encode/"Constructing a body"> =item $obj-E<gt>B<encoded>(%options) Inherited, see L<Mail::Message::Body::Encode/"Constructing a body"> =item $obj-E<gt>B<eol>( ['CR'|'LF'|'CRLF'|'NATIVE'] ) Inherited, see L<Mail::Message::Body::Encode/"Constructing a body"> =item $obj-E<gt>B<foreachLine>(CODE) Inherited, see L<Mail::Message::Body::Construct/"Constructing a body"> =item $obj-E<gt>B<stripSignature>(%options) Inherited, see L<Mail::Message::Body::Construct/"Constructing a body"> =item $obj-E<gt>B<unify>($body) Inherited, see L<Mail::Message::Body::Encode/"Constructing a body"> =back =head2 The body =over 4 =item $obj-E<gt>B<isDelayed>() Returns a C<true> or C<false> value, depending on whether the body of this message has been read from file. This can only C<false> for a L<Mail::Message::Body::Delayed|Mail::Message::Body::Delayed>. =item $obj-E<gt>B<isMultipart>() Returns whether this message-body contains parts which are messages by themselves. =item $obj-E<gt>B<isNested>() Only C<true> for a message body which contains exactly one sub-message: the C<Mail::Message::Body::Nested> body type. =item $obj-E<gt>B<message>( [$message] ) Returns the message (or message part) where this body belongs to, optionally setting it to a new C<$message> first. If C<undef> is passed, the body will be disconnected from the message. =item $obj-E<gt>B<partNumberOf>($part) Returns a string for multiparts and nested, otherwise an error. It is used in L<Mail::Message::partNumber()|Mail::Message/"The message">. =back =head2 About the payload =over 4 =item $obj-E<gt>B<charset>() Returns the character set which is used in the text body as string. This is part of the result of what the C<type> method returns. =item $obj-E<gt>B<checked>( [BOOLEAN] ) Returns whether the body encoding has been checked or not (optionally after setting the flag to a new value). =item $obj-E<gt>B<contentId>( [STRING|$field] ) Returns (optionally after setting) the id (unique reference) of a message part. The related header field is C<Content-ID>. A L<Mail::Message::Field|Mail::Message::Field> object is returned (which stringifies into the field content). The field content will be C<none> if no disposition was specified. The argument can be a C<STRING> (which is converted into a field), or a fully prepared header C<$field>. =item $obj-E<gt>B<description>( [STRING|$field] ) Returns (optionally after setting) the informal description of the body content. The related header field is C<Content-Description>. A L<Mail::Message::Field|Mail::Message::Field> object is returned (which stringifies into the field content). The field content will be C<none> if no disposition was specified. The argument can be a C<STRING> (which is converted into a field), or a fully prepared header field. =item $obj-E<gt>B<disposition>( [STRING|$field] ) Returns (optionally after setting) how the message can be disposed (unpacked). The related header field is C<Content-Disposition>. A L<Mail::Message::Field|Mail::Message::Field> object is returned (which stringifies into the field content). The field content will be C<none> if no disposition was specified. The argument can be a C<STRING> (which is converted into a field), or a fully prepared header field. RFC9078 adds type C<reaction>. This part content is restricted to a single line of emoji's. =item $obj-E<gt>B<dispositionFilename>( [$directory] ) Inherited, see L<Mail::Message::Body::Encode/"About the payload"> =item $obj-E<gt>B<isBinary>() Inherited, see L<Mail::Message::Body::Encode/"About the payload"> =item $obj-E<gt>B<isText>() Inherited, see L<Mail::Message::Body::Encode/"About the payload"> =item $obj-E<gt>B<language>( [@langs|\@langs|$langs|$field] ) Returns (optionally after setting) the C<Content-Language> header, as specified in RFC3282. Returns the field with a comma separated list of languages as body. =item $obj-E<gt>B<mimeType>() Returns a L<MIME::Type|MIME::Type> object which is related to this body's type. This differs from the C<type> method, which results in a L<Mail::Message::Field|Mail::Message::Field>. » example: if($body->mimeType eq 'text/html') {...} print $body->mimeType->simplified; =item $obj-E<gt>B<nrLines>() Returns the number of lines in the message body. For multi-part messages, this includes the header lines and boundaries of all the parts. =item $obj-E<gt>B<size>() The total number of bytes in the message body. The size of the body is computed in the shape it is in. For example, if this is a base64 encoded message, the size of the encoded data is returned; you may want to call L<Mail::Message::decoded()|Mail::Message/"The body"> first. =item $obj-E<gt>B<transferEncoding>( [STRING|$field] ) Returns the transfer-encoding of the data within this body as L<Mail::Message::Field|Mail::Message::Field> (which stringifies to its content). If it needs to be changed, call the L<encode()|Mail::Message::Body::Encode/"Constructing a body"> or L<encoded()|Mail::Message::Body::Encode/"Constructing a body"> method. When no encoding is present, the field contains the text C<none>. The optional C<STRING> or C<$field> enforces a new encoding to be set, without the actual required translations. » example: my $transfer = $msg->decoded->transferEncoding; $transfer->print; # --> Content-Encoding: base64 print $transfer; # --> base64 if($msg->body->transferEncoding eq 'none') {...} =item $obj-E<gt>B<type>( [STRING|$field] ) Returns the type of information the body contains as L<Mail::Message::Field|Mail::Message::Field> object. The type is taken from the header field C<Content-Type>. If the header did not contain that field, then you will get a default field containing C<text/plain>. You usually can better use L<mimeType()|Mail::Message::Body/"About the payload">, because that will return a clever object with type information. » example: my $msg = $folder->message(6); $msg->get('Content-Type')->print; # --> Content-Type: text/plain; charset="us-ascii" my $content = $msg->decoded; my $type = $content->type; print "This is a $type message\n"; # --> This is a text/plain; charset="us-ascii" message print "This is a ", $type->body, "message\n"; # --> This is a text/plain message print "Comment: ", $type->comment, "\n"; # --> Comment: charset="us-ascii" =back =head2 Access to the payload =over 4 =item $obj-E<gt>B<endsOnNewline>() Returns whether the last line of the body is terminated by a new-line (in transport it will become a CRLF). An empty body will return C<true> as well: the newline comes from the line before it. =item $obj-E<gt>B<file>() Return the content of the body as a file handle. The returned stream may be a real file, or a simulated file in any form that Perl supports. While you may not be able to write to the file handle, you can read from it. WARNING: Even if the file handle supports writing, do not write to the file handle. If you do, some of the internal values of the L<Mail::Message::Body|Mail::Message::Body> may not be updated. =item $obj-E<gt>B<lines>() Return the content of the body as a list of lines (in LIST context) or a reference to an array of lines (in SCALAR context). In scalar context the array of lines is cached to avoid needless copying and therefore provide much faster access for large messages. To just get the number of lines in the body, use the L<nrLines()|Mail::Message::Body/"About the payload"> method, which is usually much more efficient. BE WARNED: For some types of bodies the reference will refer to the original data. You must not change the referenced data! If you do, some of the essential internal variables of the L<Mail::Message::Body|Mail::Message::Body> may not be updated. » example: my @lines = $body->lines; # copies lines my $line3 = ($body->lines)[3] # only one copy print $lines[0]; my $linesref = $body->lines; # reference to originals my $line3 = $body->lines->[3] # only one copy (faster) print $linesref->[0]; print $body->[0]; # by overloading =item $obj-E<gt>B<print>( [$fh] ) Print the body to the specified C<$fh> (defaults to the selected handle). an IO::File object or... any object with a C<print()> method will do. Nothing useful is returned. =item $obj-E<gt>B<printEscapedFrom>($fh) Print the body to the specified C<$fh> but all lines which start with 'From ' (optionally already preceded by E<gt>'s) will habe an E<gt> added in front. Nothing useful is returned. =item $obj-E<gt>B<string>() Return the content of the body as a scalar (a single string). This is a copy of the internally kept information. » example: my $text = $body->string; print "Body: $body\n"; # by overloading =item $obj-E<gt>B<stripTrailingNewline>() Remove the newline from the last line, or the last line if it does not contain anything else than a newline. =item $obj-E<gt>B<write>(%options) Write the content of the body to a file. Be warned that you may want to decode the body before writing it! -Option --Default filename <required> =over 2 =item filename => FILENAME =back » example: write the data to a file use File::Temp; my $fn = tempfile; $message->decoded->write(filename => $fn); » example: using the content-disposition information to write use File::Temp; my $dir = tempdir; mkdir $dir or die; my $fn = $message->body->dispositionFilename($dir); $message->decoded->write(filename => $fn); =back =head2 Internals =over 4 =item $any-E<gt>B<addTransferEncHandler>( $name, <$class|$object> ) Inherited, see L<Mail::Message::Body::Encode/"Internals"> =item $obj-E<gt>B<contentInfoFrom>($head) Transfer the body related info from the header into this body. =item $obj-E<gt>B<contentInfoTo>($head) Copy the content information (the C<Content-*> fields) into the specified C<$head>. The body was created from raw data without the required information, which must be added. See also L<contentInfoFrom()|Mail::Message::Body/"Internals">. =item $obj-E<gt>B<fileLocation>( [$begin, $end] ) The location of the body in the file. Returned a list containing begin and end. The begin is the offsets of the first byte if the folder used for this body. The end is the offset of the first byte of the next message. =item $obj-E<gt>B<getTransferEncHandler>($type) Inherited, see L<Mail::Message::Body::Encode/"Internals"> =item $obj-E<gt>B<isModified>() Returns whether the body has changed. =item $obj-E<gt>B<load>() Be sure that the body is loaded. This returns the loaded body. =item $obj-E<gt>B<modified>( [BOOLEAN] ) Change the body modification flag. This will force a re-write of the body to a folder file when it is closed. It is quite dangerous to change the body: the same body may be shared between messages within your program. Especially be warned that you have to change the message-id when you change the body of the message: no two messages should have the same id. Without value, the current setting is returned, although you can better use L<isModified()|Mail::Message::Body/"Internals">. =item $obj-E<gt>B<moveLocation>( [$distance] ) Move the registration of the message to a new location over C<$distance>. This is called when the message is written to a new version of the same folder-file. =item $obj-E<gt>B<read>( $parser, $head, $bodytype, [$chars, [$lines]] ) Read the body with the C<$parser> from file. The implementation of this method will differ between types of bodies. The C<$bodytype> argument is a class name or a code reference of a routine which can produce a class name, and is used in multipart bodies to determine the type of the body for each part. The C<$chars> argument is the estimated number of bytes in the body, or C<undef> when this is not known. This data can sometimes be derived from the header (the C<Content-Length> line) or file-size. The second argument is the estimated number of C<$lines> of the body. It is less useful than the C<$chars> but may be of help determining whether the message separator is trustworthy. This value may be found in the C<Lines> field of the header. =back =head2 Error handling Extends L<"Error handling" in Mail::Reporter|Mail::Reporter/"Error handling">. Extends L<"Error handling" in Mail::Reporter|Mail::Reporter/"Error handling">. =over 4 =item $obj-E<gt>B<AUTOLOAD>() When an unknown method is called on a message body object, this may not be problematic. For performance reasons, some methods are implemented in separate files, and only demand-loaded. If this delayed compilation of additional modules does not help, an error will be produced. Improves base, see L<Mail::Reporter/"Error handling"> =item $obj-E<gt>B<notImplemented>() Inherited, see L<Mail::Reporter/"Error handling"> =item $obj-E<gt>B<notImplemented>() Inherited, see L<Mail::Reporter/"Error handling"> =back =head2 Cleanup Extends L<"Cleanup" in Mail::Reporter|Mail::Reporter/"Cleanup">. Extends L<"Cleanup" in Mail::Reporter|Mail::Reporter/"Cleanup">. =over 4 =item $obj-E<gt>B<DESTROY>() Inherited, see L<Mail::Reporter/"Cleanup"> =item $obj-E<gt>B<DESTROY>() Inherited, see L<Mail::Reporter/"Cleanup"> =back =head1 DETAILS =head2 Access to the body A body can be contained in a message, but may also live without a message. In both cases it stores data, and the same questions can be asked: what type of data it is, how many bytes and lines, what encoding is used. Any body can be encoded and decoded, returning a new body object. However, bodies which are part of a message will always be in a shape that they can be written to a file or send to somewhere: they will be encoded if needed. =head4 » Example my $body = Mail::Message::Body::String->new(mime_type => 'image/gif'); $body->print(\*OUT); # this is binary image data... my $encoded = $message->body($body); $encoded->print(\*OUT); # ascii data, encoded image Now encoded refers to the body of the C<$message> which is the content of C<$body> in a shape that it can be transmitted. Usually C<base64> encoding is used. =head2 Body class implementation The body of a message can be stored in many ways. Roughly, the implementations can be split in two groups: the data collectors and the complex bodies. The primer implement various ways to access data, and are full compatible: they only differ in performance and memory footprint under different circumstances. The latter are created to handle complex multiparts and lazy extraction. =head3 Data collector bodies =over 4 =item * L<Mail::Message::Body::String|Mail::Message::Body::String> The whole message body is stored in one scalar. Small messages can be contained this way without performance penalties. =item * L<Mail::Message::Body::Lines|Mail::Message::Body::Lines> Each line of the message body is stored as single scalar. This is a useful representation for a detailed look in the message body, which is usually line-organized. =item * L<Mail::Message::Body::File|Mail::Message::Body::File> The message body is stored in an external temporary file. This type of storage is especially useful when the body is large, the total folder is large, or memory is limited. =item * C<Mail::Message::Body::InFolder> NOT IMPLEMENTED YET. The message is kept in the folder, and is only taken out when the content is changed. =item * C<Mail::Message::Body::External> NOT IMPLEMENTED YET. The message is kept in a separate file, usually because the message body is large. The difference with the C<::External> object is that this external storage stays this way between closing and opening of a folder. The C<::External> object only uses a file when the folder is open. =back =head3 Complex bodies =over 4 =item * L<Mail::Message::Body::Delayed|Mail::Message::Body::Delayed> The message-body is not yet read, but the exact location of the body is known so the message can be read when needed. This is part of the lazy extraction mechanism. Once extracted, the object can become any simple or complex body. =item * L<Mail::Message::Body::Multipart|Mail::Message::Body::Multipart> The message body contains a set of sub-messages (which can contain multipart bodies themselves). Each sub-message is an instance of L<Mail::Message::Part|Mail::Message::Part>, which is an extension of L<Mail::Message|Mail::Message>. =item * L<Mail::Message::Body::Nested|Mail::Message::Body::Nested> Nested messages, like C<message/rfc822>: they contain a message in the body. For most code, they simply behave like multiparts. =back =head2 Character encoding PERL A body object can be part of a message, or stand-alone. In case it is a part of a message, the "transport encoding" and the content must be in a shape that the data can be transported via SMTP. However, when you want to process the body data in simple Perl (or when you construct the body data from normal Perl strings), you need to be aware of Perl's internal representation of strings. That can either be cp1252 (extended latin1) or utf8 (not real UTF-8, but something alike, see the perlunicode manual page) So, before you start using the data from an incoming message, do my $body = $msg->decoded; my @lines = $body->lines; Now, the body has character-set 'PERL' (when it is text) When you create a new body which contains text content (the default), it will be created with character-set 'PERL' unless you specify a character-set explicitly. my $body = Mail::Box::Body::Lines->new(data => \@lines); # now mime=text/plain, charset=PERL my $msg = Mail::Message->buildFromBody($body); $msg->body($body); $msg->attach($body); # etc # these all will convert the charset=PERL into real utf-8, # cp1252 or us-ascii, which depends on the characters found. =head3 Autodetection of character-set This "Body" object represents data as part of an existing message, or to become part of a message. The body can be in two states: =over 4 =item 1. ready to be processed textually, using Perl's string operations =item 2. raw bytes read or to be written =back In the first case, the body content has no transfer encoding on it (C<none>), and the character-set is C<PERL>. In the second version, the body may have transfer encoding and has an (IANA listed) charset on it (defaults to C<us-ascii>) Using L<encode()|Mail::Message::Body::Encode/"Constructing a body"> (maybe via L<decoded()|Mail::Message::Body/"Constructing a body">), you can convert bodies from one state into a different one. In one go, you can change the transfer-encoding, the character-set, or whether it is in PERL string format or raw (in bytes). A serious problem is created when a conversion is needed, while the input or output character-set is not explicitly known. The email RFCs state that the default is C<us-ascii>. However, in the real world it can be anything. Therefore, in such situations autodetection kicks in. =over 4 =item 1. When a Body is read (using L<Mail::Message::read()|Mail::Message::Construct::Read/"Constructing a message"> and friends), the character-set may stay undefined until transfer-decoding has been applicied. At that moment, (configurable auto-detection) is applied; =item 2. When a Body is created witin the program, without specific character-set, it will use 'PERL'; =item 3. When a Body is written, the requested character-set is not specified, and the current character-set is C<PERL>, then auto-dectection is used. This may result in C<us-ascii>, C<cp1252> and C<utf-8>; =item 4. In all other cases, the character-set is known so "easy". =back =head1 DIAGNOSTICS =over 4 =item Warning: Content-Transfer-Encoding '$te' requires explicit charset, defaulted to utf-8. Cast by C<encode()> =item Error: cannot concatenate element $which Cast by C<concatenate()> =item Fault: cannot open $file to write body: $! Cast by C<write()> =item Warning: charset '$name' is not known. The encoding or decoding of a message body encounters a character set which is not understood by Perl's Encode module. Cast by C<encode()> =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =item Fault: error closing $file after write body: $! Cast by C<write()> =item Error: message body: illegal datatype '$type' for data option. Cast by C<new()> =item Error: message body: illegal datatype '$type' for file option. Cast by C<new()> =item Warning: no decoder defined for transfer encoding '$encoding'. The data (message body) is encoded in a way which is not currently understood, therefore no decoding (or recoding) can take place. Cast by C<encode()> =item Warning: no encoder defined for transfer encoding '$encoding'. The data (message body) has been decoded, but the required encoding is unknown. The decoded data is returned. Cast by C<encode()> =item Error: no filename parameter for write() body. Cast by C<write()> =item Error: part number needs multi-part or nested. Cast by C<partNumberOf()> =item Error: unknown line terminator '$eol'. Cast by C<eol()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. �����������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Replace/���������������������������������������������������������0000755�0001750�0000144�00000000000�15166136132�021017� 5����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Replace/MailHeader.pm��������������������������������������������0000644�0001750�0000144�00000007513�15166136116�023360� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::Replace::MailHeader;{ our $VERSION = '4.05'; } use parent 'Mail::Message::Head::Complete'; use strict; use warnings; use Log::Report 'mail-message', import => [ qw/__x error panic/ ]; #-------------------- sub new(@) { my $class = shift; unshift @_, 'raw_data' if @_ % 2; $class->SUPER::new(@_); } sub init($) { my ($self, $args) = @_; $self->SUPER::init($args); $self->modify($args->{Modify} || $args->{Reformat} || 0); $self->fold_length($args->{FoldLength} || 79); $self->mail_from($args->{MailFrom} || 'KEEP'); $self; } #-------------------- sub delete($;$) { my ($self, $tag) = (shift, shift); @_ or return $self->delete($tag); my $index = shift; my @fields = $self->get($tag); my ($field) = splice @fields, $index, 1; $self->reset($tag, @fields); $field; } sub add($$) { my $self = shift; my $field = $self->add(shift); $field->unfoldedBody; } sub replace($$;$) { my ($self, $tag, $line, $index) = @_; $tag //= $line =~ s/^([^:]+)\:\s*// ? $1 : 'MISSING'; my $field = Mail::Message::Field::Fast->new($tag, $line); my @fields = $self->get($tag); $fields[ $index||0 ] = $field; $self->reset($tag, @fields); $field; } #-------------------- sub get($;$) { my $head = shift->head; my @ret = map $head->get(@_), @_; wantarray ? (map $_->unfoldedBody, @ret) : @ret ? $ret[0]->unfoldedBody : undef; } #-------------------- sub modify(;$) { my $self = shift; @_ ? ($self->{MH_refold} = shift) : $self->{MH_refold}; } sub mail_from(;$) { my $self = shift; @_ or return $self->{MH_mail_from}; my $choice = uc(shift); $choice =~ /^(IGNORE|ERROR|COERCE|KEEP)$/ or error __x"bad Mail-From choice: '{pick}'.", pick => $choice; $self->{MH_mail_from} = $choice; } sub fold(;$) { my $self = shift; my $wrap = @_ ? shift : $self->fold_length; $_->setWrapLength($wrap) for $self->orderedFields; $self; } sub unfold(;$) { my $self = shift; my @fields = @_ ? $self->get(shift) : $self->orderedFields; $_->setWrapLength(100_000) for @fields; # blunt approach $self; } sub extract($) { my ($self, $lines) = @_; my $parser = Mail::Box::Parser::Perl->new(filename => 'extract from array', data => $lines, trusted => 1); $self->read($parser); $parser->close; # Remove header from array shift @$lines while @$lines && $lines->[0] != m/^[\r\n]+/; shift @$lines if @$lines; $self; } sub read($) { my ($self, $file) = @_; my $parser = Mail::Box::Parser::Perl->new(filename => ('from file-handle '.ref $file), file => $file, trusted => 1); $self->read($parser); $parser->close; $self; } sub empty() { $_[0]->removeFields( m/^/ ) } sub header(;$) { my $self = shift; $self->extract(shift) if @_; $self->fold if $self->modify; [ $self->orderedFields ]; } sub header_hashref($) { panic "Don't use header_hashref!!!" } sub combine($;$) { panic "Don't use combine()!!!" } sub exists() { $_[0]->count } sub as_string() { $_[0]->string } sub fold_length(;$$) { my $self = shift; @_ or return $self->{MH_wrap}; my $old = $self->{MH_wrap}; my $wrap = $self->{MH_wrap} = shift; $self->fold($wrap) if $self->modify; $old; } sub tags() { $_[0]->names } sub dup() { $_[0]->clone } sub cleanup() { $_[0] } #-------------------- BEGIN { no warnings; *Mail::Header::new = sub { my $class = shift; Mail::Message::Replace::MailHeader->new(@_); }; } sub isa($) { my ($thing, $class) = @_; $class eq 'Mail::Mailer' ? 1 : $thing->SUPER::isa($class); } 1; �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Replace/MailInternet.pod�����������������������������������������0000644�0001750�0000144�00000061712�15166136120�024122� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Replace::MailInternet - fake Mail::Internet =head1 INHERITANCE Mail::Message::Replace::MailInternet is a Mail::Message is a Mail::Reporter =head1 SYNOPSIS # change use Mail::Internet; # into use Mail::Message::Replace::MailInternet; # in existing code, and the code should still work, but # with the Mail::Message features. =head1 DESCRIPTION This module is a wrapper around a L<Mail::Message|Mail::Message>, which simulates a L<Mail::Internet> object. The name-space of that module is hijacked and many methods are added. Most methods will work without any change, but you may need to have a look at your L<smtpsend()|Mail::Message::Replace::MailInternet/"The body"> and L<send()|Mail::Message::Replace::MailInternet/"The message"> calls. Extends L<"DESCRIPTION" in Mail::Message|Mail::Message/"DESCRIPTION">. =head1 OVERLOADED =head1 METHODS Extends L<"METHODS" in Mail::Message|Mail::Message/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Message|Mail::Message/"Constructors">. =over 4 =item $obj-E<gt>B<clone>(%options) Inherited, see L<Mail::Message/"Constructors"> =item $obj-E<gt>B<dup>() Duplicate the message. The result will again be a L<Mail::Internet> compatible object. =item $obj-E<gt>B<empty>() Remove all data from this object. Very dangerous! =item $class-E<gt>B<new>( [$arg], [%options] ) Inherited, see L<Mail::Reporter/"Constructors"> -Option --Defined in --Default Body undef FoldLength 79 Header undef MailFrom 'KEEP' Modify false body Mail::Message undef body_type Mail::Message Mail::Message::Body::Lines deleted Mail::Message false field_type Mail::Message undef head Mail::Message undef head_type Mail::Message Mail::Message::Replace::MailHeader labels Mail::Message +{} messageId Mail::Message undef message_id Mail::Message undef modified Mail::Message false trusted Mail::Message false =over 2 =item Body => \@lines Array of C<"\n"> terminated lines. If not specified, the lines will be read from C<$arg>. =item FoldLength => $octets Number of characters (encoded C<$octets>) permitted on any refolded header line. Passed to L<Mail::Message::Replace::MailHeader::new(FoldLength)|Mail::Message::Replace::MailHeader/"METHODS">. =item Header => $head The L<Mail::Header> object, which is passed here, is a fake one as well... It is translated into a L<new(head)|Mail::Message/"Constructors">. If not given, the header will be parsed from the C<$arg>. =item MailFrom => 'IGNORE'|'ERROR'|'COERCE'|'KEEP' What to do with leading "C<From >" lines in e-mail data. Passed to L<Mail::Message::Replace::MailHeader::new(MailFrom)|Mail::Message::Replace::MailHeader/"METHODS">. =item Modify => BOOLEAN Whether to re-fold all the incoming fields. Passed to L<Mail::Message::Replace::MailHeader::new(Modify)|Mail::Message::Replace::MailHeader/"METHODS">. =item body => $object =item body_type => $class =item deleted => BOOLEAN =item field_type => $class =item head => $object =item head_type => $class =item labels => \@pairs|\%settings =item messageId => $id =item message_id => $id =item modified => BOOLEAN =item trusted => BOOLEAN =back » example: replace traditional Mail::Internet by this wrapper # was use Mail::Internet; my $mi = Mail::Internet->new(@options); # becomes use Mail::Message::Replace::MailInternet; my $mi = Mail::Internet->new(@options); =back =head2 Attributes Extends L<"Attributes" in Mail::Message|Mail::Message/"Attributes">. =over 4 =item $obj-E<gt>B<MailFrom>( [STRING] ) Your email address. =item $obj-E<gt>B<bodyType>() Inherited, see L<Mail::Message/"Attributes"> =item $obj-E<gt>B<fieldType>() Inherited, see L<Mail::Message/"Attributes"> =item $obj-E<gt>B<headType>() Inherited, see L<Mail::Message/"Attributes"> =item $obj-E<gt>B<messageId>() Inherited, see L<Mail::Message/"Attributes"> =back =head2 Constructing a message Extends L<"Constructing a message" in Mail::Message|Mail::Message/"Constructing a message">. =over 4 =item $obj-E<gt>B<add_signature>( [$filename] ) Replaced by L<sign()|Mail::Message::Replace::MailInternet/"Constructing a message">, but still usable. C<$filename> is the file which contains the signature, which defaults to C<$ENV{HOME}/.signature>. =item $obj-E<gt>B<bounce>( [<$rg_object|%options>] ) Inherited, see L<Mail::Message::Construct::Bounce/"Constructing a message"> =item $class-E<gt>B<build>( [$message|$part|$body], @fields, %options ) Inherited, see L<Mail::Message::Construct::Build/"Constructing a message"> =item $class-E<gt>B<buildFromBody>($body, [$head], $headers) Inherited, see L<Mail::Message::Construct::Build/"Constructing a message"> =item $obj-E<gt>B<extract>(\@lines|$fh) Read header and body from an ARRAY or C<$fh> =item $obj-E<gt>B<forward>(%options) Inherited, see L<Mail::Message::Construct::Forward/"Constructing a message"> =item $obj-E<gt>B<forwardAttach>(%options) Inherited, see L<Mail::Message::Construct::Forward/"Constructing a message"> =item $obj-E<gt>B<forwardEncapsulate>(%options) Inherited, see L<Mail::Message::Construct::Forward/"Constructing a message"> =item $obj-E<gt>B<forwardInline>(%options) Inherited, see L<Mail::Message::Construct::Forward/"Constructing a message"> =item $obj-E<gt>B<forwardNo>(%options) Inherited, see L<Mail::Message::Construct::Forward/"Constructing a message"> =item $obj-E<gt>B<forwardPostlude>() Inherited, see L<Mail::Message::Construct::Forward/"Constructing a message"> =item $obj-E<gt>B<forwardPrelude>() Inherited, see L<Mail::Message::Construct::Forward/"Constructing a message"> =item $obj-E<gt>B<forwardSubject>(STRING) Inherited, see L<Mail::Message::Construct::Forward/"Constructing a message"> =item $any-E<gt>B<read>(\@lines|$fh, %options) Read header and body from the specified ARRAY or C<$fh>. When used as object method, L<Mail::Message::read()|Mail::Message::Construct::Read/"Constructing a message"> is called, to be MailBox compliant. As class method, the L<Mail::Internet|Mail::Internet> compatible read is called. C<%options> are only available in the first case. Improves base, see L<Mail::Message::Construct::Read/"Constructing a message"> -Option --Defined in --Default body_type Mail::Message::Construct::Read undef parser_class Mail::Message::Construct::Read undef seekable Mail::Message::Construct::Read false strip_status_fields Mail::Message::Construct::Read true trusted Mail::Message::Construct::Read true =over 2 =item body_type => $type =item parser_class => $type =item seekable => BOOLEAN =item strip_status_fields => BOOLEAN =item trusted => BOOLEAN =back =item $obj-E<gt>B<read_body>(\@lines|$fh) Read only the message's body from the ARRAY or C<$fh>. =item $obj-E<gt>B<read_header>(\@lines|$fh) Read only the message's header from the ARRAY or C<$fh> =item $obj-E<gt>B<rebuild>(%options) Inherited, see L<Mail::Message::Construct::Rebuild/"Constructing a message"> =item $obj-E<gt>B<reply>(%options) BE WARNED: the main job for creating a reply is done by L<Mail::Message::reply()|Mail::Message::Construct::Reply/"Constructing a message">, which may produce a result which is compatible, but may be different from L<Mail::Internet>'s version. Improves base, see L<Mail::Message::Construct::Reply/"Constructing a message"> -Option --Defined in --Default Bcc Mail::Message::Construct::Reply undef Cc Mail::Message::Construct::Reply <'cc' in current> Exclude [] From Mail::Message::Construct::Reply <'to' in current> Inline > Keep [] Message-ID Mail::Message::Construct::Reply <uniquely generated> ReplyAll <C<false>> Subject Mail::Message::Construct::Reply replySubject() To Mail::Message::Construct::Reply <sender in current> body Mail::Message::Construct::Reply undef group_reply Mail::Message::Construct::Reply true header_template $ENV{HOME}/.mailhdr include Mail::Message::Construct::Reply 'INLINE' max_signature Mail::Message::Construct::Reply 10 message_type Mail::Message::Construct::Reply Mail::Message postlude Mail::Message::Construct::Reply undef prelude Mail::Message::Construct::Reply undef quote Mail::Message::Construct::Reply '> ' signature Mail::Message::Construct::Reply undef strip_signature Mail::Message::Construct::Reply qr/^--\s/ =over 2 =item Bcc => $body|$address|\@addresses =item Cc => $body|$address|\@addresses =item Exclude => \@names Remove the fields with the specified names from the produced reply message. =item From => $body|$address|\@addresses =item Inline => STRING Quotation STRING, which is translated into L<reply(quote)|Mail::Message::Construct::Reply/"Constructing a message">. The normal default of C<quote> is "E<gt> ", in stead of "E<gt>". =item Keep => \@names Copy all header fields with the specified NAMES from the source to the reply message. =item Message-ID => $field|$line =item ReplyAll => BOOLEAN Reply to the group? Translated into L<reply(group_reply)|Mail::Message::Construct::Reply/"Constructing a message">, which has as default the exact oposite of this option, being C<true>. =item Subject => $field|$line|CODE =item To => $body|$address|\@addresses =item body => $body =item group_reply => BOOLEAN =item header_template => $filename|undef Read the return header from the template file. When this is explicitly set to C<undef>, or the file does not exist, then a header will be created. =item include => 'NO'|'INLINE'|'ATTACH' =item max_signature => INTEGER =item message_type => CLASS =item postlude => $body|\@lines =item prelude => $body|\@lines =item quote => CODE|STRING =item signature => $body|$message =item strip_signature => REGEXP|STRING|CODE =back =item $obj-E<gt>B<replyPrelude>( [STRING|$field|$address|\@addrs|\@fields] ) Inherited, see L<Mail::Message::Construct::Reply/"Constructing a message"> =item $any-E<gt>B<replySubject>(STRING) Inherited, see L<Mail::Message::Construct::Reply/"Constructing a message"> =item $obj-E<gt>B<sign>(%options) Add a signature (a few extra lines) to the message. -Option --Default File undef Signature '' =over 2 =item File => $filename Specifies a filename where the signature is in. =item Signature => STRING|\@lines The signature in memory. =back =back =head2 The message Extends L<"The message" in Mail::Message|Mail::Message/"The message">. =over 4 =item $obj-E<gt>B<container>() Inherited, see L<Mail::Message/"The message"> =item $obj-E<gt>B<endsOnNewline>() Inherited, see L<Mail::Message/"The message"> =item $obj-E<gt>B<isDummy>() Inherited, see L<Mail::Message/"The message"> =item $obj-E<gt>B<isPart>() Inherited, see L<Mail::Message/"The message"> =item $obj-E<gt>B<partNumber>() Inherited, see L<Mail::Message/"The message"> =item $obj-E<gt>B<print>( [$fh] ) Prints the whole message to the specified C<$fh>, which default to STDOUT. This calls L<Mail::Message::print()|Mail::Message/"The message">. Improves base, see L<Mail::Message/"The message"> =item $obj-E<gt>B<send>($type, %options) Send via Mail Transfer Agents (MUA). These will be handled by various L<Mail::Transport::Send|Mail::Transport::Send> extensions. The C<test> C<$type> is not supported. Improves base, see L<Mail::Message/"The message"> =item $obj-E<gt>B<size>() Inherited, see L<Mail::Message/"The message"> =item $obj-E<gt>B<toplevel>() Inherited, see L<Mail::Message/"The message"> =item $obj-E<gt>B<write>( [$fh] ) Inherited, see L<Mail::Message/"The message"> =back =head2 The header Extends L<"The header" in Mail::Message|Mail::Message/"The header">. =over 4 =item $obj-E<gt>B<add>(\@lines) Add header lines, which simply calls C<Mail::Message::Head::add()> on the header for each specified LINE. The last added LINE is returned. =item $obj-E<gt>B<bcc>() Inherited, see L<Mail::Message/"The header"> =item $obj-E<gt>B<cc>() Inherited, see L<Mail::Message/"The header"> =item $obj-E<gt>B<clean_header>() Not to be used, replaced by L<header()|Mail::Message::Replace::MailInternet/"The header">. =item $obj-E<gt>B<combine>( $tag, [$with] ) Not implemented, because I see no use for it. =item $obj-E<gt>B<date>() Inherited, see L<Mail::Message/"The header"> =item $obj-E<gt>B<delete>( $name, [$index]] ) Delete the fields with the specified C<$name>. The deleted fields are returned. BE WARNED: if no C<$name> is specified, the C<delete> is interpreted as the deletion of the message in a folder, so L<Mail::Box::Message::delete()|Mail::Message/"Flags"> will be called. This may have no negative effect at all... Calls L<Mail::Message::Replace::MailHeader::delete()|Mail::Message::Replace::MailHeader/"Access to the header"> Improves base, see L<Mail::Message/"Flags"> =item $obj-E<gt>B<destinations>() Inherited, see L<Mail::Message/"The header"> =item $obj-E<gt>B<fold>( [$length] ) Fold all the fields to a certain maximum C<$length>. Implemented by L<Mail::Message::Replace::MailHeader::fold()|Mail::Message::Replace::MailHeader/"Simulating Mail::Header"> =item $obj-E<gt>B<fold_length>( [[$tag], $length] ) Set the maximum line C<$length>. C<$tag> is ignored. Implemented by L<Mail::Message::Replace::MailHeader::fold_length()|Mail::Message::Replace::MailHeader/"Simulating Mail::Header"> =item $obj-E<gt>B<from>() Inherited, see L<Mail::Message/"The header"> =item $obj-E<gt>B<get>( $name, [$index] ) Get all the header fields with the specified C<$name>. In scalar context, only the first fitting C<$name> is returned. Even when only one C<$name> is specified, multiple lines may be returned: some fields appear more than once in a header. Calls L<Mail::Message::Replace::MailHeader::get()|Mail::Message::Replace::MailHeader/"Access to the header"> Improves base, see L<Mail::Message/"The header"> =item $obj-E<gt>B<guessTimestamp>() Inherited, see L<Mail::Message/"The header"> =item $obj-E<gt>B<head>( [$head] ) Returns the head of the message, or creates an empty one if none is defined. The C<$head> argument, which sets the header, is not available for L<Mail::Internet>, but is there to be compatible with the C<head> method of L<Mail::Message|Mail::Message>. Improves base, see L<Mail::Message/"The header"> =item $obj-E<gt>B<header>( [\@lines] ) Optionally reads a header from the ARRAY of lines, and then returns those fields as array-ref nicely folded. Implemented by L<Mail::Message::Replace::MailHeader::header()|Mail::Message::Replace::MailHeader/"Simulating Mail::Header"> =item $obj-E<gt>B<nrLines>() Inherited, see L<Mail::Message/"The header"> =item $obj-E<gt>B<print_header>($fh) Calls L<Mail::Message::Head::Complete::print()|Mail::Message::Head::Complete/"Access to the header">. =item $obj-E<gt>B<replace>( $tag, $line, [$index] ) Adds LINES to the header, but removes fields with the same name if they already exist. Calls L<Mail::Message::Replace::MailHeader::replace()|Mail::Message::Replace::MailHeader/"Access to the header"> =item $obj-E<gt>B<sender>() Inherited, see L<Mail::Message/"The header"> =item $obj-E<gt>B<study>($fieldname) Inherited, see L<Mail::Message/"The header"> =item $obj-E<gt>B<subject>() Inherited, see L<Mail::Message/"The header"> =item $obj-E<gt>B<tidy_headers>() No effect anymore (always performed). =item $obj-E<gt>B<timestamp>() Inherited, see L<Mail::Message/"The header"> =item $obj-E<gt>B<to>() Inherited, see L<Mail::Message/"The header"> =back =head2 The body Extends L<"The body" in Mail::Message|Mail::Message/"The body">. =over 4 =item $obj-E<gt>B<body>($lines|@lines) Returns an ARRAY of lines, representing the body. With arguments, a new body will be created. In L<Mail::Internet>, the body is not an object but a simple array. BE WARNED: this overrules the L<Mail::Message::body()|Mail::Message/"The body"> method, which may cause some confusion. Use L<bodyObject()|Mail::Message::Replace::MailInternet/"The body"> to get access to that body's data. Improves base, see L<Mail::Message/"The body"> =item $obj-E<gt>B<bodyObject>( [$body] ) Calls L<Mail::Message::body()|Mail::Message/"The body">, because that C<body> method is overruled by the one which has a L<Mail::Internet> compatible interface. =item $obj-E<gt>B<contentType>() Inherited, see L<Mail::Message/"The body"> =item $obj-E<gt>B<decoded>(%options) Inherited, see L<Mail::Message/"The body"> =item $obj-E<gt>B<encode>(%options) Inherited, see L<Mail::Message/"The body"> =item $obj-E<gt>B<isMultipart>() Inherited, see L<Mail::Message/"The body"> =item $obj-E<gt>B<isNested>() Inherited, see L<Mail::Message/"The body"> =item $obj-E<gt>B<parts>( [<'ALL'|'ACTIVE'|'DELETED'|'RECURSE'|$filter>] ) Inherited, see L<Mail::Message/"The body"> =item $obj-E<gt>B<print_body>( [$fh] ) Prints the body to the specified C<$fh>, which defaults to STDOUT. This calls L<Mail::Message::Body::print()|Mail::Message::Body/"Access to the payload">. =item $obj-E<gt>B<remove_sig>( [$nrlines] ) Remove the signature of a message with a maximum of C<$nrlines> lines, which defaults to 10. The work is done on the decoded body content, by L<Mail::Message::Body::stripSignature()|Mail::Message::Body::Construct/"Constructing a body">. =item $obj-E<gt>B<smtpsend>(%options) This method is calling L<Mail::Message::send()|Mail::Message/"The message"> via C<smtp>, which is implemented in L<Mail::Transport::SMTP|Mail::Transport::SMTP>. The implementation is slightly different, so this method is not 100% compliant. -Option --Default Debug false Hello <helo_domain from Net::Config> Host $ENV{SMTPHOSTS} or from Net::Config MailFrom $ENV{MAILADDRESS} or $ENV{USER} Port 25 =over 2 =item Debug => BOOLEAN =item Hello => STRING =item Host => $hostname Only the first detected C<$hostname> is taken, so differs from the original implementation. =item MailFrom => STRING Your e-mail address. This simulated L<Mail::Internet> object does not try to create an e-mail address from the sendmail configuration file, because that is generally a bad idea in environments with virtual hosts, as we have now-adays. =item Port => INTEGER =back =item $obj-E<gt>B<tidy_body>() Removes blank lines from begin and end of the body. =back =head2 Flags Extends L<"Flags" in Mail::Message|Mail::Message/"Flags">. =over 4 =item $obj-E<gt>B<deleted>( [BOOLEAN] ) Inherited, see L<Mail::Message/"Flags"> =item $obj-E<gt>B<isDeleted>() Inherited, see L<Mail::Message/"Flags"> =item $obj-E<gt>B<isModified>() Inherited, see L<Mail::Message/"Flags"> =item $obj-E<gt>B<label>($label|PAIRS) Inherited, see L<Mail::Message/"Flags"> =item $obj-E<gt>B<labels>() Inherited, see L<Mail::Message/"Flags"> =item $obj-E<gt>B<labelsToStatus>() Inherited, see L<Mail::Message/"Flags"> =item $obj-E<gt>B<modified>( [BOOLEAN] ) Inherited, see L<Mail::Message/"Flags"> =item $obj-E<gt>B<statusToLabels>() Inherited, see L<Mail::Message/"Flags"> =back =head2 The whole message as text Extends L<"The whole message as text" in Mail::Message|Mail::Message/"The whole message as text">. =over 4 =item $obj-E<gt>B<as_mbox_string>() Returns the whole message as one string, which can be included in an MBOX folder (while not using L<Mail::Box::Mbox|Mail::Box::Mbox>). Lines in the body which start with C<From > are escaped with an E<gt>. =item $obj-E<gt>B<file>() Inherited, see L<Mail::Message::Construct::Text/"The whole message as text"> =item $obj-E<gt>B<lines>() Inherited, see L<Mail::Message::Construct::Text/"The whole message as text"> =item $obj-E<gt>B<printStructure>( [$fh|undef],[$indent] ) Inherited, see L<Mail::Message::Construct::Text/"The whole message as text"> =item $obj-E<gt>B<string>() Inherited, see L<Mail::Message::Construct::Text/"The whole message as text"> =back =head2 The nasty bits =over 4 =item $any-E<gt>B<isa>($class) Of course, the C<isa()> class inheritance check should not see our nasty trick. =back =head2 Internals Extends L<"Internals" in Mail::Message|Mail::Message/"Internals">. =over 4 =item $obj-E<gt>B<clonedFrom>() Inherited, see L<Mail::Message/"Internals"> =item $class-E<gt>B<coerce>($message) Coerce (adapt type) of the specified C<$message> (anything L<Mail::Message::coerce()|Mail::Message/"Internals"> accepts) into an L<Mail::Internet|Mail::Internet> simulating object. Improves base, see L<Mail::Message/"Internals"> =item $obj-E<gt>B<isDelayed>() Inherited, see L<Mail::Message/"Internals"> =item $obj-E<gt>B<isTrusted>() Inherited, see L<Mail::Message/"Internals"> =item $obj-E<gt>B<readBody>( $parser, $head, [$bodytype] ) Inherited, see L<Mail::Message/"Internals"> =item $obj-E<gt>B<readFromParser>( $parser, [$bodytype] ) Inherited, see L<Mail::Message/"Internals"> =item $obj-E<gt>B<readHead>( $parser, [$class] ) Inherited, see L<Mail::Message/"Internals"> =item $obj-E<gt>B<recursiveRebuildPart>($part, %options) Inherited, see L<Mail::Message::Construct::Rebuild/"Internals"> =item $obj-E<gt>B<storeBody>($body) Inherited, see L<Mail::Message/"Internals"> =item $obj-E<gt>B<takeMessageId>( [STRING] ) Inherited, see L<Mail::Message/"Internals"> =back =head2 Error handling Extends L<"Error handling" in Mail::Message|Mail::Message/"Error handling">. =over 4 =item $obj-E<gt>B<AUTOLOAD>() Inherited, see L<Mail::Message::Construct/"METHODS"> =item $obj-E<gt>B<notImplemented>() Inherited, see L<Mail::Reporter/"Error handling"> =item $any-E<gt>B<shortSize>( [$value] ) Inherited, see L<Mail::Message/"Error handling"> =item $obj-E<gt>B<shortString>() Inherited, see L<Mail::Message/"Error handling"> =back =head2 Cleanup Extends L<"Cleanup" in Mail::Message|Mail::Message/"Cleanup">. =over 4 =item $obj-E<gt>B<DESTROY>() Inherited, see L<Mail::Reporter/"Cleanup"> =item $obj-E<gt>B<destruct>() Inherited, see L<Mail::Message/"Cleanup"> =back =head1 DETAILS Extends L<"DETAILS" in Mail::Message|Mail::Message/"DETAILS">. =head1 DIAGNOSTICS =over 4 =item Error: Cannot include forward source as $kind. Unknown alternative for the L<forward(include)|Mail::Message::Construct::Forward/"Constructing a message">. Valid choices are C<NO>, C<INLINE>, C<ATTACH>, and C<ENCAPSULATE>. Cast by C<forward()> =item Error: Mail::Internet does not support $what data. The data can only be a file handle or an ARRAY. Other data types are not supported (see L<read()|Mail::Message::Replace::MailInternet/"Constructing a message"> if you want to have more). Cast by C<new()> =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =item Error: method bounce requires To, Cc, or Bcc. The message L<bounce()|Mail::Message::Construct::Bounce/"Constructing a message"> method forwards a received message off to someone else without modification; you must specified it's new destination. If you have the urge not to specify any destination, you probably are looking for L<reply()|Mail::Message::Replace::MailInternet/"Constructing a message">. When you wish to modify the content, use L<forward()|Mail::Message::Construct::Forward/"Constructing a message">. Cast by C<bounce()> =item Error: method forwardAttach requires a preamble. Cast by C<forwardAttach()> =item Error: method forwardEncapsulate requires a preamble. Cast by C<forwardEncapsulate()> =item Error: method forwardNo requires a To. Cast by C<forwardNo()> =item Error: method forwardNo requires a body. Cast by C<forwardNo()> =item Error: no rebuild rule $name defined. Cast by C<rebuild()> =item Error: only build() Mail::Message's; they are not in a folder yet. You may wish to construct a message to be stored in a some kind of folder, but you need to do that in two steps. First, create a normal L<Mail::Message|Mail::Message>, and then add it to the folder. During this L<Mail::Box::addMessage()|Mail::Box/"The folder"> process, the message will get L<coerce()|Mail::Message::Replace::MailInternet/"Internals">-d into the right message type, adding storage information and the like. Cast by C<build()> =item Error: select parts via '$what'? Cast by C<parts()> =item Warning: skipped unknown key '$key' in build. Cast by C<build()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. ������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Replace/MailHeader.pod�������������������������������������������0000644�0001750�0000144�00000034205�15166136120�023517� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Replace::MailHeader - fake Mail::Header =head1 INHERITANCE Mail::Message::Replace::MailHeader is a Mail::Message::Head::Complete is a Mail::Message::Head is a Mail::Reporter =head1 SYNOPSIS # change use Mail::Internet; use Mail::Header; # into use Mail::Message::Replace::MailInternet; # in existing code, and the code should still work, but # with the Mail::Message features. =head1 DESCRIPTION This module is a wrapper around a L<Mail::Message::Head::Complete|Mail::Message::Head::Complete>, which simulates a L<Mail::Header> object. The name-space of that module is hijacked and many methods are added. Most methods will work without any change, but you should test your software again. Small changes have been made to L<fold_length()|Mail::Message::Replace::MailHeader/"Simulating Mail::Header">, L<header_hashref()|Mail::Message::Replace::MailHeader/"Simulating Mail::Header">. Extends L<"DESCRIPTION" in Mail::Message::Head::Complete|Mail::Message::Head::Complete/"DESCRIPTION">. =head1 OVERLOADED Extends L<"OVERLOADED" in Mail::Message::Head::Complete|Mail::Message::Head::Complete/"OVERLOADED">. =over 4 =item overload: B<""> stringifaction Inherited, see L<Mail::Message::Head/"OVERLOADED"> =item overload: B<bool> true/false Inherited, see L<Mail::Message::Head/"OVERLOADED"> =back =head1 METHODS Extends L<"METHODS" in Mail::Message::Head::Complete|Mail::Message::Head::Complete/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Message::Head::Complete|Mail::Message::Head::Complete/"Constructors">. =over 4 =item $class-E<gt>B<build>( [PAIR|$field], ... ) Inherited, see L<Mail::Message::Head::Complete/"Constructors"> =item $obj-E<gt>B<clone>( [@names|ARRAY|Regexps] ) Inherited, see L<Mail::Message::Head::Complete/"Constructors"> =item $class-E<gt>B<new>( [$arg], %options ) The C<$arg> is an array with header lines. Improves base, see L<Mail::Message::Head/"Constructors"> -Option --Defined in --Default FoldLength 79 MailFrom 'KEEP' Modify false field_type Mail::Message::Head Mail::Message::Field::Fast message Mail::Message::Head undef modified Mail::Message::Head false =over 2 =item FoldLength => $octets =item MailFrom => 'IGNORE'|'ERROR'|'COERCE'|'KEEP' How to handle the C<From > lines. See L<mail_from()|Mail::Message::Replace::MailHeader/"Simulating Mail::Header">. =item Modify => BOOLEAN Reformat all header lines when they come in: change the folding. =item field_type => CLASS =item message => $message =item modified => BOOLEAN =back =back =head2 Attributes Extends L<"Attributes" in Mail::Message::Head::Complete|Mail::Message::Head::Complete/"Attributes">. =head2 The header Extends L<"The header" in Mail::Message::Head::Complete|Mail::Message::Head::Complete/"The header">. =over 4 =item $obj-E<gt>B<isDelayed>() Inherited, see L<Mail::Message::Head/"The header"> =item $obj-E<gt>B<isEmpty>() Inherited, see L<Mail::Message::Head/"The header"> =item $obj-E<gt>B<isModified>() Inherited, see L<Mail::Message::Head/"The header"> =item $obj-E<gt>B<knownNames>() Inherited, see L<Mail::Message::Head/"The header"> =item $obj-E<gt>B<message>( [$message] ) Inherited, see L<Mail::Message::Head/"The header"> =item $obj-E<gt>B<modified>( [BOOLEAN] ) Inherited, see L<Mail::Message::Head/"The header"> =item $obj-E<gt>B<nrLines>() Inherited, see L<Mail::Message::Head::Complete/"The header"> =item $obj-E<gt>B<orderedFields>() Inherited, see L<Mail::Message::Head/"The header"> =item $obj-E<gt>B<size>() Inherited, see L<Mail::Message::Head::Complete/"The header"> =item $obj-E<gt>B<wrap>($integer) Inherited, see L<Mail::Message::Head::Complete/"The header"> =back =head2 Access to the header Extends L<"Access to the header" in Mail::Message::Head::Complete|Mail::Message::Head::Complete/"Access to the header">. =over 4 =item $obj-E<gt>B<add>( $line, [$index] ) Add a header line, which simply calls C<Mail::Message::Head::add()> on the header for the specified C<$line>. The C<$index> is ignored, the unfolded body of the field is returned. Improves base, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<addListGroup>($object) Inherited, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<addResentGroup>($resent_group|$data) Inherited, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<addSpamGroup>($object) Inherited, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<count>($name) Inherited, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<delete>( $tag, [$index] ) Delete the fields with the specified C<$tag>. The deleted fields are returned. If no index is given, then all are removed. Improves base, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<get>( $name, [$index] ) Get all the header fields with the specified C<$name>. In scalar context, only the first fitting C<$name> is returned. Even when only one C<$name> is specified, multiple lines may be returned in list context: some fields appear more than once in a header. Improves base, see L<Mail::Message::Head/"Access to the header"> =item $obj-E<gt>B<grepNames>( [@names|ARRAY|Regexps] ) Inherited, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<listGroup>() Inherited, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<names>() Inherited, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<print>( [$fh] ) Inherited, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<printSelected>($fh, <STRING|Regexp>, ...) Inherited, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<printUndisclosed>( [$fh] ) Inherited, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<removeContentInfo>() Inherited, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<removeField>($field) Inherited, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<removeFields>( <STRING|Regexp>, ... ) Inherited, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<removeFieldsExcept>( <STRING|Regexp>, ... ) Inherited, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<removeListGroup>() Inherited, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<removeResentGroups>() Inherited, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<removeSpamGroups>() Inherited, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<replace>( $tag, $line, [$index] ) Replace the field named C<$tag>. from place C<$index> (by default the first) by the C<$line>. When C<$tag> is C<undef>, it will be extracted from the C<$line> first. This calls L<Mail::Message::Head::Complete::reset()|Mail::Message::Head::Complete/"Access to the header"> on the message's head. =item $obj-E<gt>B<resentGroups>() Inherited, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<reset>($name, @fields) Inherited, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<set>( $field | $line | <$name, $body, [$attrs]> ) Inherited, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<spamDetected>() Inherited, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<spamGroups>( [$names] ) Inherited, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<string>() Inherited, see L<Mail::Message::Head::Complete/"Access to the header"> =item $obj-E<gt>B<study>( $name, [$index] ) Inherited, see L<Mail::Message::Head/"Access to the header"> =back =head2 About the body Extends L<"About the body" in Mail::Message::Head::Complete|Mail::Message::Head::Complete/"About the body">. =over 4 =item $obj-E<gt>B<guessBodySize>() Inherited, see L<Mail::Message::Head/"About the body"> =item $obj-E<gt>B<guessTimeStamp>() Inherited, see L<Mail::Message::Head::Complete/"About the body"> =item $obj-E<gt>B<isMultipart>() Inherited, see L<Mail::Message::Head/"About the body"> =item $obj-E<gt>B<recvstamp>() Inherited, see L<Mail::Message::Head::Complete/"About the body"> =item $obj-E<gt>B<timestamp>() Inherited, see L<Mail::Message::Head::Complete/"About the body"> =back =head2 Internals Extends L<"Internals" in Mail::Message::Head::Complete|Mail::Message::Head::Complete/"Internals">. =over 4 =item $obj-E<gt>B<addNoRealize>($field) Inherited, see L<Mail::Message::Head/"Internals"> =item $obj-E<gt>B<addOrderedFields>($fields) Inherited, see L<Mail::Message::Head/"Internals"> =item $obj-E<gt>B<createFromLine>() Inherited, see L<Mail::Message::Head::Complete/"Internals"> =item $obj-E<gt>B<createMessageId>() Inherited, see L<Mail::Message::Head::Complete/"Internals"> =item $obj-E<gt>B<fileLocation>() Inherited, see L<Mail::Message::Head/"Internals"> =item $obj-E<gt>B<load>() Inherited, see L<Mail::Message::Head/"Internals"> =item $any-E<gt>B<messageIdPrefix>( [$prefix, [$hostname]|CODE] ) Inherited, see L<Mail::Message::Head::Complete/"Internals"> =item $obj-E<gt>B<moveLocation>($distance) Inherited, see L<Mail::Message::Head/"Internals"> =item $obj-E<gt>B<setNoRealize>($field) Inherited, see L<Mail::Message::Head/"Internals"> =back =head2 Error handling Extends L<"Error handling" in Mail::Message::Head::Complete|Mail::Message::Head::Complete/"Error handling">. =over 4 =item $obj-E<gt>B<AUTOLOAD>() Inherited, see L<Mail::Reporter/"Error handling"> =item $obj-E<gt>B<notImplemented>() Inherited, see L<Mail::Reporter/"Error handling"> =back =head2 Cleanup Extends L<"Cleanup" in Mail::Message::Head::Complete|Mail::Message::Head::Complete/"Cleanup">. =over 4 =item $obj-E<gt>B<DESTROY>() Inherited, see L<Mail::Reporter/"Cleanup"> =back =head2 Access to the header =head2 Simulating Mail::Header =over 4 =item $obj-E<gt>B<as_string>() Returns the whole header as one big scalar. Calls L<Mail::Message::Head::Complete::string()|Mail::Message::Head::Complete/"Access to the header">. =item $obj-E<gt>B<cleanup>() Cleanup memory usage. Not needed here. =item $obj-E<gt>B<combine>( $tag, [$with] ) I do not see any valid reason for this command, so did not implement it. =item $obj-E<gt>B<dup>() Duplicate the header, which is simply L<clone()|Mail::Message::Head::Complete/"Constructors">. =item $obj-E<gt>B<empty>() Clean-out the whole hash. Better not use this (simply create another header object), although it should work. =item $obj-E<gt>B<exists>() Returns whether there are any fields. =item $obj-E<gt>B<extract>(\@lines) Extract (and remove) header fields from the array. =item $obj-E<gt>B<fold>( [$length] ) Refold all fields in the header, to C<$length> or whatever L<fold_length()|Mail::Message::Replace::MailHeader/"Simulating Mail::Header"> returns. =item $obj-E<gt>B<fold_length>( [[$tag], $length] ) Returns the line wrap, optionally after setting it to C<$length>. The old value is returned. The C<$tag> argument is ignored, because it is silly to have different lines fold in different ways. This method cannot be called statically anymore. =item $obj-E<gt>B<header>( [ARRAY] ) Extract the fields from the C<ARRAY>, if specified, and then fold the fields. Returned is an array with all fields, produced via L<orderedFields()|Mail::Message::Head/"The header">. =item $obj-E<gt>B<header_hashref>(HASH) If you are using this method, you must be stupid... anyway: I do not want to support it for now: use L<add()|Mail::Message::Replace::MailHeader/"Access to the header"> and friends. =item $obj-E<gt>B<mail_from>( ['IGNORE'|'ERROR'|'COERCE'|'KEEP'] ) What to do when a header line in the form `From ' is encountered. Valid values are C<IGNORE> - ignore and discard the header, C<ERROR> - invoke an error (die), C<COERCE> - rename them as Mail-From and C<KEEP> - keep them. =item $obj-E<gt>B<modify>( [BOOLEAN] ) Refold the headers when they are added. =item $obj-E<gt>B<read>($file) Read the header from the C<$file>. Improves base, see L<Mail::Message::Head/"Internals"> =item $obj-E<gt>B<tags>() Returns all the names of fields, implemented by L<Mail::Message::Head::Complete::names()|Mail::Message::Head::Complete/"Access to the header">. =item $obj-E<gt>B<unfold>( [$tag] ) Remove the folding for all instances of C<$tag>, or all fields at once. =back =head2 The nasty bits =over 4 =item $any-E<gt>B<isa>($class) Of course, the C<isa()> class inheritance check should not see our nasty trick. =back =head1 DETAILS Extends L<"DETAILS" in Mail::Message::Head::Complete|Mail::Message::Head::Complete/"DETAILS">. =head1 DIAGNOSTICS =over 4 =item Error: bad Mail-From choice: '$pick'. Cast by C<mail_from()> =item Warning: cannot remove field $name from header: not found. You ask to remove a field which is not known in the header. Using L<delete()|Mail::Message::Replace::MailHeader/"Access to the header">, L<reset()|Mail::Message::Head::Complete/"Access to the header">, or L<set()|Mail::Message::Head::Complete/"Access to the header"> to do the job will not result in warnings: those methods check the existence of the field first. Cast by C<removeField()> =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =item Warning: field objects have an implied name ($name) Cast by C<build()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Replace/MailInternet.pm������������������������������������������0000644�0001750�0000144�00000016535�15166136116�023764� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::Replace::MailInternet;{ our $VERSION = '4.05'; } use parent 'Mail::Message'; use strict; use warnings; use Log::Report 'mail-message', import => [ qw/__x error/ ]; use Mail::Box::FastScalar (); use Mail::Box::Parser::Perl (); use Mail::Message::Body::Lines (); use IO::Handle (); use File::Spec (); use Scalar::Util qw/blessed/; #-------------------- sub new(@) { my $class = shift; my $data = @_ % 2 ? shift : undef; $class = __PACKAGE__ if $class eq 'Mail::Internet'; $class->SUPER::new(@_, raw_data => $data); } sub init($) { my ($self, $args) = @_; $args->{head_type} ||= 'Mail::Message::Replace::MailHeader'; $args->{head} ||= $args->{Header}; $args->{body} ||= $args->{Body}; $self->SUPER::init($args); $self->{MI_wrap} = $args->{FoldLength} || 79; $self->{MI_mail_from} = $args->{MailFrom}; $self->{MI_modify} = exists $args->{Modify} ? $args->{Modify} : 1; $self->processRawData($self->{raw_data}, !defined $args->{Header}, !defined $args->{Body}) if defined $self->{raw_data}; $self; } sub processRawData($$$) { my ($self, $data, $get_head, $get_body) = @_; $get_head || $get_body or return $self; my ($filename, $lines); if(ref $data eq 'ARRAY') { $filename = 'array of lines'; $lines = $data; } elsif(ref $data eq 'GLOB' || (blessed $data && $data->isa('IO::Handle'))) { $filename = 'file (' . (ref $data) . ')'; $lines = [ $data->getlines ]; } else { error __x"Mail::Internet does not support {what UNKNOWN} data.", what => $data; } @$lines or return; my $buffer = join '', @$lines; my $file = Mail::Box::FastScalar->new(\$buffer); my $parser = Mail::Box::Parser::Perl->new(filename => $filename, file => $file, trusted => 1); my $head; if($get_head) { my $from = $lines->[0] =~ m/^From / ? shift @$lines : undef; my $head = $self->{MM_head_type}->new( MailFrom => $self->{MI_mail_from}, Modify => $self->{MI_modify}, FoldLength => $self->{MI_wrap} ); $head->read($parser); $head->mail_from($from) if defined $from; $self->head($head); } else { $head = $self->head; } $self->storeBody($self->readBody($parser, $head)) if $get_body; $self->addReport($parser); $parser->stop; $self; } sub dup() { my $self = shift; (ref $self)->coerce($self->clone); } sub empty() { $_[0]->DESTROY } #-------------------- sub MailFrom(;$) { my $self = shift; @_ ? ($self->{MI_mail_from} = shift) : $self->{MU_mail_from}; } #-------------------- sub read($@) { my $thing = shift; blessed $thing or return $thing->SUPER::read(@_); # Mail::Message behavior # Mail::Header emulation my $data = shift; $thing->processRawData($data, 1, 1); } sub read_body($) { my ($self, $data) = @_; $self->processRawData($data, 0, 1); } sub read_header($) { my ($self, $data) = @_; $self->processRawData($data, 1, 0); } sub extract($) { my ($self, $data) = @_; $self->processRawData($data, 1, 1); } sub reply(@) { my ($self, %args) = @_; my $reply_head = $self->{MM_head_type}->new; my $home = $ENV{HOME} || File::Spec->curdir; my $headtemp = File::Spec->catfile($home, '.mailhdr'); if(open my $head, '<:raw', $headtemp) { my $parser = Mail::Box::Parser::Perl->new(filename => $headtemp, file => $head, trusted => 1); $reply_head->read($parser); $parser->close; } $args{quote} ||= delete $args{Inline} || '>'; $args{group_reply} ||= delete $args{ReplyAll} || 0; my $keep = delete $args{Keep} || []; my $exclude = delete $args{Exclude} || []; my $reply = $self->SUPER::reply(%args); my $head = $self->head; $reply_head->add($_->clone) for map $head->get($_), @$keep; $reply_head->reset($_) for @$exclude; (ref $self)->coerce($reply); } sub add_signature(;$) { my $self = shift; my $fn = shift // File::Spec->catfile($ENV{HOME} || File::Spec->curdir, '.signature'); $self->sign(File => $fn); } sub sign(@) { my ($self, $args) = @_; my $sig; if(my $filename = delete $self->{File}) { $sig = Mail::Message::Body->new(file => $filename); } elsif(my $sign = delete $self->{Signature}) { $sig = Mail::Message::Body->new(data => $sign); } defined $sig or return; my $body = $self->decoded->stripSignature; my $set = $body->concatenate($body, "-- \n", $sig); $self->body($set) if defined $set; $set; } #-------------------- sub send($@) { my ($self, $type, %args) = @_; $self->send(via => $type); } #-------------------- sub head(;$) { my $self = shift; return $self->SUPER::head(@_) if @_; $self->SUPER::head // $self->{MM_head_type}->new(message => $self); } sub header(;$) { shift->head->header(@_) } sub fold(;$) { shift->head->fold(@_) } sub fold_length(;$$) { shift->head->fold_length(@_) } sub combine($;$) { shift->head->combine(@_) } sub print_header(@) { shift->head->print(@_) } sub clean_header() { $_[0]->header } sub tidy_headers() { } sub add(@) { shift->head->add(@_) } sub replace(@) { shift->head->replace(@_) } sub get(@) { shift->head->get(@_) } sub delete(@) { my $self = shift; @_ ? $self->head->delete(@_) : $self->SUPER::delete; } #-------------------- sub body(@) { my $self = shift; unless(@_) { my $body = $self->body; return defined $body ? (scalar $body->lines) : []; } my $data = ref $_[0] eq 'ARRAY' ? shift : \@_; my $body = Mail::Message::Body::Lines->new(data => $data); $self->body($body); $body; } sub print_body(@) { shift->SUPER::body->print(@_) } sub bodyObject(;$) { shift->SUPER::body(@_) } sub remove_sig(;$) { my ($self, $lines) = @_; my $stripped = $self->decoded->stripSignature(max_lines => $lines // 10); $self->body($stripped) if defined $stripped; $stripped; } sub tidy_body(;$) { my $self = shift; my $body = $self->body or return; my @body = $body->lines; shift @body while @body && $body[ 0] =~ m/^\s*$/; pop @body while @body && $body[-1] =~ m/^\s*$/; return $body if $body->nrLines == @body; my $new = Mail::Message::Body::Lines->new(based_on => $body, data=>\@body); $self->body($new); } sub smtpsend(@) { my ($self, %args) = @_; my $from = $args{MailFrom} || $ENV{MAILADDRESS} || $ENV{USER} || 'unknown'; $args{helo} ||= delete $args{Hello}; $args{port} ||= delete $args{Port}; $args{smtp_debug} ||= delete $args{Debug}; my $host = $args{Host}; unless(defined $host) { my $hosts = $ENV{SMTPHOSTS}; $host = (split /\:/, $hosts)[0] if defined $hosts; } $args{host} = $host; $self->send(via => 'smtp', %args); } #-------------------- sub as_mbox_string() { my $self = shift; my $mboxmsg = Mail::Box::Mbox->coerce($self); my $buffer = ''; my $file = Mail::Box::FastScalar->new(\$buffer); $mboxmsg->print($file); $buffer; } #-------------------- BEGIN { no warnings; *Mail::Internet::new = sub (@) { my $class = shift; Mail::Message::Replace::MailInternet->new(@_); }; } sub isa($) { my ($thing, $class) = @_; $class eq 'Mail::Internet' ? 1 : $thing->SUPER::isa($class); } #-------------------- sub coerce() { $_[0]->notImplemented } 1; �������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Head.pod���������������������������������������������������������0000644�0001750�0000144�00000033512�15166136117�021020� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Head - the header of one message =head1 INHERITANCE Mail::Message::Head is a Mail::Reporter Mail::Message::Head is extended by Mail::Box::IMAP4::Head Mail::Message::Head::Complete Mail::Message::Head::Delayed Mail::Message::Head::Subset =head1 SYNOPSIS my $head = Mail::Message::Head->new; $head->add('From: me@localhost'); $head->add(From => 'me@localhost'); $head->add(Mail::Message::Field->new(From => 'me')); my $subject = $head->get('subject'); my @rec = $head->get('received'); $head->delete('From'); =head1 DESCRIPTION C<Mail::Message::Head> MIME headers are part of L<Mail::Message|Mail::Message> messages, which are grouped in L<Mail::Box|Mail::Box> folders. A long list of standard MIME header fields with definitions can be found in RFC4021 (L<https://www.rfc-editor.org/rfc/rfc4021.html>) and its updates RFC5322 and RFC6854. B<ATTENTION!!!> most functionality about e-mail headers is described in L<Mail::Message::Head::Complete|Mail::Message::Head::Complete>, which is a matured header object. Other kinds of headers will be translated to that type when time comes. On this page, the general methods which are available on any header are described. Read about differences in the sub-class specific pages. Extends L<"DESCRIPTION" in Mail::Reporter|Mail::Reporter/"DESCRIPTION">. =head1 OVERLOADED =over 4 =item overload: B<""> stringifaction The header, when used as string, will format as if L<Mail::Message::Head::Complete::string()|Mail::Message::Head::Complete/"Access to the header"> was called, so return a nicely folder full header. An exception is made for Carp, which will get a simplified string to avoid unreadible messages from C<croak> and C<confess>. » example: using a header object as string print $head; # implicit stringification by print $head->print; # the same print "$head"; # explicit stringication =item overload: B<bool> true/false When the header does not contain any lines (which is illegal, according to the RFCs), C<false> is returned. In all other cases, a C<true> value is produced. =back =head1 METHODS Extends L<"METHODS" in Mail::Reporter|Mail::Reporter/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Reporter|Mail::Reporter/"Constructors">. =over 4 =item $class-E<gt>B<build>( [PAIR|$field]-LIST ) A fast way to construct a header with many lines. The PAIRs are C<(name, content)> pairs of the header, but it is also possible to pass L<Mail::Message::Field|Mail::Message::Field> objects. A L<Mail::Message::Head::Complete|Mail::Message::Head::Complete> header is created by simply calling L<Mail::Message::Head::Complete::build()|Mail::Message::Head::Complete/"Constructors">, and then each field is added. Double field names are permitted. » example: my $subject = Mail::Message::Field->new(Subject => 'xyz'); my $head = Mail::Message::Head->build( From => 'me@example.com', To => 'you@anywhere.aq', $subject, Received => 'one', Received => 'two', ); print ref $head; # --> Mail::Message::Head::Complete =item $class-E<gt>B<new>(%options) Create a new message header object. The object will store all the fields of a header. When you get information from the header, it will be returned to you as L<Mail::Message::Field|Mail::Message::Field> objects, although the fields may be stored differently internally. If you try to instantiate a L<Mail::Message::Head|Mail::Message::Head>, you will automatically be upgraded to a L<Mail::Message::Head::Complete|Mail::Message::Head::Complete> --a full head. Improves base, see L<Mail::Reporter/"Constructors"> -Option --Default field_type Mail::Message::Field::Fast message undef modified false =over 2 =item field_type => CLASS The type of objects that all the fields will have. This must be an extension of L<Mail::Message::Field|Mail::Message::Field>. =item message => $message The C<$message> where this header belongs to. Usually, this is not known at creation of the header, but sometimes it is. If not, call the L<message()|Mail::Message::Head/"The header"> method later to set it. =item modified => BOOLEAN =back =back =head2 Attributes Extends L<"Attributes" in Mail::Reporter|Mail::Reporter/"Attributes">. =head2 The header =over 4 =item $obj-E<gt>B<isDelayed>() Headers may only be partially read, in which case they are called delayed. This method returns C<true> if some header information still needs to be read. Returns C<false> if all header data has been read. Will never trigger completion. =item $obj-E<gt>B<isEmpty>() Are there any fields defined in the current header? Be warned that the header will not be loaded for this: delayed headers will return C<true> in any case. =item $obj-E<gt>B<isModified>() Returns whether the header has been modified after being read. » example: if($head->isModified) { ... } =item $obj-E<gt>B<knownNames>() Like L<Mail::Message::Head::Complete::names()|Mail::Message::Head::Complete/"Access to the header">, but only returns the known header fields, which may be less than C<names> for header types which are partial. C<names()> will trigger completion, where C<knownNames()> does not. =item $obj-E<gt>B<message>( [$message] ) Get (after setting) the message where this header belongs to. This does not trigger completion. =item $obj-E<gt>B<modified>( [BOOLEAN] ) Sets the modified flag to C<BOOLEAN>. Without value, the current setting is returned, but in that case you can better use L<isModified()|Mail::Message::Head/"The header">. Changing this flag will not trigger header completion. » example: $head->modified(1); if($head->modified) { ... } if($head->isModified) { ... } =item $obj-E<gt>B<orderedFields>() Returns the fields ordered the way they were read or added. =back =head2 Access to the header =over 4 =item $obj-E<gt>B<get>( $name, [$index] ) Get the data which is related to the field with the C<$name>. The case of the characters in C<$name> does not matter. If there is only one data element defined for the C<$name>, or if there is an C<$index> specified as the second argument, only the specified element will be returned. If the field C<$name> matches more than one header the return value depends on the context. In LIST context, all values will be returned in the order they are read. In SCALAR context, only the last value will be returned. » example: my $head = Mail::Message::Head->new; $head->add('Received: abc'); $head->add('Received: xyz'); $head->add('Subject: greetings'); my @rec_list = $head->get('Received'); my $rec_scalar = $head->get('Received'); print ",@rec_list,$rec_scalar," # ,abc xyz, xyz, print $head->get('Received', 0); # abc my @sub_list = $head->get('Subject'); my $sub_scalar = $head->get('Subject'); print ",@sub_list,$sub_scalar," # ,greetings, greetings, =item $obj-E<gt>B<study>( $name, [$index] ) Like L<get()|Mail::Message::Head/"Access to the header">, but puts more effort in understanding the contents of the field. L<Mail::Message::Field::study()|Mail::Message::Field/"Access to the content"> will be called for the field with the specified FIELDNAME, which returns L<Mail::Message::Field::Full|Mail::Message::Field::Full> objects. In scalar context only the last field with that name is returned. When an C<$index> is specified, that element is returned. =back =head2 About the body =over 4 =item $obj-E<gt>B<guessBodySize>() Try to estimate the size of the body of this message, but without parsing the header or body. The result might be C<undef> or a few percent of the real size. It may even be very far of the real value, that's why this is a guess. =item $obj-E<gt>B<isMultipart>() Returns whether the body of the related message is a multipart body. May trigger completion, when the C<Content-Type> field is not defined. =back =head2 Internals =over 4 =item $obj-E<gt>B<addNoRealize>($field) Add a field, like L<Mail::Message::Head::Complete::add()|Mail::Message::Head::Complete/"Access to the header"> does, but avoid the loading of a possibly partial header. This method does not test the validity of the argument, nor flag the header as changed. This does not trigger completion. =item $obj-E<gt>B<addOrderedFields>($fields) Z<> =item $obj-E<gt>B<fileLocation>() Returns the location of the header in the file, as a pair begin and end. The begin is the first byte of the header. The end is the first byte after the header. =item $obj-E<gt>B<load>() Be sure that the header is loaded. This returns the loaded header object. =item $obj-E<gt>B<moveLocation>($distance) Move the registration of the header in the file. =item $obj-E<gt>B<read>($parser) Read the header information of one message into this header structure. This method is called by the folder object (some L<Mail::Box|Mail::Box> sub-class), which passes the C<$parser> as an argument. =item $obj-E<gt>B<setNoRealize>($field) Set a field, but avoid the loading of a possibly partial header as set() does. This method does not test the validity of the argument, nor flag the header as changed. This does not trigger completion. =back =head2 Error handling Extends L<"Error handling" in Mail::Reporter|Mail::Reporter/"Error handling">. =over 4 =item $obj-E<gt>B<AUTOLOAD>() Inherited, see L<Mail::Reporter/"Error handling"> =item $obj-E<gt>B<notImplemented>() Inherited, see L<Mail::Reporter/"Error handling"> =back =head2 Cleanup Extends L<"Cleanup" in Mail::Reporter|Mail::Reporter/"Cleanup">. =over 4 =item $obj-E<gt>B<DESTROY>() Inherited, see L<Mail::Reporter/"Cleanup"> =back =head1 DETAILS =head2 Ordered header fields Many Perl implementations make a big mistake by disturbing the order of header fields. For some fields (especially the I<resent groups>, see L<Mail::Message::Head::ResentGroup|Mail::Message::Head::ResentGroup>) the order shall be maintained. MailBox will keep the order of the fields as they were found in the source. When your add a new field, it will be added at the end. If your replace a field with a new value, it will stay in the original order. =head2 Head class implementation The header of a MIME message object contains a set of lines, which are called I<fields> (by default represented by L<Mail::Message::Field|Mail::Message::Field> objects). Dependent on the situation, the knowledge about the fields can be in one of three situations, each represented by a sub-class of this module: =over 4 =item * L<Mail::Message::Head::Complete|Mail::Message::Head::Complete> In this case, it is sure that all knowledge about the header is available. When you L<get()|Mail::Message::Head/"Access to the header"> information from the header and it is not there, it will never be there. =item * L<Mail::Message::Head::Subset|Mail::Message::Head::Subset> There is no certainty whether all header lines are known (probably not). This may be caused as result of reading a fast index file, as described in L<Mail::Box::MH::Index|Mail::Box::MH::Index>. The object is automatically transformed into a L<Mail::Message::Head::Complete|Mail::Message::Head::Complete> when all header lines must be known. =item * L<Mail::Message::Head::Partial|Mail::Message::Head::Partial> A partial header is like a subset header: probably the header is incomplete. The means that you are not sure whether a L<get()|Mail::Message::Head/"Access to the header"> for a field fails because the field is not a part of the message or that it fails because it is not yet known to the program. Where the subset header knows where to get the other fields, the partial header does not know it. It cannot hide its imperfection. =item * L<Mail::Message::Head::Delayed|Mail::Message::Head::Delayed> In this case, there is no single field known. Access to this header will always trigger the loading of the full header. =back =head2 Subsets of header fields Message headers can be quite large, and therefore MailBox provides simplified access to some subsets of information. You can grab these sets of fields together, create and delete them as group. On the moment, the following sets are defined: =over 4 =item * L<Mail::Message::Head::ResentGroup|Mail::Message::Head::ResentGroup> A I<resent group> is a set of fields which is used to log one step in the transmission of the message from the original sender to the destination. Each step adds a set of headers to indicate when the message was received and how it was forwarded (without modification). These fields are best created using L<Mail::Message::bounce()|Mail::Message::Construct::Bounce/"Constructing a message">. =item * L<Mail::Message::Head::ListGroup|Mail::Message::Head::ListGroup> Fields which are used to administer and log mailing list activity. Mailing list software has to play trics with the original message to be able to get the reply on that message back to the mailing list. Usually a large number of lines are added. =item * L<Mail::Message::Head::SpamGroup|Mail::Message::Head::SpamGroup> A set of fields which contains header fields which are produced by spam detection software. You may want to remove these fields when you store a message for a longer period of time. =back =head1 DIAGNOSTICS =over 4 =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Part.pod���������������������������������������������������������0000644�0001750�0000144�00000037324�15166136120�021064� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Part - a part of a message, but a message by itself =head1 INHERITANCE Mail::Message::Part is a Mail::Message is a Mail::Reporter =head1 SYNOPSIS my Mail::Message $message = ...; if($message->isMultipart) { my Mail::Message::Part $part; foreach $part ($message->body->parts) { $part->print(\*OUT); my $attached_head = $part->head; my $attached_body = $part->body; # encoded as read my $attached_body = $part->decoded; # transfer-encoding removed } } =head1 DESCRIPTION A C<Mail::Message::Part> object contains a message which is included in the body of another message. For instance I<attachments> are I<parts>. READ L<Mail::Message|Mail::Message> FIRST. A part is a special message: it has a reference to its parent message, and will usually not be sub-classed into mail folder specific variants. Extends L<"DESCRIPTION" in Mail::Message|Mail::Message/"DESCRIPTION">. =head1 METHODS Extends L<"METHODS" in Mail::Message|Mail::Message/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Message|Mail::Message/"Constructors">. =over 4 =item $obj-E<gt>B<clone>(%options) Inherited, see L<Mail::Message/"Constructors"> =item $class-E<gt>B<new>(%options) Create a message part. Improves base, see L<Mail::Reporter/"Constructors"> -Option --Defined in --Default body Mail::Message undef body_type Mail::Message Mail::Message::Body::Lines container <required> deleted Mail::Message false field_type Mail::Message undef head Mail::Message <empty header> head_type Mail::Message Mail::Message::Head::Complete labels Mail::Message +{} messageId Mail::Message undef message_id Mail::Message undef modified Mail::Message false trusted Mail::Message false =over 2 =item body => $object =item body_type => $class =item container => BODY Reference to the parental L<Mail::Message::Body|Mail::Message::Body> object where this part is a member of. That object may be a L<Mail::Message::Body::Multipart|Mail::Message::Body::Multipart> or a L<Mail::Message::Body::Nested|Mail::Message::Body::Nested>. =item deleted => BOOLEAN =item field_type => $class =item head => $object =item head_type => $class =item labels => \@pairs|\%settings =item messageId => $id =item message_id => $id =item modified => BOOLEAN =item trusted => BOOLEAN =back =back =head2 Attributes Extends L<"Attributes" in Mail::Message|Mail::Message/"Attributes">. =over 4 =item $obj-E<gt>B<bodyType>() Inherited, see L<Mail::Message/"Attributes"> =item $obj-E<gt>B<fieldType>() Inherited, see L<Mail::Message/"Attributes"> =item $obj-E<gt>B<headType>() Inherited, see L<Mail::Message/"Attributes"> =item $obj-E<gt>B<messageId>() Inherited, see L<Mail::Message/"Attributes"> =back =head2 Constructing a message Extends L<"Constructing a message" in Mail::Message|Mail::Message/"Constructing a message">. =over 4 =item $obj-E<gt>B<bounce>( [<$rg_object|%options>] ) Inherited, see L<Mail::Message::Construct::Bounce/"Constructing a message"> =item $class-E<gt>B<build>( [$message|$part|$body], @fields, %options ) Inherited, see L<Mail::Message::Construct::Build/"Constructing a message"> =item $class-E<gt>B<buildFromBody>($body, $container, $headers) Shape a message part around a C<$body>. Bodies have information about their content in them, which is used to construct a header for the message. Next to that, more C<$headers> can be specified. No headers are obligatory. No extra headers are fabricated automatically. Improves base, see L<Mail::Message::Construct::Build/"Constructing a message"> » example: my $multi = Mail::Message::Body::Multipart->new; my $part = Mail::Message::Part->buildFromBody($body, $multi); =item $obj-E<gt>B<forward>(%options) Inherited, see L<Mail::Message::Construct::Forward/"Constructing a message"> =item $obj-E<gt>B<forwardAttach>(%options) Inherited, see L<Mail::Message::Construct::Forward/"Constructing a message"> =item $obj-E<gt>B<forwardEncapsulate>(%options) Inherited, see L<Mail::Message::Construct::Forward/"Constructing a message"> =item $obj-E<gt>B<forwardInline>(%options) Inherited, see L<Mail::Message::Construct::Forward/"Constructing a message"> =item $obj-E<gt>B<forwardNo>(%options) Inherited, see L<Mail::Message::Construct::Forward/"Constructing a message"> =item $obj-E<gt>B<forwardPostlude>() Inherited, see L<Mail::Message::Construct::Forward/"Constructing a message"> =item $obj-E<gt>B<forwardPrelude>() Inherited, see L<Mail::Message::Construct::Forward/"Constructing a message"> =item $obj-E<gt>B<forwardSubject>(STRING) Inherited, see L<Mail::Message::Construct::Forward/"Constructing a message"> =item $class-E<gt>B<read>($fh|$text|\$text|\@lines, %options) Inherited, see L<Mail::Message::Construct::Read/"Constructing a message"> =item $obj-E<gt>B<rebuild>(%options) Inherited, see L<Mail::Message::Construct::Rebuild/"Constructing a message"> =item $obj-E<gt>B<reply>(%options) Inherited, see L<Mail::Message::Construct::Reply/"Constructing a message"> =item $obj-E<gt>B<replyPrelude>( [STRING|$field|$address|\@addrs|\@fields] ) Inherited, see L<Mail::Message::Construct::Reply/"Constructing a message"> =item $any-E<gt>B<replySubject>(STRING) Inherited, see L<Mail::Message::Construct::Reply/"Constructing a message"> =back =head2 The message Extends L<"The message" in Mail::Message|Mail::Message/"The message">. =over 4 =item $obj-E<gt>B<container>() Inherited, see L<Mail::Message/"The message"> =item $obj-E<gt>B<endsOnNewline>() Inherited, see L<Mail::Message/"The message"> =item $obj-E<gt>B<isDummy>() Inherited, see L<Mail::Message/"The message"> =item $obj-E<gt>B<isPart>() Inherited, see L<Mail::Message/"The message"> =item $obj-E<gt>B<partNumber>() Inherited, see L<Mail::Message/"The message"> =item $obj-E<gt>B<print>( [$fh] ) Inherited, see L<Mail::Message/"The message"> =item $obj-E<gt>B<printEscapedFrom>($fh) Prints the message part, but all lines which start with 'From ' will get a leading E<gt>. See L<Mail::Message::Body::printEscapedFrom()|Mail::Message::Body/"Access to the payload">. =item $obj-E<gt>B<send>( [$mailer], %options ) Inherited, see L<Mail::Message/"The message"> =item $obj-E<gt>B<size>() Inherited, see L<Mail::Message/"The message"> =item $obj-E<gt>B<toplevel>() Inherited, see L<Mail::Message/"The message"> =item $obj-E<gt>B<write>( [$fh] ) Inherited, see L<Mail::Message/"The message"> =back =head2 The header Extends L<"The header" in Mail::Message|Mail::Message/"The header">. =over 4 =item $obj-E<gt>B<bcc>() Inherited, see L<Mail::Message/"The header"> =item $obj-E<gt>B<cc>() Inherited, see L<Mail::Message/"The header"> =item $obj-E<gt>B<date>() Inherited, see L<Mail::Message/"The header"> =item $obj-E<gt>B<destinations>() Inherited, see L<Mail::Message/"The header"> =item $obj-E<gt>B<from>() Inherited, see L<Mail::Message/"The header"> =item $obj-E<gt>B<get>($fieldname) Inherited, see L<Mail::Message/"The header"> =item $obj-E<gt>B<guessTimestamp>() Inherited, see L<Mail::Message/"The header"> =item $obj-E<gt>B<head>( [$head] ) Inherited, see L<Mail::Message/"The header"> =item $obj-E<gt>B<nrLines>() Inherited, see L<Mail::Message/"The header"> =item $obj-E<gt>B<sender>() Inherited, see L<Mail::Message/"The header"> =item $obj-E<gt>B<study>($fieldname) Inherited, see L<Mail::Message/"The header"> =item $obj-E<gt>B<subject>() Inherited, see L<Mail::Message/"The header"> =item $obj-E<gt>B<timestamp>() Inherited, see L<Mail::Message/"The header"> =item $obj-E<gt>B<to>() Inherited, see L<Mail::Message/"The header"> =back =head2 The body Extends L<"The body" in Mail::Message|Mail::Message/"The body">. =over 4 =item $obj-E<gt>B<body>( [$body] ) Inherited, see L<Mail::Message/"The body"> =item $obj-E<gt>B<contentType>() Inherited, see L<Mail::Message/"The body"> =item $obj-E<gt>B<decoded>(%options) Inherited, see L<Mail::Message/"The body"> =item $obj-E<gt>B<encode>(%options) Inherited, see L<Mail::Message/"The body"> =item $obj-E<gt>B<isMultipart>() Inherited, see L<Mail::Message/"The body"> =item $obj-E<gt>B<isNested>() Inherited, see L<Mail::Message/"The body"> =item $obj-E<gt>B<parts>( [<'ALL'|'ACTIVE'|'DELETED'|'RECURSE'|$filter>] ) Inherited, see L<Mail::Message/"The body"> =back =head2 Flags Extends L<"Flags" in Mail::Message|Mail::Message/"Flags">. =over 4 =item $obj-E<gt>B<delete>() Inherited, see L<Mail::Message/"Flags"> =item $obj-E<gt>B<deleted>( [BOOLEAN] ) Inherited, see L<Mail::Message/"Flags"> =item $obj-E<gt>B<isDeleted>() Inherited, see L<Mail::Message/"Flags"> =item $obj-E<gt>B<isModified>() Inherited, see L<Mail::Message/"Flags"> =item $obj-E<gt>B<label>($label|PAIRS) Inherited, see L<Mail::Message/"Flags"> =item $obj-E<gt>B<labels>() Inherited, see L<Mail::Message/"Flags"> =item $obj-E<gt>B<labelsToStatus>() Inherited, see L<Mail::Message/"Flags"> =item $obj-E<gt>B<modified>( [BOOLEAN] ) Inherited, see L<Mail::Message/"Flags"> =item $obj-E<gt>B<statusToLabels>() Inherited, see L<Mail::Message/"Flags"> =back =head2 The whole message as text Extends L<"The whole message as text" in Mail::Message|Mail::Message/"The whole message as text">. =over 4 =item $obj-E<gt>B<file>() Inherited, see L<Mail::Message::Construct::Text/"The whole message as text"> =item $obj-E<gt>B<lines>() Inherited, see L<Mail::Message::Construct::Text/"The whole message as text"> =item $obj-E<gt>B<printStructure>( [$fh|undef],[$indent] ) Inherited, see L<Mail::Message::Construct::Text/"The whole message as text"> =item $obj-E<gt>B<string>() Inherited, see L<Mail::Message::Construct::Text/"The whole message as text"> =back =head2 Internals Extends L<"Internals" in Mail::Message|Mail::Message/"Internals">. =over 4 =item $obj-E<gt>B<clonedFrom>() Inherited, see L<Mail::Message/"Internals"> =item $class-E<gt>B<coerce>( <$body|$message>, $multipart, @headers ) Transforms a C<$body> or C<$message> to a real message part. The C<$multipart> refers to the parental body. When a C<$body> is specified, extra C<@headers> can be supplied as well. Bodies are coerced into message parts by calling L<buildFromBody()|Mail::Message::Part/"METHODS">. If you specify a C<$message> residing in a folder, this message will automatically be cloned. Improves base, see L<Mail::Message/"Internals"> =item $obj-E<gt>B<isDelayed>() Inherited, see L<Mail::Message/"Internals"> =item $obj-E<gt>B<isTrusted>() Inherited, see L<Mail::Message/"Internals"> =item $obj-E<gt>B<readBody>( $parser, $head, [$bodytype] ) Inherited, see L<Mail::Message/"Internals"> =item $obj-E<gt>B<readFromParser>( $parser, [$bodytype] ) Inherited, see L<Mail::Message/"Internals"> =item $obj-E<gt>B<readHead>( $parser, [$class] ) Inherited, see L<Mail::Message/"Internals"> =item $obj-E<gt>B<recursiveRebuildPart>($part, %options) Inherited, see L<Mail::Message::Construct::Rebuild/"Internals"> =item $obj-E<gt>B<storeBody>($body) Inherited, see L<Mail::Message/"Internals"> =item $obj-E<gt>B<takeMessageId>( [STRING] ) Inherited, see L<Mail::Message/"Internals"> =back =head2 Error handling Extends L<"Error handling" in Mail::Message|Mail::Message/"Error handling">. =over 4 =item $obj-E<gt>B<AUTOLOAD>() Inherited, see L<Mail::Message::Construct/"METHODS"> =item $obj-E<gt>B<notImplemented>() Inherited, see L<Mail::Reporter/"Error handling"> =item $any-E<gt>B<shortSize>( [$value] ) Inherited, see L<Mail::Message/"Error handling"> =item $obj-E<gt>B<shortString>() Inherited, see L<Mail::Message/"Error handling"> =back =head2 Cleanup Extends L<"Cleanup" in Mail::Message|Mail::Message/"Cleanup">. =over 4 =item $obj-E<gt>B<DESTROY>() Inherited, see L<Mail::Reporter/"Cleanup"> =item $obj-E<gt>B<destruct>() Message parts can not be destructed per part: only whole messages can be forcefully freed from memory. Of course, you can L<delete()|Mail::Message/"Flags"> separate parts, which only sets a flag not to write a part again. Furthermore, you may cosider L<rebuild()|Mail::Message::Construct::Rebuild/"Constructing a message"> to get rit of deleted parts. Improves base, see L<Mail::Message/"Cleanup"> =back =head1 DETAILS Extends L<"DETAILS" in Mail::Message|Mail::Message/"DETAILS">. =head1 DIAGNOSTICS =over 4 =item Error: Cannot include forward source as $kind. Unknown alternative for the L<forward(include)|Mail::Message::Construct::Forward/"Constructing a message">. Valid choices are C<NO>, C<INLINE>, C<ATTACH>, and C<ENCAPSULATE>. Cast by C<forward()> =item Error: No default mailer found to send message. The message L<send()|Mail::Message/"The message"> mechanism had not enough information to automatically find a mail transfer agent to sent this message. Specify a mailer explicitly using the C<via> options. Cast by C<send()> =item Error: cannot include reply source as $kind. Unknown alternative for the C<include> option of L<reply()|Mail::Message::Construct::Reply/"Constructing a message">. Valid choices are C<NO>, C<INLINE>, and C<ATTACH>. Cast by C<reply()> =item Error: cannot read message from a $source. Cast by C<read()> =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =item Error: method bounce requires To, Cc, or Bcc. The message L<bounce()|Mail::Message::Construct::Bounce/"Constructing a message"> method forwards a received message off to someone else without modification; you must specified it's new destination. If you have the urge not to specify any destination, you probably are looking for L<reply()|Mail::Message::Construct::Reply/"Constructing a message">. When you wish to modify the content, use L<forward()|Mail::Message::Construct::Forward/"Constructing a message">. Cast by C<bounce()> =item Error: method forwardAttach requires a preamble. Cast by C<forwardAttach()> =item Error: method forwardEncapsulate requires a preamble. Cast by C<forwardEncapsulate()> =item Error: method forwardNo requires a To. Cast by C<forwardNo()> =item Error: method forwardNo requires a body. Cast by C<forwardNo()> =item Error: no container specified for part. Cast by C<new()> =item Error: no rebuild rule $name defined. Cast by C<rebuild()> =item Error: only build() Mail::Message's; they are not in a folder yet. You may wish to construct a message to be stored in a some kind of folder, but you need to do that in two steps. First, create a normal L<Mail::Message|Mail::Message>, and then add it to the folder. During this L<Mail::Box::addMessage()|Mail::Box/"The folder"> process, the message will get L<coerce()|Mail::Message::Part/"METHODS">-d into the right message type, adding storage information and the like. Cast by C<build()> =item Error: select parts via '$what'? Cast by C<parts()> =item Warning: skipped unknown key '$key' in build. Cast by C<build()> =item Error: you cannot destruct message parts, only whole messages. Message parts can not be destructed per part: only whole messages can be forcefully freed from memory. Consider L<delete()|Mail::Message/"Flags"> or L<rebuild()|Mail::Message::Construct::Rebuild/"Constructing a message">. Cast by C<destruct()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Convert.pm�������������������������������������������������������0000644�0001750�0000144�00000001655�15166136116�021433� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::Convert;{ our $VERSION = '4.05'; } use parent 'Mail::Reporter'; use strict; use warnings; use Log::Report 'mail-message', import => [ qw// ]; #-------------------- sub init($) { my ($self, $args) = @_; $self->SUPER::init($args); $self->{MMC_fields} = $args->{fields} || qr#^(Resent\-)?(To|From|Cc|Bcc|Subject|Date)\b#i; $self; } #-------------------- sub selectedFields($) { my ($self, $head) = @_; $head->grepNames($self->{MMC_fields}); } #-------------------- 1; �����������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Field.pm���������������������������������������������������������0000644�0001750�0000144�00000024557�15166136117�021045� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::Field;{ our $VERSION = '4.05'; } use parent 'Mail::Reporter'; use strict; use warnings; use Log::Report 'mail-message', import => [ qw/__x error info panic warning/ ]; use Mail::Address (); use IO::Handle (); use Date::Format qw/strftime/; use Scalar::Util qw/blessed/; use Hash::Case::Preserve (); our %_structured; # not to be used directly: call isStructured! my $default_wrap_length = 78; use overload qq("") => sub { $_[0]->unfoldedBody }, '0+' => sub { $_[0]->toInt || 0 }, bool => sub {1}, cmp => sub { $_[0]->unfoldedBody cmp "$_[1]" }, '<=>' => sub { $_[2] ? $_[1] <=> $_[0]->toInt : $_[0]->toInt <=> $_[1] }, fallback => 1; #-------------------- sub new(@) { my $class = shift; if($class eq __PACKAGE__) # bootstrap { require Mail::Message::Field::Fast; return Mail::Message::Field::Fast->new(@_); } $class->SUPER::new(@_); } #-------------------- # attempt to change the case of a tag to that required by RFC822. That # being all characters are lowercase except the first of each # word. Also if the word is an `acronym' then all characters are # uppercase. We, rather arbitrarily, decide that a word is an acronym # if it does not contain a vowel and isn't the well-known 'Cc' or # 'Bcc' headers. my %wf_lookup = qw/mime MIME ldap LDAP soap SOAP swe SWE bcc Bcc cc Cc id ID/; sub wellformedName(;$) { my $thing = shift; my $name = @_ ? shift : $thing->name; join '-', map { $wf_lookup{lc $_} || ( /[aeiouyAEIOUY]/ ? ucfirst lc : uc ) } split /\-/, $name, -1; } sub folded { $_[0]->notImplemented } sub body() { my $self = shift; my $body = $self->unfoldedBody; $self->isStructured or return $body; my ($first) = $body =~ m/^((?:"[^"]*"|'[^']*'|[^;])*)/; $first =~ s/\s+$//r; } sub foldedBody { $_[0]->notImplemented } sub unfoldedBody { $_[0]->notImplemented } #-------------------- sub length { length $_[0]->folded } BEGIN { %_structured = map +(lc($_) => 1), qw/ To Cc Bcc From Date Reply-To Sender Resent-Date Resent-From Resent-Sender Resent-To Return-Path List-Help List-Post List-Unsubscribe Mailing-List Received References Message-ID In-Reply-To Delivered-To Content-Type Content-Disposition Content-ID MIME-Version Precedence Status /; } sub isStructured(;$) { my $name = $_[1] // (blessed $_[0] ? $_[0]->name : panic); exists $_structured{lc $name}; } sub print(;$) { my $self = shift; my $fh = shift || select; $fh->print(scalar $self->folded); } sub toString(;$) { shift->string(@_) } sub string(;$) { my $self = shift; return $self->folded unless @_; my $wrap = shift || $default_wrap_length; my $name = $self->Name; my @lines = $self->fold($name, $self->unfoldedBody, $wrap); $lines[0] = $name . ':' . $lines[0]; wantarray ? @lines : join('', @lines); } sub toDisclose() { $_[0]->name !~ m! ^ (?: (?:x-)?status | (?:resent-)?bcc | content-length | x-spam- ) $ !x; } sub nrLines() { my @l = $_[0]->foldedBody; scalar @l } *size = \&length; #-------------------- sub stripCFWS($) { my $thing = shift; # get (folded) data my $string = @_ ? shift : $thing->foldedBody; # remove comments my $r = ''; my $in_dquotes = 0; my $open_paren = 0; my @s = split m/([()"])/, $string; while(@s) { my $s = shift @s; if(CORE::length($r)&& substr($r, -1) eq "\\") { $r .= $s } elsif($s eq '"') { $in_dquotes = not $in_dquotes; $r .= $s } elsif($s eq '(' && !$in_dquotes) { $open_paren++ } elsif($s eq ')' && !$in_dquotes) { $open_paren-- } elsif($open_paren) {} # in comment else { $r .= $s } } # beautify and unfold at the same time $r =~ s/\s+/ /grs =~ s/\s+$//r =~ s/^\s+//r; } sub comment(;$) { my $self = shift; $self->isStructured or return undef; my $body = $self->unfoldedBody; if(@_) { my $comment = shift; $body =~ s/\s*\;.*//; $body .= "; $comment" if defined $comment && CORE::length($comment); $self->unfoldedBody($body); return $comment; } $body =~ s/.*?\;\s*// ? $body : ''; } sub content() { shift->unfoldedBody } # Compatibility sub attribute($;$) { my ($self, $attr) = (shift, shift); # Although each attribute can appear only once, some (intentionally) # broken messages do repeat them. See github issue 20. Apple Mail and # Outlook will take the last of the repeated in such case, so we do that # as well. tie my %attrs, 'Hash::Case::Preserve', [ $self->attributes ]; @_ or return $attrs{$attr}; # set the value my $value = shift; my $body = $self->unfoldedBody; unless(defined $value) # remove attribute { for($body) { s/\b$attr\s*=\s*"(?>[^\\"]|\\.)*"//i or s/\b$attr\s*=\s*[;\s]*//i; } $self->unfoldedBody($body); return undef; } my $quoted = $value =~ s/(["\\])/\\$1/gr; for($body) { s/\b$attr\s*=\s*"(?>[^\\"]|\\.){0,1000}"/$attr="$quoted"/i or s/\b$attr\s*=\s*[^;\s]*/$attr="$quoted"/i or do { $_ .= qq(; $attr="$quoted") } } $self->unfoldedBody($body); $value; } sub attributes() { my $self = shift; my $body = $self->unfoldedBody; my @attrs; while($body =~ m/ \b(\w+)\s*\=\s* ( "( (?: [^"]|\\" )* )" | '( (?: [^']|\\' )* )' | ([^;\s]*) ) /xig) { push @attrs, $1 => $+; } @attrs; } sub toInt() { my $self = shift; $self->body =~ m/^\s*(\d+)\s*$/ and return $1; warning __x"field content is not numerical: {content}", content => $self->toString; undef; } my @weekday = qw/Sun Mon Tue Wed Thu Fri Sat Sun/; my @month = qw/Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec/; sub toDate(@) { my $class = shift; my @time = @_== 0 ? localtime() : @_==1 ? localtime(shift) : @_; my $format = "$weekday[$time[6]], %d $month[$time[4]] %Y %H:%M:%S %z"; my $time = strftime $format, @time; # for C libs which do not (GNU compliantly) support %z $time =~ s/ (\%z|[A-Za-z ]+)$/_tz_offset($1)/re; } sub _tz_offset($) { my $zone = shift; require Time::Zone; my $diff = $zone eq '%z' ? Time::Zone::tz_local_offset() : Time::Zone::tz_offset($zone); my $minutes = int((abs($diff)+0.01) / 60); # float rounding errors my $hours = int(($minutes+0.01) / 60); $minutes -= $hours * 60; sprintf +($diff < 0 ? " -%02d%02d" : " +%02d%02d"), $hours, $minutes; } sub addresses() { Mail::Address->parse(shift->unfoldedBody) } sub study() { my $self = shift; require Mail::Message::Field::Full; Mail::Message::Field::Full->new(scalar $self->folded); } sub dateToTimestamp($) { my $string = $_[0]->stripCFWS($_[1]); # in RFC822, FWSes can appear within the time. $string =~ s/(\d\d)\s*\:\s*(\d\d)\s*\:\s*(\d\d)/$1:$2:$3/; require Date::Parse; Date::Parse::str2time($string, 'GMT'); } #-------------------- sub consume($;$) { my $self = shift; my ($name, $body) = defined $_[1] ? @_ : split(/\s*\:\s*/, (shift), 2); $name !~ m/[^\041-\071\073-\176]/ or warning __x"illegal character in field name '{name}'.", name => $name; panic $name if $name =~ m/[^\041-\071\073-\176]/; # # Compose the body. # if(ref $body) # Objects or array { my $flat = $self->stringifyData($body) // return (); $body = $self->fold($name, $flat); } elsif($body !~ s/\n+$/\n/g) # Added by user... { $body = $self->fold($name, $body); } else # Created by parser { # correct erroneous wrap-seperators (dos files under UNIX) $body =~ s/[\012\015]+/\n/g; $body =~ s/^[ \t]*/ /; # start with one blank, folding kept unchanged } ($name, $body); } sub stringifyData($) { my ($self, $arg) = (shift, shift); my @addr; foreach my $obj (ref $arg eq 'ARRAY' ? @$arg : ($arg)) { defined $obj or next; if(!ref $obj) { push @addr, $obj; next } if($obj->isa('Mail::Address')) { push @addr, $obj->format; next } if($obj->isa('Mail::Identity') || $obj->isa('User::Identity')) { require Mail::Message::Field::Address; push @addr, Mail::Message::Field::Address->coerce($obj)->string; } elsif($obj->isa('User::Identity::Collection::Emails')) { my @roles = $obj->roles or next; require Mail::Message::Field::AddrGroup; my $group = Mail::Message::Field::AddrGroup->coerce($obj); push @addr, $group->string if $group; } elsif($obj->isa('Mail::Message::Field')) { my $folded = join ' ', $obj->foldedBody; push @addr, $folded =~ s/^ //r =~ s/\n\z//r; } else { push @addr, "$obj"; # any other object is stringified } } @addr ? join(', ',@addr) : undef; } sub setWrapLength(;$) { my $self = shift; $self->foldedBody(scalar $self->fold($self->Name, $self->unfoldedBody, $_[0])) if @_; $self; } sub defaultWrapLength(;$) { my $self = shift; @_ ? ($default_wrap_length = shift) : $default_wrap_length; } sub fold($$;$) { my $thing = shift; my $name = shift; my $line = shift; my $wrap = shift || $default_wrap_length; $line //= ''; $line =~ s/\n(\s?)/$1/gms; # Remove accidental folding CORE::length($line) or return " \n"; # empty field my $lname = CORE::length($name); $lname <= $wrap -5 # Cannot find a real limit in the spec or error __x"field name too long (max {count}), in '{name}'.", count => $wrap - 5, name => $name; my @folded; while(1) { my $max = $wrap - (@folded ? 1 : $lname + 2); my $min = $max >> 2; last if CORE::length($line) < $max; # First, with try to get a block which ends on a ; or , to keep attributes # on the same line. Only then we fold on any blank. $line =~ s/^ ( .{$min,$max} # some text [;,] # followed at a ; or , )[ \t] # and then a WSP //x || $line =~ s/^ ( .{$min,$max} # some text )[ \t] # and then a WSP //x || $line =~ s/^ ( .{$max,}? ) # longer, but minimal chars [ \t] # followed by a WSP //x || $line =~ s/^ (.*) //sx; # everything push @folded, " $1\n"; } push @folded, " $line\n" if CORE::length($line); wantarray ? @folded : join('', @folded); } sub unfold($) { my $string = $_[1]; for($string) { s/\r?\n(\s)/$1/gs; # remove FWS s/\r?\n/ /gs; s/^\s+//; s/\s+$//; } $string; } #-------------------- 1; �������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Field.pod��������������������������������������������������������0000644�0001750�0000144�00000072460�15166136117�021207� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������=encoding utf8 =head1 NAME Mail::Message::Field - one line of a message header =head1 INHERITANCE Mail::Message::Field is a Mail::Reporter Mail::Message::Field is extended by Mail::Message::Field::Fast Mail::Message::Field::Flex Mail::Message::Field::Full =head1 SYNOPSIS my $field = Mail::Message::Field->new(From => 'fish@tux.aq'); print $field->name; print $field->body; print $field->comment; print $field->content; # body & comment $field->print(\*OUT); print $field->string; print "$field\n"; print $field->attribute('charset') || 'us-ascii'; =head1 DESCRIPTION This implementation follows the guidelines of rfc2822 as close as possible, and may there produce a different output than implementations based on the obsolete rfc822. However, the old output will still be accepted. These objects each store one header line, and facilitates access routines to the information hidden in it. Also, you may want to have a look at the added methods of a message: my @from = $message->from; my $sender = $message->sender; my $subject = $message->subject; my $msgid = $message->messageId; my @to = $message->to; my @cc = $message->cc; my @bcc = $message->bcc; my @dest = $message->destinations; my $other = $message->get('Reply-To'); Extends L<"DESCRIPTION" in Mail::Reporter|Mail::Reporter/"DESCRIPTION">. =head1 OVERLOADED =over 4 =item overload: B<'""'> stringification Produces the unfolded body of the field, which may be what you expect. This is what makes what the field object seems to be a simple string. The string is produced by L<unfoldedBody()|Mail::Message::Field/"Attributes">. » example: print $msg->get('subject'); # via overloading print $msg->get('subject')->unfoldedBody; # same my $subject = $msg->get('subject') || 'your mail'; print "Re: $subject\n"; =item overload: B<'0+'> numification When the field is numeric, the value will be returned. The result is produced by L<toInt()|Mail::Message::Field/"Access to the content">. If the value is not correct, a C<0> is produced, to simplify calculations. =item overload: B<'<=>'> numeric comparison Compare the integer field contents with something else. » example: if($msg->get('Content-Length') > 10000) ... if($msg->size > 10000) ... ; # same, but better =item overload: B<bool> boolean Always C<true>, to make it possible to say C<if($field)>. =item overload: B<cmp> string comparison Compare the unfolded body of a field with another field or a string, using the buildin C<cmp>. =back =head1 METHODS Extends L<"METHODS" in Mail::Reporter|Mail::Reporter/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Reporter|Mail::Reporter/"Constructors">. =over 4 =item $obj-E<gt>B<clone>() Create a copy of this field object. =item $class-E<gt>B<new>($data) See L<Mail::Message::Field::Fast::new()|Mail::Message::Field::Fast/"METHODS">, L<Mail::Message::Field::Flex::new()|Mail::Message::Field::Flex/"METHODS">, and L<Mail::Message::Field::Full::new()|Mail::Message::Field::Full/"METHODS">. By default, a C<Fast> field is produced. Improves base, see L<Mail::Reporter/"Constructors"> =back =head2 Attributes Extends L<"Attributes" in Mail::Reporter|Mail::Reporter/"Attributes">. =over 4 =item $obj-E<gt>B<Name>() Returns the name of this field in original casing. See L<name()|Mail::Message::Field/"Attributes"> as well. =item $obj-E<gt>B<body>() This method may not be what you want: the L<foldedBody()|Mail::Message::Field/"Attributes"> and L<unfoldedBody()|Mail::Message::Field/"Attributes"> are probably where you are looking for. Those will return the full content of a field, even when it is structured. Returns the body of the field. When this field is structured, it will be B<stripped> from everything what is behind the first semi-color (C<;>). In any case, the string is unfolded. Whether the field is structured is defined by L<isStructured()|Mail::Message::Field/"The field">. =item $obj-E<gt>B<folded>() Returns the folded version of the whole header. When the header is shorter than the wrap length, a list of one line is returned. Otherwise more lines will be returned, all but the first starting with at least one blank. See also L<foldedBody()|Mail::Message::Field/"Attributes"> to get the same information without the field's name. In scalar context, the lines are delived into one string, which is a little faster because that's the way they are stored internally... » example: my @lines = $field->folded; print $field->folded; print scalar $field->folded; # faster =item $obj-E<gt>B<foldedBody>( [$body] ) Returns the body as a set of lines. In scalar context, this will be one line containing newlines. Be warned about the newlines when you do pattern matching on the result of this method. The optional C<$body> argument changes the field's body. The folding of the argument must be correct. =item $obj-E<gt>B<name>() Returns the name of this field, with all characters lower-cased for ease of comparison. See L<Name()|Mail::Message::Field/"Attributes"> as well. =item $obj-E<gt>B<unfoldedBody>( [$body, [$wrap]] ) Returns the body as one single line, where all folding information (if available) is removed. This line will also NOT end on a new-line. The optional C<$body> argument changes the field's body. The right folding is performed before assignment. The C<$wrap> may be specified to enforce a folding size. » example: my $body = $field->unfoldedBody; print "$field"; # via overloading =item $obj-E<gt>B<wellformedName>( [STRING] ) (Instance method class method) As instance method, the current field's name is correctly formatted and returned. When a C<STRING> is used, that one is formatted. » example: print Mail::Message::Field->Name('content-type') # --> Content-Type my $field = $head->get('date'); print $field->Name; # --> Date =back =head2 The field =over 4 =item $any-E<gt>B<isStructured>( [$name] ) Some fields are described in the RFCs as being I<structured>: having a well described syntax. These fields have common ideas about comments and the like, what they do not share with unstructured fields, like the C<Subject> field. » example: my $field = Mail::Message::Field->new(From => 'me'); if($field->isStructured) Mail::Message::Field->isStructured('From'); =item $obj-E<gt>B<length>() Returns the total length of the field in characters, which includes the field's name, body and folding characters. =item $obj-E<gt>B<nrLines>() Returns the number of lines needed to display this header-line. =item $obj-E<gt>B<print>( [$fh] ) Print the whole header-line to the specified file-handle. One line may result in more than one printed line, because of the folding of long lines. The C<$fh> defaults to the selected handle. =item $obj-E<gt>B<size>() Returns the number of bytes needed to display this header-line, Same as L<length()|Mail::Message::Field/"The field">. =item $obj-E<gt>B<string>( [$wrap] ) Returns the field as string. By default, this returns the same as L<folded()|Mail::Message::Field/"Attributes">. However, the optional C<$wrap> will cause to re-fold to take place (without changing the folding stored inside the field). =item $obj-E<gt>B<toDisclose>() Returns whether this field can be disclosed to other people, for instance when sending the message to another party. Returns a C<true> or C<false> condition. See also L<Mail::Message::Head::Complete::printUndisclosed()|Mail::Message::Head::Complete/"Access to the header">. =back =head2 Access to the content =over 4 =item $obj-E<gt>B<addresses>() Returns a list of L<Mail::Address|Mail::Address> objects, which represent the e-mail addresses found in this header line. Only applicable to fields which contain addresses. » example: my @addrs = $message->get('to')->addresses; my @addrs = $message->to; # Better, uses Mail::Message::Field::Addresses my @addrs = $message->study('to')->addresses; =item $obj-E<gt>B<attribute>( $name, [$value] ) Get the value of an B<body> attribute, optionally after setting it to a new value. Attributes are part of some header lines, and hide themselves in the comment field. If the attribute does not exist, then C<undef> is returned. The attribute is still encoded. » example: my $field = Mail::Message::Field->new( 'Content-Type: text/plain; charset="us-ascii"'); print $field->attribute('charset'); # --> us-ascii print $field->attribute('bitmap') || 'no'; # --> no $field->attribute(filename => '/tmp/xyz'); $field->print; # --> Content-Type: text/plain; charset="us-ascii"; # filename="/tmp/xyz" # Automatically folded, and no doubles created. =item $obj-E<gt>B<attributes>() Returns a list of key-value pairs, where the values are not yet decoded. Keys may appear more than once and must be interpreted case insensitive (RFC2073 section 5.1) » example: my @pairs = $head->get('Content-Disposition')->attributes; =item $obj-E<gt>B<comment>( [STRING] ) Returns the unfolded comment (part after a semi-colon) in a structured header-line. optionally after setting it to a new C<STRING> first. When C<undef> is specified as C<STRING>, the comment is removed. Whether the field is structured is defined by L<isStructured()|Mail::Message::Field/"The field">. The I<comment> part of a header field often contains C<attributes>. Often it is preferred to use L<attribute()|Mail::Message::Field/"Access to the content"> on them. =item $any-E<gt>B<dateToTimestamp>(STRING) Convert a C<STRING> which represents and RFC compliant time string into a timestamp like is produced by the local C<POSIX::time()> function. Only applicable to fields which contain a date. Better result: my $df = $msg->study('Date') or return; $df->time; =item $any-E<gt>B<stripCFWS>( [STRING] ) Remove the I<comments> and I<folding white spaces> from the C<STRING>. Without string and only as instance method, the L<unfoldedBody()|Mail::Message::Field/"Attributes"> is being stripped and returned. WARNING: This operation is only allowed for structured header fields (which are defined by the various RFCs as being so. You don't want parts within braces which are in the Subject header line to be removed, to give an example. =item $obj-E<gt>B<study>() Study the header field in detail: turn on the full parsing and detailed understanding of the content of the fields. L<Mail::Message::Field::Fast|Mail::Message::Field::Fast> and L<Mail::Message::Field::Fast|Mail::Message::Field::Fast> objects will be transformed into any L<Mail::Message::Field::Full|Mail::Message::Field::Full> object. » example: my $subject = $msg->head->get('subject')->study; my $subject = $msg->get('subject')->study; # same my $subject = $msg->head->study('subject'); # same my $subject = $msg->study('subject'); # same =item $any-E<gt>B<toDate>( [$time] ) Convert a timestamp into an rfc2822 compliant date format. This differs from the default output of C<localtime> in scalar context. Without argument, the C<localtime> is used to get the current time. C<$time> can be specified as one numeric (like the result of C<time()>) and as list (like produced by c<localtime()> in list context). Be sure to have your timezone set right, especially when this script runs automatically. » example: my $now = time; Mail::Message::Field->toDate($now); Mail::Message::Field->toDate(time); Mail::Message::Field->toDate(localtime); Mail::Message::Field->toDate; # same # returns something like: # Wed, 28 Aug 2002 10:40:25 +0200 =item $obj-E<gt>B<toInt>() Returns the value which is related to this field as integer. A check is performed whether this is right. =back =head2 Parsing =over 4 =item $obj-E<gt>B<consume>( $line | <$name,<$body|$objects>> ) Accepts a whole field C<$line>, or a pair with the field's C<$name> and C<$body>. In the latter case, the C<$body> data may be specified as array of C<$objects> which are stringified. Returned is a nicely formatted pair of two strings: the field's name and a folded body. This method is called by L<new()|Mail::Message::Field/"Constructors">, and usually not by an application program. The details about converting the C<$objects> to a field content are explained in L</Specifying field data>. =item $obj-E<gt>B<defaultWrapLength>( [$length] ) Any field from any header for any message will have this default wrapping. This is maintained in one global variable. Without a specified C<$length>, the current value is returned. The default is 78. =item $any-E<gt>B<fold>( $name, $body, [$maxchars] ) Make the header field with C<$name> fold into multiple lines. Wrapping is performed by inserting newlines before a blanks in the C<$body>, such that no line exceeds the C<$maxchars> and each line is as long as possible. The RFC requests for folding on nice spots, but this request is mainly ignored because it would make folding too slow. =item $obj-E<gt>B<setWrapLength>( [$length] ) Force the wrapping of this field to the specified C<$length> characters. The wrapping is performed with L<fold()|Mail::Message::Field/"Parsing"> and the results stored within the field object. » example: refolding the field $field->setWrapLength(99); =item $obj-E<gt>B<stringifyData>(STRING|ARRAY|$objects) This method implements the translation of user supplied objects into ascii fields. The process is explained in L</Specifying field data>. =item $obj-E<gt>B<unfold>(STRING) The reverse action of L<fold()|Mail::Message::Field/"Parsing">: all lines which form the body of a field are joined into one by removing all line terminators (even the last). Possible leading blanks on the first line are removed as well. =back =head2 Error handling Extends L<"Error handling" in Mail::Reporter|Mail::Reporter/"Error handling">. =over 4 =item $obj-E<gt>B<AUTOLOAD>() Inherited, see L<Mail::Reporter/"Error handling"> =item $obj-E<gt>B<notImplemented>() Inherited, see L<Mail::Reporter/"Error handling"> =back =head2 Cleanup Extends L<"Cleanup" in Mail::Reporter|Mail::Reporter/"Cleanup">. =over 4 =item $obj-E<gt>B<DESTROY>() Inherited, see L<Mail::Reporter/"Cleanup"> =back =head1 DETAILS =head2 Field syntax Fields are stored in the header of a message, which are represented by L<Mail::Message::Head|Mail::Message::Head> objects. A field is a combination of a I<name>, I<body>, and I<attributes>. Especially the term "body" is cause for confusion: sometimes the attributes are considered to be part of the body. The name of the field is followed by a colon ("C<:>", not preceded by blanks, but followed by one blank). Each attribute is preceded by a separate semi-colon ("C<;>"). Names of fields are case-insensitive and cannot contain blanks. =head4 » Example: of fields Correct fields: Field: hi! Content-Type: text/html; charset=latin1 Incorrect fields, but accepted: Field : wrong, blank before colon Field: # wrong, empty Field:not nice, blank preferred after colon One Two: wrong, blank in name =head3 Folding fields Fields which are long can be folded to span more than one line. The real limit for lines in messages is only at 998 characters, however such long lines are not easy to read without support of an application. Therefore rfc2822 (which defines the message syntax) specifies explicitly that field lines can be re-formatted into multiple sorter lines without change of meaning, by adding new-line characters to any field before any blank or tab. Usually, the lines are reformatted to create lines which are 78 characters maximum. Some applications try harder to fold on nice spots, like before attributes. Especially the C<Received> field is often manually folded into some nice layout. In most cases however, it is preferred to produce lines which are as long as possible but max 78. BE WARNED that all fields can be subjected to folding, and that you usually want the unfolded value. =head4 » Example: of field folding Subject: this is a short line, and not folded Subject: this subject field is much longer, and therefore folded into multiple lines, although one more than needed. =head3 Structured fields The rfc2822 describes a large number of header fields explicitly. These fields have a defined meaning. For some of the fields, like the C<Subject> field, the meaning is straight forward the contents itself. These fields are the I<Unstructured Fields>. Other fields have a well defined internal syntax because their content is needed by e-mail applications. For instance, the C<To> field contains addresses which must be understood by all applications in the same way. These are the I<Structured Fields>, see L<isStructured()|Mail::Message::Field/"The field">. =head3 Comments in fields Stuctured fields can contain comments, which are pieces of text enclosed in parenthesis. These comments can be placed close to anywhere in the line and must be ignored be the application. Not all applications are capable of handling comments correctly in all circumstances. =head4 » Example: of field comments To: mailbox (Mail::Box mailinglist) <mailbox@overmeer.net> Date: Thu, 13 Sep 2001 09:40:48 +0200 (CEST) Subject: goodbye (was: hi!) On the first line, the text "L<Mail::Box|Mail::Box> mailinglist" is used as comment. Be warned that rfc2822 explicitly states that comments in e-mail address specifications should not be considered to contain any usable information. On the second line, the timezone is specified as comment. The C<Date> field format has no way to indicate the timezone of the sender, but only contains the timezone difference to UTC, however one could decide to add this as comment. Application must ignore this data because the C<Date> field is structured. The last field is unstructured. The text between parentheses is an integral part of the subject line. =head2 Getting a field As many programs as there are handling e-mail, as many variations on accessing the header information are requested. Be careful which way you access the data: read the variations described here and decide which solution suites your needs best. =head3 Using get() field The C<get()> interface is copied from other Perl modules which can handle e-mail messages. Many applications which simply replace L<Mail::Internet|Mail::Internet> objects by L<Mail::Message|Mail::Message> objects will work without modification. There is more than one get method. The exact results depend on which get you use. When L<Mail::Message::get()|Mail::Message/"The header"> is called, you will get the unfolded, stripped from comments, stripped from attributes contents of the field as B<string>. Character-set encodings will still be in the string. If the same fieldname appears more than once in the header, only the last value is returned. When L<Mail::Message::Head::get()|Mail::Message::Head/"Access to the header"> is called in scalar context, the last field with the specified name is returned as field B<object>. This object strinigfies into the unfolded contents of the field, including attributes and comments. In list context, all appearances of the field in the header are returned as objects. BE WARNED that some lines seem unique, but are not according to the official rfc. For instance, C<To> fields can appear more than once. If your program calls C<get('to')> in scalar context, some information is lost. =head4 » Example: of using get() print $msg->get('subject') || 'no subject'; print $msg->head->get('subject') || 'no subject'; my @to = $msg->head->get('to'); =head3 Using study() field As the name C<study> already implies, this way of accessing the fields is much more thorough but also slower. The C<study> of a field is like a C<get>, but provides easy access to the content of the field and handles character-set decoding correctly. The L<Mail::Message::study()|Mail::Message/"The header"> method will only return the last field with that name as object. L<Mail::Message::Head::study()|Mail::Message::Head/"Access to the header"> and L<Mail::Message::Field::study()|Mail::Message::Field/"Access to the content"> return all fields when used in list context. =head4 » Example: of using study() print $msg->study('subject') || 'no subject'; my @rec = $msg->head->study('Received'); my $from = $msg->head->get('From')->study; my $from = $msg->head->study('From'); # same my @addr = $from->addresses; =head3 Using resent groups Some fields belong together in a group of fields. For instance, a set of lines is used to define one step in the mail transport process. Each step adds a C<Received> line, and optionally some C<Resent-*> lines and C<Return-Path>. These groups of lines shall stay together and in order when the message header is processed. The C<Mail::Message::Head::ResentGroup> object simplifies the access to these related fields. These resent groups can be deleted as a whole, or correctly constructed. =head4 » Example: of using resent groups my $rgs = $msg->head->resentGroups; $rgs[0]->delete if @rgs; $msg->head->removeResentGroups; =head2 The field's data There are many ways to get the fields info as object, and there are also many ways to process this data within the field. =head3 Access to the field =over 4 =item * L<string()|Mail::Message::Field/"The field"> Returns the text of the body exactly as will be printed to file when L<print()|Mail::Message::Field/"The field"> is called, so name, main body, and attributes. =item * L<foldedBody()|Mail::Message::Field/"Attributes"> Returns the text of the body, like L<string()|Mail::Message::Field/"The field">, but without the name of the field. =item * L<unfoldedBody()|Mail::Message::Field/"Attributes"> Returns the text of the body, like L<foldedBody()|Mail::Message::Field/"Attributes">, but then with all new-lines removed. This is the normal way to get the content of unstructured fields. Character-set encodings will still be in place. Fields are stringified into their unfolded representation. =item * L<stripCFWS()|Mail::Message::Field/"Access to the content"> Returns the text of structured fields, where new-lines and comments are removed from the string. This is a good start for parsing the field, for instance to find e-mail addresses in them. =item * L<Mail::Message::Field::Full::decodedBody()|Mail::Message::Field::Full/"Access to the body"> Studied fields can produce the unfolded text decoded into utf8 strings. This is an expensive process, but the only correct way to get the field's data. More useful for people who are not living in ASCII space. =item * Studied fields Studied fields have powerful methods to provide ways to access and produce the contents of (structured) fields exactly as the involved rfcs prescribe. =back =head3 Using simplified field access Some fields are accessed that often that there are support methods to provide simplified access. All these methods are called upon a message directly. =head4 » Example: of simplified field access print $message->subject; print $message->get('subject') || ''; # same my @from = $message->from; # returns addresses $message->reply->send if $message->sender; The C<sender> method will return the address specified in the C<Sender> field, or the first named in the C<From> field. It will return C<undef> in case no address is known. =head3 Specifying field data Field data can be anything, strongly dependent on the type of field at hand. If you decide to construct the fields very carefully via some L<Mail::Message::Field::Full|Mail::Message::Field::Full> extension (like via L<Mail::Message::Field::Addresses|Mail::Message::Field::Addresses> objects), then you will have protection build-in. However, you can bluntly create any L<Mail::Message::Field|Mail::Message::Field> object based on some data. When you create a field, you may specify a string, object, or an array of strings and objects. On the moment, objects are only used to help the construction on e-mail addresses, however you may add some of your own. The following rules (implemented in L<stringifyData()|Mail::Message::Field/"Parsing">) are obeyed given the argument is: =over 4 =item * a string The string must be following the (complicated) rules of the rfc2822, and is made field content as specified. When the string is not terminated by a new-line (C<"\n">) it will be folded according to the standard rules. =item * a L<Mail::Address|Mail::Address> object The most used Perl object to parse and produce address lines. This object does not understand character set encodings in phrases. =item * a L<Mail::Identity|Mail::Identity> object As part of the L<User::Identity|User::Identity> distribution, this object has full understanding of the meaning of one e-mail address, related to a person. All features defined by rfc2822 are implemented. =item * a L<User::Identity|User::Identity> object A person is specified, which may have more than one L<Mail::Identity|Mail::Identity>'s defined. Some methods, like L<Mail::Message::reply()|Mail::Message::Construct::Reply/"Constructing a message"> and L<Mail::Message::forward()|Mail::Message::Construct::Forward/"Constructing a message"> try to select the right e-mail address smart (see their method descriptions), but in other cases the first e-mail address found is used. =item * a L<User::Identity::Collection::Emails|User::Identity::Collection::Emails> object All L<Mail::Identity|Mail::Identity> objects in the collection will be included in the field as a group carying the name of the collection. =item * any other object For all other objects, the stringification overload is used to produce the field content. =item * an ARRAY You may also specify an array with a mixture of any of the above. The elements will be joined as comma-separated list. If you do not want comma's inbetween, you will have to process the array yourself. =back =head4 » Example: specifying simple field data my $f = Mail::Message::Field->new(Subject => 'hi!'); my $b = Mail::Message->build(Subject => 'monkey'); =head4 » Example: s specifying e-mail addresses for a field use Mail::Address; my $fish = Mail::Address->new('Mail::Box', 'fish@tux.aq'); print $fish->format; # ==> Mail::Box <fish@tux.aq> my $exa = Mail::Address->new(undef, 'me@example.com'); print $exa->format; # ==> me@example.com my $b = $msg->build(To => "you@example.com"); my $b = $msg->build(To => $fish); my $b = $msg->build(To => [ $fish, $exa ]); my @all = ($fish, "you@example.com", $exa); my $b = $msg->build(To => \@all); my $b = $msg->build(To => [ "xyz", @all ]); =head4 » Example: specifying identities for a field use User::Identity; my $patrik = User::Identity->new( name => 'patrik', full_name => "Patrik Fältström", # from rfc charset => "ISO-8859-1", ); $patrik->add(email => "him@home.net"); my $b = $msg->build(To => $patrik); $b->get('To')->print; # ==> =?ISO-8859-1?Q?Patrik_F=E4ltstr=F6m?= # <him@home.net> =head2 Field class implementation For performance reasons only, there are three types of fields: the fast, the flexible, and the full understander: =over 4 =item * L<Mail::Message::Field::Fast|Mail::Message::Field::Fast> C<Fast> objects are not derived from a C<Mail::Reporter>. The consideration is that fields are so often created, and such a small objects at the same time. The fast field implementation uses an array to store the data: that will be faster than using a hash. Fast fields are not easily inheritable, because the object creation and initiation is merged into one method. =item * L<Mail::Message::Field::Flex|Mail::Message::Field::Flex> The flexible implementation uses a hash to store the data. The L<new()|Mail::Message::Field/"Constructors"> and C<init> methods are split, so this object is extensible. =item * L<Mail::Message::Field::Full|Mail::Message::Field::Full> With a full implementation of all applicable RFCs (about 5), the best understanding of the fields is reached. However, this comes with a serious memory and performance penalty. These objects are created from fast or flex header fields when L<study()|Mail::Message::Field/"Access to the content"> is called. =back =head1 DIAGNOSTICS =over 4 =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C<notImplemented()> =item Warning: field content is not numerical: $content The numeric value of a field is requested (for instance the C<Lines> or C<Content-Length> fields should be numerical), however the data contains weird characters. Cast by C<toInt()> =item Error: field name too long (max $count), in '$name'. It is not specified in the RFCs how long a field name can be, but at least it should be a few characters shorter than the line wrap. Cast by C<fold()> =item Warning: illegal character in field name $name. A new field is being created which does contain characters not permitted by the RFCs. Using this field in messages may break other e-mail clients or transfer agents, and therefore mutulate or extinguish your message. Cast by C<consume()> =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F<http://perl.overmeer.net/mailbox/> =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Head.pm����������������������������������������������������������0000644�0001750�0000144�00000010364�15166136116�020651� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::Head;{ our $VERSION = '4.05'; } use parent 'Mail::Reporter'; use strict; use warnings; use Log::Report 'mail-message', import => [ qw/mistake/ ]; use Mail::Message::Head::Complete; use Mail::Message::Field::Fast; use Scalar::Util qw/weaken/; #-------------------- use overload qq("") => 'string_unless_carp', bool => 'isEmpty'; # To satisfy overload in static resolving. sub toString() { $_[0]->load->toString } sub string() { $_[0]->load->string } sub string_unless_carp() { my $self = shift; (caller)[0] eq 'Carp' or return $self->toString; my $class = ref $self =~ s/^Mail::Message/MM/r; "$class object"; } #-------------------- sub new(@) { my $class = shift; $class eq __PACKAGE__ ? Mail::Message::Head::Complete->new(@_) : $class->SUPER::new(@_); } sub init($) { my ($self, $args) = @_; $self->SUPER::init($args); $self->message($args->{message}) if defined $args->{message}; $self->{MMH_field_type} = $args->{field_type} if $args->{field_type}; $self->{MMH_fields} = {}; $self->{MMH_order} = []; $self->{MMH_modified} = $args->{modified} || 0; $self; } sub build(@) { shift; Mail::Message::Head::Complete->build(@_); } #-------------------- sub isDelayed { 1 } sub modified(;$) { my $self = shift; return $self->isModified unless @_; $self->{MMH_modified} = shift; } sub isModified() { $_[0]->{MMH_modified} } sub isEmpty { scalar keys %{ $_[0]->{MMH_fields}} } sub message(;$) { my $self = shift; if(@_) { $self->{MMH_message} = shift; weaken($self->{MMH_message}); } $self->{MMH_message}; } sub orderedFields() { grep defined, @{ $_[0]->{MMH_order}} } sub knownNames() { keys %{ $_[0]->{MMH_fields}} } #-------------------- sub get($;$) { my $known = shift->{MMH_fields}; my $value = $known->{lc(shift)}; my $index = shift; if(defined $index) { return ! defined $value ? undef : ref $value eq 'ARRAY' ? $value->[$index] : $index == 0 ? $value : undef; } if(wantarray) { return ! defined $value ? () : ref $value eq 'ARRAY' ? @$value : ($value); } ! defined $value ? undef : ref $value eq 'ARRAY' ? $value->[-1] : $value; } sub get_all(@) { my @all = shift->get(@_) } # compatibility, force list sub setField($$) {shift->add(@_)} # compatibility sub study($;$) { my $self = shift; return map $_->study, $self->get(@_) if wantarray; my $got = $self->get(@_); defined $got ? $got->study : undef; } #-------------------- sub isMultipart() { my $type = $_[0]->get('Content-Type', 0); $type && scalar $type->body =~ m[^multipart/]i; } #-------------------- sub read($) { my ($self, $parser) = @_; my @fields = $parser->readHeader; @$self{ qw/MMH_begin MMH_end/ } = (shift @fields, shift @fields); my $type = $self->{MMH_field_type} // 'Mail::Message::Field::Fast'; $self->addNoRealize( $type->new(@$_) ) for @fields; $self; } # Warning: fields are added in addResentGroup() as well! sub addOrderedFields(@) { my $order = shift->{MMH_order}; foreach (@_) { push @$order, $_; weaken( $order->[-1] ); } @_; } sub load($) { $_[0] } sub fileLocation() { my $self = shift; @$self{ qw/MMH_begin MMH_end/ }; } sub moveLocation($) { my ($self, $dist) = @_; $self->{MMH_begin} -= $dist; $self->{MMH_end} -= $dist; $self; } sub setNoRealize($) { my ($self, $field) = @_; my $known = $self->{MMH_fields}; my $name = $field->name; $self->addOrderedFields($field); $known->{$name} = $field; $field; } sub addNoRealize($) { my ($self, $field) = @_; my $known = $self->{MMH_fields}; my $name = $field->name; $self->addOrderedFields($field); if(defined $known->{$name}) { if(ref $known->{$name} eq 'ARRAY') { push @{$known->{$name}}, $field } else { $known->{$name} = [ $known->{$name}, $field ] } } else { $known->{$name} = $field; } $field; } #-------------------- 1; ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mail-Message-4.05/lib/Mail/Message/Test.pm����������������������������������������������������������0000644�0001750�0000144�00000004515�15166136116�020730� 0����������������������������������������������������������������������������������������������������ustar�00markov��������������������������users���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::Test;{ our $VERSION = '4.05'; } use parent 'Exporter'; use strict; use warnings; use Log::Report 'mail-message', import => [ qw// ]; use File::Copy qw/copy/; use List::Util qw/first/; use IO::File; # to overrule open() use Test::More; our @EXPORT = qw/compare_message_prints reproducable_text $raw_html_data $crlf_platform/; our $crlf_platform = $^O =~ m/mswin32/i; # # Compare the text of two messages, rather strict. # On CRLF platforms, the Content-Length may be different. # sub compare_message_prints($$$) { my ($first, $second, $label) = @_; if($crlf_platform) { s/Content-Length: (\d+)/Content-Length: <removed>/g for $first, $second; } is($first, $second, $label); } # # Strip message text down the things which are the same on all # platforms and all situations. # sub reproducable_text($) { my $text = shift; my @lines = split /^/m, $text; foreach (@lines) { s/((?:references|message-id|date|content-length)\: ).*/$1<removed>/i; s/boundary-\d+/boundary-<removed>/g; } join '', @lines; } # # A piece of HTML text which is used in some tests. # our $raw_html_data = <<'TEXT'; <HTML> <HEAD> <TITLE>My home page

Life according to Brian

This is normal text, but not in a paragraph.

New paragraph in a bad way. And this is just a continuation. When texts get long, they must be auto-wrapped; and even that is working already.

Silly subsection at once

and another chapter

again a section

Normal paragraph, which contains an , some italics with linebreak and code

And now for the preformatted stuff
   it should stay as it was
      even   with   strange blanks
  and indentations
And back to normal text...
  • list item 1
    1. list item 1.1
    2. list item 1.2
  • list item 2
TEXT 1; Mail-Message-4.05/lib/Mail/Message/TransferEnc.pod0000644000175000001440000001244215166136120022362 0ustar00markovusers00000000000000=encoding utf8 =head1 NAME Mail::Message::TransferEnc - message transfer encoder/decoder =head1 INHERITANCE Mail::Message::TransferEnc is a Mail::Reporter Mail::Message::TransferEnc is extended by Mail::Message::TransferEnc::Base64 Mail::Message::TransferEnc::Binary Mail::Message::TransferEnc::EightBit Mail::Message::TransferEnc::QuotedPrint Mail::Message::TransferEnc::SevenBit =head1 SYNOPSIS my Mail::Message $msg = ...; my $decoded = $msg->decoded; my $encoded = $msg->encode(transfer => 'base64'); =head1 DESCRIPTION This class is the base for various encoders and decoders, which are used during transport of the message. These packages, and all which are derived, are invoked by the message's L and L methods: my $message = $folder->message(3); my $decoded_body = $message->decoded; my $encoded_body = $message->encode(transfer => 'base64'); Rules for transfer encodings are specified in RFC4289. The full list of permissible content transfer encodings can be found at L The following coders/decoders are currently supported (April 2025, the full list at IANA): =over 4 =item * L C for binary information. =item * L C<7bit> for plain old ASCII characters only. =item * L C<8bit> for extended character set data, not encoded. =item * L C encdoded extended character set data. =back Extends L<"DESCRIPTION" in Mail::Reporter|Mail::Reporter/"DESCRIPTION">. =head1 METHODS Extends L<"METHODS" in Mail::Reporter|Mail::Reporter/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Reporter|Mail::Reporter/"Constructors">. =over 4 =item $class-EB(%options) Inherited, see L =back =head2 Attributes Extends L<"Attributes" in Mail::Reporter|Mail::Reporter/"Attributes">. =head2 The Encoder =over 4 =item $class-EB($type, $class) Adds one new encoder to the list known by the L suite. The C<$type> is found in the message's header in the C field. =item $obj-EB($type, %options) Create a new coder/decoder based on the required type. =item $obj-EB() The name of the encoder. Case is not significant. =back =head2 Encoding =over 4 =item $obj-EB($body, %options) Check whether the body is correctly encoded. If so, the body reference is returned with the C flag set. Otherwise, a new object is created and returned. -Option --Default result_type =over 2 =item result_type => CLASS The type of the body to be produced, when the checker decides to return modified data. =back =item $obj-EB($body, %options) Use the encoder to decode the content of C<$body>. A new body is returned. -Option --Default result_type =over 2 =item result_type => CLASS The type of the body to be produced, when the decoder decides to return modified data. =back =item $obj-EB($body, %options) Use the encoder to encode the content of C<$body>. -Option --Default result_type =over 2 =item result_type => CLASS The type of the body to be produced, when the decoder decides to return modified data. =back =back =head2 Error handling Extends L<"Error handling" in Mail::Reporter|Mail::Reporter/"Error handling">. =over 4 =item $obj-EB() Inherited, see L =item $obj-EB() Inherited, see L =back =head2 Cleanup Extends L<"Cleanup" in Mail::Reporter|Mail::Reporter/"Cleanup">. =over 4 =item $obj-EB() Inherited, see L =back =head1 DIAGNOSTICS =over 4 =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C =item Error: decoder for transfer encoding $type does not work: $@ Compiling the required transfer encoding resulted in errors, which means that the decoder can not be used. Cast by C =item Error: no decoder for transfer encoding $type. A decoder for the specified type of transfer encoding is not implemented. Cast by C =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. Mail-Message-4.05/lib/Mail/Message/Convert.pod0000644000175000001440000001116215166136117021574 0ustar00markovusers00000000000000=encoding utf8 =head1 NAME Mail::Message::Convert - conversions between message types =head1 INHERITANCE Mail::Message::Convert is a Mail::Reporter Mail::Message::Convert is extended by Mail::Message::Convert::EmailSimple Mail::Message::Convert::Html Mail::Message::Convert::HtmlFormatPS Mail::Message::Convert::HtmlFormatText Mail::Message::Convert::MailInternet Mail::Message::Convert::MimeEntity Mail::Message::Convert::TextAutoformat =head1 SYNOPSIS Available methods are very converter-specific. =head1 DESCRIPTION This class is the base for various message (and message parts) converters. Extends L<"DESCRIPTION" in Mail::Reporter|Mail::Reporter/"DESCRIPTION">. =head2 Converters between message objects Internally, the L is called when foreign objects are used where message objects are expected. That method will automatically create the converting objects, and re-use them. =over 4 =item * L Converts the simple L messages into L objects. =item * L Converts the more complicated MIME::Entity messages into L objects. =item * L Converts Email::Simple messages into L objects. =back =head2 Other converters =over 4 =item * L Plays tricks with HTML/XMHTML without help of external modules. =item * L Converts HTML body objects to plain text objects using the HTML::FormatText module. =item * L Converts HTML body objects to Postscript objects using the HTML::FormatPS module. =item * L Converts a text message into text using Text::Autoformat. =back =head1 METHODS Extends L<"METHODS" in Mail::Reporter|Mail::Reporter/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Reporter|Mail::Reporter/"Constructors">. =over 4 =item $class-EB(%options) Inherited, see L -Option--Default fields =over 2 =item fields => $name|$regex|\@names|\@regexes Select the fields of a header which are to be handled. Other fields will not be used. The value of this option is passed to L whenever converters feel a need for header line selection. By default, the C, C, C, C, C, C, and their C counterparts will be selected. Specify an empty list to get all fields. =back =back =head2 Attributes Extends L<"Attributes" in Mail::Reporter|Mail::Reporter/"Attributes">. =head2 Converting =over 4 =item $obj-EB($head) Returns a list of fields to be included in the format. The list is an ordered selection of the fields in the actual header, and filtered through the information as specified with L. =back =head2 Error handling Extends L<"Error handling" in Mail::Reporter|Mail::Reporter/"Error handling">. =over 4 =item $obj-EB() Inherited, see L =item $obj-EB() Inherited, see L =back =head2 Cleanup Extends L<"Cleanup" in Mail::Reporter|Mail::Reporter/"Cleanup">. =over 4 =item $obj-EB() Inherited, see L =back =head1 DIAGNOSTICS =over 4 =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. Mail-Message-4.05/lib/Mail/Message/Part.pm0000644000175000001440000000552015166136117020715 0ustar00markovusers00000000000000# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::Part;{ our $VERSION = '4.05'; } use parent 'Mail::Message'; use strict; use warnings; use Log::Report 'mail-message', import => [ qw/__x error panic/ ]; use Scalar::Util qw/weaken/; #-------------------- sub init($) { my ($self, $args) = @_; $args->{head} ||= Mail::Message::Head::Complete->new; $self->SUPER::init($args); exists $args->{container} or error __x"no container specified for part."; weaken($self->{MMP_container}) if $self->{MMP_container} = $args->{container}; $self; } sub coerce($@) { my ($class, $thing, $container) = (shift, shift, shift); if($thing->isa($class)) { $thing->container($container); return $thing; } return $class->buildFromBody($thing, $container, @_) if $thing->isa('Mail::Message::Body'); # Although cloning is a Bad Thing(tm), we must avoid modifying # header fields of messages which reside in a folder. my $message = $thing->isa('Mail::Box::Message') ? $thing->clone : $thing; my $part = $class->SUPER::coerce($message); $part->container($container); $part; } sub buildFromBody($$;@) { my ($class, $body, $container) = (shift, shift, shift); my $head = Mail::Message::Head::Complete->new; while(@_) { if(ref $_[0]) {$head->add(shift)} else {$head->add(shift, shift)} } my $part = $class->new(head => $head, container => $container); $part->body($body); $part; } sub container(;$) { my $self = shift; @_ or return $self->{MMP_container}; $self->{MMP_container} = shift; weaken($self->{MMP_container}); } sub toplevel() { my $body = shift->container or return; my $msg = $body->message or return; $msg->toplevel; } sub isPart() { 1 } sub partNumber() { my $self = shift; my $body = $self->container or panic 'no container'; $body->partNumberOf($self); } sub readFromParser($;$) { my ($self, $parser, $bodytype) = @_; my $head = $self->readHead($parser) // Mail::Message::Head::Complete->new(message => $self, field_type => $self->{MM_field_type}); my $body = $self->readBody($parser, $head, $bodytype) // Mail::Message::Body::Lines->new(data => []); $self->head($head); $self->storeBody($body->contentInfoFrom($head)); $self; } #-------------------- sub printEscapedFrom($) { my ($self, $out) = @_; $self->head->print($out); $self->body->printEscapedFrom($out); } #-------------------- sub destruct() { my $self = shift; error __x"you cannot destruct message parts, only whole messages."; } 1; Mail-Message-4.05/lib/Mail/Message/Construct.pod0000644000175000001440000000332015166136117022135 0ustar00markovusers00000000000000=encoding utf8 =head1 NAME Mail::Message::Construct - extends the functionality of a Mail::Message =head1 SYNOPSIS # See Mail::Message =head1 DESCRIPTION Complex functionality on L objects is implemented in different files which are autoloaded. This file implements the functionality related to creating message replies. The following constructors are available: =over 4 =item L =item L =item L =item L =item L =item L =item L =back =head1 METHODS =over 4 =item $obj-EB() When an unknown method is called on this message, this may mean that not all code is compiled. For performance reasons, most of the complex activities on messages are dynamically loaded from other packages. An error will be produced when loading does not help resolving the requested method. Improves base, see L =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. Mail-Message-4.05/lib/Mail/Message/Body.pm0000644000175000001440000002355215166136116020710 0ustar00markovusers00000000000000# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::Body;{ our $VERSION = '4.05'; } use parent 'Mail::Reporter'; use strict; use warnings; use Log::Report 'mail-message', import => [ qw/__x error fault info panic/ ]; use Scalar::Util qw/weaken refaddr blessed/; use File::Basename qw/basename/; use Mail::Message::Field (); use Mail::Message::Body::Lines (); use Mail::Message::Body::File (); use MIME::Types (); my $mime_types = MIME::Types->new; my $mime_plain = $mime_types->type('text/plain'); #-------------------- use overload bool => sub {1}, # $body->print if $body '""' => 'string_unless_carp', '@{}' => 'lines', '==' => sub {ref $_[1] && refaddr $_[0] == refaddr $_[1]}, '!=' => sub {ref $_[1] && refaddr $_[0] != refaddr $_[1]}; #-------------------- my $body_count = 0; # to be able to compare bodies for equivalence. sub new(@) { my $class = shift; $class eq __PACKAGE__ or return $class->SUPER::new(@_); my %args = @_; exists $args{file} ? Mail::Message::Body::File->new(@_) : Mail::Message::Body::Lines->new(@_); } # All body implementations shall implement all of the following!! sub _data_from_filename(@) { $_[0]->notImplemented } sub _data_from_filehandle(@) { $_[0]->notImplemented } sub _data_from_lines(@) { $_[0]->notImplemented } sub init($) { my ($self, $args) = @_; $self->SUPER::init($args); $self->{MMB_modified} = $args->{modified} || 0; my $filename = $args->{filename}; my $mime = $args->{mime_type}; if(defined(my $file = $args->{file})) { if(!ref $file) { $self->_data_from_filename($file) or return; $filename ||= $file; $mime ||= $mime_types->mimeTypeOf($filename) || (-T $file ? 'text/plain' : 'application/octet-stream'); } elsif(ref $file eq 'GLOB' || (blessed $file && $file->isa('IO::Handle'))) { $self->_data_from_filehandle($file) or return; } else { error __x"message body: illegal datatype '{type}' for file option.", type => ref $file // $file; } } elsif(defined(my $data = $args->{data})) { if(!ref $data) { my @lines = split /^/, $data; $self->_data_from_lines(\@lines) } elsif(ref $data eq 'ARRAY') { $self->_data_from_lines($data) or return; } else { error __x"message body: illegal datatype '{type}' for data option.", type => ref $data // $data; } } elsif(! $self->isMultipart && ! $self->isNested) { # Neither 'file' nor 'data', so empty body. $self->_data_from_lines( [] ) or return; } # Set the content info my ($transfer, $disp, $descr, $cid, $lang) = @$args{ qw/transfer_encoding disposition description content_id language/ }; if(defined $filename) { $disp //= Mail::Message::Field->new( 'Content-Disposition' => (-T $filename ? 'inline' : 'attachment'), filename => basename($filename) ); $mime //= $mime_types->mimeTypeOf($filename); } if(ref $mime && $mime->isa('MIME::Type')) { $mime = $mime->type; } if(defined(my $based = $args->{based_on})) { $mime //= $based->type; $transfer //= $based->transferEncoding; $disp //= $based->disposition; $descr //= $based->description; $lang //= $based->language; $cid //= $based->contentId; $self->{MMB_checked} = exists $args->{checked} ? $args->{checked} : $based->checked; } else { $transfer = $args->{transfer_encoding}; $self->{MMB_checked} = $args->{checked} || 0; } $mime ||= 'text/plain'; $mime = $self->type($mime); my $default_charset = exists $args->{charset} ? $args->{charset} : 'PERL'; $mime->attribute(charset => $default_charset) if $default_charset && $mime =~ m!^text/!i && !$mime->attribute('charset'); $self->transferEncoding($transfer) if defined $transfer; $self->disposition($disp) if defined $disp; $self->description($descr) if defined $descr; $self->language($lang) if defined $lang; $self->contentId($cid) if defined $cid; $self->type($mime); # Set message where the body belongs to. $self->message($args->{message}) if defined $args->{message}; $self->{MMB_seqnr} = $body_count++; $self; } sub clone() { $_[0]->notImplemented } #-------------------- sub decoded(@) { my $self = shift; $self->encode(charset => 'PERL', transfer_encoding => 'none', @_); } #-------------------- sub message(;$) { my $self = shift; if(@_) { if($self->{MMB_message} = shift) { weaken $self->{MMB_message}; } } $self->{MMB_message}; } sub isDelayed() {0} sub isMultipart() {0} sub isNested() {0} sub partNumberOf($) { error __x"part number needs multi-part or nested."; } #-------------------- sub type(;$) { my $self = shift; return $self->{MMB_type} if !@_ && defined $self->{MMB_type}; delete $self->{MMB_mime}; my $type = shift // 'text/plain'; $self->{MMB_type} = blessed $type ? $type->clone : Mail::Message::Field->new('Content-Type' => $type); } sub mimeType() { my $self = shift; return $self->{MMB_mime} if exists $self->{MMB_mime}; my $field = $self->{MMB_type}; my $body = defined $field ? $field->body : ''; $self->{MMB_mime} = length $body ? ($mime_types->type($body) || MIME::Type->new(type => $body)) : $mime_plain; } sub charset() { $_[0]->type->attribute('charset') } sub transferEncoding(;$) { my $self = shift; return $self->{MMB_transfer} if !@_ && defined $self->{MMB_transfer}; my $set = shift // 'none'; $self->{MMB_transfer} = blessed $set ? $set->clone : Mail::Message::Field->new('Content-Transfer-Encoding' => $set); } sub description(;$) { my $self = shift; return $self->{MMB_description} if !@_ && $self->{MMB_description}; my $disp = shift // 'none'; $self->{MMB_description} = blessed $disp ? $disp->clone : Mail::Message::Field->new('Content-Description' => $disp); } sub disposition(;$) { my $self = shift; return $self->{MMB_disposition} if !@_ && $self->{MMB_disposition}; my $disp = shift // 'none'; $self->{MMB_disposition} = blessed $disp ? $disp->clone : Mail::Message::Field->new('Content-Disposition' => $disp); } sub language(@) { my $self = shift; return $self->{MMB_lang} if !@_ && $self->{MMB_lang}; my $langs = @_ > 1 ? (join ', ', @_) : blessed $_[0] ? $_[0] : ref $_[0] eq 'ARRAY' ? (join ', ', @{$_[0]}) : $_[0]; $self->{MMB_lang} = ! defined $langs || ! length $langs ? undef : blessed $langs ? $langs->clone : Mail::Message::Field->new('Content-Language' => $langs); } sub contentId(;$) { my $self = shift; return $self->{MMB_id} if !@_ && $self->{MMB_id}; my $cid = shift // 'none'; $self->{MMB_id} = blessed $cid ? $cid->clone : Mail::Message::Field->new('Content-ID' => $cid); } sub checked(;$) { my $self = shift; @_ ? ($self->{MMB_checked} = shift) : $self->{MMB_checked}; } sub nrLines(@) { $_[0]->notImplemented } sub size(@) { $_[0]->notImplemented } #-------------------- sub string() { $_[0]->notImplemented } sub string_unless_carp() { my $self = shift; (caller)[0] eq 'Carp' or return $self->string; my $class = ref $self =~ s/^Mail::Message/MM/r; "$class object"; } sub lines() { $_[0]->notImplemented } sub file(;$) { $_[0]->notImplemented } sub print(;$) { $_[0]->notImplemented } sub printEscapedFrom($) { $_[0]->notImplemented } sub write(@) { my ($self, %args) = @_; my $filename = $args{filename} or error __x"no filename parameter for write() body."; #XXX encoding? open my $out, '>', $filename or fault __x"cannot open {file} to write body", file => $filename; $self->print($out); $out->close or fault __x"error closing {file} after write body", file => $filename; $self; } sub endsOnNewline() { $_[0]->notImplemented } sub stripTrailingNewline() { $_[0]->notImplemented } #-------------------- sub read(@) { $_[0]->notImplemented } sub contentInfoTo($) { my ($self, $head) = @_; return unless defined $head; my $lines = $self->nrLines; my $size = $self->size; $size += $lines if $Mail::Message::crlf_platform; $head->set($self->type); $head->set($self->transferEncoding); $head->set($self->disposition); $head->set($self->description); $head->set($self->language); $head->set($self->contentId); $self; } sub contentInfoFrom($) { my ($self, $head) = @_; $self->type($head->get('Content-Type', 0)); my ($te, $disp, $desc, $cid, $lang) = map { my $x = $head->get("Content-$_") || ''; s/^\s+//,s/\s+$// for $x; length $x ? $x : undef; } qw/Transfer-Encoding Disposition Description ID Language/; $self->transferEncoding($te); $self->disposition($disp); $self->description($desc); $self->language($lang); $self->contentId($cid); delete $self->{MMB_mime}; $self; } sub modified(;$) { my $self = shift; @_ or return $self->isModified; # compat 2.036 $self->{MMB_modified} = shift; } sub isModified() { $_[0]->{MMB_modified} } sub fileLocation(;@) { my $self = shift; @_ or return @$self{ qw/MMB_begin MMB_end/ }; @$self{ qw/MMB_begin MMB_end/ } = @_; } sub moveLocation($) { my ($self, $dist) = @_; $self->{MMB_begin} -= $dist; $self->{MMB_end} -= $dist; $self; } sub load() { $_[0] } #-------------------- my @in_encode = qw/check encode encoded eol isBinary isText unify dispositionFilename/; my %in_module = map +($_ => 'encode'), @in_encode; sub AUTOLOAD(@) { my $self = shift; our $AUTOLOAD; my $call = $AUTOLOAD =~ s/.*\:\://gr; my $mod = $in_module{$call} || 'construct'; if($mod eq 'encode') { require Mail::Message::Body::Encode } else { require Mail::Message::Body::Construct } no strict 'refs'; return $self->$call(@_) if $self->can($call); # now loaded # AUTOLOAD inheritance is a pain panic "method $call() is not defined for a " . ref $self; } #-------------------- 1; Mail-Message-4.05/lib/Mail/Message/TransferEnc.pm0000644000175000001440000000303515166136116022217 0ustar00markovusers00000000000000# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message::TransferEnc;{ our $VERSION = '4.05'; } use parent 'Mail::Reporter'; use strict; use warnings; use Log::Report 'mail-message', import => [ qw/__x error/ ]; #-------------------- my %encoder = ( 'base64' => 'Mail::Message::TransferEnc::Base64', '7bit' => 'Mail::Message::TransferEnc::SevenBit', '8bit' => 'Mail::Message::TransferEnc::EightBit', 'quoted-printable' => 'Mail::Message::TransferEnc::QuotedPrint', ); #-------------------- sub create($@) { my ($class, $type) = (shift, shift); my $encoder = $encoder{lc $type} or error __x"no decoder for transfer encoding {type}.", type => $type; eval "require $encoder"; $@ and error __x"decoder for transfer encoding {type} does not work:\n{error}", type => $type, error => $@; $encoder->new(@_); } sub addTransferEncoder($$) { my ($class, $type, $encoderclass) = @_; $encoder{lc $type} = $encoderclass; $class; } sub name { $_[0]->notImplemented } #-------------------- sub check($@) { $_[0]->notImplemented } sub decode($@) { $_[0]->notImplemented } sub encode($) { $_[0]->notImplemented } #-------------------- 1; Mail-Message-4.05/lib/Mail/Box/0000755000175000001440000000000015166136132016610 5ustar00markovusers00000000000000Mail-Message-4.05/lib/Mail/Box/FastScalar.pod0000644000175000001440000000175015166136117021345 0ustar00markovusers00000000000000=encoding utf8 =head1 NAME Mail::Box::FastScalar - fast alternative to IO::Scalar =head1 SYNOPSIS my $fh = Mail::Box::FastScalar->new; $fh->open(\my $out); my $fh = Mail::Box::FastScalar->new(\my $out); =head1 DESCRIPTION Extremely fast IO::Scalar replacement - over 20x improvement in C and C methods. Contributed by "Todd Richmond" (C) =head2 Warnings You cannot modify the original reference between calls unless you C<$obj->seek(1, 0)> to reset the object - VERY rare usage case. $/ must be C or string - "" and \scalar unimplemented =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. Mail-Message-4.05/lib/Mail/Box/Parser/0000755000175000001440000000000015166136132020044 5ustar00markovusers00000000000000Mail-Message-4.05/lib/Mail/Box/Parser/Perl.pm0000644000175000001440000001647115166136116021317 0ustar00markovusers00000000000000# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Box::Parser::Perl;{ our $VERSION = '4.05'; } use parent 'Mail::Box::Parser'; use strict; use warnings; use Log::Report 'mail-message', import => [ qw/__x error fault info warning trace/ ]; use List::Util qw/sum/; use IO::File (); use Mail::Message::Field (); my $empty_line = qr/^\015?\012?$/; #-------------------- sub init(@) { my ($self, $args) = @_; $self->SUPER::init($args); $self->{MBPP_mode} = $args->{mode} || 'r'; $self->{MBPP_filename} = $args->{filename} || ref $args->{file} or error __x"filename or handle required to create a parser."; $self->start(file => $args->{file}); $self; } #-------------------- sub filename() { $_[0]->{MBPP_filename} } sub openMode() { $_[0]->{MBPP_mode} } sub file() { $_[0]->{MBPP_file} } #-------------------- sub start(@) { my ($self, %args) = @_; $self->openFile(%args) or return; $self->takeFileInfo; trace "opened folder ".$self->filename." to be parsed"; $self; } sub stop() { my $self = shift; trace "close parser for file " . $self->filename; $self->closeFile; } sub restart() { my $self = shift; $self->closeFile; $self->openFile(@_) or return; $self->takeFileInfo; trace "restarted parser for file " . $self->filename; $self; } sub fileChanged() { my $self = shift; my ($size, $mtime) = (stat $self->filename)[7,9]; return 0 if !defined $size || !defined $mtime; $size != $self->{MBPP_size} || $mtime != $self->{MBPP_mtime}; } sub filePosition(;$) { my $self = shift; @_ ? $self->file->seek(shift, 0) : $self->file->tell; } sub readHeader() { my $self = shift; my $file = $self->file or return (); my @ret = ($file->tell, undef); my $line = $file->getline; LINE: while(defined $line) { last LINE if $line =~ $empty_line; my ($name, $body) = split /\s*\:\s*/, $line, 2; unless(defined $body) { warning __x"unexpected end of header in {file}:\n {line}", file => $self->filename, line => $line; if(@ret && $self->fixHeaderErrors) { $ret[-1][1] .= ' '.$line; # glue err line to previous field $line = $file->getline; next LINE; } $file->seek(-length $line, 1); last LINE; } length $body or $body = "\n"; # Collect folded lines while($line = $file->getline) { $line =~ m!^[ \t]! ? ($body .= $line) : last; } $body =~ s/\015//g; push @ret, [ $name, $body ]; } $ret[1] = $file->tell; @ret; } sub _is_good_end($) { my ($self, $where) = @_; # No seps, then when have to trust it. my $sep = $self->activeSeparator // return 1; my $file = $self->file; my $here = $file->tell; $file->seek($where, 0) or return 0; # Find first non-empty line on specified location. my $line = $file->getline; $line = $file->getline while defined $line && $line =~ $empty_line; # Check completed, return to old spot. $file->seek($here, 0); $line // return 1; substr($line, 0, length $sep) eq $sep && ($sep ne 'From ' || $line =~ m/ (?:19[6-9]|20[0-3])[0-9]\b/ ); } sub readSeparator() { my $self = shift; my $sep = $self->activeSeparator // return (); my $file = $self->file; my $start = $file->tell; my $line = $file->getline; while(defined $line && $line =~ $empty_line) { $start = $file->tell; $line = $file->getline; } $line // return (); $line =~ s/[\012\015]+$/\n/; substr($line, 0, length $sep) eq $sep and return ($start, $line); $file->seek($start, 0); (); } sub _readStrippedLines(;$$) { my ($self, $exp_chars, $exp_lines) = @_; my $seps = $self->separators; my $file = $self->file; my $lines = []; my $msgend; if(@$seps) { LINE: while(1) { my $where = $file->getpos; my $line = $file->getline or last LINE; foreach my $sep (@$seps) { substr($line, 0, length $sep) eq $sep or next; # Some apps fail to escape lines starting with From next if $sep eq 'From ' && $line !~ m/ 19[789][0-9]| 20[0-9][0-9]/; $file->setpos($where); $msgend = $file->tell; last LINE; } push @$lines, $line; } if(@$lines && $lines->[-1] =~ s/\015?\012\z//) { # Keep an empty line to signal the existence of a preamble, but # remove a second. pop @$lines if @$seps==1 && @$lines > 1 && length($lines->[-1])==0; } } else # File without separators. { $lines = ref $file eq 'Mail::Box::FastScalar' ? $file->getlines : [ $file->getlines ]; } my $bodyend = $file->tell; if($self->stripGt) { s/^\>(\>*From\s)/$1/ for @$lines; } unless($self->trusted) { s/\015$// for @$lines; # input is read as binary stream (i.e. preserving CRLF on Windows). # Code is based on this assumption. Removal of CR if not trusted # conflicts with this assumption. [Markus Spann] } ($bodyend, $lines, $msgend); } sub _take_scalar($$) { my ($self, $begin, $end) = @_; my $file = $self->file; $file->seek($begin, 0); my $buffer; $file->read($buffer, $end-$begin); $buffer =~ s/\015//gr; } sub bodyAsString(;$$) { my ($self, $exp_chars, $exp_lines) = @_; my $file = $self->file; my $begin = $file->tell; if(defined $exp_chars && $exp_chars>=0) { # Get at once may be successful my $end = $begin + $exp_chars; if($self->_is_good_end($end)) { my $body = $self->_take_scalar($begin, $end); $body =~ s/^\>(\>*From\s)/$1/gm if $self->stripGt; return ($begin, $file->tell, $body); } } my ($end, $lines) = $self->_readStrippedLines($exp_chars, $exp_lines); ($begin, $end, join('', @$lines)); } sub bodyAsList(;$$) { my ($self, $exp_chars, $exp_lines) = @_; my $file = $self->file; my $begin = $file->tell; my ($end, $lines) = $self->_readStrippedLines($exp_chars, $exp_lines); ($begin, $end, $lines); } sub bodyAsFile($;$$) { my ($self, $out, $exp_chars, $exp_lines) = @_; my $file = $self->file; my $begin = $file->tell; my ($end, $lines) = $self->_readStrippedLines($exp_chars, $exp_lines); $out->print($_) for @$lines; ($begin, $end, scalar @$lines); } sub bodyDelayed(;$$) { my ($self, $exp_chars, $exp_lines) = @_; my $file = $self->file; my $begin = $file->tell; if(defined $exp_chars) { my $end = $begin + $exp_chars; if($self->_is_good_end($end)) { $file->seek($end, 0); return ($begin, $end, $exp_chars, $exp_lines); } } my ($end, $lines) = $self->_readStrippedLines($exp_chars, $exp_lines); my $chars = sum(map length, @$lines); ($begin, $end, $chars, scalar @$lines); } sub openFile(%) { my ($self, %args) = @_; #XXX IO::File is hard to remove because of the mode to be translated my $fh = $self->{MBPP_file} = $args{file} || IO::File->new($self->filename, $args{mode} || $self->openMode) or return; $fh->binmode(':raw') if $fh->can('binmode') || $fh->can('BINMODE'); $self->resetSeparators; $self; } sub closeFile() { my $self = shift; $self->resetSeparators; my $file = delete $self->{MBPP_file} or return; $file->close; $self; } sub takeFileInfo() { my $self = shift; @$self{ qw/MBPP_size MBPP_mtime/ } = (stat $self->filename)[7,9]; } #-------------------- #-------------------- sub DESTROY { my $self = shift; $self->stop; $self->SUPER::DESTROY; } 1; Mail-Message-4.05/lib/Mail/Box/Parser/Lines.pm0000644000175000001440000000772715166136116021473 0ustar00markovusers00000000000000# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Box::Parser::Lines;{ our $VERSION = '4.05'; } use parent 'Mail::Box::Parser'; use strict; use warnings; use Log::Report 'mail-message', import => [ qw/__x panic warning/ ]; use Mail::Message::Field (); #-------------------- sub init(@) { my ($self, $args) = @_; $self->SUPER::init($args); $self->{MBPL_lines} = $args->{lines} or panic "No lines"; $self->{MBPL_source} = $args->{source} or panic "No source"; $self; } #-------------------- sub lines() { $_[0]->{MBPL_lines} } sub source() { $_[0]->{MBPL_source} } #-------------------- my $is_empty_line = qr/^\015?\012?$/; sub readHeader() { my $self = shift; my $lines = $self->lines; my @ret; LINE: while(@$lines) { my $line = shift @$lines; last if $line =~ $is_empty_line; my ($name, $body) = split /\s*\:\s*/, $line, 2; unless(defined $body) { warning __x"unexpected end of header in {source}:\n {line}", source => $self->source, line => $line; if(@ret && $self->fixHeaderErrors) { $ret[-1][1] .= ' '.$line; # glue err line to previous field next LINE; } unshift @$lines, $line; last LINE; } # Collect folded lines $body .= shift @$lines while @$lines && $lines->[0] =~ m!^[ \t]!; push @ret, [ $name, $body ]; } (undef, undef, @ret); } sub _is_good_end() { my $self = shift; # No seps, then when have to trust it. my $sep = $self->activeSeparator // return 1; # Find first non-empty line on specified location. my $lines = $self->lines; my $skip = 0; while($skip < @$lines && $lines->[$skip] =~ $is_empty_line) { $skip++ } $skip < @$lines or return 1; my $line = $lines->[$skip]; substr($line, 0, length $sep) eq $sep && ($sep ne 'From ' || $line =~ m/ (?:19[6-9]|20[0-3])[0-9]\b/ ); } sub readSeparator() { my $self = shift; my $sep = $self->activeSeparator // return (); my $lines = $self->lines; my $skip = 0; while($skip < @$lines && $lines->[$skip] =~ $is_empty_line) { $skip++ } $skip < @$lines or return (); my $line = $lines->[$skip]; substr($line, 0, length $sep) eq $sep or return (); splice @$lines, 0, $skip+1; (undef, $line); } sub _read_stripped_lines(;$$) { my ($self, $exp_chars, $exp_lines) = @_; my $seps = $self->separators; my $lines = $self->lines; my $take = []; if(@$seps) { LINE: while(1) { my $line = shift @$lines or last LINE; foreach my $sep (@$seps) { substr($line, 0, length $sep) eq $sep or next; # Some apps fail to escape take starting with From next if $sep eq 'From ' && $line !~ m/ 19[789][0-9]| 20[0-9][0-9]/; unshift @$lines, $line; # keep separator last LINE; } push @$take, $line; } if(@$take && $take->[-1] =~ s/\015?\012\z//) { # Keep an empty line to signal the existence of a preamble, but # remove a second. pop @$take if @$seps==1 && @$take > 1 && length($take->[-1])==0; } } else # File without separators. { $take = $lines; } if($self->stripGt) { s/^\>(\>*From\s)/$1/ for @$take; } unless($self->trusted) { s/\015// for @$take; # remove \r, keep \n } $take; } sub bodyAsString(;$$) { my ($self, $exp_chars, $exp_lines) = @_; my $take = $self->_read_stripped_lines($exp_chars, $exp_lines); return (undef, undef, join('', @$take)); } sub bodyAsList(;$$) { my ($self, $exp_chars, $exp_lines) = @_; my $take = $self->_read_stripped_lines($exp_chars, $exp_lines); (undef, undef, $take); } sub bodyAsFile($;$$) { my ($self, $out, $exp_chars, $exp_lines) = @_; my $take = $self->_read_stripped_lines($exp_chars, $exp_lines); $out->print($_) for @$take; (undef, undef, scalar @$take); } 1; Mail-Message-4.05/lib/Mail/Box/Parser/Perl.pod0000644000175000001440000001303015166136117021452 0ustar00markovusers00000000000000=encoding utf8 =head1 NAME Mail::Box::Parser::Perl - reading messages from file using Perl =head1 INHERITANCE Mail::Box::Parser::Perl is a Mail::Box::Parser is a Mail::Reporter =head1 SYNOPSIS =head1 DESCRIPTION The C implements parsing of messages in Perl. This may be a little slower than the C based parser L, but will also work on platforms where no C compiler is available. Extends L<"DESCRIPTION" in Mail::Box::Parser|Mail::Box::Parser/"DESCRIPTION">. =head1 METHODS Extends L<"METHODS" in Mail::Box::Parser|Mail::Box::Parser/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Box::Parser|Mail::Box::Parser/"Constructors">. =over 4 =item $class-EB(%options) Inherited, see L -Option --Defined in --Default file undef filename fix_header_errors Mail::Box::Parser false mode 'r' trusted Mail::Box::Parser false =over 2 =item file => $filehandle Any IO::File or C C<$filehandle> which can be used to read the data from. In case this option is specified, the C is informational only. =item filename => FILENAME The name of the file to be read. =item fix_header_errors => BOOLEAN =item mode => $mode File open C<$mode>, which defaults to C<'r'>, which means `read-only'. See C for possible modes. Only applicable when no C is specified. =item trusted => BOOLEAN =back =back =head2 Attributes Extends L<"Attributes" in Mail::Box::Parser|Mail::Box::Parser/"Attributes">. =over 4 =item $any-EB( [$class] ) Inherited, see L =item $obj-EB() Z<> =item $obj-EB() Returns the name of the file this parser is working on. =item $obj-EB( [BOOLEAN] ) Inherited, see L =item $obj-EB() Z<> =item $obj-EB() Inherited, see L =back =head2 Parsing Extends L<"Parsing" in Mail::Box::Parser|Mail::Box::Parser/"Parsing">. =over 4 =item $obj-EB( $fh [$chars, [$lines]] ) Inherited, see L =item $obj-EB( [$chars, [$lines]] ) Inherited, see L =item $obj-EB( [$chars, [$lines]] ) Inherited, see L =item $obj-EB( [$chars, [$lines]] ) Inherited, see L =item $obj-EB() Close the file which was being parsed. =item $obj-EB() Returns whether the file which is parsed has changed after the last time takeFileInfo() was called. =item $obj-EB( [$position] ) Returns the location of the next byte to be used in the file which is parsed. When a C<$position> is specified, the location in the file is moved to the indicated spot first. =item $obj-EB() Inherited, see L =item $obj-EB(%options) Open the file to be parsed. =item $obj-EB() Inherited, see L =item $obj-EB(%options) Restart the parser on a certain file, usually because the content has changed. The C<%options> are passed to L. =item $obj-EB(%options) Start the parser by opening a file. -Option--Default file undef =over 2 =item file => FILEHANDLE|undef The file is already open, for instance because the data must be read from STDIN. =back =item $obj-EB() Stop the parser, which will include a close of the file. The lock on the folder will not be removed (is not the responsibility of the parser). Improves base, see L =item $obj-EB() Capture some data about the file being parsed, to be compared later. =back =head2 Error handling Extends L<"Error handling" in Mail::Box::Parser|Mail::Box::Parser/"Error handling">. =over 4 =item $obj-EB() Inherited, see L =item $obj-EB() Inherited, see L =back =head2 Cleanup Extends L<"Cleanup" in Mail::Box::Parser|Mail::Box::Parser/"Cleanup">. =over 4 =item $obj-EB() Inherited, see L =back =head1 DIAGNOSTICS =over 4 =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C =item Error: filename or handle required to create a parser. Cast by C =item Error: parser $type does not extend $pkg. Cast by C =item Warning: unexpected end of header in $file:\n $line Cast by C =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. Mail-Message-4.05/lib/Mail/Box/Parser/Lines.pod0000644000175000001440000000762115166136117021633 0ustar00markovusers00000000000000=encoding utf8 =head1 NAME Mail::Box::Parser::Lines - reading messages from file using Perl =head1 INHERITANCE Mail::Box::Parser::Lines is a Mail::Box::Parser is a Mail::Reporter =head1 SYNOPSIS =head1 DESCRIPTION This C implements parsing of messages in Perl, with an ARRAY as source. B Useful when the message is already in memory. When you plan to use this yourself, you probably need to use L. Extends L<"DESCRIPTION" in Mail::Box::Parser|Mail::Box::Parser/"DESCRIPTION">. =head1 METHODS Extends L<"METHODS" in Mail::Box::Parser|Mail::Box::Parser/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Box::Parser|Mail::Box::Parser/"Constructors">. =over 4 =item $class-EB(%options) Inherited, see L -Option --Defined in --Default fix_header_errors Mail::Box::Parser false lines source trusted Mail::Box::Parser false =over 2 =item fix_header_errors => BOOLEAN =item lines => \@lines =item source => $name =item trusted => BOOLEAN =back =back =head2 Attributes Extends L<"Attributes" in Mail::Box::Parser|Mail::Box::Parser/"Attributes">. =over 4 =item $any-EB( [$class] ) Inherited, see L =item $obj-EB( [BOOLEAN] ) Inherited, see L =item $obj-EB() Returns an ARRAY with the remaining lines. =item $obj-EB() The name of the source. =item $obj-EB() Inherited, see L =back =head2 Parsing Extends L<"Parsing" in Mail::Box::Parser|Mail::Box::Parser/"Parsing">. =over 4 =item $obj-EB( $fh [$chars, [$lines]] ) Inherited, see L =item $obj-EB( [$chars, [$lines]] ) Inherited, see L =item $obj-EB( [$chars, [$lines]] ) Inherited, see L =item $obj-EB( [$chars, [$lines]] ) Inherited, see L =item $obj-EB() Inherited, see L =item $obj-EB() Inherited, see L =item $obj-EB() Inherited, see L =back =head2 Error handling Extends L<"Error handling" in Mail::Box::Parser|Mail::Box::Parser/"Error handling">. =over 4 =item $obj-EB() Inherited, see L =item $obj-EB() Inherited, see L =back =head2 Cleanup Extends L<"Cleanup" in Mail::Box::Parser|Mail::Box::Parser/"Cleanup">. =over 4 =item $obj-EB() Inherited, see L =back =head1 DIAGNOSTICS =over 4 =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C =item Error: parser $type does not extend $pkg. Cast by C =item Warning: unexpected end of header in $source:\n $line Cast by C =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. Mail-Message-4.05/lib/Mail/Box/FastScalar.pm0000644000175000001440000000764315166136117021206 0ustar00markovusers00000000000000# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Box::FastScalar;{ our $VERSION = '4.05'; } use strict; use warnings; use integer; use Log::Report 'mail-message', import => [ qw// ]; use Scalar::Util qw/blessed/; #-------------------- sub new(;$) { my ($class, $ref) = @_; (bless +{ }, $class)->open($ref); } sub autoflush() {} sub binmode() {} sub clearerr { 0 } sub flush() {} sub sync() { 0 } sub opened() { $_[0]->{ref} } sub open($) { my $self = $_[0]; my $ref = $self->{ref} = $_[1] // \(my $tmp); $$ref //= ''; $self->{pos} = 0; $self; } sub close() { undef $_[0]->{ref} } sub eof() { my $self = $_[0]; $self->{pos} >= length ${$self->{ref}}; } sub getc() { my $self = $_[0]; substr ${$self->{ref}}, $self->{pos}++, 1; } sub print { my $self = shift; my $pos = $self->{pos}; my $ref = $self->{ref}; my $len = length $$ref; if ($pos >= $len) { $$ref .= $_ for @_; $self->{pos} = length $$ref; } else { my $buf = $#_ ? join('', @_) : $_[0]; $len = length $buf; substr($$ref, $pos, $len) = $buf; $self->{pos} = $pos + $len; } 1; } sub read($$;$) { my $self = $_[0]; my $buf = substr ${$self->{ref}}, $self->{pos}, $_[2]; $self->{pos} += $_[2]; ($_[3] ? substr($_[1], $_[3]) : $_[1]) = $buf; length $buf; } sub sysread($$;$) { shift->read(@_) } sub seek($$) { my ($self, $delta, $whence) = @_; my $len = length ${$self->{ref}}; if ($whence == 0) { $self->{pos} = $delta } elsif ($whence == 1) { $self->{pos} += $delta } elsif ($whence == 2) { $self->{pos} = $len + $delta } else { return } if($self->{pos} > $len) { $self->{pos} = $len } elsif($self->{pos} < 0) { $self->{pos} = 0 } 1; } sub sysseek($$) { $_[0]->seek($_[1], $_[2]) } sub setpos($) { $_[0]->seek($_[1], 0) } sub sref() { $_[0]->{ref} } sub getpos() { $_[0]->{pos} } sub tell() { $_[0]->{pos} } sub write($$;$) { my $self = $_[0]; my $pos = $self->{pos}; my $ref = $self->{ref}; my $len = length $$ref; if($pos >= $len) { $$ref .= substr($_[1], $_[3] || 0, $_[2]); $self->{pos} = length $$ref; $len = $self->{pos} - $len; } else { my $buf = substr($_[1], $_[3] || 0, $_[2]); $len = length $buf; substr($$ref, $pos, $len) = $buf; $self->{pos} = $pos + $len; } $len; } sub syswrite($;$$) { shift->write(@_) } sub getline() { my $self = shift; my $ref = $self->{ref}; my $pos = $self->{pos}; my $idx; if( !defined $/ || ($idx = index($$ref, $/, $pos)) == -1) { return if $pos >= length $$ref; $self->{pos} = length $$ref; return substr $$ref, $pos; } substr $$ref, $pos, ($self->{pos} = $idx + length $/) - $pos; } sub getlines() { my $self = $_[0]; my $ref = $self->{ref}; my $pos = $self->{pos}; my @lines; if(defined $/) { my $idx; my $sep_length = length $/; while(($idx = index($$ref, $/, $pos)) != -1) { push @lines, substr($$ref, $pos, $idx + $sep_length - $pos); $pos = $idx + $sep_length; } } my $r = substr $$ref, $pos; push @lines, $r if length $r > 0; $self->{pos} = length $$ref; wantarray ? @lines : \@lines; } # Call OO, because this module might be extended sub TIEHANDLE { blessed $_[1] && $_[1]->isa(__PACKAGE__) ? $_[1] : shift->new(@_) } sub GETC { shift->getc(@_) } sub PRINT { shift->print(@_) } sub PRINTF { shift->print(sprintf shift, @_) } sub READ { shift->read(@_) } sub READLINE { wantarray ? shift->getlines(@_) : shift->getline(@_) } sub WRITE { shift->write(@_) } sub CLOSE { shift->close(@_) } sub SEEK { shift->seek(@_) } sub TELL { shift->tell(@_) } sub EOF { shift->eof(@_) } 1; Mail-Message-4.05/lib/Mail/Box/Parser.pod0000644000175000001440000002260215166136117020555 0ustar00markovusers00000000000000=encoding utf8 =head1 NAME Mail::Box::Parser - reading and writing messages =head1 INHERITANCE Mail::Box::Parser is a Mail::Reporter Mail::Box::Parser is extended by Mail::Box::Parser::C Mail::Box::Parser::Lines Mail::Box::Parser::Perl =head1 SYNOPSIS # Not instatiatiated itself =head1 DESCRIPTION The C manages the parsing of folders. Usually, you won't need to know anything about this module, except the options which are involved with this code. There are currently three implementations of this module: =over 4 =item * L A fast parser written in C. This package is released as separate module on CPAN, because the module distribution via CPAN can not handle XS files which are not located in the root directory of the module tree. If a C compiler is available on your system, it will be used automatically. =item * L A slower parser when the message is in a file, like mbox, which only uses plain Perl. This module is a bit slower, and does less checking and less recovery. =item * L Useful when the message is already in memory. When you plan to use this yourself, you probably need to use L. =back Extends L<"DESCRIPTION" in Mail::Reporter|Mail::Reporter/"DESCRIPTION">. =head1 METHODS Extends L<"METHODS" in Mail::Reporter|Mail::Reporter/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Reporter|Mail::Reporter/"Constructors">. =over 4 =item $class-EB(%options) Create a parser object which can handle one file. For mbox-like mailboxes, this object can be used to read a whole folder. In case of MH-like mailboxes, each message is contained in a single file, so each message has its own parser object. Improves base, see L -Option --Default fix_header_errors false trusted false =over 2 =item fix_header_errors => BOOLEAN When header errors are detected, the parsing of the header will be stopped. Other header lines will become part of the body of the message. Set this flag to have the erroneous line added to the previous header line. =item trusted => BOOLEAN Is the input from the file to be trusted, or does it require extra tests. Related to L. =back =back =head2 Attributes Extends L<"Attributes" in Mail::Reporter|Mail::Reporter/"Attributes">. =over 4 =item $any-EB( [$class] ) Returns the parser to be used to parse all subsequent messages, possibly first setting the parser using the optional argument. Usually, the parser is autodetected; the C-based parser will be used when it can be, and the Perl-based parser will be used otherwise. The C<$class> argument allows you to specify a package name to force a particular parser to be used (such as your own custom parser). You have to C or C the package yourself before calling this method with an argument. The parser must be a sub-class of C. =item $obj-EB( [BOOLEAN] ) If set to C, parsing of a header will not stop on an error, but attempt to add the erroneous this line to previous field. Without C, the current setting is returned. » example: $folder->parser->fixHeaderErrors(1); my $folder = $mgr->open('folder', fix_header_errors => 1); =item $obj-EB() Trust the source of the data: do not run additional tests. =back =head2 Parsing =over 4 =item $obj-EB( $fh [$chars, [$lines]] ) Try to read one message-body from the file, and immediately write it to the specified file-handle. Optionally, the predicted number of CHARacterS and/or C<$lines> to be read can be supplied. These values may be C and may be wrong. The return is a list of three scalars: the location of the body (begin and end) and the number of lines in the body. =item $obj-EB( [$chars, [$lines]] ) Try to read one message-body from the file. Optionally, the predicted number of CHARacterS and/or C<$lines> to be read can be supplied. These values may be C and may be wrong. The return is a list of scalars, each containing one line (including line terminator), preceded by two integers representing the location in the file where this body started and ended. =item $obj-EB( [$chars, [$lines]] ) Try to read one message-body from the file. Optionally, the predicted number of CHARacterS and/or C<$lines> to be read can be supplied. These values may be C and may be wrong. Returned is a list of three scalars: the location in the file where the body starts, where the body ends, and the string containing the whole body. =item $obj-EB( [$chars, [$lines]] ) Try to read one message-body from the file, but the data is skipped. Optionally, the predicted number of CHARacterS and/or C<$lines> to be skipped can be supplied. These values may be C and may be wrong. The return is a list of four scalars: the location of the body (begin and end), the size of the body, and the number of lines in the body. The number of lines may be C. =item $obj-EB() Returns the character or characters which are used to separate lines in the folder file. This is based on the first line of the file. UNIX systems use a single LF to separate lines. Windows uses a CR and a LF. Mac uses CR. =item $obj-EB() Read the whole message-header and return it as list of field-value pairs. Mind that some fields will appear more than once. The first element will represent the position in the file where the header starts. The follows the list of header field names and bodies. » example: my ($where, @header) = $parser->readHeader; =item $obj-EB() Stop the parser. =back =head3 Administering separators The various "separators" methods are used by L to detect parts, and for the file based mailboxes to flag where the new message starts. =over 4 =item $obj-EB() Z<> =item $obj-EB() Remove the last-pushed separator from the list which is maintained by the parser. This will return C when there is none left. =item $obj-EB(STRING|Regexp) Add a boundary line. Separators tell the parser where to stop reading. A famous separator is the C-line, which is used in Mbox-like folders to separate messages. But also parts (I) is a message are divided by separators. The specified C describes the start of the separator-line. The Regexp can specify a more complicated format. =item $obj-EB(%options) Read the currently active separator (the last one which was pushed). The line (or C) is returned. Blank-lines before the separator lines are ignored. The return are two scalars, where the first gives the location of the separator in the file, and the second the line which is found as separator. A new separator is activated using L. =item $obj-EB() Z<> =item $obj-EB() Z<> =item $obj-EB() Z<> =back =head2 Error handling Extends L<"Error handling" in Mail::Reporter|Mail::Reporter/"Error handling">. =over 4 =item $obj-EB() Inherited, see L =item $obj-EB() Inherited, see L =back =head2 Cleanup Extends L<"Cleanup" in Mail::Reporter|Mail::Reporter/"Cleanup">. =over 4 =item $obj-EB() Inherited, see L =back =head1 DIAGNOSTICS =over 4 =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C =item Error: parser $type does not extend $pkg. Cast by C =item Warning: unexpected end of header in $source: $line While parsing a message from the specified source (usually a file name), the parser found a syntax error. According to the MIME specification in the RFCs, each header line must either contain a colon, or start with a blank to indicate a folded field. Apparently, this header contains a line which starts on the first position, but not with a field name. By default, parsing of the header will be stopped. If there are more header lines after the erroneous line, they will be added to the body of the message. In case of L set, the parsing of the header will be continued. The erroneous line will be added to the preceding field. Cast by C =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. Mail-Message-4.05/lib/Mail/Box/Parser.pm0000644000175000001440000000524415166136116020411 0ustar00markovusers00000000000000# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Box::Parser;{ our $VERSION = '4.05'; } use parent 'Mail::Reporter'; use strict; use warnings; use Log::Report 'mail-message', import => [ qw/__x error/ ]; #-------------------- sub new(@) { my $class = shift; $class eq __PACKAGE__ ? $class->defaultParserType->new(@_) # bootstrap right parser : $class->SUPER::new(@_); } sub init(@) { my ($self, $args) = @_; $self->SUPER::init($args); $self->{MBP_trusted} = $args->{trusted}; $self->{MBP_fix} = $args->{fix_header_errors}; $self->{MBP_seps} = []; $self; } #-------------------- sub fixHeaderErrors(;$) { my $self = shift; @_ ? ($self->{MBP_fix} = shift) : $self->{MBP_fix}; } sub trusted() { $_[0]->{MBP_trusted} } my $parser_type; sub defaultParserType(;$) { my $class = shift; # Select the parser manually? if(@_) { $parser_type = shift; return $parser_type if $parser_type->isa( __PACKAGE__ ); error __x"parser {type} does not extend {pkg}.", type => $parser_type, pkg => __PACKAGE__; } # Already determined which parser we want? $parser_type and return $parser_type; # Try to use C-based parser. eval 'require Mail::Box::Parser::C'; $@ or return $parser_type = 'Mail::Box::Parser::C'; # Fall-back on Perl-based parser. require Mail::Box::Parser::Perl; $parser_type = 'Mail::Box::Parser::Perl'; } #-------------------- sub readHeader() { $_[0]->notImplemented } sub bodyAsString() { $_[0]->notImplemented } sub bodyAsList() { $_[0]->notImplemented } sub bodyAsFile() { $_[0]->notImplemented } sub bodyDelayed() { $_[0]->notImplemented } sub lineSeparator() { $_[0]->{MBP_linesep} } sub stop() { } sub filePosition() { undef } #-------------------- sub readSeparator() { $_[0]->notImplemented } sub pushSeparator($) { my ($self, $sep) = @_; unshift @{$self->{MBP_seps}}, $sep; $self->{MBP_strip_gt}++ if $sep eq 'From '; $self; } sub popSeparator() { my $self = shift; my $sep = shift @{$self->{MBP_seps}}; $self->{MBP_strip_gt}-- if $sep eq 'From '; $sep; } sub separators() { $_[0]->{MBP_seps} } sub activeSeparator() { $_[0]->separators->[0] } sub resetSeparators() { $_[0]->{MBP_seps} = []; $_[0]->{MBP_strip_gt} = 0 } sub stripGt { $_[0]->{MBP_strip_gt} } #-------------------- #-------------------- 1; Mail-Message-4.05/lib/Mail/Reporter.pod0000644000175000001440000000473115166136120020370 0ustar00markovusers00000000000000=encoding utf8 =head1 NAME Mail::Reporter - base-class and error reporter for Mail::Box =head1 INHERITANCE Mail::Reporter is extended by HTML::FromMail HTML::FromMail::Format HTML::FromMail::Object Mail::Box Mail::Box::Collection Mail::Box::Identity Mail::Box::Locker Mail::Box::MH::Index Mail::Box::MH::Labels Mail::Box::Manager Mail::Box::Parser Mail::Box::Search Mail::Box::Thread::Manager Mail::Box::Thread::Node Mail::Message Mail::Message::Body Mail::Message::Body Mail::Message::Body::Delayed Mail::Message::Convert Mail::Message::Field Mail::Message::Field::Attribute Mail::Message::Head Mail::Message::Head::FieldGroup Mail::Message::TransferEnc Mail::Server Mail::Transport =head1 SYNOPSIS =head1 DESCRIPTION The C class is the base class for all classes, except L because it would become slow... This base class is used during initiation of the objects. =head1 METHODS The C class is the base for nearly all other objects. It can store and report problems, and contains the general constructor L. =head2 Constructors =over 4 =item $class-EB(%options) This is the base constructor for all modules, (as long as there is no need for another base object) =back =head2 Attributes =head2 Error handling =over 4 =item $obj-EB() By default, produce a nice warning if the sub-classes cannot resolve a method. =item $obj-EB() Z<> =back =head2 Cleanup =over 4 =item $obj-EB() Cleanup the object. =back =head1 DIAGNOSTICS =over 4 =item Error: class $package does not implement method $method. Fatal error: the specific C<$package> (or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast by C =back =head1 SEE ALSO This module is part of Mail-Message version 4.05, built on April 10, 2026. Website: F =head1 LICENSE For contributors see file ChangeLog. This software is copyright (c) 2001-2026 by Mark Overmeer. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. Mail-Message-4.05/lib/Mail/Message.pm0000644000175000001440000003416715166136116020017 0ustar00markovusers00000000000000# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Message;{ our $VERSION = '4.05'; } use parent 'Mail::Reporter'; use strict; use warnings; use Log::Report 'mail-message', import => [ qw/__x error info panic/ ]; use Mail::Message::Part (); use Mail::Message::Head::Complete (); use Mail::Message::Construct (); use Mail::Message::Body::Lines (); use Mail::Message::Body::Multipart (); use Mail::Message::Body::Nested (); use Scalar::Util qw/weaken blessed/; #-------------------- our $crlf_platform = $^O =~ m/win32/i; sub init($) { my ($self, $args) = @_; $self->SUPER::init($args); # Field initializations also in coerce() $self->{MM_modified} = $args->{modified} || 0; $self->{MM_trusted} = $args->{trusted} || 0; # Set the header my $head; if(defined($head = $args->{head})) { $self->head($head) } elsif(my $msgid = $args->{message_id} || $args->{messageId} || $args->{messageID}) { $self->takeMessageId($msgid); } # Set the body if(my $body = $args->{body}) { $self->{MM_body} = $body; $body->message($self); } $self->{MM_body_type} = $args->{body_type} // 'Mail::Message::Body::Lines'; $self->{MM_head_type} = $args->{head_type} // 'Mail::Message::Head::Complete'; $self->{MM_field_type} = $args->{field_type} if defined $args->{field_type}; my $labels = $args->{labels} || []; my @labels = ref $labels eq 'ARRAY' ? @$labels : %$labels; push @labels, deleted => $args->{deleted} if exists $args->{deleted}; $self->{MM_labels} = { @labels }; $self; } sub clone(@) { my ($self, %args) = @_; # First clone body, which may trigger head load as well. If head is # triggered first, then it may be decided to be lazy on the body at # moment. And then the body would be triggered. my ($head, $body) = ($self->head, $self->body); $head = $head->clone unless $args{shallow} || $args{shallow_head}; $body = $body->clone unless $args{shallow} || $args{shallow_body}; my $clone = Mail::Message->new(head => $head, body => $body); my %labels = %{$self->labels}; delete $labels{deleted}; $clone->{MM_labels} = \%labels; $clone->{MM_cloned} = $self; weaken($clone->{MM_cloned}); $clone; } #-------------------- sub messageId() { $_[0]->{MM_message_id} || $_[0]->takeMessageId} sub messageID() { $_[0]->messageId } # compatibility sub fieldType() { $_[0]->{MM_field_type} } sub headType() { $_[0]->{MM_head_type} } sub bodyType() { $_[0]->{MM_body_type} } #-------------------- #-------------------- sub container() { undef } # overridden by Mail::Message::Part sub isPart() { 0 } # overridden by Mail::Message::Part sub partNumber() { my $self = shift; my $cont = $self->container; $cont ? $cont->partNumber : undef; } sub toplevel() { $_[0] } # overridden by Mail::Message::Part sub isDummy() { 0 } sub endsOnNewline() { $_[0]->body->endsOnNewline } sub print(;$) { my $self = shift; my $out = shift || select; $self->head->print($out); my $body = $self->body; $body->print($out) if $body; # We need a new-line at the end of a full message. ref $self ne __PACKAGE__ or $body->endsOnNewline or $out->print("\n"); $self; } sub write(;$) { my $self = shift; my $out = shift || select; $self->head->print($out); $self->body->print($out); $self; } my $default_mailer; sub send(@) { my $self = shift; # Loosely coupled module require Mail::Transport::Send; my $mailer; $default_mailer = $mailer = shift if ref $_[0] && $_[0]->isa('Mail::Transport::Send'); my %args = @_; if( ! $args{via} && defined $default_mailer ) { $mailer = $default_mailer; } else { my $via = delete $args{via} || 'sendmail'; $default_mailer = $mailer = Mail::Transport->new(via => $via, %args); } $mailer->send($self, %args); } sub size() { my $self = shift; $self->head->size + $self->body->size; } #-------------------- sub head(;$) { my $self = shift; @_ or return $self->{MM_head}; my $head = shift; unless(defined $head) { delete $self->{MM_head}; return undef; } blessed $head && $head->isa('Mail::Message::Head') or panic; $head->message($self); if(my $old = $self->{MM_head}) { $self->{MM_modified}++ unless $old->isDelayed; } $self->{MM_head} = $head; $self->takeMessageId unless $head->isDelayed; $head; } sub get($) { my $self = shift; my $field = $self->head->get(shift) or return undef; $field->body; } sub study($) { my $head = shift->head or return; scalar $head->study(@_); # return only last } sub from() { my @from = shift->head->get('From') or return (); map $_->addresses, @from; } sub sender() { my $self = shift; my $sender = $self->head->get('Sender') || $self->head->get('From'); $sender ? ($sender->addresses)[0] : (); # first specified address } sub to() { map $_->addresses, $_[0]->head->get('To') } sub cc() { map $_->addresses, $_[0]->head->get('Cc') } sub bcc() { map $_->addresses, $_[0]->head->get('Bcc') } sub destinations() { my $self = shift; my %to = map +(lc($_->address) => $_), $self->to, $self->cc, $self->bcc; values %to; } sub subject() { $_[0]->get('subject') // '' } sub guessTimestamp() { $_[0]->head->guessTimestamp } sub timestamp() { my $head = $_[0]->head; $head->recvstamp || $head->timestamp; } sub nrLines() { my $self = shift; $self->head->nrLines + $self->body->nrLines; } #-------------------- sub body(;$@) { my $self = shift; @_ or return $self->{MM_body}; my $head = $self->head; $head->removeContentInfo if defined $head; my ($rawbody, %args) = @_; unless(defined $rawbody) { # Disconnect body from message. my $body = delete $self->{MM_body}; $body->message(undef) if defined $body; return $body; } blessed $rawbody && $rawbody->isa('Mail::Message::Body') or panic; # Bodies of real messages must be encoded for safe transmission. # Message parts will get encoded on the moment the whole multipart # is transformed into a real message. my $body = $self->isPart ? $rawbody : $rawbody->encoded; $body->contentInfoTo($self->head); my $oldbody = $self->{MM_body}; return $body if defined $oldbody && $body==$oldbody; $body->message($self); $body->modified(1) if defined $oldbody; $self->{MM_body} = $body; } sub decoded(@) { my $body = shift->body->load; $body ? $body->decoded(@_) : undef; } sub encode(@) { my $body = shift->body->load; $body ? $body->encode(@_) : undef; } sub isMultipart() { $_[0]->head->isMultipart } sub isNested() { $_[0]->body->isNested } sub contentType() { my $head = shift->head; my $ct = (defined $head ? $head->get('Content-Type', 0) : undef) // ''; $ct =~ s/\s*\;.*//; length $ct ? $ct : 'text/plain'; } sub parts(;$) { my $self = shift; my $what = shift || 'ACTIVE'; my $body = $self->body; my $recurse = $what eq 'RECURSE' || ref $what; my @parts = $body->isNested ? $body->nested->parts($what) : $body->isMultipart ? $body->parts($recurse ? 'RECURSE' : ()) : $self; ref $what eq 'CODE' ? (grep $what->($_), @parts) : $what eq 'ACTIVE' ? (grep !$_->isDeleted, @parts) : $what eq 'DELETED' ? (grep $_->isDeleted, @parts) : $what eq 'ALL' ? @parts : $recurse ? @parts : error __x"select parts via '{what}'?", what => $what; } #-------------------- sub modified(;$) { my $self = shift; @_ or return $self->isModified; # compatibility 2.036 my $flag = $self->{MM_modified} = shift; my $head = $self->head; $head->modified($flag) if $head; my $body = $self->body; $body->modified($flag) if $body; $flag; } sub isModified() { my $self = shift; return 1 if $self->{MM_modified}; my $head = $self->head; if($head && $head->isModified) { $self->{MM_modified}++; return 1; } my $body = $self->body; if($body && $body->isModified) { $self->{MM_modified}++; return 1; } 0; } sub label($;$@) { my $self = shift; @_ > 1 or return $self->{MM_labels}{$_[0]}; my %labels = @_; @{$self->{MM_labels}}{keys %labels} = values %labels; $_[1]; } sub labels() { my $self = shift; wantarray ? keys %{$self->{MM_labels}} : $self->{MM_labels}; } sub isDeleted() { $_[0]->label('deleted') } sub delete() { my $self = shift; my $old = $self->label('deleted'); $old || $self->label(deleted => time); } sub deleted(;$) { my $self = shift; @_ ? $self->label(deleted => shift) : $self->label('deleted') # compat 2.036 } sub labelsToStatus() { my $self = shift; my $head = $self->head; my $labels = $self->labels; my $status = $head->get('status') || ''; my $newstatus = $labels->{seen} ? 'RO' : $labels->{old} ? 'O' : ''; my $xstatus = $head->get('x-status') || ''; my $newxstatus = ($labels->{replied} ? 'A' : '') . ($labels->{flagged} ? 'F' : ''); $head->set(Status => $newstatus) if $newstatus ne $status; $head->set('X-Status' => $newxstatus) if $newxstatus ne $xstatus; $self; } sub statusToLabels() { my $self = shift; my $head = $self->head; if(my $status = $head->get('status')) { $status = $status->foldedBody; $self->label(seen => (index($status, 'R') >= 0), old => (index($status, 'O') >= 0)); } if(my $xstatus = $head->get('x-status')) { $xstatus = $xstatus->foldedBody; $self->label(replied => (index($xstatus, 'A') >= 0), flagged => (index($xstatus, 'F') >= 0)); } $self; } #-------------------- my $mail_internet_converter; my $mime_entity_converter; my $email_simple_converter; sub coerce($@) { my ($class, $message) = @_; blessed $message or error __x"coercion starts with some object, not '{type}'.", type => ref $message // $message ; return $message if ref $message eq $class; if($message->isa(__PACKAGE__)) { $message->head->modified(1); $message->body->modified(1); return bless $message, $class; } if($message->isa('MIME::Entity')) { unless($mime_entity_converter) { eval {require Mail::Message::Convert::MimeEntity}; $@ and error __x"please install MIME::Entity."; $mime_entity_converter = Mail::Message::Convert::MimeEntity->new; } $message = $mime_entity_converter->from($message) or return; } elsif($message->isa('Mail::Internet')) { unless($mail_internet_converter) { eval { require Mail::Message::Convert::MailInternet }; $@ and error __x"please install Mail::Internet."; $mail_internet_converter = Mail::Message::Convert::MailInternet->new; } $message = $mail_internet_converter->from($message) or return; } elsif($message->isa('Email::Simple')) { unless($email_simple_converter) { eval {require Mail::Message::Convert::EmailSimple}; $@ and error __x"please install Email::Simple."; $email_simple_converter = Mail::Message::Convert::EmailSimple->new; } $message = $email_simple_converter->from($message) or return; } elsif($message->isa('Email::Abstract')) { return $class->coerce($message->object); } else { error __x"cannot coerce a {type} object into a {me} object.", type => ref $message, me => __PACKAGE__; } $message->{MM_modified} ||= 0; bless $message, $class; } sub clonedFrom() { $_[0]->{MM_cloned} } # All next routines try to create compatibility with release < 2.0 sub isParsed() { not $_[0]->isDelayed } sub headIsRead() { not $_[0]->head->isDelayed } sub readFromParser($;$) { my ($self, $parser, $bodytype) = @_; my $head = $self->readHead($parser) // Mail::Message::Head::Complete->new(message => $self, field_type => $self->fieldType); my $body = $self->readBody($parser, $head, $bodytype) or return; $self->head($head); $self->storeBody($body); $self; } sub readHead($;$) { my ($self, $parser, $headtype) = @_; $headtype //= $self->headType; $headtype->new(message => $self, field_type => $self->fieldType) ->read($parser); } sub readBody($$;$$) { my ($self, $parser, $head, $getbodytype) = @_; my $bodytype = ! $getbodytype ? $self->bodyType : ref $getbodytype ? $getbodytype->($self, $head) : $getbodytype; my $body; if($bodytype->isDelayed) { # autodetect charset after transfer decoding. $body = $bodytype->new(message => $self, charset => undef); } else { my $ct = $head->get('Content-Type', 0); my $type = defined $ct ? lc($ct->body) : 'text/plain'; # Be sure you have acceptable bodies for multiparts and nested. if(substr($type, 0, 10) eq 'multipart/' && !$bodytype->isMultipart) { $bodytype = 'Mail::Message::Body::Multipart'; } elsif($type eq 'message/rfc822') { # RFC2046 forbids the extras of RFC6532, but Outlook implemented it anyway: # transfer encoding of this part. In that case, do not use a ::Nested my $enc = $head->get('Content-Transfer-Encoding') || 'none'; $bodytype = 'Mail::Message::Body::Nested' if $enc =~ m/^(?:none|7bit|8bit|binary)$/i && ! $bodytype->isNested; } $body = $bodytype->new(message => $self, checked => $self->isTrusted, charset => undef); $body->contentInfoFrom($head); } my $lines = $head->get('Lines'); # usually off-by-one my $size = $head->guessBodySize; $body->read($parser, $head, $getbodytype, $size, $lines); } sub storeBody($) { my ($self, $body) = @_; $self->{MM_body} = $body; $body->message($self); $body; } sub isDelayed() { my $body = shift->body; !$body || $body->isDelayed; } sub takeMessageId(;$) { my $self = shift; my $msgid = (@_ ? shift : $self->get('Message-ID')) || ''; if($msgid =~ m/\<([^>]*)\>/s) { $msgid = $1 =~ s/\s//grs; } $self->{MM_message_id} = $msgid || $self->head->createMessageId; } sub isTrusted() { $_[0]->{MM_trusted} } #-------------------- sub shortSize(;$) { my $self = shift; my $size = shift // $self->head->guessBodySize; !defined $size ? '?' : $size < 1_000 ? sprintf "%3d " , $size : $size < 10_000 ? sprintf "%3.1fK", $size/1024 : $size < 1_000_000 ? sprintf "%3.0fK", $size/1024 : $size < 10_000_000 ? sprintf "%3.1fM", $size/(1024*1024) : sprintf "%3.0fM", $size/(1024*1024); } sub shortString() { my $self = shift; sprintf "%4s %-30.30s", $self->shortSize, $self->subject; } #-------------------- sub destruct() { $_[0] = undef } #-------------------- 1; Mail-Message-4.05/lib/Mail/Reporter.pm0000644000175000001440000000235215166136117020225 0ustar00markovusers00000000000000# This code is part of Perl distribution Mail-Message version 4.05. # The POD got stripped from this file by OODoc version 3.06. # For contributors see file ChangeLog. # This software is copyright (c) 2001-2026 by Mark Overmeer. # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later package Mail::Reporter;{ our $VERSION = '4.05'; } use strict; use warnings; use Log::Report 'mail-message', import => [ qw/__x error panic warning/ ]; use Scalar::Util qw/dualvar blessed/; #-------------------- sub new(@) { my $class = shift; (bless +{}, $class)->init( +{@_} ); } sub init($) { shift } #-------------------- #-------------------- sub notImplemented(@) { my $self = shift; my $package = ref $self || $self; my $sub = (caller 1)[3]; error __x"class {package} does not implement method {method}.", class => $package, method => $sub; } sub AUTOLOAD(@) { my $thing = shift; our $AUTOLOAD; my $class = ref $thing || $thing; my $method = $AUTOLOAD =~ s/^.*\:\://r; panic "method $method() is not defined for a $class."; } #-------------------- sub DESTROY { $_[0] } 1; Mail-Message-4.05/lib/Mail/Message.pod0000644000175000001440000013425615166136117020166 0ustar00markovusers00000000000000=encoding utf8 =head1 NAME Mail::Message - general message object =head1 INHERITANCE Mail::Message has extra code in Mail::Message::Construct Mail::Message::Construct::Bounce Mail::Message::Construct::Build Mail::Message::Construct::Forward Mail::Message::Construct::Read Mail::Message::Construct::Rebuild Mail::Message::Construct::Reply Mail::Message::Construct::Text Mail::Message is a Mail::Reporter Mail::Message is extended by Mail::Box::Message Mail::Message::Dummy Mail::Message::Part Mail::Message::Replace::MailInternet =head1 SYNOPSIS use Mail::Box::Manager; my $mgr = Mail::Box::Manager->new; my $folder = $mgr->open(folder => 'INBOX'); my $msg = $folder->message(2); # $msg is a Mail::Message my $subject = $msg->subject; # The message's subject my @cc = $msg->cc; # List of Mail::Address'es my $head = $msg->head; # Mail::Message::Head my $body = $msg->decoded; # Mail::Message::Body $msg->decoded->print($outfile); # Send a simple email Mail::Message->build( To => 'you@example.com', From => 'me@example.com', Subject => "My subject", data => "Some plain text content.\n" )->send(via => 'postfix'); # See related Mail::Message::Construct::* manuals my $msg = Mail::Message->read(\@lines); my $reply_msg = $msg->reply(...); my $frwd_msg = $msg->forward(...); my $bounce = $msg->bounce(...); =head1 DESCRIPTION A C object is a container for MIME-encoded message information, as defined by RFC2822. Everything what is not specificaly related to storing the messages in mailboxes (folders) is implemented in this class. Methods which are related to folders is implemented in the L extension. The main methods are L, to get information from a message header field, and L to get the intended content of a message. But there are many more which can assist your program. Complex message handling, like construction of replies and forwards, are implemented in separate packages which are autoloaded into this class. This means you can simply use these methods as if they are part of this class. Those package add functionality to all kinds of message objects. Extends L<"DESCRIPTION" in Mail::Reporter|Mail::Reporter/"DESCRIPTION">. =head1 METHODS Extends L<"METHODS" in Mail::Reporter|Mail::Reporter/"METHODS">. =head2 Constructors Extends L<"Constructors" in Mail::Reporter|Mail::Reporter/"Constructors">. =over 4 =item $obj-EB(%options) Create a copy of this message. Returned is a C object. The head and body are taken. Labels are copied with the message, but the delete and modified flags are not. BE WARNED: the clone of any kind of message (or a message part) will B be a C object. For example, a L's clone is detached from the folder of its original. When you use L with the cloned message at hand, then the clone will automatically be coerced into the right message type to be added. See also L and L. -Option --Default shallow false shallow_body false shallow_head false =over 2 =item shallow => BOOLEAN When a shallow clone is made, the header and body of the message will not be cloned, but shared. This is quite dangerous: for instance in some folder types, the header fields are used to store folder flags. When one of both shallow clones change the flags, that will update the header and thereby be visible in both. There are situations where a shallow clone can be used safely. For instance, when L is used and you are sure that the original message cannot get undeleted after the move. =item shallow_body => BOOLEAN A rather safe bet, because you are not allowed to modify the body of a message: you may only set a new body with L. =item shallow_head => BOOLEAN Only the head is reused, not the body. This is probably a bad choice, because the header fields can be updated, for instance when labels change. =back » example: of cloning my $copy = $msg->clone; =item $class-EB(%options) Inherited, see L -Option --Default body undef body_type Mail::Message::Body::Lines deleted false field_type undef head undef head_type Mail::Message::Head::Complete labels +{} messageId undef message_id undef modified false trusted false =over 2 =item body => $object Instantiate the message with a body which has been created somewhere before the message is constructed. The C<$object> must be a sub-class of L. See also L and L. =item body_type => $class Default type of body to be created for L. =item deleted => BOOLEAN Is the file deleted from the start? =item field_type => $class =item head => $object Instantiate the message with a head which has been created somewhere before the message is constructed. The C<$object> must be a (sub-)class of L. See also L. =item head_type => $class Default type of head to be created for L. =item labels => \@pairs|\%settings Initial C<%settings> of the labels. In case of L type objectss, this shall reflect the state the message is in inside the folder. For newly constructed L objectss, this may be anything you want, because L will take care of the folder specifics once the message is added to one. =item messageId => $id Deprecated alternative to C. =item message_id => $id [4.05] The C<$id> string on which this message can be recognized. If none specified and not defined in the header --but one is needed-- there will be one assigned to the message to be able to pass unique message-ids between objects. =item modified => BOOLEAN Flags this message as being modified from the beginning on. Usually, modification is auto-detected, but there may be reasons to be extra explicit. =item trusted => BOOLEAN Is this message from a trusted source? If not, the content must be checked before use. This checking will be performed when the body data is decoded or used for transmission. =back =back =head2 Attributes Extends L<"Attributes" in Mail::Reporter|Mail::Reporter/"Attributes">. =over 4 =item $obj-EB() [4.05] The class to contain the text of normal bodies. This can be L (default, kept in an ARRAY of lines), L (kept in a single string), or L (kept externally in a file). The multipart and nested body types are not configured here. =item $obj-EB() [4.05] The class used to manange the field in the header. This is either L or L. Defaults to the preference of the used head class (C<::Fast>). =item $obj-EB() [4.05] The class used to administer the header fields. This is either L (default) or L. =item $obj-EB() Retrieve the message's id. Every message has a unique message-id. This id is used mainly for recognizing discussion threads. =back =head2 Constructing a message Complex construction of messages is implemented in different Perl modules, which have their own manual page. Although coded in separate files and described in separate manuals, they are all directly addressable from the L class. =over 4 =item $obj-EB( [<$rg_object|%options>] ) Inherited, see L =item $class-EB( [$message|$part|$body], @fields, %options ) Inherited, see L =item $class-EB($body, [$head], $headers) Inherited, see L =item $obj-EB(%options) Inherited, see L =item $obj-EB(%options) Inherited, see L =item $obj-EB(%options) Inherited, see L =item $obj-EB(%options) Inherited, see L =item $obj-EB(%options) Inherited, see L =item $obj-EB() Inherited, see L =item $obj-EB() Inherited, see L =item $obj-EB(STRING) Inherited, see L =item $class-EB($fh|$text|\$text|\@lines, %options) Inherited, see L =item $obj-EB(%options) Inherited, see L =item $obj-EB(%options) Inherited, see L =item $obj-EB( [STRING|$field|$address|\@addrs|\@fields] ) Inherited, see L =item $any-EB(STRING) Inherited, see L =back =head2 The message =over 4 =item $obj-EB() If the message is a part of another message, C returns the reference to the containing body. » example: my Mail::Message $msg = ... unless $msg->body->isMultipart or return; my $part = $msg->body->part(2); $part->body->isMultipart or return; my $nested = $part->body->part(3); $nested->container; # returns $msg->body $nested->toplevel; # returns $msg $msg->container; # returns undef $msg->toplevel; # returns $msg $msg->isPart; # returns false $part->isPart; # returns true =item $obj-EB() Return C when the printed message has a trailing "\n". In rare cases, that's not the case. For instance, when the body is read from a file which was generated without trailing new-line. =item $obj-EB() Dummy messages are used to fill holes in linked-list and such, where only a message-id is known, but not the place of the header of body data. This method is also available for L objects, where this will return C. On any extension of C, this will return C. =item $obj-EB() Returns C if the message is a part of another message. This is the case for L extensions of C. =item $obj-EB() Returns a string representing the location of this part. In case the top message is a single message, 'C' is returned. When it is a multipart, '1' up to the number of multiparts is returned. A multi-level nested part may for instance return '2.5.1'. Usually, this string is very short. Numbering follows the IMAP4 design, see RFC2060 section 6.4.5. =item $obj-EB( [$fh] ) Print the message to the C<$fh> (file handle), which defaults to the selected filehandle, without the encapsulation sometimes required by a folder » example: $message->print(\*STDERR); # to the error output $message->print; # to the selected file my $out = IO::File->new('out', 'w'); $message->print($out); # no encapsulation: no folder $message->write($out); # with encapsulation: is folder. =item $obj-EB( [$mailer], %options ) Transmit the message to anything outside this Perl program. Returns C when sending failed even after retries. The optional C<$mailer> is a L object. When the C<$mailer> is not specified, one will be created and kept as default for the next messages as well. The C<%options> are mailer specific, and a mixture of what is usable for the creation of the mailer object and the sending itself. Therefore, see for possible options L and L. That object also provides a C method which gives more low-level control. See C in the distribution of L. » example: $message->send; # is short (but little less flexibile) for my $mailer = Mail::Transport::SMTP->new(@smtpopts); $mailer->send($message, @sendopts); » example: $message->send(via => 'sendmail') =item $obj-EB() Returns an estimated size of the whole message in bytes. In many occasions, the functions which process the message further, for instance L or L will need to add/change header lines or add CR characters, so the size is only an estimate with a few percent margin of the real result. The computation assumes that each line ending is represented by one character (like UNIX, MacOS, and sometimes Cygwin), and not two characters (like Windows and sometimes Cygwin). If you write the message to file on a system which uses CR and LF to end a single line (all Windows versions), the result in that file will be at least L larger than this method returns. =item $obj-EB() Returns a reference to the main message, which will be the current message if the message is not part of another message. =item $obj-EB( [$fh] ) Write the message to the FILE-HANDLE, which defaults to the selected C<$fh>, with all surrounding information which is needed to put it correctly in a folder file. In most cases, the result of C will be the same as with L. The main exception is for Mbox folder messages, which will get printed with their leading 'From ' line and a trailing blank. Each line of their body which starts with 'From ' will have an 'E' added in front. =back =head2 The header =over 4 =item $obj-EB() Returns the addresses which are specified on the C header line (or lines) A list of L objects is returned. C stands for I: destinations of the message which are not listed in the messages actually sent. So, this field will be empty for received messages, but may be present in messages you construct yourself. =item $obj-EB() Returns the addresses which are specified on the C header line (or lines) A list of L objects is returned. C stands for I; the people addressed on this line receive the message informational, and are usually not expected to reply on its content. =item $obj-EB() Method has been removed for reasons of consistency. Use L or C<< $msg->head->get('Date') >>. =item $obj-EB() Returns a list of L objects which contains the combined info of active C, C, and C addresses. Double addresses are removed if detectable. =item $obj-EB() Returns the addresses from the senders. It is possible to have more than one address specified in the C field of the message, according to the specification. Therefore a list of L objects is returned, which usually has length 1. If you need only one address from a sender, for instance to create a "original message by" line in constructed forwarded message body, then use L. » example: using from() to get all sender addresses my @from = $message->from; =item $obj-EB($fieldname) Returns the value which is stored in the header field with the specified name. The C<$fieldname> is case insensitive. The I of the field is returned, stripped from any attributes. See L. If the field has multiple appearances in the header, only the last instance is returned. If you need more complex handing of fields, then call L yourself. See L when you want to be smart, doing the better (but slower) job. » example: the get() short-cut for header fields print $msg->get('Content-Type'), "\n"; # is equivalent to: print $msg->head->get('Content-Type')->body, "\n"; =item $obj-EB() Return an estimate on the time this message was sent. The data is derived from the header, where it can be derived from the C and C lines. For MBox-like folders you may get the date from the from-line as well. This method may return C if the header is not parsed or only partially known. If you require a time, then use the L method, described below. » example: using guessTimestamp() to get a transmission date print "Receipt ", ($message->timestamp || 'unknown'), "\n"; =item $obj-EB( [$head] ) Return (optionally after setting) the C<$head> of this message. The head must be an (sub-)class of L. When the head is added, status information is taken from it and transformed into labels. More labels can be added by the LABELS hash. They are added later. » example: my $header = Mail::Message::Head->new; $msg->head($header); # set my $head = $msg->head; # get =item $obj-EB() Returns the number of lines used for the whole message. =item $obj-EB() Returns exactly one address, which is the originator of this message. The returned L object is taken from the C header field, unless that field does not exists, in which case the first address from the C field is taken. If none of both provide an address, C is returned. » example: using sender() to get exactly one sender address my $sender = $message->sender; print "Reply to: ", $sender->format, "\n" if defined $sender; =item $obj-EB($fieldname) Study the content of a field, like L does, with as main difference that a L object is returned. These objects stringify to an utf8 decoded representation of the data contained in the field, where L does not decode. When the field does not exist, then C is returned. See L. » example: the study() short-cut for header fields print $msg->study('to'), "\n"; # is equivalent to: print $msg->head->study('to'), "\n"; # and print $msg->head->get('to')->study, "\n"; # or better: if(my $to = $msg->study('to')) { print "$to\n" } if(my $to = $msg->get('to')) { print $to->study, "\n" } =item $obj-EB() Returns the message's subject, or the empty string. The subject may have encoded characters in it; use L to get rit of that. » example: using subject() to get the message's subject print $msg->subject; print $msg->study('subject'); =item $obj-EB() Get a good timestamp for the message, doesn't matter how much work it is. The value returned is compatible with the platform dependent result of function time(). In these days, the timestamp as supplied by the message (in the C field) is not trustable at all: many spammers produce illegal or unreal dates to influence their location in the displayed folder. To start, the received headers are tried for a date (see L) and only then the C field. In very rare cases, only with some locally produced messages, no stamp can be found. =item $obj-EB() Returns the addresses which are specified on the C header line (or lines). A list of L objects is returned. The people addressed here are the targets of the content, and should read it contents carefully. » example: using to() to get all primar destination addresses my @to = $message->to; =back =head2 The body =over 4 =item $obj-EB( [$body] ) Return the body of this message. BE WARNED that this returns you an object which may be encoded: use decoded() to get a body with usable data. With options, a new C<$body> is set for this message. This is B for normal use unless you understand the consequences: you change the message content without changing the message-ID. The right way to go is via $message = Mail::Message->buildFromBody($body); # or $message = Mail::Message->build($body); # or $message = $origmsg->forward(body => $body); The C<$body> must be an (sub-)class of L. In this case, information from the specified body will be copied into the header. The body object will be encoded if needed, because messages written to file or transmitted shall not contain binary data. The converted body is returned. When C<$body> is C, the current message body will be dissected from the message. All relation will be cut. The body is returned, and can be connected to a different message. » example: my $body = $msg->body; my @encoded = $msg->body->lines; my $new = Mail::Message::Body->new(mime_type => 'text/html'); my $converted = $msg->body($new); =item $obj-EB() Returns the content type header line, or C if it is not defined. The parameters will be stripped off. =item $obj-EB(%options) Decodes the body of this message, and returns it as a body object. Short for C<< $msg->body->decoded >> All C<%options> are passed-on. =item $obj-EB(%options) Encode the message to a certain format. Read the details in the dedicated manual page L. The C<%options> which can be specified here are those of the L method. =item $obj-EB() Check whether this message is a multipart message (has attachments). To find this out, we need at least the header of the message; there is no need to read the body of the message to detect this. =item $obj-EB() Returns C for C messages and message parts. =item $obj-EB( [<'ALL'|'ACTIVE'|'DELETED'|'RECURSE'|$filter>] ) Returns the I of this message. Maybe a bit inconvenient: it returns the message itself when it is not a multipart. Usually, the term I is used with I messages: messages which are encapsulated in the body of a message. To abstract this concept: this method will return you all header-body combinations which are stored within this message B the multipart and message/rfc822 wrappers. Objects returned are C's and L's. The option default to 'C', which will return the message itself for single-parts, the nested content of a message/rfc822 object, respectively the parts of a multipart without recursion. In case of 'C', the parts of multiparts will be collected recursively. This option cannot be combined with the other options, which you may want: it that case you have to test yourself. 'C' and 'C' check for the deleted flag on messages and message parts. The C<$filter> is a code reference, which is called for each part of the message; each part as C would return. » example: my @parts = $msg->parts; # $msg not multipart: returns ($msg) my $parts = $msg->parts('ACTIVE'); # returns ($msg) $msg->delete; my @parts = $msg->parts; # returns ($msg) my $parts = $msg->parts('ACTIVE'); # returns () =back =head2 Flags =over 4 =item $obj-EB() Flag the message to be deleted, which is a shortcut for $msg->label(deleted => time); The real deletion only takes place on a synchronization of the folder. See L as well. The time stamp of the moment of deletion is stored as value, but that is not always preserved in the folder (depends on the implementation). When the same message is deleted more than once, the first time stamp will stay. » example: $message->delete; $message->deleted(1); # exactly the same $message->label(deleted => 1); delete $message; =item $obj-EB( [BOOLEAN] ) Set the delete flag for this message. Without argument, the method returns the same as L, which is preferred. When a C value is given, L is called. » example: $message->deleted(1); # delete $message->delete; # delete (preferred) $message->deleted(0); # undelete if($message->deleted) {...} # check if($message->isDeleted) {...} # check (preferred) =item $obj-EB() Short-cut for $msg->label('deleted') For some folder types, you will get the time of deletion in return. This depends on the implementation. » example: next if $message->isDeleted; if(my $when = $message->isDeleted) { print scalar localtime $when; } =item $obj-EB() Returns whether this message is flagged as being modified. Modifications are changes in header lines, when a new body is set to the message (dangerous), or when labels change. =item $obj-EB