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