2 // PukiWiki - Yet another WikiWikiWeb clone.
3 // $Id: mail.php,v 1.7 2005/06/09 15:16:41 henoheno Exp $
5 // 2003-2005 PukiWiki Developers Team
6 // 2003 Originally written by upk
7 // License: GPL v2 or (at your option) any later version
9 // E-mail related functions
11 // Send a mail to the administrator
12 function pkwk_mail_notify($subject, $message, $footer = array())
14 global $smtp_server, $smtp_auth, $notify_to, $notify_from, $notify_header;
15 static $_to, $_headers, $_after_pop;
19 if (! PKWK_OPTIMISE) {
21 $func = 'pkwk_mail_notify(): ';
22 $mail_regex = '/[^@]+@[^@]{1,}\.[^@]{2,}/';
23 if (! preg_match($mail_regex, $notify_to))
24 die($func . 'Invalid $notify_to');
25 if (! preg_match($mail_regex, $notify_from))
26 die($func . 'Invalid $notify_from');
27 if ($notify_header != '') {
28 $header_regex = "/\A(?:\r\n|\r|\n)|\r\n\r\n/";
29 if (preg_match($header_regex, $notify_header))
30 die($func . 'Invalid $notify_header');
31 if (preg_match('/^From:/im', $notify_header))
32 die($func . 'Redundant \'From:\' in $notify_header');
38 'X-Mailer: PukiWiki/' . S_VERSION .
39 ' PHP/' . phpversion() . "\r\n" .
40 'From: ' . $notify_from;
42 // Additional header(s) by admin
43 if ($notify_header != '') $_headers .= "\r\n" . $notify_header;
45 $_after_pop = $smtp_auth;
48 if ($subject == '' || ($message == '' && empty($footer))) return FALSE;
51 if (isset($footer['PAGE'])) $subject = str_replace('$page', $footer['PAGE'], $subject);
54 if (isset($footer['REMOTE_ADDR'])) $footer['REMOTE_ADDR'] = & $_SERVER['REMOTE_ADDR'];
55 if (isset($footer['USER_AGENT']))
56 $footer['USER_AGENT'] = '(' . UA_PROFILE . ') ' . UA_NAME . '/' . UA_VERS;
57 if (! empty($footer)) {
59 if ($message != '') $_footer = "\n" . str_repeat('-', 30) . "\n";
60 foreach($footer as $key => $value)
61 $_footer .= $key . ': ' . $value . "\n";
65 // Wait POP/APOP auth completion
67 $result = pop_before_smtp();
68 if ($result !== TRUE) die($result);
71 ini_set('SMTP', $smtp_server);
73 if ($_headers == '') {
74 return mb_send_mail($_to, $subject, $message);
76 return mb_send_mail($_to, $subject, $message, $_headers);
80 // APOP/POP Before SMTP
81 function pop_before_smtp($pop_userid = '', $pop_passwd = '',
82 $pop_server = 'localhost', $pop_port = 110)
84 $pop_auth_use_apop = TRUE; // Always try APOP, by default
85 $must_use_apop = FALSE; // Always try POP for APOP-disabled server
86 if (isset($GLOBALS['pop_auth_use_apop'])) {
87 // Force APOP only, or POP only
88 $pop_auth_use_apop = $must_use_apop = $GLOBALS['pop_auth_use_apop'];
91 // Compat: GLOBALS > function arguments
92 foreach(array('pop_userid', 'pop_passwd', 'pop_server', 'pop_port') as $global) {
93 if(isset($GLOBALS[$global]) && $GLOBALS[$global] !== '')
94 $$global = $GLOBALS[$global];
99 foreach(array('pop_userid', 'pop_server', 'pop_port') as $global)
100 if($$global == '') $die .= 'pop_before_smtp(): $' . $global . ' seems blank' . "\n";
101 if ($die) return ($die);
104 $errno = 0; $errstr = '';
105 $fp = @fsockopen($pop_server, $pop_port, $errno, $errstr, 30);
106 if (! $fp) return ('pop_before_smtp(): ' . $errstr . ' (' . $errno . ')');
108 // Greeting message from server, may include <challenge-string> of APOP
109 $message = fgets($fp, 1024); // 512byte max
110 if (! preg_match('/^\+OK/', $message)) {
112 return ('pop_before_smtp(): Greeting message seems invalid');
115 $challenge = array();
116 if ($pop_auth_use_apop &&
117 (preg_match('/<.*>/', $message, $challenge) || $must_use_apop)) {
118 $method = 'APOP'; // APOP auth
119 if (! isset($challenge[0])) {
120 $response = md5(time()); // Someting worthless but variable
122 $response = md5($challenge[0] . $pop_passwd);
124 fputs($fp, 'APOP ' . $pop_userid . ' ' . $response . "\r\n");
126 $method = 'POP'; // POP auth
127 fputs($fp, 'USER ' . $pop_userid . "\r\n");
128 $message = fgets($fp, 1024); // 512byte max
129 if (! preg_match('/^\+OK/', $message)) {
131 return ('pop_before_smtp(): USER seems invalid');
133 fputs($fp, 'PASS ' . $pop_passwd . "\r\n");
136 $result = fgets($fp, 1024); // 512byte max, auth result
137 $auth = preg_match('/^\+OK/', $result);
140 fputs($fp, 'STAT' . "\r\n"); // STAT, trigger SMTP relay!
141 $message = fgets($fp, 1024); // 512byte max
145 fputs($fp, 'QUIT' . "\r\n");
146 $message = fgets($fp, 1024); // 512byte max, last '+OK'
150 return ('pop_before_smtp(): ' . $method . ' authentication failed');
152 return TRUE; // Success