<?php
if (!defined('puyuetian')) {
	exit('403');
}

function sendmail($mailto, $mailtitle, $mailcontent, $timeout = false)
{
	global $_G;
	if (!filter_var($mailto, FILTER_VALIDATE_EMAIL) || !$_G['SET']['APP_SYSTEMEMAIL_LOAD']) {
		return false;
	}
	$timeout = Cnum($_G['SET']['APP_SYSTEMEMAIL_TIMEOUTSECONDS'], 10, true, 1, 60);
	$smtpserver = $_G['SET']['APP_SYSTEMEMAIL_SMTP'];
	$smtpserverport = Cnum($_G['SET']['APP_SYSTEMEMAIL_PORT'], 25, true, 1);
	$smtpuser = $_G['SET']['APP_SYSTEMEMAIL_USER'];
	$smtppass = $_G['SET']['APP_SYSTEMEMAIL_PASS'];
	$smtpname = strip_tags($_G['SET']['APP_SYSTEMEMAIL_NAME']);
	if (!$smtpname) {
		$smtpname = $smtpuser;
	}
	$smtp = new smtp($smtpserver, $smtpserverport, true, $smtpuser, $smtppass, $timeout);
	$smtp -> debug = $_G['SET']['APP_SYSTEMEMAIL_DEBUG'];
	$r = $smtp -> sendmail($mailto, $smtpuser, $smtpname, strip_tags($mailtitle), $mailcontent, 'HTML');
	if ($r !== true) {
		if ($smtp -> debug) {
			NewMessage(1, "<b>[邮箱调试信息]</b>{$r}", 0, 2);
		}
		return false;
	}
	return true;
}

/*
 * 邮件发送类
 */
class smtp
{
	/* Public Variables */
	public $smtp_port;
	public $time_out;
	public $host_name;
	public $log_file;
	public $relay_host;
	public $debug;
	public $auth;
	public $user;
	public $pass;

	/* Private Variables */
	private $sock;

	/* Constractor */
	public function __construct($relay_host = '', $smtp_port = 25, $auth = false, $user, $pass, $timeout = 10)
	{
		$this -> debug = false;
		$this -> smtp_port = $smtp_port;
		$this -> relay_host = $relay_host;
		$this -> time_out = $timeout;
		//is used in fsockopen()
		#
		$this -> auth = $auth;
		//auth
		$this -> user = $user;
		$this -> pass = $pass;
		#
		$this -> host_name = 'localhost';
		//is used in HELO command
		$this -> log_file = '';

		$this -> sock = false;
	}

	/* Main Function */
	public function sendmail($to, $from, $name, $subject = "", $body = "", $mailtype)
	{
		$body = preg_replace("/(^|(\r\n))(\\.)/", "\\1.\\3", $body);
		$header = '';
		$header .= "MIME-Version:1.0\r\n";
		if ($mailtype == 'HTML') {
			$header .= "Content-Type:text/html;charset=utf-8\r\n";
		}
		$header .= "To: {$to}\r\n";
		$header .= "From: {$name}<{$from}>\r\n";
		$header .= "Subject: {$subject}\r\n";
		$header .= "Date: " . date('r') . "\r\n";
		//$header .= "X-Mailer:{$_G['SYSTEM']['DOMAIN']}\r\n";
		$messageid = md5(date('YmdHis') . CreateRandomString(7) . $from);
		$header .= "Message-ID: {$messageid}\r\n";
		$r = $this -> smtp_sockopen($to);
		if ($r !== true) {
			return "无法发送邮件至：{$to}，{$r}";
		}
		$r = $this -> smtp_send($this -> host_name, $from, $to, $header, $body);
		if ($r !== true) {
			return "无法发送邮件至：{$to}，{$r}";
		}
		fclose($this -> sock);
		return true;
	}

	/* Private Functions */

	public function smtp_send($helo, $from, $to, $header, $body = "")
	{
		if (!$this -> smtp_putcmd('HELO', $helo)) {
			return 'HELO命令发送出错';
		}
		// 验证身份
		if ($this -> auth) {
			if (!$this -> smtp_putcmd('AUTH LOGIN', base64_encode($this -> user))) {
				return 'SMTP用户账户错误';
			}
			if (!$this -> smtp_putcmd('', base64_encode($this -> pass))) {
				return 'SMTP用户密码错误';
			}
		}
		#
		if (!$this -> smtp_putcmd('MAIL', "FROM:<{$from}>")) {
			return '发信人邮箱校验失败';
		}

		if (!$this -> smtp_putcmd('RCPT', "TO:<{$to}>")) {
			return '收信人邮箱校验失败';
		}

		if (!$this -> smtp_putcmd('DATA') || !$this -> smtp_message($header, $body)) {
			return '邮件内容校验失败';
		}

		if (!$this -> smtp_eom()) {
			return '邮件内容结尾出错';
		}

		if (!$this -> smtp_putcmd('QUIT')) {
			return 'SMTP服务器连接关闭失败';
		}

		return true;
	}

	public function smtp_sockopen($address)
	{
		return $this -> smtp_sockopen_relay();
	}

	public function smtp_sockopen_relay()
	{
		$this -> sock = fsockopen($this -> relay_host, $this -> smtp_port, $errno, $errstr, $this -> time_out);
		if (!($this -> sock && $this -> smtp_ok())) {
			return "无法连接SMTP服务器[" . $this -> relay_host . "]，错误{$errno}";
		}
		return true;
	}

	public function smtp_message($header, $body)
	{
		fputs($this -> sock, $header . "\r\n" . $body);
		return true;
	}

	public function smtp_eom()
	{
		fputs($this -> sock, "\r\n.\r\n");
		return $this -> smtp_ok();
	}

	public function smtp_ok()
	{
		$response = str_replace("\r\n", '', fgets($this -> sock, 512));
		if (!preg_match("/^[23]/", $response)) {
			fputs($this -> sock, "QUIT\r\n");
			fgets($this -> sock, 512);
			return false;
		}
		return true;
	}

	public function smtp_putcmd($cmd, $arg = '')
	{
		if ($arg != '') {
			if ($cmd == '') {
				$cmd = $arg;
			} else {
				$cmd = $cmd . ' ' . $arg;
			}
		}

		fputs($this -> sock, $cmd . "\r\n");
		return $this -> smtp_ok();
	}
}
