information about changes
[squirrelmail.git] / functions / imap_general.php
CommitLineData
59177427 1<?php
bccadd02 2
35586184 3/**
a6fd80f5 4 * imap_general.php
35586184 5 *
6c84ba1e 6 * Copyright (c) 1999-2005 The SquirrelMail Project Team
15e6162e 7 * Licensed under the GNU GPL. For full terms see the file COPYING.
35586184 8 *
15e6162e 9 * This implements all functions that do general imap functions.
35586184 10 *
eb19bc67 11 * @version $Id$
d6c32258 12 * @package squirrelmail
eb19bc67 13 * @subpackage imap
35586184 14 */
15
d6c32258 16/** Includes.. */
b68edc75 17require_once(SM_PATH . 'functions/page_header.php');
47a29326 18require_once(SM_PATH . 'functions/auth.php');
19
35586184 20
48af4b64 21/**
22 * Generates a new session ID by incrementing the last one used;
23 * this ensures that each command has a unique ID.
b35a5862 24 * @param bool $unique_id (since 1.3.0) controls use of unique
25 * identifiers/message sequence numbers in IMAP commands. See IMAP
26 * rfc 'UID command' chapter.
48af4b64 27 * @return string IMAP session id of the form 'A000'.
b35a5862 28 * @since 1.2.0
48af4b64 29 */
2aca19a1 30function sqimap_session_id($unique_id = FALSE) {
31 static $sqimap_session_id = 1;
32
487daa81 33 if (!$unique_id) {
098ea084 34 return( sprintf("A%03d", $sqimap_session_id++) );
487daa81 35 } else {
098ea084 36 return( sprintf("A%03d", $sqimap_session_id++) . ' UID' );
487daa81 37 }
9c737111 38}
39
48af4b64 40/**
3411d4ec 41 * Both send a command and accept the result from the command.
42 * This is to allow proper session number handling.
b35a5862 43 * @param resource $imap_stream imap connection resource
44 * @param string $query imap command
45 * @param boolean $handle_errors see sqimap_retrieve_imap_response()
46 * @param mixed $response
47 * @param mixed $message
48 * @param boolean $unique_id (since 1.3.0) controls use of unique
49 * identifiers/message sequence numbers in IMAP commands. See IMAP
50 * rfc 'UID command' chapter.
51 * @return mixed returns false on imap error. displays error message
52 * if imap stream is not available.
53 * @since 1.2.3
3411d4ec 54 */
487daa81 55function sqimap_run_command_list ($imap_stream, $query, $handle_errors, &$response, &$message, $unique_id = false) {
c5809184 56 if ($imap_stream) {
098ea084 57 $sid = sqimap_session_id($unique_id);
58 fputs ($imap_stream, $sid . ' ' . $query . "\r\n");
bc78cc6e 59 $tag_uid_a = explode(' ',trim($sid));
60 $tag = $tag_uid_a[0];
0dc05a81 61 $read = sqimap_retrieve_imap_response ($imap_stream, $tag, $handle_errors, $response, $message, $query );
bc78cc6e 62 /* get the response and the message */
63 $message = $message[$tag];
1e0a2f0e 64 $response = $response[$tag];
bc78cc6e 65 return $read[$tag];
c5809184 66 } else {
67 global $squirrelmail_language, $color;
68 set_up_language($squirrelmail_language);
69 require_once(SM_PATH . 'functions/display_messages.php');
6fd95361 70 $string = "<b><font color=\"$color[2]\">\n" .
c5809184 71 _("ERROR : No available imapstream.") .
72 "</b></font>\n";
73 error_box($string,$color);
098ea084 74 return false;
c5809184 75 }
1c72b151 76}
77
b35a5862 78/**
79 * @param resource $imap_stream imap connection resource
80 * @param string $query imap command
81 * @param boolean $handle_errors see sqimap_retrieve_imap_response()
82 * @param mixed $response
83 * @param mixed $message
84 * @param boolean $unique_id (since 1.3.0) controls use of unique
85 * identifiers/message sequence numbers in IMAP commands. See IMAP
86 * rfc 'UID command' chapter.
87 * @param mixed $filter (since 1.4.1 and 1.5.0)
88 * @param mixed $outputstream (since 1.4.1 and 1.5.0)
89 * @param mixed $no_return (since 1.4.1 and 1.5.0)
90 * @return mixed returns false on imap error. displays error message
91 * if imap stream is not available.
92 * @since 1.2.3
93 */
1e0a2f0e 94function sqimap_run_command ($imap_stream, $query, $handle_errors, &$response,
7c7b74b3 95 &$message, $unique_id = false,$filter=false,
96 $outputstream=false,$no_return=false) {
c5809184 97 if ($imap_stream) {
98 $sid = sqimap_session_id($unique_id);
1e0a2f0e 99 fputs ($imap_stream, $sid . ' ' . $query . "\r\n");
bc78cc6e 100 $tag_uid_a = explode(' ',trim($sid));
101 $tag = $tag_uid_a[0];
1e0a2f0e 102
bc78cc6e 103 $read = sqimap_read_data ($imap_stream, $tag, $handle_errors, $response,
7c7b74b3 104 $message, $query,$filter,$outputstream,$no_return);
91e0dccc 105 if (empty($read)) { //Imap server dropped its connection
ec73f243 106 $response = '';
107 $message = '';
108 return false;
109 }
bc78cc6e 110 /* retrieve the response and the message */
111 $response = $response[$tag];
112 $message = $message[$tag];
1e0a2f0e 113
bc78cc6e 114 if (!empty($read[$tag])) {
115 return $read[$tag][0];
116 } else {
117 return $read[$tag];
118 }
c5809184 119 } else {
120 global $squirrelmail_language, $color;
121 set_up_language($squirrelmail_language);
122 require_once(SM_PATH . 'functions/display_messages.php');
6fd95361 123 $string = "<b><font color=\"$color[2]\">\n" .
c5809184 124 _("ERROR : No available imapstream.") .
125 "</b></font>\n";
126 error_box($string,$color);
098ea084 127 return false;
1e0a2f0e 128 }
bc78cc6e 129}
48af4b64 130
0022f6db 131/**
132 * @param mixed $new_query
133 * @param string $tag
134 * @param array $aQuery
135 * @param boolean $unique_id
136 * @since 1.5.0
137 */
bc78cc6e 138function sqimap_prepare_pipelined_query($new_query,&$tag,&$aQuery,$unique_id) {
139 $sid = sqimap_session_id($unique_id);
140 $tag_uid_a = explode(' ',trim($sid));
141 $tag = $tag_uid_a[0];
0b38d197 142 $query = $sid . ' '.$new_query."\r\n";
bc78cc6e 143 $aQuery[$tag] = $query;
42a07ac1 144}
145
0022f6db 146/**
147 * @param stream $imap_stream
148 * @param array $aQueryList
149 * @param boolean $handle_errors
150 * @param array $aServerResponse
151 * @param array $aServerMessage
152 * @param boolean $unique_id
153 * @param mixed $filter see sqimap_retrieve_imap_response()
154 * @param mixed $outputstream see sqimap_retrieve_imap_response()
155 * @param mixed $no_return see sqimap_retrieve_imap_response()
156 * @since 1.5.0
157 */
1e0a2f0e 158function sqimap_run_pipelined_command ($imap_stream, $aQueryList, $handle_errors,
bc78cc6e 159 &$aServerResponse, &$aServerMessage, $unique_id = false,
1e0a2f0e 160 $filter=false,$outputstream=false,$no_return=false) {
bc78cc6e 161 $aResponse = false;
5c300c60 162
1e0a2f0e 163 /*
52c8b585 164 Do not fire all calls at once to the imap-server but split the calls up
1e0a2f0e 165 in portions of $iChunkSize. If we do not do that I think we misbehave as
52c8b585 166 IMAP client or should handle BYE calls if the IMAP-server drops the
167 connection because the number of queries is to large. This isn't tested
168 but a wild guess how it could work in the field.
1e0a2f0e 169
170 After testing it on Exchange 2000 we discovered that a chunksize of 32
0b38d197 171 was quicker then when we raised it to 128.
52c8b585 172 */
173 $iQueryCount = count($aQueryList);
174 $iChunkSize = 32;
175 // array_chunk would also do the job but it's supported from php > 4.2
176 $aQueryChunks = array();
177 $iLoops = floor($iQueryCount / $iChunkSize);
178
5c300c60 179 if ($iLoops * $iChunkSize != $iQueryCount) ++$iLoops;
52c8b585 180
181 if (!function_exists('array_chunk')) { // arraychunk replacement
5c300c60 182 reset($aQueryList);
52c8b585 183 for($i=0;$i<$iLoops;++$i) {
5c300c60 184 for($j=0;$j<$iChunkSize;++$j) {
185 $key = key($aQueryList);
186 $aTmp[$key] = $aQueryList[$key];
187 if (next($aQueryList) === false) break;
188 }
189 $aQueryChunks[] = $aTmp;
1e0a2f0e 190 }
52c8b585 191 } else {
192 $aQueryChunks = array_chunk($aQueryList,$iChunkSize,true);
bc78cc6e 193 }
1e0a2f0e 194
52c8b585 195 for ($i=0;$i<$iLoops;++$i) {
196 $aQuery = $aQueryChunks[$i];
197 foreach($aQuery as $tag => $query) {
198 fputs($imap_stream,$query);
199 $aResults[$tag] = false;
200 }
52c8b585 201 foreach($aQuery as $tag => $query) {
5c300c60 202 if ($aResults[$tag] == false) {
1e0a2f0e 203 $aReturnedResponse = sqimap_retrieve_imap_response ($imap_stream, $tag,
bc78cc6e 204 $handle_errors, $response, $message, $query,
205 $filter,$outputstream,$no_return);
52c8b585 206 foreach ($aReturnedResponse as $returned_tag => $aResponse) {
5c300c60 207 if (!empty($aResponse)) {
52c8b585 208 $aResults[$returned_tag] = $aResponse[0];
5c300c60 209 } else {
210 $aResults[$returned_tag] = $aResponse;
211 }
52c8b585 212 $aServerResponse[$returned_tag] = $response[$returned_tag];
213 $aServerMessage[$returned_tag] = $message[$returned_tag];
214 }
bc78cc6e 215 }
216 }
217 }
b7277e4f 218 return $aResults;
bc78cc6e 219}
9c737111 220
1e0a2f0e 221/**
48af4b64 222 * Custom fgets function: gets a line from the IMAP-server,
223 * no matter how big it may be.
224 * @param stream imap_stream the stream to read from
225 * @return string a line
0022f6db 226 * @since 1.2.8
b8c285ab 227 */
b8c285ab 228function sqimap_fgets($imap_stream) {
229 $read = '';
230 $buffer = 4096;
231 $results = '';
c41daf03 232 $offset = 0;
233 while (strpos($results, "\r\n", $offset) === false) {
b8c285ab 234 if (!($read = fgets($imap_stream, $buffer))) {
329a7ca5 235 /* this happens in case of an error */
236 /* reset $results because it's useless */
237 $results = false;
b8c285ab 238 break;
239 }
c41daf03 240 if ( $results != '' ) {
241 $offset = strlen($results) - 1;
242 }
b8c285ab 243 $results .= $read;
244 }
245 return $results;
246}
247
0022f6db 248/**
249 * @param stream $imap_stream
250 * @param integer $iSize
251 * @param mixed $filter see sqimap_retrieve_imap_response()
252 * @param mixed $outputstream see sqimap_retrieve_imap_response()
253 * @param mixed $no_return see sqimap_retrieve_imap_response()
254 * @return string
255 * @since 1.4.1
256 */
7c7b74b3 257function sqimap_fread($imap_stream,$iSize,$filter=false,
258 $outputstream=false, $no_return=false) {
259 if (!$filter || !$outputstream) {
260 $iBufferSize = $iSize;
261 } else {
811318c5 262 // see php bug 24033. They changed fread behaviour %$^&$%
977a6085 263 $iBufferSize = 7800; // multiple of 78 in case of base64 decoding.
264 }
265 if ($iSize < $iBufferSize) {
266 $iBufferSize = $iSize;
7c7b74b3 267 }
7c0ec1d8 268
5eba0be2 269 $iRetrieved = 0;
977a6085 270 $results = '';
271 $sRead = $sReadRem = '';
1e0a2f0e 272 // NB: fread can also stop at end of a packet on sockets.
977a6085 273 while ($iRetrieved < $iSize) {
7c7b74b3 274 $sRead = fread($imap_stream,$iBufferSize);
977a6085 275 $iLength = strlen($sRead);
276 $iRetrieved += $iLength ;
277 $iRemaining = $iSize - $iRetrieved;
278 if ($iRemaining < $iBufferSize) {
279 $iBufferSize = $iRemaining;
280 }
13aabbcf 281 if ($sRead == '') {
7c7b74b3 282 $results = false;
283 break;
284 }
13aabbcf 285 if ($sReadRem != '') {
977a6085 286 $sRead = $sReadRem . $sRead;
287 $sReadRem = '';
288 }
7c0ec1d8 289
13aabbcf 290 if ($filter && $sRead != '') {
1e0a2f0e 291 // in case the filter is base64 decoding we return a remainder
7c0ec1d8 292 $sReadRem = $filter($sRead);
7c7b74b3 293 }
13aabbcf 294 if ($outputstream && $sRead != '') {
7c7b74b3 295 if (is_resource($outputstream)) {
296 fwrite($outputstream,$sRead);
297 } else if ($outputstream == 'php://stdout') {
298 echo $sRead;
299 }
300 }
301 if ($no_return) {
302 $sRead = '';
1e0a2f0e 303 } else {
977a6085 304 $results .= $sRead;
7c7b74b3 305 }
7c7b74b3 306 }
1e0a2f0e 307 return $results;
308}
977a6085 309
7c0ec1d8 310
48af4b64 311/**
312 * Obsolete function, inform plugins that use it
b35a5862 313 * @since 1.1.3
314 * @deprecated (since 1.5.0) use sqimap_run_command or sqimap_run_command_list instead
48af4b64 315 */
1e0a2f0e 316function sqimap_read_data_list($imap_stream, $tag, $handle_errors,
0dc05a81 317 &$response, &$message, $query = '') {
318 global $color, $squirrelmail_language;
319 set_up_language($squirrelmail_language);
320 require_once(SM_PATH . 'functions/display_messages.php');
6fd95361 321 $string = "<b><font color=\"$color[2]\">\n" .
0dc05a81 322 _("ERROR : Bad function call.") .
6fd95361 323 "</b><br />\n" .
0dc05a81 324 _("Reason:") . ' '.
6fd95361 325 'There is a plugin installed which make use of the <br />' .
326 'SquirrelMail internal function sqimap_read_data_list.<br />'.
327 'Please adapt the installed plugin and let it use<br />'.
328 'sqimap_run_command or sqimap_run_command_list instead<br /><br />'.
329 'The following query was issued:<br />'.
330 htmlspecialchars($query) . '<br />' . "</font><br />\n";
0dc05a81 331 error_box($string,$color);
1e0a2f0e 332 echo '</body></html>';
333 exit;
0dc05a81 334}
7c7b74b3 335
48af4b64 336/**
337 * Function to display an error related to an IMAP-query.
338 * @param string title the caption of the error box
339 * @param string query the query that went wrong
ec73f243 340 * @param string message_title optional message title
341 * @param string message optional error message
342 * @param string $link an optional link to try again
48af4b64 343 * @return void
0022f6db 344 * @since 1.5.0
48af4b64 345 */
ec73f243 346function sqimap_error_box($title, $query = '', $message_title = '', $message = '', $link = '')
4974c2a0 347{
348 global $color, $squirrelmail_language;
349
350 set_up_language($squirrelmail_language);
351 require_once(SM_PATH . 'functions/display_messages.php');
6fd95361 352 $string = "<font color=\"$color[2]\"><b>\n" . $title . "</b><br />\n";
bf15f116 353 $cmd = explode(' ',$query);
354 $cmd= strtolower($cmd[0]);
355
356 if ($query != '' && $cmd != 'login')
6fd95361 357 $string .= _("Query:") . ' ' . htmlspecialchars($query) . '<br />';
4974c2a0 358 if ($message_title != '')
359 $string .= $message_title;
360 if ($message != '')
361 $string .= htmlspecialchars($message);
6fd95361 362 $string .= "</font><br />\n";
ec73f243 363 if ($link != '')
364 $string .= $link;
4974c2a0 365 error_box($string,$color);
366}
367
48af4b64 368/**
3411d4ec 369 * Reads the output from the IMAP stream. If handle_errors is set to true,
370 * this will also handle all errors that are received. If it is not set,
48af4b64 371 * the errors will be sent back through $response and $message.
0022f6db 372 * @param stream $imap_stream
373 * @param mixed $tag
374 * @param boolean $handle_errors
375 * @param array $response
376 * @param array $message
377 * @param mixed $query
378 * @param mixed $filter
379 * @param mixed $outputstream
380 * @param mixed $no_return
381 * @since 1.5.0
bee165ef 382 */
1e0a2f0e 383function sqimap_retrieve_imap_response($imap_stream, $tag, $handle_errors,
7c7b74b3 384 &$response, &$message, $query = '',
385 $filter = false, $outputstream = false, $no_return = false) {
9c737111 386 global $color, $squirrelmail_language;
9c737111 387 $read = '';
bc78cc6e 388 if (!is_array($message)) $message = array();
389 if (!is_array($response)) $response = array();
ec73f243 390 $aResponse = '';
b8c285ab 391 $resultlist = array();
392 $data = array();
393 $read = sqimap_fgets($imap_stream);
8d8da447 394 $i = 0;
bea3eb1e 395 while ($read) {
396 $char = $read{0};
397 switch ($char)
398 {
15bc7f66 399 case '+':
400 default:
401 $read = sqimap_fgets($imap_stream);
402 break;
403
404 case $tag{0}:
405 {
bea3eb1e 406 /* get the command */
407 $arg = '';
408 $i = strlen($tag)+1;
409 $s = substr($read,$i);
410 if (($j = strpos($s,' ')) || ($j = strpos($s,"\n"))) {
411 $arg = substr($s,0,$j);
412 }
413 $found_tag = substr($read,0,$i-1);
5c300c60 414 if ($found_tag) {
bea3eb1e 415 switch ($arg)
416 {
15bc7f66 417 case 'OK':
418 case 'BAD':
419 case 'NO':
420 case 'BYE':
421 case 'PREAUTH':
bc78cc6e 422 $response[$found_tag] = $arg;
423 $message[$found_tag] = trim(substr($read,$i+strlen($arg)));
424 if (!empty($data)) {
425 $resultlist[] = $data;
426 }
5c300c60 427 $aResponse[$found_tag] = $resultlist;
428 $data = $resultlist = array();
429 if ($found_tag == $tag) {
430 break 3; /* switch switch while */
431 }
432 break;
1e0a2f0e 433 default:
bea3eb1e 434 /* this shouldn't happen */
bc78cc6e 435 $response[$found_tag] = $arg;
436 $message[$found_tag] = trim(substr($read,$i+strlen($arg)));
437 if (!empty($data)) {
438 $resultlist[] = $data;
439 }
440 $aResponse[$found_tag] = $resultlist;
5c300c60 441 $data = $resultlist = array();
442 if ($found_tag == $tag) {
443 break 3; /* switch switch while */
444 }
bc78cc6e 445 }
bea3eb1e 446 }
5c300c60 447 $read = sqimap_fgets($imap_stream);
448 if ($read === false) { /* error */
4920e1e0 449 break 2; /* switch while */
5c300c60 450 }
451 break;
15bc7f66 452 } // end case $tag{0}
453
454 case '*':
455 {
bea3eb1e 456 if (preg_match('/^\*\s\d+\sFETCH/',$read)) {
457 /* check for literal */
458 $s = substr($read,-3);
459 $fetch_data = array();
460 do { /* outer loop, continue until next untagged fetch
461 or tagged reponse */
462 do { /* innerloop for fetching literals. with this loop
463 we prohibid that literal responses appear in the
464 outer loop so we can trust the untagged and
465 tagged info provided by $read */
466 if ($s === "}\r\n") {
467 $j = strrpos($read,'{');
468 $iLit = substr($read,$j+1,-3);
469 $fetch_data[] = $read;
7c7b74b3 470 $sLiteral = sqimap_fread($imap_stream,$iLit,$filter,$outputstream,$no_return);
329a7ca5 471 if ($sLiteral === false) { /* error */
472 break 4; /* while while switch while */
473 }
bea3eb1e 474 /* backwards compattibility */
475 $aLiteral = explode("\n", $sLiteral);
476 /* release not neaded data */
477 unset($sLiteral);
478 foreach ($aLiteral as $line) {
479 $fetch_data[] = $line ."\n";
480 }
481 /* release not neaded data */
1e0a2f0e 482 unset($aLiteral);
bea3eb1e 483 /* next fgets belongs to this fetch because
484 we just got the exact literalsize and there
485 must follow data to complete the response */
329a7ca5 486 $read = sqimap_fgets($imap_stream);
487 if ($read === false) { /* error */
488 break 4; /* while while switch while */
489 }
c0b23345 490 $fetch_data[] = $read;
bea3eb1e 491 } else {
329a7ca5 492 $fetch_data[] = $read;
bea3eb1e 493 }
494 /* retrieve next line and check in the while
495 statements if it belongs to this fetch response */
496 $read = sqimap_fgets($imap_stream);
329a7ca5 497 if ($read === false) { /* error */
498 break 4; /* while while switch while */
499 }
bea3eb1e 500 /* check for next untagged reponse and break */
501 if ($read{0} == '*') break 2;
502 $s = substr($read,-3);
503 } while ($s === "}\r\n");
504 $s = substr($read,-3);
505 } while ($read{0} !== '*' &&
106d4087 506 substr($read,0,strlen($tag)) !== $tag);
329a7ca5 507 $resultlist[] = $fetch_data;
bea3eb1e 508 /* release not neaded data */
509 unset ($fetch_data);
510 } else {
511 $s = substr($read,-3);
512 do {
513 if ($s === "}\r\n") {
514 $j = strrpos($read,'{');
515 $iLit = substr($read,$j+1,-3);
516 $data[] = $read;
329a7ca5 517 $sLiteral = fread($imap_stream,$iLit);
c0b23345 518 if ($sLiteral === false) { /* error */
329a7ca5 519 $read = false;
520 break 3; /* while switch while */
521 }
c0b23345 522 $data[] = $sLiteral;
b7277e4f 523 $data[] = sqimap_fgets($imap_stream);
bea3eb1e 524 } else {
329a7ca5 525 $data[] = $read;
bea3eb1e 526 }
527 $read = sqimap_fgets($imap_stream);
329a7ca5 528 if ($read === false) {
529 break 3; /* while switch while */
530 } else if ($read{0} == '*') {
106d4087 531 break;
532 }
bea3eb1e 533 $s = substr($read,-3);
534 } while ($s === "}\r\n");
535 break 1;
1e0a2f0e 536 }
bea3eb1e 537 break;
15bc7f66 538 } // end case '*'
539 } // end switch
c0b23345 540 } // end while
1e0a2f0e 541
c0b23345 542 /* error processing in case $read is false */
d7542838 543 if ($read === false) {
d3d9ef2d 544 // try to retrieve an untagged bye respons from the results
545 $sResponse = array_pop($data);
d7542838 546 if ($sResponse !== NULL && strpos($sResponse,'* BYE') !== false) {
547 if (!$handle_errors) {
548 $query = '';
549 }
550 sqimap_error_box(_("ERROR : Imap server closed the connection."), $query, _("Server responded:"),$sResponse);
551 echo '</body></html>';
552 exit;
553 } else if ($handle_errors) {
1e0a2f0e 554 unset($data);
ec73f243 555 sqimap_error_box(_("ERROR : Connection dropped by imap-server."), $query);
556 exit;
557 }
b8c285ab 558 }
1e0a2f0e 559
15bc7f66 560 /* Set $resultlist array */
b8c285ab 561 if (!empty($data)) {
bc78cc6e 562 //$resultlist[] = $data;
9c737111 563 }
b8c285ab 564 elseif (empty($resultlist)) {
1e0a2f0e 565 $resultlist[] = array();
b8c285ab 566 }
15bc7f66 567
568 /* Return result or handle errors */
bee165ef 569 if ($handle_errors == false) {
bc78cc6e 570 return $aResponse;
dd381002 571 }
4974c2a0 572 switch ($response[$tag]) {
dd381002 573 case 'OK':
bc78cc6e 574 return $aResponse;
329a7ca5 575 break;
1e0a2f0e 576 case 'NO':
dd381002 577 /* ignore this error from M$ exchange, it is not fatal (aka bug) */
6b6c2e06 578 if (strstr($message[$tag], 'command resulted in') === false) {
4974c2a0 579 sqimap_error_box(_("ERROR : Could not complete request."), $query, _("Reason Given: "), $message[$tag]);
329a7ca5 580 echo '</body></html>';
052e0c26 581 exit;
9c737111 582 }
329a7ca5 583 break;
1e0a2f0e 584 case 'BAD':
4974c2a0 585 sqimap_error_box(_("ERROR : Bad or malformed request."), $query, _("Server responded: "), $message[$tag]);
1e0a2f0e 586 echo '</body></html>';
587 exit;
588 case 'BYE':
4974c2a0 589 sqimap_error_box(_("ERROR : Imap server closed the connection."), $query, _("Server responded: "), $message[$tag]);
1e0a2f0e 590 echo '</body></html>';
9c737111 591 exit;
1e0a2f0e 592 default:
4974c2a0 593 sqimap_error_box(_("ERROR : Unknown imap response."), $query, _("Server responded: "), $message[$tag]);
329a7ca5 594 /* the error is displayed but because we don't know the reponse we
595 return the result anyway */
1e0a2f0e 596 return $aResponse;
329a7ca5 597 break;
9c737111 598 }
9c737111 599}
600
0022f6db 601/**
602 * @param stream $imap_stream
603 * @param string $tag_uid
604 * @param boolean $handle_errors
605 * @param array $response
606 * @param array $message
607 * @param mixed $query (since 1.2.5)
608 * @param mixed $filter (since 1.4.1) see sqimap_retrieve_imap_response()
609 * @param mixed $outputstream (since 1.4.1) see sqimap_retrieve_imap_response()
610 * @param mixed $no_return (since 1.4.1) see sqimap_retrieve_imap_response()
611 */
1e0a2f0e 612function sqimap_read_data ($imap_stream, $tag_uid, $handle_errors,
7c7b74b3 613 &$response, &$message, $query = '',
614 $filter=false,$outputstream=false,$no_return=false) {
bc78cc6e 615
616 $tag_uid_a = explode(' ',trim($tag_uid));
617 $tag = $tag_uid_a[0];
618
1e0a2f0e 619 $res = sqimap_retrieve_imap_response($imap_stream, $tag, $handle_errors,
620 $response, $message, $query,$filter,$outputstream,$no_return);
621 return $res;
9c737111 622}
623
48af4b64 624/**
b98732e8 625 * Connects to the IMAP server and returns a resource identifier for use with
626 * the other SquirrelMail IMAP functions. Does NOT login!
48af4b64 627 * @param string server hostname of IMAP server
628 * @param int port port number to connect to
629 * @param bool tls whether to use TLS when connecting.
630 * @return imap-stream resource identifier
0022f6db 631 * @since 1.5.0 (usable only in 1.5.1 or later)
b98732e8 632 */
633function sqimap_create_stream($server,$port,$tls=false) {
ce68b76b 634 global $squirrelmail_language;
b98732e8 635
57ffe0af 636 if ($tls == true) {
b98732e8 637 if ((check_php_version(4,3)) and (extension_loaded('openssl'))) {
638 /* Use TLS by prefixing "tls://" to the hostname */
57ffe0af 639 $server = 'tls://' . $server;
b98732e8 640 } else {
641 require_once(SM_PATH . 'functions/display_messages.php');
3b151851 642 logout_error( sprintf(_("Error connecting to IMAP server: %s."), $server).
643 '<br />'.
644 _("TLS is enabled, but this version of PHP does not support TLS sockets, or is missing the openssl extension.").
645 '<br /><br />'.
646 _("Please contact your system administrator and report this error.") );
b98732e8 647 }
648 }
649
82f403aa 650 $imap_stream = @fsockopen($server, $port, $error_number, $error_string, 15);
b98732e8 651
652 /* Do some error correction */
653 if (!$imap_stream) {
654 set_up_language($squirrelmail_language, true);
655 require_once(SM_PATH . 'functions/display_messages.php');
3b151851 656 logout_error( sprintf(_("Error connecting to IMAP server: %s."), $server).
657 "<br />\r\n$error_number : $error_string<br />\r\n" );
b98732e8 658 exit;
659 }
660 $server_info = fgets ($imap_stream, 1024);
661 return $imap_stream;
662}
663
48af4b64 664/**
3411d4ec 665 * Logs the user into the imap server. If $hide is set, no error messages
666 * will be displayed. This function returns the imap connection handle.
0022f6db 667 * @param string $username user name
668 * @param string $password encrypted password
669 * @param string $imap_server_address address of imap server
670 * @param integer $imap_port port of imap server
671 * @param boolean $hide controls display connection errors
672 * @return stream
3411d4ec 673 */
9c737111 674function sqimap_login ($username, $password, $imap_server_address, $imap_port, $hide) {
fe55c7c7 675 global $color, $squirrelmail_language, $onetimepad, $use_imap_tls,
676 $imap_auth_mech, $sqimap_capabilities;
85fc999e 677
eb2f6102 678 if (!isset($onetimepad) || empty($onetimepad)) {
679 sqgetglobalvar('onetimepad' , $onetimepad , SQ_SESSION );
680 }
fe55c7c7 681 if (!isset($sqimap_capabilities)) {
682 sqgetglobalvar('sqimap_capabilities' , $capability , SQ_SESSION );
683 }
684
b98732e8 685 $host = $imap_server_address;
bd9829d7 686 $imap_server_address = sqimap_get_user_server($imap_server_address, $username);
fe55c7c7 687
b98732e8 688 $imap_stream = sqimap_create_stream($imap_server_address,$imap_port,$use_imap_tls);
fe55c7c7 689
2f1f7a12 690 /* Decrypt the password */
691 $password = OneTimePadDecrypt($password, $onetimepad);
692
b98732e8 693 if (($imap_auth_mech == 'cram-md5') OR ($imap_auth_mech == 'digest-md5')) {
3b151851 694 // We're using some sort of authentication OTHER than plain or login
b98732e8 695 $tag=sqimap_session_id(false);
696 if ($imap_auth_mech == 'digest-md5') {
098ea084 697 $query = $tag . " AUTHENTICATE DIGEST-MD5\r\n";
b98732e8 698 } elseif ($imap_auth_mech == 'cram-md5') {
098ea084 699 $query = $tag . " AUTHENTICATE CRAM-MD5\r\n";
b98732e8 700 }
701 fputs($imap_stream,$query);
702 $answer=sqimap_fgets($imap_stream);
703 // Trim the "+ " off the front
704 $response=explode(" ",$answer,3);
705 if ($response[0] == '+') {
098ea084 706 // Got a challenge back
b98732e8 707 $challenge=$response[1];
708 if ($imap_auth_mech == 'digest-md5') {
709 $reply = digest_md5_response($username,$password,$challenge,'imap',$host);
710 } elseif ($imap_auth_mech == 'cram-md5') {
711 $reply = cram_md5_response($username,$password,$challenge);
712 }
713 fputs($imap_stream,$reply);
714 $read=sqimap_fgets($imap_stream);
715 if ($imap_auth_mech == 'digest-md5') {
3b151851 716 // DIGEST-MD5 has an extra step..
b98732e8 717 if (substr($read,0,1) == '+') { // OK so far..
098ea084 718 fputs($imap_stream,"\r\n");
719 $read=sqimap_fgets($imap_stream);
098ea084 720 }
b98732e8 721 }
722 $results=explode(" ",$read,3);
723 $response=$results[1];
724 $message=$results[2];
725 } else {
3b151851 726 // Fake the response, so the error trap at the bottom will work
b98732e8 727 $response="BAD";
728 $message='IMAP server does not appear to support the authentication method selected.';
729 $message .= ' Please contact your system administrator.';
730 }
fe0b18b3 731 } elseif ($imap_auth_mech == 'login') {
b98732e8 732 // Original IMAP login code
733 $query = 'LOGIN "' . quoteimap($username) . '" "' . quoteimap($password) . '"';
734 $read = sqimap_run_command ($imap_stream, $query, false, $response, $message);
1e7fc1cb 735 } elseif ($imap_auth_mech == 'plain') {
fe55c7c7 736 /***
737 * SASL PLAIN
738 *
739 * RFC 2595 Chapter 6
740 *
741 * The mechanism consists of a single message from the client to the
742 * server. The client sends the authorization identity (identity to
743 * login as), followed by a US-ASCII NUL character, followed by the
744 * authentication identity (identity whose password will be used),
745 * followed by a US-ASCII NUL character, followed by the clear-text
746 * password. The client may leave the authorization identity empty to
747 * indicate that it is the same as the authentication identity.
748 *
749 **/
b98732e8 750 $tag=sqimap_session_id(false);
2bd6b461 751 $sasl = (isset($capability['SASL-IR']) && $capability['SASL-IR']) ? true : false;
b98732e8 752 $auth = base64_encode("$username\0$username\0$password");
fe55c7c7 753 if ($sasl) {
754 // IMAP Extension for SASL Initial Client Response
2bd6b461 755 // <draft-siemborski-imap-sasl-initial-response-01b.txt>
fe55c7c7 756 $query = $tag . " AUTHENTICATE PLAIN $auth\r\n";
757 fputs($imap_stream, $query);
b98732e8 758 $read = sqimap_fgets($imap_stream);
fe55c7c7 759 } else {
760 $query = $tag . " AUTHENTICATE PLAIN\r\n";
761 fputs($imap_stream, $query);
762 $read=sqimap_fgets($imap_stream);
763 if (substr($read,0,1) == '+') { // OK so far..
764 fputs($imap_stream, "$auth\r\n");
765 $read = sqimap_fgets($imap_stream);
766 }
098ea084 767 }
b98732e8 768 $results=explode(" ",$read,3);
769 $response=$results[1];
770 $message=$results[2];
771 } else {
772 $response="BAD";
773 $message="Internal SquirrelMail error - unknown IMAP authentication method chosen. Please contact the developers.";
774 }
fe55c7c7 775
b98732e8 776 /* If the connection was not successful, lets see why */
9c737111 777 if ($response != 'OK') {
778 if (!$hide) {
74424a43 779 if ($response != 'NO') {
3411d4ec 780 /* "BAD" and anything else gets reported here. */
098ea084 781 $message = htmlspecialchars($message);
9c737111 782 set_up_language($squirrelmail_language, true);
098ea084 783 require_once(SM_PATH . 'functions/display_messages.php');
9c737111 784 if ($response == 'BAD') {
6fd95361 785 $string = sprintf (_("Bad request: %s")."<br />\r\n", $message);
9c737111 786 } else {
6fd95361 787 $string = sprintf (_("Unknown error: %s") . "<br />\n", $message);
9c737111 788 }
1e7fc1cb 789 if (isset($read) && is_array($read)) {
6fd95361 790 $string .= '<br />' . _("Read data:") . "<br />\n";
9c737111 791 foreach ($read as $line) {
6fd95361 792 $string .= htmlspecialchars($line) . "<br />\n";
9c737111 793 }
794 }
098ea084 795 error_box($string,$color);
9c737111 796 exit;
165e24a7 797 } else {
3411d4ec 798 /*
799 * If the user does not log in with the correct
1c72b151 800 * username and password it is not possible to get the
801 * correct locale from the user's preferences.
802 * Therefore, apply the same hack as on the login
803 * screen.
3411d4ec 804 *
805 * $squirrelmail_language is set by a cookie when
1c72b151 806 * the user selects language and logs out
bee165ef 807 */
fe55c7c7 808
9c737111 809 set_up_language($squirrelmail_language, true);
bd9c880b 810 include_once(SM_PATH . 'functions/display_messages.php' );
098ea084 811 sqsession_destroy();
d5c472f1 812 /* terminate the session nicely */
813 sqimap_logout($imap_stream);
bd9c880b 814 logout_error( _("Unknown user or password incorrect.") );
9c737111 815 exit;
052e0c26 816 }
9c737111 817 } else {
052e0c26 818 exit;
9c737111 819 }
820 }
1d20443c 821
822 /* Special error case:
823 * Login referrals. The server returns:
824 * ? OK [REFERRAL <imap url>]
825 * Check RFC 2221 for details. Since we do not support login referrals yet
826 * we log the user out.
827 */
2da1524c 828 if ( stristr($message, 'REFERRAL imap') === TRUE ) {
1d20443c 829 sqimap_logout($imap_stream);
830 set_up_language($squirrelmail_language, true);
831 include_once(SM_PATH . 'functions/display_messages.php' );
832 sqsession_destroy();
edde1f5c 833 logout_error( _("Your mailbox is not located at this server. Try a different server or consult your system administrator") );
1d20443c 834 exit;
835 }
836
9c737111 837 return $imap_stream;
838}
f1e6f580 839
48af4b64 840/**
841 * Simply logs out the IMAP session
842 * @param stream imap_stream the IMAP connection to log out.
843 * @return void
844 */
9c737111 845function sqimap_logout ($imap_stream) {
8d936b0c 846 /* Logout is not valid until the server returns 'BYE'
847 * If we don't have an imap_ stream we're already logged out */
26a2cc8b 848 if(isset($imap_stream) && $imap_stream)
8d936b0c 849 sqimap_run_command($imap_stream, 'LOGOUT', false, $response, $message);
9c737111 850}
851
48af4b64 852/**
853 * Retreive the CAPABILITY string from the IMAP server.
854 * If capability is set, returns only that specific capability,
855 * else returns array of all capabilities.
0022f6db 856 * @param $imap_stream
857 * @param string $capability (optional since 1.3.0)
858 * @return mixed (string if $capability is set and found,
859 * false, if $capability is set and not found,
860 * array if $capability not set)
48af4b64 861 */
487daa81 862function sqimap_capability($imap_stream, $capability='') {
9c737111 863 global $sqimap_capabilities;
9c737111 864 if (!is_array($sqimap_capabilities)) {
1c72b151 865 $read = sqimap_run_command($imap_stream, 'CAPABILITY', true, $a, $b);
866
9c737111 867 $c = explode(' ', $read[0]);
868 for ($i=2; $i < count($c); $i++) {
869 $cap_list = explode('=', $c[$i]);
3411d4ec 870 if (isset($cap_list[1])) {
ecc92309 871 // FIX ME. capabilities can occure multiple times.
872 // THREAD=REFERENCES THREAD=ORDEREDSUBJECT
9c737111 873 $sqimap_capabilities[$cap_list[0]] = $cap_list[1];
3411d4ec 874 } else {
9c737111 875 $sqimap_capabilities[$cap_list[0]] = TRUE;
3411d4ec 876 }
f1e6f580 877 }
9c737111 878 }
487daa81 879 if ($capability) {
098ea084 880 if (isset($sqimap_capabilities[$capability])) {
881 return $sqimap_capabilities[$capability];
882 } else {
883 return false;
884 }
f1e6f580 885 }
487daa81 886 return $sqimap_capabilities;
9c737111 887}
888
48af4b64 889/**
890 * Returns the delimeter between mailboxes: INBOX/Test, or INBOX.Test
0022f6db 891 * @param stream $imap_stream
892 * @return string
48af4b64 893 */
9c737111 894function sqimap_get_delimiter ($imap_stream = false) {
3411d4ec 895 global $sqimap_delimiter, $optional_delimiter;
85fc999e 896
9c737111 897 /* Use configured delimiter if set */
898 if((!empty($optional_delimiter)) && $optional_delimiter != 'detect') {
899 return $optional_delimiter;
900 }
85fc999e 901
9c737111 902 /* Do some caching here */
903 if (!$sqimap_delimiter) {
904 if (sqimap_capability($imap_stream, 'NAMESPACE')) {
3411d4ec 905 /*
906 * According to something that I can't find, this is supposed to work on all systems
907 * OS: This won't work in Courier IMAP.
908 * OS: According to rfc2342 response from NAMESPACE command is:
909 * OS: * NAMESPACE (PERSONAL NAMESPACES) (OTHER_USERS NAMESPACE) (SHARED NAMESPACES)
910 * OS: We want to lookup all personal NAMESPACES...
911 */
1c72b151 912 $read = sqimap_run_command($imap_stream, 'NAMESPACE', true, $a, $b);
f1e6f580 913 if (eregi('\\* NAMESPACE +(\\( *\\(.+\\) *\\)|NIL) +(\\( *\\(.+\\) *\\)|NIL) +(\\( *\\(.+\\) *\\)|NIL)', $read[0], $data)) {
9c737111 914 if (eregi('^\\( *\\((.*)\\) *\\)', $data[1], $data2)) {
f1e6f580 915 $pn = $data2[1];
9c737111 916 }
f1e6f580 917 $pna = explode(')(', $pn);
9c737111 918 while (list($k, $v) = each($pna)) {
862ff2d3 919 $lst = explode('"', $v);
920 if (isset($lst[3])) {
921 $pn[$lst[1]] = $lst[3];
922 } else {
74424a43 923 $pn[$lst[1]] = '';
862ff2d3 924 }
f1e6f580 925 }
926 }
927 $sqimap_delimiter = $pn[0];
928 } else {
929 fputs ($imap_stream, ". LIST \"INBOX\" \"\"\r\n");
930 $read = sqimap_read_data($imap_stream, '.', true, $a, $b);
91e0dccc 931 $read = $read['.'][0]; //sqimap_read_data() now returns a tag array of response array
f1e6f580 932 $quote_position = strpos ($read[0], '"');
933 $sqimap_delimiter = substr ($read[0], $quote_position+1, 1);
934 }
935 }
936 return $sqimap_delimiter;
9c737111 937}
052e0c26 938
48af4b64 939/**
940 * This encodes a mailbox name for use in IMAP commands.
941 * @param string what the mailbox to encode
942 * @return string the encoded mailbox string
0022f6db 943 * @since 1.5.0
48af4b64 944 */
b2306cbe 945function sqimap_encode_mailbox_name($what)
946{
91e0dccc 947 if (ereg("[\"\\\r\n]", $what))
948 return '{' . strlen($what) . "}\r\n" . $what; /* 4.3 literal form */
949 return '"' . $what . '"'; /* 4.3 quoted string form */
b2306cbe 950}
951
48af4b64 952/**
953 * Gets the number of messages in the current mailbox.
1e0a2f0e 954 *
955 * OBSOLETE use sqimap_status_messages instead.
48af4b64 956 */
9c737111 957function sqimap_get_num_messages ($imap_stream, $mailbox) {
b2306cbe 958 $read_ary = sqimap_run_command ($imap_stream, 'EXAMINE ' . sqimap_encode_mailbox_name($mailbox), false, $result, $message);
9c737111 959 for ($i = 0; $i < count($read_ary); $i++) {
85fc999e 960 if (ereg("[^ ]+ +([^ ]+) +EXISTS", $read_ary[$i], $regs)) {
961 return $regs[1];
962 }
9c737111 963 }
1f720b34 964 return false; //"BUG! Couldn't get number of messages in $mailbox!";
9c737111 965}
1e0a2f0e 966include_once(SM_PATH . 'functions/rfc822address.php');
9c737111 967
1e0a2f0e 968/**
969 * OBSOLETE FUNCTION should be removed after mailbox_display,
970 * printMessage function is adapted
971 */
91688e5f 972function parseAddress($address, $max=0) {
1e0a2f0e 973 $aAddress = parseRFC822Address($address,array('limit'=> $max));
974 /*
975 * Because the expected format of the array element is changed we adapt it now.
976 * This also implies that this function is obsolete and should be removed after the
977 * rest of the source is adapted. See Rfc822Address.php for the new function.
978 */
979 array_walk($aAddress, '_adaptAddress');
980 return $aAddress;
981}
91688e5f 982
1e0a2f0e 983/**
984 * OBSOLETE FUNCTION should be removed after mailbox_display,
985 * printMessage function is adapted
986 */
987function _adaptAddress(&$aAddr,$k) {
988 $sPersonal = (isset($aAddr[SQM_ADDR_PERSONAL]) && $aAddr[SQM_ADDR_PERSONAL]) ?
989 $aAddr[SQM_ADDR_PERSONAL] : '';
990 $sEmail = ($aAddr[SQM_ADDR_HOST]) ?
3cd52f38 991 $aAddr[SQM_ADDR_MAILBOX] . '@'.$aAddr[SQM_ADDR_HOST] :
992 $aAddr[SQM_ADDR_MAILBOX];
1e0a2f0e 993 $aAddr = array($sEmail,$sPersonal);
994}
91688e5f 995
48af4b64 996/**
997 * Returns the number of unseen messages in this folder.
26e90c74 998 * obsoleted by sqimap_status_messages !
3411d4ec 999 */
9c737111 1000function sqimap_unseen_messages ($imap_stream, $mailbox) {
26e90c74 1001 $aStatus = sqimap_status_messages($imap_stream,$mailbox,array('UNSEEN'));
1002 return $aStatus['UNSEEN'];
9c737111 1003}
1004
48af4b64 1005/**
26e90c74 1006 * Returns the status items of a mailbox.
1007 * Default it returns MESSAGES,UNSEEN and RECENT
1008 * Supported status items are MESSAGES, UNSEEN, RECENT, UIDNEXT and UIDVALIDITY
1f720b34 1009 */
1e0a2f0e 1010function sqimap_status_messages ($imap_stream, $mailbox,
26e90c74 1011 $aStatusItems = array('MESSAGES','UNSEEN','RECENT')) {
1012
3fedd15b 1013 $aStatusItems = implode(' ',$aStatusItems);
26e90c74 1014 $read_ary = sqimap_run_command ($imap_stream, 'STATUS ' . sqimap_encode_mailbox_name($mailbox) .
1015 " ($aStatusItems)", false, $result, $message);
1f720b34 1016 $i = 0;
26e90c74 1017 $messages = $unseen = $recent = $uidnext = $uidvalidity = false;
1f720b34 1018 $regs = array(false,false);
1019 while (isset($read_ary[$i])) {
1020 if (preg_match('/UNSEEN\s+([0-9]+)/i', $read_ary[$i], $regs)) {
098ea084 1021 $unseen = $regs[1];
1022 }
1f720b34 1023 if (preg_match('/MESSAGES\s+([0-9]+)/i', $read_ary[$i], $regs)) {
098ea084 1024 $messages = $regs[1];
1025 }
b8ec18ef 1026 if (preg_match('/RECENT\s+([0-9]+)/i', $read_ary[$i], $regs)) {
098ea084 1027 $recent = $regs[1];
1e0a2f0e 1028 }
26e90c74 1029 if (preg_match('/UIDNEXT\s+([0-9]+)/i', $read_ary[$i], $regs)) {
1030 $uidnext = $regs[1];
1e0a2f0e 1031 }
26e90c74 1032 if (preg_match('/UIDVALIDITY\s+([0-9]+)/i', $read_ary[$i], $regs)) {
1033 $uidvalidity = $regs[1];
1e0a2f0e 1034 }
1f720b34 1035 $i++;
1036 }
1e0a2f0e 1037 return array('MESSAGES' => $messages,
1038 'UNSEEN'=>$unseen,
26e90c74 1039 'RECENT' => $recent,
1040 'UIDNEXT' => $uidnext,
1041 'UIDVALIDITY' => $uidvalidity);
1f720b34 1042}
1043
9c737111 1044
48af4b64 1045/**
1046 * Saves a message to a given folder -- used for saving sent messages
3411d4ec 1047 */
9c737111 1048function sqimap_append ($imap_stream, $sent_folder, $length) {
b2306cbe 1049 fputs ($imap_stream, sqimap_session_id() . ' APPEND ' . sqimap_encode_mailbox_name($sent_folder) . " (\\Seen) \{$length}\r\n");
85fc999e 1050 $tmp = fgets ($imap_stream, 1024);
7ec3a6b9 1051 sqimap_append_checkresponse($tmp, $sent_folder);
9c737111 1052}
1053
8813fb15 1054function sqimap_append_done ($imap_stream, $folder='') {
9c737111 1055 fputs ($imap_stream, "\r\n");
1056 $tmp = fgets ($imap_stream, 1024);
7ec3a6b9 1057 sqimap_append_checkresponse($tmp, $folder);
1058}
1059
1060function sqimap_append_checkresponse($response, $folder) {
1061
1062 if (preg_match("/(.*)(BAD|NO)(.*)$/", $response, $regs)) {
1063 global $squirrelmail_language, $color;
69146537 1064 set_up_language($squirrelmail_language);
1f720b34 1065 require_once(SM_PATH . 'functions/display_messages.php');
7ec3a6b9 1066
098ea084 1067 $reason = $regs[3];
1068 if ($regs[2] == 'NO') {
6fd95361 1069 $string = "<b><font color=\"$color[2]\">\n" .
098ea084 1070 _("ERROR : Could not append message to") ." $folder." .
6fd95361 1071 "</b><br />\n" .
098ea084 1072 _("Server responded: ") .
6fd95361 1073 $reason . "<br />\n";
098ea084 1074 if (preg_match("/(.*)(quota)(.*)$/i", $reason, $regs)) {
1e0a2f0e 1075 $string .= _("Solution: ") .
1076 _("Remove unneccessary messages from your folder and start with your Trash folder.")
6fd95361 1077 ."<br />\n";
098ea084 1078 }
1079 $string .= "</font>\n";
1080 error_box($string,$color);
1081 } else {
6fd95361 1082 $string = "<b><font color=\"$color[2]\">\n" .
098ea084 1083 _("ERROR : Bad or malformed request.") .
6fd95361 1084 "</b><br />\n" .
098ea084 1085 _("Server responded: ") .
7ec3a6b9 1086 $reason . "</font><br />\n";
098ea084 1087 error_box($string,$color);
8813fb15 1088 exit;
098ea084 1089 }
69146537 1090 }
9c737111 1091}
85fc999e 1092
bd9829d7 1093function sqimap_get_user_server ($imap_server, $username) {
bd9829d7 1094 if (substr($imap_server, 0, 4) != "map:") {
1095 return $imap_server;
1096 }
bd9829d7 1097 $function = substr($imap_server, 4);
1098 return $function($username);
1099}
1100
48af4b64 1101/**
1102 * This is an example that gets imapservers from yellowpages (NIS).
1e0a2f0e 1103 * you can simple put map:map_yp_alias in your $imap_server_address
bd9829d7 1104 * in config.php use your own function instead map_yp_alias to map your
48af4b64 1105 * LDAP whatever way to find the users imapserver.
1106 */
bd9829d7 1107function map_yp_alias($username) {
1108 $yp = `ypmatch $username aliases`;
1109 return chop(substr($yp, strlen($username)+1));
1e0a2f0e 1110}
bd9829d7 1111
edde1f5c 1112?>