- Fix busy loop and notice when two literals in IMAP fetch (#1739433).
[squirrelmail.git] / functions / imap_general.php
index 38ef57224b4c35814517d0673c47d3a46f6f8455..6011497ebb5f151bd77b3276f29709b365138d70 100755 (executable)
@@ -5,7 +5,7 @@
  *
  * This implements all functions that do general IMAP functions.
  *
- * @copyright © 1999-2006 The SquirrelMail Project Team
+ * @copyright © 1999-2007 The SquirrelMail Project Team
  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  * @version $Id$
  * @package squirrelmail
@@ -466,6 +466,7 @@ function sqimap_retrieve_imap_response($imap_stream, $tag, $handle_errors,
                             we prohibid that literal responses appear in the
                             outer loop so we can trust the untagged and
                             tagged info provided by $read */
+                        $read_literal = false;
                         if ($s === "}\r\n") {
                             $j = strrpos($read,'{');
                             $iLit = substr($read,$j+1,-3);
@@ -490,7 +491,9 @@ function sqimap_retrieve_imap_response($imap_stream, $tag, $handle_errors,
                             if ($read === false) { /* error */
                                 break 4; /* while while switch while */
                             }
-                            $fetch_data[] = $read;
+                            $s = substr($read,-3);
+                            $read_literal = true;
+                            continue;
                         } else {
                             $fetch_data[] = $read;
                         }
@@ -503,7 +506,7 @@ function sqimap_retrieve_imap_response($imap_stream, $tag, $handle_errors,
                         /* check for next untagged reponse and break */
                         if ($read{0} == '*') break 2;
                         $s = substr($read,-3);
-                    } while ($s === "}\r\n");
+                    } while ($s === "}\r\n" || $read_literal);
                     $s = substr($read,-3);
                 } while ($read{0} !== '*' &&
                          substr($read,0,strlen($tag)) !== $tag);
@@ -748,15 +751,22 @@ function sqimap_create_stream($server,$port,$tls=0) {
 
 /**
  * Logs the user into the IMAP server.  If $hide is set, no error messages
- * will be displayed.  This function returns the IMAP connection handle.
+ * will be displayed (if set to 1, just exits, if set to 2, returns FALSE).
+ * This function returns the IMAP connection handle.
  * @param string $username user name
  * @param string $password password encrypted with onetimepad. Since 1.5.2
  *  function can use internal password functions, if parameter is set to
  *  boolean false.
  * @param string $imap_server_address address of imap server
  * @param integer $imap_port port of imap server
- * @param boolean $hide controls display connection errors
- * @return stream
+ * @param int $hide controls display connection errors:
+ *                  0 = do not hide
+ *                  1 = show no errors (just exit)
+ *                  2 = show no errors (return FALSE)
+ *                  3 = show no errors (return error string)
+ * @return mixed The IMAP connection stream, or if the connection fails,
+ *               FALSE if $hide is set to 2 or an error string if $hide
+ *               is set to 3.
  */
 function sqimap_login ($username, $password, $imap_server_address, $imap_port, $hide) {
     global $color, $squirrelmail_language, $onetimepad, $use_imap_tls,
@@ -770,11 +780,11 @@ function sqimap_login ($username, $password, $imap_server_address, $imap_port, $
 
     if(!empty($authz)) {
         /* authz plugin - specific:
-         * Get proxy login parameters from authz plugin configuration. If they 
+         * Get proxy login parameters from authz plugin configuration. If they
          * exist, they will override the current ones.
          * This is useful if we want to use different SASL authentication mechanism
          * and/or different TLS settings for proxy logins. */
-        global $authz_imap_auth_mech, $authz_use_imap_tls, $authz_imapPort_tls; 
+        global $authz_imap_auth_mech, $authz_use_imap_tls, $authz_imapPort_tls;
         $imap_auth_mech = !empty($authz_imap_auth_mech) ? strtolower($authz_imap_auth_mech) : $imap_auth_mech;
         $use_imap_tls = !empty($authz_use_imap_tls)? $authz_use_imap_tls : $use_imap_tls;
         $imap_port = !empty($authz_use_imap_tls)? $authz_imapPort_tls : $imap_port;
@@ -897,14 +907,17 @@ function sqimap_login ($username, $password, $imap_server_address, $imap_port, $
 
     /* If the connection was not successful, lets see why */
     if ($response != 'OK') {
-        if (!$hide) {
+        if (!$hide || $hide == 3) {
+//FIXME: UUURG... We don't want HTML in error messages, should also do html sanitizing of error messages elsewhere; should't assume output is destined for an HTML browser here
             if ($response != 'NO') {
                 /* "BAD" and anything else gets reported here. */
                 $message = htmlspecialchars($message);
                 set_up_language($squirrelmail_language, true);
                 if ($response == 'BAD') {
+                    if ($hide == 3) return sprintf(_("Bad request: %s"), $message);
                     $string = sprintf (_("Bad request: %s")."<br />\r\n", $message);
                 } else {
+                    if ($hide == 3) return sprintf(_("Unknown error: %s"), $message);
                     $string = sprintf (_("Unknown error: %s") . "<br />\n", $message);
                 }
                 if (isset($read) && is_array($read)) {
@@ -929,13 +942,15 @@ function sqimap_login ($username, $password, $imap_server_address, $imap_port, $
 
                 set_up_language($squirrelmail_language, true);
                 sqsession_destroy();
-                sqsetcookieflush();
+
                 /* terminate the session nicely */
                 sqimap_logout($imap_stream);
+                if ($hide == 3) return _("Unknown user or password incorrect.");
                 logout_error( _("Unknown user or password incorrect.") );
                 exit;
             }
         } else {
+            if ($hide == 2) return FALSE;
             exit;
         }
     }
@@ -1041,7 +1056,7 @@ function sqimap_get_delimiter ($imap_stream = false) {
              * OS: According to rfc2342 response from NAMESPACE command is:
              * OS: * NAMESPACE (PERSONAL NAMESPACES) (OTHER_USERS NAMESPACE) (SHARED NAMESPACES)
              * OS: We want to lookup all personal NAMESPACES...
-             * 
+             *
              * TODO: remove this in favour of the information from sqimap_get_namespace()
              */
             $read = sqimap_run_command($imap_stream, 'NAMESPACE', true, $a, $b);
@@ -1082,7 +1097,7 @@ function sqimap_get_namespace($imap_stream) {
     $read = sqimap_run_command($imap_stream, 'NAMESPACE', true, $a, $b);
     return sqimap_parse_namespace($read[0]);
 }
-    
+
 /**
  * Parses a NAMESPACE response and returns an array with the available
  * personal, users and shared namespaces.
@@ -1267,7 +1282,7 @@ function sqimap_status_messages ($imap_stream, $mailbox,
     if (!empty($hook_status)) {
          $hook_status['MAILBOX']=$mailbox;
          $hook_status['CALLER']='sqimap_status_messages';
-         do_hook_function('folder_status',$hook_status);
+         do_hook('folder_status', $hook_status);
     }
     return $status;
 }