2 // PukiWiki - Yet another WikiWikiWeb clone.
3 // $Id: mail.php,v 1.5 2005/06/07 14:37:46 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) {
20 $mail_regex = '/[^@]+@[^@]{1,}\.[^@]{2,}/';
21 $header_regex = "/\A(?:\r\n|\r|\n)|\r\n\r\n/";
22 if (! preg_match($mail_regex, $notify_to))
23 die('pkwk_mail_notify(): Invalid $notify_to');
24 if (! preg_match($mail_regex, $notify_from))
25 die('pkwk_mail_notify(): Invalid $notify_from');
26 if ($notify_header != '' && preg_match($header_regex, $notify_header))
27 die('pkwk_mail_notify(): Invalid $notify_header');
32 'X-Mailer: PukiWiki/' . S_VERSION .
33 ' PHP/' . phpversion() . "\r\n" .
34 'From: ' . $notify_from;
36 // Additional header(s) by admin
37 if ($notify_header != '') $_headers .= "\r\n" . $notify_header;
39 $_after_pop = $smtp_auth;
42 if ($subject == '' || ($message == '' && empty($footer))) return FALSE;
45 if (isset($footer['PAGE'])) $subject = str_replace('$page', $footer['PAGE'], $subject);
48 if (isset($footer['REMOTE_ADDR'])) $footer['REMOTE_ADDR'] = & $_SERVER['REMOTE_ADDR'];
49 if (isset($footer['USER_AGENT']))
50 $footer['USER_AGENT'] = '(' . UA_PROFILE . ') ' . UA_NAME . '/' . UA_VERS;
51 if (! empty($footer)) {
52 if ($message != '') $_footer = "\n" . str_repeat('-', 30) . "\n";
53 foreach($footer as $key => $value)
54 $_footer .= $key . ': ' . $value . "\n";
58 // Wait POP/APOP auth completion
60 $result = pop_before_smtp();
61 if ($result !== TRUE) die($result);
64 ini_set('SMTP', $smtp_server);
66 if ($_headers == '') {
67 return mb_send_mail($_to, $subject, $message);
69 return mb_send_mail($_to, $subject, $message, $_headers);
73 // APOP/POP Before SMTP
74 function pop_before_smtp($pop_userid = '', $pop_passwd = '',
75 $pop_server = 'localhost', $pop_port = 110)
77 $pop_auth_use_apop = TRUE; // Always try APOP, by default
78 $must_use_apop = FALSE; // Always try POP for APOP-disabled server
79 if (isset($GLOBALS['pop_auth_use_apop'])) {
80 // Force APOP only, or POP only
81 $pop_auth_use_apop = $must_use_apop = $GLOBALS['pop_auth_use_apop'];
84 // Compat: GLOBALS > function arguments
85 foreach(array('pop_userid', 'pop_passwd', 'pop_server', 'pop_port') as $global) {
86 if(isset($GLOBALS[$global]) && $GLOBALS[$global] !== '')
87 $$global = $GLOBALS[$global];
92 foreach(array('pop_userid', 'pop_server', 'pop_port') as $global)
93 if($$global == '') $die .= 'pop_before_smtp(): $' . $global . ' seems blank' . "\n";
94 if ($die) return ($die);
97 $errno = 0; $errstr = '';
98 $fp = @fsockopen($pop_server, $pop_port, $errno, $errstr, 30);
99 if (! $fp) return ('pop_before_smtp(): ' . $errstr . ' (' . $errno . ')');
101 // Greeting message from server, may include <challenge-string> of APOP
102 $message = fgets($fp, 1024); // 512byte max
103 if (! preg_match('/^\+OK/', $message)) {
105 return ('pop_before_smtp(): Greeting message seems invalid');
108 $challenge = array();
109 if ($pop_auth_use_apop &&
110 (preg_match('/<.*>/', $message, $challenge) || $must_use_apop)) {
111 $method = 'APOP'; // APOP auth
112 if (! isset($challenge[0])) {
113 $response = md5(time()); // Someting worthless but variable
115 $response = md5($challenge[0] . $pop_passwd);
117 fputs($fp, 'APOP ' . $pop_userid . ' ' . $response . "\r\n");
119 $method = 'POP'; // POP auth
120 fputs($fp, 'USER ' . $pop_userid . "\r\n");
121 $message = fgets($fp, 1024); // 512byte max
122 if (! preg_match('/^\+OK/', $message)) {
124 return ('pop_before_smtp(): USER seems invalid');
126 fputs($fp, 'PASS ' . $pop_passwd . "\r\n");
129 $result = fgets($fp, 1024); // 512byte max, auth result
130 $auth = preg_match('/^\+OK/', $result);
133 fputs($fp, 'STAT' . "\r\n"); // STAT, trigger SMTP relay!
134 $message = fgets($fp, 1024); // 512byte max
138 fputs($fp, 'QUIT' . "\r\n");
139 $message = fgets($fp, 1024); // 512byte max, last '+OK'
143 return ('pop_before_smtp(): ' . $method . ' authentication failed');
145 return TRUE; // Success