summaryrefslogtreecommitdiff
path: root/program/lib/smtp.inc
diff options
context:
space:
mode:
Diffstat (limited to 'program/lib/smtp.inc')
-rw-r--r--program/lib/smtp.inc351
1 files changed, 351 insertions, 0 deletions
diff --git a/program/lib/smtp.inc b/program/lib/smtp.inc
new file mode 100644
index 000000000..ebff9d263
--- /dev/null
+++ b/program/lib/smtp.inc
@@ -0,0 +1,351 @@
+<?php
+/////////////////////////////////////////////////////////
+//
+// include/smtp.inc
+//
+// (C)Copyright 2002 Ryo Chijiiwa <Ryo@IlohaMail.org>
+//
+// This file is part of IlohaMail.
+// IlohaMail is free software released under the GPL
+// license. See enclosed file COPYING for details,
+// or see http://www.fsf.org/copyleft/gpl.html
+//
+/////////////////////////////////////////////////////////
+
+/********************************************************
+
+ AUTHOR: Ryo Chijiiwa <ryo@ilohamail.org>
+ FILE: include/smtp.php
+ PURPOSE:
+ Provide SMTP functionality using pure PHP.
+ PRE-CONDITIONS:
+ The functions here require a SMTP server configured to allow relaying.
+ POST-CONDITIONS:
+ The following global variables are returned:
+ $smtp_errornum - error number, 0 if successful
+ $smtp_error - error message(s)
+ $SMTP_TYPE - Optional
+ COMMENTS:
+ The optional $smtp_message_file can be used for sending extremely large
+ messages. Storing large messages in a variable will consume whatever
+ amount of memory required, which may be more than is available if dealing
+ with messages with large attachments. By storing them in a file, it becomes
+ possible to read/send bits at a time, drastically reducing memory useage.
+
+ This library only provides bare-bones SMTP functionality. It is up to the
+ parent code to form valid RFC822 (MIME) messages.
+
+********************************************************/
+
+ //set some global constants
+ if (strcasecmp($SMTP_TYPE, "courier")==0){
+ $SMTP_REPLY_DELIM = "-";
+ $SMTP_DATA_REPLY = 250;
+ }else{
+ $SMTP_REPLY_DELIM = " ";
+ $SMTP_DATA_REPLY = 354;
+ }
+
+ /* fgets replacement that's multi-line aware */
+ function smtp_get_response($fp, $len){
+ $end = false;
+ do{
+ $line = chop(fgets($fp, 5120));
+ // echo "SMTP:".$line."<br>\n"; flush();
+ if ((strlen($line)==3) || ($line[3]==' ')) $end = true;
+ }while(!$end);
+
+ return $line;
+ }
+
+
+ function smtp_check_reply($reply){
+ global $smtp_error;
+ global $SMTP_REPLY_DELIM;
+
+ $a = explode($SMTP_REPLY_DELIM, chop($reply));
+
+ if (count($a) >= 1){
+
+ if ($a[0]==250||$a[0]==354) return true;
+ else{
+ $smtp_error .= $reply."\n";
+ }
+ }else{
+ $smtp_error .= "Invalid SMTP response line: $reply\n";
+ }
+
+ return false;
+ }
+
+
+ function smtp_split($str){
+ $result = array();
+ $pos = strpos($str, " ");
+ if ($pos===false){
+ $result[0] = $str;
+ }else{
+ $result[0] = substr($str, 0, $pos);
+ $result[1] = substr($str, $pos+1);
+ }
+
+ return $result;
+ }
+
+
+ function smtp_ehlo(&$conn, $host){
+ $result = "";
+ fputs($conn, "EHLO $host\r\n");
+ //echo "Sent: EHLO $host\n"; flush();
+ do{
+ $line = fgets($conn, 2048);
+ //echo "Got: $line"; flush();
+ $a = explode(" ", $line);
+ if ($a[0]=="250-AUTH") $result .= substr($line, 9);
+ }while(!is_numeric($a[0]));
+
+ if ($a[0]==250) return $result;
+ else return $a[0];
+
+ }
+
+
+ function smtp_auth_login(&$conn, $user, $pass){
+ $auth["username"] = base64_encode($user);
+ $auth["password"] = base64_encode($pass);
+
+ fputs($conn, "AUTH LOGIN\r\n");
+
+ //echo "Sent: AUTH LOGIN\n"; flush();
+
+ //get first line
+ $line = smtp_get_response($conn, 1024);
+ //echo "AUTH_LOGIN << $line"; flush();
+ $parts = smtp_split($line);
+ //valid reply?
+ if (($parts[0]!=334) || (empty($parts[1]))) return false;
+ //send data
+ $prompt = eregi_replace("[^a-z]", "", strtolower(base64_decode($parts[1])));
+ fputs($conn, $auth[$prompt]."\r\n");
+ //echo "AUT_LOGIN >> ".$auth[$prompt]."\n"; flush();
+
+ //get second line
+ $line = smtp_get_response($conn, 1024);
+ //echo "AUTH_LOGIN << $line"; flush();
+ $parts = smtp_split($line);
+ //valid reply?
+ if (($parts[0]!=334) || (empty($parts[1]))) return false;
+ $prompt = eregi_replace("[^a-z]", "", strtolower(base64_decode($parts[1])));
+ fputs($conn, $auth[$prompt]."\r\n");
+ //echo "AUT_LOGIN >> ".$auth[$prompt]."\n"; flush();
+
+ $line = smtp_get_response($conn, 1024);
+ //echo "AUTH_LOGIN << $line"; flush();
+ $parts = smtp_split($line);
+ return ($parts[0]==235);
+ }
+
+
+ function smtp_connect($host, $port, $user, $pass){
+ global $smtp_errornum;
+ global $smtp_error;
+
+ //auth user?
+ global $SMTP_USER, $SMTP_PASSWORD;
+ if ((!empty($SMTP_USER)) && (!empty($SMTP_PASSWORD))){
+ $user = $SMTP_USER;
+ $pass = $SMTP_PASSWORD;
+ }
+
+ // echo "User: $user<br>\n";
+
+ //figure out auth mode
+ global $AUTH_MODE;
+ $auth_mode = $AUTH_MODE["smtp"];
+ if (empty($auth_mode)) $auth_mode = "none";
+ if (empty($user) || empty($pass)) $auth_mode = "none";
+
+ // echo "authmode: $auth_mode<br>\n"; flush();
+
+ //initialize defaults
+ if (empty($host)) $host = "localhost";
+ if (empty($port)) $port = 25;
+
+ // echo "Connecting to $host:$port<br>\n"; flush();
+
+ //connect to SMTP server
+ $conn = fsockopen($host, $port);
+
+ if (!$conn){
+ //echo "fsockopen failed\n";
+ $smtp_error = "Couldn't connect to $host:$port<br>\n";
+ return false;
+ }
+
+ //read greeting
+ $greeting = smtp_get_response($conn, 1024);
+
+ // echo "Connected: $greeting<br>\n"; flush();
+
+ if (($auth_mode=="check") || ($auth_mode=="auth")){
+ // echo "Trying EHLO<br>\n"; flush();
+ $auth_modes = smtp_ehlo($conn, $_SERVER["SERVER_NAME"]);
+ // echo "smtp_ehlo returned: $auth_modes<br>\n"; flush();
+ if ($auth_modes===false){
+ $smtp_error = "EHLO failed\n";
+ $conn = false;
+ }else if (stristr($auth_modes, "LOGIN")!==false){
+ echo "trying AUTH LOGIN\n"; flush();
+ if (!smtp_auth_login($conn, $user, $pass)){
+ //echo "CONN: AUTH_LOGIN failed\n"; flush();
+ $conn = false;
+ }
+ //echo "Conn after LOGIN: $conn<br>\n"; flush();
+ }
+ }else{
+ fputs($conn, "HELO ".$_SERVER["SERVER_NAME"]."\r\n");
+ $line = smtp_get_response($conn, 1024);
+ if (!smtp_check_reply($line)){
+ $conn = false;
+ $smtp_error .= $line."\n";
+ }
+ // echo "after HELO: $conn<br>\n"; flush();
+ }
+
+ return $conn;
+ }
+
+
+ function smtp_close($conn){
+ fclose($conn);
+ }
+
+
+ function smtp_mail($conn, $from, $recipients, $message, $is_file){
+ global $smtp_errornum;
+ global $smtp_error;
+ global $SMTP_DATA_REPLY;
+
+ //check recipients and sender addresses
+ if ((count($recipients)==0) || (!is_array($recipients))){
+ $smtp_errornum = -1;
+ $smtp_error .= "Recipients list is empty\n";
+ return false;
+ }
+ if (empty($from)){
+ $smtp_errornum = -2;
+ $smtp_error .= "From address unspecified\n";
+ return false;
+ }
+
+ if (!$conn){
+ $smtp_errornum = -3;
+ $smtp_error .= "Invalid connection\n";
+ }
+
+ if (!ereg("^<", $from)) $from = "<".$from;
+ if (!ereg(">$", $from)) $from = $from.">";
+
+ //send MAIL FROM command
+ $command = "MAIL FROM: $from\r\n";
+ // echo nl2br(htmlspecialchars($command));
+ fputs($conn, $command);
+
+ if (smtp_check_reply(smtp_get_response($conn, 1024))){
+ //send RCPT TO commands, count valid recipients
+ $num_recipients = 0;
+ while ( list($k, $recipient) = each($recipients) ){
+ $command = "RCPT TO: $recipient\r\n";
+ fputs($conn, $command);
+ $reply = smtp_check_reply(smtp_get_response($conn, 1024));
+ if ($reply) $num_recipients++;
+ else $smtp_error .= $reply."\n";
+ }
+
+ //error out if no valid recipiets
+ if ($num_recipients == 0){
+ $smtp_errornum = -1;
+ $smtp_error .= "No valid recipients\n";
+ return false;
+ }
+
+ //send DATA command
+ fputs($conn, "DATA\r\n");
+ $reply = chop(smtp_get_response($conn, 1024));
+ $a = explode(" ", $reply);
+
+ //error out if DATA command ill received
+ if ($a[0]!=$SMTP_DATA_REPLY){
+ $smtp_errornum = -4;
+ $smtp_error .= $reply;
+ return false;
+ }
+ //send data
+ if ($is_file){
+ //if message file, open file
+ $fp = false;
+ if (file_exists(realpath($message))) $fp = fopen($message, "rb");
+ if (!$fp)
+ {
+ $smtp_errornum = -4;
+ $smtp_error .= "Invlid message file\n";
+ return false;
+ }
+
+ //send file
+ while(!feof($fp)){
+ $buffer = chop(fgets($fp, 4096), "\r\n");
+ fputs($conn, $buffer."\r\n");
+ }
+ fclose($fp);
+ fputs($conn, "\r\n.\r\n");
+
+ return smtp_check_reply(smtp_get_response($conn, 1024));
+ }else{
+ //else, send message
+ $message = str_replace("\r\n", "\n", $message);
+ $message = str_replace("\n", "\r\n", $message);
+ $message = str_replace("\r\n.\r\n", "\r\n..\r\n", $message);
+ fputs($conn, $message);
+ fputs($conn, "\r\n.\r\n");
+
+ return smtp_check_reply(smtp_get_response($conn, 1024));
+ }
+ }
+
+ return false;
+ }
+
+
+ function smtp_ExplodeQuotedString($delimiter, $string){
+ $quotes=explode("\"", $string);
+ while ( list($key, $val) = each($quotes))
+ if (($key % 2) == 1)
+ $quotes[$key] = str_replace($delimiter, "_!@!_", $quotes[$key]);
+ $string=implode("\"", $quotes);
+
+ $result=explode($delimiter, $string);
+ while ( list($key, $val) = each($result) )
+ $result[$key] = str_replace("_!@!_", $delimiter, $result[$key]);
+
+ return $result;
+ }
+
+
+ function smtp_expand($str){
+ $addresses = array();
+ $recipients = smtp_ExplodeQuotedString(",", $str);
+ reset($recipients);
+ while ( list($k, $recipient) = each($recipients) ){
+ $a = explode(" ", $recipient);
+ while ( list($k2, $word) = each($a) ){
+ if ((strpos($word, "@") > 0) && (strpos($word, "\"")===false)){
+ if (!ereg("^<", $word)) $word = "<".$word;
+ if (!ereg(">$", $word)) $word = $word.">";
+ if (in_array($word, $addresses)===false) array_push($addresses, $word);
+ }
+ }
+ }
+ return $addresses;
+ }
+?> \ No newline at end of file