| 1 |
#!/usr/bin/php |
|---|
| 2 |
<? |
|---|
| 3 |
|
|---|
| 4 |
|
|---|
| 5 |
# Copyright (c) 2007 Shigeru KANEMOTO |
|---|
| 6 |
# All rights reserved. |
|---|
| 7 |
|
|---|
| 8 |
define('ML_LIST_ADDRESS', 'list@example.com'); |
|---|
| 9 |
$ML_LIST_SUBSCRIBERS = array( |
|---|
| 10 |
|
|---|
| 11 |
"somebody@example.com" => "�ʤޤ�" |
|---|
| 12 |
); |
|---|
| 13 |
|
|---|
| 14 |
define('ML_EMAIL_MAX_SIZE', 100000); |
|---|
| 15 |
define('ML_CHARSET', 'iso-2022-jp'); |
|---|
| 16 |
define('ML_CODE_CHARSET', 'euc-jp'); |
|---|
| 17 |
|
|---|
| 18 |
//////////////////////////////////////////////////////////////////////////////// |
|---|
| 19 |
|
|---|
| 20 |
// �饤�֥� |
|---|
| 21 |
require_once('PEAR.php'); |
|---|
| 22 |
require_once('Mail.php'); |
|---|
| 23 |
require_once('Mail/mime.php'); |
|---|
| 24 |
require_once('Mail/mimeDecode.php'); |
|---|
| 25 |
require_once('Mail/RFC822.php'); |
|---|
| 26 |
|
|---|
| 27 |
function decodeSingleAddress($s) { |
|---|
| 28 |
$a = Mail_RFC822::parseAddressList($s); |
|---|
| 29 |
if (PEAR::isError($a) || count($a) != 1) |
|---|
| 30 |
return ''; |
|---|
| 31 |
$a = $a[0]; |
|---|
| 32 |
if ($a->mailbox == '') |
|---|
| 33 |
return ''; |
|---|
| 34 |
return strtolower($a->mailbox . '@' . $a->host); |
|---|
| 35 |
} |
|---|
| 36 |
|
|---|
| 37 |
function decodeSomeAddresses($s) { |
|---|
| 38 |
$a = Mail_RFC822::parseAddressList($s); |
|---|
| 39 |
if (PEAR::isError($a)) |
|---|
| 40 |
return array(); |
|---|
| 41 |
$aa = array(); |
|---|
| 42 |
foreach ($a as $v) { |
|---|
| 43 |
if ($v->mailbox != '') |
|---|
| 44 |
$aa[] = strtolower($v->mailbox . '@' . $v->host); |
|---|
| 45 |
} |
|---|
| 46 |
return $aa; |
|---|
| 47 |
} |
|---|
| 48 |
|
|---|
| 49 |
|
|---|
| 50 |
|
|---|
| 51 |
|
|---|
| 52 |
|
|---|
| 53 |
|
|---|
| 54 |
|
|---|
| 55 |
$input = ''; |
|---|
| 56 |
$len = ML_EMAIL_MAX_SIZE; |
|---|
| 57 |
feof(STDIN) && $len > 0) { |
|---|
| 58 |
$s = fread(STDIN, $len); |
|---|
| 59 |
$input .= $s; |
|---|
| 60 |
$len -= strlen($s); |
|---|
| 61 |
$s); |
|---|
| 62 |
|
|---|
| 63 |
feof(STDIN)) { |
|---|
| 64 |
|
|---|
| 65 |
fputs(STDERR, "Mail data size too large.\n"); |
|---|
| 66 |
|
|---|
| 67 |
exit(0); |
|---|
| 68 |
} |
|---|
| 69 |
|
|---|
| 70 |
|
|---|
| 71 |
|
|---|
| 72 |
|
|---|
| 73 |
$decoder = new Mail_mimeDecode($input); |
|---|
| 74 |
PEAR::isError($decoder)) { |
|---|
| 75 |
|
|---|
| 76 |
fputs(STDERR, "Could not decode MIME.\n"); |
|---|
| 77 |
|
|---|
| 78 |
exit(0); |
|---|
| 79 |
} |
|---|
| 80 |
$input); |
|---|
| 81 |
$given = $decoder->decode( |
|---|
| 82 |
|
|---|
| 83 |
'include_bodies' => true, |
|---|
| 84 |
'decode_bodies' => true, |
|---|
| 85 |
'decode_headers' => true |
|---|
| 86 |
) |
|---|
| 87 |
|
|---|
| 88 |
$decoder); |
|---|
| 89 |
|
|---|
| 90 |
|
|---|
| 91 |
|
|---|
| 92 |
|
|---|
| 93 |
|
|---|
| 94 |
|
|---|
| 95 |
fputs(STDERR, "No 'from' header found.\n"); |
|---|
| 96 |
|
|---|
| 97 |
exit(0); |
|---|
| 98 |
} |
|---|
| 99 |
$from = decodeSingleAddress($given->headers['from']); |
|---|
| 100 |
$from == '' || !isset($ML_LIST_SUBSCRIBERS[$from])) { |
|---|
| 101 |
|
|---|
| 102 |
fputs(STDERR, "Sender not allowed.\n"); |
|---|
| 103 |
|
|---|
| 104 |
exit(0); |
|---|
| 105 |
} |
|---|
| 106 |
|
|---|
| 107 |
|
|---|
| 108 |
if (array_search(ML_LIST_ADDRESS, decodeSomeAddresses($given->headers['to'])) === false |
|---|
| 109 |
&& array_search(ML_LIST_ADDRESS, decodeSomeAddresses($given->headers['cc'])) === false) { |
|---|
| 110 |
|
|---|
| 111 |
fputs(STDERR, "Recipient not allowed.\n"); |
|---|
| 112 |
|
|---|
| 113 |
exit(0); |
|---|
| 114 |
} |
|---|
| 115 |
|
|---|
| 116 |
|
|---|
| 117 |
|
|---|
| 118 |
|
|---|
| 119 |
|
|---|
| 120 |
$subject = $given->headers['subject']; |
|---|
| 121 |
$subject = preg_replace('!^(re(\d+|\[\d+\])?[:>]\s*)+!i', 'Re:', $subject); |
|---|
| 122 |
|
|---|
| 123 |
|
|---|
| 124 |
|
|---|
| 125 |
|
|---|
| 126 |
|
|---|
| 127 |
class ProcessMimeParts { |
|---|
| 128 |
$mime_; |
|---|
| 129 |
$charset_; |
|---|
| 130 |
$text_; |
|---|
| 131 |
$i_; |
|---|
| 132 |
|
|---|
| 133 |
ProcessMimeParts($s) { |
|---|
| 134 |
$this->mime_ = new Mail_mime(); |
|---|
| 135 |
$this->charset_ = ''; |
|---|
| 136 |
$this->text_ = $s; |
|---|
| 137 |
$this->i_ = 0; |
|---|
| 138 |
|
|---|
| 139 |
|
|---|
| 140 |
doit($o) { |
|---|
| 141 |
$o->ctype_primary == 'multipart') { |
|---|
| 142 |
$o->parts as $oo) |
|---|
| 143 |
$this->doit($oo); |
|---|
| 144 |
|
|---|
| 145 |
$o->ctype_primary == 'text') { |
|---|
| 146 |
$o->ctype_secondary == 'plain') { |
|---|
| 147 |
$this->charset_ != '') |
|---|
| 148 |
|
|---|
| 149 |
$o->ctype_parameters['charset'])) |
|---|
| 150 |
|
|---|
| 151 |
$this->charset_ = strtolower($o->ctype_parameters['charset']); |
|---|
| 152 |
$this->text_ .= |
|---|
| 153 |
mb_convert_encoding($o->body, ML_CHARSET, $this->charset_); |
|---|
| 154 |
|
|---|
| 155 |
|
|---|
| 156 |
$o->ctype_primary == 'image') { |
|---|
| 157 |
$fn = ''; |
|---|
| 158 |
$o->d_parameters['name'])) |
|---|
| 159 |
$fn = $o->d_parameters['name']; |
|---|
| 160 |
|
|---|
| 161 |
$o->d_parameters['filename'])) |
|---|
| 162 |
$fn = $o->d_parameters['filename']; |
|---|
| 163 |
|
|---|
| 164 |
$fn = sprintf("%d.jpg", $this->i_++); |
|---|
| 165 |
$this->mime_->addAttachment( |
|---|
| 166 |
$o->body, $o->ctype_primary . '/' . $o->ctype_secondary, |
|---|
| 167 |
$fn, false); |
|---|
| 168 |
|
|---|
| 169 |
|
|---|
| 170 |
|
|---|
| 171 |
done($subject) { |
|---|
| 172 |
$this->charset_ == '') { |
|---|
| 173 |
fputs(STDERR, "No charset found.\n"); |
|---|
| 174 |
|
|---|
| 175 |
exit(0); |
|---|
| 176 |
} |
|---|
| 177 |
|
|---|
| 178 |
$this->mime_->setTXTBody($this->text_); |
|---|
| 179 |
$body = $this->mime_->get( |
|---|
| 180 |
|
|---|
| 181 |
'text_charset' => $charset |
|---|
| 182 |
) |
|---|
| 183 |
|
|---|
| 184 |
|
|---|
| 185 |
|
|---|
| 186 |
|
|---|
| 187 |
$body = preg_replace("!\r?\n!", "\r\n", $body); |
|---|
| 188 |
|
|---|
| 189 |
$headers = $this->mime_->headers( |
|---|
| 190 |
|
|---|
| 191 |
'From' => ML_LIST_ADDRESS, |
|---|
| 192 |
'To' => ML_LIST_ADDRESS, |
|---|
| 193 |
'Subject' => '=?'.ML_CHARSET.'?B?'.base64_encode($subject).'?=' |
|---|
| 194 |
) |
|---|
| 195 |
|
|---|
| 196 |
|
|---|
| 197 |
$body, $headers); |
|---|
| 198 |
|
|---|
| 199 |
|
|---|
| 200 |
|
|---|
| 201 |
$pm = new ProcessMimeParts( |
|---|
| 202 |
"[".mb_convert_encoding($ML_LIST_SUBSCRIBERS[$from], ML_CHARSET, ML_CODE_CHARSET)."]\n" |
|---|
| 203 |
); |
|---|
| 204 |
|
|---|
| 205 |
$pm->doit($given); |
|---|
| 206 |
$body, $headers) = $pm->done($subject); |
|---|
| 207 |
$pm); |
|---|
| 208 |
|
|---|
| 209 |
|
|---|
| 210 |
|
|---|
| 211 |
|
|---|
| 212 |
|
|---|
| 213 |
unset($ML_LIST_SUBSCRIBERS[$from]); |
|---|
| 214 |
$dest = array_keys($ML_LIST_SUBSCRIBERS); |
|---|
| 215 |
|
|---|
| 216 |
|
|---|
| 217 |
|
|---|
| 218 |
|
|---|
| 219 |
|
|---|
| 220 |
$mail = Mail::factory('smtp'); |
|---|
| 221 |
$o = $mail->send($dest, $headers, $body); |
|---|
| 222 |
$o !== True) |
|---|
| 223 |
fputs(STDERR, $o->toString()); |
|---|
| 224 |
|
|---|
| 225 |
?> |
|---|
| 226 |
|
|---|