LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   howto send a mail with attachment via perl script ? (https://www.linuxquestions.org/questions/programming-9/howto-send-a-mail-with-attachment-via-perl-script-150129/)

cccc 02-24-2004 06:52 PM

howto send a mail with attachment via perl script ?
 
hi

in my perl script I write the log with

BEGIN
{
use CGI::Carp qw(carpout);
my $errorlog = "/var/errorlog.txt";
open(LOG, ">$errorlog") or die("Unable to open $errorlog: $!\n");
print LOG "Errors:\n";
carpout(*LOG);
}


and transfer 2 file via ftp

.............................................................................................
.............................................................................................
my $ftp = Net::FTP->new ($server, Timeout => 9000, Debug => 3);
$ftp or die "$server: cannot connect: $@";
# If you don't use ~/.netrc
$ftp->login ('anonymous', 'mail@domain.net') or
die "$_: cannot logon: " . $ftp->message;

# Put file 2 (not 1) to the ftp server
$ftp->put ($f2) or
die "$server: cannot put $f2: " . $ftp->message;

$ftp->quit;

# wait for 10 seconds
sleep (1 * 10);
}

but how to send the mail on the end with the log file errorlog.txt as attachment,
when the transfer was successfully completed ?

I think something like this:

open(MAIL, "|/usr/sbin/sendmail -t");
print MAIL "to:$mail\n";
print MAIL "from:$linux\n";
print MAIL "subject:ftp transfer was successfully \n";

print MAIL "------------------------------------------------------------------\n";

print MAIL "ftp transfer was successfully\n\n";

print MAIL "Time: ". localtime(time) ." \n";

print MAIL "------------------------------------------------------------------\n";


Attachment ?


close(MAIL);
}


kind regards
cccc

david_ross 02-25-2004 01:12 PM

The best way to see it is to read the source of a message in your inbox that has an attachment. The trick is to use multipart boundaries. Here is a cut down example from an e-mail sent to me:
Code:

From: xyz@host.com
To: xyz@host.com
Subject: Some subject
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="----=_NextPart_000_002F_01C3F989.5E1B7780"


------=_NextPart_001_0030_01C3F989.5E1B7780
Content-Type: text/plain;
Content-Transfer-Encoding: quoted-printable

This is the message text

below is the binary content of a jpg in a new multipart section

------=_NextPart_000_002F_01C3F989.5E1B7780
Content-Type: image/jpeg; name="file.jpg"
Content-Disposition: attachment; filename="file.jpg"
Content-Transfer-Encoding: base64

/9j/4AAQSkZJRgABAQEASABIAAD/7Q2AUGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAAHscAgAAAgAC
HAJ4AG9XaW0gRGVsdm95ZQ1MaWNrIDMsIDIwMDANY2liYWNocmltZSBwcmludCBvbiBhbHVtaW51
bSwgZWQuICMgNS82DTQ5IDEvNCB4IDM5IDMvOCBpbmNoZXMgKDEyNSB4IDEwMCBjbSkNU1cgMDIy
Xc7Hr007KxuAoAKooQH3Mzb3E0BB2PrqUtIDbGVoDWlpqbSRQ1bqRv8ADUo+5DSkNRbqWgAKarQi
gFN9TTSyszuzWipIUEncVAAFDpyWJYmteoBt9NdSfiT6/wDiv6j1p6/H01weeJCpwuY4/LG42jiy
qmJhw2Lcy0ISgApvryGRXEOZ5pzWL49jBVKF8JZmn5Ht2C4pNEhFT7WWvqSNTKSql2kNLgTT2qoF
RvUL/DRivIvaRTTrU3AEkbGgOoXuANQH+Br8Nq9f8TqH3VqQBUmlRQj5HbUQY1rYCelq2hmB9N/+
mkdbhcLWIYMChUKCAFtKgDau2/pp2UOKmoIIJFA

------=_NextPart_000_002F_01C3F989.5E1B7780--


cccc 02-25-2004 04:11 PM

thanks

but how will be the perl code, if I can ask you
to read to read the source from /var/errorlog.txt ?

regards
cccc

david_ross 02-26-2004 12:31 PM

Code:

open(FILE, "/var/errorlog.txt");
$content=<FILE>;
close(FILE);

open(MAIL, "|/usr/sbin/sendmail -t");
print MAIL <<"EOF";
From: xyz\@host.com
To: xyz\@host.com
Subject: Some subject
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="----=_NextPart_000_002F_01C3F989.5E1B7780"


------=_NextPart_001_0030_01C3F989.5E1B7780
Content-Type: text/plain;
Content-Transfer-Encoding: quoted-printable

This is the message text

below is the binary content of a jpg in a new multipart section

