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.

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