Project

General

Profile

Feature #2190 » 0001-FileUtils-chmod-to-symbolic-mode-added.patch

takkanm (三村 益隆), 05/17/2010 06:07 PM

View differences:

lib/fileutils.rb
OPT_TABLE['install'] = [:mode, :preserve, :noop, :verbose]
def user_mask(target)
mask = 0
target.each_byte do |byte_chr|
case byte_chr.chr
when "u"
mask |= 04700
when "g"
mask |= 02070
when "o"
mask |= 01007
when "a"
mask |= 07777
end
end
mask
end
private_module_function :user_mask
def mode_mask(mode, path)
mask = 0
mode.each_byte do |byte_chr|
case byte_chr.chr
when "r"
mask |= 0444
when "w"
mask |= 0222
when "x"
mask |= 0111
when "X"
mask |= 0111 if FileTest::directory? path
when "s"
mask |= 06000
when "t"
mask |= 01000
end
end
mask
end
private_module_function :mode_mask
def current_file_mode(path)
stat = File.stat(path)
current_mode = (stat.mode & 0777)
current_mode + 04000 if stat.setuid?
current_mode + 02000 if stat.setgid?
current_mode + 01000 if stat.sticky?
end
private_module_function :current_file_mode
def symbolic_modes_to_i(modes, path)
current_mode = current_file_mode(path)
current_mode = (File.stat(path).mode & 07777)
modes.split(/,/).inject(0) do |mode, mode_sym|
mode_sym = "a#{mode_sym}" if mode_sym =~ %r!^[+-=]!
target, mode = mode_sym.split %r![+-=]!
user_mask = user_mask(target)
mode_mask = mode_mask(mode ? mode : "", path)
case mode_sym
when /=/
current_mode &= ~(user_mask)
current_mode |= user_mask & mode_mask
when /\+/
current_mode |= user_mask & mode_mask
when /-/
current_mode &= ~(user_mask & mode_mask)
end
end
end
private_module_function :symbolic_modes_to_i
def fu_mode(mode, path)
mode.class == String ? symbolic_modes_to_i(mode, path) : mode
end
private_module_function :fu_mode
#
# Options: noop verbose
#
# Changes permission bits on the named files (in +list+) to the bit pattern
# represented by +mode+.
#
# +mode+ is the symbolic and absolute mode can be used.
#
# Absolute mode is
# FileUtils.chmod 0755, 'somecommand'
# FileUtils.chmod 0644, %w(my.rb your.rb his.rb her.rb)
# FileUtils.chmod 0755, '/usr/bin/ruby', :verbose => true
#
# Symbolic mode is
# FileUtils.chmod "u=wrx,go=rx", 'somecommand'
# FileUtils.chmod "u=wr,go=rr", %w(my.rb your.rb his.rb her.rb)
# FileUtils.chmod "u=wrx,go=rx", '/usr/bin/ruby', :verbose => true
#
# "a" is user, group, other mask.
# "u" is user's mask.
# "g" is group's mask.
# "o" is other's mask.
# "w" is write permission.
# "r" is read permission.
# "x" is execute permission.
# "s" is uid, gid.
# "t" is sticky bit.
# "+" is added to a class given the specified mode.
# "-" Is removed from a given class given mode.
# "=" Is the exact nature of the class will be given a specified mode.
def chmod(mode, list, options = {})
fu_check_options options, OPT_TABLE['chmod']
list = fu_list(list)
fu_output_message sprintf('chmod %o %s', mode, list.join(' ')) if options[:verbose]
return if options[:noop]
list.each do |path|
Entry_.new(path).chmod mode
Entry_.new(path).chmod(fu_mode(mode, path))
end
end
module_function :chmod
......
# to the bit pattern represented by +mode+.
#
# FileUtils.chmod_R 0700, "/tmp/app.#{$$}"
# FileUtils.chmod_R "u=wrx", "/tmp/app.#{$$}"
#
def chmod_R(mode, list, options = {})
fu_check_options options, OPT_TABLE['chmod_R']
......
list.each do |root|
Entry_.new(root).traverse do |ent|
begin
ent.chmod mode
ent.chmod(fu_mode(mode, ent.path))
rescue
raise unless options[:force]
end
test/fileutils/test_fileutils.rb
assert_equal 0500, File.stat('tmp/a').mode & 0777
end if have_file_perm?
def test_chmod_symbol_mode
check_singleton :chmod
touch 'tmp/a'
chmod "u=wrx,g=,o=", 'tmp/a'
assert_equal 0700, File.stat('tmp/a').mode & 0777
chmod "u=rx,go=", 'tmp/a'
assert_equal 0500, File.stat('tmp/a').mode & 0777
chmod "+wrx", 'tmp/a'
assert_equal 0777, File.stat('tmp/a').mode & 0777
chmod "u+s,o=s", 'tmp/a'
assert_equal 04770, File.stat('tmp/a').mode & 07777
chmod "u-w,go-wrx", 'tmp/a'
assert_equal 04500, File.stat('tmp/a').mode & 07777
chmod "+s", 'tmp/a'
assert_equal 06500, File.stat('tmp/a').mode & 07777
chmod "u+t,o+t", 'tmp/a'
assert_equal 07500, File.stat('tmp/a').mode & 07777
chmod "a-t,a-s", 'tmp/a'
assert_equal 0500, File.stat('tmp/a').mode & 07777
end if have_file_perm?
def test_chmod_R
check_singleton :chmod_R
......
chmod_R 0700, 'tmp/dir' # to remove
end if have_file_perm?
def test_chmod_symbol_mode_R
check_singleton :chmod_R
mkdir_p 'tmp/dir/dir'
touch %w( tmp/dir/file tmp/dir/dir/file )
chmod_R "u=wrx,g=,o=", 'tmp/dir'
assert_equal 0700, File.stat('tmp/dir').mode & 0777
assert_equal 0700, File.stat('tmp/dir/file').mode & 0777
assert_equal 0700, File.stat('tmp/dir/dir').mode & 0777
assert_equal 0700, File.stat('tmp/dir/dir/file').mode & 0777
chmod_R "u=xr,g+X,o=", 'tmp/dir'
assert_equal 0510, File.stat('tmp/dir').mode & 0777
assert_equal 0500, File.stat('tmp/dir/file').mode & 0777
assert_equal 0510, File.stat('tmp/dir/dir').mode & 0777
assert_equal 0500, File.stat('tmp/dir/dir/file').mode & 0777
chmod_R 0700, 'tmp/dir' # to remove
end if have_file_perm?
# FIXME: How can I test this method?
def test_chown
check_singleton :chown
    (1-1/1)