PERL: ping and e-mail

I need a script to open a text file with ip's in it, ping them, split the results into the ip and time from the results and e-mail them ?

here what i've done.
its porbly wrong and not workin.its for win nt4

use Net::SMTP;

# get list of ip's to ping
open (PINGFILE, "< c:\\Documents and Settings\\pinghosts.txt") or die "Can't open PingHost lsit: $!";

my @pinglist;
my $machinenumber = 0;

while ($line = <PINGFILE>) {
chomp $line;
$pinglist[$machinenumber] = $line;
$machinenumber++;
}

# now ping all machines
foreach $host (@pinglist)
{

system ("ping $host > @result");

}

#split result into name and time
foreach $reply (@results){
($reply)=split(//, $_)
};

#get list of e-mail addresses to send e-mails to
open (EMAILS, "< c:\\Documents and Settings\\emaillist.txt") or die "Can't open e-mail list: $!";

@TO = readdir EMAILS;

foreach $to (@TO){}

$from = "colinctdprep@oceanfree.net";
@body = $reply;
$subject = "PERL pinghost program report";
{

$smtp = Net::SMTP->new("icmp");
die "Could not make connection: $!" if (defined $smtp);

    $smtp-&gt;mail\($from\);
	$smtp-&gt;to\($to\);
	
	$smtp-&gt;data\(\);
	$smtp-&gt;datasend\("To: $to\\n"\);
	$smtp-&gt;datasend\("From: $from\\n"\);
	$smtp-&gt;datasend\("Subject: $subject\\n"\);
	$smtp-&gt;datasend\("\\n"\);
	foreach\(@body\) \{
	     $smtp-&gt;datasend\("$_\\n"\);
		           \}
	$smtp-&gt;dataend\(\);
	$smtp-&gt;quit;
\}

close EMAILS;

Here are some suggestions:

use Net::SMTP;

my (@pinglist, $host, @results, @TO);

# get list of ip's to ping
# using a single instead of double quote around the filename eliminates the need for \\
# the second line stores the entire file in an array automagically
# it's good to always close a file when you're done with it

open (PINGFILE, '<c:\Documents and Settings\pinghosts.txt') or die "Can't open PingHost list: $!";
@pinglist = <PINGFILE>;
close(PINGFILE);

# now ping all machines
# this scrolls through the array, but each IP address is stored in $_ intead of $host
# you can't use > to push new values into an array, so you may want to create a new text file

foreach (@pinglist) {
system("ping $_ > results.txt");
}

open (IPFILE, '<results.txt') or die "Can't open IP list: $!";
@results = <IPFILE>;
close(IPFILE);

I hope some of these are helpful suggestions.. this pretty much cuts off in the middle of your script, but I'm out of time for now

it just print the result on screen not into results.txt

Sorry, I may be telling you wrong on that part. I don't have a computer set up to test Perl right now.. you could try pushing the result directly into the @results array:

# now ping all machines
foreach (@pinglist) {
push(@result, system("ping $_"));
}

still wont work :frowning:

keeps printing the results onto screen.

can you put thr results into an array lik this

foreach (@pinglist) {

system ("ping $_ \@results")
}

???

perleo,

without giving you the WHOLE answer, the following code will ping each IP address in the requested file and store the results in the array @results :slight_smile:

#!/perl/bin/perl -w

use strict;
use Net::SMTP; 

# get list of ip's to ping 
open (PINGFILE, "< c:\\pinghosts.txt") or die "Can't open PingHost list: $!"; 

my @pinglist;
my @results;
my $holder;

while (my $line = <PINGFILE>) { 
	chomp $line;
	# place the host ipaddress in the array @pinglist
	push @pinglist, $line; 
} 

# now ping all machines
foreach my $host (@pinglist) {
	# place results of ping in $holder 
	$holder = `ping $host`;
	# place contents of $holder into the array @results
	push @results, $holder; 
} 

NOTE: check the location of the file to open - I changed it for testing purposes.

Let me know how it goes

:smiley:

works :smiley:

so, how do i split the result just to print the IP and the time
e.g: 192.001.0.002 time>1ms

something like

@result=split(// , $_);

and then to print the results from the split into an array.
can you PLEASE! help me with that !

OK - here we go. The details you require are in the array @pingDetails. It's possibly a bit crude, but it does work!

#!/perl/bin/perl -w

#use strict;
use Net::SMTP;

# get list of ip's to ping
open (PINGFILE, "< c:\\pinghosts.txt") or die "Can't open PingHost list: $!";

my @pinglist;
my @results;
my @pingDetails;
my $holder;

while (my $line = <PINGFILE>) {
	chomp $line;
	# place the host ipaddress in the array @pinglist
	push @pinglist, $line;
}

# now ping all machines
foreach my $host (@pinglist) {
	# place results of ping in $holder
	$holder = `ping $host`;
	# place contents of $holder into the array @results
	push @results, $holder;
}

foreach my $result (@results) {
	# pull out the IP address and time details
	$result =~/(\d*\.\d*\.\d*\.\d*).*(time\<\d*ms)/;
	#place the results into $details and push into the array
	my $details = $1 . " " . $2 . "\n";
	push @pingDetails, $details;
}

Let me know how it goes :wink:

IT WORKS PERFECT !!! :slight_smile:

now last part. E-mail. i have this from a book but i get a error about the $smtp->mail($from); part.

$from = "colinctdprep@oceanfree.net";
@body = $result;
$subject = "PERL pinghost program report";
{

$smtp = Net::SMTP->new("icmp");
die "Could not make connection: $!" if (defined $smtp);

    $smtp-&gt;mail\($from\);
	$smtp-&gt;to\($to\);
	
	$smtp-&gt;data\(\);
	$smtp-&gt;datasend\("To: $to\\n"\);
	$smtp-&gt;datasend\("From: $from\\n"\);
	$smtp-&gt;datasend\("Subject: $subject\\n"\);
	$smtp-&gt;datasend\("\\n"\);
	foreach\(@body\) \{
	     $smtp-&gt;datasend\("$_\\n"\);
		           \}
	$smtp-&gt;dataend\(\);
	$smtp-&gt;quit;
\}

this is for windows NT. can you PLEASE help on this.
It has to open a list of e-mail address and put the @pingDetails into a text file and e-mail it to the e-mail address in the file.
and it has to use colin@oceanfree.net as the sending e-mail.

And i really apprectate the help. :rolleyes:

Try placing a \ symbol before the @ sign in your email address:

$from = "colinctdprep\@oceanfree.net";

The @ symbol may be screwing things up..

I think this will work:

#get list of e-mail addresses to send e-mails to

opendir (EMAILS, "< c:\\Documents and Settings\\emaillist.txt") || die ("Can't open e-mail list: $!");
my @TO = readdir EMAILS;
closedir (EMAILS);

my $from = "colinctdprep\@oceanfree.net"; 
my $subject = "PERL pinghost program report";

foreach my $to (@TO) {

  $smtp = Net::SMTP->new("icmp");
  die "Could not make connection: $!" unless $smtp;

  $smtp->mail($from);
  $smtp->to($to);

  $smtp->data();
  $smtp->datasend("To: $to\n");
  $smtp->datasend("From: $from\n");
  $smtp->datasend("Subject: $subject\n");
  $smtp->datasend("\n");

  foreach(@pingDetails) {
    $smtp->datasend("$_\n");
  }

  $smtp->dataend();
  $smtp->quit();

}

Reference: Perl Programming

still wont work oombera.

WIntellect have u got an awnser to this problem ?

:frowning: Hmm...

What error message are you getting now? Still the $smtp->mail($from); one?

If not, then you may want to try changing the email addresses inside the emaillist.txt file so that each address has a backslash before the @ symbol as well.. or create a small file and experiment with just a few addresses.

every time it open the emaillist.txt is erases the e-mail addresses inside it.

I canged that part to the chomp to take the output and put it ina array and still the same, it erases the addresses in the file. I tried the \ before the @ in the addresses and still erases the addresses. :frowning:

The file that had the emails is actually empty after that? Strange..

Here's a site that tells several ways to read a file:
http://bip.weizmann.ac.il/course/prog/file\_input_output/index.html
http://bip.weizmann.ac.il/course/prog/file\_input_output/7.html

Here's one of the ways from that website:

#get list of e-mail addresses to send e-mails to

open (EMAILS, "< c:\\Documents and Settings\\emaillist.txt") || die ("Can't open e-mail list: $!");

my $from = "colinctdprep\@oceanfree.net"; 
my $subject = "PERL pinghost program report";

while (my $to = <EMAILS>) {

  chomp ($to);

  $smtp = Net::SMTP->new("icmp");
  die "Could not make connection: $!" unless $smtp;

  $smtp->mail($from);
  $smtp->to($to);

  $smtp->data();
  $smtp->datasend("To: $to\n");
  $smtp->datasend("From: $from\n");
  $smtp->datasend("Subject: $subject\n");
  $smtp->datasend("\n");

  foreach(@pingDetails) {
    $smtp->datasend("$_\n");
  }

  $smtp->dataend();
  $smtp->quit();

}

close (EMAILS);

and here's another way:

#get list of e-mail addresses to send e-mails to

open (EMAILS, "< c:\\Documents and Settings\\emaillist.txt") || die ("Can't open e-mail list: $!");
my @TO = <EMAILS>;
chomp (@TO);
close (EMAILS);

my $from = "colinctdprep\@oceanfree.net"; 
my $subject = "PERL pinghost program report";

my $to_addr;

foreach $to_addr (@TO) {

  $smtp = Net::SMTP->new("icmp");
  die "Could not make connection: $!" unless $smtp;

  $smtp->mail($from);
  $smtp->to($to_addr);

  $smtp->data();
  $smtp->datasend("To: $to_addr\n");
  $smtp->datasend("From: $from\n");
  $smtp->datasend("Subject: $subject\n");
  $smtp->datasend("\n");

  foreach(@pingDetails) {
    $smtp->datasend("$_\n");
  }

  $smtp->dataend();
  $smtp->quit();

}

From what I've read, I think this was the problem:

I think oombera gave you the correction with this suggestion:

Failing this, I would also recommend adding a backslash "\" to each email address - otherwise Perl may be mistaking it for an array!!!

Keep us posted!

that works but its having trouble connecting to send the e-mail.

$smtp = Net::SMTP->new("icmp");
die "Could not make connection: $!" unless $smtp;

It diplays the "Could not make connection" on the screen
the ("icmp") seems to be the problem iam guessing. The machine i using to run the script is connected directly to the internet, no proxy.

What should this line be?

"icmp" should be replaced with whatever the name of your SMTP server is. If you're using an email program that connects to the same server, that may be one way to find out the name of it if you don't know it. It'll probably look something like "smtp.your_isp.com"

Seeing as you're on a windows box, you're probably using Outlook / Outlook Express for Email?

You should be able to find out from there, under the accounts menu, in the properties is a field marked:

Outgoing mail (SMTP)

this is probably what you want.

:smiley: got it to work !!!

Thanks oombera and WIntellect for your help!