3 Implements an EMail-to-Wiki gateway, if you assign it a POP3 / IMAP
4 account and/or MBOX spool file to read from. An mail sent to there
5 will create a new page or append to an existing one, if either the
6 To: field or the Subject: contains a WikiWord (everything else will
7 get written onto "SpammerSubmissions"). Enriched mail bodys will be
8 checked for convertability into WikiMarkup, but HTML emails and any
9 multipart/* objects will get rejected outright.
13 // define("MAIL2WIKI_POP3", "mailuser:pw@mail.example.com"); // for POP3+IMAP
14 // define("MAIL2WIKI_MBOX", "/var/spool/mail/towiki"); // from local mbox file
15 define("MAIL2WIKI_SPAM", "SpammerSubmissions"); // to save rejected stuff onto (as-is, in rfc822 format); you could also set this to false or zero to disable
16 define("MAIL2WIKI_ATONCE", 50); // max amount of mails to process in one run
22 #-- check remote mail account
23 if (defined("MAIL2WIKI_POP3")) {
26 $username = strtok(MAIL2WIKI_POP3, ":");
27 $password = strtok("@");
28 $mailserver = strtok("/");
29 ($box = strtok(".")) or
31 if (($mx = imap_open('{'."$mailserver/pop3:110}$box", $username, $password))
32 or ($mx = imap_open('{'."$mailserver}$box", $username, $password)))
34 echo "[$cron]: opened connection to $mailserver to check for submissions\n";
36 #-- loop through all messages
37 $msg_count = imap_num_msg($mx);
38 echo "[$cron]: $msg_count found\n";
39 if ($msg_count > MAIL2WIKI_ATONCE * 1.1) {
40 $msg_count = MAIL2WIKI_ATONCE;
41 echo "[$cron]: proeccsing only $msg_count now\n";
43 for ($msg=1; $msg<=$msg_count; $msg++) {
46 $mbox = imap_fetchheader($server, $msg, FT_PREFETCHTEXT);
47 imap_delete($server, $msg);
49 #-- into our spool array
53 #-- close, delete messages
60 #-- read on Unix server
61 if (defined("MAIL2WIKI_MBOX")) {
62 // open for read-write or forget it
63 if ($f = fopen(MAIL2WIKI_MBOX, "rw")) {
66 #-- try to read 2MB file,
67 # but fail if we really can do that (this is far too large!!)
68 $mbox = fread($f, 1<<21);
69 if (strlen($mbox) >= (1<<21)) {
73 #-- split mbox file into individual messages, append to $incoming[] list
75 and ($mbox = preg_split("/^From [^\s]+@[^\s]+ \w\w\w?,? \w\w\w \d\d \d\d:\d\d:\d\d \d\d\d\d$/m",
77 #-- append to processing list
78 $incoming = array_merge($incoming, $mbox);
81 #-- clear inbox file completely
93 #-- store it --------------------------------------------------------------
95 echo "[$cron]: storing " . count($incoming) . " pages\n";
96 $rx_wiki = "/^([".EWIKI_CHARS_U."]+[".EWIKI_CHARS_L."]+){2,})$/";
98 foreach ($incoming as $mbox) {
100 #-- convert line breaks
101 $mbox = preg_replace('/(\r\n|\r)/', "\n", $mbox);
102 $page = substr($mbox, strpos($mbox, "\n\n")+2); // content body
104 #-- check for WikiWord
106 if (preg_match('/^To:\s*"(.+)"|^To:\s*<?(.+?)@/i', $mbox, $uu)) {
108 $ok = preg_match($rx_wiki, $uu[1]);
110 elseif ($id=$uu[2]) {
111 $ok = preg_match($rx_wiki, $uu[2]);
114 if (!$ok && preg_match('/^Subject:[ ]*([^\s]+)[ ]*$/i', $mbox, $uu)) {
115 $ok = preg_match($rx_wiki, $id=$uu[1]);
118 #-- check content-type
119 $ok = $ok && preg_match('#^Content-Type:\s*([^.+0-9_a-z/]+)#i', $mbox, $uu);
121 $ct = strtok(strtolower($uu[1]), "/");
127 if (($st == "plain") || strstr($st, "wiki")) {
130 elseif ($st == "enriched") {
131 // how to decode that?
140 #-- save full msg as spam
142 echo "[$cron]: spam/unwanted content detected\n";
143 if (MAIL2WIKI_SPAM) {
144 ewiki_db::APPEND(MAIL2WIKI_SPAM, "\n----\n$mbox\n");
148 #-- save as new Wiki page
149 elseif (!ewiki_db::GET($id)) {
150 ewiki_db::APPEND($id, $page);
152 #-- as comment to existing one
154 if (preg_match("/^From: [^\n]+/m", $mbox, $uu)) {
155 $from = from_mail_or_link($uu[1]);
162 echo "[$cron]: storing mail from '$from' onto page '$id'\n";
164 ewiki_db::APPEND($id, "\n\n$from$page\n");
173 #-- return a WikiPageUserName or [name|email@...] string back
174 function from_mail_or_link($from) {
175 $from = strtr($from, "<>\"\'", " ");
176 $l = strpos($from, "@");
177 if ($l = strrpos($from, " ", $l)) {
178 $name = substr($from, 0, $l);
179 $mail = substr($from, $l+1);
180 $wiki = str_replace(" ", "", $name);
181 if (ewiki_db::GET($wiki)) {
186 return("$wiki|$email");