/**
 * 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_retrieve_imap_response($imap_stream, $tag, $handle_errors, &$response, &$message, $query = '', $filter = false, $outputstream = false, $no_return = false)
{
    global $color, $squirrelmail_language;
    $read = '';
    if (!is_array($message)) {
        $message = array();
    }
    if (!is_array($response)) {
        $response = array();
    }
    $aResponse = '';
    $resultlist = array();
    $data = array();
    $read = sqimap_fgets($imap_stream);
    $i = $k = 0;
    while ($read) {
        $char = $read[0];
        switch ($char) {
            case '+':
            default:
                $read = sqimap_fgets($imap_stream);
                break;
            case $tag[0]:
                /* get the command */
                $arg = '';
                $i = strlen($tag) + 1;
                $s = substr($read, $i);
                if (($j = strpos($s, ' ')) || ($j = strpos($s, "\n"))) {
                    $arg = substr($s, 0, $j);
                }
                $found_tag = substr($read, 0, $i - 1);
                if ($found_tag) {
                    switch ($arg) {
                        case 'OK':
                        case 'BAD':
                        case 'NO':
                        case 'BYE':
                        case 'PREAUTH':
                            $response[$found_tag] = $arg;
                            $message[$found_tag] = trim(substr($read, $i + strlen($arg)));
                            if (!empty($data)) {
                                $resultlist[] = $data;
                            }
                            $aResponse[$found_tag] = $resultlist;
                            $data = $resultlist = array();
                            if ($found_tag == $tag) {
                                break 3;
                                /* switch switch while */
                            }
                            break;
                        default:
                            /* this shouldn't happen */
                            $response[$found_tag] = $arg;
                            $message[$found_tag] = trim(substr($read, $i + strlen($arg)));
                            if (!empty($data)) {
                                $resultlist[] = $data;
                            }
                            $aResponse[$found_tag] = $resultlist;
                            $data = $resultlist = array();
                            if ($found_tag == $tag) {
                                break 3;
                                /* switch switch while */
                            }
                    }
                }
                $read = sqimap_fgets($imap_stream);
                if ($read === false) {
                    /* error */
                    break 3;
                    /* switch switch while */
                }
                break;
                // end case $tag{0}
            // end case $tag{0}
            case '*':
                if (preg_match('/^\\*\\s\\d+\\sFETCH/', $read)) {
                    /* check for literal */
                    $s = substr($read, -3);
                    $fetch_data = array();
                    do {
                        /* outer loop, continue until next untagged fetch
                           or tagged reponse */
                        do {
                            /* innerloop for fetching literals. with this loop
                               we prohibid that literal responses appear in the
                               outer loop so we can trust the untagged and
                               tagged info provided by $read */
                            if ($s === "}\r\n") {
                                $j = strrpos($read, '{');
                                $iLit = substr($read, $j + 1, -3);
                                $fetch_data[] = $read;
                                $sLiteral = sqimap_fread($imap_stream, $iLit, $filter, $outputstream, $no_return);
                                if ($sLiteral === false) {
                                    /* error */
                                    break 4;
                                    /* while while switch while */
                                }
                                /* backwards compattibility */
                                $aLiteral = explode("\n", $sLiteral);
                                /* release not neaded data */
                                unset($sLiteral);
                                foreach ($aLiteral as $line) {
                                    $fetch_data[] = $line . "\n";
                                }
                                /* release not neaded data */
                                unset($aLiteral);
                                /* next fgets belongs to this fetch because
                                   we just got the exact literalsize and there
                                   must follow data to complete the response */
                                $read = sqimap_fgets($imap_stream);
                                if ($read === false) {
                                    /* error */
                                    break 4;
                                    /* while while switch while */
                                }
                                $fetch_data[] = $read;
                            } else {
                                $fetch_data[] = $read;
                            }
                            /* retrieve next line and check in the while
                               statements if it belongs to this fetch response */
                            $read = sqimap_fgets($imap_stream);
                            if ($read === false) {
                                /* error */
                                break 4;
                                /* while while switch while */
                            }
                            /* check for next untagged reponse and break */
                            if ($read[0] == '*') {
                                break 2;
                            }
                            $s = substr($read, -3);
                        } while ($s === "}\r\n");
                        $s = substr($read, -3);
                    } while ($read[0] !== '*' && substr($read, 0, strlen($tag)) !== $tag);
                    $resultlist[] = $fetch_data;
                    /* release not neaded data */
                    unset($fetch_data);
                } else {
                    $s = substr($read, -3);
                    do {
                        if ($s === "}\r\n") {
                            $j = strrpos($read, '{');
                            $iLit = substr($read, $j + 1, -3);
                            $data[] = $read;
                            $sLiteral = fread($imap_stream, $iLit);
                            if ($sLiteral === false) {
                                /* error */
                                $read = false;
                                break 3;
                                /* while switch while */
                            }
                            $data[] = $sLiteral;
                            $data[] = sqimap_fgets($imap_stream);
                        } else {
                            $data[] = $read;
                        }
                        $read = sqimap_fgets($imap_stream);
                        if ($read === false) {
                            break 3;
                            /* while switch while */
                        } else {
                            if ($read[0] == '*') {
                                break;
                            }
                        }
                        $s = substr($read, -3);
                    } while ($s === "}\r\n");
                    break 1;
                }
                break;
                // end case '*'
        }
        // end switch
    }
    // end while
    /* error processing in case $read is false */
    if ($read === false) {
        // try to retrieve an untagged bye respons from the results
        $sResponse = array_pop($data);
        if ($sResponse !== NULL && strpos($sResponse, '* BYE') !== false) {
            if (!$handle_errors) {
                $query = '';
            }
            sqimap_error_box(_("ERROR : Imap server closed the connection."), $query, _("Server responded:"), $sResponse);
            echo '</body></html>';
            exit;
        } else {
            if ($handle_errors) {
                unset($data);
                sqimap_error_box(_("ERROR : Connection dropped by imap-server."), $query);
                exit;
            }
        }
    }
    /* Set $resultlist array */
    if (!empty($data)) {
        //$resultlist[] = $data;
    } elseif (empty($resultlist)) {
        $resultlist[] = array();
    }
    /* Return result or handle errors */
    if ($handle_errors == false) {
        return $aResponse;
    }
    switch ($response[$tag]) {
        case 'OK':
            return $aResponse;
            break;
        case 'NO':
            /* ignore this error from M$ exchange, it is not fatal (aka bug) */
            if (strstr($message[$tag], 'command resulted in') === false) {
                sqimap_error_box(_("ERROR : Could not complete request."), $query, _("Reason Given: "), $message[$tag]);
                echo '</body></html>';
                exit;
            }
            break;
        case 'BAD':
            sqimap_error_box(_("ERROR : Bad or malformed request."), $query, _("Server responded: "), $message[$tag]);
            echo '</body></html>';
            exit;
        case 'BYE':
            sqimap_error_box(_("ERROR : Imap server closed the connection."), $query, _("Server responded: "), $message[$tag]);
            echo '</body></html>';
            exit;
        default:
            sqimap_error_box(_("ERROR : Unknown imap response."), $query, _("Server responded: "), $message[$tag]);
            /* the error is displayed but because we don't know the reponse we
               return the result anyway */
            return $aResponse;
            break;
    }
}
Exemple #2
0
/**
 * 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_list($imap_stream, $tag_uid, $handle_errors, &$response, &$message, $query = '', $filter = false, $outputstream = false, $no_return = false)
{
    global $color, $squirrelmail_language;
    $read = '';
    $tag_uid_a = explode(' ', trim($tag_uid));
    $tag = $tag_uid_a[0];
    $resultlist = array();
    $data = array();
    $read = sqimap_fgets($imap_stream);
    $i = 0;
    while ($read) {
        $char = $read[0];
        switch ($char) {
            case '+':
            default:
                $read = sqimap_fgets($imap_stream);
                break;
            case $tag[0]:
                /* get the command */
                $arg = '';
                $i = strlen($tag) + 1;
                $s = substr($read, $i);
                if (($j = strpos($s, ' ')) || ($j = strpos($s, "\n"))) {
                    $arg = substr($s, 0, $j);
                }
                $found_tag = substr($read, 0, $i - 1);
                if ($arg && $found_tag == $tag) {
                    switch ($arg) {
                        case 'OK':
                        case 'BAD':
                        case 'NO':
                        case 'BYE':
                        case 'PREAUTH':
                            $response = $arg;
                            $message = trim(substr($read, $i + strlen($arg)));
                            break 3;
                            /* switch switch while */
                        /* switch switch while */
                        default:
                            /* this shouldn't happen */
                            $response = $arg;
                            $message = trim(substr($read, $i + strlen($arg)));
                            break 3;
                            /* switch switch while */
                    }
                } elseif ($found_tag !== $tag) {
                    /* reset data array because we do not need this reponse */
                    $data = array();
                    $read = sqimap_fgets($imap_stream);
                    break;
                }
                // end case $tag{0}
            // end case $tag{0}
            case '*':
                if (preg_match('/^\\*\\s\\d+\\sFETCH/', $read)) {
                    /* check for literal */
                    $s = substr($read, -3);
                    $fetch_data = array();
                    do {
                        /* outer loop, continue until next untagged fetch
                           or tagged reponse */
                        do {
                            /* innerloop for fetching literals. with this loop
                               we prohibid that literal responses appear in the
                               outer loop so we can trust the untagged and
                               tagged info provided by $read */
                            if ($s === "}\r\n") {
                                $j = strrpos($read, '{');
                                $iLit = substr($read, $j + 1, -3);
                                $fetch_data[] = $read;
                                $sLiteral = sqimap_fread($imap_stream, $iLit, $filter, $outputstream, $no_return);
                                if ($sLiteral === false) {
                                    /* error */
                                    break 4;
                                    /* while while switch while */
                                }
                                /* backwards compattibility */
                                $aLiteral = explode("\n", $sLiteral);
                                /* release not neaded data */
                                unset($sLiteral);
                                foreach ($aLiteral as $line) {
                                    $fetch_data[] = $line . "\n";
                                }
                                /* release not neaded data */
                                unset($aLiteral);
                                /* next fgets belongs to this fetch because
                                   we just got the exact literalsize and there
                                   must follow data to complete the response */
                                $read = sqimap_fgets($imap_stream);
                                if ($read === false) {
                                    /* error */
                                    break 4;
                                    /* while while switch while */
                                }
                                $fetch_data[] = $read;
                            } else {
                                $fetch_data[] = $read;
                            }
                            /* retrieve next line and check in the while
                               statements if it belongs to this fetch response */
                            $read = sqimap_fgets($imap_stream);
                            if ($read === false) {
                                /* error */
                                break 4;
                                /* while while switch while */
                            }
                            /* check for next untagged reponse and break */
                            if ($read[0] == '*') {
                                break 2;
                            }
                            $s = substr($read, -3);
                        } while ($s === "}\r\n");
                        $s = substr($read, -3);
                    } while ($read[0] !== '*' && substr($read, 0, strlen($tag)) !== $tag);
                    $resultlist[] = $fetch_data;
                    /* release not neaded data */
                    unset($fetch_data);
                } else {
                    $s = substr($read, -3);
                    do {
                        if ($s === "}\r\n") {
                            $j = strrpos($read, '{');
                            $iLit = substr($read, $j + 1, -3);
                            // check for numeric value to avoid that untagged responses like:
                            // * OK [PARSE] Unexpected characters at end of address: {SET:debug=51}
                            // will trigger literal fetching  ({SET:debug=51} !== int )
                            if (is_numeric($iLit)) {
                                $data[] = $read;
                                $sLiteral = fread($imap_stream, $iLit);
                                if ($sLiteral === false) {
                                    /* error */
                                    $read = false;
                                    break 3;
                                    /* while switch while */
                                }
                                $data[] = $sLiteral;
                                $data[] = sqimap_fgets($imap_stream);
                            } else {
                                $data[] = $read;
                            }
                        } else {
                            $data[] = $read;
                        }
                        $read = sqimap_fgets($imap_stream);
                        if ($read === false) {
                            break 3;
                            /* while switch while */
                        } else {
                            if ($read[0] == '*') {
                                break;
                            }
                        }
                        $s = substr($read, -3);
                    } while ($s === "}\r\n");
                    break 1;
                }
                break;
                // end case '*'
        }
        // end switch
    }
    // end while
    /* error processing in case $read is false */
    if ($read === false) {
        unset($data);
        set_up_language($squirrelmail_language);
        require_once SM_PATH . 'functions/display_messages.php';
        $string = "<b><font color=\"{$color['2']}\">\n" . _("ERROR: Connection dropped by IMAP server.") . "</b><br />\n";
        $cmd = explode(' ', $query);
        $cmd = strtolower($cmd[0]);
        if ($query != '' && $cmd != 'login') {
            $string .= "Query:" . ' ' . htmlspecialchars($query) . '<br />' . "</font><br />\n";
        }
        error_box($string, $color);
        exit;
    }
    /* Set $resultlist array */
    if (!empty($data)) {
        $resultlist[] = $data;
    } elseif (empty($resultlist)) {
        $resultlist[] = array();
    }
    /* Return result or handle errors */
    if ($handle_errors == false) {
        return $resultlist;
    }
    switch ($response) {
        case 'OK':
            return $resultlist;
            break;
        case 'NO':
            /* ignore this error from M$ exchange, it is not fatal (aka bug) */
            if (strstr($message, 'command resulted in') === false) {
                set_up_language($squirrelmail_language);
                require_once SM_PATH . 'functions/display_messages.php';
                $string = "<b><font color=\"{$color['2']}\">\n" . _("ERROR: Could not complete request.") . "</b><br />\n" . _("Query:") . ' ' . htmlspecialchars($query) . '<br />' . _("Reason Given:") . ' ' . htmlspecialchars($message) . "</font><br />\n";
                error_box($string, $color);
                echo '</body></html>';
                exit;
            }
            break;
        case 'BAD':
            set_up_language($squirrelmail_language);
            require_once SM_PATH . 'functions/display_messages.php';
            $string = "<b><font color=\"{$color['2']}\">\n" . _("ERROR: Bad or malformed request.") . "</b><br />\n" . _("Query:") . ' ' . htmlspecialchars($query) . '<br />' . _("Server responded:") . ' ' . htmlspecialchars($message) . "</font><br />\n";
            error_box($string, $color);
            echo '</body></html>';
            exit;
        case 'BYE':
            set_up_language($squirrelmail_language);
            require_once SM_PATH . 'functions/display_messages.php';
            $string = "<b><font color=\"{$color['2']}\">\n" . _("ERROR: IMAP server closed the connection.") . "</b><br />\n" . _("Query:") . ' ' . htmlspecialchars($query) . '<br />' . _("Server responded:") . ' ' . htmlspecialchars($message) . "</font><br />\n";
            error_box($string, $color);
            echo '</body></html>';
            exit;
        default:
            set_up_language($squirrelmail_language);
            require_once SM_PATH . 'functions/display_messages.php';
            $string = "<b><font color=\"{$color['2']}\">\n" . _("ERROR: Unknown IMAP response.") . "</b><br />\n" . _("Query:") . ' ' . htmlspecialchars($query) . '<br />' . _("Server responded:") . ' ' . htmlspecialchars($message) . "</font><br />\n";
            error_box($string, $color);
            /* the error is displayed but because we don't know the reponse we
               return the result anyway */
            return $resultlist;
            break;
    }
}
function sqimap_read_data_list($imap_stream, $tag_uid, $handle_errors, &$response, &$message, $query = '', $filter = false, $outputstream = false, $no_return = false)
{
    $read = '';
    $tag_uid_a = explode(' ', trim($tag_uid));
    $tag = $tag_uid_a[0];
    $resultlist = array();
    $data = array();
    $read = sqimap_fgets($imap_stream);
    $i = 0;
    while ($read) {
        $char = substr($read, 0, 1);
        switch ($char) {
            case '+':
            default:
                $read = sqimap_fgets($imap_stream);
                break;
            case substr($tag, 0, 1):
                /* get the command */
                $arg = '';
                $i = strlen($tag) + 1;
                $s = substr($read, $i);
                if (($j = strpos($s, ' ')) || ($j = strpos($s, "\n"))) {
                    $arg = substr($s, 0, $j);
                }
                $found_tag = substr($read, 0, $i - 1);
                if ($arg && $found_tag == $tag) {
                    switch ($arg) {
                        case 'OK':
                        case 'BAD':
                        case 'NO':
                        case 'BYE':
                        case 'PREAUTH':
                            $response = $arg;
                            $message = trim(substr($read, $i + strlen($arg)));
                            break 3;
                            /* switch switch while */
                        /* switch switch while */
                        default:
                            /* this shouldn't happen */
                            $response = $arg;
                            $message = trim(substr($read, $i + strlen($arg)));
                            break 3;
                            /* switch switch while */
                    }
                } elseif ($found_tag !== $tag) {
                    /* reset data array because we do not need this reponse */
                    $data = array();
                    $read = sqimap_fgets($imap_stream);
                    break;
                }
                // end case substr($tag, 0, 1)
            // end case substr($tag, 0, 1)
            case '*':
                if (preg_match('/^\\*\\s\\d+\\sFETCH/', $read)) {
                    /* check for literal */
                    $s = substr($read, -3);
                    $fetch_data = array();
                    do {
                        /* outer loop, continue until next untagged fetch
                           or tagged reponse */
                        do {
                            /* innerloop for fetching literals. with this loop
                               we prohibid that literal responses appear in the
                               outer loop so we can trust the untagged and
                               tagged info provided by $read */
                            if ($s === "}\r\n") {
                                $j = strrpos($read, '{');
                                $iLit = substr($read, $j + 1, -3);
                                $fetch_data[] = $read;
                                $sLiteral = sqimap_fread($imap_stream, $iLit, $filter, $outputstream, $no_return);
                                if ($sLiteral === false) {
                                    /* error */
                                    break 4;
                                    /* while while switch while */
                                }
                                /* backwards compattibility */
                                $aLiteral = explode("\n", $sLiteral);
                                /* release not neaded data */
                                unset($sLiteral);
                                foreach ($aLiteral as $line) {
                                    $fetch_data[] = $line . "\n";
                                }
                                /* release not neaded data */
                                unset($aLiteral);
                                /* next fgets belongs to this fetch because
                                   we just got the exact literalsize and there
                                   must follow data to complete the response */
                                $read = sqimap_fgets($imap_stream);
                                if ($read === false) {
                                    /* error */
                                    break 4;
                                    /* while while switch while */
                                }
                                $fetch_data[] = $read;
                            } else {
                                $fetch_data[] = $read;
                            }
                            /* retrieve next line and check in the while
                               statements if it belongs to this fetch response */
                            $read = sqimap_fgets($imap_stream);
                            if ($read === false) {
                                /* error */
                                break 4;
                                /* while while switch while */
                            }
                            /* check for next untagged reponse and break */
                            if (substr($read, 0, 1) == '*') {
                                break 2;
                            }
                            $s = substr($read, -3);
                        } while ($s === "}\r\n");
                        $s = substr($read, -3);
                    } while (substr($read, 0, 1) !== '*' && substr($read, 0, strlen($tag)) !== $tag);
                    $resultlist[] = $fetch_data;
                    /* release not neaded data */
                    unset($fetch_data);
                } else {
                    $s = substr($read, -3);
                    do {
                        if ($s === "}\r\n") {
                            $j = strrpos($read, '{');
                            $iLit = substr($read, $j + 1, -3);
                            $data[] = $read;
                            $sLiteral = fread($imap_stream, $iLit);
                            if ($sLiteral === false) {
                                /* error */
                                $read = false;
                                break 3;
                                /* while switch while */
                            }
                            $data[] = $sLiteral;
                            $data[] = sqimap_fgets($imap_stream);
                        } else {
                            $data[] = $read;
                        }
                        $read = sqimap_fgets($imap_stream);
                        if ($read === false) {
                            break 3;
                            /* while switch while */
                        } elseif (substr($read, 0, 1) == '*') {
                            break;
                        }
                        $s = substr($read, -3);
                    } while ($s === "}\r\n");
                    break 1;
                }
                break;
                // end case '*'
        }
        // end switch
    }
    // end while
    /* error processing in case $read is false */
    if ($read === false) {
        unset($data);
        echo date("d.m.Y @ G:i:s") . ": ERROR: Connection dropped by IMAP server.\n";
        exit;
    }
    /* Set $resultlist array */
    if (!empty($data)) {
        $resultlist[] = $data;
    } elseif (empty($resultlist)) {
        $resultlist[] = array();
    }
    /* Return result or handle errors */
    if ($handle_errors == false) {
        return $resultlist;
    }
    switch ($response) {
        case 'OK':
            return $resultlist;
            break;
        case 'NO':
            /* ignore this error from M$ exchange, it is not fatal (aka bug) */
            if (strstr($message, 'command resulted in') === false) {
                echo date("d.m.Y @ G:i:s") . ": ERROR: Could not complete request.\n";
                exit;
            }
            break;
        case 'BAD':
            echo date("d.m.Y @ G:i:s") . ": ERROR: Bad or malformed request.\n";
            exit;
        case 'BYE':
            echo date("d.m.Y @ G:i:s") . ": ERROR: IMAP server closed the connection.\n";
            exit;
        default:
            echo date("d.m.Y @ G:i:s") . ": ERROR: Unknown IMAP response.\n";
            return $resultlist;
            break;
    }
}