From d29aac0e3969fcd88d2dc76698ea802718c200e6 Mon Sep 17 00:00:00 2001 From: lkehresman Date: Mon, 21 Feb 2000 12:00:17 +0000 Subject: [PATCH] Rewrote IMAP functions. git-svn-id: https://svn.code.sf.net/p/squirrelmail/code/trunk/squirrelmail@227 7612ce4b-ef26-0410-bec9-ea0150e637f0 --- functions/imap.php | 352 +--------------------------------- functions/imap_general.php | 226 ++++++++++++++++++++++ functions/imap_mailbox.php | 200 +++++++++++++++++++ functions/imap_messages.php | 272 ++++++++++++++++++++++++++ functions/mailbox_display.php | 30 +-- functions/mime.php | 2 +- functions/strings.php | 23 ++- 7 files changed, 746 insertions(+), 359 deletions(-) create mode 100755 functions/imap_general.php create mode 100755 functions/imap_mailbox.php create mode 100755 functions/imap_messages.php diff --git a/functions/imap.php b/functions/imap.php index f2b192ef..44c63bda 100644 --- a/functions/imap.php +++ b/functions/imap.php @@ -1,348 +1,10 @@ ERROR: Could not complete request.
  Reason given: $message

"; - exit; - } else if ($response == "BAD") { - echo "
ERROR: Bad or malformed request.
  Server responded: $message