------=_NextPart_000_002F_01C3F989.5E1B7780
Content-Type: text/plain; name="errorlog.txt"
Content-Disposition: attachment; filename="errorlog.txt"
Content-Transfer-Encoding: base64

$content

------=_NextPart_000_002F_01C3F989.5E1B7780--
EOF

close(MAIL);


cccc 02-26-2004 01:55 PM

hallo david_ross

I've tried this but wont work:

open(FILE, "/var/errorlog.txt");
$content=<FILE>;
close(FILE);

open(MAIL, "|/usr/sbin/sendmail -t");
print MAIL <<"EOF";
From:root\@domain.net
To:xxx\@domain.net
Subject: transfer was successfully !

hi,

transfer was successfully !

$content

Time: ", scalar localtime,

EOF

close(MAIL);


I get error mesage for 2 lines:

$content=<FILE>;

" Global symbol "$content" requires explicit package name "

and

$content

" Global symbol "$content" requires explicit package name "


regards
ccc

dford 02-26-2004 04:08 PM

At CPAN there is a module that does just what you need: Net-SMTP-Multipart-1.5.tar.gz

It relies on Net::SMTP and Mime::Base64. Be sure to read the POD it tells you how to use it for just what you asked for. The location is: http://www.cpan.org/authors/id/D/DR/...art-1.5.tar.gz

cccc 02-26-2004 05:44 PM

but this way from david_ross should work also
and I want to know what's wrong.

regards
cccc

hallamigo 02-26-2004 05:56 PM

I would suggest you use MIME::Lite (found on CPAN) - it's really easy and straight forward. Below is the sub I use to send a contact card. (I use qmail as a mail server - but it should make sense.)

use strict;
use MIME::Lite;

sub sendEmail {
my $name = $_[0];
my $from = $_[1];
my $to = $_[2];
my $subject = $_[3];
my $body = "Please see the attached.";

my $injector = "/var/qmail/bin/qmail-inject";

open (MESSAGE, "| $injector -f '$from' '$to'") or erp("> Can't open $injector!\n");

my $msg;
$msg = MIME::Lite -> new(
From => "$name <$from>",
To => "$to",
Subject => "$subject",
Type => "multipart/mixed"
);

$msg -> attach(
Type => "text/html",
Data => "$body"
);

$msg -> attach(
Type => "text/x-vcard",
Path => "/usr/local/apache/vcard.vcf",
Filename => "info.vcf",
Disposition => "attachment"
);

$msg -> print(\*MESSAGE);
close (MESSAGE);
}

dford 02-26-2004 09:50 PM

Quote:

Originally posted by cccc
but this way from david_ross should work also
and I want to know what's wrong.

regards
cccc



Well basically it ought to work. Here is my test script:

#!/usr/bin/perl

$localtime = localtime();
open(FILE,"/var/log/dmesg");
$content = <FILE>;
open(MAIL, "| cat > foo.txt");

print MAIL << "EOF";
From: dford
To: dford
Subject: Successful

Hi!
$content

Time: $localtime

EOF
exit;


And my results are:

From: dford
To: dford
Subject: Successful

Hi!
Linux version 2.4.20-28.9 (bhcompile@porky.devel.redhat.com) (gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)) #1 Thu Dec 18 13:45:22 EST 2003


Time: Thu Feb 26 21:36:20 2004


So, what else is in your script? :cool:

cccc 02-29-2004 06:57 PM

hi dford

and where should I put the path to sendmail on your script ?

kind regards
cccc

dford 03-01-2004 02:28 PM

My script was just a quick hack test. Where I had:
Code:

open(MAIL, "| cat > foo.txt");
You should replace that with david_ross's:
Code:

open(MAIL, "|/usr/sbin/sendmail -t");
You also should probably add:
Code:

close(MAIL);
before the exit; as well.

cccc 03-03-2004 07:16 PM

hi

I have a script , NO ERRORS, but NO MAILS !

knows someone what's wrong ?


Code:

#!/usr/bin/perl -w
use MIME::Lite;
use Getopt::Std;
use Net::SMTP;

my $SMTP_SERVER = '/usr/sbin/sendmail -t';
my $DEFAULT_SENDER = 'sender@domain.net';
my $DEFAULT_RECIPIENT = 'recipient@domain.net';

MIME::Lite->send('sendmail', $SMTP_SERVER, Timeout=>60);

my (%o, $msg);

# process options
getopts('hf:t:s:', \%o);

$o{f} ||= $DEFAULT_SENDER;
$o{t} ||= $DEFAULT_RECIPIENT;
$o{s} ||= 'attachment';

if ($o{h} or !@ARGV) {
die "usage:\n\t$0 -h -f -t -s /var/log/log.txt\n";
}

