PageRenderTime 90ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/mail.php

https://github.com/miya5n/pukiwiki
PHP | 162 lines | 118 code | 21 blank | 23 comment | 44 complexity | 26d2e77e3ba3f655e4ec2ab1aff81ba8 MD5 | raw file
Possible License(s): GPL-2.0
  1. <?php
  2. // PukiWiki - Yet another WikiWikiWeb clone.
  3. // $Id: mail.php,v 1.12 2007/02/21 14:39:05 henoheno Exp $
  4. // Copyright (C)
  5. // 2003-2007 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. // Send a mail to the administrator
  11. function pkwk_mail_notify($subject, $message, $summary = array(), $summary_position = FALSE)
  12. {
  13. global $smtp_server, $smtp_auth, $notify_to, $notify_from, $notify_header;
  14. static $_to, $_headers, $_after_pop;
  15. // Init and lock
  16. if (! isset($_to)) {
  17. if (! PKWK_OPTIMISE) {
  18. // Validation check
  19. $func = 'pkwk_mail_notify(): ';
  20. $mail_regex = '/[^@]+@[^@]{1,}\.[^@]{2,}/';
  21. if (! preg_match($mail_regex, $notify_to))
  22. die($func . 'Invalid $notify_to');
  23. if (! preg_match($mail_regex, $notify_from))
  24. die($func . 'Invalid $notify_from');
  25. if ($notify_header != '') {
  26. $header_regex = "/\A(?:\r\n|\r|\n)|\r\n\r\n/";
  27. if (preg_match($header_regex, $notify_header))
  28. die($func . 'Invalid $notify_header');
  29. if (preg_match('/^From:/im', $notify_header))
  30. die($func . 'Redundant \'From:\' in $notify_header');
  31. }
  32. }
  33. $_to = $notify_to;
  34. $_headers =
  35. 'X-Mailer: PukiWiki/' . S_VERSION .
  36. ' PHP/' . phpversion() . "\r\n" .
  37. 'From: ' . $notify_from;
  38. // Additional header(s) by admin
  39. if ($notify_header != '') $_headers .= "\r\n" . $notify_header;
  40. $_after_pop = $smtp_auth;
  41. }
  42. if ($subject == '' || ($message == '' && empty($summary))) return FALSE;
  43. // Subject:
  44. if (isset($summary['PAGE'])) $subject = str_replace('$page', $summary['PAGE'], $subject);
  45. // Summary
  46. if (isset($summary['REMOTE_ADDR'])) $summary['REMOTE_ADDR'] = & $_SERVER['REMOTE_ADDR'];
  47. if (isset($summary['USER_AGENT']))
  48. $summary['USER_AGENT'] = '(' . UA_PROFILE . ') ' . UA_NAME . '/' . UA_VERS;
  49. if (! empty($summary)) {
  50. $_separator = ($message == '') ? '' : str_repeat('-', 30) . "\n";
  51. foreach($summary as $key => $value) {
  52. $summary[$key] = $key . ': ' . $value . "\n";
  53. }
  54. // Top or Bottom
  55. if ($summary_position) {
  56. $message = implode('', $summary) . $_separator . "\n" . $message;
  57. } else {
  58. $message = $message . "\n" . $_separator . implode('', $summary);
  59. }
  60. unset($summary);
  61. }
  62. // Wait POP/APOP auth completion
  63. if ($_after_pop) {
  64. $result = pop_before_smtp();
  65. if ($result !== TRUE) die($result);
  66. }
  67. ini_set('SMTP', $smtp_server);
  68. mb_language(LANG);
  69. if ($_headers == '') {
  70. return mb_send_mail($_to, $subject, $message);
  71. } else {
  72. return mb_send_mail($_to, $subject, $message, $_headers);
  73. }
  74. }
  75. // APOP/POP Before SMTP
  76. function pop_before_smtp($pop_userid = '', $pop_passwd = '',
  77. $pop_server = 'localhost', $pop_port = 110)
  78. {
  79. $pop_auth_use_apop = TRUE; // Always try APOP, by default
  80. $must_use_apop = FALSE; // Always try POP for APOP-disabled server
  81. if (isset($GLOBALS['pop_auth_use_apop'])) {
  82. // Force APOP only, or POP only
  83. $pop_auth_use_apop = $must_use_apop = $GLOBALS['pop_auth_use_apop'];
  84. }
  85. // Compat: GLOBALS > function arguments
  86. foreach(array('pop_userid', 'pop_passwd', 'pop_server', 'pop_port') as $global) {
  87. if(isset($GLOBALS[$global]) && $GLOBALS[$global] !== '')
  88. $$global = $GLOBALS[$global];
  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. // Connect
  96. $errno = 0; $errstr = '';
  97. $fp = @fsockopen($pop_server, $pop_port, $errno, $errstr, 30);
  98. if (! $fp) return ('pop_before_smtp(): ' . $errstr . ' (' . $errno . ')');
  99. // Greeting message from server, may include <challenge-string> of APOP
  100. $message = fgets($fp, 1024); // 512byte max
  101. if (! preg_match('/^\+OK/', $message)) {
  102. fclose($fp);
  103. return ('pop_before_smtp(): Greeting message seems invalid');
  104. }
  105. $challenge = array();
  106. if ($pop_auth_use_apop &&
  107. (preg_match('/<.*>/', $message, $challenge) || $must_use_apop)) {
  108. $method = 'APOP'; // APOP auth
  109. if (! isset($challenge[0])) {
  110. $response = md5(time()); // Someting worthless but variable
  111. } else {
  112. $response = md5($challenge[0] . $pop_passwd);
  113. }
  114. fputs($fp, 'APOP ' . $pop_userid . ' ' . $response . "\r\n");
  115. } else {
  116. $method = 'POP'; // POP auth
  117. fputs($fp, 'USER ' . $pop_userid . "\r\n");
  118. $message = fgets($fp, 1024); // 512byte max
  119. if (! preg_match('/^\+OK/', $message)) {
  120. fclose($fp);
  121. return ('pop_before_smtp(): USER seems invalid');
  122. }
  123. fputs($fp, 'PASS ' . $pop_passwd . "\r\n");
  124. }
  125. $result = fgets($fp, 1024); // 512byte max, auth result
  126. $auth = preg_match('/^\+OK/', $result);
  127. if ($auth) {
  128. fputs($fp, 'STAT' . "\r\n"); // STAT, trigger SMTP relay!
  129. $message = fgets($fp, 1024); // 512byte max
  130. }
  131. // Disconnect anyway
  132. fputs($fp, 'QUIT' . "\r\n");
  133. $message = fgets($fp, 1024); // 512byte max, last '+OK'
  134. fclose($fp);
  135. if (! $auth) {
  136. return ('pop_before_smtp(): ' . $method . ' authentication failed');
  137. } else {
  138. return TRUE; // Success
  139. }
  140. }
  141. ?>