23 if (!class_exists(
'MIME5')) require_once
'MIME5.php';
35 static private function _cres(
$conn = null, &$resp, $code1 = null, $code2 = null, $debug = null) {
38 if (!is_resource(
$conn)) $err[] =
'invalid resource connection';
39 if (!(is_int($code1) && $code1 > 99 && $code1 < 1000)) $err[] =
'invalid 1 code value';
41 if (!(is_int($code2) && $code2 > 99 && $code2 < 1000)) $err[] =
'invalid 2 code value';
43 if (count($err) > 0)
return FUNC5::trace($debug, implode(
', ', $err), 1);
47 if ($result = fgets(
$conn, self::BLEN)) {
49 $rescode = substr($result, 0, 3);
50 if (!($rescode == $code1 || $rescode == $code2)) {
55 $resp[] =
'can not read';
59 }
while ($result[3] ==
'-');
64 static public function mxconnect($host = null, $port = null, $tout = null, $name = null, $context = null, $debug = null) {
68 if (!is_string($host))
FUNC5::trace($debug,
'invalid host type');
70 $host = strtolower(trim($host));
76 foreach ($arr as $mx) {
77 if ($con = self::connect($mx, $port, null, null, null, $tout, $name, $context, null, $debug))
break;
80 if (!$con) $con =
self::connect($host, $port, null, null, null, $tout, $name, $context, null, $debug);
84 static public function connect($host = null, $port = null, $user = null, $pass = null, $vssl = null, $tout = null, $name = null, $context = null, $login = null, $debug = null) {
87 $_RESULT = $err = array();
90 if (!is_string($host)) $err[] =
'invalid host type';
92 $host = strtolower(trim($host));
95 if (!(is_int($port) && $port > 0)) $err[] =
'invalid port value';
97 if (!is_string($user)) $err[] =
'invalid username type';
98 else if (($user =
FUNC5::str_clear($user)) ==
'') $err[] =
'invalid username value';
101 if (!is_string($pass)) $err[] =
'invalid password type';
102 else if (($pass =
FUNC5::str_clear($pass)) ==
'') $err[] =
'invalid password value';
104 if (($user != null && $pass == null) || ($user == null && $pass != null)) $err[] =
'invalid username/password combination';
106 if (!is_string($vssl)) $err[] =
'invalid ssl version type';
108 $vssl = strtolower($vssl);
109 if (!($vssl ==
'tls' || $vssl ==
'ssl' || $vssl ==
'sslv2' || $vssl ==
'sslv3')) $err[] =
'invalid ssl version value';
112 if (!(is_int($tout) && $tout > 0)) $err[] =
'invalid timeout value';
114 if (!is_string($name)) $err[] =
'invalid name type';
116 $name = strtolower(trim($name));
119 }
else $name =
'127.0.0.1';
120 if ($context != null && !is_resource($context)) $err[] =
'invalid context type';
121 if ($login != null) {
122 $login = strtolower(trim($login));
123 if (!($login ==
'login' || $login ==
'plain' || $login ==
'cram-md5')) $err[] =
'invalid authentication type value';
125 if (count($err) > 0)
FUNC5::trace($debug, implode(
', ', $err));
128 $prt = ($vssl == null) ?
'tcp' : $vssl;
129 $conn = ($context == null) ? stream_socket_client($prt.
'://'.$host.
':'.$port, $errno, $errstr, $tout) : stream_socket_client($prt.
'://'.$host.
':'.$port, $errno, $errstr, $tout, STREAM_CLIENT_CONNECT, $context);
130 if (!
$conn) $_RESULT[101] = $errstr;
131 else if (!stream_set_timeout(
$conn, self::COUT)) $_RESULT[102] =
'could not set stream timeout';
132 else if (!self::_cres(
$conn, $resp, 220, null, $debug)) $_RESULT[103] = $resp;
137 if ($user == null) $ret =
true;
138 else if ($login != null) $ret =
self::auth(
$conn, $user, $pass, $login, $debug);
140 list($code, $arr) = each($_RESULT);
141 $auth[
'default'] = $auth[
'login'] = $auth[
'plain'] = $auth[
'cram-md5'] =
false;
142 foreach ($arr as $line) {
143 if (substr($line, 0, strlen(
'250-AUTH ')) ==
'250-AUTH ') {
144 foreach (explode(
' ', substr($line, strlen(
'250-AUTH '))) as $type) {
145 $type = strtolower(trim($type));
146 if ($type ==
'login' || $type ==
'plain' || $type ==
'cram-md5') $auth[$type] =
true;
148 }
else if (substr($line, 0, strlen(
'250 AUTH=')) ==
'250 AUTH=') {
149 $expl = explode(
' ', strtolower(trim(substr($line, strlen(
'250 AUTH=')))), 2);
150 if (
$expl[0] ==
'login' ||
$expl[0] ==
'plain' ||
$expl[0] ==
'cram-md5') $auth[
'default'] =
$expl[0];
153 if ($auth[
'default']) $ret =
self::auth(
$conn, $user, $pass, $auth[
'default'], $debug);
154 if (!$ret && $auth[
'login'] && $auth[
'default'] !=
'login') $ret =
self::auth(
$conn, $user, $pass,
'login', $debug);
155 if (!$ret && $auth[
'plain'] && $auth[
'default'] !=
'plain') $ret =
self::auth(
$conn, $user, $pass,
'plain', $debug);
156 if (!$ret && $auth[
'cram-md5'] && $auth[
'default'] !=
'cram-md5') $ret =
self::auth(
$conn, $user, $pass,
'cram-md5', $debug);
157 if (!$ret && !$auth[
'login'] && $auth[
'default'] !=
'login') $ret =
self::auth(
$conn, $user, $pass,
'login', $debug);
158 if (!$ret && !$auth[
'plain'] && $auth[
'default'] !=
'plain') $ret =
self::auth(
$conn, $user, $pass,
'plain', $debug);
159 if (!$ret && !$auth[
'cram-md5'] && $auth[
'default'] !=
'cram-md5') $ret =
self::auth(
$conn, $user, $pass,
'cram-md5', $debug);
174 $_RESULT = $err = array();
175 if (!is_resource(
$conn)) $err[] =
'invalid resource connection';
176 if (!is_array($addrs)) $err[] =
'invalid to address type';
179 if (count($addrs) > 0) {
180 foreach ($addrs as $addr) {
186 }
else $aver =
false;
187 if (!$aver) $err[] =
'invalid to address value';
189 if (!is_string(
$mess)) $err[] =
'invalid message value';
191 $from = @ini_get(
'sendmail_from');
194 if (!is_string(
$from)) $err[] =
'invalid from address type';
197 if (count($err) > 0)
FUNC5::trace($debug, implode(
', ', $err));
202 foreach ($addrs as $dest) {
203 if (!self::to(
$conn, $dest, $debug)) {
209 if (self::data(
$conn,
$mess, $debug)) $ret = self::rset(
$conn, $debug);
220 if (!is_resource(
$conn))
return FUNC5::trace($debug,
'invalid resource connection', 1);
222 if (!fwrite(
$conn,
'QUIT'.self::CRLF)) $_RESULT[300] =
'can not write';
223 else $_RESULT[301] =
'Send QUIT';
224 return @fclose(
$conn);
228 static public function quit(
$conn = null, $debug = null) {
234 else if (!fwrite(
$conn,
'QUIT'.self::CRLF)) $_RESULT[302] =
'can not write';
236 $_RESULT[303] = ($vget = @fgets(
$conn, self::BLEN)) ? $vget :
'can not read';
242 static public function helo(
$conn = null, $host = null, $debug = null) {
245 $_RESULT = $err = array();
246 if (!is_resource(
$conn)) $err[] =
'invalid resource connection';
247 if (!is_string($host)) $err[] =
'invalid host type';
249 $host = strtolower(trim($host));
252 if (count($err) > 0)
FUNC5::trace($debug, implode(
', ', $err));
255 if (!fwrite(
$conn,
'HELO '.$host.self::CRLF)) $_RESULT[304] =
'can not write';
256 else if (!self::_cres(
$conn, $resp, 250, null, $debug)) $_RESULT[305] = $resp;
258 $_RESULT[306] = $resp;
265 static public function ehlo(
$conn = null, $host = null, $debug = null) {
268 $_RESULT = $err = array();
269 if (!is_resource(
$conn)) $err[] =
'invalid resource connection';
270 if (!is_string($host)) $err[] =
'invalid host type';
272 $host = strtolower(trim($host));
275 if (count($err) > 0)
FUNC5::trace($debug, implode(
', ', $err));
278 if (!fwrite(
$conn,
'EHLO '.$host.self::CRLF)) $_RESULT[307] =
'can not write';
279 else if (!self::_cres(
$conn, $resp, 250, null, $debug)) $_RESULT[308] = $resp;
281 $_RESULT[309] = $resp;
288 static public function auth(
$conn = null, $user = null, $pass = null, $type = null, $debug = null) {
291 $_RESULT = $err = array();
292 if (!is_resource(
$conn)) $err[] =
'invalid resource connection';
293 if (!is_string($user)) $err[] =
'invalid username type';
294 else if (($user =
FUNC5::str_clear($user)) ==
'') $err[] =
'invalid username value';
295 if (!is_string($pass)) $err[] =
'invalid password type';
296 else if (($pass =
FUNC5::str_clear($pass)) ==
'') $err[] =
'invalid password value';
297 if ($type == null) $type =
'login';
298 if (!is_string($type)) $err[] =
'invalid authentication type';
300 $type = strtolower(trim($type));
301 if (!($type ==
'login' || $type ==
'plain' || $type ==
'cram-md5')) $err[] =
'invalid authentication type value';
303 if (count($err) > 0)
FUNC5::trace($debug, implode(
', ', $err));
306 if ($type ==
'login') {
307 if (!fwrite(
$conn,
'AUTH LOGIN'.self::CRLF)) $_RESULT[310] =
'can not write';
308 else if (!self::_cres(
$conn, $resp, 334, null, $debug)) $_RESULT[311] = $resp;
309 else if (!fwrite(
$conn, base64_encode($user).self::CRLF)) $_RESULT[312] =
'can not write';
310 else if (!self::_cres(
$conn, $resp, 334, null, $debug)) $_RESULT[313] = $resp;
311 else if (!fwrite(
$conn, base64_encode($pass).self::CRLF)) $_RESULT[314] =
'can not write';
312 else if (!self::_cres(
$conn, $resp, 235, null, $debug)) $_RESULT[315] = $resp;
314 $_RESULT[316] = $resp;
317 }
else if ($type ==
'plain') {
318 if (!fwrite(
$conn,
'AUTH PLAIN '.base64_encode($user.chr(0).$user.chr(0).$pass).self::CRLF)) $_RESULT[317] =
'can not write';
319 else if (!self::_cres(
$conn, $resp, 235, null, $debug)) $_RESULT[318] = $resp;
321 $_RESULT[319] = $resp;
324 }
else if ($type ==
'cram-md5') {
325 if (!fwrite(
$conn,
'AUTH CRAM-MD5'.self::CRLF)) $_RESULT[200] =
'can not write';
326 else if (!self::_cres(
$conn, $resp, 334, null, $debug)) $_RESULT[201] = $resp;
328 if (strlen($pass) > 64) $pass = pack(
'H32', md5($pass));
329 if (strlen($pass) < 64) $pass = str_pad($pass, 64, chr(0));
330 $pad1 = substr($pass, 0, 64) ^ str_repeat(chr(0x36), 64);
331 $pad2 = substr($pass, 0, 64) ^ str_repeat(chr(0x5C), 64);
332 $chal = substr($resp[count($resp)-1], 4);
333 $innr = pack(
'H32', md5($pad1.base64_decode($chal)));
334 if (!fwrite(
$conn, base64_encode($user.
' '.md5($pad2.$innr)).self::CRLF)) $_RESULT[202] =
'can not write';
335 else if (!self::_cres(
$conn, $resp, 235, null, $debug)) $_RESULT[203] = $resp;
337 $_RESULT[204] = $resp;
346 static public function from(
$conn = null, $addr = null, $debug = null) {
349 $_RESULT = $err = array();
350 if (!is_resource(
$conn)) $err[] =
'invalid resource connection';
351 if (!is_string($addr)) $err[] =
'invalid from address type';
352 else if (!($addr !=
'' &&
FUNC5::is_mail($addr))) $err[] =
'invalid from address value';
353 if (count($err) > 0)
FUNC5::trace($debug, implode(
', ', $err));
356 if (!fwrite(
$conn,
'MAIL FROM:<'.$addr.
'>'.self::CRLF)) $_RESULT[320] =
'can not write';
357 else if (!self::_cres(
$conn, $resp, 250, null, $debug)) $_RESULT[321] = $resp;
359 $_RESULT[322] = $resp;
366 static public function to(
$conn = null, $addr = null, $debug = null) {
369 $_RESULT = $err = array();
370 if (!is_resource(
$conn)) $err[] =
'invalid resource connection';
371 if (!is_string($addr)) $err[] =
'invalid to address type';
372 else if (!($addr !=
'' &&
FUNC5::is_mail($addr))) $err[] =
'invalid to address value';
373 if (count($err) > 0)
FUNC5::trace($debug, implode(
', ', $err));
376 if (!fwrite(
$conn,
'RCPT TO:<'.$addr.
'>'.self::CRLF)) $_RESULT[323] =
'can not write';
377 else if (!self::_cres(
$conn, $resp, 250, 251, $debug)) $_RESULT[324] = $resp;
379 $_RESULT[325] = $resp;
389 $_RESULT = $err = array();
390 if (!is_resource(
$conn)) $err[] =
'invalid resource connection';
391 if (!(is_string(
$mess) &&
$mess !=
'')) $err[] =
'invalid message value';
392 if (count($err) > 0)
FUNC5::trace($debug, implode(
', ', $err));
395 if (!fwrite(
$conn,
'DATA'.self::CRLF)) $_RESULT[326] =
'can not write';
396 else if (!self::_cres(
$conn, $resp, 354, null, $debug)) $_RESULT[327] = $resp;
399 foreach (explode(self::CRLF,
$mess) as $line) {
400 if ($line !=
'' && $line[0] ==
'.') $line =
'.'.$line;
401 if (!fwrite(
$conn, $line.self::CRLF)) {
402 $_RESULT[328] =
'can not write';
408 if (!fwrite(
$conn,
'.'.self::CRLF)) $_RESULT[329] =
'can not write';
409 else if (!self::_cres(
$conn, $resp, 250, null, $debug)) $_RESULT[330] = $resp;
411 $_RESULT[331] = $resp;
420 static public function rset(
$conn = null, $debug = null) {
426 else if (!fwrite(
$conn,
'RSET'.self::CRLF)) $_RESULT[332] =
'can not write';
427 else if (!self::_cres(
$conn, $resp, 250, null, $debug)) $_RESULT[333] = $resp;
429 $_RESULT[334] = $resp;
435 static public function recv(
$conn = null, $code1 = null, $code2 = null, $debug = null) {
440 if (!self::_cres(
$conn, $resp, $code1, $code2, $debug)) $_RESULT[335] = $resp;
442 $_RESULT[336] = $resp;