private function getResponse($fp, $clientVer)
{
$response = '';
$len = 0;
$header = fread($fp, 8);
if (strlen($header) === 8) {
list($status, $ver, $len) = array_values(unpack('n2a/Nb', $header));
$left = $len;
while ($left > 0 && !feof($fp)) {
$chunk = fread($fp, min(8192, $left));
if ($chunk) {
$response .= $chunk;
$left -= strlen($chunk);
}
}
}
if ($this->socket === false) {
fclose($fp);
}
// check response
$read = strlen($response);
if (!$response || $read != $len) {
$this->error = $len ? sprintf('failed to read searchd response (status=%d, ver=%d, len=%d, read=%d)', $status, $ver, $len, $read) : 'received zero-sized searchd response';
return false;
}
// check status
if ($status === self::SEARCHD_WARNING) {
list(, $wlen) = unpack('N*', substr($response, 0, 4));
$this->warning = substr($response, 4, $wlen);
return substr($response, 4 + $wlen);
}
if ($status === self::SEARCHD_ERROR) {
$this->error = 'searchd error: ' . substr($response, 4);
return false;
}
if ($status === self::SEARCHD_RETRY) {
$this->error = 'temporary searchd error: ' . substr($response, 4);
return false;
}
if ($status !== self::SEARCHD_OK) {
$this->error = sprintf('unknown status code \'%d\'', $status);
return false;
}
// check version
if ($ver < $clientVer) {
$this->warning = sprintf('searchd command v.%d.%d older than client\'s v.%d.%d, some options might not work', $ver >> 8, $ver & 0xff, $clientVer >> 8, $clientVer & 0xff);
}
return $response;
}