Link to home
Start Free TrialLog in
Avatar of anant99
anant99

asked on

sendmail with attachment

hi !

i want to use sendmail to send multiple attachments. the file extensions may/may not be different. also the files are large - 200kb and higher. please help.

thanks,
Anant
Avatar of maneshr
maneshr

anant99,

".to send multiple attachments..."

Here is a fully functional and ready to use HTML file and Perl script that should help you.

This script in addition to emailing the files, also stores the files in the /tmp directory of your server.

NOTE: i have commented the code so that you will find it easy to understand and maintain the same.
Please remember to change the directory path and any other settings that are unique per your servers settings.

Let me know how this script works for you.
==========multi_email_attachements.html
<HTML>
<HEAD>
<TITLE>Manesh R. - MAIL-A-FILE DEMO PAGE</TITLE>
</HEAD>

<BODY BGCOLOR=#FFFFFF TEXT=#000000 LINK=#0000FF VLINK=#0000FF ALINK=#FF0000>

<CENTER>
<H2 ALIGN=CENTER><FONT FACE=ARIAL>Manesh's MAIL-A-FILE Demo</FONT></H2>
<BR>
  <FORM METHOD="post" ENCTYPE="multipart/form-data" ACTION="/cgi-bin/multi_email_attachements.pl">
    <TABLE WIDTH=600 BORDER=0 CELLPADDING=1 CELLSPACING=0 BGCOLOR=#000000><TR><TD>
<TABLE WIDTH=100% BORDER=0 CELLPADDING=3 CELLSPACING=2 BGCOLOR=#FFFFFF>
<TR>
            <TD VALIGN=TOP COLSPAN=2 BGCOLOR=#336699 ALIGN=MIDDLE> <FONT FACE=ARIAL SIZE=+1 COLOR=#FFFFFF>Sender's
              Info</FONT> </TD>
          </TR>

<TR>
<TD BGCOLOR=#DDDDDD ALIGN=RIGHT><FONT FACE=ARIAL SIZE=-1><B>Sender's Name: </b></FONT></TD>
<TD><INPUT type="text" name="name_sender" size=35 maxlength=30></TD>
</TR>

<TR>
<TD BGCOLOR=#DDDDDD ALIGN=RIGHT><FONT FACE=ARIAL SIZE=-1><B>Sender's E-mail: </b></FONT></TD>
<TD><INPUT type="text" name="email_sender" size=35>
</TD></TR>

<TR>
<TD VALIGN=TOP COLSPAN=2 BGCOLOR=#336699 ALIGN=MIDDLE>
<FONT FACE=ARIAL SIZE=+1 COLOR=#FFFFFF>Recipient's Info</FONT>
</TD></TR>

<TR>
<TD BGCOLOR=#DDDDDD ALIGN=RIGHT><FONT FACE=ARIAL SIZE=-1><B>Recipient's Name: </b></FONT></TD>
<TD><INPUT type="text" name="name_recipient" size=35 maxlength=30></TD>
</TR>

<TR>
<TD BGCOLOR=#DDDDDD ALIGN=RIGHT><FONT FACE=ARIAL SIZE=-1><B>Recipient's E-mail: </b></FONT></TD>
<TD><INPUT type="text" name="email_recipient" size=35>
</TD></TR>

<TR>
<TD BGCOLOR=#DDDDDD ALIGN=RIGHT><FONT FACE=ARIAL SIZE=-1><B>Cc: </b></FONT></TD>
<TD><INPUT type="text" name="cc" size=35>
</TD></TR>

<TR>
<TD BGCOLOR=#DDDDDD ALIGN=RIGHT><FONT FACE=ARIAL SIZE=-1><B>Bcc: </b></FONT></TD>
<TD><INPUT type="text" name="bcc" size=35>
</TD></TR>

<TR>
<TD VALIGN=TOP COLSPAN=2 BGCOLOR=#336699 ALIGN=MIDDLE>
<FONT FACE=ARIAL SIZE=+1 COLOR=#FFFFFF>Subject and File Attachment Info</FONT>
</TD></TR>

<TR>
<TD BGCOLOR=#DDDDDD ALIGN=RIGHT><FONT FACE=ARIAL SIZE=-1><B>Subject </b></FONT></TD>
<TD><INPUT TYPE="text" NAME="subject" SIZE=35></TD>
</TR>

<TR>
<TD BGCOLOR=#DDDDDD ALIGN=RIGHT><FONT FACE=ARIAL SIZE=-1><B>1st File To Attach </b></FONT></TD>
<TD><INPUT TYPE="FILE" NAME="file_attached_A" SIZE=35></TD>
</TR>

