module Puppet::Util::SymbolicFileMode

Constants

SetGIDBit
SetUIDBit
StickyBit
SymbolicMode
SymbolicSpecialToBit

Public Instance Methods

display_mode(value) click to toggle source
   # File lib/puppet/util/symbolic_file_mode.rb
23 def display_mode(value)
24   if value =~ /^0?[0-7]{1,4}$/
25     value.rjust(4, "0")
26   else
27     value
28   end
29 end
normalize_symbolic_mode(value) click to toggle source
   # File lib/puppet/util/symbolic_file_mode.rb
31 def normalize_symbolic_mode(value)
32   return nil if value.nil?
33 
34   # We need to treat integers as octal numbers.
35   #
36   # "A numeric mode is from one to four octal digits (0-7), derived by adding
37   # up the bits with values 4, 2, and 1. Omitted digits are assumed to be
38   # leading zeros."
39   if value.is_a? Numeric
40     value.to_s(8)
41   elsif value =~ /^0?[0-7]{1,4}$/
42     value.to_i(8).to_s(8) # strip leading 0's
43   else
44     value
45   end
46 end
symbolic_mode_to_int(modification, to_mode = 0, is_a_directory = false) click to toggle source
    # File lib/puppet/util/symbolic_file_mode.rb
 48 def symbolic_mode_to_int(modification, to_mode = 0, is_a_directory = false)
 49   if modification.nil? or modification == ''
 50     raise Puppet::Error, _("An empty mode string is illegal")
 51   elsif modification =~ /^[0-7]+$/
 52     return modification.to_i(8)
 53   elsif modification =~ /^\d+$/
 54     raise Puppet::Error, _("Numeric modes must be in octal, not decimal!")
 55   end
 56 
 57   fail _("non-numeric current mode (%{mode})") % { mode: to_mode.inspect } unless to_mode.is_a?(Numeric)
 58 
 59   original_mode = {
 60     's' => (to_mode & 07000) >> 9,
 61     'u' => (to_mode & 00700) >> 6,
 62     'g' => (to_mode & 00070) >> 3,
 63     'o' => (to_mode & 00007) >> 0,
 64     # Are there any execute bits set in the original mode?
 65     'any x?' => (to_mode & 00111) != 0
 66   }
 67   final_mode = {
 68     's' => original_mode['s'],
 69     'u' => original_mode['u'],
 70     'g' => original_mode['g'],
 71     'o' => original_mode['o'],
 72   }
 73 
 74   modification.split(/\s*,\s*/).each do |part|
 75     begin
 76       _, to, dsl = /^([ugoa]*)([-+=].*)$/.match(part).to_a
 77       if dsl.nil? then raise Puppet::Error, _('Missing action') end
 78       to = "a" unless to and to.length > 0
 79 
 80       # We want a snapshot of the mode before we start messing with it to
 81       # make actions like 'a-g' atomic.  Various parts of the DSL refer to
 82       # the original mode, the final mode, or the current snapshot of the
 83       # mode, for added fun.
 84       snapshot_mode = {}
 85       final_mode.each {|k,v| snapshot_mode[k] = v }
 86 
 87       to.gsub('a', 'ugo').split('').uniq.each do |who|
 88         value = snapshot_mode[who]
 89 
 90         action = '!'
 91         actions = {
 92           '!' => lambda {|_,_| raise Puppet::Error, _('Missing operation (-, =, or +)') },
 93           '=' => lambda {|m,v| m | v },
 94           '+' => lambda {|m,v| m | v },
 95           '-' => lambda {|m,v| m & ~v },
 96         }
 97 
 98         dsl.split('').each do |op|
 99           case op
100           when /[-+=]/
101             action = op
102             # Clear all bits, if this is assignment
103             value  = 0 if op == '='
104 
105           when /[ugo]/
106             value = actions[action].call(value, snapshot_mode[op])
107 
108           when /[rwx]/
109             value = actions[action].call(value, SymbolicMode[op])
110 
111           when 'X'
112             # Only meaningful in combination with "set" actions.
113             if action != '+'
114               raise Puppet::Error, _("X only works with the '+' operator")
115             end
116 
117             # As per the BSD manual page, set if this is a directory, or if
118             # any execute bit is set on the original (unmodified) mode.
119             # Ignored otherwise; it is "add if", not "add or clear".
120             if is_a_directory or original_mode['any x?']
121               value = actions[action].call(value, ExecBit)
122             end
123 
124           when /[st]/
125             bit = SymbolicSpecialToBit[op][who] or fail _("internal error")
126             final_mode['s'] = actions[action].call(final_mode['s'], bit)
127 
128           else
129             raise Puppet::Error, _('Unknown operation')
130           end
131         end
132 
133         # Now, assign back the value.
134         final_mode[who] = value
135       end
136 
137     rescue Puppet::Error => e
138       if part.inspect != modification.inspect
139         rest = " at #{part.inspect}"
140       else
141         rest = ''
142       end
143 
144       raise Puppet::Error, _("%{error}%{rest} in symbolic mode %{modification}") % { error: e, rest: rest, modification: modification.inspect }, e.backtrace
145     end
146   end
147 
148   result =
149     final_mode['s'] << 9 |
150     final_mode['u'] << 6 |
151     final_mode['g'] << 3 |
152     final_mode['o'] << 0
153   return result
154 end
valid_symbolic_mode?(value) click to toggle source
   # File lib/puppet/util/symbolic_file_mode.rb
16 def valid_symbolic_mode?(value)
17   value = normalize_symbolic_mode(value)
18   return true if value =~ /^0?[0-7]{1,4}$/
19   return true if value =~ /^([ugoa]*[-=+][-=+rstwxXugo]*)(,[ugoa]*[-=+][-=+rstwxXugo]*)*$/
20   return false
21 end