#!/usr/bin/env ruby require 'getoptlong' require 'readline' require 'singleton' require 'yaml' # Monkey-path the Array class. class Array # ["foo", {"foo" => 1}].cleanup => [{"foo" => 1}] # If the key in a Hash element of an Array is also present as an element of # the Array, delete the latter. def cleanup array = self.dup self.grep(Hash).map(&:keys).flatten.each do |x| array.delete x end array end end # Class handles configuration parameters. class FlagsConfig < Hash # This is a singleton class. include Singleton # Merges a Hash or YAML file (containing a Hash) with itself. def load config if config.class == Hash merge! config return end unless config.nil? merge_yaml! config end end # Merge Config Hash with Hash in YAML file. def merge_yaml! path merge!(load_file path) do |key, old, new| (old + new).uniq.cleanup if old.is_a? Array and new.is_a? Array end end # Load YAML file and work around tabs not working for identation. def load_file path YAML.load open(path).read.gsub(/\t/, ' ') rescue Psych::SyntaxError => e print path, ':', e.message.split(':').last, "\n" exit 1 end end # A method to print a beautiful usage message. def usage $stderr.puts < e usage end # Whatever is left over is a filter. filters = ARGV # Exit if we are not running with root privileges. if Process.uid != 0 $stderr << "Root privileges needed.\n" exit 1 end # Either default config paths or overridden ones. config_paths = if new_configs.empty? ['/etc/pax-flags-libre/*.conf', '/usr/share/pax-flags-libre/*.conf'] else new_configs end # Initialize the singleton config object... config = FlagsConfig.instance # ... and load every config file. config_paths.each do |path| Dir.glob(path).each do |file| config.load file end end # Helper text for simple entries. puts < /dev/null') system stop unless prepend start_again = true if start end end if xattr # setfattr seems to be picky about the order of the flags, # rearrange it beforehand xflags = flags[/[Pp]/] + flags[/[Ee]/] + flags[/[Mm]/] + flags[/[Rr]/] + flags[/[Ss]/] print xflags, ' ', path, "\n" else print flags, ' ', path, "\n" end # Set the flags and notify the user. unless prepend if xattr `setfattr -n user.pax.flags -v #{xflags} "#{path}"` else header = 'c' header = 'C' if e['header'] == 'create' `paxctl -#{header}#{flags} "#{path}"` end end # Start the complex entries service again, if it is neccessary. system start unless prepend if start_again end end