home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / tsw / TSW_3.4.0.exe / Apache2 / admin / smtp.inc < prev    next >
Encoding:
Text File  |  2003-10-25  |  8.8 KB  |  338 lines

  1. <?php 
  2. /////////////////////////////////////////////////////////
  3. //    
  4. //    include/smtp.inc
  5. //
  6. //    (C)Copyright 2002 Ryo Chijiiwa <Ryo@IlohaMail.org>
  7. //
  8. //        This file is part of IlohaMail.
  9. //        IlohaMail is free software released under the GPL 
  10. //        license.  See enclosed file COPYING for details,
  11. //        or see http://www.fsf.org/copyleft/gpl.html
  12. //
  13. /////////////////////////////////////////////////////////
  14.  
  15. /********************************************************
  16.  
  17.     AUTHOR: Ryo Chijiiwa <ryo@ilohamail.org>
  18.     FILE:  include/smtp.php
  19.     PURPOSE:
  20.         Provide SMTP functionality using pure PHP.
  21.     PRE-CONDITIONS:
  22.         The functions here require a SMTP server configured to allow relaying.
  23.     POST-CONDITIONS:
  24.         The following global variables are returned:
  25.         $smtp_errornum - error number, 0 if successful
  26.         $smtp_error - error message(s)
  27.         $SMTP_TYPE - Optional
  28.     COMMENTS:
  29.         The optional $smtp_message_file can be used for sending extremely large
  30.         messages.  Storing large messages in a variable will consume whatever
  31.         amount of memory required, which may be more than is available if dealing
  32.         with messages with large attachments.  By storing them in a file, it becomes
  33.         possible to read/send bits at a time, drastically reducing memory useage.
  34.         
  35.         This library only provides bare-bones SMTP functionality.  It is up to the
  36.         parent code to form valid RFC822 (MIME) messages.
  37.             
  38. ********************************************************/
  39.     
  40.     //set some global constants
  41.     if (strcasecmp($SMTP_TYPE, "courier")==0){
  42.         $SMTP_REPLY_DELIM = "-";
  43.         $SMTP_DATA_REPLY = 250;
  44.     }else{
  45.         $SMTP_REPLY_DELIM = " ";
  46.         $SMTP_DATA_REPLY = 354;
  47.     }
  48.  
  49.     function smtp_check_reply($reply){
  50.         global $smtp_error;
  51.         global $SMTP_REPLY_DELIM;
  52.         
  53.         $a = explode($SMTP_REPLY_DELIM, chop($reply));
  54.  
  55.         if (count($a) >= 1){
  56.  
  57.             if ($a[0]==250||$a[0]==354) return true;
  58.             else{
  59.                 $smtp_error .= $reply."\n";
  60.             }
  61.         }else{
  62.             $smtp_error .= "Invalid SMTP response line: $reply\n";
  63.         }
  64.         
  65.         return false;
  66.     }
  67.     
  68.     
  69.     function smtp_split($str){
  70.         $result = array();
  71.         $pos = strpos($str, " ");
  72.         if ($pos===false){
  73.             $result[0] = $str;
  74.         }else{
  75.             $result[0] = substr($str, 0, $pos);
  76.             $result[1] = substr($str, $pos+1);
  77.         }
  78.         
  79.         return $result;
  80.     }
  81.     
  82.     
  83.     function smtp_ehlo(&$conn, $host){
  84.         $result = array();
  85.         fputs($conn, "EHLO $host\r\n");
  86.         //echo "Sent: EHLO $host\n"; flush();
  87.         do{
  88.             $line = fgets($conn, 2048);
  89.             //echo "Got: $line"; flush();
  90.             $a = explode(" ", $line);
  91.             if ($a[0]=="250-AUTH") $result["auth"] = substr($line, 9);
  92.         }while(!is_numeric($a[0]));
  93.         
  94.         if ($a[0]==250) return $result;
  95.         else return $a[0];
  96.         
  97.     }
  98.     
  99.     
  100.     function smtp_auth_login(&$conn, $user, $pass){
  101.         $auth["username"] = base64_encode($user);
  102.         $auth["password"] = base64_encode($pass);
  103.     
  104.         fputs($conn, "AUTH LOGIN\r\n");
  105.         
  106.         //echo "Sent: AUTH LOGIN\n"; flush();
  107.         
  108.         //get first line
  109.         $line = fgets($conn, 1024);
  110.         //echo "AUTH_LOGIN << $line"; flush();
  111.         $parts = smtp_split($line);
  112.         //valid reply?
  113.         if (($parts[0]!=334) || (empty($parts[1]))) return false;
  114.         //send data
  115.         $prompt = eregi_replace("[^a-z]", "", strtolower(base64_decode($parts[1])));
  116.         fputs($conn, $auth[$prompt]."\r\n");
  117.         //echo "AUT_LOGIN >> ".$auth[$prompt]."\n"; flush();
  118.  
  119.         //get second line
  120.         $line = fgets($conn, 1024);
  121.         //echo "AUTH_LOGIN << $line"; flush();
  122.         $parts = smtp_split($line);
  123.         //valid reply?
  124.         if (($parts[0]!=334) || (empty($parts[1]))) return false;
  125.         $prompt = eregi_replace("[^a-z]", "", strtolower(base64_decode($parts[1])));
  126.         fputs($conn, $auth[$prompt]."\r\n");
  127.         //echo "AUT_LOGIN >> ".$auth[$prompt]."\n"; flush();
  128.  
  129.         $line = fgets($conn, 1024);
  130.         //echo "AUTH_LOGIN << $line"; flush();
  131.         $parts = smtp_split($line);
  132.         return ($parts[0]==235);
  133.     }
  134.     
  135.     
  136.     function smtp_connect($host, $port, $user, $pass){
  137.         global $smtp_errornum;
  138.         global $smtp_error;
  139.  
  140.         //auth user?
  141.         global $SMTP_USER, $SMTP_PASSWORD;
  142.         if ((!empty($SMTP_USER)) && (!empty($SMTP_PASSWORD))){
  143.             $user = $SMTP_USER;
  144.             $pass = $SMTP_PASSWORD;
  145.         }
  146.         
  147.         echo "User: $user<br>\n";
  148.         
  149.         //figure out auth mode
  150.         global $AUTH_MODE;
  151.         $auth_mode = $AUTH_MODE["smtp"];
  152.         if (empty($auth_mode)) $auth_mode = "none";
  153.         if (empty($user) || empty($pass)) $auth_mode = "none";
  154.         
  155.         echo "authmode: $auth_mode<br>\n"; flush();
  156.         
  157.         //initialize defaults
  158.         if (empty($host)) $host = "localhost";
  159.         if (empty($port)) $port = 25;
  160.         
  161.         echo "Connecting to $host:$port<br>\n"; flush();
  162.         
  163.         //connect to SMTP server
  164.         $conn = fsockopen($host, $port);
  165.     
  166.         if (!$conn){
  167.             echo "fsockopen failed\n";
  168.             $smtp_error = "Couldn't connect to $host:$port<br>\n";
  169.             return false;
  170.         }
  171.         
  172.         //read greeting
  173.         $greeting = fgets($conn, 1024);
  174.             
  175.         echo "Connected: $greeting<br>\n"; flush();
  176.  
  177.         if (($auth_mode=="check") || ($auth_mode=="auth")){
  178.             echo "Trying EHLO<br>\n"; flush();
  179.             $auth_modes = smtp_ehlo($conn, $_SERVER["SERVER_NAME"]);
  180.             echo "smtp_ehlo returned: $auth_modes<br>\n"; flush();
  181.             if ($auth_modes===false){
  182.                 $smtp_error = "EHLO failed\n";
  183.                 $conn = false;
  184.             }else if (stristr($auth_modes, "LOGIN")==0){
  185.                 echo "trying AUTH LOGIN\n"; flush();
  186.                 if (!smtp_auth_login($conn, $user, $pass)){
  187.                     //echo "CONN: AUTH_LOGIN failed\n"; flush();
  188.                     $conn = false;
  189.                 }
  190.                 echo "Conn after LOGIN: $conn<br>\n"; flush();
  191.             }
  192.         }else{
  193.             fputs($conn, "HELO ".$_SERVER["SERVER_NAME"]."\r\n");
  194.             $line = fgets($conn, 1024);
  195.             if (!smtp_check_reply($line)){
  196.                 $conn = false;
  197.                 $smtp_error .= $line."\n";
  198.             }
  199.             echo "after HELO: $conn<br>\n"; flush();
  200.         }
  201.     
  202.         return $conn;
  203.     }
  204.     
  205.     
  206.     function smtp_close($conn){
  207.         fclose($conn);
  208.     }
  209.  
  210.  
  211.     function smtp_mail($conn, $from, $recipients, $message, $is_file){
  212.         global $smtp_errornum;
  213.         global $smtp_error;
  214.         global $SMTP_DATA_REPLY;
  215.         
  216.         //check recipients and sender addresses
  217.         if ((count($recipients)==0) || (!is_array($recipients))){
  218.             $smtp_errornum = -1;
  219.             $smtp_error .= "Recipients list is empty\n";
  220.             return false;
  221.         }
  222.         if (empty($from)){
  223.             $smtp_errornum = -2;
  224.             $smtp_error .= "From address unspecified\n";
  225.             return false;
  226.         }
  227.         
  228.         if (!$conn){            
  229.             $smtp_errornum = -3;
  230.             $smtp_error .= "Invalid connection\n";
  231.         }
  232.  
  233.         if (!ereg("^<", $from)) $from = "<".$from;
  234.         if (!ereg(">$", $from)) $from = $from.">";
  235.         
  236.         //send MAIL FROM command
  237.         $command = "MAIL FROM: $from\r\n";
  238.         echo nl2br(htmlspecialchars($command));
  239.         fputs($conn, $command);
  240.  
  241.         if (smtp_check_reply(fgets($conn, 1024))){
  242.             //send RCPT TO commands, count valid recipients
  243.             $num_recipients = 0;    
  244.             while ( list($k, $recipient) = each($recipients) ){
  245.                 $command = "RCPT TO: $recipient\r\n";
  246.                 fputs($conn, $command);
  247.                 $reply = smtp_check_reply(fgets($conn, 1024));
  248.                 if ($reply) $num_recipients++;
  249.                 else $smtp_error .= $reply."\n";
  250.             }
  251.             
  252.             //error out if no valid recipiets
  253.             if ($num_recipients == 0){
  254.                 $smtp_errornum = -1;
  255.                 $smtp_error .= "No valid recipients\n";
  256.                 return false;
  257.             }
  258.             
  259.             //send DATA command
  260.             fputs($conn, "DATA\r\n");
  261.             $reply = chop(fgets($conn, 1024));
  262.             $a = explode(" ", $reply);
  263.             
  264.             //error out if DATA command ill received
  265.             if ($a[0]!=$SMTP_DATA_REPLY){
  266.                 $smtp_errornum = -4;
  267.                 $smtp_error .= $reply;
  268.                 return false;    
  269.             }
  270.             //send data
  271.             if ($is_file){
  272.                 //if message file, open file
  273.                 $fp = false;
  274.                 if (file_exists(realpath($message))) $fp = fopen($message, "rb");
  275.                 if (!$fp)
  276.                 { 
  277.                     $smtp_errornum = -4;
  278.                     $smtp_error .= "Invlid message file\n";
  279.                     return false;
  280.                 }
  281.                 
  282.                 //send file
  283.                 while(!feof($fp)){
  284.                     $buffer = chop(fgets($fp, 4096), "\r\n");
  285.                     fputs($conn, $buffer."\r\n");
  286.                 }
  287.                 fclose($fp);
  288.                 fputs($conn, "\r\n.\r\n");
  289.                 
  290.                 return smtp_check_reply(fgets($conn, 1024));
  291.             }else{
  292.                 //else, send message
  293.                 $message = str_replace("\r\n", "\n", $message);
  294.                 $message = str_replace("\n", "\r\n", $message);
  295.                 $message = str_replace("\r\n.\r\n", "\r\n..\r\n", $message);
  296.                 fputs($conn, $message);
  297.                 fputs($conn, "\r\n.\r\n");
  298.                 
  299.                 return smtp_check_reply(fgets($conn, 1024));
  300.             }
  301.         }
  302.         
  303.         return false;
  304.     }
  305.  
  306.     
  307.     function smtp_ExplodeQuotedString($delimiter, $string){
  308.         $quotes=explode("\"", $string);
  309.         while ( list($key, $val) = each($quotes))
  310.             if (($key % 2) == 1) 
  311.                 $quotes[$key] = str_replace($delimiter, "_!@!_", $quotes[$key]);
  312.         $string=implode("\"", $quotes);
  313.     
  314.         $result=explode($delimiter, $string);
  315.         while ( list($key, $val) = each($result) )
  316.             $result[$key] = str_replace("_!@!_", $delimiter, $result[$key]);
  317.     
  318.         return $result;
  319.     }    
  320.     
  321.     
  322.     function smtp_expand($str){
  323.         $addresses = array();
  324.         $recipients = smtp_ExplodeQuotedString(",", $str);
  325.         reset($recipients);
  326.         while ( list($k, $recipient) = each($recipients) ){
  327.             $a = explode(" ", $recipient);
  328.             while ( list($k2, $word) = each($a) ){
  329.                 if ((strpos($word, "@") > 0) && (strpos($word, "\"")===false)){
  330.                     if (!ereg("^<", $word)) $word = "<".$word;
  331.                     if (!ereg(">$", $word)) $word = $word.">";
  332.                     if (in_array($word, $addresses)===false) array_push($addresses, $word);
  333.                 }
  334.             }
  335.         }
  336.         return $addresses;
  337.     }
  338. ?>