function _parseACL($acl)
{
// Take off the first and last characters (the braces)
$acl = substr($acl, 1, strlen($acl) - 2);
// Pick out individual ACE's by carefully parsing. This is necessary in order
// to cope with usernames and stuff that contain commas
$aces = array();
$i = $j = 0;
$in_quotes = false;
while ($i < strlen($acl)) {
// If current char is a double quote and it's not escaped, then
// enter quoted bit
$char = substr($acl, $i, 1);
if ($char == '"' && ($i == 0 || substr($acl, $i - 1, 1) != '\\')) {
$in_quotes = !$in_quotes;
} elseif ($char == ',' && !$in_quotes) {
// Add text so far to the array
$aces[] = substr($acl, $j, $i - $j);
$j = $i + 1;
}
$i++;
}
// Add final text to the array
$aces[] = substr($acl, $j);
// Create the array to be returned
$temp = array();
// For each ACE, generate an entry in $temp
foreach ($aces as $v) {
// If the ACE begins with a double quote, strip them off both ends
// and unescape backslashes and double quotes
$unquote = false;
if (strpos($v, '"') === 0) {
$v = substr($v, 1, strlen($v) - 2);
$v = str_replace('\\"', '"', $v);
$v = str_replace('\\\\', '\\', $v);
}
// Figure out type of ACE (public, user or group)
if (strpos($v, '=') === 0) {
$atype = 'public';
} else {
if ($this->hasRoles()) {
$atype = 'role';
} else {
if (strpos($v, 'group ') === 0) {
$atype = 'group';
// Tear off 'group' prefix
$v = substr($v, 6);
} else {
$atype = 'user';
}
}
}
// Break on unquoted equals sign...
$i = 0;
$in_quotes = false;
$entity = null;
$chars = null;
while ($i < strlen($v)) {
// If current char is a double quote and it's not escaped, then
// enter quoted bit
$char = substr($v, $i, 1);
$next_char = substr($v, $i + 1, 1);
if ($char == '"' && ($i == 0 || $next_char != '"')) {
$in_quotes = !$in_quotes;
} elseif ($char == '"' && $next_char == '"') {
$i++;
} elseif ($char == '=' && !$in_quotes) {
// Split on current equals sign
$entity = substr($v, 0, $i);
$chars = substr($v, $i + 1);
break;
}
$i++;
}
// Check for quoting on entity name, and unescape if necessary
if (strpos($entity, '"') === 0) {
$entity = substr($entity, 1, strlen($entity) - 2);
$entity = str_replace('""', '"', $entity);
}
// New row to be added to $temp
// (type, grantee, privileges, grantor, grant option?
$row = array($atype, $entity, array(), '', array());
// Loop over chars and add privs to $row
for ($i = 0; $i < strlen($chars); $i++) {
// Append to row's privs list the string representing
// the privilege
$char = substr($chars, $i, 1);
if ($char == '*') {
$row[4][] = $this->privmap[substr($chars, $i - 1, 1)];
} elseif ($char == '/') {
$grantor = substr($chars, $i + 1);
// Check for quoting
if (strpos($grantor, '"') === 0) {
$grantor = substr($grantor, 1, strlen($grantor) - 2);
$grantor = str_replace('""', '"', $grantor);
}
$row[3] = $grantor;
break;
} else {
if (!isset($this->privmap[$char])) {
return -3;
} else {
$row[2][] = $this->privmap[$char];
}
}
}
// Append row to temp
$temp[] = $row;
}
return $temp;
}