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