Browse Source

imap_mailbox: Fixed minor bug in sqimap_mailbox_list
imap_general: Added sqimap_capability function to check capabilities of server.
imap_general: Rewrote sqimap_get_delim to use NAMESPACE capability (if available) to get delimiter.
Whole issue is more complicated, because you can have more NAMESPACES on IMAP server.

Ondřej Surý 25 years ago
parent
commit
2780154b27
2 changed files with 79 additions and 37 deletions
  1. 76 37
      functions/imap_general.php
  2. 3 0
      functions/imap_mailbox.php

+ 76 - 37
functions/imap_general.php

@@ -5,27 +5,24 @@
     **  This implements all functions that do general imap functions.
     **/
 
+   $imap_general_debug = false;
+   //$imap_general_debug = false;
+
    /******************************************************************************
     **  Reads the output from the IMAP stream.  If handle_errors is set to true,
     **  this will also handle all errors that are received.  If it is not set,
     **  the errors will be sent back through $response and $message
     ******************************************************************************/
    function sqimap_read_data ($imap_stream, $pre, $handle_errors, &$response, &$message) {
-      global $color, $squirrelmail_language;
-
-      //$imap_general_debug = true;
-      $imap_general_debug = false;
+      global $color, $squirrelmail_language, $imap_general_debug;
 
-      $read = fgets ($imap_stream, 1024);
-		if ($imap_general_debug) echo "<small><tt><font color=cc0000>$read</font></tt></small><br>";
       $counter = 0;
-      while (! ereg("^$pre (OK|BAD|NO)(.*)$", $read, $regs)) {
-         $data[$counter] = $read;
-         $read = fgets ($imap_stream, 1024);
-			if ($imap_general_debug) echo "<small><tt><font color=cc0000>$read</font></tt></small><br>";
-         $counter++;
-      }
-      
+	  do {
+          $data[$counter] = $read = fgets ($imap_stream, 4096);
+          if ($imap_general_debug) { echo "<small><tt><font color=cc0000>$read</font></tt></small><br>"; flush(); }
+          $counter++;
+	  } while (! ereg("^$pre (OK|BAD|NO)(.*)$", $read, $regs));
+
       $response = $regs[1];
       $message = trim($regs[2]);
       
@@ -54,9 +51,6 @@
       return $data;
    }
    
-
-
-   
    /******************************************************************************
     **  Logs the user into the imap server.  If $hide is set, no error messages
     **  will be displayed.  This function returns the imap connection handle.
@@ -161,35 +155,80 @@
       fputs ($imap_stream, "a001 LOGOUT\r\n");
    }
 
+function sqimap_capability($imap_stream, $capability) {
+	global $sqimap_capabilities;
+	global $imap_general_debug;
 
+	if (!is_array($sqimap_capabilities)) {
+		fputs ($imap_stream, "a001 CAPABILITY\r\n");
+		$read = sqimap_read_data($imap_stream, "a001", true, $a, $b);
+
+		$c = explode(' ', $read[0]);
+		for ($i=2; $i < count($c); $i++) {
+			list($k, $v) = explode('=', $c[$i]);
+			$sqimap_capabilities[$k] = ($v)?$v:TRUE;
+		}
+	}
+	return $sqimap_capabilities[$capability];
+}
 
    /******************************************************************************
     **  Returns the delimeter between mailboxes:  INBOX/Test, or INBOX.Test... 
     ******************************************************************************/
-   function sqimap_get_delimiter ($imap_stream = false) {
-		global $optional_delimiter;
-		if (!$optional_delimiter) $optional_delimiter = "detect";
+function sqimap_get_delimiter ($imap_stream = false) {
+	global $imap_general_debug;
+    global $sqimap_delimiter;
 
-		if (strtolower($optional_delimiter) == "detect") {
-      	fputs ($imap_stream, ". LIST \"INBOX\" \"\"\r\n");
-      	$read = sqimap_read_data($imap_stream, ".", true, $a, $b);
-      	$quote_position = strpos ($read[0], "\"");
-      	$delim = substr ($read[0], $quote_position+1, 1);
-      	return $delim;
+	/* Do some caching here */
+    if (!$sqimap_delimiter) {
+		if (sqimap_capability($imap_stream, "NAMESPACE")) {
+			/* According to something that I can't find, this is supposed to work on all systems
+			   OS: This won't work in Courier IMAP.
+			   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...
+			*/
+			fputs ($imap_stream, "a001 NAMESPACE\r\n");
+			$read = sqimap_read_data($imap_stream, "a001", true, $a, $b);
+			if (eregi('\* NAMESPACE +(\( *\(.+\) *\)|NIL) +(\( *\(.+\) *\)|NIL) +(\( *\(.+\) *\)|NIL)', $read[0], $data)) {
+				if (eregi('^\( *\((.*)\) *\)', $data[1], $data2))
+					$pn = $data2[1];
+				$pna = explode(')(', $pn);
+				while (list($k, $v) = each($pna))
+				{
+					list($_, $n, $_, $d) = explode('"', $v);
+					$pn[$n] = $d;
+				}
+/* OS: We don't need this code right now, it is for other_users and shared folders
+				if (eregi('^\( *\((.*)\) *\)', $data[2], $data2))
+					$on = $data2[1];
+				if (eregi('^\( *\((.*)\) *\)', $data[3], $data2))
+					$sn = $data2[1];
+				unset($data);
+				$ona = explode(')(', $on);
+				while (list($k, $v) = each($ona))
+				{
+					list($_, $n, $_, $d) = explode('"', $v);
+					$on[$n] = $d;
+				}
+				$sna = explode(')(', $sn);
+				while (list($k, $v) = each($sna))
+				{
+					list($_, $n, $_, $d) = explode('"', $v);
+					$sn[$n] = $d;
+				}
+*/
+			}
+			$sqimap_delimiter = $pn[0];
 		} else {
-			return $optional_delimiter;
+			fputs ($imap_stream, ". LIST \"INBOX\" \"\"\r\n");
+			$read = sqimap_read_data($imap_stream, ".", true, $a, $b);
+			$quote_position = strpos ($read[0], "\"");
+			$sqimap_delimiter = substr ($read[0], $quote_position+1, 1);
 		}
-   
-   /* According to something that I can't find, this is supposed to work on all systems
-   
-      fputs ($imap_stream, "a001 NAMESPACE\r\n");
-      $read = sqimap_read_data($imap_stream, "a001", true, $a, $b);
-      eregi("\"\" \"(.)\"", $read[0], $regs);
-      return $regs[1];
-   */
-   }
-
-
+	}
+	return $sqimap_delimiter;
+}
 
 
    /******************************************************************************

+ 3 - 0
functions/imap_mailbox.php

@@ -201,6 +201,9 @@
       fputs ($imap_stream, "a001 LSUB \"\" \"*\"\r\n");
       $lsub_ary = sqimap_read_data ($imap_stream, "a001", true, $response, $message);
 
+	  /** OS: we don't want to parse last element of array, 'cause it is OK command, so we unset it **/
+	  unset($lsub_ary[count($lsub_ary)-1]);
+
       for ($i=0;$i < count($lsub_ary); $i++) {
          $sorted_lsub_ary[$i] = find_mailbox_name($lsub_ary[$i]);
          if ($sorted_lsub_ary[$i] == "INBOX")