"; - exit; - } - } - - return $data; - } - - /** Parse the incoming mailbox name and return a string that is the FOLDER.MAILBOX **/ - function findMailboxName($mailbox) { - $mailbox = trim($mailbox); - if (substr($mailbox, strlen($mailbox)-1, strlen($mailbox)) == "\"") { - $mailbox = substr($mailbox, 0, strlen($mailbox) - 1); - $pos = strrpos($mailbox, "\"") + 1; - $box = substr($mailbox, $pos, strlen($mailbox)); - } else { - $box = substr($mailbox, strrpos($mailbox, " ")+1, strlen($mailbox)); - } - return $box; - } - - /** - Finds the delimeter between mailboxes. This should now be more compliant across - different server types that vary in their RFC2060 compliance. - **/ - function findMailboxDelimeter($imapConnection) { - fputs($imapConnection, ". list \"\" *\n"); - $read = imapReadData($imapConnection, ".", true, $a, $b); - $quotePosition = strpos($read[0], "\""); - $delim = substr($read[0], $quotePosition+1, 1); - - return $delim; - } - - function getMailboxFlags($imapConnection, $mailbox) { - $name = findMailboxName($mailbox); - fputs ($imapConnection, "1 LIST \"$name\" *\n"); - $data = imapReadData($imapConnection, "1", true, $response, $message); - $mailbox = $data[0]; - $mailbox = trim($mailbox); - $mailbox = substr($mailbox, strpos($mailbox, "(")+1, strlen($mailbox)); - $mailbox = substr($mailbox, 0, strpos($mailbox, ")")); - $mailbox = str_replace("\\", "", $mailbox); - $mailbox = strtolower($mailbox); - $mailbox = explode(" ", $mailbox); - return $mailbox; - } - - // handles logging onto an imap server. - function loginToImapServer($username, $key, $imapServerAddress, $hide) { - require("../config/config.php"); - - $imapConnection = fsockopen($imapServerAddress, 143, &$errorNumber, &$errorString); - if (!$imapConnection) { - echo "Error connecting to IMAP Server.
"; - echo "$errorNumber : $errorString
"; - exit; - } - $serverInfo = fgets($imapConnection, 256); - - // login - fputs($imapConnection, "a001 LOGIN \"$username\" \"$key\"\n"); - $read = fgets($imapConnection, 1024); - if ($debug_login == true) { - echo "SERVER SAYS: $read
"; - } - - /** If the login attempt was UNsuccessful, lets see why **/ - if (substr($read, 0, 7) != "a001 OK") { - if (!$hide) { - if (substr($read, 0, 8) == "a001 BAD") { - echo "Bad request: $read
"; - exit; - } - else if (substr($read, 0, 7) == "a001 NO") { - echo "
"; - echo ""; - echo " "; - echo " "; - echo "
"; - echo "
ERROR
"; - echo "
"; - echo "

Unknown user or password incorrect.
Click here to try again.
"; - echo "
"; - echo ""; - exit; - } - else { - echo "Unknown error: $read
"; - exit; - } - } else { - exit; - } - } - - return $imapConnection; - } - - /** must be sent in the form: user.. **/ - function createFolder($imapConnection, $folder, $type) { - require ("../config/config.php"); - - if (strtolower($type) == "noselect") { - $dm = findMailboxDelimeter($imapConnection); - $folder = "$folder$dm"; - } else { - $folder = "$folder"; - } - fputs($imapConnection, "1 create \"$folder\"\n"); - $data = imapReadData($imapConnection, "1", false, $response, $message); - - if ($response == "NO") { - echo "
ERROR: Could not complete request.
  Reason given: $message

"; - echo "Possible solutions:
  • You may need to specify that the folder is a subfolder of INBOX
  • "; - echo "
  • Try renaming the folder to something different.
  • "; - exit; - } else if ($response == "BAD") { - echo "ERROR: Bad or malformed request.
      Server responded: $message

    "; - exit; - } - fputs($imapConnection, "1 SUBSCRIBE \"$folder\"\n"); - $data = imapReadData($imapConnection, "1", true, $response, $message); - } - - /** - This is a recursive function that checks to see if the folder has any subfolders, - and if so, it calls removeFolder on the subfolders first, then removes the parent - folder. - **/ - function removeFolder($imapConnection, $folder, $delimiter) { - global $boxes; - - // bug if there are 2 subfolders of a folder, it won't get to the second one - for ($i = 0; $i < count($boxes); $i++) { - if (strstr($boxes[$i]["UNFORMATTED"], $folder . $delimiter)) { - $newDelete = $boxes[$i]["UNFORMATTED"]; - $boxes = removeElement($boxes, $i); - removeFolder($imapConnection, $newDelete, $boxes, $delimiter); - } - } - - fputs ($imapConnection, "1 unsubscribe \"$folder\"\n"); - $data = imapReadData($imapConnection, "1", true, $response, $message); - fputs($imapConnection, "1 delete \"$folder\"\n"); - $data = imapReadData($imapConnection, "1", false, $response, $message); - if ($response == "NO") { - echo "ERROR: Could not delete the folder $folder.
    "; - echo "Probable causes:
    "; - echo "
  • This folder may contain subfolders. Delete all subfolders first
  • "; - echo "

    The actual message returned from the server was:
    $message
    "; - echo ""; - exit; - } else if ($response == "BAD") { - echo "ERROR: Bad or malformed request.
      Server responded: $message

    "; - echo ""; - exit; - } - } - - /** Sends back two arrays, boxesFormatted and boxesUnformatted **/ - function getFolderList($imapConnection, &$boxes) { - require ("../config/config.php"); - if (!function_exists("ary_sort")) - include("../functions/array.php"); - - /** First we get the inbox **/ - fputs($imapConnection, "1 LIST \"\" INBOX\n"); - $str = imapReadData($imapConnection, "1", true, $response, $message); - $dm = findMailboxDelimeter($imapConnection); - $g = 0; - for ($i = 0;$i < count($str); $i++) { - $mailbox = chop($str[$i]); - if (substr(findMailboxName($mailbox), 0, 1) != ".") { - $boxes[$g]["RAW"] = $mailbox; - - $mailbox = findMailboxName($mailbox); - $periodCount = countCharInString($mailbox, $dm); - if (substr($mailbox, -1) == $dm) - $periodCount--; - - // indent the correct number of spaces. - for ($j = 0;$j < $periodCount;$j++) - $boxes[$g]["FORMATTED"] = $boxes[$g]["FORMATTED"] . "  "; - - $boxes[$g]["FORMATTED"] = $boxes[$g]["FORMATTED"] . readShortMailboxName($mailbox, $dm); - $boxes[$g]["UNFORMATTED"] = $mailbox; - $boxes[$g]["ID"] = $g; - $g++; - } - } - - /** Next, we get all subscribed folders **/ - fputs($imapConnection, "1 LSUB \"\" *\n"); - $str = imapReadData($imapConnection, "1", true, $response, $message); - $dm = findMailboxDelimeter($imapConnection); - for ($i = 0;$i < count($str); $i++) { - $mailbox = chop($str[$i]); - if (substr(findMailboxName($mailbox), 0, 1) != ".") { - $boxes[$g]["RAW"] = $mailbox; - - // Get the mailbox name and format it. If there is a $dm at the end of it, remove it. - $mailbox = findMailboxName($mailbox); - $periodCount = countCharInString($mailbox, $dm); - if (substr($mailbox, -1) == $dm) - $periodCount = $periodCount - 1; - - // indent the correct number of spaces. - for ($j = 0;$j < $periodCount;$j++) - $boxes[$g]["FORMATTED"] = $boxes[$g]["FORMATTED"] . "  "; - - $boxes[$g]["FORMATTED"] = $boxes[$g]["FORMATTED"] . readShortMailboxName($mailbox, $dm); - $boxes[$g]["UNFORMATTED"] = $mailbox; - $boxes[$g]["ID"] = $g; - $g++; - } - } - - $original = $boxes; - - for ($i = 0; $i < count($original); $i++) { - $boxes[$i]["UNFORMATTED"] = strtolower($boxes[$i]["UNFORMATTED"]); - } - - $boxes = ary_sort($boxes, "UNFORMATTED", 1); - - for ($i = 0; $i < count($original); $i++) { - for ($j = 0; $j < count($original); $j++) { - if ($boxes[$i]["ID"] == $original[$j]["ID"]) { - $boxes[$i]["UNFORMATTED"] = $original[$j]["UNFORMATTED"]; - $boxes[$i]["FORMATTED"] = $original[$j]["FORMATTED"]; - $boxes[$i]["RAW"] = $original[$j]["RAW"]; - } - } - } - - for ($i = 0; $i < count($boxes); $i++) { - if ($boxes[$i]["UNFORMATTED"] == $special_folders[0]) { - $boxesnew[0]["FORMATTED"] = $boxes[$i]["FORMATTED"]; - $boxesnew[0]["UNFORMATTED"] = trim($boxes[$i]["UNFORMATTED"]); - $boxesnew[0]["RAW"] = trim($boxes[$i]["RAW"]); - $boxes[$i]["USED"] = true; - } - } - if ($list_special_folders_first == true) { - for ($i = 0; $i < count($boxes); $i++) { - for ($j = 1; $j < count($special_folders); $j++) { - if (substr($boxes[$i]["UNFORMATTED"], 0, strlen($special_folders[$j])) == $special_folders[$j]) { - $pos = count($boxesnew); - $boxesnew[$pos]["FORMATTED"] = $boxes[$i]["FORMATTED"]; - $boxesnew[$pos]["RAW"] = trim($boxes[$i]["RAW"]); - $boxesnew[$pos]["UNFORMATTED"] = trim($boxes[$i]["UNFORMATTED"]); - $boxes[$i]["USED"] = true; - } - } - } - } - for ($i = 0; $i < count($boxes); $i++) { - if (($boxes[$i]["UNFORMATTED"] != $special_folders[0]) && - ($boxes[$i]["UNFORMATTED"] != ".mailboxlist") && - ($boxes[$i]["USED"] == false)) { - $pos = count($boxesnew); - $boxesnew[$pos]["FORMATTED"] = $boxes[$i]["FORMATTED"]; - $boxesnew[$pos]["RAW"] = trim($boxes[$i]["RAW"]); - $boxesnew[$pos]["UNFORMATTED"] = trim($boxes[$i]["UNFORMATTED"]); - $boxes[$i]["USED"] = true; - } - } - - $boxes = $boxesnew; - } - - function deleteMessages($imapConnection, $a, $b, $numMessages, $trash_folder, $move_to_trash, $auto_expunge, $mailbox) { - /** check if they would like to move it to the trash folder or not */ - if (($move_to_trash == true) && (folderExists($imapConnection, $trash_folder))) { - $success = copyMessages($imapConnection, $a, $b, $trash_folder); - if ($success == true) - setMessageFlag($imapConnection, $a, $b, "Deleted"); - else - echo "There was an error moving the messages.
    Messages NOT deleted."; - } else { - setMessageFlag($imapConnection, $a, $b, "Deleted"); - } - if ($auto_expunge == true) - expungeBox($imapConnection, $mailbox); - } - - function stripComments($line) { - if (strpos($line, ";")) { - $line = substr($line, 0, strpos($line, ";")); - } - - if (strpos($line, "(") && strpos($line, ")")) { - $full_line = $full_line . substr($line, 0, strpos($line, "(")); - $full_line = $full_line . substr($line, strpos($line, ")")+1, strlen($line) - strpos($line, ")")); - } else { - $full_line = $line; - } - return $full_line; - } - - function folderExists($imapConnection, $folderName) { - getFolderList($imapConnection, $folders); - $found = false; - for ($i = 0; ($i < count($folders)) && (!$found); $i++) { - if ($folders[$i]["UNFORMATTED"] == $folderName) - $found = true; - } - return $found; - } + + include ("../functions/imap_mailbox.php"); + include ("../functions/imap_messages.php"); + include ("../functions/imap_general.php"); ?> + diff --git a/functions/imap_general.php b/functions/imap_general.php new file mode 100755 index 00000000..c3def07a --- /dev/null +++ b/functions/imap_general.php @@ -0,0 +1,226 @@ +"; + echo _("ERROR : Could not complete request."); + echo "
    "; + echo _("Reason Given: "); + echo "$message

    "; + exit; + } else if ($response == "BAD") { + echo "
    "; + echo _("ERROR : Bad or malformed request."); + echo "
    "; + echo _("Server responded: "); + echo "$message

    "; + exit; + } + } + + 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. + ******************************************************************************/ + function sqimap_login ($username, $password, $imap_server_address, $hide) { + global $color; + $imap_stream = fsockopen ($imap_server_address, 143, &$error_number, &$error_string); + $server_info = fgets ($imap_stream, 1024); + + /** Do some error correction **/ + if (!$imap_stream) { + if (!$hide) { + echo "Error connecting to IMAP server: $imap_server_address.
    \n"; + echo "$error_number : $error_string
    \n"; + } + exit; + } + + fputs ($imap_stream, "a001 LOGIN \"$username\" \"$password\"\n"); + $read = fgets ($imap_stream, 1024); + + /** If the connection was not successful, lets see why **/ + if (substr($read, 0, 7) != "a001 OK") { + if (!$hide) { + if (substr($read, 0, 8) == "a001 BAD") { + echo "Bad request: $read
    \n"; + exit; + } else if (substr($read, 0, 7) == "a001 NO") { + ?> + + > +
    + align=center> + + + + + + +
    > + > +
    + +
    +
    +
    + > +
    +
    + +
    +
    +
    + + + "; + exit; + } + } else { + exit; + } + } + + return $imap_stream; + } + + + + + /****************************************************************************** + ** Simply logs out the imap session + ******************************************************************************/ + function sqimap_logout ($imap_stream) { + fputs ($imap_stream, "a001 LOGOUT\n"); + } + + + + /****************************************************************************** + ** Returns the delimeter between mailboxes: INBOX/Test, or INBOX.Test... + ******************************************************************************/ + function sqimap_get_delimiter ($imap_stream) { + fputs ($imap_stream, ". LIST \"\" *\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; + } + + + + + /****************************************************************************** + ** Gets the number of messages in the current mailbox. + ******************************************************************************/ + function sqimap_get_num_messages ($imap_stream, $mailbox) { + fputs ($imap_stream, "a001 EXAMINE \"$mailbox\"\n"); + $read_ary = sqimap_read_data ($imap_stream, "a001", true, $result, $message); + for ($i = 0; $i < count($read_ary); $i++) { + if (substr(trim($read_ary[$i]), -6) == EXISTS) { + $array = explode (" ", $read_ary[$i]); + $num = $array[1]; + } + } + return $num; + } + + + /****************************************************************************** + ** Returns a displayable email address + ******************************************************************************/ + function sqimap_find_email ($string) { + /** Luke Ehresman + ** + ** lehresma@css.tayloru.edu + **/ + + if (strpos($string, "<") && strpos($string, ">")) { + $string = substr($string, strpos($string, "<")+1); + $string = substr($string, 0, strpos($string, ">")); + } + return $string; + } + + + /****************************************************************************** + ** Returns a displayable email address + ******************************************************************************/ + function sqimap_find_displayable_name ($string) { + if (strpos($string, "<") && strpos($string, ">")) { + if (strpos($string, "<") == 0) { + $string = sqimap_find_email($string); + } else { + $string = substr($string, 0, strpos($string, "<")); + } + } + return $string; + } + + + + /****************************************************************************** + ** Returns the number of unseen messages in this folder + ******************************************************************************/ + function sqimap_unseen_messages ($imap_stream, &$num_unseen) { + fputs ($imap_stream, "a001 SEARCH UNSEEN NOT DELETED\n"); + $read_ary = sqimap_read_data ($imap_stream, "a001", true, $result, $message); + $unseen = false; + + if (strlen($read_ary[0]) > 10) { + $unseen = true; + $ary = explode (" ", $read_ary[0]); + $num_unseen = count($ary) - 2; + } else { + $unseen = false; + $num_unseen = 0; + } + + return $unseen; + } +?> diff --git a/functions/imap_mailbox.php b/functions/imap_mailbox.php new file mode 100755 index 00000000..16b50a2e --- /dev/null +++ b/functions/imap_mailbox.php @@ -0,0 +1,200 @@ + diff --git a/functions/imap_messages.php b/functions/imap_messages.php new file mode 100755 index 00000000..ab986688 --- /dev/null +++ b/functions/imap_messages.php @@ -0,0 +1,272 @@ + 0) { + $bound = substr($bound, $pos, strpos($line, " ", $pos)); + } else { + $bound = substr($bound, $pos); + } + $bound = str_replace("\"", "", $bound); + $header["BOUNDARY"] = $bound; + } + + /** Detect the charset **/ + if (strpos(strtolower(trim($line)), "charset=")) { + $pos = strpos($line, "charset=") + 8; + $charset = trim($line); + if (strpos($line, " ", $pos) > 0) { + $charset = substr($charset, $pos, strpos($line, " ", $pos)); + } else { + $charset = substr($charset, $pos); + } + $charset = str_replace("\"", "", $charset); + $header["CHARSET"] = $charset; + } else { + $header["CHARSET"] = "us-ascii"; + } + + /** Detects filename if any **/ + if (strpos(strtolower(trim($line)), "name=")) { + $pos = strpos($line, "name=") + 5; + $name = trim($line); + if (strpos($line, " ", $pos) > 0) { + $name = substr($name, $pos, strpos($line, " ", $pos)); + } else { + $name = substr($name, $pos); + } + $name = str_replace("\"", "", $name); + $header["FILENAME"] = $name; + } + } + + /** REPLY-TO **/ + else if (strtolower(substr($read[$i], 0, 9)) == "reply-to:") { + $header["REPLYTO"] = trim(substr($read[$i], 9, strlen($read[$i]))); + $i++; + } + + /** FROM **/ + else if (strtolower(substr($read[$i], 0, 5)) == "from:") { + $header["FROM"] = trim(substr($read[$i], 5, strlen($read[$i]) - 6)); + if ($header["REPLYTO"] == "") + $header["REPLYTO"] = $header["FROM"]; + $i++; + } + /** DATE **/ + else if (strtolower(substr($read[$i], 0, 5)) == "date:") { + $d = substr($read[$i], 5); + $d = trim($d); + $d = ereg_replace(" ", " ", $d); + $d = explode(" ", $d); + $header["DATE"] = getTimeStamp($d); + $i++; + } + /** SUBJECT **/ + else if (strtolower(substr($read[$i], 0, 8)) == "subject:") { + $header["SUBJECT"] = trim(substr($read[$i], 8, strlen($read[$i]) - 9)); + if (strlen(Chop($header["SUBJECT"])) == 0) + $header["SUBJECT"] = "(no subject)"; + $i++; + } + /** CC **/ + else if (strtolower(substr($read[$i], 0, 3)) == "cc:") { + $pos = 0; + $header["CC"][$pos] = trim(substr($read[$i], 4)); + $i++; + while ((substr($read[$i], 0, 1) == " ") && (trim($read[$i]) != "")) { + $pos++; + $header["CC"][$pos] = trim($read[$i]); + $i++; + } + } + /** TO **/ + else if (strtolower(substr($read[$i], 0, 3)) == "to:") { + $pos = 0; + $header["TO"][$pos] = trim(substr($read[$i], 4)); + $i++; + while ((substr($read[$i], 0, 1) == " ") && (trim($read[$i]) != "")){ + $pos++; + $header["TO"][$pos] = trim($read[$i]); + $i++; + } + } + + /** ERROR CORRECTION **/ + else if (substr($read[$i], 0, 1) == ")") { + if ($header["SUBJECT"] == "") + $header["SUBJECT"] = "(no subject)"; + + if ($header["FROM"] == "") + $header["FROM"] = "(unknown sender)"; + + if ($header["DATE"] == "") + $header["DATE"] = time(); + $i++; + } + else { + $i++; + } + } + return $header; + } + + /****************************************************************************** + ** Returns the body of a message. + ******************************************************************************/ + function sqimap_get_message_body ($imap_stream, $bound, $id, $type0, $type1) { + fputs ($imap_stream, "a001 FETCH $id:$id BODY[TEXT]\n"); + $read = sqimap_read_data ($imap_stream, "a001", true, $response, $message); + + $i = 0; + $j = 0; + while ($i < count($read)) { + if ( ($i != 0) && ($i != count($read)-1) && ($i != count($read)) ) { + $bodytmp[$j] = $read[$i]; + $j++; + } + $i++; + } + $body = $bodytmp; + return decodeMime($body, $bound, $type0, $type1); + } +?> diff --git a/functions/mailbox_display.php b/functions/mailbox_display.php index a4ed4b0f..d9f52b7b 100644 --- a/functions/mailbox_display.php +++ b/functions/mailbox_display.php @@ -10,7 +10,7 @@ function printMessageInfo($imapConnection, $t, $i, $from, $subject, $dateString, $answered, $seen, $mailbox, $sort, $startMessage) { require ("../config/config.php"); - $senderName = getSenderName($from); + $senderName = $from; $urlMailbox = urlencode($mailbox); $subject = trim(stripslashes($subject)); echo "\n"; @@ -34,9 +34,14 @@ function showMessagesForMailbox($imapConnection, $mailbox, $numMessages, $startMessage, $sort, $color) { include ("../config/config.php"); - if (1 <= $numMessages) { - getMessageHeaders($imapConnection, 1, $numMessages, $from, $subject, $date); - getMessageFlags($imapConnection, 1, $numMessages, $flags); + if ($numMessages >= 1) { + for ($q = 0; $q < $numMessages; $q++) { + sqimap_get_small_header ($imapConnection, $q+1, $f, $s, $d); + $from[$q] = $f; + $date[$q] = $d; + $subject[$q] = $s; + } + $flags = sqimap_get_flags ($imapConnection, 1, $numMessages); } $j = 0; @@ -47,7 +52,7 @@ $messages[$j]["TIME_STAMP"] = getTimeStamp($tmpdate); $messages[$j]["DATE_STRING"] = getDateString($messages[$j]["TIME_STAMP"]); $messages[$j]["ID"] = $j+1; - $messages[$j]["FROM"] = getSenderName($from[$j]); + $messages[$j]["FROM"] = $from[$j]; $messages[$j]["SUBJECT"] = $subject[$j]; $messages[$j]["FLAG_DELETED"] = false; $messages[$j]["FLAG_ANSWERED"] = false; @@ -192,21 +197,21 @@ echo " ". _("Move selected to:") .""; echo "