File Coverage

blib/lib/Mail/Send/Loop.pm
Criterion Covered Total %
statement 12 240 5.0
branch 0 76 0.0
condition 0 65 0.0
subroutine 4 15 26.6
pod 6 11 54.5
total 22 407 5.4


line stmt bran cond sub pod time code
1             package Mail::Send::Loop;
2            
3             # h2xs -O -AX -n Mail::Send::Loop -v 0.1
4            
5 1     1   18907 use strict;
  1         2  
  1         30  
6 1     1   3 use warnings;
  1         2  
  1         23  
7            
8 1     1   753 use IO::Socket;
  1         23330  
  1         4  
9 1     1   1703 use MIME::Lite;
  1         29078  
  1         2333  
10            
11             require Exporter;
12            
13             our @ISA = qw(Exporter);
14            
15             # Items to export into callers namespace by default. Note: do not export
16             # names by default without a very good reason. Use EXPORT_OK instead.
17             # Do not simply export all your public functions/methods/constants.
18            
19             # This allows declaration use Mail::Send::Loop ':all';
20             # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
21             # will save memory.
22             our %EXPORT_TAGS = ( 'all' => [ qw(
23            
24             ) ] );
25            
26             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
27            
28             our @EXPORT = qw(
29            
30             );
31            
32             our $VERSION = '0.3';
33            
34            
35             # -----
36             my $EOF = "\x0d\x0a";
37             my $SMTP_DATA = "DATA" . $EOF;
38             my $SMTP_QUIT = "QUIT" . $EOF;
39            
40             my $debug = 1;
41             my $recv_data;
42             my %gMediaTypes;
43             my $gCOUNT;
44            
45             sub new {
46 0     0 1   my ($unknown, %usr_parms)= @_;
47 0 0         my $class = ref($unknown) ? ref($unknown) : $unknown;
48            
49 0           my %obj_parms ;
50 0           while(my($k, $v) = each %usr_parms){
51 0           $obj_parms{lc($k)} = $v;
52             }
53            
54 0           my $self = {};
55            
56 0           $self->{mail_host} = $obj_parms{mail_host};
57 0   0       $self->{mail_port} = $obj_parms{mail_port} || 25;
58 0   0       $self->{greeting} = $obj_parms{greeting} || 'test.net';
59 0           $self->{debug} = $obj_parms{debug};
60 0           $self->{senders} = $obj_parms{senders};
61 0           $self->{recipients} = $obj_parms{recipients};
62 0   0       $self->{mail_mode} = $obj_parms{mail_mode} || '1tom'; # in 1 TCP session, how many emails sent
63 0   0       $self->{mail_count} = $obj_parms{mail_count}|| '0'; # 0 run once, # > 0, only send # of emails, -1 endless loop
64            
65 0 0         if( defined $self->{debug}){
66 0           $debug = 1;
67             }else{
68 0           undef $debug;
69             }
70            
71 0           &readMediaTypes(\%gMediaTypes);
72            
73 0           bless $self, $class;
74 0           $self;
75             }
76            
77             sub setDebug(){
78 0     0 1   my $self = shift;
79 0           my $status = shift;
80            
81 0 0         if( $status =~ /(off|0|disable)/i ){
82 0           undef $debug;
83             }else{
84 0           $debug = 1;
85             }
86             }
87            
88             sub emailMode(){
89 0     0 1   my $self = shift;
90 0   0       my $mode = shift || '';
91            
92 0 0         if( $mode =~ /(1tom|1to1)/i ){
93 0           $self->{mail_mode} = $mode;
94             }
95 0           return $self->{mail_mode};
96             }
97            
98             sub sendMail_EML(){
99 0     0 1   my $self = shift;
100 0           my $emlf = shift;
101 0           my $mailSender = shift;
102 0           my $recepient = shift;
103            
104 0 0         if( ! -e $emlf ){
105 0           print " Error: Cannot find $emlf\n";
106 0           return 0;
107             }
108            
109 0           open(INPUT, $emlf);
110 0           my $content = do { local $/; };
  0            
  0            
111 0           close INPUT;
112             #$content =~ s/\x0a\./\x0a\.\./sg; # . at beginning of the line need be 2
113            
114 0           my $mail_socket = &createMailSocket($self->{mail_host}, $self->{mail_port}, $self->{greeting});
115            
116 0           $gCOUNT++;
117 0           &sendMail_OneTcpSession(\$mail_socket, $mailSender, $recepient, $content);
118            
119 0           &closeMailSocket(\$mail_socket);
120            
121 0           return 1;
122             }
123            
124             sub sendMail_AllFilesInFolder(){
125 0     0 1   my $self = shift;
126 0           my %usr_parms = @_;
127            
128 0           my $mail_folder = $usr_parms{mail_folder};
129 0   0       my $mail_mode = $usr_parms{mail_mode} || $self->{mail_mode};
130 0   0       my $mail_subject= $usr_parms{mail_subject} || "send the file as attachment";
131 0   0       my $mail_text_bd= $usr_parms{mail_txt_body}|| "this is a test email with MIME attachment";
132 0   0       my $greeting = $usr_parms{greeting} || $self->{greeting};
133 0   0       my $sender_list = $usr_parms{senders} || $self->{senders};
134 0   0       my $rpient_list = $usr_parms{recipients} || $self->{recipients};
135 0   0       my $mail_count = $usr_parms{mail_count} || $self->{mail_count};
136            
137 0 0 0       if(! $sender_list || ! $rpient_list){
138 0           print " Error: please define sender and recipient lists!\n";
139 0           exit;
140             }
141            
142 0           $gCOUNT =0;
143            
144 0           my $mail_host = $self->{mail_host};
145 0           my $mail_port = $self->{mail_port};
146            
147 0           my @files = glob("$mail_folder/*.*");
148            
149 0           my $socketClosed; # TRUE or FALSE
150            
151             # when 0, send all files only once
152 0 0         $self->{mail_count} = $mail_count if( $mail_count =~ /^\d+$/ );
153 0 0         $self->{mail_count} = scalar @files if( $mail_count == 0);
154            
155 0           my $mail_socket;
156 0 0         $mail_socket = &createMailSocket($mail_host, $mail_port, $greeting) if($mail_mode =~ /1tom/i);
157            
158 0           while(1){
159 0           my @mailSender = ( @{$sender_list} ) x (int(scalar @files / scalar @{$sender_list}) + 1 ) ;
  0            
  0            
160 0           my @recepients = ( @{$rpient_list} ) x (int(scalar @files / scalar @{$rpient_list}) + 1 ) ;
  0            
  0            
161            
162 0           foreach(@files){
163 0           my $org = $_;
164            
165 0           $gCOUNT++;
166            
167 0 0         $mail_socket = &createMailSocket($mail_host, $mail_port, $greeting) if($mail_mode =~ /1to1/i);
168            
169 0 0         if($org =~ /\.eml$/i){
170 0 0         open(INPUT, $org) or die "Could not open file: org\n";
171 0           my $content = do { local $/; };
  0            
  0            
172 0           close INPUT;
173            
174 0           &sendMail_OneTcpSession(\$mail_socket, shift @mailSender, shift @recepients, $content);
175            
176             }else{
177 0           my $mSender = shift @mailSender;
178 0           my $mRecepient = shift @recepients;
179            
180             ### Create the multipart container
181 0 0         my $msg = MIME::Lite->new (
182             From => $mSender,
183             To => $mRecepient,
184             Subject => "$mail_subject: $mail_mode " . $gCOUNT,
185             Type =>'multipart/mixed'
186             ) or die "Error creating multipart container: $!\n";
187            
188 0           $org =~ /(.*)\.(.*)$/i;
189 0           my $ext = lc($2);
190             #print "$ext $gMediaTypes{$ext} \n";
191            
192             ### Add the text message part
193 0 0         $msg->attach (
194             Type => 'TEXT',
195             Data => $mail_text_bd
196             ) or die "Error adding the text message part: $!\n";
197            
198 0 0         $msg->attach (
199             Type => $gMediaTypes{$ext},
200             Path => $org,
201             Filename => $org,
202             Disposition => 'attachment'
203             ) or die "Error adding $org: $!\n";
204            
205 0           &sendMail_OneTcpSession(\$mail_socket, $mSender, $mRecepient, $msg->as_string);
206             }
207            
208 0 0         if($self->{mail_count} == $gCOUNT){
209 0           &closeMailSocket(\$mail_socket);
210 0           $socketClosed = 1;
211 0           goto MAIL_CLOSE;
212             }
213            
214 0 0         &closeMailSocket(\$mail_socket) if($mail_mode =~ /1to1/i);
215             }
216             }
217            
218             MAIL_CLOSE:
219 0 0 0       &closeMailSocket(\$mail_socket) if($mail_mode =~ /1tom/i && $socketClosed != 1);
220            
221 0           $self->{mail_count} = 0;
222 0           return $gCOUNT;
223             }
224            
225             sub sendMail_LoopAllUsers(){
226 0     0 1   my $self = shift;
227 0           my %usr_parms = @_;
228            
229 0           my $mail_body = $usr_parms{mail_body};
230 0   0       my $mail_mode = $usr_parms{mail_mode} || $self->{mail_mode};
231 0   0       my $greeting = $usr_parms{greeting} || $self->{greeting};
232 0   0       my $sender_list = $usr_parms{senders} || $self->{senders};
233 0   0       my $rpient_list = $usr_parms{recipients} || $self->{recipients};
234 0   0       my $mail_count = $usr_parms{mail_count} || $self->{mail_count};
235            
236 0           my $mail_host = $self->{mail_host};
237 0           my $mail_port = $self->{mail_port};
238            
239 0 0 0       if(! $sender_list || ! $rpient_list || ! $mail_body){
      0        
240 0           print " Error: please define sender, recipient lists and email body!\n";
241 0           exit;
242             }
243            
244 0           $gCOUNT =0;
245            
246 0           my $socketClosed;
247            
248             # when 0, send all files only once
249 0 0         $self->{mail_count} = $mail_count if( $mail_count =~ /^\d+$/ );
250 0 0         $self->{mail_count} = ( scalar @{$sender_list} ) * ( scalar @{$rpient_list} ) if( $mail_count == 0);
  0            
  0            
251            
252 0           my $mail_socket;
253 0 0         $mail_socket = &createMailSocket($mail_host, $mail_port, $greeting) if($mail_mode =~ /1tom/i);
254            
255 0           while(1){
256            
257 0           foreach(@{$sender_list}){
  0            
258 0           my $sender = $_;
259            
260 0           foreach(@{$rpient_list}){
  0            
261            
262 0 0         $mail_socket = &createMailSocket($mail_host, $mail_port, $greeting) if($mail_mode =~ /1to1/i);
263            
264 0           $gCOUNT++;
265 0           &sendMail_OneTcpSession(\$mail_socket, $sender, $_, $mail_body);
266            
267 0 0         if($self->{mail_count} == $gCOUNT){
268 0           &closeMailSocket(\$mail_socket);
269 0           $socketClosed = 1;
270 0           goto MAIL_CLOSE;
271             }
272            
273 0 0         &closeMailSocket(\$mail_socket) if($mail_mode =~ /1to1/i);
274             }
275             }
276             }
277            
278             MAIL_CLOSE:
279 0 0 0       &closeMailSocket(\$mail_socket) if($mail_mode =~ /1tom/i && $socketClosed != 1);
280            
281 0           $self->{mail_count} = 0;
282 0           return $gCOUNT;
283             }
284            
285             sub sendMail_OneTcpSession(){
286 0     0 0   my $SOCKET = shift;
287 0           my $mailf_addr = shift;
288 0           my $rcptT_addr = shift;
289 0           my $mail_body = shift;
290            
291 0           my $mail_socket = ${$SOCKET};
  0            
292            
293 0           my $mail_from = "MAIL FROM: " . $mailf_addr . $EOF;
294 0           my $rcpt_to = "RCPT TO: " . $rcptT_addr . $EOF;
295            
296             #MAIL FROM
297 0           $mail_socket->send($mail_from);
298 0           $mail_socket->recv($recv_data, 1024);
299 0 0         if( $recv_data !~ /^250/){
300 0           print " Error: $mail_from->$recv_data";
301 0           close $mail_socket;
302             }
303 0           &dbg_print("$mail_from->$recv_data");
304            
305             #RCPT TO
306 0           $mail_socket->send($rcpt_to);
307 0           $mail_socket->recv($recv_data, 1024);
308 0 0         if( $recv_data !~ /^250/){
309 0           print " Error: $rcpt_to\t\t->$recv_data";
310 0           close $mail_socket;
311             }
312 0           &dbg_print("$rcpt_to->$recv_data");
313            
314             #DATA
315 0           $mail_socket->send($SMTP_DATA);
316 0           $mail_socket->recv($recv_data, 1024);
317 0 0         if( $recv_data !~ /^354/){
318 0           print " Error: $SMTP_DATA->$recv_data";
319 0           close $mail_socket;
320             }
321 0           &dbg_print("$SMTP_DATA->$recv_data");
322            
323 0           $mail_socket->send( $mail_body . "$EOF\.$EOF");
324 0           $mail_socket->recv($recv_data, 1024);
325 0 0         if( $recv_data !~ /^250/){
326 0           print " Error: Mail Body->$recv_data";
327 0           close $mail_socket;
328             }
329 0           &dbg_print("Mail Body->$recv_data " . ' email length: ' . length($mail_body) . "\t $gCOUNT sent");
330             }
331            
332             sub createMailSocket(){
333 0   0 0 0   my $mail_host = shift || "127.0.0.1";
334 0   0       my $mail_port = shift || "25";
335 0   0       my $greeting = shift || "test.net";
336            
337 0           my $smtp_EHLO = "HELO $greeting" . $EOF;
338            
339 0 0         my $mail_socket = new IO::Socket::INET (
340             PeerAddr => $mail_host,
341             PeerPort => $mail_port,
342             Proto => 'tcp',
343             )
344             or die "Couldn't connect to Server\n";
345            
346             #Greeting
347 0           $mail_socket->recv($recv_data, 1024);
348 0 0         print "Greeting->$recv_data" if($debug);
349            
350             #EHLO
351 0           $mail_socket->send($smtp_EHLO);
352 0           $mail_socket->recv($recv_data, 1024);
353 0 0         if( $recv_data !~ /^250/){
354 0           print " Error: $smtp_EHLO->$recv_data";
355 0           close $mail_socket;
356             }
357 0           &dbg_print("$smtp_EHLO->$recv_data");
358 0           return $mail_socket;
359             }
360            
361             sub closeMailSocket(){
362 0     0 0   my $SOCKET = shift;
363 0           my $mail_socket = ${$SOCKET};
  0            
364            
365             #QUIT
366 0           $mail_socket->send( $SMTP_QUIT );
367 0           $mail_socket->recv($recv_data, 1024);
368 0 0         if( $recv_data !~ /^221/){
369 0           print " Error: QUIT->$recv_data";
370 0           close $mail_socket;
371             }
372 0           &dbg_print("QUIT->$recv_data");
373 0           print "\n";
374            
375 0           close $mail_socket;
376             }
377            
378             sub dbg_print(){
379 0     0 0   my $str = shift;
380            
381 0           $str =~ s/\x0d//g;
382 0           $str =~ s/\x0a//g;
383 0 0         print " INFO : $str\n" if($debug);
384             }
385            
386             sub readMediaTypes(){
387 0     0 0   my $mediaType = shift; # reference to hash
388            
389 0           my $mediaFile;
390 0           foreach(@INC){
391 0 0         if(-e "$_/LWP/media.types") {
392 0           $mediaFile = "$_/LWP/media.types";
393 0           last;
394             }
395             }
396            
397 0           open(MIME, $mediaFile);
398 0           while(){
399 0           chomp $_;
400 0 0         next if($_ =~ /^#/);
401            
402 0           my $line = $_;
403 0           my @part = split /\s+/, $line;
404 0 0         next if(scalar @part < 2);
405            
406             #print "$line\n";
407            
408 0           my $last = scalar @part - 1;
409 0           foreach( @part[1..$last] ){
410 0           ${$mediaType}{lc($_)} = $part[0];
  0            
411             }
412             }
413 0           close MIME;
414             #print sort values %{$mediaType};
415            
416 0           ${$mediaType}{xlsx} = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
  0            
417 0           ${$mediaType}{docx} = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
  0            
418 0           ${$mediaType}{pptx} = 'application/vnd.openxmlformats-officedocument.presentationml.presentation';
  0            
419 0           ${$mediaType}{db} = 'application/binary'; # Thumbs.db
  0            
420             }
421            
422             1;
423             __END__