OSDN Git Service

Added pkwk_mail_notify(): Send a mail to the administrator
[pukiwiki/pukiwiki.git] / lib / mail.php
1 <?php
2 // PukiWiki - Yet another WikiWikiWeb clone.
3 // $Id: mail.php,v 1.5 2005/06/07 14:37:46 henoheno Exp $
4 // Copyright (C)
5 //   2003-2005 PukiWiki Developers Team
6 //   2003      Originally written by upk
7 // License: GPL v2 or (at your option) any later version
8 //
9 // E-mail related functions
10
11 // Send a mail to the administrator
12 function pkwk_mail_notify($subject, $message, $footer = array())
13 {
14         global $smtp_server, $smtp_auth, $notify_to, $notify_from, $notify_header;
15         static $_to, $_headers, $_after_pop;
16
17         // Init and lock
18         if (! isset($_to)) {
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');
28                 }
29
30                 $_to      = $notify_to;
31                 $_headers =
32                         'X-Mailer: PukiWiki/' . S_VERSION .
33                         ' PHP/' . phpversion() . "\r\n" .
34                         'From: ' . $notify_from;
35                         
36                 // Additional header(s) by admin
37                 if ($notify_header != '') $_headers .= "\r\n" . $notify_header;
38
39                 $_after_pop = $smtp_auth;
40         }
41
42         if ($subject == '' || ($message == '' && empty($footer))) return FALSE;
43
44         // Subject:
45         if (isset($footer['PAGE'])) $subject = str_replace('$page', $footer['PAGE'], $subject);
46
47         // Footer
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";
55                 $message .= $_footer;
56         }
57
58         // Wait POP/APOP auth completion
59         if ($_after_pop) {
60                 $result = pop_before_smtp();
61                 if ($result !== TRUE) die($result);
62         }
63
64         ini_set('SMTP', $smtp_server);
65         mb_language(LANG);
66         if ($_headers == '') {
67                 return mb_send_mail($_to, $subject, $message);
68         } else {
69                 return mb_send_mail($_to, $subject, $message, $_headers);
70         }
71 }
72
73 // APOP/POP Before SMTP
74 function pop_before_smtp($pop_userid = '', $pop_passwd = '',
75         $pop_server = 'localhost', $pop_port = 110)
76 {
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'];
82         }
83
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];
88         }
89
90         // Check
91         $die = '';
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);
95
96         // Connect
97         $errno = 0; $errstr = '';
98         $fp = @fsockopen($pop_server, $pop_port, $errno, $errstr, 30);
99         if (! $fp) return ('pop_before_smtp(): ' . $errstr . ' (' . $errno . ')');
100
101         // Greeting message from server, may include <challenge-string> of APOP
102         $message = fgets($fp, 1024); // 512byte max
103         if (! preg_match('/^\+OK/', $message)) {
104                 fclose($fp);
105                 return ('pop_before_smtp(): Greeting message seems invalid');
106         }
107
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
114                 } else {
115                         $response = md5($challenge[0] . $pop_passwd);
116                 }
117                 fputs($fp, 'APOP ' . $pop_userid . ' ' . $response . "\r\n");
118         } else {
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)) {
123                         fclose($fp);
124                         return ('pop_before_smtp(): USER seems invalid');
125                 }
126                 fputs($fp, 'PASS ' . $pop_passwd . "\r\n");
127         }
128
129         $result = fgets($fp, 1024); // 512byte max, auth result
130         $auth   = preg_match('/^\+OK/', $result);
131
132         if ($auth) {
133                 fputs($fp, 'STAT' . "\r\n"); // STAT, trigger SMTP relay!
134                 $message = fgets($fp, 1024); // 512byte max
135         }
136
137         // Disconnect anyway
138         fputs($fp, 'QUIT' . "\r\n");
139         $message = fgets($fp, 1024); // 512byte max, last '+OK'
140         fclose($fp);
141
142         if (! $auth) {
143                 return ('pop_before_smtp(): ' . $method . ' authentication failed');
144         } else {
145                 return TRUE;    // Success
146         }
147 }
148 ?>