If you want to automatically process images or other attachments that are sent to a mailbox address in your cPanel account, then you need look no further than the Pipe to Program option in the cPanel Forwarders screen.
This is an often overlooked feature of cPanel accounts, probably because it’s not that easy to understand from a novice’s point of view. However, I’m going to do my best to explain how useful this feature is, and give an example of how you can pipe email using Perl.
What is piping anyway?
We’re not talking about the pretty decorations around a cake! In computer speak a pipe is a method of passing the standard output (stdout) from one process as the standard input (sdtin) to another. In Linux pipes allow many commands to be stuck together to achieve quite powerful results (or disasters!).
cPanel allows you to set up email forwarders that, instead of sending the email message onto another email address, pipe email straight to a program, or script. The script itself must be located somewhere in your home directory, but could be written in any suitable scripting language (PHP, Perl, Ruby, Bash etc.) or could be a compiled executable. It’s up to you!
How to configure the pipe
For this example, lets assume that we have a CTTV system that sends an email with an attachment every time it senses movement. We have configured the system to sent the email to cctv@endlessgeek.com. Now, we don’t actually need this mailbox to exist – as long as the forwarder is there, the mail system will accept the messages.
To get started, log into cPanel and open the Forwarder screen from the Mail section.
On the next screen, click the Add Forwarder button (NOT the Add Domain Forwarder button).
On the Add a New Forwarder screen, fill in the Address to Forward: with the address from which you want to pipe email. Click the Advanced Options link to reveal the Pipe to a Program option button, which you should click and then enter the path and name of your script in the box provided. In this case our script will be placed in the top level of our home directory and will be a Perl script called cctv.pl
Click the Add Forwarder button, and you’re done! You should see something like this in your Forwarders now:
Now for the script!
Perl script to strip attachments from MIME message
Excuse the verbose title – search engines, you know. OK, so this perl script should run fine on any cPanel server v11.40 and later. Time::Piece is a core module and should already be installed. However, MIME::Parser is not, so open a terminal session via SSH, and type in:
perl -MMIME::Parser -e ‘exit;’
If the module is installed, you won’t get any message at all. If it isn’t you will get an error message, and will need to ask your host to install the module for you. Many cPanel hosts allow you to install your own Perl modules via the Perl Modules icon in Software/Services:
Once you are happy that MIME::Parser is installed, then you can copy and paste this script and save it to your home directory, using the name you gave when setting up the piped forwarder above. Don’t forget to make sure that you set the permissions for this file to chmod 755 otherwise it isn’t going to be able to do its magic.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
#!/usr/local/bin/perl -w use strict; use MIME::Parser; use Time::Piece; # Replace 'userdir' with your own cPanel user name my $logfile='/home/userdir/extracted.log'; # Create the directory below and chmod 755 - this is where your images will go my $attachdir='/home/userdir/extracted'; my $parser=new MIME::Parser; $parser->ignore_errors(1); $parser->extract_uuencode(1); $parser->tmp_recycling(0); $parser->output_to_core(1); my $entity=$parser->parse(\*STDIN); my $from=$entity->head->get('From'); my $subject=$entity->head->get('Subject'); my @parts=$entity->parts; my $aname='attachment001'; while(my $part = shift(@parts)) { if($part->parts) { push @parts,$part->parts; # Nested multi-part next; } my $type=$part->head->mime_type || $part->head->effective_type; if($type !~ /^(text|message)/i) { # Not a text, save it my $filename=$part->head->recommended_filename || $aname; $aname++; my $io=$part->open("r"); my $datestamp = localtime->strftime('%Y%m%d-%H%M'); $filename =~ s/[;<>\*\|`&\$!#\(\)\[\]\{\}:'"\n]//g; open(F,">> $attachdir/$datestamp-$filename"); my $buf; while($io->read($buf,1024)) { print F $buf; } close(F); $io->close; open(LOG,">> $logfile"); print LOG localtime()." From: $from\tSubject: $subject\tFile: $datestamp-$filename\n"; close(LOG); } } |
Not a lot more to say really – if all is well you should be able to email a message containing an image attachment. Once the message is received by your server it will be piped to your script and you should find the event in the logfile extracted.log and the image in the extracted directory 🙂
Hello, im trying to get this script working, but i ran into a problem. When i try to send mail to the forwarded email i get mail delivery failed return message that says :
cagefs_enter: /home/xxxx/mailfwd.pl: No such file or directory
The autofiller in cpanel forward finds the file.
Logfile is not created.
Any suggestions ?
Interesting – I use this script on a server that also runs CloudLinux/CageFS so I’m unsure what your error relates to… have you tried running
cagefsctl –force-update
on this server?