Add BSD::Control::Feature#status
This commit is contained in:
parent
e84e824579
commit
4eaf98b9bc
5 changed files with 123 additions and 0 deletions
|
@ -1,5 +1,8 @@
|
|||
#include <libhbsdcontrol.h>
|
||||
#include <ruby.h>
|
||||
#include <sys/extattr.h>
|
||||
#include <libutil.h>
|
||||
#include <errno.h>
|
||||
#include "include/ffi.h"
|
||||
|
||||
/**
|
||||
|
@ -56,6 +59,43 @@ ffi_reset(VALUE self, VALUE rb_feature, VALUE rb_path)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* BSD::Control::FFI.status
|
||||
**/
|
||||
VALUE
|
||||
ffi_status(VALUE self, VALUE rb_feature, VALUE rb_path)
|
||||
{
|
||||
VALUE rb_enable_flag, rb_disable_flag;
|
||||
char *enable_flag, *disable_flag, *path, enable_data[2], disable_data[2];
|
||||
int namespace;
|
||||
|
||||
rb_enable_flag = rb_funcall(rb_feature, rb_intern("enable"), 0);
|
||||
rb_disable_flag = rb_funcall(rb_feature, rb_intern("disable"), 0);
|
||||
Check_Type(rb_path, T_STRING);
|
||||
Check_Type(rb_enable_flag, T_STRING);
|
||||
Check_Type(rb_disable_flag, T_STRING);
|
||||
path = RSTRING_PTR(rb_path);
|
||||
enable_flag = RSTRING_PTR(rb_enable_flag);
|
||||
disable_flag = RSTRING_PTR(rb_disable_flag);
|
||||
if (extattr_string_to_namespace("system", &namespace) == -1) {
|
||||
rb_syserr_fail(errno, "extattr_string_to_namespace");
|
||||
}
|
||||
if (extattr_get_file(path, namespace, enable_flag, &enable_data, 2) == -1) {
|
||||
rb_syserr_fail(errno, "extattr_get_file");
|
||||
}
|
||||
if (extattr_get_file(path, namespace, disable_flag, &disable_data, 2) == -1) {
|
||||
rb_syserr_fail(errno, "extattr_get_file");
|
||||
}
|
||||
if (strcmp(enable_data, disable_data) == 0) {
|
||||
return (ID2SYM(rb_intern("conflict")));
|
||||
} else if (strcmp(enable_data, "1") == 0) {
|
||||
return (ID2SYM(rb_intern("enabled")));
|
||||
} else {
|
||||
return (ID2SYM(rb_intern("disabled")));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* BSD::Control::FFI.library_version
|
||||
**/
|
||||
|
|
|
@ -15,5 +15,6 @@ Init_hbsdctl(void)
|
|||
rb_define_singleton_method(rb_mFFI, "available_features", ffi_available_features, 0);
|
||||
rb_define_singleton_method(rb_mFFI, "library_version", ffi_library_version, 0);
|
||||
rb_define_singleton_method(rb_mFFI, "reset!", ffi_reset, 2);
|
||||
rb_define_singleton_method(rb_mFFI, "status", ffi_status, 2);
|
||||
rb_define_private_method(rb_cFeature, "set!", feature_set, 2);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include <ruby.h>
|
||||
VALUE ffi_library_version(VALUE);
|
||||
VALUE ffi_available_features(VALUE);
|
||||
VALUE ffi_status(VALUE, VALUE, VALUE);
|
||||
VALUE ffi_reset(VALUE, VALUE, VALUE);
|
||||
|
|
|
@ -55,6 +55,47 @@ module BSD::Control
|
|||
FFI.reset!(self, path)
|
||||
end
|
||||
|
||||
##
|
||||
# @return [Boolean]
|
||||
# Returns true when a feature is enabled.
|
||||
def enabled?(path)
|
||||
status(path) == :enabled
|
||||
end
|
||||
|
||||
##
|
||||
# @return [Boolean]
|
||||
# Returns true when a feature is disabled.
|
||||
def disabled?(path)
|
||||
status(path) == :disabled
|
||||
end
|
||||
|
||||
##
|
||||
# @return [Boolean]
|
||||
# Returns true when a feature is configured to use the system default.
|
||||
def sysdef?(path)
|
||||
status(path) == :sysdef
|
||||
end
|
||||
|
||||
##
|
||||
# @return [Boolean]
|
||||
# Returns true when a feature is in conflict
|
||||
# (i.e: the feature is both enabled and disabled at the same time).
|
||||
def conflict?(path)
|
||||
status(path) == :conflict
|
||||
end
|
||||
|
||||
##
|
||||
# @param [String] path
|
||||
# The path to a file.
|
||||
# @return [Symbol]
|
||||
# Returns the feature status of a file.
|
||||
# Status can be one of: `:conflict`, `:sysdef`, `:enabled`, `:disabled`.
|
||||
def status(path)
|
||||
FFI.status(self, path)
|
||||
rescue Errno::ENOATTR
|
||||
:sysdef
|
||||
end
|
||||
|
||||
# @endgroup
|
||||
|
||||
##
|
||||
|
|
40
test/superuser/status_feature_test.rb
Normal file
40
test/superuser/status_feature_test.rb
Normal file
|
@ -0,0 +1,40 @@
|
|||
require_relative "../setup"
|
||||
module BSD::Control
|
||||
class EnableFeatureTest < Test::Unit::TestCase
|
||||
require 'fileutils'
|
||||
include FileUtils
|
||||
|
||||
def test_mprotect_sysdef_status
|
||||
touch(file)
|
||||
assert_equal :sysdef,
|
||||
BSD::Control.feature!(:mprotect).status(file)
|
||||
ensure
|
||||
rm(file)
|
||||
end
|
||||
|
||||
def test_mprotect_enabled_status
|
||||
touch(file)
|
||||
BSD::Control.feature!(:mprotect).enable!(file)
|
||||
assert_equal :enabled,
|
||||
BSD::Control.feature!(:mprotect).status(file)
|
||||
ensure
|
||||
rm(file)
|
||||
end
|
||||
|
||||
|
||||
def test_mprotect_disabled_status
|
||||
touch(file)
|
||||
BSD::Control.feature!(:mprotect).disable!(file)
|
||||
assert_equal :disabled,
|
||||
BSD::Control.feature!(:mprotect).status(file)
|
||||
ensure
|
||||
rm(file)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def file
|
||||
File.join(__dir__, "file")
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue