diff options
| author | fukachan <fukachan> | 2018-01-01 03:24:59 +0000 |
|---|---|---|
| committer | fukachan <fukachan> | 2018-01-01 03:24:59 +0000 |
| commit | 3c4d0bcf412dde7975d734ddf893b554d560bb40 (patch) | |
| tree | 216e3ccdee539ffd1ec362c072e4aa1842fd4f4a | |
| parent | 44d6a143795090ec867a44ca5c1f5e1ae90e0664 (diff) | |
| download | fml8-3c4d0bcf412dde7975d734ddf893b554d560bb40.tar.gz fml8-3c4d0bcf412dde7975d734ddf893b554d560bb40.tar.bz2 fml8-3c4d0bcf412dde7975d734ddf893b554d560bb40.zip | |
Initial revision
36 files changed, 5368 insertions, 0 deletions
diff --git a/cpan/dist/MailTools/META.json b/cpan/dist/MailTools/META.json new file mode 100644 index 00000000..d07aa320 --- /dev/null +++ b/cpan/dist/MailTools/META.json @@ -0,0 +1,46 @@ +{ + "abstract" : "Various ancient e-mail related modules", + "author" : [ + "Mark Overmeer <perl@overmeer.net>" + ], + "dynamic_config" : 1, + "generated_by" : "ExtUtils::MakeMaker version 6.64, CPAN::Meta::Converter version 2.120630", + "license" : [ + "perl_5" + ], + "meta-spec" : { + "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", + "version" : 2 + }, + "name" : "MailTools", + "no_index" : { + "directory" : [ + "t", + "inc" + ] + }, + "prereqs" : { + "build" : { + "requires" : { + "ExtUtils::MakeMaker" : "0" + } + }, + "configure" : { + "requires" : { + "ExtUtils::MakeMaker" : "0" + } + }, + "runtime" : { + "requires" : { + "Date::Format" : "0", + "Date::Parse" : "0", + "IO::Handle" : "0", + "Net::Domain" : "1.05", + "Net::SMTP" : "1.03", + "Test::More" : "0" + } + } + }, + "release_status" : "stable", + "version" : "2.19" +} diff --git a/cpan/dist/MailTools/META.yml b/cpan/dist/MailTools/META.yml new file mode 100644 index 00000000..a3667ede --- /dev/null +++ b/cpan/dist/MailTools/META.yml @@ -0,0 +1,27 @@ +--- +abstract: 'Various ancient e-mail related modules' +author: + - 'Mark Overmeer <perl@overmeer.net>' +build_requires: + ExtUtils::MakeMaker: 0 +configure_requires: + ExtUtils::MakeMaker: 0 +dynamic_config: 1 +generated_by: 'ExtUtils::MakeMaker version 6.64, CPAN::Meta::Converter version 2.120630' +license: perl +meta-spec: + url: http://module-build.sourceforge.net/META-spec-v1.4.html + version: 1.4 +name: MailTools +no_index: + directory: + - t + - inc +requires: + Date::Format: 0 + Date::Parse: 0 + IO::Handle: 0 + Net::Domain: 1.05 + Net::SMTP: 1.03 + Test::More: 0 +version: 2.19 diff --git a/cpan/dist/MailTools/examples/mail-mailer.pl b/cpan/dist/MailTools/examples/mail-mailer.pl new file mode 100644 index 00000000..6f08cca0 --- /dev/null +++ b/cpan/dist/MailTools/examples/mail-mailer.pl @@ -0,0 +1,113 @@ +#!/usr/bin/perl -w + +# Note by Mark Overmeer: +# This script does work, but Mail::Send may provide a nicer interface + +# NAME +# mail-mailer.pl - Smtp client written in Perl +# +# SYNOPSIS +# mail-mailer.pl -s "Test" --smtp=my-smtp-server.com admin@net1.net +# +# INTRODUCTION +# This script can be an alternative to the 'mail' Unix command when +# sending e-mails. +# It reads the mail body from the standard input. +# If your system is Windows, use the '--smtp' option to send your +# e-mails. +# This script works in Linux, Unix and Windows environments. +# +# OPTIONS +# -f From +# -s Subject +# -c Cc-address +# -b bcc-address +# --sendmail Use sendmail to send the e-mail +# --qmail Use qmail-inject to send the e-mail +# --smtp=HOSTNAME Use HOSTNAME as the SMTP server. +# --help Prints the help info and exits +# +# EXAMPLES +# cat mailbody.txt | mail-mailer.pl -f me@mydom.com -s "Hy dude" --sendmail friend@dom.com +# +# AUTHOR +# Bruno Negrao G Zica <bnegrao@engepel.com.br> +# +# COPYRIGHT +# Copyright (c) 2004 Bruno Negrao G Zica. All rights reserved. +# This program is free software; you can redistribute it and/or modify +# it under the same terms as Perl itself. +# +# LAST MODIFIED +# 01/12/2004 +################################################################## +use Mail::Mailer; +use Getopt::Long; +use strict; + +# hash that'll receive the arguments and options +my %opt; +GetOptions ( \%opt, 'help', 'f=s', 's=s', 'c=s', 'b=s', 'sendmail', + 'qmail', 'smtp=s' ); + +if ($opt{help}) { help(); exit 0; } + +$opt{to} = $ARGV[$#ARGV]; # the "To" address is the last argument +die "Error: You didn't specify a destination e-mail address.\n" + unless ( $opt{to} || $opt{c} || $opt{b} ); + +# Defining the method to send the message +my $mailer; # Mail::Mailer object +if ($opt{sendmail}) { + $mailer = new Mail::Mailer 'sendmail'; +} elsif ($opt{qmail}) { + $mailer = new Mail::Mailer 'qmail'; +} elsif ($opt{smtp}) { + $mailer = new Mail::Mailer 'smtp', Server => $opt{smtp}; +} else { + die "Error: you didn't specify the delivery method. ". + "Possible methods are:\n'--qmail', '--sendmail', and ". + "--smtp=HOSTNAME\n"; +} +# Setting the headers +my %headers; # hash with the e-mail headers +$headers{To} = $opt{to}; +$headers{From} = $opt{f} if defined $opt{f}; +$headers{Cc} = $opt{c} if defined $opt{c}; +$headers{Bcc} = $opt{b} if defined $opt{b}; +$headers{Subject} = $opt{s} if defined $opt{s}; +$mailer->open(\%headers); + +# Reading and feeding the e-mail body +while (<STDIN>) { + last if ( $_ =~ /^\.$/ ); + print $mailer $_; +} + +# Finishing +$mailer->close(); + +# Subroutines +sub help { + print ' +Example 1: Entering the e-mail body by hand: +mail-mailer.pl -s "Hy buddy" --qmail friend@domain.com +[ ENTER YOU MESSAGE BODY ] +[ A SINGLE . (dot sign) ALONE IN ONE LINE TO SAY ] +[ YOU FINISHED YOUR E-MAIL ] +. + +Example 2: Using the output of another program as the body: +dir c:\ | perl mail-mailer.pl -f me@mydom.com -s "My c:\" admin@mydom.com --smtp=server1.mydom.com + +OPTIONS +-f addr From address. +-s TEXT Subject. +-c addr Cc-address. +-b addr bcc-address. +--sendmail Use sendmail to send the e-mail. +--qmail Use qmail-inject to send the e-mail. +--smtp HOSTNAME Use HOSTNAME as the SMTP server. +--help Prints this help text. +'; +} diff --git a/cpan/dist/MailTools/lib/Mail/Address.pm b/cpan/dist/MailTools/lib/Mail/Address.pm new file mode 100644 index 00000000..13b2ff7d --- /dev/null +++ b/cpan/dist/MailTools/lib/Mail/Address.pm @@ -0,0 +1,276 @@ +# Copyrights 1995-2017 by [Mark Overmeer <perl@overmeer.net>]. +# For other contributors see ChangeLog. +# See the manual pages for details on the licensing terms. +# Pod stripped from pm file by OODoc 2.02. +package Mail::Address; +use vars '$VERSION'; +$VERSION = '2.19'; + +use strict; + +use Carp; + +# use locale; removed in version 1.78, because it causes taint problems + +sub Version { our $VERSION } + + + +# given a comment, attempt to extract a person's name +sub _extract_name +{ # This function can be called as method as well + my $self = @_ && ref $_[0] ? shift : undef; + + local $_ = shift + or return ''; + + # Using encodings, too hard. See Mail::Message::Field::Full. + return '' if m/\=\?.*?\?\=/; + + # trim whitespace + s/^\s+//; + s/\s+$//; + s/\s+/ /; + + # Disregard numeric names (e.g. 123456.1234@compuserve.com) + return "" if /^[\d ]+$/; + + s/^\((.*)\)$/$1/; # remove outermost parenthesis + s/^"(.*)"$/$1/; # remove outer quotation marks + s/\(.*?\)//g; # remove minimal embedded comments + s/\\//g; # remove all escapes + s/^"(.*)"$/$1/; # remove internal quotation marks + s/^([^\s]+) ?, ?(.*)$/$2 $1/; # reverse "Last, First M." if applicable + s/,.*//; + + # Change casing only when the name contains only upper or only + # lower cased characters. + unless( m/[A-Z]/ && m/[a-z]/ ) + { # Set the case of the name to first char upper rest lower + s/\b(\w+)/\L\u$1/igo; # Upcase first letter on name + s/\bMc(\w)/Mc\u$1/igo; # Scottish names such as 'McLeod' + s/\bo'(\w)/O'\u$1/igo; # Irish names such as 'O'Malley, O'Reilly' + s/\b(x*(ix)?v*(iv)?i*)\b/\U$1/igo; # Roman numerals, eg 'Level III Support' + } + + # some cleanup + s/\[[^\]]*\]//g; + s/(^[\s'"]+|[\s'"]+$)//g; + s/\s{2,}/ /g; + + $_; +} + +sub _tokenise +{ local $_ = join ',', @_; + my (@words,$snippet,$field); + + s/\A\s+//; + s/[\r\n]+/ /g; + + while ($_ ne '') + { $field = ''; + if(s/^\s*\(/(/ ) # (...) + { my $depth = 0; + + PAREN: while(s/^(\(([^\(\)\\]|\\.)*)//) + { $field .= $1; + $depth++; + while(s/^(([^\(\)\\]|\\.)*\)\s*)//) + { $field .= $1; + last PAREN unless --$depth; + $field .= $1 if s/^(([^\(\)\\]|\\.)+)//; + } + } + + carp "Unmatched () '$field' '$_'" + if $depth; + + $field =~ s/\s+\Z//; + push @words, $field; + + next; + } + + if( s/^("(?:[^"\\]+|\\.)*")\s*// # "..." + || s/^(\[(?:[^\]\\]+|\\.)*\])\s*// # [...] + || s/^([^\s()<>\@,;:\\".[\]]+)\s*// + || s/^([()<>\@,;:\\".[\]])\s*// + ) + { push @words, $1; + next; + } + + croak "Unrecognised line: $_"; + } + + push @words, ","; + \@words; +} + +sub _find_next +{ my ($idx, $tokens, $len) = @_; + + while($idx < $len) + { my $c = $tokens->[$idx]; + return $c if $c eq ',' || $c eq ';' || $c eq '<'; + $idx++; + } + + ""; +} + +sub _complete +{ my ($class, $phrase, $address, $comment) = @_; + + @$phrase || @$comment || @$address + or return undef; + + my $o = $class->new(join(" ",@$phrase), join("",@$address), join(" ",@$comment)); + @$phrase = @$address = @$comment = (); + $o; +} + +#------------ + +sub new(@) +{ my $class = shift; + bless [@_], $class; +} + + +sub parse(@) +{ my $class = shift; + my @line = grep {defined} @_; + my $line = join '', @line; + + my (@phrase, @comment, @address, @objs); + my ($depth, $idx) = (0, 0); + + my $tokens = _tokenise @line; + my $len = @$tokens; + my $next = _find_next $idx, $tokens, $len; + + local $_; + for(my $idx = 0; $idx < $len; $idx++) + { $_ = $tokens->[$idx]; + + if(substr($_,0,1) eq '(') { push @comment, $_ } + elsif($_ eq '<') { $depth++ } + elsif($_ eq '>') { $depth-- if $depth } + elsif($_ eq ',' || $_ eq ';') + { warn "Unmatched '<>' in $line" if $depth; + my $o = $class->_complete(\@phrase, \@address, \@comment); + push @objs, $o if defined $o; + $depth = 0; + $next = _find_next $idx+1, $tokens, $len; + } + elsif($depth) { push @address, $_ } + elsif($next eq '<') { push @phrase, $_ } + elsif( /^[.\@:;]$/ || !@address || $address[-1] =~ /^[.\@:;]$/ ) + { push @address, $_ } + else + { warn "Unmatched '<>' in $line" if $depth; + my $o = $class->_complete(\@phrase, \@address, \@comment); + push @objs, $o if defined $o; + $depth = 0; + push @address, $_; + } + } + @objs; +} + +#------------ + +sub phrase { shift->set_or_get(0, @_) } +sub address { shift->set_or_get(1, @_) } +sub comment { shift->set_or_get(2, @_) } + +sub set_or_get($) +{ my ($self, $i) = (shift, shift); + @_ or return $self->[$i]; + + my $val = $self->[$i]; + $self->[$i] = shift if @_; + $val; +} + + +my $atext = '[\-\w !#$%&\'*+/=?^`{|}~]'; +sub format +{ my @addrs; + + foreach (@_) + { my ($phrase, $email, $comment) = @$_; + my @addr; + + if(defined $phrase && length $phrase) + { push @addr + , $phrase =~ /^(?:\s*$atext\s*)+$/o ? $phrase + : $phrase =~ /(?<!\\)"/ ? $phrase + : qq("$phrase"); + + push @addr, "<$email>" + if defined $email && length $email; + } + elsif(defined $email && length $email) + { push @addr, $email; + } + + if(defined $comment && $comment =~ /\S/) + { $comment =~ s/^\s*\(?/(/; + $comment =~ s/\)?\s*$/)/; + } + + push @addr, $comment + if defined $comment && length $comment; + + push @addrs, join(" ", @addr) + if @addr; + } + + join ", ", @addrs; +} + +#------------ + +sub name +{ my $self = shift; + my $phrase = $self->phrase; + my $addr = $self->address; + + $phrase = $self->comment + unless defined $phrase && length $phrase; + + my $name = $self->_extract_name($phrase); + + # first.last@domain address + if($name eq '' && $addr =~ /([^\%\.\@_]+([\._][^\%\.\@_]+)+)[\@\%]/) + { ($name = $1) =~ s/[\._]+/ /g; + $name = _extract_name $name; + } + + if($name eq '' && $addr =~ m#/g=#i) # X400 style address + { my ($f) = $addr =~ m#g=([^/]*)#i; + my ($l) = $addr =~ m#s=([^/]*)#i; + $name = _extract_name "$f $l"; + } + + length $name ? $name : undef; +} + + +sub host +{ my $addr = shift->address || ''; + my $i = rindex $addr, '@'; + $i >= 0 ? substr($addr, $i+1) : undef; +} + + +sub user +{ my $addr = shift->address || ''; + my $i = rindex $addr, '@'; + $i >= 0 ? substr($addr,0,$i) : $addr; +} + +1; diff --git a/cpan/dist/MailTools/lib/Mail/Address.pod b/cpan/dist/MailTools/lib/Mail/Address.pod new file mode 100644 index 00000000..e3eeb066 --- /dev/null +++ b/cpan/dist/MailTools/lib/Mail/Address.pod @@ -0,0 +1,164 @@ +=encoding utf8 + +=head1 NAME + +Mail::Address - parse mail addresses + +=head1 SYNOPSIS + + use Mail::Address; + my @addrs = Mail::Address->parse($line); + + foreach $addr (@addrs) { + print $addr->format,"\n"; + } + +=head1 DESCRIPTION + +C<Mail::Address> extracts and manipulates email addresses from a message +header. It cannot be used to extract addresses from some random text. +You can use this module to create RFC822 compliant fields. + +Although C<Mail::Address> is a very popular subject for books, and is +used in many applications, it does a very poor job on the more complex +message fields. It does only handle simple address formats (which +covers about 95% of what can be found). Problems are with + +=over 4 + +=item * + +no support for address groups, even not with the semi-colon as +separator between addresses; + +=item * + +limited support for escapes in phrases and comments. There are +cases where it can get wrong; and + +=item * + +you have to take care of most escaping when you create an address yourself: +C<Mail::Address> does not do that for you. + +=back + +Often requests are made to the maintainers of this code improve this +situation, but this is not a good idea, where it will break zillions +of existing applications. If you wish for a fully RFC2822 compliant +implementation you may take a look at L<Mail::Message::Field::Full>, +part of MailBox. + +B<. Example> + + my $s = Mail::Message::Field::Full->new($from_header); + # ref $s isa Mail::Message::Field::Addresses; + + my @g = $s->groups; # all groups, at least one + # ref $g[0] isa Mail::Message::Field::AddrGroup; + my $ga = $g[0]->addresses; # group addresses + + my @a = $s->addresses; # all addresses + # ref $a[0] isa Mail::Message::Field::Address; + +=head1 METHODS + +=head2 Constructors + +=over 4 + +=item Mail::Address-E<gt>B<new>( PHRASE, ADDRESS, [ COMMENT ] ) + +Create a new C<Mail::Address> object which represents an address with the +elements given. In a message these 3 elements would be seen like: + + PHRASE <ADDRESS> (COMMENT) + ADDRESS (COMMENT) + +example: + + Mail::Address->new("Perl5 Porters", "perl5-porters@africa.nicoh.com"); + +=item $obj-E<gt>B<parse>(LINE) + +Parse the given line a return a list of extracted C<Mail::Address> objects. +The line would normally be one taken from a To,Cc or Bcc line in a message + +example: + + my @addr = Mail::Address->parse($line); + +=back + +=head2 Accessors + +=over 4 + +=item $obj-E<gt>B<address>() + +Return the address part of the object. + +=item $obj-E<gt>B<comment>() + +Return the comment part of the object + +=item $obj-E<gt>B<format>( [ADDRESSes] ) + +Return a string representing the address in a suitable form to be placed +on a C<To>, C<Cc>, or C<Bcc> line of a message. This method is called on +the first ADDRESS to be used; other specified ADDRESSes will be appended, +separated with commas. + +=item $obj-E<gt>B<phrase>() + +Return the phrase part of the object. + +=back + +=head2 Smart accessors + +=over 4 + +=item $obj-E<gt>B<host>() + +Return the address excluding the user id and '@' + +=item $obj-E<gt>B<name>() + +Using the information contained within the object attempt to identify what +the person or groups name is. + +B<Note:> This function tries to be smart with the "phrase" of the +email address, which is probably a very bad idea. Consider to use +L<phrase()|Mail::Address/"Accessors"> itself. + +=item $obj-E<gt>B<user>() + +Return the address excluding the '@' and the mail domain + +=back + +=head1 SEE ALSO + +This module is part of the MailTools distribution, +F<http://perl.overmeer.net/mailtools/>. + +=head1 AUTHORS + +The MailTools bundle was developed by Graham Barr. Later, Mark +Overmeer took over maintenance without commitment to further development. + +Mail::Cap by Gisle Aas E<lt>aas@oslonett.noE<gt>. +Mail::Field::AddrList by Peter Orbaek E<lt>poe@cit.dkE<gt>. +Mail::Mailer and Mail::Send by Tim Bunce E<lt>Tim.Bunce@ig.co.ukE<gt>. +For other contributors see ChangeLog. + +=head1 LICENSE + +Copyrights 1995-2000 Graham Barr E<lt>gbarr@pobox.comE<gt> and +2001-2017 Mark Overmeer E<lt>perl@overmeer.netE<gt>. + +This program is free software; you can redistribute it and/or modify it +under the same terms as Perl itself. +See F<http://www.perl.com/perl/misc/Artistic.html> + diff --git a/cpan/dist/MailTools/lib/Mail/Cap.pm b/cpan/dist/MailTools/lib/Mail/Cap.pm new file mode 100644 index 00000000..12dbbb4f --- /dev/null +++ b/cpan/dist/MailTools/lib/Mail/Cap.pm @@ -0,0 +1,250 @@ +# Copyrights 1995-2017 by [Mark Overmeer <perl@overmeer.net>]. +# For other contributors see ChangeLog. +# See the manual pages for details on the licensing terms. +# Pod stripped from pm file by OODoc 2.02. +package Mail::Cap; +use vars '$VERSION'; +$VERSION = '2.19'; + +use strict; + +sub Version { our $VERSION } + + +our $useCache = 1; # don't evaluate tests every time + +my @path; +if($^O eq "MacOS") +{ @path = split /\,/, $ENV{MAILCAPS} || "$ENV{HOME}mailcap"; +} +else +{ @path = split /\:/ + , ( $ENV{MAILCAPS} || (defined $ENV{HOME} ? "$ENV{HOME}/.mailcap:" : '') + . '/etc/mailcap:/usr/etc/mailcap:/usr/local/etc/mailcap' + ); # this path is specified under RFC1524 appendix A +} + +#-------- + +sub new +{ my $class = shift; + + unshift @_, 'filename' if @_ % 2; + my %args = @_; + + my $take_all = $args{take} && uc $args{take} eq 'ALL'; + + my $self = bless {_count => 0}, $class; + + $self->_process_file($args{filename}) + if defined $args{filename} && -r $args{filename}; + + if(!defined $args{filename} || $take_all) + { foreach my $fname (@path) + { -r $fname or next; + + $self->_process_file($fname); + last unless $take_all; + } + } + + unless($self->{_count}) + { # Set up default mailcap + $self->{'audio/*'} = [{'view' => "showaudio %s"}]; + $self->{'image/*'} = [{'view' => "xv %s"}]; + $self->{'message/rfc822'} = [{'view' => "xterm -e metamail %s"}]; + } + + $self; +} + +sub _process_file +{ my $self = shift; + my $file = shift or return; + + local *MAILCAP; + open MAILCAP, $file + or return; + + $self->{_file} = $file; + + local $_; + while(<MAILCAP>) + { next if /^\s*#/; # comment + next if /^\s*$/; # blank line + $_ .= <MAILCAP> # continuation line + while s/(^|[^\\])((?:\\\\)*)\\\s*$/$1$2/; + chomp; + s/\0//g; # ensure no NULs in the line + s/(^|[^\\]);/$1\0/g; # make field separator NUL + my ($type, $view, @parts) = split /\s*\0\s*/; + + $type .= "/*" if $type !~ m[/]; + $view =~ s/\\;/;/g; + $view =~ s/\\\\/\\/g; + my %field = (view => $view); + + foreach (@parts) + { my($key, $val) = split /\s*\=\s*/, $_, 2; + if(defined $val) + { $val =~ s/\\;/;/g; + $val =~ s/\\\\/\\/g; + $field{$key} = $val; + } + else + { $field{$key} = 1; + } + } + + if(my $test = $field{test}) + { unless ($test =~ /\%/) + { # No parameters in test, can perform it right away + system $test; + next if $?; + } + } + + # record this entry + unless(exists $self->{$type}) + { $self->{$type} = []; + $self->{_count}++; + } + push @{$self->{$type}}, \%field; + } + + close MAILCAP; +} + +#------------------ + +sub view { my $self = shift; $self->_run($self->viewCmd(@_)) } +sub compose { my $self = shift; $self->_run($self->composeCmd(@_)) } +sub edit { my $self = shift; $self->_run($self->editCmd(@_)) } +sub print { my $self = shift; $self->_run($self->printCmd(@_)) } + +sub _run($) +{ my ($self, $cmd) = @_; + defined $cmd or return 0; + + system $cmd; + 1; +} + +#------------------ + +sub viewCmd { shift->_createCommand(view => @_) } +sub composeCmd { shift->_createCommand(compose => @_) } +sub editCmd { shift->_createCommand(edit => @_) } +sub printCmd { shift->_createCommand(print => @_) } + +sub _createCommand($$$) +{ my ($self, $method, $type, $file) = @_; + my $entry = $self->getEntry($type, $file); + + $entry && exists $entry->{$method} + or return undef; + + $self->expandPercentMacros($entry->{$method}, $type, $file); +} + +sub makeName($$) +{ my ($self, $type, $basename) = @_; + my $template = $self->nametemplate($type) + or return $basename; + + $template =~ s/%s/$basename/g; + $template; +} + +#------------------ + +sub field($$) +{ my($self, $type, $field) = @_; + my $entry = $self->getEntry($type); + $entry->{$field}; +} + + +sub description { shift->field(shift, 'description'); } +sub textualnewlines { shift->field(shift, 'textualnewlines'); } +sub x11_bitmap { shift->field(shift, 'x11-bitmap'); } +sub nametemplate { shift->field(shift, 'nametemplate'); } + +sub getEntry +{ my($self, $origtype, $file) = @_; + + return $self->{_cache}{$origtype} + if $useCache && exists $self->{_cache}{$origtype}; + + my ($fulltype, @params) = split /\s*;\s*/, $origtype; + my ($type, $subtype) = split m[/], $fulltype, 2; + $subtype ||= ''; + + my $entry; + foreach (@{$self->{"$type/$subtype"}}, @{$self->{"$type/*"}}) + { if(exists $_->{'test'}) + { # must run test to see if it applies + my $test = $self->expandPercentMacros($_->{'test'}, + $origtype, $file); + system $test; + next if $?; + } + $entry = { %$_ }; # make copy + last; + } + $self->{_cache}{$origtype} = $entry if $useCache; + $entry; +} + +sub expandPercentMacros +{ my ($self, $text, $type, $file) = @_; + defined $type or return $text; + defined $file or $file = ""; + + my ($fulltype, @params) = split /\s*;\s*/, $type; + ($type, my $subtype) = split m[/], $fulltype, 2; + + my %params; + foreach (@params) + { my($key, $val) = split /\s*=\s*/, $_, 2; + $params{$key} = $val; + } + $text =~ s/\\%/\0/g; # hide all escaped %'s + $text =~ s/%t/$fulltype/g; # expand %t + $text =~ s/%s/$file/g; # expand %s + { # expand %{field} + local $^W = 0; # avoid warnings when expanding %params + $text =~ s/%\{\s*(.*?)\s*\}/$params{$1}/g; + } + $text =~ s/\0/%/g; + $text; +} + +# This following procedures can be useful for debugging purposes + +sub dumpEntry +{ my($hash, $prefix) = @_; + defined $prefix or $prefix = ""; + print "$prefix$_ = $hash->{$_}\n" + for sort keys %$hash; +} + +sub dump +{ my $self = shift; + foreach (keys %$self) + { next if /^_/; + print "$_\n"; + foreach (@{$self->{$_}}) + { dumpEntry($_, "\t"); + print "\n"; + } + } + + if(exists $self->{_cache}) + { print "Cached types\n"; + print "\t$_\n" + for keys %{$self->{_cache}}; + } +} + +1; diff --git a/cpan/dist/MailTools/lib/Mail/Cap.pod b/cpan/dist/MailTools/lib/Mail/Cap.pod new file mode 100644 index 00000000..96db477b --- /dev/null +++ b/cpan/dist/MailTools/lib/Mail/Cap.pod @@ -0,0 +1,157 @@ +=encoding utf8 + +=head1 NAME + +Mail::Cap - understand mailcap files + +=head1 SYNOPSIS + + my $mc = Mail::Cap->new; + + my $desc = $mc->description('image/gif'); + print "GIF desc: $desc\n"; + + my $cmd = $mc->viewCmd('text/plain; charset=iso-8859-1', 'file.txt'); + +=head1 DESCRIPTION + +Parse mailcap files as specified in "RFC 1524 --A User Agent +Configuration Mechanism For Multimedia Mail Format Information>. In +the description below C<$type> refers to the MIME type as specified in +the C<Content-Type> header of mail or HTTP messages. Examples of +types are: + + image/gif + text/html + text/plain; charset=iso-8859-1 + +You could also take a look at the File::MimeInfo distribution, which +are accessing tables which are used by many applications on a system, +and therefore have succeeded the mail-cap specifications on modern +(UNIX) systems. + +=head1 METHODS + +=head2 Constructors + +=over 4 + +=item Mail::Cap-E<gt>B<new>(OPTIONS) + +Create and initialize a new Mail::Cap object. If you give it an +argument it will try to parse the specified file. Without any +arguments it will search for the mailcap file using the standard +mailcap path, or the MAILCAPS environment variable if it is defined. + + -Option --Default + filename undef + take 'FIRST' + +=over 2 + +=item filename => FILENAME + +Add the specified file to the list to standard locations. This file +is tried first. + +=item take => 'ALL'|'FIRST' + +Include all mailcap files you can find. By default, only the first +file is parsed, however the RFC tells us to include ALL. To maintain +backwards compatibility, the default only takes the FIRST. + +=back + +example: + + $mcap = new Mail::Cap; + $mcap = new Mail::Cap "/mydir/mailcap"; + $mcap = new Mail::Cap filename => "/mydir/mailcap"; + $mcap = new Mail::Cap take => 'ALL'; + $mcap = Mail::Cap->new(take => 'ALL'); + +=back + +=head2 Run commands + +These methods invoke a suitable program presenting or manipulating the +media object in the specified file. They all return C<1> if a command +was found, and C<0> otherwise. You might test C<$?> for the outcome +of the command. + +=over 4 + +=item $obj-E<gt>B<compose>(TYPE, FILE) + +=item $obj-E<gt>B<edit>(TYPE, FILE) + +=item $obj-E<gt>B<print>(TYPE, FILE) + +=item $obj-E<gt>B<view>(TYPE, FILE) + +=back + +=head2 Command creator + +These methods return a string that is suitable for feeding to system() +in order to invoke a suitable program presenting or manipulating the +media object in the specified file. It will return C<undef> if no +suitable specification exists. + +=over 4 + +=item $obj-E<gt>B<composeCmd>(TYPE, FILE) + +=item $obj-E<gt>B<editCmd>(TYPE, FILE) + +=item $obj-E<gt>B<printCmd>(TYPE, FILE) + +=item $obj-E<gt>B<viewCmd>(TYPE, FILE) + +=back + +=head2 Look-up definitions + +Methods return the corresponding mailcap field for the type. + +=over 4 + +=item $obj-E<gt>B<description>(TYPE) + +=item $obj-E<gt>B<field>(TYPE, FIELD) + +Returns the specified field for the type. Returns undef if no +specification exists. + +=item $obj-E<gt>B<nametemplate>(TYPE) + +=item $obj-E<gt>B<textualnewlines>(TYPE) + +=item $obj-E<gt>B<x11_bitmap>(TYPE) + +=back + +=head1 SEE ALSO + +This module is part of the MailTools distribution, +F<http://perl.overmeer.net/mailtools/>. + +=head1 AUTHORS + +The MailTools bundle was developed by Graham Barr. Later, Mark +Overmeer took over maintenance without commitment to further development. + +Mail::Cap by Gisle Aas E<lt>aas@oslonett.noE<gt>. +Mail::Field::AddrList by Peter Orbaek E<lt>poe@cit.dkE<gt>. +Mail::Mailer and Mail::Send by Tim Bunce E<lt>Tim.Bunce@ig.co.ukE<gt>. +For other contributors see ChangeLog. + +=head1 LICENSE + +Copyrights 1995-2000 Graham Barr E<lt>gbarr@pobox.comE<gt> and +2001-2017 Mark Overmeer E<lt>perl@overmeer.netE<gt>. + +This program is free software; you can redistribute it and/or modify it +under the same terms as Perl itself. +See F<http://www.perl.com/perl/misc/Artistic.html> + diff --git a/cpan/dist/MailTools/lib/Mail/Field.pm b/cpan/dist/MailTools/lib/Mail/Field.pm new file mode 100644 index 00000000..6b73823e --- /dev/null +++ b/cpan/dist/MailTools/lib/Mail/Field.pm @@ -0,0 +1,227 @@ +# Copyrights 1995-2017 by [Mark Overmeer <perl@overmeer.net>]. +# For other contributors see ChangeLog. +# See the manual pages for details on the licensing terms. +# Pod stripped from pm file by OODoc 2.02. +package Mail::Field; +use vars '$VERSION'; +$VERSION = '2.19'; + + +use strict; + +use Carp; +use Mail::Field::Generic; + + +sub _header_pkg_name +{ my $header = lc shift; + $header =~ s/((\b|_)\w)/\U$1/g; + + if(length($header) > 8) + { my @header = split /[-_]+/, $header; + my $chars = int((7 + @header) / @header) || 1; + $header = substr join('', map {substr $_,0,$chars} @header), 0, 8; + } + else + { $header =~ s/[-_]+//g; + } + + 'Mail::Field::' . $header; +} + +sub _require_dir +{ my($class, $dir, $dir_sep) = @_; + + local *DIR; + opendir DIR, $dir + or return; + + my @inc; + foreach my $f (readdir DIR) + { $f =~ /^([\w\-]+)/ or next; + my $p = $1; + my $n = "$dir$dir_sep$p"; + + if(-d $n ) + { _require_dir("${class}::$f", $n, $dir_sep); + } + else + { $p =~ s/-/_/go; + eval "require ${class}::$p"; + + # added next warning in 2.14, may be ignored for ancient code + warn $@ if $@; + } + } + closedir DIR; +} + +sub import +{ my $class = shift; + + if(@_) + { local $_; + eval "require " . _header_pkg_name($_) || die $@ + for @_; + return; + } + + my ($dir, $dir_sep); + foreach my $f (grep defined $INC{$_}, keys %INC) + { next if $f !~ /^Mail(\W)Field\W/i; + $dir_sep = $1; +# $dir = ($INC{$f} =~ /(.*Mail\W+Field)/i)[0] . $dir_sep; + ($dir = $INC{$f}) =~ s/(Mail\W+Field).*/$1$dir_sep/; + last; + } + + _require_dir('Mail::Field', $dir, $dir_sep); +} + +# register a header class, this creates a new method in Mail::Field +# which will call new on that class +sub register +{ my $thing = shift; + my $method = lc shift; + my $class = shift || ref($thing) || $thing; + + $method =~ tr/-/_/; + $class = _header_pkg_name $method + if $class eq "Mail::Field"; + + croak "Re-register of $method" + if Mail::Field->can($method); + + no strict 'refs'; + *{$method} = sub { + shift; + $class->can('stringify') or eval "require $class" or die $@; + $class->_build(@_); + }; +} + +# the *real* constructor +# if called with one argument then the `parse' method will be called +# otherwise the `create' method is called + +sub _build +{ my $self = bless {}, shift; + @_==1 ? $self->parse(@_) : $self->create(@_); +} + +#------------- + +sub new +{ my $class = shift; + my $field = lc shift; + $field =~ tr/-/_/; + $class->$field(@_); +} + + +sub combine {confess "Combine not implemented" } + +our $AUTOLOAD; +sub AUTOLOAD +{ my $method = $AUTOLOAD; + $method =~ s/.*:://; + + $method =~ /^[^A-Z\x00-\x1f\x80-\xff :]+$/ + or croak "Undefined subroutine &$AUTOLOAD called"; + + my $class = _header_pkg_name $method; + + unless(eval "require $class") + { my $tag = $method; + $tag =~ s/_/-/g; + $tag = join '-', + map { /^[b-df-hj-np-tv-z]+$|^MIME$/i ? uc($_) : ucfirst(lc $_) } + split /\-/, $tag; + + no strict; + @{"${class}::ISA"} = qw(Mail::Field::Generic); + *{"${class}::tag"} = sub { $tag }; + } + + Mail::Field->can($method) + or $class->register($method); + + goto &$AUTOLOAD; +} + + +# Of course, the functionality should have been in the Mail::Header class +sub extract +{ my ($class, $tag, $head) = (shift, shift, shift); + + my $method = lc $tag; + $method =~ tr/-/_/; + + if(@_==0 && wantarray) + { my @ret; + my $text; # need real copy! + foreach $text ($head->get($tag)) + { chomp $text; + push @ret, $class->$method($text); + } + return @ret; + } + + my $idx = shift || 0; + my $text = $head->get($tag,$idx) + or return undef; + + chomp $text; + $class->$method($text); +} + +#------------- + +# before 2.00, this method could be called as class method, however +# not all extensions supported that. +sub create +{ my ($self, %arg) = @_; + %$self = (); + $self->set(\%arg); +} + + +# before 2.00, this method could be called as class method, however +# not all extensions supported that. +sub parse +{ my $class = ref shift; + confess "parse() not implemented"; +} + +#------------- + +sub stringify { confess "stringify() not implemented" } + + +sub tag +{ my $thing = shift; + my $tag = ref($thing) || $thing; + $tag =~ s/.*:://; + $tag =~ s/_/-/g; + + join '-', + map { /^[b-df-hj-np-tv-z]+$|^MIME$/i ? uc($_) : ucfirst(lc $_) } + split /\-/, $tag; +} + + +sub set(@) { confess "set() not implemented" } + +# prevent the calling of AUTOLOAD for DESTROY :-) +sub DESTROY {} + +#------------- + +sub text +{ my $self = shift; + @_ ? $self->parse(@_) : $self->stringify; +} + +#------------- + +1; diff --git a/cpan/dist/MailTools/lib/Mail/Field.pod b/cpan/dist/MailTools/lib/Mail/Field.pod new file mode 100644 index 00000000..f8374a1b --- /dev/null +++ b/cpan/dist/MailTools/lib/Mail/Field.pod @@ -0,0 +1,196 @@ +=encoding utf8 + +=head1 NAME + +Mail::Field - base-class for manipulation of mail header fields + +=head1 INHERITANCE + + Mail::Field is extended by + Mail::Field::AddrList + Mail::Field::Date + Mail::Field::Generic + +=head1 SYNOPSIS + + use Mail::Field; + + my $field = Mail::Field->new('Subject', 'some subject text'); + my $field = Mail::Field->new(Subject => 'some subject text'); + print $field->tag,": ",$field->stringify,"\n"; + + my $field = Mail::Field->subject('some subject text'); + +=head1 DESCRIPTION + +C<Mail::Field> creates and manipulates fields in MIME headers, collected +within a L<Mail::Header|Mail::Header> object. Different field types have their +own sub-class (extension), defining additional useful accessors to the +field content. + +People are invited to merge their implementation to special fields into +MailTools, to maintain a consistent set of packages and documentation. + +=head1 METHODS + +=head2 Constructors + +Mail::Field (and it's sub-classes) define several methods which return +new objects. These can all be categorized as constructor. + +=over 4 + +=item Mail::Field-E<gt>B<combine>(FIELDS) + +Take a LIST of C<Mail::Field> objects (which should all be of the same +sub-class) and create a new object in that same class. + +=item Mail::Field-E<gt>B<extract>( TAG, HEAD [, INDEX ] ) + +Takes as arguments the tag name, a C<Mail::Head> object +and optionally an index. + +If the index argument is given then C<extract> will retrieve the given tag +from the C<Mail::Head> object and create a new C<Mail::Field> based object. +I<undef> will be returned in the field does not exist. + +If the index argument is not given the result depends on the context +in which C<extract> is called. If called in a scalar context the result +will be as if C<extract> was called with an index value of zero. If called +in an array context then all tags will be retrieved and a list of +C<Mail::Field> objects will be returned. + +=item Mail::Field-E<gt>B<new>( TAG [, STRING | OPTIONS] ) + +Create an object in the class which defines the field specified by +the TAG argument. + +=back + +=head2 "Fake" constructors + +=over 4 + +=item $obj-E<gt>B<create>(OPTIONS) + +This constructor is used internally with preprocessed field information. +When called on an existing object, its original content will get +replaced. + +=item $obj-E<gt>B<parse>() + +Parse a field line. + +=back + +=head2 Accessors + +=over 4 + +=item $obj-E<gt>B<set>(OPTIONS) + +Change the settings (the content, but then smart) of this field. + +=item $obj-E<gt>B<stringify>() + +Returns the field as a string. + +=item $obj-E<gt>B<tag>() + +=item Mail::Field-E<gt>B<tag>() + +Return the tag (in the correct case) for this item. Well, actually any +casing is OK, because the field tags are treated case-insensitive; however +people have some preferences. + +=back + +=head2 Smart accessors + +=over 4 + +=item $obj-E<gt>B<text>( [STRING] ) + +Without arguments, the field is returned as L<stringify()|Mail::Field/"Accessors"> does. Otherwise, +the STRING is parsed with L<parse()|Mail::Field/""Fake" constructors"> to replace the object's content. + +It is more clear to call either L<stringify()|Mail::Field/"Accessors"> or L<parse()|Mail::Field/""Fake" constructors"> directly, because +this method does not add additional processing. + +=back + +=head1 DETAILS + +=head2 SUB-CLASS PACKAGE NAMES + +All sub-classes should be called Mail::Field::I<name> where I<name> is +derived from the tag using these rules. + +=over 4 + +=item * + +Consider a tag as being made up of elements separated by '-' + +=item * + +Convert all characters to lowercase except the first in each element, which +should be uppercase. + +=item * + +I<name> is then created from these elements by using the first +N characters from each element. + +=item * + +N is calculated by using the formula :- + + int((7 + #elements) / #elements) + +=item * + +I<name> is then limited to a maximum of 8 characters, keeping the first 8 +characters. + +=back + +For an example of this take a look at the definition of the +C<_header_pkg_name()> subroutine in C<Mail::Field> + +=head1 DIAGNOSTICS + +=over 4 + +=item Error: Undefined subroutine <method> called + +Mail::Field objects use autoloading to compile new functionality. +Apparently, the method called is not implemented for the specific +class of the field object. + +=back + +=head1 SEE ALSO + +This module is part of the MailTools distribution, +F<http://perl.overmeer.net/mailtools/>. + +=head1 AUTHORS + +The MailTools bundle was developed by Graham Barr. Later, Mark +Overmeer took over maintenance without commitment to further development. + +Mail::Cap by Gisle Aas E<lt>aas@oslonett.noE<gt>. +Mail::Field::AddrList by Peter Orbaek E<lt>poe@cit.dkE<gt>. +Mail::Mailer and Mail::Send by Tim Bunce E<lt>Tim.Bunce@ig.co.ukE<gt>. +For other contributors see ChangeLog. + +=head1 LICENSE + +Copyrights 1995-2000 Graham Barr E<lt>gbarr@pobox.comE<gt> and +2001-2017 Mark Overmeer E<lt>perl@overmeer.netE<gt>. + +This program is free software; you can redistribute it and/or modify it +under the same terms as Perl itself. +See F<http://www.perl.com/perl/misc/Artistic.html> + diff --git a/cpan/dist/MailTools/lib/Mail/Field/AddrList.pm b/cpan/dist/MailTools/lib/Mail/Field/AddrList.pm new file mode 100644 index 00000000..3887b87e --- /dev/null +++ b/cpan/dist/MailTools/lib/Mail/Field/AddrList.pm @@ -0,0 +1,68 @@ +# Copyrights 1995-2017 by [Mark Overmeer <perl@overmeer.net>]. +# For other contributors see ChangeLog. +# See the manual pages for details on the licensing terms. +# Pod stripped from pm file by OODoc 2.02. +use strict; + +package Mail::Field::AddrList; +use vars '$VERSION'; +$VERSION = '2.19'; + +use base 'Mail::Field'; + +use Carp; +use Mail::Address; + + +my $x = bless []; +$x->register('To'); +$x->register('From'); +$x->register('Cc'); +$x->register('Reply-To'); +$x->register('Sender'); + +sub create(@) +{ my ($self, %arg) = @_; + $self->{AddrList} = {}; + + while(my ($e, $n) = each %arg) + { $self->{AddrList}{$e} = Mail::Address->new($n, $e); + } + + $self; +} + +sub parse($) +{ my ($self, $string) = @_; + foreach my $a (Mail::Address->parse($string)) + { my $e = $a->address; + $self->{AddrList}{$e} = $a; + } + $self; +} + +sub stringify() +{ my $self = shift; + join(", ", map { $_->format } values %{$self->{AddrList}}); +} + + +sub addresses { keys %{shift->{AddrList}} } + + +# someone forgot to implement a method to return the Mail::Address +# objects. Added in 2.00; a pity that the name addresses() is already +# given :( That one should have been named emails() +sub addr_list { values %{shift->{AddrList}} } + + +sub names { map { $_->name } values %{shift->{AddrList}} } + + +sub set_address($$) +{ my ($self, $email, $name) = @_; + $self->{AddrList}{$email} = Mail::Address->new($name, $email); + $self; +} + +1; diff --git a/cpan/dist/MailTools/lib/Mail/Field/AddrList.pod b/cpan/dist/MailTools/lib/Mail/Field/AddrList.pod new file mode 100644 index 00000000..a42091fd --- /dev/null +++ b/cpan/dist/MailTools/lib/Mail/Field/AddrList.pod @@ -0,0 +1,175 @@ +=encoding utf8 + +=head1 NAME + +Mail::Field::AddrList - object representation of e-mail address lists + +=head1 INHERITANCE + + Mail::Field::AddrList + is a Mail::Field + +=head1 SYNOPSIS + + use Mail::Field::AddrList; + + $to = Mail::Field->new('To'); + $from = Mail::Field->new('From', 'poe@daimi.aau.dk (Peter Orbaek)'); + + $from->create('foo@bar.com' => 'Mr. Foo', poe => 'Peter'); + $from->parse('foo@bar.com (Mr Foo), Peter Orbaek <poe>'); + + # make a RFC822 header string + print $from->stringify(),"\n"; + + # extract e-mail addresses and names + @addresses = $from->addresses(); # strings + @names = $from->names(); # strings + @addr = $from->addr_list(); # Mail::Address objects (v2.00) + + # adjoin a new address to the list + $from->set_address('foo@bar.com', 'Mr. Foo'); + +=head1 DESCRIPTION + +Defines parsing and formatting of address field, for the following +fields: C<To>, C<From>, C<Cc>, C<Reply-To>, and C<Sender>. + +All the normally used features of the address field specification of +RFC2822 are implemented, but some complex (and therefore hardly ever used) +constructs will not be understood. Use Mail::Message::Field::Full +in MailBox if you need full RFC compliance. + +Extends L<"DESCRIPTION" in Mail::Field|Mail::Field/"DESCRIPTION">. + +=head1 METHODS + +Extends L<"METHODS" in Mail::Field|Mail::Field/"METHODS">. + +=head2 Constructors + +Extends L<"Constructors" in Mail::Field|Mail::Field/"Constructors">. + +=over 4 + +=item Mail::Field::AddrList-E<gt>B<combine>(FIELDS) + +Inherited, see L<Mail::Field/"Constructors"> + +=item Mail::Field::AddrList-E<gt>B<extract>( TAG, HEAD [, INDEX ] ) + +Inherited, see L<Mail::Field/"Constructors"> + +=item Mail::Field::AddrList-E<gt>B<new>( TAG [, STRING | OPTIONS] ) + +Inherited, see L<Mail::Field/"Constructors"> + +=back + +=head2 "Fake" constructors + +Extends L<""Fake" constructors" in Mail::Field|Mail::Field/""Fake" constructors">. + +=over 4 + +=item $obj-E<gt>B<create>(OPTIONS) + +Inherited, see L<Mail::Field/""Fake" constructors"> + +=item $obj-E<gt>B<parse>() + +Inherited, see L<Mail::Field/""Fake" constructors"> + +=back + +=head2 Accessors + +Extends L<"Accessors" in Mail::Field|Mail::Field/"Accessors">. + +=over 4 + +=item $obj-E<gt>B<set>(OPTIONS) + +Inherited, see L<Mail::Field/"Accessors"> + +=item $obj-E<gt>B<stringify>() + +Inherited, see L<Mail::Field/"Accessors"> + +=item $obj-E<gt>B<tag>() + +=item Mail::Field::AddrList-E<gt>B<tag>() + +Inherited, see L<Mail::Field/"Accessors"> + +=back + +=head2 Smart accessors + +Extends L<"Smart accessors" in Mail::Field|Mail::Field/"Smart accessors">. + +=over 4 + +=item $obj-E<gt>B<addr_list>() + +Returns the collected L<Mail::Address|Mail::Address> objects. + +=item $obj-E<gt>B<addresses>() + +Returns a list if email addresses, found in the field content. + +=item $obj-E<gt>B<names>() + +Returns a list of nicely formatted named, for each of the addresses +found in the content. + +=item $obj-E<gt>B<set_address>(EMAIL, NAME) + +Add/replace an EMAIL address to the field. + +=item $obj-E<gt>B<text>( [STRING] ) + +Inherited, see L<Mail::Field/"Smart accessors"> + +=back + +=head1 DETAILS + +Extends L<"DETAILS" in Mail::Field|Mail::Field/"DETAILS">. + +=head1 DIAGNOSTICS + +=over 4 + +=item Error: Undefined subroutine <method> called + +Mail::Field objects use autoloading to compile new functionality. +Apparently, the method called is not implemented for the specific +class of the field object. + +=back + +=head1 SEE ALSO + +This module is part of the MailTools distribution, +F<http://perl.overmeer.net/mailtools/>. + +=head1 AUTHORS + +The MailTools bundle was developed by Graham Barr. Later, Mark +Overmeer took over maintenance without commitment to further development. + +Mail::Cap by Gisle Aas E<lt>aas@oslonett.noE<gt>. +Mail::Field::AddrList by Peter Orbaek E<lt>poe@cit.dkE<gt>. +Mail::Mailer and Mail::Send by Tim Bunce E<lt>Tim.Bunce@ig.co.ukE<gt>. +For other contributors see ChangeLog. + +=head1 LICENSE + +Copyrights 1995-2000 Graham Barr E<lt>gbarr@pobox.comE<gt> and +2001-2017 Mark Overmeer E<lt>perl@overmeer.netE<gt>. + +This program is free software; you can redistribute it and/or modify it +under the same terms as Perl itself. +See F<http://www.perl.com/perl/misc/Artistic.html> + diff --git a/cpan/dist/MailTools/lib/Mail/Field/Date.pm b/cpan/dist/MailTools/lib/Mail/Field/Date.pm new file mode 100644 index 00000000..303d0ecc --- /dev/null +++ b/cpan/dist/MailTools/lib/Mail/Field/Date.pm @@ -0,0 +1,62 @@ +# Copyrights 1995-2017 by [Mark Overmeer <perl@overmeer.net>]. +# For other contributors see ChangeLog. +# See the manual pages for details on the licensing terms. +# Pod stripped from pm file by OODoc 2.02. +use strict; + +package Mail::Field::Date; +use vars '$VERSION'; +$VERSION = '2.19'; + +use base 'Mail::Field'; + +use Date::Format qw(time2str); +use Date::Parse qw(str2time); + +(bless [])->register('Date'); + + +sub set() +{ my $self = shift; + my $arg = @_ == 1 ? shift : { @_ }; + + foreach my $s (qw(Time TimeStr)) + { if(exists $arg->{$s}) + { $self->{$s} = $arg->{$s} } + else { delete $self->{$s} } + } + + $self; +} + +sub parse($) +{ my $self = shift; + delete $self->{Time}; + $self->{TimeStr} = shift; + $self; +} + + +sub time(;$) +{ my $self = shift; + + if(@_) + { delete $self->{TimeStr}; + return $self->{Time} = shift; + } + + $self->{Time} ||= str2time $self->{TimeStr}; +} + +sub stringify +{ my $self = shift; + $self->{TimeStr} ||= time2str("%a, %e %b %Y %T %z", $self->time); +} + +sub reformat +{ my $self = shift; + $self->time($self->time); + $self->stringify; +} + +1; diff --git a/cpan/dist/MailTools/lib/Mail/Field/Date.pod b/cpan/dist/MailTools/lib/Mail/Field/Date.pod new file mode 100644 index 00000000..2a41e19f --- /dev/null +++ b/cpan/dist/MailTools/lib/Mail/Field/Date.pod @@ -0,0 +1,152 @@ +=encoding utf8 + +=head1 NAME + +Mail::Field::Date - a date header field + +=head1 INHERITANCE + + Mail::Field::Date + is a Mail::Field + +=head1 SYNOPSIS + + use HTTP::Date 'time2iso'; + my $field = Mail::Field->new(Date => time2iso()); + +=head1 DESCRIPTION + +Represents one "Date" header field. + +Extends L<"DESCRIPTION" in Mail::Field|Mail::Field/"DESCRIPTION">. + +=head1 METHODS + +Extends L<"METHODS" in Mail::Field|Mail::Field/"METHODS">. + +=head2 Constructors + +Extends L<"Constructors" in Mail::Field|Mail::Field/"Constructors">. + +=over 4 + +=item Mail::Field::Date-E<gt>B<combine>(FIELDS) + +Inherited, see L<Mail::Field/"Constructors"> + +=item Mail::Field::Date-E<gt>B<extract>( TAG, HEAD [, INDEX ] ) + +Inherited, see L<Mail::Field/"Constructors"> + +=item Mail::Field::Date-E<gt>B<new>( TAG [, STRING | OPTIONS] ) + +Inherited, see L<Mail::Field/"Constructors"> + +=back + +=head2 "Fake" constructors + +Extends L<""Fake" constructors" in Mail::Field|Mail::Field/""Fake" constructors">. + +=over 4 + +=item $obj-E<gt>B<create>(OPTIONS) + +Inherited, see L<Mail::Field/""Fake" constructors"> + +=item $obj-E<gt>B<parse>() + +Inherited, see L<Mail::Field/""Fake" constructors"> + +=back + +=head2 Accessors + +Extends L<"Accessors" in Mail::Field|Mail::Field/"Accessors">. + +=over 4 + +=item $obj-E<gt>B<set>(OPTIONS) + + -Option --Default + Time undef + TimeStr undef + +=over 2 + +=item Time => SECONDS + +=item TimeStr => STRING + +A string acceptable to Date::Parse. + +=back + +=item $obj-E<gt>B<stringify>() + +Inherited, see L<Mail::Field/"Accessors"> + +=item $obj-E<gt>B<tag>() + +=item Mail::Field::Date-E<gt>B<tag>() + +Inherited, see L<Mail::Field/"Accessors"> + +=back + +=head2 Smart accessors + +Extends L<"Smart accessors" in Mail::Field|Mail::Field/"Smart accessors">. + +=over 4 + +=item $obj-E<gt>B<text>( [STRING] ) + +Inherited, see L<Mail::Field/"Smart accessors"> + +=item $obj-E<gt>B<time>( [TIME] ) + +Query (or change) the TIME (as stored in the field) in seconds. + +=back + +=head1 DETAILS + +Extends L<"DETAILS" in Mail::Field|Mail::Field/"DETAILS">. + +=head1 DIAGNOSTICS + +=over 4 + +=item Error: Undefined subroutine <method> called + +Mail::Field objects use autoloading to compile new functionality. +Apparently, the method called is not implemented for the specific +class of the field object. + +=back + +=head1 SEE ALSO + +This module is part of the MailTools distribution, +F<http://perl.overmeer.net/mailtools/>. + +=head1 AUTHORS + +The MailTools bundle was developed by Graham Barr. Later, Mark +Overmeer took over maintenance without commitment to further development. + +Mail::Cap by Gisle Aas E<lt>aas@oslonett.noE<gt>. +Mail::Field::AddrList by Peter Orbaek E<lt>poe@cit.dkE<gt>. +Mail::Mailer and Mail::Send by Tim Bunce E<lt>Tim.Bunce@ig.co.ukE<gt>. +For other contributors see ChangeLog. + +=head1 LICENSE + +Copyrights 1995-2000 Graham Barr E<lt>gbarr@pobox.comE<gt> and +2001-2017 Mark Overmeer E<lt>perl@overmeer.netE<gt>. + +This program is free software; you can redistribute it and/or modify it +under the same terms as Perl itself. +See F<http://www.perl.com/perl/misc/Artistic.html> + diff --git a/cpan/dist/MailTools/lib/Mail/Field/Generic.pm b/cpan/dist/MailTools/lib/Mail/Field/Generic.pm new file mode 100644 index 00000000..2a9d193c --- /dev/null +++ b/cpan/dist/MailTools/lib/Mail/Field/Generic.pm @@ -0,0 +1,33 @@ +# Copyrights 1995-2017 by [Mark Overmeer <perl@overmeer.net>]. +# For other contributors see ChangeLog. +# See the manual pages for details on the licensing terms. +# Pod stripped from pm file by OODoc 2.02. +package Mail::Field::Generic; +use vars '$VERSION'; +$VERSION = '2.19'; + + +use Carp; +use base 'Mail::Field'; + + +sub create +{ my ($self, %arg) = @_; + $self->{Text} = delete $arg{Text}; + + croak "Unknown options " . join(",", keys %arg) + if %arg; + + $self; +} + + +sub parse +{ my $self = shift; + $self->{Text} = shift || ""; + $self; +} + +sub stringify { shift->{Text} } + +1; diff --git a/cpan/dist/MailTools/lib/Mail/Field/Generic.pod b/cpan/dist/MailTools/lib/Mail/Field/Generic.pod new file mode 100644 index 00000000..cdb90560 --- /dev/null +++ b/cpan/dist/MailTools/lib/Mail/Field/Generic.pod @@ -0,0 +1,147 @@ +=encoding utf8 + +=head1 NAME + +Mail::Field::Generic - implementation for inspecific fields + +=head1 INHERITANCE + + Mail::Field::Generic + is a Mail::Field + +=head1 SYNOPSIS + + use Mail::Field; + my $field = Mail::Field->new('Subject', 'some subject text'); + my $field = Mail::Field->new(subject => 'some subject text'); + +=head1 DESCRIPTION + +A generic implementation for header fields without own +implementation. This is fine for fields like C<Subject>, C<X-Mailer>, +etc., where the field holds only a string of no particular +importance/format. + +Extends L<"DESCRIPTION" in Mail::Field|Mail::Field/"DESCRIPTION">. + +=head1 METHODS + +Extends L<"METHODS" in Mail::Field|Mail::Field/"METHODS">. + +=head2 Constructors + +Extends L<"Constructors" in Mail::Field|Mail::Field/"Constructors">. + +=over 4 + +=item Mail::Field::Generic-E<gt>B<combine>(FIELDS) + +Inherited, see L<Mail::Field/"Constructors"> + +=item Mail::Field::Generic-E<gt>B<extract>( TAG, HEAD [, INDEX ] ) + +Inherited, see L<Mail::Field/"Constructors"> + +=item Mail::Field::Generic-E<gt>B<new>( TAG [, STRING | OPTIONS] ) + +Inherited, see L<Mail::Field/"Constructors"> + +=back + +=head2 "Fake" constructors + +Extends L<""Fake" constructors" in Mail::Field|Mail::Field/""Fake" constructors">. + +=over 4 + +=item $obj-E<gt>B<create>(OPTIONS) + + -Option--Default + Text '' + +=over 2 + +=item Text => STRING + +=back + +=item $obj-E<gt>B<parse>( [STRING] ) + +Set the new text, which is empty when no STRING is provided. + +=back + +=head2 Accessors + +Extends L<"Accessors" in Mail::Field|Mail::Field/"Accessors">. + +=over 4 + +=item $obj-E<gt>B<set>(OPTIONS) + +Inherited, see L<Mail::Field/"Accessors"> + +=item $obj-E<gt>B<stringify>() + +Inherited, see L<Mail::Field/"Accessors"> + +=item $obj-E<gt>B<tag>() + +=item Mail::Field::Generic-E<gt>B<tag>() + +Inherited, see L<Mail::Field/"Accessors"> + +=back + +=head2 Smart accessors + +Extends L<"Smart accessors" in Mail::Field|Mail::Field/"Smart accessors">. + +=over 4 + +=item $obj-E<gt>B<text>( [STRING] ) + +Inherited, see L<Mail::Field/"Smart accessors"> + +=back + +=head1 DETAILS + +Extends L<"DETAILS" in Mail::Field|Mail::Field/"DETAILS">. + +=head1 DIAGNOSTICS + +=over 4 + +=item Error: Undefined subroutine <method> called + +Mail::Field objects use autoloading to compile new functionality. +Apparently, the method called is not implemented for the specific +class of the field object. + +=back + +=head1 SEE ALSO + +This module is part of the MailTools distribution, +F<http://perl.overmeer.net/mailtools/>. + +=head1 AUTHORS + +The MailTools bundle was developed by Graham Barr. Later, Mark +Overmeer took over maintenance without commitment to further development. + +Mail::Cap by Gisle Aas E<lt>aas@oslonett.noE<gt>. +Mail::Field::AddrList by Peter Orbaek E<lt>poe@cit.dkE<gt>. +Mail::Mailer and Mail::Send by Tim Bunce E<lt>Tim.Bunce@ig.co.ukE<gt>. +For other contributors see ChangeLog. + +=head1 LICENSE + +Copyrights 1995-2000 Graham Barr E<lt>gbarr@pobox.comE<gt> and +2001-2017 Mark Overmeer E<lt>perl@overmeer.netE<gt>. + +This program is free software; you can redistribute it and/or modify it +under the same terms as Perl itself. +See F<http://www.perl.com/perl/misc/Artistic.html> + diff --git a/cpan/dist/MailTools/lib/Mail/Filter.pm b/cpan/dist/MailTools/lib/Mail/Filter.pm new file mode 100644 index 00000000..05320f9d --- /dev/null +++ b/cpan/dist/MailTools/lib/Mail/Filter.pm @@ -0,0 +1,70 @@ +# Copyrights 1995-2017 by [Mark Overmeer <perl@overmeer.net>]. +# For other contributors see ChangeLog. +# See the manual pages for details on the licensing terms. +# Pod stripped from pm file by OODoc 2.02. +package Mail::Filter; +use vars '$VERSION'; +$VERSION = '2.19'; + + +use strict; +use Carp; + + +sub new(@) +{ my $class = shift; + bless { filters => [ @_ ] }, $class; +} + +#------------ + +sub add(@) +{ my $self = shift; + push @{$self->{filters}}, @_; +} + +#------------ + +sub _filter($) +{ my ($self, $mail) = @_; + + foreach my $sub ( @{$self->{filters}} ) + { my $mail + = ref $sub eq 'CODE' ? $sub->($self,$mail) + : !ref $sub ? $self->$sub($mail) + : carp "Cannot call filter '$sub', ignored"; + + ref $mail or last; + } + + $mail; +} + +sub filter +{ my ($self, $obj) = @_; + if($obj->isa('Mail::Folder')) + { $self->{folder} = $obj; + foreach my $m ($obj->message_list) + { my $mail = $obj->get_message($m) or next; + $self->{msgnum} = $m; + $self->_filter($mail); + } + delete $self->{folder}; + delete $self->{msgnum}; + } + elsif($obj->isa('Mail::Internet')) + { return $self->filter($obj); + } + else + { carp "Cannot process '$obj'"; + return undef; + } +} + + +sub folder() {shift->{folder}} + + +sub msgnum() {shift->{msgnum}} + +1; diff --git a/cpan/dist/MailTools/lib/Mail/Filter.pod b/cpan/dist/MailTools/lib/Mail/Filter.pod new file mode 100644 index 00000000..e4397c72 --- /dev/null +++ b/cpan/dist/MailTools/lib/Mail/Filter.pod @@ -0,0 +1,106 @@ +=encoding utf8 + +=head1 NAME + +Mail::Filter - filter mail through multiple subroutines + +=head1 SYNOPSIS + + use Mail::Filter; + + my $filter = Mail::Filter->new( \&filter1, \&filter2 ); + + my $mail = Mail::Internet->new( [<>] ); + my $mail = $filter->filter($mail); + + my $folder = Mail::Folder->new( .... ); + my $filter->filter($folder); + +=head1 DESCRIPTION + +C<Mail::Filter> provides an interface to filtering Email through multiple +subroutines. + +C<Mail::Filter> filters mail by calling each filter subroutine in turn. Each +filter subroutine is called with two arguments, the first is the filter +object and the second is the mail or folder object being filtered. + +The result from each filter sub is passed to the next filter as the mail +object. If a filter subroutine returns undef, then C<Mail::Filter> will abort +and return immediately. + +The function returns the result from the last subroutine to operate on the +mail object. + +=head1 METHODS + +=head2 Constructors + +=over 4 + +=item Mail::Filter-E<gt>B<new>( [FILTER [, ... ]] ) + +Create a new C<Mail::Filter> object with the given filter subroutines. Each +filter may be either a code reference or the name of a method to call +on the <Mail::Filter> object. + +=back + +=head2 Accessors + +=over 4 + +=item $obj-E<gt>B<add>( FILTER [, FILTER ...] ) + +Add the given filters to the end of the filter list. + +=back + +=head2 Processing + +=over 4 + +=item $obj-E<gt>B<filter>(MAIL-OBJECT | MAIL-FOLDER) + +If the first argument is a C<Mail::Internet> object, then this object will +be passed through the filter list. If the first argument is a C<Mail::Folder> +object, then each message in turn will be passed through the filter list. + +=item $obj-E<gt>B<folder>() + +While the C<filter> method is called with a C<Mail::Folder> object, these +filter subroutines can call this method to obtain the folder object that is +being processed. + +=item $obj-E<gt>B<msgnum>() + +If the C<filter> method is called with a C<Mail::Folder> object, then the +filter subroutines may call this method to obtain the message number +of the message that is being processed. + +=back + +=head1 SEE ALSO + +This module is part of the MailTools distribution, +F<http://perl.overmeer.net/mailtools/>. + +=head1 AUTHORS + +The MailTools bundle was developed by Graham Barr. Later, Mark +Overmeer took over maintenance without commitment to further development. + +Mail::Cap by Gisle Aas E<lt>aas@oslonett.noE<gt>. +Mail::Field::AddrList by Peter Orbaek E<lt>poe@cit.dkE<gt>. +Mail::Mailer and Mail::Send by Tim Bunce E<lt>Tim.Bunce@ig.co.ukE<gt>. +For other contributors see ChangeLog. + +=head1 LICENSE + +Copyrights 1995-2000 Graham Barr E<lt>gbarr@pobox.comE<gt> and +2001-2017 Mark Overmeer E<lt>perl@overmeer.netE<gt>. + +This program is free software; you can redistribute it and/or modify it +under the same terms as Perl itself. +See F<http://www.perl.com/perl/misc/Artistic.html> + diff --git a/cpan/dist/MailTools/lib/Mail/Header.pm b/cpan/dist/MailTools/lib/Mail/Header.pm new file mode 100644 index 00000000..a999f656 --- /dev/null +++ b/cpan/dist/MailTools/lib/Mail/Header.pm @@ -0,0 +1,632 @@ +# Copyrights 1995-2017 by [Mark Overmeer <perl@overmeer.net>]. +# For other contributors see ChangeLog. +# See the manual pages for details on the licensing terms. +# Pod stripped from pm file by OODoc 2.02. +package Mail::Header; +use vars '$VERSION'; +$VERSION = '2.19'; + + +use strict; +use Carp; + +my $MAIL_FROM = 'KEEP'; +my %HDR_LENGTHS = (); + +our $FIELD_NAME = '[^\x00-\x1f\x7f-\xff :]+:'; + + +## +## Private functions +## + +sub _error { warn @_; () } + +# tidy up internal hash table and list + +sub _tidy_header +{ my $self = shift; + my $deleted = 0; + + for(my $i = 0 ; $i < @{$self->{mail_hdr_list}}; $i++) + { next if defined $self->{mail_hdr_list}[$i]; + + splice @{$self->{mail_hdr_list}}, $i, 1; + $deleted++; + $i--; + } + + if($deleted) + { local $_; + my @del; + + while(my ($key,$ref) = each %{$self->{mail_hdr_hash}} ) + { push @del, $key + unless @$ref = grep { ref $_ && defined $$_ } @$ref; + } + + delete $self->{'mail_hdr_hash'}{$_} for @del; + } +} + +# fold the line to the given length + +my %STRUCTURE = map { (lc $_ => undef) } + 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 + Content-Length Content-Type Content-Disposition + Delivered-To + Lines + MIME-Version + Precedence + Status + }; + +sub _fold_line +{ my($ln,$maxlen) = @_; + + $maxlen = 20 + if $maxlen < 20; + + my $max = int($maxlen - 5); # 4 for leading spcs + 1 for [\,\;] + my $min = int($maxlen * 4 / 5) - 4; + + $_[0] =~ s/[\r\n]+//og; # Remove new-lines + $_[0] =~ s/\s*\Z/\n/so; # End line with a EOLN + + return if $_[0] =~ /^From\s/io; + + if(length($_[0]) > $maxlen) + { if($_[0] =~ /^([-\w]+)/ && exists $STRUCTURE{ lc $1 } ) + { #Split the line up + # first bias towards splitting at a , or a ; >4/5 along the line + # next split a whitespace + # else we are looking at a single word and probably don't want to split + my $x = ""; + $x .= "$1\n " while $_[0] =~ + s/^\s* + ( [^"]{$min,$max} [,;] + | [^"]{1,$max} [,;\s] + | [^\s"]*(?:"[^"]*"[ \t]?[^\s"]*)+\s + ) //x; + + $x .= $_[0]; + $_[0] = $x; + $_[0] =~ s/(\A\s+|[\t ]+\Z)//sog; + $_[0] =~ s/\s+\n/\n/sog; + } + else + { $_[0] =~ s/(.{$min,$max})(\s)/$1\n$2/g; + $_[0] =~ s/\s*$/\n/s; + } + } + + $_[0] =~ s/\A(\S+)\n\s*(?=\S)/$1 /so; +} + +# Tags are case-insensitive, but there is a (slightly) preferred construction +# being all characters are lowercase except the first of each word. Also +# if the word is an `acronym' then all characters are uppercase. We decide +# a word is an acronym if it does not contain a vowel. +# In general, this change of capitalization is a bad idea, but it is in +# the code for ages, and therefore probably crucial for existing +# applications. + +sub _tag_case +{ my $tag = shift; + $tag =~ s/\:$//; + join '-' + , map { /^[b-df-hj-np-tv-z]+$|^(?:MIME|SWE|SOAP|LDAP|ID)$/i + ? uc($_) : ucfirst(lc($_)) + } split m/\-/, $tag, -1; +} + +# format a complete line +# ensure line starts with the given tag +# ensure tag is correct case +# change the 'From ' tag as required +# fold the line + +sub _fmt_line +{ my ($self, $tag, $line, $modify) = @_; + $modify ||= $self->{mail_hdr_modify}; + my $ctag = undef; + + ($tag) = $line =~ /^($FIELD_NAME|From )/oi + unless defined $tag; + + if(defined $tag && $tag =~ /^From /io && $self->{mail_hdr_mail_from} ne 'KEEP') + { if($self->{mail_hdr_mail_from} eq 'COERCE') + { $line =~ s/^From /Mail-From: /o; + $tag = "Mail-From:"; + } + elsif($self->{mail_hdr_mail_from} eq 'IGNORE') + { return (); + } + elsif($self->{mail_hdr_mail_from} eq 'ERROR') + { return _error "unadorned 'From ' ignored: <$line>"; + } + } + + if(defined $tag) + { $tag = _tag_case($ctag = $tag); + $ctag = $tag if $modify; + $ctag =~ s/([^ :])$/$1:/o if defined $ctag; + } + + defined $ctag && $ctag =~ /^($FIELD_NAME|From )/oi + or croak "Bad RFC822 field name '$tag'\n"; + + # Ensure the line starts with tag + if(defined $ctag && ($modify || $line !~ /^\Q$ctag\E/i)) + { (my $xtag = $ctag) =~ s/\s*\Z//o; + $line =~ s/^(\Q$ctag\E)?\s*/$xtag /i; + } + + my $maxlen = $self->{mail_hdr_lengths}{$tag} + || $HDR_LENGTHS{$tag} + || $self->fold_length; + + if ($modify && defined $maxlen) + { # folding will fix bad header continuations for us + _fold_line $line, $maxlen; + } + elsif($line =~ /\r?\n\S/) + { return _error "Bad header continuation, skipping '$tag': ", + "no space after newline in '$line'\n"; + } + + + $line =~ s/\n*$/\n/so; + ($tag, $line); +} + +sub _insert +{ my ($self, $tag, $line, $where) = @_; + + if($where < 0) + { $where = @{$self->{mail_hdr_list}} + $where + 1; + $where = 0 if $where < 0; + } + elsif($where >= @{$self->{mail_hdr_list}}) + { $where = @{$self->{mail_hdr_list}}; + } + + my $atend = $where == @{$self->{mail_hdr_list}}; + splice @{$self->{mail_hdr_list}}, $where, 0, $line; + + $self->{mail_hdr_hash}{$tag} ||= []; + my $ref = \${$self->{mail_hdr_list}}[$where]; + + my $def = $self->{mail_hdr_hash}{$tag}; + if($def && $where) + { if($atend) { push @$def, $ref } + else + { my $i = 0; + foreach my $ln (@{$self->{mail_hdr_list}}) + { my $r = \$ln; + last if $r == $ref; + $i++ if $r == $def->[$i]; + } + splice @$def, $i, 0, $ref; + } + } + else + { unshift @$def, $ref; + } +} + +#------------ + +sub new +{ my $call = shift; + my $class = ref($call) || $call; + my $arg = @_ % 2 ? shift : undef; + my %opt = @_; + + $opt{Modify} = delete $opt{Reformat} + unless exists $opt{Modify}; + + my $self = bless + { mail_hdr_list => [] + , mail_hdr_hash => {} + , mail_hdr_modify => (delete $opt{Modify} || 0) + , mail_hdr_foldlen => 79 + , mail_hdr_lengths => {} + }, $class; + + $self->mail_from( uc($opt{MailFrom} || $MAIL_FROM) ); + + $self->fold_length($opt{FoldLength}) + if exists $opt{FoldLength}; + + if(!ref $arg) {} + elsif(ref($arg) eq 'ARRAY') { $self->extract( [ @$arg ] ) } + elsif(defined fileno($arg)) { $self->read($arg) } + + $self; +} + + +sub dup +{ my $self = shift; + my $dup = ref($self)->new; + + %$dup = %$self; + $dup->empty; # rebuild tables + + $dup->{mail_hdr_list} = [ @{$self->{mail_hdr_list}} ]; + + foreach my $ln ( @{$dup->{mail_hdr_list}} ) + { my $tag = _tag_case +($ln =~ /^($FIELD_NAME|From )/oi)[0]; + push @{$dup->{mail_hdr_hash}{$tag}}, \$ln; + } + + $dup; +} + +#------------ + +sub extract +{ my ($self, $lines) = @_; + $self->empty; + + while(@$lines) + { my $line = shift @$lines; + last if $line =~ /^\r?$/; + + $line =~ /^($FIELD_NAME|From )/o or next; + my $tag = $1; + + $line .= shift @$lines + while @$lines && $lines->[0] =~ /^[ \t]+/; + + ($tag, $line) = _fmt_line $self, $tag, $line; + + _insert $self, $tag, $line, -1 + if defined $line; + } + + $self; +} + + +sub read +{ my ($self, $fd) = @_; + $self->empty; + + my ($ln, $tag, $line); + while(1) + { $ln = <$fd>; + + if(defined $ln && defined $line && $ln =~ /^[ \t]+/) + { $line .= $ln; # folded line + next; + } + + if(defined $line) + { ($tag, $line) = _fmt_line $self, $tag, $line; + _insert $self, $tag, $line, -1 + if defined $line; + ($tag, $line) = (); + } + + last if !defined $ln || $ln =~ m/^\r?$/; + + $ln =~ /^($FIELD_NAME|From )/o or next; + ($tag, $line) = ($1, $ln); + } + + $self; +} + + +sub empty +{ my $self = shift; + $self->{mail_hdr_list} = []; + $self->{mail_hdr_hash} = {}; + $self; +} + + +sub header +{ my $self = shift; + + $self->extract(@_) + if @_; + + $self->fold + if $self->{mail_hdr_modify}; + + [ @{$self->{mail_hdr_list}} ]; +} + + +sub header_hashref +{ my ($self, $hashref) = @_; + + while(my ($key, $value) = each %$hashref) + { $self->add($key, $_) for ref $value ? @$value : $value; + } + + $self->fold + if $self->{mail_hdr_modify}; + + defined wantarray # MO, added minimal optimization + or return; + + +{ map { ($_ => [$self->get($_)] ) } # MO: Eh? + keys %{$self->{mail_hdr_hash}} + }; +} + +#------------ + +sub modify +{ my $self = shift; + my $old = $self->{mail_hdr_modify}; + + $self->{mail_hdr_modify} = 0 + shift + if @_; + + $old; +} + + +sub mail_from +{ my $thing = shift; + my $choice = uc shift; + + $choice =~ /^(IGNORE|ERROR|COERCE|KEEP)$/ + or die "bad Mail-From choice: '$choice'"; + + if(ref $thing) { $thing->{mail_hdr_mail_from} = $choice } + else { $MAIL_FROM = $choice } + + $thing; +} + + +sub fold_length +{ my $thing = shift; + my $old; + + if(@_ == 2) + { my $tag = _tag_case shift; + my $len = shift; + + my $hash = ref $thing ? $thing->{mail_hdr_lengths} : \%HDR_LENGTHS; + $old = $hash->{$tag}; + $hash->{$tag} = $len > 20 ? $len : 20; + } + else + { my $self = $thing; + my $len = shift; + $old = $self->{mail_hdr_foldlen}; + + if(defined $len) + { $self->{mail_hdr_foldlen} = $len > 20 ? $len : 20; + $self->fold if $self->{mail_hdr_modify}; + } + } + + $old; +} + +#------------ + +sub fold +{ my ($self, $maxlen) = @_; + + while(my ($tag, $list) = each %{$self->{mail_hdr_hash}}) + { my $len = $maxlen + || $self->{mail_hdr_lengths}{$tag} + || $HDR_LENGTHS{$tag} + || $self->fold_length; + + foreach my $ln (@$list) + { _fold_line $$ln, $len + if defined $ln; + } + } + + $self; +} + + +sub unfold +{ my $self = shift; + + if(@_) + { my $tag = _tag_case shift; + my $list = $self->{mail_hdr_hash}{$tag} + or return $self; + + foreach my $ln (@$list) + { $$ln =~ s/\r?\n\s+/ /sog + if defined $ln && defined $$ln; + } + + return $self; + } + + while( my ($tag, $list) = each %{$self->{mail_hdr_hash}}) + { foreach my $ln (@$list) + { $$ln =~ s/\r?\n\s+/ /sog + if defined $ln && defined $$ln; + } + } + + $self; +} + + +sub add +{ my ($self, $tag, $text, $where) = @_; + ($tag, my $line) = _fmt_line $self, $tag, $text; + + defined $tag && defined $line + or return undef; + + defined $where + or $where = -1; + + _insert $self, $tag, $line, $where; + + $line =~ /^\S+\s(.*)/os; + $1; +} + + +sub replace +{ my $self = shift; + my $idx = @_ % 2 ? pop @_ : 0; + + my ($tag, $line); + TAG: + while(@_) + { ($tag,$line) = _fmt_line $self, splice(@_,0,2); + + defined $tag && defined $line + or return undef; + + my $field = $self->{mail_hdr_hash}{$tag}; + if($field && defined $field->[$idx]) + { ${$field->[$idx]} = $line } + else { _insert $self, $tag, $line, -1 } + } + + $line =~ /^\S+\s*(.*)/os; + $1; +} + + +sub combine +{ my $self = shift; + my $tag = _tag_case shift; + my $with = shift || ' '; + + $tag =~ /^From /io && $self->{mail_hdr_mail_from} ne 'KEEP' + and return _error "unadorned 'From ' ignored"; + + my $def = $self->{mail_hdr_hash}{$tag} + or return undef; + + return $def->[0] + if @$def <= 1; + + my @lines = $self->get($tag); + chomp @lines; + + my $line = (_fmt_line $self, $tag, join($with,@lines), 1)[1]; + + $self->{mail_hdr_hash}{$tag} = [ \$line ]; + $line; +} + + +sub get +{ my $self = shift; + my $tag = _tag_case shift; + my $idx = shift; + + my $def = $self->{mail_hdr_hash}{$tag} + or return (); + + my $l = length $tag; + $l += 1 if $tag !~ / $/o; + + if(defined $idx || !wantarray) + { $idx ||= 0; + defined $def->[$idx] or return undef; + my $val = ${$def->[$idx]}; + defined $val or return undef; + + $val = substr $val, $l; + $val =~ s/^\s+//; + return $val; + } + + map { my $tmp = substr $$_,$l; $tmp =~ s/^\s+//; $tmp } @$def; +} + + + +sub count +{ my $self = shift; + my $tag = _tag_case shift; + my $def = $self->{mail_hdr_hash}{$tag}; + defined $def ? scalar(@$def) : 0; +} + + + +sub delete +{ my $self = shift; + my $tag = _tag_case shift; + my $idx = shift; + my @val; + + if(my $def = $self->{mail_hdr_hash}{$tag}) + { my $l = length $tag; + $l += 2 if $tag !~ / $/; + + if(defined $idx) + { if(defined $def->[$idx]) + { push @val, substr ${$def->[$idx]}, $l; + undef ${$def->[$idx]}; + } + } + else + { @val = map {my $x = substr $$_,$l; undef $$_; $x } @$def; + } + + _tidy_header($self); + } + + @val; +} + + + +sub print +{ my $self = shift; + my $fd = shift || \*STDOUT; + + foreach my $ln (@{$self->{mail_hdr_list}}) + { defined $ln or next; + print $fd $ln or return 0; + } + + 1; +} + + +sub as_string { join '', grep {defined} @{shift->{mail_hdr_list}} } + + +sub tags { keys %{shift->{mail_hdr_hash}} } + + +sub cleanup +{ my $self = shift; + my $deleted = 0; + + foreach my $key (@_ ? @_ : keys %{$self->{mail_hdr_hash}}) + { my $fields = $self->{mail_hdr_hash}{$key}; + foreach my $field (@$fields) + { next if $$field =~ /^\S+\s+\S/s; + undef $$field; + $deleted++; + } + } + + _tidy_header $self + if $deleted; + + $self; +} + +1; diff --git a/cpan/dist/MailTools/lib/Mail/Header.pod b/cpan/dist/MailTools/lib/Mail/Header.pod new file mode 100644 index 00000000..9f90f4f8 --- /dev/null +++ b/cpan/dist/MailTools/lib/Mail/Header.pod @@ -0,0 +1,255 @@ +=encoding utf8 + +=head1 NAME + +Mail::Header - manipulate MIME headers + +=head1 SYNOPSIS + + use Mail::Header; + + my $head = Mail::Header->new; + my $head = Mail::Header->new( \*STDIN ); + my $head = Mail::Header->new( [<>], Modify => 0); + +=head1 DESCRIPTION + +Read, write, create, and manipulate MIME headers, the leading part +of each modern e-mail message, but also used in other protocols +like HTTP. The fields are kept in L<Mail::Field|Mail::Field> objects. + +Be aware that the header fields each have a name part, which shall +be treated case-insensitive, and a content part, which may be folded +over multiple lines. + +Mail::Header does not always follow the RFCs strict enough, does not +help you with character encodings. It does not use weak references +where it could (because those did not exist when the module was written) +which costs some performance and make the implementation a little more +complicated. The Mail::Message::Head implementation is much newer +and therefore better. + +=head1 METHODS + +=head2 Constructors + +=over 4 + +=item $obj-E<gt>B<dup>() + +Create a duplicate of the current object. + +=item $obj-E<gt>B<new>( [ARG], [OPTIONS] ) + +=item Mail::Header-E<gt>B<new>( [ARG], [OPTIONS] ) + +ARG may be either a file descriptor (reference to a GLOB) +or a reference to an array. If given the new object will be +initialized with headers either from the array of read from +the file descriptor. + +OPTIONS is a list of options given in the form of key-value +pairs, just like a hash table. Valid options are + + -Option --Default + FoldLength 79 + MailFrom 'KEEP' + Modify false + +=over 2 + +=item FoldLength => INTEGER + +The default length of line to be used when folding header lines. +See L<fold_length()|Mail::Header/"Accessors">. + +=item MailFrom => 'IGNORE'|'COERCE'|'KEEP'|'ERROR' + +See method L<mail_from()|Mail::Header/"Accessors">. + +=item Modify => BOOLEAN + +If this value is I<true> then the headers will be re-formatted, +otherwise the format of the header lines will remain unchanged. + +=back + +=back + +=head2 "Fake" constructors + +Be warned that the next constructors all require an already created +header object, of which the original content will be destroyed. + +=over 4 + +=item $obj-E<gt>B<empty>() + +Empty an existing C<Mail::Header> object of all lines. + +=item $obj-E<gt>B<extract>(ARRAY) + +Extract a header from the given array into an existing Mail::Header +object. C<extract> B<will modify> this array. +Returns the object that the method was called on. + +=item $obj-E<gt>B<header>( [ARRAY] ) + +C<header> does multiple operations. First it will extract a header from +the ARRAY, if given. It will then reformat the header (if reformatting +is permitted), and finally return a reference to an array which +contains the header in a printable form. + +=item $obj-E<gt>B<header_hashref>( [HASH] ) + +As L<header()|Mail::Header/""Fake" constructors">, but it will eventually set headers from a hash +reference, and it will return the headers as a hash reference. + +example: + + $fields->{From} = 'Tobias Brox <tobix@cpan.org>'; + $fields->{To} = ['you@somewhere', 'me@localhost']; + $head->header_hashref($fields); + +=item $obj-E<gt>B<read>(FILEHANDLE) + +Read a header from the given file descriptor into an existing Mail::Header +object. + +=back + +=head2 Accessors + +=over 4 + +=item $obj-E<gt>B<fold_length>( [TAG], [LENGTH] ) + +Set the default fold length for all tags or just one. With no arguments +the default fold length is returned. With two arguments it sets the fold +length for the given tag and returns the previous value. If only C<LENGTH> +is given it sets the default fold length for the current object. + +In the two argument form C<fold_length> may be called as a static method, +setting default fold lengths for tags that will be used by B<all> +C<Mail::Header> objects. See the C<fold> method for +a description on how C<Mail::Header> uses these values. + +=item $obj-E<gt>B<mail_from>('IGNORE'|'COERCE'|'KEEP'|'ERROR') + +This specifies what to do when a C<`From '> line is encountered. +Valid values are C<IGNORE> - ignore and discard the header, +C<ERROR> - invoke an error (call die), C<COERCE> - rename them as Mail-From +and C<KEEP> - keep them. + +=item $obj-E<gt>B<modify>( [VALUE] ) + +If C<VALUE> is I<false> then C<Mail::Header> will not do any automatic +reformatting of the headers, other than to ensure that the line +starts with the tags given. + +=back + +=head2 Processing + +=over 4 + +=item $obj-E<gt>B<add>( TAG, LINE [, INDEX] ) + +Add a new line to the header. If TAG is C<undef> the tag will be +extracted from the beginning of the given line. If INDEX is given, +the new line will be inserted into the header at the given point, otherwise +the new line will be appended to the end of the header. + +=item $obj-E<gt>B<as_string>() + +Returns the header as a single string. + +=item $obj-E<gt>B<cleanup>() + +Remove any header line that, other than the tag, only contains whitespace + +=item $obj-E<gt>B<combine>( TAG [, WITH] ) + +Combine all instances of TAG into one. The lines will be +joined together WITH, or a single space if not given. The new +item will be positioned in the header where the first instance was, all +other instances of TAG will be removed. + +=item $obj-E<gt>B<count>(TAG) + +Returns the number of times the given atg appears in the header + +=item $obj-E<gt>B<delete>( TAG [, INDEX ] ) + +Delete a tag from the header. If an INDEX id is given, then the Nth instance +of the tag will be removed. If no INDEX is given, then all instances +of tag will be removed. + +=item $obj-E<gt>B<fold>( [LENGTH] ) + +Fold the header. If LENGTH is not given, then C<Mail::Header> uses the +following rules to determine what length to fold a line. + +=item $obj-E<gt>B<get>( TAG [, INDEX] ) + +Get the text from a line. If an INDEX is given, then the text of the Nth +instance will be returned. If it is not given the return value depends on the +context in which C<get> was called. In an array context a list of all the +text from all the instances of the TAG will be returned. In a scalar context +the text for the first instance will be returned. + +The lines are unfolded, but still terminated with a new-line (see C<chomp>) + +=item $obj-E<gt>B<print>( [FILEHANDLE] ) + +Print the header to the given file descriptor, or C<STDOUT> if no +file descriptor is given. + +=item $obj-E<gt>B<replace>( TAG, LINE [, INDEX ] ) + +Replace a line in the header. If TAG is C<undef> the tag will be +extracted from the beginning of the given line. If INDEX is given +the new line will replace the Nth instance of that tag, otherwise the +first instance of the tag is replaced. If the tag does not appear in the +header then a new line will be appended to the header. + +=item $obj-E<gt>B<tags>() + +Returns an array of all the tags that exist in the header. Each tag will +only appear in the list once. The order of the tags is not specified. + +=item $obj-E<gt>B<unfold>( [TAG] ) + +Unfold all instances of the given tag so that they do not spread across +multiple lines. If C<TAG> is not given then all lines are unfolded. + +The unfolding process is wrong but (for compatibility reasons) will +not be repaired: only one blank at the start of the line should be +removed, not all of them. + +=back + +=head1 SEE ALSO + +This module is part of the MailTools distribution, +F<http://perl.overmeer.net/mailtools/>. + +=head1 AUTHORS + +The MailTools bundle was developed by Graham Barr. Later, Mark +Overmeer took over maintenance without commitment to further development. + +Mail::Cap by Gisle Aas E<lt>aas@oslonett.noE<gt>. +Mail::Field::AddrList by Peter Orbaek E<lt>poe@cit.dkE<gt>. +Mail::Mailer and Mail::Send by Tim Bunce E<lt>Tim.Bunce@ig.co.ukE<gt>. +For other contributors see ChangeLog. + +=head1 LICENSE + +Copyrights 1995-2000 Graham Barr E<lt>gbarr@pobox.comE<gt> and +2001-2017 Mark Overmeer E<lt>perl@overmeer.netE<gt>. + +This program is free software; you can redistribute it and/or modify it +under the same terms as Perl itself. +See F<http://www.perl.com/perl/misc/Artistic.html> + diff --git a/cpan/dist/MailTools/lib/Mail/Internet.pm b/cpan/dist/MailTools/lib/Mail/Internet.pm new file mode 100644 index 00000000..bace44be --- /dev/null +++ b/cpan/dist/MailTools/lib/Mail/Internet.pm @@ -0,0 +1,554 @@ +# Copyrights 1995-2017 by [Mark Overmeer <perl@overmeer.net>]. +# For other contributors see ChangeLog. +# See the manual pages for details on the licensing terms. +# Pod stripped from pm file by OODoc 2.02. +package Mail::Internet; +use vars '$VERSION'; +$VERSION = '2.19'; + +use strict; +# use warnings? probably breaking too much code + +use Carp; +use Mail::Header; +use Mail::Util qw/mailaddress/; +use Mail::Address; + + +sub new(@) +{ my $call = shift; + my $arg = @_ % 2 ? shift : undef; + my %opt = @_; + + my $class = ref($call) || $call; + my $self = bless {}, $class; + + $self->{mail_inet_head} = $opt{Header} if exists $opt{Header}; + $self->{mail_inet_body} = $opt{Body} if exists $opt{Body}; + + my $head = $self->head; + $head->fold_length(delete $opt{FoldLength} || 79); + $head->mail_from($opt{MailFrom}) if exists $opt{MailFrom}; + $head->modify(exists $opt{Modify} ? $opt{Modify} : 1); + + if(!defined $arg) { } + elsif(ref($arg) eq 'ARRAY') + { $self->header($arg) unless exists $opt{Header}; + $self->body($arg) unless exists $opt{Body}; + } + elsif(defined fileno($arg)) + { $self->read_header($arg) unless exists $opt{Header}; + $self->read_body($arg) unless exists $opt{Body}; + } + else + { croak "couldn't understand $arg to Mail::Internet constructor"; + } + + $self; +} + + +sub read(@) +{ my $self = shift; + $self->read_header(@_); + $self->read_body(@_); +} + +sub read_body($) +{ my ($self, $fd) = @_; + $self->body( [ <$fd> ] ); +} + +sub read_header(@) +{ my $head = shift->head; + $head->read(@_); + $head->header; +} + + +sub extract($) +{ my ($self, $lines) = @_; + $self->head->extract($lines); + $self->body($lines); +} + + +sub dup() +{ my $self = shift; + my $dup = ref($self)->new; + + my $body = $self->{mail_inet_body} || []; + my $head = $self->{mail_inet_head};; + + $dup->{mail_inet_body} = [ @$body ]; + $dup->{mail_inet_head} = $head->dup if $head; + $dup; +} + +#--------------- + +sub body(;$@) +{ my $self = shift; + + return $self->{mail_inet_body} ||= [] + unless @_; + + $self->{mail_inet_body} = ref $_[0] eq 'ARRAY' ? $_[0] : [ @_ ]; +} + + +sub head { shift->{mail_inet_head} ||= Mail::Header->new } + +#--------------- + +sub print($) +{ my $self = shift; + my $fd = shift || \*STDOUT; + + $self->print_header($fd) + and print $fd "\n" + and $self->print_body($fd); +} + + +sub print_header($) { shift->head->print(@_) } + +sub print_body($) +{ my $self = shift; + my $fd = shift || \*STDOUT; + + foreach my $ln (@{$self->body}) + { print $fd $ln or return 0; + } + + 1; +} + + +sub as_string() +{ my $self = shift; + $self->head->as_string . "\n" . join '', @{$self->body}; +} + + +sub as_mbox_string($) +{ my $self = shift->dup; + my $escaped = shift; + + $self->head->delete('Content-Length'); + $self->escape_from unless $escaped; + $self->as_string . "\n"; +} + +#--------------- + +sub header { shift->head->header(@_) } +sub fold { shift->head->fold(@_) } +sub fold_length { shift->head->fold_length(@_) } +sub combine { shift->head->combine(@_) } + + +sub add(@) +{ my $head = shift->head; + my $ret; + while(@_) + { my ($tag, $line) = splice @_, 0, 2; + $ret = $head->add($tag, $line, -1) + or return undef; + } + + $ret; +} + + +sub replace(@) +{ my $head = shift->head; + my $ret; + + while(@_) + { my ($tag, $line) = splice @_, 0, 2; + $ret = $head->replace($tag, $line, 0) + or return undef; + } + + $ret; +} + + +sub get(@) +{ my $head = shift->head; + + return map { $head->get($_) } @_ + if wantarray; + + foreach my $tag (@_) + { my $r = $head->get($tag); + return $r if defined $r; + } + + undef; +} + + +sub delete(@) +{ my $head = shift->head; + map { $head->delete($_) } @_; +} + +# Undocumented; unused??? +sub empty() +{ my $self = shift; + %$self = (); + 1; +} + +#--------------- + +sub remove_sig($) +{ my $body = shift->body; + my $nlines = shift || 10; + my $start = @$body; + + my $i = 0; + while($i++ < $nlines && $start--) + { next if $body->[$start] !~ /^--[ ]?[\r\n]/; + + splice @$body, $start, $i; + last; + } +} + + +sub sign(@) +{ my ($self, %arg) = @_; + my ($sig, @sig); + + if($sig = delete $arg{File}) + { local *SIG; + + if(open(SIG, $sig)) + { local $_; + while(<SIG>) { last unless /^(--)?\s*$/ } + @sig = ($_, <SIG>, "\n"); + close SIG; + } + } + elsif($sig = delete $arg{Signature}) + { @sig = ref($sig) ? @$sig : split(/\n/, $sig); + } + + if(@sig) + { $self->remove_sig; + s/[\r\n]*$/\n/ for @sig; + push @{$self->body}, "-- \n", @sig; + } + + $self; +} + + +sub tidy_body() +{ my $body = shift->body; + + shift @$body while @$body && $body->[0] =~ /^\s*$/; + pop @$body while @$body && $body->[-1] =~ /^\s*$/; + $body; +} + +#--------------- + +sub reply(@) +{ my ($self, %arg) = @_; + my $class = ref $self; + my @reply; + + local *MAILHDR; + if(open(MAILHDR, "$ENV{HOME}/.mailhdr")) + { # User has defined a mail header template + @reply = <MAILHDR>; + close MAILHDR; + } + + my $reply = $class->new(\@reply); + + # The Subject line + my $subject = $self->get('Subject') || ""; + $subject = "Re: " . $subject + if $subject =~ /\S+/ && $subject !~ /Re:/i; + + $reply->replace(Subject => $subject); + + # Locate who we are sending to + my $to = $self->get('Reply-To') + || $self->get('From') + || $self->get('Return-Path') + || ""; + + my $sender = (Mail::Address->parse($to))[0]; + + my $name = $sender->name; + unless(defined $name) + { my $fr = $self->get('From'); + $fr = (Mail::Address->parse($fr))[0] if defined $fr; + $name = $fr->name if defined $fr; + } + + my $indent = $arg{Indent} || ">"; + if($indent =~ /\%/) + { my %hash = ( '%' => '%'); + my @name = $name ? grep( {length $_} split /[\n\s]+/, $name) : ''; + + $hash{f} = $name[0]; + $hash{F} = $#name ? substr($hash{f},0,1) : $hash{f}; + + $hash{l} = $#name ? $name[$#name] : ""; + $hash{L} = substr($hash{l},0,1) || ""; + + $hash{n} = $name || ""; + $hash{I} = join "", map {substr($_,0,1)} @name; + + $indent =~ s/\%(.)/defined $hash{$1} ? $hash{$1} : $1/eg; + } + + my $id = $sender->address; + $reply->replace(To => $id); + + # Find addresses not to include + my $mailaddresses = $ENV{MAILADDRESSES} || ""; + + my %nocc = (lc($id) => 1); + $nocc{lc $_->address} = 1 + for Mail::Address->parse($reply->get('Bcc'), $mailaddresses); + + if($arg{ReplyAll}) # Who shall we copy this to + { my %cc; + foreach my $addr (Mail::Address->parse($self->get('To'), $self->get('Cc'))) + { my $lc = lc $addr->address; + $cc{$lc} = $addr->format + unless $nocc{$lc}; + } + my $cc = join ', ', values %cc; + $reply->replace(Cc => $cc); + } + + # References + my $refs = $self->get('References') || ""; + my $mid = $self->get('Message-Id'); + + $refs .= " " . $mid if defined $mid; + $reply->replace(References => $refs); + + # In-Reply-To + my $date = $self->get('Date'); + my $inreply = ""; + + if(defined $mid) + { $inreply = $mid; + my @comment; + push @comment, "from $name" if defined $name; + push @comment, "on $date" if defined $date; + local $" = ' '; + $inreply .= " (@comment)" if @comment; + } + elsif(defined $name) + { $inreply = $name . "'s message"; + $inreply .= "of " . $date if defined $date; + } + $reply->replace('In-Reply-To' => $inreply); + + # Quote the body + my $body = $reply->body; + @$body = @{$self->body}; # copy body + $reply->remove_sig; + $reply->tidy_body; + s/\A/$indent/ for @$body; + + # Add references + unshift @{$body}, (defined $name ? $name . " " : "") . "<$id> writes:\n"; + + if(defined $arg{Keep} && ref $arg{Keep} eq 'ARRAY') # Include lines + { foreach my $keep (@{$arg{Keep}}) + { my $ln = $self->get($keep); + $reply->replace($keep => $ln) if defined $ln; + } + } + + if(defined $arg{Exclude} && ref $arg{Exclude} eq 'ARRAY') # Exclude lines + { $reply->delete(@{$arg{Exclude}}); + } + + $reply->head->cleanup; # remove empty header lines + $reply; +} + + +sub smtpsend($@) +{ my ($self, %opt) = @_; + + require Net::SMTP; + require Net::Domain; + + my $host = $opt{Host}; + my $envelope = $opt{MailFrom} || mailaddress(); + my $quit = 1; + + my ($smtp, @hello); + + push @hello, Hello => $opt{Hello} + if defined $opt{Hello}; + + push @hello, Port => $opt{Port} + if exists $opt{Port}; + + push @hello, Debug => $opt{Debug} + if exists $opt{Debug}; + + if(!defined $host) + { local $SIG{__DIE__}; + my @hosts = qw(mailhost localhost); + unshift @hosts, split /\:/, $ENV{SMTPHOSTS} + if defined $ENV{SMTPHOSTS}; + + foreach $host (@hosts) + { $smtp = eval { Net::SMTP->new($host, @hello) }; + last if defined $smtp; + } + } + elsif(UNIVERSAL::isa($host,'Net::SMTP') + || UNIVERSAL::isa($host,'Net::SMTP::SSL')) + { $smtp = $host; + $quit = 0; + } + else + { local $SIG{__DIE__}; + $smtp = eval { Net::SMTP->new($host, @hello) }; + } + + defined $smtp or return (); + + my $head = $self->cleaned_header_dup; + + # Who is it to + + my @rcpt = map { ref $_ ? @$_ : $_ } grep { defined } @opt{'To','Cc','Bcc'}; + @rcpt = map { $head->get($_) } qw(To Cc Bcc) + unless @rcpt; + + my @addr = map {$_->address} Mail::Address->parse(@rcpt); + @addr or return (); + + $head->delete('Bcc'); + + # Send it + + my $ok = $smtp->mail($envelope) + && $smtp->to(@addr) + && $smtp->data(join("", @{$head->header}, "\n", @{$self->body})); + + $quit && $smtp->quit; + $ok ? @addr : (); +} + + +sub send($@) +{ my ($self, $type, @args) = @_; + + require Mail::Mailer; + + my $head = $self->cleaned_header_dup; + my $mailer = Mail::Mailer->new($type, @args); + + $mailer->open($head->header_hashref); + $self->print_body($mailer); + $mailer->close; +} + + +sub nntppost +{ my ($self, %opt) = @_; + + require Net::NNTP; + + my $groups = $self->get('Newsgroups') || ""; + my @groups = split /[\s,]+/, $groups; + @groups or return (); + + my $head = $self->cleaned_header_dup; + + # Remove these incase the NNTP host decides to mail as well as me + $head->delete(qw(To Cc Bcc)); + + my $news; + my $quit = 1; + + my $host = $opt{Host}; + if(ref($host) && UNIVERSAL::isa($host,'Net::NNTP')) + { $news = $host; + $quit = 0; + } + else + { my @opt = $opt{Host}; + + push @opt, Port => $opt{Port} + if exists $opt{Port}; + + push @opt, Debug => $opt{Debug} + if exists $opt{Debug}; + + $news = Net::NNTP->new(@opt) + or return (); + } + + $news->post(@{$head->header}, "\n", @{$self->body}); + my $rc = $news->code; + + $news->quit if $quit; + + $rc == 240 ? @groups : (); +} + + +sub escape_from +{ my $body = shift->body; + scalar grep { s/\A(>*From) />$1 /o } @$body; +} + + + +sub unescape_from +{ my $body = shift->body; + scalar grep { s/\A>(>*From) /$1 /o } @$body; +} + +# Don't tell people it exists +sub cleaned_header_dup() +{ my $head = shift->head->dup; + + $head->delete('From '); # Just in case :-) + + # An original message should not have any Received lines + $head->delete('Received'); + + $head->replace('X-Mailer', "Perl5 Mail::Internet v".$Mail::Internet::VERSION) + unless $head->count('X-Mailer'); + + my $name = eval {local $SIG{__DIE__}; (getpwuid($>))[6]} || $ENV{NAME} ||""; + + while($name =~ s/\([^\(\)]*\)//) { 1; } + + if($name =~ /[^\w\s]/) + { $name =~ s/"/\"/g; + $name = '"' . $name . '"'; + } + + my $from = sprintf "%s <%s>", $name, mailaddress(); + $from =~ s/\s{2,}/ /g; + + foreach my $tag (qw(From Sender)) + { $head->get($tag) or $head->add($tag, $from); + } + + $head; +} + +1; diff --git a/cpan/dist/MailTools/lib/Mail/Internet.pod b/cpan/dist/MailTools/lib/Mail/Internet.pod new file mode 100644 index 00000000..a6c42b7f --- /dev/null +++ b/cpan/dist/MailTools/lib/Mail/Internet.pod @@ -0,0 +1,387 @@ +=encoding utf8 + +=head1 NAME + +Mail::Internet - manipulate email messages + +=head1 SYNOPSIS + + use Mail::Internet; + my $msg = Mail::Internet->new(\*STDIN); + +=head1 DESCRIPTION + +This package implements reading, creating, manipulating, and writing email +messages. Sometimes, the implementation tries to be too smart, but in +the general case it works as expected. + +If you start writing a B<new application>, you should use the L<Mail::Box> +distribution, which has more features and handles messages much better +according to the RFCs. See L<http://perl.overmeer.net/mailbox/>. +You may also chose L<MIME::Entity>, to get at least some multipart +support in your application. + +=head1 METHODS + +=head2 Constructors + +=over 4 + +=item $obj-E<gt>B<dup>() + +Duplicate the message as a whole. Both header and body will be +deep-copied: a new L<Mail::Internet|Mail::Internet> object is returned. + +=item $obj-E<gt>B<extract>(ARRAY-of-LINES) + +Extract header and body from an ARRAY of message lines. Requires an +object already created with L<new()|Mail::Internet/"Constructors">, which contents will get overwritten. + +=item $obj-E<gt>B<new>( [ARG], [OPTIONS] ) + +=item Mail::Internet-E<gt>B<new>( [ARG], [OPTIONS] ) + +ARG is optional and may be either a file descriptor (reference to a GLOB) +or a reference to an array. If given the new object will be +initialized with headers and body either from the array of read from +the file descriptor. + +The L<Mail::Header::new()|Mail::Header/"Constructors"> OPTIONS C<Modify>, C<MailFrom> and C<FoldLength> +may also be given. + + -Option--Default + Body [] + Header undef + +=over 2 + +=item Body => ARRAY-of-LINES + +The value of this option should be a reference to an array which contains +the lines for the body of the message. Each line should be terminated with +C<\n> (LF). If Body is given then C<Mail::Internet> will not attempt to +read the body from C<ARG> (even if it is specified). + +=item Header => Mail::Header + +The value of this option should be a L<Mail::Header|Mail::Header> object. If given then +C<Mail::Internet> will not attempt to read a mail header from C<ARG>, if +it was specified. + +=back + +=item $obj-E<gt>B<read>(FILEHANDLE) + +Read a message from the FILEHANDLE into an already existing message +object. Better use L<new()|Mail::Internet/"Constructors"> with the FILEHANDLE as first argument. + +=back + +=head2 Accessors + +=over 4 + +=item $obj-E<gt>B<body>( [BODY] ) + +Returns the body of the message. This is a reference to an array. +Each entry in the array represents a single line in the message. + +If I<BODY> is given, it can be a reference to an array or an array, then +the body will be replaced. If a reference is passed, it is used directly +and not copied, so any subsequent changes to the array will change the +contents of the body. + +=item $obj-E<gt>B<head>() + +Returns the C<Mail::Header> object which holds the headers for the current +message + +=back + +=head2 Processing the message as a whole + +=over 4 + +=item $obj-E<gt>B<as_mbox_string>( [ALREADY_ESCAPED] ) + +Returns the message as a string in mbox format. C<ALREADY_ESCAPED>, if +given and true, indicates that L<escape_from()|Mail::Internet/"High-level functionality"> has already been called on +this object. + +=item $obj-E<gt>B<as_string>() + +Returns the message as a single string. + +=item $obj-E<gt>B<print>( [FILEHANDLE] ) + +Print the header, body or whole message to file descriptor I<FILEHANDLE>. +I<$fd> should be a reference to a GLOB. If I<FILEHANDLE> is not given the +output will be sent to STDOUT. + +example: + + $mail->print( \*STDOUT ); # Print message to STDOUT + +=item $obj-E<gt>B<print_body>( [FILEHANDLE] ) + +Print only the body to the FILEHANDLE (default STDOUT). + +=item $obj-E<gt>B<print_header>( [FILEHANDLE] ) + +Print only the header to the FILEHANDLE (default STDOUT). + +=back + +=head2 Processing the header + +Most of these methods are simply wrappers around methods provided +by L<Mail::Header|Mail::Header>. + +=over 4 + +=item $obj-E<gt>B<add>(PAIRS-of-FIELD) + +The PAIRS are field-name and field-content. For each PAIR, +L<Mail::Header::add()|Mail::Header/"Processing"> is called. All fields are added after +existing fields. The last addition is returned. + +=item $obj-E<gt>B<combine>( TAG, [WITH] ) + +See L<Mail::Header::combine()|Mail::Header/"Processing">. + +=item $obj-E<gt>B<delete>( TAG, [TAGs] ) + +Delete all fields with the name TAG. L<Mail::Header::delete()|Mail::Header/"Processing"> is doing the +work. + +=item $obj-E<gt>B<fold>( [LENGTH] ) + +See L<Mail::Header::fold()|Mail::Header/"Processing">. + +=item $obj-E<gt>B<fold_length>( [TAG], [LENGTH] ) + +See L<Mail::Header::fold_length()|Mail::Header/"Accessors">. + +=item $obj-E<gt>B<get>( TAG, [TAGs] ) + +In LIST context, all fields with the name TAG are returned. In SCALAR +context, only the first field which matches the earliest TAG is returned. +L<Mail::Header::get()|Mail::Header/"Processing"> is called to collect the data. + +=item $obj-E<gt>B<header>( [ARRAY-of-LINES] ) + +See L<Mail::Header::header()|Mail::Header/""Fake" constructors">. + +=item $obj-E<gt>B<replace>(PAIRS-of-FIELD) + +The PAIRS are field-name and field-content. For each PAIR, +L<Mail::Header::replace()|Mail::Header/"Processing"> is called with INDEX 0. If a FIELD is already +in the header, it will be removed first. Do not specified the same +field-name twice. + +=back + +=head2 Processing the body + +=over 4 + +=item $obj-E<gt>B<remove_sig>( [NLINES] ) + +Attempts to remove a users signature from the body of a message. It does this +by looking for a line equal to C<'-- '> within the last C<NLINES> of the +message. If found then that line and all lines after it will be removed. If +C<NLINES> is not given a default value of 10 will be used. This would be of +most use in auto-reply scripts. + +=item $obj-E<gt>B<sign>(OPTIONS) + +Add your signature to the body. L<remove_sig()|Mail::Internet/"Processing the body"> will strip existing +signatures first. + + -Option --Default + File undef + Signature [] + +=over 2 + +=item File => FILEHANDLE + +Take from the FILEHANDLE all lines starting from the first C<< -- >>. + +=item Signature => STRING|ARRAY-of-LINES + +=back + +=item $obj-E<gt>B<tidy_body>() + +Removes all leading and trailing lines from the body that only contain +white spaces. + +=back + +=head2 High-level functionality + +=over 4 + +=item $obj-E<gt>B<escape_from>() + +It can cause problems with some applications if a message contains a line +starting with C<`From '>, in particular when attempting to split a folder. +This method inserts a leading C<`>'> on any line that matches the regular +expression C</^>*From/> + +=item $obj-E<gt>B<nntppost>( [OPTIONS] ) + +Post an article via NNTP. Requires Net::NNTP to be installed. + + -Option--Default + Debug <false> + Host <required> + Port 119 + +=over 2 + +=item Debug => BOOLEAN + +Debug value to pass to Net::NNTP, see L<Net::NNTP> + +=item Host => HOSTNAME|Net::NNTP object + +Name of NNTP server to connect to, or a Net::NNTP object to use. + +=item Port => INTEGER + +Port number to connect to on remote host + +=back + +=item $obj-E<gt>B<reply>(OPTIONS) + +Create a new object with header initialised for a reply to the current +object. And the body will be a copy of the current message indented. + +The C<.mailhdr> file in your home directory (if exists) will be read +first, to provide defaults. + + -Option --Default + Exclude [] + Indent '>' + Keep [] + ReplyAll false + +=over 2 + +=item Exclude => ARRAY-of-FIELDS + +Remove the listed FIELDS from the produced message. + +=item Indent => STRING + +Use as indentation string. The string may contain C<%%> to get a single C<%>, +C<%f> to get the first from name, C<%F> is the first character of C<%f>, +C<%l> is the last name, C<%L> its first character, C<%n> the whole from +string, and C<%I> the first character of each of the names in the from string. + +=item Keep => ARRAY-of-FIELDS + +Copy the listed FIELDS from the original message. + +=item ReplyAll => BOOLEAN + +Automatically include all To and Cc addresses of the original mail, +excluding those mentioned in the Bcc list. + +=back + +=item $obj-E<gt>B<send>( [TYPE, [ARGS...]] ) + +Send a Mail::Internet message using L<Mail::Mailer|Mail::Mailer>. TYPE and ARGS are +passed on to L<Mail::Mailer::new()|Mail::Mailer/"Constructors">. + +=item $obj-E<gt>B<smtpsend>( [OPTIONS] ) + +Send a Mail::Internet message using direct SMTP. to the given +ADDRESSES, each can be either a string or a reference to a list of email +addresses. If none of C<To>, <Cc> or C<Bcc> are given then the addresses +are extracted from the message being sent. + +The return value will be a list of email addresses that the message was sent +to. If the message was not sent the list will be empty. + +Requires Net::SMTP and Net::Domain to be installed. + + -Option --Default + Bcc undef + Cc undef + Debug <false> + Hello localhost.localdomain + Host $ENV{SMTPHOSTS} + MailFrom Mail::Util::mailaddress() + Port 25 + To undef + +=over 2 + +=item Bcc => ADDRESSES + +=item Cc => ADDRESSES + +=item Debug => BOOLEAN + +Debug value to pass to Net::SMPT, see <Net::SMTP> + +=item Hello => STRING + +Send a HELO (or EHLO) command to the server with the given name. + +=item Host => HOSTNAME + +Name of the SMTP server to connect to, or a Net::SMTP object to use + +If C<Host> is not given then the SMTP host is found by attempting +connections first to hosts specified in C<$ENV{SMTPHOSTS}>, a colon +separated list, then C<mailhost> and C<localhost>. + +=item MailFrom => ADDRESS + +The e-mail address which is used as sender. By default, +L<Mail::Util::mailaddress()|Mail::Util/"FUNCTIONS"> provides the address of the sender. + +=item Port => INTEGER + +Port number to connect to on remote host + +=item To => ADDRESSES + +=back + +=item $obj-E<gt>B<unescape_from>(()) + +Remove the escaping added by L<escape_from()|Mail::Internet/"High-level functionality">. + +=back + +=head1 SEE ALSO + +This module is part of the MailTools distribution, +F<http://perl.overmeer.net/mailtools/>. + +=head1 AUTHORS + +The MailTools bundle was developed by Graham Barr. Later, Mark +Overmeer took over maintenance without commitment to further development. + +Mail::Cap by Gisle Aas E<lt>aas@oslonett.noE<gt>. +Mail::Field::AddrList by Peter Orbaek E<lt>poe@cit.dkE<gt>. +Mail::Mailer and Mail::Send by Tim Bunce E<lt>Tim.Bunce@ig.co.ukE<gt>. +For other contributors see ChangeLog. + +=head1 LICENSE + +Copyrights 1995-2000 Graham Barr E<lt>gbarr@pobox.comE<gt> and +2001-2017 Mark Overmeer E<lt>perl@overmeer.netE<gt>. + +This program is free software; you can redistribute it and/or modify it +under the same terms as Perl itself. +See F<http://www.perl.com/perl/misc/Artistic.html> + diff --git a/cpan/dist/MailTools/lib/Mail/Mailer.pm b/cpan/dist/MailTools/lib/Mail/Mailer.pm new file mode 100644 index 00000000..7fc90d45 --- /dev/null +++ b/cpan/dist/MailTools/lib/Mail/Mailer.pm @@ -0,0 +1,217 @@ +# Copyrights 1995-2017 by [Mark Overmeer <perl@overmeer.net>]. +# For other contributors see ChangeLog. +# See the manual pages for details on the licensing terms. +# Pod stripped from pm file by OODoc 2.02. +package Mail::Mailer; +use vars '$VERSION'; +$VERSION = '2.19'; + +use base 'IO::Handle'; + +use strict; +use POSIX qw/_exit/; + +use Carp; +use Config; + +#-------------- + + +sub is_exe($); + +sub Version { our $VERSION } + +our @Mailers = + ( sendmail => '/usr/lib/sendmail;/usr/sbin/sendmail;/usr/ucblib/sendmail' + , smtp => undef + , smtps => undef + , qmail => '/usr/sbin/qmail-inject;/var/qmail/bin/qmail-inject' + , testfile => undef + ); + +push @Mailers, map { split /\:/, $_, 2 } + split /$Config{path_sep}/, $ENV{PERL_MAILERS} + if $ENV{PERL_MAILERS}; + +our %Mailers = @Mailers; +our $MailerType; +our $MailerBinary; + +# does this really need to be done? or should a default mailer be specified? + +$Mailers{sendmail} = 'sendmail' + if $^O eq 'os2' && ! is_exe $Mailers{sendmail}; + +if($^O =~ m/MacOS|VMS|MSWin|os2|NetWare/i ) +{ $MailerType = 'smtp'; + $MailerBinary = $Mailers{$MailerType}; +} +else +{ for(my $i = 0 ; $i < @Mailers ; $i += 2) + { $MailerType = $Mailers[$i]; + if(my $binary = is_exe $Mailers{$MailerType}) + { $MailerBinary = $binary; + last; + } + } +} + +sub import +{ shift; # class + @_ or return; + + my $type = shift; + my $exe = shift || $Mailers{$type}; + + is_exe $exe + or carp "Cannot locate '$exe'"; + + $MailerType = $type; + $Mailers{$MailerType} = $exe; +} + +sub to_array($) +{ my ($self, $thing) = @_; + ref $thing ? @$thing : $thing; +} + +sub is_exe($) +{ my $exe = shift || ''; + + foreach my $cmd (split /\;/, $exe) + { $cmd =~ s/^\s+//; + + # remove any options + my $name = ($cmd =~ /^(\S+)/)[0]; + + # check for absolute or relative path + return $cmd + if -x $name && ! -d $name && $name =~ m![\\/]!; + + if(defined $ENV{PATH}) + { foreach my $dir (split /$Config{path_sep}/, $ENV{PATH}) + { return "$dir/$cmd" + if -x "$dir/$name" && ! -d "$dir/$name"; + } + } + } + 0; +} + + +sub new($@) +{ my ($class, $type, @args) = @_; + + unless($type) + { $MailerType or croak "No MailerType specified"; + + warn "No real MTA found, using '$MailerType'" + if $MailerType eq 'testfile'; + + $type = $MailerType; + } + + my $exe = $Mailers{$type}; + + if(defined $exe) + { $exe = is_exe $exe + if defined $type; + + $exe ||= $MailerBinary + or croak "No mailer type specified (and no default available), thus can not find executable program."; + } + + $class = "Mail::Mailer::$type"; + eval "require $class" or die $@; + + my $glob = $class->SUPER::new; # object is a GLOB! + %{*$glob} = (Exe => $exe, Args => [ @args ]); + $glob; +} + + +sub open($) +{ my ($self, $hdrs) = @_; + my $exe = *$self->{Exe}; # no exe, then direct smtp + my $args = *$self->{Args}; + + my @to = $self->who_to($hdrs); + my $sender = $self->who_sender($hdrs); + + $self->close; # just in case; + + if(defined $exe) + { # Fork and start a mailer + my $child = open $self, '|-'; + defined $child or die "Failed to send: $!"; + + if($child==0) + { # Child process will handle sending, but this is not real exec() + # this is a setup!!! + unless($self->exec($exe, $args, \@to, $sender)) + { warn $!; # setup failed + _exit(1); # no DESTROY(), keep it for parent + } + } + } + else + { # Sending is handled by a subclass + $self->exec(undef, $args, \@to) + or die $!; + } + + $self->set_headers($hdrs); + $self; +} + +sub _cleanup_hdrs($) +{ foreach my $h (values %{(shift)}) + { foreach (ref $h ? @$h : $h) + { s/\n\s*/ /g; + s/\s+$//; + } + } +} + +sub exec($$$$) +{ my($self, $exe, $args, $to, $sender) = @_; + + # Fork and exec the mailer (no shell involved to avoid risks) + my @exe = split /\s+/, $exe; + exec @exe, @$args, @$to; +} + +sub can_cc { 1 } # overridden in subclass for mailer that can't + +sub who_to($) +{ my($self, $hdrs) = @_; + my @to = $self->to_array($hdrs->{To}); + unless($self->can_cc) # Can't cc/bcc so add them to @to + { push @to, $self->to_array($hdrs->{Cc} ) if $hdrs->{Cc}; + push @to, $self->to_array($hdrs->{Bcc}) if $hdrs->{Bcc}; + } + @to; +} + +sub who_sender($) +{ my ($self, $hdrs) = @_; + ($self->to_array($hdrs->{Sender} || $hdrs->{From}))[0]; +} + +sub epilogue { + # This could send a .signature, also see ::smtp subclass +} + +sub close(@) +{ my $self = shift; + fileno $self or return; + + $self->epilogue; + CORE::close $self; +} + +sub DESTROY { shift->close } + +#-------------- + +1; diff --git a/cpan/dist/MailTools/lib/Mail/Mailer.pod b/cpan/dist/MailTools/lib/Mail/Mailer.pod new file mode 100644 index 00000000..7b9c63f9 --- /dev/null +++ b/cpan/dist/MailTools/lib/Mail/Mailer.pod @@ -0,0 +1,152 @@ +=encoding utf8 + +=head1 NAME + +Mail::Mailer - send simple emails + +=head1 INHERITANCE + + Mail::Mailer + is a IO::Handle + +=head1 SYNOPSIS + + use Mail::Mailer; + use Mail::Mailer qw(mail); # specifies default mailer + + $mailer = Mail::Mailer->new; + $mailer = Mail::Mailer->new($type, @args); + + $mailer->open(\%headers); + print $mailer $body; + $mailer->close + or die "couldn't send whole message: $!\n"; + +=head1 DESCRIPTION + +Sends mail using any of the built-in methods. As TYPE argument +to L<new()|Mail::Mailer/"Constructors">, you can specify any of + +=over 4 + +=item C<sendmail> + +Use the C<sendmail> program to deliver the mail. + +=item C<smtp> + +Use the C<smtp> protocol via Net::SMTP to deliver the mail. The server +to use can be specified in C<@args> with + + $mailer = Mail::Mailer->new('smtp', Server => $server); + +The smtp mailer does not handle C<Cc> and C<Bcc> lines, neither their +C<Resent-*> fellows. The C<Debug> options enables debugging output +from C<Net::SMTP>. + +You may also use the C<< Auth => [ $user, $password ] >> option for SASL +authentication. To make this work, you have to install the L<Authen::SASL> +distribution yourself: it is not automatically installed. + +=item C<smtps> + +Use the smtp over ssl protocol via L<Net::SMTP::SSL> to deliver the mail. +Usage is identical to C<smtp>. You have to install Authen::SASL as +well. + + $mailer = Mail::Mailer->new('smtps', Server => $server); + +=item C<qmail> + +Use qmail's qmail-inject program to deliver the mail. + +=item C<testfile> + +Used for debugging, this displays the data to the file named in +C<$Mail::Mailer::testfile::config{outfile}> which defaults to a file +named C<mailer.testfile>. No mail is ever sent. + +=back + +C<Mail::Mailer> will search for executables in the above order. The +default mailer will be the first one found. + +=head1 METHODS + +=head2 Constructors + +=over 4 + +=item Mail::Mailer-E<gt>B<new>(TYPE, ARGS) + +The TYPE is one of the back-end sender implementations, as described in +the DESCRIPTION chapter of this manual page. The ARGS are passed to +that back-end. + +=item $obj-E<gt>B<open>(HASH) + +The HASH consists of key and value pairs, the key being the name of +the header field (eg, C<To>), and the value being the corresponding +contents of the header field. The value can either be a scalar +(eg, C<gnat@frii.com>) or a reference to an array of scalars +(C<< eg, ['gnat@frii.com', 'Tim.Bunce@ig.co.uk'] >>). + +=back + +=head1 DETAILS + +=head2 ENVIRONMENT VARIABLES + +=over 4 + +=item PERL_MAILERS + +Augments/override the build in choice for binary used to send out +our mail messages. + +Format: + + "type1:mailbinary1;mailbinary2;...:type2:mailbinaryX;...:..." + +Example: assume you want you use private sendmail binary instead +of mailx, one could set C<PERL_MAILERS> to: + + "mail:/does/not/exists:sendmail:$HOME/test/bin/sendmail" + +On systems which may include C<:> in file names, use C<|> as separator +between type-groups. + + "mail:c:/does/not/exists|sendmail:$HOME/test/bin/sendmail" + +=back + +=head2 BUGS + +Mail::Mailer does not help with folding, and does not protect +against various web-script hacker attacks, for instance where +a new-line is inserted in the content of the field. + +=head1 SEE ALSO + +This module is part of the MailTools distribution, +F<http://perl.overmeer.net/mailtools/>. + +=head1 AUTHORS + +The MailTools bundle was developed by Graham Barr. Later, Mark +Overmeer took over maintenance without commitment to further development. + +Mail::Cap by Gisle Aas E<lt>aas@oslonett.noE<gt>. +Mail::Field::AddrList by Peter Orbaek E<lt>poe@cit.dkE<gt>. +Mail::Mailer and Mail::Send by Tim Bunce E<lt>Tim.Bunce@ig.co.ukE<gt>. +For other contributors see ChangeLog. + +=head1 LICENSE + +Copyrights 1995-2000 Graham Barr E<lt>gbarr@pobox.comE<gt> and +2001-2017 Mark Overmeer E<lt>perl@overmeer.netE<gt>. + +This program is free software; you can redistribute it and/or modify it +under the same terms as Perl itself. +See F<http://www.perl.com/perl/misc/Artistic.html> + diff --git a/cpan/dist/MailTools/lib/Mail/Mailer/qmail.pm b/cpan/dist/MailTools/lib/Mail/Mailer/qmail.pm new file mode 100644 index 00000000..19660675 --- /dev/null +++ b/cpan/dist/MailTools/lib/Mail/Mailer/qmail.pm @@ -0,0 +1,22 @@ +# Copyrights 1995-2017 by [Mark Overmeer <perl@overmeer.net>]. +# For other contributors see ChangeLog. +# See the manual pages for details on the licensing terms. +# Pod stripped from pm file by OODoc 2.02. + +use strict; + +package Mail::Mailer::qmail; +use vars '$VERSION'; +$VERSION = '2.19'; + +use base 'Mail::Mailer::rfc822'; + +sub exec($$$$) +{ my($self, $exe, $args, $to, $sender) = @_; + my $address = defined $sender && $sender =~ m/\<(.*?)\>/ ? $1 : $sender; + + exec($exe, (defined $address ? "-f$address" : ())); + die "ERROR: cannot run $exe: $!"; +} + +1; diff --git a/cpan/dist/MailTools/lib/Mail/Mailer/rfc822.pm b/cpan/dist/MailTools/lib/Mail/Mailer/rfc822.pm new file mode 100644 index 00000000..c87e76f5 --- /dev/null +++ b/cpan/dist/MailTools/lib/Mail/Mailer/rfc822.pm @@ -0,0 +1,30 @@ +# Copyrights 1995-2017 by [Mark Overmeer <perl@overmeer.net>]. +# For other contributors see ChangeLog. +# See the manual pages for details on the licensing terms. +# Pod stripped from pm file by OODoc 2.02. +use strict; + +package Mail::Mailer::rfc822; +use vars '$VERSION'; +$VERSION = '2.19'; + +use base 'Mail::Mailer'; + +sub set_headers +{ my ($self, $hdrs) = @_; + + local $\ = ""; + + foreach (keys %$hdrs) + { next unless m/^[A-Z]/; + + foreach my $h ($self->to_array($hdrs->{$_})) + { $h =~ s/\n+\Z//; + print $self "$_: $h\n"; + } + } + + print $self "\n"; # terminate headers +} + +1; diff --git a/cpan/dist/MailTools/lib/Mail/Mailer/sendmail.pm b/cpan/dist/MailTools/lib/Mail/Mailer/sendmail.pm new file mode 100644 index 00000000..343b6cc1 --- /dev/null +++ b/cpan/dist/MailTools/lib/Mail/Mailer/sendmail.pm @@ -0,0 +1,26 @@ +# Copyrights 1995-2017 by [Mark Overmeer <perl@overmeer.net>]. +# For other contributors see ChangeLog. +# See the manual pages for details on the licensing terms. +# Pod stripped from pm file by OODoc 2.02. +use strict; + +package Mail::Mailer::sendmail; +use vars '$VERSION'; +$VERSION = '2.19'; + +use base 'Mail::Mailer::rfc822'; + +sub exec($$$$) +{ my($self, $exe, $args, $to, $sender) = @_; + # Fork and exec the mailer (no shell involved to avoid risks) + + # We should always use a -t on sendmail so that Cc: and Bcc: work + # Rumor: some sendmails may ignore or break with -t (AIX?) + # Chopped out the @$to arguments, because -t means + # they are sent in the body, and postfix complains if they + # are also given on command line. + + exec( $exe, '-t', @$args ); +} + +1; diff --git a/cpan/dist/MailTools/lib/Mail/Mailer/smtp.pm b/cpan/dist/MailTools/lib/Mail/Mailer/smtp.pm new file mode 100644 index 00000000..aa5e4a87 --- /dev/null +++ b/cpan/dist/MailTools/lib/Mail/Mailer/smtp.pm @@ -0,0 +1,103 @@ +# Copyrights 1995-2017 by [Mark Overmeer <perl@overmeer.net>]. +# For other contributors see ChangeLog. +# See the manual pages for details on the licensing terms. +# Pod stripped from pm file by OODoc 2.02. +use strict; + +package Mail::Mailer::smtp; +use vars '$VERSION'; +$VERSION = '2.19'; + +use base 'Mail::Mailer::rfc822'; + +use Net::SMTP; +use Mail::Util qw(mailaddress); +use Carp; + +sub can_cc { 0 } + +sub exec { + my ($self, $exe, $args, $to) = @_; + my %opt = @$args; + my $host = $opt{Server} || undef; + $opt{Debug} ||= 0; + + my $smtp = Net::SMTP->new($host, %opt) + or return undef; + + if($opt{Auth}) + { $smtp->auth(@{$opt{Auth}}) + or return undef; + } + + ${*$self}{sock} = $smtp; + + $smtp->mail($opt{From} || mailaddress()); + $smtp->to($_) for @$to; + $smtp->data; + + untie *$self if tied *$self; + tie *$self, 'Mail::Mailer::smtp::pipe', $self; + $self; +} + +sub set_headers($) +{ my ($self, $hdrs) = @_; + $self->SUPER::set_headers + ( { From => "<" . mailaddress() . ">" + , %$hdrs + , 'X-Mailer' => "Mail::Mailer[v$Mail::Mailer::VERSION] Net::SMTP[v$Net::SMTP::VERSION]" + } + ); +} + +sub epilogue() +{ my $self = shift; + my $sock = ${*$self}{sock}; + + my $ok = $sock->dataend; + $sock->quit; + + delete ${*$self}{sock}; + untie *$self; + $ok; +} + +sub close(@) +{ my ($self, @to) = @_; + my $sock = ${*$self}{sock}; + + $sock && fileno $sock + or return 1; + + my $ok = $self->epilogue; + + # Epilogue should destroy the SMTP filehandle, + # but just to be on the safe side. + $sock && fileno $sock + or return $ok; + + close $sock + or croak 'Cannot destroy socket filehandle'; + + $ok; +} + +package Mail::Mailer::smtp::pipe; +use vars '$VERSION'; +$VERSION = '2.19'; + + +sub TIEHANDLE +{ my ($class, $self) = @_; + my $sock = ${*$self}{sock}; + bless \$sock, $class; +} + +sub PRINT +{ my $self = shift; + my $sock = $$self; + $sock->datasend( @_ ); +} + +1; diff --git a/cpan/dist/MailTools/lib/Mail/Mailer/smtps.pm b/cpan/dist/MailTools/lib/Mail/Mailer/smtps.pm new file mode 100644 index 00000000..90d10efc --- /dev/null +++ b/cpan/dist/MailTools/lib/Mail/Mailer/smtps.pm @@ -0,0 +1,108 @@ +# Copyrights 1995-2017 by [Mark Overmeer <perl@overmeer.net>]. +# For other contributors see ChangeLog. +# See the manual pages for details on the licensing terms. +# Pod stripped from pm file by OODoc 2.02. +# Based on smtp.pm, adapted by Maciej Żenczykowski + +use strict; + +package Mail::Mailer::smtps; +use vars '$VERSION'; +$VERSION = '2.19'; + +use base 'Mail::Mailer::rfc822'; + +use Net::SMTP::SSL; +use Mail::Util qw(mailaddress); +use Carp; + +sub can_cc { 0 } + +sub exec { + my ($self, $exe, $args, $to) = @_; + my %opt = @$args; + my $host = $opt{Server} || undef; + $opt{Debug} ||= 0; + $opt{Port} ||= 465; + + my $smtp = Net::SMTP::SSL->new($host, %opt) + or return undef; + + if($opt{Auth}) + { $smtp->auth(@{$opt{Auth}}) + or return undef; + } + + ${*$self}{sock} = $smtp; + + $smtp->mail($opt{From} || mailaddress); + $smtp->to($_) for @$to; + $smtp->data; + + untie *$self if tied *$self; + tie *$self, 'Mail::Mailer::smtps::pipe', $self; + $self; +} + +sub set_headers($) +{ my ($self, $hdrs) = @_; + $self->SUPER::set_headers + ( { From => "<" . mailaddress() . ">" + , %$hdrs + , 'X-Mailer' => "Mail::Mailer[v$Mail::Mailer::VERSION] " + . " Net::SMTP[v$Net::SMTP::VERSION]" + . " Net::SMTP::SSL[v$Net::SMTP::SSL::VERSION]" + } + ); +} + +sub epilogue() +{ my $self = shift; + my $sock = ${*$self}{sock}; + + my $ok = $sock->dataend; + $sock->quit; + + delete ${*$self}{sock}; + untie *$self; + $ok; +} + +sub close(@) +{ my ($self, @to) = @_; + my $sock = ${*$self}{sock}; + + $sock && fileno $sock + or return 1; + + my $ok = $self->epilogue; + + # Epilogue should destroy the SMTP filehandle, + # but just to be on the safe side. + $sock && fileno $sock + or return $ok; + + close $sock + or croak 'Cannot destroy socket filehandle'; + + $ok; +} + +package Mail::Mailer::smtps::pipe; +use vars '$VERSION'; +$VERSION = '2.19'; + + +sub TIEHANDLE +{ my ($class, $self) = @_; + my $sock = ${*$self}{sock}; + bless \$sock, $class; +} + +sub PRINT +{ my $self = shift; + my $sock = $$self; + $sock->datasend( @_ ); +} + +1; diff --git a/cpan/dist/MailTools/lib/Mail/Mailer/testfile.pm b/cpan/dist/MailTools/lib/Mail/Mailer/testfile.pm new file mode 100644 index 00000000..94dcad40 --- /dev/null +++ b/cpan/dist/MailTools/lib/Mail/Mailer/testfile.pm @@ -0,0 +1,54 @@ +# Copyrights 1995-2017 by [Mark Overmeer <perl@overmeer.net>]. +# For other contributors see ChangeLog. +# See the manual pages for details on the licensing terms. +# Pod stripped from pm file by OODoc 2.02. +use strict; + +package Mail::Mailer::testfile; +use vars '$VERSION'; +$VERSION = '2.19'; + +use base 'Mail::Mailer::rfc822'; + +use Mail::Util qw/mailaddress/; + +my $num = 0; +sub can_cc() { 0 } + +sub exec($$$) +{ my ($self, $exe, $args, $to) = @_; + + my $outfn = $Mail::Mailer::testfile::config{outfile} || 'mailer.testfile'; + open F, '>>', $outfn + or die "Cannot append message to testfile $outfn: $!"; + + print F "\n===\ntest ", ++$num, " ", (scalar localtime), + "\nfrom: " . mailaddress(), + "\nto: " . join(' ',@{$to}), "\n\n"; + close F; + + untie *$self if tied *$self; + tie *$self, 'Mail::Mailer::testfile::pipe', $self; + $self; +} + +sub close { 1 } + +package Mail::Mailer::testfile::pipe; +use vars '$VERSION'; +$VERSION = '2.19'; + + +sub TIEHANDLE +{ my ($class, $self) = @_; + bless \$self, $class; +} + +sub PRINT +{ my $self = shift; + open F, '>>', $Mail::Mailer::testfile::config{outfile} || 'mailer.testfile'; + print F @_; + close F; +} + +1; diff --git a/cpan/dist/MailTools/lib/Mail/Send.pm b/cpan/dist/MailTools/lib/Mail/Send.pm new file mode 100644 index 00000000..01add435 --- /dev/null +++ b/cpan/dist/MailTools/lib/Mail/Send.pm @@ -0,0 +1,63 @@ +# Copyrights 1995-2017 by [Mark Overmeer <perl@overmeer.net>]. +# For other contributors see ChangeLog. +# See the manual pages for details on the licensing terms. +# Pod stripped from pm file by OODoc 2.02. +package Mail::Send; +use vars '$VERSION'; +$VERSION = '2.19'; + + +use strict; + +use Mail::Mailer (); + +sub Version { our $VERSION } + +#------------------ + +sub new(@) +{ my ($class, %attr) = @_; + my $self = bless {}, $class; + + while(my($key, $value) = each %attr) + { $key = lc $key; + $self->$key($value); + } + + $self; +} + +#--------------- + +sub set($@) +{ my ($self, $hdr, @values) = @_; + $self->{$hdr} = [ @values ] if @values; + @{$self->{$hdr} || []}; # return new (or original) values +} + + +sub add($@) +{ my ($self, $hdr, @values) = @_; + push @{$self->{$hdr}}, @values; +} + + +sub delete($) +{ my($self, $hdr) = @_; + delete $self->{$hdr}; +} + + +sub to { my $self=shift; $self->set('To', @_); } +sub cc { my $self=shift; $self->set('Cc', @_); } +sub bcc { my $self=shift; $self->set('Bcc', @_); } +sub subject { my $self=shift; $self->set('Subject', join (' ', @_)); } + +#--------------- + +sub open(@) +{ my $self = shift; + Mail::Mailer->new(@_)->open($self); +} + +1; diff --git a/cpan/dist/MailTools/lib/Mail/Send.pod b/cpan/dist/MailTools/lib/Mail/Send.pod new file mode 100644 index 00000000..bda52154 --- /dev/null +++ b/cpan/dist/MailTools/lib/Mail/Send.pod @@ -0,0 +1,116 @@ +=encoding utf8 + +=head1 NAME + +Mail::Send - Simple electronic mail interface + +=head1 SYNOPSIS + + require Mail::Send; + + $msg = Mail::Send->new; + $msg = Mail::Send->new(Subject => 'example', To => 'timbo'); + + $msg->to('user@host'); + $msg->to('user@host', 'user2@example.com'); + $msg->subject('example subject'); + $msg->cc('user@host'); + $msg->bcc('someone@else'); + + $msg->set($header, @values); + $msg->add($header, @values); + $msg->delete($header); + + # Launch mailer and set headers. The filehandle returned + # by open() is an instance of the Mail::Mailer class. + # Arguments to the open() method are passed to the Mail::Mailer + # constructor. + + $fh = $msg->open; # some default mailer + $fh = $msg->open('sendmail'); # explicit + print $fh "Body of message"; + $fh->close # complete the message and send it + or die "couldn't send whole message: $!\n"; + +=head1 DESCRIPTION + +L<Mail::Send|Mail::Send> creates e-mail messages without using the L<Mail::Header|Mail::Header> +knowledge, which means that all escaping and folding must be done by +you! Simplicity has its price. + +When you have time, take a look at Mail::Transport + +=head1 METHODS + +=head2 Constructors + +=over 4 + +=item Mail::Send-E<gt>B<new>(PAIRS) + +A list of header fields (provided as key-value PAIRS) can be +used to initialize the object. + +=back + +=head2 Header fields + +=over 4 + +=item $obj-E<gt>B<add>(FIELDNAME, VALUES) + +Add values to the list of defined values for the FIELDNAME. + +=item $obj-E<gt>B<bcc>(VALUES) + +=item $obj-E<gt>B<cc>(VALUES) + +=item $obj-E<gt>B<delete>(FIELDNAME) + +=item $obj-E<gt>B<set>(FIELDNAME, VALUES) + +VALUES will replace the old values for the FIELDNAME. Returned is +the LIST of values after modification. + +=item $obj-E<gt>B<subject>(VALUES) + +=item $obj-E<gt>B<to>(VALUES) + +=back + +=head2 Sending + +=over 4 + +=item $obj-E<gt>B<open>(OPTIONS) + +The OPTIONS are used to initiate a mailer object via +L<Mail::Mailer::new()|Mail::Mailer/"Constructors">. Then L<Mail::Mailer::open()|Mail::Mailer/"Constructors"> is called +with the knowledge collected in this Mail::Send object. + +=back + +=head1 SEE ALSO + +This module is part of the MailTools distribution, +F<http://perl.overmeer.net/mailtools/>. + +=head1 AUTHORS + +The MailTools bundle was developed by Graham Barr. Later, Mark +Overmeer took over maintenance without commitment to further development. + +Mail::Cap by Gisle Aas E<lt>aas@oslonett.noE<gt>. +Mail::Field::AddrList by Peter Orbaek E<lt>poe@cit.dkE<gt>. +Mail::Mailer and Mail::Send by Tim Bunce E<lt>Tim.Bunce@ig.co.ukE<gt>. +For other contributors see ChangeLog. + +=head1 LICENSE + +Copyrights 1995-2000 Graham Barr E<lt>gbarr@pobox.comE<gt> and +2001-2017 Mark Overmeer E<lt>perl@overmeer.netE<gt>. + +This program is free software; you can redistribute it and/or modify it +under the same terms as Perl itself. +See F<http://www.perl.com/perl/misc/Artistic.html> + diff --git a/cpan/dist/MailTools/lib/Mail/Util.pm b/cpan/dist/MailTools/lib/Mail/Util.pm new file mode 100644 index 00000000..af7894a7 --- /dev/null +++ b/cpan/dist/MailTools/lib/Mail/Util.pm @@ -0,0 +1,151 @@ +# Copyrights 1995-2017 by [Mark Overmeer <perl@overmeer.net>]. +# For other contributors see ChangeLog. +# See the manual pages for details on the licensing terms. +# Pod stripped from pm file by OODoc 2.02. +package Mail::Util; +use vars '$VERSION'; +$VERSION = '2.19'; + +use base 'Exporter'; + +use strict; +use Carp; + +our @EXPORT_OK = qw(read_mbox maildomain mailaddress); + +sub Version { our $VERSION } + +my ($domain, $mailaddress); +my @sendmailcf = qw(/etc /etc/sendmail /etc/ucblib + /etc/mail /usr/lib /var/adm/sendmail); + + +sub read_mbox($) +{ my $file = shift; + + local *FH; + open FH,'<', $file + or croak "cannot open '$file': $!\n"; + + local $_; + my @mbox; + my $mail = []; + my $blank = 1; + + while(<FH>) + { if($blank && /^From .*\d{4}/) + { push @mbox, $mail if @$mail; + $mail = [ $_ ]; + $blank = 0; + } + else + { $blank = m/^$/ ? 1 : 0; + push @$mail, $_; + } + } + + push @mbox, $mail if @$mail; + close FH; + + wantarray ? @mbox : \@mbox; +} + + +sub maildomain() +{ return $domain + if defined $domain; + + $domain = $ENV{MAILDOMAIN} + and return $domain; + + # Try sendmail configuration file + + my $config = (grep -r, map {"$_/sendmail.cf"} @sendmailcf)[0]; + + local *CF; + local $_; + if(defined $config && open CF, '<', $config) + { my %var; + while(<CF>) + { if(my ($v, $arg) = /^D([a-zA-Z])([\w.\$\-]+)/) + { $arg =~ s/\$([a-zA-Z])/exists $var{$1} ? $var{$1} : '$'.$1/eg; + $var{$v} = $arg; + } + } + close CF; + $domain = $var{j} if defined $var{j}; + $domain = $var{M} if defined $var{M}; + + $domain = $1 + if $domain && $domain =~ m/([A-Za-z0-9](?:[\.\-A-Za-z0-9]+))/; + + return $domain + if defined $domain && $domain !~ /\$/; + } + + # Try smail config file if exists + + if(open CF, '<', "/usr/lib/smail/config") + { while(<CF>) + { if( /\A\s*hostnames?\s*=\s*(\S+)/ ) + { $domain = (split /\:/,$1)[0]; + last; + } + } + close CF; + + return $domain + if defined $domain; + } + + # Try a SMTP connection to 'mailhost' + + if(eval {require Net::SMTP}) + { foreach my $host (qw(mailhost localhost)) + { # hosts are local, so short timeout + my $smtp = eval { Net::SMTP->new($host, Timeout => 5) }; + if(defined $smtp) + { $domain = $smtp->domain; + $smtp->quit; + last; + } + } + } + + # Use internet(DNS) domain name, if it can be found + $domain = Net::Domain::domainname() + if !defined $domain && eval {require Net::Domain}; + + $domain ||= "localhost"; +} + + +sub mailaddress(;$) +{ $mailaddress = shift if @_; + + return $mailaddress + if defined $mailaddress; + + # Get user name from environment + $mailaddress = $ENV{MAILADDRESS}; + + unless($mailaddress || $^O ne 'MacOS') + { require Mac::InternetConfig; + + no strict; + Mac::InternetConfig->import; + $mailaddress = $InternetConfig{kICEmail()}; + } + + $mailaddress ||= $ENV{USER} || $ENV{LOGNAME} || eval {getpwuid $>} + || "postmaster"; + + # Add domain if it does not exist + $mailaddress .= '@' . maildomain + if $mailaddress !~ /\@/; + + $mailaddress =~ s/(^.*<|>.*$)//g; + $mailaddress; +} + +1; diff --git a/cpan/dist/MailTools/lib/Mail/Util.pod b/cpan/dist/MailTools/lib/Mail/Util.pod new file mode 100644 index 00000000..8eb71268 --- /dev/null +++ b/cpan/dist/MailTools/lib/Mail/Util.pod @@ -0,0 +1,119 @@ +=encoding utf8 + +=head1 NAME + +Mail::Util - mail utility functions + +=head1 INHERITANCE + + Mail::Util + is a Exporter + +=head1 SYNOPSIS + + use Mail::Util qw( ... ); + +=head1 DESCRIPTION + +This package provides several mail related utility functions. Any function +required must by explicitly listed on the use line to be exported into +the calling package. + +=head1 FUNCTIONS + +=over 4 + +=item B<mailaddress>( [ADDRESS] ) + +Return a guess at the current users mail address. The user can force +the return value by setting the MAILADDRESS environment variable. +[2.10] You may set the ADDRESS via the parameter. + +WARNING: +When not supplied via the environment variable, <mailaddress> looks at +various configuration files and other environmental data. Although this +seems to be smart behavior, this is not predictable enough (IMHO) to +be used. Please set the MAILADDRESS explicitly, and do not trust on +the "automatic detection", even when that produces a correct address +(on the moment) + +example: + + # in your main script + $ENV{MAILADDRESS} = 'me@example.com'; + + # everywhere else + use Mail::Util 'mailaddress'; + print mailaddress; + + # since v2.10 + mailaddress "me@example.com"; + +=item B<maildomain>() + +Attempt to determine the current user mail domain string via the following +methods + +=over 4 + +=item * Look for the MAILDOMAIN environment variable, which can be set from outside the program. This is by far the best way to configure the domain. + +=item * Look for a sendmail.cf file and extract DH parameter + +=item * Look for a smail config file and usr the first host defined in hostname(s) + +=item * Try an SMTP connect (if Net::SMTP exists) first to mailhost then localhost + +=item * Use value from Net::Domain::domainname (if Net::Domain exists) + +=back + +WARNING: +On modern machines, there is only one good way to provide information to +this method: the first; always explicitly configure the MAILDOMAIN. + +example: + + # in your main script + $ENV{MAILDOMAIN} = 'example.com'; + + # everywhere else + use Mail::Util 'maildomain'; + print maildomain; + +=item B<read_mbox>(FILE) + +Read FILE, a binmail mailbox file, and return a list of references. +Each reference is a reference to an array containing one message. + +WARNING: +This method does not quote lines which accidentally also start with the +message separator C<From>, so this implementation can be considered +broken. See Mail::Box::Mbox + +=back + +=head1 SEE ALSO + +This module is part of the MailTools distribution, +F<http://perl.overmeer.net/mailtools/>. + +=head1 AUTHORS + +The MailTools bundle was developed by Graham Barr. Later, Mark +Overmeer took over maintenance without commitment to further development. + +Mail::Cap by Gisle Aas E<lt>aas@oslonett.noE<gt>. +Mail::Field::AddrList by Peter Orbaek E<lt>poe@cit.dkE<gt>. +Mail::Mailer and Mail::Send by Tim Bunce E<lt>Tim.Bunce@ig.co.ukE<gt>. +For other contributors see ChangeLog. + +=head1 LICENSE + +Copyrights 1995-2000 Graham Barr E<lt>gbarr@pobox.comE<gt> and +2001-2017 Mark Overmeer E<lt>perl@overmeer.netE<gt>. + +This program is free software; you can redistribute it and/or modify it +under the same terms as Perl itself. +See F<http://www.perl.com/perl/misc/Artistic.html> + diff --git a/cpan/dist/MailTools/lib/MailTools.pm b/cpan/dist/MailTools/lib/MailTools.pm new file mode 100644 index 00000000..77accb7d --- /dev/null +++ b/cpan/dist/MailTools/lib/MailTools.pm @@ -0,0 +1,11 @@ +# Copyrights 1995-2017 by [Mark Overmeer <perl@overmeer.net>]. +# For other contributors see ChangeLog. +# See the manual pages for details on the licensing terms. +# Pod stripped from pm file by OODoc 2.02. +package MailTools; +use vars '$VERSION'; +$VERSION = '2.19'; + + + +1; diff --git a/cpan/dist/MailTools/lib/MailTools.pod b/cpan/dist/MailTools/lib/MailTools.pod new file mode 100644 index 00000000..17d25a5f --- /dev/null +++ b/cpan/dist/MailTools/lib/MailTools.pod @@ -0,0 +1,92 @@ +=encoding utf8 + +=head1 NAME + +MailTools - bundle of ancient email modules + +=head1 SYNOPSIS + + # This is a place-holder for the distribution + +=head1 DESCRIPTION + +MailTools is a bundle: an ancient form of combining packages into one +distribution. Gladly, it can be distributed as if it is a normal +distribution as well. + +B<Be warned:> The code you find here is very old. It works for simple +emails, but when you start with new code then please use more +sofisticated libraries. The main reason that you still find this code +on CPAN, is because many books use it as example. + +=head2 Component + +In this distribution, you find + +=over 4 + +=item Mail::Address + +Parse email address from a header line. + +=item Mail::Cap + +Interpret mailcap files: mappings of file-types to applications as used +by many command-line email programs. + +=item Mail::Field + +Simplifies access to (some) email header fields. Used by L<Mail::Header|Mail::Header>. + +=item Mail::Filter + +Process L<Mail::Internet|Mail::Internet> messages. + +=item Mail::Header + +Collection of L<Mail::Field|Mail::Field> objects, representing the header of a +L<Mail::Internet|Mail::Internet> object. + +=item Mail::Internet + +Represents a single email message, with header and body. + +=item Mail::Mailer + +Send L<Mail::Internet|Mail::Internet> emails via direct smtp or local MTA's. + +=item Mail::Send + +Build a L<Mail::Internet|Mail::Internet> object, and then send it out using +L<Mail::Mailer|Mail::Mailer>. + +=item Mail::Util + +"Smart functions" you should not depend on. + +=back + +=head1 SEE ALSO + +This module is part of the MailTools distribution, +F<http://perl.overmeer.net/mailtools/>. + +=head1 AUTHORS + +The MailTools bundle was developed by Graham Barr. Later, Mark +Overmeer took over maintenance without commitment to further development. + +Mail::Cap by Gisle Aas E<lt>aas@oslonett.noE<gt>. +Mail::Field::AddrList by Peter Orbaek E<lt>poe@cit.dkE<gt>. +Mail::Mailer and Mail::Send by Tim Bunce E<lt>Tim.Bunce@ig.co.ukE<gt>. +For other contributors see ChangeLog. + +=head1 LICENSE + +Copyrights 1995-2000 Graham Barr E<lt>gbarr@pobox.comE<gt> and +2001-2017 Mark Overmeer E<lt>perl@overmeer.netE<gt>. + +This program is free software; you can redistribute it and/or modify it +under the same terms as Perl itself. +See F<http://www.perl.com/perl/misc/Artistic.html> + diff --git a/cpan/dist/MailTools/xt/99pod.t b/cpan/dist/MailTools/xt/99pod.t new file mode 100644 index 00000000..ab9b19b2 --- /dev/null +++ b/cpan/dist/MailTools/xt/99pod.t @@ -0,0 +1,7 @@ +#!/usr/bin/perl +use warnings; +use strict; + +use Test::Pod; + +all_pod_files_ok(); |