# construct and send email
$msg = new MIME::Lite(
From => $o{f},
To => $o{t},
Subject => $o{s},
Data => "Hi",
Type => "multipart/mixed",
);

while (@ARGV) {
$msg->attach('Type' => 'application/octet-stream',
'Encoding' => 'base64',
'Path' => shift @ARGV);
}

kind regards
cccc

dford 03-03-2004 08:32 PM

It looks like you just need to add
Code:

$msg->send();
to the end.

cccc 03-04-2004 04:44 AM

hi dford

I've added.
but still NO mails !

kind regards
cccc

dford 03-04-2004 09:58 AM

Okay here is the script I used, basically the script you had:
Code:

#!/opt/perl/bin/perl -w
use MIME::Lite;
use Getopt::Std;
use Net::SMTP;

my $SMTP_SERVER = '/usr/sbin/sendmail -t';
my $DEFAULT_SENDER = 'dford@tacsea.metapath.com';
my $DEFAULT_RECIPIENT = 'don.ford@metapath.com';

my (%o, $msg);

# process options
getopts('hf:t:s:', \%o);

$o{f} ||= $DEFAULT_SENDER;
$o{t} ||= $DEFAULT_RECIPIENT;
$o{s} ||= 'attachment';

if ($o{h} or !@ARGV) {
die "usage:\n\t$0 -h -f -t -s /var/log/log.txt\n";
}

# construct and send email
$msg = new MIME::Lite(
From => $o{f},
To => $o{t},
Subject => $o{s},
Data => "Hi",
Type => "multipart/mixed",
);

while (@ARGV) {
$msg->attach('Type' => 'application/octet-stream',
'Encoding' => 'base64',
'Path' => shift @ARGV);
}

$msg->send;

I did not see the "Hi", but otherwise this worked fine. (I did change the email addresses to reduce spam potential.) I did have some issues with a bad To email address at first, but you should see the bounce messages in your mail box on the machine. I wonder if you are having issues with sendmail?

cccc 03-05-2004 12:02 PM

thanks dford

I don't know, what's wrong.
I use the same script and it doesn't send any mails !
I've spend a lot of time about this problem.

greetings
cccc

dford 03-05-2004 12:39 PM

Is sendmail running? I tested sending through sendmail directly with this:
Code:

echo 'From: dford1234@metapath.com
To: dford1234@computer.org
Subject: Test
Hi!
Bye!
.' | /usr/sbin/sendmail dford1234@computer.org

Something like this should work. If it doesn't, perhaps you are running qmail or another MTA? Or no MTA at all?

Note: email addresses were altered to not add to my spam load. You can probably figure them out though. :D

cccc 03-05-2004 01:34 PM

Yes !

this one for example works excellent and sends mail:

Code:

open(MAIL, "|/usr/sbin/sendmail -t");
print MAIL "to:$mail\n";
print MAIL "from:$linux\n";
print MAIL "subject:sendmail test\n";
print MAIL "hi\n\n";
print MAIL "TEST\n\n";
close(MAIL);
}

I don't know if really important, but I use postfix
and the path to postfix is:
/usr/sbin/sendmail
I use this path at all other scripts and it works.

kind regards
cccc

dford 03-05-2004 02:39 PM

Hmmm...try something like this instead of the $msg->send(); line:
Code:

$str = $msg->as_string;
open(MAIL, "|/usr/sbin/sendmail -t");
print MAIL $str;
close(MAIL);

This should turn the message into a string and then print that string in the same way your working example does. You may need to tweak this some, but it should work. Again this works on my system, but my system is using a "traditional" sendmail.

cccc 03-05-2004 03:10 PM

I've replaced, but now I have on this new lines errors:

[Fri Mar 5 22:07:47 2004] mail.cgi: Global symbol "$str" requires explicit package name at mail.cgi line 58.
[Fri Mar 5 22:07:47 2004] mail.cgi: Global symbol "$str" requires explicit package name at mail.cgi line 60.
[Fri Mar 5 22:07:47 2004] mail.cgi: Execution of mail.cgi aborted due to compilation errors.

dford 03-05-2004 03:46 PM

You might just add:
my $str;

cccc 03-05-2004 03:59 PM

thanks for your time and help, but still no mails


dford 03-05-2004 07:19 PM

So, just to be clear, when you enter:
Code:

perl mail.cgi /var/log/log.txt
or something similar you get no error messages and no email? It just returns you to a prompt?

cccc 03-05-2004 07:47 PM

Hi

sorry, my mistake the file was not readable.
now it works !

thanks for your time and HELP !
cccc

dford 03-05-2004 07:49 PM

You are welcome! Glad it is working now!


All times are GMT -5. The time now is 12:53 AM.