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