root/python/ml/ml.php

リビジョン 47, 5.6 kB (コミッタ: sgk, コミット時期: 11 ヶ月 前)

Copyright

  • svn:executable 属性の設定値: *
Line 
1 #!/usr/bin/php
2 <?
3
4   # ml.py -- simple mailing list to just distribute messages in a group.
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     # 'email address (lower case)' => 'real name'
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');    // encoding of this source code.
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   while (!feof(STDIN) && $len > 0) {
58     $s = fread(STDIN, $len);
59     $input .= $s;
60     $len -= strlen($s);
61     unset($s);
62   }
63   if (!feof(STDIN)) {
64     // �᡼���ǡ�������������롣
65     fputs(STDERR, "Mail data size too large.\n");
66 //    exit(65);    // EX_DATAERR
67     exit(0);    // XXX Courier�����顼�򥭥����夷�Ƥ��ޤ���
68   }
69
70
71   //
72   // MIME�ǥ�����  //
73   $decoder = new Mail_mimeDecode($input);
74   if (PEAR::isError($decoder)) {
75     // MIME�ǥ����ɼ����
76     fputs(STDERR, "Could not decode MIME.\n");
77 //    exit(65);    // EX_DATAERR
78     exit(0);    // XXX Courier�����顼�򥭥����夷�Ƥ��ޤ���
79   }
80   unset($input);
81   $given = $decoder->decode(
82     array(
83       'include_bodies' => true,
84       'decode_bodies' => true,
85       'decode_headers' => true
86     )
87   );
88   unset($decoder);
89
90
91   //
92   // ���Ԥθ���  //
93
94   // ����Ԥ򸡾�  if (!isset($given->headers['from'])) {
95     fputs(STDERR, "No 'from' header found.\n");
96 //    exit(65);    // EX_DATAERR
97     exit(0);    // XXX Courier�����顼�򥭥����夷�Ƥ��ޤ���
98   }
99   $from = decodeSingleAddress($given->headers['from']);
100   if ($from == '' || !isset($ML_LIST_SUBSCRIBERS[$from])) {
101     // ����Ԥ��桼���ǤϤʤ���
102     fputs(STDERR, "Sender not allowed.\n");
103 //    exit(65);    // EX_DATAERR
104     exit(0);    // XXX Courier�����顼�򥭥����夷�Ƥ��ޤ���
105   }
106
107   // ����򸡾�XXX isset?
108   if (array_search(ML_LIST_ADDRESS, decodeSomeAddresses($given->headers['to'])) === false
109    && array_search(ML_LIST_ADDRESS, decodeSomeAddresses($given->headers['cc'])) === false) {
110     // �����ML�ǤϤʤ���
111     fputs(STDERR, "Recipient not allowed.\n");
112 //    exit(65);    // EX_DATAERR
113     exit(0);    // XXX Courier�����顼�򥭥����夷�Ƥ��ޤ���
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     var $mime_;
129     var $charset_;
130     var $text_;
131     var $i_;
132
133     function ProcessMimeParts($s) {
134       $this->mime_ = new Mail_mime();
135       $this->charset_ = '';
136       $this->text_ = $s;
137       $this->i_ = 0;
138     }
139
140     function doit($o) {
141       if ($o->ctype_primary == 'multipart') {
142     foreach ($o->parts as $oo)
143       $this->doit($oo);
144       } else
145       if ($o->ctype_primary == 'text') {
146     if ($o->ctype_secondary == 'plain') {
147       if ($this->charset_ != '')
148         return;
149       if (!isset($o->ctype_parameters['charset']))
150         return;
151       $this->charset_ = strtolower($o->ctype_parameters['charset']);
152       $this->text_ .=
153         mb_convert_encoding($o->body, ML_CHARSET, $this->charset_);
154     }
155       } else
156       if ($o->ctype_primary == 'image') {
157     $fn = '';
158     if (isset($o->d_parameters['name']))
159       $fn = $o->d_parameters['name'];
160     else
161     if (isset($o->d_parameters['filename']))
162       $fn = $o->d_parameters['filename'];
163     else
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     function done($subject) {
172       if ($this->charset_ == '') {
173     fputs(STDERR, "No charset found.\n");
174 //    exit(65);    // EX_DATAERR
175     exit(0);    // XXX Courier�����顼�򥭥����夷�Ƥ��ޤ���
176       }
177
178       $this->mime_->setTXTBody($this->text_);
179       $body = $this->mime_->get(
180     array(
181       'text_charset' => $charset
182     )
183       );
184
185       // PEAR�Х���      // Mail_mime::get()�����Ԥ�;�פˤĤ��롣
186       // SMTP::send()�����Ԥ�;�פ���
187       $body = preg_replace("!\r?\n!", "\r\n", $body);    // \r\n���      $body = preg_replace("!\r\n\r\n$!", "", $body);
188
189       $headers = $this->mime_->headers(
190     array(
191       'From' => ML_LIST_ADDRESS,
192       'To' => ML_LIST_ADDRESS,
193       'Subject' => '=?'.ML_CHARSET.'?B?'.base64_encode($subject).'?='
194     )
195       );
196
197       return array($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   list($body, $headers) = $pm->done($subject);
207   unset($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');    // 'mail'���o:�إå������������
221   $o = $mail->send($dest, $headers, $body);
222   if ($o !== True)
223     fputs(STDERR, $o->toString());
224
225 ?>
226
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。