Friendica Communications Platform (please note that this is a clone of the repository at github, issues are handled there) https://friendi.ca
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

307 lines
8.9 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. <?php
  2. require_once('include/html2plain.php');
  3. require_once('include/msgclean.php');
  4. require_once('include/quoteconvert.php');
  5. function email_connect($mailbox,$username,$password) {
  6. if(! function_exists('imap_open'))
  7. return false;
  8. $mbox = @imap_open($mailbox,$username,$password);
  9. return $mbox;
  10. }
  11. function email_poll($mbox,$email_addr) {
  12. if(! ($mbox && $email_addr))
  13. return array();
  14. $search1 = @imap_search($mbox,'FROM "' . $email_addr . '"', SE_UID);
  15. if(! $search1)
  16. $search1 = array();
  17. $search2 = @imap_search($mbox,'TO "' . $email_addr . '"', SE_UID);
  18. if(! $search2)
  19. $search2 = array();
  20. $search3 = @imap_search($mbox,'CC "' . $email_addr . '"', SE_UID);
  21. if(! $search3)
  22. $search3 = array();
  23. $search4 = @imap_search($mbox,'BCC "' . $email_addr . '"', SE_UID);
  24. if(! $search4)
  25. $search4 = array();
  26. $res = array_unique(array_merge($search1,$search2,$search3,$search4));
  27. return $res;
  28. }
  29. function construct_mailbox_name($mailacct) {
  30. $ret = '{' . $mailacct['server'] . ((intval($mailacct['port'])) ? ':' . $mailacct['port'] : '');
  31. $ret .= (($mailacct['ssltype']) ? '/' . $mailacct['ssltype'] . '/novalidate-cert' : '');
  32. $ret .= '}' . $mailacct['mailbox'];
  33. return $ret;
  34. }
  35. function email_msg_meta($mbox,$uid) {
  36. $ret = (($mbox && $uid) ? @imap_fetch_overview($mbox,$uid,FT_UID) : array(array()));
  37. return ((count($ret)) ? $ret[0] : array());
  38. }
  39. function email_msg_headers($mbox,$uid) {
  40. $raw_header = (($mbox && $uid) ? @imap_fetchheader($mbox,$uid,FT_UID) : '');
  41. $raw_header = str_replace("\r",'',$raw_header);
  42. $ret = array();
  43. $h = split("\n",$raw_header);
  44. if(count($h))
  45. foreach($h as $line ) {
  46. if (preg_match("/^[a-zA-Z]/", $line)) {
  47. $key = substr($line,0,strpos($line,':'));
  48. $value = substr($line,strpos($line,':')+1);
  49. $last_entry = strtolower($key);
  50. $ret[$last_entry] = trim($value);
  51. }
  52. else {
  53. $ret[$last_entry] .= ' ' . trim($line);
  54. }
  55. }
  56. return $ret;
  57. }
  58. function email_get_msg($mbox,$uid, $reply) {
  59. $ret = array();
  60. $struc = (($mbox && $uid) ? @imap_fetchstructure($mbox,$uid,FT_UID) : null);
  61. if(! $struc)
  62. return $ret;
  63. // for testing purposes: Collect imported mails
  64. // $file = tempnam("/tmp/friendica2/", "mail-in-");
  65. // file_put_contents($file, json_encode($struc));
  66. if(! $struc->parts) {
  67. $ret['body'] = email_get_part($mbox,$uid,$struc,0, 'html');
  68. $html = $ret['body'];
  69. if (trim($ret['body']) == '')
  70. $ret['body'] = email_get_part($mbox,$uid,$struc,0, 'plain');
  71. else
  72. $ret['body'] = html2bbcode($ret['body']);
  73. }
  74. else {
  75. $text = '';
  76. $html = '';
  77. foreach($struc->parts as $ptop => $p) {
  78. $x = email_get_part($mbox,$uid,$p,$ptop + 1, 'plain');
  79. if($x) $text .= $x;
  80. $x = email_get_part($mbox,$uid,$p,$ptop + 1, 'html');
  81. if($x) $html .= $x;
  82. }
  83. if (trim($html) != '')
  84. $ret['body'] = html2bbcode($html);
  85. else
  86. $ret['body'] = $text;
  87. }
  88. $ret['body'] = removegpg($ret['body']);
  89. $msg = removesig($ret['body']);
  90. $ret['body'] = $msg['body'];
  91. $ret['body'] = convertquote($ret['body'], $reply);
  92. if (trim($html) != '')
  93. $ret['body'] = removelinebreak($ret['body']);
  94. $ret['body'] = unifyattributionline($ret['body']);
  95. return $ret;
  96. }
  97. // At the moment - only return plain/text.
  98. // Later we'll repackage inline images as data url's and make the HTML safe
  99. function email_get_part($mbox,$uid,$p,$partno, $subtype) {
  100. // $partno = '1', '2', '2.1', '2.1.3', etc for multipart, 0 if simple
  101. global $htmlmsg,$plainmsg,$charset,$attachments;
  102. //echo $partno."\n";
  103. // DECODE DATA
  104. $data = ($partno)
  105. ? @imap_fetchbody($mbox,$uid,$partno, FT_UID|FT_PEEK)
  106. : @imap_body($mbox,$uid,FT_UID|FT_PEEK);
  107. // for testing purposes: Collect imported mails
  108. // $file = tempnam("/tmp/friendica2/", "mail-body-");
  109. // file_put_contents($file, $data);
  110. // Any part may be encoded, even plain text messages, so check everything.
  111. if ($p->encoding==4)
  112. $data = quoted_printable_decode($data);
  113. elseif ($p->encoding==3)
  114. $data = base64_decode($data);
  115. // PARAMETERS
  116. // get all parameters, like charset, filenames of attachments, etc.
  117. $params = array();
  118. if ($p->parameters)
  119. foreach ($p->parameters as $x)
  120. $params[strtolower($x->attribute)] = $x->value;
  121. if (isset($p->dparameters) and $p->dparameters)
  122. foreach ($p->dparameters as $x)
  123. $params[strtolower($x->attribute)] = $x->value;
  124. // ATTACHMENT
  125. // Any part with a filename is an attachment,
  126. // so an attached text file (type 0) is not mistaken as the message.
  127. if ((isset($params['filename']) and $params['filename']) || (isset($params['name']) and $params['name'])) {
  128. // filename may be given as 'Filename' or 'Name' or both
  129. $filename = ($params['filename'])? $params['filename'] : $params['name'];
  130. // filename may be encoded, so see imap_mime_header_decode()
  131. $attachments[$filename] = $data; // this is a problem if two files have same name
  132. }
  133. // TEXT
  134. if ($p->type == 0 && $data) {
  135. // Messages may be split in different parts because of inline attachments,
  136. // so append parts together with blank row.
  137. if (strtolower($p->subtype)==$subtype) {
  138. $data = iconv($params['charset'], 'UTF-8//IGNORE', $data);
  139. return (trim($data) ."\n\n");
  140. } else
  141. $data = '';
  142. // $htmlmsg .= $data ."<br><br>";
  143. $charset = $params['charset']; // assume all parts are same charset
  144. }
  145. // EMBEDDED MESSAGE
  146. // Many bounce notifications embed the original message as type 2,
  147. // but AOL uses type 1 (multipart), which is not handled here.
  148. // There are no PHP functions to parse embedded messages,
  149. // so this just appends the raw source to the main message.
  150. // elseif ($p->type==2 && $data) {
  151. // $plainmsg .= $data."\n\n";
  152. // }
  153. // SUBPART RECURSION
  154. if (isset($p->parts) and $p->parts) {
  155. $x = "";
  156. foreach ($p->parts as $partno0=>$p2) {
  157. $x .= email_get_part($mbox,$uid,$p2,$partno . '.' . ($partno0+1), $subtype); // 1.2, 1.2.1, etc.
  158. //if($x)
  159. // return $x;
  160. }
  161. return $x;
  162. }
  163. }
  164. function email_header_encode($in_str, $charset) {
  165. $out_str = $in_str;
  166. $need_to_convert = false;
  167. for($x = 0; $x < strlen($in_str); $x ++) {
  168. if((ord($in_str[$x]) == 0) || ((ord($in_str[$x]) > 128))) {
  169. $need_to_convert = true;
  170. }
  171. }
  172. if(! $need_to_convert)
  173. return $in_str;
  174. if ($out_str && $charset) {
  175. // define start delimimter, end delimiter and spacer
  176. $end = "?=";
  177. $start = "=?" . $charset . "?B?";
  178. $spacer = $end . "\r\n " . $start;
  179. // determine length of encoded text within chunks
  180. // and ensure length is even
  181. $length = 75 - strlen($start) - strlen($end);
  182. /*
  183. [EDIT BY danbrown AT php DOT net: The following
  184. is a bugfix provided by (gardan AT gmx DOT de)
  185. on 31-MAR-2005 with the following note:
  186. "This means: $length should not be even,
  187. but divisible by 4. The reason is that in
  188. base64-encoding 3 8-bit-chars are represented
  189. by 4 6-bit-chars. These 4 chars must not be
  190. split between two encoded words, according
  191. to RFC-2047.
  192. */
  193. $length = $length - ($length % 4);
  194. // encode the string and split it into chunks
  195. // with spacers after each chunk
  196. $out_str = base64_encode($out_str);
  197. $out_str = chunk_split($out_str, $length, $spacer);
  198. // remove trailing spacer and
  199. // add start and end delimiters
  200. $spacer = preg_quote($spacer);
  201. $out_str = preg_replace("/" . $spacer . "$/", "", $out_str);
  202. $out_str = $start . $out_str . $end;
  203. }
  204. return $out_str;
  205. }
  206. function email_send($addr, $subject, $headers, $item) {
  207. //$headers .= 'MIME-Version: 1.0' . "\n";
  208. //$headers .= 'Content-Type: text/html; charset=UTF-8' . "\n";
  209. //$headers .= 'Content-Type: text/plain; charset=UTF-8' . "\n";
  210. //$headers .= 'Content-Transfer-Encoding: 8bit' . "\n\n";
  211. $part = uniqid("", true);
  212. $html = prepare_body($item);
  213. $headers .= "Mime-Version: 1.0\n";
  214. $headers .= 'Content-Type: multipart/alternative; boundary="=_'.$part.'"'."\n\n";
  215. $body = "\n--=_".$part."\n";
  216. $body .= "Content-Transfer-Encoding: 8bit\n";
  217. $body .= "Content-Type: text/plain; charset=utf-8; format=flowed\n\n";
  218. $body .= html2plain($html)."\n";
  219. $body .= "--=_".$part."\n";
  220. $body .= "Content-Transfer-Encoding: 8bit\n";
  221. $body .= "Content-Type: text/html; charset=utf-8\n\n";
  222. $body .= '<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">'.$html."</body></html>\n";
  223. $body .= "--=_".$part."--";
  224. //$message = '<html><body>' . $html . '</body></html>';
  225. //$message = html2plain($html);
  226. logger('notifier: email delivery to ' . $addr);
  227. mail($addr, $subject, $body, $headers);
  228. }
  229. function iri2msgid($iri) {
  230. if (!strpos($iri, "@"))
  231. $msgid = preg_replace("/urn:(\S+):(\S+)\.(\S+):(\d+):(\S+)/i", "urn!$1!$4!$5@$2.$3", $iri);
  232. else
  233. $msgid = $iri;
  234. return($msgid);
  235. }
  236. function msgid2iri($msgid) {
  237. if (strpos($msgid, "@"))
  238. $iri = preg_replace("/urn!(\S+)!(\d+)!(\S+)@(\S+)\.(\S+)/i", "urn:$1:$4.$5:$2:$3", $msgid);
  239. else
  240. $iri = $msgid;
  241. return($iri);
  242. }