<TR>
<TD BGCOLOR=#DDDDDD ALIGN=RIGHT><FONT FACE=ARIAL SIZE=-1><B>2nd File To Attach </b></FONT></TD>
<TD><INPUT TYPE="FILE" NAME="file_attached_B" SIZE=35></TD>
</TR>

<TR>
<TD BGCOLOR=#DDDDDD ALIGN=RIGHT><FONT FACE=ARIAL SIZE=-1><B>3rd File To Attach </b></FONT></TD>
<TD><INPUT TYPE="FILE" NAME="file_attached_C" SIZE=35></TD>
</TR>

<TR>
<TD BGCOLOR=#DDDDDD ALIGN=RIGHT><FONT FACE=ARIAL SIZE=-1><B>4th File To Attach </b></FONT></TD>
<TD><INPUT TYPE="FILE" NAME="file_attached_D" SIZE=35></TD>
</TR>

<TR>
<TD BGCOLOR=#DDDDDD ALIGN=RIGHT><FONT FACE=ARIAL SIZE=-1><B>5th File To Attach </b></FONT></TD>
<TD><INPUT TYPE="FILE" NAME="file_attached_E" SIZE=35></TD>
</TR>

<TR>
<TD VALIGN=TOP COLSPAN=2 BGCOLOR=#336699 ALIGN=MIDDLE>
<FONT FACE=ARIAL SIZE=+1 COLOR=#FFFFFF>Message/Comments</FONT>
</TD></TR>

<TR>
<TD BGCOLOR=#DDDDDD ALIGN=RIGHT><FONT FACE=ARIAL SIZE=-1><B>Message/Comments: </b></FONT></TD>
<TD>
<TEXTAREA NAME=main_message COLS=42 ROWS=5 WRAP=VIRTUAL></TEXTAREA >
</TD>
</TR>

<TR>
<TD BGCOLOR=#336699 ALIGN=MIDDLE><INPUT type="submit" value=" Send Mail "></TD>
<TD>
<FONT FACE=ARIAL SIZE=-1>
Submitting this forms with file attachments may take longer than usual depending on the size of the file you attached. Please be patient and press the submit button only once.
</font></TD>
</TR>

</table></TD></TR></TABLE>

</form>

<BR><HR NOSHADE WIDTH=600>
<FONT FACE=ARIAL SIZE=-1>Mail-A-File &copy 1998-2099 <A HREF=http://icthus.net/CGI-City>CGI City</A></FONT>
<BR><BR><BR><BR>
</center></BODY></HTML>


==========multi_email_attachements.pl

#!/usr/local/bin/perl

$|++;

use CGI;
$query=new CGI;

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

$dir_to_store="/tmp";
$no_of_files=0;
@list=();
$boundary="Message-Boundary-19990614";
$mailprog ="/usr/lib/sendmail";

foreach ($query->param){
      if ($query->param($_)){      ##      The user entered some value!!
            if (/^file_attached_[A-Z]$/){      ##      The uploaded file!!
                  ++$no_of_files;
                  push(@list,$_);
            }else{      ##      One of the other items (Sender's Name, Sender's Email, etc...).
                  ##      Store the value in a variable.
                  ##      The name of the variable is the same as the HTML form element name
                  ##      Eg if the HTML element is called name_sender, the PERL
                  ##      variable will be called $name_sender.
                  $$_=$query->param($_);
            }
      }
}

