I have set email interception on my server.
following is my email forwarder set on server
testemail#my.server.com,"/home/server/php_pipe_mail.php"
following is my code for php_pipe_mail.php
#!/usr/bin/php -q
<?php
require_once('mimeDecode.php');
include('sql-connect.php');
error_reporting(E_ALL);
ob_start();
$raw_email = '';
if (!$stdin = fopen("php://stdin", "R"))
{
echo "ERROR: UNABLE TO OPEN php://stdin \n";
}
// ABLE TO READ THE MAIL
else
{
while (!feof($stdin))
{
$raw_email .= fread($stdin, 4096);
}
fclose($stdin);
}
$raw_email = preg_replace('/ +/', ' ', $raw_email);
var_dump($raw_email);
$buf = ob_get_contents();
$params['include_bodies'] = true;
$params['decode_bodies'] = true;
$params['decode_headers'] = true;
$params['input'] = $buf;
$params['crlf'] = "\r\n";
//Creating temp file on server
$myFile = "amail.txt";
$fh = fopen($myFile, 'w') or die("can't open file");
fwrite($fh, $buf);
fclose($fh);
//Generating mail structure in object format
$structure = Mail_mimeDecode::decode($params);
$attachment = array();
$mail_date= date( 'Y-m-d H:i:s', strtotime($structure->headers['date']) );
$from = $structure->headers['from'];
$to = $structure->headers['to'];
$subject = htmlentities($structure->headers['subject'],ENT_QUOTES);
if($structure->ctype_primary == "multipart")
{
$body_text = $structure->parts[0]->parts[0]->body;
$body_html = $structure->parts[0]->parts[1]->body;
$x = 0;
//fetch attachment
foreach ($structure->parts as $part) {
// only save if an attachment
if (isset($part->disposition) and ($part->disposition=='attachment')) {
$attachment[$x]["filename"] = $part->d_parameters['filename'];
$attachment[$x]["content_type"] = $part->ctype_primary . "/" . $part->ctype_secondary;
$attachment[$x]["body"] = addslashes($part->body);
$x++;
}
}
}
else
{
$body_text = $structure->parts[0]->body;
$body_html = $structure->parts[1]->body;
}
$qry1 = "insert into mail_buffer(mail_date,mail_from, mail_to,mail_subject,mail_text_body,mail_html_body) Values('". $mail_date ."','".$from."','".$to."','".$subject."','".$body_text."','".$body_html."')";
mysql_query($qry1) or die(mysql_error($con));
$last_id = mysql_insert_id();
if(count($attachment) > 0)
{
for($i=0; $i < count($attachment); $i++)
{
$qry = "insert into mail_attachment(email_id,content_type, file_name,body) Values('". $last_id ."','".$attachment[$i]['content_type']."','".$attachment[$i]['filename']."','".$attachment[$i]['body']."')";
mysql_query($qry) or die(mysql_error($con));
}
}
mysql_close($con);
ob_end_clean();
?>
Now above script works perfectly fine.
I am able to fetch message header, body and attachments and can store them in database without any problems.
When email without attachments come everything works fine and email is delivered to email address I am intercepting.
But following is not working.
When email with attachments comes than email content is being stored in database but email is not delivering to email address I am intercepting and I am getting following error message in bounce back email.
A message that you sent could not be delivered to one or more of its
recipients. This is a permanent error. The following address(es) failed:
pipe to |/home/server/php_pipe_mail.php
generated by testemail#my.server.com
Can anyone help me regarding the matter.
Thanks.
Could it be that, when an attachment is present, your script is echoing something? I have had problems piping emails before, and seen failure messages returned to senders, and they have been due to the piping script producing some kind of output. Maybe your error_reporting(E_ALL); is allowing the script to produce an output - try error_reporting(0);
Related
I'm running a PHP script that runs a sequence of SQL queries, writes the results to CSV, and saves it. It also mails the report to a recipient.
The CSV portion of the code works perfectly, and the PHPMailer portion sends the test email with no problem. However, when I un-comment the attachment portion of PHPMailer and run the script it says "File could not be accessed". When I replace the comment, it writes the file and sends the test email again just fine.
The line in question, which I comment/uncomment accordingly, is: $mail->addAttachment($fp);
So, the two pieces are working, but this being my first time using PHPMailer, I'm not sure the best way to go about fixing this. As far as I can tell, I'm using the addAttachment code properly and I'm closing the CSV at the very end.
Any help is much appreciated.
The script:
if (!$result) die('Couldn\'t fetch records');
$num_fields = mysqli_num_fields($result);
$headers = array();
while ($fieldinfo = mysqli_fetch_field($result)) {
$headers[] = $fieldinfo->name;
}
$fp = fopen('dailyReportTestPHP.csv', 'w');
if ($fp && $result) {
fputcsv($fp, $headers);
while ($row = $result->fetch_array(MYSQLI_NUM)) {
fputcsv($fp, array_values($row));
}
}
$mail = new PHPMailer(true);
$address = "hnorman#jacksonfurnind.com";
try{
$mail->setFrom("hnorman#jacksonfurnind.com");
$mail->addAddress($address);
$mail->addAttachment($fp);
$mail->isHTML(true);
$mail->Subject = "Test";
$mail->Body = "Test";
$mail->Send();
echo 'message sent';
} catch (Exception $e){
echo 'message failed';
echo 'mail error:' . $mail->ErrorInfo;
}
fclose($fp);
It's because $fp is an open file handle; PHPMailer is expecting a string containing the path to the file to be passed to addAttachment(). So, move the fclose call to before you create the PHPMailer instance, and then do this:
$mail->addAttachment('dailyReportTestPHP.csv');
I'm trying to create a piece of code that will go into the mailbox and take out the attachments of a specific file. So far I am only able to view if there is an attachment or if there is not an attachment on the e-mail.
But I want it to be able to take the attachments out of the e-mail and then save them to a specified directory. The type of attachment I'm trying to take out is a .jpg
I've tried a bunch of different pieces of code that I've found on google and I've been trying to tailor it to fit into my code, but so far I have been unsuccessful in finding anything that works correctly.
I was wondering if anyone would be able to help me create a piece of code that would be able to take the attachments out of the emails and store them in a directory.
Thanks.
<?php
/* connect to email */
$hostname = '{*****.com:110/pop3}INBOX';
$username = '*****';
$password = '*****';
// try to connect
$inbox = imap_open($hostname,$username,$password) or die('Cannot connect to server: ' . imap_last_error());
// grab emails
$emails = imap_search($inbox,'ALL');
// Search for the 39th email, which has an attachment
$count = 39;
// Fetch all the information about an email
$attachment = imap_fetchstructure($inbox, $count);
// find out how may parts the object has
$numparts = count($attachment->parts);
// find if if multipart message
if ($numparts >= 2) {
foreach ($attachment->parts as $part) {
if ($part->disposition == "INLINE") {
// inline message. Show number of lines
printf("Inline message has %s lines<BR>", $part->lines);
} elseif ($part->disposition == "ATTACHMENT") {
// an attachment
echo "Attachment found!";
// print out the file name
echo "Filename: ", $part->dparameters[0]->value;
}
}
}
//}
else {
// only one part so get some useful info
echo "No attachment";
}
imap_close($imap);
?>
Instead of imap_search I used imap_check to retrieve messages overview, and the following worked.
Go over messages found with imap_check, and this is how you extract the binary data of attachment:
$mbox = imap_open( . . . . );
$IMAPobj = imap_check($inbox);
$start = $IMAPobj->Nmsgs-30;
$end = $IMAPobj->Nmsgs;
$result = imap_fetch_overview($inbox,"$start:$end",0);
$count = $end;
foreach ($result as $overview) {
$parts = mail_mime_to_array($inbox, $count);
foreach($parts as $part) {
if(#$part['filename'] || #$part['name'] ) {
$partName = $part['filename'] ? $part['filename'] : $part['name'];
echo "Attachment name is " . basename($partName);
echo "\n";
if(preg_match( . . . write here a regex to detect ".jpg" in $partName . . .)) {
echo "Found file! Extracting binary data...";
$fileContents = $part['data'];
file_put_contents("attachment.jpg", $fileContents);
}
}
}
}
I've got a script running when a certain email address receives an email, procmail pipes to a PHP script, which is then parsed by Plancake, not many problems there. I've got an if statement on strpos, depending on if the body contains a certain text. For some reason, when I add the MySQL code, the entire thing stops working. Unfortunately the way it's setup I'm not quite sure how to add error checking. Here's the code:
<?php
require_once("PlancakeEmailParser.php");
$rawEmail = '';
if (($fp = fopen('php://stdin', 'r')) !== false) {
while (!feof($fp)) {
$rawEmail .= fread($fp, 1024);
}
fclose($fp);
}
$emailParser = new PlancakeEmailParser($rawEmail);
$emailSubject = $emailParser->getSubject();
$emailBody = $emailParser->getPlainBody();
$emailHeader = $emailParser->getHeader('From');
$message = "FROM: ".$emailHeader."\n\nSubject: ".$emailSubject."\n\nBody: ".$emailBody;
$status = 4;
preg_match("/\d+/", "$emailSubject", $matches);
$number = $matches[0];
$short = substr($message, 0, strpos( $message, 'Begin'));
if (stripos($short,'approve') !== false) {
echo 'true';
$msg = approve;
//file_put_contents('/home/symantec_mail/task' . $number . 'short.php',$msg);
file_put_contents('/home/symantec_mail/task' . $number . 'approve_short_reply.txt',$message);
file_put_contents('/home/symantec_mail/task' . $number . 'approve_reply.txt',$rawEmail);
}
if (stripos($short,'complete') !== false) {
echo 'true';
$msg = complete;
when I uncomment the following mysqli code, everything stops.
//$mysqli = new mysqli("localhost", "user", "pass", "db");
//$update = $mysqli->prepare("UPDATE task_overview SET status = ? WHERE task_id = ?");
//$update->bind_param('ii', $status, $number");
//$update->execute();
rest of the code.
//file_put_contents('/home/symantec_mail/task' . $number . 'short.php',$msg);
file_put_contents('/home/symantec_mail/' . $number . 'complete_short_reply.txt',$message);
file_put_contents('/home/symantec_mail/' . $number . 'complete_reply.txt',$rawEmail);
}
?>
Really not sure why I can't execute these commands. I will point out that it's on a different shell account than my normal web server, although the PHP is still executing, I'm really not sure if I'm communicating with the MySQL server. Please if you have any suggestions, even if it's for error checking I'll greatly appreciate it.
I'm trying to get 'email message' from any Email Service Provider, like: yahoo, Gmail, Hotmail. But I can't get it. It's show error message.
Following is my php script..
<?php
if( $mbox = imap_open("{yoursitename.com:110/pop3/notls}INBOX", "username of mailbox",
"password of mailbox")){
$path = "set path here for where the attachments are store";
$check = imap_mailboxmsginfo($mbox);
function getmsg($mbox,$mid) {
global $charset,$htmlmsg,$plainmsg,$attachments,$from,$to,$subj,$timages,$path;
$htmlmsg = $plainmsg = $charset = '';
$attachments = array();
// HEADER
$h = imap_headerinfo($mbox,$mid);
// add code here to get date, from, to, cc, subject...
$date = $h->date;
$from = $h->fromaddress;
$to = $h->toaddress;
$subj = htmlspecialchars($h->Subject);
// BODY
$s = imap_fetchstructure($mbox,$mid);
if (!$s->parts) // simple
getpart($mbox,$mid,$s,0); // pass 0 as part-number
else { // multipart: cycle through each part
foreach ($s->parts as $partno0=>$p)
getpart($mbox,$mid,$p,$partno0+1);
}
}
function getpart($mbox,$mid,$p,$partno) {
// $partno = '1', '2', '2.1', '2.1.3', etc for multipart, 0 if simple
global
$htmlmsg,$plainmsg,$charset,$attachments,$partid,$last_mail_id,$patterns,$pic,
$newstr,$c,$ok,$timages,$subj,$path;
$patterns = array();
$pic = array();
$image=array();
$data = ($partno) ? imap_fetchbody($mbox,$mid,$partno) : imap_body($mbox,$mid);
// simple
if ($p->encoding==4)
$data = quoted_printable_decode($data);
else if ($p->encoding==3)
$data = base64_decode($data);
// PARAMETERS // get all parameters, like charset, filenames of attachments,
etc.
$params = array();
if ($p->parameters)
foreach ($p->parameters as $x)
$params[strtolower($x->attribute)] = $x->value;
if ($p->dparameters)
foreach ($p->dparameters as $x)
$params[strtolower($x->attribute)] = $x->value;
// ATTACHMENT // Any part with a filename is an attachment,
// so an attached text file (type 0) is not mistaken as the message.
if ($params['filename'] || $params['name']) {
$partid = htmlentities($p->id,ENT_QUOTES);
// filename may be given as 'Filename' or 'Name' or both
$filename = ($params['filename'])? $params['filename'] : $params['name'];
// filename may be encoded, so see imap_mime_header_decode()
$attachments[$filename] = $data; // this is a problem if two files have same name
//store id and filename in array
$image[$key] = $filename;
}
//save the attachments in the directory
foreach( $attachments as $key => $val){
$fname = $key;
$fp = fopen("$path/$fname","w");
fwrite($fp, $val);
fclose($fp);
}
// TEXT
if ($p->type==0 && $data) {
// Messages may be split in different parts because of inline attachments,
// so append parts together with blank row.
if (strtolower($p->subtype)=='plain')
$plainmsg .= trim($data)."\n\n";
else
//preg_match_all('/<img[^>]+>/i',$data, $result);
$htmlmsg .= $data."<br><br>";
$charset = $params['charset']; // assume all parts are same charset
}
// There are no PHP functions to parse embedded messages, so this just appends the
raw source to the main message.
else if ($p->type==2 && $data) {
$plainmsg .= $data."\n\n";
}
// SUBPART RECURSION
if ($p->parts) {
foreach ($p->parts as $partno0=>$p2)
getpart($mbox,$mid,$p2,$partno.'.'.($partno0+1)); // 1.2, 1.2.1, etc.
}
}
$attachments = array();
$num_msg = imap_num_msg($mbox);
if($num_msg>0) {
getmsg($mbox,1);
}else {
echo "Sorry!...No Messages in MailBox...<br>";
}
//imap_delete and imap_expunge are used to delete the mail after fetching....Uncomment
it if you want to delete the mail from mailbox
//imap_delete($mbox,1);
//imap_expunge($mbox);
imap_close($mbox);
}else { exit ("Can't connect: " . imap_last_error() ."\n"); echo "FAIL!\n"; };
?>
error message:
Warning: imap_open() [function.imap-open]: Couldn't open stream {yahoo.com:110/pop3
/notls}INBOX in D:\xampp server\xampp\htdocs\practice\php\email.php on line 2
Fatal error: Maximum execution time of 30 seconds exceeded in D:\xampp server\xampp
\htdocs\practice\php\email.php on line 2
Notice: Unknown: Can't connect to yahoo.com,110: Timed out (errflg=1) in Unknown on
line 0
Notice: Unknown: Can't connect to yahoo.com,110: Timed out (errflg=1) in Unknown on
line 0
Notice: Unknown: Can't connect to yahoo.com,110: Timed out (errflg=2) in Unknown on line 0
Can anyone fix it?
Thanks.
As arkascha said, yahoo.com doesn't listen on port 110.
Yahoo's POP3 server is pop.mail.yahoo.com on port 110 (or 995 with SSL) as stated in this Yahoo help article
OK, this is Another Project Im Working ON.
Its a Chat Client. and Using it For Staff
I want the server to have a staff.txt on it.
and I want the php file to do this.
Execute the php.
if The Submitted Username is Found in the staff.txt then
The Username changes to [Staff]"Username Here"
I got the search and find down.
I Cant seem to keep the username that was submitted, and just adding staff to it.
Im Adding my Source Now.
<?php
// Parameters (Leave this Alone)
$Message = $_GET["message"];
$Username = htmlspecialchars($_GET["username"]);
$time = ($_GET["time"]);
// User Banning
$data = file_get_contents('Banned.txt');
if(strpos($data, $Username) !== FALSE)
{
die();
}
else
{
// File Writing (Leave this Alone)
$File = "Chat.txt";
$Handle = fopen($File, "a");
fwrite($Handle, $Username);
fwrite($Handle, ": ");
fwrite($Handle, $Message);
fwrite($Handle, " -:-:- ");
fwrite($Handle, $time);
fwrite($Handle, "\r\n");
print "Message Sent";
fclose($Handle);
}
?>
I have user banning working, and i Want the Staff To Work in the same way.
Any Help would be appreciated
Trying it a different way
If ($Username=="!divider!StaffMember1") $Username="!divider![Staff] StaffMember1";
If ($Username=="!divider!StaffMember2") $Username="!divider![Staff] StaffMember2";
that seems to work fine in the php file thats running the php with everything else.
Is there a way to have that list in a seperate file? .txt file or .php doesnt matter.
You can just do it like the banlist:
<?php
// Parameters (Leave this Alone)
$Message = $_GET["message"];
$Username = htmlspecialchars($_GET["username"]);
$time = ($_GET["time"]);
// check staff
$data = file_get_contents('staff.txt');
if(strpos($data, $Username) !== FALSE)
$Username = '[STAFF]' . $Username;
// User Banning
$data = file_get_contents('Banned.txt');
if(strpos($data, $Username) !== FALSE)
{
die();
}
else
{
// File Writing (Leave this Alone)
$File = "Chat.txt";
$Handle = fopen($File, "a");
fwrite($Handle, $Username);
fwrite($Handle, ": ");
fwrite($Handle, $Message);
fwrite($Handle, " -:-:- ");
fwrite($Handle, $time);
fwrite($Handle, "\r\n");
print "Message Sent";
fclose($Handle);
}
?>