test: Support more options
Adds -g, -G, -k, -O and -u options.
This commit is contained in:
parent
caab6ac968
commit
6c86b40724
Notes:
sideshowbarker
2024-07-17 06:25:32 +09:00
Author: https://github.com/implicitfield Commit: https://github.com/SerenityOS/serenity/commit/6c86b40724 Pull-request: https://github.com/SerenityOS/serenity/pull/15395 Reviewed-by: https://github.com/linusg ✅
2 changed files with 97 additions and 3 deletions
|
@ -71,6 +71,11 @@ The expression can take any of the following forms:
|
|||
* `-w <file>` whether the current user has write access to the file
|
||||
* `-x <file>` whether the current user has execute access to the file
|
||||
* `-e <file>` whether the file exists
|
||||
* `-g <file>` whether the file exists and has the set-group-ID bit set
|
||||
* `-G <file>` whether the file exists and is owned by the effective group ID
|
||||
* `-k <file>` whether the file exists and has the sticky bit set
|
||||
* `-O <file>` whether the file exists and is owned by the effective user ID
|
||||
* `-u <file>` whether the file exists and has the set-user-ID bit set
|
||||
|
||||
|
||||
Except for `-h/-L`, all file checks dereference symbolic links.
|
||||
|
|
|
@ -182,6 +182,89 @@ private:
|
|||
Permission m_kind { Read };
|
||||
};
|
||||
|
||||
class FileHasFlag : public Condition {
|
||||
public:
|
||||
enum Flag {
|
||||
SGID,
|
||||
SUID,
|
||||
SVTX,
|
||||
};
|
||||
FileHasFlag(StringView path, Flag kind)
|
||||
: m_path(path)
|
||||
, m_kind(kind)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
virtual bool check() const override
|
||||
{
|
||||
struct stat statbuf;
|
||||
int rc = stat(m_path.characters(), &statbuf);
|
||||
|
||||
if (rc < 0) {
|
||||
if (errno != ENOENT) {
|
||||
perror(m_path.characters());
|
||||
g_there_was_an_error = true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (m_kind) {
|
||||
case SGID:
|
||||
return statbuf.st_mode & S_ISGID;
|
||||
case SUID:
|
||||
return statbuf.st_mode & S_ISUID;
|
||||
case SVTX:
|
||||
return statbuf.st_mode & S_ISVTX;
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
String m_path;
|
||||
Flag m_kind { SGID };
|
||||
};
|
||||
|
||||
class FileIsOwnedBy : public Condition {
|
||||
public:
|
||||
enum Owner {
|
||||
EffectiveGID,
|
||||
EffectiveUID,
|
||||
};
|
||||
FileIsOwnedBy(StringView path, Owner kind)
|
||||
: m_path(path)
|
||||
, m_kind(kind)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
virtual bool check() const override
|
||||
{
|
||||
struct stat statbuf;
|
||||
int rc = stat(m_path.characters(), &statbuf);
|
||||
|
||||
if (rc < 0) {
|
||||
if (errno != ENOENT) {
|
||||
perror(m_path.characters());
|
||||
g_there_was_an_error = true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (m_kind) {
|
||||
case EffectiveGID:
|
||||
return statbuf.st_gid == getgid();
|
||||
case EffectiveUID:
|
||||
return statbuf.st_uid == getuid();
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
String m_path;
|
||||
Owner m_kind { EffectiveGID };
|
||||
};
|
||||
|
||||
class StringCompare : public Condition {
|
||||
public:
|
||||
enum Mode {
|
||||
|
@ -374,6 +457,12 @@ static OwnPtr<Condition> parse_simple_expression(char* argv[])
|
|||
return make<UserHasPermission>(value, UserHasPermission::Execute);
|
||||
case 'e':
|
||||
return make<UserHasPermission>(value, UserHasPermission::Any);
|
||||
case 'g':
|
||||
return make<FileHasFlag>(value, FileHasFlag::SGID);
|
||||
case 'k':
|
||||
return make<FileHasFlag>(value, FileHasFlag::SVTX);
|
||||
case 'u':
|
||||
return make<FileHasFlag>(value, FileHasFlag::SUID);
|
||||
case 'o':
|
||||
case 'a':
|
||||
// '-a' and '-o' are boolean ops, which are part of a complex expression
|
||||
|
@ -384,11 +473,11 @@ static OwnPtr<Condition> parse_simple_expression(char* argv[])
|
|||
return make<StringCompare>(""sv, value, StringCompare::NotEqual);
|
||||
case 'z':
|
||||
return make<StringCompare>(""sv, value, StringCompare::Equal);
|
||||
case 'g':
|
||||
case 'G':
|
||||
case 'k':
|
||||
case 'N':
|
||||
return make<FileIsOwnedBy>(value, FileIsOwnedBy::EffectiveGID);
|
||||
case 'O':
|
||||
return make<FileIsOwnedBy>(value, FileIsOwnedBy::EffectiveUID);
|
||||
case 'N':
|
||||
case 's':
|
||||
// 'optind' has been incremented to refer to the argument after the
|
||||
// operator, while we want to print the operator itself.
|
||||
|
|
Loading…
Add table
Reference in a new issue