NobuNobu
nobun****@users*****
2006年 4月 11日 (火) 22:04:04 JST
Index: xoops2jp/html/class/mail/phpmailer/ChangeLog.txt diff -u xoops2jp/html/class/mail/phpmailer/ChangeLog.txt:1.1 xoops2jp/html/class/mail/phpmailer/ChangeLog.txt:1.1.16.1 --- xoops2jp/html/class/mail/phpmailer/ChangeLog.txt:1.1 Thu Sep 9 14:14:50 2004 +++ xoops2jp/html/class/mail/phpmailer/ChangeLog.txt Tue Apr 11 22:04:03 2006 @@ -1,5 +1,35 @@ ChangeLog +Version 1.73 (Sun, Jun 10 2005) +* Fixed denial of service bug: http://www.cybsec.com/vuln/PHPMailer-DOS.pdf +* Now has a total of 20 translations +* Fixed alt attachments bug: http://tinyurl.com/98u9k + +Version 1.72 (Wed, May 25 2004) +* Added Dutch, Swedish, Czech, Norwegian, and Turkish translations. +* Received: Removed this method because spam filter programs like +SpamAssassin reject this header. +* Fixed error count bug. +* SetLanguage default is now "language/". +* Fixed magic_quotes_runtime bug. + +Version 1.71 (Tue, Jul 28 2003) +* Made several speed enhancements +* Added German and Italian translation files +* Fixed HELO/AUTH bugs on keep-alive connects +* Now provides an error message if language file does not load +* Fixed attachment EOL bug +* Updated some unclear documentation +* Added additional tests and improved others + +Version 1.70 (Mon, Jun 20 2003) +* Added SMTP keep-alive support +* Added IsError method for error detection +* Added error message translation support (SetLanguage) +* Refactored many methods to increase library performance +* Hello now sends the newer EHLO message before HELO as per RFC 2821 +* Removed the boundary class and replaced it with GetBoundary +* Removed queue support methods * New $Hostname variable * New Message-ID header * Received header reformat @@ -10,6 +40,7 @@ * quoted-encoding should now encode NULs \000 * Fixed encoding of body/AltBody (#553370) * Adds "To: undisclosed-recipients:;" when all recipients are hidden (BCC) +* Multiple bug fixes Version 1.65 (Fri, Aug 09 2002) * Fixed non-visible attachment bug (#585097) for Outlook Index: xoops2jp/html/class/mail/phpmailer/README diff -u xoops2jp/html/class/mail/phpmailer/README:1.1 xoops2jp/html/class/mail/phpmailer/README:1.1.16.1 --- xoops2jp/html/class/mail/phpmailer/README:1.1 Thu Sep 9 14:14:50 2004 +++ xoops2jp/html/class/mail/phpmailer/README Tue Apr 11 22:04:03 2006 @@ -1,9 +1,11 @@ -phpmailer - PHP email class -============================== -http://phpmailer.sourceforge.net +PHPMailer +Full Featured Email Transfer Class for PHP +========================================== -Please read LICENSE for information on this softwares availability and -distribution. +http://phpmailer.sourceforge.net/ + +This software is licenced under the LGPL. Please read LICENSE for information on the +software availability and distribution. Class Features: - Send emails with multiple TOs, CCs, BCCs and REPLY-TOs @@ -12,8 +14,8 @@ - Support for 8bit, base64, binary, and quoted-printable encoding - Uses the same methods as the very popular AspEmail active server (COM) component - SMTP authentication -- Word wrap -- Many more... +- Native language support +- Word wrap, and more! Why you might need it: @@ -37,19 +39,34 @@ Copy class.phpmailer.php into your php.ini include_path. If you are using the SMTP mailer then place class.smtp.php in your path as well. +In the language directory you will find several files like +phpmailer.lang-en.php. If you look right before the .php extension +that there are two letters. These represent the language type of the +translation file. For instance "en" is the English file and "br" is +the Portuguese file. Chose the file that best fits with your language +and place it in the PHP include path. If your language is English +then you have nothing more to do. If it is a different language then +you must point PHPMailer to the correct translation. To do this, call +the PHPMailer SetLanguage method like so: + +// To load the Portuguese version +$mail->SetLanguage("br", "/optional/path/to/language/directory/"); + +That's it. You should now be ready to use PHPMailer! + -Example +A Simple Example: <?php require("class.phpmailer.php"); -$mail = new phpmailer(); +$mail = new PHPMailer(); $mail->IsSMTP(); // set mailer to use SMTP $mail->Host = "smtp1.example.com;smtp2.example.com"; // specify main and backup server -$mail->SMTPAuth = true // turn on SMTP authentication -$mail->Username = "jswan" // SMTP username -$mail->Password = "secret" // SMTP password +$mail->SMTPAuth = true; // turn on SMTP authentication +$mail->Username = "jswan"; // SMTP username +$mail->Password = "secret"; // SMTP password $mail->From = "from****@examp*****"; $mail->FromName = "Mailer"; @@ -82,4 +99,4 @@ Download: http://sourceforge.net/project/showfiles.php?group_id=26031 -Brent R. Matzelle <bmatz****@yahoo*****> +Brent R. Matzelle Index: xoops2jp/html/class/mail/phpmailer/class.phpmailer.php diff -u xoops2jp/html/class/mail/phpmailer/class.phpmailer.php:1.1 xoops2jp/html/class/mail/phpmailer/class.phpmailer.php:1.1.16.1 --- xoops2jp/html/class/mail/phpmailer/class.phpmailer.php:1.1 Thu Sep 9 14:14:50 2004 +++ xoops2jp/html/class/mail/phpmailer/class.phpmailer.php Tue Apr 11 22:04:03 2006 @@ -1,23 +1,23 @@ <?php //////////////////////////////////////////////////// -// phpmailer - PHP email class -// -// Version 1.65, Created 08/09/2002 +// PHPMailer - PHP email class // // Class for sending email using either // sendmail, PHP mail(), or SMTP. Methods are // based upon the standard AspEmail(tm) classes. // -// Author: Brent R. Matzelle <bmatz****@yahoo*****> +// Copyright (C) 2001 - 2003 Brent R. Matzelle // // License: LGPL, see LICENSE //////////////////////////////////////////////////// /** - * phpmailer - PHP email transport class + * PHPMailer - PHP email transport class + * @package PHPMailer * @author Brent R. Matzelle + * @copyright 2001 - 2003 Brent R. Matzelle */ -class phpmailer +class PHPMailer { ///////////////////////////////////////////////// // PUBLIC VARIABLES @@ -25,21 +25,18 @@ /** * Email priority (1 = High, 3 = Normal, 5 = low). - * @access public * @var int */ var $Priority = 3; /** * Sets the CharSet of the message. - * @access public * @var string */ var $CharSet = "iso-8859-1"; /** * Sets the Content-type of the message. - * @access public * @var string */ var $ContentType = "text/plain"; @@ -47,43 +44,37 @@ /** * Sets the Encoding of the message. Options for this are "8bit", * "7bit", "binary", "base64", and "quoted-printable". - * @access public * @var string */ var $Encoding = "8bit"; /** * Holds the most recent mailer error message. - * @access public * @var string */ var $ErrorInfo = ""; /** * Sets the From email address for the message. - * @access public * @var string */ var $From = "root @ localhost"; /** * Sets the From name of the message. - * @access public * @var string */ var $FromName = "Root User"; /** - * Sets the Sender email of the message. If not empty, will be sent via -f to sendmail - * or as 'MAIL FROM' in smtp mode. - * @access public + * Sets the Sender email (Return-Path) of the message. If not empty, + * will be sent via -f to sendmail or as 'MAIL FROM' in smtp mode. * @var string */ var $Sender = ""; /** * Sets the Subject of the message. - * @access public * @var string */ var $Subject = ""; @@ -91,7 +82,6 @@ /** * Sets the Body of the message. This can be either an HTML or text body. * If HTML then run IsHTML(true). - * @access public * @var string */ var $Body = ""; @@ -101,7 +91,6 @@ * email to multipart/alternative. This body can be read by mail * clients that do not have HTML email capability such as mutt. Clients * that can read HTML will view the normal Body. - * @access public * @var string */ var $AltBody = ""; @@ -109,72 +98,49 @@ /** * Sets word wrapping on the body of the message to a given number of * characters. - * @access public * @var int */ var $WordWrap = 0; /** * Method to send mail: ("mail", "sendmail", or "smtp"). - * @access public * @var string */ var $Mailer = "mail"; /** * Sets the path of the sendmail program. - * @access public * @var string */ var $Sendmail = "/usr/sbin/sendmail"; - - /** - * Turns Microsoft mail client headers on and off. Useful mostly - * for older clients. - * @access public - * @var bool - */ - var $UseMSMailHeaders = false; /** - * Path to phpmailer plugins. This is now only useful if the SMTP class + * Path to PHPMailer plugins. This is now only useful if the SMTP class * is in a different directory than the PHP include path. - * @access public * @var string */ var $PluginDir = ""; /** - * Holds phpmailer version. - * @access public + * Holds PHPMailer version. * @var string */ - var $Version = "1.65"; + var $Version = "1.73"; /** * Sets the email address that a reading confirmation will be sent. - * @access public * @var string */ var $ConfirmReadingTo = ""; /** - * Sets the line endings of the message. - * @access public - * @var string - */ - var $LE = "\n"; - - /** * Sets the hostname to use in Message-Id and Received headers * and as default HELO string. If empty, the value returned * by SERVER_NAME is used or 'localhost.localdomain'. - * @access public * @var string */ var $Hostname = ""; - ///////////////////////////////////////////////// // SMTP VARIABLES ///////////////////////////////////////////////// @@ -185,42 +151,36 @@ * for each host by using this format: [hostname:port] * (e.g. "smtp1.example.com:25;smtp2.example.com"). * Hosts will be tried in order. - * @access public * @var string */ var $Host = "localhost"; /** * Sets the default SMTP server port. - * @access public * @var int */ var $Port = 25; /** * Sets the SMTP HELO of the message (Default is $Hostname). - * @access public * @var string */ var $Helo = ""; /** * Sets SMTP authentication. Utilizes the Username and Password variables. - * @access public * @var bool */ var $SMTPAuth = false; /** * Sets SMTP username. - * @access public * @var string */ var $Username = ""; /** * Sets SMTP password. - * @access public * @var string */ var $Password = ""; @@ -228,83 +188,48 @@ /** * Sets the SMTP server timeout in seconds. This function will not * work with the win32 version. - * @access public * @var int */ var $Timeout = 10; /** * Sets SMTP class debugging on or off. - * @access public * @var bool */ var $SMTPDebug = false; - - ///////////////////////////////////////////////// - // PRIVATE VARIABLES - ///////////////////////////////////////////////// - /** - * Holds all "To" addresses. - * @access private - * @var array + * Prevents the SMTP connection from being closed after each mail + * sending. If this is set to true then to close the connection + * requires an explicit call to SmtpClose(). + * @var bool */ - var $to = array(); + var $SMTPKeepAlive = false; - /** - * Holds all "CC" addresses. - * @access private - * @var array + /**#@+ + * @access private */ + var $smtp = NULL; + var $to = array(); var $cc = array(); - - /** - * Holds all "BCC" addresses. - * @access private - * @var array - */ var $bcc = array(); - - /** - * Holds all "Reply-To" addresses. - * @var array - */ var $ReplyTo = array(); - - /** - * Holds all string and binary attachments. - * @access private - * @var array - */ var $attachment = array(); - - /** - * Holds all custom headers. - * @var array - */ var $CustomHeader = array(); - - /** - * Holds the type of the message. - * @var string - */ var $message_type = ""; - - /** - * Holds the message boundaries. - * @access private - * @var string array - */ var $boundary = array(); - + var $language = array(); + var $error_count = 0; + var $LE = "\n"; + /**#@-*/ + ///////////////////////////////////////////////// // VARIABLE METHODS ///////////////////////////////////////////////// /** - * Sets message type to HTML. Returns void. - * @access public + * Sets message type to HTML. + * @param bool $bool * @return void */ function IsHTML($bool) { @@ -316,8 +241,6 @@ /** * Sets Mailer to send message using SMTP. - * Returns void. - * @access public * @return void */ function IsSMTP() { @@ -326,8 +249,6 @@ /** * Sets Mailer to send message using PHP mail() function. - * Returns void. - * @access public * @return void */ function IsMail() { @@ -336,8 +257,6 @@ /** * Sets Mailer to send message using the $Sendmail program. - * Returns void. - * @access public * @return void */ function IsSendmail() { @@ -345,12 +264,10 @@ } /** - * Sets Mailer to send message using the qmail MTA. Returns void. - * @access public + * Sets Mailer to send message using the qmail MTA. * @return void */ function IsQmail() { - //$this->Sendmail = "/var/qmail/bin/qmail-inject"; $this->Sendmail = "/var/qmail/bin/sendmail"; $this->Mailer = "sendmail"; } @@ -361,8 +278,9 @@ ///////////////////////////////////////////////// /** - * Adds a "To" address. Returns void. - * @access public + * Adds a "To" address. + * @param string $address + * @param string $name * @return void */ function AddAddress($address, $name = "") { @@ -374,10 +292,9 @@ /** * Adds a "Cc" address. Note: this function works * with the SMTP mailer on win32, not with the "mail" - * mailer. This is a PHP bug that has been submitted - * on http://bugs.php.net. The *NIX version of PHP - * functions correctly. Returns void. - * @access public + * mailer. + * @param string $address + * @param string $name * @return void */ function AddCC($address, $name = "") { @@ -389,11 +306,9 @@ /** * Adds a "Bcc" address. Note: this function works * with the SMTP mailer on win32, not with the "mail" - * mailer. This is a PHP bug that has been submitted - * on http://bugs.php.net. The *NIX version of PHP - * functions correctly. - * Returns void. - * @access public + * mailer. + * @param string $address + * @param string $name * @return void */ function AddBCC($address, $name = "") { @@ -403,8 +318,9 @@ } /** - * Adds a "Reply-to" address. Returns void. - * @access public + * Adds a "Reply-to" address. + * @param string $address + * @param string $name * @return void */ function AddReplyTo($address, $name = "") { @@ -421,17 +337,17 @@ /** * Creates message and assigns Mailer. If the message is * not sent successfully then it returns false. Use the ErrorInfo - * variable to view description of the error. Returns bool. - * @access public + * variable to view description of the error. * @return bool */ function Send() { $header = ""; $body = ""; + $result = true; if((count($this->to) + count($this->cc) + count($this->bcc)) < 1) { - $this->error_handler("You must provide at least one recipient email address"); + $this->SetError($this->Lang("provide_address")); return false; } @@ -439,153 +355,40 @@ if(!empty($this->AltBody)) $this->ContentType = "multipart/alternative"; - // Attach sender information & date - $header = $this->received(); - $header .= sprintf("Date: %s%s", $this->rfc_date(), $this->LE); - $header .= $this->create_header(); - - if(!$body = $this->create_body()) - return false; + $this->error_count = 0; // reset errors + $this->SetMessageType(); + $header .= $this->CreateHeader(); + $body = $this->CreateBody(); - //echo "<pre>".$header . $body . "</pre>"; // debugging + if($body == "") { return false; } // Choose the mailer - if($this->Mailer == "sendmail") - { - if(!$this->sendmail_send($header, $body)) - return false; - } - elseif($this->Mailer == "mail") - { - if(!$this->mail_send($header, $body)) - return false; - } - elseif($this->Mailer == "smtp") + switch($this->Mailer) { - if(!$this->smtp_send($header, $body)) - return false; - } - else - { - $this->error_handler(sprintf("%s mailer is not supported", $this->Mailer)); - return false; + case "sendmail": + $result = $this->SendmailSend($header, $body); + break; + case "mail": + $result = $this->MailSend($header, $body); + break; + case "smtp": + $result = $this->SmtpSend($header, $body); + break; + default: + $this->SetError($this->Mailer . $this->Lang("mailer_not_supported")); + $result = false; + break; } - return true; + return $result; } /** - * Sends mail message to an assigned queue directory. Has an optional - * sendTime argument. This is used when the user wants the - * message to be sent from the queue at a predetermined time. - * The data must be a valid timestamp like that returned from - * the time() or strtotime() functions. Returns false on failure - * or the message file name if success. - * @access public - * @return string - */ - function SendToQueue($queue_path, $send_time = 0) { - $message = array(); - $header = ""; - $body = ""; - - // If invalid or empty just set to the current time - if($send_time == 0) - $send_time = time(); - - if(!is_dir($queue_path)) - { - $this->error_handler("The supplied queue directory does not exist"); - return false; - } - - if((count($this->to) + count($this->cc) + count($this->bcc)) < 1) - { - $this->error_handler("You must provide at least one recipient email address"); - return false; - } - - // Set whether the message is multipart/alternative - if(!empty($this->AltBody)) - $this->ContentType = "multipart/alternative"; - - $header = $this->create_header(); - if(!$body = $this->create_body()) - return false; - - // Seed randomizer - mt_srand(time()); - $msg_id = md5(uniqid(mt_rand())); - - $fp = @fopen($queue_path . $msg_id . ".pqm", "wb"); - if(!$fp) - { - $this->error_handler(sprintf("Could not write to %s directory", $queue_path)); - return false; - } - - $message[] = sprintf("----START PQM HEADER----%s", $this->LE); - $message[] = sprintf("SendTime: %s%s", $send_time, $this->LE); - $message[] = sprintf("Mailer: %s%s", $this->Mailer, $this->LE); - - // Choose the mailer - if($this->Mailer == "sendmail") - { - $message[] = sprintf("Sendmail: %s%s", $this->Sendmail, $this->LE); - $message[] = sprintf("Sender: %s%s", $this->Sender, $this->LE); - } - elseif($this->Mailer == "mail") - { - $message[] = sprintf("Sender: %s%s", $this->Sender, $this->LE); - $message[] = sprintf("Subject: %s%s", $this->Subject, $this->LE); - $message[] = sprintf("to: %s%s", $this->addr_list($this->to), $this->LE); - } - elseif($this->Mailer == "smtp") - { - $message[] = sprintf("Host: %s%s", $this->Host, $this->LE); - $message[] = sprintf("Port: %d%s", $this->Port, $this->LE); - $message[] = sprintf("Helo: %s%s", $this->Helo, $this->LE); - $message[] = sprintf("Timeout: %d%s", $this->Timeout, $this->LE); - - if($this->SMTPAuth) - $auth_no = 1; - else - $auth_no = 0; - $message[] = sprintf("SMTPAuth: %d%s", $auth_no, $this->LE); - $message[] = sprintf("Username: %s%s", $this->Username, $this->LE); - $message[] = sprintf("Password: %s%s", $this->Password, $this->LE); - $message[] = sprintf("From: %s%s", $this->From, $this->LE); - - $message[] = sprintf("to: %s%s", $this->addr_list($this->to), $this->LE); - $message[] = sprintf("cc: %s%s", $this->addr_list($this->cc), $this->LE); - $message[] = sprintf("bcc: %s%s", $this->addr_list($this->bcc), $this->LE); - } - else - { - $this->error_handler(sprintf("%s mailer is not supported", $this->Mailer)); - return false; - } - - $message[] = sprintf("----END PQM HEADER----%s", $this->LE); // end of pqm header - $message[] = $header; - $message[] = $body; - - if(fwrite($fp, join("", $message)) == -1) - { - $this->error_handler("Write to file failed"); - return false; - } - fclose($fp); - - return ($msg_id . ".pqm"); - } - - /** - * Sends mail using the $Sendmail program. Returns bool. + * Sends mail using the $Sendmail program. * @access private * @return bool */ - function sendmail_send($header, $body) { + function SendmailSend($header, $body) { if ($this->Sender != "") $sendmail = sprintf("%s -oi -f %s -t", $this->Sendmail, $this->Sender); else @@ -593,7 +396,7 @@ if(!@$mail = popen($sendmail, "w")) { - $this->error_handler(sprintf("Could not execute %s", $this->Sendmail)); + $this->SetError($this->Lang("execute") . $this->Sendmail); return false; } @@ -603,7 +406,7 @@ $result = pclose($mail) >> 8 & 0xFF; if($result != 0) { - $this->error_handler(sprintf("Could not execute %s", $this->Sendmail)); + $this->SetError($this->Lang("execute") . $this->Sendmail); return false; } @@ -611,41 +414,35 @@ } /** - * Sends mail using the PHP mail() function. Returns bool. + * Sends mail using the PHP mail() function. * @access private * @return bool */ - function mail_send($header, $body) { - //$to = substr($this->addr_append("To", $this->to), 4, -2); - - // Cannot add Bcc's to the $to - $to = $this->to[0][0]; // no extra comma - for($i = 1; $i < count($this->to); $i++) - $to .= sprintf(",%s", $this->to[$i][0]); - - if ($this->Sender != "" && PHP_VERSION >= "4.0") + function MailSend($header, $body) { + $to = ""; + for($i = 0; $i < count($this->to); $i++) { - $old_from = ini_get("sendmail_from"); - ini_set("sendmail_from", $this->Sender); + if($i != 0) { $to .= ", "; } + $to .= $this->to[$i][0]; } - if ($this->Sender != "" && PHP_VERSION >= "4.0.5") + if ($this->Sender != "" && strlen(ini_get("safe_mode"))< 1) { - // The fifth parameter to mail is only available in PHP >= 4.0.5 + $old_from = ini_get("sendmail_from"); + ini_set("sendmail_from", $this->Sender); $params = sprintf("-oi -f %s", $this->Sender); - $rt = @mail($to, $this->encode_header($this->Subject), $body, $header, $params); + $rt = @mail($to, $this->EncodeHeader($this->Subject), $body, + $header, $params); } else - { - $rt = @mail($to, $this->encode_header($this->Subject), $body, $header); - } + $rt = @mail($to, $this->EncodeHeader($this->Subject), $body, $header); if (isset($old_from)) ini_set("sendmail_from", $old_from); if(!$rt) { - $this->error_handler("Could not instantiate mail()"); + $this->SetError($this->Lang("instantiate")); return false; } @@ -659,158 +456,178 @@ * @access private * @return bool */ - function smtp_send($header, $body) { - // Include SMTP class code, but not twice + function SmtpSend($header, $body) { include_once($this->PluginDir . "class.smtp.php"); - - $smtp = new SMTP; - - $smtp->do_debug = $this->SMTPDebug; - - // Try to connect to all SMTP servers - $hosts = explode(";", $this->Host); - $index = 0; - $connection = false; - $smtp_from = ""; + $error = ""; $bad_rcpt = array(); - $e = ""; - // Retry while there is no connection - while($index < count($hosts) && $connection == false) - { - if(strstr($hosts[$index], ":")) - list($host, $port) = explode(":", $hosts[$index]); - else - { - $host = $hosts[$index]; - $port = $this->Port; - } - - if($smtp->Connect($host, $port, $this->Timeout)) - $connection = true; - //printf("%s host could not connect<br>", $hosts[$index]); //debug only - $index++; - } - if(!$connection) - { - $this->error_handler("SMTP Error: could not connect to SMTP host server(s)"); + if(!$this->SmtpConnect()) return false; - } - - // Must perform HELO before authentication - if ($this->Helo != '') - $smtp->Hello($this->Helo); - else - $smtp->Hello($this->get_server_hostname()); - - // If user requests SMTP authentication - if($this->SMTPAuth) - { - if(!$smtp->Authenticate($this->Username, $this->Password)) - { - $this->error_handler("SMTP Error: Could not authenticate"); - return false; - } - } - if ($this->Sender == "") - $smtp_from = $this->From; - else - $smtp_from = $this->Sender; - - if(!$smtp->Mail(sprintf("<%s>", $smtp_from))) + $smtp_from = ($this->Sender == "") ? $this->From : $this->Sender; + if(!$this->smtp->Mail($smtp_from)) { - $e = sprintf("SMTP Error: From address [%s] failed", $smtp_from); - $this->error_handler($e); + $error = $this->Lang("from_failed") . $smtp_from; + $this->SetError($error); + $this->smtp->Reset(); return false; } // Attempt to send attach all recipients for($i = 0; $i < count($this->to); $i++) { - if(!$smtp->Recipient(sprintf("<%s>", $this->to[$i][0]))) + if(!$this->smtp->Recipient($this->to[$i][0])) $bad_rcpt[] = $this->to[$i][0]; } for($i = 0; $i < count($this->cc); $i++) { - if(!$smtp->Recipient(sprintf("<%s>", $this->cc[$i][0]))) + if(!$this->smtp->Recipient($this->cc[$i][0])) $bad_rcpt[] = $this->cc[$i][0]; } for($i = 0; $i < count($this->bcc); $i++) { - if(!$smtp->Recipient(sprintf("<%s>", $this->bcc[$i][0]))) + if(!$this->smtp->Recipient($this->bcc[$i][0])) $bad_rcpt[] = $this->bcc[$i][0]; } - // Create error message - if(count($bad_rcpt) > 0) + if(count($bad_rcpt) > 0) // Create error message { for($i = 0; $i < count($bad_rcpt); $i++) { - if($i != 0) - $e .= ", "; - $e .= $bad_rcpt[$i]; + if($i != 0) { $error .= ", "; } + $error .= $bad_rcpt[$i]; } - $e = sprintf("SMTP Error: The following recipients failed [%s]", $e); - $this->error_handler($e); - + $error = $this->Lang("recipients_failed") . $error; + $this->SetError($error); + $this->smtp->Reset(); return false; } - - if(!$smtp->Data(sprintf("%s%s", $header, $body))) + if(!$this->smtp->Data($header . $body)) { - $this->error_handler("SMTP Error: Data not accepted"); + $this->SetError($this->Lang("data_not_accepted")); + $this->smtp->Reset(); return false; } - $smtp->Quit(); - $smtp->Close(); + if($this->SMTPKeepAlive == true) + $this->smtp->Reset(); + else + $this->SmtpClose(); return true; } - - ///////////////////////////////////////////////// - // MESSAGE CREATION METHODS - ///////////////////////////////////////////////// - /** - * Creates recipient headers. Returns string. + * Initiates a connection to an SMTP server. Returns false if the + * operation failed. * @access private - * @return string + * @return bool */ - function addr_append($type, $addr) { - $addr_str = $type . ": "; - $addr_str .= $this->addr_format($addr[0]); - if(count($addr) > 1) + function SmtpConnect() { + if($this->smtp == NULL) { $this->smtp = new SMTP(); } + + $this->smtp->do_debug = $this->SMTPDebug; + $hosts = explode(";", $this->Host); + $index = 0; + $connection = ($this->smtp->Connected()); + + // Retry while there is no connection + while($index < count($hosts) && $connection == false) { - for($i = 1; $i < count($addr); $i++) + if(strstr($hosts[$index], ":")) + list($host, $port) = explode(":", $hosts[$index]); + else + { + $host = $hosts[$index]; + $port = $this->Port; + } + + if($this->smtp->Connect($host, $port, $this->Timeout)) { - $addr_str .= sprintf(", %s", $this->addr_format($addr[$i])); + if ($this->Helo != '') + $this->smtp->Hello($this->Helo); + else + $this->smtp->Hello($this->ServerHostname()); + + if($this->SMTPAuth) + { + if(!$this->smtp->Authenticate($this->Username, + $this->Password)) + { + $this->SetError($this->Lang("authenticate")); + $this->smtp->Reset(); + $connection = false; + } + } + $connection = true; } - $addr_str .= $this->LE; + $index++; } - else - $addr_str .= $this->LE; + if(!$connection) + $this->SetError($this->Lang("connect_host")); - return($addr_str); + return $connection; + } + + /** + * Closes the active SMTP session if one exists. + * @return void + */ + function SmtpClose() { + if($this->smtp != NULL) + { + if($this->smtp->Connected()) + { + $this->smtp->Quit(); + $this->smtp->Close(); + } + } } + + /** + * Sets the language for all class error messages. Returns false + * if it cannot load the language file. The default language type + * is English. + * @param string $lang_type Type of language (e.g. Portuguese: "br") + * @param string $lang_path Path to the language file directory + * @access public + * @return bool + */ + function SetLanguage($lang_type, $lang_path = "language/") { + if(file_exists($lang_path.'phpmailer.lang-'.$lang_type.'.php')) + include($lang_path.'phpmailer.lang-'.$lang_type.'.php'); + else if(file_exists($lang_path.'phpmailer.lang-en.php')) + include($lang_path.'phpmailer.lang-en.php'); + else + { + $this->SetError("Could not load language file"); + return false; + } + $this->language = $PHPMAILER_LANG; + return true; + } + + ///////////////////////////////////////////////// + // MESSAGE CREATION METHODS + ///////////////////////////////////////////////// + /** - * Creates a semicolon delimited list for use in pqm files. + * Creates recipient headers. * @access private * @return string */ - function addr_list($list_array) { - $addr_list = ""; - for($i = 0; $i < count($list_array); $i++) - { - if($i > 0) - $addr_list .= ";"; - $addr_list .= $list_array[$i][0]; + function AddrAppend($type, $addr) { + $addr_str = $type . ": "; + $addr_str .= $this->AddrFormat($addr[0]); + if(count($addr) > 1) + { + for($i = 1; $i < count($addr); $i++) + $addr_str .= ", " . $this->AddrFormat($addr[$i]); } - - return $addr_list; + $addr_str .= $this->LE; + + return $addr_str; } /** @@ -818,11 +635,14 @@ * @access private * @return string */ - function addr_format($addr) { + function AddrFormat($addr) { if(empty($addr[1])) $formatted = $addr[0]; else - $formatted = sprintf('%s <%s>', $this->encode_header($addr[1], 'phrase'), $addr[0]); + { + $formatted = $this->EncodeHeader($addr[1], 'phrase') . " <" . + $addr[0] . ">"; + } return $formatted; } @@ -830,19 +650,16 @@ /** * Wraps message for use with mailers that do not * automatically perform wrapping and for quoted-printable. - * Original written by philippe. Returns string. + * Original written by philippe. * @access private * @return string */ - function word_wrap($message, $length, $qp_mode = false) { - if ($qp_mode) - $soft_break = sprintf(" =%s", $this->LE); - else - $soft_break = $this->LE; + function WrapText($message, $length, $qp_mode = false) { + $soft_break = ($qp_mode) ? sprintf(" =%s", $this->LE) : $this->LE; - $message = $this->fix_eol($message); + $message = $this->FixEOL($message); if (substr($message, -1) == $this->LE) - $message = substr($message, 0, -1); + $message = substr($message, 0, -1); $line = explode($this->LE, $message); $message = ""; @@ -895,10 +712,8 @@ else { $buf_o = $buf; - if ($e == 0) - $buf .= $word; - else - $buf .= " " . $word; + $buf .= ($e == 0) ? $word : (" " . $word); + if (strlen($buf) > $length and $buf_o != "") { $message .= $buf_o . $soft_break; @@ -909,7 +724,7 @@ $message .= $buf . $this->LE; } - return ($message); + return $message; } /** @@ -924,218 +739,245 @@ switch($this->message_type) { case "alt": - case "alt_attachment": - $this->AltBody = $this->word_wrap($this->AltBody, $this->WordWrap); + // fall through + case "alt_attachments": + $this->AltBody = $this->WrapText($this->AltBody, $this->WordWrap); break; default: - $this->Body = $this->word_wrap($this->Body, $this->WordWrap); + $this->Body = $this->WrapText($this->Body, $this->WordWrap); break; } } /** - * Assembles message header. Returns a string if successful - * or false if unsuccessful. + * Assembles message header. * @access private * @return string */ - function create_header() { - $header = array(); + function CreateHeader() { + $result = ""; // Set the boundaries $uniq_id = md5(uniqid(time())); $this->boundary[1] = "b1_" . $uniq_id; $this->boundary[2] = "b2_" . $uniq_id; + $result .= $this->HeaderLine("Date", $this->RFCDate()); + if($this->Sender == "") + $result .= $this->HeaderLine("Return-Path", trim($this->From)); + else + $result .= $this->HeaderLine("Return-Path", trim($this->Sender)); + // To be created automatically by mail() if($this->Mailer != "mail") { if(count($this->to) > 0) - $header[] = $this->addr_append("To", $this->to); + $result .= $this->AddrAppend("To", $this->to); else if (count($this->cc) == 0) - $header[] = "To: undisclosed-recipients:;".$this->LE; + $result .= $this->HeaderLine("To", "undisclosed-recipients:;"); + if(count($this->cc) > 0) + $result .= $this->AddrAppend("Cc", $this->cc); } $from = array(); $from[0][0] = trim($this->From); $from[0][1] = $this->FromName; - $header[] = $this->addr_append("From", $from); - - if(count($this->cc) > 0) - $header[] = $this->addr_append("Cc", $this->cc); + $result .= $this->AddrAppend("From", $from); // sendmail and mail() extract Bcc from the header before sending if((($this->Mailer == "sendmail") || ($this->Mailer == "mail")) && (count($this->bcc) > 0)) - $header[] = $this->addr_append("Bcc", $this->bcc); + $result .= $this->AddrAppend("Bcc", $this->bcc); if(count($this->ReplyTo) > 0) - $header[] = $this->addr_append("Reply-to", $this->ReplyTo); + $result .= $this->AddrAppend("Reply-to", $this->ReplyTo); // mail() sets the subject itself if($this->Mailer != "mail") - $header[] = sprintf("Subject: %s%s", $this->encode_header(trim($this->Subject)), $this->LE); + $result .= $this->HeaderLine("Subject", $this->EncodeHeader(trim($this->Subject))); - $header[] = sprintf("Message-ID: <%s@%s>%s", $uniq_id, $this->get_server_hostname(), $this->LE); - $header[] = sprintf("X-Priority: %d%s", $this->Priority, $this->LE); - $header[] = sprintf("X-Mailer: phpmailer [version %s]%s", $this->Version, $this->LE); - if($this->Sender == "") - $header[] = sprintf("Return-Path: %s%s", trim($this->From), $this->LE); - else - $header[] = sprintf("Return-Path: %s%s", trim($this->Sender), $this->LE); + $result .= sprintf("Message-ID: <%s@%s>%s", $uniq_id, $this->ServerHostname(), $this->LE); + $result .= $this->HeaderLine("X-Priority", $this->Priority); + $result .= $this->HeaderLine("X-Mailer", "PHPMailer [version " . $this->Version . "]"); if($this->ConfirmReadingTo != "") - $header[] = sprintf("Disposition-Notification-To: <%s>%s", - trim($this->ConfirmReadingTo), $this->LE); + { + $result .= $this->HeaderLine("Disposition-Notification-To", + "<" . trim($this->ConfirmReadingTo) . ">"); + } // Add custom headers for($index = 0; $index < count($this->CustomHeader); $index++) - $header[] = sprintf("%s: %s%s", trim($this->CustomHeader[$index][0]), $this->encode_header(trim($this->CustomHeader[$index][1])), $this->LE); - - if($this->UseMSMailHeaders) - $header[] = $this->AddMSMailHeaders(); - - $header[] = sprintf("MIME-Version: 1.0%s", $this->LE); - - // Determine what type of message this is - if(count($this->attachment) < 1 && strlen($this->AltBody) < 1) - $this->message_type = "plain"; - else { - if(count($this->attachment) > 0) - $this->message_type = "attachments"; - if(strlen($this->AltBody) > 0 && count($this->attachment) < 1) - $this->message_type = "alt"; - if(strlen($this->AltBody) > 0 && count($this->attachment) > 0) - $this->message_type = "alt_attachments"; + $result .= $this->HeaderLine(trim($this->CustomHeader[$index][0]), + $this->EncodeHeader(trim($this->CustomHeader[$index][1]))); } - + $result .= $this->HeaderLine("MIME-Version", "1.0"); + switch($this->message_type) { case "plain": - $header[] = sprintf("Content-Transfer-Encoding: %s%s", - $this->Encoding, $this->LE); - $header[] = sprintf("Content-Type: %s; charset=\"%s\"", + $result .= $this->HeaderLine("Content-Transfer-Encoding", $this->Encoding); + $result .= sprintf("Content-Type: %s; charset=\"%s\"", $this->ContentType, $this->CharSet); break; case "attachments": + // fall through case "alt_attachments": - if($this->EmbeddedImageCount() > 0) + if($this->InlineImageExists()) { - $header[] = sprintf("Content-Type: %s;%s\ttype=\"text/html\";%s\tboundary=\"%s\"%s", + $result .= sprintf("Content-Type: %s;%s\ttype=\"text/html\";%s\tboundary=\"%s\"%s", "multipart/related", $this->LE, $this->LE, $this->boundary[1], $this->LE); } else { - $header[] = sprintf("Content-Type: %s;%s", - "multipart/mixed", $this->LE); - $header[] = sprintf("\tboundary=\"%s\"%s", $this->boundary[1], $this->LE); + $result .= $this->HeaderLine("Content-Type", "multipart/mixed;"); + $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"'); } break; case "alt": - $header[] = sprintf("Content-Type: %s;%s", - "multipart/alternative", $this->LE); - $header[] = sprintf("\tboundary=\"%s\"%s", $this->boundary[1], $this->LE); + $result .= $this->HeaderLine("Content-Type", "multipart/alternative;"); + $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"'); break; } - // No additional lines when using mail() function if($this->Mailer != "mail") - $header[] = $this->LE.$this->LE; + $result .= $this->LE.$this->LE; - return(join("", $header)); + return $result; } /** - * Assembles the message body. Returns a string if successful - * or false if unsuccessful. + * Assembles the message body. Returns an empty string on failure. * @access private * @return string */ - function create_body() { - $body = array(); + function CreateBody() { + $result = ""; $this->SetWordWrap(); switch($this->message_type) { case "alt": - // Return text of body - $bndry = new Boundary($this->boundary[1]); - $bndry->CharSet = $this->CharSet; - $bndry->Encoding = $this->Encoding; - $body[] = $bndry->GetSource(); - - $body[] = $this->encode_string($this->AltBody, $this->Encoding); - $body[] = $this->LE.$this->LE; - - $bndry = new Boundary($this->boundary[1]); - $bndry->CharSet = $this->CharSet; - $bndry->ContentType = "text/html"; - $bndry->Encoding = $this->Encoding; - $body[] = $bndry->GetSource(); + $result .= $this->GetBoundary($this->boundary[1], "", + "text/plain", ""); + $result .= $this->EncodeString($this->AltBody, $this->Encoding); + $result .= $this->LE.$this->LE; + $result .= $this->GetBoundary($this->boundary[1], "", + "text/html", ""); - $body[] = $this->encode_string($this->Body, $this->Encoding); - $body[] = $this->LE.$this->LE; + $result .= $this->EncodeString($this->Body, $this->Encoding); + $result .= $this->LE.$this->LE; - // End the boundary - $body[] = sprintf("%s--%s--%s", $this->LE, - $this->boundary[1], $this->LE.$this->LE); + $result .= $this->EndBoundary($this->boundary[1]); break; case "plain": - $body[] = $this->encode_string($this->Body, $this->Encoding); + $result .= $this->EncodeString($this->Body, $this->Encoding); break; case "attachments": - $bndry = new Boundary($this->boundary[1]); - $bndry->CharSet = $this->CharSet; - $bndry->ContentType = $this->ContentType; - $bndry->Encoding = $this->Encoding; - $body[] = $bndry->GetSource(false) . $this->LE; - $body[] = $this->encode_string($this->Body, $this->Encoding); - $body[] = $this->LE; + $result .= $this->GetBoundary($this->boundary[1], "", "", ""); + $result .= $this->EncodeString($this->Body, $this->Encoding); + $result .= $this->LE; - if(!$body[] = $this->attach_all()) - return false; + $result .= $this->AttachAll(); break; case "alt_attachments": - $body[] = sprintf("--%s%s", $this->boundary[1], $this->LE); - $body[] = sprintf("Content-Type: %s;%s" . - "\tboundary=\"%s\"%s", + $result .= sprintf("--%s%s", $this->boundary[1], $this->LE); + $result .= sprintf("Content-Type: %s;%s" . + "\tboundary=\"%s\"%s", "multipart/alternative", $this->LE, $this->boundary[2], $this->LE.$this->LE); // Create text body - $bndry = new Boundary($this->boundary[2]); - $bndry->CharSet = $this->CharSet; - $bndry->ContentType = "text/plain"; - $bndry->Encoding = $this->Encoding; - $body[] = $bndry->GetSource() . $this->LE; - - $body[] = $this->encode_string($this->AltBody, $this->Encoding); - $body[] = $this->LE.$this->LE; + $result .= $this->GetBoundary($this->boundary[2], "", + "text/plain", "") . $this->LE; + + $result .= $this->EncodeString($this->AltBody, $this->Encoding); + $result .= $this->LE.$this->LE; // Create the HTML body - $bndry = new Boundary($this->boundary[2]); - $bndry->CharSet = $this->CharSet; - $bndry->ContentType = "text/html"; - $bndry->Encoding = $this->Encoding; - $body[] = $bndry->GetSource() . $this->LE; + $result .= $this->GetBoundary($this->boundary[2], "", + "text/html", "") . $this->LE; - $body[] = $this->encode_string($this->Body, $this->Encoding); - $body[] = $this->LE.$this->LE; + $result .= $this->EncodeString($this->Body, $this->Encoding); + $result .= $this->LE.$this->LE; - $body[] = sprintf("%s--%s--%s", $this->LE, - $this->boundary[2], $this->LE.$this->LE); + $result .= $this->EndBoundary($this->boundary[2]); - if(!$body[] = $this->attach_all()) - return false; + $result .= $this->AttachAll(); break; } - $sBody = join("", $body); + if($this->IsError()) + $result = ""; - return $sBody; + return $result; } + /** + * Returns the start of a message boundary. + * @access private + */ + function GetBoundary($boundary, $charSet, $contentType, $encoding) { + $result = ""; + if($charSet == "") { $charSet = $this->CharSet; } + if($contentType == "") { $contentType = $this->ContentType; } + if($encoding == "") { $encoding = $this->Encoding; } + + $result .= $this->TextLine("--" . $boundary); + $result .= sprintf("Content-Type: %s; charset = \"%s\"", + $contentType, $charSet); + $result .= $this->LE; + $result .= $this->HeaderLine("Content-Transfer-Encoding", $encoding); + $result .= $this->LE; + + return $result; + } + + /** + * Returns the end of a message boundary. + * @access private + */ + function EndBoundary($boundary) { + return $this->LE . "--" . $boundary . "--" . $this->LE; + } + + /** + * Sets the message type. + * @access private + * @return void + */ + function SetMessageType() { + if(count($this->attachment) < 1 && strlen($this->AltBody) < 1) + $this->message_type = "plain"; + else + { + if(count($this->attachment) > 0) + $this->message_type = "attachments"; + if(strlen($this->AltBody) > 0 && count($this->attachment) < 1) + $this->message_type = "alt"; + if(strlen($this->AltBody) > 0 && count($this->attachment) > 0) + $this->message_type = "alt_attachments"; + } + } + + /** + * Returns a formatted header line. + * @access private + * @return string + */ + function HeaderLine($name, $value) { + return $name . ": " . $value . $this->LE; + } + + /** + * Returns a formatted mail line. + * @access private + * @return string + */ + function TextLine($value) { + return $value . $this->LE; + } ///////////////////////////////////////////////// // ATTACHMENT METHODS @@ -1143,17 +985,19 @@ /** * Adds an attachment from a path on the filesystem. - * Checks if attachment is valid and then adds - * the attachment to the list. * Returns false if the file could not be found * or accessed. - * @access public + * @param string $path Path to the attachment. + * @param string $name Overrides the attachment name. + * @param string $encoding File encoding (see $Encoding). + * @param string $type File extension (MIME) type. * @return bool */ - function AddAttachment($path, $name = "", $encoding = "base64", $type = "application/octet-stream") { + function AddAttachment($path, $name = "", $encoding = "base64", + $type = "application/octet-stream") { if(!@is_file($path)) { - $this->error_handler(sprintf("Could not access [%s] file", $path)); + $this->SetError($this->Lang("file_access") . $path); return false; } @@ -1161,7 +1005,6 @@ if($name == "") $name = $filename; - // Append to $attachment array $cur = count($this->attachment); $this->attachment[$cur][0] = $path; $this->attachment[$cur][1] = $filename; @@ -1177,11 +1020,11 @@ /** * Attaches all fs, string, and binary attachments to the message. - * Returns a string if successful or false if unsuccessful. + * Returns an empty string on failure. * @access private * @return string */ - function attach_all() { + function AttachAll() { // Return text of body $mime = array(); @@ -1191,13 +1034,10 @@ // Check for string attachment $bString = $this->attachment[$i][5]; if ($bString) - { $string = $this->attachment[$i][0]; - } else - { $path = $this->attachment[$i][0]; - } + $filename = $this->attachment[$i][1]; $name = $this->attachment[$i][2]; $encoding = $this->attachment[$i][3]; @@ -1218,93 +1058,92 @@ // Encode as string attachment if($bString) { - if(!$mime[] = $this->encode_string($string, $encoding)) - return false; + $mime[] = $this->EncodeString($string, $encoding); + if($this->IsError()) { return ""; } $mime[] = $this->LE.$this->LE; } else { - if(!$mime[] = $this->encode_file($path, $encoding)) - return false; + $mime[] = $this->EncodeFile($path, $encoding); + if($this->IsError()) { return ""; } $mime[] = $this->LE.$this->LE; } } $mime[] = sprintf("--%s--%s", $this->boundary[1], $this->LE); - return(join("", $mime)); + return join("", $mime); } /** - * Encodes attachment in requested format. Returns a - * string if successful or false if unsuccessful. + * Encodes attachment in requested format. Returns an + * empty string on failure. * @access private * @return string */ - function encode_file ($path, $encoding = "base64") { + function EncodeFile ($path, $encoding = "base64") { if(!@$fd = fopen($path, "rb")) { - $this->error_handler(sprintf("File Error: Could not open file %s", $path)); - return false; + $this->SetError($this->Lang("file_open") . $path); + return ""; } + $magic_quotes = get_magic_quotes_runtime(); + set_magic_quotes_runtime(0); $file_buffer = fread($fd, filesize($path)); - $file_buffer = $this->encode_string($file_buffer, $encoding); + $file_buffer = $this->EncodeString($file_buffer, $encoding); fclose($fd); + set_magic_quotes_runtime($magic_quotes); return $file_buffer; } /** - * Encodes string to requested format. Returns a - * string if successful or false if unsuccessful. + * Encodes string to requested format. Returns an + * empty string on failure. * @access private * @return string */ - function encode_string ($str, $encoding = "base64") { + function EncodeString ($str, $encoding = "base64") { + $encoded = ""; switch(strtolower($encoding)) { case "base64": // chunk_split is found in PHP >= 3.0.6 - $encoded = chunk_split(base64_encode($str)); + $encoded = chunk_split(base64_encode($str), 76, $this->LE); break; - case "7bit": case "8bit": - $encoded = $this->fix_eol($str); - if (substr($encoded, -2) != $this->LE) + $encoded = $this->FixEOL($str); + if (substr($encoded, -(strlen($this->LE))) != $this->LE) $encoded .= $this->LE; break; - case "binary": $encoded = $str; break; - case "quoted-printable": - $encoded = $this->encode_qp($str); + $encoded = $this->EncodeQP($str); break; - default: - $this->error_handler(sprintf("Unknown encoding: %s", $encoding)); - return false; + $this->SetError($this->Lang("encoding") . $encoding); + break; } - return($encoded); + return $encoded; } /** - * Encode a header string to best of Q, B, quoted or none. Returns a string. + * Encode a header string to best of Q, B, quoted or none. * @access private * @return string */ - function encode_header ($str, $position = 'text') { + function EncodeHeader ($str, $position = 'text') { $x = 0; switch (strtolower($position)) { case 'phrase': - if (preg_match_all('/[\200-\377]/', $str, $matches) == 0) { + if (!preg_match('/[\200-\377]/', $str)) { // Can't use addslashes as we don't know what value has magic_quotes_sybase. - $encoded = addcslashes($str, '\000-\037\177'); - $encoded = preg_replace('/([\"])/', '\\"', $encoded); + $encoded = addcslashes($str, "\0..\37\177\\\""); - if (($str == $encoded) && (preg_match_all('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str, $matches) == 0)) + if (($str == $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str)) return ($encoded); else return ("\"$encoded\""); @@ -1325,32 +1164,32 @@ $maxlen = 75 - 7 - strlen($this->CharSet); // Try to select the encoding which should produce the shortest output -// if (strlen($str)/3 < $x) { + if (strlen($str)/3 < $x) { $encoding = 'B'; $encoded = base64_encode($str); $maxlen -= $maxlen % 4; $encoded = trim(chunk_split($encoded, $maxlen, "\n")); -// } else { -// $encoding = 'Q'; -// $encoded = $this->encode_q($str, $position); -// $encoded = $this->word_wrap($encoded, $maxlen, true); -// $encoded = str_replace("=".$this->LE, "\n", trim($encoded)); -// } + } else { + $encoding = 'Q'; + $encoded = $this->EncodeQ($str, $position); + $encoded = $this->WrapText($encoded, $maxlen, true); + $encoded = str_replace("=".$this->LE, "\n", trim($encoded)); + } $encoded = preg_replace('/^(.*)$/m', " =?".$this->CharSet."?$encoding?\\1?=", $encoded); $encoded = trim(str_replace("\n", $this->LE, $encoded)); - return($encoded); + return $encoded; } /** - * Encode string to quoted-printable. Returns a string. + * Encode string to quoted-printable. * @access private * @return string */ - function encode_qp ($str) { - $encoded = $this->fix_eol($str); - if (substr($encoded, -2) != $this->LE) + function EncodeQP ($str) { + $encoded = $this->FixEOL($str); + if (substr($encoded, -(strlen($this->LE))) != $this->LE) $encoded .= $this->LE; // Replace every high ascii, control and = characters @@ -1361,28 +1200,27 @@ "'='.sprintf('%02X', ord('\\1')).'".$this->LE."'", $encoded); // Maximum line length of 76 characters before CRLF (74 + space + '=') - $encoded = $this->word_wrap($encoded, 74, true); + $encoded = $this->WrapText($encoded, 74, true); return $encoded; } /** - * Encode string to q encoding. Returns a string. + * Encode string to q encoding. * @access private * @return string */ - function encode_q ($str, $position = 'text') { + function EncodeQ ($str, $position = "text") { // There should not be any EOL in the string $encoded = preg_replace("[\r\n]", "", $str); switch (strtolower($position)) { - case 'phrase': + case "phrase": $encoded = preg_replace("/([^A-Za-z0-9!*+\/ -])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded); break; - case 'comment': + case "comment": $encoded = preg_replace("/([\(\)\"])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded); - // Fall-through - case 'text': + case "text": default: // Replace every high ascii, control =, ? and _ characters $encoded = preg_replace('/([\000-\011\013\014\016-\037\075\077\137\177-\377])/e', @@ -1400,10 +1238,14 @@ * Adds a string or binary attachment (non-filesystem) to the list. * This method can be used to attach ascii or binary data, * such as a BLOB record from a database. - * @access public + * @param string $string String attachment data. + * @param string $filename Name of the attachment. + * @param string $encoding File encoding (see $Encoding). + * @param string $type File extension (MIME) type. * @return void */ - function AddStringAttachment($string, $filename, $encoding = "base64", $type = "application/octet-stream") { + function AddStringAttachment($string, $filename, $encoding = "base64", + $type = "application/octet-stream") { // Append to $attachment array $cur = count($this->attachment); $this->attachment[$cur][0] = $string; @@ -1418,17 +1260,23 @@ /** * Adds an embedded attachment. This can include images, sounds, and - * just about any other document. - * @param cid this is the Content Id of the attachment. Use this to identify + * just about any other document. Make sure to set the $type to an + * image type. For JPEG images use "image/jpeg" and for GIF images + * use "image/gif". + * @param string $path Path to the attachment. + * @param string $cid Content ID of the attachment. Use this to identify * the Id for accessing the image in an HTML form. - * @access public + * @param string $name Overrides the attachment name. + * @param string $encoding File encoding (see $Encoding). + * @param string $type File extension (MIME) type. * @return bool */ - function AddEmbeddedImage($path, $cid, $name = "", $encoding = "base64", $type = "application/octet-stream") { + function AddEmbeddedImage($path, $cid, $name = "", $encoding = "base64", + $type = "application/octet-stream") { if(!@is_file($path)) { - $this->error_handler(sprintf("Could not access [%s] file", $path)); + $this->SetError($this->Lang("file_access") . $path); return false; } @@ -1451,19 +1299,22 @@ } /** - * Returns the number of embedded images in an email. + * Returns true if an inline attachment is present. * @access private - * @return int + * @return bool */ - function EmbeddedImageCount() { - $ret = 0; + function InlineImageExists() { + $result = false; for($i = 0; $i < count($this->attachment); $i++) { if($this->attachment[$i][6] == "inline") - $ret++; + { + $result = true; + break; + } } - return $ret; + return $result; } ///////////////////////////////////////////////// @@ -1472,7 +1323,6 @@ /** * Clears all recipients assigned in the TO array. Returns void. - * @access public * @return void */ function ClearAddresses() { @@ -1481,7 +1331,6 @@ /** * Clears all recipients assigned in the CC array. Returns void. - * @access public * @return void */ function ClearCCs() { @@ -1490,7 +1339,6 @@ /** * Clears all recipients assigned in the BCC array. Returns void. - * @access public * @return void */ function ClearBCCs() { @@ -1499,7 +1347,6 @@ /** * Clears all recipients assigned in the ReplyTo array. Returns void. - * @access public * @return void */ function ClearReplyTos() { @@ -1509,7 +1356,6 @@ /** * Clears all recipients assigned in the TO, CC and BCC * array. Returns void. - * @access public * @return void */ function ClearAllRecipients() { @@ -1521,7 +1367,6 @@ /** * Clears all previously set filesystem, string, and binary * attachments. Returns void. - * @access public * @return void */ function ClearAttachments() { @@ -1530,7 +1375,6 @@ /** * Clears all custom headers. Returns void. - * @access public * @return void */ function ClearCustomHeaders() { @@ -1548,60 +1392,24 @@ * @access private * @return void */ - function error_handler($msg) { + function SetError($msg) { + $this->error_count++; $this->ErrorInfo = $msg; } /** - * Returns the proper RFC 822 formatted date. Returns string. + * Returns the proper RFC 822 formatted date. * @access private * @return string */ - function rfc_date() { + function RFCDate() { $tz = date("Z"); $tzs = ($tz < 0) ? "-" : "+"; $tz = abs($tz); $tz = ($tz/3600)*100 + ($tz%3600)/60; - $date = sprintf("%s %s%04d", date("D, j M Y H:i:s"), $tzs, $tz); - return $date; - } - - /** - * Returns received header for message tracing. Returns string. - * @access private - * @return string - */ - function received() { - // Check for vars because they might not exist. Possibly - // write a small retrieval function (that mailer can use too!) - - if ($this->get_server_var('SERVER_NAME') != '') - { - $protocol = ($this->get_server_var('HTTPS') == 'on') ? 'HTTPS' : 'HTTP'; - $remote = $this->get_server_var('REMOTE_HOST'); - if ($remote == '') - $remote = 'phpmailer'; - $remote .= ' (['.$this->get_server_var('REMOTE_ADDR').'])'; - } - else - { - $protocol = 'local'; - $remote = $this->get_server_var('USER'); - if ($remote == '') - $remote = 'phpmailer'; - } - - $str = sprintf("Received: from %s %s\tby %s " . - "with %s (phpmailer);%s\t%s%s", - $remote, - $this->LE, - $this->get_server_hostname(), - $protocol, - $this->LE, - $this->rfc_date(), - $this->LE); + $result = sprintf("%s %s%04d", date("D, j M Y H:i:s"), $tzs, $tz); - return $str; + return $result; } /** @@ -1611,7 +1419,7 @@ * @access private * @return mixed */ - function get_server_var($varName) { + function ServerVar($varName) { global $HTTP_SERVER_VARS; global $HTTP_ENV_VARS; @@ -1633,147 +1441,59 @@ * @access private * @return string */ - function get_server_hostname() { - if ($this->Hostname != '') - return $this->Hostname; - elseif ($this->get_server_var('SERVER_NAME') != '') - return $this->get_server_var('SERVER_NAME'); - else - return 'localhost.localdomain'; + function ServerHostname() { + if ($this->Hostname != "") + $result = $this->Hostname; + elseif ($this->ServerVar('SERVER_NAME') != "") + $result = $this->ServerVar('SERVER_NAME'); + else + $result = "localhost.localdomain"; + + return $result; } /** - * Changes every end of line from CR or LF to CRLF. Returns string. + * Returns a message in the appropriate language. * @access private * @return string */ - function fix_eol($str) { - $str = str_replace("\r\n", "\n", $str); - $str = str_replace("\r", "\n", $str); - $str = str_replace("\n", $this->LE, $str); - return $str; + function Lang($key) { + if(count($this->language) < 1) + $this->SetLanguage("en"); // set the default language + + if(isset($this->language[$key])) + return $this->language[$key]; + else + return "Language string failed to load: " . $key; } - + /** - * Adds a custom header. Returns void. - * @access public - * @return void + * Returns true if an error occurred. + * @return bool */ - function AddCustomHeader($custom_header) { - // Append to $custom_header array - $this->CustomHeader[] = explode(":", $custom_header, 2); + function IsError() { + return ($this->error_count > 0); } /** - * Adds all the Microsoft message headers. Returns string. + * Changes every end of line from CR or LF to CRLF. * @access private * @return string */ - function AddMSMailHeaders() { - $MSHeader = ""; - if($this->Priority == 1) - $MSPriority = "High"; - elseif($this->Priority == 5) - $MSPriority = "Low"; - else - $MSPriority = "Medium"; - - $MSHeader .= sprintf("X-MSMail-Priority: %s%s", $MSPriority, $this->LE); - $MSHeader .= sprintf("Importance: %s%s", $MSPriority, $this->LE); - - return($MSHeader); + function FixEOL($str) { + $str = str_replace("\r\n", "\n", $str); + $str = str_replace("\r", "\n", $str); + $str = str_replace("\n", $this->LE, $str); + return $str; } -} - - -/** - * Boundary - MIME message boundary class - * @author Brent R. Matzelle - */ -class Boundary -{ - /** - * Sets the boundary ID. - * @access private - * @var string - */ - var $ID = 0; - /** - * Sets the boundary Content Type. - * @access public - * @var string - */ - var $ContentType = "text/plain"; - - /** - * Sets the Encoding. - * @access public - * @var string - */ - var $Encoding = ""; - - /** - * Sets an attachment disposition. - * @access public - * @var string - */ - var $Disposition = ""; - - /** - * Sets an attachment file name. - * @access public - * @var string - */ - var $FileName = ""; - - /** - * Sets the Char set. - * @access public - * @var string - */ - var $CharSet = ""; - - /** - * Sets the line endings of the message. Default is "\n"; - * @access public - * @var string - */ - var $LE = "\n"; - - /** - * Main constructor. - */ - function Boundary($boundary_id) { - $this->ID = $boundary_id; - } - - /** - * Returns the source of the boundary. - * @access public - * @return string + * Adds a custom header. + * @return void */ - function GetSource($bLineEnding = true) { - $mime = array(); - $mime[] = sprintf("--%s%s", $this->ID, $this->LE); - $mime[] = sprintf("Content-Type: %s; charset = \"%s\"%s", - $this->ContentType, $this->CharSet, $this->LE); - $mime[] = sprintf("Content-Transfer-Encoding: %s%s", $this->Encoding, - $this->LE); - - if(strlen($this->Disposition) > 0) - { - $mime[] = sprintf("Content-Disposition: %s;"); - if(strlen($this->FileName) > 0) - $mime[] = sprinf("filename=\"%s\"", $this->FileName); - } - - if($bLineEnding) - $mime[] = $this->LE; - - return join("", $mime); + function AddCustomHeader($custom_header) { + $this->CustomHeader[] = explode(":", $custom_header, 2); } } -?> +?> \ No newline at end of file Index: xoops2jp/html/class/mail/phpmailer/class.smtp.php diff -u xoops2jp/html/class/mail/phpmailer/class.smtp.php:1.2 xoops2jp/html/class/mail/phpmailer/class.smtp.php:1.2.6.1 --- xoops2jp/html/class/mail/phpmailer/class.smtp.php:1.2 Sat Jun 11 11:32:39 2005 +++ xoops2jp/html/class/mail/phpmailer/class.smtp.php Tue Apr 11 22:04:03 2006 @@ -14,22 +14,40 @@ //////////////////////////////////////////////////// /** - * STMP is rfc 821 compliant and implements all the rfc 821 SMTP + * SMTP is rfc 821 compliant and implements all the rfc 821 SMTP * commands except TURN which will always return a not implemented * error. SMTP also provides some utility methods for sending mail * to an SMTP server. + * @package PHPMailer * @author Chris Ryan */ class SMTP { - var $SMTP_PORT = 25; # the default SMTP PORT - var $CRLF = "\r\n"; # CRLF pair + /** + * SMTP server port + * @var int + */ + var $SMTP_PORT = 25; + + /** + * SMTP reply line ending + * @var string + */ + var $CRLF = "\r\n"; + + /** + * Sets whether debugging is turned on + * @var bool + */ + var $do_debug; # the level of debug to perform + /**#@+ + * @access private + */ var $smtp_conn; # the socket to the server var $error; # error if any on the last call var $helo_rply; # the reply the server sent to us for HELO - - var $do_debug; # the level of debug to perform + /**#@-*/ /** * Initialize the class so that the data is in a known state. @@ -101,7 +119,7 @@ # so we will give it a longer timeout for the first read // Windows still does not have support for this timeout function if(substr(PHP_OS, 0, 3) != "WIN") - socket_set_timeout($this->smtp_conn, 1, 0); + socket_set_timeout($this->smtp_conn, $tval, 0); # get any announcement stuff $announce = $this->get_lines(); @@ -315,12 +333,10 @@ while(strlen($line) > $max_line_length) { $pos = strrpos(substr($line,0,$max_line_length)," "); - // fix for infinite loop bug - // added by onokazu, 2005/5/31 - if (!$pos) { + # Patch to fix DOS attack + if(!$pos) { $pos = $max_line_length - 1; } - // end fix $lines_out[] = substr($line,0,$pos); $line = substr($line,$pos + 1); @@ -454,7 +470,23 @@ $host = "localhost"; } - fputs($this->smtp_conn,"HELO " . $host . $this->CRLF); + // Send extended hello first (RFC 2821) + if(!$this->SendHello("EHLO", $host)) + { + if(!$this->SendHello("HELO", $host)) + return false; + } + + return true; + } + + /** + * Sends a HELO/EHLO command. + * @access private + * @return bool + */ + function SendHello($hello, $host) { + fputs($this->smtp_conn, $hello . " " . $host . $this->CRLF); $rply = $this->get_lines(); $code = substr($rply,0,3); @@ -465,7 +497,7 @@ if($code != 250) { $this->error = - array("error" => "HELO not accepted from server", + array("error" => $hello . " not accepted from server", "smtp_code" => $code, "smtp_msg" => substr($rply,4)); if($this->do_debug >= 1) { @@ -476,7 +508,7 @@ } $this->helo_rply = $rply; - + return true; } @@ -556,7 +588,7 @@ return false; } - fputs($this->smtp_conn,"MAIL FROM:" . $from . $this->CRLF); + fputs($this->smtp_conn,"MAIL FROM:<" . $from . ">" . $this->CRLF); $rply = $this->get_lines(); $code = substr($rply,0,3); @@ -695,7 +727,7 @@ return false; } - fputs($this->smtp_conn,"RCPT TO:" . $to . $this->CRLF); + fputs($this->smtp_conn,"RCPT TO:<" . $to . ">" . $this->CRLF); $rply = $this->get_lines(); $code = substr($rply,0,3);