fb62ebd1773682c06f9ef805b94ca978e5818bbd
6 * Copyright (c) 1999-2003 The SquirrelMail Project Team
7 * Licensed under the GNU GPL. For full terms see the file COPYING.
9 * This implements all functions that do general imap functions.
14 require_once(SM_PATH
. 'functions/page_header.php');
15 require_once(SM_PATH
. 'functions/auth.php');
18 global $sqimap_session_id;
19 $sqimap_session_id = 1;
21 /* Sets an unique session id in order to avoid simultanous sessions crash. */
22 function sqimap_session_id($unique_id = false) {
23 global $data_dir, $username, $sqimap_session_id;
25 return( sprintf("A%03d", $sqimap_session_id++
) );
27 return( sprintf("A%03d", $sqimap_session_id++
) . ' UID' );
32 * Both send a command and accept the result from the command.
33 * This is to allow proper session number handling.
35 function sqimap_run_command_list ($imap_stream, $query, $handle_errors, &$response, &$message, $unique_id = false) {
37 $sid = sqimap_session_id($unique_id);
38 fputs ($imap_stream, $sid . ' ' . $query . "\r\n");
39 $tag_uid_a = explode(' ',trim($sid));
41 $read = sqimap_read_data_list ($imap_stream, $tag, $handle_errors, $response, $message, $query );
42 /* get the response and the message */
43 $message = $message[$tag];
44 $response = $response[$tag];
47 global $squirrelmail_language, $color;
48 set_up_language($squirrelmail_language);
49 require_once(SM_PATH
. 'functions/display_messages.php');
50 $string = "<b><font color=$color[2]>\n" .
51 _("ERROR : No available imapstream.") .
53 error_box($string,$color);
58 function sqimap_run_command ($imap_stream, $query, $handle_errors, &$response,
59 &$message, $unique_id = false,$filter=false,
60 $outputstream=false,$no_return=false) {
62 $sid = sqimap_session_id($unique_id);
63 fputs ($imap_stream, $sid . ' ' . $query . "\r\n");
64 $tag_uid_a = explode(' ',trim($sid));
67 $read = sqimap_read_data ($imap_stream, $tag, $handle_errors, $response,
68 $message, $query,$filter,$outputstream,$no_return);
69 /* retrieve the response and the message */
70 $response = $response[$tag];
71 $message = $message[$tag];
73 if (!empty($read[$tag])) {
74 return $read[$tag][0];
79 global $squirrelmail_language, $color;
80 set_up_language($squirrelmail_language);
81 require_once(SM_PATH
. 'functions/display_messages.php');
82 $string = "<b><font color=$color[2]>\n" .
83 _("ERROR : No available imapstream.") .
85 error_box($string,$color);
89 function sqimap_prepare_pipelined_query($new_query,&$tag,&$aQuery,$unique_id) {
90 $sid = sqimap_session_id($unique_id);
91 $tag_uid_a = explode(' ',trim($sid));
93 $query = $sid . ' '.$new_query."\n";
94 $aQuery[$tag] = $query;
97 function sqimap_run_pipelined_command ($imap_stream, $aQuery, $handle_errors,
98 &$aServerResponse, &$aServerMessage, $unique_id = false,
99 $filter=false,$outputstream=false,$no_return=false) {
101 foreach($aQuery as $tag => $query) {
102 fputs($imap_stream,$query);
103 $aResults[$tag] = false;
106 foreach($aQuery as $tag => $query) {
107 if (!$aResults[$tag]) {
108 $aReturnedResponse = sqimap_read_data_list ($imap_stream, $tag,
109 $handle_errors, $response, $message, $query,
110 $filter,$outputstream,$no_return);
111 foreach ($aReturnedResponse as $returned_tag => $aResponse) {
112 if (!empty($aResponse)) {
113 $aResults[$returned_tag] = $aResponse[0];
115 $aResults[$returned_tag] = $aResponse;
117 $aServerResponse[$returned_tag] = $response[$returned_tag];
118 $aServerMessage[$returned_tag] = $message[$returned_tag];
126 * custom fgets function. gets a line from IMAP
127 * no matter how big it may be
130 function sqimap_fgets($imap_stream) {
135 while (strpos($results, "\r\n", $offset) === false) {
136 if (!($read = fgets($imap_stream, $buffer))) {
137 /* this happens in case of an error */
138 /* reset $results because it's useless */
142 if ( $results != '' ) {
143 $offset = strlen($results) - 1;
150 function sqimap_fread($imap_stream,$iSize,$filter=false,
151 $outputstream=false, $no_return=false) {
152 if (!$filter ||
!$outputstream) {
153 $iBufferSize = $iSize;
155 $iBufferSize = 62400; // multiple of 78 in case of base64 decoding.
157 $iRet = $iSize - $iBufferSize;
160 $results = $sReadRem = '';
161 $bFinished = $bBufferSizeAdapted = $bBufferIsOk = false;
162 while (($iRetrieved < ($iSize - $iBufferSize))) {
163 $sRead = fread($imap_stream,$iBufferSize);
168 $iRetrieved +
= $iBufferSize;
170 // in case line-endings do not appear at position 78 we adapt the buffersize so we can base64 decode on the fly
171 if (!$bBufferSizeAdapted) {
172 $i = strpos($sRead,"\n");
175 $iFragments = floor($iBufferSize / $i);
176 $iNewBufferSize = $iFragments * $i;
177 $iRemainder = $iNewBufferSize +
$i - $iBufferSize;
178 if ($iNewBufferSize == $iBufferSize) {
181 $iNewBufferSize = $iBufferSize;
182 $bBufferSizeAdapted = true;
184 if (!$bBufferIsOk && ($iRemainder +
$iBufferSize) < $iSize) {
185 $sReadRem = fread($imap_stream,$iRemainder);
186 } else if (!$bBufferIsOk) {
187 $sReadRem = fread($imap_stream,$iSize - $iBufferSize);
190 if (!$sReadRem && $sReadRem !== '') {
194 $iBufferSize = $iNewBufferSize;
195 $bBufferSizeAdapted = true;
197 $sReadRem = fread($imap_stream,$iSize - $iBufferSize);
205 $iRetrieved +
= $iRemainder;
211 if (is_resource($outputstream)) {
212 fwrite($outputstream,$sRead);
213 } else if ($outputstream == 'php://stdout') {
222 if (!$results && !$bFinished) {
223 $sRead = fread($imap_stream,($iSize - ($iRetrieved)));
228 if (is_resource($outputstream)) {
229 fwrite($outputstream,$sRead);
230 } else if ($outputstream == 'php://stdout') { // FIXME
245 * Reads the output from the IMAP stream. If handle_errors is set to true,
246 * this will also handle all errors that are received. If it is not set,
247 * the errors will be sent back through $response and $message
250 function sqimap_read_data_list ($imap_stream, $tag, $handle_errors,
251 &$response, &$message, $query = '',
252 $filter = false, $outputstream = false, $no_return = false) {
253 global $color, $squirrelmail_language;
255 if (!is_array($message)) $message = array();
256 if (!is_array($response)) $response = array();
257 $resultlist = array();
259 $read = sqimap_fgets($imap_stream);
267 $read = sqimap_fgets($imap_stream);
272 /* get the command */
275 $s = substr($read,$i);
276 if (($j = strpos($s,' ')) ||
($j = strpos($s,"\n"))) {
277 $arg = substr($s,0,$j);
279 $found_tag = substr($read,0,$i-1);
280 if ($arg && $found_tag==$tag) {
288 $response[$found_tag] = $arg;
289 $message[$found_tag] = trim(substr($read,$i+
strlen($arg)));
291 $resultlist[] = $data;
293 $aResponse[$tag] = $resultlist;
294 break 3; /* switch switch while */
296 /* this shouldn't happen */
297 $response[$found_tag] = $arg;
298 $message[$found_tag] = trim(substr($read,$i+
strlen($arg)));
300 $resultlist[] = $data;
302 $aResponse[$found_tag] = $resultlist;
303 break 3; /* switch switch while */
305 } elseif($found_tag !== $tag) {
306 /* not the tag we are looking for, continue */
308 $resultlist[] = $data;
310 $aResponse[$found_tag] = $resultlist;
311 $resultlist = $data = array();
312 $read = sqimap_fgets($imap_stream);
313 if ($read === false) { /* error */
314 break 3; /* switch switch while */
318 } // end case $tag{0}
322 if (preg_match('/^\*\s\d+\sFETCH/',$read)) {
323 /* check for literal */
324 $s = substr($read,-3);
325 $fetch_data = array();
326 do { /* outer loop, continue until next untagged fetch
328 do { /* innerloop for fetching literals. with this loop
329 we prohibid that literal responses appear in the
330 outer loop so we can trust the untagged and
331 tagged info provided by $read */
332 if ($s === "}\r\n") {
333 $j = strrpos($read,'{');
334 $iLit = substr($read,$j+
1,-3);
335 $fetch_data[] = $read;
336 $sLiteral = sqimap_fread($imap_stream,$iLit,$filter,$outputstream,$no_return);
337 if ($sLiteral === false) { /* error */
338 break 4; /* while while switch while */
340 /* backwards compattibility */
341 $aLiteral = explode("\n", $sLiteral);
342 /* release not neaded data */
344 foreach ($aLiteral as $line) {
345 $fetch_data[] = $line ."\n";
347 /* release not neaded data */
349 /* next fgets belongs to this fetch because
350 we just got the exact literalsize and there
351 must follow data to complete the response */
352 $read = sqimap_fgets($imap_stream);
353 if ($read === false) { /* error */
354 break 4; /* while while switch while */
356 $fetch_data[] = $read;
358 $fetch_data[] = $read;
360 /* retrieve next line and check in the while
361 statements if it belongs to this fetch response */
362 $read = sqimap_fgets($imap_stream);
363 if ($read === false) { /* error */
364 break 4; /* while while switch while */
366 /* check for next untagged reponse and break */
367 if ($read{0} == '*') break 2;
368 $s = substr($read,-3);
369 } while ($s === "}\r\n");
370 $s = substr($read,-3);
371 } while ($read{0} !== '*' &&
372 substr($read,0,strlen($tag)) !== $tag);
373 $resultlist[] = $fetch_data;
374 /* release not neaded data */
377 $s = substr($read,-3);
379 if ($s === "}\r\n") {
380 $j = strrpos($read,'{');
381 $iLit = substr($read,$j+
1,-3);
383 $sLiteral = fread($imap_stream,$iLit);
384 if ($sLiteral === false) { /* error */
386 break 3; /* while switch while */
389 $data[] = sqimap_fgets($imap_stream);
393 $read = sqimap_fgets($imap_stream);
394 if ($read === false) {
395 break 3; /* while switch while */
396 } else if ($read{0} == '*') {
399 $s = substr($read,-3);
400 } while ($s === "}\r\n");
408 /* error processing in case $read is false */
409 if ($read === false) {
411 set_up_language($squirrelmail_language);
412 require_once(SM_PATH
. 'functions/display_messages.php');
413 $string = "<b><font color=$color[2]>\n" .
414 _("ERROR : Connection dropped by imap-server.") .
417 htmlspecialchars($query) . '<br>' . "</font><br>\n";
418 error_box($string,$color);
422 /* Set $resultlist array */
424 //$resultlist[] = $data;
426 elseif (empty($resultlist)) {
427 $resultlist[] = array();
430 /* Return result or handle errors */
431 if ($handle_errors == false) {
433 return( $resultlist );
435 switch ($response[$tag])
441 /* ignore this error from M$ exchange, it is not fatal (aka bug) */
442 if (strstr($message[$tag], 'command resulted in') === false) {
443 set_up_language($squirrelmail_language);
444 require_once(SM_PATH
. 'functions/display_messages.php');
445 $string = "<b><font color=$color[2]>\n" .
446 _("ERROR : Could not complete request.") .
449 htmlspecialchars($query) . '<br>' .
450 _("Reason Given: ") .
451 htmlspecialchars($message[$tag]) . "</font><br>\n";
452 error_box($string,$color);
453 echo '</body></html>';
458 set_up_language($squirrelmail_language);
459 require_once(SM_PATH
. 'functions/display_messages.php');
460 $string = "<b><font color=$color[2]>\n" .
461 _("ERROR : Bad or malformed request.") .
464 htmlspecialchars($query) . '<br>' .
465 _("Server responded: ") .
466 htmlspecialchars($message[$tag]) . "</font><br>\n";
467 error_box($string,$color);
468 echo '</body></html>';
471 set_up_language($squirrelmail_language);
472 require_once(SM_PATH
. 'functions/display_messages.php');
473 $string = "<b><font color=$color[2]>\n" .
474 _("ERROR : Imap server closed the connection.") .
477 htmlspecialchars($query) . '<br>' .
478 _("Server responded: ") .
479 htmlspecialchars($message[$tag]) . "</font><br>\n";
480 error_box($string,$color);
481 echo '</body></html>';
484 set_up_language($squirrelmail_language);
485 require_once(SM_PATH
. 'functions/display_messages.php');
486 $string = "<b><font color=$color[2]>\n" .
487 _("ERROR : Unknown imap response.") .
490 htmlspecialchars($query) . '<br>' .
491 _("Server responded: ") .
492 htmlspecialchars($message[$tag]) . "</font><br>\n";
493 error_box($string,$color);
494 /* the error is displayed but because we don't know the reponse we
495 return the result anyway */
501 function sqimap_read_data ($imap_stream, $tag_uid, $handle_errors,
502 &$response, &$message, $query = '',
503 $filter=false,$outputstream=false,$no_return=false) {
505 $tag_uid_a = explode(' ',trim($tag_uid));
506 $tag = $tag_uid_a[0];
508 $res = sqimap_read_data_list($imap_stream, $tag, $handle_errors,
509 $response, $message, $query,$filter,$outputstream,$no_return);
510 /* sqimap_read_data should be called for one response
511 but since it just calls sqimap_read_data_list which
512 handles multiple responses we need to check for that
513 and merge the $res array IF they are seperated and
514 IF it was a FETCH response. */
516 // if (isset($res[1]) && is_array($res[1]) && isset($res[1][0])
517 // && preg_match('/^\* \d+ FETCH/', $res[1][0])) {
518 // $result = array();
519 // foreach($res as $index=>$value) {
520 // $result = array_merge($result, $res["$index"]);
523 if (isset($result)) {
524 return $result[$tag];
532 * Logs the user into the imap server. If $hide is set, no error messages
533 * will be displayed. This function returns the imap connection handle.
535 function sqimap_login ($username, $password, $imap_server_address, $imap_port, $hide) {
536 global $color, $squirrelmail_language, $onetimepad, $use_imap_tls, $imap_auth_mech;
538 if (!isset($onetimepad) ||
empty($onetimepad)) {
539 sqgetglobalvar('onetimepad' , $onetimepad , SQ_SESSION
);
541 $imap_server_address = sqimap_get_user_server($imap_server_address, $username);
542 $host=$imap_server_address;
544 if (($use_imap_tls == true) and (check_php_version(4,3)) and (extension_loaded('openssl'))) {
545 /* Use TLS by prefixing "tls://" to the hostname */
546 $imap_server_address = 'tls://' . $imap_server_address;
549 $imap_stream = fsockopen ( $imap_server_address, $imap_port, $error_number, $error_string, 15);
551 /* Do some error correction */
554 set_up_language($squirrelmail_language, true);
555 require_once(SM_PATH
. 'functions/display_messages.php');
556 $string = sprintf (_("Error connecting to IMAP server: %s.") .
557 "<br>\r\n", $imap_server_address) .
558 "$error_number : $error_string<br>\r\n";
559 logout_error($string,$color);
564 $server_info = fgets ($imap_stream, 1024);
566 /* Decrypt the password */
567 $password = OneTimePadDecrypt($password, $onetimepad);
569 if (($imap_auth_mech == 'cram-md5') OR ($imap_auth_mech == 'digest-md5')) {
570 // We're using some sort of authentication OTHER than plain or login
571 $tag=sqimap_session_id(false);
572 if ($imap_auth_mech == 'digest-md5') {
573 $query = $tag . " AUTHENTICATE DIGEST-MD5\r\n";
574 } elseif ($imap_auth_mech == 'cram-md5') {
575 $query = $tag . " AUTHENTICATE CRAM-MD5\r\n";
577 fputs($imap_stream,$query);
578 $answer=sqimap_fgets($imap_stream);
579 // Trim the "+ " off the front
580 $response=explode(" ",$answer,3);
581 if ($response[0] == '+') {
582 // Got a challenge back
583 $challenge=$response[1];
584 if ($imap_auth_mech == 'digest-md5') {
585 $reply = digest_md5_response($username,$password,$challenge,'imap',$host);
586 } elseif ($imap_auth_mech == 'cram-md5') {
587 $reply = cram_md5_response($username,$password,$challenge);
589 fputs($imap_stream,$reply);
590 $read=sqimap_fgets($imap_stream);
591 if ($imap_auth_mech == 'digest-md5') {
592 // DIGEST-MD5 has an extra step..
593 if (substr($read,0,1) == '+') { // OK so far..
594 fputs($imap_stream,"\r\n");
595 $read=sqimap_fgets($imap_stream);
598 $results=explode(" ",$read,3);
599 $response=$results[1];
600 $message=$results[2];
602 // Fake the response, so the error trap at the bottom will work
604 $message='IMAP server does not appear to support the authentication method selected.';
605 $message .= ' Please contact your system administrator.';
607 } elseif ($imap_auth_mech == 'login') {
608 // Original IMAP login code
609 $query = 'LOGIN "' . quoteimap($username) . '" "' . quoteimap($password) . '"';
610 $read = sqimap_run_command ($imap_stream, $query, false, $response, $message);
611 } elseif ($imap_auth_mech == 'plain') {
612 /* Replace this with SASL PLAIN if it ever gets implemented */
614 $message='SquirrelMail does not support SASL PLAIN yet. Rerun conf.pl and use login instead.';
617 $message="Internal SquirrelMail error - unknown IMAP authentication method chosen. Please contact the developers.";
620 /* If the connection was not successful, lets see why */
621 if ($response != 'OK') {
623 if ($response != 'NO') {
624 /* "BAD" and anything else gets reported here. */
625 $message = htmlspecialchars($message);
626 set_up_language($squirrelmail_language, true);
627 require_once(SM_PATH
. 'functions/display_messages.php');
628 if ($response == 'BAD') {
629 $string = sprintf (_("Bad request: %s")."<br>\r\n", $message);
631 $string = sprintf (_("Unknown error: %s") . "<br>\n", $message);
633 if (isset($read) && is_array($read)) {
634 $string .= '<br>' . _("Read data:") . "<br>\n";
635 foreach ($read as $line) {
636 $string .= htmlspecialchars($line) . "<br>\n";
639 error_box($string,$color);
643 * If the user does not log in with the correct
644 * username and password it is not possible to get the
645 * correct locale from the user's preferences.
646 * Therefore, apply the same hack as on the login
649 * $squirrelmail_language is set by a cookie when
650 * the user selects language and logs out
653 set_up_language($squirrelmail_language, true);
654 include_once(SM_PATH
. 'functions/display_messages.php' );
656 logout_error( _("Unknown user or password incorrect.") );
666 /* Simply logs out the IMAP session */
667 function sqimap_logout ($imap_stream) {
668 /* Logout is not valid until the server returns 'BYE'
669 * If we don't have an imap_ stream we're already logged out */
670 if(isset($imap_stream) && $imap_stream)
671 sqimap_run_command($imap_stream, 'LOGOUT', false, $response, $message);
674 function sqimap_capability($imap_stream, $capability='') {
675 global $sqimap_capabilities;
676 if (!is_array($sqimap_capabilities)) {
677 $read = sqimap_run_command($imap_stream, 'CAPABILITY', true, $a, $b);
679 $c = explode(' ', $read[0]);
680 for ($i=2; $i < count($c); $i++
) {
681 $cap_list = explode('=', $c[$i]);
682 if (isset($cap_list[1])) {
683 $sqimap_capabilities[$cap_list[0]] = $cap_list[1];
685 $sqimap_capabilities[$cap_list[0]] = TRUE;
690 if (isset($sqimap_capabilities[$capability])) {
691 return $sqimap_capabilities[$capability];
696 return $sqimap_capabilities;
699 /* Returns the delimeter between mailboxes: INBOX/Test, or INBOX.Test */
700 function sqimap_get_delimiter ($imap_stream = false) {
701 global $sqimap_delimiter, $optional_delimiter;
703 /* Use configured delimiter if set */
704 if((!empty($optional_delimiter)) && $optional_delimiter != 'detect') {
705 return $optional_delimiter;
708 /* Do some caching here */
709 if (!$sqimap_delimiter) {
710 if (sqimap_capability($imap_stream, 'NAMESPACE')) {
712 * According to something that I can't find, this is supposed to work on all systems
713 * OS: This won't work in Courier IMAP.
714 * OS: According to rfc2342 response from NAMESPACE command is:
715 * OS: * NAMESPACE (PERSONAL NAMESPACES) (OTHER_USERS NAMESPACE) (SHARED NAMESPACES)
716 * OS: We want to lookup all personal NAMESPACES...
718 $read = sqimap_run_command($imap_stream, 'NAMESPACE', true, $a, $b);
719 if (eregi('\\* NAMESPACE +(\\( *\\(.+\\) *\\)|NIL) +(\\( *\\(.+\\) *\\)|NIL) +(\\( *\\(.+\\) *\\)|NIL)', $read[0], $data)) {
720 if (eregi('^\\( *\\((.*)\\) *\\)', $data[1], $data2)) {
723 $pna = explode(')(', $pn);
724 while (list($k, $v) = each($pna)) {
725 $lst = explode('"', $v);
726 if (isset($lst[3])) {
727 $pn[$lst[1]] = $lst[3];
733 $sqimap_delimiter = $pn[0];
735 fputs ($imap_stream, ". LIST \"INBOX\" \"\"\r\n");
736 $read = sqimap_read_data($imap_stream, '.', true, $a, $b);
737 $quote_position = strpos ($read[0], '"');
738 $sqimap_delimiter = substr ($read[0], $quote_position+
1, 1);
741 return $sqimap_delimiter;
745 /* Gets the number of messages in the current mailbox. */
746 function sqimap_get_num_messages ($imap_stream, $mailbox) {
747 $read_ary = sqimap_run_command ($imap_stream, "EXAMINE \"$mailbox\"", false, $result, $message);
748 for ($i = 0; $i < count($read_ary); $i++
) {
749 if (ereg("[^ ]+ +([^ ]+) +EXISTS", $read_ary[$i], $regs)) {
753 return false; //"BUG! Couldn't get number of messages in $mailbox!";
757 function parseAddress($address, $max=0) {
760 $iCnt = strlen($address);
761 $aSpecials = array('(' ,'<' ,',' ,';' ,':');
762 $aReplace = array(' (',' <',' ,',' ;',' :');
763 $address = str_replace($aSpecials,$aReplace,$address);
764 $i = $iAddrFound = $bGroup = 0;
766 $cChar = $address{$i};
770 $iEnd = strpos($address,'>',$i+
1);
772 $sToken = substr($address,$i);
775 $sToken = substr($address,$i,$iEnd - $i +
1);
778 $sToken = str_replace($aReplace, $aSpecials,$sToken);
779 $aTokens[] = $sToken;
782 $iEnd = strpos($address,$cChar,$i+
1);
784 // skip escaped quotes
785 $prev_char = $address{$iEnd-1};
786 while ($prev_char === '\\' && substr($address,$iEnd-2,2) !== '\\\\') {
787 $iEnd = strpos($address,$cChar,$iEnd+
1);
789 $prev_char = $address{$iEnd-1};
796 $sToken = substr($address,$i);
799 // also remove the surrounding quotes
800 $sToken = substr($address,$i+
1,$iEnd - $i -1);
803 $sToken = str_replace($aReplace, $aSpecials,$sToken);
804 if ($sToken) $aTokens[] = $sToken;
807 $iEnd = strpos($address,')',$i);
809 $sToken = substr($address,$i);
812 $sToken = substr($address,$i,$iEnd - $i +
1);
815 $sToken = str_replace($aReplace, $aSpecials,$sToken);
816 $aTokens[] = $sToken;
826 if ($max && $max == $iAddrFound) {
838 $iEnd = strpos($address,' ',$i+
1);
840 $sToken = trim(substr($address,$i,$iEnd - $i));
843 $sToken = trim(substr($address,$i));
846 if ($sToken) $aTokens[] = $sToken;
850 $sPersonal = $sEmail = $sComment = $sGroup = '';
851 $aStack = $aComment = array();
852 foreach ($aTokens as $sToken) {
853 if ($max && $max == count($aAddress)) {
865 $aComment[] = substr($sToken,1,-1);
869 $sEmail = trim(implode(' ',$aStack));
870 $aAddress[] = array($sGroup,$sEmail);
871 $aStack = $aComment = array();
877 while (count($aStack) && !$sEmail) {
878 $sEmail = trim(array_pop($aStack));
881 if (count($aStack)) {
882 $sPersonal = trim(implode('',$aStack));
886 if (!$sPersonal && count($aComment)) {
887 $sComment = implode(' ',$aComment);
888 $sPersonal .= $sComment;
890 $aAddress[] = array($sEmail,$sPersonal);
891 $sPersonal = $sComment = $sEmail = '';
892 $aStack = $aComment = array();
895 $sGroup = implode(' ',$aStack); break;
899 $sEmail = trim(substr($sToken,1,-1));
904 default: $aStack[] = $sToken; break;
907 /* now do the action again for the last address */
909 while (count($aStack) && !$sEmail) {
910 $sEmail = trim(array_pop($aStack));
913 if (count($aStack)) {
914 $sPersonal = trim(implode('',$aStack));
918 if (!$sPersonal && count($aComment)) {
919 $sComment = implode(' ',$aComment);
920 $sPersonal .= $sComment;
922 $aAddress[] = array($sEmail,$sPersonal);
929 * Returns the number of unseen messages in this folder
931 function sqimap_unseen_messages ($imap_stream, $mailbox) {
932 $read_ary = sqimap_run_command ($imap_stream, "STATUS \"$mailbox\" (UNSEEN)", false, $result, $message);
934 $regs = array(false, false);
935 while (isset($read_ary[$i])) {
936 if (ereg("UNSEEN ([0-9]+)", $read_ary[$i], $regs)) {
945 * Returns the number of unseen/total messages in this folder
947 function sqimap_status_messages ($imap_stream, $mailbox) {
948 $read_ary = sqimap_run_command ($imap_stream, "STATUS \"$mailbox\" (MESSAGES UNSEEN RECENT)", false, $result, $message);
950 $messages = $unseen = $recent = false;
951 $regs = array(false,false);
952 while (isset($read_ary[$i])) {
953 if (preg_match('/UNSEEN\s+([0-9]+)/i', $read_ary[$i], $regs)) {
956 if (preg_match('/MESSAGES\s+([0-9]+)/i', $read_ary[$i], $regs)) {
957 $messages = $regs[1];
959 if (preg_match('/RECENT\s+([0-9]+)/i', $read_ary[$i], $regs)) {
964 return array('MESSAGES' => $messages, 'UNSEEN'=>$unseen, 'RECENT' => $recent);
969 * Saves a message to a given folder -- used for saving sent messages
971 function sqimap_append ($imap_stream, $sent_folder, $length) {
972 fputs ($imap_stream, sqimap_session_id() . " APPEND \"$sent_folder\" (\\Seen) \{$length}\r\n");
973 $tmp = fgets ($imap_stream, 1024);
976 function sqimap_append_done ($imap_stream, $folder='') {
977 global $squirrelmail_language, $color;
978 fputs ($imap_stream, "\r\n");
979 $tmp = fgets ($imap_stream, 1024);
980 if (preg_match("/(.*)(BAD|NO)(.*)$/", $tmp, $regs)) {
981 set_up_language($squirrelmail_language);
982 require_once(SM_PATH
. 'functions/display_messages.php');
984 if ($regs[2] == 'NO') {
985 $string = "<b><font color=$color[2]>\n" .
986 _("ERROR : Could not append message to") ." $folder." .
988 _("Server responded: ") .
990 if (preg_match("/(.*)(quota)(.*)$/i", $reason, $regs)) {
991 $string .= _("Solution: ") .
992 _("Remove unneccessary messages from your folder and start with your Trash folder.")
995 $string .= "</font>\n";
996 error_box($string,$color);
998 $string = "<b><font color=$color[2]>\n" .
999 _("ERROR : Bad or malformed request.") .
1001 _("Server responded: ") .
1002 $tmp . "</font><br>\n";
1003 error_box($string,$color);
1009 function sqimap_get_user_server ($imap_server, $username) {
1010 if (substr($imap_server, 0, 4) != "map:") {
1011 return $imap_server;
1013 $function = substr($imap_server, 4);
1014 return $function($username);
1017 /* This is an example that gets imapservers from yellowpages (NIS).
1018 * you can simple put map:map_yp_alias in your $imap_server_address
1019 * in config.php use your own function instead map_yp_alias to map your
1020 * LDAP whatever way to find the users imapserver. */
1022 function map_yp_alias($username) {
1023 $yp = `ypmatch
$username aliases`
;
1024 return chop(substr($yp, strlen($username)+
1));