imap.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. <?
  2. /**
  3. ** imap.php
  4. **
  5. ** Functions for the IMAP connection
  6. **
  7. **/
  8. /** Read from the connection until we get either an OK or BAD message. **/
  9. function imapReadData($connection, $pre, $handle_errors, &$response, &$message) {
  10. require ("../config/config.php");
  11. $read = fgets($connection, 1024);
  12. $counter = 0;
  13. while ((substr($read, 0, strlen("$pre OK")) != "$pre OK") &&
  14. (substr($read, 0, strlen("$pre BAD")) != "$pre BAD") &&
  15. (substr($read, 0, strlen("$pre NO")) != "$pre NO")) {
  16. $data[$counter] = $read;
  17. $read = fgets($connection, 1024);
  18. $counter++;
  19. }
  20. if (substr($read, 0, strlen("$pre OK")) == "$pre OK") {
  21. $response = "OK";
  22. $message = trim(substr($read, strlen("$pre OK"), strlen($read)));
  23. } else if (substr($read, 0, strlen("$pre BAD")) == "$pre BAD") {
  24. $response = "BAD";
  25. $message = trim(substr($read, strlen("$pre BAD"), strlen($read)));
  26. } else {
  27. $response = "NO";
  28. $message = trim(substr($read, strlen("$pre NO"), strlen($read)));
  29. }
  30. if ($handle_errors == true) {
  31. if ($response == "NO") {
  32. echo "<BR><B><FONT FACE=\"Arial,Helvetica\" COLOR=FF0000>ERROR</FONT FACE=\"Arial,Helvetica\"><FONT FACE=\"Arial,Helvetica\" COLOR=CC0000>: Could not complete request.</B> </FONT FACE=\"Arial,Helvetica\"><BR><FONT FACE=\"Arial,Helvetica\" COLOR=CC0000>&nbsp;&nbsp;<B>Reason given:</B> $message</FONT FACE=\"Arial,Helvetica\"><BR><BR>";
  33. exit;
  34. } else if ($response == "BAD") {
  35. echo "<BR><B><FONT FACE=\"Arial,Helvetica\" COLOR=FF0000>ERROR</FONT FACE=\"Arial,Helvetica\"><FONT FACE=\"Arial,Helvetica\" COLOR=CC0000>: Bad or malformed request.</B></FONT FACE=\"Arial,Helvetica\"><BR><FONT FACE=\"Arial,Helvetica\" COLOR=CC0000>&nbsp;&nbsp;<B>Server responded:</B> $message</FONT FACE=\"Arial,Helvetica\"><BR><BR>";
  36. exit;
  37. }
  38. }
  39. return $data;
  40. }
  41. /** Parse the incoming mailbox name and return a string that is the FOLDER.MAILBOX **/
  42. function findMailboxName($mailbox) {
  43. $mailbox = trim($mailbox);
  44. if (substr($mailbox, strlen($mailbox)-1, strlen($mailbox)) == "\"") {
  45. $mailbox = substr($mailbox, 0, strlen($mailbox) - 1);
  46. $pos = strrpos($mailbox, "\"") + 1;
  47. $box = substr($mailbox, $pos, strlen($mailbox));
  48. } else {
  49. $box = substr($mailbox, strrpos($mailbox, " ")+1, strlen($mailbox));
  50. }
  51. return $box;
  52. }
  53. /** Finds the delimeter between mailboxes **/
  54. function findMailboxDelimeter($imapConnection) {
  55. fputs($imapConnection, ". list \"\" \"\"\n");
  56. $read = fgets($imapConnection, 1024);
  57. if (strrpos($read, "\"") == strlen($read)) {
  58. $pos = strrpos($read, "\"");
  59. $read = substr($read, 0, $pos);
  60. $pos = strrpos($read, "\"");
  61. $read = substr($read, 0, $pos);
  62. } else {
  63. $pos = strrpos($read, " ");
  64. $read = substr($read, 0, $pos);
  65. }
  66. $pos = strrpos($read, "\"");
  67. $read = substr($read, 0, $pos);
  68. $pos = strrpos($read, "\"");
  69. $read = substr($read, $pos+1, strlen($read));
  70. $tmp = fgets($imapConnection, 1024);
  71. return $read;
  72. }
  73. function getMailboxFlags($mailbox) {
  74. $mailbox = trim($mailbox);
  75. $mailbox = substr($mailbox, strpos($mailbox, "(")+1, strlen($mailbox));
  76. $mailbox = substr($mailbox, 0, strpos($mailbox, ")"));
  77. $mailbox = str_replace("\\", "", $mailbox);
  78. $mailbox = strtolower($mailbox);
  79. $mailbox = explode(" ", $mailbox);
  80. return $mailbox;
  81. }
  82. // handles logging onto an imap server.
  83. function loginToImapServer($username, $key, $imapServerAddress, $hide) {
  84. require("../config/config.php");
  85. $imapConnection = fsockopen($imapServerAddress, 143, &$errorNumber, &$errorString);
  86. if (!$imapConnection) {
  87. echo "Error connecting to IMAP Server.<br>";
  88. echo "$errorNumber : $errorString<br>";
  89. exit;
  90. }
  91. $serverInfo = fgets($imapConnection, 256);
  92. // login
  93. fputs($imapConnection, "a001 LOGIN \"$username\" \"$key\"\n");
  94. $read = fgets($imapConnection, 1024);
  95. if ($debug_login == true) {
  96. echo "SERVER SAYS: $read<BR>";
  97. }
  98. /** If the login attempt was UNsuccessful, lets see why **/
  99. if (substr($read, 0, 7) != "a001 OK") {
  100. if (!$hide) {
  101. if (substr($read, 0, 8) == "a001 BAD") {
  102. echo "Bad request: $read<BR>";
  103. exit;
  104. }
  105. else if (substr($read, 0, 7) == "a001 NO") {
  106. echo "<HTML><BODY BGCOLOR=FFFFFF><BR>";
  107. echo "<TABLE COLS=1 WIDTH=70% NOBORDER BGCOLOR=FFFFFF ALIGN=CENTER>";
  108. echo " <TR>";
  109. echo " <TD BGCOLOR=\"DCDCDC\">";
  110. echo " <FONT FACE=\"Arial,Helvetica\" COLOR=CC0000><B><CENTER>ERROR</CENTER></B></FONT>";
  111. echo " </TD></TR><TR><TD>";
  112. echo " <CENTER><FONT FACE=\"Arial,Helvetica\"><BR>Unknown user or password incorrect.<BR><A HREF=\"login.php\" TARGET=_top>Click here to try again</A>.</FONT></CENTER>";
  113. echo " </TD></TR>";
  114. echo "</TABLE>";
  115. echo "</BODY></HTML>";
  116. exit;
  117. }
  118. else {
  119. echo "Unknown error: $read<BR>";
  120. exit;
  121. }
  122. } else {
  123. exit;
  124. }
  125. }
  126. return $imapConnection;
  127. }
  128. /** must be sent in the form: user.<USER>.<FOLDER> **/
  129. function createFolder($imapConnection, $folder, $type) {
  130. require ("../config/config.php");
  131. if (strtolower($type) == "noselect") {
  132. $dm = findMailboxDelimeter($imapConnection);
  133. $folder = "$folder$dm";
  134. } else {
  135. $folder = "$folder";
  136. }
  137. fputs($imapConnection, "1 create \"$folder\"\n");
  138. $data = imapReadData($imapConnection, "1", false, $response, $message);
  139. if ($response == "NO") {
  140. echo "<BR><B><FONT FACE=\"Arial,Helvetica\" COLOR=FF0000>ERROR</FONT FACE=\"Arial,Helvetica\"><FONT FACE=\"Arial,Helvetica\" COLOR=CC0000>: Could not complete request.</B> </FONT FACE=\"Arial,Helvetica\"><BR><FONT FACE=\"Arial,Helvetica\" COLOR=CC0000>&nbsp;&nbsp;<B>Reason given:</B> $message</FONT FACE=\"Arial,Helvetica\"><BR><BR>";
  141. echo "<FONT FACE=\"Arial,Helvetica\">Possible solutions:<BR><LI>You may need to specify that the folder is a subfolder of INBOX</LI>";
  142. echo "<LI>Try renaming the folder to something different.</LI>";
  143. exit;
  144. } else if ($response == "BAD") {
  145. echo "<B><FONT FACE=\"Arial,Helvetica\" COLOR=FF0000>ERROR</FONT FACE=\"Arial,Helvetica\"><FONT FACE=\"Arial,Helvetica\" COLOR=CC0000>: Bad or malformed request.</B></FONT FACE=\"Arial,Helvetica\"><BR><FONT FACE=\"Arial,Helvetica\" COLOR=CC0000>&nbsp;&nbsp;<B>Server responded:</B> $message</FONT FACE=\"Arial,Helvetica\"><BR><BR>";
  146. exit;
  147. }
  148. fputs($imapConnection, "1 SUBSCRIBE \"$folder\"\n");
  149. $data = imapReadData($imapConnection, "1", true, $response, $message);
  150. }
  151. function removeFolder($imapConnection, $folder) {
  152. fputs($imapConnection, "1 delete \"$folder\"\n");
  153. $data = imapReadData($imapConnection, "1", false, $response, $message);
  154. if ($response == "NO") {
  155. echo "<FONT FACE=\"Arial,Helvetica\" COLOR=FF0000><B>ERROR</B>: Could not delete the folder $folder.</FONT>";
  156. echo "<FONT FACE=\"Arial,Helvetica\" COLOR=\"$color[8]\">Probable causes:</FONT><BR>";
  157. echo "<FONT FACE=\"Arial,Helvetica\" COLOR=\"$color[8]\"><LI>This folder may contain subfolders. Delete all subfolders first</LI></FONT>";
  158. exit;
  159. } else if ($response == "BAD") {
  160. echo "<B><FONT COLOR=FF0000>ERROR</FONT><FONT COLOR=CC0000>: Bad or malformed request.</B></FONT><BR><FONT COLOR=CC0000>&nbsp;&nbsp;<B>Server responded:</B> $message</FONT><BR><BR>";
  161. exit;
  162. }
  163. }
  164. /** Sends back two arrays, boxesFormatted and boxesUnformatted **/
  165. function getFolderList($imapConnection, &$boxes) {
  166. require ("../config/config.php");
  167. if (!function_exists("ary_sort"))
  168. include("../functions/array.php");
  169. /** First we get the inbox **/
  170. fputs($imapConnection, "1 LIST \"\" INBOX\n");
  171. $str = imapReadData($imapConnection, "1", true, $response, $message);
  172. $dm = findMailboxDelimeter($imapConnection);
  173. $g = 0;
  174. for ($i = 0;$i < count($str); $i++) {
  175. $mailbox = chop($str[$i]);
  176. if (substr(findMailboxName($mailbox), 0, 1) != ".") {
  177. $boxes[$g]["RAW"] = $mailbox;
  178. $mailbox = findMailboxName($mailbox);
  179. $periodCount = countCharInString($mailbox, $dm);
  180. // indent the correct number of spaces.
  181. for ($j = 0;$j < $periodCount;$j++)
  182. $boxes[$g]["FORMATTED"] = $boxes[$g]["FORMATTED"] . "&nbsp;&nbsp;";
  183. $boxes[$g]["FORMATTED"] = $boxes[$g]["FORMATTED"] . readShortMailboxName($mailbox, $dm);
  184. $boxes[$g]["UNFORMATTED"] = $mailbox;
  185. $boxes[$g]["ID"] = $g;
  186. $g++;
  187. }
  188. }
  189. /** Next, we get all subscribed folders **/
  190. fputs($imapConnection, "1 LSUB \"\" *\n");
  191. $str = imapReadData($imapConnection, "1", true, $response, $message);
  192. $dm = findMailboxDelimeter($imapConnection);
  193. for ($i = 0;$i < count($str); $i++) {
  194. $mailbox = chop($str[$i]);
  195. if (substr(findMailboxName($mailbox), 0, 1) != ".") {
  196. $boxes[$g]["RAW"] = $mailbox;
  197. $mailbox = findMailboxName($mailbox);
  198. $periodCount = countCharInString($mailbox, $dm);
  199. // indent the correct number of spaces.
  200. for ($j = 0;$j < $periodCount;$j++)
  201. $boxes[$g]["FORMATTED"] = $boxes[$g]["FORMATTED"] . "&nbsp;&nbsp;";
  202. $boxes[$g]["FORMATTED"] = $boxes[$g]["FORMATTED"] . readShortMailboxName($mailbox, $dm);
  203. $boxes[$g]["UNFORMATTED"] = $mailbox;
  204. $boxes[$g]["ID"] = $g;
  205. $g++;
  206. }
  207. }
  208. $original = $boxes;
  209. for ($i = 0; $i < count($original); $i++) {
  210. $boxes[$i]["UNFORMATTED"] = strtolower($boxes[$i]["UNFORMATTED"]);
  211. }
  212. $boxes = ary_sort($boxes, "UNFORMATTED", 1);
  213. for ($i = 0; $i < count($original); $i++) {
  214. for ($j = 0; $j < count($original); $j++) {
  215. if ($boxes[$i]["ID"] == $original[$j]["ID"]) {
  216. $boxes[$i]["UNFORMATTED"] = $original[$j]["UNFORMATTED"];
  217. $boxes[$i]["FORMATTED"] = $original[$j]["FORMATTED"];
  218. $boxes[$i]["RAW"] = $original[$j]["RAW"];
  219. }
  220. }
  221. }
  222. for ($i = 0; $i < count($boxes); $i++) {
  223. if ($boxes[$i]["UNFORMATTED"] == $special_folders[0]) {
  224. $boxesnew[0]["FORMATTED"] = $boxes[$i]["FORMATTED"];
  225. $boxesnew[0]["UNFORMATTED"] = trim($boxes[$i]["UNFORMATTED"]);
  226. $boxesnew[0]["RAW"] = trim($boxes[$i]["RAW"]);
  227. $boxes[$i]["USED"] = true;
  228. }
  229. }
  230. if ($list_special_folders_first == true) {
  231. for ($i = 0; $i < count($boxes); $i++) {
  232. for ($j = 1; $j < count($special_folders); $j++) {
  233. if (substr($boxes[$i]["UNFORMATTED"], 0, strlen($special_folders[$j])) == $special_folders[$j]) {
  234. $pos = count($boxesnew);
  235. $boxesnew[$pos]["FORMATTED"] = $boxes[$i]["FORMATTED"];
  236. $boxesnew[$pos]["RAW"] = trim($boxes[$i]["RAW"]);
  237. $boxesnew[$pos]["UNFORMATTED"] = trim($boxes[$i]["UNFORMATTED"]);
  238. $boxes[$i]["USED"] = true;
  239. }
  240. }
  241. }
  242. }
  243. for ($i = 0; $i < count($boxes); $i++) {
  244. if (($boxes[$i]["UNFORMATTED"] != $special_folders[0]) &&
  245. ($boxes[$i]["UNFORMATTED"] != ".mailboxlist") &&
  246. ($boxes[$i]["USED"] == false)) {
  247. $pos = count($boxesnew);
  248. $boxesnew[$pos]["FORMATTED"] = $boxes[$i]["FORMATTED"];
  249. $boxesnew[$pos]["RAW"] = trim($boxes[$i]["RAW"]);
  250. $boxesnew[$pos]["UNFORMATTED"] = trim($boxes[$i]["UNFORMATTED"]);
  251. $boxes[$i]["USED"] = true;
  252. }
  253. }
  254. $boxes = $boxesnew;
  255. }
  256. function deleteMessages($imapConnection, $a, $b, $numMessages, $trash_folder, $move_to_trash, $auto_expunge, $mailbox) {
  257. /** check if they would like to move it to the trash folder or not */
  258. if (($move_to_trash == true) && (folderExists($imapConnection, $trash_folder))) {
  259. $success = copyMessages($imapConnection, $a, $b, $trash_folder);
  260. if ($success == true)
  261. setMessageFlag($imapConnection, $a, $b, "Deleted");
  262. } else {
  263. setMessageFlag($imapConnection, $a, $b, "Deleted");
  264. }
  265. if ($auto_expunge == true)
  266. expungeBox($imapConnection, $mailbox);
  267. }
  268. function stripComments($line) {
  269. if (strpos($line, ";")) {
  270. $line = substr($line, 0, strpos($line, ";"));
  271. }
  272. if (strpos($line, "(") && strpos($line, ")")) {
  273. $full_line = $full_line . substr($line, 0, strpos($line, "("));
  274. $full_line = $full_line . substr($line, strpos($line, ")")+1, strlen($line) - strpos($line, ")"));
  275. } else {
  276. $full_line = $line;
  277. }
  278. return $full_line;
  279. }
  280. function folderExists($imapConnection, $folderName) {
  281. getFolderList($imapConnection, $folders);
  282. $found = false;
  283. for ($i = 0; ($i < count($folders)) && (!$found); $i++) {
  284. if ($folders[$i]["UNFORMATTED"] == $folderName)
  285. $found = true;
  286. }
  287. return $found;
  288. }
  289. ?>