Gossamer Forum
Home : General : Perl Programming :

Sending file by email blues :(

Quote Reply
Sending file by email blues :(
Please can someone tell me why this won't work! I thought at first it must be the location to sendmail, but that didnt work (tried all three different locations possibilities). I then added an error sub to see if the email actually was being sent, but that didn't return anything, so now I am officially stumped! Any ideas you guys? I have never learned how to program the encode stuff, so all of this is new to me Frown

Well, here is the code;

Code:
#!/usr/bin/perl

### User variables - you may change things in this section as indicated ###

# Change this to the correct path to Sendmail for your system #
$mailprog="/usr/lib/sendmail";

# Change this to the LITERAL PATH to the files you wish to mail. Do not forget the ending / #
$filelocation="/home/wwwtempl/public_html/templates/purchase/download/";

# Change this to the email address you want mails to be sent FROM and leave \ behind the @ sign#
$adminmail="webmaster\@wwwtemplates.com";

# Change this to the name you want mails to be sent FROM #
$adminname="Webmaster";

# Change this to reflect the subject line you require for your mails #
$subjectline="Your Template from WWWTemplates.com";

# Change this to show the message you want to include (i.e. the body of the email). #
# A new line is entered by using \n e.g. Hi there\n\nThank-you for your interest in blah blah #
# Note that "Dear Name\n\n" has been inserted for you automatically, Name being the name submitted #

# Change this to the URL of the screen you want to display after the user has submitted the form #
#(i.e. a confirmation screen)#
$returnscreen="http://wwwtemplates.com/templates/purchase/safe/confirmed.cgi?do=sent";

# DO NOT alter anything from here on #

read (STDIN,$temp,$ENV{'CONTENT_LENGTH'});
@pairs=split(/&/,$temp);
foreach $item(@pairs)
{
($key,$content)=split (/=/,$item);
$content=~tr /+/ /;
$content=~s /%(..)/pack("c",hex($1))/ge;
$fields{$key}=$content;
}

require ("mimetypes.pl");

&sendproduct;

$message = qw~First of all, let me congratulate you on your purchase from our quality selection of templates. We hope you enjoy using your purchase, and it saves you a lot of money from time you would have otherwise spent trying to do something like this! Please find attached a copy of the template you just purchased. ~;

sub sendproduct
{

$file=$filelocation.$fields{'attachment'};
($ext) = $file =~ m,\.([^\.]*)$,;
$ext =~ tr,a-z,A-Z,;
$fext=&mimetype($ext);


my @boundaryv = (0..9, 'A'..'F');
srand(time ^ $$);
for (my $i = 0; $i++ < 24;)
{
$boundary .= $boundaryv[rand(@boundaryv)];
}

open MAIL, "| $mailprog -t" || die &error('$!');
print MAIL "To: $fields{'email'}\n";
print MAIL "From: $adminmail\n";
print MAIL "MIME-Version: 1.0\n";
print MAIL "Subject: $subjectline\n";
print MAIL "Content-Type: multipart/mixed; boundary=\"------------$boundary\"\n";
print MAIL "\n";
print MAIL "This is a multi-part message in MIME format.\n";
print MAIL "--------------$boundary\n";
print MAIL "Content-Type: text/plain; charset=us-ascii\n";
print MAIL "Content-Transfer-Encoding: 7bit\n\n";
print MAIL "$message";
print MAIL "\n";
print MAIL "--------------$boundary\n";
print MAIL "Content-Type: $fext; name=\"$fields{'attachment'}\"\n";
print MAIL "Content-Transfer-Encoding: base64\n";
print MAIL "Content-Disposition: inline; filename=\"$fields{'attachment'}\"\n\n";

my $buf;
$/=0;
open INPUT, "$file";
binmode INPUT if ($^O eq 'NT' or $^O eq 'MSWin32');
while(read(INPUT, $buf, 60*57))
{
print MAIL &encode_base64($buf);
}
close INPUT;

print MAIL "\n--------------$boundary--\n";
print MAIL "\n";
close MAIL;
print "Location: $returnscreen\n\n";
exit();
}


sub encode_base64 #($)
{
my ($res, $eol, $padding) = ("", "\n", undef);

while (($_[0] =~ /(.{1,45})/gs))
{
$res .= substr(pack('u', $1), 1);
chop $res;
}

$res =~ tr#` -_#AA-Za-z0-9+/#; # ` help emacs
$padding = (3 - length($_[0]) % 3) % 3; # fix padding at the end

$res =~ s#.{$padding}$#'=' x $padding#e if $padding; # pad eoedv data with ='s
$res =~ s#(.{1,76})#$1$eol#g if (length $eol); # lines of at least 76 characters

return $res;
}

sub error
{

$error = shift;

print "Content-type: text/html \n\n";
print "$error";

}
Thanks to anyone that can help!

Andy

webmaster@ace-installer.com
http://www.ace-installer.com
Quote Reply
Re: Sending file by email blues :( In reply to
Im not surprised it doesn't report anything Wink

&error('$!');

Spot the error?

That encode_base64 sub it yucky too....you should use

use MIME::Base64 qw(encode_base64);

Hmmm also no exit in the error sub

I already posted code in this very forum on how to send a file by email.

Mods:http://wiredon.net/gt/download.shtml
Installations:http://wiredon.net/gt/
Quote Reply
Re: Sending file by email blues :( In reply to
Yeah, I wasn't too keen on the code myself either! Just I don't have time to learn how to do this stuff on my own! Frown

I'll keep trying, and thanks for your help Smile

Andy

webmaster@ace-installer.com
http://www.ace-installer.com
Quote Reply
Re: Sending file by email blues :( In reply to
So why isn't it working?

What happens?

Mods:http://wiredon.net/gt/download.shtml
Installations:http://wiredon.net/gt/
Quote Reply
Re: Sending file by email blues :( In reply to
http://www.gossamer-threads.com/...ew=&sb=&vc=1

Mods:http://wiredon.net/gt/download.shtml
Installations:http://wiredon.net/gt/
Quote Reply
Re: Sending file by email blues :( In reply to
I've changed the line where it accesses sendmail to;

open (MAIL, "| $mailprog -t") || die &error("$!");

This now works when sending to HotMail accounts, but for some reason won't send if I try to send emails to my POP 3 accounts Frown

Oh, and thanks for the link Smile I'll have a look at it later.

Andy

webmaster@ace-installer.com
http://www.ace-installer.com
Quote Reply
Re: Sending file by email blues :( In reply to
Hi,

You do realize that if I pass in:

email=alex@gossamer-threads.com
attachment=/etc/passwd

I can have it send me an email with your password file attached? Also, because file is not checked, I can also run commands on your server quite easily.

Need to always check form input. =)

Cheers,

Alex

--
Gossamer Threads Inc.
Quote Reply
Re: Sending file by email blues :( In reply to
Mmm, thanks for that Alex! I'll remembr that in the future! Wink I think the email thing is something to do with the copy of Sendmail on my hosts server. Would that sound right, as it only seems to send to certain email addresses???

Thanks

Andy

webmaster@ace-installer.com
http://www.ace-installer.com
Quote Reply
Re: [Andy] Sending file by email blues :( In reply to
i'm sure you have this working now! i'm able to send attachments and they work fine on my email program. however, the attachments arrive inline and garbled on phones. if yours is working, could you please post the code? thanks!
Quote Reply
Re: [delicia] Sending file by email blues :( In reply to
Hi,

I actually do mine different in my own code. This sends out a 2 part message (plain text and HTML). Its important these days to send out both plain and HTML versions, as it will help you with spam filters.

Code:
sub do_emailing_new {
# Plugins::Emails::do_emailing_new("foo_bar_template","Some subject",$opts)

use MIME::Lite;
use MIME::Base64;
use Encode;
use Links::SiteHTML;

my ($template,$subject,$opts) = @_;

my $to = $opts->{to};

my $from = $opts->{from} || '"Andy" <andy@mysite.com>';

my $html = Links::SiteHTML::display($template, { %$opts } );
my $text = Links::SiteHTML::display("${template}_txt", { %$opts }, { compress => 0 } );

$html = decode( 'utf-8', $html );
$text = decode( 'utf-8', $text );

# print "FOO: $html \n";

use Email::MIME;
use Email::Address::XS;
use Email::Sender::Simple qw(sendmail);
use IO::All;

# multipart message
my @parts = (
Email::MIME->create(
body_str => $text,
attributes => {
encoding => 'quoted-printable',
content_type => "text/plain",
disposition => "inline",
charset => "UTF-8",
}
),
Email::MIME->create(
body_str => $html,
attributes => {
encoding => 'quoted-printable',
charset => "UTF-8",
content_type => "text/html",
disposition => "inline",
}
)
);

if ($opts->{attach_file}) {

my $filename = (reverse split /\//, $opts->{attach_file})[0];

push @parts, Email::MIME->create(
attributes => {
filename => $filename,
content_type => "application/pdf",
encoding => "base64",
name => $filename,
},
body => io( $opts->{attach_file} )->binary->all,
)
}


my $email = Email::MIME->create(
header_str => [
From => $from,
To => [ $to ],
Subject => $subject,
],
parts => \@parts,
attributes => {
encoding => 'base64',
charset => "UTF-8",
content_type => "multipart/alternative",
disposition => "inline",
}
);

#print $email->as_string. "\n\n";

my $bcc = '';
my $bcc = 'andy@ultranerds.co.uk';
if ($bcc) {
sendmail($email,{ to => [$to, $bcc] });
} else {
sendmail($email->as_string);
}

}

Basically you create 2 templates - template_name.html and template_name_txt.html

Call with:

Code:
Plugins::Emails::do_emailing_new("foo_bar_template","Some subject",$opts)
;

$opts contains the following variables:

Code:
from
to (email)

From memory, both of those can be in the format is:

Code:
Some persons name <andy.newby@gmail.com>

I'm sure you can figure out the rest :)

Andy (mod)
andy@ultranerds.co.uk
Want to give me something back for my help? Please see my Amazon Wish List
GLinks ULTRA Package | GLinks ULTRA Package PRO
Links SQL Plugins | Website Design and SEO | UltraNerds | ULTRAGLobals Plugin | Pre-Made Template Sets | FREE GLinks Plugins!
Quote Reply
Re: [Andy] Sending file by email blues :( In reply to
you give me too much credit! first, i don't understand templates at all. also, i am able to send attachments fine. the problem only occurs when the recipient opens the mail on iphone or android. instead of showing link to the attachment, the pdf (or whatever) appears as garbled text in the body of the message. i think i'm just doing one little thing wrong, but i've struggled with this off and on (when i have time) for months. after the print MAIL statements for the text part of the message, i have the following:
Code:
### 02/03/2020
print MAIL "\n";
print MAIL "--------------$boundary\n";
print MAIL "Content-Type: pdf; name=\"$attach\"\n";
print MAIL "Content-Transfer-Encoding: base64\n";
print MAIL "Content-Disposition: attachment; filename=\"$attach\"\n\n";
####
$newfile = substr($attach,rindex($attach,"/"));
$newfile =~ s/\///;
open(FILE, "uuencode $attach $newfile|") or die;
while( <FILE>) { print MAIL; };
close(FILE);
### 02/03/2020
print MAIL "\n--------------$boundary--\n";
print MAIL "\n";
#####
i tried replacing
open(FILE, "uuencode $attach $newfile|") or die;
with
open(FILE, "base64 $attach $newfile|") or die;
but it had no effect at all
Quote Reply
Re: [delicia] Sending file by email blues :( In reply to
Hi,

Sorry, I don't send files like that. You have to be so careful to get all the right headers, it much better to send it using existing modules.

Quote:
also, i am able to send attachments fine. the problem only occurs when the recipient opens the mail on iphone or android. instead of showing link to the attachment, the pdf (or whatever) appears as garbled text in the body of the message.

By definition, that's not fine :) haha. It means you are sending data that the phone isn't expecting. The way you are sending emails is very 1990 - you need to update to a better method if you want your emails to come out properly ;)

With regards to the templates - you don't have to use the template bit. You could just as easily do:

Code:
my $html = qq|My html message - you can use <b>etc</b> in here - NO HEADERS - just the email body!|;
my $text = qq|A text version as well (good for mobiles, or low data devices|;

Then the rest of the code basically stands

Cheers

Andy

Andy (mod)
andy@ultranerds.co.uk
Want to give me something back for my help? Please see my Amazon Wish List
GLinks ULTRA Package | GLinks ULTRA Package PRO
Links SQL Plugins | Website Design and SEO | UltraNerds | ULTRAGLobals Plugin | Pre-Made Template Sets | FREE GLinks Plugins!
Quote Reply
Re: [Andy] Sending file by email blues :( In reply to
ok, i'm trying to implement your code but i'm getting internal error. ran perl check and it says it cannot find email::MIME. now what??? Gossamer Threads is my host
Quote Reply
Re: [delicia] Sending file by email blues :( In reply to
Hi,

Email GT, and ask them to make sure you have these modules installed:

Code:
use Email::MIME;
use Email::Address::XS;
use Email::Sender::Simple qw(sendmail);
use IO::All;

Also, the best way to play with it would be to make a simple test.cgi script and get the code working like that first (then once you are happy, you can put the code into your main scripts)

Cheers

Andy (mod)
andy@ultranerds.co.uk
Want to give me something back for my help? Please see my Amazon Wish List
GLinks ULTRA Package | GLinks ULTRA Package PRO
Links SQL Plugins | Website Design and SEO | UltraNerds | ULTRAGLobals Plugin | Pre-Made Template Sets | FREE GLinks Plugins!