smtp_connect(); // Connection au serveur POP3 localhost sur le port 110 $socket = $POP3->pop_connect("localhost",110); $POP3->pop_login($socket,"*** USER ***","*** PASSWORD ***"); // Annalyse du message 1 sur le serveur $mime->parse_mail($POP3, $socket, 1); // Affichage de toutes les infos sur le message print_r($mail); // Affichage du message analysé print("

 


".$mime->fullbody); // Envoi d'un message $SMTP->smtp_mail($con_smtp, '"Moi" ', Array('"toi" '), "Salut", "", "Salut !!"); ?> */ /** * SMTP Class v1.3 * Send mails to SMTP server easly and fastly * Go to http://forum.maxg.info for help & info */ class SMTP { var $t = Array(); var $v = "1.3"; /** * SMTP connect function * * @Access public * @Param str $str_Host = SMTP Server * @Param int $int_Port = SMTP Port * @Param str $str_Sendscript = Banner to send on connect * @Param int $int_Auth = User SMTP Authentification * @Param str $str_User = SMTP User for the auth (no encoding) * @Param str $str_Pass = SMTP Password for the auth (no encoding) * @Return obj $fp = Connection pointer for the commands */ function smtp_connect($str_Host="localhost",$int_Port=25,$str_Sendscript="phpsmtplib@maxg.info",$int_Auth=0,$str_User="",$str_Pass="") { $fp = fsockopen ("$str_Host", $int_Port, $int_Err, $str_Err,1); if (!$fp) { die("Impossible de se connecter au serveur $str_host :
$int_Err : $str_Err
"); } $this->t[] = "<- ".fgets ($fp, 200); $qu = "HELO $str_Sendscript\r\n"; fputs ($fp, $qu, strlen($qu)); $this->t[] = "-> ".trim($qu); $this->t[] = "<- ".fgets($fp,100); $qu = "NOOP Librairie PHP-SMTP ".$this->v." (http://www.maxg.info)\r\n"; fputs ($fp, $qu, strlen($qu)); $this->t[] = "-> ".trim($qu); $this->t[] = "<- ".fgets($fp,100); if($int_Auth==1) { $qu = "AUTH LOGIN\r\n"; fputs ($fp, $qu, strlen($qu)); $this->t[] = "-> ".trim($qu); $this->t[] = "<- ".fgets($fp, 200); fputs ($fp, base64_encode($str_User)."\r\n"); $this->t[] = "<- ".fgets($fp, 200); fputs ($fp, base64_encode($str_Pass)."\r\n"); $this->t[] = "<- ".fgets($fp, 200); } return $fp; } /** * SMTP Mail function - send a SMTP mail * * @Access public * @Param obj $fp = Connection pointer * @Param str $str_From = Mail sender (format = ) * @Param arr $ar_To = Array of the recipients (format = ["Name" ] ) * @Param str $str_Subject = Subject of the mail * @Param str $str_Headers = Headers to add (Mime-Version,X-Priority...) * @Param str $str_Body = Body of your mail (can be MIME multipart) * @Return bool = Success if true, Fail if false */ function smtp_mail ($fp, $str_From, $ar_To, $str_Subject, $str_Headers, $str_Body) { if (!$fp) return FALSE; $qu = "MAIL FROM:<$str_From>\r\n"; fputs($fp, $qu, strlen($qu)); $this->t[] = "-> ".trim($qu); $this->t[] = "<- ".fgets($fp,100); for($z=0;isset($ar_To[$z]);$z++){ $qu = "RCPT TO:".trim($ar_To[$z])."\r\n"; fputs($fp, $qu); $this->t[] = "-> ".trim($qu); $this->t[] = "<- ".fgets($fp,300); } $all = implode("; ",$ar_To); $qu = "DATA\r\n"; fputs($fp, $qu, strlen($qu)); $this->t[] = "-> ".trim($qu); $this->t[] = "<- ".fgets($fp, 100); $qu = "From: $str_From\r\n"; fputs($fp, $qu, strlen($qu)); if ($str_Headers) { $qu = $str_Headers; fputs($fp, $qu, strlen($qu)); } $qu = "To: $all\r\nSubject: $str_Subject\r\n"; fputs($fp, $qu, strlen($qu)); $qu = "\r\n$str_Body\r\n"; fputs($fp, $qu, strlen($qu)); $qu = "\r\n.\r\n"; fputs($fp, $qu, strlen($qu)); usleep(10); $this->t[] = "<- ".fgets($fp, 100); $qu = "RSET\r\n"; fputs ($fp, $qu, strlen($qu)); $this->t[] = "-> ".trim($qu); $this->t[] = "<- ".fgets($fp, 100); return TRUE; } /** * SMTP Close function * * @Param obj $fp = Connection pointer * @Return arr = IN/OUT commands (begins with "<-" / "->" means IN/OUT) */ function smtp_close ($fp) { if (!$fp) return 0; $qu = "QUIT\r\n"; fputs($fp,$qu,strlen($qu)); $this->t[] = "-> ".trim($qu); $this->t[] = "<- ".fgets($fp,200); fclose($fp); return $this->t; } } // Classe POP3 class POP3 { var $totaille = 0 ; // Total Mailbox size var $banner = ""; // POP3 banner var $dial = Array(); // Server replies var $sizes = Array(); // Messages sizes /** * Connects to server * * @Param str &$str_Host = POP3 server to connect * @Param int &$int_Port = Port to connect (110 by default) * @Return { * Succes: obj $soket = Connection object for the server * Error : bol FALSE = Unable to connect. * also create $int_Error (err num) and $str_Err * Note : str $POP3->banner is created (POP3 banner) * } */ function pop_connect($str_Host = "localhost", $int_Port = 110) { $soket = fsockopen ($str_Host, $int_Port, $int_Err, $str_Err); if (!$soket) { global $str_Err,$int_Err; return FALSE; } $this->banner = ($this->dial[]=fgets($soket,100)); return $soket; } /** * Login * * @Param obj $soket = Connection pointer created with pop_connect() * @Param str $str_User = Username to send * @Param str $str_Pass = Password to send * @Return { * Succes: int $int_nMsg = Number of messages on the mailbox * Error : -1 = invalid connection pointer * -2 = invalid username * -3 = bad password * -4 = STAT failed * Note : int $POP3->totaille is created (Mailbox size) * } */ function pop_login($soket, $str_User, $str_Pass) { if (!$soket) { return -1; } $flag = md5(trim(substr($this->banner,strpos($this->banner,"<"),strlen($this->banner)-1)).$str_Pass); $qu = "APOP $str_User $flag\r\n"; fputs($soket,$qu); $this->dial[] = "-> ".$qu; if(eregi("-ERR",($this->dial[]="<- ".fgets($soket,100)))) { $qu = "USER $str_User\r\n"; fputs($soket,$qu); $this->dial[] = "-> ".$qu; if(eregi("-ERR",($this->dial[]="<- ".fgets($soket,100)))) return -2; $qu = "PASS $str_Pass\r\n"; fputs($soket,$qu); $this->dial[] = "-> ".str_replace($str_Pass,"[Pass]",$qu); if(eregi("-ERR",($this->dial[]="<- ".fgets($soket,100)))) return -3; } $qu = "STAT\r\n"; fputs($soket, $qu); $this->dial[] = "-> ".$qu; $r = split(" ",($this->dial[]="<- ".fgets($soket,100))); if($r[1]=="-ERR") return -4; $this->totaille = $r[3]; $qu = "NOOP POP3 Librairie, dev.maxg.info\r\n"; fputs($soket,$qu); $this->dial[]="-> ".$qu; $this->dial[]="<- ".fgets($soket,200); return $r[2]; } /** * Remove a message from a mailbox * * @Param obj $soket = Connection pointer * @Param int $int_Msgid = Message number * @Return { * Succes: TRUE; * Error : -1 : Bad connection pointer * -2 : Unable to delete * } */ function pop_delete($soket, $int_Msgid) { if (!$soket) { return -1; } $qu = "DELE $int_Msgid\r\n"; fputs($soket, $qu); $this->dial[] = "-> ".$qu; if(substr(($this->dial[]="<- ".fgets($soket,100)),3,6)=="+OK") return true; else return -2; } /** * Gets message list * * @Param obj $soket = Connection pointer * @Param int $count = Number of mails (see pop_login()) * @Return { * Succes: Array of mails * Error : -1 : bad connection pointer * -2 : LIST command failed * } */ function pop_list($soket,$count) { if (!$soket) { return -1; } $qu = "LIST\r\n"; fputs($soket,$qu); $this->dial[] = "-> ".$qu; if(substr(($this->dial[]="<- ".fgets($soket,200)),3,7)=="-ERR") return -2; $rep[0] = $count; for($j=1;$j<=$count; $j++) { if($j > $count) { break; } $line = fgets($soket,500); $line = split(" ",$line); if($line[0] != $j) { $rep[$j] = "deleted"; } else { $rep[$j] = $line[1]; } unset($line); } $this->sizes=$rep; return $rep; } /** * Gets the headers of a mail * * @Param obj $soket = Connection pointer * @Param int $int_Id = Message ID (see pop_list()) * @Return { * Succes: Array of the headers * Error : -1 : bad connection pointer * -2 : TOP command failed * } */ function pop_top($soket, $int_Id) { if (!$soket) return -1; $all=""; $qu = "TOP $int_Id 0\r\n"; fputs($soket, $qu); $this->dial[] = "-> ".$qu; if(eregi("-ERR", ($this->dial[]="<- ".fgets($soket, 200)))) return -2; while (!ereg("^\.\r\n",$line=fgets($soket,200))) { if(!trim($line)) continue; $all.=$line; if($line[0]!="\t"){ if($data&&$hname){ $ar_Headers[strtolower($hname)].=$data; } $line=explode(":",$line,2); $hname = trim($line[0]); $data = trim($line[1]); }else{ $data.="\r\n\t".trim($line); } } if($data&&$hname) $ar_Headers["$hname"]=$data; $ar_Headers["all"] = $all; return $ar_Headers; } /** * Download a mail * * @Param obj $soket = Connection pointer * @Param int $int_Id = Message ID (see pop_list()) * @Return { * Succes: Array of the lines * Error : -1 : bad connection pointer * -2 : RETR command failed * } */ function pop_get($soket, $int_Id) { if (!$soket) return -1; $qu = "TOP $int_Id 9999\r\n"; fputs($soket,$qu); $this->dial[] = "-> ".$qu; if(eregi("-ERR",($this->dial[]="<- ".fgets($soket, 200)))) return -2; $line = fgets($soket, 2000); for($h=0; !ereg("^\.\r\n",$line); $h++) { $ar_Rep[$h] = $line; $line = fgets($soket,2000); if(empty($line)){ break; } } return $ar_Rep; } /** * Close connection to server * * @Param obj $soket = Connection pointer * @Return { * Succes: TRUE * Error : -1 : bad connection pointer * Note : $POP3->dial is created (the server dialog) * } */ function pop_quit($soket) { if(!$soket) return -1; $qu = "QUIT\r\n"; fputs($soket,$qu); $this->dial[]="-> ".$qu; $this->dial[]="<- ".fgets($soket,200); fclose($soket); return TRUE; } } /* * Mail Parsing Function * ========================================================= Il est beaucoup plus difficile que l'on pourrait le croire d'annalyser les en-têtes d'un message. Cette fonction doit pouvoir le faire sans IMAP ! A noter que la classe fait 300 lignes PILE (huhu :-) ========================================================== TODO : explicitement indiqué (## NOT IMPLEMENTD ##) ADD : Gestion de IMAP 4 possible mais sans utilisation de la librairie de PHP... =========================================================== Id:$parse_mail.inc.php;class£04/03§bouchon@maxg.info$ Todo:$addlines:#{12,13,14,}|trim(@each)$ =========================================================== */ class MiMail { var $fromname = "", // Nom expéditeur $fromaddr = "", // Adresse expéditeur $to = "", // Nom Destinataire $date = "", // Date d'envoi $subject = "", // Sujet $priority = 3, // Priorité du message $size = "", // Taille du mail $unit = "", // Unités (By,Kb,Mb) $ctype = "", // Type de contenu $reply_to = "", // Adresse de réponse $decodeattach = 0, // Annalyse ou pas des pièces (performances) $attachments = Array(), // Pièces jointes $mime = 0, // Message multipart ou simple ? $otherversion = 0, // Si le message comporte une version texte. $body = "", // Texte du message $fullbody = ""; // Message intégral non décodé var $timestamp = "", // Format de date $html = 1, // Préférer le HTML au texte (alternative) $wordwrap = 150, // Mots par ligne $url = ""; // URL du script // Fonction de construction function MiMail($url, $timestamp = "d/m/Y h:i", $html = 1, $ww=150, $decatt=0 ){ $this->timestamp = $timestamp; $this->wordwrap=$ww; $this->html = $html; $this->url=$url; $this->decodeattach=$decatt; } function decode_mime($string) { if(($pos = strpos($string,"=?")) === false) return $string; while(!($pos === false)) { $newresult .= substr($string,0,$pos); $string = substr($string,$pos+2,strlen($string)); $intpos = strpos($string,"?"); $charset = substr($string,0,$intpos); $enctype = strtolower(substr($string,$intpos+1,1)); $string = substr($string,$intpos+3,strlen($string)); $endpos = strpos($string,"?="); $mystring = substr($string,0,$endpos); $string = substr($string,$endpos+2,strlen($string)); if($enctype == "q") { $mystring = $this->decode_quoted_printable($mystring); } else if ($enctype == "b") $mystring = $this->decode_base64($mystring); $newresult .= $mystring; $pos = strpos($string,"=?"); } return $newresult.$string; } function decode_quoted_printable($body){ $body = preg_replace("/=([0-9A-F]{2})/e","chr(hexdec('\\1'))",$body); return str_replace("=\r\n","",$body); } function decode_base64($body){ $body = eregi_replace("\r|\n","",$body); return base64_decode($body); } function decode_7bits($body){ ## Not implemented ## return $body; } function decode_8bits($body){ ## Not implemented ## return $body; } function decode_encoding($headers,$body){ $cte = "Content-Transfer-Encoding:"; if(eregi("$cte base64",$headers)) $body = $this->decode_base64($body); elseif(eregi("$cte 8bits",$headers)) $body = $this->decode_8bits($body); elseif(eregi("$cte 7bits",$headers)) $body = $this->decode_7bits($body); else $body = $this->decode_quoted_printable($body); return $body; } function decode_disposition($headers,$ctype){ $in=eregi("inline",$headers); if($in||($ctype=="alternative")) $dispo="i"; elseif(eregi("attachment",$headers)) $dispo="a"; else{ switch($ctype){ case "related": $dispo="i"; break; case "mixed": $dispo="i"; break; default: $dispo="a"; } } if(eregi('name="',$headers)){ $fname=substr($headers,strpos($headers,'name="')+6,50); $fname=substr($fname,0,strpos($fname,'"')); $id=substr($headers,strpos($headers,"Content-ID: <")+13,50); $id=substr($id,0,strpos($id,">")); }else{ $fname=""; $id="";} return Array($dispo,$fname,$id); } /** * Analyse du content-type * Permet d'analyser récursivement les parties de message * * @Param str $tag = Tag ou headers entiers à analyser * * @Return { * Array( * str $ctype = Content-Type, ou si multipart * retourne le type de multipart, * str $bound = Retourne le Boundary si présent * } */ function content_type($tag){ if(!trim($tag)) return Array("text/plain",""); if(eregi('multipart',$tag)){ $ctype = eregi_replace("(.*)multipart/([a-z]*)(.*)","\\2",$tag); if(!$ctype) $ctype="related"; $bound = substr($tag,strpos($tag,'boundary="')+10,strlen($tag)); $bound = substr($bound,0,strpos($bound,'"')); }else{ $ctype = substr($tag,strpos($tag,"Content-Type: ")+14,35); $ctype = trim(eregi_replace("(([a-z]|-)*/([a-z]|-)*)(.*)","\\1",$ctype)); $bound = ""; } return(Array($ctype,$bound)); } /** * Analyse de structur d'un message * Cette fonction récursive a été de loin la plus chiante à faire : * imaginez que j'ai du lire 30 RFC (si si !) alors que je n'en * respecte que la moitié ... HYPER HARD * * Pour ceux qui ont le malheur de lire ceci, je peux les consoler en disant * que je faire une classe pour IMAP4 -- ARGGG ! * Rien qu'à voir le nombre de commandes on peut se suicider !! * * Je tiens à ajouter que cette classe est plutot optimisée, et que la plupart * des messages compatibles RFC sont correctement analysés. * * @Param str $msg = Message à analyser * @Param str $bound = Boundary du Content-Type * @Param str $dtype = Type de multipart (alternative, mixed, related) * @Param str $tenc = Type d'encodage * * @Return { * None * } */ function fetch_structure( $msg, $bound, $dtype, $tenc = "7bits" ){ if($bound){ if(!eregi($bound,$msg)) return $msg; $parts = spliti("(\-*)$bound(--)?\r\n",$msg); foreach($parts as $p){ if(!eregi("content-type",$p)) continue; $headers = substr($p,0,strpos($p,"\r\n\r\n")); list($ctype,$bound)=$this->content_type($headers); $body = substr($p,strpos($p,"\r\n\r\n")+4,strlen($p)); if($bound) $this->fetch_structure($body,$bound,$ctype); else{ list($dispo,$fname,$id)=$this->decode_disposition($headers,$dtype); if($dtype=="alternative"){ if($this->html){ if($ctype=="text/html") $disp=1; else{ $disp=0; $this->otherversion=1;} }else{ if($ctype=="text/plain") $disp=1; else{ $disp=0; $this->otherversion=1;} } }else{ if($dispo=="i") $disp=1; else $disp=0; } if($disp){ if($ctype=="text/plain") $this->body.="
".$this->decode_encoding($headers,$body)."
"; else $this->body.=$this->decode_encoding($headers,$body); } else{ if($id) $index = $id; else $index = count($this->attachments)+1; if($fname) $this->attachments[$index]=Array($fname,($this->decodeattach?$this->decode_encoding($headers,$body):"[NOT PARSED]"),$ctype); } } } }else{ $this->body.=wordwrap($this->decode_encoding("Content-Transfert-Encoding: ".$tenc,$msg),$this->wordwrap); } } /** * Analyse totale d'un message * Supporte pas trop mal les différents types de mail * On dirait pas comme ca mais c'est C-H-I-A-N-T * * @Param obj $POP3 = Objet créé par la classe pop3 * @Param ptr $soket = Pointeur de connection * @Param int $msgid = ID du message à annalyser * * @Return { * int TRUE on succes. * } */ function parse_mail($POP3,$soket,$msgid,$justheaders=0) { $mail = $POP3->pop_top($soket, $msgid); if($mail<0) return(-1); $to = $this->decode_mime($mail['to']); $this->to = htmlentities(trim($to)); $this->priority = $mail['x-priority']; $sujet = $mail[subject]; $this->subject = trim($this->decode_mime($sujet)); $from = $mail[from]; if($imap_ok){ $tmpfrom = imap_mime_header_decode ( $from ); for($r=0,$from="";$tmpfrom[$r];$r++) $from .= $tmpfrom[$r]->text; }else{ $from = $this->decode_mime($from); } if(ereg("<",$from)){ $froms = explode('<',$from,2); $froms[0]=str_replace('"',"",trim($froms[0])); $froms[1]=substr(trim($froms[1]),0,strlen(trim($froms[1]))-1); $from = $froms[0]; $addr_from = $froms[1]; }else{ $addr_from=$from; $from=""; } if(!$addr_from) $addr_from=substr($mail['return-path'],1,strlen($mail['eturn-path'])-1); $this->fromname = trim($from); $this->fromaddr = trim($addr_from); $this->reply_to=($mail['return-path']?$mail['return-path']:$addr_from); $this->date=@date($this->timestamp,@strtotime($mail['date'])); $this->mime=(@eregi("multipart",$mail['content-type'])?1:0); if($justheaders) return(1); $ar_Msg=$POP3->pop_get($soket, $msgid); $this->fullbody = implode('',$ar_Msg); $size = strlen(implode('',$ar_Msg)); $un = Array("By","Kb","Mb","Gb","Tb"); for($u=0;$size>=1024;$u++) $size=round($size/1024,1); $this->size=$size; $this->unit=$un[$u]; for($i=0,$ok=0;isset($ar_Msg[$i]); $i++){ $k = $ar_Msg[$i];if($k=="\r\n") $ok=1; if($ok) $body .= $k; } list($ctype,$bound)=$this->content_type("Content-Type: ".$mail['content-type']); $this->ctype = $ctype; $this->fetch_structure($body,$bound,$ctype,$mail['content-transfert-encoding']); if($this->html){ foreach($this->attachments as $k=>$v){ $this->body = str_replace("cid:$k",$this->url."&ac=read&msgNum=$msgid&attach=$k&name=".$v[0],$this->body); } } }} ?>