Changeset 4088 in subversion for trunk/roundcubemail/program/include/rcube_imap_generic.php
- Timestamp:
- Oct 14, 2010 6:22:25 AM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/roundcubemail/program/include/rcube_imap_generic.php
r4041 r4088 113 113 private $prefs; 114 114 115 const ERROR_OK = 0; 116 const ERROR_NO = -1; 117 const ERROR_BAD = -2; 118 const ERROR_BYE = -3; 119 const ERROR_COMMAND = -5; 120 const ERROR_UNKNOWN = -4; 121 115 122 /** 116 123 * Object constructor … … 265 272 } 266 273 267 function parseResult($string) 268 { 269 $a = explode(' ', trim($string)); 270 if (count($a) >= 2) { 271 $res = strtoupper($a[1]); 274 function parseResult($string, $err_prefix='') 275 { 276 if (preg_match('/^[a-z0-9*]+ (OK|NO|BAD|BYE)(.*)$/i', trim($string), $matches)) { 277 $res = strtoupper($matches[1]); 278 $str = trim($matches[2]); 279 272 280 if ($res == 'OK') { 273 return 0;281 return self::ERROR_OK; 274 282 } else if ($res == 'NO') { 275 return -1;283 $this->errornum = self::ERROR_NO; 276 284 } else if ($res == 'BAD') { 277 return -2;285 $this->errornum = self::ERROR_BAD; 278 286 } else if ($res == 'BYE') { 279 287 @fclose($this->fp); 280 288 $this->fp = null; 281 return -3; 282 } 283 } 284 return -4; 289 $this->errornum = self::ERROR_BYE; 290 } 291 292 if ($str) 293 $this->error = $err_prefix ? $err_prefix.$str : $str; 294 295 return $this->errornum; 296 } 297 return self::ERROR_UNKNOWN; 298 } 299 300 private function set_error($code, $msg='') 301 { 302 $this->errornum = $code; 303 $this->error = $msg; 285 304 } 286 305 … … 378 397 // process result 379 398 $result = $this->parseResult($line); 380 if ($result == 0) { 381 $this->errornum = 0; 399 if ($result == self::ERROR_OK) { 382 400 return $this->fp; 383 401 } 384 402 385 $this->error = "Authentication for $user failed (AUTH): $line"; 386 $this->errornum = $result; 403 $this->error = "Authentication for $user failed (AUTH): $line"; 387 404 388 405 return $result; … … 403 420 $result = $this->parseResult($line); 404 421 405 if ($result == 0) { 406 $this->errornum = 0; 422 if ($result == self::ERROR_OK) { 407 423 return $this->fp; 408 424 } 409 425 410 426 @fclose($this->fp); 411 $this->fp = false; 412 413 $this->error = "Authentication for $user failed (LOGIN): $line"; 414 $this->errornum = $result; 427 $this->fp = false; 428 $this->error = "Authentication for $user failed (LOGIN): $line"; 415 429 416 430 return $result; … … 551 565 // initialize connection 552 566 $this->error = ''; 553 $this->errornum = 0;567 $this->errornum = self::ERROR_OK; 554 568 $this->selected = ''; 555 569 $this->user = $user; … … 559 573 // check input 560 574 if (empty($host)) { 561 $this->error = "Empty host"; 562 $this->errornum = -2; 575 $this->set_error(self::ERROR_BAD, "Empty host"); 563 576 return false; 564 577 } 565 578 if (empty($user)) { 566 $this->error = "Empty user"; 567 $this->errornum = -1; 579 $this->set_error(self::ERROR_NO, "Empty user"); 568 580 return false; 569 581 } 570 582 if (empty($password)) { 571 $this->error = "Empty password"; 572 $this->errornum = -1; 583 $this->set_error(self::ERROR_NO, "Empty password"); 573 584 return false; 574 585 } … … 589 600 590 601 if (!$this->fp) { 591 $this->error = sprintf("Could not connect to %s:%d: %s", $host, $this->prefs['port'], $errstr); 592 $this->errornum = -2; 602 $this->set_error(self::ERROR_BAD, sprintf("Could not connect to %s:%d: %s", $host, $this->prefs['port'], $errstr)); 593 603 return false; 594 604 } … … 609 619 else 610 620 $this->error = sprintf("Empty startup greeting (%s:%d)", $host, $this->prefs['port']); 611 $this->errornum = -2;621 $this->errornum = self::ERROR_BAD; 612 622 return false; 613 623 } … … 627 637 $line = $this->readLine(4096); 628 638 if (!preg_match('/^tls0 OK/', $line)) { 629 $this->error = "Server responded to STARTTLS with: $line"; 630 $this->errornum = -2; 639 $this->set_error(self::ERROR_BAD, "Server responded to STARTTLS with: $line"); 631 640 return false; 632 641 } 633 642 634 643 if (!stream_socket_enable_crypto($this->fp, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) { 635 $this->error = "Unable to negotiate TLS"; 636 $this->errornum = -2; 644 $this->set_error(self::ERROR_BAD, "Unable to negotiate TLS"); 637 645 return false; 638 646 } … … 666 674 667 675 // stop if server sent BYE response 668 if ($result == -3) {676 if ($result == self::ERROR_BYE) { 669 677 return false; 670 678 } … … 718 726 } 719 727 720 if ($this->putLine("sel1 SELECT \"".$this->escape($mailbox).'"')) { 721 do { 722 $line = rtrim($this->readLine(512)); 723 724 if (preg_match('/^\* ([0-9]+) (EXISTS|RECENT)$/', $line, $m)) { 725 $token = strtolower($m[2]); 726 $this->$token = (int) $m[1]; 727 } 728 else if (preg_match('/\[?PERMANENTFLAGS\s+\(([^\)]+)\)\]/U', $line, $match)) { 729 $this->permanentflags = explode(' ', $match[1]); 730 } 731 } while (!$this->startsWith($line, 'sel1', true, true)); 732 733 if ($this->parseResult($line) == 0) { 734 $this->selected = $mailbox; 735 return true; 736 } 737 } 738 739 $this->error = "Couldn't select $mailbox"; 728 $command = "sel1 SELECT \"".$this->escape($mailbox).'"'; 729 730 if (!$this->putLine($command)) { 731 $this->set_error(self::ERROR_COMMAND, "Unable to send command: $command"); 732 return false; 733 } 734 735 do { 736 $line = rtrim($this->readLine(512)); 737 738 if (preg_match('/^\* ([0-9]+) (EXISTS|RECENT)$/', $line, $m)) { 739 $token = strtolower($m[2]); 740 $this->$token = (int) $m[1]; 741 } 742 else if (preg_match('/\[?PERMANENTFLAGS\s+\(([^\)]+)\)\]/U', $line, $match)) { 743 $this->permanentflags = explode(' ', $match[1]); 744 } 745 } while (!$this->startsWith($line, 'sel1', true, true)); 746 747 if ($this->parseResult($line, 'SELECT: ') == self::ERROR_OK) { 748 $this->selected = $mailbox; 749 return true; 750 } 751 740 752 return false; 741 753 } … … 802 814 803 815 if (!$this->putLineC($command)) { 816 $this->set_error(self::ERROR_COMMAND, "Unable to send command: $command"); 804 817 return false; 805 818 } … … 813 826 } while (!$this->startsWith($line, 's ', true, true)); 814 827 815 $result_code = $this->parseResult($line); 816 if ($result_code != 0) { 817 $this->error = "Sort: $line"; 828 $result_code = $this->parseResult($line, 'SORT: '); 829 if ($result_code != self::ERROR_OK) { 818 830 return false; 819 831 } … … 883 895 884 896 if (!$this->putLine($request)) { 897 $this->set_error(self::ERROR_COMMAND, "Unable to send command: $request"); 885 898 return false; 886 899 } … … 1016 1029 1017 1030 $result = -1; 1018 if ($this->putLine("fuid FETCH $id (UID)")) { 1019 do { 1020 $line = rtrim($this->readLine(1024)); 1021 if (preg_match("/^\* $id FETCH \(UID (.*)\)/i", $line, $r)) { 1022 $result = $r[1]; 1023 } 1024 } while (!$this->startsWith($line, 'fuid', true, true)); 1025 } 1031 $command = "fuid FETCH $id (UID)"; 1032 1033 if (!$this->putLine($command)) { 1034 $this->set_error(self::ERROR_COMMAND, "Unable to send command: $command"); 1035 return -1; 1036 } 1037 1038 do { 1039 $line = rtrim($this->readLine(1024)); 1040 if (preg_match("/^\* $id FETCH \(UID (.*)\)/i", $line, $r)) { 1041 $result = $r[1]; 1042 } 1043 } while (!$this->startsWith($line, 'fuid', true, true)); 1026 1044 1027 1045 return $result; … … 1064 1082 1065 1083 if (!$this->putLine($request)) { 1084 $this->set_error(self::ERROR_COMMAND, "Unable to send command: $request"); 1066 1085 return false; 1067 1086 } … … 1369 1388 1370 1389 $c = 0; 1371 $command = $messages ? "UID EXPUNGE $messages" : "EXPUNGE"; 1372 1373 if (!$this->putLine("exp1 $command")) { 1390 $command = $messages ? "exp1 UID EXPUNGE $messages" : "exp1 EXPUNGE"; 1391 1392 if (!$this->putLine($command)) { 1393 $this->set_error(self::ERROR_COMMAND, "Unable to send command: $command"); 1374 1394 return -1; 1375 1395 } … … 1382 1402 } while (!$this->startsWith($line, 'exp1', true, true)); 1383 1403 1384 if ($this->parseResult($line ) == 0) {1404 if ($this->parseResult($line, 'EXPUNGE: ') == self::ERROR_OK) { 1385 1405 $this->selected = ''; // state has changed, need to reselect 1386 1406 return $c; 1387 1407 } 1388 $this->error = $line; 1408 1389 1409 return -1; 1390 1410 } … … 1403 1423 1404 1424 $c = 0; 1405 if (!$this->putLine("flg UID STORE $messages {$mod}FLAGS ($flag)")) { 1425 $command = "flg UID STORE $messages {$mod}FLAGS ($flag)"; 1426 if (!$this->putLine($command)) { 1427 $this->set_error(self::ERROR_COMMAND, "Unable to send command: $command"); 1406 1428 return false; 1407 1429 } … … 1414 1436 } while (!$this->startsWith($line, 'flg', true, true)); 1415 1437 1416 if ($this->parseResult($line ) == 0) {1438 if ($this->parseResult($line, 'STORE: ') == self::ERROR_OK) { 1417 1439 return $c; 1418 1440 } 1419 1441 1420 $this->error = $line;1421 1442 return -1; 1422 1443 } … … 1444 1465 } 1445 1466 1446 $this->putLine("cpy1 UID COPY $messages \"".$this->escape($to)."\""); 1447 $line = $this->readReply(); 1448 return $this->parseResult($line); 1467 $command = "cpy1 UID COPY $messages \"".$this->escape($to)."\""; 1468 1469 if (!$this->putLine($command)) { 1470 $this->set_error(self::ERROR_COMMAND, "Unable to send command: $command"); 1471 } 1472 1473 $line = $this->readReply(); 1474 return $this->parseResult($line, 'COPY: '); 1449 1475 } 1450 1476 … … 1526 1552 $data = ''; 1527 1553 1528 if (!$this->putLineC("thrd1 THREAD $algorithm $encoding $criteria")) { 1554 $command = "thrd1 THREAD $algorithm $encoding $criteria"; 1555 1556 if (!$this->putLineC($command)) { 1557 $this->set_error(self::ERROR_COMMAND, "Unable to send command: $command"); 1529 1558 return false; 1530 1559 } … … 1538 1567 } while (!$this->startsWith($line, 'thrd1', true, true)); 1539 1568 1540 $result_code = $this->parseResult($line );1541 if ($result_code == 0) {1569 $result_code = $this->parseResult($line, 'THREAD: '); 1570 if ($result_code == self::ERROR_OK) { 1542 1571 $depthmap = array(); 1543 1572 $haschildren = array(); … … 1546 1575 } 1547 1576 1548 $this->error = "Thread: $line";1549 1577 return false; 1550 1578 } … … 1567 1595 1568 1596 if (!$this->putLineC($query)) { 1597 $this->set_error(self::ERROR_COMMAND, "Unable to send command: $query"); 1569 1598 return false; 1570 1599 } … … 1579 1608 } while (!$this->startsWith($line, 'srch1', true, true)); 1580 1609 1581 $result_code = $this->parseResult($line );1582 if ($result_code == 0) {1610 $result_code = $this->parseResult($line, 'SEARCH: '); 1611 if ($result_code == self::ERROR_OK) { 1583 1612 return preg_split('/\s+/', $data, -1, PREG_SPLIT_NO_EMPTY); 1584 1613 } 1585 1614 1586 $this->error = "Search: $line";1587 1615 return false; 1588 1616 } … … 1633 1661 $ref = $this->escape($ref); 1634 1662 $mailbox = $this->escape($mailbox); 1663 $query = $key." ".$command." \"". $ref ."\" \"". $mailbox ."\""; 1635 1664 1636 1665 // send command 1637 if (!$this->putLine($ key." ".$command." \"". $ref ."\" \"". $mailbox ."\"")) {1638 $this->error = "Couldn't send $command command";1666 if (!$this->putLine($query)) { 1667 $this->set_error(self::ERROR_COMMAND, "Unable to send command: $query"); 1639 1668 return false; 1640 1669 } … … 1658 1687 if (is_array($folders)) { 1659 1688 return $folders; 1660 } else if ($this->parseResult($line ) == 0) {1689 } else if ($this->parseResult($line, $command.': ') == self::ERROR_OK) { 1661 1690 return array(); 1662 1691 } 1663 1692 1664 $this->error = $line;1665 1693 return false; 1666 1694 } … … 1687 1715 // send request 1688 1716 if (!$this->putLine($request)) { 1717 $this->set_error(self::ERROR_COMMAND, "Unable to send command: $request"); 1689 1718 return false; 1690 1719 } … … 1742 1771 // send request 1743 1772 if (!$this->putLine($request)) { 1773 $this->set_error(self::ERROR_COMMAND, "Unable to send command: $request"); 1744 1774 return false; 1745 1775 } … … 1867 1897 function createFolder($folder) 1868 1898 { 1869 if ($this->putLine('c CREATE "' . $this->escape($folder) . '"')) { 1870 do { 1871 $line = $this->readLine(300); 1872 } while (!$this->startsWith($line, 'c ', true, true)); 1873 return ($this->parseResult($line) == 0); 1874 } 1875 return false; 1899 $command = 'c CREATE "' . $this->escape($folder) . '"'; 1900 1901 if (!$this->putLine($command)) { 1902 $this->set_error(self::ERROR_COMMAND, "Unable to send command: $command"); 1903 return false; 1904 } 1905 1906 do { 1907 $line = $this->readLine(300); 1908 } while (!$this->startsWith($line, 'c ', true, true)); 1909 1910 return ($this->parseResult($line, 'CREATE: ') == self::ERROR_OK); 1876 1911 } 1877 1912 1878 1913 function renameFolder($from, $to) 1879 1914 { 1880 if ($this->putLine('r RENAME "' . $this->escape($from) . '" "' . $this->escape($to) . '"')) { 1881 do { 1882 $line = $this->readLine(300); 1883 } while (!$this->startsWith($line, 'r ', true, true)); 1884 return ($this->parseResult($line) == 0); 1885 } 1886 return false; 1915 $command = 'r RENAME "' . $this->escape($from) . '" "' . $this->escape($to) . '"'; 1916 1917 if (!$this->putLine($command)) { 1918 $this->set_error(self::ERROR_COMMAND, "Unable to send command: $command"); 1919 return false; 1920 } 1921 do { 1922 $line = $this->readLine(300); 1923 } while (!$this->startsWith($line, 'r ', true, true)); 1924 1925 return ($this->parseResult($line, 'RENAME: ') == self::ERROR_OK); 1887 1926 } 1888 1927 1889 1928 function deleteFolder($folder) 1890 1929 { 1891 if ($this->putLine('d DELETE "' . $this->escape($folder). '"')) { 1892 do { 1893 $line = $this->readLine(300); 1894 } while (!$this->startsWith($line, 'd ', true, true)); 1895 return ($this->parseResult($line) == 0); 1896 } 1897 return false; 1930 $command = 'd DELETE "' . $this->escape($folder). '"'; 1931 1932 if (!$this->putLine($command)) { 1933 $this->set_error(self::ERROR_COMMAND, "Unable to send command: $command"); 1934 return false; 1935 } 1936 do { 1937 $line = $this->readLine(300); 1938 } while (!$this->startsWith($line, 'd ', true, true)); 1939 1940 return ($this->parseResult($line, 'DELETE: ') == self::ERROR_OK); 1898 1941 } 1899 1942 … … 1909 1952 function subscribe($folder) 1910 1953 { 1911 $query = 'sub1 SUBSCRIBE "' . $this->escape($folder). '"'; 1912 $this->putLine($query); 1954 $command = 'sub1 SUBSCRIBE "' . $this->escape($folder). '"'; 1955 1956 if (!$this->putLine($command)) { 1957 $this->set_error(self::ERROR_COMMAND, "Unable to send command: $command"); 1958 return false; 1959 } 1913 1960 1914 1961 $line = trim($this->readLine(512)); 1915 return ($this->parseResult($line ) == 0);1962 return ($this->parseResult($line, 'SUBSCRIBE: ') == self::ERROR_OK); 1916 1963 } 1917 1964 1918 1965 function unsubscribe($folder) 1919 1966 { 1920 $query = 'usub1 UNSUBSCRIBE "' . $this->escape($folder) . '"'; 1921 $this->putLine($query); 1967 $command = 'usub1 UNSUBSCRIBE "' . $this->escape($folder) . '"'; 1968 1969 if (!$this->putLine($command)) { 1970 $this->set_error(self::ERROR_COMMAND, "Unable to send command: $command"); 1971 return false; 1972 } 1922 1973 1923 1974 $line = trim($this->readLine(512)); 1924 return ($this->parseResult($line ) == 0);1975 return ($this->parseResult($line, 'UNSUBSCRIBE: ') == self::ERROR_OK); 1925 1976 } 1926 1977 … … 1945 1996 1946 1997 if ($line[0] != '+') { 1947 // $errornum = $this->parseResult($line); 1948 $this->error = "Cannot write to folder: $line"; 1998 $this->parseResult($line, 'APPEND: '); 1949 1999 return false; 1950 2000 } … … 1958 2008 } while (!$this->startsWith($line, 'a ', true, true)); 1959 2009 1960 $result = ($this->parseResult($line) == 0); 1961 if (!$result) { 1962 $this->error = $line; 1963 } 1964 return $result; 1965 } 1966 1967 $this->error = "Couldn't send command \"$request\""; 2010 return ($this->parseResult($line, 'APPEND: ') == self::ERROR_OK); 2011 } 2012 else { 2013 $this->set_error(self::ERROR_COMMAND, "Unable to send command: $request"); 2014 } 2015 1968 2016 return false; 1969 2017 } … … 1981 2029 } 1982 2030 if (!$in_fp) { 1983 $this-> error = "Couldn't open $path for reading";2031 $this->set_error(self::ERROR_UNKNOWN, "Couldn't open $path for reading"); 1984 2032 return false; 1985 2033 } … … 2003 2051 2004 2052 if ($line[0] != '+') { 2005 //$errornum = $this->parseResult($line); 2006 $this->error = "Cannot write to folder: $line"; 2053 $this->parseResult($line, 'APPEND: '); 2007 2054 return false; 2008 2055 } … … 2029 2076 } while (!$this->startsWith($line, 'a ', true, true)); 2030 2077 2031 $result = ($this->parseResult($line) == 0); 2032 if (!$result) { 2033 $this->error = $line; 2034 } 2035 2036 return $result; 2037 } 2038 2039 $this->error = "Couldn't send command \"$request\""; 2078 2079 return ($this->parseResult($line, 'APPEND: ') == self::ERROR_OK); 2080 } 2081 else { 2082 $this->set_error(self::ERROR_COMMAND, "Unable to send command: $request"); 2083 } 2084 2040 2085 return false; 2041 2086 } … … 2049 2094 $key = 'F1247'; 2050 2095 $result = false; 2051 2052 if ($this->putLine($key . ($is_uid ? ' UID' : '') ." FETCH $id (BODYSTRUCTURE)")) { 2096 $command = $key . ($is_uid ? ' UID' : '') ." FETCH $id (BODYSTRUCTURE)"; 2097 2098 if ($this->putLine($command)) { 2053 2099 do { 2054 2100 $line = $this->readLine(5000); … … 2060 2106 $result = trim(substr($result, strpos($result, 'BODYSTRUCTURE')+13, -1)); 2061 2107 } 2108 else { 2109 $this->set_error(self::ERROR_COMMAND, "Unable to send command: $command"); 2110 } 2062 2111 2063 2112 return $result; … … 2074 2123 $result = false; 2075 2124 $quota_lines = array(); 2125 $command = 'QUOT1 GETQUOTAROOT "INBOX"'; 2076 2126 2077 2127 // get line(s) containing quota info 2078 if ($this->putLine( 'QUOT1 GETQUOTAROOT "INBOX"')) {2128 if ($this->putLine($command)) { 2079 2129 do { 2080 2130 $line = rtrim($this->readLine(5000)); … … 2084 2134 } while (!$this->startsWith($line, 'QUOT1', true, true)); 2085 2135 } 2136 else { 2137 $this->set_error(self::ERROR_COMMAND, "Unable to send command: $command"); 2138 } 2086 2139 2087 2140 // return false if not found, parse if found
Note: See TracChangeset
for help on using the changeset viewer.