if (! $no_of_files){      ##      No file selected for upload
      print "<FONT COLOR=RED><B>Enter at least one file for upload.</B></FONT><br>\n";
      exit;
}else{

      ##      Get the email ready for delivery!!
      open(MAIL, "| $mailprog -t ");
      print MAIL "To: $name_recipient <$email_recipient>\n";
      print MAIL "From: $name_sender <$email_sender>\n";
      print MAIL "CC: $cc\n";
      print MAIL "BCC: $bcc\n";
      print MAIL "Subject: $subject\n";
      print MAIL "MIME-Version: 1.0\n";
      print MAIL "Content-type: Multipart/1;\n";
      print MAIL "\tboundary=$boundary\n";
      print MAIL "\n";
      print MAIL "\n";
      print MAIL "--$boundary\n";

      foreach (@list){
            $uploaded_file=$query->param($_);

            $tmp_uploaded_file=$query->param($_);
            $tmp_uploaded_file=~ s/\\/\//g;
            @tmp_uploaded_file=split(/\//,$tmp_uploaded_file);

            $filename = $tmp_uploaded_file[$#tmp_uploaded_file];

            $content="";
            while($bytesread=read($uploaded_file,$data,1024)){
                  $size+=$bytesread;
                  $content.=$data;
            }
            close($uploaded_file);
            
            print "<B>$uploaded_file has been emailed.</B><br>\n";
            print "<B>Size = ",$size," byte(s)</B><P>\n";
            $size=0;

            ##  Print the header for that attachment.
            print MAIL "Content-type: application/octet-stream; name=\"$filename\"; type=Unknown\n";
            print MAIL "Content-transfer-encoding: BASE64\n";
            print MAIL "Content-disposition: attachment\n";
            print MAIL "\n";

            $content= encode_base64($content);  ##  Use base64 for encoding the contents

            ##  Attach the file!!
            print MAIL $content;
            print MAIL "\n";
            print MAIL "--$boundary\n";
      }

      ##      Add the text part of the message
      print MAIL "Content-type: text/plain; charset=US-ASCII\n";
      print MAIL "Content-description: Mail message body\n";
      print MAIL "Content-transfer-encoding: 7BIT\n";
      print MAIL "\n";
      print MAIL "Sender's Name: $name_sender\n";
      print MAIL "Sender's Email: $email_sender\n";
      print MAIL "Recipient's Name: $name_recipient\n";
      print MAIL "Recipient's Email: $email_recipient\n";
      print MAIL "CC: $cc\n";
      print MAIL "BCC: $bcc\n";
      print MAIL "--$boundary\n";

      ##  Send out the contents!!
      print MAIL "Message/Comments\n$main_message";
      print MAIL "\n";
      print MAIL "--$boundary--\n";

      close(MAIL);
}

sub encode_base64 ($;$){
      my $res = "";
      my $eol = $_[1];
      $eol = "\n" unless defined $eol;
      pos($_[0]) = 0;                          # ensure start at the beginning
      while ($_[0] =~ /(.{1,45})/gs) {
            $res .= substr(pack('u', $1), 1);
            chop($res);
      }
      $res =~ tr|` -_|AA-Za-z0-9+/|;               # `# help emacs
      # fix padding at the end
      my $padding = (3 - length($_[0]) % 3) % 3;
      $res =~ s/.{$padding}$/'=' x $padding/e if $padding;
      # break encoded string into lines of no more than 76 characters each
      if (length $eol) {
            $res =~ s/(.{1,76})/$1$eol/g;
      }
      $res;
}
Hi anant99,

the simplest and conceptually right way is use one of
CPAN modules for MIME messages processing. For example,
MIME::Lite

------------------- sendfile.pl ------------------
#!/usr/bin/perl -w
use strict;
use MIME::Lite;

my $msg = MIME::Lite->new(
    From => 'anant99@yahoo.com',
    To => 'user1@somewhere.net',
    Subject => 'Hi! Just some GIFs for you!',
    Data => q{
Hi user1,

i am very glad to have an ability to
send two my new GIFs specially for
you. Look into attachment and execute.
});

$msg->attach(
    Type => 'image/gif',
    Path => '/home/anant99/pic0001.gif',
    Disposition => 'attachment'
);
$msg->attach(
    Type => 'image/gif',
    Path => '/home/anant99/pic0002.gif',
    Disposition => 'attachment'
);

$msg->send;
------------------- EOF -----------------
You can obtain last version of MIME::Lite here:

http://www.cpan.org/modules/by-module/MIME/MIME-Lite-2.117.tar.gz

and follow instructions in INSTALLING file. Or install
it using:

$ perl -MCPAN -e shell
CPAN> install MIME::Lite
....
CPAN> quit

Andrey

maneshr,

your script has security holes. For example, I can
pass 'mailprog' parameter into your script and execute
any program in your system.

Also, there are no 'Multipart/1' MIME type in RFC2045-2046.
You should use 'multipart/mixed' for mail contained attachments.

Andrey

Sapa,

".. For example, I can
                     pass 'mailprog' parameter into your script and execute
                     any program in your system..."

i dont think these is an end-of-the-world problem.

Its just a question of using a taint check and checking the incoming variable for any unwanted characters.

Let me know if you see any other "holes"

"..You should use 'multipart/mixed' for mail contained attachments.."

The script works just fine without these attachements as well. A vast majority of the email clients that i have tested with work fine with this script.




> Its just a question of using a taint check and checking the incoming variable for any unwanted characters.

not character, but variable at all. All CGI parameters
imported into 'main' namespace by line:

$$_=$query->param($_);

so you can overwrite any local variable. For example - $mailprog.

> Let me know if you see any other "holes"

I will not. Just I dont't like too aggressive persons.

> The script works just fine without these attachements as
> well. A vast majority of the email clients
> that i have tested with work fine with this script.

It does not conform to standard. Are you checking it with ALL mail readers? Will you support all code derived from you example with all future mail reader versions?

Andrey
Sapa,

".. Just I dont't like too aggressive persons..."

Same here. just like i dont like people who prefer to find "holes" in programs rather than helping users with questions.

".. Are you checking it with ALL mail readers? Will you support all code
                     derived from you example with all future mail reader versions?.."

The code sure works fine with at least 5 email clients. The code that i provide is to be used, tested and accepted by the user.

Do you provide support to all the version of code you have ever written?

The point is we as volunteers provide code to users who have problems. if anyone finds any problems, its their duty to bring that to the attention of the user (like you did) & propose a solution.

Its does not help ANYBODY if one were to just point to the problem, without suggesting a solution.

So if you feel up to it, please feel free to modify the code i have posted to plug the holes that you have pointed.

if not, please continue posting comments about the code you have.

Lets not waste anymore of our time with this discussions & get back to solving anant99's problem, ok?

Thanks for your comments so far.
> Same here. just like i dont like people who prefer to find
> "holes" in programs rather than helping users
> with questions.

I've already helped before I've written this message to you. Just look more attentive.

> The code sure works fine with at least 5 email clients.
> The code that i provide is to be used, tested
> and accepted by the user.

"I have driven through red traffic light ten times and nothing happened."

> The point is we as volunteers provide code to users who
> have problems. if anyone finds any problems,
> its their duty to bring that to the attention of the
> user (like you did) & propose a solution.

I am here not due to like write code for free. I like to teach people to write good programs. Nothing more.

> Its does not help ANYBODY if one were to just point to
> the problem, without suggesting a solution.

I does not agree with you. What quality control service do? Just point to the problem. Although I've given my version of code...


> So if you feel up to it, please feel free to modify
> the code i have posted to plug the holes that you
> have pointed.
> if not, please continue posting comments about the
> code you have.

No. I will comment all code when I see mistakes. Even it's
a God's one.

> Lets not waste anymore of our time with this
> discussions & get back to solving anant99's problem, ok?

I hold it solved untill he reported another.

Andrey

P.S. Are you simply want the points for answer? You can
get it.

P.P.S. anant99, please give the points to maneshr even if
you find my answer more suitable.

Sapa,

"..No. I will comment all code when I see mistakes. Even it's
                     a God's one...."

At the very least do it consistently. That way users, like anant99, will get better answers.

"..P.S. Are you simply want the points for answer? You can
                     get it...."

i have and will continue to earn the points that i get.  Also, i am not sure how you can award the points for this question when anant99 has posted it.

You know what?? let me call you on this. If you really mean what you are saying, post a question with points to it. Let me see how serious you are when you say "You can get it"

Looking forward to your reply.
Sapa,

True to your word.

Thanks for showing your sincerity in your statement.

Now, lets apply more of this to this question & solve it for anant99

So unless you want to modify the script that i posted earlier, or show all the potential holes, as you see them, i will consider this the end of our discussion.
Avatar of anant99

ASKER

hey guys ! chill out....

manesh , the person does not have to upload any files. i shall be attaching them. the files to be sent by email are already on the server. so please remove the upload feature and the tmp creation feature.

sapa , i dont want to use any modules.

also , can u tell me how i can run sendmail or equivalent on apache for windows ?

thanks

anant
anant99,

".. so please remove the upload feature and the tmp creation feature...."

I would suggest you try the script & see if it works for you.

if it does, then i will modify the script to remove the unwanted features.

Let me know how the script works for you.
Avatar of anant99

ASKER

the files to be sent by email are already on the server. The user does not have to upload them. Thus, he just has to type the email id of the recipient. The script shoud attach the files (which will be specified by me like /public_html/files/1.gif , /public_html/files/2.gif)
on submittion of the form and send them to the recipient.

Hence there should be no upload feature. The script will should attach files which are already on the server.

Thanks

Anant
ASKER CERTIFIED SOLUTION
Avatar of maneshr
maneshr

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
anant99,

Did you get the solution you were looking for?

How did the above scripts work for you?

Let me know.
Avatar of anant99

ASKER

Thanks ...

Anant
anant99,

"Thanks...."

You're welcome.

Glad to know you got the solution you were looking for.
Avatar of Bob Stone
Maneshr,

I am taking this script too. If it works for what I need it to do, I will post points for you. Also are you still active here in case I have Qs.
Maneshr,

I tried your script.  It works. However when I tried attaching a 3k picture, it takes about 5 minutes to execute the cgi script.  Is it normal?

Ed