Skip to content

Instantly share code, notes, and snippets.

@djberg96
Created January 19, 2016 13:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save djberg96/d95e28e0b8eac67be208 to your computer and use it in GitHub Desktop.
Save djberg96/d95e28e0b8eac67be208 to your computer and use it in GitHub Desktop.
require 'ffi'
class File
class ACL
extend FFI::Library
ffi_lib :acl
ACL_TYPE_ACCESS = 0x8000
ACL_FIRST_ENTRY = 0
ACL_NEXT_ENTRY = 1
ACL_USER_OBJ = 0x01
ACL_USER = 0x02
ACL_GROUP_OBJ = 0x04
ACL_GROUP = 0x08
ACL_MASK = 0x10
ACL_OTHER = 0x20
attach_function :acl_get_file, [:string, :int], :pointer
attach_function :acl_get_entry, [:pointer, :int, :pointer], :int
attach_function :acl_get_tag_type, [:pointer, :pointer], :int
attach_function :acl_free, [:pointer], :int
attach_function :acl_to_text, [:pointer, :pointer], :string
def initialize(file, access = ACL_TYPE_ACCESS)
@acl = acl_get_file(file, access)
if @acl.null?
raise SystemCallError.new("acl_init", FFI.errno)
end
get_acl_info(@acl)
ObjectSpace.define_finalizer(self, proc{ acl_free(@acl) })
end
def to_s
len = FFI::MemoryPointer.new(:size_t)
text = acl_to_text(@acl, len)
if text.empty? || text.nil?
raise SystemCallError.new("acl_to_text", FFI.errno)
end
text
end
def get_acl_info(acl)
ent_ptr = FFI::MemoryPointer.new(:pointer)
tag_ptr = FFI::MemoryPointer.new(:int)
entry_id = ACL_FIRST_ENTRY
while val = acl_get_entry(acl, entry_id, ent_ptr)
break if val < 1
# TODO: Fails. Why?
if acl_get_tag_type(ent_ptr, tag_ptr) != 0
raise SystemCallError.new("acl_get_tag_type", FFI.errno)
end
entry_id = ACL_NEXT_ENTRY
end
end
private
def tag_type(value)
case value
when ACL_USER_OBJ
"user_obj"
when ACL_USER
"user"
when ACL_GROUP_OBJ
"group_obj"
when ACL_GROUP
"group"
when ACL_MASK
"mask"
when ACL_OTHER
"other"
else
"none"
end
end
end
end
acl = File::ACL.new('test.txt')
#puts acl.to_s
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment